📄 common.cpp
字号:
DOUT (DBG_PROBE, ("5bit master out found"));
}
//
// Print debug output for quality of headphones volume.
//
if (GetPinConfig (PINC_HPOUT_PRESENT))
{
if (GetNodeConfig (NODEC_6BIT_HPOUT_VOLUME))
{
DOUT (DBG_PROBE, ("6bit headphone out found"));
}
else
{
DOUT (DBG_PROBE, ("5bit headphone out found"));
}
}
//
// Print debug output for quality of mono out volume.
//
if (GetPinConfig (PINC_MONOOUT_PRESENT))
{
if (GetNodeConfig (NODEC_6BIT_MONOOUT_VOLUME))
{
DOUT (DBG_PROBE, ("6bit mono out found"));
}
else
{
DOUT (DBG_PROBE, ("5bit mono out found"));
}
}
//
// Print sample rate information.
//
if (GetNodeConfig (NODEC_PCM_VARIABLERATE_SUPPORTED))
{
DOUT (DBG_PROBE, ("PCM variable sample rate supported"));
}
else
{
DOUT (DBG_PROBE, ("only 48KHz PCM supported"));
}
//
// Print double rate information.
//
if (GetNodeConfig (NODEC_PCM_DOUBLERATE_SUPPORTED))
{
DOUT (DBG_PROBE, ("PCM double sample rate supported"));
}
//
// Print mic rate information.
//
if (GetNodeConfig (NODEC_MIC_VARIABLERATE_SUPPORTED))
{
DOUT (DBG_PROBE, ("MIC variable sample rate supported"));
}
else
{
DOUT (DBG_PROBE, ("only 48KHz MIC supported"));
}
// print DAC information
if (GetNodeConfig (NODEC_CENTER_DAC_PRESENT))
{
DOUT (DBG_PROBE, ("center DAC found"));
}
if (GetNodeConfig (NODEC_SURROUND_DAC_PRESENT))
{
DOUT (DBG_PROBE, ("surround DAC found"));
}
if (GetNodeConfig (NODEC_LFE_DAC_PRESENT))
{
DOUT (DBG_PROBE, ("LFE DAC found"));
}
}
#endif
/*****************************************************************************
* CAdapterCommon::NonDelegatingQueryInterface
*****************************************************************************
* Obtains an interface. This function works just like a COM QueryInterface
* call and is used if the object is not being aggregated.
* We basically just check any GUID we know and return this object in case we
* know it.
*/
STDMETHODIMP_(NTSTATUS) CAdapterCommon::NonDelegatingQueryInterface
(
IN REFIID Interface,
OUT PVOID * Object
)
{
PAGED_CODE ();
ASSERT (Object);
DOUT (DBG_PRINT, ("[CAdapterCommon::NonDelegatingQueryInterface]"));
// Is it IID_IUnknown?
if (IsEqualGUIDAligned (Interface, IID_IUnknown))
{
*Object = (PVOID)(PUNKNOWN)(PADAPTERCOMMON)this;
}
else
// or IID_IAdapterCommon ...
if (IsEqualGUIDAligned (Interface, IID_IAdapterCommon))
{
*Object = (PVOID)(PADAPTERCOMMON)this;
}
else
// or IID_IAdapterPowerManagement ...
if (IsEqualGUIDAligned (Interface, IID_IAdapterPowerManagement))
{
*Object = (PVOID)(PADAPTERPOWERMANAGEMENT)this;
}
else
{
// nothing found, must be an unknown interface.
*Object = NULL;
return STATUS_INVALID_PARAMETER;
}
//
// We reference the interface for the caller.
//
((PUNKNOWN)*Object)->AddRef ();
return STATUS_SUCCESS;
}
/*****************************************************************************
* CAdapterCommon::InitAC97
*****************************************************************************
* Initialize the ICH (without hosing the modem if it got installed first).
*/
NTSTATUS CAdapterCommon::InitAC97 (void)
{
PAGED_CODE ();
DOUT (DBG_PRINT, ("[CAdapterCommon::InitAC97]"));
//
// First check if there is an AC link to the primary CoDec.
//
NTSTATUS ntStatus = PrimaryCodecReady ();
if (NT_SUCCESS (ntStatus))
{
//
// Second, reset this primary CoDec; If this is a AMC97 CoDec, only
// the audio registers are reset. If this is a MC97 CoDec, the CoDec
// should ignore the reset (according to the spec).
//
WriteCodecRegister (AC97REG_RESET, 0x00, -1);
ntStatus = PowerUpCodec ();
}
else
{
DOUT (DBG_ERROR, ("Initialization of AC97 CoDec failed."));
}
return ntStatus;
}
/*****************************************************************************
* CAdapterCommon::Check6thBitSupport
*****************************************************************************
* Probes for 6th bit volume control support.
* The passed parameters are the AC97 register that has the volume control and
* the node config that should be set in this case.
*/
NTSTATUS CAdapterCommon::Check6thBitSupport
(
IN AC97Register AC97Reg,
IN TopoNodeConfig Config
)
{
NTSTATUS ntStatus;
WORD wCodecReg;
WORD wOriginal;
// Read the current value.
ntStatus = ReadCodecRegister (AC97Reg, &wOriginal);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
// Write the 6th bit; for mono controls we write 0x20, for stereo
// controls 0x2020.
ntStatus = WriteCodecRegister (AC97Reg,
(AC97Reg == AC97REG_MMONO_VOLUME) ? 0x0020 : 0x2020, -1);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
// And read back.
ntStatus = ReadCodecRegister (AC97Reg, &wCodecReg);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
// Check return. For mono 0x20 and for stereo 0x2020.
if (((wCodecReg & 0x0020) && (AC97Reg == AC97REG_MMONO_VOLUME)) ||
(wCodecReg & 0x2020))
{
SetNodeConfig (Config, TRUE);
}
else
{
SetNodeConfig (Config, FALSE);
}
// Restore original value.
WriteCodecRegister (AC97Reg, wOriginal, -1);
return ntStatus;
}
/*****************************************************************************
* CAdapterCommon::ProbeHWConfig
*****************************************************************************
* Probes the hardware configuration.
* If this function returns with an error, then the configuration is not
* complete! Probing the registers is done by reading them (and comparing with
* the HW default value) or when the default is unknown, writing to them and
* reading back + restoring.
* Additionally, we read the registry so that a HW vendor can overwrite (means
* disable) found registers in case the adapter (e.g. video) is not visible to
* the user (he can't plug in a video audio there).
*
* This is a very long function with all of the error checking!
*/
NTSTATUS CAdapterCommon::ProbeHWConfig (void)
{
PAGED_CODE ();
NTSTATUS ntStatus = STATUS_SUCCESS;
DWORD dwGlobalStatus;
WORD wCodecID;
WORD wCodecReg;
DOUT (DBG_PRINT, ("[CAdapterCommon::ProbeHWConfig]"));
//
// Wait for the whatever 97 to complete reset and establish a link.
//
ntStatus = PrimaryCodecReady ();
if (!NT_SUCCESS (ntStatus))
return ntStatus;
//
// Master volume is one of the supported registers on an AC97
//
ntStatus = ReadCodecRegister (AC97REG_MASTER_VOLUME, &wCodecReg);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
// Default is x8000.
if (wCodecReg != 0x8000)
return STATUS_NO_SUCH_DEVICE;
//
// This gives us information about the AC97 CoDec
//
ntStatus = ReadCodecRegister (AC97REG_RESET, &wCodecID);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
//
// Fill out the configuration stuff.
//
SetPinConfig (PINC_MICIN_PRESENT, wCodecID & 0x0001);
// Check if OEM wants to disable MIC record line.
if (DisableAC97Pin (PINC_MICIN_PRESENT))
SetPinConfig (PINC_MICIN_PRESENT, FALSE);
// If we still have MIC record line, enable the DAC in ext. audio register.
if (GetPinConfig (PINC_MICIN_PRESENT))
// Enable ADC MIC.
WriteCodecRegister (AC97REG_EXT_AUDIO_CTRL, 0, 0x4000);
else
// Disable ADC MIC.
WriteCodecRegister (AC97REG_EXT_AUDIO_CTRL, 0x4000, 0x4000);
//
// Continue setting configuration information.
//
SetNodeConfig (NODEC_TONE_PRESENT, wCodecID & 0x0004);
SetNodeConfig (NODEC_SIMUL_STEREO_PRESENT, wCodecID & 0x0008);
SetPinConfig (PINC_HPOUT_PRESENT, wCodecID & 0x0010);
// Check if OEM wants to disable headphone output.
if (DisableAC97Pin (PINC_HPOUT_PRESENT))
SetPinConfig (PINC_HPOUT_PRESENT, FALSE);
SetNodeConfig (NODEC_LOUDNESS_PRESENT, wCodecID & 0x0020);
SetNodeConfig (NODEC_3D_PRESENT, wCodecID & 0x7C00);
//
// Test for the input pins that are always there but could be disabled
// by the HW vender
//
// Check if OEM wants to disable mic input.
SetPinConfig (PINC_MIC_PRESENT, !DisableAC97Pin (PINC_MIC_PRESENT));
// Check if OEM wants to disable line input.
SetPinConfig (PINC_LINEIN_PRESENT, !DisableAC97Pin (PINC_LINEIN_PRESENT));
// Check if OEM wants to disable CD input.
SetPinConfig (PINC_CD_PRESENT, !DisableAC97Pin (PINC_CD_PRESENT));
//
// For the rest, we have to probe the registers.
//
//
// Test for Mono out.
//
ntStatus = ReadCodecRegister (AC97REG_MMONO_VOLUME, &wCodecReg);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
// Default is x8000.
SetPinConfig (PINC_MONOOUT_PRESENT, (wCodecReg == 0x8000));
// Check if OEM wants to disable mono output.
if (DisableAC97Pin (PINC_MONOOUT_PRESENT))
SetPinConfig (PINC_MONOOUT_PRESENT, FALSE);
//
// Test for PC beeper support.
//
ntStatus = ReadCodecRegister (AC97REG_BEEP_VOLUME, &wCodecReg);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
// default is x0 or x8000. If it's 0x8000 then we know for sure that the
// CoDec has a PcBeep, otherwise we have to check the register
if (wCodecReg == 0x8000)
SetPinConfig (PINC_PCBEEP_PRESENT, TRUE);
else if (!wCodecReg)
{
// mute the pc beeper.
ntStatus = WriteCodecRegister (AC97REG_BEEP_VOLUME, 0x8000, -1);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
// read back
ntStatus = ReadCodecRegister (AC97REG_BEEP_VOLUME, &wCodecReg);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
if (wCodecReg == 0x8000)
{
// yep, we have support.
SetPinConfig (PINC_PCBEEP_PRESENT, TRUE);
// reset to default value.
WriteCodecRegister (AC97REG_BEEP_VOLUME, 0x0, -1);
}
else
// nope, not present
SetPinConfig (PINC_PCBEEP_PRESENT, FALSE);
}
else
// any other value then 0x0 and 0x8000.
SetPinConfig (PINC_PCBEEP_PRESENT, FALSE);
// Check if OEM wants to disable beeper support.
if (DisableAC97Pin (PINC_PCBEEP_PRESENT))
SetPinConfig (PINC_PCBEEP_PRESENT, FALSE);
//
// Test for phone support.
//
ntStatus = ReadCodecRegister (AC97REG_PHONE_VOLUME, &wCodecReg);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
// Default is x8008.
SetPinConfig (PINC_PHONE_PRESENT, (wCodecReg == 0x8008));
// Check if OEM wants to disable phone input.
if (DisableAC97Pin (PINC_PHONE_PRESENT))
SetPinConfig (PINC_PHONE_PRESENT, FALSE);
//
// Test for video support.
//
ntStatus = ReadCodecRegister (AC97REG_VIDEO_VOLUME, &wCodecReg);
if (!NT_SUCCESS (ntStatus))
return ntStatus;
// Default is x8808.
SetPinConfig (PINC_VIDEO_PRESENT, (wCodecReg == 0x8808));
// Check if OEM wants to disable video input.
if (DisableAC97Pin (PINC_VIDEO_PRESENT))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -