PATCH 14/44 multiproto + backward compatibility [DIB3000MC]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





--- v4l-dvb/linux/drivers/media/dvb/frontends/dib3000mc.c	2006-06-30 19:59:10.000000000 +0400
+++ mp-bc1/linux/drivers/media/dvb/frontends/dib3000mc.c	2006-07-23 11:38:01.000000000 +0400
@@ -49,8 +49,10 @@ MODULE_PARM_DESC(debug, "set debugging l
 #define deb_getf(args...) dprintk(0x08,args)
 #define deb_stat(args...) dprintk(0x10,args)
 
-static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode,
-	fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth)
+static int dib3000mc_set_impulse_noise_compat(struct dib3000_state * state,
+					      int mode,
+					      fe_transmit_mode_t transmission_mode,
+					      fe_bandwidth_t bandwidth)
 {
 	switch (transmission_mode) {
 		case TRANSMISSION_MODE_2K:
@@ -95,7 +97,55 @@ static int dib3000mc_set_impulse_noise(s
 	return 0;
 }
 
-static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset,
+static int dib3000mc_set_impulse_noise(struct dib3000_state * state,
+				       int mode,
+				       enum dvbfe_transmission_mode transmission_mode,
+				       enum dvbfe_bandwidth bandwidth)
+{
+	switch (transmission_mode) {
+	case DVBFE_TRANSMISSION_MODE_2K:
+		wr_foreach(dib3000mc_reg_fft, dib3000mc_fft_modes[0]);
+		break;
+	case DVBFE_TRANSMISSION_MODE_8K:
+		wr_foreach(dib3000mc_reg_fft, dib3000mc_fft_modes[1]);
+		break;
+	default:
+		break;
+	}
+
+	switch (bandwidth) {
+/*	case BANDWIDTH_5_MHZ:
+		wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[0]);
+		break; */
+	case DVBFE_BANDWIDTH_6_MHZ:
+		wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[1]);
+		break;
+	case DVBFE_BANDWIDTH_7_MHZ:
+		wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[2]);
+		break;
+	case DVBFE_BANDWIDTH_8_MHZ:
+		wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[3]);
+		break;
+	default:
+		break;
+	}
+
+	switch (mode) {
+	case 0: /* no impulse */ /* fall through */
+		wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[0]);
+		break;
+	case 1: /* new algo */
+		wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[1]);
+		set_or(DIB3000MC_REG_IMP_NOISE_55,DIB3000MC_IMP_NEW_ALGO(0)); /* gives 1<<10 */
+		break;
+	default: /* old algo */
+		wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[3]);
+		break;
+	}
+	return 0;
+}
+
+static int dib3000mc_set_timing_compat(struct dib3000_state *state, int upd_offset,
 		fe_transmit_mode_t fft, fe_bandwidth_t bw)
 {
 	u16 timf_msb,timf_lsb;
@@ -149,7 +199,69 @@ static int dib3000mc_set_timing(struct d
 	return 0;
 }
 
-static int dib3000mc_init_auto_scan(struct dib3000_state *state, fe_bandwidth_t bw, int boost)
+static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset,
+		fe_transmit_mode_t fft,  enum dvbfe_bandwidth bw)
+{
+	u16 timf_msb,timf_lsb;
+	s32 tim_offset,tim_sgn;
+	u64 comp1,comp2,comp=0;
+
+	switch (bw) {
+	case DVBFE_BANDWIDTH_8_MHZ:
+		comp = DIB3000MC_CLOCK_REF * 8;
+		break;
+	case DVBFE_BANDWIDTH_7_MHZ:
+		comp = DIB3000MC_CLOCK_REF * 7;
+		break;
+	case DVBFE_BANDWIDTH_6_MHZ:
+		comp = DIB3000MC_CLOCK_REF * 6;
+		break;
+	default:
+		err("unknown bandwidth (%d)", bw);
+		break;
+	}
+	timf_msb = (comp >> 16) & 0xff;
+	timf_lsb = (comp & 0xffff);
+
+	// Update the timing offset ;
+	if (upd_offset > 0) {
+		if (!state->timing_offset_comp_done) {
+			msleep(200);
+			state->timing_offset_comp_done = 1;
+		}
+		tim_offset = rd(DIB3000MC_REG_TIMING_OFFS_MSB);
+		if ((tim_offset & 0x2000) == 0x2000)
+			tim_offset |= 0xC000;
+		if (fft == DVBFE_TRANSMISSION_MODE_2K)
+			tim_offset <<= 2;
+		state->timing_offset += tim_offset;
+	}
+
+	tim_offset = state->timing_offset;
+	if (tim_offset < 0) {
+		tim_sgn = 1;
+		tim_offset = -tim_offset;
+	} else
+		tim_sgn = 0;
+
+	comp1 =  (u32)tim_offset * (u32)timf_lsb ;
+	comp2 =  (u32)tim_offset * (u32)timf_msb ;
+	comp  = ((comp1 >> 16) + comp2) >> 7;
+
+	if (tim_sgn == 0)
+		comp = (u32)(timf_msb << 16) + (u32) timf_lsb + comp;
+	else
+		comp = (u32)(timf_msb << 16) + (u32) timf_lsb - comp ;
+
+	timf_msb = (comp >> 16) & 0xff;
+	timf_lsb = comp & 0xffff;
+
+	wr(DIB3000MC_REG_TIMING_FREQ_MSB,timf_msb);
+	wr(DIB3000MC_REG_TIMING_FREQ_LSB,timf_lsb);
+	return 0;
+}
+
+static int dib3000mc_init_auto_scan_compat(struct dib3000_state *state, fe_bandwidth_t bw, int boost)
 {
 	if (boost) {
 		wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_ON);
@@ -185,7 +297,43 @@ static int dib3000mc_init_auto_scan(stru
 	return 0;
 }
 
-static int dib3000mc_set_adp_cfg(struct dib3000_state *state, fe_modulation_t con)
+static int dib3000mc_init_auto_scan(struct dib3000_state *state, enum dvbfe_bandwidth bw, int boost)
+{
+	if (boost) {
+		wr(DIB3000MC_REG_SCAN_BOOST, DIB3000MC_SCAN_BOOST_ON);
+	} else {
+		wr(DIB3000MC_REG_SCAN_BOOST, DIB3000MC_SCAN_BOOST_OFF);
+	}
+	switch (bw) {
+	case DVBFE_BANDWIDTH_8_MHZ:
+		wr_foreach(dib3000mc_reg_bandwidth, dib3000mc_bandwidth_8mhz);
+		break;
+	case DVBFE_BANDWIDTH_7_MHZ:
+		wr_foreach(dib3000mc_reg_bandwidth, dib3000mc_bandwidth_7mhz);
+		break;
+	case DVBFE_BANDWIDTH_6_MHZ:
+		wr_foreach(dib3000mc_reg_bandwidth, dib3000mc_bandwidth_6mhz);
+		break;
+/*	case BANDWIDTH_5_MHZ:
+		wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_5mhz);
+		break;*/
+	case BANDWIDTH_AUTO:
+		return -EOPNOTSUPP;
+	default:
+		err("unknown bandwidth value (%d).",bw);
+		return -EINVAL;
+}
+	if (boost) {
+		u32 timeout = (rd(DIB3000MC_REG_BW_TIMOUT_MSB) << 16) +
+			rd(DIB3000MC_REG_BW_TIMOUT_LSB);
+		timeout *= 85; timeout >>= 7;
+		wr(DIB3000MC_REG_BW_TIMOUT_MSB,(timeout >> 16) & 0xffff);
+		wr(DIB3000MC_REG_BW_TIMOUT_LSB,timeout & 0xffff);
+	}
+	return 0;
+}
+
+static int dib3000mc_set_adp_cfg_compat(struct dib3000_state *state, fe_modulation_t con)
 {
 	switch (con) {
 		case QAM_64:
@@ -206,7 +354,29 @@ static int dib3000mc_set_adp_cfg(struct 
 	return 0;
 }
 
-static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val)
+static int dib3000mc_set_adp_cfg(struct dib3000_state *state,
+				 enum dvbfe_modulation con)
+{
+	switch (con) {
+	case DVBFE_MOD_QAM64:
+		wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[2]);
+		break;
+	case DVBFE_MOD_QAM16:
+		wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]);
+		break;
+	case DVBFE_MOD_QPSK:
+		wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[0]);
+		break;
+	case DVBFE_MOD_QAMAUTO:
+		break;
+	default:
+		warn("unkown constellation.");
+		break;
+	}
+	return 0;
+}
+
+static int dib3000mc_set_general_cfg_compat(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val)
 {
 	struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
 	fe_code_rate_t fe_cr = FEC_NONE;
@@ -293,6 +463,145 @@ static int dib3000mc_set_general_cfg(str
 	return 0;
 }
 
+static int dib3000mc_set_general_cfg(struct dib3000_state *state,
+				     struct dvbfe_params *fep,
+				     int *auto_val)
+{
+	struct dvbt_params *dvbt = &fep->delsys.dvbt;
+	enum dvbfe_fec fe_cr = DVBFE_FEC_NONE;
+	u8 fft = 0, guard = 0, qam = 0, alpha = 0, sel_hp = 0, cr = 0, hrch = 0;
+	int seq;
+
+	switch (dvbt->transmission_mode) {
+	case DVBFE_TRANSMISSION_MODE_2K:
+		fft = DIB3000_TRANSMISSION_MODE_2K;
+		break;
+	case DVBFE_TRANSMISSION_MODE_8K:
+		fft = DIB3000_TRANSMISSION_MODE_8K;
+		break;
+	case DVBFE_TRANSMISSION_MODE_AUTO:
+		break;
+	default:
+		return -EINVAL;
+	}
+	switch (dvbt->guard_interval) {
+	case DVBFE_GUARD_INTERVAL_1_32:
+		guard = DIB3000_GUARD_TIME_1_32;
+		break;
+	case DVBFE_GUARD_INTERVAL_1_16:
+		guard = DIB3000_GUARD_TIME_1_16;
+		break;
+	case DVBFE_GUARD_INTERVAL_1_8:
+		guard = DIB3000_GUARD_TIME_1_8;
+		break;
+	case DVBFE_GUARD_INTERVAL_1_4:
+		guard = DIB3000_GUARD_TIME_1_4;
+		break;
+	case DVBFE_GUARD_INTERVAL_AUTO:
+		break;
+	default:
+		return -EINVAL;
+	}
+	switch (dvbt->constellation) {
+	case DVBFE_MOD_QPSK:
+		qam = DIB3000_CONSTELLATION_QPSK;
+		break;
+	case DVBFE_MOD_QAM16:
+		qam = DIB3000_CONSTELLATION_16QAM;
+		break;
+	case DVBFE_MOD_QAM64:
+		qam = DIB3000_CONSTELLATION_64QAM;
+		break;
+	case DVBFE_MOD_QAMAUTO:
+		break;
+	default:
+		return -EINVAL;
+	}
+	switch (dvbt->hierarchy) {
+	case DVBFE_HIERARCHY_OFF: /* fall through */
+		break;
+	case DVBFE_HIERARCHY_ON:
+		switch (dvbt->alpha) {
+		case DVBFE_ALPHA_1:
+			alpha = DIB3000_ALPHA_1;
+			break;
+		case DVBFE_ALPHA_2:
+			alpha = DIB3000_ALPHA_2;
+			break;
+		case DVBFE_ALPHA_4:
+			alpha = DIB3000_ALPHA_4;
+			break;
+		}
+		break;
+	case DVBFE_HIERARCHY_AUTO:
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (dvbt->hierarchy == DVBFE_HIERARCHY_OFF) {
+		hrch   = DIB3000_HRCH_OFF;
+		sel_hp = DIB3000_SELECT_HP;
+		fe_cr  = dvbt->code_rate_HP;
+	} else if (dvbt->hierarchy != DVBFE_HIERARCHY_AUTO) {
+		hrch   = DIB3000_HRCH_ON;
+		sel_hp = DIB3000_SELECT_LP;
+		fe_cr  = dvbt->code_rate_LP;
+	}
+	switch (fe_cr) {
+	case DVBFE_FEC_1_2:
+		cr = DIB3000_FEC_1_2;
+		break;
+	case DVBFE_FEC_2_3:
+		cr = DIB3000_FEC_2_3;
+		break;
+	case DVBFE_FEC_3_4:
+		cr = DIB3000_FEC_3_4;
+		break;
+	case DVBFE_FEC_5_6:
+		cr = DIB3000_FEC_5_6;
+		break;
+	case DVBFE_FEC_7_8:
+		cr = DIB3000_FEC_7_8;
+		break;
+	case DVBFE_FEC_NONE:
+		break;
+	case DVBFE_FEC_AUTO:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	wr(DIB3000MC_REG_DEMOD_PARM, DIB3000MC_DEMOD_PARM(alpha, qam, guard, fft));
+	wr(DIB3000MC_REG_HRCH_PARM,DIB3000MC_HRCH_PARM(sel_hp, cr, hrch));
+
+	switch (fep->inversion) {
+	case INVERSION_OFF:
+		wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
+		break;
+	case INVERSION_AUTO: /* fall through */
+	case INVERSION_ON:
+		wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_ON);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	seq = dib3000_seq
+		[dvbt->transmission_mode == DVBFE_TRANSMISSION_MODE_AUTO]
+		[dvbt->guard_interval == DVBFE_GUARD_INTERVAL_AUTO]
+		[fep->inversion == INVERSION_AUTO];
+
+	deb_setf("seq? %d\n", seq);
+	wr(DIB3000MC_REG_SEQ_TPS, DIB3000MC_SEQ_TPS(seq,1));
+	*auto_val = dvbt->constellation == DVBFE_MOD_QAMAUTO			||
+		    dvbt->hierarchy == DVBFE_HIERARCHY_AUTO			||
+		    dvbt->guard_interval == DVBFE_GUARD_INTERVAL_AUTO		||
+		    dvbt->transmission_mode == DVBFE_TRANSMISSION_MODE_AUTO	||
+		    fe_cr == DVBFE_FEC_AUTO					||
+		    fep->inversion == INVERSION_AUTO;
+	return 0;
+}
+
 static int dib3000mc_get_frontend(struct dvb_frontend* fe,
 				  struct dvb_frontend_parameters *fep)
 {
@@ -454,6 +763,170 @@ static int dib3000mc_get_frontend(struct
 	return 0;
 }
 
+static int dib3000mc_get_params(struct dvb_frontend *fe,
+				struct dvbfe_params *fep)
+{
+	struct dib3000_state *state = fe->demodulator_priv;
+	struct dvbt_params *dvbt = &fep->delsys.dvbt;
+	enum dvbfe_fec *cr;
+	u16 tps_val,cr_val;
+	int inv_test1,inv_test2;
+	u32 dds_val, threshold = 0x1000000;
+
+	if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507))
+		return 0;
+
+	dds_val = (rd(DIB3000MC_REG_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB);
+	deb_getf("DDS_FREQ: %6x\n",dds_val);
+	if (dds_val < threshold)
+		inv_test1 = 0;
+	else if (dds_val == threshold)
+		inv_test1 = 1;
+	else
+		inv_test1 = 2;
+
+	dds_val = (rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB);
+	deb_getf("DDS_SET_FREQ: %6x\n",dds_val);
+	if (dds_val < threshold)
+		inv_test2 = 0;
+	else if (dds_val == threshold)
+		inv_test2 = 1;
+	else
+		inv_test2 = 2;
+
+	fep->inversion =
+		((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
+		((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
+		INVERSION_ON : INVERSION_OFF;
+
+	deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);
+
+	fep->frequency = state->last_tuned_freq;
+	fep->delsys.dvbt.bandwidth= state->last_tuned_bw;
+
+	tps_val = rd(DIB3000MC_REG_TUNING_PARM);
+
+	switch (DIB3000MC_TP_QAM(tps_val)) {
+	case DIB3000_CONSTELLATION_QPSK:
+		deb_getf("QPSK ");
+		dvbt->constellation = DVBFE_MOD_QPSK;
+		break;
+	case DIB3000_CONSTELLATION_16QAM:
+		deb_getf("QAM16 ");
+		dvbt->constellation = DVBFE_MOD_QAM16;
+		break;
+	case DIB3000_CONSTELLATION_64QAM:
+		deb_getf("QAM64 ");
+		dvbt->constellation = DVBFE_MOD_QAM64;
+		break;
+	default:
+		err("Unexpected constellation returned by TPS (%d)", tps_val);
+		break;
+	}
+
+	if (DIB3000MC_TP_HRCH(tps_val)) {
+		deb_getf("HRCH ON ");
+		cr = &dvbt->code_rate_LP;
+		dvbt->code_rate_HP = DVBFE_FEC_NONE;
+		switch (DIB3000MC_TP_ALPHA(tps_val)) {
+		case DIB3000_ALPHA_0:
+			deb_getf("HIERARCHY_NONE ");
+			dvbt->hierarchy = DVBFE_HIERARCHY_OFF;
+			break;
+		case DIB3000_ALPHA_1:
+			deb_getf("HIERARCHY_1 ");
+			dvbt->hierarchy = DVBFE_HIERARCHY_ON;
+			dvbt->alpha = DVBFE_ALPHA_1;
+			break;
+		case DIB3000_ALPHA_2:
+			deb_getf("HIERARCHY_2 ");
+			dvbt->hierarchy = DVBFE_HIERARCHY_ON;
+			dvbt->alpha = DVBFE_ALPHA_2;
+			break;
+		case DIB3000_ALPHA_4:
+			deb_getf("HIERARCHY_4 ");
+			dvbt->hierarchy = DVBFE_HIERARCHY_ON;
+			dvbt->alpha = DVBFE_ALPHA_4;
+			break;
+		default:
+			err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
+			break;
+		}
+		cr_val = DIB3000MC_TP_FEC_CR_LP(tps_val);
+	} else {
+		deb_getf("HRCH OFF ");
+		cr = &dvbt->code_rate_HP;
+		dvbt->code_rate_LP = DVBFE_FEC_NONE;
+		dvbt->hierarchy = DVBFE_HIERARCHY_OFF;
+		cr_val = DIB3000MC_TP_FEC_CR_HP(tps_val);
+	}
+
+	switch (cr_val) {
+	case DIB3000_FEC_1_2:
+		deb_getf("FEC_1_2 ");
+		*cr = DVBFE_FEC_1_2;
+		break;
+	case DIB3000_FEC_2_3:
+		deb_getf("FEC_2_3 ");
+		*cr = DVBFE_FEC_2_3;
+		break;
+	case DIB3000_FEC_3_4:
+		deb_getf("FEC_3_4 ");
+		*cr = DVBFE_FEC_3_4;
+		break;
+	case DIB3000_FEC_5_6:
+		deb_getf("FEC_5_6 ");
+		*cr = DVBFE_FEC_4_5;
+		break;
+	case DIB3000_FEC_7_8:
+		deb_getf("FEC_7_8 ");
+		*cr = DVBFE_FEC_7_8;
+		break;
+	default:
+		err("Unexpected FEC returned by TPS (%d)", tps_val);
+		break;
+	}
+
+	switch (DIB3000MC_TP_GUARD(tps_val)) {
+	case DIB3000_GUARD_TIME_1_32:
+		deb_getf("GUARD_INTERVAL_1_32 ");
+		dvbt->guard_interval = DVBFE_GUARD_INTERVAL_1_32;
+		break;
+	case DIB3000_GUARD_TIME_1_16:
+		deb_getf("GUARD_INTERVAL_1_16 ");
+		dvbt->guard_interval = DVBFE_GUARD_INTERVAL_1_16;
+		break;
+	case DIB3000_GUARD_TIME_1_8:
+		deb_getf("GUARD_INTERVAL_1_8 ");
+		dvbt->guard_interval = DVBFE_GUARD_INTERVAL_1_8;
+		break;
+	case DIB3000_GUARD_TIME_1_4:
+		deb_getf("GUARD_INTERVAL_1_4 ");
+		dvbt->guard_interval = DVBFE_GUARD_INTERVAL_1_4;
+		break;
+	default:
+		err("Unexpected Guard Time returned by TPS (%d)", tps_val);
+		break;
+	}
+
+	switch (DIB3000MC_TP_FFT(tps_val)) {
+	case DIB3000_TRANSMISSION_MODE_2K:
+		deb_getf("TRANSMISSION_MODE_2K ");
+		dvbt->transmission_mode = DVBFE_TRANSMISSION_MODE_2K;
+		break;
+	case DIB3000_TRANSMISSION_MODE_8K:
+		deb_getf("TRANSMISSION_MODE_8K ");
+		dvbt->transmission_mode = DVBFE_TRANSMISSION_MODE_8K;
+		break;
+	default:
+		err("unexpected transmission mode return by TPS (%d)", tps_val);
+		break;
+	}
+	deb_getf("\n");
+
+	return 0;
+}
+
 static int dib3000mc_set_frontend(struct dvb_frontend* fe,
 				  struct dvb_frontend_parameters *fep, int tuner)
 {
@@ -462,14 +935,15 @@ static int dib3000mc_set_frontend(struct
 	int search_state,auto_val;
 	u16 val;
 
-	if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */
-		fe->ops.tuner_ops.set_params(fe, fep);
-		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+	if (tuner && fe->ops.tuner_ops.set_params_compat) { /* initial call from dvb */
+		fe->ops.tuner_ops.set_params_compat(fe, fep);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
 
 		state->last_tuned_freq = fep->frequency;
 	//	if (!scanboost) {
-			dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth);
-			dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0);
+			dib3000mc_set_timing_compat(state,0,ofdm->transmission_mode,ofdm->bandwidth);
+			dib3000mc_init_auto_scan_compat(state, ofdm->bandwidth, 0);
 			state->last_tuned_bw = ofdm->bandwidth;
 
 			wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
@@ -491,7 +965,7 @@ static int dib3000mc_set_frontend(struct
 				wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]);
 			}
 			auto_val = 0;
-			dib3000mc_set_general_cfg(state,fep,&auto_val);
+			dib3000mc_set_general_cfg_compat(state, fep, &auto_val);
 			dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
 
 			val = rd(DIB3000MC_REG_DEMOD_PARM);
@@ -536,11 +1010,11 @@ static int dib3000mc_set_frontend(struct
 //		dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth);
 
 		auto_val = 0;
-		dib3000mc_set_general_cfg(state,fep,&auto_val);
+		dib3000mc_set_general_cfg_compat(state, fep, &auto_val);
 		if (auto_val)
 			deb_info("auto_val is true, even though an auto search was already performed.\n");
 
-		dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
+		dib3000mc_set_impulse_noise_compat(state, 0, ofdm->constellation, ofdm->bandwidth);
 
 		val = rd(DIB3000MC_REG_DEMOD_PARM);
 		wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
@@ -549,13 +1023,116 @@ static int dib3000mc_set_frontend(struct
 		msleep(30);
 
 		wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
-			dib3000mc_set_adp_cfg(state,ofdm->constellation);
+			dib3000mc_set_adp_cfg_compat(state, ofdm->constellation);
 		wr_foreach(dib3000mc_reg_offset,
 				dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
 	}
 	return 0;
 }
 
+static int dib3000mc_set_param(struct dvb_frontend *fe,
+			       struct dvbfe_params *fep, int tuner)
+{
+	struct dib3000_state *state = fe->demodulator_priv;
+	struct dvbt_params *dvbt = &fep->delsys.dvbt;
+	int search_state,auto_val;
+	u16 val;
+
+	if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */
+		fe->ops.tuner_ops.set_params(fe, fep);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+
+		state->last_tuned_freq = fep->frequency;
+	//	if (!scanboost) {
+			dib3000mc_set_timing(state, 0, dvbt->transmission_mode, dvbt->bandwidth);
+			dib3000mc_init_auto_scan(state, dvbt->bandwidth, 0);
+			state->last_tuned_bw = dvbt->bandwidth;
+
+			wr_foreach(dib3000mc_reg_agc_bandwidth, dib3000mc_agc_bandwidth);
+			wr(DIB3000MC_REG_RESTART, DIB3000MC_RESTART_AGC);
+			wr(DIB3000MC_REG_RESTART, DIB3000MC_RESTART_OFF);
+
+			/* Default cfg isi offset adp */
+			wr_foreach(dib3000mc_reg_offset, dib3000mc_offset[0]);
+
+			wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT);
+			dib3000mc_set_adp_cfg(state, dvbt->constellation);
+			wr(DIB3000MC_REG_UNK_133, DIB3000MC_UNK_133);
+
+			wr_foreach(dib3000mc_reg_bandwidth_general, dib3000mc_bandwidth_general);
+			/* power smoothing */
+			if (dvbt->bandwidth != DVBFE_BANDWIDTH_8_MHZ) {
+				wr_foreach(dib3000mc_reg_bw, dib3000mc_bw[0]);
+			} else {
+				wr_foreach(dib3000mc_reg_bw, dib3000mc_bw[3]);
+			}
+			auto_val = 0;
+			dib3000mc_set_general_cfg(state, fep, &auto_val);
+			dib3000mc_set_impulse_noise(state, 0, dvbt->constellation, dvbt->bandwidth);
+
+			val = rd(DIB3000MC_REG_DEMOD_PARM);
+			wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON);
+			wr(DIB3000MC_REG_DEMOD_PARM,val);
+	//	}
+		msleep(70);
+
+		/* something has to be auto searched */
+		if (auto_val) {
+			int as_count=0;
+
+			deb_setf("autosearch enabled.\n");
+
+			val = rd(DIB3000MC_REG_DEMOD_PARM);
+			wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
+			wr(DIB3000MC_REG_DEMOD_PARM,val);
+
+			while ((search_state = dib3000_search_status(
+						rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100)
+				msleep(10);
+
+			deb_info("search_state after autosearch %d after %d checks\n", search_state, as_count);
+
+			if (search_state == 1) {
+				struct dvbfe_params feps;
+				if (dib3000mc_get_params(fe, &feps) == 0) {
+					deb_setf("reading tuning data from frontend succeeded.\n");
+					return dib3000mc_set_param(fe, &feps, 0);
+				}
+			}
+		} else {
+			dib3000mc_set_impulse_noise(state, 0, dvbt->transmission_mode, dvbt->bandwidth);
+			wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
+			dib3000mc_set_adp_cfg(state, dvbt->constellation);
+
+			/* set_offset_cfg */
+			wr_foreach(dib3000mc_reg_offset,
+					dib3000mc_offset[(dvbt->transmission_mode == TRANSMISSION_MODE_8K)+1]);
+		}
+	} else { /* second call, after autosearch (fka: set_WithKnownParams) */
+//		dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth);
+
+		auto_val = 0;
+		dib3000mc_set_general_cfg(state, fep, &auto_val);
+		if (auto_val)
+			deb_info("auto_val is true, even though an auto search was already performed.\n");
+
+		dib3000mc_set_impulse_noise(state, 0, dvbt->constellation, dvbt->bandwidth);
+
+		val = rd(DIB3000MC_REG_DEMOD_PARM);
+		wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
+		wr(DIB3000MC_REG_DEMOD_PARM,val);
+
+		msleep(30);
+
+		wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
+			dib3000mc_set_adp_cfg(state, dvbt->constellation);
+		wr_foreach(dib3000mc_reg_offset,
+				dib3000mc_offset[(dvbt->transmission_mode == TRANSMISSION_MODE_8K)+1]);
+	}
+	return 0;
+}
+
 static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
 {
 	struct dib3000_state *state = fe->demodulator_priv;
@@ -740,6 +1317,12 @@ static int dib3000mc_set_frontend_and_tu
 	return dib3000mc_set_frontend(fe, fep, 1);
 }
 
+static int dib3000mc_set_params(struct dvb_frontend *fe,
+				struct dvbfe_params *fep)
+{
+	return dib3000mc_set_param(fe, fep, 1);
+}
+
 static void dib3000mc_release(struct dvb_frontend* fe)
 {
 	struct dib3000_state *state = fe->demodulator_priv;
@@ -875,6 +1458,36 @@ error:
 }
 EXPORT_SYMBOL(dib3000mc_attach);
 
+static struct dvbfe_info dvbt_info	= {
+	.name				= "DiBcom 3000P/M-C 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			= 44250000,
+	.frequency_max			= 867250000,
+	.frequency_step			= 62500,
+};
+
+static int dib3000mc_get_info(struct dvb_frontend *fe,
+			      struct dvbfe_info *fe_info)
+{
+	memcpy(fe_info, &dvbt_info, sizeof (dvbt_info));
+
+	return 0;
+}
+
+static int dib3000mc_get_delsys(struct dvb_frontend *fe,
+				enum dvbfe_delsys *fe_delsys)
+{
+	*fe_delsys = DVBFE_DELSYS_DVBT;
+
+	return 0;
+}
+
 static struct dvb_frontend_ops dib3000mc_ops = {
 
 	.info = {
@@ -907,6 +1520,11 @@ static struct dvb_frontend_ops dib3000mc
 	.read_signal_strength = dib3000mc_read_signal_strength,
 	.read_snr = dib3000mc_read_snr,
 	.read_ucblocks = dib3000mc_read_unc_blocks,
+
+	.set_params	= dib3000mc_set_params,
+	.get_params	= dib3000mc_get_params,
+	.get_info	= dib3000mc_get_info,
+	.get_delsys	= dib3000mc_get_delsys,
 };
 
 MODULE_AUTHOR(DRIVER_AUTHOR);


_______________________________________________

linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux