diff options
Diffstat (limited to 'drivers/media/dvb/frontends/af9013.c')
-rw-r--r-- | drivers/media/dvb/frontends/af9013.c | 251 |
1 files changed, 64 insertions, 187 deletions
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index dac917f7bb7f..e2a95c07bab4 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c | |||
@@ -42,6 +42,8 @@ struct af9013_state { | |||
42 | 42 | ||
43 | struct af9013_config config; | 43 | struct af9013_config config; |
44 | 44 | ||
45 | /* tuner/demod RF and IF AGC limits used for signal strength calc */ | ||
46 | u8 signal_strength_en, rf_50, rf_80, if_50, if_80; | ||
45 | u16 signal_strength; | 47 | u16 signal_strength; |
46 | u32 ber; | 48 | u32 ber; |
47 | u32 ucblocks; | 49 | u32 ucblocks; |
@@ -220,184 +222,37 @@ static u32 af913_div(u32 a, u32 b, u32 x) | |||
220 | 222 | ||
221 | static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw) | 223 | static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw) |
222 | { | 224 | { |
223 | int ret = 0; | 225 | int ret, i, j, found; |
224 | u8 i = 0; | ||
225 | u8 buf[24]; | ||
226 | u32 uninitialized_var(ns_coeff1_2048nu); | ||
227 | u32 uninitialized_var(ns_coeff1_8191nu); | ||
228 | u32 uninitialized_var(ns_coeff1_8192nu); | ||
229 | u32 uninitialized_var(ns_coeff1_8193nu); | ||
230 | u32 uninitialized_var(ns_coeff2_2k); | ||
231 | u32 uninitialized_var(ns_coeff2_8k); | ||
232 | |||
233 | deb_info("%s: adc_clock:%d bw:%d\n", __func__, | 226 | deb_info("%s: adc_clock:%d bw:%d\n", __func__, |
234 | state->config.adc_clock, bw); | 227 | state->config.adc_clock, bw); |
235 | 228 | ||
236 | switch (state->config.adc_clock) { | 229 | /* lookup coeff from table */ |
237 | case 28800: /* 28.800 MHz */ | 230 | for (i = 0, found = 0; i < ARRAY_SIZE(coeff_table); i++) { |
238 | switch (bw) { | 231 | if (coeff_table[i].adc_clock == state->config.adc_clock && |
239 | case BANDWIDTH_6_MHZ: | 232 | coeff_table[i].bw == bw) { |
240 | ns_coeff1_2048nu = 0x01e79e7a; | 233 | found = 1; |
241 | ns_coeff1_8191nu = 0x0079eb6e; | ||
242 | ns_coeff1_8192nu = 0x0079e79e; | ||
243 | ns_coeff1_8193nu = 0x0079e3cf; | ||
244 | ns_coeff2_2k = 0x00f3cf3d; | ||
245 | ns_coeff2_8k = 0x003cf3cf; | ||
246 | break; | ||
247 | case BANDWIDTH_7_MHZ: | ||
248 | ns_coeff1_2048nu = 0x0238e38e; | ||
249 | ns_coeff1_8191nu = 0x008e3d55; | ||
250 | ns_coeff1_8192nu = 0x008e38e4; | ||
251 | ns_coeff1_8193nu = 0x008e3472; | ||
252 | ns_coeff2_2k = 0x011c71c7; | ||
253 | ns_coeff2_8k = 0x00471c72; | ||
254 | break; | 234 | break; |
255 | case BANDWIDTH_8_MHZ: | ||
256 | ns_coeff1_2048nu = 0x028a28a3; | ||
257 | ns_coeff1_8191nu = 0x00a28f3d; | ||
258 | ns_coeff1_8192nu = 0x00a28a29; | ||
259 | ns_coeff1_8193nu = 0x00a28514; | ||
260 | ns_coeff2_2k = 0x01451451; | ||
261 | ns_coeff2_8k = 0x00514514; | ||
262 | break; | ||
263 | default: | ||
264 | ret = -EINVAL; | ||
265 | } | 235 | } |
266 | break; | ||
267 | case 20480: /* 20.480 MHz */ | ||
268 | switch (bw) { | ||
269 | case BANDWIDTH_6_MHZ: | ||
270 | ns_coeff1_2048nu = 0x02adb6dc; | ||
271 | ns_coeff1_8191nu = 0x00ab7313; | ||
272 | ns_coeff1_8192nu = 0x00ab6db7; | ||
273 | ns_coeff1_8193nu = 0x00ab685c; | ||
274 | ns_coeff2_2k = 0x0156db6e; | ||
275 | ns_coeff2_8k = 0x0055b6dc; | ||
276 | break; | ||
277 | case BANDWIDTH_7_MHZ: | ||
278 | ns_coeff1_2048nu = 0x03200001; | ||
279 | ns_coeff1_8191nu = 0x00c80640; | ||
280 | ns_coeff1_8192nu = 0x00c80000; | ||
281 | ns_coeff1_8193nu = 0x00c7f9c0; | ||
282 | ns_coeff2_2k = 0x01900000; | ||
283 | ns_coeff2_8k = 0x00640000; | ||
284 | break; | ||
285 | case BANDWIDTH_8_MHZ: | ||
286 | ns_coeff1_2048nu = 0x03924926; | ||
287 | ns_coeff1_8191nu = 0x00e4996e; | ||
288 | ns_coeff1_8192nu = 0x00e49249; | ||
289 | ns_coeff1_8193nu = 0x00e48b25; | ||
290 | ns_coeff2_2k = 0x01c92493; | ||
291 | ns_coeff2_8k = 0x00724925; | ||
292 | break; | ||
293 | default: | ||
294 | ret = -EINVAL; | ||
295 | } | ||
296 | break; | ||
297 | case 28000: /* 28.000 MHz */ | ||
298 | switch (bw) { | ||
299 | case BANDWIDTH_6_MHZ: | ||
300 | ns_coeff1_2048nu = 0x01f58d10; | ||
301 | ns_coeff1_8191nu = 0x007d672f; | ||
302 | ns_coeff1_8192nu = 0x007d6344; | ||
303 | ns_coeff1_8193nu = 0x007d5f59; | ||
304 | ns_coeff2_2k = 0x00fac688; | ||
305 | ns_coeff2_8k = 0x003eb1a2; | ||
306 | break; | ||
307 | case BANDWIDTH_7_MHZ: | ||
308 | ns_coeff1_2048nu = 0x02492492; | ||
309 | ns_coeff1_8191nu = 0x00924db7; | ||
310 | ns_coeff1_8192nu = 0x00924925; | ||
311 | ns_coeff1_8193nu = 0x00924492; | ||
312 | ns_coeff2_2k = 0x01249249; | ||
313 | ns_coeff2_8k = 0x00492492; | ||
314 | break; | ||
315 | case BANDWIDTH_8_MHZ: | ||
316 | ns_coeff1_2048nu = 0x029cbc15; | ||
317 | ns_coeff1_8191nu = 0x00a7343f; | ||
318 | ns_coeff1_8192nu = 0x00a72f05; | ||
319 | ns_coeff1_8193nu = 0x00a729cc; | ||
320 | ns_coeff2_2k = 0x014e5e0a; | ||
321 | ns_coeff2_8k = 0x00539783; | ||
322 | break; | ||
323 | default: | ||
324 | ret = -EINVAL; | ||
325 | } | ||
326 | break; | ||
327 | case 25000: /* 25.000 MHz */ | ||
328 | switch (bw) { | ||
329 | case BANDWIDTH_6_MHZ: | ||
330 | ns_coeff1_2048nu = 0x0231bcb5; | ||
331 | ns_coeff1_8191nu = 0x008c7391; | ||
332 | ns_coeff1_8192nu = 0x008c6f2d; | ||
333 | ns_coeff1_8193nu = 0x008c6aca; | ||
334 | ns_coeff2_2k = 0x0118de5b; | ||
335 | ns_coeff2_8k = 0x00463797; | ||
336 | break; | ||
337 | case BANDWIDTH_7_MHZ: | ||
338 | ns_coeff1_2048nu = 0x028f5c29; | ||
339 | ns_coeff1_8191nu = 0x00a3dc29; | ||
340 | ns_coeff1_8192nu = 0x00a3d70a; | ||
341 | ns_coeff1_8193nu = 0x00a3d1ec; | ||
342 | ns_coeff2_2k = 0x0147ae14; | ||
343 | ns_coeff2_8k = 0x0051eb85; | ||
344 | break; | ||
345 | case BANDWIDTH_8_MHZ: | ||
346 | ns_coeff1_2048nu = 0x02ecfb9d; | ||
347 | ns_coeff1_8191nu = 0x00bb44c1; | ||
348 | ns_coeff1_8192nu = 0x00bb3ee7; | ||
349 | ns_coeff1_8193nu = 0x00bb390d; | ||
350 | ns_coeff2_2k = 0x01767dce; | ||
351 | ns_coeff2_8k = 0x005d9f74; | ||
352 | break; | ||
353 | default: | ||
354 | ret = -EINVAL; | ||
355 | } | ||
356 | break; | ||
357 | default: | ||
358 | err("invalid xtal"); | ||
359 | return -EINVAL; | ||
360 | } | 236 | } |
361 | if (ret) { | 237 | |
362 | err("invalid bandwidth"); | 238 | if (!found) { |
363 | return ret; | 239 | err("invalid bw or clock"); |
240 | ret = -EINVAL; | ||
241 | goto error; | ||
364 | } | 242 | } |
365 | 243 | ||
366 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x03000000) >> 24); | 244 | deb_info("%s: coeff: ", __func__); |
367 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x00ff0000) >> 16); | 245 | debug_dump(coeff_table[i].val, sizeof(coeff_table[i].val), deb_info); |
368 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x0000ff00) >> 8); | ||
369 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x000000ff)); | ||
370 | buf[i++] = (u8) ((ns_coeff2_2k & 0x01c00000) >> 22); | ||
371 | buf[i++] = (u8) ((ns_coeff2_2k & 0x003fc000) >> 14); | ||
372 | buf[i++] = (u8) ((ns_coeff2_2k & 0x00003fc0) >> 6); | ||
373 | buf[i++] = (u8) ((ns_coeff2_2k & 0x0000003f)); | ||
374 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x03000000) >> 24); | ||
375 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x00ffc000) >> 16); | ||
376 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x0000ff00) >> 8); | ||
377 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x000000ff)); | ||
378 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x03000000) >> 24); | ||
379 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x00ffc000) >> 16); | ||
380 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x0000ff00) >> 8); | ||
381 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x000000ff)); | ||
382 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x03000000) >> 24); | ||
383 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x00ffc000) >> 16); | ||
384 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x0000ff00) >> 8); | ||
385 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x000000ff)); | ||
386 | buf[i++] = (u8) ((ns_coeff2_8k & 0x01c00000) >> 22); | ||
387 | buf[i++] = (u8) ((ns_coeff2_8k & 0x003fc000) >> 14); | ||
388 | buf[i++] = (u8) ((ns_coeff2_8k & 0x00003fc0) >> 6); | ||
389 | buf[i++] = (u8) ((ns_coeff2_8k & 0x0000003f)); | ||
390 | |||
391 | deb_info("%s: coeff:", __func__); | ||
392 | debug_dump(buf, sizeof(buf), deb_info); | ||
393 | 246 | ||
394 | /* program */ | 247 | /* program */ |
395 | for (i = 0; i < sizeof(buf); i++) { | 248 | for (j = 0; j < sizeof(coeff_table[i].val); j++) { |
396 | ret = af9013_write_reg(state, 0xae00 + i, buf[i]); | 249 | ret = af9013_write_reg(state, 0xae00 + j, |
250 | coeff_table[i].val[j]); | ||
397 | if (ret) | 251 | if (ret) |
398 | break; | 252 | break; |
399 | } | 253 | } |
400 | 254 | ||
255 | error: | ||
401 | return ret; | 256 | return ret; |
402 | } | 257 | } |
403 | 258 | ||
@@ -486,6 +341,19 @@ static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) | |||
486 | if_sample_freq = 4300000; /* 4.3 MHz */ | 341 | if_sample_freq = 4300000; /* 4.3 MHz */ |
487 | break; | 342 | break; |
488 | } | 343 | } |
344 | } else if (state->config.tuner == AF9013_TUNER_TDA18218) { | ||
345 | switch (bw) { | ||
346 | case BANDWIDTH_6_MHZ: | ||
347 | if_sample_freq = 3000000; /* 3 MHz */ | ||
348 | break; | ||
349 | case BANDWIDTH_7_MHZ: | ||
350 | if_sample_freq = 3500000; /* 3.5 MHz */ | ||
351 | break; | ||
352 | case BANDWIDTH_8_MHZ: | ||
353 | default: | ||
354 | if_sample_freq = 4000000; /* 4 MHz */ | ||
355 | break; | ||
356 | } | ||
489 | } | 357 | } |
490 | 358 | ||
491 | while (if_sample_freq > (adc_freq / 2)) | 359 | while (if_sample_freq > (adc_freq / 2)) |
@@ -1097,45 +965,31 @@ static int af9013_update_signal_strength(struct dvb_frontend *fe) | |||
1097 | { | 965 | { |
1098 | struct af9013_state *state = fe->demodulator_priv; | 966 | struct af9013_state *state = fe->demodulator_priv; |
1099 | int ret; | 967 | int ret; |
1100 | u8 tmp0; | 968 | u8 rf_gain, if_gain; |
1101 | u8 rf_gain, rf_50, rf_80, if_gain, if_50, if_80; | ||
1102 | int signal_strength; | 969 | int signal_strength; |
1103 | 970 | ||
1104 | deb_info("%s\n", __func__); | 971 | deb_info("%s\n", __func__); |
1105 | 972 | ||
1106 | state->signal_strength = 0; | 973 | if (state->signal_strength_en) { |
1107 | |||
1108 | ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, &tmp0); | ||
1109 | if (ret) | ||
1110 | goto error; | ||
1111 | if (tmp0) { | ||
1112 | ret = af9013_read_reg(state, 0x9bbd, &rf_50); | ||
1113 | if (ret) | ||
1114 | goto error; | ||
1115 | ret = af9013_read_reg(state, 0x9bd0, &rf_80); | ||
1116 | if (ret) | ||
1117 | goto error; | ||
1118 | ret = af9013_read_reg(state, 0x9be2, &if_50); | ||
1119 | if (ret) | ||
1120 | goto error; | ||
1121 | ret = af9013_read_reg(state, 0x9be4, &if_80); | ||
1122 | if (ret) | ||
1123 | goto error; | ||
1124 | ret = af9013_read_reg(state, 0xd07c, &rf_gain); | 974 | ret = af9013_read_reg(state, 0xd07c, &rf_gain); |
1125 | if (ret) | 975 | if (ret) |
1126 | goto error; | 976 | goto error; |
1127 | ret = af9013_read_reg(state, 0xd07d, &if_gain); | 977 | ret = af9013_read_reg(state, 0xd07d, &if_gain); |
1128 | if (ret) | 978 | if (ret) |
1129 | goto error; | 979 | goto error; |
1130 | signal_strength = (0xffff / (9 * (rf_50 + if_50) - \ | 980 | signal_strength = (0xffff / \ |
1131 | 11 * (rf_80 + if_80))) * (10 * (rf_gain + if_gain) - \ | 981 | (9 * (state->rf_50 + state->if_50) - \ |
1132 | 11 * (rf_80 + if_80)); | 982 | 11 * (state->rf_80 + state->if_80))) * \ |
983 | (10 * (rf_gain + if_gain) - \ | ||
984 | 11 * (state->rf_80 + state->if_80)); | ||
1133 | if (signal_strength < 0) | 985 | if (signal_strength < 0) |
1134 | signal_strength = 0; | 986 | signal_strength = 0; |
1135 | else if (signal_strength > 0xffff) | 987 | else if (signal_strength > 0xffff) |
1136 | signal_strength = 0xffff; | 988 | signal_strength = 0xffff; |
1137 | 989 | ||
1138 | state->signal_strength = signal_strength; | 990 | state->signal_strength = signal_strength; |
991 | } else { | ||
992 | state->signal_strength = 0; | ||
1139 | } | 993 | } |
1140 | 994 | ||
1141 | error: | 995 | error: |
@@ -1368,6 +1222,7 @@ static int af9013_init(struct dvb_frontend *fe) | |||
1368 | break; | 1222 | break; |
1369 | case AF9013_TUNER_MXL5005D: | 1223 | case AF9013_TUNER_MXL5005D: |
1370 | case AF9013_TUNER_MXL5005R: | 1224 | case AF9013_TUNER_MXL5005R: |
1225 | case AF9013_TUNER_MXL5007T: | ||
1371 | len = ARRAY_SIZE(tuner_init_mxl5005); | 1226 | len = ARRAY_SIZE(tuner_init_mxl5005); |
1372 | init = tuner_init_mxl5005; | 1227 | init = tuner_init_mxl5005; |
1373 | break; | 1228 | break; |
@@ -1393,6 +1248,7 @@ static int af9013_init(struct dvb_frontend *fe) | |||
1393 | init = tuner_init_mt2060_2; | 1248 | init = tuner_init_mt2060_2; |
1394 | break; | 1249 | break; |
1395 | case AF9013_TUNER_TDA18271: | 1250 | case AF9013_TUNER_TDA18271: |
1251 | case AF9013_TUNER_TDA18218: | ||
1396 | len = ARRAY_SIZE(tuner_init_tda18271); | 1252 | len = ARRAY_SIZE(tuner_init_tda18271); |
1397 | init = tuner_init_tda18271; | 1253 | init = tuner_init_tda18271; |
1398 | break; | 1254 | break; |
@@ -1438,6 +1294,27 @@ static int af9013_init(struct dvb_frontend *fe) | |||
1438 | if (ret) | 1294 | if (ret) |
1439 | goto error; | 1295 | goto error; |
1440 | 1296 | ||
1297 | /* read values needed for signal strength calculation */ | ||
1298 | ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, | ||
1299 | &state->signal_strength_en); | ||
1300 | if (ret) | ||
1301 | goto error; | ||
1302 | |||
1303 | if (state->signal_strength_en) { | ||
1304 | ret = af9013_read_reg(state, 0x9bbd, &state->rf_50); | ||
1305 | if (ret) | ||
1306 | goto error; | ||
1307 | ret = af9013_read_reg(state, 0x9bd0, &state->rf_80); | ||
1308 | if (ret) | ||
1309 | goto error; | ||
1310 | ret = af9013_read_reg(state, 0x9be2, &state->if_50); | ||
1311 | if (ret) | ||
1312 | goto error; | ||
1313 | ret = af9013_read_reg(state, 0x9be4, &state->if_80); | ||
1314 | if (ret) | ||
1315 | goto error; | ||
1316 | } | ||
1317 | |||
1441 | error: | 1318 | error: |
1442 | return ret; | 1319 | return ret; |
1443 | } | 1320 | } |