1 /* ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
3 * Copyright (C) 2010 by Mauro Carvalho Chehab
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/bitrev.h>
16 #include <linux/module.h>
17 #include "rc-core-priv.h"
20 #define NEC_UNIT 562500 /* ns */
21 #define NEC_HEADER_PULSE (16 * NEC_UNIT)
22 #define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */
23 #define NEC_HEADER_SPACE (8 * NEC_UNIT)
24 #define NEC_REPEAT_SPACE (4 * NEC_UNIT)
25 #define NEC_BIT_PULSE (1 * NEC_UNIT)
26 #define NEC_BIT_0_SPACE (1 * NEC_UNIT)
27 #define NEC_BIT_1_SPACE (3 * NEC_UNIT)
28 #define NEC_TRAILER_PULSE (1 * NEC_UNIT)
29 #define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */
30 #define NECX_REPEAT_BITS 1
42 * ir_nec_decode() - Decode one NEC pulse or space
43 * @dev: the struct rc_dev descriptor of the device
44 * @duration: the struct ir_raw_event descriptor of the pulse/space
46 * This function returns -EINVAL if the pulse violates the state machine
48 static int ir_nec_decode(struct rc_dev
*dev
, struct ir_raw_event ev
)
50 struct nec_dec
*data
= &dev
->raw
->nec
;
52 enum rc_proto rc_proto
;
53 u8 address
, not_address
, command
, not_command
;
55 if (!is_timing_event(ev
)) {
57 data
->state
= STATE_INACTIVE
;
61 IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n",
62 data
->state
, TO_US(ev
.duration
), TO_STR(ev
.pulse
));
64 switch (data
->state
) {
70 if (eq_margin(ev
.duration
, NEC_HEADER_PULSE
, NEC_UNIT
* 2)) {
71 data
->is_nec_x
= false;
72 data
->necx_repeat
= false;
73 } else if (eq_margin(ev
.duration
, NECX_HEADER_PULSE
, NEC_UNIT
/ 2))
74 data
->is_nec_x
= true;
79 data
->state
= STATE_HEADER_SPACE
;
82 case STATE_HEADER_SPACE
:
86 if (eq_margin(ev
.duration
, NEC_HEADER_SPACE
, NEC_UNIT
)) {
87 data
->state
= STATE_BIT_PULSE
;
89 } else if (eq_margin(ev
.duration
, NEC_REPEAT_SPACE
, NEC_UNIT
/ 2)) {
90 data
->state
= STATE_TRAILER_PULSE
;
100 if (!eq_margin(ev
.duration
, NEC_BIT_PULSE
, NEC_UNIT
/ 2))
103 data
->state
= STATE_BIT_SPACE
;
106 case STATE_BIT_SPACE
:
110 if (data
->necx_repeat
&& data
->count
== NECX_REPEAT_BITS
&&
111 geq_margin(ev
.duration
,
112 NEC_TRAILER_SPACE
, NEC_UNIT
/ 2)) {
113 IR_dprintk(1, "Repeat last key\n");
115 data
->state
= STATE_INACTIVE
;
118 } else if (data
->count
> NECX_REPEAT_BITS
)
119 data
->necx_repeat
= false;
122 if (eq_margin(ev
.duration
, NEC_BIT_1_SPACE
, NEC_UNIT
/ 2))
124 else if (!eq_margin(ev
.duration
, NEC_BIT_0_SPACE
, NEC_UNIT
/ 2))
128 if (data
->count
== NEC_NBITS
)
129 data
->state
= STATE_TRAILER_PULSE
;
131 data
->state
= STATE_BIT_PULSE
;
135 case STATE_TRAILER_PULSE
:
139 if (!eq_margin(ev
.duration
, NEC_TRAILER_PULSE
, NEC_UNIT
/ 2))
142 data
->state
= STATE_TRAILER_SPACE
;
145 case STATE_TRAILER_SPACE
:
149 if (!geq_margin(ev
.duration
, NEC_TRAILER_SPACE
, NEC_UNIT
/ 2))
152 if (data
->count
== NEC_NBITS
) {
153 address
= bitrev8((data
->bits
>> 24) & 0xff);
154 not_address
= bitrev8((data
->bits
>> 16) & 0xff);
155 command
= bitrev8((data
->bits
>> 8) & 0xff);
156 not_command
= bitrev8((data
->bits
>> 0) & 0xff);
158 scancode
= ir_nec_bytes_to_scancode(address
,
165 data
->necx_repeat
= true;
167 rc_keydown(dev
, rc_proto
, scancode
, 0);
172 data
->state
= STATE_INACTIVE
;
176 IR_dprintk(1, "NEC decode failed at count %d state %d (%uus %s)\n",
177 data
->count
, data
->state
, TO_US(ev
.duration
), TO_STR(ev
.pulse
));
178 data
->state
= STATE_INACTIVE
;
183 * ir_nec_scancode_to_raw() - encode an NEC scancode ready for modulation.
184 * @protocol: specific protocol to use
185 * @scancode: a single NEC scancode.
186 * @raw: raw data to be modulated.
188 static u32
ir_nec_scancode_to_raw(enum rc_proto protocol
, u32 scancode
)
190 unsigned int addr
, addr_inv
, data
, data_inv
;
192 data
= scancode
& 0xff;
194 if (protocol
== RC_PROTO_NEC32
) {
195 /* 32-bit NEC (used by Apple and TiVo remotes) */
196 /* scan encoding: aaAAddDD */
197 addr_inv
= (scancode
>> 24) & 0xff;
198 addr
= (scancode
>> 16) & 0xff;
199 data_inv
= (scancode
>> 8) & 0xff;
200 } else if (protocol
== RC_PROTO_NECX
) {
202 /* scan encoding AAaaDD */
203 addr
= (scancode
>> 16) & 0xff;
204 addr_inv
= (scancode
>> 8) & 0xff;
205 data_inv
= data
^ 0xff;
208 /* scan encoding: AADD */
209 addr
= (scancode
>> 8) & 0xff;
210 addr_inv
= addr
^ 0xff;
211 data_inv
= data
^ 0xff;
214 /* raw encoding: ddDDaaAA */
215 return data_inv
<< 24 |
221 static const struct ir_raw_timings_pd ir_nec_timings
= {
222 .header_pulse
= NEC_HEADER_PULSE
,
223 .header_space
= NEC_HEADER_SPACE
,
224 .bit_pulse
= NEC_BIT_PULSE
,
225 .bit_space
[0] = NEC_BIT_0_SPACE
,
226 .bit_space
[1] = NEC_BIT_1_SPACE
,
227 .trailer_pulse
= NEC_TRAILER_PULSE
,
228 .trailer_space
= NEC_TRAILER_SPACE
,
233 * ir_nec_encode() - Encode a scancode as a stream of raw events
235 * @protocol: protocol to encode
236 * @scancode: scancode to encode
237 * @events: array of raw ir events to write into
238 * @max: maximum size of @events
240 * Returns: The number of events written.
241 * -ENOBUFS if there isn't enough space in the array to fit the
242 * encoding. In this case all @max events will have been written.
244 static int ir_nec_encode(enum rc_proto protocol
, u32 scancode
,
245 struct ir_raw_event
*events
, unsigned int max
)
247 struct ir_raw_event
*e
= events
;
251 /* Convert a NEC scancode to raw NEC data */
252 raw
= ir_nec_scancode_to_raw(protocol
, scancode
);
254 /* Modulate the raw data using a pulse distance modulation */
255 ret
= ir_raw_gen_pd(&e
, max
, &ir_nec_timings
, NEC_NBITS
, raw
);
262 static struct ir_raw_handler nec_handler
= {
263 .protocols
= RC_PROTO_BIT_NEC
| RC_PROTO_BIT_NECX
|
265 .decode
= ir_nec_decode
,
266 .encode
= ir_nec_encode
,
269 static int __init
ir_nec_decode_init(void)
271 ir_raw_handler_register(&nec_handler
);
273 printk(KERN_INFO
"IR NEC protocol handler initialized\n");
277 static void __exit
ir_nec_decode_exit(void)
279 ir_raw_handler_unregister(&nec_handler
);
282 module_init(ir_nec_decode_init
);
283 module_exit(ir_nec_decode_exit
);
285 MODULE_LICENSE("GPL");
286 MODULE_AUTHOR("Mauro Carvalho Chehab");
287 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
288 MODULE_DESCRIPTION("NEC IR protocol decoder");