diff options
author | Maxim Levitsky <maximlevitsky@gmail.com> | 2010-10-16 18:56:28 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-21 08:59:47 -0400 |
commit | 4651918a4afdd49bdea21d2f919b189ef17a6399 (patch) | |
tree | 73a4e3b5f7da1d655a059bb9b69135cf6f395e02 | |
parent | fb249ca61d469a9cb666ba7e1d992787dc6bad82 (diff) |
[media] IR: extend ir_raw_event and do refactoring
Add new event types for timeout & carrier report
Move timeout handling from ir_raw_event_store_with_filter to
ir-lirc-codec, where it is really needed.
Now lirc bridge ensures proper gap handling.
Extend lirc bridge for carrier & timeout reports
Note: all new ir_raw_event variables now should be initialized
like that: DEFINE_IR_RAW_EVENT(ev);
To clean an existing event, use init_ir_raw_event(&ev);
Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Acked-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/IR/ene_ir.c | 4 | ||||
-rw-r--r-- | drivers/media/IR/ir-core-priv.h | 13 | ||||
-rw-r--r-- | drivers/media/IR/ir-jvc-decoder.c | 5 | ||||
-rw-r--r-- | drivers/media/IR/ir-lirc-codec.c | 128 | ||||
-rw-r--r-- | drivers/media/IR/ir-nec-decoder.c | 5 | ||||
-rw-r--r-- | drivers/media/IR/ir-raw-event.c | 45 | ||||
-rw-r--r-- | drivers/media/IR/ir-rc5-decoder.c | 5 | ||||
-rw-r--r-- | drivers/media/IR/ir-rc5-sz-decoder.c | 5 | ||||
-rw-r--r-- | drivers/media/IR/ir-rc6-decoder.c | 5 | ||||
-rw-r--r-- | drivers/media/IR/ir-sony-decoder.c | 5 | ||||
-rw-r--r-- | drivers/media/IR/mceusb.c | 3 | ||||
-rw-r--r-- | drivers/media/IR/nuvoton-cir.c | 5 | ||||
-rw-r--r-- | drivers/media/IR/streamzap.c | 6 | ||||
-rw-r--r-- | include/media/ir-core.h | 40 |
14 files changed, 181 insertions, 93 deletions
diff --git a/drivers/media/IR/ene_ir.c b/drivers/media/IR/ene_ir.c index f5beea04906a..0795872ff5de 100644 --- a/drivers/media/IR/ene_ir.c +++ b/drivers/media/IR/ene_ir.c | |||
@@ -697,7 +697,7 @@ static irqreturn_t ene_isr(int irq, void *data) | |||
697 | unsigned long flags; | 697 | unsigned long flags; |
698 | irqreturn_t retval = IRQ_NONE; | 698 | irqreturn_t retval = IRQ_NONE; |
699 | struct ene_device *dev = (struct ene_device *)data; | 699 | struct ene_device *dev = (struct ene_device *)data; |
700 | struct ir_raw_event ev; | 700 | DEFINE_IR_RAW_EVENT(ev); |
701 | 701 | ||
702 | spin_lock_irqsave(&dev->hw_lock, flags); | 702 | spin_lock_irqsave(&dev->hw_lock, flags); |
703 | 703 | ||
@@ -898,7 +898,7 @@ static int ene_set_learning_mode(void *data, int enable) | |||
898 | } | 898 | } |
899 | 899 | ||
900 | /* outside interface: enable or disable idle mode */ | 900 | /* outside interface: enable or disable idle mode */ |
901 | static void ene_rx_set_idle(void *data, int idle) | 901 | static void ene_rx_set_idle(void *data, bool idle) |
902 | { | 902 | { |
903 | struct ene_device *dev = (struct ene_device *)data; | 903 | struct ene_device *dev = (struct ene_device *)data; |
904 | 904 | ||
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h index 6830580ae4db..81c936bd793f 100644 --- a/drivers/media/IR/ir-core-priv.h +++ b/drivers/media/IR/ir-core-priv.h | |||
@@ -88,6 +88,12 @@ struct ir_raw_event_ctrl { | |||
88 | struct ir_input_dev *ir_dev; | 88 | struct ir_input_dev *ir_dev; |
89 | struct lirc_driver *drv; | 89 | struct lirc_driver *drv; |
90 | int carrier_low; | 90 | int carrier_low; |
91 | |||
92 | ktime_t gap_start; | ||
93 | u64 gap_duration; | ||
94 | bool gap; | ||
95 | bool send_timeout_reports; | ||
96 | |||
91 | } lirc; | 97 | } lirc; |
92 | }; | 98 | }; |
93 | 99 | ||
@@ -115,9 +121,14 @@ static inline void decrease_duration(struct ir_raw_event *ev, unsigned duration) | |||
115 | ev->duration -= duration; | 121 | ev->duration -= duration; |
116 | } | 122 | } |
117 | 123 | ||
124 | /* Returns true if event is normal pulse/space event */ | ||
125 | static inline bool is_timing_event(struct ir_raw_event ev) | ||
126 | { | ||
127 | return !ev.carrier_report && !ev.reset; | ||
128 | } | ||
129 | |||
118 | #define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) | 130 | #define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) |
119 | #define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") | 131 | #define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") |
120 | #define IS_RESET(ev) (ev.duration == 0) | ||
121 | /* | 132 | /* |
122 | * Routines from ir-sysfs.c - Meant to be called only internally inside | 133 | * Routines from ir-sysfs.c - Meant to be called only internally inside |
123 | * ir-core | 134 | * ir-core |
diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c index 77a89c4de014..63dca6e5458b 100644 --- a/drivers/media/IR/ir-jvc-decoder.c +++ b/drivers/media/IR/ir-jvc-decoder.c | |||
@@ -50,8 +50,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
50 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC)) | 50 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC)) |
51 | return 0; | 51 | return 0; |
52 | 52 | ||
53 | if (IS_RESET(ev)) { | 53 | if (!is_timing_event(ev)) { |
54 | data->state = STATE_INACTIVE; | 54 | if (ev.reset) |
55 | data->state = STATE_INACTIVE; | ||
55 | return 0; | 56 | return 0; |
56 | } | 57 | } |
57 | 58 | ||
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c index 20ac9a4ce522..1d9c6b0fd0ea 100644 --- a/drivers/media/IR/ir-lirc-codec.c +++ b/drivers/media/IR/ir-lirc-codec.c | |||
@@ -32,6 +32,7 @@ | |||
32 | static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) | 32 | static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) |
33 | { | 33 | { |
34 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); | 34 | struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); |
35 | struct lirc_codec *lirc = &ir_dev->raw->lirc; | ||
35 | int sample; | 36 | int sample; |
36 | 37 | ||
37 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC)) | 38 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC)) |
@@ -40,21 +41,57 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
40 | if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf) | 41 | if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf) |
41 | return -EINVAL; | 42 | return -EINVAL; |
42 | 43 | ||
43 | if (IS_RESET(ev)) | 44 | /* Packet start */ |
45 | if (ev.reset) | ||
44 | return 0; | 46 | return 0; |
45 | 47 | ||
46 | IR_dprintk(2, "LIRC data transfer started (%uus %s)\n", | 48 | /* Carrier reports */ |
47 | TO_US(ev.duration), TO_STR(ev.pulse)); | 49 | if (ev.carrier_report) { |
50 | sample = LIRC_FREQUENCY(ev.carrier); | ||
51 | |||
52 | /* Packet end */ | ||
53 | } else if (ev.timeout) { | ||
54 | |||
55 | if (lirc->gap) | ||
56 | return 0; | ||
57 | |||
58 | lirc->gap_start = ktime_get(); | ||
59 | lirc->gap = true; | ||
60 | lirc->gap_duration = ev.duration; | ||
61 | |||
62 | if (!lirc->send_timeout_reports) | ||
63 | return 0; | ||
64 | |||
65 | sample = LIRC_TIMEOUT(ev.duration / 1000); | ||
48 | 66 | ||
49 | sample = ev.duration / 1000; | 67 | /* Normal sample */ |
50 | if (ev.pulse) | 68 | } else { |
51 | sample |= PULSE_BIT; | 69 | |
70 | if (lirc->gap) { | ||
71 | int gap_sample; | ||
72 | |||
73 | lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(), | ||
74 | lirc->gap_start)); | ||
75 | |||
76 | /* Convert to ms and cap by LIRC_VALUE_MASK */ | ||
77 | do_div(lirc->gap_duration, 1000); | ||
78 | lirc->gap_duration = min(lirc->gap_duration, | ||
79 | (u64)LIRC_VALUE_MASK); | ||
80 | |||
81 | gap_sample = LIRC_SPACE(lirc->gap_duration); | ||
82 | lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, | ||
83 | (unsigned char *) &gap_sample); | ||
84 | lirc->gap = false; | ||
85 | } | ||
86 | |||
87 | sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) : | ||
88 | LIRC_SPACE(ev.duration / 1000); | ||
89 | } | ||
52 | 90 | ||
53 | lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, | 91 | lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf, |
54 | (unsigned char *) &sample); | 92 | (unsigned char *) &sample); |
55 | wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll); | 93 | wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll); |
56 | 94 | ||
57 | |||
58 | return 0; | 95 | return 0; |
59 | } | 96 | } |
60 | 97 | ||
@@ -102,7 +139,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
102 | struct ir_input_dev *ir_dev; | 139 | struct ir_input_dev *ir_dev; |
103 | int ret = 0; | 140 | int ret = 0; |
104 | void *drv_data; | 141 | void *drv_data; |
105 | __u32 val = 0; | 142 | __u32 val = 0, tmp; |
106 | 143 | ||
107 | lirc = lirc_get_pdata(filep); | 144 | lirc = lirc_get_pdata(filep); |
108 | if (!lirc) | 145 | if (!lirc) |
@@ -130,22 +167,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
130 | case LIRC_SET_SEND_MODE: | 167 | case LIRC_SET_SEND_MODE: |
131 | if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) | 168 | if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK)) |
132 | return -EINVAL; | 169 | return -EINVAL; |
133 | break; | 170 | return 0; |
134 | 171 | ||
135 | /* TX settings */ | 172 | /* TX settings */ |
136 | case LIRC_SET_TRANSMITTER_MASK: | 173 | case LIRC_SET_TRANSMITTER_MASK: |
137 | if (ir_dev->props->s_tx_mask) | 174 | if (!ir_dev->props->s_tx_mask) |
138 | ret = ir_dev->props->s_tx_mask(drv_data, val); | ||
139 | else | ||
140 | return -EINVAL; | 175 | return -EINVAL; |
141 | break; | 176 | |
177 | return ir_dev->props->s_tx_mask(drv_data, val); | ||
142 | 178 | ||
143 | case LIRC_SET_SEND_CARRIER: | 179 | case LIRC_SET_SEND_CARRIER: |
144 | if (ir_dev->props->s_tx_carrier) | 180 | if (!ir_dev->props->s_tx_carrier) |
145 | ir_dev->props->s_tx_carrier(drv_data, val); | ||
146 | else | ||
147 | return -EINVAL; | 181 | return -EINVAL; |
148 | break; | 182 | |
183 | return ir_dev->props->s_tx_carrier(drv_data, val); | ||
149 | 184 | ||
150 | case LIRC_SET_SEND_DUTY_CYCLE: | 185 | case LIRC_SET_SEND_DUTY_CYCLE: |
151 | if (!ir_dev->props->s_tx_duty_cycle) | 186 | if (!ir_dev->props->s_tx_duty_cycle) |
@@ -154,39 +189,42 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
154 | if (val <= 0 || val >= 100) | 189 | if (val <= 0 || val >= 100) |
155 | return -EINVAL; | 190 | return -EINVAL; |
156 | 191 | ||
157 | ir_dev->props->s_tx_duty_cycle(ir_dev->props->priv, val); | 192 | return ir_dev->props->s_tx_duty_cycle(drv_data, val); |
158 | break; | ||
159 | 193 | ||
160 | /* RX settings */ | 194 | /* RX settings */ |
161 | case LIRC_SET_REC_CARRIER: | 195 | case LIRC_SET_REC_CARRIER: |
162 | if (ir_dev->props->s_rx_carrier_range) | 196 | if (!ir_dev->props->s_rx_carrier_range) |
163 | ret = ir_dev->props->s_rx_carrier_range( | ||
164 | ir_dev->props->priv, | ||
165 | ir_dev->raw->lirc.carrier_low, val); | ||
166 | else | ||
167 | return -ENOSYS; | 197 | return -ENOSYS; |
168 | 198 | ||
169 | if (!ret) | 199 | if (val <= 0) |
170 | ir_dev->raw->lirc.carrier_low = 0; | 200 | return -EINVAL; |
171 | break; | 201 | |
202 | return ir_dev->props->s_rx_carrier_range(drv_data, | ||
203 | ir_dev->raw->lirc.carrier_low, val); | ||
172 | 204 | ||
173 | case LIRC_SET_REC_CARRIER_RANGE: | 205 | case LIRC_SET_REC_CARRIER_RANGE: |
174 | if (val >= 0) | 206 | if (val <= 0) |
175 | ir_dev->raw->lirc.carrier_low = val; | 207 | return -EINVAL; |
176 | break; | ||
177 | 208 | ||
209 | ir_dev->raw->lirc.carrier_low = val; | ||
210 | return 0; | ||
178 | 211 | ||
179 | case LIRC_GET_REC_RESOLUTION: | 212 | case LIRC_GET_REC_RESOLUTION: |
180 | val = ir_dev->props->rx_resolution; | 213 | val = ir_dev->props->rx_resolution; |
181 | break; | 214 | break; |
182 | 215 | ||
183 | case LIRC_SET_WIDEBAND_RECEIVER: | 216 | case LIRC_SET_WIDEBAND_RECEIVER: |
184 | if (ir_dev->props->s_learning_mode) | 217 | if (!ir_dev->props->s_learning_mode) |
185 | return ir_dev->props->s_learning_mode( | ||
186 | ir_dev->props->priv, !!val); | ||
187 | else | ||
188 | return -ENOSYS; | 218 | return -ENOSYS; |
189 | 219 | ||
220 | return ir_dev->props->s_learning_mode(drv_data, !!val); | ||
221 | |||
222 | case LIRC_SET_MEASURE_CARRIER_MODE: | ||
223 | if (!ir_dev->props->s_carrier_report) | ||
224 | return -ENOSYS; | ||
225 | |||
226 | return ir_dev->props->s_carrier_report(drv_data, !!val); | ||
227 | |||
190 | /* Generic timeout support */ | 228 | /* Generic timeout support */ |
191 | case LIRC_GET_MIN_TIMEOUT: | 229 | case LIRC_GET_MIN_TIMEOUT: |
192 | if (!ir_dev->props->max_timeout) | 230 | if (!ir_dev->props->max_timeout) |
@@ -201,10 +239,20 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, | |||
201 | break; | 239 | break; |
202 | 240 | ||
203 | case LIRC_SET_REC_TIMEOUT: | 241 | case LIRC_SET_REC_TIMEOUT: |
204 | if (val < ir_dev->props->min_timeout || | 242 | if (!ir_dev->props->max_timeout) |
205 | val > ir_dev->props->max_timeout) | 243 | return -ENOSYS; |
206 | return -EINVAL; | 244 | |
207 | ir_dev->props->timeout = val * 1000; | 245 | tmp = val * 1000; |
246 | |||
247 | if (tmp < ir_dev->props->min_timeout || | ||
248 | tmp > ir_dev->props->max_timeout) | ||
249 | return -EINVAL; | ||
250 | |||
251 | ir_dev->props->timeout = tmp; | ||
252 | break; | ||
253 | |||
254 | case LIRC_SET_REC_TIMEOUT_REPORTS: | ||
255 | lirc->send_timeout_reports = !!val; | ||
208 | break; | 256 | break; |
209 | 257 | ||
210 | default: | 258 | default: |
@@ -280,6 +328,10 @@ static int ir_lirc_register(struct input_dev *input_dev) | |||
280 | if (ir_dev->props->s_learning_mode) | 328 | if (ir_dev->props->s_learning_mode) |
281 | features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; | 329 | features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; |
282 | 330 | ||
331 | if (ir_dev->props->s_carrier_report) | ||
332 | features |= LIRC_CAN_MEASURE_CARRIER; | ||
333 | |||
334 | |||
283 | if (ir_dev->props->max_timeout) | 335 | if (ir_dev->props->max_timeout) |
284 | features |= LIRC_CAN_SET_REC_TIMEOUT; | 336 | features |= LIRC_CAN_SET_REC_TIMEOUT; |
285 | 337 | ||
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c index d597421d6547..70993f79c8a2 100644 --- a/drivers/media/IR/ir-nec-decoder.c +++ b/drivers/media/IR/ir-nec-decoder.c | |||
@@ -54,8 +54,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
54 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC)) | 54 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC)) |
55 | return 0; | 55 | return 0; |
56 | 56 | ||
57 | if (IS_RESET(ev)) { | 57 | if (!is_timing_event(ev)) { |
58 | data->state = STATE_INACTIVE; | 58 | if (ev.reset) |
59 | data->state = STATE_INACTIVE; | ||
59 | return 0; | 60 | return 0; |
60 | } | 61 | } |
61 | 62 | ||
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index 119b567feeab..0d59ef7d1014 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c | |||
@@ -174,7 +174,7 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev, | |||
174 | if (ir->idle && !ev->pulse) | 174 | if (ir->idle && !ev->pulse) |
175 | return 0; | 175 | return 0; |
176 | else if (ir->idle) | 176 | else if (ir->idle) |
177 | ir_raw_event_set_idle(input_dev, 0); | 177 | ir_raw_event_set_idle(input_dev, false); |
178 | 178 | ||
179 | if (!raw->this_ev.duration) { | 179 | if (!raw->this_ev.duration) { |
180 | raw->this_ev = *ev; | 180 | raw->this_ev = *ev; |
@@ -187,48 +187,35 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev, | |||
187 | 187 | ||
188 | /* Enter idle mode if nessesary */ | 188 | /* Enter idle mode if nessesary */ |
189 | if (!ev->pulse && ir->props->timeout && | 189 | if (!ev->pulse && ir->props->timeout && |
190 | raw->this_ev.duration >= ir->props->timeout) | 190 | raw->this_ev.duration >= ir->props->timeout) { |
191 | ir_raw_event_set_idle(input_dev, 1); | 191 | ir_raw_event_set_idle(input_dev, true); |
192 | } | ||
192 | return 0; | 193 | return 0; |
193 | } | 194 | } |
194 | EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); | 195 | EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); |
195 | 196 | ||
196 | void ir_raw_event_set_idle(struct input_dev *input_dev, int idle) | 197 | /** |
198 | * ir_raw_event_set_idle() - hint the ir core if device is receiving | ||
199 | * IR data or not | ||
200 | * @input_dev: the struct input_dev device descriptor | ||
201 | * @idle: the hint value | ||
202 | */ | ||
203 | void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle) | ||
197 | { | 204 | { |
198 | struct ir_input_dev *ir = input_get_drvdata(input_dev); | 205 | struct ir_input_dev *ir = input_get_drvdata(input_dev); |
199 | struct ir_raw_event_ctrl *raw = ir->raw; | 206 | struct ir_raw_event_ctrl *raw = ir->raw; |
200 | ktime_t now; | ||
201 | u64 delta; | ||
202 | 207 | ||
203 | if (!ir->props) | 208 | if (!ir->props || !ir->raw) |
204 | return; | 209 | return; |
205 | 210 | ||
206 | if (!ir->raw) | 211 | IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); |
207 | goto out; | ||
208 | 212 | ||
209 | if (idle) { | 213 | if (idle) { |
210 | IR_dprintk(2, "enter idle mode\n"); | 214 | raw->this_ev.timeout = true; |
211 | raw->last_event = ktime_get(); | ||
212 | } else { | ||
213 | IR_dprintk(2, "exit idle mode\n"); | ||
214 | |||
215 | now = ktime_get(); | ||
216 | delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event)); | ||
217 | |||
218 | WARN_ON(raw->this_ev.pulse); | ||
219 | |||
220 | raw->this_ev.duration = | ||
221 | min(raw->this_ev.duration + delta, | ||
222 | (u64)IR_MAX_DURATION); | ||
223 | |||
224 | ir_raw_event_store(input_dev, &raw->this_ev); | 215 | ir_raw_event_store(input_dev, &raw->this_ev); |
225 | 216 | init_ir_raw_event(&raw->this_ev); | |
226 | if (raw->this_ev.duration == IR_MAX_DURATION) | ||
227 | ir_raw_event_reset(input_dev); | ||
228 | |||
229 | raw->this_ev.duration = 0; | ||
230 | } | 217 | } |
231 | out: | 218 | |
232 | if (ir->props->s_idle) | 219 | if (ir->props->s_idle) |
233 | ir->props->s_idle(ir->props->priv, idle); | 220 | ir->props->s_idle(ir->props->priv, idle); |
234 | ir->idle = idle; | 221 | ir->idle = idle; |
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c index df4770d978ad..572ed4ca8c68 100644 --- a/drivers/media/IR/ir-rc5-decoder.c +++ b/drivers/media/IR/ir-rc5-decoder.c | |||
@@ -55,8 +55,9 @@ static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
55 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5)) | 55 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5)) |
56 | return 0; | 56 | return 0; |
57 | 57 | ||
58 | if (IS_RESET(ev)) { | 58 | if (!is_timing_event(ev)) { |
59 | data->state = STATE_INACTIVE; | 59 | if (ev.reset) |
60 | data->state = STATE_INACTIVE; | ||
60 | return 0; | 61 | return 0; |
61 | } | 62 | } |
62 | 63 | ||
diff --git a/drivers/media/IR/ir-rc5-sz-decoder.c b/drivers/media/IR/ir-rc5-sz-decoder.c index 68f11d6acd5b..7c413501a3f7 100644 --- a/drivers/media/IR/ir-rc5-sz-decoder.c +++ b/drivers/media/IR/ir-rc5-sz-decoder.c | |||
@@ -51,8 +51,9 @@ static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
51 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ)) | 51 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ)) |
52 | return 0; | 52 | return 0; |
53 | 53 | ||
54 | if (IS_RESET(ev)) { | 54 | if (!is_timing_event(ev)) { |
55 | data->state = STATE_INACTIVE; | 55 | if (ev.reset) |
56 | data->state = STATE_INACTIVE; | ||
56 | return 0; | 57 | return 0; |
57 | } | 58 | } |
58 | 59 | ||
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c index f1624b8279bc..d25da91f44ff 100644 --- a/drivers/media/IR/ir-rc6-decoder.c +++ b/drivers/media/IR/ir-rc6-decoder.c | |||
@@ -85,8 +85,9 @@ static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
85 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) | 85 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) |
86 | return 0; | 86 | return 0; |
87 | 87 | ||
88 | if (IS_RESET(ev)) { | 88 | if (!is_timing_event(ev)) { |
89 | data->state = STATE_INACTIVE; | 89 | if (ev.reset) |
90 | data->state = STATE_INACTIVE; | ||
90 | return 0; | 91 | return 0; |
91 | } | 92 | } |
92 | 93 | ||
diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/IR/ir-sony-decoder.c index b9074f07c7a0..2d15730822bc 100644 --- a/drivers/media/IR/ir-sony-decoder.c +++ b/drivers/media/IR/ir-sony-decoder.c | |||
@@ -48,8 +48,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev) | |||
48 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY)) | 48 | if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY)) |
49 | return 0; | 49 | return 0; |
50 | 50 | ||
51 | if (IS_RESET(ev)) { | 51 | if (!is_timing_event(ev)) { |
52 | data->state = STATE_INACTIVE; | 52 | if (ev.reset) |
53 | data->state = STATE_INACTIVE; | ||
53 | return 0; | 54 | return 0; |
54 | } | 55 | } |
55 | 56 | ||
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index bc620e10ef77..6825da5771f6 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c | |||
@@ -660,7 +660,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) | |||
660 | 660 | ||
661 | static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | 661 | static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) |
662 | { | 662 | { |
663 | struct ir_raw_event rawir = { .pulse = false, .duration = 0 }; | 663 | DEFINE_IR_RAW_EVENT(rawir); |
664 | int i, start_index = 0; | 664 | int i, start_index = 0; |
665 | u8 hdr = MCE_CONTROL_HEADER; | 665 | u8 hdr = MCE_CONTROL_HEADER; |
666 | 666 | ||
@@ -997,6 +997,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
997 | ir->len_in = maxp; | 997 | ir->len_in = maxp; |
998 | ir->flags.microsoft_gen1 = is_microsoft_gen1; | 998 | ir->flags.microsoft_gen1 = is_microsoft_gen1; |
999 | ir->flags.tx_mask_inverted = tx_mask_inverted; | 999 | ir->flags.tx_mask_inverted = tx_mask_inverted; |
1000 | init_ir_raw_event(&ir->rawir); | ||
1000 | 1001 | ||
1001 | /* Saving usb interface data for use by the transmitter routine */ | 1002 | /* Saving usb interface data for use by the transmitter routine */ |
1002 | ir->usb_ep_in = ep_in; | 1003 | ir->usb_ep_in = ep_in; |
diff --git a/drivers/media/IR/nuvoton-cir.c b/drivers/media/IR/nuvoton-cir.c index 2f0f78078b57..301be53aee85 100644 --- a/drivers/media/IR/nuvoton-cir.c +++ b/drivers/media/IR/nuvoton-cir.c | |||
@@ -586,7 +586,7 @@ static void nvt_dump_rx_buf(struct nvt_dev *nvt) | |||
586 | */ | 586 | */ |
587 | static void nvt_process_rx_ir_data(struct nvt_dev *nvt) | 587 | static void nvt_process_rx_ir_data(struct nvt_dev *nvt) |
588 | { | 588 | { |
589 | struct ir_raw_event rawir = { .pulse = false, .duration = 0 }; | 589 | DEFINE_IR_RAW_EVENT(rawir); |
590 | unsigned int count; | 590 | unsigned int count; |
591 | u32 carrier; | 591 | u32 carrier; |
592 | u8 sample; | 592 | u8 sample; |
@@ -622,6 +622,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) | |||
622 | } | 622 | } |
623 | 623 | ||
624 | rawir.duration += nvt->rawir.duration; | 624 | rawir.duration += nvt->rawir.duration; |
625 | |||
626 | init_ir_raw_event(&nvt->rawir); | ||
625 | nvt->rawir.duration = 0; | 627 | nvt->rawir.duration = 0; |
626 | nvt->rawir.pulse = rawir.pulse; | 628 | nvt->rawir.pulse = rawir.pulse; |
627 | 629 | ||
@@ -1016,6 +1018,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) | |||
1016 | 1018 | ||
1017 | spin_lock_init(&nvt->nvt_lock); | 1019 | spin_lock_init(&nvt->nvt_lock); |
1018 | spin_lock_init(&nvt->tx.lock); | 1020 | spin_lock_init(&nvt->tx.lock); |
1021 | init_ir_raw_event(&nvt->rawir); | ||
1019 | 1022 | ||
1020 | ret = -EBUSY; | 1023 | ret = -EBUSY; |
1021 | /* now claim resources */ | 1024 | /* now claim resources */ |
diff --git a/drivers/media/IR/streamzap.c b/drivers/media/IR/streamzap.c index 86a4f68feea4..548381c35bfd 100644 --- a/drivers/media/IR/streamzap.c +++ b/drivers/media/IR/streamzap.c | |||
@@ -146,7 +146,7 @@ static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir) | |||
146 | static void sz_push_full_pulse(struct streamzap_ir *sz, | 146 | static void sz_push_full_pulse(struct streamzap_ir *sz, |
147 | unsigned char value) | 147 | unsigned char value) |
148 | { | 148 | { |
149 | struct ir_raw_event rawir; | 149 | DEFINE_IR_RAW_EVENT(rawir); |
150 | 150 | ||
151 | if (sz->idle) { | 151 | if (sz->idle) { |
152 | long deltv; | 152 | long deltv; |
@@ -193,7 +193,7 @@ static void sz_push_half_pulse(struct streamzap_ir *sz, | |||
193 | static void sz_push_full_space(struct streamzap_ir *sz, | 193 | static void sz_push_full_space(struct streamzap_ir *sz, |
194 | unsigned char value) | 194 | unsigned char value) |
195 | { | 195 | { |
196 | struct ir_raw_event rawir; | 196 | DEFINE_IR_RAW_EVENT(rawir); |
197 | 197 | ||
198 | rawir.pulse = false; | 198 | rawir.pulse = false; |
199 | rawir.duration = ((int) value) * SZ_RESOLUTION; | 199 | rawir.duration = ((int) value) * SZ_RESOLUTION; |
@@ -270,7 +270,7 @@ static void streamzap_callback(struct urb *urb) | |||
270 | break; | 270 | break; |
271 | case FullSpace: | 271 | case FullSpace: |
272 | if (sz->buf_in[i] == SZ_TIMEOUT) { | 272 | if (sz->buf_in[i] == SZ_TIMEOUT) { |
273 | struct ir_raw_event rawir; | 273 | DEFINE_IR_RAW_EVENT(rawir); |
274 | 274 | ||
275 | rawir.pulse = false; | 275 | rawir.pulse = false; |
276 | rawir.duration = timeout; | 276 | rawir.duration = timeout; |
diff --git a/include/media/ir-core.h b/include/media/ir-core.h index 4dd43d44ec5e..6dc37fae6606 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h | |||
@@ -60,6 +60,7 @@ enum rc_driver_type { | |||
60 | * @s_idle: optional: enable/disable hardware idle mode, upon which, | 60 | * @s_idle: optional: enable/disable hardware idle mode, upon which, |
61 | device doesn't interrupt host until it sees IR pulses | 61 | device doesn't interrupt host until it sees IR pulses |
62 | * @s_learning_mode: enable wide band receiver used for learning | 62 | * @s_learning_mode: enable wide band receiver used for learning |
63 | * @s_carrier_report: enable carrier reports | ||
63 | */ | 64 | */ |
64 | struct ir_dev_props { | 65 | struct ir_dev_props { |
65 | enum rc_driver_type driver_type; | 66 | enum rc_driver_type driver_type; |
@@ -82,8 +83,9 @@ struct ir_dev_props { | |||
82 | int (*s_tx_duty_cycle)(void *priv, u32 duty_cycle); | 83 | int (*s_tx_duty_cycle)(void *priv, u32 duty_cycle); |
83 | int (*s_rx_carrier_range)(void *priv, u32 min, u32 max); | 84 | int (*s_rx_carrier_range)(void *priv, u32 min, u32 max); |
84 | int (*tx_ir)(void *priv, int *txbuf, u32 n); | 85 | int (*tx_ir)(void *priv, int *txbuf, u32 n); |
85 | void (*s_idle)(void *priv, int enable); | 86 | void (*s_idle)(void *priv, bool enable); |
86 | int (*s_learning_mode)(void *priv, int enable); | 87 | int (*s_learning_mode)(void *priv, int enable); |
88 | int (*s_carrier_report) (void *priv, int enable); | ||
87 | }; | 89 | }; |
88 | 90 | ||
89 | struct ir_input_dev { | 91 | struct ir_input_dev { |
@@ -163,22 +165,48 @@ u32 ir_g_keycode_from_table(struct input_dev *input_dev, u32 scancode); | |||
163 | /* From ir-raw-event.c */ | 165 | /* From ir-raw-event.c */ |
164 | 166 | ||
165 | struct ir_raw_event { | 167 | struct ir_raw_event { |
166 | unsigned pulse:1; | 168 | union { |
167 | unsigned duration:31; | 169 | u32 duration; |
170 | |||
171 | struct { | ||
172 | u32 carrier; | ||
173 | u8 duty_cycle; | ||
174 | }; | ||
175 | }; | ||
176 | |||
177 | unsigned pulse:1; | ||
178 | unsigned reset:1; | ||
179 | unsigned timeout:1; | ||
180 | unsigned carrier_report:1; | ||
168 | }; | 181 | }; |
169 | 182 | ||
170 | #define IR_MAX_DURATION 0x7FFFFFFF /* a bit more than 2 seconds */ | 183 | #define DEFINE_IR_RAW_EVENT(event) \ |
184 | struct ir_raw_event event = { \ | ||
185 | { .duration = 0 } , \ | ||
186 | .pulse = 0, \ | ||
187 | .reset = 0, \ | ||
188 | .timeout = 0, \ | ||
189 | .carrier_report = 0 } | ||
190 | |||
191 | static inline void init_ir_raw_event(struct ir_raw_event *ev) | ||
192 | { | ||
193 | memset(ev, 0, sizeof(*ev)); | ||
194 | } | ||
195 | |||
196 | #define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */ | ||
171 | 197 | ||
172 | void ir_raw_event_handle(struct input_dev *input_dev); | 198 | void ir_raw_event_handle(struct input_dev *input_dev); |
173 | int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev); | 199 | int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev); |
174 | int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type); | 200 | int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type); |
175 | int ir_raw_event_store_with_filter(struct input_dev *input_dev, | 201 | int ir_raw_event_store_with_filter(struct input_dev *input_dev, |
176 | struct ir_raw_event *ev); | 202 | struct ir_raw_event *ev); |
177 | void ir_raw_event_set_idle(struct input_dev *input_dev, int idle); | 203 | void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle); |
178 | 204 | ||
179 | static inline void ir_raw_event_reset(struct input_dev *input_dev) | 205 | static inline void ir_raw_event_reset(struct input_dev *input_dev) |
180 | { | 206 | { |
181 | struct ir_raw_event ev = { .pulse = false, .duration = 0 }; | 207 | DEFINE_IR_RAW_EVENT(ev); |
208 | ev.reset = true; | ||
209 | |||
182 | ir_raw_event_store(input_dev, &ev); | 210 | ir_raw_event_store(input_dev, &ev); |
183 | ir_raw_event_handle(input_dev); | 211 | ir_raw_event_handle(input_dev); |
184 | } | 212 | } |