|
|
/********************************************************************************
** 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_
|