--- v4l-dvb/linux/drivers/media/dvb/frontends/mt352.c 2006-06-30 19:59:10.000000000 +0400 +++ mp-bc1/linux/drivers/media/dvb/frontends/mt352.c 2006-07-23 11:39:11.000000000 +0400 @@ -287,8 +287,8 @@ static int mt352_set_parameters(struct d mt352_calc_input_freq(state, buf+6); if (state->config.no_tuner) { - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); + if (fe->ops.tuner_ops.set_params_compat) { + fe->ops.tuner_ops.set_params_compat(fe, param); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } @@ -296,8 +296,8 @@ static int mt352_set_parameters(struct d mt352_write(fe, buf, 8); mt352_write(fe, fsm_go, 2); } else { - if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5); + if (fe->ops.tuner_ops.calc_regs_compat) { + fe->ops.tuner_ops.calc_regs_compat(fe, param, buf+8, 5); buf[8] <<= 1; mt352_write(fe, buf, sizeof(buf)); mt352_write(fe, tuner_go, 2); @@ -563,6 +563,296 @@ error: return NULL; } +static struct dvbfe_info dvbt_info = { + .name = "Zarlink MT352 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 mt352_set_params(struct dvb_frontend* fe, + struct dvbfe_params *param) +{ + struct mt352_state* state = fe->demodulator_priv; + unsigned char buf[13]; + static unsigned char tuner_go[] = { 0x5d, 0x01 }; + static unsigned char fsm_go[] = { 0x5e, 0x01 }; + unsigned int tps = 0; + struct dvbt_params *op = ¶m->delsys.dvbt; + + switch (op->code_rate_HP) { + case DVBFE_FEC_2_3: + tps |= (1 << 7); + break; + case DVBFE_FEC_3_4: + tps |= (2 << 7); + break; + case DVBFE_FEC_5_6: + tps |= (3 << 7); + break; + case DVBFE_FEC_7_8: + tps |= (4 << 7); + break; + case DVBFE_FEC_1_2: + case DVBFE_FEC_AUTO: + break; + default: + return -EINVAL; + } + + switch (op->code_rate_LP) { + case DVBFE_FEC_2_3: + tps |= (1 << 4); + break; + case DVBFE_FEC_3_4: + tps |= (2 << 4); + break; + case DVBFE_FEC_5_6: + tps |= (3 << 4); + break; + case DVBFE_FEC_7_8: + tps |= (4 << 4); + break; + case DVBFE_FEC_1_2: + case DVBFE_FEC_AUTO: + break; + case DVBFE_FEC_NONE: + if (op->hierarchy == DVBFE_HIERARCHY_AUTO || + op->hierarchy == DVBFE_HIERARCHY_OFF) + break; + default: + return -EINVAL; + } + + switch (op->constellation) { + case DVBFE_MOD_QPSK: + break; + case DVBFE_MOD_QAMAUTO: + case DVBFE_MOD_QAM16: + tps |= (1 << 13); + break; + case DVBFE_MOD_QAM64: + tps |= (2 << 13); + break; + default: + return -EINVAL; + } + + switch (op->transmission_mode) { + case DVBFE_TRANSMISSION_MODE_2K: + case DVBFE_TRANSMISSION_MODE_AUTO: + break; + case DVBFE_TRANSMISSION_MODE_8K: + tps |= (1 << 0); + break; + default: + return -EINVAL; + } + + switch (op->guard_interval) { + case DVBFE_GUARD_INTERVAL_1_32: + case DVBFE_GUARD_INTERVAL_AUTO: + break; + case DVBFE_GUARD_INTERVAL_1_16: + tps |= (1 << 2); + break; + case DVBFE_GUARD_INTERVAL_1_8: + tps |= (2 << 2); + break; + case DVBFE_GUARD_INTERVAL_1_4: + tps |= (3 << 2); + break; + default: + return -EINVAL; + } + + switch (op->hierarchy) { + case DVBFE_HIERARCHY_AUTO: + case DVBFE_HIERARCHY_OFF: + break; + case DVBFE_HIERARCHY_ON: + switch (op->alpha) { + case DVBFE_ALPHA_1: + tps |= (1 << 10); + break; + case DVBFE_ALPHA_2: + tps |= (2 << 10); + break; + case DVBFE_ALPHA_4: + tps |= (3 << 10); + break; + } + break; + default: + return -EINVAL; + } + + buf[0] = TPS_GIVEN_1; /* TPS_GIVEN_1 and following registers */ + + buf[1] = msb(tps); /* TPS_GIVEN_(1|0) */ + buf[2] = lsb(tps); + + buf[3] = 0x50; // old +// buf[3] = 0xf4; // pinnacle + + mt352_calc_nominal_rate(state, op->bandwidth, buf+4); + mt352_calc_input_freq(state, buf+6); + + if (state->config.no_tuner) { + if (fe->ops.tuner_ops.set_params) { + fe->ops.tuner_ops.set_params(fe, param); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + mt352_write(fe, buf, 8); + mt352_write(fe, fsm_go, 2); + } else { + if (fe->ops.tuner_ops.calc_regs) { + fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5); + buf[8] <<= 1; + mt352_write(fe, buf, sizeof (buf)); + mt352_write(fe, tuner_go, 2); + } + } + + return 0; +} + +static int mt352_get_params(struct dvb_frontend* fe, + struct dvbfe_params *param) +{ + struct mt352_state* state = fe->demodulator_priv; + u16 tps; + u16 div; + u8 trl; + struct dvbt_params *op = ¶m->delsys.dvbt; + enum dvbfe_fec tps_fec_to_api[8] = { + DVBFE_FEC_1_2, + DVBFE_FEC_2_3, + DVBFE_FEC_3_4, + DVBFE_FEC_5_6, + DVBFE_FEC_7_8, + DVBFE_FEC_AUTO, + DVBFE_FEC_AUTO, + DVBFE_FEC_AUTO + }; + + if ( (mt352_read_register(state,0x00) & 0xC0) != 0xC0 ) + return -EINVAL; + + /* Use TPS_RECEIVED-registers, not the TPS_CURRENT-registers because + * the mt352 sometimes works with the wrong parameters + */ + tps = (mt352_read_register(state, TPS_RECEIVED_1) << 8) | mt352_read_register(state, TPS_RECEIVED_0); + div = (mt352_read_register(state, CHAN_START_1) << 8) | mt352_read_register(state, CHAN_START_0); + trl = mt352_read_register(state, TRL_NOMINAL_RATE_1); + + op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7]; + op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7]; + + switch ( (tps >> 13) & 3) { + case 0: + op->constellation = DVBFE_MOD_QPSK; + break; + case 1: + op->constellation = DVBFE_MOD_QAM16; + break; + case 2: + op->constellation = DVBFE_MOD_QAM64; + break; + default: + op->constellation = DVBFE_MOD_QAMAUTO; + break; + } + + op->transmission_mode = (tps & 0x01) ? DVBFE_TRANSMISSION_MODE_8K : DVBFE_TRANSMISSION_MODE_2K; + + switch ((tps >> 2) & 3) { + case 0: + op->guard_interval = DVBFE_GUARD_INTERVAL_1_32; + break; + case 1: + op->guard_interval = DVBFE_GUARD_INTERVAL_1_16; + break; + case 2: + op->guard_interval = DVBFE_GUARD_INTERVAL_1_8; + break; + case 3: + op->guard_interval = DVBFE_GUARD_INTERVAL_1_4; + break; + default: + op->guard_interval = DVBFE_GUARD_INTERVAL_AUTO; + break; + } + + switch ((tps >> 10) & 7) { + case 0: + op->hierarchy = DVBFE_HIERARCHY_OFF; + break; + case 1: + op->alpha = DVBFE_ALPHA_1; + op->hierarchy = DVBFE_HIERARCHY_ON; + break; + case 2: + op->alpha = DVBFE_ALPHA_2; + op->hierarchy = DVBFE_HIERARCHY_ON; + break; + case 3: + op->alpha = DVBFE_ALPHA_4; + op->hierarchy = DVBFE_HIERARCHY_ON; + break; + default: + op->hierarchy = DVBFE_HIERARCHY_AUTO; + break; + } + + param->frequency = (500 * (div - IF_FREQUENCYx6) ) / 3 * 1000; + + if (trl == 0x72) + op->bandwidth = DVBFE_BANDWIDTH_8_MHZ; + else if (trl == 0x64) + op->bandwidth = DVBFE_BANDWIDTH_7_MHZ; + else + op->bandwidth = DVBFE_BANDWIDTH_6_MHZ; + + + if (mt352_read_register(state, STATUS_2) & 0x02) + param->inversion = INVERSION_OFF; + else + param->inversion = INVERSION_ON; + + return 0; +} + +static int mt352_get_info(struct dvb_frontend *fe, + struct dvbfe_info *fe_info) +{ + memcpy(fe_info, &dvbt_info, sizeof (dvbt_info)); + + return 0; +} + +static int mt352_get_delsys(struct dvb_frontend *fe, + enum dvbfe_delsys *fe_delsys) +{ + *fe_delsys = DVBFE_DELSYS_DVBT; + + return 0; +} + +static enum dvbfe_algo mt352_get_algo(struct dvb_frontend *fe) +{ + return DVBFE_ALGO_RECOVERY; +} + static struct dvb_frontend_ops mt352_ops = { .info = { @@ -595,6 +885,12 @@ static struct dvb_frontend_ops mt352_ops .read_signal_strength = mt352_read_signal_strength, .read_snr = mt352_read_snr, .read_ucblocks = mt352_read_ucblocks, + + .set_params = mt352_set_params, + .get_params = mt352_get_params, + .get_info = mt352_get_info, + .get_delsys = mt352_get_delsys, + .get_frontend_algo = mt352_get_algo, }; module_param(debug, int, 0644);
_______________________________________________ linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb