|
|
//==========================================================================;
//
// WDMTuner.CPP
// WDM Tuner MiniDriver.
// Philips Tuner.
// CATIWDMTuner class implementation.
// Copyright (c) 1996 - 1997 ATI Technologies Inc. All Rights Reserved.
//
// $Date: 10 Aug 1999 16:15:44 $
// $Revision: 1.6 $
// $Author: KLEBANOV $
//
//==========================================================================;
extern "C" { #include "strmini.h"
#include "ksmedia.h"
#include "wdmdebug.h"
}
#include "atitunep.h"
#include "wdmdrv.h"
#include "aticonfg.h"
#define ATI_TVAUDIO_SUPPORT
/*^^*
* AdapterCompleteInitialization() * Purpose : Called when SRB_COMPLETE_UNINITIALIZATION SRB is received. * * Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb * * Outputs : BOOL : returns TRUE * Author : IKLEBANOV *^^*/ NTSTATUS CATIWDMTuner::AdapterCompleteInitialization( PHW_STREAM_REQUEST_BLOCK pSrb) { PADAPTER_DATA_EXTENSION pPrivateData = ( PADAPTER_DATA_EXTENSION)( pSrb->HwDeviceExtension); PDEVICE_OBJECT pDeviceObject = pPrivateData->PhysicalDeviceObject; KSPIN_MEDIUM mediumKSPin; NTSTATUS ntStatus; UINT nIndex; HANDLE hFolder; ULONG ulInstance;
ENSURE { nIndex = 0;
switch( m_ulNumberOfPins) { case 2: // TVTuner with TVAudio
::RtlCopyMemory( &m_pTVTunerPinsMediumInfo[nIndex ++], &ATITVTunerVideoOutMedium, sizeof( KSPIN_MEDIUM)); #ifdef ATI_TVAUDIO_SUPPORT
#pragma message ("\n!!! PAY ATTENTION: Tuner PinMedium is compiled with TVAudio support !!!\n")
::RtlCopyMemory( &m_pTVTunerPinsMediumInfo[nIndex], &ATITVTunerTVAudioOutMedium, sizeof( KSPIN_MEDIUM)); #else
#pragma message ("\n!!! PAY ATTENTION: Tuner PinMedium is compiled without TVAudio support !!!\n")
::RtlCopyMemory( &m_pTVTunerPinsMediumInfo[nIndex ++], &ATIXBarAudioTunerInMedium, sizeof( KSPIN_MEDIUM)); #endif
break;
case 3: // TVTuner with TVAudio with separate FM Audio output
::RtlCopyMemory( &m_pTVTunerPinsMediumInfo[nIndex ++], &ATITVTunerVideoOutMedium, sizeof( KSPIN_MEDIUM)); #ifdef ATI_TVAUDIO_SUPPORT
::RtlCopyMemory( &m_pTVTunerPinsMediumInfo[nIndex ++], &ATITVTunerTVAudioOutMedium, sizeof( KSPIN_MEDIUM)); #else
::RtlCopyMemory( &m_pTVTunerPinsMediumInfo[nIndex ++], &ATIXBarAudioTunerInMedium, sizeof( KSPIN_MEDIUM)); #endif
case 1: // it can be FM Tuner only.
::RtlCopyMemory( &m_pTVTunerPinsMediumInfo[nIndex], &ATITVTunerRadioAudioOutMedium, sizeof( KSPIN_MEDIUM)); break; }
ulInstance = ::GetDriverInstanceNumber( pDeviceObject); hFolder = ::OpenRegistryFolder( pDeviceObject, UNICODE_WDM_REG_PIN_MEDIUMS);
for( nIndex = 0; nIndex < m_ulNumberOfPins; nIndex ++) { if( ::ReadPinMediumFromRegistryFolder( hFolder, nIndex, &mediumKSPin)) ::RtlCopyMemory( &m_pTVTunerPinsMediumInfo[nIndex], &mediumKSPin, sizeof( KSPIN_MEDIUM)); m_pTVTunerPinsMediumInfo[nIndex].Id = ulInstance;
// all the possible pins exposed are the outputs
m_pTVTunerPinsDirectionInfo[nIndex] = TRUE; }
if( hFolder != NULL) ::ZwClose( hFolder);
ntStatus = StreamClassRegisterFilterWithNoKSPins( \ pDeviceObject , // IN PDEVICE_OBJECT DeviceObject,
&KSCATEGORY_TVTUNER, // IN GUID * InterfaceClassGUID
m_ulNumberOfPins, // IN ULONG PinCount,
m_pTVTunerPinsDirectionInfo, // IN ULONG * Flags,
m_pTVTunerPinsMediumInfo, // IN KSPIN_MEDIUM * MediumList,
NULL); // IN GUID * CategoryList
if( !NT_SUCCESS( ntStatus)) FAIL;
OutputDebugInfo(( "CATIWDMTuner:AdapterCompleteInitialization() exit\n"));
} END_ENSURE;
if( !NT_SUCCESS( ntStatus)) OutputDebugError(( "CATIWDMTuner:AdapterCompleteInitialization() ntStatus=%x\n", ntStatus));
return( ntStatus); }
/*^^*
* AdapterUnInitialize() * Purpose : Called when SRB_UNINITIALIZE_DEVICE SRB is received. * * Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb * * Outputs : BOOL : returns TRUE * Author : IKLEBANOV *^^*/ BOOL CATIWDMTuner::AdapterUnInitialize( PHW_STREAM_REQUEST_BLOCK pSrb) {
OutputDebugTrace(( "CATIWDMTuner:AdapterUnInitialize()\n"));
// just deallocate the any memory was allocated at run-time
if( m_pTVTunerPinsMediumInfo != NULL) { ::ExFreePool( m_pTVTunerPinsMediumInfo); m_pTVTunerPinsMediumInfo = NULL; }
if( m_pTVTunerPinsDirectionInfo != NULL) { ::ExFreePool( m_pTVTunerPinsDirectionInfo); m_pTVTunerPinsDirectionInfo = NULL; }
pSrb->Status = STATUS_SUCCESS; return( TRUE); }
/*^^*
* AdapterGetStreamInfo() * Purpose : fills in HW_STREAM_HEADER for StreamClass driver * * Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb * * Outputs : BOOL : returns TRUE * Author : IKLEBANOV *^^*/ BOOL CATIWDMTuner::AdapterGetStreamInfo( PHW_STREAM_REQUEST_BLOCK pSrb) { // pick up the pointer to the stream header data structure
PHW_STREAM_HEADER pStreamHeader = ( PHW_STREAM_HEADER)&( pSrb->CommandData.StreamBuffer->StreamHeader);
// no streams are supported
DEBUG_ASSERT( pSrb->NumberOfBytesToTransfer >= sizeof( HW_STREAM_HEADER));
OutputDebugTrace(( "CATIWDMTuner:AdapterGetStreamInfo()\n"));
m_wdmTunerStreamHeader.NumberOfStreams = 0; m_wdmTunerStreamHeader.SizeOfHwStreamInformation = sizeof( HW_STREAM_INFORMATION); m_wdmTunerStreamHeader.NumDevPropArrayEntries = 1; m_wdmTunerStreamHeader.DevicePropertiesArray = &m_wdmTunerPropertySet; m_wdmTunerStreamHeader.NumDevEventArrayEntries = 0; m_wdmTunerStreamHeader.DeviceEventsArray = NULL; m_wdmTunerStreamHeader.Topology = &m_wdmTunerTopology;
* pStreamHeader = m_wdmTunerStreamHeader;
pSrb->Status = STATUS_SUCCESS; return( TRUE); }
/*^^*
* AdapterQueryUnload() * Purpose : Called when the class driver is about to unload the MiniDriver * The MiniDriver checks if any open stream left. * * Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb * * Outputs : BOOL : returns TRUE * Author : IKLEBANOV *^^*/ BOOL CATIWDMTuner::AdapterQueryUnload( PHW_STREAM_REQUEST_BLOCK pSrb) {
OutputDebugTrace(( "CATIWDMTuner:AdapterQueryUnload()\n"));
pSrb->Status = STATUS_SUCCESS; return( TRUE); }
/*^^*
* operator new * Purpose : CATIWDMTuner class overloaded operator new. * Provides placement for a CATIWDMTuner class object from the PADAPTER_DEVICE_EXTENSION * allocated by the StreamClassDriver for the MiniDriver. * * Inputs : UINT size_t : size of the object to be placed * PVOID pAllocation : casted pointer to the CWDMTuner allocated data * * Outputs : PVOID : pointer of the CATIWDMTuner class object * Author : IKLEBANOV *^^*/ PVOID CATIWDMTuner::operator new( size_t size_t, PVOID pAllocation) {
if( size_t != sizeof( CATIWDMTuner)) { OutputDebugError(( "CATIWDMTuner: operator new() fails\n")); return( NULL); } else return( pAllocation); }
/*^^*
* ~CATIWDMTuner() * Purpose : CATIWDMTuner class destructor. * Frees the allocated memory. * * Inputs : none * * Outputs : none * Author : IKLEBANOV *^^*/ CATIWDMTuner::~CATIWDMTuner() {
OutputDebugTrace(( "CATIWDMTuner:~CATIWDMTuner()\n"));
if( m_pTVTunerPinsMediumInfo != NULL) { ::ExFreePool( m_pTVTunerPinsMediumInfo); m_pTVTunerPinsMediumInfo = NULL; }
if( m_pTVTunerPinsDirectionInfo != NULL) { ::ExFreePool( m_pTVTunerPinsDirectionInfo); m_pTVTunerPinsDirectionInfo = NULL; } }
/*^^*
* CATIWDMTuner() * Purpose : CATIWDMTuner class constructor. * Performs checking of the hardware presence. Sets the hardware in an initial state. * * Inputs : CI2CScript * pCScript : pointer to the I2CScript class object * PUINT puiError : pointer to return a completion error code * * Outputs : none * Author : IKLEBANOV *^^*/ CATIWDMTuner::CATIWDMTuner( PPORT_CONFIGURATION_INFORMATION pConfigInfo, CI2CScript * pCScript, PUINT puiErrorCode) :m_CATIConfiguration( pConfigInfo, pCScript, puiErrorCode) { UINT uiError;
OutputDebugTrace(( "CATIWDMTuner:CATIWDMTuner() enter\n"));
// error code was carried over from ATIConfiguration class constructor
uiError = * puiErrorCode;
m_pTVTunerPinsMediumInfo = NULL; m_pTVTunerPinsDirectionInfo = NULL; m_ulPowerState = PowerDeviceD0; ENSURE { if( uiError != WDMMINI_NOERROR) // ATIConfiguration Class object was constructed with an error
FAIL;
if( pCScript == NULL) { uiError = WDMMINI_INVALIDPARAM; FAIL; }
if( !m_CATIConfiguration.GetTunerConfiguration( &m_uiTunerId, &m_uchTunerI2CAddress) || ( !m_uchTunerI2CAddress)) { // there was no hardware information found
uiError = WDMMINI_NOHARDWARE; FAIL; }
// Set tuner capabilities ( RO properties) based upon the TunerId
if( !SetTunerWDMCapabilities( m_uiTunerId) || ( !m_ulNumberOfPins)) { // there is unsupported hardware was found
uiError = WDMMINI_UNKNOWNHARDWARE; FAIL; }
m_pTVTunerPinsMediumInfo = ( PKSPIN_MEDIUM) \ ::ExAllocatePool( NonPagedPool, sizeof( KSPIN_MEDIUM) * m_ulNumberOfPins); if( m_pTVTunerPinsMediumInfo == NULL) { uiError = WDMMINI_ERROR_MEMORYALLOCATION; FAIL; } m_pTVTunerPinsDirectionInfo = ( PBOOL) \ ::ExAllocatePool( NonPagedPool, sizeof( BOOL) * m_ulNumberOfPins); if( m_pTVTunerPinsDirectionInfo == NULL) { uiError = WDMMINI_ERROR_MEMORYALLOCATION; FAIL; }
m_pI2CScript = pCScript;
SetWDMTunerKSProperties(); SetWDMTunerKSTopology();
// Set run-time WDM properties at the last
m_ulVideoStandard = ( m_ulNumberOfStandards == 1) ? // unknown standard or the only one
m_wdmTunerCaps.ulStandardsSupported : 0x0L; m_ulTunerInput = 0L; // unknown input or the only one
m_ulTuningFrequency = 0L; // unknown tuning frequency
#ifndef ATI_TVAUDIO_SUPPORT
{ // this code is needed to initilaize TVAudio path off the tuner
// if there is no separate MiniDriver for TVAudio is assumed
UINT uiAudioConfiguration; UCHAR uchAudioI2CAddress;
if( m_CATIConfiguration.GetAudioConfiguration( &uiAudioConfiguration, &uchAudioI2CAddress)) { m_CATIConfiguration.InitializeAudioConfiguration( pCScript, uiAudioConfiguration, uchAudioI2CAddress); } } #endif // ATI_TVAUDIO_SUPPORT
* puiErrorCode = WDMMINI_NOERROR;
OutputDebugTrace(( "CATIWDMTuner:CATIWDMTuner() exit\n"));
return;
} END_ENSURE;
* puiErrorCode = uiError;
OutputDebugError(( "CATIWDMTuner:CATIWDMTuner() Error = %x\n", uiError)); }
/*^^*
* SetTunerCapabilities() * Purpose : Sets the capabilities ( RO properties) based upon the Tuner Id * * Inputs : UINT puiTunerId : Tuner Id * * Outputs : returns TRUE, if there is a supported Tuner Id specified; * also sets the following WDM Tuner properities: * Author : IKLEBANOV *^^*/ BOOL CATIWDMTuner::SetTunerWDMCapabilities( UINT uiTunerId) { ::RtlZeroMemory( &m_wdmTunerCaps, sizeof( ATI_KSPROPERTY_TUNER_CAPS)); m_ulIntermediateFrequency = 0x0L;
switch( uiTunerId) { case 0x01: // FI1236 NTSC M/N North America
m_ulNumberOfStandards = 3; m_wdmTunerCaps.ulStandardsSupported = KS_AnalogVideo_NTSC_M | KS_AnalogVideo_PAL_M | KS_AnalogVideo_PAL_N; m_wdmTunerCaps.ulNumberOfInputs = 1; m_wdmTunerCaps.ulMinFrequency = 54000000L; m_wdmTunerCaps.ulMaxFrequency = 801250000L; m_ulIntermediateFrequency = 45750000L; m_ulSupportedModes = KSPROPERTY_TUNER_MODE_TV; m_ulNumberOfPins = 2; break;
case 0x02: // FI1236J NTSC M/N Japan
m_ulNumberOfStandards = 1; m_wdmTunerCaps.ulStandardsSupported = KS_AnalogVideo_NTSC_M_J; m_wdmTunerCaps.ulNumberOfInputs = 1; m_wdmTunerCaps.ulMinFrequency = 54000000L; m_wdmTunerCaps.ulMaxFrequency = 765250000L; m_ulIntermediateFrequency = 45750000L; m_ulSupportedModes = KSPROPERTY_TUNER_MODE_TV; m_ulNumberOfPins = 2; break;
case 0x03: // FI1216 PAL B/G
m_ulNumberOfStandards = 2; m_wdmTunerCaps.ulStandardsSupported = KS_AnalogVideo_PAL_B | KS_AnalogVideo_PAL_G; m_wdmTunerCaps.ulNumberOfInputs = 1; m_wdmTunerCaps.ulMinFrequency = 54000000L; m_wdmTunerCaps.ulMaxFrequency = 855250000L; m_ulIntermediateFrequency = 38900000L; m_ulSupportedModes = KSPROPERTY_TUNER_MODE_TV; m_ulNumberOfPins = 2; break;
case 0x04: // FI1246 MK2 PAL I
m_ulNumberOfStandards = 1; m_wdmTunerCaps.ulStandardsSupported = KS_AnalogVideo_PAL_I; m_wdmTunerCaps.ulNumberOfInputs = 1; m_wdmTunerCaps.ulMinFrequency = 45750000L; m_wdmTunerCaps.ulMaxFrequency = 855250000L; m_ulIntermediateFrequency = 38900000L; m_ulSupportedModes = KSPROPERTY_TUNER_MODE_TV; m_ulNumberOfPins = 2; break;
case 0x05: // FI1216 PAL B/G, SECAM L/L'
m_ulNumberOfStandards = 3; m_wdmTunerCaps.ulStandardsSupported = KS_AnalogVideo_PAL_B | KS_AnalogVideo_PAL_G | KS_AnalogVideo_SECAM_L; m_wdmTunerCaps.ulNumberOfInputs = 1; m_wdmTunerCaps.ulMinFrequency = 54000000L; m_wdmTunerCaps.ulMaxFrequency = 855250000L; m_ulIntermediateFrequency = 38900000L; m_ulSupportedModes = KSPROPERTY_TUNER_MODE_TV; m_ulNumberOfPins = 2; break;
case 0x06: // FR1236MK2 NTSC M/N North America + Japan
m_ulNumberOfStandards = 4; m_wdmTunerCaps.ulStandardsSupported = KS_AnalogVideo_NTSC_M | KS_AnalogVideo_PAL_M | KS_AnalogVideo_NTSC_M_J | KS_AnalogVideo_PAL_N; m_wdmTunerCaps.ulNumberOfInputs = 1; m_wdmTunerCaps.ulMinFrequency = 54000000L; m_wdmTunerCaps.ulMaxFrequency = 801250000L; m_ulIntermediateFrequency = 45750000L; m_ulSupportedModes = KSPROPERTY_TUNER_MODE_TV; m_ulNumberOfPins = 2; break;
case 0x07: // FI1256 PAL D/K China
m_ulNumberOfStandards = 1; m_wdmTunerCaps.ulStandardsSupported = KS_AnalogVideo_PAL_D | KS_AnalogVideo_SECAM_D; m_wdmTunerCaps.ulNumberOfInputs = 1; m_wdmTunerCaps.ulMinFrequency = 48250000L; m_wdmTunerCaps.ulMaxFrequency = 855250000L; m_ulIntermediateFrequency = 38000000L; m_ulSupportedModes = KSPROPERTY_TUNER_MODE_TV; m_ulNumberOfPins = 2; break;
case 0x08: // NTSC North America NEC FM Tuner
m_ulNumberOfStandards = 3; m_wdmTunerCaps.ulStandardsSupported = KS_AnalogVideo_NTSC_M | KS_AnalogVideo_PAL_M | KS_AnalogVideo_PAL_N; m_wdmTunerCaps.ulNumberOfInputs = 2; m_wdmTunerCaps.ulMinFrequency = 54000000L; m_wdmTunerCaps.ulMaxFrequency = 801250000L; m_ulIntermediateFrequency = 45750000L; m_ulSupportedModes = KSPROPERTY_TUNER_MODE_TV | KSPROPERTY_TUNER_MODE_FM_RADIO; m_ulNumberOfPins = 2; break;
case 0x10: // NTSC North America Alps Tuner
case 0x11: // NTSC North America Alps Tuner
m_ulNumberOfStandards = 3; m_wdmTunerCaps.ulStandardsSupported = KS_AnalogVideo_NTSC_M | KS_AnalogVideo_PAL_M | KS_AnalogVideo_PAL_N; m_wdmTunerCaps.ulNumberOfInputs = 1; m_wdmTunerCaps.ulMinFrequency = 54000000L; m_wdmTunerCaps.ulMaxFrequency = 801250000L; m_ulIntermediateFrequency = 45750000L; m_ulSupportedModes = KSPROPERTY_TUNER_MODE_TV; m_ulNumberOfPins = 2; break;
case 0x12: // NTSC North America Alps Tuner with FM
m_ulNumberOfStandards = 3; m_wdmTunerCaps.ulStandardsSupported = KS_AnalogVideo_NTSC_M | KS_AnalogVideo_PAL_M | KS_AnalogVideo_PAL_N; m_wdmTunerCaps.ulNumberOfInputs = 1; m_wdmTunerCaps.ulMinFrequency = 54000000L; m_wdmTunerCaps.ulMaxFrequency = 801250000L; m_ulIntermediateFrequency = 45750000L; m_ulSupportedModes = KSPROPERTY_TUNER_MODE_TV | KSPROPERTY_TUNER_MODE_FM_RADIO; m_ulNumberOfPins = 2; break;
case 0x0D: // Temic 4006 FN5 PAL B/G + PAL/I + PAL D + SECAM D/K
m_ulNumberOfStandards = 6; m_wdmTunerCaps.ulStandardsSupported = KS_AnalogVideo_PAL_B | KS_AnalogVideo_PAL_G | KS_AnalogVideo_PAL_I | KS_AnalogVideo_PAL_D | KS_AnalogVideo_SECAM_D | KS_AnalogVideo_SECAM_K; m_wdmTunerCaps.ulNumberOfInputs = 1; m_wdmTunerCaps.ulMinFrequency = 45000000L; m_wdmTunerCaps.ulMaxFrequency = 868000000L; m_ulIntermediateFrequency = 38900000L; m_ulSupportedModes = KSPROPERTY_TUNER_MODE_TV; m_ulNumberOfPins = 2; break;
default: return( FALSE); }
m_ulTunerMode = KSPROPERTY_TUNER_MODE_TV;
m_wdmTunerCaps.ulTuningGranularity = 62500L; m_wdmTunerCaps.ulSettlingTime = 150; m_wdmTunerCaps.ulStrategy = KS_TUNER_STRATEGY_PLL;
return( TRUE); }
/*^^*
* AdapterSetPowerState() * Purpose : Sets Power Managemeny mode * * Inputs : PHW_STREAM_REQUEST_BLOCK pSrb : pointer to the current Srb * * Outputs : NTSTATUS as the result of operation * Author : TOM *^^*/ NTSTATUS CATIWDMTuner::AdapterSetPowerState( PHW_STREAM_REQUEST_BLOCK pSrb) { PADAPTER_DATA_EXTENSION pPrivateData = ( PADAPTER_DATA_EXTENSION)(( PHW_STREAM_REQUEST_BLOCK)pSrb)->HwDeviceExtension; CI2CScript * pCScript = &pPrivateData->CScript; DEVICE_POWER_STATE nDeviceState = pSrb->CommandData.DeviceState; LARGE_INTEGER liWakeUpTime; NTSTATUS ntStatus;
m_pPendingDeviceSrb = pSrb; ntStatus = STATUS_ADAPTER_HARDWARE_ERROR;
switch( nDeviceState) { case PowerDeviceD0: case PowerDeviceD3: if( nDeviceState != m_ulPowerState) { m_CATIConfiguration.SetTunerPowerState( m_pI2CScript, ( nDeviceState == PowerDeviceD0 ? TRUE : FALSE));
// if transition form D3 to D0 we have to restore frequency
if(( nDeviceState == PowerDeviceD0) && ( m_ulPowerState == PowerDeviceD3)) { // we have to wait approx. 10ms for tuner to power up
liWakeUpTime.QuadPart = ATIHARDWARE_TUNER_WAKEUP_DELAY; KeDelayExecutionThread( KernelMode, FALSE, &liWakeUpTime);
// now we have to restore frequency
if( SetTunerFrequency( m_ulTuningFrequency)) ntStatus = STATUS_SUCCESS; else ntStatus = STATUS_ADAPTER_HARDWARE_ERROR; } else ntStatus = STATUS_SUCCESS;
m_ulPowerState = nDeviceState; } else ntStatus = STATUS_SUCCESS; break;
case PowerDeviceD1: case PowerDeviceD2: ntStatus = STATUS_SUCCESS; break;
default: ntStatus = STATUS_INVALID_PARAMETER; break; }
return( ntStatus); }
|