diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-08 08:36:57 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:38:19 -0500 |
commit | 9af0ef27a06f3e8976b90a4ed4758e25ea0f2df5 (patch) | |
tree | b096cbad3214b09e9e2f65a432fe6df1b9d48609 | |
parent | 92d90f1a57dcb6c6ab5a7b9ad949bdb7531931a4 (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.c | 63 |
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; | |||
32 | module_param(debug, int, 0644); | 32 | module_param(debug, int, 0644); |
33 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | 33 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); |
34 | 34 | ||
35 | static int deemphasis_50; | ||
36 | MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis"); | ||
37 | |||
35 | /* ---------------------------------------------------------------------- */ | 38 | /* ---------------------------------------------------------------------- */ |
36 | 39 | ||
37 | struct tda8290_priv { | 40 | struct 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 | ||
153 | struct { | ||
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 | |||
145 | static void tda8290_set_params(struct dvb_frontend *fe, | 173 | static 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 | ||