1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * ImgTec IR Decoder setup for Philips RC-6 protocol. |
4 | * |
5 | * Copyright 2012-2014 Imagination Technologies Ltd. |
6 | */ |
7 | |
8 | #include "img-ir-hw.h" |
9 | |
10 | /* Convert RC6 data to a scancode */ |
11 | static int img_ir_rc6_scancode(int len, u64 raw, u64 enabled_protocols, |
12 | struct img_ir_scancode_req *request) |
13 | { |
14 | unsigned int addr, cmd, mode, trl1, trl2; |
15 | |
16 | /* |
17 | * Due to a side effect of the decoder handling the double length |
18 | * Trailer bit, the header information is a bit scrambled, and the |
19 | * raw data is shifted incorrectly. |
20 | * This workaround effectively recovers the header bits. |
21 | * |
22 | * The Header field should look like this: |
23 | * |
24 | * StartBit ModeBit2 ModeBit1 ModeBit0 TrailerBit |
25 | * |
26 | * But what we get is: |
27 | * |
28 | * ModeBit2 ModeBit1 ModeBit0 TrailerBit1 TrailerBit2 |
29 | * |
30 | * The start bit is not important to recover the scancode. |
31 | */ |
32 | |
33 | raw >>= 27; |
34 | |
35 | trl1 = (raw >> 17) & 0x01; |
36 | trl2 = (raw >> 16) & 0x01; |
37 | |
38 | mode = (raw >> 18) & 0x07; |
39 | addr = (raw >> 8) & 0xff; |
40 | cmd = raw & 0xff; |
41 | |
42 | /* |
43 | * Due to the above explained irregularity the trailer bits cannot |
44 | * have the same value. |
45 | */ |
46 | if (trl1 == trl2) |
47 | return -EINVAL; |
48 | |
49 | /* Only mode 0 supported for now */ |
50 | if (mode) |
51 | return -EINVAL; |
52 | |
53 | request->protocol = RC_PROTO_RC6_0; |
54 | request->scancode = addr << 8 | cmd; |
55 | request->toggle = trl2; |
56 | return IMG_IR_SCANCODE; |
57 | } |
58 | |
59 | /* Convert RC6 scancode to RC6 data filter */ |
60 | static int img_ir_rc6_filter(const struct rc_scancode_filter *in, |
61 | struct img_ir_filter *out, u64 protocols) |
62 | { |
63 | /* Not supported by the hw. */ |
64 | return -EINVAL; |
65 | } |
66 | |
67 | /* |
68 | * RC-6 decoder |
69 | * see http://www.sbprojects.com/knowledge/ir/rc6.php |
70 | */ |
71 | struct img_ir_decoder img_ir_rc6 = { |
72 | .type = RC_PROTO_BIT_RC6_0, |
73 | .control = { |
74 | .bitorien = 1, |
75 | .code_type = IMG_IR_CODETYPE_BIPHASE, |
76 | .decoden = 1, |
77 | .decodinpol = 1, |
78 | }, |
79 | /* main timings */ |
80 | .tolerance = 20, |
81 | /* |
82 | * Due to a quirk in the img-ir decoder, default header values do |
83 | * not work, the values described below were extracted from |
84 | * successful RTL test cases. |
85 | */ |
86 | .timings = { |
87 | /* leader symbol */ |
88 | .ldr = { |
89 | .pulse = { 650 }, |
90 | .space = { 660 }, |
91 | }, |
92 | /* 0 symbol */ |
93 | .s00 = { |
94 | .pulse = { 370 }, |
95 | .space = { 370 }, |
96 | }, |
97 | /* 01 symbol */ |
98 | .s01 = { |
99 | .pulse = { 370 }, |
100 | .space = { 370 }, |
101 | }, |
102 | /* free time */ |
103 | .ft = { |
104 | .minlen = 21, |
105 | .maxlen = 21, |
106 | .ft_min = 2666, /* 2.666 ms */ |
107 | }, |
108 | }, |
109 | |
110 | /* scancode logic */ |
111 | .scancode = img_ir_rc6_scancode, |
112 | .filter = img_ir_rc6_filter, |
113 | }; |
114 | |