aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/ir-raw-event.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/IR/ir-raw-event.c')
-rw-r--r--drivers/media/IR/ir-raw-event.c81
1 files changed, 42 insertions, 39 deletions
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index 8e0e1b1f8c87..a06a07e4e0b1 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -39,22 +39,34 @@ static int ir_raw_event_thread(void *data)
39 struct ir_raw_event ev; 39 struct ir_raw_event ev;
40 struct ir_raw_handler *handler; 40 struct ir_raw_handler *handler;
41 struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; 41 struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data;
42 int retval;
42 43
43 while (!kthread_should_stop()) { 44 while (!kthread_should_stop()) {
44 try_to_freeze();
45 45
46 mutex_lock(&ir_raw_handler_lock); 46 spin_lock_irq(&raw->lock);
47 retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev));
48
49 if (!retval) {
50 set_current_state(TASK_INTERRUPTIBLE);
51
52 if (kthread_should_stop())
53 set_current_state(TASK_RUNNING);
47 54
48 while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) { 55 spin_unlock_irq(&raw->lock);
49 list_for_each_entry(handler, &ir_raw_handler_list, list) 56 schedule();
50 handler->decode(raw->input_dev, ev); 57 continue;
51 raw->prev_ev = ev;
52 } 58 }
53 59
54 mutex_unlock(&ir_raw_handler_lock); 60 spin_unlock_irq(&raw->lock);
61
55 62
56 set_current_state(TASK_INTERRUPTIBLE); 63 BUG_ON(retval != sizeof(ev));
57 schedule(); 64
65 mutex_lock(&ir_raw_handler_lock);
66 list_for_each_entry(handler, &ir_raw_handler_list, list)
67 handler->decode(raw->input_dev, ev);
68 raw->prev_ev = ev;
69 mutex_unlock(&ir_raw_handler_lock);
58 } 70 }
59 71
60 return 0; 72 return 0;
@@ -77,7 +89,7 @@ int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
77 if (!ir->raw) 89 if (!ir->raw)
78 return -EINVAL; 90 return -EINVAL;
79 91
80 IR_dprintk(2, "sample: (05%dus %s)\n", 92 IR_dprintk(2, "sample: (%05dus %s)\n",
81 TO_US(ev->duration), TO_STR(ev->pulse)); 93 TO_US(ev->duration), TO_STR(ev->pulse));
82 94
83 if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev)) 95 if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
@@ -162,7 +174,7 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev,
162 if (ir->idle && !ev->pulse) 174 if (ir->idle && !ev->pulse)
163 return 0; 175 return 0;
164 else if (ir->idle) 176 else if (ir->idle)
165 ir_raw_event_set_idle(input_dev, 0); 177 ir_raw_event_set_idle(input_dev, false);
166 178
167 if (!raw->this_ev.duration) { 179 if (!raw->this_ev.duration) {
168 raw->this_ev = *ev; 180 raw->this_ev = *ev;
@@ -175,48 +187,35 @@ int ir_raw_event_store_with_filter(struct input_dev *input_dev,
175 187
176 /* Enter idle mode if nessesary */ 188 /* Enter idle mode if nessesary */
177 if (!ev->pulse && ir->props->timeout && 189 if (!ev->pulse && ir->props->timeout &&
178 raw->this_ev.duration >= ir->props->timeout) 190 raw->this_ev.duration >= ir->props->timeout) {
179 ir_raw_event_set_idle(input_dev, 1); 191 ir_raw_event_set_idle(input_dev, true);
192 }
180 return 0; 193 return 0;
181} 194}
182EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); 195EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
183 196
184void 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)
185{ 204{
186 struct ir_input_dev *ir = input_get_drvdata(input_dev); 205 struct ir_input_dev *ir = input_get_drvdata(input_dev);
187 struct ir_raw_event_ctrl *raw = ir->raw; 206 struct ir_raw_event_ctrl *raw = ir->raw;
188 ktime_t now;
189 u64 delta;
190 207
191 if (!ir->props) 208 if (!ir->props || !ir->raw)
192 return; 209 return;
193 210
194 if (!ir->raw) 211 IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");
195 goto out;
196 212
197 if (idle) { 213 if (idle) {
198 IR_dprintk(2, "enter idle mode\n"); 214 raw->this_ev.timeout = true;
199 raw->last_event = ktime_get();
200 } else {
201 IR_dprintk(2, "exit idle mode\n");
202
203 now = ktime_get();
204 delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
205
206 WARN_ON(raw->this_ev.pulse);
207
208 raw->this_ev.duration =
209 min(raw->this_ev.duration + delta,
210 (u64)IR_MAX_DURATION);
211
212 ir_raw_event_store(input_dev, &raw->this_ev); 215 ir_raw_event_store(input_dev, &raw->this_ev);
213 216 init_ir_raw_event(&raw->this_ev);
214 if (raw->this_ev.duration == IR_MAX_DURATION)
215 ir_raw_event_reset(input_dev);
216
217 raw->this_ev.duration = 0;
218 } 217 }
219out: 218
220 if (ir->props->s_idle) 219 if (ir->props->s_idle)
221 ir->props->s_idle(ir->props->priv, idle); 220 ir->props->s_idle(ir->props->priv, idle);
222 ir->idle = idle; 221 ir->idle = idle;
@@ -232,11 +231,14 @@ EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
232void ir_raw_event_handle(struct input_dev *input_dev) 231void ir_raw_event_handle(struct input_dev *input_dev)
233{ 232{
234 struct ir_input_dev *ir = input_get_drvdata(input_dev); 233 struct ir_input_dev *ir = input_get_drvdata(input_dev);
234 unsigned long flags;
235 235
236 if (!ir->raw) 236 if (!ir->raw)
237 return; 237 return;
238 238
239 spin_lock_irqsave(&ir->raw->lock, flags);
239 wake_up_process(ir->raw->thread); 240 wake_up_process(ir->raw->thread);
241 spin_unlock_irqrestore(&ir->raw->lock, flags);
240} 242}
241EXPORT_SYMBOL_GPL(ir_raw_event_handle); 243EXPORT_SYMBOL_GPL(ir_raw_event_handle);
242 244
@@ -275,6 +277,7 @@ int ir_raw_event_register(struct input_dev *input_dev)
275 return rc; 277 return rc;
276 } 278 }
277 279
280 spin_lock_init(&ir->raw->lock);
278 ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw, 281 ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw,
279 "rc%u", (unsigned int)ir->devno); 282 "rc%u", (unsigned int)ir->devno);
280 283