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

📄 prophnd.cpp

📁 AC97 Sample Driver and Related Code Samples. This directory contains a sample AC97 adapter driver a
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        // get the registered DB values
        ntStatus = GetDBValues (that->AdapterCommon, NodeDef, &lMinimum,
                                &lMaximum, &uStep);
        if (!NT_SUCCESS (ntStatus))
            return ntStatus;

        // do a get
        if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
        {
            WORD    wRegister;

            // first get the stuff.
            ntStatus = that->AdapterCommon->ReadCodecRegister (
                    that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
            if (!NT_SUCCESS (ntStatus))
                return ntStatus;

            // mask out every unused bit.
            wRegister &= that->AdapterCommon->GetNodeMask (NodeDef);

            // rotate if bass tone control or 3D center control
            if ((NodeDef == NODE_BASS) || (NodeDef == NODE_VIRT_3D_CENTER))
                wRegister >>= 8;

            // convert from reg to dB.dB value.
            if ((NodeDef == NODE_VIRT_3D_CENTER) ||
                (NodeDef == NODE_VIRT_3D_DEPTH))
            {
                // That's for the 3D controls
                *Level = lMinimum + uStep * wRegister;
            }
            else
            {
                if (wRegister == 0x000F)
                    *Level = 0;     // bypass
                else
                    // And that's for the tone controls
                    *Level = lMaximum - uStep * wRegister;
            }
            
            // when we have cache information then return this instead
            // of the calculated value. if we don't, store the calculated
            // value.
            if (that->stNodeCache[NodeDef].bLeftValid)
                *Level = that->stNodeCache[NodeDef].lLeft;
            else
            {
                that->stNodeCache[NodeDef].lLeft = *Level;
                that->stNodeCache[NodeDef].bLeftValid = -1;
            }

            // we return a LONG
            PropertyRequest->ValueSize = sizeof(LONG);
            DOUT (DBG_PROPERTY, ("GET: %s = 0x%x", NodeStrings[NodeDef], *Level));
            // ntStatus was set with the read call! whatever this is, return it.
        }
        else        // that must be a set
        {
            WORD    wRegister;
            LONG    lLevel = *Level;

            // calculate the dB.dB value.
            // check borders.
            if (lLevel > lMaximum) lLevel = lMaximum;
            if (lLevel < lMinimum) lLevel = lMinimum;
            
            // write the value to the node cache.
            that->stNodeCache[NodeDef].lLeft = *Level;
            that->stNodeCache[NodeDef].bLeftValid = -1;

            // convert from dB.dB value to reg.
            if ((NodeDef == NODE_VIRT_3D_CENTER) ||
                (NodeDef == NODE_VIRT_3D_DEPTH))
            {
                // For 3D controls
                wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
            }
            else
            {
                // For tone controls
                wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
                // We don't prg. 0dB Bass or 0dB Treble, instead we smartly prg.
                // a bypass which is reg. value 0x0F.
                if (wRegister == 7)             // 0 dB
                    wRegister = 0x000F;         // bypass
            }

            // rotate if bass tone control or 3D center control
            if ((NodeDef == NODE_BASS) || (NodeDef == NODE_VIRT_3D_CENTER))
                wRegister <<= 8;

            // write the stuff.
            ntStatus = that->AdapterCommon->WriteCodecRegister (
                    that->AdapterCommon->GetNodeReg (NodeDef),
                    wRegister,
                    that->AdapterCommon->GetNodeMask (NodeDef));

            DOUT (DBG_PROPERTY,("SET: %s -> 0x%x", NodeStrings[NodeDef], *Level));
            // ntStatus was set with the write call! whatever this is, return in.
        }
    }
    else
    {
        if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
        {
            ntStatus = BasicSupportHandler (PropertyRequest);
        }
    }

    return ntStatus;
}
            
/*****************************************************************************
 * CMiniportTopologyICH::PropertyHandler_Ulong
 *****************************************************************************
 * Accesses a ULONG value property. For MUX and DEMUX.
 * This function (property handler) is called by portcls every time there is a
 * get, set or basic support request for the node. The connection between the
 * node type and the property handler is made in the automation table which is
 * referenced when you register the node.
 * We use this property handler for all muxer controls.
 */
NTSTATUS CMiniportTopologyICH::PropertyHandler_Ulong
(
    IN      PPCPROPERTY_REQUEST   PropertyRequest
)
{
    PAGED_CODE ();

    ASSERT (PropertyRequest);

    DOUT (DBG_PRINT, ("[CMiniportTopologyICH::PropertyHandler_Ulong]"));

    NTSTATUS        ntStatus = STATUS_INVALID_PARAMETER;
    TopoNodes       NodeDef;
    LONG            lMinimum, lMaximum;
    ULONG           uStep;
    // The major target is the object pointer to the topology miniport.
    CMiniportTopologyICH *that =
        (CMiniportTopologyICH *) PropertyRequest->MajorTarget;

    ASSERT (that);


    // validate node instance
    if (PropertyRequest->Node == (ULONG)-1)
        return ntStatus;

    // if we should do a get or set.
    if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
        (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
    {
        // validate buffer size.
        if (PropertyRequest->ValueSize < sizeof(ULONG))
            return ntStatus;

        // get the pointer to the buffer.
        PULONG PropValue = (PULONG)PropertyRequest->Value;

        // Switch on the node id. This is just for parameter checking.
        // If something goes wrong, we will immideately return with
        // ntStatus, which is STATUS_INVALID_PARAMETER.
        switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
        {
            case NODE_MONOOUT_SELECT:
            case NODE_WAVEIN_SELECT:
                // check the type
                if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_MUX_SOURCE)
                    return ntStatus;
                break;
                
            case NODE_INVALID:
            default:
                // Ooops
                DOUT (DBG_ERROR, ("PropertyHandler_Tone: Invalid node requested."));
                return ntStatus;
        }

        // Now do some action!

        // should we return the value?
        if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
        {
            WORD    wRegister;

            // first get the stuff.
            ntStatus = that->AdapterCommon->ReadCodecRegister (
                    that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
            if (!NT_SUCCESS (ntStatus))
                return ntStatus;

            // mask out every unused bit.
            wRegister &= that->AdapterCommon->GetNodeMask (NodeDef);

            // calculate the selected pin
            if (NodeDef == NODE_MONOOUT_SELECT)
            {
                // for mono out we have just one bit
                if (wRegister)
                    *PropValue = 2;
                else
                    *PropValue = 1;
            }
            else
            {
                // the wave in muxer is a stereo muxer, so just return the
                // right channel (gives values 0-7) and adjust it by adding 1.
                *PropValue = (wRegister & AC97REG_MASK_RIGHT) + 1;
            }

            // we return a LONG
            PropertyRequest->ValueSize = sizeof(LONG);
            DOUT (DBG_PROPERTY, ("GET: %s = 0x%x", NodeStrings[NodeDef],
                    *PropValue));
            // ntStatus was set with the read call! whatever this is, return it.
        }
        else        // that must be a set
        {
            TopoNodes   VirtNode;
            WORD        wRegister;
            ULONG       ulSelect = *PropValue;
            LONG        lLevel;

            // Check the selection first.
            if (NodeDef == NODE_MONOOUT_SELECT)
            {
                if ((ulSelect < 1) || (ulSelect > 2))
                    return ntStatus;    // STATUS_INVALID_PARAMETER
            }
            else
            {
                if ((ulSelect < 1) || (ulSelect > 8))
                    return ntStatus;    // STATUS_INVALID_PARAMETER
            }

            // calculate the register value for programming.
            if (NodeDef == NODE_MONOOUT_SELECT)
            {
                // for mono out we have just one bit
                if (ulSelect == 2)
                    // the mask will make sure we only prg. one bit.
                    wRegister = -1;
                else
                    // ulSelect == 1
                    wRegister = 0;
            }
            else
            {
                // *257 is the same as: (ulSelect << 8) + ulSelect
                wRegister = (WORD)(ulSelect - 1) * 257;
            }

            // write the stuff.
            ntStatus = that->AdapterCommon->WriteCodecRegister (
                    that->AdapterCommon->GetNodeReg (NodeDef),
                    wRegister,
                    that->AdapterCommon->GetNodeMask (NodeDef));

            // Store the virt. node for later use.
            // Tricky: Master input virtual controls must be defined consecutively.
            if (NodeDef == NODE_MONOOUT_SELECT)
                VirtNode = (TopoNodes)(NODE_VIRT_MONOOUT_VOLUME1 + (ulSelect - 1));
            else
                VirtNode = (TopoNodes)(NODE_VIRT_MASTER_INPUT_VOLUME1 + (ulSelect - 1));

            // Virtual controls make our life more complicated. When the user
            // changes the input source say from CD to LiniIn, then the system just
            // sends a message to the input muxer that the selection changed.
            // Cause we have only one HW register for the input muxer, all volumes
            // displayed for the user are "virtualized", means they are not there,
            // and when the selection changes, we have to prg. the volume of the
            // selected input to the HW register. That's what we do now.
            
            // get the registered DB values
            ntStatus = GetDBValues (that->AdapterCommon, VirtNode,
                                    &lMinimum, &lMaximum, &uStep);
            if (!NT_SUCCESS (ntStatus))
                return ntStatus;

            // We can be lazy here and don't check for mono controls. Reason
            // is that the level handler writes the volume value for mono
            // controls into both the left and right node cache ;))
            
            if (that->stNodeCache[VirtNode].bLeftValid &&
                that->stNodeCache[VirtNode].bRightValid)
            {
                // prg. left channel
                lLevel = that->stNodeCache[VirtNode].lLeft;

                // calculate the dB.dB value.
                if (NodeDef == NODE_MONOOUT_SELECT)
                    wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
                else
                    wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);

                // write left channel.
                ntStatus = that->AdapterCommon->WriteCodecRegister (
                    that->AdapterCommon->GetNodeReg (VirtNode),
                    wRegister << 8,
                    that->AdapterCommon->GetNodeMask (VirtNode) & AC97REG_MASK_LEFT);

                // prg. right channel
                lLevel = that->stNodeCache[VirtNode].lRight;

                // calculate the dB.dB value.
                if (NodeDef == NODE_MONOOUT_SELECT)
                    wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
                else
          

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -