Commit ba8fc39954bf3bc51f502e8a02f959d45edd096c
Committed by
Mauro Carvalho Chehab
1 parent
0a1153736f
Exists in
master
and in
7 other branches
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; |