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