diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb/af9015.c')
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9015.c | 394 |
1 files changed, 207 insertions, 187 deletions
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index ea1ed3b4592a..31c0a0ed39f5 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include "tda18271.h" | 31 | #include "tda18271.h" |
32 | #include "mxl5005s.h" | 32 | #include "mxl5005s.h" |
33 | #include "mc44s803.h" | 33 | #include "mc44s803.h" |
34 | #include "tda18218.h" | ||
35 | #include "mxl5007t.h" | ||
34 | 36 | ||
35 | static int dvb_usb_af9015_debug; | 37 | static int dvb_usb_af9015_debug; |
36 | module_param_named(debug, dvb_usb_af9015_debug, int, 0644); | 38 | module_param_named(debug, dvb_usb_af9015_debug, int, 0644); |
@@ -205,12 +207,18 @@ static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val) | |||
205 | return af9015_write_regs(d, addr, &val, 1); | 207 | return af9015_write_regs(d, addr, &val, 1); |
206 | } | 208 | } |
207 | 209 | ||
208 | static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) | 210 | static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len) |
209 | { | 211 | { |
210 | struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, 1, val}; | 212 | struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, |
213 | val}; | ||
211 | return af9015_ctrl_msg(d, &req); | 214 | return af9015_ctrl_msg(d, &req); |
212 | } | 215 | } |
213 | 216 | ||
217 | static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) | ||
218 | { | ||
219 | return af9015_read_regs(d, addr, val, 1); | ||
220 | } | ||
221 | |||
214 | static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, | 222 | static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, |
215 | u8 val) | 223 | u8 val) |
216 | { | 224 | { |
@@ -241,7 +249,7 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
241 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 249 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
242 | int ret = 0, i = 0; | 250 | int ret = 0, i = 0; |
243 | u16 addr; | 251 | u16 addr; |
244 | u8 mbox, addr_len; | 252 | u8 uninitialized_var(mbox), addr_len; |
245 | struct req_t req; | 253 | struct req_t req; |
246 | 254 | ||
247 | /* TODO: implement bus lock | 255 | /* TODO: implement bus lock |
@@ -280,7 +288,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. | |||
280 | } else { | 288 | } else { |
281 | addr = msg[i].buf[0]; | 289 | addr = msg[i].buf[0]; |
282 | addr_len = 1; | 290 | addr_len = 1; |
283 | mbox = 0; | 291 | /* mbox is don't care in that case */ |
284 | } | 292 | } |
285 | 293 | ||
286 | if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { | 294 | if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { |
@@ -494,7 +502,8 @@ static int af9015_copy_firmware(struct dvb_usb_device *d) | |||
494 | /* wait 2nd demodulator ready */ | 502 | /* wait 2nd demodulator ready */ |
495 | msleep(100); | 503 | msleep(100); |
496 | 504 | ||
497 | ret = af9015_read_reg_i2c(d, 0x3a, 0x98be, &val); | 505 | ret = af9015_read_reg_i2c(d, |
506 | af9015_af9013_config[1].demod_address, 0x98be, &val); | ||
498 | if (ret) | 507 | if (ret) |
499 | goto error; | 508 | goto error; |
500 | else | 509 | else |
@@ -597,37 +606,6 @@ free: | |||
597 | return ret; | 606 | return ret; |
598 | } | 607 | } |
599 | 608 | ||
600 | static int af9015_download_ir_table(struct dvb_usb_device *d) | ||
601 | { | ||
602 | int i, packets = 0, ret; | ||
603 | u16 addr = 0x9a56; /* ir-table start address */ | ||
604 | struct req_t req = {WRITE_MEMORY, 0, 0, 0, 0, 1, NULL}; | ||
605 | u8 *data = NULL; | ||
606 | deb_info("%s:\n", __func__); | ||
607 | |||
608 | data = af9015_config.ir_table; | ||
609 | packets = af9015_config.ir_table_size; | ||
610 | |||
611 | /* no remote */ | ||
612 | if (!packets) | ||
613 | goto exit; | ||
614 | |||
615 | /* load remote ir-table */ | ||
616 | for (i = 0; i < packets; i++) { | ||
617 | req.addr = addr + i; | ||
618 | req.data = &data[i]; | ||
619 | ret = af9015_ctrl_msg(d, &req); | ||
620 | if (ret) { | ||
621 | err("ir-table download failed at packet %d with " \ | ||
622 | "code %d", i, ret); | ||
623 | return ret; | ||
624 | } | ||
625 | } | ||
626 | |||
627 | exit: | ||
628 | return 0; | ||
629 | } | ||
630 | |||
631 | static int af9015_init(struct dvb_usb_device *d) | 609 | static int af9015_init(struct dvb_usb_device *d) |
632 | { | 610 | { |
633 | int ret; | 611 | int ret; |
@@ -637,10 +615,6 @@ static int af9015_init(struct dvb_usb_device *d) | |||
637 | if (ret) | 615 | if (ret) |
638 | goto error; | 616 | goto error; |
639 | 617 | ||
640 | ret = af9015_download_ir_table(d); | ||
641 | if (ret) | ||
642 | goto error; | ||
643 | |||
644 | error: | 618 | error: |
645 | return ret; | 619 | return ret; |
646 | } | 620 | } |
@@ -733,125 +707,102 @@ error: | |||
733 | return ret; | 707 | return ret; |
734 | } | 708 | } |
735 | 709 | ||
736 | struct af9015_setup { | 710 | struct af9015_rc_setup { |
737 | unsigned int id; | 711 | unsigned int id; |
738 | struct ir_scancode *rc_key_map; | 712 | char *rc_codes; |
739 | unsigned int rc_key_map_size; | ||
740 | u8 *ir_table; | ||
741 | unsigned int ir_table_size; | ||
742 | }; | 713 | }; |
743 | 714 | ||
744 | static const struct af9015_setup *af9015_setup_match(unsigned int id, | 715 | static char *af9015_rc_setup_match(unsigned int id, |
745 | const struct af9015_setup *table) | 716 | const struct af9015_rc_setup *table) |
746 | { | 717 | { |
747 | for (; table->rc_key_map; table++) | 718 | for (; table->rc_codes; table++) |
748 | if (table->id == id) | 719 | if (table->id == id) |
749 | return table; | 720 | return table->rc_codes; |
750 | return NULL; | 721 | return NULL; |
751 | } | 722 | } |
752 | 723 | ||
753 | static const struct af9015_setup af9015_setup_modparam[] = { | 724 | static const struct af9015_rc_setup af9015_rc_setup_modparam[] = { |
754 | { AF9015_REMOTE_A_LINK_DTU_M, | 725 | { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M }, |
755 | ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link), | 726 | { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II }, |
756 | af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) }, | 727 | { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND }, |
757 | { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, | 728 | { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE }, |
758 | ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi), | 729 | { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS }, |
759 | af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) }, | ||
760 | { AF9015_REMOTE_MYGICTV_U718, | ||
761 | ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv), | ||
762 | af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) }, | ||
763 | { AF9015_REMOTE_DIGITTRADE_DVB_T, | ||
764 | ir_codes_af9015_table_digittrade, ARRAY_SIZE(ir_codes_af9015_table_digittrade), | ||
765 | af9015_ir_table_digittrade, ARRAY_SIZE(af9015_ir_table_digittrade) }, | ||
766 | { AF9015_REMOTE_AVERMEDIA_KS, | ||
767 | ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia), | ||
768 | af9015_ir_table_avermedia_ks, ARRAY_SIZE(af9015_ir_table_avermedia_ks) }, | ||
769 | { } | 730 | { } |
770 | }; | 731 | }; |
771 | 732 | ||
772 | /* don't add new entries here anymore, use hashes instead */ | 733 | static const struct af9015_rc_setup af9015_rc_setup_hashes[] = { |
773 | static const struct af9015_setup af9015_setup_usbids[] = { | 734 | { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II }, |
774 | { USB_VID_LEADTEK, | 735 | { 0xa3703d00, RC_MAP_ALINK_DTU_M }, |
775 | ir_codes_af9015_table_leadtek, ARRAY_SIZE(ir_codes_af9015_table_leadtek), | 736 | { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */ |
776 | af9015_ir_table_leadtek, ARRAY_SIZE(af9015_ir_table_leadtek) }, | ||
777 | { USB_VID_VISIONPLUS, | ||
778 | ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan), | ||
779 | af9015_ir_table_twinhan, ARRAY_SIZE(af9015_ir_table_twinhan) }, | ||
780 | { USB_VID_KWORLD_2, /* TODO: use correct rc keys */ | ||
781 | ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan), | ||
782 | af9015_ir_table_kworld, ARRAY_SIZE(af9015_ir_table_kworld) }, | ||
783 | { USB_VID_AVERMEDIA, | ||
784 | ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia), | ||
785 | af9015_ir_table_avermedia, ARRAY_SIZE(af9015_ir_table_avermedia) }, | ||
786 | { USB_VID_MSI_2, | ||
787 | ir_codes_af9015_table_msi_digivox_iii, ARRAY_SIZE(ir_codes_af9015_table_msi_digivox_iii), | ||
788 | af9015_ir_table_msi_digivox_iii, ARRAY_SIZE(af9015_ir_table_msi_digivox_iii) }, | ||
789 | { } | 737 | { } |
790 | }; | 738 | }; |
791 | 739 | ||
792 | static const struct af9015_setup af9015_setup_hashes[] = { | 740 | static const struct af9015_rc_setup af9015_rc_setup_usbids[] = { |
793 | { 0xb8feb708, | 741 | { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, |
794 | ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi), | 742 | RC_MAP_TERRATEC_SLIM }, |
795 | af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) }, | 743 | { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700, |
796 | { 0xa3703d00, | 744 | RC_MAP_AZUREWAVE_AD_TU700 }, |
797 | ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link), | 745 | { (USB_VID_VISIONPLUS << 16) + USB_PID_TINYTWIN, |
798 | af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) }, | 746 | RC_MAP_AZUREWAVE_AD_TU700 }, |
799 | { 0x9b7dc64e, | 747 | { (USB_VID_MSI_2 << 16) + USB_PID_MSI_DIGI_VOX_MINI_III, |
800 | ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv), | 748 | RC_MAP_MSI_DIGIVOX_III }, |
801 | af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) }, | 749 | { (USB_VID_LEADTEK << 16) + USB_PID_WINFAST_DTV_DONGLE_GOLD, |
750 | RC_MAP_LEADTEK_Y04G0051 }, | ||
751 | { (USB_VID_AVERMEDIA << 16) + USB_PID_AVERMEDIA_VOLAR_X, | ||
752 | RC_MAP_AVERMEDIA_M135A }, | ||
753 | { (USB_VID_AFATECH << 16) + USB_PID_TREKSTOR_DVBT, | ||
754 | RC_MAP_TREKSTOR }, | ||
755 | { (USB_VID_KWORLD_2 << 16) + USB_PID_TINYTWIN_2, | ||
756 | RC_MAP_DIGITALNOW_TINYTWIN }, | ||
757 | { (USB_VID_GTEK << 16) + USB_PID_TINYTWIN_3, | ||
758 | RC_MAP_DIGITALNOW_TINYTWIN }, | ||
802 | { } | 759 | { } |
803 | }; | 760 | }; |
804 | 761 | ||
805 | static void af9015_set_remote_config(struct usb_device *udev, | 762 | static void af9015_set_remote_config(struct usb_device *udev, |
806 | struct dvb_usb_device_properties *props) | 763 | struct dvb_usb_device_properties *props) |
807 | { | 764 | { |
808 | const struct af9015_setup *table = NULL; | 765 | u16 vid = le16_to_cpu(udev->descriptor.idVendor); |
809 | 766 | u16 pid = le16_to_cpu(udev->descriptor.idProduct); | |
810 | if (dvb_usb_af9015_remote) { | 767 | |
811 | /* load remote defined as module param */ | 768 | /* try to load remote based module param */ |
812 | table = af9015_setup_match(dvb_usb_af9015_remote, | 769 | props->rc.core.rc_codes = af9015_rc_setup_match( |
813 | af9015_setup_modparam); | 770 | dvb_usb_af9015_remote, af9015_rc_setup_modparam); |
814 | } else { | 771 | |
815 | u16 vendor = le16_to_cpu(udev->descriptor.idVendor); | 772 | /* try to load remote based eeprom hash */ |
816 | 773 | if (!props->rc.core.rc_codes) | |
817 | table = af9015_setup_match(af9015_config.eeprom_sum, | 774 | props->rc.core.rc_codes = af9015_rc_setup_match( |
818 | af9015_setup_hashes); | 775 | af9015_config.eeprom_sum, af9015_rc_setup_hashes); |
819 | 776 | ||
820 | if (!table && vendor == USB_VID_AFATECH) { | 777 | /* try to load remote based USB ID */ |
821 | /* Check USB manufacturer and product strings and try | 778 | if (!props->rc.core.rc_codes) |
822 | to determine correct remote in case of chip vendor | 779 | props->rc.core.rc_codes = af9015_rc_setup_match( |
823 | reference IDs are used. | 780 | (vid << 16) + pid, af9015_rc_setup_usbids); |
824 | DO NOT ADD ANYTHING NEW HERE. Use hashes instead. | 781 | |
825 | */ | 782 | /* try to load remote based USB iManufacturer string */ |
826 | char manufacturer[10]; | 783 | if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) { |
827 | memset(manufacturer, 0, sizeof(manufacturer)); | 784 | /* Check USB manufacturer and product strings and try |
828 | usb_string(udev, udev->descriptor.iManufacturer, | 785 | to determine correct remote in case of chip vendor |
829 | manufacturer, sizeof(manufacturer)); | 786 | reference IDs are used. |
830 | if (!strcmp("MSI", manufacturer)) { | 787 | DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */ |
831 | /* iManufacturer 1 MSI | 788 | char manufacturer[10]; |
832 | iProduct 2 MSI K-VOX */ | 789 | memset(manufacturer, 0, sizeof(manufacturer)); |
833 | table = af9015_setup_match( | 790 | usb_string(udev, udev->descriptor.iManufacturer, |
834 | AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, | 791 | manufacturer, sizeof(manufacturer)); |
835 | af9015_setup_modparam); | 792 | if (!strcmp("MSI", manufacturer)) { |
836 | } else if (udev->descriptor.idProduct == | 793 | /* iManufacturer 1 MSI |
837 | cpu_to_le16(USB_PID_TREKSTOR_DVBT)) { | 794 | iProduct 2 MSI K-VOX */ |
838 | table = &(const struct af9015_setup){ 0, | 795 | props->rc.core.rc_codes = af9015_rc_setup_match( |
839 | ir_codes_af9015_table_trekstor, | 796 | AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, |
840 | ARRAY_SIZE(ir_codes_af9015_table_trekstor), | 797 | af9015_rc_setup_modparam); |
841 | af9015_ir_table_trekstor, | 798 | } |
842 | ARRAY_SIZE(af9015_ir_table_trekstor) | ||
843 | }; | ||
844 | } | ||
845 | } else if (!table) | ||
846 | table = af9015_setup_match(vendor, af9015_setup_usbids); | ||
847 | } | 799 | } |
848 | 800 | ||
849 | if (table) { | 801 | /* finally load "empty" just for leaving IR receiver enabled */ |
850 | props->rc.legacy.rc_key_map = table->rc_key_map; | 802 | if (!props->rc.core.rc_codes) |
851 | props->rc.legacy.rc_key_map_size = table->rc_key_map_size; | 803 | props->rc.core.rc_codes = RC_MAP_EMPTY; |
852 | af9015_config.ir_table = table->ir_table; | 804 | |
853 | af9015_config.ir_table_size = table->ir_table_size; | 805 | return; |
854 | } | ||
855 | } | 806 | } |
856 | 807 | ||
857 | static int af9015_read_config(struct usb_device *udev) | 808 | static int af9015_read_config(struct usb_device *udev) |
@@ -877,10 +828,9 @@ static int af9015_read_config(struct usb_device *udev) | |||
877 | 828 | ||
878 | deb_info("%s: IR mode:%d\n", __func__, val); | 829 | deb_info("%s: IR mode:%d\n", __func__, val); |
879 | for (i = 0; i < af9015_properties_count; i++) { | 830 | for (i = 0; i < af9015_properties_count; i++) { |
880 | if (val == AF9015_IR_MODE_DISABLED) { | 831 | if (val == AF9015_IR_MODE_DISABLED) |
881 | af9015_properties[i].rc.legacy.rc_key_map = NULL; | 832 | af9015_properties[i].rc.core.rc_codes = NULL; |
882 | af9015_properties[i].rc.legacy.rc_key_map_size = 0; | 833 | else |
883 | } else | ||
884 | af9015_set_remote_config(udev, &af9015_properties[i]); | 834 | af9015_set_remote_config(udev, &af9015_properties[i]); |
885 | } | 835 | } |
886 | 836 | ||
@@ -992,20 +942,19 @@ static int af9015_read_config(struct usb_device *udev) | |||
992 | case AF9013_TUNER_MT2060_2: | 942 | case AF9013_TUNER_MT2060_2: |
993 | case AF9013_TUNER_TDA18271: | 943 | case AF9013_TUNER_TDA18271: |
994 | case AF9013_TUNER_QT1010A: | 944 | case AF9013_TUNER_QT1010A: |
945 | case AF9013_TUNER_TDA18218: | ||
995 | af9015_af9013_config[i].rf_spec_inv = 1; | 946 | af9015_af9013_config[i].rf_spec_inv = 1; |
996 | break; | 947 | break; |
997 | case AF9013_TUNER_MXL5003D: | 948 | case AF9013_TUNER_MXL5003D: |
998 | case AF9013_TUNER_MXL5005D: | 949 | case AF9013_TUNER_MXL5005D: |
999 | case AF9013_TUNER_MXL5005R: | 950 | case AF9013_TUNER_MXL5005R: |
951 | case AF9013_TUNER_MXL5007T: | ||
1000 | af9015_af9013_config[i].rf_spec_inv = 0; | 952 | af9015_af9013_config[i].rf_spec_inv = 0; |
1001 | break; | 953 | break; |
1002 | case AF9013_TUNER_MC44S803: | 954 | case AF9013_TUNER_MC44S803: |
1003 | af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; | 955 | af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; |
1004 | af9015_af9013_config[i].rf_spec_inv = 1; | 956 | af9015_af9013_config[i].rf_spec_inv = 1; |
1005 | break; | 957 | break; |
1006 | case AF9013_TUNER_TDA18218: | ||
1007 | warn("tuner NXP TDA18218 not supported yet"); | ||
1008 | return -ENODEV; | ||
1009 | default: | 958 | default: |
1010 | warn("tuner id:%d not supported, please report!", val); | 959 | warn("tuner id:%d not supported, please report!", val); |
1011 | return -ENODEV; | 960 | return -ENODEV; |
@@ -1020,9 +969,13 @@ error: | |||
1020 | err("eeprom read failed:%d", ret); | 969 | err("eeprom read failed:%d", ret); |
1021 | 970 | ||
1022 | /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM | 971 | /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM |
1023 | content :-( Override some wrong values here. */ | 972 | content :-( Override some wrong values here. Ditto for the |
973 | AVerTV Red HD+ (A850T) device. */ | ||
1024 | if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA && | 974 | if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA && |
1025 | le16_to_cpu(udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) { | 975 | ((le16_to_cpu(udev->descriptor.idProduct) == |
976 | USB_PID_AVERMEDIA_A850) || | ||
977 | (le16_to_cpu(udev->descriptor.idProduct) == | ||
978 | USB_PID_AVERMEDIA_A850T))) { | ||
1026 | deb_info("%s: AverMedia A850: overriding config\n", __func__); | 979 | deb_info("%s: AverMedia A850: overriding config\n", __func__); |
1027 | /* disable dual mode */ | 980 | /* disable dual mode */ |
1028 | af9015_config.dual_mode = 0; | 981 | af9015_config.dual_mode = 0; |
@@ -1059,36 +1012,53 @@ static int af9015_identify_state(struct usb_device *udev, | |||
1059 | return ret; | 1012 | return ret; |
1060 | } | 1013 | } |
1061 | 1014 | ||
1062 | static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 1015 | static int af9015_rc_query(struct dvb_usb_device *d) |
1063 | { | 1016 | { |
1064 | u8 buf[8]; | 1017 | struct af9015_state *priv = d->priv; |
1065 | struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf}; | 1018 | int ret; |
1066 | struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; | 1019 | u8 buf[16]; |
1067 | int i, ret; | ||
1068 | |||
1069 | memset(buf, 0, sizeof(buf)); | ||
1070 | 1020 | ||
1071 | ret = af9015_ctrl_msg(d, &req); | 1021 | /* read registers needed to detect remote controller code */ |
1022 | ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); | ||
1072 | if (ret) | 1023 | if (ret) |
1073 | return ret; | 1024 | goto error; |
1074 | 1025 | ||
1075 | *event = 0; | 1026 | if (buf[14] || buf[15]) { |
1076 | *state = REMOTE_NO_KEY_PRESSED; | 1027 | deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, |
1028 | buf[12], buf[13], buf[14], buf[15]); | ||
1077 | 1029 | ||
1078 | for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) { | 1030 | /* clean IR code from mem */ |
1079 | if (!buf[1] && rc5_custom(&keymap[i]) == buf[0] && | 1031 | ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4); |
1080 | rc5_data(&keymap[i]) == buf[2]) { | 1032 | if (ret) |
1081 | *event = keymap[i].keycode; | 1033 | goto error; |
1082 | *state = REMOTE_KEY_PRESSED; | 1034 | |
1083 | break; | 1035 | if (buf[14] == (u8) ~buf[15]) { |
1036 | if (buf[12] == (u8) ~buf[13]) { | ||
1037 | /* NEC */ | ||
1038 | priv->rc_keycode = buf[12] << 8 | buf[14]; | ||
1039 | } else { | ||
1040 | /* NEC extended*/ | ||
1041 | priv->rc_keycode = buf[12] << 16 | | ||
1042 | buf[13] << 8 | buf[14]; | ||
1043 | } | ||
1044 | ir_keydown(d->rc_input_dev, priv->rc_keycode, 0); | ||
1045 | } else { | ||
1046 | priv->rc_keycode = 0; /* clear just for sure */ | ||
1084 | } | 1047 | } |
1048 | } else if (priv->rc_repeat != buf[6] || buf[0]) { | ||
1049 | deb_rc("%s: key repeated\n", __func__); | ||
1050 | ir_keydown(d->rc_input_dev, priv->rc_keycode, 0); | ||
1051 | } else { | ||
1052 | deb_rc("%s: no key press\n", __func__); | ||
1085 | } | 1053 | } |
1086 | if (!buf[1]) | ||
1087 | deb_rc("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
1088 | __func__, buf[0], buf[1], buf[2], buf[3], buf[4], | ||
1089 | buf[5], buf[6], buf[7]); | ||
1090 | 1054 | ||
1091 | return 0; | 1055 | priv->rc_repeat = buf[6]; |
1056 | |||
1057 | error: | ||
1058 | if (ret) | ||
1059 | err("%s: failed:%d", __func__, ret); | ||
1060 | |||
1061 | return ret; | ||
1092 | } | 1062 | } |
1093 | 1063 | ||
1094 | /* init 2nd I2C adapter */ | 1064 | /* init 2nd I2C adapter */ |
@@ -1100,11 +1070,6 @@ static int af9015_i2c_init(struct dvb_usb_device *d) | |||
1100 | 1070 | ||
1101 | strncpy(state->i2c_adap.name, d->desc->name, | 1071 | strncpy(state->i2c_adap.name, d->desc->name, |
1102 | sizeof(state->i2c_adap.name)); | 1072 | sizeof(state->i2c_adap.name)); |
1103 | #ifdef I2C_ADAP_CLASS_TV_DIGITAL | ||
1104 | state->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, | ||
1105 | #else | ||
1106 | state->i2c_adap.class = I2C_CLASS_TV_DIGITAL, | ||
1107 | #endif | ||
1108 | state->i2c_adap.algo = d->props.i2c_algo; | 1073 | state->i2c_adap.algo = d->props.i2c_algo; |
1109 | state->i2c_adap.algo_data = NULL; | 1074 | state->i2c_adap.algo_data = NULL; |
1110 | state->i2c_adap.dev.parent = &d->udev->dev; | 1075 | state->i2c_adap.dev.parent = &d->udev->dev; |
@@ -1166,7 +1131,7 @@ static struct qt1010_config af9015_qt1010_config = { | |||
1166 | 1131 | ||
1167 | static struct tda18271_config af9015_tda18271_config = { | 1132 | static struct tda18271_config af9015_tda18271_config = { |
1168 | .gate = TDA18271_GATE_DIGITAL, | 1133 | .gate = TDA18271_GATE_DIGITAL, |
1169 | .small_i2c = 1, | 1134 | .small_i2c = TDA18271_16_BYTE_CHUNK_INIT, |
1170 | }; | 1135 | }; |
1171 | 1136 | ||
1172 | static struct mxl5005s_config af9015_mxl5003_config = { | 1137 | static struct mxl5005s_config af9015_mxl5003_config = { |
@@ -1208,12 +1173,22 @@ static struct mc44s803_config af9015_mc44s803_config = { | |||
1208 | .dig_out = 1, | 1173 | .dig_out = 1, |
1209 | }; | 1174 | }; |
1210 | 1175 | ||
1176 | static struct tda18218_config af9015_tda18218_config = { | ||
1177 | .i2c_address = 0xc0, | ||
1178 | .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */ | ||
1179 | }; | ||
1180 | |||
1181 | static struct mxl5007t_config af9015_mxl5007t_config = { | ||
1182 | .xtal_freq_hz = MxL_XTAL_24_MHZ, | ||
1183 | .if_freq_hz = MxL_IF_4_57_MHZ, | ||
1184 | }; | ||
1185 | |||
1211 | static int af9015_tuner_attach(struct dvb_usb_adapter *adap) | 1186 | static int af9015_tuner_attach(struct dvb_usb_adapter *adap) |
1212 | { | 1187 | { |
1213 | struct af9015_state *state = adap->dev->priv; | 1188 | struct af9015_state *state = adap->dev->priv; |
1214 | struct i2c_adapter *i2c_adap; | 1189 | struct i2c_adapter *i2c_adap; |
1215 | int ret; | 1190 | int ret; |
1216 | deb_info("%s: \n", __func__); | 1191 | deb_info("%s:\n", __func__); |
1217 | 1192 | ||
1218 | /* select I2C adapter */ | 1193 | /* select I2C adapter */ |
1219 | if (adap->id == 0) | 1194 | if (adap->id == 0) |
@@ -1238,6 +1213,10 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) | |||
1238 | ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap, | 1213 | ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap, |
1239 | &af9015_tda18271_config) == NULL ? -ENODEV : 0; | 1214 | &af9015_tda18271_config) == NULL ? -ENODEV : 0; |
1240 | break; | 1215 | break; |
1216 | case AF9013_TUNER_TDA18218: | ||
1217 | ret = dvb_attach(tda18218_attach, adap->fe, i2c_adap, | ||
1218 | &af9015_tda18218_config) == NULL ? -ENODEV : 0; | ||
1219 | break; | ||
1241 | case AF9013_TUNER_MXL5003D: | 1220 | case AF9013_TUNER_MXL5003D: |
1242 | ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap, | 1221 | ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap, |
1243 | &af9015_mxl5003_config) == NULL ? -ENODEV : 0; | 1222 | &af9015_mxl5003_config) == NULL ? -ENODEV : 0; |
@@ -1255,6 +1234,10 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) | |||
1255 | ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap, | 1234 | ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap, |
1256 | &af9015_mc44s803_config) == NULL ? -ENODEV : 0; | 1235 | &af9015_mc44s803_config) == NULL ? -ENODEV : 0; |
1257 | break; | 1236 | break; |
1237 | case AF9013_TUNER_MXL5007T: | ||
1238 | ret = dvb_attach(mxl5007t_attach, adap->fe, i2c_adap, | ||
1239 | 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0; | ||
1240 | break; | ||
1258 | case AF9013_TUNER_UNKNOWN: | 1241 | case AF9013_TUNER_UNKNOWN: |
1259 | default: | 1242 | default: |
1260 | ret = -ENODEV; | 1243 | ret = -ENODEV; |
@@ -1300,10 +1283,16 @@ static struct usb_device_id af9015_usb_table[] = { | |||
1300 | /* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)}, | 1283 | /* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)}, |
1301 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)}, | 1284 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)}, |
1302 | {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)}, | 1285 | {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)}, |
1286 | {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)}, | ||
1287 | {USB_DEVICE(USB_VID_TERRATEC, | ||
1288 | USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)}, | ||
1289 | /* 35 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)}, | ||
1290 | {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)}, | ||
1303 | {0}, | 1291 | {0}, |
1304 | }; | 1292 | }; |
1305 | MODULE_DEVICE_TABLE(usb, af9015_usb_table); | 1293 | MODULE_DEVICE_TABLE(usb, af9015_usb_table); |
1306 | 1294 | ||
1295 | #define AF9015_RC_INTERVAL 500 | ||
1307 | static struct dvb_usb_device_properties af9015_properties[] = { | 1296 | static struct dvb_usb_device_properties af9015_properties[] = { |
1308 | { | 1297 | { |
1309 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1298 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
@@ -1354,14 +1343,19 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1354 | 1343 | ||
1355 | .identify_state = af9015_identify_state, | 1344 | .identify_state = af9015_identify_state, |
1356 | 1345 | ||
1357 | .rc.legacy = { | 1346 | .rc.core = { |
1347 | .protocol = IR_TYPE_NEC, | ||
1348 | .module_name = "af9015", | ||
1358 | .rc_query = af9015_rc_query, | 1349 | .rc_query = af9015_rc_query, |
1359 | .rc_interval = 150, | 1350 | .rc_interval = AF9015_RC_INTERVAL, |
1351 | .rc_props = { | ||
1352 | .allowed_protos = IR_TYPE_NEC, | ||
1353 | }, | ||
1360 | }, | 1354 | }, |
1361 | 1355 | ||
1362 | .i2c_algo = &af9015_i2c_algo, | 1356 | .i2c_algo = &af9015_i2c_algo, |
1363 | 1357 | ||
1364 | .num_device_descs = 9, /* max 9 */ | 1358 | .num_device_descs = 12, /* check max from dvb-usb.h */ |
1365 | .devices = { | 1359 | .devices = { |
1366 | { | 1360 | { |
1367 | .name = "Afatech AF9015 DVB-T USB2.0 stick", | 1361 | .name = "Afatech AF9015 DVB-T USB2.0 stick", |
@@ -1389,7 +1383,8 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1389 | { | 1383 | { |
1390 | .name = "DigitalNow TinyTwin DVB-T Receiver", | 1384 | .name = "DigitalNow TinyTwin DVB-T Receiver", |
1391 | .cold_ids = {&af9015_usb_table[5], | 1385 | .cold_ids = {&af9015_usb_table[5], |
1392 | &af9015_usb_table[28], NULL}, | 1386 | &af9015_usb_table[28], |
1387 | &af9015_usb_table[36], NULL}, | ||
1393 | .warm_ids = {NULL}, | 1388 | .warm_ids = {NULL}, |
1394 | }, | 1389 | }, |
1395 | { | 1390 | { |
@@ -1413,6 +1408,21 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1413 | .cold_ids = {&af9015_usb_table[9], NULL}, | 1408 | .cold_ids = {&af9015_usb_table[9], NULL}, |
1414 | .warm_ids = {NULL}, | 1409 | .warm_ids = {NULL}, |
1415 | }, | 1410 | }, |
1411 | { | ||
1412 | .name = "TerraTec Cinergy T Stick RC", | ||
1413 | .cold_ids = {&af9015_usb_table[33], NULL}, | ||
1414 | .warm_ids = {NULL}, | ||
1415 | }, | ||
1416 | { | ||
1417 | .name = "TerraTec Cinergy T Stick Dual RC", | ||
1418 | .cold_ids = {&af9015_usb_table[34], NULL}, | ||
1419 | .warm_ids = {NULL}, | ||
1420 | }, | ||
1421 | { | ||
1422 | .name = "AverMedia AVerTV Red HD+ (A850T)", | ||
1423 | .cold_ids = {&af9015_usb_table[35], NULL}, | ||
1424 | .warm_ids = {NULL}, | ||
1425 | }, | ||
1416 | } | 1426 | } |
1417 | }, { | 1427 | }, { |
1418 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1428 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
@@ -1463,14 +1473,19 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1463 | 1473 | ||
1464 | .identify_state = af9015_identify_state, | 1474 | .identify_state = af9015_identify_state, |
1465 | 1475 | ||
1466 | .rc.legacy = { | 1476 | .rc.core = { |
1477 | .protocol = IR_TYPE_NEC, | ||
1478 | .module_name = "af9015", | ||
1467 | .rc_query = af9015_rc_query, | 1479 | .rc_query = af9015_rc_query, |
1468 | .rc_interval = 150, | 1480 | .rc_interval = AF9015_RC_INTERVAL, |
1481 | .rc_props = { | ||
1482 | .allowed_protos = IR_TYPE_NEC, | ||
1483 | }, | ||
1469 | }, | 1484 | }, |
1470 | 1485 | ||
1471 | .i2c_algo = &af9015_i2c_algo, | 1486 | .i2c_algo = &af9015_i2c_algo, |
1472 | 1487 | ||
1473 | .num_device_descs = 9, /* max 9 */ | 1488 | .num_device_descs = 9, /* check max from dvb-usb.h */ |
1474 | .devices = { | 1489 | .devices = { |
1475 | { | 1490 | { |
1476 | .name = "Xtensions XD-380", | 1491 | .name = "Xtensions XD-380", |
@@ -1572,14 +1587,19 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1572 | 1587 | ||
1573 | .identify_state = af9015_identify_state, | 1588 | .identify_state = af9015_identify_state, |
1574 | 1589 | ||
1575 | .rc.legacy = { | 1590 | .rc.core = { |
1591 | .protocol = IR_TYPE_NEC, | ||
1592 | .module_name = "af9015", | ||
1576 | .rc_query = af9015_rc_query, | 1593 | .rc_query = af9015_rc_query, |
1577 | .rc_interval = 150, | 1594 | .rc_interval = AF9015_RC_INTERVAL, |
1595 | .rc_props = { | ||
1596 | .allowed_protos = IR_TYPE_NEC, | ||
1597 | }, | ||
1578 | }, | 1598 | }, |
1579 | 1599 | ||
1580 | .i2c_algo = &af9015_i2c_algo, | 1600 | .i2c_algo = &af9015_i2c_algo, |
1581 | 1601 | ||
1582 | .num_device_descs = 9, /* max 9 */ | 1602 | .num_device_descs = 9, /* check max from dvb-usb.h */ |
1583 | .devices = { | 1603 | .devices = { |
1584 | { | 1604 | { |
1585 | .name = "AverMedia AVerTV Volar GPS 805 (A805)", | 1605 | .name = "AverMedia AVerTV Volar GPS 805 (A805)", |
@@ -1672,7 +1692,7 @@ static int af9015_usb_probe(struct usb_interface *intf, | |||
1672 | static void af9015_i2c_exit(struct dvb_usb_device *d) | 1692 | static void af9015_i2c_exit(struct dvb_usb_device *d) |
1673 | { | 1693 | { |
1674 | struct af9015_state *state = d->priv; | 1694 | struct af9015_state *state = d->priv; |
1675 | deb_info("%s: \n", __func__); | 1695 | deb_info("%s:\n", __func__); |
1676 | 1696 | ||
1677 | /* remove 2nd I2C adapter */ | 1697 | /* remove 2nd I2C adapter */ |
1678 | if (d->state & DVB_USB_STATE_I2C) | 1698 | if (d->state & DVB_USB_STATE_I2C) |
@@ -1682,7 +1702,7 @@ static void af9015_i2c_exit(struct dvb_usb_device *d) | |||
1682 | static void af9015_usb_device_exit(struct usb_interface *intf) | 1702 | static void af9015_usb_device_exit(struct usb_interface *intf) |
1683 | { | 1703 | { |
1684 | struct dvb_usb_device *d = usb_get_intfdata(intf); | 1704 | struct dvb_usb_device *d = usb_get_intfdata(intf); |
1685 | deb_info("%s: \n", __func__); | 1705 | deb_info("%s:\n", __func__); |
1686 | 1706 | ||
1687 | /* remove 2nd I2C adapter */ | 1707 | /* remove 2nd I2C adapter */ |
1688 | if (d != NULL && d->desc != NULL) | 1708 | if (d != NULL && d->desc != NULL) |