Pull sem2mutex-ioc4 into release branch
[linux-2.6] / drivers / media / video / tda9887.c
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
12 #include <media/v4l2-common.h>
13 #include <media/tuner.h>
14
15
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)
26    - Hauppauge PVR-150/500 (possibly more)
27 */
28
29
30 /* Addresses to scan */
31 static unsigned short normal_i2c[] = {
32         0x84 >>1,
33         0x86 >>1,
34         0x96 >>1,
35         I2C_CLIENT_END,
36 };
37 I2C_CLIENT_INSMOD;
38
39 /* insmod options */
40 static unsigned int debug = 0;
41 module_param(debug, int, 0644);
42 MODULE_LICENSE("GPL");
43
44 /* ---------------------------------------------------------------------- */
45
46 #define UNSET       (-1U)
47 #define tda9887_info(fmt, arg...) do {\
48         printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
49                         i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
50 #define tda9887_dbg(fmt, arg...) do {\
51         if (debug) \
52                 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
53                         i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
54
55 struct tda9887 {
56         struct i2c_client  client;
57         v4l2_std_id        std;
58         enum tuner_mode    mode;
59         unsigned int       config;
60         unsigned int       using_v4l2;
61         unsigned int       radio_mode;
62         unsigned char      data[4];
63 };
64
65 struct tvnorm {
66         v4l2_std_id       std;
67         char              *name;
68         unsigned char     b;
69         unsigned char     c;
70         unsigned char     e;
71 };
72
73 static struct i2c_driver driver;
74 static 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
117 #define cTopMask                0x1f    // bit c0:4
118 #define cTopPalSecamDefault     0x14    // bit c0:4
119 #define cTopNtscRadioDefault    0x10    // bit c0:4
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
149 static struct tvnorm tvnorms[] = {
150         {
151                 .std   = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N,
152                 .name  = "PAL-BGHN",
153                 .b     = ( cNegativeFmTV  |
154                            cQSS           ),
155                 .c     = ( cDeemphasisON  |
156                            cDeemphasis50  |
157                            cTopPalSecamDefault),
158                 .e     = ( cGating_36     |
159                            cAudioIF_5_5   |
160                            cVideoIF_38_90 ),
161         },{
162                 .std   = V4L2_STD_PAL_I,
163                 .name  = "PAL-I",
164                 .b     = ( cNegativeFmTV  |
165                            cQSS           ),
166                 .c     = ( cDeemphasisON  |
167                            cDeemphasis50  |
168                            cTopPalSecamDefault),
169                 .e     = ( cGating_36     |
170                            cAudioIF_6_0   |
171                            cVideoIF_38_90 ),
172         },{
173                 .std   = V4L2_STD_PAL_DK,
174                 .name  = "PAL-DK",
175                 .b     = ( cNegativeFmTV  |
176                            cQSS           ),
177                 .c     = ( cDeemphasisON  |
178                            cDeemphasis50  |
179                            cTopPalSecamDefault),
180                 .e     = ( cGating_36     |
181                            cAudioIF_6_5   |
182                            cVideoIF_38_90 ),
183         },{
184                 .std   = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,
185                 .name  = "PAL-M/Nc",
186                 .b     = ( cNegativeFmTV  |
187                            cQSS           ),
188                 .c     = ( cDeemphasisON  |
189                            cDeemphasis75  |
190                            cTopNtscRadioDefault),
191                 .e     = ( cGating_36     |
192                            cAudioIF_4_5   |
193                            cVideoIF_45_75 ),
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         },{
204                 .std   = V4L2_STD_SECAM_L,
205                 .name  = "SECAM-L",
206                 .b     = ( cPositiveAmTV  |
207                            cQSS           ),
208                 .c     = ( cTopPalSecamDefault),
209                 .e     = ( cGating_36     |
210                            cAudioIF_6_5   |
211                            cVideoIF_38_90 ),
212         },{
213                 .std   = V4L2_STD_SECAM_LC,
214                 .name  = "SECAM-L'",
215                 .b     = ( cOutputPort2Inactive |
216                            cPositiveAmTV  |
217                            cQSS           ),
218                 .c     = ( cTopPalSecamDefault),
219                 .e     = ( cGating_36     |
220                            cAudioIF_6_5   |
221                            cVideoIF_33_90 ),
222         },{
223                 .std   = V4L2_STD_SECAM_DK,
224                 .name  = "SECAM-DK",
225                 .b     = ( cNegativeFmTV  |
226                            cQSS           ),
227                 .c     = ( cDeemphasisON  |
228                            cDeemphasis50  |
229                            cTopPalSecamDefault),
230                 .e     = ( cGating_36     |
231                            cAudioIF_6_5   |
232                            cVideoIF_38_90 ),
233         },{
234                 .std   = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
235                 .name  = "NTSC-M",
236                 .b     = ( cNegativeFmTV  |
237                            cQSS           ),
238                 .c     = ( cDeemphasisON  |
239                            cDeemphasis75  |
240                            cTopNtscRadioDefault),
241                 .e     = ( cGating_36     |
242                            cAudioIF_4_5   |
243                            cVideoIF_45_75 ),
244         },{
245                 .std   = V4L2_STD_NTSC_M_JP,
246                 .name  = "NTSC-M-JP",
247                 .b     = ( cNegativeFmTV  |
248                            cQSS           ),
249                 .c     = ( cDeemphasisON  |
250                            cDeemphasis50  |
251                            cTopNtscRadioDefault),
252                 .e     = ( cGating_36     |
253                            cAudioIF_4_5   |
254                            cVideoIF_58_75 ),
255         }
256 };
257
258 static struct tvnorm radio_stereo = {
259         .name = "Radio Stereo",
260         .b    = ( cFmRadio       |
261                   cQSS           ),
262         .c    = ( cDeemphasisOFF |
263                   cAudioGain6    |
264                   cTopNtscRadioDefault),
265         .e    = ( cTunerGainLow  |
266                   cAudioIF_5_5   |
267                   cRadioIF_38_90 ),
268 };
269
270 static struct tvnorm radio_mono = {
271         .name = "Radio Mono",
272         .b    = ( cFmRadio       |
273                   cQSS           ),
274         .c    = ( cDeemphasisON  |
275                   cDeemphasis75  |
276                   cTopNtscRadioDefault),
277         .e    = ( cTunerGainLow  |
278                   cAudioIF_5_5   |
279                   cRadioIF_38_90 ),
280 };
281
282 /* ---------------------------------------------------------------------- */
283
284 static void dump_read_message(struct tda9887 *t, unsigned char *buf)
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         };
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");
310 }
311
312 static void dump_write_message(struct tda9887 *t, unsigned char *buf)
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
352         tda9887_info("write: byte B 0x%02x\n",buf[1]);
353         tda9887_info("  B0   video mode      : %s\n",
354                (buf[1] & 0x01) ? "video trap" : "sound trap");
355         tda9887_info("  B1   auto mute fm    : %s\n",
356                (buf[1] & 0x02) ? "yes" : "no");
357         tda9887_info("  B2   carrier mode    : %s\n",
358                (buf[1] & 0x04) ? "QSS" : "Intercarrier");
359         tda9887_info("  B3-4 tv sound/radio  : %s\n",
360                sound[(buf[1] & 0x18) >> 3]);
361         tda9887_info("  B5   force mute audio: %s\n",
362                (buf[1] & 0x20) ? "yes" : "no");
363         tda9887_info("  B6   output port 1   : %s\n",
364                (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
365         tda9887_info("  B7   output port 2   : %s\n",
366                (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
367
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",
372                (buf[2] & 0x80) ? "-6" : "0");
373
374         tda9887_info("write: byte E 0x%02x\n",buf[3]);
375         tda9887_info("  E0-1 sound carrier   : %s\n",
376                carrier[(buf[3] & 0x03)]);
377         tda9887_info("  E6   l pll gating   : %s\n",
378                (buf[3] & 0x40) ? "36" : "13");
379
380         if (buf[1] & 0x08) {
381                 /* radio */
382                 tda9887_info("  E2-4 video if        : %s\n",
383                        rif[(buf[3] & 0x0c) >> 2]);
384                 tda9887_info("  E7   vif agc output  : %s\n",
385                        (buf[3] & 0x80)
386                        ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
387                        : "fm radio carrier afc");
388         } else {
389                 /* video */
390                 tda9887_info("  E2-4 video if        : %s\n",
391                        vif[(buf[3] & 0x1c) >> 2]);
392                 tda9887_info("  E5   tuner gain      : %s\n",
393                        (buf[3] & 0x80)
394                        ? ((buf[3] & 0x20) ? "external" : "normal")
395                        : ((buf[3] & 0x20) ? "minimum"  : "normal"));
396                 tda9887_info("  E7   vif agc output  : %s\n",
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         }
403         tda9887_info("--\n");
404 }
405
406 /* ---------------------------------------------------------------------- */
407
408 static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
409 {
410         struct tvnorm *norm = NULL;
411         int i;
412
413         if (t->mode == T_RADIO) {
414                 if (t->radio_mode == V4L2_TUNER_MODE_MONO)
415                         norm = &radio_mono;
416                 else
417                         norm = &radio_stereo;
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) {
427                 tda9887_dbg("Unsupported tvnorm entry - audio muted\n");
428                 return -1;
429         }
430
431         tda9887_dbg("configure for: %s\n",norm->name);
432         buf[1] = norm->b;
433         buf[2] = norm->c;
434         buf[3] = norm->e;
435         return 0;
436 }
437
438 static unsigned int port1  = UNSET;
439 static unsigned int port2  = UNSET;
440 static unsigned int qss    = UNSET;
441 static unsigned int adjust = UNSET;
442
443 module_param(port1, int, 0644);
444 module_param(port2, int, 0644);
445 module_param(qss, int, 0644);
446 module_param(adjust, int, 0644);
447
448 static 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
470         if (adjust >= 0x00 && adjust < 0x20) {
471                 buf[2] &= ~cTopMask;
472                 buf[2] |= adjust;
473         }
474         return 0;
475 }
476
477 static 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         }
509         if (t->config & TDA9887_TOP_SET) {
510                 buf[2] &= ~cTopMask;
511                 buf[2] |= (t->config >> 8) & cTopMask;
512         }
513         if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
514                 buf[1] &= ~cQSS;
515         return 0;
516 }
517
518 /* ---------------------------------------------------------------------- */
519
520 static char pal[] = "--";
521 static char secam[] = "--";
522 static char ntsc[] = "-";
523
524 module_param_string(pal, pal, sizeof(pal), 0644);
525 module_param_string(secam, secam, sizeof(secam), 0644);
526 module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
527
528 static 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':
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                         }
548                         break;
549                 case 'i':
550                 case 'I':
551                         tda9887_dbg("insmod fixup: PAL => PAL-I\n");
552                         t->std = V4L2_STD_PAL_I;
553                         break;
554                 case 'd':
555                 case 'D':
556                 case 'k':
557                 case 'K':
558                         tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
559                         t->std = V4L2_STD_PAL_DK;
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;
566                 case '-':
567                         /* default parameter, do nothing */
568                         break;
569                 default:
570                         tda9887_info("pal= argument not recognised\n");
571                         break;
572                 }
573         }
574         if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
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;
585                 case 'd':
586                 case 'D':
587                 case 'k':
588                 case 'K':
589                         tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n");
590                         t->std = V4L2_STD_SECAM_DK;
591                         break;
592                 case 'l':
593                 case 'L':
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                         }
601                         break;
602                 case '-':
603                         /* default parameter, do nothing */
604                         break;
605                 default:
606                         tda9887_info("secam= argument not recognised\n");
607                         break;
608                 }
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 'k':
623                 case 'K':
624                         tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
625                         t->std = V4L2_STD_NTSC_M_KR;
626                         break;
627                 case '-':
628                         /* default parameter, do nothing */
629                         break;
630                 default:
631                         tda9887_info("ntsc= argument not recognised\n");
632                         break;
633                 }
634         }
635         return 0;
636 }
637
638 static int tda9887_status(struct tda9887 *t)
639 {
640         unsigned char buf[1];
641         int rc;
642
643         memset(buf,0,sizeof(buf));
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);
646         dump_read_message(t, buf);
647         return 0;
648 }
649
650 static int tda9887_configure(struct tda9887 *t)
651 {
652         int rc;
653
654         memset(t->data,0,sizeof(t->data));
655         tda9887_set_tvnorm(t,t->data);
656
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          */
670         t->data[1] |= cOutputPort1Inactive;
671         t->data[1] |= cOutputPort2Inactive;
672
673         tda9887_set_config(t,t->data);
674         tda9887_set_insmod(t,t->data);
675
676         if (t->mode == T_STANDBY) {
677                 t->data[1] |= cForcedMuteAudioON;
678         }
679
680         tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
681                 t->data[1],t->data[2],t->data[3]);
682         if (debug > 1)
683                 dump_write_message(t, t->data);
684
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);
687
688         if (debug > 2) {
689                 msleep_interruptible(1000);
690                 tda9887_status(t);
691         }
692         return 0;
693 }
694
695 /* ---------------------------------------------------------------------- */
696
697 static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
698 {
699         struct tda9887 *t;
700
701         client_template.adapter = adap;
702         client_template.addr    = addr;
703
704         if (NULL == (t = kzalloc(sizeof(*t), GFP_KERNEL)))
705                 return -ENOMEM;
706
707         t->client      = client_template;
708         t->std         = 0;
709         t->radio_mode = V4L2_TUNER_MODE_STEREO;
710
711         tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
712
713         i2c_set_clientdata(&t->client, t);
714         i2c_attach_client(&t->client);
715
716         return 0;
717 }
718
719 static int tda9887_probe(struct i2c_adapter *adap)
720 {
721         if (adap->class & I2C_CLASS_TV_ANALOG)
722                 return i2c_probe(adap, &addr_data, tda9887_attach);
723         return 0;
724 }
725
726 static 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) \
736                           tda9887_info("switching to v4l2\n"); \
737                           t->using_v4l2 = 1;
738 #define CHECK_V4L2      if (t->using_v4l2) { if (debug) \
739                           tda9887_info("ignore v4l1 call\n"); \
740                           return 0; }
741
742 static int
743 tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
744 {
745         struct tda9887 *t = i2c_get_clientdata(client);
746
747         switch (cmd) {
748
749         /* --- configuration --- */
750         case AUDC_SET_RADIO:
751         {
752                 t->mode = T_RADIO;
753                 tda9887_configure(t);
754                 break;
755         }
756         case TUNER_SET_STANDBY:
757         {
758                 t->mode = T_STANDBY;
759                 tda9887_configure(t);
760                 break;
761         }
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;
786                 t->mode = T_ANALOG_TV;
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;
798                 t->mode = T_ANALOG_TV;
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) {
810                         if (t->mode == T_ANALOG_TV)
811                                 return 0;
812                         t->mode = T_ANALOG_TV;
813                 }
814                 if (V4L2_TUNER_RADIO == f->type) {
815                         if (t->mode == T_RADIO)
816                                 return 0;
817                         t->mode = T_RADIO;
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
832                 if (t->mode == T_RADIO) {
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         }
840         case VIDIOC_S_TUNER:
841         {
842                 struct v4l2_tuner* tuner = arg;
843
844                 if (t->mode == T_RADIO) {
845                         t->radio_mode = tuner->audmode;
846                         tda9887_configure (t);
847                 }
848                 break;
849         }
850         case VIDIOC_LOG_STATUS:
851         {
852                 tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]);
853                 break;
854         }
855         default:
856                 /* nothing */
857                 break;
858         }
859         return 0;
860 }
861
862 static int tda9887_suspend(struct device * dev, pm_message_t state)
863 {
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");
868         return 0;
869 }
870
871 static int tda9887_resume(struct device * dev)
872 {
873         struct i2c_client *c = container_of(dev, struct i2c_client, dev);
874         struct tda9887 *t = i2c_get_clientdata(c);
875
876         tda9887_dbg("resume\n");
877         tda9887_configure(t);
878         return 0;
879 }
880
881 /* ----------------------------------------------------------------------- */
882
883 static struct i2c_driver driver = {
884         .id             = I2C_DRIVERID_TDA9887,
885         .attach_adapter = tda9887_probe,
886         .detach_client  = tda9887_detach,
887         .command        = tda9887_command,
888         .driver = {
889                 .name    = "tda9887",
890                 .suspend = tda9887_suspend,
891                 .resume  = tda9887_resume,
892         },
893 };
894 static struct i2c_client client_template =
895 {
896         .name      = "tda9887",
897         .driver    = &driver,
898 };
899
900 static int __init tda9887_init_module(void)
901 {
902         return i2c_add_driver(&driver);
903 }
904
905 static void __exit tda9887_cleanup_module(void)
906 {
907         i2c_del_driver(&driver);
908 }
909
910 module_init(tda9887_init_module);
911 module_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  */