vserver 1.9.3
[linux-2.6.git] / drivers / media / video / tda9887.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/i2c.h>
4 #include <linux/types.h>
5 #include <linux/videodev.h>
6 #include <linux/init.h>
7 #include <linux/errno.h>
8 #include <linux/slab.h>
9
10 #include <media/audiochip.h>
11 #include <media/tuner.h>
12 #include <media/id.h>
13
14 /* Chips:
15    TDA9885 (PAL, NTSC)
16    TDA9886 (PAL, SECAM, NTSC)
17    TDA9887 (PAL, SECAM, NTSC, FM Radio)
18
19    found on:
20    - Pinnacle PCTV (Jul.2002 Version with MT2032, bttv)
21       TDA9887 (world), TDA9885 (USA)
22       Note: OP2 of tda988x must be set to 1, else MT2032 is disabled!
23    - KNC One TV-Station RDS (saa7134)
24 */
25
26
27 /* Addresses to scan */
28 static unsigned short normal_i2c[] = {
29         0x86 >>1,
30         0x96 >>1,
31         I2C_CLIENT_END,
32 };
33 static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END};
34 I2C_CLIENT_INSMOD;
35
36 /* insmod options */
37 static unsigned int debug = 0;
38 MODULE_PARM(debug,"i");
39 MODULE_LICENSE("GPL");
40
41 /* ---------------------------------------------------------------------- */
42
43 #define UNSET       (-1U)
44 #define PREFIX      "tda9885/6/7: "
45 #define dprintk     if (debug) printk
46
47 struct tda9887 {
48         struct i2c_client  client;
49         v4l2_std_id        std;
50         unsigned int       radio;
51         unsigned int       config;
52         unsigned int       pinnacle_id;
53         unsigned int       using_v4l2;
54 };
55
56 struct tvnorm {
57         v4l2_std_id       std;
58         char              *name;
59         unsigned char     b;
60         unsigned char     c;
61         unsigned char     e;
62 };
63
64 static struct i2c_driver driver;
65 static struct i2c_client client_template;
66
67 /* ---------------------------------------------------------------------- */
68
69 //
70 // TDA defines
71 //
72
73 //// first reg (b)
74 #define cVideoTrapBypassOFF     0x00    // bit b0
75 #define cVideoTrapBypassON      0x01    // bit b0
76
77 #define cAutoMuteFmInactive     0x00    // bit b1
78 #define cAutoMuteFmActive       0x02    // bit b1
79
80 #define cIntercarrier           0x00    // bit b2
81 #define cQSS                    0x04    // bit b2
82
83 #define cPositiveAmTV           0x00    // bit b3:4
84 #define cFmRadio                0x08    // bit b3:4
85 #define cNegativeFmTV           0x10    // bit b3:4
86
87
88 #define cForcedMuteAudioON      0x20    // bit b5
89 #define cForcedMuteAudioOFF     0x00    // bit b5
90
91 #define cOutputPort1Active      0x00    // bit b6
92 #define cOutputPort1Inactive    0x40    // bit b6
93
94 #define cOutputPort2Active      0x00    // bit b7
95 #define cOutputPort2Inactive    0x80    // bit b7
96
97
98 //// second reg (c)
99 #define cDeemphasisOFF          0x00    // bit c5
100 #define cDeemphasisON           0x20    // bit c5
101
102 #define cDeemphasis75           0x00    // bit c6
103 #define cDeemphasis50           0x40    // bit c6
104
105 #define cAudioGain0             0x00    // bit c7
106 #define cAudioGain6             0x80    // bit c7
107
108
109 //// third reg (e)
110 #define cAudioIF_4_5             0x00    // bit e0:1
111 #define cAudioIF_5_5             0x01    // bit e0:1
112 #define cAudioIF_6_0             0x02    // bit e0:1
113 #define cAudioIF_6_5             0x03    // bit e0:1
114
115
116 #define cVideoIF_58_75           0x00    // bit e2:4
117 #define cVideoIF_45_75           0x04    // bit e2:4
118 #define cVideoIF_38_90           0x08    // bit e2:4
119 #define cVideoIF_38_00           0x0C    // bit e2:4
120 #define cVideoIF_33_90           0x10    // bit e2:4
121 #define cVideoIF_33_40           0x14    // bit e2:4
122 #define cRadioIF_45_75           0x18    // bit e2:4
123 #define cRadioIF_38_90           0x1C    // bit e2:4
124
125
126 #define cTunerGainNormal         0x00    // bit e5
127 #define cTunerGainLow            0x20    // bit e5
128
129 #define cGating_18               0x00    // bit e6
130 #define cGating_36               0x40    // bit e6
131
132 #define cAgcOutON                0x80    // bit e7
133 #define cAgcOutOFF               0x00    // bit e7
134
135 /* ---------------------------------------------------------------------- */
136
137 static struct tvnorm tvnorms[] = {
138         {
139                 .std   = V4L2_STD_PAL_BG,
140                 .name  = "PAL-BG",
141                 .b     = ( cNegativeFmTV  |
142                            cQSS           ),
143                 .c     = ( cDeemphasisON  |
144                            cDeemphasis50  ),
145                 .e     = ( cAudioIF_5_5   |
146                            cVideoIF_38_90 ),
147         },{
148                 .std   = V4L2_STD_PAL_I,
149                 .name  = "PAL-I",
150                 .b     = ( cNegativeFmTV  |
151                            cQSS           ),
152                 .c     = ( cDeemphasisON  |
153                            cDeemphasis50  ),
154                 .e     = ( cAudioIF_6_0   |
155                            cVideoIF_38_90 ),
156         },{
157                 .std   = V4L2_STD_PAL_DK,
158                 .name  = "PAL-DK",
159                 .b     = ( cNegativeFmTV  |
160                            cQSS           ),
161                 .c     = ( cDeemphasisON  |
162                            cDeemphasis50  ),
163                 .e     = ( cAudioIF_6_5   |
164                            cVideoIF_38_00 ),
165         },{
166                 .std   = V4L2_STD_PAL_M | V4L2_STD_PAL_N,
167                 .name  = "PAL-M/N",
168                 .b     = ( cNegativeFmTV  |
169                            cQSS           ),
170                 .c     = ( cDeemphasisON  |
171                            cDeemphasis75  ),
172                 .e     = ( cAudioIF_4_5   |
173                            cVideoIF_45_75 ),
174         },{
175                 .std   = V4L2_STD_SECAM_L,
176                 .name  = "SECAM-L",
177                 .b     = ( cPositiveAmTV  |
178                            cQSS           ),
179                 .e     = ( cAudioIF_6_5   |
180                            cVideoIF_38_90 ),
181         },{
182                 .std   = V4L2_STD_SECAM_DK,
183                 .name  = "SECAM-DK",
184                 .b     = ( cNegativeFmTV  |
185                            cQSS           ),
186                 .c     = ( cDeemphasisON  |
187                            cDeemphasis50  ),
188                 .e     = ( cAudioIF_6_5   |
189                            cVideoIF_38_00 ),
190         },{
191                 .std   = V4L2_STD_NTSC_M,
192                 .name  = "NTSC-M",
193                 .b     = ( cNegativeFmTV  |
194                            cQSS           ),
195                 .c     = ( cDeemphasisON  |
196                            cDeemphasis50  ),
197                 .e     = ( cGating_36     |
198                            cAudioIF_4_5   |
199                            cVideoIF_45_75 ),
200         },{
201                 .std   = V4L2_STD_NTSC_M_JP,
202                 .name  = "NTSC-JP",
203                 .b     = ( cNegativeFmTV  |
204                            cQSS           ),
205                 .c     = ( cDeemphasisON  |
206                            cDeemphasis50  ),
207                 .e     = ( cGating_36     |
208                            cAudioIF_4_5   |
209                            cVideoIF_58_75 ),
210         }
211 };
212
213 static struct tvnorm radio = {
214         .name = "radio",
215         .b    = ( cFmRadio       |
216                   cQSS           ),
217         .c    = ( cDeemphasisON  |
218                   cDeemphasis50  ),
219         .e    = ( cAudioIF_5_5   |
220                   cRadioIF_38_90 ),
221 };
222
223 /* ---------------------------------------------------------------------- */
224
225 static void dump_read_message(unsigned char *buf)
226 {
227         static char *afc[16] = {
228                 "- 12.5 kHz",
229                 "- 37.5 kHz",
230                 "- 62.5 kHz",
231                 "- 87.5 kHz",
232                 "-112.5 kHz",
233                 "-137.5 kHz",
234                 "-162.5 kHz",
235                 "-187.5 kHz [min]",
236                 "+187.5 kHz [max]",
237                 "+162.5 kHz",
238                 "+137.5 kHz",
239                 "+112.5 kHz",
240                 "+ 87.5 kHz",
241                 "+ 62.5 kHz",
242                 "+ 37.5 kHz",
243                 "+ 12.5 kHz",
244         };
245         printk(PREFIX "read: 0x%2x\n", buf[0]);
246         printk("  after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
247         printk("  afc            : %s\n", afc[(buf[0] >> 1) & 0x0f]);
248         printk("  afc window     : %s\n", (buf[0] & 0x40) ? "in" : "out");
249         printk("  vfi level      : %s\n", (buf[0] & 0x80) ? "high" : "low");
250 }
251
252 static void dump_write_message(unsigned char *buf)
253 {
254         static char *sound[4] = {
255                 "AM/TV",
256                 "FM/radio",
257                 "FM/TV",
258                 "FM/radio"
259         };
260         static char *adjust[32] = {
261                 "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
262                 "-8",  "-7",  "-6",  "-5",  "-4",  "-3",  "-2",  "-1",
263                 "0",   "+1",  "+2",  "+3",  "+4",  "+5",  "+6",  "+7",
264                 "+8",  "+9",  "+10", "+11", "+12", "+13", "+14", "+15"
265         };
266         static char *deemph[4] = {
267                 "no", "no", "75", "50"
268         };
269         static char *carrier[4] = {
270                 "4.5 MHz",
271                 "5.5 MHz",
272                 "6.0 MHz",
273                 "6.5 MHz / AM"
274         };
275         static char *vif[8] = {
276                 "58.75 MHz",
277                 "45.75 MHz",
278                 "38.9 MHz",
279                 "38.0 MHz",
280                 "33.9 MHz",
281                 "33.4 MHz",
282                 "45.75 MHz + pin13",
283                 "38.9 MHz + pin13",
284         };
285         static char *rif[4] = {
286                 "44 MHz",
287                 "52 MHz",
288                 "52 MHz",
289                 "44 MHz",
290         };
291
292         printk(PREFIX "write: byte B 0x%02x\n",buf[1]);
293         printk("  B0   video mode      : %s\n",
294                (buf[1] & 0x01) ? "video trap" : "sound trap");
295         printk("  B1   auto mute fm    : %s\n",
296                (buf[1] & 0x02) ? "yes" : "no");
297         printk("  B2   carrier mode    : %s\n",
298                (buf[1] & 0x04) ? "QSS" : "Intercarrier");
299         printk("  B3-4 tv sound/radio  : %s\n",
300                sound[(buf[1] & 0x18) >> 3]);
301         printk("  B5   force mute audio: %s\n",
302                (buf[1] & 0x20) ? "yes" : "no");
303         printk("  B6   output port 1   : %s\n",
304                (buf[1] & 0x40) ? "high" : "low");
305         printk("  B7   output port 2   : %s\n",
306                (buf[1] & 0x80) ? "high" : "low");
307
308         printk(PREFIX "write: byte C 0x%02x\n",buf[2]);
309         printk("  C0-4 top adjustment  : %s dB\n", adjust[buf[2] & 0x1f]);
310         printk("  C5-6 de-emphasis     : %s\n", deemph[(buf[2] & 0x60) >> 5]);
311         printk("  C7   audio gain      : %s\n",
312                (buf[2] & 0x80) ? "-6" : "0");
313
314         printk(PREFIX "write: byte E 0x%02x\n",buf[3]);
315         printk("  E0-1 sound carrier   : %s\n",
316                carrier[(buf[3] & 0x03)]);
317         printk("  E6   l pll ganting   : %s\n",
318                (buf[3] & 0x40) ? "36" : "13");
319
320         if (buf[1] & 0x08) {
321                 /* radio */
322                 printk("  E2-4 video if        : %s\n",
323                        rif[(buf[3] & 0x0c) >> 2]);
324                 printk("  E7   vif agc output  : %s\n",
325                        (buf[3] & 0x80)
326                        ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
327                        : "fm radio carrier afc");
328         } else {
329                 /* video */
330                 printk("  E2-4 video if        : %s\n",
331                        vif[(buf[3] & 0x1c) >> 2]);
332                 printk("  E5   tuner gain      : %s\n",
333                        (buf[3] & 0x80)
334                        ? ((buf[3] & 0x20) ? "external" : "normal")
335                        : ((buf[3] & 0x20) ? "minimum"  : "normal"));
336                 printk("  E7   vif agc output  : %s\n",
337                        (buf[3] & 0x80)
338                        ? ((buf[3] & 0x20)
339                           ? "pin3 port, pin22 vif agc out"
340                           : "pin22 port, pin3 vif acg ext in")
341                        : "pin3+pin22 port");
342         }
343         printk("--\n");
344 }
345
346 /* ---------------------------------------------------------------------- */
347
348 static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
349 {
350         struct tvnorm *norm = NULL;
351         int i;
352
353         if (t->radio) {
354                 norm = &radio;
355         } else {
356                 for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
357                         if (tvnorms[i].std & t->std) {
358                                 norm = tvnorms+i;
359                                 break;
360                         }
361                 }
362         }
363         if (NULL == norm) {
364                 dprintk(PREFIX "Oops: no tvnorm entry found\n");
365                 return -1;
366         }
367
368         dprintk(PREFIX "configure for: %s\n",norm->name);
369         buf[1] = norm->b;
370         buf[2] = norm->c;
371         buf[3] = norm->e;
372         return 0;
373 }
374
375 static unsigned int port1  = 1;
376 static unsigned int port2  = 1;
377 static unsigned int qss    = UNSET;
378 static unsigned int adjust = 0x10;
379 MODULE_PARM(port1,"i");
380 MODULE_PARM(port2,"i");
381 MODULE_PARM(qss,"i");
382 MODULE_PARM(adjust,"i");
383
384 static int tda9887_set_insmod(struct tda9887 *t, char *buf)
385 {
386         if (port1)
387                 buf[1] |= cOutputPort1Inactive;
388         if (port2)
389                 buf[1] |= cOutputPort2Inactive;
390         if (UNSET != qss) {
391                 if (qss)
392                         buf[1] |= cQSS;
393                 else
394                         buf[1] &= ~cQSS;
395         }
396
397         if (adjust >= 0x00 && adjust < 0x20)
398                 buf[2] |= adjust;
399         return 0;
400 }
401
402 static int tda9887_set_config(struct tda9887 *t, char *buf)
403 {
404         if (t->config & TDA9887_PORT1)
405                 buf[1] |= cOutputPort1Inactive;
406         if (t->config & TDA9887_PORT2)
407                 buf[1] |= cOutputPort2Inactive;
408         if (t->config & TDA9887_QSS)
409                 buf[1] |= cQSS;
410         if (t->config & TDA9887_INTERCARRIER)
411                 buf[1] &= ~cQSS;
412
413         if (t->config & TDA9887_AUTOMUTE)
414                 buf[1] |= cAutoMuteFmActive;
415         if (t->config & TDA9887_DEEMPHASIS_MASK) {
416                 buf[2] &= ~0x60;
417                 switch (t->config & TDA9887_DEEMPHASIS_MASK) {
418                 case TDA9887_DEEMPHASIS_NONE:
419                         buf[2] |= cDeemphasisOFF;
420                         break;
421                 case TDA9887_DEEMPHASIS_50:
422                         buf[2] |= cDeemphasisON | cDeemphasis50;
423                         break;
424                 case TDA9887_DEEMPHASIS_75:
425                         buf[2] |= cDeemphasisON | cDeemphasis75;
426                         break;
427                 }
428         }
429         return 0;
430 }
431
432 /* ---------------------------------------------------------------------- */
433
434 static int tda9887_set_pinnacle(struct tda9887 *t, char *buf)
435 {
436         unsigned int bCarrierMode = UNSET;
437
438         if (t->std & V4L2_STD_PAL) {
439                 if ((1 == t->pinnacle_id) || (7 == t->pinnacle_id)) {
440                         bCarrierMode = cIntercarrier;
441                 } else {
442                         bCarrierMode = cQSS;
443                 }
444         }
445         if (t->std & V4L2_STD_NTSC) {
446                 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
447                         bCarrierMode = cIntercarrier;
448                 } else {
449                         bCarrierMode = cQSS;
450                 }
451         }
452
453         if (bCarrierMode != UNSET) {
454                 buf[1] &= ~0x04;
455                 buf[1] |= bCarrierMode;
456         }
457         return 0;
458 }
459
460 /* ---------------------------------------------------------------------- */
461
462 static char *pal = "-";
463 MODULE_PARM(pal,"s");
464 static char *secam = "-";
465 MODULE_PARM(secam,"s");
466
467 static int tda9887_fixup_std(struct tda9887 *t)
468 {
469         /* get more precise norm info from insmod option */
470         if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
471                 switch (pal[0]) {
472                 case 'b':
473                 case 'B':
474                 case 'g':
475                 case 'G':
476                         dprintk(PREFIX "insmod fixup: PAL => PAL-BG\n");
477                         t->std = V4L2_STD_PAL_BG;
478                         break;
479                 case 'i':
480                 case 'I':
481                         dprintk(PREFIX "insmod fixup: PAL => PAL-I\n");
482                         t->std = V4L2_STD_PAL_I;
483                         break;
484                 case 'd':
485                 case 'D':
486                 case 'k':
487                 case 'K':
488                         dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n");
489                         t->std = V4L2_STD_PAL_DK;
490                         break;
491                 }
492         }
493         if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
494                 switch (secam[0]) {
495                 case 'd':
496                 case 'D':
497                 case 'k':
498                 case 'K':
499                         dprintk(PREFIX "insmod fixup: SECAM => SECAM-DK\n");
500                         t->std = V4L2_STD_SECAM_DK;
501                         break;
502                 case 'l':
503                 case 'L':
504                         dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n");
505                         t->std = V4L2_STD_SECAM_L;
506                         break;
507                 }
508         }
509         return 0;
510 }
511
512 static int tda9887_status(struct tda9887 *t)
513 {
514         unsigned char buf[1];
515         int rc;
516
517         memset(buf,0,sizeof(buf));
518         if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
519                 printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc);
520         dump_read_message(buf);
521         return 0;
522 }
523
524 static int tda9887_configure(struct tda9887 *t)
525 {
526         unsigned char buf[4];
527         int rc;
528
529         memset(buf,0,sizeof(buf));
530         tda9887_set_tvnorm(t,buf);
531         if (UNSET != t->pinnacle_id) {
532                 tda9887_set_pinnacle(t,buf);
533         }
534         tda9887_set_config(t,buf);
535         tda9887_set_insmod(t,buf);
536
537         dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n",
538                 buf[1],buf[2],buf[3]);
539         if (debug > 1)
540                 dump_write_message(buf);
541
542         if (4 != (rc = i2c_master_send(&t->client,buf,4)))
543                 printk(PREFIX "i2c i/o error: rc == %d (should be 4)\n",rc);
544
545         if (debug > 2) {
546                 set_current_state(TASK_INTERRUPTIBLE);
547                 schedule_timeout(HZ);
548                 tda9887_status(t);
549         }
550         return 0;
551 }
552
553 /* ---------------------------------------------------------------------- */
554
555 static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
556 {
557         struct tda9887 *t;
558
559         client_template.adapter = adap;
560         client_template.addr    = addr;
561
562         printk(PREFIX "chip found @ 0x%x\n", addr<<1);
563
564         if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
565                 return -ENOMEM;
566         memset(t,0,sizeof(*t));
567         t->client      = client_template;
568         t->std         = 0;;
569         t->pinnacle_id = UNSET;
570         i2c_set_clientdata(&t->client, t);
571         i2c_attach_client(&t->client);
572         
573         return 0;
574 }
575
576 static int tda9887_probe(struct i2c_adapter *adap)
577 {
578 #ifdef I2C_CLASS_TV_ANALOG
579         if (adap->class & I2C_CLASS_TV_ANALOG)
580                 return i2c_probe(adap, &addr_data, tda9887_attach);
581 #else
582         switch (adap->id) {
583         case I2C_ALGO_BIT | I2C_HW_B_BT848:
584         case I2C_ALGO_BIT | I2C_HW_B_RIVA:
585         case I2C_ALGO_SAA7134:
586                 return i2c_probe(adap, &addr_data, tda9887_attach);
587                 break;
588         }
589 #endif
590         return 0;
591 }
592
593 static int tda9887_detach(struct i2c_client *client)
594 {
595         struct tda9887 *t = i2c_get_clientdata(client);
596
597         i2c_detach_client(client);
598         kfree(t);
599         return 0;
600 }
601
602 #define SWITCH_V4L2     if (!t->using_v4l2 && debug) \
603                           printk(PREFIX "switching to v4l2\n"); \
604                           t->using_v4l2 = 1;
605 #define CHECK_V4L2      if (t->using_v4l2) { if (debug) \
606                           printk(PREFIX "ignore v4l1 call\n"); \
607                           return 0; }
608
609 static int
610 tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
611 {
612         struct tda9887 *t = i2c_get_clientdata(client);
613
614         switch (cmd) {
615
616         /* --- configuration --- */
617         case AUDC_SET_RADIO:
618                 t->radio = 1;
619                 tda9887_configure(t);
620                 break;
621                 
622         case AUDC_CONFIG_PINNACLE:
623         {
624                 int *i = arg;
625
626                 t->pinnacle_id = *i;
627                 tda9887_configure(t);
628                 break;
629         }
630         case TDA9887_SET_CONFIG:
631         {
632                 int *i = arg;
633
634                 t->config = *i;
635                 tda9887_configure(t);
636                 break;
637         }
638         /* --- v4l ioctls --- */
639         /* take care: bttv does userspace copying, we'll get a
640            kernel pointer here... */
641         case VIDIOCSCHAN:
642         {
643                 static const v4l2_std_id map[] = {
644                         [ VIDEO_MODE_PAL   ] = V4L2_STD_PAL,
645                         [ VIDEO_MODE_NTSC  ] = V4L2_STD_NTSC_M,
646                         [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
647                         [ 4 /* bttv */     ] = V4L2_STD_PAL_M,
648                         [ 5 /* bttv */     ] = V4L2_STD_PAL_N,
649                         [ 6 /* bttv */     ] = V4L2_STD_NTSC_M_JP,
650                 };
651                 struct video_channel *vc = arg;
652
653                 CHECK_V4L2;
654                 t->radio = 0;
655                 if (vc->norm < ARRAY_SIZE(map))
656                         t->std = map[vc->norm];
657                 tda9887_fixup_std(t);
658                 tda9887_configure(t);
659                 break;
660         }
661         case VIDIOC_S_STD:
662         {
663                 v4l2_std_id *id = arg;
664
665                 SWITCH_V4L2;
666                 t->radio = 0;
667                 t->std   = *id;
668                 tda9887_fixup_std(t);
669                 tda9887_configure(t);
670                 break;
671         }
672         case VIDIOC_S_FREQUENCY:
673         {
674                 struct v4l2_frequency *f = arg;
675
676                 SWITCH_V4L2;
677                 if (V4L2_TUNER_ANALOG_TV == f->type) {
678                         if (t->radio == 0)
679                                 return 0;
680                         t->radio = 0;
681                 }
682                 if (V4L2_TUNER_RADIO == f->type) {
683                         if (t->radio == 1)
684                                 return 0;
685                         t->radio = 1;
686                 }
687                 tda9887_configure(t);
688                 break;
689         }
690         case VIDIOC_G_TUNER:
691         {
692                 static int AFC_BITS_2_kHz[] = {
693                         -12500,  -37500,  -62500,  -97500,
694                         -112500, -137500, -162500, -187500,
695                         187500,  162500,  137500,  112500,
696                         97500 ,  62500,   37500 ,  12500
697                 };
698                 struct v4l2_tuner* tuner = arg;
699
700                 if (t->radio) {
701                         __u8 reg = 0;
702                         tuner->afc=0;
703                         if (1 == i2c_master_recv(&t->client,&reg,1))
704                                 tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
705                 }
706                 break;
707         }
708         default:
709                 /* nothing */
710                 break;
711         }
712         return 0;
713 }
714
715 /* ----------------------------------------------------------------------- */
716
717 static struct i2c_driver driver = {
718         .owner          = THIS_MODULE,
719         .name           = "i2c tda9887 driver",
720         .id             = -1, /* FIXME */
721         .flags          = I2C_DF_NOTIFY,
722         .attach_adapter = tda9887_probe,
723         .detach_client  = tda9887_detach,
724         .command        = tda9887_command,
725 };
726 static struct i2c_client client_template =
727 {
728         I2C_DEVNAME("tda9887"),
729         .flags     = I2C_CLIENT_ALLOW_USE,
730         .driver    = &driver,
731 };
732
733 static int __init tda9887_init_module(void)
734 {
735         return i2c_add_driver(&driver);
736 }
737
738 static void __exit tda9887_cleanup_module(void)
739 {
740         i2c_del_driver(&driver);
741 }
742
743 module_init(tda9887_init_module);
744 module_exit(tda9887_cleanup_module);
745
746 /*
747  * Overrides for Emacs so that we follow Linus's tabbing style.
748  * ---------------------------------------------------------------------------
749  * Local variables:
750  * c-basic-offset: 8
751  * End:
752  */