1 // SPDX-License-Identifier: GPL-2.0-only
2 /* ir-sharp-decoder.c - handle Sharp IR Pulse/Space protocol
4 * Copyright (C) 2013-2014 Imagination Technologies Ltd.
6 * Based on NEC decoder:
7 * Copyright (C) 2010 by Mauro Carvalho Chehab
10 #include <linux/bitrev.h>
11 #include <linux/module.h>
12 #include "rc-core-priv.h"
14 #define SHARP_NBITS 15
15 #define SHARP_UNIT 40 /* us */
16 #define SHARP_BIT_PULSE (8 * SHARP_UNIT) /* 320us */
17 #define SHARP_BIT_0_PERIOD (25 * SHARP_UNIT) /* 1ms (680us space) */
18 #define SHARP_BIT_1_PERIOD (50 * SHARP_UNIT) /* 2ms (1680us space) */
19 #define SHARP_BIT_0_SPACE (17 * SHARP_UNIT) /* 680us space */
20 #define SHARP_BIT_1_SPACE (42 * SHARP_UNIT) /* 1680us space */
21 #define SHARP_ECHO_SPACE (1000 * SHARP_UNIT) /* 40 ms */
22 #define SHARP_TRAILER_SPACE (125 * SHARP_UNIT) /* 5 ms (even longer) */
34 * ir_sharp_decode() - Decode one Sharp pulse or space
35 * @dev: the struct rc_dev descriptor of the device
36 * @ev: the struct ir_raw_event descriptor of the pulse/space
38 * This function returns -EINVAL if the pulse violates the state machine
40 static int ir_sharp_decode(struct rc_dev
*dev
, struct ir_raw_event ev
)
42 struct sharp_dec
*data
= &dev
->raw
->sharp
;
43 u32 msg
, echo
, address
, command
, scancode
;
45 if (!is_timing_event(ev
)) {
47 data
->state
= STATE_INACTIVE
;
51 dev_dbg(&dev
->dev
, "Sharp decode started at state %d (%uus %s)\n",
52 data
->state
, ev
.duration
, TO_STR(ev
.pulse
));
54 switch (data
->state
) {
60 if (!eq_margin(ev
.duration
, SHARP_BIT_PULSE
,
65 data
->pulse_len
= ev
.duration
;
66 data
->state
= STATE_BIT_SPACE
;
73 if (!eq_margin(ev
.duration
, SHARP_BIT_PULSE
,
77 data
->pulse_len
= ev
.duration
;
78 data
->state
= STATE_BIT_SPACE
;
86 if (eq_margin(data
->pulse_len
+ ev
.duration
, SHARP_BIT_1_PERIOD
,
89 else if (!eq_margin(data
->pulse_len
+ ev
.duration
,
90 SHARP_BIT_0_PERIOD
, SHARP_BIT_PULSE
* 2))
94 if (data
->count
== SHARP_NBITS
||
95 data
->count
== SHARP_NBITS
* 2)
96 data
->state
= STATE_TRAILER_PULSE
;
98 data
->state
= STATE_BIT_PULSE
;
102 case STATE_TRAILER_PULSE
:
106 if (!eq_margin(ev
.duration
, SHARP_BIT_PULSE
,
107 SHARP_BIT_PULSE
/ 2))
110 if (data
->count
== SHARP_NBITS
) {
111 /* exp,chk bits should be 1,0 */
112 if ((data
->bits
& 0x3) != 0x2 &&
113 /* DENON variant, both chk bits 0 */
114 (data
->bits
& 0x3) != 0x0)
116 data
->state
= STATE_ECHO_SPACE
;
118 data
->state
= STATE_TRAILER_SPACE
;
122 case STATE_ECHO_SPACE
:
126 if (!eq_margin(ev
.duration
, SHARP_ECHO_SPACE
,
127 SHARP_ECHO_SPACE
/ 4))
130 data
->state
= STATE_BIT_PULSE
;
134 case STATE_TRAILER_SPACE
:
138 if (!geq_margin(ev
.duration
, SHARP_TRAILER_SPACE
,
139 SHARP_BIT_PULSE
/ 2))
142 /* Validate - command, ext, chk should be inverted in 2nd */
143 msg
= (data
->bits
>> 15) & 0x7fff;
144 echo
= data
->bits
& 0x7fff;
145 if ((msg
^ echo
) != 0x3ff) {
147 "Sharp checksum error: received 0x%04x, 0x%04x\n",
152 address
= bitrev8((msg
>> 7) & 0xf8);
153 command
= bitrev8((msg
>> 2) & 0xff);
155 scancode
= address
<< 8 | command
;
156 dev_dbg(&dev
->dev
, "Sharp scancode 0x%04x\n", scancode
);
158 rc_keydown(dev
, RC_PROTO_SHARP
, scancode
, 0);
159 data
->state
= STATE_INACTIVE
;
163 dev_dbg(&dev
->dev
, "Sharp decode failed at count %d state %d (%uus %s)\n",
164 data
->count
, data
->state
, ev
.duration
, TO_STR(ev
.pulse
));
165 data
->state
= STATE_INACTIVE
;
169 static const struct ir_raw_timings_pd ir_sharp_timings
= {
172 .bit_pulse
= SHARP_BIT_PULSE
,
173 .bit_space
[0] = SHARP_BIT_0_SPACE
,
174 .bit_space
[1] = SHARP_BIT_1_SPACE
,
175 .trailer_pulse
= SHARP_BIT_PULSE
,
176 .trailer_space
= SHARP_ECHO_SPACE
,
181 * ir_sharp_encode() - Encode a scancode as a stream of raw events
183 * @protocol: protocol to encode
184 * @scancode: scancode to encode
185 * @events: array of raw ir events to write into
186 * @max: maximum size of @events
188 * Returns: The number of events written.
189 * -ENOBUFS if there isn't enough space in the array to fit the
190 * encoding. In this case all @max events will have been written.
192 static int ir_sharp_encode(enum rc_proto protocol
, u32 scancode
,
193 struct ir_raw_event
*events
, unsigned int max
)
195 struct ir_raw_event
*e
= events
;
199 raw
= (((bitrev8(scancode
>> 8) >> 3) << 8) & 0x1f00) |
201 ret
= ir_raw_gen_pd(&e
, max
, &ir_sharp_timings
, SHARP_NBITS
,
208 raw
= (((bitrev8(scancode
>> 8) >> 3) << 8) & 0x1f00) |
210 ret
= ir_raw_gen_pd(&e
, max
, &ir_sharp_timings
, SHARP_NBITS
,
218 static struct ir_raw_handler sharp_handler
= {
219 .protocols
= RC_PROTO_BIT_SHARP
,
220 .decode
= ir_sharp_decode
,
221 .encode
= ir_sharp_encode
,
223 .min_timeout
= SHARP_ECHO_SPACE
+ SHARP_ECHO_SPACE
/ 4,
226 static int __init
ir_sharp_decode_init(void)
228 ir_raw_handler_register(&sharp_handler
);
230 pr_info("IR Sharp protocol handler initialized\n");
234 static void __exit
ir_sharp_decode_exit(void)
236 ir_raw_handler_unregister(&sharp_handler
);
239 module_init(ir_sharp_decode_init
);
240 module_exit(ir_sharp_decode_exit
);
242 MODULE_LICENSE("GPL");
243 MODULE_AUTHOR("James Hogan <jhogan@kernel.org>");
244 MODULE_DESCRIPTION("Sharp IR protocol decoder");