cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mt2063.c (66384B)


      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
     22static unsigned int debug;
     23module_param(debug, int, 0644);
     24MODULE_PARM_DESC(debug, "Set Verbosity level");
     25
     26#define dprintk(level, fmt, arg...) do {				\
     27if (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
     65enum 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
     74struct 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 */
     83struct 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 */
    115enum 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 */
    136enum 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 */
    147enum 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
    212struct 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 */
    239static 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 */
    271static 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 */
    292static 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 */
    339static 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
    357struct MT2063_FIFZone_t {
    358	s32 min_;
    359	s32 max_;
    360};
    361
    362static 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
    393static 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 */
    425static 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 */
    479static 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 */
    550static 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 */
    678static 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 */
    787static 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 */
    908static 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
    980enum 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
    990static 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
    999static const u8 RFAGCEN[]	= {  0,  0,  0,  0,  0,  0 };
   1000static const u8 LNARIN[]	= {  0,  0,  3,  3,  3,  3 };
   1001static const u8 FIFFQEN[]	= {  1,  1,  1,  1,  1,  1 };
   1002static const u8 FIFFQ[]		= {  0,  0,  0,  0,  0,  0 };
   1003static const u8 DNC1GC[]	= {  0,  0,  0,  0,  0,  0 };
   1004static const u8 DNC2GC[]	= {  0,  0,  0,  0,  0,  0 };
   1005static const u8 ACLNAMAX[]	= { 31, 31, 31, 31, 31, 31 };
   1006static const u8 LNATGT[]	= { 44, 43, 43, 43, 43, 43 };
   1007static const u8 RFOVDIS[]	= {  0,  0,  0,  0,  0,  0 };
   1008static const u8 ACRFMAX[]	= { 31, 31, 31, 31, 31, 31 };
   1009static const u8 PD1TGT[]	= { 36, 36, 38, 38, 36, 38 };
   1010static const u8 FIFOVDIS[]	= {  0,  0,  0,  0,  0,  0 };
   1011static const u8 ACFIFMAX[]	= { 29, 29, 29, 29, 29, 29 };
   1012static const u8 PD2TGT[]	= { 40, 33, 38, 42, 30, 38 };
   1013
   1014/*
   1015 * mt2063_set_dnc_output_enable()
   1016 */
   1017static 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 */
   1039static 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
   1173static 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 */
   1315static 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 */
   1345static 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
   1379static 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 */
   1403static 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 */
   1430static 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 */
   1461static 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 */
   1487static 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 */
   1508static 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
   1709static 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 */
   1734static 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 */
   1761static 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
   1772static 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
   1988static 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
   2010static 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
   2020static 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
   2094static 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
   2158static 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
   2174static 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
   2190static 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
   2207struct 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}
   2229EXPORT_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 */
   2236static 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
   2250static 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
   2265MODULE_AUTHOR("Mauro Carvalho Chehab");
   2266MODULE_DESCRIPTION("MT2063 Silicon tuner");
   2267MODULE_LICENSE("GPL");