Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / drivers / media / tuners / mt2063.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Driver for mt2063 Micronas tuner
4  *
5  * Copyright (c) 2011 Mauro Carvalho Chehab
6  *
7  * This driver came from a driver originally written by:
8  *              Henry Wang <Henry.wang@AzureWave.com>
9  * Made publicly available by Terratec, at:
10  *      http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
11  */
12
13 #include <linux/init.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/string.h>
17 #include <linux/videodev2.h>
18 #include <linux/gcd.h>
19
20 #include "mt2063.h"
21
22 static unsigned int debug;
23 module_param(debug, int, 0644);
24 MODULE_PARM_DESC(debug, "Set Verbosity level");
25
26 #define dprintk(level, fmt, arg...) do {                                \
27 if (debug >= level)                                                     \
28         printk(KERN_DEBUG "mt2063 %s: " fmt, __func__, ## arg); \
29 } while (0)
30
31
32 /* positive error codes used internally */
33
34 /*  Info: Unavoidable LO-related spur may be present in the output  */
35 #define MT2063_SPUR_PRESENT_ERR             (0x00800000)
36
37 /*  Info: Mask of bits used for # of LO-related spurs that were avoided during tuning  */
38 #define MT2063_SPUR_CNT_MASK                (0x001f0000)
39 #define MT2063_SPUR_SHIFT                   (16)
40
41 /*  Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */
42 #define MT2063_UPC_RANGE                    (0x04000000)
43
44 /*  Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */
45 #define MT2063_DNC_RANGE                    (0x08000000)
46
47 /*
48  *  Constant defining the version of the following structure
49  *  and therefore the API for this code.
50  *
51  *  When compiling the tuner driver, the preprocessor will
52  *  check against this version number to make sure that
53  *  it matches the version that the tuner driver knows about.
54  */
55
56 /* DECT Frequency Avoidance */
57 #define MT2063_DECT_AVOID_US_FREQS      0x00000001
58
59 #define MT2063_DECT_AVOID_EURO_FREQS    0x00000002
60
61 #define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0)
62
63 #define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0)
64
65 enum MT2063_DECT_Avoid_Type {
66         MT2063_NO_DECT_AVOIDANCE = 0,                           /* Do not create DECT exclusion zones.     */
67         MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS,      /* Avoid US DECT frequencies.              */
68         MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS,  /* Avoid European DECT frequencies.        */
69         MT2063_AVOID_BOTH                                       /* Avoid both regions. Not typically used. */
70 };
71
72 #define MT2063_MAX_ZONES 48
73
74 struct MT2063_ExclZone_t {
75         u32 min_;
76         u32 max_;
77         struct MT2063_ExclZone_t *next_;
78 };
79
80 /*
81  *  Structure of data needed for Spur Avoidance
82  */
83 struct MT2063_AvoidSpursData_t {
84         u32 f_ref;
85         u32 f_in;
86         u32 f_LO1;
87         u32 f_if1_Center;
88         u32 f_if1_Request;
89         u32 f_if1_bw;
90         u32 f_LO2;
91         u32 f_out;
92         u32 f_out_bw;
93         u32 f_LO1_Step;
94         u32 f_LO2_Step;
95         u32 f_LO1_FracN_Avoid;
96         u32 f_LO2_FracN_Avoid;
97         u32 f_zif_bw;
98         u32 f_min_LO_Separation;
99         u32 maxH1;
100         u32 maxH2;
101         enum MT2063_DECT_Avoid_Type avoidDECT;
102         u32 bSpurPresent;
103         u32 bSpurAvoided;
104         u32 nSpursFound;
105         u32 nZones;
106         struct MT2063_ExclZone_t *freeZones;
107         struct MT2063_ExclZone_t *usedZones;
108         struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES];
109 };
110
111 /*
112  * Parameter for function MT2063_SetPowerMask that specifies the power down
113  * of various sections of the MT2063.
114  */
115 enum MT2063_Mask_Bits {
116         MT2063_REG_SD = 0x0040,         /* Shutdown regulator                 */
117         MT2063_SRO_SD = 0x0020,         /* Shutdown SRO                       */
118         MT2063_AFC_SD = 0x0010,         /* Shutdown AFC A/D                   */
119         MT2063_PD_SD = 0x0002,          /* Enable power detector shutdown     */
120         MT2063_PDADC_SD = 0x0001,       /* Enable power detector A/D shutdown */
121         MT2063_VCO_SD = 0x8000,         /* Enable VCO shutdown                */
122         MT2063_LTX_SD = 0x4000,         /* Enable LTX shutdown                */
123         MT2063_LT1_SD = 0x2000,         /* Enable LT1 shutdown                */
124         MT2063_LNA_SD = 0x1000,         /* Enable LNA shutdown                */
125         MT2063_UPC_SD = 0x0800,         /* Enable upconverter shutdown        */
126         MT2063_DNC_SD = 0x0400,         /* Enable downconverter shutdown      */
127         MT2063_VGA_SD = 0x0200,         /* Enable VGA shutdown                */
128         MT2063_AMP_SD = 0x0100,         /* Enable AMP shutdown                */
129         MT2063_ALL_SD = 0xFF73,         /* All shutdown bits for this tuner   */
130         MT2063_NONE_SD = 0x0000         /* No shutdown bits                   */
131 };
132
133 /*
134  *  Possible values for MT2063_DNC_OUTPUT
135  */
136 enum MT2063_DNC_Output_Enable {
137         MT2063_DNC_NONE = 0,
138         MT2063_DNC_1,
139         MT2063_DNC_2,
140         MT2063_DNC_BOTH
141 };
142
143 /*
144  *  Two-wire serial bus subaddresses of the tuner registers.
145  *  Also known as the tuner's register addresses.
146  */
147 enum MT2063_Register_Offsets {
148         MT2063_REG_PART_REV = 0,        /*  0x00: Part/Rev Code         */
149         MT2063_REG_LO1CQ_1,             /*  0x01: LO1C Queued Byte 1    */
150         MT2063_REG_LO1CQ_2,             /*  0x02: LO1C Queued Byte 2    */
151         MT2063_REG_LO2CQ_1,             /*  0x03: LO2C Queued Byte 1    */
152         MT2063_REG_LO2CQ_2,             /*  0x04: LO2C Queued Byte 2    */
153         MT2063_REG_LO2CQ_3,             /*  0x05: LO2C Queued Byte 3    */
154         MT2063_REG_RSVD_06,             /*  0x06: Reserved              */
155         MT2063_REG_LO_STATUS,           /*  0x07: LO Status             */
156         MT2063_REG_FIFFC,               /*  0x08: FIFF Center           */
157         MT2063_REG_CLEARTUNE,           /*  0x09: ClearTune Filter      */
158         MT2063_REG_ADC_OUT,             /*  0x0A: ADC_OUT               */
159         MT2063_REG_LO1C_1,              /*  0x0B: LO1C Byte 1           */
160         MT2063_REG_LO1C_2,              /*  0x0C: LO1C Byte 2           */
161         MT2063_REG_LO2C_1,              /*  0x0D: LO2C Byte 1           */
162         MT2063_REG_LO2C_2,              /*  0x0E: LO2C Byte 2           */
163         MT2063_REG_LO2C_3,              /*  0x0F: LO2C Byte 3           */
164         MT2063_REG_RSVD_10,             /*  0x10: Reserved              */
165         MT2063_REG_PWR_1,               /*  0x11: PWR Byte 1            */
166         MT2063_REG_PWR_2,               /*  0x12: PWR Byte 2            */
167         MT2063_REG_TEMP_STATUS,         /*  0x13: Temp Status           */
168         MT2063_REG_XO_STATUS,           /*  0x14: Crystal Status        */
169         MT2063_REG_RF_STATUS,           /*  0x15: RF Attn Status        */
170         MT2063_REG_FIF_STATUS,          /*  0x16: FIF Attn Status       */
171         MT2063_REG_LNA_OV,              /*  0x17: LNA Attn Override     */
172         MT2063_REG_RF_OV,               /*  0x18: RF Attn Override      */
173         MT2063_REG_FIF_OV,              /*  0x19: FIF Attn Override     */
174         MT2063_REG_LNA_TGT,             /*  0x1A: Reserved              */
175         MT2063_REG_PD1_TGT,             /*  0x1B: Pwr Det 1 Target      */
176         MT2063_REG_PD2_TGT,             /*  0x1C: Pwr Det 2 Target      */
177         MT2063_REG_RSVD_1D,             /*  0x1D: Reserved              */
178         MT2063_REG_RSVD_1E,             /*  0x1E: Reserved              */
179         MT2063_REG_RSVD_1F,             /*  0x1F: Reserved              */
180         MT2063_REG_RSVD_20,             /*  0x20: Reserved              */
181         MT2063_REG_BYP_CTRL,            /*  0x21: Bypass Control        */
182         MT2063_REG_RSVD_22,             /*  0x22: Reserved              */
183         MT2063_REG_RSVD_23,             /*  0x23: Reserved              */
184         MT2063_REG_RSVD_24,             /*  0x24: Reserved              */
185         MT2063_REG_RSVD_25,             /*  0x25: Reserved              */
186         MT2063_REG_RSVD_26,             /*  0x26: Reserved              */
187         MT2063_REG_RSVD_27,             /*  0x27: Reserved              */
188         MT2063_REG_FIFF_CTRL,           /*  0x28: FIFF Control          */
189         MT2063_REG_FIFF_OFFSET,         /*  0x29: FIFF Offset           */
190         MT2063_REG_CTUNE_CTRL,          /*  0x2A: Reserved              */
191         MT2063_REG_CTUNE_OV,            /*  0x2B: Reserved              */
192         MT2063_REG_CTRL_2C,             /*  0x2C: Reserved              */
193         MT2063_REG_FIFF_CTRL2,          /*  0x2D: Fiff Control          */
194         MT2063_REG_RSVD_2E,             /*  0x2E: Reserved              */
195         MT2063_REG_DNC_GAIN,            /*  0x2F: DNC Control           */
196         MT2063_REG_VGA_GAIN,            /*  0x30: VGA Gain Ctrl         */
197         MT2063_REG_RSVD_31,             /*  0x31: Reserved              */
198         MT2063_REG_TEMP_SEL,            /*  0x32: Temperature Selection */
199         MT2063_REG_RSVD_33,             /*  0x33: Reserved              */
200         MT2063_REG_RSVD_34,             /*  0x34: Reserved              */
201         MT2063_REG_RSVD_35,             /*  0x35: Reserved              */
202         MT2063_REG_RSVD_36,             /*  0x36: Reserved              */
203         MT2063_REG_RSVD_37,             /*  0x37: Reserved              */
204         MT2063_REG_RSVD_38,             /*  0x38: Reserved              */
205         MT2063_REG_RSVD_39,             /*  0x39: Reserved              */
206         MT2063_REG_RSVD_3A,             /*  0x3A: Reserved              */
207         MT2063_REG_RSVD_3B,             /*  0x3B: Reserved              */
208         MT2063_REG_RSVD_3C,             /*  0x3C: Reserved              */
209         MT2063_REG_END_REGS
210 };
211
212 struct mt2063_state {
213         struct i2c_adapter *i2c;
214
215         bool init;
216
217         const struct mt2063_config *config;
218         struct dvb_tuner_ops ops;
219         struct dvb_frontend *frontend;
220
221         u32 frequency;
222         u32 srate;
223         u32 bandwidth;
224         u32 reference;
225
226         u32 tuner_id;
227         struct MT2063_AvoidSpursData_t AS_Data;
228         u32 f_IF1_actual;
229         u32 rcvr_mode;
230         u32 ctfilt_sw;
231         u32 CTFiltMax[31];
232         u32 num_regs;
233         u8 reg[MT2063_REG_END_REGS];
234 };
235
236 /*
237  * mt2063_write - Write data into the I2C bus
238  */
239 static int mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
240 {
241         struct dvb_frontend *fe = state->frontend;
242         int ret;
243         u8 buf[60];
244         struct i2c_msg msg = {
245                 .addr = state->config->tuner_address,
246                 .flags = 0,
247                 .buf = buf,
248                 .len = len + 1
249         };
250
251         dprintk(2, "\n");
252
253         msg.buf[0] = reg;
254         memcpy(msg.buf + 1, data, len);
255
256         if (fe->ops.i2c_gate_ctrl)
257                 fe->ops.i2c_gate_ctrl(fe, 1);
258         ret = i2c_transfer(state->i2c, &msg, 1);
259         if (fe->ops.i2c_gate_ctrl)
260                 fe->ops.i2c_gate_ctrl(fe, 0);
261
262         if (ret < 0)
263                 printk(KERN_ERR "%s error ret=%d\n", __func__, ret);
264
265         return ret;
266 }
267
268 /*
269  * mt2063_write - Write register data into the I2C bus, caching the value
270  */
271 static int mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
272 {
273         int status;
274
275         dprintk(2, "\n");
276
277         if (reg >= MT2063_REG_END_REGS)
278                 return -ERANGE;
279
280         status = mt2063_write(state, reg, &val, 1);
281         if (status < 0)
282                 return status;
283
284         state->reg[reg] = val;
285
286         return 0;
287 }
288
289 /*
290  * mt2063_read - Read data from the I2C bus
291  */
292 static int mt2063_read(struct mt2063_state *state,
293                            u8 subAddress, u8 *pData, u32 cnt)
294 {
295         int status = 0; /* Status to be returned        */
296         struct dvb_frontend *fe = state->frontend;
297         u32 i = 0;
298
299         dprintk(2, "addr 0x%02x, cnt %d\n", subAddress, cnt);
300
301         if (fe->ops.i2c_gate_ctrl)
302                 fe->ops.i2c_gate_ctrl(fe, 1);
303
304         for (i = 0; i < cnt; i++) {
305                 u8 b0[] = { subAddress + i };
306                 struct i2c_msg msg[] = {
307                         {
308                                 .addr = state->config->tuner_address,
309                                 .flags = 0,
310                                 .buf = b0,
311                                 .len = 1
312                         }, {
313                                 .addr = state->config->tuner_address,
314                                 .flags = I2C_M_RD,
315                                 .buf = pData + i,
316                                 .len = 1
317                         }
318                 };
319
320                 status = i2c_transfer(state->i2c, msg, 2);
321                 dprintk(2, "addr 0x%02x, ret = %d, val = 0x%02x\n",
322                            subAddress + i, status, *(pData + i));
323                 if (status < 0)
324                         break;
325         }
326         if (fe->ops.i2c_gate_ctrl)
327                 fe->ops.i2c_gate_ctrl(fe, 0);
328
329         if (status < 0)
330                 printk(KERN_ERR "Can't read from address 0x%02x,\n",
331                        subAddress + i);
332
333         return status;
334 }
335
336 /*
337  * FIXME: Is this really needed?
338  */
339 static int MT2063_Sleep(struct dvb_frontend *fe)
340 {
341         /*
342          *  ToDo:  Add code here to implement a OS blocking
343          */
344         msleep(100);
345
346         return 0;
347 }
348
349 /*
350  * Microtune spur avoidance
351  */
352
353 /*  Implement ceiling, floor functions.  */
354 #define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))
355 #define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))
356
357 struct MT2063_FIFZone_t {
358         s32 min_;
359         s32 max_;
360 };
361
362 static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t
363                                             *pAS_Info,
364                                             struct MT2063_ExclZone_t *pPrevNode)
365 {
366         struct MT2063_ExclZone_t *pNode;
367
368         dprintk(2, "\n");
369
370         /*  Check for a node in the free list  */
371         if (pAS_Info->freeZones != NULL) {
372                 /*  Use one from the free list  */
373                 pNode = pAS_Info->freeZones;
374                 pAS_Info->freeZones = pNode->next_;
375         } else {
376                 /*  Grab a node from the array  */
377                 pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones];
378         }
379
380         if (pPrevNode != NULL) {
381                 pNode->next_ = pPrevNode->next_;
382                 pPrevNode->next_ = pNode;
383         } else {                /*  insert at the beginning of the list  */
384
385                 pNode->next_ = pAS_Info->usedZones;
386                 pAS_Info->usedZones = pNode;
387         }
388
389         pAS_Info->nZones++;
390         return pNode;
391 }
392
393 static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t
394                                             *pAS_Info,
395                                             struct MT2063_ExclZone_t *pPrevNode,
396                                             struct MT2063_ExclZone_t
397                                             *pNodeToRemove)
398 {
399         struct MT2063_ExclZone_t *pNext = pNodeToRemove->next_;
400
401         dprintk(2, "\n");
402
403         /*  Make previous node point to the subsequent node  */
404         if (pPrevNode != NULL)
405                 pPrevNode->next_ = pNext;
406
407         /*  Add pNodeToRemove to the beginning of the freeZones  */
408         pNodeToRemove->next_ = pAS_Info->freeZones;
409         pAS_Info->freeZones = pNodeToRemove;
410
411         /*  Decrement node count  */
412         pAS_Info->nZones--;
413
414         return pNext;
415 }
416
417 /*
418  * MT_AddExclZone()
419  *
420  * Add (and merge) an exclusion zone into the list.
421  * If the range (f_min, f_max) is totally outside the
422  * 1st IF BW, ignore the entry.
423  * If the range (f_min, f_max) is negative, ignore the entry.
424  */
425 static void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
426                                u32 f_min, u32 f_max)
427 {
428         struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
429         struct MT2063_ExclZone_t *pPrev = NULL;
430         struct MT2063_ExclZone_t *pNext = NULL;
431
432         dprintk(2, "\n");
433
434         /*  Check to see if this overlaps the 1st IF filter  */
435         if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2)))
436             && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2)))
437             && (f_min < f_max)) {
438                 /*
439                  *                1        2         3      4       5        6
440                  *
441                  *   New entry:  |---|    |--|      |--|    |-|    |---|    |--|
442                  *                or       or        or     or      or
443                  *   Existing:  |--|      |--|      |--|    |---|  |-|      |--|
444                  */
445
446                 /*  Check for our place in the list  */
447                 while ((pNode != NULL) && (pNode->max_ < f_min)) {
448                         pPrev = pNode;
449                         pNode = pNode->next_;
450                 }
451
452                 if ((pNode != NULL) && (pNode->min_ < f_max)) {
453                         /*  Combine me with pNode  */
454                         if (f_min < pNode->min_)
455                                 pNode->min_ = f_min;
456                         if (f_max > pNode->max_)
457                                 pNode->max_ = f_max;
458                 } else {
459                         pNode = InsertNode(pAS_Info, pPrev);
460                         pNode->min_ = f_min;
461                         pNode->max_ = f_max;
462                 }
463
464                 /*  Look for merging possibilities  */
465                 pNext = pNode->next_;
466                 while ((pNext != NULL) && (pNext->min_ < pNode->max_)) {
467                         if (pNext->max_ > pNode->max_)
468                                 pNode->max_ = pNext->max_;
469                         /*  Remove pNext, return ptr to pNext->next  */
470                         pNext = RemoveNode(pAS_Info, pNode, pNext);
471                 }
472         }
473 }
474
475 /*
476  *  Reset all exclusion zones.
477  *  Add zones to protect the PLL FracN regions near zero
478  */
479 static void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info)
480 {
481         u32 center;
482
483         dprintk(2, "\n");
484
485         pAS_Info->nZones = 0;   /*  this clears the used list  */
486         pAS_Info->usedZones = NULL;     /*  reset ptr                  */
487         pAS_Info->freeZones = NULL;     /*  reset ptr                  */
488
489         center =
490             pAS_Info->f_ref *
491             ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 +
492               pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in;
493         while (center <
494                pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
495                pAS_Info->f_LO1_FracN_Avoid) {
496                 /*  Exclude LO1 FracN  */
497                 MT2063_AddExclZone(pAS_Info,
498                                    center - pAS_Info->f_LO1_FracN_Avoid,
499                                    center - 1);
500                 MT2063_AddExclZone(pAS_Info, center + 1,
501                                    center + pAS_Info->f_LO1_FracN_Avoid);
502                 center += pAS_Info->f_ref;
503         }
504
505         center =
506             pAS_Info->f_ref *
507             ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 -
508               pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out;
509         while (center <
510                pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
511                pAS_Info->f_LO2_FracN_Avoid) {
512                 /*  Exclude LO2 FracN  */
513                 MT2063_AddExclZone(pAS_Info,
514                                    center - pAS_Info->f_LO2_FracN_Avoid,
515                                    center - 1);
516                 MT2063_AddExclZone(pAS_Info, center + 1,
517                                    center + pAS_Info->f_LO2_FracN_Avoid);
518                 center += pAS_Info->f_ref;
519         }
520
521         if (MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
522                 /*  Exclude LO1 values that conflict with DECT channels */
523                 MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */
524                 MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */
525                 MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */
526                 MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */
527                 MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */
528         }
529
530         if (MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
531                 MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */
532                 MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */
533                 MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */
534                 MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16  */
535                 MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */
536                 MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */
537                 MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */
538                 MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */
539                 MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52  */
540                 MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */
541         }
542 }
543
544 /*
545  * MT_ChooseFirstIF - Choose the best available 1st IF
546  *                    If f_Desired is not excluded, choose that first.
547  *                    Otherwise, return the value closest to f_Center that is
548  *                    not excluded
549  */
550 static u32 MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
551 {
552         /*
553          * Update "f_Desired" to be the nearest "combinational-multiple" of
554          * "f_LO1_Step".
555          * The resulting number, F_LO1 must be a multiple of f_LO1_Step.
556          * And F_LO1 is the arithmetic sum of f_in + f_Center.
557          * Neither f_in, nor f_Center must be a multiple of f_LO1_Step.
558          * However, the sum must be.
559          */
560         const u32 f_Desired =
561             pAS_Info->f_LO1_Step *
562             ((pAS_Info->f_if1_Request + pAS_Info->f_in +
563               pAS_Info->f_LO1_Step / 2) / pAS_Info->f_LO1_Step) -
564             pAS_Info->f_in;
565         const u32 f_Step =
566             (pAS_Info->f_LO1_Step >
567              pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->
568             f_LO2_Step;
569         u32 f_Center;
570         s32 i;
571         s32 j = 0;
572         u32 bDesiredExcluded = 0;
573         u32 bZeroExcluded = 0;
574         s32 tmpMin, tmpMax;
575         s32 bestDiff;
576         struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
577         struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES];
578
579         dprintk(2, "\n");
580
581         if (pAS_Info->nZones == 0)
582                 return f_Desired;
583
584         /*
585          *  f_Center needs to be an integer multiple of f_Step away
586          *  from f_Desired
587          */
588         if (pAS_Info->f_if1_Center > f_Desired)
589                 f_Center =
590                     f_Desired +
591                     f_Step *
592                     ((pAS_Info->f_if1_Center - f_Desired +
593                       f_Step / 2) / f_Step);
594         else
595                 f_Center =
596                     f_Desired -
597                     f_Step *
598                     ((f_Desired - pAS_Info->f_if1_Center +
599                       f_Step / 2) / f_Step);
600
601         /*
602          * Take MT_ExclZones, center around f_Center and change the
603          * resolution to f_Step
604          */
605         while (pNode != NULL) {
606                 /*  floor function  */
607                 tmpMin =
608                     floor((s32) (pNode->min_ - f_Center), (s32) f_Step);
609
610                 /*  ceil function  */
611                 tmpMax =
612                     ceil((s32) (pNode->max_ - f_Center), (s32) f_Step);
613
614                 if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired))
615                         bDesiredExcluded = 1;
616
617                 if ((tmpMin < 0) && (tmpMax > 0))
618                         bZeroExcluded = 1;
619
620                 /*  See if this zone overlaps the previous  */
621                 if ((j > 0) && (tmpMin < zones[j - 1].max_))
622                         zones[j - 1].max_ = tmpMax;
623                 else {
624                         /*  Add new zone  */
625                         zones[j].min_ = tmpMin;
626                         zones[j].max_ = tmpMax;
627                         j++;
628                 }
629                 pNode = pNode->next_;
630         }
631
632         /*
633          *  If the desired is okay, return with it
634          */
635         if (bDesiredExcluded == 0)
636                 return f_Desired;
637
638         /*
639          *  If the desired is excluded and the center is okay, return with it
640          */
641         if (bZeroExcluded == 0)
642                 return f_Center;
643
644         /*  Find the value closest to 0 (f_Center)  */
645         bestDiff = zones[0].min_;
646         for (i = 0; i < j; i++) {
647                 if (abs(zones[i].min_) < abs(bestDiff))
648                         bestDiff = zones[i].min_;
649                 if (abs(zones[i].max_) < abs(bestDiff))
650                         bestDiff = zones[i].max_;
651         }
652
653         if (bestDiff < 0)
654                 return f_Center - ((u32) (-bestDiff) * f_Step);
655
656         return f_Center + (bestDiff * f_Step);
657 }
658
659 /**
660  * IsSpurInBand() - Checks to see if a spur will be present within the IF's
661  *                  bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW)
662  *
663  *                    ma   mb                                     mc   md
664  *                  <--+-+-+-------------------+-------------------+-+-+-->
665  *                     |   ^                   0                   ^   |
666  *                     ^   b=-fIFOut+fIFBW/2      -b=+fIFOut-fIFBW/2   ^
667  *                     a=-fIFOut-fIFBW/2              -a=+fIFOut+fIFBW/2
668  *
669  *                  Note that some equations are doubled to prevent round-off
670  *                  problems when calculating fIFBW/2
671  *
672  * @pAS_Info:   Avoid Spurs information block
673  * @fm:         If spur, amount f_IF1 has to move negative
674  * @fp:         If spur, amount f_IF1 has to move positive
675  *
676  *  Returns 1 if an LO spur would be present, otherwise 0.
677  */
678 static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
679                         u32 *fm, u32 * fp)
680 {
681         /*
682          **  Calculate LO frequency settings.
683          */
684         u32 n, n0;
685         const u32 f_LO1 = pAS_Info->f_LO1;
686         const u32 f_LO2 = pAS_Info->f_LO2;
687         const u32 d = pAS_Info->f_out + pAS_Info->f_out_bw / 2;
688         const u32 c = d - pAS_Info->f_out_bw;
689         const u32 f = pAS_Info->f_zif_bw / 2;
690         const u32 f_Scale = (f_LO1 / (UINT_MAX / 2 / pAS_Info->maxH1)) + 1;
691         s32 f_nsLO1, f_nsLO2;
692         s32 f_Spur;
693         u32 ma, mb, mc, md, me, mf;
694         u32 lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
695
696         dprintk(2, "\n");
697
698         *fm = 0;
699
700         /*
701          ** For each edge (d, c & f), calculate a scale, based on the gcd
702          ** of f_LO1, f_LO2 and the edge value.  Use the larger of this
703          ** gcd-based scale factor or f_Scale.
704          */
705         lo_gcd = gcd(f_LO1, f_LO2);
706         gd_Scale = max((u32) gcd(lo_gcd, d), f_Scale);
707         hgds = gd_Scale / 2;
708         gc_Scale = max((u32) gcd(lo_gcd, c), f_Scale);
709         hgcs = gc_Scale / 2;
710         gf_Scale = max((u32) gcd(lo_gcd, f), f_Scale);
711         hgfs = gf_Scale / 2;
712
713         n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2);
714
715         /*  Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic  */
716         for (n = n0; n <= pAS_Info->maxH1; ++n) {
717                 md = (n * ((f_LO1 + hgds) / gd_Scale) -
718                       ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
719
720                 /*  If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present  */
721                 if (md >= pAS_Info->maxH1)
722                         break;
723
724                 ma = (n * ((f_LO1 + hgds) / gd_Scale) +
725                       ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
726
727                 /*  If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic  */
728                 if (md == ma)
729                         continue;
730
731                 mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
732                       ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
733                 if (mc != md) {
734                         f_nsLO1 = (s32) (n * (f_LO1 / gc_Scale));
735                         f_nsLO2 = (s32) (mc * (f_LO2 / gc_Scale));
736                         f_Spur =
737                             (gc_Scale * (f_nsLO1 - f_nsLO2)) +
738                             n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
739
740                         *fp = ((f_Spur - (s32) c) / (mc - n)) + 1;
741                         *fm = (((s32) d - f_Spur) / (mc - n)) + 1;
742                         return 1;
743                 }
744
745                 /*  Location of Zero-IF-spur to be checked  */
746                 me = (n * ((f_LO1 + hgfs) / gf_Scale) +
747                       ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
748                 mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
749                       ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
750                 if (me != mf) {
751                         f_nsLO1 = n * (f_LO1 / gf_Scale);
752                         f_nsLO2 = me * (f_LO2 / gf_Scale);
753                         f_Spur =
754                             (gf_Scale * (f_nsLO1 - f_nsLO2)) +
755                             n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
756
757                         *fp = ((f_Spur + (s32) f) / (me - n)) + 1;
758                         *fm = (((s32) f - f_Spur) / (me - n)) + 1;
759                         return 1;
760                 }
761
762                 mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
763                       ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
764                 if (ma != mb) {
765                         f_nsLO1 = n * (f_LO1 / gc_Scale);
766                         f_nsLO2 = ma * (f_LO2 / gc_Scale);
767                         f_Spur =
768                             (gc_Scale * (f_nsLO1 - f_nsLO2)) +
769                             n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
770
771                         *fp = (((s32) d + f_Spur) / (ma - n)) + 1;
772                         *fm = (-(f_Spur + (s32) c) / (ma - n)) + 1;
773                         return 1;
774                 }
775         }
776
777         /*  No spurs found  */
778         return 0;
779 }
780
781 /*
782  * MT_AvoidSpurs() - Main entry point to avoid spurs.
783  *                   Checks for existing spurs in present LO1, LO2 freqs
784  *                   and if present, chooses spur-free LO1, LO2 combination
785  *                   that tunes the same input/output frequencies.
786  */
787 static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
788 {
789         int status = 0;
790         u32 fm, fp;             /*  restricted range on LO's        */
791         pAS_Info->bSpurAvoided = 0;
792         pAS_Info->nSpursFound = 0;
793
794         dprintk(2, "\n");
795
796         if (pAS_Info->maxH1 == 0)
797                 return 0;
798
799         /*
800          * Avoid LO Generated Spurs
801          *
802          * Make sure that have no LO-related spurs within the IF output
803          * bandwidth.
804          *
805          * If there is an LO spur in this band, start at the current IF1 frequency
806          * and work out until we find a spur-free frequency or run up against the
807          * 1st IF SAW band edge.  Use temporary copies of fLO1 and fLO2 so that they
808          * will be unchanged if a spur-free setting is not found.
809          */
810         pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
811         if (pAS_Info->bSpurPresent) {
812                 u32 zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in;   /*  current attempt at a 1st IF  */
813                 u32 zfLO1 = pAS_Info->f_LO1;    /*  current attempt at an LO1 freq  */
814                 u32 zfLO2 = pAS_Info->f_LO2;    /*  current attempt at an LO2 freq  */
815                 u32 delta_IF1;
816                 u32 new_IF1;
817
818                 /*
819                  **  Spur was found, attempt to find a spur-free 1st IF
820                  */
821                 do {
822                         pAS_Info->nSpursFound++;
823
824                         /*  Raise f_IF1_upper, if needed  */
825                         MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
826
827                         /*  Choose next IF1 that is closest to f_IF1_CENTER              */
828                         new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
829
830                         if (new_IF1 > zfIF1) {
831                                 pAS_Info->f_LO1 += (new_IF1 - zfIF1);
832                                 pAS_Info->f_LO2 += (new_IF1 - zfIF1);
833                         } else {
834                                 pAS_Info->f_LO1 -= (zfIF1 - new_IF1);
835                                 pAS_Info->f_LO2 -= (zfIF1 - new_IF1);
836                         }
837                         zfIF1 = new_IF1;
838
839                         if (zfIF1 > pAS_Info->f_if1_Center)
840                                 delta_IF1 = zfIF1 - pAS_Info->f_if1_Center;
841                         else
842                                 delta_IF1 = pAS_Info->f_if1_Center - zfIF1;
843
844                         pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
845                 /*
846                  *  Continue while the new 1st IF is still within the 1st IF bandwidth
847                  *  and there is a spur in the band (again)
848                  */
849                 } while ((2 * delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && pAS_Info->bSpurPresent);
850
851                 /*
852                  * Use the LO-spur free values found.  If the search went all
853                  * the way to the 1st IF band edge and always found spurs, just
854                  * leave the original choice.  It's as "good" as any other.
855                  */
856                 if (pAS_Info->bSpurPresent == 1) {
857                         status |= MT2063_SPUR_PRESENT_ERR;
858                         pAS_Info->f_LO1 = zfLO1;
859                         pAS_Info->f_LO2 = zfLO2;
860                 } else
861                         pAS_Info->bSpurAvoided = 1;
862         }
863
864         status |=
865             ((pAS_Info->
866               nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK);
867
868         return status;
869 }
870
871 /*
872  * Constants used by the tuning algorithm
873  */
874 #define MT2063_REF_FREQ          (16000000UL)   /* Reference oscillator Frequency (in Hz) */
875 #define MT2063_IF1_BW            (22000000UL)   /* The IF1 filter bandwidth (in Hz) */
876 #define MT2063_TUNE_STEP_SIZE       (50000UL)   /* Tune in steps of 50 kHz */
877 #define MT2063_SPUR_STEP_HZ        (250000UL)   /* Step size (in Hz) to move IF1 when avoiding spurs */
878 #define MT2063_ZIF_BW             (2000000UL)   /* Zero-IF spur-free bandwidth (in Hz) */
879 #define MT2063_MAX_HARMONICS_1         (15UL)   /* Highest intra-tuner LO Spur Harmonic to be avoided */
880 #define MT2063_MAX_HARMONICS_2          (5UL)   /* Highest inter-tuner LO Spur Harmonic to be avoided */
881 #define MT2063_MIN_LO_SEP         (1000000UL)   /* Minimum inter-tuner LO frequency separation */
882 #define MT2063_LO1_FRACN_AVOID          (0UL)   /* LO1 FracN numerator avoid region (in Hz) */
883 #define MT2063_LO2_FRACN_AVOID     (199999UL)   /* LO2 FracN numerator avoid region (in Hz) */
884 #define MT2063_MIN_FIN_FREQ      (44000000UL)   /* Minimum input frequency (in Hz) */
885 #define MT2063_MAX_FIN_FREQ    (1100000000UL)   /* Maximum input frequency (in Hz) */
886 #define MT2063_MIN_FOUT_FREQ     (36000000UL)   /* Minimum output frequency (in Hz) */
887 #define MT2063_MAX_FOUT_FREQ     (57000000UL)   /* Maximum output frequency (in Hz) */
888 #define MT2063_MIN_DNC_FREQ    (1293000000UL)   /* Minimum LO2 frequency (in Hz) */
889 #define MT2063_MAX_DNC_FREQ    (1614000000UL)   /* Maximum LO2 frequency (in Hz) */
890 #define MT2063_MIN_UPC_FREQ    (1396000000UL)   /* Minimum LO1 frequency (in Hz) */
891 #define MT2063_MAX_UPC_FREQ    (2750000000UL)   /* Maximum LO1 frequency (in Hz) */
892
893 /*
894  *  Define the supported Part/Rev codes for the MT2063
895  */
896 #define MT2063_B0       (0x9B)
897 #define MT2063_B1       (0x9C)
898 #define MT2063_B2       (0x9D)
899 #define MT2063_B3       (0x9E)
900
901 /**
902  * mt2063_lockStatus - Checks to see if LO1 and LO2 are locked
903  *
904  * @state:      struct mt2063_state pointer
905  *
906  * This function returns 0, if no lock, 1 if locked and a value < 1 if error
907  */
908 static int mt2063_lockStatus(struct mt2063_state *state)
909 {
910         const u32 nMaxWait = 100;       /*  wait a maximum of 100 msec   */
911         const u32 nPollRate = 2;        /*  poll status bits every 2 ms */
912         const u32 nMaxLoops = nMaxWait / nPollRate;
913         const u8 LO1LK = 0x80;
914         u8 LO2LK = 0x08;
915         int status;
916         u32 nDelays = 0;
917
918         dprintk(2, "\n");
919
920         /*  LO2 Lock bit was in a different place for B0 version  */
921         if (state->tuner_id == MT2063_B0)
922                 LO2LK = 0x40;
923
924         do {
925                 status = mt2063_read(state, MT2063_REG_LO_STATUS,
926                                      &state->reg[MT2063_REG_LO_STATUS], 1);
927
928                 if (status < 0)
929                         return status;
930
931                 if ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) ==
932                     (LO1LK | LO2LK)) {
933                         return TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO;
934                 }
935                 msleep(nPollRate);      /*  Wait between retries  */
936         } while (++nDelays < nMaxLoops);
937
938         /*
939          * Got no lock or partial lock
940          */
941         return 0;
942 }
943
944 /*
945  *  Constants for setting receiver modes.
946  *  (6 modes defined at this time, enumerated by mt2063_delivery_sys)
947  *  (DNC1GC & DNC2GC are the values, which are used, when the specific
948  *   DNC Output is selected, the other is always off)
949  *
950  *                enum mt2063_delivery_sys
951  * -------------+----------------------------------------------
952  * Mode 0 :     | MT2063_CABLE_QAM
953  * Mode 1 :     | MT2063_CABLE_ANALOG
954  * Mode 2 :     | MT2063_OFFAIR_COFDM
955  * Mode 3 :     | MT2063_OFFAIR_COFDM_SAWLESS
956  * Mode 4 :     | MT2063_OFFAIR_ANALOG
957  * Mode 5 :     | MT2063_OFFAIR_8VSB
958  * --------------+----------------------------------------------
959  *
960  *                |<----------   Mode  -------------->|
961  *    Reg Field   |  0  |  1  |  2  |  3  |  4  |  5  |
962  *    ------------+-----+-----+-----+-----+-----+-----+
963  *    RFAGCen     | OFF | OFF | OFF | OFF | OFF | OFF
964  *    LNARin      |   0 |   0 |   3 |   3 |  3  |  3
965  *    FIFFQen     |   1 |   1 |   1 |   1 |  1  |  1
966  *    FIFFq       |   0 |   0 |   0 |   0 |  0  |  0
967  *    DNC1gc      |   0 |   0 |   0 |   0 |  0  |  0
968  *    DNC2gc      |   0 |   0 |   0 |   0 |  0  |  0
969  *    GCU Auto    |   1 |   1 |   1 |   1 |  1  |  1
970  *    LNA max Atn |  31 |  31 |  31 |  31 | 31  | 31
971  *    LNA Target  |  44 |  43 |  43 |  43 | 43  | 43
972  *    ign  RF Ovl |   0 |   0 |   0 |   0 |  0  |  0
973  *    RF  max Atn |  31 |  31 |  31 |  31 | 31  | 31
974  *    PD1 Target  |  36 |  36 |  38 |  38 | 36  | 38
975  *    ign FIF Ovl |   0 |   0 |   0 |   0 |  0  |  0
976  *    FIF max Atn |   5 |   5 |   5 |   5 |  5  |  5
977  *    PD2 Target  |  40 |  33 |  42 |  42 | 33  | 42
978  */
979
980 enum mt2063_delivery_sys {
981         MT2063_CABLE_QAM = 0,
982         MT2063_CABLE_ANALOG,
983         MT2063_OFFAIR_COFDM,
984         MT2063_OFFAIR_COFDM_SAWLESS,
985         MT2063_OFFAIR_ANALOG,
986         MT2063_OFFAIR_8VSB,
987         MT2063_NUM_RCVR_MODES
988 };
989
990 static const char *mt2063_mode_name[] = {
991         [MT2063_CABLE_QAM]              = "digital cable",
992         [MT2063_CABLE_ANALOG]           = "analog cable",
993         [MT2063_OFFAIR_COFDM]           = "digital offair",
994         [MT2063_OFFAIR_COFDM_SAWLESS]   = "digital offair without SAW",
995         [MT2063_OFFAIR_ANALOG]          = "analog offair",
996         [MT2063_OFFAIR_8VSB]            = "analog offair 8vsb",
997 };
998
999 static const u8 RFAGCEN[]       = {  0,  0,  0,  0,  0,  0 };
1000 static const u8 LNARIN[]        = {  0,  0,  3,  3,  3,  3 };
1001 static const u8 FIFFQEN[]       = {  1,  1,  1,  1,  1,  1 };
1002 static const u8 FIFFQ[]         = {  0,  0,  0,  0,  0,  0 };
1003 static const u8 DNC1GC[]        = {  0,  0,  0,  0,  0,  0 };
1004 static const u8 DNC2GC[]        = {  0,  0,  0,  0,  0,  0 };
1005 static const u8 ACLNAMAX[]      = { 31, 31, 31, 31, 31, 31 };
1006 static const u8 LNATGT[]        = { 44, 43, 43, 43, 43, 43 };
1007 static const u8 RFOVDIS[]       = {  0,  0,  0,  0,  0,  0 };
1008 static const u8 ACRFMAX[]       = { 31, 31, 31, 31, 31, 31 };
1009 static const u8 PD1TGT[]        = { 36, 36, 38, 38, 36, 38 };
1010 static const u8 FIFOVDIS[]      = {  0,  0,  0,  0,  0,  0 };
1011 static const u8 ACFIFMAX[]      = { 29, 29, 29, 29, 29, 29 };
1012 static const u8 PD2TGT[]        = { 40, 33, 38, 42, 30, 38 };
1013
1014 /*
1015  * mt2063_set_dnc_output_enable()
1016  */
1017 static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
1018                                         enum MT2063_DNC_Output_Enable *pValue)
1019 {
1020         dprintk(2, "\n");
1021
1022         if ((state->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) { /* if DNC1 is off */
1023                 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)   /* if DNC2 is off */
1024                         *pValue = MT2063_DNC_NONE;
1025                 else
1026                         *pValue = MT2063_DNC_2;
1027         } else {        /* DNC1 is on */
1028                 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)   /* if DNC2 is off */
1029                         *pValue = MT2063_DNC_1;
1030                 else
1031                         *pValue = MT2063_DNC_BOTH;
1032         }
1033         return 0;
1034 }
1035
1036 /*
1037  * mt2063_set_dnc_output_enable()
1038  */
1039 static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
1040                                         enum MT2063_DNC_Output_Enable nValue)
1041 {
1042         int status = 0; /* Status to be returned        */
1043         u8 val = 0;
1044
1045         dprintk(2, "\n");
1046
1047         /* selects, which DNC output is used */
1048         switch (nValue) {
1049         case MT2063_DNC_NONE:
1050                 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;  /* Set DNC1GC=3 */
1051                 if (state->reg[MT2063_REG_DNC_GAIN] !=
1052                     val)
1053                         status |=
1054                             mt2063_setreg(state,
1055                                           MT2063_REG_DNC_GAIN,
1056                                           val);
1057
1058                 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;  /* Set DNC2GC=3 */
1059                 if (state->reg[MT2063_REG_VGA_GAIN] !=
1060                     val)
1061                         status |=
1062                             mt2063_setreg(state,
1063                                           MT2063_REG_VGA_GAIN,
1064                                           val);
1065
1066                 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
1067                 if (state->reg[MT2063_REG_RSVD_20] !=
1068                     val)
1069                         status |=
1070                             mt2063_setreg(state,
1071                                           MT2063_REG_RSVD_20,
1072                                           val);
1073
1074                 break;
1075         case MT2063_DNC_1:
1076                 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);     /* Set DNC1GC=x */
1077                 if (state->reg[MT2063_REG_DNC_GAIN] !=
1078                     val)
1079                         status |=
1080                             mt2063_setreg(state,
1081                                           MT2063_REG_DNC_GAIN,
1082                                           val);
1083
1084                 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;  /* Set DNC2GC=3 */
1085                 if (state->reg[MT2063_REG_VGA_GAIN] !=
1086                     val)
1087                         status |=
1088                             mt2063_setreg(state,
1089                                           MT2063_REG_VGA_GAIN,
1090                                           val);
1091
1092                 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
1093                 if (state->reg[MT2063_REG_RSVD_20] !=
1094                     val)
1095                         status |=
1096                             mt2063_setreg(state,
1097                                           MT2063_REG_RSVD_20,
1098                                           val);
1099
1100                 break;
1101         case MT2063_DNC_2:
1102                 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;  /* Set DNC1GC=3 */
1103                 if (state->reg[MT2063_REG_DNC_GAIN] !=
1104                     val)
1105                         status |=
1106                             mt2063_setreg(state,
1107                                           MT2063_REG_DNC_GAIN,
1108                                           val);
1109
1110                 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);     /* Set DNC2GC=x */
1111                 if (state->reg[MT2063_REG_VGA_GAIN] !=
1112                     val)
1113                         status |=
1114                             mt2063_setreg(state,
1115                                           MT2063_REG_VGA_GAIN,
1116                                           val);
1117
1118                 val = (state->reg[MT2063_REG_RSVD_20] | 0x40);  /* Set PD2MUX=1 */
1119                 if (state->reg[MT2063_REG_RSVD_20] !=
1120                     val)
1121                         status |=
1122                             mt2063_setreg(state,
1123                                           MT2063_REG_RSVD_20,
1124                                           val);
1125
1126                 break;
1127         case MT2063_DNC_BOTH:
1128                 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);     /* Set DNC1GC=x */
1129                 if (state->reg[MT2063_REG_DNC_GAIN] !=
1130                     val)
1131                         status |=
1132                             mt2063_setreg(state,
1133                                           MT2063_REG_DNC_GAIN,
1134                                           val);
1135
1136                 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);     /* Set DNC2GC=x */
1137                 if (state->reg[MT2063_REG_VGA_GAIN] !=
1138                     val)
1139                         status |=
1140                             mt2063_setreg(state,
1141                                           MT2063_REG_VGA_GAIN,
1142                                           val);
1143
1144                 val = (state->reg[MT2063_REG_RSVD_20] | 0x40);  /* Set PD2MUX=1 */
1145                 if (state->reg[MT2063_REG_RSVD_20] !=
1146                     val)
1147                         status |=
1148                             mt2063_setreg(state,
1149                                           MT2063_REG_RSVD_20,
1150                                           val);
1151
1152                 break;
1153         default:
1154                 break;
1155         }
1156
1157         return status;
1158 }
1159
1160 /*
1161  * MT2063_SetReceiverMode() - Set the MT2063 receiver mode, according with
1162  *                            the selected enum mt2063_delivery_sys type.
1163  *
1164  *  (DNC1GC & DNC2GC are the values, which are used, when the specific
1165  *   DNC Output is selected, the other is always off)
1166  *
1167  * @state:      ptr to mt2063_state structure
1168  * @Mode:       desired receiver delivery system
1169  *
1170  * Note: Register cache must be valid for it to work
1171  */
1172
1173 static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
1174                                   enum mt2063_delivery_sys Mode)
1175 {
1176         int status = 0; /* Status to be returned        */
1177         u8 val;
1178         u32 longval;
1179
1180         dprintk(2, "\n");
1181
1182         if (Mode >= MT2063_NUM_RCVR_MODES)
1183                 status = -ERANGE;
1184
1185         /* RFAGCen */
1186         if (status >= 0) {
1187                 val =
1188                     (state->
1189                      reg[MT2063_REG_PD1_TGT] & ~0x40) | (RFAGCEN[Mode]
1190                                                                    ? 0x40 :
1191                                                                    0x00);
1192                 if (state->reg[MT2063_REG_PD1_TGT] != val)
1193                         status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1194         }
1195
1196         /* LNARin */
1197         if (status >= 0) {
1198                 u8 val = (state->reg[MT2063_REG_CTRL_2C] & ~0x03) |
1199                          (LNARIN[Mode] & 0x03);
1200                 if (state->reg[MT2063_REG_CTRL_2C] != val)
1201                         status |= mt2063_setreg(state, MT2063_REG_CTRL_2C, val);
1202         }
1203
1204         /* FIFFQEN and FIFFQ */
1205         if (status >= 0) {
1206                 val =
1207                     (state->
1208                      reg[MT2063_REG_FIFF_CTRL2] & ~0xF0) |
1209                     (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
1210                 if (state->reg[MT2063_REG_FIFF_CTRL2] != val) {
1211                         status |=
1212                             mt2063_setreg(state, MT2063_REG_FIFF_CTRL2, val);
1213                         /* trigger FIFF calibration, needed after changing FIFFQ */
1214                         val =
1215                             (state->reg[MT2063_REG_FIFF_CTRL] | 0x01);
1216                         status |=
1217                             mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1218                         val =
1219                             (state->
1220                              reg[MT2063_REG_FIFF_CTRL] & ~0x01);
1221                         status |=
1222                             mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1223                 }
1224         }
1225
1226         /* DNC1GC & DNC2GC */
1227         status |= mt2063_get_dnc_output_enable(state, &longval);
1228         status |= mt2063_set_dnc_output_enable(state, longval);
1229
1230         /* acLNAmax */
1231         if (status >= 0) {
1232                 u8 val = (state->reg[MT2063_REG_LNA_OV] & ~0x1F) |
1233                          (ACLNAMAX[Mode] & 0x1F);
1234                 if (state->reg[MT2063_REG_LNA_OV] != val)
1235                         status |= mt2063_setreg(state, MT2063_REG_LNA_OV, val);
1236         }
1237
1238         /* LNATGT */
1239         if (status >= 0) {
1240                 u8 val = (state->reg[MT2063_REG_LNA_TGT] & ~0x3F) |
1241                          (LNATGT[Mode] & 0x3F);
1242                 if (state->reg[MT2063_REG_LNA_TGT] != val)
1243                         status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1244         }
1245
1246         /* ACRF */
1247         if (status >= 0) {
1248                 u8 val = (state->reg[MT2063_REG_RF_OV] & ~0x1F) |
1249                          (ACRFMAX[Mode] & 0x1F);
1250                 if (state->reg[MT2063_REG_RF_OV] != val)
1251                         status |= mt2063_setreg(state, MT2063_REG_RF_OV, val);
1252         }
1253
1254         /* PD1TGT */
1255         if (status >= 0) {
1256                 u8 val = (state->reg[MT2063_REG_PD1_TGT] & ~0x3F) |
1257                          (PD1TGT[Mode] & 0x3F);
1258                 if (state->reg[MT2063_REG_PD1_TGT] != val)
1259                         status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1260         }
1261
1262         /* FIFATN */
1263         if (status >= 0) {
1264                 u8 val = ACFIFMAX[Mode];
1265                 if (state->reg[MT2063_REG_PART_REV] != MT2063_B3 && val > 5)
1266                         val = 5;
1267                 val = (state->reg[MT2063_REG_FIF_OV] & ~0x1F) |
1268                       (val & 0x1F);
1269                 if (state->reg[MT2063_REG_FIF_OV] != val)
1270                         status |= mt2063_setreg(state, MT2063_REG_FIF_OV, val);
1271         }
1272
1273         /* PD2TGT */
1274         if (status >= 0) {
1275                 u8 val = (state->reg[MT2063_REG_PD2_TGT] & ~0x3F) |
1276                     (PD2TGT[Mode] & 0x3F);
1277                 if (state->reg[MT2063_REG_PD2_TGT] != val)
1278                         status |= mt2063_setreg(state, MT2063_REG_PD2_TGT, val);
1279         }
1280
1281         /* Ignore ATN Overload */
1282         if (status >= 0) {
1283                 val = (state->reg[MT2063_REG_LNA_TGT] & ~0x80) |
1284                       (RFOVDIS[Mode] ? 0x80 : 0x00);
1285                 if (state->reg[MT2063_REG_LNA_TGT] != val)
1286                         status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1287         }
1288
1289         /* Ignore FIF Overload */
1290         if (status >= 0) {
1291                 val = (state->reg[MT2063_REG_PD1_TGT] & ~0x80) |
1292                       (FIFOVDIS[Mode] ? 0x80 : 0x00);
1293                 if (state->reg[MT2063_REG_PD1_TGT] != val)
1294                         status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1295         }
1296
1297         if (status >= 0) {
1298                 state->rcvr_mode = Mode;
1299                 dprintk(1, "mt2063 mode changed to %s\n",
1300                         mt2063_mode_name[state->rcvr_mode]);
1301         }
1302
1303         return status;
1304 }
1305
1306 /*
1307  * MT2063_ClearPowerMaskBits () - Clears the power-down mask bits for various
1308  *                                sections of the MT2063
1309  *
1310  * @Bits:               Mask bits to be cleared.
1311  *
1312  * See definition of MT2063_Mask_Bits type for description
1313  * of each of the power bits.
1314  */
1315 static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
1316                                      enum MT2063_Mask_Bits Bits)
1317 {
1318         int status = 0;
1319
1320         dprintk(2, "\n");
1321         Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD);   /* Only valid bits for this tuner */
1322         if ((Bits & 0xFF00) != 0) {
1323                 state->reg[MT2063_REG_PWR_2] &= ~(u8) (Bits >> 8);
1324                 status |=
1325                     mt2063_write(state,
1326                                     MT2063_REG_PWR_2,
1327                                     &state->reg[MT2063_REG_PWR_2], 1);
1328         }
1329         if ((Bits & 0xFF) != 0) {
1330                 state->reg[MT2063_REG_PWR_1] &= ~(u8) (Bits & 0xFF);
1331                 status |=
1332                     mt2063_write(state,
1333                                     MT2063_REG_PWR_1,
1334                                     &state->reg[MT2063_REG_PWR_1], 1);
1335         }
1336
1337         return status;
1338 }
1339
1340 /*
1341  * MT2063_SoftwareShutdown() - Enables or disables software shutdown function.
1342  *                             When Shutdown is 1, any section whose power
1343  *                             mask is set will be shutdown.
1344  */
1345 static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
1346 {
1347         int status;
1348
1349         dprintk(2, "\n");
1350         if (Shutdown == 1)
1351                 state->reg[MT2063_REG_PWR_1] |= 0x04;
1352         else
1353                 state->reg[MT2063_REG_PWR_1] &= ~0x04;
1354
1355         status = mt2063_write(state,
1356                             MT2063_REG_PWR_1,
1357                             &state->reg[MT2063_REG_PWR_1], 1);
1358
1359         if (Shutdown != 1) {
1360                 state->reg[MT2063_REG_BYP_CTRL] =
1361                     (state->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
1362                 status |=
1363                     mt2063_write(state,
1364                                     MT2063_REG_BYP_CTRL,
1365                                     &state->reg[MT2063_REG_BYP_CTRL],
1366                                     1);
1367                 state->reg[MT2063_REG_BYP_CTRL] =
1368                     (state->reg[MT2063_REG_BYP_CTRL] & 0x9F);
1369                 status |=
1370                     mt2063_write(state,
1371                                     MT2063_REG_BYP_CTRL,
1372                                     &state->reg[MT2063_REG_BYP_CTRL],
1373                                     1);
1374         }
1375
1376         return status;
1377 }
1378
1379 static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
1380 {
1381         return f_ref * (f_LO / f_ref)
1382             + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
1383 }
1384
1385 /**
1386  * fLO_FractionalTerm() - Calculates the portion contributed by FracN / denom.
1387  *                        This function preserves maximum precision without
1388  *                        risk of overflow.  It accurately calculates
1389  *                        f_ref * num / denom to within 1 HZ with fixed math.
1390  *
1391  * @f_ref:      SRO frequency.
1392  * @num:        Fractional portion of the multiplier
1393  * @denom:      denominator portion of the ratio
1394  *
1395  * This calculation handles f_ref as two separate 14-bit fields.
1396  * Therefore, a maximum value of 2^28-1 may safely be used for f_ref.
1397  * This is the genesis of the magic number "14" and the magic mask value of
1398  * 0x03FFF.
1399  *
1400  * This routine successfully handles denom values up to and including 2^18.
1401  *  Returns:        f_ref * num / denom
1402  */
1403 static u32 MT2063_fLO_FractionalTerm(u32 f_ref, u32 num, u32 denom)
1404 {
1405         u32 t1 = (f_ref >> 14) * num;
1406         u32 term1 = t1 / denom;
1407         u32 loss = t1 % denom;
1408         u32 term2 =
1409             (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
1410         return (term1 << 14) + term2;
1411 }
1412
1413 /*
1414  * CalcLO1Mult()- Calculates Integer divider value and the numerator
1415  *                value for a FracN PLL.
1416  *
1417  *                This function assumes that the f_LO and f_Ref are
1418  *                evenly divisible by f_LO_Step.
1419  *
1420  * @Div:        OUTPUT: Whole number portion of the multiplier
1421  * @FracN:      OUTPUT: Fractional portion of the multiplier
1422  * @f_LO:       desired LO frequency.
1423  * @f_LO_Step:  Minimum step size for the LO (in Hz).
1424  * @f_Ref:      SRO frequency.
1425  * @f_Avoid:    Range of PLL frequencies to avoid near integer multiples
1426  *              of f_Ref (in Hz).
1427  *
1428  * Returns:        Recalculated LO frequency.
1429  */
1430 static u32 MT2063_CalcLO1Mult(u32 *Div,
1431                               u32 *FracN,
1432                               u32 f_LO,
1433                               u32 f_LO_Step, u32 f_Ref)
1434 {
1435         /*  Calculate the whole number portion of the divider */
1436         *Div = f_LO / f_Ref;
1437
1438         /*  Calculate the numerator value (round to nearest f_LO_Step) */
1439         *FracN =
1440             (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1441              (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1442
1443         return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
1444 }
1445
1446 /**
1447  * CalcLO2Mult() - Calculates Integer divider value and the numerator
1448  *                 value for a FracN PLL.
1449  *
1450  *                  This function assumes that the f_LO and f_Ref are
1451  *                  evenly divisible by f_LO_Step.
1452  *
1453  * @Div:        OUTPUT: Whole number portion of the multiplier
1454  * @FracN:      OUTPUT: Fractional portion of the multiplier
1455  * @f_LO:       desired LO frequency.
1456  * @f_LO_Step:  Minimum step size for the LO (in Hz).
1457  * @f_Ref:      SRO frequency.
1458  *
1459  * Returns: Recalculated LO frequency.
1460  */
1461 static u32 MT2063_CalcLO2Mult(u32 *Div,
1462                               u32 *FracN,
1463                               u32 f_LO,
1464                               u32 f_LO_Step, u32 f_Ref)
1465 {
1466         /*  Calculate the whole number portion of the divider */
1467         *Div = f_LO / f_Ref;
1468
1469         /*  Calculate the numerator value (round to nearest f_LO_Step) */
1470         *FracN =
1471             (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1472              (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1473
1474         return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
1475                                                             8191);
1476 }
1477
1478 /*
1479  * FindClearTuneFilter() - Calculate the corrrect ClearTune filter to be
1480  *                         used for a given input frequency.
1481  *
1482  * @state:      ptr to tuner data structure
1483  * @f_in:       RF input center frequency (in Hz).
1484  *
1485  * Returns: ClearTune filter number (0-31)
1486  */
1487 static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
1488 {
1489         u32 RFBand;
1490         u32 idx;                /*  index loop                      */
1491
1492         /*
1493          **  Find RF Band setting
1494          */
1495         RFBand = 31;            /*  def when f_in > all    */
1496         for (idx = 0; idx < 31; ++idx) {
1497                 if (state->CTFiltMax[idx] >= f_in) {
1498                         RFBand = idx;
1499                         break;
1500                 }
1501         }
1502         return RFBand;
1503 }
1504
1505 /*
1506  * MT2063_Tune() - Change the tuner's tuned frequency to RFin.
1507  */
1508 static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
1509 {                               /* RF input center frequency   */
1510
1511         int status = 0;
1512         u32 LO1;                /*  1st LO register value           */
1513         u32 Num1;               /*  Numerator for LO1 reg. value    */
1514         u32 f_IF1;              /*  1st IF requested                */
1515         u32 LO2;                /*  2nd LO register value           */
1516         u32 Num2;               /*  Numerator for LO2 reg. value    */
1517         u32 ofLO1, ofLO2;       /*  last time's LO frequencies      */
1518         u8 fiffc = 0x80;        /*  FIFF center freq from tuner     */
1519         u32 fiffof;             /*  Offset from FIFF center freq    */
1520         const u8 LO1LK = 0x80;  /*  Mask for LO1 Lock bit           */
1521         u8 LO2LK = 0x08;        /*  Mask for LO2 Lock bit           */
1522         u8 val;
1523         u32 RFBand;
1524
1525         dprintk(2, "\n");
1526         /*  Check the input and output frequency ranges                   */
1527         if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
1528                 return -EINVAL;
1529
1530         if ((state->AS_Data.f_out < MT2063_MIN_FOUT_FREQ)
1531             || (state->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
1532                 return -EINVAL;
1533
1534         /*
1535          * Save original LO1 and LO2 register values
1536          */
1537         ofLO1 = state->AS_Data.f_LO1;
1538         ofLO2 = state->AS_Data.f_LO2;
1539
1540         /*
1541          * Find and set RF Band setting
1542          */
1543         if (state->ctfilt_sw == 1) {
1544                 val = (state->reg[MT2063_REG_CTUNE_CTRL] | 0x08);
1545                 if (state->reg[MT2063_REG_CTUNE_CTRL] != val) {
1546                         status |=
1547                             mt2063_setreg(state, MT2063_REG_CTUNE_CTRL, val);
1548                 }
1549                 val = state->reg[MT2063_REG_CTUNE_OV];
1550                 RFBand = FindClearTuneFilter(state, f_in);
1551                 state->reg[MT2063_REG_CTUNE_OV] =
1552                     (u8) ((state->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
1553                               | RFBand);
1554                 if (state->reg[MT2063_REG_CTUNE_OV] != val) {
1555                         status |=
1556                             mt2063_setreg(state, MT2063_REG_CTUNE_OV, val);
1557                 }
1558         }
1559
1560         /*
1561          * Read the FIFF Center Frequency from the tuner
1562          */
1563         if (status >= 0) {
1564                 status |=
1565                     mt2063_read(state,
1566                                    MT2063_REG_FIFFC,
1567                                    &state->reg[MT2063_REG_FIFFC], 1);
1568                 fiffc = state->reg[MT2063_REG_FIFFC];
1569         }
1570         /*
1571          * Assign in the requested values
1572          */
1573         state->AS_Data.f_in = f_in;
1574         /*  Request a 1st IF such that LO1 is on a step size */
1575         state->AS_Data.f_if1_Request =
1576             MT2063_Round_fLO(state->AS_Data.f_if1_Request + f_in,
1577                              state->AS_Data.f_LO1_Step,
1578                              state->AS_Data.f_ref) - f_in;
1579
1580         /*
1581          * Calculate frequency settings.  f_IF1_FREQ + f_in is the
1582          * desired LO1 frequency
1583          */
1584         MT2063_ResetExclZones(&state->AS_Data);
1585
1586         f_IF1 = MT2063_ChooseFirstIF(&state->AS_Data);
1587
1588         state->AS_Data.f_LO1 =
1589             MT2063_Round_fLO(f_IF1 + f_in, state->AS_Data.f_LO1_Step,
1590                              state->AS_Data.f_ref);
1591
1592         state->AS_Data.f_LO2 =
1593             MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1594                              state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1595
1596         /*
1597          * Check for any LO spurs in the output bandwidth and adjust
1598          * the LO settings to avoid them if needed
1599          */
1600         status |= MT2063_AvoidSpurs(&state->AS_Data);
1601         /*
1602          * MT_AvoidSpurs spurs may have changed the LO1 & LO2 values.
1603          * Recalculate the LO frequencies and the values to be placed
1604          * in the tuning registers.
1605          */
1606         state->AS_Data.f_LO1 =
1607             MT2063_CalcLO1Mult(&LO1, &Num1, state->AS_Data.f_LO1,
1608                                state->AS_Data.f_LO1_Step, state->AS_Data.f_ref);
1609         state->AS_Data.f_LO2 =
1610             MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1611                              state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1612         state->AS_Data.f_LO2 =
1613             MT2063_CalcLO2Mult(&LO2, &Num2, state->AS_Data.f_LO2,
1614                                state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1615
1616         /*
1617          *  Check the upconverter and downconverter frequency ranges
1618          */
1619         if ((state->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ)
1620             || (state->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
1621                 status |= MT2063_UPC_RANGE;
1622         if ((state->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ)
1623             || (state->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
1624                 status |= MT2063_DNC_RANGE;
1625         /*  LO2 Lock bit was in a different place for B0 version  */
1626         if (state->tuner_id == MT2063_B0)
1627                 LO2LK = 0x40;
1628
1629         /*
1630          *  If we have the same LO frequencies and we're already locked,
1631          *  then skip re-programming the LO registers.
1632          */
1633         if ((ofLO1 != state->AS_Data.f_LO1)
1634             || (ofLO2 != state->AS_Data.f_LO2)
1635             || ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) !=
1636                 (LO1LK | LO2LK))) {
1637                 /*
1638                  * Calculate the FIFFOF register value
1639                  *
1640                  *           IF1_Actual
1641                  * FIFFOF = ------------ - 8 * FIFFC - 4992
1642                  *            f_ref/64
1643                  */
1644                 fiffof =
1645                     (state->AS_Data.f_LO1 -
1646                      f_in) / (state->AS_Data.f_ref / 64) - 8 * (u32) fiffc -
1647                     4992;
1648                 if (fiffof > 0xFF)
1649                         fiffof = 0xFF;
1650
1651                 /*
1652                  * Place all of the calculated values into the local tuner
1653                  * register fields.
1654                  */
1655                 if (status >= 0) {
1656                         state->reg[MT2063_REG_LO1CQ_1] = (u8) (LO1 & 0xFF);     /* DIV1q */
1657                         state->reg[MT2063_REG_LO1CQ_2] = (u8) (Num1 & 0x3F);    /* NUM1q */
1658                         state->reg[MT2063_REG_LO2CQ_1] = (u8) (((LO2 & 0x7F) << 1)      /* DIV2q */
1659                                                                    |(Num2 >> 12));      /* NUM2q (hi) */
1660                         state->reg[MT2063_REG_LO2CQ_2] = (u8) ((Num2 & 0x0FF0) >> 4);   /* NUM2q (mid) */
1661                         state->reg[MT2063_REG_LO2CQ_3] = (u8) (0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */
1662
1663                         /*
1664                          * Now write out the computed register values
1665                          * IMPORTANT: There is a required order for writing
1666                          *            (0x05 must follow all the others).
1667                          */
1668                         status |= mt2063_write(state, MT2063_REG_LO1CQ_1, &state->reg[MT2063_REG_LO1CQ_1], 5);  /* 0x01 - 0x05 */
1669                         if (state->tuner_id == MT2063_B0) {
1670                                 /* Re-write the one-shot bits to trigger the tune operation */
1671                                 status |= mt2063_write(state, MT2063_REG_LO2CQ_3, &state->reg[MT2063_REG_LO2CQ_3], 1);  /* 0x05 */
1672                         }
1673                         /* Write out the FIFF offset only if it's changing */
1674                         if (state->reg[MT2063_REG_FIFF_OFFSET] !=
1675                             (u8) fiffof) {
1676                                 state->reg[MT2063_REG_FIFF_OFFSET] =
1677                                     (u8) fiffof;
1678                                 status |=
1679                                     mt2063_write(state,
1680                                                     MT2063_REG_FIFF_OFFSET,
1681                                                     &state->
1682                                                     reg[MT2063_REG_FIFF_OFFSET],
1683                                                     1);
1684                         }
1685                 }
1686
1687                 /*
1688                  * Check for LO's locking
1689                  */
1690
1691                 if (status < 0)
1692                         return status;
1693
1694                 status = mt2063_lockStatus(state);
1695                 if (status < 0)
1696                         return status;
1697                 if (!status)
1698                         return -EINVAL;         /* Couldn't lock */
1699
1700                 /*
1701                  * If we locked OK, assign calculated data to mt2063_state structure
1702                  */
1703                 state->f_IF1_actual = state->AS_Data.f_LO1 - f_in;
1704         }
1705
1706         return status;
1707 }
1708
1709 static const u8 MT2063B0_defaults[] = {
1710         /* Reg,  Value */
1711         0x19, 0x05,
1712         0x1B, 0x1D,
1713         0x1C, 0x1F,
1714         0x1D, 0x0F,
1715         0x1E, 0x3F,
1716         0x1F, 0x0F,
1717         0x20, 0x3F,
1718         0x22, 0x21,
1719         0x23, 0x3F,
1720         0x24, 0x20,
1721         0x25, 0x3F,
1722         0x27, 0xEE,
1723         0x2C, 0x27,     /*  bit at 0x20 is cleared below  */
1724         0x30, 0x03,
1725         0x2C, 0x07,     /*  bit at 0x20 is cleared here   */
1726         0x2D, 0x87,
1727         0x2E, 0xAA,
1728         0x28, 0xE1,     /*  Set the FIFCrst bit here      */
1729         0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
1730         0x00
1731 };
1732
1733 /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
1734 static const u8 MT2063B1_defaults[] = {
1735         /* Reg,  Value */
1736         0x05, 0xF0,
1737         0x11, 0x10,     /* New Enable AFCsd */
1738         0x19, 0x05,
1739         0x1A, 0x6C,
1740         0x1B, 0x24,
1741         0x1C, 0x28,
1742         0x1D, 0x8F,
1743         0x1E, 0x14,
1744         0x1F, 0x8F,
1745         0x20, 0x57,
1746         0x22, 0x21,     /* New - ver 1.03 */
1747         0x23, 0x3C,     /* New - ver 1.10 */
1748         0x24, 0x20,     /* New - ver 1.03 */
1749         0x2C, 0x24,     /*  bit at 0x20 is cleared below  */
1750         0x2D, 0x87,     /*  FIFFQ=0  */
1751         0x2F, 0xF3,
1752         0x30, 0x0C,     /* New - ver 1.11 */
1753         0x31, 0x1B,     /* New - ver 1.11 */
1754         0x2C, 0x04,     /*  bit at 0x20 is cleared here  */
1755         0x28, 0xE1,     /*  Set the FIFCrst bit here      */
1756         0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
1757         0x00
1758 };
1759
1760 /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
1761 static const u8 MT2063B3_defaults[] = {
1762         /* Reg,  Value */
1763         0x05, 0xF0,
1764         0x19, 0x3D,
1765         0x2C, 0x24,     /*  bit at 0x20 is cleared below  */
1766         0x2C, 0x04,     /*  bit at 0x20 is cleared here  */
1767         0x28, 0xE1,     /*  Set the FIFCrst bit here      */
1768         0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
1769         0x00
1770 };
1771
1772 static int mt2063_init(struct dvb_frontend *fe)
1773 {
1774         int status;
1775         struct mt2063_state *state = fe->tuner_priv;
1776         u8 all_resets = 0xF0;   /* reset/load bits */
1777         const u8 *def = NULL;
1778         char *step;
1779         u32 FCRUN;
1780         s32 maxReads;
1781         u32 fcu_osc;
1782         u32 i;
1783
1784         dprintk(2, "\n");
1785
1786         state->rcvr_mode = MT2063_CABLE_QAM;
1787
1788         /*  Read the Part/Rev code from the tuner */
1789         status = mt2063_read(state, MT2063_REG_PART_REV,
1790                              &state->reg[MT2063_REG_PART_REV], 1);
1791         if (status < 0) {
1792                 printk(KERN_ERR "Can't read mt2063 part ID\n");
1793                 return status;
1794         }
1795
1796         /* Check the part/rev code */
1797         switch (state->reg[MT2063_REG_PART_REV]) {
1798         case MT2063_B0:
1799                 step = "B0";
1800                 break;
1801         case MT2063_B1:
1802                 step = "B1";
1803                 break;
1804         case MT2063_B2:
1805                 step = "B2";
1806                 break;
1807         case MT2063_B3:
1808                 step = "B3";
1809                 break;
1810         default:
1811                 printk(KERN_ERR "mt2063: Unknown mt2063 device ID (0x%02x)\n",
1812                        state->reg[MT2063_REG_PART_REV]);
1813                 return -ENODEV; /*  Wrong tuner Part/Rev code */
1814         }
1815
1816         /*  Check the 2nd byte of the Part/Rev code from the tuner */
1817         status = mt2063_read(state, MT2063_REG_RSVD_3B,
1818                              &state->reg[MT2063_REG_RSVD_3B], 1);
1819
1820         /* b7 != 0 ==> NOT MT2063 */
1821         if (status < 0 || ((state->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) {
1822                 printk(KERN_ERR "mt2063: Unknown part ID (0x%02x%02x)\n",
1823                        state->reg[MT2063_REG_PART_REV],
1824                        state->reg[MT2063_REG_RSVD_3B]);
1825                 return -ENODEV; /*  Wrong tuner Part/Rev code */
1826         }
1827
1828         printk(KERN_INFO "mt2063: detected a mt2063 %s\n", step);
1829
1830         /*  Reset the tuner  */
1831         status = mt2063_write(state, MT2063_REG_LO2CQ_3, &all_resets, 1);
1832         if (status < 0)
1833                 return status;
1834
1835         /* change all of the default values that vary from the HW reset values */
1836         /*  def = (state->reg[PART_REV] == MT2063_B0) ? MT2063B0_defaults : MT2063B1_defaults; */
1837         switch (state->reg[MT2063_REG_PART_REV]) {
1838         case MT2063_B3:
1839                 def = MT2063B3_defaults;
1840                 break;
1841
1842         case MT2063_B1:
1843                 def = MT2063B1_defaults;
1844                 break;
1845
1846         case MT2063_B0:
1847                 def = MT2063B0_defaults;
1848                 break;
1849
1850         default:
1851                 return -ENODEV;
1852                 break;
1853         }
1854
1855         while (status >= 0 && *def) {
1856                 u8 reg = *def++;
1857                 u8 val = *def++;
1858                 status = mt2063_write(state, reg, &val, 1);
1859         }
1860         if (status < 0)
1861                 return status;
1862
1863         /*  Wait for FIFF location to complete.  */
1864         FCRUN = 1;
1865         maxReads = 10;
1866         while (status >= 0 && (FCRUN != 0) && (maxReads-- > 0)) {
1867                 msleep(2);
1868                 status = mt2063_read(state,
1869                                          MT2063_REG_XO_STATUS,
1870                                          &state->
1871                                          reg[MT2063_REG_XO_STATUS], 1);
1872                 FCRUN = (state->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
1873         }
1874
1875         if (FCRUN != 0 || status < 0)
1876                 return -ENODEV;
1877
1878         status = mt2063_read(state,
1879                            MT2063_REG_FIFFC,
1880                            &state->reg[MT2063_REG_FIFFC], 1);
1881         if (status < 0)
1882                 return status;
1883
1884         /* Read back all the registers from the tuner */
1885         status = mt2063_read(state,
1886                                 MT2063_REG_PART_REV,
1887                                 state->reg, MT2063_REG_END_REGS);
1888         if (status < 0)
1889                 return status;
1890
1891         /*  Initialize the tuner state.  */
1892         state->tuner_id = state->reg[MT2063_REG_PART_REV];
1893         state->AS_Data.f_ref = MT2063_REF_FREQ;
1894         state->AS_Data.f_if1_Center = (state->AS_Data.f_ref / 8) *
1895                                       ((u32) state->reg[MT2063_REG_FIFFC] + 640);
1896         state->AS_Data.f_if1_bw = MT2063_IF1_BW;
1897         state->AS_Data.f_out = 43750000UL;
1898         state->AS_Data.f_out_bw = 6750000UL;
1899         state->AS_Data.f_zif_bw = MT2063_ZIF_BW;
1900         state->AS_Data.f_LO1_Step = state->AS_Data.f_ref / 64;
1901         state->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
1902         state->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
1903         state->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
1904         state->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
1905         state->AS_Data.f_if1_Request = state->AS_Data.f_if1_Center;
1906         state->AS_Data.f_LO1 = 2181000000UL;
1907         state->AS_Data.f_LO2 = 1486249786UL;
1908         state->f_IF1_actual = state->AS_Data.f_if1_Center;
1909         state->AS_Data.f_in = state->AS_Data.f_LO1 - state->f_IF1_actual;
1910         state->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
1911         state->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
1912         state->num_regs = MT2063_REG_END_REGS;
1913         state->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
1914         state->ctfilt_sw = 0;
1915
1916         state->CTFiltMax[0] = 69230000;
1917         state->CTFiltMax[1] = 105770000;
1918         state->CTFiltMax[2] = 140350000;
1919         state->CTFiltMax[3] = 177110000;
1920         state->CTFiltMax[4] = 212860000;
1921         state->CTFiltMax[5] = 241130000;
1922         state->CTFiltMax[6] = 274370000;
1923         state->CTFiltMax[7] = 309820000;
1924         state->CTFiltMax[8] = 342450000;
1925         state->CTFiltMax[9] = 378870000;
1926         state->CTFiltMax[10] = 416210000;
1927         state->CTFiltMax[11] = 456500000;
1928         state->CTFiltMax[12] = 495790000;
1929         state->CTFiltMax[13] = 534530000;
1930         state->CTFiltMax[14] = 572610000;
1931         state->CTFiltMax[15] = 598970000;
1932         state->CTFiltMax[16] = 635910000;
1933         state->CTFiltMax[17] = 672130000;
1934         state->CTFiltMax[18] = 714840000;
1935         state->CTFiltMax[19] = 739660000;
1936         state->CTFiltMax[20] = 770410000;
1937         state->CTFiltMax[21] = 814660000;
1938         state->CTFiltMax[22] = 846950000;
1939         state->CTFiltMax[23] = 867820000;
1940         state->CTFiltMax[24] = 915980000;
1941         state->CTFiltMax[25] = 947450000;
1942         state->CTFiltMax[26] = 983110000;
1943         state->CTFiltMax[27] = 1021630000;
1944         state->CTFiltMax[28] = 1061870000;
1945         state->CTFiltMax[29] = 1098330000;
1946         state->CTFiltMax[30] = 1138990000;
1947
1948         /*
1949          **   Fetch the FCU osc value and use it and the fRef value to
1950          **   scale all of the Band Max values
1951          */
1952
1953         state->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
1954         status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
1955                               &state->reg[MT2063_REG_CTUNE_CTRL], 1);
1956         if (status < 0)
1957                 return status;
1958
1959         /*  Read the ClearTune filter calibration value  */
1960         status = mt2063_read(state, MT2063_REG_FIFFC,
1961                              &state->reg[MT2063_REG_FIFFC], 1);
1962         if (status < 0)
1963                 return status;
1964
1965         fcu_osc = state->reg[MT2063_REG_FIFFC];
1966
1967         state->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
1968         status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
1969                               &state->reg[MT2063_REG_CTUNE_CTRL], 1);
1970         if (status < 0)
1971                 return status;
1972
1973         /*  Adjust each of the values in the ClearTune filter cross-over table  */
1974         for (i = 0; i < 31; i++)
1975                 state->CTFiltMax[i] = (state->CTFiltMax[i] / 768) * (fcu_osc + 640);
1976
1977         status = MT2063_SoftwareShutdown(state, 1);
1978         if (status < 0)
1979                 return status;
1980         status = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
1981         if (status < 0)
1982                 return status;
1983
1984         state->init = true;
1985
1986         return 0;
1987 }
1988
1989 static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
1990 {
1991         struct mt2063_state *state = fe->tuner_priv;
1992         int status;
1993
1994         dprintk(2, "\n");
1995
1996         if (!state->init)
1997                 return -ENODEV;
1998
1999         *tuner_status = 0;
2000         status = mt2063_lockStatus(state);
2001         if (status < 0)
2002                 return status;
2003         if (status)
2004                 *tuner_status = TUNER_STATUS_LOCKED;
2005
2006         dprintk(1, "Tuner status: %d", *tuner_status);
2007
2008         return 0;
2009 }
2010
2011 static void mt2063_release(struct dvb_frontend *fe)
2012 {
2013         struct mt2063_state *state = fe->tuner_priv;
2014
2015         dprintk(2, "\n");
2016
2017         fe->tuner_priv = NULL;
2018         kfree(state);
2019 }
2020
2021 static int mt2063_set_analog_params(struct dvb_frontend *fe,
2022                                     struct analog_parameters *params)
2023 {
2024         struct mt2063_state *state = fe->tuner_priv;
2025         s32 pict_car;
2026         s32 pict2chanb_vsb;
2027         s32 ch_bw;
2028         s32 if_mid;
2029         s32 rcvr_mode;
2030         int status;
2031
2032         dprintk(2, "\n");
2033
2034         if (!state->init) {
2035                 status = mt2063_init(fe);
2036                 if (status < 0)
2037                         return status;
2038         }
2039
2040         switch (params->mode) {
2041         case V4L2_TUNER_RADIO:
2042                 pict_car = 38900000;
2043                 ch_bw = 8000000;
2044                 pict2chanb_vsb = -(ch_bw / 2);
2045                 rcvr_mode = MT2063_OFFAIR_ANALOG;
2046                 break;
2047         case V4L2_TUNER_ANALOG_TV:
2048                 rcvr_mode = MT2063_CABLE_ANALOG;
2049                 if (params->std & ~V4L2_STD_MN) {
2050                         pict_car = 38900000;
2051                         ch_bw = 6000000;
2052                         pict2chanb_vsb = -1250000;
2053                 } else if (params->std & V4L2_STD_PAL_G) {
2054                         pict_car = 38900000;
2055                         ch_bw = 7000000;
2056                         pict2chanb_vsb = -1250000;
2057                 } else {                /* PAL/SECAM standards */
2058                         pict_car = 38900000;
2059                         ch_bw = 8000000;
2060                         pict2chanb_vsb = -1250000;
2061                 }
2062                 break;
2063         default:
2064                 return -EINVAL;
2065         }
2066         if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2067
2068         state->AS_Data.f_LO2_Step = 125000;     /* FIXME: probably 5000 for FM */
2069         state->AS_Data.f_out = if_mid;
2070         state->AS_Data.f_out_bw = ch_bw + 750000;
2071         status = MT2063_SetReceiverMode(state, rcvr_mode);
2072         if (status < 0)
2073                 return status;
2074
2075         dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2076                 params->frequency, ch_bw, pict2chanb_vsb);
2077
2078         status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2079         if (status < 0)
2080                 return status;
2081
2082         state->frequency = params->frequency;
2083         return 0;
2084 }
2085
2086 /*
2087  * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
2088  * So, the amount of the needed bandwidth is given by:
2089  *      Bw = Symbol_rate * (1 + 0.15)
2090  * As such, the maximum symbol rate supported by 6 MHz is given by:
2091  *      max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
2092  */
2093 #define MAX_SYMBOL_RATE_6MHz    5217391
2094
2095 static int mt2063_set_params(struct dvb_frontend *fe)
2096 {
2097         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
2098         struct mt2063_state *state = fe->tuner_priv;
2099         int status;
2100         s32 pict_car;
2101         s32 pict2chanb_vsb;
2102         s32 ch_bw;
2103         s32 if_mid;
2104         s32 rcvr_mode;
2105
2106         if (!state->init) {
2107                 status = mt2063_init(fe);
2108                 if (status < 0)
2109                         return status;
2110         }
2111
2112         dprintk(2, "\n");
2113
2114         if (c->bandwidth_hz == 0)
2115                 return -EINVAL;
2116         if (c->bandwidth_hz <= 6000000)
2117                 ch_bw = 6000000;
2118         else if (c->bandwidth_hz <= 7000000)
2119                 ch_bw = 7000000;
2120         else
2121                 ch_bw = 8000000;
2122
2123         switch (c->delivery_system) {
2124         case SYS_DVBT:
2125                 rcvr_mode = MT2063_OFFAIR_COFDM;
2126                 pict_car = 36125000;
2127                 pict2chanb_vsb = -(ch_bw / 2);
2128                 break;
2129         case SYS_DVBC_ANNEX_A:
2130         case SYS_DVBC_ANNEX_C:
2131                 rcvr_mode = MT2063_CABLE_QAM;
2132                 pict_car = 36125000;
2133                 pict2chanb_vsb = -(ch_bw / 2);
2134                 break;
2135         default:
2136                 return -EINVAL;
2137         }
2138         if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2139
2140         state->AS_Data.f_LO2_Step = 125000;     /* FIXME: probably 5000 for FM */
2141         state->AS_Data.f_out = if_mid;
2142         state->AS_Data.f_out_bw = ch_bw + 750000;
2143         status = MT2063_SetReceiverMode(state, rcvr_mode);
2144         if (status < 0)
2145                 return status;
2146
2147         dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2148                 c->frequency, ch_bw, pict2chanb_vsb);
2149
2150         status = MT2063_Tune(state, (c->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2151
2152         if (status < 0)
2153                 return status;
2154
2155         state->frequency = c->frequency;
2156         return 0;
2157 }
2158
2159 static int mt2063_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
2160 {
2161         struct mt2063_state *state = fe->tuner_priv;
2162
2163         dprintk(2, "\n");
2164
2165         if (!state->init)
2166                 return -ENODEV;
2167
2168         *freq = state->AS_Data.f_out;
2169
2170         dprintk(1, "IF frequency: %d\n", *freq);
2171
2172         return 0;
2173 }
2174
2175 static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
2176 {
2177         struct mt2063_state *state = fe->tuner_priv;
2178
2179         dprintk(2, "\n");
2180
2181         if (!state->init)
2182                 return -ENODEV;
2183
2184         *bw = state->AS_Data.f_out_bw - 750000;
2185
2186         dprintk(1, "bandwidth: %d\n", *bw);
2187
2188         return 0;
2189 }
2190
2191 static const struct dvb_tuner_ops mt2063_ops = {
2192         .info = {
2193                  .name = "MT2063 Silicon Tuner",
2194                  .frequency_min_hz  =  45 * MHz,
2195                  .frequency_max_hz  = 865 * MHz,
2196          },
2197
2198         .init = mt2063_init,
2199         .sleep = MT2063_Sleep,
2200         .get_status = mt2063_get_status,
2201         .set_analog_params = mt2063_set_analog_params,
2202         .set_params    = mt2063_set_params,
2203         .get_if_frequency = mt2063_get_if_frequency,
2204         .get_bandwidth = mt2063_get_bandwidth,
2205         .release = mt2063_release,
2206 };
2207
2208 struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
2209                                    struct mt2063_config *config,
2210                                    struct i2c_adapter *i2c)
2211 {
2212         struct mt2063_state *state = NULL;
2213
2214         dprintk(2, "\n");
2215
2216         state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
2217         if (!state)
2218                 return NULL;
2219
2220         state->config = config;
2221         state->i2c = i2c;
2222         state->frontend = fe;
2223         state->reference = config->refclock / 1000;     /* kHz */
2224         fe->tuner_priv = state;
2225         fe->ops.tuner_ops = mt2063_ops;
2226
2227         printk(KERN_INFO "%s: Attaching MT2063\n", __func__);
2228         return fe;
2229 }
2230 EXPORT_SYMBOL_GPL(mt2063_attach);
2231
2232 #if 0
2233 /*
2234  * Ancillary routines visible outside mt2063
2235  * FIXME: Remove them in favor of using standard tuner callbacks
2236  */
2237 static int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
2238 {
2239         struct mt2063_state *state = fe->tuner_priv;
2240         int err = 0;
2241
2242         dprintk(2, "\n");
2243
2244         err = MT2063_SoftwareShutdown(state, 1);
2245         if (err < 0)
2246                 printk(KERN_ERR "%s: Couldn't shutdown\n", __func__);
2247
2248         return err;
2249 }
2250
2251 static int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
2252 {
2253         struct mt2063_state *state = fe->tuner_priv;
2254         int err = 0;
2255
2256         dprintk(2, "\n");
2257
2258         err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
2259         if (err < 0)
2260                 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
2261
2262         return err;
2263 }
2264 #endif
2265
2266 MODULE_AUTHOR("Mauro Carvalho Chehab");
2267 MODULE_DESCRIPTION("MT2063 Silicon tuner");
2268 MODULE_LICENSE("GPL");