diff options
author | Hermann Pitton <hermann-pitton@arcor.de> | 2006-12-07 19:45:28 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-02-21 10:34:12 -0500 |
commit | 9160723ed620f31bf38332dee02041b1cb4c9967 (patch) | |
tree | 1e2bbbb78b98d9c21a769634f908874f79cbc7ba /drivers/media/common/ir-functions.c | |
parent | c8f71b01a50597e298dc3214a2f2be7b8d31170c (diff) |
V4L/DVB (4961): Add support for the ASUS P7131 remote control
Besides adding the board specific code, this patch moves
the RC5 decoding code from bt8xx to ir-functions.c to make it available
for all drivers.
Signed-off-by: Marc Fargas <telenieko.telenieko.com>
Signed-off-by: Hermann Pitton <hermann-pitton@arcor.de>
Signed-off-by: Hartmut Hackmann <hartmut.hackmann@t-online.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/common/ir-functions.c')
-rw-r--r-- | drivers/media/common/ir-functions.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index 9a8dd8764c99..cbf7c0564889 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c | |||
@@ -256,6 +256,112 @@ int ir_decode_biphase(u32 *samples, int count, int low, int high) | |||
256 | return value; | 256 | return value; |
257 | } | 257 | } |
258 | 258 | ||
259 | /* RC5 decoding stuff, moved from bttv-input.c to share it with | ||
260 | * saa7134 */ | ||
261 | |||
262 | /* decode raw bit pattern to RC5 code */ | ||
263 | u32 ir_rc5_decode(unsigned int code) | ||
264 | { | ||
265 | unsigned int org_code = code; | ||
266 | unsigned int pair; | ||
267 | unsigned int rc5 = 0; | ||
268 | int i; | ||
269 | |||
270 | for (i = 0; i < 14; ++i) { | ||
271 | pair = code & 0x3; | ||
272 | code >>= 2; | ||
273 | |||
274 | rc5 <<= 1; | ||
275 | switch (pair) { | ||
276 | case 0: | ||
277 | case 2: | ||
278 | break; | ||
279 | case 1: | ||
280 | rc5 |= 1; | ||
281 | break; | ||
282 | case 3: | ||
283 | dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code); | ||
284 | return 0; | ||
285 | } | ||
286 | } | ||
287 | dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " | ||
288 | "instr=%x\n", rc5, org_code, RC5_START(rc5), | ||
289 | RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); | ||
290 | return rc5; | ||
291 | } | ||
292 | |||
293 | void ir_rc5_timer_end(unsigned long data) | ||
294 | { | ||
295 | struct card_ir *ir = (struct card_ir *)data; | ||
296 | struct timeval tv; | ||
297 | unsigned long current_jiffies, timeout; | ||
298 | u32 gap; | ||
299 | u32 rc5 = 0; | ||
300 | |||
301 | /* get time */ | ||
302 | current_jiffies = jiffies; | ||
303 | do_gettimeofday(&tv); | ||
304 | |||
305 | /* avoid overflow with gap >1s */ | ||
306 | if (tv.tv_sec - ir->base_time.tv_sec > 1) { | ||
307 | gap = 200000; | ||
308 | } else { | ||
309 | gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + | ||
310 | tv.tv_usec - ir->base_time.tv_usec; | ||
311 | } | ||
312 | |||
313 | /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */ | ||
314 | if (gap < 28000) { | ||
315 | dprintk(1, "ir-common: spurious timer_end\n"); | ||
316 | return; | ||
317 | } | ||
318 | |||
319 | ir->active = 0; | ||
320 | if (ir->last_bit < 20) { | ||
321 | /* ignore spurious codes (caused by light/other remotes) */ | ||
322 | dprintk(1, "ir-common: short code: %x\n", ir->code); | ||
323 | } else { | ||
324 | ir->code = (ir->code << ir->shift_by) | 1; | ||
325 | rc5 = ir_rc5_decode(ir->code); | ||
326 | |||
327 | /* two start bits? */ | ||
328 | if (RC5_START(rc5) != ir->start) { | ||
329 | dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5)); | ||
330 | |||
331 | /* right address? */ | ||
332 | } else if (RC5_ADDR(rc5) == ir->addr) { | ||
333 | u32 toggle = RC5_TOGGLE(rc5); | ||
334 | u32 instr = RC5_INSTR(rc5); | ||
335 | |||
336 | /* Good code, decide if repeat/repress */ | ||
337 | if (toggle != RC5_TOGGLE(ir->last_rc5) || | ||
338 | instr != RC5_INSTR(ir->last_rc5)) { | ||
339 | dprintk(1, "ir-common: instruction %x, toggle %x\n", instr, | ||
340 | toggle); | ||
341 | ir_input_nokey(ir->dev, &ir->ir); | ||
342 | ir_input_keydown(ir->dev, &ir->ir, instr, | ||
343 | instr); | ||
344 | } | ||
345 | |||
346 | /* Set/reset key-up timer */ | ||
347 | timeout = current_jiffies + (500 + ir->rc5_key_timeout | ||
348 | * HZ) / 1000; | ||
349 | mod_timer(&ir->timer_keyup, timeout); | ||
350 | |||
351 | /* Save code for repeat test */ | ||
352 | ir->last_rc5 = rc5; | ||
353 | } | ||
354 | } | ||
355 | } | ||
356 | |||
357 | void ir_rc5_timer_keyup(unsigned long data) | ||
358 | { | ||
359 | struct card_ir *ir = (struct card_ir *)data; | ||
360 | |||
361 | dprintk(1, "ir-common: key released\n"); | ||
362 | ir_input_nokey(ir->dev, &ir->ir); | ||
363 | } | ||
364 | |||
259 | EXPORT_SYMBOL_GPL(ir_input_init); | 365 | EXPORT_SYMBOL_GPL(ir_input_init); |
260 | EXPORT_SYMBOL_GPL(ir_input_nokey); | 366 | EXPORT_SYMBOL_GPL(ir_input_nokey); |
261 | EXPORT_SYMBOL_GPL(ir_input_keydown); | 367 | EXPORT_SYMBOL_GPL(ir_input_keydown); |
@@ -265,6 +371,10 @@ EXPORT_SYMBOL_GPL(ir_dump_samples); | |||
265 | EXPORT_SYMBOL_GPL(ir_decode_biphase); | 371 | EXPORT_SYMBOL_GPL(ir_decode_biphase); |
266 | EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); | 372 | EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); |
267 | 373 | ||
374 | EXPORT_SYMBOL_GPL(ir_rc5_decode); | ||
375 | EXPORT_SYMBOL_GPL(ir_rc5_timer_end); | ||
376 | EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup); | ||
377 | |||
268 | /* | 378 | /* |
269 | * Local variables: | 379 | * Local variables: |
270 | * c-basic-offset: 8 | 380 | * c-basic-offset: 8 |