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