aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tuner-simple.c
diff options
context:
space:
mode:
authorMichael Krufky <mkrufky@linuxtv.org>2008-04-22 13:41:51 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 12:42:25 -0400
commitc7a9f3aa1e1b6c7ade5208b30683bec3553c3079 (patch)
treed97e234bcc7791cff962cbfe1ce144b79045c974 /drivers/media/video/tuner-simple.c
parentb65aa2605683d90966a16abc68112c1fd9e3f3d8 (diff)
V4L/DVB (7129): tuner-simple: move device-specific code into three separate functions
Move the switch..case blocks with device-specific code from functions simple_set_tv_freq and simple_set_radio_freq ...into three new functions: simple_std_setup, simple_post_tune and simple_radio_bandswitch Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/tuner-simple.c')
-rw-r--r--drivers/media/video/tuner-simple.c331
1 files changed, 184 insertions, 147 deletions
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index de0b291459f7..10addf2ba5ce 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -251,59 +251,13 @@ static int simple_config_lookup(struct dvb_frontend *fe,
251 251
252/* ---------------------------------------------------------------------- */ 252/* ---------------------------------------------------------------------- */
253 253
254static int simple_set_tv_freq(struct dvb_frontend *fe, 254static int simple_std_setup(struct dvb_frontend *fe,
255 struct analog_parameters *params) 255 struct analog_parameters *params,
256 u8 *buffer, u8 *config, u8 *cb)
256{ 257{
257 struct tuner_simple_priv *priv = fe->tuner_priv; 258 struct tuner_simple_priv *priv = fe->tuner_priv;
258 u8 config, cb, tuneraddr; 259 u8 tuneraddr;
259 u16 div; 260 int rc;
260 struct tunertype *tun;
261 u8 buffer[4];
262 int rc, IFPCoff, i;
263 enum param_type desired_type;
264 struct tuner_params *t_params;
265
266 tun = priv->tun;
267
268 /* IFPCoff = Video Intermediate Frequency - Vif:
269 940 =16*58.75 NTSC/J (Japan)
270 732 =16*45.75 M/N STD
271 704 =16*44 ATSC (at DVB code)
272 632 =16*39.50 I U.K.
273 622.4=16*38.90 B/G D/K I, L STD
274 592 =16*37.00 D China
275 590 =16.36.875 B Australia
276 543.2=16*33.95 L' STD
277 171.2=16*10.70 FM Radio (at set_radio_freq)
278 */
279
280 if (params->std == V4L2_STD_NTSC_M_JP) {
281 IFPCoff = 940;
282 desired_type = TUNER_PARAM_TYPE_NTSC;
283 } else if ((params->std & V4L2_STD_MN) &&
284 !(params->std & ~V4L2_STD_MN)) {
285 IFPCoff = 732;
286 desired_type = TUNER_PARAM_TYPE_NTSC;
287 } else if (params->std == V4L2_STD_SECAM_LC) {
288 IFPCoff = 543;
289 desired_type = TUNER_PARAM_TYPE_SECAM;
290 } else {
291 IFPCoff = 623;
292 desired_type = TUNER_PARAM_TYPE_PAL;
293 }
294
295 t_params = simple_tuner_params(fe, desired_type);
296
297 i = simple_config_lookup(fe, t_params, &params->frequency,
298 &config, &cb);
299
300 div = params->frequency + IFPCoff + offset;
301
302 tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, "
303 "Offset=%d.%02d MHz, div=%0d\n",
304 params->frequency / 16, params->frequency % 16 * 100 / 16,
305 IFPCoff / 16, IFPCoff % 16 * 100 / 16,
306 offset / 16, offset % 16 * 100 / 16, div);
307 261
308 /* tv norm specific stuff for multi-norm tuners */ 262 /* tv norm specific stuff for multi-norm tuners */
309 switch (priv->type) { 263 switch (priv->type) {
@@ -311,45 +265,45 @@ static int simple_set_tv_freq(struct dvb_frontend *fe,
311 /* 0x01 -> ??? no change ??? */ 265 /* 0x01 -> ??? no change ??? */
312 /* 0x02 -> PAL BDGHI / SECAM L */ 266 /* 0x02 -> PAL BDGHI / SECAM L */
313 /* 0x04 -> ??? PAL others / SECAM others ??? */ 267 /* 0x04 -> ??? PAL others / SECAM others ??? */
314 cb &= ~0x03; 268 *cb &= ~0x03;
315 if (params->std & V4L2_STD_SECAM_L) 269 if (params->std & V4L2_STD_SECAM_L)
316 /* also valid for V4L2_STD_SECAM */ 270 /* also valid for V4L2_STD_SECAM */
317 cb |= PHILIPS_MF_SET_STD_L; 271 *cb |= PHILIPS_MF_SET_STD_L;
318 else if (params->std & V4L2_STD_SECAM_LC) 272 else if (params->std & V4L2_STD_SECAM_LC)
319 cb |= PHILIPS_MF_SET_STD_LC; 273 *cb |= PHILIPS_MF_SET_STD_LC;
320 else /* V4L2_STD_B|V4L2_STD_GH */ 274 else /* V4L2_STD_B|V4L2_STD_GH */
321 cb |= PHILIPS_MF_SET_STD_BG; 275 *cb |= PHILIPS_MF_SET_STD_BG;
322 break; 276 break;
323 277
324 case TUNER_TEMIC_4046FM5: 278 case TUNER_TEMIC_4046FM5:
325 cb &= ~0x0f; 279 *cb &= ~0x0f;
326 280
327 if (params->std & V4L2_STD_PAL_BG) { 281 if (params->std & V4L2_STD_PAL_BG) {
328 cb |= TEMIC_SET_PAL_BG; 282 *cb |= TEMIC_SET_PAL_BG;
329 283
330 } else if (params->std & V4L2_STD_PAL_I) { 284 } else if (params->std & V4L2_STD_PAL_I) {
331 cb |= TEMIC_SET_PAL_I; 285 *cb |= TEMIC_SET_PAL_I;
332 286
333 } else if (params->std & V4L2_STD_PAL_DK) { 287 } else if (params->std & V4L2_STD_PAL_DK) {
334 cb |= TEMIC_SET_PAL_DK; 288 *cb |= TEMIC_SET_PAL_DK;
335 289
336 } else if (params->std & V4L2_STD_SECAM_L) { 290 } else if (params->std & V4L2_STD_SECAM_L) {
337 cb |= TEMIC_SET_PAL_L; 291 *cb |= TEMIC_SET_PAL_L;
338 292
339 } 293 }
340 break; 294 break;
341 295
342 case TUNER_PHILIPS_FQ1216ME: 296 case TUNER_PHILIPS_FQ1216ME:
343 cb &= ~0x0f; 297 *cb &= ~0x0f;
344 298
345 if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { 299 if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
346 cb |= PHILIPS_SET_PAL_BGDK; 300 *cb |= PHILIPS_SET_PAL_BGDK;
347 301
348 } else if (params->std & V4L2_STD_PAL_I) { 302 } else if (params->std & V4L2_STD_PAL_I) {
349 cb |= PHILIPS_SET_PAL_I; 303 *cb |= PHILIPS_SET_PAL_I;
350 304
351 } else if (params->std & V4L2_STD_SECAM_L) { 305 } else if (params->std & V4L2_STD_SECAM_L) {
352 cb |= PHILIPS_SET_PAL_L; 306 *cb |= PHILIPS_SET_PAL_L;
353 307
354 } 308 }
355 break; 309 break;
@@ -359,15 +313,15 @@ static int simple_set_tv_freq(struct dvb_frontend *fe,
359 /* 0x01 -> ATSC antenna input 2 */ 313 /* 0x01 -> ATSC antenna input 2 */
360 /* 0x02 -> NTSC antenna input 1 */ 314 /* 0x02 -> NTSC antenna input 1 */
361 /* 0x03 -> NTSC antenna input 2 */ 315 /* 0x03 -> NTSC antenna input 2 */
362 cb &= ~0x03; 316 *cb &= ~0x03;
363 if (!(params->std & V4L2_STD_ATSC)) 317 if (!(params->std & V4L2_STD_ATSC))
364 cb |= 2; 318 *cb |= 2;
365 /* FIXME: input */ 319 /* FIXME: input */
366 break; 320 break;
367 321
368 case TUNER_MICROTUNE_4042FI5: 322 case TUNER_MICROTUNE_4042FI5:
369 /* Set the charge pump for fast tuning */ 323 /* Set the charge pump for fast tuning */
370 config |= TUNER_CHARGE_PUMP; 324 *config |= TUNER_CHARGE_PUMP;
371 break; 325 break;
372 326
373 case TUNER_PHILIPS_TUV1236D: 327 case TUNER_PHILIPS_TUV1236D:
@@ -379,9 +333,9 @@ static int simple_set_tv_freq(struct dvb_frontend *fe,
379 buffer[1] = 0x00; 333 buffer[1] = 0x00;
380 buffer[2] = 0x17; 334 buffer[2] = 0x17;
381 buffer[3] = 0x00; 335 buffer[3] = 0x00;
382 cb &= ~0x40; 336 *cb &= ~0x40;
383 if (params->std & V4L2_STD_ATSC) { 337 if (params->std & V4L2_STD_ATSC) {
384 cb |= 0x40; 338 *cb |= 0x40;
385 buffer[1] = 0x04; 339 buffer[1] = 0x04;
386 } 340 }
387 /* set to the correct mode (analog or digital) */ 341 /* set to the correct mode (analog or digital) */
@@ -400,6 +354,165 @@ static int simple_set_tv_freq(struct dvb_frontend *fe,
400 break; 354 break;
401 } 355 }
402 356
357 return 0;
358}
359
360static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer,
361 u16 div, u8 config, u8 cb)
362{
363 struct tuner_simple_priv *priv = fe->tuner_priv;
364 int rc;
365
366 switch (priv->type) {
367 case TUNER_LG_TDVS_H06XF:
368 /* Set the Auxiliary Byte. */
369 buffer[0] = buffer[2];
370 buffer[0] &= ~0x20;
371 buffer[0] |= 0x18;
372 buffer[1] = 0x20;
373 tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]);
374
375 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
376 if (2 != rc)
377 tuner_warn("i2c i/o error: rc == %d "
378 "(should be 2)\n", rc);
379 break;
380 case TUNER_MICROTUNE_4042FI5:
381 {
382 /* FIXME - this may also work for other tuners */
383 unsigned long timeout = jiffies + msecs_to_jiffies(1);
384 u8 status_byte = 0;
385
386 /* Wait until the PLL locks */
387 for (;;) {
388 if (time_after(jiffies, timeout))
389 return 0;
390 rc = tuner_i2c_xfer_recv(&priv->i2c_props,
391 &status_byte, 1);
392 if (1 != rc) {
393 tuner_warn("i2c i/o read error: rc == %d "
394 "(should be 1)\n", rc);
395 break;
396 }
397 if (status_byte & TUNER_PLL_LOCKED)
398 break;
399 udelay(10);
400 }
401
402 /* Set the charge pump for optimized phase noise figure */
403 config &= ~TUNER_CHARGE_PUMP;
404 buffer[0] = (div>>8) & 0x7f;
405 buffer[1] = div & 0xff;
406 buffer[2] = config;
407 buffer[3] = cb;
408 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
409 buffer[0], buffer[1], buffer[2], buffer[3]);
410
411 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
412 if (4 != rc)
413 tuner_warn("i2c i/o error: rc == %d "
414 "(should be 4)\n", rc);
415 break;
416 }
417 }
418
419 return 0;
420}
421
422static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
423{
424 struct tuner_simple_priv *priv = fe->tuner_priv;
425
426 switch (priv->type) {
427 case TUNER_TENA_9533_DI:
428 case TUNER_YMEC_TVF_5533MF:
429 tuner_dbg("This tuner doesn't have FM. "
430 "Most cards have a TEA5767 for FM\n");
431 return 0;
432 case TUNER_PHILIPS_FM1216ME_MK3:
433 case TUNER_PHILIPS_FM1236_MK3:
434 case TUNER_PHILIPS_FMD1216ME_MK3:
435 case TUNER_LG_NTSC_TAPE:
436 case TUNER_PHILIPS_FM1256_IH3:
437 buffer[3] = 0x19;
438 break;
439 case TUNER_TNF_5335MF:
440 buffer[3] = 0x11;
441 break;
442 case TUNER_LG_PAL_FM:
443 buffer[3] = 0xa5;
444 break;
445 case TUNER_THOMSON_DTT761X:
446 buffer[3] = 0x39;
447 break;
448 case TUNER_MICROTUNE_4049FM5:
449 default:
450 buffer[3] = 0xa4;
451 break;
452 }
453
454 return 0;
455}
456
457/* ---------------------------------------------------------------------- */
458
459static int simple_set_tv_freq(struct dvb_frontend *fe,
460 struct analog_parameters *params)
461{
462 struct tuner_simple_priv *priv = fe->tuner_priv;
463 u8 config, cb;
464 u16 div;
465 struct tunertype *tun;
466 u8 buffer[4];
467 int rc, IFPCoff, i;
468 enum param_type desired_type;
469 struct tuner_params *t_params;
470
471 tun = priv->tun;
472
473 /* IFPCoff = Video Intermediate Frequency - Vif:
474 940 =16*58.75 NTSC/J (Japan)
475 732 =16*45.75 M/N STD
476 704 =16*44 ATSC (at DVB code)
477 632 =16*39.50 I U.K.
478 622.4=16*38.90 B/G D/K I, L STD
479 592 =16*37.00 D China
480 590 =16.36.875 B Australia
481 543.2=16*33.95 L' STD
482 171.2=16*10.70 FM Radio (at set_radio_freq)
483 */
484
485 if (params->std == V4L2_STD_NTSC_M_JP) {
486 IFPCoff = 940;
487 desired_type = TUNER_PARAM_TYPE_NTSC;
488 } else if ((params->std & V4L2_STD_MN) &&
489 !(params->std & ~V4L2_STD_MN)) {
490 IFPCoff = 732;
491 desired_type = TUNER_PARAM_TYPE_NTSC;
492 } else if (params->std == V4L2_STD_SECAM_LC) {
493 IFPCoff = 543;
494 desired_type = TUNER_PARAM_TYPE_SECAM;
495 } else {
496 IFPCoff = 623;
497 desired_type = TUNER_PARAM_TYPE_PAL;
498 }
499
500 t_params = simple_tuner_params(fe, desired_type);
501
502 i = simple_config_lookup(fe, t_params, &params->frequency,
503 &config, &cb);
504
505 div = params->frequency + IFPCoff + offset;
506
507 tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, "
508 "Offset=%d.%02d MHz, div=%0d\n",
509 params->frequency / 16, params->frequency % 16 * 100 / 16,
510 IFPCoff / 16, IFPCoff % 16 * 100 / 16,
511 offset / 16, offset % 16 * 100 / 16, div);
512
513 /* tv norm specific stuff for multi-norm tuners */
514 simple_std_setup(fe, params, &buffer[1], &config, &cb);
515
403 if (t_params->cb_first_if_lower_freq && div < priv->last_div) { 516 if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
404 buffer[0] = config; 517 buffer[0] = config;
405 buffer[1] = cb; 518 buffer[1] = cb;
@@ -463,58 +576,8 @@ static int simple_set_tv_freq(struct dvb_frontend *fe,
463 if (4 != rc) 576 if (4 != rc)
464 tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc); 577 tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
465 578
466 switch (priv->type) { 579 simple_post_tune(fe, &buffer[0], div, config, cb);
467 case TUNER_LG_TDVS_H06XF:
468 /* Set the Auxiliary Byte. */
469 buffer[0] = buffer[2];
470 buffer[0] &= ~0x20;
471 buffer[0] |= 0x18;
472 buffer[1] = 0x20;
473 tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]);
474
475 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
476 if (2 != rc)
477 tuner_warn("i2c i/o error: rc == %d "
478 "(should be 2)\n", rc);
479 break;
480 case TUNER_MICROTUNE_4042FI5:
481 {
482 /* FIXME - this may also work for other tuners */
483 unsigned long timeout = jiffies + msecs_to_jiffies(1);
484 u8 status_byte = 0;
485
486 /* Wait until the PLL locks */
487 for (;;) {
488 if (time_after(jiffies, timeout))
489 return 0;
490 rc = tuner_i2c_xfer_recv(&priv->i2c_props,
491 &status_byte, 1);
492 if (1 != rc) {
493 tuner_warn("i2c i/o read error: rc == %d "
494 "(should be 1)\n", rc);
495 break;
496 }
497 if (status_byte & TUNER_PLL_LOCKED)
498 break;
499 udelay(10);
500 }
501
502 /* Set the charge pump for optimized phase noise figure */
503 config &= ~TUNER_CHARGE_PUMP;
504 buffer[0] = (div>>8) & 0x7f;
505 buffer[1] = div & 0xff;
506 buffer[2] = config;
507 buffer[3] = cb;
508 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
509 buffer[0], buffer[1], buffer[2], buffer[3]);
510 580
511 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
512 if (4 != rc)
513 tuner_warn("i2c i/o error: rc == %d "
514 "(should be 4)\n", rc);
515 break;
516 }
517 }
518 return 0; 581 return 0;
519} 582}
520 583
@@ -555,33 +618,7 @@ static int simple_set_radio_freq(struct dvb_frontend *fe,
555 } 618 }
556 619
557 /* Bandswitch byte */ 620 /* Bandswitch byte */
558 switch (priv->type) { 621 simple_radio_bandswitch(fe, &buffer[0]);
559 case TUNER_TENA_9533_DI:
560 case TUNER_YMEC_TVF_5533MF:
561 tuner_dbg("This tuner doesn't have FM. "
562 "Most cards have a TEA5767 for FM\n");
563 return 0;
564 case TUNER_PHILIPS_FM1216ME_MK3:
565 case TUNER_PHILIPS_FM1236_MK3:
566 case TUNER_PHILIPS_FMD1216ME_MK3:
567 case TUNER_LG_NTSC_TAPE:
568 case TUNER_PHILIPS_FM1256_IH3:
569 buffer[3] = 0x19;
570 break;
571 case TUNER_TNF_5335MF:
572 buffer[3] = 0x11;
573 break;
574 case TUNER_LG_PAL_FM:
575 buffer[3] = 0xa5;
576 break;
577 case TUNER_THOMSON_DTT761X:
578 buffer[3] = 0x39;
579 break;
580 case TUNER_MICROTUNE_4049FM5:
581 default:
582 buffer[3] = 0xa4;
583 break;
584 }
585 622
586 buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) | 623 buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) |
587 TUNER_RATIO_SELECT_50; /* 50 kHz step */ 624 TUNER_RATIO_SELECT_50; /* 50 kHz step */