aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/em28xx/em28xx-input.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-12-15 06:29:12 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-12-21 18:16:19 -0500
commit0dae88392395e228e67436cd08f084d395b39df5 (patch)
tree602c98d27267dcefefc03a71323fb075fa0fe767 /drivers/media/usb/em28xx/em28xx-input.c
parent105e3687ada4ebe6dfbda7abc3b16106f86a787d (diff)
[media] em28xx: add support for RC6 mode 0 on devices that support it
Newer em28xx chipsets (em2874 and upper) are capable of supporting RC6 codes, on both mode 0 (command mode, 16 bits payload size, similar to RC5, also called "Philips mode") and mode 6a (OEM command mode, with offers a few alternatives with regards to the payload size). I don't have any mode 6a control ATM to test it, so, I opted to add support only to mode 0. After this patch, adding support to mode 6a should not be hard. Tested with a Philips television remote controller. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/em28xx/em28xx-input.c')
-rw-r--r--drivers/media/usb/em28xx/em28xx-input.c93
1 files changed, 76 insertions, 17 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index 507370c5217d..3899ea823336 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -285,6 +285,9 @@ static int em2874_polling_getkey(struct em28xx_IR *ir,
285 else /* Normal NEC */ 285 else /* Normal NEC */
286 poll_result->scancode = msg[1] << 8 | msg[3]; 286 poll_result->scancode = msg[1] << 8 | msg[3];
287 break; 287 break;
288 case RC_BIT_RC6_0:
289 poll_result->scancode = msg[1] << 8 | msg[2];
290 break;
288 default: 291 default:
289 poll_result->scancode = (msg[1] << 24) | (msg[2] << 16) | 292 poll_result->scancode = (msg[1] << 24) | (msg[2] << 16) |
290 (msg[3] << 8) | msg[4]; 293 (msg[3] << 8) | msg[4];
@@ -361,15 +364,42 @@ static void em28xx_ir_stop(struct rc_dev *rc)
361 cancel_delayed_work_sync(&ir->work); 364 cancel_delayed_work_sync(&ir->work);
362} 365}
363 366
364static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) 367static int em2860_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
365{ 368{
366 int rc = 0;
367 struct em28xx_IR *ir = rc_dev->priv; 369 struct em28xx_IR *ir = rc_dev->priv;
368 struct em28xx *dev = ir->dev; 370 struct em28xx *dev = ir->dev;
369 u8 ir_config = EM2874_IR_RC5;
370 371
371 /* Adjust xclk based o IR table for RC5/NEC tables */ 372 /* Adjust xclk based on IR table for RC5/NEC tables */
373 if (*rc_type & RC_BIT_RC5) {
374 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
375 ir->full_code = 1;
376 *rc_type = RC_BIT_RC5;
377 } else if (*rc_type & RC_BIT_NEC) {
378 dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
379 ir->full_code = 1;
380 *rc_type = RC_BIT_NEC;
381 } else if (*rc_type & RC_BIT_UNKNOWN) {
382 *rc_type = RC_BIT_UNKNOWN;
383 } else {
384 *rc_type = ir->rc_type;
385 return -EINVAL;
386 }
387 ir->get_key = default_polling_getkey;
388 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
389 EM28XX_XCLK_IR_RC5_MODE);
390
391 ir->rc_type = *rc_type;
372 392
393 return 0;
394}
395
396static int em2874_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
397{
398 struct em28xx_IR *ir = rc_dev->priv;
399 struct em28xx *dev = ir->dev;
400 u8 ir_config = EM2874_IR_RC5;
401
402 /* Adjust xclk and set type based on IR table for RC5/NEC/RC6 tables */
373 if (*rc_type & RC_BIT_RC5) { 403 if (*rc_type & RC_BIT_RC5) {
374 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; 404 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
375 ir->full_code = 1; 405 ir->full_code = 1;
@@ -379,33 +409,47 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
379 ir_config = EM2874_IR_NEC | EM2874_IR_NEC_NO_PARITY; 409 ir_config = EM2874_IR_NEC | EM2874_IR_NEC_NO_PARITY;
380 ir->full_code = 1; 410 ir->full_code = 1;
381 *rc_type = RC_BIT_NEC; 411 *rc_type = RC_BIT_NEC;
382 } else if (*rc_type != RC_BIT_UNKNOWN) 412 } else if (*rc_type & RC_BIT_RC6_0) {
383 rc = -EINVAL; 413 dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
414 ir_config = EM2874_IR_RC6_MODE_0;
415 ir->full_code = 1;
416 *rc_type = RC_BIT_RC6_0;
417 } else if (*rc_type & RC_BIT_UNKNOWN) {
418 *rc_type = RC_BIT_UNKNOWN;
419 } else {
420 *rc_type = ir->rc_type;
421 return -EINVAL;
422 }
384 423
385 ir->rc_type = *rc_type; 424 ir->get_key = em2874_polling_getkey;
425 em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1);
386 426
387 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, 427 em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
388 EM28XX_XCLK_IR_RC5_MODE); 428 EM28XX_XCLK_IR_RC5_MODE);
389 429
430 ir->rc_type = *rc_type;
431
432 return 0;
433}
434static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
435{
436 struct em28xx_IR *ir = rc_dev->priv;
437 struct em28xx *dev = ir->dev;
438
390 /* Setup the proper handler based on the chip */ 439 /* Setup the proper handler based on the chip */
391 switch (dev->chip_id) { 440 switch (dev->chip_id) {
392 case CHIP_ID_EM2860: 441 case CHIP_ID_EM2860:
393 case CHIP_ID_EM2883: 442 case CHIP_ID_EM2883:
394 ir->get_key = default_polling_getkey; 443 return em2860_ir_change_protocol(rc_dev, rc_type);
395 break;
396 case CHIP_ID_EM2884: 444 case CHIP_ID_EM2884:
397 case CHIP_ID_EM2874: 445 case CHIP_ID_EM2874:
398 case CHIP_ID_EM28174: 446 case CHIP_ID_EM28174:
399 ir->get_key = em2874_polling_getkey; 447 return em2874_ir_change_protocol(rc_dev, rc_type);
400 em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1);
401 break;
402 default: 448 default:
403 printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n", 449 printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n",
404 dev->chip_id); 450 dev->chip_id);
405 rc = -EINVAL; 451 return -EINVAL;
406 } 452 }
407
408 return rc;
409} 453}
410 454
411static void em28xx_register_i2c_ir(struct em28xx *dev) 455static void em28xx_register_i2c_ir(struct em28xx *dev)
@@ -573,6 +617,21 @@ static int em28xx_ir_init(struct em28xx *dev)
573 rc->open = em28xx_ir_start; 617 rc->open = em28xx_ir_start;
574 rc->close = em28xx_ir_stop; 618 rc->close = em28xx_ir_stop;
575 619
620 switch (dev->chip_id) {
621 case CHIP_ID_EM2860:
622 case CHIP_ID_EM2883:
623 rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC;
624 break;
625 case CHIP_ID_EM2884:
626 case CHIP_ID_EM2874:
627 case CHIP_ID_EM28174:
628 rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC | RC_BIT_RC6_0;
629 break;
630 default:
631 err = -ENODEV;
632 goto err_out_free;
633 }
634
576 /* By default, keep protocol field untouched */ 635 /* By default, keep protocol field untouched */
577 rc_type = RC_BIT_UNKNOWN; 636 rc_type = RC_BIT_UNKNOWN;
578 err = em28xx_ir_change_protocol(rc, &rc_type); 637 err = em28xx_ir_change_protocol(rc, &rc_type);
@@ -615,9 +674,9 @@ static int em28xx_ir_init(struct em28xx *dev)
615 674
616 return 0; 675 return 0;
617 676
618 err_out_stop: 677err_out_stop:
619 dev->ir = NULL; 678 dev->ir = NULL;
620 err_out_free: 679err_out_free:
621 rc_free_device(rc); 680 rc_free_device(rc);
622 kfree(ir); 681 kfree(ir);
623 return err; 682 return err;