diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 226 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134.h | 2 |
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 */ |
58 | static int saa7134_rc5_irq(struct saa7134_dev *dev); | ||
59 | static int saa7134_nec_irq(struct saa7134_dev *dev); | ||
58 | static int saa7134_raw_decode_irq(struct saa7134_dev *dev); | 60 | static int saa7134_raw_decode_irq(struct saa7134_dev *dev); |
61 | static 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 | |||
535 | static 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 | |||
512 | int saa7134_input_init1(struct saa7134_dev *dev) | 568 | int 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 | |||
1027 | static 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 | |||
1069 | static 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 | |||
1166 | static 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> |