diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2006-01-09 12:25:18 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 2006-01-09 12:25:18 -0500 |
commit | f98c55ea18e87905bdf69eb4a187e94572ed9494 (patch) | |
tree | 7e5c755c76bc268ed761735e8fe75d56fa661654 /drivers | |
parent | a82c51d59344117320eeda3715f93c0695a9fbe6 (diff) |
V4L/DVB (3116): tda9887 improvements: better defaults, better configurability.
- Set the tuner takeover point to 0x10 for NTSC/radio and 0x14 for PAL/SECAM.
- Allow override through TDA9887_SET_CONFIG
- PAL-N belongs with PAL-BG as does PAL-H. PAL-Nc belongs to PAL-M
- Add SECAM-BGH
- Set video freq to cVideoIF_38_90 for DK standards.
- Add cTunerGainLow to radio, change deemphasis to 75 for mono.
- Add ntsc module param for 'M' and 'J' (Japanese) standards.
- Fix module handling for 2.4.
- Now able to select all standards through pal/secam/ntsc module options
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/tda9887.c | 164 |
1 files changed, 132 insertions, 32 deletions
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index ceaa29975c8e..32f133ed0b0b 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c | |||
@@ -114,6 +114,9 @@ static struct i2c_client client_template; | |||
114 | #define cAudioGain0 0x00 // bit c7 | 114 | #define cAudioGain0 0x00 // bit c7 |
115 | #define cAudioGain6 0x80 // bit c7 | 115 | #define cAudioGain6 0x80 // bit c7 |
116 | 116 | ||
117 | #define cTopMask 0x1f // bit c0:4 | ||
118 | #define cTopPalSecamDefault 0x14 // bit c0:4 | ||
119 | #define cTopNtscRadioDefault 0x10 // bit c0:4 | ||
117 | 120 | ||
118 | //// third reg (e) | 121 | //// third reg (e) |
119 | #define cAudioIF_4_5 0x00 // bit e0:1 | 122 | #define cAudioIF_4_5 0x00 // bit e0:1 |
@@ -145,13 +148,15 @@ static struct i2c_client client_template; | |||
145 | 148 | ||
146 | static struct tvnorm tvnorms[] = { | 149 | static struct tvnorm tvnorms[] = { |
147 | { | 150 | { |
148 | .std = V4L2_STD_PAL_BG, | 151 | .std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N, |
149 | .name = "PAL-BG", | 152 | .name = "PAL-BGHN", |
150 | .b = ( cNegativeFmTV | | 153 | .b = ( cNegativeFmTV | |
151 | cQSS ), | 154 | cQSS ), |
152 | .c = ( cDeemphasisON | | 155 | .c = ( cDeemphasisON | |
153 | cDeemphasis50 ), | 156 | cDeemphasis50 | |
154 | .e = ( cAudioIF_5_5 | | 157 | cTopPalSecamDefault), |
158 | .e = ( cGating_36 | | ||
159 | cAudioIF_5_5 | | ||
155 | cVideoIF_38_90 ), | 160 | cVideoIF_38_90 ), |
156 | },{ | 161 | },{ |
157 | .std = V4L2_STD_PAL_I, | 162 | .std = V4L2_STD_PAL_I, |
@@ -159,8 +164,10 @@ static struct tvnorm tvnorms[] = { | |||
159 | .b = ( cNegativeFmTV | | 164 | .b = ( cNegativeFmTV | |
160 | cQSS ), | 165 | cQSS ), |
161 | .c = ( cDeemphasisON | | 166 | .c = ( cDeemphasisON | |
162 | cDeemphasis50 ), | 167 | cDeemphasis50 | |
163 | .e = ( cAudioIF_6_0 | | 168 | cTopPalSecamDefault), |
169 | .e = ( cGating_36 | | ||
170 | cAudioIF_6_0 | | ||
164 | cVideoIF_38_90 ), | 171 | cVideoIF_38_90 ), |
165 | },{ | 172 | },{ |
166 | .std = V4L2_STD_PAL_DK, | 173 | .std = V4L2_STD_PAL_DK, |
@@ -168,23 +175,37 @@ static struct tvnorm tvnorms[] = { | |||
168 | .b = ( cNegativeFmTV | | 175 | .b = ( cNegativeFmTV | |
169 | cQSS ), | 176 | cQSS ), |
170 | .c = ( cDeemphasisON | | 177 | .c = ( cDeemphasisON | |
171 | cDeemphasis50 ), | 178 | cDeemphasis50 | |
172 | .e = ( cAudioIF_6_5 | | 179 | cTopPalSecamDefault), |
173 | cVideoIF_38_00 ), | 180 | .e = ( cGating_36 | |
181 | cAudioIF_6_5 | | ||
182 | cVideoIF_38_90 ), | ||
174 | },{ | 183 | },{ |
175 | .std = V4L2_STD_PAL_M | V4L2_STD_PAL_N, | 184 | .std = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc, |
176 | .name = "PAL-M/N", | 185 | .name = "PAL-M/Nc", |
177 | .b = ( cNegativeFmTV | | 186 | .b = ( cNegativeFmTV | |
178 | cQSS ), | 187 | cQSS ), |
179 | .c = ( cDeemphasisON | | 188 | .c = ( cDeemphasisON | |
180 | cDeemphasis75 ), | 189 | cDeemphasis75 | |
181 | .e = ( cAudioIF_4_5 | | 190 | cTopNtscRadioDefault), |
191 | .e = ( cGating_36 | | ||
192 | cAudioIF_4_5 | | ||
182 | cVideoIF_45_75 ), | 193 | cVideoIF_45_75 ), |
183 | },{ | 194 | },{ |
195 | .std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, | ||
196 | .name = "SECAM-BGH", | ||
197 | .b = ( cPositiveAmTV | | ||
198 | cQSS ), | ||
199 | .c = ( cTopPalSecamDefault), | ||
200 | .e = ( cGating_36 | | ||
201 | cAudioIF_5_5 | | ||
202 | cVideoIF_38_90 ), | ||
203 | },{ | ||
184 | .std = V4L2_STD_SECAM_L, | 204 | .std = V4L2_STD_SECAM_L, |
185 | .name = "SECAM-L", | 205 | .name = "SECAM-L", |
186 | .b = ( cPositiveAmTV | | 206 | .b = ( cPositiveAmTV | |
187 | cQSS ), | 207 | cQSS ), |
208 | .c = ( cTopPalSecamDefault), | ||
188 | .e = ( cGating_36 | | 209 | .e = ( cGating_36 | |
189 | cAudioIF_6_5 | | 210 | cAudioIF_6_5 | |
190 | cVideoIF_38_90 ), | 211 | cVideoIF_38_90 ), |
@@ -194,6 +215,7 @@ static struct tvnorm tvnorms[] = { | |||
194 | .b = ( cOutputPort2Inactive | | 215 | .b = ( cOutputPort2Inactive | |
195 | cPositiveAmTV | | 216 | cPositiveAmTV | |
196 | cQSS ), | 217 | cQSS ), |
218 | .c = ( cTopPalSecamDefault), | ||
197 | .e = ( cGating_36 | | 219 | .e = ( cGating_36 | |
198 | cAudioIF_6_5 | | 220 | cAudioIF_6_5 | |
199 | cVideoIF_33_90 ), | 221 | cVideoIF_33_90 ), |
@@ -203,26 +225,30 @@ static struct tvnorm tvnorms[] = { | |||
203 | .b = ( cNegativeFmTV | | 225 | .b = ( cNegativeFmTV | |
204 | cQSS ), | 226 | cQSS ), |
205 | .c = ( cDeemphasisON | | 227 | .c = ( cDeemphasisON | |
206 | cDeemphasis50 ), | 228 | cDeemphasis50 | |
207 | .e = ( cAudioIF_6_5 | | 229 | cTopPalSecamDefault), |
208 | cVideoIF_38_00 ), | 230 | .e = ( cGating_36 | |
231 | cAudioIF_6_5 | | ||
232 | cVideoIF_38_90 ), | ||
209 | },{ | 233 | },{ |
210 | .std = V4L2_STD_NTSC_M, | 234 | .std = V4L2_STD_NTSC_M, |
211 | .name = "NTSC-M", | 235 | .name = "NTSC-M", |
212 | .b = ( cNegativeFmTV | | 236 | .b = ( cNegativeFmTV | |
213 | cQSS ), | 237 | cQSS ), |
214 | .c = ( cDeemphasisON | | 238 | .c = ( cDeemphasisON | |
215 | cDeemphasis75 ), | 239 | cDeemphasis75 | |
240 | cTopNtscRadioDefault), | ||
216 | .e = ( cGating_36 | | 241 | .e = ( cGating_36 | |
217 | cAudioIF_4_5 | | 242 | cAudioIF_4_5 | |
218 | cVideoIF_45_75 ), | 243 | cVideoIF_45_75 ), |
219 | },{ | 244 | },{ |
220 | .std = V4L2_STD_NTSC_M_JP, | 245 | .std = V4L2_STD_NTSC_M_JP, |
221 | .name = "NTSC-JP", | 246 | .name = "NTSC-M-JP", |
222 | .b = ( cNegativeFmTV | | 247 | .b = ( cNegativeFmTV | |
223 | cQSS ), | 248 | cQSS ), |
224 | .c = ( cDeemphasisON | | 249 | .c = ( cDeemphasisON | |
225 | cDeemphasis50 ), | 250 | cDeemphasis50 | |
251 | cTopNtscRadioDefault), | ||
226 | .e = ( cGating_36 | | 252 | .e = ( cGating_36 | |
227 | cAudioIF_4_5 | | 253 | cAudioIF_4_5 | |
228 | cVideoIF_58_75 ), | 254 | cVideoIF_58_75 ), |
@@ -234,8 +260,10 @@ static struct tvnorm radio_stereo = { | |||
234 | .b = ( cFmRadio | | 260 | .b = ( cFmRadio | |
235 | cQSS ), | 261 | cQSS ), |
236 | .c = ( cDeemphasisOFF | | 262 | .c = ( cDeemphasisOFF | |
237 | cAudioGain6 ), | 263 | cAudioGain6 | |
238 | .e = ( cAudioIF_5_5 | | 264 | cTopNtscRadioDefault), |
265 | .e = ( cTunerGainLow | | ||
266 | cAudioIF_5_5 | | ||
239 | cRadioIF_38_90 ), | 267 | cRadioIF_38_90 ), |
240 | }; | 268 | }; |
241 | 269 | ||
@@ -244,8 +272,10 @@ static struct tvnorm radio_mono = { | |||
244 | .b = ( cFmRadio | | 272 | .b = ( cFmRadio | |
245 | cQSS ), | 273 | cQSS ), |
246 | .c = ( cDeemphasisON | | 274 | .c = ( cDeemphasisON | |
247 | cDeemphasis50), | 275 | cDeemphasis75 | |
248 | .e = ( cAudioIF_5_5 | | 276 | cTopNtscRadioDefault), |
277 | .e = ( cTunerGainLow | | ||
278 | cAudioIF_5_5 | | ||
249 | cRadioIF_38_90 ), | 279 | cRadioIF_38_90 ), |
250 | }; | 280 | }; |
251 | 281 | ||
@@ -408,7 +438,8 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) | |||
408 | static unsigned int port1 = UNSET; | 438 | static unsigned int port1 = UNSET; |
409 | static unsigned int port2 = UNSET; | 439 | static unsigned int port2 = UNSET; |
410 | static unsigned int qss = UNSET; | 440 | static unsigned int qss = UNSET; |
411 | static unsigned int adjust = 0x10; | 441 | static unsigned int adjust = UNSET; |
442 | |||
412 | module_param(port1, int, 0644); | 443 | module_param(port1, int, 0644); |
413 | module_param(port2, int, 0644); | 444 | module_param(port2, int, 0644); |
414 | module_param(qss, int, 0644); | 445 | module_param(qss, int, 0644); |
@@ -436,8 +467,10 @@ static int tda9887_set_insmod(struct tda9887 *t, char *buf) | |||
436 | buf[1] &= ~cQSS; | 467 | buf[1] &= ~cQSS; |
437 | } | 468 | } |
438 | 469 | ||
439 | if (adjust >= 0x00 && adjust < 0x20) | 470 | if (adjust >= 0x00 && adjust < 0x20) { |
471 | buf[2] &= ~cTopMask; | ||
440 | buf[2] |= adjust; | 472 | buf[2] |= adjust; |
473 | } | ||
441 | return 0; | 474 | return 0; |
442 | } | 475 | } |
443 | 476 | ||
@@ -473,6 +506,10 @@ static int tda9887_set_config(struct tda9887 *t, char *buf) | |||
473 | break; | 506 | break; |
474 | } | 507 | } |
475 | } | 508 | } |
509 | if (t->config & TDA9887_TOP_SET) { | ||
510 | buf[2] &= ~cTopMask; | ||
511 | buf[2] |= (t->config >> 8) & cTopMask; | ||
512 | } | ||
476 | if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) | 513 | if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) |
477 | buf[1] &= ~cQSS; | 514 | buf[1] &= ~cQSS; |
478 | return 0; | 515 | return 0; |
@@ -480,10 +517,13 @@ static int tda9887_set_config(struct tda9887 *t, char *buf) | |||
480 | 517 | ||
481 | /* ---------------------------------------------------------------------- */ | 518 | /* ---------------------------------------------------------------------- */ |
482 | 519 | ||
483 | static char pal[] = "-"; | 520 | static char pal[] = "--"; |
521 | static char secam[] = "--"; | ||
522 | static char ntsc[] = "-"; | ||
523 | |||
484 | module_param_string(pal, pal, sizeof(pal), 0644); | 524 | module_param_string(pal, pal, sizeof(pal), 0644); |
485 | static char secam[] = "-"; | ||
486 | module_param_string(secam, secam, sizeof(secam), 0644); | 525 | module_param_string(secam, secam, sizeof(secam), 0644); |
526 | module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); | ||
487 | 527 | ||
488 | static int tda9887_fixup_std(struct tda9887 *t) | 528 | static int tda9887_fixup_std(struct tda9887 *t) |
489 | { | 529 | { |
@@ -494,8 +534,17 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
494 | case 'B': | 534 | case 'B': |
495 | case 'g': | 535 | case 'g': |
496 | case 'G': | 536 | case 'G': |
497 | tda9887_dbg("insmod fixup: PAL => PAL-BG\n"); | 537 | case 'h': |
498 | t->std = V4L2_STD_PAL_BG; | 538 | case 'H': |
539 | case 'n': | ||
540 | case 'N': | ||
541 | if (pal[1] == 'c' || pal[1] == 'C') { | ||
542 | tda9887_dbg("insmod fixup: PAL => PAL-Nc\n"); | ||
543 | t->std = V4L2_STD_PAL_Nc; | ||
544 | } else { | ||
545 | tda9887_dbg("insmod fixup: PAL => PAL-BGHN\n"); | ||
546 | t->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N; | ||
547 | } | ||
499 | break; | 548 | break; |
500 | case 'i': | 549 | case 'i': |
501 | case 'I': | 550 | case 'I': |
@@ -509,6 +558,11 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
509 | tda9887_dbg("insmod fixup: PAL => PAL-DK\n"); | 558 | tda9887_dbg("insmod fixup: PAL => PAL-DK\n"); |
510 | t->std = V4L2_STD_PAL_DK; | 559 | t->std = V4L2_STD_PAL_DK; |
511 | break; | 560 | break; |
561 | case 'm': | ||
562 | case 'M': | ||
563 | tda9887_dbg("insmod fixup: PAL => PAL-M\n"); | ||
564 | t->std = V4L2_STD_PAL_M; | ||
565 | break; | ||
512 | case '-': | 566 | case '-': |
513 | /* default parameter, do nothing */ | 567 | /* default parameter, do nothing */ |
514 | break; | 568 | break; |
@@ -519,6 +573,15 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
519 | } | 573 | } |
520 | if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { | 574 | if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { |
521 | switch (secam[0]) { | 575 | switch (secam[0]) { |
576 | case 'b': | ||
577 | case 'B': | ||
578 | case 'g': | ||
579 | case 'G': | ||
580 | case 'h': | ||
581 | case 'H': | ||
582 | tda9887_dbg("insmod fixup: SECAM => SECAM-BGH\n"); | ||
583 | t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; | ||
584 | break; | ||
522 | case 'd': | 585 | case 'd': |
523 | case 'D': | 586 | case 'D': |
524 | case 'k': | 587 | case 'k': |
@@ -528,8 +591,13 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
528 | break; | 591 | break; |
529 | case 'l': | 592 | case 'l': |
530 | case 'L': | 593 | case 'L': |
531 | tda9887_dbg("insmod fixup: SECAM => SECAM-L\n"); | 594 | if (secam[1] == 'c' || secam[1] == 'C') { |
532 | t->std = V4L2_STD_SECAM_L; | 595 | tda9887_dbg("insmod fixup: SECAM => SECAM-L'\n"); |
596 | t->std = V4L2_STD_SECAM_LC; | ||
597 | } else { | ||
598 | tda9887_dbg("insmod fixup: SECAM => SECAM-L\n"); | ||
599 | t->std = V4L2_STD_SECAM_L; | ||
600 | } | ||
533 | break; | 601 | break; |
534 | case '-': | 602 | case '-': |
535 | /* default parameter, do nothing */ | 603 | /* default parameter, do nothing */ |
@@ -539,6 +607,26 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
539 | break; | 607 | break; |
540 | } | 608 | } |
541 | } | 609 | } |
610 | if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { | ||
611 | switch (ntsc[0]) { | ||
612 | case 'm': | ||
613 | case 'M': | ||
614 | tda9887_dbg("insmod fixup: NTSC => NTSC-M\n"); | ||
615 | t->std = V4L2_STD_NTSC_M; | ||
616 | break; | ||
617 | case 'j': | ||
618 | case 'J': | ||
619 | tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); | ||
620 | t->std = V4L2_STD_NTSC_M_JP; | ||
621 | break; | ||
622 | case '-': | ||
623 | /* default parameter, do nothing */ | ||
624 | break; | ||
625 | default: | ||
626 | tda9887_info("ntsc= argument not recognised\n"); | ||
627 | break; | ||
628 | } | ||
629 | } | ||
542 | return 0; | 630 | return 0; |
543 | } | 631 | } |
544 | 632 | ||
@@ -561,6 +649,19 @@ static int tda9887_configure(struct tda9887 *t) | |||
561 | memset(t->data,0,sizeof(t->data)); | 649 | memset(t->data,0,sizeof(t->data)); |
562 | tda9887_set_tvnorm(t,t->data); | 650 | tda9887_set_tvnorm(t,t->data); |
563 | 651 | ||
652 | /* A note on the port settings: | ||
653 | These settings tend to depend on the specifics of the board. | ||
654 | By default they are set to inactive (bit value 1) by this driver, | ||
655 | overwriting any changes made by the tvnorm. This means that it | ||
656 | is the responsibility of the module using the tda9887 to set | ||
657 | these values in case of changes in the tvnorm. | ||
658 | In many cases port 2 should be made active (0) when selecting | ||
659 | SECAM-L, and port 2 should remain inactive (1) for SECAM-L'. | ||
660 | |||
661 | For the other standards the tda9887 application note says that | ||
662 | the ports should be set to active (0), but, again, that may | ||
663 | differ depending on the precise hardware configuration. | ||
664 | */ | ||
564 | t->data[1] |= cOutputPort1Inactive; | 665 | t->data[1] |= cOutputPort1Inactive; |
565 | t->data[1] |= cOutputPort2Inactive; | 666 | t->data[1] |= cOutputPort2Inactive; |
566 | 667 | ||
@@ -571,7 +672,6 @@ static int tda9887_configure(struct tda9887 *t) | |||
571 | t->data[1] |= cForcedMuteAudioON; | 672 | t->data[1] |= cForcedMuteAudioON; |
572 | } | 673 | } |
573 | 674 | ||
574 | |||
575 | tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", | 675 | tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", |
576 | t->data[1],t->data[2],t->data[3]); | 676 | t->data[1],t->data[2],t->data[3]); |
577 | if (debug > 1) | 677 | if (debug > 1) |