aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/ir-nec-decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/IR/ir-nec-decoder.c')
-rw-r--r--drivers/media/IR/ir-nec-decoder.c120
1 files changed, 67 insertions, 53 deletions
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
index 14609d9580a8..ba79233112ef 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -17,13 +17,15 @@
17 17
18#define NEC_NBITS 32 18#define NEC_NBITS 32
19#define NEC_UNIT 562500 /* ns */ 19#define NEC_UNIT 562500 /* ns */
20#define NEC_HEADER_PULSE PULSE(16) 20#define NEC_HEADER_PULSE (16 * NEC_UNIT)
21#define NECX_HEADER_PULSE PULSE(8) /* Less common NEC variant */ 21#define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */
22#define NEC_HEADER_SPACE SPACE(8) 22#define NEC_HEADER_SPACE (8 * NEC_UNIT)
23#define NEC_REPEAT_SPACE SPACE(4) 23#define NEC_REPEAT_SPACE (8 * NEC_UNIT)
24#define NEC_BIT_PULSE PULSE(1) 24#define NEC_BIT_PULSE (1 * NEC_UNIT)
25#define NEC_BIT_0_SPACE SPACE(1) 25#define NEC_BIT_0_SPACE (1 * NEC_UNIT)
26#define NEC_BIT_1_SPACE SPACE(3) 26#define NEC_BIT_1_SPACE (3 * NEC_UNIT)
27#define NEC_TRAILER_PULSE (1 * NEC_UNIT)
28#define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */
27 29
28/* Used to register nec_decoder clients */ 30/* Used to register nec_decoder clients */
29static LIST_HEAD(decoder_list); 31static LIST_HEAD(decoder_list);
@@ -119,15 +121,14 @@ static struct attribute_group decoder_attribute_group = {
119/** 121/**
120 * ir_nec_decode() - Decode one NEC pulse or space 122 * ir_nec_decode() - Decode one NEC pulse or space
121 * @input_dev: the struct input_dev descriptor of the device 123 * @input_dev: the struct input_dev descriptor of the device
122 * @duration: duration in ns of pulse/space 124 * @duration: the struct ir_raw_event descriptor of the pulse/space
123 * 125 *
124 * This function returns -EINVAL if the pulse violates the state machine 126 * This function returns -EINVAL if the pulse violates the state machine
125 */ 127 */
126static int ir_nec_decode(struct input_dev *input_dev, s64 duration) 128static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
127{ 129{
128 struct decoder_data *data; 130 struct decoder_data *data;
129 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); 131 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
130 int u;
131 u32 scancode; 132 u32 scancode;
132 u8 address, not_address, command, not_command; 133 u8 address, not_address, command, not_command;
133 134
@@ -138,59 +139,88 @@ static int ir_nec_decode(struct input_dev *input_dev, s64 duration)
138 if (!data->enabled) 139 if (!data->enabled)
139 return 0; 140 return 0;
140 141
141 if (IS_RESET(duration)) { 142 if (IS_RESET(ev)) {
142 data->state = STATE_INACTIVE; 143 data->state = STATE_INACTIVE;
143 return 0; 144 return 0;
144 } 145 }
145 146
146 u = TO_UNITS(duration, NEC_UNIT); 147 IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n",
147 if (DURATION(u) == 0) 148 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
148 goto out;
149
150 IR_dprintk(2, "NEC decode started at state %d (%i units, %ius)\n",
151 data->state, u, TO_US(duration));
152 149
153 switch (data->state) { 150 switch (data->state) {
154 151
155 case STATE_INACTIVE: 152 case STATE_INACTIVE:
156 if (u == NEC_HEADER_PULSE || u == NECX_HEADER_PULSE) { 153 if (!ev.pulse)
157 data->count = 0; 154 break;
158 data->state = STATE_HEADER_SPACE; 155
159 } 156 if (!eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2) &&
157 !eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
158 break;
159
160 data->count = 0;
161 data->state = STATE_HEADER_SPACE;
160 return 0; 162 return 0;
161 163
162 case STATE_HEADER_SPACE: 164 case STATE_HEADER_SPACE:
163 if (u == NEC_HEADER_SPACE) { 165 if (ev.pulse)
166 break;
167
168 if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) {
164 data->state = STATE_BIT_PULSE; 169 data->state = STATE_BIT_PULSE;
165 return 0; 170 return 0;
166 } else if (u == NEC_REPEAT_SPACE) { 171 } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
167 ir_repeat(input_dev); 172 ir_repeat(input_dev);
168 IR_dprintk(1, "Repeat last key\n"); 173 IR_dprintk(1, "Repeat last key\n");
169 data->state = STATE_TRAILER_PULSE; 174 data->state = STATE_TRAILER_PULSE;
170 return 0; 175 return 0;
171 } 176 }
177
172 break; 178 break;
173 179
174 case STATE_BIT_PULSE: 180 case STATE_BIT_PULSE:
175 if (u == NEC_BIT_PULSE) { 181 if (!ev.pulse)
176 data->state = STATE_BIT_SPACE; 182 break;
177 return 0; 183
178 } 184 if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2))
179 break; 185 break;
186
187 data->state = STATE_BIT_SPACE;
188 return 0;
180 189
181 case STATE_BIT_SPACE: 190 case STATE_BIT_SPACE:
182 if (u != NEC_BIT_0_SPACE && u != NEC_BIT_1_SPACE) 191 if (ev.pulse)
183 break; 192 break;
184 193
185 data->nec_bits <<= 1; 194 data->nec_bits <<= 1;
186 if (u == NEC_BIT_1_SPACE) 195 if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
187 data->nec_bits |= 1; 196 data->nec_bits |= 1;
197 else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
198 break;
188 data->count++; 199 data->count++;
189 200
190 if (data->count != NEC_NBITS) { 201 if (data->count == NEC_NBITS)
202 data->state = STATE_TRAILER_PULSE;
203 else
191 data->state = STATE_BIT_PULSE; 204 data->state = STATE_BIT_PULSE;
192 return 0; 205
193 } 206 return 0;
207
208 case STATE_TRAILER_PULSE:
209 if (!ev.pulse)
210 break;
211
212 if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2))
213 break;
214
215 data->state = STATE_TRAILER_SPACE;
216 return 0;
217
218 case STATE_TRAILER_SPACE:
219 if (ev.pulse)
220 break;
221
222 if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
223 break;
194 224
195 address = bitrev8((data->nec_bits >> 24) & 0xff); 225 address = bitrev8((data->nec_bits >> 24) & 0xff);
196 not_address = bitrev8((data->nec_bits >> 16) & 0xff); 226 not_address = bitrev8((data->nec_bits >> 16) & 0xff);
@@ -210,34 +240,18 @@ static int ir_nec_decode(struct input_dev *input_dev, s64 duration)
210 command; 240 command;
211 IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode); 241 IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode);
212 } else { 242 } else {
213 /* normal NEC */ 243 /* Normal NEC */
214 scancode = address << 8 | command; 244 scancode = address << 8 | command;
215 IR_dprintk(1, "NEC scancode 0x%04x\n", scancode); 245 IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
216 } 246 }
217 247
218 ir_keydown(input_dev, scancode, 0); 248 ir_keydown(input_dev, scancode, 0);
219 data->state = STATE_TRAILER_PULSE; 249 data->state = STATE_INACTIVE;
220 return 0; 250 return 0;
221
222 case STATE_TRAILER_PULSE:
223 if (u > 0) {
224 data->state = STATE_TRAILER_SPACE;
225 return 0;
226 }
227 break;
228
229 case STATE_TRAILER_SPACE:
230 if (u < 0) {
231 data->state = STATE_INACTIVE;
232 return 0;
233 }
234
235 break;
236 } 251 }
237 252
238out: 253 IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n",
239 IR_dprintk(1, "NEC decode failed at state %d (%i units, %ius)\n", 254 data->state, TO_US(ev.duration), TO_STR(ev.pulse));
240 data->state, u, TO_US(duration));
241 data->state = STATE_INACTIVE; 255 data->state = STATE_INACTIVE;
242 return -EINVAL; 256 return -EINVAL;
243} 257}