📄 hwctxt.cpp
字号:
BOOL HardwareContext::MapDMADescriptors(void)
{
DMA_ADAPTER_OBJECT Adapter;
PHYSICAL_ADDRESS PA;
Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
Adapter.InterfaceType = Internal;
Adapter.BusNumber = 0;
m_vpAudioRcvA = (DMADescriptor_T *) HalAllocateCommonBuffer(&Adapter, 0x20, &PA, FALSE);
if (m_vpAudioRcvA)
{
m_vpAudioRcvA_Physical = (DMADescriptor_T *) PA.LowPart;
}
m_vpAudioRcvB = (DMADescriptor_T *) HalAllocateCommonBuffer(&Adapter, 0x20, &PA, FALSE);
if (m_vpAudioRcvB)
{
m_vpAudioRcvB_Physical = (DMADescriptor_T *) PA.LowPart;
}
m_vpAudioXmitA = (DMADescriptor_T *) HalAllocateCommonBuffer(&Adapter, 0x20, &PA, FALSE);
if (m_vpAudioXmitA)
{
m_vpAudioXmitA_Physical = (DMADescriptor_T *) PA.LowPart;
}
m_vpAudioXmitB = (DMADescriptor_T *) HalAllocateCommonBuffer(&Adapter, 0x20, &PA, FALSE);
if (m_vpAudioXmitB)
{
m_vpAudioXmitB_Physical = (DMADescriptor_T *) PA.LowPart;
}
if (!m_vpAudioRcvA || !m_vpAudioRcvB ||
!m_vpAudioXmitA || !m_vpAudioXmitB)
{
DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: MapDMADescriptors: failed to allocate DMA descriptor buffer(s).\r\n")));
return(FALSE);
}
return (TRUE);
}
//------------------------------------------------------------------------------------------------------------
// Function: MapDeviceRegisters
//
// Purpose: Map the On-chip Device registers required for the audio driver.
//
// Returns: TRUE indicates success. FALSE indicates failure
//
//-------------------------------------------------------------------------------------------------------------
BOOL HardwareContext::MapDeviceRegisters(void)
{
PHYSICAL_ADDRESS PA;
PA.QuadPart = PXA255_BASE_REG_PA_DMAC;
m_pDMARegisters = (volatile DMAC_REG_T *) MmMapIoSpace(PA, sizeof(DMAC_REG_T), FALSE);
PA.QuadPart = PXA255_BASE_REG_PA_AC97;
m_pAc97regs = (volatile AC97_REG_T *) MmMapIoSpace(PA, sizeof(AC97_REG_T), FALSE);
PA.QuadPart = PXA255_BASE_REG_PA_GPIO;
m_pGPIORegisters = (volatile GPIO_REG_T *) MmMapIoSpace(PA, sizeof(GPIO_REG_T), FALSE);
PA.QuadPart = PXA255_BASE_REG_PA_OST;
m_pOSTimer = (volatile OST_REG_T *) MmMapIoSpace(PA, sizeof(OST_REG_T), FALSE);
PA.QuadPart = PXA255_BASE_REG_PA_CLK;
m_pClockRegs = (volatile CLK_REG_T *) MmMapIoSpace(PA, sizeof(CLK_REG_T), FALSE);
if (!m_pDMARegisters || !m_pAc97regs || !m_pGPIORegisters || !m_pOSTimer || !m_pClockRegs)
{
DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: MapDeviceRegisters: failed to map device register(s).\r\n")));
return(FALSE);
}
return (TRUE);
}
BOOL HardwareContext::InitAudioDMA()
{
_TCHAR EventName[20];
DWORD dwDMAIrq = IRQ_DMAC;
// Covert the hardwre DMA controller interrupt IRQ into a logical SYSINTR value
if(m_SysIntrAudioDMA == SYSINTR_UNDEFINED)
{
if(!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwDMAIrq, sizeof(DWORD), &m_SysIntrAudioDMA, sizeof(DWORD), NULL))
{
DEBUGMSG(ZONE_ERROR, (TEXT("Error obtaining DMA interrupt SYSINTR value!\n")));
return (FALSE);
}
}
// Install the DMA ISR handler
if(m_hDMAIsrHandler == NULL)
{
GIISR_INFO Info;
HANDLE hBusAccessHandle;
PVOID PhysAddr;
DWORD inIoSpace = 0; // io space
PHYSICAL_ADDRESS DmaRegisterAddress = {DMA_INTERRUPT_REGISTER, 0};
m_hDMAIsrHandler = LoadIntChainHandler(g_wszDmaIsrDll,
g_wszDmaIsrHandler,
(BYTE)dwDMAIrq);
if(m_hDMAIsrHandler == NULL)
{
DEBUGMSG(ZONE_ERROR, (TEXT("LoadIntChainHandler (%s, %s, %d) failed!\r\n"),
g_wszDmaIsrDll,
g_wszDmaIsrHandler,
dwDMAIrq));
return FALSE;
}
hBusAccessHandle = CreateBusAccessHandle((LPCTSTR)m_DriverIndex);
if(!BusTransBusAddrToStatic(hBusAccessHandle, Internal, 0, DmaRegisterAddress, sizeof(DWORD), &inIoSpace, &PhysAddr))
{
DEBUGMSG(ZONE_ERROR, (L"Failed TransBusAddrToStatic\r\n"));
return FALSE;
}
DEBUGMSG(ZONE_INIT, (L"Installed ISR handler, Dll = '%s', Handler = '%s', Irq = %d, PhysAddr = 0x%x\r\n",
g_wszDmaIsrDll, g_wszDmaIsrHandler, dwDMAIrq, PhysAddr));
// Set up ISR handler
Info.SysIntr = m_SysIntrAudioDMA;
Info.CheckPort = TRUE;
Info.PortIsIO = FALSE;
Info.UseMaskReg = FALSE;
Info.PortAddr = (DWORD)PhysAddr;
Info.PortSize = sizeof(DWORD);
Info.Mask = DMA_AUDIO_INTR;
if (!KernelLibIoControl(m_hDMAIsrHandler, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL))
{
DEBUGMSG(ZONE_ERROR, (L"KernelLibIoControl call failed.\r\n"));
}
CloseBusAccessHandle(hBusAccessHandle);
}
//Create event for m_SysIntrAudioDMA
m_hAudioInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!m_hAudioInterrupt)
{
return FALSE;
}
if (!InterruptInitialize (m_SysIntrAudioDMA, m_hAudioInterrupt, NULL, 0))
{
return FALSE;
}
//create and start m_hAudioInterruptThread
m_hAudioInterruptThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)CallInterruptThread,
this,
0,
NULL);
if (!m_hAudioInterruptThread)
{
return FALSE;
}
CeSetThreadPriority(m_hAudioInterruptThread, GetInterruptThreadPriority());
// Get DMA channel event handler
// Compose the name of the channel event for use with CreateEvent(...) below.
wsprintf(EventName, TEXT("DMA_CHANNEL_%d"), m_RecordingChannel);
hInputIntEvent = CreateEvent(NULL,FALSE,FALSE, EventName);
if (hInputIntEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,(TEXT("gDMAInputEvent (Named) is Zero...\r\n")));
return (FALSE);
}
wsprintf(EventName, TEXT("DMA_CHANNEL_%d"), m_PlaybackChannel);
hOutputIntEvent = CreateEvent(NULL,FALSE,FALSE, EventName);
if (hOutputIntEvent == NULL)
{
DEBUGMSG(ZONE_ERROR,(TEXT("gDMAOutputEvent (Named) is Zero...\r\n")));
return (FALSE);
}
return TRUE;
}
//------------------------------------------------------------------------------------------------------------
// Function: UnMapDeviceRegisters
//
// Purpose: Unmap the On-chip Device registers required for the audio driver.
//
//-------------------------------------------------------------------------------------------------------------
void HardwareContext::UnMapDeviceRegisters(void)
{
if (m_pDMARegisters)
{
MmUnmapIoSpace((void *)m_pDMARegisters, sizeof(DMAC_REG_T));
m_pDMARegisters = NULL;
}
if (m_pAc97regs)
{
MmUnmapIoSpace((void *)m_pAc97regs, sizeof(AC97_REG_T));
m_pAc97regs = NULL;
}
if (m_pGPIORegisters)
{
MmUnmapIoSpace((void *)m_pGPIORegisters, sizeof(GPIO_REG_T));
m_pGPIORegisters = NULL;
}
if (m_pOSTimer)
{
MmUnmapIoSpace((void *)m_pOSTimer, sizeof(OST_REG_T));
m_pOSTimer = NULL;
}
if (m_pClockRegs)
{
MmUnmapIoSpace((void *)m_pClockRegs, sizeof(CLK_REG_T));
m_pClockRegs = NULL;
}
return;
}
void HardwareContext::DeinitAudioDMA()
{
//shutdown DMA interrupt thread
if (hInputIntEvent)
{
SetEvent(hInputIntEvent);
}
if (hOutputIntEvent)
{
SetEvent(hOutputIntEvent);
}
if (m_hAudioInterrupt)
{
SetEvent(m_hAudioInterrupt);
}
if (m_hAudioInputInterruptThread)
{
WaitForSingleObject(m_hAudioInputInterruptThread, INFINITE);
CloseHandle(m_hAudioInputInterruptThread);
m_hAudioInputInterruptThread = NULL;
}
if (m_hAudioOutputInterruptThread)
{
WaitForSingleObject(m_hAudioOutputInterruptThread, INFINITE);
CloseHandle(m_hAudioOutputInterruptThread);
m_hAudioOutputInterruptThread = NULL;
}
if (m_hAudioInterruptThread)
{
WaitForSingleObject(m_hAudioInterruptThread, INFINITE);
CloseHandle(m_hAudioInterruptThread);
m_hAudioOutputInterruptThread = NULL;
}
//release DMA channel event
if (hInputIntEvent)
{
CloseHandle(hInputIntEvent);
hInputIntEvent = NULL;
}
if (hOutputIntEvent)
{
CloseHandle(hOutputIntEvent);
hOutputIntEvent = NULL;
}
if (m_hAudioInterrupt)
{
CloseHandle(m_hAudioInterrupt);
m_hAudioInterrupt = NULL;
}
}
void HardwareContext::UnmapDMA(void)
{
DMA_ADAPTER_OBJECT Adapter;
PHYSICAL_ADDRESS PA;
Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
Adapter.InterfaceType = Internal;
Adapter.BusNumber = 0;
if (m_vpAudioRcvA)
{
PA.LowPart = (DWORD)m_vpAudioRcvA_Physical;
HalFreeCommonBuffer(&Adapter, 0x20, PA, (PVOID)m_vpAudioRcvA, FALSE);
m_vpAudioRcvA = NULL;
}
if (m_vpAudioRcvB)
{
PA.LowPart = (DWORD)m_vpAudioRcvB_Physical;
HalFreeCommonBuffer(&Adapter, 0x20, PA, (PVOID)m_vpAudioRcvB, FALSE);
m_vpAudioRcvB = NULL;
}
if (m_vpAudioXmitA)
{
PA.LowPart = (DWORD)m_vpAudioXmitA_Physical;
HalFreeCommonBuffer(&Adapter, 0x20, PA, (PVOID)m_vpAudioXmitA, FALSE);
m_vpAudioXmitA = NULL;
}
if (m_vpAudioXmitB)
{
PA.LowPart = (DWORD)m_vpAudioXmitB_Physical;
HalFreeCommonBuffer(&Adapter, 0x20, PA, (PVOID)m_vpAudioXmitB, FALSE);
m_vpAudioXmitB = NULL;
}
if (m_Output_pbDMA_PAGES[0])
{
PA.LowPart = (DWORD)(m_Output_pbDMA_PAGES_Physical[0]);
HalFreeCommonBuffer(&Adapter, (AUDIO_BUFFER_SIZE * NUM_DMA_AUDIO_BUFFERS), PA, m_Output_pbDMA_PAGES[0], FALSE);
m_Output_pbDMA_PAGES[0] = NULL;
}
return;
}
BOOL HardwareContext::SafeWriteAC97(BYTE Offset, unsigned short int Data)
{
if (FALSE == m_InPowerHandler)
{
return WriteAC97(Offset, Data);
}
else
{
return WriteAC97Raw(Offset, Data);
}
}
BOOL HardwareContext::SafeReadAC97(BYTE Offset, unsigned short int * Data)
{
if (FALSE == m_InPowerHandler)
{
return ReadAC97(Offset, Data);
}
else
{
return ReadAC97Raw(Offset, Data);
}
}
void HardwareContext::GetPowerCapabilities(void * pBuf)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("HardwareContext::GetPwerCapabilities()\r\n")));
memcpy(pBuf, &g_PowerCaps, sizeof(POWER_CAPABILITIES));
}
CEDEVICE_POWER_STATE HardwareContext::GetPowerState(void)
{
return m_dwPowerState;
}
BOOL HardwareContext::QueryPowerState(CEDEVICE_POWER_STATE dwState)
{
return VALID_DX(dwState);
}
DWORD HardwareContext::SetPowerState(CEDEVICE_POWER_STATE dwState)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("HardwareContext::SetPowerState(): dwState=D%d\r\n"), dwState));
switch (dwState)
{
case D0:
m_dwPowerState = D0;
break;
case D1:
m_dwPowerState = D1;
break;
case D2:
m_dwPowerState = D2;
// Initialize Codec
InitCodec();
Lock();
// Restart DMA if it was running before suspend.
if(m_saveOutputDMARunning)
{
m_saveOutputDMARunning = FALSE;
StartOutputDMA();
}
if(m_saveInputDMARunning)
{
m_saveInputDMARunning = FALSE;
StartInputDMA();
}
Unlock();
break;
case D3:
m_dwPowerState = D3;
Lock();
if (m_OutputDMARunning)
{
m_saveOutputDMARunning = TRUE;
StopOutputDMA();
}
if (m_InputDMARunning)
{
m_saveInputDMARunning = TRUE;
StopInputDMA();
}
Unlock();
// Power down Codec
DeInitCodec();
break;
case D4:
m_dwPowerState = D4;
//Do nothing. AC link is turned off in PowerDown().
break;
default:
return MMSYSERR_INVALPARAM;
}
return MMSYSERR_NOERROR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -