aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/ir-nec-decoder.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-04-03 17:51:50 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-19 11:56:55 -0400
commit2f16f6315f583964732bc23c873d4024281d763c (patch)
treea20f719a7d4aef15a24f55f4c6e1aaaa90c8a8b7 /drivers/media/IR/ir-nec-decoder.c
parent13c24497086418010bf4f76378bcae241d7f59cd (diff)
V4L/DVB: ir-nec-decoder: Reimplement the entire decoder
Thanks to Andy Walls <awalls@md.metrocast.net> for pointing me his code, that gave me some ideas to better implement it. After some work with saa7134 bits, I found a way to catch both IRQ edge pulses. By enabling it, the NEC decoder can now take both pulse and spaces into account, making it more precise. Instead of the old strategy of handling the events all at once, this code implements a state machine. Due to that, it handles individual pulse or space events, validating them against the protocol, producing a much more reliable decoding. With the new implementation, the protocol trailer bits are properly handled, making possible for the repeat key to work. Also, the code is now capable of handling both NEC and NEC extended IR devices. With NEC, it produces a 16 bits code, while with NEC extended, a 24 bits code is returned. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/IR/ir-nec-decoder.c')
-rw-r--r--drivers/media/IR/ir-nec-decoder.c271
1 files changed, 167 insertions, 104 deletions
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
index 0b50060ffbaf..33b260f517f5 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -14,6 +14,14 @@
14 14
15#include <media/ir-core.h> 15#include <media/ir-core.h>
16 16
17#define NEC_UNIT 559979 /* ns */
18#define NEC_HEADER_MARK (16 * NEC_UNIT)
19#define NEC_HEADER_SPACE (8 * NEC_UNIT)
20#define NEC_REPEAT_SPACE (4 * NEC_UNIT)
21#define NEC_MARK (NEC_UNIT)
22#define NEC_0_SYMBOL (NEC_UNIT)
23#define NEC_1_SYMBOL (3 * NEC_UNIT)
24
17/* Start time: 4.5 ms + 560 us of the next pulse */ 25/* Start time: 4.5 ms + 560 us of the next pulse */
18#define MIN_START_TIME (3900000 + 560000) 26#define MIN_START_TIME (3900000 + 560000)
19#define MAX_START_TIME (5100000 + 560000) 27#define MAX_START_TIME (5100000 + 560000)
@@ -43,10 +51,32 @@
43static LIST_HEAD(decoder_list); 51static LIST_HEAD(decoder_list);
44static spinlock_t decoder_lock; 52static spinlock_t decoder_lock;
45 53
54enum nec_state {
55 STATE_INACTIVE,
56 STATE_HEADER_MARK,
57 STATE_HEADER_SPACE,
58 STATE_MARK,
59 STATE_SPACE,
60 STATE_TRAILER_MARK,
61 STATE_TRAILER_SPACE,
62};
63
64struct nec_code {
65 u8 address;
66 u8 not_address;
67 u8 command;
68 u8 not_command;
69};
70
46struct decoder_data { 71struct decoder_data {
47 struct list_head list; 72 struct list_head list;
48 struct ir_input_dev *ir_dev; 73 struct ir_input_dev *ir_dev;
49 int enabled:1; 74 int enabled:1;
75
76 /* State machine control */
77 enum nec_state state;
78 struct nec_code nec_code;
79 unsigned count;
50}; 80};
51 81
52 82
@@ -118,139 +148,173 @@ static struct attribute_group decoder_attribute_group = {
118}; 148};
119 149
120 150
121/** is_repeat - Check if it is a NEC repeat event 151/**
152 * handle_event() - Decode one NEC pulse or space
122 * @input_dev: the struct input_dev descriptor of the device 153 * @input_dev: the struct input_dev descriptor of the device
123 * @pos: the position of the first event 154 * @ev: event array with type/duration of pulse/space
124 * @len: the length of the buffer 155 *
156 * This function returns -EINVAL if the pulse violates the state machine
125 */ 157 */
126static int is_repeat(struct ir_raw_event *evs, int len, int pos) 158static int handle_event(struct input_dev *input_dev,
159 struct ir_raw_event *ev)
127{ 160{
128 if ((evs[pos].delta.tv_nsec < MIN_REPEAT_START_TIME) || 161 struct decoder_data *data;
129 (evs[pos].delta.tv_nsec > MAX_REPEAT_START_TIME)) 162 struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
130 return 0; 163 int bit, last_bit;
131 164
132 if (++pos >= len) 165 data = get_decoder_data(ir_dev);
133 return 0; 166 if (!data)
167 return -EINVAL;
134 168
135 if ((evs[pos].delta.tv_nsec < MIN_REPEAT_TIME) || 169 /* Except for the initial event, what matters is the previous bit */
136 (evs[pos].delta.tv_nsec > MAX_REPEAT_TIME)) 170 bit = (ev->type & IR_PULSE) ? 1 : 0;
137 return 0;
138 171
139 return 1; 172 last_bit = !bit;
140}
141 173
142/** 174 /* Discards spurious space last_bits when inactive */
143 * __ir_nec_decode() - Decode one NEC pulsecode
144 * @input_dev: the struct input_dev descriptor of the device
145 * @evs: event array with type/duration of pulse/space
146 * @len: length of the array
147 * @pos: position to start seeking for a code
148 * This function returns -EINVAL if no pulse got decoded,
149 * 0 if buffer is empty and 1 if one keycode were handled.
150 */
151static int __ir_nec_decode(struct input_dev *input_dev,
152 struct ir_raw_event *evs,
153 int len, int *pos)
154{
155 struct ir_input_dev *ir = input_get_drvdata(input_dev);
156 int count = -1;
157 int ircode = 0, not_code = 0;
158
159 /* Be sure that the first event is an start one and is a pulse */
160 for (; *pos < len; (*pos)++) {
161 /* Very long delays are considered as start events */
162 if (evs[*pos].delta.tv_nsec > MAX_NEC_TIME)
163 break;
164 if (evs[*pos].type & IR_START_EVENT)
165 break;
166 IR_dprintk(1, "%luus: Spurious NEC %s\n",
167 (evs[*pos].delta.tv_nsec + 500) / 1000,
168 (evs[*pos].type & IR_SPACE) ? "space" : "pulse");
169 175
170 } 176 /* Very long delays are considered as start events */
171 if (*pos >= len) 177 if (ev->delta.tv_nsec > NEC_HEADER_MARK + NEC_HEADER_SPACE - NEC_UNIT / 2)
172 return 0; 178 data->state = STATE_INACTIVE;
173 179
174 (*pos)++; /* First event doesn't contain data */ 180 if (ev->type & IR_START_EVENT)
181 data->state = STATE_INACTIVE;
175 182
176 if (evs[*pos].type != IR_PULSE) 183 switch (data->state) {
177 goto err; 184 case STATE_INACTIVE:
185 if (!bit) /* PULSE marks the start event */
186 return 0;
178 187
179 /* Check if it is a NEC repeat event */ 188 data->count = 0;
180 if (is_repeat(evs, len, *pos)) { 189 data->state = STATE_HEADER_MARK;
181 *pos += 2; 190 memset (&data->nec_code, 0, sizeof(data->nec_code));
182 if (ir->keypressed) { 191 return 0;
183 ir_repeat(input_dev); 192 case STATE_HEADER_MARK:
184 IR_dprintk(1, "NEC repeat event\n"); 193 if (!last_bit)
185 return 1; 194 goto err;
186 } else { 195 if (ev->delta.tv_nsec < NEC_HEADER_MARK - 6 * NEC_UNIT)
187 IR_dprintk(1, "missing NEC repeat event\n"); 196 goto err;
197 data->state = STATE_HEADER_SPACE;
198 return 0;
199 case STATE_HEADER_SPACE:
200 if (last_bit)
201 goto err;
202 if (ev->delta.tv_nsec >= NEC_HEADER_SPACE - NEC_UNIT / 2) {
203 data->state = STATE_MARK;
188 return 0; 204 return 0;
189 } 205 }
190 }
191 206
192 /* First space should have 4.5 ms otherwise is not NEC protocol */ 207 if (ev->delta.tv_nsec >= NEC_REPEAT_SPACE - NEC_UNIT / 2) {
193 if ((evs[*pos].delta.tv_nsec < MIN_START_TIME) || 208 ir_repeat(input_dev);
194 (evs[*pos].delta.tv_nsec > MAX_START_TIME)) 209 IR_dprintk(1, "Repeat last key\n");
210 data->state = STATE_TRAILER_MARK;
211 return 0;
212 }
195 goto err; 213 goto err;
214 case STATE_MARK:
215 if (!last_bit)
216 goto err;
217 if ((ev->delta.tv_nsec > NEC_MARK + NEC_UNIT / 2) ||
218 (ev->delta.tv_nsec < NEC_MARK - NEC_UNIT / 2))
219 goto err;
220 data->state = STATE_SPACE;
221 return 0;
222 case STATE_SPACE:
223 if (last_bit)
224 goto err;
196 225
197 count = 0; 226 if ((ev->delta.tv_nsec >= NEC_0_SYMBOL - NEC_UNIT / 2) &&
198 for ((*pos)++; *pos < len; (*pos)++) { 227 (ev->delta.tv_nsec < NEC_0_SYMBOL + NEC_UNIT / 2))
199 int bit;
200 if ((evs[*pos].delta.tv_nsec > MIN_BIT1_TIME) &&
201 (evs[*pos].delta.tv_nsec < MAX_BIT1_TIME))
202 bit = 1;
203 else if ((evs[*pos].delta.tv_nsec > MIN_BIT0_TIME) &&
204 (evs[*pos].delta.tv_nsec < MAX_BIT0_TIME))
205 bit = 0; 228 bit = 0;
206 else 229 else if ((ev->delta.tv_nsec >= NEC_1_SYMBOL - NEC_UNIT / 2) &&
207 goto err; 230 (ev->delta.tv_nsec < NEC_1_SYMBOL + NEC_UNIT / 2))
231 bit = 1;
232 else {
233 IR_dprintk(1, "Decode failed at %d-th bit (%s) @%luus\n",
234 data->count,
235 last_bit ? "pulse" : "space",
236 (ev->delta.tv_nsec + 500) / 1000);
237
238 goto err2;
239 }
208 240
241 /* Ok, we've got a valid bit. proccess it */
209 if (bit) { 242 if (bit) {
210 int shift = count; 243 int shift = data->count;
211 /* Address first, then command */ 244
245 /*
246 * NEC transmit bytes on this temporal order:
247 * address | not address | command | not command
248 */
212 if (shift < 8) { 249 if (shift < 8) {
213 shift += 8; 250 data->nec_code.address |= 1 << shift;
214 ircode |= 1 << shift;
215 } else if (shift < 16) { 251 } else if (shift < 16) {
216 not_code |= 1 << shift; 252 data->nec_code.not_address |= 1 << (shift - 8);
217 } else if (shift < 24) { 253 } else if (shift < 24) {
218 shift -= 16; 254 data->nec_code.command |= 1 << (shift - 16);
219 ircode |= 1 << shift;
220 } else { 255 } else {
221 shift -= 24; 256 data->nec_code.not_command |= 1 << (shift - 24);
222 not_code |= 1 << shift;
223 } 257 }
224 } 258 }
225 if (++count == 32) 259 if (++data->count == 32) {
226 break; 260 u32 scancode;
227 } 261 /*
228 (*pos)++; 262 * Fixme: may need to accept Extended NEC protocol?
229 263 */
230 /* 264 if ((data->nec_code.command ^ data->nec_code.not_command) != 0xff)
231 * Fixme: may need to accept Extended NEC protocol? 265 goto checksum_err;
232 */ 266
233 if ((ircode & ~not_code) != ircode) { 267 if ((data->nec_code.address ^ data->nec_code.not_address) != 0xff) {
234 IR_dprintk(1, "NEC checksum error: code 0x%04x, not-code 0x%04x\n", 268 /* Extended NEC */
235 ircode, not_code); 269 scancode = data->nec_code.address << 16 |
236 return -EINVAL; 270 data->nec_code.not_address << 8 |
237 } 271 data->nec_code.command;
272 IR_dprintk(1, "NEC scancode 0x%06x\n", scancode);
273 } else {
274 /* normal NEC */
275 scancode = data->nec_code.address << 8 |
276 data->nec_code.command;
277 IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
278 }
279 ir_keydown(input_dev, scancode, 0);
238 280
239 IR_dprintk(1, "NEC scancode 0x%04x\n", ircode); 281 data->state = STATE_TRAILER_MARK;
240 ir_keydown(input_dev, ircode, 0); 282 } else
283 data->state = STATE_MARK;
284 return 0;
285 case STATE_TRAILER_MARK:
286 if (!last_bit)
287 goto err;
288 data->state = STATE_TRAILER_SPACE;
289 return 0;
290 case STATE_TRAILER_SPACE:
291 if (last_bit)
292 goto err;
293 data->state = STATE_INACTIVE;
294 return 0;
295 }
241 296
242 return 1;
243err: 297err:
244 IR_dprintk(1, "NEC decoded failed at bit %d (%s) while decoding %luus time\n", 298 IR_dprintk(1, "NEC decoded failed at state %d (%s) @ %luus\n",
245 count, 299 data->state,
246 (evs[*pos].type & IR_SPACE) ? "space" : "pulse", 300 bit ? "pulse" : "space",
247 (evs[*pos].delta.tv_nsec + 500) / 1000); 301 (ev->delta.tv_nsec + 500) / 1000);
302err2:
303 data->state = STATE_INACTIVE;
304 return -EINVAL;
248 305
306checksum_err:
307 data->state = STATE_INACTIVE;
308 IR_dprintk(1, "NEC checksum error: received 0x%02x%02x%02x%02x\n",
309 data->nec_code.address,
310 data->nec_code.not_address,
311 data->nec_code.command,
312 data->nec_code.not_command);
249 return -EINVAL; 313 return -EINVAL;
250} 314}
251 315
252/** 316/**
253 * __ir_nec_decode() - Decodes all NEC pulsecodes on a given array 317 * ir_nec_decode() - Decodes all NEC pulsecodes on a given array
254 * @input_dev: the struct input_dev descriptor of the device 318 * @input_dev: the struct input_dev descriptor of the device
255 * @evs: event array with type/duration of pulse/space 319 * @evs: event array with type/duration of pulse/space
256 * @len: length of the array 320 * @len: length of the array
@@ -269,10 +333,9 @@ static int ir_nec_decode(struct input_dev *input_dev,
269 if (!data || !data->enabled) 333 if (!data || !data->enabled)
270 return 0; 334 return 0;
271 335
272 while (pos < len) { 336 for (pos = 0; pos < len; pos++)
273 if (__ir_nec_decode(input_dev, evs, len, &pos) > 0) 337 handle_event(input_dev, &evs[pos]);
274 rc++; 338
275 }
276 return rc; 339 return rc;
277} 340}
278 341