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