diff options
Diffstat (limited to 'drivers/media/video/saa7134/saa7134-input.c')
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 210 |
1 files changed, 204 insertions, 6 deletions
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index ad08d13dffdd..c53fd5f9f6b5 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -62,8 +62,11 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of " | |||
62 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ | 62 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ |
63 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) | 63 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) |
64 | 64 | ||
65 | /** rc5 functions */ | 65 | /* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */ |
66 | static int saa7134_rc5_irq(struct saa7134_dev *dev); | 66 | static int saa7134_rc5_irq(struct saa7134_dev *dev); |
67 | static int saa7134_nec_irq(struct saa7134_dev *dev); | ||
68 | static void nec_task(unsigned long data); | ||
69 | static void saa7134_nec_timer(unsigned long data); | ||
67 | 70 | ||
68 | /* -------------------- GPIO generic keycode builder -------------------- */ | 71 | /* -------------------- GPIO generic keycode builder -------------------- */ |
69 | 72 | ||
@@ -115,6 +118,53 @@ static int build_key(struct saa7134_dev *dev) | |||
115 | 118 | ||
116 | /* --------------------- Chip specific I2C key builders ----------------- */ | 119 | /* --------------------- Chip specific I2C key builders ----------------- */ |
117 | 120 | ||
121 | static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, | ||
122 | u32 *ir_raw) | ||
123 | { | ||
124 | unsigned char b; | ||
125 | int gpio; | ||
126 | |||
127 | /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ | ||
128 | struct saa7134_dev *dev = ir->c.adapter->algo_data; | ||
129 | if (dev == NULL) { | ||
130 | dprintk("get_key_msi_tvanywhere_plus: " | ||
131 | "gir->c.adapter->algo_data is NULL!\n"); | ||
132 | return -EIO; | ||
133 | } | ||
134 | |||
135 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ | ||
136 | |||
137 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
138 | saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
139 | |||
140 | gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); | ||
141 | |||
142 | /* GPIO&0x40 is pulsed low when a button is pressed. Don't do | ||
143 | I2C receive if gpio&0x40 is not low. */ | ||
144 | |||
145 | if (gpio & 0x40) | ||
146 | return 0; /* No button press */ | ||
147 | |||
148 | /* GPIO says there is a button press. Get it. */ | ||
149 | |||
150 | if (1 != i2c_master_recv(&ir->c, &b, 1)) { | ||
151 | i2cdprintk("read error\n"); | ||
152 | return -EIO; | ||
153 | } | ||
154 | |||
155 | /* No button press */ | ||
156 | |||
157 | if (b == 0xff) | ||
158 | return 0; | ||
159 | |||
160 | /* Button pressed */ | ||
161 | |||
162 | dprintk("get_key_msi_tvanywhere_plus: Key = 0x%02X\n", b); | ||
163 | *ir_key = b; | ||
164 | *ir_raw = b; | ||
165 | return 1; | ||
166 | } | ||
167 | |||
118 | static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 168 | static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
119 | { | 169 | { |
120 | unsigned char b; | 170 | unsigned char b; |
@@ -280,7 +330,9 @@ void saa7134_input_irq(struct saa7134_dev *dev) | |||
280 | { | 330 | { |
281 | struct card_ir *ir = dev->remote; | 331 | struct card_ir *ir = dev->remote; |
282 | 332 | ||
283 | if (!ir->polling && !ir->rc5_gpio) { | 333 | if (ir->nec_gpio) { |
334 | saa7134_nec_irq(dev); | ||
335 | } else if (!ir->polling && !ir->rc5_gpio) { | ||
284 | build_key(dev); | 336 | build_key(dev); |
285 | } else if (ir->rc5_gpio) { | 337 | } else if (ir->rc5_gpio) { |
286 | saa7134_rc5_irq(dev); | 338 | saa7134_rc5_irq(dev); |
@@ -316,6 +368,10 @@ void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) | |||
316 | ir->addr = 0x17; | 368 | ir->addr = 0x17; |
317 | ir->rc5_key_timeout = ir_rc5_key_timeout; | 369 | ir->rc5_key_timeout = ir_rc5_key_timeout; |
318 | ir->rc5_remote_gap = ir_rc5_remote_gap; | 370 | ir->rc5_remote_gap = ir_rc5_remote_gap; |
371 | } else if (ir->nec_gpio) { | ||
372 | setup_timer(&ir->timer_keyup, saa7134_nec_timer, | ||
373 | (unsigned long)dev); | ||
374 | tasklet_init(&ir->tlet, nec_task, (unsigned long)dev); | ||
319 | } | 375 | } |
320 | } | 376 | } |
321 | 377 | ||
@@ -335,6 +391,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
335 | u32 mask_keyup = 0; | 391 | u32 mask_keyup = 0; |
336 | int polling = 0; | 392 | int polling = 0; |
337 | int rc5_gpio = 0; | 393 | int rc5_gpio = 0; |
394 | int nec_gpio = 0; | ||
338 | int ir_type = IR_TYPE_OTHER; | 395 | int ir_type = IR_TYPE_OTHER; |
339 | int err; | 396 | int err; |
340 | 397 | ||
@@ -391,6 +448,12 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
391 | saa_setb(SAA7134_GPIO_GPMODE0, 0x4); | 448 | saa_setb(SAA7134_GPIO_GPMODE0, 0x4); |
392 | saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); | 449 | saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); |
393 | break; | 450 | break; |
451 | case SAA7134_BOARD_AVERMEDIA_M135A: | ||
452 | ir_codes = ir_codes_avermedia_m135a; | ||
453 | mask_keydown = 0x0040000; | ||
454 | mask_keycode = 0x00013f; | ||
455 | nec_gpio = 1; | ||
456 | break; | ||
394 | case SAA7134_BOARD_AVERMEDIA_777: | 457 | case SAA7134_BOARD_AVERMEDIA_777: |
395 | case SAA7134_BOARD_AVERMEDIA_A16AR: | 458 | case SAA7134_BOARD_AVERMEDIA_A16AR: |
396 | ir_codes = ir_codes_avermedia; | 459 | ir_codes = ir_codes_avermedia; |
@@ -499,6 +562,12 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
499 | mask_keyup = 0x040000; | 562 | mask_keyup = 0x040000; |
500 | polling = 50; // ms | 563 | polling = 50; // ms |
501 | break; | 564 | break; |
565 | case SAA7134_BOARD_ENCORE_ENLTV_FM53: | ||
566 | ir_codes = ir_codes_encore_enltv_fm53; | ||
567 | mask_keydown = 0x0040000; | ||
568 | mask_keycode = 0x00007f; | ||
569 | nec_gpio = 1; | ||
570 | break; | ||
502 | case SAA7134_BOARD_10MOONSTVMASTER3: | 571 | case SAA7134_BOARD_10MOONSTVMASTER3: |
503 | ir_codes = ir_codes_encore_enltv; | 572 | ir_codes = ir_codes_encore_enltv; |
504 | mask_keycode = 0x5f80000; | 573 | mask_keycode = 0x5f80000; |
@@ -511,6 +580,12 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
511 | mask_keydown = 0xf00000; | 580 | mask_keydown = 0xf00000; |
512 | polling = 50; /* ms */ | 581 | polling = 50; /* ms */ |
513 | break; | 582 | break; |
583 | case SAA7134_BOARD_REAL_ANGEL_220: | ||
584 | ir_codes = ir_codes_real_audio_220_32_keys; | ||
585 | mask_keycode = 0x3f00; | ||
586 | mask_keyup = 0x4000; | ||
587 | polling = 50; /* ms */ | ||
588 | break; | ||
514 | } | 589 | } |
515 | if (NULL == ir_codes) { | 590 | if (NULL == ir_codes) { |
516 | printk("%s: Oops: IR config error [card=%d]\n", | 591 | printk("%s: Oops: IR config error [card=%d]\n", |
@@ -533,6 +608,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
533 | ir->mask_keyup = mask_keyup; | 608 | ir->mask_keyup = mask_keyup; |
534 | ir->polling = polling; | 609 | ir->polling = polling; |
535 | ir->rc5_gpio = rc5_gpio; | 610 | ir->rc5_gpio = rc5_gpio; |
611 | ir->nec_gpio = nec_gpio; | ||
536 | 612 | ||
537 | /* init input device */ | 613 | /* init input device */ |
538 | snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", | 614 | snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", |
@@ -612,6 +688,11 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) | |||
612 | ir->get_key = get_key_purpletv; | 688 | ir->get_key = get_key_purpletv; |
613 | ir->ir_codes = ir_codes_purpletv; | 689 | ir->ir_codes = ir_codes_purpletv; |
614 | break; | 690 | break; |
691 | case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: | ||
692 | snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus"); | ||
693 | ir->get_key = get_key_msi_tvanywhere_plus; | ||
694 | ir->ir_codes = ir_codes_msi_tvanywhere_plus; | ||
695 | break; | ||
615 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: | 696 | case SAA7134_BOARD_HAUPPAUGE_HVR1110: |
616 | snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110"); | 697 | snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110"); |
617 | ir->get_key = get_key_hvr1110; | 698 | ir->get_key = get_key_hvr1110; |
@@ -675,8 +756,125 @@ static int saa7134_rc5_irq(struct saa7134_dev *dev) | |||
675 | return 1; | 756 | return 1; |
676 | } | 757 | } |
677 | 758 | ||
678 | /* ---------------------------------------------------------------------- | 759 | |
679 | * Local variables: | 760 | /* On NEC protocol, One has 2.25 ms, and zero has 1.125 ms |
680 | * c-basic-offset: 8 | 761 | The first pulse (start) has 9 + 4.5 ms |
681 | * End: | ||
682 | */ | 762 | */ |
763 | |||
764 | static void saa7134_nec_timer(unsigned long data) | ||
765 | { | ||
766 | struct saa7134_dev *dev = (struct saa7134_dev *) data; | ||
767 | struct card_ir *ir = dev->remote; | ||
768 | |||
769 | dprintk("Cancel key repeat\n"); | ||
770 | |||
771 | ir_input_nokey(ir->dev, &ir->ir); | ||
772 | } | ||
773 | |||
774 | static void nec_task(unsigned long data) | ||
775 | { | ||
776 | struct saa7134_dev *dev = (struct saa7134_dev *) data; | ||
777 | struct card_ir *ir; | ||
778 | struct timeval tv; | ||
779 | int count, pulse, oldpulse, gap; | ||
780 | u32 ircode = 0, not_code = 0; | ||
781 | int ngap = 0; | ||
782 | |||
783 | if (!data) { | ||
784 | printk(KERN_ERR "saa713x/ir: Can't recover dev struct\n"); | ||
785 | /* GPIO will be kept disabled */ | ||
786 | return; | ||
787 | } | ||
788 | |||
789 | ir = dev->remote; | ||
790 | |||
791 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ | ||
792 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
793 | saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
794 | |||
795 | oldpulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown; | ||
796 | pulse = oldpulse; | ||
797 | |||
798 | do_gettimeofday(&tv); | ||
799 | ir->base_time = tv; | ||
800 | |||
801 | /* Decode NEC pulsecode. This code can take up to 76.5 ms to run. | ||
802 | Unfortunately, using IRQ to decode pulse didn't work, since it uses | ||
803 | a pulse train of 38KHz. This means one pulse on each 52 us | ||
804 | */ | ||
805 | do { | ||
806 | /* Wait until the end of pulse/space or 5 ms */ | ||
807 | for (count = 0; count < 500; count++) { | ||
808 | udelay(10); | ||
809 | /* rising SAA7134_GPIO_GPRESCAN reads the status */ | ||
810 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
811 | saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
812 | pulse = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) | ||
813 | & ir->mask_keydown; | ||
814 | if (pulse != oldpulse) | ||
815 | break; | ||
816 | } | ||
817 | |||
818 | do_gettimeofday(&tv); | ||
819 | gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + | ||
820 | tv.tv_usec - ir->base_time.tv_usec; | ||
821 | |||
822 | if (!pulse) { | ||
823 | /* Bit 0 has 560 us, while bit 1 has 1120 us. | ||
824 | Do something only if bit == 1 | ||
825 | */ | ||
826 | if (ngap && (gap > 560 + 280)) { | ||
827 | unsigned int shift = ngap - 1; | ||
828 | |||
829 | /* Address first, then command */ | ||
830 | if (shift < 8) { | ||
831 | shift += 8; | ||
832 | ircode |= 1 << shift; | ||
833 | } else if (shift < 16) { | ||
834 | not_code |= 1 << shift; | ||
835 | } else if (shift < 24) { | ||
836 | shift -= 16; | ||
837 | ircode |= 1 << shift; | ||
838 | } else { | ||
839 | shift -= 24; | ||
840 | not_code |= 1 << shift; | ||
841 | } | ||
842 | } | ||
843 | ngap++; | ||
844 | } | ||
845 | |||
846 | |||
847 | ir->base_time = tv; | ||
848 | |||
849 | /* TIMEOUT - Long pulse */ | ||
850 | if (gap >= 5000) | ||
851 | break; | ||
852 | oldpulse = pulse; | ||
853 | } while (ngap < 32); | ||
854 | |||
855 | if (ngap == 32) { | ||
856 | /* FIXME: should check if not_code == ~ircode */ | ||
857 | ir->code = ir_extract_bits(ircode, ir->mask_keycode); | ||
858 | |||
859 | dprintk("scancode = 0x%02x (code = 0x%02x, notcode= 0x%02x)\n", | ||
860 | ir->code, ircode, not_code); | ||
861 | |||
862 | ir_input_keydown(ir->dev, &ir->ir, ir->code, ir->code); | ||
863 | } else | ||
864 | dprintk("Repeat last key\n"); | ||
865 | |||
866 | /* Keep repeating the last key */ | ||
867 | mod_timer(&ir->timer_keyup, jiffies + msecs_to_jiffies(150)); | ||
868 | |||
869 | saa_setl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); | ||
870 | } | ||
871 | |||
872 | static int saa7134_nec_irq(struct saa7134_dev *dev) | ||
873 | { | ||
874 | struct card_ir *ir = dev->remote; | ||
875 | |||
876 | saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); | ||
877 | tasklet_schedule(&ir->tlet); | ||
878 | |||
879 | return 1; | ||
880 | } | ||