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