summaryrefslogtreecommitdiff
path: root/audio/sysvad/PhoneAudioSample/FMWave.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'audio/sysvad/PhoneAudioSample/FMWave.cpp')
-rw-r--r--audio/sysvad/PhoneAudioSample/FMWave.cpp389
1 files changed, 389 insertions, 0 deletions
diff --git a/audio/sysvad/PhoneAudioSample/FMWave.cpp b/audio/sysvad/PhoneAudioSample/FMWave.cpp
new file mode 100644
index 00000000..4d571f57
--- /dev/null
+++ b/audio/sysvad/PhoneAudioSample/FMWave.cpp
@@ -0,0 +1,389 @@
+/*++
+
+Copyright (c) Microsoft Corporation All Rights Reserved
+
+Module Name:
+
+ fmwave.cpp
+
+Abstract:
+
+ Implementation of wavert miniport for fm
+
+--*/
+
+#pragma warning (disable : 4127)
+
+#include <sysvad.h>
+#include "simple.h"
+#include "FmWave.h"
+#include "FmTopo.h"
+#include "FmToptable.h"
+
+//=============================================================================
+// CFmMiniportWaveRT
+//=============================================================================
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+CreateFmMiniportWaveRT
+(
+ _Out_ PUNKNOWN * Unknown,
+ _In_ REFCLSID,
+ _In_opt_ PUNKNOWN UnknownOuter,
+ _When_((PoolType & NonPagedPoolMustSucceed) != 0,
+ __drv_reportError("Must succeed pool allocations are forbidden. "
+ "Allocation failures cause a system crash"))
+ _In_ POOL_TYPE PoolType,
+ _In_ PUNKNOWN UnknownAdapter,
+ _In_opt_ PVOID DeviceContext,
+ _In_ PENDPOINT_MINIPAIR MiniportPair
+)
+/*++
+
+Routine Description:
+
+ Create the wavert miniport.
+
+Arguments:
+
+ Unknown -
+
+ RefClsId -
+
+ UnknownOuter -
+
+ PoolType -
+
+ UnkownAdapter -
+
+ DeviceContext -
+
+ MiniportPair -
+
+Return Value:
+
+ NT status code.
+
+--*/
+{
+ UNREFERENCED_PARAMETER(UnknownOuter);
+
+ PAGED_CODE();
+
+ ASSERT(Unknown);
+ ASSERT(MiniportPair);
+
+ CMiniportWaveRT *obj = new (PoolType, MINWAVERT_POOLTAG) CFmMiniportWaveRT
+ (
+ UnknownAdapter,
+ MiniportPair,
+ DeviceContext
+ );
+ if (NULL == obj)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ obj->AddRef();
+ *Unknown = reinterpret_cast<IUnknown*>(obj);
+
+ return STATUS_SUCCESS;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+CFmMiniportWaveRT::~CFmMiniportWaveRT
+(
+ void
+)
+/*++
+
+Routine Description:
+
+ Destructor for wavert miniport
+
+Arguments:
+
+Return Value:
+
+ NT status code.
+
+--*/
+{
+ PAGED_CODE();
+
+ DPF_ENTER(("[CFmMiniportWaveRT::~CFmMiniportWaveRT]"));
+
+} // ~CFmMiniportWaveRT
+
+
+//=============================================================================
+#pragma code_seg("PAGE")
+STDMETHODIMP
+CFmMiniportWaveRT::NonDelegatingQueryInterface
+(
+ _In_ REFIID Interface,
+ _COM_Outptr_ PVOID * Object
+)
+/*++
+
+Routine Description:
+
+ QueryInterface for CFmMiniportWaveRT
+
+Arguments:
+
+ Interface - GUID of the interface
+
+ Object - interface object to be returned.
+
+Return Value:
+
+ NT status code.
+
+--*/
+{
+ PAGED_CODE();
+
+ ASSERT(Object);
+
+ if (IsEqualGUIDAligned(Interface, IID_IAdapterPowerManagement))
+ {
+ *Object = PVOID(PADAPTERPOWERMANAGEMENT(this));
+ }
+ else
+ {
+ *Object = NULL;
+ }
+
+ if (*Object)
+ {
+ // We reference the interface for the caller.
+
+ PUNKNOWN(*Object)->AddRef();
+ return STATUS_SUCCESS;
+ }
+
+ return CMiniportWaveRT::NonDelegatingQueryInterface(Interface, Object);
+}
+
+#pragma code_seg("PAGE")
+NTSTATUS
+PropertyHandler_FmRxWaveFilter
+(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest
+)
+/*++
+
+Routine Description:
+
+ Redirects general property request to miniport object
+
+Arguments:
+
+ PropertyRequest -
+
+Return Value:
+
+ NT status code.
+
+--*/
+{
+ PAGED_CODE();
+
+ NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+ CFmMiniportWaveRT* pWaveHelper = reinterpret_cast<CFmMiniportWaveRT*>(PropertyRequest->MajorTarget);
+
+ if (pWaveHelper == NULL)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ pWaveHelper->AddRef();
+
+ if (pWaveHelper->m_DeviceType == eFmRxDevice &&
+ IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_FMRXControl))
+ {
+ switch (PropertyRequest->PropertyItem->Id)
+ {
+ case KSPROPERTY_FMRX_STATE:
+ ntStatus = pWaveHelper->PropertyHandler_FmRxState(PropertyRequest);
+ break;
+
+ default:
+ DPF(D_TERSE, ("[PropertyHandler_FmRxWaveFilter: Invalid Device Request"));
+ }
+ }
+ else
+ {
+ ntStatus = PropertyHandler_WaveFilter(PropertyRequest);
+ }
+
+ pWaveHelper->Release();
+
+ return ntStatus;
+} // PropertyHandler_FmRxWaveFilter
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
+CFmMiniportWaveRT::PropertyHandler_FmRxState
+(
+_In_ PPCPROPERTY_REQUEST PropertyRequest
+)
+{
+ NTSTATUS ntStatus = STATUS_INVALID_PARAMETER;
+
+ PAGED_CODE();
+
+ DPF_ENTER(("[CFmMiniportWaveRT::PropertyHandler_FmRxState]"));
+
+ if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
+ {
+ ULONG flags = PropertyRequest->PropertyItem->Flags;
+ ntStatus = PropertyHandler_BasicSupport(PropertyRequest, flags, VT_ILLEGAL);
+ }
+ else
+ {
+ ntStatus =
+ ValidatePropertyParams
+ (
+ PropertyRequest,
+ sizeof(BOOL),
+ 0
+ );
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
+ {
+ BOOL* fmrxState = (BOOL*)PropertyRequest->Value;
+ *fmrxState = m_bFmRxState;
+ ntStatus = STATUS_SUCCESS;
+ }
+ else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
+ {
+ BOOL fmrxNewState = *(BOOL*)PropertyRequest->Value;
+ if (fmrxNewState == m_bFmRxState)
+ {
+ ntStatus = STATUS_SUCCESS;
+ }
+ else
+ {
+ // Turn on FM hardware
+ m_bFmRxState = fmrxNewState;
+
+ // NOTE: Set the Jack state to Active ONLY if the driver supports
+ // recording FM data. If the driver doesn't support recording FM
+ // data, the jack state should never be changed to Active
+ ntStatus = UpdateTopologyJackState(m_bFmRxState);
+
+ // When we're using FM, we need idle power management disabled.
+ // passing true here enables power management, false disables.
+ // when FM is enabled (true), we want to pass false do disable idle
+ // power management
+ m_pAdapterCommon->SetIdlePowerManagement(m_pMiniportPair, m_bFmRxState?FALSE:TRUE);
+ }
+ }
+ else
+ {
+ ntStatus = STATUS_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ return ntStatus;
+} // PropertyHandler_FmRxState
+
+
+
+#pragma code_seg("PAGE")
+NTSTATUS
+CFmMiniportWaveRT::UpdateTopologyJackState
+(
+ _In_ BOOL NewState
+)
+{
+ PAGED_CODE ();
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ IUnknown *pUnknown = NULL;
+ IFmTopology *pFmTopology = NULL;
+
+ // GetFilters returns the topology port, then topology miniport, then wave port, then wave miniport.
+ // we only need the topology miniport.
+ ntStatus = m_pAdapterCommon->GetFilters(m_pMiniportPair, NULL, &pUnknown, NULL, NULL);
+ if (NT_SUCCESS(ntStatus))
+ {
+ ntStatus = pUnknown->QueryInterface(IID_IFmTopology, (PVOID *)&pFmTopology);
+ if (NT_SUCCESS(ntStatus))
+ {
+ ntStatus = pFmTopology->UpdateTopologyJackState(NewState);
+ }
+ }
+
+ SAFE_RELEASE(pFmTopology);
+ SAFE_RELEASE(pUnknown);
+
+ return STATUS_SUCCESS;
+}
+#pragma code_seg()
+
+
+//=============================================================================
+#pragma code_seg()
+STDMETHODIMP_(void)
+CFmMiniportWaveRT::PowerChangeState
+(
+ _In_ POWER_STATE NewState
+)
+{
+ DPF_ENTER(("[CFmMiniportWaveRT::PowerChangeState]"));
+ UNREFERENCED_PARAMETER(NewState);
+
+ /*
+ Turn on and off fm specific hardware here, if applicable.
+ */
+
+} // PowerStateChange
+
+//=============================================================================
+#pragma code_seg()
+STDMETHODIMP_(NTSTATUS)
+CFmMiniportWaveRT::QueryDeviceCapabilities
+(
+ _Inout_updates_bytes_(sizeof(DEVICE_CAPABILITIES)) PDEVICE_CAPABILITIES PowerDeviceCaps
+)
+{
+ UNREFERENCED_PARAMETER(PowerDeviceCaps);
+
+ /*
+ Unused at the miniport layer. Any device capabilities should be reported in CAdapterCommon
+ */
+
+ return (STATUS_SUCCESS);
+} // QueryDeviceCapabilities
+
+//=============================================================================
+#pragma code_seg()
+STDMETHODIMP_(NTSTATUS)
+CFmMiniportWaveRT::QueryPowerChangeState
+(
+ _In_ POWER_STATE NewStateQuery
+)
+{
+ UNREFERENCED_PARAMETER(NewStateQuery);
+
+ DPF_ENTER(("[CFmMiniportWaveRT::QueryPowerChangeState]"));
+
+ // if we're in a call state other than disabled, then we need the hardware turned on
+ if (m_bFmRxState)
+ {
+ return STATUS_RESOURCE_IN_USE;
+ }
+
+ return STATUS_SUCCESS;
+} // QueryPowerChangeState
+
+