V4L/DVB: ir-core: change duration to be coded as a u32 integer
[safe/jmp/linux-2.6] / drivers / media / IR / ir-raw-event.c
1 /* ir-raw-event.c - handle IR Pulse/Space event
2  *
3  * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation version 2 of the License.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  */
14
15 #include <linux/workqueue.h>
16 #include <linux/spinlock.h>
17 #include <linux/sched.h>
18 #include "ir-core-priv.h"
19
20 /* Define the max number of pulse/space transitions to buffer */
21 #define MAX_IR_EVENT_SIZE      512
22
23 /* Used to handle IR raw handler extensions */
24 static LIST_HEAD(ir_raw_handler_list);
25 static DEFINE_SPINLOCK(ir_raw_handler_lock);
26
27 /**
28  * RUN_DECODER()        - runs an operation on all IR decoders
29  * @ops:        IR raw handler operation to be called
30  * @arg:        arguments to be passed to the callback
31  *
32  * Calls ir_raw_handler::ops for all registered IR handlers. It prevents
33  * new decode addition/removal while running, by locking ir_raw_handler_lock
34  * mutex. If an error occurs, it stops the ops. Otherwise, it returns a sum
35  * of the return codes.
36  */
37 #define RUN_DECODER(ops, ...) ({                                            \
38         struct ir_raw_handler           *_ir_raw_handler;                   \
39         int _sumrc = 0, _rc;                                                \
40         spin_lock(&ir_raw_handler_lock);                                    \
41         list_for_each_entry(_ir_raw_handler, &ir_raw_handler_list, list) {  \
42                 if (_ir_raw_handler->ops) {                                 \
43                         _rc = _ir_raw_handler->ops(__VA_ARGS__);            \
44                         if (_rc < 0)                                        \
45                                 break;                                      \
46                         _sumrc += _rc;                                      \
47                 }                                                           \
48         }                                                                   \
49         spin_unlock(&ir_raw_handler_lock);                                  \
50         _sumrc;                                                             \
51 })
52
53 #ifdef MODULE
54 /* Used to load the decoders */
55 static struct work_struct wq_load;
56 #endif
57
58 static void ir_raw_event_work(struct work_struct *work)
59 {
60         struct ir_raw_event ev;
61         struct ir_raw_event_ctrl *raw =
62                 container_of(work, struct ir_raw_event_ctrl, rx_work);
63
64         while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev))
65                 RUN_DECODER(decode, raw->input_dev, ev);
66 }
67
68 int ir_raw_event_register(struct input_dev *input_dev)
69 {
70         struct ir_input_dev *ir = input_get_drvdata(input_dev);
71         int rc;
72
73         ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
74         if (!ir->raw)
75                 return -ENOMEM;
76
77         ir->raw->input_dev = input_dev;
78         INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
79
80         rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
81                          GFP_KERNEL);
82         if (rc < 0) {
83                 kfree(ir->raw);
84                 ir->raw = NULL;
85                 return rc;
86         }
87
88         rc = RUN_DECODER(raw_register, input_dev);
89         if (rc < 0) {
90                 kfifo_free(&ir->raw->kfifo);
91                 kfree(ir->raw);
92                 ir->raw = NULL;
93                 return rc;
94         }
95
96         return rc;
97 }
98
99 void ir_raw_event_unregister(struct input_dev *input_dev)
100 {
101         struct ir_input_dev *ir = input_get_drvdata(input_dev);
102
103         if (!ir->raw)
104                 return;
105
106         cancel_work_sync(&ir->raw->rx_work);
107         RUN_DECODER(raw_unregister, input_dev);
108
109         kfifo_free(&ir->raw->kfifo);
110         kfree(ir->raw);
111         ir->raw = NULL;
112 }
113
114 /**
115  * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
116  * @input_dev:  the struct input_dev device descriptor
117  * @ev:         the struct ir_raw_event descriptor of the pulse/space
118  *
119  * This routine (which may be called from an interrupt context) stores a
120  * pulse/space duration for the raw ir decoding state machines. Pulses are
121  * signalled as positive values and spaces as negative values. A zero value
122  * will reset the decoding state machines.
123  */
124 int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
125 {
126         struct ir_input_dev *ir = input_get_drvdata(input_dev);
127
128         if (!ir->raw)
129                 return -EINVAL;
130
131         if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
132                 return -ENOMEM;
133
134         return 0;
135 }
136 EXPORT_SYMBOL_GPL(ir_raw_event_store);
137
138 /**
139  * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space
140  * @input_dev:  the struct input_dev device descriptor
141  * @type:       the type of the event that has occurred
142  *
143  * This routine (which may be called from an interrupt context) is used to
144  * store the beginning of an ir pulse or space (or the start/end of ir
145  * reception) for the raw ir decoding state machines. This is used by
146  * hardware which does not provide durations directly but only interrupts
147  * (or similar events) on state change.
148  */
149 int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type)
150 {
151         struct ir_input_dev     *ir = input_get_drvdata(input_dev);
152         ktime_t                 now;
153         s64                     delta; /* ns */
154         struct ir_raw_event     ev;
155         int                     rc = 0;
156
157         if (!ir->raw)
158                 return -EINVAL;
159
160         now = ktime_get();
161         delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
162
163         /* Check for a long duration since last event or if we're
164          * being called for the first time, note that delta can't
165          * possibly be negative.
166          */
167         ev.duration = 0;
168         if (delta > IR_MAX_DURATION || !ir->raw->last_type)
169                 type |= IR_START_EVENT;
170         else
171                 ev.duration = delta;
172
173         if (type & IR_START_EVENT)
174                 ir_raw_event_reset(input_dev);
175         else if (ir->raw->last_type & IR_SPACE) {
176                 ev.pulse = false;
177                 rc = ir_raw_event_store(input_dev, &ev);
178         } else if (ir->raw->last_type & IR_PULSE) {
179                 ev.pulse = true;
180                 rc = ir_raw_event_store(input_dev, &ev);
181         } else
182                 return 0;
183
184         ir->raw->last_event = now;
185         ir->raw->last_type = type;
186         return rc;
187 }
188 EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
189
190 /**
191  * ir_raw_event_handle() - schedules the decoding of stored ir data
192  * @input_dev:  the struct input_dev device descriptor
193  *
194  * This routine will signal the workqueue to start decoding stored ir data.
195  */
196 void ir_raw_event_handle(struct input_dev *input_dev)
197 {
198         struct ir_input_dev *ir = input_get_drvdata(input_dev);
199
200         if (!ir->raw)
201                 return;
202
203         schedule_work(&ir->raw->rx_work);
204 }
205 EXPORT_SYMBOL_GPL(ir_raw_event_handle);
206
207 /*
208  * Extension interface - used to register the IR decoders
209  */
210
211 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
212 {
213         spin_lock(&ir_raw_handler_lock);
214         list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
215         spin_unlock(&ir_raw_handler_lock);
216         return 0;
217 }
218 EXPORT_SYMBOL(ir_raw_handler_register);
219
220 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
221 {
222         spin_lock(&ir_raw_handler_lock);
223         list_del(&ir_raw_handler->list);
224         spin_unlock(&ir_raw_handler_lock);
225 }
226 EXPORT_SYMBOL(ir_raw_handler_unregister);
227
228 #ifdef MODULE
229 static void init_decoders(struct work_struct *work)
230 {
231         /* Load the decoder modules */
232
233         load_nec_decode();
234         load_rc5_decode();
235         load_rc6_decode();
236
237         /* If needed, we may later add some init code. In this case,
238            it is needed to change the CONFIG_MODULE test at ir-core.h
239          */
240 }
241 #endif
242
243 void ir_raw_init(void)
244 {
245 #ifdef MODULE
246         INIT_WORK(&wq_load, init_decoders);
247         schedule_work(&wq_load);
248 #endif
249 }