⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.cpp

📁 AC97 Sample Driver and Related Code Samples. This directory contains a sample AC97 adapter driver a
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        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 + -