PATCH 33/44 multiproto + backward compatibility [STV0299]

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

 




--- v4l-dvb/linux/drivers/media/dvb/frontends/stv0299.c	2006-06-30 19:59:10.000000000 +0400
+++ mp-bc1/linux/drivers/media/dvb/frontends/stv0299.c	2006-07-23 11:40:35.000000000 +0400
@@ -130,7 +130,7 @@ static int stv0299_readregs (struct stv0
 	return ret == 2 ? 0 : ret;
 }
 
-static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec)
+static int stv0299_set_FEC_compat(struct stv0299_state* state, fe_code_rate_t fec)
 {
 	dprintk ("%s\n", __FUNCTION__);
 
@@ -166,7 +166,43 @@ static int stv0299_set_FEC (struct stv02
     }
 }
 
-static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state)
+static int stv0299_set_FEC(struct stv0299_state* state, enum dvbfe_fec fec)
+{
+	dprintk ("%s\n", __FUNCTION__);
+
+	switch (fec) {
+	case DVBFE_FEC_AUTO:
+	{
+		return stv0299_writeregI (state, 0x31, 0x1f);
+	}
+	case DVBFE_FEC_1_2:
+	{
+		return stv0299_writeregI (state, 0x31, 0x01);
+	}
+	case DVBFE_FEC_2_3:
+	{
+		return stv0299_writeregI (state, 0x31, 0x02);
+	}
+	case DVBFE_FEC_3_4:
+	{
+		return stv0299_writeregI (state, 0x31, 0x04);
+	}
+	case DVBFE_FEC_5_6:
+	{
+		return stv0299_writeregI (state, 0x31, 0x08);
+	}
+	case DVBFE_FEC_7_8:
+	{
+		return stv0299_writeregI (state, 0x31, 0x10);
+	}
+	default:
+	{
+		return -EINVAL;
+	}
+    }
+}
+
+static fe_code_rate_t stv0299_get_fec_compat(struct stv0299_state* state)
 {
 	static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6,
 					     FEC_7_8, FEC_1_2 };
@@ -183,6 +219,29 @@ static fe_code_rate_t stv0299_get_fec (s
 	return fec_tab [index];
 }
 
+static fe_code_rate_t stv0299_get_fec(struct stv0299_state* state)
+{
+	static fe_code_rate_t fec_tab [] = {
+		DVBFE_FEC_2_3,
+		DVBFE_FEC_3_4,
+		DVBFE_FEC_5_6,
+		DVBFE_FEC_7_8,
+		DVBFE_FEC_1_2
+	};
+
+	u8 index;
+
+	dprintk ("%s\n", __FUNCTION__);
+
+	index = stv0299_readreg (state, 0x1b);
+	index &= 0x7;
+
+	if (index > 4)
+		return DVBFE_FEC_AUTO;
+
+	return fec_tab[index];
+}
+
 static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout)
 {
 	unsigned long start = jiffies;
@@ -546,12 +605,13 @@ static int stv0299_set_frontend(struct d
 	if (state->config->invert) invval = (~invval) & 1;
 	stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
 
-	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);
 	}
 
-	stv0299_set_FEC (state, p->u.qpsk.fec_inner);
+	stv0299_set_FEC_compat(state, p->u.qpsk.fec_inner);
 	stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
 	stv0299_writeregI(state, 0x22, 0x00);
 	stv0299_writeregI(state, 0x23, 0x00);
@@ -582,7 +642,7 @@ static int stv0299_get_frontend(struct d
 	if (state->config->invert) invval = (~invval) & 1;
 	p->inversion = invval ? INVERSION_ON : INVERSION_OFF;
 
-	p->u.qpsk.fec_inner = stv0299_get_fec (state);
+	p->u.qpsk.fec_inner = stv0299_get_fec_compat(state);
 	p->u.qpsk.symbol_rate = stv0299_get_symbolrate (state);
 
 	return 0;
@@ -616,12 +676,24 @@ static int stv0299_get_tune_settings(str
 	struct stv0299_state* state = fe->demodulator_priv;
 
 	fesettings->min_delay_ms = state->config->min_delay_ms;
-	if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) {
-		fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000;
-		fesettings->max_drift = 5000;
+
+	if (fe->legacy) {
+		if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) {
+			fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000;
+			fesettings->max_drift = 5000;
+		} else {
+			fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000;
+			fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000;
+		}
 	} else {
-		fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000;
-		fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000;
+		if (fesettings->fe_params.delsys.dvbs.symbol_rate < 10000000) {
+			fesettings->step_size = fesettings->fe_params.delsys.dvbs.symbol_rate / 32000;
+			fesettings->max_drift = 5000;
+		} else {
+			fesettings->step_size = fesettings->fe_params.delsys.dvbs.symbol_rate / 16000;
+			fesettings->max_drift = fesettings->fe_params.delsys.dvbs.symbol_rate / 2000;
+		}
+
 	}
 	return 0;
 }
@@ -672,8 +744,107 @@ error:
 	return NULL;
 }
 
-static struct dvb_frontend_ops stv0299_ops = {
+static int stv0299_set_params(struct dvb_frontend* fe, struct dvbfe_params *p)
+{
+	struct stv0299_state* state = fe->demodulator_priv;
+	int invval = 0;
+
+	dprintk ("%s: Frequency=[%d] SymbolRate=[%d]\n",
+		 __func__, p->frequency, p->delsys.dvbs.symbol_rate);
+
+	// set the inversion
+	if (p->inversion == INVERSION_OFF)
+		invval = 0;
+	else if (p->inversion == INVERSION_ON)
+		invval = 1;
+	else {
+		printk("stv0299 does not support auto-inversion\n");
+		return -EINVAL;
+	}
+	if (state->config->invert)
+		invval = (~invval) & 1;
+	stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
+
+	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);
+	}
+
+	stv0299_set_FEC(state, p->delsys.dvbs.fec);
+	stv0299_set_symbolrate(fe, p->delsys.dvbs.symbol_rate);
+	stv0299_writeregI(state, 0x22, 0x00);
+	stv0299_writeregI(state, 0x23, 0x00);
+
+	state->tuner_frequency = p->frequency;
+	state->fec_inner = p->delsys.dvbs.fec;
+	state->symbol_rate = p->delsys.dvbs.symbol_rate;
+
+	return 0;
+}
+
+static int stv0299_get_params(struct dvb_frontend* fe, struct dvbfe_params *p)
+{
+	struct stv0299_state* state = fe->demodulator_priv;
+	s32 derot_freq;
+	int invval;
 
+	derot_freq = (s32)(s16) ((stv0299_readreg (state, 0x22) << 8)
+				| stv0299_readreg (state, 0x23));
+
+	derot_freq *= (state->config->mclk >> 16);
+	derot_freq += 500;
+	derot_freq /= 1000;
+
+	p->frequency += derot_freq;
+
+	invval = stv0299_readreg(state, 0x0c) & 1;
+	if (state->config->invert)
+		invval = (~invval) & 1;
+	p->inversion = invval ? INVERSION_ON : INVERSION_OFF;
+
+	p->delsys.dvbs.fec = stv0299_get_fec(state);
+	p->delsys.dvbs.symbol_rate = stv0299_get_symbolrate(state);
+
+	return 0;
+}
+
+
+static struct dvbfe_info dvbs_info	= {
+	.name				= "STV0299 DVB-S",
+	.delivery			= DVBFE_DELSYS_DVBS,
+	.delsys				= {
+		.dvbs.modulation	= DVBFE_MOD_QPSK,
+		.dvbs.fec		= DVBFE_FEC_1_2 | DVBFE_FEC_2_3 |
+					  DVBFE_FEC_3_4 | DVBFE_FEC_5_6 |
+					  DVBFE_FEC_7_8 | DVBFE_FEC_AUTO
+	},
+
+	.frequency_min			= 950000,
+	.frequency_max			= 2150000,
+	.frequency_step			= 125,
+	.frequency_tolerance		= 0,
+	.symbol_rate_min		= 1000000,
+	.symbol_rate_max		= 45000000,
+	.symbol_rate_tolerance		= 500
+};
+
+static int stv0299_get_info(struct dvb_frontend *fe, struct dvbfe_info *fe_info)
+{
+	memcpy(fe_info, &dvbs_info, sizeof (dvbs_info));
+
+	return 0;
+}
+
+static int stv0299_get_delsys(struct dvb_frontend *fe, enum dvbfe_delsys *fe_delsys)
+{
+	*fe_delsys = DVBFE_DELSYS_DVBS;
+
+	return 0;
+}
+
+static struct dvb_frontend_ops stv0299_ops = {
+	/*	Info is deprecated	*/
 	.info = {
 		.name			= "ST STV0299 DVB-S",
 		.type			= FE_QPSK,
@@ -711,6 +882,11 @@ static struct dvb_frontend_ops stv0299_o
 	.set_tone = stv0299_set_tone,
 	.set_voltage = stv0299_set_voltage,
 	.dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd,
+
+	.set_params	= stv0299_set_params,
+	.get_params	= stv0299_get_params,
+	.get_info	= stv0299_get_info,
+	.get_delsys	= stv0299_get_delsys,
 };
 
 module_param(debug_legacy_dish_switch, int, 0444);

_______________________________________________

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