]> err.no Git - linux-2.6/blob - drivers/media/dvb/frontends/tda18271-fe.c
V4L/DVB (6727): tda18271: convert table lookup loops to functions
[linux-2.6] / drivers / media / dvb / frontends / tda18271-fe.c
1 /*
2     tda18271-fe.c - driver for the Philips / NXP TDA18271 silicon tuner
3
4     Copyright (C) 2007 Michael Krufky (mkrufky@linuxtv.org)
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <linux/delay.h>
22 #include <linux/videodev2.h>
23 #include "tuner-driver.h"
24
25 #include "tda18271.h"
26 #include "tda18271-priv.h"
27
28 int tda18271_debug;
29 module_param_named(debug, tda18271_debug, int, 0644);
30 MODULE_PARM_DESC(debug, "set debug level (info=1, map=2, reg=4 (or-able))");
31
32 /*---------------------------------------------------------------------*/
33
34 #define TDA18271_ANALOG  0
35 #define TDA18271_DIGITAL 1
36
37 struct tda18271_priv {
38         u8 i2c_addr;
39         struct i2c_adapter *i2c_adap;
40         unsigned char tda18271_regs[TDA18271_NUM_REGS];
41         int mode;
42
43         u32 frequency;
44         u32 bandwidth;
45 };
46
47 static int tda18271_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
48 {
49         struct tda18271_priv *priv = fe->tuner_priv;
50         struct analog_tuner_ops *ops = fe->ops.analog_demod_ops;
51         int ret = 0;
52
53         switch (priv->mode) {
54         case TDA18271_ANALOG:
55                 if (ops && ops->i2c_gate_ctrl)
56                         ret = ops->i2c_gate_ctrl(fe, enable);
57                 break;
58         case TDA18271_DIGITAL:
59                 if (fe->ops.i2c_gate_ctrl)
60                         ret = fe->ops.i2c_gate_ctrl(fe, enable);
61                 break;
62         }
63
64         return ret;
65 };
66
67 /*---------------------------------------------------------------------*/
68
69 static void tda18271_dump_regs(struct dvb_frontend *fe)
70 {
71         struct tda18271_priv *priv = fe->tuner_priv;
72         unsigned char *regs = priv->tda18271_regs;
73
74         dbg_reg("=== TDA18271 REG DUMP ===\n");
75         dbg_reg("ID_BYTE            = 0x%x\n", 0xff & regs[R_ID]);
76         dbg_reg("THERMO_BYTE        = 0x%x\n", 0xff & regs[R_TM]);
77         dbg_reg("POWER_LEVEL_BYTE   = 0x%x\n", 0xff & regs[R_PL]);
78         dbg_reg("EASY_PROG_BYTE_1   = 0x%x\n", 0xff & regs[R_EP1]);
79         dbg_reg("EASY_PROG_BYTE_2   = 0x%x\n", 0xff & regs[R_EP2]);
80         dbg_reg("EASY_PROG_BYTE_3   = 0x%x\n", 0xff & regs[R_EP3]);
81         dbg_reg("EASY_PROG_BYTE_4   = 0x%x\n", 0xff & regs[R_EP4]);
82         dbg_reg("EASY_PROG_BYTE_5   = 0x%x\n", 0xff & regs[R_EP5]);
83         dbg_reg("CAL_POST_DIV_BYTE  = 0x%x\n", 0xff & regs[R_CPD]);
84         dbg_reg("CAL_DIV_BYTE_1     = 0x%x\n", 0xff & regs[R_CD1]);
85         dbg_reg("CAL_DIV_BYTE_2     = 0x%x\n", 0xff & regs[R_CD2]);
86         dbg_reg("CAL_DIV_BYTE_3     = 0x%x\n", 0xff & regs[R_CD3]);
87         dbg_reg("MAIN_POST_DIV_BYTE = 0x%x\n", 0xff & regs[R_MPD]);
88         dbg_reg("MAIN_DIV_BYTE_1    = 0x%x\n", 0xff & regs[R_MD1]);
89         dbg_reg("MAIN_DIV_BYTE_2    = 0x%x\n", 0xff & regs[R_MD2]);
90         dbg_reg("MAIN_DIV_BYTE_3    = 0x%x\n", 0xff & regs[R_MD3]);
91 }
92
93 static void tda18271_read_regs(struct dvb_frontend *fe)
94 {
95         struct tda18271_priv *priv = fe->tuner_priv;
96         unsigned char *regs = priv->tda18271_regs;
97         unsigned char buf = 0x00;
98         int ret;
99         struct i2c_msg msg[] = {
100                 { .addr = priv->i2c_addr, .flags = 0,
101                   .buf = &buf, .len = 1 },
102                 { .addr = priv->i2c_addr, .flags = I2C_M_RD,
103                   .buf = regs, .len = 16 }
104         };
105
106         tda18271_i2c_gate_ctrl(fe, 1);
107
108         /* read all registers */
109         ret = i2c_transfer(priv->i2c_adap, msg, 2);
110
111         tda18271_i2c_gate_ctrl(fe, 0);
112
113         if (ret != 2)
114                 printk("ERROR: %s: i2c_transfer returned: %d\n",
115                        __FUNCTION__, ret);
116
117         if (tda18271_debug & DBG_REG)
118                 tda18271_dump_regs(fe);
119 }
120
121 static void tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
122 {
123         struct tda18271_priv *priv = fe->tuner_priv;
124         unsigned char *regs = priv->tda18271_regs;
125         unsigned char buf[TDA18271_NUM_REGS+1];
126         struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
127                                .buf = buf, .len = len+1 };
128         int i, ret;
129
130         BUG_ON((len == 0) || (idx+len > sizeof(buf)));
131
132         buf[0] = idx;
133         for (i = 1; i <= len; i++) {
134                 buf[i] = regs[idx-1+i];
135         }
136
137         tda18271_i2c_gate_ctrl(fe, 1);
138
139         /* write registers */
140         ret = i2c_transfer(priv->i2c_adap, &msg, 1);
141
142         tda18271_i2c_gate_ctrl(fe, 0);
143
144         if (ret != 1)
145                 printk(KERN_WARNING "ERROR: %s: i2c_transfer returned: %d\n",
146                        __FUNCTION__, ret);
147 }
148
149 /*---------------------------------------------------------------------*/
150
151 static int tda18271_init_regs(struct dvb_frontend *fe)
152 {
153         struct tda18271_priv *priv = fe->tuner_priv;
154         unsigned char *regs = priv->tda18271_regs;
155
156         printk(KERN_INFO "tda18271: initializing registers\n");
157
158         /* initialize registers */
159         regs[R_ID]   = 0x83;
160         regs[R_TM]   = 0x08;
161         regs[R_PL]   = 0x80;
162         regs[R_EP1]  = 0xc6;
163         regs[R_EP2]  = 0xdf;
164         regs[R_EP3]  = 0x16;
165         regs[R_EP4]  = 0x60;
166         regs[R_EP5]  = 0x80;
167         regs[R_CPD]  = 0x80;
168         regs[R_CD1]  = 0x00;
169         regs[R_CD2]  = 0x00;
170         regs[R_CD3]  = 0x00;
171         regs[R_MPD]  = 0x00;
172         regs[R_MD1]  = 0x00;
173         regs[R_MD2]  = 0x00;
174         regs[R_MD3]  = 0x00;
175         regs[R_EB1]  = 0xff;
176         regs[R_EB2]  = 0x01;
177         regs[R_EB3]  = 0x84;
178         regs[R_EB4]  = 0x41;
179         regs[R_EB5]  = 0x01;
180         regs[R_EB6]  = 0x84;
181         regs[R_EB7]  = 0x40;
182         regs[R_EB8]  = 0x07;
183         regs[R_EB9]  = 0x00;
184         regs[R_EB10] = 0x00;
185         regs[R_EB11] = 0x96;
186         regs[R_EB12] = 0x0f;
187         regs[R_EB13] = 0xc1;
188         regs[R_EB14] = 0x00;
189         regs[R_EB15] = 0x8f;
190         regs[R_EB16] = 0x00;
191         regs[R_EB17] = 0x00;
192         regs[R_EB18] = 0x00;
193         regs[R_EB19] = 0x00;
194         regs[R_EB20] = 0x20;
195         regs[R_EB21] = 0x33;
196         regs[R_EB22] = 0x48;
197         regs[R_EB23] = 0xb0;
198
199         tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
200         /* setup AGC1 & AGC2 */
201         regs[R_EB17] = 0x00;
202         tda18271_write_regs(fe, R_EB17, 1);
203         regs[R_EB17] = 0x03;
204         tda18271_write_regs(fe, R_EB17, 1);
205         regs[R_EB17] = 0x43;
206         tda18271_write_regs(fe, R_EB17, 1);
207         regs[R_EB17] = 0x4c;
208         tda18271_write_regs(fe, R_EB17, 1);
209
210         regs[R_EB20] = 0xa0;
211         tda18271_write_regs(fe, R_EB20, 1);
212         regs[R_EB20] = 0xa7;
213         tda18271_write_regs(fe, R_EB20, 1);
214         regs[R_EB20] = 0xe7;
215         tda18271_write_regs(fe, R_EB20, 1);
216         regs[R_EB20] = 0xec;
217         tda18271_write_regs(fe, R_EB20, 1);
218
219         /* image rejection calibration */
220
221         /* low-band */
222         regs[R_EP3] = 0x1f;
223         regs[R_EP4] = 0x66;
224         regs[R_EP5] = 0x81;
225         regs[R_CPD] = 0xcc;
226         regs[R_CD1] = 0x6c;
227         regs[R_CD2] = 0x00;
228         regs[R_CD3] = 0x00;
229         regs[R_MPD] = 0xcd;
230         regs[R_MD1] = 0x77;
231         regs[R_MD2] = 0x08;
232         regs[R_MD3] = 0x00;
233
234         tda18271_write_regs(fe, R_EP3, 11);
235         msleep(5); /* pll locking */
236
237         regs[R_EP1] = 0xc6;
238         tda18271_write_regs(fe, R_EP1, 1);
239         msleep(5); /* wanted low measurement */
240
241         regs[R_EP3] = 0x1f;
242         regs[R_EP4] = 0x66;
243         regs[R_EP5] = 0x85;
244         regs[R_CPD] = 0xcb;
245         regs[R_CD1] = 0x66;
246         regs[R_CD2] = 0x70;
247         regs[R_CD3] = 0x00;
248
249         tda18271_write_regs(fe, R_EP3, 7);
250         msleep(5); /* pll locking */
251
252         regs[R_EP2] = 0xdf;
253         tda18271_write_regs(fe, R_EP2, 1);
254         msleep(30); /* image low optimization completion */
255
256         /* mid-band */
257         regs[R_EP3] = 0x1f;
258         regs[R_EP4] = 0x66;
259         regs[R_EP5] = 0x82;
260         regs[R_CPD] = 0xa8;
261         regs[R_CD1] = 0x66;
262         regs[R_CD2] = 0x00;
263         regs[R_CD3] = 0x00;
264         regs[R_MPD] = 0xa9;
265         regs[R_MD1] = 0x73;
266         regs[R_MD2] = 0x1a;
267         regs[R_MD3] = 0x00;
268
269         tda18271_write_regs(fe, R_EP3, 11);
270         msleep(5); /* pll locking */
271
272         regs[R_EP1] = 0xc6;
273         tda18271_write_regs(fe, R_EP1, 1);
274         msleep(5); /* wanted mid measurement */
275
276         regs[R_EP3] = 0x1f;
277         regs[R_EP4] = 0x66;
278         regs[R_EP5] = 0x86;
279         regs[R_CPD] = 0xa8;
280         regs[R_CD1] = 0x66;
281         regs[R_CD2] = 0xa0;
282         regs[R_CD3] = 0x00;
283
284         tda18271_write_regs(fe, R_EP3, 7);
285         msleep(5); /* pll locking */
286
287         regs[R_EP2] = 0xdf;
288         tda18271_write_regs(fe, R_EP2, 1);
289         msleep(30); /* image mid optimization completion */
290
291         /* high-band */
292         regs[R_EP3] = 0x1f;
293         regs[R_EP4] = 0x66;
294         regs[R_EP5] = 0x83;
295         regs[R_CPD] = 0x98;
296         regs[R_CD1] = 0x65;
297         regs[R_CD2] = 0x00;
298         regs[R_CD3] = 0x00;
299         regs[R_MPD] = 0x99;
300         regs[R_MD1] = 0x71;
301         regs[R_MD2] = 0xcd;
302         regs[R_MD3] = 0x00;
303
304         tda18271_write_regs(fe, R_EP3, 11);
305         msleep(5); /* pll locking */
306
307         regs[R_EP1] = 0xc6;
308         tda18271_write_regs(fe, R_EP1, 1);
309         msleep(5); /* wanted high measurement */
310
311         regs[R_EP3] = 0x1f;
312         regs[R_EP4] = 0x66;
313         regs[R_EP5] = 0x87;
314         regs[R_CPD] = 0x98;
315         regs[R_CD1] = 0x65;
316         regs[R_CD2] = 0x50;
317         regs[R_CD3] = 0x00;
318
319         tda18271_write_regs(fe, R_EP3, 7);
320         msleep(5); /* pll locking */
321
322         regs[R_EP2] = 0xdf;
323
324         tda18271_write_regs(fe, R_EP2, 1);
325         msleep(30); /* image high optimization completion */
326
327         regs[R_EP4] = 0x64;
328         tda18271_write_regs(fe, R_EP4, 1);
329
330         regs[R_EP1] = 0xc6;
331         tda18271_write_regs(fe, R_EP1, 1);
332
333         return 0;
334 }
335
336 static int tda18271_init(struct dvb_frontend *fe)
337 {
338         struct tda18271_priv *priv = fe->tuner_priv;
339         unsigned char *regs = priv->tda18271_regs;
340
341         tda18271_read_regs(fe);
342
343         /* test IR_CAL_OK to see if we need init */
344         if ((regs[R_EP1] & 0x08) == 0)
345                 tda18271_init_regs(fe);
346
347         return 0;
348 }
349
350 static int tda18271_tune(struct dvb_frontend *fe,
351                          u32 ifc, u32 freq, u32 bw, u8 std)
352 {
353         struct tda18271_priv *priv = fe->tuner_priv;
354         unsigned char *regs = priv->tda18271_regs;
355         u32 div, N = 0;
356         u8 d, pd, val;
357
358         tda18271_init(fe);
359
360         dbg_info("freq = %d, ifc = %d\n", freq, ifc);
361
362         /* RF tracking filter calibration */
363
364         /* calculate BP_Filter */
365         tda18271_calc_bp_filter(&freq, &val);
366
367         regs[R_EP1]  &= ~0x07; /* clear bp filter bits */
368         regs[R_EP1]  |= val;
369         tda18271_write_regs(fe, R_EP1, 1);
370
371         regs[R_EB4]  &= 0x07;
372         regs[R_EB4]  |= 0x60;
373         tda18271_write_regs(fe, R_EB4, 1);
374
375         regs[R_EB7]   = 0x60;
376         tda18271_write_regs(fe, R_EB7, 1);
377
378         regs[R_EB14]  = 0x00;
379         tda18271_write_regs(fe, R_EB14, 1);
380
381         regs[R_EB20]  = 0xcc;
382         tda18271_write_regs(fe, R_EB20, 1);
383
384         /* set CAL mode to RF tracking filter calibration */
385         regs[R_EB4]  |= 0x03;
386
387         /* calculate CAL PLL */
388
389         switch (priv->mode) {
390         case TDA18271_ANALOG:
391                 N = freq - 1250000;
392                 break;
393         case TDA18271_DIGITAL:
394                 N = freq + bw / 2;
395                 break;
396         }
397
398         tda18271_calc_cal_pll(&N, &pd, &d);
399
400         regs[R_CPD]   = pd;
401
402         div =  ((d * (N / 1000)) << 7) / 125;
403         regs[R_CD1]   = 0xff & (div >> 16);
404         regs[R_CD2]   = 0xff & (div >> 8);
405         regs[R_CD3]   = 0xff & div;
406
407         /* calculate MAIN PLL */
408
409         switch (priv->mode) {
410         case TDA18271_ANALOG:
411                 N = freq - 250000;
412                 break;
413         case TDA18271_DIGITAL:
414                 N = freq + bw / 2 + 1000000;
415                 break;
416         }
417
418         tda18271_calc_main_pll(&N, &pd, &d);
419
420         regs[R_MPD]   = (0x7f & pd);
421
422         switch (priv->mode) {
423         case TDA18271_ANALOG:
424                 regs[R_MPD]  &= ~0x08;
425                 break;
426         case TDA18271_DIGITAL:
427                 regs[R_MPD]  |=  0x08;
428                 break;
429         }
430
431         div =  ((d * (N / 1000)) << 7) / 125;
432         regs[R_MD1]   = 0xff & (div >> 16);
433         regs[R_MD2]   = 0xff & (div >> 8);
434         regs[R_MD3]   = 0xff & div;
435
436         tda18271_write_regs(fe, R_EP3, 11);
437         msleep(5); /* RF tracking filter calibration initialization */
438
439         /* search for K,M,CO for RF Calibration */
440         tda18271_calc_km(&freq, &val);
441
442         regs[R_EB13] &= 0x83;
443         regs[R_EB13] |= val;
444         tda18271_write_regs(fe, R_EB13, 1);
445
446         /* search for RF_BAND */
447         tda18271_calc_rf_band(&freq, &val);
448
449         regs[R_EP2]  &= ~0xe0; /* clear rf band bits */
450         regs[R_EP2]  |= (val << 5);
451
452         /* search for Gain_Taper */
453         tda18271_calc_gain_taper(&freq, &val);
454
455         regs[R_EP2]  &= ~0x1f; /* clear gain taper bits */
456         regs[R_EP2]  |= val;
457
458         tda18271_write_regs(fe, R_EP2, 1);
459         tda18271_write_regs(fe, R_EP1, 1);
460         tda18271_write_regs(fe, R_EP2, 1);
461         tda18271_write_regs(fe, R_EP1, 1);
462
463         regs[R_EB4]  &= 0x07;
464         regs[R_EB4]  |= 0x40;
465         tda18271_write_regs(fe, R_EB4, 1);
466
467         regs[R_EB7]   = 0x40;
468         tda18271_write_regs(fe, R_EB7, 1);
469         msleep(10);
470
471         regs[R_EB20]  = 0xec;
472         tda18271_write_regs(fe, R_EB20, 1);
473         msleep(60); /* RF tracking filter calibration completion */
474
475         regs[R_EP4]  &= ~0x03; /* set cal mode to normal */
476         tda18271_write_regs(fe, R_EP4, 1);
477
478         tda18271_write_regs(fe, R_EP1, 1);
479
480         /* RF tracking filer correction for VHF_Low band */
481         tda18271_calc_rf_cal(&freq, &val);
482
483         /* VHF_Low band only */
484         if (val != 0) {
485                 regs[R_EB14] = val;
486                 tda18271_write_regs(fe, R_EB14, 1);
487         }
488
489         /* Channel Configuration */
490
491         switch (priv->mode) {
492         case TDA18271_ANALOG:
493                 regs[R_EB22]  = 0x2c;
494                 break;
495         case TDA18271_DIGITAL:
496                 regs[R_EB22]  = 0x37;
497                 break;
498         }
499         tda18271_write_regs(fe, R_EB22, 1);
500
501         regs[R_EP1]  |= 0x40; /* set dis power level on */
502
503         /* set standard */
504         regs[R_EP3]  &= ~0x1f; /* clear std bits */
505
506         /* see table 22 */
507         regs[R_EP3]  |= std;
508
509         regs[R_EP4]  &= ~0x03; /* set cal mode to normal */
510
511         regs[R_EP4]  &= ~0x1c; /* clear if level bits */
512         switch (priv->mode) {
513         case TDA18271_ANALOG:
514                 regs[R_MPD]  &= ~0x80; /* IF notch = 0 */
515                 break;
516         case TDA18271_DIGITAL:
517                 regs[R_EP4]  |= 0x04;
518                 regs[R_MPD]  |= 0x80;
519                 break;
520         }
521
522         regs[R_EP4]  &= ~0x80; /* turn this bit on only for fm */
523
524         /* image rejection validity EP5[2:0] */
525         tda18271_calc_ir_measure(&freq, &val);
526
527         regs[R_EP5] &= ~0x07;
528         regs[R_EP5] |= val;
529
530         /* calculate MAIN PLL */
531         N = freq + ifc;
532
533         tda18271_calc_main_pll(&N, &pd, &d);
534
535         regs[R_MPD]   = (0x7f & pd);
536         switch (priv->mode) {
537         case TDA18271_ANALOG:
538                 regs[R_MPD]  &= ~0x08;
539                 break;
540         case TDA18271_DIGITAL:
541                 regs[R_MPD]  |= 0x08;
542                 break;
543         }
544
545         div =  ((d * (N / 1000)) << 7) / 125;
546         regs[R_MD1]   = 0xff & (div >> 16);
547         regs[R_MD2]   = 0xff & (div >> 8);
548         regs[R_MD3]   = 0xff & div;
549
550         tda18271_write_regs(fe, R_TM, 15);
551         msleep(5);
552
553         return 0;
554 }
555
556 /* ------------------------------------------------------------------ */
557
558 static int tda18271_set_params(struct dvb_frontend *fe,
559                                struct dvb_frontend_parameters *params)
560 {
561         struct tda18271_priv *priv = fe->tuner_priv;
562         u8 std;
563         u32 bw, sgIF = 0;
564
565         u32 freq = params->frequency;
566
567         priv->mode = TDA18271_DIGITAL;
568
569         /* see table 22 */
570         if (fe->ops.info.type == FE_ATSC) {
571                 switch (params->u.vsb.modulation) {
572                 case VSB_8:
573                 case VSB_16:
574                         std = 0x1b; /* device-specific (spec says 0x1c) */
575                         sgIF = 5380000;
576                         break;
577                 case QAM_64:
578                 case QAM_256:
579                         std = 0x18; /* device-specific (spec says 0x1d) */
580                         sgIF = 4000000;
581                         break;
582                 default:
583                         printk(KERN_WARNING "%s: modulation not set!\n",
584                                __FUNCTION__);
585                         return -EINVAL;
586                 }
587                 freq += 1750000; /* Adjust to center (+1.75MHZ) */
588                 bw = 6000000;
589         } else if (fe->ops.info.type == FE_OFDM) {
590                 switch (params->u.ofdm.bandwidth) {
591                 case BANDWIDTH_6_MHZ:
592                         std = 0x1b; /* device-specific (spec says 0x1c) */
593                         bw = 6000000;
594                         sgIF = 3300000;
595                         break;
596                 case BANDWIDTH_7_MHZ:
597                         std = 0x19; /* device-specific (spec says 0x1d) */
598                         bw = 7000000;
599                         sgIF = 3800000;
600                         break;
601                 case BANDWIDTH_8_MHZ:
602                         std = 0x1a; /* device-specific (spec says 0x1e) */
603                         bw = 8000000;
604                         sgIF = 4300000;
605                         break;
606                 default:
607                         printk(KERN_WARNING "%s: bandwidth not set!\n",
608                                __FUNCTION__);
609                         return -EINVAL;
610                 }
611         } else {
612                 printk(KERN_WARNING "%s: modulation type not supported!\n",
613                        __FUNCTION__);
614                 return -EINVAL;
615         }
616
617         return tda18271_tune(fe, sgIF, freq, bw, std);
618 }
619
620 static int tda18271_set_analog_params(struct dvb_frontend *fe,
621                                       struct analog_parameters *params)
622 {
623         struct tda18271_priv *priv = fe->tuner_priv;
624         u8 std;
625         unsigned int sgIF;
626         char *mode;
627
628         priv->mode = TDA18271_ANALOG;
629
630         /* see table 22 */
631         if (params->std & V4L2_STD_MN) {
632                 std = 0x0d;
633                 sgIF =  92;
634                 mode = "MN";
635         } else if (params->std & V4L2_STD_B) {
636                 std = 0x0e;
637                 sgIF =  108;
638                 mode = "B";
639         } else if (params->std & V4L2_STD_GH) {
640                 std = 0x0f;
641                 sgIF =  124;
642                 mode = "GH";
643         } else if (params->std & V4L2_STD_PAL_I) {
644                 std = 0x0f;
645                 sgIF =  124;
646                 mode = "I";
647         } else if (params->std & V4L2_STD_DK) {
648                 std = 0x0f;
649                 sgIF =  124;
650                 mode = "DK";
651         } else if (params->std & V4L2_STD_SECAM_L) {
652                 std = 0x0f;
653                 sgIF =  124;
654                 mode = "L";
655         } else if (params->std & V4L2_STD_SECAM_LC) {
656                 std = 0x0f;
657                 sgIF =  20;
658                 mode = "LC";
659         } else {
660                 std = 0x0f;
661                 sgIF =  124;
662                 mode = "xx";
663         }
664
665         if (params->mode == V4L2_TUNER_RADIO)
666                 sgIF =  88; /* if frequency is 5.5 MHz */
667
668         dbg_info("setting tda18271 to system %s\n", mode);
669
670         return tda18271_tune(fe, sgIF * 62500, params->frequency * 62500,
671                              0, std);
672 }
673
674 static int tda18271_release(struct dvb_frontend *fe)
675 {
676         kfree(fe->tuner_priv);
677         fe->tuner_priv = NULL;
678         return 0;
679 }
680
681 static int tda18271_get_frequency(struct dvb_frontend *fe, u32 *frequency)
682 {
683         struct tda18271_priv *priv = fe->tuner_priv;
684         *frequency = priv->frequency;
685         return 0;
686 }
687
688 static int tda18271_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
689 {
690         struct tda18271_priv *priv = fe->tuner_priv;
691         *bandwidth = priv->bandwidth;
692         return 0;
693 }
694
695 static struct dvb_tuner_ops tda18271_tuner_ops = {
696         .info = {
697                 .name = "NXP TDA18271HD",
698                 .frequency_min  =  45000000,
699                 .frequency_max  = 864000000,
700                 .frequency_step =     62500
701         },
702         .init              = tda18271_init,
703         .set_params        = tda18271_set_params,
704         .set_analog_params = tda18271_set_analog_params,
705         .release           = tda18271_release,
706         .get_frequency     = tda18271_get_frequency,
707         .get_bandwidth     = tda18271_get_bandwidth,
708 };
709
710 struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
711                                      struct i2c_adapter *i2c)
712 {
713         struct tda18271_priv *priv = NULL;
714
715         dbg_info("@ %d-%04x\n", i2c_adapter_id(i2c), addr);
716         priv = kzalloc(sizeof(struct tda18271_priv), GFP_KERNEL);
717         if (priv == NULL)
718                 return NULL;
719
720         priv->i2c_addr = addr;
721         priv->i2c_adap = i2c;
722
723         memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops,
724                sizeof(struct dvb_tuner_ops));
725
726         fe->tuner_priv = priv;
727
728         tda18271_init_regs(fe);
729
730         return fe;
731 }
732 EXPORT_SYMBOL_GPL(tda18271_attach);
733 MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver");
734 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
735 MODULE_LICENSE("GPL");
736
737 /*
738  * Overrides for Emacs so that we follow Linus's tabbing style.
739  * ---------------------------------------------------------------------------
740  * Local variables:
741  * c-basic-offset: 8
742  * End:
743  */