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