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