]> err.no Git - linux-2.6/blob - drivers/media/video/tda9887.c
V4L/DVB (3116): tda9887 improvements: better defaults, better configurability.
[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/audiochip.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,
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 '-':
623                         /* default parameter, do nothing */
624                         break;
625                 default:
626                         tda9887_info("ntsc= argument not recognised\n");
627                         break;
628                 }
629         }
630         return 0;
631 }
632
633 static int tda9887_status(struct tda9887 *t)
634 {
635         unsigned char buf[1];
636         int rc;
637
638         memset(buf,0,sizeof(buf));
639         if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
640                 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
641         dump_read_message(t, buf);
642         return 0;
643 }
644
645 static int tda9887_configure(struct tda9887 *t)
646 {
647         int rc;
648
649         memset(t->data,0,sizeof(t->data));
650         tda9887_set_tvnorm(t,t->data);
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          */
665         t->data[1] |= cOutputPort1Inactive;
666         t->data[1] |= cOutputPort2Inactive;
667
668         tda9887_set_config(t,t->data);
669         tda9887_set_insmod(t,t->data);
670
671         if (t->mode == T_STANDBY) {
672                 t->data[1] |= cForcedMuteAudioON;
673         }
674
675         tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
676                 t->data[1],t->data[2],t->data[3]);
677         if (debug > 1)
678                 dump_write_message(t, t->data);
679
680         if (4 != (rc = i2c_master_send(&t->client,t->data,4)))
681                 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
682
683         if (debug > 2) {
684                 msleep_interruptible(1000);
685                 tda9887_status(t);
686         }
687         return 0;
688 }
689
690 /* ---------------------------------------------------------------------- */
691
692 static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
693 {
694         struct tda9887 *t;
695
696         client_template.adapter = adap;
697         client_template.addr    = addr;
698
699         if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
700                 return -ENOMEM;
701         memset(t,0,sizeof(*t));
702
703         t->client      = client_template;
704         t->std         = 0;
705         t->radio_mode = V4L2_TUNER_MODE_STEREO;
706
707         tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
708
709         i2c_set_clientdata(&t->client, t);
710         i2c_attach_client(&t->client);
711
712         return 0;
713 }
714
715 static int tda9887_probe(struct i2c_adapter *adap)
716 {
717 #ifdef I2C_CLASS_TV_ANALOG
718         if (adap->class & I2C_CLASS_TV_ANALOG)
719                 return i2c_probe(adap, &addr_data, tda9887_attach);
720 #else
721         switch (adap->id) {
722         case I2C_HW_B_BT848:
723         case I2C_HW_B_RIVA:
724         case I2C_HW_SAA7134:
725                 return i2c_probe(adap, &addr_data, tda9887_attach);
726                 break;
727         }
728 #endif
729         return 0;
730 }
731
732 static int tda9887_detach(struct i2c_client *client)
733 {
734         struct tda9887 *t = i2c_get_clientdata(client);
735
736         i2c_detach_client(client);
737         kfree(t);
738         return 0;
739 }
740
741 #define SWITCH_V4L2     if (!t->using_v4l2 && debug) \
742                           tda9887_info("switching to v4l2\n"); \
743                           t->using_v4l2 = 1;
744 #define CHECK_V4L2      if (t->using_v4l2) { if (debug) \
745                           tda9887_info("ignore v4l1 call\n"); \
746                           return 0; }
747
748 static int
749 tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
750 {
751         struct tda9887 *t = i2c_get_clientdata(client);
752
753         switch (cmd) {
754
755         /* --- configuration --- */
756         case AUDC_SET_RADIO:
757         {
758                 t->mode = T_RADIO;
759                 tda9887_configure(t);
760                 break;
761         }
762         case TUNER_SET_STANDBY:
763         {
764                 t->mode = T_STANDBY;
765                 tda9887_configure(t);
766                 break;
767         }
768         case TDA9887_SET_CONFIG:
769         {
770                 int *i = arg;
771
772                 t->config = *i;
773                 tda9887_configure(t);
774                 break;
775         }
776         /* --- v4l ioctls --- */
777         /* take care: bttv does userspace copying, we'll get a
778            kernel pointer here... */
779         case VIDIOCSCHAN:
780         {
781                 static const v4l2_std_id map[] = {
782                         [ VIDEO_MODE_PAL   ] = V4L2_STD_PAL,
783                         [ VIDEO_MODE_NTSC  ] = V4L2_STD_NTSC_M,
784                         [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
785                         [ 4 /* bttv */     ] = V4L2_STD_PAL_M,
786                         [ 5 /* bttv */     ] = V4L2_STD_PAL_N,
787                         [ 6 /* bttv */     ] = V4L2_STD_NTSC_M_JP,
788                 };
789                 struct video_channel *vc = arg;
790
791                 CHECK_V4L2;
792                 t->mode = T_ANALOG_TV;
793                 if (vc->norm < ARRAY_SIZE(map))
794                         t->std = map[vc->norm];
795                 tda9887_fixup_std(t);
796                 tda9887_configure(t);
797                 break;
798         }
799         case VIDIOC_S_STD:
800         {
801                 v4l2_std_id *id = arg;
802
803                 SWITCH_V4L2;
804                 t->mode = T_ANALOG_TV;
805                 t->std   = *id;
806                 tda9887_fixup_std(t);
807                 tda9887_configure(t);
808                 break;
809         }
810         case VIDIOC_S_FREQUENCY:
811         {
812                 struct v4l2_frequency *f = arg;
813
814                 SWITCH_V4L2;
815                 if (V4L2_TUNER_ANALOG_TV == f->type) {
816                         if (t->mode == T_ANALOG_TV)
817                                 return 0;
818                         t->mode = T_ANALOG_TV;
819                 }
820                 if (V4L2_TUNER_RADIO == f->type) {
821                         if (t->mode == T_RADIO)
822                                 return 0;
823                         t->mode = T_RADIO;
824                 }
825                 tda9887_configure(t);
826                 break;
827         }
828         case VIDIOC_G_TUNER:
829         {
830                 static int AFC_BITS_2_kHz[] = {
831                         -12500,  -37500,  -62500,  -97500,
832                         -112500, -137500, -162500, -187500,
833                         187500,  162500,  137500,  112500,
834                         97500 ,  62500,   37500 ,  12500
835                 };
836                 struct v4l2_tuner* tuner = arg;
837
838                 if (t->mode == T_RADIO) {
839                         __u8 reg = 0;
840                         tuner->afc=0;
841                         if (1 == i2c_master_recv(&t->client,&reg,1))
842                                 tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
843                 }
844                 break;
845         }
846         case VIDIOC_S_TUNER:
847         {
848                 struct v4l2_tuner* tuner = arg;
849
850                 if (t->mode == T_RADIO) {
851                         t->radio_mode = tuner->audmode;
852                         tda9887_configure (t);
853                 }
854                 break;
855         }
856         case VIDIOC_LOG_STATUS:
857         {
858                 tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]);
859                 break;
860         }
861         default:
862                 /* nothing */
863                 break;
864         }
865         return 0;
866 }
867
868 static int tda9887_suspend(struct device * dev, pm_message_t state)
869 {
870         struct i2c_client *c = container_of(dev, struct i2c_client, dev);
871         struct tda9887 *t = i2c_get_clientdata(c);
872
873         tda9887_dbg("suspend\n");
874         return 0;
875 }
876
877 static int tda9887_resume(struct device * dev)
878 {
879         struct i2c_client *c = container_of(dev, struct i2c_client, dev);
880         struct tda9887 *t = i2c_get_clientdata(c);
881
882         tda9887_dbg("resume\n");
883         tda9887_configure(t);
884         return 0;
885 }
886
887 /* ----------------------------------------------------------------------- */
888
889 static struct i2c_driver driver = {
890         .id             = -1, /* FIXME */
891         .attach_adapter = tda9887_probe,
892         .detach_client  = tda9887_detach,
893         .command        = tda9887_command,
894         .driver = {
895                 .name    = "i2c tda9887 driver",
896                 .suspend = tda9887_suspend,
897                 .resume  = tda9887_resume,
898         },
899 };
900 static struct i2c_client client_template =
901 {
902         .name      = "tda9887",
903         .driver    = &driver,
904 };
905
906 static int __init tda9887_init_module(void)
907 {
908         return i2c_add_driver(&driver);
909 }
910
911 static void __exit tda9887_cleanup_module(void)
912 {
913         i2c_del_driver(&driver);
914 }
915
916 module_init(tda9887_init_module);
917 module_exit(tda9887_cleanup_module);
918
919 /*
920  * Overrides for Emacs so that we follow Linus's tabbing style.
921  * ---------------------------------------------------------------------------
922  * Local variables:
923  * c-basic-offset: 8
924  * End:
925  */