diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb/af9015.c')
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9015.c | 433 |
1 files changed, 234 insertions, 199 deletions
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index ea1ed3b4592a..100ebc37e99e 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)) { |
@@ -471,6 +479,7 @@ static int af9015_init_endpoint(struct dvb_usb_device *d) | |||
471 | ret = af9015_set_reg_bit(d, 0xd50b, 0); | 479 | ret = af9015_set_reg_bit(d, 0xd50b, 0); |
472 | else | 480 | else |
473 | ret = af9015_clear_reg_bit(d, 0xd50b, 0); | 481 | ret = af9015_clear_reg_bit(d, 0xd50b, 0); |
482 | |||
474 | error: | 483 | error: |
475 | if (ret) | 484 | if (ret) |
476 | err("endpoint init failed:%d", ret); | 485 | err("endpoint init failed:%d", ret); |
@@ -494,7 +503,8 @@ static int af9015_copy_firmware(struct dvb_usb_device *d) | |||
494 | /* wait 2nd demodulator ready */ | 503 | /* wait 2nd demodulator ready */ |
495 | msleep(100); | 504 | msleep(100); |
496 | 505 | ||
497 | ret = af9015_read_reg_i2c(d, 0x3a, 0x98be, &val); | 506 | ret = af9015_read_reg_i2c(d, |
507 | af9015_af9013_config[1].demod_address, 0x98be, &val); | ||
498 | if (ret) | 508 | if (ret) |
499 | goto error; | 509 | goto error; |
500 | else | 510 | else |
@@ -597,47 +607,17 @@ free: | |||
597 | return ret; | 607 | return ret; |
598 | } | 608 | } |
599 | 609 | ||
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) | 610 | static int af9015_init(struct dvb_usb_device *d) |
632 | { | 611 | { |
633 | int ret; | 612 | int ret; |
634 | deb_info("%s:\n", __func__); | 613 | deb_info("%s:\n", __func__); |
635 | 614 | ||
636 | ret = af9015_init_endpoint(d); | 615 | /* init RC canary */ |
616 | ret = af9015_write_reg(d, 0x98e9, 0xff); | ||
637 | if (ret) | 617 | if (ret) |
638 | goto error; | 618 | goto error; |
639 | 619 | ||
640 | ret = af9015_download_ir_table(d); | 620 | ret = af9015_init_endpoint(d); |
641 | if (ret) | 621 | if (ret) |
642 | goto error; | 622 | goto error; |
643 | 623 | ||
@@ -685,9 +665,8 @@ error: | |||
685 | static int af9015_download_firmware(struct usb_device *udev, | 665 | static int af9015_download_firmware(struct usb_device *udev, |
686 | const struct firmware *fw) | 666 | const struct firmware *fw) |
687 | { | 667 | { |
688 | int i, len, packets, remainder, ret; | 668 | int i, len, remaining, ret; |
689 | struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; | 669 | struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; |
690 | u16 addr = 0x5100; /* firmware start address */ | ||
691 | u16 checksum = 0; | 670 | u16 checksum = 0; |
692 | 671 | ||
693 | deb_info("%s:\n", __func__); | 672 | deb_info("%s:\n", __func__); |
@@ -699,24 +678,20 @@ static int af9015_download_firmware(struct usb_device *udev, | |||
699 | af9015_config.firmware_size = fw->size; | 678 | af9015_config.firmware_size = fw->size; |
700 | af9015_config.firmware_checksum = checksum; | 679 | af9015_config.firmware_checksum = checksum; |
701 | 680 | ||
702 | #define FW_PACKET_MAX_DATA 55 | 681 | #define FW_ADDR 0x5100 /* firmware start address */ |
703 | 682 | #define LEN_MAX 55 /* max packet size */ | |
704 | packets = fw->size / FW_PACKET_MAX_DATA; | 683 | for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) { |
705 | remainder = fw->size % FW_PACKET_MAX_DATA; | 684 | len = remaining; |
706 | len = FW_PACKET_MAX_DATA; | 685 | if (len > LEN_MAX) |
707 | for (i = 0; i <= packets; i++) { | 686 | len = LEN_MAX; |
708 | if (i == packets) /* set size of the last packet */ | ||
709 | len = remainder; | ||
710 | 687 | ||
711 | req.data_len = len; | 688 | req.data_len = len; |
712 | req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); | 689 | req.data = (u8 *) &fw->data[fw->size - remaining]; |
713 | req.addr = addr; | 690 | req.addr = FW_ADDR + fw->size - remaining; |
714 | addr += FW_PACKET_MAX_DATA; | ||
715 | 691 | ||
716 | ret = af9015_rw_udev(udev, &req); | 692 | ret = af9015_rw_udev(udev, &req); |
717 | if (ret) { | 693 | if (ret) { |
718 | err("firmware download failed at packet %d with " \ | 694 | err("firmware download failed:%d", ret); |
719 | "code %d", i, ret); | ||
720 | goto error; | 695 | goto error; |
721 | } | 696 | } |
722 | } | 697 | } |
@@ -733,125 +708,104 @@ error: | |||
733 | return ret; | 708 | return ret; |
734 | } | 709 | } |
735 | 710 | ||
736 | struct af9015_setup { | 711 | struct af9015_rc_setup { |
737 | unsigned int id; | 712 | unsigned int id; |
738 | struct ir_scancode *rc_key_map; | 713 | char *rc_codes; |
739 | unsigned int rc_key_map_size; | ||
740 | u8 *ir_table; | ||
741 | unsigned int ir_table_size; | ||
742 | }; | 714 | }; |
743 | 715 | ||
744 | static const struct af9015_setup *af9015_setup_match(unsigned int id, | 716 | static char *af9015_rc_setup_match(unsigned int id, |
745 | const struct af9015_setup *table) | 717 | const struct af9015_rc_setup *table) |
746 | { | 718 | { |
747 | for (; table->rc_key_map; table++) | 719 | for (; table->rc_codes; table++) |
748 | if (table->id == id) | 720 | if (table->id == id) |
749 | return table; | 721 | return table->rc_codes; |
750 | return NULL; | 722 | return NULL; |
751 | } | 723 | } |
752 | 724 | ||
753 | static const struct af9015_setup af9015_setup_modparam[] = { | 725 | static const struct af9015_rc_setup af9015_rc_setup_modparam[] = { |
754 | { AF9015_REMOTE_A_LINK_DTU_M, | 726 | { 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), | 727 | { 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) }, | 728 | { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND }, |
757 | { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, | 729 | { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE }, |
758 | ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi), | 730 | { 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 | { } | 731 | { } |
770 | }; | 732 | }; |
771 | 733 | ||
772 | /* don't add new entries here anymore, use hashes instead */ | 734 | static const struct af9015_rc_setup af9015_rc_setup_hashes[] = { |
773 | static const struct af9015_setup af9015_setup_usbids[] = { | 735 | { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II }, |
774 | { USB_VID_LEADTEK, | 736 | { 0xa3703d00, RC_MAP_ALINK_DTU_M }, |
775 | ir_codes_af9015_table_leadtek, ARRAY_SIZE(ir_codes_af9015_table_leadtek), | 737 | { 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 | { } | 738 | { } |
790 | }; | 739 | }; |
791 | 740 | ||
792 | static const struct af9015_setup af9015_setup_hashes[] = { | 741 | static const struct af9015_rc_setup af9015_rc_setup_usbids[] = { |
793 | { 0xb8feb708, | 742 | { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_RC, |
794 | ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi), | 743 | RC_MAP_TERRATEC_SLIM_2 }, |
795 | af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) }, | 744 | { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, |
796 | { 0xa3703d00, | 745 | RC_MAP_TERRATEC_SLIM }, |
797 | ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link), | 746 | { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700, |
798 | af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) }, | 747 | RC_MAP_AZUREWAVE_AD_TU700 }, |
799 | { 0x9b7dc64e, | 748 | { (USB_VID_VISIONPLUS << 16) + USB_PID_TINYTWIN, |
800 | ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv), | 749 | RC_MAP_AZUREWAVE_AD_TU700 }, |
801 | af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) }, | 750 | { (USB_VID_MSI_2 << 16) + USB_PID_MSI_DIGI_VOX_MINI_III, |
751 | RC_MAP_MSI_DIGIVOX_III }, | ||
752 | { (USB_VID_LEADTEK << 16) + USB_PID_WINFAST_DTV_DONGLE_GOLD, | ||
753 | RC_MAP_LEADTEK_Y04G0051 }, | ||
754 | { (USB_VID_AVERMEDIA << 16) + USB_PID_AVERMEDIA_VOLAR_X, | ||
755 | RC_MAP_AVERMEDIA_M135A }, | ||
756 | { (USB_VID_AFATECH << 16) + USB_PID_TREKSTOR_DVBT, | ||
757 | RC_MAP_TREKSTOR }, | ||
758 | { (USB_VID_KWORLD_2 << 16) + USB_PID_TINYTWIN_2, | ||
759 | RC_MAP_DIGITALNOW_TINYTWIN }, | ||
760 | { (USB_VID_GTEK << 16) + USB_PID_TINYTWIN_3, | ||
761 | RC_MAP_DIGITALNOW_TINYTWIN }, | ||
802 | { } | 762 | { } |
803 | }; | 763 | }; |
804 | 764 | ||
805 | static void af9015_set_remote_config(struct usb_device *udev, | 765 | static void af9015_set_remote_config(struct usb_device *udev, |
806 | struct dvb_usb_device_properties *props) | 766 | struct dvb_usb_device_properties *props) |
807 | { | 767 | { |
808 | const struct af9015_setup *table = NULL; | 768 | u16 vid = le16_to_cpu(udev->descriptor.idVendor); |
809 | 769 | u16 pid = le16_to_cpu(udev->descriptor.idProduct); | |
810 | if (dvb_usb_af9015_remote) { | 770 | |
811 | /* load remote defined as module param */ | 771 | /* try to load remote based module param */ |
812 | table = af9015_setup_match(dvb_usb_af9015_remote, | 772 | props->rc.core.rc_codes = af9015_rc_setup_match( |
813 | af9015_setup_modparam); | 773 | dvb_usb_af9015_remote, af9015_rc_setup_modparam); |
814 | } else { | 774 | |
815 | u16 vendor = le16_to_cpu(udev->descriptor.idVendor); | 775 | /* try to load remote based eeprom hash */ |
816 | 776 | if (!props->rc.core.rc_codes) | |
817 | table = af9015_setup_match(af9015_config.eeprom_sum, | 777 | props->rc.core.rc_codes = af9015_rc_setup_match( |
818 | af9015_setup_hashes); | 778 | af9015_config.eeprom_sum, af9015_rc_setup_hashes); |
819 | 779 | ||
820 | if (!table && vendor == USB_VID_AFATECH) { | 780 | /* try to load remote based USB ID */ |
821 | /* Check USB manufacturer and product strings and try | 781 | if (!props->rc.core.rc_codes) |
822 | to determine correct remote in case of chip vendor | 782 | props->rc.core.rc_codes = af9015_rc_setup_match( |
823 | reference IDs are used. | 783 | (vid << 16) + pid, af9015_rc_setup_usbids); |
824 | DO NOT ADD ANYTHING NEW HERE. Use hashes instead. | 784 | |
825 | */ | 785 | /* try to load remote based USB iManufacturer string */ |
826 | char manufacturer[10]; | 786 | if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) { |
827 | memset(manufacturer, 0, sizeof(manufacturer)); | 787 | /* Check USB manufacturer and product strings and try |
828 | usb_string(udev, udev->descriptor.iManufacturer, | 788 | to determine correct remote in case of chip vendor |
829 | manufacturer, sizeof(manufacturer)); | 789 | reference IDs are used. |
830 | if (!strcmp("MSI", manufacturer)) { | 790 | DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */ |
831 | /* iManufacturer 1 MSI | 791 | char manufacturer[10]; |
832 | iProduct 2 MSI K-VOX */ | 792 | memset(manufacturer, 0, sizeof(manufacturer)); |
833 | table = af9015_setup_match( | 793 | usb_string(udev, udev->descriptor.iManufacturer, |
834 | AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, | 794 | manufacturer, sizeof(manufacturer)); |
835 | af9015_setup_modparam); | 795 | if (!strcmp("MSI", manufacturer)) { |
836 | } else if (udev->descriptor.idProduct == | 796 | /* iManufacturer 1 MSI |
837 | cpu_to_le16(USB_PID_TREKSTOR_DVBT)) { | 797 | iProduct 2 MSI K-VOX */ |
838 | table = &(const struct af9015_setup){ 0, | 798 | props->rc.core.rc_codes = af9015_rc_setup_match( |
839 | ir_codes_af9015_table_trekstor, | 799 | AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, |
840 | ARRAY_SIZE(ir_codes_af9015_table_trekstor), | 800 | af9015_rc_setup_modparam); |
841 | af9015_ir_table_trekstor, | 801 | } |
842 | ARRAY_SIZE(af9015_ir_table_trekstor) | ||
843 | }; | ||
844 | } | ||
845 | } else if (!table) | ||
846 | table = af9015_setup_match(vendor, af9015_setup_usbids); | ||
847 | } | 802 | } |
848 | 803 | ||
849 | if (table) { | 804 | /* finally load "empty" just for leaving IR receiver enabled */ |
850 | props->rc.legacy.rc_key_map = table->rc_key_map; | 805 | if (!props->rc.core.rc_codes) |
851 | props->rc.legacy.rc_key_map_size = table->rc_key_map_size; | 806 | props->rc.core.rc_codes = RC_MAP_EMPTY; |
852 | af9015_config.ir_table = table->ir_table; | 807 | |
853 | af9015_config.ir_table_size = table->ir_table_size; | 808 | return; |
854 | } | ||
855 | } | 809 | } |
856 | 810 | ||
857 | static int af9015_read_config(struct usb_device *udev) | 811 | static int af9015_read_config(struct usb_device *udev) |
@@ -877,10 +831,9 @@ static int af9015_read_config(struct usb_device *udev) | |||
877 | 831 | ||
878 | deb_info("%s: IR mode:%d\n", __func__, val); | 832 | deb_info("%s: IR mode:%d\n", __func__, val); |
879 | for (i = 0; i < af9015_properties_count; i++) { | 833 | for (i = 0; i < af9015_properties_count; i++) { |
880 | if (val == AF9015_IR_MODE_DISABLED) { | 834 | if (val == AF9015_IR_MODE_DISABLED) |
881 | af9015_properties[i].rc.legacy.rc_key_map = NULL; | 835 | af9015_properties[i].rc.core.rc_codes = NULL; |
882 | af9015_properties[i].rc.legacy.rc_key_map_size = 0; | 836 | else |
883 | } else | ||
884 | af9015_set_remote_config(udev, &af9015_properties[i]); | 837 | af9015_set_remote_config(udev, &af9015_properties[i]); |
885 | } | 838 | } |
886 | 839 | ||
@@ -992,20 +945,19 @@ static int af9015_read_config(struct usb_device *udev) | |||
992 | case AF9013_TUNER_MT2060_2: | 945 | case AF9013_TUNER_MT2060_2: |
993 | case AF9013_TUNER_TDA18271: | 946 | case AF9013_TUNER_TDA18271: |
994 | case AF9013_TUNER_QT1010A: | 947 | case AF9013_TUNER_QT1010A: |
948 | case AF9013_TUNER_TDA18218: | ||
995 | af9015_af9013_config[i].rf_spec_inv = 1; | 949 | af9015_af9013_config[i].rf_spec_inv = 1; |
996 | break; | 950 | break; |
997 | case AF9013_TUNER_MXL5003D: | 951 | case AF9013_TUNER_MXL5003D: |
998 | case AF9013_TUNER_MXL5005D: | 952 | case AF9013_TUNER_MXL5005D: |
999 | case AF9013_TUNER_MXL5005R: | 953 | case AF9013_TUNER_MXL5005R: |
954 | case AF9013_TUNER_MXL5007T: | ||
1000 | af9015_af9013_config[i].rf_spec_inv = 0; | 955 | af9015_af9013_config[i].rf_spec_inv = 0; |
1001 | break; | 956 | break; |
1002 | case AF9013_TUNER_MC44S803: | 957 | case AF9013_TUNER_MC44S803: |
1003 | af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; | 958 | af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; |
1004 | af9015_af9013_config[i].rf_spec_inv = 1; | 959 | af9015_af9013_config[i].rf_spec_inv = 1; |
1005 | break; | 960 | break; |
1006 | case AF9013_TUNER_TDA18218: | ||
1007 | warn("tuner NXP TDA18218 not supported yet"); | ||
1008 | return -ENODEV; | ||
1009 | default: | 961 | default: |
1010 | warn("tuner id:%d not supported, please report!", val); | 962 | warn("tuner id:%d not supported, please report!", val); |
1011 | return -ENODEV; | 963 | return -ENODEV; |
@@ -1020,9 +972,13 @@ error: | |||
1020 | err("eeprom read failed:%d", ret); | 972 | err("eeprom read failed:%d", ret); |
1021 | 973 | ||
1022 | /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM | 974 | /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM |
1023 | content :-( Override some wrong values here. */ | 975 | content :-( Override some wrong values here. Ditto for the |
976 | AVerTV Red HD+ (A850T) device. */ | ||
1024 | if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA && | 977 | if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA && |
1025 | le16_to_cpu(udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) { | 978 | ((le16_to_cpu(udev->descriptor.idProduct) == |
979 | USB_PID_AVERMEDIA_A850) || | ||
980 | (le16_to_cpu(udev->descriptor.idProduct) == | ||
981 | USB_PID_AVERMEDIA_A850T))) { | ||
1026 | deb_info("%s: AverMedia A850: overriding config\n", __func__); | 982 | deb_info("%s: AverMedia A850: overriding config\n", __func__); |
1027 | /* disable dual mode */ | 983 | /* disable dual mode */ |
1028 | af9015_config.dual_mode = 0; | 984 | af9015_config.dual_mode = 0; |
@@ -1059,36 +1015,71 @@ static int af9015_identify_state(struct usb_device *udev, | |||
1059 | return ret; | 1015 | return ret; |
1060 | } | 1016 | } |
1061 | 1017 | ||
1062 | static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 1018 | static int af9015_rc_query(struct dvb_usb_device *d) |
1063 | { | 1019 | { |
1064 | u8 buf[8]; | 1020 | struct af9015_state *priv = d->priv; |
1065 | struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf}; | 1021 | int ret; |
1066 | struct ir_scancode *keymap = d->props.rc.legacy.rc_key_map; | 1022 | u8 buf[17]; |
1067 | int i, ret; | ||
1068 | |||
1069 | memset(buf, 0, sizeof(buf)); | ||
1070 | 1023 | ||
1071 | ret = af9015_ctrl_msg(d, &req); | 1024 | /* read registers needed to detect remote controller code */ |
1025 | ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); | ||
1072 | if (ret) | 1026 | if (ret) |
1027 | goto error; | ||
1028 | |||
1029 | /* If any of these are non-zero, assume invalid data */ | ||
1030 | if (buf[1] || buf[2] || buf[3]) | ||
1073 | return ret; | 1031 | return ret; |
1074 | 1032 | ||
1075 | *event = 0; | 1033 | /* Check for repeat of previous code */ |
1076 | *state = REMOTE_NO_KEY_PRESSED; | 1034 | if ((priv->rc_repeat != buf[6] || buf[0]) && |
1035 | !memcmp(&buf[12], priv->rc_last, 4)) { | ||
1036 | deb_rc("%s: key repeated\n", __func__); | ||
1037 | rc_keydown(d->rc_dev, priv->rc_keycode, 0); | ||
1038 | priv->rc_repeat = buf[6]; | ||
1039 | return ret; | ||
1040 | } | ||
1077 | 1041 | ||
1078 | for (i = 0; i < d->props.rc.legacy.rc_key_map_size; i++) { | 1042 | /* Only process key if canary killed */ |
1079 | if (!buf[1] && rc5_custom(&keymap[i]) == buf[0] && | 1043 | if (buf[16] != 0xff && buf[0] != 0x01) { |
1080 | rc5_data(&keymap[i]) == buf[2]) { | 1044 | deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, |
1081 | *event = keymap[i].keycode; | 1045 | buf[12], buf[13], buf[14], buf[15]); |
1082 | *state = REMOTE_KEY_PRESSED; | 1046 | |
1083 | break; | 1047 | /* Reset the canary */ |
1048 | ret = af9015_write_reg(d, 0x98e9, 0xff); | ||
1049 | if (ret) | ||
1050 | goto error; | ||
1051 | |||
1052 | /* Remember this key */ | ||
1053 | memcpy(priv->rc_last, &buf[12], 4); | ||
1054 | if (buf[14] == (u8) ~buf[15]) { | ||
1055 | if (buf[12] == (u8) ~buf[13]) { | ||
1056 | /* NEC */ | ||
1057 | priv->rc_keycode = buf[12] << 8 | buf[14]; | ||
1058 | } else { | ||
1059 | /* NEC extended*/ | ||
1060 | priv->rc_keycode = buf[12] << 16 | | ||
1061 | buf[13] << 8 | buf[14]; | ||
1062 | } | ||
1063 | } else { | ||
1064 | /* 32 bit NEC */ | ||
1065 | priv->rc_keycode = buf[12] << 24 | buf[13] << 16 | | ||
1066 | buf[14] << 8 | buf[15]; | ||
1084 | } | 1067 | } |
1068 | rc_keydown(d->rc_dev, priv->rc_keycode, 0); | ||
1069 | } else { | ||
1070 | deb_rc("%s: no key press\n", __func__); | ||
1071 | /* Invalidate last keypress */ | ||
1072 | /* Not really needed, but helps with debug */ | ||
1073 | priv->rc_last[2] = priv->rc_last[3]; | ||
1085 | } | 1074 | } |
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 | 1075 | ||
1091 | return 0; | 1076 | priv->rc_repeat = buf[6]; |
1077 | |||
1078 | error: | ||
1079 | if (ret) | ||
1080 | err("%s: failed:%d", __func__, ret); | ||
1081 | |||
1082 | return ret; | ||
1092 | } | 1083 | } |
1093 | 1084 | ||
1094 | /* init 2nd I2C adapter */ | 1085 | /* init 2nd I2C adapter */ |
@@ -1100,11 +1091,6 @@ static int af9015_i2c_init(struct dvb_usb_device *d) | |||
1100 | 1091 | ||
1101 | strncpy(state->i2c_adap.name, d->desc->name, | 1092 | strncpy(state->i2c_adap.name, d->desc->name, |
1102 | sizeof(state->i2c_adap.name)); | 1093 | 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; | 1094 | state->i2c_adap.algo = d->props.i2c_algo; |
1109 | state->i2c_adap.algo_data = NULL; | 1095 | state->i2c_adap.algo_data = NULL; |
1110 | state->i2c_adap.dev.parent = &d->udev->dev; | 1096 | state->i2c_adap.dev.parent = &d->udev->dev; |
@@ -1166,7 +1152,7 @@ static struct qt1010_config af9015_qt1010_config = { | |||
1166 | 1152 | ||
1167 | static struct tda18271_config af9015_tda18271_config = { | 1153 | static struct tda18271_config af9015_tda18271_config = { |
1168 | .gate = TDA18271_GATE_DIGITAL, | 1154 | .gate = TDA18271_GATE_DIGITAL, |
1169 | .small_i2c = 1, | 1155 | .small_i2c = TDA18271_16_BYTE_CHUNK_INIT, |
1170 | }; | 1156 | }; |
1171 | 1157 | ||
1172 | static struct mxl5005s_config af9015_mxl5003_config = { | 1158 | static struct mxl5005s_config af9015_mxl5003_config = { |
@@ -1208,12 +1194,22 @@ static struct mc44s803_config af9015_mc44s803_config = { | |||
1208 | .dig_out = 1, | 1194 | .dig_out = 1, |
1209 | }; | 1195 | }; |
1210 | 1196 | ||
1197 | static struct tda18218_config af9015_tda18218_config = { | ||
1198 | .i2c_address = 0xc0, | ||
1199 | .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */ | ||
1200 | }; | ||
1201 | |||
1202 | static struct mxl5007t_config af9015_mxl5007t_config = { | ||
1203 | .xtal_freq_hz = MxL_XTAL_24_MHZ, | ||
1204 | .if_freq_hz = MxL_IF_4_57_MHZ, | ||
1205 | }; | ||
1206 | |||
1211 | static int af9015_tuner_attach(struct dvb_usb_adapter *adap) | 1207 | static int af9015_tuner_attach(struct dvb_usb_adapter *adap) |
1212 | { | 1208 | { |
1213 | struct af9015_state *state = adap->dev->priv; | 1209 | struct af9015_state *state = adap->dev->priv; |
1214 | struct i2c_adapter *i2c_adap; | 1210 | struct i2c_adapter *i2c_adap; |
1215 | int ret; | 1211 | int ret; |
1216 | deb_info("%s: \n", __func__); | 1212 | deb_info("%s:\n", __func__); |
1217 | 1213 | ||
1218 | /* select I2C adapter */ | 1214 | /* select I2C adapter */ |
1219 | if (adap->id == 0) | 1215 | if (adap->id == 0) |
@@ -1238,6 +1234,10 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) | |||
1238 | ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap, | 1234 | ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap, |
1239 | &af9015_tda18271_config) == NULL ? -ENODEV : 0; | 1235 | &af9015_tda18271_config) == NULL ? -ENODEV : 0; |
1240 | break; | 1236 | break; |
1237 | case AF9013_TUNER_TDA18218: | ||
1238 | ret = dvb_attach(tda18218_attach, adap->fe, i2c_adap, | ||
1239 | &af9015_tda18218_config) == NULL ? -ENODEV : 0; | ||
1240 | break; | ||
1241 | case AF9013_TUNER_MXL5003D: | 1241 | case AF9013_TUNER_MXL5003D: |
1242 | ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap, | 1242 | ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap, |
1243 | &af9015_mxl5003_config) == NULL ? -ENODEV : 0; | 1243 | &af9015_mxl5003_config) == NULL ? -ENODEV : 0; |
@@ -1255,6 +1255,10 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) | |||
1255 | ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap, | 1255 | ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap, |
1256 | &af9015_mc44s803_config) == NULL ? -ENODEV : 0; | 1256 | &af9015_mc44s803_config) == NULL ? -ENODEV : 0; |
1257 | break; | 1257 | break; |
1258 | case AF9013_TUNER_MXL5007T: | ||
1259 | ret = dvb_attach(mxl5007t_attach, adap->fe, i2c_adap, | ||
1260 | 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0; | ||
1261 | break; | ||
1258 | case AF9013_TUNER_UNKNOWN: | 1262 | case AF9013_TUNER_UNKNOWN: |
1259 | default: | 1263 | default: |
1260 | ret = -ENODEV; | 1264 | ret = -ENODEV; |
@@ -1300,10 +1304,16 @@ static struct usb_device_id af9015_usb_table[] = { | |||
1300 | /* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)}, | 1304 | /* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)}, |
1301 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)}, | 1305 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)}, |
1302 | {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)}, | 1306 | {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)}, |
1307 | {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)}, | ||
1308 | {USB_DEVICE(USB_VID_TERRATEC, | ||
1309 | USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)}, | ||
1310 | /* 35 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)}, | ||
1311 | {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)}, | ||
1303 | {0}, | 1312 | {0}, |
1304 | }; | 1313 | }; |
1305 | MODULE_DEVICE_TABLE(usb, af9015_usb_table); | 1314 | MODULE_DEVICE_TABLE(usb, af9015_usb_table); |
1306 | 1315 | ||
1316 | #define AF9015_RC_INTERVAL 500 | ||
1307 | static struct dvb_usb_device_properties af9015_properties[] = { | 1317 | static struct dvb_usb_device_properties af9015_properties[] = { |
1308 | { | 1318 | { |
1309 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1319 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
@@ -1354,14 +1364,17 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1354 | 1364 | ||
1355 | .identify_state = af9015_identify_state, | 1365 | .identify_state = af9015_identify_state, |
1356 | 1366 | ||
1357 | .rc.legacy = { | 1367 | .rc.core = { |
1368 | .protocol = RC_TYPE_NEC, | ||
1369 | .module_name = "af9015", | ||
1358 | .rc_query = af9015_rc_query, | 1370 | .rc_query = af9015_rc_query, |
1359 | .rc_interval = 150, | 1371 | .rc_interval = AF9015_RC_INTERVAL, |
1372 | .allowed_protos = RC_TYPE_NEC, | ||
1360 | }, | 1373 | }, |
1361 | 1374 | ||
1362 | .i2c_algo = &af9015_i2c_algo, | 1375 | .i2c_algo = &af9015_i2c_algo, |
1363 | 1376 | ||
1364 | .num_device_descs = 9, /* max 9 */ | 1377 | .num_device_descs = 12, /* check max from dvb-usb.h */ |
1365 | .devices = { | 1378 | .devices = { |
1366 | { | 1379 | { |
1367 | .name = "Afatech AF9015 DVB-T USB2.0 stick", | 1380 | .name = "Afatech AF9015 DVB-T USB2.0 stick", |
@@ -1389,7 +1402,8 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1389 | { | 1402 | { |
1390 | .name = "DigitalNow TinyTwin DVB-T Receiver", | 1403 | .name = "DigitalNow TinyTwin DVB-T Receiver", |
1391 | .cold_ids = {&af9015_usb_table[5], | 1404 | .cold_ids = {&af9015_usb_table[5], |
1392 | &af9015_usb_table[28], NULL}, | 1405 | &af9015_usb_table[28], |
1406 | &af9015_usb_table[36], NULL}, | ||
1393 | .warm_ids = {NULL}, | 1407 | .warm_ids = {NULL}, |
1394 | }, | 1408 | }, |
1395 | { | 1409 | { |
@@ -1413,6 +1427,21 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1413 | .cold_ids = {&af9015_usb_table[9], NULL}, | 1427 | .cold_ids = {&af9015_usb_table[9], NULL}, |
1414 | .warm_ids = {NULL}, | 1428 | .warm_ids = {NULL}, |
1415 | }, | 1429 | }, |
1430 | { | ||
1431 | .name = "TerraTec Cinergy T Stick RC", | ||
1432 | .cold_ids = {&af9015_usb_table[33], NULL}, | ||
1433 | .warm_ids = {NULL}, | ||
1434 | }, | ||
1435 | { | ||
1436 | .name = "TerraTec Cinergy T Stick Dual RC", | ||
1437 | .cold_ids = {&af9015_usb_table[34], NULL}, | ||
1438 | .warm_ids = {NULL}, | ||
1439 | }, | ||
1440 | { | ||
1441 | .name = "AverMedia AVerTV Red HD+ (A850T)", | ||
1442 | .cold_ids = {&af9015_usb_table[35], NULL}, | ||
1443 | .warm_ids = {NULL}, | ||
1444 | }, | ||
1416 | } | 1445 | } |
1417 | }, { | 1446 | }, { |
1418 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1447 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
@@ -1463,14 +1492,17 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1463 | 1492 | ||
1464 | .identify_state = af9015_identify_state, | 1493 | .identify_state = af9015_identify_state, |
1465 | 1494 | ||
1466 | .rc.legacy = { | 1495 | .rc.core = { |
1496 | .protocol = RC_TYPE_NEC, | ||
1497 | .module_name = "af9015", | ||
1467 | .rc_query = af9015_rc_query, | 1498 | .rc_query = af9015_rc_query, |
1468 | .rc_interval = 150, | 1499 | .rc_interval = AF9015_RC_INTERVAL, |
1500 | .allowed_protos = RC_TYPE_NEC, | ||
1469 | }, | 1501 | }, |
1470 | 1502 | ||
1471 | .i2c_algo = &af9015_i2c_algo, | 1503 | .i2c_algo = &af9015_i2c_algo, |
1472 | 1504 | ||
1473 | .num_device_descs = 9, /* max 9 */ | 1505 | .num_device_descs = 9, /* check max from dvb-usb.h */ |
1474 | .devices = { | 1506 | .devices = { |
1475 | { | 1507 | { |
1476 | .name = "Xtensions XD-380", | 1508 | .name = "Xtensions XD-380", |
@@ -1572,14 +1604,17 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1572 | 1604 | ||
1573 | .identify_state = af9015_identify_state, | 1605 | .identify_state = af9015_identify_state, |
1574 | 1606 | ||
1575 | .rc.legacy = { | 1607 | .rc.core = { |
1608 | .protocol = RC_TYPE_NEC, | ||
1609 | .module_name = "af9015", | ||
1576 | .rc_query = af9015_rc_query, | 1610 | .rc_query = af9015_rc_query, |
1577 | .rc_interval = 150, | 1611 | .rc_interval = AF9015_RC_INTERVAL, |
1612 | .allowed_protos = RC_TYPE_NEC, | ||
1578 | }, | 1613 | }, |
1579 | 1614 | ||
1580 | .i2c_algo = &af9015_i2c_algo, | 1615 | .i2c_algo = &af9015_i2c_algo, |
1581 | 1616 | ||
1582 | .num_device_descs = 9, /* max 9 */ | 1617 | .num_device_descs = 9, /* check max from dvb-usb.h */ |
1583 | .devices = { | 1618 | .devices = { |
1584 | { | 1619 | { |
1585 | .name = "AverMedia AVerTV Volar GPS 805 (A805)", | 1620 | .name = "AverMedia AVerTV Volar GPS 805 (A805)", |
@@ -1672,7 +1707,7 @@ static int af9015_usb_probe(struct usb_interface *intf, | |||
1672 | static void af9015_i2c_exit(struct dvb_usb_device *d) | 1707 | static void af9015_i2c_exit(struct dvb_usb_device *d) |
1673 | { | 1708 | { |
1674 | struct af9015_state *state = d->priv; | 1709 | struct af9015_state *state = d->priv; |
1675 | deb_info("%s: \n", __func__); | 1710 | deb_info("%s:\n", __func__); |
1676 | 1711 | ||
1677 | /* remove 2nd I2C adapter */ | 1712 | /* remove 2nd I2C adapter */ |
1678 | if (d->state & DVB_USB_STATE_I2C) | 1713 | if (d->state & DVB_USB_STATE_I2C) |
@@ -1682,7 +1717,7 @@ static void af9015_i2c_exit(struct dvb_usb_device *d) | |||
1682 | static void af9015_usb_device_exit(struct usb_interface *intf) | 1717 | static void af9015_usb_device_exit(struct usb_interface *intf) |
1683 | { | 1718 | { |
1684 | struct dvb_usb_device *d = usb_get_intfdata(intf); | 1719 | struct dvb_usb_device *d = usb_get_intfdata(intf); |
1685 | deb_info("%s: \n", __func__); | 1720 | deb_info("%s:\n", __func__); |
1686 | 1721 | ||
1687 | /* remove 2nd I2C adapter */ | 1722 | /* remove 2nd I2C adapter */ |
1688 | if (d != NULL && d->desc != NULL) | 1723 | if (d != NULL && d->desc != NULL) |