--- v4l-dvb/linux/drivers/media/dvb/frontends/stv0299.c 2006-06-30 19:59:10.000000000 +0400 +++ mp-bc1/linux/drivers/media/dvb/frontends/stv0299.c 2006-07-23 11:40:35.000000000 +0400 @@ -130,7 +130,7 @@ static int stv0299_readregs (struct stv0 return ret == 2 ? 0 : ret; } -static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) +static int stv0299_set_FEC_compat(struct stv0299_state* state, fe_code_rate_t fec) { dprintk ("%s\n", __FUNCTION__); @@ -166,7 +166,43 @@ static int stv0299_set_FEC (struct stv02 } } -static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state) +static int stv0299_set_FEC(struct stv0299_state* state, enum dvbfe_fec fec) +{ + dprintk ("%s\n", __FUNCTION__); + + switch (fec) { + case DVBFE_FEC_AUTO: + { + return stv0299_writeregI (state, 0x31, 0x1f); + } + case DVBFE_FEC_1_2: + { + return stv0299_writeregI (state, 0x31, 0x01); + } + case DVBFE_FEC_2_3: + { + return stv0299_writeregI (state, 0x31, 0x02); + } + case DVBFE_FEC_3_4: + { + return stv0299_writeregI (state, 0x31, 0x04); + } + case DVBFE_FEC_5_6: + { + return stv0299_writeregI (state, 0x31, 0x08); + } + case DVBFE_FEC_7_8: + { + return stv0299_writeregI (state, 0x31, 0x10); + } + default: + { + return -EINVAL; + } + } +} + +static fe_code_rate_t stv0299_get_fec_compat(struct stv0299_state* state) { static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_1_2 }; @@ -183,6 +219,29 @@ static fe_code_rate_t stv0299_get_fec (s return fec_tab [index]; } +static fe_code_rate_t stv0299_get_fec(struct stv0299_state* state) +{ + static fe_code_rate_t fec_tab [] = { + DVBFE_FEC_2_3, + DVBFE_FEC_3_4, + DVBFE_FEC_5_6, + DVBFE_FEC_7_8, + DVBFE_FEC_1_2 + }; + + u8 index; + + dprintk ("%s\n", __FUNCTION__); + + index = stv0299_readreg (state, 0x1b); + index &= 0x7; + + if (index > 4) + return DVBFE_FEC_AUTO; + + return fec_tab[index]; +} + static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout) { unsigned long start = jiffies; @@ -546,12 +605,13 @@ static int stv0299_set_frontend(struct d if (state->config->invert) invval = (~invval) & 1; stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + if (fe->ops.tuner_ops.set_params_compat) { + fe->ops.tuner_ops.set_params_compat(fe, p); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); } - stv0299_set_FEC (state, p->u.qpsk.fec_inner); + stv0299_set_FEC_compat(state, p->u.qpsk.fec_inner); stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); stv0299_writeregI(state, 0x22, 0x00); stv0299_writeregI(state, 0x23, 0x00); @@ -582,7 +642,7 @@ static int stv0299_get_frontend(struct d if (state->config->invert) invval = (~invval) & 1; p->inversion = invval ? INVERSION_ON : INVERSION_OFF; - p->u.qpsk.fec_inner = stv0299_get_fec (state); + p->u.qpsk.fec_inner = stv0299_get_fec_compat(state); p->u.qpsk.symbol_rate = stv0299_get_symbolrate (state); return 0; @@ -616,12 +676,24 @@ static int stv0299_get_tune_settings(str struct stv0299_state* state = fe->demodulator_priv; fesettings->min_delay_ms = state->config->min_delay_ms; - if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) { - fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000; - fesettings->max_drift = 5000; + + if (fe->legacy) { + if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) { + fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000; + fesettings->max_drift = 5000; + } else { + fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000; + fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000; + } } else { - fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000; - fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000; + if (fesettings->fe_params.delsys.dvbs.symbol_rate < 10000000) { + fesettings->step_size = fesettings->fe_params.delsys.dvbs.symbol_rate / 32000; + fesettings->max_drift = 5000; + } else { + fesettings->step_size = fesettings->fe_params.delsys.dvbs.symbol_rate / 16000; + fesettings->max_drift = fesettings->fe_params.delsys.dvbs.symbol_rate / 2000; + } + } return 0; } @@ -672,8 +744,107 @@ error: return NULL; } -static struct dvb_frontend_ops stv0299_ops = { +static int stv0299_set_params(struct dvb_frontend* fe, struct dvbfe_params *p) +{ + struct stv0299_state* state = fe->demodulator_priv; + int invval = 0; + + dprintk ("%s: Frequency=[%d] SymbolRate=[%d]\n", + __func__, p->frequency, p->delsys.dvbs.symbol_rate); + + // set the inversion + if (p->inversion == INVERSION_OFF) + invval = 0; + else if (p->inversion == INVERSION_ON) + invval = 1; + else { + printk("stv0299 does not support auto-inversion\n"); + return -EINVAL; + } + if (state->config->invert) + invval = (~invval) & 1; + stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); + + if (fe->ops.tuner_ops.set_params) { + fe->ops.tuner_ops.set_params(fe, p); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + stv0299_set_FEC(state, p->delsys.dvbs.fec); + stv0299_set_symbolrate(fe, p->delsys.dvbs.symbol_rate); + stv0299_writeregI(state, 0x22, 0x00); + stv0299_writeregI(state, 0x23, 0x00); + + state->tuner_frequency = p->frequency; + state->fec_inner = p->delsys.dvbs.fec; + state->symbol_rate = p->delsys.dvbs.symbol_rate; + + return 0; +} + +static int stv0299_get_params(struct dvb_frontend* fe, struct dvbfe_params *p) +{ + struct stv0299_state* state = fe->demodulator_priv; + s32 derot_freq; + int invval; + derot_freq = (s32)(s16) ((stv0299_readreg (state, 0x22) << 8) + | stv0299_readreg (state, 0x23)); + + derot_freq *= (state->config->mclk >> 16); + derot_freq += 500; + derot_freq /= 1000; + + p->frequency += derot_freq; + + invval = stv0299_readreg(state, 0x0c) & 1; + if (state->config->invert) + invval = (~invval) & 1; + p->inversion = invval ? INVERSION_ON : INVERSION_OFF; + + p->delsys.dvbs.fec = stv0299_get_fec(state); + p->delsys.dvbs.symbol_rate = stv0299_get_symbolrate(state); + + return 0; +} + + +static struct dvbfe_info dvbs_info = { + .name = "STV0299 DVB-S", + .delivery = DVBFE_DELSYS_DVBS, + .delsys = { + .dvbs.modulation = DVBFE_MOD_QPSK, + .dvbs.fec = DVBFE_FEC_1_2 | DVBFE_FEC_2_3 | + DVBFE_FEC_3_4 | DVBFE_FEC_5_6 | + DVBFE_FEC_7_8 | DVBFE_FEC_AUTO + }, + + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_step = 125, + .frequency_tolerance = 0, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .symbol_rate_tolerance = 500 +}; + +static int stv0299_get_info(struct dvb_frontend *fe, struct dvbfe_info *fe_info) +{ + memcpy(fe_info, &dvbs_info, sizeof (dvbs_info)); + + return 0; +} + +static int stv0299_get_delsys(struct dvb_frontend *fe, enum dvbfe_delsys *fe_delsys) +{ + *fe_delsys = DVBFE_DELSYS_DVBS; + + return 0; +} + +static struct dvb_frontend_ops stv0299_ops = { + /* Info is deprecated */ .info = { .name = "ST STV0299 DVB-S", .type = FE_QPSK, @@ -711,6 +882,11 @@ static struct dvb_frontend_ops stv0299_o .set_tone = stv0299_set_tone, .set_voltage = stv0299_set_voltage, .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd, + + .set_params = stv0299_set_params, + .get_params = stv0299_get_params, + .get_info = stv0299_get_info, + .get_delsys = stv0299_get_delsys, }; module_param(debug_legacy_dish_switch, int, 0444);
_______________________________________________ linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb