diff options
Diffstat (limited to 'drivers/media/video/tda8290.c')
-rw-r--r-- | drivers/media/video/tda8290.c | 136 |
1 files changed, 98 insertions, 38 deletions
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index 027c8a074dfe..e6c3e6167191 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c | |||
@@ -192,14 +192,52 @@ static struct tda827xa_data tda827xa_analog[] = { | |||
192 | { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */ | 192 | { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */ |
193 | }; | 193 | }; |
194 | 194 | ||
195 | static void tda827xa_lna_gain(struct i2c_client *c, int high) | ||
196 | { | ||
197 | struct tuner *t = i2c_get_clientdata(c); | ||
198 | unsigned char buf[] = {0x22, 0x01}; | ||
199 | int arg; | ||
200 | struct i2c_msg msg = {.addr = c->addr, .flags = 0, .buf = buf, .len = sizeof(buf)}; | ||
201 | if (t->config) { | ||
202 | if (high) | ||
203 | tuner_dbg("setting LNA to high gain\n"); | ||
204 | else | ||
205 | tuner_dbg("setting LNA to low gain\n"); | ||
206 | } | ||
207 | switch (t->config) { | ||
208 | case 0: /* no LNA */ | ||
209 | break; | ||
210 | case 1: /* switch is GPIO 0 of tda8290 */ | ||
211 | case 2: | ||
212 | /* turn Vsync on */ | ||
213 | if (t->std & V4L2_STD_MN) | ||
214 | arg = 5; | ||
215 | else | ||
216 | arg = 4; | ||
217 | if (t->gpio_func) | ||
218 | t->gpio_func(c->adapter->algo_data, 22, 5); | ||
219 | buf[1] = high ? 0 : 1; | ||
220 | if (t->config == 2) | ||
221 | buf[1] = high ? 1 : 0; | ||
222 | i2c_transfer(c->adapter, &msg, 1); | ||
223 | break; | ||
224 | case 3: /* switch with GPIO of saa713x */ | ||
225 | if (t->gpio_func) | ||
226 | t->gpio_func(c->adapter->algo_data, 22, high); | ||
227 | break; | ||
228 | } | ||
229 | } | ||
230 | |||
195 | static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | 231 | static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq) |
196 | { | 232 | { |
197 | unsigned char tuner_reg[14]; | 233 | unsigned char tuner_reg[11]; |
198 | unsigned char reg2[2]; | ||
199 | u32 N; | 234 | u32 N; |
200 | int i; | 235 | int i; |
201 | struct tuner *t = i2c_get_clientdata(c); | 236 | struct tuner *t = i2c_get_clientdata(c); |
202 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0}; | 237 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0, .buf = tuner_reg}; |
238 | |||
239 | tda827xa_lna_gain( c, 1); | ||
240 | msleep(10); | ||
203 | 241 | ||
204 | if (t->mode == V4L2_TUNER_RADIO) | 242 | if (t->mode == V4L2_TUNER_RADIO) |
205 | freq = freq / 1000; | 243 | freq = freq / 1000; |
@@ -222,48 +260,58 @@ static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
222 | tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) + | 260 | tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) + |
223 | tda827xa_analog[i].sbs; | 261 | tda827xa_analog[i].sbs; |
224 | tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4); | 262 | tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4); |
225 | tuner_reg[7] = 0x0c; | 263 | tuner_reg[7] = 0x1c; |
226 | tuner_reg[8] = 4; | 264 | tuner_reg[8] = 4; |
227 | tuner_reg[9] = 0x20; | 265 | tuner_reg[9] = 0x20; |
228 | tuner_reg[10] = 0xff; | 266 | tuner_reg[10] = 0x00; |
229 | tuner_reg[11] = 0xe0; | 267 | msg.len = 11; |
230 | tuner_reg[12] = 0; | 268 | i2c_transfer(c->adapter, &msg, 1); |
231 | tuner_reg[13] = 0x39 + (t->tda827x_lpsel << 1); | ||
232 | 269 | ||
233 | msg.buf = tuner_reg; | 270 | tuner_reg[0] = 0x90; |
234 | msg.len = 14; | 271 | tuner_reg[1] = 0xff; |
272 | tuner_reg[2] = 0xe0; | ||
273 | tuner_reg[3] = 0; | ||
274 | tuner_reg[4] = 0x99 + (t->tda827x_lpsel << 1); | ||
275 | msg.len = 5; | ||
235 | i2c_transfer(c->adapter, &msg, 1); | 276 | i2c_transfer(c->adapter, &msg, 1); |
236 | 277 | ||
237 | msg.buf= reg2; | 278 | tuner_reg[0] = 0xa0; |
279 | tuner_reg[1] = 0xc0; | ||
238 | msg.len = 2; | 280 | msg.len = 2; |
239 | reg2[0] = 0x60; | ||
240 | reg2[1] = 0x3c; | ||
241 | i2c_transfer(c->adapter, &msg, 1); | 281 | i2c_transfer(c->adapter, &msg, 1); |
242 | 282 | ||
243 | reg2[0] = 0xa0; | 283 | tuner_reg[0] = 0x30; |
244 | reg2[1] = 0xc0; | 284 | tuner_reg[1] = 0x10 + tda827xa_analog[i].scr; |
245 | i2c_transfer(c->adapter, &msg, 1); | 285 | i2c_transfer(c->adapter, &msg, 1); |
246 | 286 | ||
247 | msleep(2); | 287 | msg.flags = I2C_M_RD; |
248 | reg2[0] = 0x30; | 288 | i2c_transfer(c->adapter, &msg, 1); |
249 | reg2[1] = 0x10 + tda827xa_analog[i].scr; | 289 | msg.flags = 0; |
290 | tuner_reg[1] >>= 4; | ||
291 | tuner_dbg("AGC2 gain is: %d\n", tuner_reg[1]); | ||
292 | if (tuner_reg[1] < 1) | ||
293 | tda827xa_lna_gain( c, 0); | ||
294 | |||
295 | msleep(100); | ||
296 | tuner_reg[0] = 0x60; | ||
297 | tuner_reg[1] = 0x3c; | ||
250 | i2c_transfer(c->adapter, &msg, 1); | 298 | i2c_transfer(c->adapter, &msg, 1); |
251 | 299 | ||
252 | msleep(550); | 300 | msleep(163); |
253 | reg2[0] = 0x50; | 301 | tuner_reg[0] = 0x50; |
254 | reg2[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); | 302 | tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); |
255 | i2c_transfer(c->adapter, &msg, 1); | 303 | i2c_transfer(c->adapter, &msg, 1); |
256 | 304 | ||
257 | reg2[0] = 0x80; | 305 | tuner_reg[0] = 0x80; |
258 | reg2[1] = 0x28; | 306 | tuner_reg[1] = 0x28; |
259 | i2c_transfer(c->adapter, &msg, 1); | 307 | i2c_transfer(c->adapter, &msg, 1); |
260 | 308 | ||
261 | reg2[0] = 0xb0; | 309 | tuner_reg[0] = 0xb0; |
262 | reg2[1] = 0x01; | 310 | tuner_reg[1] = 0x01; |
263 | i2c_transfer(c->adapter, &msg, 1); | 311 | i2c_transfer(c->adapter, &msg, 1); |
264 | 312 | ||
265 | reg2[0] = 0xc0; | 313 | tuner_reg[0] = 0xc0; |
266 | reg2[1] = 0x19 + (t->tda827x_lpsel << 1); | 314 | tuner_reg[1] = 0x19 + (t->tda827x_lpsel << 1); |
267 | i2c_transfer(c->adapter, &msg, 1); | 315 | i2c_transfer(c->adapter, &msg, 1); |
268 | } | 316 | } |
269 | 317 | ||
@@ -319,7 +367,9 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
319 | unsigned char addr_pll_stat = 0x1b; | 367 | unsigned char addr_pll_stat = 0x1b; |
320 | unsigned char adc_sat, agc_stat, | 368 | unsigned char adc_sat, agc_stat, |
321 | pll_stat; | 369 | pll_stat; |
370 | int i; | ||
322 | 371 | ||
372 | tuner_dbg("tda827xa config is 0x%02x\n", t->config); | ||
323 | i2c_master_send(c, easy_mode, 2); | 373 | i2c_master_send(c, easy_mode, 2); |
324 | i2c_master_send(c, agc_out_on, 2); | 374 | i2c_master_send(c, agc_out_on, 2); |
325 | i2c_master_send(c, soft_reset, 2); | 375 | i2c_master_send(c, soft_reset, 2); |
@@ -340,17 +390,22 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
340 | tda827xa_tune(c, ifc, freq); | 390 | tda827xa_tune(c, ifc, freq); |
341 | else | 391 | else |
342 | tda827x_tune(c, ifc, freq); | 392 | tda827x_tune(c, ifc, freq); |
393 | for (i = 0; i < 3; i++) { | ||
394 | i2c_master_send(c, &addr_pll_stat, 1); | ||
395 | i2c_master_recv(c, &pll_stat, 1); | ||
396 | if (pll_stat & 0x80) { | ||
397 | i2c_master_send(c, &addr_adc_sat, 1); | ||
398 | i2c_master_recv(c, &adc_sat, 1); | ||
399 | i2c_master_send(c, &addr_agc_stat, 1); | ||
400 | i2c_master_recv(c, &agc_stat, 1); | ||
401 | tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat); | ||
402 | break; | ||
403 | } else { | ||
404 | tuner_dbg("tda8290 not locked, no signal?\n"); | ||
405 | msleep(100); | ||
406 | } | ||
407 | } | ||
343 | /* adjust headroom resp. gain */ | 408 | /* adjust headroom resp. gain */ |
344 | i2c_master_send(c, &addr_adc_sat, 1); | ||
345 | i2c_master_recv(c, &adc_sat, 1); | ||
346 | i2c_master_send(c, &addr_agc_stat, 1); | ||
347 | i2c_master_recv(c, &agc_stat, 1); | ||
348 | i2c_master_send(c, &addr_pll_stat, 1); | ||
349 | i2c_master_recv(c, &pll_stat, 1); | ||
350 | if (pll_stat & 0x80) | ||
351 | tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat); | ||
352 | else | ||
353 | tuner_dbg("tda8290 not locked, no signal?\n"); | ||
354 | if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) { | 409 | if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) { |
355 | tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n", | 410 | tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n", |
356 | agc_stat, adc_sat, pll_stat & 0x80); | 411 | agc_stat, adc_sat, pll_stat & 0x80); |
@@ -487,11 +542,16 @@ static void standby(struct i2c_client *c) | |||
487 | 542 | ||
488 | static void tda8290_init_if(struct i2c_client *c) | 543 | static void tda8290_init_if(struct i2c_client *c) |
489 | { | 544 | { |
545 | struct tuner *t = i2c_get_clientdata(c); | ||
490 | unsigned char set_VS[] = { 0x30, 0x6F }; | 546 | unsigned char set_VS[] = { 0x30, 0x6F }; |
547 | unsigned char set_GP00_CF[] = { 0x20, 0x01 }; | ||
491 | unsigned char set_GP01_CF[] = { 0x20, 0x0B }; | 548 | unsigned char set_GP01_CF[] = { 0x20, 0x0B }; |
492 | 549 | ||
550 | if ((t->config == 1) || (t->config == 2)) | ||
551 | i2c_master_send(c, set_GP00_CF, 2); | ||
552 | else | ||
553 | i2c_master_send(c, set_GP01_CF, 2); | ||
493 | i2c_master_send(c, set_VS, 2); | 554 | i2c_master_send(c, set_VS, 2); |
494 | i2c_master_send(c, set_GP01_CF, 2); | ||
495 | } | 555 | } |
496 | 556 | ||
497 | static void tda8290_init_tuner(struct i2c_client *c) | 557 | static void tda8290_init_tuner(struct i2c_client *c) |