1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ImgTec IR Decoder setup for NEC protocol.
5 * Copyright 2010-2014 Imagination Technologies Ltd.
9 #include <linux/bitrev.h>
10 #include <linux/log2.h>
12 /* Convert NEC data to a scancode */
13 static int img_ir_nec_scancode(int len
, u64 raw
, u64 enabled_protocols
,
14 struct img_ir_scancode_req
*request
)
16 unsigned int addr
, addr_inv
, data
, data_inv
;
17 /* a repeat code has no data */
19 return IMG_IR_REPEATCODE
;
22 /* raw encoding: ddDDaaAA */
23 addr
= (raw
>> 0) & 0xff;
24 addr_inv
= (raw
>> 8) & 0xff;
25 data
= (raw
>> 16) & 0xff;
26 data_inv
= (raw
>> 24) & 0xff;
27 if ((data_inv
^ data
) != 0xff) {
28 /* 32-bit NEC (used by Apple and TiVo remotes) */
29 /* scan encoding: as transmitted, MSBit = first received bit */
30 request
->scancode
= bitrev8(addr
) << 24 |
31 bitrev8(addr_inv
) << 16 |
34 request
->protocol
= RC_PROTO_NEC32
;
35 } else if ((addr_inv
^ addr
) != 0xff) {
37 /* scan encoding: AAaaDD */
38 request
->scancode
= addr
<< 16 |
41 request
->protocol
= RC_PROTO_NECX
;
44 /* scan encoding: AADD */
45 request
->scancode
= addr
<< 8 |
47 request
->protocol
= RC_PROTO_NEC
;
49 return IMG_IR_SCANCODE
;
52 /* Convert NEC scancode to NEC data filter */
53 static int img_ir_nec_filter(const struct rc_scancode_filter
*in
,
54 struct img_ir_filter
*out
, u64 protocols
)
56 unsigned int addr
, addr_inv
, data
, data_inv
;
57 unsigned int addr_m
, addr_inv_m
, data_m
, data_inv_m
;
59 data
= in
->data
& 0xff;
60 data_m
= in
->mask
& 0xff;
62 protocols
&= RC_PROTO_BIT_NEC
| RC_PROTO_BIT_NECX
| RC_PROTO_BIT_NEC32
;
65 * If only one bit is set, we were requested to do an exact
66 * protocol. This should be the case for wakeup filters; for
67 * normal filters, guess the protocol from the scancode.
69 if (!is_power_of_2(protocols
)) {
70 if ((in
->data
| in
->mask
) & 0xff000000)
71 protocols
= RC_PROTO_BIT_NEC32
;
72 else if ((in
->data
| in
->mask
) & 0x00ff0000)
73 protocols
= RC_PROTO_BIT_NECX
;
75 protocols
= RC_PROTO_BIT_NEC
;
78 if (protocols
== RC_PROTO_BIT_NEC32
) {
79 /* 32-bit NEC (used by Apple and TiVo remotes) */
80 /* scan encoding: as transmitted, MSBit = first received bit */
81 addr
= bitrev8(in
->data
>> 24);
82 addr_m
= bitrev8(in
->mask
>> 24);
83 addr_inv
= bitrev8(in
->data
>> 16);
84 addr_inv_m
= bitrev8(in
->mask
>> 16);
85 data
= bitrev8(in
->data
>> 8);
86 data_m
= bitrev8(in
->mask
>> 8);
87 data_inv
= bitrev8(in
->data
>> 0);
88 data_inv_m
= bitrev8(in
->mask
>> 0);
89 } else if (protocols
== RC_PROTO_BIT_NECX
) {
91 /* scan encoding AAaaDD */
92 addr
= (in
->data
>> 16) & 0xff;
93 addr_m
= (in
->mask
>> 16) & 0xff;
94 addr_inv
= (in
->data
>> 8) & 0xff;
95 addr_inv_m
= (in
->mask
>> 8) & 0xff;
96 data_inv
= data
^ 0xff;
100 /* scan encoding: AADD */
101 addr
= (in
->data
>> 8) & 0xff;
102 addr_m
= (in
->mask
>> 8) & 0xff;
103 addr_inv
= addr
^ 0xff;
105 data_inv
= data
^ 0xff;
109 /* raw encoding: ddDDaaAA */
110 out
->data
= data_inv
<< 24 |
114 out
->mask
= data_inv_m
<< 24 |
123 * See also http://www.sbprojects.com/knowledge/ir/nec.php
124 * http://wiki.altium.com/display/ADOH/NEC+Infrared+Transmission+Protocol
126 struct img_ir_decoder img_ir_nec
= {
127 .type
= RC_PROTO_BIT_NEC
| RC_PROTO_BIT_NECX
| RC_PROTO_BIT_NEC32
,
130 .code_type
= IMG_IR_CODETYPE_PULSEDIST
,
133 .unit
= 562500, /* 562.5 us */
137 .pulse
= { 16 /* 9ms */ },
138 .space
= { 8 /* 4.5ms */ },
142 .pulse
= { 1 /* 562.5 us */ },
143 .space
= { 1 /* 562.5 us */ },
147 .pulse
= { 1 /* 562.5 us */ },
148 .space
= { 3 /* 1687.5 us */ },
154 .ft_min
= 10, /* 5.625 ms */
158 .repeat
= 108, /* 108 ms */
162 .space
= { 4 /* 2.25 ms */ },
166 .minlen
= 0, /* repeat code has no data */
171 .scancode
= img_ir_nec_scancode
,
172 .filter
= img_ir_nec_filter
,