diff options
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/frontends/s5h1411.c | 84 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/s5h1411.h | 2 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110.c | 2 |
3 files changed, 60 insertions, 28 deletions
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c index 2febfb5a846..40644aacffc 100644 --- a/drivers/media/dvb/frontends/s5h1411.c +++ b/drivers/media/dvb/frontends/s5h1411.c | |||
@@ -38,6 +38,7 @@ struct s5h1411_state { | |||
38 | struct dvb_frontend frontend; | 38 | struct dvb_frontend frontend; |
39 | 39 | ||
40 | fe_modulation_t current_modulation; | 40 | fe_modulation_t current_modulation; |
41 | unsigned int first_tune:1; | ||
41 | 42 | ||
42 | u32 current_frequency; | 43 | u32 current_frequency; |
43 | int if_freq; | 44 | int if_freq; |
@@ -62,7 +63,7 @@ static struct init_tab { | |||
62 | { S5H1411_I2C_TOP_ADDR, 0x08, 0x0047, }, | 63 | { S5H1411_I2C_TOP_ADDR, 0x08, 0x0047, }, |
63 | { S5H1411_I2C_TOP_ADDR, 0x1c, 0x0400, }, | 64 | { S5H1411_I2C_TOP_ADDR, 0x1c, 0x0400, }, |
64 | { S5H1411_I2C_TOP_ADDR, 0x1e, 0x0370, }, | 65 | { S5H1411_I2C_TOP_ADDR, 0x1e, 0x0370, }, |
65 | { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342a, }, | 66 | { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342c, }, |
66 | { S5H1411_I2C_TOP_ADDR, 0x24, 0x0231, }, | 67 | { S5H1411_I2C_TOP_ADDR, 0x24, 0x0231, }, |
67 | { S5H1411_I2C_TOP_ADDR, 0x25, 0x1011, }, | 68 | { S5H1411_I2C_TOP_ADDR, 0x25, 0x1011, }, |
68 | { S5H1411_I2C_TOP_ADDR, 0x26, 0x0f07, }, | 69 | { S5H1411_I2C_TOP_ADDR, 0x26, 0x0f07, }, |
@@ -100,7 +101,6 @@ static struct init_tab { | |||
100 | { S5H1411_I2C_TOP_ADDR, 0x78, 0x3141, }, | 101 | { S5H1411_I2C_TOP_ADDR, 0x78, 0x3141, }, |
101 | { S5H1411_I2C_TOP_ADDR, 0x7a, 0x3141, }, | 102 | { S5H1411_I2C_TOP_ADDR, 0x7a, 0x3141, }, |
102 | { S5H1411_I2C_TOP_ADDR, 0xb3, 0x8003, }, | 103 | { S5H1411_I2C_TOP_ADDR, 0xb3, 0x8003, }, |
103 | { S5H1411_I2C_TOP_ADDR, 0xb5, 0xafbb, }, | ||
104 | { S5H1411_I2C_TOP_ADDR, 0xb5, 0xa6bb, }, | 104 | { S5H1411_I2C_TOP_ADDR, 0xb5, 0xa6bb, }, |
105 | { S5H1411_I2C_TOP_ADDR, 0xb6, 0x0609, }, | 105 | { S5H1411_I2C_TOP_ADDR, 0xb6, 0x0609, }, |
106 | { S5H1411_I2C_TOP_ADDR, 0xb7, 0x2f06, }, | 106 | { S5H1411_I2C_TOP_ADDR, 0xb7, 0x2f06, }, |
@@ -393,7 +393,7 @@ static int s5h1411_set_if_freq(struct dvb_frontend *fe, int KHz) | |||
393 | 393 | ||
394 | switch (KHz) { | 394 | switch (KHz) { |
395 | case 3250: | 395 | case 3250: |
396 | s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d9); | 396 | s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d5); |
397 | s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x5342); | 397 | s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x5342); |
398 | s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x10d9); | 398 | s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x10d9); |
399 | break; | 399 | break; |
@@ -464,13 +464,25 @@ static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion) | |||
464 | 464 | ||
465 | if (inversion == 1) | 465 | if (inversion == 1) |
466 | val |= 0x1000; /* Inverted */ | 466 | val |= 0x1000; /* Inverted */ |
467 | else | ||
468 | val |= 0x0000; | ||
469 | 467 | ||
470 | state->inversion = inversion; | 468 | state->inversion = inversion; |
471 | return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val); | 469 | return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val); |
472 | } | 470 | } |
473 | 471 | ||
472 | static int s5h1411_set_serialmode(struct dvb_frontend *fe, int serial) | ||
473 | { | ||
474 | struct s5h1411_state *state = fe->demodulator_priv; | ||
475 | u16 val; | ||
476 | |||
477 | dprintk("%s(%d)\n", __func__, serial); | ||
478 | val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbd) & ~0x100; | ||
479 | |||
480 | if (serial == 1) | ||
481 | val |= 0x100; | ||
482 | |||
483 | return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, val); | ||
484 | } | ||
485 | |||
474 | static int s5h1411_enable_modulation(struct dvb_frontend *fe, | 486 | static int s5h1411_enable_modulation(struct dvb_frontend *fe, |
475 | fe_modulation_t m) | 487 | fe_modulation_t m) |
476 | { | 488 | { |
@@ -478,6 +490,12 @@ static int s5h1411_enable_modulation(struct dvb_frontend *fe, | |||
478 | 490 | ||
479 | dprintk("%s(0x%08x)\n", __func__, m); | 491 | dprintk("%s(0x%08x)\n", __func__, m); |
480 | 492 | ||
493 | if ((state->first_tune == 0) && (m == state->current_modulation)) { | ||
494 | dprintk("%s() Already at desired modulation. Skipping...\n", | ||
495 | __func__); | ||
496 | return 0; | ||
497 | } | ||
498 | |||
481 | switch (m) { | 499 | switch (m) { |
482 | case VSB_8: | 500 | case VSB_8: |
483 | dprintk("%s() VSB_8\n", __func__); | 501 | dprintk("%s() VSB_8\n", __func__); |
@@ -502,6 +520,7 @@ static int s5h1411_enable_modulation(struct dvb_frontend *fe, | |||
502 | } | 520 | } |
503 | 521 | ||
504 | state->current_modulation = m; | 522 | state->current_modulation = m; |
523 | state->first_tune = 0; | ||
505 | s5h1411_softreset(fe); | 524 | s5h1411_softreset(fe); |
506 | 525 | ||
507 | return 0; | 526 | return 0; |
@@ -535,7 +554,7 @@ static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable) | |||
535 | return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val); | 554 | return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val); |
536 | } | 555 | } |
537 | 556 | ||
538 | static int s5h1411_sleep(struct dvb_frontend *fe, int enable) | 557 | static int s5h1411_set_powerstate(struct dvb_frontend *fe, int enable) |
539 | { | 558 | { |
540 | struct s5h1411_state *state = fe->demodulator_priv; | 559 | struct s5h1411_state *state = fe->demodulator_priv; |
541 | 560 | ||
@@ -551,6 +570,11 @@ static int s5h1411_sleep(struct dvb_frontend *fe, int enable) | |||
551 | return 0; | 570 | return 0; |
552 | } | 571 | } |
553 | 572 | ||
573 | static int s5h1411_sleep(struct dvb_frontend *fe) | ||
574 | { | ||
575 | return s5h1411_set_powerstate(fe, 1); | ||
576 | } | ||
577 | |||
554 | static int s5h1411_register_reset(struct dvb_frontend *fe) | 578 | static int s5h1411_register_reset(struct dvb_frontend *fe) |
555 | { | 579 | { |
556 | struct s5h1411_state *state = fe->demodulator_priv; | 580 | struct s5h1411_state *state = fe->demodulator_priv; |
@@ -574,9 +598,6 @@ static int s5h1411_set_frontend(struct dvb_frontend *fe, | |||
574 | 598 | ||
575 | s5h1411_enable_modulation(fe, p->u.vsb.modulation); | 599 | s5h1411_enable_modulation(fe, p->u.vsb.modulation); |
576 | 600 | ||
577 | /* Allow the demod to settle */ | ||
578 | msleep(100); | ||
579 | |||
580 | if (fe->ops.tuner_ops.set_params) { | 601 | if (fe->ops.tuner_ops.set_params) { |
581 | if (fe->ops.i2c_gate_ctrl) | 602 | if (fe->ops.i2c_gate_ctrl) |
582 | fe->ops.i2c_gate_ctrl(fe, 1); | 603 | fe->ops.i2c_gate_ctrl(fe, 1); |
@@ -587,6 +608,10 @@ static int s5h1411_set_frontend(struct dvb_frontend *fe, | |||
587 | fe->ops.i2c_gate_ctrl(fe, 0); | 608 | fe->ops.i2c_gate_ctrl(fe, 0); |
588 | } | 609 | } |
589 | 610 | ||
611 | /* Issue a reset to the demod so it knows to resync against the | ||
612 | newly tuned frequency */ | ||
613 | s5h1411_softreset(fe); | ||
614 | |||
590 | return 0; | 615 | return 0; |
591 | } | 616 | } |
592 | 617 | ||
@@ -599,7 +624,7 @@ static int s5h1411_init(struct dvb_frontend *fe) | |||
599 | 624 | ||
600 | dprintk("%s()\n", __func__); | 625 | dprintk("%s()\n", __func__); |
601 | 626 | ||
602 | s5h1411_sleep(fe, 0); | 627 | s5h1411_set_powerstate(fe, 0); |
603 | s5h1411_register_reset(fe); | 628 | s5h1411_register_reset(fe); |
604 | 629 | ||
605 | for (i = 0; i < ARRAY_SIZE(init_tab); i++) | 630 | for (i = 0; i < ARRAY_SIZE(init_tab); i++) |
@@ -610,12 +635,17 @@ static int s5h1411_init(struct dvb_frontend *fe) | |||
610 | /* The datasheet says that after initialisation, VSB is default */ | 635 | /* The datasheet says that after initialisation, VSB is default */ |
611 | state->current_modulation = VSB_8; | 636 | state->current_modulation = VSB_8; |
612 | 637 | ||
638 | /* Although the datasheet says it's in VSB, empirical evidence | ||
639 | shows problems getting lock on the first tuning request. Make | ||
640 | sure we call enable_modulation the first time around */ | ||
641 | state->first_tune = 1; | ||
642 | |||
613 | if (state->config->output_mode == S5H1411_SERIAL_OUTPUT) | 643 | if (state->config->output_mode == S5H1411_SERIAL_OUTPUT) |
614 | /* Serial */ | 644 | /* Serial */ |
615 | s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1101); | 645 | s5h1411_set_serialmode(fe, 1); |
616 | else | 646 | else |
617 | /* Parallel */ | 647 | /* Parallel */ |
618 | s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1001); | 648 | s5h1411_set_serialmode(fe, 0); |
619 | 649 | ||
620 | s5h1411_set_spectralinversion(fe, state->config->inversion); | 650 | s5h1411_set_spectralinversion(fe, state->config->inversion); |
621 | s5h1411_set_if_freq(fe, state->config->vsb_if); | 651 | s5h1411_set_if_freq(fe, state->config->vsb_if); |
@@ -637,28 +667,29 @@ static int s5h1411_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
637 | 667 | ||
638 | *status = 0; | 668 | *status = 0; |
639 | 669 | ||
640 | /* Get the demodulator status */ | 670 | /* Register F2 bit 15 = Master Lock, removed */ |
641 | reg = (s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2) >> 15) | ||
642 | & 0x0001; | ||
643 | if (reg) | ||
644 | *status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_SIGNAL; | ||
645 | 671 | ||
646 | switch (state->current_modulation) { | 672 | switch (state->current_modulation) { |
647 | case QAM_64: | 673 | case QAM_64: |
648 | case QAM_256: | 674 | case QAM_256: |
649 | reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf0); | 675 | reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf0); |
650 | if (reg & 0x100) | 676 | if (reg & 0x10) /* QAM FEC Lock */ |
651 | *status |= FE_HAS_VITERBI; | 677 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; |
652 | if (reg & 0x10) | 678 | if (reg & 0x100) /* QAM EQ Lock */ |
653 | *status |= FE_HAS_SYNC; | 679 | *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; |
680 | |||
654 | break; | 681 | break; |
655 | case VSB_8: | 682 | case VSB_8: |
656 | reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x5e); | ||
657 | if (reg & 0x0001) | ||
658 | *status |= FE_HAS_SYNC; | ||
659 | reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2); | 683 | reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2); |
660 | if (reg & 0x1000) | 684 | if (reg & 0x1000) /* FEC Lock */ |
661 | *status |= FE_HAS_VITERBI; | 685 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; |
686 | if (reg & 0x2000) /* EQ Lock */ | ||
687 | *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; | ||
688 | |||
689 | reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x53); | ||
690 | if (reg & 0x1) /* AFC Lock */ | ||
691 | *status |= FE_HAS_SIGNAL; | ||
692 | |||
662 | break; | 693 | break; |
663 | default: | 694 | default: |
664 | return -EINVAL; | 695 | return -EINVAL; |
@@ -863,6 +894,7 @@ static struct dvb_frontend_ops s5h1411_ops = { | |||
863 | }, | 894 | }, |
864 | 895 | ||
865 | .init = s5h1411_init, | 896 | .init = s5h1411_init, |
897 | .sleep = s5h1411_sleep, | ||
866 | .i2c_gate_ctrl = s5h1411_i2c_gate_ctrl, | 898 | .i2c_gate_ctrl = s5h1411_i2c_gate_ctrl, |
867 | .set_frontend = s5h1411_set_frontend, | 899 | .set_frontend = s5h1411_set_frontend, |
868 | .get_frontend = s5h1411_get_frontend, | 900 | .get_frontend = s5h1411_get_frontend, |
diff --git a/drivers/media/dvb/frontends/s5h1411.h b/drivers/media/dvb/frontends/s5h1411.h index 7d542bc00c4..45ec0f82989 100644 --- a/drivers/media/dvb/frontends/s5h1411.h +++ b/drivers/media/dvb/frontends/s5h1411.h | |||
@@ -47,7 +47,7 @@ struct s5h1411_config { | |||
47 | u16 mpeg_timing; | 47 | u16 mpeg_timing; |
48 | 48 | ||
49 | /* IF Freq for QAM and VSB in KHz */ | 49 | /* IF Freq for QAM and VSB in KHz */ |
50 | #define S5H1411_IF_2500 2500 | 50 | #define S5H1411_IF_3250 3250 |
51 | #define S5H1411_IF_3500 3500 | 51 | #define S5H1411_IF_3500 3500 |
52 | #define S5H1411_IF_4000 4000 | 52 | #define S5H1411_IF_4000 4000 |
53 | #define S5H1411_IF_5380 5380 | 53 | #define S5H1411_IF_5380 5380 |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index c7c770c2898..aa1ff524256 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/timer.h> | 37 | #include <linux/timer.h> |
38 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
39 | #include <linux/byteorder/swabb.h> | ||
40 | #include <linux/smp_lock.h> | 39 | #include <linux/smp_lock.h> |
41 | 40 | ||
42 | #include <linux/kernel.h> | 41 | #include <linux/kernel.h> |
@@ -52,6 +51,7 @@ | |||
52 | #include <linux/i2c.h> | 51 | #include <linux/i2c.h> |
53 | #include <linux/kthread.h> | 52 | #include <linux/kthread.h> |
54 | #include <asm/unaligned.h> | 53 | #include <asm/unaligned.h> |
54 | #include <asm/byteorder.h> | ||
55 | 55 | ||
56 | #include <asm/system.h> | 56 | #include <asm/system.h> |
57 | 57 | ||