windows-nt/Source/XPSP1/NT/drivers/ddk/wdmaudio/ac97/driver/mintopo.h
2020-09-26 16:20:57 +08:00

339 lines
11 KiB
C++

/********************************************************************************
** Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved.
**
** Portions Copyright (c) 1998-1999 Intel Corporation
**
********************************************************************************/
#ifndef _MINTOPO_H_
#define _MINTOPO_H_
#include "shared.h"
#include "guids.h"
#ifdef INCLUDE_PRIVATE_PROPERTY
#include "prvprop.h"
#endif
/*****************************************************************************
* Structures and Definitions
*/
// This structure is used to translate the TopoPins member to a (registered)
// system pin member or vice versa.
typedef struct
{
TopoPins PinDef;
int PinNr;
} tPinTranslationTable;
// This structure is used to translate the TopoNodes member to a (registered)
// system node member or vice versa.
typedef struct
{
TopoNodes NodeDef;
int NodeNr;
} tNodeTranslationTable;
// max. number of connections
const int TOPO_MAX_CONNECTIONS = 0x80;
// Looking at the structure stMapNodeToReg, it defines a mask for a node.
// A volume node for instance could be used to prg. the left or right channel,
// so we have to mask the mask in stMapNodeToReg with a "left channel mask"
// or a "right channel mask" to only prg. the left or right channel.
const WORD AC97REG_MASK_LEFT = 0x3F00;
const WORD AC97REG_MASK_RIGHT = 0x003F;
const WORD AC97REG_MASK_MUTE = 0x8000;
// When the user moves the fader of a volume control to the bottom, the
// system calls the property handler with a -MAXIMUM dB value. That's not
// what you returned at a basic support "data range", but the most negative
// value you can represent with a long.
const long PROP_MOST_NEGATIVE = (long)0x80000000;
// We must cache the values for the volume and tone controls. If we don't,
// the controls will "jump".
// We have around 50% volume controls in the nodes. One way would be to
// create a separate structure for the node cache and a second array for
// the mapping. But we just use one big array (that could cache mute controls
// too) and in that way simplify the code a little.
// We use the bLeftValid and bRightValid to indicate whether the values stored
// in lLeft and lRight are true - remember at startup we only write and
// initialize the AC97 registers and not this structure. But as soon as there
// is a property get or a property set, this element (node) will be stored here
// and marked valid.
// We don't have to save/restore the virtual controls for WaveIn and MonoOut
// in the registry, cause WDMAUD will do this for every node that is exposed
// in the topology. We can also be sure that this structure gets initialized at
// startup because WDMAUD will query every node that it finds.
typedef struct
{
long lLeft;
long lRight;
BYTE bLeftValid;
BYTE bRightValid;
} tNodeCache;
/*****************************************************************************
* Classes
*/
/*****************************************************************************
* CMiniportTopologyICH
*****************************************************************************
* ICH topology miniport. This object is associated with the device and is
* created when the device is started. The class inherits IMiniportTopology
* so it can expose this interface and CUnknown so it automatically gets
* reference counting and aggregation support.
*/
class CMiniportTopologyICH : public IMiniportTopologyICH,
public CUnknown
{
private:
PADAPTERCOMMON AdapterCommon; // Adapter common object
PPCFILTER_DESCRIPTOR FilterDescriptor; // Filter Descriptor
PPCPIN_DESCRIPTOR PinDescriptors; // Pin Descriptors
PPCNODE_DESCRIPTOR NodeDescriptors; // Node Descriptors
PPCCONNECTION_DESCRIPTOR ConnectionDescriptors; // Connection Descriptors
tPinTranslationTable stPinTrans[PIN_TOP_ELEMENT]; // pin translation table
tNodeTranslationTable stNodeTrans[NODE_TOP_ELEMENT]; // node translation table
tNodeCache stNodeCache[NODE_TOP_ELEMENT]; // cache for nodes.
BOOL m_bCopyProtectFlag; // Copy protect flag for DRM.
/*************************************************************************
* CMiniportTopologyICH methods
*
* These are private member functions used internally by the object. See
* MINIPORT.CPP for specific descriptions.
*/
// builds the topology.
NTSTATUS BuildTopology (void);
// registers (builds) the pins
NTSTATUS BuildPinDescriptors (void);
// registers (builds) the nodes
NTSTATUS BuildNodeDescriptors (void);
// registers (builds) the connection between the pin, nodes.
NTSTATUS BuildConnectionDescriptors (void);
#if (DBG)
// dumps the topology. you can specify if you want to dump pins, nodes,
// connections (see debug.h).
void DumpTopology (void);
#endif
// translates the system node id to a TopoNode.
TopoNodes TransNodeNrToNodeDef (IN int Node)
{
#if (DBG)
TopoNodes n;
n = stNodeTrans[Node].NodeDef;
// check for invalid translation. could be caused by a connection
// to a not registered node or wrong use of nodes.
if (n == NODE_INVALID)
DOUT (DBG_ERROR, ("Invalid node nr %u.", Node));
return n;
#else
return stNodeTrans[Node].NodeDef;
#endif
};
// translates a TopoNode to a system node id.
int TransNodeDefToNodeNr (IN TopoNodes Node)
{
#if (DBG)
int n;
// check for invalid translation. could be caused by a connection
// to a not registered node or wrong use of nodes.
n = stNodeTrans[Node].NodeNr;
if (n == -1)
DOUT (DBG_ERROR, ("Invalid TopoNode %u.", Node));
return n;
#else
return stNodeTrans[Node].NodeNr;
#endif
};
// translates a system pin id to a TopoPin.
TopoPins TransPinNrToPinDef (IN int Pin)
{
#if (DBG)
TopoPins p;
p = stPinTrans[Pin].PinDef;
// check for invalid translation. could be caused by a connection
// to a not registered pin or wrong use of pins.
if (p == PIN_INVALID)
DOUT (DBG_ERROR, ("Invalid pin nr %u.", Pin));
return p;
#else
return stPinTrans[Pin].PinDef;
#endif
};
// translates a TopoPin to a system pin id.
int TransPinDefToPinNr (IN TopoPins Pin)
{
#if (DBG)
int p;
p = stPinTrans[Pin].PinNr;
// check for invalid translation. could be caused by a connection
// to a not registered pin or wrong use of pins.
if (p == -1)
DOUT (DBG_ERROR, ("Invalid TopoPin %u.", Pin));
return p;
#else
return stPinTrans[Pin].PinNr;
#endif
};
// sets one table entry for translation.
void SetNodeTranslation (IN int NodeNr, IN TopoNodes NodeDef)
{
stNodeTrans[NodeNr].NodeDef = NodeDef;
stNodeTrans[NodeDef].NodeNr = NodeNr;
};
// sets one table entry for translation.
void SetPinTranslation (IN int PinNr, IN TopoPins PinDef)
{
stPinTrans[PinNr].PinDef = PinDef;
stPinTrans[PinDef].PinNr = PinNr;
};
// Updates the record mute - used for DRM.
void UpdateRecordMute (void);
public:
/*************************************************************************
* The following two macros are from STDUNK.H. DECLARE_STD_UNKNOWN()
* defines inline IUnknown implementations that use CUnknown's aggregation
* support. NonDelegatingQueryInterface() is declared, but it cannot be
* implemented generically. Its definition appears in MINIPORT.CPP.
* DEFINE_STD_CONSTRUCTOR() defines inline a constructor which accepts
* only the outer unknown, which is used for aggregation. The standard
* create macro (in MINIPORT.CPP) uses this constructor.
*/
DECLARE_STD_UNKNOWN ();
DEFINE_STD_CONSTRUCTOR (CMiniportTopologyICH);
~CMiniportTopologyICH ();
/*************************************************************************
* include IMiniportTopology (public/exported) methods
*/
IMP_IMiniportTopology;
/*************************************************************************
* IMiniportTopologyICH methods
*/
// returns the system pin id's for wave out, wave in and mic in.
STDMETHODIMP_(NTSTATUS) GetPhysicalConnectionPins
(
OUT PULONG WaveOutSource,
OUT PULONG WaveInDest,
OUT PULONG MicInDest
);
// sets the copy protect flag.
STDMETHODIMP_(void) SetCopyProtectFlag (BOOL flag)
{
if (m_bCopyProtectFlag != flag)
{
m_bCopyProtectFlag = flag;
UpdateRecordMute ();
}
};
/*************************************************************************
* static functions for the property handler.
* They are not part of an COM interface and are called directly.
*/
// Get the data range of volume or tone controls in dB.
// Called by the property handler.
static NTSTATUS GetDBValues
(
IN PADAPTERCOMMON,
IN TopoNodes Node,
OUT LONG *plMinimum,
OUT LONG *plMaximum,
OUT ULONG *puStep
);
// Calculates the speaker mute with respect to master mono.
// Called by the property handler.
static NTSTATUS SetMultichannelMute
(
IN CMiniportTopologyICH *that,
IN TopoNodes Mute
);
// Calculates the speaker volume with respect to master mono.
// Called by the property handler.
static NTSTATUS SetMultichannelVolume
(
IN CMiniportTopologyICH *that,
IN TopoNodes Volume
);
// property handler for mute controls of checkboxes like Loudness.
static NTSTATUS PropertyHandler_OnOff
(
IN PPCPROPERTY_REQUEST PropertyRequest
);
// This routine is the basic support handler for volume or tone controls.
static NTSTATUS BasicSupportHandler
(
IN PPCPROPERTY_REQUEST PropertyRequest
);
// property handler for all volume controls.
static NTSTATUS PropertyHandler_Level
(
IN PPCPROPERTY_REQUEST PropertyRequest
);
// property handler for tone controls.
static NTSTATUS PropertyHandler_Tone
(
IN PPCPROPERTY_REQUEST PropertyRequest
);
// property handler for muxer. we have just two muxer, one for recording
// and one for mono out.
static NTSTATUS PropertyHandler_Ulong
(
IN PPCPROPERTY_REQUEST PropertyRequest
);
// this says that audio is played and processed without CPU resources.
static NTSTATUS PropertyHandler_CpuResources
(
IN PPCPROPERTY_REQUEST PropertyRequest
);
#ifdef INCLUDE_PRIVATE_PROPERTY
// property handler for private properties. we currently have only
// one request defined (KSPROPERTY_AC97_FEATURES).
static NTSTATUS PropertyHandler_Private
(
IN PPCPROPERTY_REQUEST PropertyRequest
);
#endif
};
#endif // _MINTOPO_H_