diff options
author | James Bottomley <jejb@titanic.(none)> | 2005-11-10 09:29:07 -0500 |
---|---|---|
committer | James Bottomley <jejb@titanic.(none)> | 2005-11-10 09:29:07 -0500 |
commit | 8a87a0b6313109d2fea87b1271d497c954ce2ca8 (patch) | |
tree | 1b7ae51ff681e27118590e9cab4bf0ce38f5d80e /drivers/media/dvb/bt8xx | |
parent | e6a04466ba965875a6132700fabb2f2c0249c41a (diff) | |
parent | 3b44f137b9a846c5452d9e6e1271b79b1dbcc942 (diff) |
Merge by hand (whitespace conflicts in libata.h)
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/media/dvb/bt8xx')
-rw-r--r-- | drivers/media/dvb/bt8xx/Kconfig | 4 | ||||
-rw-r--r-- | drivers/media/dvb/bt8xx/dst.c | 136 | ||||
-rw-r--r-- | drivers/media/dvb/bt8xx/dst_ca.c | 123 | ||||
-rw-r--r-- | drivers/media/dvb/bt8xx/dst_common.h | 5 | ||||
-rw-r--r-- | drivers/media/dvb/bt8xx/dvb-bt8xx.c | 114 | ||||
-rw-r--r-- | drivers/media/dvb/bt8xx/dvb-bt8xx.h | 1 |
6 files changed, 272 insertions, 111 deletions
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig index 1e85d16491b0..2337b41714e0 100644 --- a/drivers/media/dvb/bt8xx/Kconfig +++ b/drivers/media/dvb/bt8xx/Kconfig | |||
@@ -6,10 +6,12 @@ config DVB_BT8XX | |||
6 | select DVB_NXT6000 | 6 | select DVB_NXT6000 |
7 | select DVB_CX24110 | 7 | select DVB_CX24110 |
8 | select DVB_OR51211 | 8 | select DVB_OR51211 |
9 | select DVB_LGDT330X | ||
9 | help | 10 | help |
10 | Support for PCI cards based on the Bt8xx PCI bridge. Examples are | 11 | Support for PCI cards based on the Bt8xx PCI bridge. Examples are |
11 | the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, | 12 | the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, |
12 | the pcHDTV HD2000 cards, and certain AVerMedia cards. | 13 | the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and |
14 | some AVerMedia cards. | ||
13 | 15 | ||
14 | Since these cards have no MPEG decoder onboard, they transmit | 16 | Since these cards have no MPEG decoder onboard, they transmit |
15 | only compressed MPEG data over the PCI bus, so you need | 17 | only compressed MPEG data over the PCI bus, so you need |
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 | /* |
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index 6776a592045f..e6541aff3996 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c | |||
@@ -69,62 +69,53 @@ static int ca_set_pid(void) | |||
69 | } | 69 | } |
70 | 70 | ||
71 | 71 | ||
72 | static int put_checksum(u8 *check_string, int length) | 72 | static void put_checksum(u8 *check_string, int length) |
73 | { | 73 | { |
74 | u8 i = 0, checksum = 0; | 74 | dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum."); |
75 | 75 | dprintk(verbose, DST_CA_DEBUG, 1, " -> string length : 0x%02x", length); | |
76 | dprintk(verbose, DST_CA_DEBUG, 1, " ========================= Checksum calculation ==========================="); | 76 | check_string[length] = dst_check_sum (check_string, length); |
77 | dprintk(verbose, DST_CA_DEBUG, 1, " String Length=[0x%02x]", length); | 77 | dprintk(verbose, DST_CA_DEBUG, 1, " -> checksum : 0x%02x", check_string[length]); |
78 | dprintk(verbose, DST_CA_DEBUG, 1, " String=["); | ||
79 | |||
80 | while (i < length) { | ||
81 | dprintk(verbose, DST_CA_DEBUG, 0, " %02x", check_string[i]); | ||
82 | checksum += check_string[i]; | ||
83 | i++; | ||
84 | } | ||
85 | dprintk(verbose, DST_CA_DEBUG, 0, " ]\n"); | ||
86 | dprintk(verbose, DST_CA_DEBUG, 1, "Sum=[%02x]\n", checksum); | ||
87 | check_string[length] = ~checksum + 1; | ||
88 | dprintk(verbose, DST_CA_DEBUG, 1, " Checksum=[%02x]", check_string[length]); | ||
89 | dprintk(verbose, DST_CA_DEBUG, 1, " =========================================================================="); | ||
90 | |||
91 | return 0; | ||
92 | } | 78 | } |
93 | 79 | ||
94 | static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) | 80 | static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) |
95 | { | 81 | { |
96 | u8 reply; | 82 | u8 reply; |
97 | 83 | ||
84 | down(&state->dst_mutex); | ||
98 | dst_comm_init(state); | 85 | dst_comm_init(state); |
99 | msleep(65); | 86 | msleep(65); |
100 | 87 | ||
101 | if (write_dst(state, data, len)) { | 88 | if (write_dst(state, data, len)) { |
102 | dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); | 89 | dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); |
103 | dst_error_recovery(state); | 90 | dst_error_recovery(state); |
104 | return -1; | 91 | goto error; |
105 | } | 92 | } |
106 | if ((dst_pio_disable(state)) < 0) { | 93 | if ((dst_pio_disable(state)) < 0) { |
107 | dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); | 94 | dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); |
108 | return -1; | 95 | goto error; |
109 | } | 96 | } |
110 | if (read_dst(state, &reply, GET_ACK) < 0) { | 97 | if (read_dst(state, &reply, GET_ACK) < 0) { |
111 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); | 98 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); |
112 | dst_error_recovery(state); | 99 | dst_error_recovery(state); |
113 | return -1; | 100 | goto error; |
114 | } | 101 | } |
115 | if (read) { | 102 | if (read) { |
116 | if (! dst_wait_dst_ready(state, LONG_DELAY)) { | 103 | if (! dst_wait_dst_ready(state, LONG_DELAY)) { |
117 | dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); | 104 | dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); |
118 | return -1; | 105 | goto error; |
119 | } | 106 | } |
120 | if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ | 107 | if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ |
121 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); | 108 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); |
122 | dst_error_recovery(state); | 109 | dst_error_recovery(state); |
123 | return -1; | 110 | goto error; |
124 | } | 111 | } |
125 | } | 112 | } |
126 | 113 | up(&state->dst_mutex); | |
127 | return 0; | 114 | return 0; |
115 | |||
116 | error: | ||
117 | up(&state->dst_mutex); | ||
118 | return -EIO; | ||
128 | } | 119 | } |
129 | 120 | ||
130 | 121 | ||
@@ -166,7 +157,7 @@ static int ca_get_app_info(struct dst_state *state) | |||
166 | return 0; | 157 | return 0; |
167 | } | 158 | } |
168 | 159 | ||
169 | static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg) | 160 | static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg) |
170 | { | 161 | { |
171 | int i; | 162 | int i; |
172 | u8 slot_cap[256]; | 163 | u8 slot_cap[256]; |
@@ -192,25 +183,25 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, | |||
192 | p_ca_caps->descr_num = slot_cap[7]; | 183 | p_ca_caps->descr_num = slot_cap[7]; |
193 | p_ca_caps->descr_type = 1; | 184 | p_ca_caps->descr_type = 1; |
194 | 185 | ||
195 | if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) | 186 | if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps))) |
196 | return -EFAULT; | 187 | return -EFAULT; |
197 | 188 | ||
198 | return 0; | 189 | return 0; |
199 | } | 190 | } |
200 | 191 | ||
201 | /* Need some more work */ | 192 | /* Need some more work */ |
202 | static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) | 193 | static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) |
203 | { | 194 | { |
204 | return -EOPNOTSUPP; | 195 | return -EOPNOTSUPP; |
205 | } | 196 | } |
206 | 197 | ||
207 | 198 | ||
208 | static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg) | 199 | static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg) |
209 | { | 200 | { |
210 | int i; | 201 | int i; |
211 | static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; | 202 | static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; |
212 | 203 | ||
213 | u8 *slot_info = state->rxbuffer; | 204 | u8 *slot_info = state->messages; |
214 | 205 | ||
215 | put_checksum(&slot_command[0], 7); | 206 | put_checksum(&slot_command[0], 7); |
216 | if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { | 207 | if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { |
@@ -238,19 +229,19 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s | |||
238 | } else | 229 | } else |
239 | p_ca_slot_info->flags = 0; | 230 | p_ca_slot_info->flags = 0; |
240 | 231 | ||
241 | if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) | 232 | if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info))) |
242 | return -EFAULT; | 233 | return -EFAULT; |
243 | 234 | ||
244 | return 0; | 235 | return 0; |
245 | } | 236 | } |
246 | 237 | ||
247 | 238 | ||
248 | static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) | 239 | static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) |
249 | { | 240 | { |
250 | u8 i = 0; | 241 | u8 i = 0; |
251 | u32 command = 0; | 242 | u32 command = 0; |
252 | 243 | ||
253 | if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) | 244 | if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) |
254 | return -EFAULT; | 245 | return -EFAULT; |
255 | 246 | ||
256 | if (p_ca_message->msg) { | 247 | if (p_ca_message->msg) { |
@@ -266,7 +257,7 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
266 | switch (command) { | 257 | switch (command) { |
267 | case CA_APP_INFO: | 258 | case CA_APP_INFO: |
268 | memcpy(p_ca_message->msg, state->messages, 128); | 259 | memcpy(p_ca_message->msg, state->messages, 128); |
269 | if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) ) | 260 | if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) |
270 | return -EFAULT; | 261 | return -EFAULT; |
271 | break; | 262 | break; |
272 | } | 263 | } |
@@ -315,7 +306,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l | |||
315 | return 0; | 306 | return 0; |
316 | } | 307 | } |
317 | 308 | ||
318 | u32 asn_1_decode(u8 *asn_1_array) | 309 | static u32 asn_1_decode(u8 *asn_1_array) |
319 | { | 310 | { |
320 | u8 length_field = 0, word_count = 0, count = 0; | 311 | u8 length_field = 0, word_count = 0, count = 0; |
321 | u32 length = 0; | 312 | u32 length = 0; |
@@ -328,7 +319,8 @@ u32 asn_1_decode(u8 *asn_1_array) | |||
328 | } else { | 319 | } else { |
329 | word_count = length_field & 0x7f; | 320 | word_count = length_field & 0x7f; |
330 | for (count = 0; count < word_count; count++) { | 321 | for (count = 0; count < word_count; count++) { |
331 | length = (length | asn_1_array[count + 1]) << 8; | 322 | length = length << 8; |
323 | length += asn_1_array[count + 1]; | ||
332 | dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length); | 324 | dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length); |
333 | } | 325 | } |
334 | } | 326 | } |
@@ -399,13 +391,14 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message | |||
399 | return 0; | 391 | return 0; |
400 | } | 392 | } |
401 | 393 | ||
402 | static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) | 394 | static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) |
403 | { | 395 | { |
404 | int i = 0; | 396 | int i = 0; |
405 | unsigned int ca_message_header_len; | 397 | unsigned int ca_message_header_len; |
406 | 398 | ||
407 | u32 command = 0; | 399 | u32 command = 0; |
408 | struct ca_msg *hw_buffer; | 400 | struct ca_msg *hw_buffer; |
401 | int result = 0; | ||
409 | 402 | ||
410 | if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { | 403 | if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { |
411 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | 404 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); |
@@ -413,8 +406,11 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
413 | } | 406 | } |
414 | dprintk(verbose, DST_CA_DEBUG, 1, " "); | 407 | dprintk(verbose, DST_CA_DEBUG, 1, " "); |
415 | 408 | ||
416 | if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) | 409 | if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) { |
417 | return -EFAULT; | 410 | result = -EFAULT; |
411 | goto free_mem_and_exit; | ||
412 | } | ||
413 | |||
418 | 414 | ||
419 | if (p_ca_message->msg) { | 415 | if (p_ca_message->msg) { |
420 | ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ | 416 | ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ |
@@ -433,7 +429,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
433 | dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); | 429 | dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); |
434 | if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started | 430 | if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started |
435 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); | 431 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); |
436 | return -1; | 432 | result = -1; |
433 | goto free_mem_and_exit; | ||
437 | } | 434 | } |
438 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); | 435 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); |
439 | break; | 436 | break; |
@@ -442,7 +439,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
442 | /* Have to handle the 2 basic types of cards here */ | 439 | /* Have to handle the 2 basic types of cards here */ |
443 | if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { | 440 | if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { |
444 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); | 441 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); |
445 | return -1; | 442 | result = -1; |
443 | goto free_mem_and_exit; | ||
446 | } | 444 | } |
447 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); | 445 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); |
448 | break; | 446 | break; |
@@ -451,22 +449,28 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
451 | 449 | ||
452 | if ((ca_get_app_info(state)) < 0) { | 450 | if ((ca_get_app_info(state)) < 0) { |
453 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); | 451 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); |
454 | return -1; | 452 | result = -1; |
453 | goto free_mem_and_exit; | ||
455 | } | 454 | } |
456 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); | 455 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); |
457 | break; | 456 | break; |
458 | } | 457 | } |
459 | } | 458 | } |
460 | return 0; | 459 | free_mem_and_exit: |
460 | kfree (hw_buffer); | ||
461 | |||
462 | return result; | ||
461 | } | 463 | } |
462 | 464 | ||
463 | static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) | 465 | static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg) |
464 | { | 466 | { |
465 | struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; | 467 | struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; |
466 | struct dst_state* state = (struct dst_state*) dvbdev->priv; | 468 | struct dst_state* state = (struct dst_state*) dvbdev->priv; |
467 | struct ca_slot_info *p_ca_slot_info; | 469 | struct ca_slot_info *p_ca_slot_info; |
468 | struct ca_caps *p_ca_caps; | 470 | struct ca_caps *p_ca_caps; |
469 | struct ca_msg *p_ca_message; | 471 | struct ca_msg *p_ca_message; |
472 | void __user *arg = (void __user *)ioctl_arg; | ||
473 | int result = 0; | ||
470 | 474 | ||
471 | if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { | 475 | if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { |
472 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | 476 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); |
@@ -486,14 +490,16 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
486 | dprintk(verbose, DST_CA_INFO, 1, " Sending message"); | 490 | dprintk(verbose, DST_CA_INFO, 1, " Sending message"); |
487 | if ((ca_send_message(state, p_ca_message, arg)) < 0) { | 491 | if ((ca_send_message(state, p_ca_message, arg)) < 0) { |
488 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); | 492 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); |
489 | return -1; | 493 | result = -1; |
494 | goto free_mem_and_exit; | ||
490 | } | 495 | } |
491 | break; | 496 | break; |
492 | case CA_GET_MSG: | 497 | case CA_GET_MSG: |
493 | dprintk(verbose, DST_CA_INFO, 1, " Getting message"); | 498 | dprintk(verbose, DST_CA_INFO, 1, " Getting message"); |
494 | if ((ca_get_message(state, p_ca_message, arg)) < 0) { | 499 | if ((ca_get_message(state, p_ca_message, arg)) < 0) { |
495 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); | 500 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); |
496 | return -1; | 501 | result = -1; |
502 | goto free_mem_and_exit; | ||
497 | } | 503 | } |
498 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); | 504 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); |
499 | break; | 505 | break; |
@@ -506,7 +512,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
506 | dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); | 512 | dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); |
507 | if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { | 513 | if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { |
508 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); | 514 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); |
509 | return -1; | 515 | result = -1; |
516 | goto free_mem_and_exit; | ||
510 | } | 517 | } |
511 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !"); | 518 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !"); |
512 | break; | 519 | break; |
@@ -514,7 +521,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
514 | dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); | 521 | dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); |
515 | if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { | 522 | if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { |
516 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); | 523 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); |
517 | return -1; | 524 | result = -1; |
525 | goto free_mem_and_exit; | ||
518 | } | 526 | } |
519 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); | 527 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); |
520 | break; | 528 | break; |
@@ -522,7 +530,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
522 | dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); | 530 | dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); |
523 | if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { | 531 | if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { |
524 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); | 532 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); |
525 | return -1; | 533 | result = -1; |
534 | goto free_mem_and_exit; | ||
526 | } | 535 | } |
527 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); | 536 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); |
528 | break; | 537 | break; |
@@ -530,7 +539,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
530 | dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); | 539 | dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); |
531 | if ((ca_set_slot_descr()) < 0) { | 540 | if ((ca_set_slot_descr()) < 0) { |
532 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); | 541 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); |
533 | return -1; | 542 | result = -1; |
543 | goto free_mem_and_exit; | ||
534 | } | 544 | } |
535 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); | 545 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); |
536 | break; | 546 | break; |
@@ -538,14 +548,19 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
538 | dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); | 548 | dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); |
539 | if ((ca_set_pid()) < 0) { | 549 | if ((ca_set_pid()) < 0) { |
540 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); | 550 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); |
541 | return -1; | 551 | result = -1; |
552 | goto free_mem_and_exit; | ||
542 | } | 553 | } |
543 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); | 554 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); |
544 | default: | 555 | default: |
545 | return -EOPNOTSUPP; | 556 | result = -EOPNOTSUPP; |
546 | }; | 557 | }; |
558 | free_mem_and_exit: | ||
559 | kfree (p_ca_message); | ||
560 | kfree (p_ca_slot_info); | ||
561 | kfree (p_ca_caps); | ||
547 | 562 | ||
548 | return 0; | 563 | return result; |
549 | } | 564 | } |
550 | 565 | ||
551 | static int dst_ca_open(struct inode *inode, struct file *file) | 566 | static int dst_ca_open(struct inode *inode, struct file *file) |
@@ -582,7 +597,7 @@ static int dst_ca_write(struct file *file, const char __user *buffer, size_t len | |||
582 | 597 | ||
583 | static struct file_operations dst_ca_fops = { | 598 | static struct file_operations dst_ca_fops = { |
584 | .owner = THIS_MODULE, | 599 | .owner = THIS_MODULE, |
585 | .ioctl = (void *)dst_ca_ioctl, | 600 | .ioctl = dst_ca_ioctl, |
586 | .open = dst_ca_open, | 601 | .open = dst_ca_open, |
587 | .release = dst_ca_release, | 602 | .release = dst_ca_release, |
588 | .read = dst_ca_read, | 603 | .read = dst_ca_read, |
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h index 3281a6ca3685..81557f38fe38 100644 --- a/drivers/media/dvb/bt8xx/dst_common.h +++ b/drivers/media/dvb/bt8xx/dst_common.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #ifndef DST_COMMON_H | 22 | #ifndef DST_COMMON_H |
23 | #define DST_COMMON_H | 23 | #define DST_COMMON_H |
24 | 24 | ||
25 | #include <linux/smp_lock.h> | ||
25 | #include <linux/dvb/frontend.h> | 26 | #include <linux/dvb/frontend.h> |
26 | #include <linux/device.h> | 27 | #include <linux/device.h> |
27 | #include "bt878.h" | 28 | #include "bt878.h" |
@@ -49,6 +50,7 @@ | |||
49 | #define DST_TYPE_HAS_FW_BUILD 64 | 50 | #define DST_TYPE_HAS_FW_BUILD 64 |
50 | #define DST_TYPE_HAS_OBS_REGS 128 | 51 | #define DST_TYPE_HAS_OBS_REGS 128 |
51 | #define DST_TYPE_HAS_INC_COUNT 256 | 52 | #define DST_TYPE_HAS_INC_COUNT 256 |
53 | #define DST_TYPE_HAS_MULTI_FE 512 | ||
52 | 54 | ||
53 | /* Card capability list */ | 55 | /* Card capability list */ |
54 | 56 | ||
@@ -117,6 +119,9 @@ struct dst_state { | |||
117 | u8 fw_version[8]; | 119 | u8 fw_version[8]; |
118 | u8 card_info[8]; | 120 | u8 card_info[8]; |
119 | u8 vendor[8]; | 121 | u8 vendor[8]; |
122 | u8 board_info[8]; | ||
123 | |||
124 | struct semaphore dst_mutex; | ||
120 | }; | 125 | }; |
121 | 126 | ||
122 | struct dst_types { | 127 | struct dst_types { |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index c5c7672cd538..2e398090cf63 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "dvb_frontend.h" | 34 | #include "dvb_frontend.h" |
35 | #include "dvb-bt8xx.h" | 35 | #include "dvb-bt8xx.h" |
36 | #include "bt878.h" | 36 | #include "bt878.h" |
37 | #include "dvb-pll.h" | ||
37 | 38 | ||
38 | static int debug; | 39 | static int debug; |
39 | 40 | ||
@@ -279,7 +280,7 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front | |||
279 | data[0] = (div >> 8) & 0x7f; | 280 | data[0] = (div >> 8) & 0x7f; |
280 | data[1] = div & 0xff; | 281 | data[1] = div & 0xff; |
281 | data[2] = ((div >> 10) & 0x60) | cfg; | 282 | data[2] = ((div >> 10) & 0x60) | cfg; |
282 | data[3] = cpump | band_select; | 283 | data[3] = (cpump << 6) | band_select; |
283 | 284 | ||
284 | i2c_transfer(card->i2c_adapter, &msg, 1); | 285 | i2c_transfer(card->i2c_adapter, &msg, 1); |
285 | return (div * 166666 - 36000000); | 286 | return (div * 166666 - 36000000); |
@@ -522,9 +523,7 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) | |||
522 | /* | 523 | /* |
523 | * Reset the frontend, must be called before trying | 524 | * Reset the frontend, must be called before trying |
524 | * to initialise the MT352 or mt352_attach | 525 | * to initialise the MT352 or mt352_attach |
525 | * will fail. | 526 | * will fail. Same goes for the nxt6000 frontend. |
526 | * | ||
527 | * Presumably not required for the NXT6000 frontend. | ||
528 | * | 527 | * |
529 | */ | 528 | */ |
530 | 529 | ||
@@ -546,14 +545,63 @@ static struct mt352_config digitv_alps_tded4_config = { | |||
546 | .pll_set = digitv_alps_tded4_pll_set, | 545 | .pll_set = digitv_alps_tded4_pll_set, |
547 | }; | 546 | }; |
548 | 547 | ||
548 | static int tdvs_tua6034_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | ||
549 | { | ||
550 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; | ||
551 | u8 buf[4]; | ||
552 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
553 | int err; | ||
554 | |||
555 | dvb_pll_configure(&dvb_pll_tdvs_tua6034, buf, params->frequency, 0); | ||
556 | dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
557 | __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); | ||
558 | if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) { | ||
559 | printk(KERN_WARNING "dvb-bt8xx: %s error " | ||
560 | "(addr %02x <- %02x, err = %i)\n", | ||
561 | __FUNCTION__, buf[0], buf[1], err); | ||
562 | if (err < 0) | ||
563 | return err; | ||
564 | else | ||
565 | return -EREMOTEIO; | ||
566 | } | ||
567 | |||
568 | /* Set the Auxiliary Byte. */ | ||
569 | buf[2] &= ~0x20; | ||
570 | buf[2] |= 0x18; | ||
571 | buf[3] = 0x50; | ||
572 | i2c_transfer(card->i2c_adapter, &msg, 1); | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static struct lgdt330x_config tdvs_tua6034_config = { | ||
578 | .demod_address = 0x0e, | ||
579 | .demod_chip = LGDT3303, | ||
580 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | ||
581 | .pll_set = tdvs_tua6034_pll_set, | ||
582 | }; | ||
583 | |||
584 | static void lgdt330x_reset(struct dvb_bt8xx_card *bt) | ||
585 | { | ||
586 | /* Set pin 27 of the lgdt3303 chip high to reset the frontend */ | ||
587 | |||
588 | /* Pulse the reset line */ | ||
589 | bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */ | ||
590 | bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */ | ||
591 | msleep(100); | ||
592 | |||
593 | bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */ | ||
594 | msleep(100); | ||
595 | } | ||
596 | |||
549 | static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | 597 | static void frontend_init(struct dvb_bt8xx_card *card, u32 type) |
550 | { | 598 | { |
551 | int ret; | 599 | int ret; |
552 | struct dst_state* state = NULL; | 600 | struct dst_state* state = NULL; |
553 | 601 | ||
554 | switch(type) { | 602 | switch(type) { |
555 | #ifdef BTTV_DVICO_DVBT_LITE | 603 | #ifdef BTTV_BOARD_DVICO_DVBT_LITE |
556 | case BTTV_DVICO_DVBT_LITE: | 604 | case BTTV_BOARD_DVICO_DVBT_LITE: |
557 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); | 605 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); |
558 | if (card->fe != NULL) { | 606 | if (card->fe != NULL) { |
559 | card->fe->ops->info.frequency_min = 174000000; | 607 | card->fe->ops->info.frequency_min = 174000000; |
@@ -562,10 +610,19 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
562 | break; | 610 | break; |
563 | #endif | 611 | #endif |
564 | 612 | ||
565 | #ifdef BTTV_TWINHAN_VP3021 | 613 | #ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE |
566 | case BTTV_TWINHAN_VP3021: | 614 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: |
615 | lgdt330x_reset(card); | ||
616 | card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); | ||
617 | if (card->fe != NULL) | ||
618 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); | ||
619 | break; | ||
620 | #endif | ||
621 | |||
622 | #ifdef BTTV_BOARD_TWINHAN_VP3021 | ||
623 | case BTTV_BOARD_TWINHAN_VP3021: | ||
567 | #else | 624 | #else |
568 | case BTTV_NEBULA_DIGITV: | 625 | case BTTV_BOARD_NEBULA_DIGITV: |
569 | #endif | 626 | #endif |
570 | /* | 627 | /* |
571 | * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); | 628 | * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); |
@@ -573,6 +630,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
573 | */ | 630 | */ |
574 | 631 | ||
575 | /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ | 632 | /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ |
633 | digitv_alps_tded4_reset(card); | ||
576 | card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); | 634 | card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); |
577 | if (card->fe != NULL) { | 635 | if (card->fe != NULL) { |
578 | dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); | 636 | dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); |
@@ -587,11 +645,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
587 | dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); | 645 | dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); |
588 | break; | 646 | break; |
589 | 647 | ||
590 | case BTTV_AVDVBT_761: | 648 | case BTTV_BOARD_AVDVBT_761: |
591 | card->fe = sp887x_attach(µtune_mt7202dtf_config, card->i2c_adapter); | 649 | card->fe = sp887x_attach(µtune_mt7202dtf_config, card->i2c_adapter); |
592 | break; | 650 | break; |
593 | 651 | ||
594 | case BTTV_AVDVBT_771: | 652 | case BTTV_BOARD_AVDVBT_771: |
595 | card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); | 653 | card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); |
596 | if (card->fe != NULL) { | 654 | if (card->fe != NULL) { |
597 | card->fe->ops->info.frequency_min = 174000000; | 655 | card->fe->ops->info.frequency_min = 174000000; |
@@ -599,7 +657,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
599 | } | 657 | } |
600 | break; | 658 | break; |
601 | 659 | ||
602 | case BTTV_TWINHAN_DST: | 660 | case BTTV_BOARD_TWINHAN_DST: |
603 | /* DST is not a frontend driver !!! */ | 661 | /* DST is not a frontend driver !!! */ |
604 | state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); | 662 | state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); |
605 | /* Setup the Card */ | 663 | /* Setup the Card */ |
@@ -620,11 +678,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
620 | ret = dst_ca_attach(state, &card->dvb_adapter); | 678 | ret = dst_ca_attach(state, &card->dvb_adapter); |
621 | break; | 679 | break; |
622 | 680 | ||
623 | case BTTV_PINNACLESAT: | 681 | case BTTV_BOARD_PINNACLESAT: |
624 | card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); | 682 | card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); |
625 | break; | 683 | break; |
626 | 684 | ||
627 | case BTTV_PC_HDTV: | 685 | case BTTV_BOARD_PC_HDTV: |
628 | card->fe = or51211_attach(&or51211_config, card->i2c_adapter); | 686 | card->fe = or51211_attach(&or51211_config, card->i2c_adapter); |
629 | break; | 687 | break; |
630 | } | 688 | } |
@@ -746,7 +804,7 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
746 | card->i2c_adapter = &sub->core->i2c_adap; | 804 | card->i2c_adapter = &sub->core->i2c_adap; |
747 | 805 | ||
748 | switch(sub->core->type) { | 806 | switch(sub->core->type) { |
749 | case BTTV_PINNACLESAT: | 807 | case BTTV_BOARD_PINNACLESAT: |
750 | card->gpio_mode = 0x0400c060; | 808 | card->gpio_mode = 0x0400c060; |
751 | /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, | 809 | /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, |
752 | BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ | 810 | BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ |
@@ -754,8 +812,8 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
754 | card->irq_err_ignore = 0; | 812 | card->irq_err_ignore = 0; |
755 | break; | 813 | break; |
756 | 814 | ||
757 | #ifdef BTTV_DVICO_DVBT_LITE | 815 | #ifdef BTTV_BOARD_DVICO_DVBT_LITE |
758 | case BTTV_DVICO_DVBT_LITE: | 816 | case BTTV_BOARD_DVICO_DVBT_LITE: |
759 | #endif | 817 | #endif |
760 | card->gpio_mode = 0x0400C060; | 818 | card->gpio_mode = 0x0400C060; |
761 | card->op_sync_orin = 0; | 819 | card->op_sync_orin = 0; |
@@ -765,26 +823,34 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
765 | * DA_APP(parallel) */ | 823 | * DA_APP(parallel) */ |
766 | break; | 824 | break; |
767 | 825 | ||
768 | #ifdef BTTV_TWINHAN_VP3021 | 826 | #ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE |
769 | case BTTV_TWINHAN_VP3021: | 827 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: |
828 | #endif | ||
829 | card->gpio_mode = 0x0400c060; | ||
830 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | ||
831 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; | ||
832 | break; | ||
833 | |||
834 | #ifdef BTTV_BOARD_TWINHAN_VP3021 | ||
835 | case BTTV_BOARD_TWINHAN_VP3021: | ||
770 | #else | 836 | #else |
771 | case BTTV_NEBULA_DIGITV: | 837 | case BTTV_BOARD_NEBULA_DIGITV: |
772 | #endif | 838 | #endif |
773 | case BTTV_AVDVBT_761: | 839 | case BTTV_BOARD_AVDVBT_761: |
774 | card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); | 840 | card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); |
775 | card->op_sync_orin = 0; | 841 | card->op_sync_orin = 0; |
776 | card->irq_err_ignore = 0; | 842 | card->irq_err_ignore = 0; |
777 | /* A_PWRDN DA_SBR DA_APP (high speed serial) */ | 843 | /* A_PWRDN DA_SBR DA_APP (high speed serial) */ |
778 | break; | 844 | break; |
779 | 845 | ||
780 | case BTTV_AVDVBT_771: //case 0x07711461: | 846 | case BTTV_BOARD_AVDVBT_771: //case 0x07711461: |
781 | card->gpio_mode = 0x0400402B; | 847 | card->gpio_mode = 0x0400402B; |
782 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | 848 | card->op_sync_orin = BT878_RISC_SYNC_MASK; |
783 | card->irq_err_ignore = 0; | 849 | card->irq_err_ignore = 0; |
784 | /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ | 850 | /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ |
785 | break; | 851 | break; |
786 | 852 | ||
787 | case BTTV_TWINHAN_DST: | 853 | case BTTV_BOARD_TWINHAN_DST: |
788 | card->gpio_mode = 0x2204f2c; | 854 | card->gpio_mode = 0x2204f2c; |
789 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | 855 | card->op_sync_orin = BT878_RISC_SYNC_MASK; |
790 | card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | | 856 | card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | |
@@ -802,7 +868,7 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
802 | * RISC+FIFO ENABLE */ | 868 | * RISC+FIFO ENABLE */ |
803 | break; | 869 | break; |
804 | 870 | ||
805 | case BTTV_PC_HDTV: | 871 | case BTTV_BOARD_PC_HDTV: |
806 | card->gpio_mode = 0x0100EC7B; | 872 | card->gpio_mode = 0x0100EC7B; |
807 | card->op_sync_orin = 0; | 873 | card->op_sync_orin = 0; |
808 | card->irq_err_ignore = 0; | 874 | card->irq_err_ignore = 0; |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h index 9ec8e5bd6c1f..cf035a80361c 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "nxt6000.h" | 35 | #include "nxt6000.h" |
36 | #include "cx24110.h" | 36 | #include "cx24110.h" |
37 | #include "or51211.h" | 37 | #include "or51211.h" |
38 | #include "lgdt330x.h" | ||
38 | 39 | ||
39 | struct dvb_bt8xx_card { | 40 | struct dvb_bt8xx_card { |
40 | struct semaphore lock; | 41 | struct semaphore lock; |