diff options
Diffstat (limited to 'drivers/media/common/tuners/tuner-xc2028.c')
-rw-r--r-- | drivers/media/common/tuners/tuner-xc2028.c | 116 |
1 files changed, 55 insertions, 61 deletions
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 3acbaa04e1b..27555995f7e 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c | |||
@@ -311,7 +311,7 @@ static int load_all_firmwares(struct dvb_frontend *fe) | |||
311 | n_array, fname, name, | 311 | n_array, fname, name, |
312 | priv->firm_version >> 8, priv->firm_version & 0xff); | 312 | priv->firm_version >> 8, priv->firm_version & 0xff); |
313 | 313 | ||
314 | priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL); | 314 | priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL); |
315 | if (priv->firm == NULL) { | 315 | if (priv->firm == NULL) { |
316 | tuner_err("Not enough memory to load firmware file.\n"); | 316 | tuner_err("Not enough memory to load firmware file.\n"); |
317 | rc = -ENOMEM; | 317 | rc = -ENOMEM; |
@@ -891,7 +891,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) | |||
891 | 891 | ||
892 | /* Frequency is locked */ | 892 | /* Frequency is locked */ |
893 | if (frq_lock == 1) | 893 | if (frq_lock == 1) |
894 | signal = 32768; | 894 | signal = 1 << 11; |
895 | 895 | ||
896 | /* Get SNR of the video signal */ | 896 | /* Get SNR of the video signal */ |
897 | rc = xc2028_get_reg(priv, 0x0040, &signal); | 897 | rc = xc2028_get_reg(priv, 0x0040, &signal); |
@@ -962,14 +962,24 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | |||
962 | * For DTV 7/8, the firmware uses BW = 8000, so it needs a | 962 | * For DTV 7/8, the firmware uses BW = 8000, so it needs a |
963 | * further adjustment to get the frequency center on VHF | 963 | * further adjustment to get the frequency center on VHF |
964 | */ | 964 | */ |
965 | |||
966 | /* | ||
967 | * The firmware DTV78 used to work fine in UHF band (8 MHz | ||
968 | * bandwidth) but not at all in VHF band (7 MHz bandwidth). | ||
969 | * The real problem was connected to the formula used to | ||
970 | * calculate the center frequency offset in VHF band. | ||
971 | * In fact, removing the 500KHz adjustment fixed the problem. | ||
972 | * This is coherent to what was implemented for the DTV7 | ||
973 | * firmware. | ||
974 | * In the end, now the center frequency is the same for all 3 | ||
975 | * firmwares (DTV7, DTV8, DTV78) and doesn't depend on channel | ||
976 | * bandwidth. | ||
977 | */ | ||
978 | |||
965 | if (priv->cur_fw.type & DTV6) | 979 | if (priv->cur_fw.type & DTV6) |
966 | offset = 1750000; | 980 | offset = 1750000; |
967 | else if (priv->cur_fw.type & DTV7) | 981 | else /* DTV7 or DTV8 or DTV78 */ |
968 | offset = 2250000; | ||
969 | else /* DTV8 or DTV78 */ | ||
970 | offset = 2750000; | 982 | offset = 2750000; |
971 | if ((priv->cur_fw.type & DTV78) && freq < 470000000) | ||
972 | offset -= 500000; | ||
973 | 983 | ||
974 | /* | 984 | /* |
975 | * xc3028 additional "magic" | 985 | * xc3028 additional "magic" |
@@ -979,17 +989,13 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | |||
979 | * newer firmwares | 989 | * newer firmwares |
980 | */ | 990 | */ |
981 | 991 | ||
982 | #if 1 | ||
983 | /* | 992 | /* |
984 | * The proper adjustment would be to do it at s-code table. | 993 | * The proper adjustment would be to do it at s-code table. |
985 | * However, this didn't work, as reported by | 994 | * However, this didn't work, as reported by |
986 | * Robert Lowery <rglowery@exemail.com.au> | 995 | * Robert Lowery <rglowery@exemail.com.au> |
987 | */ | 996 | */ |
988 | 997 | ||
989 | if (priv->cur_fw.type & DTV7) | 998 | #if 0 |
990 | offset += 500000; | ||
991 | |||
992 | #else | ||
993 | /* | 999 | /* |
994 | * Still need tests for XC3028L (firmware 3.2 or upper) | 1000 | * Still need tests for XC3028L (firmware 3.2 or upper) |
995 | * So, for now, let's just comment the per-firmware | 1001 | * So, for now, let's just comment the per-firmware |
@@ -1084,68 +1090,28 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe, | |||
1084 | V4L2_TUNER_ANALOG_TV, type, p->std, 0); | 1090 | V4L2_TUNER_ANALOG_TV, type, p->std, 0); |
1085 | } | 1091 | } |
1086 | 1092 | ||
1087 | static int xc2028_set_params(struct dvb_frontend *fe, | 1093 | static int xc2028_set_params(struct dvb_frontend *fe) |
1088 | struct dvb_frontend_parameters *p) | ||
1089 | { | 1094 | { |
1095 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
1096 | u32 delsys = c->delivery_system; | ||
1097 | u32 bw = c->bandwidth_hz; | ||
1090 | struct xc2028_data *priv = fe->tuner_priv; | 1098 | struct xc2028_data *priv = fe->tuner_priv; |
1091 | unsigned int type=0; | 1099 | unsigned int type=0; |
1092 | fe_bandwidth_t bw = BANDWIDTH_8_MHZ; | ||
1093 | u16 demod = 0; | 1100 | u16 demod = 0; |
1094 | 1101 | ||
1095 | tuner_dbg("%s called\n", __func__); | 1102 | tuner_dbg("%s called\n", __func__); |
1096 | 1103 | ||
1097 | switch(fe->ops.info.type) { | 1104 | switch (delsys) { |
1098 | case FE_OFDM: | 1105 | case SYS_DVBT: |
1099 | bw = p->u.ofdm.bandwidth; | 1106 | case SYS_DVBT2: |
1100 | /* | 1107 | /* |
1101 | * The only countries with 6MHz seem to be Taiwan/Uruguay. | 1108 | * The only countries with 6MHz seem to be Taiwan/Uruguay. |
1102 | * Both seem to require QAM firmware for OFDM decoding | 1109 | * Both seem to require QAM firmware for OFDM decoding |
1103 | * Tested in Taiwan by Terry Wu <terrywu2009@gmail.com> | 1110 | * Tested in Taiwan by Terry Wu <terrywu2009@gmail.com> |
1104 | */ | 1111 | */ |
1105 | if (bw == BANDWIDTH_6_MHZ) | 1112 | if (bw <= 6000000) |
1106 | type |= QAM; | 1113 | type |= QAM; |
1107 | break; | ||
1108 | case FE_ATSC: | ||
1109 | bw = BANDWIDTH_6_MHZ; | ||
1110 | /* The only ATSC firmware (at least on v2.7) is D2633 */ | ||
1111 | type |= ATSC | D2633; | ||
1112 | break; | ||
1113 | /* DVB-S and pure QAM (FE_QAM) are not supported */ | ||
1114 | default: | ||
1115 | return -EINVAL; | ||
1116 | } | ||
1117 | |||
1118 | switch (bw) { | ||
1119 | case BANDWIDTH_8_MHZ: | ||
1120 | if (p->frequency < 470000000) | ||
1121 | priv->ctrl.vhfbw7 = 0; | ||
1122 | else | ||
1123 | priv->ctrl.uhfbw8 = 1; | ||
1124 | type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV8; | ||
1125 | type |= F8MHZ; | ||
1126 | break; | ||
1127 | case BANDWIDTH_7_MHZ: | ||
1128 | if (p->frequency < 470000000) | ||
1129 | priv->ctrl.vhfbw7 = 1; | ||
1130 | else | ||
1131 | priv->ctrl.uhfbw8 = 0; | ||
1132 | type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV7; | ||
1133 | type |= F8MHZ; | ||
1134 | break; | ||
1135 | case BANDWIDTH_6_MHZ: | ||
1136 | type |= DTV6; | ||
1137 | priv->ctrl.vhfbw7 = 0; | ||
1138 | priv->ctrl.uhfbw8 = 0; | ||
1139 | break; | ||
1140 | default: | ||
1141 | tuner_err("error: bandwidth not supported.\n"); | ||
1142 | }; | ||
1143 | 1114 | ||
1144 | /* | ||
1145 | Selects between D2633 or D2620 firmware. | ||
1146 | It doesn't make sense for ATSC, since it should be D2633 on all cases | ||
1147 | */ | ||
1148 | if (fe->ops.info.type != FE_ATSC) { | ||
1149 | switch (priv->ctrl.type) { | 1115 | switch (priv->ctrl.type) { |
1150 | case XC2028_D2633: | 1116 | case XC2028_D2633: |
1151 | type |= D2633; | 1117 | type |= D2633; |
@@ -1161,6 +1127,34 @@ static int xc2028_set_params(struct dvb_frontend *fe, | |||
1161 | else | 1127 | else |
1162 | type |= D2620; | 1128 | type |= D2620; |
1163 | } | 1129 | } |
1130 | break; | ||
1131 | case SYS_ATSC: | ||
1132 | /* The only ATSC firmware (at least on v2.7) is D2633 */ | ||
1133 | type |= ATSC | D2633; | ||
1134 | break; | ||
1135 | /* DVB-S and pure QAM (FE_QAM) are not supported */ | ||
1136 | default: | ||
1137 | return -EINVAL; | ||
1138 | } | ||
1139 | |||
1140 | if (bw <= 6000000) { | ||
1141 | type |= DTV6; | ||
1142 | priv->ctrl.vhfbw7 = 0; | ||
1143 | priv->ctrl.uhfbw8 = 0; | ||
1144 | } else if (bw <= 7000000) { | ||
1145 | if (c->frequency < 470000000) | ||
1146 | priv->ctrl.vhfbw7 = 1; | ||
1147 | else | ||
1148 | priv->ctrl.uhfbw8 = 0; | ||
1149 | type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV7; | ||
1150 | type |= F8MHZ; | ||
1151 | } else { | ||
1152 | if (c->frequency < 470000000) | ||
1153 | priv->ctrl.vhfbw7 = 0; | ||
1154 | else | ||
1155 | priv->ctrl.uhfbw8 = 1; | ||
1156 | type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV8; | ||
1157 | type |= F8MHZ; | ||
1164 | } | 1158 | } |
1165 | 1159 | ||
1166 | /* All S-code tables need a 200kHz shift */ | 1160 | /* All S-code tables need a 200kHz shift */ |
@@ -1185,7 +1179,7 @@ static int xc2028_set_params(struct dvb_frontend *fe, | |||
1185 | */ | 1179 | */ |
1186 | } | 1180 | } |
1187 | 1181 | ||
1188 | return generic_set_freq(fe, p->frequency, | 1182 | return generic_set_freq(fe, c->frequency, |
1189 | V4L2_TUNER_DIGITAL_TV, type, 0, demod); | 1183 | V4L2_TUNER_DIGITAL_TV, type, 0, demod); |
1190 | } | 1184 | } |
1191 | 1185 | ||