090730_RTL2832U_LINUX_Ver1.1.patch
author Tomas Zeman <tzeman@volny.cz>
Wed, 27 Oct 2010 09:33:59 +0200
changeset 3 03e1009276b5
parent 2 f5f9afd6ded8
permissions -rw-r--r--
rtl2832u-build.patch: changes to Makefiles... w.r.t. recipe

# 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