diff options
author | Antti Palosaari <crope@iki.fi> | 2012-09-17 13:01:35 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-09-27 14:14:10 -0400 |
commit | ef37be1b4dd4d6fb4d4d9aae21af1ba616205322 (patch) | |
tree | 31acb4668f55ef2a0341d9131446ffe716833e87 /drivers/media/usb/dvb-usb-v2/rtl28xxu.c | |
parent | 4395e4b76d550242f83eea4c461aacea66ddd385 (diff) |
[media] rtl28xxu: move rtl2832u tuner probing to .read_config()
Move rtl2832u tuner probing correct place.
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/dvb-usb-v2/rtl28xxu.c')
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 351 |
1 files changed, 174 insertions, 177 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 226ec542a703..5eabeacccbc1 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c | |||
@@ -254,6 +254,156 @@ static struct i2c_algorithm rtl28xxu_i2c_algo = { | |||
254 | .functionality = rtl28xxu_i2c_func, | 254 | .functionality = rtl28xxu_i2c_func, |
255 | }; | 255 | }; |
256 | 256 | ||
257 | static int rtl2832u_read_config(struct dvb_usb_device *d) | ||
258 | { | ||
259 | struct rtl28xxu_priv *priv = d_to_priv(d); | ||
260 | int ret; | ||
261 | u8 buf[2], val; | ||
262 | /* open RTL2832U/RTL2832 I2C gate */ | ||
263 | struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"}; | ||
264 | /* close RTL2832U/RTL2832 I2C gate */ | ||
265 | struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"}; | ||
266 | /* tuner probes */ | ||
267 | struct rtl28xxu_req req_fc0012 = {0x00c6, CMD_I2C_RD, 1, buf}; | ||
268 | struct rtl28xxu_req req_fc0013 = {0x00c6, CMD_I2C_RD, 1, buf}; | ||
269 | struct rtl28xxu_req req_mt2266 = {0x00c0, CMD_I2C_RD, 1, buf}; | ||
270 | struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf}; | ||
271 | struct rtl28xxu_req req_mt2063 = {0x00c0, CMD_I2C_RD, 1, buf}; | ||
272 | struct rtl28xxu_req req_max3543 = {0x00c0, CMD_I2C_RD, 1, buf}; | ||
273 | struct rtl28xxu_req req_tua9001 = {0x7ec0, CMD_I2C_RD, 2, buf}; | ||
274 | struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf}; | ||
275 | struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf}; | ||
276 | struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; | ||
277 | |||
278 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | ||
279 | |||
280 | ret = rtl28xx_rd_reg(d, SYS_GPIO_DIR, &val); | ||
281 | if (ret) | ||
282 | goto err; | ||
283 | |||
284 | val &= 0xbf; | ||
285 | |||
286 | ret = rtl28xx_wr_reg(d, SYS_GPIO_DIR, val); | ||
287 | if (ret) | ||
288 | goto err; | ||
289 | |||
290 | /* enable as output GPIO3 and GPIO6 */ | ||
291 | ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_EN, &val); | ||
292 | if (ret) | ||
293 | goto err; | ||
294 | |||
295 | val |= 0x48; | ||
296 | |||
297 | ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, val); | ||
298 | if (ret) | ||
299 | goto err; | ||
300 | |||
301 | /* | ||
302 | * Probe used tuner. We need to know used tuner before demod attach | ||
303 | * since there is some demod params needed to set according to tuner. | ||
304 | */ | ||
305 | |||
306 | /* open demod I2C gate */ | ||
307 | ret = rtl28xxu_ctrl_msg(d, &req_gate_open); | ||
308 | if (ret) | ||
309 | goto err; | ||
310 | |||
311 | priv->tuner_name = "NONE"; | ||
312 | |||
313 | /* check FC0012 ID register; reg=00 val=a1 */ | ||
314 | ret = rtl28xxu_ctrl_msg(d, &req_fc0012); | ||
315 | if (ret == 0 && buf[0] == 0xa1) { | ||
316 | priv->tuner = TUNER_RTL2832_FC0012; | ||
317 | priv->tuner_name = "FC0012"; | ||
318 | goto found; | ||
319 | } | ||
320 | |||
321 | /* check FC0013 ID register; reg=00 val=a3 */ | ||
322 | ret = rtl28xxu_ctrl_msg(d, &req_fc0013); | ||
323 | if (ret == 0 && buf[0] == 0xa3) { | ||
324 | priv->tuner = TUNER_RTL2832_FC0013; | ||
325 | priv->tuner_name = "FC0013"; | ||
326 | goto found; | ||
327 | } | ||
328 | |||
329 | /* check MT2266 ID register; reg=00 val=85 */ | ||
330 | ret = rtl28xxu_ctrl_msg(d, &req_mt2266); | ||
331 | if (ret == 0 && buf[0] == 0x85) { | ||
332 | priv->tuner = TUNER_RTL2832_MT2266; | ||
333 | priv->tuner_name = "MT2266"; | ||
334 | goto found; | ||
335 | } | ||
336 | |||
337 | /* check FC2580 ID register; reg=01 val=56 */ | ||
338 | ret = rtl28xxu_ctrl_msg(d, &req_fc2580); | ||
339 | if (ret == 0 && buf[0] == 0x56) { | ||
340 | priv->tuner = TUNER_RTL2832_FC2580; | ||
341 | priv->tuner_name = "FC2580"; | ||
342 | goto found; | ||
343 | } | ||
344 | |||
345 | /* check MT2063 ID register; reg=00 val=9e || 9c */ | ||
346 | ret = rtl28xxu_ctrl_msg(d, &req_mt2063); | ||
347 | if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) { | ||
348 | priv->tuner = TUNER_RTL2832_MT2063; | ||
349 | priv->tuner_name = "MT2063"; | ||
350 | goto found; | ||
351 | } | ||
352 | |||
353 | /* check MAX3543 ID register; reg=00 val=38 */ | ||
354 | ret = rtl28xxu_ctrl_msg(d, &req_max3543); | ||
355 | if (ret == 0 && buf[0] == 0x38) { | ||
356 | priv->tuner = TUNER_RTL2832_MAX3543; | ||
357 | priv->tuner_name = "MAX3543"; | ||
358 | goto found; | ||
359 | } | ||
360 | |||
361 | /* check TUA9001 ID register; reg=7e val=2328 */ | ||
362 | ret = rtl28xxu_ctrl_msg(d, &req_tua9001); | ||
363 | if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) { | ||
364 | priv->tuner = TUNER_RTL2832_TUA9001; | ||
365 | priv->tuner_name = "TUA9001"; | ||
366 | goto found; | ||
367 | } | ||
368 | |||
369 | /* check MXL5007R ID register; reg=d9 val=14 */ | ||
370 | ret = rtl28xxu_ctrl_msg(d, &req_mxl5007t); | ||
371 | if (ret == 0 && buf[0] == 0x14) { | ||
372 | priv->tuner = TUNER_RTL2832_MXL5007T; | ||
373 | priv->tuner_name = "MXL5007T"; | ||
374 | goto found; | ||
375 | } | ||
376 | |||
377 | /* check E4000 ID register; reg=02 val=40 */ | ||
378 | ret = rtl28xxu_ctrl_msg(d, &req_e4000); | ||
379 | if (ret == 0 && buf[0] == 0x40) { | ||
380 | priv->tuner = TUNER_RTL2832_E4000; | ||
381 | priv->tuner_name = "E4000"; | ||
382 | goto found; | ||
383 | } | ||
384 | |||
385 | /* check TDA18272 ID register; reg=00 val=c760 */ | ||
386 | ret = rtl28xxu_ctrl_msg(d, &req_tda18272); | ||
387 | if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) { | ||
388 | priv->tuner = TUNER_RTL2832_TDA18272; | ||
389 | priv->tuner_name = "TDA18272"; | ||
390 | goto found; | ||
391 | } | ||
392 | |||
393 | found: | ||
394 | dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name); | ||
395 | |||
396 | /* close demod I2C gate */ | ||
397 | ret = rtl28xxu_ctrl_msg(d, &req_gate_close); | ||
398 | if (ret < 0) | ||
399 | goto err; | ||
400 | |||
401 | return 0; | ||
402 | err: | ||
403 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | ||
404 | return ret; | ||
405 | } | ||
406 | |||
257 | static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = { | 407 | static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = { |
258 | .i2c_addr = 0x10, /* 0x20 */ | 408 | .i2c_addr = 0x10, /* 0x20 */ |
259 | .xtal = 28800000, | 409 | .xtal = 28800000, |
@@ -537,199 +687,45 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) | |||
537 | struct dvb_usb_device *d = adap_to_d(adap); | 687 | struct dvb_usb_device *d = adap_to_d(adap); |
538 | struct rtl28xxu_priv *priv = d_to_priv(d); | 688 | struct rtl28xxu_priv *priv = d_to_priv(d); |
539 | struct rtl2832_config *rtl2832_config; | 689 | struct rtl2832_config *rtl2832_config; |
540 | u8 buf[2], val; | ||
541 | /* open RTL2832U/RTL2832 I2C gate */ | ||
542 | struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"}; | ||
543 | /* close RTL2832U/RTL2832 I2C gate */ | ||
544 | struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"}; | ||
545 | /* for FC0012 tuner probe */ | ||
546 | struct rtl28xxu_req req_fc0012 = {0x00c6, CMD_I2C_RD, 1, buf}; | ||
547 | /* for FC0013 tuner probe */ | ||
548 | struct rtl28xxu_req req_fc0013 = {0x00c6, CMD_I2C_RD, 1, buf}; | ||
549 | /* for MT2266 tuner probe */ | ||
550 | struct rtl28xxu_req req_mt2266 = {0x00c0, CMD_I2C_RD, 1, buf}; | ||
551 | /* for FC2580 tuner probe */ | ||
552 | struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf}; | ||
553 | /* for MT2063 tuner probe */ | ||
554 | struct rtl28xxu_req req_mt2063 = {0x00c0, CMD_I2C_RD, 1, buf}; | ||
555 | /* for MAX3543 tuner probe */ | ||
556 | struct rtl28xxu_req req_max3543 = {0x00c0, CMD_I2C_RD, 1, buf}; | ||
557 | /* for TUA9001 tuner probe */ | ||
558 | struct rtl28xxu_req req_tua9001 = {0x7ec0, CMD_I2C_RD, 2, buf}; | ||
559 | /* for MXL5007T tuner probe */ | ||
560 | struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf}; | ||
561 | /* for E4000 tuner probe */ | ||
562 | struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf}; | ||
563 | /* for TDA18272 tuner probe */ | ||
564 | struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; | ||
565 | 690 | ||
566 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | 691 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
567 | 692 | ||
568 | ret = rtl28xx_rd_reg(d, SYS_GPIO_DIR, &val); | 693 | switch (priv->tuner) { |
569 | if (ret) | 694 | case TUNER_RTL2832_FC0012: |
570 | goto err; | ||
571 | |||
572 | val &= 0xbf; | ||
573 | |||
574 | ret = rtl28xx_wr_reg(d, SYS_GPIO_DIR, val); | ||
575 | if (ret) | ||
576 | goto err; | ||
577 | |||
578 | /* enable as output GPIO3 and GPIO6*/ | ||
579 | ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_EN, &val); | ||
580 | if (ret) | ||
581 | goto err; | ||
582 | |||
583 | val |= 0x48; | ||
584 | |||
585 | ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, val); | ||
586 | if (ret) | ||
587 | goto err; | ||
588 | |||
589 | /* | ||
590 | * Probe used tuner. We need to know used tuner before demod attach | ||
591 | * since there is some demod params needed to set according to tuner. | ||
592 | */ | ||
593 | |||
594 | /* open demod I2C gate */ | ||
595 | ret = rtl28xxu_ctrl_msg(d, &req_gate_open); | ||
596 | if (ret) | ||
597 | goto err; | ||
598 | |||
599 | priv->tuner = TUNER_NONE; | ||
600 | |||
601 | /* check FC0012 ID register; reg=00 val=a1 */ | ||
602 | ret = rtl28xxu_ctrl_msg(d, &req_fc0012); | ||
603 | if (ret == 0 && buf[0] == 0xa1) { | ||
604 | priv->tuner = TUNER_RTL2832_FC0012; | ||
605 | rtl2832_config = &rtl28xxu_rtl2832_fc0012_config; | 695 | rtl2832_config = &rtl28xxu_rtl2832_fc0012_config; |
606 | dev_info(&d->udev->dev, "%s: FC0012 tuner found", | 696 | break; |
607 | KBUILD_MODNAME); | 697 | case TUNER_RTL2832_FC0013: |
608 | goto found; | ||
609 | } | ||
610 | |||
611 | /* check FC0013 ID register; reg=00 val=a3 */ | ||
612 | ret = rtl28xxu_ctrl_msg(d, &req_fc0013); | ||
613 | if (ret == 0 && buf[0] == 0xa3) { | ||
614 | priv->tuner = TUNER_RTL2832_FC0013; | ||
615 | rtl2832_config = &rtl28xxu_rtl2832_fc0013_config; | 698 | rtl2832_config = &rtl28xxu_rtl2832_fc0013_config; |
616 | dev_info(&d->udev->dev, "%s: FC0013 tuner found", | 699 | break; |
617 | KBUILD_MODNAME); | 700 | case TUNER_RTL2832_FC2580: |
618 | goto found; | ||
619 | } | ||
620 | |||
621 | /* check MT2266 ID register; reg=00 val=85 */ | ||
622 | ret = rtl28xxu_ctrl_msg(d, &req_mt2266); | ||
623 | if (ret == 0 && buf[0] == 0x85) { | ||
624 | priv->tuner = TUNER_RTL2832_MT2266; | ||
625 | /* TODO implement tuner */ | ||
626 | dev_info(&d->udev->dev, "%s: MT2266 tuner found", | ||
627 | KBUILD_MODNAME); | ||
628 | goto unsupported; | ||
629 | } | ||
630 | |||
631 | /* check FC2580 ID register; reg=01 val=56 */ | ||
632 | ret = rtl28xxu_ctrl_msg(d, &req_fc2580); | ||
633 | if (ret == 0 && buf[0] == 0x56) { | ||
634 | priv->tuner = TUNER_RTL2832_FC2580; | ||
635 | /* FIXME: do not abuse fc0012 settings */ | 701 | /* FIXME: do not abuse fc0012 settings */ |
636 | rtl2832_config = &rtl28xxu_rtl2832_fc0012_config; | 702 | rtl2832_config = &rtl28xxu_rtl2832_fc0012_config; |
637 | dev_info(&d->udev->dev, "%s: FC2580 tuner found", | 703 | break; |
638 | KBUILD_MODNAME); | 704 | case TUNER_RTL2832_TUA9001: |
639 | goto found; | ||
640 | } | ||
641 | |||
642 | /* check MT2063 ID register; reg=00 val=9e || 9c */ | ||
643 | ret = rtl28xxu_ctrl_msg(d, &req_mt2063); | ||
644 | if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) { | ||
645 | priv->tuner = TUNER_RTL2832_MT2063; | ||
646 | /* TODO implement tuner */ | ||
647 | dev_info(&d->udev->dev, "%s: MT2063 tuner found", | ||
648 | KBUILD_MODNAME); | ||
649 | goto unsupported; | ||
650 | } | ||
651 | |||
652 | /* check MAX3543 ID register; reg=00 val=38 */ | ||
653 | ret = rtl28xxu_ctrl_msg(d, &req_max3543); | ||
654 | if (ret == 0 && buf[0] == 0x38) { | ||
655 | priv->tuner = TUNER_RTL2832_MAX3543; | ||
656 | /* TODO implement tuner */ | ||
657 | dev_info(&d->udev->dev, "%s: MAX3534 tuner found", | ||
658 | KBUILD_MODNAME); | ||
659 | goto unsupported; | ||
660 | } | ||
661 | |||
662 | /* check TUA9001 ID register; reg=7e val=2328 */ | ||
663 | ret = rtl28xxu_ctrl_msg(d, &req_tua9001); | ||
664 | if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) { | ||
665 | priv->tuner = TUNER_RTL2832_TUA9001; | ||
666 | rtl2832_config = &rtl28xxu_rtl2832_tua9001_config; | 705 | rtl2832_config = &rtl28xxu_rtl2832_tua9001_config; |
667 | dev_info(&d->udev->dev, "%s: TUA9001 tuner found", | 706 | break; |
668 | KBUILD_MODNAME); | 707 | case TUNER_RTL2832_E4000: |
669 | goto found; | ||
670 | } | ||
671 | |||
672 | /* check MXL5007R ID register; reg=d9 val=14 */ | ||
673 | ret = rtl28xxu_ctrl_msg(d, &req_mxl5007t); | ||
674 | if (ret == 0 && buf[0] == 0x14) { | ||
675 | priv->tuner = TUNER_RTL2832_MXL5007T; | ||
676 | /* TODO implement tuner */ | ||
677 | dev_info(&d->udev->dev, "%s: MXL5007T tuner found", | ||
678 | KBUILD_MODNAME); | ||
679 | goto unsupported; | ||
680 | } | ||
681 | |||
682 | /* check E4000 ID register; reg=02 val=40 */ | ||
683 | ret = rtl28xxu_ctrl_msg(d, &req_e4000); | ||
684 | if (ret == 0 && buf[0] == 0x40) { | ||
685 | priv->tuner = TUNER_RTL2832_E4000; | ||
686 | /* FIXME: do not abuse fc0012 settings */ | 708 | /* FIXME: do not abuse fc0012 settings */ |
687 | rtl2832_config = &rtl28xxu_rtl2832_fc0012_config; | 709 | rtl2832_config = &rtl28xxu_rtl2832_fc0012_config; |
688 | dev_info(&d->udev->dev, "%s: E4000 tuner found", | 710 | break; |
689 | KBUILD_MODNAME); | 711 | default: |
690 | goto found; | 712 | dev_err(&d->udev->dev, "%s: unknown tuner=%s\n", |
691 | } | 713 | KBUILD_MODNAME, priv->tuner_name); |
692 | 714 | ret = -ENODEV; | |
693 | /* check TDA18272 ID register; reg=00 val=c760 */ | ||
694 | ret = rtl28xxu_ctrl_msg(d, &req_tda18272); | ||
695 | if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) { | ||
696 | priv->tuner = TUNER_RTL2832_TDA18272; | ||
697 | /* TODO implement tuner */ | ||
698 | dev_info(&d->udev->dev, "%s: TDA18272 tuner found", | ||
699 | KBUILD_MODNAME); | ||
700 | goto unsupported; | ||
701 | } | ||
702 | |||
703 | unsupported: | ||
704 | /* close demod I2C gate */ | ||
705 | ret = rtl28xxu_ctrl_msg(d, &req_gate_close); | ||
706 | if (ret) | ||
707 | goto err; | ||
708 | |||
709 | /* tuner not found */ | ||
710 | dev_dbg(&d->udev->dev, "%s: No compatible tuner found\n", __func__); | ||
711 | ret = -ENODEV; | ||
712 | return ret; | ||
713 | |||
714 | found: | ||
715 | /* close demod I2C gate */ | ||
716 | ret = rtl28xxu_ctrl_msg(d, &req_gate_close); | ||
717 | if (ret) | ||
718 | goto err; | 715 | goto err; |
716 | } | ||
719 | 717 | ||
720 | /* attach demodulator */ | 718 | /* attach demodulator */ |
721 | adap->fe[0] = dvb_attach(rtl2832_attach, rtl2832_config, | 719 | adap->fe[0] = dvb_attach(rtl2832_attach, rtl2832_config, &d->i2c_adap); |
722 | &d->i2c_adap); | 720 | if (!adap->fe[0]) { |
723 | if (adap->fe[0] == NULL) { | 721 | ret = -ENODEV; |
724 | ret = -ENODEV; | 722 | goto err; |
725 | goto err; | 723 | } |
726 | } | ||
727 | 724 | ||
728 | /* set fe callbacks */ | 725 | /* set fe callback */ |
729 | adap->fe[0]->callback = rtl2832u_frontend_callback; | 726 | adap->fe[0]->callback = rtl2832u_frontend_callback; |
730 | 727 | ||
731 | return ret; | 728 | return 0; |
732 | |||
733 | err: | 729 | err: |
734 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); | 730 | dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); |
735 | return ret; | 731 | return ret; |
@@ -1304,6 +1300,7 @@ static const struct dvb_usb_device_properties rtl2832u_props = { | |||
1304 | 1300 | ||
1305 | .power_ctrl = rtl2832u_power_ctrl, | 1301 | .power_ctrl = rtl2832u_power_ctrl, |
1306 | .i2c_algo = &rtl28xxu_i2c_algo, | 1302 | .i2c_algo = &rtl28xxu_i2c_algo, |
1303 | .read_config = rtl2832u_read_config, | ||
1307 | .frontend_attach = rtl2832u_frontend_attach, | 1304 | .frontend_attach = rtl2832u_frontend_attach, |
1308 | .tuner_attach = rtl2832u_tuner_attach, | 1305 | .tuner_attach = rtl2832u_tuner_attach, |
1309 | .init = rtl28xxu_init, | 1306 | .init = rtl28xxu_init, |