1/*
2 * Driver for mt2063 Micronas tuner
3 *
4 * Copyright (c) 2011 Mauro Carvalho Chehab
5 *
6 * This driver came from a driver originally written by:
7 *		Henry Wang <Henry.wang@AzureWave.com>
8 * Made publicly available by Terratec, at:
9 *	http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
10 * The original driver's license is GPL, as declared with MODULE_LICENSE()
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation under version 2 of the License.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU General Public License for more details.
20 */
21
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/videodev2.h>
27
28#include "mt2063.h"
29
30static unsigned int debug;
31module_param(debug, int, 0644);
32MODULE_PARM_DESC(debug, "Set Verbosity level");
33
34#define dprintk(level, fmt, arg...) do {				\
35if (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
73enum 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
82struct 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 */
91struct 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 */
123enum 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 */
144enum 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 */
155enum 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
220struct 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 */
248static 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 */
280static 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 */
301static 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 */
348static 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
366struct MT2063_FIFZone_t {
367	s32 min_;
368	s32 max_;
369};
370
371static 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
402static 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 */
434static 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 */
488static 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 */
559static 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 */
676static 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 */
708static 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 */
817static 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 */
938static 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
1010enum 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
1020static 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
1029static const u8 RFAGCEN[]	= {  0,  0,  0,  0,  0,  0 };
1030static const u8 LNARIN[]	= {  0,  0,  3,  3,  3,  3 };
1031static const u8 FIFFQEN[]	= {  1,  1,  1,  1,  1,  1 };
1032static const u8 FIFFQ[]		= {  0,  0,  0,  0,  0,  0 };
1033static const u8 DNC1GC[]	= {  0,  0,  0,  0,  0,  0 };
1034static const u8 DNC2GC[]	= {  0,  0,  0,  0,  0,  0 };
1035static const u8 ACLNAMAX[]	= { 31, 31, 31, 31, 31, 31 };
1036static const u8 LNATGT[]	= { 44, 43, 43, 43, 43, 43 };
1037static const u8 RFOVDIS[]	= {  0,  0,  0,  0,  0,  0 };
1038static const u8 ACRFMAX[]	= { 31, 31, 31, 31, 31, 31 };
1039static const u8 PD1TGT[]	= { 36, 36, 38, 38, 36, 38 };
1040static const u8 FIFOVDIS[]	= {  0,  0,  0,  0,  0,  0 };
1041static const u8 ACFIFMAX[]	= { 29, 29, 29, 29, 29, 29 };
1042static const u8 PD2TGT[]	= { 40, 33, 38, 42, 30, 38 };
1043
1044/*
1045 * mt2063_set_dnc_output_enable()
1046 */
1047static 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 */
1069static 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
1203static 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] & ~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] & ~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] & ~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] | 0x01);
1246			status |=
1247			    mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1248			val =
1249			    (state->
1250			     reg[MT2063_REG_FIFF_CTRL] & ~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] & ~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] & ~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] & ~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] & ~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] & ~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] & ~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] & ~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] & ~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 */
1345static 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 */
1375static 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
1409static 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 */
1433static 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 */
1460static 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 */
1493static 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 */
1519static 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 */
1540static 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
1741static 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 */
1766static 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 */
1793static 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
1804static 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
2021static 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
2043static 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
2055static 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
2129static 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
2193static 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
2209static 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
2225static 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
2243struct 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}
2265EXPORT_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 */
2272static 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
2286static 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
2301MODULE_AUTHOR("Mauro Carvalho Chehab");
2302MODULE_DESCRIPTION("MT2063 Silicon tuner");
2303MODULE_LICENSE("GPL");
2304