V4L/DVB: ir-nec-decoder: Cleanups
[cascardo/linux.git] / drivers / media / IR / ir-nec-decoder.c
1 /* ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
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
17 #define NEC_NBITS               32
18 #define NEC_UNIT                559979 /* ns */
19 #define NEC_HEADER_MARK         (16 * NEC_UNIT)
20 #define NEC_HEADER_SPACE        (8 * NEC_UNIT)
21 #define NEC_REPEAT_SPACE        (4 * NEC_UNIT)
22 #define NEC_MARK                (NEC_UNIT)
23 #define NEC_0_SPACE             (NEC_UNIT)
24 #define NEC_1_SPACE             (3 * NEC_UNIT)
25
26 /* Used to register nec_decoder clients */
27 static LIST_HEAD(decoder_list);
28 static spinlock_t decoder_lock;
29
30 enum nec_state {
31         STATE_INACTIVE,
32         STATE_HEADER_MARK,
33         STATE_HEADER_SPACE,
34         STATE_MARK,
35         STATE_SPACE,
36         STATE_TRAILER_MARK,
37         STATE_TRAILER_SPACE,
38 };
39
40 struct nec_code {
41         u8      address;
42         u8      not_address;
43         u8      command;
44         u8      not_command;
45 };
46
47 struct decoder_data {
48         struct list_head        list;
49         struct ir_input_dev     *ir_dev;
50         int                     enabled:1;
51
52         /* State machine control */
53         enum nec_state          state;
54         struct nec_code         nec_code;
55         unsigned                count;
56 };
57
58
59 /**
60  * get_decoder_data()   - gets decoder data
61  * @input_dev:  input device
62  *
63  * Returns the struct decoder_data that corresponds to a device
64  */
65
66 static struct decoder_data *get_decoder_data(struct  ir_input_dev *ir_dev)
67 {
68         struct decoder_data *data = NULL;
69
70         spin_lock(&decoder_lock);
71         list_for_each_entry(data, &decoder_list, list) {
72                 if (data->ir_dev == ir_dev)
73                         break;
74         }
75         spin_unlock(&decoder_lock);
76         return data;
77 }
78
79 static ssize_t store_enabled(struct device *d,
80                              struct device_attribute *mattr,
81                              const char *buf,
82                              size_t len)
83 {
84         unsigned long value;
85         struct ir_input_dev *ir_dev = dev_get_drvdata(d);
86         struct decoder_data *data = get_decoder_data(ir_dev);
87
88         if (!data)
89                 return -EINVAL;
90
91         if (strict_strtoul(buf, 10, &value) || value > 1)
92                 return -EINVAL;
93
94         data->enabled = value;
95
96         return len;
97 }
98
99 static ssize_t show_enabled(struct device *d,
100                              struct device_attribute *mattr, char *buf)
101 {
102         struct ir_input_dev *ir_dev = dev_get_drvdata(d);
103         struct decoder_data *data = get_decoder_data(ir_dev);
104
105         if (!data)
106                 return -EINVAL;
107
108         if (data->enabled)
109                 return sprintf(buf, "1\n");
110         else
111         return sprintf(buf, "0\n");
112 }
113
114 static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
115
116 static struct attribute *decoder_attributes[] = {
117         &dev_attr_enabled.attr,
118         NULL
119 };
120
121 static struct attribute_group decoder_attribute_group = {
122         .name   = "nec_decoder",
123         .attrs  = decoder_attributes,
124 };
125
126
127 /**
128  * handle_event() - Decode one NEC pulse or space
129  * @input_dev:  the struct input_dev descriptor of the device
130  * @ev:         event array with type/duration of pulse/space
131  *
132  * This function returns -EINVAL if the pulse violates the state machine
133  */
134 static int handle_event(struct input_dev *input_dev,
135                         struct ir_raw_event *ev)
136 {
137         struct decoder_data *data;
138         struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
139         int bit, last_bit;
140
141         data = get_decoder_data(ir_dev);
142         if (!data)
143                 return -EINVAL;
144
145         /* Except for the initial event, what matters is the previous bit */
146         bit = (ev->type & IR_PULSE) ? 1 : 0;
147
148         last_bit = !bit;
149
150         /* Discards spurious space last_bits when inactive */
151
152         /* Very long delays are considered as start events */
153         if (ev->delta.tv_nsec > NEC_HEADER_MARK + NEC_HEADER_SPACE - NEC_UNIT / 2)
154                 data->state = STATE_INACTIVE;
155
156         if (ev->type & IR_START_EVENT)
157                 data->state = STATE_INACTIVE;
158
159         switch (data->state) {
160         case STATE_INACTIVE:
161                 if (!bit)               /* PULSE marks the start event */
162                         return 0;
163
164                 data->count = 0;
165                 data->state = STATE_HEADER_MARK;
166                 memset (&data->nec_code, 0, sizeof(data->nec_code));
167                 return 0;
168         case STATE_HEADER_MARK:
169                 if (!last_bit)
170                         goto err;
171                 if (ev->delta.tv_nsec < NEC_HEADER_MARK - 6 * NEC_UNIT)
172                         goto err;
173                 data->state = STATE_HEADER_SPACE;
174                 return 0;
175         case STATE_HEADER_SPACE:
176                 if (last_bit)
177                         goto err;
178                 if (ev->delta.tv_nsec >= NEC_HEADER_SPACE - NEC_UNIT / 2) {
179                         data->state = STATE_MARK;
180                         return 0;
181                 }
182
183                 if (ev->delta.tv_nsec >= NEC_REPEAT_SPACE - NEC_UNIT / 2) {
184                         ir_repeat(input_dev);
185                         IR_dprintk(1, "Repeat last key\n");
186                         data->state = STATE_TRAILER_MARK;
187                         return 0;
188                 }
189                 goto err;
190         case STATE_MARK:
191                 if (!last_bit)
192                         goto err;
193                 if ((ev->delta.tv_nsec > NEC_MARK + NEC_UNIT / 2) ||
194                     (ev->delta.tv_nsec < NEC_MARK - NEC_UNIT / 2))
195                         goto err;
196                 data->state = STATE_SPACE;
197                 return 0;
198         case STATE_SPACE:
199                 if (last_bit)
200                         goto err;
201
202                 if ((ev->delta.tv_nsec >= NEC_0_SPACE - NEC_UNIT / 2) &&
203                     (ev->delta.tv_nsec < NEC_0_SPACE + NEC_UNIT / 2))
204                         bit = 0;
205                 else if ((ev->delta.tv_nsec >= NEC_1_SPACE - NEC_UNIT / 2) &&
206                          (ev->delta.tv_nsec < NEC_1_SPACE + NEC_UNIT / 2))
207                         bit = 1;
208                 else {
209                         IR_dprintk(1, "Decode failed at %d-th bit (%s) @%luus\n",
210                                 data->count,
211                                 last_bit ? "pulse" : "space",
212                                 (ev->delta.tv_nsec + 500) / 1000);
213
214                         goto err2;
215                 }
216
217                 /* Ok, we've got a valid bit. proccess it */
218                 if (bit) {
219                         int shift = data->count;
220
221                         /*
222                          * NEC transmit bytes on this temporal order:
223                          * address | not address | command | not command
224                          */
225                         if (shift < 8) {
226                                 data->nec_code.address |= 1 << shift;
227                         } else if (shift < 16) {
228                                 data->nec_code.not_address |= 1 << (shift - 8);
229                         } else if (shift < 24) {
230                                 data->nec_code.command |= 1 << (shift - 16);
231                         } else {
232                                 data->nec_code.not_command |= 1 << (shift - 24);
233                         }
234                 }
235                 if (++data->count == NEC_NBITS) {
236                         u32 scancode;
237                         /*
238                          * Fixme: may need to accept Extended NEC protocol?
239                          */
240                         if ((data->nec_code.command ^ data->nec_code.not_command) != 0xff)
241                                 goto checksum_err;
242
243                         if ((data->nec_code.address ^ data->nec_code.not_address) != 0xff) {
244                                 /* Extended NEC */
245                                 scancode = data->nec_code.address << 16 |
246                                            data->nec_code.not_address << 8 |
247                                            data->nec_code.command;
248                                 IR_dprintk(1, "NEC scancode 0x%06x\n", scancode);
249                         } else {
250                                 /* normal NEC */
251                                 scancode = data->nec_code.address << 8 |
252                                            data->nec_code.command;
253                                 IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
254                         }
255                         ir_keydown(input_dev, scancode, 0);
256
257                         data->state = STATE_TRAILER_MARK;
258                 } else
259                         data->state = STATE_MARK;
260                 return 0;
261         case STATE_TRAILER_MARK:
262                 if (!last_bit)
263                         goto err;
264                 data->state = STATE_TRAILER_SPACE;
265                 return 0;
266         case STATE_TRAILER_SPACE:
267                 if (last_bit)
268                         goto err;
269                 data->state = STATE_INACTIVE;
270                 return 0;
271         }
272
273 err:
274         IR_dprintk(1, "NEC decoded failed at state %d (%s) @ %luus\n",
275                    data->state,
276                    bit ? "pulse" : "space",
277                    (ev->delta.tv_nsec + 500) / 1000);
278 err2:
279         data->state = STATE_INACTIVE;
280         return -EINVAL;
281
282 checksum_err:
283         data->state = STATE_INACTIVE;
284         IR_dprintk(1, "NEC checksum error: received 0x%02x%02x%02x%02x\n",
285                    data->nec_code.address,
286                    data->nec_code.not_address,
287                    data->nec_code.command,
288                    data->nec_code.not_command);
289         return -EINVAL;
290 }
291
292 /**
293  * ir_nec_decode() - Decodes all NEC pulsecodes on a given array
294  * @input_dev:  the struct input_dev descriptor of the device
295  * @evs:        event array with type/duration of pulse/space
296  * @len:        length of the array
297  * This function returns the number of decoded pulses
298  */
299 static int ir_nec_decode(struct input_dev *input_dev,
300                          struct ir_raw_event *evs,
301                          int len)
302 {
303         struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
304         struct decoder_data *data;
305         int pos = 0;
306         int rc = 0;
307
308         data = get_decoder_data(ir_dev);
309         if (!data || !data->enabled)
310                 return 0;
311
312         for (pos = 0; pos < len; pos++)
313                 handle_event(input_dev, &evs[pos]);
314
315         return rc;
316 }
317
318 static int ir_nec_register(struct input_dev *input_dev)
319 {
320         struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
321         struct decoder_data *data;
322         int rc;
323
324         rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
325         if (rc < 0)
326                 return rc;
327
328         data = kzalloc(sizeof(*data), GFP_KERNEL);
329         if (!data) {
330                 sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
331                 return -ENOMEM;
332         }
333
334         data->ir_dev = ir_dev;
335         data->enabled = 1;
336
337         spin_lock(&decoder_lock);
338         list_add_tail(&data->list, &decoder_list);
339         spin_unlock(&decoder_lock);
340
341         return 0;
342 }
343
344 static int ir_nec_unregister(struct input_dev *input_dev)
345 {
346         struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
347         static struct decoder_data *data;
348
349         data = get_decoder_data(ir_dev);
350         if (!data)
351                 return 0;
352
353         sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
354
355         spin_lock(&decoder_lock);
356         list_del(&data->list);
357         spin_unlock(&decoder_lock);
358
359         return 0;
360 }
361
362 static struct ir_raw_handler nec_handler = {
363         .decode         = ir_nec_decode,
364         .raw_register   = ir_nec_register,
365         .raw_unregister = ir_nec_unregister,
366 };
367
368 static int __init ir_nec_decode_init(void)
369 {
370         ir_raw_handler_register(&nec_handler);
371
372         printk(KERN_INFO "IR NEC protocol handler initialized\n");
373         return 0;
374 }
375
376 static void __exit ir_nec_decode_exit(void)
377 {
378         ir_raw_handler_unregister(&nec_handler);
379 }
380
381 module_init(ir_nec_decode_init);
382 module_exit(ir_nec_decode_exit);
383
384 MODULE_LICENSE("GPL");
385 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
386 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
387 MODULE_DESCRIPTION("NEC IR protocol decoder");