--- v4l-dvb/linux/drivers/media/dvb/frontends/sp8870.c 2006-06-30 19:59:10.000000000 +0400 +++ mp-bc1/linux/drivers/media/dvb/frontends/sp8870.c 2006-07-23 11:40:17.000000000 +0400 @@ -169,7 +169,7 @@ static int sp8870_read_data_valid_signal return (sp8870_readreg(state, 0x0D02) > 0); } -static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) +static int configure_reg0xc05_compat(struct dvb_frontend_parameters *p, u16 *reg0xc05) { int known_parameters = 1; @@ -240,6 +240,83 @@ static int configure_reg0xc05 (struct dv return 0; } +static int configure_reg0xc05(struct dvbfe_params *p, u16 *reg0xc05) +{ + int known_parameters = 1; + + *reg0xc05 = 0x000; + + switch (p->delsys.dvbt.constellation) { + case DVBFE_MOD_QPSK: + break; + case DVBFE_MOD_QAM16: + *reg0xc05 |= (1 << 10); + break; + case DVBFE_MOD_QAM64: + *reg0xc05 |= (2 << 10); + break; + case DVBFE_MOD_QAMAUTO: + known_parameters = 0; + break; + default: + return -EINVAL; + }; + + switch (p->delsys.dvbt.hierarchy) { + case DVBFE_HIERARCHY_OFF: + break; + case DVBFE_HIERARCHY_ON: + switch (p->delsys.dvbt.alpha) { + case DVBFE_ALPHA_1: + *reg0xc05 |= (1 << 7); + break; + case DVBFE_ALPHA_2: + *reg0xc05 |= (2 << 7); + break; + case DVBFE_ALPHA_4: + *reg0xc05 |= (3 << 7); + break; + default: + return -EINVAL; + } + break; + case HIERARCHY_AUTO: + known_parameters = 0; + break; + default: + return -EINVAL; + }; + + switch (p->delsys.dvbt.code_rate_HP) { + case DVBFE_FEC_1_2: + break; + case DVBFE_FEC_2_3: + *reg0xc05 |= (1 << 3); + break; + case DVBFE_FEC_3_4: + *reg0xc05 |= (2 << 3); + break; + case DVBFE_FEC_5_6: + *reg0xc05 |= (3 << 3); + break; + case DVBFE_FEC_7_8: + *reg0xc05 |= (4 << 3); + break; + case DVBFE_FEC_AUTO: + known_parameters = 0; + break; + default: + return -EINVAL; + }; + + if (known_parameters) + *reg0xc05 |= (2 << 1); /* use specified parameters */ + else + *reg0xc05 |= (1 << 1); /* enable autoprobing */ + + return 0; +} + static int sp8870_wake_up(struct sp8870_state* state) { // enable TS output and interface pins @@ -253,16 +330,17 @@ static int sp8870_set_frontend_parameter int err; u16 reg0xc05; - if ((err = configure_reg0xc05(p, ®0xc05))) + if ((err = configure_reg0xc05_compat(p, ®0xc05))) return err; // system controller stop sp8870_microcontroller_stop(state); // set tuner parameters - 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); } // sample rate correction bit [23..17] @@ -579,6 +657,97 @@ error: return NULL; } +static struct dvbfe_info dvbt_info = { + .name = "Spase SP8870 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 = 470000000, + .frequency_max = 860000000, + .frequency_step = 166666, +}; + +static int sp8870_set_params(struct dvb_frontend* fe, + struct dvbfe_params *p) +{ + struct sp8870_state* state = fe->demodulator_priv; + int err; + u16 reg0xc05; + + if ((err = configure_reg0xc05(p, ®0xc05))) + return err; + + // system controller stop + sp8870_microcontroller_stop(state); + + // set tuner parameters + 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); + } + + // sample rate correction bit [23..17] + sp8870_writereg(state, 0x0319, 0x000A); + + // sample rate correction bit [16..0] + sp8870_writereg(state, 0x031A, 0x0AAB); + + // integer carrier offset + sp8870_writereg(state, 0x0309, 0x0400); + + // fractional carrier offset + sp8870_writereg(state, 0x030A, 0x0000); + + // filter for 6/7/8 Mhz channel + if (p->delsys.dvbt.bandwidth == DVBFE_BANDWIDTH_6_MHZ) + sp8870_writereg(state, 0x0311, 0x0002); + else if (p->delsys.dvbt.bandwidth == DVBFE_BANDWIDTH_7_MHZ) + sp8870_writereg(state, 0x0311, 0x0001); + else + sp8870_writereg(state, 0x0311, 0x0000); + + // scan order: 2k first = 0x0000, 8k first = 0x0001 + if (p->delsys.dvbt.transmission_mode == DVBFE_TRANSMISSION_MODE_2K) + sp8870_writereg(state, 0x0338, 0x0000); + else + sp8870_writereg(state, 0x0338, 0x0001); + + sp8870_writereg(state, 0xc05, reg0xc05); + + // read status reg in order to clear pending irqs + sp8870_readreg(state, 0x200); + + // system controller start + sp8870_microcontroller_start(state); + + return 0; +} + + +static int sp8870_get_info(struct dvb_frontend *fe, struct dvbfe_info *fe_info) +{ + memcpy(fe_info, &dvbt_info, sizeof (dvbt_info)); + + return 0; +} + +static int sp8870_get_delsys(struct dvb_frontend *fe, enum dvbfe_delsys *fe_delsys) +{ + *fe_delsys = DVBFE_DELSYS_DVBT; + + return 0; +} + +static enum dvbfe_algo sp8870_get_algo(struct dvb_frontend *fe) +{ + return DVBFE_ALGO_RECOVERY; +} + static struct dvb_frontend_ops sp8870_ops = { .info = { @@ -608,6 +777,11 @@ static struct dvb_frontend_ops sp8870_op .read_ber = sp8870_read_ber, .read_signal_strength = sp8870_read_signal_strength, .read_ucblocks = sp8870_read_uncorrected_blocks, + + .set_params = sp8870_set_params, + .get_info = sp8870_get_info, + .get_delsys = sp8870_get_delsys, + .get_frontend_algo = sp8870_get_algo, }; module_param(debug, int, 0644);
_______________________________________________ linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb