diff options
Diffstat (limited to 'drivers/media/dvb/bt8xx/dst.c')
-rw-r--r-- | drivers/media/dvb/bt8xx/dst.c | 136 |
1 files changed, 104 insertions, 32 deletions
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index b3c9d7327ac1..8977c7a313df 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -690,8 +690,8 @@ struct dst_types dst_tlist[] = { | |||
690 | .device_id = "DTT-CI", | 690 | .device_id = "DTT-CI", |
691 | .offset = 1, | 691 | .offset = 1, |
692 | .dst_type = DST_TYPE_IS_TERR, | 692 | .dst_type = DST_TYPE_IS_TERR, |
693 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, | 693 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE, |
694 | .dst_feature = 0 | 694 | .dst_feature = DST_TYPE_HAS_CA |
695 | }, | 695 | }, |
696 | 696 | ||
697 | { | 697 | { |
@@ -796,6 +796,56 @@ static int dst_get_vendor(struct dst_state *state) | |||
796 | return 0; | 796 | return 0; |
797 | } | 797 | } |
798 | 798 | ||
799 | static int dst_get_tuner_info(struct dst_state *state) | ||
800 | { | ||
801 | u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
802 | u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
803 | |||
804 | get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); | ||
805 | get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); | ||
806 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | ||
807 | if (dst_command(state, get_tuner_2, 8) < 0) { | ||
808 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | ||
809 | return -1; | ||
810 | } | ||
811 | } else { | ||
812 | if (dst_command(state, get_tuner_1, 8) < 0) { | ||
813 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | ||
814 | return -1; | ||
815 | } | ||
816 | } | ||
817 | memset(&state->board_info, '\0', 8); | ||
818 | memcpy(&state->board_info, &state->rxbuffer, 8); | ||
819 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | ||
820 | if (state->board_info[1] == 0x0b) { | ||
821 | if (state->type_flags & DST_TYPE_HAS_TS204) | ||
822 | state->type_flags &= ~DST_TYPE_HAS_TS204; | ||
823 | state->type_flags |= DST_TYPE_HAS_NEWTUNE; | ||
824 | dprintk(verbose, DST_INFO, 1, "DST type has TS=188"); | ||
825 | } else { | ||
826 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | ||
827 | state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; | ||
828 | state->type_flags |= DST_TYPE_HAS_TS204; | ||
829 | dprintk(verbose, DST_INFO, 1, "DST type has TS=204"); | ||
830 | } | ||
831 | } else { | ||
832 | if (state->board_info[0] == 0xbc) { | ||
833 | if (state->type_flags & DST_TYPE_HAS_TS204) | ||
834 | state->type_flags &= ~DST_TYPE_HAS_TS204; | ||
835 | state->type_flags |= DST_TYPE_HAS_NEWTUNE; | ||
836 | dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]); | ||
837 | |||
838 | } else if (state->board_info[0] == 0xcc) { | ||
839 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | ||
840 | state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; | ||
841 | state->type_flags |= DST_TYPE_HAS_TS204; | ||
842 | dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]); | ||
843 | } | ||
844 | } | ||
845 | |||
846 | return 0; | ||
847 | } | ||
848 | |||
799 | static int dst_get_device_id(struct dst_state *state) | 849 | static int dst_get_device_id(struct dst_state *state) |
800 | { | 850 | { |
801 | u8 reply; | 851 | u8 reply; |
@@ -855,15 +905,12 @@ static int dst_get_device_id(struct dst_state *state) | |||
855 | state->dst_type = use_dst_type; | 905 | state->dst_type = use_dst_type; |
856 | dst_type_flags_print(state->type_flags); | 906 | dst_type_flags_print(state->type_flags); |
857 | 907 | ||
858 | if (state->type_flags & DST_TYPE_HAS_TS204) { | ||
859 | dst_packsize(state, 204); | ||
860 | } | ||
861 | |||
862 | return 0; | 908 | return 0; |
863 | } | 909 | } |
864 | 910 | ||
865 | static int dst_probe(struct dst_state *state) | 911 | static int dst_probe(struct dst_state *state) |
866 | { | 912 | { |
913 | sema_init(&state->dst_mutex, 1); | ||
867 | if ((rdc_8820_reset(state)) < 0) { | 914 | if ((rdc_8820_reset(state)) < 0) { |
868 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); | 915 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); |
869 | return -1; | 916 | return -1; |
@@ -886,6 +933,13 @@ static int dst_probe(struct dst_state *state) | |||
886 | dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); | 933 | dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); |
887 | return 0; | 934 | return 0; |
888 | } | 935 | } |
936 | if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { | ||
937 | if (dst_get_tuner_info(state) < 0) | ||
938 | dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command"); | ||
939 | } | ||
940 | if (state->type_flags & DST_TYPE_HAS_TS204) { | ||
941 | dst_packsize(state, 204); | ||
942 | } | ||
889 | if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { | 943 | if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { |
890 | if (dst_fw_ver(state) < 0) { | 944 | if (dst_fw_ver(state) < 0) { |
891 | dprintk(verbose, DST_INFO, 1, "FW: Unsupported command"); | 945 | dprintk(verbose, DST_INFO, 1, "FW: Unsupported command"); |
@@ -907,21 +961,23 @@ static int dst_probe(struct dst_state *state) | |||
907 | int dst_command(struct dst_state *state, u8 *data, u8 len) | 961 | int dst_command(struct dst_state *state, u8 *data, u8 len) |
908 | { | 962 | { |
909 | u8 reply; | 963 | u8 reply; |
964 | |||
965 | down(&state->dst_mutex); | ||
910 | if ((dst_comm_init(state)) < 0) { | 966 | if ((dst_comm_init(state)) < 0) { |
911 | dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); | 967 | dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); |
912 | return -1; | 968 | goto error; |
913 | } | 969 | } |
914 | if (write_dst(state, data, len)) { | 970 | if (write_dst(state, data, len)) { |
915 | dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); | 971 | dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); |
916 | if ((dst_error_recovery(state)) < 0) { | 972 | if ((dst_error_recovery(state)) < 0) { |
917 | dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); | 973 | dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); |
918 | return -1; | 974 | goto error; |
919 | } | 975 | } |
920 | return -1; | 976 | goto error; |
921 | } | 977 | } |
922 | if ((dst_pio_disable(state)) < 0) { | 978 | if ((dst_pio_disable(state)) < 0) { |
923 | dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); | 979 | dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); |
924 | return -1; | 980 | goto error; |
925 | } | 981 | } |
926 | if (state->type_flags & DST_TYPE_HAS_FW_1) | 982 | if (state->type_flags & DST_TYPE_HAS_FW_1) |
927 | udelay(3000); | 983 | udelay(3000); |
@@ -929,36 +985,41 @@ int dst_command(struct dst_state *state, u8 *data, u8 len) | |||
929 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); | 985 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); |
930 | if ((dst_error_recovery(state)) < 0) { | 986 | if ((dst_error_recovery(state)) < 0) { |
931 | dprintk(verbose, DST_INFO, 1, "Recovery Failed."); | 987 | dprintk(verbose, DST_INFO, 1, "Recovery Failed."); |
932 | return -1; | 988 | goto error; |
933 | } | 989 | } |
934 | return -1; | 990 | goto error; |
935 | } | 991 | } |
936 | if (reply != ACK) { | 992 | if (reply != ACK) { |
937 | dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); | 993 | dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); |
938 | return -1; | 994 | goto error; |
939 | } | 995 | } |
940 | if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) | 996 | if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) |
941 | return 0; | 997 | goto error; |
942 | if (state->type_flags & DST_TYPE_HAS_FW_1) | 998 | if (state->type_flags & DST_TYPE_HAS_FW_1) |
943 | udelay(3000); | 999 | udelay(3000); |
944 | else | 1000 | else |
945 | udelay(2000); | 1001 | udelay(2000); |
946 | if (!dst_wait_dst_ready(state, NO_DELAY)) | 1002 | if (!dst_wait_dst_ready(state, NO_DELAY)) |
947 | return -1; | 1003 | goto error; |
948 | if (read_dst(state, state->rxbuffer, FIXED_COMM)) { | 1004 | if (read_dst(state, state->rxbuffer, FIXED_COMM)) { |
949 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); | 1005 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); |
950 | if ((dst_error_recovery(state)) < 0) { | 1006 | if ((dst_error_recovery(state)) < 0) { |
951 | dprintk(verbose, DST_INFO, 1, "Recovery failed."); | 1007 | dprintk(verbose, DST_INFO, 1, "Recovery failed."); |
952 | return -1; | 1008 | goto error; |
953 | } | 1009 | } |
954 | return -1; | 1010 | goto error; |
955 | } | 1011 | } |
956 | if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { | 1012 | if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { |
957 | dprintk(verbose, DST_INFO, 1, "checksum failure"); | 1013 | dprintk(verbose, DST_INFO, 1, "checksum failure"); |
958 | return -1; | 1014 | goto error; |
959 | } | 1015 | } |
960 | 1016 | up(&state->dst_mutex); | |
961 | return 0; | 1017 | return 0; |
1018 | |||
1019 | error: | ||
1020 | up(&state->dst_mutex); | ||
1021 | return -EIO; | ||
1022 | |||
962 | } | 1023 | } |
963 | EXPORT_SYMBOL(dst_command); | 1024 | EXPORT_SYMBOL(dst_command); |
964 | 1025 | ||
@@ -1016,7 +1077,7 @@ static int dst_get_tuna(struct dst_state *state) | |||
1016 | return 0; | 1077 | return 0; |
1017 | state->diseq_flags &= ~(HAS_LOCK); | 1078 | state->diseq_flags &= ~(HAS_LOCK); |
1018 | if (!dst_wait_dst_ready(state, NO_DELAY)) | 1079 | if (!dst_wait_dst_ready(state, NO_DELAY)) |
1019 | return 0; | 1080 | return -EIO; |
1020 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | 1081 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) |
1021 | /* how to get variable length reply ???? */ | 1082 | /* how to get variable length reply ???? */ |
1022 | retval = read_dst(state, state->rx_tuna, 10); | 1083 | retval = read_dst(state, state->rx_tuna, 10); |
@@ -1024,22 +1085,27 @@ static int dst_get_tuna(struct dst_state *state) | |||
1024 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); | 1085 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); |
1025 | if (retval < 0) { | 1086 | if (retval < 0) { |
1026 | dprintk(verbose, DST_DEBUG, 1, "read not successful"); | 1087 | dprintk(verbose, DST_DEBUG, 1, "read not successful"); |
1027 | return 0; | 1088 | return retval; |
1028 | } | 1089 | } |
1029 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 1090 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { |
1030 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { | 1091 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { |
1031 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); | 1092 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); |
1032 | return 0; | 1093 | return -EIO; |
1033 | } | 1094 | } |
1034 | } else { | 1095 | } else { |
1035 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { | 1096 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { |
1036 | dprintk(verbose, DST_INFO, 1, "checksum failure? "); | 1097 | dprintk(verbose, DST_INFO, 1, "checksum failure? "); |
1037 | return 0; | 1098 | return -EIO; |
1038 | } | 1099 | } |
1039 | } | 1100 | } |
1040 | if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) | 1101 | if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) |
1041 | return 0; | 1102 | return 0; |
1042 | state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; | 1103 | if (state->dst_type == DST_TYPE_IS_SAT) { |
1104 | state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; | ||
1105 | } else { | ||
1106 | state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4]; | ||
1107 | } | ||
1108 | state->decode_freq = state->decode_freq * 1000; | ||
1043 | state->decode_lock = 1; | 1109 | state->decode_lock = 1; |
1044 | state->diseq_flags |= HAS_LOCK; | 1110 | state->diseq_flags |= HAS_LOCK; |
1045 | 1111 | ||
@@ -1062,10 +1128,10 @@ static int dst_write_tuna(struct dvb_frontend *fe) | |||
1062 | dst_set_voltage(fe, SEC_VOLTAGE_13); | 1128 | dst_set_voltage(fe, SEC_VOLTAGE_13); |
1063 | } | 1129 | } |
1064 | state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); | 1130 | state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); |
1065 | 1131 | down(&state->dst_mutex); | |
1066 | if ((dst_comm_init(state)) < 0) { | 1132 | if ((dst_comm_init(state)) < 0) { |
1067 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); | 1133 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); |
1068 | return -1; | 1134 | goto error; |
1069 | } | 1135 | } |
1070 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 1136 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { |
1071 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); | 1137 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); |
@@ -1077,23 +1143,29 @@ static int dst_write_tuna(struct dvb_frontend *fe) | |||
1077 | if (retval < 0) { | 1143 | if (retval < 0) { |
1078 | dst_pio_disable(state); | 1144 | dst_pio_disable(state); |
1079 | dprintk(verbose, DST_DEBUG, 1, "write not successful"); | 1145 | dprintk(verbose, DST_DEBUG, 1, "write not successful"); |
1080 | return retval; | 1146 | goto werr; |
1081 | } | 1147 | } |
1082 | if ((dst_pio_disable(state)) < 0) { | 1148 | if ((dst_pio_disable(state)) < 0) { |
1083 | dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); | 1149 | dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); |
1084 | return -1; | 1150 | goto error; |
1085 | } | 1151 | } |
1086 | if ((read_dst(state, &reply, GET_ACK) < 0)) { | 1152 | if ((read_dst(state, &reply, GET_ACK) < 0)) { |
1087 | dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); | 1153 | dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); |
1088 | return -1; | 1154 | goto error; |
1089 | } | 1155 | } |
1090 | if (reply != ACK) { | 1156 | if (reply != ACK) { |
1091 | dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); | 1157 | dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); |
1092 | return 0; | 1158 | goto error; |
1093 | } | 1159 | } |
1094 | state->diseq_flags |= ATTEMPT_TUNE; | 1160 | state->diseq_flags |= ATTEMPT_TUNE; |
1095 | 1161 | retval = dst_get_tuna(state); | |
1096 | return dst_get_tuna(state); | 1162 | werr: |
1163 | up(&state->dst_mutex); | ||
1164 | return retval; | ||
1165 | |||
1166 | error: | ||
1167 | up(&state->dst_mutex); | ||
1168 | return -EIO; | ||
1097 | } | 1169 | } |
1098 | 1170 | ||
1099 | /* | 1171 | /* |