--- v4l-dvb/linux/drivers/media/dvb/frontends/cx22702.c 2006-06-30 19:59:10.000000000 +0400 +++ mp-bc1/linux/drivers/media/dvb/frontends/cx22702.c 2006-07-23 11:37:19.000000000 +0400 @@ -139,7 +139,8 @@ static int cx22702_set_inversion (struct } /* Retrieve the demod settings */ -static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_parameters *p) +static int cx22702_get_tps_compat(struct cx22702_state *state, + struct dvb_ofdm_parameters *p) { u8 val; @@ -193,6 +194,108 @@ static int cx22702_get_tps (struct cx227 return 0; } +static int cx22702_get_tps(struct cx22702_state *state, + struct dvbt_params *p) +{ + u8 val; + + /* Make sure the TPS regs are valid */ + if (!(cx22702_readreg(state, 0x0A) & 0x20)) + return -EAGAIN; + + val = cx22702_readreg(state, 0x01); + switch ((val &0x18) >> 3) { + case 0: + p->constellation = DVBFE_MOD_QPSK; + break; + case 1: + p->constellation = DVBFE_MOD_QAM16; + break; + case 2: + p->constellation = DVBFE_MOD_QAM64; + break; + } + switch (val & 0x07) { + case 0: + p->hierarchy = DVBFE_HIERARCHY_OFF; + break; + case 1: + p->alpha = DVBFE_ALPHA_1; + p->hierarchy = DVBFE_HIERARCHY_ON; + break; + case 2: + p->alpha = DVBFE_ALPHA_2; + p->hierarchy = DVBFE_HIERARCHY_ON; + break; + case 3: + p->alpha = DVBFE_ALPHA_4; + p->hierarchy = DVBFE_HIERARCHY_ON; + break; + } + + val = cx22702_readreg(state, 0x02); + switch ((val & 0x38) >> 3) { + case 0: + p->code_rate_HP = DVBFE_FEC_1_2; + break; + case 1: + p->code_rate_HP = DVBFE_FEC_2_3; + break; + case 2: + p->code_rate_HP = DVBFE_FEC_3_4; + break; + case 3: + p->code_rate_HP = DVBFE_FEC_5_6; + break; + case 4: + p->code_rate_HP = DVBFE_FEC_7_8; + break; + } + switch (val & 0x07) { + case 0: + p->code_rate_LP = DVBFE_FEC_1_2; + break; + case 1: + p->code_rate_LP = DVBFE_FEC_2_3; + break; + case 2: + p->code_rate_LP = DVBFE_FEC_3_4; + break; + case 3: + p->code_rate_LP = DVBFE_FEC_5_6; + break; + case 4: + p->code_rate_LP = DVBFE_FEC_7_8; + break; + } + + val = cx22702_readreg (state, 0x03); + switch ((val & 0x0c) >> 2) { + case 0: + p->guard_interval = DVBFE_GUARD_INTERVAL_1_32; + break; + case 1: + p->guard_interval = DVBFE_GUARD_INTERVAL_1_16; + break; + case 2: + p->guard_interval = DVBFE_GUARD_INTERVAL_1_8; + break; + case 3: + p->guard_interval = DVBFE_GUARD_INTERVAL_1_4; + break; + } + switch (val & 0x03) { + case 0: + p->transmission_mode = DVBFE_TRANSMISSION_MODE_2K; + break; + case 1: + p->transmission_mode = DVBFE_TRANSMISSION_MODE_8K; + break; + } + + return 0; +} + static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) { struct cx22702_state* state = fe->demodulator_priv; @@ -209,9 +312,10 @@ static int cx22702_set_tps (struct dvb_f u8 val; struct cx22702_state* state = fe->demodulator_priv; - 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); } /* set inversion */ @@ -447,7 +551,7 @@ static int cx22702_get_frontend(struct d u8 reg0C = cx22702_readreg (state, 0x0C); p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF; - return cx22702_get_tps (state, &p->u.ofdm); + return cx22702_get_tps_compat(state, &p->u.ofdm); } static int cx22702_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) @@ -493,6 +597,223 @@ error: return NULL; } +static struct dvbfe_info dvbt_info = { + .name = "Conexant CX22702 DVB-T", + .delivery = DVBFE_DELSYS_DVBT, + .delsys = { + .dvbt.modulation = DVBFE_MOD_OFDM, + .dvbt.stream_priority = DVBFE_STREAM_PRIORITY_HP | + DVBFE_STREAM_PRIORITY_LP, + }, + + .frequency_min = 177000000, + .frequency_max = 858000000, + .frequency_step = 166666, +}; + +static int cx22702_set_params(struct dvb_frontend* fe, + struct dvbfe_params *p) +{ + u8 val; + struct cx22702_state* state = fe->demodulator_priv; + + 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); + } + + /* set inversion */ + cx22702_set_inversion (state, p->inversion); + + /* set bandwidth */ + switch(p->delsys.dvbt.bandwidth) { + case DVBFE_BANDWIDTH_6_MHZ: + cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20 ); + break; + case DVBFE_BANDWIDTH_7_MHZ: + cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10 ); + break; + case DVBFE_BANDWIDTH_8_MHZ: + cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf ); + break; + default: + dprintk ("%s: invalid bandwidth\n",__FUNCTION__); + return -EINVAL; + } + + + p->delsys.dvbt.code_rate_LP = FEC_AUTO; //temp hack as manual not working + + /* use auto configuration? */ + if((p->delsys.dvbt.hierarchy == DVBFE_HIERARCHY_AUTO) || + (p->delsys.dvbt.constellation == DVBFE_MOD_QAMAUTO) || + (p->delsys.dvbt.code_rate_HP == DVBFE_FEC_AUTO) || + (p->delsys.dvbt.code_rate_LP == DVBFE_FEC_AUTO) || + (p->delsys.dvbt.guard_interval == DVBFE_GUARD_INTERVAL_AUTO) || + (p->delsys.dvbt.transmission_mode == DVBFE_TRANSMISSION_MODE_AUTO) ) { + + /* TPS Source - use hardware driven values */ + cx22702_writereg(state, 0x06, 0x10); + cx22702_writereg(state, 0x07, 0x9); + cx22702_writereg(state, 0x08, 0xC1); + cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc ); + cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 ); + cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ + dprintk("%s: Autodetecting\n",__FUNCTION__); + return 0; + } + + /* manually programmed values */ + val = 0; + switch (p->delsys.dvbt.constellation) { + case DVBFE_MOD_QPSK: + val = (val & 0xe7); + break; + case DVBFE_MOD_QAM16: + val = (val & 0xe7) | 0x08; + break; + case DVBFE_MOD_QAM64: + val = (val & 0xe7) | 0x10; + break; + default: + dprintk ("%s: invalid constellation\n",__FUNCTION__); + return -EINVAL; + } + switch (p->delsys.dvbt.hierarchy) { + case DVBFE_HIERARCHY_OFF: + val = (val & 0xf8); + break; + case DVBFE_HIERARCHY_ON: + switch (p->delsys.dvbt.alpha) { + case DVBFE_ALPHA_1: + val = (val & 0xf8) | 1; + break; + case DVBFE_ALPHA_2: + val = (val & 0xf8) | 2; + break; + case DVBFE_ALPHA_4: + val = (val & 0xf8) | 3 ; + break; + } + break; + case DVBFE_HIERARCHY_AUTO: + break; + default: + dprintk ("%s: invalid hierarchy\n", __FUNCTION__); + return -EINVAL; + } + cx22702_writereg (state, 0x06, val); + + val = 0; + switch (p->delsys.dvbt.code_rate_HP) { + case DVBFE_FEC_NONE: + case DVBFE_FEC_1_2: + val = (val & 0xc7); + break; + case DVBFE_FEC_2_3: + val = (val & 0xc7) | 0x08; + break; + case DVBFE_FEC_3_4: + val = (val & 0xc7) | 0x10; + break; + case DVBFE_FEC_5_6: + val = (val & 0xc7) | 0x18; + break; + case DVBFE_FEC_7_8: + val = (val & 0xc7) | 0x20; + break; + default: + dprintk ("%s: invalid code_rate_HP\n",__FUNCTION__); + return -EINVAL; + } + switch (p->delsys.dvbt.code_rate_LP) { + case DVBFE_FEC_NONE: + case DVBFE_FEC_1_2: + val = (val & 0xf8); + break; + case DVBFE_FEC_2_3: + val = (val & 0xf8) | 1; + break; + case DVBFE_FEC_3_4: + val = (val & 0xf8) | 2; + break; + case DVBFE_FEC_5_6: + val = (val & 0xf8) | 3; + break; + case DVBFE_FEC_7_8: + val = (val & 0xf8) | 4; + break; + default: + dprintk ("%s: invalid code_rate_LP\n",__FUNCTION__); + return -EINVAL; + } + cx22702_writereg (state, 0x07, val); + + val = 0; + switch (p->delsys.dvbt.guard_interval) { + case DVBFE_GUARD_INTERVAL_1_32: + val = (val & 0xf3); + break; + case DVBFE_GUARD_INTERVAL_1_16: + val = (val & 0xf3) | 0x04; + break; + case DVBFE_GUARD_INTERVAL_1_8: + val = (val & 0xf3) | 0x08; + break; + case DVBFE_GUARD_INTERVAL_1_4: + val = (val & 0xf3) | 0x0c; + break; + default: + dprintk ("%s: invalid guard_interval\n",__FUNCTION__); + return -EINVAL; + } + switch (p->delsys.dvbt.transmission_mode) { + case DVBFE_TRANSMISSION_MODE_2K: + val = (val & 0xfc); + break; + case DVBFE_TRANSMISSION_MODE_8K: + val = (val & 0xfc) | 1; + break; + default: + dprintk ("%s: invalid transmission_mode\n",__FUNCTION__); + return -EINVAL; + } + cx22702_writereg(state, 0x08, val); + cx22702_writereg(state, 0x0B, (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02 ); + cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 ); + + /* Begin channel aquisition */ + cx22702_writereg(state, 0x00, 0x01); + + return 0; +} + +static int cx22702_get_params(struct dvb_frontend* fe, + struct dvbfe_params *p) +{ + struct cx22702_state* state = fe->demodulator_priv; + + u8 reg0C = cx22702_readreg (state, 0x0C); + + p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF; + return cx22702_get_tps(state, &p->delsys.dvbt); +} + +static int cx22702_get_info(struct dvb_frontend *fe, struct dvbfe_info *fe_info) +{ + memcpy(fe_info, &dvbt_info, sizeof (dvbt_info)); + + return 0; +} + +static int cx22702_get_delsys(struct dvb_frontend *fe, enum dvbfe_delsys *fe_delsys) +{ + *fe_delsys = DVBFE_DELSYS_DVBT; + + return 0; +} + static struct dvb_frontend_ops cx22702_ops = { .info = { @@ -522,6 +843,11 @@ static struct dvb_frontend_ops cx22702_o .read_signal_strength = cx22702_read_signal_strength, .read_snr = cx22702_read_snr, .read_ucblocks = cx22702_read_ucblocks, + + .set_params = cx22702_set_params, + .get_params = cx22702_get_params, + .get_info = cx22702_get_info, + .get_delsys = cx22702_get_delsys, }; module_param(debug, int, 0644);
_______________________________________________ linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb