090730_RTL2832U_LINUX_Ver1.1.patch: imported rar archive into v4l-dvb tree
authorTomas Zeman <tzeman@volny.cz>
Wed, 27 Oct 2010 09:27:24 +0200
changeset 2 f5f9afd6ded8
parent 1 7546f67b14aa
child 3 03e1009276b5
090730_RTL2832U_LINUX_Ver1.1.patch: imported rar archive into v4l-dvb tree
090730_RTL2832U_LINUX_Ver1.1.patch
series
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/090730_RTL2832U_LINUX_Ver1.1.patch	Wed Oct 27 09:27:24 2010 +0200
@@ -0,0 +1,27536 @@
+# HG changeset patch
+# Parent abd3aac6644e1a31020f4cdfdee84bde7ca1e1b4
+Import of 090730_RTL2832U_LINUX_Ver1.1.rar into ./linux/drivers/media/dvb/dvb-usb/
+
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/demod_rtl2832.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/demod_rtl2832.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,2828 @@
++/**
++
++@file
++
++@brief   RTL2832 demod module definition
++
++One can manipulate RTL2832 demod through RTL2832 module.
++RTL2832 module is derived from DVB-T demod module.
++
++*/
++
++
++#include "demod_rtl2832.h"
++
++
++
++
++
++/**
++
++@brief   RTL2832 demod module builder
++
++Use BuildRtl2832Module() to build RTL2832 module, set all module function pointers with the corresponding
++functions, and initialize module private variables.
++
++
++@param [in]   ppDemod                      Pointer to RTL2832 demod module pointer
++@param [in]   pDvbtDemodModuleMemory       Pointer to an allocated DVB-T demod module memory
++@param [in]   pRtl2832ExtraModuleMemory    Pointer to an allocated RTL2832 extra module memory
++@param [in]   pBaseInterfaceModuleMemory   Pointer to an allocated base interface module memory
++@param [in]   pI2cBridgeModuleMemory       Pointer to an allocated I2C bridge module memory
++@param [in]   DeviceAddr                   RTL2832 I2C device address
++@param [in]   CrystalFreqHz                RTL2832 crystal frequency in Hz
++@param [in]   AppMode                      RTL2832 application mode for setting
++@param [in]   UpdateFuncRefPeriodMs        RTL2832 update function reference period in millisecond for setting
++@param [in]   IsFunc1Enabled               RTL2832 Function 1 enabling status for setting
++
++
++@note
++	-# One should call BuildRtl2832Module() to build RTL2832 module before using it.
++
++*/
++void
++BuildRtl2832Module(
++	DVBT_DEMOD_MODULE **ppDemod,
++	DVBT_DEMOD_MODULE *pDvbtDemodModuleMemory,
++	RTL2832_EXTRA_MODULE *pRtl2832ExtraModuleMemory,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory,
++	unsigned char DeviceAddr,
++	unsigned long CrystalFreqHz,
++	int AppMode,
++	unsigned long UpdateFuncRefPeriodMs,
++	int IsFunc1Enabled
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	RTL2832_EXTRA_MODULE *pExtra;
++
++
++
++	// Set demod module pointer, 
++	*ppDemod = pDvbtDemodModuleMemory;
++
++	// Get demod module.
++	pDemod = *ppDemod;
++
++	// Set demod extra module pointer, base interface module pointer, and I2C bridge module pointer.
++	pDemod->pExtra         = pRtl2832ExtraModuleMemory;
++	pDemod->pBaseInterface = pBaseInterfaceModuleMemory;
++	pDemod->pI2cBridge     = pI2cBridgeModuleMemory;
++
++	// Get demod extra module.
++	pExtra = (RTL2832_EXTRA_MODULE *)pDemod->pExtra;
++
++
++	// Set demod type.
++	pDemod->DemodType = DVBT_DEMOD_TYPE_RTL2832;
++
++	// Set demod I2C device address.
++	pDemod->DeviceAddr = DeviceAddr;
++
++	// Set demod crystal frequency in Hz.
++	pDemod->CrystalFreqHz = CrystalFreqHz;
++
++
++	// Initialize demod parameter setting status
++	pDemod->IsBandwidthModeSet = NO;
++	pDemod->IsIfFreqHzSet      = NO;
++	pDemod->IsSpectrumModeSet  = NO;
++
++
++	// Initialize demod register table.
++	rtl2832_InitRegTable(pDemod);
++
++	
++	// Set I2C bridge demod arguments.
++	rtl2832_SetI2cBridgeModuleDemodArg(pDemod);
++
++
++	// Set demod module I2C function pointers with default functions.
++	pDemod->SetRegPage         = dvbt_demod_default_SetRegPage;
++	pDemod->SetRegBytes        = dvbt_demod_default_SetRegBytes;
++	pDemod->GetRegBytes        = dvbt_demod_default_GetRegBytes;
++	pDemod->SetRegMaskBits     = dvbt_demod_default_SetRegMaskBits;
++	pDemod->GetRegMaskBits     = dvbt_demod_default_GetRegMaskBits;
++	pDemod->SetRegBits         = dvbt_demod_default_SetRegBits;
++	pDemod->GetRegBits         = dvbt_demod_default_GetRegBits;
++	pDemod->SetRegBitsWithPage = dvbt_demod_default_SetRegBitsWithPage;
++	pDemod->GetRegBitsWithPage = dvbt_demod_default_GetRegBitsWithPage;
++
++
++	// Set demod module manipulating function pointers with default functions.
++	pDemod->GetDemodType     = dvbt_demod_default_GetDemodType;
++	pDemod->GetDeviceAddr    = dvbt_demod_default_GetDeviceAddr;
++	pDemod->GetCrystalFreqHz = dvbt_demod_default_GetCrystalFreqHz;
++
++	pDemod->GetBandwidthMode = dvbt_demod_default_GetBandwidthMode;
++	pDemod->GetIfFreqHz      = dvbt_demod_default_GetIfFreqHz;
++	pDemod->GetSpectrumMode  = dvbt_demod_default_GetSpectrumMode;
++
++
++	// Set demod module manipulating function pointers with particular functions.
++	pDemod->IsConnectedToI2c  = rtl2832_IsConnectedToI2c;
++	pDemod->SoftwareReset     = rtl2832_SoftwareReset;
++	pDemod->Initialize        = rtl2832_Initialize;
++	pDemod->SetBandwidthMode  = rtl2832_SetBandwidthMode;
++	pDemod->SetIfFreqHz       = rtl2832_SetIfFreqHz;
++	pDemod->SetSpectrumMode   = rtl2832_SetSpectrumMode;
++
++	pDemod->IsTpsLocked       = rtl2832_IsTpsLocked;
++	pDemod->IsSignalLocked    = rtl2832_IsSignalLocked;
++
++	pDemod->GetSignalStrength = rtl2832_GetSignalStrength;
++	pDemod->GetSignalQuality  = rtl2832_GetSignalQuality;
++
++	pDemod->GetBer            = rtl2832_GetBer;
++	pDemod->GetSnrDb          = rtl2832_GetSnrDb;
++
++	pDemod->GetRfAgc          = rtl2832_GetRfAgc;
++	pDemod->GetIfAgc          = rtl2832_GetIfAgc;
++	pDemod->GetDiAgc          = rtl2832_GetDiAgc;
++
++	pDemod->GetTrOffsetPpm    = rtl2832_GetTrOffsetPpm;
++	pDemod->GetCrOffsetHz     = rtl2832_GetCrOffsetHz;
++
++	pDemod->GetConstellation  = rtl2832_GetConstellation;
++	pDemod->GetHierarchy      = rtl2832_GetHierarchy;
++	pDemod->GetCodeRateLp     = rtl2832_GetCodeRateLp;
++	pDemod->GetCodeRateHp     = rtl2832_GetCodeRateHp;
++	pDemod->GetGuardInterval  = rtl2832_GetGuardInterval;
++	pDemod->GetFftMode        = rtl2832_GetFftMode;
++
++	pDemod->UpdateFunction    = rtl2832_UpdateFunction;
++	pDemod->ResetFunction     = rtl2832_ResetFunction;
++
++
++	// Initialize demod extra module variables.
++	pExtra->AppMode = AppMode;
++
++
++	// Initialize demod Function 1 variables.
++	pExtra->Func1State = RTL2832_FUNC1_STATE_NORMAL;
++
++	pExtra->IsFunc1Enabled = IsFunc1Enabled;
++
++	pExtra->Func1WaitTimeMax        = DivideWithCeiling(RTL2832_FUNC1_WAIT_TIME_MS, UpdateFuncRefPeriodMs);
++	pExtra->Func1GettingTimeMax     = DivideWithCeiling(RTL2832_FUNC1_GETTING_TIME_MS, UpdateFuncRefPeriodMs);
++	pExtra->Func1GettingNumEachTime = DivideWithCeiling(RTL2832_FUNC1_GETTING_NUM_MIN, pExtra->Func1GettingTimeMax + 1);
++
++	pExtra->Func1QamBak  = 0xff;
++	pExtra->Func1HierBak = 0xff;
++	pExtra->Func1LpCrBak = 0xff;
++	pExtra->Func1HpCrBak = 0xff;
++	pExtra->Func1GiBak   = 0xff;
++	pExtra->Func1FftBak  = 0xff;
++
++
++	// Set demod extra module function pointers.
++	pExtra->GetAppMode = rtl2832_GetAppMode;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C
++
++*/
++void
++rtl2832_IsConnectedToI2c(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAnswer
++	)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	unsigned char Nothing;
++
++
++
++	// Get base interface.
++	pBaseInterface = pDemod->pBaseInterface;
++
++
++	// Send read command.
++	// Note: The number of reading bytes must be greater than 0.
++	if(pBaseInterface->I2cRead(pBaseInterface, pDemod->DeviceAddr, &Nothing, LEN_1_BYTE) == FUNCTION_ERROR)
++		goto error_status_i2c_read;
++
++
++	// Set I2cConnectionStatus with YES.
++	*pAnswer = YES;
++
++
++	return;
++
++
++error_status_i2c_read:
++
++	// Set I2cConnectionStatus with NO.
++	*pAnswer = NO;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_SOFTWARE_RESET
++
++*/
++int
++rtl2832_SoftwareReset(
++	DVBT_DEMOD_MODULE *pDemod
++	)
++{
++	// Set SOFT_RST with 1. Then, set SOFT_RST with 0.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SOFT_RST, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SOFT_RST, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_INITIALIZE
++
++*/
++int
++rtl2832_Initialize(
++	DVBT_DEMOD_MODULE *pDemod
++	)
++{
++	// Initializing table entry only used in Initialize()
++	typedef struct
++	{
++		int RegBitName;
++		unsigned long WritingValue;
++	}
++	INIT_TABLE_ENTRY;
++
++	// Initializing table entry with mode only used in Initialize()
++	typedef struct
++	{
++		int RegBitName;
++		unsigned long WritingValue[RTL2832_APPLICATION_MODE_NUM];
++	}
++	INIT_TABLE_ENTRY_WITH_MODE;
++
++
++
++	static const INIT_TABLE_ENTRY InitTable[RTL2832_INIT_TABLE_LEN] =
++	{
++		// RegBitName,				WritingValue
++		{DVBT_AD_EN_REG,			0x1		},
++		{DVBT_AD_EN_REG1,			0x1		},
++		{DVBT_RSD_BER_FAIL_VAL,		0x2800	},
++		{DVBT_MGD_THD0,				0x10	},
++		{DVBT_MGD_THD1,				0x20	},
++		{DVBT_MGD_THD2,				0x20	},
++		{DVBT_MGD_THD3,				0x40	},
++		{DVBT_MGD_THD4,				0x22	},
++		{DVBT_MGD_THD5,				0x32	},
++		{DVBT_MGD_THD6,				0x37	},
++		{DVBT_MGD_THD7,				0x39	},
++		{DVBT_EN_BK_TRK,			0x0		},
++		{DVBT_EN_CACQ_NOTCH,		0x0		},
++		{DVBT_AD_AV_REF,			0x2a	},
++		{DVBT_REG_PI,				0x3		},
++		{DVBT_PIP_ON,				0x0		},
++		{DVBT_CDIV_PH0,				0x8		},
++		{DVBT_CDIV_PH1,				0x8		},
++		{DVBT_SCALE1_B92,			0x4		},
++		{DVBT_SCALE1_B93,			0xb0	},
++		{DVBT_SCALE1_BA7,			0x78	},
++		{DVBT_SCALE1_BA9,			0x28	},
++		{DVBT_SCALE1_BAA,			0x59	},
++		{DVBT_SCALE1_BAB,			0x83	},
++		{DVBT_SCALE1_BAC,			0xd4	},
++		{DVBT_SCALE1_BB0,			0x65	},
++		{DVBT_SCALE1_BB1,			0x43	},
++		{DVBT_KB_P1,				0x1		},
++		{DVBT_KB_P2,				0x4		},
++		{DVBT_KB_P3,				0x7		},
++		{DVBT_K1_CR_STEP12,			0xa		},
++	};
++
++	static const INIT_TABLE_ENTRY_WITH_MODE InitTableWithAppMode[RTL2832_INIT_TABLE_LEN_WITH_APP_MODE] =
++	{
++		// RegBitName,				WritingValue for {Dongle, STB}
++		{DVBT_TRK_KS_P2,			{0x4,	0x4}},
++		{DVBT_TRK_KS_I2,			{0x7,	0x7}},
++		{DVBT_TR_THD_SET2,			{0x6,	0x6}},
++		{DVBT_TRK_KC_I2,			{0x5,	0x6}},
++		{DVBT_CR_THD_SET2,			{0x1,	0x1}},
++	};
++
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	RTL2832_EXTRA_MODULE *pExtra;
++
++	int i;
++
++	int AppMode;
++
++
++
++	// Get base interface and demod extra module.
++	pBaseInterface = pDemod->pBaseInterface;
++	pExtra         = (RTL2832_EXTRA_MODULE *)pDemod->pExtra;
++
++	// Get application mode.
++	pExtra->GetAppMode(pDemod, &AppMode);
++
++
++	// Initialize demod registers according to the initializing table.
++	for(i = 0; i < RTL2832_INIT_TABLE_LEN; i++)
++	{
++		if(pDemod->SetRegBitsWithPage(pDemod, InitTable[i].RegBitName, InitTable[i].WritingValue)
++			!= FUNCTION_SUCCESS)
++			goto error_status_set_registers;
++	}
++
++
++	// Initialize demod registers according to the initializing table with application mode.
++	for(i = 0; i < RTL2832_INIT_TABLE_LEN_WITH_APP_MODE; i++)
++	{
++		if(pDemod->SetRegBitsWithPage(pDemod, InitTableWithAppMode[i].RegBitName,
++			InitTableWithAppMode[i].WritingValue[AppMode]) != FUNCTION_SUCCESS)
++			goto error_status_set_registers;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_SET_BANDWIDTH_MODE
++
++*/
++int
++rtl2832_SetBandwidthMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int BandwidthMode
++	)
++{
++	static const unsigned char HlpfxTable[DVBT_BANDWIDTH_MODE_NUM][RTL2832_H_LPF_X_LEN] =
++	{
++		// H_LPF_X writing value for 6 MHz bandwidth
++		{
++			0xf5,	0xff,	0x15,	0x38,	0x5d,	0x6d,	0x52,	0x07,	0xfa,	0x2f,
++			0x53,	0xf5,	0x3f,	0xca,	0x0b,	0x91,	0xea,	0x30,	0x63,	0xb2,
++			0x13,	0xda,	0x0b,	0xc4,	0x18,	0x7e,	0x16,	0x66,	0x08,	0x67,
++			0x19,	0xe0,
++		},
++
++		// H_LPF_X writing value for 7 MHz bandwidth
++		{
++			0xe7,	0xcc,	0xb5,	0xba,	0xe8,	0x2f,	0x67,	0x61,	0x00,	0xaf,
++			0x86,	0xf2,	0xbf,	0x59,	0x04,	0x11,	0xb6,	0x33,	0xa4,	0x30,
++			0x15,	0x10,	0x0a,	0x42,	0x18,	0xf8,	0x17,	0xd9,	0x07,	0x22,
++			0x19,	0x10,
++		},
++
++		// H_LPF_X writing value for 8 MHz bandwidth
++		{
++			0x09,	0xf6,	0xd2,	0xa7,	0x9a,	0xc9,	0x27,	0x77,	0x06,	0xbf,
++			0xec,	0xf4,	0x4f,	0x0b,	0xfc,	0x01,	0x63,	0x35,	0x54,	0xa7,
++			0x16,	0x66,	0x08,	0xb4,	0x19,	0x6e,	0x19,	0x65,	0x05,	0xc8,
++			0x19,	0xe0,
++		},
++	};
++
++
++	unsigned long CrystalFreqHz;
++
++	long ConstWithBandwidthMode;
++
++	MPI MpiCrystalFreqHz;
++	MPI MpiConst, MpiVar0, MpiVar1, MpiNone;
++
++	unsigned long RsampRatio;
++
++	long CfreqOffRatioInt;
++	unsigned long CfreqOffRatioBinary;
++
++
++
++	// Get demod crystal frequency in Hz.
++	pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz);
++
++
++	// Set H_LPF_X registers with HlpfxTable according to BandwidthMode.
++	if(pDemod->SetRegPage(pDemod, RTL2832_H_LPF_X_PAGE) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	if(pDemod->SetRegBytes(pDemod, RTL2832_H_LPF_X_ADDR, HlpfxTable[BandwidthMode], RTL2832_H_LPF_X_LEN) !=
++		FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Determine constant value with bandwidth mode.
++	switch(BandwidthMode)
++	{
++		default:
++		case DVBT_BANDWIDTH_6MHZ:	ConstWithBandwidthMode = 48000000;		break;
++		case DVBT_BANDWIDTH_7MHZ:	ConstWithBandwidthMode = 56000000;		break;
++		case DVBT_BANDWIDTH_8MHZ:	ConstWithBandwidthMode = 64000000;		break;
++	}
++
++
++	// Calculate RSAMP_RATIO value.
++	// Note: RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22) / ConstWithBandwidthMode)
++	MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz);
++	MpiSetValue(&MpiVar1,          ConstWithBandwidthMode);
++	MpiSetValue(&MpiConst,         7);
++
++	MpiMul(&MpiVar0, MpiCrystalFreqHz, MpiConst);
++	MpiLeftShift(&MpiVar0, MpiVar0, 22);
++	MpiDiv(&MpiVar0, &MpiNone, MpiVar0, MpiVar1);
++
++	MpiGetValue(MpiVar0, (long *)&RsampRatio);
++
++
++	// Set RSAMP_RATIO with calculated value.
++	// Note: Use SetRegBitsWithPage() to set register bits with page setting.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_RSAMP_RATIO, RsampRatio) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Calculate CFREQ_OFF_RATIO value.
++	// Note: CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20) / (CrystalFreqHz * 7))
++	MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz);
++	MpiSetValue(&MpiVar0,          ConstWithBandwidthMode);
++	MpiSetValue(&MpiConst,         7);
++
++	MpiLeftShift(&MpiVar0, MpiVar0, 20);
++	MpiMul(&MpiVar1, MpiCrystalFreqHz, MpiConst);
++	MpiDiv(&MpiVar0, &MpiNone, MpiVar0, MpiVar1);
++
++	MpiGetValue(MpiVar0, &CfreqOffRatioInt);
++	CfreqOffRatioInt = - CfreqOffRatioInt;
++
++	CfreqOffRatioBinary = SignedIntToBin(CfreqOffRatioInt, RTL2832_CFREQ_OFF_RATIO_BIT_NUM);
++
++
++	// Set CFREQ_OFF_RATIO with calculated value.
++	// Note: Use SetRegBitsWithPage() to set register bits with page setting.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CFREQ_OFF_RATIO, CfreqOffRatioBinary) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++
++	// Set demod bandwidth mode parameter.
++	pDemod->BandwidthMode      = BandwidthMode;
++	pDemod->IsBandwidthModeSet = YES;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_SET_IF_FREQ_HZ
++
++*/
++int
++rtl2832_SetIfFreqHz(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long IfFreqHz
++	)
++{
++	unsigned long CrystalFreqHz;
++
++	unsigned long EnBbin;
++
++	MPI MpiCrystalFreqHz, MpiVar, MpiNone;
++
++	long PsetIffreqInt;
++	unsigned long PsetIffreqBinary;
++
++
++
++	// Get demod crystal frequency in Hz.
++	pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz);
++
++
++	// Determine and set EN_BBIN value.
++	EnBbin = (IfFreqHz == IF_FREQ_0HZ) ? 0x1 : 0x0;
++
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_EN_BBIN, EnBbin) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Calculate PSET_IFFREQ value.
++	// Note: PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22) / CrystalFreqHz)
++	MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz);
++
++	MpiSetValue(&MpiVar, (IfFreqHz % CrystalFreqHz));
++	MpiLeftShift(&MpiVar, MpiVar, RTL2832_PSET_IFFREQ_BIT_NUM);
++	MpiDiv(&MpiVar, &MpiNone, MpiVar, MpiCrystalFreqHz);
++
++	MpiGetValue(MpiVar, &PsetIffreqInt);
++	PsetIffreqInt = - PsetIffreqInt;
++
++	PsetIffreqBinary = SignedIntToBin(PsetIffreqInt, RTL2832_PSET_IFFREQ_BIT_NUM);
++
++
++	// Set PSET_IFFREQ with calculated value.
++	// Note: Use SetRegBitsWithPage() to set register bits with page setting.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_PSET_IFFREQ, PsetIffreqBinary) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Set demod IF frequnecy parameter.
++	pDemod->IfFreqHz      = IfFreqHz;
++	pDemod->IsIfFreqHzSet = YES;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_SET_SPECTRUM_MODE
++
++*/
++int
++rtl2832_SetSpectrumMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int SpectrumMode
++	)
++{
++	unsigned long SpecInv;
++
++
++
++	// Determine SpecInv according to spectrum mode.
++	switch(SpectrumMode)
++	{
++		default:
++		case SPECTRUM_NORMAL:		SpecInv = 0;		break;
++		case SPECTRUM_INVERSE:		SpecInv = 1;		break;
++	}
++
++
++	// Set SPEC_INV with SpecInv.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SPEC_INV, SpecInv) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Set demod spectrum mode parameter.
++	pDemod->SpectrumMode      = SpectrumMode;
++	pDemod->IsSpectrumModeSet = YES;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_IS_TPS_LOCKED
++
++*/
++int
++rtl2832_IsTpsLocked(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAnswer
++	)
++{
++	unsigned long FsmStage;
++
++
++
++	// Get FSM stage from FSM_STAGE.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++
++	// Determine answer according to FSM stage.
++	if(FsmStage > 9)
++		*pAnswer = YES;
++	else
++		*pAnswer = NO;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_IS_SIGNAL_LOCKED
++
++*/
++int
++rtl2832_IsSignalLocked(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAnswer
++	)
++{
++	unsigned long FsmStage;
++
++
++
++	// Get FSM stage from FSM_STAGE.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++
++	// Determine answer according to FSM stage.
++	if(FsmStage == 11)
++		*pAnswer = YES;
++	else
++		*pAnswer = NO;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH
++
++*/
++int
++rtl2832_GetSignalStrength(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pSignalStrength
++	)
++{
++	unsigned long FsmStage;
++	int IfAgc;
++
++
++
++	// Get FSM stage and IF AGC value.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	if(pDemod->GetIfAgc(pDemod, &IfAgc) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++
++	//  Determine signal strength according to FSM stage and IF AGC value.
++	if(FsmStage < 10)
++		*pSignalStrength = 0;
++	else
++		*pSignalStrength = 55 - IfAgc / 182;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_SIGNAL_QUALITY
++
++*/
++int
++rtl2832_GetSignalQuality(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pSignalQuality
++	)
++{
++	unsigned long FsmStage, RsdBerEst;
++
++	MPI MpiVar;
++	long Var;
++
++
++
++	// Get FSM_STAGE and RSD_BER_EST.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSD_BER_EST, &RsdBerEst) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++
++	// If demod is not signal-locked, set signal quality with zero.
++	if(FsmStage < 10)
++	{
++		*pSignalQuality = 0;
++		goto success_status_non_signal_lock;
++	}
++
++	// Determine signal quality according to RSD_BER_EST.
++	// Note: Map RSD_BER_EST value 8192 ~ 128 to 10 ~ 100
++	//       Original formula: SignalQuality = 205 - 15 * log2(RSD_BER_EST)
++	//       Adjusted formula: SignalQuality = ((205 << 5) - 15 * (log2(RSD_BER_EST) << 5)) >> 5
++	//       If RSD_BER_EST > 8192, signal quality is 10.
++	//       If RSD_BER_EST < 128, signal quality is 100.
++	if(RsdBerEst > 8192)
++	{
++		*pSignalQuality = 10;
++	}
++	else if(RsdBerEst < 128)
++	{
++		*pSignalQuality = 100;
++	}
++	else
++	{
++		MpiSetValue(&MpiVar, RsdBerEst);
++		MpiLog2(&MpiVar, MpiVar, RTL2832_SQ_FRAC_BIT_NUM);
++		MpiGetValue(MpiVar, &Var);
++
++		*pSignalQuality = ((205 << RTL2832_SQ_FRAC_BIT_NUM) - 15 * Var) >> RTL2832_SQ_FRAC_BIT_NUM;
++	}
++
++
++success_status_non_signal_lock:
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_BER
++
++*/
++int
++rtl2832_GetBer(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pBerNum,
++	unsigned long *pBerDen
++	)
++{
++	unsigned long RsdBerEst;
++
++
++
++	// Get RSD_BER_EST.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSD_BER_EST, &RsdBerEst) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++
++	// Set BER numerator according to RSD_BER_EST.
++	*pBerNum = RsdBerEst;
++
++	// Set BER denominator.
++	*pBerDen = RTL2832_BER_DEN_VALUE;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_SNR_DB
++
++*/
++int
++rtl2832_GetSnrDb(
++	DVBT_DEMOD_MODULE *pDemod,
++	long *pSnrDbNum,
++	long *pSnrDbDen
++	)
++{
++	unsigned long FsmStage;
++	unsigned long CeEstEvm;
++	int Constellation, Hierarchy;
++
++	static const long SnrDbNumConst[DVBT_CONSTELLATION_NUM][DVBT_HIERARCHY_NUM] =
++	{
++		{122880,	122880,		122880,		122880,		},
++		{146657,	146657,		156897,		171013,		},
++		{167857,	167857,		173127,		181810,		},
++	};
++
++	long Var;
++	MPI MpiCeEstEvm, MpiVar;
++
++
++
++	// Get FSM stage, CE_EST_EVM, constellation, and hierarchy.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_CE_EST_EVM, &CeEstEvm) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	if(pDemod->GetConstellation(pDemod, &Constellation) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	if(pDemod->GetHierarchy(pDemod, &Hierarchy) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++
++
++	// SNR dB formula
++	// Original formula: SNR_dB = 10 * log10(Norm * pow(2, 11) / CeEstEvm)
++	// Adjusted formula: SNR_dB = (SNR_DB_NUM_CONST - 10 * log2(CeEstEvm) * pow(2, SNR_FRAC_BIT_NUM)) / SNR_DB_DEN
++	//                   SNR_DB_NUM_CONST = 10 * log2(Norm * pow(2, 11)) * pow(2, SNR_FRAC_BIT_NUM)
++	//                   SNR_DB_DEN       = log2(10) * pow(2, SNR_FRAC_BIT_NUM)
++	// Norm:
++	//	                 None      Alpha=1   Alpha=2   Alpha=4
++	//        4-QAM      2         2         2         2
++	//       16-QAM      10        10        20        52
++	//       64-QAM      42        42        60        108
++
++
++	// If FSM stage < 10, set CE_EST_EVM with max value.
++	if(FsmStage < 10)
++		CeEstEvm = RTL2832_CE_EST_EVM_MAX_VALUE;
++
++
++	// Calculate SNR dB numerator.
++	MpiSetValue(&MpiCeEstEvm, CeEstEvm);
++
++	MpiLog2(&MpiVar, MpiCeEstEvm, RTL2832_SNR_FRAC_BIT_NUM);
++
++	MpiGetValue(MpiVar, &Var);
++
++	*pSnrDbNum = SnrDbNumConst[Constellation][Hierarchy] - 10 * Var;
++
++	
++	// Set SNR dB denominator.
++	*pSnrDbDen = RTL2832_SNR_DB_DEN;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_RF_AGC
++
++*/
++int
++rtl2832_GetRfAgc(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pRfAgc
++	)
++{
++	unsigned long Value;
++
++
++
++	// Get RF_AGC_VAL to Value.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RF_AGC_VAL, &Value) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++
++	// Convert Value to signed integer and store the signed integer to RfAgc.
++	*pRfAgc = (int)BinToSignedInt(Value, RTL2832_RF_AGC_REG_BIT_NUM);
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_IF_AGC
++
++*/
++int
++rtl2832_GetIfAgc(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pIfAgc
++	)
++{
++	unsigned long Value;
++
++
++
++	// Get IF_AGC_VAL to Value.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_IF_AGC_VAL, &Value) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++
++	// Convert Value to signed integer and store the signed integer to IfAgc.
++	*pIfAgc = (int)BinToSignedInt(Value, RTL2832_IF_AGC_REG_BIT_NUM);
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_DI_AGC
++
++*/
++int
++rtl2832_GetDiAgc(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char *pDiAgc
++	)
++{
++	unsigned long Value;
++
++
++
++	// Get DAGC_VAL to DiAgc.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_DAGC_VAL, &Value) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	*pDiAgc = (unsigned char)Value;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_TR_OFFSET_PPM
++
++*/
++int
++rtl2832_GetTrOffsetPpm(
++	DVBT_DEMOD_MODULE *pDemod,
++	long *pTrOffsetPpm
++	)
++{
++	unsigned long SfreqOffBinary;
++	long SfreqOffInt;
++
++	MPI MpiSfreqOffInt;
++	MPI MpiConst, MpiVar;
++
++
++	// Get SfreqOff binary value from SFREQ_OFF register bits.
++	// Note: The function GetRegBitsWithPage() will set register page automatically.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_SFREQ_OFF, &SfreqOffBinary) != FUNCTION_SUCCESS)
++		goto error_status_get_demod_registers;
++
++	// Convert SfreqOff binary value to signed integer.
++	SfreqOffInt = BinToSignedInt(SfreqOffBinary, RTL2832_SFREQ_OFF_BIT_NUM);
++
++	
++	// Get TR offset in ppm.
++	// Note: Original formula:   TrOffsetPpm = (SfreqOffInt * 1000000) / pow(2, 24)
++	//       Adjusted formula:   TrOffsetPpm = (SfreqOffInt * 1000000) >> 24
++	MpiSetValue(&MpiSfreqOffInt, SfreqOffInt);
++	MpiSetValue(&MpiConst,       1000000);
++
++	MpiMul(&MpiVar, MpiSfreqOffInt, MpiConst);
++	MpiRightShift(&MpiVar, MpiVar, 24);
++
++	MpiGetValue(MpiVar, pTrOffsetPpm);
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_demod_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_CR_OFFSET_HZ
++
++*/
++int
++rtl2832_GetCrOffsetHz(
++	DVBT_DEMOD_MODULE *pDemod,
++	long *pCrOffsetHz
++	)
++{
++	int BandwidthMode;
++	int FftMode;
++
++	unsigned long CfreqOffBinary;
++	long CfreqOffInt;
++
++	long ConstWithBandwidthMode, ConstWithFftMode;
++
++	MPI MpiCfreqOffInt;
++	MPI MpiConstWithBandwidthMode, MpiConstWithFftMode;
++	MPI MpiConst, MpiVar0, MpiVar1, MpiNone;
++
++
++
++	// Get demod bandwidth mode.
++	if(pDemod->GetBandwidthMode(pDemod, &BandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_get_demod_bandwidth_mode;
++
++
++	// Get demod FFT mode.
++	if(pDemod->GetFftMode(pDemod, &FftMode) != FUNCTION_SUCCESS)
++		goto error_status_get_demod_registers;
++
++
++	// Get CfreqOff binary value from CFREQ_OFF register bits.
++	// Note: The function GetRegBitsWithPage() will set register page automatically.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_CFREQ_OFF, &CfreqOffBinary) != FUNCTION_SUCCESS)
++		goto error_status_get_demod_registers;
++
++	// Convert CfreqOff binary value to signed integer.
++	CfreqOffInt = BinToSignedInt(CfreqOffBinary, RTL2832_CFREQ_OFF_BIT_NUM);
++
++
++	// Determine constant value with bandwidth mode.
++	switch(BandwidthMode)
++	{
++		default:
++		case DVBT_BANDWIDTH_6MHZ:	ConstWithBandwidthMode = 48000000;		break;
++		case DVBT_BANDWIDTH_7MHZ:	ConstWithBandwidthMode = 56000000;		break;
++		case DVBT_BANDWIDTH_8MHZ:	ConstWithBandwidthMode = 64000000;		break;
++	}
++
++
++	// Determine constant value with FFT mode.
++	switch(FftMode)
++	{
++		default:
++		case DVBT_FFT_MODE_2K:		ConstWithFftMode = 2048;		break;
++		case DVBT_FFT_MODE_8K:		ConstWithFftMode = 8192;		break;
++	}
++
++
++	// Get Cr offset in Hz.
++	// Note: Original formula:   CrOffsetHz = (CfreqOffInt * ConstWithBandwidthMode) / (ConstWithFftMode * 7 * 128)
++	//       Adjusted formula:   CrOffsetHz = (CfreqOffInt * ConstWithBandwidthMode) / ((ConstWithFftMode * 7) << 7)
++	MpiSetValue(&MpiCfreqOffInt,            CfreqOffInt);
++	MpiSetValue(&MpiConstWithBandwidthMode, ConstWithBandwidthMode);
++	MpiSetValue(&MpiConstWithFftMode,       ConstWithFftMode);
++	MpiSetValue(&MpiConst,                  7);
++
++	MpiMul(&MpiVar0, MpiCfreqOffInt, MpiConstWithBandwidthMode);
++	MpiMul(&MpiVar1, MpiConstWithFftMode, MpiConst);
++	MpiLeftShift(&MpiVar1, MpiVar1, 7);
++	MpiDiv(&MpiVar0, &MpiNone, MpiVar0, MpiVar1);
++
++	MpiGetValue(MpiVar0, pCrOffsetHz);
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_demod_registers:
++error_status_get_demod_bandwidth_mode:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_CONSTELLATION
++
++*/
++int
++rtl2832_GetConstellation(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pConstellation
++	)
++{
++	unsigned long ReadingValue;
++
++
++	// Get TPS constellation information from RX_CONSTEL.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_CONSTEL, &ReadingValue) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	switch(ReadingValue)
++	{
++		default:
++		case 0:		*pConstellation = DVBT_CONSTELLATION_QPSK;			break;
++		case 1:		*pConstellation = DVBT_CONSTELLATION_16QAM;			break;
++		case 2:		*pConstellation = DVBT_CONSTELLATION_64QAM;			break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_HIERARCHY
++
++*/
++int
++rtl2832_GetHierarchy(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pHierarchy
++	)
++{
++	unsigned long ReadingValue;
++
++
++	// Get TPS hierarchy infromation from RX_HIER.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_HIER, &ReadingValue) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	switch(ReadingValue)
++	{
++		default:
++		case 0:		*pHierarchy = DVBT_HIERARCHY_NONE;				break;
++		case 1:		*pHierarchy = DVBT_HIERARCHY_ALPHA_1;			break;
++		case 2:		*pHierarchy = DVBT_HIERARCHY_ALPHA_2;			break;
++		case 3:		*pHierarchy = DVBT_HIERARCHY_ALPHA_4;			break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_CODE_RATE_LP
++
++*/
++int
++rtl2832_GetCodeRateLp(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pCodeRateLp
++	)
++{
++	unsigned long ReadingValue;
++
++
++	// Get TPS low-priority code rate infromation from RX_C_RATE_LP.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_C_RATE_LP, &ReadingValue) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	switch(ReadingValue)
++	{
++		default:
++		case 0:		*pCodeRateLp = DVBT_CODE_RATE_1_OVER_2;			break;
++		case 1:		*pCodeRateLp = DVBT_CODE_RATE_2_OVER_3;			break;
++		case 2:		*pCodeRateLp = DVBT_CODE_RATE_3_OVER_4;			break;
++		case 3:		*pCodeRateLp = DVBT_CODE_RATE_5_OVER_6;			break;
++		case 4:		*pCodeRateLp = DVBT_CODE_RATE_7_OVER_8;			break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_CODE_RATE_HP
++
++*/
++int
++rtl2832_GetCodeRateHp(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pCodeRateHp
++	)
++{
++	unsigned long ReadingValue;
++
++
++	// Get TPS high-priority code rate infromation from RX_C_RATE_HP.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_C_RATE_HP, &ReadingValue) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	switch(ReadingValue)
++	{
++		default:
++		case 0:		*pCodeRateHp = DVBT_CODE_RATE_1_OVER_2;			break;
++		case 1:		*pCodeRateHp = DVBT_CODE_RATE_2_OVER_3;			break;
++		case 2:		*pCodeRateHp = DVBT_CODE_RATE_3_OVER_4;			break;
++		case 3:		*pCodeRateHp = DVBT_CODE_RATE_5_OVER_6;			break;
++		case 4:		*pCodeRateHp = DVBT_CODE_RATE_7_OVER_8;			break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_GUARD_INTERVAL
++
++*/
++int
++rtl2832_GetGuardInterval(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pGuardInterval
++	)
++{
++	unsigned long ReadingValue;
++
++
++	// Get TPS guard interval infromation from GI_IDX.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_GI_IDX, &ReadingValue) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	switch(ReadingValue)
++	{
++		default:
++		case 0:		*pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_32;			break;
++		case 1:		*pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_16;			break;
++		case 2:		*pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_8;				break;
++		case 3:		*pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_4;				break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_FFT_MODE
++
++*/
++int
++rtl2832_GetFftMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pFftMode
++	)
++{
++	unsigned long ReadingValue;
++
++
++	// Get TPS FFT mode infromation from FFT_MODE_IDX.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FFT_MODE_IDX, &ReadingValue) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	switch(ReadingValue)
++	{
++		default:
++		case 0:		*pFftMode = DVBT_FFT_MODE_2K;			break;
++		case 1:		*pFftMode = DVBT_FFT_MODE_8K;			break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_UPDATE_FUNCTION
++
++*/
++int
++rtl2832_UpdateFunction(
++	DVBT_DEMOD_MODULE *pDemod
++	)
++{
++	RTL2832_EXTRA_MODULE *pExtra;
++
++
++	// Get demod extra module.
++	pExtra = (RTL2832_EXTRA_MODULE *)pDemod->pExtra;
++
++
++	// Execute Function 1 according to Function 1 enabling status
++	if(pExtra->IsFunc1Enabled == YES)
++	{
++		if(rtl2832_func1_Update(pDemod) != FUNCTION_SUCCESS)
++			goto error_status_execute_function;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_RESET_FUNCTION
++
++*/
++int
++rtl2832_ResetFunction(
++	DVBT_DEMOD_MODULE *pDemod
++	)
++{
++	RTL2832_EXTRA_MODULE *pExtra;
++
++
++	// Get demod extra module.
++	pExtra = (RTL2832_EXTRA_MODULE *)pDemod->pExtra;
++
++
++	// Reset Function 1 settings according to Function 1 enabling status.
++	if(pExtra->IsFunc1Enabled == YES)
++	{
++		if(rtl2832_func1_Reset(pDemod) != FUNCTION_SUCCESS)
++			goto error_status_execute_function;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD
++
++*/
++int
++rtl2832_ForwardI2cReadingCmd(
++	I2C_BRIDGE_MODULE *pI2cBridge,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	unsigned char TunerDeviceAddr;
++
++
++
++	// Get demod module.
++	pDemod = (DVBT_DEMOD_MODULE *)pI2cBridge->pPrivateData;
++
++
++	// Get base interface.
++	pBaseInterface = pDemod->pBaseInterface;
++
++
++	// Get tuner device address.
++	TunerDeviceAddr = *pI2cBridge->pTunerDeviceAddr;
++
++
++	// Send I2C reading command.
++	if(pBaseInterface->I2cRead(pBaseInterface, TunerDeviceAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS)
++		goto error_send_i2c_reading_command;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_send_i2c_reading_command:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD
++
++*/
++int
++rtl2832_ForwardI2cWritingCmd(
++	I2C_BRIDGE_MODULE *pI2cBridge,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	unsigned char TunerDeviceAddr;
++
++
++
++	// Get demod module.
++	pDemod = (DVBT_DEMOD_MODULE *)pI2cBridge->pPrivateData;
++
++
++	// Get base interface.
++	pBaseInterface = pDemod->pBaseInterface;
++
++
++	// Get tuner device address.
++	TunerDeviceAddr = *pI2cBridge->pTunerDeviceAddr;
++
++
++	// Send I2C writing command.
++	if(pBaseInterface->I2cWrite(pBaseInterface, TunerDeviceAddr, pWritingBytes, ByteNum) != FUNCTION_SUCCESS)
++		goto error_send_i2c_writing_command;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_send_i2c_writing_command:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Initialize RTL2832 register table.
++
++Use rtl2832_InitRegTable() to initialize RTL2832 register table.
++
++
++@param [in]   pDemod   RTL2832 demod module pointer
++
++
++@note
++	-# The rtl2832_InitRegTable() function will be called by BuildRtl2832Module().
++
++*/
++void
++rtl2832_InitRegTable(
++	DVBT_DEMOD_MODULE *pDemod
++	)
++{
++	static const DVBT_PRIMARY_REG_ENTRY PrimaryRegTable[RTL2832_REG_TABLE_LEN] =
++	{
++		// Software reset register
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_SOFT_RST,						0x1,		0x1,			2,		2},
++
++		// Tuner I2C forwording register
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_IIC_REPEAT,					0x1,		0x1,			3,		3},
++
++		// Registers for initialization
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_TR_WAIT_MIN_8K,				0x1,		0x88,			11,		2},
++		{DVBT_RSD_BER_FAIL_VAL,				0x1,		0x8f,			15,		0},
++		{DVBT_EN_BK_TRK,					0x1,		0xa6,			7,		7},
++		{DVBT_AD_EN_REG,					0x0,		0x8,			7,		7},
++		{DVBT_AD_EN_REG1,					0x0,		0x8,			6,		6},
++		{DVBT_EN_BBIN,						0x1,		0xb1,			0,		0},
++		{DVBT_MGD_THD0,						0x1,		0x95,			7,		0},
++		{DVBT_MGD_THD1,						0x1,		0x96,			7,		0},
++		{DVBT_MGD_THD2,						0x1,		0x97,			7,		0},
++		{DVBT_MGD_THD3,						0x1,		0x98,			7,		0},
++		{DVBT_MGD_THD4,						0x1,		0x99,			7,		0},
++		{DVBT_MGD_THD5,						0x1,		0x9a,			7,		0},
++		{DVBT_MGD_THD6,						0x1,		0x9b,			7,		0},
++		{DVBT_MGD_THD7,						0x1,		0x9c,			7,		0},
++		{DVBT_EN_CACQ_NOTCH,				0x1,		0x61,			4,		4},
++		{DVBT_AD_AV_REF,					0x0,		0x9,			6,		0},
++		{DVBT_REG_PI,						0x0,		0xa,			2,		0},
++		{DVBT_PIP_ON,						0x0,		0x21,			3,		3},
++		{DVBT_SCALE1_B92,					0x2,		0x92,			7,		0},
++		{DVBT_SCALE1_B93,					0x2,		0x93,			7,		0},
++		{DVBT_SCALE1_BA7,					0x2,		0xa7,			7,		0},
++		{DVBT_SCALE1_BA9,					0x2,		0xa9,			7,		0},
++		{DVBT_SCALE1_BAA,					0x2,		0xaa,			7,		0},
++		{DVBT_SCALE1_BAB,					0x2,		0xab,			7,		0},
++		{DVBT_SCALE1_BAC,					0x2,		0xac,			7,		0},
++		{DVBT_SCALE1_BB0,					0x2,		0xb0,			7,		0},
++		{DVBT_SCALE1_BB1,					0x2,		0xb1,			7,		0},
++		{DVBT_KB_P1,						0x1,		0x64,			3,		1},
++		{DVBT_KB_P2,						0x1,		0x64,			6,		4},
++		{DVBT_KB_P3,						0x1,		0x65,			2,		0},
++		{DVBT_OPT_ADC_IQ,					0x0,		0x6,			5,		4},
++		{DVBT_AD_AVI,						0x0,		0x9,			1,		0},
++		{DVBT_AD_AVQ,						0x0,		0x9,			3,		2},
++		{DVBT_K1_CR_STEP12,					0x2,		0xad,			9,		4},
++
++		// Registers for initialization according to mode
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_TRK_KS_P2,					0x1,		0x6f,			2,		0},
++		{DVBT_TRK_KS_I2,					0x1,		0x70,			5,		3},
++		{DVBT_TR_THD_SET2,					0x1,		0x72,			3,		0},
++		{DVBT_TRK_KC_P2,					0x1,		0x73,			5,		3},
++		{DVBT_TRK_KC_I2,					0x1,		0x75,			2,		0},
++		{DVBT_CR_THD_SET2,					0x1,		0x76,			7,		6},
++
++		// Registers for IF setting
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_PSET_IFFREQ,					0x1,		0x19,			21,		0},
++		{DVBT_SPEC_INV,						0x1,		0x15,			0,		0},
++
++		// Registers for bandwidth programming
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_RSAMP_RATIO,					0x1,		0x9f,			27,		2},
++		{DVBT_CFREQ_OFF_RATIO,				0x1,		0x9d,			23,		4},
++
++		// FSM stage register
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_FSM_STAGE,					0x3,		0x51,			6,		3},
++
++		// TPS content registers
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_RX_CONSTEL,					0x3,		0x3c,			3,		2},
++		{DVBT_RX_HIER,						0x3,		0x3c,			6,		4},
++		{DVBT_RX_C_RATE_LP,					0x3,		0x3d,			2,		0},
++		{DVBT_RX_C_RATE_HP,					0x3,		0x3d,			5,		3},
++		{DVBT_GI_IDX,						0x3,		0x51,			1,		0},
++		{DVBT_FFT_MODE_IDX,					0x3,		0x51,			2,		2},
++
++		// Performance measurement registers
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_RSD_BER_EST,					0x3,		0x4e,			15,		0},
++		{DVBT_CE_EST_EVM,					0x4,		0xc,			15,		0},
++
++		// AGC registers
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_RF_AGC_VAL,					0x3,		0x5b,			13,		0},
++		{DVBT_IF_AGC_VAL,					0x3,		0x59,			13,		0},
++		{DVBT_DAGC_VAL,						0x3,		0x5,			7,		0},
++
++		// TR offset and CR offset registers
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_SFREQ_OFF,					0x3,		0x18,			13,		0},
++		{DVBT_CFREQ_OFF,					0x3,		0x5f,			17,		0},
++
++		// AGC relative registers
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_POLAR_RF_AGC,					0x0,		0xe,			1,		1},
++		{DVBT_POLAR_IF_AGC,					0x0,		0xe,			0,		0},
++		{DVBT_AAGC_HOLD,					0x1,		0x4,			5,		5},
++		{DVBT_EN_RF_AGC,					0x1,		0x4,			6,		6},
++		{DVBT_EN_IF_AGC,					0x1,		0x4,			7,		7},
++		{DVBT_IF_AGC_MIN,					0x1,		0x8,			7,		0},
++		{DVBT_IF_AGC_MAX,					0x1,		0x9,			7,		0},
++		{DVBT_RF_AGC_MIN,					0x1,		0xa,			7,		0},
++		{DVBT_RF_AGC_MAX,					0x1,		0xb,			7,		0},
++		{DVBT_IF_AGC_MAN,					0x1,		0xc,			6,		6},
++		{DVBT_IF_AGC_MAN_VAL,				0x1,		0xc,			13,		0},
++		{DVBT_RF_AGC_MAN,					0x1,		0xe,			6,		6},
++		{DVBT_RF_AGC_MAN_VAL,				0x1,		0xe,			13,		0},
++		{DVBT_DAGC_TRG_VAL,					0x1,		0x12,			7,		0},
++		{DVBT_AGC_TARG_VAL_0,				0x1,		0x2,			0,		0},
++		{DVBT_AGC_TARG_VAL_8_1,				0x1,		0x3,			7,		0},
++		{DVBT_AAGC_LOOP_GAIN,				0x1,		0xc7,			5,		1},
++		{DVBT_LOOP_GAIN2_3_0,				0x1,		0x4,			4,		1},
++		{DVBT_LOOP_GAIN2_4,					0x1,		0x5,			7,		7},
++		{DVBT_LOOP_GAIN3,					0x1,		0xc8,			4,		0},
++		{DVBT_VTOP1,						0x1,		0x6,			5,		0},
++		{DVBT_VTOP2,						0x1,		0xc9,			5,		0},
++		{DVBT_VTOP3,						0x1,		0xca,			5,		0},
++		{DVBT_KRF1,							0x1,		0xcb,			7,		0},
++		{DVBT_KRF2,							0x1,		0x7,			7,		0},
++		{DVBT_KRF3,							0x1,		0xcd,			7,		0},
++		{DVBT_KRF4,							0x1,		0xce,			7,		0},
++
++		// TS interface registers
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_CKOUTPAR,						0x1,		0x7b,			5,		5},
++		{DVBT_CKOUT_PWR,					0x1,		0x7b,			6,		6},
++		{DVBT_SYNC_DUR,						0x1,		0x7b,			7,		7},
++		{DVBT_ERR_DUR,						0x1,		0x7c,			0,		0},
++		{DVBT_SYNC_LVL,						0x1,		0x7c,			1,		1},
++		{DVBT_ERR_LVL,						0x1,		0x7c,			2,		2},
++		{DVBT_VAL_LVL,						0x1,		0x7c,			3,		3},
++		{DVBT_SERIAL,						0x1,		0x7c,			4,		4},
++		{DVBT_SER_LSB,						0x1,		0x7c,			5,		5},
++		{DVBT_CDIV_PH0,						0x1,		0x7d,			3,		0},
++		{DVBT_CDIV_PH1,						0x1,		0x7d,			7,		4},
++		{DVBT_CKOUTPAR_PIP,					0x0,		0xb7,			4,		4},
++		{DVBT_CKOUT_PWR_PIP,				0x0,		0xb7,			3,		3},
++		{DVBT_SYNC_LVL_PIP,					0x0,		0xb7,			2,		2},
++		{DVBT_ERR_LVL_PIP,					0x0,		0xb7,			1,		1},
++		{DVBT_VAL_LVL_PIP,					0x0,		0xb7,			0,		0},
++		{DVBT_CKOUTPAR_PID,					0x0,		0xb9,			4,		4},
++		{DVBT_CKOUT_PWR_PID,				0x0,		0xb9,			3,		3},
++		{DVBT_SYNC_LVL_PID,					0x0,		0xb9,			2,		2},
++		{DVBT_ERR_LVL_PID,					0x0,		0xb9,			1,		1},
++		{DVBT_VAL_LVL_PID,					0x0,		0xb9,			0,		0},
++
++		// FSM state-holding register
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_SM_PASS,						0x1,		0x93,			11,		0},
++
++		// AD7 registers
++		// RegBitName,						PageNo,		RegStartAddr,	MSB,	LSB
++		{DVBT_AD7_SETTING,					0x0,		0x11,			15,		0},
++		{DVBT_RSSI_R,						0x3,		0x1,			6,		0},
++
++		// ACI detection registers
++		{DVBT_ACI_DET_IND,					0x3,		0x12,			0,		0},
++	};
++
++
++	int i;
++	int RegBitName;
++
++
++
++	// Initialize register table according to primary register table.
++	// Note: 1. Register table rows are sorted by register bit name key.
++	//       2. The default value of the IsAvailable variable is "NO".
++	for(i = 0; i < DVBT_REG_TABLE_LEN_MAX; i++)
++		pDemod->RegTable[i].IsAvailable  = NO;
++
++	for(i = 0; i < RTL2832_REG_TABLE_LEN; i++)
++	{
++		RegBitName = PrimaryRegTable[i].RegBitName;
++
++		pDemod->RegTable[RegBitName].IsAvailable  = YES;
++		pDemod->RegTable[RegBitName].PageNo       = PrimaryRegTable[i].PageNo;
++		pDemod->RegTable[RegBitName].RegStartAddr = PrimaryRegTable[i].RegStartAddr;
++		pDemod->RegTable[RegBitName].Msb          = PrimaryRegTable[i].Msb;
++		pDemod->RegTable[RegBitName].Lsb          = PrimaryRegTable[i].Lsb;
++	}
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Set I2C bridge module demod arguments.
++
++RTL2832 builder will use rtl2832_SetI2cBridgeModuleDemodArg() to set I2C bridge module demod arguments.
++
++
++@param [in]   pDemod   The demod module pointer
++
++
++@see   BuildRtl2832Module()
++
++*/
++void
++rtl2832_SetI2cBridgeModuleDemodArg(
++	DVBT_DEMOD_MODULE *pDemod
++	)
++{
++	I2C_BRIDGE_MODULE *pI2cBridge;
++
++
++
++	// Get I2C bridge module.
++	pI2cBridge = pDemod->pI2cBridge;
++
++	// Set I2C bridge module demod arguments.
++	pI2cBridge->pPrivateData = (void *)pDemod;
++	pI2cBridge->ForwardI2cReadingCmd = rtl2832_ForwardI2cReadingCmd;
++	pI2cBridge->ForwardI2cWritingCmd = rtl2832_ForwardI2cWritingCmd;
++
++
++	return;
++}
++
++
++
++
++
++/*
++
++@see   RTL2832_FP_GET_APP_MODE
++
++*/
++void
++rtl2832_GetAppMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAppMode
++	)
++{
++	RTL2832_EXTRA_MODULE *pExtra;
++
++
++
++	// Get demod extra module.
++	pExtra = (RTL2832_EXTRA_MODULE *)pDemod->pExtra;
++
++
++	// Get demod type from demod module.
++	*pAppMode = pExtra->AppMode;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Reset Function 1 variables and registers.
++
++One can use rtl2832_func1_Reset() to reset Function 1 variables and registers.
++
++
++@param [in]   pDemod   The demod module pointer
++
++
++@retval   FUNCTION_SUCCESS   Reset Function 1 variables and registers successfully.
++@retval   FUNCTION_ERROR     Reset Function 1 variables and registers unsuccessfully.
++
++
++@note
++	-# Need to execute Function 1 reset function when change tuner RF frequency or demod parameters.
++	-# Function 1 update flow also employs Function 1 reset function.
++
++*/
++int
++rtl2832_func1_Reset(
++	DVBT_DEMOD_MODULE *pDemod
++	)
++{
++	RTL2832_EXTRA_MODULE *pExtra;
++
++
++
++	// Get demod extra module.
++	pExtra = (RTL2832_EXTRA_MODULE *)pDemod->pExtra;
++
++	// Reset demod Function 1 variables.
++	pExtra->Func1State               = RTL2832_FUNC1_STATE_NORMAL;
++	pExtra->Func1WaitTime            = 0;
++	pExtra->Func1GettingTime         = 0;
++	pExtra->Func1RsdBerEstSumNormal  = 0;
++	pExtra->Func1RsdBerEstSumConfig1 = 0;
++	pExtra->Func1RsdBerEstSumConfig2 = 0;
++	pExtra->Func1RsdBerEstSumConfig3 = 0;
++
++
++	// Reset demod Function 1 registers.
++    if(rtl2832_func1_ResetReg(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Update demod registers with Function 1.
++
++One can use rtl2832_func1_Update() to update demod registers with Function 1.
++
++
++@param [in]   pDemod   The demod module pointer
++
++
++@retval   FUNCTION_SUCCESS   Update demod registers with Function 1 successfully.
++@retval   FUNCTION_ERROR     Update demod registers with Function 1 unsuccessfully.
++
++*/
++int
++rtl2832_func1_Update(
++	DVBT_DEMOD_MODULE *pDemod
++	)
++{
++	RTL2832_EXTRA_MODULE *pExtra;
++
++	int Answer;
++	int MinWeightedBerConfigMode;
++
++
++
++	// Get demod extra module.
++	pExtra = (RTL2832_EXTRA_MODULE *)pDemod->pExtra;
++
++
++	// Run FSM.
++	switch(pExtra->Func1State)
++	{
++		case RTL2832_FUNC1_STATE_NORMAL:
++
++			// Ask if criterion is matched.
++			if(rtl2832_func1_IsCriterionMatched(pDemod, &Answer) != FUNCTION_SUCCESS)
++				goto error_status_execute_function;
++
++			if(Answer == YES)
++			{
++				// Accumulate RSD_BER_EST for normal case.
++				if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumNormal) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Reset getting time counter.
++				pExtra->Func1GettingTime = 0;
++
++				// Go to RTL2832_FUNC1_STATE_NORMAL_GET_BER state.
++				pExtra->Func1State = RTL2832_FUNC1_STATE_NORMAL_GET_BER;
++			}
++
++			break;
++
++
++		case RTL2832_FUNC1_STATE_NORMAL_GET_BER:
++
++			// Accumulate RSD_BER_EST for normal case.
++			if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumNormal) != FUNCTION_SUCCESS)
++				goto error_status_execute_function;
++
++			// Use getting time counter to hold RTL2832_FUNC1_STATE_NORMAL_GET_BER state several times.
++			pExtra->Func1GettingTime += 1;
++
++			if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax)
++			{
++				// Set common registers for configuration 1, 2, and 3 case.
++				if(rtl2832_func1_SetCommonReg(pDemod) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Set registers with FFT mode for configuration 1, 2, and 3 case.
++				if(rtl2832_func1_SetRegWithFftMode(pDemod, pExtra->Func1FftBak) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Set registers for configuration 1 case.
++				if(rtl2832_func1_SetRegWithConfigMode(pDemod, RTL2832_FUNC1_CONFIG_1) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Reset demod by software reset.
++				if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Reset wait time counter.
++				pExtra->Func1WaitTime = 0;
++
++				// Go to RTL2832_FUNC1_STATE_CONFIG_1_WAIT state.
++				pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_1_WAIT;
++			}
++
++			break;
++
++
++		case RTL2832_FUNC1_STATE_CONFIG_1_WAIT:
++
++			// Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_1_WAIT state several times.
++			pExtra->Func1WaitTime += 1;
++
++			if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax)
++			{
++				// Accumulate RSD_BER_EST for configuration 1 case.
++				if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig1) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Reset getting time counter.
++				pExtra->Func1GettingTime = 0;
++
++				// Go to RTL2832_FUNC1_STATE_CONFIG_1_GET_BER state.
++				pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_1_GET_BER;
++			}
++
++			break;
++
++
++		case RTL2832_FUNC1_STATE_CONFIG_1_GET_BER:
++
++			// Accumulate RSD_BER_EST for configuration 1 case.
++			if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig1) != FUNCTION_SUCCESS)
++				goto error_status_execute_function;
++
++			// Use getting time counter to hold RTL2832_FUNC1_STATE_CONFIG_1_GET_BER state several times.
++			pExtra->Func1GettingTime += 1;
++
++			if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax)
++			{
++				// Set registers for configuration 2 case.
++				if(rtl2832_func1_SetRegWithConfigMode(pDemod, RTL2832_FUNC1_CONFIG_2) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Reset demod by software reset.
++				if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Reset wait time counter.
++				pExtra->Func1WaitTime = 0;
++
++				// Go to RTL2832_FUNC1_STATE_CONFIG_2_WAIT state.
++				pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_2_WAIT;
++			}
++
++			break;
++
++
++		case RTL2832_FUNC1_STATE_CONFIG_2_WAIT:
++
++			// Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_2_WAIT state several times.
++			pExtra->Func1WaitTime += 1;
++
++			if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax)
++			{
++				// Accumulate RSD_BER_EST for configuration 2 case.
++				if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig2) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Reset getting time counter.
++				pExtra->Func1GettingTime = 0;
++
++				// Go to RTL2832_FUNC1_STATE_CONFIG_2_GET_BER state.
++				pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_2_GET_BER;
++			}
++
++			break;
++
++
++		case RTL2832_FUNC1_STATE_CONFIG_2_GET_BER:
++
++			// Accumulate RSD_BER_EST for configuration 2 case.
++			if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig2) != FUNCTION_SUCCESS)
++				goto error_status_execute_function;
++
++			// Use getting time counter to hold RTL2832_FUNC1_STATE_CONFIG_2_GET_BER state several times.
++			pExtra->Func1GettingTime += 1;
++
++			if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax)
++			{
++				// Set registers for configuration 3 case.
++				if(rtl2832_func1_SetRegWithConfigMode(pDemod, RTL2832_FUNC1_CONFIG_3) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Reset demod by software reset.
++				if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Reset wait time counter.
++				pExtra->Func1WaitTime = 0;
++
++				// Go to RTL2832_FUNC1_STATE_CONFIG_3_WAIT state.
++				pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_3_WAIT;
++			}
++
++			break;
++
++
++		case RTL2832_FUNC1_STATE_CONFIG_3_WAIT:
++
++			// Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_3_WAIT state several times.
++			pExtra->Func1WaitTime += 1;
++
++			if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax)
++			{
++				// Accumulate RSD_BER_EST for configuration 3 case.
++				if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig3) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Reset getting time counter.
++				pExtra->Func1GettingTime = 0;
++
++				// Go to RTL2832_FUNC1_STATE_CONFIG_3_GET_BER state.
++				pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_3_GET_BER;
++			}
++
++			break;
++
++
++		case RTL2832_FUNC1_STATE_CONFIG_3_GET_BER:
++
++			// Accumulate RSD_BER_EST for configuration 3 case.
++			if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig3) != FUNCTION_SUCCESS)
++				goto error_status_execute_function;
++
++			// Use getting time counter to hold RTL2832_FUNC1_STATE_CONFIG_3_GET_BER state several times.
++			pExtra->Func1GettingTime += 1;
++
++			if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax)
++			{
++				// Determine minimum-weighted-BER configuration mode.
++				rtl2832_func1_GetMinWeightedBerConfigMode(pDemod, &MinWeightedBerConfigMode);
++
++				// Set registers with minimum-weighted-BER configuration mode.
++				switch(MinWeightedBerConfigMode)
++				{
++					case RTL2832_FUNC1_CONFIG_NORMAL:
++
++						// Reset registers for normal configuration.
++						if(rtl2832_func1_ResetReg(pDemod) != FUNCTION_SUCCESS)
++							goto error_status_execute_function;
++
++						break;
++
++
++					case RTL2832_FUNC1_CONFIG_1:
++					case RTL2832_FUNC1_CONFIG_2:
++					case RTL2832_FUNC1_CONFIG_3:
++
++						// Set registers for minimum-weighted-BER configuration.
++						if(rtl2832_func1_SetRegWithConfigMode(pDemod, MinWeightedBerConfigMode) != FUNCTION_SUCCESS)
++							goto error_status_execute_function;
++
++						break;
++
++
++					default:
++
++						// Get error configuration mode, reset registers.
++						if(rtl2832_func1_ResetReg(pDemod) != FUNCTION_SUCCESS)
++							goto error_status_execute_function;
++
++						break;
++				}
++
++				// Reset demod by software reset.
++				if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++
++				// Reset wait time counter.
++				pExtra->Func1WaitTime = 0;
++
++				// Go to RTL2832_FUNC1_STATE_DETERMINED_WAIT state.
++				pExtra->Func1State = RTL2832_FUNC1_STATE_DETERMINED_WAIT;
++			}
++
++			break;
++
++
++		case RTL2832_FUNC1_STATE_DETERMINED_WAIT:
++
++			// Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_3_WAIT state several times.
++			pExtra->Func1WaitTime += 1;
++
++			if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax)
++			{
++				// Go to RTL2832_FUNC1_STATE_DETERMINED state.
++				pExtra->Func1State = RTL2832_FUNC1_STATE_DETERMINED;
++			}
++
++			break;
++
++
++		case RTL2832_FUNC1_STATE_DETERMINED:
++
++			// Ask if criterion is matched.
++			if(rtl2832_func1_IsCriterionMatched(pDemod, &Answer) != FUNCTION_SUCCESS)
++				goto error_status_execute_function;
++
++			if(Answer == NO)
++			{
++				// Reset FSM.
++				// Note: rtl2832_func1_Reset() will set FSM state with RTL2832_FUNC1_STATE_NORMAL.
++				if(rtl2832_func1_Reset(pDemod) != FUNCTION_SUCCESS)
++					goto error_status_execute_function;
++			}
++
++			break;
++
++
++		default:
++
++			// Get error state, reset FSM.
++			// Note: rtl2832_func1_Reset() will set FSM state with RTL2832_FUNC1_STATE_NORMAL.
++			if(rtl2832_func1_Reset(pDemod) != FUNCTION_SUCCESS)
++				goto error_status_execute_function;
++
++			break;
++	}
++
++
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Ask if criterion is matched for Function 1.
++
++One can use rtl2832_func1_IsCriterionMatched() to ask if criterion is matched for Function 1.
++
++
++@param [in]    pDemod    The demod module pointer
++@param [out]   pAnswer   Pointer to an allocated memory for storing answer
++
++
++@retval   FUNCTION_SUCCESS   Ask if criterion is matched for Function 1 successfully.
++@retval   FUNCTION_ERROR     Ask if criterion is matched for Function 1 unsuccessfully.
++
++*/
++int
++rtl2832_func1_IsCriterionMatched(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAnswer
++	)
++{
++	RTL2832_EXTRA_MODULE *pExtra;
++
++	unsigned long FsmStage;
++
++	int Qam;
++	int Hier;
++	int LpCr;
++	int HpCr;
++	int Gi;
++	int Fft;
++
++	unsigned long Reg0, Reg1;
++
++	int BandwidthMode;
++
++
++
++	// Get demod extra module.
++	pExtra = (RTL2832_EXTRA_MODULE *)pDemod->pExtra;
++
++
++	// Get FSM_STAGE.
++    if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++
++	// Get QAM.
++	if(pDemod->GetConstellation(pDemod, &Qam) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get hierarchy.
++	if(pDemod->GetHierarchy(pDemod, &Hier) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get low-priority code rate.
++	if(pDemod->GetCodeRateLp(pDemod, &LpCr) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get high-priority code rate.
++	if(pDemod->GetCodeRateHp(pDemod, &HpCr) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get guard interval.
++	if(pDemod->GetGuardInterval(pDemod, &Gi) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get FFT mode.
++	if(pDemod->GetFftMode(pDemod, &Fft) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	// Get REG_0 and REG_1.
++	if(pDemod->SetRegPage(pDemod, 0x3) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->GetRegMaskBits(pDemod, 0x22, 0, 0, &Reg0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->GetRegMaskBits(pDemod, 0x1a, 15, 3, &Reg1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Get bandwidth mode.
++	if(pDemod->GetBandwidthMode(pDemod, &BandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	// Determine criterion answer.
++	*pAnswer = 
++		(FsmStage == 11) && 
++
++		(Qam  == pExtra->Func1QamBak) &&
++		(Hier == pExtra->Func1HierBak) &&
++		(LpCr == pExtra->Func1LpCrBak) &&
++		(HpCr == pExtra->Func1HpCrBak) &&
++		(Gi   == pExtra->Func1GiBak) &&
++		(Fft  == pExtra->Func1FftBak) &&
++
++		(Reg0 == 0x1) &&
++
++		((BandwidthMode == DVBT_BANDWIDTH_8MHZ) &&
++		 ( ((Fft == DVBT_FFT_MODE_2K) && (Reg1 > 1424) && (Reg1 < 1440)) ||
++		   ((Fft == DVBT_FFT_MODE_8K) && (Reg1 > 5696) && (Reg1 < 5760))    ) );
++
++
++	// Backup TPS information.
++	pExtra->Func1QamBak  = Qam;
++	pExtra->Func1HierBak = Hier;
++	pExtra->Func1LpCrBak = LpCr;
++	pExtra->Func1HpCrBak = HpCr;
++	pExtra->Func1GiBak   = Gi;
++	pExtra->Func1FftBak  = Fft;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_registers:
++error_status_execute_function:
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Accumulate RSD_BER_EST value for Function 1.
++
++One can use rtl2832_func1_AccumulateRsdBerEst() to accumulate RSD_BER_EST for Function 1.
++
++
++@param [in]   pDemod               The demod module pointer
++@param [in]   pAccumulativeValue   Accumulative RSD_BER_EST value
++
++
++@retval   FUNCTION_SUCCESS   Accumulate RSD_BER_EST for Function 1 successfully.
++@retval   FUNCTION_ERROR     Accumulate RSD_BER_EST for Function 1 unsuccessfully.
++
++*/
++int
++rtl2832_func1_AccumulateRsdBerEst(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pAccumulativeValue
++	)
++{
++	RTL2832_EXTRA_MODULE *pExtra;
++
++	int i;
++	unsigned long RsdBerEst;
++
++
++
++	// Get demod extra module.
++	pExtra = (RTL2832_EXTRA_MODULE *)pDemod->pExtra;
++
++
++	// Get RSD_BER_EST with assigned times.
++	for(i = 0; i < pExtra->Func1GettingNumEachTime; i++)
++	{
++		// Get RSD_BER_EST.
++		if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSD_BER_EST, &RsdBerEst) != FUNCTION_SUCCESS)
++			goto error_status_get_registers;
++
++		// Accumulate RSD_BER_EST to accumulative value.
++		*pAccumulativeValue += RsdBerEst;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Reset registers for Function 1.
++
++One can use rtl2832_func1_ResetReg() to reset registers for Function 1.
++
++
++@param [in]   pDemod   The demod module pointer
++
++
++@retval   FUNCTION_SUCCESS   Reset registers for Function 1 successfully.
++@retval   FUNCTION_ERROR     Reset registers for Function 1 unsuccessfully.
++
++*/
++int
++rtl2832_func1_ResetReg(
++	DVBT_DEMOD_MODULE *pDemod
++	)
++{
++	// Reset Function 1 registers.
++    if(pDemod->SetRegPage(pDemod, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x65, 2, 0, 0x7) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x68, 5, 4, 0x3) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x5b, 2, 0, 0x5) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x5b, 5, 3, 0x5) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x5c, 2, 0, 0x5) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x5c, 5, 3, 0x5) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xd0, 3, 2, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xd1, 14, 0, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xd3, 14, 0, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xd5, 14, 0, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x1, 0, 0, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xb4, 7, 6, 0x3) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xd2, 1, 1, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xb5, 7, 7, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Set common registers for Function 1.
++
++One can use rtl2832_func1_SetCommonReg() to set common registers for Function 1.
++
++
++@param [in]   pDemod   The demod module pointer
++
++
++@retval   FUNCTION_SUCCESS   Set common registers for Function 1 successfully.
++@retval   FUNCTION_ERROR     Set common registers for Function 1 unsuccessfully.
++
++*/
++int
++rtl2832_func1_SetCommonReg(
++	DVBT_DEMOD_MODULE *pDemod
++	)
++{
++	// Set common registers for Function 1.
++    if(pDemod->SetRegPage(pDemod, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x65, 2, 0, 0x5) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x68, 5, 4, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xd2, 1, 1, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xb5, 7, 7, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Set registers with FFT mode for Function 1.
++
++One can use rtl2832_func1_SetRegWithConfigMode() to set registers with FFT mode for Function 1.
++
++
++@param [in]   pDemod    The demod module pointer
++@param [in]   FftMode   FFT mode for setting
++
++
++@retval   FUNCTION_SUCCESS   Set registers with FFT mode for Function 1 successfully.
++@retval   FUNCTION_ERROR     Set registers with FFT mode for Function 1 unsuccessfully.
++
++*/
++int
++rtl2832_func1_SetRegWithFftMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int FftMode
++	)
++{
++	typedef struct
++	{
++		unsigned long Reg0[DVBT_FFT_MODE_NUM];
++		unsigned long Reg1[DVBT_FFT_MODE_NUM];
++	}
++	FFT_REF_ENTRY;
++
++
++
++	static const FFT_REF_ENTRY FftRefTable =
++	{
++		// 2K mode,   8K mode
++		{0x0,         0x1    },
++		{0x3,         0x0    },
++	};
++
++
++
++	// Set registers with FFT mode for Function 1.
++    if(pDemod->SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x1, 0, 0, FftRefTable.Reg0[FftMode]) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xb4, 7, 6, FftRefTable.Reg1[FftMode]) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Set registers with configuration mode for Function 1.
++
++One can use rtl2832_func1_SetRegWithConfigMode() to set registers with configuration mode for Function 1.
++
++
++@param [in]   pDemod       The demod module pointer
++@param [in]   ConfigMode   Configuration mode for setting
++
++
++@retval   FUNCTION_SUCCESS   Set registers with configuration mode for Function 1 successfully.
++@retval   FUNCTION_ERROR     Set registers with configuration mode for Function 1 unsuccessfully.
++
++
++@note
++	-# This function can not set RTL2832_FUNC1_CONFIG_NORMAL configuration mode.
++
++*/
++int
++rtl2832_func1_SetRegWithConfigMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int ConfigMode
++	)
++{
++	typedef struct
++	{
++		unsigned long Reg0[RTL2832_FUNC1_CONFIG_MODE_NUM];
++		unsigned long Reg1[RTL2832_FUNC1_CONFIG_MODE_NUM];
++		unsigned long Reg2[RTL2832_FUNC1_CONFIG_MODE_NUM];
++		unsigned long Reg3[RTL2832_FUNC1_CONFIG_MODE_NUM];
++		unsigned long Reg4[RTL2832_FUNC1_CONFIG_MODE_NUM];
++
++		unsigned long Reg5Ref[RTL2832_FUNC1_CONFIG_MODE_NUM];
++		unsigned long Reg6Ref[RTL2832_FUNC1_CONFIG_MODE_NUM];
++		unsigned long Reg7Ref[RTL2832_FUNC1_CONFIG_MODE_NUM];
++	}
++	CONFIG_REF_ENTRY;
++
++
++
++	static const CONFIG_REF_ENTRY ConfigRefTable =
++	{
++		// Config 1,   Config 2,   Config 3
++		{0x5,          0x4,        0x5     },
++		{0x5,          0x4,        0x7     },
++		{0x5,          0x4,        0x7     },
++		{0x7,          0x6,        0x5     },
++		{0x3,          0x3,        0x2     },
++
++		{4437,         4437,       4325    },
++		{6000,         5500,       6500    },
++		{6552,         5800,       5850    },
++	};
++
++	int BandwidthMode;
++
++	static const unsigned long Const[DVBT_BANDWIDTH_MODE_NUM] =
++	{
++		// 6Mhz, 7Mhz, 8Mhz
++		48,      56,   64,
++	};
++
++	unsigned long Reg5, Reg6, Reg7;
++
++
++
++	// Get bandwidth mode.
++	if(pDemod->GetBandwidthMode(pDemod, &BandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Calculate REG_5, REG_6, and REG_7 with bandwidth mode and configuration mode.
++	Reg5 = (ConfigRefTable.Reg5Ref[ConfigMode] * 7 * 2048 * 8) / (1000 * Const[BandwidthMode]);
++	Reg6 = (ConfigRefTable.Reg6Ref[ConfigMode] * 7 * 2048 * 8) / (1000 * Const[BandwidthMode]);
++	Reg7 = (ConfigRefTable.Reg7Ref[ConfigMode] * 7 * 2048 * 8) / (1000 * Const[BandwidthMode]);
++
++
++	// Set registers with bandwidth mode and configuration mode.
++    if(pDemod->SetRegPage(pDemod, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x5b, 2, 0, ConfigRefTable.Reg0[ConfigMode]) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x5b, 5, 3, ConfigRefTable.Reg1[ConfigMode]) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x5c, 2, 0, ConfigRefTable.Reg2[ConfigMode]) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0x5c, 5, 3, ConfigRefTable.Reg3[ConfigMode]) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xd0, 3, 2, ConfigRefTable.Reg4[ConfigMode]) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xd1, 14, 0, Reg5) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xd3, 14, 0, Reg6) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++    if(pDemod->SetRegMaskBits(pDemod, 0xd5, 14, 0, Reg7) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_registers:
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Get minimum-weighted-BER configuration mode for Function 1.
++
++One can use rtl2832_func1_GetMinWeightedBerConfigMode() to get minimum-weighted-BER configuration mode for Function 1.
++
++
++@param [in]    pDemod        The demod module pointer
++@param [out]   pConfigMode   Pointer to an allocated memory for storing configuration mode answer
++
++
++@retval   FUNCTION_SUCCESS   Get minimum-weighted-BER configuration mode for Function 1 successfully.
++@retval   FUNCTION_ERROR     Get minimum-weighted-BER configuration mode for Function 1 unsuccessfully.
++
++*/
++void
++rtl2832_func1_GetMinWeightedBerConfigMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pConfigMode
++	)
++{
++	RTL2832_EXTRA_MODULE *pExtra;
++
++	unsigned long WeightedBerNormal;
++	unsigned long WeightedBerConfig1;
++	unsigned long WeightedBerConfig2;
++	unsigned long WeightedBerConfig3;
++
++
++
++	// Get demod extra module.
++	pExtra = (RTL2832_EXTRA_MODULE *)pDemod->pExtra;
++
++
++	// Calculate weighted BER for all configuration mode
++	WeightedBerNormal  = pExtra->Func1RsdBerEstSumNormal * 2;
++	WeightedBerConfig1 = pExtra->Func1RsdBerEstSumConfig1;
++	WeightedBerConfig2 = pExtra->Func1RsdBerEstSumConfig2;
++	WeightedBerConfig3 = pExtra->Func1RsdBerEstSumConfig3;
++
++
++	// Determine minimum-weighted-BER configuration mode.
++	if(WeightedBerNormal <= WeightedBerConfig1 &&
++		WeightedBerNormal <= WeightedBerConfig2 &&
++		WeightedBerNormal <= WeightedBerConfig3)
++	{
++		*pConfigMode = RTL2832_FUNC1_CONFIG_NORMAL;
++	}
++	else if(WeightedBerConfig1 <= WeightedBerNormal &&
++		WeightedBerConfig1 <= WeightedBerConfig2 &&
++		WeightedBerConfig1 <= WeightedBerConfig3)
++	{
++		*pConfigMode = RTL2832_FUNC1_CONFIG_1;
++	}
++	else if(WeightedBerConfig2 <= WeightedBerNormal &&
++		WeightedBerConfig2 <= WeightedBerConfig1 &&
++		WeightedBerConfig2 <= WeightedBerConfig3)
++	{
++		*pConfigMode = RTL2832_FUNC1_CONFIG_2;
++	}
++	else if(WeightedBerConfig3 <= WeightedBerNormal &&
++		WeightedBerConfig3 <= WeightedBerConfig1 &&
++		WeightedBerConfig3 <= WeightedBerConfig2)
++	{
++		*pConfigMode = RTL2832_FUNC1_CONFIG_3;
++	}
++
++
++	return;
++}
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/demod_rtl2832.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/demod_rtl2832.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,542 @@
++#ifndef __DEMOD_RTL2832_H
++#define __DEMOD_RTL2832_H
++
++/**
++
++@file
++
++@brief   RTL2832 demod module declaration
++
++One can manipulate RTL2832 demod through RTL2832 module.
++RTL2832 module is derived from DVB-T demod module.
++
++
++
++@par Example:
++@code
++
++// The example is the same as the DVB-T demod example in dvbt_demod_base.h except the listed lines.
++
++
++
++#include "demod_rtl2832.h"
++
++
++...
++
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++
++	DVBT_DEMOD_MODULE     DvbtDemodModuleMemory;
++	RTL2832_EXTRA_MODULE  Rtl2832ExtraModuleMemory;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++	I2C_BRIDGE_MODULE     I2cBridgeModuleMemory;
++
++
++	...
++
++
++
++	// Build RTL2832 demod module.
++	BuildRtl2832Module(
++		&pDemod,
++		&DvbtDemodModuleMemory,
++		&Rtl2832ExtraModuleMemory,
++		&BaseInterfaceModuleMemory,
++		&I2cBridgeModuleMemory,
++		0x20,								// I2C device address is 0x20 in 8-bit format.
++		CRYSTAL_FREQ_28800000HZ,			// Crystal frequency is 28.8 MHz.
++		RTL2832_APPLICATION_STB				// Application mode is STB.
++		50,									// Update function reference period is 50 millisecond
++		ON									// Function 1 enabling status is on.
++		);
++
++
++
++	// See the example for other DVB-T demod functions in dvbt_demod_base.h
++
++	...
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++#include "dvbt_demod_base.h"
++
++
++
++
++
++// Definitions
++
++// Initializing
++#define RTL2832_INIT_TABLE_LEN						31
++#define RTL2832_INIT_TABLE_LEN_WITH_APP_MODE		5
++
++
++// Bandwidth setting
++#define RTL2832_H_LPF_X_PAGE		1
++#define RTL2832_H_LPF_X_ADDR		0x1c
++#define RTL2832_H_LPF_X_LEN			32
++#define RTL2832_RATIO_PAGE			1
++#define RTL2832_RATIO_ADDR			0x9d
++#define RTL2832_RATIO_LEN			6
++
++
++// Bandwidth setting
++#define RTL2832_CFREQ_OFF_RATIO_BIT_NUM		20
++
++
++// IF frequency setting
++#define RTL2832_PSET_IFFREQ_BIT_NUM		22
++
++
++// Signal quality
++#define RTL2832_SQ_FRAC_BIT_NUM			5
++
++
++// BER
++#define RTL2832_BER_DEN_VALUE				1000000
++
++
++// SNR
++#define RTL2832_CE_EST_EVM_MAX_VALUE		65535
++#define RTL2832_SNR_FRAC_BIT_NUM			10
++#define RTL2832_SNR_DB_DEN					3402
++
++
++// AGC
++#define RTL2832_RF_AGC_REG_BIT_NUM		14
++#define RTL2832_IF_AGC_REG_BIT_NUM		14
++
++
++// TR offset and CR offset
++#define RTL2832_SFREQ_OFF_BIT_NUM		14
++#define RTL2832_CFREQ_OFF_BIT_NUM		18
++
++
++// Register table length
++#define RTL2832_REG_TABLE_LEN			112
++
++
++// Function 1
++#define RTL2832_FUNC1_WAIT_TIME_MS			500
++#define RTL2832_FUNC1_GETTING_TIME_MS		200
++#define RTL2832_FUNC1_GETTING_NUM_MIN		20
++
++
++
++/// Demod application modes
++enum RTL2832_APPLICATION_MODE
++{
++	RTL2832_APPLICATION_DONGLE,
++	RTL2832_APPLICATION_STB,
++};
++#define RTL2832_APPLICATION_MODE_NUM		2
++
++
++// Function 1
++enum RTL2832_FUNC1_CONFIG_MODE
++{
++	RTL2832_FUNC1_CONFIG_1,
++	RTL2832_FUNC1_CONFIG_2,
++	RTL2832_FUNC1_CONFIG_3,
++};
++#define RTL2832_FUNC1_CONFIG_MODE_NUM		3
++#define RTL2832_FUNC1_CONFIG_NORMAL			-1
++
++
++enum RTL2832_FUNC1_STATE
++{
++	RTL2832_FUNC1_STATE_NORMAL,
++	RTL2832_FUNC1_STATE_NORMAL_GET_BER,
++	RTL2832_FUNC1_STATE_CONFIG_1_WAIT,
++	RTL2832_FUNC1_STATE_CONFIG_1_GET_BER,
++	RTL2832_FUNC1_STATE_CONFIG_2_WAIT,
++	RTL2832_FUNC1_STATE_CONFIG_2_GET_BER,
++	RTL2832_FUNC1_STATE_CONFIG_3_WAIT,
++	RTL2832_FUNC1_STATE_CONFIG_3_GET_BER,
++	RTL2832_FUNC1_STATE_DETERMINED_WAIT,
++	RTL2832_FUNC1_STATE_DETERMINED,
++};
++
++
++
++
++
++/// RTL2832 extra module
++typedef struct RTL2832_EXTRA_MODULE_TAG RTL2832_EXTRA_MODULE;
++
++
++
++
++
++/*
++
++@brief   RTL2832 application mode getting function pointer
++
++One can use RTL2832_FP_GET_APP_MODE() to get RTL2832 application mode.
++
++
++@param [in]    pDemod     The demod module pointer
++@param [out]   pAppMode   Pointer to an allocated memory for storing demod application mode
++
++
++@retval   FUNCTION_SUCCESS   Get demod application mode successfully.
++@retval   FUNCTION_ERROR     Get demod application mode unsuccessfully.
++
++
++@note
++	-# Demod building function will set RTL2832_FP_GET_APP_MODE() with the corresponding function.
++
++
++@see   RTL2832_APPLICATION_MODE
++
++*/
++typedef void
++(*RTL2832_FP_GET_APP_MODE)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAppMode
++	);
++
++
++
++
++
++struct RTL2832_EXTRA_MODULE_TAG
++{
++	// RTL2832 extra variables
++	int AppMode;
++
++	// RTL2832 update procedure enabling status
++	int IsFunc1Enabled;
++
++	// RTL2832 update Function 1 variables
++	int Func1State;
++
++	int Func1WaitTimeMax;
++	int Func1GettingTimeMax;
++	int Func1GettingNumEachTime;
++
++	int Func1WaitTime;
++	int Func1GettingTime;
++
++	unsigned long Func1RsdBerEstSumNormal;
++	unsigned long Func1RsdBerEstSumConfig1;
++	unsigned long Func1RsdBerEstSumConfig2;
++	unsigned long Func1RsdBerEstSumConfig3;
++
++	int Func1QamBak;
++	int Func1HierBak;
++	int Func1LpCrBak;
++	int Func1HpCrBak;
++	int Func1GiBak;
++	int Func1FftBak;
++
++
++	// RTL2832 extra function pointers
++	RTL2832_FP_GET_APP_MODE GetAppMode;
++};
++
++
++
++
++
++// Demod module builder
++void
++BuildRtl2832Module(
++	DVBT_DEMOD_MODULE **ppDemod,
++	DVBT_DEMOD_MODULE *pDvbtDemodModuleMemory,
++	RTL2832_EXTRA_MODULE *pRtl2832ExtraModuleMemory,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory,
++	unsigned char DeviceAddr,
++	unsigned long CrystalFreqHz,
++	int AppMode,
++	unsigned long UpdateFuncRefPeriodMs,
++	int IsFunc1Enabled
++	);
++
++
++
++
++
++// Manipulating functions
++void
++rtl2832_IsConnectedToI2c(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAnswer
++);
++
++int
++rtl2832_SoftwareReset(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++int
++rtl2832_Initialize(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++int
++rtl2832_SetBandwidthMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int BandwidthMode
++	);
++
++int
++rtl2832_SetIfFreqHz(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long IfFreqHz
++	);
++
++int
++rtl2832_SetSpectrumMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int SpectrumMode
++	);
++
++int
++rtl2832_IsTpsLocked(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAnswer
++	);
++
++int
++rtl2832_IsSignalLocked(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAnswer
++	);
++
++int
++rtl2832_GetSignalStrength(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pSignalStrength
++	);
++
++int
++rtl2832_GetSignalQuality(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pSignalQuality
++	);
++
++int
++rtl2832_GetBer(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pBerNum,
++	unsigned long *pBerDen
++	);
++
++int
++rtl2832_GetSnrDb(
++	DVBT_DEMOD_MODULE *pDemod,
++	long *pSnrDbNum,
++	long *pSnrDbDen
++	);
++
++int
++rtl2832_GetRfAgc(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pRfAgc
++	);
++
++int
++rtl2832_GetIfAgc(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pIfAgc
++	);
++
++int
++rtl2832_GetDiAgc(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char *pDiAgc
++	);
++
++int
++rtl2832_GetTrOffsetPpm(
++	DVBT_DEMOD_MODULE *pDemod,
++	long *pTrOffsetPpm
++	);
++
++int
++rtl2832_GetCrOffsetHz(
++	DVBT_DEMOD_MODULE *pDemod,
++	long *pCrOffsetHz
++	);
++
++int
++rtl2832_GetConstellation(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pConstellation
++	);
++
++int
++rtl2832_GetHierarchy(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pHierarchy
++	);
++
++int
++rtl2832_GetCodeRateLp(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pCodeRateLp
++	);
++
++int
++rtl2832_GetCodeRateHp(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pCodeRateHp
++	);
++
++int
++rtl2832_GetGuardInterval(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pGuardInterval
++	);
++
++int
++rtl2832_GetFftMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pFftMode
++	);
++
++int
++rtl2832_UpdateFunction(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++int
++rtl2832_ResetFunction(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++
++
++
++
++// I2C command forwarding functions
++int
++rtl2832_ForwardI2cReadingCmd(
++	I2C_BRIDGE_MODULE *pI2cBridge,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	);
++
++int
++rtl2832_ForwardI2cWritingCmd(
++	I2C_BRIDGE_MODULE *pI2cBridge,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	);
++
++
++
++
++
++// Register table initializing
++void
++rtl2832_InitRegTable(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++
++
++
++
++// I2C birdge module demod argument setting
++void
++rtl2832_SetI2cBridgeModuleDemodArg(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++
++
++
++
++// RTL2832 extra functions
++void
++rtl2832_GetAppMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAppMode
++	);
++
++
++
++
++
++// RTL2832 dependence
++int
++rtl2832_func1_Reset(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++int
++rtl2832_func1_Update(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++int
++rtl2832_func1_IsCriterionMatched(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAnswer
++	);
++
++int
++rtl2832_func1_AccumulateRsdBerEst(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pAccumulativeValue
++	);
++
++int
++rtl2832_func1_ResetReg(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++int
++rtl2832_func1_SetCommonReg(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++int
++rtl2832_func1_SetRegWithFftMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int FftMode
++	);
++
++int
++rtl2832_func1_SetRegWithConfigMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int ConfigMode
++	);
++
++void
++rtl2832_func1_GetMinWeightedBerConfigMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pConfigMode
++	);
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++#endif
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/dvbt_demod_base.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/dvbt_demod_base.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,689 @@
++/**
++
++@file
++
++@brief   DVB-T demod default function definition
++
++DVB-T demod default functions.
++
++*/
++
++#include "dvbt_demod_base.h"
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_SET_REG_PAGE
++
++*/
++int
++dvbt_demod_default_SetRegPage(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long PageNo
++	)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	struct dvb_usb_device	*d;
++
++	// Get base interface.
++	pBaseInterface = pDemod->pBaseInterface;
++	
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);  //add by chialing
++
++	if( mutex_lock_interruptible(&d->usb_mutex) )	goto error;
++
++	 pDemod->PageNo = PageNo;
++
++	mutex_unlock(&d->usb_mutex);
++	
++	return FUNCTION_SUCCESS;
++
++error:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_SET_REG_BYTES
++
++*/
++int
++dvbt_demod_default_SetRegBytes(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	unsigned int i, j;
++
++	unsigned char DeviceAddr;
++	unsigned char WritingBuffer[I2C_BUFFER_LEN];
++	unsigned char WritingByteNum, WritingByteNumMax, WritingByteNumRem;
++	unsigned char RegWritingAddr;
++	
++	struct dvb_usb_device	*d;
++
++	// Get base interface.
++	pBaseInterface = pDemod->pBaseInterface;
++	
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);  //add by chialing
++
++	// Get demod I2C device address.
++	pDemod->GetDeviceAddr(pDemod, &DeviceAddr);
++
++
++	// Calculate maximum writing byte number.
++	WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE;
++
++
++	// Set demod register bytes with writing bytes.
++	// Note: Set demod register bytes considering maximum writing byte number.
++	for(i = 0; i < ByteNum; i += WritingByteNumMax)
++	{
++		// Set register writing address.
++		RegWritingAddr = RegStartAddr + i;
++
++		// Calculate remainder writing byte number.
++		WritingByteNumRem = ByteNum - i;
++
++		// Determine writing byte number.
++		WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem;
++
++
++		// Set writing buffer.
++		// Note: The I2C format of demod register byte setting is as follows:
++		//       start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + stop_bit
++//		WritingBuffer[0] = RegWritingAddr;
++
++		for(j = 0; j < WritingByteNum; j++)
++//			WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j];
++			WritingBuffer[j] = pWritingBytes[i + j];
++
++		// Set demod register bytes with writing buffer.
++//		if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) !=
++//			FUNCTION_SUCCESS)
++//			goto error_status_set_demod_registers;
++
++		if(write_rtl2832_demod_register( d, DeviceAddr, pDemod->PageNo, RegWritingAddr, WritingBuffer, WritingByteNum )) goto error;
++
++		
++	}
++
++
++	return FUNCTION_SUCCESS;
++error:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_REG_BYTES
++
++*/
++int
++dvbt_demod_default_GetRegBytes(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	unsigned int i;
++	unsigned char DeviceAddr;
++	unsigned char ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem;
++	unsigned char RegReadingAddr;
++
++	struct dvb_usb_device	*d;
++
++	// Get base interface.
++	pBaseInterface = pDemod->pBaseInterface;
++
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);  //add by chialing
++
++	// Get demod I2C device address.
++	pDemod->GetDeviceAddr(pDemod, &DeviceAddr);
++
++
++	// Calculate maximum reading byte number.
++	ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax;
++
++
++	// Get demod register bytes.
++	// Note: Get demod register bytes considering maximum reading byte number.
++	for(i = 0; i < ByteNum; i += ReadingByteNumMax)
++	{
++		// Set register reading address.
++		RegReadingAddr = RegStartAddr + i;
++
++		// Calculate remainder reading byte number.
++		ReadingByteNumRem = ByteNum - i;
++
++		// Determine reading byte number.
++		ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem;
++
++
++		// Set demod register reading address.
++		// Note: The I2C format of demod register reading address setting is as follows:
++		//       start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit
++//		if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS)
++//			goto error_status_set_demod_register_reading_address;
++
++		// Get demod register bytes.
++		// Note: The I2C format of demod register byte getting is as follows:
++		//       start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit
++//		if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS)
++//			goto error_status_get_demod_registers;
++
++
++		if(read_rtl2832_demod_register(d, DeviceAddr, pDemod->PageNo, RegReadingAddr, &pReadingBytes[i], ReadingByteNum)) goto error;
++
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++error:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_SET_REG_MASK_BITS
++
++*/
++int
++dvbt_demod_default_SetRegMaskBits(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	unsigned char Msb,
++	unsigned char Lsb,
++	const unsigned long WritingValue
++	)
++{
++	int i;
++
++	unsigned char ReadingBytes[LEN_4_BYTE];
++	unsigned char WritingBytes[LEN_4_BYTE];
++
++	unsigned char ByteNum;
++	unsigned long Mask;
++	unsigned char Shift;
++
++	unsigned long Value;
++
++
++	// Calculate writing byte number according to MSB.
++	ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE;
++
++
++	// Generate mask and shift according to MSB and LSB.
++	Mask = 0;
++
++	for(i = Lsb; i < (unsigned char)(Msb + 1); i++)
++		Mask |= 0x1 << i;
++
++	Shift = Lsb;
++
++
++	// Get demod register bytes according to register start adddress and byte number.
++	if(pDemod->GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS)
++		goto error_status_get_demod_registers;
++
++
++	// Combine reading bytes into an unsigned integer value.
++	// Note: Put lower address byte on value MSB.
++	//       Put upper address byte on value LSB.
++	Value = 0;
++
++	for(i = 0; i < ByteNum; i++)
++		Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * (ByteNum - i -1));
++
++
++	// Reserve unsigned integer value unmask bit with mask and inlay writing value into it.
++	Value &= ~Mask;
++	Value |= (WritingValue << Shift) & Mask;
++
++
++	// Separate unsigned integer value into writing bytes.
++	// Note: Pick up lower address byte from value MSB.
++	//       Pick up upper address byte from value LSB.
++	for(i = 0; i < ByteNum; i++)
++		WritingBytes[i] = (unsigned char)((Value >> (BYTE_SHIFT * (ByteNum - i -1))) & BYTE_MASK);
++
++
++	// Write demod register bytes with writing bytes.
++	if(pDemod->SetRegBytes(pDemod, RegStartAddr, WritingBytes, ByteNum) != FUNCTION_SUCCESS)
++		goto error_status_set_demod_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_demod_registers:
++error_status_set_demod_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_REG_MASK_BITS
++
++*/
++int
++dvbt_demod_default_GetRegMaskBits(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	unsigned char Msb,
++	unsigned char Lsb,
++	unsigned long *pReadingValue
++	)
++{
++	int i;
++
++	unsigned char ReadingBytes[LEN_4_BYTE];
++
++	unsigned char ByteNum;
++	unsigned long Mask;
++	unsigned char Shift;
++
++	unsigned long Value;
++
++
++	// Calculate writing byte number according to MSB.
++	ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE;
++
++
++	// Generate mask and shift according to MSB and LSB.
++	Mask = 0;
++
++	for(i = Lsb; i < (unsigned char)(Msb + 1); i++)
++		Mask |= 0x1 << i;
++
++	Shift = Lsb;
++
++
++	// Get demod register bytes according to register start adddress and byte number.
++	if(pDemod->GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS)
++		goto error_status_get_demod_registers;
++
++
++	// Combine reading bytes into an unsigned integer value.
++	// Note: Put lower address byte on value MSB.
++	//       Put upper address byte on value LSB.
++	Value = 0;
++
++	for(i = 0; i < ByteNum; i++)
++		Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * (ByteNum - i -1));
++
++
++	// Get register bits from unsigned integaer value with mask and shift
++	*pReadingValue = (Value & Mask) >> Shift;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_demod_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_SET_REG_BITS
++
++*/
++int
++dvbt_demod_default_SetRegBits(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	const unsigned long WritingValue
++	)
++{
++	unsigned char RegStartAddr;
++	unsigned char Msb;
++	unsigned char Lsb;
++
++
++	// Check if register bit name is available.
++	if(pDemod->RegTable[RegBitName].IsAvailable == NO)
++		goto error_status_register_bit_name;
++
++
++	// Get register start address, MSB, and LSB from register table with register bit name key.
++	RegStartAddr = pDemod->RegTable[RegBitName].RegStartAddr;
++	Msb          = pDemod->RegTable[RegBitName].Msb;
++	Lsb          = pDemod->RegTable[RegBitName].Lsb;
++
++
++	// Set register mask bits.
++	if(pDemod->SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS)
++		goto error_status_set_demod_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_register_bit_name:
++error_status_set_demod_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_REG_BITS
++
++*/
++int
++dvbt_demod_default_GetRegBits(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	unsigned long *pReadingValue
++	)
++{
++	unsigned char RegStartAddr;
++	unsigned char Msb;
++	unsigned char Lsb;
++
++
++	// Check if register bit name is available.
++	if(pDemod->RegTable[RegBitName].IsAvailable == NO)
++		goto error_status_register_bit_name;
++
++
++	// Get register start address, MSB, and LSB from register table with register bit name key.
++	RegStartAddr = pDemod->RegTable[RegBitName].RegStartAddr;
++	Msb          = pDemod->RegTable[RegBitName].Msb;
++	Lsb          = pDemod->RegTable[RegBitName].Lsb;
++
++
++	// Get register mask bits.
++	if(pDemod->GetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, pReadingValue) != FUNCTION_SUCCESS)
++		goto error_status_get_demod_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_register_bit_name:
++error_status_get_demod_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE
++
++*/
++int
++dvbt_demod_default_SetRegBitsWithPage(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	const unsigned long WritingValue
++	)
++{
++	unsigned long PageNo;
++
++
++	// Get register page number from register table with register bit name key.
++	PageNo = pDemod->RegTable[RegBitName].PageNo;
++
++
++	// Set register page number.
++	if(pDemod->SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS)
++		goto error_status_set_demod_registers;
++
++
++	// Set register mask bits with register bit name key.
++	if(pDemod->SetRegBits(pDemod, RegBitName, WritingValue) != FUNCTION_SUCCESS)
++		goto error_status_set_demod_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_demod_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE
++
++*/
++int
++dvbt_demod_default_GetRegBitsWithPage(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	unsigned long *pReadingValue
++	)
++{
++	unsigned long PageNo;
++
++
++	// Get register page number from register table with register bit name key.
++	PageNo = pDemod->RegTable[RegBitName].PageNo;
++
++
++	// Set register page number.
++	if(pDemod->SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS)
++		goto error_status_set_demod_registers;
++
++
++	// Get register mask bits with register bit name key.
++	if(pDemod->GetRegBits(pDemod, RegBitName, pReadingValue) != FUNCTION_SUCCESS)
++		goto error_status_get_demod_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_demod_registers:
++error_status_get_demod_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_DEMOD_TYPE
++
++*/
++void
++dvbt_demod_default_GetDemodType(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pDemodType
++	)
++{
++	// Get demod type from demod module.
++	*pDemodType = pDemod->DemodType;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_DEVICE_ADDR
++
++*/
++void
++dvbt_demod_default_GetDeviceAddr(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char *pDeviceAddr
++	)
++{
++	// Get demod I2C device address from demod module.
++	*pDeviceAddr = pDemod->DeviceAddr;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ
++
++*/
++void
++dvbt_demod_default_GetCrystalFreqHz(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pCrystalFreqHz
++	)
++{
++	// Get demod crystal frequency in Hz from demod module.
++	*pCrystalFreqHz = pDemod->CrystalFreqHz;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_BANDWIDTH_MODE
++
++*/
++int
++dvbt_demod_default_GetBandwidthMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pBandwidthMode
++	)
++{
++	// Get demod bandwidth mode from demod module.
++	if(pDemod->IsBandwidthModeSet != YES)
++		goto error_status_get_demod_bandwidth_mode;
++
++	*pBandwidthMode = pDemod->BandwidthMode;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_demod_bandwidth_mode:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_IF_FREQ_HZ
++
++*/
++int
++dvbt_demod_default_GetIfFreqHz(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pIfFreqHz
++	)
++{
++	// Get demod IF frequency in Hz from demod module.
++	if(pDemod->IsIfFreqHzSet != YES)
++		goto error_status_get_demod_if_frequency;
++
++	*pIfFreqHz = pDemod->IfFreqHz;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_demod_if_frequency:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_DEMOD_FP_GET_SPECTRUM_MODE
++
++*/
++int
++dvbt_demod_default_GetSpectrumMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pSpectrumMode
++	)
++{
++	// Get demod spectrum mode from demod module.
++	if(pDemod->IsSpectrumModeSet != YES)
++		goto error_status_get_demod_spectrum_mode;
++
++	*pSpectrumMode = pDemod->SpectrumMode;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_demod_spectrum_mode:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++
++
++
++
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/dvbt_demod_base.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/dvbt_demod_base.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,2547 @@
++#ifndef __DVBT_DEMOD_BASE_H
++#define __DVBT_DEMOD_BASE_H
++
++/**
++
++@file
++
++@brief   DVB-T demod base module definition
++
++DVB-T demod base module definitions contains demod module structure, demod funciton pointers, and demod definitions.
++
++
++
++@par Example:
++@code
++
++
++#include "demod_xxx.h"
++
++
++
++int
++CustomI2cRead(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	)
++{
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++	return FUNCTION_ERROR;
++}
++
++
++
++int
++CustomI2cWrite(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	)
++{
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++	return FUNCTION_ERROR;
++}
++
++
++
++void
++CustomWaitMs(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned long WaitTimeMs
++	)
++{
++	...
++}
++
++
++
++int main(void)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE DvbtDemodModuleMemory;
++
++	I2C_BRIDGE_MODULE I2cBridgeModuleMemory;
++
++	int BandwidthMode;
++	unsigned long IfFreqHz;
++	int SpectrumMode;
++
++	int DemodType;
++	unsigned char DeviceAddr;
++	unsigned long CrystalFreqHz;
++
++	long RfAgc, IfAgc;
++	unsigned long DiAgc;
++
++	int Answer;
++	long TrOffsetPpm, CrOffsetHz;
++	unsigned long BerNum, BerDen;
++	double Ber;
++	long SnrDbNum, SnrDbDen;
++	double SnrDb;
++	unsigned long SignalStrength, SignalQuality;
++
++	int Constellation;
++	int Hierarchy;
++	int CodeRateLp;
++	int CodeRateHp;
++	int GuardInterval;
++	int FftMode;
++
++
++
++	// Build base interface module.
++	BuildBaseInterface(
++		&pBaseInterface,
++		&BaseInterfaceModuleMemory,
++		9,								// Set maximum I2C reading byte number with 9.
++		8,								// Set maximum I2C writing byte number with 8.
++		CustomI2cRead,					// Employ CustomI2cRead() as basic I2C reading function.
++		CustomI2cWrite,					// Employ CustomI2cWrite() as basic I2C writing function.
++		CustomWaitMs					// Employ CustomWaitMs() as basic waiting function.
++		);
++
++
++	// Build DVB-T demod XXX module.
++	BuildXxxModule(
++		&pDemod,
++		&DvbtDemodModuleMemory,
++		&BaseInterfaceModuleMemory,
++		&I2cBridgeModuleMemory,
++		0x20,							// Demod I2C device address is 0x20 in 8-bit format.
++		CRYSTAL_FREQ_28800000HZ,		// Demod crystal frequency is 28.8 MHz.
++		...								// Other arguments by each demod module
++		);
++
++
++
++
++
++	// ==== Initialize DVB-T demod and set its parameters =====
++
++	// Initialize demod.
++	pDemod->Initialize(pDemod);
++
++
++	// Set demod parameters. (bandwidth mode, IF frequency, spectrum mode)
++	// Note: In the example:
++	//       1. Bandwidth mode is 8 MHz.
++	//       2. IF frequency is 36.125 MHz.
++	//       3. Spectrum mode is SPECTRUM_INVERSE.
++	BandwidthMode = DVBT_BANDWIDTH_8MHZ;
++	IfFreqHz      = IF_FREQ_36125000HZ;
++	SpectrumMode  = SPECTRUM_INVERSE;
++
++	pDemod->SetBandwidthMode(pDemod, BandwidthMode);
++	pDemod->SetIfFreqHz(pDemod,      IfFreqHz);
++	pDemod->SetSpectrumMode(pDemod,  SpectrumMode);
++
++
++	// Need to set tuner before demod software reset.
++	// The order to set demod and tuner is not important.
++	// Note: One can use "pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1);"
++	//       for tuner I2C command forwarding.
++
++
++	// Reset demod by software reset.
++	pDemod->SoftwareReset(pDemod);
++
++
++	// Wait maximum 1000 ms for demod converge.
++	for(i = 0; i < 25; i++)
++	{
++		// Wait 40 ms.
++		pBaseInterface->WaitMs(pBaseInterface, 40);
++
++		// Check signal lock status.
++		// Note: If Answer is YES, signal is locked.
++		//       If Answer is NO, signal is not locked.
++		pDemod->IsSignalLocked(pDemod, &Answer);
++
++		if(Answer == YES)
++		{
++			// Signal is locked.
++			break;
++		}
++	}
++
++
++
++
++
++	// ==== Get DVB-T demod information =====
++
++	// Get demod type.
++	// Note: One can find demod type in MODULE_TYPE enumeration.
++	pDemod->GetDemodType(pDemod, &DemodType);
++
++	// Get demod I2C device address.
++	pDemod->GetDeviceAddr(pDemod, &DeviceAddr);
++
++	// Get demod crystal frequency in Hz.
++	pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz);
++
++
++	// Ask demod if it is connected to I2C bus.
++	// Note: If Answer is YES, demod is connected to I2C bus.
++	//       If Answer is NO, demod is not connected to I2C bus.
++	pDemod->IsConnectedToI2c(pDemod, &Answer);
++
++
++	// Get demod parameters. (bandwidth mode, IF frequency, spectrum mode)
++	pDemod->GetBandwidthMode(pDemod, &BandwidthMode);
++	pDemod->GetIfFreqHz(pDemod,      &IfFreqHz);
++	pDemod->GetSpectrumMode(pDemod,  &SpectrumMode);
++
++
++	// Get demod AGC value.
++	// Note: The range of RF AGC and IF AGC value is -8192 ~ 8191.
++	//       The range of digital AGC value is 0 ~ 255.
++	pDemod->GetRfAgc(pDemod, &RfAgc);
++	pDemod->GetIfAgc(pDemod, &IfAgc);
++	pDemod->GetDiAgc(pDemod, &DiAgc);
++
++
++	// Get demod lock status.
++	// Note: If Answer is YES, it is locked.
++	//       If Answer is NO, it is not locked.
++	pDemod->IsTpsLocked(pDemod,    &Answer);
++	pDemod->IsSignalLocked(pDemod, &Answer);
++
++
++	// Get TR offset (symbol timing offset) in ppm.
++	pDemod->GetTrOffsetPpm(pDemod, &TrOffsetPpm);
++
++	// Get CR offset (RF frequency offset) in Hz.
++	pDemod->GetCrOffsetHz(pDemod, &CrOffsetHz);
++
++
++	// Get BER.
++	pDemod->GetBer(pDemod, &BerNum, &BerDen);
++	Ber = (double)BerNum / (double)BerDen;
++
++	// Get SNR in dB.
++	pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen);
++	SnrDb = (double)SnrDbNum / (double)SnrDbDen;
++
++
++	// Get signal strength.
++	// Note: 1. The range of SignalStrength is 0~100.
++	//       2. Need to map SignalStrength value to UI signal strength bar manually.
++	pDemod->GetSignalStrength(pDemod, &SignalStrength);
++
++	// Get signal quality.
++	// Note: 1. The range of SignalQuality is 0~100.
++	//       2. Need to map SignalQuality value to UI signal quality bar manually.
++	pDemod->GetSignalQuality(pDemod, &SignalQuality);
++
++
++	// Get TPS information.
++	// Note: One can find TPS information definitions in the enumerations as follows:
++	//       1. DVBT_CONSTELLATION_MODE.
++	//       2. DVBT_HIERARCHY_MODE.
++	//       3. DVBT_CODE_RATE_MODE. (for low-priority and high-priority code rate)
++	//       4. DVBT_GUARD_INTERVAL_MODE.
++	//       5. DVBT_FFT_MODE_MODE
++	pDemod->GetConstellation(pDemod, &Constellation);
++	pDemod->GetHierarchy(pDemod,     &Hierarchy);
++	pDemod->GetCodeRateLp(pDemod,    &CodeRateLp);
++	pDemod->GetCodeRateHp(pDemod,    &CodeRateHp);
++	pDemod->GetGuardInterval(pDemod, &GuardInterval);
++	pDemod->GetFftMode(pDemod,       &FftMode);
++
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++#include "foundation.h"
++
++
++
++
++
++// Definitions
++
++// Page register address
++#define DVBT_DEMOD_PAGE_REG_ADDR		0x00
++
++
++// Bandwidth modes
++#define DVBT_BANDWIDTH_NONE			-1
++enum DVBT_BANDWIDTH_MODE
++{
++	DVBT_BANDWIDTH_6MHZ,
++	DVBT_BANDWIDTH_7MHZ,
++	DVBT_BANDWIDTH_8MHZ,
++};
++#define DVBT_BANDWIDTH_MODE_NUM		3
++
++
++// Constellation
++enum DVBT_CONSTELLATION_MODE
++{
++	DVBT_CONSTELLATION_QPSK,
++	DVBT_CONSTELLATION_16QAM,
++	DVBT_CONSTELLATION_64QAM,
++};
++#define DVBT_CONSTELLATION_NUM		3
++
++
++// Hierarchy
++enum DVBT_HIERARCHY_MODE
++{
++	DVBT_HIERARCHY_NONE,
++	DVBT_HIERARCHY_ALPHA_1,
++	DVBT_HIERARCHY_ALPHA_2,
++	DVBT_HIERARCHY_ALPHA_4,
++};
++#define DVBT_HIERARCHY_NUM			4
++
++
++// Code rate
++enum DVBT_CODE_RATE_MODE
++{
++	DVBT_CODE_RATE_1_OVER_2,
++	DVBT_CODE_RATE_2_OVER_3,
++	DVBT_CODE_RATE_3_OVER_4,
++	DVBT_CODE_RATE_5_OVER_6,
++	DVBT_CODE_RATE_7_OVER_8,
++};
++#define DVBT_CODE_RATE_NUM			5
++
++
++// Guard interval
++enum DVBT_GUARD_INTERVAL_MODE
++{
++	DVBT_GUARD_INTERVAL_1_OVER_32,
++	DVBT_GUARD_INTERVAL_1_OVER_16,
++	DVBT_GUARD_INTERVAL_1_OVER_8,
++	DVBT_GUARD_INTERVAL_1_OVER_4,
++};
++#define DVBT_GUARD_INTERVAL_NUM		4
++
++
++// FFT mode
++enum DVBT_FFT_MODE_MODE
++{
++	DVBT_FFT_MODE_2K,
++	DVBT_FFT_MODE_8K,
++};
++#define DVBT_FFT_MODE_NUM			2
++
++
++
++
++
++// Register entry definitions
++
++// Register entry
++typedef struct
++{
++	int IsAvailable;
++	unsigned long PageNo;
++	unsigned char RegStartAddr;
++	unsigned char Msb;
++	unsigned char Lsb;
++}
++DVBT_REG_ENTRY;
++
++
++
++// Primary register entry
++typedef struct
++{
++	int RegBitName;
++	unsigned long PageNo;
++	unsigned char RegStartAddr;
++	unsigned char Msb;
++	unsigned char Lsb;
++}
++DVBT_PRIMARY_REG_ENTRY;
++
++
++
++
++
++// Register table dependence
++
++// Demod register bit names
++enum DVBT_REG_BIT_NAME
++{
++	// Software reset register
++	DVBT_SOFT_RST,
++
++	// Tuner I2C forwording register
++	DVBT_IIC_REPEAT,
++
++
++	// Registers for initializing
++	DVBT_TR_WAIT_MIN_8K,
++	DVBT_RSD_BER_FAIL_VAL,
++	DVBT_EN_BK_TRK,
++	DVBT_REG_PI,
++
++	DVBT_REG_PFREQ_1_0,				// For RTL2830 only
++	DVBT_PD_DA8,					// For RTL2830 only
++	DVBT_LOCK_TH,					// For RTL2830 only
++	DVBT_BER_PASS_SCAL,				// For RTL2830 only
++	DVBT_CE_FFSM_BYPASS,			// For RTL2830 only
++	DVBT_ALPHAIIR_N,				// For RTL2830 only
++	DVBT_ALPHAIIR_DIF,				// For RTL2830 only
++	DVBT_EN_TRK_SPAN,				// For RTL2830 only
++	DVBT_LOCK_TH_LEN,				// For RTL2830 only
++	DVBT_CCI_THRE,					// For RTL2830 only
++	DVBT_CCI_MON_SCAL,				// For RTL2830 only
++	DVBT_CCI_M0,					// For RTL2830 only
++	DVBT_CCI_M1,					// For RTL2830 only
++	DVBT_CCI_M2,					// For RTL2830 only
++	DVBT_CCI_M3,					// For RTL2830 only
++	DVBT_SPEC_INIT_0,				// For RTL2830 only
++	DVBT_SPEC_INIT_1,				// For RTL2830 only
++	DVBT_SPEC_INIT_2,				// For RTL2830 only
++
++	DVBT_AD_EN_REG,					// For RTL2832 only
++	DVBT_AD_EN_REG1,				// For RTL2832 only
++	DVBT_EN_BBIN,					// For RTL2832 only
++	DVBT_MGD_THD0,					// For RTL2832 only
++	DVBT_MGD_THD1,					// For RTL2832 only
++	DVBT_MGD_THD2,					// For RTL2832 only
++	DVBT_MGD_THD3,					// For RTL2832 only
++	DVBT_MGD_THD4,					// For RTL2832 only
++	DVBT_MGD_THD5,					// For RTL2832 only
++	DVBT_MGD_THD6,					// For RTL2832 only
++	DVBT_MGD_THD7,					// For RTL2832 only
++	DVBT_EN_CACQ_NOTCH,				// For RTL2832 only
++	DVBT_AD_AV_REF,					// For RTL2832 only
++	DVBT_PIP_ON,					// For RTL2832 only
++	DVBT_SCALE1_B92,				// For RTL2832 only
++	DVBT_SCALE1_B93,				// For RTL2832 only
++	DVBT_SCALE1_BA7,				// For RTL2832 only
++	DVBT_SCALE1_BA9,				// For RTL2832 only
++	DVBT_SCALE1_BAA,				// For RTL2832 only
++	DVBT_SCALE1_BAB,				// For RTL2832 only
++	DVBT_SCALE1_BAC,				// For RTL2832 only
++	DVBT_SCALE1_BB0,				// For RTL2832 only
++	DVBT_SCALE1_BB1,				// For RTL2832 only
++	DVBT_KB_P1,						// For RTL2832 only
++	DVBT_KB_P2,						// For RTL2832 only
++	DVBT_KB_P3,						// For RTL2832 only
++	DVBT_OPT_ADC_IQ,				// For RTL2832 only
++	DVBT_AD_AVI,					// For RTL2832 only
++	DVBT_AD_AVQ,					// For RTL2832 only
++	DVBT_K1_CR_STEP12,				// For RTL2832 only
++
++	// Registers for initializing according to mode
++	DVBT_TRK_KS_P2,
++	DVBT_TRK_KS_I2,
++	DVBT_TR_THD_SET2,
++	DVBT_TRK_KC_P2,
++	DVBT_TRK_KC_I2,
++	DVBT_CR_THD_SET2,
++
++	// Registers for IF setting
++	DVBT_PSET_IFFREQ,
++	DVBT_SPEC_INV,
++
++
++	// Registers for bandwidth programming
++	DVBT_BW_INDEX,					// For RTL2830 only
++
++	DVBT_RSAMP_RATIO,				// For RTL2832 only
++	DVBT_CFREQ_OFF_RATIO,			// For RTL2832 only
++
++
++	// FSM stage register
++	DVBT_FSM_STAGE,
++
++	// TPS content registers
++	DVBT_RX_CONSTEL,
++	DVBT_RX_HIER,
++	DVBT_RX_C_RATE_LP,
++	DVBT_RX_C_RATE_HP,
++	DVBT_GI_IDX,
++	DVBT_FFT_MODE_IDX,
++	
++	// Performance measurement registers
++	DVBT_RSD_BER_EST,
++	DVBT_CE_EST_EVM,
++
++	// AGC registers
++	DVBT_RF_AGC_VAL,
++	DVBT_IF_AGC_VAL,
++	DVBT_DAGC_VAL,
++
++	// TR offset and CR offset registers
++	DVBT_SFREQ_OFF,
++	DVBT_CFREQ_OFF,
++
++
++	// AGC relative registers
++	DVBT_POLAR_RF_AGC,
++	DVBT_POLAR_IF_AGC,
++	DVBT_AAGC_HOLD,
++	DVBT_EN_RF_AGC,
++	DVBT_EN_IF_AGC,
++	DVBT_IF_AGC_MIN,
++	DVBT_IF_AGC_MAX,
++	DVBT_RF_AGC_MIN,
++	DVBT_RF_AGC_MAX,
++	DVBT_IF_AGC_MAN,
++	DVBT_IF_AGC_MAN_VAL,
++	DVBT_RF_AGC_MAN,
++	DVBT_RF_AGC_MAN_VAL,
++	DVBT_DAGC_TRG_VAL,
++
++	DVBT_AGC_TARG_VAL,				// For RTL2830 only
++	DVBT_LOOP_GAIN_3_0,				// For RTL2830 only
++	DVBT_LOOP_GAIN_4,				// For RTL2830 only
++	DVBT_VTOP,						// For RTL2830 only
++	DVBT_KRF,						// For RTL2830 only
++
++	DVBT_AGC_TARG_VAL_0,			// For RTL2832 only
++	DVBT_AGC_TARG_VAL_8_1,			// For RTL2832 only
++	DVBT_AAGC_LOOP_GAIN,			// For RTL2832 only
++	DVBT_LOOP_GAIN2_3_0,			// For RTL2832 only
++	DVBT_LOOP_GAIN2_4,				// For RTL2832 only
++	DVBT_LOOP_GAIN3,				// For RTL2832 only
++	DVBT_VTOP1,						// For RTL2832 only
++	DVBT_VTOP2,						// For RTL2832 only
++	DVBT_VTOP3,						// For RTL2832 only
++	DVBT_KRF1,						// For RTL2832 only
++	DVBT_KRF2,						// For RTL2832 only
++	DVBT_KRF3,						// For RTL2832 only
++	DVBT_KRF4,						// For RTL2832 only
++
++
++	// TS interface registers
++	DVBT_CKOUTPAR,
++	DVBT_CKOUT_PWR,
++	DVBT_SYNC_DUR,
++	DVBT_ERR_DUR,
++	DVBT_SYNC_LVL,
++	DVBT_ERR_LVL,
++	DVBT_VAL_LVL,
++	DVBT_SERIAL,
++	DVBT_SER_LSB,
++	DVBT_CDIV_PH0,
++	DVBT_CDIV_PH1,
++
++	DVBT_CKOUTPAR_PIP,				// For RTL2832 only
++	DVBT_CKOUT_PWR_PIP,				// For RTL2832 only
++	DVBT_SYNC_LVL_PIP,				// For RTL2832 only
++	DVBT_ERR_LVL_PIP,				// For RTL2832 only
++	DVBT_VAL_LVL_PIP,				// For RTL2832 only
++	DVBT_CKOUTPAR_PID,				// For RTL2832 only
++	DVBT_CKOUT_PWR_PID,				// For RTL2832 only
++	DVBT_SYNC_LVL_PID,				// For RTL2832 only
++	DVBT_ERR_LVL_PID,				// For RTL2832 only
++	DVBT_VAL_LVL_PID,				// For RTL2832 only
++
++
++	// FSM state-holding register
++	DVBT_SM_PASS,
++
++	// Registers for function 2 (for RTL2830 only)
++	DVBT_UPDATE_REG_2,
++
++	// Registers for function 3 (for RTL2830 only)
++	DVBT_BTHD_P3,
++	DVBT_BTHD_D3,
++
++	// Registers for function 4 (for RTL2830 only)
++	DVBT_FUNC4_REG0,
++	DVBT_FUNC4_REG1,
++	DVBT_FUNC4_REG2,
++	DVBT_FUNC4_REG3,
++	DVBT_FUNC4_REG4,
++	DVBT_FUNC4_REG5,
++	DVBT_FUNC4_REG6,
++	DVBT_FUNC4_REG7,
++	DVBT_FUNC4_REG8,
++	DVBT_FUNC4_REG9,
++	DVBT_FUNC4_REG10,
++
++	// Registers for functin 5 (for RTL2830 only)
++	DVBT_FUNC5_REG0,
++	DVBT_FUNC5_REG1,
++	DVBT_FUNC5_REG2,
++	DVBT_FUNC5_REG3,
++	DVBT_FUNC5_REG4,
++	DVBT_FUNC5_REG5,
++	DVBT_FUNC5_REG6,
++	DVBT_FUNC5_REG7,
++	DVBT_FUNC5_REG8,
++	DVBT_FUNC5_REG9,
++	DVBT_FUNC5_REG10,
++	DVBT_FUNC5_REG11,
++	DVBT_FUNC5_REG12,
++	DVBT_FUNC5_REG13,
++	DVBT_FUNC5_REG14,
++	DVBT_FUNC5_REG15,
++	DVBT_FUNC5_REG16,
++	DVBT_FUNC5_REG17,
++	DVBT_FUNC5_REG18,
++
++	// AD7 registers (for RTL2832 only)
++	DVBT_AD7_SETTING,
++	DVBT_RSSI_R,
++
++	// ACI detection registers (for RTL2832 only)
++	DVBT_ACI_DET_IND,
++
++	// Test registers for test only
++	DVBT_TEST_REG_1,
++	DVBT_TEST_REG_2,
++	DVBT_TEST_REG_3,
++	DVBT_TEST_REG_4,
++
++	// Item terminator
++	DVBT_REG_BIT_NAME_ITEM_TERMINATOR,
++};
++
++
++
++// Register table length definitions
++#define DVBT_REG_TABLE_LEN_MAX			DVBT_REG_BIT_NAME_ITEM_TERMINATOR
++
++
++
++
++
++// DVB-T demod module pre-definition
++typedef struct DVBT_DEMOD_MODULE_TAG DVBT_DEMOD_MODULE;
++
++
++
++
++
++/**
++
++@brief   DVB-T demod register page setting function pointer
++
++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_PAGE() to set demod register page.
++
++
++@param [in]   pDemod   The demod module pointer
++@param [in]   PageNo   Page number
++
++
++@retval   FUNCTION_SUCCESS   Set register page successfully with page number.
++@retval   FUNCTION_ERROR     Set register page unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_SET_REG_PAGE() with the corresponding function.
++
++
++@par Example:
++@code
++
++
++#include "demod_pseudo.h"
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE AtscDemodModuleMemory;
++	PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory;
++
++
++	// Build pseudo demod module.
++	BuildPseudoDemodModule(&pDemod, &AtscDemodModuleMemory, &PseudoExtraModuleMemory);
++
++	...
++
++	// Set demod register page with page number 2.
++	pDemod->SetRegPage(pDemod, 2);
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_SET_REG_PAGE)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long PageNo
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod register byte setting function pointer
++
++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_BYTES() to set demod register bytes.
++
++
++@param [in]   pDemod          The demod module pointer
++@param [in]   RegStartAddr    Demod register start address
++@param [in]   pWritingBytes   Pointer to writing bytes
++@param [in]   ByteNum         Writing byte number
++
++
++@retval   FUNCTION_SUCCESS   Set demod register bytes successfully with writing bytes.
++@retval   FUNCTION_ERROR     Set demod register bytes unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_SET_REG_BYTES() with the corresponding function.
++	-# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_SET_REG_BYTES().
++
++
++@see   DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_GET_REG_BYTES
++
++
++
++@par Example:
++@code
++
++
++#include "demod_pseudo.h"
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE AtscDemodModuleMemory;
++	PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory;
++	unsigned char WritingBytes[10];
++
++
++	// Build pseudo demod module.
++	BuildPseudoDemodModule(&pDemod, &AtscDemodModuleMemory, &PseudoExtraModuleMemory);
++
++	...
++
++	// Set demod register bytes (page 1, address 0x17 ~ 0x1b) with 5 writing bytes.
++	pDemod->SetRegPage(pDemod, 1);
++	pDemod->SetRegBytes(pDemod, 0x17, WritingBytes, 5);
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_SET_REG_BYTES)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod register byte getting function pointer
++
++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_BYTES() to get demod register bytes.
++
++
++@param [in]    pDemod          The demod module pointer
++@param [in]    RegStartAddr    Demod register start address
++@param [out]   pReadingBytes   Pointer to an allocated memory for storing reading bytes
++@param [in]    ByteNum         Reading byte number
++
++
++@retval   FUNCTION_SUCCESS   Get demod register bytes successfully with reading byte number.
++@retval   FUNCTION_ERROR     Get demod register bytes unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_REG_BYTES() with the corresponding function.
++	-# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_GET_REG_BYTES().
++
++
++@see   DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_SET_REG_BYTES
++
++
++
++@par Example:
++@code
++
++
++#include "demod_pseudo.h"
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE AtscDemodModuleMemory;
++	PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory;
++	unsigned char ReadingBytes[10];
++
++
++	// Build pseudo demod module.
++	BuildPseudoDemodModule(&pDemod, &AtscDemodModuleMemory, &PseudoExtraModuleMemory);
++
++	...
++
++	// Get demod register bytes (page 1, address 0x17 ~ 0x1b) with reading byte number 5.
++	pDemod->SetRegPage(pDemod, 1);
++	pDemod->GetRegBytes(pDemod, 0x17, ReadingBytes, 5);
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_REG_BYTES)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod register mask bits setting function pointer
++
++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_MASK_BITS() to set demod register mask bits.
++
++
++@param [in]   pDemod         The demod module pointer
++@param [in]   RegStartAddr   Demod register start address
++@param [in]   Msb            Mask MSB with 0-based index
++@param [in]   Lsb            Mask LSB with 0-based index
++@param [in]   WritingValue   The mask bits writing value
++
++
++@retval   FUNCTION_SUCCESS   Set demod register mask bits successfully with writing value.
++@retval   FUNCTION_ERROR     Set demod register mask bits unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_SET_REG_MASK_BITS() with the corresponding function.
++	-# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_SET_REG_MASK_BITS().
++	-# The constraints of DVBT_DEMOD_FP_SET_REG_MASK_BITS() function usage are described as follows:
++		-# The mask MSB and LSB must be 0~31.
++		-# The mask MSB must be greater than or equal to LSB.
++
++
++@see   DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_GET_REG_MASK_BITS
++
++
++
++@par Example:
++@code
++
++
++#include "demod_pseudo.h"
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE AtscDemodModuleMemory;
++	PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory;
++
++
++	// Build pseudo demod module.
++	BuildPseudoDemodModule(&pDemod, &AtscDemodModuleMemory, &PseudoExtraModuleMemory);
++
++	...
++
++	// Set demod register bits (page 1, address {0x18, 0x17} [12:5]) with writing value 0x1d.
++	pDemod->SetRegPage(pDemod, 1);
++	pDemod->SetRegMaskBits(pDemod, 0x17, 12, 5, 0x1d);
++
++
++	// Result:
++	//
++	// Writing value = 0x1d = 0001 1101 b
++	// 
++	// Page 1
++	// Register address   0x17          0x18
++	// Register value     xxx0 0011 b   101x xxxx b
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_SET_REG_MASK_BITS)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	unsigned char Msb,
++	unsigned char Lsb,
++	const unsigned long WritingValue
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod register mask bits getting function pointer
++
++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_MASK_BITS() to get demod register mask bits.
++
++
++@param [in]    pDemod          The demod module pointer
++@param [in]    RegStartAddr    Demod register start address
++@param [in]    Msb             Mask MSB with 0-based index
++@param [in]    Lsb             Mask LSB with 0-based index
++@param [out]   pReadingValue   Pointer to an allocated memory for storing reading value
++
++
++@retval   FUNCTION_SUCCESS   Get demod register mask bits successfully.
++@retval   FUNCTION_ERROR     Get demod register mask bits unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_REG_MASK_BITS() with the corresponding function.
++	-# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_GET_REG_MASK_BITS().
++	-# The constraints of DVBT_DEMOD_FP_GET_REG_MASK_BITS() function usage are described as follows:
++		-# The mask MSB and LSB must be 0~31.
++		-# The mask MSB must be greater than or equal to LSB.
++
++
++@see   DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_SET_REG_MASK_BITS
++
++
++
++@par Example:
++@code
++
++
++#include "demod_pseudo.h"
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE AtscDemodModuleMemory;
++	PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory;
++	unsigned long ReadingValue;
++
++
++	// Build pseudo demod module.
++	BuildPseudoDemodModule(&pDemod, &AtscDemodModuleMemory, &PseudoExtraModuleMemory);
++
++	...
++
++	// Get demod register bits (page 1, address {0x18, 0x17} [12:5]).
++	pDemod->SetRegPage(pDemod, 1);
++	pDemod->GetRegMaskBits(pDemod, 0x17, 12, 5, &ReadingValue);
++
++
++	// Result:
++	//
++	// Page 1
++	// Register address   0x18          0x17
++	// Register value     xxx0 0011 b   101x xxxx b
++	//
++	// Reading value = 0001 1101 b = 0x1d
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_REG_MASK_BITS)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	unsigned char Msb,
++	unsigned char Lsb,
++	unsigned long *pReadingValue
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod register bits setting function pointer
++
++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_BITS() to set demod register bits with bit name.
++
++
++@param [in]   pDemod         The demod module pointer
++@param [in]   RegBitName     Pre-defined demod register bit name
++@param [in]   WritingValue   The mask bits writing value
++
++
++@retval   FUNCTION_SUCCESS   Set demod register bits successfully with bit name and writing value.
++@retval   FUNCTION_ERROR     Set demod register bits unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_SET_REG_BITS() with the corresponding function.
++	-# Need to set register page before using DVBT_DEMOD_FP_SET_REG_BITS().
++	-# Register bit names are pre-defined keys for bit access, and one can find these in demod header file.
++
++
++@see   DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_GET_REG_BITS
++
++
++
++@par Example:
++@code
++
++
++#include "demod_pseudo.h"
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE AtscDemodModuleMemory;
++	PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory;
++
++
++	// Build pseudo demod module.
++	BuildPseudoDemodModule(&pDemod, &AtscDemodModuleMemory, &PseudoExtraModuleMemory);
++
++	...
++
++	// Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d.
++	// The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1.
++	pDemod->SetRegPage(pDemod, 1);
++	pDemod->SetRegBits(pDemod, PSEUDO_REG_BIT_NAME, 0x1d);
++
++
++	// Result:
++	//
++	// Writing value = 0x1d = 0001 1101 b
++	// 
++	// Page 1
++	// Register address   0x18          0x17
++	// Register value     xxx0 0011 b   101x xxxx b
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_SET_REG_BITS)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	const unsigned long WritingValue
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod register bits getting function pointer
++
++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_BITS() to get demod register bits with bit name.
++
++
++@param [in]    pDemod          The demod module pointer
++@param [in]    RegBitName      Pre-defined demod register bit name
++@param [out]   pReadingValue   Pointer to an allocated memory for storing reading value
++
++
++@retval   FUNCTION_SUCCESS   Get demod register bits successfully with bit name.
++@retval   FUNCTION_ERROR     Get demod register bits unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_REG_BITS() with the corresponding function.
++	-# Need to set register page before using DVBT_DEMOD_FP_GET_REG_BITS().
++	-# Register bit names are pre-defined keys for bit access, and one can find these in demod header file.
++
++
++@see   DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_SET_REG_BITS
++
++
++
++@par Example:
++@code
++
++
++#include "demod_pseudo.h"
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE AtscDemodModuleMemory;
++	PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory;
++	unsigned long ReadingValue;
++
++
++	// Build pseudo demod module.
++	BuildPseudoDemodModule(&pDemod, &AtscDemodModuleMemory, &PseudoExtraModuleMemory);
++
++	...
++
++	// Get demod register bits with bit name PSEUDO_REG_BIT_NAME.
++	// The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1.
++	pDemod->SetRegPage(pDemod, 1);
++	pDemod->GetRegBits(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue);
++
++
++	// Result:
++	//
++	// Page 1
++	// Register address   0x18          0x17
++	// Register value     xxx0 0011 b   101x xxxx b
++	//
++	// Reading value = 0001 1101 b = 0x1d
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_REG_BITS)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	unsigned long *pReadingValue
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod register bits setting function pointer (with page setting)
++
++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE() to set demod register bits with bit name and
++page setting.
++
++
++@param [in]   pDemod         The demod module pointer
++@param [in]   RegBitName     Pre-defined demod register bit name
++@param [in]   WritingValue   The mask bits writing value
++
++
++@retval   FUNCTION_SUCCESS   Set demod register bits successfully with bit name, page setting, and writing value.
++@retval   FUNCTION_ERROR     Set demod register bits unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE() with the corresponding function.
++	-# Don't need to set register page before using DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE().
++	-# Register bit names are pre-defined keys for bit access, and one can find these in demod header file.
++
++
++@see   DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE
++
++
++
++@par Example:
++@code
++
++
++#include "demod_pseudo.h"
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE AtscDemodModuleMemory;
++	PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory;
++
++
++	// Build pseudo demod module.
++	BuildPseudoDemodModule(&pDemod, &AtscDemodModuleMemory, &PseudoExtraModuleMemory);
++
++	...
++
++	// Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d.
++	// The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1.
++	pDemod->SetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, 0x1d);
++
++
++	// Result:
++	//
++	// Writing value = 0x1d = 0001 1101 b
++	// 
++	// Page 1
++	// Register address   0x18          0x17
++	// Register value     xxx0 0011 b   101x xxxx b
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	const unsigned long WritingValue
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod register bits getting function pointer (with page setting)
++
++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE() to get demod register bits with bit name and
++page setting.
++
++
++@param [in]    pDemod          The demod module pointer
++@param [in]    RegBitName      Pre-defined demod register bit name
++@param [out]   pReadingValue   Pointer to an allocated memory for storing reading value
++
++
++@retval   FUNCTION_SUCCESS   Get demod register bits successfully with bit name and page setting.
++@retval   FUNCTION_ERROR     Get demod register bits unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE() with the corresponding function.
++	-# Don't need to set register page before using DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE().
++	-# Register bit names are pre-defined keys for bit access, and one can find these in demod header file.
++
++
++@see   DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE
++
++
++
++@par Example:
++@code
++
++
++#include "demod_pseudo.h"
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE AtscDemodModuleMemory;
++	PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory;
++	unsigned long ReadingValue;
++
++
++	// Build pseudo demod module.
++	BuildPseudoDemodModule(&pDemod, &AtscDemodModuleMemory, &PseudoExtraModuleMemory);
++
++	...
++
++	// Get demod register bits with bit name PSEUDO_REG_BIT_NAME.
++	// The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1.
++	pDemod->GetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue);
++
++
++	// Result:
++	//
++	// Page 1
++	// Register address   0x18          0x17
++	// Register value     xxx0 0011 b   101x xxxx b
++	//
++	// Reading value = 0001 1101 b = 0x1d
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	unsigned long *pReadingValue
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod type getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_DEMOD_TYPE() to get DVB-T demod type.
++
++
++@param [in]    pDemod       The demod module pointer
++@param [out]   pDemodType   Pointer to an allocated memory for storing demod type
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_DEMOD_TYPE() with the corresponding function.
++
++
++@see   MODULE_TYPE
++
++*/
++typedef void
++(*DVBT_DEMOD_FP_GET_DEMOD_TYPE)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pDemodType
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod I2C device address getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_DEVICE_ADDR() to get DVB-T demod I2C device address.
++
++
++@param [in]    pDemod        The demod module pointer
++@param [out]   pDeviceAddr   Pointer to an allocated memory for storing demod I2C device address
++
++
++@retval   FUNCTION_SUCCESS   Get demod device address successfully.
++@retval   FUNCTION_ERROR     Get demod device address unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_DEVICE_ADDR() with the corresponding function.
++
++*/
++typedef void
++(*DVBT_DEMOD_FP_GET_DEVICE_ADDR)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char *pDeviceAddr
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod crystal frequency getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() to get DVB-T demod crystal frequency in Hz.
++
++
++@param [in]    pDemod           The demod module pointer
++@param [out]   pCrystalFreqHz   Pointer to an allocated memory for storing demod crystal frequency in Hz
++
++
++@retval   FUNCTION_SUCCESS   Get demod crystal frequency successfully.
++@retval   FUNCTION_ERROR     Get demod crystal frequency unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() with the corresponding function.
++
++*/
++typedef void
++(*DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pCrystalFreqHz
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod I2C bus connection asking function pointer
++
++One can use DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C() to ask DVB-T demod if it is connected to I2C bus.
++
++
++@param [in]    pDemod    The demod module pointer
++@param [out]   pAnswer   Pointer to an allocated memory for storing answer
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C() with the corresponding function.
++
++*/
++typedef void
++(*DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAnswer
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod software resetting function pointer
++
++One can use DVBT_DEMOD_FP_SOFTWARE_RESET() to reset DVB-T demod by software reset.
++
++
++@param [in]   pDemod   The demod module pointer
++
++
++@retval   FUNCTION_SUCCESS   Reset demod by software reset successfully.
++@retval   FUNCTION_ERROR     Reset demod by software reset unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_SOFTWARE_RESET() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_SOFTWARE_RESET)(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod initializing function pointer
++
++One can use DVBT_DEMOD_FP_INITIALIZE() to initialie DVB-T demod.
++
++
++@param [in]   pDemod   The demod module pointer
++
++
++@retval   FUNCTION_SUCCESS   Initialize demod successfully.
++@retval   FUNCTION_ERROR     Initialize demod unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_INITIALIZE() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_INITIALIZE)(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod bandwidth mode setting function pointer
++
++One can use DVBT_DEMOD_FP_SET_DVBT_MODE() to set DVB-T demod bandwidth mode.
++
++
++@param [in]   pDemod	      The demod module pointer
++@param [in]   BandwidthMode   Bandwidth mode for setting
++
++
++@retval   FUNCTION_SUCCESS   Set demod bandwidth mode successfully.
++@retval   FUNCTION_ERROR     Set demod bandwidth mode unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_SET_DVBT_MODE() with the corresponding function.
++
++
++@see   DVBT_BANDWIDTH_MODE
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_SET_BANDWIDTH_MODE)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int BandwidthMode
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod IF frequency setting function pointer
++
++One can use DVBT_DEMOD_FP_SET_IF_FREQ_HZ() to set DVB-T demod IF frequency in Hz.
++
++
++@param [in]   pDemod     The demod module pointer
++@param [in]   IfFreqHz   IF frequency in Hz for setting
++
++
++@retval   FUNCTION_SUCCESS   Set demod IF frequency successfully.
++@retval   FUNCTION_ERROR     Set demod IF frequency unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_SET_IF_FREQ_HZ() with the corresponding function.
++
++
++@see   IF_FREQ_HZ
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_SET_IF_FREQ_HZ)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long IfFreqHz
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod spectrum mode setting function pointer
++
++One can use DVBT_DEMOD_FP_SET_SPECTRUM_MODE() to set DVB-T demod spectrum mode.
++
++
++@param [in]   pDemod         The demod module pointer
++@param [in]   SpectrumMode   Spectrum mode for setting
++
++
++@retval   FUNCTION_SUCCESS   Set demod spectrum mode successfully.
++@retval   FUNCTION_ERROR     Set demod spectrum mode unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_SET_SPECTRUM_MODE() with the corresponding function.
++
++
++@see   SPECTRUM_MODE
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_SET_SPECTRUM_MODE)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int SpectrumMode
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod bandwidth mode getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_DVBT_MODE() to get DVB-T demod bandwidth mode.
++
++
++@param [in]    pDemod           The demod module pointer
++@param [out]   pBandwidthMode   Pointer to an allocated memory for storing demod bandwidth mode
++
++
++@retval   FUNCTION_SUCCESS   Get demod bandwidth mode successfully.
++@retval   FUNCTION_ERROR     Get demod bandwidth mode unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_DVBT_MODE() with the corresponding function.
++
++
++@see   DVBT_DVBT_MODE
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_BANDWIDTH_MODE)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pBandwidthMode
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod IF frequency getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_IF_FREQ_HZ() to get DVB-T demod IF frequency in Hz.
++
++
++@param [in]    pDemod      The demod module pointer
++@param [out]   pIfFreqHz   Pointer to an allocated memory for storing demod IF frequency in Hz
++
++
++@retval   FUNCTION_SUCCESS   Get demod IF frequency successfully.
++@retval   FUNCTION_ERROR     Get demod IF frequency unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_IF_FREQ_HZ() with the corresponding function.
++
++
++@see   IF_FREQ_HZ
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_IF_FREQ_HZ)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pIfFreqHz
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod spectrum mode getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_SPECTRUM_MODE() to get DVB-T demod spectrum mode.
++
++
++@param [in]    pDemod          The demod module pointer
++@param [out]   pSpectrumMode   Pointer to an allocated memory for storing demod spectrum mode
++
++
++@retval   FUNCTION_SUCCESS   Get demod spectrum mode successfully.
++@retval   FUNCTION_ERROR     Get demod spectrum mode unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_SPECTRUM_MODE() with the corresponding function.
++
++
++@see   SPECTRUM_MODE
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_SPECTRUM_MODE)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pSpectrumMode
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod TPS lock asking function pointer
++
++One can use DVBT_DEMOD_FP_IS_TPS_LOCKED() to ask DVB-T demod if it is TPS-locked.
++
++
++@param [in]    pDemod    The demod module pointer
++@param [out]   pAnswer   Pointer to an allocated memory for storing answer
++
++
++@retval   FUNCTION_SUCCESS   Perform TPS lock asking to demod successfully.
++@retval   FUNCTION_ERROR     Perform TPS lock asking to demod unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_IS_TPS_LOCKED() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_IS_TPS_LOCKED)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAnswer
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod signal lock asking function pointer
++
++One can use DVBT_DEMOD_FP_IS_SIGNAL_LOCKED() to ask DVB-T demod if it is signal-locked.
++
++
++@param [in]    pDemod    The demod module pointer
++@param [out]   pAnswer   Pointer to an allocated memory for storing answer
++
++
++@retval   FUNCTION_SUCCESS   Perform signal lock asking to demod successfully.
++@retval   FUNCTION_ERROR     Perform signal lock asking to demod unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_IS_SIGNAL_LOCKED() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_IS_SIGNAL_LOCKED)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pAnswer
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod signal strength getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH() to get signal strength.
++
++
++@param [in]    pDemod            The demod module pointer
++@param [out]   pSignalStrength   Pointer to an allocated memory for storing signal strength (value = 0 ~ 100)
++
++
++@retval   FUNCTION_SUCCESS   Get demod signal strength successfully.
++@retval   FUNCTION_ERROR     Get demod signal strength unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pSignalStrength
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod signal quality getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_SIGNAL_QUALITY() to get signal quality.
++
++
++@param [in]    pDemod           The demod module pointer
++@param [out]   pSignalQuality   Pointer to an allocated memory for storing signal quality (value = 0 ~ 100)
++
++
++@retval   FUNCTION_SUCCESS   Get demod signal quality successfully.
++@retval   FUNCTION_ERROR     Get demod signal quality unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_SIGNAL_QUALITY() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_SIGNAL_QUALITY)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pSignalQuality
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod BER getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_BER() to get BER.
++
++
++@param [in]    pDemod          The demod module pointer
++@param [out]   pBerNum         Pointer to an allocated memory for storing BER numerator
++@param [out]   pBerDen         Pointer to an allocated memory for storing BER denominator
++
++
++@retval   FUNCTION_SUCCESS   Get demod error rate value successfully.
++@retval   FUNCTION_ERROR     Get demod error rate value unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_BER() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_BER)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pBerNum,
++	unsigned long *pBerDen
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod SNR getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_SNR_DB() to get SNR in dB.
++
++
++@param [in]    pDemod      The demod module pointer
++@param [out]   pSnrDbNum   Pointer to an allocated memory for storing SNR dB numerator
++@param [out]   pSnrDbDen   Pointer to an allocated memory for storing SNR dB denominator
++
++
++@retval   FUNCTION_SUCCESS   Get demod SNR successfully.
++@retval   FUNCTION_ERROR     Get demod SNR unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_SNR_DB() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_SNR_DB)(
++	DVBT_DEMOD_MODULE *pDemod,
++	long *pSnrDbNum,
++	long *pSnrDbDen
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod RF AGC getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_RF_AGC() to get DVB-T demod RF AGC value.
++
++
++@param [in]    pDemod   The demod module pointer
++@param [out]   pRfAgc   Pointer to an allocated memory for storing RF AGC value
++
++
++@retval   FUNCTION_SUCCESS   Get demod RF AGC value successfully.
++@retval   FUNCTION_ERROR     Get demod RF AGC value unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_RF_AGC() with the corresponding function.
++	-# The range of RF AGC value is (-pow(2, 13)) ~ (pow(2, 13) - 1).
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_RF_AGC)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pRfAgc
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod IF AGC getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_IF_AGC() to get DVB-T demod IF AGC value.
++
++
++@param [in]    pDemod   The demod module pointer
++@param [out]   pIfAgc   Pointer to an allocated memory for storing IF AGC value
++
++
++@retval   FUNCTION_SUCCESS   Get demod IF AGC value successfully.
++@retval   FUNCTION_ERROR     Get demod IF AGC value unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_IF_AGC() with the corresponding function.
++	-# The range of IF AGC value is (-pow(2, 13)) ~ (pow(2, 13) - 1).
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_IF_AGC)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pIfAgc
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod digital AGC getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_DI_AGC() to get DVB-T demod digital AGC value.
++
++
++@param [in]    pDemod   The demod module pointer
++@param [out]   pDiAgc   Pointer to an allocated memory for storing digital AGC value
++
++
++@retval   FUNCTION_SUCCESS   Get demod digital AGC value successfully.
++@retval   FUNCTION_ERROR     Get demod digital AGC value unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_DI_AGC() with the corresponding function.
++	-# The range of digital AGC value is 0 ~ (pow(2, 8) - 1).
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_DI_AGC)(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char *pDiAgc
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod TR offset getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm.
++
++
++@param [in]    pDemod         The demod module pointer
++@param [out]   pTrOffsetPpm   Pointer to an allocated memory for storing TR offset in ppm
++
++
++@retval   FUNCTION_SUCCESS   Get demod TR offset successfully.
++@retval   FUNCTION_ERROR     Get demod TR offset unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_TR_OFFSET_PPM() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_TR_OFFSET_PPM)(
++	DVBT_DEMOD_MODULE *pDemod,
++	long *pTrOffsetPpm
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod CR offset getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz.
++
++
++@param [in]    pDemod        The demod module pointer
++@param [out]   pCrOffsetHz   Pointer to an allocated memory for storing CR offset in Hz
++
++
++@retval   FUNCTION_SUCCESS   Get demod CR offset successfully.
++@retval   FUNCTION_ERROR     Get demod CR offset unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_CR_OFFSET_HZ() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_CR_OFFSET_HZ)(
++	DVBT_DEMOD_MODULE *pDemod,
++	long *pCrOffsetHz
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod constellation mode getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_CONSTELLATION() to get DVB-T demod constellation mode.
++
++
++@param [in]    pDemod           The demod module pointer
++@param [out]   pConstellation   Pointer to an allocated memory for storing demod constellation mode
++
++
++@retval   FUNCTION_SUCCESS   Get demod constellation mode successfully.
++@retval   FUNCTION_ERROR     Get demod constellation mode unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_CONSTELLATION() with the corresponding function.
++
++
++@see   DVBT_CONSTELLATION_MODE
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_CONSTELLATION)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pConstellation
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod hierarchy mode getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_HIERARCHY() to get DVB-T demod hierarchy mode.
++
++
++@param [in]    pDemod       The demod module pointer
++@param [out]   pHierarchy   Pointer to an allocated memory for storing demod hierarchy mode
++
++
++@retval   FUNCTION_SUCCESS   Get demod hierarchy mode successfully.
++@retval   FUNCTION_ERROR     Get demod hierarchy mode unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_HIERARCHY() with the corresponding function.
++
++
++@see   DVBT_HIERARCHY_MODE
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_HIERARCHY)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pHierarchy
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod low-priority code rate mode getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_CODE_RATE_LP() to get DVB-T demod low-priority code rate mode.
++
++
++@param [in]    pDemod        The demod module pointer
++@param [out]   pCodeRateLp   Pointer to an allocated memory for storing demod low-priority code rate mode
++
++
++@retval   FUNCTION_SUCCESS   Get demod low-priority code rate mode successfully.
++@retval   FUNCTION_ERROR     Get demod low-priority code rate mode unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_CODE_RATE_LP() with the corresponding function.
++
++
++@see   DVBT_CODE_RATE_MODE
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_CODE_RATE_LP)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pCodeRateLp
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod high-priority code rate mode getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_CODE_RATE_HP() to get DVB-T demod high-priority code rate mode.
++
++
++@param [in]    pDemod        The demod module pointer
++@param [out]   pCodeRateHp   Pointer to an allocated memory for storing demod high-priority code rate mode
++
++
++@retval   FUNCTION_SUCCESS   Get demod high-priority code rate mode successfully.
++@retval   FUNCTION_ERROR     Get demod high-priority code rate mode unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_CODE_RATE_HP() with the corresponding function.
++
++
++@see   DVBT_CODE_RATE_MODE
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_CODE_RATE_HP)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pCodeRateHp
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod guard interval mode getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_GUARD_INTERVAL() to get DVB-T demod guard interval mode.
++
++
++@param [in]    pDemod           The demod module pointer
++@param [out]   pGuardInterval   Pointer to an allocated memory for storing demod guard interval mode
++
++
++@retval   FUNCTION_SUCCESS   Get demod guard interval mode successfully.
++@retval   FUNCTION_ERROR     Get demod guard interval mode unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_GUARD_INTERVAL() with the corresponding function.
++
++
++@see   DVBT_GUARD_INTERVAL_MODE
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_GUARD_INTERVAL)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pGuardInterval
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod FFT mode getting function pointer
++
++One can use DVBT_DEMOD_FP_GET_FFT_MODE() to get DVB-T demod FFT mode.
++
++
++@param [in]    pDemod     The demod module pointer
++@param [out]   pFftMode   Pointer to an allocated memory for storing demod FFT mode
++
++
++@retval   FUNCTION_SUCCESS   Get demod FFT mode successfully.
++@retval   FUNCTION_ERROR     Get demod FFT mode unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_GET_FFT_MODE() with the corresponding function.
++
++
++@see   DVBT_FFT_MODE_MODE
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_GET_FFT_MODE)(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pFftMode
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod updating function pointer
++
++One can use DVBT_DEMOD_FP_UPDATE_FUNCTION() to update demod register setting.
++
++
++@param [in]   pDemod   The demod module pointer
++
++
++@retval   FUNCTION_SUCCESS   Update demod setting successfully.
++@retval   FUNCTION_ERROR     Update demod setting unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_UPDATE_FUNCTION() with the corresponding function.
++
++
++
++@par Example:
++@code
++
++
++#include "demod_pseudo.h"
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE DvbtDemodModuleMemory;
++	PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory;
++
++
++	// Build pseudo demod module.
++	BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory);
++
++	...
++
++	// Execute ResetFunction() before demod software reset.
++	pDemod->ResetFunction(pDemod);
++
++	// Reset demod by software.
++	pDemod->SoftwareReset(pDemod);
++
++	...
++
++	return 0;
++}
++
++
++void PeriodicallyExecutingFunction
++{
++	// Executing UpdateFunction() periodically.
++	pDemod->UpdateFunction(pDemod);
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_UPDATE_FUNCTION)(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T demod reseting function pointer
++
++One can use DVBT_DEMOD_FP_RESET_FUNCTION() to reset demod register setting.
++
++
++@param [in]   pDemod   The demod module pointer
++
++
++@retval   FUNCTION_SUCCESS   Reset demod setting successfully.
++@retval   FUNCTION_ERROR     Reset demod setting unsuccessfully.
++
++
++@note
++	-# Demod building function will set DVBT_DEMOD_FP_RESET_FUNCTION() with the corresponding function.
++
++
++
++@par Example:
++@code
++
++
++#include "demod_pseudo.h"
++
++
++int main(void)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	DVBT_DEMOD_MODULE DvbtDemodModuleMemory;
++	PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory;
++
++
++	// Build pseudo demod module.
++	BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory);
++
++	...
++
++	// Execute ResetFunction() before demod software reset.
++	pDemod->ResetFunction(pDemod);
++
++	// Reset demod by software.
++	pDemod->SoftwareReset(pDemod);
++
++	...
++
++	return 0;
++}
++
++
++void PeriodicallyExecutingFunction
++{
++	// Executing UpdateFunction() periodically.
++	pDemod->UpdateFunction(pDemod);
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_DEMOD_FP_RESET_FUNCTION)(
++	DVBT_DEMOD_MODULE *pDemod
++	);
++
++
++
++
++
++/// DVB-T demod module structure
++struct DVBT_DEMOD_MODULE_TAG
++{
++
++	unsigned long PageNo;
++
++	// Private variables
++	int           DemodType;
++	unsigned char DeviceAddr;
++	unsigned long CrystalFreqHz;
++
++	int           BandwidthMode;
++	unsigned long IfFreqHz;
++	int           SpectrumMode;
++
++	int IsBandwidthModeSet;
++	int IsIfFreqHzSet;
++	int IsSpectrumModeSet;
++
++	void *pExtra;									///<   Demod extra module used by driving module
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	I2C_BRIDGE_MODULE *pI2cBridge;
++
++
++	// Demod register table
++	DVBT_REG_ENTRY RegTable[DVBT_REG_TABLE_LEN_MAX];
++
++
++	// Demod I2C function pointers
++	DVBT_DEMOD_FP_SET_REG_PAGE             SetRegPage;
++	DVBT_DEMOD_FP_SET_REG_BYTES            SetRegBytes;
++	DVBT_DEMOD_FP_GET_REG_BYTES            GetRegBytes;
++	DVBT_DEMOD_FP_SET_REG_MASK_BITS        SetRegMaskBits;
++	DVBT_DEMOD_FP_GET_REG_MASK_BITS        GetRegMaskBits;
++	DVBT_DEMOD_FP_SET_REG_BITS             SetRegBits;
++	DVBT_DEMOD_FP_GET_REG_BITS             GetRegBits;
++	DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE   SetRegBitsWithPage;
++	DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE   GetRegBitsWithPage;
++
++
++	// Demod manipulating function pointers
++	DVBT_DEMOD_FP_GET_DEMOD_TYPE        GetDemodType;
++	DVBT_DEMOD_FP_GET_DEVICE_ADDR       GetDeviceAddr;
++	DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ   GetCrystalFreqHz;
++
++	DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C   IsConnectedToI2c;
++
++	DVBT_DEMOD_FP_SOFTWARE_RESET        SoftwareReset;
++
++	DVBT_DEMOD_FP_INITIALIZE            Initialize;
++	DVBT_DEMOD_FP_SET_BANDWIDTH_MODE    SetBandwidthMode;
++	DVBT_DEMOD_FP_SET_IF_FREQ_HZ        SetIfFreqHz;
++	DVBT_DEMOD_FP_SET_SPECTRUM_MODE     SetSpectrumMode;
++	DVBT_DEMOD_FP_GET_BANDWIDTH_MODE    GetBandwidthMode;
++	DVBT_DEMOD_FP_GET_IF_FREQ_HZ        GetIfFreqHz;
++	DVBT_DEMOD_FP_GET_SPECTRUM_MODE     GetSpectrumMode;
++
++	DVBT_DEMOD_FP_IS_TPS_LOCKED         IsTpsLocked;
++	DVBT_DEMOD_FP_IS_SIGNAL_LOCKED      IsSignalLocked;
++
++	DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH   GetSignalStrength;
++	DVBT_DEMOD_FP_GET_SIGNAL_QUALITY    GetSignalQuality;
++
++	DVBT_DEMOD_FP_GET_BER               GetBer;
++	DVBT_DEMOD_FP_GET_SNR_DB            GetSnrDb;
++
++	DVBT_DEMOD_FP_GET_RF_AGC            GetRfAgc;
++	DVBT_DEMOD_FP_GET_IF_AGC            GetIfAgc;
++	DVBT_DEMOD_FP_GET_DI_AGC            GetDiAgc;
++
++	DVBT_DEMOD_FP_GET_TR_OFFSET_PPM     GetTrOffsetPpm;
++	DVBT_DEMOD_FP_GET_CR_OFFSET_HZ      GetCrOffsetHz;
++
++	DVBT_DEMOD_FP_GET_CONSTELLATION     GetConstellation;
++	DVBT_DEMOD_FP_GET_HIERARCHY         GetHierarchy;
++	DVBT_DEMOD_FP_GET_CODE_RATE_LP      GetCodeRateLp;
++	DVBT_DEMOD_FP_GET_CODE_RATE_HP      GetCodeRateHp;
++	DVBT_DEMOD_FP_GET_GUARD_INTERVAL    GetGuardInterval;
++	DVBT_DEMOD_FP_GET_FFT_MODE          GetFftMode;
++
++	DVBT_DEMOD_FP_UPDATE_FUNCTION       UpdateFunction;
++	DVBT_DEMOD_FP_RESET_FUNCTION        ResetFunction;
++};
++
++
++
++
++
++
++
++// DVB-T demod default I2C functions
++int
++dvbt_demod_default_SetRegPage(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long PageNo
++	);
++
++int
++dvbt_demod_default_SetRegBytes(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	);
++
++int
++dvbt_demod_default_GetRegBytes(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	);
++
++int
++dvbt_demod_default_SetRegMaskBits(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	unsigned char Msb,
++	unsigned char Lsb,
++	const unsigned long WritingValue
++	);
++
++int
++dvbt_demod_default_GetRegMaskBits(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char RegStartAddr,
++	unsigned char Msb,
++	unsigned char Lsb,
++	unsigned long *pReadingValue
++	);
++
++int
++dvbt_demod_default_SetRegBits(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	const unsigned long WritingValue
++	);
++
++int
++dvbt_demod_default_GetRegBits(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	unsigned long *pReadingValue
++	);
++
++int
++dvbt_demod_default_SetRegBitsWithPage(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	const unsigned long WritingValue
++	);
++
++int
++dvbt_demod_default_GetRegBitsWithPage(
++	DVBT_DEMOD_MODULE *pDemod,
++	int RegBitName,
++	unsigned long *pReadingValue
++	);
++
++
++
++
++
++// DVB-T demod default manipulating functions
++void
++dvbt_demod_default_GetDemodType(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pDemodType
++	);
++
++void
++dvbt_demod_default_GetDeviceAddr(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned char *pDeviceAddr
++	);
++
++void
++dvbt_demod_default_GetCrystalFreqHz(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pCrystalFreqHz
++	);
++
++int
++dvbt_demod_default_GetBandwidthMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pBandwidthMode
++	);
++
++int
++dvbt_demod_default_GetIfFreqHz(
++	DVBT_DEMOD_MODULE *pDemod,
++	unsigned long *pIfFreqHz
++	);
++
++int
++dvbt_demod_default_GetSpectrumMode(
++	DVBT_DEMOD_MODULE *pDemod,
++	int *pSpectrumMode
++	);
++
++
++
++
++
++
++
++#endif
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/dvbt_nim_base.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/dvbt_nim_base.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,531 @@
++/**
++
++@file
++
++@brief   DVB-T NIM base module definition
++
++DVB-T NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default
++functions.
++
++*/
++
++
++#include "dvbt_nim_base.h"
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_GET_NIM_TYPE
++
++*/
++void
++dvbt_nim_default_GetNimType(
++	DVBT_NIM_MODULE *pNim,
++	int *pNimType
++	)
++{
++	// Get NIM type from NIM module.
++	*pNimType = pNim->NimType;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_SET_PARAMETERS
++
++*/
++int
++dvbt_nim_default_SetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long RfFreqHz,
++	int BandwidthMode
++	)
++{
++	TUNER_MODULE *pTuner;
++	DVBT_DEMOD_MODULE *pDemod;
++
++
++	// Get tuner module and demod module.
++	pTuner = pNim->pTuner;
++	pDemod = pNim->pDemod;
++
++
++	// Set tuner RF frequency in Hz.
++	if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Set demod bandwidth mode.
++	if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Reset demod particular registers.
++	if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Reset demod by software reset.
++	if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_GET_PARAMETERS
++
++*/
++int
++dvbt_nim_default_GetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pRfFreqHz,
++	int *pBandwidthMode
++	)
++{
++	TUNER_MODULE *pTuner;
++	DVBT_DEMOD_MODULE *pDemod;
++
++
++	// Get tuner module and demod module.
++	pTuner = pNim->pTuner;
++	pDemod = pNim->pDemod;
++
++
++	// Get tuner RF frequency in Hz.
++	if(pTuner->GetRfFreqHz(pTuner, pRfFreqHz) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get demod bandwidth mode.
++	if(pDemod->GetBandwidthMode(pDemod, pBandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_IS_SIGNAL_PRESENT
++
++*/
++int
++dvbt_nim_default_IsSignalPresent(
++	DVBT_NIM_MODULE *pNim,
++	int *pAnswer
++	)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	DVBT_DEMOD_MODULE *pDemod;
++	int i;
++
++
++	// Get base interface and demod module.
++	pBaseInterface = pNim->pBaseInterface;
++	pDemod         = pNim->pDemod;
++
++
++	// Wait for signal present check.
++	for(i = 0; i < DEFAULT_DVBT_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX; i++)
++	{
++		// Wait 20 ms.
++		pBaseInterface->WaitMs(pBaseInterface, 20);
++
++		// Check TPS present status on demod.
++		// Note: If TPS is locked, stop signal present check.
++		if(pDemod->IsTpsLocked(pDemod, pAnswer) != FUNCTION_SUCCESS)
++			goto error_status_execute_function;
++
++		if(*pAnswer == YES)
++			break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_IS_SIGNAL_LOCKED
++
++*/
++int
++dvbt_nim_default_IsSignalLocked(
++	DVBT_NIM_MODULE *pNim,
++	int *pAnswer
++	)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	DVBT_DEMOD_MODULE *pDemod;
++	int i;
++
++
++	// Get base interface and demod module.
++	pBaseInterface = pNim->pBaseInterface;
++	pDemod         = pNim->pDemod;
++
++
++	// Wait for signal lock check.
++	for(i = 0; i < DEFAULT_DVBT_NIM_SINGAL_LOCK_CHECK_TIMES_MAX; i++)
++	{
++		// Wait 20 ms.
++		pBaseInterface->WaitMs(pBaseInterface, 20);
++
++		// Check signal lock status on demod.
++		// Note: If signal is locked, stop signal lock check.
++		if(pDemod->IsSignalLocked(pDemod, pAnswer) != FUNCTION_SUCCESS)
++			goto error_status_execute_function;
++
++		if(*pAnswer == YES)
++			break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_GET_SIGNAL_STRENGTH
++
++*/
++int
++dvbt_nim_default_GetSignalStrength(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pSignalStrength
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++
++
++	// Get demod module.
++	pDemod = pNim->pDemod;
++
++
++	// Get signal strength from demod.
++	if(pDemod->GetSignalStrength(pDemod, pSignalStrength) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_GET_SIGNAL_QUALITY
++
++*/
++int
++dvbt_nim_default_GetSignalQuality(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pSignalQuality
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++
++
++	// Get demod module.
++	pDemod = pNim->pDemod;
++
++
++	// Get signal quality from demod.
++	if(pDemod->GetSignalQuality(pDemod, pSignalQuality) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_GET_BER
++
++*/
++int
++dvbt_nim_default_GetBer(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pBerNum,
++	unsigned long *pBerDen
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++
++
++	// Get demod module.
++	pDemod = pNim->pDemod;
++
++
++	// Get BER from demod.
++	if(pDemod->GetBer(pDemod, pBerNum, pBerDen) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_GET_SNR_DB
++
++*/
++int
++dvbt_nim_default_GetSnrDb(
++	DVBT_NIM_MODULE *pNim,
++	long *pSnrDbNum,
++	long *pSnrDbDen
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++
++
++	// Get demod module.
++	pDemod = pNim->pDemod;
++
++
++	// Get SNR in dB from demod.
++	if(pDemod->GetSnrDb(pDemod, pSnrDbNum, pSnrDbDen) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_GET_TR_OFFSET_PPM
++
++*/
++int
++dvbt_nim_default_GetTrOffsetPpm(
++	DVBT_NIM_MODULE *pNim,
++	long *pTrOffsetPpm
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++
++
++	// Get demod module.
++	pDemod = pNim->pDemod;
++
++
++	// Get TR offset in ppm from demod.
++	if(pDemod->GetTrOffsetPpm(pDemod, pTrOffsetPpm) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_GET_CR_OFFSET_HZ
++
++*/
++int
++dvbt_nim_default_GetCrOffsetHz(
++	DVBT_NIM_MODULE *pNim,
++	long *pCrOffsetHz
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++
++
++	// Get demod module.
++	pDemod = pNim->pDemod;
++
++
++	// Get CR offset in Hz from demod.
++	if(pDemod->GetCrOffsetHz(pDemod, pCrOffsetHz) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_GET_TPS_INFO
++
++*/
++int
++dvbt_nim_default_GetTpsInfo(
++	DVBT_NIM_MODULE *pNim,
++	int *pConstellation,
++	int *pHierarchy,
++	int *pCodeRateLp,
++	int *pCodeRateHp,
++	int *pGuardInterval,
++	int *pFftMode
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++
++
++	// Get demod module.
++	pDemod = pNim->pDemod;
++
++
++	// Get TPS constellation information from demod.
++	if(pDemod->GetConstellation(pDemod, pConstellation) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get TPS hierarchy information from demod.
++	if(pDemod->GetHierarchy(pDemod, pHierarchy) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get TPS low-priority code rate information from demod.
++	if(pDemod->GetCodeRateLp(pDemod, pCodeRateLp) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get TPS high-priority code rate information from demod.
++	if(pDemod->GetCodeRateHp(pDemod, pCodeRateHp) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get TPS guard interval information from demod.
++	if(pDemod->GetGuardInterval(pDemod, pGuardInterval) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get TPS FFT mode information from demod.
++	if(pDemod->GetFftMode(pDemod, pFftMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_UPDATE_FUNCTION
++
++*/
++int
++dvbt_nim_default_UpdateFunction(
++	DVBT_NIM_MODULE *pNim
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++
++
++	// Get demod module.
++	pDemod = pNim->pDemod;
++
++
++	// Update demod particular registers.
++	if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++
++
++
++
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/dvbt_nim_base.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/dvbt_nim_base.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,845 @@
++#ifndef __DVBT_NIM_BASE_H
++#define __DVBT_NIM_BASE_H
++
++/**
++
++@file
++
++@brief   DVB-T NIM base module definition
++
++DVB-T NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default
++functions.
++
++
++
++@par Example:
++@code
++
++
++#include "nim_demodx_tunery.h"
++
++
++
++int
++CustomI2cRead(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	)
++{
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++	return FUNCTION_ERROR;
++}
++
++
++
++int
++CustomI2cWrite(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	)
++{
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++	return FUNCTION_ERROR;
++}
++
++
++
++void
++CustomWaitMs(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned long WaitTimeMs
++	)
++{
++	...
++}
++
++
++
++int main(void)
++{
++	DVBT_NIM_MODULE *pNim;
++	DVBT_NIM_MODULE DvbtNimModuleMemory;
++	DEMODX_EXTRA_MODULE DemodxExtraModuleMemory;
++	TUNERY_EXTRA_MODULE TuneryExtraModuleMemory;
++
++	unsigned long RfFreqHz;
++	int BandwidthMode;
++
++	int Answer;
++	unsigned long SignalStrength, SignalQuality;
++	unsigned long BerNum, BerDen, PerNum, PerDen;
++	double Ber, Per;
++	unsigned long SnrDbNum, SnrDbDen;
++	double SnrDb;
++	long TrOffsetPpm, CrOffsetHz;
++
++	int Constellation;
++	int Hierarchy;
++	int CodeRateLp;
++	int CodeRateHp;
++	int GuardInterval;
++	int FftMode;
++
++
++
++	// Build Demod-X Tuner-Y NIM module.
++	BuildDemodxTuneryModule(
++		&pNim,
++		&DvbtNimModuleMemory,
++
++		9,								// Maximum I2C reading byte number is 9.
++		8,								// Maximum I2C writing byte number is 8.
++		CustomI2cRead,					// Employ CustomI2cRead() as basic I2C reading function.
++		CustomI2cWrite,					// Employ CustomI2cWrite() as basic I2C writing function.
++		CustomWaitMs					// Employ CustomWaitMs() as basic waiting function.
++
++		&DemodxExtraModuleMemory,		// Employ Demod-X extra module.
++		0x20,							// The Demod-X I2C device address is 0x20 in 8-bit format.
++		CRYSTAL_FREQ_28800000HZ,		// The Demod-X crystal frequency is 28.8 MHz.
++		...								// Other arguments for Demod-X
++
++		&TunerxExtraModuleMemory,		// Employ Tuner-Y extra module.
++		0xc0,							// The Tuner-Y I2C device address is 0xc0 in 8-bit format.
++		...								// Other arguments for Tuner-Y
++		);
++
++
++
++	// Get NIM type.
++	// Note: NIM types are defined in the MODULE_TYPE enumeration.
++	pNim->GetNimType(pNim, &NimType);
++
++
++
++
++
++
++
++	// ==== Initialize NIM and set its parameters =====
++
++	// Initialize NIM.
++	pNim->Initialize(pNim);
++
++	// Set NIM parameters. (RF frequency, bandwdith mode)
++	// Note: In the example:
++	//       1. RF frequency is 666 MHz.
++	//       2. Bandwidth mode is 8 MHz.
++	RfFreqHz      = 666000000;
++	BandwidthMode = DVBT_BANDWIDTH_8MHZ;
++	pNim->SetParameters(pNim, RfFreqHz, BandwidthMode);
++
++
++
++
++
++	// ==== Get NIM information =====
++
++	// Get NIM parameters. (RF frequency, bandwdith mode)
++	pNim->GetParameters(pNim, &RfFreqHz, &BandwidthMode);
++
++
++	// Get signal present status.
++	// Note: 1. The IsSignalPresent() function will wait maximum 1000 ms for signal present check.
++	//       2. The argument Answer is YES when the NIM module has found DVB-T signal in the RF channel.
++	//       3. The argument Answer is NO when the NIM module does not find DVB-T signal in the RF channel.
++	// Recommendation: Use the IsSignalPresent() function for channel scan.
++	pNim->IsSignalPresent(pNim, &Answer);
++
++	// Get signal lock status.
++	// Note: 1. The IsSignalLocked() function will wait maximum 1000 ms for signal lock check.
++	//       2. The argument Answer is YES when the NIM module has locked DVB-T signal in the RF channel.
++	//          At the same time, the NIM module sends TS packets through TS interface hardware pins.
++	//       3. The argument Answer is NO when the NIM module does not lock DVB-T signal in the RF channel.
++	// Recommendation: Use the IsSignalLocked() function for signal lock check.
++	pNim->IsSignalLocked(pNim, &Answer);
++
++
++	// Get signal strength.
++	// Note: 1. The range of SignalStrength is 0~100.
++	//       2. Need to map SignalStrength value to UI signal strength bar manually.
++	pNim->GetSignalStrength(pNim, &SignalStrength);
++
++	// Get signal quality.
++	// Note: 1. The range of SignalQuality is 0~100.
++	//       2. Need to map SignalQuality value to UI signal quality bar manually.
++	pNim->GetSignalQuality(pNim, &SignalQuality);
++
++
++	// Get BER.
++	pNim->GetBer(pNim, &BerNum, &BerDen);
++	Ber = (double)BerNum / (double)BerDen;
++
++	// Get SNR in dB.
++	pNim->GetSnrDb(pNim, &SnrDbNum, &SnrDbDen);
++	SnrDb = (double)SnrDbNum / (double)SnrDbDen;
++
++
++	// Get TR offset (symbol timing offset) in ppm.
++	pNim->GetTrOffsetPpm(pNim, &TrOffsetPpm);
++
++	// Get CR offset (RF frequency offset) in Hz.
++	pNim->GetCrOffsetHz(pNim, &CrOffsetHz);
++
++
++	// Get TPS information.
++	// Note: One can find TPS information definitions in the enumerations as follows:
++	//       1. DVBT_CONSTELLATION_MODE.
++	//       2. DVBT_HIERARCHY_MODE.
++	//       3. DVBT_CODE_RATE_MODE. (for low-priority and high-priority code rate)
++	//       4. DVBT_GUARD_INTERVAL_MODE.
++	//       5. DVBT_FFT_MODE_MODE
++	pNim->GetTpsInfo(pNim, &Constellation, &Hierarchy, &CodeRateLp, &CodeRateHp, &GuardInterval, &FftMode);
++
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++#include "foundation.h"
++#include "tuner_base.h"
++#include "dvbt_demod_base.h"
++
++
++
++
++
++// Definitions
++#define DEFAULT_DVBT_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX			1
++#define DEFAULT_DVBT_NIM_SINGAL_LOCK_CHECK_TIMES_MAX			1
++
++
++
++
++
++/// DVB-T NIM module pre-definition
++typedef struct DVBT_NIM_MODULE_TAG DVBT_NIM_MODULE;
++
++
++
++
++
++/**
++
++@brief   DVB-T demod type getting function pointer
++
++One can use DVBT_NIM_FP_GET_NIM_TYPE() to get DVB-T NIM type.
++
++
++@param [in]    pNim       The NIM module pointer
++@param [out]   pNimType   Pointer to an allocated memory for storing NIM type
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_GET_NIM_TYPE() with the corresponding function.
++
++
++@see   MODULE_TYPE
++
++*/
++typedef void
++(*DVBT_NIM_FP_GET_NIM_TYPE)(
++	DVBT_NIM_MODULE *pNim,
++	int *pNimType
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM initializing function pointer
++
++One can use DVBT_NIM_FP_INITIALIZE() to initialie DVB-T NIM.
++
++
++@param [in]   pNim   The NIM module pointer
++
++
++@retval   FUNCTION_SUCCESS   Initialize NIM successfully.
++@retval   FUNCTION_ERROR     Initialize NIM unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_INITIALIZE() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_NIM_FP_INITIALIZE)(
++	DVBT_NIM_MODULE *pNim
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM parameter setting function pointer
++
++One can use DVBT_NIM_FP_SET_PARAMETERS() to set DVB-T NIM parameters.
++
++
++@param [in]   pNim            The NIM module pointer
++@param [in]   RfFreqHz        RF frequency in Hz for setting
++@param [in]   BandwidthMode   Bandwidth mode for setting
++
++
++@retval   FUNCTION_SUCCESS   Set NIM parameters successfully.
++@retval   FUNCTION_ERROR     Set NIM parameters unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_SET_PARAMETERS() with the corresponding function.
++
++
++@see   DVBT_BANDWIDTH_MODE
++
++*/
++typedef int
++(*DVBT_NIM_FP_SET_PARAMETERS)(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long RfFreqHz,
++	int BandwidthMode
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM parameter getting function pointer
++
++One can use DVBT_NIM_FP_GET_PARAMETERS() to get DVB-T NIM parameters.
++
++
++@param [in]    pNim             The NIM module pointer
++@param [out]   pRfFreqHz        Pointer to an allocated memory for storing NIM RF frequency in Hz
++@param [out]   pBandwidthMode   Pointer to an allocated memory for storing NIM bandwidth mode
++
++
++@retval   FUNCTION_SUCCESS   Get NIM parameters successfully.
++@retval   FUNCTION_ERROR     Get NIM parameters unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_GET_PARAMETERS() with the corresponding function.
++
++
++@see   DVBT_BANDWIDTH_MODE
++
++*/
++typedef int
++(*DVBT_NIM_FP_GET_PARAMETERS)(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pRfFreqHz,
++	int *pBandwidthMode
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM signal present asking function pointer
++
++One can use DVBT_NIM_FP_IS_SIGNAL_PRESENT() to ask DVB-T NIM if signal is present.
++
++
++@param [in]    pNim      The NIM module pointer
++@param [out]   pAnswer   Pointer to an allocated memory for storing answer
++
++
++@retval   FUNCTION_SUCCESS   Perform signal present asking to NIM successfully.
++@retval   FUNCTION_ERROR     Perform signal present asking to NIM unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_IS_SIGNAL_PRESENT() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_NIM_FP_IS_SIGNAL_PRESENT)(
++	DVBT_NIM_MODULE *pNim,
++	int *pAnswer
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM signal lock asking function pointer
++
++One can use DVBT_NIM_FP_IS_SIGNAL_LOCKED() to ask DVB-T NIM if signal is locked.
++
++
++@param [in]    pNim      The NIM module pointer
++@param [out]   pAnswer   Pointer to an allocated memory for storing answer
++
++
++@retval   FUNCTION_SUCCESS   Perform signal lock asking to NIM successfully.
++@retval   FUNCTION_ERROR     Perform signal lock asking to NIM unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_IS_SIGNAL_LOCKED() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_NIM_FP_IS_SIGNAL_LOCKED)(
++	DVBT_NIM_MODULE *pNim,
++	int *pAnswer
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM signal strength getting function pointer
++
++One can use DVBT_NIM_FP_GET_SIGNAL_STRENGTH() to get signal strength.
++
++
++@param [in]    pNim              The NIM module pointer
++@param [out]   pSignalStrength   Pointer to an allocated memory for storing signal strength (value = 0 ~ 100)
++
++
++@retval   FUNCTION_SUCCESS   Get NIM signal strength successfully.
++@retval   FUNCTION_ERROR     Get NIM signal strength unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_GET_SIGNAL_STRENGTH() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_NIM_FP_GET_SIGNAL_STRENGTH)(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pSignalStrength
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM signal quality getting function pointer
++
++One can use DVBT_NIM_FP_GET_SIGNAL_QUALITY() to get signal quality.
++
++
++@param [in]    pNim             The NIM module pointer
++@param [out]   pSignalQuality   Pointer to an allocated memory for storing signal quality (value = 0 ~ 100)
++
++
++@retval   FUNCTION_SUCCESS   Get NIM signal quality successfully.
++@retval   FUNCTION_ERROR     Get NIM signal quality unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_GET_SIGNAL_QUALITY() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_NIM_FP_GET_SIGNAL_QUALITY)(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pSignalQuality
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM BER value getting function pointer
++
++One can use DVBT_NIM_FP_GET_BER() to get BER.
++
++
++@param [in]    pNim            The NIM module pointer
++@param [out]   pBerNum         Pointer to an allocated memory for storing BER numerator
++@param [out]   pBerDen         Pointer to an allocated memory for storing BER denominator
++
++
++@retval   FUNCTION_SUCCESS   Get NIM BER value successfully.
++@retval   FUNCTION_ERROR     Get NIM BER value unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_GET_BER() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_NIM_FP_GET_BER)(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pBerNum,
++	unsigned long *pBerDen
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM SNR getting function pointer
++
++One can use DVBT_NIM_FP_GET_SNR_DB() to get SNR in dB.
++
++
++@param [in]    pNim        The NIM module pointer
++@param [out]   pSnrDbNum   Pointer to an allocated memory for storing SNR dB numerator
++@param [out]   pSnrDbDen   Pointer to an allocated memory for storing SNR dB denominator
++
++
++@retval   FUNCTION_SUCCESS   Get NIM SNR successfully.
++@retval   FUNCTION_ERROR     Get NIM SNR unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_GET_SNR_DB() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_NIM_FP_GET_SNR_DB)(
++	DVBT_NIM_MODULE *pNim,
++	long *pSnrDbNum,
++	long *pSnrDbDen
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM TR offset getting function pointer
++
++One can use DVBT_NIM_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm.
++
++
++@param [in]    pNim           The NIM module pointer
++@param [out]   pTrOffsetPpm   Pointer to an allocated memory for storing TR offset in ppm
++
++
++@retval   FUNCTION_SUCCESS   Get NIM TR offset successfully.
++@retval   FUNCTION_ERROR     Get NIM TR offset unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_GET_TR_OFFSET_PPM() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_NIM_FP_GET_TR_OFFSET_PPM)(
++	DVBT_NIM_MODULE *pNim,
++	long *pTrOffsetPpm
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM CR offset getting function pointer
++
++One can use DVBT_NIM_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz.
++
++
++@param [in]    pNim          The NIM module pointer
++@param [out]   pCrOffsetHz   Pointer to an allocated memory for storing CR offset in Hz
++
++
++@retval   FUNCTION_SUCCESS   Get NIM CR offset successfully.
++@retval   FUNCTION_ERROR     Get NIM CR offset unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_GET_CR_OFFSET_HZ() with the corresponding function.
++
++*/
++typedef int
++(*DVBT_NIM_FP_GET_CR_OFFSET_HZ)(
++	DVBT_NIM_MODULE *pNim,
++	long *pCrOffsetHz
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM TPS information getting function pointer
++
++One can use DVBT_NIM_FP_GET_TPS_INFO() to get TPS information.
++
++
++@param [in]    pNim             The NIM module pointer
++@param [out]   pConstellation   Pointer to an allocated memory for storing demod constellation mode
++@param [out]   pHierarchy       Pointer to an allocated memory for storing demod hierarchy mode
++@param [out]   pCodeRateLp      Pointer to an allocated memory for storing demod low-priority code rate mode
++@param [out]   pCodeRateHp      Pointer to an allocated memory for storing demod high-priority code rate mode
++@param [out]   pGuardInterval   Pointer to an allocated memory for storing demod guard interval mode
++@param [out]   pFftMode         Pointer to an allocated memory for storing demod FFT mode
++
++
++@retval   FUNCTION_SUCCESS   Get NIM TPS information successfully.
++@retval   FUNCTION_ERROR     Get NIM TPS information unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_GET_TPS_INFO() with the corresponding function.
++
++
++@see   DVBT_CONSTELLATION_MODE, DVBT_HIERARCHY_MODE, DVBT_CODE_RATE_MODE, DVBT_GUARD_INTERVAL_MODE, DVBT_FFT_MODE_MODE
++
++*/
++typedef int
++(*DVBT_NIM_FP_GET_TPS_INFO)(
++	DVBT_NIM_MODULE *pNim,
++	int *pConstellation,
++	int *pHierarchy,
++	int *pCodeRateLp,
++	int *pCodeRateHp,
++	int *pGuardInterval,
++	int *pFftMode
++	);
++
++
++
++
++
++/**
++
++@brief   DVB-T NIM updating function pointer
++
++One can use DVBT_NIM_FP_UPDATE_FUNCTION() to update NIM register setting.
++
++
++@param [in]   pNim   The NIM module pointer
++
++
++@retval   FUNCTION_SUCCESS   Update NIM setting successfully.
++@retval   FUNCTION_ERROR     Update NIM setting unsuccessfully.
++
++
++@note
++	-# NIM building function will set DVBT_NIM_FP_UPDATE_FUNCTION() with the corresponding function.
++
++
++
++@par Example:
++@code
++
++
++#include "nim_demodx_tunery.h"
++
++
++int main(void)
++{
++	DVBT_NIM_MODULE *pNim;
++	DVBT_NIM_MODULE DvbtNimModuleMemory;
++	DEMODX_EXTRA_MODULE DemodxExtraModuleMemory;
++	TUNERY_EXTRA_MODULE TuneryExtraModuleMemory;
++
++
++	// Build Demod-X Tuner-Y NIM module.
++	BuildDemodxTuneryModule(
++		...
++		);
++
++	...
++
++
++	return 0;
++}
++
++
++void PeriodicallyExecutingFunction
++{
++	// Executing UpdateFunction() periodically.
++	pNim->UpdateFunction(pNim);
++}
++
++
++@endcode
++
++*/
++typedef int
++(*DVBT_NIM_FP_UPDATE_FUNCTION)(
++	DVBT_NIM_MODULE *pNim
++	);
++
++
++
++
++
++/// DVB-T NIM module structure
++struct DVBT_NIM_MODULE_TAG
++{
++	// Private variables
++	int NimType;
++	int DemodTsInterfaceMode;
++
++	void *pExtra;												///<   NIM extra module used by driving module
++
++
++	// Modules
++	BASE_INTERFACE_MODULE *pBaseInterface;						///<   Base interface module pointer
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;			///<   Base interface module memory
++
++	I2C_BRIDGE_MODULE *pI2cBridge;								///<   I2C bridge module pointer
++	I2C_BRIDGE_MODULE I2cBridgeModuleMemory;					///<   I2C bridge module memory
++
++	TUNER_MODULE *pTuner;										///<   Tuner module pointer
++	TUNER_MODULE TunerModuleMemory;								///<   Tuner module memory
++
++	DVBT_DEMOD_MODULE *pDemod;									///<   DVB-T demod module pointer
++	DVBT_DEMOD_MODULE DvbtDemodModuleMemory;					///<   DVB-T demod module memory
++
++
++	// NIM manipulating functions
++	DVBT_NIM_FP_GET_NIM_TYPE          GetNimType;
++	DVBT_NIM_FP_INITIALIZE            Initialize;
++	DVBT_NIM_FP_SET_PARAMETERS        SetParameters;
++	DVBT_NIM_FP_GET_PARAMETERS        GetParameters;
++	DVBT_NIM_FP_IS_SIGNAL_PRESENT     IsSignalPresent;
++	DVBT_NIM_FP_IS_SIGNAL_LOCKED      IsSignalLocked;
++	DVBT_NIM_FP_GET_SIGNAL_STRENGTH   GetSignalStrength;
++	DVBT_NIM_FP_GET_SIGNAL_QUALITY    GetSignalQuality;
++	DVBT_NIM_FP_GET_BER               GetBer;
++	DVBT_NIM_FP_GET_SNR_DB            GetSnrDb;
++	DVBT_NIM_FP_GET_TR_OFFSET_PPM     GetTrOffsetPpm;
++	DVBT_NIM_FP_GET_CR_OFFSET_HZ      GetCrOffsetHz;
++	DVBT_NIM_FP_GET_TPS_INFO          GetTpsInfo;
++	DVBT_NIM_FP_UPDATE_FUNCTION       UpdateFunction;
++};
++
++
++
++
++
++
++
++// DVB-T NIM default manipulaing functions
++void
++dvbt_nim_default_GetNimType(
++	DVBT_NIM_MODULE *pNim,
++	int *pNimType
++	);
++
++int
++dvbt_nim_default_SetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long RfFreqHz,
++	int BandwidthMode
++	);
++
++int
++dvbt_nim_default_GetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pRfFreqHz,
++	int *pBandwidthMode
++	);
++
++int
++dvbt_nim_default_IsSignalPresent(
++	DVBT_NIM_MODULE *pNim,
++	int *pAnswer
++	);
++
++int
++dvbt_nim_default_IsSignalLocked(
++	DVBT_NIM_MODULE *pNim,
++	int *pAnswer
++	);
++
++int
++dvbt_nim_default_GetSignalStrength(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pSignalStrength
++	);
++
++int
++dvbt_nim_default_GetSignalQuality(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pSignalQuality
++	);
++
++int
++dvbt_nim_default_GetBer(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long *pBerNum,
++	unsigned long *pBerDen
++	);
++
++int
++dvbt_nim_default_GetSnrDb(
++	DVBT_NIM_MODULE *pNim,
++	long *pSnrDbNum,
++	long *pSnrDbDen
++	);
++
++int
++dvbt_nim_default_GetTrOffsetPpm(
++	DVBT_NIM_MODULE *pNim,
++	long *pTrOffsetPpm
++	);
++
++int
++dvbt_nim_default_GetCrOffsetHz(
++	DVBT_NIM_MODULE *pNim,
++	long *pCrOffsetHz
++	);
++
++int
++dvbt_nim_default_GetTpsInfo(
++	DVBT_NIM_MODULE *pNim,
++	int *pConstellation,
++	int *pHierarchy,
++	int *pCodeRateLp,
++	int *pCodeRateHp,
++	int *pGuardInterval,
++	int *pFftMode
++	);
++
++int
++dvbt_nim_default_UpdateFunction(
++	DVBT_NIM_MODULE *pNim
++	);
++
++
++
++
++
++
++
++#endif
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/foundation.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/foundation.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,352 @@
++/**
++
++@file
++
++@brief   Fundamental interface definition
++
++Fundamental interface contains base function pointers and some mathematics tools.
++
++*/
++
++
++#include "foundation.h"
++
++
++
++
++
++// Base interface builder
++void
++BuildBaseInterface(
++	BASE_INTERFACE_MODULE **ppBaseInterface,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	unsigned char I2cReadingByteNumMax,
++	unsigned char I2cWritingByteNumMax,
++	BASE_FP_I2C_READ I2cRead,
++	BASE_FP_I2C_WRITE I2cWrite,
++	BASE_FP_WAIT_MS WaitMs
++	)
++{
++	// Set base interface module pointer.
++	*ppBaseInterface = pBaseInterfaceModuleMemory;
++
++
++	// Set all base interface function pointers and arguments.
++	(*ppBaseInterface)->I2cReadingByteNumMax      = I2cReadingByteNumMax;
++	(*ppBaseInterface)->I2cWritingByteNumMax      = I2cWritingByteNumMax;
++	(*ppBaseInterface)->I2cRead                   = I2cRead;
++	(*ppBaseInterface)->I2cWrite                  = I2cWrite;
++	(*ppBaseInterface)->WaitMs                    = WaitMs;
++	(*ppBaseInterface)->SetUserDefinedDataPointer = base_interface_SetUserDefinedDataPointer;
++	(*ppBaseInterface)->GetUserDefinedDataPointer = base_interface_GetUserDefinedDataPointer;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Set user defined data pointer of base interface structure for custom basic function implementation.
++
++@note
++	-# Base interface builder will set BASE_FP_SET_USER_DEFINED_DATA_POINTER() function pointer with
++	   base_interface_SetUserDefinedDataPointer().
++
++@see   BASE_FP_SET_USER_DEFINED_DATA_POINTER
++
++*/
++void
++base_interface_SetUserDefinedDataPointer(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	void *pUserDefinedData
++	)
++{
++	// Set user defined data pointer of base interface structure with user defined data pointer argument.
++	pBaseInterface->pUserDefinedData = pUserDefinedData;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Get user defined data pointer of base interface structure for custom basic function implementation.
++
++@note
++	-# Base interface builder will set BASE_FP_GET_USER_DEFINED_DATA_POINTER() function pointer with
++	   base_interface_GetUserDefinedDataPointer().
++
++@see   BASE_FP_GET_USER_DEFINED_DATA_POINTER
++
++*/
++void
++base_interface_GetUserDefinedDataPointer(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	void **ppUserDefinedData
++	)
++{
++	// Get user defined data pointer from base interface structure to the caller user defined data pointer.
++	*ppUserDefinedData = pBaseInterface->pUserDefinedData;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Convert signed integer to binary.
++
++Convert 2's complement signed integer to binary with bit number.
++
++
++@param [in]   Value    the converting value in 2's complement format
++@param [in]   BitNum   the bit number of the converting value
++
++
++@return   Converted binary
++
++
++@note
++	The converting value must be -pow(2, BitNum - 1) ~ (pow(2, BitNum - 1) -1).
++
++
++
++@par Example:
++@code
++
++
++#include "foundation.h"
++
++
++int main(void)
++{
++	long Value = -345;
++	unsigned long Binary;
++
++
++	// Convert 2's complement integer to binary with 10 bit number.
++	Binary = SignedIntToBin(Value, 10);
++
++
++	// Result in base 2:
++	// Value  = 1111 1111 1111 1111 1111 1110 1010 0111 b = -345  (in 32-bit 2's complement format)
++	// Binary = 0000 0000 0000 0000 0000 0010 1010 0111 b =  679  (in 10-bit binary format)
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++unsigned long
++SignedIntToBin(
++	long Value,
++	unsigned char BitNum
++	)
++{
++	unsigned int i;
++	unsigned long Mask, Binary;
++
++
++
++	// Generate Mask according to BitNum.
++	Mask = 0;
++	for(i = 0; i < BitNum; i++)
++		Mask |= 0x1 << i;
++
++
++	// Convert signed integer to binary with Mask.
++	Binary = Value & Mask;
++
++
++	return Binary;
++}
++
++
++
++
++
++/**
++
++@brief   Convert binary to signed integer.
++
++Convert binary to 2's complement signed integer with bit number.
++
++
++@param [in]   Binary   the converting binary
++@param [in]   BitNum   the bit number of the converting binary
++
++
++@return   Converted 2's complement signed integer
++
++
++@note
++	The converting binary must be 0 ~ (pow(2, BitNum) - 1).
++
++
++
++@par Example:
++@code
++
++
++#include "foundation.h"
++
++
++int main(void)
++{
++	unsigned long Binary = 679;
++	long Value;
++
++
++	// Convert binary to 2's complement integer with 10 bit number.
++	Value = BinToSignedInt(Binary, 10);
++
++
++	// Result in base 2:
++	// Binary = 0000 0000 0000 0000 0000 0010 1010 0111 b =  679  (in 10-bit binary format)
++	// Value  = 1111 1111 1111 1111 1111 1110 1010 0111 b = -345  (in 32-bit 2's complement format)
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++long
++BinToSignedInt(
++	unsigned long Binary,
++	unsigned char BitNum
++	)
++{
++	int i;
++
++	unsigned char SignedBit;
++	unsigned long SignedBitExtension;
++
++	long Value;
++
++
++
++	// Get signed bit.
++	SignedBit = (unsigned char)((Binary >> (BitNum - 1)) & BIT_0_MASK);
++
++
++	// Generate signed bit extension.
++	SignedBitExtension = 0;
++
++	for(i = BitNum; i < LONG_BIT_NUM; i++)
++		SignedBitExtension |= SignedBit << i;
++
++
++	// Combine binary value and signed bit extension to signed integer value.
++	Value = (long)(Binary | SignedBitExtension);
++
++
++	return Value;
++}
++
++
++
++
++
++/**
++
++@brief   Get devision reult with ceiling.
++
++Get unsigned devision reult with ceiling.
++
++
++@param [in]   Dividend   the dividend
++@param [in]   Divisor    the divisor
++
++
++@return   Result with ceiling
++
++
++@note
++	The dividend and divisor must be unsigned integer.
++
++
++
++@par Example:
++@code
++
++
++#include "foundation.h"
++
++
++int main(void)
++{
++	long Value;
++
++
++	// Get ceil(100 / 20) reult.
++	Value = DivideWithCeiling(100, 20);
++
++	// Result: Value  = 5
++
++
++	// Get ceil(100 / 30) reult.
++	Value = DivideWithCeiling(100, 30);
++
++	// Result: Value  = 4
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++unsigned long
++DivideWithCeiling(
++	unsigned long Dividend,
++	unsigned long Divisor
++	)
++{
++	unsigned long Result;
++
++
++	// Get primitive division result.
++	Result = Dividend / Divisor;
++
++	// Adjust primitive result with ceiling.
++	if(Dividend % Divisor > 0)
++		Result += 1;
++
++
++	return Result;
++}
++
++
++
++
++
++
++
++
++
++
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/foundation.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/foundation.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,891 @@
++#ifndef __FOUNDATION_H
++#define __FOUNDATION_H
++
++/**
++
++@file
++
++@brief   Fundamental interface declaration
++
++Fundamental interface contains base function pointers and some mathematics tools.
++
++*/
++
++
++#include "i2c_bridge.h"
++#include "math_mpi.h"
++#include "dvb-usb.h"
++#include "rtl2832u_io.h" 
++
++
++
++// Definitions
++
++// API version
++#define REALTEK_NIM_API_VERSION		"Realtek NIM API 2008.12.04"
++
++
++
++// Constants
++#define INVALID_POINTER_VALUE		0
++#define NO_USE						0
++
++#define LEN_1_BYTE					1
++#define LEN_2_BYTE					2
++#define LEN_3_BYTE					3
++#define LEN_4_BYTE					4
++#define LEN_5_BYTE					5
++#define LEN_6_BYTE					6
++#define LEN_11_BYTE					11
++
++#define LEN_1_BIT					1
++
++#define BYTE_MASK					0xff
++#define BYTE_SHIFT					8
++#define BYTE_BIT_NUM				8
++#define LONG_BIT_NUM				32
++
++#define BIT_0_MASK					0x1
++#define BIT_1_MASK					0x2
++#define BIT_3_MASK					0x8
++#define BIT_4_MASK					0x10
++#define BIT_8_MASK					0x100
++#define BIT_7_SHIFT					7
++#define BIT_8_SHIFT					8
++
++
++
++// I2C buffer length
++// Note: I2C_BUFFER_LEN must be greater than I2cReadingByteNumMax and I2cWritingByteNumMax in BASE_INTERFACE_MODULE.
++#define I2C_BUFFER_LEN				128
++
++
++
++
++
++/// Module types
++enum MODULE_TYPE
++{
++	// DVB-T demod
++	DVBT_DEMOD_TYPE_RTL2830,			///<   RTL2830 DVB-T demod
++	DVBT_DEMOD_TYPE_RTL2832,			///<   RTL2832 DVB-T demod
++
++	// QAM demod
++	QAM_DEMOD_TYPE_RTL2840,				///<   RTL2840 DVB-C demod
++	QAM_DEMOD_TYPE_RTL2810_OC,			///<   RTL2810 OpenCable demod
++	QAM_DEMOD_TYPE_RTL2820_OC,			///<   RTL2820 OpenCable demod
++	QAM_DEMOD_TYPE_RTD2885_QAM,			///<   RTD2885 QAM demod
++
++	// OOB demod
++	OOB_DEMOD_TYPE_RTL2820_OOB,			///<   RTL2820 OOB demod
++
++	// ATSC demod
++	ATSC_DEMOD_TYPE_RTL2820_ATSC,		///<   RTL2820 ATSC demod
++	ATSC_DEMOD_TYPE_RTD2885_ATSC,		///<   RTD2885 ATSC demod
++
++	// DTMB demod
++	DTMB_DEMOD_TYPE_RTL2836,			///<   RTL2836 DTMB demod
++
++	// Tuner
++	TUNER_TYPE_TDCGG052D,				///<   TDCG-G052D tuner (QAM)
++	TUNER_TYPE_TDCHG001D,				///<   TDCH-G001D tuner (QAM)
++	TUNER_TYPE_TDQE3003A,				///<   TDQE3-003A tuner (QAM)
++	TUNER_TYPE_DCT7045,					///<   DCT-7045 tuner (QAM)
++	TUNER_TYPE_MT2062,					///<   MT2062 tuner (QAM)
++	TUNER_TYPE_MXL5005S,				///<   MxL5005S tuner (DVB-T, ATSC)
++	TUNER_TYPE_TDVMH715P,				///<   TDVM-H751P tuner (QAM, OOB, ATSC)
++	TUNER_TYPE_UBA00AL,					///<   UBA00AL tuner (QAM, ATSC)
++	TUNER_TYPE_MT2266,					///<   MT2266 tuner (DVB-T)
++	TUNER_TYPE_FC2580,					///<   FC2580 tuner (DVB-T)
++	TUNER_TYPE_TUA9001,					///<   TUA9001 tuner (DVB-T)
++	TUNER_TYPE_DTT75300,				///<   DTT-75300 tuner (DVB-T)
++	TUNER_TYPE_MXL5007T,				///<   MxL5007T tuner (DVB-T, ATSC)
++
++	// DVB-T NIM
++	DVBT_NIM_USER_DEFINITION,			///<   DVB-T NIM:   User definition
++	DVBT_NIM_RTL2832_MT2266,			///<   DVB-T NIM:   RTL2832 + MT2266
++	DVBT_NIM_RTL2832_FC2580,			///<   DVB-T NIM:   RTL2832 + FC2580
++	DVBT_NIM_RTL2832_TUA9001,			///<   DVB-T NIM:   RTL2832 + TUA9001
++	DVBT_NIM_RTL2832_MXL5005S,			///<   DVB-T NIM:   RTL2832 + MxL5005S
++	DVBT_NIM_RTL2832_DTT75300,			///<   DVB-T NIM:   RTL2832 + DTT-75300
++	DVBT_NIM_RTL2832_MXL5007T,			///<   DVB-T NIM:   RTL2832 + MxL5007T
++
++	// QAM NIM
++	QAM_NIM_USER_DEFINITION,			///<   QAM NIM:   User definition
++	QAM_NIM_RTL2840_TDQE3003A,			///<   QAM NIM:   RTL2840 + TDQE3-003A
++	QAM_NIM_RTL2840_DCT7045,			///<   QAM NIM:   RTL2840 + DCT-7045
++	QAM_NIM_RTL2840_DCT7046,			///<   QAM NIM:   RTL2840 + DCT-7046
++	QAM_NIM_RTL2840_MT2062,				///<   QAM NIM:   RTL2840 + MT2062
++
++	// DCR NIM
++	DCR_NIM_RTL2820_TDVMH715P,			///<   DCR NIM:   RTL2820 + TDVM-H751P
++	DCR_NIM_RTD2885_UBA00AL,			///<   DCR NIM:   RTD2885 + UBA00AL
++
++	// DTMB NIM
++	DTMB_NIM_RTL2836_FC2580,			///<   DTMB NIM:   RTL2836 + FC2580
++};
++
++
++
++
++
++/// On/off status
++enum ON_OFF_STATUS
++{
++	OFF,		///<   Off
++	ON,			///<   On
++};
++
++
++/// Yes/no status
++enum YES_NO_STATUS
++{
++	NO,			///<   No
++	YES,		///<   Yes
++};
++
++
++/// Lock status
++enum LOCK_STATUS
++{
++	NOT_LOCKED,			///<   Not locked
++	LOCKED,				///<   Locked
++};
++
++
++/// Loss status
++enum LOSS_STATUS
++{
++	NOT_LOST,			///<   Not lost
++	LOST,				///<   Lost
++};
++
++
++/// Function return status
++enum FUNCTION_RETURN_STATUS
++{
++	FUNCTION_SUCCESS,			///<   Execute function successfully.
++	FUNCTION_ERROR,				///<   Execute function unsuccessfully.
++};
++
++
++/// Crystal frequency
++enum CRYSTAL_FREQ_HZ
++{
++	CRYSTAL_FREQ_4000000HZ  =  4000000,			///<   Crystal frequency =    4.0 MHz
++	CRYSTAL_FREQ_16000000HZ = 16000000,			///<   Crystal frequency =   16.0 MHz
++	CRYSTAL_FREQ_16384000HZ = 16384000,			///<   Crystal frequency = 16.384 MHz
++	CRYSTAL_FREQ_16457143HZ = 16457143,			///<   Crystal frequency = 16.457 MHz
++	CRYSTAL_FREQ_25000000HZ = 25000000,			///<   Crystal frequency =   25.0 MHz
++	CRYSTAL_FREQ_27000000HZ = 27000000,			///<   Crystal frequency =   27.0 MHz
++	CRYSTAL_FREQ_28800000HZ = 28800000,			///<   Crystal frequency =   28.8 MHz
++};
++
++
++/// IF frequency
++enum IF_FREQ_HZ
++{
++	IF_FREQ_0HZ        =        0,			///<   IF frequency =      0 MHz
++	IF_FREQ_4570000HZ  =  4570000,			///<   IF frequency =   4.57 MHz
++	IF_FREQ_4571429HZ  =  4571429,			///<   IF frequency =  4.571 MHz
++	IF_FREQ_36000000HZ = 36000000,			///<   IF frequency =   36.0 MHz
++	IF_FREQ_36125000HZ = 36125000,			///<   IF frequency = 36.125 MHz
++	IF_FREQ_36166667HZ = 36166667,			///<   IF frequency = 36.167 MHz
++	IF_FREQ_43750000HZ = 43750000,			///<   IF frequency =  43.75 MHz
++	IF_FREQ_44000000HZ = 44000000,			///<   IF frequency =   44.0 MHz
++};
++
++
++/// Spectrum mode
++enum SPECTRUM_MODE
++{
++	SPECTRUM_NORMAL,			///<   Normal spectrum
++	SPECTRUM_INVERSE,			///<   Inverse spectrum
++};
++#define SPECTRUM_MODE_NUM		2
++
++
++/// TS interface mode
++enum TS_INTERFACE_MODE
++{
++	TS_INTERFACE_PARALLEL,			///<   Parallel TS interface
++	TS_INTERFACE_SERIAL,			///<   Serial TS interface
++};
++#define TS_INTERFACE_MODE_NUM		2
++
++
++
++
++
++/// Base interface module alias
++typedef struct BASE_INTERFACE_MODULE_TAG BASE_INTERFACE_MODULE;
++
++
++
++
++
++/**
++
++@brief   Basic I2C reading function pointer
++
++Upper layer functions will use BASE_FP_I2C_READ() to read ByteNum bytes from I2C device to pReadingBytes buffer.
++
++
++@param [in]    pBaseInterface   The base interface module pointer
++@param [in]    DeviceAddr       I2C device address in 8-bit format
++@param [out]   pReadingBytes    Buffer pointer to an allocated memory for storing reading bytes
++@param [in]    ByteNum          Reading byte number
++
++
++@retval   FUNCTION_SUCCESS   Read bytes from I2C device with reading byte number successfully.
++@retval   FUNCTION_ERROR     Read bytes from I2C device unsuccessfully.
++
++
++@note
++	The requirements of BASE_FP_I2C_READ() function are described as follows:
++	-# Follow the I2C format for BASE_FP_I2C_READ(). \n
++	   start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit
++	-# Don't allocate memory on pReadingBytes.
++	-# Upper layer functions should allocate memory on pReadingBytes before using BASE_FP_I2C_READ().
++	-# Need to assign I2C reading funtion to BASE_FP_I2C_READ() for upper layer functions.
++
++
++
++@par Example:
++@code
++
++
++#include "foundation.h"
++
++
++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer.
++int
++CustomI2cRead(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	)
++{
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++
++	return FUNCTION_ERROR;
++}
++
++
++int main(void)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++	unsigned char ReadingBytes[100];
++
++
++	// Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module.
++	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...);
++
++	...
++
++	// Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes.
++	pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33);
++	
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef int
++(*BASE_FP_I2C_READ)(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	);
++
++
++
++
++
++/**
++
++@brief   Basic I2C writing function pointer
++
++Upper layer functions will use BASE_FP_I2C_WRITE() to write ByteNum bytes from pWritingBytes buffer to I2C device.
++
++
++@param [in]   pBaseInterface   The base interface module pointer
++@param [in]   DeviceAddr       I2C device address in 8-bit format
++@param [in]   pWritingBytes    Buffer pointer to writing bytes
++@param [in]   ByteNum          Writing byte number
++
++
++@retval   FUNCTION_SUCCESS   Write bytes to I2C device with writing bytes successfully.
++@retval   FUNCTION_ERROR     Write bytes to I2C device unsuccessfully.
++
++
++@note
++	The requirements of BASE_FP_I2C_WRITE() function are described as follows:
++	-# Follow the I2C format for BASE_FP_I2C_WRITE(). \n
++	   start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit
++	-# Need to assign I2C writing funtion to BASE_FP_I2C_WRITE() for upper layer functions.
++
++
++
++@par Example:
++@code
++
++
++#include "foundation.h"
++
++
++// Implement I2C writing funciton for BASE_FP_I2C_WRITE function pointer.
++int
++CustomI2cWrite(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	)
++{
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++
++	return FUNCTION_ERROR;
++}
++
++
++int main(void)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++	unsigned char WritingBytes[100];
++
++
++	// Assign implemented I2C writing funciton to BASE_FP_I2C_WRITE in base interface module.
++	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., ..., CustomI2cWrite, ...);
++
++	...
++
++	// Use I2cWrite() to write 33 bytes from WritingBytes to I2C device.
++	pBaseInterface->I2cWrite(pBaseInterface, 0x20, WritingBytes, 33);
++	
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef int
++(*BASE_FP_I2C_WRITE)(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	);
++
++
++
++
++
++/**
++
++@brief   Basic waiting function pointer
++
++Upper layer functions will use BASE_FP_WAIT_MS() to wait WaitTimeMs millisecond.
++
++
++@param [in]   pBaseInterface   The base interface module pointer
++@param [in]   WaitTimeMs       Waiting time in millisecond
++
++
++@note
++	The requirements of BASE_FP_WAIT_MS() function are described as follows:
++	-# Need to assign a waiting function to BASE_FP_WAIT_MS() for upper layer functions.
++
++
++
++@par Example:
++@code
++
++
++#include "foundation.h"
++
++
++// Implement waiting funciton for BASE_FP_WAIT_MS function pointer.
++void
++CustomWaitMs(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned long WaitTimeMs
++	)
++{
++	...
++
++	return;
++}
++
++
++int main(void)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++
++
++	// Assign implemented waiting funciton to BASE_FP_WAIT_MS in base interface module.
++	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., ..., ..., CustomWaitMs);
++
++	...
++
++	// Use WaitMs() to wait 30 millisecond.
++	pBaseInterface->WaitMs(pBaseInterface, 30);
++	
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef void
++(*BASE_FP_WAIT_MS)(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned long WaitTimeMs
++	);
++
++
++
++
++
++/**
++
++@brief   User defined data pointer setting function pointer
++
++One can use BASE_FP_SET_USER_DEFINED_DATA_POINTER() to set user defined data pointer of base interface structure for
++custom basic function implementation.
++
++
++@param [in]   pBaseInterface     The base interface module pointer
++@param [in]   pUserDefinedData   Pointer to user defined data
++
++
++@note
++	One can use BASE_FP_GET_USER_DEFINED_DATA_POINTER() to get user defined data pointer of base interface structure for
++	custom basic function implementation.
++
++
++
++@par Example:
++@code
++
++
++#include "foundation.h"
++
++
++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer.
++int
++CustomI2cRead(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	)
++{
++	CUSTOM_USER_DEFINED_DATA *pUserDefinedData;
++
++
++	// Get user defined data pointer of base interface structure for custom I2C reading function.
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&pUserDefinedData);
++
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++
++	return FUNCTION_ERROR;
++}
++
++
++int main(void)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++	unsigned char ReadingBytes[100];
++
++	CUSTOM_USER_DEFINED_DATA UserDefinedData;
++
++
++	// Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module.
++	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...);
++
++	...
++
++	// Set user defined data pointer of base interface structure for custom basic functions.
++	pBaseInterface->SetUserDefinedDataPointer(pBaseInterface, &UserDefinedData);
++
++	// Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes.
++	pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33);
++	
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef void
++(*BASE_FP_SET_USER_DEFINED_DATA_POINTER)(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	void *pUserDefinedData
++	);
++
++
++
++
++
++/**
++
++@brief   User defined data pointer getting function pointer
++
++One can use BASE_FP_GET_USER_DEFINED_DATA_POINTER() to get user defined data pointer of base interface structure for
++custom basic function implementation.
++
++
++@param [in]   pBaseInterface      The base interface module pointer
++@param [in]   ppUserDefinedData   Pointer to user defined data pointer
++
++
++@note
++	One can use BASE_FP_SET_USER_DEFINED_DATA_POINTER() to set user defined data pointer of base interface structure for
++	custom basic function implementation.
++
++
++
++@par Example:
++@code
++
++
++#include "foundation.h"
++
++
++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer.
++int
++CustomI2cRead(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	)
++{
++	CUSTOM_USER_DEFINED_DATA *pUserDefinedData;
++
++
++	// Get user defined data pointer of base interface structure for custom I2C reading function.
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&pUserDefinedData);
++
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++
++	return FUNCTION_ERROR;
++}
++
++
++int main(void)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++	unsigned char ReadingBytes[100];
++
++	CUSTOM_USER_DEFINED_DATA UserDefinedData;
++
++
++	// Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module.
++	BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...);
++
++	...
++
++	// Set user defined data pointer of base interface structure for custom basic functions.
++	pBaseInterface->SetUserDefinedDataPointer(pBaseInterface, &UserDefinedData);
++
++	// Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes.
++	pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33);
++	
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++typedef void
++(*BASE_FP_GET_USER_DEFINED_DATA_POINTER)(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	void **ppUserDefinedData
++	);
++
++
++
++
++
++/// Base interface module structure
++struct BASE_INTERFACE_MODULE_TAG
++{
++	// Variables and function pointers
++	unsigned char I2cReadingByteNumMax;
++	unsigned char I2cWritingByteNumMax;
++
++	BASE_FP_I2C_READ    I2cRead;
++	BASE_FP_I2C_WRITE   I2cWrite;
++	BASE_FP_WAIT_MS     WaitMs;
++
++	BASE_FP_SET_USER_DEFINED_DATA_POINTER   SetUserDefinedDataPointer;
++	BASE_FP_GET_USER_DEFINED_DATA_POINTER   GetUserDefinedDataPointer;
++
++
++	// User defined data
++	void *pUserDefinedData;
++};
++
++
++
++
++
++/**
++
++@brief   Base interface builder
++
++Use BuildBaseInterface() to build base interface for module functions to access basic functions.
++
++
++@param [in]   ppBaseInterface              Pointer to base interface module pointer
++@param [in]   pBaseInterfaceModuleMemory   Pointer to an allocated base interface module memory
++@param [in]   I2cReadingByteNumMax         Maximum I2C reading byte number for basic I2C reading function
++@param [in]   I2cWritingByteNumMax         Maximum I2C writing byte number for basic I2C writing function
++@param [in]   I2cRead                      Basic I2C reading function pointer
++@param [in]   I2cWrite                     Basic I2C writing function pointer
++@param [in]   WaitMs                       Basic waiting function pointer
++
++
++@note
++	-# One should build base interface before using module functions.
++	-# The I2C reading format is described as follows:
++	   start_bit + (device_addr | reading_bit) + reading_byte * byte_num + stop_bit
++	-# The I2cReadingByteNumMax is the maximum byte_num of the I2C reading format.
++	-# The I2C writing format is described as follows:
++	   start_bit + (device_addr | writing_bit) + writing_byte * byte_num + stop_bit
++	-# The I2cWritingByteNumMax is the maximum byte_num of the I2C writing format.
++
++
++
++@par Example:
++@code
++
++
++#include "foundation.h"
++
++
++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer.
++int
++CustomI2cRead(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	)
++{
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++
++	return FUNCTION_ERROR;
++}
++
++
++// Implement I2C writing funciton for BASE_FP_I2C_WRITE function pointer.
++int
++CustomI2cWrite(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	)
++{
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++
++	return FUNCTION_ERROR;
++}
++
++
++// Implement waiting funciton for BASE_FP_WAIT_MS function pointer.
++void
++CustomWaitMs(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned long WaitTimeMs
++	)
++{
++	...
++
++	return;
++}
++
++
++int main(void)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++
++
++	// Build base interface with the following settings.
++	//
++	// 1. Assign 9 to maximum I2C reading byte number.
++	// 2. Assign 8 to maximum I2C writing byte number.
++	// 3. Assign CustomI2cRead() to basic I2C reading function pointer.
++	// 4. Assign CustomI2cWrite() to basic I2C writing function pointer.
++	// 5. Assign CustomWaitMs() to basic waiting function pointer.
++	//
++	BuildBaseInterface(
++		&pBaseInterface,
++		&BaseInterfaceModuleMemory,
++		9,
++		8,
++		CustomI2cRead,
++		CustomI2cWrite,
++		CustomWaitMs
++		);
++
++	...
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++void
++BuildBaseInterface(
++	BASE_INTERFACE_MODULE **ppBaseInterface,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	unsigned char I2cReadingByteNumMax,
++	unsigned char I2cWritingByteNumMax,
++	BASE_FP_I2C_READ I2cRead,
++	BASE_FP_I2C_WRITE I2cWrite,
++	BASE_FP_WAIT_MS WaitMs
++	);
++
++
++
++
++
++// User data pointer of base interface structure setting and getting functions
++void
++base_interface_SetUserDefinedDataPointer(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	void *pUserDefinedData
++	);
++
++void
++base_interface_GetUserDefinedDataPointer(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	void **ppUserDefinedData
++	);
++
++
++
++
++
++// Math functions
++
++// Binary and signed integer converter
++unsigned long
++SignedIntToBin(
++	long Value,
++	unsigned char BitNum
++	);
++
++long
++BinToSignedInt(
++	unsigned long Binary,
++	unsigned char BitNum
++	);
++
++
++
++// Arithmetic
++unsigned long
++DivideWithCeiling(
++	unsigned long Dividend,
++	unsigned long Divisor
++	);
++
++
++
++
++
++
++
++
++
++
++
++/**
++
++@mainpage Realtek demod Source Code Manual
++
++@note
++	-# The Realtek demod API source code is designed for demod IC driver porting.
++	-# The API source code is written in C language without floating-point arithmetic.
++	-# One can use the API to manipulate Realtek demod IC.
++	-# The API will call custom underlayer functions through API base interface module.
++
++
++@par Important:
++	-# Please assign API base interface module with custom underlayer functions instead of modifying API source code.
++	-# Please see the example code to understand the relation bewteen API and custom system.
++
++*/
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++#endif
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/history.txt
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/history.txt	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,11 @@
++
++History of Realtek RTL2832U DVB-T Linux Driver: 
++
++
++Ver 1.1  a. add customers' VID&PID
++         b. solve the bug that our module cann't be removed when the device is plugged out.
++
++Ver 1.0  support  tuners--MT2266 FC2580 TUA9001 and MXL5007T 		
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/i2c_bridge.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/i2c_bridge.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,119 @@
++#ifndef __I2C_BRIDGE_H
++#define __I2C_BRIDGE_H
++
++/**
++
++@file
++
++@brief   I2C bridge module
++
++I2C bridge module contains I2C forwarding function pointers.
++
++*/
++
++
++
++
++
++/// I2C bridge module pre-definition
++typedef struct I2C_BRIDGE_MODULE_TAG I2C_BRIDGE_MODULE;
++
++
++
++
++
++/**
++
++@brief   I2C reading command forwarding function pointer
++
++Tuner upper level functions will use I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD() to send tuner I2C reading command through
++demod.
++
++
++@param [in]    pI2cBridge      The I2C bridge module pointer
++@param [out]   pReadingBytes   Pointer to an allocated memory for storing reading bytes
++@param [in]    ByteNum         Reading byte number
++
++
++@retval   FUNCTION_SUCCESS   Forwarding I2C reading command successfully.
++@retval   FUNCTION_ERROR     Forwarding I2C reading command unsuccessfully.
++
++
++@note
++	-# Demod building function will set I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD() with the corresponding function.
++
++*/
++typedef int
++(*I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD)(
++	I2C_BRIDGE_MODULE *pI2cBridge,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	);
++
++
++
++
++
++/**
++
++@brief   I2C writing command forwarding function pointer
++
++Tuner upper level functions will use I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD() to send tuner I2C writing command through
++demod.
++
++
++@param [in]    pI2cBridge      The I2C bridge module pointer
++@param [out]   pWritingBytes   Pointer to writing bytes
++@param [in]    ByteNum         Writing byte number
++
++
++@retval   FUNCTION_SUCCESS   Forwarding I2C writing command successfully.
++@retval   FUNCTION_ERROR     Forwarding I2C writing command unsuccessfully.
++
++
++@note
++	-# Demod building function will set I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD() with the corresponding function.
++
++*/
++typedef int
++(*I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD)(
++	I2C_BRIDGE_MODULE *pI2cBridge,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	);
++
++
++
++
++
++/// I2C bridge module structure
++struct I2C_BRIDGE_MODULE_TAG
++{
++	// Private variables
++	void *pPrivateData;
++	unsigned char *pTunerDeviceAddr;
++
++
++	// I2C bridge function pointers
++	I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD   ForwardI2cReadingCmd;	///<   I2C reading command forwading function pointer
++	I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD   ForwardI2cWritingCmd;   ///<   I2C writing command forwading function pointer
++
++};
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++#endif
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/math_mpi.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/math_mpi.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,1054 @@
++/**
++
++@file
++
++@brief   Mutliple precision integer (MPI) arithmetic definition
++
++One can use to mutliple precision arithmetic to manipulate large signed integers.
++
++*/
++
++
++#include "math_mpi.h"
++
++
++
++
++
++/**
++
++@brief   Set multiple precision signed integer value.
++
++Use MpiSetValue() to set multiple precision signed integer MPI value.
++
++
++@param [in]   pMpiVar   Pointer to an MPI variable
++@param [in]   Value     Value for setting
++
++
++@note
++	The MPI bit number will be minimized in MpiSetValue().
++
++*/
++void
++MpiSetValue(
++	MPI *pMpiVar,
++	long Value
++	)
++{
++	int i;
++	unsigned char SignedBit;
++	unsigned char ExtensionByte;
++
++
++
++	// Set MPI value according to ansigned value.
++	for(i = 0; i < MPI_LONG_BYTE_NUM; i++)
++		pMpiVar->Value[i] = (unsigned char)((Value >> (MPI_BYTE_SHIFT * i)) & MPI_BYTE_MASK);
++
++	
++	// Get extension byte according to signed bit.
++	SignedBit = (unsigned char)((Value >> (MPI_LONG_BIT_NUM - 1)) & MPI_BIT_0_MASK);
++	ExtensionByte = (SignedBit == 0x0) ? 0x00 : 0xff;
++
++
++	// Extend MPI signed bit with extension byte stuff.
++	for(i = MPI_LONG_BYTE_NUM; i < MPI_VALUE_BYTE_NUM_MAX; i++)
++		pMpiVar->Value[i] = ExtensionByte;
++
++
++	// Minimize MPI bit number.
++	MpiMinimizeBitNum(pMpiVar);
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Get multiple precision signed integer value.
++
++Use MpiGetValue() to get multiple precision unsigned integer MPI value.
++
++
++@param [in]    MpiVar   Pointer to an MPI variable
++@param [out]   pValue   Pointer to an allocated memory for getting MPI value
++
++
++@note
++    The necessary bit number of MPI value must be less than or equal to 32 bits.
++
++*/
++void
++MpiGetValue(
++	MPI MpiVar,
++	long *pValue
++	)
++{
++	int i;
++	unsigned long Value;
++
++
++
++	// Set value with zero.
++	Value = 0x0;
++
++
++	// Combine MPI value bytes into value.
++	for(i = 0; i < MPI_LONG_BYTE_NUM; i++)
++		Value |= MpiVar.Value[i] << (MPI_BYTE_SHIFT * i);
++
++
++	// Assigned value to value pointer.
++	*pValue = (long)Value;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Set multiple precision signed integer bit value.
++
++Use MpiSetBit() to set multiple precision signed integer MPI bit value.
++
++
++@param [in]   pMpiVar       Pointer to an MPI variable
++@param [in]   BitPosition   Bit position with zero-based index
++@param [in]   BitValue      Bit value for setting
++
++
++@note
++	Bit position must be 0 ~ (MPI bit number).
++
++*/
++void
++MpiSetBit(
++	MPI *pMpiVar,
++	unsigned long BitPosition,
++	unsigned char BitValue
++	)
++{
++	unsigned long TargetBytePos, TargetBitPos;
++
++
++
++	// Calculate target byte and bit position.
++	TargetBytePos = BitPosition / MPI_BYTE_BIT_NUM;
++	TargetBitPos  = BitPosition % MPI_BYTE_BIT_NUM;
++
++
++	// Set MPI bit value according to calculated target byte and bit position.
++	pMpiVar->Value[TargetBytePos] &= (unsigned char)(~(0x1 << TargetBitPos));
++	pMpiVar->Value[TargetBytePos] |= (BitValue & MPI_BIT_0_MASK) << TargetBitPos;
++
++
++	return;
++}
++
++
++
++
++
++
++/**
++
++@brief   Get multiple precision signed integer bit value.
++
++Use MpiGetBit() to get multiple precision unsigned integer MPI bit value.
++
++
++@param [in]    MpiVar        Pointer to an MPI variable
++@param [in]    BitPosition   Bit position with zero-based index
++@param [out]   pBitValue     Pointer to an allocated memory for getting MPI bit value
++
++
++@note
++	Bit position must be 0 ~ (MPI bit number).
++
++*/
++void
++MpiGetBit(
++	MPI MpiVar,
++	unsigned long BitPosition,
++	unsigned char *pBitValue
++	)
++{
++	unsigned long TargetBytePos, TargetBitPos;
++
++
++
++	// Calculate target byte and bit position.
++	TargetBytePos = BitPosition / MPI_BYTE_BIT_NUM;
++	TargetBitPos  = BitPosition % MPI_BYTE_BIT_NUM;
++
++
++	// Get MPI bit value according to calculated target byte and bit position.
++	*pBitValue = (MpiVar.Value[TargetBytePos] >> TargetBitPos) & MPI_BIT_0_MASK;
++
++
++	return;
++}
++	
++
++
++
++	
++/**
++
++@brief   Get multiple precision signed integer signed bit value.
++
++Use MpiGetBit() to get multiple precision unsigned integer MPI signed bit value.
++
++
++@param [in]    MpiVar            Pointer to an MPI variable
++@param [out]   pSignedBitValue   Pointer to an allocated memory for getting MPI signed bit value
++
++*/
++void
++MpiGetSignedBit(
++	MPI MpiVar,
++	unsigned char *pSignedBitValue
++	)
++{
++	// Get MPI variable signed bit.
++	MpiGetBit(MpiVar, MPI_VALUE_BIT_NUM_MAX - 1, pSignedBitValue);
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Assign multiple precision signed integer with another one.
++
++Use MpiAssign() to assign multiple precision signed integer with another one.
++
++
++@param [out]   pResult   Pointer to an allocated memory for storing result
++@param [in]    Operand   Operand
++
++
++@note
++	The result bit number will be minimized in MpiAssign().
++
++*/
++void
++MpiAssign(
++	MPI *pResult,
++	MPI Operand
++	)
++{
++	unsigned int i;
++
++
++
++	// Copy value bytes from operand to result.
++	for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++)
++		pResult->Value[i] = Operand.Value[i];
++
++
++	// Minimize result bit nubmer.
++	MpiMinimizeBitNum(pResult);
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Minus unary multiple precision signed integer.
++
++Use MpiUnaryMinus() to minus unary multiple precision signed integer.
++
++
++@param [out]   pResult   Pointer to an allocated memory for storing result
++@param [in]    Operand   Operand
++
++
++@note
++	The result bit number will be minimized in MpiUnaryMinus().
++
++*/
++void
++MpiUnaryMinus(
++	MPI *pResult,
++	MPI Operand
++	)
++{
++	unsigned int i;
++	MPI Const;
++
++
++
++	// Set result value byte with operand bitwise complement value byte.
++	for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++)
++		pResult->Value[i] = ~Operand.Value[i];
++
++
++	// Add result with 0x1.
++	// Note: MpiAdd() will minimize result bit number.
++	MpiSetValue(&Const, 0x1);
++	MpiAdd(pResult, *pResult, Const);
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Add multiple precision signed integers.
++
++Use MpiAdd() to add multiple precision signed integers.
++
++
++@param [out]   pSum     Pointer to an allocated memory for storing sum
++@param [in]    Augend   Augend
++@param [in]    Addend   Addend
++
++
++@note
++	The sum bit number will be minimized in MpiAdd().
++
++*/
++void
++MpiAdd(
++	MPI *pSum,
++	MPI Augend,
++	MPI Addend
++	)
++{
++	unsigned int i;
++	unsigned long MiddleResult;
++	unsigned char Carry;
++
++
++	// Add augend and addend to sum form value LSB byte to value MSB byte.
++	Carry = 0;
++
++	for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++)
++	{
++		// Set current sum value byte and determine carry.
++		MiddleResult   = Augend.Value[i] + Addend.Value[i] + Carry;
++		pSum->Value[i] = (unsigned char)(MiddleResult & MPI_BYTE_MASK);
++		Carry          = (unsigned char)((MiddleResult >> MPI_BYTE_SHIFT) & MPI_BYTE_MASK);
++	}
++	
++
++	// Minimize sum bit nubmer.
++	MpiMinimizeBitNum(pSum);
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   subtract multiple precision signed integers.
++
++Use MpiSub() to subtract multiple precision signed integers.
++
++
++@param [out]   pDifference   Pointer to an allocated memory for storing difference
++@param [in]    Minuend       Minuend
++@param [in]    Subtrahend    Subtrahend
++
++
++@note
++	The difference bit number will be minimized in MpiSub().
++
++*/
++void
++MpiSub(
++	MPI *pDifference,
++	MPI Minuend,
++	MPI Subtrahend
++	)
++{
++	MPI MiddleResult;
++
++
++
++	// Take subtrahend unary minus value.
++	MpiUnaryMinus(&MiddleResult, Subtrahend);
++
++
++	// Add minuend and subtrahend unary minus value to difference.
++	// Note: MpiAdd() will minimize result bit number.
++	MpiAdd(pDifference, Minuend, MiddleResult);
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Multiply arbitrary precision signed integers.
++
++Use MpiMul() to multiply arbitrary precision signed integers.
++
++
++@param [out]   pProduct        Pointer to an allocated memory for storing product
++@param [in]    Multiplicand    Multiplicand
++@param [in]    Multiplicator   Multiplicator
++
++
++@note
++	-# The sum of multiplicand and multiplicator bit number must be less MPI_VALUE_BIT_NUM_MAX.
++	-# The product bit number will be minimized in MpiMul().
++
++*/
++void
++MpiMul(
++	MPI *pProduct,
++	MPI Multiplicand,
++	MPI Multiplicator
++	)
++{
++	int i;
++
++	unsigned char MultiplicandSignedBit, MultiplicatorSignedBit;
++	MPI MultiplicandAbs, MultiplicatorAbs;
++
++	unsigned char CurrentBit;
++
++
++
++	// Get multiplicand signed bit.
++	MpiGetSignedBit(Multiplicand, &MultiplicandSignedBit);
++
++	// Take absolute value of multiplicand.
++	if(MultiplicandSignedBit == 0x0)
++		MpiAssign(&MultiplicandAbs, Multiplicand);
++	else
++		MpiUnaryMinus(&MultiplicandAbs, Multiplicand);
++
++
++	// Get multiplicator signed bit.
++	MpiGetSignedBit(Multiplicator, &MultiplicatorSignedBit);
++
++	// Take absolute value of multiplicator.
++	if(MultiplicatorSignedBit == 0x0)
++		MpiAssign(&MultiplicatorAbs, Multiplicator);
++	else
++		MpiUnaryMinus(&MultiplicatorAbs, Multiplicator);
++
++
++	// Multiply multiplicand and multiplicator from LSB bit to MSB bit.
++	MpiSetValue(pProduct, 0x0);
++
++	for(i = MPI_VALUE_BIT_NUM_MAX - 1; i > -1; i--)
++	{
++		// Shift product toward left with one bit.
++		MpiLeftShift(pProduct, *pProduct, 1);
++
++		// Get current absolute multiplicator bit value.
++		MpiGetBit(MultiplicatorAbs, i, &CurrentBit);
++
++		// If current multiplicator bit is 0x1, add absolute multiplicand value to product.
++		// Note: MpiAdd() will minimize result bit number.
++		if(CurrentBit == 0x1)
++			MpiAdd(pProduct, *pProduct, MultiplicandAbs);
++	}
++
++
++	// Determine the signed bit of product according to signed bits of multiplicand and multiplicator.
++	// Note: MpiUnaryMinus() will minimize result bit number.
++	if(MultiplicandSignedBit != MultiplicatorSignedBit)
++		MpiUnaryMinus(pProduct, *pProduct);
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Divide arbitrary precision signed integers.
++
++Use MpiDiv() to divide arbitrary precision signed integers.
++
++
++@param [out]   pQuotient    Pointer to an allocated memory for storing quotient
++@param [out]   pRemainder   Pointer to an allocated memory for storing remainder
++@param [in]    Dividend     Dividend
++@param [in]    Divisor      Divisor
++
++
++@note
++	-# The dividend bit number must be minimized.
++	-# The divisor must be not equal to zero.
++	-# The product bit number will be minimized in MpiDiv().
++
++*/
++void
++MpiDiv(
++	MPI *pQuotient,
++	MPI *pRemainder,
++	MPI Dividend,
++	MPI Divisor
++	)
++{
++	unsigned int i;
++
++	unsigned char DividendSignedBit, DivisorSignedBit;
++	MPI DividendAbs, DivisorAbs;
++
++	unsigned long PrimaryDividendBitNum;
++	unsigned char ShiftBit;
++
++	MPI Const;
++	MPI MiddleResult;
++
++
++
++	// Get dividend signed bit.
++	MpiGetSignedBit(Dividend, &DividendSignedBit);
++
++	// Take absolute value of dividend.
++	if(DividendSignedBit == 0x0)
++		MpiAssign(&DividendAbs, Dividend);
++	else
++		MpiUnaryMinus(&DividendAbs, Dividend);
++
++
++	// Get divisor signed bit.
++	MpiGetSignedBit(Divisor, &DivisorSignedBit);
++
++	// Take absolute value of divisor.
++	if(DivisorSignedBit == 0x0)
++		MpiAssign(&DivisorAbs, Divisor);
++	else
++		MpiUnaryMinus(&DivisorAbs, Divisor);
++
++
++	// Get primary absolute dividend bit number.
++	PrimaryDividendBitNum = DividendAbs.BitNum;
++
++
++	// Get quotient and remainder by division algorithm.
++	MpiSetValue(pQuotient, 0x0);
++	MpiSetValue(pRemainder, 0x0);
++
++	for(i = 0; i < PrimaryDividendBitNum; i++)
++	{
++		// Shift quotient toward left with one bit.
++		// Note: MpiLeftShift() will minimize result bit number.
++		MpiLeftShift(pQuotient, *pQuotient, 1);
++
++		// Shift remainder toward left with one bit.
++		MpiLeftShift(pRemainder, *pRemainder, 1);
++
++		// Shift absolute dividend toward left with one bit.
++		MpiLeftShift(&DividendAbs, DividendAbs, 1);
++
++		// Set remainder LSB according to absolute dividend.
++		MpiGetBit(DividendAbs, PrimaryDividendBitNum, &ShiftBit);
++		MpiSetBit(pRemainder, 0, ShiftBit);
++
++		// If remainder is greater than or equal to absolute divisor,
++		// substract absolute divisor from remainder and set quotient LSB with one.
++		if(MpiGreaterThan(*pRemainder, DivisorAbs) || MpiEqualTo(*pRemainder, DivisorAbs))
++		{
++			MpiSub(pRemainder, *pRemainder, DivisorAbs);
++			MpiSetBit(pQuotient, 0, 0x1);
++		}
++	}
++
++
++	// Modify quotient according to dividend signed bit, divisor signed bit, and remainder.
++
++	// Determine the signed bit of quotient.
++	if(DividendSignedBit != DivisorSignedBit)
++	{
++		// Take unary minus quotient.
++		// Note: MpiUnaryMinus() will minimize result bit number.
++		MpiUnaryMinus(pQuotient, *pQuotient);
++
++		// If remainder is greater than zero, subtract 1 from quotient.
++		// Note: MpiSub() will minimize result bit number.
++		MpiSetValue(&Const, 0x0);
++
++		if(MpiGreaterThan(*pRemainder, Const))
++		{
++			MpiSetValue(&Const, 0x1);
++			MpiSub(pQuotient, *pQuotient, Const);
++		}
++	}
++
++
++	// Modify remainder according to dividend, divisor, and quotient.
++
++	// Remainder = dividend - divisor * quotient;
++	// Note: MpiSub() will minimize result bit number.
++	MpiMul(&MiddleResult, Divisor, *pQuotient);
++	MpiSub(pRemainder, Dividend, MiddleResult);
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Shift multiple precision signed integer toward right.
++
++Use MpiRightShift() to shift arbitrary precision signed integer toward right with assigned bit number.
++
++
++@param [out]   pResult       Pointer to an allocated memory for storing result
++@param [in]    Operand       Operand
++@param [in]    ShiftBitNum   Shift bit number
++
++
++@note
++	-# The result MSB bits will be stuffed with signed bit
++	-# The result bit number will be minimized in MpiRightShift().
++
++*/
++void
++MpiRightShift(
++	MPI *pResult,
++	MPI Operand,
++	unsigned long ShiftBitNum
++	)
++{
++	unsigned int i;
++	unsigned long StuffBitNum;
++	unsigned char CurrentBit;
++	unsigned char SignedBit;
++
++
++
++	// Determine stuff bit number according to shift bit nubmer.
++	StuffBitNum = (ShiftBitNum < MPI_VALUE_BIT_NUM_MAX) ? ShiftBitNum : MPI_VALUE_BIT_NUM_MAX;
++
++
++	// Copy operand bits to result with stuff bit number.
++	for(i = 0; i < (MPI_VALUE_BIT_NUM_MAX - StuffBitNum); i++)
++	{
++		MpiGetBit(Operand, i + StuffBitNum, &CurrentBit);
++		MpiSetBit(pResult, i, CurrentBit);
++	}
++
++
++	// Get operand signed bit.
++	MpiGetSignedBit(Operand, &SignedBit);
++
++
++	// Stuff result MSB bits with signed bit.
++	for(i = (MPI_VALUE_BIT_NUM_MAX - StuffBitNum); i < MPI_VALUE_BIT_NUM_MAX; i++)
++		MpiSetBit(pResult, i, SignedBit);
++
++
++	// Minimize result bit number.
++	MpiMinimizeBitNum(pResult);
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Shift multiple precision signed integer toward left.
++
++Use MpiLeftShift() to shift arbitrary precision signed integer toward left with assigned bit number.
++
++
++@param [out]   pResult       Pointer to an allocated memory for storing result
++@param [in]    Operand       Operand
++@param [in]    ShiftBitNum   Shift bit number
++
++
++@note
++	The result bit number will be minimized in MpiLeftShift().
++
++*/
++void
++MpiLeftShift(
++	MPI *pResult,
++	MPI Operand,
++	unsigned long ShiftBitNum
++	)
++{
++	unsigned int i;
++	unsigned long StuffBitNum;
++	unsigned char CurrentBit;
++
++
++	// Determine stuff bit number according to shift bit nubmer.
++	StuffBitNum = (ShiftBitNum < MPI_VALUE_BIT_NUM_MAX) ? ShiftBitNum : MPI_VALUE_BIT_NUM_MAX;
++
++
++	// Stuff result LSB bits with zeros
++	for(i = 0; i < StuffBitNum; i++)
++		MpiSetBit(pResult, i, 0x0);
++
++
++	// Copy operand bits to result with stuff bit number.
++	for(i = StuffBitNum; i < MPI_VALUE_BIT_NUM_MAX; i++)
++	{
++		MpiGetBit(Operand, i - StuffBitNum, &CurrentBit);
++		MpiSetBit(pResult, i, CurrentBit);
++	}
++
++
++	// Minimize result bit number.
++	MpiMinimizeBitNum(pResult);
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Compare multiple precision signed integes with equal-to criterion.
++
++Use MpiEqualTo() to compare multiple precision signed integes with equal-to criterion.
++
++
++@param [in]   MpiLeft    Left MPI
++@param [in]   MpiRight   Right MPI
++
++
++@retval   MPI_NO    "Left MPI == Right MPI" is false.
++@retval   MPI_YES   "Left MPI == Right MPI" is true.
++
++
++@note
++	The constants MPI_YES and MPI_NO are defined in MPI_YES_NO_STATUS enumeration.
++
++*/
++int
++MpiEqualTo(
++	MPI MpiLeft,
++	MPI MpiRight
++	)
++{
++	unsigned int i;
++
++
++
++	// Check not-equal-to condition.
++	for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++)
++	{
++		if(MpiLeft.Value[i] != MpiRight.Value[i])
++			goto condition_others;
++	}
++		
++
++	// Right MPI is greater than left MPI.
++	return MPI_YES;
++
++
++condition_others:
++
++
++	// Other conditions.
++	return MPI_NO;
++}
++
++
++
++
++
++/**
++
++@brief   Compare multiple precision signed integes with greater-than criterion.
++
++Use MpiGreaterThan() to compare multiple precision signed integes with greater-than criterion.
++
++
++@param [in]   MpiLeft    Left MPI
++@param [in]   MpiRight   Right MPI
++
++
++@retval   MPI_NO    "Left MPI > Right MPI" is false.
++@retval   MPI_YES   "Left MPI > Right MPI" is true.
++
++
++@note
++	The constants MPI_YES and MPI_NO are defined in MPI_YES_NO_STATUS enumeration.
++
++*/
++int
++MpiGreaterThan(
++	MPI MpiLeft,
++	MPI MpiRight
++	)
++{
++	MPI MiddleResult;
++	unsigned char SignedBit;
++
++
++
++	// Check equal-to condition.
++	if(MpiEqualTo(MpiLeft, MpiRight) == MPI_YES)
++		goto condition_others;
++
++
++	// Subtract right MPI form left MPI.
++	MpiSub(&MiddleResult, MpiLeft, MpiRight);
++
++
++	// Check less-than condition.
++	MpiGetSignedBit(MiddleResult, &SignedBit);
++
++	if(SignedBit == 0x1)
++		goto condition_others;
++
++
++	// Right MPI is greater than left MPI.
++	return MPI_YES;
++
++
++condition_others:
++
++
++	// Other conditions.
++	return MPI_NO;
++}
++
++
++
++
++
++/**
++
++@brief   Compare multiple precision signed integes with less-than criterion.
++
++Use MpiLessThan() to compare multiple precision signed integes with less-than criterion.
++
++
++@param [in]   MpiLeft    Left MPI
++@param [in]   MpiRight   Right MPI
++
++
++@retval   MPI_NO    "Left MPI < Right MPI" is false.
++@retval   MPI_YES   "Left MPI < Right MPI" is true.
++
++
++@note
++	The constants MPI_YES and MPI_NO are defined in MPI_YES_NO_STATUS enumeration.
++
++*/
++int
++MpiLessThan(
++	MPI MpiLeft,
++	MPI MpiRight
++	)
++{
++	MPI MiddleResult;
++	unsigned char SignedBit;
++
++
++
++	// Check equal-to condition.
++	if(MpiEqualTo(MpiLeft, MpiRight) == MPI_YES)
++		goto condition_others;
++
++
++	// Subtract right MPI form left MPI.
++	MpiSub(&MiddleResult, MpiLeft, MpiRight);
++
++
++	// Check greater-than condition.
++	MpiGetSignedBit(MiddleResult, &SignedBit);
++
++	if(SignedBit == 0x0)
++		goto condition_others;
++
++
++	// Right MPI is less than left MPI.
++	return MPI_YES;
++
++
++condition_others:
++
++
++	// Other conditions.
++	return MPI_NO;
++}
++
++
++
++
++
++/**
++
++@brief   Minimize multiple precision signed integer bit number.
++
++Use MpiMinimizeBitNum() to minimize multiple precision signed integer MPI bit number.
++
++
++@param [in]   pMpiVar   Pointer to an allocated memory for storing result
++
++*/
++void
++MpiMinimizeBitNum(
++	MPI *pMpiVar
++	)
++{
++	int i;
++	unsigned char SignedBit;
++	unsigned char BitValue;
++
++
++
++	// Get signed bit form MPI;
++	MpiGetSignedBit(*pMpiVar, &SignedBit);
++
++
++	// Find MPI MSB position.
++	// Note: The MSB of signed integer is the rightest signed bit.
++	for(i = (MPI_VALUE_BIT_NUM_MAX - 2); i > -1; i--)
++	{
++		// Get current bit value.
++		MpiGetBit(*pMpiVar, i, &BitValue);
++
++		// Compare current bit with signed bit.
++		if(BitValue != SignedBit)
++			break;
++	}
++
++
++	// Set MPI bit number.
++	// Note: MPI bit number must be greater than one.
++	pMpiVar->BitNum = (i == -1) ? 2 : (i + 2);
++
++
++	return;
++}
++
++
++
++
++
++
++/**
++
++@brief   Calculate multiple precision signed integer logarithm with base 2.
++
++Use MpiMinimizeBitNum() to calculate multiple precision signed integer logarithm with base 2.
++
++
++@param [out]   pResult            Pointer to an allocated memory for storing result (unit: pow(2, - ResultFracBitNum))
++@param [in]    MpiVar             MPI variable for calculating
++@param [in]    ResultFracBitNum   Result fraction bit number
++
++
++@note
++	-# MPI variable bit number must be minimized.
++	-# MPI variable bit number must be less than (MPI_VALUE_BIT_NUM_MAX / 2 + 1).
++    -# MPI variable must be greater than zero.
++	-# If MPI variable is zero, the result is zero in MpiLog2().
++	-# The result bit number will be minimized in MpiLog2().
++
++*/
++void
++MpiLog2(
++	MPI *pResult,
++	MPI MpiVar,
++	unsigned long ResultFracBitNum
++	)
++{
++	unsigned int i;
++	MPI MiddleResult;
++	unsigned char BitValue;
++
++
++
++	// Get integer part of MPI logarithm result with base 2.
++	MpiSetValue(pResult, (long)(MpiVar.BitNum - 2));
++
++
++	// Get fraction part of MPI logarithm result with base 2 by logarithm algorithm.
++	// Note: Take middle result format as follows:
++	//                         x x . x x ~ x
++	//       (integer part 2 bits) . (fraction part MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM bits)
++	
++	// Set middle result with initial value.
++	MpiLeftShift(&MiddleResult, MpiVar, (MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM - MpiVar.BitNum + 2));
++
++	// Calculate result fraction bits.
++	for(i = 0; i < ResultFracBitNum; i++)
++	{
++		// Shift result toward left with one bit.
++		// Note: MpiLeftShift() will minimize result bit number.
++		MpiLeftShift(pResult, *pResult, 1);
++
++		// Square middle result.
++		MpiMul(&MiddleResult, MiddleResult, MiddleResult);
++
++		// Shift middle result toward right with fraction bit num.
++		MpiRightShift(&MiddleResult, MiddleResult, MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM);
++
++		// Get middle result integer part bit 1.
++		MpiGetBit(MiddleResult, MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM + 1, &BitValue);
++
++		// If middle result integer part bit 1 is equal to 0x1,
++		// shift middle result with one bit toward right and set result LSB with one.
++		if(BitValue == 0x1)
++		{
++			MpiRightShift(&MiddleResult, MiddleResult, 1);
++			MpiSetBit(pResult, 0, 0x1);
++		}
++	}
++
++
++	return;
++}
++
++
++
++
++
++
++
++
++
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/math_mpi.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/math_mpi.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,201 @@
++#ifndef __MATH_MPI_H
++#define __MATH_MPI_H
++
++/**
++
++@file
++
++@brief   Mutliple precision integer (MPI) arithmetic declaration
++
++One can use to mutliple precision arithmetic to manipulate large signed integers.
++
++*/
++
++
++
++
++
++// Constant
++#define MPI_BYTE_BIT_NUM			8
++#define MPI_LONG_BYTE_NUM			4
++#define MPI_LONG_BIT_NUM			32
++
++
++
++// Mask and shift
++#define MPI_BYTE_MASK				0xff
++#define MPI_BYTE_SHIFT				8
++
++#define MPI_BIT_0_MASK				0x1
++#define MPI_BIT_7_SHIFT				7
++
++
++
++// Multiple precision integer definition
++#define MPI_VALUE_BYTE_NUM_MAX		10												///<   Maximum MPI value byte number
++#define MPI_VALUE_BIT_NUM_MAX		(MPI_VALUE_BYTE_NUM_MAX * MPI_BYTE_BIT_NUM)		///<   Maximum MPI value bit number
++
++/// Multiple precision integer structure
++typedef struct
++{
++	unsigned long BitNum;
++	unsigned char Value[MPI_VALUE_BYTE_NUM_MAX];
++}
++MPI;
++
++
++
++///  MPI yes/no status
++enum MPI_YES_NO_STATUS
++{
++	MPI_NO,			///<   No
++	MPI_YES,		///<   Yes
++};
++
++
++
++// Logarithm with base 2
++#define MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM			(MPI_VALUE_BIT_NUM_MAX / 2 - 2)
++
++
++
++
++
++// MPI access
++void
++MpiSetValue(
++	MPI *pMpiVar,
++	long Value
++	);
++
++void
++MpiGetValue(
++	MPI MpiVar,
++	long *pValue
++	);
++
++void
++MpiSetBit(
++	MPI *pMpiVar,
++	unsigned long BitPosition,
++	unsigned char BitValue
++	);
++
++void
++MpiGetBit(
++	MPI MpiVar,
++	unsigned long BitPosition,
++	unsigned char *pBitValue
++	);
++
++void
++MpiGetSignedBit(
++	MPI MpiVar,
++	unsigned char *pSignedBit
++	);
++
++
++
++// MPI operator
++void
++MpiAssign(
++	MPI *pResult,
++	MPI Operand
++	);
++
++void
++MpiUnaryMinus(
++	MPI *pResult,
++	MPI Operand
++	);
++
++void
++MpiAdd(
++	MPI *pSum,
++	MPI Augend,
++	MPI Addend
++	);
++
++void
++MpiSub(
++	MPI *pDifference,
++	MPI Minuend,
++	MPI Subtrahend
++	);
++
++void
++MpiMul(
++	MPI *pProduct,
++	MPI Multiplicand,
++	MPI Multiplicator
++	);
++
++void
++MpiDiv(
++	MPI *pQuotient,
++	MPI *pRemainder,
++	MPI Dividend,
++	MPI Divisor
++	);
++
++void
++MpiRightShift(
++	MPI *pResult,
++	MPI Operand,
++	unsigned long ShiftBitNum
++	);
++
++void
++MpiLeftShift(
++	MPI *pResult,
++	MPI Operand,
++	unsigned long ShiftBitNum
++	);
++
++int
++MpiEqualTo(
++	MPI MpiLeft,
++	MPI MpiRight
++	);
++
++int
++MpiGreaterThan(
++	MPI MpiLeft,
++	MPI MpiRight
++	);
++
++int
++MpiLessThan(
++	MPI MpiLeft,
++	MPI MpiRight
++	);
++
++void
++MpiMinimizeBitNum(
++	MPI *pMpiVar
++	);
++
++
++
++// MPI special function
++void
++MpiLog2(
++	MPI *pResult,
++	MPI MpiVar,
++	unsigned long ResultFracBitNum
++	);
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++#endif
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,387 @@
++/**
++
++@file
++
++@brief   RTL2832 FC2580 NIM module definition
++
++One can manipulate RTL2832 FC2580 NIM through RTL2832 FC2580 NIM module.
++RTL2832 FC2580 NIM module is derived from DVB-T NIM module.
++
++*/
++
++
++#include "nim_rtl2832_fc2580.h"
++
++
++
++
++
++/**
++
++@brief   RTL2832 FC2580 NIM module builder
++
++Use BuildRtl2832Fc2580Module() to build RTL2832 FC2580 NIM module, set all module function pointers with the
++corresponding functions, and initialize module private variables.
++
++
++@param [in]   ppNim                       Pointer to RTL2832 FC2580 NIM module pointer
++@param [in]   pDvbtNimModuleMemory        Pointer to an allocated DVB-T NIM module memory
++@param [in]   I2cReadingByteNumMax        Maximum I2C reading byte number for basic I2C reading function
++@param [in]   I2cWritingByteNumMax        Maximum I2C writing byte number for basic I2C writing function
++@param [in]   I2cRead                     Basic I2C reading function pointer
++@param [in]   I2cWrite                    Basic I2C writing function pointer
++@param [in]   WaitMs                      Basic waiting function pointer
++@param [in]   pRtl2832ExtraModuleMemory   Pointer to an allocated RTL2832 extra module memory
++@param [in]   DemodDeviceAddr             RTL2832 I2C device address
++@param [in]   DemodCrystalFreqHz          RTL2832 crystal frequency in Hz
++@param [in]   DemodAppMode                RTL2832 application mode for setting
++@param [in]   DemodTsInterfaceMode        RTL2832 TS interface mode for setting
++@param [in]   pFc2580ExtraModuleMemory    Pointer to an allocated FC2580 extra module memory
++@param [in]   TunerDeviceAddr             FC2580 I2C device address
++@param [in]   TunerAgcMode                FC2580 AGC mode
++
++
++@note
++	-# One should call BuildRtl2832Fc2580Module() to build RTL2832 FC2580 NIM module before using it.
++
++*/
++void
++BuildRtl2832Fc2580Module(
++	DVBT_NIM_MODULE **ppNim,								// DVB-T NIM dependence
++	DVBT_NIM_MODULE *pDvbtNimModuleMemory,
++
++	unsigned char I2cReadingByteNumMax,						// Base interface dependence
++	unsigned char I2cWritingByteNumMax,
++	BASE_FP_I2C_READ I2cRead,
++	BASE_FP_I2C_WRITE I2cWrite,
++	BASE_FP_WAIT_MS WaitMs,
++
++	RTL2832_EXTRA_MODULE *pRtl2832ExtraModuleMemory,		// Demod dependence
++	unsigned char DemodDeviceAddr,
++	unsigned long DemodCrystalFreqHz,
++	int DemodAppMode,
++	int DemodTsInterfaceMode,
++	unsigned long DemodUpdateFuncRefPeriodMs,
++	int DemodIsFunc1Enabled,
++
++	FC2580_EXTRA_MODULE *pFc2580ExtraModuleMemory,			// Tuner dependence
++	unsigned char TunerDeviceAddr,
++	unsigned long TunerCrystalFreqHz,
++	int TunerAgcMode
++	)
++{
++	DVBT_NIM_MODULE *pNim;
++
++
++
++	// Set NIM module pointer with NIM module memory.
++	*ppNim = pDvbtNimModuleMemory;
++	
++	// Get NIM module.
++	pNim = *ppNim;
++
++	// Set I2C bridge module pointer with I2C bridge module memory.
++	pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory;
++
++	// Set NIM extra module pointer.
++	pNim->pExtra = INVALID_POINTER_VALUE;
++
++
++	// Set NIM type.
++	pNim->NimType = DVBT_NIM_RTL2832_FC2580;
++
++
++	// Build base interface module.
++	BuildBaseInterface(
++		&pNim->pBaseInterface,
++		&pNim->BaseInterfaceModuleMemory,
++		I2cReadingByteNumMax,
++		I2cWritingByteNumMax,
++		I2cRead,
++		I2cWrite,
++		WaitMs
++		);
++
++	// Build RTL2832 demod module.
++	BuildRtl2832Module(
++		&pNim->pDemod,
++		&pNim->DvbtDemodModuleMemory,
++		pRtl2832ExtraModuleMemory,
++		&pNim->BaseInterfaceModuleMemory,
++		&pNim->I2cBridgeModuleMemory,
++		DemodDeviceAddr,
++		DemodCrystalFreqHz,
++		DemodAppMode,
++		DemodUpdateFuncRefPeriodMs,
++		DemodIsFunc1Enabled
++		);
++
++	// Build FC2580 tuner module.
++	BuildFc2580Module(
++		&pNim->pTuner,
++		&pNim->TunerModuleMemory,
++		pFc2580ExtraModuleMemory,
++		&pNim->BaseInterfaceModuleMemory,
++		&pNim->I2cBridgeModuleMemory,
++		TunerDeviceAddr,
++		TunerCrystalFreqHz,
++		TunerAgcMode
++		);
++
++
++	// Set NIM module variables.
++	pNim->DemodTsInterfaceMode = DemodTsInterfaceMode;
++
++
++	// Set NIM module function pointers with default functions.
++	pNim->GetNimType        = dvbt_nim_default_GetNimType;
++	pNim->GetParameters     = dvbt_nim_default_GetParameters;
++	pNim->IsSignalPresent   = dvbt_nim_default_IsSignalPresent;
++	pNim->IsSignalLocked    = dvbt_nim_default_IsSignalLocked;
++	pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength;
++	pNim->GetSignalQuality  = dvbt_nim_default_GetSignalQuality;
++	pNim->GetBer            = dvbt_nim_default_GetBer;
++	pNim->GetSnrDb          = dvbt_nim_default_GetSnrDb;
++	pNim->GetTrOffsetPpm    = dvbt_nim_default_GetTrOffsetPpm;
++	pNim->GetCrOffsetHz     = dvbt_nim_default_GetCrOffsetHz;
++	pNim->GetTpsInfo        = dvbt_nim_default_GetTpsInfo;
++	pNim->UpdateFunction    = dvbt_nim_default_UpdateFunction;
++
++	// Set NIM module function pointers with particular functions.
++	pNim->Initialize     = rtl2832_fc2580_Initialize;
++	pNim->SetParameters  = rtl2832_fc2580_SetParameters;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_INITIALIZE
++
++*/
++int
++rtl2832_fc2580_Initialize(
++	DVBT_NIM_MODULE *pNim
++	)
++{
++	typedef struct
++	{
++		int RegBitName;
++		unsigned long Value;
++	}
++	REG_VALUE_ENTRY;
++
++
++	static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN] =
++	{
++		// RegBitName,				Value
++		{DVBT_DAGC_TRG_VAL,			0x39	},
++		{DVBT_AGC_TARG_VAL_0,		0x0		},
++		{DVBT_AGC_TARG_VAL_8_1,		0x5a	},
++		{DVBT_AAGC_LOOP_GAIN,		0x16    },
++		{DVBT_LOOP_GAIN2_3_0,		0x6		},
++		{DVBT_LOOP_GAIN2_4,			0x1		},
++		{DVBT_LOOP_GAIN3,			0x16	},
++		{DVBT_VTOP1,				0x35	},
++		{DVBT_VTOP2,				0x21	},
++		{DVBT_VTOP3,				0x21	},
++		{DVBT_KRF1,					0x0		},
++		{DVBT_KRF2,					0x40	},
++		{DVBT_KRF3,					0x10	},
++		{DVBT_KRF4,					0x10	},
++		{DVBT_IF_AGC_MIN,			0x80	},
++		{DVBT_IF_AGC_MAX,			0x7f	},
++		{DVBT_RF_AGC_MIN,			0x9c	},
++		{DVBT_RF_AGC_MAX,			0x7f	},
++		{DVBT_POLAR_RF_AGC,			0x0		},
++		{DVBT_POLAR_IF_AGC,			0x0		},
++		{DVBT_AD7_SETTING,			0xe9f4	},
++	};
++
++
++	TUNER_MODULE *pTuner;
++	DVBT_DEMOD_MODULE *pDemod;
++
++	int i;
++
++	int RegBitName;
++	unsigned long Value;
++
++
++
++	// Get tuner module and demod module.
++	pTuner = pNim->pTuner;
++	pDemod = pNim->pDemod;
++
++
++	// Enable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	// Initialize tuner.
++	if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Disable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Initialize demod.
++	if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Set demod IF frequency with 0 Hz.
++	if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Set demod spectrum mode with SPECTRUM_NORMAL.
++	if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	// Set demod registers.
++	for(i = 0; i < RTL2832_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN; i++)
++	{
++		// Get register bit name and its value.
++		RegBitName = AdditionalInitRegValueTable[i].RegBitName;
++		Value      = AdditionalInitRegValueTable[i].Value;
++
++		// Set demod registers
++		if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS)
++			goto error_status_set_registers;
++	}
++
++
++	// Set TS interface according to TS interface mode.
++	switch(pNim->DemodTsInterfaceMode)
++	{
++		case TS_INTERFACE_PARALLEL:
++
++			// Set demod TS interface with parallel mode.
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SERIAL,   0) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH0, 9) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH1, 9) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			break;
++
++
++		default:
++		case TS_INTERFACE_SERIAL:
++
++			// Set demod TS interface with serial mode.
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SERIAL,   1) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH0, 2) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH1, 2) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_SET_PARAMETERS
++
++*/
++int
++rtl2832_fc2580_SetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long RfFreqHz,
++	int BandwidthMode
++	)
++{
++	TUNER_MODULE *pTuner;
++	DVBT_DEMOD_MODULE *pDemod;
++
++	FC2580_EXTRA_MODULE *pTunerExtra;
++	int TunerBandwidthMode;
++
++
++
++	// Get tuner module and demod module.
++	pTuner = pNim->pTuner;
++	pDemod = pNim->pDemod;
++
++	// Get tuner extra module.
++	pTunerExtra = (FC2580_EXTRA_MODULE *)pTuner->pExtra;
++
++
++	// Enable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	// Set tuner RF frequency in Hz.
++	if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Determine TunerBandwidthMode according to bandwidth mode.
++	switch(BandwidthMode)
++	{
++		default:
++		case DVBT_BANDWIDTH_6MHZ:		TunerBandwidthMode = FC2580_BANDWIDTH_6000000HZ;		break;
++		case DVBT_BANDWIDTH_7MHZ:		TunerBandwidthMode = FC2580_BANDWIDTH_7000000HZ;		break;
++		case DVBT_BANDWIDTH_8MHZ:		TunerBandwidthMode = FC2580_BANDWIDTH_8000000HZ;		break;
++	}
++
++	// Set tuner bandwidth mode with TunerBandwidthMode.
++	if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Disable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Set demod bandwidth mode.
++	if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Reset demod particular registers.
++	if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	// Reset demod by software reset.
++	if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,146 @@
++#ifndef __NIM_RTL2832_FC2580
++#define __NIM_RTL2832_FC2580
++
++/**
++
++@file
++
++@brief   RTL2832 FC2580 NIM module declaration
++
++One can manipulate RTL2832 FC2580 NIM through RTL2832 FC2580 NIM module.
++RTL2832 FC2580 NIM module is derived from DVB-T NIM module.
++
++
++
++@par Example:
++@code
++
++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines.
++
++
++
++#include "nim_rtl2832_fc2580.h"
++
++
++...
++
++
++
++int main(void)
++{
++	DVBT_NIM_MODULE *pNim;
++	DVBT_NIM_MODULE DvbtNimModuleMemory;
++	RTL2832_EXTRA_MODULE Rtl2832ExtraModuleMemory;
++	FC2580_EXTRA_MODULE Fc2580ExtraModuleMemory;
++
++	...
++
++
++
++	// Build RTL2832 FC2580 NIM module.
++	BuildRtl2832Fc2580Module(
++		&pNim,
++		&DvbtNimModuleMemory,
++
++		9,								// Maximum I2C reading byte number is 9.
++		8,								// Maximum I2C writing byte number is 8.
++		CustomI2cRead,					// Employ CustomI2cRead() as basic I2C reading function.
++		CustomI2cWrite,					// Employ CustomI2cWrite() as basic I2C writing function.
++		CustomWaitMs,					// Employ CustomWaitMs() as basic waiting function.
++
++		&Rtl2832ExtraModuleMemory,		// Employ RTL2832 extra module for RTL2832 module.
++		0x20,							// The RTL2832 I2C device address is 0x20 in 8-bit format.
++		CRYSTAL_FREQ_28800000HZ,		// The RTL2832 crystal frequency is 28.8 MHz.
++		RTL2832_APPLICATION_STB,		// The RTL2832 application mode is STB mode.
++		50,								// The RTL2832 update function reference period is 50 millisecond
++		ON,								// The RTL2832 Function 1 enabling status is on.
++
++		&Fc2580ExtraModuleMemory,		// Employ FC2580 extra module for FC2580 module.
++		0xac,							// The FC2580 I2C device address is 0xac in 8-bit format.
++		CRYSTAL_FREQ_16384000HZ,		// The FC2580 crystal frequency is 16.384 MHz.
++		FC2580_AGC_EXTERNAL				// The FC2580 AGC mode is external AGC mode.
++		);
++
++
++
++	// See the example for other NIM functions in dvbt_nim_base.h
++
++	...
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++#include "demod_rtl2832.h"
++#include "tuner_fc2580.h"
++#include "dvbt_nim_base.h"
++
++
++
++
++
++// Definitions
++#define RTL2832_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN		21
++
++
++
++
++
++// Builder
++void
++BuildRtl2832Fc2580Module(
++	DVBT_NIM_MODULE **ppNim,								// DVB-T NIM dependence
++	DVBT_NIM_MODULE *pDvbtNimModuleMemory,
++
++	unsigned char I2cReadingByteNumMax,						// Base interface dependence
++	unsigned char I2cWritingByteNumMax,
++	BASE_FP_I2C_READ I2cRead,
++	BASE_FP_I2C_WRITE I2cWrite,
++	BASE_FP_WAIT_MS WaitMs,
++
++	RTL2832_EXTRA_MODULE *pRtl2832ExtraModuleMemory,		// Demod dependence
++	unsigned char DemodDeviceAddr,
++	unsigned long DemodCrystalFreqHz,
++	int DemodAppMode,
++	int DemodTsInterfaceMode,
++	unsigned long DemodUpdateFuncRefPeriodMs,
++	int DemodIsFunc1Enabled,
++
++	FC2580_EXTRA_MODULE *pFc2580ExtraModuleMemory,			// Tuner dependence
++	unsigned char TunerDeviceAddr,
++	unsigned long TunerCrystalFreqHz,
++	int TunerAgcMode
++	);
++
++
++
++
++
++// RTL2832 FC2580 NIM manipulaing functions
++int
++rtl2832_fc2580_Initialize(
++	DVBT_NIM_MODULE *pNim
++	);
++
++int
++rtl2832_fc2580_SetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long RfFreqHz,
++	int BandwidthMode
++	);
++
++
++
++
++
++
++
++#endif
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,1108 @@
++/**
++
++@file
++
++@brief   RTL2832 MT2266 NIM module definition
++
++One can manipulate RTL2832 MT2266 NIM through RTL2832 MT2266 NIM module.
++RTL2832 MT2266 NIM module is derived from DVB-T NIM module.
++
++*/
++
++
++#include "nim_rtl2832_mt2266.h"
++
++
++
++
++
++/**
++
++@brief   RTL2832 MT2266 NIM module builder
++
++Use BuildRtl2832Mt2266Module() to build RTL2832 MT2266 NIM module, set all module function pointers with the
++corresponding functions, and initialize module private variables.
++
++
++@param [in]   ppNim                       Pointer to RTL2832 MT2266 NIM module pointer
++@param [in]   pDvbtNimModuleMemory        Pointer to an allocated DVB-T NIM module memory
++@param [in]   I2cReadingByteNumMax        Maximum I2C reading byte number for basic I2C reading function
++@param [in]   I2cWritingByteNumMax        Maximum I2C writing byte number for basic I2C writing function
++@param [in]   I2cRead                     Basic I2C reading function pointer
++@param [in]   I2cWrite                    Basic I2C writing function pointer
++@param [in]   WaitMs                      Basic waiting function pointer
++@param [in]   pRtl2832ExtraModuleMemory   Pointer to an allocated RTL2832 extra module memory
++@param [in]   DemodDeviceAddr             RTL2832 I2C device address
++@param [in]   DemodCrystalFreqHz          RTL2832 crystal frequency in Hz
++@param [in]   DemodAppMode                RTL2832 application mode for setting
++@param [in]   DemodTsInterfaceMode        RTL2832 TS interface mode for setting
++@param [in]   pMt2266ExtraModuleMemory    Pointer to an allocated MT2266 extra module memory
++@param [in]   TunerDeviceAddr             MT2266 I2C device address
++
++
++@note
++	-# One should call BuildRtl2832Mt2266Module() to build RTL2832 MT2266 NIM module before using it.
++
++*/
++void
++BuildRtl2832Mt2266Module(
++	DVBT_NIM_MODULE **ppNim,								// DVB-T NIM dependence
++	DVBT_NIM_MODULE *pDvbtNimModuleMemory,
++	RTL2832_MT2266_EXTRA_MODULE *pRtl2832Mt2266ExtraModuleMemory,
++
++	unsigned char I2cReadingByteNumMax,						// Base interface dependence
++	unsigned char I2cWritingByteNumMax,
++	BASE_FP_I2C_READ I2cRead,
++	BASE_FP_I2C_WRITE I2cWrite,
++	BASE_FP_WAIT_MS WaitMs,
++
++	RTL2832_EXTRA_MODULE *pRtl2832ExtraModuleMemory,		// Demod dependence
++	unsigned char DemodDeviceAddr,
++	unsigned long DemodCrystalFreqHz,
++	int DemodAppMode,
++	int DemodTsInterfaceMode,
++	unsigned long DemodUpdateFuncRefPeriodMs,
++	int DemodIsFunc1Enabled,
++
++	MT2266_EXTRA_MODULE *pMt2266ExtraModuleMemory,			// Tuner dependence
++	unsigned char TunerDeviceAddr
++	)
++{
++	DVBT_NIM_MODULE *pNim;
++	RTL2832_MT2266_EXTRA_MODULE *pExtra;
++
++
++
++	// Set NIM module pointer with NIM module memory.
++	*ppNim = pDvbtNimModuleMemory;
++	
++	// Get NIM module.
++	pNim = *ppNim;
++
++	// Set I2C bridge module pointer with I2C bridge module memory.
++	pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory;
++
++	// Set NIM extra module pointer.
++	pNim->pExtra = pRtl2832Mt2266ExtraModuleMemory;
++
++	// Get NIM extra module.
++	pExtra = (RTL2832_MT2266_EXTRA_MODULE *)pNim->pExtra;
++
++
++	// Set NIM type.
++	pNim->NimType = DVBT_NIM_RTL2832_MT2266;
++
++
++	// Build base interface module.
++	BuildBaseInterface(
++		&pNim->pBaseInterface,
++		&pNim->BaseInterfaceModuleMemory,
++		I2cReadingByteNumMax,
++		I2cWritingByteNumMax,
++		I2cRead,
++		I2cWrite,
++		WaitMs
++		);
++
++	// Build RTL2832 demod module.
++	BuildRtl2832Module(
++		&pNim->pDemod,
++		&pNim->DvbtDemodModuleMemory,
++		pRtl2832ExtraModuleMemory,
++		&pNim->BaseInterfaceModuleMemory,
++		&pNim->I2cBridgeModuleMemory,
++		DemodDeviceAddr,
++		DemodCrystalFreqHz,
++		DemodAppMode,
++		DemodUpdateFuncRefPeriodMs,
++		DemodIsFunc1Enabled
++		);
++
++	// Build MT2266 tuner module.
++	BuildMt2266Module(
++		&pNim->pTuner,
++		&pNim->TunerModuleMemory,
++		pMt2266ExtraModuleMemory,
++		&pNim->BaseInterfaceModuleMemory,
++		&pNim->I2cBridgeModuleMemory,
++		TunerDeviceAddr
++		);
++
++
++	// Set NIM module variables.
++	pNim->DemodTsInterfaceMode = DemodTsInterfaceMode;
++
++
++	// Set NIM module function pointers with default functions.
++	pNim->GetNimType        = dvbt_nim_default_GetNimType;
++	pNim->GetParameters     = dvbt_nim_default_GetParameters;
++	pNim->IsSignalPresent   = dvbt_nim_default_IsSignalPresent;
++	pNim->IsSignalLocked    = dvbt_nim_default_IsSignalLocked;
++	pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength;
++	pNim->GetSignalQuality  = dvbt_nim_default_GetSignalQuality;
++	pNim->GetBer            = dvbt_nim_default_GetBer;
++	pNim->GetSnrDb          = dvbt_nim_default_GetSnrDb;
++	pNim->GetTrOffsetPpm    = dvbt_nim_default_GetTrOffsetPpm;
++	pNim->GetCrOffsetHz     = dvbt_nim_default_GetCrOffsetHz;
++	pNim->GetTpsInfo        = dvbt_nim_default_GetTpsInfo;
++
++	// Set NIM module function pointers with particular functions.
++	pNim->Initialize     = rtl2832_mt2266_Initialize;
++	pNim->SetParameters  = rtl2832_mt2266_SetParameters;
++	pNim->UpdateFunction = rtl2832_mt2266_UpdateFunction;
++
++
++	// Initialize NIM extra module variables.
++	pExtra->LnaConfig       = 0xff;
++	pExtra->UhfSens         = 0xff;
++	pExtra->AgcCurrentState = 0xff;
++	pExtra->LnaGainOld      = 0xffffffff;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_INITIALIZE
++
++*/
++int
++rtl2832_mt2266_Initialize(
++	DVBT_NIM_MODULE *pNim
++	)
++{
++	typedef struct
++	{
++		int RegBitName;
++		unsigned long Value;
++	}
++	REG_VALUE_ENTRY;
++
++
++	static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_MT2266_ADDITIONAL_INIT_REG_TABLE_LEN] =
++	{
++		// RegBitName,				Value
++		{DVBT_DAGC_TRG_VAL,			0x39	},
++		{DVBT_AGC_TARG_VAL_0,		0x0		},
++		{DVBT_AGC_TARG_VAL_8_1,		0x5a	},
++		{DVBT_AAGC_LOOP_GAIN,		0x16    },
++		{DVBT_LOOP_GAIN2_3_0,		0x6		},
++		{DVBT_LOOP_GAIN2_4,			0x1		},
++		{DVBT_LOOP_GAIN3,			0x16	},
++		{DVBT_VTOP1,				0x35	},
++		{DVBT_VTOP2,				0x21	},
++		{DVBT_VTOP3,				0x21	},
++		{DVBT_KRF1,					0x0		},
++		{DVBT_KRF2,					0x40	},
++		{DVBT_KRF3,					0x10	},
++		{DVBT_KRF4,					0x10	},
++		{DVBT_IF_AGC_MIN,			0xc0	},	// Note: The IF_AGC_MIN value will be set again by demod_pdcontrol_reset().
++		{DVBT_IF_AGC_MAX,			0x7f	},
++		{DVBT_RF_AGC_MIN,			0x9c	},
++		{DVBT_RF_AGC_MAX,			0x7f	},
++		{DVBT_POLAR_RF_AGC,			0x1		},
++		{DVBT_POLAR_IF_AGC,			0x1		},
++		{DVBT_AD7_SETTING,			0xe9f4	},
++	};
++
++
++	TUNER_MODULE *pTuner;
++	DVBT_DEMOD_MODULE *pDemod;
++
++	int i;
++
++	int RegBitName;
++	unsigned long Value;
++
++
++
++	// Get tuner module and demod module.
++	pTuner = pNim->pTuner;
++	pDemod = pNim->pDemod;
++
++
++	// Enable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	// Initialize tuner.
++	if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Disable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Initialize demod.
++	if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Set demod IF frequency with 0 Hz.
++	if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Set demod spectrum mode with SPECTRUM_NORMAL.
++	if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	// Set demod registers.
++	for(i = 0; i < RTL2832_MT2266_ADDITIONAL_INIT_REG_TABLE_LEN; i++)
++	{
++		// Get register bit name and its value.
++		RegBitName = AdditionalInitRegValueTable[i].RegBitName;
++		Value      = AdditionalInitRegValueTable[i].Value;
++
++		// Set demod registers
++		if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS)
++			goto error_status_set_registers;
++	}
++
++
++	// Set TS interface according to TS interface mode.
++	switch(pNim->DemodTsInterfaceMode)
++	{
++		case TS_INTERFACE_PARALLEL:
++
++			// Set demod TS interface with parallel mode.
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SERIAL,   0) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH0, 9) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH1, 9) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			break;
++
++
++		default:
++		case TS_INTERFACE_SERIAL:
++
++			// Set demod TS interface with serial mode.
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SERIAL,   1) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH0, 2) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH1, 2) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_SET_PARAMETERS
++
++*/
++int
++rtl2832_mt2266_SetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long RfFreqHz,
++	int BandwidthMode
++	)
++{
++	TUNER_MODULE *pTuner;
++	DVBT_DEMOD_MODULE *pDemod;
++
++	MT2266_EXTRA_MODULE *pMt2266Extra;
++	Handle_t Mt2266Handle;
++	unsigned long BandwidthHz;
++
++	RTL2832_MT2266_EXTRA_MODULE *pRtl2832Mt2266Extra;
++
++	UData_t Status;
++
++
++
++	// Get tuner module and demod module.
++	pTuner = pNim->pTuner;
++	pDemod = pNim->pDemod;
++
++	// Get tuner extra module.
++	pMt2266Extra = (MT2266_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get tuner handle.
++	Mt2266Handle = pMt2266Extra->DeviceHandle;
++
++	// Get NIM extra module.
++	pRtl2832Mt2266Extra = (RTL2832_MT2266_EXTRA_MODULE *)pNim->pExtra;
++
++
++	// Enable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	// Set tuner RF frequency in Hz.
++	if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Determine BandwidthHz according to bandwidth mode.
++	switch(BandwidthMode)
++	{
++		default:
++		case DVBT_BANDWIDTH_6MHZ:		BandwidthHz = MT2266_BANDWIDTH_6MHZ;		break;
++		case DVBT_BANDWIDTH_7MHZ:		BandwidthHz = MT2266_BANDWIDTH_7MHZ;		break;
++		case DVBT_BANDWIDTH_8MHZ:		BandwidthHz = MT2266_BANDWIDTH_8MHZ;		break;
++	}
++
++	// Set tuner bandwidth in Hz with BandwidthHz.
++	if(pMt2266Extra->SetBandwidthHz(pTuner, BandwidthHz) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Disable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Set demod bandwidth mode.
++	if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Reset demod particular registers.
++	if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	// Reset demod by software reset.
++	if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Enable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	// Reset MT2266 update procedure.
++	Status = demod_pdcontrol_reset(pDemod, Mt2266Handle, &pRtl2832Mt2266Extra->AgcCurrentState);
++
++	if(MT_IS_ERROR(Status))
++		goto error_status_execute_function;
++
++	// Disable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_UPDATE_FUNCTION
++
++*/
++int
++rtl2832_mt2266_UpdateFunction(
++	DVBT_NIM_MODULE *pNim
++	)
++{
++	TUNER_MODULE *pTuner;
++	DVBT_DEMOD_MODULE *pDemod;
++	MT2266_EXTRA_MODULE *pMt2266Extra;
++	RTL2832_MT2266_EXTRA_MODULE *pRtl2832Mt2266Extra;
++
++	Handle_t Mt2266Handle;
++	UData_t Status;
++
++
++
++	// Get tuner module and demod module.
++	pTuner = pNim->pTuner;
++	pDemod = pNim->pDemod;
++
++	// Get tuner extra module and tuner handle.
++	pMt2266Extra = (MT2266_EXTRA_MODULE *)pTuner->pExtra;
++	pMt2266Extra->GetHandle(pTuner, &Mt2266Handle);
++
++	// Get NIM extra module.
++	pRtl2832Mt2266Extra = (RTL2832_MT2266_EXTRA_MODULE *)pNim->pExtra;
++
++
++	// Update demod particular registers.
++	if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	// Enable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	// Update demod and tuner register setting.
++	Status = demod_pdcontrol(
++		pDemod,
++		Mt2266Handle,
++		&pRtl2832Mt2266Extra->LnaConfig,
++		&pRtl2832Mt2266Extra->UhfSens,
++		&pRtl2832Mt2266Extra->AgcCurrentState,
++		(u32t *)&pRtl2832Mt2266Extra->LnaGainOld
++		);
++
++	if(MT_IS_ERROR(Status))
++		goto error_status_execute_function;
++
++	// Disable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++// The following context is source code provided by Microtune.
++
++
++
++
++
++// Additional definition for mt_control.c
++UData_t
++demod_get_pd(
++	handle_t demod_handle,
++	u16t *pd_value
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	unsigned long RssiR;
++
++
++	// Get demod module.
++	pDemod = (DVBT_DEMOD_MODULE *)demod_handle;
++
++	// Get RSSI_R value.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSSI_R, &RssiR) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	// Set pd_value according to RSSI_R.
++	*pd_value = (u16t)RssiR;
++
++
++	return MT_OK;
++
++
++error_status_get_registers:
++	return MT_COMM_ERR;
++}
++
++
++
++UData_t
++demod_get_agc(
++	handle_t demod_handle,
++	u16t *rf_level,
++	u16t *bb_level
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	int RfAgc;
++	int IfAgc;
++
++
++	// Get demod module.
++	pDemod = (DVBT_DEMOD_MODULE *)demod_handle;
++
++	// Get RF and IF AGC value.
++	if(pDemod->GetRfAgc(pDemod, &RfAgc) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	if(pDemod->GetIfAgc(pDemod, &IfAgc) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	// Convert RF and IF AGC value to proper format.
++	*rf_level = (u16t)((RfAgc + (1 << (RTL2832_RF_AGC_REG_BIT_NUM - 1))) *
++		(1 << (MT2266_DEMOD_ASSUMED_AGC_REG_BIT_NUM - RTL2832_RF_AGC_REG_BIT_NUM)));
++
++	*bb_level = (u16t)((IfAgc + (1 << (RTL2832_IF_AGC_REG_BIT_NUM - 1))) *
++		(1 << (MT2266_DEMOD_ASSUMED_AGC_REG_BIT_NUM - RTL2832_IF_AGC_REG_BIT_NUM)));
++
++
++	return MT_OK;
++
++
++error_status_get_registers:
++	return MT_COMM_ERR;
++}
++
++
++
++UData_t
++demod_set_bbagclim(
++	handle_t demod_handle,
++	int on_off_status
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++	unsigned long IfAgcMinBinary;
++	long IfAgcMinInt;
++
++
++	// Get demod module.
++	pDemod = (DVBT_DEMOD_MODULE *)demod_handle;
++
++	// Get IF_AGC_MIN binary value.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_IF_AGC_MIN, &IfAgcMinBinary) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	// Convert IF_AGC_MIN binary value to integer.
++	IfAgcMinInt = BinToSignedInt(IfAgcMinBinary, RTL2832_MT2266_IF_AGC_MIN_BIT_NUM);
++
++	// Modify IF_AGC_MIN integer according to on_off_status.
++	switch(on_off_status)
++	{
++		case 1:
++
++			IfAgcMinInt += RTL2832_MT2266_IF_AGC_MIN_INT_STEP;
++
++			if(IfAgcMinInt > RTL2832_MT2266_IF_AGC_MIN_INT_MAX)
++				IfAgcMinInt = RTL2832_MT2266_IF_AGC_MIN_INT_MAX;
++
++			break;
++
++		default:
++		case 0:
++
++			IfAgcMinInt -= RTL2832_MT2266_IF_AGC_MIN_INT_STEP;
++
++			if(IfAgcMinInt < RTL2832_MT2266_IF_AGC_MIN_INT_MIN)
++				IfAgcMinInt = RTL2832_MT2266_IF_AGC_MIN_INT_MIN;
++
++			break;
++	}
++
++	// Convert modified IF_AGC_MIN integer to binary value.
++	IfAgcMinBinary = SignedIntToBin(IfAgcMinInt, RTL2832_MT2266_IF_AGC_MIN_BIT_NUM);
++
++	// Set IF_AGC_MIN with modified binary value.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IF_AGC_MIN, IfAgcMinBinary) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	return MT_OK;
++
++
++error_status_set_registers:
++error_status_get_registers:
++	return MT_COMM_ERR;
++}
++
++
++
++
++
++UData_t
++tuner_set_bw_normal(
++	handle_t tuner_handle,
++	handle_t demod_handle
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++
++	int DemodBandwidthMode;
++	unsigned int TunerBandwidthHz;
++	unsigned int TargetTunerBandwidthHz;
++
++
++	// Get demod module.
++	pDemod = (DVBT_DEMOD_MODULE *)demod_handle;
++
++	// Get demod bandwidth mode.
++	if(pDemod->GetBandwidthMode(pDemod, &DemodBandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Determine tuner target bandwidth.
++	switch(DemodBandwidthMode)
++	{
++		case DVBT_BANDWIDTH_6MHZ:	TargetTunerBandwidthHz = MT2266_BANDWIDTH_6MHZ;		break;
++		case DVBT_BANDWIDTH_7MHZ:	TargetTunerBandwidthHz = MT2266_BANDWIDTH_7MHZ;		break;
++		default:
++		case DVBT_BANDWIDTH_8MHZ:	TargetTunerBandwidthHz = MT2266_BANDWIDTH_8MHZ;		break;
++	}
++
++	// Get tuner bandwidth.
++	if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_OUTPUT_BW, &TunerBandwidthHz)))
++		goto error_status_get_tuner_bandwidth;
++
++	// Set tuner bandwidth with normal setting according to demod bandwidth mode.
++	if(TunerBandwidthHz != TargetTunerBandwidthHz)
++	{
++		if(MT_IS_ERROR(MT2266_SetParam(tuner_handle, MT2266_OUTPUT_BW, TargetTunerBandwidthHz)))
++			goto error_status_set_tuner_bandwidth;
++	}
++
++
++	return MT_OK;
++
++
++error_status_set_tuner_bandwidth:
++error_status_get_tuner_bandwidth:
++error_status_execute_function:
++	return MT_COMM_ERR;
++}
++
++
++
++
++
++UData_t
++tuner_set_bw_narrow(
++	handle_t tuner_handle,
++	handle_t demod_handle
++	)
++{
++	DVBT_DEMOD_MODULE *pDemod;
++
++	int DemodBandwidthMode;
++	unsigned long AciDetInd;
++	unsigned int TunerBandwidthHz;
++	unsigned int TargetTunerBandwidthHz;
++
++
++	// Get demod module.
++	pDemod = (DVBT_DEMOD_MODULE *)demod_handle;
++
++	// Get demod bandwidth mode.
++	if(pDemod->GetBandwidthMode(pDemod, &DemodBandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Get demod ACI_DET_IND.
++	if(pDemod->GetRegBitsWithPage(pDemod, DVBT_ACI_DET_IND, &AciDetInd) != FUNCTION_SUCCESS)
++		goto error_status_get_registers;
++
++	// Determine tuner target bandwidth according to ACI_DET_IND.
++	if(AciDetInd == 0x1)
++	{
++		// Choose narrow target bandwidth.
++		switch(DemodBandwidthMode)
++		{
++			case DVBT_BANDWIDTH_6MHZ:	TargetTunerBandwidthHz = MT2266_BANDWIDTH_5MHZ;		break;
++			case DVBT_BANDWIDTH_7MHZ:	TargetTunerBandwidthHz = MT2266_BANDWIDTH_6MHZ;		break;
++			default:
++			case DVBT_BANDWIDTH_8MHZ:	TargetTunerBandwidthHz = MT2266_BANDWIDTH_7MHZ;		break;
++		}
++	}
++	else
++	{
++		// Choose normal target bandwidth.
++		switch(DemodBandwidthMode)
++		{
++			case DVBT_BANDWIDTH_6MHZ:	TargetTunerBandwidthHz = MT2266_BANDWIDTH_6MHZ;		break;
++			case DVBT_BANDWIDTH_7MHZ:	TargetTunerBandwidthHz = MT2266_BANDWIDTH_7MHZ;		break;
++			default:
++			case DVBT_BANDWIDTH_8MHZ:	TargetTunerBandwidthHz = MT2266_BANDWIDTH_8MHZ;		break;
++		}
++	}
++
++	// Get tuner bandwidth.
++	if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_OUTPUT_BW, &TunerBandwidthHz)))
++		goto error_status_get_tuner_bandwidth;
++
++	// Set tuner bandwidth with normal setting according to demod bandwidth mode.
++	if(TunerBandwidthHz != TargetTunerBandwidthHz)
++	{
++		if(MT_IS_ERROR(MT2266_SetParam(tuner_handle, MT2266_OUTPUT_BW, TargetTunerBandwidthHz)))
++			goto error_status_set_tuner_bandwidth;
++	}
++
++
++	return MT_OK;
++
++
++error_status_set_tuner_bandwidth:
++error_status_get_tuner_bandwidth:
++error_status_get_registers:
++error_status_execute_function:
++	return MT_COMM_ERR;
++}
++
++
++
++
++
++// Microtune source code - mt_control.c
++
++
++
++UData_t demod_pdcontrol_reset(handle_t demod_handle, handle_t tuner_handle, u8t *agc_current_state) {
++
++	DVBT_DEMOD_MODULE *pDemod;
++	unsigned long BinaryValue;
++
++
++	// Get demod module.
++	pDemod = (DVBT_DEMOD_MODULE *)demod_handle;
++
++	// Reset AGC current state.
++	*agc_current_state = AGC_STATE_START;
++
++	// Calculate RTL2832_MT2266_IF_AGC_MIN_INT_MIN binary value.
++	BinaryValue = SignedIntToBin(RTL2832_MT2266_IF_AGC_MIN_INT_MIN, RTL2832_MT2266_IF_AGC_MIN_BIT_NUM);
++
++	// Set IF_AGC_MIN with binary value.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IF_AGC_MIN, BinaryValue) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	// Set tuner bandwidth with normal setting.
++	if(MT_IS_ERROR(tuner_set_bw_normal(tuner_handle, demod_handle)))
++		goto error_status_set_tuner_bandwidth;
++
++
++	return MT_OK;
++
++
++error_status_set_tuner_bandwidth:
++error_status_set_registers:
++	return MT_COMM_ERR;
++}
++
++
++
++UData_t demod_pdcontrol(handle_t demod_handle, handle_t tuner_handle, u8t* lna_config, u8t* uhf_sens,
++					 u8t *agc_current_state, u32t *lna_gain_old) {
++
++	u16t pd_value;
++	u16t rf_level, bb_level;
++	u32t lna_gain;
++	u8t zin=0;
++	
++//	u8t temp[2];
++//	u8t agc_bb_min;
++//	demod_data_t* local_data;
++
++	
++	u8t band=1;  /* band=0: vhf, band=1: uhf low, band=2: uhf high */
++	u32t freq;
++
++	// AGC threshold values
++	u16t sens_on[]  = {11479, 11479, 32763};
++	u16t sens_off[] = {36867, 36867, 44767};
++	u16t lin_off[]  = {23619, 23619, 23619};
++	u16t lin_on[]   = {38355, 38355, 38355};
++	u16t pd_upper[] = {85,    85,    85};
++	u16t pd_lower[] = {74,    74,    74};
++	u8t next_state;
++
++	// demod_data_t* local_data = (demod_data_t*)demod_handle;	
++
++	if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_INPUT_FREQ, &freq))) goto error_status;
++	if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_LNA_GAIN, &lna_gain))) goto error_status;
++	if(MT_IS_ERROR(MT2266_GetReg(tuner_handle,0x1e,&zin))) goto error_status;
++
++	if (freq <= 250000000) band=0;
++	else if (freq < 660000000) band=1;
++	else band=2;
++	
++	if(MT_IS_ERROR(demod_get_pd(demod_handle, &pd_value))) goto error_status;
++	if(MT_IS_ERROR(demod_get_agc(demod_handle, &rf_level, &bb_level))) goto error_status;
++
++	rf_level=0xffff-rf_level;
++	bb_level=0xffff-bb_level;
++
++/*
++#ifndef _HOST_DLL
++	uart_write_nr("St:");
++	uart_writedez(agc_current_state[num]);
++
++	uart_write_nr(" PD: ");
++	uart_writehex16(pd_value);
++
++	uart_write_nr(" AGC: ");
++	uart_writehex16(rf_level);
++	uart_writehex16(bb_level);	
++#endif
++*/
++
++	next_state = *agc_current_state;
++	
++	switch (*agc_current_state) {
++	
++	case AGC_STATE_START : {
++		if ((int)lna_gain < LNAGAIN_MIN)  
++			next_state=AGC_STATE_LNAGAIN_BELOW_MIN;
++		else if (lna_gain > LNAGAIN_MAX)  
++			next_state=AGC_STATE_LNAGAIN_ABOVE_MAX;
++		else 
++			next_state=AGC_STATE_NORMAL;
++		break;
++		}
++	
++	case AGC_STATE_LNAGAIN_BELOW_MIN : {
++		if ((int)lna_gain < LNAGAIN_MIN ) 
++			next_state=AGC_STATE_LNAGAIN_BELOW_MIN;
++		else next_state=AGC_STATE_NORMAL;
++		
++		break;
++		}
++	
++	case AGC_STATE_LNAGAIN_ABOVE_MAX : {
++		if (lna_gain > LNAGAIN_MAX ) 
++			next_state=AGC_STATE_LNAGAIN_ABOVE_MAX;
++		else next_state=AGC_STATE_NORMAL;
++		break;
++		}
++	
++	case AGC_STATE_NORMAL : {
++		if (rf_level > lin_on[band] ) {
++			*lna_gain_old = lna_gain;
++			next_state = AGC_STATE_MAS_GRANDE_SIGNAL;
++			}
++		else if (pd_value > pd_upper[band]) {
++			next_state = AGC_STATE_GRANDE_INTERFERER;
++			}
++		else if ( (pd_value < pd_lower[band]) && (lna_gain < LNAGAIN_MAX) ) {
++			next_state = AGC_STATE_NO_INTERFERER;
++			}
++		else if ( bb_level < sens_on[band]) {
++			next_state = AGC_STATE_SMALL_SIGNAL;
++			}
++		break;
++		}
++	
++	case AGC_STATE_NO_INTERFERER : {
++		if (pd_value > pd_lower[band] ) 
++			next_state = AGC_STATE_MEDIUM_INTERFERER;
++		else if (pd_value < pd_lower[band] )
++			next_state = AGC_STATE_NORMAL;
++		else if ( lna_gain == LNAGAIN_MAX )
++			next_state = AGC_STATE_NORMAL;
++		break;
++		}
++
++	case AGC_STATE_MEDIUM_INTERFERER : {
++		if (pd_value > pd_upper[band] ) 
++			next_state = AGC_STATE_GRANDE_INTERFERER;
++		else if (pd_value < pd_lower[band] )
++			next_state = AGC_STATE_NO_INTERFERER;
++		break;
++		}
++
++	
++	case AGC_STATE_GRANDE_INTERFERER : {
++		if (pd_value < pd_upper[band] )
++			next_state = AGC_STATE_MEDIUM_INTERFERER;
++		break;
++		}
++	
++	case AGC_STATE_MAS_GRANDE_SIGNAL : {
++		if (rf_level < lin_on[band])
++			next_state = AGC_STATE_GRANDE_SIGNAL;
++		else if (pd_value > pd_upper[band]) {
++			next_state = AGC_STATE_GRANDE_INTERFERER;
++			}
++		break;
++		}
++		
++	case AGC_STATE_MEDIUM_SIGNAL : {
++		if (rf_level > lin_off[band])
++			next_state = AGC_STATE_GRANDE_SIGNAL;
++		else if (lna_gain >= *lna_gain_old) 
++			next_state = AGC_STATE_NORMAL;
++		else if (pd_value > pd_upper[band])
++			next_state = AGC_STATE_GRANDE_INTERFERER;
++		break;
++		}
++	
++	case AGC_STATE_GRANDE_SIGNAL : {
++		if (rf_level > lin_on[band])
++			next_state = AGC_STATE_MAS_GRANDE_SIGNAL;
++		else if (rf_level < lin_off[band]) 
++			next_state = AGC_STATE_MEDIUM_SIGNAL;
++		else if (pd_value > pd_upper[band])
++			next_state = AGC_STATE_GRANDE_INTERFERER;
++		break;
++		}
++	
++	case AGC_STATE_SMALL_SIGNAL : {
++		if (pd_value > pd_upper[band] ) 
++			next_state = AGC_STATE_GRANDE_INTERFERER;
++		else if (bb_level > sens_off[band]) 
++			next_state = AGC_STATE_NORMAL;
++		else if ( (bb_level < sens_on[band]) && (lna_gain == LNAGAIN_MAX) )
++			next_state = AGC_STATE_MAX_SENSITIVITY;
++		break;
++		}
++		
++	case AGC_STATE_MAX_SENSITIVITY : {
++		if (bb_level > sens_off[band]) 
++			next_state = AGC_STATE_SMALL_SIGNAL;
++		break;
++		}
++		
++	}
++			
++	*agc_current_state = next_state;	
++	
++	
++	switch (*agc_current_state) {
++		
++		case AGC_STATE_LNAGAIN_BELOW_MIN : {
++			if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status;
++			break;
++			}
++		
++		case AGC_STATE_LNAGAIN_ABOVE_MAX : {
++			if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_DECR, LNAGAIN_MIN))) goto error_status;
++			break;
++			}
++			
++		case AGC_STATE_NORMAL : {
++			if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status;
++			if (zin >= 2) {
++				zin -= 2;
++				if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status;
++			}
++			break;
++			}
++		
++		case AGC_STATE_NO_INTERFERER : {
++			if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status;
++			if (zin >= 2) {
++				zin -= 2;
++				if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status;
++			}
++
++			if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status;
++			break;
++			}
++
++		case AGC_STATE_MEDIUM_INTERFERER : {
++			if (zin >= 2) {
++				zin -= 2;
++				if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status;
++			}
++
++			// Additional setting
++			// Set tuner with normal bandwidth.
++			if(MT_IS_ERROR(tuner_set_bw_normal(tuner_handle, demod_handle))) goto error_status;
++
++			break;
++			}
++		
++		case AGC_STATE_GRANDE_INTERFERER : {
++			if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_DECR, LNAGAIN_MIN))) goto error_status;
++			if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,1))) goto error_status;
++
++			// Additional setting
++			// Set tuner with narrow bandwidth.
++			if(MT_IS_ERROR(tuner_set_bw_narrow(tuner_handle, demod_handle))) goto error_status;
++
++			break;
++			}
++		
++		case AGC_STATE_MEDIUM_SIGNAL : {
++			if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status;
++			if (zin >= 2) {
++				zin -= 2;
++				if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status;
++			}
++			if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status;
++			break;
++			}
++			
++		case AGC_STATE_GRANDE_SIGNAL : {
++			if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status;
++			break;
++			}
++
++		case AGC_STATE_MAS_GRANDE_SIGNAL : {
++			if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_DECR, LNAGAIN_MIN))) goto error_status;
++			if (lna_gain==0) {
++				if (zin <= 64) {
++					zin += 2;
++					if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status;
++					}
++				}
++			if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status;
++			break;
++			}
++		
++		case AGC_STATE_SMALL_SIGNAL : {
++			if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status;
++			if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_UHF_NORMAL,1))) goto error_status;
++			if (zin >= 2) {
++				zin -= 2;
++				if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status;
++			}
++
++			if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status;
++			*uhf_sens=0;
++			break;
++			}
++		
++		case AGC_STATE_MAX_SENSITIVITY : {
++			if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_UHF_MAXSENS,1))) goto error_status;
++			if (zin >= 2) {
++				zin -= 2;
++				if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status;
++			}
++			if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status;
++			*uhf_sens=1;
++			break;
++			}
++	}	
++
++	if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_LNA_GAIN,&lna_gain))) goto error_status;
++
++	*lna_config=(u8t)lna_gain;
++
++/*
++#ifndef _HOST_DLL
++	uart_write_nr(" LNA ");	
++	uart_writedez(lna_gain);
++	uart_write_nr(" SENS ");
++	uart_writedez(*uhf_sens);
++	uart_write_nr(" Z ");
++	uart_writedez(zin);
++	uart_write(" ");
++#endif
++*/
++
++
++
++	return MT_OK;
++
++
++error_status:
++	return MT_COMM_ERR;
++}
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,266 @@
++#ifndef __NIM_RTL2832_MT2266
++#define __NIM_RTL2832_MT2266
++
++/**
++
++@file
++
++@brief   RTL2832 MT2266 NIM module declaration
++
++One can manipulate RTL2832 MT2266 NIM through RTL2832 MT2266 NIM module.
++RTL2832 MT2266 NIM module is derived from DVB-T NIM module.
++
++
++
++@par Example:
++@code
++
++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines.
++
++
++
++#include "nim_rtl2832_mt2266.h"
++
++
++...
++
++
++
++int main(void)
++{
++	DVBT_NIM_MODULE *pNim;
++	DVBT_NIM_MODULE DvbtNimModuleMemory;
++	RTL2832_EXTRA_MODULE Rtl2832ExtraModuleMemory;
++	MT2266_EXTRA_MODULE Mt2266ExtraModuleMemory;
++
++	...
++
++
++
++	// Build RTL2832 MT2266 NIM module.
++	BuildRtl2832Mt2266Module(
++		&pNim,
++		&DvbtNimModuleMemory,
++
++		9,								// Maximum I2C reading byte number is 9.
++		8,								// Maximum I2C writing byte number is 8.
++		CustomI2cRead,					// Employ CustomI2cRead() as basic I2C reading function.
++		CustomI2cWrite,					// Employ CustomI2cWrite() as basic I2C writing function.
++		CustomWaitMs,					// Employ CustomWaitMs() as basic waiting function.
++
++		&Rtl2832ExtraModuleMemory,		// Employ RTL2832 extra module for RTL2832 module.
++		0x20,							// The RTL2832 I2C device address is 0x20 in 8-bit format.
++		CRYSTAL_FREQ_28800000HZ,		// The RTL2832 crystal frequency is 28.8 MHz.
++		RTL2832_APPLICATION_STB,		// The RTL2832 application mode is STB mode.
++		50,								// The RTL2832 update function reference period is 50 millisecond
++		ON,								// The RTL2832 Function 1 enabling status is on.
++
++		&Mt2266ExtraModuleMemory,		// Employ MT2266 extra module for MT2266 module.
++		0xc0							// The MT2266 I2C device address is 0xc0 in 8-bit format.
++		);
++
++
++
++	// See the example for other NIM functions in dvbt_nim_base.h
++
++	...
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++#include "demod_rtl2832.h"
++#include "tuner_mt2266.h"
++#include "dvbt_nim_base.h"
++
++
++
++
++
++// Definitions
++#define RTL2832_MT2266_ADDITIONAL_INIT_REG_TABLE_LEN		21
++
++#define RTL2832_MT2266_IF_AGC_MIN_BIT_NUM		8
++#define RTL2832_MT2266_IF_AGC_MIN_INT_MAX		36
++#define RTL2832_MT2266_IF_AGC_MIN_INT_MIN		-64
++#define RTL2832_MT2266_IF_AGC_MIN_INT_STEP		0
++
++
++
++
++
++// RTL2832 MT2266 extra module
++typedef struct RTL2832_MT2266_EXTRA_MODULE_TAG RTL2832_MT2266_EXTRA_MODULE;
++struct RTL2832_MT2266_EXTRA_MODULE_TAG
++{
++	// Extra variables
++	unsigned char LnaConfig;
++	unsigned char UhfSens;
++	unsigned char AgcCurrentState;
++	unsigned long LnaGainOld;
++};
++
++
++
++
++
++// Builder
++void
++BuildRtl2832Mt2266Module(
++	DVBT_NIM_MODULE **ppNim,								// DVB-T NIM dependence
++	DVBT_NIM_MODULE *pDvbtNimModuleMemory,
++	RTL2832_MT2266_EXTRA_MODULE *pRtl2832Mt2266ExtraModuleMemory,
++
++	unsigned char I2cReadingByteNumMax,						// Base interface dependence
++	unsigned char I2cWritingByteNumMax,
++	BASE_FP_I2C_READ I2cRead,
++	BASE_FP_I2C_WRITE I2cWrite,
++	BASE_FP_WAIT_MS WaitMs,
++
++	RTL2832_EXTRA_MODULE *pRtl2832ExtraModuleMemory,		// Demod dependence
++	unsigned char DemodDeviceAddr,
++	unsigned long DemodCrystalFreqHz,
++	int DemodAppMode,
++	int DemodTsInterfaceMode,
++	unsigned long DemodUpdateFuncRefPeriodMs,
++	int DemodIsFunc1Enabled,
++
++	MT2266_EXTRA_MODULE *pMt2266ExtraModuleMemory,			// Tuner dependence
++	unsigned char TunerDeviceAddr
++	);
++
++
++
++
++
++// RTL2832 MT2266 NIM manipulaing functions
++int
++rtl2832_mt2266_Initialize(
++	DVBT_NIM_MODULE *pNim
++	);
++
++int
++rtl2832_mt2266_SetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long RfFreqHz,
++	int BandwidthMode
++	);
++
++int
++rtl2832_mt2266_UpdateFunction(
++	DVBT_NIM_MODULE *pNim
++	);
++
++
++
++
++
++// The following context is source code provided by Microtune.
++
++
++
++
++
++// Additional definition for mt_control.c
++typedef unsigned char    u8t;
++typedef unsigned short   u16t;
++typedef unsigned long    u32t;
++typedef void *           handle_t;
++
++#define MT2266_DEMOD_ASSUMED_AGC_REG_BIT_NUM		16
++
++
++
++// Microtune source code - mt_control.c
++
++
++
++/*  $Id: mt_control.c,v 1.6 2008/01/02 12:04:39 tune\tpinz Exp $ */
++/*! 
++ * \file mt_control.c 
++ * \author Thomas Pinz, Microtune GmbH&Co KG
++ * \author Marie-Curie-Str. 1, 85055 Ingolstadt
++ * \author E-Mail: thomas.pinz@microtune.com
++ */
++
++
++#define LNAGAIN_MIN 0
++#define LNAGAIN_MAX 14
++
++#define AGC_STATE_START 0
++#define AGC_STATE_LNAGAIN_BELOW_MIN 1
++#define AGC_STATE_LNAGAIN_ABOVE_MAX 2
++#define AGC_STATE_NORMAL 3
++#define AGC_STATE_NO_INTERFERER 4
++#define AGC_STATE_MEDIUM_INTERFERER 5
++#define AGC_STATE_GRANDE_INTERFERER 6
++#define AGC_STATE_MEDIUM_SIGNAL 7
++#define AGC_STATE_GRANDE_SIGNAL 8
++#define AGC_STATE_MAS_GRANDE_SIGNAL 9
++#define AGC_STATE_MAX_SENSITIVITY 10
++#define AGC_STATE_SMALL_SIGNAL 11
++
++
++UData_t
++demod_get_pd(
++	handle_t demod_handle,
++	u16t *pd_value
++	);
++
++UData_t
++demod_get_agc(
++	handle_t demod_handle,
++	u16t *rf_level,
++	u16t *bb_level
++	);
++
++UData_t
++demod_set_bbagclim(
++	handle_t demod_handle,
++	int on_off_status
++	);
++
++UData_t
++tuner_set_bw_normal(
++	handle_t tuner_handle,
++	handle_t demod_handle
++	);
++
++UData_t
++tuner_set_bw_narrow(
++	handle_t tuner_handle,
++	handle_t demod_handle
++	);
++
++UData_t
++demod_pdcontrol_reset(
++	handle_t demod_handle,
++	handle_t tuner_handle,
++	u8t *agc_current_state
++	);
++
++UData_t
++demod_pdcontrol(
++	handle_t demod_handle,
++	handle_t tuner_handle,
++	u8t* lna_config,
++	u8t* uhf_sens,
++	u8t *agc_current_state,
++	u32t *lna_gain_old
++	);
++
++
++
++
++
++
++
++#endif
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,397 @@
++/**
++
++@file
++
++@brief   RTL2832 MxL5007T NIM module definition
++
++One can manipulate RTL2832 MxL5007T NIM through RTL2832 MxL5007T NIM module.
++RTL2832 MxL5007T NIM module is derived from DVB-T NIM module.
++
++*/
++
++
++#include "nim_rtl2832_mxl5007t.h"
++
++
++
++
++
++/**
++
++@brief   RTL2832 MxL5007T NIM module builder
++
++Use BuildRtl2832Mxl5007tModule() to build RTL2832 MxL5007T NIM module, set all module function pointers with the
++corresponding functions, and initialize module private variables.
++
++
++@param [in]   ppNim                        Pointer to RTL2832 MxL5007T NIM module pointer
++@param [in]   pDvbtNimModuleMemory         Pointer to an allocated DVB-T NIM module memory
++@param [in]   I2cReadingByteNumMax         Maximum I2C reading byte number for basic I2C reading function
++@param [in]   I2cWritingByteNumMax         Maximum I2C writing byte number for basic I2C writing function
++@param [in]   I2cRead                      Basic I2C reading function pointer
++@param [in]   I2cWrite                     Basic I2C writing function pointer
++@param [in]   WaitMs                       Basic waiting function pointer
++@param [in]   pRtl2832ExtraModuleMemory    Pointer to an allocated RTL2832 extra module memory
++@param [in]   DemodDeviceAddr              RTL2832 I2C device address
++@param [in]   DemodCrystalFreqHz           RTL2832 crystal frequency in Hz
++@param [in]   DemodAppMode                 RTL2832 application mode for setting
++@param [in]   DemodTsInterfaceMode         RTL2832 TS interface mode for setting
++@param [in]   DemodUpdateFuncRefPeriodMs   RTL2832 update function reference period in millisecond for setting
++@param [in]   DemodIsFunc1Enabled          RTL2832 Function 1 enabling status for setting
++@param [in]   pMxl5007tExtraModuleMemory   Pointer to an allocated Mxl5007T extra module memory
++@param [in]   TunerDeviceAddr              Mxl5007T I2C device address
++@param [in]   TunerAgcMode                 Mxl5007T AGC mode
++
++
++@note
++	-# One should call BuildRtl2832Mxl5007tModule() to build RTL2832 MxL5007T NIM module before using it.
++
++*/
++void
++BuildRtl2832Mxl5007tModule(
++	DVBT_NIM_MODULE **ppNim,								// DVB-T NIM dependence
++	DVBT_NIM_MODULE *pDvbtNimModuleMemory,
++
++	unsigned char I2cReadingByteNumMax,						// Base interface dependence
++	unsigned char I2cWritingByteNumMax,
++	BASE_FP_I2C_READ I2cRead,
++	BASE_FP_I2C_WRITE I2cWrite,
++	BASE_FP_WAIT_MS WaitMs,
++
++	RTL2832_EXTRA_MODULE *pRtl2832ExtraModuleMemory,		// Demod dependence
++	unsigned char DemodDeviceAddr,
++	unsigned long DemodCrystalFreqHz,
++	int DemodAppMode,
++	int DemodTsInterfaceMode,
++	unsigned long DemodUpdateFuncRefPeriodMs,
++	int DemodIsFunc1Enabled,
++
++	MXL5007T_EXTRA_MODULE *pMxl5007tExtraModuleMemory,			// Tuner dependence
++	unsigned char TunerDeviceAddr,
++	unsigned long TunerCrystalFreqHz,
++	int TunerClkOutMode,
++	int TunerClkOutAmpMode
++	)
++{
++	DVBT_NIM_MODULE *pNim;
++
++
++
++	// Set NIM module pointer with NIM module memory.
++	*ppNim = pDvbtNimModuleMemory;
++	
++	// Get NIM module.
++	pNim = *ppNim;
++
++	// Set I2C bridge module pointer with I2C bridge module memory.
++	pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory;
++
++	// Set NIM extra module pointer.
++	pNim->pExtra = INVALID_POINTER_VALUE;
++
++
++	// Set NIM type.
++	pNim->NimType = DVBT_NIM_RTL2832_MXL5007T;
++
++
++	// Build base interface module.
++	BuildBaseInterface(
++		&pNim->pBaseInterface,
++		&pNim->BaseInterfaceModuleMemory,
++		I2cReadingByteNumMax,
++		I2cWritingByteNumMax,
++		I2cRead,
++		I2cWrite,
++		WaitMs
++		);
++
++	// Build RTL2832 demod module.
++	BuildRtl2832Module(
++		&pNim->pDemod,
++		&pNim->DvbtDemodModuleMemory,
++		pRtl2832ExtraModuleMemory,
++		&pNim->BaseInterfaceModuleMemory,
++		&pNim->I2cBridgeModuleMemory,
++		DemodDeviceAddr,
++		DemodCrystalFreqHz,
++		DemodAppMode,
++		DemodUpdateFuncRefPeriodMs,
++		DemodIsFunc1Enabled
++		);
++
++	// Build Mxl5007T tuner module.
++	BuildMxl5007tModule(
++		&pNim->pTuner,
++		&pNim->TunerModuleMemory,
++		pMxl5007tExtraModuleMemory,
++		&pNim->BaseInterfaceModuleMemory,
++		&pNim->I2cBridgeModuleMemory,
++		TunerDeviceAddr,
++		TunerCrystalFreqHz,
++		RTL2832_MXL5007T_STANDARD_MODE_DEFAULT,
++		RTL2832_MXL5007T_IF_FREQ_HZ_DEFAULT,
++		RTL2832_MXL5007T_SPECTRUM_MODE_DEFAULT,
++		TunerClkOutMode,
++		TunerClkOutAmpMode,
++		RTL2832_MXL5007T_QAM_IF_DIFF_OUT_LEVEL_DEFAULT
++		);
++
++
++	// Set NIM module variables.
++	pNim->DemodTsInterfaceMode = DemodTsInterfaceMode;
++
++
++	// Set NIM module function pointers with default functions.
++	pNim->GetNimType        = dvbt_nim_default_GetNimType;
++	pNim->GetParameters     = dvbt_nim_default_GetParameters;
++	pNim->IsSignalPresent   = dvbt_nim_default_IsSignalPresent;
++	pNim->IsSignalLocked    = dvbt_nim_default_IsSignalLocked;
++	pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength;
++	pNim->GetSignalQuality  = dvbt_nim_default_GetSignalQuality;
++	pNim->GetBer            = dvbt_nim_default_GetBer;
++	pNim->GetSnrDb          = dvbt_nim_default_GetSnrDb;
++	pNim->GetTrOffsetPpm    = dvbt_nim_default_GetTrOffsetPpm;
++	pNim->GetCrOffsetHz     = dvbt_nim_default_GetCrOffsetHz;
++	pNim->GetTpsInfo        = dvbt_nim_default_GetTpsInfo;
++	pNim->UpdateFunction    = dvbt_nim_default_UpdateFunction;
++
++	// Set NIM module function pointers with particular functions.
++	pNim->Initialize     = rtl2832_mxl5007t_Initialize;
++	pNim->SetParameters  = rtl2832_mxl5007t_SetParameters;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_INITIALIZE
++
++*/
++int
++rtl2832_mxl5007t_Initialize(
++	DVBT_NIM_MODULE *pNim
++	)
++{
++	typedef struct
++	{
++		int RegBitName;
++		unsigned long Value;
++	}
++	REG_VALUE_ENTRY;
++
++
++	static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN] =
++	{
++		// RegBitName,				Value
++		{DVBT_DAGC_TRG_VAL,			0x39	},
++		{DVBT_AGC_TARG_VAL_0,		0x0		},
++		{DVBT_AGC_TARG_VAL_8_1,		0x32	},
++		{DVBT_AAGC_LOOP_GAIN,		0x16    },
++		{DVBT_LOOP_GAIN2_3_0,		0x6		},
++		{DVBT_LOOP_GAIN2_4,			0x1		},
++		{DVBT_LOOP_GAIN3,			0x16	},
++		{DVBT_VTOP1,				0x35	},
++		{DVBT_VTOP2,				0x21	},
++		{DVBT_VTOP3,				0x21	},
++		{DVBT_KRF1,					0x0		},
++		{DVBT_KRF2,					0x40	},
++		{DVBT_KRF3,					0x10	},
++		{DVBT_KRF4,					0x10	},
++		{DVBT_IF_AGC_MIN,			0x80	},
++		{DVBT_IF_AGC_MAX,			0x7f	},
++		{DVBT_RF_AGC_MIN,			0x80	},
++		{DVBT_RF_AGC_MAX,			0x7f	},
++		{DVBT_POLAR_RF_AGC,			0x0		},
++		{DVBT_POLAR_IF_AGC,			0x0		},
++		{DVBT_AD7_SETTING,			0xe9d4	},
++		{DVBT_AD_EN_REG1,			0x0		},
++		{DVBT_CKOUT_PWR_PID,		0x0		},
++	};
++
++
++	TUNER_MODULE *pTuner;
++	DVBT_DEMOD_MODULE *pDemod;
++
++	int i;
++
++	int RegBitName;
++	unsigned long Value;
++
++
++
++	// Get tuner module and demod module.
++	pTuner = pNim->pTuner;
++	pDemod = pNim->pDemod;
++
++
++	// Enable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	// Initialize tuner.
++	if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Disable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Initialize demod.
++	if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Set demod IF frequency with NIM default.
++	if(pDemod->SetIfFreqHz(pDemod, RTL2832_MXL5007T_IF_FREQ_HZ_DEFAULT) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Set demod spectrum mode with NIM default.
++	if(pDemod->SetSpectrumMode(pDemod, RTL2832_MXL5007T_SPECTRUM_MODE_DEFAULT) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	// Set demod registers.
++	for(i = 0; i < RTL2832_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN; i++)
++	{
++		// Get register bit name and its value.
++		RegBitName = AdditionalInitRegValueTable[i].RegBitName;
++		Value      = AdditionalInitRegValueTable[i].Value;
++
++		// Set demod registers
++		if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS)
++			goto error_status_set_registers;
++	}
++
++
++	// Set TS interface according to TS interface mode.
++	switch(pNim->DemodTsInterfaceMode)
++	{
++		case TS_INTERFACE_PARALLEL:
++
++			// Set demod TS interface with parallel mode.
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SERIAL,   0) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH0, 9) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH1, 9) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			break;
++
++
++		default:
++		case TS_INTERFACE_SERIAL:
++
++			// Set demod TS interface with serial mode.
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SERIAL,   1) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH0, 2) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH1, 2) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_SET_PARAMETERS
++
++*/
++int
++rtl2832_mxl5007t_SetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long RfFreqHz,
++	int BandwidthMode
++	)
++{
++	TUNER_MODULE *pTuner;
++	DVBT_DEMOD_MODULE *pDemod;
++
++	MXL5007T_EXTRA_MODULE *pTunerExtra;
++	int TunerBandwidthMode;
++
++
++
++	// Get tuner module and demod module.
++	pTuner = pNim->pTuner;
++	pDemod = pNim->pDemod;
++
++	// Get tuner extra module.
++	pTunerExtra = (MXL5007T_EXTRA_MODULE *)pTuner->pExtra;
++
++
++	// Enable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	// Set tuner RF frequency in Hz.
++	if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Determine TunerBandwidthMode according to bandwidth mode.
++	switch(BandwidthMode)
++	{
++		default:
++		case DVBT_BANDWIDTH_6MHZ:		TunerBandwidthMode = MXL5007T_BANDWIDTH_6000000HZ;		break;
++		case DVBT_BANDWIDTH_7MHZ:		TunerBandwidthMode = MXL5007T_BANDWIDTH_7000000HZ;		break;
++		case DVBT_BANDWIDTH_8MHZ:		TunerBandwidthMode = MXL5007T_BANDWIDTH_8000000HZ;		break;
++	}
++
++	// Set tuner bandwidth mode with TunerBandwidthMode.
++	if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Disable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Set demod bandwidth mode.
++	if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Reset demod particular registers.
++	if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	// Reset demod by software reset.
++	if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,155 @@
++#ifndef __NIM_RTL2832_MXL5007T
++#define __NIM_RTL2832_MXL5007T
++
++/**
++
++@file
++
++@brief   RTL2832 MxL5007T NIM module declaration
++
++One can manipulate RTL2832 MxL5007T NIM through RTL2832 MxL5007T NIM module.
++RTL2832 MxL5007T NIM module is derived from DVB-T NIM module.
++
++
++
++@par Example:
++@code
++
++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines.
++
++
++
++#include "nim_rtl2832_mxl5007t.h"
++
++
++...
++
++
++
++int main(void)
++{
++	DVBT_NIM_MODULE *pNim;
++	DVBT_NIM_MODULE DvbtNimModuleMemory;
++	RTL2832_EXTRA_MODULE Rtl2832ExtraModuleMemory;
++	MXL5007T_EXTRA_MODULE Mxl5007tExtraModuleMemory;
++
++	...
++
++
++
++	// Build RTL2832 MxL5007T NIM module.
++	BuildRtl2832Mxl5007tModule(
++		&pNim,
++		&DvbtNimModuleMemory,
++
++		9,								// Maximum I2C reading byte number is 9.
++		8,								// Maximum I2C writing byte number is 8.
++		CustomI2cRead,					// Employ CustomI2cRead() as basic I2C reading function.
++		CustomI2cWrite,					// Employ CustomI2cWrite() as basic I2C writing function.
++		CustomWaitMs,					// Employ CustomWaitMs() as basic waiting function.
++
++		&Rtl2832ExtraModuleMemory,		// Employ RTL2832 extra module for RTL2832 module.
++		0x20,							// The RTL2832 I2C device address is 0x20 in 8-bit format.
++		CRYSTAL_FREQ_28800000HZ,		// The RTL2832 crystal frequency is 28.8 MHz.
++		RTL2832_APPLICATION_STB,		// The RTL2832 application mode is STB mode.
++		TS_INTERFACE_SERIAL,			// The RTL2832 TS interface mode is serial.
++		50,								// The RTL2832 update function reference period is 50 millisecond
++		ON,								// The RTL2832 Function 1 enabling status is on.
++
++		&Mxl5007tExtraModuleMemory,		// Employ Mxl5007T extra module for Mxl5007T module.
++		0xc0,							// The MxL5007T I2C device address is 0xc0 in 8-bit format.
++		CRYSTAL_FREQ_16000000HZ,		// The MxL5007T Crystal frequency is 16.0 MHz.
++		MXL5007T_CLK_OUT_DISABLE,		// The MxL5007T clock output mode is disabled.
++		MXL5007T_CLK_OUT_AMP_0			// The MxL5007T clock output amplitude is 0.
++		);
++
++
++
++	// See the example for other NIM functions in dvbt_nim_base.h
++
++	...
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++#include "demod_rtl2832.h"
++#include "tuner_mxl5007t.h"
++#include "dvbt_nim_base.h"
++
++
++
++
++
++// Definitions
++#define RTL2832_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN		23
++
++// Default
++#define RTL2832_MXL5007T_STANDARD_MODE_DEFAULT				MXL5007T_STANDARD_DVBT
++#define RTL2832_MXL5007T_IF_FREQ_HZ_DEFAULT					IF_FREQ_4570000HZ
++#define RTL2832_MXL5007T_SPECTRUM_MODE_DEFAULT				SPECTRUM_NORMAL
++#define RTL2832_MXL5007T_QAM_IF_DIFF_OUT_LEVEL_DEFAULT		0
++
++
++
++
++
++// Builder
++void
++BuildRtl2832Mxl5007tModule(
++	DVBT_NIM_MODULE **ppNim,								// DVB-T NIM dependence
++	DVBT_NIM_MODULE *pDvbtNimModuleMemory,
++
++	unsigned char I2cReadingByteNumMax,						// Base interface dependence
++	unsigned char I2cWritingByteNumMax,
++	BASE_FP_I2C_READ I2cRead,
++	BASE_FP_I2C_WRITE I2cWrite,
++	BASE_FP_WAIT_MS WaitMs,
++
++	RTL2832_EXTRA_MODULE *pRtl2832ExtraModuleMemory,		// Demod dependence
++	unsigned char DemodDeviceAddr,
++	unsigned long DemodCrystalFreqHz,
++	int DemodAppMode,
++	int DemodTsInterfaceMode,
++	unsigned long DemodUpdateFuncRefPeriodMs,
++	int DemodIsFunc1Enabled,
++
++	MXL5007T_EXTRA_MODULE *pMxl5007tExtraModuleMemory,			// Tuner dependence
++	unsigned char TunerDeviceAddr,
++	unsigned long TunerCrystalFreqHz,
++	int TunerClkOutMode,
++	int TunerClkOutAmpMode
++	);
++
++
++
++
++
++// RTL2832 MxL5007T NIM manipulaing functions
++int
++rtl2832_mxl5007t_Initialize(
++	DVBT_NIM_MODULE *pNim
++	);
++
++int
++rtl2832_mxl5007t_SetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long RfFreqHz,
++	int BandwidthMode
++	);
++
++
++
++
++
++
++
++#endif
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,386 @@
++/**
++
++@file
++
++@brief   RTL2832 TUA9001 NIM module definition
++
++One can manipulate RTL2832 TUA9001 NIM through RTL2832 TUA9001 NIM module.
++RTL2832 TUA9001 NIM module is derived from DVB-T NIM module.
++
++*/
++
++
++#include "nim_rtl2832_tua9001.h"
++
++
++
++
++
++/**
++
++@brief   RTL2832 TUA9001 NIM module builder
++
++Use BuildRtl2832Tua9001Module() to build RTL2832 TUA9001 NIM module, set all module function pointers with the
++corresponding functions, and initialize module private variables.
++
++
++@param [in]   ppNim                       Pointer to RTL2832 TUA9001 NIM module pointer
++@param [in]   pDvbtNimModuleMemory        Pointer to an allocated DVB-T NIM module memory
++@param [in]   I2cReadingByteNumMax        Maximum I2C reading byte number for basic I2C reading function
++@param [in]   I2cWritingByteNumMax        Maximum I2C writing byte number for basic I2C writing function
++@param [in]   I2cRead                     Basic I2C reading function pointer
++@param [in]   I2cWrite                    Basic I2C writing function pointer
++@param [in]   WaitMs                      Basic waiting function pointer
++@param [in]   pRtl2832ExtraModuleMemory   Pointer to an allocated RTL2832 extra module memory
++@param [in]   DemodDeviceAddr             RTL2832 I2C device address
++@param [in]   DemodCrystalFreqHz          RTL2832 crystal frequency in Hz
++@param [in]   DemodAppMode                RTL2832 application mode for setting
++@param [in]   DemodTsInterfaceMode        RTL2832 TS interface mode for setting
++@param [in]   pTua9001ExtraModuleMemory    Pointer to an allocated TUA9001 extra module memory
++@param [in]   TunerDeviceAddr             TUA9001 I2C device address
++@param [in]   TunerAgcMode                TUA9001 AGC mode
++
++
++@note
++	-# One should call BuildRtl2832Tua9001Module() to build RTL2832 TUA9001 NIM module before using it.
++
++*/
++void
++BuildRtl2832Tua9001Module(
++	DVBT_NIM_MODULE **ppNim,								// DVB-T NIM dependence
++	DVBT_NIM_MODULE *pDvbtNimModuleMemory,
++
++	unsigned char I2cReadingByteNumMax,						// Base interface dependence
++	unsigned char I2cWritingByteNumMax,
++	BASE_FP_I2C_READ I2cRead,
++	BASE_FP_I2C_WRITE I2cWrite,
++	BASE_FP_WAIT_MS WaitMs,
++
++	RTL2832_EXTRA_MODULE *pRtl2832ExtraModuleMemory,		// Demod dependence
++	unsigned char DemodDeviceAddr,
++	unsigned long DemodCrystalFreqHz,
++	int DemodAppMode,
++	int DemodTsInterfaceMode,
++	unsigned long DemodUpdateFuncRefPeriodMs,
++	int DemodIsFunc1Enabled,
++
++	TUA9001_EXTRA_MODULE *pTua9001ExtraModuleMemory,		// Tuner dependence
++	unsigned char TunerDeviceAddr
++	)
++{
++	DVBT_NIM_MODULE *pNim;
++
++
++
++	// Set NIM module pointer with NIM module memory.
++	*ppNim = pDvbtNimModuleMemory;
++	
++	// Get NIM module.
++	pNim = *ppNim;
++
++	// Set I2C bridge module pointer with I2C bridge module memory.
++	pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory;
++
++	// Set NIM extra module pointer.
++	pNim->pExtra = INVALID_POINTER_VALUE;
++
++
++	// Set NIM type.
++	pNim->NimType = DVBT_NIM_RTL2832_TUA9001;
++
++
++	// Build base interface module.
++	BuildBaseInterface(
++		&pNim->pBaseInterface,
++		&pNim->BaseInterfaceModuleMemory,
++		I2cReadingByteNumMax,
++		I2cWritingByteNumMax,
++		I2cRead,
++		I2cWrite,
++		WaitMs
++		);
++
++	// Build RTL2832 demod module.
++	BuildRtl2832Module(
++		&pNim->pDemod,
++		&pNim->DvbtDemodModuleMemory,
++		pRtl2832ExtraModuleMemory,
++		&pNim->BaseInterfaceModuleMemory,
++		&pNim->I2cBridgeModuleMemory,
++		DemodDeviceAddr,
++		DemodCrystalFreqHz,
++		DemodAppMode,
++		DemodUpdateFuncRefPeriodMs,
++		DemodIsFunc1Enabled
++		);
++
++	// Build TUA9001 tuner module.
++	BuildTua9001Module(
++		&pNim->pTuner,
++		&pNim->TunerModuleMemory,
++		pTua9001ExtraModuleMemory,
++		&pNim->BaseInterfaceModuleMemory,
++		&pNim->I2cBridgeModuleMemory,
++		TunerDeviceAddr
++		);
++
++
++	// Set NIM module variables.
++	pNim->DemodTsInterfaceMode = DemodTsInterfaceMode;
++
++
++	// Set NIM module function pointers with default functions.
++	pNim->GetNimType        = dvbt_nim_default_GetNimType;
++	pNim->GetParameters     = dvbt_nim_default_GetParameters;
++	pNim->IsSignalPresent   = dvbt_nim_default_IsSignalPresent;
++	pNim->IsSignalLocked    = dvbt_nim_default_IsSignalLocked;
++	pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength;
++	pNim->GetSignalQuality  = dvbt_nim_default_GetSignalQuality;
++	pNim->GetBer            = dvbt_nim_default_GetBer;
++	pNim->GetSnrDb          = dvbt_nim_default_GetSnrDb;
++	pNim->GetTrOffsetPpm    = dvbt_nim_default_GetTrOffsetPpm;
++	pNim->GetCrOffsetHz     = dvbt_nim_default_GetCrOffsetHz;
++	pNim->GetTpsInfo        = dvbt_nim_default_GetTpsInfo;
++	pNim->UpdateFunction    = dvbt_nim_default_UpdateFunction;
++
++	// Set NIM module function pointers with particular functions.
++	pNim->Initialize     = rtl2832_tua9001_Initialize;
++	pNim->SetParameters  = rtl2832_tua9001_SetParameters;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_INITIALIZE
++
++*/
++int
++rtl2832_tua9001_Initialize(
++	DVBT_NIM_MODULE *pNim
++	)
++{
++	typedef struct
++	{
++		int RegBitName;
++		unsigned long Value;
++	}
++	REG_VALUE_ENTRY;
++
++
++	static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_TUA9001_ADDITIONAL_INIT_REG_TABLE_LEN] =
++	{
++		// RegBitName,				Value
++		{DVBT_DAGC_TRG_VAL,			0x39	},
++		{DVBT_AGC_TARG_VAL_0,		0x0		},
++		{DVBT_AGC_TARG_VAL_8_1,		0x5a	},
++		{DVBT_AAGC_LOOP_GAIN,		0x16    },
++		{DVBT_LOOP_GAIN2_3_0,		0x6		},
++		{DVBT_LOOP_GAIN2_4,			0x1		},
++		{DVBT_LOOP_GAIN3,			0x16	},
++		{DVBT_VTOP1,				0x35	},
++		{DVBT_VTOP2,				0x21	},
++		{DVBT_VTOP3,				0x21	},
++		{DVBT_KRF1,					0x0		},
++		{DVBT_KRF2,					0x40	},
++		{DVBT_KRF3,					0x10	},
++		{DVBT_KRF4,					0x10	},
++		{DVBT_IF_AGC_MIN,			0x80	},
++		{DVBT_IF_AGC_MAX,			0x7f	},
++		{DVBT_RF_AGC_MIN,			0x9c	},
++		{DVBT_RF_AGC_MAX,			0x7f	},
++		{DVBT_POLAR_RF_AGC,			0x0		},
++		{DVBT_POLAR_IF_AGC,			0x0		},
++		{DVBT_AD7_SETTING,			0xe9f4	},
++		{DVBT_OPT_ADC_IQ,			0x1		},
++		{DVBT_AD_AVI,				0x0		},
++		{DVBT_AD_AVQ,				0x0		},
++	};
++
++
++	TUNER_MODULE *pTuner;
++	DVBT_DEMOD_MODULE *pDemod;
++
++	int i;
++
++	int RegBitName;
++	unsigned long Value;
++
++
++
++	// Get tuner module and demod module.
++	pTuner = pNim->pTuner;
++	pDemod = pNim->pDemod;
++
++
++	// Enable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	// Initialize tuner.
++	if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Disable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Initialize demod.
++	if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Set demod IF frequency with 0 Hz.
++	if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Set demod spectrum mode with SPECTRUM_NORMAL.
++	if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	// Set demod registers.
++	for(i = 0; i < RTL2832_TUA9001_ADDITIONAL_INIT_REG_TABLE_LEN; i++)
++	{
++		// Get register bit name and its value.
++		RegBitName = AdditionalInitRegValueTable[i].RegBitName;
++		Value      = AdditionalInitRegValueTable[i].Value;
++
++		// Set demod registers
++		if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS)
++			goto error_status_set_registers;
++	}
++
++
++	// Set TS interface according to TS interface mode.
++	switch(pNim->DemodTsInterfaceMode)
++	{
++		case TS_INTERFACE_PARALLEL:
++
++			// Set demod TS interface with parallel mode.
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SERIAL,   0) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH0, 9) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH1, 9) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			break;
++
++
++		default:
++		case TS_INTERFACE_SERIAL:
++
++			// Set demod TS interface with serial mode.
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SERIAL,   1) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH0, 2) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CDIV_PH1, 2) != FUNCTION_SUCCESS)
++				goto error_status_set_registers;
++
++			break;
++	}
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   DVBT_NIM_FP_SET_PARAMETERS
++
++*/
++int
++rtl2832_tua9001_SetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long RfFreqHz,
++	int BandwidthMode
++	)
++{
++	TUNER_MODULE *pTuner;
++	DVBT_DEMOD_MODULE *pDemod;
++
++	TUA9001_EXTRA_MODULE *pTunerExtra;
++	int TunerBandwidthMode;
++
++
++
++	// Get tuner module and demod module.
++	pTuner = pNim->pTuner;
++	pDemod = pNim->pDemod;
++
++	// Get tuner extra module.
++	pTunerExtra = (TUA9001_EXTRA_MODULE *)pTuner->pExtra;
++
++
++	// Enable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++	// Set tuner RF frequency in Hz.
++	if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Determine TunerBandwidthMode according to bandwidth mode.
++	switch(BandwidthMode)
++	{
++		default:
++		case DVBT_BANDWIDTH_6MHZ:		TunerBandwidthMode = TUA9001_BANDWIDTH_6MHZ;		break;
++		case DVBT_BANDWIDTH_7MHZ:		TunerBandwidthMode = TUA9001_BANDWIDTH_7MHZ;		break;
++		case DVBT_BANDWIDTH_8MHZ:		TunerBandwidthMode = TUA9001_BANDWIDTH_8MHZ;		break;
++	}
++
++	// Set tuner bandwidth mode with TunerBandwidthMode.
++	if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Disable demod DVBT_IIC_REPEAT.
++	if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS)
++		goto error_status_set_registers;
++
++
++	// Set demod bandwidth mode.
++	if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++	// Reset demod particular registers.
++	if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	// Reset demod by software reset.
++	if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS)
++		goto error_status_execute_function;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_execute_function:
++error_status_set_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,142 @@
++#ifndef __NIM_RTL2832_TUA9001
++#define __NIM_RTL2832_TUA9001
++
++/**
++
++@file
++
++@brief   RTL2832 TUA9001 NIM module declaration
++
++One can manipulate RTL2832 TUA9001 NIM through RTL2832 TUA9001 NIM module.
++RTL2832 TUA9001 NIM module is derived from DVB-T NIM module.
++
++
++
++@par Example:
++@code
++
++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines.
++
++
++
++#include "nim_rtl2832_tua9001.h"
++
++
++...
++
++
++
++int main(void)
++{
++	DVBT_NIM_MODULE *pNim;
++	DVBT_NIM_MODULE DvbtNimModuleMemory;
++	RTL2832_EXTRA_MODULE Rtl2832ExtraModuleMemory;
++	TUA9001_EXTRA_MODULE Tua9001ExtraModuleMemory;
++
++	...
++
++
++
++	// Build RTL2832 TUA9001 NIM module.
++	BuildRtl2832Tua9001Module(
++		&pNim,
++		&DvbtNimModuleMemory,
++
++		9,								// Maximum I2C reading byte number is 9.
++		8,								// Maximum I2C writing byte number is 8.
++		CustomI2cRead,					// Employ CustomI2cRead() as basic I2C reading function.
++		CustomI2cWrite,					// Employ CustomI2cWrite() as basic I2C writing function.
++		CustomWaitMs,					// Employ CustomWaitMs() as basic waiting function.
++
++		&Rtl2832ExtraModuleMemory,		// Employ RTL2832 extra module for RTL2832 module.
++		0x20,							// The RTL2832 I2C device address is 0x20 in 8-bit format.
++		CRYSTAL_FREQ_28800000HZ,		// The RTL2832 crystal frequency is 28.8 MHz.
++		RTL2832_APPLICATION_STB,		// The RTL2832 application mode is STB mode.
++		50,								// The RTL2832 update function reference period is 50 millisecond
++		ON,								// The RTL2832 Function 1 enabling status is on.
++
++		&Tua9001ExtraModuleMemory,		// Employ TUA9001 extra module for TUA9001 module.
++		0xac,							// The TUA9001 I2C device address is 0xac in 8-bit format.
++		);
++
++
++
++	// See the example for other NIM functions in dvbt_nim_base.h
++
++	...
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++#include "demod_rtl2832.h"
++#include "tuner_tua9001.h"
++#include "dvbt_nim_base.h"
++
++
++
++
++
++// Definitions
++#define RTL2832_TUA9001_ADDITIONAL_INIT_REG_TABLE_LEN		24
++
++
++
++
++
++// Builder
++void
++BuildRtl2832Tua9001Module(
++	DVBT_NIM_MODULE **ppNim,								// DVB-T NIM dependence
++	DVBT_NIM_MODULE *pDvbtNimModuleMemory,
++
++	unsigned char I2cReadingByteNumMax,						// Base interface dependence
++	unsigned char I2cWritingByteNumMax,
++	BASE_FP_I2C_READ I2cRead,
++	BASE_FP_I2C_WRITE I2cWrite,
++	BASE_FP_WAIT_MS WaitMs,
++
++	RTL2832_EXTRA_MODULE *pRtl2832ExtraModuleMemory,		// Demod dependence
++	unsigned char DemodDeviceAddr,
++	unsigned long DemodCrystalFreqHz,
++	int DemodAppMode,
++	int DemodTsInterfaceMode,
++	unsigned long UpdateFuncRefPeriodMs,
++	int IsFunc1Enabled,
++
++	TUA9001_EXTRA_MODULE *pTua9001ExtraModuleMemory,		// Tuner dependence
++	unsigned char TunerDeviceAddr
++	);
++
++
++
++
++
++// RTL2832 TUA9001 NIM manipulaing functions
++int
++rtl2832_tua9001_Initialize(
++	DVBT_NIM_MODULE *pNim
++	);
++
++int
++rtl2832_tua9001_SetParameters(
++	DVBT_NIM_MODULE *pNim,
++	unsigned long RfFreqHz,
++	int BandwidthMode
++	);
++
++
++
++
++
++
++
++#endif
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/readme.txt
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/readme.txt	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,40 @@
++Driver Installation in Linux
++
++1.  Download "v4l-dvb-(version)" source code from http://linuxtv.org/. 
++
++2.	Copy the folder 'rtl2832u_linux_driver' and "v4l-dvb-(version)" source code to the desktop.
++
++3.	Click 'Applications' -> 'Accessories' -> 'Terminal' to enter the console mode. 
++
++4.	Type 'cd /root/Desktop/rtl2832u_linux_driver' to enter the folder.
++
++5.	In the folder 'rtl2832u_linux_driver', type the following command to compile & install. 
++
++	a. Type 'cp -f *.* /root/Desktop/v4l-dvb-(version)/linux/drivers/media/dvb/dvb-usb' to copy all files into v4l-dvb-(version) code.
++
++	b. add the following lines to Makefile in v4l-dvb-(version)/linux/drivers/media/dvb/dvb-usb.
++dvb-usb-rtl2832u-objs = demod_rtl2832.o	dvbt_demod_base.o dvbt_nim_base.o foundation.o math_mpi.o nim_rtl2832_mxl5007t.o nim_rtl2832_fc2580.o nim_rtl2832_mt2266.o rtl2832u.o rtl2832u_fe.o rtl2832u_io.o tuner_mxl5007t.o tuner_fc2580.o tuner_mt2266.o tuner_tua9001.o nim_rtl2832_tua9001.o
++obj-$(CONFIG_DVB_USB_RTL2832U) += dvb-usb-rtl2832u.o
++
++	c. add the following lines to Kconfig in v4l-dvb-(version)/linux/drivers/media/dvb/dvb-usb.	
++config DVB_USB_RTL2832U
++	tristate "Realtek RTL2832U DVB-T USB2.0 support"
++	depends on DVB_USB
++	help
++	  Realtek RTL2832U DVB-T driver.
++				
++   	d. Type 'make clean'
++   	d. Type 'make'   	
++   	f. Type 'make install'
++
++6.	Plug in our DVB-T USB device;
++
++7.	Type 'lsmod | grep dvb', and it will show
++   	dvb_usb_rtl2831u
++   	dvb_usb
++   	dvb_core
++   	i2c_core
++    
++    Your driver has been installed successfully.
++
++8. Install the applications --'Xine' and 'linuxtv-dvb-apps'. 
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/rtl2832u.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/rtl2832u.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,287 @@
++
++#include <linux/module.h>
++#include <linux/version.h>
++
++#include "rtl2832u.h"
++#include "rtl2832u_io.h"
++
++int dvb_usb_rtl2832u_debug;
++module_param_named(debug,dvb_usb_rtl2832u_debug, int, 0644);
++MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
++
++//DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
++
++#define	USB_EPA_CTL	0x0148
++
++
++static int rtl2832u_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff)
++{
++	u8 data[2];	
++	//3 to avoid  scanning  channels loss
++	if(onoff)
++	{
++		data[0] = data[1] = 0;		
++		if ( write_usb_sys_char_bytes( adap->dev , RTD2832U_USB , USB_EPA_CTL , data , 2) ) goto error;				
++	}
++	else
++	{
++		data[0] = 0x10;	//3stall epa, set bit 4 to 1
++		data[1] = 0x02;	//3reset epa, set bit 9 to 1
++		if ( write_usb_sys_char_bytes( adap->dev , RTD2832U_USB , USB_EPA_CTL , data , 2) ) goto error;		
++	}
++
++	return 0;
++error: 
++	return -1;
++}
++
++
++static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
++{
++	adap->fe = rtl2832u_fe_attach(adap->dev); 
++	return 0;
++}
++
++
++static void rtl2832u_usb_disconnect(struct usb_interface *intf)
++{
++	try_module_get(THIS_MODULE);
++	dvb_usb_device_exit(intf);	
++}
++
++
++static struct dvb_usb_device_properties rtl2832u_1st_properties;
++static struct dvb_usb_device_properties rtl2832u_2nd_properties;
++static struct dvb_usb_device_properties rtl2832u_3th_properties;
++
++
++static int rtl2832u_usb_probe(struct usb_interface *intf,
++		const struct usb_device_id *id)
++{
++	if ( ( 0== dvb_usb_device_init(intf,&rtl2832u_1st_properties,THIS_MODULE,NULL) )||
++		( 0== dvb_usb_device_init(intf,&rtl2832u_2nd_properties,THIS_MODULE,NULL) ) ||
++		( 0== dvb_usb_device_init(intf,&rtl2832u_3th_properties,THIS_MODULE,NULL) ))
++		return 0;
++
++	return -ENODEV;
++}
++
++static struct usb_device_id rtl2832u_usb_table [] = {
++	{ USB_DEVICE(USB_VID_REALTEK, USB_PID_RTD2832U_WARM) },
++	{ USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_USB_WARM) },
++	{ USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_WARM_6) },
++	{ USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_USB_WARM) },
++	{ USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_MINIUSB_WARM) },
++	{ USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_5217_WARM) },
++
++	{ USB_DEVICE(USB_VID_REALTEK, USB_PID_RTD2832U_2ND_WARM) },
++	{ USB_DEVICE(USB_VID_GOLDENBRIDGE, USB_PID_GOLDENBRIDGE_WARM) },
++	{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_WARM) },
++	{ USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_MINI_WARM) },
++	{ USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_GPS_WARM) },	
++	{ USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_WARM_7) },
++	
++	{ USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_WARM_3) },
++	{ USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_WARM_8) },
++	{ USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM) },	
++	{ 0 },
++};
++
++
++MODULE_DEVICE_TABLE(usb, rtl2832u_usb_table);
++
++static struct dvb_usb_device_properties rtl2832u_1st_properties = {
++
++	.num_adapters = 1,
++	.adapter = 
++	{
++		{
++			.streaming_ctrl = rtl2832u_streaming_ctrl,
++			.frontend_attach = rtl2832u_frontend_attach,
++			//parameter for the MPEG2-data transfer 
++			.stream = 
++			{
++				.type = USB_BULK,
++				.count = RTD2831_URB_NUMBER,
++				.endpoint = 0x01,		//data pipe
++				.u = 
++				{
++					.bulk = 
++					{
++						.buffersize = RTD2831_URB_SIZE,
++					}
++				}
++			},
++		}
++	},
++	
++	.num_device_descs = 6,
++	.devices = {
++		{ .name = "RTL2832U DVB-T USB DEVICE",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[0], NULL },
++		},
++		{ .name = "DVB-T USB Dongle",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[1], NULL },
++		},
++		{ .name = "USB DVB-T Device",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[2], NULL },
++		},
++		{ .name = "DK DVBT DONGLE",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[3], NULL },
++		},
++		{ .name = "DK mini DVBT DONGLE",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[4], NULL },
++		},
++		{ .name = "DK 5217 DVBT DONGLE",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[5], NULL },
++		},		
++		{ NULL },
++	}
++};
++
++
++static struct dvb_usb_device_properties rtl2832u_2nd_properties = {
++
++	.num_adapters = 1,
++	.adapter = 
++	{
++		{
++			.streaming_ctrl = rtl2832u_streaming_ctrl,
++			.frontend_attach = rtl2832u_frontend_attach,
++			//parameter for the MPEG2-data transfer 
++			.stream = 
++			{
++				.type = USB_BULK,
++				.count = RTD2831_URB_NUMBER,
++				.endpoint = 0x01,		//data pipe
++				.u = 
++				{
++					.bulk = 
++					{
++						.buffersize = RTD2831_URB_SIZE,
++					}
++				}
++			},
++		}
++	},
++	
++	.num_device_descs = 6,
++	.devices = {
++		{ .name = "RTL2832U DVB-T USB DEVICE",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[6], NULL },
++		},
++		{ .name = "RTL2832U DVB-T USB DEVICE",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[7], NULL },
++		},
++		{ .name = "Digital TV Tuner Card",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[8], NULL },
++		},
++		{ .name = "DVB-T FTA USB Half Minicard",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[9], NULL },
++		},
++		{ .name = "DVB-T + GPS Minicard",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[10], NULL },
++		},
++		{ .name = "UB450-T",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[11], NULL },
++		},
++		{ NULL },
++	}
++};
++
++
++
++static struct dvb_usb_device_properties rtl2832u_3th_properties = {
++
++	.num_adapters = 1,
++	.adapter = 
++	{
++		{
++			.streaming_ctrl = rtl2832u_streaming_ctrl,
++			.frontend_attach = rtl2832u_frontend_attach,
++			//parameter for the MPEG2-data transfer 
++			.stream = 
++			{
++				.type = USB_BULK,
++				.count = RTD2831_URB_NUMBER,
++				.endpoint = 0x01,		//data pipe
++				.u = 
++				{
++					.bulk = 
++					{
++						.buffersize = RTD2831_URB_SIZE,
++					}
++				}
++			},
++		}
++	},
++	
++	.num_device_descs = 3,
++	.devices = {
++		{ .name = "USB DVB-T Device",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[12], NULL },
++		},
++		{ .name = "USB DVB-T Device",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[13], NULL },
++		},
++		{ .name = "RT DTV 2832U",
++		  .cold_ids = { NULL, NULL },
++		  .warm_ids = { &rtl2832u_usb_table[14], NULL },
++		},
++		{ NULL },
++	}
++};
++
++
++
++
++static struct usb_driver rtl2832u_usb_driver = {
++	.name		= "dvb_usb_rtl2832u",
++	.probe		= rtl2832u_usb_probe,
++	.disconnect	= rtl2832u_usb_disconnect,
++	.id_table		= rtl2832u_usb_table,
++};
++
++
++static int __init rtl2832u_usb_module_init(void)
++{
++	int result;
++	if ((result = usb_register(&rtl2832u_usb_driver))) {
++		err("usb_register failed. (%d)",result);
++		return result;
++	}
++
++	return 0;
++}
++
++static void __exit rtl2832u_usb_module_exit(void)
++{
++	usb_deregister(&rtl2832u_usb_driver);
++}
++
++
++
++module_init(rtl2832u_usb_module_init);
++module_exit(rtl2832u_usb_module_exit);
++
++
++
++MODULE_AUTHOR("Realtek");
++MODULE_DESCRIPTION("Driver for the RTL2832U DVB-T USB2.0 device");
++MODULE_VERSION("1.1");
++MODULE_LICENSE("GPL");
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/rtl2832u.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/rtl2832u.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,56 @@
++
++#ifndef _RTL2832U_H_
++#define _RTL2832U_H_
++
++
++
++#include "dvb-usb.h"
++
++#define	USB_VID_REALTEK					0x0BDA
++#define	USB_PID_RTD2832U_WARM			0x2832
++#define	USB_PID_RTD2832U_2ND_WARM		0x2838 
++
++
++#define	USB_VID_GOLDENBRIDGE				0x1680
++#define	USB_PID_GOLDENBRIDGE_WARM		0xA332
++
++#define	USB_VID_YUAN						0x1164
++#define	USB_PID_YUAN_WARM				0x6601
++
++#define	USB_VID_AZUREWAVE				0x13D3
++#define	USB_PID_AZUREWAVE_MINI_WARM	0x3234
++#define	USB_PID_AZUREWAVE_USB_WARM		0x3274
++#define	USB_PID_AZUREWAVE_GPS_WARM		0x3282
++
++#define	USB_VID_KWORLD_1ST					0x1B80
++#define	USB_PID_KWORLD_WARM_6				0xD396
++#define	USB_PID_KWORLD_WARM_3				0xD393
++#define	USB_PID_KWORLD_WARM_7				0xD397
++#define	USB_PID_KWORLD_WARM_8				0xD398
++
++
++#define	USB_VID_DEXATEK					0x1D19
++#define	USB_PID_DEXATEK_USB_WARM		0x1101
++#define	USB_PID_DEXATEK_MINIUSB_WARM	0x1102
++#define	USB_PID_DEXATEK_5217_WARM		0x1103
++
++
++#define	USB_VID_GTEK					0x1F4D
++#define	USB_PID_GTEK_WARM			0x0837
++
++
++
++
++
++
++#define RTD2831_URB_SIZE				4096
++#define RTD2831_URB_NUMBER				10
++
++
++
++extern struct dvb_frontend * rtl2832u_fe_attach(struct dvb_usb_device *d);
++
++#endif
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/rtl2832u_fe.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/rtl2832u_fe.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,1588 @@
++
++#include "rtl2832u_fe.h"
++#include "rtl2832u_io.h"
++#include "rtl2832u.h"
++
++
++#define UPDATE_PROCEDURE_PERIOD	500   //500ms
++
++
++
++
++static struct rtl2832_reg_addr rtl2832_reg_map[]= {
++	/* RTD2831_RMAP_INDEX_USB_CTRL_BIT5*/			{ RTD2832U_USB, USB_CTRL, 5, 5		},
++	/* RTD2831_RMAP_INDEX_USB_STAT*/				{ RTD2832U_USB, USB_STAT, 0, 7		},
++	/* RTD2831_RMAP_INDEX_USB_EPA_CTL*/			{ RTD2832U_USB, USB_EPA_CTL, 0, 31	},
++	/* RTD2831_RMAP_INDEX_USB_SYSCTL*/				{ RTD2832U_USB, USB_SYSCTL, 0, 31		},
++	/* RTD2831_RMAP_INDEX_USB_EPA_CFG*/			{ RTD2832U_USB, USB_EPA_CFG, 0, 31	},
++	/* RTD2831_RMAP_INDEX_USB_EPA_MAXPKT*/		{ RTD2832U_USB, USB_EPA_MAXPKT, 0, 31},
++	/* RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG*/		{ RTD2832U_USB, USB_EPA_FIFO_CFG, 0, 31},
++
++	/* RTD2831_RMAP_INDEX_SYS_DEMOD_CTL*/			{ RTD2832U_SYS, DEMOD_CTL, 0, 7	       },
++	/* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL*/	{ RTD2832U_SYS, GPIO_OUTPUT_VAL, 0, 7	},
++	/* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT3*/{ RTD2832U_SYS, GPIO_OUTPUT_EN, 3, 3	},
++	/* RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT3*/		{ RTD2832U_SYS, GPIO_DIR, 3, 3		},
++	/* RTD2831_RMAP_INDEX_SYS_GPIO_CFG0_BIT67*/	{ RTD2832U_SYS, GPIO_CFG0, 6, 7		},
++	/* RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1*/		{ RTD2832U_SYS, DEMOD_CTL1, 0, 7	       },	
++	/* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT1*/{ RTD2832U_SYS, GPIO_OUTPUT_EN, 1, 1	},
++	/* RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT1*/		{ RTD2832U_SYS, GPIO_DIR, 1, 1		},
++	/* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT6*/{ RTD2832U_SYS, GPIO_OUTPUT_EN, 6, 6	},	
++	/* RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT6*/		{ RTD2832U_SYS, GPIO_DIR, 6, 6		},
++
++	
++
++#if 0
++	/* RTD2831_RMAP_INDEX_SYS_GPD*/			{ RTD2832U_SYS, GPD, 0, 7		},
++	/* RTD2831_RMAP_INDEX_SYS_GPOE*/			{ RTD2832U_SYS, GPOE, 0, 7	},
++	/* RTD2831_RMAP_INDEX_SYS_GPO*/			{ RTD2832U_SYS, GPO, 0, 7		},
++	/* RTD2831_RMAP_INDEX_SYS_SYS_0*/			{ RTD2832U_SYS, SYS_0, 0, 7	},
++#endif
++   
++};                                          
++
++
++
++
++static void 	
++custom_wait_ms(
++	BASE_INTERFACE_MODULE*	pBaseInterface,
++	unsigned long				WaitTimeMs)
++{
++	platform_wait(WaitTimeMs);
++	return;	
++}
++
++
++static int
++custom_i2c_read(
++	BASE_INTERFACE_MODULE*	pBaseInterface,
++	unsigned char				DeviceAddr,
++	unsigned char*			pReadingBytes,
++	unsigned char				ByteNum
++	)
++{
++	struct dvb_usb_device *d;
++
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);
++	if ( read_rtl2832_stdi2c( d, DeviceAddr , pReadingBytes , ByteNum ) ) goto error;
++	
++	return 0;
++error:
++	return 1;
++}
++
++
++
++static int
++custom_i2c_write(
++	BASE_INTERFACE_MODULE*	pBaseInterface,
++	unsigned char				DeviceAddr,
++	const unsigned char*			pWritingBytes,
++	unsigned char				ByteNum)
++{
++	struct dvb_usb_device *d;
++
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);
++	if ( write_rtl2832_stdi2c( d, DeviceAddr , (unsigned char*)pWritingBytes , ByteNum ) ) goto error;
++	
++	return 0;
++error:
++	return 1;
++}
++
++
++
++static int
++read_usb_sys_register(
++	struct rtl2832_state*		p_state,
++	rtl2832_reg_map_index		reg_map_index,
++	int*						p_val)
++{
++	RegType			reg_type=	rtl2832_reg_map[reg_map_index].reg_type;
++	unsigned short	reg_addr=	rtl2832_reg_map[reg_map_index].reg_addr;
++	int				bit_low=	rtl2832_reg_map[reg_map_index].bit_low;
++	int				bit_high=	rtl2832_reg_map[reg_map_index].bit_high;
++
++	int	n_byte_read=(bit_high>> 3)+ 1;
++
++	*p_val= 0;
++	if (read_usb_sys_int_bytes(p_state->d, reg_type, reg_addr, n_byte_read, p_val)) goto error;
++
++	*p_val= ((*p_val>> bit_low) & rtl2832_reg_mask[bit_high- bit_low]);
++ 
++	return 0;
++
++error:
++	return 1;
++}
++
++
++
++
++static int
++write_usb_sys_register(
++	struct rtl2832_state*		p_state,
++	rtl2832_reg_map_index		reg_map_index,
++	int						val_write)
++{
++	RegType			reg_type=	rtl2832_reg_map[reg_map_index].reg_type;
++	unsigned short	reg_addr=	rtl2832_reg_map[reg_map_index].reg_addr;
++	int				bit_low=	rtl2832_reg_map[reg_map_index].bit_low;
++	int				bit_high=	rtl2832_reg_map[reg_map_index].bit_high;
++	
++	int	n_byte_write=	(bit_high>> 3)+ 1;
++	int	val_read= 0;
++	int	new_val_write;
++
++	if (read_usb_sys_int_bytes(p_state->d, reg_type, reg_addr, n_byte_write, &val_read)) goto error;
++
++	new_val_write= (val_read & (~(rtl2832_reg_mask[bit_high- bit_low]<< bit_low))) | (val_write<< bit_low);
++
++	if (write_usb_sys_int_bytes(p_state->d, reg_type, reg_addr, n_byte_write, new_val_write)) goto error;
++	return 0;
++	
++error:
++	return 1;
++}
++
++
++
++static int 
++set_tuner_power(
++	struct rtl2832_state*	p_state,
++	unsigned char			b_gpio4, 
++	unsigned char			onoff)
++{
++
++	int			data;
++
++	deb_info(" +%s \n", __FUNCTION__);
++	
++	if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error;		
++
++	if(b_gpio4)
++	{
++		if(onoff)		data &= ~(BIT4);   //set bit4 to 0
++		else			data |= BIT4;		//set bit4 to 1		
++
++	}
++	else
++	{
++		if(onoff)		data &= ~(BIT3);   //set bit3 to 0
++		else			data |= BIT3;		//set bit3 to 1		
++	}
++	
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error;
++
++	deb_info(" -%s \n", __FUNCTION__);
++
++	return 0;
++error:
++	return 1;
++}
++
++
++
++static int 
++set_demod_power(
++	struct rtl2832_state*	p_state,
++	unsigned char			onoff)
++{
++
++	int			data;
++
++	deb_info(" +%s \n", __FUNCTION__);
++	
++	if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error;		
++	if(onoff)		data &= ~(BIT0);   //set bit0 to 0
++	else			data |= BIT0;		//set bit0 to 1	
++	data &= ~(BIT0);   //3 Demod Power always ON => hw issue.	
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error;
++
++	deb_info(" -%s \n", __FUNCTION__);
++	return 0;
++error:
++	return 1;
++}
++
++
++
++//3//////// Set GPIO3 "OUT"  => Turn ON/OFF Tuner Power
++//3//////// Set GPIO3 "IN"      => Button  Wake UP (USB IF) , NO implement in rtl2832u linux driver
++
++static int 
++gpio3_out_setting(
++	struct rtl2832_state*	p_state)
++{
++	int			data;
++
++	deb_info(" +%s \n", __FUNCTION__);
++
++	// GPIO3_PAD Pull-HIGH, BIT76
++	data = 2;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_CFG0_BIT67,data) ) goto error;
++
++	// GPO_GPIO3 = 1, GPIO3 output value = 1 
++	if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error;		
++	data |= BIT3;		//set bit3 to 1
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error;
++
++	// GPD_GPIO3=0, GPIO3 output direction
++	data = 0;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT3,data) ) goto error;
++
++	// GPOE_GPIO3=1, GPIO3 output enable
++	data = 1;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT3,data) ) goto error;
++
++	//BTN_WAKEUP_DIS = 1
++	data = 1;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_CTRL_BIT5,data) ) goto error;
++
++	deb_info(" -%s \n", __FUNCTION__);
++
++	return 0;
++error:
++	return 1;
++}
++
++
++
++
++
++
++static int 
++usb_epa_fifo_reset(
++	struct rtl2832_state*	p_state)
++{
++
++	int					data;
++
++	deb_info(" +%s \n", __FUNCTION__);
++	
++	//3 reset epa fifo:
++	//3[9] Reset EPA FIFO
++	//3 [5] FIFO Flush,Write 1 to flush the oldest TS packet (a 188 bytes block)
++
++	data = 0x0210;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,data) ) goto error;
++
++	data = 0xffff;
++	if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,&data) ) goto error;
++
++	if( (data & 0xffff) != 0x0210)
++	{
++		deb_info("Write error RTD2831_RMAP_INDEX_USB_EPA_CTL = 0x%x\n",data);
++	 	goto error;	
++	}
++
++	data=0x0000;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,data) ) goto error;
++
++	data = 0xffff;
++	if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,&data) ) goto error;
++
++	if( ( data  & 0xffff) != 0x0000)
++	{
++		deb_info("Write error RTD2831_RMAP_INDEX_USB_EPA_CTL = 0x%x\n",data);
++	 	goto error;	
++	}
++
++	deb_info(" -%s \n", __FUNCTION__);
++
++	return 0;
++
++error:
++	return 1;
++
++}
++
++
++
++static int 
++usb_init_bulk_setting(
++	struct rtl2832_state*	p_state)
++{
++
++	int					data;
++	
++	deb_info(" +%s \n", __FUNCTION__);
++	
++	//3 1.FULL packer mode(for bulk)
++	//3 2.DMA enable.
++	if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_SYSCTL, &data) ) goto error;
++
++	data &=0xffffff00;
++	data |= 0x09;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_SYSCTL, data) ) goto error;
++
++	data=0;
++	if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_SYSCTL, &data) ) goto error;
++      
++	if((data&0xff)!=0x09)  
++	{
++		deb_info("Open bulk FULL packet mode error!!\n");
++	 	goto error;
++	}
++
++	//3check epa config,
++	//3[9-8]:00, 1 transaction per microframe
++	//3[7]:1, epa enable
++	//3[6-5]:10, bulk mode
++	//3[4]:1, device to host
++	//3[3:0]:0001, endpoint number
++	data = 0;
++	if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CFG, &data) ) goto error;                
++	if((data&0x0300)!=0x0000 || (data&0xff)!=0xd1)
++	{
++		deb_info("Open bulk EPA config error! data=0x%x \n" , data);
++	 	goto error;	
++	}
++
++	//3 EPA maxsize packet 
++	//3 512:highspeedbulk, 64:fullspeedbulk. 
++	//3 940:highspeediso,  940:fullspeediso.
++
++	//3 get info :HIGH_SPEED or FULL_SPEED
++	if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_STAT, &data) ) goto error;	
++	if(data&0x01)  
++	{
++		data = 0x00000200;
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, data) ) goto error;
++
++		data=0;
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, &data) ) goto error;
++	                      
++		if((data&0xffff)!=0x0200)
++		{
++			deb_info("Open bulk EPA max packet size error!\n");
++		 	goto error;
++		}
++
++		deb_info("HIGH SPEED\n");
++	}
++	else 
++    	{
++		data = 0x00000040;
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, data) ) goto error;
++
++		data=0;
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, &data) ) goto error;
++	                      
++		if((data&0xffff)!=0x0200)
++		{
++			deb_info("Open bulk EPA max packet size error!\n");
++		 	goto error;
++		}
++		
++		deb_info("FULL SPEED\n");
++	}	
++
++	deb_info(" -%s \n", __FUNCTION__);
++	
++	return 0;
++
++error:	
++	return 1;
++}
++
++
++static int 
++usb_init_setting(
++	struct rtl2832_state*	p_state)
++{
++
++	int					data;
++
++	deb_info(" +%s \n", __FUNCTION__);
++
++	if ( usb_init_bulk_setting(p_state) ) goto error;
++
++	//3 change fifo length of EPA 
++	data = 0x00000014;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG, data) ) goto error;
++	data = 0xcccccccc;
++	if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG, &data) ) goto error;
++	if( (data & 0xff) != 0x14)
++	{
++		deb_info("Write error RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG =0x%x\n",data);
++	 	goto error;
++	}
++
++	if ( usb_epa_fifo_reset(p_state) ) goto error;
++
++	deb_info(" -%s \n", __FUNCTION__);
++	
++	return 0;
++
++error: 
++	return 1;	
++}
++
++
++
++static int 
++suspend_latch_setting(
++	struct rtl2832_state*	p_state,
++	unsigned char			resume)
++{
++
++	int					data;
++	deb_info(" +%s \n", __FUNCTION__);
++
++	if (resume)
++	{
++		//3 Suspend_latch_en = 0  => Set BIT4 = 0 
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error;		
++		data &= (~BIT4);	//set bit4 to 0
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error;
++	}
++	else
++	{
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error;		
++		data |= BIT4;		//set bit4 to 1
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error;
++	}
++
++	deb_info(" -%s \n", __FUNCTION__);	
++
++	return 0;
++error:
++	return 1;
++
++}
++
++
++
++
++
++//3////// DEMOD_CTL1  => IR Setting , IR wakeup from suspend mode
++//3////// if resume =1, resume
++//3////// if resume = 0, suspend
++
++
++static int 
++demod_ctl1_setting(
++	struct rtl2832_state*	p_state,
++	unsigned char			resume)
++{
++
++	int					data;
++
++	deb_info(" +%s \n", __FUNCTION__);
++	
++	if(resume)
++	{
++		// IR_suspend	
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error;		
++		data &= (~BIT2);		//set bit2 to 0
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error;
++
++		//Clk_400k
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error;		
++		data &= (~BIT3);		//set bit3 to 0
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error;
++	}
++	else
++	{
++		//Clk_400k
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error;		
++		data |= BIT3;		//set bit3 to 1
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error;
++
++		// IR_suspend		
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error;		
++		data |= BIT2;		//set bit2 to 1
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error;
++	}
++
++	deb_info(" -%s \n", __FUNCTION__);
++	
++	return 0;
++error:
++	return 1;
++
++}
++
++
++
++
++static int 
++demod_ctl_setting(
++	struct rtl2832_state*	p_state,
++	unsigned char			resume)
++{
++
++	int					data;
++	unsigned char				tmp;
++
++	deb_info(" +%s \n", __FUNCTION__);
++		
++	if(resume)
++	{
++		// PLL setting
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error;		
++		data |= BIT7;		//set bit7 to 1
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error;
++
++		
++		//2 + Begin LOCK
++		// Demod  H/W Reset
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error;		
++		data &= (~BIT5);	//set bit5 to 0
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error;
++
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error;		
++		data |= BIT5;		//set bit5 to 1
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error;
++		
++		//3 reset page chache to 0 		
++		if ( read_rtl2832_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 0, 1, &tmp, 1 ) ) goto error;	
++		//2 -End LOCK
++
++		// delay 5ms
++		platform_wait(5);
++
++		// ADC_Q setting
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error;		
++		data |= BIT3;		//set bit3 to 1
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error;
++
++		// ADC_I setting
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error;		
++		data |= BIT6;		//set bit3 to 1
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error;
++	}
++	else
++	{
++
++		// ADC_I setting
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error;		
++		data &= (~BIT6);		//set bit3 to 0
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error;
++
++		// ADC_Q setting
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error;		
++		data &= (~BIT3);		//set bit3 to 0
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error;
++
++		// PLL setting
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error;		
++		data &= (~BIT7);		//set bit7 to 0
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error;
++
++	}
++
++	deb_info(" -%s \n", __FUNCTION__);
++
++	return 0;
++error: 
++	return 1;	
++
++}
++
++
++static int
++read_tuner_id_register(
++	struct rtl2832_state*	p_state,
++	unsigned char			tuner_addr,
++	unsigned char			tuner_offset,
++	unsigned char*		id_data,
++	unsigned char			length)
++{
++	unsigned char				i2c_repeater;	
++	struct dvb_usb_device*	d = p_state->d;
++
++	//2 + Begin LOCK
++	if(read_rtl2832_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error;
++	i2c_repeater |= BIT3;	
++	if(write_rtl2832_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error;
++	
++	if(read_rtl2832_tuner_register(d, tuner_addr, tuner_offset, id_data, length)) goto error;
++
++	if(read_rtl2832_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error;
++	i2c_repeater &= (~BIT3);	
++	if(write_rtl2832_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error;
++	//2 - End LOCK
++	return 0;
++	
++error:
++	return 1;
++}
++
++
++
++static int
++check_mxl5007t_chip_version(
++	struct rtl2832_state*	p_state,
++	unsigned char			*chipversion)
++{
++
++	unsigned char Buffer[LEN_2_BYTE];
++	unsigned char	i2c_repeater;	
++
++	struct dvb_usb_device*	d = p_state->d;	
++
++
++	Buffer[0] = (unsigned char)MXL5007T_I2C_READING_CONST;
++	Buffer[1] = (unsigned char)MXL5007T_CHECK_ADDRESS;
++
++
++	if(read_rtl2832_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error;
++	i2c_repeater |= BIT3;	
++	if(write_rtl2832_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error;
++
++
++	write_rtl2832_stdi2c(d, MXL5007T_BASE_ADDRESS , Buffer, LEN_2_BYTE);
++
++	read_rtl2832_stdi2c(d, MXL5007T_BASE_ADDRESS, Buffer, LEN_1_BYTE);
++
++	if(read_rtl2832_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error;
++	i2c_repeater &= (~BIT3);
++	if(write_rtl2832_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error;
++
++
++
++	switch(Buffer[0])
++	{
++		case MXL5007T_CHECK_VALUE: 
++			*chipversion = MxL_5007T_V4;
++			break;
++		default: 
++			*chipversion = MxL_UNKNOWN_ID;
++			break;
++	}	
++
++	return 0;
++
++error:
++
++	return 1;
++
++}
++
++
++
++
++
++
++static int 
++check_tuner_type(
++	struct rtl2832_state	*p_state)
++{
++	MT2266_EXTRA_MODULE	*p_mt2266_extra;
++	unsigned char				tuner_id_data[2];
++
++
++	if ((!read_tuner_id_register(p_state, MT2266_TUNER_ADDR, MT2266_OFFSET,  tuner_id_data, LEN_1_BYTE)) && 
++		( tuner_id_data[0] == MT2266_CHECK_VAL ))
++	{
++		 	p_state->tuner_type = RTL2832_TUNER_TYPE_MT2266;
++	}
++	else
++	{
++		if ((!read_tuner_id_register(p_state, FC2580_TUNER_ADDR, FC2580_OFFSET,  tuner_id_data, LEN_1_BYTE)) &&
++			((tuner_id_data[0]&(~BIT7)) == FC2580_CHECK_VAL ))
++		{
++			p_state->tuner_type = RTL2832_TUNER_TYPE_FC2580;
++		}
++		else
++		{
++			if ((!read_tuner_id_register(p_state, TUA9001_TUNER_ADDR, TUA9001_OFFSET,  tuner_id_data, LEN_2_BYTE)) &&
++				(((tuner_id_data[0]<<8)|tuner_id_data[1]) == TUA9001_CHECK_VAL ))
++			{
++				p_state->tuner_type = RTL2832_TUNER_TYPE_TUA9001;
++
++			}
++			else
++			{
++				unsigned char chip_version;
++				if ((!check_mxl5007t_chip_version(p_state, &chip_version)) &&
++					(chip_version == MXL5007T_CHECK_VALUE) )
++				{
++					p_state->tuner_type = RTL2832_TUNER_TYPE_MXL5007T;
++				}
++				else
++				{
++			
++					p_state->tuner_type = RTL2832_TUNER_TYPE_UNKNOWN;
++				}
++			}	
++		}
++
++	}
++
++
++	if( p_state->tuner_type == RTL2832_TUNER_TYPE_MT2266)
++	{
++		//3 Build RTL2832 MT2266 NIM module.
++		BuildRtl2832Mt2266Module(
++			&p_state->pNim,
++			&p_state->DvbtNimModuleMemory,
++			&p_state->Rtl2832Mt2266ExtraModuleMemory,
++
++			9,											// Maximum I2C reading byte number is 9.
++			8,											// Maximum I2C writing byte number is 8.
++			NULL,//custom_i2c_read,							// Employ CustomI2cRead() as basic I2C reading function.
++			NULL,//custom_i2c_write,							// Employ CustomI2cWrite() as basic I2C writing function.
++			custom_wait_ms,							// Employ CustomWaitMs() as basic waiting function.
++
++			&p_state->Rtl2832ExtraModuleMemory,			// Employ RTL2832 extra module for RTL2832 module.
++			RTL2832_DEMOD_ADDR,						// The RTL2832 I2C device address is 0x20 in 8-bit format.
++			CRYSTAL_FREQ_28800000HZ,					// The RTL2832 crystal frequency is 28.8 MHz.
++			RTL2832_APPLICATION_DONGLE,					// The RTL2832 application mode is STB mode.
++			TS_INTERFACE_PARALLEL,
++			200,											// The RTL2832 update function reference period is 200 millisecond
++			OFF,											// The RTL2832 Function 1 enabling status is on.
++
++			&p_state->Mt2266ExtraModuleMemory,			// Employ MT2266 extra module for MT2266 module.
++			MT2266_TUNER_ADDR							// The MT2266 I2C device address is 0xc0 in 8-bit format.
++			);
++
++		p_mt2266_extra = (MT2266_EXTRA_MODULE *)(p_state->pNim->pTuner->pExtra);
++
++		if(p_mt2266_extra->OpenHandle(p_state->pNim->pTuner))
++			deb_info("%s : MT2266 Open Handle Failed....\n", __FUNCTION__);
++		p_state->is_mt2266_nim_module_built = 1;
++
++		deb_info("%s : MT2266 tuner on board...\n", __FUNCTION__);
++	}
++	else if( p_state->tuner_type == RTL2832_TUNER_TYPE_FC2580)
++	{
++
++		//3Build RTL2832 FC2580 NIM module.
++		BuildRtl2832Fc2580Module(
++			&p_state->pNim,
++			&p_state->DvbtNimModuleMemory,
++
++			9,											// Maximum I2C reading byte number is 9.
++			8,											// Maximum I2C writing byte number is 8.
++			NULL,//custom_i2c_read,							// Employ CustomI2cRead() as basic I2C reading function.
++			NULL,//custom_i2c_write,							// Employ CustomI2cWrite() as basic I2C writing function.
++			custom_wait_ms,							// Employ CustomWaitMs() as basic waiting function.
++
++			&p_state->Rtl2832ExtraModuleMemory,			// Employ RTL2832 extra module for RTL2832 module.
++			RTL2832_DEMOD_ADDR,						// The RTL2832 I2C device address is 0x20 in 8-bit format.
++			CRYSTAL_FREQ_28800000HZ,					// The RTL2832 crystal frequency is 28.8 MHz.		
++			RTL2832_APPLICATION_DONGLE,					// The RTL2832 application mode is STB mode.
++			TS_INTERFACE_PARALLEL,
++			200,											// The RTL2832 update function reference period is 200 millisecond
++			OFF,											// The RTL2832 Function 1 enabling status is on.
++
++			&p_state->Fc2580ExtraModuleMemory,			// Employ FC2580 extra module for FC2580 module.
++			FC2580_TUNER_ADDR,							// The FC2580 I2C device address is 0xac in 8-bit format.
++			CRYSTAL_FREQ_16384000HZ,					// The FC2580 crystal frequency is 16.384 MHz.			
++			FC2580_AGC_INTERNAL						// The FC2580 AGC mode is external AGC mode.
++			);
++
++		deb_info("%s : FC2580 tuner on board...\n", __FUNCTION__);		
++	}
++	else if( p_state->tuner_type == RTL2832_TUNER_TYPE_TUA9001)
++	{
++
++		//3Build RTL2832 TUA9001 NIM module.
++		BuildRtl2832Tua9001Module(
++			&p_state->pNim,
++			&p_state->DvbtNimModuleMemory,
++
++			9,											// Maximum I2C reading byte number is 9.
++			8,											// Maximum I2C writing byte number is 8.
++			NULL,//custom_i2c_read,							// Employ CustomI2cRead() as basic I2C reading function.
++			NULL,//custom_i2c_write,							// Employ CustomI2cWrite() as basic I2C writing function.
++			custom_wait_ms,							// Employ CustomWaitMs() as basic waiting function.
++
++			&p_state->Rtl2832ExtraModuleMemory,			// Employ RTL2832 extra module for RTL2832 module.
++			RTL2832_DEMOD_ADDR,						// The RTL2832 I2C device address is 0x20 in 8-bit format.
++			CRYSTAL_FREQ_28800000HZ,					// The RTL2832 crystal frequency is 28.8 MHz.		
++			RTL2832_APPLICATION_DONGLE,					// The RTL2832 application mode is STB mode.
++			TS_INTERFACE_PARALLEL,
++			200,											// The RTL2832 update function reference period is 200 millisecond
++			OFF,											// The RTL2832 Function 1 enabling status is on.
++
++			&p_state->TUA9001ExtraModuleMemory,			// Employ TUA9001 extra module for FC2580 module.
++			TUA9001_TUNER_ADDR							// The TUA9001 I2C device address is 0xc0 in 8-bit format.
++			);
++		
++		deb_info("%s : TUA9001 tuner on board...\n", __FUNCTION__);		
++	}
++	else if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T)
++	{
++
++		//3Build RTL2832 MXL5007 NIM module.
++		BuildRtl2832Mxl5007tModule(
++			&p_state->pNim,
++			&p_state->DvbtNimModuleMemory,
++
++			9,											// Maximum I2C reading byte number is 9.
++			8,											// Maximum I2C writing byte number is 8.
++			custom_i2c_read,							// Employ CustomI2cRead() as basic I2C reading function.
++			custom_i2c_write,							// Employ CustomI2cWrite() as basic I2C writing function.
++			custom_wait_ms,							// Employ CustomWaitMs() as basic waiting function.
++
++			&p_state->Rtl2832ExtraModuleMemory,			// Employ RTL2832 extra module for RTL2832 module.
++			RTL2832_DEMOD_ADDR,						// The RTL2832 I2C device address is 0x20 in 8-bit format.
++			CRYSTAL_FREQ_28800000HZ,					// The RTL2832 crystal frequency is 28.8 MHz.		
++			RTL2832_APPLICATION_DONGLE,					// The RTL2832 application mode is STB mode.
++			TS_INTERFACE_PARALLEL,
++			200,											// The RTL2832 update function reference period is 200 millisecond
++			OFF,											// The RTL2832 Function 1 enabling status is on.
++
++			&p_state->MXL5007TExtraModuleMemory,			// Employ MxL5007T  extra module for MxL5007T  module.
++			MXL5007T_BASE_ADDRESS,										// The MxL5007T I2C device address is 0xc0 in 8-bit format.
++			CRYSTAL_FREQ_16000000HZ,					// The MxL5007T Crystal frequency is 16.0 MHz.
++			MXL5007T_CLK_OUT_DISABLE,					// The MxL5007T clock output mode is disabled.
++			MXL5007T_CLK_OUT_AMP_0						// The MxL5007T clock output amplitude is 0.
++			);
++		
++		deb_info("%s : MXL5007T tuner on board...\n", __FUNCTION__);		
++	}	
++	else
++	{
++		deb_info("%s : Unknown tuner on board...\n", __FUNCTION__);		
++		goto error;
++	}
++	
++	// Set user defined data pointer of base interface structure for custom basic functions.
++	p_state->pNim->pBaseInterface->SetUserDefinedDataPointer(p_state->pNim->pBaseInterface, p_state->d );
++
++
++	return 0;
++error:
++	return 1;
++}
++
++static int 
++gpio1_output_enable_direction(
++	struct rtl2832_state*	p_state)
++{
++	int data;
++	// GPD_GPIO1=0, GPIO1 output direction
++	data = 0;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT1,data) ) goto error;
++
++	// GPOE_GPIO1=1, GPIO1 output enable
++	data = 1;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT1,data) ) goto error;
++
++	return 0;
++error:
++	return 1;
++}
++
++
++static int 
++gpio6_output_enable_direction(
++	struct rtl2832_state*	p_state)
++{
++	int data;
++	// GPD_GPIO6=0, GPIO6 output direction
++	data = 0;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT6,data) ) goto error;
++
++	// GPOE_GPIO6=1, GPIO6 output enable
++	data = 1;
++	if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT6,data) ) goto error;
++
++	return 0;
++error:
++	return 1;
++}
++
++
++
++
++static int 
++check_reset_parameters(
++	struct rtl2832_state*	p_state,
++	unsigned long			frequency,
++	enum fe_bandwidth	bandwidth,	
++	int*					reset_needed)
++{
++
++	int							is_lock;	
++	unsigned int					diff_ms;
++
++	deb_info(" +%s \n", __FUNCTION__);
++
++	*reset_needed = 1;	 //3initialize "reset_needed"
++	
++	if( (p_state->current_frequency == frequency) && (p_state->current_bandwidth == bandwidth) )
++	{
++		if( p_state->pNim->IsSignalLocked(p_state->pNim, &is_lock) ) goto error;
++		diff_ms = 0;		
++		
++		while( !(is_lock == LOCKED || diff_ms > 200) )
++		{
++			platform_wait(40);
++			diff_ms += 40;
++			if( p_state->pNim->IsSignalLocked(p_state->pNim, &is_lock) ) goto error;
++		}
++
++	       if (is_lock==YES)		
++	       {
++		   *reset_needed = 0;		 //3 set "reset_needed" = 0
++		   deb_info("%s : The same frequency = %d setting\n", __FUNCTION__, (int)frequency);
++	       }
++	}	   
++
++	deb_info(" -%s \n", __FUNCTION__);
++
++	return 0;
++
++error:
++	
++	*reset_needed = 1; 	//3 set "reset_needed" = 1
++	return 1;
++}
++
++
++/*
++void
++rtl2832_update_functions(struct work_struct *work)
++{
++	struct rtl2832_state* p_state = container_of( work , struct rtl2832_state , update_procedure_work.work); 
++	unsigned  long ber_num, ber_dem;
++	long snr_num = 0;
++	long snr_dem = 0;
++	long _snr= 0;
++
++
++	if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) )	goto mutex_error;
++
++	deb_info("+%s\n", __FUNCTION__);	
++	
++	p_state->pNim->UpdateFunction(p_state->pNim);
++	p_state->pNim->GetBer( p_state->pNim , &ber_num , &ber_dem);
++	p_state->pNim->GetSnrDb(p_state->pNim, &snr_num, &snr_dem) ;
++
++	_snr = snr_num / snr_dem;
++	if( _snr < 0 ) _snr = 0;
++
++	deb_info("-%s : ber = %lu, snr = %lu\n", __FUNCTION__,ber_num,_snr);
++	
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++	
++	schedule_delayed_work(&p_state->update_procedure_work,UPDATE_PROCEDURE_PERIOD);
++	
++	return;
++
++mutex_error:
++	return;
++	
++}
++
++*/
++
++
++static int 
++rtl2832_init(
++	struct dvb_frontend*	fe)
++{
++	struct rtl2832_state*	p_state = fe->demodulator_priv;
++
++	if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) )	goto mutex_error;
++
++	deb_info(" +%s\n", __FUNCTION__);
++	
++	//usb_reset_device(p_state->d->udev);
++
++	if( usb_init_setting(p_state) ) goto error;
++	
++	if( gpio3_out_setting(p_state) ) goto error;				//3Set GPIO3 OUT	
++	
++	if( demod_ctl1_setting(p_state , 1) ) goto error;		//3	DEMOD_CTL1, resume = 1
++
++	if( set_demod_power(p_state , 1) ) goto error;		//3	turn ON demod power
++
++	if( suspend_latch_setting(p_state , 1) ) goto error;		//3 suspend_latch_en = 0, resume = 1 					
++
++	if( demod_ctl_setting(p_state , 1) ) goto error;		//3 	DEMOD_CTL, resume =1
++
++	//3 Auto detect Tuner Power Pin (GPIO3 or GPIO4)	
++	if( set_tuner_power(p_state , 0 , 1) ) goto error;		//3	turn ON tuner power, 1st try GPIO3
++
++	if( check_tuner_type(p_state) )
++	{
++		if(p_state->tuner_type == RTL2832_TUNER_TYPE_UNKNOWN)
++		{
++			if( set_tuner_power(p_state , 0 , 0) )	goto error;			//3recover GPIO3 setting at 1st try
++			if( set_tuner_power(p_state , 1 , 1) )	goto error;			//3 2nd try GPIO4
++			if( check_tuner_type(p_state) )		goto error;				
++			
++			p_state->pNim->pTuner->b_set_tuner_power_gpio4 = 1;	//4 Tuner Power Pin : GPIO4	
++		}
++		else
++		{
++			goto error;
++		}	
++	}
++	else
++	{
++		p_state->pNim->pTuner->b_set_tuner_power_gpio4 = 0;	//4 Tuner Power Pin : GPIO3	
++	}
++
++	
++	if( p_state->tuner_type == RTL2832_TUNER_TYPE_TUA9001)
++	{	
++		if( gpio1_output_enable_direction(p_state) )	goto error;	
++	}
++	else if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T)
++	{
++		//3 MXL5007T : Set GPIO6 OUTPUT_EN & OUTPUT_DIR & OUTPUT_VAL for YUAN
++		int	data;		
++		if( gpio6_output_enable_direction(p_state) )	goto error;	
++
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error;		
++		data |= BIT6;
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error;
++
++	}
++		
++	
++	//3 Nim initialize
++	if ( p_state->pNim->Initialize(p_state->pNim) ) goto error;
++
++	p_state->is_initial = 1;
++
++	deb_info(" -%s \n", __FUNCTION__);
++
++	mutex_unlock(&p_state->i2c_repeater_mutex);	
++
++	//schedule_delayed_work(&(p_state->update_procedure_work), 0);  //3 Initialize update function	
++	
++	return 0;
++
++error:
++	mutex_unlock(&p_state->i2c_repeater_mutex);	
++	
++mutex_error:
++	deb_info(" -%s  error end\n", __FUNCTION__);
++
++	return -1;
++}
++
++
++static void
++rtl2832_release(
++	struct dvb_frontend*	fe)
++{
++	struct rtl2832_state* p_state = fe->demodulator_priv;
++	MT2266_EXTRA_MODULE*	p_mt2266_extra;	
++
++	if( p_state->pNim== NULL)
++	{
++		deb_info(" %s pNim = NULL \n", __FUNCTION__);
++		return;
++	}
++
++	if( p_state->is_mt2266_nim_module_built)
++	{
++		p_mt2266_extra = (MT2266_EXTRA_MODULE *)(p_state->pNim->pTuner->pExtra);
++		p_mt2266_extra->CloseHandle(p_state->pNim->pTuner);
++		p_state->is_mt2266_nim_module_built = 0;
++	}
++	
++	if(p_state->is_initial)
++	{
++	//	cancel_rearming_delayed_work( &(p_state->update_procedure_work) );
++	//	flush_scheduled_work();		
++		p_state->is_initial = 0;
++	}
++
++	kfree(p_state);
++
++	deb_info("  %s \n", __FUNCTION__);	
++
++	return;
++}
++
++
++
++static int 
++rtl2832_sleep(
++	struct dvb_frontend*	fe)
++{
++	struct rtl2832_state* p_state = fe->demodulator_priv;
++	MT2266_EXTRA_MODULE*	p_mt2266_extra;
++	DVBT_DEMOD_MODULE	*pDemod;
++	DVBT_NIM_MODULE		*pNim;
++	int 			data;
++
++//	int			page_no, addr_no;
++//	unsigned char		reg_value;
++
++
++	pNim = p_state->pNim;
++	pDemod = pNim->pDemod;
++
++	if( pNim== NULL)
++	{
++		deb_info(" %s pNim = NULL \n", __FUNCTION__);
++		return -1;
++	}
++
++	if( p_state->is_mt2266_nim_module_built)
++	{
++		p_mt2266_extra = (MT2266_EXTRA_MODULE *)(p_state->pNim->pTuner->pExtra);
++		p_mt2266_extra->CloseHandle(p_state->pNim->pTuner);
++		p_state->is_mt2266_nim_module_built = 0;
++	}
++	
++	if( p_state->is_initial )
++	{
++
++	//	cancel_rearming_delayed_work( &(p_state->update_procedure_work) );
++	//	flush_scheduled_work();		
++		p_state->is_initial = 0;
++	}
++
++	if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) )	goto mutex_error;
++
++	deb_info(" +%s \n", __FUNCTION__);
++
++#if 0
++	//2 For debug
++	for( page_no = 0; page_no < 3; page_no++ )
++	{
++		pDemod->SetRegPage(pDemod, page_no);
++		for( addr_no = 0; addr_no < 256; addr_no++ )
++		{
++			pDemod->GetRegBytes(pDemod, addr_no, &reg_value, 1);
++			printk("0x%x, 0x%x, 0x%x\n", page_no, addr_no, reg_value);
++		}
++	}
++#endif
++
++	 if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T)
++	{
++		//3 MXL5007T : Set GPIO6 OUTPUT_VAL  OFF for YUAN
++		if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error;		
++		data &= (~BIT6);
++		if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error;
++
++	}
++
++
++	if( demod_ctl1_setting(p_state , 0) ) goto error;		//3	DEMOD_CTL1, resume = 0
++
++	if( set_tuner_power(p_state, p_state->pNim->pTuner->b_set_tuner_power_gpio4, 0) ) goto error;		//3	turn OFF tuner power
++
++	if( demod_ctl_setting(p_state , 0) ) goto error;		//3 	DEMOD_CTL, resume =0	
++	//2 for H/W reason
++	//if( suspend_latch_setting(p_state , 0) ) goto error;		//3 suspend_latch_en = 1, resume = 0					
++
++	//if( set_demod_power(p_state , 0) ) goto error;		//3	turn OFF demod power
++
++	deb_info(" -%s \n", __FUNCTION__);
++
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++
++	return 0;
++	
++error:
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++	
++mutex_error:	
++
++	return 1;
++}
++
++
++
++
++
++static int
++rtl2832_set_parameters(
++	struct dvb_frontend*	fe,
++	struct dvb_frontend_parameters*	param)
++{
++	struct rtl2832_state* p_state = fe->demodulator_priv;
++	struct dvb_ofdm_parameters*	p_ofdm_param= &param->u.ofdm;
++	unsigned long					frequency = param->frequency;
++	int							bandwidth_mode;
++	int							is_signal_present;
++	int							reset_needed;
++
++
++	if( p_state->pNim== NULL)
++	{
++		deb_info(" %s pNim = NULL \n", __FUNCTION__);
++		return -1;
++	}
++
++	if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) )	goto mutex_error;
++	
++	deb_info(" +%s frequency = %lu , bandwidth = %u\n", __FUNCTION__, frequency ,p_ofdm_param->bandwidth);
++	
++	if ( check_reset_parameters( p_state , frequency , p_ofdm_param->bandwidth, &reset_needed) ) goto error;
++	if( reset_needed == 0 )
++	{
++		mutex_unlock(&p_state->i2c_repeater_mutex);		
++		return 0;
++	}
++
++	
++	switch (p_ofdm_param->bandwidth) 
++	{
++		case BANDWIDTH_6_MHZ:
++		bandwidth_mode = DVBT_BANDWIDTH_6MHZ; 	
++		break;
++		
++		case BANDWIDTH_7_MHZ:
++		bandwidth_mode = DVBT_BANDWIDTH_7MHZ;
++		break;
++		
++		case BANDWIDTH_8_MHZ:
++		default:
++		bandwidth_mode = DVBT_BANDWIDTH_8MHZ;	
++		break;
++	}
++
++	if ( p_state->pNim->SetParameters( p_state->pNim,  frequency , bandwidth_mode ) ) goto error; 
++
++
++	if ( p_state->pNim->IsSignalPresent( p_state->pNim, &is_signal_present) ) goto error;
++
++	deb_info("  %s : ****** Signal Present = %d ******\n", __FUNCTION__, is_signal_present);	
++
++	p_state->current_frequency = frequency;	
++	p_state->current_bandwidth = p_ofdm_param->bandwidth;	
++
++	deb_info(" -%s \n", __FUNCTION__);
++
++	mutex_unlock(&p_state->i2c_repeater_mutex);	
++
++	return 0;
++
++error:	
++	mutex_unlock(&p_state->i2c_repeater_mutex);	
++	
++mutex_error:	
++	p_state->current_frequency = 0;
++	p_state->current_bandwidth = -1;	
++	deb_info(" -%s  error end\n", __FUNCTION__);
++
++	return -1;
++	
++}
++
++
++
++static int 
++rtl2832_get_parameters(
++	struct dvb_frontend*	fe,
++	struct dvb_frontend_parameters*	param)
++{
++	//struct rtl2832_state* p_state = fe->demodulator_priv;
++	return 0;
++}
++
++
++static int 
++rtl2832_read_status(
++	struct dvb_frontend*	fe,
++	fe_status_t*	status)
++{
++	struct rtl2832_state*	p_state = fe->demodulator_priv;
++	int	is_lock;			
++	unsigned  long ber_num, ber_dem;
++	long			snr_num, snr_dem, snr;
++
++
++	if( p_state->pNim== NULL)
++	{
++		deb_info(" %s pNim = NULL \n", __FUNCTION__);
++		return -1;
++	}
++
++	*status = 0;	//3initialize "status"
++	
++	if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) )	goto mutex_error;
++	
++	if( p_state->pNim->GetBer( p_state->pNim , &ber_num , &ber_dem) ) goto error;
++
++	if (p_state->pNim->GetSnrDb(p_state->pNim, &snr_num, &snr_dem) )  goto error;
++	
++	if( p_state->pNim->IsSignalLocked(p_state->pNim, &is_lock) ) goto error;
++	
++		
++	if( is_lock==YES ) *status|= (FE_HAS_CARRIER| FE_HAS_VITERBI| FE_HAS_LOCK| FE_HAS_SYNC| FE_HAS_SIGNAL);
++
++	 snr = snr_num/snr_dem;
++
++	deb_info("%s :******Signal Lock=%d******\n", __FUNCTION__, is_lock);
++	deb_info("%s : ber = 0x%x \n", __FUNCTION__, (unsigned int)ber_num);	
++	deb_info("%s : snr = 0x%x \n", __FUNCTION__, (int)snr);	
++
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++	
++	return 0;
++
++error:
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++	
++mutex_error:
++	return -1;
++}
++
++
++
++static int 
++rtl2832_read_ber(
++	struct dvb_frontend*	fe,
++	u32*	ber)
++{
++	struct rtl2832_state* p_state = fe->demodulator_priv;
++	unsigned  long ber_num, ber_dem;
++
++	if( p_state->pNim== NULL)
++	{
++		deb_info(" %s pNim = NULL \n", __FUNCTION__);
++		return -1;
++	}
++
++
++	if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) )	goto mutex_error;
++	
++	if( p_state->pNim->GetBer( p_state->pNim , &ber_num , &ber_dem) ) 
++	{
++		*ber = 19616;
++		goto error;
++	}
++	
++	*ber =  ber_num;
++
++	deb_info("  %s : ber = 0x%x \n", __FUNCTION__, *ber);	
++
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++		
++	return 0;
++	
++error:
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++	
++mutex_error:
++	return -1;
++}
++
++
++static int 
++rtl2832_read_signal_strength(
++	struct dvb_frontend*	fe,
++	u16*	strength)
++{
++	struct rtl2832_state* p_state = fe->demodulator_priv;
++	unsigned long		_strength;
++
++	if( p_state->pNim== NULL)
++	{
++		deb_info(" %s pNim = NULL \n", __FUNCTION__);
++		return -1;
++	}
++
++	if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) )	goto mutex_error;
++	
++	if( p_state->pNim->GetSignalStrength( p_state->pNim ,  &_strength) ) 
++	{
++		*strength = 0;
++		goto error;
++	}
++	
++	*strength = (_strength<<8) | _strength;
++
++	deb_info("  %s : strength = 0x%x \n", __FUNCTION__, *strength);		
++
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++	
++	return 0;
++	
++error:
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++	
++mutex_error:
++	return -1;
++}
++
++
++static int 
++rtl2832_read_signal_quality(
++	struct dvb_frontend*	fe,
++	u32*	quality)
++{
++	struct rtl2832_state* p_state = fe->demodulator_priv;
++	unsigned long		_quality;
++
++	if( p_state->pNim== NULL)
++	{
++		deb_info(" %s pNim = NULL \n", __FUNCTION__);
++		return -1;
++	}
++
++	if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) )	goto mutex_error;
++	
++	if ( p_state->pNim->GetSignalQuality( p_state->pNim ,  &_quality) )
++	{
++		*quality  = 0;		
++		goto error;
++	}
++
++	*quality = _quality;
++	
++	deb_info("  %s : quality = 0x%x \n", __FUNCTION__, *quality);	
++
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++	
++	return 0;
++	
++error:
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++	
++mutex_error:
++	return -1;	
++}
++
++
++
++static int 
++rtl2832_read_snr(
++	struct dvb_frontend*	fe,
++	u16*	snr)
++{
++	struct rtl2832_state* p_state = fe->demodulator_priv;
++	long snr_num = 0;
++	long snr_dem = 0;
++	long _snr= 0;
++
++	if( p_state->pNim== NULL)
++	{
++		deb_info(" %s pNim = NULL \n", __FUNCTION__);
++		return -1;
++	}
++
++	if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) )	goto mutex_error;
++
++	if (p_state->pNim->GetSnrDb(p_state->pNim, &snr_num, &snr_dem) ) 
++	{
++		*snr = 0;
++		goto error;
++	}
++
++	_snr = snr_num / snr_dem;
++
++	if( _snr < 0 ) _snr = 0;
++
++	*snr = _snr;
++
++	deb_info("  %s : snr = 0x%x \n", __FUNCTION__, *snr);	
++
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++	
++	return 0;
++	
++error:
++	mutex_unlock(&p_state->i2c_repeater_mutex);
++	
++mutex_error:
++	return -1;
++}
++
++
++
++static int 
++rtl2832_get_tune_settings(
++	struct dvb_frontend*	fe,
++	struct dvb_frontend_tune_settings*	fe_tune_settings)
++{
++	deb_info("  %s : Do Nothing\n", __FUNCTION__);	
++	fe_tune_settings->min_delay_ms = 1000;
++	return 0;
++}
++
++
++static int 
++rtl2832_ts_bus_ctrl(
++	struct dvb_frontend*	fe,
++	int	acquire)
++{
++	deb_info("  %s : Do Nothing\n", __FUNCTION__);	
++	return 0;
++}
++	
++
++
++
++static struct dvb_frontend_ops rtl2832_ops;
++
++struct dvb_frontend* rtl2832u_fe_attach(struct dvb_usb_device *d)
++{
++
++	struct rtl2832_state*       p_state= NULL;
++
++
++	deb_info("+%s\n", __FUNCTION__);
++	 
++	//3 linux fe_attach  necessary setting
++	/*allocate memory for the internal state */
++	p_state = kzalloc(sizeof(struct rtl2832_state), GFP_KERNEL);
++	if (p_state == NULL) goto error;
++	memset(p_state,0,sizeof(*p_state));
++
++	p_state->is_mt2266_nim_module_built = 0; //initialize is_mt2266_nim_module_built 
++	p_state->is_initial = 0;			//initialize is_initial 
++	
++	p_state->d = d;
++
++	/* setup the state */
++	memcpy(&p_state->frontend.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
++	memset(&p_state->fep, 0, sizeof(struct dvb_frontend_parameters));
++	
++ 	/* create dvb_frontend */
++	p_state->frontend.demodulator_priv = p_state;
++
++//	INIT_DELAYED_WORK( &(p_state->update_procedure_work), rtl2832_update_functions);
++	mutex_init(&p_state->i2c_repeater_mutex);
++	
++	deb_info("-%s\n", __FUNCTION__);
++	return &p_state->frontend;
++
++error:	
++	return NULL;	
++
++
++}
++
++
++
++static struct dvb_frontend_ops rtl2832_ops = {
++    .info = {
++        .name               = "Realtek RTL2832 DVB-T",
++        .type               = FE_OFDM,
++        .frequency_min      = 174000000,
++        .frequency_max      = 862000000,
++        .frequency_stepsize = 166667,
++        .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
++            FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
++            FE_CAN_FEC_AUTO |
++            FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
++            FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
++            FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
++            FE_CAN_MUTE_TS
++    },
++
++    .init =					rtl2832_init,
++    .release =				rtl2832_release,
++
++    .sleep =				rtl2832_sleep,
++
++    .set_frontend =			rtl2832_set_parameters,
++    .get_frontend =			rtl2832_get_parameters,
++    .get_tune_settings =		rtl2832_get_tune_settings,
++
++    .read_status =			rtl2832_read_status,
++    .read_ber =			rtl2832_read_ber,
++    .read_signal_strength =	rtl2832_read_signal_strength,
++    .read_snr =			rtl2832_read_snr,
++    .read_ucblocks =		rtl2832_read_signal_quality,
++    .ts_bus_ctrl   =			rtl2832_ts_bus_ctrl, 
++};
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/rtl2832u_fe.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/rtl2832u_fe.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,207 @@
++
++#ifndef __RTL2832U_FE_H__
++#define __RTL2832U_FE_H__
++
++#include "nim_rtl2832_tua9001.h"
++#include "nim_rtl2832_mt2266.h"
++#include "nim_rtl2832_fc2580.h"
++#include "nim_rtl2832_mxl5007t.h"
++#include "rtl2832u_io.h"
++
++
++
++typedef enum{
++	RTL2832_TUNER_TYPE_MT2266 = 0,		
++	RTL2832_TUNER_TYPE_FC2580,	
++	RTL2832_TUNER_TYPE_TUA9001,	
++	RTL2832_TUNER_TYPE_MXL5007T,		
++	RTL2832_TUNER_TYPE_UNKNOWN,	
++}RTL2832_TUNER_TYPE;
++
++
++
++struct rtl2832_state {
++	struct dvb_frontend			frontend;
++	struct dvb_frontend_parameters	fep;	
++	struct dvb_usb_device*		d;
++
++	struct mutex					i2c_repeater_mutex;
++
++       unsigned long					current_frequency;	
++	enum fe_bandwidth			current_bandwidth;		
++	   
++	RTL2832_TUNER_TYPE			tuner_type;
++	unsigned char					is_mt2266_nim_module_built;  //3 For close MT handle
++
++	//3if init() is called, is_initial is true ->check it to see if need to flush work queue 
++	unsigned short				is_initial;		
++	//struct delayed_work			update_procedure_work;	
++
++	DVBT_NIM_MODULE*			pNim;
++	DVBT_NIM_MODULE			DvbtNimModuleMemory;
++	RTL2832_EXTRA_MODULE		Rtl2832ExtraModuleMemory;
++	MT2266_EXTRA_MODULE		Mt2266ExtraModuleMemory;	
++	FC2580_EXTRA_MODULE		Fc2580ExtraModuleMemory;
++	TUA9001_EXTRA_MODULE		TUA9001ExtraModuleMemory;
++	MXL5007T_EXTRA_MODULE		MXL5007TExtraModuleMemory;
++	RTL2832_MT2266_EXTRA_MODULE	Rtl2832Mt2266ExtraModuleMemory;
++
++
++};
++
++
++
++#define RTL2832_DEMOD_ADDR	0x20
++#define MT2266_TUNER_ADDR		0xc0
++#define FC2580_TUNER_ADDR		0xac
++#define TUA9001_TUNER_ADDR	0xc0
++
++#define MT2266_OFFSET			0x00
++#define MT2266_CHECK_VAL		0x85
++
++#define FC2580_OFFSET			0x01
++#define FC2580_CHECK_VAL		0x56
++
++#define TUA9001_OFFSET			0x7e
++#define TUA9001_CHECK_VAL		0x2328
++
++#define MXL5007T_BASE_ADDRESS	0xc0
++#define MXL5007T_CHECK_ADDRESS	0xD9
++#define MXL5007T_CHECK_VALUE	0x14
++
++
++
++
++
++struct rtl2832_reg_addr{
++	RegType			reg_type;
++	unsigned short	reg_addr;
++	int				bit_low;
++	int				bit_high;
++};
++
++
++
++typedef enum{
++	RTD2831_RMAP_INDEX_USB_CTRL_BIT5 =0,
++	RTD2831_RMAP_INDEX_USB_STAT,		
++	RTD2831_RMAP_INDEX_USB_EPA_CTL,
++	RTD2831_RMAP_INDEX_USB_SYSCTL,
++	RTD2831_RMAP_INDEX_USB_EPA_CFG,
++	RTD2831_RMAP_INDEX_USB_EPA_MAXPKT,
++	RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG,	
++
++	RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,
++	RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,		
++	RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT3,		
++	RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT3,			
++	RTD2831_RMAP_INDEX_SYS_GPIO_CFG0_BIT67,
++	RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,
++	RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT1,		
++	RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT1,	
++	RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT6,		
++	RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT6,	
++#if 0	
++    RTD2831_RMAP_INDEX_SYS_GPD,
++    RTD2831_RMAP_INDEX_SYS_GPOE,
++    RTD2831_RMAP_INDEX_SYS_GPO,
++    RTD2831_RMAP_INDEX_SYS_SYS_0,    
++#endif 
++
++} rtl2832_reg_map_index;
++
++
++
++#define USB_SYSCTL				0x0000 	
++#define USB_CTRL				0x0010
++#define USB_STAT				0x0014	
++#define USB_EPA_CTL				0x0148  	
++#define USB_EPA_CFG				0x0144
++#define USB_EPA_MAXPKT			0x0158  
++#define USB_EPA_FIFO_CFG		0x0160 
++
++#define DEMOD_CTL				0x0000	
++#define GPIO_OUTPUT_VAL		0x0001
++#define GPIO_OUTPUT_EN			0x0003
++#define GPIO_DIR					0x0004
++#define GPIO_CFG0				0x0007
++#define GPIO_CFG1				0x0008	
++#define DEMOD_CTL1				0x000b
++
++
++static int rtl2832_reg_mask[32]= {
++    0x00000001,
++    0x00000003,
++    0x00000007,
++    0x0000000f,
++    0x0000001f,
++    0x0000003f,
++    0x0000007f,
++    0x000000ff,
++    0x000001ff,
++    0x000003ff,
++    0x000007ff,
++    0x00000fff,
++    0x00001fff,
++    0x00003fff,
++    0x00007fff,
++    0x0000ffff,
++    0x0001ffff,
++    0x0003ffff,
++    0x0007ffff,
++    0x000fffff,
++    0x001fffff,
++    0x003fffff,
++    0x007fffff,
++    0x00ffffff,
++    0x01ffffff,
++    0x03ffffff,
++    0x07ffffff,
++    0x0fffffff,
++    0x1fffffff,
++    0x3fffffff,
++    0x7fffffff,
++    0xffffffff
++};
++
++
++
++
++#define BIT0		0x00000001
++#define BIT1		0x00000002
++#define BIT2		0x00000004
++#define BIT3		0x00000008
++#define BIT4		0x00000010
++#define BIT5		0x00000020
++#define BIT6		0x00000040
++#define BIT7		0x00000080
++#define BIT8		0x00000100
++#define BIT9		0x00000200
++#define BIT10	0x00000400
++#define BIT11	0x00000800
++#define BIT12	0x00001000
++#define BIT13	0x00002000
++#define BIT14	0x00004000
++#define BIT15	0x00008000
++#define BIT16	0x00010000
++#define BIT17	0x00020000
++#define BIT18	0x00040000
++#define BIT19	0x00080000
++#define BIT20	0x00100000
++#define BIT21	0x00200000
++#define BIT22	0x00400000
++#define BIT23	0x00800000
++#define BIT24	0x01000000
++#define BIT25	0x02000000
++#define BIT26	0x04000000
++#define BIT27	0x08000000
++#define BIT28	0x10000000
++#define BIT29	0x20000000
++#define BIT30	0x40000000
++#define BIT31	0x80000000
++
++
++
++#endif // __RTD2830_PRIV_H__
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/rtl2832u_io.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/rtl2832u_io.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,635 @@
++
++
++#include "rtl2832u_io.h"
++#include <linux/time.h>
++
++#define ERROR_TRY_MAX_NUM		4
++
++
++
++void
++platform_wait(
++	unsigned long nMinDelayTime)
++{
++	// The unit of Sleep() waiting time is millisecond.
++	unsigned long usec;
++	do {
++		usec = (nMinDelayTime > 8000) ? 8000 : nMinDelayTime;
++		msleep(usec);
++		nMinDelayTime -= usec;
++		} while (nMinDelayTime > 0);
++
++	return;
++	
++}
++
++
++
++
++
++static int 
++read_usb_register(
++	struct dvb_usb_device*	dib,
++	unsigned short	offset,
++	unsigned char*	data,
++	unsigned short	bytelength)
++{
++	int ret = -ENOMEM;
++ 
++        ret = usb_control_msg(dib->udev,								/* pointer to device */
++                usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT),			/* pipe to control endpoint */
++                0,														/* USB message request value */
++                SKEL_VENDOR_IN,										/* USB message request type value */
++                (USB_BASE_ADDRESS<<8) + offset,						/* USB message value */
++                0x0100,													/* USB message index value */
++                data,													/* pointer to the receive buffer */
++                bytelength,												/* length of the buffer */
++                DIBUSB_I2C_TIMEOUT);									/* time to wait for the message to complete before timing out */
++ 	
++        if (ret != bytelength)
++	{
++		deb_info(" %s: offset=0x%x, error code=0x%x !\n", __FUNCTION__, offset, ret);
++		return 1;
++       }
++
++	return 0; 
++}
++
++
++
++static int 
++write_usb_register(
++	struct dvb_usb_device*	dib,
++	unsigned short	offset,
++	unsigned char*	data,
++	unsigned short	bytelength)
++{
++	int ret = -ENOMEM;
++	unsigned char try_num;
++
++	try_num = 0;	
++error_write_again:
++	try_num++;	
++ 
++        ret = usb_control_msg(dib->udev,								/* pointer to device */
++                usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT),		/* pipe to control endpoint */
++                0,														/* USB message request value */
++                SKEL_VENDOR_OUT,										/* USB message request type value */
++                (USB_BASE_ADDRESS<<8) + offset,						/* USB message value */
++                0x0110,													/* USB message index value */
++                data,													/* pointer to the receive buffer */
++                bytelength,												/* length of the buffer */
++                DIBUSB_I2C_TIMEOUT);									/* time to wait for the message to complete before timing out */
++
++        if (ret != bytelength)
++	{
++		deb_info("error try = %d, %s: offset=0x%x, error code=0x%x !\n",try_num ,__FUNCTION__, offset, ret);
++
++		if( try_num > ERROR_TRY_MAX_NUM )	goto error;
++		else				goto error_write_again;
++       }
++
++	return 0;
++error:
++	return 1;
++ }
++
++
++
++
++static int 
++read_sys_register(
++	struct dvb_usb_device*	dib,
++	unsigned short	offset,
++	unsigned char*	data,
++	unsigned short	bytelength)
++{
++	int ret = -ENOMEM;
++ 
++        ret = usb_control_msg(dib->udev,								/* pointer to device */
++                usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT),		/* pipe to control endpoint */
++                0,														/* USB message request value */
++                SKEL_VENDOR_IN,										/* USB message request type value */
++                (SYS_BASE_ADDRESS<<8) + offset,						/* USB message value */
++                0x0200,													/* USB message index value */
++                data,													/* pointer to the receive buffer */
++                bytelength,												/* length of the buffer */
++                DIBUSB_I2C_TIMEOUT);									/* time to wait for the message to complete before timing out */
++			
++        if (ret != bytelength)
++	{
++		deb_info(" %s: offset=0x%x, error code=0x%x !\n", __FUNCTION__, offset, ret);
++		return 1;
++       }
++
++	return 0; 
++
++  }
++
++
++static int 
++write_sys_register(
++	struct dvb_usb_device*	dib,
++	unsigned short	offset,
++	unsigned char*	data,
++	unsigned short	bytelength)
++{ 
++	int ret = -ENOMEM;
++	unsigned char try_num;
++
++	try_num = 0;	
++error_write_again:	
++	try_num++;	
++
++        ret = usb_control_msg(dib->udev,								/* pointer to device */
++                usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT),		/* pipe to control endpoint */
++                0,														/* USB message request value */
++                SKEL_VENDOR_OUT,										/* USB message request type value */
++                (SYS_BASE_ADDRESS<<8) + offset,						/* USB message value */
++                0x0210,													/* USB message index value */
++                data,													/* pointer to the receive buffer */
++                bytelength,												/* length of the buffer */
++                DIBUSB_I2C_TIMEOUT);									/* time to wait for the message to complete before timing out */
++		
++        if (ret != bytelength)
++	{
++		deb_info(" error try= %d, %s: offset=0x%x, error code=0x%x !\n",try_num, __FUNCTION__, offset, ret);
++		if( try_num > ERROR_TRY_MAX_NUM )	goto error;
++		else				goto error_write_again;	
++        }
++
++	return 0;
++error:
++	return 1;
++ }
++
++
++
++
++int 
++read_rtl2832_demod_register(
++	struct dvb_usb_device*dib,
++	unsigned char			demod_device_addr,	
++	unsigned char 		page,
++	unsigned char 		offset,
++	unsigned char*		data,
++	unsigned short		bytelength)
++{
++	int ret = -ENOMEM;
++	int i;
++
++	if( mutex_lock_interruptible(&dib->usb_mutex) )	goto error;
++
++        ret = usb_control_msg(dib->udev,								/* pointer to device */
++                usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT),			/* pipe to control endpoint */
++                0,														/* USB message request value */
++                SKEL_VENDOR_IN,										/* USB message request type value */
++                demod_device_addr + (offset<<8),						/* USB message value */
++                (0x0000 + page),										/* USB message index value */
++                data,													/* pointer to the receive buffer */
++                bytelength,												/* length of the buffer */
++                DIBUSB_I2C_TIMEOUT);									/* time to wait for the message to complete before timing out */
++
++	mutex_unlock(&dib->usb_mutex);
++
++	
++//		deb_info("%s: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(", __FUNCTION__, ret, demod_device_addr, bytelength,page, offset);
++//		for(i = 0; i < bytelength; i++)
++//			deb_info("0x%x,", data[i]);
++//		deb_info(")\n");
++			
++        if (ret != bytelength)
++	{
++		deb_info("error!! %s: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(", __FUNCTION__, ret, demod_device_addr, bytelength,page, offset);
++		for(i = 0; i < bytelength; i++)
++			deb_info("0x%x,", data[i]);
++		deb_info(")\n");
++		
++		goto error;
++       }
++
++	return 0;  
++
++error:
++	return 1;
++}
++
++
++
++
++int
++write_rtl2832_demod_register(
++	struct dvb_usb_device*dib,
++	unsigned char			demod_device_addr,		
++	unsigned char			page,
++	unsigned char			offset,
++	unsigned char			*data,
++	unsigned short		bytelength)
++{
++	int ret = -ENOMEM;
++	unsigned char  i, try_num;
++
++	try_num = 0;	
++error_write_again:	
++	try_num++;
++
++	if( mutex_lock_interruptible(&dib->usb_mutex) )	goto error;
++	
++        ret = usb_control_msg(dib->udev,								/* pointer to device */
++                usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT),		/* pipe to control endpoint */
++                0,														/* USB message request value */
++                SKEL_VENDOR_OUT,										/* USB message request type value */
++                demod_device_addr + (offset<<8),						/* USB message value */
++                (0x0010 + page),										/* USB message index value */
++                data,													/* pointer to the receive buffer */
++                bytelength,												/* length of the buffer */
++                DIBUSB_I2C_TIMEOUT);									/* time to wait for the message to complete before timing out */
++
++	mutex_unlock(&dib->usb_mutex);
++
++//		deb_info("%s: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(", __FUNCTION__, ret, demod_device_addr, bytelength, page,offset);
++//		for(i = 0; i < bytelength; i++)
++//			deb_info("0x%x,", data[i]);
++//		deb_info(")\n");
++
++
++        if (ret != bytelength)
++	{
++		deb_info("error try = %d!! %s: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(",try_num , __FUNCTION__, ret, demod_device_addr, bytelength,page,offset);
++		for(i = 0; i < bytelength; i++)
++			deb_info("0x%x,", data[i]);
++		deb_info(")\n");
++	
++		if( try_num > ERROR_TRY_MAX_NUM )	goto error;
++		else				goto error_write_again;
++        }
++
++	return 0;
++
++error:
++	return 1;
++ }
++
++
++
++
++
++
++int 
++read_rtl2832_tuner_register(
++	struct dvb_usb_device	*dib,
++	unsigned char			device_address,
++	unsigned char			offset,
++	unsigned char			*data,
++	unsigned short		bytelength)
++{
++	int ret = -ENOMEM;
++ 	int i;
++	unsigned char data_tmp[128];	
++
++
++	if( mutex_lock_interruptible(&dib->usb_mutex) )	goto error;
++	
++        ret = usb_control_msg(dib->udev,								/* pointer to device */
++                usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT),			/* pipe to control endpoint */
++                0,														/* USB message request value */
++                SKEL_VENDOR_IN,										/* USB message request type value */
++                device_address+(offset<<8),							/* USB message value */
++                0x0300,													/* USB message index value */
++                data_tmp,												/* pointer to the receive buffer */
++                bytelength,												/* length of the buffer */
++                DIBUSB_I2C_TIMEOUT);									/* time to wait for the message to complete before timing out */
++
++	mutex_unlock(&dib->usb_mutex);
++
++//		deb_info("%s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(", __FUNCTION__, ret, device_address, bytelength,offset);
++//		for(i = 0; i < bytelength; i++)
++//			deb_info("0x%x,", data_tmp[i]);
++//		deb_info(")\n");
++			
++        if (ret != bytelength)
++ 	{
++		deb_info("error!! %s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(", __FUNCTION__, ret, device_address, bytelength,offset);
++		for(i = 0; i < bytelength; i++)
++			deb_info("0x%x,", data_tmp[i]);
++		deb_info(")\n");
++		
++		goto error;
++        }
++
++	memcpy(data,data_tmp,bytelength);
++
++	return 0;
++	
++error:
++	return 1;   
++	
++ 
++}
++
++int write_rtl2832_tuner_register(
++	struct dvb_usb_device *dib,
++	unsigned char			device_address,
++	unsigned char			offset,
++	unsigned char			*data,
++	unsigned short		bytelength)
++{
++	int ret = -ENOMEM;
++	unsigned char  i, try_num;
++
++	try_num = 0;	
++error_write_again:	
++	try_num++;
++
++	if( mutex_lock_interruptible(&dib->usb_mutex) )	goto error;
++ 
++        ret = usb_control_msg(dib->udev,								/* pointer to device */
++                usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT),		/* pipe to control endpoint */
++                0,														/* USB message request value */
++                SKEL_VENDOR_OUT,										/* USB message request type value */
++                device_address+(offset<<8),							/* USB message value */
++                0x0310,													/* USB message index value */
++                data,													/* pointer to the receive buffer */
++                bytelength,												/* length of the buffer */
++                DIBUSB_I2C_TIMEOUT);									/* time to wait for the message to complete before timing out */
++
++	mutex_unlock(&dib->usb_mutex);
++
++//		deb_info("%s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(", __FUNCTION__, ret, device_address, bytelength, offset);
++//		for(i = 0; i < bytelength; i++)
++//			deb_info("0x%x,", data[i]);
++//		deb_info(")\n");
++
++			
++        if (ret != bytelength)
++	{
++		deb_info("error try= %d!! %s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(",try_num, __FUNCTION__, ret, device_address, bytelength, offset);
++		for(i = 0; i < bytelength; i++)
++			deb_info("0x%x,", data[i]);
++		deb_info(")\n");
++		
++		if( try_num > ERROR_TRY_MAX_NUM )	goto error;
++		else				goto error_write_again;
++       }
++
++	return 0;
++
++error:
++	return 1;
++ }
++
++
++
++
++int
++read_rtl2832_stdi2c(
++	struct dvb_usb_device*	dib,
++	unsigned short			dev_i2c_addr,
++	unsigned char*			data,
++	unsigned short			bytelength)
++{
++	int i;
++	int ret = -ENOMEM;
++	unsigned char  try_num;
++	unsigned char data_tmp[128];	
++
++	try_num = 0;	
++error_write_again:		
++	try_num ++;	
++        
++
++	if(bytelength >= 128)
++	{
++		deb_info("%s error bytelength >=128  \n", __FUNCTION__);
++		goto error;
++	}
++
++	if( mutex_lock_interruptible(&dib->usb_mutex) )	goto error;
++	
++	ret = usb_control_msg(dib->udev,								/* pointer to device */
++		usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT),			/* pipe to control endpoint */
++		0,														/* USB message request value */
++		SKEL_VENDOR_IN,											/* USB message request type value */
++		dev_i2c_addr,											/* USB message value */
++		0x0600,													/* USB message index value */
++		data_tmp,												/* pointer to the receive buffer */
++		bytelength,												/* length of the buffer */
++		DIBUSB_I2C_TIMEOUT);									/* time to wait for the message to complete before timing out */
++
++	mutex_unlock(&dib->usb_mutex);
++ 
++	if (ret != bytelength)
++	{
++		deb_info("error try= %d!! %s: ret=%d, DA=0x%x, len=%d, data=(",try_num, __FUNCTION__, ret, dev_i2c_addr, bytelength);
++		for(i = 0; i < bytelength; i++)
++			deb_info("0x%x,", data_tmp[i]);
++		deb_info(")\n");
++		
++		if( try_num > ERROR_TRY_MAX_NUM )	goto error;
++		else				goto error_write_again;
++	}
++
++ 	memcpy(data,data_tmp,bytelength);
++
++	return 0;  
++error: 
++	return 1;
++
++}
++
++
++
++int 
++write_rtl2832_stdi2c(
++	struct dvb_usb_device*	dib,
++	unsigned short			dev_i2c_addr,
++	unsigned char*			data,
++	unsigned short			bytelength)
++{
++	int i;
++	int ret = -ENOMEM;  
++	unsigned char  try_num;
++
++	try_num = 0;	
++error_write_again:		
++	try_num ++;	
++
++	if( mutex_lock_interruptible(&dib->usb_mutex) )	goto error;
++
++	ret = usb_control_msg(dib->udev,								/* pointer to device */
++		usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT),			/* pipe to control endpoint */
++		0,														/* USB message request value */
++		SKEL_VENDOR_OUT,										/* USB message request type value */
++		dev_i2c_addr,											/* USB message value */
++		0x0610,													/* USB message index value */
++		data,													/* pointer to the receive buffer */
++		bytelength,												/* length of the buffer */
++		DIBUSB_I2C_TIMEOUT);									/* time to wait for the message to complete before timing out */
++
++	mutex_unlock(&dib->usb_mutex);
++ 
++	if (ret != bytelength)
++	{
++		deb_info("error try= %d!! %s: ret=%d, DA=0x%x, len=%d, data=(",try_num, __FUNCTION__, ret, dev_i2c_addr, bytelength);
++		for(i = 0; i < bytelength; i++)
++			deb_info("0x%x,", data[i]);
++		deb_info(")\n");
++		
++		if( try_num > ERROR_TRY_MAX_NUM )	goto error;
++		else				goto error_write_again;		
++
++	}
++ 
++	return 0;
++	
++error:
++	return 1;  
++	
++}
++
++
++
++
++
++
++//3for return PUCHAR value
++
++int
++read_usb_sys_char_bytes(
++	struct dvb_usb_device*	dib,
++	RegType	type,
++	unsigned short	byte_addr,
++	unsigned char*	buf,
++	unsigned short	byte_num)
++{
++	int ret = 1;
++
++	if( byte_num != 1 && byte_num !=2 && byte_num !=4)
++	{
++		deb_info("error!! %s: length = %d \n", __FUNCTION__, byte_num);
++		return 1;
++	}
++
++
++	if( mutex_lock_interruptible(&dib->usb_mutex) )	return 1;
++		
++	if( type == RTD2832U_USB )
++	{
++		ret = read_usb_register( dib , byte_addr , buf , byte_num);
++	}
++	else if ( type == RTD2832U_SYS )
++	{
++		ret = read_sys_register( dib , byte_addr , buf , byte_num);
++	}
++	
++	mutex_unlock(&dib->usb_mutex);
++
++	return ret;
++	
++}
++
++
++
++int
++write_usb_sys_char_bytes(
++	struct dvb_usb_device*	dib,
++	RegType	type,
++	unsigned short	byte_addr,
++	unsigned char*	buf,
++	unsigned short	byte_num)
++{
++	int ret = 1;
++
++	if( byte_num != 1 && byte_num !=2 && byte_num !=4)
++	{
++		deb_info("error!! %s: length = %d \n", __FUNCTION__, byte_num);
++		return 1;
++	}
++
++	if( mutex_lock_interruptible(&dib->usb_mutex) )	return 1;	
++	
++	if( type == RTD2832U_USB )
++	{
++		ret = write_usb_register( dib , byte_addr , buf , byte_num);
++	}
++	else if ( type == RTD2832U_SYS )
++	{
++		ret = write_sys_register( dib , byte_addr , buf , byte_num);
++	}
++	
++	mutex_unlock(&dib->usb_mutex);	
++	
++	return ret;
++	
++}
++
++
++//3for return INT value
++int
++read_usb_sys_int_bytes(
++	struct dvb_usb_device*	dib,
++	RegType	type,
++	unsigned short	byte_addr,
++	unsigned short	n_bytes,
++	int*	p_val)
++{
++	int	i;
++	u8	val[LEN_4_BYTE];
++	int	nbit_shift; 
++
++	*p_val= 0;
++
++	if (read_usb_sys_char_bytes( dib, type, byte_addr, val , n_bytes)) goto error;
++
++	for (i= 0; i< n_bytes; i++)
++	{				
++		nbit_shift = i<<3 ;
++		*p_val = *p_val + (val[i]<<nbit_shift );
++       }
++
++	return 0;
++error:
++	return 1;
++			
++}
++
++
++
++int
++write_usb_sys_int_bytes(
++	struct dvb_usb_device*	dib,
++	RegType	type,
++	unsigned short	byte_addr,
++	unsigned short	n_bytes,
++	int	val)
++{
++	int	i;
++	int	nbit_shift;
++	u8	u8_val[LEN_4_BYTE];		
++
++	for (i= n_bytes- 1; i>= 0; i--)
++	{
++		nbit_shift= i << 3;		
++		u8_val[i] = (val>> nbit_shift) & 0xff;
++    	}
++
++	if( write_usb_sys_char_bytes( dib , type , byte_addr, u8_val , n_bytes) ) goto error;			
++
++	return 0;
++error:
++	return 1;
++}
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/rtl2832u_io.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/rtl2832u_io.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,206 @@
++
++
++
++#ifndef __USB_SYS_RTL2832_H__
++#define __USB_SYS_RTL2832_H__
++
++#include "dvb-usb.h"
++
++extern int dvb_usb_rtl2832u_debug;
++#define deb_info(args...) dprintk(dvb_usb_rtl2832u_debug,0x01,args)
++#define deb_xfer(args...) dprintk(dvb_usb_rtl2832u_debug,0x02,args)
++
++#define LEN_1_BYTE					1
++#define LEN_2_BYTE					2
++#define LEN_4_BYTE					4
++
++
++#define	RTL2832_CTRL_ENDPOINT	0x00
++#define DIBUSB_I2C_TIMEOUT				5000
++
++#define SKEL_VENDOR_IN  (USB_DIR_IN|USB_TYPE_VENDOR)
++#define SKEL_VENDOR_OUT (USB_DIR_OUT|USB_TYPE_VENDOR)
++
++#define SYS_BASE_ADDRESS	0x30 //0x3000
++#define USB_BASE_ADDRESS	0x20 //0x2000 
++
++typedef enum { RTD2832U_USB =1, RTD2832U_SYS=2 } RegType;
++
++//3////////////////////////
++//3for return PUCHAR value
++//3///////////////////////
++
++int
++read_usb_sys_char_bytes(
++	struct dvb_usb_device*	dib,
++	RegType	type,
++	unsigned short	byte_addr,
++	unsigned char*	buf,
++	unsigned short	byte_num);
++
++
++
++int
++write_usb_sys_char_bytes(
++	struct dvb_usb_device*	dib,
++	RegType	type,
++	unsigned short	byte_addr,
++	unsigned char*	buf,
++	unsigned short	byte_num);
++
++
++
++//3//////////////////
++//3for return INT value
++//3//////////////////
++
++int
++read_usb_sys_int_bytes(
++	struct dvb_usb_device*	dib,
++	RegType	type,
++	unsigned short	byte_addr,
++	unsigned short	n_bytes,
++	int*	p_val);
++
++
++int
++write_usb_sys_int_bytes(
++	struct dvb_usb_device*	dib,
++	RegType	type,
++	unsigned short	byte_addr,
++	unsigned short	n_bytes,
++	int	val);
++
++/////////////////////////////////////
++
++void
++platform_wait(
++	unsigned long nMinDelayTime);
++
++
++
++#if 0
++//3//////////////////
++//3for std i2c r/w
++//3//////////////////
++
++int
++read_rtl2832_stdi2c(
++	struct dvb_usb_device*	dib,
++	unsigned short			dev_i2c_addr,
++	unsigned char*			data,
++	unsigned short			bytelength);
++
++int 
++write_rtl2832_stdi2c(
++	struct dvb_usb_device*	dib,
++	unsigned short			dev_i2c_addr,
++	unsigned char*			data,
++	unsigned short			bytelength);
++
++#endif
++
++
++
++int 
++read_rtl2832_demod_register(
++	struct dvb_usb_device*dib,
++	unsigned char			demod_device_addr,	
++	unsigned char 		page,
++	unsigned char 		offset,
++	unsigned char*		data,
++	unsigned short		bytelength);
++
++
++
++
++int
++write_rtl2832_demod_register(
++	struct dvb_usb_device*dib,
++	unsigned char			demod_device_addr,		
++	unsigned char			page,
++	unsigned char			offset,
++	unsigned char			*data,
++	unsigned short		bytelength);
++
++
++
++int 
++read_rtl2832_tuner_register(
++	struct dvb_usb_device	*dib,
++	unsigned char			device_address,
++	unsigned char			offset,
++	unsigned char			*data,
++	unsigned short		bytelength);
++
++
++
++
++int write_rtl2832_tuner_register(
++	struct dvb_usb_device *dib,
++	unsigned char			device_address,
++	unsigned char			offset,
++	unsigned char			*data,
++	unsigned short		bytelength);
++
++
++
++
++
++int 
++	write_rtl2832_stdi2c(
++	struct dvb_usb_device*	dib,
++	unsigned short			dev_i2c_addr,
++	unsigned char*			data,
++	unsigned short			bytelength);
++
++
++
++int
++	read_rtl2832_stdi2c(
++	struct dvb_usb_device*	dib,
++	unsigned short			dev_i2c_addr,
++	unsigned char*			data,
++	unsigned short			bytelength);
++
++
++////////////////////////////////////
++
++#define BIT0		0x00000001
++#define BIT1		0x00000002
++#define BIT2		0x00000004
++#define BIT3		0x00000008
++#define BIT4		0x00000010
++#define BIT5		0x00000020
++#define BIT6		0x00000040
++#define BIT7		0x00000080
++#define BIT8		0x00000100
++#define BIT9		0x00000200
++#define BIT10	0x00000400
++#define BIT11	0x00000800
++#define BIT12	0x00001000
++#define BIT13	0x00002000
++#define BIT14	0x00004000
++#define BIT15	0x00008000
++#define BIT16	0x00010000
++#define BIT17	0x00020000
++#define BIT18	0x00040000
++#define BIT19	0x00080000
++#define BIT20	0x00100000
++#define BIT21	0x00200000
++#define BIT22	0x00400000
++#define BIT23	0x00800000
++#define BIT24	0x01000000
++#define BIT25	0x02000000
++#define BIT26	0x04000000
++#define BIT27	0x08000000
++#define BIT28	0x10000000
++#define BIT29	0x20000000
++#define BIT30	0x40000000
++#define BIT31	0x80000000
++
++
++#endif
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/tuner_base.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/tuner_base.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,365 @@
++#ifndef __TUNER_BASE_H
++#define __TUNER_BASE_H
++
++/**
++
++@file
++
++@brief   Tuner base module definition
++
++Tuner base module definitions contains tuner module structure, tuner funciton pointers, and tuner definitions.
++
++
++
++@par Example:
++@code
++
++
++#include "demod_xxx.h"
++#include "tuner_xxx.h"
++
++
++
++int
++CustomI2cRead(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	)
++{
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++	return FUNCTION_ERROR;
++}
++
++
++
++int
++CustomI2cWrite(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned char DeviceAddr,
++	const unsigned char *pWritingBytes,
++	unsigned char ByteNum
++	)
++{
++	...
++
++	return FUNCTION_SUCCESS;
++
++error_status:
++	return FUNCTION_ERROR;
++}
++
++
++
++void
++CustomWaitMs(
++	BASE_INTERFACE_MODULE *pBaseInterface,
++	unsigned long WaitTimeMs
++	)
++{
++	...
++}
++
++
++
++int main(void)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++
++	XXX_DEMOD_MODULE *pDemod;
++	XXX_DEMOD_MODULE XxxDemodModuleMemory;
++
++	TUNER_MODULE *pTuner;
++	TUNER_MODULE TunerModuleMemory;
++
++	I2C_BRIDGE_MODULE I2cBridgeModuleMemory;
++
++	unsigned long RfFreqHz;
++
++	int TunerType;
++	unsigned char DeviceAddr;
++
++
++
++	// Build base interface module.
++	BuildBaseInterface(
++		&pBaseInterface,
++		&BaseInterfaceModuleMemory,
++		9,								// Set maximum I2C reading byte number with 9.
++		8,								// Set maximum I2C writing byte number with 8.
++		CustomI2cRead,					// Employ CustomI2cRead() as basic I2C reading function.
++		CustomI2cWrite,					// Employ CustomI2cWrite() as basic I2C writing function.
++		CustomWaitMs					// Employ CustomWaitMs() as basic waiting function.
++		);
++
++
++	// Build dmeod XXX module.
++	// Note: Demod module builder will set I2cBridgeModuleMemory for tuner I2C command forwarding.
++	//       Must execute demod builder to set I2cBridgeModuleMemory before use tuner functions.
++	BuildDemodXxxModule(
++		&pDemod,
++		&XxxDemodModuleMemory,
++		&BaseInterfaceModuleMemory,
++		&I2cBridgeModuleMemory,
++		...								// Other arguments by each demod module
++		)
++
++
++	// Build tuner XXX module.
++	BuildTunerXxxModule(
++		&pTuner,
++		&TunerModuleMemory,
++		&BaseInterfaceModuleMemory,
++		&I2cBridgeModuleMemory,
++		0xc0,							// Tuner I2C device address is 0xc0 in 8-bit format.
++		...								// Other arguments by each demod module
++		);
++
++
++
++
++
++	// ==== Initialize tuner and set its parameters =====
++
++	// Initialize tuner.
++	pTuner->Initialize(pTuner);
++
++
++	// Set tuner parameters. (RF frequency)
++	// Note: In the example, RF frequency is 474 MHz.
++	RfFreqHz = 474000000;
++
++	pTuner->SetIfFreqHz(pTuner, RfFreqHz);
++
++
++
++
++
++	// ==== Get tuner information =====
++
++	// Get tuenr type.
++	// Note: One can find tuner type in MODULE_TYPE enumeration.
++	pTuner->GetTunerType(pTuner, &TunerType);
++
++	// Get tuner I2C device address.
++	pTuner->GetDeviceAddr(pTuner, &DeviceAddr);
++
++
++	// Get tuner parameters. (RF frequency)
++	pTuner->GetRfFreqHz(pTuner, &RfFreqHz);
++
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++#include "foundation.h"
++
++
++
++
++
++/// tuner module pre-definition
++typedef struct TUNER_MODULE_TAG TUNER_MODULE;
++
++
++
++
++
++/**
++
++@brief   Tuner type getting function pointer
++
++One can use TUNER_FP_GET_TUNER_TYPE() to get tuner type.
++
++
++@param [in]    pTuner       The tuner module pointer
++@param [out]   pTunerType   Pointer to an allocated memory for storing tuner type
++
++
++@note
++	-# Tuner building function will set TUNER_FP_GET_TUNER_TYPE() with the corresponding function.
++
++
++@see   TUNER_TYPE
++
++*/
++typedef void
++(*TUNER_FP_GET_TUNER_TYPE)(
++	TUNER_MODULE *pTuner,
++	int *pTunerType
++	);
++
++
++
++
++
++/**
++
++@brief   Tuner I2C device address getting function pointer
++
++One can use TUNER_FP_GET_DEVICE_ADDR() to get tuner I2C device address.
++
++
++@param [in]    pTuner        The tuner module pointer
++@param [out]   pDeviceAddr   Pointer to an allocated memory for storing tuner I2C device address
++
++
++@retval   FUNCTION_SUCCESS   Get tuner device address successfully.
++@retval   FUNCTION_ERROR     Get tuner device address unsuccessfully.
++
++
++@note
++	-# Tuner building function will set TUNER_FP_GET_DEVICE_ADDR() with the corresponding function.
++
++*/
++typedef void
++(*TUNER_FP_GET_DEVICE_ADDR)(
++	TUNER_MODULE *pTuner,
++	unsigned char *pDeviceAddr
++	);
++
++
++
++
++
++/**
++
++@brief   Tuner initializing function pointer
++
++One can use TUNER_FP_INITIALIZE() to initialie tuner.
++
++
++@param [in]   pTuner   The tuner module pointer
++
++
++@retval   FUNCTION_SUCCESS   Initialize tuner successfully.
++@retval   FUNCTION_ERROR     Initialize tuner unsuccessfully.
++
++
++@note
++	-# Tuner building function will set TUNER_FP_INITIALIZE() with the corresponding function.
++
++*/
++typedef int
++(*TUNER_FP_INITIALIZE)(
++	TUNER_MODULE *pTuner
++	);
++
++
++
++
++
++/**
++
++@brief   Tuner RF frequency setting function pointer
++
++One can use TUNER_FP_SET_RF_FREQ_HZ() to set tuner RF frequency in Hz.
++
++
++@param [in]   pTuner     The tuner module pointer
++@param [in]   RfFreqHz   RF frequency in Hz for setting
++
++
++@retval   FUNCTION_SUCCESS   Set tuner RF frequency successfully.
++@retval   FUNCTION_ERROR     Set tuner RF frequency unsuccessfully.
++
++
++@note
++	-# Tuner building function will set TUNER_FP_SET_RF_FREQ_HZ() with the corresponding function.
++
++*/
++typedef int
++(*TUNER_FP_SET_RF_FREQ_HZ)(
++	TUNER_MODULE *pTuner,
++	unsigned long RfFreqHz
++	);
++
++
++
++
++
++/**
++
++@brief   Tuner RF frequency getting function pointer
++
++One can use TUNER_FP_GET_RF_FREQ_HZ() to get tuner RF frequency in Hz.
++
++
++@param [in]   pTuner      The tuner module pointer
++@param [in]   pRfFreqHz   Pointer to an allocated memory for storing demod RF frequency in Hz
++
++
++@retval   FUNCTION_SUCCESS   Get tuner RF frequency successfully.
++@retval   FUNCTION_ERROR     Get tuner RF frequency unsuccessfully.
++
++
++@note
++	-# Tuner building function will set TUNER_FP_GET_RF_FREQ_HZ() with the corresponding function.
++
++*/
++typedef int
++(*TUNER_FP_GET_RF_FREQ_HZ)(
++	TUNER_MODULE *pTuner,
++	unsigned long *pRfFreqHz
++	);
++
++
++
++
++
++/// Tuner module structure
++struct TUNER_MODULE_TAG
++{
++	unsigned char		b_set_tuner_power_gpio4;					//3add by chialing 2008.08.19
++	// Private variables
++	int           TunerType;									///<   Tuner type
++	unsigned char DeviceAddr;									///<   Tuner I2C device address
++	unsigned long RfFreqHz;										///<   Tuner RF frequency in Hz
++
++	int IsRfFreqHzSet;											///<   Tuner RF frequency in Hz (setting status)
++
++	void *pExtra;												///<   Tuner extra module used by driving module
++	BASE_INTERFACE_MODULE *pBaseInterface;						///<   Base interface module
++	I2C_BRIDGE_MODULE *pI2cBridge;								///<   I2C bridge module
++
++
++	// Tuner manipulating functions
++	TUNER_FP_GET_TUNER_TYPE          GetTunerType;				///<   Tuner type getting function pointer
++	TUNER_FP_GET_DEVICE_ADDR         GetDeviceAddr;				///<   Tuner I2C device address getting function pointer
++
++	TUNER_FP_INITIALIZE              Initialize;				///<   Tuner initializing function pointer
++	TUNER_FP_SET_RF_FREQ_HZ          SetRfFreqHz;				///<   Tuner RF frequency setting function pointer
++	TUNER_FP_GET_RF_FREQ_HZ          GetRfFreqHz;				///<   Tuner RF frequency getting function pointer
++
++};
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++#endif
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/tuner_fc2580.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/tuner_fc2580.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,992 @@
++/**
++
++@file
++
++@brief   FC2580 tuner module definition
++
++One can manipulate FC2580 tuner through FC2580 module.
++FC2580 module is derived from tuner module.
++
++*/
++
++
++#include "tuner_fc2580.h"
++
++
++
++
++
++/**
++
++@brief   FC2580 tuner module builder
++
++Use BuildFc2580Module() to build FC2580 module, set all module function pointers with the corresponding functions,
++and initialize module private variables.
++
++
++@param [in]   ppTuner                      Pointer to FC2580 tuner module pointer
++@param [in]   pTunerModuleMemory           Pointer to an allocated tuner module memory
++@param [in]   pFc2580ExtraModuleMemory     Pointer to an allocated FC2580 extra module memory
++@param [in]   pBaseInterfaceModuleMemory   Pointer to an allocated base interface module memory
++@param [in]   pI2cBridgeModuleMemory       Pointer to an allocated I2C bridge module memory
++@param [in]   DeviceAddr                   FC2580 I2C device address
++@param [in]   AgcMode                      FC2580 AGC mode
++
++
++@note
++	-# One should call BuildFc2580Module() to build FC2580 module before using it.
++
++*/
++void
++BuildFc2580Module(
++	TUNER_MODULE **ppTuner,
++	TUNER_MODULE *pTunerModuleMemory,
++	FC2580_EXTRA_MODULE *pFc2580ExtraModuleMemory,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory,
++	unsigned char DeviceAddr,
++	unsigned long CrystalFreqHz,
++	int AgcMode
++	)
++{
++	TUNER_MODULE *pTuner;
++	FC2580_EXTRA_MODULE *pExtra;
++
++
++
++	// Set tuner module pointer.
++	*ppTuner = pTunerModuleMemory;
++
++	// Get tuner module.
++	pTuner = *ppTuner;
++
++	// Set tuner extra module pointer, base interface module pointer, and I2C bridge module pointer.
++	pTuner->pExtra         = pFc2580ExtraModuleMemory;
++	pTuner->pBaseInterface = pBaseInterfaceModuleMemory;
++	pTuner->pI2cBridge     = pI2cBridgeModuleMemory;
++
++	// Get tuner extra module.
++	pExtra = (FC2580_EXTRA_MODULE *)pTuner->pExtra;
++
++
++
++	// Set tuner type.
++	pTuner->TunerType = TUNER_TYPE_FC2580;
++
++	// Set tuner I2C device address.
++	pTuner->DeviceAddr = DeviceAddr;
++
++
++	// Initialize tuner parameter setting status.
++	pTuner->IsRfFreqHzSet = NO;
++
++
++	// Set I2C bridge tuner arguments.
++	fc2580_SetI2cBridgeModuleTunerArg(pTuner);
++
++
++	// Set tuner module manipulating function pointers.
++	pTuner->GetTunerType  = fc2580_GetTunerType;
++	pTuner->GetDeviceAddr = fc2580_GetDeviceAddr;
++
++	pTuner->Initialize    = fc2580_Initialize;
++	pTuner->SetRfFreqHz   = fc2580_SetRfFreqHz;
++	pTuner->GetRfFreqHz   = fc2580_GetRfFreqHz;
++
++
++	// Initialize tuner extra module variables.
++	pExtra->CrystalFreqHz      = CrystalFreqHz;
++	pExtra->AgcMode            = AgcMode;
++	pExtra->IsBandwidthModeSet = NO;
++
++	// Set tuner extra module function pointers.
++	pExtra->SetBandwidthMode = fc2580_SetBandwidthMode;
++	pExtra->GetBandwidthMode = fc2580_GetBandwidthMode;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_TUNER_TYPE
++
++*/
++void
++fc2580_GetTunerType(
++	TUNER_MODULE *pTuner,
++	int *pTunerType
++	)
++{
++	// Get tuner type from tuner module.
++	*pTunerType = pTuner->TunerType;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_DEVICE_ADDR
++
++*/
++void
++fc2580_GetDeviceAddr(
++	TUNER_MODULE *pTuner,
++	unsigned char *pDeviceAddr
++	)
++{
++	// Get tuner I2C device address from tuner module.
++	*pDeviceAddr = pTuner->DeviceAddr;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_INITIALIZE
++
++*/
++int
++fc2580_Initialize(
++	TUNER_MODULE *pTuner
++	)
++{
++	FC2580_EXTRA_MODULE *pExtra;
++	int AgcMode;
++	unsigned int CrystalFreqKhz;
++
++
++
++	// Get tuner extra module.
++	pExtra = (FC2580_EXTRA_MODULE *)pTuner->pExtra;
++
++
++	// Get AGC mode.
++	AgcMode = pExtra->AgcMode;
++
++	// Initialize tuner with AGC mode.
++	// Note: CrystalFreqKhz = round(CrystalFreqHz / 1000)
++	CrystalFreqKhz = (unsigned int)((pExtra->CrystalFreqHz + 500) / 1000);
++
++	if(fc2580_set_init(pTuner, AgcMode, CrystalFreqKhz) != FCI_SUCCESS)
++		goto error_status_initialize_tuner;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_initialize_tuner:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_SET_RF_FREQ_HZ
++
++*/
++int
++fc2580_SetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long RfFreqHz
++	)
++{
++	FC2580_EXTRA_MODULE *pExtra;
++	unsigned int RfFreqKhz;
++	unsigned int CrystalFreqKhz;
++
++
++
++	// Get tuner extra module.
++	pExtra = (FC2580_EXTRA_MODULE *)pTuner->pExtra;
++
++
++	// Set tuner RF frequency in KHz.
++	// Note: RfFreqKhz = round(RfFreqHz / 1000)
++	//       CrystalFreqKhz = round(CrystalFreqHz / 1000)
++	RfFreqKhz = (unsigned int)((RfFreqHz + 500) / 1000);
++	CrystalFreqKhz = (unsigned int)((pExtra->CrystalFreqHz + 500) / 1000);
++
++	if(fc2580_set_freq(pTuner, RfFreqKhz, CrystalFreqKhz) != FCI_SUCCESS)
++		goto error_status_set_tuner_rf_frequency;
++
++
++	// Set tuner RF frequency parameter.
++	pTuner->RfFreqHz      = RfFreqHz;
++	pTuner->IsRfFreqHzSet = YES;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_tuner_rf_frequency:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_RF_FREQ_HZ
++
++*/
++int
++fc2580_GetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long *pRfFreqHz
++	)
++{
++	// Get tuner RF frequency in Hz from tuner module.
++	if(pTuner->IsRfFreqHzSet != YES)
++		goto error_status_get_tuner_rf_frequency;
++
++	*pRfFreqHz = pTuner->RfFreqHz;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_tuner_rf_frequency:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Set FC2580 tuner bandwidth mode.
++
++*/
++int
++fc2580_SetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int BandwidthMode
++	)
++{
++	FC2580_EXTRA_MODULE *pExtra;
++	unsigned int CrystalFreqKhz;
++
++
++
++	// Get tuner extra module.
++	pExtra = (FC2580_EXTRA_MODULE *)pTuner->pExtra;
++
++
++	// Set tuner bandwidth mode.
++	// Note: CrystalFreqKhz = round(CrystalFreqHz / 1000)
++	CrystalFreqKhz = (unsigned int)((pExtra->CrystalFreqHz + 500) / 1000);
++
++	if(fc2580_set_filter(pTuner, (unsigned char)BandwidthMode, CrystalFreqKhz) != FCI_SUCCESS)
++		goto error_status_set_tuner_bandwidth_mode;
++
++
++	// Set tuner bandwidth mode parameter.
++	pExtra->BandwidthMode      = BandwidthMode;
++	pExtra->IsBandwidthModeSet = YES;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_tuner_bandwidth_mode:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Get FC2580 tuner bandwidth mode.
++
++*/
++int
++fc2580_GetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int *pBandwidthMode
++	)
++{
++	FC2580_EXTRA_MODULE *pExtra;
++
++
++
++	// Get tuner extra module.
++	pExtra = (FC2580_EXTRA_MODULE *)pTuner->pExtra;
++
++
++	// Get tuner bandwidth mode from tuner module.
++	if(pExtra->IsBandwidthModeSet != YES)
++		goto error_status_get_tuner_bandwidth_mode;
++
++	*pBandwidthMode = pExtra->BandwidthMode;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_tuner_bandwidth_mode:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Set I2C bridge module tuner arguments.
++
++FC2580 builder will use fc2580_SetI2cBridgeModuleTunerArg() to set I2C bridge module tuner arguments.
++
++
++@param [in]   pTuner   The tuner module pointer
++
++
++@see   BuildFc2580Module()
++
++*/
++void
++fc2580_SetI2cBridgeModuleTunerArg(
++	TUNER_MODULE *pTuner
++	)
++{
++	I2C_BRIDGE_MODULE *pI2cBridge;
++
++
++
++	// Get I2C bridge module.
++	pI2cBridge = pTuner->pI2cBridge;
++
++	// Set I2C bridge module tuner arguments.
++	pI2cBridge->pTunerDeviceAddr = &pTuner->DeviceAddr;
++
++
++	return;
++}
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// The following context is source code provided by FCI.
++
++
++
++
++
++// FCI source code - fc2580_driver_v14011_r.c
++
++
++/*==============================================================================
++    FILE NAME   : FC2580_driver_v1400_r.c
++    
++    VERSION     : 1.400_r
++    
++    UPDATE      : September 22. 2008
++				
++==============================================================================*/ 
++
++/*==============================================================================
++
++  Chip ID of FC2580 is 0x56 or 0xAC(including I2C write bit)
++
++==============================================================================*/
++
++//#include "fc2580_driver_v1400_r.h"
++
++//fc2580_band_type curr_band = NO_BAND;
++//unsigned int freq_xtal = 16384;
++
++
++/*==============================================================================
++		milisecond delay function					EXTERNAL FUNCTION
++
++  This function is a generic function which write a byte into fc2580's
++ specific address.
++
++  <input parameter>
++
++  a
++	length of wanted delay in milisecond unit
++
++==============================================================================*/
++void wait_msec(TUNER_MODULE *pTuner, int a)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++
++	// Get base interface.
++	pBaseInterface = pTuner->pBaseInterface;
++
++
++	// Wait time in millisecond.
++	pBaseInterface->WaitMs(pBaseInterface, (unsigned long)a);
++
++
++	return;
++}
++
++/*==============================================================================
++
++           fc2580 i2c write
++
++  This function is a generic function which write a byte into fc2580's
++ specific address.
++
++  <input parameter>
++
++  addr
++	fc2580's memory address\
++	type : byte
++
++  data
++	target data
++	type : byte
++
++==============================================================================*/
++fci_result_type fc2580_i2c_write( TUNER_MODULE *pTuner, unsigned char addr, unsigned char data )
++{
++	I2C_BRIDGE_MODULE *pI2cBridge;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	unsigned char TunerDeviceAddr;
++
++	struct dvb_usb_device	*d;	
++	
++//	unsigned char WritingBytes[2];
++	unsigned char WritingBytes[1];
++
++
++	// Get I2C bridge.
++	pI2cBridge = pTuner->pI2cBridge;
++	pBaseInterface = pTuner->pBaseInterface;	
++
++	// Get tuner device address.
++	TunerDeviceAddr = *pI2cBridge->pTunerDeviceAddr;
++
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);	
++	
++
++	// Set writing bytes.
++	// Note: The I2C format of tuner register byte setting is as follows:
++	//       start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit
++//	WritingBytes[0] = addr;
++//	WritingBytes[1] = data;
++	WritingBytes[0] = data;
++	
++	// Set tuner register bytes with writing buffer.
++//	if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, WritingBytes, LEN_2_BYTE) != FUNCTION_SUCCESS)
++//		goto error_status_set_tuner_registers;
++
++
++	if (write_rtl2832_tuner_register(d, TunerDeviceAddr, addr, WritingBytes, LEN_1_BYTE)) goto error;
++
++
++	return FCI_SUCCESS;
++
++error:
++	return FCI_FAIL;
++};
++
++/*==============================================================================
++
++           fc2580 i2c read
++
++  This function is a generic function which gets called to read data from
++ fc2580's target memory address.
++
++  <input parameter>
++
++  addr
++	fc2580's memory address
++	type : byte
++
++
++ <return value>
++  data
++	a byte of data read out of target address 'addr'
++	type : byte
++
++==============================================================================*/
++fci_result_type fc2580_i2c_read( TUNER_MODULE *pTuner, unsigned char addr, unsigned char *read_data )
++{
++	I2C_BRIDGE_MODULE *pI2cBridge;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	unsigned char TunerDeviceAddr;
++
++	struct dvb_usb_device	*d;	
++
++
++	// Get I2C bridge.
++	pI2cBridge = pTuner->pI2cBridge;
++	pBaseInterface = pTuner->pBaseInterface;	
++
++	// Get tuner device address.
++	TunerDeviceAddr = *pI2cBridge->pTunerDeviceAddr;
++
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);	
++
++
++	// Set tuner register reading address.
++	// Note: The I2C format of tuner register reading address setting is as follows:
++	//       start_bit + (DeviceAddr | writing_bit) + addr + stop_bit
++//	if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, &addr, LEN_1_BYTE) != FUNCTION_SUCCESS)
++//		goto error_status_set_tuner_register_reading_address;
++
++	// Get tuner register byte.
++	// Note: The I2C format of tuner register byte getting is as follows:
++	//       start_bit + (DeviceAddr | reading_bit) + read_data + stop_bit
++//	if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, read_data, LEN_1_BYTE) != FUNCTION_SUCCESS)
++//		goto error_status_get_tuner_registers;
++
++
++	if(read_rtl2832_tuner_register(d, TunerDeviceAddr, addr, read_data, LEN_1_BYTE)) goto error;
++
++	return FCI_SUCCESS;
++
++error:
++	return FCI_FAIL;
++};
++
++
++/*==============================================================================
++       fc2580 I2C Test
++
++  This function is a generic function which tests I2C interface's availability
++
++  by reading out it's I2C id data from reg. address '0x01'.
++
++  <input parameter>
++
++  None
++  
++  <return value>
++  int
++	1 : success - communication is avilable
++	0 : fail - communication is unavailable
++  
++
++==============================================================================*/
++//int fc2580_i2c_test( void )
++//{
++//	return ( fc2580_i2c_read( 0x01 ) == 0x56 )? 0x01 : 0x00;
++//}
++
++
++
++
++/*==============================================================================
++       fc2580 initial setting
++
++  This function is a generic function which gets called to initialize
++
++  fc2580 in DVB-H mode or L-Band TDMB mode
++
++  <input parameter>
++
++  ifagc_mode
++    type : integer
++	1 : Internal AGC
++	2 : Voltage Control Mode
++
++==============================================================================*/
++fci_result_type fc2580_set_init( TUNER_MODULE *pTuner, int ifagc_mode, unsigned int freq_xtal )
++{
++	fci_result_type result = FCI_SUCCESS;
++
++	result &= fc2580_i2c_write(pTuner, 0x00, 0x00);	/*** Confidential ***/
++	result &= fc2580_i2c_write(pTuner, 0x12, 0x86);
++	result &= fc2580_i2c_write(pTuner, 0x14, 0x5C);
++	result &= fc2580_i2c_write(pTuner, 0x16, 0x3C);
++	result &= fc2580_i2c_write(pTuner, 0x1F, 0xD2);
++	result &= fc2580_i2c_write(pTuner, 0x09, 0xD7);
++	result &= fc2580_i2c_write(pTuner, 0x0B, 0xD5);
++	result &= fc2580_i2c_write(pTuner, 0x0C, 0x32);
++	result &= fc2580_i2c_write(pTuner, 0x0E, 0x43);
++	result &= fc2580_i2c_write(pTuner, 0x21, 0x0A);
++	result &= fc2580_i2c_write(pTuner, 0x22, 0x82);
++	if( ifagc_mode == 1 )
++	{
++		result &= fc2580_i2c_write(pTuner, 0x45, 0x10);	//internal AGC
++		result &= fc2580_i2c_write(pTuner, 0x4C, 0x00);	//HOLD_AGC polarity
++	}
++	else if( ifagc_mode == 2 )
++	{
++		result &= fc2580_i2c_write(pTuner, 0x45, 0x20);	//Voltage Control Mode
++		result &= fc2580_i2c_write(pTuner, 0x4C, 0x02);	//HOLD_AGC polarity
++	}
++	result &= fc2580_i2c_write(pTuner, 0x3F, 0x88);
++	result &= fc2580_i2c_write(pTuner, 0x02, 0x0E);
++	result &= fc2580_i2c_write(pTuner, 0x58, 0x14);
++	result &= fc2580_set_filter(pTuner, 8, freq_xtal);	//BW = 7.8MHz
++
++	return result;
++}
++
++
++/*==============================================================================
++       fc2580 frequency setting
++
++  This function is a generic function which gets called to change LO Frequency
++
++  of fc2580 in DVB-H mode or L-Band TDMB mode
++
++  <input parameter>
++  freq_xtal: kHz
++
++  f_lo
++	Value of target LO Frequency in 'kHz' unit
++	ex) 2.6GHz = 2600000
++
++==============================================================================*/
++fci_result_type fc2580_set_freq( TUNER_MODULE *pTuner, unsigned int f_lo, unsigned int freq_xtal )
++{
++	unsigned int f_diff, f_diff_shifted, n_val, k_val;
++	unsigned int f_vco, r_val, f_comp;
++	unsigned char pre_shift_bits = 4;// number of preshift to prevent overflow in shifting f_diff to f_diff_shifted
++	unsigned char data_0x18;
++	unsigned char data_0x02 = (USE_EXT_CLK<<5)|0x0E;
++	
++	fc2580_band_type band = ( f_lo > 1000000 )? L_BAND : ( f_lo > 400000 )? UHF_BAND : VHF_BAND;
++
++	fci_result_type result = FCI_SUCCESS;
++
++	f_vco = ( band == UHF_BAND )? f_lo * 4 : (( band == L_BAND )? f_lo * 2 : f_lo * 12);
++	r_val = ( f_vco >= 2*76*freq_xtal )? 1 : ( f_vco >= 76*freq_xtal )? 2 : 4;
++	f_comp = freq_xtal/r_val;
++	n_val =	( f_vco / 2 ) / f_comp;
++	
++	f_diff = f_vco - 2* f_comp * n_val;
++	f_diff_shifted = f_diff << ( 20 - pre_shift_bits );
++	k_val = f_diff_shifted / ( ( 2* f_comp ) >> pre_shift_bits );
++	
++	if( f_diff_shifted - k_val * ( ( 2* f_comp ) >> pre_shift_bits ) >= ( f_comp >> pre_shift_bits ) )
++	k_val = k_val + 1;
++	
++	if( f_vco >= BORDER_FREQ )	//Select VCO Band
++		data_0x02 = data_0x02 | 0x08;	//0x02[3] = 1;
++	else
++		data_0x02 = data_0x02 & 0xF7;	//0x02[3] = 0;
++	
++//	if( band != curr_band ) {
++		switch(band)
++		{
++			case UHF_BAND:
++				data_0x02 = (data_0x02 & 0x3F);
++
++				result &= fc2580_i2c_write(pTuner, 0x25, 0xF0);
++				result &= fc2580_i2c_write(pTuner, 0x27, 0x77);
++				result &= fc2580_i2c_write(pTuner, 0x28, 0x53);
++				result &= fc2580_i2c_write(pTuner, 0x29, 0x60);
++				result &= fc2580_i2c_write(pTuner, 0x30, 0x09);
++				result &= fc2580_i2c_write(pTuner, 0x50, 0x8C);
++				result &= fc2580_i2c_write(pTuner, 0x53, 0x50);
++
++				if( f_lo < 538000 )
++					result &= fc2580_i2c_write(pTuner, 0x5F, 0x13);
++				else					
++					result &= fc2580_i2c_write(pTuner, 0x5F, 0x15);
++
++				if( f_lo < 538000 )
++				{
++					result &= fc2580_i2c_write(pTuner, 0x61, 0x07);
++					result &= fc2580_i2c_write(pTuner, 0x62, 0x06);
++					result &= fc2580_i2c_write(pTuner, 0x67, 0x06);
++					result &= fc2580_i2c_write(pTuner, 0x68, 0x08);
++					result &= fc2580_i2c_write(pTuner, 0x69, 0x10);
++					result &= fc2580_i2c_write(pTuner, 0x6A, 0x12);
++				}
++				else if( f_lo < 794000 )
++				{
++					result &= fc2580_i2c_write(pTuner, 0x61, 0x03);
++					result &= fc2580_i2c_write(pTuner, 0x62, 0x03);
++					result &= fc2580_i2c_write(pTuner, 0x67, 0x03);  //ACI improve
++					result &= fc2580_i2c_write(pTuner, 0x68, 0x05);  //ACI improve
++					result &= fc2580_i2c_write(pTuner, 0x69, 0x0C);
++					result &= fc2580_i2c_write(pTuner, 0x6A, 0x0E);
++				}
++				else
++				{
++					result &= fc2580_i2c_write(pTuner, 0x61, 0x07);
++					result &= fc2580_i2c_write(pTuner, 0x62, 0x06);
++					result &= fc2580_i2c_write(pTuner, 0x67, 0x07);
++					result &= fc2580_i2c_write(pTuner, 0x68, 0x09);
++					result &= fc2580_i2c_write(pTuner, 0x69, 0x10);
++					result &= fc2580_i2c_write(pTuner, 0x6A, 0x12);
++				}
++
++				result &= fc2580_i2c_write(pTuner, 0x63, 0x15);
++
++				result &= fc2580_i2c_write(pTuner, 0x6B, 0x0B);
++				result &= fc2580_i2c_write(pTuner, 0x6C, 0x0C);
++				result &= fc2580_i2c_write(pTuner, 0x6D, 0x78);
++				result &= fc2580_i2c_write(pTuner, 0x6E, 0x32);
++				result &= fc2580_i2c_write(pTuner, 0x6F, 0x14);
++				result &= fc2580_set_filter(pTuner, 8, freq_xtal);	//BW = 7.8MHz
++				break;
++			case VHF_BAND:
++				data_0x02 = (data_0x02 & 0x3F) | 0x80;
++				result &= fc2580_i2c_write(pTuner, 0x27, 0x77);
++				result &= fc2580_i2c_write(pTuner, 0x28, 0x33);
++				result &= fc2580_i2c_write(pTuner, 0x29, 0x40);
++				result &= fc2580_i2c_write(pTuner, 0x30, 0x09);
++				result &= fc2580_i2c_write(pTuner, 0x50, 0x8C);
++				result &= fc2580_i2c_write(pTuner, 0x53, 0x50);
++				result &= fc2580_i2c_write(pTuner, 0x5F, 0x0F);
++				result &= fc2580_i2c_write(pTuner, 0x61, 0x07);
++				result &= fc2580_i2c_write(pTuner, 0x62, 0x00);
++				result &= fc2580_i2c_write(pTuner, 0x63, 0x15);
++				result &= fc2580_i2c_write(pTuner, 0x67, 0x03);
++				result &= fc2580_i2c_write(pTuner, 0x68, 0x05);
++				result &= fc2580_i2c_write(pTuner, 0x69, 0x10);
++				result &= fc2580_i2c_write(pTuner, 0x6A, 0x12);
++				result &= fc2580_i2c_write(pTuner, 0x6B, 0x08);
++				result &= fc2580_i2c_write(pTuner, 0x6C, 0x0A);
++				result &= fc2580_i2c_write(pTuner, 0x6D, 0x78);
++				result &= fc2580_i2c_write(pTuner, 0x6E, 0x32);
++				result &= fc2580_i2c_write(pTuner, 0x6F, 0x54);
++				result &= fc2580_set_filter(pTuner, 7, freq_xtal);	//BW = 6.8MHz
++				break;
++			case L_BAND:
++				data_0x02 = (data_0x02 & 0x3F) | 0x40;
++				result &= fc2580_i2c_write(pTuner, 0x2B, 0x70);
++				result &= fc2580_i2c_write(pTuner, 0x2C, 0x37);
++				result &= fc2580_i2c_write(pTuner, 0x2D, 0xE7);
++				result &= fc2580_i2c_write(pTuner, 0x30, 0x09);
++				result &= fc2580_i2c_write(pTuner, 0x44, 0x20);
++				result &= fc2580_i2c_write(pTuner, 0x50, 0x8C);
++				result &= fc2580_i2c_write(pTuner, 0x53, 0x50);
++				result &= fc2580_i2c_write(pTuner, 0x5F, 0x0F);
++				result &= fc2580_i2c_write(pTuner, 0x61, 0x0F);
++				result &= fc2580_i2c_write(pTuner, 0x62, 0x00);
++				result &= fc2580_i2c_write(pTuner, 0x63, 0x13);
++				result &= fc2580_i2c_write(pTuner, 0x67, 0x00);
++				result &= fc2580_i2c_write(pTuner, 0x68, 0x02);
++				result &= fc2580_i2c_write(pTuner, 0x69, 0x0C);
++				result &= fc2580_i2c_write(pTuner, 0x6A, 0x0E);
++				result &= fc2580_i2c_write(pTuner, 0x6B, 0x08);
++				result &= fc2580_i2c_write(pTuner, 0x6C, 0x0A);
++				result &= fc2580_i2c_write(pTuner, 0x6D, 0xA0);
++				result &= fc2580_i2c_write(pTuner, 0x6E, 0x50);
++				result &= fc2580_i2c_write(pTuner, 0x6F, 0x14);
++				result &= fc2580_set_filter(pTuner, 1, freq_xtal);	//BW = 1.53MHz
++				break;
++			default:
++				break;
++		}
++//		curr_band = band;
++//	}
++
++	//A command about AGC clock's pre-divide ratio
++	if( freq_xtal >= 28000 )
++		result &= fc2580_i2c_write(pTuner, 0x4B, 0x22 );
++
++	//Commands about VCO Band and PLL setting.
++	result &= fc2580_i2c_write(pTuner, 0x02, data_0x02);
++	data_0x18 = ( ( r_val == 1 )? 0x00 : ( ( r_val == 2 )? 0x10 : 0x20 ) ) + (unsigned char)(k_val >> 16);
++	result &= fc2580_i2c_write(pTuner, 0x18, data_0x18);						//Load 'R' value and high part of 'K' values
++	result &= fc2580_i2c_write(pTuner, 0x1A, (unsigned char)( k_val >> 8 ) );	//Load middle part of 'K' value
++	result &= fc2580_i2c_write(pTuner, 0x1B, (unsigned char)( k_val ) );		//Load lower part of 'K' value
++	result &= fc2580_i2c_write(pTuner, 0x1C, (unsigned char)( n_val ) );		//Load 'N' value
++
++	//A command about UHF LNA Load Cap
++	if( band == UHF_BAND )
++		result &= fc2580_i2c_write(pTuner, 0x2D, ( f_lo <= (unsigned int)794000 )? 0x9F : 0x8F );	//LNA_OUT_CAP
++	
++
++	return result;
++}
++
++
++/*==============================================================================
++       fc2580 filter BW setting
++
++  This function is a generic function which gets called to change Bandwidth
++
++  frequency of fc2580's channel selection filter
++
++  <input parameter>
++  freq_xtal: kHz
++
++  filter_bw
++    1 : 1.53MHz(TDMB)
++	6 : 6MHz   (Bandwidth 6MHz)
++	7 : 6.8MHz (Bandwidth 7MHz)
++	8 : 7.8MHz (Bandwidth 8MHz)
++	
++
++==============================================================================*/
++fci_result_type fc2580_set_filter( TUNER_MODULE *pTuner, unsigned char filter_bw, unsigned int freq_xtal )
++{
++	unsigned char	cal_mon, i;
++	fci_result_type result = FCI_SUCCESS;
++
++	if(filter_bw == 1)
++	{
++		result &= fc2580_i2c_write(pTuner, 0x36, 0x1C);
++		result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(4151*freq_xtal/1000000) );
++		result &= fc2580_i2c_write(pTuner, 0x39, 0x00);
++		result &= fc2580_i2c_write(pTuner, 0x2E, 0x09);
++	}
++	if(filter_bw == 6)
++	{
++		result &= fc2580_i2c_write(pTuner, 0x36, 0x18);
++		result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(4400*freq_xtal/1000000) );
++		result &= fc2580_i2c_write(pTuner, 0x39, 0x00);
++		result &= fc2580_i2c_write(pTuner, 0x2E, 0x09);
++	}
++	else if(filter_bw == 7)
++	{
++		result &= fc2580_i2c_write(pTuner, 0x36, 0x18);
++		result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(3910*freq_xtal/1000000) );
++		result &= fc2580_i2c_write(pTuner, 0x39, 0x80);
++		result &= fc2580_i2c_write(pTuner, 0x2E, 0x09);
++	}
++	else if(filter_bw == 8)
++	{
++		result &= fc2580_i2c_write(pTuner, 0x36, 0x18);
++		result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(3300*freq_xtal/1000000) );
++		result &= fc2580_i2c_write(pTuner, 0x39, 0x80);
++		result &= fc2580_i2c_write(pTuner, 0x2E, 0x09);
++	}
++
++	
++	for(i=0; i<5; i++)
++	{
++		wait_msec(pTuner, 5);//wait 5ms
++		result &= fc2580_i2c_read(pTuner, 0x2F, &cal_mon);
++		if( (cal_mon & 0xC0) != 0xC0)
++		{
++			result &= fc2580_i2c_write(pTuner, 0x2E, 0x01);
++			result &= fc2580_i2c_write(pTuner, 0x2E, 0x09);
++		}
++		else
++			break;
++	}
++
++	result &= fc2580_i2c_write(pTuner, 0x2E, 0x01);
++
++	return result;
++}
++
++/*==============================================================================
++       fc2580 RSSI function
++
++  This function is a generic function which returns fc2580's
++  
++  current RSSI value.
++
++  <input parameter>
++	none
++
++  <return value>
++  int
++  	rssi : estimated input power.
++
++==============================================================================*/
++//int fc2580_get_rssi(void) {
++//	
++//	unsigned char s_lna, s_rfvga, s_cfs, s_ifvga;
++//	int ofs_lna, ofs_rfvga, ofs_csf, ofs_ifvga, rssi;
++//
++//	fc2580_i2c_read(0x71, &s_lna );
++//	fc2580_i2c_read(0x72, &s_rfvga );
++//	fc2580_i2c_read(0x73, &s_cfs );
++//	fc2580_i2c_read(0x74, &s_ifvga );
++//	
++//
++//	ofs_lna = 
++//			(curr_band==UHF_BAND)?
++//				(s_lna==0)? 0 :
++//				(s_lna==1)? -6 :
++//				(s_lna==2)? -17 :
++//				(s_lna==3)? -22 : -30 :
++//			(curr_band==VHF_BAND)?
++//				(s_lna==0)? 0 :
++//				(s_lna==1)? -6 :
++//				(s_lna==2)? -19 :
++//				(s_lna==3)? -24 : -32 :
++//			(curr_band==L_BAND)?
++//				(s_lna==0)? 0 :
++//				(s_lna==1)? -6 :
++//				(s_lna==2)? -11 :
++//				(s_lna==3)? -16 : -34 :
++//			0;//NO_BAND
++//	ofs_rfvga = -s_rfvga+((s_rfvga>=11)? 1 : 0) + ((s_rfvga>=18)? 1 : 0);
++//	ofs_csf = -6*s_cfs;
++//	ofs_ifvga = s_ifvga/4;
++//
++//	return rssi = ofs_lna+ofs_rfvga+ofs_csf+ofs_ifvga+OFS_RSSI;
++//				
++//}
++
++/*==============================================================================
++       fc2580 Xtal frequency Setting
++
++  This function is a generic function which sets 
++  
++  the frequency of xtal.
++  
++  <input parameter>
++  
++  frequency
++  	frequency value of internal(external) Xtal(clock) in kHz unit.
++
++==============================================================================*/
++//void fc2580_set_freq_xtal(unsigned int frequency) {
++//
++//	freq_xtal = frequency;
++//
++//}
++
++
++
++
++
++
++
++
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/tuner_fc2580.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/tuner_fc2580.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,519 @@
++#ifndef __TUNER_FC2580_H
++#define __TUNER_FC2580_H
++
++/**
++
++@file
++
++@brief   FC2580 tuner module declaration
++
++One can manipulate FC2580 tuner through FC2580 module.
++FC2580 module is derived from tuner module.
++
++
++
++@par Example:
++@code
++
++// The example is the same as the tuner example in tuner_base.h except the listed lines.
++
++
++
++#include "tuner_fc2580.h"
++
++
++...
++
++
++
++int main(void)
++{
++	TUNER_MODULE        *pTuner;
++	FC2580_EXTRA_MODULE *pTunerExtra;
++
++	TUNER_MODULE          TunerModuleMemory;
++	FC2580_EXTRA_MODULE   Fc2580ExtraModuleMemory;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++	I2C_BRIDGE_MODULE     I2cBridgeModuleMemory;
++
++	unsigned long BandwidthMode;
++
++
++	...
++
++
++
++	// Build FC2580 tuner module.
++	BuildFc2580Module(
++		&pTuner,
++		&TunerModuleMemory,
++		&Fc2580ExtraModuleMemory,
++		&BaseInterfaceModuleMemory,
++		&I2cBridgeModuleMemory,
++		0xac,								// I2C device address is 0xac in 8-bit format.
++		CRYSTAL_FREQ_16384000HZ,			// Crystal frequency is 16.384 MHz.
++		FC2580_AGC_EXTERNAL					// The FC2580 AGC mode is external AGC mode.
++		);
++
++
++
++
++
++	// Get FC2580 tuner extra module.
++	pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra);
++
++
++
++
++
++	// ==== Initialize tuner and set its parameters =====
++
++	...
++
++	// Set FC2580 bandwidth.
++	pTunerExtra->SetBandwidthMode(pTuner, FC2580_BANDWIDTH_6MHZ);
++
++
++
++
++
++	// ==== Get tuner information =====
++
++	...
++
++	// Get FC2580 bandwidth.
++	pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode);
++
++
++
++	// See the example for other tuner functions in tuner_base.h
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++
++
++
++#include "tuner_base.h"
++
++
++
++
++
++// The following context is source code provided by FCI.
++
++
++
++
++
++// FCI source code - fc2580_driver_v1400_r.h
++
++
++/*==============================================================================
++    FILE NAME   : FC2580_driver_v1400_r.h  
++    
++    VERSION     : 1.400_r
++    
++    UPDATE      : September 22. 2008
++				
++==============================================================================*/ 
++
++/*==============================================================================
++
++  Chip ID of FC2580 is 0x56 or 0xAC(including I2C write bit)
++
++==============================================================================*/
++
++
++#define	BORDER_FREQ	2600000	//2.6GHz : The border frequency which determines whether Low VCO or High VCO is used
++#define USE_EXT_CLK	0	//0 : Use internal XTAL Oscillator / 1 : Use External Clock input
++#define OFS_RSSI 57
++
++typedef enum {
++	UHF_BAND,
++	L_BAND,
++	VHF_BAND,
++	NO_BAND
++} fc2580_band_type;
++
++typedef enum {
++	FCI_FAIL,
++	FCI_SUCCESS
++} fci_result_type;
++
++/*==============================================================================
++		i2c command write							EXTERNAL FUNCTION
++
++  This function is a generic function which write a byte into fc2580's
++ specific address.
++
++  <input parameter>
++
++  slave_id
++	i2c id of slave chip
++	type : byte
++	
++  addr
++	memory address of slave chip
++	type : byte
++
++  data
++	target data
++	type : byte
++
++==============================================================================*/
++//extern fci_result_type i2c_write( unsigned char slave_id, unsigned char addr, unsigned char *data, unsigned char n );
++
++/*==============================================================================
++		i2c command write							EXTERNAL FUNCTION
++
++  This function is a generic function which gets called to read data from
++ slave chip's target memory address.
++
++  <input parameter>
++
++  slave_id
++	i2c id of slave chip
++	type : byte
++	
++  addr
++	memory address of slave chip
++	type : byte
++
++  <return value>
++  data
++	a byte of data read out of target address 'addr' of slave chip
++	type : byte
++
++==============================================================================*/
++//extern fci_result_type i2c_read( unsigned char slave_id, unsigned char addr, unsigned char *read_data, unsigned char n );
++
++/*==============================================================================
++		milisecond delay function					EXTERNAL FUNCTION
++
++  This function is a generic function which write a byte into fc2580's
++ specific address.
++
++  <input parameter>
++
++  a
++	length of wanted delay in milisecond unit
++
++==============================================================================*/
++extern void wait_msec(TUNER_MODULE *pTuner, int a);
++
++
++
++/*==============================================================================
++       fc2580 i2c command write
++
++  This function is a generic function which write a byte into fc2580's
++ specific address.
++
++  <input parameter>
++
++  addr
++	fc2580's memory address
++	type : byte
++
++  data
++	target data
++	type : byte
++
++==============================================================================*/
++fci_result_type fc2580_i2c_write( TUNER_MODULE *pTuner, unsigned char addr, unsigned char data );
++
++/*==============================================================================
++       fc2580 i2c data read
++
++  This function is a generic function which gets called to read data from
++ fc2580's target memory address.
++
++  <input parameter>
++
++  addr
++	fc2580's memory address
++	type : byte
++
++
++  <return value>
++  data
++	a byte of data read out of target address 'addr'
++	type : byte
++
++==============================================================================*/
++fci_result_type fc2580_i2c_read( TUNER_MODULE *pTuner, unsigned char addr, unsigned char *read_data );
++
++/*==============================================================================
++       fc2580 initial setting
++
++  This function is a generic function which gets called to initialize
++
++  fc2580 in DVB-H mode or L-Band TDMB mode
++
++  <input parameter>
++
++  ifagc_mode
++    type : integer
++	1 : Internal AGC
++	2 : Voltage Control Mode
++
++==============================================================================*/
++fci_result_type fc2580_set_init( TUNER_MODULE *pTuner, int ifagc_mode, unsigned int freq_xtal );
++
++/*==============================================================================
++       fc2580 frequency setting
++
++  This function is a generic function which gets called to change LO Frequency
++
++  of fc2580 in DVB-H mode or L-Band TDMB mode
++
++  <input parameter>
++
++  f_lo
++	Value of target LO Frequency in 'kHz' unit
++	ex) 2.6GHz = 2600000
++
++==============================================================================*/
++fci_result_type fc2580_set_freq( TUNER_MODULE *pTuner, unsigned int f_lo, unsigned int freq_xtal );
++
++
++/*==============================================================================
++       fc2580 filter BW setting
++
++  This function is a generic function which gets called to change Bandwidth
++
++  frequency of fc2580's channel selection filter
++
++  <input parameter>
++
++  filter_bw
++    1 : 1.53MHz(TDMB)
++	6 : 6MHz
++	7 : 7MHz
++	8 : 7.8MHz
++
++
++==============================================================================*/
++fci_result_type fc2580_set_filter( TUNER_MODULE *pTuner, unsigned char filter_bw, unsigned int freq_xtal );
++
++/*==============================================================================
++       fc2580 RSSI function
++
++  This function is a generic function which returns fc2580's
++  
++  current RSSI value.
++
++  
++  
++
++==============================================================================*/
++//int fc2580_get_rssi(void); 
++
++/*==============================================================================
++       fc2580 Xtal frequency Setting
++
++  This function is a generic function which sets 
++  
++  the frequency of xtal.
++  
++  <input parameter>
++  
++  frequency
++  	frequency value of internal(external) Xtal(clock) in kHz unit.
++
++==============================================================================*/
++//void fc2580_set_freq_xtal(unsigned int frequency);
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// The following context is FC2580 tuner API source code
++
++
++
++
++
++// Definitions
++
++// AGC mode
++enum FC2580_AGC_MODE
++{
++	FC2580_AGC_INTERNAL = 1,
++	FC2580_AGC_EXTERNAL = 2,
++};
++
++
++// Bandwidth mode
++enum FC2580_BANDWIDTH_MODE
++{
++	FC2580_BANDWIDTH_1530000HZ = 1,
++	FC2580_BANDWIDTH_6000000HZ = 6,
++	FC2580_BANDWIDTH_7000000HZ = 7,
++	FC2580_BANDWIDTH_8000000HZ = 8,
++};
++
++
++
++
++
++// FC2580 extra module
++typedef struct FC2580_EXTRA_MODULE_TAG FC2580_EXTRA_MODULE;
++
++
++
++
++
++// FC2580 bandwidth mode setting function pointer
++typedef int
++(*FC2580_FP_SET_BANDWIDTH_MODE)(
++	TUNER_MODULE *pTuner,
++	int BandwidthMode
++	);
++
++
++
++// FC2580 bandwidth mode getting function pointer
++typedef int
++(*FC2580_FP_GET_BANDWIDTH_MODE)(
++	TUNER_MODULE *pTuner,
++	int *pBandwidthMode
++	);
++
++
++
++
++
++// FC2580 extra module
++struct FC2580_EXTRA_MODULE_TAG
++{
++	// FC2580 extra variables
++	unsigned long CrystalFreqHz;
++	int AgcMode;
++	int BandwidthMode;
++	int IsBandwidthModeSet;
++
++	// FC2580 extra function pointers
++	FC2580_FP_SET_BANDWIDTH_MODE   SetBandwidthMode;
++	FC2580_FP_GET_BANDWIDTH_MODE   GetBandwidthMode;
++};
++
++
++
++
++
++// Builder
++void
++BuildFc2580Module(
++	TUNER_MODULE **ppTuner,
++	TUNER_MODULE *pTunerModuleMemory,
++	FC2580_EXTRA_MODULE *pFc2580ExtraModuleMemory,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory,
++	unsigned char DeviceAddr,
++	unsigned long CrystalFreqHz,
++	int AgcMode
++	);
++
++
++
++
++
++// Manipulaing functions
++void
++fc2580_GetTunerType(
++	TUNER_MODULE *pTuner,
++	int *pTunerType
++	);
++
++void
++fc2580_GetDeviceAddr(
++	TUNER_MODULE *pTuner,
++	unsigned char *pDeviceAddr
++	);
++
++int
++fc2580_Initialize(
++	TUNER_MODULE *pTuner
++	);
++
++int
++fc2580_SetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long RfFreqHz
++	);
++
++int
++fc2580_GetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long *pRfFreqHz
++	);
++
++
++
++
++
++// Extra manipulaing functions
++int
++fc2580_SetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int BandwidthMode
++	);
++
++int
++fc2580_GetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int *pBandwidthMode
++	);
++
++
++
++
++
++// I2C birdge module demod argument setting
++void
++fc2580_SetI2cBridgeModuleTunerArg(
++	TUNER_MODULE *pTuner
++	);
++
++
++
++
++
++
++
++
++
++
++
++
++
++#endif
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/tuner_mt2266.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/tuner_mt2266.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,3331 @@
++/**
++
++@file
++
++@brief   MT2266 tuner module definition
++
++One can manipulate MT2266 tuner through MT2266 module.
++MT2266 module is derived from tuner module.
++
++*/
++
++
++#include "tuner_mt2266.h"
++
++
++
++
++
++/**
++
++@brief   MT2266 tuner module builder
++
++Use BuildMt2266Module() to build MT2266 module, set all module function pointers with the corresponding functions,
++and initialize module private variables.
++
++
++@param [in]   ppTuner                      Pointer to MT2266 tuner module pointer
++@param [in]   pTunerModuleMemory           Pointer to an allocated tuner module memory
++@param [in]   pMt2266ExtraModuleMemory     Pointer to an allocated MT2266 extra module memory
++@param [in]   pBaseInterfaceModuleMemory   Pointer to an allocated base interface module memory
++@param [in]   pI2cBridgeModuleMemory       Pointer to an allocated I2C bridge module memory
++@param [in]   DeviceAddr                   MT2266 I2C device address
++
++
++@note
++	-# One should call BuildMt2266Module() to build MT2266 module before using it.
++
++*/
++void
++BuildMt2266Module(
++	TUNER_MODULE **ppTuner,
++	TUNER_MODULE *pTunerModuleMemory,
++	MT2266_EXTRA_MODULE *pMt2266ExtraModuleMemory,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory,
++	unsigned char DeviceAddr
++	)
++{
++	TUNER_MODULE *pTuner;
++	MT2266_EXTRA_MODULE *pExtra;
++
++
++
++	// Set tuner module pointer.
++	*ppTuner = pTunerModuleMemory;
++
++	// Get tuner module.
++	pTuner = *ppTuner;
++
++	// Set tuner extra module pointer, base interface module pointer, and I2C bridge module pointer.
++	pTuner->pExtra         = pMt2266ExtraModuleMemory;
++	pTuner->pBaseInterface = pBaseInterfaceModuleMemory;
++	pTuner->pI2cBridge     = pI2cBridgeModuleMemory;
++
++	// Get tuner extra module.
++	pExtra = (MT2266_EXTRA_MODULE *)pTuner->pExtra;
++
++
++
++	// Set tuner type.
++	pTuner->TunerType = TUNER_TYPE_MT2266;
++
++	// Set tuner I2C device address.
++	pTuner->DeviceAddr = DeviceAddr;
++
++
++	// Initialize tuner parameter setting status.
++	pTuner->IsRfFreqHzSet = NO;
++
++
++	// Set I2C bridge tuner arguments.
++	mt2266_SetI2cBridgeModuleTunerArg(pTuner);
++
++
++	// Set tuner module manipulating function pointers.
++	pTuner->GetTunerType  = mt2266_GetTunerType;
++	pTuner->GetDeviceAddr = mt2266_GetDeviceAddr;
++
++	pTuner->Initialize    = mt2266_Initialize;
++	pTuner->SetRfFreqHz   = mt2266_SetRfFreqHz;
++	pTuner->GetRfFreqHz   = mt2266_GetRfFreqHz;
++
++
++	// Initialize tuner extra module variables.
++	pExtra->IsBandwidthHzSet = NO;
++
++	// Set tuner extra module function pointers.
++	pExtra->OpenHandle     = mt2266_OpenHandle;
++	pExtra->CloseHandle    = mt2266_CloseHandle;
++	pExtra->GetHandle      = mt2266_GetHandle;
++	pExtra->SetBandwidthHz = mt2266_SetBandwidthHz;
++	pExtra->GetBandwidthHz = mt2266_GetBandwidthHz;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_TUNER_TYPE
++
++*/
++void
++mt2266_GetTunerType(
++	TUNER_MODULE *pTuner,
++	int *pTunerType
++	)
++{
++	// Get tuner type from tuner module.
++	*pTunerType = pTuner->TunerType;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_DEVICE_ADDR
++
++*/
++void
++mt2266_GetDeviceAddr(
++	TUNER_MODULE *pTuner,
++	unsigned char *pDeviceAddr
++	)
++{
++	// Get tuner I2C device address from tuner module.
++	*pDeviceAddr = pTuner->DeviceAddr;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_INITIALIZE
++
++*/
++int
++mt2266_Initialize(
++	TUNER_MODULE *pTuner
++	)
++{
++	MT2266_EXTRA_MODULE *pExtra;
++
++	Handle_t DeviceHandle;
++	UData_t Status;
++
++
++
++	// Get tuner extra module.
++	pExtra = (MT2266_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get tuner handle.
++	DeviceHandle = pExtra->DeviceHandle;
++
++
++	// Re-initialize tuner.
++	Status = MT2266_ReInit(DeviceHandle);
++
++	if(MT_IS_ERROR(Status))
++		goto error_status_initialize_tuner;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_initialize_tuner:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_SET_RF_FREQ_HZ
++
++*/
++int
++mt2266_SetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long RfFreqHz
++	)
++{
++	MT2266_EXTRA_MODULE *pExtra;
++
++	Handle_t DeviceHandle;
++	UData_t Status;
++
++
++
++	// Get tuner extra module.
++	pExtra = (MT2266_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get tuner handle.
++	DeviceHandle = pExtra->DeviceHandle;
++
++
++	// Set tuner RF frequency in Hz.
++	Status = MT2266_ChangeFreq(DeviceHandle, RfFreqHz);
++
++	if(MT_IS_ERROR(Status))
++		goto error_status_set_tuner_rf_frequency;
++
++
++	// Set tuner RF frequency parameter.
++	pTuner->RfFreqHz      = RfFreqHz;
++	pTuner->IsRfFreqHzSet = YES;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_tuner_rf_frequency:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_RF_FREQ_HZ
++
++*/
++int
++mt2266_GetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long *pRfFreqHz
++	)
++{
++	// Get tuner RF frequency in Hz from tuner module.
++	if(pTuner->IsRfFreqHzSet != YES)
++		goto error_status_get_tuner_rf_frequency;
++
++	*pRfFreqHz = pTuner->RfFreqHz;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_tuner_rf_frequency:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Open MT2266 tuner handle.
++
++*/
++int
++mt2266_OpenHandle(
++	TUNER_MODULE *pTuner
++	)
++{
++	MT2266_EXTRA_MODULE *pExtra;
++
++	unsigned char DeviceAddr;
++	UData_t Status;
++
++
++
++	// Get tuner extra module.
++	pExtra = (MT2266_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get tuner I2C device address.
++	pTuner->GetDeviceAddr(pTuner, &DeviceAddr);
++
++
++	// Open MT2266 handle.
++	// Note: 1. Must take tuner extra module DeviceHandle as handle input argument.
++	//       2. Take pTuner as user-defined data input argument.
++	Status = MT2266_Open(DeviceAddr, &pExtra->DeviceHandle, pTuner);
++
++	if(MT_IS_ERROR(Status))
++		goto error_status_open_mt2266_handle;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_open_mt2266_handle:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Close MT2266 tuner handle.
++
++*/
++int
++mt2266_CloseHandle(
++	TUNER_MODULE *pTuner
++	)
++{
++	MT2266_EXTRA_MODULE *pExtra;
++
++	Handle_t DeviceHandle;
++	UData_t Status;
++
++
++
++	// Get tuner extra module.
++	pExtra = (MT2266_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get tuner handle.
++	DeviceHandle = pExtra->DeviceHandle;
++
++
++	// Close MT2266 handle.
++	Status = MT2266_Close(DeviceHandle);
++
++	if(MT_IS_ERROR(Status))
++		goto error_status_open_mt2266_handle;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_open_mt2266_handle:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Get MT2266 tuner handle.
++
++*/
++void
++mt2266_GetHandle(
++	TUNER_MODULE *pTuner,
++	void **pDeviceHandle
++	)
++{
++	MT2266_EXTRA_MODULE *pExtra;
++
++
++
++	// Get tuner extra module.
++	pExtra = (MT2266_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get tuner handle.
++	*pDeviceHandle = pExtra->DeviceHandle;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@brief   Set MT2266 tuner bandwidth in Hz.
++
++*/
++int
++mt2266_SetBandwidthHz(
++	TUNER_MODULE *pTuner,
++	unsigned long BandwidthHz
++	)
++{
++	MT2266_EXTRA_MODULE *pExtra;
++
++	Handle_t DeviceHandle;
++	UData_t Status;
++
++
++
++	// Get tuner extra module.
++	pExtra = (MT2266_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get tuner handle.
++	DeviceHandle = pExtra->DeviceHandle;
++
++
++	// Set tuner bandwidth in Hz.
++	Status = MT2266_SetParam(DeviceHandle, MT2266_OUTPUT_BW, BandwidthHz);
++
++	if(MT_IS_ERROR(Status))
++		goto error_status_set_tuner_bandwidth;
++
++
++	// Set tuner bandwidth parameter.
++	pExtra->BandwidthHz      = BandwidthHz;
++	pExtra->IsBandwidthHzSet = YES;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_tuner_bandwidth:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Get MT2266 tuner bandwidth in Hz.
++
++*/
++int
++mt2266_GetBandwidthHz(
++	TUNER_MODULE *pTuner,
++	unsigned long *pBandwidthHz
++	)
++{
++	MT2266_EXTRA_MODULE *pExtra;
++
++
++
++	// Get tuner extra module.
++	pExtra = (MT2266_EXTRA_MODULE *)pTuner->pExtra;
++
++
++	// Get tuner bandwidth in Hz from tuner module.
++	if(pExtra->IsBandwidthHzSet != YES)
++		goto error_status_get_tuner_bandwidth;
++
++	*pBandwidthHz = pExtra->BandwidthHz;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_tuner_bandwidth:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Set I2C bridge module tuner arguments.
++
++MT2266 builder will use mt2266_SetI2cBridgeModuleTunerArg() to set I2C bridge module tuner arguments.
++
++
++@param [in]   pTuner   The tuner module pointer
++
++
++@see   BuildMt2266Module()
++
++*/
++void
++mt2266_SetI2cBridgeModuleTunerArg(
++	TUNER_MODULE *pTuner
++	)
++{
++	I2C_BRIDGE_MODULE *pI2cBridge;
++
++
++
++	// Get I2C bridge module.
++	pI2cBridge = pTuner->pI2cBridge;
++
++	// Set I2C bridge module tuner arguments.
++	pI2cBridge->pTunerDeviceAddr = &pTuner->DeviceAddr;
++
++
++	return;
++}
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// The following context is source code provided by Microtune.
++
++
++
++
++
++// Microtune source code - mt_userdef.c
++
++
++/*****************************************************************************
++**
++**  Name: mt_userdef.c
++**
++**  Description:    User-defined MicroTuner software interface 
++**
++**  Functions
++**  Requiring
++**  Implementation: MT_WriteSub
++**                  MT_ReadSub
++**                  MT_Sleep
++**
++**  References:     None
++**
++**  Exports:        None
++**
++**  CVS ID:         $Id: mt_userdef.c,v 1.2 2006/10/26 16:39:18 software Exp $
++**  CVS Source:     $Source: /export/home/cvsroot/software/tuners/MT2266/mt_userdef.c,v $
++**	               
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   03-25-2004    DAD    Original
++**
++*****************************************************************************/
++//#include "mt_userdef.h"
++
++
++/*****************************************************************************
++**
++**  Name: MT_WriteSub
++**
++**  Description:    Write values to device using a two-wire serial bus.
++**
++**  Parameters:     hUserData  - User-specific I/O parameter that was
++**                               passed to tuner's Open function.
++**                  addr       - device serial bus address  (value passed
++**                               as parameter to MTxxxx_Open)
++**                  subAddress - serial bus sub-address (Register Address)
++**                  pData      - pointer to the Data to be written to the 
++**                               device 
++**                  cnt        - number of bytes/registers to be written
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_COMM_ERR      - Serial bus communications error
++**                      user-defined
++**
++**  Notes:          This is a callback function that is called from the
++**                  the tuning algorithm.  You MUST provide code for this
++**                  function to write data using the tuner's 2-wire serial 
++**                  bus.
++**
++**                  The hUserData parameter is a user-specific argument.
++**                  If additional arguments are needed for the user's
++**                  serial bus read/write functions, this argument can be
++**                  used to supply the necessary information.
++**                  The hUserData parameter is initialized in the tuner's Open
++**                  function.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   03-25-2004    DAD    Original
++**
++*****************************************************************************/
++UData_t MT_WriteSub(Handle_t hUserData, 
++                    UData_t addr, 
++                    U8Data subAddress, 
++                    U8Data *pData, 
++                    UData_t cnt)
++{
++//    UData_t status = MT_OK;                  /* Status to be returned        */
++    /*
++    **  ToDo:  Add code here to implement a serial-bus write
++    **         operation to the MTxxxx tuner.  If successful,
++    **         return MT_OK.
++    */
++/*  return status;  */
++
++
++	TUNER_MODULE *pTuner;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	I2C_BRIDGE_MODULE *pI2cBridge;
++
++	unsigned int i, j;
++
++	unsigned char RegStartAddr;
++	unsigned char *pWritingBytes;
++	unsigned char ByteNum;
++
++	unsigned char WritingBuffer[I2C_BUFFER_LEN];
++	unsigned char WritingByteNum, WritingByteNumMax, WritingByteNumRem;
++	unsigned char RegWritingAddr;
++	unsigned char TunerDeviceAddr;	
++
++	struct dvb_usb_device	*d;
++
++	// Get tuner module, base interface, and I2C bridge.
++	pTuner         = (TUNER_MODULE *)hUserData;
++	pBaseInterface = pTuner->pBaseInterface;
++	pI2cBridge     = pTuner->pI2cBridge;
++
++	// Get tuner device address.
++	TunerDeviceAddr = *pI2cBridge->pTunerDeviceAddr;
++	
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);  //add by chialing
++
++
++	// Get regiser start address, writing bytes, and byte number.
++	RegStartAddr  = subAddress;
++	pWritingBytes = pData;
++	ByteNum       = (unsigned char)cnt;
++
++
++	// Calculate maximum writing byte number.
++	WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE;
++
++
++	// Set tuner register bytes with writing bytes.
++	// Note: Set tuner register bytes considering maximum writing byte number.
++	for(i = 0; i < ByteNum; i += WritingByteNumMax)
++	{
++		// Set register writing address.
++		RegWritingAddr = RegStartAddr + i;
++
++		// Calculate remainder writing byte number.
++		WritingByteNumRem = ByteNum - i;
++
++		// Determine writing byte number.
++		WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem;
++
++
++		// Set writing buffer.
++		// Note: The I2C format of tuner register byte setting is as follows:
++		//       start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) +
++		//       stop_bit
++//		WritingBuffer[0] = RegWritingAddr;
++
++		for(j = 0; j < WritingByteNum; j++)
++			WritingBuffer[j] = pWritingBytes[i + j];
++
++
++
++		// Set tuner register bytes with writing buffer.
++//		if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, WritingBuffer, WritingByteNum + LEN_1_BYTE) != 
++//			FUNCTION_SUCCESS)
++//			goto error_status_set_tuner_registers;
++
++		if(write_rtl2832_tuner_register( d, TunerDeviceAddr, RegWritingAddr, WritingBuffer, WritingByteNum )) goto error;
++
++	
++	}
++
++
++	return MT_OK;
++
++error:
++	
++	return MT_COMM_ERR;
++}
++
++
++/*****************************************************************************
++**
++**  Name: MT_ReadSub
++**
++**  Description:    Read values from device using a two-wire serial bus.
++**
++**  Parameters:     hUserData  - User-specific I/O parameter that was
++**                               passed to tuner's Open function.
++**                  addr       - device serial bus address  (value passed
++**                               as parameter to MTxxxx_Open)
++**                  subAddress - serial bus sub-address (Register Address)
++**                  pData      - pointer to the Data to be written to the 
++**                               device 
++**                  cnt        - number of bytes/registers to be written
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_COMM_ERR      - Serial bus communications error
++**                      user-defined
++**
++**  Notes:          This is a callback function that is called from the
++**                  the tuning algorithm.  You MUST provide code for this
++**                  function to read data using the tuner's 2-wire serial 
++**                  bus.
++**
++**                  The hUserData parameter is a user-specific argument.
++**                  If additional arguments are needed for the user's
++**                  serial bus read/write functions, this argument can be
++**                  used to supply the necessary information.
++**                  The hUserData parameter is initialized in the tuner's Open
++**                  function.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   03-25-2004    DAD    Original
++**
++*****************************************************************************/
++UData_t MT_ReadSub(Handle_t hUserData, 
++                   UData_t addr, 
++                   U8Data subAddress, 
++                   U8Data *pData, 
++                   UData_t cnt)
++{
++ //   UData_t status = MT_OK;                        /* Status to be returned        */
++
++    /*
++    **  ToDo:  Add code here to implement a serial-bus read
++    **         operation to the MTxxxx tuner.  If successful,
++    **         return MT_OK.
++    */
++/*  return status;  */
++
++
++	TUNER_MODULE *pTuner;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	I2C_BRIDGE_MODULE *pI2cBridge;
++
++	unsigned int i;
++
++	unsigned char RegStartAddr;
++	unsigned char *pReadingBytes;
++	unsigned char ByteNum;
++
++	unsigned char ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem;
++	unsigned char RegReadingAddr;
++
++	unsigned char TunerDeviceAddr;
++
++
++	struct dvb_usb_device	*d;
++
++	// Get tuner module, base interface, and I2C bridge.
++	pTuner         = (TUNER_MODULE *)hUserData;
++	pBaseInterface = pTuner->pBaseInterface;
++	pI2cBridge     = pTuner->pI2cBridge;
++
++	// Get tuner device address.
++	TunerDeviceAddr = *pI2cBridge->pTunerDeviceAddr;
++
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);
++
++
++	// Get regiser start address, writing bytes, and byte number.
++	RegStartAddr  = subAddress;
++	pReadingBytes = pData;
++	ByteNum       = (unsigned char)cnt;
++
++
++	// Calculate maximum reading byte number.
++	ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax;
++
++
++	// Get tuner register bytes.
++	// Note: Get tuner register bytes considering maximum reading byte number.
++	for(i = 0; i < ByteNum; i += ReadingByteNumMax)
++	{
++		// Set register reading address.
++		RegReadingAddr = RegStartAddr + i;
++
++		// Calculate remainder reading byte number.
++		ReadingByteNumRem = ByteNum - i;
++
++		// Determine reading byte number.
++		ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem;
++
++
++		// Set tuner register reading address.
++		// Note: The I2C format of tuner register reading address setting is as follows:
++		//       start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit
++//		if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS)
++//			goto error_status_set_tuner_register_reading_address;
++
++		// Get tuner register bytes.
++		// Note: The I2C format of tuner register byte getting is as follows:
++		//       start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit
++//		if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS)
++//			goto error_status_get_tuner_registers;
++
++		if(read_rtl2832_tuner_register(d, TunerDeviceAddr, RegReadingAddr, &pReadingBytes[i], ReadingByteNum)) goto error;
++
++	}
++
++	return MT_OK;
++
++error:
++	return MT_COMM_ERR;
++}
++
++
++/*****************************************************************************
++**
++**  Name: MT_Sleep
++**
++**  Description:    Delay execution for "nMinDelayTime" milliseconds
++**
++**  Parameters:     hUserData     - User-specific I/O parameter that was
++**                                  passed to tuner's Open function.
++**                  nMinDelayTime - Delay time in milliseconds
++**
++**  Returns:        None.
++**
++**  Notes:          This is a callback function that is called from the
++**                  the tuning algorithm.  You MUST provide code that
++**                  blocks execution for the specified period of time. 
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   03-25-2004    DAD    Original
++**
++*****************************************************************************/
++void MT_Sleep(Handle_t hUserData, 
++              UData_t nMinDelayTime)
++{
++    /*
++    **  ToDo:  Add code here to implement a OS blocking
++    **         for a period of "nMinDelayTime" milliseconds.
++    */
++
++
++	TUNER_MODULE *pTuner;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++
++
++	// Get tuner module, base interface.
++	pTuner         = (TUNER_MODULE *)hUserData;
++	pBaseInterface = pTuner->pBaseInterface;
++
++
++	// Wait nMinDelayTime milliseconds.
++	pBaseInterface->WaitMs(pBaseInterface, nMinDelayTime);
++
++
++	return;
++}
++
++
++#if defined(MT2060_CNT)
++#if MT2060_CNT > 0
++/*****************************************************************************
++**
++**  Name: MT_TunerGain  (MT2060 only)
++**
++**  Description:    Measure the relative tuner gain using the demodulator
++**
++**  Parameters:     hUserData  - User-specific I/O parameter that was
++**                               passed to tuner's Open function.
++**                  pMeas      - Tuner gain (1/100 of dB scale).
++**                               ie. 1234 = 12.34 (dB)
++**
++**  Returns:        status:
++**                      MT_OK  - No errors
++**                      user-defined errors could be set
++**
++**  Notes:          This is a callback function that is called from the
++**                  the 1st IF location routine.  You MUST provide
++**                  code that measures the relative tuner gain in a dB
++**                  (not linear) scale.  The return value is an integer
++**                  value scaled to 1/100 of a dB.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   06-16-2004    DAD    Original
++**   N/A   11-30-2004    DAD    Renamed from MT_DemodInputPower.  This name
++**                              better describes what this function does.
++**
++*****************************************************************************/
++UData_t MT_TunerGain(Handle_t hUserData,
++                     SData_t* pMeas)
++{
++    UData_t status = MT_OK;                        /* Status to be returned        */
++
++    /*
++    **  ToDo:  Add code here to return the gain / power level measured
++    **         at the input to the demodulator.
++    */
++
++
++
++    return (status);
++}
++#endif
++#endif
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// Microtune source code - mt2266.c
++
++
++
++/*****************************************************************************
++**
++**  Name: mt2266.c
++**
++**  Copyright 2007 Microtune, Inc. All Rights Reserved
++**
++**  This source code file contains confidential information and/or trade
++**  secrets of Microtune, Inc. or its affiliates and is subject to the
++**  terms of your confidentiality agreement with Microtune, Inc. or one of
++**  its affiliates, as applicable.
++**
++*****************************************************************************/
++
++/*****************************************************************************
++**
++**  Name: mt2266.c
++**
++**  Description:    Microtune MT2266 Tuner software interface.
++**                  Supports tuners with Part/Rev code: 0x85.
++**
++**  Functions
++**  Implemented:    UData_t  MT2266_Open
++**                  UData_t  MT2266_Close
++**                  UData_t  MT2266_ChangeFreq
++**                  UData_t  MT2266_GetLocked
++**                  UData_t  MT2266_GetParam
++**                  UData_t  MT2266_GetReg
++**                  UData_t  MT2266_GetUHFXFreqs
++**                  UData_t  MT2266_GetUserData
++**                  UData_t  MT2266_ReInit
++**                  UData_t  MT2266_SetParam
++**                  UData_t  MT2266_SetPowerModes
++**                  UData_t  MT2266_SetReg
++**                  UData_t  MT2266_SetUHFXFreqs
++**
++**  References:     AN-00010: MicroTuner Serial Interface Application Note
++**                  MicroTune, Inc.
++**
++**  Exports:        None
++**
++**  Dependencies:   MT_ReadSub(hUserData, IC_Addr, subAddress, *pData, cnt);
++**                  - Read byte(s) of data from the two-wire bus.
++**
++**                  MT_WriteSub(hUserData, IC_Addr, subAddress, *pData, cnt);
++**                  - Write byte(s) of data to the two-wire bus.
++**
++**                  MT_Sleep(hUserData, nMinDelayTime);
++**                  - Delay execution for x milliseconds
++**
++**  CVS ID:         $Id: mt2266.c,v 1.5 2007/10/02 18:43:17 software Exp $
++**  CVS Source:     $Source: /export/home/cvsroot/software/tuners/MT2266/mt2266.c,v $
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**   N/A   06-08-2006    JWS    Ver 1.01: Corrected problem with tuner ID check
++**   N/A   11-01-2006    RSK    Ver 1.02: Adding multiple-filter support
++**                                        as well as Get/Set functions.
++**   N/A   11-29-2006    DAD    Ver 1.03: Parenthesis clarification for gcc
++**   N/A   12-20-2006    RSK    Ver 1.04: Adding fLO_FractionalTerm() usage.
++**   118   05-09-2007    RSK    Ver 1.05: Adding Standard MTxxxx_Tune() API.
++**
++*****************************************************************************/
++//#include "mt2266.h"
++//#include <stdlib.h>                     /* for NULL */
++#define MT_NULL			0
++
++/*  Version of this module                          */
++#define VERSION 10005             /*  Version 01.05 */
++
++
++#ifndef MT2266_CNT
++#error You must define MT2266_CNT in the "mt_userdef.h" file
++#endif
++
++/*
++**  Normally, the "reg" array in the tuner structure is used as a cache
++**  containing the current value of the tuner registers.  If the user's
++**  application MUST change tuner registers without using the MT2266_SetReg
++**  routine provided, he may compile this code with the __NO_CACHE__
++**  variable defined.
++**  The PREFETCH macro will insert code code to re-read tuner registers if
++**  __NO_CACHE__ is defined.  If it is not defined (normal) then PREFETCH
++**  does nothing.
++*/
++
++#if defined(__NO_CACHE__)
++#define PREFETCH(var, cnt) \
++    if (MT_NO_ERROR(status)) \
++    status |= MT_ReadSub(pInfo->hUserData, pInfo->address, (var), &pInfo->reg[(var)], (cnt));
++#else
++#define PREFETCH(var, cnt)
++#endif
++
++
++
++/*
++**  Two-wire serial bus subaddresses of the tuner registers.
++**  Also known as the tuner's register addresses.
++*/
++enum MT2266_Register_Offsets
++{
++    MT2266_PART_REV = 0,   /*  0x00 */
++    MT2266_LO_CTRL_1,      /*  0x01 */
++    MT2266_LO_CTRL_2,      /*  0x02 */
++    MT2266_LO_CTRL_3,      /*  0x03 */
++    MT2266_SMART_ANT,      /*  0x04 */
++    MT2266_BAND_CTRL,      /*  0x05 */
++    MT2266_CLEARTUNE,      /*  0x06 */
++    MT2266_IGAIN,          /*  0x07 */
++    MT2266_BBFILT_1,       /*  0x08 */
++    MT2266_BBFILT_2,       /*  0x09 */
++    MT2266_BBFILT_3,       /*  0x0A */
++    MT2266_BBFILT_4,       /*  0x0B */
++    MT2266_BBFILT_5,       /*  0x0C */
++    MT2266_BBFILT_6,       /*  0x0D */
++    MT2266_BBFILT_7,       /*  0x0E */
++    MT2266_BBFILT_8,       /*  0x0F */
++    MT2266_RCC_CTRL,       /*  0x10 */
++    MT2266_RSVD_11,        /*  0x11 */
++    MT2266_STATUS_1,       /*  0x12 */
++    MT2266_STATUS_2,       /*  0x13 */
++    MT2266_STATUS_3,       /*  0x14 */
++    MT2266_STATUS_4,       /*  0x15 */
++    MT2266_STATUS_5,       /*  0x16 */
++    MT2266_SRO_CTRL,       /*  0x17 */
++    MT2266_RSVD_18,        /*  0x18 */
++    MT2266_RSVD_19,        /*  0x19 */
++    MT2266_RSVD_1A,        /*  0x1A */
++    MT2266_RSVD_1B,        /*  0x1B */
++    MT2266_ENABLES,        /*  0x1C */
++    MT2266_RSVD_1D,        /*  0x1D */
++    MT2266_RSVD_1E,        /*  0x1E */
++    MT2266_RSVD_1F,        /*  0x1F */
++    MT2266_GPO,            /*  0x20 */
++    MT2266_RSVD_21,        /*  0x21 */
++    MT2266_RSVD_22,        /*  0x22 */
++    MT2266_RSVD_23,        /*  0x23 */
++    MT2266_RSVD_24,        /*  0x24 */
++    MT2266_RSVD_25,        /*  0x25 */
++    MT2266_RSVD_26,        /*  0x26 */
++    MT2266_RSVD_27,        /*  0x27 */
++    MT2266_RSVD_28,        /*  0x28 */
++    MT2266_RSVD_29,        /*  0x29 */
++    MT2266_RSVD_2A,        /*  0x2A */
++    MT2266_RSVD_2B,        /*  0x2B */
++    MT2266_RSVD_2C,        /*  0x2C */
++    MT2266_RSVD_2D,        /*  0x2D */
++    MT2266_RSVD_2E,        /*  0x2E */
++    MT2266_RSVD_2F,        /*  0x2F */
++    MT2266_RSVD_30,        /*  0x30 */
++    MT2266_RSVD_31,        /*  0x31 */
++    MT2266_RSVD_32,        /*  0x32 */
++    MT2266_RSVD_33,        /*  0x33 */
++    MT2266_RSVD_34,        /*  0x34 */
++    MT2266_RSVD_35,        /*  0x35 */
++    MT2266_RSVD_36,        /*  0x36 */
++    MT2266_RSVD_37,        /*  0x37 */
++    MT2266_RSVD_38,        /*  0x38 */
++    MT2266_RSVD_39,        /*  0x39 */
++    MT2266_RSVD_3A,        /*  0x3A */
++    MT2266_RSVD_3B,        /*  0x3B */
++    MT2266_RSVD_3C,        /*  0x3C */
++    END_REGS
++};
++
++/*
++** DefaultsEntry points to an array of U8Data used to initialize
++** various registers (the first byte is the starting subaddress)
++** and a count of the bytes (including subaddress) in the array.
++**
++** DefaultsList is an array of DefaultsEntry elements terminated
++** by an entry with a NULL pointer for the data array.
++*/
++typedef struct MT2266_DefaultsEntryTag
++{
++    U8Data *data;
++    UData_t cnt;
++} MT2266_DefaultsEntry;
++
++typedef MT2266_DefaultsEntry MT2266_DefaultsList[];
++
++#define DEF_LIST_ENTRY(a) {a, sizeof(a)/sizeof(U8Data) - 1}
++#define END_DEF_LIST {0,0}
++
++/*
++** Constants used by the tuning algorithm
++*/
++                                        /* REF_FREQ is now the actual crystal frequency */
++#define REF_FREQ          (30000000UL)  /* Reference oscillator Frequency (in Hz) */
++#define TUNE_STEP_SIZE          (50UL)  /* Tune in steps of 50 kHz */
++#define MIN_UHF_FREQ     (350000000UL)  /* Minimum UHF frequency (in Hz) */
++#define MAX_UHF_FREQ     (900000000UL)  /* Maximum UHF frequency (in Hz) */
++#define MIN_VHF_FREQ     (174000000UL)  /* Minimum VHF frequency (in Hz) */
++#define MAX_VHF_FREQ     (230000000UL)  /* Maximum VHF frequency (in Hz) */
++#define OUTPUT_BW          (8000000UL)  /* Output channel bandwidth (in Hz) */
++#define UHF_DEFAULT_FREQ (600000000UL)  /* Default UHF input frequency (in Hz) */
++
++
++/*
++**  The number of Tuner Registers
++*/
++static const UData_t Num_Registers = END_REGS;
++
++/*
++**  Crossover Frequency sets for 2 filters, without and with attenuation.
++*/
++typedef struct
++{
++    MT2266_XFreq_Set    xfreq[ MT2266_NUMBER_OF_XFREQ_SETS ];
++
++}  MT2266_XFreqs_t;
++
++
++MT2266_XFreqs_t MT2266_default_XFreqs =
++{
++    /*  xfreq  */
++    {
++        /*  uhf0  */
++        {                                /*          < 0 MHz: 15+1 */
++            0UL,                         /*    0 ..    0 MHz: 15 */
++            0UL,                         /*    0 ..  443 MHz: 14 */
++            443000 / TUNE_STEP_SIZE,     /*  443 ..  470 MHz: 13 */
++            470000 / TUNE_STEP_SIZE,     /*  470 ..  496 MHz: 12 */
++            496000 / TUNE_STEP_SIZE,     /*  496 ..  525 MHz: 11 */
++            525000 / TUNE_STEP_SIZE,     /*  525 ..  552 MHz: 10 */
++            552000 / TUNE_STEP_SIZE,     /*  552 ..  580 MHz:  9 */
++            580000 / TUNE_STEP_SIZE,     /*  580 ..  657 MHz:  8 */
++            657000 / TUNE_STEP_SIZE,     /*  657 ..  682 MHz:  7 */
++            682000 / TUNE_STEP_SIZE,     /*  682 ..  710 MHz:  6 */
++            710000 / TUNE_STEP_SIZE,     /*  710 ..  735 MHz:  5 */
++            735000 / TUNE_STEP_SIZE,     /*  735 ..  763 MHz:  4 */
++            763000 / TUNE_STEP_SIZE,     /*  763 ..  802 MHz:  3 */
++            802000 / TUNE_STEP_SIZE,     /*  802 ..  840 MHz:  2 */
++            840000 / TUNE_STEP_SIZE,     /*  840 ..  877 MHz:  1 */
++            877000 / TUNE_STEP_SIZE      /*  877+        MHz:  0 */
++        },
++
++        /*  uhf1  */
++        {                                /*        < 443 MHz: 15+1 */
++            443000 / TUNE_STEP_SIZE,     /*  443 ..  470 MHz: 15 */
++            470000 / TUNE_STEP_SIZE,     /*  470 ..  496 MHz: 14 */
++            496000 / TUNE_STEP_SIZE,     /*  496 ..  525 MHz: 13 */
++            525000 / TUNE_STEP_SIZE,     /*  525 ..  552 MHz: 12 */
++            552000 / TUNE_STEP_SIZE,     /*  552 ..  580 MHz: 11 */
++            580000 / TUNE_STEP_SIZE,     /*  580 ..  605 MHz: 10 */
++            605000 / TUNE_STEP_SIZE,     /*  605 ..  632 MHz:  9 */
++            632000 / TUNE_STEP_SIZE,     /*  632 ..  657 MHz:  8 */
++            657000 / TUNE_STEP_SIZE,     /*  657 ..  682 MHz:  7 */
++            682000 / TUNE_STEP_SIZE,     /*  682 ..  710 MHz:  6 */
++            710000 / TUNE_STEP_SIZE,     /*  710 ..  735 MHz:  5 */
++            735000 / TUNE_STEP_SIZE,     /*  735 ..  763 MHz:  4 */
++            763000 / TUNE_STEP_SIZE,     /*  763 ..  802 MHz:  3 */
++            802000 / TUNE_STEP_SIZE,     /*  802 ..  840 MHz:  2 */
++            840000 / TUNE_STEP_SIZE,     /*  840 ..  877 MHz:  1 */
++            877000 / TUNE_STEP_SIZE      /*  877+        MHz:  0 */
++        },
++
++        /*  uhf0_a  */
++        {                                /*        <   0 MHz: 15+1 */
++            0UL,                         /*    0 ..    0 MHz: 15 */
++            0UL,                         /*    0 ..  442 MHz: 14 */
++            442000 / TUNE_STEP_SIZE,     /*  442 ..  472 MHz: 13 */
++            472000 / TUNE_STEP_SIZE,     /*  472 ..  505 MHz: 12 */
++            505000 / TUNE_STEP_SIZE,     /*  505 ..  535 MHz: 11 */
++            535000 / TUNE_STEP_SIZE,     /*  535 ..  560 MHz: 10 */
++            560000 / TUNE_STEP_SIZE,     /*  560 ..  593 MHz:  9 */
++            593000 / TUNE_STEP_SIZE,     /*  593 ..  673 MHz:  8 */
++            673000 / TUNE_STEP_SIZE,     /*  673 ..  700 MHz:  7 */
++            700000 / TUNE_STEP_SIZE,     /*  700 ..  727 MHz:  6 */
++            727000 / TUNE_STEP_SIZE,     /*  727 ..  752 MHz:  5 */
++            752000 / TUNE_STEP_SIZE,     /*  752 ..  783 MHz:  4 */
++            783000 / TUNE_STEP_SIZE,     /*  783 ..  825 MHz:  3 */
++            825000 / TUNE_STEP_SIZE,     /*  825 ..  865 MHz:  2 */
++            865000 / TUNE_STEP_SIZE,     /*  865 ..  905 MHz:  1 */
++            905000 / TUNE_STEP_SIZE      /*  905+        MHz:  0 */
++        },
++
++        /*  uhf1_a  */
++        {                                /*        < 442 MHz: 15+1 */
++            442000 / TUNE_STEP_SIZE,     /*  442 ..  472 MHz: 15 */
++            472000 / TUNE_STEP_SIZE,     /*  472 ..  505 MHz: 14 */
++            505000 / TUNE_STEP_SIZE,     /*  505 ..  535 MHz: 13 */
++            535000 / TUNE_STEP_SIZE,     /*  535 ..  560 MHz: 12 */
++            560000 / TUNE_STEP_SIZE,     /*  560 ..  593 MHz: 11 */
++            593000 / TUNE_STEP_SIZE,     /*  593 ..  620 MHz: 10 */
++            620000 / TUNE_STEP_SIZE,     /*  620 ..  647 MHz:  9 */
++            647000 / TUNE_STEP_SIZE,     /*  647 ..  673 MHz:  8 */
++            673000 / TUNE_STEP_SIZE,     /*  673 ..  700 MHz:  7 */
++            700000 / TUNE_STEP_SIZE,     /*  700 ..  727 MHz:  6 */
++            727000 / TUNE_STEP_SIZE,     /*  727 ..  752 MHz:  5 */
++            752000 / TUNE_STEP_SIZE,     /*  752 ..  783 MHz:  4 */
++            783000 / TUNE_STEP_SIZE,     /*  783 ..  825 MHz:  3 */
++            825000 / TUNE_STEP_SIZE,     /*  825 ..  865 MHz:  2 */
++            865000 / TUNE_STEP_SIZE,     /*  865 ..  905 MHz:  1 */
++            905000 / TUNE_STEP_SIZE      /*  905+        MHz:  0 */
++        }
++    }
++};
++
++typedef struct
++{
++    Handle_t    handle;
++    Handle_t    hUserData;
++    UData_t     address;
++    UData_t     version;
++    UData_t     tuner_id;
++    UData_t     f_Ref;
++    UData_t     f_Step;
++    UData_t     f_in;
++    UData_t     f_LO;
++    UData_t     f_bw;
++    UData_t     band;
++    UData_t     num_regs;
++    U8Data      RC2_Value;
++    U8Data      RC2_Nominal;
++    U8Data      reg[END_REGS];
++
++    MT2266_XFreqs_t xfreqs;
++
++}  MT2266_Info_t;
++
++static UData_t nMaxTuners = MT2266_CNT;
++static MT2266_Info_t MT2266_Info[MT2266_CNT];
++static MT2266_Info_t *Avail[MT2266_CNT];
++static UData_t nOpenTuners = 0;
++
++/*
++**  Constants used to write a minimal set of registers when changing bands.
++**  If the user wants a total reset, they should call MT2266_Open() again.
++**  Skip 01, 02, 03, 04  (get overwritten anyways)
++**  Write 05
++**  Skip 06 - 18
++**  Write 19   (diff for L-Band)
++**  Skip 1A 1B 1C
++**  Write 1D - 2B
++**  Skip 2C - 3C
++*/
++
++static U8Data MT2266_VHF_defaults1[] =
++{
++    0x05,              /* address 0xC0, reg 0x05 */
++    0x04,              /* Reg 0x05 LBANDen = 1 (that's right)*/
++};
++static U8Data MT2266_VHF_defaults2[] =
++{
++    0x19,              /* address 0xC0, reg 0x19 */
++    0x61,              /* Reg 0x19 CAPto = 3*/
++};
++static U8Data MT2266_VHF_defaults3[] =
++{
++    0x1D,              /* address 0xC0, reg 0x1D */
++    0xFE,              /* reg 0x1D */
++    0x00,              /* reg 0x1E */
++    0x00,              /* reg 0x1F */
++    0xB4,              /* Reg 0x20 GPO = 1*/
++    0x03,              /* Reg 0x21 LBIASen = 1, UBIASen = 1*/
++    0xA5,              /* Reg 0x22 */
++    0xA5,              /* Reg 0x23 */
++    0xA5,              /* Reg 0x24 */
++    0xA5,              /* Reg 0x25 */
++    0x82,              /* Reg 0x26 CASCM = b0001 (bits reversed)*/
++    0xAA,              /* Reg 0x27 */
++    0xF1,              /* Reg 0x28 */
++    0x17,              /* Reg 0x29 */
++    0x80,              /* Reg 0x2A MIXbiasen = 1*/
++    0x1F,              /* Reg 0x2B */
++};
++
++static MT2266_DefaultsList MT2266_VHF_defaults = {
++    DEF_LIST_ENTRY(MT2266_VHF_defaults1),
++    DEF_LIST_ENTRY(MT2266_VHF_defaults2),
++    DEF_LIST_ENTRY(MT2266_VHF_defaults3),
++    END_DEF_LIST
++};
++
++static U8Data MT2266_UHF_defaults1[] =
++{
++    0x05,              /* address 0xC0, reg 0x05 */
++    0x52,              /* Reg 0x05 */
++};
++static U8Data MT2266_UHF_defaults2[] =
++{
++    0x19,              /* address 0xC0, reg 0x19 */
++    0x61,              /* Reg 0x19 CAPto = 3*/
++};
++static U8Data MT2266_UHF_defaults3[] =
++{
++    0x1D,              /* address 0xC0, reg 0x1D */
++    0xDC,              /* Reg 0x1D */
++    0x00,              /* Reg 0x1E */
++    0x0A,              /* Reg 0x1F */
++    0xD4,              /* Reg 0x20 GPO = 1*/
++    0x03,              /* Reg 0x21 LBIASen = 1, UBIASen = 1*/
++    0x64,              /* Reg 0x22 */
++    0x64,              /* Reg 0x23 */
++    0x64,              /* Reg 0x24 */
++    0x64,              /* Reg 0x25 */
++    0x22,              /* Reg 0x26 CASCM = b0100 (bits reversed)*/
++    0xAA,              /* Reg 0x27 */
++    0xF2,              /* Reg 0x28 */
++    0x1E,              /* Reg 0x29 */
++    0x80,              /* Reg 0x2A MIXbiasen = 1*/
++    0x14,              /* Reg 0x2B */
++};
++
++static MT2266_DefaultsList MT2266_UHF_defaults = {
++    DEF_LIST_ENTRY(MT2266_UHF_defaults1),
++    DEF_LIST_ENTRY(MT2266_UHF_defaults2),
++    DEF_LIST_ENTRY(MT2266_UHF_defaults3),
++    END_DEF_LIST
++};
++
++
++static UData_t UncheckedSet(MT2266_Info_t* pInfo,
++                            U8Data         reg,
++                            U8Data         val);
++
++static UData_t UncheckedGet(MT2266_Info_t* pInfo,
++                            U8Data   reg,
++                            U8Data*  val);
++
++
++/******************************************************************************
++**
++**  Name: MT2266_Open
++**
++**  Description:    Initialize the tuner's register values.
++**
++**  Parameters:     MT2266_Addr  - Serial bus address of the tuner.
++**                  hMT2266      - 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
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**   N/A   11-01-2006    RSK    Ver 1.02: Initialize Crossover Tables to Default
++**
++******************************************************************************/
++UData_t MT2266_Open(UData_t MT2266_Addr,
++                    Handle_t* hMT2266,
++                    Handle_t hUserData)
++{
++    UData_t status = MT_OK;             /*  Status to be returned.  */
++    SData_t i, j;
++    MT2266_Info_t* pInfo = MT_NULL;
++
++    /*  Check the argument before using  */
++    if (hMT2266 == MT_NULL)
++        return MT_ARG_NULL;
++    *hMT2266 = MT_NULL;
++
++    /*
++    **  If this is our first tuner, initialize the address fields and
++    **  the list of available control blocks.
++    */
++    if (nOpenTuners == 0)
++    {
++        for (i=MT2266_CNT-1; i>=0; i--)
++        {
++            MT2266_Info[i].handle = MT_NULL;
++            MT2266_Info[i].address = MAX_UDATA;
++            MT2266_Info[i].hUserData = MT_NULL;
++
++            /* Reset the UHF Crossover Frequency tables on open/init. */
++            for (j=0; j< MT2266_NUM_XFREQS; j++ )
++            {
++                MT2266_Info[i].xfreqs.xfreq[MT2266_UHF0][j]       = MT2266_default_XFreqs.xfreq[MT2266_UHF0][j];
++                MT2266_Info[i].xfreqs.xfreq[MT2266_UHF1][j]       = MT2266_default_XFreqs.xfreq[MT2266_UHF1][j];
++                MT2266_Info[i].xfreqs.xfreq[MT2266_UHF0_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF0_ATTEN][j];
++                MT2266_Info[i].xfreqs.xfreq[MT2266_UHF1_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF1_ATTEN][j];
++            }
++
++            Avail[i] = &MT2266_Info[i];
++        }
++    }
++
++    /*
++    **  Look for an existing MT2266_State_t entry with this address.
++    */
++    for (i=MT2266_CNT-1; i>=0; i--)
++    {
++        /*
++        **  If an open'ed handle provided, we'll re-initialize that structure.
++        **
++        **  We recognize an open tuner because the address and hUserData are
++        **  the same as one that has already been opened
++        */
++        if ((MT2266_Info[i].address == MT2266_Addr) &&
++            (MT2266_Info[i].hUserData == hUserData))
++        {
++            pInfo = &MT2266_Info[i];
++            break;
++        }
++    }
++
++    /*  If not found, choose an empty spot.  */
++    if (pInfo == MT_NULL)
++    {
++        /*  Check to see that we're not over-allocating.  */
++        if (nOpenTuners == MT2266_CNT)
++            return MT_TUNER_CNT_ERR;
++
++        /* Use the next available block from the list */
++        pInfo = Avail[nOpenTuners];
++        nOpenTuners++;
++    }
++
++    pInfo->handle = (Handle_t) pInfo;
++    pInfo->hUserData = hUserData;
++    pInfo->address = MT2266_Addr;
++
++//    status |= MT2266_ReInit((Handle_t) pInfo);
++
++    if (MT_IS_ERROR(status))
++        MT2266_Close((Handle_t) pInfo);
++    else
++        *hMT2266 = pInfo->handle;
++
++    return (status);
++}
++
++
++static UData_t IsValidHandle(MT2266_Info_t* handle)
++{
++    return ((handle != MT_NULL) && (handle->handle == handle)) ? 1 : 0;
++}
++
++
++/******************************************************************************
++**
++**  Name: MT2266_Close
++**
++**  Description:    Release the handle to the tuner.
++**
++**  Parameters:     hMT2266      - Handle to the MT2266 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
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++******************************************************************************/
++UData_t MT2266_Close(Handle_t hMT2266)
++{
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) hMT2266;
++
++    if (!IsValidHandle(pInfo))
++        return MT_INV_HANDLE;
++
++    /* Remove the tuner from our list of tuners */
++    pInfo->handle = MT_NULL;
++    pInfo->address = MAX_UDATA;
++    pInfo->hUserData = MT_NULL;
++    nOpenTuners--;
++    Avail[nOpenTuners] = pInfo; /* Return control block to available list */
++
++    return MT_OK;
++}
++
++
++/******************************************************************************
++**
++**  Name: Run_BB_RC_Cal2
++**
++**  Description:    Run Base Band RC Calibration (Method 2)
++**                  MT2266 B0 only, others return MT_OK
++**
++**  Parameters:     hMT2266      - Handle to the MT2266 tuner
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_COMM_ERR      - Serial bus communications error
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**
++**  Dependencies:   mt_errordef.h - definition of error codes
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++******************************************************************************/
++static UData_t Run_BB_RC_Cal2(Handle_t h)
++{
++    UData_t status = MT_OK;                  /* Status to be returned */
++    U8Data tmp_rcc;
++    U8Data dumy;
++
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status |= MT_INV_HANDLE;
++
++    /*
++    ** Set the crystal frequency in the calibration register
++    ** and enable RC calibration #2
++    */
++    PREFETCH(MT2266_RCC_CTRL, 1);  /* Fetch register(s) if __NO_CACHE__ defined */
++    tmp_rcc = pInfo->reg[MT2266_RCC_CTRL];
++    if (pInfo->f_Ref < (36000000 /*/ TUNE_STEP_SIZE*/))
++        tmp_rcc = (tmp_rcc & 0xDF) | 0x10;
++    else
++        tmp_rcc |= 0x30;
++    status |= UncheckedSet(pInfo, MT2266_RCC_CTRL, tmp_rcc);
++
++    /*  Read RC Calibration value  */
++    status |= UncheckedGet(pInfo, MT2266_STATUS_4, &dumy);
++
++    /* Disable RC Cal 2 */
++    status |= UncheckedSet(pInfo, MT2266_RCC_CTRL, pInfo->reg[MT2266_RCC_CTRL] & 0xEF);
++
++    /* Store RC Cal 2 value */
++    pInfo->RC2_Value = pInfo->reg[MT2266_STATUS_4];
++
++    if (pInfo->f_Ref < (36000000 /*/ TUNE_STEP_SIZE*/))
++        pInfo->RC2_Nominal = (U8Data) ((pInfo->f_Ref + 77570) / 155139);
++    else
++        pInfo->RC2_Nominal = (U8Data) ((pInfo->f_Ref + 93077) / 186154);
++
++    return (status);
++}
++
++
++/******************************************************************************
++**
++**  Name: Set_BBFilt
++**
++**  Description:    Set Base Band Filter bandwidth
++**                  Based on SRO frequency & BB RC Calibration
++**                  User stores channel bw as 5-8 MHz.  This routine
++**                  calculates a 3 dB corner bw based on 1/2 the bandwidth
++**                  and a bandwidth related constant.
++**
++**  Parameters:     hMT2266      - Handle to the MT2266 tuner
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_COMM_ERR      - Serial bus communications error
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**
++**  Dependencies:   mt_errordef.h - definition of error codes
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++******************************************************************************/
++static UData_t Set_BBFilt(Handle_t h)
++{
++    UData_t f_3dB_bw;
++    U8Data BBFilt = 0;
++    U8Data Sel = 0;
++    SData_t TmpFilt;
++    SData_t i;
++    UData_t status = MT_OK;                  /* Status to be returned */
++
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status |= MT_INV_HANDLE;
++
++	/* Check RC2_Value value */
++	if(pInfo->RC2_Value == 0)
++		return MT_UNKNOWN;
++
++    /*
++    ** Convert the channel bandwidth into a 3 dB bw by dividing it by 2
++    ** and subtracting 300, 250, 200, or 0 kHz based on 8, 7, 6, 5 MHz
++    ** channel bandwidth.
++    */
++    f_3dB_bw = (pInfo->f_bw / 2);  /* bw -> bw/2 */
++    if (pInfo->f_bw > 7500000)
++    {
++        /*  >3.75 MHz corner  */
++        f_3dB_bw -= 300000;
++        Sel = 0x00;
++        TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 81;
++    }
++    else if (pInfo->f_bw > 6500000)
++    {
++        /*  >3.25 MHz .. 3.75 MHz corner  */
++        f_3dB_bw -= 250000;
++        Sel = 0x00;
++        TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 81;
++    }
++    else if (pInfo->f_bw > 5500000)
++    {
++        /*  >2.75 MHz .. 3.25 MHz corner  */
++        f_3dB_bw -= 200000;
++        Sel = 0x80;
++        TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 113;
++    }
++    else
++    {
++        /*  <= 2.75 MHz corner  */
++        Sel = 0xC0;
++        TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 129;
++    }
++
++    if (TmpFilt > 63)
++        TmpFilt = 63;
++    else if (TmpFilt < 0)
++        TmpFilt = 0;
++    BBFilt = ((U8Data) TmpFilt) | Sel;
++
++    for ( i = MT2266_BBFILT_1; i <= MT2266_BBFILT_8; i++ )
++        pInfo->reg[i] = BBFilt;
++
++    if (MT_NO_ERROR(status))
++        status |= MT_WriteSub(pInfo->hUserData,
++                              pInfo->address,
++                              MT2266_BBFILT_1,
++                              &pInfo->reg[MT2266_BBFILT_1],
++                              8);
++
++    return (status);
++}
++
++
++/****************************************************************************
++**
++**  Name: MT2266_GetLocked
++**
++**  Description:    Checks to see if the PLL is locked.
++**
++**  Parameters:     h            - Open handle to the tuner (from MT2266_Open).
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      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
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++****************************************************************************/
++UData_t MT2266_GetLocked(Handle_t h)
++{
++    const UData_t nMaxWait = 200;            /*  wait a maximum of 200 msec   */
++    const UData_t nPollRate = 2;             /*  poll status bits every 2 ms */
++    const UData_t nMaxLoops = nMaxWait / nPollRate;
++    UData_t status = MT_OK;                  /* Status to be returned */
++    UData_t nDelays = 0;
++    U8Data statreg;
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++
++    if (IsValidHandle(pInfo) == 0)
++        return MT_INV_HANDLE;
++
++    do
++    {
++        status |= UncheckedGet(pInfo, MT2266_STATUS_1, &statreg);
++
++        if ((MT_IS_ERROR(status)) || ((statreg & 0x40) == 0x40))
++            return (status);
++
++        MT_Sleep(pInfo->hUserData, nPollRate);       /*  Wait between retries  */
++    }
++    while (++nDelays < nMaxLoops);
++
++    if ((statreg & 0x40) != 0x40)
++        status |= MT_DNC_UNLOCK;
++
++    return (status);
++}
++
++
++/****************************************************************************
++**
++**  Name: MT2266_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 MT2266_Open)
++**                  param       - Tuning algorithm parameter
++**                                (see enum MT2266_Param)
++**                  pValue      - ptr to returned value
++**
++**                  param                   Description
++**                  ----------------------  --------------------------------
++**                  MT2266_IC_ADDR          Serial Bus address of this tuner
++**                  MT2266_MAX_OPEN         Max number of MT2266's that can be open
++**                  MT2266_NUM_OPEN         Number of MT2266's currently open
++**                  MT2266_NUM_REGS         Number of tuner registers
++**                  MT2266_SRO_FREQ         crystal frequency
++**                  MT2266_STEPSIZE         minimum tuning step size
++**                  MT2266_INPUT_FREQ       input center frequency
++**                  MT2266_LO_FREQ          LO Frequency
++**                  MT2266_OUTPUT_BW        Output channel bandwidth
++**                  MT2266_RC2_VALUE        Base band filter cal RC code (method 2)
++**                  MT2266_RC2_NOMINAL      Base band filter nominal cal RC code
++**                  MT2266_RF_ADC           RF attenuator A/D readback
++**                  MT2266_RF_ATTN          RF attenuation (0-255)
++**                  MT2266_RF_EXT           External control of RF atten
++**                  MT2266_LNA_GAIN         LNA gain setting (0-15)
++**                  MT2266_BB_ADC           BB attenuator A/D readback
++**                  MT2266_BB_ATTN          Baseband attenuation (0-255)
++**                  MT2266_BB_EXT           External control of BB atten
++**
++**  Usage:          status |= MT2266_GetParam(hMT2266,
++**                                            MT2266_OUTPUT_BW,
++**                                            &f_bw);
++**
++**  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 MT2266_Open() FIRST!
++**
++**  See Also:       MT2266_SetParam, MT2266_Open
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++****************************************************************************/
++UData_t MT2266_GetParam(Handle_t     h,
++                        MT2266_Param param,
++                        UData_t*     pValue)
++{
++    UData_t status = MT_OK;                  /* Status to be returned        */
++    U8Data tmp;
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++
++    if (pValue == MT_NULL)
++        status |= MT_ARG_NULL;
++
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status |= MT_INV_HANDLE;
++
++    if (MT_NO_ERROR(status))
++    {
++        switch (param)
++        {
++        /*  Serial Bus address of this tuner      */
++        case MT2266_IC_ADDR:
++            *pValue = pInfo->address;
++            break;
++
++        /*  Max # of MT2266's allowed to be open  */
++        case MT2266_MAX_OPEN:
++            *pValue = nMaxTuners;
++            break;
++
++        /*  # of MT2266's open                    */
++        case MT2266_NUM_OPEN:
++            *pValue = nOpenTuners;
++            break;
++
++        /*  Number of tuner registers             */
++        case MT2266_NUM_REGS:
++            *pValue = Num_Registers;
++            break;
++
++        /*  crystal frequency                     */
++        case MT2266_SRO_FREQ:
++            *pValue = pInfo->f_Ref;
++            break;
++
++        /*  minimum tuning step size              */
++        case MT2266_STEPSIZE:
++            *pValue = pInfo->f_Step;
++            break;
++
++        /*  input center frequency                */
++        case MT2266_INPUT_FREQ:
++            *pValue = pInfo->f_in;
++            break;
++
++        /*  LO Frequency                          */
++        case MT2266_LO_FREQ:
++            *pValue = pInfo->f_LO;
++            break;
++
++        /*  Output Channel Bandwidth              */
++        case MT2266_OUTPUT_BW:
++            *pValue = pInfo->f_bw;
++            break;
++
++        /*  Base band filter cal RC code          */
++        case MT2266_RC2_VALUE:
++            *pValue = (UData_t) pInfo->RC2_Value;
++            break;
++
++        /*  Base band filter nominal cal RC code          */
++        case MT2266_RC2_NOMINAL:
++            *pValue = (UData_t) pInfo->RC2_Nominal;
++            break;
++
++        /*  RF attenuator A/D readback            */
++        case MT2266_RF_ADC:
++            status |= UncheckedGet(pInfo, MT2266_STATUS_2, &tmp);
++            if (MT_NO_ERROR(status))
++                *pValue = (UData_t) tmp;
++            break;
++
++        /*  BB attenuator A/D readback            */
++        case MT2266_BB_ADC:
++            status |= UncheckedGet(pInfo, MT2266_STATUS_3, &tmp);
++            if (MT_NO_ERROR(status))
++                *pValue = (UData_t) tmp;
++            break;
++
++        /*  RF attenuator setting                 */
++        case MT2266_RF_ATTN:
++            PREFETCH(MT2266_RSVD_1F, 1);  /* Fetch register(s) if __NO_CACHE__ defined */
++            if (MT_NO_ERROR(status))
++                *pValue = pInfo->reg[MT2266_RSVD_1F];
++            break;
++
++        /*  BB attenuator setting                 */
++        case MT2266_BB_ATTN:
++            PREFETCH(MT2266_RSVD_2C, 3);  /* Fetch register(s) if __NO_CACHE__ defined */
++            *pValue = pInfo->reg[MT2266_RSVD_2C]
++                    + pInfo->reg[MT2266_RSVD_2D]
++                    + pInfo->reg[MT2266_RSVD_2E] - 3;
++            break;
++
++        /*  RF external / internal atten control  */
++        case MT2266_RF_EXT:
++            PREFETCH(MT2266_GPO, 1);  /* Fetch register(s) if __NO_CACHE__ defined */
++            *pValue = ((pInfo->reg[MT2266_GPO] & 0x40) != 0x00);
++            break;
++
++        /*  BB external / internal atten control  */
++        case MT2266_BB_EXT:
++            PREFETCH(MT2266_RSVD_33, 1);  /* Fetch register(s) if __NO_CACHE__ defined */
++            *pValue = ((pInfo->reg[MT2266_RSVD_33] & 0x10) != 0x00);
++            break;
++
++        /*  LNA gain setting (0-15)               */
++        case MT2266_LNA_GAIN:
++            PREFETCH(MT2266_IGAIN, 1);  /* Fetch register(s) if __NO_CACHE__ defined */
++            *pValue = ((pInfo->reg[MT2266_IGAIN] & 0x3C) >> 2);
++            break;
++
++        case MT2266_EOP:
++        default:
++            status |= MT_ARG_RANGE;
++        }
++    }
++    return (status);
++}
++
++
++/****************************************************************************
++**  LOCAL FUNCTION - DO NOT USE OUTSIDE OF mt2266.c
++**
++**  Name: UncheckedGet
++**
++**  Description:    Gets an MT2266 register with minimal checking
++**
++**                  NOTE: This is a local function that performs the same
++**                  steps as the MT2266_GetReg function that is available
++**                  in the external API.  It does not do any of the standard
++**                  error checking that the API function provides and should
++**                  not be called from outside this file.
++**
++**  Parameters:     *pInfo      - Tuner control structure
++**                  reg         - MT2266 register/subaddress location
++**                  *val        - MT2266 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 MT2266_Open() FIRST!
++**
++**                  Use this function if you need to read a register from
++**                  the MT2266.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++****************************************************************************/
++static UData_t UncheckedGet(MT2266_Info_t* pInfo,
++                            U8Data   reg,
++                            U8Data*  val)
++{
++    UData_t status;                  /* Status to be returned        */
++
++#if defined(_DEBUG)
++    status = MT_OK;
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status |= MT_INV_HANDLE;
++
++    if (val == MT_NULL)
++        status |= MT_ARG_NULL;
++
++    if (reg >= END_REGS)
++        status |= MT_ARG_RANGE;
++
++    if (MT_IS_ERROR(status))
++        return(status);
++#endif
++
++    status = MT_ReadSub(pInfo->hUserData, pInfo->address, reg, &pInfo->reg[reg], 1);
++
++    if (MT_NO_ERROR(status))
++        *val = pInfo->reg[reg];
++
++    return (status);
++}
++
++
++/****************************************************************************
++**
++**  Name: MT2266_GetReg
++**
++**  Description:    Gets an MT2266 register.
++**
++**  Parameters:     h           - Tuner handle (returned by MT2266_Open)
++**                  reg         - MT2266 register/subaddress location
++**                  *val        - MT2266 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 MT2266_Open() FIRST!
++**
++**                  Use this function if you need to read a register from
++**                  the MT2266.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++****************************************************************************/
++UData_t MT2266_GetReg(Handle_t h,
++                      U8Data   reg,
++                      U8Data*  val)
++{
++    UData_t status = MT_OK;                  /* Status to be returned        */
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status |= MT_INV_HANDLE;
++
++    if (val == MT_NULL)
++        status |= MT_ARG_NULL;
++
++    if (reg >= END_REGS)
++        status |= MT_ARG_RANGE;
++
++    if (MT_NO_ERROR(status))
++        status |= UncheckedGet(pInfo, reg, val);
++
++    return (status);
++}
++
++
++/****************************************************************************
++**
++**  Name: MT2266_GetUHFXFreqs
++**
++**  Description:    Retrieves the specified set of UHF Crossover Frequencies
++**
++**  Parameters:     h            - Open handle to the tuner (from MT2266_Open).
++**
++**  Usage:          MT2266_Freq_Set  tmpFreqs;
++**                  status = MT2266_GetUHFXFreqs(hMT2266,
++**                                               MT2266_UHF1_WITH_ATTENUATION,
++**                                               tmpFreqs );
++**                  if (status & MT_ARG_RANGE)
++**                      // error, Invalid UHF Crossover Frequency Set requested.
++**                  else
++**                      for( int i = 0;  i < MT2266_NUM_XFREQS; i++ )
++**                         . . .
++**
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_ARG_RANGE     - freq_type is out of range.
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**
++**  Dependencies:   freqs_buffer *must* be defined of type MT2266_Freq_Set
++**                     to assure sufficient space allocation!
++**
++**                  USERS MUST CALL MT2266_Open() FIRST!
++**
++**  See Also:       MT2266_SetUHFXFreqs
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   10-26-2006   RSK     Original.
++**
++****************************************************************************/
++UData_t MT2266_GetUHFXFreqs(Handle_t h,
++                            MT2266_UHFXFreq_Type freq_type,
++                            MT2266_XFreq_Set     freqs_buffer)
++{
++    UData_t status = MT_OK;                  /* Status to be returned        */
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status = MT_INV_HANDLE;
++
++    if (freq_type >= MT2266_NUMBER_OF_XFREQ_SETS)
++        status |= MT_ARG_RANGE;
++
++    if (MT_NO_ERROR(status))
++    {
++        int  i;
++
++        for( i = 0; i < MT2266_NUM_XFREQS; i++ )
++        {
++            freqs_buffer[i] = pInfo->xfreqs.xfreq[ freq_type ][i] * TUNE_STEP_SIZE / 1000;
++        }
++    }
++
++    return (status);
++}
++
++
++/****************************************************************************
++**
++**  Name: MT2266_GetUserData
++**
++**  Description:    Gets the user-defined data item.
++**
++**  Parameters:     h           - Tuner handle (returned by MT2266_Open)
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**                      MT_ARG_NULL      - Null pointer argument passed
++**
++**  Dependencies:   USERS MUST CALL MT2266_Open() FIRST!
++**
++**                  The hUserData parameter is a user-specific argument
++**                  that is stored internally with the other tuner-
++**                  specific information.
++**
++**                  For example, if additional arguments are needed
++**                  for the user to identify the device communicating
++**                  with the tuner, this argument can be used to supply
++**                  the necessary information.
++**
++**                  The hUserData parameter is initialized in the tuner's
++**                  Open function to NULL.
++**
++**  See Also:       MT2266_SetUserData, MT2266_Open
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++****************************************************************************/
++UData_t MT2266_GetUserData(Handle_t h,
++                           Handle_t* hUserData)
++{
++    UData_t status = MT_OK;                  /* Status to be returned        */
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status = MT_INV_HANDLE;
++
++    if (hUserData == MT_NULL)
++        status |= MT_ARG_NULL;
++
++    if (MT_NO_ERROR(status))
++        *hUserData = pInfo->hUserData;
++
++    return (status);
++}
++
++
++/******************************************************************************
++**
++**  Name: MT2266_ReInit
++**
++**  Description:    Initialize the tuner's register values.
++**
++**  Parameters:     h           - Tuner handle (returned by MT2266_Open)
++**
++**  Returns:        status:
++**                      MT_OK             - No errors
++**                      MT_TUNER_ID_ERR   - Tuner Part/Rev code mismatch
++**                      MT_TUNER_INIT_ERR - Tuner initialization failed
++**                      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
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**   N/A   06-08-2006    JWS    Ver 1.01: Corrected problem with tuner ID check
++**   N/A   11-01-2006    RSK    Ver 1.02: Initialize XFreq Tables to Default
++**   N/A   11-29-2006    DAD    Ver 1.03: Parenthesis clarification
++**
++******************************************************************************/
++UData_t MT2266_ReInit(Handle_t h)
++{
++    int j;
++
++    U8Data MT2266_Init_Defaults1[] =
++    {
++        0x01,            /* Start w/register 0x01 */
++        0x00,            /* Reg 0x01 */
++        0x00,            /* Reg 0x02 */
++        0x28,            /* Reg 0x03 */
++        0x00,            /* Reg 0x04 */
++        0x52,            /* Reg 0x05 */
++        0x99,            /* Reg 0x06 */
++        0x3F,            /* Reg 0x07 */
++    };
++
++    U8Data MT2266_Init_Defaults2[] =
++    {
++        0x17,            /* Start w/register 0x17 */
++        0x6D,            /* Reg 0x17 */
++        0x71,            /* Reg 0x18 */
++        0x61,            /* Reg 0x19 */
++        0xC0,            /* Reg 0x1A */
++        0xBF,            /* Reg 0x1B */
++        0xFF,            /* Reg 0x1C */
++        0xDC,            /* Reg 0x1D */
++        0x00,            /* Reg 0x1E */
++        0x0A,            /* Reg 0x1F */
++        0xD4,            /* Reg 0x20 */
++        0x03,            /* Reg 0x21 */
++        0x64,            /* Reg 0x22 */
++        0x64,            /* Reg 0x23 */
++        0x64,            /* Reg 0x24 */
++        0x64,            /* Reg 0x25 */
++        0x22,            /* Reg 0x26 */
++        0xAA,            /* Reg 0x27 */
++        0xF2,            /* Reg 0x28 */
++        0x1E,            /* Reg 0x29 */
++        0x80,            /* Reg 0x2A */
++        0x14,            /* Reg 0x2B */
++        0x01,            /* Reg 0x2C */
++        0x01,            /* Reg 0x2D */
++        0x01,            /* Reg 0x2E */
++        0x01,            /* Reg 0x2F */
++        0x01,            /* Reg 0x30 */
++        0x01,            /* Reg 0x31 */
++        0x7F,            /* Reg 0x32 */
++        0x5E,            /* Reg 0x33 */
++        0x3F,            /* Reg 0x34 */
++        0xFF,            /* Reg 0x35 */
++        0xFF,            /* Reg 0x36 */
++        0xFF,            /* Reg 0x37 */
++        0x00,            /* Reg 0x38 */
++        0x77,            /* Reg 0x39 */
++        0x0F,            /* Reg 0x3A */
++        0x2D,            /* Reg 0x3B */
++    };
++
++    UData_t status = MT_OK;                  /* Status to be returned        */
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++    U8Data BBVref;
++    U8Data tmpreg = 0;
++    U8Data statusreg = 0;
++
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status |= MT_INV_HANDLE;
++
++    /*  Read the Part/Rev code from the tuner */
++    if (MT_NO_ERROR(status))
++        status |= UncheckedGet(pInfo, MT2266_PART_REV, &tmpreg);
++    if (MT_NO_ERROR(status) && (tmpreg != 0x85))  // MT226? B0
++        status |= MT_TUNER_ID_ERR;
++    else
++    {
++        /*
++        **  Read the status register 5
++        */
++        tmpreg = pInfo->reg[MT2266_RSVD_11] |= 0x03;
++        if (MT_NO_ERROR(status))
++            status |= UncheckedSet(pInfo, MT2266_RSVD_11, tmpreg);
++        tmpreg &= ~(0x02);
++        if (MT_NO_ERROR(status))
++            status |= UncheckedSet(pInfo, MT2266_RSVD_11, tmpreg);
++
++        /*  Get and store the status 5 register value  */
++        if (MT_NO_ERROR(status))
++            status |= UncheckedGet(pInfo, MT2266_STATUS_5, &statusreg);
++
++        /*  MT2266  */
++        if (MT_IS_ERROR(status) || ((statusreg & 0x30) != 0x30))
++                status |= MT_TUNER_ID_ERR;      /*  Wrong tuner Part/Rev code   */
++    }
++
++    if (MT_NO_ERROR(status))
++    {
++        /*  Initialize the tuner state.  Hold off on f_in and f_LO */
++        pInfo->version = VERSION;
++        pInfo->tuner_id = pInfo->reg[MT2266_PART_REV];
++        pInfo->f_Ref = REF_FREQ;
++        pInfo->f_Step = TUNE_STEP_SIZE * 1000;  /* kHz -> Hz */
++        pInfo->f_in = UHF_DEFAULT_FREQ;
++        pInfo->f_LO = UHF_DEFAULT_FREQ;
++        pInfo->f_bw = OUTPUT_BW;
++        pInfo->band = MT2266_UHF_BAND;
++        pInfo->num_regs = END_REGS;
++
++        /* Reset the UHF Crossover Frequency tables on open/init. */
++        for (j=0; j< MT2266_NUM_XFREQS; j++ )
++        {
++            pInfo->xfreqs.xfreq[MT2266_UHF0][j]       = MT2266_default_XFreqs.xfreq[MT2266_UHF0][j];
++            pInfo->xfreqs.xfreq[MT2266_UHF1][j]       = MT2266_default_XFreqs.xfreq[MT2266_UHF1][j];
++            pInfo->xfreqs.xfreq[MT2266_UHF0_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF0_ATTEN][j];
++            pInfo->xfreqs.xfreq[MT2266_UHF1_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF1_ATTEN][j];
++        }
++
++        /*  Write the default values to the tuner registers. Default mode is UHF */
++        status |= MT_WriteSub(pInfo->hUserData,
++                              pInfo->address,
++                              MT2266_Init_Defaults1[0],
++                              &MT2266_Init_Defaults1[1],
++                              sizeof(MT2266_Init_Defaults1)/sizeof(U8Data)-1);
++        status |= MT_WriteSub(pInfo->hUserData,
++                              pInfo->address,
++                              MT2266_Init_Defaults2[0],
++                              &MT2266_Init_Defaults2[1],
++                              sizeof(MT2266_Init_Defaults2)/sizeof(U8Data)-1);
++    }
++
++    /*  Read back all the registers from the tuner */
++    if (MT_NO_ERROR(status))
++    {
++        status |= MT_ReadSub(pInfo->hUserData, pInfo->address, 0, &pInfo->reg[0], END_REGS);
++    }
++
++    /*
++    **  Set reg[0x33] based on statusreg
++    */
++    if (MT_NO_ERROR(status))
++    {
++        BBVref = (((statusreg >> 6) + 2) & 0x03);
++        tmpreg = (pInfo->reg[MT2266_RSVD_33] & ~(0x60)) | (BBVref << 5);
++        status |= UncheckedSet(pInfo, MT2266_RSVD_33, tmpreg);
++    }
++
++    /*  Run the baseband filter calibration  */
++    if (MT_NO_ERROR(status))
++        status |= Run_BB_RC_Cal2(h);
++
++    /*  Set the baseband filter bandwidth to the default  */
++    if (MT_NO_ERROR(status))
++        status |= Set_BBFilt(h);
++
++    return (status);
++}
++
++
++/****************************************************************************
++**
++**  Name: MT2266_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 MT2266_Open)
++**                  param       - Tuning algorithm parameter
++**                                (see enum MT2266_Param)
++**                  nValue      - value to be set
++**
++**                  param                   Description
++**                  ----------------------  --------------------------------
++**                  MT2266_SRO_FREQ         crystal frequency
++**                  MT2266_STEPSIZE         minimum tuning step size
++**                  MT2266_INPUT_FREQ       Center of input channel
++**                  MT2266_OUTPUT_BW        Output channel bandwidth
++**                  MT2266_RF_ATTN          RF attenuation (0-255)
++**                  MT2266_RF_EXT           External control of RF atten
++**                  MT2266_LNA_GAIN         LNA gain setting (0-15)
++**                  MT2266_LNA_GAIN_DECR    Decrement LNA Gain (arg=min)
++**                  MT2266_LNA_GAIN_INCR    Increment LNA Gain (arg=max)
++**                  MT2266_BB_ATTN          Baseband attenuation (0-255)
++**                  MT2266_BB_EXT           External control of BB atten
++**                  MT2266_UHF_MAXSENS      Set for UHF max sensitivity mode
++**                  MT2266_UHF_NORMAL       Set for UHF normal mode
++**
++**  Usage:          status |= MT2266_SetParam(hMT2266,
++**                                            MT2266_STEPSIZE,
++**                                            50000);
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**                      MT_ARG_RANGE     - Invalid parameter requested
++**                                         or set value out of range
++**                                         or non-writable parameter
++**
++**  Dependencies:   USERS MUST CALL MT2266_Open() FIRST!
++**
++**  See Also:       MT2266_GetParam, MT2266_Open
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**   N/A   11-29-2006    DAD    Ver 1.03: Parenthesis clarification for gcc
++**
++****************************************************************************/
++UData_t MT2266_SetParam(Handle_t     h,
++                        MT2266_Param param,
++                        UData_t      nValue)
++{
++    UData_t status = MT_OK;                  /* Status to be returned        */
++    U8Data tmpreg;
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status |= MT_INV_HANDLE;
++
++    if (MT_NO_ERROR(status))
++    {
++        switch (param)
++        {
++        /*  crystal frequency                     */
++        case MT2266_SRO_FREQ:
++            pInfo->f_Ref = nValue;
++            if (pInfo->f_Ref < 22000000)
++            {
++                /*  Turn off f_SRO divide by 2  */
++                status |= UncheckedSet(pInfo,
++                                       MT2266_SRO_CTRL,
++                                       (U8Data) (pInfo->reg[MT2266_SRO_CTRL] &= 0xFE));
++            }
++            else
++            {
++                /*  Turn on f_SRO divide by 2  */
++                status |= UncheckedSet(pInfo,
++                                       MT2266_SRO_CTRL,
++                                       (U8Data) (pInfo->reg[MT2266_SRO_CTRL] |= 0x01));
++            }
++            status |= Run_BB_RC_Cal2(h);
++            if (MT_NO_ERROR(status))
++                status |= Set_BBFilt(h);
++            break;
++
++        /*  minimum tuning step size              */
++        case MT2266_STEPSIZE:
++            pInfo->f_Step = nValue;
++            break;
++
++        /*  Width of output channel               */
++        case MT2266_OUTPUT_BW:
++            pInfo->f_bw = nValue;
++            status |= Set_BBFilt(h);
++            break;
++
++        /*  BB attenuation (0-255)                */
++        case MT2266_BB_ATTN:
++            if (nValue > 255)
++                status |= MT_ARG_RANGE;
++            else
++            {
++                UData_t BBA_Stage1;
++                UData_t BBA_Stage2;
++                UData_t BBA_Stage3;
++
++                BBA_Stage3 = (nValue > 102) ? 103 : nValue + 1;
++                BBA_Stage2 = (nValue > 175) ? 75 : nValue + 2 - BBA_Stage3;
++                BBA_Stage1 = (nValue > 176) ? nValue - 175 : 1;
++                pInfo->reg[MT2266_RSVD_2C] = (U8Data) BBA_Stage1;
++                pInfo->reg[MT2266_RSVD_2D] = (U8Data) BBA_Stage2;
++                pInfo->reg[MT2266_RSVD_2E] = (U8Data) BBA_Stage3;
++                pInfo->reg[MT2266_RSVD_2F] = (U8Data) BBA_Stage1;
++                pInfo->reg[MT2266_RSVD_30] = (U8Data) BBA_Stage2;
++                pInfo->reg[MT2266_RSVD_31] = (U8Data) BBA_Stage3;
++                status |= MT_WriteSub(pInfo->hUserData,
++                                      pInfo->address,
++                                      MT2266_RSVD_2C,
++                                      &pInfo->reg[MT2266_RSVD_2C],
++                                      6);
++            }
++            break;
++
++        /*  RF attenuation (0-255)                */
++        case MT2266_RF_ATTN:
++            if (nValue > 255)
++                status |= MT_ARG_RANGE;
++            else
++                status |= UncheckedSet(pInfo, MT2266_RSVD_1F, (U8Data) nValue);
++            break;
++
++        /*  RF external / internal atten control  */
++        case MT2266_RF_EXT:
++            if (nValue == 0)
++                tmpreg = pInfo->reg[MT2266_GPO] &= ~0x40;
++            else
++                tmpreg = pInfo->reg[MT2266_GPO] |= 0x40;
++            status |= UncheckedSet(pInfo, MT2266_GPO, tmpreg);
++            break;
++
++        /*  LNA gain setting (0-15)               */
++        case MT2266_LNA_GAIN:
++            if (nValue > 15)
++                status |= MT_ARG_RANGE;
++            else
++            {
++                tmpreg = (pInfo->reg[MT2266_IGAIN] & 0xC3) | ((U8Data)nValue << 2);
++                status |= UncheckedSet(pInfo, MT2266_IGAIN, tmpreg);
++            }
++            break;
++
++        /*  Decrement LNA Gain setting, argument is min LNA Gain setting  */
++        case MT2266_LNA_GAIN_DECR:
++            if (nValue > 15)
++                status |= MT_ARG_RANGE;
++            else
++            {
++                PREFETCH(MT2266_IGAIN, 1);
++                if (MT_NO_ERROR(status) && ((U8Data) ((pInfo->reg[MT2266_IGAIN] & 0x3C) >> 2) > (U8Data) nValue))
++                    status |= UncheckedSet(pInfo, MT2266_IGAIN, pInfo->reg[MT2266_IGAIN] - 0x04);
++            }
++            break;
++
++        /*  Increment LNA Gain setting, argument is max LNA Gain setting  */
++        case MT2266_LNA_GAIN_INCR:
++            if (nValue > 15)
++                status |= MT_ARG_RANGE;
++            else
++            {
++                PREFETCH(MT2266_IGAIN, 1);
++                if (MT_NO_ERROR(status) && ((U8Data) ((pInfo->reg[MT2266_IGAIN] & 0x3C) >> 2) < (U8Data) nValue))
++                    status |= UncheckedSet(pInfo, MT2266_IGAIN, pInfo->reg[MT2266_IGAIN] + 0x04);
++            }
++            break;
++
++        /*  BB external / internal atten control  */
++        case MT2266_BB_EXT:
++            if (nValue == 0)
++                tmpreg = pInfo->reg[MT2266_RSVD_33] &= ~0x08;
++            else
++                tmpreg = pInfo->reg[MT2266_RSVD_33] |= 0x08;
++            status |= UncheckedSet(pInfo, MT2266_RSVD_33, tmpreg);
++            break;
++
++        /*  Set for UHF max sensitivity mode  */
++        case MT2266_UHF_MAXSENS:
++            PREFETCH(MT2266_BAND_CTRL, 1);
++            if (MT_NO_ERROR(status) && ((pInfo->reg[MT2266_BAND_CTRL] & 0x30) == 0x10))
++                status |= UncheckedSet(pInfo, MT2266_BAND_CTRL, pInfo->reg[MT2266_BAND_CTRL] ^ 0x30);
++            break;
++
++        /*  Set for UHF normal mode  */
++        case MT2266_UHF_NORMAL:
++            if (MT_NO_ERROR(status) && ((pInfo->reg[MT2266_BAND_CTRL] & 0x30) == 0x20))
++                status |= UncheckedSet(pInfo, MT2266_BAND_CTRL, pInfo->reg[MT2266_BAND_CTRL] ^ 0x30);
++            break;
++
++        /*  These parameters are read-only  */
++        case MT2266_IC_ADDR:
++        case MT2266_MAX_OPEN:
++        case MT2266_NUM_OPEN:
++        case MT2266_NUM_REGS:
++        case MT2266_INPUT_FREQ:
++        case MT2266_LO_FREQ:
++        case MT2266_RC2_VALUE:
++        case MT2266_RF_ADC:
++        case MT2266_BB_ADC:
++        case MT2266_EOP:
++        default:
++            status |= MT_ARG_RANGE;
++        }
++    }
++    return (status);
++}
++
++
++/****************************************************************************
++**
++**  Name: MT2266_SetPowerModes
++**
++**  Description:    Sets the bits in the MT2266_ENABLES register and the
++**                  SROsd bit in the MT2266_SROADC_CTRL register.
++**
++**  Parameters:     h           - Tuner handle (returned by MT2266_Open)
++**                  flags       - Bit mask of flags to indicate enabled
++**                                bits.
++**
++**  Usage:          status = MT2266_SetPowerModes(hMT2266, flags);
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**
++**  Dependencies:   USERS MUST CALL MT2266_Open() FIRST!
++**
++**                  The bits in the MT2266_ENABLES register and the
++**                  SROsd bit are set according to the supplied flags.
++**
++**                  The pre-defined flags are as follows:
++**                      MT2266_SROen
++**                      MT2266_LOen
++**                      MT2266_ADCen
++**                      MT2266_PDen
++**                      MT2266_DCOCen
++**                      MT2266_BBen
++**                      MT2266_MIXen
++**                      MT2266_LNAen
++**                      MT2266_ALL_ENABLES
++**                      MT2266_NO_ENABLES
++**                      MT2266_SROsd
++**                      MT2266_SRO_NOT_sd
++**
++**                  ONLY the enable bits (or SROsd bit) specified in the
++**                  flags parameter will be set.  Any flag which is not
++**                  included, will cause that bit to be disabled.
++**
++**                  The ALL_ENABLES, NO_ENABLES, and SRO_NOT_sd constants
++**                  are for convenience.  The NO_ENABLES and SRO_NOT_sd
++**                  do not actually have to be included, but are provided
++**                  for clarity.
++**
++**  See Also:       MT2266_Open
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++****************************************************************************/
++UData_t MT2266_SetPowerModes(Handle_t h,
++                             UData_t  flags)
++{
++    UData_t status = MT_OK;                  /* Status to be returned */
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++    U8Data tmpreg;
++
++    /*  Verify that the handle passed points to a valid tuner */
++    if (IsValidHandle(pInfo) == 0)
++        status |= MT_INV_HANDLE;
++
++    PREFETCH(MT2266_SRO_CTRL, 1);  /* Fetch register(s) if __NO_CACHE__ defined */
++    if (MT_NO_ERROR(status))
++    {
++        if (flags & MT2266_SROsd)
++            tmpreg = pInfo->reg[MT2266_SRO_CTRL] |= 0x10;  /* set the SROsd bit */
++        else
++            tmpreg = pInfo->reg[MT2266_SRO_CTRL] &= 0xEF;  /* clear the SROsd bit */
++        status |= UncheckedSet(pInfo, MT2266_SRO_CTRL, tmpreg);
++    }
++
++    PREFETCH(MT2266_ENABLES, 1);  /* Fetch register(s) if __NO_CACHE__ defined */
++
++    if (MT_NO_ERROR(status))
++    {
++        status |= UncheckedSet(pInfo, MT2266_ENABLES, (U8Data)(flags & 0xff));
++    }
++
++    return status;
++}
++
++
++/****************************************************************************
++**  LOCAL FUNCTION - DO NOT USE OUTSIDE OF mt2266.c
++**
++**  Name: UncheckedSet
++**
++**  Description:    Sets an MT2266 register.
++**
++**                  NOTE: This is a local function that performs the same
++**                  steps as the MT2266_SetReg function that is available
++**                  in the external API.  It does not do any of the standard
++**                  error checking that the API function provides and should
++**                  not be called from outside this file.
++**
++**  Parameters:     *pInfo      - Tuner control structure
++**                  reg         - MT2266 register/subaddress location
++**                  val         - MT2266 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 MT2266_Open() FIRST!
++**
++**                  Sets a register value without any preliminary checking for
++**                  valid handles or register numbers.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++****************************************************************************/
++static UData_t UncheckedSet(MT2266_Info_t* pInfo,
++                            U8Data         reg,
++                            U8Data         val)
++{
++    UData_t status;                  /* Status to be returned */
++
++#if defined(_DEBUG)
++    status = MT_OK;
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status |= MT_INV_HANDLE;
++
++    if (reg >= END_REGS)
++        status |= MT_ARG_RANGE;
++
++    if (MT_IS_ERROR(status))
++        return (status);
++#endif
++
++    status = MT_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, 1);
++
++    if (MT_NO_ERROR(status))
++        pInfo->reg[reg] = val;
++
++    return (status);
++}
++
++
++/****************************************************************************
++**
++**  Name: MT2266_SetReg
++**
++**  Description:    Sets an MT2266 register.
++**
++**  Parameters:     h           - Tuner handle (returned by MT2266_Open)
++**                  reg         - MT2266 register/subaddress location
++**                  val         - MT2266 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 MT2266_Open() FIRST!
++**
++**                  Use this function if you need to override a default
++**                  register value
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++****************************************************************************/
++UData_t MT2266_SetReg(Handle_t h,
++                      U8Data   reg,
++                      U8Data   val)
++{
++    UData_t status = MT_OK;                  /* Status to be returned */
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status |= MT_INV_HANDLE;
++
++    if (reg >= END_REGS)
++        status |= MT_ARG_RANGE;
++
++    if (MT_NO_ERROR(status))
++        status |= UncheckedSet(pInfo, reg, val);
++
++    return (status);
++}
++
++
++/****************************************************************************
++**
++**  Name: MT2266_SetUHFXFreqs
++**
++**  Description:    Assigns the specified set of UHF Crossover Frequencies
++**
++**  Parameters:     h            - Open handle to the tuner (from MT2266_Open).
++**
++**  Usage:          MT2266_Freq_Set  tmpFreqs;
++**                  status = MT2266_GetUHFXFreqs(hMT2266,
++**                                               MT2266_UHF1_WITH_ATTENUATION,
++**                                               tmpFreqs );
++**                   ...
++**                  tmpFreqs[i] = <desired value>
++**                   ...
++**                  status = MT2266_SetUHFXFreqs(hMT2266,
++**                                               MT2266_UHF1_WITH_ATTENUATION,
++**                                               tmpFreqs );
++**
++**                  if (status & MT_ARG_RANGE)
++**                      // error, Invalid UHF Crossover Frequency Set requested.
++**                  else
++**                      for( int i = 0;  i < MT2266_NUM_XFREQS; i++ )
++**                         . . .
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_ARG_RANGE     - freq_type is out of range.
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**
++**  Dependencies:   freqs_buffer *must* be defined of type MT2266_Freq_Set
++**                     to assure sufficient space allocation!
++**
++**                  USERS MUST CALL MT2266_Open() FIRST!
++**
++**  See Also:       MT2266_SetUHFXFreqs
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   10-26-2006   RSK     Original.
++**
++****************************************************************************/
++UData_t MT2266_SetUHFXFreqs(Handle_t h,
++                            MT2266_UHFXFreq_Type freq_type,
++                            MT2266_XFreq_Set     freqs_buffer)
++{
++    UData_t status = MT_OK;                     /* Status to be returned */
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        status = MT_INV_HANDLE;
++
++    if (freq_type >= MT2266_NUMBER_OF_XFREQ_SETS)
++        status |= MT_ARG_RANGE;
++
++    if (MT_NO_ERROR(status))
++    {
++        int  i;
++
++        for( i = 0; i < MT2266_NUM_XFREQS; i++ )
++        {
++            pInfo->xfreqs.xfreq[ freq_type ][i] = freqs_buffer[i] * 1000 / TUNE_STEP_SIZE;
++        }
++    }
++
++    return (status);
++}
++
++
++/****************************************************************************
++** LOCAL FUNCTION
++**
++**  Name: RoundToStep
++**
++**  Description:    Rounds the given frequency to the closes f_Step value
++**                  given the tuner ref frequency..
++**
++**
++**  Parameters:     freq      - Frequency to be rounded (in Hz).
++**                  f_Step    - Step size for the frequency (in Hz).
++**                  f_Ref     - SRO frequency (in Hz).
++**
++**  Returns:        Rounded frequency.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**
++****************************************************************************/
++static UData_t RoundToStep(UData_t freq, UData_t f_Step, UData_t f_ref)
++{
++    return f_ref * (freq / f_ref)
++        + f_Step * (((freq % f_ref) + (f_Step / 2)) / f_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
++**  -------------------------------------------------------------------------
++**   N/A   12-20-2006    RSK    Ver 1.04: Adding fLO_FractionalTerm() usage.
++**
++****************************************************************************/
++static UData_t fLO_FractionalTerm( UData_t f_ref,
++                                   UData_t num,
++                                   UData_t denom )
++{
++    UData_t t1     = (f_ref >> 14) * num;
++    UData_t term1  = t1 / denom;
++    UData_t loss   = t1 % denom;
++    UData_t term2  = ( ((f_ref & 0x00003FFF) * num + (loss<<14)) + (denom/2) )  / denom;
++    return ((term1 << 14) + term2);
++}
++
++
++/****************************************************************************
++** LOCAL FUNCTION
++**
++**  Name: CalcLOMult
++**
++**  Description:    Calculates Integer divider value and the numerator
++**                  value for LO's 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.
++**                  denom     - LO FracN denominator value
++**                  f_Ref     - SRO frequency.
++**
++**  Returns:        Recalculated LO frequency.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**   N/A   12-20-2006    RSK    Ver 1.04: Adding fLO_FractionalTerm() usage.
++**
++****************************************************************************/
++static UData_t CalcLOMult(UData_t *Div,
++                          UData_t *FracN,
++                          UData_t  f_LO,
++                          UData_t  denom,
++                          UData_t  f_Ref)
++{
++    UData_t a, b, i;
++    const SData_t TwoNShift = 13;   // bits to shift to obtain 2^n qty
++    const SData_t RoundShift = 18;  // bits to shift before rounding
++
++    /*  Calculate the whole number portion of the divider */
++    *Div = f_LO / f_Ref;
++
++    /*
++    **  Calculate the FracN numerator 1 bit at a time.  This keeps the
++    **  integer values from overflowing when large values are multiplied.
++    **  This loop calculates the fractional portion of F/20MHz accurate
++    **  to 32 bits.  The 2^n factor is represented by the placement of
++    **  the value in the 32-bit word.  Since we want as much accuracy
++    **  as possible, we'll leave it at the top of the word.
++    */
++    *FracN = 0;
++    a = f_LO;
++    for (i=32; i>0; --i)
++    {
++        b = 2*(a % f_Ref);
++        *FracN = (*FracN * 2) + (b >= f_Ref);
++        a = b;
++    }
++
++    /*
++    **  If the denominator is a 2^n - 1 value (the usual case) then the
++    **  value we really need is (F/20) * 2^n - (F/20).  Shifting the
++    **  calculated (F/20) value to the right and subtracting produces
++    **  the desired result -- still accurate to 32 bits.
++    */
++    if ((denom & 0x01) != 0)
++        *FracN -= (*FracN >> TwoNShift);
++
++    /*
++    ** Now shift the result so that it is 1 bit bigger than we need,
++    ** use the low-order bit to round the remaining bits, and shift
++    ** to make the answer the desired size.
++    */
++    *FracN >>= RoundShift;
++    *FracN = (*FracN & 0x01) + (*FracN >> 1);
++
++    /*  Check for rollover (cannot happen with 50 kHz step size) */
++    if (*FracN == (denom | 1))
++    {
++        *FracN = 0;
++        ++Div;
++    }
++
++
++    return (f_Ref * (*Div)) + fLO_FractionalTerm( f_Ref, *FracN, denom );
++}
++
++
++/****************************************************************************
++** LOCAL FUNCTION
++**
++**  Name: GetCrossover
++**
++**  Description:    Determines the appropriate value in the set of
++**                  crossover frequencies.
++**
++**                  This function assumes that the crossover frequency table
++**                  ias been properly initialized in descending order.
++**
++**  Parameters:     f_in      - The input frequency to use.
++**                  freqs     - The array of crossover frequency entries.
++**
++**  Returns:        Index of crossover frequency band to use.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   10-27-2006    RSK    Original
++**
++****************************************************************************/
++static U8Data GetCrossover( UData_t f_in,  UData_t* freqs )
++{
++    U8Data idx;
++    U8Data retVal = 0;
++
++    for (idx=0; idx< (U8Data)MT2266_NUM_XFREQS; idx++)
++    {
++        if ( freqs[idx] >= f_in)
++        {
++            retVal = (U8Data)MT2266_NUM_XFREQS - idx;
++            break;
++        }
++    }
++
++    return retVal;
++}
++
++
++/****************************************************************************
++**
++**  Name: MT2266_ChangeFreq
++**
++**  Description:    Change the tuner's tuned frequency to f_in.
++**
++**  Parameters:     h           - Open handle to the tuner (from MT2266_Open).
++**                  f_in        - RF input center frequency (in Hz).
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**                      MT_DNC_UNLOCK    - Downconverter PLL unlocked
++**                      MT_COMM_ERR      - Serial bus communications error
++**                      MT_FIN_RANGE     - Input freq out of range
++**                      MT_DNC_RANGE     - Downconverter freq out of range
++**
++**  Dependencies:   MUST CALL MT2266_Open BEFORE MT2266_ChangeFreq!
++**
++**                  MT_ReadSub       - Read byte(s) of data from the two-wire-bus
++**                  MT_WriteSub      - Write byte(s) of data to the two-wire-bus
++**                  MT_Sleep         - Delay execution for x milliseconds
++**                  MT2266_GetLocked - Checks to see if the PLL is locked
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**   N/A   11-01-2006    RSK    Ver 1.02: Added usage of UFILT0 and UFILT1.
++**   N/A   11-29-2006    DAD    Ver 1.03: Parenthesis clarification
++**   118   05-09-2007    RSK    Ver 1.05: Refactored to call _Tune() API.
++**
++****************************************************************************/
++UData_t MT2266_ChangeFreq(Handle_t h,
++                          UData_t f_in)     /* RF input center frequency   */
++{
++    return (MT2266_Tune(h, f_in));
++}
++
++
++/****************************************************************************
++**
++**  Name: MT2266_Tune
++**
++**  Description:    Change the tuner's tuned frequency to f_in.
++**
++**  Parameters:     h           - Open handle to the tuner (from MT2266_Open).
++**                  f_in        - RF input center frequency (in Hz).
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**                      MT_DNC_UNLOCK    - Downconverter PLL unlocked
++**                      MT_COMM_ERR      - Serial bus communications error
++**                      MT_FIN_RANGE     - Input freq out of range
++**                      MT_DNC_RANGE     - Downconverter freq out of range
++**
++**  Dependencies:   MUST CALL MT2266_Open BEFORE MT2266_Tune!
++**
++**                  MT_ReadSub       - Read byte(s) of data from the two-wire-bus
++**                  MT_WriteSub      - Write byte(s) of data to the two-wire-bus
++**                  MT_Sleep         - Delay execution for x milliseconds
++**                  MT2266_GetLocked - Checks to see if the PLL is locked
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**   N/A   11-01-2006    RSK    Ver 1.02: Added usage of UFILT0 and UFILT1.
++**   N/A   11-29-2006    DAD    Ver 1.03: Parenthesis clarification
++**   118   05-09-2007    RSK    Ver 1.05: Adding Standard MTxxxx_Tune() API.
++**
++****************************************************************************/
++UData_t MT2266_Tune(Handle_t h,
++                    UData_t f_in)     /* RF input center frequency   */
++{
++    MT2266_Info_t* pInfo = (MT2266_Info_t*) h;
++
++    UData_t status = MT_OK;       /*  status of operation             */
++    UData_t LO;                   /*  LO register value               */
++    UData_t Num;                  /*  Numerator for LO reg. value     */
++    UData_t ofLO;                 /*  last time's LO frequency        */
++    UData_t ofin;                 /*  last time's input frequency     */
++    U8Data  LO_Band;              /*  LO Mode bits                    */
++    UData_t s_fRef;               /*  Ref Freq scaled for LO Band     */
++    UData_t this_band;            /*  Band for the requested freq     */
++    UData_t SROx2;                /*  SRO times 2                     */
++
++    /*  Verify that the handle passed points to a valid tuner         */
++    if (IsValidHandle(pInfo) == 0)
++        return MT_INV_HANDLE;
++
++    /*
++    **  Save original input and LO value
++    */
++    ofLO = pInfo->f_LO;
++    ofin = pInfo->f_in;
++
++    /*
++    **  Assign in the requested input value
++    */
++    pInfo->f_in = f_in;
++
++    /*
++    **  Get the SRO multiplier value
++    */
++    SROx2 = (2 - (pInfo->reg[MT2266_SRO_CTRL] & 0x01));
++
++	/* Check f_Step value */
++	if(pInfo->f_Step == 0)
++		return MT_UNKNOWN;
++
++	/*  Request an LO that is on a step size boundary  */
++    pInfo->f_LO = RoundToStep(f_in, pInfo->f_Step, pInfo->f_Ref);
++
++    if (pInfo->f_LO < MIN_VHF_FREQ)
++    {
++        status |= MT_FIN_RANGE | MT_ARG_RANGE | MT_DNC_RANGE;
++        return status;  /* Does not support frequencies below MIN_VHF_FREQ  */
++    }
++    else if (pInfo->f_LO <= MAX_VHF_FREQ)
++    {
++        /*  VHF Band  */
++        s_fRef = pInfo->f_Ref * SROx2 / 4;
++        LO_Band = 0;
++        this_band = MT2266_VHF_BAND;
++    }
++    else if (pInfo->f_LO < MIN_UHF_FREQ)
++    {
++        status |= MT_FIN_RANGE | MT_ARG_RANGE | MT_DNC_RANGE;
++        return status;  /* Does not support frequencies between MAX_VHF_FREQ & MIN_UHF_FREQ */
++    }
++    else if (pInfo->f_LO <= MAX_UHF_FREQ)
++    {
++        /*  UHF Band  */
++        s_fRef = pInfo->f_Ref * SROx2 / 2;
++        LO_Band = 1;
++        this_band = MT2266_UHF_BAND;
++    }
++    else
++    {
++        status |= MT_FIN_RANGE | MT_ARG_RANGE | MT_DNC_RANGE;
++        return status;  /* Does not support frequencies above MAX_UHF_FREQ */
++    }
++
++    /*
++    ** Calculate the LO frequencies and the values to be placed
++    ** in the tuning registers.
++    */
++    pInfo->f_LO = CalcLOMult(&LO, &Num, pInfo->f_LO, 8191, s_fRef);
++
++    /*
++    **  If we have the same LO frequencies and we're already locked,
++    **  then just return without writing any registers.
++    */
++    if ((ofLO == pInfo->f_LO)
++        && ((pInfo->reg[MT2266_STATUS_1] & 0x40) == 0x40))
++    {
++        return (status);
++    }
++
++    /*
++    ** Reset defaults here if we're tuning into a new band
++    */
++    if (MT_NO_ERROR(status))
++    {
++        if (this_band != pInfo->band)
++        {
++            MT2266_DefaultsEntry *defaults = MT_NULL;
++            switch (this_band)
++            {
++                case MT2266_VHF_BAND:
++                    defaults = &MT2266_VHF_defaults[0];
++                    break;
++                case MT2266_UHF_BAND:
++                    defaults = &MT2266_UHF_defaults[0];
++                    break;
++                default:
++                    status |= MT_ARG_RANGE;
++            }
++            if ( MT_NO_ERROR(status))
++            {
++                while (defaults->data && MT_NO_ERROR(status))
++                {
++                    status |= MT_WriteSub(pInfo->hUserData, pInfo->address, defaults->data[0], &defaults->data[1], defaults->cnt);
++                    defaults++;
++                }
++                /* re-read the new registers into the cached values */
++                status |= MT_ReadSub(pInfo->hUserData, pInfo->address, 0, &pInfo->reg[0], END_REGS);
++                pInfo->band = this_band;
++            }
++        }
++    }
++
++    /*
++    **  Place all of the calculated values into the local tuner
++    **  register fields.
++    */
++    if (MT_NO_ERROR(status))
++    {
++        pInfo->reg[MT2266_LO_CTRL_1] = (U8Data)(Num >> 8);
++        pInfo->reg[MT2266_LO_CTRL_2] = (U8Data)(Num & 0xFF);
++        pInfo->reg[MT2266_LO_CTRL_3] = (U8Data)(LO & 0xFF);
++
++        /*
++        ** Now write out the computed register values
++        */
++        status |= MT_WriteSub(pInfo->hUserData, pInfo->address, MT2266_LO_CTRL_1, &pInfo->reg[MT2266_LO_CTRL_1], 3);
++
++        if (pInfo->band == MT2266_UHF_BAND)
++        {
++            U8Data UFilt0 = 0;                        /*  def when f_in > all    */
++            U8Data UFilt1 = 0;                        /*  def when f_in > all    */
++            UData_t* XFreq0;
++            UData_t* XFreq1;
++            SData_t ClearTune_Fuse;
++            SData_t f_offset;
++            UData_t f_in_;
++
++            PREFETCH(MT2266_BAND_CTRL, 2);  /* Fetch register(s) if __NO_CACHE__ defined */
++            PREFETCH(MT2266_STATUS_5, 1);  /* Fetch register(s) if __NO_CACHE__ defined */
++
++            XFreq0 = (pInfo->reg[MT2266_BAND_CTRL] & 0x10) ? pInfo->xfreqs.xfreq[ MT2266_UHF0_ATTEN ] : pInfo->xfreqs.xfreq[ MT2266_UHF0 ];
++            XFreq1 = (pInfo->reg[MT2266_BAND_CTRL] & 0x10) ? pInfo->xfreqs.xfreq[ MT2266_UHF1_ATTEN ] : pInfo->xfreqs.xfreq[ MT2266_UHF1 ];
++
++            ClearTune_Fuse = pInfo->reg[MT2266_STATUS_5] & 0x07;
++            f_offset = (10000000) * ((ClearTune_Fuse > 3) ? (ClearTune_Fuse - 8) : ClearTune_Fuse);
++            f_in_ = (f_in - f_offset) / 1000 / TUNE_STEP_SIZE;
++
++            UFilt0 = GetCrossover( f_in_, XFreq0 );
++            UFilt1 = GetCrossover( f_in_, XFreq1 );
++
++            /*  If UFilt == 16, set UBANDen and set UFilt = 15  */
++            if ( (UFilt0 == 16) || (UFilt1 == 16) )
++            {
++                pInfo->reg[MT2266_BAND_CTRL] |= 0x01;
++                if( UFilt0 > 0 ) UFilt0--;
++                if( UFilt1 > 0 ) UFilt1--;
++            }
++            else
++                pInfo->reg[MT2266_BAND_CTRL] &= ~(0x01);
++
++            pInfo->reg[MT2266_BAND_CTRL] =
++                    (pInfo->reg[MT2266_BAND_CTRL] & 0x3F) | (LO_Band << 6);
++
++            pInfo->reg[MT2266_CLEARTUNE] = (UFilt1 << 4) | UFilt0;
++            /*  Write UBANDsel  [05] & ClearTune [06]  */
++            status |= MT_WriteSub(pInfo->hUserData, pInfo->address, MT2266_BAND_CTRL, &pInfo->reg[MT2266_BAND_CTRL], 2);
++        }
++    }
++
++    /*
++    **  Check for LO lock
++    */
++    if (MT_NO_ERROR(status))
++    {
++        status |= MT2266_GetLocked(h);
++    }
++
++    return (status);
++}
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/tuner_mt2266.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/tuner_mt2266.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,1618 @@
++#ifndef __TUNER_MT2266_H
++#define __TUNER_MT2266_H
++
++/**
++
++@file
++
++@brief   MT2266 tuner module declaration
++
++One can manipulate MT2266 tuner through MT2266 module.
++MT2266 module is derived from tunerd module.
++
++
++
++@par Example:
++@code
++
++// The example is the same as the tuner example in tuner_base.h except the listed lines.
++
++
++
++#include "tuner_mt2266.h"
++
++
++...
++
++
++
++int main(void)
++{
++	TUNER_MODULE        *pTuner;
++	MT2266_EXTRA_MODULE *pTunerExtra;
++
++	TUNER_MODULE          TunerModuleMemory;
++	MT2266_EXTRA_MODULE   Mt2266ExtraModuleMemory;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++	I2C_BRIDGE_MODULE     I2cBridgeModuleMemory;
++
++	unsigned long BandwidthHz;
++
++
++	...
++
++
++
++	// Build MT2266 tuner module.
++	BuildMt2266Module(
++		&pTuner,
++		&TunerModuleMemory,
++		&Mt2266ExtraModuleMemory,
++		&BaseInterfaceModuleMemory,
++		&I2cBridgeModuleMemory,
++		0xc0								// I2C device address is 0xc0 in 8-bit format.
++		);
++
++
++
++
++
++	// Get MT2266 tuner extra module.
++	pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra);
++
++	// Open MT2266 handle.
++	pTunerExtra->OpenHandle(pTuner);
++
++
++
++
++
++	// ==== Initialize tuner and set its parameters =====
++
++	...
++
++	// Set MT2266 bandwidth.
++	pTunerExtra->SetBandwidthHz(pTuner, MT2266_BANDWIDTH_6MHZ);
++
++
++
++
++
++	// ==== Get tuner information =====
++
++	...
++
++	// Get MT2266 bandwidth.
++	pTunerExtra->GetBandwidthHz(pTuner, &BandwidthHz);
++
++
++
++
++
++	// Close MT2266 handle.
++	pTunerExtra->CloseHandle(pTuner);
++
++
++
++	// See the example for other tuner functions in tuner_base.h
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++
++
++
++// The following context is source code provided by Microtune.
++
++
++
++
++
++// Microtune source code - mt_errordef.h
++
++
++
++/*****************************************************************************
++**
++**  Name: mt_errordef.h
++**
++**  Description:    Definition of bits in status/error word used by various
++**                  MicroTuner control programs.
++**
++**  References:     None
++**
++**  Exports:        None
++**
++**  CVS ID:         $Id: mt_errordef.h,v 1.1 2006/06/22 20:18:12 software Exp $
++**  CVS Source:     $Source: /export/home/cvsroot/software/tuners/MT2266/mt_errordef.h,v $
++**	               
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   09-09-2004    JWS    Original
++**   088   01-26-2005    DAD    Added MT_TUNER_INIT_ERR.
++**   N/A   12-09-2005    DAD    Added MT_TUNER_TIMEOUT (info).
++**
++*****************************************************************************/
++
++/*
++** Note to users:  DO NOT EDIT THIS FILE  
++**
++** If you wish to rename any of the "user defined" bits,
++** it should be done in the user file that includes this
++** source file (e.g. mt_userdef.h)
++**
++*/
++
++
++
++/*
++**  3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 
++**  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
++**  M U <- Info Codes --> <# Spurs> < User> <----- Err Codes ----->
++**
++**  31 = MT_ERROR - Master Error Flag.  If set, check Err Codes for reason.
++**  30 = MT_USER_ERROR - User-declared error flag.
++**  29 = Unused
++**  28 = Unused
++**  27 = MT_DNC_RANGE
++**  26 = MT_UPC_RANGE
++**  25 = MT_FOUT_RANGE
++**  24 = MT_FIN_OUT_OF_RANGE
++**  23 = MT_SPUR_PRESENT - Unavoidable spur in output
++**  22 = MT_TUNER_TIMEOUT
++**  21 = Unused
++**  20 = Unused
++**  19 = MT_SPUR_CNT_MASK (MSB) - Count of avoided spurs
++**  18 = MT_SPUR_CNT_MASK
++**  17 = MT_SPUR_CNT_MASK
++**  16 = MT_SPUR_CNT_MASK
++**  15 = MT_SPUR_CNT_MASK (LSB)
++**  14 = MT_USER_DEFINED4 - User-definable bit (see MT_Userdef.h)
++**  13 = MT_USER_DEFINED3 - User-definable bit (see MT_Userdef.h)
++**  12 = MT_USER_DEFINED2 - User-definable bit (see MT_Userdef.h)
++**  11 = MT_USER_DEFINED1 - User-definable bit (see MT_Userdef.h)
++**  10 = Unused
++**   9 = MT_TUNER_INIT_ERR - Tuner initialization error
++**   8 = MT_TUNER_ID_ERR - Tuner Part Code / Rev Code mismatches expected value
++**   7 = MT_TUNER_CNT_ERR - Attempt to open more than MT_TUNER_CNT tuners
++**   6 = MT_ARG_NULL - Null pointer passed as argument
++**   5 = MT_ARG_RANGE - Argument value out of range
++**   4 = MT_INV_HANDLE - Tuner handle is invalid
++**   3 = MT_COMM_ERR - Serial bus communications error
++**   2 = MT_DNC_UNLOCK - Downconverter PLL is unlocked
++**   1 = MT_UPC_UNLOCK - Upconverter PLL is unlocked
++**   0 = MT_UNKNOWN - Unknown error
++*/
++#define MT_ERROR (1 << 31)
++#define MT_USER_ERROR (1 << 30)
++
++/*  Macro to be used to check for errors  */
++#define MT_IS_ERROR(s) (((s) >> 30) != 0)
++#define MT_NO_ERROR(s) (((s) >> 30) == 0)
++
++
++#define MT_OK                           (0x00000000)
++
++/*  Unknown error  */
++#define MT_UNKNOWN                      (0x80000001)
++
++/*  Error:  Upconverter PLL is not locked  */
++#define MT_UPC_UNLOCK                   (0x80000002)
++
++/*  Error:  Downconverter PLL is not locked  */
++#define MT_DNC_UNLOCK                   (0x80000004)
++
++/*  Error:  Two-wire serial bus communications error  */
++#define MT_COMM_ERR                     (0x80000008)
++
++/*  Error:  Tuner handle passed to function was invalid  */
++#define MT_INV_HANDLE                   (0x80000010)
++
++/*  Error:  Function argument is invalid (out of range)  */
++#define MT_ARG_RANGE                    (0x80000020)
++
++/*  Error:  Function argument (ptr to return value) was NULL  */
++#define MT_ARG_NULL                     (0x80000040)
++
++/*  Error: Attempt to open more than MT_TUNER_CNT tuners  */
++#define MT_TUNER_CNT_ERR                (0x80000080)
++
++/*  Error: Tuner Part Code / Rev Code mismatches expected value  */
++#define MT_TUNER_ID_ERR                 (0x80000100)
++
++/*  Error: Tuner Initialization failure  */
++#define MT_TUNER_INIT_ERR               (0x80000200)
++
++/*  User-definable fields (see mt_userdef.h)  */
++#define MT_USER_DEFINED1                (0x00001000)
++#define MT_USER_DEFINED2                (0x00002000)
++#define MT_USER_DEFINED3                (0x00004000)
++#define MT_USER_DEFINED4                (0x00008000)
++#define MT_USER_MASK                    (0x4000f000)
++#define MT_USER_SHIFT                   (12)
++
++/*  Info: Mask of bits used for # of LO-related spurs that were avoided during tuning  */
++#define MT_SPUR_CNT_MASK                (0x001f0000)
++#define MT_SPUR_SHIFT                   (16)
++
++/*  Info: Tuner timeout waiting for condition  */
++#define MT_TUNER_TIMEOUT                (0x00400000)
++
++/*  Info: Unavoidable LO-related spur may be present in the output  */
++#define MT_SPUR_PRESENT                 (0x00800000)
++
++/*  Info: Tuner input frequency is out of range */
++#define MT_FIN_RANGE                    (0x01000000)
++
++/*  Info: Tuner output frequency is out of range */
++#define MT_FOUT_RANGE                   (0x02000000)
++
++/*  Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */
++#define MT_UPC_RANGE                    (0x04000000)
++
++/*  Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */
++#define MT_DNC_RANGE                    (0x08000000)
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// Microtune source code - mt_userdef.h
++
++
++
++/*****************************************************************************
++**
++**  Name: mt_userdef.h
++**
++**  Description:    User-defined data types needed by MicroTuner source code.
++**
++**                  Customers must provide the code for these functions
++**                  in the file "mt_userdef.c".
++**
++**                  Customers must verify that the typedef's in the 
++**                  "Data Types" section are correct for their platform.
++**
++**  Functions
++**  Requiring
++**  Implementation: MT_WriteSub
++**                  MT_ReadSub
++**                  MT_Sleep
++**
++**  References:     None
++**
++**  Exports:        None
++**
++**  CVS ID:         $Id: mt_userdef.h,v 1.1 2006/06/22 20:18:12 software Exp $
++**  CVS Source:     $Source: /export/home/cvsroot/software/tuners/MT2266/mt_userdef.h,v $
++**	               
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   03-25-2004    DAD    Original
++**   082   12-06-2004    JWS    Multi-tuner support - requires MTxxxx_CNT 
++**                              declarations
++**
++*****************************************************************************/
++#if !defined( __MT_USERDEF_H )
++#define __MT_USERDEF_H
++
++//#include "mt_errordef.h"
++
++#if defined( __cplusplus )     
++extern "C"                     /* Use "C" external linkage                  */
++{
++#endif
++
++/*
++**  Data Types
++*/
++typedef unsigned char   U8Data;         /*  type corresponds to 8 bits      */
++typedef unsigned int    UData_t;        /*  type must be at least 32 bits   */
++typedef int             SData_t;        /*  type must be at least 32 bits   */
++typedef void *          Handle_t;       /*  memory pointer type             */
++typedef double          FData_t;        /*  floating point data type        */
++
++#define MAX_UDATA         0xffffffff  /*  max value storable in UData_t   */
++
++/*
++** Define an MTxxxx_CNT macro for each type of tuner that will be built
++** into your application (e.g., MT2121, MT2060). MT_TUNER_CNT
++** must be set to the SUM of all of the MTxxxx_CNT macros.
++**
++** #define MT2050_CNT  (1)
++** #define MT2060_CNT  (1)
++** #define MT2111_CNT  (1)
++** #define MT2121_CNT  (3)
++*/
++
++
++#if !defined( MT_TUNER_CNT )
++#define MT_TUNER_CNT               (0)  /*  total num of MicroTuner tuners  */
++#endif
++
++/*
++**  Optional user-defined Error/Info Codes  (examples below)
++**
++**  This is the area where you can define user-specific error/info return
++**  codes to be returned by any of the functions you are responsible for
++**  writing such as MT_WriteSub() and MT_ReadSub.  There are four bits
++**  available in the status field for your use.  When set, these
++**  bits will be returned in the status word returned by any tuner driver
++**  call.  If you OR in the MT_ERROR bit as well, the tuner driver code
++**  will treat the code as an error.
++**
++**  The following are a few examples of errors you can provide.
++**
++**  Example 1:
++**  You might check to see the hUserData handle is correct and issue 
++**  MY_USERDATA_INVALID which would be defined like this:
++**
++**  #define MY_USERDATA_INVALID  (MT_USER_ERROR | MT_USER_DEFINED1)
++**
++**
++**  Example 2:
++**  You might be able to provide more descriptive two-wire bus errors:
++**
++**  #define NO_ACK   (MT_USER_ERROR | MT_USER_DEFINED1)
++**  #define NO_NACK  (MT_USER_ERROR | MT_USER_DEFINED2)
++**  #define BUS_BUSY (MT_USER_ERROR | MT_USER_DEFINED3)
++**
++**
++**  Example 3:
++**  You can also provide information (non-error) feedback:
++**
++**  #define MY_INFO_1   (MT_USER_DEFINED1)
++**
++**
++**  Example 4:
++**  You can combine the fields together to make a multi-bit field.
++**  This one can provide the tuner number based off of the addr
++**  passed to MT_WriteSub or MT_ReadSub.  It assumes that
++**  MT_USER_DEFINED4 through MT_USER_DEFINED1 are contiguously. If
++**  TUNER_NUM were OR'ed into the status word on an error, you could
++**  use this to identify which tuner had the problem (and whether it
++**  was during a read or write operation).
++**
++**  #define TUNER_NUM  ((addr & 0x07) >> 1) << MT_USER_SHIFT
++**
++*/
++
++/*****************************************************************************
++**
++**  Name: MT_WriteSub
++**
++**  Description:    Write values to device using a two-wire serial bus.
++**
++**  Parameters:     hUserData  - User-specific I/O parameter that was
++**                               passed to tuner's Open function.
++**                  addr       - device serial bus address  (value passed
++**                               as parameter to MTxxxx_Open)
++**                  subAddress - serial bus sub-address (Register Address)
++**                  pData      - pointer to the Data to be written to the 
++**                               device 
++**                  cnt        - number of bytes/registers to be written
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_COMM_ERR      - Serial bus communications error
++**                      user-defined
++**
++**  Notes:          This is a callback function that is called from the
++**                  the tuning algorithm.  You MUST provide code for this
++**                  function to write data using the tuner's 2-wire serial 
++**                  bus.
++**
++**                  The hUserData parameter is a user-specific argument.
++**                  If additional arguments are needed for the user's
++**                  serial bus read/write functions, this argument can be
++**                  used to supply the necessary information.
++**                  The hUserData parameter is initialized in the tuner's Open
++**                  function.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   03-25-2004    DAD    Original
++**
++*****************************************************************************/
++UData_t MT_WriteSub(Handle_t hUserData, 
++                    UData_t addr, 
++                    U8Data subAddress, 
++                    U8Data *pData, 
++                    UData_t cnt);
++
++
++/*****************************************************************************
++**
++**  Name: MT_ReadSub
++**
++**  Description:    Read values from device using a two-wire serial bus.
++**
++**  Parameters:     hUserData  - User-specific I/O parameter that was
++**                               passed to tuner's Open function.
++**                  addr       - device serial bus address  (value passed
++**                               as parameter to MTxxxx_Open)
++**                  subAddress - serial bus sub-address (Register Address)
++**                  pData      - pointer to the Data to be written to the 
++**                               device 
++**                  cnt        - number of bytes/registers to be written
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_COMM_ERR      - Serial bus communications error
++**                      user-defined
++**
++**  Notes:          This is a callback function that is called from the
++**                  the tuning algorithm.  You MUST provide code for this
++**                  function to read data using the tuner's 2-wire serial 
++**                  bus.
++**
++**                  The hUserData parameter is a user-specific argument.
++**                  If additional arguments are needed for the user's
++**                  serial bus read/write functions, this argument can be
++**                  used to supply the necessary information.
++**                  The hUserData parameter is initialized in the tuner's Open
++**                  function.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   03-25-2004    DAD    Original
++**
++*****************************************************************************/
++UData_t MT_ReadSub(Handle_t hUserData, 
++                   UData_t addr, 
++                   U8Data subAddress, 
++                   U8Data *pData, 
++                   UData_t cnt);
++
++
++/*****************************************************************************
++**
++**  Name: MT_Sleep
++**
++**  Description:    Delay execution for "nMinDelayTime" milliseconds
++**
++**  Parameters:     hUserData     - User-specific I/O parameter that was
++**                                  passed to tuner's Open function.
++**                  nMinDelayTime - Delay time in milliseconds
++**
++**  Returns:        None.
++**
++**  Notes:          This is a callback function that is called from the
++**                  the tuning algorithm.  You MUST provide code that
++**                  blocks execution for the specified period of time. 
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   03-25-2004    DAD    Original
++**
++*****************************************************************************/
++void MT_Sleep(Handle_t hUserData,
++              UData_t nMinDelayTime);
++
++
++#if defined(MT2060_CNT)
++#if MT2060_CNT > 0
++/*****************************************************************************
++**
++**  Name: MT_TunerGain  (for MT2060 only)
++**
++**  Description:    Measure the relative tuner gain using the demodulator
++**
++**  Parameters:     hUserData  - User-specific I/O parameter that was
++**                               passed to tuner's Open function.
++**                  pMeas      - Tuner gain (1/100 of dB scale).
++**                               ie. 1234 = 12.34 (dB)
++**
++**  Returns:        status:
++**                      MT_OK  - No errors
++**                      user-defined errors could be set
++**
++**  Notes:          This is a callback function that is called from the
++**                  the 1st IF location routine.  You MUST provide
++**                  code that measures the relative tuner gain in a dB
++**                  (not linear) scale.  The return value is an integer
++**                  value scaled to 1/100 of a dB.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   06-16-2004    DAD    Original
++**   N/A   11-30-2004    DAD    Renamed from MT_DemodInputPower.  This name
++**                              better describes what this function does.
++**
++*****************************************************************************/
++UData_t MT_TunerGain(Handle_t hUserData,
++                     SData_t* pMeas);
++#endif
++#endif
++
++#if defined( __cplusplus )     
++}
++#endif
++
++#endif
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// Microtune source code - mt2266.h
++
++
++
++/*****************************************************************************
++**
++**  Name: mt2266.h
++**
++**  Copyright 2007 Microtune, Inc. All Rights Reserved
++**
++**  This source code file contains confidential information and/or trade
++**  secrets of Microtune, Inc. or its affiliates and is subject to the
++**  terms of your confidentiality agreement with Microtune, Inc. or one of
++**  its affiliates, as applicable.
++**
++*****************************************************************************/
++
++/*****************************************************************************
++**
++**  Name: mt2266.h
++**
++**  Description:    Microtune MT2266 Tuner software interface.
++**                  Supports tuners with Part/Rev code: 0x85.
++**
++**  Functions
++**  Implemented:    UData_t  MT2266_Open
++**                  UData_t  MT2266_Close
++**                  UData_t  MT2266_ChangeFreq
++**                  UData_t  MT2266_GetLocked
++**                  UData_t  MT2266_GetParam
++**                  UData_t  MT2266_GetReg
++**                  UData_t  MT2266_GetUHFXFreqs
++**                  UData_t  MT2266_GetUserData
++**                  UData_t  MT2266_ReInit
++**                  UData_t  MT2266_SetParam
++**                  UData_t  MT2266_SetPowerModes
++**                  UData_t  MT2266_SetReg
++**                  UData_t  MT2266_SetUHFXFreqs
++**                  UData_t  MT2266_Tune
++**
++**  References:     AN-00010: MicroTuner Serial Interface Application Note
++**                  MicroTune, Inc.
++**
++**  Exports:        None
++**
++**  Dependencies:   MT_ReadSub(hUserData, IC_Addr, subAddress, *pData, cnt);
++**                  - Read byte(s) of data from the two-wire bus.
++**
++**                  MT_WriteSub(hUserData, IC_Addr, subAddress, *pData, cnt);
++**                  - Write byte(s) of data to the two-wire bus.
++**
++**                  MT_Sleep(hUserData, nMinDelayTime);
++**                  - Delay execution for x milliseconds
++**
++**  CVS ID:         $Id: mt2266.h,v 1.3 2007/10/02 18:43:17 software Exp $
++**  CVS Source:     $Source: /export/home/cvsroot/software/tuners/MT2266/mt2266.h,v $
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   05-30-2006    DAD    Ver 1.0: Modified version of mt2260.c (Ver 1.01).
++**   N/A   11-01-2006    RSK    Ver 1.02: Adding Get/Set UHFXFreq access functions.
++**   118   05-09-2007    RSK    Ver 1.05: Adding Standard MTxxxx_Tune() API.
++**
++*****************************************************************************/
++#if !defined( __MT2266_H )
++#define __MT2266_H
++
++//#include "mt_userdef.h"
++
++#if defined( __cplusplus )
++extern "C"                     /* Use "C" external linkage                  */
++{
++#endif
++
++/*
++**  Parameter for function MT2266_GetParam & MT2266_SetParam that
++**  specifies the tuning algorithm parameter to be read/written.
++*/
++typedef enum
++{
++    /*  tuner address                                  set by MT2266_Open() */
++    MT2266_IC_ADDR,
++
++    /*  max number of MT2266 tuners       set by MT2266_CNT in mt_userdef.h */
++    MT2266_MAX_OPEN,
++
++    /*  current number of open MT2266 tuners           set by MT2266_Open() */
++    MT2266_NUM_OPEN,
++
++    /*  Number of tuner registers                                           */
++    MT2266_NUM_REGS,
++
++    /*  crystal frequency                            (default: 18000000 Hz) */
++    MT2266_SRO_FREQ,
++
++    /*  min tuning step size                            (default: 50000 Hz) */
++    MT2266_STEPSIZE,
++
++    /*  input center frequency                   set by MT2266_ChangeFreq() */
++    MT2266_INPUT_FREQ,
++
++    /*  LO Frequency                             set by MT2266_ChangeFreq() */
++    MT2266_LO_FREQ,
++
++    /*  output channel bandwidth                      (default: 8000000 Hz) */
++    MT2266_OUTPUT_BW,
++
++    /*  Base band filter calibration RC code                 (default: N/A) */
++    MT2266_RC2_VALUE,
++
++    /*  Base band filter nominal cal RC code                 (default: N/A) */
++    MT2266_RC2_NOMINAL,
++
++    /*  RF attenuator A/D readback                              (read-only) */
++    MT2266_RF_ADC,
++
++    /*  BB attenuator A/D readback                              (read-only) */
++    MT2266_BB_ADC,
++
++    /*  RF attenuator setting                             (default: varies) */
++    MT2266_RF_ATTN,
++
++    /*  BB attenuator setting                             (default: varies) */
++    MT2266_BB_ATTN,
++
++    /*  RF external / internal atten control              (default: varies) */
++    MT2266_RF_EXT,
++
++    /*  BB external / internal atten control                   (default: 1) */
++    MT2266_BB_EXT,
++
++    /*  LNA gain setting (0-15)                           (default: varies) */
++    MT2266_LNA_GAIN,
++
++    /*  Decrement LNA Gain (where arg=min LNA Gain value)                   */
++    MT2266_LNA_GAIN_DECR,
++
++    /*  Increment LNA Gain (where arg=max LNA Gain value)                   */
++    MT2266_LNA_GAIN_INCR,
++
++    /*  Set for UHF max sensitivity mode                                    */
++    MT2266_UHF_MAXSENS,
++
++    /*  Set for UHF normal mode                                             */
++    MT2266_UHF_NORMAL,
++
++    MT2266_EOP                    /*  last entry in enumerated list         */
++} MT2266_Param;
++
++
++/*
++**  Parameter for function MT2266_GetUHFXFreqs & MT2266_SetUHFXFreqs that
++**  specifies the particular frequency crossover table to be read/written.
++*/
++typedef enum
++{
++    /*  Reference the UHF 0 filter, without any attenuation                 */
++    MT2266_UHF0,
++
++    /*  Reference the UHF 1 filter, without any attenuation                 */
++    MT2266_UHF1,
++
++    /*  Reference the UHF 0 filter, with attenuation                        */
++    MT2266_UHF0_ATTEN,
++
++    /*  Reference the UHF 1 filter, with attenuation                        */
++    MT2266_UHF1_ATTEN,
++
++    MT2266_NUMBER_OF_XFREQ_SETS    /*  last entry in enumerated list        */
++
++} MT2266_UHFXFreq_Type;
++
++
++#define  MT2266_NUM_XFREQS  (16)
++
++typedef  UData_t MT2266_XFreq_Set[ MT2266_NUM_XFREQS ];
++
++/*
++**  Constants for Specifying Operating Band of the Tuner
++*/
++#define MT2266_VHF_BAND (0)
++#define MT2266_UHF_BAND (1)
++#define MT2266_L_BAND   (2)
++
++/*
++**  Constants for specifying power modes these values
++**  are bit-mapped and can be added/OR'ed to indicate
++**  multiple settings.  Examples:
++**     MT2266_SetPowerModes(h, MT2266_NO_ENABLES + MT22266_SROsd);
++**     MT2266_SetPowerModes(h, MT2266_ALL_ENABLES | MT22266_SRO_NOT_sd);
++**     MT2266_SetPowerModes(h, MT2266_NO_ENABLES + MT22266_SROsd);
++**     MT2266_SetPowerModes(h, MT2266_SROen + MT22266_LOen + MT2266_ADCen);
++*/
++#define MT2266_SROen       (0x01)
++#define MT2266_LOen        (0x02)
++#define MT2266_ADCen       (0x04)
++#define MT2266_PDen        (0x08)
++#define MT2266_DCOCen      (0x10)
++#define MT2266_BBen        (0x20)
++#define MT2266_MIXen       (0x40)
++#define MT2266_LNAen       (0x80)
++#define MT2266_ALL_ENABLES (0xFF)
++#define MT2266_NO_ENABLES  (0x00)
++#define MT2266_SROsd       (0x100)
++#define MT2266_SRO_NOT_sd  (0x000)
++
++/* ====== Functions which are declared in mt2266.c File ======= */
++
++/******************************************************************************
++**
++**  Name: MT2266_Open
++**
++**  Description:    Initialize the tuner's register values.
++**
++**  Usage:          status = MT2266_Open(0xC0, &hMT2266, NULL);
++**                  if (MT_IS_ERROR(status))
++**                      //  Check error codes for reason
++**
++**  Parameters:     MT2266_Addr  - Serial bus address of the tuner.
++**                  hMT2266      - 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
++**  -------------------------------------------------------------------------
++**   N/A   02-03-2006   DAD/JWS Original.
++**
++******************************************************************************/
++UData_t MT2266_Open(UData_t MT2266_Addr,
++                    Handle_t* hMT2266,
++                    Handle_t hUserData);
++
++
++/******************************************************************************
++**
++**  Name: MT2266_Close
++**
++**  Description:    Release the handle to the tuner.
++**
++**  Parameters:     hMT2266      - Handle to the MT2266 tuner
++**
++**  Usage:          status = MT2266_Close(hMT2266);
++**
++**  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
++**  -------------------------------------------------------------------------
++**   N/A   02-03-2006   DAD/JWS Original.
++**
++******************************************************************************/
++UData_t MT2266_Close(Handle_t hMT2266);
++
++
++/****************************************************************************
++**
++**  Name: MT2266_ChangeFreq
++**
++**  Description:    Change the tuner's tuned frequency to f_in.
++**
++**  Parameters:     h           - Open handle to the tuner (from MT2266_Open).
++**                  f_in        - RF input center frequency (in Hz).
++**
++**  Usage:          status = MT2266_ChangeFreq(hMT2266, f_in);
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**                      MT_DNC_UNLOCK    - Downconverter PLL unlocked
++**                      MT_COMM_ERR      - Serial bus communications error
++**                      MT_FIN_RANGE     - Input freq out of range
++**                      MT_DNC_RANGE     - Downconverter freq out of range
++**
++**  Dependencies:   MUST CALL MT2266_Open BEFORE MT2266_ChangeFreq!
++**
++**                  MT_ReadSub       - Read byte(s) of data from the two-wire-bus
++**                  MT_WriteSub      - Write byte(s) of data to the two-wire-bus
++**                  MT_Sleep         - Delay execution for x milliseconds
++**                  MT2266_GetLocked - Checks to see if the PLL is locked
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   02-03-2006   DAD/JWS Original.
++**
++******************************************************************************/
++UData_t MT2266_ChangeFreq(Handle_t h,
++                          UData_t f_in);
++
++
++/****************************************************************************
++**
++**  Name: MT2266_GetLocked
++**
++**  Description:    Checks to see if the PLL is locked.
++**
++**  Parameters:     h            - Open handle to the tuner (from MT2266_Open).
++**
++**  Usage:          status = MT2266_GetLocked(hMT2266);
++**                  if (status & MT_DNC_UNLOCK)
++**                      //  error!, PLL is unlocked
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      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
++**  -------------------------------------------------------------------------
++**   N/A   02-03-2006   DAD/JWS Original.
++**
++****************************************************************************/
++UData_t MT2266_GetLocked(Handle_t h);
++
++
++/****************************************************************************
++**
++**  Name: MT2266_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 MT2266_Open)
++**                  param       - Tuning algorithm parameter
++**                                (see enum MT2266_Param)
++**                  pValue      - ptr to returned value
++**
++**                  param                   Description
++**                  ----------------------  --------------------------------
++**                  MT2266_IC_ADDR          Serial Bus address of this tuner
++**                  MT2266_MAX_OPEN         Max number of MT2266's that can be open
++**                  MT2266_NUM_OPEN         Number of MT2266's currently open
++**                  MT2266_NUM_REGS         Number of tuner registers
++**                  MT2266_SRO_FREQ         crystal frequency
++**                  MT2266_STEPSIZE         minimum tuning step size
++**                  MT2266_INPUT_FREQ       input center frequency
++**                  MT2266_LO_FREQ          LO Frequency
++**                  MT2266_OUTPUT_BW        Output channel bandwidth
++**                  MT2266_RC2_VALUE        Base band filter cal RC code (method 2)
++**                  MT2266_RF_ADC           RF attenuator A/D readback
++**                  MT2266_RF_ATTN          RF attenuation (0-255)
++**                  MT2266_RF_EXT           External control of RF atten
++**                  MT2266_LNA_GAIN         LNA gain setting (0-15)
++**                  MT2266_BB_ADC           BB attenuator A/D readback
++**                  MT2266_BB_ATTN          Baseband attenuation (0-255)
++**                  MT2266_BB_EXT           External control of BB atten
++**
++**  Usage:          status |= MT2266_GetParam(hMT2266,
++**                                            MT2266_OUTPUT_BW,
++**                                            &f_bw);
++**
++**  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 MT2266_Open() FIRST!
++**
++**  See Also:       MT2266_SetParam, MT2266_Open
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   02-03-2006   DAD/JWS Original.
++**
++****************************************************************************/
++UData_t MT2266_GetParam(Handle_t     h,
++                        MT2266_Param param,
++                        UData_t*     pValue);
++
++
++/****************************************************************************
++**
++**  Name: MT2266_GetReg
++**
++**  Description:    Gets an MT2266 register.
++**
++**  Parameters:     h           - Tuner handle (returned by MT2266_Open)
++**                  reg         - MT2266 register/subaddress location
++**                  *val        - MT2266 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 MT2266_Open() FIRST!
++**
++**                  Use this function if you need to read a register from
++**                  the MT2266.
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   02-03-2006   DAD/JWS Original.
++**
++****************************************************************************/
++UData_t MT2266_GetReg(Handle_t h,
++                      U8Data   reg,
++                      U8Data*  val);
++
++
++/****************************************************************************
++**
++**  Name: MT2266_GetUHFXFreqs
++**
++**  Description:    Retrieves the specified set of UHF Crossover Frequencies
++**
++**  Parameters:     h            - Open handle to the tuner (from MT2266_Open).
++**
++**  Usage:          MT2266_Freq_Set  tmpFreqs;
++**                  status = MT2266_GetUHFXFreqs(hMT2266,
++**                                               MT2266_UHF1_WITH_ATTENUATION,
++**                                               tmpFreqs );
++**                  if (status & MT_ARG_RANGE)
++**                      // error, Invalid UHF Crossover Frequency Set requested.
++**                  else
++**                      for( int i = 0;  i < MT2266_NUM_XFREQS; i++ )
++**                         . . .
++**
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_ARG_RANGE     - freq_type is out of range.
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**
++**  Dependencies:   freqs_buffer *must* be defined of type MT2266_Freq_Set
++**                     to assure sufficient space allocation!
++**
++**                  USERS MUST CALL MT2266_Open() FIRST!
++**
++**  See Also:       MT2266_SetUHFXFreqs
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   11-01-2006   RSK     Original.
++**
++****************************************************************************/
++UData_t MT2266_GetUHFXFreqs(Handle_t             h,
++                            MT2266_UHFXFreq_Type freq_type,
++                            MT2266_XFreq_Set     freqs_buffer);
++
++
++/****************************************************************************
++**
++**  Name: MT2266_GetUserData
++**
++**  Description:    Gets the user-defined data item.
++**
++**  Parameters:     h           - Tuner handle (returned by MT2266_Open)
++**
++**  Usage:          status = MT2266_GetUserData(hMT2266, &hUserData);
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**                      MT_ARG_NULL      - Null pointer argument passed
++**
++**  Dependencies:   USERS MUST CALL MT2266_Open() FIRST!
++**
++**                  The hUserData parameter is a user-specific argument
++**                  that is stored internally with the other tuner-
++**                  specific information.
++**
++**                  For example, if additional arguments are needed
++**                  for the user to identify the device communicating
++**                  with the tuner, this argument can be used to supply
++**                  the necessary information.
++**
++**                  The hUserData parameter is initialized in the tuner's
++**                  Open function to NULL.
++**
++**  See Also:       MT2266_SetUserData, MT2266_Open
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   02-03-2006   DAD/JWS Original.
++**
++****************************************************************************/
++UData_t MT2266_GetUserData(Handle_t  h,
++                           Handle_t* hUserData);
++
++
++/******************************************************************************
++**
++**  Name: MT2266_ReInit
++**
++**  Description:    Initialize the tuner's register values.
++**
++**  Parameters:     h           - Tuner handle (returned by MT2266_Open)
++**
++**  Returns:        status:
++**                      MT_OK             - No errors
++**                      MT_TUNER_ID_ERR   - Tuner Part/Rev code mismatch
++**                      MT_TUNER_INIT_ERR - Tuner initialization failed
++**                      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
++**  -------------------------------------------------------------------------
++**   N/A   02-03-2006   DAD/JWS Original.
++**
++******************************************************************************/
++UData_t MT2266_ReInit(Handle_t h);
++
++
++/****************************************************************************
++**
++**  Name: MT2266_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 MT2266_Open)
++**                  param       - Tuning algorithm parameter
++**                                (see enum MT2266_Param)
++**                  nValue      - value to be set
++**
++**                  param                   Description
++**                  ----------------------  --------------------------------
++**                  MT2266_SRO_FREQ         crystal frequency
++**                  MT2266_STEPSIZE         minimum tuning step size
++**                  MT2266_INPUT_FREQ       Center of input channel
++**                  MT2266_OUTPUT_BW        Output channel bandwidth
++**                  MT2266_RF_ATTN          RF attenuation (0-255)
++**                  MT2266_RF_EXT           External control of RF atten
++**                  MT2266_LNA_GAIN         LNA gain setting (0-15)
++**                  MT2266_LNA_GAIN_DECR    Decrement LNA Gain (arg=min)
++**                  MT2266_LNA_GAIN_INCR    Increment LNA Gain (arg=max)
++**                  MT2266_BB_ATTN          Baseband attenuation (0-255)
++**                  MT2266_BB_EXT           External control of BB atten
++**                  MT2266_UHF_MAXSENS      Set for UHF max sensitivity mode
++**                  MT2266_UHF_NORMAL       Set for UHF normal mode
++**
++**  Usage:          status |= MT2266_SetParam(hMT2266,
++**                                            MT2266_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 MT2266_Open() FIRST!
++**
++**  See Also:       MT2266_GetParam, MT2266_Open
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   02-03-2006   DAD/JWS Original.
++**
++****************************************************************************/
++UData_t MT2266_SetParam(Handle_t     h,
++                        MT2266_Param param,
++                        UData_t      nValue);
++
++
++/****************************************************************************
++**
++**  Name: MT2266_SetPowerModes
++**
++**  Description:    Sets the bits in the MT2266_ENABLES register and the
++**                  SROsd bit in the MT2266_SROADC_CTRL register.
++**
++**  Parameters:     h           - Tuner handle (returned by MT2266_Open)
++**                  flags       - Bit mask of flags to indicate enabled
++**                                bits.
++**
++**  Usage:          status = MT2266_SetPowerModes(hMT2266, flags);
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**
++**  Dependencies:   USERS MUST CALL MT2266_Open() FIRST!
++**
++**                  The bits in the MT2266_ENABLES register and the
++**                  SROsd bit are set according to the supplied flags.
++**
++**                  The pre-defined flags are as follows:
++**                      MT2266_SROen
++**                      MT2266_LOen
++**                      MT2266_ADCen
++**                      MT2266_PDen
++**                      MT2266_DCOCen
++**                      MT2266_BBen
++**                      MT2266_MIXen
++**                      MT2266_LNAen
++**                      MT2266_ALL_ENABLES
++**                      MT2266_NO_ENABLES
++**                      MT2266_SROsd
++**                      MT2266_SRO_NOT_sd
++**
++**                  ONLY the enable bits (or SROsd bit) specified in the
++**                  flags parameter will be set.  Any flag which is not
++**                  included, will cause that bit to be disabled.
++**
++**                  The ALL_ENABLES, NO_ENABLES, and SRO_NOT_sd constants
++**                  are for convenience.  The NO_ENABLES and SRO_NOT_sd
++**                  do not actually have to be included, but are provided
++**                  for clarity.
++**
++**  See Also:       MT2266_Open
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   02-03-2006   DAD/JWS Original.
++**
++****************************************************************************/
++UData_t MT2266_SetPowerModes(Handle_t h,
++                             UData_t  flags);
++
++
++/****************************************************************************
++**
++**  Name: MT2266_SetReg
++**
++**  Description:    Sets an MT2266 register.
++**
++**  Parameters:     h           - Tuner handle (returned by MT2266_Open)
++**                  reg         - MT2266 register/subaddress location
++**                  val         - MT2266 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 MT2266_Open() FIRST!
++**
++**                  Use this function if you need to override a default
++**                  register value
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   02-03-2006   DAD/JWS Original.
++**
++****************************************************************************/
++UData_t MT2266_SetReg(Handle_t h,
++                      U8Data   reg,
++                      U8Data   val);
++
++
++/****************************************************************************
++**
++**  Name: MT2266_SetUHFXFreqs
++**
++**  Description:    Retrieves the specified set of UHF Crossover Frequencies
++**
++**  Parameters:     h            - Open handle to the tuner (from MT2266_Open).
++**
++**  Usage:          MT2266_Freq_Set  tmpFreqs;
++**                  status = MT2266_SetUHFXFreqs(hMT2266,
++**                                               MT2266_UHF1_WITH_ATTENUATION,
++**                                               tmpFreqs );
++**                  if (status & MT_ARG_RANGE)
++**                      // error, Invalid UHF Crossover Frequency Set requested.
++**                  else
++**                      for( int i = 0;  i < MT2266_NUM_XFREQS; i++ )
++**                         . . .
++**
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_ARG_RANGE     - freq_type is out of range.
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**
++**  Dependencies:   freqs_buffer *must* be defined of type MT2266_Freq_Set
++**                     to assure sufficient space allocation!
++**
++**                  USERS MUST CALL MT2266_Open() FIRST!
++**
++**  See Also:       MT2266_SetUHFXFreqs
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   11_01-2006   RSK     Original.
++**
++****************************************************************************/
++UData_t MT2266_SetUHFXFreqs(Handle_t             h,
++                            MT2266_UHFXFreq_Type freq_type,
++                            MT2266_XFreq_Set     freqs_buffer);
++
++
++/****************************************************************************
++**
++**  Name: MT2266_Tune
++**
++**  Description:    Change the tuner's tuned frequency to f_in.
++**
++**  Parameters:     h           - Open handle to the tuner (from MT2266_Open).
++**                  f_in        - RF input center frequency (in Hz).
++**
++**  Usage:          status = MT2266_Tune(hMT2266, f_in);
++**
++**  Returns:        status:
++**                      MT_OK            - No errors
++**                      MT_INV_HANDLE    - Invalid tuner handle
++**                      MT_DNC_UNLOCK    - Downconverter PLL unlocked
++**                      MT_COMM_ERR      - Serial bus communications error
++**                      MT_FIN_RANGE     - Input freq out of range
++**                      MT_DNC_RANGE     - Downconverter freq out of range
++**
++**  Dependencies:   MUST CALL MT2266_Open BEFORE MT2266_Tune!
++**
++**                  MT_ReadSub       - Read byte(s) of data from the two-wire-bus
++**                  MT_WriteSub      - Write byte(s) of data to the two-wire-bus
++**                  MT_Sleep         - Delay execution for x milliseconds
++**                  MT2266_GetLocked - Checks to see if the PLL is locked
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   118   05-09-2007   RSK     Original API Introduction (was ChangeFreq).
++**
++******************************************************************************/
++UData_t MT2266_Tune(Handle_t h,
++                    UData_t f_in);
++
++
++#if defined( __cplusplus )
++}
++#endif
++
++#endif
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// The following context is MT2266 tuner API source code
++
++
++
++
++
++/**
++
++@file
++
++@brief   MT2266 tuner module declaration
++
++One can manipulate MT2266 tuner through MT2266 module.
++MT2266 module is derived from tuner module.
++
++*/
++
++
++#include "tuner_base.h"
++
++
++
++
++
++// Definitions
++
++// MT2266 API option
++#define __NO_CACHE__
++#define MT2266_CNT		4
++
++
++// Bandwidth modes
++enum MT2266_BANDWIDTH_HZ
++{
++	MT2266_BANDWIDTH_5MHZ = 5000000,
++	MT2266_BANDWIDTH_6MHZ = 6000000,
++	MT2266_BANDWIDTH_7MHZ = 7000000,
++	MT2266_BANDWIDTH_8MHZ = 8000000,
++};
++
++
++
++
++
++/// MT2266 extra module alias
++typedef struct MT2266_EXTRA_MODULE_TAG MT2266_EXTRA_MODULE;
++
++
++
++
++
++// MT2266 handle openning function pointer
++typedef int
++(*MT2266_FP_OPEN_HANDLE)(
++	TUNER_MODULE *pTuner
++	);
++
++
++
++// MT2266 handle closing function pointer
++typedef int
++(*MT2266_FP_CLOSE_HANDLE)(
++	TUNER_MODULE *pTuner
++	);
++
++
++
++// MT2266 handle getting function pointer
++typedef void
++(*MT2266_FP_GET_HANDLE)(
++	TUNER_MODULE *pTuner,
++	void **pDeviceHandle
++	);
++
++
++
++// MT2266 bandwidth setting function pointer
++typedef int
++(*MT2266_FP_SET_BANDWIDTH_HZ)(
++	TUNER_MODULE *pTuner,
++	unsigned long BandwidthHz
++	);
++
++
++
++// MT2266 bandwidth getting function pointer
++typedef int
++(*MT2266_FP_GET_BANDWIDTH_HZ)(
++	TUNER_MODULE *pTuner,
++	unsigned long *pBandwidthHz
++	);
++
++
++
++
++
++// MT2266 extra module
++struct MT2266_EXTRA_MODULE_TAG
++{
++	// MT2266 extra variables
++	void *DeviceHandle;
++	unsigned long BandwidthHz;
++	int IsBandwidthHzSet;
++
++	// MT2266 extra function pointers
++	MT2266_FP_OPEN_HANDLE        OpenHandle;
++	MT2266_FP_CLOSE_HANDLE       CloseHandle;
++	MT2266_FP_GET_HANDLE         GetHandle;
++	MT2266_FP_SET_BANDWIDTH_HZ   SetBandwidthHz;
++	MT2266_FP_GET_BANDWIDTH_HZ   GetBandwidthHz;
++};
++
++
++
++
++
++// Builder
++void
++BuildMt2266Module(
++	TUNER_MODULE **ppTuner,
++	TUNER_MODULE *pTunerModuleMemory,
++	MT2266_EXTRA_MODULE *pMt2266ExtraModuleMemory,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory,
++	unsigned char DeviceAddr
++	);
++
++
++
++
++
++// Manipulaing functions
++void
++mt2266_GetTunerType(
++	TUNER_MODULE *pTuner,
++	int *pTunerType
++	);
++
++void
++mt2266_GetDeviceAddr(
++	TUNER_MODULE *pTuner,
++	unsigned char *pDeviceAddr
++	);
++
++int
++mt2266_Initialize(
++	TUNER_MODULE *pTuner
++	);
++
++int
++mt2266_SetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long RfFreqHz
++	);
++
++int
++mt2266_GetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long *pRfFreqHz
++	);
++
++
++
++
++
++// Extra manipulaing functions
++int
++mt2266_OpenHandle(
++	TUNER_MODULE *pTuner
++	);
++
++int
++mt2266_CloseHandle(
++	TUNER_MODULE *pTuner
++	);
++
++void
++mt2266_GetHandle(
++	TUNER_MODULE *pTuner,
++	void **pDeviceHandle
++	);
++
++int
++mt2266_SetBandwidthHz(
++	TUNER_MODULE *pTuner,
++	unsigned long BandwidthHz
++	);
++
++int
++mt2266_GetBandwidthHz(
++	TUNER_MODULE *pTuner,
++	unsigned long *pBandwidthHz
++	);
++
++
++
++
++
++// I2C birdge module demod argument setting
++void
++mt2266_SetI2cBridgeModuleTunerArg(
++	TUNER_MODULE *pTuner
++	);
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++#endif
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/tuner_mxl5007t.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/tuner_mxl5007t.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,1289 @@
++/**
++
++@file
++
++@brief   MxL5007T tuner module definition
++
++One can manipulate MxL5007T tuner through MxL5007T module.
++MxL5007T module is derived from tuner module.
++
++*/
++
++
++#include "tuner_mxl5007t.h"
++
++
++
++
++
++/**
++
++@brief   MxL5007T tuner module builder
++
++Use BuildMxl5007tModule() to build MxL5007T module, set all module function pointers with the corresponding functions,
++and initialize module private variables.
++
++
++@param [in]   ppTuner                      Pointer to MxL5007T tuner module pointer
++@param [in]   pTunerModuleMemory           Pointer to an allocated tuner module memory
++@param [in]   pMxl5007tExtraModuleMemory   Pointer to an allocated MxL5007T extra module memory
++@param [in]   pBaseInterfaceModuleMemory   Pointer to an allocated base interface module memory
++@param [in]   pI2cBridgeModuleMemory       Pointer to an allocated I2C bridge module memory
++@param [in]   DeviceAddr                   MxL5007T I2C device address
++@param [in]   CrystalFreqHz                MxL5007T crystal frequency in Hz
++@param [in]   AgcMode                      MxL5007T AGC mode
++
++
++@note
++	-# One should call BuildMxl5007tModule() to build MxL5007T module before using it.
++
++*/
++void
++BuildMxl5007tModule(
++	TUNER_MODULE **ppTuner,
++	TUNER_MODULE *pTunerModuleMemory,
++	MXL5007T_EXTRA_MODULE *pMxl5007tExtraModuleMemory,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory,
++	unsigned char DeviceAddr,
++	unsigned long CrystalFreqHz,
++	int StandardMode,
++	unsigned long IfFreqHz,
++	int SpectrumMode,
++	int ClkOutMode,
++	int ClkOutAmpMode,
++	long QamIfDiffOutLevel
++	)
++{
++	TUNER_MODULE *pTuner;
++	MXL5007T_EXTRA_MODULE *pExtra;
++	MxL5007_TunerConfigS *pTunerConfigS;
++
++
++
++	// Set tuner module pointer.
++	*ppTuner = pTunerModuleMemory;
++
++	// Get tuner module.
++	pTuner = *ppTuner;
++
++	// Set tuner extra module pointer, base interface module pointer, and I2C bridge module pointer.
++	pTuner->pExtra         = pMxl5007tExtraModuleMemory;
++	pTuner->pBaseInterface = pBaseInterfaceModuleMemory;
++	pTuner->pI2cBridge     = pI2cBridgeModuleMemory;
++
++	// Get tuner extra module.
++	pExtra = (MXL5007T_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Set and get MaxLinear-defined MxL5007T structure pointer.
++	pExtra->pTunerConfigS = &(pExtra->TunerConfigSMemory);
++	pTunerConfigS = pExtra->pTunerConfigS;
++
++	// Set additional definition tuner module pointer.
++	pTunerConfigS->pTuner = pTuner;
++
++
++
++	// Set tuner type.
++	pTuner->TunerType = TUNER_TYPE_MXL5007T;
++
++	// Set tuner I2C device address.
++	pTuner->DeviceAddr = DeviceAddr;
++
++
++	// Initialize tuner parameter setting status.
++	pTuner->IsRfFreqHzSet = NO;
++
++
++	// Set I2C bridge tuner arguments.
++	mxl5007t_SetI2cBridgeModuleTunerArg(pTuner);
++
++
++	// Set tuner module manipulating function pointers.
++	pTuner->GetTunerType  = mxl5007t_GetTunerType;
++	pTuner->GetDeviceAddr = mxl5007t_GetDeviceAddr;
++
++	pTuner->Initialize    = mxl5007t_Initialize;
++	pTuner->SetRfFreqHz   = mxl5007t_SetRfFreqHz;
++	pTuner->GetRfFreqHz   = mxl5007t_GetRfFreqHz;
++
++
++	// Initialize tuner extra module variables.
++	pExtra->IsBandwidthModeSet = NO;
++
++
++	// Initialize MaxLinear-defined MxL5007T structure variables.
++	// Note: The API doesn't use I2C device address of MaxLinear-defined MxL5007T structure.
++	switch(StandardMode)
++	{
++		default:
++		case MXL5007T_STANDARD_DVBT:	pTunerConfigS->Mode = MxL_MODE_DVBT;		break;
++		case MXL5007T_STANDARD_ATSC:	pTunerConfigS->Mode = MxL_MODE_ATSC;		break;
++		case MXL5007T_STANDARD_QAM:		pTunerConfigS->Mode = MxL_MODE_CABLE;		break;
++		case MXL5007T_STANDARD_ISDBT:	pTunerConfigS->Mode = MxL_MODE_ISDBT;		break;
++	}
++
++	pTunerConfigS->IF_Diff_Out_Level = (SINT32)QamIfDiffOutLevel;
++
++	switch(CrystalFreqHz)
++	{
++		default:
++		case CRYSTAL_FREQ_16000000HZ:	pTunerConfigS->Xtal_Freq = MxL_XTAL_16_MHZ;			break;
++		case CRYSTAL_FREQ_25000000HZ:	pTunerConfigS->Xtal_Freq = MxL_XTAL_25_MHZ;			break;
++		case CRYSTAL_FREQ_27000000HZ:	pTunerConfigS->Xtal_Freq = MxL_XTAL_27_MHZ;			break;
++		case CRYSTAL_FREQ_28800000HZ:	pTunerConfigS->Xtal_Freq = MxL_XTAL_28_8_MHZ;		break;
++	}
++
++	switch(IfFreqHz)
++	{
++		default:
++		case IF_FREQ_4570000HZ:		pTunerConfigS->IF_Freq = MxL_IF_4_57_MHZ;		break;
++		case IF_FREQ_44000000HZ:	pTunerConfigS->IF_Freq = MxL_IF_44_MHZ;			break;
++	}
++
++	switch(SpectrumMode)
++	{
++		default:
++		case SPECTRUM_NORMAL:		pTunerConfigS->IF_Spectrum = MxL_NORMAL_IF;			break;
++		case SPECTRUM_INVERSE:		pTunerConfigS->IF_Spectrum = MxL_INVERT_IF;			break;
++	}
++
++	switch(ClkOutMode)
++	{
++		default:
++		case MXL5007T_CLK_OUT_DISABLE:		pTunerConfigS->ClkOut_Setting = MxL_CLKOUT_DISABLE;			break;
++		case MXL5007T_CLK_OUT_ENABLE:		pTunerConfigS->ClkOut_Setting = MxL_CLKOUT_ENABLE;			break;
++	}
++
++	switch(ClkOutAmpMode)
++	{
++		default:
++		case MXL5007T_CLK_OUT_AMP_0:		pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_0;		break;
++		case MXL5007T_CLK_OUT_AMP_1:		pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_1;		break;
++		case MXL5007T_CLK_OUT_AMP_2:		pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_2;		break;
++		case MXL5007T_CLK_OUT_AMP_3:		pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_3;		break;
++		case MXL5007T_CLK_OUT_AMP_4:		pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_4;		break;
++		case MXL5007T_CLK_OUT_AMP_5:		pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_5;		break;
++		case MXL5007T_CLK_OUT_AMP_6:		pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_6;		break;
++		case MXL5007T_CLK_OUT_AMP_7:		pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_7;		break;
++	}
++
++	pTunerConfigS->BW_MHz = MXL5007T_BANDWIDTH_MODE_DEFAULT;
++	pTunerConfigS->RF_Freq_Hz = MXL5007T_RF_FREQ_HZ_DEFAULT;
++
++
++	// Set tuner extra module function pointers.
++	pExtra->SetBandwidthMode = mxl5007t_SetBandwidthMode;
++	pExtra->GetBandwidthMode = mxl5007t_GetBandwidthMode;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_TUNER_TYPE
++
++*/
++void
++mxl5007t_GetTunerType(
++	TUNER_MODULE *pTuner,
++	int *pTunerType
++	)
++{
++	// Get tuner type from tuner module.
++	*pTunerType = pTuner->TunerType;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_DEVICE_ADDR
++
++*/
++void
++mxl5007t_GetDeviceAddr(
++	TUNER_MODULE *pTuner,
++	unsigned char *pDeviceAddr
++	)
++{
++	// Get tuner I2C device address from tuner module.
++	*pDeviceAddr = pTuner->DeviceAddr;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_INITIALIZE
++
++*/
++int
++mxl5007t_Initialize(
++	TUNER_MODULE *pTuner
++	)
++{
++	MXL5007T_EXTRA_MODULE *pExtra;
++	MxL5007_TunerConfigS *pTunerConfigS;
++
++
++
++	// Get tuner extra module.
++	pExtra = (MXL5007T_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get MaxLinear-defined MxL5007T structure.
++	pTunerConfigS = pExtra->pTunerConfigS;
++
++
++	// Initialize tuner.
++	if(MxL_Tuner_Init(pTunerConfigS) != MxL_OK)
++		goto error_status_initialize_tuner;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_initialize_tuner:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_SET_RF_FREQ_HZ
++
++*/
++int
++mxl5007t_SetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long RfFreqHz
++	)
++{
++	MXL5007T_EXTRA_MODULE *pExtra;
++	MxL5007_TunerConfigS *pTunerConfigS;
++
++	UINT32 Mxl5007tRfFreqHz;
++	MxL5007_BW_MHz Mxl5007tBandwidthMhz;
++
++
++
++	// Get tuner extra module.
++	pExtra = (MXL5007T_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get MaxLinear-defined MxL5007T structure.
++	pTunerConfigS = pExtra->pTunerConfigS;
++
++
++	// Get bandwidth.
++	Mxl5007tBandwidthMhz = pTunerConfigS->BW_MHz;
++
++	// Set RF frequency.
++	Mxl5007tRfFreqHz = (UINT32)RfFreqHz;
++
++	// Set MxL5007T RF frequency and bandwidth.
++	if(MxL_Tuner_RFTune(pTunerConfigS, Mxl5007tRfFreqHz, Mxl5007tBandwidthMhz) != MxL_OK)
++		goto error_status_set_tuner_rf_frequency;
++
++
++	// Set tuner RF frequency parameter.
++	pTuner->RfFreqHz      = RfFreqHz;
++	pTuner->IsRfFreqHzSet = YES;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_tuner_rf_frequency:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_RF_FREQ_HZ
++
++*/
++int
++mxl5007t_GetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long *pRfFreqHz
++	)
++{
++	// Get tuner RF frequency in Hz from tuner module.
++	if(pTuner->IsRfFreqHzSet != YES)
++		goto error_status_get_tuner_rf_frequency;
++
++	*pRfFreqHz = pTuner->RfFreqHz;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_tuner_rf_frequency:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Set MxL5007T tuner bandwidth mode.
++
++*/
++int
++mxl5007t_SetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int BandwidthMode
++	)
++{
++	MXL5007T_EXTRA_MODULE *pExtra;
++	MxL5007_TunerConfigS *pTunerConfigS;
++
++	UINT32 Mxl5007tRfFreqHz;
++	MxL5007_BW_MHz Mxl5007tBandwidthMhz;
++
++
++
++	// Get tuner extra module.
++	pExtra = (MXL5007T_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get MaxLinear-defined MxL5007T structure.
++	pTunerConfigS = pExtra->pTunerConfigS;
++
++
++	// Get RF frequency.
++	Mxl5007tRfFreqHz = pTunerConfigS->RF_Freq_Hz;
++
++	// Set bandwidth.
++	switch(BandwidthMode)
++	{
++		case MXL5007T_BANDWIDTH_6000000HZ:		Mxl5007tBandwidthMhz = MxL_BW_6MHz;		break;
++		case MXL5007T_BANDWIDTH_7000000HZ:		Mxl5007tBandwidthMhz = MxL_BW_7MHz;		break;
++		case MXL5007T_BANDWIDTH_8000000HZ:		Mxl5007tBandwidthMhz = MxL_BW_8MHz;		break;
++
++		default:	goto error_status_get_undefined_value;
++	}
++
++	// Set MxL5007T RF frequency and bandwidth.
++	if(MxL_Tuner_RFTune(pTunerConfigS, Mxl5007tRfFreqHz, Mxl5007tBandwidthMhz) != MxL_OK)
++		goto error_status_set_tuner_bandwidth;
++
++
++	// Set tuner bandwidth parameter.
++	pExtra->BandwidthMode      = BandwidthMode;
++	pExtra->IsBandwidthModeSet = YES;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_tuner_bandwidth:
++error_status_get_undefined_value:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Get MxL5007T tuner bandwidth mode.
++
++*/
++int
++mxl5007t_GetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int *pBandwidthMode
++	)
++{
++	MXL5007T_EXTRA_MODULE *pExtra;
++
++
++
++	// Get tuner extra module.
++	pExtra = (MXL5007T_EXTRA_MODULE *)pTuner->pExtra;
++
++
++	// Get tuner bandwidth mode from tuner module.
++	if(pExtra->IsBandwidthModeSet != YES)
++		goto error_status_get_tuner_bandwidth_mode;
++
++	*pBandwidthMode = pExtra->BandwidthMode;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_tuner_bandwidth_mode:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Set I2C bridge module tuner arguments.
++
++MXL5007T builder will use mxl5007t_SetI2cBridgeModuleTunerArg() to set I2C bridge module tuner arguments.
++
++
++@param [in]   pTuner   The tuner module pointer
++
++
++@see   BuildMxl5007tModule()
++
++*/
++void
++mxl5007t_SetI2cBridgeModuleTunerArg(
++	TUNER_MODULE *pTuner
++	)
++{
++	I2C_BRIDGE_MODULE *pI2cBridge;
++
++
++
++	// Get I2C bridge module.
++	pI2cBridge = pTuner->pI2cBridge;
++
++	// Set I2C bridge module tuner arguments.
++	pI2cBridge->pTunerDeviceAddr = &pTuner->DeviceAddr;
++
++
++	return;
++}
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// The following context is source code provided by MaxLinear.
++
++
++
++
++
++// MaxLinear source code - MxL_User_Define.c
++
++
++/*
++ 
++ Driver APIs for MxL5007 Tuner
++ 
++ Copyright, Maxlinear, Inc.
++ All Rights Reserved
++ 
++ File Name:      MxL_User_Define.c
++
++ */
++
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
++//																		   //
++//					I2C Functions (implement by customer)				   //
++//																		   //
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
++
++/******************************************************************************
++**
++**  Name: MxL_I2C_Write
++**
++**  Description:    I2C write operations
++**
++**  Parameters:    	
++**					DeviceAddr	- MxL5007 Device address
++**					pArray		- Write data array pointer
++**					count		- total number of array
++**
++**  Returns:        0 if success
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   12-16-2007   khuang initial release.
++**
++******************************************************************************/
++//UINT32 MxL_I2C_Write(UINT8 DeviceAddr, UINT8* pArray, UINT32 count)
++UINT32 MxL_I2C_Write(MxL5007_TunerConfigS* myTuner, UINT8* pArray, UINT32 count)
++{
++	TUNER_MODULE *pTuner;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	I2C_BRIDGE_MODULE *pI2cBridge;
++	unsigned char WritingByteNumMax;
++
++	unsigned long i;
++	unsigned char Buffer[I2C_BUFFER_LEN];
++	int WritingIndex;
++
++	unsigned char *pData;
++	unsigned long DataLen;
++
++
++
++	// Get tuner module, base interface, and I2C bridge.
++	pTuner = myTuner->pTuner;
++	pBaseInterface = pTuner->pBaseInterface;
++	pI2cBridge = pTuner->pI2cBridge;
++
++	// Get writing byte and byte number.
++	pData = (unsigned char *)pArray;
++	DataLen = (unsigned long)count;
++
++	// Calculate MxL5007T maximum writing byte number.
++	// Note: MxL5007T maximum writing byte number must be a multiple of 2.
++	WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax;
++	WritingByteNumMax = ((WritingByteNumMax % 2) == 0) ? WritingByteNumMax : (WritingByteNumMax - 1);
++
++
++	// Set register bytes.
++	// Note: The 2 kind of I2C formats of MxL5007T is described as follows:
++	//       1. start_bit + (device_addr | writing_bit) + (register_addr + writing_byte) * n + stop_bit
++	//          ...
++	//          start_bit + (device_addr | writing_bit) + (register_addr + writing_byte) * m + stop_bit
++	//       2. start_bit + (device_addr | writing_bit) + 0xff + stop_bit
++	for(i = 0, WritingIndex = 0; i < DataLen; i++, WritingIndex++)
++	{
++		// Put data into buffer.
++		Buffer[WritingIndex] = pData[i];
++
++		// If writing buffer is full or put data into buffer completely, send the I2C writing command with buffer.
++		if( (WritingIndex == (WritingByteNumMax - 1)) || (i == (DataLen - 1)) )
++		{
++			if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, Buffer, (WritingIndex + LEN_1_BYTE)) != FUNCTION_SUCCESS)
++				goto error_status_set_tuner_registers;
++
++			WritingIndex = -1;
++		}
++	}
++
++
++	return MxL_OK;
++
++
++error_status_set_tuner_registers:
++	return MxL_ERR_OTHERS;
++}
++
++/******************************************************************************
++**
++**  Name: MxL_I2C_Read
++**
++**  Description:    I2C read operations
++**
++**  Parameters:    	
++**					DeviceAddr	- MxL5007 Device address
++**					Addr		- register address for read
++**					*Data		- data return
++**
++**  Returns:        0 if success
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   12-16-2007   khuang initial release.
++**
++******************************************************************************/
++//UINT32 MxL_I2C_Read(UINT8 DeviceAddr, UINT8 Addr, UINT8* mData)
++UINT32 MxL_I2C_Read(MxL5007_TunerConfigS* myTuner, UINT8 Addr, UINT8* mData)
++{
++	TUNER_MODULE *pTuner;
++	I2C_BRIDGE_MODULE *pI2cBridge;
++
++	unsigned char Buffer[LEN_2_BYTE];
++
++
++
++	// Get tuner module and I2C bridge.
++	pTuner = myTuner->pTuner;
++	pI2cBridge = pTuner->pI2cBridge;
++
++	// Set tuner register reading address.
++	// Note: The I2C format of tuner register reading address setting is as follows:
++	//       start_bit + (DeviceAddr | writing_bit) + 0xfb + RegReadingAddr + stop_bit
++	Buffer[0] = (unsigned char)MXL5007T_I2C_READING_CONST;
++	Buffer[1] = (unsigned char)Addr;
++	if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, Buffer, LEN_2_BYTE) != FUNCTION_SUCCESS)
++		goto error_status_set_tuner_register_reading_address;
++
++	// Get tuner register bytes.
++	// Note: The I2C format of tuner register byte getting is as follows:
++	//       start_bit + (DeviceAddr | reading_bit) + reading_byte + stop_bit
++	if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, Buffer, LEN_1_BYTE) != FUNCTION_SUCCESS)
++		goto error_status_get_tuner_registers;
++
++	*mData = (UINT8)Buffer[0];
++
++
++	return MxL_OK;
++
++
++error_status_get_tuner_registers:
++error_status_set_tuner_register_reading_address:
++	return MxL_ERR_OTHERS;
++}
++
++/******************************************************************************
++**
++**  Name: MxL_Delay
++**
++**  Description:    Delay function in milli-second
++**
++**  Parameters:    	
++**					mSec		- milli-second to delay
++**
++**  Returns:        0
++**
++**  Revision History:
++**
++**   SCR      Date      Author  Description
++**  -------------------------------------------------------------------------
++**   N/A   12-16-2007   khuang initial release.
++**
++******************************************************************************/
++//void MxL_Delay(UINT32 mSec)
++void MxL_Delay(MxL5007_TunerConfigS* myTuner, UINT32 mSec)
++{
++	TUNER_MODULE *pTuner;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++
++
++	// Get tuner module and base interface.
++	pTuner = myTuner->pTuner;
++	pBaseInterface = pTuner->pBaseInterface;
++
++	// Wait in ms.
++	pBaseInterface->WaitMs(pBaseInterface, mSec);
++
++
++	return;
++}
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// MaxLinear source code - MxL5007.c
++
++
++/*
++ MxL5007 Source Code : V4.1.3
++ 
++ Copyright, Maxlinear, Inc.
++ All Rights Reserved
++ 
++ File Name:      MxL5007.c
++
++ Description: The source code is for MxL5007 user to quickly integrate MxL5007 into their software.
++	There are two functions the user can call to generate a array of I2C command that's require to
++	program the MxL5007 tuner. The user should pass an array pointer and an integer pointer in to the 
++	function. The funciton will fill up the array with format like follow:
++	
++		addr1
++		data1
++		addr2
++		data2
++		...
++	
++	The user can then pass this array to their I2C function to perform progromming the tuner. 
++*/
++//#include "StdAfx.h"
++//#include "MxL5007_Common.h"
++//#include "MxL5007.h"
++
++
++
++UINT32 MxL5007_Init(UINT8* pArray,				// a array pointer that store the addr and data pairs for I2C write
++					UINT32* Array_Size,			// a integer pointer that store the number of element in above array
++					UINT8 Mode,				
++					SINT32 IF_Diff_Out_Level,		 
++					UINT32 Xtal_Freq_Hz,			
++					UINT32 IF_Freq_Hz,				
++					UINT8 Invert_IF,											
++					UINT8 Clk_Out_Enable,    
++					UINT8 Clk_Out_Amp													
++					)
++{
++	
++	UINT32 Reg_Index=0;
++	UINT32 Array_Index=0;
++
++	IRVType IRV_Init[]=
++	{
++		//{ Addr, Data}	
++		{ 0x02, 0x06}, 
++		{ 0x03, 0x48},
++		{ 0x05, 0x04},  
++		{ 0x06, 0x10}, 
++		{ 0x2E, 0x15},  //Override
++		{ 0x30, 0x10},  //Override
++		{ 0x45, 0x58},  //Override
++		{ 0x48, 0x19},  //Override
++		{ 0x52, 0x03},  //Override
++		{ 0x53, 0x44},  //Override
++		{ 0x6A, 0x4B},  //Override
++		{ 0x76, 0x00},  //Override
++		{ 0x78, 0x18},  //Override
++		{ 0x7A, 0x17},  //Override
++		{ 0x85, 0x06},  //Override		
++		{ 0x01, 0x01}, //TOP_MASTER_ENABLE=1
++		{ 0, 0}
++	};
++
++
++	IRVType IRV_Init_Cable[]=
++	{
++		//{ Addr, Data}	
++		{ 0x02, 0x06}, 
++		{ 0x03, 0x48},
++		{ 0x05, 0x04},  
++		{ 0x06, 0x10},  
++		{ 0x09, 0x3F},  
++		{ 0x0A, 0x3F},  
++		{ 0x0B, 0x3F},  
++		{ 0x2E, 0x15},  //Override
++		{ 0x30, 0x10},  //Override
++		{ 0x45, 0x58},  //Override
++		{ 0x48, 0x19},  //Override
++		{ 0x52, 0x03},  //Override
++		{ 0x53, 0x44},  //Override
++		{ 0x6A, 0x4B},  //Override
++		{ 0x76, 0x00},  //Override
++		{ 0x78, 0x18},  //Override
++		{ 0x7A, 0x17},  //Override
++		{ 0x85, 0x06},  //Override	
++		{ 0x01, 0x01}, //TOP_MASTER_ENABLE=1
++		{ 0, 0}
++	};
++	//edit Init setting here
++
++	PIRVType myIRV;
++
++	switch(Mode)
++	{
++	case MxL_MODE_ISDBT: //ISDB-T Mode	
++		myIRV = IRV_Init;
++		SetIRVBit(myIRV, 0x06, 0x1F, 0x10);  
++		break;
++	case MxL_MODE_DVBT: //DVBT Mode			
++		myIRV = IRV_Init;
++		SetIRVBit(myIRV, 0x06, 0x1F, 0x11);  
++		break;
++	case MxL_MODE_ATSC: //ATSC Mode			
++		myIRV = IRV_Init;
++		SetIRVBit(myIRV, 0x06, 0x1F, 0x12);  
++		break;	
++	case MxL_MODE_CABLE:						
++		myIRV = IRV_Init_Cable;
++		SetIRVBit(myIRV, 0x09, 0xFF, 0xC1);	
++		SetIRVBit(myIRV, 0x0A, 0xFF, 8-IF_Diff_Out_Level);	
++		SetIRVBit(myIRV, 0x0B, 0xFF, 0x17);							
++		break;
++	
++
++	}
++
++	switch(IF_Freq_Hz)
++	{
++	case MxL_IF_4_MHZ:
++		SetIRVBit(myIRV, 0x02, 0x0F, 0x00); 		
++		break;
++	case MxL_IF_4_5_MHZ: //4.5MHz
++		SetIRVBit(myIRV, 0x02, 0x0F, 0x02); 		
++		break;
++	case MxL_IF_4_57_MHZ: //4.57MHz
++		SetIRVBit(myIRV, 0x02, 0x0F, 0x03); 
++		break;
++	case MxL_IF_5_MHZ:
++		SetIRVBit(myIRV, 0x02, 0x0F, 0x04); 
++		break;
++	case MxL_IF_5_38_MHZ: //5.38MHz
++		SetIRVBit(myIRV, 0x02, 0x0F, 0x05); 
++		break;
++	case MxL_IF_6_MHZ: 
++		SetIRVBit(myIRV, 0x02, 0x0F, 0x06); 
++		break;
++	case MxL_IF_6_28_MHZ: //6.28MHz
++		SetIRVBit(myIRV, 0x02, 0x0F, 0x07); 
++		break;
++	case MxL_IF_9_1915_MHZ: //9.1915MHz
++		SetIRVBit(myIRV, 0x02, 0x0F, 0x08); 
++		break;
++	case MxL_IF_35_25_MHZ:
++		SetIRVBit(myIRV, 0x02, 0x0F, 0x09); 
++		break;
++	case MxL_IF_36_15_MHZ:
++		SetIRVBit(myIRV, 0x02, 0x0F, 0x0a); 
++		break;
++	case MxL_IF_44_MHZ:
++		SetIRVBit(myIRV, 0x02, 0x0F, 0x0B); 
++		break;
++	}
++
++	if(Invert_IF) 
++		SetIRVBit(myIRV, 0x02, 0x10, 0x10);   //Invert IF
++	else
++		SetIRVBit(myIRV, 0x02, 0x10, 0x00);   //Normal IF
++
++
++	switch(Xtal_Freq_Hz)
++	{
++	case MxL_XTAL_16_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0x00);  //select xtal freq & Ref Freq
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x00);
++		break;
++	case MxL_XTAL_20_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0x10);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x01);
++		break;
++	case MxL_XTAL_20_25_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0x20);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x02);
++		break;
++	case MxL_XTAL_20_48_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0x30);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x03);
++		break;
++	case MxL_XTAL_24_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0x40);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x04);
++		break;
++	case MxL_XTAL_25_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0x50);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x05);
++		break;
++	case MxL_XTAL_25_14_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0x60);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x06);
++		break;
++	case MxL_XTAL_27_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0x70);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x07);
++		break;
++	case MxL_XTAL_28_8_MHZ: 
++		SetIRVBit(myIRV, 0x03, 0xF0, 0x80);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x08);
++		break;
++	case MxL_XTAL_32_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0x90);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x09);
++		break;
++	case MxL_XTAL_40_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0xA0);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x0A);
++		break;
++	case MxL_XTAL_44_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0xB0);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x0B);
++		break;
++	case MxL_XTAL_48_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0xC0);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x0C);
++		break;
++	case MxL_XTAL_49_3811_MHZ:
++		SetIRVBit(myIRV, 0x03, 0xF0, 0xD0);
++		SetIRVBit(myIRV, 0x05, 0x0F, 0x0D);
++		break;	
++	}
++
++	if(!Clk_Out_Enable) //default is enable 
++		SetIRVBit(myIRV, 0x03, 0x08, 0x00);   
++
++	//Clk_Out_Amp
++	SetIRVBit(myIRV, 0x03, 0x07, Clk_Out_Amp);   
++
++	//Generate one Array that Contain Data, Address
++	while (myIRV[Reg_Index].Num || myIRV[Reg_Index].Val)
++	{
++		pArray[Array_Index++] = myIRV[Reg_Index].Num;
++		pArray[Array_Index++] = myIRV[Reg_Index].Val;
++		Reg_Index++;
++	}
++	    
++	*Array_Size=Array_Index;
++	return 0;
++}
++
++
++UINT32 MxL5007_RFTune(UINT8* pArray, UINT32* Array_Size, UINT32 RF_Freq, UINT8 BWMHz)
++{
++	IRVType IRV_RFTune[]=
++	{
++	//{ Addr, Data}
++		{ 0x0F, 0x00},  //abort tune
++		{ 0x0C, 0x15},
++		{ 0x0D, 0x40},
++		{ 0x0E, 0x0E},	
++		{ 0x1F, 0x87},  //Override
++		{ 0x20, 0x1F},  //Override
++		{ 0x21, 0x87},  //Override
++		{ 0x22, 0x1F},  //Override		
++		{ 0x80, 0x01},  //Freq Dependent Setting
++		{ 0x0F, 0x01},	//start tune
++		{ 0, 0}
++	};
++
++	UINT32 dig_rf_freq=0;
++	UINT32 temp;
++	UINT32 Reg_Index=0;
++	UINT32 Array_Index=0;
++	UINT32 i;
++	UINT32 frac_divider = 1000000;
++
++	switch(BWMHz)
++	{
++	case MxL_BW_6MHz: //6MHz
++			SetIRVBit(IRV_RFTune, 0x0C, 0x3F, 0x15);  //set DIG_MODEINDEX, DIG_MODEINDEX_A, and DIG_MODEINDEX_CSF
++		break;
++	case MxL_BW_7MHz: //7MHz
++			SetIRVBit(IRV_RFTune, 0x0C, 0x3F, 0x2A);
++		break;
++	case MxL_BW_8MHz: //8MHz
++			SetIRVBit(IRV_RFTune, 0x0C, 0x3F, 0x3F);
++		break;
++	}
++
++
++	//Convert RF frequency into 16 bits => 10 bit integer (MHz) + 6 bit fraction
++	dig_rf_freq = RF_Freq / MHz;
++	temp = RF_Freq % MHz;
++	for(i=0; i<6; i++)
++	{
++		dig_rf_freq <<= 1;
++		frac_divider /=2;
++		if(temp > frac_divider)
++		{
++			temp -= frac_divider;
++			dig_rf_freq++;
++		}
++	}
++
++	//add to have shift center point by 7.8124 kHz
++	if(temp > 7812)
++		dig_rf_freq ++;
++    	
++	SetIRVBit(IRV_RFTune, 0x0D, 0xFF, (UINT8)dig_rf_freq);
++	SetIRVBit(IRV_RFTune, 0x0E, 0xFF, (UINT8)(dig_rf_freq>>8));
++
++	if (RF_Freq >=333*MHz)
++		SetIRVBit(IRV_RFTune, 0x80, 0x40, 0x40);
++
++	//Generate one Array that Contain Data, Address 
++	while (IRV_RFTune[Reg_Index].Num || IRV_RFTune[Reg_Index].Val)
++	{
++		pArray[Array_Index++] = IRV_RFTune[Reg_Index].Num;
++		pArray[Array_Index++] = IRV_RFTune[Reg_Index].Val;
++		Reg_Index++;
++	}
++    
++	*Array_Size=Array_Index;
++	
++	return 0;
++}
++
++//local functions called by Init and RFTune
++UINT32 SetIRVBit(PIRVType pIRV, UINT8 Num, UINT8 Mask, UINT8 Val)
++{
++	while (pIRV->Num || pIRV->Val)
++	{
++		if (pIRV->Num==Num)
++		{
++			pIRV->Val&=~Mask;
++			pIRV->Val|=Val;
++		}
++		pIRV++;
++
++	}	
++	return 0;
++}
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// MaxLinear source code - MxL5007_API.h
++
++
++/*
++
++ Driver APIs for MxL5007 Tuner
++ 
++ Copyright, Maxlinear, Inc.
++ All Rights Reserved
++ 
++ File Name:      MxL5007_API.c
++ 
++ Version:    4.1.3
++*/
++
++
++//#include "StdAfx.h"
++//#include "MxL5007_API.h"
++//#include "MxL_User_Define.c"
++//#include "MxL5007.c"
++
++
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
++//																		   //
++//							Tuner Functions								   //
++//																		   //
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
++MxL_ERR_MSG MxL_Set_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 RegData)
++{
++	UINT32 Status=0;
++	UINT8 pArray[2];
++	pArray[0] = RegAddr;
++	pArray[1] = RegData;
++//	Status = MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2);
++	Status = MxL_I2C_Write(myTuner, pArray, 2);
++	if(Status) return MxL_ERR_SET_REG;
++
++	return MxL_OK;
++
++}
++
++MxL_ERR_MSG MxL_Get_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 *RegData)
++{
++//	if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, RegAddr, RegData))
++	if(MxL_I2C_Read(myTuner, RegAddr, RegData))
++		return MxL_ERR_GET_REG;
++	return MxL_OK;
++
++}
++
++MxL_ERR_MSG MxL_Soft_Reset(MxL5007_TunerConfigS* myTuner)
++{
++	UINT32 Status=0;	
++	UINT8 reg_reset;
++	reg_reset = 0xFF;
++//	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, &reg_reset, 1))
++	if(MxL_I2C_Write(myTuner, &reg_reset, 1))
++		return MxL_ERR_OTHERS;
++
++	return MxL_OK;
++}
++
++MxL_ERR_MSG MxL_Loop_Through_On(MxL5007_TunerConfigS* myTuner, MxL5007_LoopThru isOn)
++{	
++	UINT8 pArray[2];	// a array pointer that store the addr and data pairs for I2C write	
++	
++	pArray[0]=0x04;
++	if(isOn)
++	 pArray[1]= 0x01;
++	else
++	 pArray[1]= 0x0;
++
++//	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2))
++	if(MxL_I2C_Write(myTuner, pArray, 2))
++		return MxL_ERR_OTHERS;
++
++	return MxL_OK;
++}
++
++MxL_ERR_MSG MxL_Stand_By(MxL5007_TunerConfigS* myTuner)
++{
++	UINT8 pArray[4];	// a array pointer that store the addr and data pairs for I2C write	
++	
++	pArray[0] = 0x01;
++	pArray[1] = 0x0;
++	pArray[2] = 0x0F;
++	pArray[3] = 0x0;
++
++//	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 4))
++	if(MxL_I2C_Write(myTuner, pArray, 4))
++		return MxL_ERR_OTHERS;
++
++	return MxL_OK;
++}
++
++MxL_ERR_MSG MxL_Wake_Up(MxL5007_TunerConfigS* myTuner)
++{
++	UINT8 pArray[2];	// a array pointer that store the addr and data pairs for I2C write	
++	
++	pArray[0] = 0x01;
++	pArray[1] = 0x01;
++
++//	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2))
++	if(MxL_I2C_Write(myTuner, pArray, 2))
++		return MxL_ERR_OTHERS;
++
++	if(MxL_Tuner_RFTune(myTuner, myTuner->RF_Freq_Hz, myTuner->BW_MHz))
++		return MxL_ERR_RFTUNE;
++
++	return MxL_OK;
++}
++
++MxL_ERR_MSG MxL_Tuner_Init(MxL5007_TunerConfigS* myTuner)
++{	
++	UINT8 pArray[MAX_ARRAY_SIZE];	// a array pointer that store the addr and data pairs for I2C write
++	UINT32 Array_Size;							// a integer pointer that store the number of element in above array
++
++	//Soft reset tuner
++	if(MxL_Soft_Reset(myTuner))
++		return MxL_ERR_INIT;
++
++	//perform initialization calculation
++	MxL5007_Init(pArray, &Array_Size, (UINT8)myTuner->Mode, myTuner->IF_Diff_Out_Level, (UINT32)myTuner->Xtal_Freq, 
++				(UINT32)myTuner->IF_Freq, (UINT8)myTuner->IF_Spectrum, (UINT8)myTuner->ClkOut_Setting, (UINT8)myTuner->ClkOut_Amp);
++
++	//perform I2C write here
++//	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, Array_Size))
++	if(MxL_I2C_Write(myTuner, pArray, Array_Size))
++		return MxL_ERR_INIT;
++
++	return MxL_OK;
++}
++
++
++MxL_ERR_MSG MxL_Tuner_RFTune(MxL5007_TunerConfigS* myTuner, UINT32 RF_Freq_Hz, MxL5007_BW_MHz BWMHz)
++{
++	UINT32 Status=0;
++	UINT8 pArray[MAX_ARRAY_SIZE];	// a array pointer that store the addr and data pairs for I2C write
++	UINT32 Array_Size;							// a integer pointer that store the number of element in above array
++
++	//Store information into struc
++	myTuner->RF_Freq_Hz = RF_Freq_Hz;
++	myTuner->BW_MHz = BWMHz;
++
++	//perform Channel Change calculation
++	MxL5007_RFTune(pArray,&Array_Size,RF_Freq_Hz,BWMHz);
++
++	//perform I2C write here
++//	if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, Array_Size))
++	if(MxL_I2C_Write(myTuner, pArray, Array_Size))
++		return MxL_ERR_RFTUNE;
++
++	//wait for 3ms
++//	MxL_Delay(3); 
++	MxL_Delay(myTuner, 3); 
++
++	return MxL_OK;
++}
++
++MxL5007_ChipVersion MxL_Check_ChipVersion(MxL5007_TunerConfigS* myTuner)
++{	
++	UINT8 Data;
++//	if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD9, &Data))
++	if(MxL_I2C_Read(myTuner, 0xD9, &Data))
++		return MxL_GET_ID_FAIL;
++		
++	switch(Data)
++	{
++	case 0x14: return MxL_5007T_V4; break;
++	default: return MxL_UNKNOWN_ID;
++	}	
++}
++
++MxL_ERR_MSG MxL_RFSynth_Lock_Status(MxL5007_TunerConfigS* myTuner, BOOL* isLock)
++{	
++	UINT8 Data;
++	*isLock = MxL_FALSE; 
++//	if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD8, &Data))
++	if(MxL_I2C_Read(myTuner, 0xD8, &Data))
++		return MxL_ERR_OTHERS;
++	Data &= 0x0C;
++	if (Data == 0x0C)
++		*isLock = MxL_TRUE;  //RF Synthesizer is Lock	
++	return MxL_OK;
++}
++
++MxL_ERR_MSG MxL_REFSynth_Lock_Status(MxL5007_TunerConfigS* myTuner, BOOL* isLock)
++{
++	UINT8 Data;
++	*isLock = MxL_FALSE; 
++//	if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD8, &Data))
++	if(MxL_I2C_Read(myTuner, 0xD8, &Data))
++		return MxL_ERR_OTHERS;
++	Data &= 0x03;
++	if (Data == 0x03)
++		*isLock = MxL_TRUE;   //REF Synthesizer is Lock
++	return MxL_OK;
++}
++
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/tuner_mxl5007t.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/tuner_mxl5007t.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,834 @@
++#ifndef __TUNER_MXL5007T_H
++#define __TUNER_MXL5007T_H
++
++/**
++
++@file
++
++@brief   MxL5007T tuner module declaration
++
++One can manipulate MxL5007T tuner through MxL5007T module.
++MxL5007T module is derived from tuner module.
++
++
++
++@par Example:
++@code
++
++// The example is the same as the tuner example in tuner_base.h except the listed lines.
++
++
++
++#include "tuner_mxl5007t.h"
++
++
++...
++
++
++
++int main(void)
++{
++	TUNER_MODULE        *pTuner;
++	MXL5007T_EXTRA_MODULE *pTunerExtra;
++
++	TUNER_MODULE          TunerModuleMemory;
++	MXL5007T_EXTRA_MODULE   Mxl5007tExtraModuleMemory;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++	I2C_BRIDGE_MODULE     I2cBridgeModuleMemory;
++
++	unsigned long BandwidthMode;
++
++
++	...
++
++
++
++	// Build MxL5007T tuner module.
++	BuildMxl5007tModule(
++		&pTuner,
++		&TunerModuleMemory,
++		&Mxl5007tExtraModuleMemory,
++		&BaseInterfaceModuleMemory,
++		&I2cBridgeModuleMemory,
++		0xc0,								// I2C device address is 0xc0 in 8-bit format.
++		CRYSTAL_FREQ_16000000HZ,			// Crystal frequency is 16.0 MHz.
++		MXL5007T_STANDARD_DVBT,				// The MxL5007T standard mode is DVB-T.
++		IF_FREQ_4570000HZ,					// The MxL5007T IF frequency is 4.57 MHz.
++		SPECTRUM_NORMAL,					// The MxL5007T spectrum mode is normal.
++		MXL5007T_CLK_OUT_DISABLE,			// The MxL5007T clock output mode is disabled.
++		MXL5007T_CLK_OUT_AMP_0,				// The MxL5007T clock output amplitude is 0.
++		0									// The MxL5007T QAM IF differential output level is 0 for cable only.
++		);
++
++
++
++
++
++	// Get MxL5007T tuner extra module.
++	pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra);
++
++
++
++
++
++	// ==== Initialize tuner and set its parameters =====
++
++	...
++
++	// Set MXL5007T bandwidth.
++	pTunerExtra->SetBandwidthMode(pTuner, MXL5007T_BANDWIDTH_6MHZ);
++
++
++
++
++
++	// ==== Get tuner information =====
++
++	...
++
++	// Get MXL5007T bandwidth.
++	pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode);
++
++
++
++	// See the example for other tuner functions in tuner_base.h
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++
++
++
++#include "tuner_base.h"
++
++
++
++
++
++// The following context is source code provided by MaxLinear.
++
++
++
++
++
++// MaxLinear source code - MxL5007_Common.h
++
++
++/*******************************************************************************
++ *
++ * FILE NAME          : MxL_Common.h
++ * 
++ * AUTHOR             : Kyle Huang
++ * DATE CREATED       : May 05, 2008
++ *
++ * DESCRIPTION        : 
++ *
++ *******************************************************************************
++ *                Copyright (c) 2006, MaxLinear, Inc.
++ ******************************************************************************/
++ 
++//#ifndef __MXL5007_COMMON_H
++//#define __MXL5007_COMMON_H
++
++
++
++/******************************************************************************
++*						User-Defined Types (Typedefs)
++******************************************************************************/
++
++
++/****************************************************************************
++*       Imports and definitions for WIN32                             
++****************************************************************************/
++//#include <windows.h>
++typedef unsigned char  UINT8;
++typedef unsigned short UINT16;
++typedef unsigned int   UINT32;
++typedef char           SINT8;
++typedef short          SINT16;
++typedef int            SINT32;
++//typedef float          REAL32;
++
++// Additional definition
++#define BOOL		int
++#define MxL_FALSE	0
++#define MxL_TRUE	1
++
++/****************************************************************************\
++*      Imports and definitions for non WIN32 platforms                   *
++\****************************************************************************/
++/*
++typedef unsigned char  UINT8;
++typedef unsigned short UINT16;
++typedef unsigned int   UINT32;
++typedef char           SINT8;
++typedef short          SINT16;
++typedef int            SINT32;
++typedef float          REAL32;
++
++// create a boolean 
++#ifndef __boolean__
++#define __boolean__
++typedef enum {FALSE=0,TRUE} BOOL;
++#endif //boolean
++*/
++
++
++/****************************************************************************\
++*          Definitions for all platforms					                 *
++\****************************************************************************/
++#ifndef NULL
++#define NULL (void*)0
++#endif
++
++
++
++/******************************/
++/*	MxL5007 Err message  	  */
++/******************************/
++typedef enum{
++	MxL_OK				=   0,
++	MxL_ERR_INIT		=   1,
++	MxL_ERR_RFTUNE		=   2,
++	MxL_ERR_SET_REG		=   3,
++	MxL_ERR_GET_REG		=	4,
++	MxL_ERR_OTHERS		=   10
++}MxL_ERR_MSG;
++
++/******************************/
++/*	MxL5007 Chip verstion     */
++/******************************/
++typedef enum{
++	MxL_UNKNOWN_ID		= 0x00,
++	MxL_5007T_V4		= 0x14,
++	MxL_GET_ID_FAIL		= 0xFF
++}MxL5007_ChipVersion;
++
++
++/******************************************************************************
++    CONSTANTS
++******************************************************************************/
++
++#ifndef MHz
++	#define MHz 1000000
++#endif
++
++#define MAX_ARRAY_SIZE 100
++
++
++// Enumeration of Mode
++// Enumeration of Mode
++typedef enum 
++{
++	MxL_MODE_ISDBT = 0,
++	MxL_MODE_DVBT = 1,
++	MxL_MODE_ATSC = 2,	
++	MxL_MODE_CABLE = 0x10
++} MxL5007_Mode ;
++
++typedef enum
++{
++	MxL_IF_4_MHZ	  = 4000000,
++	MxL_IF_4_5_MHZ	  = 4500000,
++	MxL_IF_4_57_MHZ	  =	4570000,
++	MxL_IF_5_MHZ	  =	5000000,
++	MxL_IF_5_38_MHZ	  =	5380000,
++	MxL_IF_6_MHZ	  =	6000000,
++	MxL_IF_6_28_MHZ	  =	6280000,
++	MxL_IF_9_1915_MHZ =	9191500,
++	MxL_IF_35_25_MHZ  = 35250000,
++	MxL_IF_36_15_MHZ  = 36150000,
++	MxL_IF_44_MHZ	  = 44000000
++} MxL5007_IF_Freq ;
++
++typedef enum
++{
++	MxL_XTAL_16_MHZ		= 16000000,
++	MxL_XTAL_20_MHZ		= 20000000,
++	MxL_XTAL_20_25_MHZ	= 20250000,
++	MxL_XTAL_20_48_MHZ	= 20480000,
++	MxL_XTAL_24_MHZ		= 24000000,
++	MxL_XTAL_25_MHZ		= 25000000,
++	MxL_XTAL_25_14_MHZ	= 25140000,
++	MxL_XTAL_27_MHZ		= 27000000,
++	MxL_XTAL_28_8_MHZ	= 28800000,
++	MxL_XTAL_32_MHZ		= 32000000,
++	MxL_XTAL_40_MHZ		= 40000000,
++	MxL_XTAL_44_MHZ		= 44000000,
++	MxL_XTAL_48_MHZ		= 48000000,
++	MxL_XTAL_49_3811_MHZ = 49381100	
++} MxL5007_Xtal_Freq ;
++
++typedef enum
++{
++	MxL_BW_6MHz = 6,
++	MxL_BW_7MHz = 7,
++	MxL_BW_8MHz = 8
++} MxL5007_BW_MHz;
++
++typedef enum
++{
++	MxL_NORMAL_IF = 0 ,
++	MxL_INVERT_IF
++
++} MxL5007_IF_Spectrum ;
++
++typedef enum
++{
++	MxL_LT_DISABLE = 0 ,
++	MxL_LT_ENABLE
++
++} MxL5007_LoopThru ;
++
++typedef enum
++{
++	MxL_CLKOUT_DISABLE = 0 ,
++	MxL_CLKOUT_ENABLE
++
++} MxL5007_ClkOut;
++
++typedef enum
++{
++	MxL_CLKOUT_AMP_0 = 0 ,
++	MxL_CLKOUT_AMP_1,
++	MxL_CLKOUT_AMP_2,
++	MxL_CLKOUT_AMP_3,
++	MxL_CLKOUT_AMP_4,
++	MxL_CLKOUT_AMP_5,
++	MxL_CLKOUT_AMP_6,
++	MxL_CLKOUT_AMP_7
++} MxL5007_ClkOut_Amp;
++
++typedef enum
++{
++	MxL_I2C_ADDR_96 = 96 ,
++	MxL_I2C_ADDR_97 = 97 ,
++	MxL_I2C_ADDR_98 = 98 ,
++	MxL_I2C_ADDR_99 = 99 	
++} MxL5007_I2CAddr ;
++
++//
++// MxL5007 TunerConfig Struct
++//
++typedef struct _MxL5007_TunerConfigS
++{
++	MxL5007_I2CAddr		I2C_Addr;
++	MxL5007_Mode		Mode;
++	SINT32				IF_Diff_Out_Level;
++	MxL5007_Xtal_Freq	Xtal_Freq;
++	MxL5007_IF_Freq	    IF_Freq;
++	MxL5007_IF_Spectrum IF_Spectrum;
++	MxL5007_ClkOut		ClkOut_Setting;
++    MxL5007_ClkOut_Amp	ClkOut_Amp;
++	MxL5007_BW_MHz		BW_MHz;
++	UINT32				RF_Freq_Hz;
++
++	// Additional definition
++	TUNER_MODULE *pTuner;
++
++} MxL5007_TunerConfigS;
++
++
++
++
++//#endif /* __MXL5007_COMMON_H__*/
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// MaxLinear source code - MxL5007.h
++
++
++
++/*
++ 
++ Driver APIs for MxL5007 Tuner
++ 
++ Copyright, Maxlinear, Inc.
++ All Rights Reserved
++ 
++ File Name:      MxL5007.h
++
++ */
++
++
++//#include "MxL5007_Common.h"
++
++
++typedef struct
++{
++	UINT8 Num;	//Register number
++	UINT8 Val;	//Register value
++} IRVType, *PIRVType;
++
++
++UINT32 MxL5007_Init(UINT8* pArray,				// a array pointer that store the addr and data pairs for I2C write
++					UINT32* Array_Size,			// a integer pointer that store the number of element in above array
++					UINT8 Mode,				
++					SINT32 IF_Diff_Out_Level,
++					UINT32 Xtal_Freq_Hz,		
++					UINT32 IF_Freq_Hz,		
++					UINT8 Invert_IF,			
++					UINT8 Clk_Out_Enable,    
++					UINT8 Clk_Out_Amp		
++					);
++UINT32 MxL5007_RFTune(UINT8* pArray, UINT32* Array_Size, 
++					 UINT32 RF_Freq,			// RF Frequency in Hz
++					 UINT8 BWMHz		// Bandwidth in MHz
++					 );
++UINT32 SetIRVBit(PIRVType pIRV, UINT8 Num, UINT8 Mask, UINT8 Val);
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// MaxLinear source code - MxL5007.h
++
++
++
++/*
++ 
++ Driver APIs for MxL5007 Tuner
++ 
++ Copyright, Maxlinear, Inc.
++ All Rights Reserved
++ 
++ File Name:      MxL5007_API.h
++ 
++ */
++//#ifndef __MxL5007_API_H
++//#define __MxL5007_API_H
++
++//#include "MxL5007_Common.h"
++
++/******************************************************************************
++**
++**  Name: MxL_Set_Register
++**
++**  Description:    Write one register to MxL5007
++**
++**  Parameters:    	myTuner				- Pointer to MxL5007_TunerConfigS
++**					RegAddr				- Register address to be written
++**					RegData				- Data to be written
++**
++**  Returns:        MxL_ERR_MSG			- MxL_OK if success	
++**										- MxL_ERR_SET_REG if fail
++**
++******************************************************************************/
++MxL_ERR_MSG MxL_Set_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 RegData);
++
++/******************************************************************************
++**
++**  Name: MxL_Get_Register
++**
++**  Description:    Read one register from MxL5007
++**
++**  Parameters:    	myTuner				- Pointer to MxL5007_TunerConfigS
++**					RegAddr				- Register address to be read
++**					RegData				- Pointer to register read
++**
++**  Returns:        MxL_ERR_MSG			- MxL_OK if success	
++**										- MxL_ERR_GET_REG if fail
++**
++******************************************************************************/
++MxL_ERR_MSG MxL_Get_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 *RegData);
++
++/******************************************************************************
++**
++**  Name: MxL_Tuner_Init
++**
++**  Description:    MxL5007 Initialization
++**
++**  Parameters:    	myTuner				- Pointer to MxL5007_TunerConfigS
++**
++**  Returns:        MxL_ERR_MSG			- MxL_OK if success	
++**										- MxL_ERR_INIT if fail
++**
++******************************************************************************/
++MxL_ERR_MSG MxL_Tuner_Init(MxL5007_TunerConfigS* );
++
++/******************************************************************************
++**
++**  Name: MxL_Tuner_RFTune
++**
++**  Description:    Frequency tunning for channel
++**
++**  Parameters:    	myTuner				- Pointer to MxL5007_TunerConfigS
++**					RF_Freq_Hz			- RF Frequency in Hz
++**					BWMHz				- Bandwidth 6, 7 or 8 MHz
++**
++**  Returns:        MxL_ERR_MSG			- MxL_OK if success	
++**										- MxL_ERR_RFTUNE if fail
++**
++******************************************************************************/
++MxL_ERR_MSG MxL_Tuner_RFTune(MxL5007_TunerConfigS*, UINT32 RF_Freq_Hz, MxL5007_BW_MHz BWMHz);		
++
++/******************************************************************************
++**
++**  Name: MxL_Soft_Reset
++**
++**  Description:    Software Reset the MxL5007 Tuner
++**
++**  Parameters:    	myTuner				- Pointer to MxL5007_TunerConfigS
++**
++**  Returns:        MxL_ERR_MSG			- MxL_OK if success	
++**										- MxL_ERR_OTHERS if fail
++**
++******************************************************************************/
++MxL_ERR_MSG MxL_Soft_Reset(MxL5007_TunerConfigS*);
++
++/******************************************************************************
++**
++**  Name: MxL_Loop_Through_On
++**
++**  Description:    Turn On/Off on-chip Loop-through
++**
++**  Parameters:    	myTuner				- Pointer to MxL5007_TunerConfigS
++**					isOn				- True to turn On Loop Through
++**										- False to turn off Loop Through
++**
++**  Returns:        MxL_ERR_MSG			- MxL_OK if success	
++**										- MxL_ERR_OTHERS if fail
++**
++******************************************************************************/
++MxL_ERR_MSG MxL_Loop_Through_On(MxL5007_TunerConfigS*, MxL5007_LoopThru);
++
++/******************************************************************************
++**
++**  Name: MxL_Standby
++**
++**  Description:    Enter Standby Mode
++**
++**  Parameters:    	myTuner				- Pointer to MxL5007_TunerConfigS
++**
++**  Returns:        MxL_ERR_MSG			- MxL_OK if success	
++**										- MxL_ERR_OTHERS if fail
++**
++******************************************************************************/
++MxL_ERR_MSG MxL_Stand_By(MxL5007_TunerConfigS*);
++
++/******************************************************************************
++**
++**  Name: MxL_Wakeup
++**
++**  Description:    Wakeup from Standby Mode (Note: after wake up, please call RF_Tune again)
++**
++**  Parameters:    	myTuner				- Pointer to MxL5007_TunerConfigS
++**
++**  Returns:        MxL_ERR_MSG			- MxL_OK if success	
++**										- MxL_ERR_OTHERS if fail
++**
++******************************************************************************/
++MxL_ERR_MSG MxL_Wake_Up(MxL5007_TunerConfigS*);
++
++/******************************************************************************
++**
++**  Name: MxL_Check_ChipVersion
++**
++**  Description:    Return the MxL5007 Chip ID
++**
++**  Parameters:    	myTuner				- Pointer to MxL5007_TunerConfigS
++**			
++**  Returns:        MxL_ChipVersion			
++**
++******************************************************************************/
++MxL5007_ChipVersion MxL_Check_ChipVersion(MxL5007_TunerConfigS*);
++
++/******************************************************************************
++**
++**  Name: MxL_RFSynth_Lock_Status
++**
++**  Description:    RF synthesizer lock status of MxL5007
++**
++**  Parameters:    	myTuner				- Pointer to MxL5007_TunerConfigS
++**					isLock				- Pointer to Lock Status
++**
++**  Returns:        MxL_ERR_MSG			- MxL_OK if success	
++**										- MxL_ERR_OTHERS if fail
++**
++******************************************************************************/
++MxL_ERR_MSG MxL_RFSynth_Lock_Status(MxL5007_TunerConfigS* , BOOL* isLock);
++
++/******************************************************************************
++**
++**  Name: MxL_REFSynth_Lock_Status
++**
++**  Description:    REF synthesizer lock status of MxL5007
++**
++**  Parameters:    	myTuner				- Pointer to MxL5007_TunerConfigS
++**					isLock				- Pointer to Lock Status
++**
++**  Returns:        MxL_ERR_MSG			- MxL_OK if success	
++**										- MxL_ERR_OTHERS if fail	
++**
++******************************************************************************/
++MxL_ERR_MSG MxL_REFSynth_Lock_Status(MxL5007_TunerConfigS* , BOOL* isLock);
++
++//#endif //__MxL5007_API_H
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// The following context is MxL5007T tuner API source code
++
++
++
++
++
++// Definitions
++
++// Standard mode
++enum MXL5007T_STANDARD_MODE
++{
++	MXL5007T_STANDARD_DVBT,
++	MXL5007T_STANDARD_ATSC,
++	MXL5007T_STANDARD_QAM,
++	MXL5007T_STANDARD_ISDBT,
++};
++
++
++// Clock output mode
++enum MXL5007T_CLK_OUT_MODE
++{
++	MXL5007T_CLK_OUT_DISABLE,
++	MXL5007T_CLK_OUT_ENABLE,
++};
++
++
++// Clock output amplitude mode
++enum MXL5007T_CLK_OUT_AMP_MODE
++{
++	MXL5007T_CLK_OUT_AMP_0,
++	MXL5007T_CLK_OUT_AMP_1,
++	MXL5007T_CLK_OUT_AMP_2,
++	MXL5007T_CLK_OUT_AMP_3,
++	MXL5007T_CLK_OUT_AMP_4,
++	MXL5007T_CLK_OUT_AMP_5,
++	MXL5007T_CLK_OUT_AMP_6,
++	MXL5007T_CLK_OUT_AMP_7,
++};
++
++
++// Bandwidth mode
++enum MXL5007T_BANDWIDTH_MODE
++{
++	MXL5007T_BANDWIDTH_6000000HZ,
++	MXL5007T_BANDWIDTH_7000000HZ,
++	MXL5007T_BANDWIDTH_8000000HZ,
++};
++
++
++
++// Constant
++#define MXL5007T_I2C_READING_CONST		0xfb
++
++// Default value
++#define MXL5007T_RF_FREQ_HZ_DEFAULT			44000000;
++#define MXL5007T_BANDWIDTH_MODE_DEFAULT		MxL_BW_6MHz;
++
++
++
++
++
++// MxL5007T extra module
++typedef struct MXL5007T_EXTRA_MODULE_TAG MXL5007T_EXTRA_MODULE;
++
++
++
++
++
++// MxL5007T bandwidth mode setting function pointer
++typedef int
++(*MXL5007T_FP_SET_BANDWIDTH_MODE)(
++	TUNER_MODULE *pTuner,
++	int BandwidthMode
++	);
++
++
++
++// MxL5007T bandwidth mode getting function pointer
++typedef int
++(*MXL5007T_FP_GET_BANDWIDTH_MODE)(
++	TUNER_MODULE *pTuner,
++	int *pBandwidthMode
++	);
++
++
++
++
++
++// MxL5007T extra module
++struct MXL5007T_EXTRA_MODULE_TAG
++{
++	// MxL5007T extra variables
++	int BandwidthMode;
++	int IsBandwidthModeSet;
++
++	// MxL5007T MaxLinear-defined structure
++	MxL5007_TunerConfigS *pTunerConfigS;
++	MxL5007_TunerConfigS TunerConfigSMemory;
++
++	// MxL5007T extra function pointers
++	MXL5007T_FP_SET_BANDWIDTH_MODE   SetBandwidthMode;
++	MXL5007T_FP_GET_BANDWIDTH_MODE   GetBandwidthMode;
++};
++
++
++
++
++
++// Builder
++void
++BuildMxl5007tModule(
++	TUNER_MODULE **ppTuner,
++	TUNER_MODULE *pTunerModuleMemory,
++	MXL5007T_EXTRA_MODULE *pMxl5007tExtraModuleMemory,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory,
++	unsigned char DeviceAddr,
++	unsigned long CrystalFreqHz,
++	int StandardMode,
++	unsigned long IfFreqHz,
++	int SpectrumMode,
++	int ClkOutMode,
++	int ClkOutAmpMode,
++	long QamIfDiffOutLevel
++	);
++
++
++
++
++
++// Manipulaing functions
++void
++mxl5007t_GetTunerType(
++	TUNER_MODULE *pTuner,
++	int *pTunerType
++	);
++
++void
++mxl5007t_GetDeviceAddr(
++	TUNER_MODULE *pTuner,
++	unsigned char *pDeviceAddr
++	);
++
++int
++mxl5007t_Initialize(
++	TUNER_MODULE *pTuner
++	);
++
++int
++mxl5007t_SetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long RfFreqHz
++	);
++
++int
++mxl5007t_GetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long *pRfFreqHz
++	);
++
++
++
++
++
++// Extra manipulaing functions
++int
++mxl5007t_SetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int BandwidthMode
++	);
++
++int
++mxl5007t_GetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int *pBandwidthMode
++	);
++
++
++
++
++
++// I2C birdge module demod argument setting
++void
++mxl5007t_SetI2cBridgeModuleTunerArg(
++	TUNER_MODULE *pTuner
++	);
++
++
++
++
++
++
++
++
++
++
++
++
++
++#endif
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/tuner_tua9001.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/tuner_tua9001.c	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,1252 @@
++/**
++
++@file
++
++@brief   TUA9001 tuner module definition
++
++One can manipulate TUA9001 tuner through TUA9001 module.
++TUA9001 module is derived from tuner module.
++
++*/
++
++
++#include "tuner_tua9001.h"
++
++
++
++
++
++/**
++
++@brief   TUA9001 tuner module builder
++
++Use BuildTua9001Module() to build TUA9001 module, set all module function pointers with the corresponding functions,
++and initialize module private variables.
++
++
++@param [in]   ppTuner                      Pointer to TUA9001 tuner module pointer
++@param [in]   pTunerModuleMemory           Pointer to an allocated tuner module memory
++@param [in]   pTua9001ExtraModuleMemory    Pointer to an allocated TUA9001 extra module memory
++@param [in]   pBaseInterfaceModuleMemory   Pointer to an allocated base interface module memory
++@param [in]   pI2cBridgeModuleMemory       Pointer to an allocated I2C bridge module memory
++@param [in]   DeviceAddr                   TUA9001 I2C device address
++
++
++@note
++	-# One should call BuildTua9001Module() to build TUA9001 module before using it.
++
++*/
++void
++BuildTua9001Module(
++	TUNER_MODULE **ppTuner,
++	TUNER_MODULE *pTunerModuleMemory,
++	TUA9001_EXTRA_MODULE *pTua9001ExtraModuleMemory,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory,
++	unsigned char DeviceAddr
++	)
++{
++	TUNER_MODULE *pTuner;
++	TUA9001_EXTRA_MODULE *pExtra;
++
++
++
++	// Set tuner module pointer.
++	*ppTuner = pTunerModuleMemory;
++
++	// Get tuner module.
++	pTuner = *ppTuner;
++
++	// Set tuner extra module pointer, base interface module pointer, and I2C bridge module pointer.
++	pTuner->pExtra         = pTua9001ExtraModuleMemory;
++	pTuner->pBaseInterface = pBaseInterfaceModuleMemory;
++	pTuner->pI2cBridge     = pI2cBridgeModuleMemory;
++
++	// Get tuner extra module.
++	pExtra = (TUA9001_EXTRA_MODULE *)pTuner->pExtra;
++
++
++
++	// Set tuner type.
++	pTuner->TunerType = TUNER_TYPE_TUA9001;
++
++	// Set tuner I2C device address.
++	pTuner->DeviceAddr = DeviceAddr;
++
++
++	// Initialize tuner parameter setting status.
++	pTuner->IsRfFreqHzSet = NO;
++
++	// Initialize tuner module variables.
++	// Note: Need to give both RF frequency and bandwidth for TUA9001 tuning function,
++	//       so we have to give a default RF frequncy.
++	pTuner->RfFreqHz = TUA9001_RF_FREQ_HZ_DEFAULT;
++
++
++	// Set I2C bridge tuner arguments.
++	tua9001_SetI2cBridgeModuleTunerArg(pTuner);
++
++
++	// Set tuner module manipulating function pointers.
++	pTuner->GetTunerType  = tua9001_GetTunerType;
++	pTuner->GetDeviceAddr = tua9001_GetDeviceAddr;
++
++	pTuner->Initialize    = tua9001_Initialize;
++	pTuner->SetRfFreqHz   = tua9001_SetRfFreqHz;
++	pTuner->GetRfFreqHz   = tua9001_GetRfFreqHz;
++
++
++	// Initialize tuner extra module variables.
++	// Note: Need to give both RF frequency and bandwidth for TUA9001 tuning function,
++	//       so we have to give a default bandwidth.
++	pExtra->BandwidthMode = TUA9001_BANDWIDTH_MODE_DEFAULT;
++	pExtra->IsBandwidthModeSet = NO;
++
++	// Set tuner extra module function pointers.
++	pExtra->SetBandwidthMode    = tua9001_SetBandwidthMode;
++	pExtra->GetBandwidthMode    = tua9001_GetBandwidthMode;
++	pExtra->GetRegBytesWithRegAddr = tua9001_GetRegBytesWithRegAddr;
++	pExtra->SetSysRegByte       = tua9001_SetSysRegByte;
++	pExtra->GetSysRegByte       = tua9001_GetSysRegByte;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_TUNER_TYPE
++
++*/
++void
++tua9001_GetTunerType(
++	TUNER_MODULE *pTuner,
++	int *pTunerType
++	)
++{
++	// Get tuner type from tuner module.
++	*pTunerType = pTuner->TunerType;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_DEVICE_ADDR
++
++*/
++void
++tua9001_GetDeviceAddr(
++	TUNER_MODULE *pTuner,
++	unsigned char *pDeviceAddr
++	)
++{
++	// Get tuner I2C device address from tuner module.
++	*pDeviceAddr = pTuner->DeviceAddr;
++
++
++	return;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_INITIALIZE
++
++*/
++int
++tua9001_Initialize(
++	TUNER_MODULE *pTuner
++	)
++{
++	TUA9001_EXTRA_MODULE *pExtra;
++
++
++
++	// Get tuner extra module.
++	pExtra = (TUA9001_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Initialize TUA9001 tuner.
++	if(initializeTua9001(pTuner) != TUNER_OK)
++		goto error_status_initialize_tuner;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_initialize_tuner:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_SET_RF_FREQ_HZ
++
++*/
++int
++tua9001_SetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long RfFreqHz
++	)
++{
++	TUA9001_EXTRA_MODULE *pExtra;
++
++	long RfFreqKhz;
++	int BandwidthMode;
++
++
++
++	// Get tuner extra module.
++	pExtra = (TUA9001_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get bandwidth mode.
++	BandwidthMode = pExtra->BandwidthMode;
++
++	// Calculate RF frequency in KHz.
++	// Note: RfFreqKhz = round(RfFreqHz / 1000)
++	RfFreqKhz = (long)((RfFreqHz + 500) / 1000);
++
++	// Set TUA9001 RF frequency and bandwidth.
++	if(tuneTua9001(pTuner, RfFreqKhz, BandwidthMode) != TUNER_OK)
++		goto error_status_set_tuner_rf_frequency;
++
++
++	// Set tuner RF frequency parameter.
++	pTuner->RfFreqHz      = (unsigned long)(RfFreqKhz * 1000);
++	pTuner->IsRfFreqHzSet = YES;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_tuner_rf_frequency:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@see   TUNER_FP_GET_RF_FREQ_HZ
++
++*/
++int
++tua9001_GetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long *pRfFreqHz
++	)
++{
++	// Get tuner RF frequency in Hz from tuner module.
++	if(pTuner->IsRfFreqHzSet != YES)
++		goto error_status_get_tuner_rf_frequency;
++
++	*pRfFreqHz = pTuner->RfFreqHz;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_tuner_rf_frequency:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Set TUA9001 tuner bandwidth mode.
++
++*/
++int
++tua9001_SetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int BandwidthMode
++	)
++{
++	TUA9001_EXTRA_MODULE *pExtra;
++
++	long RfFreqKhz;
++
++
++
++	// Get tuner extra module.
++	pExtra = (TUA9001_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get RF frequncy in KHz.
++	// Note: Doesn't need to take round() of RfFreqHz, because its value unit is 1000 Hz.
++	RfFreqKhz = (long)(pTuner->RfFreqHz / 1000);
++
++	// Set TUA9001 RF frequency and bandwidth.
++	if(tuneTua9001(pTuner, RfFreqKhz, BandwidthMode) != TUNER_OK)
++		goto error_status_set_tuner_bandwidth;
++
++
++	// Set tuner bandwidth parameter.
++	pExtra->BandwidthMode      = BandwidthMode;
++	pExtra->IsBandwidthModeSet = YES;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_tuner_bandwidth:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Get TUA9001 tuner bandwidth mode.
++
++*/
++int
++tua9001_GetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int *pBandwidthMode
++	)
++{
++	TUA9001_EXTRA_MODULE *pExtra;
++
++
++
++	// Get tuner extra module.
++	pExtra = (TUA9001_EXTRA_MODULE *)pTuner->pExtra;
++
++
++	// Get tuner bandwidth in Hz from tuner module.
++	if(pExtra->IsBandwidthModeSet != YES)
++		goto error_status_get_tuner_bandwidth;
++
++	*pBandwidthMode = pExtra->BandwidthMode;
++
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_tuner_bandwidth:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++//3 +BIg Lock in Upper Func to ON/OFF repeater
++/**
++
++@brief   Get register bytes with address.
++
++*/
++int
++tua9001_GetRegBytesWithRegAddr(
++	TUNER_MODULE *pTuner,
++	unsigned char DeviceAddr,
++	unsigned char RegAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	)
++{
++	// Get tuner register byte.
++//	if(rtl2832usb_ReadWithRegAddr(DeviceAddr, RegAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS)
++//		goto error_status_get_tuner_registers_with_address;
++
++	I2C_BRIDGE_MODULE *pI2cBridge;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	unsigned char TunerDeviceAddr;
++
++	struct dvb_usb_device	*d;	
++
++
++	// Get I2C bridge.
++	pI2cBridge = pTuner->pI2cBridge;
++	pBaseInterface = pTuner->pBaseInterface;	
++
++	// Get tuner device address.
++	TunerDeviceAddr = *pI2cBridge->pTunerDeviceAddr;
++
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);	
++
++	if( read_rtl2832_tuner_register( d, TunerDeviceAddr, RegAddr, pReadingBytes, ByteNum ) )
++		goto error_status_get_tuner_registers_with_address;
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_tuner_registers_with_address:
++	return FUNCTION_ERROR;
++}
++
++//3 -BIg Lock in Upper Func to ON/OFF repeater
++
++
++
++/**
++
++@brief   Set system register byte.
++
++*/
++int
++tua9001_SetSysRegByte(
++	TUNER_MODULE *pTuner,
++	unsigned short RegAddr,
++	unsigned char WritingByte
++	)
++{
++	// Set demod system register byte.
++//	if(RTK_SYS_Byte_Write(RegAddr, LEN_1_BYTE, &WritingByte) != TRUE)
++//		goto error_status_set_system_registers;
++
++	I2C_BRIDGE_MODULE *pI2cBridge;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	struct dvb_usb_device	*d;	
++
++	// Get I2C bridge.
++	pI2cBridge = pTuner->pI2cBridge;
++	pBaseInterface = pTuner->pBaseInterface;	
++
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);	
++
++	if ( write_usb_sys_char_bytes( d, RTD2832U_SYS, RegAddr, &WritingByte, LEN_1_BYTE) ) 
++		goto error_status_set_system_registers;
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_set_system_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Get system register byte.
++
++*/
++int
++tua9001_GetSysRegByte(
++	TUNER_MODULE *pTuner,
++	unsigned short RegAddr,
++	unsigned char *pReadingByte
++	)
++{
++	// Get demod system register byte.
++//	if(RTK_SYS_Byte_Read(RegAddr, LEN_1_BYTE, pReadingByte) != TRUE)
++//		goto error_status_get_system_registers;
++
++	I2C_BRIDGE_MODULE *pI2cBridge;
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	struct dvb_usb_device	*d;	
++
++	// Get I2C bridge.
++	pI2cBridge = pTuner->pI2cBridge;
++	pBaseInterface = pTuner->pBaseInterface;	
++
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);	
++
++	if ( read_usb_sys_char_bytes(d, RTD2832U_SYS, RegAddr, pReadingByte, LEN_1_BYTE) )
++		goto error_status_get_system_registers;
++
++	return FUNCTION_SUCCESS;
++
++
++error_status_get_system_registers:
++	return FUNCTION_ERROR;
++}
++
++
++
++
++
++/**
++
++@brief   Set I2C bridge module tuner arguments.
++
++TUA9001 builder will use tua9001_SetI2cBridgeModuleTunerArg() to set I2C bridge module tuner arguments.
++
++
++@param [in]   pTuner   The tuner module pointer
++
++
++@see   BuildTua9001Module()
++
++*/
++void
++tua9001_SetI2cBridgeModuleTunerArg(
++	TUNER_MODULE *pTuner
++	)
++{
++	I2C_BRIDGE_MODULE *pI2cBridge;
++
++
++
++	// Get I2C bridge module.
++	pI2cBridge = pTuner->pI2cBridge;
++
++	// Set I2C bridge module tuner arguments.
++	pI2cBridge->pTunerDeviceAddr = &pTuner->DeviceAddr;
++
++
++	return;
++}
++
++
++
++
++
++// TUA9001 custom-implement functions
++
++
++int setRESETN (TUNER_MODULE *pTuner, unsigned int i_state)
++{
++	TUA9001_EXTRA_MODULE *pExtra;
++	unsigned char Byte;
++
++
++	// Get tuner extra module.
++	pExtra = (TUA9001_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get GPO value.
++	if(pExtra->GetSysRegByte(pTuner, GPO_ADDR, &Byte) != FUNCTION_SUCCESS)
++		goto error_status_get_system_registers;
++
++	// Note: Hardware PCB has inverter in this pin, should give inverted value on GPIO3.
++	if (i_state == H_LEVEL)
++	{
++		/* set tuner RESETN pin to "H"  */
++		// Note: The GPIO3 output value should be '0'.
++		if( pTuner->b_set_tuner_power_gpio4 )	Byte &= ~BIT_4_MASK;
++		else									Byte &= ~BIT_3_MASK;
++	}
++	else
++	{
++		/* set tuner RESETN pin to "L"  */
++		// Note: The GPIO3 output value should be '1'.
++		if( pTuner->b_set_tuner_power_gpio4 )	Byte |= BIT_4_MASK;
++		else									Byte |= BIT_3_MASK;
++	}
++
++	// Set GPO value.
++	if(pExtra->SetSysRegByte(pTuner, GPO_ADDR, Byte) != FUNCTION_SUCCESS)
++		goto error_status_set_system_registers;
++
++
++	return TUNER_OK;
++
++
++error_status_set_system_registers:
++error_status_get_system_registers:
++	return TUNER_ERR;
++}
++
++
++
++int setRXEN (TUNER_MODULE *pTuner, unsigned int i_state)
++{
++	TUA9001_EXTRA_MODULE *pExtra;
++	unsigned char Byte;
++
++
++	// Get tuner extra module.
++	pExtra = (TUA9001_EXTRA_MODULE *)pTuner->pExtra;
++
++	// Get GPO value.
++	if(pExtra->GetSysRegByte(pTuner, GPO_ADDR, &Byte) != FUNCTION_SUCCESS)
++		goto error_status_get_system_registers;
++
++	if (i_state == H_LEVEL)
++	{
++		/* set tuner RXEN pin to "H"  */
++		// Note: The GPIO1 output value should be '1'.
++		Byte |= BIT_1_MASK;
++	}
++	else
++	{
++		/* set tuner RXEN pin to "L"  */
++		// Note: The GPIO1 output value should be '0'.
++		Byte &= ~BIT_1_MASK;
++	}
++
++	// Set GPO value.
++	if(pExtra->SetSysRegByte(pTuner, GPO_ADDR, Byte) != FUNCTION_SUCCESS)
++		goto error_status_set_system_registers;
++
++
++	return TUNER_OK;
++
++
++error_status_set_system_registers:
++error_status_get_system_registers:
++	return TUNER_ERR;
++}
++
++
++
++int setCEN (TUNER_MODULE *pTuner, unsigned int i_state)
++{
++	// Do nothing.
++	// Note: Hardware PCB always gives 'H' to tuner CEN pin.
++	return TUNER_OK;
++}
++
++
++
++int waitloop (TUNER_MODULE *pTuner, unsigned int i_looptime)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++	unsigned long WaitTimeMs;
++
++
++	// Get base interface.
++	pBaseInterface = pTuner->pBaseInterface;
++
++	/* wait time = i_looptime * 1 uS */
++	// Note: 1. The unit of WaitMs() function is ms.
++	//       2. WaitTimeMs = ceil(i_looptime / 1000)
++	WaitTimeMs = i_looptime / 1000;
++
++	if((i_looptime % 1000) > 0)
++		WaitTimeMs += 1;
++
++	pBaseInterface->WaitMs(pBaseInterface, WaitTimeMs);
++
++
++	return TUNER_OK;
++}
++
++
++
++int i2cBusWrite (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data,
++				 unsigned int length)
++{
++	BASE_INTERFACE_MODULE *pBaseInterface;
++
++	unsigned char ByteNum;
++	unsigned char WritingBytes[I2C_BUFFER_LEN];
++	unsigned int i;
++
++	I2C_BRIDGE_MODULE *pI2cBridge;
++	unsigned char TunerDeviceAddr;
++	struct dvb_usb_device	*d;
++
++	// Get base interface.
++	pBaseInterface = pTuner->pBaseInterface;
++
++	// Get I2C bridge.
++	pI2cBridge = pTuner->pI2cBridge;	
++
++	// Get tuner device address.
++	TunerDeviceAddr = *pI2cBridge->pTunerDeviceAddr;
++
++	pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d);	
++
++
++	/* I2C write data format */
++	/* STA  device_address  ACK  register_address  ACK   H_Byte-Data ACK   L_Byte-Data  !ACK  STO */
++
++	/* STA = start condition, ACK = Acknowledge, STO = stop condition                             */   
++	/* *data  = pointer to data source   */
++	/* length = number of bytes to write */
++
++	// Determine byte number.
++	//ByteNum = length + LEN_1_BYTE;
++	ByteNum = length;
++
++	// Determine writing bytes.
++	//WritingBytes[0] = registerAddress;
++
++	for(i = 0; i < length; i++)
++		//WritingBytes[LEN_1_BYTE + i] = data[i];
++		WritingBytes[i] = data[i];
++
++	// Send I2C writing command.
++//	if(pBaseInterface->I2cWrite(pBaseInterface, deviceAddress, WritingBytes, ByteNum) != FUNCTION_SUCCESS)
++//		goto error_status_set_tuner_registers;
++
++
++	if( write_rtl2832_tuner_register( d, TunerDeviceAddr, registerAddress, WritingBytes, ByteNum ) )
++		goto error_status_set_tuner_registers;
++
++
++	return TUNER_OK;
++
++
++error_status_set_tuner_registers:
++	return TUNER_ERR;
++}
++
++
++
++int i2cBusRead (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data,
++				unsigned int length)
++{
++	TUA9001_EXTRA_MODULE *pExtra;
++
++
++	// Get tuner extra module.
++	pExtra = (TUA9001_EXTRA_MODULE *)pTuner->pExtra;
++
++
++	/* I2C read data format */
++	/* STA  device_address  ACK  register_address  ACK  STA H_Byte-Data ACK  device_address_read  ACK  H_Byte-Data ACK L_Byte-Data  ACKH  STO */
++
++	/* STA = start condition, ACK = Acknowledge (generated by TUA9001), ACKH = Acknowledge (generated by Host), STO = stop condition                             */   
++	/* *data  = pointer to data destination   */
++	/* length = number of bytes to read       */
++
++	// Get tuner register bytes with address.
++	// Note: We must use re-start I2C reading format for TUA9001 tuner register reading.
++	if(pExtra->GetRegBytesWithRegAddr(pTuner, deviceAddress, registerAddress, data, length) != FUNCTION_SUCCESS)
++		goto error_status_get_tuner_registers;
++
++
++	return TUNER_OK;
++
++
++error_status_get_tuner_registers:
++	return TUNER_ERR;
++}
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// The following context is source code provided by Infineon.
++
++
++
++
++
++// Infineon source code - driver_tua9001.c
++
++
++/* ============================================================================
++** Copyright (C) 1997-2007 Infineon AG All rights reserved.
++** ============================================================================
++**
++** ============================================================================
++** Revision Information :
++**    File name: driver_tua9001.c
++**    Version:  V 1.01
++**    Date: 
++**
++** ============================================================================
++** History: 
++** 
++** Date         Author  Comment
++** ----------------------------------------------------------------------------
++**
++** 2007.11.06   Walter Pichler    created.
++** 2008.04.08   Walter Pichler    adaption to TUA 9001E
++**
++** ============================================================================
++*/
++
++/*============================================================================
++Includes
++============================================================================*/
++
++//#include "driver_tua9001.h"
++//#include "driver_tua9001_NeededFunctions.h"   /* Note: This function have to be provided by the user */
++
++/*============================================================================
++Local compiler keeys         ( usage depends on the application )
++============================================================================*/
++
++#define CRYSTAL_26_MHZ
++//#define CRYSTAL_19.2_MHZ
++//#define CRYSTAL_20.48_MHZ
++
++//#define AGC_BY_IIC
++//#define AGC_BY_AGC_BUS
++#define AGC_BY_EXT_PIN
++
++
++/*============================================================================
++Named Constants Definitions    ( usage depends on the application )
++============================================================================*/
++
++#define TUNERs_TUA9001_DEVADDR    0xC0
++
++/* Note: The correct device address depends hardware settings. See Datasheet
++      and User Manual for details. */
++
++/*============================================================================
++Local Named Constants Definitions
++============================================================================*/
++#define		OPERATIONAL_MODE     	0x03 
++#define		CHANNEL_BANDWITH    	0x04
++#define		SW_CONTR_TIME_SLICING	0x05
++#define		BASEBAND_GAIN_CONTROL	0x06
++#define		MANUAL_BASEBAND_GAIN	0x0b
++#define		REFERENCE_FREQUENCY 	0x1d
++#define		CHANNEL_WORD        	0x1f
++#define		CHANNEL_OFFSET	    	0x20
++#define		CHANNEL_FILTER_TRIMMING	0x2f
++#define		OUTPUT_BUFFER	    	0x32
++#define		RF_AGC_CONFIG_A	    	0x36
++#define		RF_AGC_CONFIG_B	    	0x37
++#define		UHF_LNA_SELECT	    	0x39
++#define		LEVEL_DETECTOR	    	0x3a
++#define		MIXER_CURRENT	    	0x3b
++#define		PORT_CONTROL		    0x3e
++#define		CRYSTAL_TRIMMING    	0x41
++#define		CHANNEL_FILTER_STATUS	0x60
++#define		SIG_STRENGHT_INDICATION	0x62
++#define		PLL_LOCK	        	0x69
++#define		RECEIVER_STATE	    	0x70
++#define		RF_INPUT	        	0x71
++#define		BASEBAND_GAIN	    	0x72
++#define		CHIP_IDENT_CODE	    	0x7e
++#define		CHIP_REVISION	    	0x7f
++
++#define TUNERs_TUA9001_BW_8         0xcf
++#define TUNERs_TUA9001_BW_7         0x10
++#define TUNERs_TUA9001_BW_6         0x20
++#define TUNERs_TUA9001_BW_5         0x30
++
++
++
++
++/*============================================================================
++ Types definition
++============================================================================*/
++
++
++
++
++/*============================================================================
++ Public Functions
++============================================================================*/
++
++
++/**
++ * tuner initialisation
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++ 
++int initializeTua9001 (TUNER_MODULE *pTuner)
++{
++  unsigned int counter;
++  char i2cseq[2];
++  tunerReceiverState_t tunerState;
++  unsigned char DeviceAddr;
++
++  // Get tuner deviece address.
++  pTuner->GetDeviceAddr(pTuner, &DeviceAddr);
++
++  /* Note: CEN may also be hard wired in the application*/
++  if(setCEN    (pTuner, H_LEVEL) != TUNER_OK) goto error_status;    /* asserting Chip enable      */
++
++  if(setRESETN (pTuner, L_LEVEL) != TUNER_OK) goto error_status;    /* asserting RESET            */
++  
++  if(setRXEN   (pTuner, L_LEVEL) != TUNER_OK) goto error_status;    /* RXEN to low >> IDLE STATE  */
++  
++  /* Note: 20ms assumes that all external power supplies are settled. If not, add more time here */
++  waitloop (pTuner, 20);          /* wait for 20 uS     */
++  
++  if(setRESETN (pTuner, H_LEVEL) != TUNER_OK) goto error_status;    /* de-asserting RESET */
++
++  /* This is to wait for the Crystal Oscillator to settle .. wait until IDLE mode is reached */  
++  counter = 6;
++  do
++    {
++    counter --;
++    waitloop (pTuner, 1000);      /* wait for 1 mS      */
++    if(getReceiverStateTua9001 (pTuner, &tunerState) != TUNER_OK) goto error_status;
++    }while ((tunerState != IDLE) && (counter));  
++
++  if (tunerState != IDLE)
++      return TUNER_ERR;   /* error >> break initialization   */
++
++  /**** Overwrite default register value ****/ 
++  i2cseq[0] = 0x65;    /* Waiting time before PLL cal. start */
++  i2cseq[1] = 0x12;   
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x1e, i2cseq, 2) != TUNER_OK) goto error_status;
++
++  i2cseq[0] = 0xB8;    /* VCO Varactor bias fine tuning */
++  i2cseq[1] = 0x88;   
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x25, i2cseq, 2) != TUNER_OK) goto error_status;
++
++  i2cseq[0] = 0x54;    /* LNA switching Threshold for UHF1/2 */
++  i2cseq[1] = 0x60;
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x39, i2cseq, 2) != TUNER_OK) goto error_status;
++
++  i2cseq[0] = 0x00;    
++  i2cseq[1] = 0xC0;
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x3b, i2cseq, 2) != TUNER_OK) goto error_status;
++
++  i2cseq[0] = 0xF0;    /* LO- Path Set LDO output voltage */
++  i2cseq[1] = 0x00;
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x3a, i2cseq, 2) != TUNER_OK) goto error_status;
++  
++  i2cseq[0] = 0x00;    /* Set EXTAGC interval */
++  i2cseq[1] = 0x00;               
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x08, i2cseq, 2) != TUNER_OK) goto error_status;
++  
++  i2cseq[0] = 0x00;    /* Set max. capacitive load */
++  i2cseq[1] = 0x30;   
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x32, i2cseq, 2) != TUNER_OK) goto error_status;
++
++
++  /**** Set Crystal Reference Frequency an Trim value ****/
++#if defined(CRYSTAL_26_MHZ)       /*  Frequency 26 MHz */
++  i2cseq[0] = 0x01;
++  i2cseq[1] = 0xB0;    
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x1d, i2cseq, 2) != TUNER_OK) goto error_status;
++
++  i2cseq[0] = 0x70;              /* NDK 3225 series 26 MHz XTAL */
++  i2cseq[1] = 0x3a;
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x41, i2cseq, 2) != TUNER_OK) goto error_status;
++  i2cseq[0] = 0x1C;
++  i2cseq[1] = 0x78;
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x40, i2cseq, 2) != TUNER_OK) goto error_status;
++
++#elif defined(CRYSTAL_19.2_MHZ)   /*  Frequency 19.2 MHz */
++  i2cseq[0] = 0x01;
++  i2cseq[1] = 0xA0;    
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x1d, i2cseq, 2) != TUNER_OK) goto error_status;
++  /* Note: Insert optimised register values for 0x40 / 0x41 for used crystal */
++  /* contact application support for further information */
++#elif defined(CRYSTAL_20.48_MHZ)   /*  Frequency 20,48 MHz */
++  i2cseq[0] = 0x01;
++  i2cseq[1] = 0xA8;    
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x1d, i2cseq, 2) != TUNER_OK) goto error_status;
++  /* Note: Insert optimised register values for 0x40 / 0x41 for used crystal */
++  /* contact application support for further information */
++#endif
++
++
++
++ /**** Set desired Analog Baseband AGC mode ****/ 
++#if defined (AGC_BY_IIC)
++  i2cseq[0] = 0x00;                /* Bypass AGC controller >>  IIC based AGC */
++  i2cseq[1] = 0x40;                     
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x06, i2cseq, 2) != TUNER_OK) goto error_status;
++#elif defined(AGC_BY_AGC_BUS)      
++  i2cseq[0] = 0x00;                /* Digital AGC bus */               
++  i2cseq[1] = 0x00;                /* 0,5 dB steps    */                    
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x06, i2cseq, 2) != TUNER_OK) goto error_status;
++#elif defined(AGC_BY_EXT_PIN)      
++  i2cseq[0] = 0x40;                /* Ext. AGC pin     */               
++  i2cseq[1] = 0x00;                                    
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x06, i2cseq, 2) != TUNER_OK) goto error_status;
++#endif 
++
++ 
++  /**** set desired RF AGC parameter *****/
++  i2cseq[0] = 0x1c;      /* Set Wideband Detector Current (100 uA) */
++  i2cseq[1] = 0x00;
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x2c, i2cseq, 2) != TUNER_OK) goto error_status;
++ 
++  i2cseq[0] = 0xC0;      /* Set RF AGC Threshold (-32.5dBm) */
++  i2cseq[1] = 0x13;
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x36, i2cseq, 2) != TUNER_OK) goto error_status;
++
++  i2cseq[0] = 0x6f;      /* RF AGC Parameter */
++  i2cseq[1] = 0x18;   
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x37, i2cseq, 2) != TUNER_OK) goto error_status;
++
++  i2cseq[0] = 0x00;      /* aditional VCO settings  */
++  i2cseq[1] = 0x08;   
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x27, i2cseq, 2) != TUNER_OK) goto error_status;
++
++  i2cseq[0] = 0x00;      /* aditional PLL settings  */
++  i2cseq[1] = 0x01;   
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x2a, i2cseq, 2) != TUNER_OK) goto error_status;
++
++  i2cseq[0] = 0x0a;      /* VCM correction         */
++  i2cseq[1] = 0x40;   
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x34, i2cseq, 2) != TUNER_OK) goto error_status;
++
++
++  return TUNER_OK;
++
++
++error_status:
++  return TUNER_ERR;
++}
++
++
++
++/**
++ * tuner tune
++ * @param i_freq   tuning frequency
++ * @param i_bandwidth  channel  bandwidth
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++
++int tuneTua9001 (TUNER_MODULE *pTuner, long i_freq, tunerDriverBW_t i_bandwidth)
++{
++  char i2cseq[2];
++  unsigned int divider_factor;
++  unsigned int ch_offset;
++  unsigned int counter;
++  unsigned int lo_path_settings;
++  tunerReceiverState_t tunerState;
++  unsigned char DeviceAddr;
++
++  // Get tuner deviece address.
++  pTuner->GetDeviceAddr(pTuner, &DeviceAddr);
++
++
++ 
++  /* de-assert RXEN >> IDLE STATE */
++  if(setRXEN   (pTuner, L_LEVEL) != TUNER_OK) goto error_status;          
++ 
++
++  /* calculate divider factor */
++  if (i_freq < 1000000)    /*  divider factor and channel offset for UHF/VHF III */
++   {
++   ch_offset = 0x1C20;     /* channel offset 150 MHz */
++   divider_factor   =  (unsigned int) (((i_freq - 150000) * 48) / 1000);
++   lo_path_settings = 0xb6de;
++  }
++
++  else                     /* calculate divider factor for L-Band Frequencies */
++   {
++   ch_offset = 0x5460;     /* channel offset 450 MHz */
++   divider_factor   =  (unsigned int) (((i_freq - 450000) * 48) / 1000);
++   lo_path_settings = 0xbede;
++   }
++
++
++  // Set LO Path
++  i2cseq[0] = lo_path_settings >> 8;
++  i2cseq[1] = lo_path_settings & 0xff;
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x2b, i2cseq, 2) != TUNER_OK) goto error_status;
++
++  // Set channel offset
++  i2cseq [0] =  ch_offset >> 8;
++  i2cseq [1] =  ch_offset & 0xff;
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x20, i2cseq, 2) != TUNER_OK) goto error_status;
++  
++  // Set Frequency
++  i2cseq [0] =  divider_factor >> 8;
++  i2cseq [1] =  divider_factor & 0xff;
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x1f, i2cseq, 2) != TUNER_OK) goto error_status;
++   
++  // Set bandwidth
++  if(i2cBusRead (pTuner, DeviceAddr,  0x04, i2cseq, 2) != TUNER_OK) goto error_status;         /* get current register value */
++  i2cseq [0] &= TUNERs_TUA9001_BW_8;
++ 
++  switch (i_bandwidth)
++    {
++    case TUNER_BANDWIDTH_8MHZ:
++         // Do nothing.
++         break; 
++    case TUNER_BANDWIDTH_7MHZ: i2cseq [0] |= TUNERs_TUA9001_BW_7;
++         break; 
++    case TUNER_BANDWIDTH_6MHZ: i2cseq [0] |= TUNERs_TUA9001_BW_6;
++         break; 
++    case TUNER_BANDWIDTH_5MHZ: i2cseq [0] |= TUNERs_TUA9001_BW_5;
++         break; 
++    default:
++         goto error_status;
++         break;	
++    }
++
++  if(i2cBusWrite (pTuner, DeviceAddr, 0x04, i2cseq, 2) != TUNER_OK) goto error_status;
++ 
++  /* assert RXEN >> RX STATE */
++  if(setRXEN   (pTuner, H_LEVEL) != TUNER_OK) goto error_status;
++
++  /* This is to wait for the RX state to settle .. wait until RX mode is reached */  
++  counter = 3;
++  do
++    {
++    counter --;
++    waitloop (pTuner, 1000);         /* wait for 1 mS      */
++    if(getReceiverStateTua9001 (pTuner, &tunerState) != TUNER_OK) goto error_status;
++    }while ((tunerState != RX) && (counter));  
++
++  if (tunerState != RX)
++    {
++    if(setRXEN  (pTuner, L_LEVEL) != TUNER_OK) goto error_status;      /* d-assert RXEN >> IDLE STATE */
++    return   TUNER_ERR;      /* error >> tuning fail        */
++    }
++
++  return TUNER_OK;
++
++
++error_status:
++  return TUNER_ERR;
++}
++
++
++/**
++ * Get pll locked state
++ * @param o_pll  pll locked state
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++
++int getPllLockedStateTua9001 (TUNER_MODULE *pTuner, tunerPllLocked_t *o_pll)
++{
++  char i2cseq[2];
++  unsigned char DeviceAddr;
++
++  // Get tuner deviece address.
++  pTuner->GetDeviceAddr(pTuner, &DeviceAddr);
++
++  if(i2cBusRead (pTuner, DeviceAddr, 0x69, i2cseq, 2) != TUNER_OK) goto error_status;           /* get current register value */
++  
++  o_pll[0]  = (i2cseq[1] & 0x08) ? PLL_LOCKED : PLL_NOT_LOCKED;
++ 
++  return TUNER_OK;
++
++
++error_status:
++  return TUNER_ERR;
++}
++
++
++/**
++ * Get tuner state
++ * @param o_tunerState tuner state
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++
++int getReceiverStateTua9001 (TUNER_MODULE *pTuner, tunerReceiverState_t *o_tunerState)
++{
++  char i2cseq[2];
++  unsigned char DeviceAddr;
++
++  // Get tuner deviece address.
++  pTuner->GetDeviceAddr(pTuner, &DeviceAddr);
++
++  if(i2cBusRead (pTuner, DeviceAddr, 0x70, i2cseq, 2) != TUNER_OK) goto error_status;           /* get current register value */
++
++//  switch (i2cseq[1] & ~0x1f)
++  // Note: Maybe the MSB byte is i2cseq[0]
++  //       The original code looks like the MSB byte is i2cseq[1]
++  // Note: ~0x0f = 0xffffffe0, not 0xe0 --> i2cseq[0] & ~0x1f result is wrong.
++  switch (i2cseq[0] & 0xe0)
++     {
++     case 0x80: o_tunerState [0] = IDLE;  break;
++     case 0x40: o_tunerState [0] = RX;    break;
++     case 0x20: o_tunerState [0] = STANDBY; 
++     }
++ 
++  return TUNER_OK;
++
++
++error_status:
++  return TUNER_ERR;
++}
++
++
++/**
++ * Get active input
++ * @param o_activeInput active input info
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++ 
++int getActiveInputTua9001 (TUNER_MODULE *pTuner, tunerActiveInput_t *o_activeInput)
++{
++  char i2cseq[2];
++  unsigned char DeviceAddr;
++
++  // Get tuner deviece address.
++  pTuner->GetDeviceAddr(pTuner, &DeviceAddr);
++
++  if(i2cBusRead (pTuner, DeviceAddr, 0x71, i2cseq, 2) != TUNER_OK) goto error_status;           /* get current register value */
++
++//  switch (i2cseq[1] & ~0x0f)
++  // Note: Maybe the MSB byte is i2cseq[0]
++  //       The original code looks like the MSB byte is i2cseq[1]
++  // Note: ~0x0f = 0xfffffff0, not 0xf0 --> i2cseq[0] & ~0x0f result is wrong.
++  switch (i2cseq[0] & 0xf0)
++     {
++     case 0x80: o_activeInput [0] = L_INPUT_ACTIVE;   break;
++     case 0x20: o_activeInput [0] = UHF_INPUT_ACTIVE; break;
++     case 0x10: o_activeInput [0] = VHF_INPUT_ACTIVE; 
++     }
++ 
++  return TUNER_OK;
++
++
++error_status:
++  return TUNER_ERR;
++}
++
++
++/**
++ * Get baseband gain value
++ * @param o_basebandGain  baseband gain value
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++
++int getBasebandGainTua9001 (TUNER_MODULE *pTuner, char *o_basebandGain)
++{
++  char i2cseq[2];
++  unsigned char DeviceAddr;
++
++  // Get tuner deviece address.
++  pTuner->GetDeviceAddr(pTuner, &DeviceAddr);
++
++  if(i2cBusRead (pTuner, DeviceAddr, 0x72, i2cseq, 2) != TUNER_OK) goto error_status;           /* get current register value */
++//  o_basebandGain [0] = i2cseq [1];
++  // Note: Maybe the MSB byte is i2cseq[0]
++  //       The original code looks like the MSB byte is i2cseq[1]
++  o_basebandGain [0] = i2cseq [0];
++ 
++  return TUNER_OK;
++
++
++error_status:
++  return TUNER_ERR;
++}
++
++
++
+diff -r abd3aac6644e linux/drivers/media/dvb/dvb-usb/tuner_tua9001.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/linux/drivers/media/dvb/dvb-usb/tuner_tua9001.h	Wed Oct 27 09:16:44 2010 +0200
+@@ -0,0 +1,572 @@
++#ifndef __TUNER_TUA9001_H
++#define __TUNER_TUA9001_H
++
++/**
++
++@file
++
++@brief   TUA9001 tuner module declaration
++
++One can manipulate TUA9001 tuner through TUA9001 module.
++TUA9001 module is derived from tunerd module.
++
++
++
++@par Example:
++@code
++
++// The example is the same as the tuner example in tuner_base.h except the listed lines.
++
++
++
++#include "tuner_tua9001.h"
++
++
++...
++
++
++
++int main(void)
++{
++	TUNER_MODULE        *pTuner;
++	TUA9001_EXTRA_MODULE *pTunerExtra;
++
++	TUNER_MODULE          TunerModuleMemory;
++	TUA9001_EXTRA_MODULE   Tua9001ExtraModuleMemory;
++	BASE_INTERFACE_MODULE BaseInterfaceModuleMemory;
++	I2C_BRIDGE_MODULE     I2cBridgeModuleMemory;
++
++	int BandwidthMode;
++
++
++	...
++
++
++
++	// Build TUA9001 tuner module.
++	BuildTua9001Module(
++		&pTuner,
++		&TunerModuleMemory,
++		&Tua9001ExtraModuleMemory,
++		&BaseInterfaceModuleMemory,
++		&I2cBridgeModuleMemory,
++		0xc0								// I2C device address is 0xc0 in 8-bit format.
++		);
++
++
++
++
++
++	// Get TUA9001 tuner extra module.
++	pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra);
++
++
++
++
++
++	// ==== Initialize tuner and set its parameters =====
++
++	...
++
++	// Set TUA9001 bandwidth.
++	pTunerExtra->SetBandwidthMode(pTuner, TUA9001_BANDWIDTH_6MHZ);
++
++
++
++
++
++	// ==== Get tuner information =====
++
++	...
++
++	// Get TUA9001 bandwidth.
++	pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode);
++
++
++
++
++
++	// See the example for other tuner functions in tuner_base.h
++
++
++	return 0;
++}
++
++
++@endcode
++
++*/
++
++
++#include "tuner_base.h"
++//#include "i2c_rtl2832usb.h"
++
++
++
++
++
++// The following context is source code provided by Infineon.
++
++
++
++
++
++// Infineon source code - driver_tua9001.h
++
++
++
++/* ============================================================================
++** Copyright (C) 1997-2007 Infineon AG All rights reserved.
++** ============================================================================
++**
++** ============================================================================
++** Revision Information :
++**    File name: driver_tua9001.h
++**    Version: 
++**    Date: 
++**
++** ============================================================================
++** History: 
++** 
++** Date         Author  Comment
++** ----------------------------------------------------------------------------
++**
++** 2007.11.06   Walter Pichler    created.
++** ============================================================================
++*/
++
++ 
++/*============================================================================
++ Named Constants Definitions
++============================================================================*/
++
++#define TUNER_OK                       0
++#define TUNER_ERR                      0xff
++
++#define H_LEVEL                        1
++#define L_LEVEL                        0
++
++
++/*============================================================================
++ Types definition
++============================================================================*/
++
++
++typedef enum {
++        TUNER_BANDWIDTH_8MHZ,
++        TUNER_BANDWIDTH_7MHZ,
++        TUNER_BANDWIDTH_6MHZ,
++        TUNER_BANDWIDTH_5MHZ,
++        } tunerDriverBW_t;
++
++
++typedef enum {
++        PLL_LOCKED,
++        PLL_NOT_LOCKED
++        }tunerPllLocked_t;
++
++
++typedef enum {
++        STANDBY,
++        IDLE,
++        RX
++        } tunerReceiverState_t;
++
++
++typedef enum {
++        L_INPUT_ACTIVE,
++        UHF_INPUT_ACTIVE,
++        VHF_INPUT_ACTIVE
++        } tunerActiveInput_t;
++
++ 
++
++/*============================================================================
++ Public functions
++============================================================================*/
++
++/**
++ * tuner initialisation
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++extern int initializeTua9001 (TUNER_MODULE *pTuner);
++
++
++/**
++ * tuner tune
++ * @param i_freq   tuning frequency
++ * @param i_bandwidth  channel  bandwidth
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++extern int tuneTua9001 (TUNER_MODULE *pTuner, long i_freq, tunerDriverBW_t i_bandwidth);
++
++
++/**
++ * Get tuner state
++ * @param o_tunerState tuner state
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++extern int getReceiverStateTua9001 (TUNER_MODULE *pTuner, tunerReceiverState_t *o_tunerState);
++
++/**
++ * Get active input
++ * @param o_activeInput active input info
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++extern int getActiveInputTua9001 (TUNER_MODULE *pTuner, tunerActiveInput_t *o_activeInput);
++
++
++/**
++ * Get baseband gain value
++ * @param o_basebandGain  baseband gain value
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++extern int getBasebandGainTua9001 (TUNER_MODULE *pTuner, char *o_basebandGain);
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// Infineon source code - driver_tua9001_NeededFunctions.h
++
++
++
++/*========================================================================================================================
++ additional needed external funtions ( have to  be provided by the user! )
++========================================================================================================================*/
++
++/**
++ * set / reset tuner reset input
++ * @param i_state   level
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++
++int setRESETN (TUNER_MODULE *pTuner, unsigned int i_state);
++
++
++/**
++ * set / reset tuner receive enable input
++ * @param i_state   level
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++
++int setRXEN (TUNER_MODULE *pTuner, unsigned int i_state);
++
++
++/**
++ * set / reset tuner chiop enable input
++ * @param i_state   level
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++
++int setCEN (TUNER_MODULE *pTuner, unsigned int i_state);
++
++
++/**
++ * waitloop 
++ * @param i_looptime   * 1uS
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++
++int waitloop (TUNER_MODULE *pTuner, unsigned int i_looptime);
++
++
++/**
++ * i2cBusWrite 
++ * @param deviceAdress    chip address 
++ * @param registerAdress  register address 
++ * @param *data           pointer to data source
++ * @param length          number of bytes to transmit
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++
++ int i2cBusWrite (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data,
++	 unsigned int length);
++
++
++/**
++ * i2cBusRead 
++ * @param deviceAdress    chip address 
++ * @param registerAdress  register address 
++ * @param *data           pointer to data destination
++ * @param length          number of bytes to read
++ * @retval TUNER_OK No error
++ * @retval TUNER_ERR Error
++*/
++
++ int i2cBusRead (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data,
++	 unsigned int length);
++
++/*========================================================================================================================
++ end of additional needed external funtions
++========================================================================================================================*/
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++// The following context is TUA9001 tuner API source code
++
++
++
++
++
++/**
++
++@file
++
++@brief   TUA9001 tuner module declaration
++
++One can manipulate TUA9001 tuner through TUA9001 module.
++TUA9001 module is derived from tuner module.
++
++*/
++
++
++
++
++
++// Definitions
++
++// Constant
++#define GPO_ADDR	0x1
++
++// Bandwidth modes
++enum TUA9001_BANDWIDTH_MODE
++{
++	TUA9001_BANDWIDTH_5MHZ = TUNER_BANDWIDTH_5MHZ,
++	TUA9001_BANDWIDTH_6MHZ = TUNER_BANDWIDTH_6MHZ,
++	TUA9001_BANDWIDTH_7MHZ = TUNER_BANDWIDTH_7MHZ,
++	TUA9001_BANDWIDTH_8MHZ = TUNER_BANDWIDTH_8MHZ,
++};
++
++// Default value
++#define TUA9001_RF_FREQ_HZ_DEFAULT			50000000;
++#define TUA9001_BANDWIDTH_MODE_DEFAULT		TUA9001_BANDWIDTH_5MHZ;
++
++
++
++
++
++/// TUA9001 extra module alias
++typedef struct TUA9001_EXTRA_MODULE_TAG TUA9001_EXTRA_MODULE;
++
++
++
++
++
++// Extra manipulaing function
++typedef int
++(*TUA9001_FP_SET_BANDWIDTH_MODE)(
++	TUNER_MODULE *pTuner,
++	int BandwidthMode
++	);
++
++typedef int
++(*TUA9001_FP_GET_BANDWIDTH_MODE)(
++	TUNER_MODULE *pTuner,
++	int *pBandwidthMode
++	);
++
++typedef int
++(*TUA9001_FP_GET_REG_BYTES_WITH_REG_ADDR)(
++	TUNER_MODULE *pTuner,
++	unsigned char DeviceAddr,
++	unsigned char RegAddr,
++	unsigned char *pReadingByte,
++	unsigned char ByteNum
++	);
++
++typedef int
++(*TUA9001_FP_SET_SYS_REG_BYTE)(
++	TUNER_MODULE *pTuner,
++	unsigned short RegAddr,
++	unsigned char WritingByte
++	);
++
++typedef int
++(*TUA9001_FP_GET_SYS_REG_BYTE)(
++	TUNER_MODULE *pTuner,
++	unsigned short RegAddr,
++	unsigned char *pReadingByte
++	);
++
++
++
++
++
++// TUA9001 extra module
++struct TUA9001_EXTRA_MODULE_TAG
++{
++	// TUA9001 extra variables
++	int BandwidthMode;
++	int IsBandwidthModeSet;
++
++	// TUA9001 extra function pointers
++	TUA9001_FP_SET_BANDWIDTH_MODE            SetBandwidthMode;
++	TUA9001_FP_GET_BANDWIDTH_MODE            GetBandwidthMode;
++	TUA9001_FP_GET_REG_BYTES_WITH_REG_ADDR   GetRegBytesWithRegAddr;
++	TUA9001_FP_SET_SYS_REG_BYTE              SetSysRegByte;
++	TUA9001_FP_GET_SYS_REG_BYTE              GetSysRegByte;
++};
++
++
++
++
++
++// Builder
++void
++BuildTua9001Module(
++	TUNER_MODULE **ppTuner,
++	TUNER_MODULE *pTunerModuleMemory,
++	TUA9001_EXTRA_MODULE *pTua9001ExtraModuleMemory,
++	BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory,
++	I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory,
++	unsigned char DeviceAddr
++	);
++
++
++
++
++
++// Manipulaing functions
++void
++tua9001_GetTunerType(
++	TUNER_MODULE *pTuner,
++	int *pTunerType
++	);
++
++void
++tua9001_GetDeviceAddr(
++	TUNER_MODULE *pTuner,
++	unsigned char *pDeviceAddr
++	);
++
++int
++tua9001_Initialize(
++	TUNER_MODULE *pTuner
++	);
++
++int
++tua9001_SetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long RfFreqHz
++	);
++
++int
++tua9001_GetRfFreqHz(
++	TUNER_MODULE *pTuner,
++	unsigned long *pRfFreqHz
++	);
++
++
++
++
++
++// Extra manipulaing functions
++int
++tua9001_SetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int BandwidthMode
++	);
++
++int
++tua9001_GetBandwidthMode(
++	TUNER_MODULE *pTuner,
++	int *pBandwidthMode
++	);
++
++int
++tua9001_GetRegBytesWithRegAddr(
++	TUNER_MODULE *pTuner,
++	unsigned char DeviceAddr,
++	unsigned char RegAddr,
++	unsigned char *pReadingBytes,
++	unsigned char ByteNum
++	);
++
++int
++tua9001_SetSysRegByte(
++	TUNER_MODULE *pTuner,
++	unsigned short RegAddr,
++	unsigned char WritingByte
++	);
++
++int
++tua9001_GetSysRegByte(
++	TUNER_MODULE *pTuner,
++	unsigned short RegAddr,
++	unsigned char *pReadingByte
++	);
++
++
++
++
++
++// I2C birdge module demod argument setting
++void
++tua9001_SetI2cBridgeModuleTunerArg(
++	TUNER_MODULE *pTuner
++	);
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++#endif
--- a/series	Wed Oct 27 09:26:29 2010 +0200
+++ b/series	Wed Oct 27 09:27:24 2010 +0200
@@ -0,0 +1,1 @@
+090730_RTL2832U_LINUX_Ver1.1.patch