diff options
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/dvb-usb/mxl111sf.c | 228 |
1 files changed, 225 insertions, 3 deletions
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c index 546ba5915a5b..b5c98da5d9e2 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include "mxl111sf-i2c.h" | 17 | #include "mxl111sf-i2c.h" |
18 | #include "mxl111sf-gpio.h" | 18 | #include "mxl111sf-gpio.h" |
19 | 19 | ||
20 | #include "mxl111sf-demod.h" | ||
20 | #include "mxl111sf-tuner.h" | 21 | #include "mxl111sf-tuner.h" |
21 | 22 | ||
22 | #include "lgdt3305.h" | 23 | #include "lgdt3305.h" |
@@ -362,6 +363,22 @@ static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | |||
362 | return ret; | 363 | return ret; |
363 | } | 364 | } |
364 | 365 | ||
366 | static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | ||
367 | { | ||
368 | struct dvb_usb_device *d = adap->dev; | ||
369 | struct mxl111sf_state *state = d->priv; | ||
370 | int ret = 0; | ||
371 | |||
372 | deb_info("%s(%d)\n", __func__, onoff); | ||
373 | |||
374 | if (onoff) { | ||
375 | ret = mxl111sf_enable_usb_output(state); | ||
376 | mxl_fail(ret); | ||
377 | } | ||
378 | |||
379 | return ret; | ||
380 | } | ||
381 | |||
365 | /* ------------------------------------------------------------------------ */ | 382 | /* ------------------------------------------------------------------------ */ |
366 | 383 | ||
367 | static struct lgdt3305_config hauppauge_lgdt3305_config = { | 384 | static struct lgdt3305_config hauppauge_lgdt3305_config = { |
@@ -438,6 +455,70 @@ fail: | |||
438 | return ret; | 455 | return ret; |
439 | } | 456 | } |
440 | 457 | ||
458 | static struct mxl111sf_demod_config mxl_demod_config = { | ||
459 | .read_reg = mxl111sf_read_reg, | ||
460 | .write_reg = mxl111sf_write_reg, | ||
461 | .program_regs = mxl111sf_ctrl_program_regs, | ||
462 | }; | ||
463 | |||
464 | static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap) | ||
465 | { | ||
466 | struct dvb_usb_device *d = adap->dev; | ||
467 | struct mxl111sf_state *state = d->priv; | ||
468 | int fe_id = adap->num_frontends_initialized; | ||
469 | struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv; | ||
470 | int ret; | ||
471 | |||
472 | deb_adv("%s()\n", __func__); | ||
473 | |||
474 | /* save a pointer to the dvb_usb_device in device state */ | ||
475 | state->d = d; | ||
476 | adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2; | ||
477 | state->alt_mode = adap_state->alt_mode; | ||
478 | |||
479 | if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0) | ||
480 | err("set interface failed"); | ||
481 | |||
482 | state->gpio_mode = MXL111SF_GPIO_MOD_DVBT; | ||
483 | adap_state->gpio_mode = state->gpio_mode; | ||
484 | adap_state->device_mode = MXL_SOC_MODE; | ||
485 | adap_state->ep6_clockphase = 1; | ||
486 | |||
487 | ret = mxl1x1sf_soft_reset(state); | ||
488 | if (mxl_fail(ret)) | ||
489 | goto fail; | ||
490 | ret = mxl111sf_init_tuner_demod(state); | ||
491 | if (mxl_fail(ret)) | ||
492 | goto fail; | ||
493 | |||
494 | ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode); | ||
495 | if (mxl_fail(ret)) | ||
496 | goto fail; | ||
497 | |||
498 | ret = mxl111sf_enable_usb_output(state); | ||
499 | if (mxl_fail(ret)) | ||
500 | goto fail; | ||
501 | ret = mxl1x1sf_top_master_ctrl(state, 1); | ||
502 | if (mxl_fail(ret)) | ||
503 | goto fail; | ||
504 | |||
505 | /* dont care if this fails */ | ||
506 | mxl111sf_init_port_expander(state); | ||
507 | |||
508 | adap->fe_adap[fe_id].fe = dvb_attach(mxl111sf_demod_attach, state, | ||
509 | &mxl_demod_config); | ||
510 | if (adap->fe_adap[fe_id].fe) { | ||
511 | adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init; | ||
512 | adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init; | ||
513 | adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep; | ||
514 | adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep; | ||
515 | return 0; | ||
516 | } | ||
517 | ret = -EIO; | ||
518 | fail: | ||
519 | return ret; | ||
520 | } | ||
521 | |||
441 | static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state, | 522 | static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state, |
442 | int antpath) | 523 | int antpath) |
443 | { | 524 | { |
@@ -567,7 +648,8 @@ struct i2c_algorithm mxl111sf_i2c_algo = { | |||
567 | #endif | 648 | #endif |
568 | }; | 649 | }; |
569 | 650 | ||
570 | /* DVB USB Driver stuff */ | 651 | static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties; |
652 | static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties; | ||
571 | static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties; | 653 | static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties; |
572 | static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties; | 654 | static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties; |
573 | 655 | ||
@@ -580,9 +662,15 @@ static int mxl111sf_probe(struct usb_interface *intf, | |||
580 | 662 | ||
581 | if (((dvb_usb_mxl111sf_isoc) && | 663 | if (((dvb_usb_mxl111sf_isoc) && |
582 | (0 == dvb_usb_device_init(intf, | 664 | (0 == dvb_usb_device_init(intf, |
665 | &mxl111sf_dvbt_isoc_properties, | ||
666 | THIS_MODULE, &d, adapter_nr) || | ||
667 | 0 == dvb_usb_device_init(intf, | ||
583 | &mxl111sf_atsc_isoc_properties, | 668 | &mxl111sf_atsc_isoc_properties, |
584 | THIS_MODULE, &d, adapter_nr))) || | 669 | THIS_MODULE, &d, adapter_nr))) || |
585 | 0 == dvb_usb_device_init(intf, | 670 | 0 == dvb_usb_device_init(intf, |
671 | &mxl111sf_dvbt_bulk_properties, | ||
672 | THIS_MODULE, &d, adapter_nr) || | ||
673 | 0 == dvb_usb_device_init(intf, | ||
586 | &mxl111sf_atsc_bulk_properties, | 674 | &mxl111sf_atsc_bulk_properties, |
587 | THIS_MODULE, &d, adapter_nr) || 0) { | 675 | THIS_MODULE, &d, adapter_nr) || 0) { |
588 | 676 | ||
@@ -669,6 +757,36 @@ static struct usb_device_id mxl111sf_table[] = { | |||
669 | MODULE_DEVICE_TABLE(usb, mxl111sf_table); | 757 | MODULE_DEVICE_TABLE(usb, mxl111sf_table); |
670 | 758 | ||
671 | 759 | ||
760 | #define MXL111SF_EP4_BULK_STREAMING_CONFIG \ | ||
761 | .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \ | ||
762 | .stream = { \ | ||
763 | .type = USB_BULK, \ | ||
764 | .count = 5, \ | ||
765 | .endpoint = 0x04, \ | ||
766 | .u = { \ | ||
767 | .bulk = { \ | ||
768 | .buffersize = 8192, \ | ||
769 | } \ | ||
770 | } \ | ||
771 | } | ||
772 | |||
773 | /* FIXME: works for v6 but not v8 silicon */ | ||
774 | #define MXL111SF_EP4_ISOC_STREAMING_CONFIG \ | ||
775 | .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \ | ||
776 | .stream = { \ | ||
777 | .type = USB_ISOC, \ | ||
778 | .count = 5, \ | ||
779 | .endpoint = 0x04, \ | ||
780 | .u = { \ | ||
781 | .isoc = { \ | ||
782 | .framesperurb = 96, \ | ||
783 | /* FIXME: v6 SILICON: */ \ | ||
784 | .framesize = 564, \ | ||
785 | .interval = 1, \ | ||
786 | } \ | ||
787 | } \ | ||
788 | } | ||
789 | |||
672 | #define MXL111SF_EP6_BULK_STREAMING_CONFIG \ | 790 | #define MXL111SF_EP6_BULK_STREAMING_CONFIG \ |
673 | .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ | 791 | .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ |
674 | .stream = { \ | 792 | .stream = { \ |
@@ -712,7 +830,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table); | |||
712 | .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \ | 830 | .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \ |
713 | .size_of_priv = sizeof(struct mxl111sf_state) | 831 | .size_of_priv = sizeof(struct mxl111sf_state) |
714 | 832 | ||
715 | static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = { | 833 | static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = { |
716 | MXL111SF_DEFAULT_DEVICE_PROPERTIES, | 834 | MXL111SF_DEFAULT_DEVICE_PROPERTIES, |
717 | 835 | ||
718 | .num_adapters = 1, | 836 | .num_adapters = 1, |
@@ -723,10 +841,106 @@ static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = { | |||
723 | .fe = {{ | 841 | .fe = {{ |
724 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | 842 | .size_of_priv = sizeof(struct mxl111sf_adap_state), |
725 | 843 | ||
844 | .frontend_attach = mxl111sf_attach_demod, | ||
845 | .tuner_attach = mxl111sf_attach_tuner, | ||
846 | |||
847 | MXL111SF_EP4_BULK_STREAMING_CONFIG, | ||
848 | } }, | ||
849 | }, | ||
850 | }, | ||
851 | .num_device_descs = 4, | ||
852 | .devices = { | ||
853 | { "Hauppauge 126xxx DVBT (bulk)", | ||
854 | { NULL }, | ||
855 | { &mxl111sf_table[4], &mxl111sf_table[8], | ||
856 | NULL }, | ||
857 | }, | ||
858 | { "Hauppauge 117xxx DVBT (bulk)", | ||
859 | { NULL }, | ||
860 | { &mxl111sf_table[15], &mxl111sf_table[18], | ||
861 | NULL }, | ||
862 | }, | ||
863 | { "Hauppauge 138xxx DVBT (bulk)", | ||
864 | { NULL }, | ||
865 | { &mxl111sf_table[20], &mxl111sf_table[22], | ||
866 | &mxl111sf_table[24], &mxl111sf_table[26], | ||
867 | NULL }, | ||
868 | }, | ||
869 | { "Hauppauge 126xxx (tp-bulk)", | ||
870 | { NULL }, | ||
871 | { &mxl111sf_table[28], &mxl111sf_table[30], | ||
872 | NULL }, | ||
873 | }, | ||
874 | } | ||
875 | }; | ||
876 | |||
877 | static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = { | ||
878 | MXL111SF_DEFAULT_DEVICE_PROPERTIES, | ||
879 | |||
880 | .num_adapters = 1, | ||
881 | .adapter = { | ||
882 | { | ||
883 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, | ||
884 | .num_frontends = 1, | ||
885 | .fe = {{ | ||
886 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | ||
887 | |||
888 | .frontend_attach = mxl111sf_attach_demod, | ||
889 | .tuner_attach = mxl111sf_attach_tuner, | ||
890 | |||
891 | MXL111SF_EP4_ISOC_STREAMING_CONFIG, | ||
892 | } }, | ||
893 | }, | ||
894 | }, | ||
895 | .num_device_descs = 4, | ||
896 | .devices = { | ||
897 | { "Hauppauge 126xxx DVBT (isoc)", | ||
898 | { NULL }, | ||
899 | { &mxl111sf_table[4], &mxl111sf_table[8], | ||
900 | NULL }, | ||
901 | }, | ||
902 | { "Hauppauge 117xxx DVBT (isoc)", | ||
903 | { NULL }, | ||
904 | { &mxl111sf_table[15], &mxl111sf_table[18], | ||
905 | NULL }, | ||
906 | }, | ||
907 | { "Hauppauge 138xxx DVBT (isoc)", | ||
908 | { NULL }, | ||
909 | { &mxl111sf_table[20], &mxl111sf_table[22], | ||
910 | &mxl111sf_table[24], &mxl111sf_table[26], | ||
911 | NULL }, | ||
912 | }, | ||
913 | { "Hauppauge 126xxx (tp-isoc)", | ||
914 | { NULL }, | ||
915 | { &mxl111sf_table[28], &mxl111sf_table[30], | ||
916 | NULL }, | ||
917 | }, | ||
918 | } | ||
919 | }; | ||
920 | |||
921 | static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = { | ||
922 | MXL111SF_DEFAULT_DEVICE_PROPERTIES, | ||
923 | |||
924 | .num_adapters = 1, | ||
925 | .adapter = { | ||
926 | { | ||
927 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, | ||
928 | .num_frontends = 2, | ||
929 | .fe = {{ | ||
930 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | ||
931 | |||
726 | .frontend_attach = mxl111sf_lgdt3305_frontend_attach, | 932 | .frontend_attach = mxl111sf_lgdt3305_frontend_attach, |
727 | .tuner_attach = mxl111sf_attach_tuner, | 933 | .tuner_attach = mxl111sf_attach_tuner, |
728 | 934 | ||
729 | MXL111SF_EP6_BULK_STREAMING_CONFIG, | 935 | MXL111SF_EP6_BULK_STREAMING_CONFIG, |
936 | }, | ||
937 | { | ||
938 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | ||
939 | |||
940 | .frontend_attach = mxl111sf_attach_demod, | ||
941 | .tuner_attach = mxl111sf_attach_tuner, | ||
942 | |||
943 | MXL111SF_EP4_BULK_STREAMING_CONFIG, | ||
730 | }}, | 944 | }}, |
731 | }, | 945 | }, |
732 | }, | 946 | }, |
@@ -776,7 +990,7 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = { | |||
776 | .adapter = { | 990 | .adapter = { |
777 | { | 991 | { |
778 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, | 992 | .fe_ioctl_override = mxl111sf_fe_ioctl_override, |
779 | .num_frontends = 1, | 993 | .num_frontends = 2, |
780 | .fe = {{ | 994 | .fe = {{ |
781 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | 995 | .size_of_priv = sizeof(struct mxl111sf_adap_state), |
782 | 996 | ||
@@ -784,6 +998,14 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = { | |||
784 | .tuner_attach = mxl111sf_attach_tuner, | 998 | .tuner_attach = mxl111sf_attach_tuner, |
785 | 999 | ||
786 | MXL111SF_EP6_ISOC_STREAMING_CONFIG, | 1000 | MXL111SF_EP6_ISOC_STREAMING_CONFIG, |
1001 | }, | ||
1002 | { | ||
1003 | .size_of_priv = sizeof(struct mxl111sf_adap_state), | ||
1004 | |||
1005 | .frontend_attach = mxl111sf_attach_demod, | ||
1006 | .tuner_attach = mxl111sf_attach_tuner, | ||
1007 | |||
1008 | MXL111SF_EP4_ISOC_STREAMING_CONFIG, | ||
787 | }}, | 1009 | }}, |
788 | }, | 1010 | }, |
789 | }, | 1011 | }, |