Linux-libre 5.4.47-gnu
[librecmc/linux-libre.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         dev_dbg(&dev->dev, "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, NEC_TRAILER_SPACE, NEC_UNIT / 2)) {
103                         dev_dbg(&dev->dev, "Repeat last key\n");
104                         rc_repeat(dev);
105                         data->state = STATE_INACTIVE;
106                         return 0;
107                 } else if (data->count > NECX_REPEAT_BITS)
108                         data->necx_repeat = false;
109
110                 data->bits <<= 1;
111                 if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
112                         data->bits |= 1;
113                 else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
114                         break;
115                 data->count++;
116
117                 if (data->count == NEC_NBITS)
118                         data->state = STATE_TRAILER_PULSE;
119                 else
120                         data->state = STATE_BIT_PULSE;
121
122                 return 0;
123
124         case STATE_TRAILER_PULSE:
125                 if (!ev.pulse)
126                         break;
127
128                 if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2))
129                         break;
130
131                 data->state = STATE_TRAILER_SPACE;
132                 return 0;
133
134         case STATE_TRAILER_SPACE:
135                 if (ev.pulse)
136                         break;
137
138                 if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
139                         break;
140
141                 if (data->count == NEC_NBITS) {
142                         address     = bitrev8((data->bits >> 24) & 0xff);
143                         not_address = bitrev8((data->bits >> 16) & 0xff);
144                         command     = bitrev8((data->bits >>  8) & 0xff);
145                         not_command = bitrev8((data->bits >>  0) & 0xff);
146
147                         scancode = ir_nec_bytes_to_scancode(address,
148                                                             not_address,
149                                                             command,
150                                                             not_command,
151                                                             &rc_proto);
152
153                         if (data->is_nec_x)
154                                 data->necx_repeat = true;
155
156                         rc_keydown(dev, rc_proto, scancode, 0);
157                 } else {
158                         rc_repeat(dev);
159                 }
160
161                 data->state = STATE_INACTIVE;
162                 return 0;
163         }
164
165         dev_dbg(&dev->dev, "NEC decode failed at count %d state %d (%uus %s)\n",
166                 data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
167         data->state = STATE_INACTIVE;
168         return -EINVAL;
169 }
170
171 /**
172  * ir_nec_scancode_to_raw() - encode an NEC scancode ready for modulation.
173  * @protocol:   specific protocol to use
174  * @scancode:   a single NEC scancode.
175  */
176 static u32 ir_nec_scancode_to_raw(enum rc_proto protocol, u32 scancode)
177 {
178         unsigned int addr, addr_inv, data, data_inv;
179
180         data = scancode & 0xff;
181
182         if (protocol == RC_PROTO_NEC32) {
183                 /* 32-bit NEC (used by Apple and TiVo remotes) */
184                 /* scan encoding: aaAAddDD */
185                 addr_inv   = (scancode >> 24) & 0xff;
186                 addr       = (scancode >> 16) & 0xff;
187                 data_inv   = (scancode >>  8) & 0xff;
188         } else if (protocol == RC_PROTO_NECX) {
189                 /* Extended NEC */
190                 /* scan encoding AAaaDD */
191                 addr       = (scancode >> 16) & 0xff;
192                 addr_inv   = (scancode >>  8) & 0xff;
193                 data_inv   = data ^ 0xff;
194         } else {
195                 /* Normal NEC */
196                 /* scan encoding: AADD */
197                 addr       = (scancode >>  8) & 0xff;
198                 addr_inv   = addr ^ 0xff;
199                 data_inv   = data ^ 0xff;
200         }
201
202         /* raw encoding: ddDDaaAA */
203         return data_inv << 24 |
204                data     << 16 |
205                addr_inv <<  8 |
206                addr;
207 }
208
209 static const struct ir_raw_timings_pd ir_nec_timings = {
210         .header_pulse   = NEC_HEADER_PULSE,
211         .header_space   = NEC_HEADER_SPACE,
212         .bit_pulse      = NEC_BIT_PULSE,
213         .bit_space[0]   = NEC_BIT_0_SPACE,
214         .bit_space[1]   = NEC_BIT_1_SPACE,
215         .trailer_pulse  = NEC_TRAILER_PULSE,
216         .trailer_space  = NEC_TRAILER_SPACE,
217         .msb_first      = 0,
218 };
219
220 /**
221  * ir_nec_encode() - Encode a scancode as a stream of raw events
222  *
223  * @protocol:   protocol to encode
224  * @scancode:   scancode to encode
225  * @events:     array of raw ir events to write into
226  * @max:        maximum size of @events
227  *
228  * Returns:     The number of events written.
229  *              -ENOBUFS if there isn't enough space in the array to fit the
230  *              encoding. In this case all @max events will have been written.
231  */
232 static int ir_nec_encode(enum rc_proto protocol, u32 scancode,
233                          struct ir_raw_event *events, unsigned int max)
234 {
235         struct ir_raw_event *e = events;
236         int ret;
237         u32 raw;
238
239         /* Convert a NEC scancode to raw NEC data */
240         raw = ir_nec_scancode_to_raw(protocol, scancode);
241
242         /* Modulate the raw data using a pulse distance modulation */
243         ret = ir_raw_gen_pd(&e, max, &ir_nec_timings, NEC_NBITS, raw);
244         if (ret < 0)
245                 return ret;
246
247         return e - events;
248 }
249
250 static struct ir_raw_handler nec_handler = {
251         .protocols      = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX |
252                                                         RC_PROTO_BIT_NEC32,
253         .decode         = ir_nec_decode,
254         .encode         = ir_nec_encode,
255         .carrier        = 38000,
256         .min_timeout    = NEC_TRAILER_SPACE,
257 };
258
259 static int __init ir_nec_decode_init(void)
260 {
261         ir_raw_handler_register(&nec_handler);
262
263         printk(KERN_INFO "IR NEC protocol handler initialized\n");
264         return 0;
265 }
266
267 static void __exit ir_nec_decode_exit(void)
268 {
269         ir_raw_handler_unregister(&nec_handler);
270 }
271
272 module_init(ir_nec_decode_init);
273 module_exit(ir_nec_decode_exit);
274
275 MODULE_LICENSE("GPL v2");
276 MODULE_AUTHOR("Mauro Carvalho Chehab");
277 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
278 MODULE_DESCRIPTION("NEC IR protocol decoder");