diff options
author | Antti Palosaari <crope@iki.fi> | 2012-09-11 21:27:09 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-09-23 18:41:55 -0400 |
commit | 5be65721a7f6cdf93e34b2b7497bda4c07c469ed (patch) | |
tree | adb74ef04fa00ae33bf408d91280ee7cdebd7303 /drivers/media | |
parent | 89054e37a8bb48c1633149122a538eb50f3c0d34 (diff) |
[media] rtl28xxu: add support for tua9001 tuner based devices
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 95 |
1 files changed, 92 insertions, 3 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index a62238f5aa2c..31c9f440a4e2 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "fc0013.h" | 32 | #include "fc0013.h" |
33 | #include "e4000.h" | 33 | #include "e4000.h" |
34 | #include "fc2580.h" | 34 | #include "fc2580.h" |
35 | #include "tua9001.h" | ||
35 | 36 | ||
36 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 37 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
37 | 38 | ||
@@ -399,6 +400,12 @@ static struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = { | |||
399 | .tuner = TUNER_RTL2832_FC0013 | 400 | .tuner = TUNER_RTL2832_FC0013 |
400 | }; | 401 | }; |
401 | 402 | ||
403 | static struct rtl2832_config rtl28xxu_rtl2832_tua9001_config = { | ||
404 | .i2c_addr = 0x10, /* 0x20 */ | ||
405 | .xtal = 28800000, | ||
406 | .tuner = TUNER_RTL2832_TUA9001, | ||
407 | }; | ||
408 | |||
402 | static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d, | 409 | static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d, |
403 | int cmd, int arg) | 410 | int cmd, int arg) |
404 | { | 411 | { |
@@ -443,6 +450,54 @@ static int rtl2832u_fc0013_tuner_callback(struct dvb_usb_device *d, | |||
443 | return 0; | 450 | return 0; |
444 | } | 451 | } |
445 | 452 | ||
453 | static int rtl2832u_tua9001_tuner_callback(struct dvb_usb_device *d, | ||
454 | int cmd, int arg) | ||
455 | { | ||
456 | int ret; | ||
457 | u8 val; | ||
458 | |||
459 | dev_dbg(&d->udev->dev, "%s: cmd=%d arg=%d\n", __func__, cmd, arg); | ||
460 | |||
461 | /* | ||
462 | * CEN always enabled by hardware wiring | ||
463 | * RESETN GPIO4 | ||
464 | * RXEN GPIO1 | ||
465 | */ | ||
466 | |||
467 | ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val); | ||
468 | if (ret < 0) | ||
469 | goto err; | ||
470 | |||
471 | switch (cmd) { | ||
472 | case TUA9001_CMD_RESETN: | ||
473 | if (arg) | ||
474 | val |= (1 << 4); | ||
475 | else | ||
476 | val &= ~(1 << 4); | ||
477 | |||
478 | ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val); | ||
479 | if (ret < 0) | ||
480 | goto err; | ||
481 | break; | ||
482 | case TUA9001_CMD_RXEN: | ||
483 | if (arg) | ||
484 | val |= (1 << 1); | ||
485 | else | ||
486 | val &= ~(1 << 1); | ||
487 | |||
488 | ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val); | ||
489 | if (ret < 0) | ||
490 | goto err; | ||
491 | break; | ||
492 | } | ||
493 | |||
494 | return 0; | ||
495 | |||
496 | err: | ||
497 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | ||
498 | return ret; | ||
499 | } | ||
500 | |||
446 | static int rtl2832u_tuner_callback(struct dvb_usb_device *d, int cmd, int arg) | 501 | static int rtl2832u_tuner_callback(struct dvb_usb_device *d, int cmd, int arg) |
447 | { | 502 | { |
448 | struct rtl28xxu_priv *priv = d->priv; | 503 | struct rtl28xxu_priv *priv = d->priv; |
@@ -453,6 +508,9 @@ static int rtl2832u_tuner_callback(struct dvb_usb_device *d, int cmd, int arg) | |||
453 | 508 | ||
454 | case TUNER_RTL2832_FC0013: | 509 | case TUNER_RTL2832_FC0013: |
455 | return rtl2832u_fc0013_tuner_callback(d, cmd, arg); | 510 | return rtl2832u_fc0013_tuner_callback(d, cmd, arg); |
511 | |||
512 | case TUNER_RTL2832_TUA9001: | ||
513 | return rtl2832u_tua9001_tuner_callback(d, cmd, arg); | ||
456 | default: | 514 | default: |
457 | break; | 515 | break; |
458 | } | 516 | } |
@@ -608,10 +666,10 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) | |||
608 | ret = rtl28xxu_ctrl_msg(d, &req_tua9001); | 666 | ret = rtl28xxu_ctrl_msg(d, &req_tua9001); |
609 | if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) { | 667 | if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) { |
610 | priv->tuner = TUNER_RTL2832_TUA9001; | 668 | priv->tuner = TUNER_RTL2832_TUA9001; |
611 | /* TODO implement tuner */ | 669 | rtl2832_config = &rtl28xxu_rtl2832_tua9001_config; |
612 | dev_info(&d->udev->dev, "%s: TUA9001 tuner found", | 670 | dev_info(&d->udev->dev, "%s: TUA9001 tuner found", |
613 | KBUILD_MODNAME); | 671 | KBUILD_MODNAME); |
614 | goto unsupported; | 672 | goto found; |
615 | } | 673 | } |
616 | 674 | ||
617 | /* check MXL5007R ID register; reg=d9 val=14 */ | 675 | /* check MXL5007R ID register; reg=d9 val=14 */ |
@@ -760,12 +818,17 @@ static const struct fc2580_config rtl2832u_fc2580_config = { | |||
760 | .clock = 16384000, | 818 | .clock = 16384000, |
761 | }; | 819 | }; |
762 | 820 | ||
821 | static struct tua9001_config rtl2832u_tua9001_config = { | ||
822 | .i2c_addr = 0x60, | ||
823 | }; | ||
824 | |||
763 | static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) | 825 | static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) |
764 | { | 826 | { |
765 | int ret; | 827 | int ret; |
766 | struct dvb_usb_device *d = adap_to_d(adap); | 828 | struct dvb_usb_device *d = adap_to_d(adap); |
767 | struct rtl28xxu_priv *priv = d_to_priv(d); | 829 | struct rtl28xxu_priv *priv = d_to_priv(d); |
768 | struct dvb_frontend *fe; | 830 | struct dvb_frontend *fe; |
831 | u8 val; | ||
769 | 832 | ||
770 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | 833 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
771 | 834 | ||
@@ -796,6 +859,33 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) | |||
796 | fe = dvb_attach(fc2580_attach, adap->fe[0], &d->i2c_adap, | 859 | fe = dvb_attach(fc2580_attach, adap->fe[0], &d->i2c_adap, |
797 | &rtl2832u_fc2580_config); | 860 | &rtl2832u_fc2580_config); |
798 | break; | 861 | break; |
862 | case TUNER_RTL2832_TUA9001: | ||
863 | /* enable GPIO1 and GPIO4 as output */ | ||
864 | ret = rtl28xx_rd_reg(d, SYS_GPIO_DIR, &val); | ||
865 | if (ret < 0) | ||
866 | goto err; | ||
867 | |||
868 | val &= ~(1 << 1); | ||
869 | val &= ~(1 << 4); | ||
870 | |||
871 | ret = rtl28xx_wr_reg(d, SYS_GPIO_DIR, val); | ||
872 | if (ret < 0) | ||
873 | goto err; | ||
874 | |||
875 | ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_EN, &val); | ||
876 | if (ret < 0) | ||
877 | goto err; | ||
878 | |||
879 | val |= (1 << 1); | ||
880 | val |= (1 << 4); | ||
881 | |||
882 | ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, val); | ||
883 | if (ret < 0) | ||
884 | goto err; | ||
885 | |||
886 | fe = dvb_attach(tua9001_attach, adap->fe[0], &d->i2c_adap, | ||
887 | &rtl2832u_tua9001_config); | ||
888 | break; | ||
799 | default: | 889 | default: |
800 | fe = NULL; | 890 | fe = NULL; |
801 | dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME, | 891 | dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME, |
@@ -978,7 +1068,6 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff) | |||
978 | if (ret) | 1068 | if (ret) |
979 | goto err; | 1069 | goto err; |
980 | 1070 | ||
981 | |||
982 | /* streaming EP: clear stall & reset */ | 1071 | /* streaming EP: clear stall & reset */ |
983 | ret = rtl28xx_wr_regs(d, USB_EPA_CTL, "\x00\x00", 2); | 1072 | ret = rtl28xx_wr_regs(d, USB_EPA_CTL, "\x00\x00", 2); |
984 | if (ret) | 1073 | if (ret) |