diff options
author | Manu Abraham <manu@kromtek.com> | 2005-07-07 20:57:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-07 21:23:56 -0400 |
commit | 7d53421c6adce47d067b834c605daeafe1ff9356 (patch) | |
tree | 1eb9e34d36f79bb9cd41676b8636445c56a0e2e8 /drivers/media/dvb/bt8xx/dst.c | |
parent | 64221be7b9006338e4a45228f013e467ee4bf045 (diff) |
[PATCH] dvb: Twinhan DST: frontend fixes
o Make the inversion setting specific, ie, only for the 200103A DVB-S
This should not be flagged on other cards.
o Make the frequency setting card specific
o Make the bandwidth setting generic such that it supports more DVB-T cards
o Set QAM size for DVB-C cards that do not autodetect QAM size
o Fix a bug that caused the polarization not to be set.
Set polarization for cards that do not autodetect polarization
o Fix a bogus frontend signal lock, that caused a tuning delay as well.
o Make the Symbolrate setting card specific
Signed-off-by: Manu Abraham <manu@kromtek.com>
Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media/dvb/bt8xx/dst.c')
-rw-r--r-- | drivers/media/dvb/bt8xx/dst.c | 227 |
1 files changed, 143 insertions, 84 deletions
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 1339912c308b..1f97c37fe9a6 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -258,10 +258,10 @@ int write_dst(struct dst_state *state, u8 *data, u8 len) | |||
258 | if (debug && (verbose > 4)) { | 258 | if (debug && (verbose > 4)) { |
259 | u8 i; | 259 | u8 i; |
260 | if (verbose > 4) { | 260 | if (verbose > 4) { |
261 | dprintk("%s writing", __FUNCTION__); | 261 | dprintk("%s writing [ ", __FUNCTION__); |
262 | for (i = 0; i < len; i++) | 262 | for (i = 0; i < len; i++) |
263 | dprintk(" %02x", data[i]); | 263 | dprintk("%02x ", data[i]); |
264 | dprintk("\n"); | 264 | dprintk("]\n"); |
265 | } | 265 | } |
266 | } | 266 | } |
267 | for (cnt = 0; cnt < 2; cnt++) { | 267 | for (cnt = 0; cnt < 2; cnt++) { |
@@ -320,10 +320,29 @@ int read_dst(struct dst_state *state, u8 * ret, u8 len) | |||
320 | } | 320 | } |
321 | EXPORT_SYMBOL(read_dst); | 321 | EXPORT_SYMBOL(read_dst); |
322 | 322 | ||
323 | static int dst_set_freq(struct dst_state *state, u32 freq) | 323 | static int dst_set_polarization(struct dst_state *state) |
324 | { | 324 | { |
325 | u8 *val; | 325 | switch (state->voltage) { |
326 | case SEC_VOLTAGE_13: // vertical | ||
327 | printk("%s: Polarization=[Vertical]\n", __FUNCTION__); | ||
328 | state->tx_tuna[8] |= 0x40; //1 | ||
329 | break; | ||
330 | |||
331 | case SEC_VOLTAGE_18: // horizontal | ||
332 | printk("%s: Polarization=[Horizontal]\n", __FUNCTION__); | ||
333 | state->tx_tuna[8] =~ 0x40; // 0 | ||
334 | break; | ||
326 | 335 | ||
336 | case SEC_VOLTAGE_OFF: | ||
337 | |||
338 | break; | ||
339 | } | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static int dst_set_freq(struct dst_state *state, u32 freq) | ||
345 | { | ||
327 | state->frequency = freq; | 346 | state->frequency = freq; |
328 | if (debug > 4) | 347 | if (debug > 4) |
329 | dprintk("%s: set Frequency %u\n", __FUNCTION__, freq); | 348 | dprintk("%s: set Frequency %u\n", __FUNCTION__, freq); |
@@ -332,46 +351,30 @@ static int dst_set_freq(struct dst_state *state, u32 freq) | |||
332 | freq = freq / 1000; | 351 | freq = freq / 1000; |
333 | if (freq < 950 || freq > 2150) | 352 | if (freq < 950 || freq > 2150) |
334 | return -EINVAL; | 353 | return -EINVAL; |
335 | val = &state->tx_tuna[0]; | 354 | |
336 | val[2] = (freq >> 8) & 0x7f; | 355 | state->tx_tuna[2] = (freq >> 8); |
337 | val[3] = (u8) freq; | 356 | state->tx_tuna[3] = (u8) freq; |
338 | val[4] = 1; | 357 | state->tx_tuna[4] = 0x01; |
339 | val[8] &= ~4; | 358 | state->tx_tuna[8] &= ~0x04; |
340 | if (freq < 1531) | 359 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { |
341 | val[8] |= 4; | 360 | if (freq < 1531) |
361 | state->tx_tuna[8] |= 0x04; | ||
362 | } | ||
363 | |||
342 | } else if (state->dst_type == DST_TYPE_IS_TERR) { | 364 | } else if (state->dst_type == DST_TYPE_IS_TERR) { |
343 | freq = freq / 1000; | 365 | freq = freq / 1000; |
344 | if (freq < 137000 || freq > 858000) | 366 | if (freq < 137000 || freq > 858000) |
345 | return -EINVAL; | 367 | return -EINVAL; |
346 | val = &state->tx_tuna[0]; | ||
347 | val[2] = (freq >> 16) & 0xff; | ||
348 | val[3] = (freq >> 8) & 0xff; | ||
349 | val[4] = (u8) freq; | ||
350 | val[5] = 0; | ||
351 | switch (state->bandwidth) { | ||
352 | case BANDWIDTH_6_MHZ: | ||
353 | val[6] = 6; | ||
354 | break; | ||
355 | |||
356 | case BANDWIDTH_7_MHZ: | ||
357 | case BANDWIDTH_AUTO: | ||
358 | val[6] = 7; | ||
359 | break; | ||
360 | 368 | ||
361 | case BANDWIDTH_8_MHZ: | 369 | state->tx_tuna[2] = (freq >> 16) & 0xff; |
362 | val[6] = 8; | 370 | state->tx_tuna[3] = (freq >> 8) & 0xff; |
363 | break; | 371 | state->tx_tuna[4] = (u8) freq; |
364 | } | ||
365 | 372 | ||
366 | val[7] = 0; | ||
367 | val[8] = 0; | ||
368 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { | 373 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { |
369 | /* guess till will get one */ | 374 | state->tx_tuna[2] = (freq >> 16) & 0xff; |
370 | freq = freq / 1000; | 375 | state->tx_tuna[3] = (freq >> 8) & 0xff; |
371 | val = &state->tx_tuna[0]; | 376 | state->tx_tuna[4] = (u8) freq; |
372 | val[2] = (freq >> 16) & 0xff; | 377 | |
373 | val[3] = (freq >> 8) & 0xff; | ||
374 | val[4] = (u8) freq; | ||
375 | } else | 378 | } else |
376 | return -EINVAL; | 379 | return -EINVAL; |
377 | return 0; | 380 | return 0; |
@@ -379,51 +382,58 @@ static int dst_set_freq(struct dst_state *state, u32 freq) | |||
379 | 382 | ||
380 | static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth) | 383 | static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth) |
381 | { | 384 | { |
382 | u8 *val; | ||
383 | |||
384 | state->bandwidth = bandwidth; | 385 | state->bandwidth = bandwidth; |
385 | 386 | ||
386 | if (state->dst_type != DST_TYPE_IS_TERR) | 387 | if (state->dst_type != DST_TYPE_IS_TERR) |
387 | return 0; | 388 | return 0; |
388 | 389 | ||
389 | val = &state->tx_tuna[0]; | ||
390 | switch (bandwidth) { | 390 | switch (bandwidth) { |
391 | case BANDWIDTH_6_MHZ: | 391 | case BANDWIDTH_6_MHZ: |
392 | val[6] = 6; | 392 | if (state->dst_hw_cap & DST_TYPE_HAS_CA) |
393 | break; | 393 | state->tx_tuna[7] = 0x06; |
394 | else { | ||
395 | state->tx_tuna[6] = 0x06; | ||
396 | state->tx_tuna[7] = 0x00; | ||
397 | } | ||
398 | break; | ||
394 | 399 | ||
395 | case BANDWIDTH_7_MHZ: | 400 | case BANDWIDTH_7_MHZ: |
396 | val[6] = 7; | 401 | if (state->dst_hw_cap & DST_TYPE_HAS_CA) |
397 | break; | 402 | state->tx_tuna[7] = 0x07; |
403 | else { | ||
404 | state->tx_tuna[6] = 0x07; | ||
405 | state->tx_tuna[7] = 0x00; | ||
406 | } | ||
407 | break; | ||
398 | 408 | ||
399 | case BANDWIDTH_8_MHZ: | 409 | case BANDWIDTH_8_MHZ: |
400 | val[6] = 8; | 410 | if (state->dst_hw_cap & DST_TYPE_HAS_CA) |
401 | break; | 411 | state->tx_tuna[7] = 0x08; |
412 | else { | ||
413 | state->tx_tuna[6] = 0x08; | ||
414 | state->tx_tuna[7] = 0x00; | ||
415 | } | ||
416 | break; | ||
402 | 417 | ||
403 | default: | 418 | default: |
404 | return -EINVAL; | 419 | return -EINVAL; |
405 | } | 420 | } |
406 | return 0; | 421 | return 0; |
407 | } | 422 | } |
408 | 423 | ||
409 | static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion) | 424 | static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion) |
410 | { | 425 | { |
411 | u8 *val; | ||
412 | |||
413 | state->inversion = inversion; | 426 | state->inversion = inversion; |
414 | |||
415 | val = &state->tx_tuna[0]; | ||
416 | |||
417 | val[8] &= ~0x80; | ||
418 | |||
419 | switch (inversion) { | 427 | switch (inversion) { |
420 | case INVERSION_OFF: | 428 | case INVERSION_OFF: // Inversion = Normal |
421 | break; | 429 | state->tx_tuna[8] &= ~0x80; |
422 | case INVERSION_ON: | 430 | break; |
423 | val[8] |= 0x80; | 431 | |
424 | break; | 432 | case INVERSION_ON: |
425 | default: | 433 | state->tx_tuna[8] |= 0x80; |
426 | return -EINVAL; | 434 | break; |
435 | default: | ||
436 | return -EINVAL; | ||
427 | } | 437 | } |
428 | return 0; | 438 | return 0; |
429 | } | 439 | } |
@@ -478,6 +488,52 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate) | |||
478 | return 0; | 488 | return 0; |
479 | } | 489 | } |
480 | 490 | ||
491 | |||
492 | static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) | ||
493 | { | ||
494 | if (state->dst_type != DST_TYPE_IS_CABLE) | ||
495 | return 0; | ||
496 | |||
497 | state->modulation = modulation; | ||
498 | switch (modulation) { | ||
499 | case QAM_16: | ||
500 | state->tx_tuna[8] = 0x10; | ||
501 | break; | ||
502 | |||
503 | case QAM_32: | ||
504 | state->tx_tuna[8] = 0x20; | ||
505 | break; | ||
506 | |||
507 | case QAM_64: | ||
508 | state->tx_tuna[8] = 0x40; | ||
509 | break; | ||
510 | |||
511 | case QAM_128: | ||
512 | state->tx_tuna[8] = 0x80; | ||
513 | break; | ||
514 | |||
515 | case QAM_256: | ||
516 | state->tx_tuna[8] = 0x00; | ||
517 | break; | ||
518 | |||
519 | case QPSK: | ||
520 | case QAM_AUTO: | ||
521 | case VSB_8: | ||
522 | case VSB_16: | ||
523 | default: | ||
524 | return -EINVAL; | ||
525 | |||
526 | } | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | static fe_modulation_t dst_get_modulation(struct dst_state *state) | ||
532 | { | ||
533 | return state->modulation; | ||
534 | } | ||
535 | |||
536 | |||
481 | u8 dst_check_sum(u8 * buf, u32 len) | 537 | u8 dst_check_sum(u8 * buf, u32 len) |
482 | { | 538 | { |
483 | u32 i; | 539 | u32 i; |
@@ -577,7 +633,7 @@ struct dst_types dst_tlist[] = { | |||
577 | .device_id = "200103A", | 633 | .device_id = "200103A", |
578 | .offset = 0, | 634 | .offset = 0, |
579 | .dst_type = DST_TYPE_IS_SAT, | 635 | .dst_type = DST_TYPE_IS_SAT, |
580 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | 636 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, |
581 | .dst_feature = 0 | 637 | .dst_feature = 0 |
582 | }, /* obsolete */ | 638 | }, /* obsolete */ |
583 | 639 | ||
@@ -626,7 +682,7 @@ struct dst_types dst_tlist[] = { | |||
626 | .device_id = "DSTMCI", | 682 | .device_id = "DSTMCI", |
627 | .offset = 1, | 683 | .offset = 1, |
628 | .dst_type = DST_TYPE_IS_SAT, | 684 | .dst_type = DST_TYPE_IS_SAT, |
629 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, | 685 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT, |
630 | .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | 686 | .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 |
631 | | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC | 687 | | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC |
632 | }, | 688 | }, |
@@ -872,7 +928,7 @@ static int dst_get_signal(struct dst_state* state) | |||
872 | { | 928 | { |
873 | int retval; | 929 | int retval; |
874 | u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb }; | 930 | u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb }; |
875 | 931 | printk("%s: Getting Signal strength and other parameters !!!!!!!!\n", __FUNCTION__); | |
876 | if ((state->diseq_flags & ATTEMPT_TUNE) == 0) { | 932 | if ((state->diseq_flags & ATTEMPT_TUNE) == 0) { |
877 | state->decode_lock = state->decode_strength = state->decode_snr = 0; | 933 | state->decode_lock = state->decode_strength = state->decode_snr = 0; |
878 | return 0; | 934 | return 0; |
@@ -954,15 +1010,8 @@ static int dst_get_tuna(struct dst_state* state) | |||
954 | state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; | 1010 | state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; |
955 | 1011 | ||
956 | state->decode_lock = 1; | 1012 | state->decode_lock = 1; |
957 | /* | ||
958 | dst->decode_n1 = (dst->rx_tuna[4] << 8) + | ||
959 | (dst->rx_tuna[5]); | ||
960 | |||
961 | dst->decode_n2 = (dst->rx_tuna[8] << 8) + | ||
962 | (dst->rx_tuna[7]); | ||
963 | */ | ||
964 | state->diseq_flags |= HAS_LOCK; | 1013 | state->diseq_flags |= HAS_LOCK; |
965 | /* dst->cur_jiff = jiffies; */ | 1014 | |
966 | return 1; | 1015 | return 1; |
967 | } | 1016 | } |
968 | 1017 | ||
@@ -1145,7 +1194,8 @@ static int dst_init(struct dvb_frontend* fe) | |||
1145 | static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; | 1194 | static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; |
1146 | static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; | 1195 | static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; |
1147 | static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; | 1196 | static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; |
1148 | state->inversion = INVERSION_ON; | 1197 | // state->inversion = INVERSION_ON; |
1198 | state->inversion = INVERSION_OFF; | ||
1149 | state->voltage = SEC_VOLTAGE_13; | 1199 | state->voltage = SEC_VOLTAGE_13; |
1150 | state->tone = SEC_TONE_OFF; | 1200 | state->tone = SEC_TONE_OFF; |
1151 | state->symbol_rate = 29473000; | 1201 | state->symbol_rate = 29473000; |
@@ -1174,7 +1224,7 @@ static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
1174 | 1224 | ||
1175 | *status = 0; | 1225 | *status = 0; |
1176 | if (state->diseq_flags & HAS_LOCK) { | 1226 | if (state->diseq_flags & HAS_LOCK) { |
1177 | dst_get_signal(state); | 1227 | // dst_get_signal(state); // don't require(?) to ask MCU |
1178 | if (state->decode_lock) | 1228 | if (state->decode_lock) |
1179 | *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI; | 1229 | *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI; |
1180 | } | 1230 | } |
@@ -1208,20 +1258,25 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
1208 | 1258 | ||
1209 | dst_set_freq(state, p->frequency); | 1259 | dst_set_freq(state, p->frequency); |
1210 | if (verbose > 4) | 1260 | if (verbose > 4) |
1211 | dprintk("Set Frequency = [%d]\n", p->frequency); | 1261 | dprintk("Set Frequency=[%d]\n", p->frequency); |
1212 | 1262 | ||
1213 | dst_set_inversion(state, p->inversion); | 1263 | // dst_set_inversion(state, p->inversion); |
1214 | if (state->dst_type == DST_TYPE_IS_SAT) { | 1264 | if (state->dst_type == DST_TYPE_IS_SAT) { |
1265 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) | ||
1266 | dst_set_inversion(state, p->inversion); | ||
1267 | |||
1215 | dst_set_fec(state, p->u.qpsk.fec_inner); | 1268 | dst_set_fec(state, p->u.qpsk.fec_inner); |
1216 | dst_set_symbolrate(state, p->u.qpsk.symbol_rate); | 1269 | dst_set_symbolrate(state, p->u.qpsk.symbol_rate); |
1270 | dst_set_polarization(state); | ||
1217 | if (verbose > 4) | 1271 | if (verbose > 4) |
1218 | dprintk("Set Symbolrate = [%d]\n", p->u.qpsk.symbol_rate); | 1272 | dprintk("Set Symbolrate=[%d]\n", p->u.qpsk.symbol_rate); |
1219 | 1273 | ||
1220 | } else if (state->dst_type == DST_TYPE_IS_TERR) { | 1274 | } else if (state->dst_type == DST_TYPE_IS_TERR) { |
1221 | dst_set_bandwidth(state, p->u.ofdm.bandwidth); | 1275 | dst_set_bandwidth(state, p->u.ofdm.bandwidth); |
1222 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { | 1276 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { |
1223 | dst_set_fec(state, p->u.qam.fec_inner); | 1277 | dst_set_fec(state, p->u.qam.fec_inner); |
1224 | dst_set_symbolrate(state, p->u.qam.symbol_rate); | 1278 | dst_set_symbolrate(state, p->u.qam.symbol_rate); |
1279 | dst_set_modulation(state, p->u.qam.modulation); | ||
1225 | } | 1280 | } |
1226 | dst_write_tuna(fe); | 1281 | dst_write_tuna(fe); |
1227 | 1282 | ||
@@ -1233,8 +1288,11 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
1233 | struct dst_state* state = fe->demodulator_priv; | 1288 | struct dst_state* state = fe->demodulator_priv; |
1234 | 1289 | ||
1235 | p->frequency = state->decode_freq; | 1290 | p->frequency = state->decode_freq; |
1236 | p->inversion = state->inversion; | 1291 | // p->inversion = state->inversion; |
1237 | if (state->dst_type == DST_TYPE_IS_SAT) { | 1292 | if (state->dst_type == DST_TYPE_IS_SAT) { |
1293 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) | ||
1294 | p->inversion = state->inversion; | ||
1295 | |||
1238 | p->u.qpsk.symbol_rate = state->symbol_rate; | 1296 | p->u.qpsk.symbol_rate = state->symbol_rate; |
1239 | p->u.qpsk.fec_inner = dst_get_fec(state); | 1297 | p->u.qpsk.fec_inner = dst_get_fec(state); |
1240 | } else if (state->dst_type == DST_TYPE_IS_TERR) { | 1298 | } else if (state->dst_type == DST_TYPE_IS_TERR) { |
@@ -1242,7 +1300,8 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
1242 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { | 1300 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { |
1243 | p->u.qam.symbol_rate = state->symbol_rate; | 1301 | p->u.qam.symbol_rate = state->symbol_rate; |
1244 | p->u.qam.fec_inner = dst_get_fec(state); | 1302 | p->u.qam.fec_inner = dst_get_fec(state); |
1245 | p->u.qam.modulation = QAM_AUTO; | 1303 | // p->u.qam.modulation = QAM_AUTO; |
1304 | p->u.qam.modulation = dst_get_modulation(state); | ||
1246 | } | 1305 | } |
1247 | 1306 | ||
1248 | return 0; | 1307 | return 0; |