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