diff options
Diffstat (limited to 'drivers/media/dvb/frontends/tda1004x.c')
-rw-r--r-- | drivers/media/dvb/frontends/tda1004x.c | 284 |
1 files changed, 160 insertions, 124 deletions
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index 687ad9cf3384..0beb370792ae 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
@@ -35,9 +35,10 @@ | |||
35 | #include "dvb_frontend.h" | 35 | #include "dvb_frontend.h" |
36 | #include "tda1004x.h" | 36 | #include "tda1004x.h" |
37 | 37 | ||
38 | #define TDA1004X_DEMOD_TDA10045 0 | 38 | enum tda1004x_demod { |
39 | #define TDA1004X_DEMOD_TDA10046 1 | 39 | TDA1004X_DEMOD_TDA10045, |
40 | 40 | TDA1004X_DEMOD_TDA10046, | |
41 | }; | ||
41 | 42 | ||
42 | struct tda1004x_state { | 43 | struct tda1004x_state { |
43 | struct i2c_adapter* i2c; | 44 | struct i2c_adapter* i2c; |
@@ -46,8 +47,9 @@ struct tda1004x_state { | |||
46 | struct dvb_frontend frontend; | 47 | struct dvb_frontend frontend; |
47 | 48 | ||
48 | /* private demod data */ | 49 | /* private demod data */ |
49 | u8 initialised:1; | 50 | u8 initialised; |
50 | u8 demod_type; | 51 | enum tda1004x_demod demod_type; |
52 | u8 fw_version; | ||
51 | }; | 53 | }; |
52 | 54 | ||
53 | 55 | ||
@@ -139,7 +141,7 @@ static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data) | |||
139 | { | 141 | { |
140 | int ret; | 142 | int ret; |
141 | u8 buf[] = { reg, data }; | 143 | u8 buf[] = { reg, data }; |
142 | struct i2c_msg msg = { .addr=0, .flags=0, .buf=buf, .len=2 }; | 144 | struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; |
143 | 145 | ||
144 | dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data); | 146 | dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data); |
145 | 147 | ||
@@ -160,8 +162,8 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg) | |||
160 | int ret; | 162 | int ret; |
161 | u8 b0[] = { reg }; | 163 | u8 b0[] = { reg }; |
162 | u8 b1[] = { 0 }; | 164 | u8 b1[] = { 0 }; |
163 | struct i2c_msg msg[] = {{ .addr=0, .flags=0, .buf=b0, .len=1}, | 165 | struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 }, |
164 | { .addr=0, .flags=I2C_M_RD, .buf=b1, .len = 1}}; | 166 | { .flags = I2C_M_RD, .buf = b1, .len = 1 }}; |
165 | 167 | ||
166 | dprintk("%s: reg=0x%x\n", __FUNCTION__, reg); | 168 | dprintk("%s: reg=0x%x\n", __FUNCTION__, reg); |
167 | 169 | ||
@@ -294,7 +296,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state, | |||
294 | u8 dspCodeCounterReg, u8 dspCodeInReg) | 296 | u8 dspCodeCounterReg, u8 dspCodeInReg) |
295 | { | 297 | { |
296 | u8 buf[65]; | 298 | u8 buf[65]; |
297 | struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = buf,.len = 0 }; | 299 | struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 }; |
298 | int tx_size; | 300 | int tx_size; |
299 | int pos = 0; | 301 | int pos = 0; |
300 | 302 | ||
@@ -304,12 +306,10 @@ static int tda1004x_do_upload(struct tda1004x_state *state, | |||
304 | 306 | ||
305 | buf[0] = dspCodeInReg; | 307 | buf[0] = dspCodeInReg; |
306 | while (pos != len) { | 308 | while (pos != len) { |
307 | |||
308 | // work out how much to send this time | 309 | // work out how much to send this time |
309 | tx_size = len - pos; | 310 | tx_size = len - pos; |
310 | if (tx_size > 0x10) { | 311 | if (tx_size > 0x10) |
311 | tx_size = 0x10; | 312 | tx_size = 0x10; |
312 | } | ||
313 | 313 | ||
314 | // send the chunk | 314 | // send the chunk |
315 | memcpy(buf + 1, mem + pos, tx_size); | 315 | memcpy(buf + 1, mem + pos, tx_size); |
@@ -322,6 +322,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state, | |||
322 | 322 | ||
323 | dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos); | 323 | dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos); |
324 | } | 324 | } |
325 | |||
325 | return 0; | 326 | return 0; |
326 | } | 327 | } |
327 | 328 | ||
@@ -335,9 +336,8 @@ static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion) | |||
335 | 336 | ||
336 | data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1); | 337 | data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1); |
337 | data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2); | 338 | data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2); |
338 | if (data1 != 0x67 || data2 != dspVersion) { | 339 | if ((data1 != 0x67) || (data2 != dspVersion)) |
339 | return -EIO; | 340 | return -EIO; |
340 | } | ||
341 | 341 | ||
342 | return 0; | 342 | return 0; |
343 | } | 343 | } |
@@ -348,9 +348,9 @@ static int tda10045_fwupload(struct dvb_frontend* fe) | |||
348 | int ret; | 348 | int ret; |
349 | const struct firmware *fw; | 349 | const struct firmware *fw; |
350 | 350 | ||
351 | |||
352 | /* don't re-upload unless necessary */ | 351 | /* don't re-upload unless necessary */ |
353 | if (tda1004x_check_upload_ok(state, 0x2c) == 0) return 0; | 352 | if (tda1004x_check_upload_ok(state, 0x2c) == 0) |
353 | return 0; | ||
354 | 354 | ||
355 | /* request the firmware, this will block until someone uploads it */ | 355 | /* request the firmware, this will block until someone uploads it */ |
356 | printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); | 356 | printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); |
@@ -381,6 +381,25 @@ static int tda10045_fwupload(struct dvb_frontend* fe) | |||
381 | return tda1004x_check_upload_ok(state, 0x2c); | 381 | return tda1004x_check_upload_ok(state, 0x2c); |
382 | } | 382 | } |
383 | 383 | ||
384 | static int tda10046_get_fw_version(struct tda1004x_state *state, | ||
385 | const struct firmware *fw) | ||
386 | { | ||
387 | const unsigned char pattern[] = { 0x67, 0x00, 0x50, 0x62, 0x5e, 0x18, 0x67 }; | ||
388 | unsigned int i; | ||
389 | |||
390 | /* area guessed from firmware v20, v21 and v25 */ | ||
391 | for (i = 0x660; i < 0x700; i++) { | ||
392 | if (!memcmp(&fw->data[i], pattern, sizeof(pattern))) { | ||
393 | state->fw_version = fw->data[i + sizeof(pattern)]; | ||
394 | printk(KERN_INFO "tda1004x: using firmware v%02x\n", | ||
395 | state->fw_version); | ||
396 | return 0; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | return -EINVAL; | ||
401 | } | ||
402 | |||
384 | static int tda10046_fwupload(struct dvb_frontend* fe) | 403 | static int tda10046_fwupload(struct dvb_frontend* fe) |
385 | { | 404 | { |
386 | struct tda1004x_state* state = fe->demodulator_priv; | 405 | struct tda1004x_state* state = fe->demodulator_priv; |
@@ -394,7 +413,8 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
394 | msleep(100); | 413 | msleep(100); |
395 | 414 | ||
396 | /* don't re-upload unless necessary */ | 415 | /* don't re-upload unless necessary */ |
397 | if (tda1004x_check_upload_ok(state, 0x20) == 0) return 0; | 416 | if (tda1004x_check_upload_ok(state, state->fw_version) == 0) |
417 | return 0; | ||
398 | 418 | ||
399 | /* request the firmware, this will block until someone uploads it */ | 419 | /* request the firmware, this will block until someone uploads it */ |
400 | printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE); | 420 | printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE); |
@@ -404,9 +424,20 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
404 | return ret; | 424 | return ret; |
405 | } | 425 | } |
406 | 426 | ||
427 | if (fw->size < 24478) { /* size of firmware v20, which is the smallest of v20, v21 and v25 */ | ||
428 | printk("tda1004x: firmware file seems to be too small (%d bytes)\n", fw->size); | ||
429 | return -EINVAL; | ||
430 | } | ||
431 | |||
432 | ret = tda10046_get_fw_version(state, fw); | ||
433 | if (ret < 0) { | ||
434 | printk("tda1004x: unable to find firmware version\n"); | ||
435 | return ret; | ||
436 | } | ||
437 | |||
407 | /* set parameters */ | 438 | /* set parameters */ |
408 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); | 439 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); |
409 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); | 440 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c); |
410 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); | 441 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); |
411 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); | 442 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); |
412 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); | 443 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); |
@@ -419,7 +450,7 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
419 | 450 | ||
420 | /* wait for DSP to initialise */ | 451 | /* wait for DSP to initialise */ |
421 | timeout = jiffies + HZ; | 452 | timeout = jiffies + HZ; |
422 | while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) { | 453 | while (!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) { |
423 | if (time_after(jiffies, timeout)) { | 454 | if (time_after(jiffies, timeout)) { |
424 | printk("tda1004x: DSP failed to initialised.\n"); | 455 | printk("tda1004x: DSP failed to initialised.\n"); |
425 | return -EIO; | 456 | return -EIO; |
@@ -427,7 +458,7 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
427 | msleep(1); | 458 | msleep(1); |
428 | } | 459 | } |
429 | 460 | ||
430 | return tda1004x_check_upload_ok(state, 0x20); | 461 | return tda1004x_check_upload_ok(state, state->fw_version); |
431 | } | 462 | } |
432 | 463 | ||
433 | static int tda1004x_encode_fec(int fec) | 464 | static int tda1004x_encode_fec(int fec) |
@@ -483,7 +514,8 @@ static int tda10045_init(struct dvb_frontend* fe) | |||
483 | 514 | ||
484 | dprintk("%s\n", __FUNCTION__); | 515 | dprintk("%s\n", __FUNCTION__); |
485 | 516 | ||
486 | if (state->initialised) return 0; | 517 | if (state->initialised) |
518 | return 0; | ||
487 | 519 | ||
488 | if (tda10045_fwupload(fe)) { | 520 | if (tda10045_fwupload(fe)) { |
489 | printk("tda1004x: firmware upload failed\n"); | 521 | printk("tda1004x: firmware upload failed\n"); |
@@ -523,7 +555,8 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
523 | struct tda1004x_state* state = fe->demodulator_priv; | 555 | struct tda1004x_state* state = fe->demodulator_priv; |
524 | dprintk("%s\n", __FUNCTION__); | 556 | dprintk("%s\n", __FUNCTION__); |
525 | 557 | ||
526 | if (state->initialised) return 0; | 558 | if (state->initialised) |
559 | return 0; | ||
527 | 560 | ||
528 | if (tda10046_fwupload(fe)) { | 561 | if (tda10046_fwupload(fe)) { |
529 | printk("tda1004x: firmware upload failed\n"); | 562 | printk("tda1004x: firmware upload failed\n"); |
@@ -545,7 +578,7 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
545 | tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream | 578 | tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream |
546 | tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer | 579 | tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer |
547 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10 | 580 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10 |
548 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 | 581 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c); // PLL P = N = 0 |
549 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99 | 582 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99 |
550 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221 | 583 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221 |
551 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // } | 584 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // } |
@@ -621,12 +654,14 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
621 | 654 | ||
622 | // set HP FEC | 655 | // set HP FEC |
623 | tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP); | 656 | tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP); |
624 | if (tmp < 0) return tmp; | 657 | if (tmp < 0) |
658 | return tmp; | ||
625 | tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp); | 659 | tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp); |
626 | 660 | ||
627 | // set LP FEC | 661 | // set LP FEC |
628 | tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP); | 662 | tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP); |
629 | if (tmp < 0) return tmp; | 663 | if (tmp < 0) |
664 | return tmp; | ||
630 | tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3); | 665 | tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3); |
631 | 666 | ||
632 | // set constellation | 667 | // set constellation |
@@ -671,7 +706,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
671 | } | 706 | } |
672 | 707 | ||
673 | // set bandwidth | 708 | // set bandwidth |
674 | switch(state->demod_type) { | 709 | switch (state->demod_type) { |
675 | case TDA1004X_DEMOD_TDA10045: | 710 | case TDA1004X_DEMOD_TDA10045: |
676 | tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth); | 711 | tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth); |
677 | break; | 712 | break; |
@@ -683,7 +718,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
683 | 718 | ||
684 | // set inversion | 719 | // set inversion |
685 | inversion = fe_params->inversion; | 720 | inversion = fe_params->inversion; |
686 | if (state->config->invert) inversion = inversion ? INVERSION_OFF : INVERSION_ON; | 721 | if (state->config->invert) |
722 | inversion = inversion ? INVERSION_OFF : INVERSION_ON; | ||
687 | switch (inversion) { | 723 | switch (inversion) { |
688 | case INVERSION_OFF: | 724 | case INVERSION_OFF: |
689 | tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0); | 725 | tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0); |
@@ -750,19 +786,19 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
750 | } | 786 | } |
751 | 787 | ||
752 | // start the lock | 788 | // start the lock |
753 | switch(state->demod_type) { | 789 | switch (state->demod_type) { |
754 | case TDA1004X_DEMOD_TDA10045: | 790 | case TDA1004X_DEMOD_TDA10045: |
755 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); | 791 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); |
756 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0); | 792 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0); |
757 | msleep(10); | ||
758 | break; | 793 | break; |
759 | 794 | ||
760 | case TDA1004X_DEMOD_TDA10046: | 795 | case TDA1004X_DEMOD_TDA10046: |
761 | tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); | 796 | tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); |
762 | msleep(10); | ||
763 | break; | 797 | break; |
764 | } | 798 | } |
765 | 799 | ||
800 | msleep(10); | ||
801 | |||
766 | return 0; | 802 | return 0; |
767 | } | 803 | } |
768 | 804 | ||
@@ -773,13 +809,13 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
773 | 809 | ||
774 | // inversion status | 810 | // inversion status |
775 | fe_params->inversion = INVERSION_OFF; | 811 | fe_params->inversion = INVERSION_OFF; |
776 | if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) { | 812 | if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) |
777 | fe_params->inversion = INVERSION_ON; | 813 | fe_params->inversion = INVERSION_ON; |
778 | } | 814 | if (state->config->invert) |
779 | if (state->config->invert) fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON; | 815 | fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON; |
780 | 816 | ||
781 | // bandwidth | 817 | // bandwidth |
782 | switch(state->demod_type) { | 818 | switch (state->demod_type) { |
783 | case TDA1004X_DEMOD_TDA10045: | 819 | case TDA1004X_DEMOD_TDA10045: |
784 | switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) { | 820 | switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) { |
785 | case 0x14: | 821 | case 0x14: |
@@ -830,9 +866,8 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
830 | 866 | ||
831 | // transmission mode | 867 | // transmission mode |
832 | fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; | 868 | fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; |
833 | if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) { | 869 | if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) |
834 | fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; | 870 | fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; |
835 | } | ||
836 | 871 | ||
837 | // guard interval | 872 | // guard interval |
838 | switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) { | 873 | switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) { |
@@ -880,30 +915,33 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status | |||
880 | 915 | ||
881 | // read status | 916 | // read status |
882 | status = tda1004x_read_byte(state, TDA1004X_STATUS_CD); | 917 | status = tda1004x_read_byte(state, TDA1004X_STATUS_CD); |
883 | if (status == -1) { | 918 | if (status == -1) |
884 | return -EIO; | 919 | return -EIO; |
885 | } | ||
886 | 920 | ||
887 | // decode | 921 | // decode |
888 | *fe_status = 0; | 922 | *fe_status = 0; |
889 | if (status & 4) *fe_status |= FE_HAS_SIGNAL; | 923 | if (status & 4) |
890 | if (status & 2) *fe_status |= FE_HAS_CARRIER; | 924 | *fe_status |= FE_HAS_SIGNAL; |
891 | if (status & 8) *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | 925 | if (status & 2) |
926 | *fe_status |= FE_HAS_CARRIER; | ||
927 | if (status & 8) | ||
928 | *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | ||
892 | 929 | ||
893 | // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi | 930 | // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi |
894 | // is getting anything valid | 931 | // is getting anything valid |
895 | if (!(*fe_status & FE_HAS_VITERBI)) { | 932 | if (!(*fe_status & FE_HAS_VITERBI)) { |
896 | // read the CBER | 933 | // read the CBER |
897 | cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB); | 934 | cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB); |
898 | if (cber == -1) return -EIO; | 935 | if (cber == -1) |
936 | return -EIO; | ||
899 | status = tda1004x_read_byte(state, TDA1004X_CBER_MSB); | 937 | status = tda1004x_read_byte(state, TDA1004X_CBER_MSB); |
900 | if (status == -1) return -EIO; | 938 | if (status == -1) |
939 | return -EIO; | ||
901 | cber |= (status << 8); | 940 | cber |= (status << 8); |
902 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); | 941 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); |
903 | 942 | ||
904 | if (cber != 65535) { | 943 | if (cber != 65535) |
905 | *fe_status |= FE_HAS_VITERBI; | 944 | *fe_status |= FE_HAS_VITERBI; |
906 | } | ||
907 | } | 945 | } |
908 | 946 | ||
909 | // if we DO have some valid VITERBI output, but don't already have SYNC | 947 | // if we DO have some valid VITERBI output, but don't already have SYNC |
@@ -911,20 +949,22 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status | |||
911 | if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) { | 949 | if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) { |
912 | // read the VBER | 950 | // read the VBER |
913 | vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB); | 951 | vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB); |
914 | if (vber == -1) return -EIO; | 952 | if (vber == -1) |
953 | return -EIO; | ||
915 | status = tda1004x_read_byte(state, TDA1004X_VBER_MID); | 954 | status = tda1004x_read_byte(state, TDA1004X_VBER_MID); |
916 | if (status == -1) return -EIO; | 955 | if (status == -1) |
956 | return -EIO; | ||
917 | vber |= (status << 8); | 957 | vber |= (status << 8); |
918 | status = tda1004x_read_byte(state, TDA1004X_VBER_MSB); | 958 | status = tda1004x_read_byte(state, TDA1004X_VBER_MSB); |
919 | if (status == -1) return -EIO; | 959 | if (status == -1) |
960 | return -EIO; | ||
920 | vber |= ((status << 16) & 0x0f); | 961 | vber |= ((status << 16) & 0x0f); |
921 | tda1004x_read_byte(state, TDA1004X_CVBER_LUT); | 962 | tda1004x_read_byte(state, TDA1004X_CVBER_LUT); |
922 | 963 | ||
923 | // if RS has passed some valid TS packets, then we must be | 964 | // if RS has passed some valid TS packets, then we must be |
924 | // getting some SYNC bytes | 965 | // getting some SYNC bytes |
925 | if (vber < 16632) { | 966 | if (vber < 16632) |
926 | *fe_status |= FE_HAS_SYNC; | 967 | *fe_status |= FE_HAS_SYNC; |
927 | } | ||
928 | } | 968 | } |
929 | 969 | ||
930 | // success | 970 | // success |
@@ -941,7 +981,7 @@ static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal) | |||
941 | dprintk("%s\n", __FUNCTION__); | 981 | dprintk("%s\n", __FUNCTION__); |
942 | 982 | ||
943 | // determine the register to use | 983 | // determine the register to use |
944 | switch(state->demod_type) { | 984 | switch (state->demod_type) { |
945 | case TDA1004X_DEMOD_TDA10045: | 985 | case TDA1004X_DEMOD_TDA10045: |
946 | reg = TDA10045H_S_AGC; | 986 | reg = TDA10045H_S_AGC; |
947 | break; | 987 | break; |
@@ -972,9 +1012,8 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr) | |||
972 | tmp = tda1004x_read_byte(state, TDA1004X_SNR); | 1012 | tmp = tda1004x_read_byte(state, TDA1004X_SNR); |
973 | if (tmp < 0) | 1013 | if (tmp < 0) |
974 | return -EIO; | 1014 | return -EIO; |
975 | if (tmp) { | 1015 | if (tmp) |
976 | tmp = 255 - tmp; | 1016 | tmp = 255 - tmp; |
977 | } | ||
978 | 1017 | ||
979 | *snr = ((tmp << 8) | tmp); | 1018 | *snr = ((tmp << 8) | tmp); |
980 | dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr); | 1019 | dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr); |
@@ -1009,11 +1048,11 @@ static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
1009 | break; | 1048 | break; |
1010 | } | 1049 | } |
1011 | 1050 | ||
1012 | if (tmp != 0x7f) { | 1051 | if (tmp != 0x7f) |
1013 | *ucblocks = tmp; | 1052 | *ucblocks = tmp; |
1014 | } else { | 1053 | else |
1015 | *ucblocks = 0xffffffff; | 1054 | *ucblocks = 0xffffffff; |
1016 | } | 1055 | |
1017 | dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks); | 1056 | dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks); |
1018 | return 0; | 1057 | return 0; |
1019 | } | 1058 | } |
@@ -1027,10 +1066,12 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) | |||
1027 | 1066 | ||
1028 | // read it in | 1067 | // read it in |
1029 | tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB); | 1068 | tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB); |
1030 | if (tmp < 0) return -EIO; | 1069 | if (tmp < 0) |
1070 | return -EIO; | ||
1031 | *ber = tmp << 1; | 1071 | *ber = tmp << 1; |
1032 | tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB); | 1072 | tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB); |
1033 | if (tmp < 0) return -EIO; | 1073 | if (tmp < 0) |
1074 | return -EIO; | ||
1034 | *ber |= (tmp << 9); | 1075 | *ber |= (tmp << 9); |
1035 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); | 1076 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); |
1036 | 1077 | ||
@@ -1042,7 +1083,7 @@ static int tda1004x_sleep(struct dvb_frontend* fe) | |||
1042 | { | 1083 | { |
1043 | struct tda1004x_state* state = fe->demodulator_priv; | 1084 | struct tda1004x_state* state = fe->demodulator_priv; |
1044 | 1085 | ||
1045 | switch(state->demod_type) { | 1086 | switch (state->demod_type) { |
1046 | case TDA1004X_DEMOD_TDA10045: | 1087 | case TDA1004X_DEMOD_TDA10045: |
1047 | tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10); | 1088 | tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10); |
1048 | break; | 1089 | break; |
@@ -1066,74 +1107,11 @@ static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronte | |||
1066 | 1107 | ||
1067 | static void tda1004x_release(struct dvb_frontend* fe) | 1108 | static void tda1004x_release(struct dvb_frontend* fe) |
1068 | { | 1109 | { |
1069 | struct tda1004x_state* state = (struct tda1004x_state*) fe->demodulator_priv; | 1110 | struct tda1004x_state *state = fe->demodulator_priv; |
1070 | kfree(state); | ||
1071 | } | ||
1072 | |||
1073 | static struct dvb_frontend_ops tda10045_ops; | ||
1074 | |||
1075 | struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, | ||
1076 | struct i2c_adapter* i2c) | ||
1077 | { | ||
1078 | struct tda1004x_state* state = NULL; | ||
1079 | |||
1080 | /* allocate memory for the internal state */ | ||
1081 | state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); | ||
1082 | if (state == NULL) goto error; | ||
1083 | |||
1084 | /* setup the state */ | ||
1085 | state->config = config; | ||
1086 | state->i2c = i2c; | ||
1087 | memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); | ||
1088 | state->initialised = 0; | ||
1089 | state->demod_type = TDA1004X_DEMOD_TDA10045; | ||
1090 | |||
1091 | /* check if the demod is there */ | ||
1092 | if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) goto error; | ||
1093 | |||
1094 | /* create dvb_frontend */ | ||
1095 | state->frontend.ops = &state->ops; | ||
1096 | state->frontend.demodulator_priv = state; | ||
1097 | return &state->frontend; | ||
1098 | |||
1099 | error: | ||
1100 | kfree(state); | 1111 | kfree(state); |
1101 | return NULL; | ||
1102 | } | ||
1103 | |||
1104 | static struct dvb_frontend_ops tda10046_ops; | ||
1105 | |||
1106 | struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, | ||
1107 | struct i2c_adapter* i2c) | ||
1108 | { | ||
1109 | struct tda1004x_state* state = NULL; | ||
1110 | |||
1111 | /* allocate memory for the internal state */ | ||
1112 | state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); | ||
1113 | if (state == NULL) goto error; | ||
1114 | |||
1115 | /* setup the state */ | ||
1116 | state->config = config; | ||
1117 | state->i2c = i2c; | ||
1118 | memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); | ||
1119 | state->initialised = 0; | ||
1120 | state->demod_type = TDA1004X_DEMOD_TDA10046; | ||
1121 | |||
1122 | /* check if the demod is there */ | ||
1123 | if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) goto error; | ||
1124 | |||
1125 | /* create dvb_frontend */ | ||
1126 | state->frontend.ops = &state->ops; | ||
1127 | state->frontend.demodulator_priv = state; | ||
1128 | return &state->frontend; | ||
1129 | |||
1130 | error: | ||
1131 | if (state) kfree(state); | ||
1132 | return NULL; | ||
1133 | } | 1112 | } |
1134 | 1113 | ||
1135 | static struct dvb_frontend_ops tda10045_ops = { | 1114 | static struct dvb_frontend_ops tda10045_ops = { |
1136 | |||
1137 | .info = { | 1115 | .info = { |
1138 | .name = "Philips TDA10045H DVB-T", | 1116 | .name = "Philips TDA10045H DVB-T", |
1139 | .type = FE_OFDM, | 1117 | .type = FE_OFDM, |
@@ -1163,8 +1141,36 @@ static struct dvb_frontend_ops tda10045_ops = { | |||
1163 | .read_ucblocks = tda1004x_read_ucblocks, | 1141 | .read_ucblocks = tda1004x_read_ucblocks, |
1164 | }; | 1142 | }; |
1165 | 1143 | ||
1166 | static struct dvb_frontend_ops tda10046_ops = { | 1144 | struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, |
1145 | struct i2c_adapter* i2c) | ||
1146 | { | ||
1147 | struct tda1004x_state *state; | ||
1148 | |||
1149 | /* allocate memory for the internal state */ | ||
1150 | state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); | ||
1151 | if (!state) | ||
1152 | return NULL; | ||
1153 | |||
1154 | /* setup the state */ | ||
1155 | state->config = config; | ||
1156 | state->i2c = i2c; | ||
1157 | memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); | ||
1158 | state->initialised = 0; | ||
1159 | state->demod_type = TDA1004X_DEMOD_TDA10045; | ||
1160 | |||
1161 | /* check if the demod is there */ | ||
1162 | if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) { | ||
1163 | kfree(state); | ||
1164 | return NULL; | ||
1165 | } | ||
1167 | 1166 | ||
1167 | /* create dvb_frontend */ | ||
1168 | state->frontend.ops = &state->ops; | ||
1169 | state->frontend.demodulator_priv = state; | ||
1170 | return &state->frontend; | ||
1171 | } | ||
1172 | |||
1173 | static struct dvb_frontend_ops tda10046_ops = { | ||
1168 | .info = { | 1174 | .info = { |
1169 | .name = "Philips TDA10046H DVB-T", | 1175 | .name = "Philips TDA10046H DVB-T", |
1170 | .type = FE_OFDM, | 1176 | .type = FE_OFDM, |
@@ -1194,6 +1200,36 @@ static struct dvb_frontend_ops tda10046_ops = { | |||
1194 | .read_ucblocks = tda1004x_read_ucblocks, | 1200 | .read_ucblocks = tda1004x_read_ucblocks, |
1195 | }; | 1201 | }; |
1196 | 1202 | ||
1203 | struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, | ||
1204 | struct i2c_adapter* i2c) | ||
1205 | { | ||
1206 | struct tda1004x_state *state; | ||
1207 | |||
1208 | /* allocate memory for the internal state */ | ||
1209 | state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); | ||
1210 | if (!state) | ||
1211 | return NULL; | ||
1212 | |||
1213 | /* setup the state */ | ||
1214 | state->config = config; | ||
1215 | state->i2c = i2c; | ||
1216 | memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); | ||
1217 | state->initialised = 0; | ||
1218 | state->demod_type = TDA1004X_DEMOD_TDA10046; | ||
1219 | state->fw_version = 0x20; /* dummy default value */ | ||
1220 | |||
1221 | /* check if the demod is there */ | ||
1222 | if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) { | ||
1223 | kfree(state); | ||
1224 | return NULL; | ||
1225 | } | ||
1226 | |||
1227 | /* create dvb_frontend */ | ||
1228 | state->frontend.ops = &state->ops; | ||
1229 | state->frontend.demodulator_priv = state; | ||
1230 | return &state->frontend; | ||
1231 | } | ||
1232 | |||
1197 | module_param(debug, int, 0644); | 1233 | module_param(debug, int, 0644); |
1198 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | 1234 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); |
1199 | 1235 | ||