bc4ca08adf4a88c00c9770efde8fc5709f930938
[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 <media/ir-core.h>
16 #include <linux/workqueue.h>
17 #include <linux/spinlock.h>
18
19 /* Define the max number of bit transitions per IR keycode */
20 #define MAX_IR_EVENT_SIZE       256
21
22 /* Used to handle IR raw handler extensions */
23 static LIST_HEAD(ir_raw_handler_list);
24 static DEFINE_SPINLOCK(ir_raw_handler_lock);
25
26 /**
27  * RUN_DECODER()        - runs an operation on all IR decoders
28  * @ops:        IR raw handler operation to be called
29  * @arg:        arguments to be passed to the callback
30  *
31  * Calls ir_raw_handler::ops for all registered IR handlers. It prevents
32  * new decode addition/removal while running, by locking ir_raw_handler_lock
33  * mutex. If an error occurs, it stops the ops. Otherwise, it returns a sum
34  * of the return codes.
35  */
36 #define RUN_DECODER(ops, ...) ({                                            \
37         struct ir_raw_handler           *_ir_raw_handler;                   \
38         int _sumrc = 0, _rc;                                                \
39         spin_lock(&ir_raw_handler_lock);                                    \
40         list_for_each_entry(_ir_raw_handler, &ir_raw_handler_list, list) {  \
41                 if (_ir_raw_handler->ops) {                                 \
42                         _rc = _ir_raw_handler->ops(__VA_ARGS__);            \
43                         if (_rc < 0)                                        \
44                                 break;                                      \
45                         _sumrc += _rc;                                      \
46                 }                                                           \
47         }                                                                   \
48         spin_unlock(&ir_raw_handler_lock);                                  \
49         _sumrc;                                                             \
50 })
51
52
53 /* Used to load the decoders */
54 static struct work_struct wq_load;
55
56 int ir_raw_event_register(struct input_dev *input_dev)
57 {
58         struct ir_input_dev *ir = input_get_drvdata(input_dev);
59         int rc, size;
60
61         ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
62         if (!ir->raw)
63                 return -ENOMEM;
64
65         size = sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE * 2;
66         size = roundup_pow_of_two(size);
67
68         rc = kfifo_alloc(&ir->raw->kfifo, size, GFP_KERNEL);
69         if (rc < 0) {
70                 kfree(ir->raw);
71                 ir->raw = NULL;
72                 return rc;
73         }
74
75         rc = RUN_DECODER(raw_register, input_dev);
76         if (rc < 0) {
77                 kfifo_free(&ir->raw->kfifo);
78                 kfree(ir->raw);
79                 ir->raw = NULL;
80                 return rc;
81         }
82
83         return rc;
84 }
85
86 void ir_raw_event_unregister(struct input_dev *input_dev)
87 {
88         struct ir_input_dev *ir = input_get_drvdata(input_dev);
89
90         if (!ir->raw)
91                 return;
92
93         RUN_DECODER(raw_unregister, input_dev);
94
95         kfifo_free(&ir->raw->kfifo);
96         kfree(ir->raw);
97         ir->raw = NULL;
98 }
99
100 int ir_raw_event_store(struct input_dev *input_dev, enum raw_event_type type)
101 {
102         struct ir_input_dev     *ir = input_get_drvdata(input_dev);
103         struct timespec         ts;
104         struct ir_raw_event     event;
105         int                     rc;
106
107         if (!ir->raw)
108                 return -EINVAL;
109
110         event.type = type;
111         event.delta.tv_sec = 0;
112         event.delta.tv_nsec = 0;
113
114         ktime_get_ts(&ts);
115
116         if (timespec_equal(&ir->raw->last_event, &event.delta))
117                 event.type |= IR_START_EVENT;
118         else
119                 event.delta = timespec_sub(ts, ir->raw->last_event);
120
121         memcpy(&ir->raw->last_event, &ts, sizeof(ts));
122
123         if (event.delta.tv_sec) {
124                 event.type |= IR_START_EVENT;
125                 event.delta.tv_sec = 0;
126                 event.delta.tv_nsec = 0;
127         }
128
129         kfifo_in(&ir->raw->kfifo, &event, sizeof(event));
130
131         return rc;
132 }
133 EXPORT_SYMBOL_GPL(ir_raw_event_store);
134
135 int ir_raw_event_handle(struct input_dev *input_dev)
136 {
137         struct ir_input_dev             *ir = input_get_drvdata(input_dev);
138         int                             rc;
139         struct ir_raw_event             ev;
140         int                             len, i;
141
142         /*
143          * Store the events into a temporary buffer. This allows calling more than
144          * one decoder to deal with the received data
145          */
146         len = kfifo_len(&ir->raw->kfifo) / sizeof(ev);
147         if (!len)
148                 return 0;
149
150         for (i = 0; i < len; i++) {
151                 rc = kfifo_out(&ir->raw->kfifo, &ev, sizeof(ev));
152                 if (rc != sizeof(ev)) {
153                         IR_dprintk(1, "overflow error: received %d instead of %zd\n",
154                                    rc, sizeof(ev));
155                         return -EINVAL;
156                 }
157                 IR_dprintk(2, "event type %d, time before event: %07luus\n",
158                         ev.type, (ev.delta.tv_nsec + 500) / 1000);
159                 rc = RUN_DECODER(decode, input_dev, &ev);
160         }
161
162         /*
163          * Call all ir decoders. This allows decoding the same event with
164          * more than one protocol handler.
165          */
166
167         return rc;
168 }
169 EXPORT_SYMBOL_GPL(ir_raw_event_handle);
170
171 /*
172  * Extension interface - used to register the IR decoders
173  */
174
175 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
176 {
177         spin_lock(&ir_raw_handler_lock);
178         list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
179         spin_unlock(&ir_raw_handler_lock);
180         return 0;
181 }
182 EXPORT_SYMBOL(ir_raw_handler_register);
183
184 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
185 {
186         spin_lock(&ir_raw_handler_lock);
187         list_del(&ir_raw_handler->list);
188         spin_unlock(&ir_raw_handler_lock);
189 }
190 EXPORT_SYMBOL(ir_raw_handler_unregister);
191
192 static void init_decoders(struct work_struct *work)
193 {
194         /* Load the decoder modules */
195
196         load_nec_decode();
197         load_rc5_decode();
198
199         /* If needed, we may later add some init code. In this case,
200            it is needed to change the CONFIG_MODULE test at ir-core.h
201          */
202 }
203
204 void ir_raw_init(void)
205 {
206 #ifdef MODULE
207         INIT_WORK(&wq_load, init_decoders);
208         schedule_work(&wq_load);
209 #endif
210 }