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