V4L/DVB: ir-core: Remove warining noise if decoders compiled builtin
[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         s64 d;
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, &d, sizeof(d)) == sizeof(d))
65                 RUN_DECODER(decode, raw->input_dev, d);
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  * @duration:   duration of the pulse or space in ns
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, s64 duration)
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, &duration, sizeof(duration)) != sizeof(duration))
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         int                     rc = 0;
155
156         if (!ir->raw)
157                 return -EINVAL;
158
159         now = ktime_get();
160         delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
161
162         /* Check for a long duration since last event or if we're
163          * being called for the first time, note that delta can't
164          * possibly be negative.
165          */
166         if (delta > NSEC_PER_SEC || !ir->raw->last_type)
167                 type |= IR_START_EVENT;
168
169         if (type & IR_START_EVENT)
170                 ir_raw_event_reset(input_dev);
171         else if (ir->raw->last_type & IR_SPACE)
172                 rc = ir_raw_event_store(input_dev, -delta);
173         else if (ir->raw->last_type & IR_PULSE)
174                 rc = ir_raw_event_store(input_dev, delta);
175         else
176                 return 0;
177
178         ir->raw->last_event = now;
179         ir->raw->last_type = type;
180         return rc;
181 }
182 EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
183
184 /**
185  * ir_raw_event_handle() - schedules the decoding of stored ir data
186  * @input_dev:  the struct input_dev device descriptor
187  *
188  * This routine will signal the workqueue to start decoding stored ir data.
189  */
190 void ir_raw_event_handle(struct input_dev *input_dev)
191 {
192         struct ir_input_dev *ir = input_get_drvdata(input_dev);
193
194         if (!ir->raw)
195                 return;
196
197         schedule_work(&ir->raw->rx_work);
198 }
199 EXPORT_SYMBOL_GPL(ir_raw_event_handle);
200
201 /*
202  * Extension interface - used to register the IR decoders
203  */
204
205 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
206 {
207         spin_lock(&ir_raw_handler_lock);
208         list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
209         spin_unlock(&ir_raw_handler_lock);
210         return 0;
211 }
212 EXPORT_SYMBOL(ir_raw_handler_register);
213
214 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
215 {
216         spin_lock(&ir_raw_handler_lock);
217         list_del(&ir_raw_handler->list);
218         spin_unlock(&ir_raw_handler_lock);
219 }
220 EXPORT_SYMBOL(ir_raw_handler_unregister);
221
222 #ifdef MODULE
223 static void init_decoders(struct work_struct *work)
224 {
225         /* Load the decoder modules */
226
227         load_nec_decode();
228         load_rc5_decode();
229
230         /* If needed, we may later add some init code. In this case,
231            it is needed to change the CONFIG_MODULE test at ir-core.h
232          */
233 }
234 #endif
235
236 void ir_raw_init(void)
237 {
238 #ifdef MODULE
239         INIT_WORK(&wq_load, init_decoders);
240         schedule_work(&wq_load);
241 #endif
242 }