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