339 lines
11 KiB
C++
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_
|
|
|