Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
[sfrench/cifs-2.6.git] / drivers / media / rc / ir-nec-decoder.c
1 // SPDX-License-Identifier: GPL-2.0
2 // ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
3 //
4 // Copyright (C) 2010 by Mauro Carvalho Chehab
5
6 #include <linux/bitrev.h>
7 #include <linux/module.h>
8 #include "rc-core-priv.h"
9
10 #define NEC_NBITS               32
11 #define NEC_UNIT                562500  /* ns */
12 #define NEC_HEADER_PULSE        (16 * NEC_UNIT)
13 #define NECX_HEADER_PULSE       (8  * NEC_UNIT) /* Less common NEC variant */
14 #define NEC_HEADER_SPACE        (8  * NEC_UNIT)
15 #define NEC_REPEAT_SPACE        (4  * NEC_UNIT)
16 #define NEC_BIT_PULSE           (1  * NEC_UNIT)
17 #define NEC_BIT_0_SPACE         (1  * NEC_UNIT)
18 #define NEC_BIT_1_SPACE         (3  * NEC_UNIT)
19 #define NEC_TRAILER_PULSE       (1  * NEC_UNIT)
20 #define NEC_TRAILER_SPACE       (10 * NEC_UNIT) /* even longer in reality */
21 #define NECX_REPEAT_BITS        1
22
23 enum nec_state {
24         STATE_INACTIVE,
25         STATE_HEADER_SPACE,
26         STATE_BIT_PULSE,
27         STATE_BIT_SPACE,
28         STATE_TRAILER_PULSE,
29         STATE_TRAILER_SPACE,
30 };
31
32 /**
33  * ir_nec_decode() - Decode one NEC pulse or space
34  * @dev:        the struct rc_dev descriptor of the device
35  * @ev:         the struct ir_raw_event descriptor of the pulse/space
36  *
37  * This function returns -EINVAL if the pulse violates the state machine
38  */
39 static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
40 {
41         struct nec_dec *data = &dev->raw->nec;
42         u32 scancode;
43         enum rc_proto rc_proto;
44         u8 address, not_address, command, not_command;
45
46         if (!is_timing_event(ev)) {
47                 if (ev.reset)
48                         data->state = STATE_INACTIVE;
49                 return 0;
50         }
51
52         IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n",
53                    data->state, TO_US(ev.duration), TO_STR(ev.pulse));
54
55         switch (data->state) {
56
57         case STATE_INACTIVE:
58                 if (!ev.pulse)
59                         break;
60
61                 if (eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT * 2)) {
62                         data->is_nec_x = false;
63                         data->necx_repeat = false;
64                 } else if (eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
65                         data->is_nec_x = true;
66                 else
67                         break;
68
69                 data->count = 0;
70                 data->state = STATE_HEADER_SPACE;
71                 return 0;
72
73         case STATE_HEADER_SPACE:
74                 if (ev.pulse)
75                         break;
76
77                 if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT)) {
78                         data->state = STATE_BIT_PULSE;
79                         return 0;
80                 } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
81                         data->state = STATE_TRAILER_PULSE;
82                         return 0;
83                 }
84
85                 break;
86
87         case STATE_BIT_PULSE:
88                 if (!ev.pulse)
89                         break;
90
91                 if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2))
92                         break;
93
94                 data->state = STATE_BIT_SPACE;
95                 return 0;
96
97         case STATE_BIT_SPACE:
98                 if (ev.pulse)
99                         break;
100
101                 if (data->necx_repeat && data->count == NECX_REPEAT_BITS &&
102                         geq_margin(ev.duration,
103                         NEC_TRAILER_SPACE, NEC_UNIT / 2)) {
104                                 IR_dprintk(1, "Repeat last key\n");
105                                 rc_repeat(dev);
106                                 data->state = STATE_INACTIVE;
107                                 return 0;
108
109                 } else if (data->count > NECX_REPEAT_BITS)
110                         data->necx_repeat = false;
111
112                 data->bits <<= 1;
113                 if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
114                         data->bits |= 1;
115                 else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
116                         break;
117                 data->count++;
118
119                 if (data->count == NEC_NBITS)
120                         data->state = STATE_TRAILER_PULSE;
121                 else
122                         data->state = STATE_BIT_PULSE;
123
124                 return 0;
125
126         case STATE_TRAILER_PULSE:
127                 if (!ev.pulse)
128                         break;
129
130                 if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2))
131                         break;
132
133                 data->state = STATE_TRAILER_SPACE;
134                 return 0;
135
136         case STATE_TRAILER_SPACE:
137                 if (ev.pulse)
138                         break;
139
140                 if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
141                         break;
142
143                 if (data->count == NEC_NBITS) {
144                         address     = bitrev8((data->bits >> 24) & 0xff);
145                         not_address = bitrev8((data->bits >> 16) & 0xff);
146                         command     = bitrev8((data->bits >>  8) & 0xff);
147                         not_command = bitrev8((data->bits >>  0) & 0xff);
148
149                         scancode = ir_nec_bytes_to_scancode(address,
150                                                             not_address,
151                                                             command,
152                                                             not_command,
153                                                             &rc_proto);
154
155                         if (data->is_nec_x)
156                                 data->necx_repeat = true;
157
158                         rc_keydown(dev, rc_proto, scancode, 0);
159                 } else {
160                         rc_repeat(dev);
161                 }
162
163                 data->state = STATE_INACTIVE;
164                 return 0;
165         }
166
167         IR_dprintk(1, "NEC decode failed at count %d state %d (%uus %s)\n",
168                    data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
169         data->state = STATE_INACTIVE;
170         return -EINVAL;
171 }
172
173 /**
174  * ir_nec_scancode_to_raw() - encode an NEC scancode ready for modulation.
175  * @protocol:   specific protocol to use
176  * @scancode:   a single NEC scancode.
177  */
178 static u32 ir_nec_scancode_to_raw(enum rc_proto protocol, u32 scancode)
179 {
180         unsigned int addr, addr_inv, data, data_inv;
181
182         data = scancode & 0xff;
183
184         if (protocol == RC_PROTO_NEC32) {
185                 /* 32-bit NEC (used by Apple and TiVo remotes) */
186                 /* scan encoding: aaAAddDD */
187                 addr_inv   = (scancode >> 24) & 0xff;
188                 addr       = (scancode >> 16) & 0xff;
189                 data_inv   = (scancode >>  8) & 0xff;
190         } else if (protocol == RC_PROTO_NECX) {
191                 /* Extended NEC */
192                 /* scan encoding AAaaDD */
193                 addr       = (scancode >> 16) & 0xff;
194                 addr_inv   = (scancode >>  8) & 0xff;
195                 data_inv   = data ^ 0xff;
196         } else {
197                 /* Normal NEC */
198                 /* scan encoding: AADD */
199                 addr       = (scancode >>  8) & 0xff;
200                 addr_inv   = addr ^ 0xff;
201                 data_inv   = data ^ 0xff;
202         }
203
204         /* raw encoding: ddDDaaAA */
205         return data_inv << 24 |
206                data     << 16 |
207                addr_inv <<  8 |
208                addr;
209 }
210
211 static const struct ir_raw_timings_pd ir_nec_timings = {
212         .header_pulse   = NEC_HEADER_PULSE,
213         .header_space   = NEC_HEADER_SPACE,
214         .bit_pulse      = NEC_BIT_PULSE,
215         .bit_space[0]   = NEC_BIT_0_SPACE,
216         .bit_space[1]   = NEC_BIT_1_SPACE,
217         .trailer_pulse  = NEC_TRAILER_PULSE,
218         .trailer_space  = NEC_TRAILER_SPACE,
219         .msb_first      = 0,
220 };
221
222 /**
223  * ir_nec_encode() - Encode a scancode as a stream of raw events
224  *
225  * @protocol:   protocol to encode
226  * @scancode:   scancode to encode
227  * @events:     array of raw ir events to write into
228  * @max:        maximum size of @events
229  *
230  * Returns:     The number of events written.
231  *              -ENOBUFS if there isn't enough space in the array to fit the
232  *              encoding. In this case all @max events will have been written.
233  */
234 static int ir_nec_encode(enum rc_proto protocol, u32 scancode,
235                          struct ir_raw_event *events, unsigned int max)
236 {
237         struct ir_raw_event *e = events;
238         int ret;
239         u32 raw;
240
241         /* Convert a NEC scancode to raw NEC data */
242         raw = ir_nec_scancode_to_raw(protocol, scancode);
243
244         /* Modulate the raw data using a pulse distance modulation */
245         ret = ir_raw_gen_pd(&e, max, &ir_nec_timings, NEC_NBITS, raw);
246         if (ret < 0)
247                 return ret;
248
249         return e - events;
250 }
251
252 static struct ir_raw_handler nec_handler = {
253         .protocols      = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX |
254                                                         RC_PROTO_BIT_NEC32,
255         .decode         = ir_nec_decode,
256         .encode         = ir_nec_encode,
257         .carrier        = 38000,
258 };
259
260 static int __init ir_nec_decode_init(void)
261 {
262         ir_raw_handler_register(&nec_handler);
263
264         printk(KERN_INFO "IR NEC protocol handler initialized\n");
265         return 0;
266 }
267
268 static void __exit ir_nec_decode_exit(void)
269 {
270         ir_raw_handler_unregister(&nec_handler);
271 }
272
273 module_init(ir_nec_decode_init);
274 module_exit(ir_nec_decode_exit);
275
276 MODULE_LICENSE("GPL v2");
277 MODULE_AUTHOR("Mauro Carvalho Chehab");
278 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
279 MODULE_DESCRIPTION("NEC IR protocol decoder");