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