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		563  /* us */
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
30enum 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 */
46static 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.overflow) {
55			dev_dbg(&dev->dev, "SANYO event overflow 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, 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, ev.duration, TO_STR(ev.pulse));
162	data->state = STATE_INACTIVE;
163	return -EINVAL;
164}
165
166static 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 */
189static 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
208static 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
216static 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
224static void __exit ir_sanyo_decode_exit(void)
225{
226	ir_raw_handler_unregister(&sanyo_handler);
227}
228
229module_init(ir_sanyo_decode_init);
230module_exit(ir_sanyo_decode_exit);
231
232MODULE_LICENSE("GPL v2");
233MODULE_AUTHOR("Mauro Carvalho Chehab");
234MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
235MODULE_DESCRIPTION("SANYO IR protocol decoder");
236