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