/*****************************************************************************
 * tables.h - HDA topology miniport tables
 *****************************************************************************
 * Copyright (c) 1997-1999 Microsoft Corporation.  All Rights Reserved.
 */

#ifndef _HDATOPO_TABLES_H_
#define _HDATOPO_TABLES_H_

/*****************************************************************************
 * The topology
 *****************************************************************************
 *
 *  wave>-------VOL---------------------+
 *                                      |
 * synth>-------VOL--+------------------+
 *                   |                  |
 *                   +--SWITCH_2X2--+   |
 *                                  |   |
 *    cd>-------VOL--+--SWITCH----------+
 *                   |              |   |
 *                   +--SWITCH_2X2--+   |
 *                                  |   |
 *   aux>-------VOL--+--SWITCH----------+
 *                   |              |   |
 *                   +--SWITCH_2X2--+   |
 *                                  |   |
 *   mic>--AGC--VOL--+--SWITCH----------+--VOL--BASS--TREBLE--GAIN-->lineout
 *                   |              |
 *                   +--SWITCH_1X2--+-------------------------GAIN-->wavein
 *
 */
 
/*****************************************************************************
 * PinDataRangesBridge
 *****************************************************************************
 * Structures indicating range of valid format values for bridge pins.
 */
static
KSDATARANGE PinDataRangesBridge[] =
{
   {
      sizeof(KSDATARANGE),
      0,
      0,
      0,
      STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
      STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG),
      STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
   }
};

/*****************************************************************************
 * PinDataRangePointersBridge
 *****************************************************************************
 * List of pointers to structures indicating range of valid format values
 * for audio bridge pins.
 */
static
PKSDATARANGE PinDataRangePointersBridge[] =
{
    &PinDataRangesBridge[0]
};

/*****************************************************************************
 * MiniportPins
 *****************************************************************************
 * List of pins.
 */
static
PCPIN_DESCRIPTOR 
MiniportPins[] =
{
    // WAVEOUT_SOURCE
    {
        0,0,0,  // InstanceCount
        NULL,   // AutomationTable
        {       // KsPinDescriptor
            0,                                          // InterfacesCount
            NULL,                                       // Interfaces
            0,                                          // MediumsCount
            NULL,                                       // Mediums
            SIZEOF_ARRAY(PinDataRangePointersBridge),   // DataRangesCount
            PinDataRangePointersBridge,                 // DataRanges
            KSPIN_DATAFLOW_IN,                          // DataFlow
            KSPIN_COMMUNICATION_NONE,                   // Communication
            &KSNODETYPE_LEGACY_AUDIO_CONNECTOR,         // Category
            NULL,                                       // Name
            0                                           // Reserved
        }
    },

    // SYNTH_SOURCE
    {
        0,0,0,  // InstanceCount
        NULL,   // AutomationTable
        {       // KsPinDescriptor
            0,                                          // InterfacesCount
            NULL,                                       // Interfaces
            0,                                          // MediumsCount
            NULL,                                       // Mediums
            SIZEOF_ARRAY(PinDataRangePointersBridge),   // DataRangesCount
            PinDataRangePointersBridge,                 // DataRanges
            KSPIN_DATAFLOW_IN,                          // DataFlow
            KSPIN_COMMUNICATION_NONE,                   // Communication
            &KSNODETYPE_SYNTHESIZER,                    // Category
            &KSAUDFNAME_MIDI,                           // Name
            0                                           // Reserved
        }
    },

    // CD_SOURCE
    {
        0,0,0,  // InstanceCount
        NULL,   // AutomationTable
        {       // KsPinDescriptor
            0,                                          // InterfacesCount
            NULL,                                       // Interfaces
            0,                                          // MediumsCount
            NULL,                                       // Mediums
            SIZEOF_ARRAY(PinDataRangePointersBridge),   // DataRangesCount
            PinDataRangePointersBridge,                 // DataRanges
            KSPIN_DATAFLOW_IN,                          // DataFlow
            KSPIN_COMMUNICATION_NONE,                   // Communication
            &KSNODETYPE_CD_PLAYER,                      // Category
            &KSAUDFNAME_CD_AUDIO,                       // Name
            0                                           // Reserved
        }
    },

    // LINEIN_SOURCE
    {
        0,0,0,  // InstanceCount
        NULL,   // AutomationTable
        {       // KsPinDescriptor
            0,                                          // InterfacesCount
            NULL,                                       // Interfaces
            0,                                          // MediumsCount
            NULL,                                       // Mediums
            SIZEOF_ARRAY(PinDataRangePointersBridge),   // DataRangesCount
            PinDataRangePointersBridge,                 // DataRanges
            KSPIN_DATAFLOW_IN,                          // DataFlow
            KSPIN_COMMUNICATION_NONE,                   // Communication
            &KSNODETYPE_LINE_CONNECTOR,                 // Category
            &KSAUDFNAME_LINE_IN,                        // Name
            0                                           // Reserved
        }
    },

    // MIC_SOURCE
    {
        0,0,0,  // InstanceCount
        NULL,   // AutomationTable
        {       // KsPinDescriptor
            0,                                          // InterfacesCount
            NULL,                                       // Interfaces
            0,                                          // MediumsCount
            NULL,                                       // Mediums
            SIZEOF_ARRAY(PinDataRangePointersBridge),   // DataRangesCount
            PinDataRangePointersBridge,                 // DataRanges
            KSPIN_DATAFLOW_IN,                          // DataFlow
            KSPIN_COMMUNICATION_NONE,                   // Communication
            &KSNODETYPE_MICROPHONE,                     // Category
            NULL,                                       // Name
            0                                           // Reserved
        }
    },

    // LINEOUT_DEST
    {
        0,0,0,  // InstanceCount
        NULL,   // AutomationTable
        {       // KsPinDescriptor
            0,                                          // InterfacesCount
            NULL,                                       // Interfaces
            0,                                          // MediumsCount
            NULL,                                       // Mediums
            SIZEOF_ARRAY(PinDataRangePointersBridge),   // DataRangesCount
            PinDataRangePointersBridge,                 // DataRanges
            KSPIN_DATAFLOW_OUT,                         // DataFlow
            KSPIN_COMMUNICATION_NONE,                   // Communication
            &KSNODETYPE_SPEAKER,                        // Category
            &KSAUDFNAME_VOLUME_CONTROL,                 // Name (this name shows up as
                                                        // the playback panel name in SoundVol)
            0                                           // Reserved
        }
    },

    // WAVEIN_DEST
    {
        0,0,0,  // InstanceCount
        NULL,   // AutomationTable
        {       // KsPinDescriptor
            0,                                          // InterfacesCount
            NULL,                                       // Interfaces
            0,                                          // MediumsCount
            NULL,                                       // Mediums
            SIZEOF_ARRAY(PinDataRangePointersBridge),   // DataRangesCount
            PinDataRangePointersBridge,                 // DataRanges
            KSPIN_DATAFLOW_OUT,                         // DataFlow
            KSPIN_COMMUNICATION_NONE,                   // Communication
            &KSCATEGORY_AUDIO,                          // Category
            NULL,                                       // Name
            0                                           // Reserved
        }
    }
};

enum
{
    WAVEOUT_SOURCE = 0,
    SYNTH_SOURCE,
    CD_SOURCE,
    LINEIN_SOURCE,
    MIC_SOURCE,
    LINEOUT_DEST,
    WAVEIN_DEST
};

/*****************************************************************************
 * PropertiesVolume
 *****************************************************************************
 * Properties for volume controls.
 */
static
PCPROPERTY_ITEM PropertiesVolume[] =
{
    { 
        &KSPROPSETID_Audio, 
        KSPROPERTY_AUDIO_VOLUMELEVEL,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_Level
    },
    {
        &KSPROPSETID_Audio,
        KSPROPERTY_AUDIO_CPU_RESOURCES,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_CpuResources
    }
};

/*****************************************************************************
 * AutomationVolume
 *****************************************************************************
 * Automation table for volume controls.
 */
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationVolume,PropertiesVolume);

/*****************************************************************************
 * PropertiesAgc
 *****************************************************************************
 * Properties for AGC controls.
 */
static
PCPROPERTY_ITEM PropertiesAgc[] =
{
    { 
        &KSPROPSETID_Audio, 
        KSPROPERTY_AUDIO_AGC,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_OnOff
    },
    {
        &KSPROPSETID_Audio,
        KSPROPERTY_AUDIO_CPU_RESOURCES,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_CpuResources
    }
};

/*****************************************************************************
 * AutomationAgc
 *****************************************************************************
 * Automation table for Agc controls.
 */
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationAgc,PropertiesAgc);

/*****************************************************************************
 * PropertiesMute
 *****************************************************************************
 * Properties for mute controls.
 */
static
PCPROPERTY_ITEM PropertiesMute[] =
{
    { 
        &KSPROPSETID_Audio, 
        KSPROPERTY_AUDIO_MUTE,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_OnOff
    },
    {
        &KSPROPSETID_Audio,
        KSPROPERTY_AUDIO_CPU_RESOURCES,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_CpuResources
    }
};

/*****************************************************************************
 * AutomationMute
 *****************************************************************************
 * Automation table for mute controls.
 */
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationMute,PropertiesMute);

/*****************************************************************************
 * PropertiesTone
 *****************************************************************************
 * Properties for tone controls.
 */
static
PCPROPERTY_ITEM PropertiesTone[] =
{
    { 
        &KSPROPSETID_Audio, 
        KSPROPERTY_AUDIO_BASS,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_Level
    },
    { 
        &KSPROPSETID_Audio, 
        KSPROPERTY_AUDIO_TREBLE,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_Level
    },
    {
        &KSPROPSETID_Audio,
        KSPROPERTY_AUDIO_CPU_RESOURCES,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_CpuResources
    }
};

/*****************************************************************************
 * AutomationTone
 *****************************************************************************
 * Automation table for tone controls.
 */
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationTone,PropertiesTone);

/*****************************************************************************
 * PropertiesSupermix
 *****************************************************************************
 * Properties for supermix controls.
 */
static
PCPROPERTY_ITEM PropertiesSupermix[] =
{
    { 
        &KSPROPSETID_Audio, 
        KSPROPERTY_AUDIO_MIX_LEVEL_CAPS,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_SuperMixCaps
    },
    { 
        &KSPROPSETID_Audio, 
        KSPROPERTY_AUDIO_MIX_LEVEL_TABLE,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_SuperMixTable
    },
    {
        &KSPROPSETID_Audio,
        KSPROPERTY_AUDIO_CPU_RESOURCES,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_CpuResources
    }
};

/*****************************************************************************
 * AutomationSupermix
 *****************************************************************************
 * Automation table for supermix controls.
 */
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSupermix,PropertiesSupermix);

/*****************************************************************************
 * TopologyNodes
 *****************************************************************************
 * List of node identifiers.
 */
static
PCNODE_DESCRIPTOR TopologyNodes[] =
{
    // WAVEOUT_VOLUME
    {
        0,                      // Flags
        &AutomationVolume,      // AutomationTable
        &KSNODETYPE_VOLUME,     // Type
        &KSAUDFNAME_WAVE_VOLUME // Name
    },

    // SYNTH_VOLUME
    {
        0,                      // Flags
        &AutomationVolume,      // AutomationTable
        &KSNODETYPE_VOLUME,     // Type
        &KSAUDFNAME_MIDI_VOLUME // Name
    },

    // SYNTH_WAVEIN_SUPERMIX
    {
        0,                      // Flags
        &AutomationSupermix,    // AutomationTable
        &KSNODETYPE_SUPERMIX,   // Type
        &KSAUDFNAME_MIDI_MUTE   // Name
    },

    // CD_VOLUME
    {
        0,                      // Flags
        &AutomationVolume,      // AutomationTable
        &KSNODETYPE_VOLUME,     // Type
        &KSAUDFNAME_CD_VOLUME   // Name
    },

    // CD_LINEOUT_SUPERMIX
    {
        0,                      // Flags
        &AutomationSupermix,    // AutomationTable
        &KSNODETYPE_SUPERMIX,   // Type
        &KSAUDFNAME_CD_MUTE     // Name
    },

    // CD_WAVEIN_SUPERMIX
    {
        0,                      // Flags
        &AutomationSupermix,    // AutomationTable
        &KSNODETYPE_SUPERMIX,   // Type
        &KSAUDFNAME_CD_MUTE     // Name
    },

    // LINEIN_VOLUME
    {
        0,                      // Flags
        &AutomationVolume,      // AutomationTable
        &KSNODETYPE_VOLUME,     // Type
        &KSAUDFNAME_LINE_VOLUME // Name
    },

    // LINEIN_LINEOUT_SUPERMIX
    {
        0,                      // Flags
        &AutomationSupermix,    // AutomationTable
        &KSNODETYPE_SUPERMIX,   // Type
        &KSAUDFNAME_LINE_MUTE   // Name
    },

    // LINEIN_WAVEIN_SUPERMIX
    {
        0,                      // Flags
        &AutomationSupermix,    // AutomationTable
        &KSNODETYPE_SUPERMIX,   // Type
        &KSAUDFNAME_LINE_MUTE   // Name
    },

    // MIC_AGC
    {
        0,                      // Flags
        &AutomationAgc,         // AutomationTable
        &KSNODETYPE_AGC,        // Type
        NULL                    // Name
    },

    // MIC_VOLUME
    {
        0,                      // Flags
        &AutomationVolume,      // AutomationTable
        &KSNODETYPE_VOLUME,     // Type
        &KSAUDFNAME_MIC_VOLUME  // Name
    },

    // MIC_LINEOUT_MUTE
    {
        0,                      // Flags
        &AutomationMute,        // AutomationTable
        &KSNODETYPE_MUTE,       // Type
        &KSAUDFNAME_MIC_MUTE    // Name
    },

    // MIC_WAVEIN_SUPERMIX
    {
        0,                      // Flags
        &AutomationSupermix,    // AutomationTable
        &KSNODETYPE_SUPERMIX,   // Type
        &KSAUDFNAME_MIC_MUTE    // Name
    },

    // LINEOUT_MIX
    {
        0,                      // Flags
        NULL,                   // AutomationTable
        &KSNODETYPE_SUM,        // Type
        NULL                    // Name
    },

    // LINEOUT_VOL
    {
        0,                      // Flags
        &AutomationVolume,      // AutomationTable
        &KSNODETYPE_VOLUME,     // Type
        &KSAUDFNAME_MASTER_VOLUME // Name
    },

    // LINEOUT_BASS
    {
        0,                      // Flags
        &AutomationTone,        // AutomationTable
        &KSNODETYPE_TONE,       // Type
        &KSAUDFNAME_BASS        // Name
    },

    // LINEOUT_TREBLE
    {
        0,                      // Flags
        &AutomationTone,        // AutomationTable
        &KSNODETYPE_TONE,       // Type
        &KSAUDFNAME_TREBLE      // Name
    },

    // LINEOUT_GAIN
    {
        0,                      // Flags
        &AutomationVolume,      // AutomationTable
        &KSNODETYPE_VOLUME,     // Type
        NULL                    // Name
    },

    // WAVEIN_MIX
    {
        0,                      // Flags
        NULL,                   // AutomationTable
        &KSNODETYPE_SUM,        // Type
        &KSAUDFNAME_RECORDING_SOURCE // Name
    },

    // WAVEIN_GAIN
    {
        0,                      // Flags
        &AutomationVolume,      // AutomationTable
        &KSNODETYPE_VOLUME,     // Type
        &KSAUDFNAME_WAVE_IN_VOLUME // Name
    }
};

/*****************************************************************************
 * ControlValueCache
 *****************************************************************************
 */
static
LONG ControlValueCache[] =
{   // Left         // Right
    0xFFF9F203,     0xFFF9F203,     // WAVEOUT_VOLUME
    0xFFF9F203,     0xFFF9F203,     // SYNTH_VOLUME
    0xFFF9F203,     0xFFF9F203,     // CD_VOLUME
    0xFFF9F203,     0xFFF9F203,     // LINEIN_VOLUME
    0xFFF9F203,     0,              // MIC_VOLUME
    0xFFF9F203,     0xFFF9F203,     // LINEOUT_VOL
    0x000242A0,     0x000242A0,     // LINEOUT_BASS
    0x000242A0,     0x000242A0,     // LINEOUT_TREBLE
    0x000C0000,     0x000C0000,     // LINEOUT_GAIN
    0x00000000,     0x00000000      // WAVEIN_GAIN
};

typedef struct
{
    BYTE    BaseRegister;           // H/W access parameter
    ULONG   CacheOffset;            // ControlValueCache offset
} ACCESS_PARM,*PACCESS_PARM;

/*****************************************************************************
 * AccessParams
 *****************************************************************************
 * Table of H/W access parameters
 */
static
ACCESS_PARM AccessParams[] =
{
    { DSP_MIX_VOICEVOLIDX_L,        0           },      // WAVEOUT_VOLUME

    { DSP_MIX_FMVOLIDX_L,           2           },      // SYNTH_VOLUME
    { MIXBIT_SYNTH_WAVEIN_R,        ULONG(-1)   },      // SYNTH_WAVEIN_SUPERMIX

    { DSP_MIX_CDVOLIDX_L,           4           },      // CD_VOLUME
    { MIXBIT_CD_LINEOUT_R,          ULONG(-1)   },      // CD_LINEOUT_SUPERMIX
    { MIXBIT_CD_WAVEIN_R,           ULONG(-1)   },      // CD_WAVEIN_SUPERMIX

    { DSP_MIX_LINEVOLIDX_L,         6           },      // LINEIN_VOLUME
    { MIXBIT_LINEIN_LINEOUT_R,      ULONG(-1)   },      // LINEIN_LINEOUT_SUPERMIX
    { MIXBIT_LINEIN_WAVEIN_R,       ULONG(-1)   },      // LINEIN_WAVEIN_SUPERMIX

    { 0,                            ULONG(-1)   },      // MIC_AGC
    { DSP_MIX_MICVOLIDX,            8           },      // MIC_VOLUME
    { 0,                            ULONG(-1)   },      // MIC_LINEOUT_MUTE
    { 0,                            ULONG(-1)   },      // MIC_WAVEIN_SUPERMIX

    { 0,                            ULONG(-1)   },      // LINEOUT_MIX
    { DSP_MIX_MASTERVOLIDX_L,       10          },      // LINEOUT_VOL
    { DSP_MIX_BASSIDX_L,            12          },      // LINEOUT_BASS
    { DSP_MIX_TREBLEIDX_L,          14          },      // LINEOUT_TREBLE
    { DSP_MIX_OUTGAINIDX_L,         16          },      // LINEOUT_GAIN

    { 0,                            ULONG(-1)   },      // WAVEIN_MIX
    { DSP_MIX_INGAINIDX_L,          18          }       // WAVEIN_GAIN
};

enum
{
    WAVEOUT_VOLUME = 0,
    SYNTH_VOLUME,
    SYNTH_WAVEIN_SUPERMIX,
    CD_VOLUME,
    CD_LINEOUT_SUPERMIX,
    CD_WAVEIN_SUPERMIX,
    LINEIN_VOLUME,
    LINEIN_LINEOUT_SUPERMIX,
    LINEIN_WAVEIN_SUPERMIX,
    MIC_AGC,
    MIC_VOLUME,
    MIC_LINEOUT_MUTE,
    MIC_WAVEIN_SUPERMIX,
    LINEOUT_MIX,
    LINEOUT_VOL,
    LINEOUT_BASS,
    LINEOUT_TREBLE,
    LINEOUT_GAIN,
    WAVEIN_MIX,
    WAVEIN_GAIN
};

/*****************************************************************************
 * ConnectionTable
 *****************************************************************************
 * Table of topology unit connections.
 *
 * Pin numbering is technically arbitrary, but the convention established here
 * is to number a solitary output pin 0 (looks like an 'o') and a solitary
 * input pin 1 (looks like an 'i').  Even destinations, which have no output,
 * have an input pin numbered 1 and no pin 0.
 *
 * Nodes are more likely to have multiple ins than multiple outs, so the more
 * general rule would be that inputs are numbered >=1.  If a node has multiple
 * outs, none of these conventions apply.
 *
 * Nodes have at most one control value.  Mixers are therefore simple summing
 * nodes with no per-pin levels.  Rather than assigning a unique pin to each
 * input to a mixer, all inputs are connected to pin 1.  This is acceptable
 * because there is no functional distinction between the inputs.
 *
 * There are no multiplexers in this topology, so there is no opportunity to
 * give an example of a multiplexer.  A multiplexer should have a single
 * output pin (0) and multiple input pins (1..n).  Its control value is an
 * integer in the range 1..n indicating which input is connected to the
 * output.
 *
 * In the case of connections to pins, as opposed to connections to nodes, the
 * node is identified as PCFILTER_NODE and the pin number identifies the
 * particular filter pin.
 */
static
PCCONNECTION_DESCRIPTOR MiniportConnections[] =
{   //  FromNode,               FromPin,          ToNode,                 ToPin
    {   PCFILTER_NODE,          WAVEOUT_SOURCE,   WAVEOUT_VOLUME,         1             },
    {   WAVEOUT_VOLUME,         0,                LINEOUT_MIX,            1             },

    {   PCFILTER_NODE,          SYNTH_SOURCE,     SYNTH_VOLUME,           1             },
    {   SYNTH_VOLUME,           0,                LINEOUT_MIX,            2             },
    {   SYNTH_VOLUME,           0,                SYNTH_WAVEIN_SUPERMIX,  1             },
    {   SYNTH_WAVEIN_SUPERMIX,  0,                WAVEIN_MIX,             1             },

    {   PCFILTER_NODE,          CD_SOURCE,        CD_VOLUME,              1             },
    {   CD_VOLUME,              0,                CD_LINEOUT_SUPERMIX,    1             },
    {   CD_LINEOUT_SUPERMIX,    0,                LINEOUT_MIX,            3             },
    {   CD_VOLUME,              0,                CD_WAVEIN_SUPERMIX,     1             },
    {   CD_WAVEIN_SUPERMIX,     0,                WAVEIN_MIX,             2             },

    {   PCFILTER_NODE,          LINEIN_SOURCE,    LINEIN_VOLUME,          1             },
    {   LINEIN_VOLUME,          0,                LINEIN_LINEOUT_SUPERMIX,1             },
    {   LINEIN_LINEOUT_SUPERMIX,0,                LINEOUT_MIX,            4             },
    {   LINEIN_VOLUME,          0,                LINEIN_WAVEIN_SUPERMIX, 1             },
    {   LINEIN_WAVEIN_SUPERMIX, 0,                WAVEIN_MIX,             3             },

    {   PCFILTER_NODE,          MIC_SOURCE,       MIC_AGC,                1             },
    {   MIC_AGC,                0,                MIC_VOLUME,             1             },
    {   MIC_VOLUME,             0,                MIC_LINEOUT_MUTE,       1             },
    {   MIC_LINEOUT_MUTE,       0,                LINEOUT_MIX,            5             },
    {   MIC_VOLUME,             0,                MIC_WAVEIN_SUPERMIX,    1             },
    {   MIC_WAVEIN_SUPERMIX,    0,                WAVEIN_MIX,             4             },

    {   LINEOUT_MIX,            0,                LINEOUT_VOL,            1             },
    {   LINEOUT_VOL,            0,                LINEOUT_BASS,           1             },
    {   LINEOUT_BASS,           0,                LINEOUT_TREBLE,         1             },
    {   LINEOUT_TREBLE,         0,                LINEOUT_GAIN,           1             },
    {   LINEOUT_GAIN,           0,                PCFILTER_NODE,          LINEOUT_DEST  },

    {   WAVEIN_MIX,             0,                WAVEIN_GAIN,            1             },
    {   WAVEIN_GAIN,            0,                PCFILTER_NODE,          WAVEIN_DEST   }
};

/*****************************************************************************
 * MiniportFilterDescription
 *****************************************************************************
 * Complete miniport description.
 */
static
PCFILTER_DESCRIPTOR MiniportFilterDescriptor =
{
    0,                                  // Version
    NULL,                               // AutomationTable
    sizeof(PCPIN_DESCRIPTOR),           // PinSize
    SIZEOF_ARRAY(MiniportPins),         // PinCount
    MiniportPins,                       // Pins
    sizeof(PCNODE_DESCRIPTOR),          // NodeSize
    SIZEOF_ARRAY(TopologyNodes),        // NodeCount
    TopologyNodes,                      // Nodes
    SIZEOF_ARRAY(MiniportConnections),  // ConnectionCount
    MiniportConnections,                // Connections
    0,                                  // CategoryCount
    NULL                                // Categories
};

#endif
