aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2006-01-09 12:25:18 -0500
committerMauro Carvalho Chehab <mchehab@brturbo.com.br>2006-01-09 12:25:18 -0500
commitf98c55ea18e87905bdf69eb4a187e94572ed9494 (patch)
tree7e5c755c76bc268ed761735e8fe75d56fa661654
parenta82c51d59344117320eeda3715f93c0695a9fbe6 (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>
-rw-r--r--drivers/media/video/tda9887.c164
-rw-r--r--include/media/tuner.h31
2 files changed, 150 insertions, 45 deletions
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index ceaa29975c8..32f133ed0b0 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
146static struct tvnorm tvnorms[] = { 149static 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)
408static unsigned int port1 = UNSET; 438static unsigned int port1 = UNSET;
409static unsigned int port2 = UNSET; 439static unsigned int port2 = UNSET;
410static unsigned int qss = UNSET; 440static unsigned int qss = UNSET;
411static unsigned int adjust = 0x10; 441static unsigned int adjust = UNSET;
442
412module_param(port1, int, 0644); 443module_param(port1, int, 0644);
413module_param(port2, int, 0644); 444module_param(port2, int, 0644);
414module_param(qss, int, 0644); 445module_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
483static char pal[] = "-"; 520static char pal[] = "--";
521static char secam[] = "--";
522static char ntsc[] = "-";
523
484module_param_string(pal, pal, sizeof(pal), 0644); 524module_param_string(pal, pal, sizeof(pal), 0644);
485static char secam[] = "-";
486module_param_string(secam, secam, sizeof(secam), 0644); 525module_param_string(secam, secam, sizeof(secam), 0644);
526module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
487 527
488static int tda9887_fixup_std(struct tda9887 *t) 528static 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)
diff --git a/include/media/tuner.h b/include/media/tuner.h
index e224722a7ff..567f05549e3 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -120,20 +120,25 @@
120#define TDA9887_SET_CONFIG _IOW('t',5,int) 120#define TDA9887_SET_CONFIG _IOW('t',5,int)
121 121
122/* tv card specific */ 122/* tv card specific */
123# define TDA9887_PRESENT (1<<0) 123#define TDA9887_PRESENT (1<<0)
124# define TDA9887_PORT1_INACTIVE (1<<1) 124#define TDA9887_PORT1_INACTIVE (1<<1)
125# define TDA9887_PORT2_INACTIVE (1<<2) 125#define TDA9887_PORT2_INACTIVE (1<<2)
126# define TDA9887_QSS (1<<3) 126#define TDA9887_QSS (1<<3)
127# define TDA9887_INTERCARRIER (1<<4) 127#define TDA9887_INTERCARRIER (1<<4)
128# define TDA9887_PORT1_ACTIVE (1<<5) 128#define TDA9887_PORT1_ACTIVE (1<<5)
129# define TDA9887_PORT2_ACTIVE (1<<6) 129#define TDA9887_PORT2_ACTIVE (1<<6)
130# define TDA9887_INTERCARRIER_NTSC (1<<7) 130#define TDA9887_INTERCARRIER_NTSC (1<<7)
131/* Tuner takeover point adjustment, in dB, -16 <= top <= 15 */
132#define TDA9887_TOP_MASK (0x3f << 8)
133#define TDA9887_TOP_SET (1 << 13)
134#define TDA9887_TOP(top) (TDA9887_TOP_SET | (((16 + (top)) & 0x1f) << 8))
135
131/* config options */ 136/* config options */
132# define TDA9887_DEEMPHASIS_MASK (3<<16) 137#define TDA9887_DEEMPHASIS_MASK (3<<16)
133# define TDA9887_DEEMPHASIS_NONE (1<<16) 138#define TDA9887_DEEMPHASIS_NONE (1<<16)
134# define TDA9887_DEEMPHASIS_50 (2<<16) 139#define TDA9887_DEEMPHASIS_50 (2<<16)
135# define TDA9887_DEEMPHASIS_75 (3<<16) 140#define TDA9887_DEEMPHASIS_75 (3<<16)
136# define TDA9887_AUTOMUTE (1<<18) 141#define TDA9887_AUTOMUTE (1<<18)
137 142
138#ifdef __KERNEL__ 143#ifdef __KERNEL__
139 144