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