aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c135
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.h4
2 files changed, 108 insertions, 31 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 5ea52c7616f1..d9ee1a9c5cbe 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -24,6 +24,7 @@
24 24
25#include "rtl2830.h" 25#include "rtl2830.h"
26#include "rtl2832.h" 26#include "rtl2832.h"
27#include "mn88472.h"
27 28
28#include "qt1010.h" 29#include "qt1010.h"
29#include "mt2060.h" 30#include "mt2060.h"
@@ -420,6 +421,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
420 struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; 421 struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
421 struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf}; 422 struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf};
422 struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf}; 423 struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf};
424 struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf};
423 425
424 dev_dbg(&d->udev->dev, "%s:\n", __func__); 426 dev_dbg(&d->udev->dev, "%s:\n", __func__);
425 427
@@ -449,7 +451,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
449 if (ret == 0 && buf[0] == 0xa1) { 451 if (ret == 0 && buf[0] == 0xa1) {
450 priv->tuner = TUNER_RTL2832_FC0012; 452 priv->tuner = TUNER_RTL2832_FC0012;
451 priv->tuner_name = "FC0012"; 453 priv->tuner_name = "FC0012";
452 goto found; 454 goto tuner_found;
453 } 455 }
454 456
455 /* check FC0013 ID register; reg=00 val=a3 */ 457 /* check FC0013 ID register; reg=00 val=a3 */
@@ -457,7 +459,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
457 if (ret == 0 && buf[0] == 0xa3) { 459 if (ret == 0 && buf[0] == 0xa3) {
458 priv->tuner = TUNER_RTL2832_FC0013; 460 priv->tuner = TUNER_RTL2832_FC0013;
459 priv->tuner_name = "FC0013"; 461 priv->tuner_name = "FC0013";
460 goto found; 462 goto tuner_found;
461 } 463 }
462 464
463 /* check MT2266 ID register; reg=00 val=85 */ 465 /* check MT2266 ID register; reg=00 val=85 */
@@ -465,7 +467,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
465 if (ret == 0 && buf[0] == 0x85) { 467 if (ret == 0 && buf[0] == 0x85) {
466 priv->tuner = TUNER_RTL2832_MT2266; 468 priv->tuner = TUNER_RTL2832_MT2266;
467 priv->tuner_name = "MT2266"; 469 priv->tuner_name = "MT2266";
468 goto found; 470 goto tuner_found;
469 } 471 }
470 472
471 /* check FC2580 ID register; reg=01 val=56 */ 473 /* check FC2580 ID register; reg=01 val=56 */
@@ -473,7 +475,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
473 if (ret == 0 && buf[0] == 0x56) { 475 if (ret == 0 && buf[0] == 0x56) {
474 priv->tuner = TUNER_RTL2832_FC2580; 476 priv->tuner = TUNER_RTL2832_FC2580;
475 priv->tuner_name = "FC2580"; 477 priv->tuner_name = "FC2580";
476 goto found; 478 goto tuner_found;
477 } 479 }
478 480
479 /* check MT2063 ID register; reg=00 val=9e || 9c */ 481 /* check MT2063 ID register; reg=00 val=9e || 9c */
@@ -481,7 +483,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
481 if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) { 483 if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) {
482 priv->tuner = TUNER_RTL2832_MT2063; 484 priv->tuner = TUNER_RTL2832_MT2063;
483 priv->tuner_name = "MT2063"; 485 priv->tuner_name = "MT2063";
484 goto found; 486 goto tuner_found;
485 } 487 }
486 488
487 /* check MAX3543 ID register; reg=00 val=38 */ 489 /* check MAX3543 ID register; reg=00 val=38 */
@@ -489,7 +491,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
489 if (ret == 0 && buf[0] == 0x38) { 491 if (ret == 0 && buf[0] == 0x38) {
490 priv->tuner = TUNER_RTL2832_MAX3543; 492 priv->tuner = TUNER_RTL2832_MAX3543;
491 priv->tuner_name = "MAX3543"; 493 priv->tuner_name = "MAX3543";
492 goto found; 494 goto tuner_found;
493 } 495 }
494 496
495 /* check TUA9001 ID register; reg=7e val=2328 */ 497 /* check TUA9001 ID register; reg=7e val=2328 */
@@ -497,7 +499,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
497 if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) { 499 if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) {
498 priv->tuner = TUNER_RTL2832_TUA9001; 500 priv->tuner = TUNER_RTL2832_TUA9001;
499 priv->tuner_name = "TUA9001"; 501 priv->tuner_name = "TUA9001";
500 goto found; 502 goto tuner_found;
501 } 503 }
502 504
503 /* check MXL5007R ID register; reg=d9 val=14 */ 505 /* check MXL5007R ID register; reg=d9 val=14 */
@@ -505,7 +507,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
505 if (ret == 0 && buf[0] == 0x14) { 507 if (ret == 0 && buf[0] == 0x14) {
506 priv->tuner = TUNER_RTL2832_MXL5007T; 508 priv->tuner = TUNER_RTL2832_MXL5007T;
507 priv->tuner_name = "MXL5007T"; 509 priv->tuner_name = "MXL5007T";
508 goto found; 510 goto tuner_found;
509 } 511 }
510 512
511 /* check E4000 ID register; reg=02 val=40 */ 513 /* check E4000 ID register; reg=02 val=40 */
@@ -513,7 +515,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
513 if (ret == 0 && buf[0] == 0x40) { 515 if (ret == 0 && buf[0] == 0x40) {
514 priv->tuner = TUNER_RTL2832_E4000; 516 priv->tuner = TUNER_RTL2832_E4000;
515 priv->tuner_name = "E4000"; 517 priv->tuner_name = "E4000";
516 goto found; 518 goto tuner_found;
517 } 519 }
518 520
519 /* check TDA18272 ID register; reg=00 val=c760 */ 521 /* check TDA18272 ID register; reg=00 val=c760 */
@@ -521,7 +523,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
521 if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) { 523 if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) {
522 priv->tuner = TUNER_RTL2832_TDA18272; 524 priv->tuner = TUNER_RTL2832_TDA18272;
523 priv->tuner_name = "TDA18272"; 525 priv->tuner_name = "TDA18272";
524 goto found; 526 goto tuner_found;
525 } 527 }
526 528
527 /* check R820T ID register; reg=00 val=69 */ 529 /* check R820T ID register; reg=00 val=69 */
@@ -529,7 +531,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
529 if (ret == 0 && buf[0] == 0x69) { 531 if (ret == 0 && buf[0] == 0x69) {
530 priv->tuner = TUNER_RTL2832_R820T; 532 priv->tuner = TUNER_RTL2832_R820T;
531 priv->tuner_name = "R820T"; 533 priv->tuner_name = "R820T";
532 goto found; 534 goto tuner_found;
533 } 535 }
534 536
535 /* check R828D ID register; reg=00 val=69 */ 537 /* check R828D ID register; reg=00 val=69 */
@@ -537,13 +539,37 @@ static int rtl2832u_read_config(struct dvb_usb_device *d)
537 if (ret == 0 && buf[0] == 0x69) { 539 if (ret == 0 && buf[0] == 0x69) {
538 priv->tuner = TUNER_RTL2832_R828D; 540 priv->tuner = TUNER_RTL2832_R828D;
539 priv->tuner_name = "R828D"; 541 priv->tuner_name = "R828D";
540 goto found; 542 goto tuner_found;
541 } 543 }
542 544
543 545tuner_found:
544found:
545 dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name); 546 dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name);
546 547
548 /* probe slave demod */
549 if (priv->tuner == TUNER_RTL2832_R828D) {
550 /* power on MN88472 demod on GPIO0 */
551 ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x01, 0x01);
552 if (ret)
553 goto err;
554
555 ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01);
556 if (ret)
557 goto err;
558
559 ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01);
560 if (ret)
561 goto err;
562
563 /* check MN88472 answers */
564 ret = rtl28xxu_ctrl_msg(d, &req_mn88472);
565 if (ret == 0 && buf[0] == 0x02) {
566 dev_dbg(&d->udev->dev, "%s: MN88472 found\n", __func__);
567 priv->slave_demod = SLAVE_DEMOD_MN88472;
568 goto demod_found;
569 }
570 }
571
572demod_found:
547 /* close demod I2C gate */ 573 /* close demod I2C gate */
548 ret = rtl28xxu_ctrl_msg(d, &req_gate_close); 574 ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
549 if (ret < 0) 575 if (ret < 0)
@@ -818,7 +844,44 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
818 /* set fe callback */ 844 /* set fe callback */
819 adap->fe[0]->callback = rtl2832u_frontend_callback; 845 adap->fe[0]->callback = rtl2832u_frontend_callback;
820 846
847 if (priv->slave_demod) {
848 struct i2c_board_info info = {};
849 struct i2c_client *client;
850
851 /*
852 * We continue on reduced mode, without DVB-T2/C, using master
853 * demod, when slave demod fails.
854 */
855 ret = 0;
856
857 /* attach slave demodulator */
858 if (priv->slave_demod == SLAVE_DEMOD_MN88472) {
859 struct mn88472_config mn88472_config = {};
860
861 mn88472_config.fe = &adap->fe[1];
862 mn88472_config.i2c_wr_max = 22,
863 strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
864 info.addr = 0x18;
865 info.platform_data = &mn88472_config;
866 request_module(info.type);
867 client = i2c_new_device(priv->demod_i2c_adapter, &info);
868 if (client == NULL || client->dev.driver == NULL) {
869 priv->slave_demod = SLAVE_DEMOD_NONE;
870 goto err_slave_demod_failed;
871 }
872
873 if (!try_module_get(client->dev.driver->owner)) {
874 i2c_unregister_device(client);
875 priv->slave_demod = SLAVE_DEMOD_NONE;
876 goto err_slave_demod_failed;
877 }
878
879 priv->i2c_client_slave_demod = client;
880 }
881 }
882
821 return 0; 883 return 0;
884err_slave_demod_failed:
822err: 885err:
823 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 886 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
824 return ret; 887 return ret;
@@ -1024,25 +1087,19 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
1024 &rtl28xxu_rtl2832_r820t_config, NULL); 1087 &rtl28xxu_rtl2832_r820t_config, NULL);
1025 break; 1088 break;
1026 case TUNER_RTL2832_R828D: 1089 case TUNER_RTL2832_R828D:
1027 /* power off mn88472 demod on GPIO0 */ 1090 fe = dvb_attach(r820t_attach, adap->fe[0],
1028 ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x00, 0x01); 1091 priv->demod_i2c_adapter,
1029 if (ret)
1030 goto err;
1031
1032 ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01);
1033 if (ret)
1034 goto err;
1035
1036 ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01);
1037 if (ret)
1038 goto err;
1039
1040 fe = dvb_attach(r820t_attach, adap->fe[0], &d->i2c_adap,
1041 &rtl2832u_r828d_config); 1092 &rtl2832u_r828d_config);
1042
1043 /* Use tuner to get the signal strength */
1044 adap->fe[0]->ops.read_signal_strength = 1093 adap->fe[0]->ops.read_signal_strength =
1045 adap->fe[0]->ops.tuner_ops.get_rf_strength; 1094 adap->fe[0]->ops.tuner_ops.get_rf_strength;
1095
1096 if (adap->fe[1]) {
1097 fe = dvb_attach(r820t_attach, adap->fe[1],
1098 priv->demod_i2c_adapter,
1099 &rtl2832u_r828d_config);
1100 adap->fe[1]->ops.read_signal_strength =
1101 adap->fe[1]->ops.tuner_ops.get_rf_strength;
1102 }
1046 break; 1103 break;
1047 default: 1104 default:
1048 dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME, 1105 dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
@@ -1097,11 +1154,19 @@ err:
1097static void rtl28xxu_exit(struct dvb_usb_device *d) 1154static void rtl28xxu_exit(struct dvb_usb_device *d)
1098{ 1155{
1099 struct rtl28xxu_priv *priv = d->priv; 1156 struct rtl28xxu_priv *priv = d->priv;
1100 struct i2c_client *client = priv->client; 1157 struct i2c_client *client;
1101 1158
1102 dev_dbg(&d->udev->dev, "%s:\n", __func__); 1159 dev_dbg(&d->udev->dev, "%s:\n", __func__);
1103 1160
1104 /* remove I2C tuner */ 1161 /* remove I2C tuner */
1162 client = priv->client;
1163 if (client) {
1164 module_put(client->dev.driver->owner);
1165 i2c_unregister_device(client);
1166 }
1167
1168 /* remove I2C slave demod */
1169 client = priv->i2c_client_slave_demod;
1105 if (client) { 1170 if (client) {
1106 module_put(client->dev.driver->owner); 1171 module_put(client->dev.driver->owner);
1107 i2c_unregister_device(client); 1172 i2c_unregister_device(client);
@@ -1235,6 +1300,7 @@ err:
1235static int rtl2832u_frontend_ctrl(struct dvb_frontend *fe, int onoff) 1300static int rtl2832u_frontend_ctrl(struct dvb_frontend *fe, int onoff)
1236{ 1301{
1237 struct dvb_usb_device *d = fe_to_d(fe); 1302 struct dvb_usb_device *d = fe_to_d(fe);
1303 struct dvb_usb_adapter *adap = fe_to_adap(fe);
1238 int ret; 1304 int ret;
1239 u8 val; 1305 u8 val;
1240 1306
@@ -1250,6 +1316,13 @@ static int rtl2832u_frontend_ctrl(struct dvb_frontend *fe, int onoff)
1250 if (ret) 1316 if (ret)
1251 goto err; 1317 goto err;
1252 1318
1319 /* bypass slave demod TS through master demod */
1320 if (fe->id == 1 && onoff) {
1321 ret = rtl2832_enable_external_ts_if(adap->fe[0]);
1322 if (ret)
1323 goto err;
1324 }
1325
1253 return 0; 1326 return 0;
1254err: 1327err:
1255 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1328 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
index a26cab10f382..c1b00b9831c9 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
@@ -58,6 +58,10 @@ struct rtl28xxu_priv {
58 struct i2c_adapter *demod_i2c_adapter; 58 struct i2c_adapter *demod_i2c_adapter;
59 bool rc_active; 59 bool rc_active;
60 struct i2c_client *client; 60 struct i2c_client *client;
61 struct i2c_client *i2c_client_slave_demod;
62 #define SLAVE_DEMOD_NONE 0
63 #define SLAVE_DEMOD_MN88472 1
64 unsigned int slave_demod:1;
61}; 65};
62 66
63enum rtl28xxu_chip_id { 67enum rtl28xxu_chip_id {