aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c226
-rw-r--r--drivers/media/video/saa7134/saa7134.h2
2 files changed, 221 insertions, 7 deletions
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 72562b8cf3be..fbb2ff171008 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -54,8 +54,11 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of "
54#define i2cdprintk(fmt, arg...) if (ir_debug) \ 54#define i2cdprintk(fmt, arg...) if (ir_debug) \
55 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg) 55 printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg)
56 56
57/* Helper function for raw decoding at GPIO16 or GPIO18 */ 57/* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */
58static int saa7134_rc5_irq(struct saa7134_dev *dev);
59static int saa7134_nec_irq(struct saa7134_dev *dev);
58static int saa7134_raw_decode_irq(struct saa7134_dev *dev); 60static int saa7134_raw_decode_irq(struct saa7134_dev *dev);
61static void nec_task(unsigned long data);
59 62
60/* -------------------- GPIO generic keycode builder -------------------- */ 63/* -------------------- GPIO generic keycode builder -------------------- */
61 64
@@ -394,8 +397,12 @@ void saa7134_input_irq(struct saa7134_dev *dev)
394 if (!ir->running) 397 if (!ir->running)
395 return; 398 return;
396 399
397 if (!ir->polling && !ir->raw_decode) { 400 if (ir->nec_gpio) {
401 saa7134_nec_irq(dev);
402 } else if (!ir->polling && !ir->rc5_gpio && !ir->raw_decode) {
398 build_key(dev); 403 build_key(dev);
404 } else if (ir->rc5_gpio) {
405 saa7134_rc5_irq(dev);
399 } else if (ir->raw_decode) { 406 } else if (ir->raw_decode) {
400 saa7134_raw_decode_irq(dev); 407 saa7134_raw_decode_irq(dev);
401 } 408 }
@@ -441,6 +448,17 @@ static int __saa7134_ir_start(void *priv)
441 (unsigned long)dev); 448 (unsigned long)dev);
442 ir->timer.expires = jiffies + HZ; 449 ir->timer.expires = jiffies + HZ;
443 add_timer(&ir->timer); 450 add_timer(&ir->timer);
451 } else if (ir->rc5_gpio) {
452 /* set timer_end for code completion */
453 init_timer(&ir->timer_end);
454 ir->timer_end.function = ir_rc5_timer_end;
455 ir->timer_end.data = (unsigned long)ir;
456 ir->shift_by = 2;
457 ir->start = 0x2;
458 ir->addr = 0x17;
459 ir->rc5_remote_gap = ir_rc5_remote_gap;
460 } else if (ir->nec_gpio) {
461 tasklet_init(&ir->tlet, nec_task, (unsigned long)dev);
444 } else if (ir->raw_decode) { 462 } else if (ir->raw_decode) {
445 /* set timer_end for code completion */ 463 /* set timer_end for code completion */
446 init_timer(&ir->timer_end); 464 init_timer(&ir->timer_end);
@@ -468,6 +486,10 @@ static void __saa7134_ir_stop(void *priv)
468 return; 486 return;
469 if (dev->remote->polling) 487 if (dev->remote->polling)
470 del_timer_sync(&dev->remote->timer); 488 del_timer_sync(&dev->remote->timer);
489 else if (ir->rc5_gpio)
490 del_timer_sync(&ir->timer_end);
491 else if (ir->nec_gpio)
492 tasklet_kill(&ir->tlet);
471 else if (ir->raw_decode) { 493 else if (ir->raw_decode) {
472 del_timer_sync(&ir->timer_end); 494 del_timer_sync(&ir->timer_end);
473 ir->active = 0; 495 ir->active = 0;
@@ -509,6 +531,40 @@ static void saa7134_ir_close(struct rc_dev *rc)
509 __saa7134_ir_stop(dev); 531 __saa7134_ir_stop(dev);
510} 532}
511 533
534
535static int saa7134_ir_change_protocol(struct rc_dev *rc, u64 ir_type)
536{
537 struct saa7134_dev *dev = rc->priv;
538 struct card_ir *ir = dev->remote;
539 u32 nec_gpio, rc5_gpio;
540
541 if (ir_type == IR_TYPE_RC5) {
542 dprintk("Changing protocol to RC5\n");
543 nec_gpio = 0;
544 rc5_gpio = 1;
545 } else if (ir_type == IR_TYPE_NEC) {
546 dprintk("Changing protocol to NEC\n");
547 nec_gpio = 1;
548 rc5_gpio = 0;
549 } else {
550 dprintk("IR protocol type %ud is not supported\n",
551 (unsigned)ir_type);
552 return -EINVAL;
553 }
554
555 if (ir->running) {
556 saa7134_ir_stop(dev);
557 ir->nec_gpio = nec_gpio;
558 ir->rc5_gpio = rc5_gpio;
559 saa7134_ir_start(dev);
560 } else {
561 ir->nec_gpio = nec_gpio;
562 ir->rc5_gpio = rc5_gpio;
563 }
564
565 return 0;
566}
567
512int saa7134_input_init1(struct saa7134_dev *dev) 568int saa7134_input_init1(struct saa7134_dev *dev)
513{ 569{
514 struct card_ir *ir; 570 struct card_ir *ir;
@@ -518,7 +574,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
518 u32 mask_keydown = 0; 574 u32 mask_keydown = 0;
519 u32 mask_keyup = 0; 575 u32 mask_keyup = 0;
520 int polling = 0; 576 int polling = 0;
577 int rc5_gpio = 0;
578 int nec_gpio = 0;
521 int raw_decode = 0; 579 int raw_decode = 0;
580 int allow_protocol_change = 0;
522 int err; 581 int err;
523 582
524 if (dev->has_remote != SAA7134_REMOTE_GPIO) 583 if (dev->has_remote != SAA7134_REMOTE_GPIO)
@@ -708,10 +767,9 @@ int saa7134_input_init1(struct saa7134_dev *dev)
708 break; 767 break;
709 case SAA7134_BOARD_ENCORE_ENLTV_FM53: 768 case SAA7134_BOARD_ENCORE_ENLTV_FM53:
710 ir_codes = RC_MAP_ENCORE_ENLTV_FM53; 769 ir_codes = RC_MAP_ENCORE_ENLTV_FM53;
711 mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ 770 mask_keydown = 0x0040000;
712 mask_keyup = 0x0040000; 771 mask_keycode = 0x00007f;
713 mask_keycode = 0xffff; 772 nec_gpio = 1;
714 raw_decode = 1;
715 break; 773 break;
716 case SAA7134_BOARD_10MOONSTVMASTER3: 774 case SAA7134_BOARD_10MOONSTVMASTER3:
717 ir_codes = RC_MAP_ENCORE_ENLTV; 775 ir_codes = RC_MAP_ENCORE_ENLTV;
@@ -771,6 +829,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
771 ir->mask_keydown = mask_keydown; 829 ir->mask_keydown = mask_keydown;
772 ir->mask_keyup = mask_keyup; 830 ir->mask_keyup = mask_keyup;
773 ir->polling = polling; 831 ir->polling = polling;
832 ir->rc5_gpio = rc5_gpio;
833 ir->nec_gpio = nec_gpio;
774 ir->raw_decode = raw_decode; 834 ir->raw_decode = raw_decode;
775 835
776 /* init input device */ 836 /* init input device */
@@ -785,6 +845,11 @@ int saa7134_input_init1(struct saa7134_dev *dev)
785 if (raw_decode) 845 if (raw_decode)
786 rc->driver_type = RC_DRIVER_IR_RAW; 846 rc->driver_type = RC_DRIVER_IR_RAW;
787 847
848 if (!raw_decode && allow_protocol_change) {
849 rc->allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
850 rc->change_protocol = saa7134_ir_change_protocol;
851 }
852
788 rc->input_name = ir->name; 853 rc->input_name = ir->name;
789 rc->input_phys = ir->phys; 854 rc->input_phys = ir->phys;
790 rc->input_id.bustype = BUS_PCI; 855 rc->input_id.bustype = BUS_PCI;
@@ -958,3 +1023,152 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
958 1023
959 return 1; 1024 return 1;
960} 1025}
1026
1027static int saa7134_rc5_irq(struct saa7134_dev *dev)
1028{
1029 struct card_ir *ir = dev->remote;
1030 struct timeval tv;
1031 u32 gap;
1032 unsigned long current_jiffies, timeout;
1033
1034 /* get time of bit */
1035 current_jiffies = jiffies;
1036 do_gettimeofday(&tv);
1037
1038 /* avoid overflow with gap >1s */
1039 if (tv.tv_sec - ir->base_time.tv_sec > 1) {
1040 gap = 200000;
1041 } else {
1042 gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
1043 tv.tv_usec - ir->base_time.tv_usec;
1044 }
1045
1046 /* active code => add bit */
1047 if (ir->active) {
1048 /* only if in the code (otherwise spurious IRQ or timer
1049 late) */
1050 if (ir->last_bit < 28) {
1051 ir->last_bit = (gap - ir_rc5_remote_gap / 2) /
1052 ir_rc5_remote_gap;
1053 ir->code |= 1 << ir->last_bit;
1054 }
1055 /* starting new code */
1056 } else {
1057 ir->active = 1;
1058 ir->code = 0;
1059 ir->base_time = tv;
1060 ir->last_bit = 0;
1061
1062 timeout = current_jiffies + (500 + 30 * HZ) / 1000;
1063 mod_timer(&ir->timer_end, timeout);
1064 }
1065
1066 return 1;
1067}
1068
1069static void nec_task(unsigned long data)
1070{
1071 struct saa7134_dev *dev = (struct saa7134_dev *) data;
1072 struct card_ir *ir;
1073 struct timeval tv;
1074 int count, pulse, oldpulse, gap;
1075 u32 ircode = 0, not_code = 0;
1076 int ngap = 0;
1077
1078 if (!data) {
1079 printk(KERN_ERR "saa713x/ir: Can't recover dev struct\n");
1080 /* GPIO will be kept disabled */
1081 return;
1082 }
1083
1084 ir = dev->remote;
1085
1086 /* rising SAA7134_GPIO_GPRESCAN reads the status */
1087 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
1088 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
1089
1090 oldpulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown;
1091 pulse = oldpulse;
1092
1093 do_gettimeofday(&tv);
1094 ir->base_time = tv;
1095
1096 /* Decode NEC pulsecode. This code can take up to 76.5 ms to run.
1097 Unfortunately, using IRQ to decode pulse didn't work, since it uses
1098 a pulse train of 38KHz. This means one pulse on each 52 us
1099 */
1100 do {
1101 /* Wait until the end of pulse/space or 5 ms */
1102 for (count = 0; count < 500; count++) {
1103 udelay(10);
1104 /* rising SAA7134_GPIO_GPRESCAN reads the status */
1105 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
1106 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
1107 pulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)
1108 & ir->mask_keydown;
1109 if (pulse != oldpulse)
1110 break;
1111 }
1112
1113 do_gettimeofday(&tv);
1114 gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
1115 tv.tv_usec - ir->base_time.tv_usec;
1116
1117 if (!pulse) {
1118 /* Bit 0 has 560 us, while bit 1 has 1120 us.
1119 Do something only if bit == 1
1120 */
1121 if (ngap && (gap > 560 + 280)) {
1122 unsigned int shift = ngap - 1;
1123
1124 /* Address first, then command */
1125 if (shift < 8) {
1126 shift += 8;
1127 ircode |= 1 << shift;
1128 } else if (shift < 16) {
1129 not_code |= 1 << shift;
1130 } else if (shift < 24) {
1131 shift -= 16;
1132 ircode |= 1 << shift;
1133 } else {
1134 shift -= 24;
1135 not_code |= 1 << shift;
1136 }
1137 }
1138 ngap++;
1139 }
1140
1141
1142 ir->base_time = tv;
1143
1144 /* TIMEOUT - Long pulse */
1145 if (gap >= 5000)
1146 break;
1147 oldpulse = pulse;
1148 } while (ngap < 32);
1149
1150 if (ngap == 32) {
1151 /* FIXME: should check if not_code == ~ircode */
1152 ir->code = ir_extract_bits(ircode, ir->mask_keycode);
1153
1154 dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n",
1155 ir->code, ircode, not_code);
1156
1157 ir_keydown(ir->dev, ir->code, 0);
1158 } else {
1159 dprintk("Repeat last key\n");
1160 ir_repeat(ir->dev);
1161 }
1162
1163 saa_setl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P);
1164}
1165
1166static int saa7134_nec_irq(struct saa7134_dev *dev)
1167{
1168 struct card_ir *ir = dev->remote;
1169
1170 saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18_P);
1171 tasklet_schedule(&ir->tlet);
1172
1173 return 1;
1174}
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index a6c726fe4c5d..4e37b8bfb6fa 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -37,7 +37,7 @@
37#include <media/v4l2-ioctl.h> 37#include <media/v4l2-ioctl.h>
38#include <media/v4l2-device.h> 38#include <media/v4l2-device.h>
39#include <media/tuner.h> 39#include <media/tuner.h>
40#include <media/ir-core.h> 40#include <media/ir-common.h>
41#include <media/ir-kbd-i2c.h> 41#include <media/ir-kbd-i2c.h>
42#include <media/videobuf-dma-sg.h> 42#include <media/videobuf-dma-sg.h>
43#include <sound/core.h> 43#include <sound/core.h>