windows-nt/Source/XPSP1/NT/drivers/wdm/bda/samples/mauitune/tuner.cpp
2020-09-26 16:20:57 +08:00

782 lines
23 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// (C) Philips Semiconductors-CSU and Microsoft 1999
// All rights are reserved. Reproduction in whole or in part is prohibited
// without the written consent of the copyright owner.
//
// Philips reserves the right to make changes without notice at any time.
// Philips makes no warranty, expressed, implied or statutory, including but
// not limited to any implied warranty of merchantibility or fitness for any
// particular purpose, or that the use will not infringe any third party
// patent, copyright or trademark. Philips must not be liable for any loss
// or damage arising from its use.
//
// TUNER.CPP
//////////////////////////////////////////////////////////////////////////////
#include "philtune.h"
/*
* CTuner()
* Input :
* Output: TRUE - if initialization data can be written to I2C
* FALSE - if there is an I2C error
* Description: CTuner Constructor.
*/
CTuner::CTuner(CI2CScript *p_I2CScript, BoardInfoType *p_BoardInfo, NTSTATUS *pStatus)
{
m_pI2CScript = p_I2CScript;
m_ucTunerAddress = TUNER_I2C_ADDRESS;
m_ulInput = 0L; // unknown input or the only one
m_ulCurrentFrequency = 0L; // unknown tuning frequency
m_ulMode = 0;
m_ulPrevMode = 0;
m_TunerID = TD1536;
m_ulPreviousFrequency = 0L;
//m_FrequencyParam.ulCurrentCFrequency = 0L;
LONG lPLLOffset;
BOOL bBusyStatus;
//GetPLLOffsetBusyStatus(&lPLLOffset, &bBusyStatus);
m_uiBoardID = 0;
if(p_BoardInfo != NULL)
{
NTSTATUS status;
status = SetCapabilities(p_BoardInfo);
if(pStatus != NULL)
*pStatus = status;
}
}
/*
* ~CTuner()
* Input :
* Output:
* Description: CTuner Destructor.
*/
CTuner::~CTuner()
{
}
/*
* SetCapabilities()
* Purpose : Sets the capabilities based upon the Tuner Id
*
* Inputs : UINT tuner : Tuner Id
*
* Outputs : returns TRUE, if there is a supported Tuner Id specified;
*
* Author : MM
*/
NTSTATUS
CTuner::SetCapabilities(BoardInfoType *p_BoardInfo)
{
NTSTATUS nStatus = STATUS_SUCCESS;
m_TunerID = (TunerTypes)(p_BoardInfo->uiTunerID);
m_ucTunerAddress = p_BoardInfo->ucTunerAddress;
m_uiBoardID = p_BoardInfo->uiBoardID;
// Note:
// If mode is KSPROPERTY_TUNER_MODE_ATSC, then the IF is
// 43.75MHz, else it is 44MHz. But as the frequency
// being passed (ulFrequency) is the Video Signal freq,
// the calculation should take into consideration that the video signal
// is 1.75 MHz from the centre of the band. This 1.75MHz should be
// added to the actual IF hence for ATSC IF = 43.75 + 1.75 = 45.5MHz
// and NTSC IF = 44 + 1.75 = 45.75MHz
// Currently , supporting only TD1536, other tune support can be added later
// as necessary
switch(m_TunerID)
{
case TD1536: // Digital Tuner
{
// Check to determine if it is a single input or a dual input
// tuner
ULONG inputs = 1;
GetNumberOfInputs(&inputs);
int i = 0;
if(p_BoardInfo->ulSupportedModes & KSPROPERTY_TUNER_MODE_TV)
{
// Set mode capabilities for TV mode
m_ModeCaps[i].ModeCaps.ulMode = KSPROPERTY_TUNER_MODE_TV;
m_ModeCaps[i].ModeCaps.ulNumberOfInputs = inputs; //2;
m_ModeCaps[i].ModeCaps.ulMinFrequency = 55250000L;
m_ModeCaps[i].ModeCaps.ulMaxFrequency = 801250000L;
m_ModeCaps[i].ModeCaps.ulStrategy = KS_TUNER_STRATEGY_PLL;
m_ModeCaps[i].ulIntermediateFrequency = 45750000L;
m_ModeCaps[i].ModeCaps.ulStandardsSupported = KS_AnalogVideo_NTSC_M;
m_ModeCaps[i].ulNumberOfStandards = 1;
m_ModeCaps[i].ModeCaps.ulTuningGranularity = 62500L;
m_ModeCaps[i].ModeCaps.ulSettlingTime = 150; // 150 ms
i++;
}
if(p_BoardInfo->ulSupportedModes & KSPROPERTY_TUNER_MODE_ATSC)
{
// Set mode capabilities for ATSC mode
m_ModeCaps[i].ModeCaps.ulMode = KSPROPERTY_TUNER_MODE_ATSC;
m_ModeCaps[i].ModeCaps.ulNumberOfInputs = inputs; //2;
m_ModeCaps[i].ModeCaps.ulMinFrequency = 55250000L;
m_ModeCaps[i].ModeCaps.ulMaxFrequency = 801250000L;
m_ModeCaps[i].ModeCaps.ulStrategy =
KS_TUNER_STRATEGY_DRIVER_TUNES;
if((m_uiBoardID == BOARD_CATALINA) ||
(m_uiBoardID == BOARD_CORFU))
m_ModeCaps[i].ulIntermediateFrequency = 45750000L;
else
m_ModeCaps[i].ulIntermediateFrequency = 45500000L;
m_ModeCaps[i].ModeCaps.ulStandardsSupported = KS_AnalogVideo_NTSC_M;
m_ModeCaps[i].ulNumberOfStandards = 0;
m_ModeCaps[i].ModeCaps.ulTuningGranularity = 62500L;
m_ModeCaps[i].ModeCaps.ulSettlingTime = 800; // 800ms
i++;
}
m_ulSupportedModes = p_BoardInfo->ulSupportedModes;
m_ulNumSupportedModes = p_BoardInfo->ulNumSupportedModes;
m_ucTunerAddress = TUNER_I2C_ADDRESS;
_DbgPrintF( DEBUGLVL_VERBOSE,("CDevice::Supported Modes = %x \n", m_ulSupportedModes));
}
break;
default:
return STATUS_INVALID_PARAMETER;
}
SetMode(KSPROPERTY_TUNER_MODE_ATSC);
m_ulVideoStandard = KS_AnalogVideo_NTSC_M;
return nStatus;
}
/*
* GetModeCapabilities()
* Inputs: TunerModeCapsType *p_TunerModeCaps : pointer to
* mode capability structure of the tuner
* Outputs: Filled TunerModeCapsType structure
* Returns: BOOL: returns TRUE, if the operation succeeds else FALSE
* Description: Returns the mode capabilities of tuner for a particluar mode.
*/
NTSTATUS
CTuner::GetModeCapabilities(TunerModeCapsType *p_TunerModeCaps)
{
ULONG ulOperationMode = p_TunerModeCaps->ulMode;
_DbgPrintF( DEBUGLVL_VERBOSE,("CTuner::GetTunerModeCapbilities Mode = %x Mode in obj %x\n",
ulOperationMode, m_ulMode ));
// QF:This is a work-around, as the mode passed by the filter the 1st time
// is not correct. Will have to be removed later.
p_TunerModeCaps->ulMode = m_ulMode;
ulOperationMode = m_ulMode;
if (!(ulOperationMode & m_ulSupportedModes))
{
// TRAP;
return STATUS_INVALID_PARAMETER;
}
// There is support for TVTuner at this time only.
// It will be enchanced later on to support FM Tuner as well.
for(ULONG i = 0; i < m_ulNumSupportedModes; i++)
{
if(ulOperationMode == m_ModeCaps[m_ulModeCapIndex].ModeCaps.ulMode)
break;
}
MemoryCopy(&p_TunerModeCaps->ulMode, &m_ModeCaps[m_ulModeCapIndex].ModeCaps,
sizeof(TunerModeCapsType));
return STATUS_SUCCESS;
}
/*
* SetMode()
* Inputs: ULONG ulMode : an operation mode required to be set
* Outputs:
* Returns: UINT: 0 - if mode is not supported
* 1 - if mode is same as previous mode
* 2 - if new mode has been set
* Description: Set TV mode
*/
NTSTATUS
CTuner::SetMode(ULONG ulMode)
{
ULONG i;
// Check if mod eis supported
if(ulMode & m_ulSupportedModes)
{
m_ulPrevMode = m_ulMode;
// Change mode only if it is different from the previous mode
if(ulMode != m_ulMode)
{
// Check if the mode supported is part of the mode capability
// structure array for the tuner. If it is , get the index into the
// array for the given mode and change the mode.
for(i = 0; i < m_ulNumSupportedModes; i++)
{
if(m_ModeCaps[i].ModeCaps.ulMode == ulMode)
{
m_ulModeCapIndex = i;
break;
}
}
if(i == m_ulNumSupportedModes)
{
_DbgPrintF( DEBUGLVL_ERROR,("CTuner::SetMode: Couldn't find mode in capability array\n"));
return STATUS_INVALID_PARAMETER;
}
else
m_ulMode = ulMode;
}
return STATUS_SUCCESS;
}
else
{
_DbgPrintF( DEBUGLVL_ERROR,("CTuner: Mode not supported : %x %x \n", ulMode, m_ulSupportedModes));
return STATUS_INVALID_PARAMETER;
}
}
/*
* GetMode()
* Inputs: ULONG *p_ulMode : pointer to operation mode that has to be read
* Outputs: operation mode
* Returns:
* Description: Get Mode (TV/ATSC)
*/
void CTuner::GetMode(ULONG *p_ulMode)
{
*p_ulMode = m_ulMode ;
}
/*
* SetVideoStandard()
* Inputs: ULONG ulStandard : a standard required to be set
* Outputs:
* Returns: NTSTATUS: STATUS_INVALID_PARAMETER - if standard is not supported
* STATUS_SUCCESS - if operation succeeded
* Description: Set the TV video standard requested.
*/
NTSTATUS
CTuner::SetVideoStandard(ULONG ulStandard)
{
if(ulStandard &
m_ModeCaps[m_ulModeCapIndex].ModeCaps.ulStandardsSupported)
{
if(ulStandard != m_ulVideoStandard)
{
m_ulVideoStandard = ulStandard;
}
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
}
/*
* GetVideoStandard()
* Inputs: ULONG *p_ulStandard : pointer to standard required to be filled
* Outputs: standard
* Returns:
* Description: Get the TV video standard requested.
*/
void CTuner::GetVideoStandard(ULONG *p_ulStandard)
{
*p_ulStandard = m_ulVideoStandard;
}
/*
* GetPLLOffsetBusyStatus()
* Purpose: Returns tuner Busy status and PLLOffset, if the tuner is not busy
* The function reads the hardware in order to accomplish the task
* The operation might be carried on either synchronously or asynchronously
* Inputs : PLONG plPLLOffset : a pointer to write a PLLOffset value
* PBOOL pbBusyStatus : a pointer to write a Busy status
*
* Outputs: BOOL : returns TRUE, if the operation succeded
* Author : MM
*/
NTSTATUS
CTuner::GetPLLOffsetBusyStatus(PLONG plPLLOffset, PBOOL pbBusyStatus)
{
UCHAR ucI2CValue = 0;
NTSTATUS nResult = STATUS_SUCCESS;
if( Read(&ucI2CValue, 1, 0) != WDMMINI_NOERROR)
nResult = STATUS_ADAPTER_HARDWARE_ERROR;
if (nResult == STATUS_SUCCESS)
{
// bit 6 - PLL locked indicator
*pbBusyStatus = !((BOOL)(ucI2CValue & 0x40));
if (!(* pbBusyStatus))
{
ucI2CValue &= 0x07; // only 3 LSBits are PLLOffset
// let's map the result into MS defined values
// from -2 to 2
*plPLLOffset = ucI2CValue - 2;
}
}
// Read only busy bit for TD1536 as the tuner does not provide
// PLL offset information.
if (m_TunerID == TD1536)
{
*plPLLOffset = 0;
// *pbBusyStatus = 0;
// return TRUE;
}
return nResult;
}
/*
* SetFrequency()
* Purpose: Sets a new Tuner frequency
* Inputs : ULONG ulFrequency : a frequency required to be set
*
* Outputs: BOOL : returns TRUE, if the operation succeded
* Author : MM
*/
BOOL CTuner::SetFrequency(ULONG ulFrequency)
{
ASSERT(m_ModeCaps[m_ulModeCapIndex].ulIntermediateFrequency != 0L);
// Change frequency
if (!ChangeFrequency(ulFrequency))
return FALSE;
m_ulCurrentFrequency = ulFrequency;
if (m_ulPreviousFrequency != ulFrequency)
{
// Mini: Delay for 400ms to let the tuner settle to a tuned state and to let
// the VSB acquire equalizer lock
if (m_ulMode == KSPROPERTY_TUNER_MODE_ATSC)
Delay(400000);
}
_DbgPrintF( DEBUGLVL_VERBOSE,("CTuner::SetTunerFrequency(): PrevFreq = %d CurrentFreq = %d\n",
m_ulPreviousFrequency,m_ulCurrentFrequency));
m_ulPreviousFrequency = ulFrequency;
return TRUE;
}
/*
* GetFrequency()
* Purpose: Gets the Tuner frequency
* Inputs : ULONG *p_ulFrequency : a frequency required
*
* Outputs:
* Author : MM
*/
void CTuner::GetFrequency(ULONG *p_ulFrequency)
{
*p_ulFrequency = m_ulCurrentFrequency;
}
/*
* ChangeFrequency()
* Input : frequency
* Output: TRUE if able to to tune to the frequency
* FALSE if unable to tune to the frequency
* Description: Change the frequency of tuner to that specified
*/
BOOL CTuner::ChangeFrequency(ULONG ulFrequency)
{
ULONG ulFrequenceDivider;
USHORT usControlCode;
UCHAR ucI2CBuffer[6];
I2CPacket i2cPacket;
BOOL bResult;
ULONG IF = m_ModeCaps[m_ulModeCapIndex].ulIntermediateFrequency;
// Set the video carrier frequency by controlling the programmable divider
// N = (16 * (FreqRF + FreqIntermediate)) / 1000000
_DbgPrintF( DEBUGLVL_VERBOSE,("CTuner: ulFrequency = %x \n", ulFrequency));
ulFrequenceDivider = ulFrequency + IF;
_DbgPrintF( DEBUGLVL_VERBOSE,("CTuner::ChangeFrequency: IF = %d\n", IF));
ulFrequenceDivider /= (1000000 / 16); // divide by 62,500
usControlCode = GetControlCode(ulFrequenceDivider);
if(!usControlCode)
return(FALSE);
// _DbgPrintF( DEBUGLVL_VERBOSE,("PhilTune: ulFrequencyDivider before %x \n", ulFrequenceDivider));
// _DbgPrintF( DEBUGLVL_VERBOSE,("PhilTune: ulFrequencyDivider after %x \n", ulFrequenceDivider));
ucI2CBuffer[0] = 0xCE;
ucI2CBuffer[1] = (UCHAR)usControlCode;
ucI2CBuffer[2] = (UCHAR)(ulFrequenceDivider >> 8);
ucI2CBuffer[3] = (UCHAR)ulFrequenceDivider;
ucI2CBuffer[4] = (UCHAR)(usControlCode >> 8);
ucI2CBuffer[5] = (UCHAR)usControlCode;
_DbgPrintF( DEBUGLVL_TERSE,("\n CPhilipsWDMTuner:Tuner Control Code = %x %x %x %x \n",
ucI2CBuffer[0], ucI2CBuffer[1], ucI2CBuffer[2], ucI2CBuffer[3]));
/*i2cPacket.uchChipAddress = m_uchTunerI2CAddress;
i2cPacket.cbReadCount = 0;
i2cPacket.cbWriteCount = 4;
i2cPacket.puchReadBuffer = NULL;
i2cPacket.puchWriteBuffer = auchI2CBuffer;
i2cPacket.usFlags = 0;
bResult = m_pI2CScript->PerformI2CPacketOperation(&i2cPacket);
return bResult;
*/
if(Write(ucI2CBuffer, sizeof(ucI2CBuffer), 0) == WDMMINI_NOERROR)
return TRUE;
else
return FALSE;
}
BOOL CTuner::TweakChannel(LONG lTweak, int iTweakReference)
{
// Should change the routine later to support tweak reference
// if tweak reference is TUNER_ABSOLUTE_TWEAK, then tweaking is about the centre
// frequency else if tweak reference is TUNER_RELATIVE_TWEAK, then tweaking is about
// the current frequency
LONG lTweakFrq = (lTweak * 62500) + m_ulCurrentFrequency;
if (lTweakFrq > 0)
if (!ChangeFrequency((ULONG)lTweakFrq))
return FALSE;
else
return FALSE;
m_ulCurrentFrequency = (ULONG)lTweakFrq;
return TRUE;
}
/*
* GetNumberOfInputs()
* Input : pointer to ULONG variable which will be filled with number of inputs
* Output: TRUE - if the number of inputs can be determined
* FALSE - if there is an I2C error & number of inputs can't be determined
* Description: Determine the number of tuner inputs
*/
BOOL CTuner::GetNumberOfInputs(ULONG *p_ulInputs)
{
UCHAR ucMode = 0;
_DbgPrintF( DEBUGLVL_VERBOSE,("CTuner::GetNumberOfInputs: Inside\n"));
if(m_uiBoardID == BOARD_CONEY)
{
if(!m_pI2CScript->ReadSeq(CONEY_I2C_PARALLEL_PORT, &ucMode, 1))
{
_DbgPrintF( DEBUGLVL_ERROR,("CTuner::GetNumberOfInputs: Error\n"));
return(FALSE);
}
// If the mode bit 0 = 1,then its a dual input tuner , else its a single input tuner
if ((ucMode & 0x1) == 0)
*p_ulInputs = 1;
else
*p_ulInputs = 2;
}
else //if(m_uiBoardID == BOARD_CATALINA)
*p_ulInputs = 1;
// else
// {
// *p_ulInputs = 1;
// _DbgPrintF( DEBUGLVL_ERROR,("CTuner::GetNumberOfInputs:Invalid Board ID\n"));
// }
m_uiNumInputs = *p_ulInputs;
_DbgPrintF( DEBUGLVL_VERBOSE,("CTuner::GetNumberOfInputs: Number of input pins = %d Mode = %x\n",
*p_ulInputs, ucMode));
return(TRUE);
}
/*
* GetInput()
* Purpose: Gets the current tuner inputs as an active one
* Inputs : ULONG nInput : input number required to be set as an active
* (begins from 0)
*
* Outputs: BOOL : returns TRUE, if the operation succeded
* Author : MM
*/
BOOL CTuner::GetInput(ULONG *p_ulInput)
{
*p_ulInput = m_ulInput;
return(TRUE);
}
/*
* SetInput()
* Purpose: Sets one of the possible Tuner inputs as an active one
* Inputs : ULONG nInput : input number required to be set as an active
* (begins from 0)
*
* Returns: UINT: 0 - if tuner input is out of range
* 1 - if tuner input is same as previous tuner input
* 2 - if new tuner input has been set
* Author : MM
*/
UINT CTuner::SetInput(ULONG ulInput)
{
if(ulInput < m_ModeCaps[m_ulModeCapIndex].ModeCaps.ulNumberOfInputs)
{
if(ulInput != m_ulInput)
m_ulInput = ulInput;
else
return 1;
return 2;
}
else
return 0;
}
/*
* GetControlCode()
* Purpose: Determines the Tuner control code to be send to tuner with a new frequency value
*
* Inputs : ULONG ulFrequencyDivider : new frequency divider
*
* Outputs: USHORT : value, the tuner should be programmed, when the new frequency is set
* id the is no valid uiTunerId is passed as paramter, 0 is returned
* Author : MM
*/
USHORT CTuner::GetControlCode(ULONG ulFrequencyDivider)
{
USHORT usLowBandFrequencyHigh, usMiddleBandFrequencyHigh;
USHORT usLowBandControl, usMiddleBandControl, usHighBandControl;
USHORT usControlCode = 0;
usLowBandFrequencyHigh = kUpperLowBand;
usMiddleBandFrequencyHigh = kUpperMidBand;
usLowBandControl = kLowBand;
usMiddleBandControl = kMidBand;
usHighBandControl = kHighBand;
switch(m_TunerID)
{
case TD1536:
{
if (m_ulMode != KSPROPERTY_TUNER_MODE_ATSC)
{
usLowBandControl = kLowBand_1536_NTSC_A;
usMiddleBandControl = kMidBand_1536_NTSC_A;
usHighBandControl = kHighBand_1536_NTSC_A;
if(m_uiBoardID == BOARD_CORONADO)
{
usLowBandControl &= 0xffbf;
usMiddleBandControl &= 0xffbf;
usHighBandControl &= 0xffbf;
}
}
else
{
usLowBandControl = kLowBand_1536_NTSC_D;
usMiddleBandControl = kMidBand_1536_NTSC_D;
usHighBandControl = kHighBand_1536_NTSC_D;
if(m_uiBoardID == BOARD_CORONADO)
{
usLowBandControl |= 0x40;
usMiddleBandControl |= 0x40;
usHighBandControl |= 0x40;
}
}
// Based on the tuner input modify control word
// Test
ULONG ulInp = m_ulInput; //1
if (ulInp == 1)
{
usLowBandControl |= 0x1;
usMiddleBandControl |= 0x1;
usHighBandControl |= 0x1;
}
else
{
usLowBandControl &= 0xfffe;
usMiddleBandControl &= 0xfffe;
usHighBandControl &= 0xfffe;
}
_DbgPrintF( DEBUGLVL_VERBOSE,("CPhilipsWDMTuner::GetControlCode(): LBand = %x, MBand = %x, HBand = %x\n", usLowBandControl,
usMiddleBandControl, usHighBandControl));
}
break;
default :
return(usControlCode);
}
if(ulFrequencyDivider <= (ULONG)usLowBandFrequencyHigh)
usControlCode = usLowBandControl;
else
{
if(ulFrequencyDivider <= (ULONG)usMiddleBandFrequencyHigh)
usControlCode = usMiddleBandControl;
else
usControlCode = usHighBandControl;
}
return(usControlCode);
}
/*
* Write()
* Input:UCHAR *p_ucBuffer - buffer to be written
* int uiNumReg - Number of registers to be written
* UINT uiStartAddr - start address
* Output : UINT - Error code
* Description: Write data to chip
*/
UINT CTuner::Write(UCHAR *p_ucBuffer, UINT uiNumReg, UINT uiStartAddr)
{
UINT uiResult = WDMMINI_NOERROR;
// The present versions of the chip do not support sub-addressing, hence
// uiStartAddr is not used.
// write to chip
//$REVIEW - Should change function decl to make uiNumReg be USHORT - TCP
if(!m_pI2CScript->WriteSeq(m_ucTunerAddress, p_ucBuffer, (USHORT) uiNumReg))
uiResult = WDMMINI_HARDWAREFAILURE;
return uiResult;
}
/*
* Read()
* Input:UCHAR *p_ucBuffer - buffer to be filled
* int uiNumReg - Number of registers to be read
* UINT uiStartAddr - start address
* Output : UINT - Error code
* Description: Read data from chip
*/
UINT CTuner::Read(UCHAR *p_ucBuffer, UINT uiNumReg, UINT uiStartAddr)
{
UINT uiResult = WDMMINI_NOERROR;
// The present versions of the chip do not support sub-addressing, hence
// uiStartAddr is not used.
// write to chip
//$REVIEW - Should change function decl to make uiNumReg be USHORT - TCP
if(!m_pI2CScript->ReadSeq(m_ucTunerAddress, p_ucBuffer, (USHORT) uiNumReg))
uiResult = WDMMINI_HARDWAREFAILURE;
return uiResult;
}
#if 0
/*
* operator new
* Purpose: CTuner class overrides operator new.
*
* Inputs : UINT uiSize : size of the object to be placed
*
* Outputs: PVOID : pointer of the CTuner class object
* Author : MM
*/
PVOID CTuner::operator new(UINT uiSize)
{
if (uiSize != sizeof(CTuner))
{
_DbgPrintF( DEBUGLVL_ERROR,("CTuner: operator new() fails\n"));
return(NULL);
}
return (AllocateFixedMemory(uiSize));
}
/*
* operator delete
* Purpose: CTuner class overrides operator delete
*
* Inputs : PVOID p_Buffer : pointer to object being deleted
*
* Outputs:
* Author : MM
*/
void CTuner::operator delete(PVOID p_Object)
{
if(p_Object != NULL)
FreeFixedMemory(p_Object);
_DbgPrintF( DEBUGLVL_VERBOSE,("CTuner: operator delete() succeeds\n"));
}
/*
* SetFrequencyParam()
* Purpose: Sets the frequency parameters for the tuner
* Inputs : TunerFrequencyType *p_Frequency : a frequency required to be set
*
* Returns: UINT: 0 - if frequency is out of range or frequency setting fails
* 1 - if frequency is same as previous frequency
* 2 - if new frequency has been set
* Author : MM
*/
UINT CTuner::SetFrequencyParam(TunerFrequencyType *p_Frequency)
{
ULONG ulFrequency = p_Frequency->ulCurrentCFrequency;
if((ulFrequency < m_ModeCaps[m_ulModeCapIndex].ModeCaps.ulMinFrequency) ||
(ulFrequency > m_ModeCaps[m_ulModeCapIndex].ModeCaps.ulMaxFrequency))
return 0;
// If the tuning frequency has changed or the tuner mode has changed ,
// then change the tuner frequency
if((ulFrequency != m_ulCurrentFrequency) ||
(m_ulPrevMode != m_ulMode))
{
// Set the tuner frequency
if(!SetFrequency(ulFrequency))
return 0;
// Update the CTuner's frequency parameters
MemoryCopy(&m_FrequencyParam, p_Frequency, sizeof(TunerFrequencyType));
return 2;
}
return 1;
}
/*
* GetFrequencyParam()
* Purpose: Gets the frequency parameters for the tuner
* Inputs : TunerFrequencyType *p_Frequency : a frequency required to be filled
* Output:
* Author : MM
*/
void CTuner::GetFrequencyParam(TunerFrequencyType *p_Frequency)
{
MemoryCopy(p_Frequency, &m_FrequencyParam, sizeof(TunerFrequencyType));
return;
}
#endif