]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/media/IR/ir-raw-event.c
Merge branch 'nfs-for-2.6.36' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[mv-sheeva.git] / 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 keep track of IR raw clients, protected by ir_raw_handler_lock */
24 static LIST_HEAD(ir_raw_client_list);
25
26 /* Used to handle IR raw handler extensions */
27 static DEFINE_SPINLOCK(ir_raw_handler_lock);
28 static LIST_HEAD(ir_raw_handler_list);
29 static u64 available_protocols;
30
31 #ifdef MODULE
32 /* Used to load the decoders */
33 static struct work_struct wq_load;
34 #endif
35
36 static void ir_raw_event_work(struct work_struct *work)
37 {
38         struct ir_raw_event ev;
39         struct ir_raw_handler *handler;
40         struct ir_raw_event_ctrl *raw =
41                 container_of(work, struct ir_raw_event_ctrl, rx_work);
42
43         while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) {
44                 spin_lock(&ir_raw_handler_lock);
45                 list_for_each_entry(handler, &ir_raw_handler_list, list)
46                         handler->decode(raw->input_dev, ev);
47                 spin_unlock(&ir_raw_handler_lock);
48                 raw->prev_ev = ev;
49         }
50 }
51
52 /**
53  * ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
54  * @input_dev:  the struct input_dev device descriptor
55  * @ev:         the struct ir_raw_event descriptor of the pulse/space
56  *
57  * This routine (which may be called from an interrupt context) stores a
58  * pulse/space duration for the raw ir decoding state machines. Pulses are
59  * signalled as positive values and spaces as negative values. A zero value
60  * will reset the decoding state machines.
61  */
62 int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
63 {
64         struct ir_input_dev *ir = input_get_drvdata(input_dev);
65
66         if (!ir->raw)
67                 return -EINVAL;
68
69         if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
70                 return -ENOMEM;
71
72         return 0;
73 }
74 EXPORT_SYMBOL_GPL(ir_raw_event_store);
75
76 /**
77  * ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space
78  * @input_dev:  the struct input_dev device descriptor
79  * @type:       the type of the event that has occurred
80  *
81  * This routine (which may be called from an interrupt context) is used to
82  * store the beginning of an ir pulse or space (or the start/end of ir
83  * reception) for the raw ir decoding state machines. This is used by
84  * hardware which does not provide durations directly but only interrupts
85  * (or similar events) on state change.
86  */
87 int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type)
88 {
89         struct ir_input_dev     *ir = input_get_drvdata(input_dev);
90         ktime_t                 now;
91         s64                     delta; /* ns */
92         struct ir_raw_event     ev;
93         int                     rc = 0;
94
95         if (!ir->raw)
96                 return -EINVAL;
97
98         now = ktime_get();
99         delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
100
101         /* Check for a long duration since last event or if we're
102          * being called for the first time, note that delta can't
103          * possibly be negative.
104          */
105         ev.duration = 0;
106         if (delta > IR_MAX_DURATION || !ir->raw->last_type)
107                 type |= IR_START_EVENT;
108         else
109                 ev.duration = delta;
110
111         if (type & IR_START_EVENT)
112                 ir_raw_event_reset(input_dev);
113         else if (ir->raw->last_type & IR_SPACE) {
114                 ev.pulse = false;
115                 rc = ir_raw_event_store(input_dev, &ev);
116         } else if (ir->raw->last_type & IR_PULSE) {
117                 ev.pulse = true;
118                 rc = ir_raw_event_store(input_dev, &ev);
119         } else
120                 return 0;
121
122         ir->raw->last_event = now;
123         ir->raw->last_type = type;
124         return rc;
125 }
126 EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
127
128 /**
129  * ir_raw_event_handle() - schedules the decoding of stored ir data
130  * @input_dev:  the struct input_dev device descriptor
131  *
132  * This routine will signal the workqueue to start decoding stored ir data.
133  */
134 void ir_raw_event_handle(struct input_dev *input_dev)
135 {
136         struct ir_input_dev *ir = input_get_drvdata(input_dev);
137
138         if (!ir->raw)
139                 return;
140
141         schedule_work(&ir->raw->rx_work);
142 }
143 EXPORT_SYMBOL_GPL(ir_raw_event_handle);
144
145 /* used internally by the sysfs interface */
146 u64
147 ir_raw_get_allowed_protocols()
148 {
149         u64 protocols;
150         spin_lock(&ir_raw_handler_lock);
151         protocols = available_protocols;
152         spin_unlock(&ir_raw_handler_lock);
153         return protocols;
154 }
155
156 /*
157  * Used to (un)register raw event clients
158  */
159 int ir_raw_event_register(struct input_dev *input_dev)
160 {
161         struct ir_input_dev *ir = input_get_drvdata(input_dev);
162         int rc;
163         struct ir_raw_handler *handler;
164
165         ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
166         if (!ir->raw)
167                 return -ENOMEM;
168
169         ir->raw->input_dev = input_dev;
170         INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
171         ir->raw->enabled_protocols = ~0;
172         rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
173                          GFP_KERNEL);
174         if (rc < 0) {
175                 kfree(ir->raw);
176                 ir->raw = NULL;
177                 return rc;
178         }
179
180         spin_lock(&ir_raw_handler_lock);
181         list_add_tail(&ir->raw->list, &ir_raw_client_list);
182         list_for_each_entry(handler, &ir_raw_handler_list, list)
183                 if (handler->raw_register)
184                         handler->raw_register(ir->raw->input_dev);
185         spin_unlock(&ir_raw_handler_lock);
186
187         return 0;
188 }
189
190 void ir_raw_event_unregister(struct input_dev *input_dev)
191 {
192         struct ir_input_dev *ir = input_get_drvdata(input_dev);
193         struct ir_raw_handler *handler;
194
195         if (!ir->raw)
196                 return;
197
198         cancel_work_sync(&ir->raw->rx_work);
199
200         spin_lock(&ir_raw_handler_lock);
201         list_del(&ir->raw->list);
202         list_for_each_entry(handler, &ir_raw_handler_list, list)
203                 if (handler->raw_unregister)
204                         handler->raw_unregister(ir->raw->input_dev);
205         spin_unlock(&ir_raw_handler_lock);
206
207         kfifo_free(&ir->raw->kfifo);
208         kfree(ir->raw);
209         ir->raw = NULL;
210 }
211
212 /*
213  * Extension interface - used to register the IR decoders
214  */
215
216 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
217 {
218         struct ir_raw_event_ctrl *raw;
219
220         spin_lock(&ir_raw_handler_lock);
221         list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
222         if (ir_raw_handler->raw_register)
223                 list_for_each_entry(raw, &ir_raw_client_list, list)
224                         ir_raw_handler->raw_register(raw->input_dev);
225         available_protocols |= ir_raw_handler->protocols;
226         spin_unlock(&ir_raw_handler_lock);
227
228         return 0;
229 }
230 EXPORT_SYMBOL(ir_raw_handler_register);
231
232 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
233 {
234         struct ir_raw_event_ctrl *raw;
235
236         spin_lock(&ir_raw_handler_lock);
237         list_del(&ir_raw_handler->list);
238         if (ir_raw_handler->raw_unregister)
239                 list_for_each_entry(raw, &ir_raw_client_list, list)
240                         ir_raw_handler->raw_unregister(raw->input_dev);
241         available_protocols &= ~ir_raw_handler->protocols;
242         spin_unlock(&ir_raw_handler_lock);
243 }
244 EXPORT_SYMBOL(ir_raw_handler_unregister);
245
246 #ifdef MODULE
247 static void init_decoders(struct work_struct *work)
248 {
249         /* Load the decoder modules */
250
251         load_nec_decode();
252         load_rc5_decode();
253         load_rc6_decode();
254         load_jvc_decode();
255         load_sony_decode();
256         load_lirc_codec();
257
258         /* If needed, we may later add some init code. In this case,
259            it is needed to change the CONFIG_MODULE test at ir-core.h
260          */
261 }
262 #endif
263
264 void ir_raw_init(void)
265 {
266 #ifdef MODULE
267         INIT_WORK(&wq_load, init_decoders);
268         schedule_work(&wq_load);
269 #endif
270 }