diff options
author | Steven Toth <stoth@hauppauge.com> | 2008-01-15 19:35:22 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:05:05 -0500 |
commit | dfc1c08aab447d49230dacb390d3f2263584d28f (patch) | |
tree | 2edf9ca4dfeb2a15b1e93eb68660f9cffb5a4bfa /drivers/media/dvb/frontends/s5h1409.c | |
parent | 387d447776484b6e1d08973337aa4c834ea7c6bc (diff) |
V4L/DVB (7041): s5h1409: Bug fix for parallel support
Parallel support was not working with the s5h1409 and the Pinnacle HD800i.
This patch fixes the demodulator driver and ensures that all existing
s5h1409 based products configure the demodulator correctly.
Signed-off-by: Steven Toth <stoth@hauppauge.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/dvb/frontends/s5h1409.c')
-rw-r--r-- | drivers/media/dvb/frontends/s5h1409.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c index 3391777e0b2f..819433485d3b 100644 --- a/drivers/media/dvb/frontends/s5h1409.c +++ b/drivers/media/dvb/frontends/s5h1409.c | |||
@@ -98,7 +98,7 @@ static struct init_tab { | |||
98 | { 0xac, 0x1003, }, | 98 | { 0xac, 0x1003, }, |
99 | { 0xad, 0x103f, }, | 99 | { 0xad, 0x103f, }, |
100 | { 0xe2, 0x0100, }, | 100 | { 0xe2, 0x0100, }, |
101 | { 0xe3, 0x0000, }, | 101 | { 0xe3, 0x1000, }, |
102 | { 0x28, 0x1010, }, | 102 | { 0x28, 0x1010, }, |
103 | { 0xb1, 0x000e, }, | 103 | { 0xb1, 0x000e, }, |
104 | }; | 104 | }; |
@@ -441,9 +441,11 @@ static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable) | |||
441 | dprintk("%s(%d)\n", __FUNCTION__, enable); | 441 | dprintk("%s(%d)\n", __FUNCTION__, enable); |
442 | 442 | ||
443 | if (enable) | 443 | if (enable) |
444 | return s5h1409_writereg(state, 0xe3, 0x1100); | 444 | return s5h1409_writereg(state, 0xe3, |
445 | s5h1409_readreg(state, 0xe3) | 0x1100); | ||
445 | else | 446 | else |
446 | return s5h1409_writereg(state, 0xe3, 0x1000); | 447 | return s5h1409_writereg(state, 0xe3, |
448 | s5h1409_readreg(state, 0xe3) & 0xeeff); | ||
447 | } | 449 | } |
448 | 450 | ||
449 | static int s5h1409_sleep(struct dvb_frontend* fe, int enable) | 451 | static int s5h1409_sleep(struct dvb_frontend* fe, int enable) |
@@ -513,13 +515,15 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe) | |||
513 | s5h1409_writereg(state, 0x96, 0x20); | 515 | s5h1409_writereg(state, 0x96, 0x20); |
514 | s5h1409_writereg(state, 0xad, | 516 | s5h1409_writereg(state, 0xad, |
515 | ( ((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)) ); | 517 | ( ((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)) ); |
516 | s5h1409_writereg(state, 0xab, 0x1100); | 518 | s5h1409_writereg(state, 0xab, |
519 | s5h1409_readreg(state, 0xab) & 0xeffe); | ||
517 | } | 520 | } |
518 | } else { | 521 | } else { |
519 | if (state->qam_state != 1) { | 522 | if (state->qam_state != 1) { |
520 | state->qam_state = 1; | 523 | state->qam_state = 1; |
521 | s5h1409_writereg(state, 0x96, 0x08); | 524 | s5h1409_writereg(state, 0x96, 0x08); |
522 | s5h1409_writereg(state, 0xab, 0x1101); | 525 | s5h1409_writereg(state, 0xab, |
526 | s5h1409_readreg(state, 0xab) | 0x1001); | ||
523 | } | 527 | } |
524 | } | 528 | } |
525 | } | 529 | } |
@@ -556,6 +560,36 @@ static int s5h1409_set_frontend (struct dvb_frontend* fe, | |||
556 | return 0; | 560 | return 0; |
557 | } | 561 | } |
558 | 562 | ||
563 | static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode) | ||
564 | { | ||
565 | struct s5h1409_state *state = fe->demodulator_priv; | ||
566 | u16 val; | ||
567 | |||
568 | dprintk("%s(%d)\n", __FUNCTION__, mode); | ||
569 | |||
570 | val = s5h1409_readreg(state, 0xac) & 0xcfff; | ||
571 | switch (mode) { | ||
572 | case S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK: | ||
573 | val |= 0x0000; | ||
574 | break; | ||
575 | case S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK: | ||
576 | dprintk("%s(%d) Mode1 or Defaulting\n", __FUNCTION__, mode); | ||
577 | val |= 0x1000; | ||
578 | break; | ||
579 | case S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK: | ||
580 | val |= 0x2000; | ||
581 | break; | ||
582 | case S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK: | ||
583 | val |= 0x3000; | ||
584 | break; | ||
585 | default: | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | |||
589 | /* Configure MPEG Signal Timing charactistics */ | ||
590 | return s5h1409_writereg(state, 0xac, val); | ||
591 | } | ||
592 | |||
559 | /* Reset the demod hardware and reset all of the configuration registers | 593 | /* Reset the demod hardware and reset all of the configuration registers |
560 | to a default state. */ | 594 | to a default state. */ |
561 | static int s5h1409_init (struct dvb_frontend* fe) | 595 | static int s5h1409_init (struct dvb_frontend* fe) |
@@ -575,13 +609,16 @@ static int s5h1409_init (struct dvb_frontend* fe) | |||
575 | state->current_modulation = VSB_8; | 609 | state->current_modulation = VSB_8; |
576 | 610 | ||
577 | if (state->config->output_mode == S5H1409_SERIAL_OUTPUT) | 611 | if (state->config->output_mode == S5H1409_SERIAL_OUTPUT) |
578 | s5h1409_writereg(state, 0xab, 0x100); /* Serial */ | 612 | s5h1409_writereg(state, 0xab, |
613 | s5h1409_readreg(state, 0xab) | 0x100); /* Serial */ | ||
579 | else | 614 | else |
580 | s5h1409_writereg(state, 0xab, 0x0); /* Parallel */ | 615 | s5h1409_writereg(state, 0xab, |
616 | s5h1409_readreg(state, 0xab) & 0xfeff); /* Parallel */ | ||
581 | 617 | ||
582 | s5h1409_set_spectralinversion(fe, state->config->inversion); | 618 | s5h1409_set_spectralinversion(fe, state->config->inversion); |
583 | s5h1409_set_if_freq(fe, state->if_freq); | 619 | s5h1409_set_if_freq(fe, state->if_freq); |
584 | s5h1409_set_gpio(fe, state->config->gpio); | 620 | s5h1409_set_gpio(fe, state->config->gpio); |
621 | s5h1409_set_mpeg_timing(fe, state->config->mpeg_timing); | ||
585 | s5h1409_softreset(fe); | 622 | s5h1409_softreset(fe); |
586 | 623 | ||
587 | /* Note: Leaving the I2C gate closed. */ | 624 | /* Note: Leaving the I2C gate closed. */ |