aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2010-10-16 18:56:28 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-21 08:59:47 -0400
commit4651918a4afdd49bdea21d2f919b189ef17a6399 (patch)
tree73a4e3b5f7da1d655a059bb9b69135cf6f395e02
parentfb249ca61d469a9cb666ba7e1d992787dc6bad82 (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.c4
-rw-r--r--drivers/media/IR/ir-core-priv.h13
-rw-r--r--drivers/media/IR/ir-jvc-decoder.c5
-rw-r--r--drivers/media/IR/ir-lirc-codec.c128
-rw-r--r--drivers/media/IR/ir-nec-decoder.c5
-rw-r--r--drivers/media/IR/ir-raw-event.c45
-rw-r--r--drivers/media/IR/ir-rc5-decoder.c5
-rw-r--r--drivers/media/IR/ir-rc5-sz-decoder.c5
-rw-r--r--drivers/media/IR/ir-rc6-decoder.c5
-rw-r--r--drivers/media/IR/ir-sony-decoder.c5
-rw-r--r--drivers/media/IR/mceusb.c3
-rw-r--r--drivers/media/IR/nuvoton-cir.c5
-rw-r--r--drivers/media/IR/streamzap.c6
-rw-r--r--include/media/ir-core.h40
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 */
901static void ene_rx_set_idle(void *data, int idle) 901static 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 */
125static 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 @@
32static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev) 32static 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}
194EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); 195EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
195 196
196void 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 */
203void 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 }
231out: 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
661static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) 661static 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 */
587static void nvt_process_rx_ir_data(struct nvt_dev *nvt) 587static 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)
146static void sz_push_full_pulse(struct streamzap_ir *sz, 146static 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,
193static void sz_push_full_space(struct streamzap_ir *sz, 193static 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 */
64struct ir_dev_props { 65struct 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
89struct ir_input_dev { 91struct 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
165struct ir_raw_event { 167struct 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
191static 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
172void ir_raw_event_handle(struct input_dev *input_dev); 198void ir_raw_event_handle(struct input_dev *input_dev);
173int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev); 199int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev);
174int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type); 200int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
175int ir_raw_event_store_with_filter(struct input_dev *input_dev, 201int ir_raw_event_store_with_filter(struct input_dev *input_dev,
176 struct ir_raw_event *ev); 202 struct ir_raw_event *ev);
177void ir_raw_event_set_idle(struct input_dev *input_dev, int idle); 203void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle);
178 204
179static inline void ir_raw_event_reset(struct input_dev *input_dev) 205static 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}