diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-17 18:48:00 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-17 18:48:00 -0300 |
commit | 5253757b29d1cd54ddd9d2f874794c907430acc8 (patch) | |
tree | ddfdf79aec8343055eb239e07b3e4a23e03f8437 /linux/drivers/media/video/em28xx/em28xx-cards.c | |
parent | acc7837ba9c6b89823348b699aae4e995cdb45fc (diff) | |
download | mediapointer-dvb-s2-5253757b29d1cd54ddd9d2f874794c907430acc8.tar.gz mediapointer-dvb-s2-5253757b29d1cd54ddd9d2f874794c907430acc8.tar.bz2 |
em28xx: Provide the proper support for switching between analog/digital
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Before this patch, HVR900/HVR950 were incorreclty going back to analog. The
result is that only digital were working.
This patch provides the proper setup for analog/digital and tuner callback.
It also properly resets analog into a sane state at open().
Thanks to Steven Toth <stoth@linuxtv.org> and Michael Krufky <mkrufky@linuxtv.org>
for helping to set the proper parameters to GPO/GPIO em2883 ports.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/video/em28xx/em28xx-cards.c')
-rw-r--r-- | linux/drivers/media/video/em28xx/em28xx-cards.c | 90 |
1 files changed, 34 insertions, 56 deletions
diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index ceb7bc034..e0d898916 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -437,19 +437,25 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table); /* Board Hauppauge WinTV HVR 900 analog */ struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { - { -1, -1, 6}, - {EM28XX_R08_GPIO, 0x2d, 10}, - {EM28XX_R08_GPIO, 0x3d, 5}, - { -1, -1, -1}, + {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10}, + {0x05, 0xff, 0x10, 10}, + { -1, -1, -1, -1}, }; + /* Board Hauppauge WinTV HVR 900 digital */ struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { - { -1, -1, 6}, - {EM28XX_R08_GPIO, 0x2e, 6}, - {EM28XX_R08_GPIO, 0x3e, 6}, - {EM2880_R04_GPO, 0x04, 10}, - {EM2880_R04_GPO, 0x0c, 10}, - { -1, -1, -1}, + {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10}, + {EM2880_R04_GPO, 0x04, 0x0f, 10}, + {EM2880_R04_GPO, 0x0c, 0x0f, 10}, + { -1, -1, -1, -1}, +}; + +/* Board Hauppauge WinTV HVR 900 tuner_callback */ +struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = { + {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, + {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10}, + {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, + { -1, -1, -1, -1}, }; /* @@ -470,7 +476,6 @@ int em28xx_tuner_callback(void *ptr, int command, int arg) { int rc = 0; struct em28xx *dev = ptr; - struct em28xx_reg_seq *gpio; if (dev->tuner_type != TUNER_XC2028) return 0; @@ -479,34 +484,10 @@ int em28xx_tuner_callback(void *ptr, int command, int arg) return 0; if (dev->mode == EM28XX_ANALOG_MODE) - gpio = dev->analog_gpio; - else - gpio = dev->digital_gpio; - -#if 1 - /* djh - Not sure if these are still required */ - dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); - if (dev->mode == EM28XX_ANALOG_MODE) - dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1); + rc = em28xx_gpio_set(dev, dev->tun_analog_gpio); else - dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1); - msleep(6); -#endif - - if (!gpio) - return rc; + rc = em28xx_gpio_set(dev, dev->tun_digital_gpio); - /* Send GPIO reset sequences specified at board entry */ - while (gpio->sleep >= 0) { - if (gpio->reg >= 0) - rc = dev->em28xx_write_regs(dev, - gpio->reg, - &gpio->val, 1); - if (gpio->sleep > 0) - msleep(gpio->sleep); - - gpio++; - } return rc; } EXPORT_SYMBOL_GPL(em28xx_tuner_callback); @@ -530,6 +511,10 @@ void em28xx_pre_card_setup(struct em28xx *dev) { int rc; + rc = em28xx_read_reg(dev, EM2880_R04_GPO); + if (rc >= 0) + dev->reg_gpo = rc; + dev->wait_after_write = 5; rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); if (rc > 0) { @@ -550,31 +535,24 @@ void em28xx_pre_card_setup(struct em28xx *dev) case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2880_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: - em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); - em28xx_write_regs(dev, 0x08, "\xff", 1); - em28xx_write_regs(dev, 0x04, "\x00", 1); - msleep(100); - em28xx_write_regs(dev, 0x04, "\x08", 1); - msleep(100); - em28xx_write_regs(dev, 0x08, "\xff", 1); - msleep(50); - em28xx_write_regs(dev, 0x08, "\x2d", 1); msleep(50); - em28xx_write_regs(dev, 0x08, "\x3d", 1); - dev->analog_gpio = hauppauge_wintv_hvr_900_analog; - dev->digital_gpio = hauppauge_wintv_hvr_900_digital; + /* Sets GPO/GPIO sequences for this device */ + dev->analog_gpio = hauppauge_wintv_hvr_900_analog; + dev->digital_gpio = hauppauge_wintv_hvr_900_digital; + dev->tun_analog_gpio = hauppauge_wintv_hvr_900_tuner_callback; + dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback; break; } -#if 0 - /* Put xc2028 tuners and demods into a sane state */ - if (dev->tuner_type == TUNER_XC2028) { - dev->mode = EM28XX_ANALOG_MODE; - em28xx_tuner_callback(dev, XC2028_TUNER_RESET, 0); - }; -#endif + + em28xx_gpio_set(dev, dev->tun_analog_gpio); + em28xx_set_mode(dev, EM28XX_ANALOG_MODE); + + /* Unlock device */ + em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); } void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) |