PATCH 9/44 multiproto + backward compatibility [CX22702]

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

 



--- 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

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

  Powered by Linux