diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-09 16:03:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-09 16:03:58 -0500 |
commit | f17578decc40df8fceff82b106582e30bdfb3189 (patch) | |
tree | 911a435a2094ac03ae649f020237674224e4124a /drivers/media/dvb | |
parent | 682e852e2638ed0aff84aa51181c9e5d2f939562 (diff) | |
parent | cec418346e5a411e907293aba7cc21ac53c95834 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
Diffstat (limited to 'drivers/media/dvb')
73 files changed, 2548 insertions, 662 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 21a9045b3ef6..0b940e152b79 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
@@ -298,7 +298,7 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir | |||
298 | } | 298 | } |
299 | 299 | ||
300 | static int lgdt3303_pll_set(struct dvb_frontend* fe, | 300 | static int lgdt3303_pll_set(struct dvb_frontend* fe, |
301 | struct dvb_frontend_parameters* params) | 301 | struct dvb_frontend_parameters* params) |
302 | { | 302 | { |
303 | struct flexcop_device *fc = fe->dvb->priv; | 303 | struct flexcop_device *fc = fe->dvb->priv; |
304 | u8 buf[4]; | 304 | u8 buf[4]; |
@@ -485,12 +485,16 @@ static struct stv0297_config alps_tdee4_stv0297_config = { | |||
485 | /* try to figure out the frontend, each card/box can have on of the following list */ | 485 | /* try to figure out the frontend, each card/box can have on of the following list */ |
486 | int flexcop_frontend_init(struct flexcop_device *fc) | 486 | int flexcop_frontend_init(struct flexcop_device *fc) |
487 | { | 487 | { |
488 | struct dvb_frontend_ops *ops; | ||
489 | |||
488 | /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ | 490 | /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ |
489 | if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { | 491 | if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { |
490 | fc->fe->ops->set_voltage = flexcop_set_voltage; | 492 | ops = fc->fe->ops; |
493 | |||
494 | ops->set_voltage = flexcop_set_voltage; | ||
491 | 495 | ||
492 | fc->fe_sleep = fc->fe->ops->sleep; | 496 | fc->fe_sleep = ops->sleep; |
493 | fc->fe->ops->sleep = flexcop_sleep; | 497 | ops->sleep = flexcop_sleep; |
494 | 498 | ||
495 | fc->dev_type = FC_SKY; | 499 | fc->dev_type = FC_SKY; |
496 | info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address); | 500 | info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address); |
@@ -522,15 +526,17 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
522 | } else | 526 | } else |
523 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ | 527 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ |
524 | if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { | 528 | if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { |
525 | fc->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; | 529 | ops = fc->fe->ops; |
526 | fc->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst; | 530 | |
527 | fc->fe->ops->set_tone = flexcop_set_tone; | 531 | ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; |
528 | fc->fe->ops->set_voltage = flexcop_set_voltage; | 532 | ops->diseqc_send_burst = flexcop_diseqc_send_burst; |
533 | ops->set_tone = flexcop_set_tone; | ||
534 | ops->set_voltage = flexcop_set_voltage; | ||
529 | 535 | ||
530 | fc->fe_sleep = fc->fe->ops->sleep; | 536 | fc->fe_sleep = ops->sleep; |
531 | fc->fe->ops->sleep = flexcop_sleep; | 537 | ops->sleep = flexcop_sleep; |
532 | 538 | ||
533 | fc->dev_type = FC_SKY_OLD; | 539 | fc->dev_type = FC_SKY_OLD; |
534 | info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address); | 540 | info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address); |
535 | } | 541 | } |
536 | 542 | ||
@@ -540,8 +546,9 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
540 | } else { | 546 | } else { |
541 | if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { | 547 | if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { |
542 | err("frontend registration failed!"); | 548 | err("frontend registration failed!"); |
543 | if (fc->fe->ops->release != NULL) | 549 | ops = fc->fe->ops; |
544 | fc->fe->ops->release(fc->fe); | 550 | if (ops->release != NULL) |
551 | ops->release(fc->fe); | ||
545 | fc->fe = NULL; | 552 | fc->fe = NULL; |
546 | return -EINVAL; | 553 | return -EINVAL; |
547 | } | 554 | } |
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h index 23cc6431e2b8..3153f9513c63 100644 --- a/drivers/media/dvb/b2c2/flexcop-reg.h +++ b/drivers/media/dvb/b2c2/flexcop-reg.h | |||
@@ -39,11 +39,13 @@ extern const char *flexcop_device_names[]; | |||
39 | /* FlexCop IBI Registers */ | 39 | /* FlexCop IBI Registers */ |
40 | #if defined(__LITTLE_ENDIAN) | 40 | #if defined(__LITTLE_ENDIAN) |
41 | #include "flexcop_ibi_value_le.h" | 41 | #include "flexcop_ibi_value_le.h" |
42 | #elif defined(__BIG_ENDIAN) | 42 | #else |
43 | #if defined(__BIG_ENDIAN) | ||
43 | #include "flexcop_ibi_value_be.h" | 44 | #include "flexcop_ibi_value_be.h" |
44 | #else | 45 | #else |
45 | #error no endian defined | 46 | #error no endian defined |
46 | #endif | 47 | #endif |
48 | #endif | ||
47 | 49 | ||
48 | #define fc_data_Tag_ID_DVB 0x3e | 50 | #define fc_data_Tag_ID_DVB 0x3e |
49 | #define fc_data_Tag_ID_ATSC 0x3f | 51 | #define fc_data_Tag_ID_ATSC 0x3f |
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 8977c7a313df..3a2ff1cc24b7 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -1341,30 +1341,40 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
1341 | return 0; | 1341 | return 0; |
1342 | } | 1342 | } |
1343 | 1343 | ||
1344 | static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | 1344 | static int dst_set_frontend(struct dvb_frontend* fe, |
1345 | struct dvb_frontend_parameters* p, | ||
1346 | unsigned int mode_flags, | ||
1347 | int *delay, | ||
1348 | fe_status_t *status) | ||
1345 | { | 1349 | { |
1346 | struct dst_state *state = fe->demodulator_priv; | 1350 | struct dst_state *state = fe->demodulator_priv; |
1347 | 1351 | ||
1348 | dst_set_freq(state, p->frequency); | 1352 | if (p != NULL) { |
1349 | dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); | 1353 | dst_set_freq(state, p->frequency); |
1354 | dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); | ||
1350 | 1355 | ||
1351 | if (state->dst_type == DST_TYPE_IS_SAT) { | 1356 | if (state->dst_type == DST_TYPE_IS_SAT) { |
1352 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) | 1357 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) |
1353 | dst_set_inversion(state, p->inversion); | 1358 | dst_set_inversion(state, p->inversion); |
1354 | dst_set_fec(state, p->u.qpsk.fec_inner); | 1359 | dst_set_fec(state, p->u.qpsk.fec_inner); |
1355 | dst_set_symbolrate(state, p->u.qpsk.symbol_rate); | 1360 | dst_set_symbolrate(state, p->u.qpsk.symbol_rate); |
1356 | dst_set_polarization(state); | 1361 | dst_set_polarization(state); |
1357 | dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); | 1362 | dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); |
1358 | 1363 | ||
1359 | } else if (state->dst_type == DST_TYPE_IS_TERR) | 1364 | } else if (state->dst_type == DST_TYPE_IS_TERR) |
1360 | dst_set_bandwidth(state, p->u.ofdm.bandwidth); | 1365 | dst_set_bandwidth(state, p->u.ofdm.bandwidth); |
1361 | else if (state->dst_type == DST_TYPE_IS_CABLE) { | 1366 | else if (state->dst_type == DST_TYPE_IS_CABLE) { |
1362 | dst_set_fec(state, p->u.qam.fec_inner); | 1367 | dst_set_fec(state, p->u.qam.fec_inner); |
1363 | dst_set_symbolrate(state, p->u.qam.symbol_rate); | 1368 | dst_set_symbolrate(state, p->u.qam.symbol_rate); |
1364 | dst_set_modulation(state, p->u.qam.modulation); | 1369 | dst_set_modulation(state, p->u.qam.modulation); |
1370 | } | ||
1371 | dst_write_tuna(fe); | ||
1365 | } | 1372 | } |
1366 | dst_write_tuna(fe); | ||
1367 | 1373 | ||
1374 | if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) | ||
1375 | dst_read_status(fe, status); | ||
1376 | |||
1377 | *delay = HZ/10; | ||
1368 | return 0; | 1378 | return 0; |
1369 | } | 1379 | } |
1370 | 1380 | ||
@@ -1445,7 +1455,7 @@ static struct dvb_frontend_ops dst_dvbt_ops = { | |||
1445 | 1455 | ||
1446 | .release = dst_release, | 1456 | .release = dst_release, |
1447 | .init = dst_init, | 1457 | .init = dst_init, |
1448 | .set_frontend = dst_set_frontend, | 1458 | .tune = dst_set_frontend, |
1449 | .get_frontend = dst_get_frontend, | 1459 | .get_frontend = dst_get_frontend, |
1450 | .read_status = dst_read_status, | 1460 | .read_status = dst_read_status, |
1451 | .read_signal_strength = dst_read_signal_strength, | 1461 | .read_signal_strength = dst_read_signal_strength, |
@@ -1469,7 +1479,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = { | |||
1469 | 1479 | ||
1470 | .release = dst_release, | 1480 | .release = dst_release, |
1471 | .init = dst_init, | 1481 | .init = dst_init, |
1472 | .set_frontend = dst_set_frontend, | 1482 | .tune = dst_set_frontend, |
1473 | .get_frontend = dst_get_frontend, | 1483 | .get_frontend = dst_get_frontend, |
1474 | .read_status = dst_read_status, | 1484 | .read_status = dst_read_status, |
1475 | .read_signal_strength = dst_read_signal_strength, | 1485 | .read_signal_strength = dst_read_signal_strength, |
@@ -1496,7 +1506,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = { | |||
1496 | 1506 | ||
1497 | .release = dst_release, | 1507 | .release = dst_release, |
1498 | .init = dst_init, | 1508 | .init = dst_init, |
1499 | .set_frontend = dst_set_frontend, | 1509 | .tune = dst_set_frontend, |
1500 | .get_frontend = dst_get_frontend, | 1510 | .get_frontend = dst_get_frontend, |
1501 | .read_status = dst_read_status, | 1511 | .read_status = dst_read_status, |
1502 | .read_signal_strength = dst_read_signal_strength, | 1512 | .read_signal_strength = dst_read_signal_strength, |
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index 2239651969c8..c650b4bf7f5f 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c | |||
@@ -283,16 +283,17 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, | |||
283 | hw_buffer->msg[4] = 0x03; | 283 | hw_buffer->msg[4] = 0x03; |
284 | hw_buffer->msg[5] = length & 0xff; | 284 | hw_buffer->msg[5] = length & 0xff; |
285 | hw_buffer->msg[6] = 0x00; | 285 | hw_buffer->msg[6] = 0x00; |
286 | |||
286 | /* | 287 | /* |
287 | * Need to compute length for EN50221 section 8.3.2, for the time being | 288 | * Need to compute length for EN50221 section 8.3.2, for the time being |
288 | * assuming 8.3.2 is not applicable | 289 | * assuming 8.3.2 is not applicable |
289 | */ | 290 | */ |
290 | memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length); | 291 | memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length); |
291 | } | 292 | } |
293 | |||
292 | return 0; | 294 | return 0; |
293 | } | 295 | } |
294 | 296 | ||
295 | |||
296 | static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply) | 297 | static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply) |
297 | { | 298 | { |
298 | if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) { | 299 | if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) { |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 77977e9c013e..01b4e0aac049 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c | |||
@@ -600,7 +600,6 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
600 | struct dst_state* state = NULL; | 600 | struct dst_state* state = NULL; |
601 | 601 | ||
602 | switch(type) { | 602 | switch(type) { |
603 | #ifdef BTTV_BOARD_DVICO_DVBT_LITE | ||
604 | case BTTV_BOARD_DVICO_DVBT_LITE: | 603 | case BTTV_BOARD_DVICO_DVBT_LITE: |
605 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); | 604 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); |
606 | if (card->fe != NULL) { | 605 | if (card->fe != NULL) { |
@@ -608,22 +607,15 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
608 | card->fe->ops->info.frequency_max = 862000000; | 607 | card->fe->ops->info.frequency_max = 862000000; |
609 | } | 608 | } |
610 | break; | 609 | break; |
611 | #endif | ||
612 | 610 | ||
613 | #ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE | ||
614 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: | 611 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: |
615 | lgdt330x_reset(card); | 612 | lgdt330x_reset(card); |
616 | card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); | 613 | card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); |
617 | if (card->fe != NULL) | 614 | if (card->fe != NULL) |
618 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); | 615 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); |
619 | break; | 616 | break; |
620 | #endif | ||
621 | 617 | ||
622 | #ifdef BTTV_BOARD_TWINHAN_VP3021 | ||
623 | case BTTV_BOARD_TWINHAN_VP3021: | ||
624 | #else | ||
625 | case BTTV_BOARD_NEBULA_DIGITV: | 618 | case BTTV_BOARD_NEBULA_DIGITV: |
626 | #endif | ||
627 | /* | 619 | /* |
628 | * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); | 620 | * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); |
629 | * this would be a cleaner solution than trying each frontend in turn. | 621 | * this would be a cleaner solution than trying each frontend in turn. |
@@ -812,9 +804,7 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
812 | card->irq_err_ignore = 0; | 804 | card->irq_err_ignore = 0; |
813 | break; | 805 | break; |
814 | 806 | ||
815 | #ifdef BTTV_BOARD_DVICO_DVBT_LITE | ||
816 | case BTTV_BOARD_DVICO_DVBT_LITE: | 807 | case BTTV_BOARD_DVICO_DVBT_LITE: |
817 | #endif | ||
818 | card->gpio_mode = 0x0400C060; | 808 | card->gpio_mode = 0x0400C060; |
819 | card->op_sync_orin = 0; | 809 | card->op_sync_orin = 0; |
820 | card->irq_err_ignore = 0; | 810 | card->irq_err_ignore = 0; |
@@ -823,19 +813,13 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
823 | * DA_APP(parallel) */ | 813 | * DA_APP(parallel) */ |
824 | break; | 814 | break; |
825 | 815 | ||
826 | #ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE | ||
827 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: | 816 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: |
828 | #endif | ||
829 | card->gpio_mode = 0x0400c060; | 817 | card->gpio_mode = 0x0400c060; |
830 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | 818 | card->op_sync_orin = BT878_RISC_SYNC_MASK; |
831 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; | 819 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; |
832 | break; | 820 | break; |
833 | 821 | ||
834 | #ifdef BTTV_BOARD_TWINHAN_VP3021 | ||
835 | case BTTV_BOARD_TWINHAN_VP3021: | ||
836 | #else | ||
837 | case BTTV_BOARD_NEBULA_DIGITV: | 822 | case BTTV_BOARD_NEBULA_DIGITV: |
838 | #endif | ||
839 | case BTTV_BOARD_AVDVBT_761: | 823 | case BTTV_BOARD_AVDVBT_761: |
840 | card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); | 824 | card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); |
841 | card->op_sync_orin = 0; | 825 | card->op_sync_orin = 0; |
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig index 7cf4c4a888ec..6018fcdba1e6 100644 --- a/drivers/media/dvb/cinergyT2/Kconfig +++ b/drivers/media/dvb/cinergyT2/Kconfig | |||
@@ -21,35 +21,35 @@ config DVB_CINERGYT2_TUNING | |||
21 | config DVB_CINERGYT2_STREAM_URB_COUNT | 21 | config DVB_CINERGYT2_STREAM_URB_COUNT |
22 | int "Number of queued USB Request Blocks for Highspeed Stream Transfers" | 22 | int "Number of queued USB Request Blocks for Highspeed Stream Transfers" |
23 | depends on DVB_CINERGYT2_TUNING | 23 | depends on DVB_CINERGYT2_TUNING |
24 | default "32" | 24 | default "32" |
25 | help | 25 | help |
26 | USB Request Blocks for Highspeed Stream transfers are scheduled in | 26 | USB Request Blocks for Highspeed Stream transfers are scheduled in |
27 | a queue for the Host Controller. | 27 | a queue for the Host Controller. |
28 | 28 | ||
29 | Usually the default value is a safe choice. | 29 | Usually the default value is a safe choice. |
30 | 30 | ||
31 | You may increase this number if you are using this device in a | 31 | You may increase this number if you are using this device in a |
32 | Server Environment with many high-traffic USB Highspeed devices | 32 | Server Environment with many high-traffic USB Highspeed devices |
33 | sharing the same USB bus. | 33 | sharing the same USB bus. |
34 | 34 | ||
35 | 35 | ||
36 | config DVB_CINERGYT2_STREAM_BUF_SIZE | 36 | config DVB_CINERGYT2_STREAM_BUF_SIZE |
37 | int "Size of URB Stream Buffers for Highspeed Transfers" | 37 | int "Size of URB Stream Buffers for Highspeed Transfers" |
38 | depends on DVB_CINERGYT2_TUNING | 38 | depends on DVB_CINERGYT2_TUNING |
39 | default "512" | 39 | default "512" |
40 | help | 40 | help |
41 | Should be a multiple of native buffer size of 512 bytes. | 41 | Should be a multiple of native buffer size of 512 bytes. |
42 | Default value is a safe choice. | 42 | Default value is a safe choice. |
43 | 43 | ||
44 | You may increase this number if you are using this device in a | 44 | You may increase this number if you are using this device in a |
45 | Server Environment with many high-traffic USB Highspeed devices | 45 | Server Environment with many high-traffic USB Highspeed devices |
46 | sharing the same USB bus. | 46 | sharing the same USB bus. |
47 | 47 | ||
48 | 48 | ||
49 | config DVB_CINERGYT2_QUERY_INTERVAL | 49 | config DVB_CINERGYT2_QUERY_INTERVAL |
50 | int "Status update interval [milliseconds]" | 50 | int "Status update interval [milliseconds]" |
51 | depends on DVB_CINERGYT2_TUNING | 51 | depends on DVB_CINERGYT2_TUNING |
52 | default "250" | 52 | default "250" |
53 | help | 53 | help |
54 | This is the interval for status readouts from the demodulator. | 54 | This is the interval for status readouts from the demodulator. |
55 | You may try lower values if you need more responsive signal quality | 55 | You may try lower values if you need more responsive signal quality |
@@ -64,9 +64,9 @@ config DVB_CINERGYT2_QUERY_INTERVAL | |||
64 | config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE | 64 | config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE |
65 | bool "Register the onboard IR Remote Control Receiver as Input Device" | 65 | bool "Register the onboard IR Remote Control Receiver as Input Device" |
66 | depends on DVB_CINERGYT2_TUNING | 66 | depends on DVB_CINERGYT2_TUNING |
67 | default "yes" | 67 | default "yes" |
68 | help | 68 | help |
69 | Enable this option if you want to use the onboard Infrared Remote | 69 | Enable this option if you want to use the onboard Infrared Remote |
70 | Control Receiver as Linux-Input device. | 70 | Control Receiver as Linux-Input device. |
71 | 71 | ||
72 | Right now only the keycode table for the default Remote Control | 72 | Right now only the keycode table for the default Remote Control |
@@ -77,7 +77,7 @@ config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE | |||
77 | config DVB_CINERGYT2_RC_QUERY_INTERVAL | 77 | config DVB_CINERGYT2_RC_QUERY_INTERVAL |
78 | int "Infrared Remote Controller update interval [milliseconds]" | 78 | int "Infrared Remote Controller update interval [milliseconds]" |
79 | depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE | 79 | depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE |
80 | default "50" | 80 | default "50" |
81 | help | 81 | help |
82 | If you have a very fast-repeating remote control you can try lower | 82 | If you have a very fast-repeating remote control you can try lower |
83 | values, for normal consumer receivers the default value should be | 83 | values, for normal consumer receivers the default value should be |
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 1d69bf031fb9..c4b4c5b6b7c8 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -131,6 +131,8 @@ struct cinergyt2 { | |||
131 | 131 | ||
132 | wait_queue_head_t poll_wq; | 132 | wait_queue_head_t poll_wq; |
133 | int pending_fe_events; | 133 | int pending_fe_events; |
134 | int disconnect_pending; | ||
135 | atomic_t inuse; | ||
134 | 136 | ||
135 | void *streambuf; | 137 | void *streambuf; |
136 | dma_addr_t streambuf_dmahandle; | 138 | dma_addr_t streambuf_dmahandle; |
@@ -343,7 +345,7 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
343 | struct dvb_demux *demux = dvbdmxfeed->demux; | 345 | struct dvb_demux *demux = dvbdmxfeed->demux; |
344 | struct cinergyt2 *cinergyt2 = demux->priv; | 346 | struct cinergyt2 *cinergyt2 = demux->priv; |
345 | 347 | ||
346 | if (down_interruptible(&cinergyt2->sem)) | 348 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
347 | return -ERESTARTSYS; | 349 | return -ERESTARTSYS; |
348 | 350 | ||
349 | if (cinergyt2->streaming == 0) | 351 | if (cinergyt2->streaming == 0) |
@@ -359,7 +361,7 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
359 | struct dvb_demux *demux = dvbdmxfeed->demux; | 361 | struct dvb_demux *demux = dvbdmxfeed->demux; |
360 | struct cinergyt2 *cinergyt2 = demux->priv; | 362 | struct cinergyt2 *cinergyt2 = demux->priv; |
361 | 363 | ||
362 | if (down_interruptible(&cinergyt2->sem)) | 364 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
363 | return -ERESTARTSYS; | 365 | return -ERESTARTSYS; |
364 | 366 | ||
365 | if (--cinergyt2->streaming == 0) | 367 | if (--cinergyt2->streaming == 0) |
@@ -479,23 +481,37 @@ static int cinergyt2_open (struct inode *inode, struct file *file) | |||
479 | { | 481 | { |
480 | struct dvb_device *dvbdev = file->private_data; | 482 | struct dvb_device *dvbdev = file->private_data; |
481 | struct cinergyt2 *cinergyt2 = dvbdev->priv; | 483 | struct cinergyt2 *cinergyt2 = dvbdev->priv; |
482 | int err; | 484 | int err = -ERESTARTSYS; |
483 | 485 | ||
484 | if ((err = dvb_generic_open(inode, file))) | 486 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
487 | return -ERESTARTSYS; | ||
488 | |||
489 | if ((err = dvb_generic_open(inode, file))) { | ||
490 | up(&cinergyt2->sem); | ||
485 | return err; | 491 | return err; |
492 | } | ||
486 | 493 | ||
487 | if (down_interruptible(&cinergyt2->sem)) | ||
488 | return -ERESTARTSYS; | ||
489 | 494 | ||
490 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | 495 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { |
491 | cinergyt2_sleep(cinergyt2, 0); | 496 | cinergyt2_sleep(cinergyt2, 0); |
492 | schedule_delayed_work(&cinergyt2->query_work, HZ/2); | 497 | schedule_delayed_work(&cinergyt2->query_work, HZ/2); |
493 | } | 498 | } |
494 | 499 | ||
500 | atomic_inc(&cinergyt2->inuse); | ||
501 | |||
495 | up(&cinergyt2->sem); | 502 | up(&cinergyt2->sem); |
496 | return 0; | 503 | return 0; |
497 | } | 504 | } |
498 | 505 | ||
506 | static void cinergyt2_unregister(struct cinergyt2 *cinergyt2) | ||
507 | { | ||
508 | dvb_unregister_device(cinergyt2->fedev); | ||
509 | dvb_unregister_adapter(&cinergyt2->adapter); | ||
510 | |||
511 | cinergyt2_free_stream_urbs(cinergyt2); | ||
512 | kfree(cinergyt2); | ||
513 | } | ||
514 | |||
499 | static int cinergyt2_release (struct inode *inode, struct file *file) | 515 | static int cinergyt2_release (struct inode *inode, struct file *file) |
500 | { | 516 | { |
501 | struct dvb_device *dvbdev = file->private_data; | 517 | struct dvb_device *dvbdev = file->private_data; |
@@ -504,7 +520,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file) | |||
504 | if (down_interruptible(&cinergyt2->sem)) | 520 | if (down_interruptible(&cinergyt2->sem)) |
505 | return -ERESTARTSYS; | 521 | return -ERESTARTSYS; |
506 | 522 | ||
507 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | 523 | if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) { |
508 | cancel_delayed_work(&cinergyt2->query_work); | 524 | cancel_delayed_work(&cinergyt2->query_work); |
509 | flush_scheduled_work(); | 525 | flush_scheduled_work(); |
510 | cinergyt2_sleep(cinergyt2, 1); | 526 | cinergyt2_sleep(cinergyt2, 1); |
@@ -512,6 +528,11 @@ static int cinergyt2_release (struct inode *inode, struct file *file) | |||
512 | 528 | ||
513 | up(&cinergyt2->sem); | 529 | up(&cinergyt2->sem); |
514 | 530 | ||
531 | if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) { | ||
532 | warn("delayed unregister in release"); | ||
533 | cinergyt2_unregister(cinergyt2); | ||
534 | } | ||
535 | |||
515 | return dvb_generic_release(inode, file); | 536 | return dvb_generic_release(inode, file); |
516 | } | 537 | } |
517 | 538 | ||
@@ -519,7 +540,14 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct | |||
519 | { | 540 | { |
520 | struct dvb_device *dvbdev = file->private_data; | 541 | struct dvb_device *dvbdev = file->private_data; |
521 | struct cinergyt2 *cinergyt2 = dvbdev->priv; | 542 | struct cinergyt2 *cinergyt2 = dvbdev->priv; |
543 | |||
544 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) | ||
545 | return -ERESTARTSYS; | ||
546 | |||
522 | poll_wait(file, &cinergyt2->poll_wq, wait); | 547 | poll_wait(file, &cinergyt2->poll_wq, wait); |
548 | |||
549 | up(&cinergyt2->sem); | ||
550 | |||
523 | return (POLLIN | POLLRDNORM | POLLPRI); | 551 | return (POLLIN | POLLRDNORM | POLLPRI); |
524 | } | 552 | } |
525 | 553 | ||
@@ -564,10 +592,15 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, | |||
564 | (__u16 __user *) arg); | 592 | (__u16 __user *) arg); |
565 | 593 | ||
566 | case FE_READ_UNCORRECTED_BLOCKS: | 594 | case FE_READ_UNCORRECTED_BLOCKS: |
567 | /* UNC are already converted to host byte order... */ | 595 | { |
568 | return put_user(stat->uncorrected_block_count, | 596 | uint32_t unc_count; |
569 | (__u32 __user *) arg); | 597 | |
598 | unc_count = stat->uncorrected_block_count; | ||
599 | stat->uncorrected_block_count = 0; | ||
570 | 600 | ||
601 | /* UNC are already converted to host byte order... */ | ||
602 | return put_user(unc_count,(__u32 __user *) arg); | ||
603 | } | ||
571 | case FE_SET_FRONTEND: | 604 | case FE_SET_FRONTEND: |
572 | { | 605 | { |
573 | struct dvbt_set_parameters_msg *param = &cinergyt2->param; | 606 | struct dvbt_set_parameters_msg *param = &cinergyt2->param; |
@@ -580,7 +613,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, | |||
580 | if (copy_from_user(&p, (void __user*) arg, sizeof(p))) | 613 | if (copy_from_user(&p, (void __user*) arg, sizeof(p))) |
581 | return -EFAULT; | 614 | return -EFAULT; |
582 | 615 | ||
583 | if (down_interruptible(&cinergyt2->sem)) | 616 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
584 | return -ERESTARTSYS; | 617 | return -ERESTARTSYS; |
585 | 618 | ||
586 | param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; | 619 | param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; |
@@ -691,7 +724,7 @@ static void cinergyt2_query_rc (void *data) | |||
691 | struct cinergyt2_rc_event rc_events[12]; | 724 | struct cinergyt2_rc_event rc_events[12]; |
692 | int n, len, i; | 725 | int n, len, i; |
693 | 726 | ||
694 | if (down_interruptible(&cinergyt2->sem)) | 727 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
695 | return; | 728 | return; |
696 | 729 | ||
697 | len = cinergyt2_command(cinergyt2, buf, sizeof(buf), | 730 | len = cinergyt2_command(cinergyt2, buf, sizeof(buf), |
@@ -786,7 +819,6 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) | |||
786 | static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) | 819 | static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) |
787 | { | 820 | { |
788 | cancel_delayed_work(&cinergyt2->rc_query_work); | 821 | cancel_delayed_work(&cinergyt2->rc_query_work); |
789 | flush_scheduled_work(); | ||
790 | input_unregister_device(cinergyt2->rc_input_dev); | 822 | input_unregister_device(cinergyt2->rc_input_dev); |
791 | } | 823 | } |
792 | 824 | ||
@@ -817,7 +849,7 @@ static void cinergyt2_query (void *data) | |||
817 | uint8_t lock_bits; | 849 | uint8_t lock_bits; |
818 | uint32_t unc; | 850 | uint32_t unc; |
819 | 851 | ||
820 | if (down_interruptible(&cinergyt2->sem)) | 852 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
821 | return; | 853 | return; |
822 | 854 | ||
823 | unc = s->uncorrected_block_count; | 855 | unc = s->uncorrected_block_count; |
@@ -917,28 +949,25 @@ static void cinergyt2_disconnect (struct usb_interface *intf) | |||
917 | { | 949 | { |
918 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); | 950 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); |
919 | 951 | ||
920 | if (down_interruptible(&cinergyt2->sem)) | 952 | flush_scheduled_work(); |
921 | return; | ||
922 | 953 | ||
923 | cinergyt2_unregister_rc(cinergyt2); | 954 | cinergyt2_unregister_rc(cinergyt2); |
924 | 955 | ||
956 | cancel_delayed_work(&cinergyt2->query_work); | ||
957 | wake_up_interruptible(&cinergyt2->poll_wq); | ||
958 | |||
925 | cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); | 959 | cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); |
926 | dvb_net_release(&cinergyt2->dvbnet); | 960 | cinergyt2->disconnect_pending = 1; |
927 | dvb_dmxdev_release(&cinergyt2->dmxdev); | ||
928 | dvb_dmx_release(&cinergyt2->demux); | ||
929 | dvb_unregister_device(cinergyt2->fedev); | ||
930 | dvb_unregister_adapter(&cinergyt2->adapter); | ||
931 | 961 | ||
932 | cinergyt2_free_stream_urbs(cinergyt2); | 962 | if (!atomic_read(&cinergyt2->inuse)) |
933 | up(&cinergyt2->sem); | 963 | cinergyt2_unregister(cinergyt2); |
934 | kfree(cinergyt2); | ||
935 | } | 964 | } |
936 | 965 | ||
937 | static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) | 966 | static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) |
938 | { | 967 | { |
939 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); | 968 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); |
940 | 969 | ||
941 | if (down_interruptible(&cinergyt2->sem)) | 970 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
942 | return -ERESTARTSYS; | 971 | return -ERESTARTSYS; |
943 | 972 | ||
944 | if (state.event > PM_EVENT_ON) { | 973 | if (state.event > PM_EVENT_ON) { |
@@ -961,7 +990,7 @@ static int cinergyt2_resume (struct usb_interface *intf) | |||
961 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); | 990 | struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); |
962 | struct dvbt_set_parameters_msg *param = &cinergyt2->param; | 991 | struct dvbt_set_parameters_msg *param = &cinergyt2->param; |
963 | 992 | ||
964 | if (down_interruptible(&cinergyt2->sem)) | 993 | if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) |
965 | return -ERESTARTSYS; | 994 | return -ERESTARTSYS; |
966 | 995 | ||
967 | if (!cinergyt2->sleeping) { | 996 | if (!cinergyt2->sleeping) { |
@@ -1014,4 +1043,3 @@ module_exit (cinergyt2_exit); | |||
1014 | 1043 | ||
1015 | MODULE_LICENSE("GPL"); | 1044 | MODULE_LICENSE("GPL"); |
1016 | MODULE_AUTHOR("Holger Waechtler, Daniel Mack"); | 1045 | MODULE_AUTHOR("Holger Waechtler, Daniel Mack"); |
1017 | |||
diff --git a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig index a9a7b3421048..12ee912a5705 100644 --- a/drivers/media/dvb/dvb-core/Kconfig +++ b/drivers/media/dvb/dvb-core/Kconfig | |||
@@ -5,7 +5,7 @@ config DVB_CORE | |||
5 | help | 5 | help |
6 | DVB core utility functions for device handling, software fallbacks etc. | 6 | DVB core utility functions for device handling, software fallbacks etc. |
7 | Say Y when you have a DVB card and want to use it. Say Y if your want | 7 | Say Y when you have a DVB card and want to use it. Say Y if your want |
8 | to build your drivers outside the kernel, but need the DVB core. All | 8 | to build your drivers outside the kernel, but need the DVB core. All |
9 | in-kernel drivers will select this automatically if needed. | 9 | in-kernel drivers will select this automatically if needed. |
10 | If unsure say N. | 10 | If unsure say N. |
11 | 11 | ||
diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile index c6baac20f529..7adb50c1e8eb 100644 --- a/drivers/media/dvb/dvb-core/Makefile +++ b/drivers/media/dvb/dvb-core/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ | 5 | dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ |
6 | dvb_ca_en50221.o dvb_frontend.o \ | 6 | dvb_ca_en50221.o dvb_frontend.o \ |
7 | dvb_net.o dvb_ringbuffer.o | 7 | dvb_net.o dvb_ringbuffer.o |
8 | 8 | ||
9 | obj-$(CONFIG_DVB_CORE) += dvb-core.o | 9 | obj-$(CONFIG_DVB_CORE) += dvb-core.o |
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 5956c35d34ac..4bb779aeff6a 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c | |||
@@ -1745,9 +1745,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) | |||
1745 | 1745 | ||
1746 | for (i = 0; i < ca->slot_count; i++) { | 1746 | for (i = 0; i < ca->slot_count; i++) { |
1747 | dvb_ca_en50221_slot_shutdown(ca, i); | 1747 | dvb_ca_en50221_slot_shutdown(ca, i); |
1748 | if (ca->slot_info[i].rx_buffer.data != NULL) { | 1748 | vfree(ca->slot_info[i].rx_buffer.data); |
1749 | vfree(ca->slot_info[i].rx_buffer.data); | ||
1750 | } | ||
1751 | } | 1749 | } |
1752 | kfree(ca->slot_info); | 1750 | kfree(ca->slot_info); |
1753 | dvb_unregister_device(ca->dvbdev); | 1751 | dvb_unregister_device(ca->dvbdev); |
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb/dvb-core/dvb_filter.c index c49fd0bd7181..772003fb1821 100644 --- a/drivers/media/dvb/dvb-core/dvb_filter.c +++ b/drivers/media/dvb/dvb-core/dvb_filter.c | |||
@@ -409,16 +409,16 @@ static u8 *skip_pes_header(u8 **bufp) | |||
409 | 409 | ||
410 | if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ | 410 | if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ |
411 | if (buf[7] & PTS_ONLY) | 411 | if (buf[7] & PTS_ONLY) |
412 | pts = buf+9; | 412 | pts = buf+9; |
413 | else pts = NULL; | 413 | else pts = NULL; |
414 | buf = inbuf + 9 + inbuf[8]; | 414 | buf = inbuf + 9 + inbuf[8]; |
415 | } else { /* mpeg1 */ | 415 | } else { /* mpeg1 */ |
416 | for (buf = inbuf + 6; *buf == 0xff; buf++) | 416 | for (buf = inbuf + 6; *buf == 0xff; buf++) |
417 | if (buf == inbuf + 6 + 16) { | 417 | if (buf == inbuf + 6 + 16) { |
418 | break; | 418 | break; |
419 | } | 419 | } |
420 | if ((*buf & 0xc0) == 0x40) | 420 | if ((*buf & 0xc0) == 0x40) |
421 | buf += 2; | 421 | buf += 2; |
422 | skip = mpeg1_skip_table [*buf >> 4]; | 422 | skip = mpeg1_skip_table [*buf >> 4]; |
423 | if (skip == 5 || skip == 10) pts = buf; | 423 | if (skip == 5 || skip == 10) pts = buf; |
424 | else pts = NULL; | 424 | else pts = NULL; |
@@ -529,9 +529,9 @@ static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_t | |||
529 | pic->picture_header = 0; | 529 | pic->picture_header = 0; |
530 | pic->sequence_header_data | 530 | pic->sequence_header_data |
531 | = ( INIT_HORIZONTAL_SIZE << 20 ) | 531 | = ( INIT_HORIZONTAL_SIZE << 20 ) |
532 | | ( INIT_VERTICAL_SIZE << 8 ) | 532 | | ( INIT_VERTICAL_SIZE << 8 ) |
533 | | ( INIT_ASPECT_RATIO << 4 ) | 533 | | ( INIT_ASPECT_RATIO << 4 ) |
534 | | ( INIT_FRAME_RATE ); | 534 | | ( INIT_FRAME_RATE ); |
535 | pic->mpeg1_flag = 0; | 535 | pic->mpeg1_flag = 0; |
536 | pic->vinfo.horizontal_size | 536 | pic->vinfo.horizontal_size |
537 | = INIT_DISP_HORIZONTAL_SIZE; | 537 | = INIT_DISP_HORIZONTAL_SIZE; |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 95ea5095e07e..4a08c4ab6730 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -92,6 +92,7 @@ static DECLARE_MUTEX(frontend_mutex); | |||
92 | 92 | ||
93 | struct dvb_frontend_private { | 93 | struct dvb_frontend_private { |
94 | 94 | ||
95 | /* thread/frontend values */ | ||
95 | struct dvb_device *dvbdev; | 96 | struct dvb_device *dvbdev; |
96 | struct dvb_frontend_parameters parameters; | 97 | struct dvb_frontend_parameters parameters; |
97 | struct dvb_fe_events events; | 98 | struct dvb_fe_events events; |
@@ -100,20 +101,25 @@ struct dvb_frontend_private { | |||
100 | wait_queue_head_t wait_queue; | 101 | wait_queue_head_t wait_queue; |
101 | pid_t thread_pid; | 102 | pid_t thread_pid; |
102 | unsigned long release_jiffies; | 103 | unsigned long release_jiffies; |
103 | int state; | 104 | unsigned int exit; |
104 | int bending; | 105 | unsigned int wakeup; |
105 | int lnb_drift; | ||
106 | int inversion; | ||
107 | int auto_step; | ||
108 | int auto_sub_step; | ||
109 | int started_auto_step; | ||
110 | int min_delay; | ||
111 | int max_drift; | ||
112 | int step_size; | ||
113 | int exit; | ||
114 | int wakeup; | ||
115 | fe_status_t status; | 106 | fe_status_t status; |
116 | fe_sec_tone_mode_t tone; | 107 | unsigned long tune_mode_flags; |
108 | unsigned int delay; | ||
109 | |||
110 | /* swzigzag values */ | ||
111 | unsigned int state; | ||
112 | unsigned int bending; | ||
113 | int lnb_drift; | ||
114 | unsigned int inversion; | ||
115 | unsigned int auto_step; | ||
116 | unsigned int auto_sub_step; | ||
117 | unsigned int started_auto_step; | ||
118 | unsigned int min_delay; | ||
119 | unsigned int max_drift; | ||
120 | unsigned int step_size; | ||
121 | int quality; | ||
122 | unsigned int check_wrapped; | ||
117 | }; | 123 | }; |
118 | 124 | ||
119 | 125 | ||
@@ -208,21 +214,21 @@ static void dvb_frontend_init(struct dvb_frontend *fe) | |||
208 | fe->ops->init(fe); | 214 | fe->ops->init(fe); |
209 | } | 215 | } |
210 | 216 | ||
211 | static void update_delay(int *quality, int *delay, int min_delay, int locked) | 217 | static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked) |
212 | { | 218 | { |
213 | int q2; | 219 | int q2; |
214 | 220 | ||
215 | dprintk ("%s\n", __FUNCTION__); | 221 | dprintk ("%s\n", __FUNCTION__); |
216 | 222 | ||
217 | if (locked) | 223 | if (locked) |
218 | (*quality) = (*quality * 220 + 36*256) / 256; | 224 | (fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256; |
219 | else | 225 | else |
220 | (*quality) = (*quality * 220 + 0) / 256; | 226 | (fepriv->quality) = (fepriv->quality * 220 + 0) / 256; |
221 | 227 | ||
222 | q2 = *quality - 128; | 228 | q2 = fepriv->quality - 128; |
223 | q2 *= q2; | 229 | q2 *= q2; |
224 | 230 | ||
225 | *delay = min_delay + q2 * HZ / (128*128); | 231 | fepriv->delay = fepriv->min_delay + q2 * HZ / (128*128); |
226 | } | 232 | } |
227 | 233 | ||
228 | /** | 234 | /** |
@@ -232,7 +238,7 @@ static void update_delay(int *quality, int *delay, int min_delay, int locked) | |||
232 | * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT | 238 | * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT |
233 | * @returns Number of complete iterations that have been performed. | 239 | * @returns Number of complete iterations that have been performed. |
234 | */ | 240 | */ |
235 | static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) | 241 | static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wrapped) |
236 | { | 242 | { |
237 | int autoinversion; | 243 | int autoinversion; |
238 | int ready = 0; | 244 | int ready = 0; |
@@ -321,6 +327,129 @@ static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) | |||
321 | return 0; | 327 | return 0; |
322 | } | 328 | } |
323 | 329 | ||
330 | static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | ||
331 | { | ||
332 | fe_status_t s; | ||
333 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | ||
334 | |||
335 | /* if we've got no parameters, just keep idling */ | ||
336 | if (fepriv->state & FESTATE_IDLE) { | ||
337 | fepriv->delay = 3*HZ; | ||
338 | fepriv->quality = 0; | ||
339 | return; | ||
340 | } | ||
341 | |||
342 | /* in SCAN mode, we just set the frontend when asked and leave it alone */ | ||
343 | if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { | ||
344 | if (fepriv->state & FESTATE_RETUNE) { | ||
345 | if (fe->ops->set_frontend) | ||
346 | fe->ops->set_frontend(fe, &fepriv->parameters); | ||
347 | fepriv->state = FESTATE_TUNED; | ||
348 | } | ||
349 | fepriv->delay = 3*HZ; | ||
350 | fepriv->quality = 0; | ||
351 | return; | ||
352 | } | ||
353 | |||
354 | /* get the frontend status */ | ||
355 | if (fepriv->state & FESTATE_RETUNE) { | ||
356 | s = 0; | ||
357 | } else { | ||
358 | if (fe->ops->read_status) | ||
359 | fe->ops->read_status(fe, &s); | ||
360 | if (s != fepriv->status) { | ||
361 | dvb_frontend_add_event(fe, s); | ||
362 | fepriv->status = s; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | /* if we're not tuned, and we have a lock, move to the TUNED state */ | ||
367 | if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) { | ||
368 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | ||
369 | fepriv->state = FESTATE_TUNED; | ||
370 | |||
371 | /* if we're tuned, then we have determined the correct inversion */ | ||
372 | if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && | ||
373 | (fepriv->parameters.inversion == INVERSION_AUTO)) { | ||
374 | fepriv->parameters.inversion = fepriv->inversion; | ||
375 | } | ||
376 | return; | ||
377 | } | ||
378 | |||
379 | /* if we are tuned already, check we're still locked */ | ||
380 | if (fepriv->state & FESTATE_TUNED) { | ||
381 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | ||
382 | |||
383 | /* we're tuned, and the lock is still good... */ | ||
384 | if (s & FE_HAS_LOCK) { | ||
385 | return; | ||
386 | } else { /* if we _WERE_ tuned, but now don't have a lock */ | ||
387 | fepriv->state = FESTATE_ZIGZAG_FAST; | ||
388 | fepriv->started_auto_step = fepriv->auto_step; | ||
389 | fepriv->check_wrapped = 0; | ||
390 | } | ||
391 | } | ||
392 | |||
393 | /* don't actually do anything if we're in the LOSTLOCK state, | ||
394 | * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ | ||
395 | if ((fepriv->state & FESTATE_LOSTLOCK) && | ||
396 | (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { | ||
397 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | ||
398 | return; | ||
399 | } | ||
400 | |||
401 | /* don't do anything if we're in the DISEQC state, since this | ||
402 | * might be someone with a motorized dish controlled by DISEQC. | ||
403 | * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */ | ||
404 | if (fepriv->state & FESTATE_DISEQC) { | ||
405 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | ||
406 | return; | ||
407 | } | ||
408 | |||
409 | /* if we're in the RETUNE state, set everything up for a brand | ||
410 | * new scan, keeping the current inversion setting, as the next | ||
411 | * tune is _very_ likely to require the same */ | ||
412 | if (fepriv->state & FESTATE_RETUNE) { | ||
413 | fepriv->lnb_drift = 0; | ||
414 | fepriv->auto_step = 0; | ||
415 | fepriv->auto_sub_step = 0; | ||
416 | fepriv->started_auto_step = 0; | ||
417 | fepriv->check_wrapped = 0; | ||
418 | } | ||
419 | |||
420 | /* fast zigzag. */ | ||
421 | if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) { | ||
422 | fepriv->delay = fepriv->min_delay; | ||
423 | |||
424 | /* peform a tune */ | ||
425 | if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) { | ||
426 | /* OK, if we've run out of trials at the fast speed. | ||
427 | * Drop back to slow for the _next_ attempt */ | ||
428 | fepriv->state = FESTATE_SEARCHING_SLOW; | ||
429 | fepriv->started_auto_step = fepriv->auto_step; | ||
430 | return; | ||
431 | } | ||
432 | fepriv->check_wrapped = 1; | ||
433 | |||
434 | /* if we've just retuned, enter the ZIGZAG_FAST state. | ||
435 | * This ensures we cannot return from an | ||
436 | * FE_SET_FRONTEND ioctl before the first frontend tune | ||
437 | * occurs */ | ||
438 | if (fepriv->state & FESTATE_RETUNE) { | ||
439 | fepriv->state = FESTATE_TUNING_FAST; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | /* slow zigzag */ | ||
444 | if (fepriv->state & FESTATE_SEARCHING_SLOW) { | ||
445 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | ||
446 | |||
447 | /* Note: don't bother checking for wrapping; we stay in this | ||
448 | * state until we get a lock */ | ||
449 | dvb_frontend_swzigzag_autotune(fe, 0); | ||
450 | } | ||
451 | } | ||
452 | |||
324 | static int dvb_frontend_is_exiting(struct dvb_frontend *fe) | 453 | static int dvb_frontend_is_exiting(struct dvb_frontend *fe) |
325 | { | 454 | { |
326 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 455 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
@@ -330,7 +459,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe) | |||
330 | 459 | ||
331 | if (fepriv->dvbdev->writers == 1) | 460 | if (fepriv->dvbdev->writers == 1) |
332 | if (time_after(jiffies, fepriv->release_jiffies + | 461 | if (time_after(jiffies, fepriv->release_jiffies + |
333 | dvb_shutdown_timeout * HZ)) | 462 | dvb_shutdown_timeout * HZ)) |
334 | return 1; | 463 | return 1; |
335 | 464 | ||
336 | return 0; | 465 | return 0; |
@@ -355,18 +484,14 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe) | |||
355 | wake_up_interruptible(&fepriv->wait_queue); | 484 | wake_up_interruptible(&fepriv->wait_queue); |
356 | } | 485 | } |
357 | 486 | ||
358 | /* | ||
359 | * FIXME: use linux/kthread.h | ||
360 | */ | ||
361 | static int dvb_frontend_thread(void *data) | 487 | static int dvb_frontend_thread(void *data) |
362 | { | 488 | { |
363 | struct dvb_frontend *fe = data; | 489 | struct dvb_frontend *fe = data; |
364 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 490 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
365 | unsigned long timeout; | 491 | unsigned long timeout; |
366 | char name [15]; | 492 | char name [15]; |
367 | int quality = 0, delay = 3*HZ; | ||
368 | fe_status_t s; | 493 | fe_status_t s; |
369 | int check_wrapped = 0; | 494 | struct dvb_frontend_parameters *params; |
370 | 495 | ||
371 | dprintk("%s\n", __FUNCTION__); | 496 | dprintk("%s\n", __FUNCTION__); |
372 | 497 | ||
@@ -377,6 +502,9 @@ static int dvb_frontend_thread(void *data) | |||
377 | sigfillset(¤t->blocked); | 502 | sigfillset(¤t->blocked); |
378 | unlock_kernel(); | 503 | unlock_kernel(); |
379 | 504 | ||
505 | fepriv->check_wrapped = 0; | ||
506 | fepriv->quality = 0; | ||
507 | fepriv->delay = 3*HZ; | ||
380 | fepriv->status = 0; | 508 | fepriv->status = 0; |
381 | dvb_frontend_init(fe); | 509 | dvb_frontend_init(fe); |
382 | fepriv->wakeup = 0; | 510 | fepriv->wakeup = 0; |
@@ -386,7 +514,7 @@ static int dvb_frontend_thread(void *data) | |||
386 | 514 | ||
387 | timeout = wait_event_interruptible_timeout(fepriv->wait_queue, | 515 | timeout = wait_event_interruptible_timeout(fepriv->wait_queue, |
388 | dvb_frontend_should_wakeup(fe), | 516 | dvb_frontend_should_wakeup(fe), |
389 | delay); | 517 | fepriv->delay); |
390 | if (0 != dvb_frontend_is_exiting(fe)) { | 518 | if (0 != dvb_frontend_is_exiting(fe)) { |
391 | /* got signal or quitting */ | 519 | /* got signal or quitting */ |
392 | break; | 520 | break; |
@@ -397,108 +525,22 @@ static int dvb_frontend_thread(void *data) | |||
397 | if (down_interruptible(&fepriv->sem)) | 525 | if (down_interruptible(&fepriv->sem)) |
398 | break; | 526 | break; |
399 | 527 | ||
400 | /* if we've got no parameters, just keep idling */ | 528 | /* do an iteration of the tuning loop */ |
401 | if (fepriv->state & FESTATE_IDLE) { | 529 | if (fe->ops->tune) { |
402 | delay = 3*HZ; | 530 | /* have we been asked to retune? */ |
403 | quality = 0; | 531 | params = NULL; |
404 | continue; | 532 | if (fepriv->state & FESTATE_RETUNE) { |
405 | } | 533 | params = &fepriv->parameters; |
534 | fepriv->state = FESTATE_TUNED; | ||
535 | } | ||
406 | 536 | ||
407 | /* get the frontend status */ | 537 | fe->ops->tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); |
408 | if (fepriv->state & FESTATE_RETUNE) { | ||
409 | s = 0; | ||
410 | } else { | ||
411 | if (fe->ops->read_status) | ||
412 | fe->ops->read_status(fe, &s); | ||
413 | if (s != fepriv->status) { | 538 | if (s != fepriv->status) { |
414 | dvb_frontend_add_event(fe, s); | 539 | dvb_frontend_add_event(fe, s); |
415 | fepriv->status = s; | 540 | fepriv->status = s; |
416 | } | 541 | } |
417 | } | 542 | } else { |
418 | /* if we're not tuned, and we have a lock, move to the TUNED state */ | 543 | dvb_frontend_swzigzag(fe); |
419 | if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) { | ||
420 | update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); | ||
421 | fepriv->state = FESTATE_TUNED; | ||
422 | |||
423 | /* if we're tuned, then we have determined the correct inversion */ | ||
424 | if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && | ||
425 | (fepriv->parameters.inversion == INVERSION_AUTO)) { | ||
426 | fepriv->parameters.inversion = fepriv->inversion; | ||
427 | } | ||
428 | continue; | ||
429 | } | ||
430 | |||
431 | /* if we are tuned already, check we're still locked */ | ||
432 | if (fepriv->state & FESTATE_TUNED) { | ||
433 | update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); | ||
434 | |||
435 | /* we're tuned, and the lock is still good... */ | ||
436 | if (s & FE_HAS_LOCK) | ||
437 | continue; | ||
438 | else { /* if we _WERE_ tuned, but now don't have a lock */ | ||
439 | fepriv->state = FESTATE_ZIGZAG_FAST; | ||
440 | fepriv->started_auto_step = fepriv->auto_step; | ||
441 | check_wrapped = 0; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | /* don't actually do anything if we're in the LOSTLOCK state, | ||
446 | * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ | ||
447 | if ((fepriv->state & FESTATE_LOSTLOCK) && | ||
448 | (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { | ||
449 | update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); | ||
450 | continue; | ||
451 | } | ||
452 | |||
453 | /* don't do anything if we're in the DISEQC state, since this | ||
454 | * might be someone with a motorized dish controlled by DISEQC. | ||
455 | * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */ | ||
456 | if (fepriv->state & FESTATE_DISEQC) { | ||
457 | update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); | ||
458 | continue; | ||
459 | } | ||
460 | |||
461 | /* if we're in the RETUNE state, set everything up for a brand | ||
462 | * new scan, keeping the current inversion setting, as the next | ||
463 | * tune is _very_ likely to require the same */ | ||
464 | if (fepriv->state & FESTATE_RETUNE) { | ||
465 | fepriv->lnb_drift = 0; | ||
466 | fepriv->auto_step = 0; | ||
467 | fepriv->auto_sub_step = 0; | ||
468 | fepriv->started_auto_step = 0; | ||
469 | check_wrapped = 0; | ||
470 | } | ||
471 | |||
472 | /* fast zigzag. */ | ||
473 | if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) { | ||
474 | delay = fepriv->min_delay; | ||
475 | |||
476 | /* peform a tune */ | ||
477 | if (dvb_frontend_autotune(fe, check_wrapped)) { | ||
478 | /* OK, if we've run out of trials at the fast speed. | ||
479 | * Drop back to slow for the _next_ attempt */ | ||
480 | fepriv->state = FESTATE_SEARCHING_SLOW; | ||
481 | fepriv->started_auto_step = fepriv->auto_step; | ||
482 | continue; | ||
483 | } | ||
484 | check_wrapped = 1; | ||
485 | |||
486 | /* if we've just retuned, enter the ZIGZAG_FAST state. | ||
487 | * This ensures we cannot return from an | ||
488 | * FE_SET_FRONTEND ioctl before the first frontend tune | ||
489 | * occurs */ | ||
490 | if (fepriv->state & FESTATE_RETUNE) { | ||
491 | fepriv->state = FESTATE_TUNING_FAST; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | /* slow zigzag */ | ||
496 | if (fepriv->state & FESTATE_SEARCHING_SLOW) { | ||
497 | update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); | ||
498 | |||
499 | /* Note: don't bother checking for wrapping; we stay in this | ||
500 | * state until we get a lock */ | ||
501 | dvb_frontend_autotune(fe, 0); | ||
502 | } | 544 | } |
503 | } | 545 | } |
504 | 546 | ||
@@ -733,7 +775,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
733 | err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); | 775 | err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); |
734 | fepriv->state = FESTATE_DISEQC; | 776 | fepriv->state = FESTATE_DISEQC; |
735 | fepriv->status = 0; | 777 | fepriv->status = 0; |
736 | fepriv->tone = (fe_sec_tone_mode_t) parg; | ||
737 | } | 778 | } |
738 | break; | 779 | break; |
739 | 780 | ||
@@ -747,7 +788,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
747 | 788 | ||
748 | case FE_DISHNETWORK_SEND_LEGACY_CMD: | 789 | case FE_DISHNETWORK_SEND_LEGACY_CMD: |
749 | if (fe->ops->dishnetwork_send_legacy_command) { | 790 | if (fe->ops->dishnetwork_send_legacy_command) { |
750 | err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); | 791 | err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned long) parg); |
751 | fepriv->state = FESTATE_DISEQC; | 792 | fepriv->state = FESTATE_DISEQC; |
752 | fepriv->status = 0; | 793 | fepriv->status = 0; |
753 | } else if (fe->ops->set_voltage) { | 794 | } else if (fe->ops->set_voltage) { |
@@ -767,13 +808,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
767 | * initialization, so parg is 8 bits and does not | 808 | * initialization, so parg is 8 bits and does not |
768 | * include the initialization or start bit | 809 | * include the initialization or start bit |
769 | */ | 810 | */ |
770 | unsigned int cmd = ((unsigned int) parg) << 1; | 811 | unsigned long cmd = ((unsigned long) parg) << 1; |
771 | struct timeval nexttime; | 812 | struct timeval nexttime; |
772 | struct timeval tv[10]; | 813 | struct timeval tv[10]; |
773 | int i; | 814 | int i; |
774 | u8 last = 1; | 815 | u8 last = 1; |
775 | if (dvb_frontend_debug) | 816 | if (dvb_frontend_debug) |
776 | printk("%s switch command: 0x%04x\n", __FUNCTION__, cmd); | 817 | printk("%s switch command: 0x%04lx\n", __FUNCTION__, cmd); |
777 | do_gettimeofday(&nexttime); | 818 | do_gettimeofday(&nexttime); |
778 | if (dvb_frontend_debug) | 819 | if (dvb_frontend_debug) |
779 | memcpy(&tv[0], &nexttime, sizeof(struct timeval)); | 820 | memcpy(&tv[0], &nexttime, sizeof(struct timeval)); |
@@ -814,7 +855,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
814 | 855 | ||
815 | case FE_ENABLE_HIGH_LNB_VOLTAGE: | 856 | case FE_ENABLE_HIGH_LNB_VOLTAGE: |
816 | if (fe->ops->enable_high_lnb_voltage) | 857 | if (fe->ops->enable_high_lnb_voltage) |
817 | err = fe->ops->enable_high_lnb_voltage(fe, (int) parg); | 858 | err = fe->ops->enable_high_lnb_voltage(fe, (long) parg); |
818 | break; | 859 | break; |
819 | 860 | ||
820 | case FE_SET_FRONTEND: { | 861 | case FE_SET_FRONTEND: { |
@@ -891,6 +932,10 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
891 | err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); | 932 | err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); |
892 | } | 933 | } |
893 | break; | 934 | break; |
935 | |||
936 | case FE_SET_FRONTEND_TUNE_MODE: | ||
937 | fepriv->tune_mode_flags = (unsigned long) parg; | ||
938 | break; | ||
894 | }; | 939 | }; |
895 | 940 | ||
896 | up (&fepriv->sem); | 941 | up (&fepriv->sem); |
@@ -932,6 +977,9 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) | |||
932 | 977 | ||
933 | /* empty event queue */ | 978 | /* empty event queue */ |
934 | fepriv->events.eventr = fepriv->events.eventw = 0; | 979 | fepriv->events.eventr = fepriv->events.eventw = 0; |
980 | |||
981 | /* normal tune mode when opened R/W */ | ||
982 | fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; | ||
935 | } | 983 | } |
936 | 984 | ||
937 | return ret; | 985 | return ret; |
@@ -990,7 +1038,6 @@ int dvb_register_frontend(struct dvb_adapter* dvb, | |||
990 | init_MUTEX (&fepriv->events.sem); | 1038 | init_MUTEX (&fepriv->events.sem); |
991 | fe->dvb = dvb; | 1039 | fe->dvb = dvb; |
992 | fepriv->inversion = INVERSION_OFF; | 1040 | fepriv->inversion = INVERSION_OFF; |
993 | fepriv->tone = SEC_TONE_OFF; | ||
994 | 1041 | ||
995 | printk ("DVB: registering frontend %i (%s)...\n", | 1042 | printk ("DVB: registering frontend %i (%s)...\n", |
996 | fe->dvb->num, | 1043 | fe->dvb->num, |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 1e0840d02f1f..70a6d14efda7 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h | |||
@@ -58,10 +58,19 @@ struct dvb_frontend_ops { | |||
58 | int (*init)(struct dvb_frontend* fe); | 58 | int (*init)(struct dvb_frontend* fe); |
59 | int (*sleep)(struct dvb_frontend* fe); | 59 | int (*sleep)(struct dvb_frontend* fe); |
60 | 60 | ||
61 | /* if this is set, it overrides the default swzigzag */ | ||
62 | int (*tune)(struct dvb_frontend* fe, | ||
63 | struct dvb_frontend_parameters* params, | ||
64 | unsigned int mode_flags, | ||
65 | int *delay, | ||
66 | fe_status_t *status); | ||
67 | |||
68 | /* these two are only used for the swzigzag code */ | ||
61 | int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | 69 | int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); |
62 | int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
63 | int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); | 70 | int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); |
64 | 71 | ||
72 | int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
73 | |||
65 | int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); | 74 | int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); |
66 | int (*read_ber)(struct dvb_frontend* fe, u32* ber); | 75 | int (*read_ber)(struct dvb_frontend* fe, u32* ber); |
67 | int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength); | 76 | int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength); |
@@ -74,8 +83,9 @@ struct dvb_frontend_ops { | |||
74 | int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); | 83 | int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); |
75 | int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); | 84 | int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); |
76 | int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); | 85 | int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); |
77 | int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, int arg); | 86 | int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); |
78 | int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd); | 87 | int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); |
88 | int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); | ||
79 | }; | 89 | }; |
80 | 90 | ||
81 | #define MAX_EVENT 8 | 91 | #define MAX_EVENT 8 |
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 86bba81e851e..6711eb6a058c 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
@@ -1222,7 +1222,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) | |||
1222 | return if_num; | 1222 | return if_num; |
1223 | } | 1223 | } |
1224 | 1224 | ||
1225 | static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned int num) | 1225 | static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num) |
1226 | { | 1226 | { |
1227 | struct net_device *net = dvbnet->device[num]; | 1227 | struct net_device *net = dvbnet->device[num]; |
1228 | struct dvb_net_priv *priv; | 1228 | struct dvb_net_priv *priv; |
@@ -1296,9 +1296,9 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, | |||
1296 | 1296 | ||
1297 | if (!capable(CAP_SYS_ADMIN)) | 1297 | if (!capable(CAP_SYS_ADMIN)) |
1298 | return -EPERM; | 1298 | return -EPERM; |
1299 | if ((unsigned int) parg >= DVB_NET_DEVICES_MAX) | 1299 | if ((unsigned long) parg >= DVB_NET_DEVICES_MAX) |
1300 | return -EINVAL; | 1300 | return -EINVAL; |
1301 | ret = dvb_net_remove_if(dvbnet, (unsigned int) parg); | 1301 | ret = dvb_net_remove_if(dvbnet, (unsigned long) parg); |
1302 | if (!ret) | 1302 | if (!ret) |
1303 | module_put(dvbdev->adapter->module); | 1303 | module_put(dvbdev->adapter->module); |
1304 | return ret; | 1304 | return ret; |
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c index 283c6e9339a4..77ad2410f4d3 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c | |||
@@ -112,10 +112,10 @@ ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, in | |||
112 | split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; | 112 | split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; |
113 | if (split > 0) { | 113 | if (split > 0) { |
114 | if (!usermem) | 114 | if (!usermem) |
115 | memcpy(buf, rbuf->data+rbuf->pread, split); | 115 | memcpy(buf, rbuf->data+rbuf->pread, split); |
116 | else | 116 | else |
117 | if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) | 117 | if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) |
118 | return -EFAULT; | 118 | return -EFAULT; |
119 | buf += split; | 119 | buf += split; |
120 | todo -= split; | 120 | todo -= split; |
121 | rbuf->pread = 0; | 121 | rbuf->pread = 0; |
@@ -124,7 +124,7 @@ ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, in | |||
124 | memcpy(buf, rbuf->data+rbuf->pread, todo); | 124 | memcpy(buf, rbuf->data+rbuf->pread, todo); |
125 | else | 125 | else |
126 | if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) | 126 | if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) |
127 | return -EFAULT; | 127 | return -EFAULT; |
128 | 128 | ||
129 | rbuf->pread = (rbuf->pread + todo) % rbuf->size; | 129 | rbuf->pread = (rbuf->pread + todo) % rbuf->size; |
130 | 130 | ||
@@ -167,7 +167,7 @@ ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t le | |||
167 | } | 167 | } |
168 | 168 | ||
169 | ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | 169 | ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, |
170 | int offset, u8* buf, size_t len, int usermem) | 170 | int offset, u8* buf, size_t len, int usermem) |
171 | { | 171 | { |
172 | size_t todo; | 172 | size_t todo; |
173 | size_t split; | 173 | size_t split; |
@@ -183,10 +183,10 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | |||
183 | split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; | 183 | split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; |
184 | if (split > 0) { | 184 | if (split > 0) { |
185 | if (!usermem) | 185 | if (!usermem) |
186 | memcpy(buf, rbuf->data+idx, split); | 186 | memcpy(buf, rbuf->data+idx, split); |
187 | else | 187 | else |
188 | if (copy_to_user(buf, rbuf->data+idx, split)) | 188 | if (copy_to_user(buf, rbuf->data+idx, split)) |
189 | return -EFAULT; | 189 | return -EFAULT; |
190 | buf += split; | 190 | buf += split; |
191 | todo -= split; | 191 | todo -= split; |
192 | idx = 0; | 192 | idx = 0; |
@@ -195,7 +195,7 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | |||
195 | memcpy(buf, rbuf->data+idx, todo); | 195 | memcpy(buf, rbuf->data+idx, todo); |
196 | else | 196 | else |
197 | if (copy_to_user(buf, rbuf->data+idx, todo)) | 197 | if (copy_to_user(buf, rbuf->data+idx, todo)) |
198 | return -EFAULT; | 198 | return -EFAULT; |
199 | 199 | ||
200 | return len; | 200 | return len; |
201 | } | 201 | } |
@@ -209,12 +209,12 @@ void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx) | |||
209 | // clean up disposed packets | 209 | // clean up disposed packets |
210 | while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) { | 210 | while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) { |
211 | if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) { | 211 | if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) { |
212 | pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8; | 212 | pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8; |
213 | pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1); | 213 | pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1); |
214 | DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE); | 214 | DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE); |
215 | } else { | 215 | } else { |
216 | // first packet is not disposed, so we stop cleaning now | 216 | // first packet is not disposed, so we stop cleaning now |
217 | break; | 217 | break; |
218 | } | 218 | } |
219 | } | 219 | } |
220 | } | 220 | } |
@@ -242,8 +242,8 @@ ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* | |||
242 | curpktstatus = rbuf->data[(idx + 2) % rbuf->size]; | 242 | curpktstatus = rbuf->data[(idx + 2) % rbuf->size]; |
243 | 243 | ||
244 | if (curpktstatus == PKT_READY) { | 244 | if (curpktstatus == PKT_READY) { |
245 | *pktlen = curpktlen; | 245 | *pktlen = curpktlen; |
246 | return idx; | 246 | return idx; |
247 | } | 247 | } |
248 | 248 | ||
249 | consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE; | 249 | consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE; |
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h index fa476f662f82..6d2560972771 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h | |||
@@ -106,7 +106,7 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); | |||
106 | ** returns number of bytes transferred or -EFAULT | 106 | ** returns number of bytes transferred or -EFAULT |
107 | */ | 107 | */ |
108 | extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, | 108 | extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, |
109 | size_t len, int usermem); | 109 | size_t len, int usermem); |
110 | 110 | ||
111 | 111 | ||
112 | /* write routines & macros */ | 112 | /* write routines & macros */ |
@@ -121,7 +121,7 @@ extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, | |||
121 | ** returns number of bytes transferred or -EFAULT | 121 | ** returns number of bytes transferred or -EFAULT |
122 | */ | 122 | */ |
123 | extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, | 123 | extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, |
124 | size_t len); | 124 | size_t len); |
125 | 125 | ||
126 | 126 | ||
127 | /** | 127 | /** |
@@ -133,7 +133,7 @@ extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, | |||
133 | * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL. | 133 | * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL. |
134 | */ | 134 | */ |
135 | extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, | 135 | extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, |
136 | size_t len); | 136 | size_t len); |
137 | 137 | ||
138 | /** | 138 | /** |
139 | * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this | 139 | * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this |
@@ -149,7 +149,7 @@ extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, | |||
149 | * returns Number of bytes read, or -EFAULT. | 149 | * returns Number of bytes read, or -EFAULT. |
150 | */ | 150 | */ |
151 | extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | 151 | extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, |
152 | int offset, u8* buf, size_t len, int usermem); | 152 | int offset, u8* buf, size_t len, int usermem); |
153 | 153 | ||
154 | /** | 154 | /** |
155 | * Dispose of a packet in the ring buffer. | 155 | * Dispose of a packet in the ring buffer. |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index a4aee8665854..06b696e9acbd 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -92,10 +92,10 @@ static int dvb_device_open(struct inode *inode, struct file *file) | |||
92 | old_fops = file->f_op; | 92 | old_fops = file->f_op; |
93 | file->f_op = fops_get(dvbdev->fops); | 93 | file->f_op = fops_get(dvbdev->fops); |
94 | if(file->f_op->open) | 94 | if(file->f_op->open) |
95 | err = file->f_op->open(inode,file); | 95 | err = file->f_op->open(inode,file); |
96 | if (err) { | 96 | if (err) { |
97 | fops_put(file->f_op); | 97 | fops_put(file->f_op); |
98 | file->f_op = fops_get(old_fops); | 98 | file->f_op = fops_get(old_fops); |
99 | } | 99 | } |
100 | fops_put(old_fops); | 100 | fops_put(old_fops); |
101 | return err; | 101 | return err; |
@@ -356,18 +356,18 @@ int dvb_usercopy(struct inode *inode, struct file *file, | |||
356 | case _IOC_WRITE: | 356 | case _IOC_WRITE: |
357 | case (_IOC_WRITE | _IOC_READ): | 357 | case (_IOC_WRITE | _IOC_READ): |
358 | if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { | 358 | if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { |
359 | parg = sbuf; | 359 | parg = sbuf; |
360 | } else { | 360 | } else { |
361 | /* too big to allocate from stack */ | 361 | /* too big to allocate from stack */ |
362 | mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); | 362 | mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); |
363 | if (NULL == mbuf) | 363 | if (NULL == mbuf) |
364 | return -ENOMEM; | 364 | return -ENOMEM; |
365 | parg = mbuf; | 365 | parg = mbuf; |
366 | } | 366 | } |
367 | 367 | ||
368 | err = -EFAULT; | 368 | err = -EFAULT; |
369 | if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) | 369 | if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) |
370 | goto out; | 370 | goto out; |
371 | break; | 371 | break; |
372 | } | 372 | } |
373 | 373 | ||
@@ -384,7 +384,7 @@ int dvb_usercopy(struct inode *inode, struct file *file, | |||
384 | case _IOC_READ: | 384 | case _IOC_READ: |
385 | case (_IOC_WRITE | _IOC_READ): | 385 | case (_IOC_WRITE | _IOC_READ): |
386 | if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) | 386 | if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) |
387 | err = -EFAULT; | 387 | err = -EFAULT; |
388 | break; | 388 | break; |
389 | } | 389 | } |
390 | 390 | ||
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 0cc6e4a0e27c..74ed5853f0fb 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h | |||
@@ -97,7 +97,7 @@ we simply define out own dvb_usercopy(), which will hopefully become | |||
97 | generic_usercopy() someday... */ | 97 | generic_usercopy() someday... */ |
98 | 98 | ||
99 | extern int dvb_usercopy(struct inode *inode, struct file *file, | 99 | extern int dvb_usercopy(struct inode *inode, struct file *file, |
100 | unsigned int cmd, unsigned long arg, | 100 | unsigned int cmd, unsigned long arg, |
101 | int (*func)(struct inode *inode, struct file *file, | 101 | int (*func)(struct inode *inode, struct file *file, |
102 | unsigned int cmd, void *arg)); | 102 | unsigned int cmd, void *arg)); |
103 | 103 | ||
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 54e2b29076b1..90a69d343b79 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -37,16 +37,16 @@ config DVB_USB_DIBUSB_MB | |||
37 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator. | 37 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator. |
38 | 38 | ||
39 | Devices supported by this driver: | 39 | Devices supported by this driver: |
40 | TwinhanDTV USB-Ter (VP7041) | 40 | Artec T1 USB1.1 boxes |
41 | TwinhanDTV Magic Box (VP7041e) | 41 | Avermedia AverTV DVBT USB1.1 |
42 | KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0 | ||
43 | Hama DVB-T USB1.1-Box | ||
44 | DiBcom USB1.1 reference devices (non-public) | ||
45 | Ultima Electronic/Artec T1 USB TVBOX | ||
46 | Compro Videomate DVB-U2000 - DVB-T USB | 42 | Compro Videomate DVB-U2000 - DVB-T USB |
43 | DiBcom USB1.1 reference devices (non-public) | ||
47 | Grandtec DVB-T USB | 44 | Grandtec DVB-T USB |
48 | Avermedia AverTV DVBT USB1.1 | 45 | Hama DVB-T USB1.1-Box |
49 | Artec T1 USB1.1 boxes | 46 | KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0 |
47 | TwinhanDTV Magic Box (VP7041e) | ||
48 | TwinhanDTV USB-Ter (VP7041) | ||
49 | Ultima Electronic/Artec T1 USB TVBOX | ||
50 | 50 | ||
51 | The VP7041 seems to be identical to "CTS Portable" (Chinese | 51 | The VP7041 seems to be identical to "CTS Portable" (Chinese |
52 | Television System). | 52 | Television System). |
@@ -54,6 +54,12 @@ config DVB_USB_DIBUSB_MB | |||
54 | Say Y if you own such a device and want to use it. You should build it as | 54 | Say Y if you own such a device and want to use it. You should build it as |
55 | a module. | 55 | a module. |
56 | 56 | ||
57 | config DVB_USB_DIBUSB_MB_FAULTY | ||
58 | bool "Support faulty USB IDs" | ||
59 | depends on DVB_USB_DIBUSB_MB | ||
60 | help | ||
61 | Support for faulty USB IDs due to an invalid EEPROM on some Artec devices. | ||
62 | |||
57 | config DVB_USB_DIBUSB_MC | 63 | config DVB_USB_DIBUSB_MC |
58 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" | 64 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" |
59 | depends on DVB_USB | 65 | depends on DVB_USB |
@@ -63,8 +69,8 @@ config DVB_USB_DIBUSB_MC | |||
63 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator. | 69 | DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator. |
64 | 70 | ||
65 | Devices supported by this driver: | 71 | Devices supported by this driver: |
66 | DiBcom USB2.0 reference devices (non-public) | ||
67 | Artec T1 USB2.0 boxes | 72 | Artec T1 USB2.0 boxes |
73 | DiBcom USB2.0 reference devices (non-public) | ||
68 | 74 | ||
69 | Say Y if you own such a device and want to use it. You should build it as | 75 | Say Y if you own such a device and want to use it. You should build it as |
70 | a module. | 76 | a module. |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index d05fab01cccd..358ed153865f 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
@@ -11,10 +11,11 @@ | |||
11 | * design, so it can be reused for the "analogue-only" device (if it will | 11 | * design, so it can be reused for the "analogue-only" device (if it will |
12 | * appear at all). | 12 | * appear at all). |
13 | * | 13 | * |
14 | * TODO: check if the cx25840-driver (from ivtv) can be used for the analogue | 14 | * TODO: Use the cx25840-driver for the analogue part |
15 | * part | ||
16 | * | 15 | * |
17 | * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) | 16 | * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) |
17 | * Copyright (C) 2005 Michael Krufky (mkrufky@m1k.net) | ||
18 | * Copyright (C) 2006 Chris Pascoe (c.pascoe@itee.uq.edu.au) | ||
18 | * | 19 | * |
19 | * This program is free software; you can redistribute it and/or modify it | 20 | * This program is free software; you can redistribute it and/or modify it |
20 | * under the terms of the GNU General Public License as published by the Free | 21 | * under the terms of the GNU General Public License as published by the Free |
@@ -25,6 +26,9 @@ | |||
25 | #include "cxusb.h" | 26 | #include "cxusb.h" |
26 | 27 | ||
27 | #include "cx22702.h" | 28 | #include "cx22702.h" |
29 | #include "lgdt330x.h" | ||
30 | #include "mt352.h" | ||
31 | #include "mt352_priv.h" | ||
28 | 32 | ||
29 | /* debug */ | 33 | /* debug */ |
30 | int dvb_usb_cxusb_debug; | 34 | int dvb_usb_cxusb_debug; |
@@ -156,6 +160,99 @@ static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) | |||
156 | return 0; | 160 | return 0; |
157 | } | 161 | } |
158 | 162 | ||
163 | static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | ||
164 | { | ||
165 | struct dvb_usb_rc_key *keymap = d->props.rc_key_map; | ||
166 | u8 ircode[4]; | ||
167 | int i; | ||
168 | |||
169 | cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4); | ||
170 | |||
171 | *event = 0; | ||
172 | *state = REMOTE_NO_KEY_PRESSED; | ||
173 | |||
174 | for (i = 0; i < d->props.rc_key_map_size; i++) { | ||
175 | if (keymap[i].custom == ircode[2] && | ||
176 | keymap[i].data == ircode[3]) { | ||
177 | *event = keymap[i].event; | ||
178 | *state = REMOTE_KEY_PRESSED; | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | struct dvb_usb_rc_key dvico_mce_rc_keys[] = { | ||
188 | { 0xfe, 0x02, KEY_TV }, | ||
189 | { 0xfe, 0x0e, KEY_MP3 }, | ||
190 | { 0xfe, 0x1a, KEY_DVD }, | ||
191 | { 0xfe, 0x1e, KEY_FAVORITES }, | ||
192 | { 0xfe, 0x16, KEY_SETUP }, | ||
193 | { 0xfe, 0x46, KEY_POWER2 }, | ||
194 | { 0xfe, 0x0a, KEY_EPG }, | ||
195 | { 0xfe, 0x49, KEY_BACK }, | ||
196 | { 0xfe, 0x4d, KEY_MENU }, | ||
197 | { 0xfe, 0x51, KEY_UP }, | ||
198 | { 0xfe, 0x5b, KEY_LEFT }, | ||
199 | { 0xfe, 0x5f, KEY_RIGHT }, | ||
200 | { 0xfe, 0x53, KEY_DOWN }, | ||
201 | { 0xfe, 0x5e, KEY_OK }, | ||
202 | { 0xfe, 0x59, KEY_INFO }, | ||
203 | { 0xfe, 0x55, KEY_TAB }, | ||
204 | { 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */ | ||
205 | { 0xfe, 0x12, KEY_NEXTSONG }, /* Skip */ | ||
206 | { 0xfe, 0x42, KEY_ENTER }, /* Windows/Start */ | ||
207 | { 0xfe, 0x15, KEY_VOLUMEUP }, | ||
208 | { 0xfe, 0x05, KEY_VOLUMEDOWN }, | ||
209 | { 0xfe, 0x11, KEY_CHANNELUP }, | ||
210 | { 0xfe, 0x09, KEY_CHANNELDOWN }, | ||
211 | { 0xfe, 0x52, KEY_CAMERA }, | ||
212 | { 0xfe, 0x5a, KEY_TUNER }, /* Live */ | ||
213 | { 0xfe, 0x19, KEY_OPEN }, | ||
214 | { 0xfe, 0x0b, KEY_1 }, | ||
215 | { 0xfe, 0x17, KEY_2 }, | ||
216 | { 0xfe, 0x1b, KEY_3 }, | ||
217 | { 0xfe, 0x07, KEY_4 }, | ||
218 | { 0xfe, 0x50, KEY_5 }, | ||
219 | { 0xfe, 0x54, KEY_6 }, | ||
220 | { 0xfe, 0x48, KEY_7 }, | ||
221 | { 0xfe, 0x4c, KEY_8 }, | ||
222 | { 0xfe, 0x58, KEY_9 }, | ||
223 | { 0xfe, 0x13, KEY_ANGLE }, /* Aspect */ | ||
224 | { 0xfe, 0x03, KEY_0 }, | ||
225 | { 0xfe, 0x1f, KEY_ZOOM }, | ||
226 | { 0xfe, 0x43, KEY_REWIND }, | ||
227 | { 0xfe, 0x47, KEY_PLAYPAUSE }, | ||
228 | { 0xfe, 0x4f, KEY_FASTFORWARD }, | ||
229 | { 0xfe, 0x57, KEY_MUTE }, | ||
230 | { 0xfe, 0x0d, KEY_STOP }, | ||
231 | { 0xfe, 0x01, KEY_RECORD }, | ||
232 | { 0xfe, 0x4e, KEY_POWER }, | ||
233 | }; | ||
234 | |||
235 | static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) | ||
236 | { | ||
237 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; | ||
238 | static u8 reset [] = { RESET, 0x80 }; | ||
239 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | ||
240 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; | ||
241 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | ||
242 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | ||
243 | |||
244 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
245 | udelay(200); | ||
246 | mt352_write(fe, reset, sizeof(reset)); | ||
247 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
248 | |||
249 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
250 | mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); | ||
251 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
159 | struct cx22702_config cxusb_cx22702_config = { | 256 | struct cx22702_config cxusb_cx22702_config = { |
160 | .demod_address = 0x63, | 257 | .demod_address = 0x63, |
161 | 258 | ||
@@ -165,17 +262,47 @@ struct cx22702_config cxusb_cx22702_config = { | |||
165 | .pll_set = dvb_usb_pll_set_i2c, | 262 | .pll_set = dvb_usb_pll_set_i2c, |
166 | }; | 263 | }; |
167 | 264 | ||
265 | struct lgdt330x_config cxusb_lgdt330x_config = { | ||
266 | .demod_address = 0x0e, | ||
267 | .demod_chip = LGDT3303, | ||
268 | .pll_set = dvb_usb_pll_set_i2c, | ||
269 | }; | ||
270 | |||
271 | struct mt352_config cxusb_dee1601_config = { | ||
272 | .demod_address = 0x0f, | ||
273 | .demod_init = cxusb_dee1601_demod_init, | ||
274 | .pll_set = dvb_usb_pll_set, | ||
275 | }; | ||
276 | |||
168 | /* Callbacks for DVB USB */ | 277 | /* Callbacks for DVB USB */ |
169 | static int cxusb_tuner_attach(struct dvb_usb_device *d) | 278 | static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d) |
170 | { | 279 | { |
171 | u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 }; | 280 | u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 }; |
172 | d->pll_addr = 0x61; | 281 | d->pll_addr = 0x61; |
173 | memcpy(d->pll_init,bpll,4); | 282 | memcpy(d->pll_init, bpll, 4); |
174 | d->pll_desc = &dvb_pll_fmd1216me; | 283 | d->pll_desc = &dvb_pll_fmd1216me; |
175 | return 0; | 284 | return 0; |
176 | } | 285 | } |
177 | 286 | ||
178 | static int cxusb_frontend_attach(struct dvb_usb_device *d) | 287 | static int cxusb_lgh064f_tuner_attach(struct dvb_usb_device *d) |
288 | { | ||
289 | u8 bpll[4] = { 0x00, 0x00, 0x18, 0x50 }; | ||
290 | /* bpll[2] : unset bit 3, set bits 4&5 | ||
291 | bpll[3] : 0x50 - digital, 0x20 - analog */ | ||
292 | d->pll_addr = 0x61; | ||
293 | memcpy(d->pll_init, bpll, 4); | ||
294 | d->pll_desc = &dvb_pll_tdvs_tua6034; | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d) | ||
299 | { | ||
300 | d->pll_addr = 0x61; | ||
301 | d->pll_desc = &dvb_pll_thomson_dtt7579; | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d) | ||
179 | { | 306 | { |
180 | u8 b; | 307 | u8 b; |
181 | if (usb_set_interface(d->udev,0,6) < 0) | 308 | if (usb_set_interface(d->udev,0,6) < 0) |
@@ -189,22 +316,84 @@ static int cxusb_frontend_attach(struct dvb_usb_device *d) | |||
189 | return -EIO; | 316 | return -EIO; |
190 | } | 317 | } |
191 | 318 | ||
319 | static int cxusb_lgdt330x_frontend_attach(struct dvb_usb_device *d) | ||
320 | { | ||
321 | if (usb_set_interface(d->udev,0,7) < 0) | ||
322 | err("set interface failed"); | ||
323 | |||
324 | cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); | ||
325 | |||
326 | if ((d->fe = lgdt330x_attach(&cxusb_lgdt330x_config, &d->i2c_adap)) != NULL) | ||
327 | return 0; | ||
328 | |||
329 | return -EIO; | ||
330 | } | ||
331 | |||
332 | static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d) | ||
333 | { | ||
334 | if (usb_set_interface(d->udev,0,0) < 0) | ||
335 | err("set interface failed"); | ||
336 | |||
337 | cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); | ||
338 | |||
339 | if ((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) | ||
340 | return 0; | ||
341 | |||
342 | return -EIO; | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * DViCO bluebird firmware needs the "warm" product ID to be patched into the | ||
347 | * firmware file before download. | ||
348 | */ | ||
349 | |||
350 | #define BLUEBIRD_01_ID_OFFSET 6638 | ||
351 | static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, const struct firmware *fw) | ||
352 | { | ||
353 | if (fw->size < BLUEBIRD_01_ID_OFFSET + 4) | ||
354 | return -EINVAL; | ||
355 | |||
356 | if (fw->data[BLUEBIRD_01_ID_OFFSET] == (USB_VID_DVICO & 0xff) && | ||
357 | fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) { | ||
358 | |||
359 | /* FIXME: are we allowed to change the fw-data ? */ | ||
360 | fw->data[BLUEBIRD_01_ID_OFFSET + 2] = udev->descriptor.idProduct + 1; | ||
361 | fw->data[BLUEBIRD_01_ID_OFFSET + 3] = udev->descriptor.idProduct >> 8; | ||
362 | |||
363 | return usb_cypress_load_firmware(udev,fw,CYPRESS_FX2); | ||
364 | } | ||
365 | |||
366 | return -EINVAL; | ||
367 | } | ||
368 | |||
192 | /* DVB USB Driver stuff */ | 369 | /* DVB USB Driver stuff */ |
193 | static struct dvb_usb_properties cxusb_properties; | 370 | static struct dvb_usb_properties cxusb_medion_properties; |
371 | static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties; | ||
372 | static struct dvb_usb_properties cxusb_bluebird_dee1601_properties; | ||
194 | 373 | ||
195 | static int cxusb_probe(struct usb_interface *intf, | 374 | static int cxusb_probe(struct usb_interface *intf, |
196 | const struct usb_device_id *id) | 375 | const struct usb_device_id *id) |
197 | { | 376 | { |
198 | return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE,NULL); | 377 | if (dvb_usb_device_init(intf,&cxusb_medion_properties,THIS_MODULE,NULL) == 0 || |
378 | dvb_usb_device_init(intf,&cxusb_bluebird_lgh064f_properties,THIS_MODULE,NULL) == 0 || | ||
379 | dvb_usb_device_init(intf,&cxusb_bluebird_dee1601_properties,THIS_MODULE,NULL) == 0) { | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | return -EINVAL; | ||
199 | } | 384 | } |
200 | 385 | ||
201 | static struct usb_device_id cxusb_table [] = { | 386 | static struct usb_device_id cxusb_table [] = { |
202 | { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) }, | 387 | { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) }, |
388 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) }, | ||
389 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) }, | ||
390 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_COLD) }, | ||
391 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_WARM) }, | ||
203 | {} /* Terminating entry */ | 392 | {} /* Terminating entry */ |
204 | }; | 393 | }; |
205 | MODULE_DEVICE_TABLE (usb, cxusb_table); | 394 | MODULE_DEVICE_TABLE (usb, cxusb_table); |
206 | 395 | ||
207 | static struct dvb_usb_properties cxusb_properties = { | 396 | static struct dvb_usb_properties cxusb_medion_properties = { |
208 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 397 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
209 | 398 | ||
210 | .usb_ctrl = CYPRESS_FX2, | 399 | .usb_ctrl = CYPRESS_FX2, |
@@ -213,8 +402,8 @@ static struct dvb_usb_properties cxusb_properties = { | |||
213 | 402 | ||
214 | .streaming_ctrl = cxusb_streaming_ctrl, | 403 | .streaming_ctrl = cxusb_streaming_ctrl, |
215 | .power_ctrl = cxusb_power_ctrl, | 404 | .power_ctrl = cxusb_power_ctrl, |
216 | .frontend_attach = cxusb_frontend_attach, | 405 | .frontend_attach = cxusb_cx22702_frontend_attach, |
217 | .tuner_attach = cxusb_tuner_attach, | 406 | .tuner_attach = cxusb_fmd1216me_tuner_attach, |
218 | 407 | ||
219 | .i2c_algo = &cxusb_i2c_algo, | 408 | .i2c_algo = &cxusb_i2c_algo, |
220 | 409 | ||
@@ -240,6 +429,91 @@ static struct dvb_usb_properties cxusb_properties = { | |||
240 | } | 429 | } |
241 | }; | 430 | }; |
242 | 431 | ||
432 | static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = { | ||
433 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
434 | |||
435 | .usb_ctrl = DEVICE_SPECIFIC, | ||
436 | .firmware = "dvb-usb-bluebird-01.fw", | ||
437 | .download_firmware = bluebird_patch_dvico_firmware_download, | ||
438 | /* use usb alt setting 0 for EP4 transfer (dvb-t), | ||
439 | use usb alt setting 7 for EP2 transfer (atsc) */ | ||
440 | |||
441 | .size_of_priv = sizeof(struct cxusb_state), | ||
442 | |||
443 | .streaming_ctrl = cxusb_streaming_ctrl, | ||
444 | .power_ctrl = cxusb_power_ctrl, | ||
445 | .frontend_attach = cxusb_lgdt330x_frontend_attach, | ||
446 | .tuner_attach = cxusb_lgh064f_tuner_attach, | ||
447 | |||
448 | .i2c_algo = &cxusb_i2c_algo, | ||
449 | |||
450 | .generic_bulk_ctrl_endpoint = 0x01, | ||
451 | /* parameter for the MPEG2-data transfer */ | ||
452 | .urb = { | ||
453 | .type = DVB_USB_BULK, | ||
454 | .count = 5, | ||
455 | .endpoint = 0x02, | ||
456 | .u = { | ||
457 | .bulk = { | ||
458 | .buffersize = 8192, | ||
459 | } | ||
460 | } | ||
461 | }, | ||
462 | |||
463 | .num_device_descs = 1, | ||
464 | .devices = { | ||
465 | { "DViCO FusionHDTV5 USB Gold", | ||
466 | { &cxusb_table[1], NULL }, | ||
467 | { &cxusb_table[2], NULL }, | ||
468 | }, | ||
469 | } | ||
470 | }; | ||
471 | |||
472 | static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = { | ||
473 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
474 | |||
475 | .usb_ctrl = DEVICE_SPECIFIC, | ||
476 | .firmware = "dvb-usb-bluebird-01.fw", | ||
477 | .download_firmware = bluebird_patch_dvico_firmware_download, | ||
478 | /* use usb alt setting 0 for EP4 transfer (dvb-t), | ||
479 | use usb alt setting 7 for EP2 transfer (atsc) */ | ||
480 | |||
481 | .size_of_priv = sizeof(struct cxusb_state), | ||
482 | |||
483 | .streaming_ctrl = cxusb_streaming_ctrl, | ||
484 | .power_ctrl = cxusb_power_ctrl, | ||
485 | .frontend_attach = cxusb_dee1601_frontend_attach, | ||
486 | .tuner_attach = cxusb_dee1601_tuner_attach, | ||
487 | |||
488 | .i2c_algo = &cxusb_i2c_algo, | ||
489 | |||
490 | .rc_interval = 150, | ||
491 | .rc_key_map = dvico_mce_rc_keys, | ||
492 | .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys), | ||
493 | .rc_query = cxusb_rc_query, | ||
494 | |||
495 | .generic_bulk_ctrl_endpoint = 0x01, | ||
496 | /* parameter for the MPEG2-data transfer */ | ||
497 | .urb = { | ||
498 | .type = DVB_USB_BULK, | ||
499 | .count = 5, | ||
500 | .endpoint = 0x04, | ||
501 | .u = { | ||
502 | .bulk = { | ||
503 | .buffersize = 8192, | ||
504 | } | ||
505 | } | ||
506 | }, | ||
507 | |||
508 | .num_device_descs = 1, | ||
509 | .devices = { | ||
510 | { "DViCO FusionHDTV DVB-T Dual USB", | ||
511 | { &cxusb_table[3], NULL }, | ||
512 | { &cxusb_table[4], NULL }, | ||
513 | }, | ||
514 | } | ||
515 | }; | ||
516 | |||
243 | static struct usb_driver cxusb_driver = { | 517 | static struct usb_driver cxusb_driver = { |
244 | .name = "dvb_usb_cxusb", | 518 | .name = "dvb_usb_cxusb", |
245 | .probe = cxusb_probe, | 519 | .probe = cxusb_probe, |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h index 135c2a81f581..087c99427853 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.h +++ b/drivers/media/dvb/dvb-usb/cxusb.h | |||
@@ -21,6 +21,8 @@ extern int dvb_usb_cxusb_debug; | |||
21 | #define CMD_STREAMING_ON 0x36 | 21 | #define CMD_STREAMING_ON 0x36 |
22 | #define CMD_STREAMING_OFF 0x37 | 22 | #define CMD_STREAMING_OFF 0x37 |
23 | 23 | ||
24 | #define CMD_GET_IR_CODE 0x47 | ||
25 | |||
24 | #define CMD_ANALOG 0x50 | 26 | #define CMD_ANALOG 0x50 |
25 | #define CMD_DIGITAL 0x51 | 27 | #define CMD_DIGITAL 0x51 |
26 | 28 | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index 52ac3e5adf5d..dd5a13195886 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c | |||
@@ -65,11 +65,11 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d) | |||
65 | d->tuner_pass_ctrl(d->fe,0,msg[0].addr); | 65 | d->tuner_pass_ctrl(d->fe,0,msg[0].addr); |
66 | 66 | ||
67 | if (b2[0] == 0xfe) { | 67 | if (b2[0] == 0xfe) { |
68 | info("this device has the Thomson Cable onboard. Which is default."); | 68 | info("This device has the Thomson Cable onboard. Which is default."); |
69 | dibusb_thomson_tuner_attach(d); | 69 | dibusb_thomson_tuner_attach(d); |
70 | } else { | 70 | } else { |
71 | u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab }; | 71 | u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab }; |
72 | info("this device has the Panasonic ENV77H11D5 onboard."); | 72 | info("This device has the Panasonic ENV77H11D5 onboard."); |
73 | d->pll_addr = 0x60; | 73 | d->pll_addr = 0x60; |
74 | memcpy(d->pll_init,bpll,4); | 74 | memcpy(d->pll_init,bpll,4); |
75 | d->pll_desc = &dvb_pll_tda665x; | 75 | d->pll_desc = &dvb_pll_tda665x; |
@@ -98,15 +98,15 @@ static int dibusb_probe(struct usb_interface *intf, | |||
98 | 98 | ||
99 | /* do not change the order of the ID table */ | 99 | /* do not change the order of the ID table */ |
100 | static struct usb_device_id dibusb_dib3000mb_table [] = { | 100 | static struct usb_device_id dibusb_dib3000mb_table [] = { |
101 | /* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD)}, | 101 | /* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD) }, |
102 | /* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM)}, | 102 | /* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM) }, |
103 | /* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, | 103 | /* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, |
104 | /* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, | 104 | /* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, |
105 | /* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, | 105 | /* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, |
106 | /* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) }, | 106 | /* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) }, |
107 | /* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) }, | 107 | /* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) }, |
108 | /* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, | 108 | /* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, |
109 | /* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, | 109 | /* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, |
110 | /* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) }, | 110 | /* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) }, |
111 | /* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) }, | 111 | /* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) }, |
112 | /* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) }, | 112 | /* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) }, |
@@ -117,27 +117,34 @@ static struct usb_device_id dibusb_dib3000mb_table [] = { | |||
117 | /* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) }, | 117 | /* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) }, |
118 | /* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) }, | 118 | /* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) }, |
119 | /* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) }, | 119 | /* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) }, |
120 | /* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, | 120 | /* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, |
121 | /* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, | 121 | /* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, |
122 | /* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, | 122 | /* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, |
123 | /* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, | 123 | /* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, |
124 | /* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, | 124 | /* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, |
125 | 125 | ||
126 | /* device ID with default DIBUSB2_0-firmware and with the hacked firmware */ | 126 | /* device ID with default DIBUSB2_0-firmware and with the hacked firmware */ |
127 | /* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, | 127 | /* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, |
128 | /* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, | 128 | /* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, |
129 | /* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, | 129 | /* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, |
130 | 130 | ||
131 | /* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, | 131 | /* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, |
132 | 132 | ||
133 | /* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, | 133 | /* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, |
134 | /* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, | 134 | /* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, |
135 | 135 | ||
136 | // #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs | 136 | /* |
137 | * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices | ||
138 | * we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that | ||
139 | * have been left on the device. If you don't have such a device but an Artec | ||
140 | * device that's supposed to work with this driver but is not detected by it, | ||
141 | * free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config. | ||
142 | */ | ||
137 | 143 | ||
138 | #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs | 144 | #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY |
139 | /* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, | 145 | /* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, |
140 | #endif | 146 | #endif |
147 | |||
141 | { } /* Terminating entry */ | 148 | { } /* Terminating entry */ |
142 | }; | 149 | }; |
143 | MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); | 150 | MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); |
@@ -257,7 +264,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { | |||
257 | } | 264 | } |
258 | }, | 265 | }, |
259 | 266 | ||
260 | #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs | 267 | #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY |
261 | .num_device_descs = 2, | 268 | .num_device_descs = 2, |
262 | #else | 269 | #else |
263 | .num_device_descs = 1, | 270 | .num_device_descs = 1, |
@@ -267,11 +274,12 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { | |||
267 | { &dibusb_dib3000mb_table[20], NULL }, | 274 | { &dibusb_dib3000mb_table[20], NULL }, |
268 | { &dibusb_dib3000mb_table[21], NULL }, | 275 | { &dibusb_dib3000mb_table[21], NULL }, |
269 | }, | 276 | }, |
270 | #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs | 277 | #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY |
271 | { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", | 278 | { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", |
272 | { &dibusb_dib3000mb_table[30], NULL }, | 279 | { &dibusb_dib3000mb_table[30], NULL }, |
273 | { NULL }, | 280 | { NULL }, |
274 | }, | 281 | }, |
282 | { NULL }, | ||
275 | #endif | 283 | #endif |
276 | } | 284 | } |
277 | }; | 285 | }; |
@@ -323,6 +331,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = { | |||
323 | { &dibusb_dib3000mb_table[27], NULL }, | 331 | { &dibusb_dib3000mb_table[27], NULL }, |
324 | { NULL } | 332 | { NULL } |
325 | }, | 333 | }, |
334 | { NULL }, | ||
326 | } | 335 | } |
327 | }; | 336 | }; |
328 | 337 | ||
@@ -369,6 +378,7 @@ static struct dvb_usb_properties artec_t1_usb2_properties = { | |||
369 | { &dibusb_dib3000mb_table[28], NULL }, | 378 | { &dibusb_dib3000mb_table[28], NULL }, |
370 | { &dibusb_dib3000mb_table[29], NULL }, | 379 | { &dibusb_dib3000mb_table[29], NULL }, |
371 | }, | 380 | }, |
381 | { NULL }, | ||
372 | } | 382 | } |
373 | }; | 383 | }; |
374 | 384 | ||
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index 450417a9e64b..e6c55c9c9417 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c | |||
@@ -32,7 +32,7 @@ static int digitv_ctrl_msg(struct dvb_usb_device *d, | |||
32 | sndbuf[1] = vv; | 32 | sndbuf[1] = vv; |
33 | sndbuf[2] = wo ? wlen : rlen; | 33 | sndbuf[2] = wo ? wlen : rlen; |
34 | 34 | ||
35 | if (!wo) { | 35 | if (wo) { |
36 | memcpy(&sndbuf[3],wbuf,wlen); | 36 | memcpy(&sndbuf[3],wbuf,wlen); |
37 | dvb_usb_generic_write(d,sndbuf,7); | 37 | dvb_usb_generic_write(d,sndbuf,7); |
38 | } else { | 38 | } else { |
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index 6e2bac873445..130ea7f21f5e 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c | |||
@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = { | |||
151 | .cold_ids = { &dtt200u_usb_table[0], NULL }, | 151 | .cold_ids = { &dtt200u_usb_table[0], NULL }, |
152 | .warm_ids = { &dtt200u_usb_table[1], NULL }, | 152 | .warm_ids = { &dtt200u_usb_table[1], NULL }, |
153 | }, | 153 | }, |
154 | { NULL }, | 154 | { 0 }, |
155 | } | 155 | } |
156 | }; | 156 | }; |
157 | 157 | ||
@@ -160,7 +160,7 @@ static struct dvb_usb_properties wt220u_properties = { | |||
160 | .pid_filter_count = 15, | 160 | .pid_filter_count = 15, |
161 | 161 | ||
162 | .usb_ctrl = CYPRESS_FX2, | 162 | .usb_ctrl = CYPRESS_FX2, |
163 | .firmware = "dvb-usb-wt220u-01.fw", | 163 | .firmware = "dvb-usb-wt220u-02.fw", |
164 | 164 | ||
165 | .power_ctrl = dtt200u_power_ctrl, | 165 | .power_ctrl = dtt200u_power_ctrl, |
166 | .streaming_ctrl = dtt200u_streaming_ctrl, | 166 | .streaming_ctrl = dtt200u_streaming_ctrl, |
@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = { | |||
192 | .cold_ids = { &dtt200u_usb_table[2], NULL }, | 192 | .cold_ids = { &dtt200u_usb_table[2], NULL }, |
193 | .warm_ids = { &dtt200u_usb_table[3], NULL }, | 193 | .warm_ids = { &dtt200u_usb_table[3], NULL }, |
194 | }, | 194 | }, |
195 | { NULL }, | 195 | { 0 }, |
196 | } | 196 | } |
197 | }; | 197 | }; |
198 | 198 | ||
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h index 6f1f3042e21a..005b0a7df358 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.h +++ b/drivers/media/dvb/dvb-usb/dtt200u.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #define _DVB_USB_DTT200U_H_ | 13 | #define _DVB_USB_DTT200U_H_ |
14 | 14 | ||
15 | #define DVB_USB_LOG_PREFIX "dtt200u" | 15 | #define DVB_USB_LOG_PREFIX "dtt200u" |
16 | |||
16 | #include "dvb-usb.h" | 17 | #include "dvb-usb.h" |
17 | 18 | ||
18 | extern int dvb_usb_dtt200u_debug; | 19 | extern int dvb_usb_dtt200u_debug; |
@@ -25,15 +26,15 @@ extern int dvb_usb_dtt200u_debug; | |||
25 | * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal) | 26 | * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal) |
26 | */ | 27 | */ |
27 | 28 | ||
28 | #define GET_SPEED 0x00 | 29 | #define GET_SPEED 0x00 |
29 | #define GET_TUNE_STATUS 0x81 | 30 | #define GET_TUNE_STATUS 0x81 |
30 | #define GET_RC_CODE 0x84 | 31 | #define GET_RC_CODE 0x84 |
31 | #define GET_CONFIGURATION 0x88 | 32 | #define GET_CONFIGURATION 0x88 |
32 | #define GET_AGC 0x89 | 33 | #define GET_AGC 0x89 |
33 | #define GET_SNR 0x8a | 34 | #define GET_SNR 0x8a |
34 | #define GET_VIT_ERR_CNT 0x8c | 35 | #define GET_VIT_ERR_CNT 0x8c |
35 | #define GET_RS_ERR_CNT 0x8d | 36 | #define GET_RS_ERR_CNT 0x8d |
36 | #define GET_RS_UNCOR_BLK_CNT 0x8e | 37 | #define GET_RS_UNCOR_BLK_CNT 0x8e |
37 | 38 | ||
38 | /* write | 39 | /* write |
39 | * 01 - init | 40 | * 01 - init |
@@ -44,12 +45,12 @@ extern int dvb_usb_dtt200u_debug; | |||
44 | * 08 - transfer switch | 45 | * 08 - transfer switch |
45 | */ | 46 | */ |
46 | 47 | ||
47 | #define SET_INIT 0x01 | 48 | #define SET_INIT 0x01 |
48 | #define SET_RF_FREQ 0x02 | 49 | #define SET_RF_FREQ 0x02 |
49 | #define SET_BANDWIDTH 0x03 | 50 | #define SET_BANDWIDTH 0x03 |
50 | #define SET_PID_FILTER 0x04 | 51 | #define SET_PID_FILTER 0x04 |
51 | #define RESET_PID_FILTER 0x05 | 52 | #define RESET_PID_FILTER 0x05 |
52 | #define SET_STREAMING 0x08 | 53 | #define SET_STREAMING 0x08 |
53 | 54 | ||
54 | extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d); | 55 | extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d); |
55 | 56 | ||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h index 7300489d3e24..a3460bf2d9fa 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-common.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h | |||
@@ -24,7 +24,7 @@ extern int dvb_usb_disable_rc_polling; | |||
24 | #define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args) | 24 | #define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args) |
25 | 25 | ||
26 | /* commonly used methods */ | 26 | /* commonly used methods */ |
27 | extern int usb_cypress_load_firmware(struct usb_device *, const char *, int); | 27 | extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_properties *); |
28 | 28 | ||
29 | extern int dvb_usb_urb_submit(struct dvb_usb_device *); | 29 | extern int dvb_usb_urb_submit(struct dvb_usb_device *); |
30 | extern int dvb_usb_urb_kill(struct dvb_usb_device *); | 30 | extern int dvb_usb_urb_kill(struct dvb_usb_device *); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c index 5244e39770a0..8535895819fb 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c | |||
@@ -9,7 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | #include "dvb-usb-common.h" | 10 | #include "dvb-usb-common.h" |
11 | 11 | ||
12 | #include <linux/firmware.h> | ||
13 | #include <linux/usb.h> | 12 | #include <linux/usb.h> |
14 | 13 | ||
15 | struct usb_cypress_controller { | 14 | struct usb_cypress_controller { |
@@ -19,9 +18,10 @@ struct usb_cypress_controller { | |||
19 | }; | 18 | }; |
20 | 19 | ||
21 | static struct usb_cypress_controller cypress[] = { | 20 | static struct usb_cypress_controller cypress[] = { |
22 | { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 }, | 21 | { .id = DEVICE_SPECIFIC, .name = "Device specific", .cpu_cs_register = 0 }, |
23 | { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 }, | 22 | { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 }, |
24 | { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, | 23 | { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 }, |
24 | { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, | ||
25 | }; | 25 | }; |
26 | 26 | ||
27 | /* | 27 | /* |
@@ -30,71 +30,117 @@ static struct usb_cypress_controller cypress[] = { | |||
30 | static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len) | 30 | static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len) |
31 | { | 31 | { |
32 | return usb_control_msg(udev, usb_sndctrlpipe(udev,0), | 32 | return usb_control_msg(udev, usb_sndctrlpipe(udev,0), |
33 | 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ); | 33 | 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000); |
34 | } | 34 | } |
35 | 35 | ||
36 | int usb_cypress_load_firmware(struct usb_device *udev, const char *filename, int type) | 36 | int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type) |
37 | { | 37 | { |
38 | const struct firmware *fw = NULL; | 38 | struct hexline hx; |
39 | u16 addr; | 39 | u8 reset; |
40 | u8 *b,*p; | 40 | int ret,pos=0; |
41 | int ret = 0,i; | ||
42 | 41 | ||
43 | if ((ret = request_firmware(&fw, filename, &udev->dev)) != 0) { | 42 | /* stop the CPU */ |
44 | err("did not find the firmware file. (%s) " | 43 | reset = 1; |
45 | "Please see linux/Documentation/dvb/ for more details on firmware-problems.", | 44 | if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) |
46 | filename); | 45 | err("could not stop the USB controller CPU."); |
46 | |||
47 | while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) { | ||
48 | deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk); | ||
49 | ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len); | ||
50 | |||
51 | if (ret != hx.len) { | ||
52 | err("error while transferring firmware " | ||
53 | "(transferred size: %d, block size: %d)", | ||
54 | ret,hx.len); | ||
55 | ret = -EINVAL; | ||
56 | break; | ||
57 | } | ||
58 | } | ||
59 | if (ret < 0) { | ||
60 | err("firmware download failed at %d with %d",pos,ret); | ||
47 | return ret; | 61 | return ret; |
48 | } | 62 | } |
49 | 63 | ||
50 | info("downloading firmware from file '%s' to the '%s'",filename,cypress[type].name); | 64 | if (ret == 0) { |
51 | |||
52 | p = kmalloc(fw->size,GFP_KERNEL); | ||
53 | if (p != NULL) { | ||
54 | u8 reset; | ||
55 | /* | ||
56 | * you cannot use the fw->data as buffer for | ||
57 | * usb_control_msg, a new buffer has to be | ||
58 | * created | ||
59 | */ | ||
60 | memcpy(p,fw->data,fw->size); | ||
61 | |||
62 | /* stop the CPU */ | ||
63 | reset = 1; | ||
64 | if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) | ||
65 | err("could not stop the USB controller CPU."); | ||
66 | for(i = 0; p[i+3] == 0 && i < fw->size; ) { | ||
67 | b = (u8 *) &p[i]; | ||
68 | addr = cpu_to_le16( *((u16 *) &b[1]) ); | ||
69 | |||
70 | deb_fw("writing to address 0x%04x (buffer: 0x%02x%02x)\n",addr,b[1],b[2]); | ||
71 | |||
72 | ret = usb_cypress_writemem(udev,addr,&b[4],b[0]); | ||
73 | |||
74 | if (ret != b[0]) { | ||
75 | err("error while transferring firmware " | ||
76 | "(transferred size: %d, block size: %d)", | ||
77 | ret,b[0]); | ||
78 | ret = -EINVAL; | ||
79 | break; | ||
80 | } | ||
81 | i += 5 + b[0]; | ||
82 | } | ||
83 | /* length in ret */ | ||
84 | if (ret > 0) | ||
85 | ret = 0; | ||
86 | /* restart the CPU */ | 65 | /* restart the CPU */ |
87 | reset = 0; | 66 | reset = 0; |
88 | if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { | 67 | if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { |
89 | err("could not restart the USB controller CPU."); | 68 | err("could not restart the USB controller CPU."); |
90 | ret = -EINVAL; | 69 | ret = -EINVAL; |
91 | } | 70 | } |
71 | } else | ||
72 | ret = -EIO; | ||
92 | 73 | ||
93 | kfree(p); | 74 | return ret; |
94 | } else { | 75 | } |
95 | ret = -ENOMEM; | 76 | EXPORT_SYMBOL(usb_cypress_load_firmware); |
77 | |||
78 | int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties *props) | ||
79 | { | ||
80 | int ret; | ||
81 | const struct firmware *fw = NULL; | ||
82 | |||
83 | if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) { | ||
84 | err("did not find the firmware file. (%s) " | ||
85 | "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", | ||
86 | props->firmware,ret); | ||
87 | return ret; | ||
96 | } | 88 | } |
97 | release_firmware(fw); | ||
98 | 89 | ||
90 | info("downloading firmware from file '%s'",props->firmware); | ||
91 | |||
92 | switch (props->usb_ctrl) { | ||
93 | case CYPRESS_AN2135: | ||
94 | case CYPRESS_AN2235: | ||
95 | case CYPRESS_FX2: | ||
96 | ret = usb_cypress_load_firmware(udev, fw, props->usb_ctrl); | ||
97 | break; | ||
98 | case DEVICE_SPECIFIC: | ||
99 | if (props->download_firmware) | ||
100 | ret = props->download_firmware(udev,fw); | ||
101 | else { | ||
102 | err("BUG: driver didn't specified a download_firmware-callback, although it claims to have a DEVICE_SPECIFIC one."); | ||
103 | ret = -EINVAL; | ||
104 | } | ||
105 | break; | ||
106 | default: | ||
107 | ret = -EINVAL; | ||
108 | break; | ||
109 | } | ||
110 | |||
111 | release_firmware(fw); | ||
99 | return ret; | 112 | return ret; |
100 | } | 113 | } |
114 | |||
115 | int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos) | ||
116 | { | ||
117 | u8 *b = (u8 *) &fw->data[*pos]; | ||
118 | int data_offs = 4; | ||
119 | if (*pos >= fw->size) | ||
120 | return 0; | ||
121 | |||
122 | memset(hx,0,sizeof(struct hexline)); | ||
123 | |||
124 | hx->len = b[0]; | ||
125 | |||
126 | if ((*pos + hx->len + 4) >= fw->size) | ||
127 | return -EINVAL; | ||
128 | |||
129 | hx->addr = le16_to_cpu( *((u16 *) &b[1]) ); | ||
130 | hx->type = b[3]; | ||
131 | |||
132 | if (hx->type == 0x04) { | ||
133 | /* b[4] and b[5] are the Extended linear address record data field */ | ||
134 | hx->addr |= (b[4] << 24) | (b[5] << 16); | ||
135 | /* hx->len -= 2; | ||
136 | data_offs += 2; */ | ||
137 | } | ||
138 | memcpy(hx->data,&b[data_offs],hx->len); | ||
139 | hx->chk = b[hx->len + data_offs]; | ||
140 | |||
141 | *pos += hx->len + 5; | ||
142 | |||
143 | return *pos; | ||
144 | } | ||
145 | EXPORT_SYMBOL(dvb_usb_get_hexline); | ||
146 | |||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index da970947dfc7..9b254532af4d 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c | |||
@@ -52,9 +52,8 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) | |||
52 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; | 52 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; |
53 | int ret = 0; | 53 | int ret = 0; |
54 | 54 | ||
55 | /* if there is nothing to initialize */ | 55 | /* if pll_desc is not used */ |
56 | if (d->pll_init[0] == 0x00 && d->pll_init[1] == 0x00 && | 56 | if (d->pll_desc == NULL) |
57 | d->pll_init[2] == 0x00 && d->pll_init[3] == 0x00) | ||
58 | return 0; | 57 | return 0; |
59 | 58 | ||
60 | if (d->tuner_pass_ctrl) | 59 | if (d->tuner_pass_ctrl) |
@@ -80,6 +79,9 @@ int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep | |||
80 | { | 79 | { |
81 | struct dvb_usb_device *d = fe->dvb->priv; | 80 | struct dvb_usb_device *d = fe->dvb->priv; |
82 | 81 | ||
82 | if (d->pll_desc == NULL) | ||
83 | return 0; | ||
84 | |||
83 | deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); | 85 | deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); |
84 | 86 | ||
85 | b[0] = d->pll_addr << 1; | 87 | b[0] = d->pll_addr << 1; |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 6be99e537e12..d22934383226 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -86,11 +86,15 @@ | |||
86 | #define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 | 86 | #define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 |
87 | #define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 | 87 | #define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 |
88 | #define USB_PID_NEBULA_DIGITV 0x0201 | 88 | #define USB_PID_NEBULA_DIGITV 0x0201 |
89 | #define USB_PID_DVICO_BLUEBIRD_LGZ201 0xdb00 | ||
90 | #define USB_PID_DVICO_BLUEBIRD_TH7579 0xdb10 | ||
91 | #define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 | 89 | #define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 |
92 | #define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01 | 90 | #define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500 |
93 | #define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11 | 91 | #define USB_PID_DVICO_BLUEBIRD_LG064F_WARM 0xd501 |
92 | #define USB_PID_DVICO_BLUEBIRD_LGZ201_COLD 0xdb00 | ||
93 | #define USB_PID_DVICO_BLUEBIRD_LGZ201_WARM 0xdb01 | ||
94 | #define USB_PID_DVICO_BLUEBIRD_TH7579_COLD 0xdb10 | ||
95 | #define USB_PID_DVICO_BLUEBIRD_TH7579_WARM 0xdb11 | ||
96 | #define USB_PID_DVICO_BLUEBIRD_DEE1601_COLD 0xdb50 | ||
97 | #define USB_PID_DVICO_BLUEBIRD_DEE1601_WARM 0xdb51 | ||
94 | #define USB_PID_MEDION_MD95700 0x0932 | 98 | #define USB_PID_MEDION_MD95700 0x0932 |
95 | #define USB_PID_KYE_DVB_T_COLD 0x701e | 99 | #define USB_PID_KYE_DVB_T_COLD 0x701e |
96 | #define USB_PID_KYE_DVB_T_WARM 0x701f | 100 | #define USB_PID_KYE_DVB_T_WARM 0x701f |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index dd8e0b94edba..2e23060cbbca 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c | |||
@@ -138,6 +138,9 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties | |||
138 | 138 | ||
139 | int ret = -ENOMEM,cold=0; | 139 | int ret = -ENOMEM,cold=0; |
140 | 140 | ||
141 | if (du != NULL) | ||
142 | *du = NULL; | ||
143 | |||
141 | if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) { | 144 | if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) { |
142 | deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); | 145 | deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); |
143 | return -ENODEV; | 146 | return -ENODEV; |
@@ -145,38 +148,40 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties | |||
145 | 148 | ||
146 | if (cold) { | 149 | if (cold) { |
147 | info("found a '%s' in cold state, will try to load a firmware",desc->name); | 150 | info("found a '%s' in cold state, will try to load a firmware",desc->name); |
148 | ret = usb_cypress_load_firmware(udev,props->firmware,props->usb_ctrl); | 151 | ret = dvb_usb_download_firmware(udev,props); |
149 | } else { | 152 | if (!props->no_reconnect) |
150 | info("found a '%s' in warm state.",desc->name); | ||
151 | d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); | ||
152 | if (d == NULL) { | ||
153 | err("no memory for 'struct dvb_usb_device'"); | ||
154 | return ret; | 153 | return ret; |
154 | } | ||
155 | |||
156 | info("found a '%s' in warm state.",desc->name); | ||
157 | d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); | ||
158 | if (d == NULL) { | ||
159 | err("no memory for 'struct dvb_usb_device'"); | ||
160 | return ret; | ||
161 | } | ||
162 | memset(d,0,sizeof(struct dvb_usb_device)); | ||
163 | |||
164 | d->udev = udev; | ||
165 | memcpy(&d->props,props,sizeof(struct dvb_usb_properties)); | ||
166 | d->desc = desc; | ||
167 | d->owner = owner; | ||
168 | |||
169 | if (d->props.size_of_priv > 0) { | ||
170 | d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL); | ||
171 | if (d->priv == NULL) { | ||
172 | err("no memory for priv in 'struct dvb_usb_device'"); | ||
173 | kfree(d); | ||
174 | return -ENOMEM; | ||
155 | } | 175 | } |
156 | memset(d,0,sizeof(struct dvb_usb_device)); | 176 | memset(d->priv,0,d->props.size_of_priv); |
157 | 177 | } | |
158 | d->udev = udev; | ||
159 | memcpy(&d->props,props,sizeof(struct dvb_usb_properties)); | ||
160 | d->desc = desc; | ||
161 | d->owner = owner; | ||
162 | |||
163 | if (d->props.size_of_priv > 0) { | ||
164 | d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL); | ||
165 | if (d->priv == NULL) { | ||
166 | err("no memory for priv in 'struct dvb_usb_device'"); | ||
167 | kfree(d); | ||
168 | return -ENOMEM; | ||
169 | } | ||
170 | memset(d->priv,0,d->props.size_of_priv); | ||
171 | } | ||
172 | 178 | ||
173 | usb_set_intfdata(intf, d); | 179 | usb_set_intfdata(intf, d); |
174 | 180 | ||
175 | if (du != NULL) | 181 | if (du != NULL) |
176 | *du = d; | 182 | *du = d; |
177 | 183 | ||
178 | ret = dvb_usb_init(d); | 184 | ret = dvb_usb_init(d); |
179 | } | ||
180 | 185 | ||
181 | if (ret == 0) | 186 | if (ret == 0) |
182 | info("%s successfully initialized and connected.",desc->name); | 187 | info("%s successfully initialized and connected.",desc->name); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index b4a1a98006c7..dd568396e594 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h | |||
@@ -10,8 +10,8 @@ | |||
10 | 10 | ||
11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
12 | #include <linux/input.h> | 12 | #include <linux/input.h> |
13 | #include <linux/module.h> | ||
14 | #include <linux/usb.h> | 13 | #include <linux/usb.h> |
14 | #include <linux/firmware.h> | ||
15 | 15 | ||
16 | #include "dvb_frontend.h" | 16 | #include "dvb_frontend.h" |
17 | #include "dvb_demux.h" | 17 | #include "dvb_demux.h" |
@@ -94,7 +94,11 @@ struct dvb_usb_device; | |||
94 | * @usb_ctrl: which USB device-side controller is in use. Needed for firmware | 94 | * @usb_ctrl: which USB device-side controller is in use. Needed for firmware |
95 | * download. | 95 | * download. |
96 | * @firmware: name of the firmware file. | 96 | * @firmware: name of the firmware file. |
97 | * | 97 | * @download_firmware: called to download the firmware when the usb_ctrl is |
98 | * DEVICE_SPECIFIC. | ||
99 | * @no_reconnect: device doesn't do a reconnect after downloading the firmware, | ||
100 | so do the warm initialization right after it | ||
101 | |||
98 | * @size_of_priv: how many bytes shall be allocated for the private field | 102 | * @size_of_priv: how many bytes shall be allocated for the private field |
99 | * of struct dvb_usb_device. | 103 | * of struct dvb_usb_device. |
100 | * | 104 | * |
@@ -142,11 +146,14 @@ struct dvb_usb_properties { | |||
142 | int caps; | 146 | int caps; |
143 | int pid_filter_count; | 147 | int pid_filter_count; |
144 | 148 | ||
145 | #define CYPRESS_AN2135 0 | 149 | #define DEVICE_SPECIFIC 0 |
146 | #define CYPRESS_AN2235 1 | 150 | #define CYPRESS_AN2135 1 |
147 | #define CYPRESS_FX2 2 | 151 | #define CYPRESS_AN2235 2 |
152 | #define CYPRESS_FX2 3 | ||
148 | int usb_ctrl; | 153 | int usb_ctrl; |
149 | const char *firmware; | 154 | const char firmware[FIRMWARE_NAME_MAX]; |
155 | int (*download_firmware) (struct usb_device *, const struct firmware *); | ||
156 | int no_reconnect; | ||
150 | 157 | ||
151 | int size_of_priv; | 158 | int size_of_priv; |
152 | 159 | ||
@@ -326,5 +333,15 @@ extern int dvb_usb_pll_init_i2c(struct dvb_frontend *); | |||
326 | extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); | 333 | extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); |
327 | extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); | 334 | extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); |
328 | 335 | ||
336 | /* commonly used firmware download types and function */ | ||
337 | struct hexline { | ||
338 | u8 len; | ||
339 | u32 addr; | ||
340 | u8 type; | ||
341 | u8 data[255]; | ||
342 | u8 chk; | ||
343 | }; | ||
344 | extern int dvb_usb_get_hexline(const struct firmware *, struct hexline *, int *); | ||
345 | extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type); | ||
329 | 346 | ||
330 | #endif | 347 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c index fac48fc7a4ac..412039d8dbae 100644 --- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c | |||
@@ -129,10 +129,6 @@ static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6]) | |||
129 | dibusb_read_eeprom_byte(d,i, &b); | 129 | dibusb_read_eeprom_byte(d,i, &b); |
130 | 130 | ||
131 | mac[5 - (i - 136)] = b; | 131 | mac[5 - (i - 136)] = b; |
132 | |||
133 | /* deb_ee("%02x ",b); | ||
134 | if ((i+1) % 16 == 0) | ||
135 | deb_ee("\n");*/ | ||
136 | } | 132 | } |
137 | 133 | ||
138 | return 0; | 134 | return 0; |
@@ -153,7 +149,7 @@ static struct usb_device_id nova_t_table [] = { | |||
153 | /* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) }, | 149 | /* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) }, |
154 | { } /* Terminating entry */ | 150 | { } /* Terminating entry */ |
155 | }; | 151 | }; |
156 | MODULE_DEVICE_TABLE (usb, nova_t_table); | 152 | MODULE_DEVICE_TABLE(usb, nova_t_table); |
157 | 153 | ||
158 | static struct dvb_usb_properties nova_t_properties = { | 154 | static struct dvb_usb_properties nova_t_properties = { |
159 | .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, | 155 | .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, |
@@ -198,6 +194,7 @@ static struct dvb_usb_properties nova_t_properties = { | |||
198 | { &nova_t_table[0], NULL }, | 194 | { &nova_t_table[0], NULL }, |
199 | { &nova_t_table[1], NULL }, | 195 | { &nova_t_table[1], NULL }, |
200 | }, | 196 | }, |
197 | { NULL }, | ||
201 | } | 198 | } |
202 | }; | 199 | }; |
203 | 200 | ||
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c index 104b5d016c7b..0885d9fb2bf2 100644 --- a/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c | |||
@@ -190,7 +190,7 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe, | |||
190 | } | 190 | } |
191 | 191 | ||
192 | static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, | 192 | static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, |
193 | struct dvb_diseqc_master_cmd *m) | 193 | struct dvb_diseqc_master_cmd *m) |
194 | { | 194 | { |
195 | struct vp702x_fe_state *st = fe->demodulator_priv; | 195 | struct vp702x_fe_state *st = fe->demodulator_priv; |
196 | u8 cmd[8],ibuf[10]; | 196 | u8 cmd[8],ibuf[10]; |
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h index 4a3e8c7eca2b..a808d48e7bf2 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.h +++ b/drivers/media/dvb/dvb-usb/vp702x.h | |||
@@ -13,47 +13,47 @@ extern int dvb_usb_vp702x_debug; | |||
13 | /* commands are read and written with USB control messages */ | 13 | /* commands are read and written with USB control messages */ |
14 | 14 | ||
15 | /* consecutive read/write operation */ | 15 | /* consecutive read/write operation */ |
16 | #define REQUEST_OUT 0xB2 | 16 | #define REQUEST_OUT 0xB2 |
17 | #define REQUEST_IN 0xB3 | 17 | #define REQUEST_IN 0xB3 |
18 | 18 | ||
19 | /* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0 | 19 | /* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0 |
20 | * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer | 20 | * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer |
21 | * the returning buffer looks as follows | 21 | * the returning buffer looks as follows |
22 | * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */ | 22 | * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */ |
23 | 23 | ||
24 | #define GET_TUNER_STATUS 0x05 | 24 | #define GET_TUNER_STATUS 0x05 |
25 | /* additional in buffer: | 25 | /* additional in buffer: |
26 | * 0 1 2 3 4 5 6 7 8 | 26 | * 0 1 2 3 4 5 6 7 8 |
27 | * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */ | 27 | * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */ |
28 | 28 | ||
29 | #define GET_SYSTEM_STRING 0x06 | 29 | #define GET_SYSTEM_STRING 0x06 |
30 | /* additional in buffer: | 30 | /* additional in buffer: |
31 | * 0 1 2 3 4 5 6 7 8 | 31 | * 0 1 2 3 4 5 6 7 8 |
32 | * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */ | 32 | * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */ |
33 | 33 | ||
34 | #define SET_DISEQC_CMD 0x08 | 34 | #define SET_DISEQC_CMD 0x08 |
35 | /* additional out buffer: | 35 | /* additional out buffer: |
36 | * 0 1 2 3 4 | 36 | * 0 1 2 3 4 |
37 | * len X1 X2 X3 X4 | 37 | * len X1 X2 X3 X4 |
38 | * additional in buffer: | 38 | * additional in buffer: |
39 | * 0 1 2 | 39 | * 0 1 2 |
40 | * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */ | 40 | * N/A 0 0 b[1] == b[2] == 0 -> success, failure otherwise */ |
41 | 41 | ||
42 | #define SET_LNB_POWER 0x09 | 42 | #define SET_LNB_POWER 0x09 |
43 | /* additional out buffer: | 43 | /* additional out buffer: |
44 | * 0 1 2 | 44 | * 0 1 2 |
45 | * 0x00 0xff 1 = on, 0 = off | 45 | * 0x00 0xff 1 = on, 0 = off |
46 | * additional in buffer: | 46 | * additional in buffer: |
47 | * 0 1 2 | 47 | * 0 1 2 |
48 | * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */ | 48 | * N/A 0 0 b[1] == b[2] == 0 -> success failure otherwise */ |
49 | 49 | ||
50 | #define GET_MAC_ADDRESS 0x0A | 50 | #define GET_MAC_ADDRESS 0x0A |
51 | /* #define GET_MAC_ADDRESS 0x0B */ | 51 | /* #define GET_MAC_ADDRESS 0x0B */ |
52 | /* additional in buffer: | 52 | /* additional in buffer: |
53 | * 0 1 2 3 4 5 6 7 8 | 53 | * 0 1 2 3 4 5 6 7 8 |
54 | * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */ | 54 | * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */ |
55 | 55 | ||
56 | #define SET_PID_FILTER 0x11 | 56 | #define SET_PID_FILTER 0x11 |
57 | /* additional in buffer: | 57 | /* additional in buffer: |
58 | * 0 1 ... 14 15 16 | 58 | * 0 1 ... 14 15 16 |
59 | * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */ | 59 | * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */ |
@@ -64,39 +64,38 @@ extern int dvb_usb_vp702x_debug; | |||
64 | * freq0 freq1 divstep srate0 srate1 srate2 flag chksum | 64 | * freq0 freq1 divstep srate0 srate1 srate2 flag chksum |
65 | */ | 65 | */ |
66 | 66 | ||
67 | |||
68 | /* one direction requests */ | 67 | /* one direction requests */ |
69 | #define READ_REMOTE_REQ 0xB4 | 68 | #define READ_REMOTE_REQ 0xB4 |
70 | /* IN i: 0; v: 0; b[0] == request, b[1] == key */ | 69 | /* IN i: 0; v: 0; b[0] == request, b[1] == key */ |
71 | 70 | ||
72 | #define READ_PID_NUMBER_REQ 0xB5 | 71 | #define READ_PID_NUMBER_REQ 0xB5 |
73 | /* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */ | 72 | /* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */ |
74 | 73 | ||
75 | #define WRITE_EEPROM_REQ 0xB6 | 74 | #define WRITE_EEPROM_REQ 0xB6 |
76 | /* OUT i: offset; v: value to write; no extra buffer */ | 75 | /* OUT i: offset; v: value to write; no extra buffer */ |
77 | 76 | ||
78 | #define READ_EEPROM_REQ 0xB7 | 77 | #define READ_EEPROM_REQ 0xB7 |
79 | /* IN i: bufferlen; v: offset; buffer with bufferlen bytes */ | 78 | /* IN i: bufferlen; v: offset; buffer with bufferlen bytes */ |
80 | 79 | ||
81 | #define READ_STATUS 0xB8 | 80 | #define READ_STATUS 0xB8 |
82 | /* IN i: 0; v: 0; bufferlen 10 */ | 81 | /* IN i: 0; v: 0; bufferlen 10 */ |
83 | 82 | ||
84 | #define READ_TUNER_REG_REQ 0xB9 | 83 | #define READ_TUNER_REG_REQ 0xB9 |
85 | /* IN i: 0; v: register; b[0] = value */ | 84 | /* IN i: 0; v: register; b[0] = value */ |
86 | 85 | ||
87 | #define READ_FX2_REG_REQ 0xBA | 86 | #define READ_FX2_REG_REQ 0xBA |
88 | /* IN i: offset; v: 0; b[0] = value */ | 87 | /* IN i: offset; v: 0; b[0] = value */ |
89 | 88 | ||
90 | #define WRITE_FX2_REG_REQ 0xBB | 89 | #define WRITE_FX2_REG_REQ 0xBB |
91 | /* OUT i: offset; v: value to write; 1 byte extra buffer */ | 90 | /* OUT i: offset; v: value to write; 1 byte extra buffer */ |
92 | 91 | ||
93 | #define SET_TUNER_POWER_REQ 0xBC | 92 | #define SET_TUNER_POWER_REQ 0xBC |
94 | /* IN i: 0 = power off, 1 = power on */ | 93 | /* IN i: 0 = power off, 1 = power on */ |
95 | 94 | ||
96 | #define WRITE_TUNER_REG_REQ 0xBD | 95 | #define WRITE_TUNER_REG_REQ 0xBD |
97 | /* IN i: register, v: value to write, no extra buffer */ | 96 | /* IN i: register, v: value to write, no extra buffer */ |
98 | 97 | ||
99 | #define RESET_TUNER 0xBE | 98 | #define RESET_TUNER 0xBE |
100 | /* IN i: 0, v: 0, no extra buffer */ | 99 | /* IN i: 0, v: 0, no extra buffer */ |
101 | 100 | ||
102 | extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); | 101 | extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); |
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 3835235b68df..028204956bb0 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c | |||
@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = { | |||
247 | .cold_ids = { &vp7045_usb_table[2], NULL }, | 247 | .cold_ids = { &vp7045_usb_table[2], NULL }, |
248 | .warm_ids = { &vp7045_usb_table[3], NULL }, | 248 | .warm_ids = { &vp7045_usb_table[3], NULL }, |
249 | }, | 249 | }, |
250 | { NULL }, | 250 | { 0 }, |
251 | } | 251 | } |
252 | }; | 252 | }; |
253 | 253 | ||
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 8e269e1c1f9d..db3a8b40031e 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -16,6 +16,12 @@ config DVB_CX24110 | |||
16 | help | 16 | help |
17 | A DVB-S tuner module. Say Y when you want to support this frontend. | 17 | A DVB-S tuner module. Say Y when you want to support this frontend. |
18 | 18 | ||
19 | config DVB_CX24123 | ||
20 | tristate "Conexant CX24123 based" | ||
21 | depends on DVB_CORE | ||
22 | help | ||
23 | A DVB-S tuner module. Say Y when you want to support this frontend. | ||
24 | |||
19 | config DVB_TDA8083 | 25 | config DVB_TDA8083 |
20 | tristate "Philips TDA8083 based" | 26 | tristate "Philips TDA8083 based" |
21 | depends on DVB_CORE | 27 | depends on DVB_CORE |
@@ -50,18 +56,19 @@ comment "DVB-T (terrestrial) frontends" | |||
50 | depends on DVB_CORE | 56 | depends on DVB_CORE |
51 | 57 | ||
52 | config DVB_SP8870 | 58 | config DVB_SP8870 |
53 | tristate "Spase sp8870 based" | 59 | tristate "Spase sp8870 based" |
54 | depends on DVB_CORE | 60 | depends on DVB_CORE |
55 | select FW_LOADER | 61 | select FW_LOADER |
56 | help | 62 | help |
57 | A DVB-T tuner module. Say Y when you want to support this frontend. | 63 | A DVB-T tuner module. Say Y when you want to support this frontend. |
58 | 64 | ||
59 | This driver needs external firmware. Please use the command | 65 | This driver needs external firmware. Please use the command |
60 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to | 66 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to |
61 | download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 67 | download/extract it, and then copy it to /usr/lib/hotplug/firmware |
68 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
62 | 69 | ||
63 | config DVB_SP887X | 70 | config DVB_SP887X |
64 | tristate "Spase sp887x based" | 71 | tristate "Spase sp887x based" |
65 | depends on DVB_CORE | 72 | depends on DVB_CORE |
66 | select FW_LOADER | 73 | select FW_LOADER |
67 | help | 74 | help |
@@ -69,7 +76,8 @@ config DVB_SP887X | |||
69 | 76 | ||
70 | This driver needs external firmware. Please use the command | 77 | This driver needs external firmware. Please use the command |
71 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to | 78 | "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to |
72 | download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 79 | download/extract it, and then copy it to /usr/lib/hotplug/firmware |
80 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
73 | 81 | ||
74 | config DVB_CX22700 | 82 | config DVB_CX22700 |
75 | tristate "Conexant CX22700 based" | 83 | tristate "Conexant CX22700 based" |
@@ -78,10 +86,10 @@ config DVB_CX22700 | |||
78 | A DVB-T tuner module. Say Y when you want to support this frontend. | 86 | A DVB-T tuner module. Say Y when you want to support this frontend. |
79 | 87 | ||
80 | config DVB_CX22702 | 88 | config DVB_CX22702 |
81 | tristate "Conexant cx22702 demodulator (OFDM)" | 89 | tristate "Conexant cx22702 demodulator (OFDM)" |
82 | depends on DVB_CORE | 90 | depends on DVB_CORE |
83 | help | 91 | help |
84 | A DVB-T tuner module. Say Y when you want to support this frontend. | 92 | A DVB-T tuner module. Say Y when you want to support this frontend. |
85 | 93 | ||
86 | config DVB_L64781 | 94 | config DVB_L64781 |
87 | tristate "LSI L64781" | 95 | tristate "LSI L64781" |
@@ -98,8 +106,9 @@ config DVB_TDA1004X | |||
98 | 106 | ||
99 | This driver needs external firmware. Please use the commands | 107 | This driver needs external firmware. Please use the commands |
100 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", | 108 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", |
101 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to | 109 | "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to |
102 | download/extract them, and then copy them to /usr/lib/hotplug/firmware. | 110 | download/extract them, and then copy them to /usr/lib/hotplug/firmware |
111 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
103 | 112 | ||
104 | config DVB_NXT6000 | 113 | config DVB_NXT6000 |
105 | tristate "NxtWave Communications NXT6000 based" | 114 | tristate "NxtWave Communications NXT6000 based" |
@@ -140,13 +149,13 @@ config DVB_VES1820 | |||
140 | tristate "VLSI VES1820 based" | 149 | tristate "VLSI VES1820 based" |
141 | depends on DVB_CORE | 150 | depends on DVB_CORE |
142 | help | 151 | help |
143 | A DVB-C tuner module. Say Y when you want to support this frontend. | 152 | A DVB-C tuner module. Say Y when you want to support this frontend. |
144 | 153 | ||
145 | config DVB_TDA10021 | 154 | config DVB_TDA10021 |
146 | tristate "Philips TDA10021 based" | 155 | tristate "Philips TDA10021 based" |
147 | depends on DVB_CORE | 156 | depends on DVB_CORE |
148 | help | 157 | help |
149 | A DVB-C tuner module. Say Y when you want to support this frontend. | 158 | A DVB-C tuner module. Say Y when you want to support this frontend. |
150 | 159 | ||
151 | config DVB_STV0297 | 160 | config DVB_STV0297 |
152 | tristate "ST STV0297 based" | 161 | tristate "ST STV0297 based" |
@@ -164,6 +173,11 @@ config DVB_NXT2002 | |||
164 | help | 173 | help |
165 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. | 174 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. |
166 | 175 | ||
176 | This driver needs external firmware. Please use the command | ||
177 | "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to | ||
178 | download/extract it, and then copy it to /usr/lib/hotplug/firmware | ||
179 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
180 | |||
167 | config DVB_NXT200X | 181 | config DVB_NXT200X |
168 | tristate "Nextwave NXT2002/NXT2004 based" | 182 | tristate "Nextwave NXT2002/NXT2004 based" |
169 | depends on DVB_CORE | 183 | depends on DVB_CORE |
@@ -172,6 +186,12 @@ config DVB_NXT200X | |||
172 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | 186 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want |
173 | to support this frontend. | 187 | to support this frontend. |
174 | 188 | ||
189 | This driver needs external firmware. Please use the commands | ||
190 | "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and | ||
191 | "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to | ||
192 | download/extract them, and then copy them to /usr/lib/hotplug/firmware | ||
193 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
194 | |||
175 | config DVB_OR51211 | 195 | config DVB_OR51211 |
176 | tristate "or51211 based (pcHDTV HD2000 card)" | 196 | tristate "or51211 based (pcHDTV HD2000 card)" |
177 | depends on DVB_CORE | 197 | depends on DVB_CORE |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index a98760fe08a1..615ec830e1c9 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -32,3 +32,4 @@ obj-$(CONFIG_DVB_OR51132) += or51132.o | |||
32 | obj-$(CONFIG_DVB_BCM3510) += bcm3510.o | 32 | obj-$(CONFIG_DVB_BCM3510) += bcm3510.o |
33 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o | 33 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o |
34 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o | 34 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o |
35 | obj-$(CONFIG_DVB_CX24123) += cx24123.o | ||
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c index 8ceb9a33c7af..3b132bafd4de 100644 --- a/drivers/media/dvb/frontends/bcm3510.c +++ b/drivers/media/dvb/frontends/bcm3510.c | |||
@@ -255,7 +255,7 @@ static int bcm3510_bert_reset(struct bcm3510_state *st) | |||
255 | bcm3510_register_value b; | 255 | bcm3510_register_value b; |
256 | int ret; | 256 | int ret; |
257 | 257 | ||
258 | if ((ret < bcm3510_readB(st,0xfa,&b)) < 0) | 258 | if ((ret = bcm3510_readB(st,0xfa,&b)) < 0) |
259 | return ret; | 259 | return ret; |
260 | 260 | ||
261 | b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); | 261 | b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); |
@@ -623,13 +623,13 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe) | |||
623 | err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); | 623 | err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); |
624 | return ret; | 624 | return ret; |
625 | } | 625 | } |
626 | deb_info("got firmware: %d\n",fw->size); | 626 | deb_info("got firmware: %zd\n",fw->size); |
627 | 627 | ||
628 | b = fw->data; | 628 | b = fw->data; |
629 | for (i = 0; i < fw->size;) { | 629 | for (i = 0; i < fw->size;) { |
630 | addr = le16_to_cpu( *( (u16 *)&b[i] ) ); | 630 | addr = le16_to_cpu( *( (u16 *)&b[i] ) ); |
631 | len = le16_to_cpu( *( (u16 *)&b[i+2] ) ); | 631 | len = le16_to_cpu( *( (u16 *)&b[i+2] ) ); |
632 | deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04x\n",addr,len,fw->size); | 632 | deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size); |
633 | if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { | 633 | if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { |
634 | err("firmware download failed: %d\n",ret); | 634 | err("firmware download failed: %d\n",ret); |
635 | return ret; | 635 | return ret; |
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 5de0e6d350b1..0fc899f81c5e 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -195,6 +195,16 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet | |||
195 | return 0; | 195 | return 0; |
196 | } | 196 | } |
197 | 197 | ||
198 | static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
199 | { | ||
200 | struct cx22702_state* state = fe->demodulator_priv; | ||
201 | dprintk ("%s(%d)\n", __FUNCTION__, enable); | ||
202 | if (enable) | ||
203 | return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe); | ||
204 | else | ||
205 | return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1); | ||
206 | } | ||
207 | |||
198 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ | 208 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ |
199 | static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 209 | static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
200 | { | 210 | { |
@@ -202,7 +212,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
202 | struct cx22702_state* state = fe->demodulator_priv; | 212 | struct cx22702_state* state = fe->demodulator_priv; |
203 | 213 | ||
204 | /* set PLL */ | 214 | /* set PLL */ |
205 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); | 215 | cx22702_i2c_gate_ctrl(fe, 1); |
206 | if (state->config->pll_set) { | 216 | if (state->config->pll_set) { |
207 | state->config->pll_set(fe, p); | 217 | state->config->pll_set(fe, p); |
208 | } else if (state->config->pll_desc) { | 218 | } else if (state->config->pll_desc) { |
@@ -216,7 +226,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
216 | } else { | 226 | } else { |
217 | BUG(); | 227 | BUG(); |
218 | } | 228 | } |
219 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); | 229 | cx22702_i2c_gate_ctrl(fe, 0); |
220 | 230 | ||
221 | /* set inversion */ | 231 | /* set inversion */ |
222 | cx22702_set_inversion (state, p->inversion); | 232 | cx22702_set_inversion (state, p->inversion); |
@@ -349,11 +359,10 @@ static int cx22702_init (struct dvb_frontend* fe) | |||
349 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); | 359 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); |
350 | 360 | ||
351 | /* init PLL */ | 361 | /* init PLL */ |
352 | if (state->config->pll_init) { | 362 | if (state->config->pll_init) |
353 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe); | ||
354 | state->config->pll_init(fe); | 363 | state->config->pll_init(fe); |
355 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); | 364 | |
356 | } | 365 | cx22702_i2c_gate_ctrl(fe, 0); |
357 | 366 | ||
358 | return 0; | 367 | return 0; |
359 | } | 368 | } |
@@ -531,6 +540,7 @@ static struct dvb_frontend_ops cx22702_ops = { | |||
531 | .read_signal_strength = cx22702_read_signal_strength, | 540 | .read_signal_strength = cx22702_read_signal_strength, |
532 | .read_snr = cx22702_read_snr, | 541 | .read_snr = cx22702_read_snr, |
533 | .read_ucblocks = cx22702_read_ucblocks, | 542 | .read_ucblocks = cx22702_read_ucblocks, |
543 | .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, | ||
534 | }; | 544 | }; |
535 | 545 | ||
536 | module_param(debug, int, 0644); | 546 | module_param(debug, int, 0644); |
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index 0c4db80ec332..d15d32c51dc5 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/jiffies.h> | ||
31 | 30 | ||
32 | #include "dvb_frontend.h" | 31 | #include "dvb_frontend.h" |
33 | #include "cx24110.h" | 32 | #include "cx24110.h" |
@@ -56,7 +55,7 @@ static int debug; | |||
56 | 55 | ||
57 | static struct {u8 reg; u8 data;} cx24110_regdata[]= | 56 | static struct {u8 reg; u8 data;} cx24110_regdata[]= |
58 | /* Comments beginning with @ denote this value should | 57 | /* Comments beginning with @ denote this value should |
59 | be the default */ | 58 | be the default */ |
60 | {{0x09,0x01}, /* SoftResetAll */ | 59 | {{0x09,0x01}, /* SoftResetAll */ |
61 | {0x09,0x00}, /* release reset */ | 60 | {0x09,0x00}, /* release reset */ |
62 | {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ | 61 | {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ |
@@ -67,26 +66,26 @@ static struct {u8 reg; u8 data;} cx24110_regdata[]= | |||
67 | {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ | 66 | {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ |
68 | {0x0a,0x00}, /* @ partial chip disables, do not set */ | 67 | {0x0a,0x00}, /* @ partial chip disables, do not set */ |
69 | {0x0b,0x01}, /* set output clock in gapped mode, start signal low | 68 | {0x0b,0x01}, /* set output clock in gapped mode, start signal low |
70 | active for first byte */ | 69 | active for first byte */ |
71 | {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ | 70 | {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ |
72 | {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ | 71 | {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ |
73 | {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 | 72 | {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 |
74 | to avoid starting the BER counter. Reset the | 73 | to avoid starting the BER counter. Reset the |
75 | CRC test bit. Finite counting selected */ | 74 | CRC test bit. Finite counting selected */ |
76 | {0x15,0xff}, /* @ size of the limited time window for RS BER | 75 | {0x15,0xff}, /* @ size of the limited time window for RS BER |
77 | estimation. It is <value>*256 RS blocks, this | 76 | estimation. It is <value>*256 RS blocks, this |
78 | gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ | 77 | gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ |
79 | {0x16,0x00}, /* @ enable all RS output ports */ | 78 | {0x16,0x00}, /* @ enable all RS output ports */ |
80 | {0x17,0x04}, /* @ time window allowed for the RS to sync */ | 79 | {0x17,0x04}, /* @ time window allowed for the RS to sync */ |
81 | {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned | 80 | {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned |
82 | for automatically */ | 81 | for automatically */ |
83 | /* leave the current code rate and normalization | 82 | /* leave the current code rate and normalization |
84 | registers as they are after reset... */ | 83 | registers as they are after reset... */ |
85 | {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting | 84 | {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting |
86 | only once */ | 85 | only once */ |
87 | {0x23,0x18}, /* @ size of the limited time window for Viterbi BER | 86 | {0x23,0x18}, /* @ size of the limited time window for Viterbi BER |
88 | estimation. It is <value>*65536 channel bits, i.e. | 87 | estimation. It is <value>*65536 channel bits, i.e. |
89 | approx. 38ms at 27.5MS/s, rate 3/4 */ | 88 | approx. 38ms at 27.5MS/s, rate 3/4 */ |
90 | {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ | 89 | {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ |
91 | /* leave front-end AGC parameters at default values */ | 90 | /* leave front-end AGC parameters at default values */ |
92 | /* leave decimation AGC parameters at default values */ | 91 | /* leave decimation AGC parameters at default values */ |
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c new file mode 100644 index 000000000000..d661c6f9cbe5 --- /dev/null +++ b/drivers/media/dvb/frontends/cx24123.c | |||
@@ -0,0 +1,889 @@ | |||
1 | /* | ||
2 | Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver | ||
3 | |||
4 | Copyright (C) 2005 Steven Toth <stoth@hauppauge.com> | ||
5 | |||
6 | Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc> | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/slab.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/moduleparam.h> | ||
27 | #include <linux/init.h> | ||
28 | |||
29 | #include "dvb_frontend.h" | ||
30 | #include "cx24123.h" | ||
31 | |||
32 | static int debug; | ||
33 | #define dprintk(args...) \ | ||
34 | do { \ | ||
35 | if (debug) printk (KERN_DEBUG "cx24123: " args); \ | ||
36 | } while (0) | ||
37 | |||
38 | struct cx24123_state | ||
39 | { | ||
40 | struct i2c_adapter* i2c; | ||
41 | struct dvb_frontend_ops ops; | ||
42 | const struct cx24123_config* config; | ||
43 | |||
44 | struct dvb_frontend frontend; | ||
45 | |||
46 | u32 lastber; | ||
47 | u16 snr; | ||
48 | u8 lnbreg; | ||
49 | |||
50 | /* Some PLL specifics for tuning */ | ||
51 | u32 VCAarg; | ||
52 | u32 VGAarg; | ||
53 | u32 bandselectarg; | ||
54 | u32 pllarg; | ||
55 | |||
56 | /* The Demod/Tuner can't easily provide these, we cache them */ | ||
57 | u32 currentfreq; | ||
58 | u32 currentsymbolrate; | ||
59 | }; | ||
60 | |||
61 | /* Various tuner defaults need to be established for a given symbol rate Sps */ | ||
62 | static struct | ||
63 | { | ||
64 | u32 symbolrate_low; | ||
65 | u32 symbolrate_high; | ||
66 | u32 VCAslope; | ||
67 | u32 VCAoffset; | ||
68 | u32 VGA1offset; | ||
69 | u32 VGA2offset; | ||
70 | u32 VCAprogdata; | ||
71 | u32 VGAprogdata; | ||
72 | } cx24123_AGC_vals[] = | ||
73 | { | ||
74 | { | ||
75 | .symbolrate_low = 1000000, | ||
76 | .symbolrate_high = 4999999, | ||
77 | .VCAslope = 0x07, | ||
78 | .VCAoffset = 0x0f, | ||
79 | .VGA1offset = 0x1f8, | ||
80 | .VGA2offset = 0x1f8, | ||
81 | .VGAprogdata = (2 << 18) | (0x1f8 << 9) | 0x1f8, | ||
82 | .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x07, | ||
83 | }, | ||
84 | { | ||
85 | .symbolrate_low = 5000000, | ||
86 | .symbolrate_high = 14999999, | ||
87 | .VCAslope = 0x1f, | ||
88 | .VCAoffset = 0x1f, | ||
89 | .VGA1offset = 0x1e0, | ||
90 | .VGA2offset = 0x180, | ||
91 | .VGAprogdata = (2 << 18) | (0x180 << 9) | 0x1e0, | ||
92 | .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x1f, | ||
93 | }, | ||
94 | { | ||
95 | .symbolrate_low = 15000000, | ||
96 | .symbolrate_high = 45000000, | ||
97 | .VCAslope = 0x3f, | ||
98 | .VCAoffset = 0x3f, | ||
99 | .VGA1offset = 0x180, | ||
100 | .VGA2offset = 0x100, | ||
101 | .VGAprogdata = (2 << 18) | (0x100 << 9) | 0x180, | ||
102 | .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x3f, | ||
103 | }, | ||
104 | }; | ||
105 | |||
106 | /* | ||
107 | * Various tuner defaults need to be established for a given frequency kHz. | ||
108 | * fixme: The bounds on the bands do not match the doc in real life. | ||
109 | * fixme: Some of them have been moved, other might need adjustment. | ||
110 | */ | ||
111 | static struct | ||
112 | { | ||
113 | u32 freq_low; | ||
114 | u32 freq_high; | ||
115 | u32 bandselect; | ||
116 | u32 VCOdivider; | ||
117 | u32 VCOnumber; | ||
118 | u32 progdata; | ||
119 | } cx24123_bandselect_vals[] = | ||
120 | { | ||
121 | { | ||
122 | .freq_low = 950000, | ||
123 | .freq_high = 1018999, | ||
124 | .bandselect = 0x40, | ||
125 | .VCOdivider = 4, | ||
126 | .VCOnumber = 7, | ||
127 | .progdata = (0 << 18) | (0 << 9) | 0x40, | ||
128 | }, | ||
129 | { | ||
130 | .freq_low = 1019000, | ||
131 | .freq_high = 1074999, | ||
132 | .bandselect = 0x80, | ||
133 | .VCOdivider = 4, | ||
134 | .VCOnumber = 8, | ||
135 | .progdata = (0 << 18) | (0 << 9) | 0x80, | ||
136 | }, | ||
137 | { | ||
138 | .freq_low = 1075000, | ||
139 | .freq_high = 1227999, | ||
140 | .bandselect = 0x01, | ||
141 | .VCOdivider = 2, | ||
142 | .VCOnumber = 1, | ||
143 | .progdata = (0 << 18) | (1 << 9) | 0x01, | ||
144 | }, | ||
145 | { | ||
146 | .freq_low = 1228000, | ||
147 | .freq_high = 1349999, | ||
148 | .bandselect = 0x02, | ||
149 | .VCOdivider = 2, | ||
150 | .VCOnumber = 2, | ||
151 | .progdata = (0 << 18) | (1 << 9) | 0x02, | ||
152 | }, | ||
153 | { | ||
154 | .freq_low = 1350000, | ||
155 | .freq_high = 1481999, | ||
156 | .bandselect = 0x04, | ||
157 | .VCOdivider = 2, | ||
158 | .VCOnumber = 3, | ||
159 | .progdata = (0 << 18) | (1 << 9) | 0x04, | ||
160 | }, | ||
161 | { | ||
162 | .freq_low = 1482000, | ||
163 | .freq_high = 1595999, | ||
164 | .bandselect = 0x08, | ||
165 | .VCOdivider = 2, | ||
166 | .VCOnumber = 4, | ||
167 | .progdata = (0 << 18) | (1 << 9) | 0x08, | ||
168 | }, | ||
169 | { | ||
170 | .freq_low = 1596000, | ||
171 | .freq_high = 1717999, | ||
172 | .bandselect = 0x10, | ||
173 | .VCOdivider = 2, | ||
174 | .VCOnumber = 5, | ||
175 | .progdata = (0 << 18) | (1 << 9) | 0x10, | ||
176 | }, | ||
177 | { | ||
178 | .freq_low = 1718000, | ||
179 | .freq_high = 1855999, | ||
180 | .bandselect = 0x20, | ||
181 | .VCOdivider = 2, | ||
182 | .VCOnumber = 6, | ||
183 | .progdata = (0 << 18) | (1 << 9) | 0x20, | ||
184 | }, | ||
185 | { | ||
186 | .freq_low = 1856000, | ||
187 | .freq_high = 2035999, | ||
188 | .bandselect = 0x40, | ||
189 | .VCOdivider = 2, | ||
190 | .VCOnumber = 7, | ||
191 | .progdata = (0 << 18) | (1 << 9) | 0x40, | ||
192 | }, | ||
193 | { | ||
194 | .freq_low = 2036000, | ||
195 | .freq_high = 2149999, | ||
196 | .bandselect = 0x80, | ||
197 | .VCOdivider = 2, | ||
198 | .VCOnumber = 8, | ||
199 | .progdata = (0 << 18) | (1 << 9) | 0x80, | ||
200 | }, | ||
201 | }; | ||
202 | |||
203 | static struct { | ||
204 | u8 reg; | ||
205 | u8 data; | ||
206 | } cx24123_regdata[] = | ||
207 | { | ||
208 | {0x00, 0x03}, /* Reset system */ | ||
209 | {0x00, 0x00}, /* Clear reset */ | ||
210 | {0x01, 0x3b}, /* Apply sensible defaults, from an i2c sniffer */ | ||
211 | {0x03, 0x07}, | ||
212 | {0x04, 0x10}, | ||
213 | {0x05, 0x04}, | ||
214 | {0x06, 0x31}, | ||
215 | {0x0d, 0x02}, | ||
216 | {0x0e, 0x03}, | ||
217 | {0x0f, 0xfe}, | ||
218 | {0x10, 0x01}, | ||
219 | {0x14, 0x01}, | ||
220 | {0x15, 0x98}, | ||
221 | {0x16, 0x00}, | ||
222 | {0x17, 0x01}, | ||
223 | {0x1b, 0x05}, | ||
224 | {0x1c, 0x80}, | ||
225 | {0x1d, 0x00}, | ||
226 | {0x1e, 0x00}, | ||
227 | {0x20, 0x41}, | ||
228 | {0x21, 0x15}, | ||
229 | {0x27, 0x14}, | ||
230 | {0x28, 0x46}, | ||
231 | {0x29, 0x00}, | ||
232 | {0x2a, 0xb0}, | ||
233 | {0x2b, 0x73}, | ||
234 | {0x2c, 0x00}, | ||
235 | {0x2d, 0x00}, | ||
236 | {0x2e, 0x00}, | ||
237 | {0x2f, 0x00}, | ||
238 | {0x30, 0x00}, | ||
239 | {0x31, 0x00}, | ||
240 | {0x32, 0x8c}, | ||
241 | {0x33, 0x00}, | ||
242 | {0x34, 0x00}, | ||
243 | {0x35, 0x03}, | ||
244 | {0x36, 0x02}, | ||
245 | {0x37, 0x3a}, | ||
246 | {0x3a, 0x00}, /* Enable AGC accumulator */ | ||
247 | {0x44, 0x00}, | ||
248 | {0x45, 0x00}, | ||
249 | {0x46, 0x05}, | ||
250 | {0x56, 0x41}, | ||
251 | {0x57, 0xff}, | ||
252 | {0x67, 0x83}, | ||
253 | }; | ||
254 | |||
255 | static int cx24123_writereg(struct cx24123_state* state, int reg, int data) | ||
256 | { | ||
257 | u8 buf[] = { reg, data }; | ||
258 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; | ||
259 | int err; | ||
260 | |||
261 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | ||
262 | printk("%s: writereg error(err == %i, reg == 0x%02x," | ||
263 | " data == 0x%02x)\n", __FUNCTION__, err, reg, data); | ||
264 | return -EREMOTEIO; | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data) | ||
271 | { | ||
272 | u8 buf[] = { reg, data }; | ||
273 | /* fixme: put the intersil addr int the config */ | ||
274 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 }; | ||
275 | int err; | ||
276 | |||
277 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | ||
278 | printk("%s: writelnbreg error (err == %i, reg == 0x%02x," | ||
279 | " data == 0x%02x)\n", __FUNCTION__, err, reg, data); | ||
280 | return -EREMOTEIO; | ||
281 | } | ||
282 | |||
283 | /* cache the write, no way to read back */ | ||
284 | state->lnbreg = data; | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int cx24123_readreg(struct cx24123_state* state, u8 reg) | ||
290 | { | ||
291 | int ret; | ||
292 | u8 b0[] = { reg }; | ||
293 | u8 b1[] = { 0 }; | ||
294 | struct i2c_msg msg[] = { | ||
295 | { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, | ||
296 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } | ||
297 | }; | ||
298 | |||
299 | ret = i2c_transfer(state->i2c, msg, 2); | ||
300 | |||
301 | if (ret != 2) { | ||
302 | printk("%s: reg=0x%x (error=%d)\n", __FUNCTION__, reg, ret); | ||
303 | return ret; | ||
304 | } | ||
305 | |||
306 | return b1[0]; | ||
307 | } | ||
308 | |||
309 | static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg) | ||
310 | { | ||
311 | return state->lnbreg; | ||
312 | } | ||
313 | |||
314 | static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) | ||
315 | { | ||
316 | switch (inversion) { | ||
317 | case INVERSION_OFF: | ||
318 | cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) & 0x7f); | ||
319 | cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); | ||
320 | break; | ||
321 | case INVERSION_ON: | ||
322 | cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) | 0x80); | ||
323 | cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); | ||
324 | break; | ||
325 | case INVERSION_AUTO: | ||
326 | cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) & 0x7f); | ||
327 | break; | ||
328 | default: | ||
329 | return -EINVAL; | ||
330 | } | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion) | ||
336 | { | ||
337 | u8 val; | ||
338 | |||
339 | val = cx24123_readreg(state, 0x1b) >> 7; | ||
340 | |||
341 | if (val == 0) | ||
342 | *inversion = INVERSION_OFF; | ||
343 | else | ||
344 | *inversion = INVERSION_ON; | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) | ||
350 | { | ||
351 | if ( (fec < FEC_NONE) || (fec > FEC_AUTO) ) | ||
352 | fec = FEC_AUTO; | ||
353 | |||
354 | /* Hardware has 5/11 and 3/5 but are never unused */ | ||
355 | switch (fec) { | ||
356 | case FEC_NONE: | ||
357 | return cx24123_writereg(state, 0x0f, 0x01); | ||
358 | case FEC_1_2: | ||
359 | return cx24123_writereg(state, 0x0f, 0x02); | ||
360 | case FEC_2_3: | ||
361 | return cx24123_writereg(state, 0x0f, 0x04); | ||
362 | case FEC_3_4: | ||
363 | return cx24123_writereg(state, 0x0f, 0x08); | ||
364 | case FEC_5_6: | ||
365 | return cx24123_writereg(state, 0x0f, 0x20); | ||
366 | case FEC_7_8: | ||
367 | return cx24123_writereg(state, 0x0f, 0x80); | ||
368 | case FEC_AUTO: | ||
369 | return cx24123_writereg(state, 0x0f, 0xae); | ||
370 | default: | ||
371 | return -EOPNOTSUPP; | ||
372 | } | ||
373 | } | ||
374 | |||
375 | static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec) | ||
376 | { | ||
377 | int ret; | ||
378 | u8 val; | ||
379 | |||
380 | ret = cx24123_readreg (state, 0x1b); | ||
381 | if (ret < 0) | ||
382 | return ret; | ||
383 | val = ret & 0x07; | ||
384 | switch (val) { | ||
385 | case 1: | ||
386 | *fec = FEC_1_2; | ||
387 | break; | ||
388 | case 3: | ||
389 | *fec = FEC_2_3; | ||
390 | break; | ||
391 | case 4: | ||
392 | *fec = FEC_3_4; | ||
393 | break; | ||
394 | case 5: | ||
395 | *fec = FEC_4_5; | ||
396 | break; | ||
397 | case 6: | ||
398 | *fec = FEC_5_6; | ||
399 | break; | ||
400 | case 7: | ||
401 | *fec = FEC_7_8; | ||
402 | break; | ||
403 | case 2: /* *fec = FEC_3_5; break; */ | ||
404 | case 0: /* *fec = FEC_5_11; break; */ | ||
405 | *fec = FEC_AUTO; | ||
406 | break; | ||
407 | default: | ||
408 | *fec = FEC_NONE; // can't happen | ||
409 | } | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | /* fixme: Symbol rates < 3MSps may not work because of precision loss */ | ||
415 | static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) | ||
416 | { | ||
417 | u32 val; | ||
418 | |||
419 | val = (srate / 1185) * 100; | ||
420 | |||
421 | /* Compensate for scaling up, by removing 17 symbols per 1Msps */ | ||
422 | val = val - (17 * (srate / 1000000)); | ||
423 | |||
424 | cx24123_writereg(state, 0x08, (val >> 16) & 0xff ); | ||
425 | cx24123_writereg(state, 0x09, (val >> 8) & 0xff ); | ||
426 | cx24123_writereg(state, 0x0a, (val ) & 0xff ); | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Based on the required frequency and symbolrate, the tuner AGC has to be configured | ||
433 | * and the correct band selected. Calculate those values | ||
434 | */ | ||
435 | static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
436 | { | ||
437 | struct cx24123_state *state = fe->demodulator_priv; | ||
438 | u32 ndiv = 0, adiv = 0, vco_div = 0; | ||
439 | int i = 0; | ||
440 | |||
441 | /* Defaults for low freq, low rate */ | ||
442 | state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; | ||
443 | state->VGAarg = cx24123_AGC_vals[0].VGAprogdata; | ||
444 | state->bandselectarg = cx24123_bandselect_vals[0].progdata; | ||
445 | vco_div = cx24123_bandselect_vals[0].VCOdivider; | ||
446 | |||
447 | /* For the given symbolerate, determine the VCA and VGA programming bits */ | ||
448 | for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++) | ||
449 | { | ||
450 | if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && | ||
451 | (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { | ||
452 | state->VCAarg = cx24123_AGC_vals[i].VCAprogdata; | ||
453 | state->VGAarg = cx24123_AGC_vals[i].VGAprogdata; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | /* For the given frequency, determine the bandselect programming bits */ | ||
458 | for (i = 0; i < sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); i++) | ||
459 | { | ||
460 | if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && | ||
461 | (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) { | ||
462 | state->bandselectarg = cx24123_bandselect_vals[i].progdata; | ||
463 | vco_div = cx24123_bandselect_vals[i].VCOdivider; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | /* Determine the N/A dividers for the requested lband freq (in kHz). */ | ||
468 | /* Note: 10111 (kHz) is the Crystal Freq and divider of 10. */ | ||
469 | ndiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) / 32) & 0x1ff; | ||
470 | adiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) % 32) & 0x1f; | ||
471 | |||
472 | if (adiv == 0) | ||
473 | adiv++; | ||
474 | |||
475 | /* determine the correct pll frequency values. */ | ||
476 | /* Command 11, refdiv 11, cpump polarity 1, cpump current 3mA 10. */ | ||
477 | state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (2 << 14); | ||
478 | state->pllarg |= (ndiv << 5) | adiv; | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | /* | ||
484 | * Tuner data is 21 bits long, must be left-aligned in data. | ||
485 | * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip. | ||
486 | */ | ||
487 | static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data) | ||
488 | { | ||
489 | struct cx24123_state *state = fe->demodulator_priv; | ||
490 | unsigned long timeout; | ||
491 | |||
492 | /* align the 21 bytes into to bit23 boundary */ | ||
493 | data = data << 3; | ||
494 | |||
495 | /* Reset the demod pll word length to 0x15 bits */ | ||
496 | cx24123_writereg(state, 0x21, 0x15); | ||
497 | |||
498 | /* write the msb 8 bits, wait for the send to be completed */ | ||
499 | timeout = jiffies + msecs_to_jiffies(40); | ||
500 | cx24123_writereg(state, 0x22, (data >> 16) & 0xff); | ||
501 | while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { | ||
502 | if (time_after(jiffies, timeout)) { | ||
503 | printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); | ||
504 | return -EREMOTEIO; | ||
505 | } | ||
506 | msleep(10); | ||
507 | } | ||
508 | |||
509 | /* send another 8 bytes, wait for the send to be completed */ | ||
510 | timeout = jiffies + msecs_to_jiffies(40); | ||
511 | cx24123_writereg(state, 0x22, (data>>8) & 0xff ); | ||
512 | while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { | ||
513 | if (time_after(jiffies, timeout)) { | ||
514 | printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); | ||
515 | return -EREMOTEIO; | ||
516 | } | ||
517 | msleep(10); | ||
518 | } | ||
519 | |||
520 | /* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */ | ||
521 | timeout = jiffies + msecs_to_jiffies(40); | ||
522 | cx24123_writereg(state, 0x22, (data) & 0xff ); | ||
523 | while ((cx24123_readreg(state, 0x20) & 0x80)) { | ||
524 | if (time_after(jiffies, timeout)) { | ||
525 | printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); | ||
526 | return -EREMOTEIO; | ||
527 | } | ||
528 | msleep(10); | ||
529 | } | ||
530 | |||
531 | /* Trigger the demod to configure the tuner */ | ||
532 | cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2); | ||
533 | cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd); | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
539 | { | ||
540 | struct cx24123_state *state = fe->demodulator_priv; | ||
541 | |||
542 | if (cx24123_pll_calculate(fe, p) != 0) { | ||
543 | printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__); | ||
544 | return -EINVAL; | ||
545 | } | ||
546 | |||
547 | /* Write the new VCO/VGA */ | ||
548 | cx24123_pll_writereg(fe, p, state->VCAarg); | ||
549 | cx24123_pll_writereg(fe, p, state->VGAarg); | ||
550 | |||
551 | /* Write the new bandselect and pll args */ | ||
552 | cx24123_pll_writereg(fe, p, state->bandselectarg); | ||
553 | cx24123_pll_writereg(fe, p, state->pllarg); | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static int cx24123_initfe(struct dvb_frontend* fe) | ||
559 | { | ||
560 | struct cx24123_state *state = fe->demodulator_priv; | ||
561 | int i; | ||
562 | |||
563 | /* Configure the demod to a good set of defaults */ | ||
564 | for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) | ||
565 | cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); | ||
566 | |||
567 | if (state->config->pll_init) | ||
568 | state->config->pll_init(fe); | ||
569 | |||
570 | /* Configure the LNB for 14V */ | ||
571 | if (state->config->use_isl6421) | ||
572 | cx24123_writelnbreg(state, 0x0, 0x2a); | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
578 | { | ||
579 | struct cx24123_state *state = fe->demodulator_priv; | ||
580 | u8 val; | ||
581 | |||
582 | switch (state->config->use_isl6421) { | ||
583 | |||
584 | case 1: | ||
585 | |||
586 | val = cx24123_readlnbreg(state, 0x0); | ||
587 | |||
588 | switch (voltage) { | ||
589 | case SEC_VOLTAGE_13: | ||
590 | return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ | ||
591 | case SEC_VOLTAGE_18: | ||
592 | return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ | ||
593 | case SEC_VOLTAGE_OFF: | ||
594 | return cx24123_writelnbreg(state, 0x0, val & 0x30); | ||
595 | default: | ||
596 | return -EINVAL; | ||
597 | }; | ||
598 | |||
599 | case 0: | ||
600 | |||
601 | val = cx24123_readreg(state, 0x29); | ||
602 | |||
603 | switch (voltage) { | ||
604 | case SEC_VOLTAGE_13: | ||
605 | dprintk("%s: setting voltage 13V\n", __FUNCTION__); | ||
606 | if (state->config->enable_lnb_voltage) | ||
607 | state->config->enable_lnb_voltage(fe, 1); | ||
608 | return cx24123_writereg(state, 0x29, val | 0x80); | ||
609 | case SEC_VOLTAGE_18: | ||
610 | dprintk("%s: setting voltage 18V\n", __FUNCTION__); | ||
611 | if (state->config->enable_lnb_voltage) | ||
612 | state->config->enable_lnb_voltage(fe, 1); | ||
613 | return cx24123_writereg(state, 0x29, val & 0x7f); | ||
614 | case SEC_VOLTAGE_OFF: | ||
615 | dprintk("%s: setting voltage off\n", __FUNCTION__); | ||
616 | if (state->config->enable_lnb_voltage) | ||
617 | state->config->enable_lnb_voltage(fe, 0); | ||
618 | return 0; | ||
619 | default: | ||
620 | return -EINVAL; | ||
621 | }; | ||
622 | } | ||
623 | |||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, | ||
628 | struct dvb_diseqc_master_cmd *cmd) | ||
629 | { | ||
630 | /* fixme: Implement diseqc */ | ||
631 | printk("%s: No support yet\n",__FUNCTION__); | ||
632 | |||
633 | return -ENOTSUPP; | ||
634 | } | ||
635 | |||
636 | static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
637 | { | ||
638 | struct cx24123_state *state = fe->demodulator_priv; | ||
639 | |||
640 | int sync = cx24123_readreg(state, 0x14); | ||
641 | int lock = cx24123_readreg(state, 0x20); | ||
642 | |||
643 | *status = 0; | ||
644 | if (lock & 0x01) | ||
645 | *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; | ||
646 | if (sync & 0x04) | ||
647 | *status |= FE_HAS_VITERBI; | ||
648 | if (sync & 0x08) | ||
649 | *status |= FE_HAS_CARRIER; | ||
650 | if (sync & 0x80) | ||
651 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | /* | ||
657 | * Configured to return the measurement of errors in blocks, because no UCBLOCKS value | ||
658 | * is available, so this value doubles up to satisfy both measurements | ||
659 | */ | ||
660 | static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber) | ||
661 | { | ||
662 | struct cx24123_state *state = fe->demodulator_priv; | ||
663 | |||
664 | state->lastber = | ||
665 | ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) | | ||
666 | (cx24123_readreg(state, 0x1d) << 8 | | ||
667 | cx24123_readreg(state, 0x1e)); | ||
668 | |||
669 | /* Do the signal quality processing here, it's derived from the BER. */ | ||
670 | /* Scale the BER from a 24bit to a SNR 16 bit where higher = better */ | ||
671 | if (state->lastber < 5000) | ||
672 | state->snr = 655*100; | ||
673 | else if ( (state->lastber >= 5000) && (state->lastber < 55000) ) | ||
674 | state->snr = 655*90; | ||
675 | else if ( (state->lastber >= 55000) && (state->lastber < 150000) ) | ||
676 | state->snr = 655*80; | ||
677 | else if ( (state->lastber >= 150000) && (state->lastber < 250000) ) | ||
678 | state->snr = 655*70; | ||
679 | else if ( (state->lastber >= 250000) && (state->lastber < 450000) ) | ||
680 | state->snr = 655*65; | ||
681 | else | ||
682 | state->snr = 0; | ||
683 | |||
684 | *ber = state->lastber; | ||
685 | |||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) | ||
690 | { | ||
691 | struct cx24123_state *state = fe->demodulator_priv; | ||
692 | *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */ | ||
693 | |||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr) | ||
698 | { | ||
699 | struct cx24123_state *state = fe->demodulator_priv; | ||
700 | *snr = state->snr; | ||
701 | |||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
706 | { | ||
707 | struct cx24123_state *state = fe->demodulator_priv; | ||
708 | *ucblocks = state->lastber; | ||
709 | |||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
714 | { | ||
715 | struct cx24123_state *state = fe->demodulator_priv; | ||
716 | |||
717 | if (state->config->set_ts_params) | ||
718 | state->config->set_ts_params(fe, 0); | ||
719 | |||
720 | state->currentfreq=p->frequency; | ||
721 | state->currentsymbolrate = p->u.qpsk.symbol_rate; | ||
722 | |||
723 | cx24123_set_inversion(state, p->inversion); | ||
724 | cx24123_set_fec(state, p->u.qpsk.fec_inner); | ||
725 | cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate); | ||
726 | cx24123_pll_tune(fe, p); | ||
727 | |||
728 | /* Enable automatic aquisition and reset cycle */ | ||
729 | cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07)); | ||
730 | cx24123_writereg(state, 0x00, 0x10); | ||
731 | cx24123_writereg(state, 0x00, 0); | ||
732 | |||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
737 | { | ||
738 | struct cx24123_state *state = fe->demodulator_priv; | ||
739 | |||
740 | if (cx24123_get_inversion(state, &p->inversion) != 0) { | ||
741 | printk("%s: Failed to get inversion status\n",__FUNCTION__); | ||
742 | return -EREMOTEIO; | ||
743 | } | ||
744 | if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) { | ||
745 | printk("%s: Failed to get fec status\n",__FUNCTION__); | ||
746 | return -EREMOTEIO; | ||
747 | } | ||
748 | p->frequency = state->currentfreq; | ||
749 | p->u.qpsk.symbol_rate = state->currentsymbolrate; | ||
750 | |||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
755 | { | ||
756 | struct cx24123_state *state = fe->demodulator_priv; | ||
757 | u8 val; | ||
758 | |||
759 | switch (state->config->use_isl6421) { | ||
760 | case 1: | ||
761 | |||
762 | val = cx24123_readlnbreg(state, 0x0); | ||
763 | |||
764 | switch (tone) { | ||
765 | case SEC_TONE_ON: | ||
766 | return cx24123_writelnbreg(state, 0x0, val | 0x10); | ||
767 | case SEC_TONE_OFF: | ||
768 | return cx24123_writelnbreg(state, 0x0, val & 0x2f); | ||
769 | default: | ||
770 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); | ||
771 | return -EINVAL; | ||
772 | } | ||
773 | |||
774 | case 0: | ||
775 | |||
776 | val = cx24123_readreg(state, 0x29); | ||
777 | |||
778 | switch (tone) { | ||
779 | case SEC_TONE_ON: | ||
780 | dprintk("%s: setting tone on\n", __FUNCTION__); | ||
781 | return cx24123_writereg(state, 0x29, val | 0x10); | ||
782 | case SEC_TONE_OFF: | ||
783 | dprintk("%s: setting tone off\n",__FUNCTION__); | ||
784 | return cx24123_writereg(state, 0x29, val & 0xef); | ||
785 | default: | ||
786 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); | ||
787 | return -EINVAL; | ||
788 | } | ||
789 | } | ||
790 | |||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | static void cx24123_release(struct dvb_frontend* fe) | ||
795 | { | ||
796 | struct cx24123_state* state = fe->demodulator_priv; | ||
797 | dprintk("%s\n",__FUNCTION__); | ||
798 | kfree(state); | ||
799 | } | ||
800 | |||
801 | static struct dvb_frontend_ops cx24123_ops; | ||
802 | |||
803 | struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | ||
804 | struct i2c_adapter* i2c) | ||
805 | { | ||
806 | struct cx24123_state* state = NULL; | ||
807 | int ret; | ||
808 | |||
809 | dprintk("%s\n",__FUNCTION__); | ||
810 | |||
811 | /* allocate memory for the internal state */ | ||
812 | state = kmalloc(sizeof(struct cx24123_state), GFP_KERNEL); | ||
813 | if (state == NULL) { | ||
814 | printk("Unable to kmalloc\n"); | ||
815 | goto error; | ||
816 | } | ||
817 | |||
818 | /* setup the state */ | ||
819 | state->config = config; | ||
820 | state->i2c = i2c; | ||
821 | memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); | ||
822 | state->lastber = 0; | ||
823 | state->snr = 0; | ||
824 | state->lnbreg = 0; | ||
825 | state->VCAarg = 0; | ||
826 | state->VGAarg = 0; | ||
827 | state->bandselectarg = 0; | ||
828 | state->pllarg = 0; | ||
829 | state->currentfreq = 0; | ||
830 | state->currentsymbolrate = 0; | ||
831 | |||
832 | /* check if the demod is there */ | ||
833 | ret = cx24123_readreg(state, 0x00); | ||
834 | if ((ret != 0xd1) && (ret != 0xe1)) { | ||
835 | printk("Version != d1 or e1\n"); | ||
836 | goto error; | ||
837 | } | ||
838 | |||
839 | /* create dvb_frontend */ | ||
840 | state->frontend.ops = &state->ops; | ||
841 | state->frontend.demodulator_priv = state; | ||
842 | return &state->frontend; | ||
843 | |||
844 | error: | ||
845 | kfree(state); | ||
846 | |||
847 | return NULL; | ||
848 | } | ||
849 | |||
850 | static struct dvb_frontend_ops cx24123_ops = { | ||
851 | |||
852 | .info = { | ||
853 | .name = "Conexant CX24123/CX24109", | ||
854 | .type = FE_QPSK, | ||
855 | .frequency_min = 950000, | ||
856 | .frequency_max = 2150000, | ||
857 | .frequency_stepsize = 1011, /* kHz for QPSK frontends */ | ||
858 | .frequency_tolerance = 29500, | ||
859 | .symbol_rate_min = 1000000, | ||
860 | .symbol_rate_max = 45000000, | ||
861 | .caps = FE_CAN_INVERSION_AUTO | | ||
862 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
863 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
864 | FE_CAN_QPSK | FE_CAN_RECOVER | ||
865 | }, | ||
866 | |||
867 | .release = cx24123_release, | ||
868 | |||
869 | .init = cx24123_initfe, | ||
870 | .set_frontend = cx24123_set_frontend, | ||
871 | .get_frontend = cx24123_get_frontend, | ||
872 | .read_status = cx24123_read_status, | ||
873 | .read_ber = cx24123_read_ber, | ||
874 | .read_signal_strength = cx24123_read_signal_strength, | ||
875 | .read_snr = cx24123_read_snr, | ||
876 | .read_ucblocks = cx24123_read_ucblocks, | ||
877 | .diseqc_send_master_cmd = cx24123_send_diseqc_msg, | ||
878 | .set_tone = cx24123_set_tone, | ||
879 | .set_voltage = cx24123_set_voltage, | ||
880 | }; | ||
881 | |||
882 | module_param(debug, int, 0644); | ||
883 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
884 | |||
885 | MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware"); | ||
886 | MODULE_AUTHOR("Steven Toth"); | ||
887 | MODULE_LICENSE("GPL"); | ||
888 | |||
889 | EXPORT_SYMBOL(cx24123_attach); | ||
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h new file mode 100644 index 000000000000..0c922b5e9263 --- /dev/null +++ b/drivers/media/dvb/frontends/cx24123.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver | ||
3 | |||
4 | Copyright (C) 2005 Steven Toth <stoth@hauppauge.com> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef CX24123_H | ||
22 | #define CX24123_H | ||
23 | |||
24 | #include <linux/dvb/frontend.h> | ||
25 | |||
26 | struct cx24123_config | ||
27 | { | ||
28 | /* the demodulator's i2c address */ | ||
29 | u8 demod_address; | ||
30 | |||
31 | /* | ||
32 | cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip | ||
33 | for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits | ||
34 | from register 0x29 of the CX24123 demodulator | ||
35 | */ | ||
36 | int use_isl6421; | ||
37 | |||
38 | /* PLL maintenance */ | ||
39 | int (*pll_init)(struct dvb_frontend* fe); | ||
40 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
41 | |||
42 | /* Need to set device param for start_dma */ | ||
43 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | ||
44 | |||
45 | void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on); | ||
46 | }; | ||
47 | |||
48 | extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | ||
49 | struct i2c_adapter* i2c); | ||
50 | |||
51 | #endif /* CX24123_H */ | ||
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index f857b869616c..a3d57ce9dd12 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -107,18 +107,19 @@ struct dvb_pll_desc dvb_pll_microtune_4042 = { | |||
107 | }; | 107 | }; |
108 | EXPORT_SYMBOL(dvb_pll_microtune_4042); | 108 | EXPORT_SYMBOL(dvb_pll_microtune_4042); |
109 | 109 | ||
110 | struct dvb_pll_desc dvb_pll_thomson_dtt7611 = { | 110 | struct dvb_pll_desc dvb_pll_thomson_dtt761x = { |
111 | .name = "Thomson dtt7611", | 111 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ |
112 | .min = 44000000, | 112 | .name = "Thomson dtt761x", |
113 | .max = 958000000, | 113 | .min = 57000000, |
114 | .max = 863000000, | ||
114 | .count = 3, | 115 | .count = 3, |
115 | .entries = { | 116 | .entries = { |
116 | { 157250000, 44000000, 62500, 0x8e, 0x39 }, | 117 | { 147000000, 44000000, 62500, 0x8e, 0x39 }, |
117 | { 454000000, 44000000, 62500, 0x8e, 0x3a }, | 118 | { 417000000, 44000000, 62500, 0x8e, 0x3a }, |
118 | { 999999999, 44000000, 62500, 0x8e, 0x3c }, | 119 | { 999999999, 44000000, 62500, 0x8e, 0x3c }, |
119 | }, | 120 | }, |
120 | }; | 121 | }; |
121 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7611); | 122 | EXPORT_SYMBOL(dvb_pll_thomson_dtt761x); |
122 | 123 | ||
123 | struct dvb_pll_desc dvb_pll_unknown_1 = { | 124 | struct dvb_pll_desc dvb_pll_unknown_1 = { |
124 | .name = "unknown 1", /* used by dntv live dvb-t */ | 125 | .name = "unknown 1", /* used by dntv live dvb-t */ |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 497d31dcf41e..24d4d2e9acd8 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
@@ -25,7 +25,7 @@ extern struct dvb_pll_desc dvb_pll_thomson_dtt759x; | |||
25 | extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; | 25 | extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; |
26 | extern struct dvb_pll_desc dvb_pll_lg_z201; | 26 | extern struct dvb_pll_desc dvb_pll_lg_z201; |
27 | extern struct dvb_pll_desc dvb_pll_microtune_4042; | 27 | extern struct dvb_pll_desc dvb_pll_microtune_4042; |
28 | extern struct dvb_pll_desc dvb_pll_thomson_dtt7611; | 28 | extern struct dvb_pll_desc dvb_pll_thomson_dtt761x; |
29 | extern struct dvb_pll_desc dvb_pll_unknown_1; | 29 | extern struct dvb_pll_desc dvb_pll_unknown_1; |
30 | 30 | ||
31 | extern struct dvb_pll_desc dvb_pll_tua6010xs; | 31 | extern struct dvb_pll_desc dvb_pll_tua6010xs; |
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index cb5301865d07..9d214643b87a 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c | |||
@@ -27,6 +27,7 @@ | |||
27 | * DViCO FusionHDTV 3 Gold-T | 27 | * DViCO FusionHDTV 3 Gold-T |
28 | * DViCO FusionHDTV 5 Gold | 28 | * DViCO FusionHDTV 5 Gold |
29 | * DViCO FusionHDTV 5 Lite | 29 | * DViCO FusionHDTV 5 Lite |
30 | * DViCO FusionHDTV 5 USB Gold | ||
30 | * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) | 31 | * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) |
31 | * | 32 | * |
32 | * TODO: | 33 | * TODO: |
@@ -402,6 +403,8 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, | |||
402 | state->config->pll_set(fe, param); | 403 | state->config->pll_set(fe, param); |
403 | 404 | ||
404 | /* Keep track of the new frequency */ | 405 | /* Keep track of the new frequency */ |
406 | /* FIXME this is the wrong way to do this... */ | ||
407 | /* The tuner is shared with the video4linux analog API */ | ||
405 | state->current_frequency = param->frequency; | 408 | state->current_frequency = param->frequency; |
406 | 409 | ||
407 | lgdt330x_SwReset(state); | 410 | lgdt330x_SwReset(state); |
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c index 52c416043a62..4f263e65ba14 100644 --- a/drivers/media/dvb/frontends/nxt2002.c +++ b/drivers/media/dvb/frontends/nxt2002.c | |||
@@ -22,7 +22,8 @@ | |||
22 | /* | 22 | /* |
23 | * This driver needs external firmware. Please use the command | 23 | * This driver needs external firmware. Please use the command |
24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to | 24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to |
25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
26 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
26 | */ | 27 | */ |
27 | #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" | 28 | #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" |
28 | #define CRC_CCIT_MASK 0x1021 | 29 | #define CRC_CCIT_MASK 0x1021 |
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c index a458a3bfff70..a16eeba0020d 100644 --- a/drivers/media/dvb/frontends/nxt6000.c +++ b/drivers/media/dvb/frontends/nxt6000.c | |||
@@ -574,11 +574,11 @@ static struct dvb_frontend_ops nxt6000_ops = { | |||
574 | .symbol_rate_max = 9360000, /* FIXME */ | 574 | .symbol_rate_max = 9360000, /* FIXME */ |
575 | .symbol_rate_tolerance = 4000, | 575 | .symbol_rate_tolerance = 4000, |
576 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | 576 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
577 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | | 577 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | |
578 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | | 578 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | |
579 | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | | 579 | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | |
580 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | | 580 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | |
581 | FE_CAN_HIERARCHY_AUTO, | 581 | FE_CAN_HIERARCHY_AUTO, |
582 | }, | 582 | }, |
583 | 583 | ||
584 | .release = nxt6000_release, | 584 | .release = nxt6000_release, |
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c index 531f76246e5f..7c3aed1f546b 100644 --- a/drivers/media/dvb/frontends/or51211.c +++ b/drivers/media/dvb/frontends/or51211.c | |||
@@ -25,7 +25,8 @@ | |||
25 | /* | 25 | /* |
26 | * This driver needs external firmware. Please use the command | 26 | * This driver needs external firmware. Please use the command |
27 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to | 27 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to |
28 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 28 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
29 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
29 | */ | 30 | */ |
30 | #define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" | 31 | #define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" |
31 | 32 | ||
@@ -112,7 +113,7 @@ static int or51211_load_firmware (struct dvb_frontend* fe, | |||
112 | u8 tudata[585]; | 113 | u8 tudata[585]; |
113 | int i; | 114 | int i; |
114 | 115 | ||
115 | dprintk("Firmware is %d bytes\n",fw->size); | 116 | dprintk("Firmware is %zd bytes\n",fw->size); |
116 | 117 | ||
117 | /* Get eprom data */ | 118 | /* Get eprom data */ |
118 | tudata[0] = 17; | 119 | tudata[0] = 17; |
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c index 18715091aed8..d69477596921 100644 --- a/drivers/media/dvb/frontends/s5h1420.c +++ b/drivers/media/dvb/frontends/s5h1420.c | |||
@@ -521,8 +521,8 @@ static void s5h1420_setfec_inversion(struct s5h1420_state* state, | |||
521 | 521 | ||
522 | case FEC_3_4: | 522 | case FEC_3_4: |
523 | s5h1420_writereg(state, 0x30, 0x04); | 523 | s5h1420_writereg(state, 0x30, 0x04); |
524 | s5h1420_writereg(state, 0x31, 0x12 | inversion); | 524 | s5h1420_writereg(state, 0x31, 0x12 | inversion); |
525 | break; | 525 | break; |
526 | 526 | ||
527 | case FEC_5_6: | 527 | case FEC_5_6: |
528 | s5h1420_writereg(state, 0x30, 0x08); | 528 | s5h1420_writereg(state, 0x30, 0x08); |
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c index fc06cd6b46c3..73829e647e50 100644 --- a/drivers/media/dvb/frontends/sp8870.c +++ b/drivers/media/dvb/frontends/sp8870.c | |||
@@ -22,7 +22,8 @@ | |||
22 | /* | 22 | /* |
23 | * This driver needs external firmware. Please use the command | 23 | * This driver needs external firmware. Please use the command |
24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to | 24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to |
25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
26 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
26 | */ | 27 | */ |
27 | #define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" | 28 | #define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" |
28 | 29 | ||
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c index e3b665782243..eb8a602198ca 100644 --- a/drivers/media/dvb/frontends/sp887x.c +++ b/drivers/media/dvb/frontends/sp887x.c | |||
@@ -5,7 +5,8 @@ | |||
5 | /* | 5 | /* |
6 | * This driver needs external firmware. Please use the command | 6 | * This driver needs external firmware. Please use the command |
7 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to | 7 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to |
8 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 8 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
9 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
9 | */ | 10 | */ |
10 | #define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw" | 11 | #define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw" |
11 | 12 | ||
@@ -581,7 +582,7 @@ static struct dvb_frontend_ops sp887x_ops = { | |||
581 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | 582 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
582 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | 583 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
583 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | | 584 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | |
584 | FE_CAN_RECOVER | 585 | FE_CAN_RECOVER |
585 | }, | 586 | }, |
586 | 587 | ||
587 | .release = sp887x_release, | 588 | .release = sp887x_release, |
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 177d71d56b67..5bcd00f792e6 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c | |||
@@ -131,6 +131,13 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len | |||
131 | return ret == 2 ? 0 : ret; | 131 | return ret == 2 ? 0 : ret; |
132 | } | 132 | } |
133 | 133 | ||
134 | int stv0299_enable_plli2c (struct dvb_frontend* fe) | ||
135 | { | ||
136 | struct stv0299_state* state = fe->demodulator_priv; | ||
137 | |||
138 | return stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ | ||
139 | } | ||
140 | |||
134 | static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) | 141 | static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) |
135 | { | 142 | { |
136 | dprintk ("%s\n", __FUNCTION__); | 143 | dprintk ("%s\n", __FUNCTION__); |
@@ -387,7 +394,7 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag | |||
387 | }; | 394 | }; |
388 | } | 395 | } |
389 | 396 | ||
390 | static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) | 397 | static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd) |
391 | { | 398 | { |
392 | struct stv0299_state* state = fe->demodulator_priv; | 399 | struct stv0299_state* state = fe->demodulator_priv; |
393 | u8 reg0x08; | 400 | u8 reg0x08; |
@@ -407,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) | |||
407 | 414 | ||
408 | cmd = cmd << 1; | 415 | cmd = cmd << 1; |
409 | if (debug_legacy_dish_switch) | 416 | if (debug_legacy_dish_switch) |
410 | printk ("%s switch command: 0x%04x\n",__FUNCTION__, cmd); | 417 | printk ("%s switch command: 0x%04lx\n",__FUNCTION__, cmd); |
411 | 418 | ||
412 | do_gettimeofday (&nexttime); | 419 | do_gettimeofday (&nexttime); |
413 | if (debug_legacy_dish_switch) | 420 | if (debug_legacy_dish_switch) |
@@ -717,5 +724,6 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " | |||
717 | "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); | 724 | "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); |
718 | MODULE_LICENSE("GPL"); | 725 | MODULE_LICENSE("GPL"); |
719 | 726 | ||
727 | EXPORT_SYMBOL(stv0299_enable_plli2c); | ||
720 | EXPORT_SYMBOL(stv0299_writereg); | 728 | EXPORT_SYMBOL(stv0299_writereg); |
721 | EXPORT_SYMBOL(stv0299_attach); | 729 | EXPORT_SYMBOL(stv0299_attach); |
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h index 9af3d71c89db..32c87b4c2f13 100644 --- a/drivers/media/dvb/frontends/stv0299.h +++ b/drivers/media/dvb/frontends/stv0299.h | |||
@@ -94,6 +94,7 @@ struct stv0299_config | |||
94 | }; | 94 | }; |
95 | 95 | ||
96 | extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); | 96 | extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); |
97 | extern int stv0299_enable_plli2c (struct dvb_frontend* fe); | ||
97 | 98 | ||
98 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | 99 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, |
99 | struct i2c_adapter* i2c); | 100 | struct i2c_adapter* i2c); |
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 425cd19136fe..21255cac9793 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c | |||
@@ -95,7 +95,7 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) | |||
95 | u8 b0 [] = { reg }; | 95 | u8 b0 [] = { reg }; |
96 | u8 b1 [] = { 0 }; | 96 | u8 b1 [] = { 0 }; |
97 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, | 97 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, |
98 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; | 98 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; |
99 | int ret; | 99 | int ret; |
100 | 100 | ||
101 | ret = i2c_transfer (state->i2c, msg, 2); | 101 | ret = i2c_transfer (state->i2c, msg, 2); |
@@ -434,7 +434,7 @@ static struct dvb_frontend_ops tda10021_ops = { | |||
434 | .frequency_max = 858000000, | 434 | .frequency_max = 858000000, |
435 | .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ | 435 | .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ |
436 | .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ | 436 | .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ |
437 | #if 0 | 437 | #if 0 |
438 | .frequency_tolerance = ???, | 438 | .frequency_tolerance = ???, |
439 | .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ | 439 | .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ |
440 | #endif | 440 | #endif |
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index dd02aff467fe..c63e9a5084eb 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
@@ -23,7 +23,8 @@ | |||
23 | * This driver needs external firmware. Please use the commands | 23 | * This driver needs external firmware. Please use the commands |
24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", | 24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", |
25 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to | 25 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to |
26 | * download/extract them, and then copy them to /usr/lib/hotplug/firmware. | 26 | * download/extract them, and then copy them to /usr/lib/hotplug/firmware |
27 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
27 | */ | 28 | */ |
28 | #define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw" | 29 | #define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw" |
29 | #define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw" | 30 | #define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw" |
@@ -271,32 +272,57 @@ static int tda10045h_set_bandwidth(struct tda1004x_state *state, | |||
271 | static int tda10046h_set_bandwidth(struct tda1004x_state *state, | 272 | static int tda10046h_set_bandwidth(struct tda1004x_state *state, |
272 | fe_bandwidth_t bandwidth) | 273 | fe_bandwidth_t bandwidth) |
273 | { | 274 | { |
274 | static u8 bandwidth_6mhz[] = { 0x80, 0x15, 0xfe, 0xab, 0x8e }; | 275 | static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 }; |
275 | static u8 bandwidth_7mhz[] = { 0x6e, 0x02, 0x53, 0xc8, 0x25 }; | 276 | static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f }; |
276 | static u8 bandwidth_8mhz[] = { 0x60, 0x12, 0xa8, 0xe4, 0xbd }; | 277 | static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d }; |
277 | 278 | ||
279 | static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 }; | ||
280 | static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab }; | ||
281 | static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 }; | ||
282 | int tda10046_clk53m; | ||
283 | |||
284 | if ((state->config->if_freq == TDA10046_FREQ_045) || | ||
285 | (state->config->if_freq == TDA10046_FREQ_052)) | ||
286 | tda10046_clk53m = 0; | ||
287 | else | ||
288 | tda10046_clk53m = 1; | ||
278 | switch (bandwidth) { | 289 | switch (bandwidth) { |
279 | case BANDWIDTH_6_MHZ: | 290 | case BANDWIDTH_6_MHZ: |
280 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz)); | 291 | if (tda10046_clk53m) |
292 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M, | ||
293 | sizeof(bandwidth_6mhz_53M)); | ||
294 | else | ||
295 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M, | ||
296 | sizeof(bandwidth_6mhz_48M)); | ||
281 | if (state->config->if_freq == TDA10046_FREQ_045) { | 297 | if (state->config->if_freq == TDA10046_FREQ_045) { |
282 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x09); | 298 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a); |
283 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x4f); | 299 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab); |
284 | } | 300 | } |
285 | break; | 301 | break; |
286 | 302 | ||
287 | case BANDWIDTH_7_MHZ: | 303 | case BANDWIDTH_7_MHZ: |
288 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz)); | 304 | if (tda10046_clk53m) |
305 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M, | ||
306 | sizeof(bandwidth_7mhz_53M)); | ||
307 | else | ||
308 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M, | ||
309 | sizeof(bandwidth_7mhz_48M)); | ||
289 | if (state->config->if_freq == TDA10046_FREQ_045) { | 310 | if (state->config->if_freq == TDA10046_FREQ_045) { |
290 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a); | 311 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); |
291 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x79); | 312 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); |
292 | } | 313 | } |
293 | break; | 314 | break; |
294 | 315 | ||
295 | case BANDWIDTH_8_MHZ: | 316 | case BANDWIDTH_8_MHZ: |
296 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz)); | 317 | if (tda10046_clk53m) |
318 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M, | ||
319 | sizeof(bandwidth_8mhz_53M)); | ||
320 | else | ||
321 | tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M, | ||
322 | sizeof(bandwidth_8mhz_48M)); | ||
297 | if (state->config->if_freq == TDA10046_FREQ_045) { | 323 | if (state->config->if_freq == TDA10046_FREQ_045) { |
298 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b); | 324 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); |
299 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3); | 325 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55); |
300 | } | 326 | } |
301 | break; | 327 | break; |
302 | 328 | ||
@@ -418,9 +444,22 @@ static int tda10045_fwupload(struct dvb_frontend* fe) | |||
418 | static void tda10046_init_plls(struct dvb_frontend* fe) | 444 | static void tda10046_init_plls(struct dvb_frontend* fe) |
419 | { | 445 | { |
420 | struct tda1004x_state* state = fe->demodulator_priv; | 446 | struct tda1004x_state* state = fe->demodulator_priv; |
447 | int tda10046_clk53m; | ||
448 | |||
449 | if ((state->config->if_freq == TDA10046_FREQ_045) || | ||
450 | (state->config->if_freq == TDA10046_FREQ_052)) | ||
451 | tda10046_clk53m = 0; | ||
452 | else | ||
453 | tda10046_clk53m = 1; | ||
421 | 454 | ||
422 | tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); | 455 | tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); |
423 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10 | 456 | if(tda10046_clk53m) { |
457 | printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n"); | ||
458 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8 | ||
459 | } else { | ||
460 | printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n"); | ||
461 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3 | ||
462 | } | ||
424 | if (state->config->xtal_freq == TDA10046_XTAL_4M ) { | 463 | if (state->config->xtal_freq == TDA10046_XTAL_4M ) { |
425 | dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); | 464 | dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); |
426 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 | 465 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 |
@@ -428,26 +467,32 @@ static void tda10046_init_plls(struct dvb_frontend* fe) | |||
428 | dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__); | 467 | dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__); |
429 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3 | 468 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3 |
430 | } | 469 | } |
431 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); | 470 | if(tda10046_clk53m) |
471 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67); | ||
472 | else | ||
473 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72); | ||
474 | /* Note clock frequency is handled implicitly */ | ||
432 | switch (state->config->if_freq) { | 475 | switch (state->config->if_freq) { |
433 | case TDA10046_FREQ_3617: | ||
434 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); | ||
435 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); | ||
436 | break; | ||
437 | case TDA10046_FREQ_3613: | ||
438 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); | ||
439 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x13); | ||
440 | break; | ||
441 | case TDA10046_FREQ_045: | 476 | case TDA10046_FREQ_045: |
442 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b); | 477 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); |
443 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3); | 478 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); |
444 | break; | 479 | break; |
445 | case TDA10046_FREQ_052: | 480 | case TDA10046_FREQ_052: |
446 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); | 481 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); |
447 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x06); | 482 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7); |
483 | break; | ||
484 | case TDA10046_FREQ_3617: | ||
485 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); | ||
486 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59); | ||
487 | break; | ||
488 | case TDA10046_FREQ_3613: | ||
489 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); | ||
490 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f); | ||
448 | break; | 491 | break; |
449 | } | 492 | } |
450 | tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz | 493 | tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz |
494 | /* let the PLLs settle */ | ||
495 | msleep(120); | ||
451 | } | 496 | } |
452 | 497 | ||
453 | static int tda10046_fwupload(struct dvb_frontend* fe) | 498 | static int tda10046_fwupload(struct dvb_frontend* fe) |
@@ -462,13 +507,13 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
462 | /* let the clocks recover from sleep */ | 507 | /* let the clocks recover from sleep */ |
463 | msleep(5); | 508 | msleep(5); |
464 | 509 | ||
510 | /* The PLLs need to be reprogrammed after sleep */ | ||
511 | tda10046_init_plls(fe); | ||
512 | |||
465 | /* don't re-upload unless necessary */ | 513 | /* don't re-upload unless necessary */ |
466 | if (tda1004x_check_upload_ok(state) == 0) | 514 | if (tda1004x_check_upload_ok(state) == 0) |
467 | return 0; | 515 | return 0; |
468 | 516 | ||
469 | /* set parameters */ | ||
470 | tda10046_init_plls(fe); | ||
471 | |||
472 | if (state->config->request_firmware != NULL) { | 517 | if (state->config->request_firmware != NULL) { |
473 | /* request the firmware, this will block until someone uploads it */ | 518 | /* request the firmware, this will block until someone uploads it */ |
474 | printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); | 519 | printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); |
@@ -484,7 +529,6 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
484 | return ret; | 529 | return ret; |
485 | } else { | 530 | } else { |
486 | /* boot from firmware eeprom */ | 531 | /* boot from firmware eeprom */ |
487 | /* Hac Note: we might need to do some GPIO Magic here */ | ||
488 | printk(KERN_INFO "tda1004x: booting from eeprom\n"); | 532 | printk(KERN_INFO "tda1004x: booting from eeprom\n"); |
489 | tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); | 533 | tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); |
490 | msleep(300); | 534 | msleep(300); |
@@ -606,10 +650,9 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
606 | 650 | ||
607 | // tda setup | 651 | // tda setup |
608 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer | 652 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer |
609 | tda1004x_write_byteI(state, TDA1004X_AUTO, 7); // select HP stream | 653 | tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream |
610 | tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer | 654 | tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer |
611 | 655 | ||
612 | tda10046_init_plls(fe); | ||
613 | switch (state->config->agc_config) { | 656 | switch (state->config->agc_config) { |
614 | case TDA10046_AGC_DEFAULT: | 657 | case TDA10046_AGC_DEFAULT: |
615 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup | 658 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup |
@@ -626,25 +669,22 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
626 | case TDA10046_AGC_TDA827X: | 669 | case TDA10046_AGC_TDA827X: |
627 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup | 670 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup |
628 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold | 671 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold |
629 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x0E); // Gain Renormalize | 672 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize |
630 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities | 673 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities |
631 | break; | 674 | break; |
632 | } | 675 | } |
676 | tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); | ||
633 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on | 677 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on |
634 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } | 678 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } |
635 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values | 679 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values |
636 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } | 680 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } |
637 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } | 681 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } |
638 | tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1 | 682 | tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1 |
639 | tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits | 683 | tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits |
640 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config | 684 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config |
641 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config | 685 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config |
642 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); | 686 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); |
643 | 687 | ||
644 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup | ||
645 | tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config | ||
646 | tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 8); // GPIO select | ||
647 | |||
648 | state->initialised = 1; | 688 | state->initialised = 1; |
649 | return 0; | 689 | return 0; |
650 | } | 690 | } |
@@ -686,9 +726,9 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
686 | 726 | ||
687 | // Set standard params.. or put them to auto | 727 | // Set standard params.. or put them to auto |
688 | if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) || | 728 | if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) || |
689 | (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || | 729 | (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || |
690 | (fe_params->u.ofdm.constellation == QAM_AUTO) || | 730 | (fe_params->u.ofdm.constellation == QAM_AUTO) || |
691 | (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { | 731 | (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { |
692 | tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto | 732 | tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto |
693 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits | 733 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits |
694 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits | 734 | tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits |
@@ -851,6 +891,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
851 | static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) | 891 | static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) |
852 | { | 892 | { |
853 | struct tda1004x_state* state = fe->demodulator_priv; | 893 | struct tda1004x_state* state = fe->demodulator_priv; |
894 | |||
854 | dprintk("%s\n", __FUNCTION__); | 895 | dprintk("%s\n", __FUNCTION__); |
855 | 896 | ||
856 | // inversion status | 897 | // inversion status |
@@ -875,16 +916,18 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
875 | break; | 916 | break; |
876 | } | 917 | } |
877 | break; | 918 | break; |
878 | |||
879 | case TDA1004X_DEMOD_TDA10046: | 919 | case TDA1004X_DEMOD_TDA10046: |
880 | switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) { | 920 | switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) { |
881 | case 0x60: | 921 | case 0x5c: |
922 | case 0x54: | ||
882 | fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; | 923 | fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; |
883 | break; | 924 | break; |
884 | case 0x6e: | 925 | case 0x6a: |
926 | case 0x60: | ||
885 | fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; | 927 | fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; |
886 | break; | 928 | break; |
887 | case 0x80: | 929 | case 0x7b: |
930 | case 0x70: | ||
888 | fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; | 931 | fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; |
889 | break; | 932 | break; |
890 | } | 933 | } |
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig index f02842be0d60..84f8f9f52869 100644 --- a/drivers/media/dvb/pluto2/Kconfig +++ b/drivers/media/dvb/pluto2/Kconfig | |||
@@ -8,7 +8,7 @@ config DVB_PLUTO2 | |||
8 | Support for PCI cards based on the Pluto2 FPGA like the Satelco | 8 | Support for PCI cards based on the Pluto2 FPGA like the Satelco |
9 | Easywatch Mobile Terrestrial DVB-T Receiver. | 9 | Easywatch Mobile Terrestrial DVB-T Receiver. |
10 | 10 | ||
11 | Since these cards have no MPEG decoder onboard, they transmit | 11 | Since these cards have no MPEG decoder onboard, they transmit |
12 | only compressed MPEG data over the PCI bus, so you need | 12 | only compressed MPEG data over the PCI bus, so you need |
13 | an external software decoder to watch TV on your computer. | 13 | an external software decoder to watch TV on your computer. |
14 | 14 | ||
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index fa5034a9ecf5..5b2aadb8385c 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig | |||
@@ -18,9 +18,10 @@ config DVB_AV7110 | |||
18 | This driver only supports the fullfeatured cards with | 18 | This driver only supports the fullfeatured cards with |
19 | onboard MPEG2 decoder. | 19 | onboard MPEG2 decoder. |
20 | 20 | ||
21 | This driver needs an external firmware. Please use the script | 21 | This driver needs an external firmware. Please use the script |
22 | "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to | 22 | "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to |
23 | download/extract it, and then copy it to /usr/lib/hotplug/firmware. | 23 | download/extract it, and then copy it to /usr/lib/hotplug/firmware |
24 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
24 | 25 | ||
25 | Say Y if you own such a card and want to use it. | 26 | Say Y if you own such a card and want to use it. |
26 | 27 | ||
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile index 825ab1c38a4f..a690730ac39d 100644 --- a/drivers/media/dvb/ttpci/Makefile +++ b/drivers/media/dvb/ttpci/Makefile | |||
@@ -16,7 +16,7 @@ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | |||
16 | hostprogs-y := fdump | 16 | hostprogs-y := fdump |
17 | 17 | ||
18 | ifdef CONFIG_DVB_AV7110_FIRMWARE | 18 | ifdef CONFIG_DVB_AV7110_FIRMWARE |
19 | $(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h | 19 | $(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h |
20 | 20 | ||
21 | $(obj)/av7110_firm.h: | 21 | $(obj)/av7110_firm.h: |
22 | $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ | 22 | $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 7dae91e5863c..8ce4146f55f1 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -133,7 +133,13 @@ static void init_av7110_av(struct av7110 *av7110) | |||
133 | /* remaining inits according to card and frontend type */ | 133 | /* remaining inits according to card and frontend type */ |
134 | av7110->analog_tuner_flags = 0; | 134 | av7110->analog_tuner_flags = 0; |
135 | av7110->current_input = 0; | 135 | av7110->current_input = 0; |
136 | if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { | 136 | if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) { |
137 | printk("dvb-ttpci: MSP3415 audio DAC @ card %d\n", | ||
138 | av7110->dvb_adapter.num); | ||
139 | av7110->adac_type = DVB_ADAC_MSP34x5; | ||
140 | av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on | ||
141 | } | ||
142 | else if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { | ||
137 | printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", | 143 | printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", |
138 | av7110->dvb_adapter.num); | 144 | av7110->dvb_adapter.num); |
139 | av7110->adac_type = DVB_ADAC_CRYSTAL; | 145 | av7110->adac_type = DVB_ADAC_CRYSTAL; |
@@ -156,10 +162,10 @@ static void init_av7110_av(struct av7110 *av7110) | |||
156 | else { | 162 | else { |
157 | av7110->adac_type = adac; | 163 | av7110->adac_type = adac; |
158 | printk("dvb-ttpci: adac type set to %d @ card %d\n", | 164 | printk("dvb-ttpci: adac type set to %d @ card %d\n", |
159 | av7110->dvb_adapter.num, av7110->adac_type); | 165 | av7110->adac_type, av7110->dvb_adapter.num); |
160 | } | 166 | } |
161 | 167 | ||
162 | if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { | 168 | if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) { |
163 | // switch DVB SCART on | 169 | // switch DVB SCART on |
164 | ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); | 170 | ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); |
165 | if (ret < 0) | 171 | if (ret < 0) |
@@ -190,17 +196,15 @@ static void recover_arm(struct av7110 *av7110) | |||
190 | 196 | ||
191 | av7110_bootarm(av7110); | 197 | av7110_bootarm(av7110); |
192 | msleep(100); | 198 | msleep(100); |
193 | restart_feeds(av7110); | ||
194 | av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config); | ||
195 | } | ||
196 | 199 | ||
197 | static void arm_error(struct av7110 *av7110) | 200 | init_av7110_av(av7110); |
198 | { | 201 | |
199 | dprintk(4, "%p\n",av7110); | 202 | /* card-specific recovery */ |
203 | if (av7110->recover) | ||
204 | av7110->recover(av7110); | ||
200 | 205 | ||
201 | av7110->arm_errors++; | 206 | restart_feeds(av7110); |
202 | av7110->arm_ready = 0; | 207 | av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config); |
203 | recover_arm(av7110); | ||
204 | } | 208 | } |
205 | 209 | ||
206 | static void av7110_arm_sync(struct av7110 *av7110) | 210 | static void av7110_arm_sync(struct av7110 *av7110) |
@@ -240,26 +244,22 @@ static int arm_thread(void *data) | |||
240 | 244 | ||
241 | if (down_interruptible(&av7110->dcomlock)) | 245 | if (down_interruptible(&av7110->dcomlock)) |
242 | break; | 246 | break; |
243 | |||
244 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); | 247 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); |
245 | up(&av7110->dcomlock); | 248 | up(&av7110->dcomlock); |
246 | 249 | ||
247 | if (newloops == av7110->arm_loops) { | 250 | if (newloops == av7110->arm_loops || av7110->arm_errors > 3) { |
248 | printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", | 251 | printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", |
249 | av7110->dvb_adapter.num); | 252 | av7110->dvb_adapter.num); |
250 | 253 | ||
251 | arm_error(av7110); | 254 | recover_arm(av7110); |
252 | av7710_set_video_mode(av7110, vidmode); | ||
253 | |||
254 | init_av7110_av(av7110); | ||
255 | 255 | ||
256 | if (down_interruptible(&av7110->dcomlock)) | 256 | if (down_interruptible(&av7110->dcomlock)) |
257 | break; | 257 | break; |
258 | |||
259 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1; | 258 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1; |
260 | up(&av7110->dcomlock); | 259 | up(&av7110->dcomlock); |
261 | } | 260 | } |
262 | av7110->arm_loops = newloops; | 261 | av7110->arm_loops = newloops; |
262 | av7110->arm_errors = 0; | ||
263 | } | 263 | } |
264 | 264 | ||
265 | av7110->arm_thread = NULL; | 265 | av7110->arm_thread = NULL; |
@@ -510,10 +510,6 @@ static void gpioirq(unsigned long data) | |||
510 | iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); | 510 | iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); |
511 | 511 | ||
512 | av7110->video_size.h = h_ar & 0xfff; | 512 | av7110->video_size.h = h_ar & 0xfff; |
513 | dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", | ||
514 | av7110->video_size.w, | ||
515 | av7110->video_size.h, | ||
516 | av7110->video_size.aspect_ratio); | ||
517 | 513 | ||
518 | event.type = VIDEO_EVENT_SIZE_CHANGED; | 514 | event.type = VIDEO_EVENT_SIZE_CHANGED; |
519 | event.u.size.w = av7110->video_size.w; | 515 | event.u.size.w = av7110->video_size.w; |
@@ -535,6 +531,11 @@ static void gpioirq(unsigned long data) | |||
535 | event.u.size.aspect_ratio = VIDEO_FORMAT_4_3; | 531 | event.u.size.aspect_ratio = VIDEO_FORMAT_4_3; |
536 | av7110->videostate.video_format = VIDEO_FORMAT_4_3; | 532 | av7110->videostate.video_format = VIDEO_FORMAT_4_3; |
537 | } | 533 | } |
534 | |||
535 | dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", | ||
536 | av7110->video_size.w, av7110->video_size.h, | ||
537 | av7110->video_size.aspect_ratio); | ||
538 | |||
538 | dvb_video_add_event(av7110, &event); | 539 | dvb_video_add_event(av7110, &event); |
539 | break; | 540 | break; |
540 | } | 541 | } |
@@ -714,6 +715,8 @@ static struct dvb_device dvbdev_osd = { | |||
714 | static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | 715 | static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, |
715 | u16 subpid, u16 pcrpid) | 716 | u16 subpid, u16 pcrpid) |
716 | { | 717 | { |
718 | u16 aflags = 0; | ||
719 | |||
717 | dprintk(4, "%p\n", av7110); | 720 | dprintk(4, "%p\n", av7110); |
718 | 721 | ||
719 | if (vpid == 0x1fff || apid == 0x1fff || | 722 | if (vpid == 0x1fff || apid == 0x1fff || |
@@ -725,8 +728,11 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | |||
725 | av7110->pids[DMX_PES_PCR] = 0; | 728 | av7110->pids[DMX_PES_PCR] = 0; |
726 | } | 729 | } |
727 | 730 | ||
728 | return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 5, | 731 | if (av7110->audiostate.bypass_mode) |
729 | pcrpid, vpid, apid, ttpid, subpid); | 732 | aflags |= 0x8000; |
733 | |||
734 | return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6, | ||
735 | pcrpid, vpid, apid, ttpid, subpid, aflags); | ||
730 | } | 736 | } |
731 | 737 | ||
732 | int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | 738 | int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, |
@@ -1043,7 +1049,7 @@ static void restart_feeds(struct av7110 *av7110) | |||
1043 | struct dvb_demux *dvbdmx = &av7110->demux; | 1049 | struct dvb_demux *dvbdmx = &av7110->demux; |
1044 | struct dvb_demux_feed *feed; | 1050 | struct dvb_demux_feed *feed; |
1045 | int mode; | 1051 | int mode; |
1046 | int i; | 1052 | int i, j; |
1047 | 1053 | ||
1048 | dprintk(4, "%p\n", av7110); | 1054 | dprintk(4, "%p\n", av7110); |
1049 | 1055 | ||
@@ -1051,10 +1057,21 @@ static void restart_feeds(struct av7110 *av7110) | |||
1051 | av7110->playing = 0; | 1057 | av7110->playing = 0; |
1052 | av7110->rec_mode = 0; | 1058 | av7110->rec_mode = 0; |
1053 | 1059 | ||
1054 | for (i = 0; i < dvbdmx->filternum; i++) { | 1060 | for (i = 0; i < dvbdmx->feednum; i++) { |
1055 | feed = &dvbdmx->feed[i]; | 1061 | feed = &dvbdmx->feed[i]; |
1056 | if (feed->state == DMX_STATE_GO) | 1062 | if (feed->state == DMX_STATE_GO) { |
1063 | if (feed->type == DMX_TYPE_SEC) { | ||
1064 | for (j = 0; j < dvbdmx->filternum; j++) { | ||
1065 | if (dvbdmx->filter[j].type != DMX_TYPE_SEC) | ||
1066 | continue; | ||
1067 | if (dvbdmx->filter[j].filter.parent != &feed->feed.sec) | ||
1068 | continue; | ||
1069 | if (dvbdmx->filter[j].state == DMX_STATE_GO) | ||
1070 | dvbdmx->filter[j].state = DMX_STATE_READY; | ||
1071 | } | ||
1072 | } | ||
1057 | av7110_start_feed(feed); | 1073 | av7110_start_feed(feed); |
1074 | } | ||
1058 | } | 1075 | } |
1059 | 1076 | ||
1060 | if (mode) | 1077 | if (mode) |
@@ -1483,9 +1500,9 @@ static int get_firmware(struct av7110* av7110) | |||
1483 | if (ret == -ENOENT) { | 1500 | if (ret == -ENOENT) { |
1484 | printk(KERN_ERR "dvb-ttpci: could not load firmware," | 1501 | printk(KERN_ERR "dvb-ttpci: could not load firmware," |
1485 | " file not found: dvb-ttpci-01.fw\n"); | 1502 | " file not found: dvb-ttpci-01.fw\n"); |
1486 | printk(KERN_ERR "dvb-ttpci: usually this should be in" | 1503 | printk(KERN_ERR "dvb-ttpci: usually this should be in " |
1487 | " /usr/lib/hotplug/firmware\n"); | 1504 | "/usr/lib/hotplug/firmware or /lib/firmware\n"); |
1488 | printk(KERN_ERR "dvb-ttpci: and can be downloaded here" | 1505 | printk(KERN_ERR "dvb-ttpci: and can be downloaded from" |
1489 | " http://www.linuxtv.org/download/dvb/firmware/\n"); | 1506 | " http://www.linuxtv.org/download/dvb/firmware/\n"); |
1490 | } else | 1507 | } else |
1491 | printk(KERN_ERR "dvb-ttpci: cannot request firmware" | 1508 | printk(KERN_ERR "dvb-ttpci: cannot request firmware" |
@@ -2110,8 +2127,10 @@ static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_p | |||
2110 | struct av7110* av7110 = fe->dvb->priv; | 2127 | struct av7110* av7110 = fe->dvb->priv; |
2111 | 2128 | ||
2112 | int ret = av7110_fe_lock_fix(av7110, 0); | 2129 | int ret = av7110_fe_lock_fix(av7110, 0); |
2113 | if (!ret) | 2130 | if (!ret) { |
2131 | av7110->saved_fe_params = *params; | ||
2114 | ret = av7110->fe_set_frontend(fe, params); | 2132 | ret = av7110->fe_set_frontend(fe, params); |
2133 | } | ||
2115 | return ret; | 2134 | return ret; |
2116 | } | 2135 | } |
2117 | 2136 | ||
@@ -2153,8 +2172,10 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, | |||
2153 | struct av7110* av7110 = fe->dvb->priv; | 2172 | struct av7110* av7110 = fe->dvb->priv; |
2154 | 2173 | ||
2155 | int ret = av7110_fe_lock_fix(av7110, 0); | 2174 | int ret = av7110_fe_lock_fix(av7110, 0); |
2156 | if (!ret) | 2175 | if (!ret) { |
2176 | av7110->saved_master_cmd = *cmd; | ||
2157 | ret = av7110->fe_diseqc_send_master_cmd(fe, cmd); | 2177 | ret = av7110->fe_diseqc_send_master_cmd(fe, cmd); |
2178 | } | ||
2158 | return ret; | 2179 | return ret; |
2159 | } | 2180 | } |
2160 | 2181 | ||
@@ -2163,8 +2184,10 @@ static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_ | |||
2163 | struct av7110* av7110 = fe->dvb->priv; | 2184 | struct av7110* av7110 = fe->dvb->priv; |
2164 | 2185 | ||
2165 | int ret = av7110_fe_lock_fix(av7110, 0); | 2186 | int ret = av7110_fe_lock_fix(av7110, 0); |
2166 | if (!ret) | 2187 | if (!ret) { |
2188 | av7110->saved_minicmd = minicmd; | ||
2167 | ret = av7110->fe_diseqc_send_burst(fe, minicmd); | 2189 | ret = av7110->fe_diseqc_send_burst(fe, minicmd); |
2190 | } | ||
2168 | return ret; | 2191 | return ret; |
2169 | } | 2192 | } |
2170 | 2193 | ||
@@ -2173,8 +2196,10 @@ static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
2173 | struct av7110* av7110 = fe->dvb->priv; | 2196 | struct av7110* av7110 = fe->dvb->priv; |
2174 | 2197 | ||
2175 | int ret = av7110_fe_lock_fix(av7110, 0); | 2198 | int ret = av7110_fe_lock_fix(av7110, 0); |
2176 | if (!ret) | 2199 | if (!ret) { |
2200 | av7110->saved_tone = tone; | ||
2177 | ret = av7110->fe_set_tone(fe, tone); | 2201 | ret = av7110->fe_set_tone(fe, tone); |
2202 | } | ||
2178 | return ret; | 2203 | return ret; |
2179 | } | 2204 | } |
2180 | 2205 | ||
@@ -2183,12 +2208,14 @@ static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t volta | |||
2183 | struct av7110* av7110 = fe->dvb->priv; | 2208 | struct av7110* av7110 = fe->dvb->priv; |
2184 | 2209 | ||
2185 | int ret = av7110_fe_lock_fix(av7110, 0); | 2210 | int ret = av7110_fe_lock_fix(av7110, 0); |
2186 | if (!ret) | 2211 | if (!ret) { |
2212 | av7110->saved_voltage = voltage; | ||
2187 | ret = av7110->fe_set_voltage(fe, voltage); | 2213 | ret = av7110->fe_set_voltage(fe, voltage); |
2214 | } | ||
2188 | return ret; | 2215 | return ret; |
2189 | } | 2216 | } |
2190 | 2217 | ||
2191 | static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd) | 2218 | static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd) |
2192 | { | 2219 | { |
2193 | struct av7110* av7110 = fe->dvb->priv; | 2220 | struct av7110* av7110 = fe->dvb->priv; |
2194 | 2221 | ||
@@ -2198,6 +2225,23 @@ static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, un | |||
2198 | return ret; | 2225 | return ret; |
2199 | } | 2226 | } |
2200 | 2227 | ||
2228 | static void dvb_s_recover(struct av7110* av7110) | ||
2229 | { | ||
2230 | av7110_fe_init(av7110->fe); | ||
2231 | |||
2232 | av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage); | ||
2233 | if (av7110->saved_master_cmd.msg_len) { | ||
2234 | msleep(20); | ||
2235 | av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd); | ||
2236 | } | ||
2237 | msleep(20); | ||
2238 | av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd); | ||
2239 | msleep(20); | ||
2240 | av7110_fe_set_tone(av7110->fe, av7110->saved_tone); | ||
2241 | |||
2242 | av7110_fe_set_frontend(av7110->fe, &av7110->saved_fe_params); | ||
2243 | } | ||
2244 | |||
2201 | static u8 read_pwm(struct av7110* av7110) | 2245 | static u8 read_pwm(struct av7110* av7110) |
2202 | { | 2246 | { |
2203 | u8 b = 0xff; | 2247 | u8 b = 0xff; |
@@ -2235,6 +2279,7 @@ static int frontend_init(struct av7110 *av7110) | |||
2235 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2279 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2236 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2280 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; |
2237 | av7110->fe->ops->set_tone = av7110_set_tone; | 2281 | av7110->fe->ops->set_tone = av7110_set_tone; |
2282 | av7110->recover = dvb_s_recover; | ||
2238 | break; | 2283 | break; |
2239 | } | 2284 | } |
2240 | 2285 | ||
@@ -2244,15 +2289,17 @@ static int frontend_init(struct av7110 *av7110) | |||
2244 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2289 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2245 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2290 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; |
2246 | av7110->fe->ops->set_tone = av7110_set_tone; | 2291 | av7110->fe->ops->set_tone = av7110_set_tone; |
2292 | av7110->recover = dvb_s_recover; | ||
2247 | break; | 2293 | break; |
2248 | } | 2294 | } |
2249 | 2295 | ||
2250 | // Try the grundig 29504-451 | 2296 | // Try the grundig 29504-451 |
2251 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); | 2297 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); |
2252 | if (av7110->fe) { | 2298 | if (av7110->fe) { |
2253 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2299 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2254 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2300 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; |
2255 | av7110->fe->ops->set_tone = av7110_set_tone; | 2301 | av7110->fe->ops->set_tone = av7110_set_tone; |
2302 | av7110->recover = dvb_s_recover; | ||
2256 | break; | 2303 | break; |
2257 | } | 2304 | } |
2258 | 2305 | ||
@@ -2274,12 +2321,12 @@ static int frontend_init(struct av7110 *av7110) | |||
2274 | case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X | 2321 | case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X |
2275 | 2322 | ||
2276 | // ALPS TDLB7 | 2323 | // ALPS TDLB7 |
2277 | av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); | 2324 | av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); |
2278 | break; | 2325 | break; |
2279 | 2326 | ||
2280 | case 0x0002: // Hauppauge/TT DVB-C premium rev2.X | 2327 | case 0x0002: // Hauppauge/TT DVB-C premium rev2.X |
2281 | 2328 | ||
2282 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); | 2329 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); |
2283 | break; | 2330 | break; |
2284 | 2331 | ||
2285 | case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ | 2332 | case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ |
@@ -2289,6 +2336,7 @@ static int frontend_init(struct av7110 *av7110) | |||
2289 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2336 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2290 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2337 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; |
2291 | av7110->fe->ops->set_tone = av7110_set_tone; | 2338 | av7110->fe->ops->set_tone = av7110_set_tone; |
2339 | av7110->recover = dvb_s_recover; | ||
2292 | } | 2340 | } |
2293 | break; | 2341 | break; |
2294 | 2342 | ||
@@ -2314,8 +2362,11 @@ static int frontend_init(struct av7110 *av7110) | |||
2314 | case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */ | 2362 | case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */ |
2315 | /* ALPS BSBE1 */ | 2363 | /* ALPS BSBE1 */ |
2316 | av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); | 2364 | av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); |
2317 | if (av7110->fe) | 2365 | if (av7110->fe) { |
2318 | av7110->fe->ops->set_voltage = lnbp21_set_voltage; | 2366 | av7110->fe->ops->set_voltage = lnbp21_set_voltage; |
2367 | av7110->fe->ops->dishnetwork_send_legacy_command = NULL; | ||
2368 | av7110->recover = dvb_s_recover; | ||
2369 | } | ||
2319 | break; | 2370 | break; |
2320 | } | 2371 | } |
2321 | } | 2372 | } |
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index cce00ef293e9..6ea30df2e823 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h | |||
@@ -98,7 +98,8 @@ struct av7110 { | |||
98 | int adac_type; /* audio DAC type */ | 98 | int adac_type; /* audio DAC type */ |
99 | #define DVB_ADAC_TI 0 | 99 | #define DVB_ADAC_TI 0 |
100 | #define DVB_ADAC_CRYSTAL 1 | 100 | #define DVB_ADAC_CRYSTAL 1 |
101 | #define DVB_ADAC_MSP 2 | 101 | #define DVB_ADAC_MSP34x0 2 |
102 | #define DVB_ADAC_MSP34x5 3 | ||
102 | #define DVB_ADAC_NONE -1 | 103 | #define DVB_ADAC_NONE -1 |
103 | 104 | ||
104 | 105 | ||
@@ -228,6 +229,9 @@ struct av7110 { | |||
228 | struct dvb_video_events video_events; | 229 | struct dvb_video_events video_events; |
229 | video_size_t video_size; | 230 | video_size_t video_size; |
230 | 231 | ||
232 | u16 wssMode; | ||
233 | u16 wssData; | ||
234 | |||
231 | u32 ir_config; | 235 | u32 ir_config; |
232 | u32 ir_command; | 236 | u32 ir_command; |
233 | void (*ir_handler)(struct av7110 *av7110, u32 ircom); | 237 | void (*ir_handler)(struct av7110 *av7110, u32 ircom); |
@@ -245,6 +249,15 @@ struct av7110 { | |||
245 | 249 | ||
246 | struct dvb_frontend* fe; | 250 | struct dvb_frontend* fe; |
247 | fe_status_t fe_status; | 251 | fe_status_t fe_status; |
252 | |||
253 | /* crash recovery */ | ||
254 | void (*recover)(struct av7110* av7110); | ||
255 | struct dvb_frontend_parameters saved_fe_params; | ||
256 | fe_sec_voltage_t saved_voltage; | ||
257 | fe_sec_tone_mode_t saved_tone; | ||
258 | struct dvb_diseqc_master_cmd saved_master_cmd; | ||
259 | fe_sec_mini_cmd_t saved_minicmd; | ||
260 | |||
248 | int (*fe_init)(struct dvb_frontend* fe); | 261 | int (*fe_init)(struct dvb_frontend* fe); |
249 | int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status); | 262 | int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status); |
250 | int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe); | 263 | int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe); |
@@ -252,7 +265,7 @@ struct av7110 { | |||
252 | int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); | 265 | int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); |
253 | int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); | 266 | int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); |
254 | int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); | 267 | int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); |
255 | int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd); | 268 | int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); |
256 | int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | 269 | int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); |
257 | }; | 270 | }; |
258 | 271 | ||
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 0696a5a4f855..400facec7407 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c | |||
@@ -309,7 +309,7 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright) | |||
309 | i2c_writereg(av7110, 0x20, 0x04, volright); | 309 | i2c_writereg(av7110, 0x20, 0x04, volright); |
310 | return 0; | 310 | return 0; |
311 | 311 | ||
312 | case DVB_ADAC_MSP: | 312 | case DVB_ADAC_MSP34x0: |
313 | vol = (volleft > volright) ? volleft : volright; | 313 | vol = (volleft > volright) ? volleft : volright; |
314 | val = (vol * 0x73 / 255) << 8; | 314 | val = (vol * 0x73 / 255) << 8; |
315 | if (vol > 0) | 315 | if (vol > 0) |
@@ -1256,7 +1256,9 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, | |||
1256 | break; | 1256 | break; |
1257 | 1257 | ||
1258 | case AUDIO_SET_BYPASS_MODE: | 1258 | case AUDIO_SET_BYPASS_MODE: |
1259 | ret = -EINVAL; | 1259 | if (FW_VERSION(av7110->arm_app) < 0x2621) |
1260 | ret = -EINVAL; | ||
1261 | av7110->audiostate.bypass_mode = (int)arg; | ||
1260 | break; | 1262 | break; |
1261 | 1263 | ||
1262 | case AUDIO_CHANNEL_SELECT: | 1264 | case AUDIO_CHANNEL_SELECT: |
@@ -1295,7 +1297,11 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, | |||
1295 | break; | 1297 | break; |
1296 | 1298 | ||
1297 | case AUDIO_GET_CAPABILITIES: | 1299 | case AUDIO_GET_CAPABILITIES: |
1298 | *(int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; | 1300 | if (FW_VERSION(av7110->arm_app) < 0x2621) |
1301 | *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; | ||
1302 | else | ||
1303 | *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 | | ||
1304 | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; | ||
1299 | break; | 1305 | break; |
1300 | 1306 | ||
1301 | case AUDIO_CLEAR_BUFFER: | 1307 | case AUDIO_CLEAR_BUFFER: |
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index 87106e8bf35b..cb377452b57d 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c | |||
@@ -230,6 +230,8 @@ int av7110_bootarm(struct av7110 *av7110) | |||
230 | 230 | ||
231 | dprintk(4, "%p\n", av7110); | 231 | dprintk(4, "%p\n", av7110); |
232 | 232 | ||
233 | av7110->arm_ready = 0; | ||
234 | |||
233 | saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); | 235 | saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); |
234 | 236 | ||
235 | /* Disable DEBI and GPIO irq */ | 237 | /* Disable DEBI and GPIO irq */ |
@@ -361,6 +363,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) | |||
361 | break; | 363 | break; |
362 | if (err) { | 364 | if (err) { |
363 | printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__); | 365 | printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__); |
366 | av7110->arm_errors++; | ||
364 | return -ETIMEDOUT; | 367 | return -ETIMEDOUT; |
365 | } | 368 | } |
366 | msleep(1); | 369 | msleep(1); |
@@ -1206,9 +1209,9 @@ int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap) | |||
1206 | switch (cap->cmd) { | 1209 | switch (cap->cmd) { |
1207 | case OSD_CAP_MEMSIZE: | 1210 | case OSD_CAP_MEMSIZE: |
1208 | if (FW_4M_SDRAM(av7110->arm_app)) | 1211 | if (FW_4M_SDRAM(av7110->arm_app)) |
1209 | cap->val = 1000000; | 1212 | cap->val = 1000000; |
1210 | else | 1213 | else |
1211 | cap->val = 92000; | 1214 | cap->val = 92000; |
1212 | return 0; | 1215 | return 0; |
1213 | default: | 1216 | default: |
1214 | return -EINVAL; | 1217 | return -EINVAL; |
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h index 2a5e87ba1052..84b83299b8be 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.h +++ b/drivers/media/dvb/ttpci/av7110_hw.h | |||
@@ -167,7 +167,8 @@ enum av7110_encoder_command { | |||
167 | LoadVidCode, | 167 | LoadVidCode, |
168 | SetMonitorType, | 168 | SetMonitorType, |
169 | SetPanScanType, | 169 | SetPanScanType, |
170 | SetFreezeMode | 170 | SetFreezeMode, |
171 | SetWSSConfig | ||
171 | }; | 172 | }; |
172 | 173 | ||
173 | enum av7110_rec_play_state { | 174 | enum av7110_rec_play_state { |
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c index f5e59fc924af..9138132ad25f 100644 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ b/drivers/media/dvb/ttpci/av7110_ir.c | |||
@@ -17,6 +17,8 @@ static int av_cnt; | |||
17 | static struct av7110 *av_list[4]; | 17 | static struct av7110 *av_list[4]; |
18 | static struct input_dev *input_dev; | 18 | static struct input_dev *input_dev; |
19 | 19 | ||
20 | static u8 delay_timer_finished; | ||
21 | |||
20 | static u16 key_map [256] = { | 22 | static u16 key_map [256] = { |
21 | KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, | 23 | KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, |
22 | KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, | 24 | KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, |
@@ -112,13 +114,16 @@ static void av7110_emit_key(unsigned long parm) | |||
112 | if (timer_pending(&keyup_timer)) { | 114 | if (timer_pending(&keyup_timer)) { |
113 | del_timer(&keyup_timer); | 115 | del_timer(&keyup_timer); |
114 | if (keyup_timer.data != keycode || new_toggle != old_toggle) { | 116 | if (keyup_timer.data != keycode || new_toggle != old_toggle) { |
117 | delay_timer_finished = 0; | ||
115 | input_event(input_dev, EV_KEY, keyup_timer.data, !!0); | 118 | input_event(input_dev, EV_KEY, keyup_timer.data, !!0); |
116 | input_event(input_dev, EV_KEY, keycode, !0); | 119 | input_event(input_dev, EV_KEY, keycode, !0); |
117 | } else | 120 | } else |
118 | input_event(input_dev, EV_KEY, keycode, 2); | 121 | if (delay_timer_finished) |
119 | 122 | input_event(input_dev, EV_KEY, keycode, 2); | |
120 | } else | 123 | } else { |
124 | delay_timer_finished = 0; | ||
121 | input_event(input_dev, EV_KEY, keycode, !0); | 125 | input_event(input_dev, EV_KEY, keycode, !0); |
126 | } | ||
122 | 127 | ||
123 | keyup_timer.expires = jiffies + UP_TIMEOUT; | 128 | keyup_timer.expires = jiffies + UP_TIMEOUT; |
124 | keyup_timer.data = keycode; | 129 | keyup_timer.data = keycode; |
@@ -145,7 +150,8 @@ static void input_register_keys(void) | |||
145 | 150 | ||
146 | static void input_repeat_key(unsigned long data) | 151 | static void input_repeat_key(unsigned long data) |
147 | { | 152 | { |
148 | /* dummy routine to disable autorepeat in the input driver */ | 153 | /* called by the input driver after rep[REP_DELAY] ms */ |
154 | delay_timer_finished = 1; | ||
149 | } | 155 | } |
150 | 156 | ||
151 | 157 | ||
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index b5aea4129fa7..94cf38c7e8a8 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c | |||
@@ -490,6 +490,58 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
490 | dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); | 490 | dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); |
491 | break; | 491 | break; |
492 | } | 492 | } |
493 | case VIDIOC_G_SLICED_VBI_CAP: | ||
494 | { | ||
495 | struct v4l2_sliced_vbi_cap *cap = arg; | ||
496 | dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n"); | ||
497 | memset(cap, 0, sizeof *cap); | ||
498 | if (FW_VERSION(av7110->arm_app) >= 0x2623) { | ||
499 | cap->service_set = V4L2_SLICED_WSS_625; | ||
500 | cap->service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
501 | } | ||
502 | break; | ||
503 | } | ||
504 | case VIDIOC_G_FMT: | ||
505 | { | ||
506 | struct v4l2_format *f = arg; | ||
507 | dprintk(2, "VIDIOC_G_FMT:\n"); | ||
508 | if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || | ||
509 | FW_VERSION(av7110->arm_app) < 0x2623) | ||
510 | return -EAGAIN; /* handled by core driver */ | ||
511 | memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); | ||
512 | if (av7110->wssMode) { | ||
513 | f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; | ||
514 | f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
515 | f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data); | ||
516 | } | ||
517 | break; | ||
518 | } | ||
519 | case VIDIOC_S_FMT: | ||
520 | { | ||
521 | struct v4l2_format *f = arg; | ||
522 | dprintk(2, "VIDIOC_S_FMT\n"); | ||
523 | if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || | ||
524 | FW_VERSION(av7110->arm_app) < 0x2623) | ||
525 | return -EAGAIN; /* handled by core driver */ | ||
526 | if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 && | ||
527 | f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) { | ||
528 | memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); | ||
529 | /* WSS controlled by firmware */ | ||
530 | av7110->wssMode = 0; | ||
531 | av7110->wssData = 0; | ||
532 | return av7110_fw_cmd(av7110, COMTYPE_ENCODER, | ||
533 | SetWSSConfig, 1, 0); | ||
534 | } else { | ||
535 | memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); | ||
536 | f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; | ||
537 | f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; | ||
538 | f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data); | ||
539 | /* WSS controlled by userspace */ | ||
540 | av7110->wssMode = 1; | ||
541 | av7110->wssData = 0; | ||
542 | } | ||
543 | break; | ||
544 | } | ||
493 | default: | 545 | default: |
494 | printk("no such ioctl\n"); | 546 | printk("no such ioctl\n"); |
495 | return -ENOIOCTLCMD; | 547 | return -ENOIOCTLCMD; |
@@ -497,6 +549,46 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
497 | return 0; | 549 | return 0; |
498 | } | 550 | } |
499 | 551 | ||
552 | static int av7110_vbi_reset(struct inode *inode, struct file *file) | ||
553 | { | ||
554 | struct saa7146_fh *fh = file->private_data; | ||
555 | struct saa7146_dev *dev = fh->dev; | ||
556 | struct av7110 *av7110 = (struct av7110*) dev->ext_priv; | ||
557 | |||
558 | dprintk(2, "%s\n", __FUNCTION__); | ||
559 | av7110->wssMode = 0; | ||
560 | av7110->wssData = 0; | ||
561 | if (FW_VERSION(av7110->arm_app) < 0x2623) | ||
562 | return 0; | ||
563 | else | ||
564 | return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); | ||
565 | } | ||
566 | |||
567 | static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) | ||
568 | { | ||
569 | struct saa7146_fh *fh = file->private_data; | ||
570 | struct saa7146_dev *dev = fh->dev; | ||
571 | struct av7110 *av7110 = (struct av7110*) dev->ext_priv; | ||
572 | struct v4l2_sliced_vbi_data d; | ||
573 | int rc; | ||
574 | |||
575 | dprintk(2, "%s\n", __FUNCTION__); | ||
576 | if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d) | ||
577 | return -EINVAL; | ||
578 | if (copy_from_user(&d, data, count)) | ||
579 | return -EFAULT; | ||
580 | if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23) | ||
581 | return -EINVAL; | ||
582 | if (d.id) { | ||
583 | av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0]; | ||
584 | rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, | ||
585 | 2, 1, av7110->wssData); | ||
586 | } else { | ||
587 | av7110->wssData = 0; | ||
588 | rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); | ||
589 | } | ||
590 | return (rc < 0) ? rc : count; | ||
591 | } | ||
500 | 592 | ||
501 | /**************************************************************************** | 593 | /**************************************************************************** |
502 | * INITIALIZATION | 594 | * INITIALIZATION |
@@ -512,6 +604,9 @@ static struct saa7146_extension_ioctls ioctls[] = { | |||
512 | { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE }, | 604 | { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE }, |
513 | { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, | 605 | { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, |
514 | { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, | 606 | { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, |
607 | { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE }, | ||
608 | { VIDIOC_G_FMT, SAA7146_BEFORE }, | ||
609 | { VIDIOC_S_FMT, SAA7146_BEFORE }, | ||
515 | { 0, 0 } | 610 | { 0, 0 } |
516 | }; | 611 | }; |
517 | 612 | ||
@@ -587,7 +682,7 @@ int av7110_init_analog_module(struct av7110 *av7110) | |||
587 | 682 | ||
588 | printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", | 683 | printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", |
589 | av7110->dvb_adapter.num); | 684 | av7110->dvb_adapter.num); |
590 | av7110->adac_type = DVB_ADAC_MSP; | 685 | av7110->adac_type = DVB_ADAC_MSP34x0; |
591 | msleep(100); // the probing above resets the msp... | 686 | msleep(100); // the probing above resets the msp... |
592 | msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); | 687 | msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); |
593 | msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); | 688 | msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); |
@@ -692,12 +787,11 @@ int av7110_init_v4l(struct av7110 *av7110) | |||
692 | saa7146_vv_release(dev); | 787 | saa7146_vv_release(dev); |
693 | return -ENODEV; | 788 | return -ENODEV; |
694 | } | 789 | } |
695 | if (av7110->analog_tuner_flags) { | 790 | if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { |
696 | if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { | 791 | ERR(("cannot register vbi v4l2 device. skipping.\n")); |
697 | ERR(("cannot register vbi v4l2 device. skipping.\n")); | 792 | } else { |
698 | } else { | 793 | if (av7110->analog_tuner_flags) |
699 | av7110->analog_tuner_flags |= ANALOG_TUNER_VBI; | 794 | av7110->analog_tuner_flags |= ANALOG_TUNER_VBI; |
700 | } | ||
701 | } | 795 | } |
702 | return 0; | 796 | return 0; |
703 | } | 797 | } |
@@ -778,7 +872,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) | |||
778 | static struct saa7146_ext_vv av7110_vv_data_st = { | 872 | static struct saa7146_ext_vv av7110_vv_data_st = { |
779 | .inputs = 1, | 873 | .inputs = 1, |
780 | .audios = 1, | 874 | .audios = 1, |
781 | .capabilities = 0, | 875 | .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT, |
782 | .flags = 0, | 876 | .flags = 0, |
783 | 877 | ||
784 | .stds = &standard[0], | 878 | .stds = &standard[0], |
@@ -787,12 +881,16 @@ static struct saa7146_ext_vv av7110_vv_data_st = { | |||
787 | 881 | ||
788 | .ioctls = &ioctls[0], | 882 | .ioctls = &ioctls[0], |
789 | .ioctl = av7110_ioctl, | 883 | .ioctl = av7110_ioctl, |
884 | |||
885 | .vbi_fops.open = av7110_vbi_reset, | ||
886 | .vbi_fops.release = av7110_vbi_reset, | ||
887 | .vbi_fops.write = av7110_vbi_write, | ||
790 | }; | 888 | }; |
791 | 889 | ||
792 | static struct saa7146_ext_vv av7110_vv_data_c = { | 890 | static struct saa7146_ext_vv av7110_vv_data_c = { |
793 | .inputs = 1, | 891 | .inputs = 1, |
794 | .audios = 1, | 892 | .audios = 1, |
795 | .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, | 893 | .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT, |
796 | .flags = SAA7146_USE_PORT_B_FOR_VBI, | 894 | .flags = SAA7146_USE_PORT_B_FOR_VBI, |
797 | 895 | ||
798 | .stds = &standard[0], | 896 | .stds = &standard[0], |
@@ -801,5 +899,9 @@ static struct saa7146_ext_vv av7110_vv_data_c = { | |||
801 | 899 | ||
802 | .ioctls = &ioctls[0], | 900 | .ioctls = &ioctls[0], |
803 | .ioctl = av7110_ioctl, | 901 | .ioctl = av7110_ioctl, |
902 | |||
903 | .vbi_fops.open = av7110_vbi_reset, | ||
904 | .vbi_fops.release = av7110_vbi_reset, | ||
905 | .vbi_fops.write = av7110_vbi_write, | ||
804 | }; | 906 | }; |
805 | 907 | ||
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 9f51bae7194c..f9d00452e639 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
@@ -127,7 +127,7 @@ static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int ad | |||
127 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); | 127 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); |
128 | udelay(1); | 128 | udelay(1); |
129 | 129 | ||
130 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 0); | 130 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); |
131 | 131 | ||
132 | if (result == -ETIMEDOUT) | 132 | if (result == -ETIMEDOUT) |
133 | budget_av->slot_status = 0; | 133 | budget_av->slot_status = 0; |
@@ -145,7 +145,7 @@ static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int a | |||
145 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); | 145 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); |
146 | udelay(1); | 146 | udelay(1); |
147 | 147 | ||
148 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 0); | 148 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); |
149 | 149 | ||
150 | if (result == -ETIMEDOUT) | 150 | if (result == -ETIMEDOUT) |
151 | budget_av->slot_status = 0; | 151 | budget_av->slot_status = 0; |
@@ -192,7 +192,7 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) | |||
192 | { | 192 | { |
193 | struct budget_av *budget_av = (struct budget_av *) ca->data; | 193 | struct budget_av *budget_av = (struct budget_av *) ca->data; |
194 | struct saa7146_dev *saa = budget_av->budget.dev; | 194 | struct saa7146_dev *saa = budget_av->budget.dev; |
195 | int timeout = 500; // 5 seconds (4.4.6 Ready) | 195 | int timeout = 50; // 5 seconds (4.4.6 Ready) |
196 | 196 | ||
197 | if (slot != 0) | 197 | if (slot != 0) |
198 | return -EINVAL; | 198 | return -EINVAL; |
@@ -256,19 +256,37 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open | |||
256 | { | 256 | { |
257 | struct budget_av *budget_av = (struct budget_av *) ca->data; | 257 | struct budget_av *budget_av = (struct budget_av *) ca->data; |
258 | struct saa7146_dev *saa = budget_av->budget.dev; | 258 | struct saa7146_dev *saa = budget_av->budget.dev; |
259 | int cam_present = 0; | ||
259 | 260 | ||
260 | if (slot != 0) | 261 | if (slot != 0) |
261 | return -EINVAL; | 262 | return -EINVAL; |
262 | 263 | ||
263 | if (!budget_av->slot_status) { | 264 | if (!budget_av->slot_status) |
265 | { | ||
266 | // first of all test the card detect line | ||
264 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | 267 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); |
265 | udelay(1); | 268 | udelay(1); |
266 | if (saa7146_read(saa, PSR) & MASK_06) | 269 | if (saa7146_read(saa, PSR) & MASK_06) |
267 | { | 270 | { |
271 | cam_present = 1; | ||
272 | } | ||
273 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | ||
274 | |||
275 | // that is unreliable however, so try and read from IO memory | ||
276 | if (!cam_present) | ||
277 | { | ||
278 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | ||
279 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) != -ETIMEDOUT) | ||
280 | { | ||
281 | cam_present = 1; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | // did we find something? | ||
286 | if (cam_present) { | ||
268 | printk(KERN_INFO "budget-av: cam inserted\n"); | 287 | printk(KERN_INFO "budget-av: cam inserted\n"); |
269 | budget_av->slot_status = 1; | 288 | budget_av->slot_status = 1; |
270 | } | 289 | } |
271 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | ||
272 | } else if (!open) { | 290 | } else if (!open) { |
273 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | 291 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); |
274 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) | 292 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) |
@@ -484,6 +502,140 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, | |||
484 | return 0; | 502 | return 0; |
485 | } | 503 | } |
486 | 504 | ||
505 | #define MIN2(a,b) ((a) < (b) ? (a) : (b)) | ||
506 | #define MIN3(a,b,c) MIN2(MIN2(a,b),c) | ||
507 | |||
508 | static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe, | ||
509 | struct i2c_adapter *i2c, | ||
510 | struct dvb_frontend_parameters *params) | ||
511 | { | ||
512 | u8 reg0 [2] = { 0x00, 0x00 }; | ||
513 | u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 }; | ||
514 | u8 reg2 [3] = { 0x02, 0x00, 0x00 }; | ||
515 | int _fband; | ||
516 | int first_ZF; | ||
517 | int R, A, N, P, M; | ||
518 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 }; | ||
519 | int freq = params->frequency; | ||
520 | |||
521 | first_ZF = (freq) / 1000; | ||
522 | |||
523 | if (abs(MIN2(abs(first_ZF-1190),abs(first_ZF-1790))) < | ||
524 | abs(MIN3(abs(first_ZF-1202),abs(first_ZF-1542),abs(first_ZF-1890)))) | ||
525 | _fband = 2; | ||
526 | else | ||
527 | _fband = 3; | ||
528 | |||
529 | if (_fband == 2) { | ||
530 | if (((first_ZF >= 950) && (first_ZF < 1350)) || | ||
531 | ((first_ZF >= 1430) && (first_ZF < 1950))) | ||
532 | reg0[1] = 0x07; | ||
533 | else if (((first_ZF >= 1350) && (first_ZF < 1430)) || | ||
534 | ((first_ZF >= 1950) && (first_ZF < 2150))) | ||
535 | reg0[1] = 0x0B; | ||
536 | } | ||
537 | |||
538 | if(_fband == 3) { | ||
539 | if (((first_ZF >= 950) && (first_ZF < 1350)) || | ||
540 | ((first_ZF >= 1455) && (first_ZF < 1950))) | ||
541 | reg0[1] = 0x07; | ||
542 | else if (((first_ZF >= 1350) && (first_ZF < 1420)) || | ||
543 | ((first_ZF >= 1950) && (first_ZF < 2150))) | ||
544 | reg0[1] = 0x0B; | ||
545 | else if ((first_ZF >= 1420) && (first_ZF < 1455)) | ||
546 | reg0[1] = 0x0F; | ||
547 | } | ||
548 | |||
549 | if (first_ZF > 1525) | ||
550 | reg1[1] |= 0x80; | ||
551 | else | ||
552 | reg1[1] &= 0x7F; | ||
553 | |||
554 | if (_fband == 2) { | ||
555 | if (first_ZF > 1430) { /* 1430MHZ */ | ||
556 | reg1[1] &= 0xCF; /* N2 */ | ||
557 | reg2[1] &= 0xCF; /* R2 */ | ||
558 | reg2[1] |= 0x10; | ||
559 | } else { | ||
560 | reg1[1] &= 0xCF; /* N2 */ | ||
561 | reg1[1] |= 0x20; | ||
562 | reg2[1] &= 0xCF; /* R2 */ | ||
563 | reg2[1] |= 0x10; | ||
564 | } | ||
565 | } | ||
566 | |||
567 | if (_fband == 3) { | ||
568 | if ((first_ZF >= 1455) && | ||
569 | (first_ZF < 1630)) { | ||
570 | reg1[1] &= 0xCF; /* N2 */ | ||
571 | reg1[1] |= 0x20; | ||
572 | reg2[1] &= 0xCF; /* R2 */ | ||
573 | } else { | ||
574 | if (first_ZF < 1455) { | ||
575 | reg1[1] &= 0xCF; /* N2 */ | ||
576 | reg1[1] |= 0x20; | ||
577 | reg2[1] &= 0xCF; /* R2 */ | ||
578 | reg2[1] |= 0x10; | ||
579 | } else { | ||
580 | if (first_ZF >= 1630) { | ||
581 | reg1[1] &= 0xCF; /* N2 */ | ||
582 | reg2[1] &= 0xCF; /* R2 */ | ||
583 | reg2[1] |= 0x10; | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | } | ||
588 | |||
589 | /* set ports, enable P0 for symbol rates > 4Ms/s */ | ||
590 | if (params->u.qpsk.symbol_rate >= 4000000) | ||
591 | reg1[1] |= 0x0c; | ||
592 | else | ||
593 | reg1[1] |= 0x04; | ||
594 | |||
595 | reg2[1] |= 0x0c; | ||
596 | |||
597 | R = 64; | ||
598 | A = 64; | ||
599 | P = 64; //32 | ||
600 | |||
601 | M = (freq * R) / 4; /* in Mhz */ | ||
602 | N = (M - A * 1000) / (P * 1000); | ||
603 | |||
604 | reg1[1] |= (N >> 9) & 0x03; | ||
605 | reg1[2] = (N >> 1) & 0xff; | ||
606 | reg1[3] = (N << 7) & 0x80; | ||
607 | |||
608 | reg2[1] |= (R >> 8) & 0x03; | ||
609 | reg2[2] = R & 0xFF; /* R */ | ||
610 | |||
611 | reg1[3] |= A & 0x7f; /* A */ | ||
612 | |||
613 | if (P == 64) | ||
614 | reg1[1] |= 0x40; /* Prescaler 64/65 */ | ||
615 | |||
616 | reg0[1] |= 0x03; | ||
617 | |||
618 | /* already enabled - do not reenable i2c repeater or TX fails */ | ||
619 | msg.buf = reg0; | ||
620 | msg.len = sizeof(reg0); | ||
621 | if (i2c_transfer(i2c, &msg, 1) != 1) | ||
622 | return -EIO; | ||
623 | |||
624 | stv0299_enable_plli2c(fe); | ||
625 | msg.buf = reg1; | ||
626 | msg.len = sizeof(reg1); | ||
627 | if (i2c_transfer(i2c, &msg, 1) != 1) | ||
628 | return -EIO; | ||
629 | |||
630 | stv0299_enable_plli2c(fe); | ||
631 | msg.buf = reg2; | ||
632 | msg.len = sizeof(reg2); | ||
633 | if (i2c_transfer(i2c, &msg, 1) != 1) | ||
634 | return -EIO; | ||
635 | |||
636 | return 0; | ||
637 | } | ||
638 | |||
487 | static u8 typhoon_cinergy1200s_inittab[] = { | 639 | static u8 typhoon_cinergy1200s_inittab[] = { |
488 | 0x01, 0x15, | 640 | 0x01, 0x15, |
489 | 0x02, 0x30, | 641 | 0x02, 0x30, |
@@ -553,6 +705,18 @@ static struct stv0299_config cinergy_1200s_config = { | |||
553 | .pll_set = philips_su1278_ty_ci_pll_set, | 705 | .pll_set = philips_su1278_ty_ci_pll_set, |
554 | }; | 706 | }; |
555 | 707 | ||
708 | static struct stv0299_config cinergy_1200s_1894_0010_config = { | ||
709 | .demod_address = 0x68, | ||
710 | .inittab = typhoon_cinergy1200s_inittab, | ||
711 | .mclk = 88000000UL, | ||
712 | .invert = 1, | ||
713 | .skip_reinit = 0, | ||
714 | .lock_output = STV0229_LOCKOUTPUT_1, | ||
715 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | ||
716 | .min_delay_ms = 100, | ||
717 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | ||
718 | .pll_set = philips_su1278sh2_tua6100_pll_set, | ||
719 | }; | ||
556 | 720 | ||
557 | static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 721 | static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
558 | { | 722 | { |
@@ -749,6 +913,15 @@ static void frontend_init(struct budget_av *budget_av) | |||
749 | switch (saa->pci->subsystem_device) { | 913 | switch (saa->pci->subsystem_device) { |
750 | 914 | ||
751 | case SUBID_DVBS_KNC1: | 915 | case SUBID_DVBS_KNC1: |
916 | if (saa->pci->subsystem_vendor == 0x1894) { | ||
917 | fe = stv0299_attach(&cinergy_1200s_1894_0010_config, | ||
918 | &budget_av->budget.i2c_adap); | ||
919 | } else { | ||
920 | fe = stv0299_attach(&typhoon_config, | ||
921 | &budget_av->budget.i2c_adap); | ||
922 | } | ||
923 | break; | ||
924 | |||
752 | case SUBID_DVBS_KNC1_PLUS: | 925 | case SUBID_DVBS_KNC1_PLUS: |
753 | case SUBID_DVBS_TYPHOON: | 926 | case SUBID_DVBS_TYPHOON: |
754 | fe = stv0299_attach(&typhoon_config, | 927 | fe = stv0299_attach(&typhoon_config, |
@@ -1003,6 +1176,7 @@ MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); | |||
1003 | static struct pci_device_id pci_tbl[] = { | 1176 | static struct pci_device_id pci_tbl[] = { |
1004 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), | 1177 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), |
1005 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), | 1178 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), |
1179 | MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010), | ||
1006 | MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), | 1180 | MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), |
1007 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), | 1181 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), |
1008 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), | 1182 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), |
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index 017fcbccb8cc..633e68c341c8 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c | |||
@@ -404,9 +404,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, | |||
404 | tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget); | 404 | tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget); |
405 | 405 | ||
406 | /* frontend power on */ | 406 | /* frontend power on */ |
407 | if (bi->type == BUDGET_FS_ACTIVY) | 407 | if (bi->type != BUDGET_FS_ACTIVY) |
408 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); | ||
409 | else | ||
410 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); | 408 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); |
411 | 409 | ||
412 | if (budget_register(budget) == 0) { | 410 | if (budget_register(budget) == 0) { |
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index fafe6407b3d0..238c77b52f89 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c | |||
@@ -112,6 +112,7 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long | |||
112 | * Routines for the Fujitsu Siemens Activy budget card | 112 | * Routines for the Fujitsu Siemens Activy budget card |
113 | * 22 kHz tone and DiSEqC are handled by the frontend. | 113 | * 22 kHz tone and DiSEqC are handled by the frontend. |
114 | * Voltage must be set here. | 114 | * Voltage must be set here. |
115 | * GPIO 1: LNBP EN, GPIO 2: LNBP VSEL | ||
115 | */ | 116 | */ |
116 | static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) | 117 | static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) |
117 | { | 118 | { |
@@ -121,11 +122,16 @@ static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) | |||
121 | 122 | ||
122 | switch (voltage) { | 123 | switch (voltage) { |
123 | case SEC_VOLTAGE_13: | 124 | case SEC_VOLTAGE_13: |
125 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); | ||
124 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); | 126 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); |
125 | break; | 127 | break; |
126 | case SEC_VOLTAGE_18: | 128 | case SEC_VOLTAGE_18: |
129 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); | ||
127 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); | 130 | saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); |
128 | break; | 131 | break; |
132 | case SEC_VOLTAGE_OFF: | ||
133 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); | ||
134 | break; | ||
129 | default: | 135 | default: |
130 | return -EINVAL; | 136 | return -EINVAL; |
131 | } | 137 | } |
@@ -206,7 +212,7 @@ static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | |||
206 | return 0; | 212 | return 0; |
207 | } | 213 | } |
208 | 214 | ||
209 | static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg) | 215 | static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, long arg) |
210 | { | 216 | { |
211 | struct budget* budget = (struct budget*) fe->dvb->priv; | 217 | struct budget* budget = (struct budget*) fe->dvb->priv; |
212 | u8 buf; | 218 | u8 buf; |
@@ -580,6 +586,7 @@ static void frontend_init(struct budget *budget) | |||
580 | if (budget->dvb_frontend) { | 586 | if (budget->dvb_frontend) { |
581 | budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; | 587 | budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; |
582 | budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | 588 | budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; |
589 | budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; | ||
583 | if (lnbp21_init(budget)) { | 590 | if (lnbp21_init(budget)) { |
584 | printk("%s: No LNBP21 found!\n", __FUNCTION__); | 591 | printk("%s: No LNBP21 found!\n", __FUNCTION__); |
585 | goto error_out; | 592 | goto error_out; |
@@ -624,7 +631,7 @@ static void frontend_init(struct budget *budget) | |||
624 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); | 631 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); |
625 | if (budget->dvb_frontend) { | 632 | if (budget->dvb_frontend) { |
626 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; | 633 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; |
627 | break; | 634 | budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; |
628 | } | 635 | } |
629 | break; | 636 | break; |
630 | 637 | ||
@@ -632,7 +639,7 @@ static void frontend_init(struct budget *budget) | |||
632 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); | 639 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); |
633 | if (budget->dvb_frontend) { | 640 | if (budget->dvb_frontend) { |
634 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; | 641 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; |
635 | break; | 642 | budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; |
636 | } | 643 | } |
637 | break; | 644 | break; |
638 | 645 | ||
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/dvb/ttpci/ttpci-eeprom.c index 18aa22b5478d..1f31e91195b0 100644 --- a/drivers/media/dvb/ttpci/ttpci-eeprom.c +++ b/drivers/media/dvb/ttpci/ttpci-eeprom.c | |||
@@ -13,7 +13,7 @@ | |||
13 | Holger Waechtler Convergence | 13 | Holger Waechtler Convergence |
14 | 14 | ||
15 | Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de> | 15 | Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de> |
16 | Metzler Brothers Systementwicklung GbR | 16 | Metzler Brothers Systementwicklung GbR |
17 | 17 | ||
18 | This program is free software; you can redistribute it and/or modify | 18 | This program is free software; you can redistribute it and/or modify |
19 | it under the terms of the GNU General Public License as published by | 19 | it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig index c6c1d41a2efb..914587d52b57 100644 --- a/drivers/media/dvb/ttusb-budget/Kconfig +++ b/drivers/media/dvb/ttusb-budget/Kconfig | |||
@@ -10,7 +10,7 @@ config DVB_TTUSB_BUDGET | |||
10 | Support for external USB adapters designed by Technotrend and | 10 | Support for external USB adapters designed by Technotrend and |
11 | produced by Hauppauge, shipped under the brand name 'Nova-USB'. | 11 | produced by Hauppauge, shipped under the brand name 'Nova-USB'. |
12 | 12 | ||
13 | These devices don't have a MPEG decoder built in, so you need | 13 | These devices don't have a MPEG decoder built in, so you need |
14 | an external software decoder to watch TV. | 14 | an external software decoder to watch TV. |
15 | 15 | ||
16 | Say Y if you own such a device and want to use it. | 16 | Say Y if you own such a device and want to use it. |
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig index c334526af66f..83611012ef34 100644 --- a/drivers/media/dvb/ttusb-dec/Kconfig +++ b/drivers/media/dvb/ttusb-dec/Kconfig | |||
@@ -8,14 +8,15 @@ config DVB_TTUSB_DEC | |||
8 | produced by Hauppauge, shipped under the brand name 'DEC2000-t' | 8 | produced by Hauppauge, shipped under the brand name 'DEC2000-t' |
9 | and 'DEC3000-s'. | 9 | and 'DEC3000-s'. |
10 | 10 | ||
11 | Even if these devices have a MPEG decoder built in, they transmit | 11 | Even if these devices have a MPEG decoder built in, they transmit |
12 | only compressed MPEG data over the USB bus, so you need | 12 | only compressed MPEG data over the USB bus, so you need |
13 | an external software decoder to watch TV on your computer. | 13 | an external software decoder to watch TV on your computer. |
14 | 14 | ||
15 | This driver needs external firmware. Please use the commands | 15 | This driver needs external firmware. Please use the commands |
16 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t", | 16 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t", |
17 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t", | 17 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t", |
18 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s", | 18 | "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s", |
19 | download/extract them, and then copy them to /usr/lib/hotplug/firmware. | 19 | download/extract them, and then copy them to /usr/lib/hotplug/firmware |
20 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
20 | 21 | ||
21 | Say Y if you own such a device and want to use it. | 22 | Say Y if you own such a device and want to use it. |
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 8abc21890129..d8966d1d25ee 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c | |||
@@ -369,7 +369,7 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, | |||
369 | 369 | ||
370 | static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) | 370 | static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) |
371 | { | 371 | { |
372 | struct ttusb_dec *dec = (struct ttusb_dec *)priv; | 372 | struct ttusb_dec *dec = priv; |
373 | 373 | ||
374 | dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, | 374 | dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, |
375 | &dec->audio_filter->feed->feed.ts, | 375 | &dec->audio_filter->feed->feed.ts, |
@@ -380,7 +380,7 @@ static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) | |||
380 | 380 | ||
381 | static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data) | 381 | static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data) |
382 | { | 382 | { |
383 | struct ttusb_dec *dec = (struct ttusb_dec *)priv; | 383 | struct ttusb_dec *dec = priv; |
384 | 384 | ||
385 | dec->video_filter->feed->cb.ts(data, 188, NULL, 0, | 385 | dec->video_filter->feed->cb.ts(data, 188, NULL, 0, |
386 | &dec->video_filter->feed->feed.ts, | 386 | &dec->video_filter->feed->feed.ts, |
@@ -965,8 +965,8 @@ static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
965 | 965 | ||
966 | case DMX_TS_PES_TELETEXT: | 966 | case DMX_TS_PES_TELETEXT: |
967 | dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid; | 967 | dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid; |
968 | dprintk(" pes_type: DMX_TS_PES_TELETEXT\n"); | 968 | dprintk(" pes_type: DMX_TS_PES_TELETEXT(not supported)\n"); |
969 | break; | 969 | return -ENOSYS; |
970 | 970 | ||
971 | case DMX_TS_PES_PCR: | 971 | case DMX_TS_PES_PCR: |
972 | dprintk(" pes_type: DMX_TS_PES_PCR\n"); | 972 | dprintk(" pes_type: DMX_TS_PES_PCR\n"); |
@@ -975,8 +975,8 @@ static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
975 | break; | 975 | break; |
976 | 976 | ||
977 | case DMX_TS_PES_OTHER: | 977 | case DMX_TS_PES_OTHER: |
978 | dprintk(" pes_type: DMX_TS_PES_OTHER\n"); | 978 | dprintk(" pes_type: DMX_TS_PES_OTHER(not supported)\n"); |
979 | break; | 979 | return -ENOSYS; |
980 | 980 | ||
981 | default: | 981 | default: |
982 | dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type); | 982 | dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type); |
@@ -1182,7 +1182,7 @@ static void ttusb_dec_init_tasklet(struct ttusb_dec *dec) | |||
1182 | (unsigned long)dec); | 1182 | (unsigned long)dec); |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | static int ttusb_init_rc(struct ttusb_dec *dec) | 1185 | static int ttusb_init_rc( struct ttusb_dec *dec) |
1186 | { | 1186 | { |
1187 | struct input_dev *input_dev; | 1187 | struct input_dev *input_dev; |
1188 | u8 b[] = { 0x00, 0x01 }; | 1188 | u8 b[] = { 0x00, 0x01 }; |
@@ -1203,13 +1203,12 @@ static int ttusb_init_rc(struct ttusb_dec *dec) | |||
1203 | input_dev->keycode = rc_keys; | 1203 | input_dev->keycode = rc_keys; |
1204 | 1204 | ||
1205 | for (i = 0; i < ARRAY_SIZE(rc_keys); i++) | 1205 | for (i = 0; i < ARRAY_SIZE(rc_keys); i++) |
1206 | set_bit(rc_keys[i], input_dev->keybit); | 1206 | set_bit(rc_keys[i], input_dev->keybit); |
1207 | 1207 | ||
1208 | input_register_device(input_dev); | 1208 | input_register_device(input_dev); |
1209 | 1209 | ||
1210 | if (usb_submit_urb(dec->irq_urb, GFP_KERNEL)) | 1210 | if (usb_submit_urb(dec->irq_urb, GFP_KERNEL)) |
1211 | printk("%s: usb_submit_urb failed\n",__FUNCTION__); | 1211 | printk("%s: usb_submit_urb failed\n",__FUNCTION__); |
1212 | |||
1213 | /* enable irq pipe */ | 1212 | /* enable irq pipe */ |
1214 | ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL); | 1213 | ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL); |
1215 | 1214 | ||
@@ -1395,6 +1394,7 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) | |||
1395 | /* We can't trust the USB IDs that some firmwares | 1394 | /* We can't trust the USB IDs that some firmwares |
1396 | give the box */ | 1395 | give the box */ |
1397 | switch (model) { | 1396 | switch (model) { |
1397 | case 0x00070001: | ||
1398 | case 0x00070008: | 1398 | case 0x00070008: |
1399 | case 0x0007000c: | 1399 | case 0x0007000c: |
1400 | ttusb_dec_set_model(dec, TTUSB_DEC3000S); | 1400 | ttusb_dec_set_model(dec, TTUSB_DEC3000S); |
@@ -1588,7 +1588,7 @@ static int fe_send_command(struct dvb_frontend* fe, const u8 command, | |||
1588 | int param_length, const u8 params[], | 1588 | int param_length, const u8 params[], |
1589 | int *result_length, u8 cmd_result[]) | 1589 | int *result_length, u8 cmd_result[]) |
1590 | { | 1590 | { |
1591 | struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv; | 1591 | struct ttusb_dec* dec = fe->dvb->priv; |
1592 | return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); | 1592 | return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); |
1593 | } | 1593 | } |
1594 | 1594 | ||
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index 725af3af5b27..a5a46175fa09 100644 --- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c | |||
@@ -42,8 +42,39 @@ struct ttusbdecfe_state { | |||
42 | 42 | ||
43 | static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status) | 43 | static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status) |
44 | { | 44 | { |
45 | *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | | 45 | struct ttusbdecfe_state* state = fe->demodulator_priv; |
46 | FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; | 46 | u8 b[] = { 0x00, 0x00, 0x00, 0x00, |
47 | 0x00, 0x00, 0x00, 0x00 }; | ||
48 | u8 result[4]; | ||
49 | int len, ret; | ||
50 | |||
51 | *status=0; | ||
52 | |||
53 | ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result); | ||
54 | if(ret) | ||
55 | return ret; | ||
56 | |||
57 | if(len != 4) { | ||
58 | printk(KERN_ERR "%s: unexpected reply\n", __FUNCTION__); | ||
59 | return -EIO; | ||
60 | } | ||
61 | |||
62 | switch(result[3]) { | ||
63 | case 1: /* not tuned yet */ | ||
64 | case 2: /* no signal/no lock*/ | ||
65 | break; | ||
66 | case 3: /* signal found and locked*/ | ||
67 | *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | | ||
68 | FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; | ||
69 | break; | ||
70 | case 4: | ||
71 | *status = FE_TIMEDOUT; | ||
72 | break; | ||
73 | default: | ||
74 | pr_info("%s: returned unknown value: %d\n", | ||
75 | __FUNCTION__, result[3]); | ||
76 | return -EIO; | ||
77 | } | ||
47 | 78 | ||
48 | return 0; | 79 | return 0; |
49 | } | 80 | } |
@@ -64,6 +95,16 @@ static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_fron | |||
64 | return 0; | 95 | return 0; |
65 | } | 96 | } |
66 | 97 | ||
98 | static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe, | ||
99 | struct dvb_frontend_tune_settings* fesettings) | ||
100 | { | ||
101 | fesettings->min_delay_ms = 1500; | ||
102 | /* Drift compensation makes no sense for DVB-T */ | ||
103 | fesettings->step_size = 0; | ||
104 | fesettings->max_drift = 0; | ||
105 | return 0; | ||
106 | } | ||
107 | |||
67 | static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 108 | static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
68 | { | 109 | { |
69 | struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; | 110 | struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; |
@@ -212,6 +253,8 @@ static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { | |||
212 | 253 | ||
213 | .set_frontend = ttusbdecfe_dvbt_set_frontend, | 254 | .set_frontend = ttusbdecfe_dvbt_set_frontend, |
214 | 255 | ||
256 | .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings, | ||
257 | |||
215 | .read_status = ttusbdecfe_read_status, | 258 | .read_status = ttusbdecfe_read_status, |
216 | }; | 259 | }; |
217 | 260 | ||
@@ -223,11 +266,11 @@ static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { | |||
223 | .frequency_min = 950000, | 266 | .frequency_min = 950000, |
224 | .frequency_max = 2150000, | 267 | .frequency_max = 2150000, |
225 | .frequency_stepsize = 125, | 268 | .frequency_stepsize = 125, |
269 | .symbol_rate_min = 1000000, /* guessed */ | ||
270 | .symbol_rate_max = 45000000, /* guessed */ | ||
226 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | 271 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
227 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | 272 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
228 | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | | 273 | FE_CAN_QPSK |
229 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | | ||
230 | FE_CAN_HIERARCHY_AUTO, | ||
231 | }, | 274 | }, |
232 | 275 | ||
233 | .release = ttusbdecfe_release, | 276 | .release = ttusbdecfe_release, |