diff options
-rw-r--r-- | linux/drivers/media/dvb/frontends/stv0299.c | 74 |
1 files changed, 31 insertions, 43 deletions
diff --git a/linux/drivers/media/dvb/frontends/stv0299.c b/linux/drivers/media/dvb/frontends/stv0299.c index 35d9211ad..8c9154948 100644 --- a/linux/drivers/media/dvb/frontends/stv0299.c +++ b/linux/drivers/media/dvb/frontends/stv0299.c @@ -103,6 +103,7 @@ static struct dvb_frontend_info uni0299_info = { struct stv0299_state { u8 tuner_type; + u8 initialised:1; u32 tuner_frequency; u32 symbol_rate; fe_code_rate_t fec_inner; @@ -371,7 +372,7 @@ static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, in regcode = 2; // setup frequency divisor - div = freq / divisor; + div = (freq + (divisor - 1)) / divisor; // round correctly buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; buf[2] = 0x80 | ((div & 0x18000) >> 10) | regcode; @@ -592,15 +593,6 @@ static int stv0299_init (struct dvb_i2c_bus *i2c, int ftype) for (i=0; i<sizeof(init_tab_su1278_tsa_tt); i+=2) { stv0299_writereg (i2c, init_tab_su1278_tsa_tt[i], init_tab_su1278_tsa_tt[i+1]); } - - // seems to be much more reliable if a proper tune is kicked off during init - stv0299_writereg(i2c, 0x0c, stv0299_readreg(i2c, 0x0c) & 0xfe); - stv0299_set_FEC(i2c, FEC_AUTO); - stv0299_set_symbolrate(i2c, 27500000, ftype); - pll_set_tv_freq (i2c, 12200000, ftype, 27500000); - stv0299_writereg (i2c, 0x22, 0x00); - stv0299_writereg (i2c, 0x23, 0x00); - dvb_delay(200); // long delay is needed to recover from sleeping break; default: @@ -635,23 +627,6 @@ static int stv0299_init (struct dvb_i2c_bus *i2c, int ftype) } -static int stv0299_check_inversion (struct dvb_i2c_bus *i2c) -{ - dprintk ("%s\n", __FUNCTION__); - - if ((stv0299_readreg (i2c, 0x1b) & 0x98) != 0x98) { - dvb_delay(30); - if ((stv0299_readreg (i2c, 0x1b) & 0x98) != 0x98) { - u8 val = stv0299_readreg (i2c, 0x0c); - dprintk ("%s : changing inversion\n", __FUNCTION__); - return stv0299_writereg (i2c, 0x0c, val ^ 0x01); - } - } - - return 0; -} - - static int stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) { dprintk ("%s\n", __FUNCTION__); @@ -892,6 +867,7 @@ static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate, int tuner // calculate value to program if (tuner_type == PHILIPS_SU1278_TSA_TT) Mclk = M_CLK_SU1278_TSA_TT; big = big << 20; + big += (Mclk-1); // round correctly do_div(big, Mclk); ratio = big << 4; @@ -1112,10 +1088,16 @@ static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) int frequency_delta = p->frequency - state->tuner_frequency; int minmax = p->u.qpsk.symbol_rate / 1000; - if ((frequency_delta > -minmax) && (frequency_delta < minmax) && + if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) && (state->fec_inner == p->u.qpsk.fec_inner) && (state->symbol_rate == p->u.qpsk.symbol_rate)) { - int Drot_freq = ((frequency_delta) << 16) / (M_CLK_SU1278_TSA_TT /1000); + int Drot_freq = (frequency_delta << 16) / (M_CLK_SU1278_TSA_TT / 1000); + + // zap the derotator registers first + stv0299_writereg (i2c, 0x22, 0x00); + stv0299_writereg (i2c, 0x23, 0x00); + + // now set them as we want stv0299_writereg (i2c, 0x22, Drot_freq >> 8); stv0299_writereg (i2c, 0x23, Drot_freq); break; @@ -1123,18 +1105,18 @@ static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) } /* A "normal" tune is requested */ - stv0299_set_FEC (i2c, p->u.qpsk.fec_inner); - stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate, state->tuner_type); - pll_set_tv_freq (i2c, p->frequency, state->tuner_type, - p->u.qpsk.symbol_rate); - stv0299_writereg (i2c, 0x22, 0x00); - stv0299_writereg (i2c, 0x23, 0x00); - if (state->tuner_type != PHILIPS_SU1278_TSA_TT) { - stv0299_readreg (i2c, 0x23); - stv0299_writereg (i2c, 0x12, 0xb9); - } - dvb_delay(10); - + stv0299_writereg (i2c, 0x32, 0x80); + stv0299_writereg (i2c, 0x22, 0x00); + stv0299_writereg (i2c, 0x23, 0x00); + stv0299_writereg (i2c, 0x32, 0x19); + stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate, state->tuner_type); + stv0299_set_FEC (i2c, p->u.qpsk.fec_inner); + pll_set_tv_freq (i2c, p->frequency, state->tuner_type, p->u.qpsk.symbol_rate); + dvb_delay(50); + stv0299_writereg (i2c, 0x22, 0x00); + stv0299_writereg (i2c, 0x23, 0x00); + pll_set_tv_freq (i2c, p->frequency, state->tuner_type, p->u.qpsk.symbol_rate); + state->tuner_frequency = p->frequency; state->fec_inner = p->u.qpsk.fec_inner; state->symbol_rate = p->u.qpsk.symbol_rate; @@ -1168,11 +1150,16 @@ static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) stv0299_writereg (i2c, 0x0c, 0x00); /* LNB power off! */ stv0299_writereg (i2c, 0x08, 0x00); /* LNB power off! */ stv0299_writereg (i2c, 0x02, 0x80); + state->initialised = 0; break; case FE_INIT: state->tuner_frequency = 0; - return stv0299_init (i2c, state->tuner_type); + if (!state->initialised) { + state->initialised = 1; + return stv0299_init (i2c, state->tuner_type); + } + break; case FE_DISEQC_SEND_MASTER_CMD: return stv0299_send_diseqc_msg (i2c, arg); @@ -1186,7 +1173,7 @@ static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) case FE_SET_VOLTAGE: return stv0299_set_voltage (i2c, (fe_sec_voltage_t) arg); - default: + default: return -EOPNOTSUPP; }; @@ -1291,6 +1278,7 @@ static int uni0299_attach (struct dvb_i2c_bus *i2c, void **data) *data = state; state->tuner_type = tuner_type; state->tuner_frequency = 0; + state->initialised = 0; return dvb_register_frontend (uni0299_ioctl, i2c, (void *) state, &uni0299_info); } |