//==========================================================================; // // ATIConfg.CPP // WDM MiniDrivers development. // ATIHwConfiguration class implementation. // Copyright (c) 1996 - 1997 ATI Technologies Inc. All Rights Reserved. // // $Date: 10 Jun 1999 09:54:42 $ // $Revision: 1.21 $ // $Author: KLEBANOV $ // //==========================================================================; extern"C" { #include "conio.h" #include "strmini.h" #include "wdmdebug.h" #include "ksmedia.h" //Paul } #include "aticonfg.h" #include "wdmdrv.h" #include "atigpio.h" #include "mmconfig.h" /*^^* * CATIHwConfiguration() * Purpose : CATIHwConfiguration Class constructor * Determines I2CExpander address and all possible hardware IDs and addresses * * Inputs : PDEVICE_OBJECT pDeviceObject : pointer to the creator DeviceObject * CI2CScript * pCScript : pointer to the I2CScript class object * PUINT puiError : pointer to return Error code * * Outputs : none * Author : IKLEBANOV *^^*/ CATIHwConfiguration::CATIHwConfiguration( PPORT_CONFIGURATION_INFORMATION pConfigInfo, CI2CScript * pCScript, PUINT puiError) { ENSURE { m_VideoInStandardsSupported = 0; m_CrystalIDInMMTable = 0xF; // invalid entry, needs to be set when set with the value from MMTable m_gpioProviderInterface.gpioOpen = NULL; m_gpioProviderInterface.gpioAccess = NULL; m_pdoDriver = NULL; m_usE2PROMValidation = ( USHORT)-1; if( InitializeAttachGPIOProvider( &m_gpioProviderInterface, pConfigInfo->PhysicalDeviceObject)) // there was no error to get GPIOInterface from the MiniVDD m_pdoDriver = pConfigInfo->RealPhysicalDeviceObject; else { * puiError = WDMMINI_ERROR_NOGPIOPROVIDER; FAIL; } if( !FindI2CExpanderAddress( pCScript)) { * puiError = WDMMINI_NOHARDWARE; FAIL; } if( !FindHardwareProperties( pConfigInfo->RealPhysicalDeviceObject, pCScript)) { * puiError = WDMMINI_NOHARDWARE; FAIL; } * puiError = WDMMINI_NOERROR; OutputDebugTrace(( "CATIHwConfig:CATIHwConfiguration() exit\n")); } END_ENSURE; if( * puiError != WDMMINI_NOERROR) OutputDebugError(( "CATIHwConfig:CATIHwConfiguration() uiError=%x\n", * puiError)); } /*^^* * FindHardwareProperties() * Purpose : Determines hardware properties : I2C address and the type * * Inputs : PDEVICEOBJECT pDeviceObject: pointer to device object * CI2CScript * pCScript : pointer to the I2CScript object * * Outputs : BOOL, TRUE if a valid ATI hardware Configuration was found * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::FindHardwareProperties( PDEVICE_OBJECT pDeviceObject, CI2CScript * pCScript) { UCHAR uchI2CValue; UCHAR uchORMask = 0x00; UCHAR uchANDMask = 0xFF; BOOL bResult = TRUE; I2CPacket i2cPacket; m_VideoInStandardsSupported = 0; //Paul m_uchTunerAddress = 0; m_usTunerId = 0; m_usTunerPowerConfiguration = ATI_TUNER_POWER_CONFIG_0; m_uchDecoderAddress = 0; m_usDecoderId = VIDEODECODER_TYPE_NOTINSTALLED; m_usDecoderConfiguration = 0; m_uchAudioAddress = 0; m_uiAudioConfiguration = 0; switch( m_uchI2CExpanderAddress) { case 0x70: // a standard external tuner board m_uchTunerAddress = 0xC0; m_uchDecoderAddress = 0x88; // we need to determine actual Decoder ID, implement later m_usDecoderId = VIDEODECODER_TYPE_BT829; if( GetI2CExpanderConfiguration( pCScript, &uchI2CValue)) { m_usTunerId = uchI2CValue & 0x0F; m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_1; if( uchI2CValue & 0x10) { m_uiAudioConfiguration = ATI_AUDIO_CONFIG_4; m_uchAudioAddress = 0x82; } else m_uiAudioConfiguration = ATI_AUDIO_CONFIG_3; } m_VideoInStandardsSupported = SetVidStdBasedOnI2CExpander( uchI2CValue ); //Paul break; case 0x78: // FM tuner m_uchTunerAddress = 0xC0; m_uchDecoderAddress = 0x88; // we need to determine actual Decoder ID, implement later m_usDecoderId = VIDEODECODER_TYPE_BT829; if( GetI2CExpanderConfiguration( pCScript, &uchI2CValue)) { m_usTunerId = uchI2CValue & 0x0F; m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_1; m_uiAudioConfiguration = ATI_AUDIO_CONFIG_5; } m_VideoInStandardsSupported = SetVidStdBasedOnI2CExpander( uchI2CValue ); //Paul break; case 0x76: // AllInWonder, configuration is in the BIOS { CATIMultimediaTable CMultimediaInfo( pDeviceObject, &m_gpioProviderInterface, &bResult); if( bResult) { // tuner and decoder Info is included m_uchTunerAddress = 0xC6; m_uchDecoderAddress = 0x8A; m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_1; m_uiAudioConfiguration = ATI_AUDIO_CONFIG_1; if( !CMultimediaInfo.GetTVTunerId( &m_usTunerId) || !CMultimediaInfo.GetVideoDecoderId( &m_usDecoderId)) bResult = FALSE; else m_VideoInStandardsSupported = SetVidStdBasedOnMMTable( &CMultimediaInfo ); //Paul } break; } case 0x7C: ENSURE { i2cPacket.uchChipAddress = m_uchI2CExpanderAddress; i2cPacket.cbReadCount = 1; i2cPacket.cbWriteCount = 0; i2cPacket.puchReadBuffer = &uchI2CValue; i2cPacket.puchWriteBuffer = NULL; i2cPacket.usFlags = 0; pCScript->ExecuteI2CPacket( &i2cPacket); if( i2cPacket.uchI2CResult != I2C_STATUS_NOERROR) { bResult = FALSE; FAIL; } uchI2CValue |= 0x0F; i2cPacket.uchChipAddress = m_uchI2CExpanderAddress; i2cPacket.cbReadCount = 0; i2cPacket.cbWriteCount = 1; i2cPacket.puchReadBuffer = NULL; i2cPacket.puchWriteBuffer = &uchI2CValue; i2cPacket.usFlags = 0; pCScript->ExecuteI2CPacket( &i2cPacket); if (i2cPacket.uchI2CResult != I2C_STATUS_NOERROR) { bResult = FALSE; FAIL; } // information should be correct now if( GetI2CExpanderConfiguration( pCScript, &uchI2CValue)) { m_usTunerId = uchI2CValue & 0x0F; } m_VideoInStandardsSupported = SetVidStdBasedOnI2CExpander( uchI2CValue ); //Paul } END_ENSURE; if (!bResult) break; // For IO Expander address == 0x7c there might be more information in the BIOS Table sto do not return // or break at this point case 0xFF: // AllInWonder PRO, configuration is in the BIOS ENSURE { CATIMultimediaTable CMultimediaInfo( pDeviceObject, &m_gpioProviderInterface, &bResult); USHORT nOEMId, nOEMRevision, nATIProductType; BOOL bATIProduct; if( !bResult) FAIL; // OEM Id information is included if( !CMultimediaInfo.IsATIProduct( &bATIProduct)) { bResult = FALSE; FAIL; } m_uchDecoderAddress = 0x8A; m_uchTunerAddress = 0xC6; if( bATIProduct) { if( !CMultimediaInfo.GetATIProductId( &nATIProductType)) { bResult = FALSE; FAIL; } if( CMultimediaInfo.GetTVTunerId( &m_usTunerId) && CMultimediaInfo.GetVideoDecoderId( &m_usDecoderId)) { switch( nATIProductType) { case ATI_PRODUCT_TYPE_AIW_PRO_NODVD: case ATI_PRODUCT_TYPE_AIW_PRO_DVD: m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_2; m_uiAudioConfiguration = ATI_AUDIO_CONFIG_2; m_usTunerPowerConfiguration = ATI_TUNER_POWER_CONFIG_1; m_uchAudioAddress = 0xB4; break; case ATI_PRODUCT_TYPE_AIW_PLUS: m_uiAudioConfiguration = ATI_AUDIO_CONFIG_6; m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_2; m_uchAudioAddress = 0xB6; break; case ATI_PRODUCT_TYPE_AIW_PRO_R128_KITCHENER: m_uiAudioConfiguration = ATI_AUDIO_CONFIG_7; m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_2; m_uchAudioAddress = 0xB4; break; case ATI_PRODUCT_TYPE_AIW_PRO_R128_TORONTO: m_uiAudioConfiguration = ATI_AUDIO_CONFIG_8; m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_UNDEFINED; m_uchAudioAddress = 0x80; break; default: bResult = FALSE; break; } } else bResult = FALSE; } else { // non ATI Product if( !CMultimediaInfo.GetOEMId( &nOEMId) || !CMultimediaInfo.GetOEMRevisionId( &nOEMRevision)) { bResult = FALSE; FAIL; } m_uchDecoderAddress = 0x8A; m_uchTunerAddress = 0xC6; switch( nOEMId) { case OEM_ID_INTEL: switch( nOEMRevision) { case INTEL_ANCHORAGE: if( CMultimediaInfo.GetVideoDecoderId( &m_usDecoderId) && CMultimediaInfo.GetTVTunerId( &m_usTunerId)) { m_uiAudioConfiguration = ATI_AUDIO_CONFIG_1; switch( m_usDecoderId) { case VIDEODECODER_TYPE_BT829: m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_3; break; case VIDEODECODER_TYPE_BT829A: m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_2; break; default: bResult = FALSE; break; } } else bResult = FALSE; break; default: bResult = FALSE; break; } break; case OEM_ID_APRICOT: switch( nOEMRevision) { case REVISION1: case REVISION2: if( CMultimediaInfo.GetTVTunerId( &m_usTunerId)) { switch( m_usDecoderId) { case VIDEODECODER_TYPE_BT829: m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_4; break; case VIDEODECODER_TYPE_BT829A: m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_2; break; } } else bResult = FALSE; break; default: bResult = FALSE; break; } break; case OEM_ID_FUJITSU: m_uchDecoderAddress = 0x88; switch( nOEMRevision) { case REVISION1: if( CMultimediaInfo.GetVideoDecoderId( &m_usDecoderId)) { switch( m_usDecoderId) { case VIDEODECODER_TYPE_BT829A: m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_2; break; default: bResult = FALSE; break; } } else bResult = FALSE; break; default: bResult = FALSE; break; } break; case OEM_ID_COMPAQ: switch( nOEMRevision) { case REVISION1: if( CMultimediaInfo.GetVideoDecoderId( &m_usDecoderId)) { switch( m_usDecoderId) { case VIDEODECODER_TYPE_BT829: m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_3; break; case VIDEODECODER_TYPE_BT829A: m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_2; break; default: bResult = FALSE; break; } } else bResult = FALSE; break; default: bResult = FALSE; break; } break; case OEM_ID_BCM: case OEM_ID_SAMSUNG: switch( nOEMRevision) { case REVISION0: if( CMultimediaInfo.GetVideoDecoderId( &m_usDecoderId)) { switch( m_usDecoderId) { case VIDEODECODER_TYPE_BT829A: m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_2; break; default: bResult = FALSE; } } else bResult = FALSE; break; default: bResult = FALSE; break; } break; case OEM_ID_SAMREX: switch( nOEMRevision) { case REVISION0: if( CMultimediaInfo.GetVideoDecoderId( &m_usDecoderId)) { switch( m_usDecoderId) { case VIDEODECODER_TYPE_BT829A: m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_2; break; default: bResult = FALSE; break; } } else bResult = FALSE; break; default: bResult = FALSE; break; } break; case OEM_ID_NEC: switch( nOEMRevision) { case REVISION0: case REVISION1: if( CMultimediaInfo.GetVideoDecoderId( &m_usDecoderId)) { switch( m_usDecoderId) { case VIDEODECODER_TYPE_BT829A: m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_2; break; default: bResult = FALSE; break; } } else bResult = FALSE; break; default: bResult = FALSE; break; } break; default: if( CMultimediaInfo.GetVideoDecoderId( &m_usDecoderId)) { if( m_usDecoderId == VIDEODECODER_TYPE_RTHEATER) { // default the configuration to Toronto board m_uiAudioConfiguration = ATI_AUDIO_CONFIG_8; m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_UNDEFINED; m_uchAudioAddress = 0x80; } else { // default the configuration to Kitchener board m_uiAudioConfiguration = ATI_AUDIO_CONFIG_7; m_usDecoderConfiguration = ATI_VIDEODECODER_CONFIG_2; m_uchAudioAddress = 0xB4; } bResult = TRUE; } else bResult = FALSE; break; } } m_VideoInStandardsSupported = SetVidStdBasedOnMMTable( &CMultimediaInfo ); //Paul } END_ENSURE; break; } OutputDebugInfo(( "CATIHwConfig:FindHardwareConfiguration() found:\n")); OutputDebugInfo(( "Tuner: Id = %d, I2CAddress = 0x%x\n", m_usTunerId, m_uchTunerAddress)); OutputDebugInfo(( "Decoder: Id = %d, I2CAddress = 0x%x, Configuration = %d\n", m_usDecoderId, m_uchDecoderAddress, m_usDecoderConfiguration)); OutputDebugInfo(( "Audio: I2CAddress = 0x%x, Configuration = %d\n", m_uchAudioAddress, m_uiAudioConfiguration)); return( bResult); } /*^^* * GetTunerConfiguration() * Purpose : Gets tuner Id and i2C address * Inputs : PUINT puiTunerId : pointer to return tuner Id * PUCHAR puchTunerAddress : pointer to return tuner I2C address * * Outputs : BOOL : returns TRUE * also sets the requested values into the input pointers * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::GetTunerConfiguration( PUINT puiTunerId, PUCHAR puchTunerAddress) { if(( puiTunerId != NULL) && ( puchTunerAddress != NULL)) { * puiTunerId = ( UINT)m_usTunerId; * puchTunerAddress = m_uchTunerAddress; return( TRUE); } else return( FALSE); } /*^^* * GetDecoderConfiguration() * Purpose : Gets decoder Id and i2C address * * Inputs : puiDecoderId : pointer to return Decoder Id * * Outputs : BOOL : returns TRUE * also sets the requested values into the input pointer * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::GetDecoderConfiguration( PUINT puiDecoderId, PUCHAR puchDecoderAddress) { if(( puiDecoderId != NULL) && ( puchDecoderAddress != NULL)) { * puiDecoderId = ( UINT)m_usDecoderId; * puchDecoderAddress = m_uchDecoderAddress; return( TRUE); } else return( FALSE); } /*^^* * GetAudioConfiguration() * Purpose : Gets Audio solution Id and i2C address * * Inputs : PUINT puiAudioConfiguration : pointer to return Audio configuration Id * PUCHAR puchAudioAddress : pointer to return audio hardware * I2C address * * Outputs : BOOL : returns TRUE * also sets the requested values into the input pointer * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::GetAudioConfiguration( PUINT puiAudioConfiguration, PUCHAR puchAudioAddress) { if(( puiAudioConfiguration != NULL) && ( puchAudioAddress != NULL)) { * puiAudioConfiguration = ( UINT)m_uiAudioConfiguration; * puchAudioAddress = m_uchAudioAddress; return( TRUE); } else return( FALSE); } /*^^* * InitializeAudioConfiguration() * Purpose : Initializes Audio Chip with default / power up values. This function will * be called at Low priority with i2CProvider locked * * Inputs : CI2CScript * pCScript : pointer to the I2CScript object * UINT uiAudioConfigurationId : detected Audio configuration * UCHAR uchAudioChipAddress : detected Audio chip I2C address * Outputs : none * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::InitializeAudioConfiguration( CI2CScript * pCScript, UINT uiAudioConfigurationId, UCHAR uchAudioChipAddress) { I2CPacket i2cPacket; UCHAR uchWrite16Value[5]; #ifdef I2S_CAPTURE UCHAR uchRead16Value[5]; #endif // I2S_CAPTURE BOOL bResult; switch( uiAudioConfigurationId) { case ATI_AUDIO_CONFIG_2: case ATI_AUDIO_CONFIG_7: // TDA9850 has to be initialized with the values from I2C EEPROM, if // those answers the CheckSum. If not, take hardcoded default values { UINT nIndex, nNumberOfRegs; PUCHAR puchInitializationBuffer = NULL; UCHAR uchWriteBuffer[2]; bResult = FALSE; nNumberOfRegs = AUDIO_TDA9850_Reg_Align3 - AUDIO_TDA9850_Reg_Control1 + 1; puchInitializationBuffer = ( PUCHAR) \ ::ExAllocatePool( NonPagedPool, nNumberOfRegs * sizeof( PUCHAR)); if( puchInitializationBuffer == NULL) return( bResult); // fill in the Initialization buffer with the defaults values puchInitializationBuffer[0] = AUDIO_TDA9850_Control1_DefaultValue; puchInitializationBuffer[1] = AUDIO_TDA9850_Control2_DefaultValue; puchInitializationBuffer[2] = AUDIO_TDA9850_Control3_DefaultValue; puchInitializationBuffer[3] = AUDIO_TDA9850_Control4_DefaultValue; puchInitializationBuffer[4] = AUDIO_TDA9850_Align1_DefaultValue; puchInitializationBuffer[5] = AUDIO_TDA9850_Align2_DefaultValue; puchInitializationBuffer[6] = AUDIO_TDA9850_Align3_DefaultValue; // we have to see if anything in I2C EEPROM is waiting for us to // overwrite the default values if( ValidateConfigurationE2PROM( pCScript)) { // The configuration E2PROM kept its integrity. Let's read the // initialization values from the device ReadConfigurationE2PROM( pCScript, 3, &puchInitializationBuffer[4]); ReadConfigurationE2PROM( pCScript, 4, &puchInitializationBuffer[5]); } // write the power-up defaults values into the chip i2cPacket.uchChipAddress = uchAudioChipAddress; i2cPacket.cbReadCount = 0; i2cPacket.cbWriteCount = 2; i2cPacket.puchReadBuffer = NULL; i2cPacket.puchWriteBuffer = uchWriteBuffer; i2cPacket.usFlags = I2COPERATION_WRITE; for( nIndex = 0; nIndex < nNumberOfRegs; nIndex ++) { uchWriteBuffer[0] = AUDIO_TDA9850_Reg_Control1 + nIndex; uchWriteBuffer[1] = puchInitializationBuffer[nIndex]; if( !( bResult = pCScript->ExecuteI2CPacket( &i2cPacket))) break; } if( puchInitializationBuffer != NULL) ::ExFreePool( puchInitializationBuffer); return( bResult); } break; case ATI_AUDIO_CONFIG_4: // TDA8425 volume control should be initialized return( SetDefaultVolumeControl( pCScript)); break; case ATI_AUDIO_CONFIG_6: { UCHAR uchWriteBuffer; // write the power-up defaults values into the chip i2cPacket.uchChipAddress = uchAudioChipAddress; i2cPacket.cbReadCount = 0; i2cPacket.cbWriteCount = 1; i2cPacket.puchReadBuffer = NULL; i2cPacket.puchWriteBuffer = &uchWriteBuffer; i2cPacket.usFlags = I2COPERATION_WRITE; uchWriteBuffer = AUDIO_TDA9851_DefaultValue; return( pCScript->ExecuteI2CPacket( &i2cPacket)); } break; case ATI_AUDIO_CONFIG_8: //Reset MSP3430 i2cPacket.uchChipAddress = m_uchAudioAddress; i2cPacket.cbReadCount = 0; i2cPacket.usFlags = I2COPERATION_WRITE; i2cPacket.puchWriteBuffer = uchWrite16Value; //Write 0x80 - 00 to Subaddr 0x00 i2cPacket.cbWriteCount = 3; uchWrite16Value[0] = 0x00; uchWrite16Value[1] = 0x80; uchWrite16Value[2] = 0x00; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //Write 0x00 - 00 to Subaddr 0x00 i2cPacket.cbWriteCount = 3; uchWrite16Value[0] = 0x00; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x00; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0x13 Val 0x3f60 i2cPacket.cbWriteCount = 5; uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x13; uchWrite16Value[3] = 0x3f; uchWrite16Value[4] = 0x60; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0x00 Val 0x0000 i2cPacket.cbWriteCount = 5; uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x00; uchWrite16Value[3] = 0x00; uchWrite16Value[4] = 0x00; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); #ifdef I2S_CAPTURE #pragma message ("\n!!! PAY ATTENTION: Driver has been build with ITT CHIP I2S CAPTURE CONFIGURED !!!\n") i2cPacket.uchChipAddress = m_uchAudioAddress; i2cPacket.usFlags = I2COPERATION_WRITE; i2cPacket.puchWriteBuffer = uchWrite16Value; i2cPacket.puchReadBuffer = uchRead16Value; //Setup I2S Source Select and Output Channel Matrix //SubAddr 0x12 Reg 0x0b Val 0x0320 i2cPacket.cbWriteCount = 5; i2cPacket.cbReadCount = 0; uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x0b; uchWrite16Value[3] = 0x03; uchWrite16Value[4] = 0x20; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //Setup MODUS i2cPacket.cbWriteCount = 5; i2cPacket.cbReadCount = 0; uchWrite16Value[0] = 0x10; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x30; uchWrite16Value[3] = 0x20; uchWrite16Value[4] = 0xe3; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); #endif // I2S_CAPTURE break; default: break; } return( TRUE); } /*^^* * GetTVAudioSignalProperties() * Purpose : Gets Audio signal properties readable from ATI dependand hardware, * like I2C expander. This call is always synchronous. * * Inputs : CI2CScript * pCScript : pointer to the I2CScript object * PBOOL pbStereo : pointer to the Stereo Indicator * PBOOL pbSAP : pointer to the SAP Indicator * * Outputs : BOOL, returns TRUE, if successful * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::GetTVAudioSignalProperties( CI2CScript * pCScript, PBOOL pbStereo, PBOOL pbSAP) { I2CPacket i2cPacket; UCHAR uchReadValue, uchWriteValue; BOOL bResult; switch( m_uiAudioConfiguration) { case ATI_AUDIO_CONFIG_1: case ATI_AUDIO_CONFIG_5: // Stereo property is read back from I2C expander i2cPacket.uchChipAddress = m_uchI2CExpanderAddress; i2cPacket.cbReadCount = 1; i2cPacket.cbWriteCount = 1; i2cPacket.puchReadBuffer = &uchReadValue; i2cPacket.puchWriteBuffer = &uchWriteValue; i2cPacket.usFlags = I2COPERATION_READWRITE; i2cPacket.uchORValue = 0x40; i2cPacket.uchANDValue = 0xFF; bResult = FALSE; ENSURE { if( !pCScript->LockI2CProviderEx()) FAIL; pCScript->ExecuteI2CPacket( &i2cPacket); if( !( bResult = ( i2cPacket.uchI2CResult == I2C_STATUS_NOERROR))) FAIL; i2cPacket.puchWriteBuffer = NULL; i2cPacket.usFlags = I2COPERATION_READ; pCScript->ExecuteI2CPacket( &i2cPacket); if( !( bResult = ( i2cPacket.uchI2CResult == I2C_STATUS_NOERROR))) FAIL; * pbStereo = uchReadValue & 0x40; bResult = TRUE; } END_ENSURE; pCScript->ReleaseI2CProvider(); break; default: bResult = FALSE; break; } if( bResult) // no case, where SAP property is read back from ATI's hardware * pbSAP = FALSE; return( bResult); } /*^^* * GetDecoderOutputEnableLevel() * Purpose : Retrieves ATI dependent hardware configuration property of the logical level * should be applied on OUTEN field of Bt829x decoder in order to enable * output stream * * Inputs : none * * Outputs : UINT, * UINT( -1) value is returned if an error occures * Author : IKLEBANOV *^^*/ UINT CATIHwConfiguration::GetDecoderOutputEnableLevel( void) { UINT uiEnableLevel; switch( m_usDecoderConfiguration) { case ATI_VIDEODECODER_CONFIG_1: case ATI_VIDEODECODER_CONFIG_3: case ATI_VIDEODECODER_CONFIG_4: uiEnableLevel = 0; break; case ATI_VIDEODECODER_CONFIG_2: uiEnableLevel = 1; break; default: uiEnableLevel = UINT( -1); break; } return( uiEnableLevel); } /*^^* * EnableDecoderI2CAccess() * Purpose : Enables/disables I2C access to the decoder chip * * Inputs : CI2CScript * pCScript : pointer to the I2CScript object * BOOL bEnable : defines what to do - enable/disable the decoder's outputs * * Outputs : none * Author : IKLEBANOV *^^*/ void CATIHwConfiguration::EnableDecoderI2CAccess( CI2CScript * pCScript, BOOL bEnable) { UCHAR uchORMask = 0; UCHAR uchANDMask = 0xFF; UCHAR uchReadValue, uchWriteValue; I2CPacket i2cPacket; switch( m_usDecoderConfiguration) { case ATI_VIDEODECODER_CONFIG_1: // Add-On TV Tuner board - ATI TV requires certain actions to be taken i2cPacket.uchChipAddress = m_uchI2CExpanderAddress; i2cPacket.cbReadCount = 1; i2cPacket.cbWriteCount = 1; if( bEnable) uchANDMask &= 0x7F; else uchORMask |= 0x80; i2cPacket.puchReadBuffer = &uchReadValue; i2cPacket.puchWriteBuffer = &uchWriteValue; i2cPacket.usFlags = I2COPERATION_READWRITE; i2cPacket.uchORValue = uchORMask; i2cPacket.uchANDValue = uchANDMask; pCScript->PerformI2CPacketOperation( &i2cPacket); break; #ifdef _X86_ case ATI_VIDEODECODER_CONFIG_3: _outp( 0x7D, ( _inp( 0x7D) | 0x80)); if( bEnable) _outp( 0x7C, ( _inp( 0x7C) & 0x7F)); else _outp( 0x7C, ( _inp( 0x7C) | 0x80)); return; case ATI_VIDEODECODER_CONFIG_4: if( bEnable) _outp( 0x78, ( _inp( 0x78) & 0xF7)); else _outp( 0x78, ( _inp( 0x78) | 0x08)); return; #endif default: break; } } /*^^* * GetI2CExpanderConfiguration() * Purpose : Gets board configuration via I2C expander * Reads the configuration registers back * Inputs : CI2CScript * pCScript : pointer to CI2CScript object * PUCHAR puchI2CValue : pointer to read the I2C value into * * Outputs : BOOL : returns TRUE * also sets the requested values into the input pointers * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::GetI2CExpanderConfiguration( CI2CScript * pCScript, PUCHAR puchI2CValue) { I2CPacket i2cPacket; if( puchI2CValue == NULL) return( FALSE); i2cPacket.uchChipAddress = m_uchI2CExpanderAddress; i2cPacket.cbReadCount = 1; i2cPacket.cbWriteCount = 0; i2cPacket.puchReadBuffer = puchI2CValue; i2cPacket.puchWriteBuffer = NULL; i2cPacket.usFlags = 0; pCScript->ExecuteI2CPacket( &i2cPacket); return(( i2cPacket.uchI2CResult == I2C_STATUS_NOERROR) ? TRUE : FALSE); } /*^^* * FindI2CExpanderAddress() * Purpose : Determines I2C expander address. * * Inputs : CI2CScript * pCScript : pointer to the I2CScript class object * * Outputs : BOOL : returns TRUE, if no I2C access error; * also sets m_uchI2CExpanderAddress class member. If any was not found, set it as 0xFF * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::FindI2CExpanderAddress( CI2CScript * pCScript) { USHORT nIndex; UCHAR uchI2CValue; I2CPacket i2cPacket; // table of the possible I2C expender addresses UCHAR auchI2CExpenderAddress[] = { 0x70, 0x78, 0x7c, 0x76}; // unknown I2C expender address m_uchI2CExpanderAddress = 0xFF; for( nIndex = 0; nIndex < sizeof( auchI2CExpenderAddress); nIndex ++) { i2cPacket.uchChipAddress = auchI2CExpenderAddress[nIndex]; i2cPacket.cbReadCount = 1; i2cPacket.cbWriteCount = 0; i2cPacket.puchReadBuffer = &uchI2CValue; i2cPacket.puchWriteBuffer = NULL; i2cPacket.usFlags = 0; pCScript->ExecuteI2CPacket( &i2cPacket); if( i2cPacket.uchI2CResult == I2C_STATUS_NOERROR) { m_uchI2CExpanderAddress = auchI2CExpenderAddress[nIndex]; break; } } OutputDebugInfo(( "CATIHwConfig:FindI2CExpanderAddress() exit address = %x\n", m_uchI2CExpanderAddress)); return( TRUE); } /*^^* * GetAudioProperties() * Purpose : Gets numbers of Audio inputs and outputs * Inputs : PULONG pulNumberOfInputs : pointer to return number of Audio inputs * PULONG pulNumberOfOutputs : pointer to return number of Audio outputs * * Outputs : BOOL : returns TRUE * also sets the requested values into the input pointers * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::GetAudioProperties( PULONG pulNumberOfInputs, PULONG pulNumberOfOutputs) { if(( pulNumberOfInputs != NULL) && ( pulNumberOfOutputs != NULL)) { // Hardcoded for AIW with no FM support - FM stuff has not been defined by Microsoft yet * pulNumberOfInputs = 2; * pulNumberOfOutputs = 1; return( TRUE); } else return( FALSE); } /*^^* * CanConnectAudioSource() * Purpose : Determines possibility to connect the specified Audio source to the audio output. * * Inputs : int nAudioSource : the audio source the function is asked about * * Outputs : BOOL : returns TRUE, the connection is possible; * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::CanConnectAudioSource( int nAudioSource) { BOOL bResult; if( nAudioSource != AUDIOSOURCE_MUTE) bResult = nAudioSource < AUDIOSOURCE_LASTSUPPORTED; else switch( m_uiAudioConfiguration) { case ATI_AUDIO_CONFIG_1: case ATI_AUDIO_CONFIG_2: case ATI_AUDIO_CONFIG_4: case ATI_AUDIO_CONFIG_5: case ATI_AUDIO_CONFIG_6: case ATI_AUDIO_CONFIG_7: case ATI_AUDIO_CONFIG_8: bResult = TRUE; break; case ATI_AUDIO_CONFIG_3: default: bResult = FALSE; break; } return( bResult); } /*^^* * SetDefaultVolumeControl() * Purpose : Set the default volume level, if the hardware support volume control * * Inputs : CI2CScript * pCScript : pointer to I2CScript class object * * Outputs : BOOL : returns FALSE, if either unknown audio source or I2C access error; * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::SetDefaultVolumeControl( CI2CScript * pCScript) { BOOL bResult; I2CPacket i2cPacket; UCHAR uchWriteBuffer[3]; switch( m_uiAudioConfiguration) { case ATI_AUDIO_CONFIG_4: ENSURE { i2cPacket.uchChipAddress = m_uchAudioAddress; i2cPacket.cbReadCount = 0; i2cPacket.cbWriteCount = 3; i2cPacket.puchReadBuffer = NULL; i2cPacket.puchWriteBuffer = uchWriteBuffer; i2cPacket.usFlags = I2COPERATION_WRITE; uchWriteBuffer[0] = 0x00; // volume left + right uchWriteBuffer[1] = 0xFA; uchWriteBuffer[2] = 0xFA; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); } END_ENSURE; break; default: bResult = TRUE; break; } return( bResult); } /*^^* * ConnectAudioSource() * Purpose : Connects the specified Audio input to the Audio output. * * Inputs : CI2CScript * pCScript : pointer to I2CScript class object * int nAudioSource : the audio source to be connected to the audio output * * Outputs : BOOL : returns FALSE, if either unknown audio source or I2C access error; * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::ConnectAudioSource( CI2CScript * pCScript, int nAudioSource) { UCHAR uchORMask = 0; UCHAR uchANDMask = 0xFF; UCHAR uchReadValue, uchWriteValue[2]; UCHAR uchWrite16Value[5]; I2CPacket i2cPacket; BOOL bI2CAccess, bResult; GPIOControl gpioAccessBlock; UCHAR uchI2CAddr; USHORT cbWRCount; USHORT cbRDCount; USHORT usI2CMode; switch( m_uiAudioConfiguration) { case ATI_AUDIO_CONFIG_1: bI2CAccess = TRUE; uchI2CAddr = m_uchI2CExpanderAddress; cbWRCount = 1; cbRDCount = 1; usI2CMode = I2COPERATION_READWRITE; uchANDMask &= 0xAF; switch( nAudioSource) { case AUDIOSOURCE_MUTE: uchORMask |= 0x00; break; case AUDIOSOURCE_TVAUDIO: uchORMask |= 0x10; break; case AUDIOSOURCE_LINEIN: uchORMask |= 0x50; break; case AUDIOSOURCE_FMAUDIO: // no FM is supported default: return( FALSE); } break; case ATI_AUDIO_CONFIG_2: bI2CAccess = FALSE; uchANDMask &= 0xFC; switch( nAudioSource) { case AUDIOSOURCE_MUTE: uchORMask |= 0x02; break; case AUDIOSOURCE_TVAUDIO: uchORMask |= 0x01; break; case AUDIOSOURCE_LINEIN: uchORMask |= 0x00; break; case AUDIOSOURCE_FMAUDIO: uchORMask |= 0x03; default: return( FALSE); } break; case ATI_AUDIO_CONFIG_3: bI2CAccess = TRUE; uchI2CAddr = m_uchI2CExpanderAddress; cbWRCount = 1; cbRDCount = 1; usI2CMode = I2COPERATION_READWRITE; uchANDMask &= 0xDF; switch( nAudioSource) { case AUDIOSOURCE_TVAUDIO: uchORMask |= 0x00; break; case AUDIOSOURCE_LINEIN: uchORMask |= 0x40; break; case AUDIOSOURCE_FMAUDIO: // no FM is supported case AUDIOSOURCE_MUTE: // no mute is supported default: return( FALSE); } break; case ATI_AUDIO_CONFIG_4: bI2CAccess = TRUE; uchI2CAddr = m_uchAudioAddress; cbWRCount = 2; cbRDCount = 0; usI2CMode = I2COPERATION_WRITE; uchWriteValue[0] = 0x08; switch( nAudioSource) { case AUDIOSOURCE_MUTE: uchWriteValue[1] = 0xF7; break; case AUDIOSOURCE_TVAUDIO: SetDefaultVolumeControl( pCScript); uchWriteValue[1] = 0xD7; break; case AUDIOSOURCE_LINEIN: SetDefaultVolumeControl( pCScript); uchWriteValue[1] = 0xCE; break; case AUDIOSOURCE_FMAUDIO: // no FM is supported default: return( FALSE); } break; case ATI_AUDIO_CONFIG_5: bI2CAccess = TRUE; uchI2CAddr = m_uchI2CExpanderAddress; cbWRCount = 1; cbRDCount = 1; usI2CMode = I2COPERATION_READWRITE; uchANDMask &= 0xAF; switch( nAudioSource) { case AUDIOSOURCE_MUTE: uchORMask |= 0x50; break; case AUDIOSOURCE_TVAUDIO: uchORMask |= 0x00; break; case AUDIOSOURCE_LINEIN: uchORMask |= 0x40; break; case AUDIOSOURCE_FMAUDIO: uchORMask |= 0x10; default: return( FALSE); } break; case ATI_AUDIO_CONFIG_6: case ATI_AUDIO_CONFIG_7: bI2CAccess = TRUE; uchI2CAddr = m_uchDecoderAddress; cbWRCount = 2; cbRDCount = 1; usI2CMode = I2COPERATION_READWRITE; uchWriteValue[0] = 0x3F; uchANDMask &= 0xFC; switch( nAudioSource) { case AUDIOSOURCE_MUTE: uchORMask |= 0x02; break; case AUDIOSOURCE_TVAUDIO: uchORMask |= 0x01; break; case AUDIOSOURCE_LINEIN: uchORMask |= 0x00; break; case AUDIOSOURCE_FMAUDIO: uchORMask |= 0x03; default: return( FALSE); } break; case ATI_AUDIO_CONFIG_8: switch( nAudioSource) { case AUDIOSOURCE_MUTE: i2cPacket.uchChipAddress = m_uchAudioAddress; i2cPacket.cbReadCount = 0; i2cPacket.cbWriteCount = 5; i2cPacket.usFlags = I2COPERATION_WRITE; i2cPacket.puchWriteBuffer = uchWrite16Value; //SubAddr 0x12 Reg 0x13 Val 0x3f60 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x13; uchWrite16Value[3] = 0x3f; uchWrite16Value[4] = 0x60; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0xD Val 0x0000 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x0d; uchWrite16Value[3] = 0x00; uchWrite16Value[4] = 0x00; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0x8 Val 0x0220 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x08; uchWrite16Value[3] = 0x02; uchWrite16Value[4] = 0x20; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0x00 Val 0x0000 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x00; uchWrite16Value[3] = 0x00; uchWrite16Value[4] = 0x00; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); break; case AUDIOSOURCE_LINEIN: i2cPacket.uchChipAddress = m_uchAudioAddress; i2cPacket.cbReadCount = 0; i2cPacket.cbWriteCount = 5; i2cPacket.usFlags = I2COPERATION_WRITE; i2cPacket.puchWriteBuffer = uchWrite16Value; //SubAddr 0x10 Reg 0x30 Val 0x0000 uchWrite16Value[0] = 0x10; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x30; uchWrite16Value[3] = 0x00; #ifdef I2S_CAPTURE #pragma message ("\n!!! PAY ATTENTION: Driver has been build with ITT CHIP I2S CAPTURE CONFIGURED !!!\n") uchWrite16Value[4] = 0xe0; #else uchWrite16Value[4] = 0x00; #endif bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x10 Reg 0x20 Val 0x0000 uchWrite16Value[0] = 0x10; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x20; uchWrite16Value[3] = 0x00; uchWrite16Value[4] = 0x00; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0xe Val 0x0000 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x0e; uchWrite16Value[3] = 0x00; uchWrite16Value[4] = 0x00; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0x13 Val 0x3c40 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x13; uchWrite16Value[3] = 0x3c; uchWrite16Value[4] = 0x40; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0x8 Val 0x3c40 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x08; uchWrite16Value[3] = 0x02; uchWrite16Value[4] = 0x20; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0xd Val 0x1900 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x0d; uchWrite16Value[3] = 0x19; uchWrite16Value[4] = 0x00; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0x00 Val 0x7300 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x00; uchWrite16Value[3] = 0x73; uchWrite16Value[4] = 0x00; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); break; case AUDIOSOURCE_TVAUDIO: i2cPacket.uchChipAddress = m_uchAudioAddress; i2cPacket.cbReadCount = 0; i2cPacket.cbWriteCount = 5; i2cPacket.usFlags = I2COPERATION_WRITE; i2cPacket.puchWriteBuffer = uchWrite16Value; //SubAddr 0x12 Reg 0x13 Val 0x3f60 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x13; uchWrite16Value[3] = 0x3f; uchWrite16Value[4] = 0x60; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0xD Val 0x0000 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x0d; uchWrite16Value[3] = 0x00; uchWrite16Value[4] = 0x00; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x10 Reg 0x30 Val 0x2003 uchWrite16Value[0] = 0x10; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x30; uchWrite16Value[3] = 0x20; #ifdef I2S_CAPTURE #pragma message ("\n!!! PAY ATTENTION: Driver has been build with ITT CHIP I2S CAPTURE CONFIGURED !!!\n") uchWrite16Value[4] = 0xe3; #else uchWrite16Value[4] = 0x03; #endif bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x10 Reg 0x20 Val 0x0020 uchWrite16Value[0] = 0x10; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x20; uchWrite16Value[3] = 0x00; uchWrite16Value[4] = 0x20; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0xE Val 0x2403 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x0e; uchWrite16Value[3] = 0x24; uchWrite16Value[4] = 0x03; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0x08 Val 0x0320 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x08; uchWrite16Value[3] = 0x03; uchWrite16Value[4] = 0x20; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); //SubAddr 0x12 Reg 0x00 Val 0x7300 uchWrite16Value[0] = 0x12; uchWrite16Value[1] = 0x00; uchWrite16Value[2] = 0x00; uchWrite16Value[3] = 0x73; uchWrite16Value[4] = 0x00; bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); if(bResult) { if( i2cPacket.uchI2CResult != I2CSCRIPT_NOERROR) return(FALSE); } else return(FALSE); break; default: return(FALSE); }//switch return(TRUE); //break; default : return( FALSE); } if( bI2CAccess) { if( pCScript == NULL) return( FALSE); i2cPacket.uchChipAddress = uchI2CAddr; i2cPacket.cbReadCount = cbRDCount; i2cPacket.cbWriteCount = cbWRCount; i2cPacket.puchReadBuffer = &uchReadValue; i2cPacket.puchWriteBuffer = uchWriteValue; i2cPacket.usFlags = usI2CMode; i2cPacket.uchORValue = uchORMask; i2cPacket.uchANDValue = uchANDMask; // synchronous execution bResult = pCScript->PerformI2CPacketOperation( &i2cPacket); OutputDebugInfo(( "CATIHwConfig: ConnectAudioSource( %d) = %d\n", nAudioSource, bResult)); if( bResult) bResult = ( i2cPacket.uchI2CResult == I2CSCRIPT_NOERROR); return( bResult); } else { // use GPIO interface to switch Audio source bResult = FALSE; ENSURE { if(( m_gpioProviderInterface.gpioOpen == NULL) || ( m_gpioProviderInterface.gpioAccess == NULL)) FAIL; uchReadValue = AUDIO_MUX_PINS; // use as a PinMask gpioAccessBlock.Pins = &uchReadValue; gpioAccessBlock.Flags = GPIO_FLAGS_BYTE; gpioAccessBlock.nBytes = 1; gpioAccessBlock.nBufferSize = 1; gpioAccessBlock.AsynchCompleteCallback = NULL; // lock GPIO provider if( !LockGPIOProviderEx( &gpioAccessBlock)) FAIL; uchReadValue = AUDIO_MUX_PINS; // use as a PinMask gpioAccessBlock.Command = GPIO_COMMAND_READ_BUFFER; gpioAccessBlock.Flags = GPIO_FLAGS_BYTE; gpioAccessBlock.dwCookie = m_dwGPIOAccessKey; gpioAccessBlock.nBytes = 1; gpioAccessBlock.nBufferSize = 1; gpioAccessBlock.Pins = &uchReadValue; gpioAccessBlock.Buffer = uchWriteValue; gpioAccessBlock.AsynchCompleteCallback = NULL; if( !AccessGPIOProvider( m_pdoDriver, &gpioAccessBlock)) FAIL; uchWriteValue[0] &= uchANDMask; uchWriteValue[0] |= uchORMask; gpioAccessBlock.Command = GPIO_COMMAND_WRITE_BUFFER; if( !AccessGPIOProvider( m_pdoDriver, &gpioAccessBlock)) FAIL; bResult = TRUE; }END_ENSURE; // nothing bad will happen if we try to release the provider even we // have not obtained it at the first place uchReadValue = AUDIO_MUX_PINS; // use as a PinMask gpioAccessBlock.Pins = &uchReadValue; gpioAccessBlock.Flags = GPIO_FLAGS_BYTE; gpioAccessBlock.nBytes = 1; gpioAccessBlock.nBufferSize = 1; gpioAccessBlock.AsynchCompleteCallback = NULL; ReleaseGPIOProvider( &gpioAccessBlock); return( bResult); } } /*^^* * GPIOIoSynchCompletionRoutine() * Purpose : This routine is for use with synchronous IRP processing. * All it does is signal an event, so the driver knows it and can continue. * * Inputs : PDEVICE_OBJECT DriverObject : Pointer to driver object created by system * PIRP pIrp : Irp that just completed * PVOID Event : Event we'll signal to say Irp is done * * Outputs : none * Author : IKLEBANOV *^^*/ extern "C" NTSTATUS GPIOIoSynchCompletionRoutine( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID Event) { KeSetEvent(( PKEVENT)Event, 0, FALSE); return( STATUS_MORE_PROCESSING_REQUIRED); } /*^^* * InitializeAttachGPIOProvider() * Purpose : determines the pointer to the parent GPIO Provider interface * This function will be called at Low priority * * Inputs : GPIOINTERFACE * pGPIOInterface : pointer to the Interface to be filled in * PDEVICE_OBJECT pDeviceObject : MiniDriver device object, which is a child of GPIO Master * * Outputs : BOOL - returns TRUE, if the interface was found * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::InitializeAttachGPIOProvider( GPIOINTERFACE * pGPIOInterface, PDEVICE_OBJECT pDeviceObject) { BOOL bResult; bResult = LocateAttachGPIOProvider( pGPIOInterface, pDeviceObject, IRP_MJ_PNP); if(( pGPIOInterface->gpioOpen == NULL) || ( pGPIOInterface->gpioAccess == NULL)) { OutputDebugError(( "CATIHwConfig(): GPIO interface has NULL pointers\n")); bResult = FALSE; } return( bResult); } /*^^* * LocateAttachGPIOProvider() * Purpose : gets the pointer to the parent GPIO Provider interface * This function will be called at Low priority * * Inputs : GPIOINTERFACE * pGPIOInterface : pointer to the Interface to be filled in * PDEVICE_OBJECT pDeviceObject : MiniDriver device object, which is a child of I2C Master * int nIrpMajorFunction : IRP major function to query the GPIO Interface * * Outputs : BOOL - returns TRUE, if the interface was found * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::LocateAttachGPIOProvider( GPIOINTERFACE * pGPIOInterface, PDEVICE_OBJECT pDeviceObject, UCHAR nIrpMajorFunction) { PIRP pIrp; BOOL bResult = FALSE; ENSURE { PIO_STACK_LOCATION pNextStack; NTSTATUS ntStatus; KEVENT Event; pIrp = IoAllocateIrp( pDeviceObject->StackSize, FALSE); if( pIrp == NULL) { OutputDebugError(( "CATIHwConfig(): can not allocate IRP\n")); FAIL; } pNextStack = IoGetNextIrpStackLocation( pIrp); if( pNextStack == NULL) { OutputDebugError(( "CATIHwConfig(): can not allocate NextStack\n")); FAIL; } pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED; pNextStack->MajorFunction = nIrpMajorFunction; pNextStack->MinorFunction = IRP_MN_QUERY_INTERFACE; KeInitializeEvent( &Event, NotificationEvent, FALSE); IoSetCompletionRoutine( pIrp, GPIOIoSynchCompletionRoutine, &Event, TRUE, TRUE, TRUE); pNextStack->Parameters.QueryInterface.InterfaceType = ( struct _GUID *)&GUID_GPIO_INTERFACE; pNextStack->Parameters.QueryInterface.Size = sizeof( GPIOINTERFACE); pNextStack->Parameters.QueryInterface.Version = 1; pNextStack->Parameters.QueryInterface.Interface = ( PINTERFACE)pGPIOInterface; pNextStack->Parameters.QueryInterface.InterfaceSpecificData = NULL; ntStatus = IoCallDriver( pDeviceObject, pIrp); if( ntStatus == STATUS_PENDING) KeWaitForSingleObject( &Event, Suspended, KernelMode, FALSE, NULL); if(( pGPIOInterface->gpioOpen == NULL) || ( pGPIOInterface->gpioAccess == NULL)) FAIL; bResult = TRUE; } END_ENSURE; if( pIrp != NULL) IoFreeIrp( pIrp); return( bResult); } /*^^* * LockGPIOProviderEx() * Purpose : locks the GPIOProvider for exclusive use * * Inputs : PGPIOControl pgpioAccessBlock : pointer to GPIO control structure * * Outputs : BOOL : retunrs TRUE, if the GPIOProvider is locked * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::LockGPIOProviderEx( PGPIOControl pgpioAccessBlock) { NTSTATUS ntStatus; LARGE_INTEGER liStartTime, liCurrentTime; KeQuerySystemTime( &liStartTime); ENSURE { if(( m_gpioProviderInterface.gpioOpen == NULL) || ( m_gpioProviderInterface.gpioAccess == NULL) || ( m_pdoDriver == NULL)) FAIL; pgpioAccessBlock->Status = GPIO_STATUS_NOERROR; pgpioAccessBlock->Command = GPIO_COMMAND_OPEN_PINS; while( TRUE) { KeQuerySystemTime( &liCurrentTime); if(( liCurrentTime.QuadPart - liStartTime.QuadPart) >= GPIO_TIMELIMIT_OPENPROVIDER) { // time has expired for attempting to lock GPIO provider return (FALSE); } ntStatus = m_gpioProviderInterface.gpioOpen( m_pdoDriver, TRUE, pgpioAccessBlock); if(( NT_SUCCESS( ntStatus)) && ( pgpioAccessBlock->Status == GPIO_STATUS_NOERROR)) break; } // the GPIO Provider has granted access - save dwCookie for further use m_dwGPIOAccessKey = pgpioAccessBlock->dwCookie; return( TRUE); } END_ENSURE; return( FALSE); } /*^^* * ReleaseGPIOProvider() * Purpose : releases the GPIOProvider for other clients' use * * Inputs : PGPIOControl pgpioAccessBlock : pointer to a composed GPIO access block * * Outputs : BOOL : retunrs TRUE, if the GPIOProvider is released * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::ReleaseGPIOProvider( PGPIOControl pgpioAccessBlock) { NTSTATUS ntStatus; ENSURE { if(( m_gpioProviderInterface.gpioOpen == NULL) || ( m_gpioProviderInterface.gpioAccess == NULL) || ( m_pdoDriver == NULL)) FAIL; pgpioAccessBlock->Status = GPIO_STATUS_NOERROR; pgpioAccessBlock->Command = GPIO_COMMAND_CLOSE_PINS; pgpioAccessBlock->dwCookie = m_dwGPIOAccessKey; ntStatus = m_gpioProviderInterface.gpioOpen( m_pdoDriver, FALSE, pgpioAccessBlock); if( !NT_SUCCESS( ntStatus)) { OutputDebugError(( "CATIHwConfig: ReleaseGPIOProvider() NTSTATUS = %x\n", ntStatus)); FAIL; } if( pgpioAccessBlock->Status != GPIO_STATUS_NOERROR) { OutputDebugError(( "CATIHwConfig: ReleaseGPIOProvider() Status = %x\n", pgpioAccessBlock->Status)); FAIL; } m_dwGPIOAccessKey = 0; return ( TRUE); } END_ENSURE; return( FALSE); } /*^^* * AccessGPIOProvider() * Purpose : provide synchronous type of access to GPIOProvider * * Inputs : PDEVICE_OBJECT pdoDriver : pointer to the client's device object * PGPIOControl pgpioAccessBlock : pointer to a composed GPIO access block * * Outputs : BOOL, TRUE if acsepted by the GPIO Provider * * Author : IKLEBANOV *^^*/ BOOL CATIHwConfiguration::AccessGPIOProvider( PDEVICE_OBJECT pdoClient, PGPIOControl pgpioAccessBlock) { NTSTATUS ntStatus; ENSURE { if(( m_gpioProviderInterface.gpioOpen == NULL) || ( m_gpioProviderInterface.gpioAccess == NULL) || ( m_pdoDriver == NULL)) FAIL; ntStatus = m_gpioProviderInterface.gpioAccess( pdoClient, pgpioAccessBlock); if( !NT_SUCCESS( ntStatus)) { OutputDebugError(( "CATIHwConfig: AccessGPIOProvider() NTSTATUS = %x\n", ntStatus)); FAIL; } if( pgpioAccessBlock->Status != GPIO_STATUS_NOERROR) { OutputDebugError(( "CATIHwConfig: AccessGPIOProvider() Status = %x\n", pgpioAccessBlock->Status)); FAIL; } return TRUE; } END_ENSURE; return( FALSE); } /*^^* * SetTunerPowerState * Purpose : Sets Tuner power mode * Inputs : CI2CScript * pCScript : pointer to the I2C Provider class * BOOL bPowerState : TRUE, if turne the power on * * Outputs : BOOL, TRUE if successfull * Author : TOM *^^*/ BOOL CATIHwConfiguration::SetTunerPowerState( CI2CScript * pCScript, BOOL bPowerState) { UCHAR uchORMask = 0x0; UCHAR uchANDMask = 0xFF; UCHAR uchPinsMask, uchValue; BOOL bResult; GPIOControl gpioAccessBlock; switch( m_usTunerPowerConfiguration) { case ATI_TUNER_POWER_CONFIG_1: if( bPowerState) uchANDMask &= 0xF7; else uchORMask |= 0x08; break; default : return( FALSE); } // use GPIO interface to turn Tuner power ON / OFF bResult = FALSE; ENSURE { if(( m_gpioProviderInterface.gpioOpen == NULL) || ( m_gpioProviderInterface.gpioAccess == NULL)) FAIL; uchPinsMask = TUNER_PM_PINS; // use as a PinMask gpioAccessBlock.Pins = &uchPinsMask; gpioAccessBlock.Flags = GPIO_FLAGS_BYTE; gpioAccessBlock.nBytes = 1; gpioAccessBlock.nBufferSize = 1; gpioAccessBlock.AsynchCompleteCallback = NULL; // try to get GPIO Provider if( !LockGPIOProviderEx( &gpioAccessBlock)) FAIL; uchPinsMask = TUNER_PM_PINS; // use as a PinMask gpioAccessBlock.Command = GPIO_COMMAND_READ_BUFFER; gpioAccessBlock.Flags = GPIO_FLAGS_BYTE; gpioAccessBlock.dwCookie = m_dwGPIOAccessKey; gpioAccessBlock.nBytes = 1; gpioAccessBlock.nBufferSize = 1; gpioAccessBlock.Pins = &uchPinsMask; gpioAccessBlock.Buffer = &uchValue; gpioAccessBlock.AsynchCompleteCallback = NULL; if( !AccessGPIOProvider( m_pdoDriver, &gpioAccessBlock)) FAIL; uchValue &= uchANDMask; uchValue |= uchORMask; gpioAccessBlock.Command = GPIO_COMMAND_WRITE_BUFFER; if( !AccessGPIOProvider( m_pdoDriver, &gpioAccessBlock)) FAIL; bResult = TRUE; } END_ENSURE; // nothing bad will happen if we try to release the provider even we // have not obtained it at the first place uchValue = TUNER_PM_PINS; // use as a PinMask gpioAccessBlock.Pins = &uchValue; gpioAccessBlock.Flags = GPIO_FLAGS_BYTE; gpioAccessBlock.nBytes = 1; gpioAccessBlock.nBufferSize = 1; gpioAccessBlock.AsynchCompleteCallback = NULL; ReleaseGPIOProvider( &gpioAccessBlock); return( bResult); } /*^^* * ValidateConfigurationE2PROM * Purpose : Checks the integrity ( check-sum) of I2C driven configuration EEPROM * Inputs : CI2CScript * pCScript : pointer to the I2C Provider class * * Outputs : BOOL, TRUE if the information inside EEPROM is valid * Author : TOM *^^*/ BOOL CATIHwConfiguration::ValidateConfigurationE2PROM( CI2CScript * pCScript) { I2CPacket i2cPacket; UCHAR uchReadValue=0, uchWriteValue, uchCheckSum=0; UINT nIndex; BOOL bResult = ( BOOL)m_usE2PROMValidation; if( m_usE2PROMValidation == ( USHORT)-1) { // the validation has not been done yet. bResult = FALSE; ENSURE { // Let's always start from byte 0. i2cPacket.uchChipAddress = AIWPRO_CONFIGURATIONE2PROM_ADDRESS; i2cPacket.cbWriteCount = 1; i2cPacket.cbReadCount = 1; i2cPacket.puchReadBuffer = &uchCheckSum; uchWriteValue = 0; i2cPacket.puchWriteBuffer = &uchWriteValue; i2cPacket.usFlags = I2COPERATION_READ | I2COPERATION_RANDOMACCESS; if( !pCScript->ExecuteI2CPacket( &i2cPacket)) FAIL; for( nIndex = 1; nIndex < AIWPRO_CONFIGURATIONE2PROM_LENGTH; nIndex ++) { // let's use auto-increment address mode i2cPacket.usFlags = I2COPERATION_READ; i2cPacket.cbWriteCount = 0; i2cPacket.puchWriteBuffer = NULL; i2cPacket.puchReadBuffer = &uchReadValue; if( !pCScript->ExecuteI2CPacket( &i2cPacket)) FAIL; uchCheckSum ^= uchReadValue; } if( nIndex != AIWPRO_CONFIGURATIONE2PROM_LENGTH) FAIL; bResult = ( uchCheckSum == 0); } END_ENSURE; m_usE2PROMValidation = ( USHORT)bResult; } return( bResult); } /*^^* * ReadConfigurationE2PROM * Purpose : Reads a single byte from I2C driver configuration EEPROM by offset * Inputs : CI2CScript * pCScript : pointer to the I2C Provider class * ULONG ulOffset : byte offset within the EEPROM * PUCHAR puchValue : pointer to the buffer to read into * * Outputs : BOOL, TRUE if I2C read operation succeeded * Author : TOM *^^*/ BOOL CATIHwConfiguration::ReadConfigurationE2PROM( CI2CScript * pCScript, ULONG ulOffset, PUCHAR puchValue) { I2CPacket i2cPacket; UCHAR uchReadValue=0, uchWriteValue; ENSURE { if( ulOffset >= AIWPRO_CONFIGURATIONE2PROM_LENGTH) FAIL; uchWriteValue = ( UCHAR)ulOffset; i2cPacket.uchChipAddress = AIWPRO_CONFIGURATIONE2PROM_ADDRESS; i2cPacket.cbWriteCount = 1; i2cPacket.cbReadCount = 1; i2cPacket.puchReadBuffer = &uchReadValue; i2cPacket.puchWriteBuffer = &uchWriteValue; i2cPacket.usFlags = I2COPERATION_READ | I2COPERATION_RANDOMACCESS; if( !pCScript->ExecuteI2CPacket( &i2cPacket)) FAIL; * puchValue = uchReadValue; return( TRUE); } END_ENSURE; return( FALSE); } //Paul ULONG CATIHwConfiguration::ReturnTunerVideoStandard( USHORT usTunerId ) //Paul: For PAL support { switch( usTunerId ) { case 1: return KS_AnalogVideo_NTSC_M; break; case 2: return KS_AnalogVideo_NTSC_M_J; break; case 3: return KS_AnalogVideo_PAL_B | KS_AnalogVideo_PAL_G; break; case 4: return KS_AnalogVideo_PAL_I; break; case 5: return KS_AnalogVideo_PAL_B | KS_AnalogVideo_PAL_G | KS_AnalogVideo_SECAM_L | KS_AnalogVideo_SECAM_L1; break; case 6: return KS_AnalogVideo_NTSC_M; break; case 7: return KS_AnalogVideo_SECAM_D | KS_AnalogVideo_SECAM_K; break; case 8: return KS_AnalogVideo_NTSC_M; break; case 9: return KS_AnalogVideo_PAL_B | KS_AnalogVideo_PAL_G; break; case 10: return KS_AnalogVideo_PAL_I; break; case 11: return KS_AnalogVideo_PAL_B | KS_AnalogVideo_PAL_G | KS_AnalogVideo_SECAM_L | KS_AnalogVideo_SECAM_L1; break; case 12: return KS_AnalogVideo_NTSC_M; break; case 13: return KS_AnalogVideo_PAL_B | KS_AnalogVideo_PAL_D | KS_AnalogVideo_PAL_G | KS_AnalogVideo_PAL_I | KS_AnalogVideo_SECAM_D | KS_AnalogVideo_SECAM_K; break; case 14: return 0; break; case 15: return 0; break; case 16: return KS_AnalogVideo_NTSC_M; break; case 17: return KS_AnalogVideo_NTSC_M; break; case 18: return KS_AnalogVideo_NTSC_M; break; default: return 0; // if we don't recognize the tuner, we say that no video standard is supported } } //Paul // bit 5 indicates the number of crystals installed. 0 means we have 2 crystals, // 1 means we only have 1, so the tuner determines the standard ULONG CATIHwConfiguration::SetVidStdBasedOnI2CExpander( UCHAR ucI2CValue ) { if ( ucI2CValue & 0x20 ) // only 1 crystal { ULONG ulTunerStd = ReturnTunerVideoStandard( ucI2CValue & 0x0F ); if ( ulTunerStd & ( KS_AnalogVideo_NTSC_Mask & ~KS_AnalogVideo_NTSC_433 | KS_AnalogVideo_PAL_60 ) ) // Then we should have NTSC-type crystal { return KS_AnalogVideo_NTSC_Mask & ~KS_AnalogVideo_NTSC_433 | KS_AnalogVideo_PAL_60 | KS_AnalogVideo_PAL_M | KS_AnalogVideo_PAL_N; } else { return KS_AnalogVideo_PAL_Mask & ~KS_AnalogVideo_PAL_60 & ~KS_AnalogVideo_PAL_M & ~KS_AnalogVideo_PAL_N | KS_AnalogVideo_SECAM_Mask | KS_AnalogVideo_NTSC_433; } } else return KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_Mask | KS_AnalogVideo_SECAM_Mask; // we support all standards (is this testable?) } //Paul // The Video In crystal type in MMTable will tell us whether we support NTSC, PAL/SECAM, or both ULONG CATIHwConfiguration::SetVidStdBasedOnMMTable( CATIMultimediaTable * pCMultimediaInfo ) { if ( pCMultimediaInfo ) { if ( pCMultimediaInfo->GetVideoInCrystalId( &m_CrystalIDInMMTable ) ) { switch ( m_CrystalIDInMMTable ) { // "NTSC and PAL Crystals Installed (for Bt8xx)" case 0: return KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_Mask; // may need to add SECAM. We will see break; // "NTSC Crystal Only (for Bt8xx)" case 1: return KS_AnalogVideo_NTSC_Mask & ~KS_AnalogVideo_NTSC_433 | KS_AnalogVideo_PAL_60 | KS_AnalogVideo_PAL_M | KS_AnalogVideo_PAL_N; // standards that use "NTSC" clock break; // "PAL Crystal Only (for Bt8xx)" case 2: return KS_AnalogVideo_PAL_Mask & ~KS_AnalogVideo_PAL_60 & ~KS_AnalogVideo_PAL_M & ~KS_AnalogVideo_PAL_N | KS_AnalogVideo_SECAM_Mask | KS_AnalogVideo_NTSC_433; // standards that use "PAL" clock break; // "NTSC, PAL, SECAM (for Bt829)" case 3: return KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_Mask | KS_AnalogVideo_SECAM_Mask; break; } } } return 0; } //Paul: Used by RT WDM to determine the VIN PLL BOOL CATIHwConfiguration::GetMMTableCrystalID( PUCHAR pucCrystalID ) { if ( ( m_uchI2CExpanderAddress==0xFF ) || ( !pucCrystalID ) ) { return FALSE; } else { *pucCrystalID = m_CrystalIDInMMTable; return TRUE; } }