Commit ba8fc39954bf3bc51f502e8a02f959d45edd096c

Authored by Hans Verkuil
Committed by Mauro Carvalho Chehab
1 parent 0a1153736f

V4L/DVB (4270): Add tda9887-specific tuner configuration

Many tda9887 settings depend on the chosen tuner. Expand the tuner parameters
to include these tda9887 settings.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

Showing 5 changed files with 160 additions and 13 deletions Side-by-side Diff

drivers/media/video/tda9887.c
... ... @@ -590,8 +590,8 @@
590 590 t->set_tv_freq = tda9887_set_freq;
591 591 t->set_radio_freq = tda9887_set_freq;
592 592 t->standby = tda9887_standby;
593   - t->tuner_status=tda9887_tuner_status;
594   - t->get_afc=tda9887_get_afc;
  593 + t->tuner_status = tda9887_tuner_status;
  594 + t->get_afc = tda9887_get_afc;
595 595  
596 596 return 0;
597 597 }
drivers/media/video/tuner-core.c
... ... @@ -416,7 +416,7 @@
416 416  
417 417 /* ---------------------------------------------------------------------- */
418 418  
419   -/* static var Used only in tuner_attach and tuner_probe */
  419 +/* static vars: used only in tuner_attach and tuner_probe */
420 420 static unsigned default_mode_mask;
421 421  
422 422 /* During client attach, set_type is called by adapter's attach_inform callback.
drivers/media/video/tuner-simple.c
... ... @@ -7,6 +7,7 @@
7 7 #include <linux/i2c.h>
8 8 #include <linux/videodev.h>
9 9 #include <media/tuner.h>
  10 +#include <media/v4l2-common.h>
10 11  
11 12 static int offset = 0;
12 13 module_param(offset, int, 0666);
... ... @@ -128,6 +129,7 @@
128 129 u8 buffer[4];
129 130 int rc, IFPCoff, i, j;
130 131 enum param_type desired_type;
  132 + struct tuner_params *params;
131 133  
132 134 tun = &tuners[t->type];
133 135  
134 136  
135 137  
136 138  
137 139  
... ... @@ -169,19 +171,20 @@
169 171 IFPCoff,t->type);
170 172 j = 0;
171 173 }
  174 + params = &tun->params[j];
172 175  
173   - for (i = 0; i < tun->params[j].count; i++) {
174   - if (freq > tun->params[j].ranges[i].limit)
  176 + for (i = 0; i < params->count; i++) {
  177 + if (freq > params->ranges[i].limit)
175 178 continue;
176 179 break;
177 180 }
178   - if (i == tun->params[j].count) {
  181 + if (i == params->count) {
179 182 tuner_dbg("TV frequency out of range (%d > %d)",
180   - freq, tun->params[j].ranges[i - 1].limit);
181   - freq = tun->params[j].ranges[--i].limit;
  183 + freq, params->ranges[i - 1].limit);
  184 + freq = params->ranges[--i].limit;
182 185 }
183   - config = tun->params[j].ranges[i].config;
184   - cb = tun->params[j].ranges[i].cb;
  186 + config = params->ranges[i].config;
  187 + cb = params->ranges[i].cb;
185 188 /* i == 0 -> VHF_LO
186 189 * i == 1 -> VHF_HI
187 190 * i == 2 -> UHF */
... ... @@ -281,7 +284,7 @@
281 284 break;
282 285 }
283 286  
284   - if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) {
  287 + if (params->cb_first_if_lower_freq && div < t->last_div) {
285 288 buffer[0] = config;
286 289 buffer[1] = cb;
287 290 buffer[2] = (div>>8) & 0x7f;
... ... @@ -293,6 +296,43 @@
293 296 buffer[3] = cb;
294 297 }
295 298 t->last_div = div;
  299 + if (params->has_tda9887) {
  300 + int config = 0;
  301 + int is_secam_l = (t->std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) &&
  302 + !(t->std & ~(V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC));
  303 +
  304 + if (t->std == V4L2_STD_SECAM_LC) {
  305 + if (params->port1_active ^ params->port1_invert_for_secam_lc)
  306 + config |= TDA9887_PORT1_ACTIVE;
  307 + if (params->port2_active ^ params->port2_invert_for_secam_lc)
  308 + config |= TDA9887_PORT2_ACTIVE;
  309 + }
  310 + else {
  311 + if (params->port1_active)
  312 + config |= TDA9887_PORT1_ACTIVE;
  313 + if (params->port2_active)
  314 + config |= TDA9887_PORT2_ACTIVE;
  315 + }
  316 + if (params->intercarrier_mode)
  317 + config |= TDA9887_INTERCARRIER;
  318 + if (is_secam_l) {
  319 + if (i == 0 && params->default_top_secam_low)
  320 + config |= TDA9887_TOP(params->default_top_secam_low);
  321 + else if (i == 1 && params->default_top_secam_mid)
  322 + config |= TDA9887_TOP(params->default_top_secam_mid);
  323 + else if (params->default_top_secam_high)
  324 + config |= TDA9887_TOP(params->default_top_secam_high);
  325 + }
  326 + else {
  327 + if (i == 0 && params->default_top_low)
  328 + config |= TDA9887_TOP(params->default_top_low);
  329 + else if (i == 1 && params->default_top_mid)
  330 + config |= TDA9887_TOP(params->default_top_mid);
  331 + else if (params->default_top_high)
  332 + config |= TDA9887_TOP(params->default_top_high);
  333 + }
  334 + i2c_clients_command(c->adapter, TDA9887_SET_CONFIG, &config);
  335 + }
296 336 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
297 337 buffer[0],buffer[1],buffer[2],buffer[3]);
298 338  
... ... @@ -339,6 +379,7 @@
339 379 u16 div;
340 380 int rc, j;
341 381 enum param_type desired_type = TUNER_PARAM_TYPE_RADIO;
  382 + struct tuner_params *params;
342 383  
343 384 tun = &tuners[t->type];
344 385  
... ... @@ -352,7 +393,8 @@
352 393 j = 0;
353 394  
354 395 div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */
355   - buffer[2] = (tun->params[j].ranges[0].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
  396 + params = &tun->params[j];
  397 + buffer[2] = (params->ranges[0].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
356 398  
357 399 switch (t->type) {
358 400 case TUNER_TENA_9533_DI:
... ... @@ -384,7 +426,7 @@
384 426 }
385 427 buffer[0] = (div>>8) & 0x7f;
386 428 buffer[1] = div & 0xff;
387   - if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) {
  429 + if (params->cb_first_if_lower_freq && div < t->last_div) {
388 430 buffer[0] = buffer[2];
389 431 buffer[1] = buffer[3];
390 432 buffer[2] = (div>>8) & 0x7f;
... ... @@ -398,6 +440,18 @@
398 440 buffer[0],buffer[1],buffer[2],buffer[3]);
399 441 t->last_div = div;
400 442  
  443 + if (params->has_tda9887) {
  444 + int config = 0;
  445 + if (params->port1_active && !params->port1_fm_high_sensitivity)
  446 + config |= TDA9887_PORT1_ACTIVE;
  447 + if (params->port2_active && !params->port2_fm_high_sensitivity)
  448 + config |= TDA9887_PORT2_ACTIVE;
  449 + if (params->intercarrier_mode)
  450 + config |= TDA9887_INTERCARRIER;
  451 +/* if (params->port1_set_for_fm_mono)
  452 + config &= ~TDA9887_PORT1_ACTIVE;*/
  453 + i2c_clients_command(c->adapter, TDA9887_SET_CONFIG, &config);
  454 + }
401 455 if (4 != (rc = i2c_master_send(c,buffer,4)))
402 456 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
403 457 }
drivers/media/video/tuner-types.c
... ... @@ -380,6 +380,10 @@
380 380 .type = TUNER_PARAM_TYPE_PAL,
381 381 .ranges = tuner_lg_pal_ranges,
382 382 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
  383 + .has_tda9887 = 1,
  384 + .port1_active = 1,
  385 + .port2_active = 1,
  386 + .port2_invert_for_secam_lc = 1,
383 387 },
384 388 };
385 389  
... ... @@ -542,6 +546,14 @@
542 546 .ranges = tuner_fm1216me_mk3_pal_ranges,
543 547 .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
544 548 .cb_first_if_lower_freq = 1,
  549 + .has_tda9887 = 1,
  550 + .port1_active = 1,
  551 + .port2_active = 1,
  552 + .port2_invert_for_secam_lc = 1,
  553 + .port1_fm_high_sensitivity = 1,
  554 + .default_top_mid = -2,
  555 + .default_top_secam_mid = -2,
  556 + .default_top_secam_high = -2,
545 557 },
546 558 };
547 559  
... ... @@ -612,6 +624,10 @@
612 624 .ranges = tuner_fm1236_mk3_ntsc_ranges,
613 625 .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
614 626 .cb_first_if_lower_freq = 1,
  627 + .has_tda9887 = 1,
  628 + .port1_active = 1,
  629 + .port2_active = 1,
  630 + .port1_fm_high_sensitivity = 1,
615 631 },
616 632 };
617 633  
... ... @@ -632,6 +648,8 @@
632 648 .type = TUNER_PARAM_TYPE_PAL,
633 649 .ranges = tuner_temic_4009f_5_pal_ranges,
634 650 .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
  651 + .has_tda9887 = 1,
  652 + .port1_invert_for_secam_lc = 1,
635 653 },
636 654 };
637 655  
... ... @@ -648,6 +666,8 @@
648 666 .type = TUNER_PARAM_TYPE_NTSC,
649 667 .ranges = tuner_panasonic_vp27_ntsc_ranges,
650 668 .count = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges),
  669 + .has_tda9887 = 1,
  670 + .intercarrier_mode = 1,
651 671 },
652 672 };
653 673  
... ... @@ -782,6 +802,13 @@
782 802 .type = TUNER_PARAM_TYPE_PAL,
783 803 .ranges = tuner_philips_fq12_6a___mk4_pal_ranges,
784 804 .count = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_pal_ranges),
  805 + .has_tda9887 = 1,
  806 + .port1_active = 1,
  807 + .port2_invert_for_secam_lc = 1,
  808 + .default_top_mid = -2,
  809 + .default_top_secam_low = -2,
  810 + .default_top_secam_mid = -2,
  811 + .default_top_secam_high = -2,
785 812 },
786 813 };
787 814  
... ... @@ -870,6 +897,12 @@
870 897 .type = TUNER_PARAM_TYPE_PAL,
871 898 .ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
872 899 .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
  900 + .has_tda9887 = 1,
  901 + .port1_active = 1,
  902 + .port2_active = 1,
  903 + .port2_fm_high_sensitivity = 1,
  904 + .port2_invert_for_secam_lc = 1,
  905 + .port1_set_for_fm_mono = 1,
873 906 },
874 907 };
875 908  
... ... @@ -1005,6 +1038,7 @@
1005 1038 .type = TUNER_PARAM_TYPE_NTSC,
1006 1039 .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges,
1007 1040 .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges),
  1041 + .has_tda9887 = 1,
1008 1042 },
1009 1043 };
1010 1044  
... ... @@ -1037,6 +1071,10 @@
1037 1071 .type = TUNER_PARAM_TYPE_PAL,
1038 1072 .ranges = tuner_samsung_tcpg_6121p30a_pal_ranges,
1039 1073 .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_pal_ranges),
  1074 + .has_tda9887 = 1,
  1075 + .port1_active = 1,
  1076 + .port2_active = 1,
  1077 + .port2_invert_for_secam_lc = 1,
1040 1078 },
1041 1079 };
1042 1080  
include/media/tuner-types.h
... ... @@ -20,6 +20,7 @@
20 20  
21 21 struct tuner_params {
22 22 enum param_type type;
  23 +
23 24 /* Many Philips based tuners have a comment like this in their
24 25 * datasheet:
25 26 *
... ... @@ -39,6 +40,60 @@
39 40 * static unless the control byte was sent first.
40 41 */
41 42 unsigned int cb_first_if_lower_freq:1;
  43 + /* Set to 1 if this tuner uses a tda9887 */
  44 + unsigned int has_tda9887:1;
  45 + /* Many Philips tuners use tda9887 PORT1 to select the FM radio
  46 + sensitivity. If this setting is 1, then set PORT1 to 1 to
  47 + get proper FM reception. */
  48 + unsigned int port1_fm_high_sensitivity:1;
  49 + /* Some Philips tuners use tda9887 PORT2 to select the FM radio
  50 + sensitivity. If this setting is 1, then set PORT2 to 1 to
  51 + get proper FM reception. */
  52 + unsigned int port2_fm_high_sensitivity:1;
  53 + /* Most tuners with a tda9887 use QSS mode. Some (cheaper) tuners
  54 + use Intercarrier mode. If this setting is 1, then the tuner
  55 + needs to be set to intercarrier mode. */
  56 + unsigned int intercarrier_mode:1;
  57 + /* This setting sets the default value for PORT1.
  58 + 0 means inactive, 1 means active. Note: the actual bit
  59 + value written to the tda9887 is inverted. So a 0 here
  60 + means a 1 in the B6 bit. */
  61 + unsigned int port1_active:1;
  62 + /* This setting sets the default value for PORT2.
  63 + 0 means inactive, 1 means active. Note: the actual bit
  64 + value written to the tda9887 is inverted. So a 0 here
  65 + means a 1 in the B7 bit. */
  66 + unsigned int port2_active:1;
  67 + /* Sometimes PORT1 is inverted when the SECAM-L' standard is selected.
  68 + Set this bit to 1 if this is needed. */
  69 + unsigned int port1_invert_for_secam_lc:1;
  70 + /* Sometimes PORT2 is inverted when the SECAM-L' standard is selected.
  71 + Set this bit to 1 if this is needed. */
  72 + unsigned int port2_invert_for_secam_lc:1;
  73 + /* Some cards require PORT1 to be 1 for mono Radio FM and 0 for stereo. */
  74 + unsigned int port1_set_for_fm_mono:1;
  75 + /* Default tda9887 TOP value in dB for the low band. Default is 0.
  76 + Range: -16:+15 */
  77 + signed int default_top_low:5;
  78 + /* Default tda9887 TOP value in dB for the mid band. Default is 0.
  79 + Range: -16:+15 */
  80 + signed int default_top_mid:5;
  81 + /* Default tda9887 TOP value in dB for the high band. Default is 0.
  82 + Range: -16:+15 */
  83 + signed int default_top_high:5;
  84 + /* Default tda9887 TOP value in dB for SECAM-L/L' for the low band.
  85 + Default is 0. Several tuners require a different TOP value for
  86 + the SECAM-L/L' standards. Range: -16:+15 */
  87 + signed int default_top_secam_low:5;
  88 + /* Default tda9887 TOP value in dB for SECAM-L/L' for the mid band.
  89 + Default is 0. Several tuners require a different TOP value for
  90 + the SECAM-L/L' standards. Range: -16:+15 */
  91 + signed int default_top_secam_mid:5;
  92 + /* Default tda9887 TOP value in dB for SECAM-L/L' for the high band.
  93 + Default is 0. Several tuners require a different TOP value for
  94 + the SECAM-L/L' standards. Range: -16:+15 */
  95 + signed int default_top_secam_high:5;
  96 +
42 97  
43 98 unsigned int count;
44 99 struct tuner_range *ranges;