hwctxt.cpp
来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C++ 代码 · 共 2,027 行 · 第 1/4 页
CPP
2,027 行
StopOutputDMA();
StopInputDMA();
Unlock();
PowerDown();
}
break;
}
// return our state
*(PCEDEVICE_POWER_STATE)pBufOut = m_Dx;
WAV_INF((_T("[WAV:INF] IOCTL_POWER_SET -> [D%d]\n\r"), m_Dx));
*pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
}
else
{
bRc = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
}
}
break;
case IOCTL_POWER_GET:
if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(CEDEVICE_POWER_STATE)) )
{
bRc = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
break;
}
*(PCEDEVICE_POWER_STATE)pBufOut = m_Dx;
RETAILMSG(1, (TEXT("WAVEDEV: IOCTL_POWER_GET: D%u \r\n"), m_Dx));
*pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
break;
default:
bRc = FALSE;
dwErr = ERROR_INVALID_FUNCTION;
DEBUGMSG (ZONE_FUNCTION, (TEXT(" Unsupported ioctl 0x%X\r\n"), dwCode));
break;
}
if (!bRc)
{
SetLastError(dwErr);
}
return(bRc);
}
BOOL
HardwareContext::StartOutputDMA()
{
ULONG OutputTransferred;
//WAV_MSG((_T("[WAV] StartOutputDMA()\r\n")));
if((m_bOutputDMARunning == FALSE) && (m_Dx == D0))
{
m_bOutputDMARunning = TRUE;
m_nOutByte[OUTPUT_DMA_BUFFER0] = 0;
m_nOutByte[OUTPUT_DMA_BUFFER1] = 0;
m_nOutputBufferInUse = OUTPUT_DMA_BUFFER0; // Start DMA with Buffer 0
m_OutputDMAStatus = (DMA_DONEA | DMA_DONEB) & ~DMA_BIU;
OutputTransferred = TransferOutputBuffer(m_OutputDMAStatus);
if(OutputTransferred)
{
CodecPowerControl(); // Turn Output Channel
CodecMuteControl(DMA_CH_OUT, FALSE); // Unmute Output Channel
// IIS PCM output enable
IIS_set_tx_mode_control(IIS_TRANSFER_NOPAUSE);
// Output DMA Start
DMA_set_channel_source(&g_OutputDMA, m_OutputDMABufferPhyPage[OUTPUT_DMA_BUFFER0], WORD_UNIT, BURST_1, INCREASE);
#if (CPU_NAME == S3C6410)
DMA_set_channel_destination(&g_OutputDMA, IIS_get_output_physical_buffer_address(IIS_CH_2), WORD_UNIT, BURST_1, FIXED);
#elif (CPU_NAME == S3C6400)
DMA_set_channel_destination(&g_OutputDMA, IIS_get_output_physical_buffer_address(IIS_CH_0), WORD_UNIT, BURST_1, FIXED);
#endif
DMA_set_channel_transfer_size(&g_OutputDMA, AUDIO_DMA_PAGE_SIZE);
DMA_set_initial_LLI(&g_OutputDMA, 1);
DMA_channel_start(&g_OutputDMA);
IIS_set_active_on();
}
else
{
WAV_ERR((_T("[WAV:ERR] StartOutputDMA() : There is no data to transfer\r\n")));
m_bOutputDMARunning = FALSE;
}
}
else
{
//WAV_ERR((_T("[WAV:ERR] StartOutputDMA() : Output DMA is already running or m_Dx[%d] is not D0\r\n"), m_Dx));
return FALSE;
}
return TRUE;
}
void
HardwareContext::StopOutputDMA()
{
//WAV_MSG((_T("[WAV] StopOutputDMA()\r\n")));
if (m_bOutputDMARunning)
{
m_OutputDMAStatus = DMA_CLEAR;
// Stop output DMA
DMA_channel_stop(&g_OutputDMA);
// IIS PCM output disable
IIS_set_tx_mode_control(IIS_TRANSFER_PAUSE);
if (m_bInputDMARunning == FALSE) IIS_set_active_off();
}
m_bOutputDMARunning = FALSE;
CodecMuteControl(DMA_CH_OUT, TRUE);
CodecPowerControl();
}
BOOL
HardwareContext::StartInputDMA()
{
WAV_MSG((_T("[WAV] StartInputDMA()\r\n")));
if(m_bInputDMARunning == FALSE)
{
m_bInputDMARunning = TRUE;
m_nInByte[INPUT_DMA_BUFFER0] = 0;
m_nInByte[INPUT_DMA_BUFFER1] = 0;
m_nInputBufferInUse = INPUT_DMA_BUFFER0; // Start DMA with Buffer 0
m_InputDMAStatus = (DMA_DONEA | DMA_DONEB) & ~DMA_BIU;
CodecPowerControl(); // Turn On Channel
CodecMuteControl(DMA_CH_IN, FALSE); // Unmute Input Channel
// IIS PCM input enable
IIS_set_rx_mode_control(IIS_TRANSFER_NOPAUSE);
#if (CPU_NAME == S3C6410)
DMA_set_channel_source(&g_InputDMA, IIS_get_input_physical_buffer_address(IIS_CH_2), WORD_UNIT, BURST_1, FIXED);
#elif (CPU_NAME == S3C6400)
DMA_set_channel_source(&g_InputDMA, IIS_get_input_physical_buffer_address(IIS_CH_0), WORD_UNIT, BURST_1, FIXED);
#endif
DMA_set_channel_destination(&g_InputDMA, m_InputDMABufferPhyPage[INPUT_DMA_BUFFER0], WORD_UNIT, BURST_1, INCREASE);
DMA_set_channel_transfer_size(&g_InputDMA, AUDIO_DMA_PAGE_SIZE);
DMA_set_initial_LLI(&g_InputDMA, 1);
DMA_channel_start(&g_InputDMA);
IIS_set_active_on();
}
else
{
//WAV_ERR((_T("[WAV:ERR] StartInputDMA() : Input DMA is already running\r\n")));
return FALSE;
}
return TRUE;
}
void
HardwareContext::StopInputDMA()
{
WAV_MSG((_T("[WAV] StopInputDMA()\r\n")));
if (m_bInputDMARunning)
{
DMA_channel_stop(&g_InputDMA);
// IIS PCM input disable
IIS_set_rx_mode_control(IIS_TRANSFER_PAUSE);
m_InputDMAStatus = DMA_CLEAR;
if (m_bOutputDMARunning == FALSE) IIS_set_active_off();
}
m_bInputDMARunning = FALSE;
CodecMuteControl(DMA_CH_IN, TRUE);
CodecPowerControl();
}
DWORD
HardwareContext::GetOutputGain (void)
{
return m_dwOutputGain;
}
MMRESULT
HardwareContext::SetOutputGain (DWORD dwGain)
{
WAV_MSG((_T("[WAV] SetOutputGain(0x%08x)\r\n"), dwGain));
m_dwOutputGain = dwGain & 0xffff; // save off so we can return this from GetGain - but only MONO
// convert 16-bit gain to 5-bit attenuation
UCHAR ucGain;
if (m_dwOutputGain == 0)
{
ucGain = 0x3F; // mute: set maximum attenuation
}
else
{
ucGain = (UCHAR) ((0xffff - m_dwOutputGain) >> 11); // codec supports 64dB attenuation, we'll only use 32
}
//ASSERT((ucGain & 0xC0) == 0); // bits 6,7 clear indicate DATA0 in Volume mode.
// TODO: When Control HW Volume???
return MMSYSERR_NOERROR;
}
DWORD
HardwareContext::GetInputGain (void)
{
return m_dwInputGain;
}
MMRESULT
HardwareContext::SetInputGain (DWORD dwGain)
{
WAV_MSG((_T("[WAV] SetInputGain(0x%08x)\r\n"), dwGain));
m_dwInputGain = dwGain;
if (!m_bInputMute)
{
m_InputDeviceContext.SetGain(dwGain);
}
return MMSYSERR_NOERROR;
}
BOOL
HardwareContext::GetOutputMute (void)
{
return m_bOutputMute;
}
MMRESULT
HardwareContext::SetOutputMute (BOOL bMute)
{
#if (CPU_NAME == S3C6400)
USHORT CodecReg;
#endif
WAV_INF((_T("[WAV:INF] ++SetOutputMute(%d)\n\r"), bMute));
m_bOutputMute = bMute;
#if (CPU_NAME == S3C6410)
if (bMute)
{
WriteCodecRegister(WM8580_DAC_CONTROL5, 0x010);
}
else
{
WriteCodecRegister(WM8580_DAC_CONTROL5, 0x000);
}
#elif (CPU_NAME == S3C6400)
CodecReg = ReadCodecRegister(WM8753_DAC_CONTROL);
if (bMute)
{
CodecReg |= WM8753_DAC_SOFT_MUTE;
}
else
{
CodecReg &= ~WM8753_DAC_SOFT_MUTE;
}
WriteCodecRegister(WM8753_DAC_CONTROL, CodecReg);
#endif
WAV_INF((_T("[WAV:INF] --SetOutputMute()\n\r")));
return MMSYSERR_NOERROR;
}
BOOL
HardwareContext::GetInputMute (void)
{
return m_bInputMute;
}
MMRESULT
HardwareContext::SetInputMute (BOOL bMute)
{
m_bInputMute = bMute;
return m_InputDeviceContext.SetGain(bMute ? 0: m_dwInputGain);
}
DWORD
HardwareContext::ForceSpeaker(BOOL bForceSpeaker)
{
// If m_NumForcedSpeaker is non-zero, audio should be routed to an
// external speaker (if hw permits).
if (bForceSpeaker)
{
m_NumForcedSpeaker++;
if (m_NumForcedSpeaker == 1)
{
SetSpeakerEnable(TRUE);
}
}
else
{
m_NumForcedSpeaker--;
if (m_NumForcedSpeaker ==0)
{
SetSpeakerEnable(FALSE);
}
}
return MMSYSERR_NOERROR;
}
void
HardwareContext::InterruptThreadOutputDMA()
{
ULONG OutputTransferred;
#if (_WIN32_WCE < 600)
// Fast way to access embedded pointers in wave headers in other processes.
SetProcPermissions((DWORD)-1);
#endif
WAV_INF((_T("[WAV:INF] ++InterruptThreadOutputDMA()\n\r")));
while(TRUE)
{
WaitForSingleObject(m_hOutputDMAInterrupt, INFINITE);
Lock();
__try
{
DMA_set_interrupt_mask(&g_OutputDMA);
DMA_clear_interrupt_pending(&g_OutputDMA);
InterruptDone(m_dwSysintrOutput);
DMA_clear_interrupt_mask(&g_OutputDMA);
if ( m_Dx == D0 )
{
// DMA Output Buffer is Changed by LLI
if (m_nOutputBufferInUse == OUTPUT_DMA_BUFFER0)
{
// Buffer0 DMA finished
// DMA start with Buffer 1
m_nOutputBufferInUse = OUTPUT_DMA_BUFFER1;
}
else
{
// Buffer 1 DMA finished
// DMA start with Buffer 0
m_nOutputBufferInUse = OUTPUT_DMA_BUFFER0;
}
if(m_OutputDMAStatus & DMA_BIU)
{
m_OutputDMAStatus &= ~DMA_STRTB; // Buffer B just completed...
m_OutputDMAStatus |= DMA_DONEB;
m_OutputDMAStatus &= ~DMA_BIU; // Buffer A is in use
}
else
{
m_OutputDMAStatus &= ~DMA_STRTA; // Buffer A just completed...
m_OutputDMAStatus |= DMA_DONEA;
m_OutputDMAStatus |= DMA_BIU; // Buffer B is in use
}
OutputTransferred = TransferOutputBuffer(m_OutputDMAStatus);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG(ZONE_ERROR, (TEXT("WAVDEV2.DLL:InterruptThreadOutputDMA() - EXCEPTION: %d"), GetExceptionCode()));
}
Unlock();
}
WAV_INF((_T("[WAV:INF] --InterruptThreadOutputDMA()\n\r")));
}
void
HardwareContext::InterruptThreadInputDMA()
{
ULONG InputTransferred; // How can I use it ???
#if (_WIN32_WCE < 600)
// Fast way to access embedded pointers in wave headers in other processes.
SetProcPermissions((DWORD)-1);
#endif
//WAV_INF((_T("[WAV:INF] ++InterruptThreadInputDMA()\n\r")));
while(TRUE)
{
WaitForSingleObject(m_hInputDMAInterrupt, INFINITE);
Lock();
__try
{
DMA_set_interrupt_mask(&g_InputDMA);
DMA_clear_interrupt_pending(&g_InputDMA);
InterruptDone(m_dwSysintrInput);
DMA_clear_interrupt_mask(&g_InputDMA);
if ( m_Dx == D0 )
{
if (m_nInputBufferInUse == INPUT_DMA_BUFFER0)
{
// Buffer0 DMA finished
// DMA start with Buffer 1
m_nInputBufferInUse = INPUT_DMA_BUFFER1;
}
else
{
// Buffer 1 DMA finished
// DMA start with Buffer 0
m_nInputBufferInUse = INPUT_DMA_BUFFER0;
}
if(m_InputDMAStatus & DMA_BIU)
{
m_InputDMAStatus &= ~DMA_STRTB; // Buffer B just completed...
m_InputDMAStatus |= DMA_DONEB;
m_InputDMAStatus &= ~DMA_BIU; // Buffer A is in use
}
else
{
m_InputDMAStatus &= ~DMA_STRTA; // Buffer A just completed...
m_InputDMAStatus |= DMA_DONEA;
m_InputDMAStatus |= DMA_BIU; // Buffer B is in use
}
InputTransferred = TransferInputBuffers(m_InputDMAStatus);
//WAV_INF((_T("[WAV:INF] InputTransferred = %d\n\r"), InputTransferred));
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DEBUGMSG(ZONE_ERROR, (TEXT("WAVDEV2.DLL:InterruptThreadInputDMA() - EXCEPTION: %d"), GetExceptionCode()));
}
Unlock();
}
//WAV_INF((_T("[WAV:INF] --InterruptThreadInputDMA()\n\r")));
}
BOOL
HardwareContext::MapRegisters()
{
BOOL bRet = TRUE;
WAV_MSG((_T("[WAV] ++MapRegisters()\n\r")));
// Alloc and Map GPIO SFR
g_pGPIOReg = (S3C6410_GPIO_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_GPIO, sizeof(S3C6410_GPIO_REG), FALSE);
if (g_pGPIOReg == NULL)
{
WAV_ERR((_T("[WAV:ERR] MapRegisters() : g_pGPIOReg DrvLib_MapIoSpace() Failed\n\r")));
bRet = FALSE;
goto CleanUp;
}
// Alloc and Map DMAC0 SFR
g_pDMAC0Reg = (S3C6410_DMAC_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_DMA0, sizeof(S3C6410_DMAC_REG), FALSE);
if (g_pDMAC0Reg == NULL)
{
WAV_ERR((_T("[WAV:ERR] MapRegisters() : g_pDMAC0Reg DrvLib_MapIoSpace() Failed\n\r")));
bRet = FALSE;
goto CleanUp;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?