aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-11-13 14:49:10 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:16:45 -0500
commit8ea43d0a2f87b8460f46ddb7b42b5eb17c5385d2 (patch)
treee7498d5734d2b0d8b55013dd9225a1d8aceb2e7c /drivers
parent6c7e653ff668d939174aa7023736f4a40fd2be08 (diff)
[media] rc: Remove ir-common module
Now, just one old bttv board uses the old RC5 raw decoding routines. Its conversion to rc-core requires the generation of IRQ data for both positive and negative transitions at the IRQ line. I'm not sure if bttv driver supports it or if the transitions will be reliable enough. So, due to the lack of hardware for testing, the better for now is to just move the legacy routines to bttv driver, and wait for someone with a Nebula Digi could help to port it to use also rc-core raw decoders. Acked-by: Hermann Pitton <hermann-pitton@arcor.de> Acked-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
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>