2011-07-20 19:52:49 -03:00
2011-07-20 19:48:59 -03:00
# include <linux/init.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/string.h>
2011-07-20 19:52:49 -03:00
# include "mt2063.h"
/* Version of this module */
# define MT2063_VERSION 10018 /* Version 01.18 */
2011-07-20 19:48:59 -03:00
static unsigned int verbose ;
2011-07-20 19:52:49 -03:00
module_param ( verbose , int , 0644 ) ;
2011-07-20 20:21:42 -03:00
2011-07-20 21:43:30 -03:00
/* Prototypes */
static void MT2063_AddExclZone ( struct MT2063_AvoidSpursData_t * pAS_Info ,
u32 f_min , u32 f_max ) ;
static u32 MT2063_ReInit ( void * h ) ;
static u32 MT2063_Close ( void * hMT2063 ) ;
static u32 MT2063_GetReg ( void * h , u8 reg , u8 * val ) ;
static u32 MT2063_GetParam ( void * h , enum MT2063_Param param , u32 * pValue ) ;
static u32 MT2063_SetReg ( void * h , u8 reg , u8 val ) ;
static u32 MT2063_SetParam ( void * h , enum MT2063_Param param , u32 nValue ) ;
2011-07-20 20:21:42 -03:00
/*****************/
/* From drivers/media/common/tuners/mt2063_cfg.h */
2011-07-20 22:00:30 -03:00
unsigned int mt2063_setTune ( struct dvb_frontend * fe , u32 f_in ,
2011-07-20 21:01:48 -03:00
u32 bw_in ,
2011-07-20 20:21:42 -03:00
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 ;
int err = 0 ;
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 ) {
printk ( " %s: Invalid parameter \n " , __func__ ) ;
return err ;
}
}
return err ;
}
2011-07-20 22:00:30 -03:00
unsigned int mt2063_lockStatus ( struct dvb_frontend * fe )
2011-07-20 20:21:42 -03:00
{
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 - > get_state ) {
if ( ( err =
tuner_ops - > get_state ( fe , DVBFE_TUNER_REFCLOCK ,
& t_state ) ) < 0 ) {
printk ( " %s: Invalid parameter \n " , __func__ ) ;
return err ;
}
}
return err ;
}
2011-07-20 22:00:30 -03:00
unsigned int tuner_MT2063_Open ( struct dvb_frontend * fe )
2011-07-20 20:21:42 -03:00
{
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 ) {
printk ( " %s: Invalid parameter \n " , __func__ ) ;
return err ;
}
}
return err ;
}
2011-07-20 22:00:30 -03:00
unsigned int tuner_MT2063_SoftwareShutdown ( struct dvb_frontend * fe )
2011-07-20 20:21:42 -03:00
{
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 ) {
printk ( " %s: Invalid parameter \n " , __func__ ) ;
return err ;
}
}
return err ;
}
2011-07-20 22:00:30 -03:00
unsigned int tuner_MT2063_ClearPowerMaskBits ( struct dvb_frontend * fe )
2011-07-20 20:21:42 -03:00
{
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 ) {
printk ( " %s: Invalid parameter \n " , __func__ ) ;
return err ;
}
}
return err ;
}
/*****************/
2011-07-20 19:52:49 -03:00
//i2c operation
static int mt2063_writeregs ( struct mt2063_state * state , u8 reg1 ,
u8 * data , int len )
{
int ret ;
u8 buf [ 60 ] ; /* = { reg1, data }; */
struct i2c_msg msg = {
. addr = state - > config - > tuner_address ,
. flags = 0 ,
. buf = buf ,
. len = len + 1
} ;
msg . buf [ 0 ] = reg1 ;
memcpy ( msg . buf + 1 , data , len ) ;
//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 ) ;
return ret ;
}
static int mt2063_read_regs ( struct mt2063_state * state , u8 reg1 , u8 * b , u8 len )
{
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 }
} ;
//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 <Henry> ======================================
//#################################################################
//=================================================================
/*****************************************************************************
* *
* * 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
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_WriteSub ( void * hUserData ,
2011-07-20 21:01:48 -03:00
u32 addr ,
u8 subAddress , u8 * pData , u32 cnt )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ; /* Status to be returned */
2011-07-20 19:52:49 -03:00
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; */
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ; //I2C bypass drxk3926 close i2c bridge
if ( mt2063_writeregs ( state , subAddress , pData , cnt ) < 0 ) {
status = MT2063_ERROR ;
}
fe - > ops . i2c_gate_ctrl ( fe , 0 ) ; //I2C bypass drxk3926 close i2c bridge
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
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_ReadSub ( void * hUserData ,
2011-07-20 21:01:48 -03:00
u32 addr ,
u8 subAddress , u8 * pData , u32 cnt )
2011-07-20 19:52:49 -03:00
{
/*
* * ToDo : Add code here to implement a serial - bus read
* * operation to the MTxxxx tuner . If successful ,
* * return MT_OK .
*/
/* return status; */
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ; /* Status to be returned */
2011-07-20 19:52:49 -03:00
struct dvb_frontend * fe = hUserData ;
struct mt2063_state * state = fe - > tuner_priv ;
2011-07-20 21:01:48 -03:00
u32 i = 0 ;
2011-07-20 19:52:49 -03:00
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ; //I2C bypass drxk3926 close i2c bridge
for ( i = 0 ; i < cnt ; i + + ) {
if ( mt2063_read_regs ( state , subAddress + i , pData + i , 1 ) < 0 ) {
status = MT2063_ERROR ;
break ;
}
}
fe - > ops . i2c_gate_ctrl ( fe , 0 ) ; //I2C bypass drxk3926 close i2c bridge
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
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 22:00:30 -03:00
static int MT2063_Sleep ( struct dvb_frontend * fe )
2011-07-20 19:52:49 -03:00
{
/*
* * ToDo : Add code here to implement a OS blocking
* * for a period of " nMinDelayTime " milliseconds .
*/
2011-07-20 22:00:30 -03:00
msleep ( 10 ) ;
return 0 ;
2011-07-20 19:52:49 -03:00
}
//end of mt2063_userdef.c
//=================================================================
//#################################################################
//=================================================================
//context of mt2063_spuravoid.c <Henry> ======================================
//#################################################################
//=================================================================
/*****************************************************************************
* *
* * 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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 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 {
2011-07-20 21:01:48 -03:00
s32 min_ ;
s32 max_ ;
2011-07-20 19:52:49 -03:00
} ;
# if MT2063_TUNER_CNT > 1
static struct MT2063_AvoidSpursData_t * TunerList [ MT2063_TUNER_CNT ] ;
2011-07-20 21:01:48 -03:00
static u32 TunerCount = 0 ;
2011-07-20 19:52:49 -03:00
# endif
2011-07-20 21:43:30 -03:00
static u32 MT2063_RegisterTuner ( struct MT2063_AvoidSpursData_t * pAS_Info )
2011-07-20 19:52:49 -03:00
{
# if MT2063_TUNER_CNT == 1
pAS_Info - > nAS_Algorithm = 1 ;
return MT2063_OK ;
# else
2011-07-20 21:01:48 -03:00
u32 index ;
2011-07-20 19:52:49 -03:00
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
}
2011-07-20 21:43:30 -03:00
static void MT2063_UnRegisterTuner ( struct MT2063_AvoidSpursData_t * pAS_Info )
2011-07-20 19:52:49 -03:00
{
2011-07-20 22:00:30 -03:00
# if MT2063_TUNER_CNT > 1
2011-07-20 21:01:48 -03:00
u32 index ;
2011-07-20 19:52:49 -03:00
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 ( ) .
*/
2011-07-20 21:43:30 -03:00
static void MT2063_ResetExclZones ( struct MT2063_AvoidSpursData_t * pAS_Info )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 center ;
2011-07-20 19:52:49 -03:00
# if MT2063_TUNER_CNT > 1
2011-07-20 21:01:48 -03:00
u32 index ;
2011-07-20 19:52:49 -03:00
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 1 st 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 1 st 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
* * 1 st 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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static void MT2063_AddExclZone ( struct MT2063_AvoidSpursData_t * pAS_Info ,
2011-07-20 21:01:48 -03:00
u32 f_min , u32 f_max )
2011-07-20 19:52:49 -03:00
{
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 1 st 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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_ChooseFirstIF ( struct MT2063_AvoidSpursData_t * pAS_Info )
2011-07-20 19:52:49 -03:00
{
/*
* * 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 .
*/
2011-07-20 21:01:48 -03:00
const u32 f_Desired =
2011-07-20 19:52:49 -03:00
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 ;
2011-07-20 21:01:48 -03:00
const u32 f_Step =
2011-07-20 19:52:49 -03:00
( pAS_Info - > f_LO1_Step >
pAS_Info - > f_LO2_Step ) ? pAS_Info - > f_LO1_Step : pAS_Info - >
f_LO2_Step ;
2011-07-20 21:01:48 -03:00
u32 f_Center ;
s32 i ;
s32 j = 0 ;
u32 bDesiredExcluded = 0 ;
u32 bZeroExcluded = 0 ;
s32 tmpMin , tmpMax ;
s32 bestDiff ;
2011-07-20 19:52:49 -03:00
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;
2011-07-20 21:01:48 -03:00
//if (!abs((s32) f_Center - (s32) pAS_Info->f_if1_Center) <= (s32) (f_Step/2))
2011-07-20 19:52:49 -03:00
// return 0;
/* Take MT_ExclZones, center around f_Center and change the resolution to f_Step */
while ( pNode ! = NULL ) {
/* floor function */
tmpMin =
2011-07-20 21:01:48 -03:00
floor ( ( s32 ) ( pNode - > min_ - f_Center ) , ( s32 ) f_Step ) ;
2011-07-20 19:52:49 -03:00
/* ceil function */
tmpMax =
2011-07-20 21:01:48 -03:00
ceil ( ( s32 ) ( pNode - > max_ - f_Center ) , ( s32 ) f_Step ) ;
2011-07-20 19:52:49 -03:00
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);
//if (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 )
2011-07-20 21:01:48 -03:00
return f_Center - ( ( u32 ) ( - bestDiff ) * f_Step ) ;
2011-07-20 19:52:49 -03:00
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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:01:48 -03:00
static u32 MT2063_gcd ( u32 u , u32 v )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 r ;
2011-07-20 19:52:49 -03:00
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
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:01:48 -03:00
static u32 MT2063_umax ( u32 a , u32 b )
2011-07-20 19:52:49 -03:00
{
return ( a > = b ) ? a : b ;
}
# if MT2063_TUNER_CNT > 1
2011-07-20 21:01:48 -03:00
static s32 RoundAwayFromZero ( s32 n , s32 d )
2011-07-20 19:52:49 -03:00
{
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 1 st local oscillator ( LO ) frequency
* * of the tuner whose output we are examining
* * f2 - The 1 st local oscillator ( LO ) frequency
* * of the adjacent tuner
* * fOffset - The 2 nd 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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:01:48 -03:00
static u32 IsSpurInAdjTunerBand ( u32 bIsMyOutput ,
u32 f1 ,
u32 f2 ,
u32 fOffset ,
u32 fIFOut ,
u32 fIFBW ,
u32 fZIFBW ,
u32 nMaxH , u32 * fp , u32 * fm )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 bSpurFound = 0 ;
2011-07-20 19:52:49 -03:00
2011-07-20 21:01:48 -03:00
const u32 fHalf_IFBW = fIFBW / 2 ;
const u32 fHalf_ZIFBW = fZIFBW / 2 ;
2011-07-20 19:52:49 -03:00
/* Calculate a scale factor for all frequencies, so that our
calculations all stay within 31 bits */
2011-07-20 21:01:48 -03:00
const u32 f_Scale =
2011-07-20 19:52:49 -03:00
( ( 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 )
*/
2011-07-20 21:01:48 -03:00
const s32 _f1 = ( s32 ) ( f1 / f_Scale ) ;
const s32 _f2 = ( s32 ) ( f2 / f_Scale ) ;
const s32 _f3 = ( s32 ) ( fOffset / f_Scale ) ;
2011-07-20 19:52:49 -03:00
2011-07-20 21:01:48 -03:00
const s32 c = ( s32 ) ( fIFOut - fHalf_IFBW ) / ( s32 ) f_Scale ;
const s32 d = ( s32 ) ( ( fIFOut + fHalf_IFBW ) / f_Scale ) ;
const s32 f = ( s32 ) ( fHalf_ZIFBW / f_Scale ) ;
2011-07-20 19:52:49 -03:00
2011-07-20 21:01:48 -03:00
s32 ma , mb , mc , md , me , mf ;
2011-07-20 19:52:49 -03:00
2011-07-20 21:01:48 -03:00
s32 fp_ = 0 ;
s32 fm_ = 0 ;
s32 n ;
2011-07-20 19:52:49 -03:00
/*
* * 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 */
2011-07-20 21:01:48 -03:00
for ( n = - ( s32 ) nMaxH ; n < = ( s32 ) nMaxH ; + + n ) {
const s32 nf1 = n * _f1 ;
2011-07-20 19:52:49 -03:00
md = ( _f3 + d - nf1 ) / _f2 ;
/* If # f2 harmonics > nMaxH, then no spurs present */
2011-07-20 21:01:48 -03:00
if ( md < = - ( s32 ) nMaxH )
2011-07-20 19:52:49 -03:00
break ;
ma = ( _f3 - d - nf1 ) / _f2 ;
2011-07-20 21:01:48 -03:00
if ( ( ma = = md ) | | ( ma > = ( s32 ) ( nMaxH ) ) )
2011-07-20 19:52:49 -03:00
continue ;
mc = ( _f3 + c - nf1 ) / _f2 ;
if ( mc ! = md ) {
2011-07-20 21:01:48 -03:00
const s32 m = ( n < 0 ) ? md : mc ;
const s32 fspur = ( nf1 + m * _f2 - _f3 ) ;
const s32 den = ( bIsMyOutput ? n - 1 : n ) ;
2011-07-20 19:52:49 -03:00
if ( den = = 0 ) {
fp_ = ( d - fspur ) * f_Scale ;
fm_ = ( fspur - c ) * f_Scale ;
} else {
fp_ =
2011-07-20 21:01:48 -03:00
( s32 ) RoundAwayFromZero ( ( d - fspur ) *
2011-07-20 19:52:49 -03:00
f_Scale , den ) ;
fm_ =
2011-07-20 21:01:48 -03:00
( s32 ) RoundAwayFromZero ( ( fspur - c ) *
2011-07-20 19:52:49 -03:00
f_Scale , den ) ;
}
2011-07-20 21:01:48 -03:00
if ( ( ( u32 ) abs ( fm_ ) > = f_Scale )
& & ( ( u32 ) abs ( fp_ ) > = f_Scale ) ) {
2011-07-20 19:52:49 -03:00
bSpurFound = 1 ;
break ;
}
}
/* Location of Zero-IF-spur to be checked */
mf = ( _f3 + f - nf1 ) / _f2 ;
me = ( _f3 - f - nf1 ) / _f2 ;
if ( me ! = mf ) {
2011-07-20 21:01:48 -03:00
const s32 m = ( n < 0 ) ? mf : me ;
const s32 fspur = ( nf1 + m * _f2 - _f3 ) ;
const s32 den = ( bIsMyOutput ? n - 1 : n ) ;
2011-07-20 19:52:49 -03:00
if ( den = = 0 ) {
fp_ = ( d - fspur ) * f_Scale ;
fm_ = ( fspur - c ) * f_Scale ;
} else {
fp_ =
2011-07-20 21:01:48 -03:00
( s32 ) RoundAwayFromZero ( ( f - fspur ) *
2011-07-20 19:52:49 -03:00
f_Scale , den ) ;
fm_ =
2011-07-20 21:01:48 -03:00
( s32 ) RoundAwayFromZero ( ( fspur + f ) *
2011-07-20 19:52:49 -03:00
f_Scale , den ) ;
}
2011-07-20 21:01:48 -03:00
if ( ( ( u32 ) abs ( fm_ ) > = f_Scale )
& & ( ( u32 ) abs ( fp_ ) > = f_Scale ) ) {
2011-07-20 19:52:49 -03:00
bSpurFound = 1 ;
break ;
}
}
mb = ( _f3 - c - nf1 ) / _f2 ;
if ( ma ! = mb ) {
2011-07-20 21:01:48 -03:00
const s32 m = ( n < 0 ) ? mb : ma ;
const s32 fspur = ( nf1 + m * _f2 - _f3 ) ;
const s32 den = ( bIsMyOutput ? n - 1 : n ) ;
2011-07-20 19:52:49 -03:00
if ( den = = 0 ) {
fp_ = ( d - fspur ) * f_Scale ;
fm_ = ( fspur - c ) * f_Scale ;
} else {
fp_ =
2011-07-20 21:01:48 -03:00
( s32 ) RoundAwayFromZero ( ( - c - fspur ) *
2011-07-20 19:52:49 -03:00
f_Scale , den ) ;
fm_ =
2011-07-20 21:01:48 -03:00
( s32 ) RoundAwayFromZero ( ( fspur + d ) *
2011-07-20 19:52:49 -03:00
f_Scale , den ) ;
}
2011-07-20 21:01:48 -03:00
if ( ( ( u32 ) abs ( fm_ ) > = f_Scale )
& & ( ( u32 ) abs ( fp_ ) > = f_Scale ) ) {
2011-07-20 19:52:49 -03:00
bSpurFound = 1 ;
break ;
}
}
}
/*
* * Verify that fm & fp are both positive
* * Add one to ensure next 1 st 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
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:01:48 -03:00
static u32 IsSpurInBand ( struct MT2063_AvoidSpursData_t * pAS_Info ,
u32 * fm , u32 * fp )
2011-07-20 19:52:49 -03:00
{
/*
* * Calculate LO frequency settings .
*/
2011-07-20 21:01:48 -03:00
u32 n , n0 ;
const u32 f_LO1 = pAS_Info - > f_LO1 ;
const u32 f_LO2 = pAS_Info - > f_LO2 ;
const u32 d = pAS_Info - > f_out + pAS_Info - > f_out_bw / 2 ;
const u32 c = d - pAS_Info - > f_out_bw ;
const u32 f = pAS_Info - > f_zif_bw / 2 ;
const u32 f_Scale = ( f_LO1 / ( MAX_UDATA / 2 / pAS_Info - > maxH1 ) ) + 1 ;
s32 f_nsLO1 , f_nsLO2 ;
s32 f_Spur ;
u32 ma , mb , mc , md , me , mf ;
u32 lo_gcd , gd_Scale , gc_Scale , gf_Scale , hgds , hgfs , hgcs ;
2011-07-20 19:52:49 -03:00
# if MT2063_TUNER_CNT > 1
2011-07-20 21:01:48 -03:00
u32 index ;
2011-07-20 19:52:49 -03:00
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 ) ;
2011-07-20 21:01:48 -03:00
gd_Scale = MT2063_umax ( ( u32 ) MT2063_gcd ( lo_gcd , d ) , f_Scale ) ;
2011-07-20 19:52:49 -03:00
hgds = gd_Scale / 2 ;
2011-07-20 21:01:48 -03:00
gc_Scale = MT2063_umax ( ( u32 ) MT2063_gcd ( lo_gcd , c ) , f_Scale ) ;
2011-07-20 19:52:49 -03:00
hgcs = gc_Scale / 2 ;
2011-07-20 21:01:48 -03:00
gf_Scale = MT2063_umax ( ( u32 ) MT2063_gcd ( lo_gcd , f ) , f_Scale ) ;
2011-07-20 19:52:49 -03:00
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 ) {
2011-07-20 21:01:48 -03:00
f_nsLO1 = ( s32 ) ( n * ( f_LO1 / gc_Scale ) ) ;
f_nsLO2 = ( s32 ) ( mc * ( f_LO2 / gc_Scale ) ) ;
2011-07-20 19:52:49 -03:00
f_Spur =
( gc_Scale * ( f_nsLO1 - f_nsLO2 ) ) +
n * ( f_LO1 % gc_Scale ) - mc * ( f_LO2 % gc_Scale ) ;
2011-07-20 21:01:48 -03:00
* fp = ( ( f_Spur - ( s32 ) c ) / ( mc - n ) ) + 1 ;
* fm = ( ( ( s32 ) d - f_Spur ) / ( mc - n ) ) + 1 ;
2011-07-20 19:52:49 -03:00
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 ) ;
2011-07-20 21:01:48 -03:00
* fp = ( ( f_Spur + ( s32 ) f ) / ( me - n ) ) + 1 ;
* fm = ( ( ( s32 ) f - f_Spur ) / ( me - n ) ) + 1 ;
2011-07-20 19:52:49 -03:00
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 ) ;
2011-07-20 21:01:48 -03:00
* fp = ( ( ( s32 ) d + f_Spur ) / ( ma - n ) ) + 1 ;
* fm = ( - ( f_Spur + ( s32 ) c ) / ( ma - n ) ) + 1 ;
2011-07-20 19:52:49 -03:00
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.
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_AvoidSpurs ( void * h , struct MT2063_AvoidSpursData_t * pAS_Info )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ;
u32 fm , fp ; /* restricted range on LO's */
2011-07-20 19:52:49 -03:00
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
* * 1 st 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 ) {
2011-07-20 21:01:48 -03:00
u32 zfIF1 = pAS_Info - > f_LO1 - pAS_Info - > f_in ; /* current attempt at a 1st IF */
u32 zfLO1 = pAS_Info - > f_LO1 ; /* current attempt at an LO1 freq */
u32 zfLO2 = pAS_Info - > f_LO2 ; /* current attempt at an LO2 freq */
u32 delta_IF1 ;
u32 new_IF1 ;
2011-07-20 19:52:49 -03:00
/*
* * Spur was found , attempt to find a spur - free 1 st 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 1 st IF is still within the 1 st 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 1 st 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 ) ;
}
//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 */
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
*/
2011-07-20 21:01:48 -03:00
static const u32 MT2063_Num_Registers = MT2063_REG_END_REGS ;
2011-07-20 19:52:49 -03:00
# define USE_GLOBAL_TUNER 0
2011-07-20 21:19:08 -03:00
static u32 nMT2063MaxTuners = 1 ;
2011-07-20 21:01:48 -03:00
static u32 nMT2063OpenTuners = 0 ;
2011-07-20 19:52:49 -03:00
/*
* * 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 |
* * - - - - - - - - - - - - - - + - - - - + - - - - + - - - - + - - - - + - - - - - + - - - - - +
* *
* *
*/
2011-07-20 21:01:48 -03:00
static const u8 RFAGCEN [ ] = { 0 , 0 , 0 , 0 , 0 , 0 } ;
static const u8 LNARIN [ ] = { 0 , 0 , 3 , 3 , 3 , 3 } ;
static const u8 FIFFQEN [ ] = { 1 , 1 , 1 , 1 , 1 , 1 } ;
static const u8 FIFFQ [ ] = { 0 , 0 , 0 , 0 , 0 , 0 } ;
static const u8 DNC1GC [ ] = { 0 , 0 , 0 , 0 , 0 , 0 } ;
static const u8 DNC2GC [ ] = { 0 , 0 , 0 , 0 , 0 , 0 } ;
static const u8 ACLNAMAX [ ] = { 31 , 31 , 31 , 31 , 31 , 31 } ;
static const u8 LNATGT [ ] = { 44 , 43 , 43 , 43 , 43 , 43 } ;
static const u8 RFOVDIS [ ] = { 0 , 0 , 0 , 0 , 0 , 0 } ;
static const u8 ACRFMAX [ ] = { 31 , 31 , 31 , 31 , 31 , 31 } ;
static const u8 PD1TGT [ ] = { 36 , 36 , 38 , 38 , 36 , 38 } ;
static const u8 FIFOVDIS [ ] = { 0 , 0 , 0 , 0 , 0 , 0 } ;
static const u8 ACFIFMAX [ ] = { 29 , 29 , 29 , 29 , 29 , 29 } ;
static const u8 PD2TGT [ ] = { 40 , 33 , 38 , 42 , 30 , 38 } ;
2011-07-20 19:52:49 -03:00
/*
* * Local Function Prototypes - not available for external access .
*/
/* Forward declaration(s): */
2011-07-20 21:01:48 -03:00
static u32 MT2063_CalcLO1Mult ( u32 * Div , u32 * FracN , u32 f_LO ,
u32 f_LO_Step , u32 f_Ref ) ;
static u32 MT2063_CalcLO2Mult ( u32 * Div , u32 * FracN , u32 f_LO ,
u32 f_LO_Step , u32 f_Ref ) ;
static u32 MT2063_fLO_FractionalTerm ( u32 f_ref , u32 num ,
u32 denom ) ;
2011-07-20 19:52:49 -03:00
/******************************************************************************
* *
* * 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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 22:00:30 -03:00
static u32 MT2063_Open ( u32 MT2063_Addr , struct MT2063_Info_t * * hMT2063 , void * hUserData )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ; /* Status to be returned. */
2011-07-20 19:52:49 -03:00
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 */
2011-07-20 21:01:48 -03:00
if ( state - > MT2063_init = = false ) {
2011-07-20 19:52:49 -03:00
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 ;
}
if ( MT2063_NO_ERROR ( status ) ) {
status | = MT2063_RegisterTuner ( & pInfo - > AS_Data ) ;
}
if ( MT2063_NO_ERROR ( status ) ) {
2011-07-20 21:01:48 -03:00
pInfo - > handle = ( void * ) pInfo ;
2011-07-20 19:52:49 -03:00
pInfo - > hUserData = hUserData ;
pInfo - > address = MT2063_Addr ;
pInfo - > rcvr_mode = MT2063_CABLE_QAM ;
2011-07-20 21:01:48 -03:00
status | = MT2063_ReInit ( ( void * ) pInfo ) ;
2011-07-20 19:52:49 -03:00
}
if ( MT2063_IS_ERROR ( status ) )
/* MT2063_Close handles the un-registration of the tuner */
2011-07-20 21:01:48 -03:00
MT2063_Close ( ( void * ) pInfo ) ;
2011-07-20 19:52:49 -03:00
else {
2011-07-20 21:01:48 -03:00
state - > MT2063_init = true ;
2011-07-20 19:52:49 -03:00
* hMT2063 = pInfo - > handle ;
}
return ( status ) ;
}
2011-07-20 21:01:48 -03:00
static u32 MT2063_IsValidHandle ( struct MT2063_Info_t * handle )
2011-07-20 19:52:49 -03:00
{
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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_Close ( void * hMT2063 )
2011-07-20 19:52:49 -03:00
{
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 ;
//kfree(pInfo);
//pInfo = NULL;
2011-07-20 21:19:08 -03:00
2011-07-20 19:52:49 -03:00
return MT2063_OK ;
}
/****************************************************************************
* *
* * 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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_GetLocked ( void * h )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
const u32 nMaxWait = 100 ; /* wait a maximum of 100 msec */
const u32 nPollRate = 2 ; /* poll status bits every 2 ms */
const u32 nMaxLoops = nMaxWait / nPollRate ;
const u8 LO1LK = 0x80 ;
u8 LO2LK = 0x08 ;
u32 status = MT2063_OK ; /* Status to be returned */
u32 nDelays = 0 ;
2011-07-20 19:52:49 -03:00
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 ) ;
}
2011-07-20 21:43:30 -03:00
msleep ( nPollRate ) ; /* Wait between retries */
2011-07-20 19:52:49 -03:00
}
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 1 st IF in use
* * MT2063_IF1_REQUEST Requested 1 st IF
* * MT2063_IF1_CENTER Center of 1 st IF SAW filter
* * MT2063_IF1_BW Bandwidth of 1 st 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 1 st 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
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_GetParam ( void * h , enum MT2063_Param param , u32 * pValue )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ; /* Status to be returned */
2011-07-20 19:52:49 -03:00
struct MT2063_Info_t * pInfo = ( struct MT2063_Info_t * ) h ;
2011-07-20 21:01:48 -03:00
u32 Div ;
u32 Num ;
2011-07-20 19:52:49 -03:00
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 :
{
2011-07-20 21:01:48 -03:00
u8 mask = ( param = = MT2063_PD1 ? 0x01 : 0x03 ) ; /* PD1 vs PD2 */
u8 orig = ( pInfo - > reg [ MT2063_REG_BYP_CTRL ] ) ;
u8 reg = ( orig & 0xF1 ) | mask ; /* Only set 3 bits (not 5) */
2011-07-20 19:52:49 -03:00
int i ;
* pValue = 0 ;
/* Initiate ADC output to reg 0x0A */
if ( reg ! = orig )
status | =
MT2063_WriteSub ( pInfo - > hUserData ,
pInfo - > address ,
MT2063_REG_BYP_CTRL ,
& reg , 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 :
{
2011-07-20 21:01:48 -03:00
u8 val ;
2011-07-20 19:52:49 -03:00
status | =
MT2063_GetReg ( pInfo , MT2063_REG_XO_STATUS ,
& val ) ;
* pValue = val & 0x1f ;
}
break ;
/* Get RF attenuator code */
case MT2063_ACRF :
{
2011-07-20 21:01:48 -03:00
u8 val ;
2011-07-20 19:52:49 -03:00
status | =
MT2063_GetReg ( pInfo , MT2063_REG_RF_STATUS ,
& val ) ;
* pValue = val & 0x1f ;
}
break ;
/* Get FIF attenuator code */
case MT2063_ACFIF :
{
2011-07-20 21:01:48 -03:00
u8 val ;
2011-07-20 19:52:49 -03:00
status | =
MT2063_GetReg ( pInfo , MT2063_REG_FIF_STATUS ,
& val ) ;
* pValue = val & 0x1f ;
}
break ;
/* Get LNA attenuator limit */
case MT2063_ACLNA_MAX :
{
2011-07-20 21:01:48 -03:00
u8 val ;
2011-07-20 19:52:49 -03:00
status | =
MT2063_GetReg ( pInfo , MT2063_REG_LNA_OV ,
& val ) ;
* pValue = val & 0x1f ;
}
break ;
/* Get RF attenuator limit */
case MT2063_ACRF_MAX :
{
2011-07-20 21:01:48 -03:00
u8 val ;
2011-07-20 19:52:49 -03:00
status | =
MT2063_GetReg ( pInfo , MT2063_REG_RF_OV ,
& val ) ;
* pValue = val & 0x1f ;
}
break ;
/* Get FIF attenuator limit */
case MT2063_ACFIF_MAX :
{
2011-07-20 21:01:48 -03:00
u8 val ;
2011-07-20 19:52:49 -03:00
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 =
2011-07-20 21:01:48 -03:00
( u32 ) MT2063_DNC_NONE ;
2011-07-20 19:52:49 -03:00
else
* pValue =
2011-07-20 21:01:48 -03:00
( u32 ) MT2063_DNC_2 ;
2011-07-20 19:52:49 -03:00
} else { /* DNC1 is on */
if ( ( pInfo - > reg [ MT2063_REG_VGA_GAIN ] & 0x03 ) = = 0x03 ) /* if DNC2 is off */
* pValue =
2011-07-20 21:01:48 -03:00
( u32 ) MT2063_DNC_1 ;
2011-07-20 19:52:49 -03:00
else
* pValue =
2011-07-20 21:01:48 -03:00
( u32 ) MT2063_DNC_BOTH ;
2011-07-20 19:52:49 -03:00
}
}
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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_GetReg ( void * h , u8 reg , u8 * val )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ; /* Status to be returned */
2011-07-20 19:52:49 -03:00
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_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
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:01:48 -03:00
static u32 MT2063_SetReceiverMode ( struct MT2063_Info_t * pInfo ,
2011-07-20 19:52:49 -03:00
enum MT2063_RCVR_MODES Mode )
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ; /* Status to be returned */
u8 val ;
u32 longval ;
2011-07-20 19:52:49 -03:00
if ( Mode > = MT2063_NUM_RCVR_MODES )
status = MT2063_ARG_RANGE ;
/* RFAGCen */
if ( MT2063_NO_ERROR ( status ) ) {
val =
( pInfo - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_PD1_TGT ] & ( u8 ) ~ 0x40 ) | ( RFAGCEN [ Mode ]
2011-07-20 19:52:49 -03:00
? 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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_FIFF_CTRL2 ] & ( u8 ) ~ 0xF0 ) |
2011-07-20 19:52:49 -03:00
( 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 =
2011-07-20 21:01:48 -03:00
( pInfo - > reg [ MT2063_REG_FIFF_CTRL ] | ( u8 ) 0x01 ) ;
2011-07-20 19:52:49 -03:00
status | =
MT2063_SetReg ( pInfo , MT2063_REG_FIFF_CTRL , val ) ;
val =
( pInfo - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_FIFF_CTRL ] & ( u8 ) ~ 0x01 ) ;
2011-07-20 19:52:49 -03:00
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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_LNA_TGT ] & ( u8 ) ~ 0x80 ) | ( RFOVDIS [ Mode ]
2011-07-20 19:52:49 -03:00
? 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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_PD1_TGT ] & ( u8 ) ~ 0x80 ) |
2011-07-20 19:52:49 -03:00
( 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 3 B 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
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_ReInit ( void * h )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u8 all_resets = 0xF0 ; /* reset/load bits */
u32 status = MT2063_OK ; /* Status to be returned */
2011-07-20 19:52:49 -03:00
struct MT2063_Info_t * pInfo = ( struct MT2063_Info_t * ) h ;
2011-07-20 22:00:30 -03:00
u8 * def = NULL ;
2011-07-20 19:52:49 -03:00
2011-07-20 21:01:48 -03:00
u8 MT2063B0_defaults [ ] = { /* Reg, Value */
2011-07-20 19:52:49 -03:00
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 */
2011-07-20 21:01:48 -03:00
u8 MT2063B1_defaults [ ] = { /* Reg, Value */
2011-07-20 19:52:49 -03:00
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 */
2011-07-20 21:01:48 -03:00
u8 MT2063B3_defaults [ ] = { /* Reg, Value */
2011-07-20 19:52:49 -03:00
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 ) {
2011-07-20 21:01:48 -03:00
u8 reg = * def + + ;
u8 val = * def + + ;
2011-07-20 19:52:49 -03:00
status | =
MT2063_WriteSub ( pInfo - > hUserData , pInfo - > address , reg , & val ,
1 ) ;
}
/* Wait for FIFF location to complete. */
if ( MT2063_NO_ERROR ( status ) ) {
2011-07-20 21:01:48 -03:00
u32 FCRUN = 1 ;
s32 maxReads = 10 ;
2011-07-20 19:52:49 -03:00
while ( MT2063_NO_ERROR ( status ) & & ( FCRUN ! = 0 )
& & ( maxReads - - > 0 ) ) {
2011-07-20 21:43:30 -03:00
msleep ( 2 ) ;
2011-07-20 19:52:49 -03:00
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 ) *
2011-07-20 21:01:48 -03:00
( ( u32 ) pInfo - > reg [ MT2063_REG_FIFFC ] + 640 ) ;
2011-07-20 19:52:49 -03:00
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 ) ) {
2011-07-20 21:01:48 -03:00
u32 fcu_osc ;
u32 i ;
2011-07-20 19:52:49 -03:00
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_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 1 st 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
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_SetParam ( void * h , enum MT2063_Param param , u32 nValue )
2011-07-20 19:48:59 -03:00
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ; /* Status to be returned */
u8 val = 0 ;
2011-07-20 19:52:49 -03:00
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 */
2011-07-20 21:01:48 -03:00
u8 tempLO2CQ [ 3 ] ;
u8 tempLO2C [ 3 ] ;
u8 tmpOneShot ;
u32 Div , FracN ;
u8 restore = 0 ;
2011-07-20 19:52:49 -03:00
/* 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 ] =
2011-07-20 21:01:48 -03:00
( u8 ) ( Div & 0x00FF ) ;
2011-07-20 19:52:49 -03:00
pInfo - > reg [ MT2063_REG_LO1CQ_2 ] =
2011-07-20 21:01:48 -03:00
( u8 ) ( FracN ) ;
2011-07-20 19:52:49 -03:00
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 */
2011-07-20 21:01:48 -03:00
u8 tempLO1CQ [ 2 ] ;
u8 tempLO1C [ 2 ] ;
u32 Div2 ;
u32 FracN2 ;
u8 tmpOneShot ;
u8 restore = 0 ;
2011-07-20 19:52:49 -03:00
/* 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 ] =
2011-07-20 21:01:48 -03:00
( u8 ) ( ( Div2 < < 1 ) |
2011-07-20 19:52:49 -03:00
( ( FracN2 > > 12 ) & 0x01 ) ) & 0xFF ;
pInfo - > reg [ MT2063_REG_LO2CQ_2 ] =
2011-07-20 21:01:48 -03:00
( u8 ) ( ( FracN2 > > 4 ) & 0xFF ) ;
2011-07-20 19:52:49 -03:00
pInfo - > reg [ MT2063_REG_LO2CQ_3 ] =
2011-07-20 21:01:48 -03:00
( u8 ) ( ( FracN2 & 0x0F ) ) ;
2011-07-20 19:52:49 -03:00
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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_CTRL_2C ] & ( u8 ) ~ 0x03 ) |
2011-07-20 19:52:49 -03:00
( 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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_LNA_TGT ] & ( u8 ) ~ 0x3F ) |
2011-07-20 19:52:49 -03:00
( 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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_PD1_TGT ] & ( u8 ) ~ 0x3F ) |
2011-07-20 19:52:49 -03:00
( 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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_PD2_TGT ] & ( u8 ) ~ 0x3F ) |
2011-07-20 19:52:49 -03:00
( 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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_LNA_OV ] & ( u8 ) ~ 0x1F ) | ( nValue
2011-07-20 19:52:49 -03:00
&
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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_RF_OV ] & ( u8 ) ~ 0x1F ) | ( nValue
2011-07-20 19:52:49 -03:00
&
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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_FIF_OV ] & ( u8 ) ~ 0x1F ) | ( nValue
2011-07-20 19:52:49 -03:00
&
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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_VGA_GAIN ] & ( u8 ) ~ 0x0C ) |
2011-07-20 19:52:49 -03:00
( ( 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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_RSVD_31 ] & ( u8 ) ~ 0x07 ) |
2011-07-20 19:52:49 -03:00
( 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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_RSVD_1E ] & ( u8 ) ~ 0x03 ) |
2011-07-20 19:52:49 -03:00
( 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 - >
2011-07-20 21:01:48 -03:00
reg [ MT2063_REG_TEMP_SEL ] & ( u8 ) ~ 0x03 ) |
2011-07-20 19:52:49 -03:00
( 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 ;
2011-07-20 19:48:59 -03:00
}
2011-07-20 19:52:49 -03:00
}
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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 22:00:30 -03:00
static u32 MT2063_ClearPowerMaskBits ( struct MT2063_Info_t * pInfo , enum MT2063_Mask_Bits Bits )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ; /* Status to be returned */
2011-07-20 19:52:49 -03:00
/* 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 ) {
2011-07-20 21:01:48 -03:00
pInfo - > reg [ MT2063_REG_PWR_2 ] & = ~ ( u8 ) ( Bits > > 8 ) ;
2011-07-20 19:52:49 -03:00
status | =
MT2063_WriteSub ( pInfo - > hUserData , pInfo - > address ,
MT2063_REG_PWR_2 ,
& pInfo - > reg [ MT2063_REG_PWR_2 ] , 1 ) ;
}
if ( ( Bits & 0xFF ) ! = 0 ) {
2011-07-20 21:01:48 -03:00
pInfo - > reg [ MT2063_REG_PWR_1 ] & = ~ ( u8 ) ( Bits & 0xFF ) ;
2011-07-20 19:52:49 -03:00
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
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 22:00:30 -03:00
static u32 MT2063_SoftwareShutdown ( struct MT2063_Info_t * pInfo , u8 Shutdown )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ; /* Status to be returned */
2011-07-20 19:52:49 -03:00
/* 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_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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_SetReg ( void * h , u8 reg , u8 val )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ; /* Status to be returned */
2011-07-20 19:52:49 -03:00
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 ) ;
}
2011-07-20 21:01:48 -03:00
static u32 MT2063_Round_fLO ( u32 f_LO , u32 f_LO_Step , u32 f_ref )
2011-07-20 19:52:49 -03:00
{
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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:01:48 -03:00
static u32 MT2063_fLO_FractionalTerm ( u32 f_ref ,
u32 num , u32 denom )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 t1 = ( f_ref > > 14 ) * num ;
u32 term1 = t1 / denom ;
u32 loss = t1 % denom ;
u32 term2 =
2011-07-20 19:52:49 -03:00
( ( ( 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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:01:48 -03:00
static u32 MT2063_CalcLO1Mult ( u32 * Div ,
u32 * FracN ,
u32 f_LO ,
u32 f_LO_Step , u32 f_Ref )
2011-07-20 19:52:49 -03:00
{
/* 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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:01:48 -03:00
static u32 MT2063_CalcLO2Mult ( u32 * Div ,
u32 * FracN ,
u32 f_LO ,
u32 f_LO_Step , u32 f_Ref )
2011-07-20 19:52:49 -03:00
{
/* 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 .
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:01:48 -03:00
static u32 FindClearTuneFilter ( struct MT2063_Info_t * pInfo , u32 f_in )
2011-07-20 19:52:49 -03:00
{
2011-07-20 21:01:48 -03:00
u32 RFBand ;
u32 idx ; /* index loop */
2011-07-20 19:52:49 -03:00
/*
* * 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
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-20 21:43:30 -03:00
static u32 MT2063_Tune ( void * h , u32 f_in )
2011-07-20 19:52:49 -03:00
{ /* RF input center frequency */
struct MT2063_Info_t * pInfo = ( struct MT2063_Info_t * ) h ;
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ; /* status of operation */
u32 LO1 ; /* 1st LO register value */
u32 Num1 ; /* Numerator for LO1 reg. value */
u32 f_IF1 ; /* 1st IF requested */
u32 LO2 ; /* 2nd LO register value */
u32 Num2 ; /* Numerator for LO2 reg. value */
u32 ofLO1 , ofLO2 ; /* last time's LO frequencies */
u32 ofin , ofout ; /* last time's I/O frequencies */
u8 fiffc = 0x80 ; /* FIFF center freq from tuner */
u32 fiffof ; /* Offset from FIFF center freq */
const u8 LO1LK = 0x80 ; /* Mask for LO1 Lock bit */
u8 LO2LK = 0x08 ; /* Mask for LO2 Lock bit */
u8 val ;
u32 RFBand ;
2011-07-20 19:52:49 -03:00
/* 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 ] =
2011-07-20 21:01:48 -03:00
( u8 ) ( ( pInfo - > reg [ MT2063_REG_CTUNE_OV ] & ~ 0x1F )
2011-07-20 19:52:49 -03:00
| 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 -
2011-07-20 21:01:48 -03:00
f_in ) / ( pInfo - > AS_Data . f_ref / 64 ) - 8 * ( u32 ) fiffc -
2011-07-20 19:52:49 -03:00
4992 ;
if ( fiffof > 0xFF )
fiffof = 0xFF ;
/*
* * Place all of the calculated values into the local tuner
* * register fields .
*/
if ( MT2063_NO_ERROR ( status ) ) {
2011-07-20 21:01:48 -03:00
pInfo - > reg [ MT2063_REG_LO1CQ_1 ] = ( u8 ) ( LO1 & 0xFF ) ; /* DIV1q */
pInfo - > reg [ MT2063_REG_LO1CQ_2 ] = ( u8 ) ( Num1 & 0x3F ) ; /* NUM1q */
pInfo - > reg [ MT2063_REG_LO2CQ_1 ] = ( u8 ) ( ( ( LO2 & 0x7F ) < < 1 ) /* DIV2q */
2011-07-20 19:52:49 -03:00
| ( Num2 > > 12 ) ) ; /* NUM2q (hi) */
2011-07-20 21:01:48 -03:00
pInfo - > reg [ MT2063_REG_LO2CQ_2 ] = ( u8 ) ( ( Num2 & 0x0FF0 ) > > 4 ) ; /* NUM2q (mid) */
pInfo - > reg [ MT2063_REG_LO2CQ_3 ] = ( u8 ) ( 0xE0 | ( Num2 & 0x000F ) ) ; /* NUM2q (lo) */
2011-07-20 19:52:49 -03:00
/*
* * 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 ] ! =
2011-07-20 21:01:48 -03:00
( u8 ) fiffof ) {
2011-07-20 19:52:49 -03:00
pInfo - > reg [ MT2063_REG_FIFF_OFFSET ] =
2011-07-20 21:01:48 -03:00
( u8 ) fiffof ;
2011-07-20 19:52:49 -03:00
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 ) ;
}
2011-07-20 21:43:30 -03:00
static u32 MT_Tune_atv ( void * h , u32 f_in , u32 bw_in ,
2011-07-20 19:52:49 -03:00
enum MTTune_atv_standard tv_type )
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ;
2011-07-20 19:52:49 -03:00
2011-07-20 21:01:48 -03:00
s32 pict_car = 0 ;
s32 pict2chanb_vsb = 0 ;
s32 pict2chanb_snd = 0 ;
s32 pict2snd1 = 0 ;
s32 pict2snd2 = 0 ;
s32 ch_bw = 0 ;
2011-07-20 19:52:49 -03:00
2011-07-20 21:01:48 -03:00
s32 if_mid = 0 ;
s32 rcvr_mode = 0 ;
u32 mode_get = 0 ;
2011-07-20 19:52:49 -03:00
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 ) ;
2011-07-20 21:01:48 -03:00
return ( u32 ) status ;
2011-07-20 19:52:49 -03:00
}
static int mt2063_init ( struct dvb_frontend * fe )
{
2011-07-20 21:01:48 -03:00
u32 status = MT2063_ERROR ;
2011-07-20 19:52:49 -03:00
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_get_status ( struct dvb_frontend * fe , u32 * status )
2011-07-20 19:48:59 -03:00
{
2011-07-20 19:52:49 -03:00
int rc = 0 ;
//get tuner lock status
return rc ;
2011-07-20 19:48:59 -03:00
}
2011-07-20 19:52:49 -03:00
static int mt2063_get_state ( struct dvb_frontend * fe ,
enum tuner_param param , struct tuner_state * state )
{
struct mt2063_state * mt2063State = fe - > tuner_priv ;
2011-07-20 19:48:59 -03:00
switch ( param ) {
case DVBFE_TUNER_FREQUENCY :
2011-07-20 19:52:49 -03:00
//get frequency
2011-07-20 19:48:59 -03:00
break ;
case DVBFE_TUNER_TUNERSTEP :
break ;
case DVBFE_TUNER_IFFREQ :
break ;
case DVBFE_TUNER_BANDWIDTH :
2011-07-20 19:52:49 -03:00
//get bandwidth
2011-07-20 19:48:59 -03:00
break ;
2011-07-20 19:52:49 -03:00
case DVBFE_TUNER_REFCLOCK :
state - > refclock =
2011-07-20 21:01:48 -03:00
( u32 )
MT2063_GetLocked ( ( void * ) ( mt2063State - > MT2063_ht ) ) ;
2011-07-20 19:48:59 -03:00
break ;
default :
break ;
}
2011-07-20 19:52:49 -03:00
return ( int ) state - > refclock ;
}
static int mt2063_set_state ( struct dvb_frontend * fe ,
enum tuner_param param , struct tuner_state * state )
2011-07-20 19:48:59 -03:00
{
2011-07-20 19:52:49 -03:00
struct mt2063_state * mt2063State = fe - > tuner_priv ;
2011-07-20 21:01:48 -03:00
u32 status = MT2063_OK ;
2011-07-20 19:52:49 -03:00
2011-07-20 19:48:59 -03:00
switch ( param ) {
case DVBFE_TUNER_FREQUENCY :
2011-07-20 19:52:49 -03:00
//set frequency
status =
2011-07-20 21:01:48 -03:00
MT_Tune_atv ( ( void * ) ( mt2063State - > MT2063_ht ) ,
2011-07-20 19:52:49 -03:00
state - > frequency , state - > bandwidth ,
mt2063State - > tv_type ) ;
mt2063State - > frequency = state - > frequency ;
2011-07-20 19:48:59 -03:00
break ;
case DVBFE_TUNER_TUNERSTEP :
break ;
case DVBFE_TUNER_IFFREQ :
break ;
case DVBFE_TUNER_BANDWIDTH :
2011-07-20 19:52:49 -03:00
//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 ) ;
2011-07-20 19:48:59 -03:00
break ;
default :
break ;
}
2011-07-20 19:52:49 -03:00
return ( int ) status ;
}
static int mt2063_release ( struct dvb_frontend * fe )
2011-07-20 19:48:59 -03:00
{
2011-07-20 19:52:49 -03:00
struct mt2063_state * state = fe - > tuner_priv ;
2011-07-20 19:48:59 -03:00
fe - > tuner_priv = NULL ;
kfree ( state ) ;
return 0 ;
2011-07-20 19:52:49 -03:00
}
static struct dvb_tuner_ops mt2063_ops = {
2011-07-20 19:48:59 -03:00
. info = {
2011-07-20 19:52:49 -03:00
. name = " MT2063 Silicon Tuner " ,
. frequency_min = 45000000 ,
. frequency_max = 850000000 ,
. frequency_step = 0 ,
} ,
. init = mt2063_init ,
2011-07-20 21:43:30 -03:00
. sleep = MT2063_Sleep ,
2011-07-20 19:52:49 -03:00
. get_status = mt2063_get_status ,
. get_state = mt2063_get_state ,
. set_state = mt2063_set_state ,
. release = mt2063_release
2011-07-20 19:48:59 -03:00
} ;
2011-07-20 19:52:49 -03:00
struct dvb_frontend * mt2063_attach ( struct dvb_frontend * fe ,
struct mt2063_config * config ,
struct i2c_adapter * i2c )
2011-07-20 19:48:59 -03:00
{
2011-07-20 19:52:49 -03:00
struct mt2063_state * state = NULL ;
2011-07-20 19:48:59 -03:00
2011-07-20 19:52:49 -03:00
state = kzalloc ( sizeof ( struct mt2063_state ) , GFP_KERNEL ) ;
2011-07-20 19:48:59 -03:00
if ( state = = NULL )
goto error ;
2011-07-20 19:52:49 -03:00
state - > config = config ;
state - > i2c = i2c ;
state - > frontend = fe ;
state - > reference = config - > refclock / 1000 ; /* kHz */
2011-07-20 21:01:48 -03:00
state - > MT2063_init = false ;
2011-07-20 19:52:49 -03:00
fe - > tuner_priv = state ;
fe - > ops . tuner_ops = mt2063_ops ;
2011-07-20 19:48:59 -03:00
2011-07-20 19:52:49 -03:00
printk ( " %s: Attaching MT2063 \n " , __func__ ) ;
2011-07-20 19:48:59 -03:00
return fe ;
error :
kfree ( state ) ;
return NULL ;
}
2011-07-20 19:52:49 -03:00
EXPORT_SYMBOL ( mt2063_attach ) ;
2011-07-20 19:48:59 -03:00
MODULE_PARM_DESC ( verbose , " Set Verbosity level " ) ;
2011-07-20 19:52:49 -03:00
MODULE_AUTHOR ( " Henry " ) ;
MODULE_DESCRIPTION ( " MT2063 Silicon tuner " ) ;
MODULE_LICENSE ( " GPL " ) ;