summary refs log tree commit diff
path: root/drivers/media/common/tuners/tda8290.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/common/tuners/tda8290.c')
-rw-r--r--drivers/media/common/tuners/tda8290.c63
1 files changed, 53 insertions, 10 deletions
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
index c112bdd4e0f0..0ee79fd7c7a9 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -32,6 +32,9 @@ static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "enable verbose debug messages");
 
+static int deemphasis_50;
+MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis");
+
 /* ---------------------------------------------------------------------- */
 
 struct tda8290_priv {
@@ -139,9 +142,34 @@ static void set_audio(struct dvb_frontend *fe,
 		mode = "xx";
 	}
 
-	tuner_dbg("setting tda829x to system %s\n", mode);
+	if (params->mode == V4L2_TUNER_RADIO) {
+		priv->tda8290_easy_mode = 0x01;		/* Start with MN values */
+		tuner_dbg("setting to radio FM\n");
+	} else {
+		tuner_dbg("setting tda829x to system %s\n", mode);
+	}
 }
 
+struct {
+	unsigned char seq[2];
+} fm_mode[] = {
+	{ { 0x01, 0x81} },	/* Put device into expert mode */
+	{ { 0x03, 0x48} },	/* Disable NOTCH and VIDEO filters */
+	{ { 0x04, 0x04} },	/* Disable color carrier filter (SSIF) */
+	{ { 0x05, 0x04} },	/* ADC headroom */
+	{ { 0x06, 0x10} },	/* group delay flat */
+
+	{ { 0x07, 0x00} },	/* use the same radio DTO values as a tda8295 */
+	{ { 0x08, 0x00} },
+	{ { 0x09, 0x80} },
+	{ { 0x0a, 0xda} },
+	{ { 0x0b, 0x4b} },
+	{ { 0x0c, 0x68} },
+
+	{ { 0x0d, 0x00} },	/* PLL off, no video carrier detect */
+	{ { 0x14, 0x00} },	/* disable auto mute if no video */
+};
+
 static void tda8290_set_params(struct dvb_frontend *fe,
 			       struct analog_parameters *params)
 {
@@ -178,15 +206,30 @@ static void tda8290_set_params(struct dvb_frontend *fe,
 	tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2);
 	msleep(1);
 
-	expert_mode[1] = priv->tda8290_easy_mode + 0x80;
-	tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2);
-	tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2);
-	tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2);
-	if (priv->tda8290_easy_mode & 0x60)
-		tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2);
-	else
-		tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2);
-	tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
+	if (params->mode == V4L2_TUNER_RADIO) {
+		int i;
+		unsigned char deemphasis[]  = { 0x13, 1 };
+
+		/* FIXME: allow using a different deemphasis */
+
+		if (deemphasis_50)
+			deemphasis[1] = 2;
+
+		for (i = 0; i < ARRAY_SIZE(fm_mode); i++)
+			tuner_i2c_xfer_send(&priv->i2c_props, fm_mode[i].seq, 2);
+
+		tuner_i2c_xfer_send(&priv->i2c_props, deemphasis, 2);
+	} else {
+		expert_mode[1] = priv->tda8290_easy_mode + 0x80;
+		tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2);
+		tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2);
+		tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2);
+		if (priv->tda8290_easy_mode & 0x60)
+			tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2);
+		else
+			tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2);
+		tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
+	}
 
 	tda8290_i2c_bridge(fe, 1);