V4L/DVB (3878): Convert ttpci/budget-patch to refactored tuner code
[deliverable/linux.git] / drivers / media / video / tda9887.c
CommitLineData
1da177e4
LT
1#include <linux/module.h>
2#include <linux/moduleparam.h>
3#include <linux/kernel.h>
4#include <linux/i2c.h>
5#include <linux/types.h>
6#include <linux/videodev.h>
7#include <linux/init.h>
8#include <linux/errno.h>
9#include <linux/slab.h>
10#include <linux/delay.h>
11
5e453dc7 12#include <media/v4l2-common.h>
1da177e4 13#include <media/tuner.h>
1da177e4 14
674434c6 15
1da177e4
LT
16/* Chips:
17 TDA9885 (PAL, NTSC)
18 TDA9886 (PAL, SECAM, NTSC)
19 TDA9887 (PAL, SECAM, NTSC, FM Radio)
20
21 found on:
22 - Pinnacle PCTV (Jul.2002 Version with MT2032, bttv)
23 TDA9887 (world), TDA9885 (USA)
24 Note: OP2 of tda988x must be set to 1, else MT2032 is disabled!
25 - KNC One TV-Station RDS (saa7134)
21d4df37 26 - Hauppauge PVR-150/500 (possibly more)
1da177e4
LT
27*/
28
29
30/* Addresses to scan */
31static unsigned short normal_i2c[] = {
32 0x84 >>1,
33 0x86 >>1,
34 0x96 >>1,
35 I2C_CLIENT_END,
36};
1da177e4
LT
37I2C_CLIENT_INSMOD;
38
39/* insmod options */
40static unsigned int debug = 0;
41module_param(debug, int, 0644);
42MODULE_LICENSE("GPL");
43
44/* ---------------------------------------------------------------------- */
45
46#define UNSET (-1U)
4eb0c144
HV
47#define tda9887_info(fmt, arg...) do {\
48 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
4ac97914 49 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
4eb0c144
HV
50#define tda9887_dbg(fmt, arg...) do {\
51 if (debug) \
4ac97914
MCC
52 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
53 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
1da177e4
LT
54
55struct tda9887 {
56 struct i2c_client client;
57 v4l2_std_id std;
793cf9e6 58 enum tuner_mode mode;
1da177e4 59 unsigned int config;
1da177e4 60 unsigned int using_v4l2;
56fc08ca 61 unsigned int radio_mode;
299392bf 62 unsigned char data[4];
1da177e4
LT
63};
64
65struct tvnorm {
66 v4l2_std_id std;
67 char *name;
68 unsigned char b;
69 unsigned char c;
70 unsigned char e;
71};
72
73static struct i2c_driver driver;
74static struct i2c_client client_template;
75
76/* ---------------------------------------------------------------------- */
77
78//
79// TDA defines
80//
81
82//// first reg (b)
83#define cVideoTrapBypassOFF 0x00 // bit b0
84#define cVideoTrapBypassON 0x01 // bit b0
85
86#define cAutoMuteFmInactive 0x00 // bit b1
87#define cAutoMuteFmActive 0x02 // bit b1
88
89#define cIntercarrier 0x00 // bit b2
90#define cQSS 0x04 // bit b2
91
92#define cPositiveAmTV 0x00 // bit b3:4
93#define cFmRadio 0x08 // bit b3:4
94#define cNegativeFmTV 0x10 // bit b3:4
95
96
97#define cForcedMuteAudioON 0x20 // bit b5
98#define cForcedMuteAudioOFF 0x00 // bit b5
99
100#define cOutputPort1Active 0x00 // bit b6
101#define cOutputPort1Inactive 0x40 // bit b6
102
103#define cOutputPort2Active 0x00 // bit b7
104#define cOutputPort2Inactive 0x80 // bit b7
105
106
107//// second reg (c)
108#define cDeemphasisOFF 0x00 // bit c5
109#define cDeemphasisON 0x20 // bit c5
110
111#define cDeemphasis75 0x00 // bit c6
112#define cDeemphasis50 0x40 // bit c6
113
114#define cAudioGain0 0x00 // bit c7
115#define cAudioGain6 0x80 // bit c7
116
f98c55ea
HV
117#define cTopMask 0x1f // bit c0:4
118#define cTopPalSecamDefault 0x14 // bit c0:4
119#define cTopNtscRadioDefault 0x10 // bit c0:4
1da177e4
LT
120
121//// third reg (e)
122#define cAudioIF_4_5 0x00 // bit e0:1
123#define cAudioIF_5_5 0x01 // bit e0:1
124#define cAudioIF_6_0 0x02 // bit e0:1
125#define cAudioIF_6_5 0x03 // bit e0:1
126
127
128#define cVideoIF_58_75 0x00 // bit e2:4
129#define cVideoIF_45_75 0x04 // bit e2:4
130#define cVideoIF_38_90 0x08 // bit e2:4
131#define cVideoIF_38_00 0x0C // bit e2:4
132#define cVideoIF_33_90 0x10 // bit e2:4
133#define cVideoIF_33_40 0x14 // bit e2:4
134#define cRadioIF_45_75 0x18 // bit e2:4
135#define cRadioIF_38_90 0x1C // bit e2:4
136
137
138#define cTunerGainNormal 0x00 // bit e5
139#define cTunerGainLow 0x20 // bit e5
140
141#define cGating_18 0x00 // bit e6
142#define cGating_36 0x40 // bit e6
143
144#define cAgcOutON 0x80 // bit e7
145#define cAgcOutOFF 0x00 // bit e7
146
147/* ---------------------------------------------------------------------- */
148
149static struct tvnorm tvnorms[] = {
150 {
f98c55ea
HV
151 .std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N,
152 .name = "PAL-BGHN",
1da177e4
LT
153 .b = ( cNegativeFmTV |
154 cQSS ),
155 .c = ( cDeemphasisON |
f98c55ea
HV
156 cDeemphasis50 |
157 cTopPalSecamDefault),
158 .e = ( cGating_36 |
159 cAudioIF_5_5 |
1da177e4
LT
160 cVideoIF_38_90 ),
161 },{
162 .std = V4L2_STD_PAL_I,
163 .name = "PAL-I",
164 .b = ( cNegativeFmTV |
165 cQSS ),
166 .c = ( cDeemphasisON |
f98c55ea
HV
167 cDeemphasis50 |
168 cTopPalSecamDefault),
169 .e = ( cGating_36 |
170 cAudioIF_6_0 |
1da177e4
LT
171 cVideoIF_38_90 ),
172 },{
173 .std = V4L2_STD_PAL_DK,
174 .name = "PAL-DK",
175 .b = ( cNegativeFmTV |
176 cQSS ),
177 .c = ( cDeemphasisON |
f98c55ea
HV
178 cDeemphasis50 |
179 cTopPalSecamDefault),
180 .e = ( cGating_36 |
181 cAudioIF_6_5 |
182 cVideoIF_38_90 ),
1da177e4 183 },{
f98c55ea
HV
184 .std = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,
185 .name = "PAL-M/Nc",
1da177e4
LT
186 .b = ( cNegativeFmTV |
187 cQSS ),
188 .c = ( cDeemphasisON |
f98c55ea
HV
189 cDeemphasis75 |
190 cTopNtscRadioDefault),
191 .e = ( cGating_36 |
192 cAudioIF_4_5 |
1da177e4 193 cVideoIF_45_75 ),
f98c55ea
HV
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 ),
1da177e4
LT
203 },{
204 .std = V4L2_STD_SECAM_L,
205 .name = "SECAM-L",
206 .b = ( cPositiveAmTV |
207 cQSS ),
f98c55ea 208 .c = ( cTopPalSecamDefault),
3375c398 209 .e = ( cGating_36 |
5f7591c0 210 cAudioIF_6_5 |
1da177e4 211 cVideoIF_38_90 ),
f3c5987a
MCC
212 },{
213 .std = V4L2_STD_SECAM_LC,
214 .name = "SECAM-L'",
215 .b = ( cOutputPort2Inactive |
216 cPositiveAmTV |
217 cQSS ),
f98c55ea 218 .c = ( cTopPalSecamDefault),
f3c5987a
MCC
219 .e = ( cGating_36 |
220 cAudioIF_6_5 |
221 cVideoIF_33_90 ),
1da177e4
LT
222 },{
223 .std = V4L2_STD_SECAM_DK,
224 .name = "SECAM-DK",
225 .b = ( cNegativeFmTV |
226 cQSS ),
227 .c = ( cDeemphasisON |
f98c55ea
HV
228 cDeemphasis50 |
229 cTopPalSecamDefault),
230 .e = ( cGating_36 |
231 cAudioIF_6_5 |
232 cVideoIF_38_90 ),
1da177e4 233 },{
0dfd812d 234 .std = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
1da177e4
LT
235 .name = "NTSC-M",
236 .b = ( cNegativeFmTV |
237 cQSS ),
238 .c = ( cDeemphasisON |
f98c55ea
HV
239 cDeemphasis75 |
240 cTopNtscRadioDefault),
1da177e4
LT
241 .e = ( cGating_36 |
242 cAudioIF_4_5 |
243 cVideoIF_45_75 ),
244 },{
245 .std = V4L2_STD_NTSC_M_JP,
f98c55ea 246 .name = "NTSC-M-JP",
1da177e4
LT
247 .b = ( cNegativeFmTV |
248 cQSS ),
249 .c = ( cDeemphasisON |
f98c55ea
HV
250 cDeemphasis50 |
251 cTopNtscRadioDefault),
1da177e4
LT
252 .e = ( cGating_36 |
253 cAudioIF_4_5 |
254 cVideoIF_58_75 ),
255 }
256};
257
56fc08ca
MCC
258static struct tvnorm radio_stereo = {
259 .name = "Radio Stereo",
260 .b = ( cFmRadio |
261 cQSS ),
262 .c = ( cDeemphasisOFF |
f98c55ea
HV
263 cAudioGain6 |
264 cTopNtscRadioDefault),
265 .e = ( cTunerGainLow |
266 cAudioIF_5_5 |
56fc08ca
MCC
267 cRadioIF_38_90 ),
268};
269
270static struct tvnorm radio_mono = {
271 .name = "Radio Mono",
1da177e4
LT
272 .b = ( cFmRadio |
273 cQSS ),
274 .c = ( cDeemphasisON |
f98c55ea
HV
275 cDeemphasis75 |
276 cTopNtscRadioDefault),
277 .e = ( cTunerGainLow |
278 cAudioIF_5_5 |
1da177e4
LT
279 cRadioIF_38_90 ),
280};
281
282/* ---------------------------------------------------------------------- */
283
4eb0c144 284static void dump_read_message(struct tda9887 *t, unsigned char *buf)
1da177e4
LT
285{
286 static char *afc[16] = {
287 "- 12.5 kHz",
288 "- 37.5 kHz",
289 "- 62.5 kHz",
290 "- 87.5 kHz",
291 "-112.5 kHz",
292 "-137.5 kHz",
293 "-162.5 kHz",
294 "-187.5 kHz [min]",
295 "+187.5 kHz [max]",
296 "+162.5 kHz",
297 "+137.5 kHz",
298 "+112.5 kHz",
299 "+ 87.5 kHz",
300 "+ 62.5 kHz",
301 "+ 37.5 kHz",
302 "+ 12.5 kHz",
303 };
4eb0c144
HV
304 tda9887_info("read: 0x%2x\n", buf[0]);
305 tda9887_info(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
306 tda9887_info(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
307 tda9887_info(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
308 tda9887_info(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
309 tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
1da177e4
LT
310}
311
4eb0c144 312static void dump_write_message(struct tda9887 *t, unsigned char *buf)
1da177e4
LT
313{
314 static char *sound[4] = {
315 "AM/TV",
316 "FM/radio",
317 "FM/TV",
318 "FM/radio"
319 };
320 static char *adjust[32] = {
321 "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
322 "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1",
323 "0", "+1", "+2", "+3", "+4", "+5", "+6", "+7",
324 "+8", "+9", "+10", "+11", "+12", "+13", "+14", "+15"
325 };
326 static char *deemph[4] = {
327 "no", "no", "75", "50"
328 };
329 static char *carrier[4] = {
330 "4.5 MHz",
331 "5.5 MHz",
332 "6.0 MHz",
333 "6.5 MHz / AM"
334 };
335 static char *vif[8] = {
336 "58.75 MHz",
337 "45.75 MHz",
338 "38.9 MHz",
339 "38.0 MHz",
340 "33.9 MHz",
341 "33.4 MHz",
342 "45.75 MHz + pin13",
343 "38.9 MHz + pin13",
344 };
345 static char *rif[4] = {
346 "44 MHz",
347 "52 MHz",
348 "52 MHz",
349 "44 MHz",
350 };
351
4eb0c144
HV
352 tda9887_info("write: byte B 0x%02x\n",buf[1]);
353 tda9887_info(" B0 video mode : %s\n",
1da177e4 354 (buf[1] & 0x01) ? "video trap" : "sound trap");
4eb0c144 355 tda9887_info(" B1 auto mute fm : %s\n",
1da177e4 356 (buf[1] & 0x02) ? "yes" : "no");
4eb0c144 357 tda9887_info(" B2 carrier mode : %s\n",
1da177e4 358 (buf[1] & 0x04) ? "QSS" : "Intercarrier");
4eb0c144 359 tda9887_info(" B3-4 tv sound/radio : %s\n",
1da177e4 360 sound[(buf[1] & 0x18) >> 3]);
4eb0c144 361 tda9887_info(" B5 force mute audio: %s\n",
1da177e4 362 (buf[1] & 0x20) ? "yes" : "no");
4eb0c144 363 tda9887_info(" B6 output port 1 : %s\n",
1da177e4 364 (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
4eb0c144 365 tda9887_info(" B7 output port 2 : %s\n",
1da177e4
LT
366 (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
367
4eb0c144
HV
368 tda9887_info("write: byte C 0x%02x\n",buf[2]);
369 tda9887_info(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]);
370 tda9887_info(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]);
371 tda9887_info(" C7 audio gain : %s\n",
1da177e4
LT
372 (buf[2] & 0x80) ? "-6" : "0");
373
4eb0c144
HV
374 tda9887_info("write: byte E 0x%02x\n",buf[3]);
375 tda9887_info(" E0-1 sound carrier : %s\n",
1da177e4 376 carrier[(buf[3] & 0x03)]);
4eb0c144 377 tda9887_info(" E6 l pll gating : %s\n",
1da177e4
LT
378 (buf[3] & 0x40) ? "36" : "13");
379
380 if (buf[1] & 0x08) {
381 /* radio */
4eb0c144 382 tda9887_info(" E2-4 video if : %s\n",
1da177e4 383 rif[(buf[3] & 0x0c) >> 2]);
4eb0c144 384 tda9887_info(" E7 vif agc output : %s\n",
1da177e4
LT
385 (buf[3] & 0x80)
386 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
387 : "fm radio carrier afc");
388 } else {
389 /* video */
4eb0c144 390 tda9887_info(" E2-4 video if : %s\n",
1da177e4 391 vif[(buf[3] & 0x1c) >> 2]);
4eb0c144 392 tda9887_info(" E5 tuner gain : %s\n",
1da177e4
LT
393 (buf[3] & 0x80)
394 ? ((buf[3] & 0x20) ? "external" : "normal")
395 : ((buf[3] & 0x20) ? "minimum" : "normal"));
4eb0c144 396 tda9887_info(" E7 vif agc output : %s\n",
1da177e4
LT
397 (buf[3] & 0x80)
398 ? ((buf[3] & 0x20)
399 ? "pin3 port, pin22 vif agc out"
400 : "pin22 port, pin3 vif acg ext in")
401 : "pin3+pin22 port");
402 }
4eb0c144 403 tda9887_info("--\n");
1da177e4
LT
404}
405
406/* ---------------------------------------------------------------------- */
407
408static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
409{
410 struct tvnorm *norm = NULL;
411 int i;
412
793cf9e6 413 if (t->mode == T_RADIO) {
56fc08ca
MCC
414 if (t->radio_mode == V4L2_TUNER_MODE_MONO)
415 norm = &radio_mono;
416 else
586b0cab 417 norm = &radio_stereo;
1da177e4
LT
418 } else {
419 for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
420 if (tvnorms[i].std & t->std) {
421 norm = tvnorms+i;
422 break;
423 }
424 }
425 }
426 if (NULL == norm) {
4eb0c144 427 tda9887_dbg("Unsupported tvnorm entry - audio muted\n");
1da177e4
LT
428 return -1;
429 }
430
4eb0c144 431 tda9887_dbg("configure for: %s\n",norm->name);
1da177e4
LT
432 buf[1] = norm->b;
433 buf[2] = norm->c;
434 buf[3] = norm->e;
435 return 0;
436}
437
438static unsigned int port1 = UNSET;
439static unsigned int port2 = UNSET;
440static unsigned int qss = UNSET;
f98c55ea
HV
441static unsigned int adjust = UNSET;
442
1da177e4
LT
443module_param(port1, int, 0644);
444module_param(port2, int, 0644);
445module_param(qss, int, 0644);
446module_param(adjust, int, 0644);
447
448static int tda9887_set_insmod(struct tda9887 *t, char *buf)
449{
450 if (UNSET != port1) {
451 if (port1)
452 buf[1] |= cOutputPort1Inactive;
453 else
454 buf[1] &= ~cOutputPort1Inactive;
455 }
456 if (UNSET != port2) {
457 if (port2)
458 buf[1] |= cOutputPort2Inactive;
459 else
460 buf[1] &= ~cOutputPort2Inactive;
461 }
462
463 if (UNSET != qss) {
464 if (qss)
465 buf[1] |= cQSS;
466 else
467 buf[1] &= ~cQSS;
468 }
469
f98c55ea
HV
470 if (adjust >= 0x00 && adjust < 0x20) {
471 buf[2] &= ~cTopMask;
1da177e4 472 buf[2] |= adjust;
f98c55ea 473 }
1da177e4
LT
474 return 0;
475}
476
477static int tda9887_set_config(struct tda9887 *t, char *buf)
478{
479 if (t->config & TDA9887_PORT1_ACTIVE)
480 buf[1] &= ~cOutputPort1Inactive;
481 if (t->config & TDA9887_PORT1_INACTIVE)
482 buf[1] |= cOutputPort1Inactive;
483 if (t->config & TDA9887_PORT2_ACTIVE)
484 buf[1] &= ~cOutputPort2Inactive;
485 if (t->config & TDA9887_PORT2_INACTIVE)
486 buf[1] |= cOutputPort2Inactive;
487
488 if (t->config & TDA9887_QSS)
489 buf[1] |= cQSS;
490 if (t->config & TDA9887_INTERCARRIER)
491 buf[1] &= ~cQSS;
492
493 if (t->config & TDA9887_AUTOMUTE)
494 buf[1] |= cAutoMuteFmActive;
495 if (t->config & TDA9887_DEEMPHASIS_MASK) {
496 buf[2] &= ~0x60;
497 switch (t->config & TDA9887_DEEMPHASIS_MASK) {
498 case TDA9887_DEEMPHASIS_NONE:
499 buf[2] |= cDeemphasisOFF;
500 break;
501 case TDA9887_DEEMPHASIS_50:
502 buf[2] |= cDeemphasisON | cDeemphasis50;
503 break;
504 case TDA9887_DEEMPHASIS_75:
505 buf[2] |= cDeemphasisON | cDeemphasis75;
506 break;
507 }
508 }
f98c55ea
HV
509 if (t->config & TDA9887_TOP_SET) {
510 buf[2] &= ~cTopMask;
511 buf[2] |= (t->config >> 8) & cTopMask;
512 }
3ae1adc6
NS
513 if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
514 buf[1] &= ~cQSS;
1da177e4
LT
515 return 0;
516}
517
518/* ---------------------------------------------------------------------- */
519
f98c55ea
HV
520static char pal[] = "--";
521static char secam[] = "--";
522static char ntsc[] = "-";
523
975e046c 524module_param_string(pal, pal, sizeof(pal), 0644);
975e046c 525module_param_string(secam, secam, sizeof(secam), 0644);
f98c55ea 526module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
1da177e4
LT
527
528static int tda9887_fixup_std(struct tda9887 *t)
529{
530 /* get more precise norm info from insmod option */
531 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
532 switch (pal[0]) {
533 case 'b':
534 case 'B':
535 case 'g':
536 case 'G':
f98c55ea
HV
537 case 'h':
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 }
1da177e4
LT
548 break;
549 case 'i':
550 case 'I':
4eb0c144 551 tda9887_dbg("insmod fixup: PAL => PAL-I\n");
1da177e4
LT
552 t->std = V4L2_STD_PAL_I;
553 break;
554 case 'd':
555 case 'D':
556 case 'k':
557 case 'K':
4eb0c144 558 tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
1da177e4
LT
559 t->std = V4L2_STD_PAL_DK;
560 break;
f98c55ea
HV
561 case 'm':
562 case 'M':
563 tda9887_dbg("insmod fixup: PAL => PAL-M\n");
564 t->std = V4L2_STD_PAL_M;
565 break;
21d4df37
MCC
566 case '-':
567 /* default parameter, do nothing */
568 break;
569 default:
4eb0c144 570 tda9887_info("pal= argument not recognised\n");
21d4df37 571 break;
1da177e4
LT
572 }
573 }
574 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
575 switch (secam[0]) {
f98c55ea
HV
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;
1da177e4
LT
585 case 'd':
586 case 'D':
587 case 'k':
588 case 'K':
4eb0c144 589 tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n");
1da177e4
LT
590 t->std = V4L2_STD_SECAM_DK;
591 break;
592 case 'l':
593 case 'L':
f98c55ea
HV
594 if (secam[1] == 'c' || secam[1] == 'C') {
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 }
1da177e4 601 break;
21d4df37
MCC
602 case '-':
603 /* default parameter, do nothing */
604 break;
605 default:
4eb0c144 606 tda9887_info("secam= argument not recognised\n");
21d4df37 607 break;
1da177e4
LT
608 }
609 }
f98c55ea
HV
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;
0dfd812d
HV
622 case 'k':
623 case 'K':
624 tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
625 t->std = V4L2_STD_NTSC_M_KR;
626 break;
f98c55ea
HV
627 case '-':
628 /* default parameter, do nothing */
629 break;
630 default:
631 tda9887_info("ntsc= argument not recognised\n");
632 break;
633 }
634 }
1da177e4
LT
635 return 0;
636}
637
638static int tda9887_status(struct tda9887 *t)
639{
640 unsigned char buf[1];
641 int rc;
642
643 memset(buf,0,sizeof(buf));
4ac97914
MCC
644 if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
645 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
4eb0c144 646 dump_read_message(t, buf);
1da177e4
LT
647 return 0;
648}
649
650static int tda9887_configure(struct tda9887 *t)
651{
1da177e4
LT
652 int rc;
653
299392bf
HV
654 memset(t->data,0,sizeof(t->data));
655 tda9887_set_tvnorm(t,t->data);
56fc08ca 656
f98c55ea
HV
657 /* A note on the port settings:
658 These settings tend to depend on the specifics of the board.
659 By default they are set to inactive (bit value 1) by this driver,
660 overwriting any changes made by the tvnorm. This means that it
661 is the responsibility of the module using the tda9887 to set
662 these values in case of changes in the tvnorm.
663 In many cases port 2 should be made active (0) when selecting
664 SECAM-L, and port 2 should remain inactive (1) for SECAM-L'.
665
666 For the other standards the tda9887 application note says that
667 the ports should be set to active (0), but, again, that may
668 differ depending on the precise hardware configuration.
669 */
299392bf
HV
670 t->data[1] |= cOutputPort1Inactive;
671 t->data[1] |= cOutputPort2Inactive;
56fc08ca 672
299392bf
HV
673 tda9887_set_config(t,t->data);
674 tda9887_set_insmod(t,t->data);
1da177e4 675
793cf9e6 676 if (t->mode == T_STANDBY) {
299392bf 677 t->data[1] |= cForcedMuteAudioON;
793cf9e6
MCC
678 }
679
4eb0c144 680 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
299392bf 681 t->data[1],t->data[2],t->data[3]);
1da177e4 682 if (debug > 1)
299392bf 683 dump_write_message(t, t->data);
1da177e4 684
4ac97914
MCC
685 if (4 != (rc = i2c_master_send(&t->client,t->data,4)))
686 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
1da177e4
LT
687
688 if (debug > 2) {
689 msleep_interruptible(1000);
690 tda9887_status(t);
691 }
692 return 0;
693}
694
695/* ---------------------------------------------------------------------- */
696
697static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
698{
699 struct tda9887 *t;
700
4ac97914
MCC
701 client_template.adapter = adap;
702 client_template.addr = addr;
1da177e4 703
7408187d 704 if (NULL == (t = kzalloc(sizeof(*t), GFP_KERNEL)))
4ac97914 705 return -ENOMEM;
56fc08ca 706
1da177e4
LT
707 t->client = client_template;
708 t->std = 0;
56fc08ca
MCC
709 t->radio_mode = V4L2_TUNER_MODE_STEREO;
710
4ac97914 711 tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
4eb0c144 712
586b0cab
MCC
713 i2c_set_clientdata(&t->client, t);
714 i2c_attach_client(&t->client);
1da177e4
LT
715
716 return 0;
717}
718
719static int tda9887_probe(struct i2c_adapter *adap)
720{
1da177e4
LT
721 if (adap->class & I2C_CLASS_TV_ANALOG)
722 return i2c_probe(adap, &addr_data, tda9887_attach);
1da177e4
LT
723 return 0;
724}
725
726static int tda9887_detach(struct i2c_client *client)
727{
728 struct tda9887 *t = i2c_get_clientdata(client);
729
730 i2c_detach_client(client);
731 kfree(t);
732 return 0;
733}
734
735#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \
4ac97914
MCC
736 tda9887_info("switching to v4l2\n"); \
737 t->using_v4l2 = 1;
1da177e4 738#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \
4eb0c144 739 tda9887_info("ignore v4l1 call\n"); \
4ac97914 740 return 0; }
1da177e4
LT
741
742static int
743tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
744{
745 struct tda9887 *t = i2c_get_clientdata(client);
746
4ac97914 747 switch (cmd) {
1da177e4
LT
748
749 /* --- configuration --- */
750 case AUDC_SET_RADIO:
793cf9e6
MCC
751 {
752 t->mode = T_RADIO;
1da177e4
LT
753 tda9887_configure(t);
754 break;
793cf9e6
MCC
755 }
756 case TUNER_SET_STANDBY:
757 {
758 t->mode = T_STANDBY;
759 tda9887_configure(t);
760 break;
761 }
1da177e4
LT
762 case TDA9887_SET_CONFIG:
763 {
764 int *i = arg;
765
766 t->config = *i;
767 tda9887_configure(t);
768 break;
769 }
770 /* --- v4l ioctls --- */
771 /* take care: bttv does userspace copying, we'll get a
772 kernel pointer here... */
773 case VIDIOCSCHAN:
774 {
775 static const v4l2_std_id map[] = {
776 [ VIDEO_MODE_PAL ] = V4L2_STD_PAL,
777 [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M,
778 [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
779 [ 4 /* bttv */ ] = V4L2_STD_PAL_M,
780 [ 5 /* bttv */ ] = V4L2_STD_PAL_N,
781 [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
782 };
783 struct video_channel *vc = arg;
784
785 CHECK_V4L2;
793cf9e6 786 t->mode = T_ANALOG_TV;
1da177e4
LT
787 if (vc->norm < ARRAY_SIZE(map))
788 t->std = map[vc->norm];
789 tda9887_fixup_std(t);
790 tda9887_configure(t);
791 break;
792 }
793 case VIDIOC_S_STD:
794 {
795 v4l2_std_id *id = arg;
796
797 SWITCH_V4L2;
793cf9e6 798 t->mode = T_ANALOG_TV;
1da177e4
LT
799 t->std = *id;
800 tda9887_fixup_std(t);
801 tda9887_configure(t);
802 break;
803 }
804 case VIDIOC_S_FREQUENCY:
805 {
806 struct v4l2_frequency *f = arg;
807
808 SWITCH_V4L2;
809 if (V4L2_TUNER_ANALOG_TV == f->type) {
793cf9e6 810 if (t->mode == T_ANALOG_TV)
1da177e4 811 return 0;
793cf9e6 812 t->mode = T_ANALOG_TV;
1da177e4
LT
813 }
814 if (V4L2_TUNER_RADIO == f->type) {
793cf9e6 815 if (t->mode == T_RADIO)
1da177e4 816 return 0;
793cf9e6 817 t->mode = T_RADIO;
1da177e4
LT
818 }
819 tda9887_configure(t);
820 break;
821 }
822 case VIDIOC_G_TUNER:
823 {
824 static int AFC_BITS_2_kHz[] = {
825 -12500, -37500, -62500, -97500,
826 -112500, -137500, -162500, -187500,
827 187500, 162500, 137500, 112500,
828 97500 , 62500, 37500 , 12500
829 };
830 struct v4l2_tuner* tuner = arg;
831
793cf9e6 832 if (t->mode == T_RADIO) {
1da177e4
LT
833 __u8 reg = 0;
834 tuner->afc=0;
835 if (1 == i2c_master_recv(&t->client,&reg,1))
836 tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
837 }
838 break;
839 }
56fc08ca
MCC
840 case VIDIOC_S_TUNER:
841 {
842 struct v4l2_tuner* tuner = arg;
843
793cf9e6 844 if (t->mode == T_RADIO) {
56fc08ca
MCC
845 t->radio_mode = tuner->audmode;
846 tda9887_configure (t);
847 }
848 break;
849 }
299392bf
HV
850 case VIDIOC_LOG_STATUS:
851 {
cd43c3f6 852 tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]);
299392bf
HV
853 break;
854 }
1da177e4
LT
855 default:
856 /* nothing */
857 break;
858 }
859 return 0;
860}
861
9480e307 862static int tda9887_suspend(struct device * dev, pm_message_t state)
1da177e4 863{
4eb0c144
HV
864 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
865 struct tda9887 *t = i2c_get_clientdata(c);
866
867 tda9887_dbg("suspend\n");
1da177e4
LT
868 return 0;
869}
870
9480e307 871static int tda9887_resume(struct device * dev)
1da177e4
LT
872{
873 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
874 struct tda9887 *t = i2c_get_clientdata(c);
875
4eb0c144 876 tda9887_dbg("resume\n");
1da177e4
LT
877 tda9887_configure(t);
878 return 0;
879}
880
881/* ----------------------------------------------------------------------- */
882
883static struct i2c_driver driver = {
20c40878 884 .id = I2C_DRIVERID_TDA9887,
afd1a0c9
MCC
885 .attach_adapter = tda9887_probe,
886 .detach_client = tda9887_detach,
887 .command = tda9887_command,
1da177e4 888 .driver = {
cab462f7 889 .name = "tda9887",
1da177e4
LT
890 .suspend = tda9887_suspend,
891 .resume = tda9887_resume,
892 },
893};
894static struct i2c_client client_template =
895{
fae91e72 896 .name = "tda9887",
afd1a0c9 897 .driver = &driver,
1da177e4
LT
898};
899
900static int __init tda9887_init_module(void)
901{
902 return i2c_add_driver(&driver);
903}
904
905static void __exit tda9887_cleanup_module(void)
906{
907 i2c_del_driver(&driver);
908}
909
910module_init(tda9887_init_module);
911module_exit(tda9887_cleanup_module);
912
913/*
914 * Overrides for Emacs so that we follow Linus's tabbing style.
915 * ---------------------------------------------------------------------------
916 * Local variables:
917 * c-basic-offset: 8
918 * End:
919 */
This page took 0.366261 seconds and 5 git commands to generate.