From 0e301442d6dfb378645ff29554685d4d34aa2ec2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Jul 2011 19:52:49 -0300 Subject: [PATCH] [media] mt2063: CodingStyle fixes convert to Unix eol, run Lindent and remove bad whitespaces Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/mt2063.c | 9048 +++++++++++----------- drivers/media/common/tuners/mt2063.h | 1365 ++-- drivers/media/common/tuners/mt2063_cfg.h | 151 +- 3 files changed, 5373 insertions(+), 5191 deletions(-) diff --git a/drivers/media/common/tuners/mt2063.c b/drivers/media/common/tuners/mt2063.c index 46001916b991..0d64eb839350 100644 --- a/drivers/media/common/tuners/mt2063.c +++ b/drivers/media/common/tuners/mt2063.c @@ -1,4471 +1,4704 @@ - + #include #include #include #include - -#include "drxk_type.h" -#include "mt2063.h" - -/* Version of this module */ -#define MT2063_VERSION 10018 /* Version 01.18 */ - + +#include "drxk_type.h" +#include "mt2063.h" + +/* Version of this module */ +#define MT2063_VERSION 10018 /* Version 01.18 */ + static unsigned int verbose; -module_param(verbose, int, 0644); - -//i2c operation -static int mt2063_writeregs(struct mt2063_state *state, u8 reg1, - u8 *data, int len) +module_param(verbose, int, 0644); + +//i2c operation +static int mt2063_writeregs(struct mt2063_state *state, u8 reg1, + u8 * data, int len) { int ret; - u8 buf[60];/* = { reg1, data };*/ - + u8 buf[60]; /* = { reg1, data }; */ + struct i2c_msg msg = { - .addr = state->config->tuner_address, - .flags = 0, - .buf = buf, - .len = len + 1 + .addr = state->config->tuner_address, + .flags = 0, + .buf = buf, + .len = len + 1 }; - msg.buf[0] = reg1; + msg.buf[0] = reg1; memcpy(msg.buf + 1, data, len); - - //printk("mt2063_writeregs state->i2c=%p\n", state->i2c); + + //printk("mt2063_writeregs state->i2c=%p\n", state->i2c); ret = i2c_transfer(state->i2c, &msg, 1); - if (ret < 0) - printk("mt2063_writeregs error ret=%d\n", ret); + if (ret < 0) + printk("mt2063_writeregs error ret=%d\n", ret); - return ret; -} - -static int mt2063_read_regs(struct mt2063_state *state, u8 reg1, u8 *b, u8 len) + return ret; +} + +static int mt2063_read_regs(struct mt2063_state *state, u8 reg1, u8 * b, u8 len) { - int ret; - u8 b0[] = { reg1 }; + int ret; + u8 b0[] = { reg1 }; struct i2c_msg msg[] = { { - .addr = state->config->tuner_address, - .flags = I2C_M_RD, - .buf = b0, - .len = 1 - }, { - .addr = state->config->tuner_address, - .flags = I2C_M_RD, - .buf = b, - .len = len - } + .addr = state->config->tuner_address, + .flags = I2C_M_RD, + .buf = b0, + .len = 1}, { + .addr = state->config->tuner_address, + .flags = I2C_M_RD, + .buf = b, + .len = len} }; - - //printk("mt2063_read_regs state->i2c=%p\n", state->i2c); - ret = i2c_transfer(state->i2c, msg, 2); - if (ret < 0) - printk("mt2063_readregs error ret=%d\n", ret); - return ret; -} - - - - -//context of mt2063_userdef.c ====================================== -//################################################################# -//================================================================= -/***************************************************************************** -** -** Name: MT_WriteSub -** -** Description: Write values to device using a two-wire serial bus. -** -** Parameters: hUserData - User-specific I/O parameter that was -** passed to tuner's Open function. -** addr - device serial bus address (value passed -** as parameter to MTxxxx_Open) -** subAddress - serial bus sub-address (Register Address) -** pData - pointer to the Data to be written to the -** device -** cnt - number of bytes/registers to be written -** -** Returns: status: -** MT_OK - No errors -** MT_COMM_ERR - Serial bus communications error -** user-defined -** -** Notes: This is a callback function that is called from the -** the tuning algorithm. You MUST provide code for this -** function to write data using the tuner's 2-wire serial -** bus. -** -** The hUserData parameter is a user-specific argument. -** If additional arguments are needed for the user's -** serial bus read/write functions, this argument can be -** used to supply the necessary information. -** The hUserData parameter is initialized in the tuner's Open -** function. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** N/A 03-25-2004 DAD Original -** -*****************************************************************************/ -UData_t MT2063_WriteSub(Handle_t hUserData, - UData_t addr, - U8Data subAddress, - U8Data *pData, - UData_t cnt) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct dvb_frontend *fe = hUserData; - struct mt2063_state *state = fe->tuner_priv; - /* - ** ToDo: Add code here to implement a serial-bus write - ** operation to the MTxxxx tuner. If successful, - ** return MT_OK. - */ -/* return status; */ - -//#if !TUNER_CONTROL_BY_DRXK_DRIVER - fe->ops.i2c_gate_ctrl(fe, 1); //I2C bypass drxk3926 close i2c bridge -//#endif - - if (mt2063_writeregs(state, subAddress,pData, cnt)<0) - { - status = MT2063_ERROR; - } - -//#if !TUNER_CONTROL_BY_DRXK_DRIVER - fe->ops.i2c_gate_ctrl(fe, 0); //I2C bypass drxk3926 close i2c bridge -//#endif - - return (status); -} - -/***************************************************************************** -** -** Name: MT_ReadSub -** -** Description: Read values from device using a two-wire serial bus. -** -** Parameters: hUserData - User-specific I/O parameter that was -** passed to tuner's Open function. -** addr - device serial bus address (value passed -** as parameter to MTxxxx_Open) -** subAddress - serial bus sub-address (Register Address) -** pData - pointer to the Data to be written to the -** device -** cnt - number of bytes/registers to be written -** -** Returns: status: -** MT_OK - No errors -** MT_COMM_ERR - Serial bus communications error -** user-defined -** -** Notes: This is a callback function that is called from the -** the tuning algorithm. You MUST provide code for this -** function to read data using the tuner's 2-wire serial -** bus. -** -** The hUserData parameter is a user-specific argument. -** If additional arguments are needed for the user's -** serial bus read/write functions, this argument can be -** used to supply the necessary information. -** The hUserData parameter is initialized in the tuner's Open -** function. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** N/A 03-25-2004 DAD Original -** -*****************************************************************************/ -UData_t MT2063_ReadSub(Handle_t hUserData, - UData_t addr, - U8Data subAddress, - U8Data *pData, - UData_t cnt) -{ - /* - ** ToDo: Add code here to implement a serial-bus read - ** operation to the MTxxxx tuner. If successful, - ** return MT_OK. - */ -/* return status; */ - UData_t status = MT2063_OK; /* Status to be returned */ - struct dvb_frontend *fe = hUserData; - struct mt2063_state *state = fe->tuner_priv; - UData_t i = 0; -//#if !TUNER_CONTROL_BY_DRXK_DRIVER - fe->ops.i2c_gate_ctrl(fe, 1); //I2C bypass drxk3926 close i2c bridge -//#endif - - for (i = 0; i < cnt; i++) - { - if (mt2063_read_regs(state, subAddress+i, pData+i, 1)<0) - { - status = MT2063_ERROR; - break; - } - } - -//#if !TUNER_CONTROL_BY_DRXK_DRIVER - fe->ops.i2c_gate_ctrl(fe, 0); //I2C bypass drxk3926 close i2c bridge -//#endif - - return(status); -} - - -/***************************************************************************** -** -** Name: MT_Sleep -** -** Description: Delay execution for "nMinDelayTime" milliseconds -** -** Parameters: hUserData - User-specific I/O parameter that was -** passed to tuner's Open function. -** nMinDelayTime - Delay time in milliseconds -** -** Returns: None. -** -** Notes: This is a callback function that is called from the -** the tuning algorithm. You MUST provide code that -** blocks execution for the specified period of time. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** N/A 03-25-2004 DAD Original -** -*****************************************************************************/ -void MT2063_Sleep(Handle_t hUserData, - UData_t nMinDelayTime) -{ - /* - ** ToDo: Add code here to implement a OS blocking - ** for a period of "nMinDelayTime" milliseconds. - */ - msleep(nMinDelayTime); -} - - -#if defined(MT2060_CNT) -#if MT2060_CNT > 0 -/***************************************************************************** -** -** Name: MT_TunerGain (MT2060 only) -** -** Description: Measure the relative tuner gain using the demodulator -** -** Parameters: hUserData - User-specific I/O parameter that was -** passed to tuner's Open function. -** pMeas - Tuner gain (1/100 of dB scale). -** ie. 1234 = 12.34 (dB) -** -** Returns: status: -** MT_OK - No errors -** user-defined errors could be set -** -** Notes: This is a callback function that is called from the -** the 1st IF location routine. You MUST provide -** code that measures the relative tuner gain in a dB -** (not linear) scale. The return value is an integer -** value scaled to 1/100 of a dB. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** N/A 06-16-2004 DAD Original -** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name -** better describes what this function does. -** -*****************************************************************************/ -UData_t MT2060_TunerGain(Handle_t hUserData, - SData_t* pMeas) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - - /* - ** ToDo: Add code here to return the gain / power level measured - ** at the input to the demodulator. - */ - - - - return (status); -} -#endif -#endif -//end of mt2063_userdef.c -//================================================================= -//################################################################# -//================================================================= - - -//context of mt2063_spuravoid.c ====================================== -//################################################################# -//================================================================= - -/***************************************************************************** -** -** Name: mt_spuravoid.c -** -** Description: Microtune spur avoidance software module. -** Supports Microtune tuner drivers. -** -** CVS ID: $Id: mt_spuravoid.c,v 1.3 2008/06/26 15:39:52 software Exp $ -** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2063/mt_spuravoid.c,v $ -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 082 03-25-2005 JWS Original multi-tuner support - requires -** MTxxxx_CNT declarations -** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0. -** 094 04-06-2005 JWS Ver 1.11 Added uceil and ufloor to get rid -** of compiler warnings -** N/A 04-07-2005 DAD Ver 1.13: Merged single- and multi-tuner spur -** avoidance into a single module. -** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range -** (f_min, f_max) < 0, ignore the entry. -** 115 03-23-2007 DAD Fix declaration of spur due to truncation -** errors. -** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from -** tuner DLL. -** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for -** multi-tuners that have -** (delta IF1) > (f_out-f_outbw/2). -** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+) -** Added logic to force f_Center within 1/2 f_Step. -** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2 -** Type casts added to preserve correct sign. -** N/A I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT -** frequencies into MT_ResetExclZones(). -** N/A I 06-20-2008 RSK Ver 1.21: New VERSION number for ver checking. -** -*****************************************************************************/ - -#if !defined(MT2063_TUNER_CNT) -#error MT2063_TUNER_CNT is not defined (see mt_userdef.h) -#endif - -#if MT2063_TUNER_CNT == 0 -#error MT2063_TUNER_CNT must be updated in mt_userdef.h -#endif - -/* Version of this module */ -#define MT2063_SPUR_VERSION 10201 /* Version 01.21 */ - - -/* Implement ceiling, floor functions. */ -#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0)) -#define uceil(n, d) ((n)/(d) + ((n)%(d) != 0)) -#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d)) -#define ufloor(n, d) ((n)/(d)) - - -struct MT2063_FIFZone_t -{ - SData_t min_; - SData_t max_; -}; - -#if MT2063_TUNER_CNT > 1 -static struct MT2063_AvoidSpursData_t* TunerList[MT2063_TUNER_CNT]; -static UData_t TunerCount = 0; -#endif - -UData_t MT2063_RegisterTuner(struct MT2063_AvoidSpursData_t* pAS_Info) -{ -#if MT2063_TUNER_CNT == 1 - pAS_Info->nAS_Algorithm = 1; - return MT2063_OK; -#else - UData_t index; - - pAS_Info->nAS_Algorithm = 2; - - /* - ** Check to see if tuner is already registered - */ - for (index = 0; index < TunerCount; index++) - { - if (TunerList[index] == pAS_Info) - { - return MT2063_OK; /* Already here - no problem */ - } - } - - /* - ** Add tuner to list - if there is room. - */ - if (TunerCount < MT2063_TUNER_CNT) - { - TunerList[TunerCount] = pAS_Info; - TunerCount++; - return MT2063_OK; - } - else - return MT2063_TUNER_CNT_ERR; -#endif -} - - -void MT2063_UnRegisterTuner(struct MT2063_AvoidSpursData_t* pAS_Info) -{ -#if MT2063_TUNER_CNT == 1 - pAS_Info; -#else - - UData_t index; - - for (index = 0; index < TunerCount; index++) - { - if (TunerList[index] == pAS_Info) - { - TunerList[index] = TunerList[--TunerCount]; - } - } -#endif -} - - -/* -** Reset all exclusion zones. -** Add zones to protect the PLL FracN regions near zero -** -** N/A I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT -** frequencies into MT_ResetExclZones(). -*/ -void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t* pAS_Info) -{ - UData_t center; -#if MT2063_TUNER_CNT > 1 - UData_t index; - struct MT2063_AvoidSpursData_t* adj; -#endif - - pAS_Info->nZones = 0; /* this clears the used list */ - pAS_Info->usedZones = NULL; /* reset ptr */ - pAS_Info->freeZones = NULL; /* reset ptr */ - - center = pAS_Info->f_ref * ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw/2 + pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in; - while (center < pAS_Info->f_if1_Center + pAS_Info->f_if1_bw/2 + pAS_Info->f_LO1_FracN_Avoid) - { - /* Exclude LO1 FracN */ - MT2063_AddExclZone(pAS_Info, center-pAS_Info->f_LO1_FracN_Avoid, center-1); - MT2063_AddExclZone(pAS_Info, center+1, center+pAS_Info->f_LO1_FracN_Avoid); - center += pAS_Info->f_ref; - } - - center = pAS_Info->f_ref * ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw/2 - pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out; - while (center < pAS_Info->f_if1_Center + pAS_Info->f_if1_bw/2 + pAS_Info->f_LO2_FracN_Avoid) - { - /* Exclude LO2 FracN */ - MT2063_AddExclZone(pAS_Info, center-pAS_Info->f_LO2_FracN_Avoid, center-1); - MT2063_AddExclZone(pAS_Info, center+1, center+pAS_Info->f_LO2_FracN_Avoid); - center += pAS_Info->f_ref; - } - - if( MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT) ) - { - /* Exclude LO1 values that conflict with DECT channels */ - MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */ - MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */ - MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */ - MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */ - MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */ - } - - if( MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT) ) - { - MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */ - MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */ - MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */ - MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16 */ - MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */ - MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */ - MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */ - MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */ - MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52 */ - MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */ - } - -#if MT2063_TUNER_CNT > 1 - /* - ** Iterate through all adjacent tuners and exclude frequencies related to them - */ - for (index = 0; index < TunerCount; ++index) - { - adj = TunerList[index]; - if (pAS_Info == adj) /* skip over our own data, don't process it */ - continue; - - /* - ** Add 1st IF exclusion zone covering adjacent tuner's LO2 - ** at "adjfLO2 + f_out" +/- m_MinLOSpacing - */ - if (adj->f_LO2 != 0) - MT2063_AddExclZone(pAS_Info, - (adj->f_LO2 + pAS_Info->f_out) - pAS_Info->f_min_LO_Separation, - (adj->f_LO2 + pAS_Info->f_out) + pAS_Info->f_min_LO_Separation ); - - /* - ** Add 1st IF exclusion zone covering adjacent tuner's LO1 - ** at "adjfLO1 - f_in" +/- m_MinLOSpacing - */ - if (adj->f_LO1 != 0) - MT2063_AddExclZone(pAS_Info, - (adj->f_LO1 - pAS_Info->f_in) - pAS_Info->f_min_LO_Separation, - (adj->f_LO1 - pAS_Info->f_in) + pAS_Info->f_min_LO_Separation ); - } -#endif -} - - -static struct MT2063_ExclZone_t* InsertNode(struct MT2063_AvoidSpursData_t* pAS_Info, - struct MT2063_ExclZone_t* pPrevNode) -{ - struct MT2063_ExclZone_t* pNode; - /* Check for a node in the free list */ - if (pAS_Info->freeZones != NULL) - { - /* Use one from the free list */ - pNode = pAS_Info->freeZones; - pAS_Info->freeZones = pNode->next_; - } - else - { - /* Grab a node from the array */ - pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones]; - } - - if (pPrevNode != NULL) - { - pNode->next_ = pPrevNode->next_; - pPrevNode->next_ = pNode; - } - else /* insert at the beginning of the list */ - { - pNode->next_ = pAS_Info->usedZones; - pAS_Info->usedZones = pNode; - } - - pAS_Info->nZones++; - return pNode; -} - - -static struct MT2063_ExclZone_t* RemoveNode(struct MT2063_AvoidSpursData_t* pAS_Info, - struct MT2063_ExclZone_t* pPrevNode, - struct MT2063_ExclZone_t* pNodeToRemove) -{ - struct MT2063_ExclZone_t* pNext = pNodeToRemove->next_; - - /* Make previous node point to the subsequent node */ - if (pPrevNode != NULL) - pPrevNode->next_ = pNext; - - /* Add pNodeToRemove to the beginning of the freeZones */ - pNodeToRemove->next_ = pAS_Info->freeZones; - pAS_Info->freeZones = pNodeToRemove; - - /* Decrement node count */ - pAS_Info->nZones--; - - return pNext; -} - - -/***************************************************************************** -** -** Name: MT_AddExclZone -** -** Description: Add (and merge) an exclusion zone into the list. -** If the range (f_min, f_max) is totally outside the -** 1st IF BW, ignore the entry. -** If the range (f_min, f_max) is negative, ignore the entry. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range -** (f_min, f_max) < 0, ignore the entry. -** -*****************************************************************************/ -void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t* pAS_Info, - UData_t f_min, - UData_t f_max) -{ - struct MT2063_ExclZone_t* pNode = pAS_Info->usedZones; - struct MT2063_ExclZone_t* pPrev = NULL; - struct MT2063_ExclZone_t* pNext = NULL; - - /* Check to see if this overlaps the 1st IF filter */ - if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2))) - && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2))) - && (f_min < f_max)) - { - /* - ** 1 2 3 4 5 6 - ** - ** New entry: |---| |--| |--| |-| |---| |--| - ** or or or or or - ** Existing: |--| |--| |--| |---| |-| |--| - */ - - /* Check for our place in the list */ - while ((pNode != NULL) && (pNode->max_ < f_min)) - { - pPrev = pNode; - pNode = pNode->next_; - } - - if ((pNode != NULL) && (pNode->min_ < f_max)) - { - /* Combine me with pNode */ - if (f_min < pNode->min_) - pNode->min_ = f_min; - if (f_max > pNode->max_) - pNode->max_ = f_max; - } - else - { - pNode = InsertNode(pAS_Info, pPrev); - pNode->min_ = f_min; - pNode->max_ = f_max; - } - - /* Look for merging possibilities */ - pNext = pNode->next_; - while ((pNext != NULL) && (pNext->min_ < pNode->max_)) - { - if (pNext->max_ > pNode->max_) - pNode->max_ = pNext->max_; - pNext = RemoveNode(pAS_Info, pNode, pNext); /* Remove pNext, return ptr to pNext->next */ - } - } -} - - -/***************************************************************************** -** -** Name: MT_ChooseFirstIF -** -** Description: Choose the best available 1st IF -** If f_Desired is not excluded, choose that first. -** Otherwise, return the value closest to f_Center that is -** not excluded -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from -** tuner DLL. -** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+) -** Added logic to force f_Center within 1/2 f_Step. -** -*****************************************************************************/ -UData_t MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t* pAS_Info) -{ - /* - ** Update "f_Desired" to be the nearest "combinational-multiple" of "f_LO1_Step". - ** The resulting number, F_LO1 must be a multiple of f_LO1_Step. And F_LO1 is the arithmetic sum - ** of f_in + f_Center. Neither f_in, nor f_Center must be a multiple of f_LO1_Step. - ** However, the sum must be. - */ - const UData_t f_Desired = pAS_Info->f_LO1_Step * ((pAS_Info->f_if1_Request + pAS_Info->f_in + pAS_Info->f_LO1_Step/2) / pAS_Info->f_LO1_Step) - pAS_Info->f_in; - const UData_t f_Step = (pAS_Info->f_LO1_Step > pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->f_LO2_Step; - UData_t f_Center; - - SData_t i; - SData_t j = 0; - UData_t bDesiredExcluded = 0; - UData_t bZeroExcluded = 0; - SData_t tmpMin, tmpMax; - SData_t bestDiff; - struct MT2063_ExclZone_t* pNode = pAS_Info->usedZones; - struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES]; - - if (pAS_Info->nZones == 0) - return f_Desired; - - /* f_Center needs to be an integer multiple of f_Step away from f_Desired */ - if (pAS_Info->f_if1_Center > f_Desired) - f_Center = f_Desired + f_Step * ((pAS_Info->f_if1_Center - f_Desired + f_Step/2) / f_Step); - else - f_Center = f_Desired - f_Step * ((f_Desired - pAS_Info->f_if1_Center + f_Step/2) / f_Step); - - //assert; - //if (!abs((SData_t) f_Center - (SData_t) pAS_Info->f_if1_Center) <= (SData_t) (f_Step/2)) - // return 0; - - /* Take MT_ExclZones, center around f_Center and change the resolution to f_Step */ - while (pNode != NULL) - { - /* floor function */ - tmpMin = floor((SData_t) (pNode->min_ - f_Center), (SData_t) f_Step); - - /* ceil function */ - tmpMax = ceil((SData_t) (pNode->max_ - f_Center), (SData_t) f_Step); - - if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired)) - bDesiredExcluded = 1; - - if ((tmpMin < 0) && (tmpMax > 0)) - bZeroExcluded = 1; - - /* See if this zone overlaps the previous */ - if ((j>0) && (tmpMin < zones[j-1].max_)) - zones[j-1].max_ = tmpMax; - else - { - /* Add new zone */ - //assert(j=MT2063_MAX_ZONES) - //break; - - zones[j].min_ = tmpMin; - zones[j].max_ = tmpMax; - j++; - } - pNode = pNode->next_; - } - - /* - ** If the desired is okay, return with it - */ - if (bDesiredExcluded == 0) - return f_Desired; - - /* - ** If the desired is excluded and the center is okay, return with it - */ - if (bZeroExcluded == 0) - return f_Center; - - /* Find the value closest to 0 (f_Center) */ - bestDiff = zones[0].min_; - for (i=0; i= b) ? a : b; -} - -#if MT2063_TUNER_CNT > 1 -static SData_t RoundAwayFromZero(SData_t n, SData_t d) -{ - return (n<0) ? floor(n, d) : ceil(n, d); -} - -/**************************************************************************** -** -** Name: IsSpurInAdjTunerBand -** -** Description: Checks to see if a spur will be present within the IF's -** bandwidth or near the zero IF. -** (fIFOut +/- fIFBW/2, -fIFOut +/- fIFBW/2) -** and -** (0 +/- fZIFBW/2) -** -** ma mb me mf mc md -** <--+-+-+-----------------+-+-+-----------------+-+-+--> -** | ^ 0 ^ | -** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^ -** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2 -** -** Note that some equations are doubled to prevent round-off -** problems when calculating fIFBW/2 -** -** The spur frequencies are computed as: -** -** fSpur = n * f1 - m * f2 - fOffset -** -** Parameters: f1 - The 1st local oscillator (LO) frequency -** of the tuner whose output we are examining -** f2 - The 1st local oscillator (LO) frequency -** of the adjacent tuner -** fOffset - The 2nd local oscillator of the tuner whose -** output we are examining -** fIFOut - Output IF center frequency -** fIFBW - Output IF Bandwidth -** nMaxH - max # of LO harmonics to search -** fp - If spur, positive distance to spur-free band edge (returned) -** fm - If spur, negative distance to spur-free band edge (returned) -** -** Returns: 1 if an LO spur would be present, otherwise 0. -** -** Dependencies: None. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** N/A 01-21-2005 JWS Original, adapted from MT_DoubleConversion. -** 115 03-23-2007 DAD Fix declaration of spur due to truncation -** errors. -** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for -** multi-tuners that have -** (delta IF1) > (f_out-f_outbw/2). -** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2 -** Type casts added to preserve correct sign. -** -****************************************************************************/ -static UData_t IsSpurInAdjTunerBand(UData_t bIsMyOutput, - UData_t f1, - UData_t f2, - UData_t fOffset, - UData_t fIFOut, - UData_t fIFBW, - UData_t fZIFBW, - UData_t nMaxH, - UData_t *fp, - UData_t *fm) -{ - UData_t bSpurFound = 0; - - const UData_t fHalf_IFBW = fIFBW / 2; - const UData_t fHalf_ZIFBW = fZIFBW / 2; - - /* Calculate a scale factor for all frequencies, so that our - calculations all stay within 31 bits */ - const UData_t f_Scale = ((f1 + (fOffset + fIFOut + fHalf_IFBW) / nMaxH) / (MAX_UDATA/2 / nMaxH)) + 1; - - /* - ** After this scaling, _f1, _f2, and _f3 are guaranteed to fit into - ** signed data types (smaller than MAX_UDATA/2) - */ - const SData_t _f1 = (SData_t) ( f1 / f_Scale); - const SData_t _f2 = (SData_t) ( f2 / f_Scale); - const SData_t _f3 = (SData_t) (fOffset / f_Scale); - - const SData_t c = (SData_t) (fIFOut - fHalf_IFBW) / (SData_t) f_Scale; - const SData_t d = (SData_t) ((fIFOut + fHalf_IFBW) / f_Scale); - const SData_t f = (SData_t) (fHalf_ZIFBW / f_Scale); - - SData_t ma, mb, mc, md, me, mf; - - SData_t fp_ = 0; - SData_t fm_ = 0; - SData_t n; - - - /* - ** If the other tuner does not have an LO frequency defined, - ** assume that we cannot interfere with it - */ - if (f2 == 0) - return 0; - - - /* Check out all multiples of f1 from -nMaxH to +nMaxH */ - for (n = -(SData_t)nMaxH; n <= (SData_t)nMaxH; ++n) - { - const SData_t nf1 = n*_f1; - md = (_f3 + d - nf1) / _f2; - - /* If # f2 harmonics > nMaxH, then no spurs present */ - if (md <= -(SData_t) nMaxH ) - break; - - ma = (_f3 - d - nf1) / _f2; - if ((ma == md) || (ma >= (SData_t) (nMaxH))) - continue; - - mc = (_f3 + c - nf1) / _f2; - if (mc != md) - { - const SData_t m = (n<0) ? md : mc; - const SData_t fspur = (nf1 + m*_f2 - _f3); - const SData_t den = (bIsMyOutput ? n - 1 : n); - if (den == 0) - { - fp_ = (d - fspur)* f_Scale; - fm_ = (fspur - c)* f_Scale; - } - else - { - fp_ = (SData_t) RoundAwayFromZero((d - fspur)* f_Scale, den); - fm_ = (SData_t) RoundAwayFromZero((fspur - c)* f_Scale, den); - } - if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) - { - bSpurFound = 1; - break; - } - } - - /* Location of Zero-IF-spur to be checked */ - mf = (_f3 + f - nf1) / _f2; - me = (_f3 - f - nf1) / _f2; - if (me != mf) - { - const SData_t m = (n<0) ? mf : me; - const SData_t fspur = (nf1 + m*_f2 - _f3); - const SData_t den = (bIsMyOutput ? n - 1 : n); - if (den == 0) - { - fp_ = (d - fspur)* f_Scale; - fm_ = (fspur - c)* f_Scale; - } - else - { - fp_ = (SData_t) RoundAwayFromZero((f - fspur)* f_Scale, den); - fm_ = (SData_t) RoundAwayFromZero((fspur + f)* f_Scale, den); - } - if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) - { - bSpurFound = 1; - break; - } - } - - mb = (_f3 - c - nf1) / _f2; - if (ma != mb) - { - const SData_t m = (n<0) ? mb : ma; - const SData_t fspur = (nf1 + m*_f2 - _f3); - const SData_t den = (bIsMyOutput ? n - 1 : n); - if (den == 0) - { - fp_ = (d - fspur)* f_Scale; - fm_ = (fspur - c)* f_Scale; - } - else - { - fp_ = (SData_t) RoundAwayFromZero((-c - fspur)* f_Scale, den); - fm_ = (SData_t) RoundAwayFromZero((fspur +d)* f_Scale, den); - } - if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) - { - bSpurFound = 1; - break; - } - } - } - - /* - ** Verify that fm & fp are both positive - ** Add one to ensure next 1st IF choice is not right on the edge - */ - if (fp_ < 0) - { - *fp = -fm_ + 1; - *fm = -fp_ + 1; - } - else if (fp_ > 0) - { - *fp = fp_ + 1; - *fm = fm_ + 1; - } - else - { - *fp = 1; - *fm = abs(fm_) + 1; - } - - return bSpurFound; -} -#endif - -/**************************************************************************** -** -** Name: IsSpurInBand -** -** Description: Checks to see if a spur will be present within the IF's -** bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW) -** -** ma mb mc md -** <--+-+-+-------------------+-------------------+-+-+--> -** | ^ 0 ^ | -** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^ -** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2 -** -** Note that some equations are doubled to prevent round-off -** problems when calculating fIFBW/2 -** -** Parameters: pAS_Info - Avoid Spurs information block -** fm - If spur, amount f_IF1 has to move negative -** fp - If spur, amount f_IF1 has to move positive -** -** Global: None -** -** Returns: 1 if an LO spur would be present, otherwise 0. -** -** Dependencies: None. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** N/A 11-28-2002 DAD Implemented algorithm from applied patent -** -****************************************************************************/ -static UData_t IsSpurInBand(struct MT2063_AvoidSpursData_t* pAS_Info, - UData_t* fm, - UData_t* fp) -{ - /* - ** Calculate LO frequency settings. - */ - UData_t n, n0; - const UData_t f_LO1 = pAS_Info->f_LO1; - const UData_t f_LO2 = pAS_Info->f_LO2; - const UData_t d = pAS_Info->f_out + pAS_Info->f_out_bw/2; - const UData_t c = d - pAS_Info->f_out_bw; - const UData_t f = pAS_Info->f_zif_bw/2; - const UData_t f_Scale = (f_LO1 / (MAX_UDATA/2 / pAS_Info->maxH1)) + 1; - SData_t f_nsLO1, f_nsLO2; - SData_t f_Spur; - UData_t ma, mb, mc, md, me, mf; - UData_t lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs; -#if MT2063_TUNER_CNT > 1 - UData_t index; - - struct MT2063_AvoidSpursData_t *adj; -#endif - *fm = 0; - - /* - ** For each edge (d, c & f), calculate a scale, based on the gcd - ** of f_LO1, f_LO2 and the edge value. Use the larger of this - ** gcd-based scale factor or f_Scale. - */ - lo_gcd = MT2063_gcd(f_LO1, f_LO2); - gd_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, d), f_Scale); - hgds = gd_Scale/2; - gc_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, c), f_Scale); - hgcs = gc_Scale/2; - gf_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, f), f_Scale); - hgfs = gf_Scale/2; - - n0 = uceil(f_LO2 - d, f_LO1 - f_LO2); - - /* Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic */ - for (n=n0; n<=pAS_Info->maxH1; ++n) - { - md = (n*((f_LO1+hgds)/gd_Scale) - ((d+hgds)/gd_Scale)) / ((f_LO2+hgds)/gd_Scale); - - /* If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present */ - if (md >= pAS_Info->maxH1) - break; - - ma = (n*((f_LO1+hgds)/gd_Scale) + ((d+hgds)/gd_Scale)) / ((f_LO2+hgds)/gd_Scale); - - /* If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic */ - if (md == ma) - continue; - - mc = (n*((f_LO1+hgcs)/gc_Scale) - ((c+hgcs)/gc_Scale)) / ((f_LO2+hgcs)/gc_Scale); - if (mc != md) - { - f_nsLO1 = (SData_t) (n*(f_LO1/gc_Scale)); - f_nsLO2 = (SData_t) (mc*(f_LO2/gc_Scale)); - f_Spur = (gc_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gc_Scale) - mc*(f_LO2 % gc_Scale); - - *fp = ((f_Spur - (SData_t) c) / (mc - n)) + 1; - *fm = (((SData_t) d - f_Spur) / (mc - n)) + 1; - return 1; - } - - /* Location of Zero-IF-spur to be checked */ - me = (n*((f_LO1+hgfs)/gf_Scale) + ((f+hgfs)/gf_Scale)) / ((f_LO2+hgfs)/gf_Scale); - mf = (n*((f_LO1+hgfs)/gf_Scale) - ((f+hgfs)/gf_Scale)) / ((f_LO2+hgfs)/gf_Scale); - if (me != mf) - { - f_nsLO1 = n*(f_LO1/gf_Scale); - f_nsLO2 = me*(f_LO2/gf_Scale); - f_Spur = (gf_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gf_Scale) - me*(f_LO2 % gf_Scale); - - *fp = ((f_Spur + (SData_t) f) / (me - n)) + 1; - *fm = (((SData_t) f - f_Spur) / (me - n)) + 1; - return 1; - } - - mb = (n*((f_LO1+hgcs)/gc_Scale) + ((c+hgcs)/gc_Scale)) / ((f_LO2+hgcs)/gc_Scale); - if (ma != mb) - { - f_nsLO1 = n*(f_LO1/gc_Scale); - f_nsLO2 = ma*(f_LO2/gc_Scale); - f_Spur = (gc_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gc_Scale) - ma*(f_LO2 % gc_Scale); - - *fp = (((SData_t) d + f_Spur) / (ma - n)) + 1; - *fm = (-(f_Spur + (SData_t) c) / (ma - n)) + 1; - return 1; - } - } - -#if MT2063_TUNER_CNT > 1 - /* If no spur found, see if there are more tuners on the same board */ - for (index = 0; index < TunerCount; ++index) - { - adj = TunerList[index]; - if (pAS_Info == adj) /* skip over our own data, don't process it */ - continue; - - /* Look for LO-related spurs from the adjacent tuner generated into my IF output */ - if (IsSpurInAdjTunerBand(1, /* check my IF output */ - pAS_Info->f_LO1, /* my fLO1 */ - adj->f_LO1, /* the other tuner's fLO1 */ - pAS_Info->f_LO2, /* my fLO2 */ - pAS_Info->f_out, /* my fOut */ - pAS_Info->f_out_bw, /* my output IF bandwidth */ - pAS_Info->f_zif_bw, /* my Zero-IF bandwidth */ - pAS_Info->maxH2, - fp, /* minimum amount to move LO's positive */ - fm)) /* miminum amount to move LO's negative */ - return 1; - /* Look for LO-related spurs from my tuner generated into the adjacent tuner's IF output */ - if (IsSpurInAdjTunerBand(0, /* check his IF output */ - pAS_Info->f_LO1, /* my fLO1 */ - adj->f_LO1, /* the other tuner's fLO1 */ - adj->f_LO2, /* the other tuner's fLO2 */ - adj->f_out, /* the other tuner's fOut */ - adj->f_out_bw, /* the other tuner's output IF bandwidth */ - pAS_Info->f_zif_bw, /* the other tuner's Zero-IF bandwidth */ - adj->maxH2, - fp, /* minimum amount to move LO's positive */ - fm)) /* miminum amount to move LO's negative */ - return 1; - } -#endif - /* No spurs found */ - return 0; -} - - -/***************************************************************************** -** -** Name: MT_AvoidSpurs -** -** Description: Main entry point to avoid spurs. -** Checks for existing spurs in present LO1, LO2 freqs -** and if present, chooses spur-free LO1, LO2 combination -** that tunes the same input/output frequencies. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0. -** -*****************************************************************************/ -UData_t MT2063_AvoidSpurs(Handle_t h, - struct MT2063_AvoidSpursData_t* pAS_Info) -{ - UData_t status = MT2063_OK; - UData_t fm, fp; /* restricted range on LO's */ - pAS_Info->bSpurAvoided = 0; - pAS_Info->nSpursFound = 0; - - if (pAS_Info->maxH1 == 0) - return MT2063_OK; - - /* - ** Avoid LO Generated Spurs - ** - ** Make sure that have no LO-related spurs within the IF output - ** bandwidth. - ** - ** If there is an LO spur in this band, start at the current IF1 frequency - ** and work out until we find a spur-free frequency or run up against the - ** 1st IF SAW band edge. Use temporary copies of fLO1 and fLO2 so that they - ** will be unchanged if a spur-free setting is not found. - */ - pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp); - if (pAS_Info->bSpurPresent) - { - UData_t zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in; /* current attempt at a 1st IF */ - UData_t zfLO1 = pAS_Info->f_LO1; /* current attempt at an LO1 freq */ - UData_t zfLO2 = pAS_Info->f_LO2; /* current attempt at an LO2 freq */ - UData_t delta_IF1; - UData_t new_IF1; - - /* - ** Spur was found, attempt to find a spur-free 1st IF - */ - do - { - pAS_Info->nSpursFound++; - - /* Raise f_IF1_upper, if needed */ - MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp); - - /* Choose next IF1 that is closest to f_IF1_CENTER */ - new_IF1 = MT2063_ChooseFirstIF(pAS_Info); - - if (new_IF1 > zfIF1) - { - pAS_Info->f_LO1 += (new_IF1 - zfIF1); - pAS_Info->f_LO2 += (new_IF1 - zfIF1); - } - else - { - pAS_Info->f_LO1 -= (zfIF1 - new_IF1); - pAS_Info->f_LO2 -= (zfIF1 - new_IF1); - } - zfIF1 = new_IF1; - - if (zfIF1 > pAS_Info->f_if1_Center) - delta_IF1 = zfIF1 - pAS_Info->f_if1_Center; - else - delta_IF1 = pAS_Info->f_if1_Center - zfIF1; - } - /* - ** Continue while the new 1st IF is still within the 1st IF bandwidth - ** and there is a spur in the band (again) - */ - while ((2*delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && - (pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp))); - - /* - ** Use the LO-spur free values found. If the search went all the way to - ** the 1st IF band edge and always found spurs, just leave the original - ** choice. It's as "good" as any other. - */ - if (pAS_Info->bSpurPresent == 1) - { - status |= MT2063_SPUR_PRESENT_ERR; - pAS_Info->f_LO1 = zfLO1; - pAS_Info->f_LO2 = zfLO2; - } - else - pAS_Info->bSpurAvoided = 1; - } - - status |= ((pAS_Info->nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK); - - return (status); -} - - -UData_t MT2063_AvoidSpursVersion(void) -{ - return (MT2063_SPUR_VERSION); -} -//end of mt2063_spuravoid.c -//================================================================= -//################################################################# -//================================================================= - - -/* -** The expected version of MT_AvoidSpursData_t -** If the version is different, an updated file is needed from Microtune -*/ -/* Expecting version 1.21 of the Spur Avoidance API */ -#define EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION 010201 - -#if MT2063_AVOID_SPURS_INFO_VERSION < EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION -#error Contact Microtune for a newer version of MT_SpurAvoid.c -#elif MT2063_AVOID_SPURS_INFO_VERSION > EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION -#error Contact Microtune for a newer version of mt2063.c -#endif - -#ifndef MT2063_CNT -#error You must define MT2063_CNT in the "mt_userdef.h" file -#endif - - -typedef enum -{ - MT2063_SET_ATTEN, - MT2063_INCR_ATTEN, - MT2063_DECR_ATTEN -} MT2063_ATTEN_CNTL_MODE; - - -//#define TUNER_MT2063_OPTIMIZATION -/* -** Constants used by the tuning algorithm -*/ -#define MT2063_REF_FREQ (16000000UL) /* Reference oscillator Frequency (in Hz) */ -#define MT2063_IF1_BW (22000000UL) /* The IF1 filter bandwidth (in Hz) */ -#define MT2063_TUNE_STEP_SIZE (50000UL) /* Tune in steps of 50 kHz */ -#define MT2063_SPUR_STEP_HZ (250000UL) /* Step size (in Hz) to move IF1 when avoiding spurs */ -#define MT2063_ZIF_BW (2000000UL) /* Zero-IF spur-free bandwidth (in Hz) */ -#define MT2063_MAX_HARMONICS_1 (15UL) /* Highest intra-tuner LO Spur Harmonic to be avoided */ -#define MT2063_MAX_HARMONICS_2 (5UL) /* Highest inter-tuner LO Spur Harmonic to be avoided */ -#define MT2063_MIN_LO_SEP (1000000UL) /* Minimum inter-tuner LO frequency separation */ -#define MT2063_LO1_FRACN_AVOID (0UL) /* LO1 FracN numerator avoid region (in Hz) */ -#define MT2063_LO2_FRACN_AVOID (199999UL) /* LO2 FracN numerator avoid region (in Hz) */ -#define MT2063_MIN_FIN_FREQ (44000000UL) /* Minimum input frequency (in Hz) */ -#define MT2063_MAX_FIN_FREQ (1100000000UL) /* Maximum input frequency (in Hz) */ -#define MT2063_MIN_FOUT_FREQ (36000000UL) /* Minimum output frequency (in Hz) */ -#define MT2063_MAX_FOUT_FREQ (57000000UL) /* Maximum output frequency (in Hz) */ -#define MT2063_MIN_DNC_FREQ (1293000000UL) /* Minimum LO2 frequency (in Hz) */ -#define MT2063_MAX_DNC_FREQ (1614000000UL) /* Maximum LO2 frequency (in Hz) */ -#define MT2063_MIN_UPC_FREQ (1396000000UL) /* Minimum LO1 frequency (in Hz) */ -#define MT2063_MAX_UPC_FREQ (2750000000UL) /* Maximum LO1 frequency (in Hz) */ - - -/* -** Define the supported Part/Rev codes for the MT2063 -*/ -#define MT2063_B0 (0x9B) -#define MT2063_B1 (0x9C) -#define MT2063_B2 (0x9D) -#define MT2063_B3 (0x9E) - -/* -** The number of Tuner Registers -*/ -static const UData_t MT2063_Num_Registers = MT2063_REG_END_REGS; - - -#define USE_GLOBAL_TUNER 0 - -static UData_t nMT2063MaxTuners = MT2063_CNT; -static struct MT2063_Info_t MT2063_Info[MT2063_CNT]; -static struct MT2063_Info_t *MT2063_Avail[MT2063_CNT]; -static UData_t nMT2063OpenTuners = 0; - - -/* -** Constants for setting receiver modes. -** (6 modes defined at this time, enumerated by MT2063_RCVR_MODES) -** (DNC1GC & DNC2GC are the values, which are used, when the specific -** DNC Output is selected, the other is always off) -** -** If PAL-L or L' is received, set: -** MT2063_SetParam(hMT2063,MT2063_TAGC,1); -** -** --------------+---------------------------------------------- -** Mode 0 : | MT2063_CABLE_QAM -** Mode 1 : | MT2063_CABLE_ANALOG -** Mode 2 : | MT2063_OFFAIR_COFDM -** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS -** Mode 4 : | MT2063_OFFAIR_ANALOG -** Mode 5 : | MT2063_OFFAIR_8VSB -** --------------+----+----+----+----+-----+-----+-------------- -** Mode | 0 | 1 | 2 | 3 | 4 | 5 | -** --------------+----+----+----+----+-----+-----+ -** -** -*/ -static const U8Data RFAGCEN[] = { 0, 0, 0, 0, 0, 0 }; -static const U8Data LNARIN[] = { 0, 0, 3, 3, 3, 3 }; -static const U8Data FIFFQEN[] = { 1, 1, 1, 1, 1, 1 }; -static const U8Data FIFFQ[] = { 0, 0, 0, 0, 0, 0 }; -static const U8Data DNC1GC[] = { 0, 0, 0, 0, 0, 0 }; -static const U8Data DNC2GC[] = { 0, 0, 0, 0, 0, 0 }; -static const U8Data ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 }; -static const U8Data LNATGT[] = { 44, 43, 43, 43, 43, 43 }; -static const U8Data RFOVDIS[] = { 0, 0, 0, 0, 0, 0 }; -static const U8Data ACRFMAX[] = { 31, 31, 31, 31, 31, 31 }; -static const U8Data PD1TGT[] = { 36, 36, 38, 38, 36, 38 }; -static const U8Data FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 }; -static const U8Data ACFIFMAX[] = { 29, 29, 29, 29, 29, 29 }; -static const U8Data PD2TGT[] = { 40, 33, 38, 42, 30, 38 }; - -/* -** Local Function Prototypes - not available for external access. -*/ - -/* Forward declaration(s): */ -static UData_t MT2063_CalcLO1Mult(UData_t *Div, UData_t *FracN, UData_t f_LO, UData_t f_LO_Step, UData_t f_Ref); -static UData_t MT2063_CalcLO2Mult(UData_t *Div, UData_t *FracN, UData_t f_LO, UData_t f_LO_Step, UData_t f_Ref); -static UData_t MT2063_fLO_FractionalTerm(UData_t f_ref, UData_t num, UData_t denom); - - -/****************************************************************************** -** -** Name: MT2063_Open -** -** Description: Initialize the tuner's register values. -** -** Parameters: MT2063_Addr - Serial bus address of the tuner. -** hMT2063 - Tuner handle passed back. -** hUserData - User-defined data, if needed for the -** MT_ReadSub() & MT_WriteSub functions. -** -** Returns: status: -** MT_OK - No errors -** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch -** MT_TUNER_INIT_ERR - Tuner initialization failed -** MT_COMM_ERR - Serial bus communications error -** MT_ARG_NULL - Null pointer argument passed -** MT_TUNER_CNT_ERR - Too many tuners open -** -** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus -** MT_WriteSub - Write byte(s) of data to the two-wire bus -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -******************************************************************************/ -UData_t MT2063_Open(UData_t MT2063_Addr, - Handle_t* hMT2063, - Handle_t hUserData) -{ - UData_t status = MT2063_OK; /* Status to be returned. */ - SData_t i; - struct MT2063_Info_t* pInfo = NULL; - struct dvb_frontend *fe= (struct dvb_frontend *)hUserData; - struct mt2063_state *state = fe->tuner_priv; - - /* Check the argument before using */ - if (hMT2063 == NULL) - { - return MT2063_ARG_NULL; - } - - /* Default tuner handle to NULL. If successful, it will be reassigned */ - -#if USE_GLOBAL_TUNER - *hMT2063 = NULL; - - /* - ** If this is our first tuner, initialize the address fields and - ** the list of available control blocks. - */ - if (nMT2063OpenTuners == 0) - { - for (i=MT2063_CNT-1; i>=0; i--) - { - MT2063_Info[i].handle = NULL; - MT2063_Info[i].address = MAX_UDATA; - MT2063_Info[i].rcvr_mode = MT2063_CABLE_QAM; - MT2063_Info[i].hUserData = NULL; - MT2063_Avail[i] = &MT2063_Info[i]; - } - } - - /* - ** Look for an existing MT2063_State_t entry with this address. - */ - for (i=MT2063_CNT-1; i>=0; i--) - { - /* - ** If an open'ed handle provided, we'll re-initialize that structure. - ** - ** We recognize an open tuner because the address and hUserData are - ** the same as one that has already been opened - */ - if ((MT2063_Info[i].address == MT2063_Addr) && - (MT2063_Info[i].hUserData == hUserData)) - { - pInfo = &MT2063_Info[i]; - break; - } - } - - /* If not found, choose an empty spot. */ - if (pInfo == NULL) - { - /* Check to see that we're not over-allocating */ - if (nMT2063OpenTuners == MT2063_CNT) - { - return MT2063_TUNER_CNT_ERR; - } - /* Use the next available block from the list */ - pInfo = MT2063_Avail[nMT2063OpenTuners]; - nMT2063OpenTuners++; - } -#else - if (state->MT2063_init==FALSE) - { - pInfo = kzalloc(sizeof (struct MT2063_Info_t), GFP_KERNEL); - if (pInfo == NULL) - { - return MT2063_TUNER_OPEN_ERR; - } - pInfo->handle = NULL; - pInfo->address = MAX_UDATA; - pInfo->rcvr_mode = MT2063_CABLE_QAM; - pInfo->hUserData = NULL; - } - else - { - pInfo = *hMT2063; - } -#endif - - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_RegisterTuner(&pInfo->AS_Data); - } - - if (MT2063_NO_ERROR(status)) - { - pInfo->handle = (Handle_t) pInfo; - - pInfo->hUserData = hUserData; - pInfo->address = MT2063_Addr; - pInfo->rcvr_mode = MT2063_CABLE_QAM; - status |= MT2063_ReInit((Handle_t) pInfo); - } - - if (MT2063_IS_ERROR(status)) - /* MT2063_Close handles the un-registration of the tuner */ - MT2063_Close((Handle_t) pInfo); - else - { - state->MT2063_init = TRUE; - *hMT2063 = pInfo->handle; - - } - - return (status); -} - - -static UData_t MT2063_IsValidHandle(struct MT2063_Info_t* handle) -{ - return ((handle != NULL) && (handle->handle == handle)) ? 1 : 0; -} - - -/****************************************************************************** -** -** Name: MT2063_Close -** -** Description: Release the handle to the tuner. -** -** Parameters: hMT2063 - Handle to the MT2063 tuner -** -** Returns: status: -** MT_OK - No errors -** MT_INV_HANDLE - Invalid tuner handle -** -** Dependencies: mt_errordef.h - definition of error codes -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -******************************************************************************/ -UData_t MT2063_Close(Handle_t hMT2063) -{ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) hMT2063; - - if (!MT2063_IsValidHandle(pInfo)) - return MT2063_INV_HANDLE; - - /* Unregister tuner with SpurAvoidance routines (if needed) */ - MT2063_UnRegisterTuner(&pInfo->AS_Data); - /* Now remove the tuner from our own list of tuners */ - pInfo->handle = NULL; - pInfo->address = MAX_UDATA; - pInfo->hUserData = NULL; - #if USE_GLOBAL_TUNER - nMT2063OpenTuners--; - MT2063_Avail[nMT2063OpenTuners] = pInfo; /* Return control block to available list */ - #else - //kfree(pInfo); - //pInfo = NULL; - #endif - return MT2063_OK; -} - - -/****************************************************************************** -** -** Name: MT2063_GetGPIO -** -** Description: Get the current MT2063 GPIO value. -** -** Parameters: h - Open handle to the tuner (from MT2063_Open). -** gpio_id - Selects GPIO0, GPIO1 or GPIO2 -** attr - Selects input readback, I/O direction or -** output value -** *value - current setting of GPIO pin -** -** Usage: status = MT2063_GetGPIO(hMT2063, MT2063_GPIO_OUT, &value); -** -** Returns: status: -** MT_OK - No errors -** MT_COMM_ERR - Serial bus communications error -** MT_INV_HANDLE - Invalid tuner handle -** MT_ARG_NULL - Null pointer argument passed -** -** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -******************************************************************************/ -UData_t MT2063_GetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id, - enum MT2063_GPIO_Attr attr, - UData_t* value) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - U8Data regno; - SData_t shift; - static U8Data GPIOreg[3] = {MT2063_REG_RF_STATUS, MT2063_REG_FIF_OV, MT2063_REG_RF_OV}; - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - if (MT2063_IsValidHandle(pInfo) == 0) - return MT2063_INV_HANDLE; - - if (value == NULL) - return MT2063_ARG_NULL; - - regno = GPIOreg[attr]; - - /* We'll read the register just in case the write didn't work last time */ - status = MT2063_ReadSub(pInfo->hUserData, pInfo->address, regno, &pInfo->reg[regno], 1); - - shift = (gpio_id - MT2063_GPIO0 + 5); - *value = (pInfo->reg[regno] >> shift) & 1; - - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_GetLocked -** -** Description: Checks to see if LO1 and LO2 are locked. -** -** Parameters: h - Open handle to the tuner (from MT2063_Open). -** -** Returns: status: -** MT_OK - No errors -** MT_UPC_UNLOCK - Upconverter PLL unlocked -** MT_DNC_UNLOCK - Downconverter PLL unlocked -** MT_COMM_ERR - Serial bus communications error -** MT_INV_HANDLE - Invalid tuner handle -** -** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus -** MT_Sleep - Delay execution for x milliseconds -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -****************************************************************************/ -UData_t MT2063_GetLocked(Handle_t h) -{ - const UData_t nMaxWait = 100; /* wait a maximum of 100 msec */ - const UData_t nPollRate = 2; /* poll status bits every 2 ms */ - const UData_t nMaxLoops = nMaxWait / nPollRate; - const U8Data LO1LK = 0x80; - U8Data LO2LK = 0x08; - UData_t status = MT2063_OK; /* Status to be returned */ - UData_t nDelays = 0; - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - if (MT2063_IsValidHandle(pInfo) == 0) - return MT2063_INV_HANDLE; - - /* LO2 Lock bit was in a different place for B0 version */ - if (pInfo->tuner_id == MT2063_B0) - LO2LK = 0x40; - - do - { - status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO_STATUS, &pInfo->reg[MT2063_REG_LO_STATUS], 1); - - if (MT2063_IS_ERROR(status)) - return (status); - - if ((pInfo->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) == (LO1LK | LO2LK)) - { - return (status); - } - MT2063_Sleep(pInfo->hUserData, nPollRate); /* Wait between retries */ - } - while (++nDelays < nMaxLoops); - - if ((pInfo->reg[MT2063_REG_LO_STATUS] & LO1LK) == 0x00) - status |= MT2063_UPC_UNLOCK; - if ((pInfo->reg[MT2063_REG_LO_STATUS] & LO2LK) == 0x00) - status |= MT2063_DNC_UNLOCK; - - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_GetParam -** -** Description: Gets a tuning algorithm parameter. -** -** This function provides access to the internals of the -** tuning algorithm - mostly for testing purposes. -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** param - Tuning algorithm parameter -** (see enum MT2063_Param) -** pValue - ptr to returned value -** -** param Description -** ---------------------- -------------------------------- -** MT2063_IC_ADDR Serial Bus address of this tuner -** MT2063_MAX_OPEN Max # of MT2063's allowed open -** MT2063_NUM_OPEN # of MT2063's open -** MT2063_SRO_FREQ crystal frequency -** MT2063_STEPSIZE minimum tuning step size -** MT2063_INPUT_FREQ input center frequency -** MT2063_LO1_FREQ LO1 Frequency -** MT2063_LO1_STEPSIZE LO1 minimum step size -** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region -** MT2063_IF1_ACTUAL Current 1st IF in use -** MT2063_IF1_REQUEST Requested 1st IF -** MT2063_IF1_CENTER Center of 1st IF SAW filter -** MT2063_IF1_BW Bandwidth of 1st IF SAW filter -** MT2063_ZIF_BW zero-IF bandwidth -** MT2063_LO2_FREQ LO2 Frequency -** MT2063_LO2_STEPSIZE LO2 minimum step size -** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region -** MT2063_OUTPUT_FREQ output center frequency -** MT2063_OUTPUT_BW output bandwidth -** MT2063_LO_SEPARATION min inter-tuner LO separation -** MT2063_AS_ALG ID of avoid-spurs algorithm in use -** MT2063_MAX_HARM1 max # of intra-tuner harmonics -** MT2063_MAX_HARM2 max # of inter-tuner harmonics -** MT2063_EXCL_ZONES # of 1st IF exclusion zones -** MT2063_NUM_SPURS # of spurs found/avoided -** MT2063_SPUR_AVOIDED >0 spurs avoided -** MT2063_SPUR_PRESENT >0 spurs in output (mathematically) -** MT2063_RCVR_MODE Predefined modes. -** MT2063_ACLNA LNA attenuator gain code -** MT2063_ACRF RF attenuator gain code -** MT2063_ACFIF FIF attenuator gain code -** MT2063_ACLNA_MAX LNA attenuator limit -** MT2063_ACRF_MAX RF attenuator limit -** MT2063_ACFIF_MAX FIF attenuator limit -** MT2063_PD1 Actual value of PD1 -** MT2063_PD2 Actual value of PD2 -** MT2063_DNC_OUTPUT_ENABLE DNC output selection -** MT2063_VGAGC VGA gain code -** MT2063_VGAOI VGA output current -** MT2063_TAGC TAGC setting -** MT2063_AMPGC AMP gain code -** MT2063_AVOID_DECT Avoid DECT Frequencies -** MT2063_CTFILT_SW Cleartune filter selection -** -** Usage: status |= MT2063_GetParam(hMT2063, -** MT2063_IF1_ACTUAL, -** &f_IF1_Actual); -** -** Returns: status: -** MT_OK - No errors -** MT_INV_HANDLE - Invalid tuner handle -** MT_ARG_NULL - Null pointer argument passed -** MT_ARG_RANGE - Invalid parameter requested -** -** Dependencies: USERS MUST CALL MT2063_Open() FIRST! -** -** See Also: MT2063_SetParam, MT2063_Open -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ -** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC -** 173 M 01-23-2008 RSK Ver 1.12: Read LO1C and LO2C registers from HW -** in GetParam. -** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT -** Split SetParam up to ACLNA / ACLNA_MAX -** removed ACLNA_INRC/DECR (+RF & FIF) -** removed GCUAUTO / BYPATNDN/UP -** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. -** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. -** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW -** -****************************************************************************/ -UData_t MT2063_GetParam(Handle_t h, - enum MT2063_Param param, - UData_t* pValue) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - UData_t Div; - UData_t Num; - - if (pValue == NULL) - status |= MT2063_ARG_NULL; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - status |= MT2063_INV_HANDLE; - - if (MT2063_NO_ERROR(status)) - { - switch (param) - { - /* Serial Bus address of this tuner */ - case MT2063_IC_ADDR: - *pValue = pInfo->address; - break; - - /* Max # of MT2063's allowed to be open */ - case MT2063_MAX_OPEN: - *pValue = nMT2063MaxTuners; - break; - - /* # of MT2063's open */ - case MT2063_NUM_OPEN: - *pValue = nMT2063OpenTuners; - break; - - /* crystal frequency */ - case MT2063_SRO_FREQ: - *pValue = pInfo->AS_Data.f_ref; - break; - - /* minimum tuning step size */ - case MT2063_STEPSIZE: - *pValue = pInfo->AS_Data.f_LO2_Step; - break; - - /* input center frequency */ - case MT2063_INPUT_FREQ: - *pValue = pInfo->AS_Data.f_in; - break; - - /* LO1 Frequency */ - case MT2063_LO1_FREQ: - { - /* read the actual tuner register values for LO1C_1 and LO1C_2 */ - status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1C_1, &pInfo->reg[MT2063_REG_LO1C_1], 2); - Div = pInfo->reg[MT2063_REG_LO1C_1]; - Num = pInfo->reg[MT2063_REG_LO1C_2] & 0x3F; - pInfo->AS_Data.f_LO1 = (pInfo->AS_Data.f_ref * Div) + MT2063_fLO_FractionalTerm(pInfo->AS_Data.f_ref, Num, 64); - } - *pValue = pInfo->AS_Data.f_LO1; - break; - - /* LO1 minimum step size */ - case MT2063_LO1_STEPSIZE: - *pValue = pInfo->AS_Data.f_LO1_Step; - break; - - /* LO1 FracN keep-out region */ - case MT2063_LO1_FRACN_AVOID_PARAM: - *pValue = pInfo->AS_Data.f_LO1_FracN_Avoid; - break; - - /* Current 1st IF in use */ - case MT2063_IF1_ACTUAL: - *pValue = pInfo->f_IF1_actual; - break; - - /* Requested 1st IF */ - case MT2063_IF1_REQUEST: - *pValue = pInfo->AS_Data.f_if1_Request; - break; - - /* Center of 1st IF SAW filter */ - case MT2063_IF1_CENTER: - *pValue = pInfo->AS_Data.f_if1_Center; - break; - - /* Bandwidth of 1st IF SAW filter */ - case MT2063_IF1_BW: - *pValue = pInfo->AS_Data.f_if1_bw; - break; - - /* zero-IF bandwidth */ - case MT2063_ZIF_BW: - *pValue = pInfo->AS_Data.f_zif_bw; - break; - - /* LO2 Frequency */ - case MT2063_LO2_FREQ: - { - /* Read the actual tuner register values for LO2C_1, LO2C_2 and LO2C_3 */ - status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2C_1, &pInfo->reg[MT2063_REG_LO2C_1], 3); - Div = (pInfo->reg[MT2063_REG_LO2C_1] & 0xFE ) >> 1; - Num = ((pInfo->reg[MT2063_REG_LO2C_1] & 0x01 ) << 12) | (pInfo->reg[MT2063_REG_LO2C_2] << 4) | (pInfo->reg[MT2063_REG_LO2C_3] & 0x00F); - pInfo->AS_Data.f_LO2 = (pInfo->AS_Data.f_ref * Div) + MT2063_fLO_FractionalTerm(pInfo->AS_Data.f_ref, Num, 8191); - } - *pValue = pInfo->AS_Data.f_LO2; - break; - - /* LO2 minimum step size */ - case MT2063_LO2_STEPSIZE: - *pValue = pInfo->AS_Data.f_LO2_Step; - break; - - /* LO2 FracN keep-out region */ - case MT2063_LO2_FRACN_AVOID: - *pValue = pInfo->AS_Data.f_LO2_FracN_Avoid; - break; - - /* output center frequency */ - case MT2063_OUTPUT_FREQ: - *pValue = pInfo->AS_Data.f_out; - break; - - /* output bandwidth */ - case MT2063_OUTPUT_BW: - *pValue = pInfo->AS_Data.f_out_bw - 750000; - break; - - /* min inter-tuner LO separation */ - case MT2063_LO_SEPARATION: - *pValue = pInfo->AS_Data.f_min_LO_Separation; - break; - - /* ID of avoid-spurs algorithm in use */ - case MT2063_AS_ALG: - *pValue = pInfo->AS_Data.nAS_Algorithm; - break; - - /* max # of intra-tuner harmonics */ - case MT2063_MAX_HARM1: - *pValue = pInfo->AS_Data.maxH1; - break; - - /* max # of inter-tuner harmonics */ - case MT2063_MAX_HARM2: - *pValue = pInfo->AS_Data.maxH2; - break; - - /* # of 1st IF exclusion zones */ - case MT2063_EXCL_ZONES: - *pValue = pInfo->AS_Data.nZones; - break; - - /* # of spurs found/avoided */ - case MT2063_NUM_SPURS: - *pValue = pInfo->AS_Data.nSpursFound; - break; - - /* >0 spurs avoided */ - case MT2063_SPUR_AVOIDED: - *pValue = pInfo->AS_Data.bSpurAvoided; - break; - - /* >0 spurs in output (mathematically) */ - case MT2063_SPUR_PRESENT: - *pValue = pInfo->AS_Data.bSpurPresent; - break; - - /* Predefined receiver setup combination */ - case MT2063_RCVR_MODE: - *pValue = pInfo->rcvr_mode; - break; - - case MT2063_PD1: - case MT2063_PD2: - { - U8Data mask = (param == MT2063_PD1 ? 0x01 : 0x03); /* PD1 vs PD2 */ - U8Data orig = (pInfo->reg[MT2063_REG_BYP_CTRL]); - U8Data reg = (orig & 0xF1) | mask; /* Only set 3 bits (not 5) */ - int i; - - *pValue = 0; - - /* Initiate ADC output to reg 0x0A */ - if (reg != orig) - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_BYP_CTRL, ®, 1); - - if (MT2063_IS_ERROR(status)) - return (status); - - for (i=0; i<8; i++) { - status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_ADC_OUT, &pInfo->reg[MT2063_REG_ADC_OUT], 1); - - if (MT2063_NO_ERROR(status)) - *pValue += pInfo->reg[MT2063_REG_ADC_OUT]; - else - { - if( i ) *pValue /= i; - return (status); - } - } - *pValue /= 8; /* divide by number of reads */ - *pValue >>=2; /* only want 6 MSB's out of 8 */ - - /* Restore value of Register BYP_CTRL */ - if (reg != orig) - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_BYP_CTRL, &orig, 1); - } - break; - - /* Get LNA attenuator code */ - case MT2063_ACLNA: - { - U8Data val; - status |= MT2063_GetReg(pInfo, MT2063_REG_XO_STATUS, &val); - *pValue = val & 0x1f; - } - break; - - /* Get RF attenuator code */ - case MT2063_ACRF: - { - U8Data val; - status |= MT2063_GetReg(pInfo, MT2063_REG_RF_STATUS, &val); - *pValue = val & 0x1f; - } - break; - - /* Get FIF attenuator code */ - case MT2063_ACFIF: - { - U8Data val; - status |= MT2063_GetReg(pInfo, MT2063_REG_FIF_STATUS, &val); - *pValue = val & 0x1f; - } - break; - - /* Get LNA attenuator limit */ - case MT2063_ACLNA_MAX: - { - U8Data val; - status |= MT2063_GetReg(pInfo, MT2063_REG_LNA_OV, &val); - *pValue = val & 0x1f; - } - break; - - /* Get RF attenuator limit */ - case MT2063_ACRF_MAX: - { - U8Data val; - status |= MT2063_GetReg(pInfo, MT2063_REG_RF_OV, &val); - *pValue = val & 0x1f; - } - break; - - /* Get FIF attenuator limit */ - case MT2063_ACFIF_MAX: - { - U8Data val; - status |= MT2063_GetReg(pInfo, MT2063_REG_FIF_OV, &val); - *pValue = val & 0x1f; - } - break; - - /* Get current used DNC output */ - case MT2063_DNC_OUTPUT_ENABLE: - { - if ( (pInfo->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) /* if DNC1 is off */ - { - if ( (pInfo->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */ - *pValue = (UData_t)MT2063_DNC_NONE; - else - *pValue = (UData_t)MT2063_DNC_2; - } - else /* DNC1 is on */ - { - if ( (pInfo->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */ - *pValue = (UData_t)MT2063_DNC_1; - else - *pValue = (UData_t)MT2063_DNC_BOTH; - } - } - break; - - /* Get VGA Gain Code */ - case MT2063_VGAGC: - *pValue = ( (pInfo->reg[MT2063_REG_VGA_GAIN] & 0x0C) >> 2 ); - break; - - /* Get VGA bias current */ - case MT2063_VGAOI: - *pValue = (pInfo->reg[MT2063_REG_RSVD_31] & 0x07); - break; - - /* Get TAGC setting */ - case MT2063_TAGC: - *pValue = (pInfo->reg[MT2063_REG_RSVD_1E] & 0x03); - break; - - /* Get AMP Gain Code */ - case MT2063_AMPGC: - *pValue = (pInfo->reg[MT2063_REG_TEMP_SEL] & 0x03); - break; - - /* Avoid DECT Frequencies */ - case MT2063_AVOID_DECT: - *pValue = pInfo->AS_Data.avoidDECT; - break; - - /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ - case MT2063_CTFILT_SW: - *pValue = pInfo->ctfilt_sw; - break; - - case MT2063_EOP: - default: - status |= MT2063_ARG_RANGE; - } - } - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_GetReg -** -** Description: Gets an MT2063 register. -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** reg - MT2063 register/subaddress location -** *val - MT2063 register/subaddress value -** -** Returns: status: -** MT_OK - No errors -** MT_COMM_ERR - Serial bus communications error -** MT_INV_HANDLE - Invalid tuner handle -** MT_ARG_NULL - Null pointer argument passed -** MT_ARG_RANGE - Argument out of range -** -** Dependencies: USERS MUST CALL MT2063_Open() FIRST! -** -** Use this function if you need to read a register from -** the MT2063. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -****************************************************************************/ -UData_t MT2063_GetReg(Handle_t h, - U8Data reg, - U8Data* val) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - status |= MT2063_INV_HANDLE; - - if (val == NULL) - status |= MT2063_ARG_NULL; - - if (reg >= MT2063_REG_END_REGS) - status |= MT2063_ARG_RANGE; - - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, reg, &pInfo->reg[reg], 1); - if (MT2063_NO_ERROR(status)) - *val = pInfo->reg[reg]; - } - - return (status); -} - - -/****************************************************************************** -** -** Name: MT2063_GetTemp -** -** Description: Get the MT2063 Temperature register. -** -** Parameters: h - Open handle to the tuner (from MT2063_Open). -** *value - value read from the register -** -** Binary -** Value Returned Value Approx Temp -** --------------------------------------------- -** MT2063_T_0C 0000 0C -** MT2063_T_10C 0001 10C -** MT2063_T_20C 0010 20C -** MT2063_T_30C 0011 30C -** MT2063_T_40C 0100 40C -** MT2063_T_50C 0101 50C -** MT2063_T_60C 0110 60C -** MT2063_T_70C 0111 70C -** MT2063_T_80C 1000 80C -** MT2063_T_90C 1001 90C -** MT2063_T_100C 1010 100C -** MT2063_T_110C 1011 110C -** MT2063_T_120C 1100 120C -** MT2063_T_130C 1101 130C -** MT2063_T_140C 1110 140C -** MT2063_T_150C 1111 150C -** -** Returns: status: -** MT_OK - No errors -** MT_COMM_ERR - Serial bus communications error -** MT_INV_HANDLE - Invalid tuner handle -** MT_ARG_NULL - Null pointer argument passed -** MT_ARG_RANGE - Argument out of range -** -** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus -** MT_WriteSub - Write byte(s) of data to the two-wire bus -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -******************************************************************************/ -UData_t MT2063_GetTemp(Handle_t h, enum MT2063_Temperature* value) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - if (MT2063_IsValidHandle(pInfo) == 0) - return MT2063_INV_HANDLE; - - if (value == NULL) - return MT2063_ARG_NULL; - - if ((MT2063_NO_ERROR(status)) && ((pInfo->reg[MT2063_REG_TEMP_SEL] & 0xE0) != 0x00)) - { - pInfo->reg[MT2063_REG_TEMP_SEL] &= (0x1F); - status |= MT2063_WriteSub(pInfo->hUserData, - pInfo->address, - MT2063_REG_TEMP_SEL, - &pInfo->reg[MT2063_REG_TEMP_SEL], - 1); - } - - if (MT2063_NO_ERROR(status)) - status |= MT2063_ReadSub(pInfo->hUserData, - pInfo->address, - MT2063_REG_TEMP_STATUS, - &pInfo->reg[MT2063_REG_TEMP_STATUS], - 1); - - if (MT2063_NO_ERROR(status)) - *value = (enum MT2063_Temperature) (pInfo->reg[MT2063_REG_TEMP_STATUS] >> 4); - - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_GetUserData -** -** Description: Gets the user-defined data item. -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** -** Returns: status: -** MT_OK - No errors -** MT_INV_HANDLE - Invalid tuner handle -** MT_ARG_NULL - Null pointer argument passed -** -** Dependencies: USERS MUST CALL MT2063_Open() FIRST! -** -** The hUserData parameter is a user-specific argument -** that is stored internally with the other tuner- -** specific information. -** -** For example, if additional arguments are needed -** for the user to identify the device communicating -** with the tuner, this argument can be used to supply -** the necessary information. -** -** The hUserData parameter is initialized in the tuner's -** Open function to NULL. -** -** See Also: MT2063_Open -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -****************************************************************************/ -UData_t MT2063_GetUserData(Handle_t h, - Handle_t* hUserData) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - status = MT2063_INV_HANDLE; - - if (hUserData == NULL) - status |= MT2063_ARG_NULL; - - if (MT2063_NO_ERROR(status)) - *hUserData = pInfo->hUserData; - - return (status); -} - - - -/****************************************************************************** -** -** Name: MT2063_SetReceiverMode -** -** Description: Set the MT2063 receiver mode -** -** --------------+---------------------------------------------- -** Mode 0 : | MT2063_CABLE_QAM -** Mode 1 : | MT2063_CABLE_ANALOG -** Mode 2 : | MT2063_OFFAIR_COFDM -** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS -** Mode 4 : | MT2063_OFFAIR_ANALOG -** Mode 5 : | MT2063_OFFAIR_8VSB -** --------------+----+----+----+----+-----+-------------------- -** (DNC1GC & DNC2GC are the values, which are used, when the specific -** DNC Output is selected, the other is always off) -** -** |<---------- Mode -------------->| -** Reg Field | 0 | 1 | 2 | 3 | 4 | 5 | -** ------------+-----+-----+-----+-----+-----+-----+ -** RFAGCen | OFF | OFF | OFF | OFF | OFF | OFF -** LNARin | 0 | 0 | 3 | 3 | 3 | 3 -** FIFFQen | 1 | 1 | 1 | 1 | 1 | 1 -** FIFFq | 0 | 0 | 0 | 0 | 0 | 0 -** DNC1gc | 0 | 0 | 0 | 0 | 0 | 0 -** DNC2gc | 0 | 0 | 0 | 0 | 0 | 0 -** GCU Auto | 1 | 1 | 1 | 1 | 1 | 1 -** LNA max Atn | 31 | 31 | 31 | 31 | 31 | 31 -** LNA Target | 44 | 43 | 43 | 43 | 43 | 43 -** ign RF Ovl | 0 | 0 | 0 | 0 | 0 | 0 -** RF max Atn | 31 | 31 | 31 | 31 | 31 | 31 -** PD1 Target | 36 | 36 | 38 | 38 | 36 | 38 -** ign FIF Ovl | 0 | 0 | 0 | 0 | 0 | 0 -** FIF max Atn | 5 | 5 | 5 | 5 | 5 | 5 -** PD2 Target | 40 | 33 | 42 | 42 | 33 | 42 -** -** -** Parameters: pInfo - ptr to MT2063_Info_t structure -** Mode - desired reciever mode -** -** Usage: status = MT2063_SetReceiverMode(hMT2063, Mode); -** -** Returns: status: -** MT_OK - No errors -** MT_COMM_ERR - Serial bus communications error -** -** Dependencies: MT2063_SetReg - Write a byte of data to a HW register. -** Assumes that the tuner cache is valid. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** N/A 01-10-2007 PINZ Added additional GCU Settings, FIFF Calib will be triggered -** 155 10-01-2007 DAD Ver 1.06: Add receiver mode for SECAM positive -** modulation -** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) -** N/A 10-22-2007 PINZ Ver 1.07: Changed some Registers at init to have -** the same settings as with MT Launcher -** N/A 10-30-2007 PINZ Add SetParam VGAGC & VGAOI -** Add SetParam DNC_OUTPUT_ENABLE -** Removed VGAGC from receiver mode, -** default now 1 -** N/A 10-31-2007 PINZ Ver 1.08: Add SetParam TAGC, removed from rcvr-mode -** Add SetParam AMPGC, removed from rcvr-mode -** Corrected names of GCU values -** reorganized receiver modes, removed, -** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) -** Actualized Receiver-Mode values -** N/A 11-12-2007 PINZ Ver 1.09: Actualized Receiver-Mode values -** N/A 11-27-2007 PINZ Improved buffered writing -** 01-03-2008 PINZ Ver 1.10: Added a trigger of BYPATNUP for -** correct wakeup of the LNA after shutdown -** Set AFCsd = 1 as default -** Changed CAP1sel default -** 01-14-2008 PINZ Ver 1.11: Updated gain settings -** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT -** Split SetParam up to ACLNA / ACLNA_MAX -** removed ACLNA_INRC/DECR (+RF & FIF) -** removed GCUAUTO / BYPATNDN/UP -** -******************************************************************************/ -static UData_t MT2063_SetReceiverMode(struct MT2063_Info_t* pInfo, enum MT2063_RCVR_MODES Mode) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - U8Data val; - UData_t longval; - - - if (Mode >= MT2063_NUM_RCVR_MODES) - status = MT2063_ARG_RANGE; - - /* RFAGCen */ - if (MT2063_NO_ERROR(status)) - { - val = (pInfo->reg[MT2063_REG_PD1_TGT] & (U8Data)~0x40) | (RFAGCEN[Mode] ? 0x40 : 0x00); - if( pInfo->reg[MT2063_REG_PD1_TGT] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT, val); - } - } - - /* LNARin */ - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_SetParam(pInfo, MT2063_LNA_RIN, LNARIN[Mode]); - } - - /* FIFFQEN and FIFFQ */ - if (MT2063_NO_ERROR(status)) - { - val = (pInfo->reg[MT2063_REG_FIFF_CTRL2] & (U8Data)~0xF0) | (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4); - if( pInfo->reg[MT2063_REG_FIFF_CTRL2] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL2, val); - /* trigger FIFF calibration, needed after changing FIFFQ */ - val = (pInfo->reg[MT2063_REG_FIFF_CTRL] | (U8Data)0x01); - status |= MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL, val); - val = (pInfo->reg[MT2063_REG_FIFF_CTRL] & (U8Data)~0x01); - status |= MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL, val); - } - } - - /* DNC1GC & DNC2GC */ - status |= MT2063_GetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, &longval); - status |= MT2063_SetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, longval); - - /* acLNAmax */ - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_SetParam(pInfo, MT2063_ACLNA_MAX, ACLNAMAX[Mode]); - } - - /* LNATGT */ - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_SetParam(pInfo, MT2063_LNA_TGT, LNATGT[Mode]); - } - - /* ACRF */ - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_SetParam(pInfo, MT2063_ACRF_MAX, ACRFMAX[Mode]); - } - - /* PD1TGT */ - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_SetParam(pInfo, MT2063_PD1_TGT, PD1TGT[Mode]); - } - - /* FIFATN */ - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_SetParam(pInfo, MT2063_ACFIF_MAX, ACFIFMAX[Mode]); - } - - /* PD2TGT */ - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_SetParam(pInfo, MT2063_PD2_TGT, PD2TGT[Mode]); - } - - /* Ignore ATN Overload */ - if (MT2063_NO_ERROR(status)) - { - val = (pInfo->reg[MT2063_REG_LNA_TGT] & (U8Data)~0x80) | (RFOVDIS[Mode] ? 0x80 : 0x00); - if( pInfo->reg[MT2063_REG_LNA_TGT] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_LNA_TGT, val); - } - } - - /* Ignore FIF Overload */ - if (MT2063_NO_ERROR(status)) - { - val = (pInfo->reg[MT2063_REG_PD1_TGT] & (U8Data)~0x80) | (FIFOVDIS[Mode] ? 0x80 : 0x00); - if( pInfo->reg[MT2063_REG_PD1_TGT] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT, val); - } - } - - if (MT2063_NO_ERROR(status)) - pInfo->rcvr_mode = Mode; - - return (status); -} - - -/****************************************************************************** -** -** Name: MT2063_ReInit -** -** Description: Initialize the tuner's register values. -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** -** Returns: status: -** MT_OK - No errors -** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch -** MT_INV_HANDLE - Invalid tuner handle -** MT_COMM_ERR - Serial bus communications error -** -** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus -** MT_WriteSub - Write byte(s) of data to the two-wire bus -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** 148 09-04-2007 RSK Ver 1.02: Corrected logic of Reg 3B Reference -** 153 09-07-2007 RSK Ver 1.03: Lock Time improvements -** N/A 10-31-2007 PINZ Ver 1.08: Changed values suitable to rcvr-mode 0 -** N/A 11-12-2007 PINZ Ver 1.09: Changed values suitable to rcvr-mode 0 -** N/A 01-03-2007 PINZ Ver 1.10: Added AFCsd = 1 into defaults -** N/A 01-04-2007 PINZ Ver 1.10: Changed CAP1sel default -** 01-14-2008 PINZ Ver 1.11: Updated gain settings -** 03-18-2008 PINZ Ver 1.13: Added Support for B3 -** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. -** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW -** -******************************************************************************/ -UData_t MT2063_ReInit(Handle_t h) -{ - U8Data all_resets = 0xF0; /* reset/load bits */ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - U8Data *def; - - U8Data MT2063B0_defaults[] = { /* Reg, Value */ - 0x19, 0x05, - 0x1B, 0x1D, - 0x1C, 0x1F, - 0x1D, 0x0F, - 0x1E, 0x3F, - 0x1F, 0x0F, - 0x20, 0x3F, - 0x22, 0x21, - 0x23, 0x3F, - 0x24, 0x20, - 0x25, 0x3F, - 0x27, 0xEE, - 0x2C, 0x27, /* bit at 0x20 is cleared below */ - 0x30, 0x03, - 0x2C, 0x07, /* bit at 0x20 is cleared here */ - 0x2D, 0x87, - 0x2E, 0xAA, - 0x28, 0xE1, /* Set the FIFCrst bit here */ - 0x28, 0xE0, /* Clear the FIFCrst bit here */ - 0x00 }; - - /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */ - U8Data MT2063B1_defaults[] = { /* Reg, Value */ - 0x05, 0xF0, - 0x11, 0x10, /* New Enable AFCsd */ - 0x19, 0x05, - 0x1A, 0x6C, - 0x1B, 0x24, - 0x1C, 0x28, - 0x1D, 0x8F, - 0x1E, 0x14, - 0x1F, 0x8F, - 0x20, 0x57, - 0x22, 0x21, /* New - ver 1.03 */ - 0x23, 0x3C, /* New - ver 1.10 */ - 0x24, 0x20, /* New - ver 1.03 */ - 0x2C, 0x24, /* bit at 0x20 is cleared below */ - 0x2D, 0x87, /* FIFFQ=0 */ - 0x2F, 0xF3, - 0x30, 0x0C, /* New - ver 1.11 */ - 0x31, 0x1B, /* New - ver 1.11 */ - 0x2C, 0x04, /* bit at 0x20 is cleared here */ - 0x28, 0xE1, /* Set the FIFCrst bit here */ - 0x28, 0xE0, /* Clear the FIFCrst bit here */ - 0x00 }; - - /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */ - U8Data MT2063B3_defaults[] = { /* Reg, Value */ - 0x05, 0xF0, - 0x19, 0x3D, - 0x2C, 0x24, /* bit at 0x20 is cleared below */ - 0x2C, 0x04, /* bit at 0x20 is cleared here */ - 0x28, 0xE1, /* Set the FIFCrst bit here */ - 0x28, 0xE0, /* Clear the FIFCrst bit here */ - 0x00 }; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - status |= MT2063_INV_HANDLE; - - /* Read the Part/Rev code from the tuner */ - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_PART_REV, pInfo->reg, 1); - } - - if (MT2063_NO_ERROR(status) /* Check the part/rev code */ - && ( (pInfo->reg[MT2063_REG_PART_REV] != MT2063_B0) /* MT2063 B0 */ - && (pInfo->reg[MT2063_REG_PART_REV] != MT2063_B1) /* MT2063 B1 */ - && (pInfo->reg[MT2063_REG_PART_REV] != MT2063_B3))) /* MT2063 B3 */ - status |= MT2063_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */ - - /* Read the Part/Rev code (2nd byte) from the tuner */ - if (MT2063_NO_ERROR(status)) - status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_RSVD_3B, &pInfo->reg[MT2063_REG_RSVD_3B], 1); - - if (MT2063_NO_ERROR(status) /* Check the 2nd part/rev code */ - && ((pInfo->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) /* b7 != 0 ==> NOT MT2063 */ - status |= MT2063_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */ - - /* Reset the tuner */ - if (MT2063_NO_ERROR(status)) - status |= MT2063_WriteSub(pInfo->hUserData, - pInfo->address, - MT2063_REG_LO2CQ_3, - &all_resets, - 1); - - /* change all of the default values that vary from the HW reset values */ - /* def = (pInfo->reg[PART_REV] == MT2063_B0) ? MT2063B0_defaults : MT2063B1_defaults; */ - switch (pInfo->reg[MT2063_REG_PART_REV]) - { - case MT2063_B3 : - def = MT2063B3_defaults; - break; - - case MT2063_B1 : - def = MT2063B1_defaults; - break; - - case MT2063_B0 : - def = MT2063B0_defaults; - break; - - default : - status |= MT2063_TUNER_ID_ERR; - break; - } - - while (MT2063_NO_ERROR(status) && *def) - { - U8Data reg = *def++; - U8Data val = *def++; - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, 1); - } - - /* Wait for FIFF location to complete. */ - if (MT2063_NO_ERROR(status)) - { - UData_t FCRUN = 1; - SData_t maxReads = 10; - while (MT2063_NO_ERROR(status) && (FCRUN != 0) && (maxReads-- > 0)) - { - MT2063_Sleep(pInfo->hUserData, 2); - status |= MT2063_ReadSub(pInfo->hUserData, - pInfo->address, - MT2063_REG_XO_STATUS, - &pInfo->reg[MT2063_REG_XO_STATUS], - 1); - FCRUN = (pInfo->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6; - } - - if (FCRUN != 0) - status |= MT2063_TUNER_INIT_ERR | MT2063_TUNER_TIMEOUT; - - if (MT2063_NO_ERROR(status)) /* Re-read FIFFC value */ - status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_FIFFC, &pInfo->reg[MT2063_REG_FIFFC], 1); - } - - /* Read back all the registers from the tuner */ - if (MT2063_NO_ERROR(status)) - status |= MT2063_ReadSub(pInfo->hUserData, - pInfo->address, - MT2063_REG_PART_REV, - pInfo->reg, - MT2063_REG_END_REGS); - - if (MT2063_NO_ERROR(status)) - { - /* Initialize the tuner state. */ - pInfo->version = MT2063_VERSION; - pInfo->tuner_id = pInfo->reg[MT2063_REG_PART_REV]; - pInfo->AS_Data.f_ref = MT2063_REF_FREQ; - pInfo->AS_Data.f_if1_Center = (pInfo->AS_Data.f_ref / 8) * ((UData_t) pInfo->reg[MT2063_REG_FIFFC] + 640); - pInfo->AS_Data.f_if1_bw = MT2063_IF1_BW; - pInfo->AS_Data.f_out = 43750000UL; - pInfo->AS_Data.f_out_bw = 6750000UL; - pInfo->AS_Data.f_zif_bw = MT2063_ZIF_BW; - pInfo->AS_Data.f_LO1_Step = pInfo->AS_Data.f_ref / 64; - pInfo->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE; - pInfo->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1; - pInfo->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2; - pInfo->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP; - pInfo->AS_Data.f_if1_Request = pInfo->AS_Data.f_if1_Center; - pInfo->AS_Data.f_LO1 = 2181000000UL; - pInfo->AS_Data.f_LO2 = 1486249786UL; - pInfo->f_IF1_actual = pInfo->AS_Data.f_if1_Center; - pInfo->AS_Data.f_in = pInfo->AS_Data.f_LO1 - pInfo->f_IF1_actual; - pInfo->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID; - pInfo->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID; - pInfo->num_regs = MT2063_REG_END_REGS; - pInfo->AS_Data.avoidDECT = MT2063_AVOID_BOTH; - pInfo->ctfilt_sw = 0; - } - - if (MT2063_NO_ERROR(status)) - { - pInfo->CTFiltMax[ 0] = 69230000; - pInfo->CTFiltMax[ 1] = 105770000; - pInfo->CTFiltMax[ 2] = 140350000; - pInfo->CTFiltMax[ 3] = 177110000; - pInfo->CTFiltMax[ 4] = 212860000; - pInfo->CTFiltMax[ 5] = 241130000; - pInfo->CTFiltMax[ 6] = 274370000; - pInfo->CTFiltMax[ 7] = 309820000; - pInfo->CTFiltMax[ 8] = 342450000; - pInfo->CTFiltMax[ 9] = 378870000; - pInfo->CTFiltMax[10] = 416210000; - pInfo->CTFiltMax[11] = 456500000; - pInfo->CTFiltMax[12] = 495790000; - pInfo->CTFiltMax[13] = 534530000; - pInfo->CTFiltMax[14] = 572610000; - pInfo->CTFiltMax[15] = 598970000; - pInfo->CTFiltMax[16] = 635910000; - pInfo->CTFiltMax[17] = 672130000; - pInfo->CTFiltMax[18] = 714840000; - pInfo->CTFiltMax[19] = 739660000; - pInfo->CTFiltMax[20] = 770410000; - pInfo->CTFiltMax[21] = 814660000; - pInfo->CTFiltMax[22] = 846950000; - pInfo->CTFiltMax[23] = 867820000; - pInfo->CTFiltMax[24] = 915980000; - pInfo->CTFiltMax[25] = 947450000; - pInfo->CTFiltMax[26] = 983110000; - pInfo->CTFiltMax[27] = 1021630000; - pInfo->CTFiltMax[28] = 1061870000; - pInfo->CTFiltMax[29] = 1098330000; - pInfo->CTFiltMax[30] = 1138990000; - } - - /* - ** Fetch the FCU osc value and use it and the fRef value to - ** scale all of the Band Max values - */ - if (MT2063_NO_ERROR(status)) - { - UData_t fcu_osc; - UData_t i; - - pInfo->reg[MT2063_REG_CTUNE_CTRL] = 0x0A; - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_CTUNE_CTRL, &pInfo->reg[MT2063_REG_CTUNE_CTRL], 1); - /* Read the ClearTune filter calibration value */ - status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_FIFFC, &pInfo->reg[MT2063_REG_FIFFC], 1); - fcu_osc = pInfo->reg[MT2063_REG_FIFFC]; - - pInfo->reg[MT2063_REG_CTUNE_CTRL] = 0x00; - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_CTUNE_CTRL, &pInfo->reg[MT2063_REG_CTUNE_CTRL], 1); - - /* Adjust each of the values in the ClearTune filter cross-over table */ - for (i = 0; i < 31; i++) - { - pInfo->CTFiltMax[i] = (pInfo->CTFiltMax[i]/768) * (fcu_osc + 640); - } - } - - return (status); -} - - -/****************************************************************************** -** -** Name: MT2063_SetGPIO -** -** Description: Modify the MT2063 GPIO value. -** -** Parameters: h - Open handle to the tuner (from MT2063_Open). -** gpio_id - Selects GPIO0, GPIO1 or GPIO2 -** attr - Selects input readback, I/O direction or -** output value -** value - value to set GPIO pin 15, 14 or 19 -** -** Usage: status = MT2063_SetGPIO(hMT2063, MT2063_GPIO1, MT2063_GPIO_OUT, 1); -** -** Returns: status: -** MT_OK - No errors -** MT_COMM_ERR - Serial bus communications error -** MT_INV_HANDLE - Invalid tuner handle -** -** Dependencies: MT_WriteSub - Write byte(s) of data to the two-wire-bus -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -******************************************************************************/ -UData_t MT2063_SetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id, - enum MT2063_GPIO_Attr attr, - UData_t value) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - U8Data regno; - SData_t shift; - static U8Data GPIOreg[3] = {0x15, 0x19, 0x18}; - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - if (MT2063_IsValidHandle(pInfo) == 0) - return MT2063_INV_HANDLE; - - regno = GPIOreg[attr]; - - shift = (gpio_id - MT2063_GPIO0 + 5); - - if (value & 0x01) - pInfo->reg[regno] |= (0x01 << shift); - else - pInfo->reg[regno] &= ~(0x01 << shift); - status = MT2063_WriteSub(pInfo->hUserData, pInfo->address, regno, &pInfo->reg[regno], 1); - - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_SetParam -** -** Description: Sets a tuning algorithm parameter. -** -** This function provides access to the internals of the -** tuning algorithm. You can override many of the tuning -** algorithm defaults using this function. -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** param - Tuning algorithm parameter -** (see enum MT2063_Param) -** nValue - value to be set -** -** param Description -** ---------------------- -------------------------------- -** MT2063_SRO_FREQ crystal frequency -** MT2063_STEPSIZE minimum tuning step size -** MT2063_LO1_FREQ LO1 frequency -** MT2063_LO1_STEPSIZE LO1 minimum step size -** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region -** MT2063_IF1_REQUEST Requested 1st IF -** MT2063_ZIF_BW zero-IF bandwidth -** MT2063_LO2_FREQ LO2 frequency -** MT2063_LO2_STEPSIZE LO2 minimum step size -** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region -** MT2063_OUTPUT_FREQ output center frequency -** MT2063_OUTPUT_BW output bandwidth -** MT2063_LO_SEPARATION min inter-tuner LO separation -** MT2063_MAX_HARM1 max # of intra-tuner harmonics -** MT2063_MAX_HARM2 max # of inter-tuner harmonics -** MT2063_RCVR_MODE Predefined modes -** MT2063_LNA_RIN Set LNA Rin (*) -** MT2063_LNA_TGT Set target power level at LNA (*) -** MT2063_PD1_TGT Set target power level at PD1 (*) -** MT2063_PD2_TGT Set target power level at PD2 (*) -** MT2063_ACLNA_MAX LNA attenuator limit (*) -** MT2063_ACRF_MAX RF attenuator limit (*) -** MT2063_ACFIF_MAX FIF attenuator limit (*) -** MT2063_DNC_OUTPUT_ENABLE DNC output selection -** MT2063_VGAGC VGA gain code -** MT2063_VGAOI VGA output current -** MT2063_TAGC TAGC setting -** MT2063_AMPGC AMP gain code -** MT2063_AVOID_DECT Avoid DECT Frequencies -** MT2063_CTFILT_SW Cleartune filter selection -** -** (*) This parameter is set by MT2063_RCVR_MODE, do not call -** additionally. -** -** Usage: status |= MT2063_SetParam(hMT2063, -** MT2063_STEPSIZE, -** 50000); -** -** Returns: status: -** MT_OK - No errors -** MT_INV_HANDLE - Invalid tuner handle -** MT_ARG_NULL - Null pointer argument passed -** MT_ARG_RANGE - Invalid parameter requested -** or set value out of range -** or non-writable parameter -** -** Dependencies: USERS MUST CALL MT2063_Open() FIRST! -** -** See Also: MT2063_GetParam, MT2063_Open -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ -** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC -** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT -** Split SetParam up to ACLNA / ACLNA_MAX -** removed ACLNA_INRC/DECR (+RF & FIF) -** removed GCUAUTO / BYPATNDN/UP -** 175 I 06-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. -** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. -** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW -** -****************************************************************************/ -UData_t MT2063_SetParam(Handle_t h, - enum MT2063_Param param, - UData_t nValue) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - U8Data val=0; - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - status |= MT2063_INV_HANDLE; - - if (MT2063_NO_ERROR(status)) - { - switch (param) - { - /* crystal frequency */ - case MT2063_SRO_FREQ: - pInfo->AS_Data.f_ref = nValue; - pInfo->AS_Data.f_LO1_FracN_Avoid = 0; - pInfo->AS_Data.f_LO2_FracN_Avoid = nValue / 80 - 1; - pInfo->AS_Data.f_LO1_Step = nValue / 64; - pInfo->AS_Data.f_if1_Center = (pInfo->AS_Data.f_ref / 8) * (pInfo->reg[MT2063_REG_FIFFC] + 640); - break; - - /* minimum tuning step size */ - case MT2063_STEPSIZE: - pInfo->AS_Data.f_LO2_Step = nValue; - break; - - - /* LO1 frequency */ - case MT2063_LO1_FREQ: - { - /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */ - /* Capture the Divider and Numerator portions of other LO */ - U8Data tempLO2CQ[3]; - U8Data tempLO2C[3]; - U8Data tmpOneShot; - UData_t Div, FracN; - U8Data restore = 0; - - /* Buffer the queue for restoration later and get actual LO2 values. */ - status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_1, &(tempLO2CQ[0]), 3); - status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, MT2063_REG_LO2C_1, &(tempLO2C[0]), 3); - - /* clear the one-shot bits */ - tempLO2CQ[2] = tempLO2CQ[2] & 0x0F; - tempLO2C[2] = tempLO2C[2] & 0x0F; - - /* only write the queue values if they are different from the actual. */ - if( ( tempLO2CQ[0] != tempLO2C[0] ) || - ( tempLO2CQ[1] != tempLO2C[1] ) || - ( tempLO2CQ[2] != tempLO2C[2] ) ) - { - /* put actual LO2 value into queue (with 0 in one-shot bits) */ - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_1, &(tempLO2C[0]), 3); - - if( status == MT2063_OK ) - { - /* cache the bytes just written. */ - pInfo->reg[MT2063_REG_LO2CQ_1] = tempLO2C[0]; - pInfo->reg[MT2063_REG_LO2CQ_2] = tempLO2C[1]; - pInfo->reg[MT2063_REG_LO2CQ_3] = tempLO2C[2]; - } - restore = 1; - } - - /* Calculate the Divider and Numberator components of LO1 */ - status = MT2063_CalcLO1Mult(&Div, &FracN, nValue, pInfo->AS_Data.f_ref/64, pInfo->AS_Data.f_ref); - pInfo->reg[MT2063_REG_LO1CQ_1] = (U8Data)(Div & 0x00FF); - pInfo->reg[MT2063_REG_LO1CQ_2] = (U8Data)(FracN); - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &pInfo->reg[MT2063_REG_LO1CQ_1], 2); - - /* set the one-shot bit to load the pair of LO values */ - tmpOneShot = tempLO2CQ[2] | 0xE0; - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_3, &tmpOneShot, 1); - - /* only restore the queue values if they were different from the actual. */ - if( restore ) - { - /* put actual LO2 value into queue (0 in one-shot bits) */ - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_1, &(tempLO2CQ[0]), 3); - - /* cache the bytes just written. */ - pInfo->reg[MT2063_REG_LO2CQ_1] = tempLO2CQ[0]; - pInfo->reg[MT2063_REG_LO2CQ_2] = tempLO2CQ[1]; - pInfo->reg[MT2063_REG_LO2CQ_3] = tempLO2CQ[2]; - } - - MT2063_GetParam( pInfo->hUserData, MT2063_LO1_FREQ, &pInfo->AS_Data.f_LO1 ); - } - break; - - /* LO1 minimum step size */ - case MT2063_LO1_STEPSIZE: - pInfo->AS_Data.f_LO1_Step = nValue; - break; - - /* LO1 FracN keep-out region */ - case MT2063_LO1_FRACN_AVOID_PARAM: - pInfo->AS_Data.f_LO1_FracN_Avoid = nValue; - break; - - /* Requested 1st IF */ - case MT2063_IF1_REQUEST: - pInfo->AS_Data.f_if1_Request = nValue; - break; - - /* zero-IF bandwidth */ - case MT2063_ZIF_BW: - pInfo->AS_Data.f_zif_bw = nValue; - break; - - /* LO2 frequency */ - case MT2063_LO2_FREQ: - { - /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */ - /* Capture the Divider and Numerator portions of other LO */ - U8Data tempLO1CQ[2]; - U8Data tempLO1C[2]; - UData_t Div2; - UData_t FracN2; - U8Data tmpOneShot; - U8Data restore = 0; - - /* Buffer the queue for restoration later and get actual LO2 values. */ - status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &(tempLO1CQ[0]), 2); - status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, MT2063_REG_LO1C_1, &(tempLO1C[0]), 2); - - /* only write the queue values if they are different from the actual. */ - if( (tempLO1CQ[0] != tempLO1C[0]) || (tempLO1CQ[1] != tempLO1C[1]) ) - { - /* put actual LO1 value into queue */ - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &(tempLO1C[0]), 2); - - /* cache the bytes just written. */ - pInfo->reg[MT2063_REG_LO1CQ_1] = tempLO1C[0]; - pInfo->reg[MT2063_REG_LO1CQ_2] = tempLO1C[1]; - restore = 1; - } - - /* Calculate the Divider and Numberator components of LO2 */ - status = MT2063_CalcLO2Mult(&Div2, &FracN2, nValue, pInfo->AS_Data.f_ref/8191, pInfo->AS_Data.f_ref); - pInfo->reg[MT2063_REG_LO2CQ_1] = (U8Data)((Div2 << 1) | ((FracN2 >> 12) & 0x01) ) & 0xFF; - pInfo->reg[MT2063_REG_LO2CQ_2] = (U8Data)((FracN2 >> 4) & 0xFF); - pInfo->reg[MT2063_REG_LO2CQ_3] = (U8Data)((FracN2 & 0x0F) ); - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &pInfo->reg[MT2063_REG_LO1CQ_1], 3); - - /* set the one-shot bit to load the LO values */ - tmpOneShot = pInfo->reg[MT2063_REG_LO2CQ_3] | 0xE0; - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_3, &tmpOneShot, 1); - - /* only restore LO1 queue value if they were different from the actual. */ - if( restore ) - { - /* put previous LO1 queue value back into queue */ - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &(tempLO1CQ[0]), 2); - - /* cache the bytes just written. */ - pInfo->reg[MT2063_REG_LO1CQ_1] = tempLO1CQ[0]; - pInfo->reg[MT2063_REG_LO1CQ_2] = tempLO1CQ[1]; - } - - MT2063_GetParam( pInfo->hUserData, MT2063_LO2_FREQ, &pInfo->AS_Data.f_LO2 ); - } - break; - - /* LO2 minimum step size */ - case MT2063_LO2_STEPSIZE: - pInfo->AS_Data.f_LO2_Step = nValue; - break; - - /* LO2 FracN keep-out region */ - case MT2063_LO2_FRACN_AVOID: - pInfo->AS_Data.f_LO2_FracN_Avoid = nValue; - break; - - /* output center frequency */ - case MT2063_OUTPUT_FREQ: - pInfo->AS_Data.f_out = nValue; - break; - - /* output bandwidth */ - case MT2063_OUTPUT_BW: - pInfo->AS_Data.f_out_bw = nValue + 750000; - break; - - /* min inter-tuner LO separation */ - case MT2063_LO_SEPARATION: - pInfo->AS_Data.f_min_LO_Separation = nValue; - break; - - /* max # of intra-tuner harmonics */ - case MT2063_MAX_HARM1: - pInfo->AS_Data.maxH1 = nValue; - break; - - /* max # of inter-tuner harmonics */ - case MT2063_MAX_HARM2: - pInfo->AS_Data.maxH2 = nValue; - break; - - case MT2063_RCVR_MODE: - status |= MT2063_SetReceiverMode(pInfo, (enum MT2063_RCVR_MODES)nValue); - break; - - /* Set LNA Rin -- nValue is desired value */ - case MT2063_LNA_RIN: - val = ( pInfo->reg[MT2063_REG_CTRL_2C] & (U8Data)~0x03) | (nValue & 0x03); - if( pInfo->reg[MT2063_REG_CTRL_2C] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_CTRL_2C, val); - } - break; - - /* Set target power level at LNA -- nValue is desired value */ - case MT2063_LNA_TGT: - val = ( pInfo->reg[MT2063_REG_LNA_TGT] & (U8Data)~0x3F) | (nValue & 0x3F); - if( pInfo->reg[MT2063_REG_LNA_TGT] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_LNA_TGT, val); - } - break; - - /* Set target power level at PD1 -- nValue is desired value */ - case MT2063_PD1_TGT: - val = ( pInfo->reg[MT2063_REG_PD1_TGT] & (U8Data)~0x3F) | (nValue & 0x3F); - if( pInfo->reg[MT2063_REG_PD1_TGT] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT, val); - } - break; - - /* Set target power level at PD2 -- nValue is desired value */ - case MT2063_PD2_TGT: - val = ( pInfo->reg[MT2063_REG_PD2_TGT] & (U8Data)~0x3F) | (nValue & 0x3F); - if( pInfo->reg[MT2063_REG_PD2_TGT] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_PD2_TGT, val); - } - break; - - /* Set LNA atten limit -- nValue is desired value */ - case MT2063_ACLNA_MAX: - val = ( pInfo->reg[MT2063_REG_LNA_OV] & (U8Data)~0x1F) | (nValue & 0x1F); - if( pInfo->reg[MT2063_REG_LNA_OV] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_LNA_OV, val); - } - break; - - /* Set RF atten limit -- nValue is desired value */ - case MT2063_ACRF_MAX: - val = ( pInfo->reg[MT2063_REG_RF_OV] & (U8Data)~0x1F) | (nValue & 0x1F); - if( pInfo->reg[MT2063_REG_RF_OV] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_RF_OV, val); - } - break; - - /* Set FIF atten limit -- nValue is desired value, max. 5 if no B3 */ - case MT2063_ACFIF_MAX: - if ( pInfo->reg[MT2063_REG_PART_REV] != MT2063_B3 && nValue > 5) - nValue = 5; - val = ( pInfo->reg[MT2063_REG_FIF_OV] & (U8Data)~0x1F) | (nValue & 0x1F); - if( pInfo->reg[MT2063_REG_FIF_OV] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_FIF_OV, val); - } - break; - - case MT2063_DNC_OUTPUT_ENABLE: - /* selects, which DNC output is used */ - switch ((enum MT2063_DNC_Output_Enable)nValue) - { - case MT2063_DNC_NONE : - { - val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC ) | 0x03; /* Set DNC1GC=3 */ - if (pInfo->reg[MT2063_REG_DNC_GAIN] != val) - status |= MT2063_SetReg(h, MT2063_REG_DNC_GAIN, val); - - val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC ) | 0x03; /* Set DNC2GC=3 */ - if (pInfo->reg[MT2063_REG_VGA_GAIN] != val) - status |= MT2063_SetReg(h, MT2063_REG_VGA_GAIN, val); - - val = (pInfo->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */ - if (pInfo->reg[MT2063_REG_RSVD_20] != val) - status |= MT2063_SetReg(h, MT2063_REG_RSVD_20, val); - - break; - } - case MT2063_DNC_1 : - { - val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC ) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */ - if (pInfo->reg[MT2063_REG_DNC_GAIN] != val) - status |= MT2063_SetReg(h, MT2063_REG_DNC_GAIN, val); - - val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC ) | 0x03; /* Set DNC2GC=3 */ - if (pInfo->reg[MT2063_REG_VGA_GAIN] != val) - status |= MT2063_SetReg(h, MT2063_REG_VGA_GAIN, val); - - val = (pInfo->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */ - if (pInfo->reg[MT2063_REG_RSVD_20] != val) - status |= MT2063_SetReg(h, MT2063_REG_RSVD_20, val); - - break; - } - case MT2063_DNC_2 : - { - val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC ) | 0x03; /* Set DNC1GC=3 */ - if (pInfo->reg[MT2063_REG_DNC_GAIN] != val) - status |= MT2063_SetReg(h, MT2063_REG_DNC_GAIN, val); - - val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC ) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */ - if (pInfo->reg[MT2063_REG_VGA_GAIN] != val) - status |= MT2063_SetReg(h, MT2063_REG_VGA_GAIN, val); - - val = (pInfo->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */ - if (pInfo->reg[MT2063_REG_RSVD_20] != val) - status |= MT2063_SetReg(h, MT2063_REG_RSVD_20, val); - - break; - } - case MT2063_DNC_BOTH : - { - val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC ) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */ - if (pInfo->reg[MT2063_REG_DNC_GAIN] != val) - status |= MT2063_SetReg(h, MT2063_REG_DNC_GAIN, val); - - val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC ) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */ - if (pInfo->reg[MT2063_REG_VGA_GAIN] != val) - status |= MT2063_SetReg(h, MT2063_REG_VGA_GAIN, val); - - val = (pInfo->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */ - if (pInfo->reg[MT2063_REG_RSVD_20] != val) - status |= MT2063_SetReg(h, MT2063_REG_RSVD_20, val); - - break; - } - default : break; - } - break; - - case MT2063_VGAGC: - /* Set VGA gain code */ - val = (pInfo->reg[MT2063_REG_VGA_GAIN] & (U8Data)~0x0C) | ( (nValue & 0x03) << 2); - if( pInfo->reg[MT2063_REG_VGA_GAIN] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_VGA_GAIN, val); - } - break; - - case MT2063_VGAOI: - /* Set VGA bias current */ - val = (pInfo->reg[MT2063_REG_RSVD_31] & (U8Data)~0x07) | (nValue & 0x07); - if( pInfo->reg[MT2063_REG_RSVD_31] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_RSVD_31, val); - } - break; - - case MT2063_TAGC: - /* Set TAGC */ - val = (pInfo->reg[MT2063_REG_RSVD_1E] & (U8Data)~0x03) | (nValue & 0x03); - if( pInfo->reg[MT2063_REG_RSVD_1E] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_RSVD_1E, val); - } - break; - - case MT2063_AMPGC: - /* Set Amp gain code */ - val = (pInfo->reg[MT2063_REG_TEMP_SEL] & (U8Data)~0x03) | (nValue & 0x03); - if( pInfo->reg[MT2063_REG_TEMP_SEL] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_TEMP_SEL, val); - } - break; - - /* Avoid DECT Frequencies */ - case MT2063_AVOID_DECT: - { - enum MT2063_DECT_Avoid_Type newAvoidSetting = (enum MT2063_DECT_Avoid_Type) nValue; - if( (newAvoidSetting >= MT2063_NO_DECT_AVOIDANCE) && (newAvoidSetting <= MT2063_AVOID_BOTH) ) - { - pInfo->AS_Data.avoidDECT = newAvoidSetting; - } - } - break; - - /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ - case MT2063_CTFILT_SW: - pInfo->ctfilt_sw = (nValue & 0x01); - break; - - /* These parameters are read-only */ - case MT2063_IC_ADDR: - case MT2063_MAX_OPEN: - case MT2063_NUM_OPEN: - case MT2063_INPUT_FREQ: - case MT2063_IF1_ACTUAL: - case MT2063_IF1_CENTER: - case MT2063_IF1_BW: - case MT2063_AS_ALG: - case MT2063_EXCL_ZONES: - case MT2063_SPUR_AVOIDED: - case MT2063_NUM_SPURS: - case MT2063_SPUR_PRESENT: - case MT2063_ACLNA: - case MT2063_ACRF: - case MT2063_ACFIF: - case MT2063_EOP: - default: - status |= MT2063_ARG_RANGE; - } - } - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_SetPowerMaskBits -** -** Description: Sets the power-down mask bits for various sections of -** the MT2063 -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** Bits - Mask bits to be set. -** -** See definition of MT2063_Mask_Bits type for description -** of each of the power bits. -** -** Returns: status: -** MT_OK - No errors -** MT_INV_HANDLE - Invalid tuner handle -** MT_COMM_ERR - Serial bus communications error -** -** Dependencies: USERS MUST CALL MT2063_Open() FIRST! -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -****************************************************************************/ -UData_t MT2063_SetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - status = MT2063_INV_HANDLE; - else - { - Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ - if ((Bits & 0xFF00) != 0) - { - pInfo->reg[MT2063_REG_PWR_2] |= (U8Data)((Bits & 0xFF00) >> 8); - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_2, &pInfo->reg[MT2063_REG_PWR_2], 1); - } - if ((Bits & 0xFF) != 0) - { - pInfo->reg[MT2063_REG_PWR_1] |= ((U8Data)Bits & 0xFF); - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_1, &pInfo->reg[MT2063_REG_PWR_1], 1); - } - } - - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_ClearPowerMaskBits -** -** Description: Clears the power-down mask bits for various sections of -** the MT2063 -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** Bits - Mask bits to be cleared. -** -** See definition of MT2063_Mask_Bits type for description -** of each of the power bits. -** -** Returns: status: -** MT_OK - No errors -** MT_INV_HANDLE - Invalid tuner handle -** MT_COMM_ERR - Serial bus communications error -** -** Dependencies: USERS MUST CALL MT2063_Open() FIRST! -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -****************************************************************************/ -UData_t MT2063_ClearPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - status = MT2063_INV_HANDLE; - else - { - Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ - if ((Bits & 0xFF00) != 0) - { - pInfo->reg[MT2063_REG_PWR_2] &= ~(U8Data)(Bits >> 8); - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_2, &pInfo->reg[MT2063_REG_PWR_2], 1); - } - if ((Bits & 0xFF) != 0) - { - pInfo->reg[MT2063_REG_PWR_1] &= ~(U8Data)(Bits & 0xFF); - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_1, &pInfo->reg[MT2063_REG_PWR_1], 1); - } - } - - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_GetPowerMaskBits -** -** Description: Returns a mask of the enabled power shutdown bits -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** Bits - Mask bits to currently set. -** -** See definition of MT2063_Mask_Bits type for description -** of each of the power bits. -** -** Returns: status: -** MT_OK - No errors -** MT_INV_HANDLE - Invalid tuner handle -** MT_ARG_NULL - Output argument is NULL -** MT_COMM_ERR - Serial bus communications error -** -** Dependencies: USERS MUST CALL MT2063_Open() FIRST! -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -****************************************************************************/ -UData_t MT2063_GetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits *Bits) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - status = MT2063_INV_HANDLE; - else - { - if (Bits == NULL) - status |= MT2063_ARG_NULL; - - if (MT2063_NO_ERROR(status)) - status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_1, &pInfo->reg[MT2063_REG_PWR_1], 2); - - if (MT2063_NO_ERROR(status)) - { - *Bits = (enum MT2063_Mask_Bits)(((SData_t)pInfo->reg[MT2063_REG_PWR_2] << 8) + pInfo->reg[MT2063_REG_PWR_1]); - *Bits = (enum MT2063_Mask_Bits)(*Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ - } - } - - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_EnableExternalShutdown -** -** Description: Enables or disables the operation of the external -** shutdown pin -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** Enabled - 0 = disable the pin, otherwise enable it -** -** Returns: status: -** MT_OK - No errors -** MT_INV_HANDLE - Invalid tuner handle -** MT_COMM_ERR - Serial bus communications error -** -** Dependencies: USERS MUST CALL MT2063_Open() FIRST! -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -****************************************************************************/ -UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - status = MT2063_INV_HANDLE; - else - { - if (Enabled == 0) - pInfo->reg[MT2063_REG_PWR_1] &= ~0x08; /* Turn off the bit */ - else - pInfo->reg[MT2063_REG_PWR_1] |= 0x08; /* Turn the bit on */ - - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_1, &pInfo->reg[MT2063_REG_PWR_1], 1); - } - - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_SoftwareShutdown -** -** Description: Enables or disables software shutdown function. When -** Shutdown==1, any section whose power mask is set will be -** shutdown. -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** Shutdown - 1 = shutdown the masked sections, otherwise -** power all sections on -** -** Returns: status: -** MT_OK - No errors -** MT_INV_HANDLE - Invalid tuner handle -** MT_COMM_ERR - Serial bus communications error -** -** Dependencies: USERS MUST CALL MT2063_Open() FIRST! -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** 01-03-2008 PINZ Ver 1.xx: Added a trigger of BYPATNUP for -** correct wakeup of the LNA -** -****************************************************************************/ -UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - { - status = MT2063_INV_HANDLE; - } - else - { - if (Shutdown == 1) - pInfo->reg[MT2063_REG_PWR_1] |= 0x04; /* Turn the bit on */ - else - pInfo->reg[MT2063_REG_PWR_1] &= ~0x04; /* Turn off the bit */ - - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_1, &pInfo->reg[MT2063_REG_PWR_1], 1); - - if (Shutdown != 1) - { - pInfo->reg[MT2063_REG_BYP_CTRL] = (pInfo->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40; - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_BYP_CTRL, &pInfo->reg[MT2063_REG_BYP_CTRL], 1); - pInfo->reg[MT2063_REG_BYP_CTRL] = (pInfo->reg[MT2063_REG_BYP_CTRL] & 0x9F); - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_BYP_CTRL, &pInfo->reg[MT2063_REG_BYP_CTRL], 1); - } - } - - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_SetExtSRO -** -** Description: Sets the external SRO driver. -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** Ext_SRO_Setting - external SRO drive setting -** -** (default) MT2063_EXT_SRO_OFF - ext driver off -** MT2063_EXT_SRO_BY_1 - ext driver = SRO frequency -** MT2063_EXT_SRO_BY_2 - ext driver = SRO/2 frequency -** MT2063_EXT_SRO_BY_4 - ext driver = SRO/4 frequency -** -** Returns: status: -** MT_OK - No errors -** MT_COMM_ERR - Serial bus communications error -** MT_INV_HANDLE - Invalid tuner handle -** -** Dependencies: USERS MUST CALL MT2063_Open() FIRST! -** -** The Ext_SRO_Setting settings default to OFF -** Use this function if you need to override the default -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** 189 S 05-13-2008 RSK Ver 1.16: Correct location for ExtSRO control. -** -****************************************************************************/ -UData_t MT2063_SetExtSRO(Handle_t h, - enum MT2063_Ext_SRO Ext_SRO_Setting) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - status = MT2063_INV_HANDLE; - else - { - pInfo->reg[MT2063_REG_CTRL_2C] = (pInfo->reg[MT2063_REG_CTRL_2C] & 0x3F) | ((U8Data)Ext_SRO_Setting << 6); - status = MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_CTRL_2C, &pInfo->reg[MT2063_REG_CTRL_2C], 1); - } - - return (status); -} - - -/**************************************************************************** -** -** Name: MT2063_SetReg -** -** Description: Sets an MT2063 register. -** -** Parameters: h - Tuner handle (returned by MT2063_Open) -** reg - MT2063 register/subaddress location -** val - MT2063 register/subaddress value -** -** Returns: status: -** MT_OK - No errors -** MT_COMM_ERR - Serial bus communications error -** MT_INV_HANDLE - Invalid tuner handle -** MT_ARG_RANGE - Argument out of range -** -** Dependencies: USERS MUST CALL MT2063_Open() FIRST! -** -** Use this function if you need to override a default -** register value -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -****************************************************************************/ -UData_t MT2063_SetReg(Handle_t h, - U8Data reg, - U8Data val) -{ - UData_t status = MT2063_OK; /* Status to be returned */ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - status |= MT2063_INV_HANDLE; - - if (reg >= MT2063_REG_END_REGS) - status |= MT2063_ARG_RANGE; - - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, 1); - if (MT2063_NO_ERROR(status)) - pInfo->reg[reg] = val; - } - - return (status); -} - - -static UData_t MT2063_Round_fLO(UData_t f_LO, UData_t f_LO_Step, UData_t f_ref) -{ - return f_ref * (f_LO / f_ref) - + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step); -} - - -/**************************************************************************** -** -** Name: fLO_FractionalTerm -** -** Description: Calculates the portion contributed by FracN / denom. -** -** This function preserves maximum precision without -** risk of overflow. It accurately calculates -** f_ref * num / denom to within 1 HZ with fixed math. -** -** Parameters: num - Fractional portion of the multiplier -** denom - denominator portion of the ratio -** This routine successfully handles denom values -** up to and including 2^18. -** f_Ref - SRO frequency. This calculation handles -** f_ref as two separate 14-bit fields. -** Therefore, a maximum value of 2^28-1 -** may safely be used for f_ref. This is -** the genesis of the magic number "14" and the -** magic mask value of 0x03FFF. -** -** Returns: f_ref * num / denom -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -****************************************************************************/ -static UData_t MT2063_fLO_FractionalTerm( UData_t f_ref, - UData_t num, - UData_t denom ) -{ - UData_t t1 = (f_ref >> 14) * num; - UData_t term1 = t1 / denom; - UData_t loss = t1 % denom; - UData_t term2 = ( ((f_ref & 0x00003FFF) * num + (loss<<14)) + (denom/2) ) / denom; - return ((term1 << 14) + term2); -} - - -/**************************************************************************** -** -** Name: CalcLO1Mult -** -** Description: Calculates Integer divider value and the numerator -** value for a FracN PLL. -** -** This function assumes that the f_LO and f_Ref are -** evenly divisible by f_LO_Step. -** -** Parameters: Div - OUTPUT: Whole number portion of the multiplier -** FracN - OUTPUT: Fractional portion of the multiplier -** f_LO - desired LO frequency. -** f_LO_Step - Minimum step size for the LO (in Hz). -** f_Ref - SRO frequency. -** f_Avoid - Range of PLL frequencies to avoid near -** integer multiples of f_Ref (in Hz). -** -** Returns: Recalculated LO frequency. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -****************************************************************************/ -static UData_t MT2063_CalcLO1Mult(UData_t *Div, - UData_t *FracN, - UData_t f_LO, - UData_t f_LO_Step, - UData_t f_Ref) -{ - /* Calculate the whole number portion of the divider */ - *Div = f_LO / f_Ref; - - /* Calculate the numerator value (round to nearest f_LO_Step) */ - *FracN = (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) + (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step); - - return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm( f_Ref, *FracN, 64 ); -} - - -/**************************************************************************** -** -** Name: CalcLO2Mult -** -** Description: Calculates Integer divider value and the numerator -** value for a FracN PLL. -** -** This function assumes that the f_LO and f_Ref are -** evenly divisible by f_LO_Step. -** -** Parameters: Div - OUTPUT: Whole number portion of the multiplier -** FracN - OUTPUT: Fractional portion of the multiplier -** f_LO - desired LO frequency. -** f_LO_Step - Minimum step size for the LO (in Hz). -** f_Ref - SRO frequency. -** f_Avoid - Range of PLL frequencies to avoid near -** integer multiples of f_Ref (in Hz). -** -** Returns: Recalculated LO frequency. -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** -****************************************************************************/ -static UData_t MT2063_CalcLO2Mult(UData_t *Div, - UData_t *FracN, - UData_t f_LO, - UData_t f_LO_Step, - UData_t f_Ref) -{ - /* Calculate the whole number portion of the divider */ - *Div = f_LO / f_Ref; - - /* Calculate the numerator value (round to nearest f_LO_Step) */ - *FracN = (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) + (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step); - - return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm( f_Ref, *FracN, 8191 ); -} - -/**************************************************************************** -** -** Name: FindClearTuneFilter -** -** Description: Calculate the corrrect ClearTune filter to be used for -** a given input frequency. -** -** Parameters: pInfo - ptr to tuner data structure -** f_in - RF input center frequency (in Hz). -** -** Returns: ClearTune filter number (0-31) -** -** Dependencies: MUST CALL MT2064_Open BEFORE FindClearTuneFilter! -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 04-10-2008 PINZ Ver 1.14: Use software-controlled ClearTune -** cross-over frequency values. -** -****************************************************************************/ -static UData_t FindClearTuneFilter(struct MT2063_Info_t* pInfo, UData_t f_in) -{ - UData_t RFBand; - UData_t idx; /* index loop */ - - /* - ** Find RF Band setting - */ - RFBand = 31; /* def when f_in > all */ - for (idx=0; idx<31; ++idx) - { - if (pInfo->CTFiltMax[idx] >= f_in) - { - RFBand = idx; - break; - } - } - return (RFBand); -} - - - -/**************************************************************************** -** -** Name: MT2063_Tune -** -** Description: Change the tuner's tuned frequency to RFin. -** -** Parameters: h - Open handle to the tuner (from MT2063_Open). -** f_in - RF input center frequency (in Hz). -** -** Returns: status: -** MT_OK - No errors -** MT_INV_HANDLE - Invalid tuner handle -** MT_UPC_UNLOCK - Upconverter PLL unlocked -** MT_DNC_UNLOCK - Downconverter PLL unlocked -** MT_COMM_ERR - Serial bus communications error -** MT_SPUR_CNT_MASK - Count of avoided LO spurs -** MT_SPUR_PRESENT - LO spur possible in output -** MT_FIN_RANGE - Input freq out of range -** MT_FOUT_RANGE - Output freq out of range -** MT_UPC_RANGE - Upconverter freq out of range -** MT_DNC_RANGE - Downconverter freq out of range -** -** Dependencies: MUST CALL MT2063_Open BEFORE MT2063_Tune! -** -** MT_ReadSub - Read data from the two-wire serial bus -** MT_WriteSub - Write data to the two-wire serial bus -** MT_Sleep - Delay execution for x milliseconds -** MT2063_GetLocked - Checks to see if LO1 and LO2 are locked -** -** Revision History: -** -** SCR Date Author Description -** ------------------------------------------------------------------------- -** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. -** 04-10-2008 PINZ Ver 1.05: Use software-controlled ClearTune -** cross-over frequency values. -** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. -** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. -** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW -** -****************************************************************************/ -UData_t MT2063_Tune(Handle_t h, - UData_t f_in) /* RF input center frequency */ -{ - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - - UData_t status = MT2063_OK; /* status of operation */ - UData_t LO1; /* 1st LO register value */ - UData_t Num1; /* Numerator for LO1 reg. value */ - UData_t f_IF1; /* 1st IF requested */ - UData_t LO2; /* 2nd LO register value */ - UData_t Num2; /* Numerator for LO2 reg. value */ - UData_t ofLO1, ofLO2; /* last time's LO frequencies */ - UData_t ofin, ofout; /* last time's I/O frequencies */ - U8Data fiffc = 0x80; /* FIFF center freq from tuner */ - UData_t fiffof; /* Offset from FIFF center freq */ - const U8Data LO1LK = 0x80; /* Mask for LO1 Lock bit */ - U8Data LO2LK = 0x08; /* Mask for LO2 Lock bit */ - U8Data val; - UData_t RFBand; - - /* Verify that the handle passed points to a valid tuner */ - if (MT2063_IsValidHandle(pInfo) == 0) - return MT2063_INV_HANDLE; - - /* Check the input and output frequency ranges */ - if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ)) - status |= MT2063_FIN_RANGE; - - if ((pInfo->AS_Data.f_out < MT2063_MIN_FOUT_FREQ) || (pInfo->AS_Data.f_out > MT2063_MAX_FOUT_FREQ)) - status |= MT2063_FOUT_RANGE; - - /* - ** Save original LO1 and LO2 register values - */ - ofLO1 = pInfo->AS_Data.f_LO1; - ofLO2 = pInfo->AS_Data.f_LO2; - ofin = pInfo->AS_Data.f_in; - ofout = pInfo->AS_Data.f_out; - - /* - ** Find and set RF Band setting - */ - if (pInfo->ctfilt_sw == 1) - { - val = ( pInfo->reg[MT2063_REG_CTUNE_CTRL] | 0x08 ); - if( pInfo->reg[MT2063_REG_CTUNE_CTRL] != val ) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_CTUNE_CTRL, val); - } - val = pInfo->reg[MT2063_REG_CTUNE_OV]; - RFBand = FindClearTuneFilter(pInfo, f_in); - pInfo->reg[MT2063_REG_CTUNE_OV] = (U8Data)((pInfo->reg[MT2063_REG_CTUNE_OV] & ~0x1F) - | RFBand); - if (pInfo->reg[MT2063_REG_CTUNE_OV] != val) - { - status |= MT2063_SetReg(pInfo, MT2063_REG_CTUNE_OV, val); - } - } - - /* - ** Read the FIFF Center Frequency from the tuner - */ - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_FIFFC, &pInfo->reg[MT2063_REG_FIFFC], 1); - fiffc = pInfo->reg[MT2063_REG_FIFFC]; - } - /* - ** Assign in the requested values - */ - pInfo->AS_Data.f_in = f_in; - /* Request a 1st IF such that LO1 is on a step size */ - pInfo->AS_Data.f_if1_Request = MT2063_Round_fLO(pInfo->AS_Data.f_if1_Request + f_in, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref) - f_in; - - /* - ** Calculate frequency settings. f_IF1_FREQ + f_in is the - ** desired LO1 frequency - */ - MT2063_ResetExclZones(&pInfo->AS_Data); - - f_IF1 = MT2063_ChooseFirstIF(&pInfo->AS_Data); - - pInfo->AS_Data.f_LO1 = MT2063_Round_fLO(f_IF1 + f_in, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref); - - pInfo->AS_Data.f_LO2 = MT2063_Round_fLO(pInfo->AS_Data.f_LO1 - pInfo->AS_Data.f_out - f_in, pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); - - /* - ** Check for any LO spurs in the output bandwidth and adjust - ** the LO settings to avoid them if needed - */ - status |= MT2063_AvoidSpurs(h, &pInfo->AS_Data); - /* - ** MT_AvoidSpurs spurs may have changed the LO1 & LO2 values. - ** Recalculate the LO frequencies and the values to be placed - ** in the tuning registers. - */ - pInfo->AS_Data.f_LO1 = MT2063_CalcLO1Mult(&LO1, &Num1, pInfo->AS_Data.f_LO1, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref); - pInfo->AS_Data.f_LO2 = MT2063_Round_fLO(pInfo->AS_Data.f_LO1 - pInfo->AS_Data.f_out - f_in, pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); - pInfo->AS_Data.f_LO2 = MT2063_CalcLO2Mult(&LO2, &Num2, pInfo->AS_Data.f_LO2, pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); - - - /* - ** Check the upconverter and downconverter frequency ranges - */ - if ((pInfo->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ) || (pInfo->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ)) - status |= MT2063_UPC_RANGE; - if ((pInfo->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ) || (pInfo->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ)) - status |= MT2063_DNC_RANGE; - /* LO2 Lock bit was in a different place for B0 version */ - if (pInfo->tuner_id == MT2063_B0) - LO2LK = 0x40; - - /* - ** If we have the same LO frequencies and we're already locked, - ** then skip re-programming the LO registers. - */ - if ((ofLO1 != pInfo->AS_Data.f_LO1) - || (ofLO2 != pInfo->AS_Data.f_LO2) - || ((pInfo->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) != (LO1LK | LO2LK))) - { - /* - ** Calculate the FIFFOF register value - ** - ** IF1_Actual - ** FIFFOF = ------------ - 8 * FIFFC - 4992 - ** f_ref/64 - */ - fiffof = (pInfo->AS_Data.f_LO1 - f_in) / (pInfo->AS_Data.f_ref / 64) - 8 * (UData_t)fiffc - 4992; - if (fiffof > 0xFF) - fiffof = 0xFF; - - /* - ** Place all of the calculated values into the local tuner - ** register fields. - */ - if (MT2063_NO_ERROR(status)) - { - pInfo->reg[MT2063_REG_LO1CQ_1] = (U8Data)(LO1 & 0xFF); /* DIV1q */ - pInfo->reg[MT2063_REG_LO1CQ_2] = (U8Data)(Num1 & 0x3F); /* NUM1q */ - pInfo->reg[MT2063_REG_LO2CQ_1] = (U8Data)(((LO2 & 0x7F) << 1) /* DIV2q */ - | (Num2 >> 12)); /* NUM2q (hi) */ - pInfo->reg[MT2063_REG_LO2CQ_2] = (U8Data)((Num2 & 0x0FF0) >> 4); /* NUM2q (mid) */ - pInfo->reg[MT2063_REG_LO2CQ_3] = (U8Data)(0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */ - - /* - ** Now write out the computed register values - ** IMPORTANT: There is a required order for writing - ** (0x05 must follow all the others). - */ - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &pInfo->reg[MT2063_REG_LO1CQ_1], 5); /* 0x01 - 0x05 */ - if (pInfo->tuner_id == MT2063_B0) - { - /* Re-write the one-shot bits to trigger the tune operation */ - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_3, &pInfo->reg[MT2063_REG_LO2CQ_3], 1); /* 0x05 */ - } - /* Write out the FIFF offset only if it's changing */ - if (pInfo->reg[MT2063_REG_FIFF_OFFSET] != (U8Data)fiffof) - { - pInfo->reg[MT2063_REG_FIFF_OFFSET] = (U8Data)fiffof; - status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_FIFF_OFFSET, &pInfo->reg[MT2063_REG_FIFF_OFFSET], 1); - } - } - - /* - ** Check for LO's locking - */ - - - if (MT2063_NO_ERROR(status)) - { - status |= MT2063_GetLocked(h); - } - /* - ** If we locked OK, assign calculated data to MT2063_Info_t structure - */ - if (MT2063_NO_ERROR(status)) - { - pInfo->f_IF1_actual = pInfo->AS_Data.f_LO1 - f_in; - } - } - - return (status); -} - -UData_t MT_Tune_atv(Handle_t h, UData_t f_in, UData_t bw_in, enum MTTune_atv_standard tv_type) -{ - - UData_t status = MT2063_OK; - struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; - struct dvb_frontend *fe = (struct dvb_frontend *)pInfo->hUserData; - struct mt2063_state *state = fe->tuner_priv; - - SData_t pict_car = 0; - SData_t pict2chanb_vsb = 0; - SData_t pict2chanb_snd = 0; - SData_t pict2snd1 = 0; - SData_t pict2snd2 = 0; - SData_t ch_bw = 0; - - SData_t if_mid = 0; - SData_t rcvr_mode =0; - UData_t mode_get =0; - - - switch (tv_type) { - case MTTUNEA_PAL_B : { - pict_car = 38900000; - ch_bw = 8000000; - pict2chanb_vsb = -1250000; - pict2snd1 = 5500000; - pict2snd2 = 5742000; - rcvr_mode =1; - break; - } - case MTTUNEA_PAL_G : { - pict_car = 38900000; - ch_bw = 7000000; - pict2chanb_vsb = -1250000; - pict2snd1 = 5500000; - pict2snd2 = 0; - rcvr_mode =1; - break; - } - case MTTUNEA_PAL_I : { - pict_car = 38900000; - ch_bw = 8000000; - pict2chanb_vsb = -1250000; - pict2snd1 = 6000000; - pict2snd2 = 0; - rcvr_mode =1; - break; - } - case MTTUNEA_PAL_L : { - pict_car = 38900000; - ch_bw = 8000000; - pict2chanb_vsb = -1250000; - pict2snd1 = 6500000; - pict2snd2 = 0; - rcvr_mode =1; - break; - } - case MTTUNEA_PAL_MN : { - pict_car = 38900000; - ch_bw = 6000000; - pict2chanb_vsb = -1250000; - pict2snd1 = 4500000; - pict2snd2 = 0; - rcvr_mode =1; - break; - } - case MTTUNEA_PAL_DK : { - pict_car = 38900000; - ch_bw = 8000000; - pict2chanb_vsb = -1250000; - pict2snd1 = 6500000; - pict2snd2 = 0; - rcvr_mode =1; - break; - } - case MTTUNEA_DIGITAL : { - pict_car = 36125000; - ch_bw = 8000000; - pict2chanb_vsb = -(ch_bw/2); - pict2snd1 = 0; - pict2snd2 = 0; - rcvr_mode = 2; - break; - } - case MTTUNEA_FMRADIO : { - pict_car = 38900000; - ch_bw = 8000000; - pict2chanb_vsb = -(ch_bw/2); - pict2snd1 = 0; - pict2snd2 = 0; - rcvr_mode =4; - //f_in -= 2900000; - break; - } - case MTTUNEA_DVBC : { - pict_car = 36125000; - ch_bw = 8000000; - pict2chanb_vsb = -(ch_bw/2); - pict2snd1 = 0; - pict2snd2 = 0; - rcvr_mode = MT2063_CABLE_QAM; - break; - } - case MTTUNEA_DVBT : { - pict_car = 36125000; - ch_bw = bw_in;//8000000 - pict2chanb_vsb = -(ch_bw/2); - pict2snd1 = 0; - pict2snd2 = 0; - rcvr_mode = MT2063_OFFAIR_COFDM; - break; - } - case MTTUNEA_UNKNOWN : break; - default : break; - } - - pict2chanb_snd = pict2chanb_vsb - ch_bw; - if_mid = pict_car - (pict2chanb_vsb + (ch_bw/2) ); - - status |= MT2063_SetParam(h,MT2063_STEPSIZE,125000); - status |= MT2063_SetParam(h,MT2063_OUTPUT_FREQ,if_mid); - status |= MT2063_SetParam(h,MT2063_OUTPUT_BW,ch_bw); - status |=MT2063_GetParam(h,MT2063_RCVR_MODE,&mode_get); - - status |= MT2063_SetParam(h,MT2063_RCVR_MODE,rcvr_mode); - status |= MT2063_Tune(h,( f_in + (pict2chanb_vsb + (ch_bw/2) ) ) ); - status |=MT2063_GetParam(h,MT2063_RCVR_MODE,&mode_get); - - return (UData_t)status; -} - - -static int mt2063_init(struct dvb_frontend *fe) -{ - UData_t status = MT2063_ERROR; - struct mt2063_state *state = fe->tuner_priv; - - status = MT2063_Open(0xC0, &(state->MT2063_ht), fe); - status |= MT2063_SoftwareShutdown(state->MT2063_ht, 1); - status |= MT2063_ClearPowerMaskBits(state->MT2063_ht, MT2063_ALL_SD); - - if(MT2063_OK != status) - { - printk("%s %d error status = 0x%x!!\n", __func__, __LINE__, status); - return -1; - } - - return 0; -} - -static int mt2063_sleep(struct dvb_frontend *fe) + //printk("mt2063_read_regs state->i2c=%p\n", state->i2c); + ret = i2c_transfer(state->i2c, msg, 2); + if (ret < 0) + printk("mt2063_readregs error ret=%d\n", ret); + + return ret; +} + +//context of mt2063_userdef.c ====================================== +//################################################################# +//================================================================= +/***************************************************************************** +** +** Name: MT_WriteSub +** +** Description: Write values to device using a two-wire serial bus. +** +** Parameters: hUserData - User-specific I/O parameter that was +** passed to tuner's Open function. +** addr - device serial bus address (value passed +** as parameter to MTxxxx_Open) +** subAddress - serial bus sub-address (Register Address) +** pData - pointer to the Data to be written to the +** device +** cnt - number of bytes/registers to be written +** +** Returns: status: +** MT_OK - No errors +** MT_COMM_ERR - Serial bus communications error +** user-defined +** +** Notes: This is a callback function that is called from the +** the tuning algorithm. You MUST provide code for this +** function to write data using the tuner's 2-wire serial +** bus. +** +** The hUserData parameter is a user-specific argument. +** If additional arguments are needed for the user's +** serial bus read/write functions, this argument can be +** used to supply the necessary information. +** The hUserData parameter is initialized in the tuner's Open +** function. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** N/A 03-25-2004 DAD Original +** +*****************************************************************************/ +UData_t MT2063_WriteSub(Handle_t hUserData, + UData_t addr, + U8Data subAddress, U8Data * pData, UData_t cnt) { - /* TODO: power down */ + UData_t status = MT2063_OK; /* Status to be returned */ + struct dvb_frontend *fe = hUserData; + struct mt2063_state *state = fe->tuner_priv; + /* + ** ToDo: Add code here to implement a serial-bus write + ** operation to the MTxxxx tuner. If successful, + ** return MT_OK. + */ +/* return status; */ + +//#if !TUNER_CONTROL_BY_DRXK_DRIVER + fe->ops.i2c_gate_ctrl(fe, 1); //I2C bypass drxk3926 close i2c bridge +//#endif + + if (mt2063_writeregs(state, subAddress, pData, cnt) < 0) { + status = MT2063_ERROR; + } +//#if !TUNER_CONTROL_BY_DRXK_DRIVER + fe->ops.i2c_gate_ctrl(fe, 0); //I2C bypass drxk3926 close i2c bridge +//#endif + + return (status); +} + +/***************************************************************************** +** +** Name: MT_ReadSub +** +** Description: Read values from device using a two-wire serial bus. +** +** Parameters: hUserData - User-specific I/O parameter that was +** passed to tuner's Open function. +** addr - device serial bus address (value passed +** as parameter to MTxxxx_Open) +** subAddress - serial bus sub-address (Register Address) +** pData - pointer to the Data to be written to the +** device +** cnt - number of bytes/registers to be written +** +** Returns: status: +** MT_OK - No errors +** MT_COMM_ERR - Serial bus communications error +** user-defined +** +** Notes: This is a callback function that is called from the +** the tuning algorithm. You MUST provide code for this +** function to read data using the tuner's 2-wire serial +** bus. +** +** The hUserData parameter is a user-specific argument. +** If additional arguments are needed for the user's +** serial bus read/write functions, this argument can be +** used to supply the necessary information. +** The hUserData parameter is initialized in the tuner's Open +** function. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** N/A 03-25-2004 DAD Original +** +*****************************************************************************/ +UData_t MT2063_ReadSub(Handle_t hUserData, + UData_t addr, + U8Data subAddress, U8Data * pData, UData_t cnt) +{ + /* + ** ToDo: Add code here to implement a serial-bus read + ** operation to the MTxxxx tuner. If successful, + ** return MT_OK. + */ +/* return status; */ + UData_t status = MT2063_OK; /* Status to be returned */ + struct dvb_frontend *fe = hUserData; + struct mt2063_state *state = fe->tuner_priv; + UData_t i = 0; +//#if !TUNER_CONTROL_BY_DRXK_DRIVER + fe->ops.i2c_gate_ctrl(fe, 1); //I2C bypass drxk3926 close i2c bridge +//#endif + + for (i = 0; i < cnt; i++) { + if (mt2063_read_regs(state, subAddress + i, pData + i, 1) < 0) { + status = MT2063_ERROR; + break; + } + } + +//#if !TUNER_CONTROL_BY_DRXK_DRIVER + fe->ops.i2c_gate_ctrl(fe, 0); //I2C bypass drxk3926 close i2c bridge +//#endif + + return (status); +} + +/***************************************************************************** +** +** Name: MT_Sleep +** +** Description: Delay execution for "nMinDelayTime" milliseconds +** +** Parameters: hUserData - User-specific I/O parameter that was +** passed to tuner's Open function. +** nMinDelayTime - Delay time in milliseconds +** +** Returns: None. +** +** Notes: This is a callback function that is called from the +** the tuning algorithm. You MUST provide code that +** blocks execution for the specified period of time. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** N/A 03-25-2004 DAD Original +** +*****************************************************************************/ +void MT2063_Sleep(Handle_t hUserData, UData_t nMinDelayTime) +{ + /* + ** ToDo: Add code here to implement a OS blocking + ** for a period of "nMinDelayTime" milliseconds. + */ + msleep(nMinDelayTime); +} + +#if defined(MT2060_CNT) +#if MT2060_CNT > 0 +/***************************************************************************** +** +** Name: MT_TunerGain (MT2060 only) +** +** Description: Measure the relative tuner gain using the demodulator +** +** Parameters: hUserData - User-specific I/O parameter that was +** passed to tuner's Open function. +** pMeas - Tuner gain (1/100 of dB scale). +** ie. 1234 = 12.34 (dB) +** +** Returns: status: +** MT_OK - No errors +** user-defined errors could be set +** +** Notes: This is a callback function that is called from the +** the 1st IF location routine. You MUST provide +** code that measures the relative tuner gain in a dB +** (not linear) scale. The return value is an integer +** value scaled to 1/100 of a dB. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** N/A 06-16-2004 DAD Original +** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name +** better describes what this function does. +** +*****************************************************************************/ +UData_t MT2060_TunerGain(Handle_t hUserData, SData_t * pMeas) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + + /* + ** ToDo: Add code here to return the gain / power level measured + ** at the input to the demodulator. + */ + + return (status); +} +#endif +#endif +//end of mt2063_userdef.c +//================================================================= +//################################################################# +//================================================================= + +//context of mt2063_spuravoid.c ====================================== +//################################################################# +//================================================================= + +/***************************************************************************** +** +** Name: mt_spuravoid.c +** +** Description: Microtune spur avoidance software module. +** Supports Microtune tuner drivers. +** +** CVS ID: $Id: mt_spuravoid.c,v 1.3 2008/06/26 15:39:52 software Exp $ +** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2063/mt_spuravoid.c,v $ +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 082 03-25-2005 JWS Original multi-tuner support - requires +** MTxxxx_CNT declarations +** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0. +** 094 04-06-2005 JWS Ver 1.11 Added uceil and ufloor to get rid +** of compiler warnings +** N/A 04-07-2005 DAD Ver 1.13: Merged single- and multi-tuner spur +** avoidance into a single module. +** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range +** (f_min, f_max) < 0, ignore the entry. +** 115 03-23-2007 DAD Fix declaration of spur due to truncation +** errors. +** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from +** tuner DLL. +** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for +** multi-tuners that have +** (delta IF1) > (f_out-f_outbw/2). +** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+) +** Added logic to force f_Center within 1/2 f_Step. +** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2 +** Type casts added to preserve correct sign. +** N/A I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT +** frequencies into MT_ResetExclZones(). +** N/A I 06-20-2008 RSK Ver 1.21: New VERSION number for ver checking. +** +*****************************************************************************/ + +#if !defined(MT2063_TUNER_CNT) +#error MT2063_TUNER_CNT is not defined (see mt_userdef.h) +#endif + +#if MT2063_TUNER_CNT == 0 +#error MT2063_TUNER_CNT must be updated in mt_userdef.h +#endif + +/* Version of this module */ +#define MT2063_SPUR_VERSION 10201 /* Version 01.21 */ + +/* Implement ceiling, floor functions. */ +#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0)) +#define uceil(n, d) ((n)/(d) + ((n)%(d) != 0)) +#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d)) +#define ufloor(n, d) ((n)/(d)) + +struct MT2063_FIFZone_t { + SData_t min_; + SData_t max_; +}; + +#if MT2063_TUNER_CNT > 1 +static struct MT2063_AvoidSpursData_t *TunerList[MT2063_TUNER_CNT]; +static UData_t TunerCount = 0; +#endif + +UData_t MT2063_RegisterTuner(struct MT2063_AvoidSpursData_t *pAS_Info) +{ +#if MT2063_TUNER_CNT == 1 + pAS_Info->nAS_Algorithm = 1; + return MT2063_OK; +#else + UData_t index; + + pAS_Info->nAS_Algorithm = 2; + + /* + ** Check to see if tuner is already registered + */ + for (index = 0; index < TunerCount; index++) { + if (TunerList[index] == pAS_Info) { + return MT2063_OK; /* Already here - no problem */ + } + } + + /* + ** Add tuner to list - if there is room. + */ + if (TunerCount < MT2063_TUNER_CNT) { + TunerList[TunerCount] = pAS_Info; + TunerCount++; + return MT2063_OK; + } else + return MT2063_TUNER_CNT_ERR; +#endif +} + +void MT2063_UnRegisterTuner(struct MT2063_AvoidSpursData_t *pAS_Info) +{ +#if MT2063_TUNER_CNT == 1 + pAS_Info; +#else + + UData_t index; + + for (index = 0; index < TunerCount; index++) { + if (TunerList[index] == pAS_Info) { + TunerList[index] = TunerList[--TunerCount]; + } + } +#endif +} + +/* +** Reset all exclusion zones. +** Add zones to protect the PLL FracN regions near zero +** +** N/A I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT +** frequencies into MT_ResetExclZones(). +*/ +void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info) +{ + UData_t center; +#if MT2063_TUNER_CNT > 1 + UData_t index; + struct MT2063_AvoidSpursData_t *adj; +#endif + + pAS_Info->nZones = 0; /* this clears the used list */ + pAS_Info->usedZones = NULL; /* reset ptr */ + pAS_Info->freeZones = NULL; /* reset ptr */ + + center = + pAS_Info->f_ref * + ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 + + pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in; + while (center < + pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 + + pAS_Info->f_LO1_FracN_Avoid) { + /* Exclude LO1 FracN */ + MT2063_AddExclZone(pAS_Info, + center - pAS_Info->f_LO1_FracN_Avoid, + center - 1); + MT2063_AddExclZone(pAS_Info, center + 1, + center + pAS_Info->f_LO1_FracN_Avoid); + center += pAS_Info->f_ref; + } + + center = + pAS_Info->f_ref * + ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 - + pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out; + while (center < + pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 + + pAS_Info->f_LO2_FracN_Avoid) { + /* Exclude LO2 FracN */ + MT2063_AddExclZone(pAS_Info, + center - pAS_Info->f_LO2_FracN_Avoid, + center - 1); + MT2063_AddExclZone(pAS_Info, center + 1, + center + pAS_Info->f_LO2_FracN_Avoid); + center += pAS_Info->f_ref; + } + + if (MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT)) { + /* Exclude LO1 values that conflict with DECT channels */ + MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */ + MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */ + MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */ + MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */ + MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */ + } + + if (MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT)) { + MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */ + MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */ + MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */ + MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16 */ + MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */ + MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */ + MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */ + MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */ + MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52 */ + MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */ + } +#if MT2063_TUNER_CNT > 1 + /* + ** Iterate through all adjacent tuners and exclude frequencies related to them + */ + for (index = 0; index < TunerCount; ++index) { + adj = TunerList[index]; + if (pAS_Info == adj) /* skip over our own data, don't process it */ + continue; + + /* + ** Add 1st IF exclusion zone covering adjacent tuner's LO2 + ** at "adjfLO2 + f_out" +/- m_MinLOSpacing + */ + if (adj->f_LO2 != 0) + MT2063_AddExclZone(pAS_Info, + (adj->f_LO2 + pAS_Info->f_out) - + pAS_Info->f_min_LO_Separation, + (adj->f_LO2 + pAS_Info->f_out) + + pAS_Info->f_min_LO_Separation); + + /* + ** Add 1st IF exclusion zone covering adjacent tuner's LO1 + ** at "adjfLO1 - f_in" +/- m_MinLOSpacing + */ + if (adj->f_LO1 != 0) + MT2063_AddExclZone(pAS_Info, + (adj->f_LO1 - pAS_Info->f_in) - + pAS_Info->f_min_LO_Separation, + (adj->f_LO1 - pAS_Info->f_in) + + pAS_Info->f_min_LO_Separation); + } +#endif +} + +static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t + *pAS_Info, + struct MT2063_ExclZone_t *pPrevNode) +{ + struct MT2063_ExclZone_t *pNode; + /* Check for a node in the free list */ + if (pAS_Info->freeZones != NULL) { + /* Use one from the free list */ + pNode = pAS_Info->freeZones; + pAS_Info->freeZones = pNode->next_; + } else { + /* Grab a node from the array */ + pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones]; + } + + if (pPrevNode != NULL) { + pNode->next_ = pPrevNode->next_; + pPrevNode->next_ = pNode; + } else { /* insert at the beginning of the list */ + + pNode->next_ = pAS_Info->usedZones; + pAS_Info->usedZones = pNode; + } + + pAS_Info->nZones++; + return pNode; +} + +static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t + *pAS_Info, + struct MT2063_ExclZone_t *pPrevNode, + struct MT2063_ExclZone_t + *pNodeToRemove) +{ + struct MT2063_ExclZone_t *pNext = pNodeToRemove->next_; + + /* Make previous node point to the subsequent node */ + if (pPrevNode != NULL) + pPrevNode->next_ = pNext; + + /* Add pNodeToRemove to the beginning of the freeZones */ + pNodeToRemove->next_ = pAS_Info->freeZones; + pAS_Info->freeZones = pNodeToRemove; + + /* Decrement node count */ + pAS_Info->nZones--; + + return pNext; +} + +/***************************************************************************** +** +** Name: MT_AddExclZone +** +** Description: Add (and merge) an exclusion zone into the list. +** If the range (f_min, f_max) is totally outside the +** 1st IF BW, ignore the entry. +** If the range (f_min, f_max) is negative, ignore the entry. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range +** (f_min, f_max) < 0, ignore the entry. +** +*****************************************************************************/ +void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info, + UData_t f_min, UData_t f_max) +{ + struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones; + struct MT2063_ExclZone_t *pPrev = NULL; + struct MT2063_ExclZone_t *pNext = NULL; + + /* Check to see if this overlaps the 1st IF filter */ + if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2))) + && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2))) + && (f_min < f_max)) { + /* + ** 1 2 3 4 5 6 + ** + ** New entry: |---| |--| |--| |-| |---| |--| + ** or or or or or + ** Existing: |--| |--| |--| |---| |-| |--| + */ + + /* Check for our place in the list */ + while ((pNode != NULL) && (pNode->max_ < f_min)) { + pPrev = pNode; + pNode = pNode->next_; + } + + if ((pNode != NULL) && (pNode->min_ < f_max)) { + /* Combine me with pNode */ + if (f_min < pNode->min_) + pNode->min_ = f_min; + if (f_max > pNode->max_) + pNode->max_ = f_max; + } else { + pNode = InsertNode(pAS_Info, pPrev); + pNode->min_ = f_min; + pNode->max_ = f_max; + } + + /* Look for merging possibilities */ + pNext = pNode->next_; + while ((pNext != NULL) && (pNext->min_ < pNode->max_)) { + if (pNext->max_ > pNode->max_) + pNode->max_ = pNext->max_; + pNext = RemoveNode(pAS_Info, pNode, pNext); /* Remove pNext, return ptr to pNext->next */ + } + } +} + +/***************************************************************************** +** +** Name: MT_ChooseFirstIF +** +** Description: Choose the best available 1st IF +** If f_Desired is not excluded, choose that first. +** Otherwise, return the value closest to f_Center that is +** not excluded +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from +** tuner DLL. +** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+) +** Added logic to force f_Center within 1/2 f_Step. +** +*****************************************************************************/ +UData_t MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info) +{ + /* + ** Update "f_Desired" to be the nearest "combinational-multiple" of "f_LO1_Step". + ** The resulting number, F_LO1 must be a multiple of f_LO1_Step. And F_LO1 is the arithmetic sum + ** of f_in + f_Center. Neither f_in, nor f_Center must be a multiple of f_LO1_Step. + ** However, the sum must be. + */ + const UData_t f_Desired = + pAS_Info->f_LO1_Step * + ((pAS_Info->f_if1_Request + pAS_Info->f_in + + pAS_Info->f_LO1_Step / 2) / pAS_Info->f_LO1_Step) - + pAS_Info->f_in; + const UData_t f_Step = + (pAS_Info->f_LO1_Step > + pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info-> + f_LO2_Step; + UData_t f_Center; + + SData_t i; + SData_t j = 0; + UData_t bDesiredExcluded = 0; + UData_t bZeroExcluded = 0; + SData_t tmpMin, tmpMax; + SData_t bestDiff; + struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones; + struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES]; + + if (pAS_Info->nZones == 0) + return f_Desired; + + /* f_Center needs to be an integer multiple of f_Step away from f_Desired */ + if (pAS_Info->f_if1_Center > f_Desired) + f_Center = + f_Desired + + f_Step * + ((pAS_Info->f_if1_Center - f_Desired + + f_Step / 2) / f_Step); + else + f_Center = + f_Desired - + f_Step * + ((f_Desired - pAS_Info->f_if1_Center + + f_Step / 2) / f_Step); + + //assert; + //if (!abs((SData_t) f_Center - (SData_t) pAS_Info->f_if1_Center) <= (SData_t) (f_Step/2)) + // return 0; + + /* Take MT_ExclZones, center around f_Center and change the resolution to f_Step */ + while (pNode != NULL) { + /* floor function */ + tmpMin = + floor((SData_t) (pNode->min_ - f_Center), (SData_t) f_Step); + + /* ceil function */ + tmpMax = + ceil((SData_t) (pNode->max_ - f_Center), (SData_t) f_Step); + + if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired)) + bDesiredExcluded = 1; + + if ((tmpMin < 0) && (tmpMax > 0)) + bZeroExcluded = 1; + + /* See if this zone overlaps the previous */ + if ((j > 0) && (tmpMin < zones[j - 1].max_)) + zones[j - 1].max_ = tmpMax; + else { + /* Add new zone */ + //assert(j=MT2063_MAX_ZONES) + //break; + + zones[j].min_ = tmpMin; + zones[j].max_ = tmpMax; + j++; + } + pNode = pNode->next_; + } + + /* + ** If the desired is okay, return with it + */ + if (bDesiredExcluded == 0) + return f_Desired; + + /* + ** If the desired is excluded and the center is okay, return with it + */ + if (bZeroExcluded == 0) + return f_Center; + + /* Find the value closest to 0 (f_Center) */ + bestDiff = zones[0].min_; + for (i = 0; i < j; i++) { + if (abs(zones[i].min_) < abs(bestDiff)) + bestDiff = zones[i].min_; + if (abs(zones[i].max_) < abs(bestDiff)) + bestDiff = zones[i].max_; + } + + if (bestDiff < 0) + return f_Center - ((UData_t) (-bestDiff) * f_Step); + + return f_Center + (bestDiff * f_Step); +} + +/**************************************************************************** +** +** Name: gcd +** +** Description: Uses Euclid's algorithm +** +** Parameters: u, v - unsigned values whose GCD is desired. +** +** Global: None +** +** Returns: greatest common divisor of u and v, if either value +** is 0, the other value is returned as the result. +** +** Dependencies: None. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** N/A 06-01-2004 JWS Original +** N/A 08-03-2004 DAD Changed to Euclid's since it can handle +** unsigned numbers. +** +****************************************************************************/ +static UData_t MT2063_gcd(UData_t u, UData_t v) +{ + UData_t r; + + while (v != 0) { + r = u % v; + u = v; + v = r; + } + + return u; +} + +/**************************************************************************** +** +** Name: umax +** +** Description: Implements a simple maximum function for unsigned numbers. +** Implemented as a function rather than a macro to avoid +** multiple evaluation of the calling parameters. +** +** Parameters: a, b - Values to be compared +** +** Global: None +** +** Returns: larger of the input values. +** +** Dependencies: None. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** N/A 06-02-2004 JWS Original +** +****************************************************************************/ +static UData_t MT2063_umax(UData_t a, UData_t b) +{ + return (a >= b) ? a : b; +} + +#if MT2063_TUNER_CNT > 1 +static SData_t RoundAwayFromZero(SData_t n, SData_t d) +{ + return (n < 0) ? floor(n, d) : ceil(n, d); +} + +/**************************************************************************** +** +** Name: IsSpurInAdjTunerBand +** +** Description: Checks to see if a spur will be present within the IF's +** bandwidth or near the zero IF. +** (fIFOut +/- fIFBW/2, -fIFOut +/- fIFBW/2) +** and +** (0 +/- fZIFBW/2) +** +** ma mb me mf mc md +** <--+-+-+-----------------+-+-+-----------------+-+-+--> +** | ^ 0 ^ | +** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^ +** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2 +** +** Note that some equations are doubled to prevent round-off +** problems when calculating fIFBW/2 +** +** The spur frequencies are computed as: +** +** fSpur = n * f1 - m * f2 - fOffset +** +** Parameters: f1 - The 1st local oscillator (LO) frequency +** of the tuner whose output we are examining +** f2 - The 1st local oscillator (LO) frequency +** of the adjacent tuner +** fOffset - The 2nd local oscillator of the tuner whose +** output we are examining +** fIFOut - Output IF center frequency +** fIFBW - Output IF Bandwidth +** nMaxH - max # of LO harmonics to search +** fp - If spur, positive distance to spur-free band edge (returned) +** fm - If spur, negative distance to spur-free band edge (returned) +** +** Returns: 1 if an LO spur would be present, otherwise 0. +** +** Dependencies: None. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** N/A 01-21-2005 JWS Original, adapted from MT_DoubleConversion. +** 115 03-23-2007 DAD Fix declaration of spur due to truncation +** errors. +** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for +** multi-tuners that have +** (delta IF1) > (f_out-f_outbw/2). +** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2 +** Type casts added to preserve correct sign. +** +****************************************************************************/ +static UData_t IsSpurInAdjTunerBand(UData_t bIsMyOutput, + UData_t f1, + UData_t f2, + UData_t fOffset, + UData_t fIFOut, + UData_t fIFBW, + UData_t fZIFBW, + UData_t nMaxH, UData_t * fp, UData_t * fm) +{ + UData_t bSpurFound = 0; + + const UData_t fHalf_IFBW = fIFBW / 2; + const UData_t fHalf_ZIFBW = fZIFBW / 2; + + /* Calculate a scale factor for all frequencies, so that our + calculations all stay within 31 bits */ + const UData_t f_Scale = + ((f1 + + (fOffset + fIFOut + + fHalf_IFBW) / nMaxH) / (MAX_UDATA / 2 / nMaxH)) + 1; + + /* + ** After this scaling, _f1, _f2, and _f3 are guaranteed to fit into + ** signed data types (smaller than MAX_UDATA/2) + */ + const SData_t _f1 = (SData_t) (f1 / f_Scale); + const SData_t _f2 = (SData_t) (f2 / f_Scale); + const SData_t _f3 = (SData_t) (fOffset / f_Scale); + + const SData_t c = (SData_t) (fIFOut - fHalf_IFBW) / (SData_t) f_Scale; + const SData_t d = (SData_t) ((fIFOut + fHalf_IFBW) / f_Scale); + const SData_t f = (SData_t) (fHalf_ZIFBW / f_Scale); + + SData_t ma, mb, mc, md, me, mf; + + SData_t fp_ = 0; + SData_t fm_ = 0; + SData_t n; + + /* + ** If the other tuner does not have an LO frequency defined, + ** assume that we cannot interfere with it + */ + if (f2 == 0) + return 0; + + /* Check out all multiples of f1 from -nMaxH to +nMaxH */ + for (n = -(SData_t) nMaxH; n <= (SData_t) nMaxH; ++n) { + const SData_t nf1 = n * _f1; + md = (_f3 + d - nf1) / _f2; + + /* If # f2 harmonics > nMaxH, then no spurs present */ + if (md <= -(SData_t) nMaxH) + break; + + ma = (_f3 - d - nf1) / _f2; + if ((ma == md) || (ma >= (SData_t) (nMaxH))) + continue; + + mc = (_f3 + c - nf1) / _f2; + if (mc != md) { + const SData_t m = (n < 0) ? md : mc; + const SData_t fspur = (nf1 + m * _f2 - _f3); + const SData_t den = (bIsMyOutput ? n - 1 : n); + if (den == 0) { + fp_ = (d - fspur) * f_Scale; + fm_ = (fspur - c) * f_Scale; + } else { + fp_ = + (SData_t) RoundAwayFromZero((d - fspur) * + f_Scale, den); + fm_ = + (SData_t) RoundAwayFromZero((fspur - c) * + f_Scale, den); + } + if (((UData_t) abs(fm_) >= f_Scale) + && ((UData_t) abs(fp_) >= f_Scale)) { + bSpurFound = 1; + break; + } + } + + /* Location of Zero-IF-spur to be checked */ + mf = (_f3 + f - nf1) / _f2; + me = (_f3 - f - nf1) / _f2; + if (me != mf) { + const SData_t m = (n < 0) ? mf : me; + const SData_t fspur = (nf1 + m * _f2 - _f3); + const SData_t den = (bIsMyOutput ? n - 1 : n); + if (den == 0) { + fp_ = (d - fspur) * f_Scale; + fm_ = (fspur - c) * f_Scale; + } else { + fp_ = + (SData_t) RoundAwayFromZero((f - fspur) * + f_Scale, den); + fm_ = + (SData_t) RoundAwayFromZero((fspur + f) * + f_Scale, den); + } + if (((UData_t) abs(fm_) >= f_Scale) + && ((UData_t) abs(fp_) >= f_Scale)) { + bSpurFound = 1; + break; + } + } + + mb = (_f3 - c - nf1) / _f2; + if (ma != mb) { + const SData_t m = (n < 0) ? mb : ma; + const SData_t fspur = (nf1 + m * _f2 - _f3); + const SData_t den = (bIsMyOutput ? n - 1 : n); + if (den == 0) { + fp_ = (d - fspur) * f_Scale; + fm_ = (fspur - c) * f_Scale; + } else { + fp_ = + (SData_t) RoundAwayFromZero((-c - fspur) * + f_Scale, den); + fm_ = + (SData_t) RoundAwayFromZero((fspur + d) * + f_Scale, den); + } + if (((UData_t) abs(fm_) >= f_Scale) + && ((UData_t) abs(fp_) >= f_Scale)) { + bSpurFound = 1; + break; + } + } + } + + /* + ** Verify that fm & fp are both positive + ** Add one to ensure next 1st IF choice is not right on the edge + */ + if (fp_ < 0) { + *fp = -fm_ + 1; + *fm = -fp_ + 1; + } else if (fp_ > 0) { + *fp = fp_ + 1; + *fm = fm_ + 1; + } else { + *fp = 1; + *fm = abs(fm_) + 1; + } + + return bSpurFound; +} +#endif + +/**************************************************************************** +** +** Name: IsSpurInBand +** +** Description: Checks to see if a spur will be present within the IF's +** bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW) +** +** ma mb mc md +** <--+-+-+-------------------+-------------------+-+-+--> +** | ^ 0 ^ | +** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^ +** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2 +** +** Note that some equations are doubled to prevent round-off +** problems when calculating fIFBW/2 +** +** Parameters: pAS_Info - Avoid Spurs information block +** fm - If spur, amount f_IF1 has to move negative +** fp - If spur, amount f_IF1 has to move positive +** +** Global: None +** +** Returns: 1 if an LO spur would be present, otherwise 0. +** +** Dependencies: None. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** N/A 11-28-2002 DAD Implemented algorithm from applied patent +** +****************************************************************************/ +static UData_t IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info, + UData_t * fm, UData_t * fp) +{ + /* + ** Calculate LO frequency settings. + */ + UData_t n, n0; + const UData_t f_LO1 = pAS_Info->f_LO1; + const UData_t f_LO2 = pAS_Info->f_LO2; + const UData_t d = pAS_Info->f_out + pAS_Info->f_out_bw / 2; + const UData_t c = d - pAS_Info->f_out_bw; + const UData_t f = pAS_Info->f_zif_bw / 2; + const UData_t f_Scale = (f_LO1 / (MAX_UDATA / 2 / pAS_Info->maxH1)) + 1; + SData_t f_nsLO1, f_nsLO2; + SData_t f_Spur; + UData_t ma, mb, mc, md, me, mf; + UData_t lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs; +#if MT2063_TUNER_CNT > 1 + UData_t index; + + struct MT2063_AvoidSpursData_t *adj; +#endif + *fm = 0; + + /* + ** For each edge (d, c & f), calculate a scale, based on the gcd + ** of f_LO1, f_LO2 and the edge value. Use the larger of this + ** gcd-based scale factor or f_Scale. + */ + lo_gcd = MT2063_gcd(f_LO1, f_LO2); + gd_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, d), f_Scale); + hgds = gd_Scale / 2; + gc_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, c), f_Scale); + hgcs = gc_Scale / 2; + gf_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, f), f_Scale); + hgfs = gf_Scale / 2; + + n0 = uceil(f_LO2 - d, f_LO1 - f_LO2); + + /* Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic */ + for (n = n0; n <= pAS_Info->maxH1; ++n) { + md = (n * ((f_LO1 + hgds) / gd_Scale) - + ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale); + + /* If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present */ + if (md >= pAS_Info->maxH1) + break; + + ma = (n * ((f_LO1 + hgds) / gd_Scale) + + ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale); + + /* If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic */ + if (md == ma) + continue; + + mc = (n * ((f_LO1 + hgcs) / gc_Scale) - + ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale); + if (mc != md) { + f_nsLO1 = (SData_t) (n * (f_LO1 / gc_Scale)); + f_nsLO2 = (SData_t) (mc * (f_LO2 / gc_Scale)); + f_Spur = + (gc_Scale * (f_nsLO1 - f_nsLO2)) + + n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale); + + *fp = ((f_Spur - (SData_t) c) / (mc - n)) + 1; + *fm = (((SData_t) d - f_Spur) / (mc - n)) + 1; + return 1; + } + + /* Location of Zero-IF-spur to be checked */ + me = (n * ((f_LO1 + hgfs) / gf_Scale) + + ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale); + mf = (n * ((f_LO1 + hgfs) / gf_Scale) - + ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale); + if (me != mf) { + f_nsLO1 = n * (f_LO1 / gf_Scale); + f_nsLO2 = me * (f_LO2 / gf_Scale); + f_Spur = + (gf_Scale * (f_nsLO1 - f_nsLO2)) + + n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale); + + *fp = ((f_Spur + (SData_t) f) / (me - n)) + 1; + *fm = (((SData_t) f - f_Spur) / (me - n)) + 1; + return 1; + } + + mb = (n * ((f_LO1 + hgcs) / gc_Scale) + + ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale); + if (ma != mb) { + f_nsLO1 = n * (f_LO1 / gc_Scale); + f_nsLO2 = ma * (f_LO2 / gc_Scale); + f_Spur = + (gc_Scale * (f_nsLO1 - f_nsLO2)) + + n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale); + + *fp = (((SData_t) d + f_Spur) / (ma - n)) + 1; + *fm = (-(f_Spur + (SData_t) c) / (ma - n)) + 1; + return 1; + } + } + +#if MT2063_TUNER_CNT > 1 + /* If no spur found, see if there are more tuners on the same board */ + for (index = 0; index < TunerCount; ++index) { + adj = TunerList[index]; + if (pAS_Info == adj) /* skip over our own data, don't process it */ + continue; + + /* Look for LO-related spurs from the adjacent tuner generated into my IF output */ + if (IsSpurInAdjTunerBand(1, /* check my IF output */ + pAS_Info->f_LO1, /* my fLO1 */ + adj->f_LO1, /* the other tuner's fLO1 */ + pAS_Info->f_LO2, /* my fLO2 */ + pAS_Info->f_out, /* my fOut */ + pAS_Info->f_out_bw, /* my output IF bandwidth */ + pAS_Info->f_zif_bw, /* my Zero-IF bandwidth */ + pAS_Info->maxH2, fp, /* minimum amount to move LO's positive */ + fm)) /* miminum amount to move LO's negative */ + return 1; + /* Look for LO-related spurs from my tuner generated into the adjacent tuner's IF output */ + if (IsSpurInAdjTunerBand(0, /* check his IF output */ + pAS_Info->f_LO1, /* my fLO1 */ + adj->f_LO1, /* the other tuner's fLO1 */ + adj->f_LO2, /* the other tuner's fLO2 */ + adj->f_out, /* the other tuner's fOut */ + adj->f_out_bw, /* the other tuner's output IF bandwidth */ + pAS_Info->f_zif_bw, /* the other tuner's Zero-IF bandwidth */ + adj->maxH2, fp, /* minimum amount to move LO's positive */ + fm)) /* miminum amount to move LO's negative */ + return 1; + } +#endif + /* No spurs found */ return 0; } - -static int mt2063_get_status(struct dvb_frontend *fe, u32 *status) + +/***************************************************************************** +** +** Name: MT_AvoidSpurs +** +** Description: Main entry point to avoid spurs. +** Checks for existing spurs in present LO1, LO2 freqs +** and if present, chooses spur-free LO1, LO2 combination +** that tunes the same input/output frequencies. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0. +** +*****************************************************************************/ +UData_t MT2063_AvoidSpurs(Handle_t h, struct MT2063_AvoidSpursData_t * pAS_Info) { - int rc = 0; - - //get tuner lock status - - return rc; + UData_t status = MT2063_OK; + UData_t fm, fp; /* restricted range on LO's */ + pAS_Info->bSpurAvoided = 0; + pAS_Info->nSpursFound = 0; + + if (pAS_Info->maxH1 == 0) + return MT2063_OK; + + /* + ** Avoid LO Generated Spurs + ** + ** Make sure that have no LO-related spurs within the IF output + ** bandwidth. + ** + ** If there is an LO spur in this band, start at the current IF1 frequency + ** and work out until we find a spur-free frequency or run up against the + ** 1st IF SAW band edge. Use temporary copies of fLO1 and fLO2 so that they + ** will be unchanged if a spur-free setting is not found. + */ + pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp); + if (pAS_Info->bSpurPresent) { + UData_t zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in; /* current attempt at a 1st IF */ + UData_t zfLO1 = pAS_Info->f_LO1; /* current attempt at an LO1 freq */ + UData_t zfLO2 = pAS_Info->f_LO2; /* current attempt at an LO2 freq */ + UData_t delta_IF1; + UData_t new_IF1; + + /* + ** Spur was found, attempt to find a spur-free 1st IF + */ + do { + pAS_Info->nSpursFound++; + + /* Raise f_IF1_upper, if needed */ + MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp); + + /* Choose next IF1 that is closest to f_IF1_CENTER */ + new_IF1 = MT2063_ChooseFirstIF(pAS_Info); + + if (new_IF1 > zfIF1) { + pAS_Info->f_LO1 += (new_IF1 - zfIF1); + pAS_Info->f_LO2 += (new_IF1 - zfIF1); + } else { + pAS_Info->f_LO1 -= (zfIF1 - new_IF1); + pAS_Info->f_LO2 -= (zfIF1 - new_IF1); + } + zfIF1 = new_IF1; + + if (zfIF1 > pAS_Info->f_if1_Center) + delta_IF1 = zfIF1 - pAS_Info->f_if1_Center; + else + delta_IF1 = pAS_Info->f_if1_Center - zfIF1; + } + /* + ** Continue while the new 1st IF is still within the 1st IF bandwidth + ** and there is a spur in the band (again) + */ + while ((2 * delta_IF1 + pAS_Info->f_out_bw <= + pAS_Info->f_if1_bw) + && (pAS_Info->bSpurPresent = + IsSpurInBand(pAS_Info, &fm, &fp))); + + /* + ** Use the LO-spur free values found. If the search went all the way to + ** the 1st IF band edge and always found spurs, just leave the original + ** choice. It's as "good" as any other. + */ + if (pAS_Info->bSpurPresent == 1) { + status |= MT2063_SPUR_PRESENT_ERR; + pAS_Info->f_LO1 = zfLO1; + pAS_Info->f_LO2 = zfLO2; + } else + pAS_Info->bSpurAvoided = 1; + } + + status |= + ((pAS_Info-> + nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK); + + return (status); } - - -static int mt2063_get_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *state) -{ - struct mt2063_state *mt2063State = fe->tuner_priv; - + +UData_t MT2063_AvoidSpursVersion(void) +{ + return (MT2063_SPUR_VERSION); +} + +//end of mt2063_spuravoid.c +//================================================================= +//################################################################# +//================================================================= + +/* +** The expected version of MT_AvoidSpursData_t +** If the version is different, an updated file is needed from Microtune +*/ +/* Expecting version 1.21 of the Spur Avoidance API */ +#define EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION 010201 + +#if MT2063_AVOID_SPURS_INFO_VERSION < EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION +#error Contact Microtune for a newer version of MT_SpurAvoid.c +#elif MT2063_AVOID_SPURS_INFO_VERSION > EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION +#error Contact Microtune for a newer version of mt2063.c +#endif + +#ifndef MT2063_CNT +#error You must define MT2063_CNT in the "mt_userdef.h" file +#endif + +typedef enum { + MT2063_SET_ATTEN, + MT2063_INCR_ATTEN, + MT2063_DECR_ATTEN +} MT2063_ATTEN_CNTL_MODE; + +//#define TUNER_MT2063_OPTIMIZATION +/* +** Constants used by the tuning algorithm +*/ +#define MT2063_REF_FREQ (16000000UL) /* Reference oscillator Frequency (in Hz) */ +#define MT2063_IF1_BW (22000000UL) /* The IF1 filter bandwidth (in Hz) */ +#define MT2063_TUNE_STEP_SIZE (50000UL) /* Tune in steps of 50 kHz */ +#define MT2063_SPUR_STEP_HZ (250000UL) /* Step size (in Hz) to move IF1 when avoiding spurs */ +#define MT2063_ZIF_BW (2000000UL) /* Zero-IF spur-free bandwidth (in Hz) */ +#define MT2063_MAX_HARMONICS_1 (15UL) /* Highest intra-tuner LO Spur Harmonic to be avoided */ +#define MT2063_MAX_HARMONICS_2 (5UL) /* Highest inter-tuner LO Spur Harmonic to be avoided */ +#define MT2063_MIN_LO_SEP (1000000UL) /* Minimum inter-tuner LO frequency separation */ +#define MT2063_LO1_FRACN_AVOID (0UL) /* LO1 FracN numerator avoid region (in Hz) */ +#define MT2063_LO2_FRACN_AVOID (199999UL) /* LO2 FracN numerator avoid region (in Hz) */ +#define MT2063_MIN_FIN_FREQ (44000000UL) /* Minimum input frequency (in Hz) */ +#define MT2063_MAX_FIN_FREQ (1100000000UL) /* Maximum input frequency (in Hz) */ +#define MT2063_MIN_FOUT_FREQ (36000000UL) /* Minimum output frequency (in Hz) */ +#define MT2063_MAX_FOUT_FREQ (57000000UL) /* Maximum output frequency (in Hz) */ +#define MT2063_MIN_DNC_FREQ (1293000000UL) /* Minimum LO2 frequency (in Hz) */ +#define MT2063_MAX_DNC_FREQ (1614000000UL) /* Maximum LO2 frequency (in Hz) */ +#define MT2063_MIN_UPC_FREQ (1396000000UL) /* Minimum LO1 frequency (in Hz) */ +#define MT2063_MAX_UPC_FREQ (2750000000UL) /* Maximum LO1 frequency (in Hz) */ + +/* +** Define the supported Part/Rev codes for the MT2063 +*/ +#define MT2063_B0 (0x9B) +#define MT2063_B1 (0x9C) +#define MT2063_B2 (0x9D) +#define MT2063_B3 (0x9E) + +/* +** The number of Tuner Registers +*/ +static const UData_t MT2063_Num_Registers = MT2063_REG_END_REGS; + +#define USE_GLOBAL_TUNER 0 + +static UData_t nMT2063MaxTuners = MT2063_CNT; +static struct MT2063_Info_t MT2063_Info[MT2063_CNT]; +static struct MT2063_Info_t *MT2063_Avail[MT2063_CNT]; +static UData_t nMT2063OpenTuners = 0; + +/* +** Constants for setting receiver modes. +** (6 modes defined at this time, enumerated by MT2063_RCVR_MODES) +** (DNC1GC & DNC2GC are the values, which are used, when the specific +** DNC Output is selected, the other is always off) +** +** If PAL-L or L' is received, set: +** MT2063_SetParam(hMT2063,MT2063_TAGC,1); +** +** --------------+---------------------------------------------- +** Mode 0 : | MT2063_CABLE_QAM +** Mode 1 : | MT2063_CABLE_ANALOG +** Mode 2 : | MT2063_OFFAIR_COFDM +** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS +** Mode 4 : | MT2063_OFFAIR_ANALOG +** Mode 5 : | MT2063_OFFAIR_8VSB +** --------------+----+----+----+----+-----+-----+-------------- +** Mode | 0 | 1 | 2 | 3 | 4 | 5 | +** --------------+----+----+----+----+-----+-----+ +** +** +*/ +static const U8Data RFAGCEN[] = { 0, 0, 0, 0, 0, 0 }; +static const U8Data LNARIN[] = { 0, 0, 3, 3, 3, 3 }; +static const U8Data FIFFQEN[] = { 1, 1, 1, 1, 1, 1 }; +static const U8Data FIFFQ[] = { 0, 0, 0, 0, 0, 0 }; +static const U8Data DNC1GC[] = { 0, 0, 0, 0, 0, 0 }; +static const U8Data DNC2GC[] = { 0, 0, 0, 0, 0, 0 }; +static const U8Data ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 }; +static const U8Data LNATGT[] = { 44, 43, 43, 43, 43, 43 }; +static const U8Data RFOVDIS[] = { 0, 0, 0, 0, 0, 0 }; +static const U8Data ACRFMAX[] = { 31, 31, 31, 31, 31, 31 }; +static const U8Data PD1TGT[] = { 36, 36, 38, 38, 36, 38 }; +static const U8Data FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 }; +static const U8Data ACFIFMAX[] = { 29, 29, 29, 29, 29, 29 }; +static const U8Data PD2TGT[] = { 40, 33, 38, 42, 30, 38 }; + +/* +** Local Function Prototypes - not available for external access. +*/ + +/* Forward declaration(s): */ +static UData_t MT2063_CalcLO1Mult(UData_t * Div, UData_t * FracN, UData_t f_LO, + UData_t f_LO_Step, UData_t f_Ref); +static UData_t MT2063_CalcLO2Mult(UData_t * Div, UData_t * FracN, UData_t f_LO, + UData_t f_LO_Step, UData_t f_Ref); +static UData_t MT2063_fLO_FractionalTerm(UData_t f_ref, UData_t num, + UData_t denom); + +/****************************************************************************** +** +** Name: MT2063_Open +** +** Description: Initialize the tuner's register values. +** +** Parameters: MT2063_Addr - Serial bus address of the tuner. +** hMT2063 - Tuner handle passed back. +** hUserData - User-defined data, if needed for the +** MT_ReadSub() & MT_WriteSub functions. +** +** Returns: status: +** MT_OK - No errors +** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch +** MT_TUNER_INIT_ERR - Tuner initialization failed +** MT_COMM_ERR - Serial bus communications error +** MT_ARG_NULL - Null pointer argument passed +** MT_TUNER_CNT_ERR - Too many tuners open +** +** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus +** MT_WriteSub - Write byte(s) of data to the two-wire bus +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +******************************************************************************/ +UData_t MT2063_Open(UData_t MT2063_Addr, Handle_t * hMT2063, Handle_t hUserData) +{ + UData_t status = MT2063_OK; /* Status to be returned. */ + SData_t i; + struct MT2063_Info_t *pInfo = NULL; + struct dvb_frontend *fe = (struct dvb_frontend *)hUserData; + struct mt2063_state *state = fe->tuner_priv; + + /* Check the argument before using */ + if (hMT2063 == NULL) { + return MT2063_ARG_NULL; + } + + /* Default tuner handle to NULL. If successful, it will be reassigned */ + +#if USE_GLOBAL_TUNER + *hMT2063 = NULL; + + /* + ** If this is our first tuner, initialize the address fields and + ** the list of available control blocks. + */ + if (nMT2063OpenTuners == 0) { + for (i = MT2063_CNT - 1; i >= 0; i--) { + MT2063_Info[i].handle = NULL; + MT2063_Info[i].address = MAX_UDATA; + MT2063_Info[i].rcvr_mode = MT2063_CABLE_QAM; + MT2063_Info[i].hUserData = NULL; + MT2063_Avail[i] = &MT2063_Info[i]; + } + } + + /* + ** Look for an existing MT2063_State_t entry with this address. + */ + for (i = MT2063_CNT - 1; i >= 0; i--) { + /* + ** If an open'ed handle provided, we'll re-initialize that structure. + ** + ** We recognize an open tuner because the address and hUserData are + ** the same as one that has already been opened + */ + if ((MT2063_Info[i].address == MT2063_Addr) && + (MT2063_Info[i].hUserData == hUserData)) { + pInfo = &MT2063_Info[i]; + break; + } + } + + /* If not found, choose an empty spot. */ + if (pInfo == NULL) { + /* Check to see that we're not over-allocating */ + if (nMT2063OpenTuners == MT2063_CNT) { + return MT2063_TUNER_CNT_ERR; + } + /* Use the next available block from the list */ + pInfo = MT2063_Avail[nMT2063OpenTuners]; + nMT2063OpenTuners++; + } +#else + if (state->MT2063_init == FALSE) { + pInfo = kzalloc(sizeof(struct MT2063_Info_t), GFP_KERNEL); + if (pInfo == NULL) { + return MT2063_TUNER_OPEN_ERR; + } + pInfo->handle = NULL; + pInfo->address = MAX_UDATA; + pInfo->rcvr_mode = MT2063_CABLE_QAM; + pInfo->hUserData = NULL; + } else { + pInfo = *hMT2063; + } +#endif + + if (MT2063_NO_ERROR(status)) { + status |= MT2063_RegisterTuner(&pInfo->AS_Data); + } + + if (MT2063_NO_ERROR(status)) { + pInfo->handle = (Handle_t) pInfo; + + pInfo->hUserData = hUserData; + pInfo->address = MT2063_Addr; + pInfo->rcvr_mode = MT2063_CABLE_QAM; + status |= MT2063_ReInit((Handle_t) pInfo); + } + + if (MT2063_IS_ERROR(status)) + /* MT2063_Close handles the un-registration of the tuner */ + MT2063_Close((Handle_t) pInfo); + else { + state->MT2063_init = TRUE; + *hMT2063 = pInfo->handle; + + } + + return (status); +} + +static UData_t MT2063_IsValidHandle(struct MT2063_Info_t *handle) +{ + return ((handle != NULL) && (handle->handle == handle)) ? 1 : 0; +} + +/****************************************************************************** +** +** Name: MT2063_Close +** +** Description: Release the handle to the tuner. +** +** Parameters: hMT2063 - Handle to the MT2063 tuner +** +** Returns: status: +** MT_OK - No errors +** MT_INV_HANDLE - Invalid tuner handle +** +** Dependencies: mt_errordef.h - definition of error codes +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +******************************************************************************/ +UData_t MT2063_Close(Handle_t hMT2063) +{ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)hMT2063; + + if (!MT2063_IsValidHandle(pInfo)) + return MT2063_INV_HANDLE; + + /* Unregister tuner with SpurAvoidance routines (if needed) */ + MT2063_UnRegisterTuner(&pInfo->AS_Data); + /* Now remove the tuner from our own list of tuners */ + pInfo->handle = NULL; + pInfo->address = MAX_UDATA; + pInfo->hUserData = NULL; +#if USE_GLOBAL_TUNER + nMT2063OpenTuners--; + MT2063_Avail[nMT2063OpenTuners] = pInfo; /* Return control block to available list */ +#else + //kfree(pInfo); + //pInfo = NULL; +#endif + return MT2063_OK; +} + +/****************************************************************************** +** +** Name: MT2063_GetGPIO +** +** Description: Get the current MT2063 GPIO value. +** +** Parameters: h - Open handle to the tuner (from MT2063_Open). +** gpio_id - Selects GPIO0, GPIO1 or GPIO2 +** attr - Selects input readback, I/O direction or +** output value +** *value - current setting of GPIO pin +** +** Usage: status = MT2063_GetGPIO(hMT2063, MT2063_GPIO_OUT, &value); +** +** Returns: status: +** MT_OK - No errors +** MT_COMM_ERR - Serial bus communications error +** MT_INV_HANDLE - Invalid tuner handle +** MT_ARG_NULL - Null pointer argument passed +** +** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +******************************************************************************/ +UData_t MT2063_GetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id, + enum MT2063_GPIO_Attr attr, UData_t * value) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + U8Data regno; + SData_t shift; + static U8Data GPIOreg[3] = + { MT2063_REG_RF_STATUS, MT2063_REG_FIF_OV, MT2063_REG_RF_OV }; + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + if (MT2063_IsValidHandle(pInfo) == 0) + return MT2063_INV_HANDLE; + + if (value == NULL) + return MT2063_ARG_NULL; + + regno = GPIOreg[attr]; + + /* We'll read the register just in case the write didn't work last time */ + status = + MT2063_ReadSub(pInfo->hUserData, pInfo->address, regno, + &pInfo->reg[regno], 1); + + shift = (gpio_id - MT2063_GPIO0 + 5); + *value = (pInfo->reg[regno] >> shift) & 1; + + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_GetLocked +** +** Description: Checks to see if LO1 and LO2 are locked. +** +** Parameters: h - Open handle to the tuner (from MT2063_Open). +** +** Returns: status: +** MT_OK - No errors +** MT_UPC_UNLOCK - Upconverter PLL unlocked +** MT_DNC_UNLOCK - Downconverter PLL unlocked +** MT_COMM_ERR - Serial bus communications error +** MT_INV_HANDLE - Invalid tuner handle +** +** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus +** MT_Sleep - Delay execution for x milliseconds +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +****************************************************************************/ +UData_t MT2063_GetLocked(Handle_t h) +{ + const UData_t nMaxWait = 100; /* wait a maximum of 100 msec */ + const UData_t nPollRate = 2; /* poll status bits every 2 ms */ + const UData_t nMaxLoops = nMaxWait / nPollRate; + const U8Data LO1LK = 0x80; + U8Data LO2LK = 0x08; + UData_t status = MT2063_OK; /* Status to be returned */ + UData_t nDelays = 0; + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + if (MT2063_IsValidHandle(pInfo) == 0) + return MT2063_INV_HANDLE; + + /* LO2 Lock bit was in a different place for B0 version */ + if (pInfo->tuner_id == MT2063_B0) + LO2LK = 0x40; + + do { + status |= + MT2063_ReadSub(pInfo->hUserData, pInfo->address, + MT2063_REG_LO_STATUS, + &pInfo->reg[MT2063_REG_LO_STATUS], 1); + + if (MT2063_IS_ERROR(status)) + return (status); + + if ((pInfo->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) == + (LO1LK | LO2LK)) { + return (status); + } + MT2063_Sleep(pInfo->hUserData, nPollRate); /* Wait between retries */ + } + while (++nDelays < nMaxLoops); + + if ((pInfo->reg[MT2063_REG_LO_STATUS] & LO1LK) == 0x00) + status |= MT2063_UPC_UNLOCK; + if ((pInfo->reg[MT2063_REG_LO_STATUS] & LO2LK) == 0x00) + status |= MT2063_DNC_UNLOCK; + + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_GetParam +** +** Description: Gets a tuning algorithm parameter. +** +** This function provides access to the internals of the +** tuning algorithm - mostly for testing purposes. +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** param - Tuning algorithm parameter +** (see enum MT2063_Param) +** pValue - ptr to returned value +** +** param Description +** ---------------------- -------------------------------- +** MT2063_IC_ADDR Serial Bus address of this tuner +** MT2063_MAX_OPEN Max # of MT2063's allowed open +** MT2063_NUM_OPEN # of MT2063's open +** MT2063_SRO_FREQ crystal frequency +** MT2063_STEPSIZE minimum tuning step size +** MT2063_INPUT_FREQ input center frequency +** MT2063_LO1_FREQ LO1 Frequency +** MT2063_LO1_STEPSIZE LO1 minimum step size +** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region +** MT2063_IF1_ACTUAL Current 1st IF in use +** MT2063_IF1_REQUEST Requested 1st IF +** MT2063_IF1_CENTER Center of 1st IF SAW filter +** MT2063_IF1_BW Bandwidth of 1st IF SAW filter +** MT2063_ZIF_BW zero-IF bandwidth +** MT2063_LO2_FREQ LO2 Frequency +** MT2063_LO2_STEPSIZE LO2 minimum step size +** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region +** MT2063_OUTPUT_FREQ output center frequency +** MT2063_OUTPUT_BW output bandwidth +** MT2063_LO_SEPARATION min inter-tuner LO separation +** MT2063_AS_ALG ID of avoid-spurs algorithm in use +** MT2063_MAX_HARM1 max # of intra-tuner harmonics +** MT2063_MAX_HARM2 max # of inter-tuner harmonics +** MT2063_EXCL_ZONES # of 1st IF exclusion zones +** MT2063_NUM_SPURS # of spurs found/avoided +** MT2063_SPUR_AVOIDED >0 spurs avoided +** MT2063_SPUR_PRESENT >0 spurs in output (mathematically) +** MT2063_RCVR_MODE Predefined modes. +** MT2063_ACLNA LNA attenuator gain code +** MT2063_ACRF RF attenuator gain code +** MT2063_ACFIF FIF attenuator gain code +** MT2063_ACLNA_MAX LNA attenuator limit +** MT2063_ACRF_MAX RF attenuator limit +** MT2063_ACFIF_MAX FIF attenuator limit +** MT2063_PD1 Actual value of PD1 +** MT2063_PD2 Actual value of PD2 +** MT2063_DNC_OUTPUT_ENABLE DNC output selection +** MT2063_VGAGC VGA gain code +** MT2063_VGAOI VGA output current +** MT2063_TAGC TAGC setting +** MT2063_AMPGC AMP gain code +** MT2063_AVOID_DECT Avoid DECT Frequencies +** MT2063_CTFILT_SW Cleartune filter selection +** +** Usage: status |= MT2063_GetParam(hMT2063, +** MT2063_IF1_ACTUAL, +** &f_IF1_Actual); +** +** Returns: status: +** MT_OK - No errors +** MT_INV_HANDLE - Invalid tuner handle +** MT_ARG_NULL - Null pointer argument passed +** MT_ARG_RANGE - Invalid parameter requested +** +** Dependencies: USERS MUST CALL MT2063_Open() FIRST! +** +** See Also: MT2063_SetParam, MT2063_Open +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ +** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC +** 173 M 01-23-2008 RSK Ver 1.12: Read LO1C and LO2C registers from HW +** in GetParam. +** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT +** Split SetParam up to ACLNA / ACLNA_MAX +** removed ACLNA_INRC/DECR (+RF & FIF) +** removed GCUAUTO / BYPATNDN/UP +** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. +** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. +** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW +** +****************************************************************************/ +UData_t MT2063_GetParam(Handle_t h, enum MT2063_Param param, UData_t * pValue) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + UData_t Div; + UData_t Num; + + if (pValue == NULL) + status |= MT2063_ARG_NULL; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + status |= MT2063_INV_HANDLE; + + if (MT2063_NO_ERROR(status)) { + switch (param) { + /* Serial Bus address of this tuner */ + case MT2063_IC_ADDR: + *pValue = pInfo->address; + break; + + /* Max # of MT2063's allowed to be open */ + case MT2063_MAX_OPEN: + *pValue = nMT2063MaxTuners; + break; + + /* # of MT2063's open */ + case MT2063_NUM_OPEN: + *pValue = nMT2063OpenTuners; + break; + + /* crystal frequency */ + case MT2063_SRO_FREQ: + *pValue = pInfo->AS_Data.f_ref; + break; + + /* minimum tuning step size */ + case MT2063_STEPSIZE: + *pValue = pInfo->AS_Data.f_LO2_Step; + break; + + /* input center frequency */ + case MT2063_INPUT_FREQ: + *pValue = pInfo->AS_Data.f_in; + break; + + /* LO1 Frequency */ + case MT2063_LO1_FREQ: + { + /* read the actual tuner register values for LO1C_1 and LO1C_2 */ + status |= + MT2063_ReadSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO1C_1, + &pInfo-> + reg[MT2063_REG_LO1C_1], 2); + Div = pInfo->reg[MT2063_REG_LO1C_1]; + Num = pInfo->reg[MT2063_REG_LO1C_2] & 0x3F; + pInfo->AS_Data.f_LO1 = + (pInfo->AS_Data.f_ref * Div) + + MT2063_fLO_FractionalTerm(pInfo->AS_Data. + f_ref, Num, 64); + } + *pValue = pInfo->AS_Data.f_LO1; + break; + + /* LO1 minimum step size */ + case MT2063_LO1_STEPSIZE: + *pValue = pInfo->AS_Data.f_LO1_Step; + break; + + /* LO1 FracN keep-out region */ + case MT2063_LO1_FRACN_AVOID_PARAM: + *pValue = pInfo->AS_Data.f_LO1_FracN_Avoid; + break; + + /* Current 1st IF in use */ + case MT2063_IF1_ACTUAL: + *pValue = pInfo->f_IF1_actual; + break; + + /* Requested 1st IF */ + case MT2063_IF1_REQUEST: + *pValue = pInfo->AS_Data.f_if1_Request; + break; + + /* Center of 1st IF SAW filter */ + case MT2063_IF1_CENTER: + *pValue = pInfo->AS_Data.f_if1_Center; + break; + + /* Bandwidth of 1st IF SAW filter */ + case MT2063_IF1_BW: + *pValue = pInfo->AS_Data.f_if1_bw; + break; + + /* zero-IF bandwidth */ + case MT2063_ZIF_BW: + *pValue = pInfo->AS_Data.f_zif_bw; + break; + + /* LO2 Frequency */ + case MT2063_LO2_FREQ: + { + /* Read the actual tuner register values for LO2C_1, LO2C_2 and LO2C_3 */ + status |= + MT2063_ReadSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO2C_1, + &pInfo-> + reg[MT2063_REG_LO2C_1], 3); + Div = + (pInfo->reg[MT2063_REG_LO2C_1] & 0xFE) >> 1; + Num = + ((pInfo-> + reg[MT2063_REG_LO2C_1] & 0x01) << 12) | + (pInfo-> + reg[MT2063_REG_LO2C_2] << 4) | (pInfo-> + reg + [MT2063_REG_LO2C_3] + & 0x00F); + pInfo->AS_Data.f_LO2 = + (pInfo->AS_Data.f_ref * Div) + + MT2063_fLO_FractionalTerm(pInfo->AS_Data. + f_ref, Num, 8191); + } + *pValue = pInfo->AS_Data.f_LO2; + break; + + /* LO2 minimum step size */ + case MT2063_LO2_STEPSIZE: + *pValue = pInfo->AS_Data.f_LO2_Step; + break; + + /* LO2 FracN keep-out region */ + case MT2063_LO2_FRACN_AVOID: + *pValue = pInfo->AS_Data.f_LO2_FracN_Avoid; + break; + + /* output center frequency */ + case MT2063_OUTPUT_FREQ: + *pValue = pInfo->AS_Data.f_out; + break; + + /* output bandwidth */ + case MT2063_OUTPUT_BW: + *pValue = pInfo->AS_Data.f_out_bw - 750000; + break; + + /* min inter-tuner LO separation */ + case MT2063_LO_SEPARATION: + *pValue = pInfo->AS_Data.f_min_LO_Separation; + break; + + /* ID of avoid-spurs algorithm in use */ + case MT2063_AS_ALG: + *pValue = pInfo->AS_Data.nAS_Algorithm; + break; + + /* max # of intra-tuner harmonics */ + case MT2063_MAX_HARM1: + *pValue = pInfo->AS_Data.maxH1; + break; + + /* max # of inter-tuner harmonics */ + case MT2063_MAX_HARM2: + *pValue = pInfo->AS_Data.maxH2; + break; + + /* # of 1st IF exclusion zones */ + case MT2063_EXCL_ZONES: + *pValue = pInfo->AS_Data.nZones; + break; + + /* # of spurs found/avoided */ + case MT2063_NUM_SPURS: + *pValue = pInfo->AS_Data.nSpursFound; + break; + + /* >0 spurs avoided */ + case MT2063_SPUR_AVOIDED: + *pValue = pInfo->AS_Data.bSpurAvoided; + break; + + /* >0 spurs in output (mathematically) */ + case MT2063_SPUR_PRESENT: + *pValue = pInfo->AS_Data.bSpurPresent; + break; + + /* Predefined receiver setup combination */ + case MT2063_RCVR_MODE: + *pValue = pInfo->rcvr_mode; + break; + + case MT2063_PD1: + case MT2063_PD2: + { + U8Data mask = (param == MT2063_PD1 ? 0x01 : 0x03); /* PD1 vs PD2 */ + U8Data orig = (pInfo->reg[MT2063_REG_BYP_CTRL]); + U8Data reg = (orig & 0xF1) | mask; /* Only set 3 bits (not 5) */ + int i; + + *pValue = 0; + + /* Initiate ADC output to reg 0x0A */ + if (reg != orig) + status |= + MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_BYP_CTRL, + ®, 1); + + if (MT2063_IS_ERROR(status)) + return (status); + + for (i = 0; i < 8; i++) { + status |= + MT2063_ReadSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_ADC_OUT, + &pInfo-> + reg + [MT2063_REG_ADC_OUT], + 1); + + if (MT2063_NO_ERROR(status)) + *pValue += + pInfo-> + reg[MT2063_REG_ADC_OUT]; + else { + if (i) + *pValue /= i; + return (status); + } + } + *pValue /= 8; /* divide by number of reads */ + *pValue >>= 2; /* only want 6 MSB's out of 8 */ + + /* Restore value of Register BYP_CTRL */ + if (reg != orig) + status |= + MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_BYP_CTRL, + &orig, 1); + } + break; + + /* Get LNA attenuator code */ + case MT2063_ACLNA: + { + U8Data val; + status |= + MT2063_GetReg(pInfo, MT2063_REG_XO_STATUS, + &val); + *pValue = val & 0x1f; + } + break; + + /* Get RF attenuator code */ + case MT2063_ACRF: + { + U8Data val; + status |= + MT2063_GetReg(pInfo, MT2063_REG_RF_STATUS, + &val); + *pValue = val & 0x1f; + } + break; + + /* Get FIF attenuator code */ + case MT2063_ACFIF: + { + U8Data val; + status |= + MT2063_GetReg(pInfo, MT2063_REG_FIF_STATUS, + &val); + *pValue = val & 0x1f; + } + break; + + /* Get LNA attenuator limit */ + case MT2063_ACLNA_MAX: + { + U8Data val; + status |= + MT2063_GetReg(pInfo, MT2063_REG_LNA_OV, + &val); + *pValue = val & 0x1f; + } + break; + + /* Get RF attenuator limit */ + case MT2063_ACRF_MAX: + { + U8Data val; + status |= + MT2063_GetReg(pInfo, MT2063_REG_RF_OV, + &val); + *pValue = val & 0x1f; + } + break; + + /* Get FIF attenuator limit */ + case MT2063_ACFIF_MAX: + { + U8Data val; + status |= + MT2063_GetReg(pInfo, MT2063_REG_FIF_OV, + &val); + *pValue = val & 0x1f; + } + break; + + /* Get current used DNC output */ + case MT2063_DNC_OUTPUT_ENABLE: + { + if ((pInfo->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) { /* if DNC1 is off */ + if ((pInfo->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */ + *pValue = + (UData_t) MT2063_DNC_NONE; + else + *pValue = + (UData_t) MT2063_DNC_2; + } else { /* DNC1 is on */ + + if ((pInfo->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */ + *pValue = + (UData_t) MT2063_DNC_1; + else + *pValue = + (UData_t) MT2063_DNC_BOTH; + } + } + break; + + /* Get VGA Gain Code */ + case MT2063_VGAGC: + *pValue = + ((pInfo->reg[MT2063_REG_VGA_GAIN] & 0x0C) >> 2); + break; + + /* Get VGA bias current */ + case MT2063_VGAOI: + *pValue = (pInfo->reg[MT2063_REG_RSVD_31] & 0x07); + break; + + /* Get TAGC setting */ + case MT2063_TAGC: + *pValue = (pInfo->reg[MT2063_REG_RSVD_1E] & 0x03); + break; + + /* Get AMP Gain Code */ + case MT2063_AMPGC: + *pValue = (pInfo->reg[MT2063_REG_TEMP_SEL] & 0x03); + break; + + /* Avoid DECT Frequencies */ + case MT2063_AVOID_DECT: + *pValue = pInfo->AS_Data.avoidDECT; + break; + + /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ + case MT2063_CTFILT_SW: + *pValue = pInfo->ctfilt_sw; + break; + + case MT2063_EOP: + default: + status |= MT2063_ARG_RANGE; + } + } + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_GetReg +** +** Description: Gets an MT2063 register. +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** reg - MT2063 register/subaddress location +** *val - MT2063 register/subaddress value +** +** Returns: status: +** MT_OK - No errors +** MT_COMM_ERR - Serial bus communications error +** MT_INV_HANDLE - Invalid tuner handle +** MT_ARG_NULL - Null pointer argument passed +** MT_ARG_RANGE - Argument out of range +** +** Dependencies: USERS MUST CALL MT2063_Open() FIRST! +** +** Use this function if you need to read a register from +** the MT2063. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +****************************************************************************/ +UData_t MT2063_GetReg(Handle_t h, U8Data reg, U8Data * val) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + status |= MT2063_INV_HANDLE; + + if (val == NULL) + status |= MT2063_ARG_NULL; + + if (reg >= MT2063_REG_END_REGS) + status |= MT2063_ARG_RANGE; + + if (MT2063_NO_ERROR(status)) { + status |= + MT2063_ReadSub(pInfo->hUserData, pInfo->address, reg, + &pInfo->reg[reg], 1); + if (MT2063_NO_ERROR(status)) + *val = pInfo->reg[reg]; + } + + return (status); +} + +/****************************************************************************** +** +** Name: MT2063_GetTemp +** +** Description: Get the MT2063 Temperature register. +** +** Parameters: h - Open handle to the tuner (from MT2063_Open). +** *value - value read from the register +** +** Binary +** Value Returned Value Approx Temp +** --------------------------------------------- +** MT2063_T_0C 0000 0C +** MT2063_T_10C 0001 10C +** MT2063_T_20C 0010 20C +** MT2063_T_30C 0011 30C +** MT2063_T_40C 0100 40C +** MT2063_T_50C 0101 50C +** MT2063_T_60C 0110 60C +** MT2063_T_70C 0111 70C +** MT2063_T_80C 1000 80C +** MT2063_T_90C 1001 90C +** MT2063_T_100C 1010 100C +** MT2063_T_110C 1011 110C +** MT2063_T_120C 1100 120C +** MT2063_T_130C 1101 130C +** MT2063_T_140C 1110 140C +** MT2063_T_150C 1111 150C +** +** Returns: status: +** MT_OK - No errors +** MT_COMM_ERR - Serial bus communications error +** MT_INV_HANDLE - Invalid tuner handle +** MT_ARG_NULL - Null pointer argument passed +** MT_ARG_RANGE - Argument out of range +** +** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus +** MT_WriteSub - Write byte(s) of data to the two-wire bus +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +******************************************************************************/ +UData_t MT2063_GetTemp(Handle_t h, enum MT2063_Temperature * value) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + if (MT2063_IsValidHandle(pInfo) == 0) + return MT2063_INV_HANDLE; + + if (value == NULL) + return MT2063_ARG_NULL; + + if ((MT2063_NO_ERROR(status)) + && ((pInfo->reg[MT2063_REG_TEMP_SEL] & 0xE0) != 0x00)) { + pInfo->reg[MT2063_REG_TEMP_SEL] &= (0x1F); + status |= MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_TEMP_SEL, + &pInfo->reg[MT2063_REG_TEMP_SEL], 1); + } + + if (MT2063_NO_ERROR(status)) + status |= MT2063_ReadSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_TEMP_STATUS, + &pInfo->reg[MT2063_REG_TEMP_STATUS], + 1); + + if (MT2063_NO_ERROR(status)) + *value = + (enum MT2063_Temperature)(pInfo-> + reg[MT2063_REG_TEMP_STATUS] >> 4); + + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_GetUserData +** +** Description: Gets the user-defined data item. +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** +** Returns: status: +** MT_OK - No errors +** MT_INV_HANDLE - Invalid tuner handle +** MT_ARG_NULL - Null pointer argument passed +** +** Dependencies: USERS MUST CALL MT2063_Open() FIRST! +** +** The hUserData parameter is a user-specific argument +** that is stored internally with the other tuner- +** specific information. +** +** For example, if additional arguments are needed +** for the user to identify the device communicating +** with the tuner, this argument can be used to supply +** the necessary information. +** +** The hUserData parameter is initialized in the tuner's +** Open function to NULL. +** +** See Also: MT2063_Open +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +****************************************************************************/ +UData_t MT2063_GetUserData(Handle_t h, Handle_t * hUserData) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + status = MT2063_INV_HANDLE; + + if (hUserData == NULL) + status |= MT2063_ARG_NULL; + + if (MT2063_NO_ERROR(status)) + *hUserData = pInfo->hUserData; + + return (status); +} + +/****************************************************************************** +** +** Name: MT2063_SetReceiverMode +** +** Description: Set the MT2063 receiver mode +** +** --------------+---------------------------------------------- +** Mode 0 : | MT2063_CABLE_QAM +** Mode 1 : | MT2063_CABLE_ANALOG +** Mode 2 : | MT2063_OFFAIR_COFDM +** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS +** Mode 4 : | MT2063_OFFAIR_ANALOG +** Mode 5 : | MT2063_OFFAIR_8VSB +** --------------+----+----+----+----+-----+-------------------- +** (DNC1GC & DNC2GC are the values, which are used, when the specific +** DNC Output is selected, the other is always off) +** +** |<---------- Mode -------------->| +** Reg Field | 0 | 1 | 2 | 3 | 4 | 5 | +** ------------+-----+-----+-----+-----+-----+-----+ +** RFAGCen | OFF | OFF | OFF | OFF | OFF | OFF +** LNARin | 0 | 0 | 3 | 3 | 3 | 3 +** FIFFQen | 1 | 1 | 1 | 1 | 1 | 1 +** FIFFq | 0 | 0 | 0 | 0 | 0 | 0 +** DNC1gc | 0 | 0 | 0 | 0 | 0 | 0 +** DNC2gc | 0 | 0 | 0 | 0 | 0 | 0 +** GCU Auto | 1 | 1 | 1 | 1 | 1 | 1 +** LNA max Atn | 31 | 31 | 31 | 31 | 31 | 31 +** LNA Target | 44 | 43 | 43 | 43 | 43 | 43 +** ign RF Ovl | 0 | 0 | 0 | 0 | 0 | 0 +** RF max Atn | 31 | 31 | 31 | 31 | 31 | 31 +** PD1 Target | 36 | 36 | 38 | 38 | 36 | 38 +** ign FIF Ovl | 0 | 0 | 0 | 0 | 0 | 0 +** FIF max Atn | 5 | 5 | 5 | 5 | 5 | 5 +** PD2 Target | 40 | 33 | 42 | 42 | 33 | 42 +** +** +** Parameters: pInfo - ptr to MT2063_Info_t structure +** Mode - desired reciever mode +** +** Usage: status = MT2063_SetReceiverMode(hMT2063, Mode); +** +** Returns: status: +** MT_OK - No errors +** MT_COMM_ERR - Serial bus communications error +** +** Dependencies: MT2063_SetReg - Write a byte of data to a HW register. +** Assumes that the tuner cache is valid. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** N/A 01-10-2007 PINZ Added additional GCU Settings, FIFF Calib will be triggered +** 155 10-01-2007 DAD Ver 1.06: Add receiver mode for SECAM positive +** modulation +** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) +** N/A 10-22-2007 PINZ Ver 1.07: Changed some Registers at init to have +** the same settings as with MT Launcher +** N/A 10-30-2007 PINZ Add SetParam VGAGC & VGAOI +** Add SetParam DNC_OUTPUT_ENABLE +** Removed VGAGC from receiver mode, +** default now 1 +** N/A 10-31-2007 PINZ Ver 1.08: Add SetParam TAGC, removed from rcvr-mode +** Add SetParam AMPGC, removed from rcvr-mode +** Corrected names of GCU values +** reorganized receiver modes, removed, +** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) +** Actualized Receiver-Mode values +** N/A 11-12-2007 PINZ Ver 1.09: Actualized Receiver-Mode values +** N/A 11-27-2007 PINZ Improved buffered writing +** 01-03-2008 PINZ Ver 1.10: Added a trigger of BYPATNUP for +** correct wakeup of the LNA after shutdown +** Set AFCsd = 1 as default +** Changed CAP1sel default +** 01-14-2008 PINZ Ver 1.11: Updated gain settings +** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT +** Split SetParam up to ACLNA / ACLNA_MAX +** removed ACLNA_INRC/DECR (+RF & FIF) +** removed GCUAUTO / BYPATNDN/UP +** +******************************************************************************/ +static UData_t MT2063_SetReceiverMode(struct MT2063_Info_t *pInfo, + enum MT2063_RCVR_MODES Mode) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + U8Data val; + UData_t longval; + + if (Mode >= MT2063_NUM_RCVR_MODES) + status = MT2063_ARG_RANGE; + + /* RFAGCen */ + if (MT2063_NO_ERROR(status)) { + val = + (pInfo-> + reg[MT2063_REG_PD1_TGT] & (U8Data) ~ 0x40) | (RFAGCEN[Mode] + ? 0x40 : + 0x00); + if (pInfo->reg[MT2063_REG_PD1_TGT] != val) { + status |= MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT, val); + } + } + + /* LNARin */ + if (MT2063_NO_ERROR(status)) { + status |= MT2063_SetParam(pInfo, MT2063_LNA_RIN, LNARIN[Mode]); + } + + /* FIFFQEN and FIFFQ */ + if (MT2063_NO_ERROR(status)) { + val = + (pInfo-> + reg[MT2063_REG_FIFF_CTRL2] & (U8Data) ~ 0xF0) | + (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4); + if (pInfo->reg[MT2063_REG_FIFF_CTRL2] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL2, val); + /* trigger FIFF calibration, needed after changing FIFFQ */ + val = + (pInfo->reg[MT2063_REG_FIFF_CTRL] | (U8Data) 0x01); + status |= + MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL, val); + val = + (pInfo-> + reg[MT2063_REG_FIFF_CTRL] & (U8Data) ~ 0x01); + status |= + MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL, val); + } + } + + /* DNC1GC & DNC2GC */ + status |= MT2063_GetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, &longval); + status |= MT2063_SetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, longval); + + /* acLNAmax */ + if (MT2063_NO_ERROR(status)) { + status |= + MT2063_SetParam(pInfo, MT2063_ACLNA_MAX, ACLNAMAX[Mode]); + } + + /* LNATGT */ + if (MT2063_NO_ERROR(status)) { + status |= MT2063_SetParam(pInfo, MT2063_LNA_TGT, LNATGT[Mode]); + } + + /* ACRF */ + if (MT2063_NO_ERROR(status)) { + status |= + MT2063_SetParam(pInfo, MT2063_ACRF_MAX, ACRFMAX[Mode]); + } + + /* PD1TGT */ + if (MT2063_NO_ERROR(status)) { + status |= MT2063_SetParam(pInfo, MT2063_PD1_TGT, PD1TGT[Mode]); + } + + /* FIFATN */ + if (MT2063_NO_ERROR(status)) { + status |= + MT2063_SetParam(pInfo, MT2063_ACFIF_MAX, ACFIFMAX[Mode]); + } + + /* PD2TGT */ + if (MT2063_NO_ERROR(status)) { + status |= MT2063_SetParam(pInfo, MT2063_PD2_TGT, PD2TGT[Mode]); + } + + /* Ignore ATN Overload */ + if (MT2063_NO_ERROR(status)) { + val = + (pInfo-> + reg[MT2063_REG_LNA_TGT] & (U8Data) ~ 0x80) | (RFOVDIS[Mode] + ? 0x80 : + 0x00); + if (pInfo->reg[MT2063_REG_LNA_TGT] != val) { + status |= MT2063_SetReg(pInfo, MT2063_REG_LNA_TGT, val); + } + } + + /* Ignore FIF Overload */ + if (MT2063_NO_ERROR(status)) { + val = + (pInfo-> + reg[MT2063_REG_PD1_TGT] & (U8Data) ~ 0x80) | + (FIFOVDIS[Mode] ? 0x80 : 0x00); + if (pInfo->reg[MT2063_REG_PD1_TGT] != val) { + status |= MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT, val); + } + } + + if (MT2063_NO_ERROR(status)) + pInfo->rcvr_mode = Mode; + + return (status); +} + +/****************************************************************************** +** +** Name: MT2063_ReInit +** +** Description: Initialize the tuner's register values. +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** +** Returns: status: +** MT_OK - No errors +** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch +** MT_INV_HANDLE - Invalid tuner handle +** MT_COMM_ERR - Serial bus communications error +** +** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus +** MT_WriteSub - Write byte(s) of data to the two-wire bus +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** 148 09-04-2007 RSK Ver 1.02: Corrected logic of Reg 3B Reference +** 153 09-07-2007 RSK Ver 1.03: Lock Time improvements +** N/A 10-31-2007 PINZ Ver 1.08: Changed values suitable to rcvr-mode 0 +** N/A 11-12-2007 PINZ Ver 1.09: Changed values suitable to rcvr-mode 0 +** N/A 01-03-2007 PINZ Ver 1.10: Added AFCsd = 1 into defaults +** N/A 01-04-2007 PINZ Ver 1.10: Changed CAP1sel default +** 01-14-2008 PINZ Ver 1.11: Updated gain settings +** 03-18-2008 PINZ Ver 1.13: Added Support for B3 +** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. +** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW +** +******************************************************************************/ +UData_t MT2063_ReInit(Handle_t h) +{ + U8Data all_resets = 0xF0; /* reset/load bits */ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + U8Data *def; + + U8Data MT2063B0_defaults[] = { /* Reg, Value */ + 0x19, 0x05, + 0x1B, 0x1D, + 0x1C, 0x1F, + 0x1D, 0x0F, + 0x1E, 0x3F, + 0x1F, 0x0F, + 0x20, 0x3F, + 0x22, 0x21, + 0x23, 0x3F, + 0x24, 0x20, + 0x25, 0x3F, + 0x27, 0xEE, + 0x2C, 0x27, /* bit at 0x20 is cleared below */ + 0x30, 0x03, + 0x2C, 0x07, /* bit at 0x20 is cleared here */ + 0x2D, 0x87, + 0x2E, 0xAA, + 0x28, 0xE1, /* Set the FIFCrst bit here */ + 0x28, 0xE0, /* Clear the FIFCrst bit here */ + 0x00 + }; + + /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */ + U8Data MT2063B1_defaults[] = { /* Reg, Value */ + 0x05, 0xF0, + 0x11, 0x10, /* New Enable AFCsd */ + 0x19, 0x05, + 0x1A, 0x6C, + 0x1B, 0x24, + 0x1C, 0x28, + 0x1D, 0x8F, + 0x1E, 0x14, + 0x1F, 0x8F, + 0x20, 0x57, + 0x22, 0x21, /* New - ver 1.03 */ + 0x23, 0x3C, /* New - ver 1.10 */ + 0x24, 0x20, /* New - ver 1.03 */ + 0x2C, 0x24, /* bit at 0x20 is cleared below */ + 0x2D, 0x87, /* FIFFQ=0 */ + 0x2F, 0xF3, + 0x30, 0x0C, /* New - ver 1.11 */ + 0x31, 0x1B, /* New - ver 1.11 */ + 0x2C, 0x04, /* bit at 0x20 is cleared here */ + 0x28, 0xE1, /* Set the FIFCrst bit here */ + 0x28, 0xE0, /* Clear the FIFCrst bit here */ + 0x00 + }; + + /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */ + U8Data MT2063B3_defaults[] = { /* Reg, Value */ + 0x05, 0xF0, + 0x19, 0x3D, + 0x2C, 0x24, /* bit at 0x20 is cleared below */ + 0x2C, 0x04, /* bit at 0x20 is cleared here */ + 0x28, 0xE1, /* Set the FIFCrst bit here */ + 0x28, 0xE0, /* Clear the FIFCrst bit here */ + 0x00 + }; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + status |= MT2063_INV_HANDLE; + + /* Read the Part/Rev code from the tuner */ + if (MT2063_NO_ERROR(status)) { + status |= + MT2063_ReadSub(pInfo->hUserData, pInfo->address, + MT2063_REG_PART_REV, pInfo->reg, 1); + } + + if (MT2063_NO_ERROR(status) /* Check the part/rev code */ + &&((pInfo->reg[MT2063_REG_PART_REV] != MT2063_B0) /* MT2063 B0 */ + &&(pInfo->reg[MT2063_REG_PART_REV] != MT2063_B1) /* MT2063 B1 */ + &&(pInfo->reg[MT2063_REG_PART_REV] != MT2063_B3))) /* MT2063 B3 */ + status |= MT2063_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */ + + /* Read the Part/Rev code (2nd byte) from the tuner */ + if (MT2063_NO_ERROR(status)) + status |= + MT2063_ReadSub(pInfo->hUserData, pInfo->address, + MT2063_REG_RSVD_3B, + &pInfo->reg[MT2063_REG_RSVD_3B], 1); + + if (MT2063_NO_ERROR(status) /* Check the 2nd part/rev code */ + &&((pInfo->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) /* b7 != 0 ==> NOT MT2063 */ + status |= MT2063_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */ + + /* Reset the tuner */ + if (MT2063_NO_ERROR(status)) + status |= MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO2CQ_3, &all_resets, 1); + + /* change all of the default values that vary from the HW reset values */ + /* def = (pInfo->reg[PART_REV] == MT2063_B0) ? MT2063B0_defaults : MT2063B1_defaults; */ + switch (pInfo->reg[MT2063_REG_PART_REV]) { + case MT2063_B3: + def = MT2063B3_defaults; + break; + + case MT2063_B1: + def = MT2063B1_defaults; + break; + + case MT2063_B0: + def = MT2063B0_defaults; + break; + + default: + status |= MT2063_TUNER_ID_ERR; + break; + } + + while (MT2063_NO_ERROR(status) && *def) { + U8Data reg = *def++; + U8Data val = *def++; + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, + 1); + } + + /* Wait for FIFF location to complete. */ + if (MT2063_NO_ERROR(status)) { + UData_t FCRUN = 1; + SData_t maxReads = 10; + while (MT2063_NO_ERROR(status) && (FCRUN != 0) + && (maxReads-- > 0)) { + MT2063_Sleep(pInfo->hUserData, 2); + status |= MT2063_ReadSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_XO_STATUS, + &pInfo-> + reg[MT2063_REG_XO_STATUS], 1); + FCRUN = (pInfo->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6; + } + + if (FCRUN != 0) + status |= MT2063_TUNER_INIT_ERR | MT2063_TUNER_TIMEOUT; + + if (MT2063_NO_ERROR(status)) /* Re-read FIFFC value */ + status |= + MT2063_ReadSub(pInfo->hUserData, pInfo->address, + MT2063_REG_FIFFC, + &pInfo->reg[MT2063_REG_FIFFC], 1); + } + + /* Read back all the registers from the tuner */ + if (MT2063_NO_ERROR(status)) + status |= MT2063_ReadSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_PART_REV, + pInfo->reg, MT2063_REG_END_REGS); + + if (MT2063_NO_ERROR(status)) { + /* Initialize the tuner state. */ + pInfo->version = MT2063_VERSION; + pInfo->tuner_id = pInfo->reg[MT2063_REG_PART_REV]; + pInfo->AS_Data.f_ref = MT2063_REF_FREQ; + pInfo->AS_Data.f_if1_Center = + (pInfo->AS_Data.f_ref / 8) * + ((UData_t) pInfo->reg[MT2063_REG_FIFFC] + 640); + pInfo->AS_Data.f_if1_bw = MT2063_IF1_BW; + pInfo->AS_Data.f_out = 43750000UL; + pInfo->AS_Data.f_out_bw = 6750000UL; + pInfo->AS_Data.f_zif_bw = MT2063_ZIF_BW; + pInfo->AS_Data.f_LO1_Step = pInfo->AS_Data.f_ref / 64; + pInfo->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE; + pInfo->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1; + pInfo->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2; + pInfo->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP; + pInfo->AS_Data.f_if1_Request = pInfo->AS_Data.f_if1_Center; + pInfo->AS_Data.f_LO1 = 2181000000UL; + pInfo->AS_Data.f_LO2 = 1486249786UL; + pInfo->f_IF1_actual = pInfo->AS_Data.f_if1_Center; + pInfo->AS_Data.f_in = + pInfo->AS_Data.f_LO1 - pInfo->f_IF1_actual; + pInfo->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID; + pInfo->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID; + pInfo->num_regs = MT2063_REG_END_REGS; + pInfo->AS_Data.avoidDECT = MT2063_AVOID_BOTH; + pInfo->ctfilt_sw = 0; + } + + if (MT2063_NO_ERROR(status)) { + pInfo->CTFiltMax[0] = 69230000; + pInfo->CTFiltMax[1] = 105770000; + pInfo->CTFiltMax[2] = 140350000; + pInfo->CTFiltMax[3] = 177110000; + pInfo->CTFiltMax[4] = 212860000; + pInfo->CTFiltMax[5] = 241130000; + pInfo->CTFiltMax[6] = 274370000; + pInfo->CTFiltMax[7] = 309820000; + pInfo->CTFiltMax[8] = 342450000; + pInfo->CTFiltMax[9] = 378870000; + pInfo->CTFiltMax[10] = 416210000; + pInfo->CTFiltMax[11] = 456500000; + pInfo->CTFiltMax[12] = 495790000; + pInfo->CTFiltMax[13] = 534530000; + pInfo->CTFiltMax[14] = 572610000; + pInfo->CTFiltMax[15] = 598970000; + pInfo->CTFiltMax[16] = 635910000; + pInfo->CTFiltMax[17] = 672130000; + pInfo->CTFiltMax[18] = 714840000; + pInfo->CTFiltMax[19] = 739660000; + pInfo->CTFiltMax[20] = 770410000; + pInfo->CTFiltMax[21] = 814660000; + pInfo->CTFiltMax[22] = 846950000; + pInfo->CTFiltMax[23] = 867820000; + pInfo->CTFiltMax[24] = 915980000; + pInfo->CTFiltMax[25] = 947450000; + pInfo->CTFiltMax[26] = 983110000; + pInfo->CTFiltMax[27] = 1021630000; + pInfo->CTFiltMax[28] = 1061870000; + pInfo->CTFiltMax[29] = 1098330000; + pInfo->CTFiltMax[30] = 1138990000; + } + + /* + ** Fetch the FCU osc value and use it and the fRef value to + ** scale all of the Band Max values + */ + if (MT2063_NO_ERROR(status)) { + UData_t fcu_osc; + UData_t i; + + pInfo->reg[MT2063_REG_CTUNE_CTRL] = 0x0A; + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, + MT2063_REG_CTUNE_CTRL, + &pInfo->reg[MT2063_REG_CTUNE_CTRL], 1); + /* Read the ClearTune filter calibration value */ + status |= + MT2063_ReadSub(pInfo->hUserData, pInfo->address, + MT2063_REG_FIFFC, + &pInfo->reg[MT2063_REG_FIFFC], 1); + fcu_osc = pInfo->reg[MT2063_REG_FIFFC]; + + pInfo->reg[MT2063_REG_CTUNE_CTRL] = 0x00; + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, + MT2063_REG_CTUNE_CTRL, + &pInfo->reg[MT2063_REG_CTUNE_CTRL], 1); + + /* Adjust each of the values in the ClearTune filter cross-over table */ + for (i = 0; i < 31; i++) { + pInfo->CTFiltMax[i] = + (pInfo->CTFiltMax[i] / 768) * (fcu_osc + 640); + } + } + + return (status); +} + +/****************************************************************************** +** +** Name: MT2063_SetGPIO +** +** Description: Modify the MT2063 GPIO value. +** +** Parameters: h - Open handle to the tuner (from MT2063_Open). +** gpio_id - Selects GPIO0, GPIO1 or GPIO2 +** attr - Selects input readback, I/O direction or +** output value +** value - value to set GPIO pin 15, 14 or 19 +** +** Usage: status = MT2063_SetGPIO(hMT2063, MT2063_GPIO1, MT2063_GPIO_OUT, 1); +** +** Returns: status: +** MT_OK - No errors +** MT_COMM_ERR - Serial bus communications error +** MT_INV_HANDLE - Invalid tuner handle +** +** Dependencies: MT_WriteSub - Write byte(s) of data to the two-wire-bus +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +******************************************************************************/ +UData_t MT2063_SetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id, + enum MT2063_GPIO_Attr attr, UData_t value) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + U8Data regno; + SData_t shift; + static U8Data GPIOreg[3] = { 0x15, 0x19, 0x18 }; + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + if (MT2063_IsValidHandle(pInfo) == 0) + return MT2063_INV_HANDLE; + + regno = GPIOreg[attr]; + + shift = (gpio_id - MT2063_GPIO0 + 5); + + if (value & 0x01) + pInfo->reg[regno] |= (0x01 << shift); + else + pInfo->reg[regno] &= ~(0x01 << shift); + status = + MT2063_WriteSub(pInfo->hUserData, pInfo->address, regno, + &pInfo->reg[regno], 1); + + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_SetParam +** +** Description: Sets a tuning algorithm parameter. +** +** This function provides access to the internals of the +** tuning algorithm. You can override many of the tuning +** algorithm defaults using this function. +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** param - Tuning algorithm parameter +** (see enum MT2063_Param) +** nValue - value to be set +** +** param Description +** ---------------------- -------------------------------- +** MT2063_SRO_FREQ crystal frequency +** MT2063_STEPSIZE minimum tuning step size +** MT2063_LO1_FREQ LO1 frequency +** MT2063_LO1_STEPSIZE LO1 minimum step size +** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region +** MT2063_IF1_REQUEST Requested 1st IF +** MT2063_ZIF_BW zero-IF bandwidth +** MT2063_LO2_FREQ LO2 frequency +** MT2063_LO2_STEPSIZE LO2 minimum step size +** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region +** MT2063_OUTPUT_FREQ output center frequency +** MT2063_OUTPUT_BW output bandwidth +** MT2063_LO_SEPARATION min inter-tuner LO separation +** MT2063_MAX_HARM1 max # of intra-tuner harmonics +** MT2063_MAX_HARM2 max # of inter-tuner harmonics +** MT2063_RCVR_MODE Predefined modes +** MT2063_LNA_RIN Set LNA Rin (*) +** MT2063_LNA_TGT Set target power level at LNA (*) +** MT2063_PD1_TGT Set target power level at PD1 (*) +** MT2063_PD2_TGT Set target power level at PD2 (*) +** MT2063_ACLNA_MAX LNA attenuator limit (*) +** MT2063_ACRF_MAX RF attenuator limit (*) +** MT2063_ACFIF_MAX FIF attenuator limit (*) +** MT2063_DNC_OUTPUT_ENABLE DNC output selection +** MT2063_VGAGC VGA gain code +** MT2063_VGAOI VGA output current +** MT2063_TAGC TAGC setting +** MT2063_AMPGC AMP gain code +** MT2063_AVOID_DECT Avoid DECT Frequencies +** MT2063_CTFILT_SW Cleartune filter selection +** +** (*) This parameter is set by MT2063_RCVR_MODE, do not call +** additionally. +** +** Usage: status |= MT2063_SetParam(hMT2063, +** MT2063_STEPSIZE, +** 50000); +** +** Returns: status: +** MT_OK - No errors +** MT_INV_HANDLE - Invalid tuner handle +** MT_ARG_NULL - Null pointer argument passed +** MT_ARG_RANGE - Invalid parameter requested +** or set value out of range +** or non-writable parameter +** +** Dependencies: USERS MUST CALL MT2063_Open() FIRST! +** +** See Also: MT2063_GetParam, MT2063_Open +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ +** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC +** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT +** Split SetParam up to ACLNA / ACLNA_MAX +** removed ACLNA_INRC/DECR (+RF & FIF) +** removed GCUAUTO / BYPATNDN/UP +** 175 I 06-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. +** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. +** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW +** +****************************************************************************/ +UData_t MT2063_SetParam(Handle_t h, enum MT2063_Param param, UData_t nValue) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + U8Data val = 0; + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + status |= MT2063_INV_HANDLE; + + if (MT2063_NO_ERROR(status)) { + switch (param) { + /* crystal frequency */ + case MT2063_SRO_FREQ: + pInfo->AS_Data.f_ref = nValue; + pInfo->AS_Data.f_LO1_FracN_Avoid = 0; + pInfo->AS_Data.f_LO2_FracN_Avoid = nValue / 80 - 1; + pInfo->AS_Data.f_LO1_Step = nValue / 64; + pInfo->AS_Data.f_if1_Center = + (pInfo->AS_Data.f_ref / 8) * + (pInfo->reg[MT2063_REG_FIFFC] + 640); + break; + + /* minimum tuning step size */ + case MT2063_STEPSIZE: + pInfo->AS_Data.f_LO2_Step = nValue; + break; + + /* LO1 frequency */ + case MT2063_LO1_FREQ: + { + /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */ + /* Capture the Divider and Numerator portions of other LO */ + U8Data tempLO2CQ[3]; + U8Data tempLO2C[3]; + U8Data tmpOneShot; + UData_t Div, FracN; + U8Data restore = 0; + + /* Buffer the queue for restoration later and get actual LO2 values. */ + status |= + MT2063_ReadSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO2CQ_1, + &(tempLO2CQ[0]), 3); + status |= + MT2063_ReadSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO2C_1, + &(tempLO2C[0]), 3); + + /* clear the one-shot bits */ + tempLO2CQ[2] = tempLO2CQ[2] & 0x0F; + tempLO2C[2] = tempLO2C[2] & 0x0F; + + /* only write the queue values if they are different from the actual. */ + if ((tempLO2CQ[0] != tempLO2C[0]) || + (tempLO2CQ[1] != tempLO2C[1]) || + (tempLO2CQ[2] != tempLO2C[2])) { + /* put actual LO2 value into queue (with 0 in one-shot bits) */ + status |= + MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO2CQ_1, + &(tempLO2C[0]), 3); + + if (status == MT2063_OK) { + /* cache the bytes just written. */ + pInfo->reg[MT2063_REG_LO2CQ_1] = + tempLO2C[0]; + pInfo->reg[MT2063_REG_LO2CQ_2] = + tempLO2C[1]; + pInfo->reg[MT2063_REG_LO2CQ_3] = + tempLO2C[2]; + } + restore = 1; + } + + /* Calculate the Divider and Numberator components of LO1 */ + status = + MT2063_CalcLO1Mult(&Div, &FracN, nValue, + pInfo->AS_Data.f_ref / + 64, + pInfo->AS_Data.f_ref); + pInfo->reg[MT2063_REG_LO1CQ_1] = + (U8Data) (Div & 0x00FF); + pInfo->reg[MT2063_REG_LO1CQ_2] = + (U8Data) (FracN); + status |= + MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO1CQ_1, + &pInfo-> + reg[MT2063_REG_LO1CQ_1], 2); + + /* set the one-shot bit to load the pair of LO values */ + tmpOneShot = tempLO2CQ[2] | 0xE0; + status |= + MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO2CQ_3, + &tmpOneShot, 1); + + /* only restore the queue values if they were different from the actual. */ + if (restore) { + /* put actual LO2 value into queue (0 in one-shot bits) */ + status |= + MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO2CQ_1, + &(tempLO2CQ[0]), 3); + + /* cache the bytes just written. */ + pInfo->reg[MT2063_REG_LO2CQ_1] = + tempLO2CQ[0]; + pInfo->reg[MT2063_REG_LO2CQ_2] = + tempLO2CQ[1]; + pInfo->reg[MT2063_REG_LO2CQ_3] = + tempLO2CQ[2]; + } + + MT2063_GetParam(pInfo->hUserData, + MT2063_LO1_FREQ, + &pInfo->AS_Data.f_LO1); + } + break; + + /* LO1 minimum step size */ + case MT2063_LO1_STEPSIZE: + pInfo->AS_Data.f_LO1_Step = nValue; + break; + + /* LO1 FracN keep-out region */ + case MT2063_LO1_FRACN_AVOID_PARAM: + pInfo->AS_Data.f_LO1_FracN_Avoid = nValue; + break; + + /* Requested 1st IF */ + case MT2063_IF1_REQUEST: + pInfo->AS_Data.f_if1_Request = nValue; + break; + + /* zero-IF bandwidth */ + case MT2063_ZIF_BW: + pInfo->AS_Data.f_zif_bw = nValue; + break; + + /* LO2 frequency */ + case MT2063_LO2_FREQ: + { + /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */ + /* Capture the Divider and Numerator portions of other LO */ + U8Data tempLO1CQ[2]; + U8Data tempLO1C[2]; + UData_t Div2; + UData_t FracN2; + U8Data tmpOneShot; + U8Data restore = 0; + + /* Buffer the queue for restoration later and get actual LO2 values. */ + status |= + MT2063_ReadSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO1CQ_1, + &(tempLO1CQ[0]), 2); + status |= + MT2063_ReadSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO1C_1, + &(tempLO1C[0]), 2); + + /* only write the queue values if they are different from the actual. */ + if ((tempLO1CQ[0] != tempLO1C[0]) + || (tempLO1CQ[1] != tempLO1C[1])) { + /* put actual LO1 value into queue */ + status |= + MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO1CQ_1, + &(tempLO1C[0]), 2); + + /* cache the bytes just written. */ + pInfo->reg[MT2063_REG_LO1CQ_1] = + tempLO1C[0]; + pInfo->reg[MT2063_REG_LO1CQ_2] = + tempLO1C[1]; + restore = 1; + } + + /* Calculate the Divider and Numberator components of LO2 */ + status = + MT2063_CalcLO2Mult(&Div2, &FracN2, nValue, + pInfo->AS_Data.f_ref / + 8191, + pInfo->AS_Data.f_ref); + pInfo->reg[MT2063_REG_LO2CQ_1] = + (U8Data) ((Div2 << 1) | + ((FracN2 >> 12) & 0x01)) & 0xFF; + pInfo->reg[MT2063_REG_LO2CQ_2] = + (U8Data) ((FracN2 >> 4) & 0xFF); + pInfo->reg[MT2063_REG_LO2CQ_3] = + (U8Data) ((FracN2 & 0x0F)); + status |= + MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO1CQ_1, + &pInfo-> + reg[MT2063_REG_LO1CQ_1], 3); + + /* set the one-shot bit to load the LO values */ + tmpOneShot = + pInfo->reg[MT2063_REG_LO2CQ_3] | 0xE0; + status |= + MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO2CQ_3, + &tmpOneShot, 1); + + /* only restore LO1 queue value if they were different from the actual. */ + if (restore) { + /* put previous LO1 queue value back into queue */ + status |= + MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_LO1CQ_1, + &(tempLO1CQ[0]), 2); + + /* cache the bytes just written. */ + pInfo->reg[MT2063_REG_LO1CQ_1] = + tempLO1CQ[0]; + pInfo->reg[MT2063_REG_LO1CQ_2] = + tempLO1CQ[1]; + } + + MT2063_GetParam(pInfo->hUserData, + MT2063_LO2_FREQ, + &pInfo->AS_Data.f_LO2); + } + break; + + /* LO2 minimum step size */ + case MT2063_LO2_STEPSIZE: + pInfo->AS_Data.f_LO2_Step = nValue; + break; + + /* LO2 FracN keep-out region */ + case MT2063_LO2_FRACN_AVOID: + pInfo->AS_Data.f_LO2_FracN_Avoid = nValue; + break; + + /* output center frequency */ + case MT2063_OUTPUT_FREQ: + pInfo->AS_Data.f_out = nValue; + break; + + /* output bandwidth */ + case MT2063_OUTPUT_BW: + pInfo->AS_Data.f_out_bw = nValue + 750000; + break; + + /* min inter-tuner LO separation */ + case MT2063_LO_SEPARATION: + pInfo->AS_Data.f_min_LO_Separation = nValue; + break; + + /* max # of intra-tuner harmonics */ + case MT2063_MAX_HARM1: + pInfo->AS_Data.maxH1 = nValue; + break; + + /* max # of inter-tuner harmonics */ + case MT2063_MAX_HARM2: + pInfo->AS_Data.maxH2 = nValue; + break; + + case MT2063_RCVR_MODE: + status |= + MT2063_SetReceiverMode(pInfo, + (enum MT2063_RCVR_MODES) + nValue); + break; + + /* Set LNA Rin -- nValue is desired value */ + case MT2063_LNA_RIN: + val = + (pInfo-> + reg[MT2063_REG_CTRL_2C] & (U8Data) ~ 0x03) | + (nValue & 0x03); + if (pInfo->reg[MT2063_REG_CTRL_2C] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_CTRL_2C, + val); + } + break; + + /* Set target power level at LNA -- nValue is desired value */ + case MT2063_LNA_TGT: + val = + (pInfo-> + reg[MT2063_REG_LNA_TGT] & (U8Data) ~ 0x3F) | + (nValue & 0x3F); + if (pInfo->reg[MT2063_REG_LNA_TGT] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_LNA_TGT, + val); + } + break; + + /* Set target power level at PD1 -- nValue is desired value */ + case MT2063_PD1_TGT: + val = + (pInfo-> + reg[MT2063_REG_PD1_TGT] & (U8Data) ~ 0x3F) | + (nValue & 0x3F); + if (pInfo->reg[MT2063_REG_PD1_TGT] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT, + val); + } + break; + + /* Set target power level at PD2 -- nValue is desired value */ + case MT2063_PD2_TGT: + val = + (pInfo-> + reg[MT2063_REG_PD2_TGT] & (U8Data) ~ 0x3F) | + (nValue & 0x3F); + if (pInfo->reg[MT2063_REG_PD2_TGT] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_PD2_TGT, + val); + } + break; + + /* Set LNA atten limit -- nValue is desired value */ + case MT2063_ACLNA_MAX: + val = + (pInfo-> + reg[MT2063_REG_LNA_OV] & (U8Data) ~ 0x1F) | (nValue + & + 0x1F); + if (pInfo->reg[MT2063_REG_LNA_OV] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_LNA_OV, + val); + } + break; + + /* Set RF atten limit -- nValue is desired value */ + case MT2063_ACRF_MAX: + val = + (pInfo-> + reg[MT2063_REG_RF_OV] & (U8Data) ~ 0x1F) | (nValue + & + 0x1F); + if (pInfo->reg[MT2063_REG_RF_OV] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_RF_OV, val); + } + break; + + /* Set FIF atten limit -- nValue is desired value, max. 5 if no B3 */ + case MT2063_ACFIF_MAX: + if (pInfo->reg[MT2063_REG_PART_REV] != MT2063_B3 + && nValue > 5) + nValue = 5; + val = + (pInfo-> + reg[MT2063_REG_FIF_OV] & (U8Data) ~ 0x1F) | (nValue + & + 0x1F); + if (pInfo->reg[MT2063_REG_FIF_OV] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_FIF_OV, + val); + } + break; + + case MT2063_DNC_OUTPUT_ENABLE: + /* selects, which DNC output is used */ + switch ((enum MT2063_DNC_Output_Enable)nValue) { + case MT2063_DNC_NONE: + { + val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03; /* Set DNC1GC=3 */ + if (pInfo->reg[MT2063_REG_DNC_GAIN] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_DNC_GAIN, + val); + + val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03; /* Set DNC2GC=3 */ + if (pInfo->reg[MT2063_REG_VGA_GAIN] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_VGA_GAIN, + val); + + val = (pInfo->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */ + if (pInfo->reg[MT2063_REG_RSVD_20] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_RSVD_20, + val); + + break; + } + case MT2063_DNC_1: + { + val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */ + if (pInfo->reg[MT2063_REG_DNC_GAIN] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_DNC_GAIN, + val); + + val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03; /* Set DNC2GC=3 */ + if (pInfo->reg[MT2063_REG_VGA_GAIN] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_VGA_GAIN, + val); + + val = (pInfo->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */ + if (pInfo->reg[MT2063_REG_RSVD_20] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_RSVD_20, + val); + + break; + } + case MT2063_DNC_2: + { + val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03; /* Set DNC1GC=3 */ + if (pInfo->reg[MT2063_REG_DNC_GAIN] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_DNC_GAIN, + val); + + val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */ + if (pInfo->reg[MT2063_REG_VGA_GAIN] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_VGA_GAIN, + val); + + val = (pInfo->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */ + if (pInfo->reg[MT2063_REG_RSVD_20] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_RSVD_20, + val); + + break; + } + case MT2063_DNC_BOTH: + { + val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */ + if (pInfo->reg[MT2063_REG_DNC_GAIN] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_DNC_GAIN, + val); + + val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */ + if (pInfo->reg[MT2063_REG_VGA_GAIN] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_VGA_GAIN, + val); + + val = (pInfo->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */ + if (pInfo->reg[MT2063_REG_RSVD_20] != + val) + status |= + MT2063_SetReg(h, + MT2063_REG_RSVD_20, + val); + + break; + } + default: + break; + } + break; + + case MT2063_VGAGC: + /* Set VGA gain code */ + val = + (pInfo-> + reg[MT2063_REG_VGA_GAIN] & (U8Data) ~ 0x0C) | + ((nValue & 0x03) << 2); + if (pInfo->reg[MT2063_REG_VGA_GAIN] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_VGA_GAIN, + val); + } + break; + + case MT2063_VGAOI: + /* Set VGA bias current */ + val = + (pInfo-> + reg[MT2063_REG_RSVD_31] & (U8Data) ~ 0x07) | + (nValue & 0x07); + if (pInfo->reg[MT2063_REG_RSVD_31] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_RSVD_31, + val); + } + break; + + case MT2063_TAGC: + /* Set TAGC */ + val = + (pInfo-> + reg[MT2063_REG_RSVD_1E] & (U8Data) ~ 0x03) | + (nValue & 0x03); + if (pInfo->reg[MT2063_REG_RSVD_1E] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_RSVD_1E, + val); + } + break; + + case MT2063_AMPGC: + /* Set Amp gain code */ + val = + (pInfo-> + reg[MT2063_REG_TEMP_SEL] & (U8Data) ~ 0x03) | + (nValue & 0x03); + if (pInfo->reg[MT2063_REG_TEMP_SEL] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_TEMP_SEL, + val); + } + break; + + /* Avoid DECT Frequencies */ + case MT2063_AVOID_DECT: + { + enum MT2063_DECT_Avoid_Type newAvoidSetting = + (enum MT2063_DECT_Avoid_Type)nValue; + if ((newAvoidSetting >= + MT2063_NO_DECT_AVOIDANCE) + && (newAvoidSetting <= MT2063_AVOID_BOTH)) { + pInfo->AS_Data.avoidDECT = + newAvoidSetting; + } + } + break; + + /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ + case MT2063_CTFILT_SW: + pInfo->ctfilt_sw = (nValue & 0x01); + break; + + /* These parameters are read-only */ + case MT2063_IC_ADDR: + case MT2063_MAX_OPEN: + case MT2063_NUM_OPEN: + case MT2063_INPUT_FREQ: + case MT2063_IF1_ACTUAL: + case MT2063_IF1_CENTER: + case MT2063_IF1_BW: + case MT2063_AS_ALG: + case MT2063_EXCL_ZONES: + case MT2063_SPUR_AVOIDED: + case MT2063_NUM_SPURS: + case MT2063_SPUR_PRESENT: + case MT2063_ACLNA: + case MT2063_ACRF: + case MT2063_ACFIF: + case MT2063_EOP: + default: + status |= MT2063_ARG_RANGE; + } + } + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_SetPowerMaskBits +** +** Description: Sets the power-down mask bits for various sections of +** the MT2063 +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** Bits - Mask bits to be set. +** +** See definition of MT2063_Mask_Bits type for description +** of each of the power bits. +** +** Returns: status: +** MT_OK - No errors +** MT_INV_HANDLE - Invalid tuner handle +** MT_COMM_ERR - Serial bus communications error +** +** Dependencies: USERS MUST CALL MT2063_Open() FIRST! +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +****************************************************************************/ +UData_t MT2063_SetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + status = MT2063_INV_HANDLE; + else { + Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ + if ((Bits & 0xFF00) != 0) { + pInfo->reg[MT2063_REG_PWR_2] |= + (U8Data) ((Bits & 0xFF00) >> 8); + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, + MT2063_REG_PWR_2, + &pInfo->reg[MT2063_REG_PWR_2], 1); + } + if ((Bits & 0xFF) != 0) { + pInfo->reg[MT2063_REG_PWR_1] |= ((U8Data) Bits & 0xFF); + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, + MT2063_REG_PWR_1, + &pInfo->reg[MT2063_REG_PWR_1], 1); + } + } + + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_ClearPowerMaskBits +** +** Description: Clears the power-down mask bits for various sections of +** the MT2063 +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** Bits - Mask bits to be cleared. +** +** See definition of MT2063_Mask_Bits type for description +** of each of the power bits. +** +** Returns: status: +** MT_OK - No errors +** MT_INV_HANDLE - Invalid tuner handle +** MT_COMM_ERR - Serial bus communications error +** +** Dependencies: USERS MUST CALL MT2063_Open() FIRST! +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +****************************************************************************/ +UData_t MT2063_ClearPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + status = MT2063_INV_HANDLE; + else { + Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ + if ((Bits & 0xFF00) != 0) { + pInfo->reg[MT2063_REG_PWR_2] &= ~(U8Data) (Bits >> 8); + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, + MT2063_REG_PWR_2, + &pInfo->reg[MT2063_REG_PWR_2], 1); + } + if ((Bits & 0xFF) != 0) { + pInfo->reg[MT2063_REG_PWR_1] &= ~(U8Data) (Bits & 0xFF); + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, + MT2063_REG_PWR_1, + &pInfo->reg[MT2063_REG_PWR_1], 1); + } + } + + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_GetPowerMaskBits +** +** Description: Returns a mask of the enabled power shutdown bits +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** Bits - Mask bits to currently set. +** +** See definition of MT2063_Mask_Bits type for description +** of each of the power bits. +** +** Returns: status: +** MT_OK - No errors +** MT_INV_HANDLE - Invalid tuner handle +** MT_ARG_NULL - Output argument is NULL +** MT_COMM_ERR - Serial bus communications error +** +** Dependencies: USERS MUST CALL MT2063_Open() FIRST! +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +****************************************************************************/ +UData_t MT2063_GetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits * Bits) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + status = MT2063_INV_HANDLE; + else { + if (Bits == NULL) + status |= MT2063_ARG_NULL; + + if (MT2063_NO_ERROR(status)) + status |= + MT2063_ReadSub(pInfo->hUserData, pInfo->address, + MT2063_REG_PWR_1, + &pInfo->reg[MT2063_REG_PWR_1], 2); + + if (MT2063_NO_ERROR(status)) { + *Bits = + (enum + MT2063_Mask_Bits)(((SData_t) pInfo-> + reg[MT2063_REG_PWR_2] << 8) + + pInfo->reg[MT2063_REG_PWR_1]); + *Bits = (enum MT2063_Mask_Bits)(*Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ + } + } + + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_EnableExternalShutdown +** +** Description: Enables or disables the operation of the external +** shutdown pin +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** Enabled - 0 = disable the pin, otherwise enable it +** +** Returns: status: +** MT_OK - No errors +** MT_INV_HANDLE - Invalid tuner handle +** MT_COMM_ERR - Serial bus communications error +** +** Dependencies: USERS MUST CALL MT2063_Open() FIRST! +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +****************************************************************************/ +UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + status = MT2063_INV_HANDLE; + else { + if (Enabled == 0) + pInfo->reg[MT2063_REG_PWR_1] &= ~0x08; /* Turn off the bit */ + else + pInfo->reg[MT2063_REG_PWR_1] |= 0x08; /* Turn the bit on */ + + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, + MT2063_REG_PWR_1, + &pInfo->reg[MT2063_REG_PWR_1], 1); + } + + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_SoftwareShutdown +** +** Description: Enables or disables software shutdown function. When +** Shutdown==1, any section whose power mask is set will be +** shutdown. +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** Shutdown - 1 = shutdown the masked sections, otherwise +** power all sections on +** +** Returns: status: +** MT_OK - No errors +** MT_INV_HANDLE - Invalid tuner handle +** MT_COMM_ERR - Serial bus communications error +** +** Dependencies: USERS MUST CALL MT2063_Open() FIRST! +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** 01-03-2008 PINZ Ver 1.xx: Added a trigger of BYPATNUP for +** correct wakeup of the LNA +** +****************************************************************************/ +UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) { + status = MT2063_INV_HANDLE; + } else { + if (Shutdown == 1) + pInfo->reg[MT2063_REG_PWR_1] |= 0x04; /* Turn the bit on */ + else + pInfo->reg[MT2063_REG_PWR_1] &= ~0x04; /* Turn off the bit */ + + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, + MT2063_REG_PWR_1, + &pInfo->reg[MT2063_REG_PWR_1], 1); + + if (Shutdown != 1) { + pInfo->reg[MT2063_REG_BYP_CTRL] = + (pInfo->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40; + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, + MT2063_REG_BYP_CTRL, + &pInfo->reg[MT2063_REG_BYP_CTRL], + 1); + pInfo->reg[MT2063_REG_BYP_CTRL] = + (pInfo->reg[MT2063_REG_BYP_CTRL] & 0x9F); + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, + MT2063_REG_BYP_CTRL, + &pInfo->reg[MT2063_REG_BYP_CTRL], + 1); + } + } + + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_SetExtSRO +** +** Description: Sets the external SRO driver. +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** Ext_SRO_Setting - external SRO drive setting +** +** (default) MT2063_EXT_SRO_OFF - ext driver off +** MT2063_EXT_SRO_BY_1 - ext driver = SRO frequency +** MT2063_EXT_SRO_BY_2 - ext driver = SRO/2 frequency +** MT2063_EXT_SRO_BY_4 - ext driver = SRO/4 frequency +** +** Returns: status: +** MT_OK - No errors +** MT_COMM_ERR - Serial bus communications error +** MT_INV_HANDLE - Invalid tuner handle +** +** Dependencies: USERS MUST CALL MT2063_Open() FIRST! +** +** The Ext_SRO_Setting settings default to OFF +** Use this function if you need to override the default +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** 189 S 05-13-2008 RSK Ver 1.16: Correct location for ExtSRO control. +** +****************************************************************************/ +UData_t MT2063_SetExtSRO(Handle_t h, enum MT2063_Ext_SRO Ext_SRO_Setting) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + status = MT2063_INV_HANDLE; + else { + pInfo->reg[MT2063_REG_CTRL_2C] = + (pInfo-> + reg[MT2063_REG_CTRL_2C] & 0x3F) | ((U8Data) Ext_SRO_Setting + << 6); + status = + MT2063_WriteSub(pInfo->hUserData, pInfo->address, + MT2063_REG_CTRL_2C, + &pInfo->reg[MT2063_REG_CTRL_2C], 1); + } + + return (status); +} + +/**************************************************************************** +** +** Name: MT2063_SetReg +** +** Description: Sets an MT2063 register. +** +** Parameters: h - Tuner handle (returned by MT2063_Open) +** reg - MT2063 register/subaddress location +** val - MT2063 register/subaddress value +** +** Returns: status: +** MT_OK - No errors +** MT_COMM_ERR - Serial bus communications error +** MT_INV_HANDLE - Invalid tuner handle +** MT_ARG_RANGE - Argument out of range +** +** Dependencies: USERS MUST CALL MT2063_Open() FIRST! +** +** Use this function if you need to override a default +** register value +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +****************************************************************************/ +UData_t MT2063_SetReg(Handle_t h, U8Data reg, U8Data val) +{ + UData_t status = MT2063_OK; /* Status to be returned */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + status |= MT2063_INV_HANDLE; + + if (reg >= MT2063_REG_END_REGS) + status |= MT2063_ARG_RANGE; + + if (MT2063_NO_ERROR(status)) { + status |= + MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, + 1); + if (MT2063_NO_ERROR(status)) + pInfo->reg[reg] = val; + } + + return (status); +} + +static UData_t MT2063_Round_fLO(UData_t f_LO, UData_t f_LO_Step, UData_t f_ref) +{ + return f_ref * (f_LO / f_ref) + + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step); +} + +/**************************************************************************** +** +** Name: fLO_FractionalTerm +** +** Description: Calculates the portion contributed by FracN / denom. +** +** This function preserves maximum precision without +** risk of overflow. It accurately calculates +** f_ref * num / denom to within 1 HZ with fixed math. +** +** Parameters: num - Fractional portion of the multiplier +** denom - denominator portion of the ratio +** This routine successfully handles denom values +** up to and including 2^18. +** f_Ref - SRO frequency. This calculation handles +** f_ref as two separate 14-bit fields. +** Therefore, a maximum value of 2^28-1 +** may safely be used for f_ref. This is +** the genesis of the magic number "14" and the +** magic mask value of 0x03FFF. +** +** Returns: f_ref * num / denom +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +****************************************************************************/ +static UData_t MT2063_fLO_FractionalTerm(UData_t f_ref, + UData_t num, UData_t denom) +{ + UData_t t1 = (f_ref >> 14) * num; + UData_t term1 = t1 / denom; + UData_t loss = t1 % denom; + UData_t term2 = + (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom; + return ((term1 << 14) + term2); +} + +/**************************************************************************** +** +** Name: CalcLO1Mult +** +** Description: Calculates Integer divider value and the numerator +** value for a FracN PLL. +** +** This function assumes that the f_LO and f_Ref are +** evenly divisible by f_LO_Step. +** +** Parameters: Div - OUTPUT: Whole number portion of the multiplier +** FracN - OUTPUT: Fractional portion of the multiplier +** f_LO - desired LO frequency. +** f_LO_Step - Minimum step size for the LO (in Hz). +** f_Ref - SRO frequency. +** f_Avoid - Range of PLL frequencies to avoid near +** integer multiples of f_Ref (in Hz). +** +** Returns: Recalculated LO frequency. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +****************************************************************************/ +static UData_t MT2063_CalcLO1Mult(UData_t * Div, + UData_t * FracN, + UData_t f_LO, + UData_t f_LO_Step, UData_t f_Ref) +{ + /* Calculate the whole number portion of the divider */ + *Div = f_LO / f_Ref; + + /* Calculate the numerator value (round to nearest f_LO_Step) */ + *FracN = + (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) + + (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step); + + return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64); +} + +/**************************************************************************** +** +** Name: CalcLO2Mult +** +** Description: Calculates Integer divider value and the numerator +** value for a FracN PLL. +** +** This function assumes that the f_LO and f_Ref are +** evenly divisible by f_LO_Step. +** +** Parameters: Div - OUTPUT: Whole number portion of the multiplier +** FracN - OUTPUT: Fractional portion of the multiplier +** f_LO - desired LO frequency. +** f_LO_Step - Minimum step size for the LO (in Hz). +** f_Ref - SRO frequency. +** f_Avoid - Range of PLL frequencies to avoid near +** integer multiples of f_Ref (in Hz). +** +** Returns: Recalculated LO frequency. +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** +****************************************************************************/ +static UData_t MT2063_CalcLO2Mult(UData_t * Div, + UData_t * FracN, + UData_t f_LO, + UData_t f_LO_Step, UData_t f_Ref) +{ + /* Calculate the whole number portion of the divider */ + *Div = f_LO / f_Ref; + + /* Calculate the numerator value (round to nearest f_LO_Step) */ + *FracN = + (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) + + (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step); + + return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, + 8191); +} + +/**************************************************************************** +** +** Name: FindClearTuneFilter +** +** Description: Calculate the corrrect ClearTune filter to be used for +** a given input frequency. +** +** Parameters: pInfo - ptr to tuner data structure +** f_in - RF input center frequency (in Hz). +** +** Returns: ClearTune filter number (0-31) +** +** Dependencies: MUST CALL MT2064_Open BEFORE FindClearTuneFilter! +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 04-10-2008 PINZ Ver 1.14: Use software-controlled ClearTune +** cross-over frequency values. +** +****************************************************************************/ +static UData_t FindClearTuneFilter(struct MT2063_Info_t *pInfo, UData_t f_in) +{ + UData_t RFBand; + UData_t idx; /* index loop */ + + /* + ** Find RF Band setting + */ + RFBand = 31; /* def when f_in > all */ + for (idx = 0; idx < 31; ++idx) { + if (pInfo->CTFiltMax[idx] >= f_in) { + RFBand = idx; + break; + } + } + return (RFBand); +} + +/**************************************************************************** +** +** Name: MT2063_Tune +** +** Description: Change the tuner's tuned frequency to RFin. +** +** Parameters: h - Open handle to the tuner (from MT2063_Open). +** f_in - RF input center frequency (in Hz). +** +** Returns: status: +** MT_OK - No errors +** MT_INV_HANDLE - Invalid tuner handle +** MT_UPC_UNLOCK - Upconverter PLL unlocked +** MT_DNC_UNLOCK - Downconverter PLL unlocked +** MT_COMM_ERR - Serial bus communications error +** MT_SPUR_CNT_MASK - Count of avoided LO spurs +** MT_SPUR_PRESENT - LO spur possible in output +** MT_FIN_RANGE - Input freq out of range +** MT_FOUT_RANGE - Output freq out of range +** MT_UPC_RANGE - Upconverter freq out of range +** MT_DNC_RANGE - Downconverter freq out of range +** +** Dependencies: MUST CALL MT2063_Open BEFORE MT2063_Tune! +** +** MT_ReadSub - Read data from the two-wire serial bus +** MT_WriteSub - Write data to the two-wire serial bus +** MT_Sleep - Delay execution for x milliseconds +** MT2063_GetLocked - Checks to see if LO1 and LO2 are locked +** +** Revision History: +** +** SCR Date Author Description +** ------------------------------------------------------------------------- +** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. +** 04-10-2008 PINZ Ver 1.05: Use software-controlled ClearTune +** cross-over frequency values. +** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. +** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. +** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW +** +****************************************************************************/ +UData_t MT2063_Tune(Handle_t h, UData_t f_in) +{ /* RF input center frequency */ + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + + UData_t status = MT2063_OK; /* status of operation */ + UData_t LO1; /* 1st LO register value */ + UData_t Num1; /* Numerator for LO1 reg. value */ + UData_t f_IF1; /* 1st IF requested */ + UData_t LO2; /* 2nd LO register value */ + UData_t Num2; /* Numerator for LO2 reg. value */ + UData_t ofLO1, ofLO2; /* last time's LO frequencies */ + UData_t ofin, ofout; /* last time's I/O frequencies */ + U8Data fiffc = 0x80; /* FIFF center freq from tuner */ + UData_t fiffof; /* Offset from FIFF center freq */ + const U8Data LO1LK = 0x80; /* Mask for LO1 Lock bit */ + U8Data LO2LK = 0x08; /* Mask for LO2 Lock bit */ + U8Data val; + UData_t RFBand; + + /* Verify that the handle passed points to a valid tuner */ + if (MT2063_IsValidHandle(pInfo) == 0) + return MT2063_INV_HANDLE; + + /* Check the input and output frequency ranges */ + if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ)) + status |= MT2063_FIN_RANGE; + + if ((pInfo->AS_Data.f_out < MT2063_MIN_FOUT_FREQ) + || (pInfo->AS_Data.f_out > MT2063_MAX_FOUT_FREQ)) + status |= MT2063_FOUT_RANGE; + + /* + ** Save original LO1 and LO2 register values + */ + ofLO1 = pInfo->AS_Data.f_LO1; + ofLO2 = pInfo->AS_Data.f_LO2; + ofin = pInfo->AS_Data.f_in; + ofout = pInfo->AS_Data.f_out; + + /* + ** Find and set RF Band setting + */ + if (pInfo->ctfilt_sw == 1) { + val = (pInfo->reg[MT2063_REG_CTUNE_CTRL] | 0x08); + if (pInfo->reg[MT2063_REG_CTUNE_CTRL] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_CTUNE_CTRL, val); + } + val = pInfo->reg[MT2063_REG_CTUNE_OV]; + RFBand = FindClearTuneFilter(pInfo, f_in); + pInfo->reg[MT2063_REG_CTUNE_OV] = + (U8Data) ((pInfo->reg[MT2063_REG_CTUNE_OV] & ~0x1F) + | RFBand); + if (pInfo->reg[MT2063_REG_CTUNE_OV] != val) { + status |= + MT2063_SetReg(pInfo, MT2063_REG_CTUNE_OV, val); + } + } + + /* + ** Read the FIFF Center Frequency from the tuner + */ + if (MT2063_NO_ERROR(status)) { + status |= + MT2063_ReadSub(pInfo->hUserData, pInfo->address, + MT2063_REG_FIFFC, + &pInfo->reg[MT2063_REG_FIFFC], 1); + fiffc = pInfo->reg[MT2063_REG_FIFFC]; + } + /* + ** Assign in the requested values + */ + pInfo->AS_Data.f_in = f_in; + /* Request a 1st IF such that LO1 is on a step size */ + pInfo->AS_Data.f_if1_Request = + MT2063_Round_fLO(pInfo->AS_Data.f_if1_Request + f_in, + pInfo->AS_Data.f_LO1_Step, + pInfo->AS_Data.f_ref) - f_in; + + /* + ** Calculate frequency settings. f_IF1_FREQ + f_in is the + ** desired LO1 frequency + */ + MT2063_ResetExclZones(&pInfo->AS_Data); + + f_IF1 = MT2063_ChooseFirstIF(&pInfo->AS_Data); + + pInfo->AS_Data.f_LO1 = + MT2063_Round_fLO(f_IF1 + f_in, pInfo->AS_Data.f_LO1_Step, + pInfo->AS_Data.f_ref); + + pInfo->AS_Data.f_LO2 = + MT2063_Round_fLO(pInfo->AS_Data.f_LO1 - pInfo->AS_Data.f_out - f_in, + pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); + + /* + ** Check for any LO spurs in the output bandwidth and adjust + ** the LO settings to avoid them if needed + */ + status |= MT2063_AvoidSpurs(h, &pInfo->AS_Data); + /* + ** MT_AvoidSpurs spurs may have changed the LO1 & LO2 values. + ** Recalculate the LO frequencies and the values to be placed + ** in the tuning registers. + */ + pInfo->AS_Data.f_LO1 = + MT2063_CalcLO1Mult(&LO1, &Num1, pInfo->AS_Data.f_LO1, + pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref); + pInfo->AS_Data.f_LO2 = + MT2063_Round_fLO(pInfo->AS_Data.f_LO1 - pInfo->AS_Data.f_out - f_in, + pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); + pInfo->AS_Data.f_LO2 = + MT2063_CalcLO2Mult(&LO2, &Num2, pInfo->AS_Data.f_LO2, + pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); + + /* + ** Check the upconverter and downconverter frequency ranges + */ + if ((pInfo->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ) + || (pInfo->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ)) + status |= MT2063_UPC_RANGE; + if ((pInfo->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ) + || (pInfo->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ)) + status |= MT2063_DNC_RANGE; + /* LO2 Lock bit was in a different place for B0 version */ + if (pInfo->tuner_id == MT2063_B0) + LO2LK = 0x40; + + /* + ** If we have the same LO frequencies and we're already locked, + ** then skip re-programming the LO registers. + */ + if ((ofLO1 != pInfo->AS_Data.f_LO1) + || (ofLO2 != pInfo->AS_Data.f_LO2) + || ((pInfo->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) != + (LO1LK | LO2LK))) { + /* + ** Calculate the FIFFOF register value + ** + ** IF1_Actual + ** FIFFOF = ------------ - 8 * FIFFC - 4992 + ** f_ref/64 + */ + fiffof = + (pInfo->AS_Data.f_LO1 - + f_in) / (pInfo->AS_Data.f_ref / 64) - 8 * (UData_t) fiffc - + 4992; + if (fiffof > 0xFF) + fiffof = 0xFF; + + /* + ** Place all of the calculated values into the local tuner + ** register fields. + */ + if (MT2063_NO_ERROR(status)) { + pInfo->reg[MT2063_REG_LO1CQ_1] = (U8Data) (LO1 & 0xFF); /* DIV1q */ + pInfo->reg[MT2063_REG_LO1CQ_2] = (U8Data) (Num1 & 0x3F); /* NUM1q */ + pInfo->reg[MT2063_REG_LO2CQ_1] = (U8Data) (((LO2 & 0x7F) << 1) /* DIV2q */ + |(Num2 >> 12)); /* NUM2q (hi) */ + pInfo->reg[MT2063_REG_LO2CQ_2] = (U8Data) ((Num2 & 0x0FF0) >> 4); /* NUM2q (mid) */ + pInfo->reg[MT2063_REG_LO2CQ_3] = (U8Data) (0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */ + + /* + ** Now write out the computed register values + ** IMPORTANT: There is a required order for writing + ** (0x05 must follow all the others). + */ + status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &pInfo->reg[MT2063_REG_LO1CQ_1], 5); /* 0x01 - 0x05 */ + if (pInfo->tuner_id == MT2063_B0) { + /* Re-write the one-shot bits to trigger the tune operation */ + status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_3, &pInfo->reg[MT2063_REG_LO2CQ_3], 1); /* 0x05 */ + } + /* Write out the FIFF offset only if it's changing */ + if (pInfo->reg[MT2063_REG_FIFF_OFFSET] != + (U8Data) fiffof) { + pInfo->reg[MT2063_REG_FIFF_OFFSET] = + (U8Data) fiffof; + status |= + MT2063_WriteSub(pInfo->hUserData, + pInfo->address, + MT2063_REG_FIFF_OFFSET, + &pInfo-> + reg[MT2063_REG_FIFF_OFFSET], + 1); + } + } + + /* + ** Check for LO's locking + */ + + if (MT2063_NO_ERROR(status)) { + status |= MT2063_GetLocked(h); + } + /* + ** If we locked OK, assign calculated data to MT2063_Info_t structure + */ + if (MT2063_NO_ERROR(status)) { + pInfo->f_IF1_actual = pInfo->AS_Data.f_LO1 - f_in; + } + } + + return (status); +} + +UData_t MT_Tune_atv(Handle_t h, UData_t f_in, UData_t bw_in, + enum MTTune_atv_standard tv_type) +{ + + UData_t status = MT2063_OK; + struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h; + struct dvb_frontend *fe = (struct dvb_frontend *)pInfo->hUserData; + struct mt2063_state *state = fe->tuner_priv; + + SData_t pict_car = 0; + SData_t pict2chanb_vsb = 0; + SData_t pict2chanb_snd = 0; + SData_t pict2snd1 = 0; + SData_t pict2snd2 = 0; + SData_t ch_bw = 0; + + SData_t if_mid = 0; + SData_t rcvr_mode = 0; + UData_t mode_get = 0; + + switch (tv_type) { + case MTTUNEA_PAL_B:{ + pict_car = 38900000; + ch_bw = 8000000; + pict2chanb_vsb = -1250000; + pict2snd1 = 5500000; + pict2snd2 = 5742000; + rcvr_mode = 1; + break; + } + case MTTUNEA_PAL_G:{ + pict_car = 38900000; + ch_bw = 7000000; + pict2chanb_vsb = -1250000; + pict2snd1 = 5500000; + pict2snd2 = 0; + rcvr_mode = 1; + break; + } + case MTTUNEA_PAL_I:{ + pict_car = 38900000; + ch_bw = 8000000; + pict2chanb_vsb = -1250000; + pict2snd1 = 6000000; + pict2snd2 = 0; + rcvr_mode = 1; + break; + } + case MTTUNEA_PAL_L:{ + pict_car = 38900000; + ch_bw = 8000000; + pict2chanb_vsb = -1250000; + pict2snd1 = 6500000; + pict2snd2 = 0; + rcvr_mode = 1; + break; + } + case MTTUNEA_PAL_MN:{ + pict_car = 38900000; + ch_bw = 6000000; + pict2chanb_vsb = -1250000; + pict2snd1 = 4500000; + pict2snd2 = 0; + rcvr_mode = 1; + break; + } + case MTTUNEA_PAL_DK:{ + pict_car = 38900000; + ch_bw = 8000000; + pict2chanb_vsb = -1250000; + pict2snd1 = 6500000; + pict2snd2 = 0; + rcvr_mode = 1; + break; + } + case MTTUNEA_DIGITAL:{ + pict_car = 36125000; + ch_bw = 8000000; + pict2chanb_vsb = -(ch_bw / 2); + pict2snd1 = 0; + pict2snd2 = 0; + rcvr_mode = 2; + break; + } + case MTTUNEA_FMRADIO:{ + pict_car = 38900000; + ch_bw = 8000000; + pict2chanb_vsb = -(ch_bw / 2); + pict2snd1 = 0; + pict2snd2 = 0; + rcvr_mode = 4; + //f_in -= 2900000; + break; + } + case MTTUNEA_DVBC:{ + pict_car = 36125000; + ch_bw = 8000000; + pict2chanb_vsb = -(ch_bw / 2); + pict2snd1 = 0; + pict2snd2 = 0; + rcvr_mode = MT2063_CABLE_QAM; + break; + } + case MTTUNEA_DVBT:{ + pict_car = 36125000; + ch_bw = bw_in; //8000000 + pict2chanb_vsb = -(ch_bw / 2); + pict2snd1 = 0; + pict2snd2 = 0; + rcvr_mode = MT2063_OFFAIR_COFDM; + break; + } + case MTTUNEA_UNKNOWN: + break; + default: + break; + } + + pict2chanb_snd = pict2chanb_vsb - ch_bw; + if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2)); + + status |= MT2063_SetParam(h, MT2063_STEPSIZE, 125000); + status |= MT2063_SetParam(h, MT2063_OUTPUT_FREQ, if_mid); + status |= MT2063_SetParam(h, MT2063_OUTPUT_BW, ch_bw); + status |= MT2063_GetParam(h, MT2063_RCVR_MODE, &mode_get); + + status |= MT2063_SetParam(h, MT2063_RCVR_MODE, rcvr_mode); + status |= MT2063_Tune(h, (f_in + (pict2chanb_vsb + (ch_bw / 2)))); + status |= MT2063_GetParam(h, MT2063_RCVR_MODE, &mode_get); + + return (UData_t) status; +} + +static int mt2063_init(struct dvb_frontend *fe) +{ + UData_t status = MT2063_ERROR; + struct mt2063_state *state = fe->tuner_priv; + + status = MT2063_Open(0xC0, &(state->MT2063_ht), fe); + status |= MT2063_SoftwareShutdown(state->MT2063_ht, 1); + status |= MT2063_ClearPowerMaskBits(state->MT2063_ht, MT2063_ALL_SD); + + if (MT2063_OK != status) { + printk("%s %d error status = 0x%x!!\n", __func__, __LINE__, + status); + return -1; + } + + return 0; +} + +static int mt2063_sleep(struct dvb_frontend *fe) +{ + /* TODO: power down */ + return 0; +} + +static int mt2063_get_status(struct dvb_frontend *fe, u32 * status) +{ + int rc = 0; + + //get tuner lock status + + return rc; +} + +static int mt2063_get_state(struct dvb_frontend *fe, + enum tuner_param param, struct tuner_state *state) +{ + struct mt2063_state *mt2063State = fe->tuner_priv; + switch (param) { case DVBFE_TUNER_FREQUENCY: - //get frequency + //get frequency break; case DVBFE_TUNER_TUNERSTEP: break; case DVBFE_TUNER_IFFREQ: break; case DVBFE_TUNER_BANDWIDTH: - //get bandwidth + //get bandwidth break; - case DVBFE_TUNER_REFCLOCK: - state->refclock = (u32_t)MT2063_GetLocked((Handle_t)(mt2063State->MT2063_ht)); + case DVBFE_TUNER_REFCLOCK: + state->refclock = + (u32_t) + MT2063_GetLocked((Handle_t) (mt2063State->MT2063_ht)); break; default: break; } - return (int)state->refclock; -} - -static int mt2063_set_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *state) + return (int)state->refclock; +} + +static int mt2063_set_state(struct dvb_frontend *fe, + enum tuner_param param, struct tuner_state *state) { - struct mt2063_state *mt2063State = fe->tuner_priv; - UData_t status = MT2063_OK; - + struct mt2063_state *mt2063State = fe->tuner_priv; + UData_t status = MT2063_OK; + switch (param) { case DVBFE_TUNER_FREQUENCY: - //set frequency - - status = MT_Tune_atv((Handle_t)(mt2063State->MT2063_ht), state->frequency, state->bandwidth, mt2063State->tv_type); - - mt2063State->frequency = state->frequency; + //set frequency + + status = + MT_Tune_atv((Handle_t) (mt2063State->MT2063_ht), + state->frequency, state->bandwidth, + mt2063State->tv_type); + + mt2063State->frequency = state->frequency; break; case DVBFE_TUNER_TUNERSTEP: break; case DVBFE_TUNER_IFFREQ: break; case DVBFE_TUNER_BANDWIDTH: - //set bandwidth - mt2063State->bandwidth = state->bandwidth; + //set bandwidth + mt2063State->bandwidth = state->bandwidth; + break; + case DVBFE_TUNER_REFCLOCK: + + break; + case DVBFE_TUNER_OPEN: + status = MT2063_Open(MT2063_I2C, &(mt2063State->MT2063_ht), fe); + break; + case DVBFE_TUNER_SOFTWARE_SHUTDOWN: + status = MT2063_SoftwareShutdown(mt2063State->MT2063_ht, 1); + break; + case DVBFE_TUNER_CLEAR_POWER_MASKBITS: + status = + MT2063_ClearPowerMaskBits(mt2063State->MT2063_ht, + MT2063_ALL_SD); break; - case DVBFE_TUNER_REFCLOCK: - - break; - case DVBFE_TUNER_OPEN: - status = MT2063_Open(MT2063_I2C, &(mt2063State->MT2063_ht), fe); - break; - case DVBFE_TUNER_SOFTWARE_SHUTDOWN: - status = MT2063_SoftwareShutdown(mt2063State->MT2063_ht, 1); - break; - case DVBFE_TUNER_CLEAR_POWER_MASKBITS: - status = MT2063_ClearPowerMaskBits(mt2063State->MT2063_ht, MT2063_ALL_SD); - break; default: break; } - return (int)status; -} - -static int mt2063_release(struct dvb_frontend *fe) + return (int)status; +} + +static int mt2063_release(struct dvb_frontend *fe) { - struct mt2063_state *state = fe->tuner_priv; + struct mt2063_state *state = fe->tuner_priv; fe->tuner_priv = NULL; kfree(state); return 0; -} - -static struct dvb_tuner_ops mt2063_ops = { - .info = { - .name = "MT2063 Silicon Tuner", - .frequency_min = 45000000, - .frequency_max = 850000000, - .frequency_step = 0, - }, +} - .init = mt2063_init, - .sleep = mt2063_sleep, - .get_status = mt2063_get_status, - .get_state = mt2063_get_state, - .set_state = mt2063_set_state, - .release = mt2063_release +static struct dvb_tuner_ops mt2063_ops = { + .info = { + .name = "MT2063 Silicon Tuner", + .frequency_min = 45000000, + .frequency_max = 850000000, + .frequency_step = 0, + }, + + .init = mt2063_init, + .sleep = mt2063_sleep, + .get_status = mt2063_get_status, + .get_state = mt2063_get_state, + .set_state = mt2063_set_state, + .release = mt2063_release }; -struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, - struct mt2063_config *config, - struct i2c_adapter *i2c) +struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, + struct mt2063_config *config, + struct i2c_adapter *i2c) { - struct mt2063_state *state = NULL; + struct mt2063_state *state = NULL; - state = kzalloc(sizeof (struct mt2063_state), GFP_KERNEL); + state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL); if (state == NULL) goto error; - state->config = config; - state->i2c = i2c; - state->frontend = fe; - state->reference = config->refclock / 1000; /* kHz */ - state->MT2063_init = FALSE; - fe->tuner_priv = state; - fe->ops.tuner_ops = mt2063_ops; + state->config = config; + state->i2c = i2c; + state->frontend = fe; + state->reference = config->refclock / 1000; /* kHz */ + state->MT2063_init = FALSE; + fe->tuner_priv = state; + fe->ops.tuner_ops = mt2063_ops; - printk("%s: Attaching MT2063 \n", __func__); + printk("%s: Attaching MT2063 \n", __func__); return fe; error: @@ -4473,14 +4706,9 @@ error: return NULL; } - - -EXPORT_SYMBOL(mt2063_attach); +EXPORT_SYMBOL(mt2063_attach); MODULE_PARM_DESC(verbose, "Set Verbosity level"); -MODULE_AUTHOR("Henry"); -MODULE_DESCRIPTION("MT2063 Silicon tuner"); -MODULE_LICENSE("GPL"); - - - +MODULE_AUTHOR("Henry"); +MODULE_DESCRIPTION("MT2063 Silicon tuner"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/common/tuners/mt2063.h b/drivers/media/common/tuners/mt2063.h index 423d1a79b963..4912f8902aaf 100644 --- a/drivers/media/common/tuners/mt2063.h +++ b/drivers/media/common/tuners/mt2063.h @@ -1,729 +1,672 @@ -#ifndef __MT2063_H__ -#define __MT2063_H__ - +#ifndef __MT2063_H__ +#define __MT2063_H__ + #include -#include "dvb_frontend.h" - -//context of mt2063_errordef.h ====================================== -//################################################################# -//================================================================= - -/* -** Note to users: DO NOT EDIT THIS FILE -** -** If you wish to rename any of the "user defined" bits, -** it should be done in the user file that includes this -** source file (e.g. mt_userdef.h) -** -*/ - - - -#define MT2063_ERROR (1 << 31) -#define MT2063_USER_ERROR (1 << 30) - -/* Macro to be used to check for errors */ -#define MT2063_IS_ERROR(s) (((s) >> 30) != 0) -#define MT2063_NO_ERROR(s) (((s) >> 30) == 0) - - -#define MT2063_OK (0x00000000) - -/* Unknown error */ -#define MT2063_UNKNOWN (0x80000001) - -/* Error: Upconverter PLL is not locked */ -#define MT2063_UPC_UNLOCK (0x80000002) - -/* Error: Downconverter PLL is not locked */ -#define MT2063_DNC_UNLOCK (0x80000004) - -/* Error: Two-wire serial bus communications error */ -#define MT2063_COMM_ERR (0x80000008) - -/* Error: Tuner handle passed to function was invalid */ -#define MT2063_INV_HANDLE (0x80000010) - -/* Error: Function argument is invalid (out of range) */ -#define MT2063_ARG_RANGE (0x80000020) - -/* Error: Function argument (ptr to return value) was NULL */ -#define MT2063_ARG_NULL (0x80000040) - -/* Error: Attempt to open more than MT_TUNER_CNT tuners */ -#define MT2063_TUNER_CNT_ERR (0x80000080) - -/* Error: Tuner Part Code / Rev Code mismatches expected value */ -#define MT2063_TUNER_ID_ERR (0x80000100) - -/* Error: Tuner Initialization failure */ -#define MT2063_TUNER_INIT_ERR (0x80000200) - -#define MT2063_TUNER_OPEN_ERR (0x80000400) - -/* User-definable fields (see mt_userdef.h) */ -#define MT2063_USER_DEFINED1 (0x00001000) -#define MT2063_USER_DEFINED2 (0x00002000) -#define MT2063_USER_DEFINED3 (0x00004000) -#define MT2063_USER_DEFINED4 (0x00008000) -#define MT2063_USER_MASK (0x4000f000) -#define MT2063_USER_SHIFT (12) - -/* Info: Mask of bits used for # of LO-related spurs that were avoided during tuning */ -#define MT2063_SPUR_CNT_MASK (0x001f0000) -#define MT2063_SPUR_SHIFT (16) - -/* Info: Tuner timeout waiting for condition */ -#define MT2063_TUNER_TIMEOUT (0x00400000) - -/* Info: Unavoidable LO-related spur may be present in the output */ -#define MT2063_SPUR_PRESENT_ERR (0x00800000) - -/* Info: Tuner input frequency is out of range */ -#define MT2063_FIN_RANGE (0x01000000) - -/* Info: Tuner output frequency is out of range */ -#define MT2063_FOUT_RANGE (0x02000000) - -/* Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */ -#define MT2063_UPC_RANGE (0x04000000) - -/* Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */ -#define MT2063_DNC_RANGE (0x08000000) - -//end of mt2063_errordef.h -//================================================================= -//################################################################# -//================================================================= - -//context of mt2063_userdef.h ====================================== -//################################################################# -//================================================================= -/* -** Data Types -*/ -#define MT2060_CNT 10 - -typedef unsigned char U8Data; /* type corresponds to 8 bits */ -typedef unsigned int UData_t; /* type must be at least 32 bits */ -typedef int SData_t; /* type must be at least 32 bits */ -typedef void * Handle_t; /* memory pointer type */ -//typedef double FData_t; /* floating point data type */ - -#define MAX_UDATA (4294967295) /* max value storable in UData_t */ - -/* -** Define an MTxxxx_CNT macro for each type of tuner that will be built -** into your application (e.g., MT2121, MT2060). MT_TUNER_CNT -** must be set to the SUM of all of the MTxxxx_CNT macros. -** -** #define MT2050_CNT (1) -** #define MT2060_CNT (1) -** #define MT2111_CNT (1) -** #define MT2121_CNT (3) -*/ - -#define MT2063_CNT (1) - -#if !defined( MT2063_TUNER_CNT ) -#define MT2063_TUNER_CNT (1) /* total num of MicroTuner tuners */ -#endif -#define MT2063_I2C (0xC0) - -UData_t MT2063_WriteSub(Handle_t hUserData, - UData_t addr, - U8Data subAddress, - U8Data *pData, - UData_t cnt); - - -UData_t MT2063_ReadSub(Handle_t hUserData, - UData_t addr, - U8Data subAddress, - U8Data *pData, - UData_t cnt); - - -void MT2063_Sleep(Handle_t hUserData, - UData_t nMinDelayTime); - - -#if defined(MT2060_CNT) -#if MT2060_CNT > 0 -UData_t MT2060_TunerGain(Handle_t hUserData, - SData_t* pMeas); -#endif -#endif -//end of mt2063_userdef.h -//================================================================= -//################################################################# -//================================================================= - - -//context of mt2063_spruavoid.h ====================================== -//################################################################# -//================================================================= -/* -** Constant defining the version of the following structure -** and therefore the API for this code. -** -** When compiling the tuner driver, the preprocessor will -** check against this version number to make sure that -** it matches the version that the tuner driver knows about. -*/ -/* Version 010201 => 1.21 */ -#define MT2063_AVOID_SPURS_INFO_VERSION 010201 - - -/* DECT Frequency Avoidance */ -#define MT2063_DECT_AVOID_US_FREQS 0x00000001 - -#define MT2063_DECT_AVOID_EURO_FREQS 0x00000002 - -#define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0) - -#define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0) - - -enum MT2063_DECT_Avoid_Type -{ - MT2063_NO_DECT_AVOIDANCE = 0, /* Do not create DECT exclusion zones. */ - MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS, /* Avoid US DECT frequencies. */ - MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS, /* Avoid European DECT frequencies. */ - MT2063_AVOID_BOTH /* Avoid both regions. Not typically used. */ - -} ; - - -#define MT2063_MAX_ZONES 48 - -struct MT2063_ExclZone_t; - -struct MT2063_ExclZone_t -{ - UData_t min_; - UData_t max_; - struct MT2063_ExclZone_t* next_; -}; - -/* -** Structure of data needed for Spur Avoidance -*/ -struct MT2063_AvoidSpursData_t -{ - UData_t nAS_Algorithm; - UData_t f_ref; - UData_t f_in; - UData_t f_LO1; - UData_t f_if1_Center; - UData_t f_if1_Request; - UData_t f_if1_bw; - UData_t f_LO2; - UData_t f_out; - UData_t f_out_bw; - UData_t f_LO1_Step; - UData_t f_LO2_Step; - UData_t f_LO1_FracN_Avoid; - UData_t f_LO2_FracN_Avoid; - UData_t f_zif_bw; - UData_t f_min_LO_Separation; - UData_t maxH1; - UData_t maxH2; - enum MT2063_DECT_Avoid_Type avoidDECT; - UData_t bSpurPresent; - UData_t bSpurAvoided; - UData_t nSpursFound; - UData_t nZones; - struct MT2063_ExclZone_t* freeZones; - struct MT2063_ExclZone_t* usedZones; - struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES]; -}; - -UData_t MT2063_RegisterTuner(struct MT2063_AvoidSpursData_t* pAS_Info); - -void MT2063_UnRegisterTuner(struct MT2063_AvoidSpursData_t* pAS_Info); - -void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t* pAS_Info); - -void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t* pAS_Info, - UData_t f_min, - UData_t f_max); - -UData_t MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t* pAS_Info); - -UData_t MT2063_AvoidSpurs(Handle_t h, - struct MT2063_AvoidSpursData_t* pAS_Info); - -UData_t MT2063_AvoidSpursVersion(void); - -//end of mt2063_spuravoid.h -//================================================================= -//################################################################# -//================================================================= - - -/* -** Values returned by the MT2063's on-chip temperature sensor -** to be read/written. -*/ -enum MT2063_Temperature -{ - MT2063_T_0C = 0, /* Temperature approx 0C */ - MT2063_T_10C, /* Temperature approx 10C */ - MT2063_T_20C, /* Temperature approx 20C */ - MT2063_T_30C, /* Temperature approx 30C */ - MT2063_T_40C, /* Temperature approx 40C */ - MT2063_T_50C, /* Temperature approx 50C */ - MT2063_T_60C, /* Temperature approx 60C */ - MT2063_T_70C, /* Temperature approx 70C */ - MT2063_T_80C, /* Temperature approx 80C */ - MT2063_T_90C, /* Temperature approx 90C */ - MT2063_T_100C, /* Temperature approx 100C */ - MT2063_T_110C, /* Temperature approx 110C */ - MT2063_T_120C, /* Temperature approx 120C */ - MT2063_T_130C, /* Temperature approx 130C */ - MT2063_T_140C, /* Temperature approx 140C */ - MT2063_T_150C, /* Temperature approx 150C */ -}; - - -/* -** Parameters for selecting GPIO bits -*/ -enum MT2063_GPIO_Attr -{ - MT2063_GPIO_IN, - MT2063_GPIO_DIR, - MT2063_GPIO_OUT, -}; - -enum MT2063_GPIO_ID -{ - MT2063_GPIO0, - MT2063_GPIO1, - MT2063_GPIO2, -}; - - -/* -** Parameter for function MT2063_SetExtSRO that specifies the external -** SRO drive frequency. -** -** MT2063_EXT_SRO_OFF is the power-up default value. -*/ -enum MT2063_Ext_SRO -{ - MT2063_EXT_SRO_OFF, /* External SRO drive off */ - MT2063_EXT_SRO_BY_4, /* External SRO drive divide by 4 */ - MT2063_EXT_SRO_BY_2, /* External SRO drive divide by 2 */ - MT2063_EXT_SRO_BY_1 /* External SRO drive divide by 1 */ -}; - - -/* -** Parameter for function MT2063_SetPowerMask that specifies the power down -** of various sections of the MT2063. -*/ -enum MT2063_Mask_Bits -{ - MT2063_REG_SD = 0x0040, /* Shutdown regulator */ - MT2063_SRO_SD = 0x0020, /* Shutdown SRO */ - MT2063_AFC_SD = 0x0010, /* Shutdown AFC A/D */ - MT2063_PD_SD = 0x0002, /* Enable power detector shutdown */ - MT2063_PDADC_SD = 0x0001, /* Enable power detector A/D shutdown */ - MT2063_VCO_SD = 0x8000, /* Enable VCO shutdown */ - MT2063_LTX_SD = 0x4000, /* Enable LTX shutdown */ - MT2063_LT1_SD = 0x2000, /* Enable LT1 shutdown */ - MT2063_LNA_SD = 0x1000, /* Enable LNA shutdown */ - MT2063_UPC_SD = 0x0800, /* Enable upconverter shutdown */ - MT2063_DNC_SD = 0x0400, /* Enable downconverter shutdown */ - MT2063_VGA_SD = 0x0200, /* Enable VGA shutdown */ - MT2063_AMP_SD = 0x0100, /* Enable AMP shutdown */ - MT2063_ALL_SD = 0xFF73, /* All shutdown bits for this tuner */ - MT2063_NONE_SD = 0x0000 /* No shutdown bits */ -}; - - -/* -** Parameter for function MT2063_GetParam & MT2063_SetParam that -** specifies the tuning algorithm parameter to be read/written. -*/ -enum MT2063_Param -{ - /* tuner address set by MT2063_Open() */ - MT2063_IC_ADDR, - - /* max number of MT2063 tuners set by MT_TUNER_CNT in mt_userdef.h */ - MT2063_MAX_OPEN, - - /* current number of open MT2063 tuners set by MT2063_Open() */ - MT2063_NUM_OPEN, - - /* crystal frequency (default: 16000000 Hz) */ - MT2063_SRO_FREQ, - - /* min tuning step size (default: 50000 Hz) */ - MT2063_STEPSIZE, - - /* input center frequency set by MT2063_Tune() */ - MT2063_INPUT_FREQ, - - /* LO1 Frequency set by MT2063_Tune() */ - MT2063_LO1_FREQ, - - /* LO1 minimum step size (default: 250000 Hz) */ - MT2063_LO1_STEPSIZE, - - /* LO1 FracN keep-out region (default: 999999 Hz) */ - MT2063_LO1_FRACN_AVOID_PARAM, - - /* Current 1st IF in use set by MT2063_Tune() */ - MT2063_IF1_ACTUAL, - - /* Requested 1st IF set by MT2063_Tune() */ - MT2063_IF1_REQUEST, - - /* Center of 1st IF SAW filter (default: 1218000000 Hz) */ - MT2063_IF1_CENTER, - - /* Bandwidth of 1st IF SAW filter (default: 20000000 Hz) */ - MT2063_IF1_BW, - - /* zero-IF bandwidth (default: 2000000 Hz) */ - MT2063_ZIF_BW, - - /* LO2 Frequency set by MT2063_Tune() */ - MT2063_LO2_FREQ, - - /* LO2 minimum step size (default: 50000 Hz) */ - MT2063_LO2_STEPSIZE, - - /* LO2 FracN keep-out region (default: 374999 Hz) */ - MT2063_LO2_FRACN_AVOID, - - /* output center frequency set by MT2063_Tune() */ - MT2063_OUTPUT_FREQ, - - /* output bandwidth set by MT2063_Tune() */ - MT2063_OUTPUT_BW, - - /* min inter-tuner LO separation (default: 1000000 Hz) */ - MT2063_LO_SEPARATION, - - /* ID of avoid-spurs algorithm in use compile-time constant */ - MT2063_AS_ALG, - - /* max # of intra-tuner harmonics (default: 15) */ - MT2063_MAX_HARM1, - - /* max # of inter-tuner harmonics (default: 7) */ - MT2063_MAX_HARM2, - - /* # of 1st IF exclusion zones used set by MT2063_Tune() */ - MT2063_EXCL_ZONES, - - /* # of spurs found/avoided set by MT2063_Tune() */ - MT2063_NUM_SPURS, - - /* >0 spurs avoided set by MT2063_Tune() */ - MT2063_SPUR_AVOIDED, - - /* >0 spurs in output (mathematically) set by MT2063_Tune() */ - MT2063_SPUR_PRESENT, - - /* Receiver Mode for some parameters. 1 is DVB-T */ - MT2063_RCVR_MODE, - - /* directly set LNA attenuation, parameter is value to set */ - MT2063_ACLNA, - - /* maximum LNA attenuation, parameter is value to set */ - MT2063_ACLNA_MAX, - - /* directly set ATN attenuation. Paremeter is value to set. */ - MT2063_ACRF, - - /* maxium ATN attenuation. Paremeter is value to set. */ - MT2063_ACRF_MAX, - - /* directly set FIF attenuation. Paremeter is value to set. */ - MT2063_ACFIF, - - /* maxium FIF attenuation. Paremeter is value to set. */ - MT2063_ACFIF_MAX, - - /* LNA Rin */ - MT2063_LNA_RIN, - - /* Power Detector LNA level target */ - MT2063_LNA_TGT, - - /* Power Detector 1 level */ - MT2063_PD1, - - /* Power Detector 1 level target */ - MT2063_PD1_TGT, - - /* Power Detector 2 level */ - MT2063_PD2, - - /* Power Detector 2 level target */ - MT2063_PD2_TGT, - - /* Selects, which DNC is activ */ - MT2063_DNC_OUTPUT_ENABLE, - - /* VGA gain code */ - MT2063_VGAGC, - - /* VGA bias current */ - MT2063_VGAOI, - - /* TAGC, determins the speed of the AGC */ - MT2063_TAGC, - - /* AMP gain code */ - MT2063_AMPGC, - - /* Control setting to avoid DECT freqs (default: MT_AVOID_BOTH) */ - MT2063_AVOID_DECT, - - /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ - MT2063_CTFILT_SW, - - MT2063_EOP /* last entry in enumerated list */ - -}; - - -/* -** Parameter for selecting tuner mode -*/ -enum MT2063_RCVR_MODES -{ - MT2063_CABLE_QAM = 0, /* Digital cable */ - MT2063_CABLE_ANALOG, /* Analog cable */ - MT2063_OFFAIR_COFDM, /* Digital offair */ - MT2063_OFFAIR_COFDM_SAWLESS, /* Digital offair without SAW */ - MT2063_OFFAIR_ANALOG, /* Analog offair */ - MT2063_OFFAIR_8VSB, /* Analog offair */ - MT2063_NUM_RCVR_MODES -}; - - -/* -** Possible values for MT2063_DNC_OUTPUT -*/ -enum MT2063_DNC_Output_Enable{ - MT2063_DNC_NONE = 0, - MT2063_DNC_1, - MT2063_DNC_2, - MT2063_DNC_BOTH -}; - -/* -** Two-wire serial bus subaddresses of the tuner registers. -** Also known as the tuner's register addresses. -*/ -enum MT2063_Register_Offsets -{ - MT2063_REG_PART_REV = 0, /* 0x00: Part/Rev Code */ - MT2063_REG_LO1CQ_1, /* 0x01: LO1C Queued Byte 1 */ - MT2063_REG_LO1CQ_2, /* 0x02: LO1C Queued Byte 2 */ - MT2063_REG_LO2CQ_1, /* 0x03: LO2C Queued Byte 1 */ - MT2063_REG_LO2CQ_2, /* 0x04: LO2C Queued Byte 2 */ - MT2063_REG_LO2CQ_3, /* 0x05: LO2C Queued Byte 3 */ - MT2063_REG_RSVD_06, /* 0x06: Reserved */ - MT2063_REG_LO_STATUS, /* 0x07: LO Status */ - MT2063_REG_FIFFC, /* 0x08: FIFF Center */ - MT2063_REG_CLEARTUNE, /* 0x09: ClearTune Filter */ - MT2063_REG_ADC_OUT, /* 0x0A: ADC_OUT */ - MT2063_REG_LO1C_1, /* 0x0B: LO1C Byte 1 */ - MT2063_REG_LO1C_2, /* 0x0C: LO1C Byte 2 */ - MT2063_REG_LO2C_1, /* 0x0D: LO2C Byte 1 */ - MT2063_REG_LO2C_2, /* 0x0E: LO2C Byte 2 */ - MT2063_REG_LO2C_3, /* 0x0F: LO2C Byte 3 */ - MT2063_REG_RSVD_10, /* 0x10: Reserved */ - MT2063_REG_PWR_1, /* 0x11: PWR Byte 1 */ - MT2063_REG_PWR_2, /* 0x12: PWR Byte 2 */ - MT2063_REG_TEMP_STATUS, /* 0x13: Temp Status */ - MT2063_REG_XO_STATUS, /* 0x14: Crystal Status */ - MT2063_REG_RF_STATUS, /* 0x15: RF Attn Status */ - MT2063_REG_FIF_STATUS, /* 0x16: FIF Attn Status */ - MT2063_REG_LNA_OV, /* 0x17: LNA Attn Override */ - MT2063_REG_RF_OV, /* 0x18: RF Attn Override */ - MT2063_REG_FIF_OV, /* 0x19: FIF Attn Override */ - MT2063_REG_LNA_TGT, /* 0x1A: Reserved */ - MT2063_REG_PD1_TGT, /* 0x1B: Pwr Det 1 Target */ - MT2063_REG_PD2_TGT, /* 0x1C: Pwr Det 2 Target */ - MT2063_REG_RSVD_1D, /* 0x1D: Reserved */ - MT2063_REG_RSVD_1E, /* 0x1E: Reserved */ - MT2063_REG_RSVD_1F, /* 0x1F: Reserved */ - MT2063_REG_RSVD_20, /* 0x20: Reserved */ - MT2063_REG_BYP_CTRL, /* 0x21: Bypass Control */ - MT2063_REG_RSVD_22, /* 0x22: Reserved */ - MT2063_REG_RSVD_23, /* 0x23: Reserved */ - MT2063_REG_RSVD_24, /* 0x24: Reserved */ - MT2063_REG_RSVD_25, /* 0x25: Reserved */ - MT2063_REG_RSVD_26, /* 0x26: Reserved */ - MT2063_REG_RSVD_27, /* 0x27: Reserved */ - MT2063_REG_FIFF_CTRL, /* 0x28: FIFF Control */ - MT2063_REG_FIFF_OFFSET, /* 0x29: FIFF Offset */ - MT2063_REG_CTUNE_CTRL, /* 0x2A: Reserved */ - MT2063_REG_CTUNE_OV, /* 0x2B: Reserved */ - MT2063_REG_CTRL_2C, /* 0x2C: Reserved */ - MT2063_REG_FIFF_CTRL2, /* 0x2D: Fiff Control */ - MT2063_REG_RSVD_2E, /* 0x2E: Reserved */ - MT2063_REG_DNC_GAIN, /* 0x2F: DNC Control */ - MT2063_REG_VGA_GAIN, /* 0x30: VGA Gain Ctrl */ - MT2063_REG_RSVD_31, /* 0x31: Reserved */ - MT2063_REG_TEMP_SEL, /* 0x32: Temperature Selection */ - MT2063_REG_RSVD_33, /* 0x33: Reserved */ - MT2063_REG_RSVD_34, /* 0x34: Reserved */ - MT2063_REG_RSVD_35, /* 0x35: Reserved */ - MT2063_REG_RSVD_36, /* 0x36: Reserved */ - MT2063_REG_RSVD_37, /* 0x37: Reserved */ - MT2063_REG_RSVD_38, /* 0x38: Reserved */ - MT2063_REG_RSVD_39, /* 0x39: Reserved */ - MT2063_REG_RSVD_3A, /* 0x3A: Reserved */ - MT2063_REG_RSVD_3B, /* 0x3B: Reserved */ - MT2063_REG_RSVD_3C, /* 0x3C: Reserved */ - MT2063_REG_END_REGS -}; - -struct MT2063_Info_t -{ - Handle_t handle; - Handle_t hUserData; - UData_t address; - UData_t version; - UData_t tuner_id; - struct MT2063_AvoidSpursData_t AS_Data; - UData_t f_IF1_actual; - UData_t rcvr_mode; - UData_t ctfilt_sw; - UData_t CTFiltMax[31]; - UData_t num_regs; - U8Data reg[MT2063_REG_END_REGS]; -} ; -typedef struct MT2063_Info_t* pMT2063_Info_t; - -enum MTTune_atv_standard{ - MTTUNEA_UNKNOWN = 0, - MTTUNEA_PAL_B, - MTTUNEA_PAL_G, - MTTUNEA_PAL_I, - MTTUNEA_PAL_L, - MTTUNEA_PAL_MN, - MTTUNEA_PAL_DK, - MTTUNEA_DIGITAL, - MTTUNEA_FMRADIO, - MTTUNEA_DVBC, - MTTUNEA_DVBT -}; - -/* ====== Functions which are declared in MT2063.c File ======= */ - -UData_t MT2063_Open(UData_t MT2063_Addr, - Handle_t* hMT2063, - Handle_t hUserData); - - -UData_t MT2063_Close(Handle_t hMT2063); - -UData_t MT2063_Tune(Handle_t h, - UData_t f_in); /* RF input center frequency */ - -UData_t MT2063_GetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id, enum MT2063_GPIO_Attr attr, UData_t* value); - - -UData_t MT2063_GetLocked(Handle_t h); - - -UData_t MT2063_GetParam(Handle_t h, - enum MT2063_Param param, - UData_t* pValue); - - -UData_t MT2063_GetReg(Handle_t h, - U8Data reg, - U8Data* val); - - -UData_t MT2063_GetTemp(Handle_t h, enum MT2063_Temperature* value); - - -UData_t MT2063_GetUserData(Handle_t h, - Handle_t* hUserData); - -UData_t MT2063_ReInit(Handle_t h); - - -UData_t MT2063_SetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id, enum MT2063_GPIO_Attr attr, UData_t value); - -UData_t MT2063_SetParam(Handle_t h, - enum MT2063_Param param, - UData_t nValue); - - -UData_t MT2063_SetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits); - -UData_t MT2063_ClearPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits); - -UData_t MT2063_GetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits *Bits); - -UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled); - -UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown); - -UData_t MT2063_SetExtSRO(Handle_t h, enum MT2063_Ext_SRO Ext_SRO_Setting); - -UData_t MT2063_SetReg(Handle_t h, - U8Data reg, - U8Data val); - -UData_t MT_Tune_atv(Handle_t h, UData_t f_in,UData_t bw_in, enum MTTune_atv_standard tv_type); - - - -struct mt2063_config { - u8 tuner_address; - u32 refclock; +#include "dvb_frontend.h" + +//context of mt2063_errordef.h ====================================== +//################################################################# +//================================================================= + +/* +** Note to users: DO NOT EDIT THIS FILE +** +** If you wish to rename any of the "user defined" bits, +** it should be done in the user file that includes this +** source file (e.g. mt_userdef.h) +** +*/ + +#define MT2063_ERROR (1 << 31) +#define MT2063_USER_ERROR (1 << 30) + +/* Macro to be used to check for errors */ +#define MT2063_IS_ERROR(s) (((s) >> 30) != 0) +#define MT2063_NO_ERROR(s) (((s) >> 30) == 0) + +#define MT2063_OK (0x00000000) + +/* Unknown error */ +#define MT2063_UNKNOWN (0x80000001) + +/* Error: Upconverter PLL is not locked */ +#define MT2063_UPC_UNLOCK (0x80000002) + +/* Error: Downconverter PLL is not locked */ +#define MT2063_DNC_UNLOCK (0x80000004) + +/* Error: Two-wire serial bus communications error */ +#define MT2063_COMM_ERR (0x80000008) + +/* Error: Tuner handle passed to function was invalid */ +#define MT2063_INV_HANDLE (0x80000010) + +/* Error: Function argument is invalid (out of range) */ +#define MT2063_ARG_RANGE (0x80000020) + +/* Error: Function argument (ptr to return value) was NULL */ +#define MT2063_ARG_NULL (0x80000040) + +/* Error: Attempt to open more than MT_TUNER_CNT tuners */ +#define MT2063_TUNER_CNT_ERR (0x80000080) + +/* Error: Tuner Part Code / Rev Code mismatches expected value */ +#define MT2063_TUNER_ID_ERR (0x80000100) + +/* Error: Tuner Initialization failure */ +#define MT2063_TUNER_INIT_ERR (0x80000200) + +#define MT2063_TUNER_OPEN_ERR (0x80000400) + +/* User-definable fields (see mt_userdef.h) */ +#define MT2063_USER_DEFINED1 (0x00001000) +#define MT2063_USER_DEFINED2 (0x00002000) +#define MT2063_USER_DEFINED3 (0x00004000) +#define MT2063_USER_DEFINED4 (0x00008000) +#define MT2063_USER_MASK (0x4000f000) +#define MT2063_USER_SHIFT (12) + +/* Info: Mask of bits used for # of LO-related spurs that were avoided during tuning */ +#define MT2063_SPUR_CNT_MASK (0x001f0000) +#define MT2063_SPUR_SHIFT (16) + +/* Info: Tuner timeout waiting for condition */ +#define MT2063_TUNER_TIMEOUT (0x00400000) + +/* Info: Unavoidable LO-related spur may be present in the output */ +#define MT2063_SPUR_PRESENT_ERR (0x00800000) + +/* Info: Tuner input frequency is out of range */ +#define MT2063_FIN_RANGE (0x01000000) + +/* Info: Tuner output frequency is out of range */ +#define MT2063_FOUT_RANGE (0x02000000) + +/* Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */ +#define MT2063_UPC_RANGE (0x04000000) + +/* Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */ +#define MT2063_DNC_RANGE (0x08000000) + +//end of mt2063_errordef.h +//================================================================= +//################################################################# +//================================================================= + +//context of mt2063_userdef.h ====================================== +//################################################################# +//================================================================= +/* +** Data Types +*/ +#define MT2060_CNT 10 + +typedef unsigned char U8Data; /* type corresponds to 8 bits */ +typedef unsigned int UData_t; /* type must be at least 32 bits */ +typedef int SData_t; /* type must be at least 32 bits */ +typedef void *Handle_t; /* memory pointer type */ +//typedef double FData_t; /* floating point data type */ + +#define MAX_UDATA (4294967295) /* max value storable in UData_t */ + +/* +** Define an MTxxxx_CNT macro for each type of tuner that will be built +** into your application (e.g., MT2121, MT2060). MT_TUNER_CNT +** must be set to the SUM of all of the MTxxxx_CNT macros. +** +** #define MT2050_CNT (1) +** #define MT2060_CNT (1) +** #define MT2111_CNT (1) +** #define MT2121_CNT (3) +*/ + +#define MT2063_CNT (1) + +#if !defined( MT2063_TUNER_CNT ) +#define MT2063_TUNER_CNT (1) /* total num of MicroTuner tuners */ +#endif +#define MT2063_I2C (0xC0) + +UData_t MT2063_WriteSub(Handle_t hUserData, + UData_t addr, + U8Data subAddress, U8Data * pData, UData_t cnt); + +UData_t MT2063_ReadSub(Handle_t hUserData, + UData_t addr, + U8Data subAddress, U8Data * pData, UData_t cnt); + +void MT2063_Sleep(Handle_t hUserData, UData_t nMinDelayTime); + +#if defined(MT2060_CNT) +#if MT2060_CNT > 0 +UData_t MT2060_TunerGain(Handle_t hUserData, SData_t * pMeas); +#endif +#endif +//end of mt2063_userdef.h +//================================================================= +//################################################################# +//================================================================= + +//context of mt2063_spruavoid.h ====================================== +//################################################################# +//================================================================= +/* +** Constant defining the version of the following structure +** and therefore the API for this code. +** +** When compiling the tuner driver, the preprocessor will +** check against this version number to make sure that +** it matches the version that the tuner driver knows about. +*/ +/* Version 010201 => 1.21 */ +#define MT2063_AVOID_SPURS_INFO_VERSION 010201 + +/* DECT Frequency Avoidance */ +#define MT2063_DECT_AVOID_US_FREQS 0x00000001 + +#define MT2063_DECT_AVOID_EURO_FREQS 0x00000002 + +#define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0) + +#define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0) + +enum MT2063_DECT_Avoid_Type { + MT2063_NO_DECT_AVOIDANCE = 0, /* Do not create DECT exclusion zones. */ + MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS, /* Avoid US DECT frequencies. */ + MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS, /* Avoid European DECT frequencies. */ + MT2063_AVOID_BOTH /* Avoid both regions. Not typically used. */ }; -struct mt2063_state { +#define MT2063_MAX_ZONES 48 + +struct MT2063_ExclZone_t; + +struct MT2063_ExclZone_t { + UData_t min_; + UData_t max_; + struct MT2063_ExclZone_t *next_; +}; + +/* +** Structure of data needed for Spur Avoidance +*/ +struct MT2063_AvoidSpursData_t { + UData_t nAS_Algorithm; + UData_t f_ref; + UData_t f_in; + UData_t f_LO1; + UData_t f_if1_Center; + UData_t f_if1_Request; + UData_t f_if1_bw; + UData_t f_LO2; + UData_t f_out; + UData_t f_out_bw; + UData_t f_LO1_Step; + UData_t f_LO2_Step; + UData_t f_LO1_FracN_Avoid; + UData_t f_LO2_FracN_Avoid; + UData_t f_zif_bw; + UData_t f_min_LO_Separation; + UData_t maxH1; + UData_t maxH2; + enum MT2063_DECT_Avoid_Type avoidDECT; + UData_t bSpurPresent; + UData_t bSpurAvoided; + UData_t nSpursFound; + UData_t nZones; + struct MT2063_ExclZone_t *freeZones; + struct MT2063_ExclZone_t *usedZones; + struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES]; +}; + +UData_t MT2063_RegisterTuner(struct MT2063_AvoidSpursData_t *pAS_Info); + +void MT2063_UnRegisterTuner(struct MT2063_AvoidSpursData_t *pAS_Info); + +void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info); + +void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info, + UData_t f_min, UData_t f_max); + +UData_t MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info); + +UData_t MT2063_AvoidSpurs(Handle_t h, struct MT2063_AvoidSpursData_t *pAS_Info); + +UData_t MT2063_AvoidSpursVersion(void); + +//end of mt2063_spuravoid.h +//================================================================= +//################################################################# +//================================================================= + +/* +** Values returned by the MT2063's on-chip temperature sensor +** to be read/written. +*/ +enum MT2063_Temperature { + MT2063_T_0C = 0, /* Temperature approx 0C */ + MT2063_T_10C, /* Temperature approx 10C */ + MT2063_T_20C, /* Temperature approx 20C */ + MT2063_T_30C, /* Temperature approx 30C */ + MT2063_T_40C, /* Temperature approx 40C */ + MT2063_T_50C, /* Temperature approx 50C */ + MT2063_T_60C, /* Temperature approx 60C */ + MT2063_T_70C, /* Temperature approx 70C */ + MT2063_T_80C, /* Temperature approx 80C */ + MT2063_T_90C, /* Temperature approx 90C */ + MT2063_T_100C, /* Temperature approx 100C */ + MT2063_T_110C, /* Temperature approx 110C */ + MT2063_T_120C, /* Temperature approx 120C */ + MT2063_T_130C, /* Temperature approx 130C */ + MT2063_T_140C, /* Temperature approx 140C */ + MT2063_T_150C, /* Temperature approx 150C */ +}; + +/* +** Parameters for selecting GPIO bits +*/ +enum MT2063_GPIO_Attr { + MT2063_GPIO_IN, + MT2063_GPIO_DIR, + MT2063_GPIO_OUT, +}; + +enum MT2063_GPIO_ID { + MT2063_GPIO0, + MT2063_GPIO1, + MT2063_GPIO2, +}; + +/* +** Parameter for function MT2063_SetExtSRO that specifies the external +** SRO drive frequency. +** +** MT2063_EXT_SRO_OFF is the power-up default value. +*/ +enum MT2063_Ext_SRO { + MT2063_EXT_SRO_OFF, /* External SRO drive off */ + MT2063_EXT_SRO_BY_4, /* External SRO drive divide by 4 */ + MT2063_EXT_SRO_BY_2, /* External SRO drive divide by 2 */ + MT2063_EXT_SRO_BY_1 /* External SRO drive divide by 1 */ +}; + +/* +** Parameter for function MT2063_SetPowerMask that specifies the power down +** of various sections of the MT2063. +*/ +enum MT2063_Mask_Bits { + MT2063_REG_SD = 0x0040, /* Shutdown regulator */ + MT2063_SRO_SD = 0x0020, /* Shutdown SRO */ + MT2063_AFC_SD = 0x0010, /* Shutdown AFC A/D */ + MT2063_PD_SD = 0x0002, /* Enable power detector shutdown */ + MT2063_PDADC_SD = 0x0001, /* Enable power detector A/D shutdown */ + MT2063_VCO_SD = 0x8000, /* Enable VCO shutdown */ + MT2063_LTX_SD = 0x4000, /* Enable LTX shutdown */ + MT2063_LT1_SD = 0x2000, /* Enable LT1 shutdown */ + MT2063_LNA_SD = 0x1000, /* Enable LNA shutdown */ + MT2063_UPC_SD = 0x0800, /* Enable upconverter shutdown */ + MT2063_DNC_SD = 0x0400, /* Enable downconverter shutdown */ + MT2063_VGA_SD = 0x0200, /* Enable VGA shutdown */ + MT2063_AMP_SD = 0x0100, /* Enable AMP shutdown */ + MT2063_ALL_SD = 0xFF73, /* All shutdown bits for this tuner */ + MT2063_NONE_SD = 0x0000 /* No shutdown bits */ +}; + +/* +** Parameter for function MT2063_GetParam & MT2063_SetParam that +** specifies the tuning algorithm parameter to be read/written. +*/ +enum MT2063_Param { + /* tuner address set by MT2063_Open() */ + MT2063_IC_ADDR, + + /* max number of MT2063 tuners set by MT_TUNER_CNT in mt_userdef.h */ + MT2063_MAX_OPEN, + + /* current number of open MT2063 tuners set by MT2063_Open() */ + MT2063_NUM_OPEN, + + /* crystal frequency (default: 16000000 Hz) */ + MT2063_SRO_FREQ, + + /* min tuning step size (default: 50000 Hz) */ + MT2063_STEPSIZE, + + /* input center frequency set by MT2063_Tune() */ + MT2063_INPUT_FREQ, + + /* LO1 Frequency set by MT2063_Tune() */ + MT2063_LO1_FREQ, + + /* LO1 minimum step size (default: 250000 Hz) */ + MT2063_LO1_STEPSIZE, + + /* LO1 FracN keep-out region (default: 999999 Hz) */ + MT2063_LO1_FRACN_AVOID_PARAM, + + /* Current 1st IF in use set by MT2063_Tune() */ + MT2063_IF1_ACTUAL, + + /* Requested 1st IF set by MT2063_Tune() */ + MT2063_IF1_REQUEST, + + /* Center of 1st IF SAW filter (default: 1218000000 Hz) */ + MT2063_IF1_CENTER, + + /* Bandwidth of 1st IF SAW filter (default: 20000000 Hz) */ + MT2063_IF1_BW, + + /* zero-IF bandwidth (default: 2000000 Hz) */ + MT2063_ZIF_BW, + + /* LO2 Frequency set by MT2063_Tune() */ + MT2063_LO2_FREQ, + + /* LO2 minimum step size (default: 50000 Hz) */ + MT2063_LO2_STEPSIZE, + + /* LO2 FracN keep-out region (default: 374999 Hz) */ + MT2063_LO2_FRACN_AVOID, + + /* output center frequency set by MT2063_Tune() */ + MT2063_OUTPUT_FREQ, + + /* output bandwidth set by MT2063_Tune() */ + MT2063_OUTPUT_BW, + + /* min inter-tuner LO separation (default: 1000000 Hz) */ + MT2063_LO_SEPARATION, + + /* ID of avoid-spurs algorithm in use compile-time constant */ + MT2063_AS_ALG, + + /* max # of intra-tuner harmonics (default: 15) */ + MT2063_MAX_HARM1, + + /* max # of inter-tuner harmonics (default: 7) */ + MT2063_MAX_HARM2, + + /* # of 1st IF exclusion zones used set by MT2063_Tune() */ + MT2063_EXCL_ZONES, + + /* # of spurs found/avoided set by MT2063_Tune() */ + MT2063_NUM_SPURS, + + /* >0 spurs avoided set by MT2063_Tune() */ + MT2063_SPUR_AVOIDED, + + /* >0 spurs in output (mathematically) set by MT2063_Tune() */ + MT2063_SPUR_PRESENT, + + /* Receiver Mode for some parameters. 1 is DVB-T */ + MT2063_RCVR_MODE, + + /* directly set LNA attenuation, parameter is value to set */ + MT2063_ACLNA, + + /* maximum LNA attenuation, parameter is value to set */ + MT2063_ACLNA_MAX, + + /* directly set ATN attenuation. Paremeter is value to set. */ + MT2063_ACRF, + + /* maxium ATN attenuation. Paremeter is value to set. */ + MT2063_ACRF_MAX, + + /* directly set FIF attenuation. Paremeter is value to set. */ + MT2063_ACFIF, + + /* maxium FIF attenuation. Paremeter is value to set. */ + MT2063_ACFIF_MAX, + + /* LNA Rin */ + MT2063_LNA_RIN, + + /* Power Detector LNA level target */ + MT2063_LNA_TGT, + + /* Power Detector 1 level */ + MT2063_PD1, + + /* Power Detector 1 level target */ + MT2063_PD1_TGT, + + /* Power Detector 2 level */ + MT2063_PD2, + + /* Power Detector 2 level target */ + MT2063_PD2_TGT, + + /* Selects, which DNC is activ */ + MT2063_DNC_OUTPUT_ENABLE, + + /* VGA gain code */ + MT2063_VGAGC, + + /* VGA bias current */ + MT2063_VGAOI, + + /* TAGC, determins the speed of the AGC */ + MT2063_TAGC, + + /* AMP gain code */ + MT2063_AMPGC, + + /* Control setting to avoid DECT freqs (default: MT_AVOID_BOTH) */ + MT2063_AVOID_DECT, + + /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ + MT2063_CTFILT_SW, + + MT2063_EOP /* last entry in enumerated list */ +}; + +/* +** Parameter for selecting tuner mode +*/ +enum MT2063_RCVR_MODES { + MT2063_CABLE_QAM = 0, /* Digital cable */ + MT2063_CABLE_ANALOG, /* Analog cable */ + MT2063_OFFAIR_COFDM, /* Digital offair */ + MT2063_OFFAIR_COFDM_SAWLESS, /* Digital offair without SAW */ + MT2063_OFFAIR_ANALOG, /* Analog offair */ + MT2063_OFFAIR_8VSB, /* Analog offair */ + MT2063_NUM_RCVR_MODES +}; + +/* +** Possible values for MT2063_DNC_OUTPUT +*/ +enum MT2063_DNC_Output_Enable { + MT2063_DNC_NONE = 0, + MT2063_DNC_1, + MT2063_DNC_2, + MT2063_DNC_BOTH +}; + +/* +** Two-wire serial bus subaddresses of the tuner registers. +** Also known as the tuner's register addresses. +*/ +enum MT2063_Register_Offsets { + MT2063_REG_PART_REV = 0, /* 0x00: Part/Rev Code */ + MT2063_REG_LO1CQ_1, /* 0x01: LO1C Queued Byte 1 */ + MT2063_REG_LO1CQ_2, /* 0x02: LO1C Queued Byte 2 */ + MT2063_REG_LO2CQ_1, /* 0x03: LO2C Queued Byte 1 */ + MT2063_REG_LO2CQ_2, /* 0x04: LO2C Queued Byte 2 */ + MT2063_REG_LO2CQ_3, /* 0x05: LO2C Queued Byte 3 */ + MT2063_REG_RSVD_06, /* 0x06: Reserved */ + MT2063_REG_LO_STATUS, /* 0x07: LO Status */ + MT2063_REG_FIFFC, /* 0x08: FIFF Center */ + MT2063_REG_CLEARTUNE, /* 0x09: ClearTune Filter */ + MT2063_REG_ADC_OUT, /* 0x0A: ADC_OUT */ + MT2063_REG_LO1C_1, /* 0x0B: LO1C Byte 1 */ + MT2063_REG_LO1C_2, /* 0x0C: LO1C Byte 2 */ + MT2063_REG_LO2C_1, /* 0x0D: LO2C Byte 1 */ + MT2063_REG_LO2C_2, /* 0x0E: LO2C Byte 2 */ + MT2063_REG_LO2C_3, /* 0x0F: LO2C Byte 3 */ + MT2063_REG_RSVD_10, /* 0x10: Reserved */ + MT2063_REG_PWR_1, /* 0x11: PWR Byte 1 */ + MT2063_REG_PWR_2, /* 0x12: PWR Byte 2 */ + MT2063_REG_TEMP_STATUS, /* 0x13: Temp Status */ + MT2063_REG_XO_STATUS, /* 0x14: Crystal Status */ + MT2063_REG_RF_STATUS, /* 0x15: RF Attn Status */ + MT2063_REG_FIF_STATUS, /* 0x16: FIF Attn Status */ + MT2063_REG_LNA_OV, /* 0x17: LNA Attn Override */ + MT2063_REG_RF_OV, /* 0x18: RF Attn Override */ + MT2063_REG_FIF_OV, /* 0x19: FIF Attn Override */ + MT2063_REG_LNA_TGT, /* 0x1A: Reserved */ + MT2063_REG_PD1_TGT, /* 0x1B: Pwr Det 1 Target */ + MT2063_REG_PD2_TGT, /* 0x1C: Pwr Det 2 Target */ + MT2063_REG_RSVD_1D, /* 0x1D: Reserved */ + MT2063_REG_RSVD_1E, /* 0x1E: Reserved */ + MT2063_REG_RSVD_1F, /* 0x1F: Reserved */ + MT2063_REG_RSVD_20, /* 0x20: Reserved */ + MT2063_REG_BYP_CTRL, /* 0x21: Bypass Control */ + MT2063_REG_RSVD_22, /* 0x22: Reserved */ + MT2063_REG_RSVD_23, /* 0x23: Reserved */ + MT2063_REG_RSVD_24, /* 0x24: Reserved */ + MT2063_REG_RSVD_25, /* 0x25: Reserved */ + MT2063_REG_RSVD_26, /* 0x26: Reserved */ + MT2063_REG_RSVD_27, /* 0x27: Reserved */ + MT2063_REG_FIFF_CTRL, /* 0x28: FIFF Control */ + MT2063_REG_FIFF_OFFSET, /* 0x29: FIFF Offset */ + MT2063_REG_CTUNE_CTRL, /* 0x2A: Reserved */ + MT2063_REG_CTUNE_OV, /* 0x2B: Reserved */ + MT2063_REG_CTRL_2C, /* 0x2C: Reserved */ + MT2063_REG_FIFF_CTRL2, /* 0x2D: Fiff Control */ + MT2063_REG_RSVD_2E, /* 0x2E: Reserved */ + MT2063_REG_DNC_GAIN, /* 0x2F: DNC Control */ + MT2063_REG_VGA_GAIN, /* 0x30: VGA Gain Ctrl */ + MT2063_REG_RSVD_31, /* 0x31: Reserved */ + MT2063_REG_TEMP_SEL, /* 0x32: Temperature Selection */ + MT2063_REG_RSVD_33, /* 0x33: Reserved */ + MT2063_REG_RSVD_34, /* 0x34: Reserved */ + MT2063_REG_RSVD_35, /* 0x35: Reserved */ + MT2063_REG_RSVD_36, /* 0x36: Reserved */ + MT2063_REG_RSVD_37, /* 0x37: Reserved */ + MT2063_REG_RSVD_38, /* 0x38: Reserved */ + MT2063_REG_RSVD_39, /* 0x39: Reserved */ + MT2063_REG_RSVD_3A, /* 0x3A: Reserved */ + MT2063_REG_RSVD_3B, /* 0x3B: Reserved */ + MT2063_REG_RSVD_3C, /* 0x3C: Reserved */ + MT2063_REG_END_REGS +}; + +struct MT2063_Info_t { + Handle_t handle; + Handle_t hUserData; + UData_t address; + UData_t version; + UData_t tuner_id; + struct MT2063_AvoidSpursData_t AS_Data; + UData_t f_IF1_actual; + UData_t rcvr_mode; + UData_t ctfilt_sw; + UData_t CTFiltMax[31]; + UData_t num_regs; + U8Data reg[MT2063_REG_END_REGS]; +}; +typedef struct MT2063_Info_t *pMT2063_Info_t; + +enum MTTune_atv_standard { + MTTUNEA_UNKNOWN = 0, + MTTUNEA_PAL_B, + MTTUNEA_PAL_G, + MTTUNEA_PAL_I, + MTTUNEA_PAL_L, + MTTUNEA_PAL_MN, + MTTUNEA_PAL_DK, + MTTUNEA_DIGITAL, + MTTUNEA_FMRADIO, + MTTUNEA_DVBC, + MTTUNEA_DVBT +}; + +/* ====== Functions which are declared in MT2063.c File ======= */ + +UData_t MT2063_Open(UData_t MT2063_Addr, + Handle_t * hMT2063, Handle_t hUserData); + +UData_t MT2063_Close(Handle_t hMT2063); + +UData_t MT2063_Tune(Handle_t h, UData_t f_in); /* RF input center frequency */ + +UData_t MT2063_GetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id, + enum MT2063_GPIO_Attr attr, UData_t * value); + +UData_t MT2063_GetLocked(Handle_t h); + +UData_t MT2063_GetParam(Handle_t h, enum MT2063_Param param, UData_t * pValue); + +UData_t MT2063_GetReg(Handle_t h, U8Data reg, U8Data * val); + +UData_t MT2063_GetTemp(Handle_t h, enum MT2063_Temperature *value); + +UData_t MT2063_GetUserData(Handle_t h, Handle_t * hUserData); + +UData_t MT2063_ReInit(Handle_t h); + +UData_t MT2063_SetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id, + enum MT2063_GPIO_Attr attr, UData_t value); + +UData_t MT2063_SetParam(Handle_t h, enum MT2063_Param param, UData_t nValue); + +UData_t MT2063_SetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits); + +UData_t MT2063_ClearPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits); + +UData_t MT2063_GetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits *Bits); + +UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled); + +UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown); + +UData_t MT2063_SetExtSRO(Handle_t h, enum MT2063_Ext_SRO Ext_SRO_Setting); + +UData_t MT2063_SetReg(Handle_t h, U8Data reg, U8Data val); + +UData_t MT_Tune_atv(Handle_t h, UData_t f_in, UData_t bw_in, + enum MTTune_atv_standard tv_type); + +struct mt2063_config { + u8 tuner_address; + u32 refclock; +}; + +struct mt2063_state { struct i2c_adapter *i2c; - const struct mt2063_config *config; - struct dvb_tuner_ops ops; - struct dvb_frontend *frontend; - struct tuner_state status; - const struct MT2063_Info_t *MT2063_ht; - enum Bool_t MT2063_init; - - enum MTTune_atv_standard tv_type; + const struct mt2063_config *config; + struct dvb_tuner_ops ops; + struct dvb_frontend *frontend; + struct tuner_state status; + const struct MT2063_Info_t *MT2063_ht; + enum Bool_t MT2063_init; + + enum MTTune_atv_standard tv_type; u32 frequency; u32 srate; u32 bandwidth; u32 reference; -}; - -#if defined(CONFIG_DVB_MT2063) || (defined(CONFIG_DVB_MT2063_MODULE) && defined(MODULE)) +}; -extern struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, - struct mt2063_config *config, - struct i2c_adapter *i2c); +#if defined(CONFIG_DVB_MT2063) || (defined(CONFIG_DVB_MT2063_MODULE) && defined(MODULE)) + +extern struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, + struct mt2063_config *config, + struct i2c_adapter *i2c); #else -static inline struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, - struct mt2063_config *config, - struct i2c_adapter *i2c) +static inline struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, + struct mt2063_config *config, + struct i2c_adapter *i2c) { printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); return NULL; } -#endif //CONFIG_DVB_MT2063 - -#endif //__MT2063_H__ +#endif //CONFIG_DVB_MT2063 + +#endif //__MT2063_H__ diff --git a/drivers/media/common/tuners/mt2063_cfg.h b/drivers/media/common/tuners/mt2063_cfg.h index 2b6bd50eddde..5f80f02ed090 100644 --- a/drivers/media/common/tuners/mt2063_cfg.h +++ b/drivers/media/common/tuners/mt2063_cfg.h @@ -1,37 +1,40 @@ - - -static unsigned int mt2063_setTune(struct dvb_frontend *fe, UData_t f_in,UData_t bw_in, enum MTTune_atv_standard tv_type) + +static unsigned int mt2063_setTune(struct dvb_frontend *fe, UData_t f_in, + UData_t bw_in, + enum MTTune_atv_standard tv_type) { - //return (int)MT_Tune_atv(h, f_in, bw_in, tv_type); - - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - struct tuner_state t_state; - struct mt2063_state *mt2063State = fe->tuner_priv; + //return (int)MT_Tune_atv(h, f_in, bw_in, tv_type); + + struct dvb_frontend_ops *frontend_ops = NULL; + struct dvb_tuner_ops *tuner_ops = NULL; + struct tuner_state t_state; + struct mt2063_state *mt2063State = fe->tuner_priv; int err = 0; - t_state.frequency = f_in; - t_state.bandwidth = bw_in; - mt2063State->tv_type = tv_type; - if (&fe->ops) + t_state.frequency = f_in; + t_state.bandwidth = bw_in; + mt2063State->tv_type = tv_type; + if (&fe->ops) frontend_ops = &fe->ops; if (&frontend_ops->tuner_ops) tuner_ops = &frontend_ops->tuner_ops; if (tuner_ops->set_state) { - if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) { + if ((err = + tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, + &t_state)) < 0) { printk("%s: Invalid parameter\n", __func__); return err; } - } - - return err; -} - -static unsigned int mt2063_lockStatus(struct dvb_frontend *fe) -{ - struct dvb_frontend_ops *frontend_ops = &fe->ops; - struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; + } + + return err; +} + +static unsigned int mt2063_lockStatus(struct dvb_frontend *fe) +{ + struct dvb_frontend_ops *frontend_ops = &fe->ops; + struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; + struct tuner_state t_state; int err = 0; if (&fe->ops) @@ -39,73 +42,81 @@ static unsigned int mt2063_lockStatus(struct dvb_frontend *fe) if (&frontend_ops->tuner_ops) tuner_ops = &frontend_ops->tuner_ops; if (tuner_ops->get_state) { - if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_REFCLOCK, &t_state)) < 0) { + if ((err = + tuner_ops->get_state(fe, DVBFE_TUNER_REFCLOCK, + &t_state)) < 0) { printk("%s: Invalid parameter\n", __func__); return err; } - } - return err; -} - -static unsigned int tuner_MT2063_Open(struct dvb_frontend *fe) -{ - struct dvb_frontend_ops *frontend_ops = &fe->ops; - struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; - int err = 0; - - if (&fe->ops) + } + return err; +} + +static unsigned int tuner_MT2063_Open(struct dvb_frontend *fe) +{ + struct dvb_frontend_ops *frontend_ops = &fe->ops; + struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; + struct tuner_state t_state; + int err = 0; + + if (&fe->ops) frontend_ops = &fe->ops; if (&frontend_ops->tuner_ops) tuner_ops = &frontend_ops->tuner_ops; if (tuner_ops->set_state) { - if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_OPEN, &t_state)) < 0) { + if ((err = + tuner_ops->set_state(fe, DVBFE_TUNER_OPEN, + &t_state)) < 0) { printk("%s: Invalid parameter\n", __func__); return err; } - } - - return err; -} - -static unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe) -{ - struct dvb_frontend_ops *frontend_ops = &fe->ops; - struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; - int err = 0; - - if (&fe->ops) + } + + return err; +} + +static unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe) +{ + struct dvb_frontend_ops *frontend_ops = &fe->ops; + struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; + struct tuner_state t_state; + int err = 0; + + if (&fe->ops) frontend_ops = &fe->ops; if (&frontend_ops->tuner_ops) tuner_ops = &frontend_ops->tuner_ops; if (tuner_ops->set_state) { - if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_SOFTWARE_SHUTDOWN, &t_state)) < 0) { + if ((err = + tuner_ops->set_state(fe, DVBFE_TUNER_SOFTWARE_SHUTDOWN, + &t_state)) < 0) { printk("%s: Invalid parameter\n", __func__); return err; } - } - - return err; -} - -static unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe) -{ - struct dvb_frontend_ops *frontend_ops = &fe->ops; - struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; - int err = 0; - - if (&fe->ops) + } + + return err; +} + +static unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe) +{ + struct dvb_frontend_ops *frontend_ops = &fe->ops; + struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; + struct tuner_state t_state; + int err = 0; + + if (&fe->ops) frontend_ops = &fe->ops; if (&frontend_ops->tuner_ops) tuner_ops = &frontend_ops->tuner_ops; if (tuner_ops->set_state) { - if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_CLEAR_POWER_MASKBITS, &t_state)) < 0) { + if ((err = + tuner_ops->set_state(fe, DVBFE_TUNER_CLEAR_POWER_MASKBITS, + &t_state)) < 0) { printk("%s: Invalid parameter\n", __func__); return err; } - } - - return err; -} + } + + return err; +}