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