]> Pileus Git - ~andy/linux/blob - drivers/media/video/tda9887.c
V4L/DVB (6783): tuner: combine set_tv_freq and set_radio_freq into a single set_param...
[~andy/linux] / 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/init.h>
6 #include <linux/errno.h>
7 #include <linux/slab.h>
8 #include <linux/delay.h>
9 #include <linux/videodev.h>
10 #include <media/v4l2-common.h>
11 #include <media/tuner.h>
12 #include "tda9887.h"
13
14
15 /* Chips:
16    TDA9885 (PAL, NTSC)
17    TDA9886 (PAL, SECAM, NTSC)
18    TDA9887 (PAL, SECAM, NTSC, FM Radio)
19
20    Used as part of several tuners
21 */
22
23 static int tda9887_debug;
24 module_param_named(debug, tda9887_debug, int, 0644);
25
26 #define tda9887_info(fmt, arg...) do {\
27         printk(KERN_INFO "%s %d-%04x: " fmt, priv->t->i2c->name, \
28                         i2c_adapter_id(priv->t->i2c->adapter), \
29                         priv->t->i2c->addr, ##arg); } while (0)
30 #define tda9887_dbg(fmt, arg...) do {\
31         if (tda9887_debug) \
32                 printk(KERN_INFO "%s %d-%04x: " fmt, priv->t->i2c->name, \
33                         i2c_adapter_id(priv->t->i2c->adapter), \
34                         priv->t->i2c->addr, ##arg); } while (0)
35
36 struct tda9887_priv {
37         struct tuner_i2c_props i2c_props;
38
39         unsigned char      data[4];
40
41         struct tuner *t;
42 };
43
44 /* ---------------------------------------------------------------------- */
45
46 #define UNSET       (-1U)
47
48 struct tvnorm {
49         v4l2_std_id       std;
50         char              *name;
51         unsigned char     b;
52         unsigned char     c;
53         unsigned char     e;
54 };
55
56 /* ---------------------------------------------------------------------- */
57
58 //
59 // TDA defines
60 //
61
62 //// first reg (b)
63 #define cVideoTrapBypassOFF     0x00    // bit b0
64 #define cVideoTrapBypassON      0x01    // bit b0
65
66 #define cAutoMuteFmInactive     0x00    // bit b1
67 #define cAutoMuteFmActive       0x02    // bit b1
68
69 #define cIntercarrier           0x00    // bit b2
70 #define cQSS                    0x04    // bit b2
71
72 #define cPositiveAmTV           0x00    // bit b3:4
73 #define cFmRadio                0x08    // bit b3:4
74 #define cNegativeFmTV           0x10    // bit b3:4
75
76
77 #define cForcedMuteAudioON      0x20    // bit b5
78 #define cForcedMuteAudioOFF     0x00    // bit b5
79
80 #define cOutputPort1Active      0x00    // bit b6
81 #define cOutputPort1Inactive    0x40    // bit b6
82
83 #define cOutputPort2Active      0x00    // bit b7
84 #define cOutputPort2Inactive    0x80    // bit b7
85
86
87 //// second reg (c)
88 #define cDeemphasisOFF          0x00    // bit c5
89 #define cDeemphasisON           0x20    // bit c5
90
91 #define cDeemphasis75           0x00    // bit c6
92 #define cDeemphasis50           0x40    // bit c6
93
94 #define cAudioGain0             0x00    // bit c7
95 #define cAudioGain6             0x80    // bit c7
96
97 #define cTopMask                0x1f    // bit c0:4
98 #define cTopDefault             0x10    // bit c0:4
99
100 //// third reg (e)
101 #define cAudioIF_4_5             0x00    // bit e0:1
102 #define cAudioIF_5_5             0x01    // bit e0:1
103 #define cAudioIF_6_0             0x02    // bit e0:1
104 #define cAudioIF_6_5             0x03    // bit e0:1
105
106
107 #define cVideoIFMask            0x1c    // bit e2:4
108 /* Video IF selection in TV Mode (bit B3=0) */
109 #define cVideoIF_58_75           0x00    // bit e2:4
110 #define cVideoIF_45_75           0x04    // bit e2:4
111 #define cVideoIF_38_90           0x08    // bit e2:4
112 #define cVideoIF_38_00           0x0C    // bit e2:4
113 #define cVideoIF_33_90           0x10    // bit e2:4
114 #define cVideoIF_33_40           0x14    // bit e2:4
115 #define cRadioIF_45_75           0x18    // bit e2:4
116 #define cRadioIF_38_90           0x1C    // bit e2:4
117
118 /* IF1 selection in Radio Mode (bit B3=1) */
119 #define cRadioIF_33_30          0x00    // bit e2,4 (also 0x10,0x14)
120 #define cRadioIF_41_30          0x04    // bit e2,4
121
122 /* Output of AFC pin in radio mode when bit E7=1 */
123 #define cRadioAGC_SIF           0x00    // bit e3
124 #define cRadioAGC_FM            0x08    // bit e3
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 | V4L2_STD_PAL_H | V4L2_STD_PAL_N,
140                 .name  = "PAL-BGHN",
141                 .b     = ( cNegativeFmTV  |
142                            cQSS           ),
143                 .c     = ( cDeemphasisON  |
144                            cDeemphasis50  |
145                            cTopDefault),
146                 .e     = ( cGating_36     |
147                            cAudioIF_5_5   |
148                            cVideoIF_38_90 ),
149         },{
150                 .std   = V4L2_STD_PAL_I,
151                 .name  = "PAL-I",
152                 .b     = ( cNegativeFmTV  |
153                            cQSS           ),
154                 .c     = ( cDeemphasisON  |
155                            cDeemphasis50  |
156                            cTopDefault),
157                 .e     = ( cGating_36     |
158                            cAudioIF_6_0   |
159                            cVideoIF_38_90 ),
160         },{
161                 .std   = V4L2_STD_PAL_DK,
162                 .name  = "PAL-DK",
163                 .b     = ( cNegativeFmTV  |
164                            cQSS           ),
165                 .c     = ( cDeemphasisON  |
166                            cDeemphasis50  |
167                            cTopDefault),
168                 .e     = ( cGating_36     |
169                            cAudioIF_6_5   |
170                            cVideoIF_38_90 ),
171         },{
172                 .std   = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,
173                 .name  = "PAL-M/Nc",
174                 .b     = ( cNegativeFmTV  |
175                            cQSS           ),
176                 .c     = ( cDeemphasisON  |
177                            cDeemphasis75  |
178                            cTopDefault),
179                 .e     = ( cGating_36     |
180                            cAudioIF_4_5   |
181                            cVideoIF_45_75 ),
182         },{
183                 .std   = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
184                 .name  = "SECAM-BGH",
185                 .b     = ( cPositiveAmTV  |
186                            cQSS           ),
187                 .c     = ( cTopDefault),
188                 .e     = ( cGating_36     |
189                            cAudioIF_5_5   |
190                            cVideoIF_38_90 ),
191         },{
192                 .std   = V4L2_STD_SECAM_L,
193                 .name  = "SECAM-L",
194                 .b     = ( cPositiveAmTV  |
195                            cQSS           ),
196                 .c     = ( cTopDefault),
197                 .e     = ( cGating_36     |
198                            cAudioIF_6_5   |
199                            cVideoIF_38_90 ),
200         },{
201                 .std   = V4L2_STD_SECAM_LC,
202                 .name  = "SECAM-L'",
203                 .b     = ( cOutputPort2Inactive |
204                            cPositiveAmTV  |
205                            cQSS           ),
206                 .c     = ( cTopDefault),
207                 .e     = ( cGating_36     |
208                            cAudioIF_6_5   |
209                            cVideoIF_33_90 ),
210         },{
211                 .std   = V4L2_STD_SECAM_DK,
212                 .name  = "SECAM-DK",
213                 .b     = ( cNegativeFmTV  |
214                            cQSS           ),
215                 .c     = ( cDeemphasisON  |
216                            cDeemphasis50  |
217                            cTopDefault),
218                 .e     = ( cGating_36     |
219                            cAudioIF_6_5   |
220                            cVideoIF_38_90 ),
221         },{
222                 .std   = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
223                 .name  = "NTSC-M",
224                 .b     = ( cNegativeFmTV  |
225                            cQSS           ),
226                 .c     = ( cDeemphasisON  |
227                            cDeemphasis75  |
228                            cTopDefault),
229                 .e     = ( cGating_36     |
230                            cAudioIF_4_5   |
231                            cVideoIF_45_75 ),
232         },{
233                 .std   = V4L2_STD_NTSC_M_JP,
234                 .name  = "NTSC-M-JP",
235                 .b     = ( cNegativeFmTV  |
236                            cQSS           ),
237                 .c     = ( cDeemphasisON  |
238                            cDeemphasis50  |
239                            cTopDefault),
240                 .e     = ( cGating_36     |
241                            cAudioIF_4_5   |
242                            cVideoIF_58_75 ),
243         }
244 };
245
246 static struct tvnorm radio_stereo = {
247         .name = "Radio Stereo",
248         .b    = ( cFmRadio       |
249                   cQSS           ),
250         .c    = ( cDeemphasisOFF |
251                   cAudioGain6    |
252                   cTopDefault),
253         .e    = ( cTunerGainLow  |
254                   cAudioIF_5_5   |
255                   cRadioIF_38_90 ),
256 };
257
258 static struct tvnorm radio_mono = {
259         .name = "Radio Mono",
260         .b    = ( cFmRadio       |
261                   cQSS           ),
262         .c    = ( cDeemphasisON  |
263                   cDeemphasis75  |
264                   cTopDefault),
265         .e    = ( cTunerGainLow  |
266                   cAudioIF_5_5   |
267                   cRadioIF_38_90 ),
268 };
269
270 /* ---------------------------------------------------------------------- */
271
272 static void dump_read_message(struct dvb_frontend *fe, unsigned char *buf)
273 {
274         struct tda9887_priv *priv = fe->analog_demod_priv;
275
276         static char *afc[16] = {
277                 "- 12.5 kHz",
278                 "- 37.5 kHz",
279                 "- 62.5 kHz",
280                 "- 87.5 kHz",
281                 "-112.5 kHz",
282                 "-137.5 kHz",
283                 "-162.5 kHz",
284                 "-187.5 kHz [min]",
285                 "+187.5 kHz [max]",
286                 "+162.5 kHz",
287                 "+137.5 kHz",
288                 "+112.5 kHz",
289                 "+ 87.5 kHz",
290                 "+ 62.5 kHz",
291                 "+ 37.5 kHz",
292                 "+ 12.5 kHz",
293         };
294         tda9887_info("read: 0x%2x\n", buf[0]);
295         tda9887_info("  after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
296         tda9887_info("  afc            : %s\n", afc[(buf[0] >> 1) & 0x0f]);
297         tda9887_info("  fmif level     : %s\n", (buf[0] & 0x20) ? "high" : "low");
298         tda9887_info("  afc window     : %s\n", (buf[0] & 0x40) ? "in" : "out");
299         tda9887_info("  vfi level      : %s\n", (buf[0] & 0x80) ? "high" : "low");
300 }
301
302 static void dump_write_message(struct dvb_frontend *fe, unsigned char *buf)
303 {
304         struct tda9887_priv *priv = fe->analog_demod_priv;
305
306         static char *sound[4] = {
307                 "AM/TV",
308                 "FM/radio",
309                 "FM/TV",
310                 "FM/radio"
311         };
312         static char *adjust[32] = {
313                 "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
314                 "-8",  "-7",  "-6",  "-5",  "-4",  "-3",  "-2",  "-1",
315                 "0",   "+1",  "+2",  "+3",  "+4",  "+5",  "+6",  "+7",
316                 "+8",  "+9",  "+10", "+11", "+12", "+13", "+14", "+15"
317         };
318         static char *deemph[4] = {
319                 "no", "no", "75", "50"
320         };
321         static char *carrier[4] = {
322                 "4.5 MHz",
323                 "5.5 MHz",
324                 "6.0 MHz",
325                 "6.5 MHz / AM"
326         };
327         static char *vif[8] = {
328                 "58.75 MHz",
329                 "45.75 MHz",
330                 "38.9 MHz",
331                 "38.0 MHz",
332                 "33.9 MHz",
333                 "33.4 MHz",
334                 "45.75 MHz + pin13",
335                 "38.9 MHz + pin13",
336         };
337         static char *rif[4] = {
338                 "44 MHz",
339                 "52 MHz",
340                 "52 MHz",
341                 "44 MHz",
342         };
343
344         tda9887_info("write: byte B 0x%02x\n",buf[1]);
345         tda9887_info("  B0   video mode      : %s\n",
346                (buf[1] & 0x01) ? "video trap" : "sound trap");
347         tda9887_info("  B1   auto mute fm    : %s\n",
348                (buf[1] & 0x02) ? "yes" : "no");
349         tda9887_info("  B2   carrier mode    : %s\n",
350                (buf[1] & 0x04) ? "QSS" : "Intercarrier");
351         tda9887_info("  B3-4 tv sound/radio  : %s\n",
352                sound[(buf[1] & 0x18) >> 3]);
353         tda9887_info("  B5   force mute audio: %s\n",
354                (buf[1] & 0x20) ? "yes" : "no");
355         tda9887_info("  B6   output port 1   : %s\n",
356                (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
357         tda9887_info("  B7   output port 2   : %s\n",
358                (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
359
360         tda9887_info("write: byte C 0x%02x\n",buf[2]);
361         tda9887_info("  C0-4 top adjustment  : %s dB\n", adjust[buf[2] & 0x1f]);
362         tda9887_info("  C5-6 de-emphasis     : %s\n", deemph[(buf[2] & 0x60) >> 5]);
363         tda9887_info("  C7   audio gain      : %s\n",
364                (buf[2] & 0x80) ? "-6" : "0");
365
366         tda9887_info("write: byte E 0x%02x\n",buf[3]);
367         tda9887_info("  E0-1 sound carrier   : %s\n",
368                carrier[(buf[3] & 0x03)]);
369         tda9887_info("  E6   l pll gating   : %s\n",
370                (buf[3] & 0x40) ? "36" : "13");
371
372         if (buf[1] & 0x08) {
373                 /* radio */
374                 tda9887_info("  E2-4 video if        : %s\n",
375                        rif[(buf[3] & 0x0c) >> 2]);
376                 tda9887_info("  E7   vif agc output  : %s\n",
377                        (buf[3] & 0x80)
378                        ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
379                        : "fm radio carrier afc");
380         } else {
381                 /* video */
382                 tda9887_info("  E2-4 video if        : %s\n",
383                        vif[(buf[3] & 0x1c) >> 2]);
384                 tda9887_info("  E5   tuner gain      : %s\n",
385                        (buf[3] & 0x80)
386                        ? ((buf[3] & 0x20) ? "external" : "normal")
387                        : ((buf[3] & 0x20) ? "minimum"  : "normal"));
388                 tda9887_info("  E7   vif agc output  : %s\n",
389                        (buf[3] & 0x80)
390                        ? ((buf[3] & 0x20)
391                           ? "pin3 port, pin22 vif agc out"
392                           : "pin22 port, pin3 vif acg ext in")
393                        : "pin3+pin22 port");
394         }
395         tda9887_info("--\n");
396 }
397
398 /* ---------------------------------------------------------------------- */
399
400 static int tda9887_set_tvnorm(struct dvb_frontend *fe)
401 {
402         struct tda9887_priv *priv = fe->analog_demod_priv;
403         struct tuner *t = priv->t;
404         struct tvnorm *norm = NULL;
405         char *buf = priv->data;
406         int i;
407
408         if (t->mode == V4L2_TUNER_RADIO) {
409                 if (t->audmode == V4L2_TUNER_MODE_MONO)
410                         norm = &radio_mono;
411                 else
412                         norm = &radio_stereo;
413         } else {
414                 for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
415                         if (tvnorms[i].std & t->std) {
416                                 norm = tvnorms+i;
417                                 break;
418                         }
419                 }
420         }
421         if (NULL == norm) {
422                 tda9887_dbg("Unsupported tvnorm entry - audio muted\n");
423                 return -1;
424         }
425
426         tda9887_dbg("configure for: %s\n",norm->name);
427         buf[1] = norm->b;
428         buf[2] = norm->c;
429         buf[3] = norm->e;
430         return 0;
431 }
432
433 static unsigned int port1  = UNSET;
434 static unsigned int port2  = UNSET;
435 static unsigned int qss    = UNSET;
436 static unsigned int adjust = UNSET;
437
438 module_param(port1, int, 0644);
439 module_param(port2, int, 0644);
440 module_param(qss, int, 0644);
441 module_param(adjust, int, 0644);
442
443 static int tda9887_set_insmod(struct dvb_frontend *fe)
444 {
445         struct tda9887_priv *priv = fe->analog_demod_priv;
446         char *buf = priv->data;
447
448         if (UNSET != port1) {
449                 if (port1)
450                         buf[1] |= cOutputPort1Inactive;
451                 else
452                         buf[1] &= ~cOutputPort1Inactive;
453         }
454         if (UNSET != port2) {
455                 if (port2)
456                         buf[1] |= cOutputPort2Inactive;
457                 else
458                         buf[1] &= ~cOutputPort2Inactive;
459         }
460
461         if (UNSET != qss) {
462                 if (qss)
463                         buf[1] |= cQSS;
464                 else
465                         buf[1] &= ~cQSS;
466         }
467
468         if (adjust >= 0x00 && adjust < 0x20) {
469                 buf[2] &= ~cTopMask;
470                 buf[2] |= adjust;
471         }
472         return 0;
473 }
474
475 static int tda9887_set_config(struct dvb_frontend *fe)
476 {
477         struct tda9887_priv *priv = fe->analog_demod_priv;
478         struct tuner *t = priv->t;
479         char *buf = priv->data;
480
481         if (t->tda9887_config & TDA9887_PORT1_ACTIVE)
482                 buf[1] &= ~cOutputPort1Inactive;
483         if (t->tda9887_config & TDA9887_PORT1_INACTIVE)
484                 buf[1] |= cOutputPort1Inactive;
485         if (t->tda9887_config & TDA9887_PORT2_ACTIVE)
486                 buf[1] &= ~cOutputPort2Inactive;
487         if (t->tda9887_config & TDA9887_PORT2_INACTIVE)
488                 buf[1] |= cOutputPort2Inactive;
489
490         if (t->tda9887_config & TDA9887_QSS)
491                 buf[1] |= cQSS;
492         if (t->tda9887_config & TDA9887_INTERCARRIER)
493                 buf[1] &= ~cQSS;
494
495         if (t->tda9887_config & TDA9887_AUTOMUTE)
496                 buf[1] |= cAutoMuteFmActive;
497         if (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) {
498                 buf[2] &= ~0x60;
499                 switch (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) {
500                 case TDA9887_DEEMPHASIS_NONE:
501                         buf[2] |= cDeemphasisOFF;
502                         break;
503                 case TDA9887_DEEMPHASIS_50:
504                         buf[2] |= cDeemphasisON | cDeemphasis50;
505                         break;
506                 case TDA9887_DEEMPHASIS_75:
507                         buf[2] |= cDeemphasisON | cDeemphasis75;
508                         break;
509                 }
510         }
511         if (t->tda9887_config & TDA9887_TOP_SET) {
512                 buf[2] &= ~cTopMask;
513                 buf[2] |= (t->tda9887_config >> 8) & cTopMask;
514         }
515         if ((t->tda9887_config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
516                 buf[1] &= ~cQSS;
517         if (t->tda9887_config & TDA9887_GATING_18)
518                 buf[3] &= ~cGating_36;
519
520         if (t->mode == V4L2_TUNER_RADIO) {
521                 if (t->tda9887_config & TDA9887_RIF_41_3) {
522                         buf[3] &= ~cVideoIFMask;
523                         buf[3] |= cRadioIF_41_30;
524                 }
525                 if (t->tda9887_config & TDA9887_GAIN_NORMAL)
526                         buf[3] &= ~cTunerGainLow;
527         }
528
529         return 0;
530 }
531
532 /* ---------------------------------------------------------------------- */
533
534 static int tda9887_status(struct dvb_frontend *fe)
535 {
536         struct tda9887_priv *priv = fe->analog_demod_priv;
537         unsigned char buf[1];
538         int rc;
539
540         memset(buf,0,sizeof(buf));
541         if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,buf,1)))
542                 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
543         dump_read_message(fe, buf);
544         return 0;
545 }
546
547 static void tda9887_configure(struct dvb_frontend *fe)
548 {
549         struct tda9887_priv *priv = fe->analog_demod_priv;
550         struct tuner *t = priv->t;
551         int rc;
552
553         memset(priv->data,0,sizeof(priv->data));
554         tda9887_set_tvnorm(fe);
555
556         /* A note on the port settings:
557            These settings tend to depend on the specifics of the board.
558            By default they are set to inactive (bit value 1) by this driver,
559            overwriting any changes made by the tvnorm. This means that it
560            is the responsibility of the module using the tda9887 to set
561            these values in case of changes in the tvnorm.
562            In many cases port 2 should be made active (0) when selecting
563            SECAM-L, and port 2 should remain inactive (1) for SECAM-L'.
564
565            For the other standards the tda9887 application note says that
566            the ports should be set to active (0), but, again, that may
567            differ depending on the precise hardware configuration.
568          */
569         priv->data[1] |= cOutputPort1Inactive;
570         priv->data[1] |= cOutputPort2Inactive;
571
572         tda9887_set_config(fe);
573         tda9887_set_insmod(fe);
574
575         if (t->mode == T_STANDBY) {
576                 priv->data[1] |= cForcedMuteAudioON;
577         }
578
579         tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
580                 priv->data[1],priv->data[2],priv->data[3]);
581         if (tda9887_debug > 1)
582                 dump_write_message(fe, priv->data);
583
584         if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,priv->data,4)))
585                 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
586
587         if (tda9887_debug > 2) {
588                 msleep_interruptible(1000);
589                 tda9887_status(fe);
590         }
591 }
592
593 /* ---------------------------------------------------------------------- */
594
595 static void tda9887_tuner_status(struct dvb_frontend *fe)
596 {
597         struct tda9887_priv *priv = fe->analog_demod_priv;
598         tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n",
599                      priv->data[1], priv->data[2], priv->data[3]);
600 }
601
602 static int tda9887_get_afc(struct dvb_frontend *fe)
603 {
604         struct tda9887_priv *priv = fe->analog_demod_priv;
605         static int AFC_BITS_2_kHz[] = {
606                 -12500,  -37500,  -62500,  -97500,
607                 -112500, -137500, -162500, -187500,
608                 187500,  162500,  137500,  112500,
609                 97500 ,  62500,   37500 ,  12500
610         };
611         int afc=0;
612         __u8 reg = 0;
613
614         if (1 == tuner_i2c_xfer_recv(&priv->i2c_props,&reg,1))
615                 afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
616
617         return afc;
618 }
619
620 static void tda9887_standby(struct dvb_frontend *fe)
621 {
622         tda9887_configure(fe);
623 }
624
625 static void tda9887_set_params(struct dvb_frontend *fe,
626                                struct analog_parameters *params)
627 {
628         tda9887_configure(fe);
629 }
630
631 static void tda9887_release(struct dvb_frontend *fe)
632 {
633         kfree(fe->analog_demod_priv);
634         fe->analog_demod_priv = NULL;
635 }
636
637 static struct analog_tuner_ops tda9887_tuner_ops = {
638         .set_params     = tda9887_set_params,
639         .standby        = tda9887_standby,
640         .tuner_status   = tda9887_tuner_status,
641         .get_afc        = tda9887_get_afc,
642         .release        = tda9887_release,
643 };
644
645 int tda9887_attach(struct tuner *t)
646 {
647         struct tda9887_priv *priv = NULL;
648
649         priv = kzalloc(sizeof(struct tda9887_priv), GFP_KERNEL);
650         if (priv == NULL)
651                 return -ENOMEM;
652         t->fe.analog_demod_priv = priv;
653
654         priv->i2c_props.addr = t->i2c->addr;
655         priv->i2c_props.adap = t->i2c->adapter;
656         priv->t = t;
657
658         strlcpy(t->i2c->name, "tda9887", sizeof(t->i2c->name));
659
660         tda9887_info("tda988[5/6/7] found @ 0x%x (%s)\n", t->i2c->addr,
661                      t->i2c->driver->driver.name);
662
663         t->fe.ops.analog_demod_ops = &tda9887_tuner_ops;
664
665         return 0;
666 }
667 EXPORT_SYMBOL_GPL(tda9887_attach);
668
669 MODULE_LICENSE("GPL");
670
671 /*
672  * Overrides for Emacs so that we follow Linus's tabbing style.
673  * ---------------------------------------------------------------------------
674  * Local variables:
675  * c-basic-offset: 8
676  * End:
677  */