📄 prophnd.cpp
字号:
// 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 + -