aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-12-08 08:36:57 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:19 -0500
commit9af0ef27a06f3e8976b90a4ed4758e25ea0f2df5 (patch)
treeb096cbad3214b09e9e2f65a432fe6df1b9d48609
parent92d90f1a57dcb6c6ab5a7b9ad949bdb7531931a4 (diff)
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>
-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;
32module_param(debug, int, 0644); 32module_param(debug, int, 0644);
33MODULE_PARM_DESC(debug, "enable verbose debug messages"); 33MODULE_PARM_DESC(debug, "enable verbose debug messages");
34 34
35static int deemphasis_50;
36MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis");
37
35/* ---------------------------------------------------------------------- */ 38/* ---------------------------------------------------------------------- */
36 39
37struct tda8290_priv { 40struct tda8290_priv {
@@ -139,9 +142,34 @@ static void set_audio(struct dvb_frontend *fe,
139 mode = "xx"; 142 mode = "xx";
140 } 143 }
141 144
142 tuner_dbg("setting tda829x to system %s\n", mode); 145 if (params->mode == V4L2_TUNER_RADIO) {
146 priv->tda8290_easy_mode = 0x01; /* Start with MN values */
147 tuner_dbg("setting to radio FM\n");
148 } else {
149 tuner_dbg("setting tda829x to system %s\n", mode);
150 }
143} 151}
144 152
153struct {
154 unsigned char seq[2];
155} fm_mode[] = {
156 { { 0x01, 0x81} }, /* Put device into expert mode */
157 { { 0x03, 0x48} }, /* Disable NOTCH and VIDEO filters */
158 { { 0x04, 0x04} }, /* Disable color carrier filter (SSIF) */
159 { { 0x05, 0x04} }, /* ADC headroom */
160 { { 0x06, 0x10} }, /* group delay flat */
161
162 { { 0x07, 0x00} }, /* use the same radio DTO values as a tda8295 */
163 { { 0x08, 0x00} },
164 { { 0x09, 0x80} },
165 { { 0x0a, 0xda} },
166 { { 0x0b, 0x4b} },
167 { { 0x0c, 0x68} },
168
169 { { 0x0d, 0x00} }, /* PLL off, no video carrier detect */
170 { { 0x14, 0x00} }, /* disable auto mute if no video */
171};
172
145static void tda8290_set_params(struct dvb_frontend *fe, 173static void tda8290_set_params(struct dvb_frontend *fe,
146 struct analog_parameters *params) 174 struct analog_parameters *params)
147{ 175{
@@ -178,15 +206,30 @@ static void tda8290_set_params(struct dvb_frontend *fe,
178 tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2); 206 tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2);
179 msleep(1); 207 msleep(1);
180 208
181 expert_mode[1] = priv->tda8290_easy_mode + 0x80; 209 if (params->mode == V4L2_TUNER_RADIO) {
182 tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2); 210 int i;
183 tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2); 211 unsigned char deemphasis[] = { 0x13, 1 };
184 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2); 212
185 if (priv->tda8290_easy_mode & 0x60) 213 /* FIXME: allow using a different deemphasis */
186 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2); 214
187 else 215 if (deemphasis_50)
188 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2); 216 deemphasis[1] = 2;
189 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2); 217
218 for (i = 0; i < ARRAY_SIZE(fm_mode); i++)
219 tuner_i2c_xfer_send(&priv->i2c_props, fm_mode[i].seq, 2);
220
221 tuner_i2c_xfer_send(&priv->i2c_props, deemphasis, 2);
222 } else {
223 expert_mode[1] = priv->tda8290_easy_mode + 0x80;
224 tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2);
225 tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2);
226 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2);
227 if (priv->tda8290_easy_mode & 0x60)
228 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2);
229 else
230 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2);
231 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
232 }
190 233
191 tda8290_i2c_bridge(fe, 1); 234 tda8290_i2c_bridge(fe, 1);
192 235