summaryrefslogtreecommitdiff
path: root/audio/sysvad/EndpointsCommon/usbhsmictopo.cpp
diff options
context:
space:
mode:
authorGirish Pattabiraman <[email protected]>2018-11-12 18:08:19 -0800
committerAdonais Romero González <[email protected]>2018-11-12 18:08:19 -0800
commit995e20f6dbca7ad10a039fa62a2de69eed092ffc (patch)
tree67075f06fd8aaedad732d6c73b682c6e0fda9dba /audio/sysvad/EndpointsCommon/usbhsmictopo.cpp
parentc9110a3bc1634a5be8e7922119ad383311104095 (diff)
RS5 Updates (#311)
* Format Changes ============== * Add KSEVENT_PINCAPS_FORMATCHANGE to Bluetooth HFP Endpoints * Remove 8 bit formats from Bluetooth HFP Endpoints Name Template ============== * Bluetooth Endpoints are now based on templates in INF and then customized with endpoints specific data Sideband Common Interface for future Sideband buses =================================================== * Add ISidebandDevice * Add current directory to TabletAudioSample include path. Remove unused compiler flags. * RS4 bug fixes * Replace FastMutex with Spinlock for DeviceFormatsAndModes to work well at DISPATCH_LEVEL * Resync with Microsoft-master branch * Replace FastMutex with Spinlock for DeviceFormatsAndModes to work well at DISPATCH_LEVEL * RS5 updates: - USB Sideband implementation - Power management options: _USE_IPortClsRuntimePower, _USE_SingleComponentMultiFxStates
Diffstat (limited to 'audio/sysvad/EndpointsCommon/usbhsmictopo.cpp')
-rw-r--r--audio/sysvad/EndpointsCommon/usbhsmictopo.cpp349
1 files changed, 349 insertions, 0 deletions
diff --git a/audio/sysvad/EndpointsCommon/usbhsmictopo.cpp b/audio/sysvad/EndpointsCommon/usbhsmictopo.cpp
new file mode 100644
index 00000000..6814b5ce
--- /dev/null
+++ b/audio/sysvad/EndpointsCommon/usbhsmictopo.cpp
@@ -0,0 +1,349 @@
+/*++
+
+Copyright (c) Microsoft Corporation All Rights Reserved
+
+Module Name:
+
+ usbhsmictopo.cpp
+
+Abstract:
+
+ Implementation of topology miniport for the mic (external: headphone).
+
+--*/
+#ifdef SYSVAD_USB_SIDEBAND
+
+#pragma warning (disable : 4127)
+
+#include <sysvad.h>
+#include "simple.h"
+#include "mintopo.h"
+#include "usbhstopo.h"
+#include "usbhsmictopo.h"
+#include "usbhsmictoptable.h"
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+PropertyHandler_UsbHsMicTopoFilter
+(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest
+)
+/*++
+
+Routine Description:
+
+ Redirects property request to miniport object
+
+Arguments:
+
+ PropertyRequest -
+
+Return Value:
+
+ NT status code.
+
+--*/
+{
+ PAGED_CODE();
+
+ ASSERT(PropertyRequest);
+
+ DPF_ENTER(("[PropertyHandler_UsbHsMicTopoFilter]"));
+
+ // PropertryRequest structure is filled by portcls.
+ // MajorTarget is a pointer to miniport object for miniports.
+ //
+ NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+
+ //
+ // This line shows how to get a pointer to the miniport topology object.
+ //
+ PCMiniportTopology pMiniport = (PCMiniportTopology)PropertyRequest->MajorTarget;
+ UNREFERENCED_VAR(pMiniport);
+
+ if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_Jack))
+ {
+ switch(PropertyRequest->PropertyItem->Id)
+ {
+ case KSPROPERTY_JACK_DESCRIPTION:
+ ntStatus = PropertyHandler_UsbHsJackDescription(
+ PropertyRequest,
+ ARRAYSIZE(UsbHsMicJackDescriptions),
+ UsbHsMicJackDescriptions);
+ break;
+
+ case KSPROPERTY_JACK_DESCRIPTION2:
+ ntStatus = PropertyHandler_UsbHsJackDescription2(
+ PropertyRequest,
+ ARRAYSIZE(UsbHsMicJackDescriptions),
+ UsbHsMicJackDescriptions);
+ break;
+
+ case KSPROPERTY_JACK_CONTAINERID:
+ ntStatus = PropertyHandler_UsbHsJackContainerId(
+ PropertyRequest,
+ ARRAYSIZE(UsbHsMicJackDescriptions),
+ UsbHsMicJackDescriptions);
+ break;
+ }
+ }
+
+ return ntStatus;
+} // PropertyHandler_UsbHsMicTopoFilter
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+PropertyHandler_UsbHsMicVolumeLevel
+(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest
+)
+/*++
+
+Routine Description:
+
+ Handles ( KSPROPSETID_Audio, KSPROPERTY_AUDIO_VOLUMELEVEL )
+
+Arguments:
+
+ PropertyRequest -
+
+Return Value:
+
+ NT status code.
+
+--*/
+{
+ PAGED_CODE();
+
+ ASSERT(PropertyRequest);
+
+ DPF_ENTER(("[PropertyHandler_UsbHsMicVolumeLevel]"));
+
+ NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+ PCMiniportTopology miniport = (PCMiniportTopology)PropertyRequest->MajorTarget;
+ PSIDEBANDDEVICECOMMON usbHsDevice = NULL;
+ ULONG channel = (ULONG)-1;
+
+ usbHsDevice = miniport->GetSidebandDevice(); // weak ref.
+ ASSERT(usbHsDevice != NULL);
+
+ if (usbHsDevice->IsVolumeSupported(miniport->m_DeviceType) == FALSE)
+ {
+ ntStatus = miniport->PropertyHandlerGeneric(PropertyRequest);
+ }
+ else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
+ {
+ ntStatus = PropertyHandler_UsbHsVolumeLevel_BasicSupport(PropertyRequest);
+ }
+ else if (PropertyRequest->InstanceSize >= sizeof(ULONG))
+ {
+ // Instance is the channel #.
+ channel = *(PULONG(PropertyRequest->Instance));
+
+ ULONG cbNeeded = sizeof(LONG);
+
+ if (PropertyRequest->ValueSize == 0)
+ {
+ PropertyRequest->ValueSize = cbNeeded;
+ ntStatus = STATUS_BUFFER_OVERFLOW;
+ }
+ else if (PropertyRequest->ValueSize < cbNeeded)
+ {
+ ntStatus = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ LONG* volume = (LONG*)PropertyRequest->Value;
+
+ if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
+ {
+ ntStatus = usbHsDevice->GetVolume(eUsbHsMicDevice, channel, volume);
+ }
+ else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
+ {
+ ntStatus = usbHsDevice->SetVolume(eUsbHsMicDevice, channel, *volume);
+ }
+ }
+ }
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+PropertyHandler_UsbHsMicMute
+(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest
+)
+/*++
+
+Routine Description:
+
+ Handles ( KSPROPSETID_Audio, KSPROPERTY_AUDIO_MUTE )
+
+Arguments:
+
+ PropertyRequest -
+
+Return Value:
+
+ NT status code.
+
+--*/
+{
+ PAGED_CODE();
+
+ ASSERT(PropertyRequest);
+
+ DPF_ENTER(("[PropertyHandler_UsbHsMicMute]"));
+
+ NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+ PCMiniportTopology miniport = (PCMiniportTopology)PropertyRequest->MajorTarget;
+ PSIDEBANDDEVICECOMMON usbHsDevice = NULL;
+ ULONG channel = (ULONG)-1;
+
+ usbHsDevice = miniport->GetSidebandDevice(); // weak ref.
+ ASSERT(usbHsDevice != NULL);
+
+ if (usbHsDevice->IsMuteSupported(miniport->m_DeviceType) == FALSE)
+ {
+ ntStatus = miniport->PropertyHandlerGeneric(PropertyRequest);
+ }
+ else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
+ {
+ ntStatus = PropertyHandler_UsbHsMute_BasicSupport(PropertyRequest);
+ }
+ else if (PropertyRequest->InstanceSize >= sizeof(ULONG))
+ {
+ // Instance is the channel #.
+ channel = *(PULONG(PropertyRequest->Instance));
+
+ ULONG cbNeeded = sizeof(LONG);
+
+ if (PropertyRequest->ValueSize == 0)
+ {
+ PropertyRequest->ValueSize = cbNeeded;
+ ntStatus = STATUS_BUFFER_OVERFLOW;
+ }
+ else if (PropertyRequest->ValueSize < cbNeeded)
+ {
+ ntStatus = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ LONG* mute = (LONG*)PropertyRequest->Value;
+
+ if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
+ {
+ *mute = usbHsDevice->GetMute(eUsbHsMicDevice, channel);
+
+ ntStatus = STATUS_SUCCESS;
+
+ }
+ else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
+ {
+ ntStatus = usbHsDevice->SetMute(eUsbHsMicDevice, channel, *mute);
+ }
+ }
+ }
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+PropertyHandler_UsbHsMicTopoNode
+(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest
+)
+/*++
+
+Routine Description:
+
+ Redirects property request to miniport object
+
+Arguments:
+
+ PropertyRequest -
+
+Return Value:
+
+ NT status code.
+
+--*/
+{
+ PAGED_CODE();
+
+ ASSERT(PropertyRequest);
+
+ DPF_ENTER(("[PropertyHandler_UsbHsMicTopoNode]"));
+
+ // PropertryRequest structure is filled by portcls.
+ // MajorTarget is a pointer to miniport object for miniports.
+ //
+ NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+
+ //
+ // This line shows how to get a pointer to the miniport topology object.
+ //
+ PCMiniportTopology pMiniport = (PCMiniportTopology)PropertyRequest->MajorTarget;
+ UNREFERENCED_VAR(pMiniport);
+
+ if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_Audio))
+ {
+ if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_VOLUMELEVEL)
+ {
+ ntStatus = PropertyHandler_UsbHsMicVolumeLevel(PropertyRequest);
+ }
+ else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MUTE)
+ {
+ ntStatus = PropertyHandler_UsbHsMicMute(PropertyRequest);
+ }
+ }
+
+ return ntStatus;
+} // PropertyHandler_UsbHsMicTopoFilter
+
+//=============================================================================
+#pragma code_seg()
+NTSTATUS
+PropertyHandler_UsbHsMicTopoNodeEvent
+(
+ _In_ PPCEVENT_REQUEST EventRequest
+)
+{
+ ASSERT(EventRequest);
+
+ DPF_ENTER(("[PropertyHandler_UsbHsMicTopoNodeEvent]"));
+
+ // Validate the node.
+ if (EventRequest->Node != KSNODE_TOPO_VOLUME &&
+ EventRequest->Node != KSNODE_TOPO_MUTE)
+ return STATUS_INVALID_PARAMETER;
+
+ return PropertyHandler_UsbHsTopoNodeEvent(EventRequest);
+}
+
+//=============================================================================
+#pragma code_seg()
+NTSTATUS
+PropertyHandler_UsbHsMicTopoFilterEvent
+(
+ _In_ PPCEVENT_REQUEST EventRequest
+)
+{
+ ASSERT(EventRequest);
+
+ DPF_ENTER(("[PropertyHandler_UsbHsMicTopoFilterEvent]"));
+
+ return PropertyHandler_UsbHsTopoNodeEvent(EventRequest);
+}
+
+#pragma code_seg()
+#endif // SYSVAD_USB_SIDEBAND
+
+