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

511 lines
16 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.
//
// VSBPROP.CPP
//////////////////////////////////////////////////////////////////////////////
#include "philtune.h"
/*
* VsbReset()
* Inputs: UINT reset
* Outputs:
* Return: BOOL: returns TRUE, if the operation succeeds else FALSE
* Description: Hardware/software reset of VSB. A software reset would imply
* writing to the reset registers of VSB and hardware reset would be a hardware
* VSB reset.
* Author : MM
*/
NTSTATUS CDevice::VsbReset(UINT uiReset)
{
BOOL bResult = TRUE;
UCHAR ucPin, ucValue;
if (uiReset & HARDWARE_RESET)
{
if (m_BoardInfo.uiBoardID == BOARD_CONEY)
{
// DO hardware reset
// ********** VSB reset . GPIO pin 0 high - low- high
// GPIO HIGH
ucPin = GPIO_VSB_RESET_PIN ; // use as a PinMask
ucValue = GPIO_VSB_SET ;
if(!m_pGpio->WriteGPIO(&ucPin, &ucValue))
{ _DbgPrintF( DEBUGLVL_ERROR,("CReceiverFE::VsbReset: GPIO write failed"));
return STATUS_ADAPTER_HARDWARE_ERROR;
}
// GPIO LOW
ucValue = GPIO_VSB_RESET ;
if(!m_pGpio->WriteGPIO(&ucPin, &ucValue))
{ _DbgPrintF( DEBUGLVL_ERROR,("CReceiverFE::VsbReset: GPIO write failed"));
return STATUS_ADAPTER_HARDWARE_ERROR;
}
// GPIO HIGH
ucValue = GPIO_VSB_SET ;
if(!m_pGpio->WriteGPIO(&ucPin, &ucValue))
{ _DbgPrintF( DEBUGLVL_ERROR,("CReceiverFE::VsbReset: GPIO write failed"));
return STATUS_ADAPTER_HARDWARE_ERROR;
}
// ((CVSB1Demod *)(m_pDemod))->InitVSB();
m_pDemod->InitVSB();
}
else if(m_BoardInfo.uiBoardID == BOARD_CATALINA)
{
ucValue = m_ucModeInit;
// To reset VSB, pull Miscellaneous register bit 1 low,
// then high and then low again
// Some boards have resets going from 0 to 1 to 0
// and others have 1 to 0 to 1
// Bit 1 = 0
// For old board
#if 0
ucValue &= ~CATALINA_HARDWARE_RESET;
if(!m_pI2CScript->WriteSeq(CATALINA_MISC_CONTROL_REGISTER, &ucValue, 1))
return STATUS_ADAPTER_HARDWARE_ERROR;
// 10ms delay
Delay(10000);
// Bit 1 = 1
#endif
ucValue |= CATALINA_HARDWARE_RESET;
if(!m_pI2CScript->WriteSeq(CATALINA_MISC_CONTROL_REGISTER, &ucValue, 1))
return STATUS_ADAPTER_HARDWARE_ERROR;
// 50ms delay
Delay(500000);
// Bit 1 = 0
ucValue &= ~CATALINA_HARDWARE_RESET;
if(!m_pI2CScript->WriteSeq(CATALINA_MISC_CONTROL_REGISTER, &ucValue, 1))
return STATUS_ADAPTER_HARDWARE_ERROR;
// 50ms delay
Delay(500000);
#if 1
ucValue |= CATALINA_HARDWARE_RESET;
if(!m_pI2CScript->WriteSeq(CATALINA_MISC_CONTROL_REGISTER, &ucValue, 1))
return STATUS_ADAPTER_HARDWARE_ERROR;
// 50ms delay
Delay(500000);
#endif
m_ucModeInit = ucValue;
// Initialize VSB2 chip
// ((CVSB2Demod *)(m_pDemod))->InitVSB();
m_pDemod->InitVSB();
}
else
{
// For boards that don't support Hardware reset, just initialize the
// chip
m_pDemod->InitVSB();
// _DbgPrintF( DEBUGLVL_ERROR,("CReceiverFE::VsbReset: Invalid Board ID"));
// return FALSE;
}
}
else
{
if ((m_BoardInfo.uiVsbChipVersion >> 8)== VSB1)
{
if(!m_pDemod->SoftwareReset(uiReset))
return STATUS_ADAPTER_HARDWARE_ERROR;
}
else if((m_BoardInfo.uiVsbChipVersion >> 8) == VSB2)
{
if(!m_pDemod->SoftwareReset(uiReset))
return STATUS_ADAPTER_HARDWARE_ERROR;
}
else
{
_DbgPrintF( DEBUGLVL_ERROR,("CReceiverFE::VsbReset: Invalid VSB Chip version"));
return STATUS_INVALID_PARAMETER;
}
// if(!m_pDemod->SoftwareReset(uiReset))
// return FALSE;
}
// delay for 50 ms
Delay(50000);
return STATUS_SUCCESS;
}
/*
* SetVsbCapabilities()
* Inputs: PKSPROPERTY_VSB_CAP_S p_Caps - pointer to VSB capability structure
* Outputs:
* Return: BOOL: returns TRUE, if the operation succeeds else FALSE
* Description: Sets the VSB capabilities (VSB demodulator scheme - VSB-16 or
* VSB-8), VSB version, modes of operation .
* Author : MM
*/
NTSTATUS CDevice::SetVsbCapabilities(PKSPROPERTY_VSB_CAP_S p_Caps)
{
return SetBoard(p_Caps->BoardID);
}
/*
* GetVsbCapabilities()
* Inputs: PKSPROPERTY_VSB_CAP_S p_Caps - pointer to VSB capability structure
* Outputs: Filled p_Caps
* Return: BOOL: returns TRUE, if the operation succeeds else FALSE
* Description: Gets the VSB capabilities (VSB demodulator scheme - VSB-16 or
* VSB-8), VSB version, modes of operation .
* Author : MM
*/
NTSTATUS CDevice::GetVsbCapabilities(PKSPROPERTY_VSB_CAP_S p_Caps)
{
p_Caps->ChipVersion = (VSBCHIPTYPE)(m_BoardInfo.uiVsbChipVersion);
p_Caps->Modulation = VSB8;
p_Caps->BoardID = m_BoardInfo.uiBoardID;
return STATUS_SUCCESS;
}
/*
* AccessRegisterList()
* Inputs: PKSPROPERTY_VSB_REG_CTRL_S p_VsbCoeff - pointer to register
* control property set structure
* UINT uiOperation - Operation (Read or Write)
* Outputs:
* Return: NTSTATUS:
* Description: Based on the operataion requested , Reads/Writes the registers
*
* Author : MM
*/
NTSTATUS CDevice::AccessRegisterList(PKSPROPERTY_VSB_REG_CTRL_S p_RegCtrl,
UINT uiOperation)
{
RegisterType *p_Registers;
UINT uiResult = WDMMINI_NOERROR;
// Allocate memory for registers
p_Registers = (RegisterType *)(AllocateFixedMemory(sizeof(RegisterType) *
p_RegCtrl->NumRegisters));
if (p_Registers == NULL)
return STATUS_NO_MEMORY;
// Create a RegisterType array
UINT uiLength = 0;
for (UINT i = 0; i < p_RegCtrl->NumRegisters; i++)
{
p_Registers[i].uiAddress = p_RegCtrl->RegisterList[i].Address;
p_Registers[i].uiLength = p_RegCtrl->RegisterList[i].Length;
p_Registers[i].p_ucBuffer = &p_RegCtrl->Buffer[uiLength];
uiLength += p_RegCtrl->RegisterList[i].Length;
}
if(uiOperation == WRITE_REGISTERS)
{
// Set the registers in chip
uiResult = SetRegisterList(p_Registers, i);
}
else
{
// Get the registers in chip
uiResult = GetRegisterList(p_Registers, i, p_RegCtrl->RegisterType);
}
// Free memory
FreeFixedMemory(p_Registers);
return MapErrorToNTSTATUS(uiResult);
}
/*
* AccessVsbCoeffList()
* Inputs: PKSPROPERTY_VSB_COEFF_CTRL_S p_VsbCoeff - pointer to register
* coefficient property set structure
* UINT uiOperation - Operation (Read or Write)
* Outputs:
* Return: BOOL: returns TRUE, if the operation succeeds else FALSE
* Description: Based on the operataion requested , Reads/Writes the coefficients
* and puts them into the buffer
* Author : MM
*/
NTSTATUS CDevice::AccessVsbCoeffList(PKSPROPERTY_VSB_COEFF_CTRL_S p_VsbCoeff,
UINT uiOperation)
{
VsbCoeffType VsbCoeff[4];
UINT i = 0;
UINT uiLength = 0;
UINT uiResult ;
for(i = 0; i < p_VsbCoeff->NumRegisters; i++)
{
VsbCoeff[i].uiID = p_VsbCoeff->CoeffList[i].ID;
if(!m_pDemod->CoeffIDToAddress(p_VsbCoeff->CoeffList[i].ID,
&VsbCoeff[i].uiAddress, uiOperation))
return STATUS_INVALID_PARAMETER;
VsbCoeff[i].uiLength = p_VsbCoeff->CoeffList[i].Length;
VsbCoeff[i].p_ucBuffer = &p_VsbCoeff->Buffer[uiLength];
uiLength += VsbCoeff[i].uiLength;
}
if(uiOperation == WRITE_REGISTERS)
{
uiResult = m_pDemod->SetCoeff(VsbCoeff, i);
}
else
{
uiResult = m_pDemod->GetCoeff(VsbCoeff, i);
}
return MapErrorToNTSTATUS(uiResult);
}
/*
* SetVsbDiagMode()
* Inputs: ULONG ulOperationMode - Operation mode (Diagnostic/Normal)
* ULONG ulType - Diagnostic type (valid only when Operation mode is Diagnostic
* Outputs:
* Return: BOOL: returns TRUE, if the operation succeeds else FALSE
* Description: Sets the output to diagnostic or data(normal) mode
* Called in response to property ID KSPROPERTY_VSB_DIAG_CTRL by SetProperty().
* Author : Mini
*/
NTSTATUS CDevice::SetVsbDiagMode(ULONG ulOperationMode, VSBDIAGTYPE ulType)
{
BOOL bResult = TRUE;
UCHAR ucPin, ucValue;
// VSB1 does not support Diagnostic streaming
if((m_BoardInfo.uiVsbChipVersion >> 8)== VSB1)
return STATUS_NOT_IMPLEMENTED;
// If the mode is NTSC, then don't put changes into effect. These will come into
// effect next time we swith to ATSC mode
ULONG ulTunerMode;
m_pTuner->GetMode(&ulTunerMode);
if(ulTunerMode == KSPROPERTY_TUNER_MODE_TV)
{
if(ulOperationMode == VSB_OPERATION_MODE_DATA)
m_uiOutputMode = VSB_OUTPUT_MODE_NORMAL;
else
{
m_uiOutputMode = VSB_OUTPUT_MODE_DIAGNOSTIC;
// Based on type passed, set the diagnostic type in the chip
if(!m_pDemod->SetDiagMode(ulType))
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
if(ulOperationMode == VSB_OPERATION_MODE_DATA)
{
m_uiOutputMode = VSB_OUTPUT_MODE_NORMAL;
// Set VSB output mode to normal mode
if(!m_pDemod->SetOutputMode(VSB_OUTPUT_MODE_NORMAL))
return STATUS_UNSUCCESSFUL;
if(m_BoardInfo.uiBoardID == BOARD_CATALINA)
{
// Set mode bits (bits 7 - 5 corresponding to bits Mode1 Mode0 Mode2) to 000
ucValue = m_ucModeInit;
ucValue &= 0x1F;
m_pI2CScript->WriteSeq(CATALINA_MISC_CONTROL_REGISTER, &ucValue, 1);
m_ucModeInit = ucValue;
}
else{}
}
else if(ulOperationMode == VSB_OPERATION_MODE_DIAG)
{
m_uiOutputMode = VSB_OUTPUT_MODE_DIAGNOSTIC;
// Set VSB output mode to diagnostic mode
if(!m_pDemod->SetOutputMode(VSB_OUTPUT_MODE_DIAGNOSTIC))
return STATUS_UNSUCCESSFUL;
// Based on type passed, set the diagnostic type in the chip
if(!m_pDemod->SetDiagMode(ulType))
return STATUS_UNSUCCESSFUL;
ULONG ulDiagRate = m_pDemod->GetDiagSpeed(ulType);
if(m_BoardInfo.uiBoardID == BOARD_CATALINA)
{
// Set mode bits (bits 7 - 5 corresponding to bits Mode1 Mode0 Mode2)
// to 100
ucValue = m_ucModeInit;
ucValue &= 0x1F;
ucValue |= 0x80;
m_pI2CScript->WriteSeq(CATALINA_MISC_CONTROL_REGISTER, &ucValue, 1);
m_ucModeInit = ucValue;
// MM; Commented out now. Once I find a way of sending IRPs to apture driver,
//this can be restored
// SendCurrentDiagInfo(ulDiagRate, DIAG_FIELD);
}
else{}
}
else
{
// Invalid operation
_DbgPrintF( DEBUGLVL_ERROR,("CReceiverFE::VsbReset: Invalid Option"));
return STATUS_INVALID_PARAMETER;
}
return STATUS_SUCCESS;
}
/*
* GetVsbDiagMode()
* Inputs: ULONG *p_ulOperationMode - pointer to Operation mode (Diagnostic/Normal)
* ULONG *p_ulType - pointer to Diagnostic type (valid only when Operation mode is Diagnostic
* Outputs: Operation mode and diagnostic type
* Return: NTSTATUS: returns STATUS_SUCCESS, if the operation succeeds
* STATUS_NOT_IMPLEMENTED if its VSB2
* STATUS_UNSUCCESSFUL if the operation didn't succeed
* Description: Gets the diagnostic type and diagnostic or data(normal) mode
* Author : MM
*/
NTSTATUS CDevice::GetVsbDiagMode(ULONG *p_ulOperationMode, ULONG *p_ulType)
{
UINT uiOutputMode;
// VSB1 does not support Diagnostic streaming
if((m_BoardInfo.uiVsbChipVersion >> 8) == VSB1)
return STATUS_NOT_IMPLEMENTED;
if(!m_pDemod->GetOutputMode(&uiOutputMode))
return STATUS_UNSUCCESSFUL;
if(!m_pDemod->GetDiagMode(p_ulType))
return STATUS_UNSUCCESSFUL;
if(uiOutputMode == VSB_OUTPUT_MODE_DIAGNOSTIC)
*p_ulOperationMode = VSB_OPERATION_MODE_DIAG;
else if(uiOutputMode == VSB_OUTPUT_MODE_NORMAL)
*p_ulOperationMode = VSB_OPERATION_MODE_DATA;
else
*p_ulOperationMode = VSB_OPERATION_MODE_INVALID;
return STATUS_SUCCESS;
}
/*
* VsbQuality()
* Inputs: UINT quality
* Outputs:
* Return: NTSTATUS: returns STATUS_SUCCESS, if the operation succeeds
* else STATUS_NOT_IMPLEMENTED if its VSB2
* Description: Enables/Disables quality check and improvement routines. Currently
* it only enables or disables chip hang in VSB1. But can be extended later if necessary
* Author : MM
*/
NTSTATUS CDevice::VsbQuality(UINT uiQu)
{
// This property set is only supported for VSB1
if ((m_BoardInfo.uiVsbChipVersion >> 8) == VSB1)
{
if(uiQu & VSB_HANG_CHECK_ENABLE)
m_bHangCheckFlag = TRUE;
else
m_bHangCheckFlag = FALSE;
return STATUS_SUCCESS;
}
else
return STATUS_NOT_IMPLEMENTED;
}
/*
* SetRegList()
* Inputs: RegListType *p_Registers - pointer to register list structure
* UINT uiNumRegisters : number of registers
* Outputs:
* Return: BOOL: returns TRUE, if the operation succeeds else FALSE
* Description: Writes to registers with the values given in the list.
* Called in response to property ID KSPROPERTY_VSB_ REG_CTRL by SetProperty().
* Author : Mini
*/
UINT CDevice::SetRegisterList(RegisterType *p_Registers, UINT uiNumRegisters)
{
return (m_pDemod->SetRegisterList(p_Registers, uiNumRegisters));
}
/*
* GetRegList()
* Inputs: RegListType *p_reg - pointer to register list structure
* UINT uiNumRegisters : number of registers
* UINT uiRegisterType : Type of Regsiter (Control or Status)
* Outputs: Filled p_reg
* Return: BOOL: returns TRUE, if the operation succeeds else FALSE
* Description: Reads from registers given in the list and fills their values back
* into the list. This is a shadow operation as the control registers cannot be
* read.
* Called in response to property ID KSPROPERTY_VSB_REG_CTRL by GetProperty().
* Author : Mini
*/
UINT CDevice::GetRegisterList(RegisterType *p_Registers, UINT uiNumRegisters,
UINT uiRegisterType)
{
return (m_pDemod->GetRegisterList(p_Registers, uiNumRegisters, uiRegisterType));
}
/*
* MapErrorToNTSTATUS()
* Maps the WDMMINI error code to NTSTATUS status code
*/
NTSTATUS CDevice::MapErrorToNTSTATUS(UINT uiErr)
{
if(uiErr == WDMMINI_NOERROR)
return STATUS_SUCCESS;
else if((uiErr == WDMMINI_HARDWAREFAILURE) ||
(uiErr == WDMMINI_NOHARDWARE) ||
(uiErr == WDMMINI_ERROR_NOI2CPROVIDER) ||
(uiErr == WDMMINI_ERROR_NOGPIOPROVIDER) ||
(uiErr == WDMMINI_UNKNOWNHARDWARE))
return STATUS_ADAPTER_HARDWARE_ERROR;
else if(uiErr == WDMMINI_INVALIDPARAM)
return STATUS_INVALID_PARAMETER;
else if(uiErr == WDMMINI_ERROR_MEMORYALLOCATION)
return STATUS_NO_MEMORY;
else if(uiErr == WDMMINI_ERROR_REGISTRY)
return STATUS_NO_MATCH;
else
return STATUS_UNSUCCESSFUL;
}