PATCH 30/44 multiproto + backward compatibility [SP8870]

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

 



--- v4l-dvb/linux/drivers/media/dvb/frontends/sp8870.c	2006-06-30 19:59:10.000000000 +0400
+++ mp-bc1/linux/drivers/media/dvb/frontends/sp8870.c	2006-07-23 11:40:17.000000000 +0400
@@ -169,7 +169,7 @@ static int sp8870_read_data_valid_signal
 	return (sp8870_readreg(state, 0x0D02) > 0);
 }
 
-static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05)
+static int configure_reg0xc05_compat(struct dvb_frontend_parameters *p, u16 *reg0xc05)
 {
 	int known_parameters = 1;
 
@@ -240,6 +240,83 @@ static int configure_reg0xc05 (struct dv
 	return 0;
 }
 
+static int configure_reg0xc05(struct dvbfe_params *p, u16 *reg0xc05)
+{
+	int known_parameters = 1;
+
+	*reg0xc05 = 0x000;
+
+	switch (p->delsys.dvbt.constellation) {
+	case DVBFE_MOD_QPSK:
+		break;
+	case DVBFE_MOD_QAM16:
+		*reg0xc05 |= (1 << 10);
+		break;
+	case DVBFE_MOD_QAM64:
+		*reg0xc05 |= (2 << 10);
+		break;
+	case DVBFE_MOD_QAMAUTO:
+		known_parameters = 0;
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	switch (p->delsys.dvbt.hierarchy) {
+	case DVBFE_HIERARCHY_OFF:
+		break;
+	case DVBFE_HIERARCHY_ON:
+		switch (p->delsys.dvbt.alpha) {
+		case DVBFE_ALPHA_1:
+			*reg0xc05 |= (1 << 7);
+			break;
+		case DVBFE_ALPHA_2:
+			*reg0xc05 |= (2 << 7);
+			break;
+		case DVBFE_ALPHA_4:
+			*reg0xc05 |= (3 << 7);
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case HIERARCHY_AUTO:
+		known_parameters = 0;
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	switch (p->delsys.dvbt.code_rate_HP) {
+	case DVBFE_FEC_1_2:
+		break;
+	case DVBFE_FEC_2_3:
+		*reg0xc05 |= (1 << 3);
+		break;
+	case DVBFE_FEC_3_4:
+		*reg0xc05 |= (2 << 3);
+		break;
+	case DVBFE_FEC_5_6:
+		*reg0xc05 |= (3 << 3);
+		break;
+	case DVBFE_FEC_7_8:
+		*reg0xc05 |= (4 << 3);
+		break;
+	case DVBFE_FEC_AUTO:
+		known_parameters = 0;
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	if (known_parameters)
+		*reg0xc05 |= (2 << 1);	/* use specified parameters */
+	else
+		*reg0xc05 |= (1 << 1);	/* enable autoprobing */
+
+	return 0;
+}
+
 static int sp8870_wake_up(struct sp8870_state* state)
 {
 	// enable TS output and interface pins
@@ -253,16 +330,17 @@ static int sp8870_set_frontend_parameter
 	int  err;
 	u16 reg0xc05;
 
-	if ((err = configure_reg0xc05(p, &reg0xc05)))
+	if ((err = configure_reg0xc05_compat(p, &reg0xc05)))
 		return err;
 
 	// system controller stop
 	sp8870_microcontroller_stop(state);
 
 	// set tuner parameters
-	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);
 	}
 
 	// sample rate correction bit [23..17]
@@ -579,6 +657,97 @@ error:
 	return NULL;
 }
 
+static struct dvbfe_info dvbt_info	= {
+	.name				= "Spase SP8870 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			= 470000000,
+	.frequency_max			= 860000000,
+	.frequency_step			= 166666,
+};
+
+static int sp8870_set_params(struct dvb_frontend* fe,
+			     struct dvbfe_params *p)
+{
+	struct sp8870_state* state = fe->demodulator_priv;
+	int  err;
+	u16 reg0xc05;
+
+	if ((err = configure_reg0xc05(p, &reg0xc05)))
+		return err;
+
+	// system controller stop
+	sp8870_microcontroller_stop(state);
+
+	// set tuner parameters
+	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);
+	}
+
+	// sample rate correction bit [23..17]
+	sp8870_writereg(state, 0x0319, 0x000A);
+
+	// sample rate correction bit [16..0]
+	sp8870_writereg(state, 0x031A, 0x0AAB);
+
+	// integer carrier offset
+	sp8870_writereg(state, 0x0309, 0x0400);
+
+	// fractional carrier offset
+	sp8870_writereg(state, 0x030A, 0x0000);
+
+	// filter for 6/7/8 Mhz channel
+	if (p->delsys.dvbt.bandwidth == DVBFE_BANDWIDTH_6_MHZ)
+		sp8870_writereg(state, 0x0311, 0x0002);
+	else if (p->delsys.dvbt.bandwidth == DVBFE_BANDWIDTH_7_MHZ)
+		sp8870_writereg(state, 0x0311, 0x0001);
+	else
+		sp8870_writereg(state, 0x0311, 0x0000);
+
+	// scan order: 2k first = 0x0000, 8k first = 0x0001
+	if (p->delsys.dvbt.transmission_mode == DVBFE_TRANSMISSION_MODE_2K)
+		sp8870_writereg(state, 0x0338, 0x0000);
+	else
+		sp8870_writereg(state, 0x0338, 0x0001);
+
+	sp8870_writereg(state, 0xc05, reg0xc05);
+
+	// read status reg in order to clear pending irqs
+	sp8870_readreg(state, 0x200);
+
+	// system controller start
+	sp8870_microcontroller_start(state);
+
+	return 0;
+}
+
+
+static int sp8870_get_info(struct dvb_frontend *fe, struct dvbfe_info *fe_info)
+{
+	memcpy(fe_info, &dvbt_info, sizeof (dvbt_info));
+
+	return 0;
+}
+
+static int sp8870_get_delsys(struct dvb_frontend *fe, enum dvbfe_delsys *fe_delsys)
+{
+	*fe_delsys = DVBFE_DELSYS_DVBT;
+
+	return 0;
+}
+
+static enum dvbfe_algo sp8870_get_algo(struct dvb_frontend *fe)
+{
+	return DVBFE_ALGO_RECOVERY;
+}
+
 static struct dvb_frontend_ops sp8870_ops = {
 
 	.info = {
@@ -608,6 +777,11 @@ static struct dvb_frontend_ops sp8870_op
 	.read_ber = sp8870_read_ber,
 	.read_signal_strength = sp8870_read_signal_strength,
 	.read_ucblocks = sp8870_read_uncorrected_blocks,
+
+	.set_params		= sp8870_set_params,
+	.get_info		= sp8870_get_info,
+	.get_delsys		= sp8870_get_delsys,
+	.get_frontend_algo	= sp8870_get_algo,
 };
 
 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