ReactOS 0.4.15-dev-7906-g1b85a5f
CAC97MiniportTopology Class Reference

#include <mintopo.h>

Inheritance diagram for CAC97MiniportTopology:
Collaboration diagram for CAC97MiniportTopology:

Public Member Functions

 DECLARE_STD_UNKNOWN ()
 
 DEFINE_STD_CONSTRUCTOR (CAC97MiniportTopology)
 
 ~CAC97MiniportTopology ()
 
 STDMETHODIMP_ (NTSTATUS) GetPhysicalConnectionPins(OUT PULONG WaveOutSource
 
 STDMETHODIMP_ (void) SetCopyProtectFlag(BOOL flag)
 

Static Public Member Functions

static NTSTATUS GetDBValues (IN PADAPTERCOMMON, IN TopoNodes Node, OUT LONG *plMinimum, OUT LONG *plMaximum, OUT ULONG *puStep)
 
static NTSTATUS SetMultichannelMute (IN CAC97MiniportTopology *that, IN TopoNodes Mute)
 
static NTSTATUS SetMultichannelVolume (IN CAC97MiniportTopology *that, IN TopoNodes Volume)
 
static NTSTATUS NTAPI PropertyHandler_OnOff (IN PPCPROPERTY_REQUEST PropertyRequest)
 
static NTSTATUS BasicSupportHandler (IN PPCPROPERTY_REQUEST PropertyRequest)
 
static NTSTATUS NTAPI PropertyHandler_Level (IN PPCPROPERTY_REQUEST PropertyRequest)
 
static NTSTATUS NTAPI PropertyHandler_Tone (IN PPCPROPERTY_REQUEST PropertyRequest)
 
static NTSTATUS NTAPI PropertyHandler_Ulong (IN PPCPROPERTY_REQUEST PropertyRequest)
 
static NTSTATUS NTAPI PropertyHandler_CpuResources (IN PPCPROPERTY_REQUEST PropertyRequest)
 

Public Attributes

 IMP_IMiniportTopology
 
OUT PULONG WaveInDest
 
OUT PULONG OUT PULONG MicInDest
 
- Public Attributes inherited from CUnknown
union {
   IUnknown   IUnknown
 
   INonDelegatingUnknown   INonDelegatingUnknown
 
}; 
 
LONG m_ref_count
 
PUNKNOWN m_outer_unknown
 

Private Member Functions

NTSTATUS BuildTopology (void)
 
NTSTATUS BuildPinDescriptors (void)
 
NTSTATUS BuildNodeDescriptors (void)
 
NTSTATUS BuildConnectionDescriptors (void)
 
TopoNodes TransNodeNrToNodeDef (IN int Node)
 
int TransNodeDefToNodeNr (IN TopoNodes Node)
 
TopoPins TransPinNrToPinDef (IN int Pin)
 
int TransPinDefToPinNr (IN TopoPins Pin)
 
void SetNodeTranslation (IN int NodeNr, IN TopoNodes NodeDef)
 
void SetPinTranslation (IN int PinNr, IN TopoPins PinDef)
 
void UpdateRecordMute (void)
 

Private Attributes

PADAPTERCOMMON AdapterCommon
 
PPCFILTER_DESCRIPTOR FilterDescriptor
 
PPCPIN_DESCRIPTOR PinDescriptors
 
PPCNODE_DESCRIPTOR NodeDescriptors
 
PPCCONNECTION_DESCRIPTOR ConnectionDescriptors
 
tPinTranslationTable stPinTrans [PIN_TOP_ELEMENT]
 
tNodeTranslationTable stNodeTrans [NODE_TOP_ELEMENT]
 
tNodeCache stNodeCache [NODE_TOP_ELEMENT]
 
BOOL m_bCopyProtectFlag
 

Detailed Description

Definition at line 94 of file mintopo.h.

Constructor & Destructor Documentation

◆ ~CAC97MiniportTopology()

CAC97MiniportTopology::~CAC97MiniportTopology ( )

Definition at line 356 of file mintopo.cpp.

357{
358 PAGED_CODE ();
359
360 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::~CAC97MiniportTopology]"));
361
362 // release all the stuff that we had referenced or allocated.
363 if (AdapterCommon)
364 {
365 // Notify the AdapterCommon that we go away.
366 AdapterCommon->SetMiniportTopology (NULL);
367 AdapterCommon->Release ();
369 }
370
372 {
375 }
376
378 {
381 }
382
383 if (NodeDescriptors)
384 {
387 }
388
389 if (PinDescriptors)
390 {
393 }
394}
#define PAGED_CODE()
PPCNODE_DESCRIPTOR NodeDescriptors
Definition: mintopo.h:101
PPCFILTER_DESCRIPTOR FilterDescriptor
Definition: mintopo.h:99
PPCPIN_DESCRIPTOR PinDescriptors
Definition: mintopo.h:100
PADAPTERCOMMON AdapterCommon
Definition: mintopo.h:98
PPCCONNECTION_DESCRIPTOR ConnectionDescriptors
Definition: mintopo.h:102
#define NULL
Definition: types.h:112
#define DOUT(lvl, strings)
Definition: debug.h:82
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG PoolTag
Definition: wdfmemory.h:164
#define DBG_PRINT(ppi, ch, level)
Definition: win32kdebug.h:168

Member Function Documentation

◆ BasicSupportHandler()

NTSTATUS CAC97MiniportTopology::BasicSupportHandler ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 572 of file prophnd.cpp.

576{
577 PAGED_CODE ();
578
579 ASSERT (PropertyRequest);
580
581 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::BasicSupportHandler]"));
582
584 // The major target is the object pointer to the topology miniport.
586 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
587
588 ASSERT (that);
589
590
591 // if there is enough space for a KSPROPERTY_DESCRIPTION information
592 if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION)))
593 {
594 // we return a KSPROPERTY_DESCRIPTION structure.
595 PKSPROPERTY_DESCRIPTION PropDesc = (PKSPROPERTY_DESCRIPTION)PropertyRequest->Value;
596
600 PropDesc->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION) +
604 PropDesc->PropTypeSet.Id = VT_I4;
605 PropDesc->PropTypeSet.Flags = 0;
606 PropDesc->MembersListCount = 1;
607 PropDesc->Reserved = 0;
608
609 // if return buffer can also hold a range description, return it too
610 if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION) +
612 {
613 // fill in the members header
615
617 Members->MembersSize = sizeof(KSPROPERTY_STEPPING_LONG);
618 Members->MembersCount = 1;
619 Members->Flags = 0;
620
621 // fill in the stepped range
623
624 ntStatus = GetDBValues (that->AdapterCommon,
625 that->TransNodeNrToNodeDef (PropertyRequest->Node),
626 &Range->Bounds.SignedMinimum,
627 &Range->Bounds.SignedMaximum,
628 &Range->SteppingDelta);
629
630 Range->Reserved = 0;
631
632 // set the return value size
633 PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) +
636
637 DOUT (DBG_PROPERTY, ("BASIC_SUPPORT: %s max=0x%x min=0x%x step=0x%x",
638 NodeStrings[that->TransNodeNrToNodeDef (PropertyRequest->Node)],
639 Range->Bounds.SignedMaximum, Range->Bounds.SignedMinimum,
640 Range->SteppingDelta));
641 } else
642 {
643 // we hadn't enough space for the range information;
644 // set the return value size
645 PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION);
646 }
647
648 ntStatus = STATUS_SUCCESS;
649 }
650 else if (PropertyRequest->ValueSize >= sizeof(ULONG))
651 {
652 // if return buffer can hold a ULONG, return the access flags
653 PULONG AccessFlags = (PULONG)PropertyRequest->Value;
654
655 *AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT |
658
659 // set the return value size
660 PropertyRequest->ValueSize = sizeof(ULONG);
661 ntStatus = STATUS_SUCCESS;
662 }
663
664 // In case there was not even enough space for a ULONG in the return buffer,
665 // we fail this request with STATUS_INVALID_DEVICE_REQUEST.
666 // Any other case will return STATUS_SUCCESS.
667 return ntStatus;
668}
LONG NTSTATUS
Definition: precomp.h:26
static NTSTATUS GetDBValues(IN PADAPTERCOMMON, IN TopoNodes Node, OUT LONG *plMinimum, OUT LONG *plMaximum, OUT ULONG *puStep)
Definition: prophnd.cpp:156
TopoNodes TransNodeNrToNodeDef(IN int Node)
Definition: mintopo.h:135
@ VT_I4
Definition: compat.h:2298
const int DBG_PROPERTY
Definition: debug.h:29
#define KSPROPERTY_TYPE_SET
Definition: dmksctrl.h:43
#define KSPROPERTY_TYPE_BASICSUPPORT
Definition: dmksctrl.h:45
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
#define KSPROPERTY_MEMBER_STEPPEDRANGES
Definition: ks.h:1559
#define KSPROPTYPESETID_General
Definition: ks.h:858
struct KSPROPERTY_STEPPING_LONG * PKSPROPERTY_STEPPING_LONG
struct KSPROPERTY_DESCRIPTION * PKSPROPERTY_DESCRIPTION
struct KSPROPERTY_MEMBERSHEADER * PKSPROPERTY_MEMBERSHEADER
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
ULONG Id
Definition: dmksctrl.h:77
ULONG Flags
Definition: dmksctrl.h:78
GUID Set
Definition: dmksctrl.h:76
ULONG DescriptionSize
Definition: ks.h:1540
KSIDENTIFIER PropTypeSet
Definition: ks.h:1541
ULONG MembersListCount
Definition: ks.h:1542
Definition: range.c:39
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59

Referenced by PropertyHandler_Level(), and PropertyHandler_Tone().

◆ BuildConnectionDescriptors()

NTSTATUS CAC97MiniportTopology::BuildConnectionDescriptors ( void  )
private

Definition at line 1580 of file mintopo.cpp.

1581{
1582// Improvement would be to not use a Macro, use (inline) function instead.
1583
1584// for node to node connections
1585#define INIT_NN_CONN( cptr, fnode, fpin, tnode, tpin ) \
1586 cptr->FromNode = TransNodeDefToNodeNr (fnode); \
1587 cptr->FromNodePin = fpin; \
1588 cptr->ToNode = TransNodeDefToNodeNr (tnode); \
1589 cptr->ToNodePin = tpin; \
1590 cptr++,ConnectionCount++
1591
1592// for filter pin to node connections
1593#define INIT_FN_CONN( cptr, fpin, tnode, tpin ) \
1594 cptr->FromNode = KSFILTER_NODE; \
1595 cptr->FromNodePin = TransPinDefToPinNr (fpin); \
1596 cptr->ToNode = TransNodeDefToNodeNr (tnode); \
1597 cptr->ToNodePin = tpin; \
1598 cptr++,ConnectionCount++
1599
1600// for node to filter pin connections
1601#define INIT_NF_CONN( cptr, fnode, fpin, tpin ) \
1602 cptr->FromNode = TransNodeDefToNodeNr (fnode); \
1603 cptr->FromNodePin = fpin; \
1604 cptr->ToNode = KSFILTER_NODE; \
1605 cptr->ToNodePin = TransPinDefToPinNr (tpin); \
1606 cptr++,ConnectionCount++
1607
1608 PAGED_CODE ();
1609
1610 NTSTATUS ntStatus = STATUS_SUCCESS;
1611 ULONG ConnectionCount = 0;
1612
1613 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::BuildConnectionDescriptors]"));
1614
1615 // allocate our descriptor memory
1619 {
1621
1622 // build the wave out (coming in) path
1623
1624 // PIN_WAVEOUT_SOURCE -> NODE_WAVEOUT_VOLUME
1625 INIT_FN_CONN (CurrentConnection, PIN_WAVEOUT_SOURCE, NODE_WAVEOUT_VOLUME, 1);
1626
1627 // NODE_WAVEOUT_VOLUME -> NODE_WAVEOUT_MUTE
1628 INIT_NN_CONN (CurrentConnection, NODE_WAVEOUT_VOLUME, 0, NODE_WAVEOUT_MUTE, 1);
1629
1630 // NODE_WAVEOUT_MUTE -> NODE_MAIN_MIX
1631 INIT_NN_CONN (CurrentConnection, NODE_WAVEOUT_MUTE, 0, NODE_MAIN_MIX, 1);
1632
1633 // build the PC beeper path
1634 if (AdapterCommon->GetPinConfig (PINC_PCBEEP_PRESENT))
1635 {
1636 // PIN_PCBEEP_SOURCE -> NODE_PCBEEP_VOLUME
1637 INIT_FN_CONN (CurrentConnection, PIN_PCBEEP_SOURCE, NODE_PCBEEP_VOLUME, 1);
1638
1639 // NODE_PCBEEP_VOLUME -> NODE_PCBEEP_MUTE
1640 INIT_NN_CONN (CurrentConnection, NODE_PCBEEP_VOLUME, 0, NODE_PCBEEP_MUTE, 1);
1641
1642 // NODE_PCBEEP_MUTE -> NODE_BEEP_MIX
1643 INIT_NN_CONN (CurrentConnection, NODE_PCBEEP_MUTE, 0, NODE_BEEP_MIX, 2);
1644 }
1645
1646 // build the phone path
1647 if (AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
1648 {
1649 // PIN_PHONE_SOURCE -> NODE_PHONE_VOLUME
1650 INIT_FN_CONN (CurrentConnection, PIN_PHONE_SOURCE, NODE_PHONE_VOLUME, 1);
1651
1652 // NODE_PHONE_VOLUME -> NODE_PHONE_MUTE
1653 INIT_NN_CONN (CurrentConnection, NODE_PHONE_VOLUME, 0, NODE_PHONE_MUTE, 1);
1654
1655 // NODE_PHONE_MUTE -> LINEOUT_BEEP_MIX
1656 INIT_NN_CONN (CurrentConnection, NODE_PHONE_MUTE, 0, NODE_BEEP_MIX, 3);
1657
1658 // PIN_PHONE_SOURCE pin -> NODE_VIRT_MASTER_INPUT_VOLUME8
1660
1661 // NODE_VIRT_MASTER_INPUT_VOLUME8 -> NODE_WAVEIN_SELECT
1663 }
1664
1665 // build MIC path
1666 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
1667 {
1668 // build the MIC selector in case we have 2 MICs
1669 if (AdapterCommon->GetPinConfig (PINC_MIC2_PRESENT))
1670 {
1671 // PIN_MIC_SOURCE pin -> NODE_MIC_SELECT
1672 INIT_FN_CONN (CurrentConnection, PIN_MIC_SOURCE, NODE_MIC_SELECT, 1);
1673
1674 // NODE_MIC_SELECT -> NODE_MIC_BOOST
1675 INIT_NN_CONN (CurrentConnection, NODE_MIC_SELECT, 0, NODE_MIC_BOOST, 1);
1676 }
1677 else
1678 {
1679 // PIN_MIC_SOURCE pin -> NODE_MIC_SELECT
1680 INIT_FN_CONN (CurrentConnection, PIN_MIC_SOURCE, NODE_MIC_BOOST, 1);
1681 }
1682
1683 // NODE_MIC_BOOST -> NODE_MIC_VOLUME
1684 INIT_NN_CONN (CurrentConnection, NODE_MIC_BOOST, 0, NODE_MIC_VOLUME, 1);
1685
1686 // NODE_MIC_VOLUME -> NODE_MIC_MUTE
1687 INIT_NN_CONN (CurrentConnection, NODE_MIC_VOLUME, 0, NODE_MIC_MUTE, 1);
1688
1689 // NODE_MIC_MUTE -> NODE_MAIN_MIX
1690 INIT_NN_CONN (CurrentConnection, NODE_MIC_MUTE, 0, NODE_MAIN_MIX, 2);
1691
1692 // NODE_MIC_BOOST -> NODE_VIRT_MASTER_INPUT_VOLUME1
1694
1695 // NODE_VIRT_MASTER_INPUT_VOLUME1 -> NODE_WAVEIN_SELECT
1697 }
1698
1699 // build the line in path
1700 if (AdapterCommon->GetPinConfig (PINC_LINEIN_PRESENT))
1701 {
1702 // PIN_LINEIN_SOURCE -> NODE_LINEIN_VOLUME
1703 INIT_FN_CONN (CurrentConnection, PIN_LINEIN_SOURCE, NODE_LINEIN_VOLUME, 1);
1704
1705 // NODE_LINEIN_VOLUME -> NODE_LINEIN_MUTE
1706 INIT_NN_CONN (CurrentConnection, NODE_LINEIN_VOLUME, 0, NODE_LINEIN_MUTE, 1);
1707
1708 // NODE_LINEIN_MUTE -> NODE_MAIN_MIX
1709 INIT_NN_CONN (CurrentConnection, NODE_LINEIN_MUTE, 0, NODE_MAIN_MIX, 3);
1710
1711 // PIN_LINEIN_SOURCE pin -> NODE_VIRT_MASTER_INPUT_VOLUME5
1713
1714 // NODE_VIRT_MASTER_INPUT_VOLUME5 -> NODE_WAVEIN_SELECT
1716 }
1717
1718 // build the CD path
1719 if (AdapterCommon->GetPinConfig (PINC_CD_PRESENT))
1720 {
1721 // PIN_CD_SOURCE -> NODE_CD_VOLUME
1722 INIT_FN_CONN (CurrentConnection, PIN_CD_SOURCE, NODE_CD_VOLUME, 1);
1723
1724 // NODE_CD_VOLUME -> NODE_CD_MUTE
1725 INIT_NN_CONN (CurrentConnection, NODE_CD_VOLUME, 0, NODE_CD_MUTE, 1);
1726
1727 // NODE_CD_MUTE -> NODE_MAIN_MIX
1728 INIT_NN_CONN (CurrentConnection, NODE_CD_MUTE, 0, NODE_MAIN_MIX, 4);
1729
1730 // PIN_CD_SOURCE pin -> NODE_VIRT_MASTER_INPUT_VOLUME2
1732
1733 // NODE_VIRT_MASTER_INPUT_VOLUME2 -> NODE_WAVEIN_SELECT
1735 }
1736
1737 // build the video path
1738 if (AdapterCommon->GetPinConfig (PINC_VIDEO_PRESENT))
1739 {
1740 // PIN_VIDEO_SOURCE -> NODE_VIDEO_VOLUME
1741 INIT_FN_CONN (CurrentConnection, PIN_VIDEO_SOURCE, NODE_VIDEO_VOLUME, 1);
1742
1743 // NODE_VIDEO_VOLUME -> NODE_VIDEO_MUTE
1744 INIT_NN_CONN (CurrentConnection, NODE_VIDEO_VOLUME, 0, NODE_VIDEO_MUTE, 1);
1745
1746 // NODE_VIDEO_MUTE -> NODE_MAIN_MIX
1747 INIT_NN_CONN (CurrentConnection, NODE_VIDEO_MUTE, 0, NODE_MAIN_MIX, 5);
1748
1749 // PIN_VIDEO_SOURCE pin -> NODE_VIRT_MASTER_INPUT_VOLUME3
1751
1752 // NODE_VIRT_MASTER_INPUT_VOLUME3 -> NODE_WAVEIN_SELECT
1754 }
1755
1756 // build the AUX path
1757 if (AdapterCommon->GetPinConfig (PINC_AUX_PRESENT))
1758 {
1759 // PIN_AUX_SOURCE pin -> NODE_AUX_VOLUME
1760 INIT_FN_CONN (CurrentConnection, PIN_AUX_SOURCE, NODE_AUX_VOLUME, 1);
1761
1762 // NODE_AUX_VOLUME -> NODE_AUX_MUTE
1763 INIT_NN_CONN (CurrentConnection, NODE_AUX_VOLUME, 0, NODE_AUX_MUTE, 1);
1764
1765 // NODE_AUX_MUTE -> NODE_MAIN_MIX
1766 INIT_NN_CONN (CurrentConnection, NODE_AUX_MUTE, 0, NODE_MAIN_MIX, 6);
1767
1768 // PIN_AUX_SOURCE pin -> NODE_VIRT_MASTER_INPUT_VOLUME4
1770
1771 // NODE_VIRT_MASTER_INPUT_VOLUME4 -> NODE_WAVEIN_SELECT
1773 }
1774
1775 // and build the head phone output.
1776 // we connect the headphones like an input so that it's in the playback panel.
1777 if (AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
1778 {
1779 // from whatever -> NODE_HPOUT_VOLUME
1780 INIT_FN_CONN (CurrentConnection, PIN_HPOUT_SOURCE, NODE_HPOUT_VOLUME, 1);
1781
1782 // NODE_HPOUT_VOLUME -> NODE_HPOUT_MUTE
1783 INIT_NN_CONN (CurrentConnection, NODE_HPOUT_VOLUME, 0, NODE_HPOUT_MUTE, 1);
1784
1785 // NODE_HPOUT_MUTE -> PIN_HPOUT_DEST pin
1786 INIT_NN_CONN( CurrentConnection, NODE_HPOUT_MUTE, 0, NODE_MAIN_MIX, 9);
1787 }
1788
1789 // build the 3D path
1790 if (AdapterCommon->GetNodeConfig (NODEC_3D_PRESENT))
1791 {
1792 // Figure out what the main 3D line is.
1793 if (AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE))
1794 {
1795 if (AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE))
1796 {
1797 // PIN_VIRT_3D_DEPTH_SOURCE -> NODE_VIRT_3D_ENABLE
1799
1800 // NODE_VIRT_3D_ENABLE -> NODE_VIRT_WAVEOUT_3D_BYPASS
1802
1803 // NODE_VIRT_WAVEOUT_3D_BYPASS -> NODE_VIRT_3D_DEPTH
1805
1806 // NODE_VIRT_3D_DEPTH -> NODE_MAIN_MIX
1807 INIT_NN_CONN (CurrentConnection, NODE_VIRT_3D_DEPTH, 0, NODE_MAIN_MIX, 7);
1808
1809 // PIN_VIRT_3D_CENTER_SOURCE -> NODE_VIRT_3D_CENTER
1811
1812 // NODE_VIRT_3D_CENTER -> NODE_MAIN_MIX
1813 INIT_NN_CONN (CurrentConnection, NODE_VIRT_3D_CENTER, 0, NODE_MAIN_MIX, 8);
1814 }
1815 else
1816 {
1817 // PIN_VIRT_3D_CENTER_SOURCE -> NODE_VIRT_3D_ENABLE
1819
1820 // NODE_VIRT_3D_ENABLE -> NODE_VIRT_WAVEOUT_3D_BYPASS
1822
1823 // NODE_VIRT_WAVEOUT_3D_BYPASS -> NODE_VIRT_3D_CENTER
1825
1826 // NODE_VIRT_3D_CENTER -> NODE_MAIN_MIX
1827 INIT_NN_CONN (CurrentConnection, NODE_VIRT_3D_CENTER, 0, NODE_MAIN_MIX, 8);
1828 }
1829 }
1830 else
1831 {
1832 // PIN_VIRT_3D_DEPTH_SOURCE -> NODE_VIRT_3D_ENABLE
1834
1835 // NODE_VIRT_3D_ENABLE -> NODE_VIRT_WAVEOUT_3D_BYPASS
1837
1838 // NODE_VIRT_WAVEOUT_3D_BYPASS -> NODE_VIRT_3D_DEPTH
1840
1841 // NODE_VIRT_3D_DEPTH -> NODE_MAIN_MIX
1842 INIT_NN_CONN (CurrentConnection, NODE_VIRT_3D_DEPTH, 0, NODE_MAIN_MIX, 7);
1843 }
1844 }
1845
1846 // build the 4 or 6 channel controls
1847
1848 // In case of multichannel or headphone we have "front speakers" volume/mute.
1849 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
1850 AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
1851 {
1852 // PIN_VIRT_FRONT_SOURCE -> NODE_FRONT_VOLUME
1853 INIT_FN_CONN (CurrentConnection, PIN_VIRT_FRONT_SOURCE, NODE_FRONT_VOLUME, 1);
1854
1855 // NODE_FRONT_VOLUME -> NODE_FRONT_MUTE
1856 INIT_NN_CONN (CurrentConnection, NODE_FRONT_VOLUME, 0, NODE_FRONT_MUTE, 1);
1857
1858 // NODE_FRONT_MUTE -> NODE_MAIN_MIX
1859 INIT_NN_CONN (CurrentConnection, NODE_FRONT_MUTE, 0, NODE_MAIN_MIX, 10);
1860 }
1861
1862 // Check for surround volumes
1863 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
1864 {
1865 // PIN_VIRT_SURROUND -> NODE_SURROUND_VOLUME
1867
1868 // NODE_SURROUND_VOLUME -> NODE_SURROUND_MUTE
1869 INIT_NN_CONN (CurrentConnection, NODE_SURROUND_VOLUME, 0, NODE_SURROUND_MUTE, 1);
1870
1871 // NODE_SURROUND_MUTE -> NODE_MAIN_MIX
1872 INIT_NN_CONN (CurrentConnection, NODE_SURROUND_MUTE, 0, NODE_MAIN_MIX, 11);
1873
1874 // check also for the center and LFE volumes
1875 if (AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
1876 {
1877 // PIN_VIRT_CENTER -> NODE_CENTER_VOLUME
1879
1880 // NODE_CENTER_VOLUME -> NODE_CENTER_MUTE
1881 INIT_NN_CONN (CurrentConnection, NODE_CENTER_VOLUME, 0, NODE_CENTER_MUTE, 1);
1882
1883 // NODE_CENTER_MUTE -> NODE_MAIN_MIX
1884 INIT_NN_CONN (CurrentConnection, NODE_CENTER_MUTE, 0, NODE_MAIN_MIX, 12);
1885
1886 // PIN_VIRT_LFE -> NODE_LFE_VOLUME
1887 INIT_FN_CONN (CurrentConnection, PIN_VIRT_LFE_SOURCE, NODE_LFE_VOLUME, 1);
1888
1889 // NODE_LFE_VOLUME -> NODE_LFE_MUTE
1890 INIT_NN_CONN (CurrentConnection, NODE_LFE_VOLUME, 0, NODE_LFE_MUTE, 1);
1891
1892 // NODE_LFE_MUTE -> NODE_MAIN_MIX
1893 INIT_NN_CONN (CurrentConnection, NODE_LFE_MUTE, 0, NODE_MAIN_MIX, 13);
1894 }
1895 }
1896
1897 // helper node variable.
1898 TopoNodes ConnectFromNode;
1899
1900 // all connections go from this one
1901 ConnectFromNode = NODE_MAIN_MIX;
1902
1903 // build the beeper & phone mix
1904 if (AdapterCommon->GetPinConfig (PINC_PCBEEP_PRESENT) ||
1905 AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
1906 {
1907 // last node -> NODE_BEEP_MIX
1908 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_BEEP_MIX, 1);
1909
1910 // next connection from this point.
1911 ConnectFromNode = NODE_BEEP_MIX;
1912 }
1913
1914 // build the tone control path
1915 if (AdapterCommon->GetNodeConfig (NODEC_TONE_PRESENT))
1916 {
1917 // last node -> NODE_BASS
1918 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_BASS, 1);
1919
1920 // NODE_BASS -> NODE_TREBLE
1921 INIT_NN_CONN (CurrentConnection, NODE_BASS, 0, NODE_TREBLE, 1);
1922
1923 // remember the last node
1924 ConnectFromNode = NODE_TREBLE;
1925
1926 // build the loudness control
1927 if (AdapterCommon->GetNodeConfig (NODEC_LOUDNESS_PRESENT))
1928 {
1929 // last node -> NODE_LOUDNESS
1930 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_LOUDNESS, 1);
1931
1932 // remember the last node
1933 ConnectFromNode = NODE_LOUDNESS;
1934 }
1935
1936 // build the simulated stereo control
1937 if (AdapterCommon->GetNodeConfig (NODEC_SIMUL_STEREO_PRESENT))
1938 {
1939 // last node -> NODE_SIMUL_STEREO
1940 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_SIMUL_STEREO, 1);
1941
1942 // remember the last node
1943 ConnectFromNode = NODE_SIMUL_STEREO;
1944 }
1945 }
1946
1947 //build the master volume output.
1948
1949 // In case of multichannel or headphone we use a master mono control.
1950 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
1951 AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
1952 {
1953 // build the connection from whatever to NODE_VIRT_MASTERMONO_VOLUME
1954 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_VIRT_MASTERMONO_VOLUME, 1);
1955
1956 // NODE_VIRT_MASTERMONO_VOLUME -> NODE_VIRT_MASTERMONO_MUTE
1958
1959 // NODE_VIRT_MASTERMONO_MUTE -> PIN_MASTEROUT_DEST pin
1961 }
1962 else
1963 {
1964 // build the connection from whatever to NODE_MASTEROUT_VOLUME
1965 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_MASTEROUT_VOLUME, 1);
1966
1967 // NODE_MASTEROUT_VOLUME -> NODE_MASTEROUT_MUTE
1968 INIT_NN_CONN (CurrentConnection, NODE_MASTEROUT_VOLUME, 0, NODE_MASTEROUT_MUTE, 1);
1969
1970 // NODE_MASTEROUT_MUTE -> PIN_MASTEROUT_DEST pin
1971 INIT_NF_CONN( CurrentConnection, NODE_MASTEROUT_MUTE, 0, PIN_MASTEROUT_DEST);
1972 }
1973
1974 // now complete the input muxer path
1975
1976 // PIN_VIRT_TONE_MIX_MONO_SOURCE -> NODE_VIRT_MASTER_INPUT_VOLUME7
1978
1979 // NODE_VIRT_MASTER_INPUT_VOLUME7 -> NODE_WAVEIN_SELECT
1981
1982 // PIN_VIRT_TONE_MIX_SOURCE -> NODE_VIRT_MASTER_INPUT_VOLUME6
1984
1985 // NODE_VIRT_MASTER_INPUT_VOLUME6 -> NODE_WAVEIN_SELECT
1987
1988 // NODE_WAVEIN_SELECT -> PIN_WAVEIN_DEST
1989 INIT_NF_CONN( CurrentConnection, NODE_WAVEIN_SELECT, 0, PIN_WAVEIN_DEST);
1990
1991 // build the mic output path (for record control)
1992 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT) &&
1993 AdapterCommon->GetPinConfig (PINC_MICIN_PRESENT))
1994 {
1995 // NODE_MIC_BOOST -> NODE_MICIN_VOLUME
1996 INIT_NN_CONN (CurrentConnection, NODE_MIC_BOOST, 0, NODE_MICIN_VOLUME, 1);
1997
1998 // NODE_MICIN_VOLUME -> NODE_MICIN_MUTE
1999 INIT_NN_CONN (CurrentConnection, NODE_MICIN_VOLUME, 0, NODE_MICIN_MUTE, 1);
2000
2001 // NODE_MICIN_MUTE -> PIN_MICIN_DEST
2002 INIT_NF_CONN( CurrentConnection, NODE_MICIN_MUTE, 0, PIN_MICIN_DEST);
2003 }
2004
2005 // build the mono path
2006 if (AdapterCommon->GetPinConfig (PINC_MONOOUT_PRESENT))
2007 {
2008 // PIN_VIRT_3D_MIX_MONO_SOURCE -> NODE_MONOOUT_SMIX
2010
2011 // NODE_VIRT_MONOOUT_VOLUME1 -> NODE_MONOOUT_SELECT
2013
2014 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
2015 {
2016 // NODE_MIC_BOOST -> NODE_VIRT_MONOOUT_VOLUME2
2017 INIT_NN_CONN (CurrentConnection, NODE_MIC_BOOST, 0, NODE_VIRT_MONOOUT_VOLUME2, 1);
2018
2019 // NODE_VIRT_MONOOUT_VOLUME2 -> NODE_MONOOUT_SELECT
2021 }
2022
2023 // NODE_MONOOUT_SELECT -> PIN_MONOOUT_DEST
2024 INIT_NF_CONN( CurrentConnection, NODE_MONOOUT_SELECT, 0, PIN_MONOOUT_DEST);
2025 }
2026
2027 // add the connections to the filter descriptor
2028 FilterDescriptor->ConnectionCount = ConnectionCount;
2030 } else
2031 {
2033 }
2034
2035 return ntStatus;
2036
2037#undef INIT_NN_CONN
2038#undef INIT_FN_CONN
2039#undef INIT_NF_CONN
2040}
#define INIT_NN_CONN(cptr, fnode, fpin, tnode, tpin)
#define INIT_NF_CONN(cptr, fnode, fpin, tpin)
#define INIT_FN_CONN(cptr, fpin, tnode, tpin)
@ PINC_LINEIN_PRESENT
Definition: shared.h:72
@ PINC_MONOOUT_PRESENT
Definition: shared.h:69
@ PINC_VIDEO_PRESENT
Definition: shared.h:66
@ PINC_MIC2_PRESENT
Definition: shared.h:65
@ PINC_PCBEEP_PRESENT
Definition: shared.h:63
@ PINC_PHONE_PRESENT
Definition: shared.h:64
@ PINC_AUX_PRESENT
Definition: shared.h:67
@ PINC_SURROUND_PRESENT
Definition: shared.h:74
@ PINC_CENTER_LFE_PRESENT
Definition: shared.h:75
@ PINC_HPOUT_PRESENT
Definition: shared.h:68
@ PINC_CD_PRESENT
Definition: shared.h:73
@ PINC_MICIN_PRESENT
Definition: shared.h:70
@ PINC_MIC_PRESENT
Definition: shared.h:71
TopoNodes
Definition: shared.h:186
@ NODE_MASTEROUT_VOLUME
Definition: shared.h:215
@ NODE_HPOUT_MUTE
Definition: shared.h:218
@ NODE_TREBLE
Definition: shared.h:212
@ NODE_WAVEOUT_MUTE
Definition: shared.h:188
@ NODE_PHONE_VOLUME
Definition: shared.h:192
@ NODE_VIRT_MASTER_INPUT_VOLUME1
Definition: shared.h:223
@ NODE_MICIN_MUTE
Definition: shared.h:232
@ NODE_LFE_MUTE
Definition: shared.h:238
@ NODE_BEEP_MIX
Definition: shared.h:210
@ NODE_VIRT_MONOOUT_VOLUME1
Definition: shared.h:220
@ NODE_PHONE_MUTE
Definition: shared.h:193
@ NODE_MIC_BOOST
Definition: shared.h:195
@ NODE_WAVEIN_SELECT
Definition: shared.h:222
@ NODE_HPOUT_VOLUME
Definition: shared.h:217
@ NODE_VIRT_MONOOUT_VOLUME2
Definition: shared.h:221
@ NODE_CENTER_MUTE
Definition: shared.h:236
@ NODE_LFE_VOLUME
Definition: shared.h:237
@ NODE_VIRT_MASTER_INPUT_VOLUME3
Definition: shared.h:225
@ NODE_VIRT_MASTER_INPUT_VOLUME8
Definition: shared.h:230
@ NODE_SIMUL_STEREO
Definition: shared.h:214
@ NODE_VIRT_MASTERMONO_MUTE
Definition: shared.h:242
@ NODE_AUX_VOLUME
Definition: shared.h:204
@ NODE_PCBEEP_MUTE
Definition: shared.h:191
@ NODE_VIRT_3D_CENTER
Definition: shared.h:207
@ NODE_LINEIN_VOLUME
Definition: shared.h:198
@ NODE_MIC_MUTE
Definition: shared.h:197
@ NODE_VIRT_WAVEOUT_3D_BYPASS
Definition: shared.h:189
@ NODE_VIRT_3D_ENABLE
Definition: shared.h:209
@ NODE_VIRT_MASTER_INPUT_VOLUME2
Definition: shared.h:224
@ NODE_CD_VOLUME
Definition: shared.h:200
@ NODE_FRONT_VOLUME
Definition: shared.h:239
@ NODE_MIC_VOLUME
Definition: shared.h:196
@ NODE_BASS
Definition: shared.h:211
@ NODE_LINEIN_MUTE
Definition: shared.h:199
@ NODE_VIRT_MASTER_INPUT_VOLUME6
Definition: shared.h:228
@ NODE_PCBEEP_VOLUME
Definition: shared.h:190
@ NODE_VIRT_MASTER_INPUT_VOLUME5
Definition: shared.h:227
@ NODE_LOUDNESS
Definition: shared.h:213
@ NODE_VIDEO_MUTE
Definition: shared.h:203
@ NODE_CENTER_VOLUME
Definition: shared.h:235
@ NODE_CD_MUTE
Definition: shared.h:201
@ NODE_VIRT_MASTER_INPUT_VOLUME7
Definition: shared.h:229
@ NODE_WAVEOUT_VOLUME
Definition: shared.h:187
@ NODE_FRONT_MUTE
Definition: shared.h:240
@ NODE_VIRT_MASTERMONO_VOLUME
Definition: shared.h:241
@ NODE_VIRT_3D_DEPTH
Definition: shared.h:208
@ NODE_SURROUND_VOLUME
Definition: shared.h:233
@ NODE_MASTEROUT_MUTE
Definition: shared.h:216
@ NODE_SURROUND_MUTE
Definition: shared.h:234
@ NODE_VIDEO_VOLUME
Definition: shared.h:202
@ NODE_MONOOUT_SELECT
Definition: shared.h:219
@ NODE_AUX_MUTE
Definition: shared.h:205
@ NODE_MICIN_VOLUME
Definition: shared.h:231
@ NODE_VIRT_MASTER_INPUT_VOLUME4
Definition: shared.h:226
@ NODE_MIC_SELECT
Definition: shared.h:194
@ NODE_MAIN_MIX
Definition: shared.h:206
@ NODEC_3D_DEPTH_ADJUSTABLE
Definition: shared.h:95
@ NODEC_TONE_PRESENT
Definition: shared.h:86
@ NODEC_3D_CENTER_ADJUSTABLE
Definition: shared.h:94
@ NODEC_LOUDNESS_PRESENT
Definition: shared.h:87
@ NODEC_3D_PRESENT
Definition: shared.h:85
@ NODEC_SIMUL_STEREO_PRESENT
Definition: shared.h:88
@ PIN_LINEIN_SOURCE
Definition: shared.h:118
@ PIN_VIRT_CENTER_SOURCE
Definition: shared.h:128
@ PIN_VIRT_3D_CENTER_SOURCE
Definition: shared.h:122
@ PIN_PCBEEP_SOURCE
Definition: shared.h:115
@ PIN_VIRT_TONE_MIX_SOURCE
Definition: shared.h:125
@ PIN_MICIN_DEST
Definition: shared.h:135
@ PIN_VIRT_LFE_SOURCE
Definition: shared.h:129
@ PIN_MIC_SOURCE
Definition: shared.h:117
@ PIN_VIDEO_SOURCE
Definition: shared.h:120
@ PIN_VIRT_TONE_MIX_MONO_SOURCE
Definition: shared.h:126
@ PIN_AUX_SOURCE
Definition: shared.h:121
@ PIN_CD_SOURCE
Definition: shared.h:119
@ PIN_WAVEOUT_SOURCE
Definition: shared.h:114
@ PIN_VIRT_SURROUND_SOURCE
Definition: shared.h:127
@ PIN_PHONE_SOURCE
Definition: shared.h:116
@ PIN_MONOOUT_DEST
Definition: shared.h:133
@ PIN_VIRT_3D_MIX_MONO_SOURCE
Definition: shared.h:124
@ PIN_VIRT_FRONT_SOURCE
Definition: shared.h:130
@ PIN_VIRT_3D_DEPTH_SOURCE
Definition: shared.h:123
@ PIN_WAVEIN_DEST
Definition: shared.h:134
@ PIN_HPOUT_SOURCE
Definition: shared.h:132
@ PIN_MASTEROUT_DEST
Definition: shared.h:131
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
const int TOPO_MAX_CONNECTIONS
Definition: mintopo.h:42
struct PCCONNECTION_DESCRIPTOR * PPCCONNECTION_DESCRIPTOR
ULONG ConnectionCount
Definition: portcls.h:362
const PCCONNECTION_DESCRIPTOR * Connections
Definition: portcls.h:363
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by BuildTopology().

◆ BuildNodeDescriptors()

NTSTATUS CAC97MiniportTopology::BuildNodeDescriptors ( void  )
private

Definition at line 978 of file mintopo.cpp.

979{
980// Improvement would be to not use a Macro, use (inline) function instead.
981#define INIT_NODE( node, nodeptr, type, name, automation, index ) \
982 nodeptr->Type = (GUID*) type; \
983 nodeptr->Name = (GUID*) name; \
984 nodeptr->AutomationTable = automation; \
985 SetNodeTranslation (index++, node); \
986 nodeptr++
987
988 PAGED_CODE ();
989
990 NTSTATUS ntStatus = STATUS_SUCCESS;
991
992 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::BuildNodeDescriptors]"));
993
994 // allocate our descriptor memory
997 if (NodeDescriptors)
998 {
1000 ULONG Index = 0;
1001
1002 //
1003 // set default node descriptor parameters
1004 //
1006 sizeof(PCNODE_DESCRIPTOR));
1007
1008 // We don't have loopback mode currently. It is only used for testing anyway.
1009
1010 // Add the NODE_WAVEOUT_VOLUME node
1012 CurrentNode,
1015 &AutomationVolume,
1016 Index);
1017
1018 // add the NODE_WAVEOUT_MUTE node
1020 CurrentNode,
1023 &AutomationMute,
1024 Index);
1025
1026 // add the PCBEEP nodes
1027 if (AdapterCommon->GetPinConfig (PINC_PCBEEP_PRESENT))
1028 {
1029 // add the NODE_PCBEEP_VOLUME node
1031 CurrentNode,
1034 &AutomationVolume,
1035 Index);
1036
1037 // add the NODE_PCBEEP_MUTE node
1039 CurrentNode,
1042 &AutomationMute,
1043 Index);
1044 }
1045
1046 // add the PHONE nodes
1047 if (AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
1048 {
1049 // add the NODE_PHONE_VOLUME node
1051 CurrentNode,
1054 &AutomationVolume,
1055 Index);
1056
1057 // add the NODE_PHONE_MUTE node
1059 CurrentNode,
1062 &AutomationMute,
1063 Index);
1064 }
1065
1066 // add the MIC nodes
1067 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
1068 {
1069 if (AdapterCommon->GetPinConfig (PINC_MIC2_PRESENT))
1070 {
1071 // add the NODE_MIC_SELECT node
1073 CurrentNode,
1076 &AutomationSpecial,
1077 Index);
1078 }
1079
1080 // add the NODE_MIC_BOOST node
1082 CurrentNode,
1085 &AutomationSpecial,
1086 Index);
1087
1088 // add the NODE_MIC_VOLUME node
1090 CurrentNode,
1093 &AutomationVolume,
1094 Index);
1095
1096 // add the NODE_MIC_MUTE node
1098 CurrentNode,
1101 &AutomationMute,
1102 Index);
1103 }
1104
1105 if (AdapterCommon->GetPinConfig (PINC_LINEIN_PRESENT))
1106 {
1107 // add the NODE_LINEIN_VOLUME node
1109 CurrentNode,
1112 &AutomationVolume,
1113 Index);
1114
1115 // add the NODE_LINEIN_MUTE node
1117 CurrentNode,
1120 &AutomationMute,
1121 Index);
1122 }
1123
1124 if (AdapterCommon->GetPinConfig (PINC_CD_PRESENT))
1125 {
1126 // add the NODE_CD_VOLUME node
1128 CurrentNode,
1131 &AutomationVolume,
1132 Index);
1133
1134 // add the NODE_CD_MUTE node
1136 CurrentNode,
1139 &AutomationMute,
1140 Index);
1141 }
1142
1143 // add the VIDEO nodes
1144 if (AdapterCommon->GetPinConfig (PINC_VIDEO_PRESENT))
1145 {
1146 // add the NODE_VIDEO_VOLUME node
1148 CurrentNode,
1151 &AutomationVolume,
1152 Index);
1153
1154 // add the NODE_VIDEO_MUTE node
1156 CurrentNode,
1159 &AutomationMute,
1160 Index);
1161 }
1162
1163 // add the AUX nodes
1164 if (AdapterCommon->GetPinConfig (PINC_AUX_PRESENT))
1165 {
1166 // add the NODE_AUX_VOLUME node
1168 CurrentNode,
1171 &AutomationVolume,
1172 Index);
1173
1174 // add the NODE_AUX_MUTE node
1176 CurrentNode,
1179 &AutomationMute,
1180 Index);
1181 }
1182
1183 // add the NODE_MAIN_MIX node
1185 CurrentNode,
1188 NULL,
1189 Index);
1190
1191 // add the 3D nodes
1192 if (AdapterCommon->GetNodeConfig (NODEC_3D_PRESENT))
1193 {
1194 if (AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE))
1195 {
1196 // add the NODE_VIRT_3D_CENTER node
1198 CurrentNode,
1201 &Automation3D,
1202 Index);
1203 }
1204
1205 if (AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE) ||
1206 (!AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE) &&
1207 !AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE)))
1208 {
1209 // add the NODE_VIRT_3D_DEPTH node
1211 CurrentNode,
1214 &Automation3D,
1215 Index);
1216 }
1217
1218 // add the NODE_VIRT_3D_ENABLE node
1220 CurrentNode,
1223 &AutomationSpecial,
1224 Index);
1225
1226 // add the NODE_VIRT_WAVEOUT_3D_BYPASS node
1228 CurrentNode,
1231 &AutomationSpecial,
1232 Index);
1233 }
1234
1235 if (AdapterCommon->GetPinConfig (PINC_PCBEEP_PRESENT) ||
1236 AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
1237 {
1238 // add the NODE_BEEP_MIX node
1240 CurrentNode,
1243 NULL,
1244 Index);
1245 }
1246
1247 // add the tone nodes
1248 if (AdapterCommon->GetNodeConfig (NODEC_TONE_PRESENT))
1249 {
1250 // add the NODE_BASS node
1252 CurrentNode,
1255 &AutomationTone,
1256 Index);
1257
1258 // add the NODE_TREBLE node
1260 CurrentNode,
1263 &AutomationTone,
1264 Index);
1265
1266 if (AdapterCommon->GetNodeConfig (NODEC_LOUDNESS_PRESENT))
1267 {
1268 // add the NODE_LOUDNESS node
1270 CurrentNode,
1272 NULL,
1273 &AutomationSpecial,
1274 Index);
1275 }
1276
1277 if (AdapterCommon->GetNodeConfig (NODEC_SIMUL_STEREO_PRESENT))
1278 {
1279 // add the NODE_SIMUL_STEREO node
1281 CurrentNode,
1284 &AutomationSpecial,
1285 Index);
1286 }
1287 }
1288
1289 // Add a "Front Speaker" volume/mute if we have surround or headphones.
1290 // The "Master" volume/mute will be mono then
1291 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
1292 AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
1293 {
1294 // Add the front speaker volume.
1296 CurrentNode,
1299 &AutomationVolume,
1300 Index);
1301
1302 // Add the front speaker mute.
1304 CurrentNode,
1307 &AutomationMute,
1308 Index);
1309
1310 // Add the master mono out volume.
1312 CurrentNode,
1315 &AutomationVolume,
1316 Index);
1317
1318 // Add the master mono out volume.
1320 CurrentNode,
1323 &AutomationMute,
1324 Index);
1325 }
1326 else
1327 {
1328 // add the NODE_MASTEROUT_VOLUME node
1330 CurrentNode,
1333 &AutomationVolume,
1334 Index);
1335
1336 // add the NODE_MASTEROUT_MUTE node
1338 CurrentNode,
1341 &AutomationMute,
1342 Index);
1343 }
1344
1345 // Add the surround control if we have one.
1346 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
1347 {
1348 // Add the surround volume.
1350 CurrentNode,
1353 &AutomationVolume,
1354 Index);
1355
1356 // Add the surround mute.
1358 CurrentNode,
1361 &AutomationMute,
1362 Index);
1363
1364 // Add the center and LFE control if we have one.
1365 if (AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
1366 {
1367 // Add the center volume.
1369 CurrentNode,
1372 &AutomationVolume,
1373 Index);
1374
1375 // Add the center mute.
1377 CurrentNode,
1380 &AutomationMute,
1381 Index);
1382
1383 // Add the LFE volume.
1385 CurrentNode,
1388 &AutomationVolume,
1389 Index);
1390
1391 // Add the LFE mute.
1393 CurrentNode,
1396 &AutomationMute,
1397 Index);
1398 }
1399 }
1400
1401 // add the HPOUT nodes
1402 if (AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
1403 {
1404 // add the NODE_HPOUT_VOLUME node
1406 CurrentNode,
1409 &AutomationVolume,
1410 Index);
1411
1412 // add the NODE_HPOUT_MUTE node
1414 CurrentNode,
1417 &AutomationMute,
1418 Index);
1419 }
1420
1421 // add the NODE_WAVEIN_SELECT node
1423 CurrentNode,
1426 &AutomationMux,
1427 Index);
1428
1429 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
1430 {
1431 // add the NODE_VIRT_MASTER_INPUT_VOLUME1 node
1433 CurrentNode,
1436 &AutomationVolume,
1437 Index);
1438 }
1439
1440 if (AdapterCommon->GetPinConfig (PINC_CD_PRESENT))
1441 {
1442 // add the NODE_VIRT_MASTER_INPUT_VOLUME2 node
1444 CurrentNode,
1447 &AutomationVolume,
1448 Index);
1449 }
1450
1451 if (AdapterCommon->GetPinConfig (PINC_VIDEO_PRESENT))
1452 {
1453 // add the NODE_VIRT_MASTER_INPUT_VOLUME3 node
1455 CurrentNode,
1458 &AutomationVolume,
1459 Index);
1460 }
1461
1462 if (AdapterCommon->GetPinConfig (PINC_AUX_PRESENT))
1463 {
1464 // add the NODE_VIRT_MASTER_INPUT_VOLUME4 node
1466 CurrentNode,
1469 &AutomationVolume,
1470 Index);
1471 }
1472
1473 if (AdapterCommon->GetPinConfig (PINC_LINEIN_PRESENT))
1474 {
1475 // add the NODE_VIRT_MASTER_INPUT_VOLUME5 node
1477 CurrentNode,
1480 &AutomationVolume,
1481 Index);
1482 }
1483
1484 // add the NODE_VIRT_MASTER_INPUT_VOLUME6 node
1486 CurrentNode,
1489 &AutomationVolume,
1490 Index);
1491
1492 // add the NODE_VIRT_MASTER_INPUT_VOLUME7 node
1494 CurrentNode,
1497 &AutomationVolume,
1498 Index);
1499
1500 if (AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
1501 {
1502 // add the NODE_VIRT_MASTER_INPUT_VOLUME8 node
1504 CurrentNode,
1507 &AutomationVolume,
1508 Index);
1509 }
1510
1511 // add the MICIN nodes
1512 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT) &&
1513 AdapterCommon->GetPinConfig (PINC_MICIN_PRESENT))
1514 {
1515 // add the NODE_MICIN_VOLUME node
1517 CurrentNode,
1520 &AutomationVolume,
1521 Index);
1522
1523 // add the NODE_MICIN_MUTE node
1525 CurrentNode,
1528 &AutomationMute,
1529 Index);
1530 }
1531
1532 // add the MONOOUT nodes
1533 if (AdapterCommon->GetPinConfig (PINC_MONOOUT_PRESENT))
1534 {
1535 // add the NODE_MONOOUT_SELECT node
1537 CurrentNode,
1540 &AutomationMux,
1541 Index);
1542
1543 // add the NODE_VIRT_MONOOUT_VOLUME1 node
1545 CurrentNode,
1548 &AutomationVolume,
1549 Index);
1550
1551 // add the NODE_VIRT_MONOOUT_VOLUME2 node
1553 CurrentNode,
1556 &AutomationVolume,
1557 Index);
1558 }
1559
1560 // add the nodes to the filter descriptor
1564 }
1565 else
1566 {
1568 }
1569
1570 return ntStatus;
1571
1572#undef INIT_NODE
1573}
#define INIT_NODE(node, nodeptr, type, name, automation, index)
@ NODE_TOP_ELEMENT
Definition: shared.h:243
#define MYKSNAME_MAIN_MIX
Definition: guids.h:42
#define MYKSNAME_PHONE_VOLUME
Definition: guids.h:24
#define MYKSNAME_FRONT_VOLUME
Definition: guids.h:156
#define MYKSNAME_HPOUT_VOLUME
Definition: guids.h:66
#define MYKSNAME_MONOOUT_SELECT
Definition: guids.h:78
#define MYKSNAME_CENTER_VOLUME
Definition: guids.h:132
#define MYKSNAME_MICIN_MUTE
Definition: guids.h:108
#define MYKSNAME_WAVEIN_SELECT
Definition: guids.h:84
#define MYKSNAME_BEEP_MIX
Definition: guids.h:60
#define MYKSNAME_PHONE_MUTE
Definition: guids.h:30
#define MYKSNAME_HPOUT_MUTE
Definition: guids.h:72
#define MYKSNAME_SIMUL_STEREO
Definition: guids.h:114
#define MYKSNAME_WAVEOUT_3D_BYPASS
Definition: guids.h:48
#define MYKSNAME_MASTER_INPUT_VOLUME
Definition: guids.h:90
#define MYKSNAME_CENTER_MUTE
Definition: guids.h:138
#define MYKSNAME_3D_ENABLE
Definition: guids.h:54
#define MYKSNAME_MICIN_VOLUME
Definition: guids.h:102
#define MYKSNAME_LFE_MUTE
Definition: guids.h:150
#define MYKSNAME_LFE_VOLUME
Definition: guids.h:144
#define MYKSNAME_LINEIN_MUTE
Definition: guids.h:36
#define MYKSNAME_SURROUND_VOLUME
Definition: guids.h:120
#define MYKSNAME_SURROUND_MUTE
Definition: guids.h:126
#define MYKSNAME_FRONT_MUTE
Definition: guids.h:162
#define KSAUDFNAME_MONO_MIX_VOLUME
Definition: ksmedia.h:564
#define KSNODETYPE_TONE
Definition: ksmedia.h:453
#define KSAUDFNAME_PC_SPEAKER_VOLUME
Definition: ksmedia.h:514
#define KSAUDFNAME_MIC_MUTE
Definition: ksmedia.h:418
#define KSAUDFNAME_MICROPHONE_BOOST
Definition: ksmedia.h:403
#define KSNODETYPE_SUM
Definition: ksmedia.h:363
#define KSNODETYPE_LOUDNESS
Definition: ksmedia.h:398
#define KSAUDFNAME_VIDEO_MUTE
Definition: ksmedia.h:609
#define KSNODETYPE_MUX
Definition: ksmedia.h:433
#define KSAUDFNAME_AUX_MUTE
Definition: ksmedia.h:423
#define KSAUDFNAME_MASTER_VOLUME
Definition: ksmedia.h:368
#define KSAUDFNAME_STEREO_MIX_VOLUME
Definition: ksmedia.h:569
#define KSAUDFNAME_VIDEO_VOLUME
Definition: ksmedia.h:574
#define KSNODETYPE_VOLUME
Definition: ksmedia.h:338
#define KSAUDFNAME_CD_MUTE
Definition: ksmedia.h:408
#define KSNODETYPE_MUTE
Definition: ksmedia.h:348
#define KSAUDFNAME_LINE_IN_VOLUME
Definition: ksmedia.h:383
#define KSAUDFNAME_MASTER_MUTE
Definition: ksmedia.h:438
#define KSNODETYPE_AGC
Definition: ksmedia.h:267
#define KSAUDFNAME_BASS
Definition: ksmedia.h:584
#define KSAUDFNAME_WAVE_VOLUME
Definition: ksmedia.h:343
#define KSAUDFNAME_TREBLE
Definition: ksmedia.h:579
#define KSAUDFNAME_AUX_VOLUME
Definition: ksmedia.h:388
#define KSAUDFNAME_MIC_VOLUME
Definition: ksmedia.h:358
#define KSAUDFNAME_ALTERNATE_MICROPHONE
Definition: ksmedia.h:604
#define KSAUDFNAME_PC_SPEAKER_MUTE
Definition: ksmedia.h:599
#define KSAUDFNAME_CD_VOLUME
Definition: ksmedia.h:373
#define KSAUDFNAME_3D_DEPTH
Definition: ksmedia.h:589
#define KSAUDFNAME_WAVE_MUTE
Definition: ksmedia.h:353
#define KSAUDFNAME_3D_CENTER
Definition: ksmedia.h:559
struct PCNODE_DESCRIPTOR * PPCNODE_DESCRIPTOR
const PCNODE_DESCRIPTOR * Nodes
Definition: portcls.h:361
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by BuildTopology().

◆ BuildPinDescriptors()

NTSTATUS CAC97MiniportTopology::BuildPinDescriptors ( void  )
private

Definition at line 704 of file mintopo.cpp.

705{
706// Improvement would be to not use a Macro, use (inline) function instead.
707#define INIT_PIN( pin, pinptr, category, name, index ) \
708 pinptr->KsPinDescriptor.Category = (GUID*) category; \
709 pinptr->KsPinDescriptor.Name = (GUID*) name; \
710 SetPinTranslation (index++, pin); \
711 pinptr++
712
713 PAGED_CODE ();
714
715 ULONG Index;
716 PPCPIN_DESCRIPTOR CurrentPin;
717
718 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::BuildPinDescriptors]"));
719
720 // allocate our descriptor memory
723 if (!PinDescriptors)
725
726 //
727 // set default pin descriptor parameters
728 //
730
731 // spend some more time and set the pin descriptors to expected values.
732 for (CurrentPin = PinDescriptors, Index = 0; Index < PIN_TOP_ELEMENT;
733 CurrentPin++, Index++)
734 {
736 CurrentPin->KsPinDescriptor.DataRanges = PinDataRangePointersAnalogBridge;
737 CurrentPin->KsPinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
738 CurrentPin->KsPinDescriptor.Communication = KSPIN_COMMUNICATION_NONE;
739 }
740
741 //
742 // modify the individual pin descriptors
743 //
744 CurrentPin = PinDescriptors;
745 Index = 0;
746
747 // add the PIN_WAVEOUT_SOURCE pin descriptor (not optional)
749 CurrentPin,
751 NULL,
752 Index);
753
754 // add the PIN_PCBEEP_SOURCE pin descriptor (optional)
755 if (AdapterCommon->GetPinConfig (PINC_PCBEEP_PRESENT))
756 {
758 CurrentPin,
761 Index);
762 }
763
764 // add the PIN_PHONE_SOURCE pin descriptor (optional)
765 if (AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
766 {
768 CurrentPin,
770 NULL,
771 Index);
772 }
773
774 // add the PIN_MIC_SOURCE pin descriptor (could be disabled)
775 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
776 {
778 CurrentPin,
780 NULL,
781 Index);
782 }
783
784 // add the PIN_LINEIN_SOURCE pin descriptor (could be disabled)
785 if (AdapterCommon->GetPinConfig (PINC_LINEIN_PRESENT))
786 {
788 CurrentPin,
791 Index);
792 }
793
794 // add the PIN_CD_SOURCE pin descriptor (could be disabled)
795 if (AdapterCommon->GetPinConfig (PINC_CD_PRESENT))
796 {
798 CurrentPin,
801 Index);
802 }
803
804 // add the PIN_VIDEO_SOURCE pin descriptor (optional)
805 if (AdapterCommon->GetPinConfig (PINC_VIDEO_PRESENT))
806 {
808 CurrentPin,
811 Index);
812 }
813
814 // add the PIN_AUX_SOURCE pin descriptor (optional)
815 if (AdapterCommon->GetPinConfig (PINC_AUX_PRESENT))
816 {
818 CurrentPin,
821 Index);
822 }
823
824 // add the PIN_VIRT_TONE_MIX_SOURCE pin descriptor (not optional)
826 CurrentPin,
829 Index);
830
831 // add the PIN_VIRT_TONE_MIX_MONO_SOURCE pin descriptor (not optional)
833 CurrentPin,
836 Index);
837
838 // create a virt. pin for the 3D controls
839 if (AdapterCommon->GetNodeConfig (NODEC_3D_PRESENT))
840 {
841 if (AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE))
842 {
844 CurrentPin,
847 Index);
848 }
849
850 // A weird way would be to have 3D but only fixed sliders. In that case,
851 // display one fixed slider (3D depth).
852 if (AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE) ||
853 (!AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE) &&
854 !AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE)))
855 {
857 CurrentPin,
860 Index);
861 }
862 }
863
864 // Add a "Front speaker" pin if we have multichannel or headphones.
865 // We use a master mono then ...
866 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
867 AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
868 {
869 // Add a "Front speaker" pin, because in multichannel we want
870 // to display a master mono that effects all channels.
872 CurrentPin,
875 Index);
876 }
877
878 // check for multichannel
879 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
880 {
881 // Add the Rear Speaker Volume pin.
883 CurrentPin,
886 Index);
887
888 // add the Center Volume pin if we support at least 6 channel.
889 if (AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
890 {
892 CurrentPin,
895 Index);
896
898 CurrentPin,
901 Index);
902 }
903 }
904
905 // add the PIN_MASTEROUT_DEST pin descriptor (not optional)
906 CurrentPin->KsPinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
908 CurrentPin,
911 Index);
912
913 // add the PIN_HPOUT_SOURCE pin descriptor (optional)
914 if (AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
915 {
917 CurrentPin,
919 NULL,
920 Index);
921 }
922
923 // add the PIN_WAVEIN_DEST pin descriptor (not optional)
924 CurrentPin->KsPinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
926 CurrentPin,
928 NULL,
929 Index);
930
931 // add the PIN_MICIN_DEST pin descriptor (optional)
932 if (AdapterCommon->GetPinConfig (PINC_MICIN_PRESENT) &&
933 AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
934 {
935 CurrentPin->KsPinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
937 CurrentPin,
939 NULL,
940 Index);
941 }
942
943 // add the PIN_MONOOUT_DEST pin descriptor (optional)
944 if (AdapterCommon->GetPinConfig (PINC_MONOOUT_PRESENT))
945 {
946 // add the PIN_VIRT_3D_MIX_MONO_SOURCE pin descriptor
948 CurrentPin,
951 Index);
952
953 CurrentPin->KsPinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
954 // and the normal output pin
956 CurrentPin,
959 Index);
960 }
961
962 // add the pin descriptor informatin to the filter descriptor
966
967
968 return STATUS_SUCCESS;
969
970#undef INIT_PIN
971}
#define INIT_PIN(pin, pinptr, category, name, index)
#define SIZEOF_ARRAY(ar)
Definition: cdrom.h:1482
static PKSDATARANGE PinDataRangePointersAnalogBridge[]
Definition: miniport.cpp:49
@ PIN_TOP_ELEMENT
Definition: shared.h:136
#define MYKSNAME_CENTER
Definition: guids.h:174
#define MYKSNAME_LFE
Definition: guids.h:180
#define MYKSNAME_SURROUND
Definition: guids.h:168
#define MYKSNAME_FRONT
Definition: guids.h:186
@ KSPIN_DATAFLOW_IN
Definition: ks.h:1249
@ KSPIN_DATAFLOW_OUT
Definition: ks.h:1250
@ KSPIN_COMMUNICATION_NONE
Definition: ks.h:1254
#define KSAUDFNAME_LINE_IN
Definition: ksmedia.h:534
#define KSNODETYPE_CD_PLAYER
Definition: ksmedia.h:302
#define KSNODETYPE_MICROPHONE
Definition: ksmedia.h:297
#define KSAUDFNAME_CD_AUDIO
Definition: ksmedia.h:524
#define KSNODETYPE_ANALOG_CONNECTOR
Definition: ksmedia.h:323
#define KSAUDFNAME_MONO_OUT
Definition: ksmedia.h:594
#define KSAUDFNAME_MONO_MIX
Definition: ksmedia.h:554
#define KSAUDFNAME_VOLUME_CONTROL
Definition: ksmedia.h:428
#define KSAUDFNAME_AUX
Definition: ksmedia.h:544
#define KSAUDFNAME_STEREO_MIX
Definition: ksmedia.h:549
#define KSNODETYPE_LINE_CONNECTOR
Definition: ksmedia.h:318
#define KSAUDFNAME_PC_SPEAKER
Definition: ksmedia.h:529
#define KSCATEGORY_AUDIO
Definition: ksmedia.h:172
#define KSNODETYPE_HEADPHONES
Definition: ksmedia.h:484
#define KSAUDFNAME_VIDEO
Definition: ksmedia.h:539
#define KSNODETYPE_SPEAKER
Definition: ksmedia.h:328
#define KSNODETYPE_PHONE_LINE
Definition: ksmedia.h:519
struct PCPIN_DESCRIPTOR * PPCPIN_DESCRIPTOR
const PCPIN_DESCRIPTOR * Pins
Definition: portcls.h:358
KSPIN_DESCRIPTOR KsPinDescriptor
Definition: portcls.h:343

Referenced by BuildTopology().

◆ BuildTopology()

NTSTATUS CAC97MiniportTopology::BuildTopology ( void  )
private

Definition at line 656 of file mintopo.cpp.

657{
658 PAGED_CODE ();
659
660 NTSTATUS ntStatus = STATUS_SUCCESS;
661
662 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::BuildTopology]"));
663
664 // allocate our filter descriptor
668 {
669 // clear out the filter descriptor
671
672#ifdef INCLUDE_PRIVATE_PROPERTY
673 // Set the Filter automation table.
674 FilterDescriptor->AutomationTable = &FilterAutomationPrivate;
675#endif
676
677 // build the pin list
678 ntStatus = BuildPinDescriptors ();
679 if (NT_SUCCESS (ntStatus))
680 {
681 // build the node list
682 ntStatus = BuildNodeDescriptors ();
683 if (NT_SUCCESS (ntStatus))
684 {
685 // build the connection list
686 ntStatus = BuildConnectionDescriptors ();
687 }
688 }
689 }
690 else
691 {
693 }
694
695 // that's whatever one of these build... functions returned.
696 return ntStatus;
697}
NTSTATUS BuildPinDescriptors(void)
Definition: mintopo.cpp:704
NTSTATUS BuildNodeDescriptors(void)
Definition: mintopo.cpp:978
NTSTATUS BuildConnectionDescriptors(void)
Definition: mintopo.cpp:1580
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct PCFILTER_DESCRIPTOR * PPCFILTER_DESCRIPTOR
const PCAUTOMATION_TABLE * AutomationTable
Definition: portcls.h:355

◆ DECLARE_STD_UNKNOWN()

CAC97MiniportTopology::DECLARE_STD_UNKNOWN ( )

◆ DEFINE_STD_CONSTRUCTOR()

CAC97MiniportTopology::DEFINE_STD_CONSTRUCTOR ( CAC97MiniportTopology  )

◆ GetDBValues()

NTSTATUS CAC97MiniportTopology::GetDBValues ( IN PADAPTERCOMMON  AdapterCommon,
IN TopoNodes  Node,
OUT LONG plMinimum,
OUT LONG plMaximum,
OUT ULONG puStep 
)
static

Definition at line 155 of file prophnd.cpp.

163{
164 PAGED_CODE();
165
166 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::GetDBValues]"));
167
168 // This is going to be simple. Check the node and return the parameters.
169 switch (Node)
170 {
171 // These nodes could have 5bit or 6bit controls, so we first
172 // have to check this.
178 case NODE_LFE_VOLUME:
181 // needed for the config query
183
184 // which node to query?
188 if (Node == NODE_HPOUT_VOLUME)
194
195 // check if we have 6th bit support.
196 if (AdapterCommon->GetNodeConfig (config))
197 {
198 // 6bit control
199 *plMaximum = 0; // 0 dB
200 *plMinimum = 0xFFA18000; // -94.5 dB
201 *puStep = 0x00018000; // 1.5 dB
202 }
203 else
204 {
205 // 5bit control
206 *plMaximum = 0; // 0 dB
207 *plMinimum = 0xFFD18000; // -46.5 dB
208 *puStep = 0x00018000; // 1.5 dB
209 }
210 break;
211
213 // This virtual control gets added to the speaker volumes.
214 // We assume 5-bit volumes.
215 *plMaximum = 0; // 0 dB
216 *plMinimum = 0xFFD18000; // -46.5 dB
217 *puStep = 0x00018000; // 1.5 dB
218 break;
219
221 *plMaximum = 0; // 0 dB
222 *plMinimum = 0xFFD30000; // -45 dB
223 *puStep = 0x00030000; // 3 dB
224 break;
225
229 case NODE_CD_VOLUME:
231 case NODE_AUX_VOLUME:
233 *plMaximum = 0x000C0000; // 12 dB
234 *plMinimum = 0xFFDD8000; // -34.5 dB
235 *puStep = 0x00018000; // 1.5 dB
236 break;
237
238
247 case NODE_MIC_VOLUME:
248 *plMaximum = 0x00168000; // 22.5 dB
249 *plMinimum = 0; // 0 dB
250 *puStep = 0x00018000; // 1.5 dB
251 break;
252
253 case NODE_BASS:
254 case NODE_TREBLE:
255 *plMaximum = 0x000A8000; // 10.5 dB
256 *plMinimum = 0xFFF58000; // -10.5 dB
257 *puStep = 0x00018000; // 1.5 dB
258 break;
259
260 // These nodes can be fixed or variable.
261 // Normally we won't display a fixed volume slider, but if 3D is
262 // supported and both sliders are fixed, we have to display one fixed
263 // slider for the advanced control panel.
266 if (AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE) &&
268 {
269 *plMaximum = 0x000F0000; // +15 dB
270 *plMinimum = 0x00000000; // 0 dB
271 *puStep = 0x00010000; // 1 dB
272 }
273 else
274 if (AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE) &&
276 {
277 *plMaximum = 0x000F0000; // +15 dB
278 *plMinimum = 0x00000000; // 0 dB
279 *puStep = 0x00010000; // 1 dB
280 }
281 else
282 {
283 // In case it is fixed, read the value and return it.
284 WORD wRegister;
285
286 // read the register
287 if (!NT_SUCCESS (AdapterCommon->ReadCodecRegister (
288 AdapterCommon->GetNodeReg (Node), &wRegister)))
289 wRegister = 0; // in case we fail.
290
291 // mask out the control
292 wRegister &= AdapterCommon->GetNodeMask (Node);
294 {
295 wRegister >>= 8;
296 }
297 // calculate the dB value.
298 *plMaximum = (DWORD)(-wRegister) << 16; // fixed value
299 *plMinimum = (DWORD)(-wRegister) << 16; // fixed value
300 *puStep = 0x00010000; // 1 dB
301 }
302 break;
303
304 case NODE_INVALID:
305 default:
306 // poeser pupe, tu.
307 DOUT (DBG_ERROR, ("GetDBValues: Invalid node requested."));
309 }
310
311 return STATUS_SUCCESS;
312}
struct config_s config
@ NODE_INVALID
Definition: shared.h:244
TopoNodeConfig
Definition: shared.h:84
@ NODEC_6BIT_CENTER_LFE_VOLUME
Definition: shared.h:93
@ NODEC_6BIT_HPOUT_VOLUME
Definition: shared.h:90
@ NODEC_6BIT_SURROUND_VOLUME
Definition: shared.h:92
@ NODEC_6BIT_MONOOUT_VOLUME
Definition: shared.h:91
@ NODEC_6BIT_MASTER_VOLUME
Definition: shared.h:89
unsigned short WORD
Definition: ntddk_ex.h:93
#define DBG_ERROR
Definition: nfs41_debug.h:78
#define DWORD
Definition: nt_native.h:44
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: dlist.c:348

Referenced by BasicSupportHandler(), PropertyHandler_Level(), PropertyHandler_Tone(), PropertyHandler_Ulong(), and SetMultichannelVolume().

◆ PropertyHandler_CpuResources()

NTSTATUS CAC97MiniportTopology::PropertyHandler_CpuResources ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 1624 of file prophnd.cpp.

1628{
1629 PAGED_CODE ();
1630
1631 ASSERT (PropertyRequest);
1632
1633 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_CpuResources]"));
1634
1635 CAC97MiniportTopology *that =
1636 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
1638
1639 ASSERT (that);
1640
1641 // validate node
1642 if (PropertyRequest->Node == (ULONG)-1)
1643 return ntStatus;
1644
1645 // validate the node def.
1646 if (that->TransNodeNrToNodeDef (PropertyRequest->Node) == NODE_INVALID)
1647 return ntStatus;
1648
1649 // we should do a get
1650 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
1651 {
1652 // just return the flag.
1653 if (PropertyRequest->ValueSize >= sizeof(LONG))
1654 {
1655 *((PLONG)PropertyRequest->Value) = KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU;
1656 PropertyRequest->ValueSize = sizeof(LONG);
1657 ntStatus = STATUS_SUCCESS;
1658 }
1659 else // not enough buffer.
1660 {
1661 ntStatus = STATUS_BUFFER_TOO_SMALL;
1662 }
1663 }
1664
1665 return ntStatus;
1666}
#define KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU
Definition: ksmedia.h:1198
long LONG
Definition: pedump.c:60
int32_t * PLONG
Definition: typedefs.h:58
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

◆ PropertyHandler_Level()

NTSTATUS CAC97MiniportTopology::PropertyHandler_Level ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 681 of file prophnd.cpp.

685{
686 PAGED_CODE ();
687
688 ASSERT (PropertyRequest);
689
690 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_Level]"));
691
693 TopoNodes NodeDef;
694 LONG channel;
696 ULONG uStep;
697 // The major target is the object pointer to the topology miniport.
699 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
700
701 ASSERT (that);
702
703 // validate node
704 if (PropertyRequest->Node == (ULONG)-1)
705 return ntStatus;
706
707 // do the appropriate action for the request.
708
709 // we should do a get or a set?
710 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
711 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
712 {
713 // validate parameters
714 if ((PropertyRequest->InstanceSize < sizeof(LONG)) ||
715 (PropertyRequest->ValueSize < sizeof(LONG)))
716 return ntStatus;
717
718 // get channel information
719 channel = *((PLONG)PropertyRequest->Instance);
720
721 // check channel types, return when unknown
722 // as you can see, we have no multichannel support.
723 if ((channel != CHAN_LEFT) &&
724 (channel != CHAN_RIGHT) &&
725 (channel != CHAN_MASTER))
726 return ntStatus;
727
728 // get the buffer
729 PLONG Level = (PLONG)PropertyRequest->Value;
730
731 // Switch on the node id. This is just for parameter checking.
732 // If something goes wrong, we will immideately return with
733 // ntStatus, which is STATUS_INVALID_PARAMETER.
734 switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
735 {
736 // these are mono channels, don't respond to a right channel
737 // request.
740 case NODE_MIC_VOLUME:
749 case NODE_LFE_VOLUME:
750 // check type
751 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_VOLUMELEVEL)
752 return ntStatus;
753 // check channel
754 if (channel == CHAN_RIGHT)
755 return ntStatus;
756 // Well, this is a fake for the routine below that should work
757 // for all nodes ... On AC97 the right channel are the LSBs and
758 // mono channels have only LSBs used. Windows however thinks that
759 // mono channels are left channels (only). So we could say here
760 // we have a right channel request (to prg. the LSBs) instead of
761 // a left channel request. But we have some controls that are HW-
762 // stereo, but exposed to the system as mono. These are the virtual
763 // volume controls in front of the wave-in muxer for the MIC, PHONE
764 // and MONO MIX signals (see to the switch:
765 // NODE_VIRT_MASTER_INPUT_VOLUME1, 7 and 8). Saying we have a MASTER
766 // request makes sure the value is prg. for left and right channel,
767 // but on HW-mono controls the right channel is prg. only, cause the
768 // mask in ac97reg.h leads to a 0-mask for left channel prg. which
769 // just does nothing ;)
770 channel = CHAN_MASTER;
771 break;
772
773 // These are stereo channels.
779 case NODE_CD_VOLUME:
781 case NODE_AUX_VOLUME:
788 // check type
789 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_VOLUMELEVEL)
790 return ntStatus;
791 // check channel; we don't support a get with master
792 if ((channel == CHAN_MASTER) &&
793 (PropertyRequest->Verb & KSPROPERTY_TYPE_GET))
794 return ntStatus;
795 break;
796
797 case NODE_INVALID:
798 default:
799 // Ooops
800 DOUT (DBG_ERROR, ("PropertyHandler_Level: Invalid node requested."));
801 return ntStatus;
802 }
803
804 // Now, do some action!
805
806 // get the registered dB values.
807 ntStatus = GetDBValues (that->AdapterCommon, NodeDef, &lMinimum,
808 &lMaximum, &uStep);
809 if (!NT_SUCCESS (ntStatus))
810 return ntStatus;
811
812 // do a get
813 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
814 {
815 WORD wRegister;
816
817 // Read the HW register for the node except NODE_VIRT_MASTERMONO_VOLUME
818 // since this is pure virtual.
819 if (NodeDef != NODE_VIRT_MASTERMONO_VOLUME)
820 {
821 // Get the register and read it.
822 ntStatus = that->AdapterCommon->ReadCodecRegister (
823 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
824 if (!NT_SUCCESS (ntStatus))
825 return ntStatus;
826
827 // mask out every unused bit and rotate.
828 if (channel == CHAN_LEFT)
829 {
830 wRegister = (wRegister & (that->AdapterCommon->GetNodeMask (NodeDef)
831 & AC97REG_MASK_LEFT)) >> 8;
832 }
833 else // here goes mono or stereo-right
834 {
835 wRegister &= (that->AdapterCommon->GetNodeMask (NodeDef) &
837 }
838
839 // Oops - NODE_PCBEEP_VOLUME doesn't use bit0. We have to adjust.
840 if (NodeDef == NODE_PCBEEP_VOLUME)
841 wRegister >>= 1;
842
843 // we have to translate the reg to dB.dB value.
844
845 switch (NodeDef)
846 {
847 // for record, we calculate it reverse.
857 *Level = lMinimum + uStep * wRegister;
858 break;
859 default:
860 *Level = lMaximum - uStep * wRegister;
861 break;
862 }
863
864 // For the virtual controls, which are in front of a muxer, there
865 // is no mute control displayed. But we have a HW mute control, so
866 // what we do is enabling this mute when the user moves the slider
867 // down to the bottom and disabling it on every other position.
868 // We will return a PROP_MOST_NEGATIVE value in case the slider
869 // is moved to the bottom.
870 // We do this only for the "mono muxer" since the volume there ranges
871 // from 0 to -46.5dB. The record volumes only have a range from
872 // 0 to +22.5dB and we cannot mute them when the slider is down.
873 if ((NodeDef == NODE_VIRT_MONOOUT_VOLUME1) ||
874 (NodeDef == NODE_VIRT_MONOOUT_VOLUME2))
875 {
876 // read the register again.
877 ntStatus = that->AdapterCommon->ReadCodecRegister (
878 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
879 if (!NT_SUCCESS (ntStatus))
880 return ntStatus;
881 // return most negative value in case it is checked.
882 if (wRegister & AC97REG_MASK_MUTE)
884 }
885 }
886 else // This is master mono volume.
887 {
888 // Assume 0dB for master mono volume.
889 *Level = 0;
890 }
891
892 // when we have cache information then return this instead
893 // of the calculated value. if we don't, store the calculated
894 // value.
895 // We do that twice for master because in case we didn't set
896 // the NodeCache yet it will be set then.
897 if ((channel == CHAN_LEFT) || (channel == CHAN_MASTER))
898 {
899 if (that->stNodeCache[NodeDef].bLeftValid)
900 *Level = that->stNodeCache[NodeDef].lLeft;
901 else
902 {
903 that->stNodeCache[NodeDef].lLeft = *Level;
904 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
905 }
906 }
907
908 if ((channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
909 {
910 if (that->stNodeCache[NodeDef].bRightValid)
911 *Level = that->stNodeCache[NodeDef].lRight;
912 else
913 {
914 that->stNodeCache[NodeDef].lRight = *Level;
915 that->stNodeCache[NodeDef].bRightValid = (BYTE)-1;
916 }
917 }
918
919 // thats all, good bye.
920 PropertyRequest->ValueSize = sizeof(LONG);
921 DOUT (DBG_PROPERTY, ("GET: %s(%s) = 0x%x",NodeStrings[NodeDef],
922 channel==CHAN_LEFT ? "L" : "R", *Level));
923
924 // ntStatus was set with the read call! whatever this is, return it.
925 }
926 else // this must be a set
927 {
928 WORD wRegister;
929 LONG lLevel = *Level;
930
931 //
932 // Check borders.
933 //
934 // These 2 lines will have a special effect on sndvol32.
935 // Whenever you move the balance slider on a volume, one channel
936 // keeps the same and the other volume channel gets descreased.
937 // With ac97 on recording controls, the default slider position
938 // is at 0dB and the range of the volume is 0dB till +22.5dB.
939 // That means that panning (moving the balance slider) is simply
940 // impossible. If you would store the volume like sndvol gives it
941 // to you and you return it on a get, then the balance slider
942 // moves and stays at the position the user wanted it. However,
943 // if you return the actual volume the balance slider will jump
944 // back to the position that the HW can do (play with it to see
945 // how it works).
946 //
947 if (lLevel > lMaximum) lLevel = lMaximum;
948 if (lLevel < lMinimum) lLevel = lMinimum;
949
950 // First update the node cache.
951 if ((channel == CHAN_LEFT) || (channel == CHAN_MASTER))
952 {
953 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
954 that->stNodeCache[NodeDef].lLeft = lLevel;
955 }
956 if ((channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
957 {
958 that->stNodeCache[NodeDef].bRightValid = (BYTE)-1;
959 that->stNodeCache[NodeDef].lRight = lLevel;
960 }
961
962 //
963 // If we have a master mono, then we have to program the speaker
964 // volumes a little different.
965 // Check for master mono (surround or headphone present) and
966 // if one of the speaker volumes is requested.
967 //
968 if ((that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
969 that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT)) &&
970 ((NodeDef == NODE_VIRT_MASTERMONO_VOLUME) || (NodeDef == NODE_LFE_VOLUME) ||
971 (NodeDef == NODE_CENTER_VOLUME) || (NodeDef == NODE_FRONT_VOLUME) ||
972 (NodeDef == NODE_SURROUND_VOLUME) || (NodeDef == NODE_HPOUT_VOLUME)))
973 {
974 //
975 // For master mono we have to update all speaker volumes.
976 //
977 if (NodeDef == NODE_VIRT_MASTERMONO_VOLUME)
978 {
979 // Update all speaker volumes.
980 ntStatus = SetMultichannelVolume (that, NODE_FRONT_VOLUME);
981 if (that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
982 ntStatus = SetMultichannelVolume (that, NODE_HPOUT_VOLUME);
983 if (that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
985 if (that->AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
986 {
987 ntStatus = SetMultichannelVolume (that, NODE_CENTER_VOLUME);
988 ntStatus = SetMultichannelVolume (that, NODE_LFE_VOLUME);
989 }
990 }
991 else // update the individual speaker volume only.
992 {
993 ntStatus = SetMultichannelVolume (that, NodeDef);
994 }
995 }
996 else // This is for all other volumes (or no master mono present).
997 {
998 // calculate the dB.dB value.
999
1000 // The nodes are calculated differently.
1001 switch (NodeDef)
1002 {
1003 // for record controls we calculate it 'reverse'.
1012 // read the wavein selector.
1013 ntStatus = that->AdapterCommon->ReadCodecRegister (
1014 that->AdapterCommon->GetNodeReg (NODE_WAVEIN_SELECT),
1015 &wRegister);
1016 if (!NT_SUCCESS (ntStatus))
1017 return ntStatus;
1018
1019 // mask out every unused bit.
1020 wRegister &= (that->AdapterCommon->GetNodeMask (
1022
1023 // check if the volume that we change belongs to the active
1024 // (selected) virtual channel.
1025 // Tricky: If the virtual nodes are not defined consecutively
1026 // this comparision will fail.
1027 if ((NodeDef - NODE_VIRT_MASTER_INPUT_VOLUME1) != wRegister)
1028 return ntStatus;
1029
1030 // fall through for calculation.
1031
1032 case NODE_MICIN_VOLUME:
1033 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1034 break;
1035
1038 // read the monoout selector.
1039 ntStatus = that->AdapterCommon->ReadCodecRegister (
1040 that->AdapterCommon->GetNodeReg (NODE_MONOOUT_SELECT),
1041 &wRegister);
1042 if (!NT_SUCCESS (ntStatus))
1043 return ntStatus;
1044
1045 // mask out every unused bit.
1046 wRegister &= that->AdapterCommon->GetNodeMask (NODE_MONOOUT_SELECT);
1047
1048 // check if the volume that we change belongs to the active
1049 // (selected) virtual channel.
1050 // Note: Monout select is set if we want to prg. MIC (Volume2).
1051 if ((!wRegister && (NodeDef == NODE_VIRT_MONOOUT_VOLUME2)) ||
1052 (wRegister && (NodeDef == NODE_VIRT_MONOOUT_VOLUME1)))
1053 return ntStatus;
1054
1055 // fall through for calculation.
1056 default:
1057 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1058 break;
1059 }
1060
1061 // Oops - NODE_PCBEEP_VOLUME doesn't use bit0. We have to adjust.
1062 if (NodeDef == NODE_PCBEEP_VOLUME)
1063 wRegister <<= 1;
1064
1065 // write the stuff (with mask!).
1066 // Note: mono channels are 'master' here (see fake above).
1067 // this makes sure that left and right channel is prg. for the virt.
1068 // controls. On controls that only have the right channel, the left
1069 // channel programming does nothing cause the mask will be zero.
1070 if ((channel == CHAN_LEFT) || (channel == CHAN_MASTER))
1071 {
1072 // write only left.
1073 ntStatus = that->AdapterCommon->WriteCodecRegister (
1074 that->AdapterCommon->GetNodeReg (NodeDef),
1075 wRegister << 8,
1076 that->AdapterCommon->GetNodeMask (NodeDef) & AC97REG_MASK_LEFT);
1077 // immediately return on error
1078 if (!NT_SUCCESS (ntStatus))
1079 return ntStatus;
1080 }
1081
1082 if ((channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
1083 {
1084 // write only right.
1085 ntStatus = that->AdapterCommon->WriteCodecRegister (
1086 that->AdapterCommon->GetNodeReg (NodeDef),
1087 wRegister,
1088 that->AdapterCommon->GetNodeMask (NodeDef) & AC97REG_MASK_RIGHT);
1089 // immediately return on error
1090 if (!NT_SUCCESS (ntStatus))
1091 return ntStatus;
1092 }
1093
1094 // For the virtual controls, which are in front of a muxer, there
1095 // is no mute control displayed. But we have a HW mute control, so
1096 // what we do is enabling this mute when the user moves the slider
1097 // down to the bottom and disabling it on every other position.
1098 // We do this only for the "mono muxer", the recording mutes will
1099 // never be muted.
1100 // Tricky: Master input virtual controls must be defined consecutively.
1101 if ((NodeDef >= NODE_VIRT_MASTER_INPUT_VOLUME1) &&
1102 (NodeDef <= NODE_VIRT_MASTER_INPUT_VOLUME8))
1103 {
1104 // disable the mute; this only works because the mute and volume
1105 // share the same register.
1106 ntStatus = that->AdapterCommon->WriteCodecRegister (
1107 that->AdapterCommon->GetNodeReg (NodeDef),
1109
1110 // Just in case.
1111 that->UpdateRecordMute ();
1112 }
1113
1114 if ((NodeDef == NODE_VIRT_MONOOUT_VOLUME1) ||
1115 (NodeDef == NODE_VIRT_MONOOUT_VOLUME2))
1116 {
1117 // these are only mono controls so checking one entry is enough.
1118 if ( that->stNodeCache[NodeDef].bLeftValid &&
1119 (that->stNodeCache[NodeDef].lLeft <= lMinimum))
1120 {
1121 // set the mute; this only works because the mute and volume
1122 // share the same register.
1123 ntStatus = that->AdapterCommon->WriteCodecRegister (
1124 that->AdapterCommon->GetNodeReg (NodeDef),
1126 }
1127 else
1128 {
1129 // clear the mute; this only works because the mute and volume
1130 // share the same register.
1131 ntStatus = that->AdapterCommon->WriteCodecRegister (
1132 that->AdapterCommon->GetNodeReg (NodeDef),
1134 }
1135 }
1136 }
1137
1138 DOUT (DBG_PROPERTY, ("SET: %s(%s) -> 0x%x", NodeStrings[NodeDef],
1139 channel==CHAN_LEFT ? "L" : channel==CHAN_RIGHT ? "R" : "M",
1140 *Level));
1141
1142 // ntStatus was set with the read call! whatever this is, return it.
1143 }
1144 }
1145 else
1146 {
1147 if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
1148 {
1149 ntStatus = BasicSupportHandler (PropertyRequest);
1150 }
1151 }
1152
1153 return ntStatus;
1154}
tNodeCache stNodeCache[NODE_TOP_ELEMENT]
Definition: mintopo.h:106
static NTSTATUS BasicSupportHandler(IN PPCPROPERTY_REQUEST PropertyRequest)
Definition: prophnd.cpp:573
static NTSTATUS SetMultichannelVolume(IN CAC97MiniportTopology *that, IN TopoNodes Volume)
Definition: prophnd.cpp:77
void UpdateRecordMute(void)
Definition: mintopo.cpp:2053
#define CHAN_MASTER
Definition: interfaces.hpp:68
#define CHAN_RIGHT
Definition: interfaces.hpp:67
#define CHAN_LEFT
Definition: interfaces.hpp:66
@ KSPROPERTY_AUDIO_VOLUMELEVEL
Definition: ksmedia.h:1057
const WORD AC97REG_MASK_RIGHT
Definition: mintopo.h:49
const WORD AC97REG_MASK_MUTE
Definition: mintopo.h:50
const WORD AC97REG_MASK_LEFT
Definition: mintopo.h:48
const long PROP_MOST_NEGATIVE
Definition: mintopo.h:56
LONG lMinimum
Definition: mmsystem.h:0
LONG lMaximum
Definition: mmsystem.h:1
BYTE bLeftValid
Definition: mintopo.h:77
BYTE bRightValid
Definition: mintopo.h:78
long lLeft
Definition: mintopo.h:75
long lRight
Definition: mintopo.h:76
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
unsigned char BYTE
Definition: xxhash.c:193

◆ PropertyHandler_OnOff()

NTSTATUS CAC97MiniportTopology::PropertyHandler_OnOff ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 326 of file prophnd.cpp.

330{
331 PAGED_CODE ();
332
333 ASSERT (PropertyRequest);
334
336 LONG channel;
337 TopoNodes NodeDef;
338 // The major target is the object pointer to the topology miniport.
340 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
341
342 ASSERT (that);
343
344 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_OnOff]"));
345
346 // validate node
347 if (PropertyRequest->Node == (ULONG)-1)
348 return ntStatus;
349
350 // do the appropriate action for the request.
351
352 // we should do a get or a set?
353 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
354 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
355 {
356 // validate parameters
357 if ((PropertyRequest->InstanceSize < sizeof(LONG)) ||
358 (PropertyRequest->ValueSize < sizeof(BOOL)))
359 return ntStatus;
360
361 // get channel
362 channel = *(PLONG)PropertyRequest->Instance;
363
364 // check channel types, return when unknown
365 // as you can see, we have no multichannel support.
366 if ((channel != CHAN_LEFT) &&
367 (channel != CHAN_RIGHT) &&
368 (channel != CHAN_MASTER))
369 return ntStatus;
370
371 // We have only mono mutes or On/Off checkboxes although they might control
372 // a stereo path. For example, we have a 1-bit mute for CD Volume. This
373 // mute controls both CD Volume channels.
374 if (channel == CHAN_RIGHT)
375 return ntStatus;
376
377 // get the buffer
378 PBOOL OnOff = (PBOOL)PropertyRequest->Value;
379
380 // Switch on the node id. This is just for parameter checking.
381 // If something goes wrong, we will immediately return with
382 // ntStatus, which is STATUS_INVALID_PARAMETER.
383 switch (NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
384 {
385 // These are mutes for mono volumes.
386 case NODE_PCBEEP_MUTE:
387 case NODE_PHONE_MUTE:
388 case NODE_MIC_MUTE:
389 case NODE_MICIN_MUTE:
390 case NODE_CENTER_MUTE:
391 case NODE_LFE_MUTE:
393 // check type
394 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_MUTE)
395 return ntStatus;
396 break;
397
398 // Well, this one is a AGC, although there is no _automatic_ gain
399 // control, but we have a mic boost (which is some kind of manual
400 // gain control).
401 // The 3D Bypass is a real fake, but that's how you get check boxes
402 // on the advanced control panel.
403 // Both controls are in a mono path.
405 case NODE_MIC_BOOST:
406 // check type
407 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_AGC)
408 return ntStatus;
409 break;
410
411 // Simulated Stereo is a AGC control in a stereo path.
413 // check type
414 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_AGC)
415 return ntStatus;
416 break;
417
418 // This is a loudness control in a stereo path. We have to check the
419 // type.
420 case NODE_LOUDNESS:
421 // check type
422 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_LOUDNESS)
423 return ntStatus;
424 break;
425
426 // For 3D Enable and Mic are exposed as loudness in a mono path.
428 case NODE_MIC_SELECT:
429 // check type
430 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_LOUDNESS)
431 return ntStatus;
432 break;
433
434 // These are mutes in a stereo path.
435 // Because the HW has only one mute-bit for the stereo channel, we
436 // expose the mute as mono. this works in current OS and hopefully
437 // will work in future OS.
439 case NODE_LINEIN_MUTE:
440 case NODE_CD_MUTE:
441 case NODE_VIDEO_MUTE:
442 case NODE_AUX_MUTE:
444 case NODE_FRONT_MUTE:
446 case NODE_HPOUT_MUTE:
447 // just check the type.
448 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_MUTE)
449 return ntStatus;
450 break;
451
452 case NODE_INVALID:
453 default:
454 // Ooops.
455 DOUT (DBG_ERROR, ("PropertyHandler_OnOff: Invalid node requested."));
456 return ntStatus;
457 }
458
459 // Now, do some action!
460
461 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
462 {
463 WORD wRegister;
464
465 // Read the HW register for the node except NODE_VIRT_MASTERMONO_MUTE,
466 // since this is pure virtual.
467 if (NodeDef != NODE_VIRT_MASTERMONO_MUTE)
468 {
469 // get the register and read it.
470 ntStatus = that->AdapterCommon->ReadCodecRegister (
471 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
472 if (!NT_SUCCESS (ntStatus))
473 return ntStatus;
474 // Mask out every unused bit.
475 wRegister &= that->AdapterCommon->GetNodeMask (NodeDef);
476 // Store the value.
477 *OnOff = wRegister ? TRUE : FALSE;
478 }
479 else
480 {
481 // Assume no mute for master mono.
482 *OnOff = FALSE;
483 }
484
485 // When we have cache information then return this instead of the
486 // calculated value. If we don't, store the calculated value.
487 if (that->stNodeCache[NodeDef].bLeftValid)
488 *OnOff = that->stNodeCache[NodeDef].lLeft;
489 else
490 {
491 that->stNodeCache[NodeDef].lLeft = *OnOff;
492 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
493 }
494
495 PropertyRequest->ValueSize = sizeof(BOOL);
496 DOUT (DBG_PROPERTY, ("GET: %s = 0x%x", NodeStrings[NodeDef], *OnOff));
497
498 // Set the return code here.
499 ntStatus = STATUS_SUCCESS;
500 }
501 else // this must be a set.
502 {
503 // First update the node cache.
504 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
505 that->stNodeCache[NodeDef].lLeft = (*OnOff) ? TRUE : FALSE;
506
507 //
508 // If we have a master mono, then we have to program the speaker
509 // mutes a little different.
510 // Check for master mono (surround or headphone present) and
511 // if one of the speaker mutes is requested.
512 //
513 if ((that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
514 that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT)) &&
515 ((NodeDef == NODE_VIRT_MASTERMONO_MUTE) || (NodeDef == NODE_LFE_MUTE) ||
516 (NodeDef == NODE_CENTER_MUTE) || (NodeDef == NODE_FRONT_MUTE) ||
517 (NodeDef == NODE_SURROUND_MUTE) || (NodeDef == NODE_HPOUT_MUTE)))
518 {
519 //
520 // For master mono we have to update all speakers.
521 //
522 if (NodeDef == NODE_VIRT_MASTERMONO_MUTE)
523 {
524 // Update all speaker mutes.
525 ntStatus = SetMultichannelMute (that, NODE_FRONT_MUTE);
526 if (that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
527 ntStatus = SetMultichannelMute (that, NODE_HPOUT_MUTE);
528 if (that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
529 ntStatus = SetMultichannelMute (that, NODE_SURROUND_MUTE);
530 if (that->AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
531 {
532 ntStatus = SetMultichannelMute (that, NODE_CENTER_MUTE);
533 ntStatus = SetMultichannelMute (that, NODE_LFE_MUTE);
534 }
535 }
536 else // Update the individual speaker mute.
537 {
538 ntStatus = SetMultichannelMute (that, NodeDef);
539 }
540 }
541 else
542 {
543 //
544 // For all other mutes/checkboxes just write the value to the HW.
545 //
546 ntStatus = that->AdapterCommon->WriteCodecRegister (
547 that->AdapterCommon->GetNodeReg (NodeDef),
548 (*OnOff) ? -1 : 0,
549 that->AdapterCommon->GetNodeMask (NodeDef));
550 }
551
552 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x", NodeStrings[NodeDef], *OnOff));
553
554 // ntStatus was set with the write call! whatever this is, return it.
555 }
556 }
557
558 return ntStatus;
559}
static NTSTATUS SetMultichannelMute(IN CAC97MiniportTopology *that, IN TopoNodes Mute)
Definition: prophnd.cpp:36
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
switch(r->id)
Definition: btrfs.c:3046
unsigned int BOOL
Definition: ntddk_ex.h:94
@ KSPROPERTY_AUDIO_MUTE
Definition: ksmedia.h:1066
@ KSPROPERTY_AUDIO_AGC
Definition: ksmedia.h:1074
@ KSPROPERTY_AUDIO_LOUDNESS
Definition: ksmedia.h:1076
if(dx< 0)
Definition: linetemp.h:194
#define BOOL
Definition: nt_native.h:43
BOOL * PBOOL
Definition: windef.h:161

◆ PropertyHandler_Tone()

NTSTATUS CAC97MiniportTopology::PropertyHandler_Tone ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 1168 of file prophnd.cpp.

1172{
1173 PAGED_CODE ();
1174
1175 ASSERT (PropertyRequest);
1176
1177 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_Tone]"));
1178
1180 TopoNodes NodeDef;
1182 ULONG uStep;
1183 // The major target is the object pointer to the topology miniport.
1184 CAC97MiniportTopology *that =
1185 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
1186
1187 ASSERT (that);
1188
1189 // validate node
1190 if (PropertyRequest->Node == (ULONG)-1)
1191 return ntStatus;
1192
1193 // do the appropriate action for the request.
1194
1195 // we should do a get or a set?
1196 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
1197 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
1198 {
1199 // validate parameters
1200 if ((PropertyRequest->InstanceSize < sizeof(LONG)) ||
1201 (PropertyRequest->ValueSize < sizeof(LONG)))
1202 return ntStatus;
1203
1204 // get the buffer
1205 PLONG Level = (PLONG)PropertyRequest->Value;
1206
1207 // Switch on the node id. This is just for parameter checking.
1208 // If something goes wrong, we will immideately return with
1209 // ntStatus, which is STATUS_INVALID_PARAMETER.
1210 switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
1211 {
1212 case NODE_BASS:
1213 // check type.
1214 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_BASS)
1215 return ntStatus;
1216 break;
1217
1218 case NODE_TREBLE:
1219 // check type.
1220 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_TREBLE)
1221 return ntStatus;
1222 break;
1223
1225 case NODE_VIRT_3D_DEPTH:
1226 // check 3D control
1227 if (!that->AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE)
1228 && (NodeDef == NODE_VIRT_3D_CENTER))
1229 return ntStatus;
1230 if (!that->AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE)
1231 && (NodeDef == NODE_VIRT_3D_DEPTH))
1232 return ntStatus;
1233 // check type
1234 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_VOLUMELEVEL)
1235 return ntStatus;
1236 // check channel
1237 if (*(PLONG(PropertyRequest->Instance)) == CHAN_RIGHT)
1238 return ntStatus;
1239 break;
1240
1241 case NODE_INVALID:
1242 default:
1243 // Ooops
1244 DOUT (DBG_ERROR, ("PropertyHandler_Tone: Invalid node requested."));
1245 return ntStatus;
1246 }
1247
1248 // Now, do some action!
1249
1250 // get the registered DB values
1251 ntStatus = GetDBValues (that->AdapterCommon, NodeDef, &lMinimum,
1252 &lMaximum, &uStep);
1253 if (!NT_SUCCESS (ntStatus))
1254 return ntStatus;
1255
1256 // do a get
1257 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
1258 {
1259 WORD wRegister;
1260
1261 // first get the stuff.
1262 ntStatus = that->AdapterCommon->ReadCodecRegister (
1263 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
1264 if (!NT_SUCCESS (ntStatus))
1265 return ntStatus;
1266
1267 // mask out every unused bit.
1268 wRegister &= that->AdapterCommon->GetNodeMask (NodeDef);
1269
1270 // rotate if bass tone control or 3D center control
1271 if ((NodeDef == NODE_BASS) || (NodeDef == NODE_VIRT_3D_CENTER))
1272 wRegister >>= 8;
1273
1274 // convert from reg to dB.dB value.
1275 if ((NodeDef == NODE_VIRT_3D_CENTER) ||
1276 (NodeDef == NODE_VIRT_3D_DEPTH))
1277 {
1278 // That's for the 3D controls
1279 *Level = lMinimum + uStep * wRegister;
1280 }
1281 else
1282 {
1283 if (wRegister == 0x000F)
1284 *Level = 0; // bypass
1285 else
1286 // And that's for the tone controls
1287 *Level = lMaximum - uStep * wRegister;
1288 }
1289
1290 // when we have cache information then return this instead
1291 // of the calculated value. if we don't, store the calculated
1292 // value.
1293 if (that->stNodeCache[NodeDef].bLeftValid)
1294 *Level = that->stNodeCache[NodeDef].lLeft;
1295 else
1296 {
1297 that->stNodeCache[NodeDef].lLeft = *Level;
1298 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
1299 }
1300
1301 // we return a LONG
1302 PropertyRequest->ValueSize = sizeof(LONG);
1303 DOUT (DBG_PROPERTY, ("GET: %s = 0x%x", NodeStrings[NodeDef], *Level));
1304 // ntStatus was set with the read call! whatever this is, return it.
1305 }
1306 else // that must be a set
1307 {
1308 WORD wRegister;
1309 LONG lLevel = *Level;
1310
1311 // calculate the dB.dB value.
1312 // check borders.
1313 if (lLevel > lMaximum) lLevel = lMaximum;
1314 if (lLevel < lMinimum) lLevel = lMinimum;
1315
1316 // write the value to the node cache.
1317 that->stNodeCache[NodeDef].lLeft = *Level;
1318 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
1319
1320 // convert from dB.dB value to reg.
1321 if ((NodeDef == NODE_VIRT_3D_CENTER) ||
1322 (NodeDef == NODE_VIRT_3D_DEPTH))
1323 {
1324 // For 3D controls
1325 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1326 }
1327 else
1328 {
1329 // For tone controls
1330 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1331 // We don't prg. 0dB Bass or 0dB Treble, instead we smartly prg.
1332 // a bypass which is reg. value 0x0F.
1333 if (wRegister == 7) // 0 dB
1334 wRegister = 0x000F; // bypass
1335 }
1336
1337 // rotate if bass tone control or 3D center control
1338 if ((NodeDef == NODE_BASS) || (NodeDef == NODE_VIRT_3D_CENTER))
1339 wRegister <<= 8;
1340
1341 // write the stuff.
1342 ntStatus = that->AdapterCommon->WriteCodecRegister (
1343 that->AdapterCommon->GetNodeReg (NodeDef),
1344 wRegister,
1345 that->AdapterCommon->GetNodeMask (NodeDef));
1346
1347 DOUT (DBG_PROPERTY,("SET: %s -> 0x%x", NodeStrings[NodeDef], *Level));
1348 // ntStatus was set with the write call! whatever this is, return in.
1349 }
1350 }
1351 else
1352 {
1353 if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
1354 {
1355 ntStatus = BasicSupportHandler (PropertyRequest);
1356 }
1357 }
1358
1359 return ntStatus;
1360}
@ KSPROPERTY_AUDIO_BASS
Definition: ksmedia.h:1067
@ KSPROPERTY_AUDIO_TREBLE
Definition: ksmedia.h:1069

◆ PropertyHandler_Ulong()

NTSTATUS CAC97MiniportTopology::PropertyHandler_Ulong ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 1372 of file prophnd.cpp.

1376{
1377 PAGED_CODE ();
1378
1379 ASSERT (PropertyRequest);
1380
1381 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_Ulong]"));
1382
1384 TopoNodes NodeDef;
1386 ULONG uStep;
1387 // The major target is the object pointer to the topology miniport.
1388 CAC97MiniportTopology *that =
1389 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
1390
1391 ASSERT (that);
1392
1393
1394 // validate node instance
1395 if (PropertyRequest->Node == (ULONG)-1)
1396 return ntStatus;
1397
1398 // if we should do a get or set.
1399 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
1400 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
1401 {
1402 // validate buffer size.
1403 if (PropertyRequest->ValueSize < sizeof(ULONG))
1404 return ntStatus;
1405
1406 // get the pointer to the buffer.
1407 PULONG PropValue = (PULONG)PropertyRequest->Value;
1408
1409 // Switch on the node id. This is just for parameter checking.
1410 // If something goes wrong, we will immideately return with
1411 // ntStatus, which is STATUS_INVALID_PARAMETER.
1412 switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
1413 {
1415 case NODE_WAVEIN_SELECT:
1416 // check the type
1417 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_MUX_SOURCE)
1418 return ntStatus;
1419 break;
1420
1421 case NODE_INVALID:
1422 default:
1423 // Ooops
1424 DOUT (DBG_ERROR, ("PropertyHandler_Tone: Invalid node requested."));
1425 return ntStatus;
1426 }
1427
1428 // Now do some action!
1429
1430 // should we return the value?
1431 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
1432 {
1433 WORD wRegister;
1434
1435 // first get the stuff.
1436 ntStatus = that->AdapterCommon->ReadCodecRegister (
1437 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
1438 if (!NT_SUCCESS (ntStatus))
1439 return ntStatus;
1440
1441 // mask out every unused bit.
1442 wRegister &= that->AdapterCommon->GetNodeMask (NodeDef);
1443
1444 // calculate the selected pin
1445 if (NodeDef == NODE_MONOOUT_SELECT)
1446 {
1447 // for mono out we have just one bit
1448 if (wRegister)
1449 *PropValue = 2;
1450 else
1451 *PropValue = 1;
1452 }
1453 else
1454 {
1455 // the wave in muxer is a stereo muxer, so just return the
1456 // right channel (gives values 0-7) and adjust it by adding 1.
1457 *PropValue = (wRegister & AC97REG_MASK_RIGHT) + 1;
1458 }
1459
1460 // we return a LONG
1461 PropertyRequest->ValueSize = sizeof(LONG);
1462 DOUT (DBG_PROPERTY, ("GET: %s = 0x%x", NodeStrings[NodeDef],
1463 *PropValue));
1464 // ntStatus was set with the read call! whatever this is, return it.
1465 }
1466 else // that must be a set
1467 {
1468 TopoNodes VirtNode;
1469 WORD wRegister;
1470 ULONG ulSelect = *PropValue;
1471 LONG lLevel;
1472
1473 // Check the selection first.
1474 if (NodeDef == NODE_MONOOUT_SELECT)
1475 {
1476 if ((ulSelect < 1) || (ulSelect > 2))
1477 return ntStatus; // STATUS_INVALID_PARAMETER
1478 }
1479 else
1480 {
1481 if ((ulSelect < 1) || (ulSelect > 8))
1482 return ntStatus; // STATUS_INVALID_PARAMETER
1483 }
1484
1485 // calculate the register value for programming.
1486 if (NodeDef == NODE_MONOOUT_SELECT)
1487 {
1488 // for mono out we have just one bit
1489 if (ulSelect == 2)
1490 // the mask will make sure we only prg. one bit.
1491 wRegister = 0xFFFF;
1492 else
1493 // ulSelect == 1
1494 wRegister = 0;
1495 }
1496 else
1497 {
1498 // *257 is the same as: (ulSelect << 8) + ulSelect
1499 wRegister = (WORD)(ulSelect - 1) * 257;
1500 }
1501
1502 // write the stuff.
1503 ntStatus = that->AdapterCommon->WriteCodecRegister (
1504 that->AdapterCommon->GetNodeReg (NodeDef),
1505 wRegister,
1506 that->AdapterCommon->GetNodeMask (NodeDef));
1507
1508 // Store the virt. node for later use.
1509 // Tricky: Master input virtual controls must be defined consecutively.
1510 if (NodeDef == NODE_MONOOUT_SELECT)
1511 VirtNode = (TopoNodes)(NODE_VIRT_MONOOUT_VOLUME1 + (ulSelect - 1));
1512 else
1513 VirtNode = (TopoNodes)(NODE_VIRT_MASTER_INPUT_VOLUME1 + (ulSelect - 1));
1514
1515 // Virtual controls make our life more complicated. When the user
1516 // changes the input source say from CD to LiniIn, then the system just
1517 // sends a message to the input muxer that the selection changed.
1518 // Cause we have only one HW register for the input muxer, all volumes
1519 // displayed for the user are "virtualized", means they are not there,
1520 // and when the selection changes, we have to prg. the volume of the
1521 // selected input to the HW register. That's what we do now.
1522
1523 // get the registered DB values
1524 ntStatus = GetDBValues (that->AdapterCommon, VirtNode,
1525 &lMinimum, &lMaximum, &uStep);
1526 if (!NT_SUCCESS (ntStatus))
1527 return ntStatus;
1528
1529 // We can be lazy here and don't check for mono controls. Reason
1530 // is that the level handler writes the volume value for mono
1531 // controls into both the left and right node cache ;))
1532
1533 if (that->stNodeCache[VirtNode].bLeftValid &&
1534 that->stNodeCache[VirtNode].bRightValid)
1535 {
1536 // prg. left channel
1537 lLevel = that->stNodeCache[VirtNode].lLeft;
1538
1539 // calculate the dB.dB value.
1540 if (NodeDef == NODE_MONOOUT_SELECT)
1541 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1542 else
1543 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1544
1545 // write left channel.
1546 ntStatus = that->AdapterCommon->WriteCodecRegister (
1547 that->AdapterCommon->GetNodeReg (VirtNode),
1548 wRegister << 8,
1549 that->AdapterCommon->GetNodeMask (VirtNode) & AC97REG_MASK_LEFT);
1550
1551 // prg. right channel
1552 lLevel = that->stNodeCache[VirtNode].lRight;
1553
1554 // calculate the dB.dB value.
1555 if (NodeDef == NODE_MONOOUT_SELECT)
1556 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1557 else
1558 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1559
1560 // write right channel.
1561 ntStatus = that->AdapterCommon->WriteCodecRegister (
1562 that->AdapterCommon->GetNodeReg (VirtNode),
1563 wRegister,
1564 that->AdapterCommon->GetNodeMask (VirtNode) & AC97REG_MASK_RIGHT);
1565
1566 // For the virtual controls, which are in front of a muxer, there
1567 // is no mute control displayed. But we have a HW mute control, so
1568 // what we do is enabling this mute when the user moves the slider
1569 // down to the bottom and disabling it on every other position.
1570 // We do this only for the "mono muxer", the recording mutes will
1571 // never be muted.
1572 if (NodeDef == NODE_WAVEIN_SELECT)
1573 {
1574 // disable the mute; this only works because the mute and volume
1575 // share the same register.
1576 ntStatus = that->AdapterCommon->WriteCodecRegister (
1577 that->AdapterCommon->GetNodeReg (VirtNode),
1579
1580 that->UpdateRecordMute ();
1581 }
1582
1583 if (NodeDef == NODE_MONOOUT_SELECT)
1584 {
1585 // these are only mono controls so checking one entry is enough.
1586 if ( that->stNodeCache[VirtNode].bLeftValid &&
1587 (that->stNodeCache[VirtNode].lLeft <= lMinimum))
1588 {
1589 // set the mute; this only works because the mute and volume
1590 // share the same register.
1591 ntStatus = that->AdapterCommon->WriteCodecRegister (
1592 that->AdapterCommon->GetNodeReg (VirtNode),
1594 }
1595 else
1596 {
1597 // clear the mute; this only works because the mute and volume
1598 // share the same register.
1599 ntStatus = that->AdapterCommon->WriteCodecRegister (
1600 that->AdapterCommon->GetNodeReg (VirtNode),
1602 }
1603 }
1604 }
1605
1606 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x", NodeStrings[NodeDef],
1607 *PropValue));
1608 // ntStatus was set with the write call! whatever this is, return it.
1609 }
1610 }
1611
1612 return ntStatus;
1613}
@ KSPROPERTY_AUDIO_MUX_SOURCE
Definition: ksmedia.h:1065

◆ SetMultichannelMute()

NTSTATUS CAC97MiniportTopology::SetMultichannelMute ( IN CAC97MiniportTopology that,
IN TopoNodes  Mute 
)
static

Definition at line 35 of file prophnd.cpp.

40{
41 PAGED_CODE();
42
43 NTSTATUS ntStatus = STATUS_SUCCESS;
44 BOOL bMute;
45
46 // The first calls to SetMultichannelMute could be without valid
47 // cache information because WDMAUD might currently query the nodes
48 // (this is at system startup). When WDMAUD queried all nodes then
49 // all cache information will be valid.
50 if (that->stNodeCache[NODE_VIRT_MASTERMONO_MUTE].bLeftValid &&
51 that->stNodeCache[Mute].bLeftValid)
52 {
53 // We get the master mono mute and the mute that is to change.
54 // Then we "or" them and write the value to the register.
55 bMute = that->stNodeCache[NODE_VIRT_MASTERMONO_MUTE].lLeft ||
56 that->stNodeCache[Mute].lLeft;
57
58 ntStatus = that->AdapterCommon->WriteCodecRegister (
59 that->AdapterCommon->GetNodeReg (Mute),
60 bMute ? -1 : 0,
61 that->AdapterCommon->GetNodeMask (Mute));
62
63 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x", NodeStrings[Mute], (int)bMute));
64 }
65
66 return ntStatus;
67}

Referenced by PropertyHandler_OnOff().

◆ SetMultichannelVolume()

NTSTATUS CAC97MiniportTopology::SetMultichannelVolume ( IN CAC97MiniportTopology that,
IN TopoNodes  Volume 
)
static

Definition at line 76 of file prophnd.cpp.

81{
82 PAGED_CODE();
83
84 NTSTATUS ntStatus = STATUS_SUCCESS;
86 ULONG uStep;
87 LONG lLevel;
88 WORD wRegister;
89
90 // The first calls to SetMultichannelMute could be without valid
91 // cache information because WDMAUD might currently query the nodes
92 // (this is at system startup). When WDMAUD queried all nodes then
93 // all cache information will be valid.
94 if (that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].bLeftValid &&
95 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].bRightValid &&
96 that->stNodeCache[Volume].bLeftValid &&
97 that->stNodeCache[Volume].bRightValid)
98 {
99 // We get the master mono volume and the volume that is to change.
100 // Then we substract master mono from it and write the value to the
101 // register.
102 lLevel = that->stNodeCache[Volume].lLeft +
103 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].lLeft;
104
105 // Translate the dB value into a register value.
106
107 // Get the registered DB values
108 ntStatus = GetDBValues (that->AdapterCommon, Volume,
109 &lMinimum, &lMaximum, &uStep);
110 if (!NT_SUCCESS(ntStatus))
111 return ntStatus;
112
113 // Check borders.
114 if (lLevel < lMinimum) lLevel = lMinimum;
115 if (lLevel > lMaximum) lLevel = lMaximum;
116
117 // Calculate the register value
118 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep) << 8;
119
120 // Get the right value too.
121 lLevel = that->stNodeCache[Volume].lRight +
122 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].lRight;
123
124 // Check borders.
125 if (lLevel < lMinimum) lLevel = lMinimum;
126 if (lLevel > lMaximum) lLevel = lMaximum;
127
128 // Add it to the register value.
129 wRegister += (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
130
131 // Write it.
132 ntStatus = that->AdapterCommon->WriteCodecRegister (
133 that->AdapterCommon->GetNodeReg (Volume),
134 wRegister,
135 that->AdapterCommon->GetNodeMask (Volume));
136
137 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x/0x%x", NodeStrings[Volume],
138 that->stNodeCache[Volume].lLeft +
139 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].lLeft,
140 lLevel));
141 }
142
143 return ntStatus;
144}
UNICODE_STRING Volume
Definition: fltkernel.h:1172

Referenced by PropertyHandler_Level().

◆ SetNodeTranslation()

void CAC97MiniportTopology::SetNodeTranslation ( IN int  NodeNr,
IN TopoNodes  NodeDef 
)
inlineprivate

Definition at line 203 of file mintopo.h.

204 {
205 stNodeTrans[NodeNr].NodeDef = NodeDef;
206 stNodeTrans[NodeDef].NodeNr = NodeNr;
207 };
tNodeTranslationTable stNodeTrans[NODE_TOP_ELEMENT]
Definition: mintopo.h:105
TopoNodes NodeDef
Definition: mintopo.h:37

◆ SetPinTranslation()

void CAC97MiniportTopology::SetPinTranslation ( IN int  PinNr,
IN TopoPins  PinDef 
)
inlineprivate

Definition at line 210 of file mintopo.h.

211 {
212 stPinTrans[PinNr].PinDef = PinDef;
213 stPinTrans[PinDef].PinNr = PinNr;
214 };
tPinTranslationTable stPinTrans[PIN_TOP_ELEMENT]
Definition: mintopo.h:104
TopoPins PinDef
Definition: mintopo.h:28

◆ STDMETHODIMP_() [1/2]

CAC97MiniportTopology::STDMETHODIMP_ ( NTSTATUS  )

◆ STDMETHODIMP_() [2/2]

CAC97MiniportTopology::STDMETHODIMP_ ( void  )
inline

Definition at line 251 of file mintopo.h.

252 {
254 {
257 }
258 };
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52

◆ TransNodeDefToNodeNr()

int CAC97MiniportTopology::TransNodeDefToNodeNr ( IN TopoNodes  Node)
inlineprivate

Definition at line 152 of file mintopo.h.

153 {
154#if (DBG)
155 int n;
156
157 // check for invalid translation. could be caused by a connection
158 // to a not registered node or wrong use of nodes.
160 if (n == -1)
161 DOUT (DBG_ERROR, ("Invalid TopoNode %u.", Node));
162 return n;
163#else
164 return stNodeTrans[Node].NodeNr;
165#endif
166 };
union node Node
Definition: types.h:1255
GLdouble n
Definition: glext.h:7729

◆ TransNodeNrToNodeDef()

TopoNodes CAC97MiniportTopology::TransNodeNrToNodeDef ( IN int  Node)
inlineprivate

Definition at line 135 of file mintopo.h.

136 {
137#if (DBG)
138 TopoNodes n;
139
141 // check for invalid translation. could be caused by a connection
142 // to a not registered node or wrong use of nodes.
143 if (n == NODE_INVALID)
144 DOUT (DBG_ERROR, ("Invalid node nr %u.", Node));
145 return n;
146#else
147 return stNodeTrans[Node].NodeDef;
148#endif
149 };

Referenced by BasicSupportHandler(), PropertyHandler_CpuResources(), PropertyHandler_Level(), PropertyHandler_OnOff(), PropertyHandler_Tone(), and PropertyHandler_Ulong().

◆ TransPinDefToPinNr()

int CAC97MiniportTopology::TransPinDefToPinNr ( IN TopoPins  Pin)
inlineprivate

Definition at line 186 of file mintopo.h.

187 {
188#if (DBG)
189 int p;
190
192 // check for invalid translation. could be caused by a connection
193 // to a not registered pin or wrong use of pins.
194 if (p == -1)
195 DOUT (DBG_ERROR, ("Invalid TopoPin %u.", Pin));
196 return p;
197#else
198 return stPinTrans[Pin].PinNr;
199#endif
200 };
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:427
GLfloat GLfloat p
Definition: glext.h:8902

◆ TransPinNrToPinDef()

TopoPins CAC97MiniportTopology::TransPinNrToPinDef ( IN int  Pin)
inlineprivate

Definition at line 169 of file mintopo.h.

170 {
171#if (DBG)
172 TopoPins p;
173
175 // check for invalid translation. could be caused by a connection
176 // to a not registered pin or wrong use of pins.
177 if (p == PIN_INVALID)
178 DOUT (DBG_ERROR, ("Invalid pin nr %u.", Pin));
179 return p;
180#else
181 return stPinTrans[Pin].PinDef;
182#endif
183 };
TopoPins
Definition: shared.h:112
@ PIN_INVALID
Definition: shared.h:137

◆ UpdateRecordMute()

void CAC97MiniportTopology::UpdateRecordMute ( void  )
private

Definition at line 2053 of file mintopo.cpp.

2054{
2055 PAGED_CODE ();
2056
2057 WORD wRegister;
2058 //TopoNodes Node;
2059
2060 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::UpdateRecordMute]"));
2061
2062 // Get the record muxer setting.
2063 if (!NT_SUCCESS (AdapterCommon->ReadCodecRegister (
2064 AdapterCommon->GetNodeReg (NODE_WAVEIN_SELECT), &wRegister)))
2065 return;
2066
2067 // Mask out every unused bit.
2068 wRegister &= (AdapterCommon->GetNodeMask (NODE_WAVEIN_SELECT) & AC97REG_MASK_RIGHT);
2069
2070#if 0
2071 // Calculate how we would program the mute.
2072 switch (wRegister)
2073 {
2074 // This is stereo mix.
2075 case 5:
2077 break;
2078
2079 // This is mono mix.
2080 case 6:
2082 break;
2083
2084 // Something else selected than stereo mix or mono mix.
2085 default:
2086 return;
2087 }
2088#endif
2089
2090 // Program the mute.
2091 AdapterCommon->WriteCodecRegister (AC97REG_RECORD_GAIN,
2093}
@ AC97REG_RECORD_GAIN
Definition: ac97reg.h:32

Referenced by PropertyHandler_Level(), PropertyHandler_Ulong(), and STDMETHODIMP_().

Member Data Documentation

◆ AdapterCommon

◆ ConnectionDescriptors

PPCCONNECTION_DESCRIPTOR CAC97MiniportTopology::ConnectionDescriptors
private

Definition at line 102 of file mintopo.h.

Referenced by BuildConnectionDescriptors(), and ~CAC97MiniportTopology().

◆ FilterDescriptor

PPCFILTER_DESCRIPTOR CAC97MiniportTopology::FilterDescriptor
private

◆ IMP_IMiniportTopology

CAC97MiniportTopology::IMP_IMiniportTopology

Definition at line 237 of file mintopo.h.

◆ m_bCopyProtectFlag

BOOL CAC97MiniportTopology::m_bCopyProtectFlag
private

Definition at line 107 of file mintopo.h.

Referenced by STDMETHODIMP_(), and UpdateRecordMute().

◆ MicInDest

OUT PULONG OUT PULONG CAC97MiniportTopology::MicInDest

Definition at line 247 of file mintopo.h.

◆ NodeDescriptors

PPCNODE_DESCRIPTOR CAC97MiniportTopology::NodeDescriptors
private

Definition at line 101 of file mintopo.h.

Referenced by BuildNodeDescriptors(), and ~CAC97MiniportTopology().

◆ PinDescriptors

PPCPIN_DESCRIPTOR CAC97MiniportTopology::PinDescriptors
private

Definition at line 100 of file mintopo.h.

Referenced by BuildPinDescriptors(), and ~CAC97MiniportTopology().

◆ stNodeCache

tNodeCache CAC97MiniportTopology::stNodeCache[NODE_TOP_ELEMENT]
private

◆ stNodeTrans

tNodeTranslationTable CAC97MiniportTopology::stNodeTrans[NODE_TOP_ELEMENT]
private

Definition at line 105 of file mintopo.h.

Referenced by SetNodeTranslation(), TransNodeDefToNodeNr(), and TransNodeNrToNodeDef().

◆ stPinTrans

tPinTranslationTable CAC97MiniportTopology::stPinTrans[PIN_TOP_ELEMENT]
private

Definition at line 104 of file mintopo.h.

Referenced by SetPinTranslation(), TransPinDefToPinNr(), and TransPinNrToPinDef().

◆ WaveInDest

OUT PULONG CAC97MiniportTopology::WaveInDest

Definition at line 246 of file mintopo.h.


The documentation for this class was generated from the following files: