GNU Linux-libre 4.19.207-gnu1
[releases.git] / drivers / media / rc / ir-sanyo-decoder.c
1 // SPDX-License-Identifier: GPL-2.0
2 // ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol
3 //
4 // Copyright (C) 2011 by Mauro Carvalho Chehab
5 //
6 // This protocol uses the NEC protocol timings. However, data is formatted as:
7 //      13 bits Custom Code
8 //      13 bits NOT(Custom Code)
9 //      8 bits Key data
10 //      8 bits NOT(Key data)
11 //
12 // According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
13 // Information for this protocol is available at the Sanyo LC7461 datasheet.
14
15 #include <linux/module.h>
16 #include <linux/bitrev.h>
17 #include "rc-core-priv.h"
18
19 #define SANYO_NBITS             (13+13+8+8)
20 #define SANYO_UNIT              562500  /* ns */
21 #define SANYO_HEADER_PULSE      (16  * SANYO_UNIT)
22 #define SANYO_HEADER_SPACE      (8   * SANYO_UNIT)
23 #define SANYO_BIT_PULSE         (1   * SANYO_UNIT)
24 #define SANYO_BIT_0_SPACE       (1   * SANYO_UNIT)
25 #define SANYO_BIT_1_SPACE       (3   * SANYO_UNIT)
26 #define SANYO_REPEAT_SPACE      (150 * SANYO_UNIT)
27 #define SANYO_TRAILER_PULSE     (1   * SANYO_UNIT)
28 #define SANYO_TRAILER_SPACE     (10  * SANYO_UNIT)      /* in fact, 42 */
29
30 enum sanyo_state {
31         STATE_INACTIVE,
32         STATE_HEADER_SPACE,
33         STATE_BIT_PULSE,
34         STATE_BIT_SPACE,
35         STATE_TRAILER_PULSE,
36         STATE_TRAILER_SPACE,
37 };
38
39 /**
40  * ir_sanyo_decode() - Decode one SANYO pulse or space
41  * @dev:        the struct rc_dev descriptor of the device
42  * @ev:         the struct ir_raw_event descriptor of the pulse/space
43  *
44  * This function returns -EINVAL if the pulse violates the state machine
45  */
46 static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
47 {
48         struct sanyo_dec *data = &dev->raw->sanyo;
49         u32 scancode;
50         u16 address;
51         u8 command, not_command;
52
53         if (!is_timing_event(ev)) {
54                 if (ev.reset) {
55                         dev_dbg(&dev->dev, "SANYO event reset received. reset to state 0\n");
56                         data->state = STATE_INACTIVE;
57                 }
58                 return 0;
59         }
60
61         dev_dbg(&dev->dev, "SANYO decode started at state %d (%uus %s)\n",
62                 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
63
64         switch (data->state) {
65
66         case STATE_INACTIVE:
67                 if (!ev.pulse)
68                         break;
69
70                 if (eq_margin(ev.duration, SANYO_HEADER_PULSE, SANYO_UNIT / 2)) {
71                         data->count = 0;
72                         data->state = STATE_HEADER_SPACE;
73                         return 0;
74                 }
75                 break;
76
77
78         case STATE_HEADER_SPACE:
79                 if (ev.pulse)
80                         break;
81
82                 if (eq_margin(ev.duration, SANYO_HEADER_SPACE, SANYO_UNIT / 2)) {
83                         data->state = STATE_BIT_PULSE;
84                         return 0;
85                 }
86
87                 break;
88
89         case STATE_BIT_PULSE:
90                 if (!ev.pulse)
91                         break;
92
93                 if (!eq_margin(ev.duration, SANYO_BIT_PULSE, SANYO_UNIT / 2))
94                         break;
95
96                 data->state = STATE_BIT_SPACE;
97                 return 0;
98
99         case STATE_BIT_SPACE:
100                 if (ev.pulse)
101                         break;
102
103                 if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) {
104                         rc_repeat(dev);
105                         dev_dbg(&dev->dev, "SANYO repeat last key\n");
106                         data->state = STATE_INACTIVE;
107                         return 0;
108                 }
109
110                 data->bits <<= 1;
111                 if (eq_margin(ev.duration, SANYO_BIT_1_SPACE, SANYO_UNIT / 2))
112                         data->bits |= 1;
113                 else if (!eq_margin(ev.duration, SANYO_BIT_0_SPACE, SANYO_UNIT / 2))
114                         break;
115                 data->count++;
116
117                 if (data->count == SANYO_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, SANYO_TRAILER_PULSE, SANYO_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, SANYO_TRAILER_SPACE, SANYO_UNIT / 2))
139                         break;
140
141                 address     = bitrev16((data->bits >> 29) & 0x1fff) >> 3;
142                 /* not_address = bitrev16((data->bits >> 16) & 0x1fff) >> 3; */
143                 command     = bitrev8((data->bits >>  8) & 0xff);
144                 not_command = bitrev8((data->bits >>  0) & 0xff);
145
146                 if ((command ^ not_command) != 0xff) {
147                         dev_dbg(&dev->dev, "SANYO checksum error: received 0x%08llx\n",
148                                 data->bits);
149                         data->state = STATE_INACTIVE;
150                         return 0;
151                 }
152
153                 scancode = address << 8 | command;
154                 dev_dbg(&dev->dev, "SANYO scancode: 0x%06x\n", scancode);
155                 rc_keydown(dev, RC_PROTO_SANYO, scancode, 0);
156                 data->state = STATE_INACTIVE;
157                 return 0;
158         }
159
160         dev_dbg(&dev->dev, "SANYO decode failed at count %d state %d (%uus %s)\n",
161                 data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
162         data->state = STATE_INACTIVE;
163         return -EINVAL;
164 }
165
166 static const struct ir_raw_timings_pd ir_sanyo_timings = {
167         .header_pulse  = SANYO_HEADER_PULSE,
168         .header_space  = SANYO_HEADER_SPACE,
169         .bit_pulse     = SANYO_BIT_PULSE,
170         .bit_space[0]  = SANYO_BIT_0_SPACE,
171         .bit_space[1]  = SANYO_BIT_1_SPACE,
172         .trailer_pulse = SANYO_TRAILER_PULSE,
173         .trailer_space = SANYO_TRAILER_SPACE,
174         .msb_first     = 1,
175 };
176
177 /**
178  * ir_sanyo_encode() - Encode a scancode as a stream of raw events
179  *
180  * @protocol:   protocol to encode
181  * @scancode:   scancode to encode
182  * @events:     array of raw ir events to write into
183  * @max:        maximum size of @events
184  *
185  * Returns:     The number of events written.
186  *              -ENOBUFS if there isn't enough space in the array to fit the
187  *              encoding. In this case all @max events will have been written.
188  */
189 static int ir_sanyo_encode(enum rc_proto protocol, u32 scancode,
190                            struct ir_raw_event *events, unsigned int max)
191 {
192         struct ir_raw_event *e = events;
193         int ret;
194         u64 raw;
195
196         raw = ((u64)(bitrev16(scancode >> 8) & 0xfff8) << (8 + 8 + 13 - 3)) |
197               ((u64)(bitrev16(~scancode >> 8) & 0xfff8) << (8 + 8 +  0 - 3)) |
198               ((bitrev8(scancode) & 0xff) << 8) |
199               (bitrev8(~scancode) & 0xff);
200
201         ret = ir_raw_gen_pd(&e, max, &ir_sanyo_timings, SANYO_NBITS, raw);
202         if (ret < 0)
203                 return ret;
204
205         return e - events;
206 }
207
208 static struct ir_raw_handler sanyo_handler = {
209         .protocols      = RC_PROTO_BIT_SANYO,
210         .decode         = ir_sanyo_decode,
211         .encode         = ir_sanyo_encode,
212         .carrier        = 38000,
213         .min_timeout    = SANYO_TRAILER_SPACE,
214 };
215
216 static int __init ir_sanyo_decode_init(void)
217 {
218         ir_raw_handler_register(&sanyo_handler);
219
220         printk(KERN_INFO "IR SANYO protocol handler initialized\n");
221         return 0;
222 }
223
224 static void __exit ir_sanyo_decode_exit(void)
225 {
226         ir_raw_handler_unregister(&sanyo_handler);
227 }
228
229 module_init(ir_sanyo_decode_init);
230 module_exit(ir_sanyo_decode_exit);
231
232 MODULE_LICENSE("GPL v2");
233 MODULE_AUTHOR("Mauro Carvalho Chehab");
234 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
235 MODULE_DESCRIPTION("SANYO IR protocol decoder");