V4L/DVB (9775): tda8290: fix FM radio

tda8290 were using some random video standard for FM. This results on random
errors. Instead, program tda8290 in expert mode, using a configuration near the
one specified on NXP datasheet for tda8295 (available on their site).

Also, properly display that the device is on radio mode.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
index c112bdd..0ee79fd 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -32,6 +32,9 @@
 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 @@
 		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 @@
 	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);