PATCH 21/44 multiproto + backward compatibility [MT312]

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

 




--- v4l-dvb/linux/drivers/media/dvb/frontends/mt312.c	2006-06-30 19:59:10.000000000 +0400
+++ mp-bc1/linux/drivers/media/dvb/frontends/mt312.c	2006-07-23 11:39:03.000000000 +0400
@@ -208,7 +208,7 @@ static int mt312_get_symbol_rate(struct 
 	return 0;
 }
 
-static int mt312_get_code_rate(struct mt312_state* state, fe_code_rate_t *cr)
+static int mt312_get_code_rate_compat(struct mt312_state* state, fe_code_rate_t *cr)
 {
 	const fe_code_rate_t fec_tab[8] =
 	    { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8,
@@ -225,6 +225,30 @@ static int mt312_get_code_rate(struct mt
 	return 0;
 }
 
+static int mt312_get_code_rate(struct mt312_state* state, enum dvbfe_fec *cr)
+{
+	enum dvbfe_fec fec_tab[8] = {
+		DVBFE_FEC_1_2,
+		DVBFE_FEC_2_3,
+		DVBFE_FEC_3_4,
+		DVBFE_FEC_5_6,
+		DVBFE_FEC_6_7,
+		DVBFE_FEC_7_8,
+		DVBFE_FEC_AUTO,
+		DVBFE_FEC_AUTO
+	};
+
+	int ret;
+	u8 fec_status;
+
+	if ((ret = mt312_readreg(state, FEC_STATUS, &fec_status)) < 0)
+		return ret;
+
+	*cr = fec_tab[(fec_status >> 4) & 0x07];
+
+	return 0;
+}
+
 static int mt312_initfe(struct dvb_frontend* fe)
 {
 	struct mt312_state *state = fe->demodulator_priv;
@@ -522,9 +546,10 @@ static int mt312_set_frontend(struct dvb
 		return -EINVAL;
 	}
 
-	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);
 	}
 
 	/* sr = (u16)(sr * 256.0 / 1000000.0) */
@@ -566,7 +591,7 @@ static int mt312_get_frontend(struct dvb
 	if ((ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate)) < 0)
 		return ret;
 
-	if ((ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner)) < 0)
+	if ((ret = mt312_get_code_rate_compat(state, &p->u.qpsk.fec_inner)) < 0)
 		return ret;
 
 	return 0;
@@ -617,6 +642,200 @@ static void mt312_release(struct dvb_fro
 	kfree(state);
 }
 
+static struct dvbfe_info vp310_info	= {
+	.name				= "Zarlink VP310 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			= (MT312_PLL_CLK / 1000) / 128,
+	.symbol_rate_min		= MT312_SYS_CLK / 128,
+	.symbol_rate_max		= MT312_SYS_CLK / 2
+};
+
+static struct dvbfe_info mt312_info	= {
+	.name				= "Zarlink MT312 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			= (MT312_PLL_CLK / 1000) / 128,
+	.symbol_rate_min		= MT312_SYS_CLK / 128,
+	.symbol_rate_max		= MT312_SYS_CLK / 2
+};
+
+static int mt312_get_info(struct dvb_frontend *fe, struct dvbfe_info *fe_info)
+{
+	struct mt312_state *state = fe->demodulator_priv;
+
+	switch (state->id) {
+	case ID_VP310:
+		memcpy(fe_info, &vp310_info, sizeof (vp310_info));
+		break;
+	case ID_MT312:
+		memcpy(fe_info, &mt312_info, sizeof (mt312_info));
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mt312_get_delsys(struct dvb_frontend *fe, enum dvbfe_delsys *fe_delsys)
+{
+	*fe_delsys = DVBFE_DELSYS_DVBS;
+
+	return 0;
+}
+
+static int mt312_set_params(struct dvb_frontend* fe,
+			    struct dvbfe_params *p)
+{
+	struct mt312_state *state = fe->demodulator_priv;
+	int ret;
+	u8 buf[5], config_val;
+	u16 sr;
+
+	const u8 fec_tab[15] = {
+		0x00,	// NONE
+		0x00,	// 1_4
+		0x00,	// 1_3
+		0x00,	// 2_5
+		0x01,	// 1_2
+		0x00,	// 3_5
+		0x02,	// 2_3
+		0x04,	// 3_4
+		0x3f,	// 4_5
+		0x08,	// 5_6
+		0x10,	// 6_7
+		0x20,	// 7_8
+		0x3f,	// 8_9
+		0x00,	// 9_10
+		0x3f	// AUTO
+	};
+
+	const u8 inv_tab[3] = { 0x00, 0x40, 0x80 };
+
+	dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency);
+
+//	if ((p->frequency < fe->ops.info.frequency_min) ||
+//	    (p->frequency > fe->ops.info.frequency_max))
+//		return -EINVAL;
+
+//	if ((p->inversion < INVERSION_OFF) ||
+//	    (p->inversion > INVERSION_ON))
+//		return -EINVAL;
+
+//	if ((p->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) ||
+//	    (p->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max))
+//		return -EINVAL;
+
+//	if ((p->u.qpsk.fec_inner < FEC_NONE) ||
+//	    (p->u.qpsk.fec_inner > FEC_AUTO))
+//		return -EINVAL;
+
+//	if ((p->u.qpsk.fec_inner == FEC_4_5) ||
+//	    (p->u.qpsk.fec_inner == FEC_8_9))
+//		return -EINVAL;
+
+	switch (state->id) {
+	case ID_VP310:
+	// For now we will do this only for the VP310.
+	// It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03
+		ret = mt312_readreg(state, CONFIG, &config_val);
+		if (ret < 0)
+			return ret;
+		if (p->delsys.dvbs.symbol_rate >= 30000000) { //Note that 30MS/s should use 90MHz
+			if ((config_val & 0x0c) == 0x08) { //We are running 60MHz
+				state->frequency = 90;
+				if ((ret = mt312_initfe(fe)) < 0)
+					return ret;
+			}
+		} else {
+			if ((config_val & 0x0c) == 0x0C) { //We are running 90MHz
+				state->frequency = 60;
+				if ((ret = mt312_initfe(fe)) < 0)
+					return ret;
+			}
+		}
+		break;
+
+	case ID_MT312:
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	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);
+	}
+
+	/* sr = (u16)(sr * 256.0 / 1000000.0) */
+	sr = mt312_div(p->delsys.dvbs.symbol_rate * 4, 15625);
+
+	/* SYM_RATE */
+	buf[0] = (sr >> 8) & 0x3f;
+	buf[1] = (sr >> 0) & 0xff;
+
+	/* VIT_MODE */
+	buf[2] = inv_tab[p->inversion] | fec_tab[fls(p->delsys.dvbs.fec)];
+
+	/* QPSK_CTRL */
+	buf[3] = 0x40;		/* swap I and Q before QPSK demodulation */
+
+	if (p->delsys.dvbs.symbol_rate < 10000000)
+		buf[3] |= 0x04;	/* use afc mode */
+
+	/* GO */
+	buf[4] = 0x01;
+
+	if ((ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf))) < 0)
+		return ret;
+
+	mt312_reset(state, 0);
+
+	return 0;
+}
+
+static int mt312_get_params(struct dvb_frontend* fe,
+			    struct dvbfe_params *p)
+{
+	struct mt312_state *state = fe->demodulator_priv;
+	int ret;
+
+	if ((ret = mt312_get_inversion(state, &p->inversion)) < 0)
+		return ret;
+
+	if ((ret = mt312_get_symbol_rate(state, &p->delsys.dvbs.symbol_rate)) < 0)
+		return ret;
+
+	if ((ret = mt312_get_code_rate(state, &p->delsys.dvbs.fec)) < 0)
+		return ret;
+
+	return 0;
+}
+
+static enum dvbfe_algo mt312_get_algo(struct dvb_frontend *fe)
+{
+	return DVBFE_ALGO_RECOVERY;
+}
+
 static struct dvb_frontend_ops vp310_mt312_ops = {
 
 	.info = {
@@ -654,6 +873,12 @@ static struct dvb_frontend_ops vp310_mt3
 	.diseqc_send_burst = mt312_send_burst,
 	.set_tone = mt312_set_tone,
 	.set_voltage = mt312_set_voltage,
+
+	.set_params		= mt312_set_params,
+	.get_params		= mt312_get_params,
+	.get_info		= mt312_get_info,
+	.get_delsys		= mt312_get_delsys,
+	.get_frontend_algo	= mt312_get_algo,
 };
 
 struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,

_______________________________________________

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