aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx/em28xx-cards.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-04-17 20:48:00 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:09:42 -0400
commitc67ec53f8f4e90ebd482789e2f6d121f41a0bd90 (patch)
tree7c5c242cb50e8b1bfdeab4157370c7dbfda34bf9 /drivers/media/video/em28xx/em28xx-cards.c
parent82ac4f876505615ba9dc6a73cd9a584bad8fe23f (diff)
V4L/DVB (7615): em28xx: Provide the proper support for switching between analog/digital
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 'drivers/media/video/em28xx/em28xx-cards.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c81
1 files changed, 34 insertions, 47 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index ed50b4e55264..13ffde281067 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -436,19 +436,25 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table);
436 436
437/* Board Hauppauge WinTV HVR 900 analog */ 437/* Board Hauppauge WinTV HVR 900 analog */
438struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { 438struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
439 { -1, -1, 6}, 439 {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10},
440 {EM28XX_R08_GPIO, 0x2d, 10}, 440 {0x05, 0xff, 0x10, 10},
441 {EM28XX_R08_GPIO, 0x3d, 5}, 441 { -1, -1, -1, -1},
442 { -1, -1, -1},
443}; 442};
443
444/* Board Hauppauge WinTV HVR 900 digital */ 444/* Board Hauppauge WinTV HVR 900 digital */
445struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { 445struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
446 { -1, -1, 6}, 446 {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
447 {EM28XX_R08_GPIO, 0x2e, 6}, 447 {EM2880_R04_GPO, 0x04, 0x0f, 10},
448 {EM28XX_R08_GPIO, 0x3e, 6}, 448 {EM2880_R04_GPO, 0x0c, 0x0f, 10},
449 {EM2880_R04_GPO, 0x04, 10}, 449 { -1, -1, -1, -1},
450 {EM2880_R04_GPO, 0x0c, 10}, 450};
451 { -1, -1, -1}, 451
452/* Board Hauppauge WinTV HVR 900 tuner_callback */
453struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = {
454 {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
455 {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10},
456 {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
457 { -1, -1, -1, -1},
452}; 458};
453 459
454/* 460/*
@@ -469,7 +475,6 @@ int em28xx_tuner_callback(void *ptr, int command, int arg)
469{ 475{
470 int rc = 0; 476 int rc = 0;
471 struct em28xx *dev = ptr; 477 struct em28xx *dev = ptr;
472 struct em28xx_reg_seq *gpio;
473 478
474 if (dev->tuner_type != TUNER_XC2028) 479 if (dev->tuner_type != TUNER_XC2028)
475 return 0; 480 return 0;
@@ -478,32 +483,10 @@ int em28xx_tuner_callback(void *ptr, int command, int arg)
478 return 0; 483 return 0;
479 484
480 if (dev->mode == EM28XX_ANALOG_MODE) 485 if (dev->mode == EM28XX_ANALOG_MODE)
481 gpio = dev->analog_gpio; 486 rc = em28xx_gpio_set(dev, dev->tun_analog_gpio);
482 else 487 else
483 gpio = dev->digital_gpio; 488 rc = em28xx_gpio_set(dev, dev->tun_digital_gpio);
484 489
485 /* djh - Not sure if these are still required */
486 dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1);
487 if (dev->mode == EM28XX_ANALOG_MODE)
488 dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1);
489 else
490 dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1);
491 msleep(6);
492
493 if (!gpio)
494 return rc;
495
496 /* Send GPIO reset sequences specified at board entry */
497 while (gpio->sleep >= 0) {
498 if (gpio->reg >= 0)
499 rc = dev->em28xx_write_regs(dev,
500 gpio->reg,
501 &gpio->val, 1);
502 if (gpio->sleep > 0)
503 msleep(gpio->sleep);
504
505 gpio++;
506 }
507 return rc; 490 return rc;
508} 491}
509EXPORT_SYMBOL_GPL(em28xx_tuner_callback); 492EXPORT_SYMBOL_GPL(em28xx_tuner_callback);
@@ -527,6 +510,10 @@ void em28xx_pre_card_setup(struct em28xx *dev)
527{ 510{
528 int rc; 511 int rc;
529 512
513 rc = em28xx_read_reg(dev, EM2880_R04_GPO);
514 if (rc >= 0)
515 dev->reg_gpo = rc;
516
530 dev->wait_after_write = 5; 517 dev->wait_after_write = 5;
531 rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); 518 rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
532 if (rc > 0) { 519 if (rc > 0) {
@@ -547,24 +534,24 @@ void em28xx_pre_card_setup(struct em28xx *dev)
547 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 534 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
548 case EM2880_BOARD_TERRATEC_HYBRID_XS: 535 case EM2880_BOARD_TERRATEC_HYBRID_XS:
549 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: 536 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
550 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); 537 em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
551 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); 538 em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
552 em28xx_write_regs(dev, 0x08, "\xff", 1);
553 em28xx_write_regs(dev, 0x04, "\x00", 1);
554 msleep(100);
555 em28xx_write_regs(dev, 0x04, "\x08", 1);
556 msleep(100);
557 em28xx_write_regs(dev, 0x08, "\xff", 1);
558 msleep(50);
559 em28xx_write_regs(dev, 0x08, "\x2d", 1);
560 msleep(50); 539 msleep(50);
561 em28xx_write_regs(dev, 0x08, "\x3d", 1);
562 540
563 dev->analog_gpio = hauppauge_wintv_hvr_900_analog; 541 /* Sets GPO/GPIO sequences for this device */
564 dev->digital_gpio = hauppauge_wintv_hvr_900_digital; 542 dev->analog_gpio = hauppauge_wintv_hvr_900_analog;
543 dev->digital_gpio = hauppauge_wintv_hvr_900_digital;
544 dev->tun_analog_gpio = hauppauge_wintv_hvr_900_tuner_callback;
545 dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback;
565 546
566 break; 547 break;
567 } 548 }
549
550 em28xx_gpio_set(dev, dev->tun_analog_gpio);
551 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
552
553 /* Unlock device */
554 em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);
568} 555}
569 556
570void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) 557void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)