hwctxt.cpp
来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C++ 代码 · 共 2,027 行 · 第 1/4 页
CPP
2,027 行
// No done bits set- must not be my interrupt
return 0;
case DMA_DONEA|DMA_DONEB|DMA_BIU:
// Load B, then A
BytesTransferred = FillInputBuffer(INPUT_DMA_BUFFER1);
// fall through
case DMA_DONEA: // This should never happen!
case DMA_DONEA|DMA_BIU:
// Load A
BytesTransferred += FillInputBuffer(INPUT_DMA_BUFFER0);
break;
case DMA_DONEA|DMA_DONEB:
// Load A, then B
BytesTransferred = FillInputBuffer(INPUT_DMA_BUFFER0);
BytesTransferred += FillInputBuffer(INPUT_DMA_BUFFER1);
break;
case DMA_DONEB|DMA_BIU: // This should never happen!
case DMA_DONEB:
// Load B
BytesTransferred += FillInputBuffer(INPUT_DMA_BUFFER1);
break;
}
// If it was our interrupt, but we weren't able to transfer any bytes
// (e.g. no empty buffers ready to be filled)
// Then stop the input DMA
if (BytesTransferred==0)
{
StopInputDMA();
}
else
{
StartInputDMA(); // for DMA resume when wake up
}
return BytesTransferred;
}
ULONG
HardwareContext::FillInputBuffer(int nBufferNumber)
{
ULONG BytesTransferred = 0;
PBYTE pBufferStart = m_InputDMABufferVirPage[nBufferNumber];
PBYTE pBufferEnd = pBufferStart + AUDIO_DMA_PAGE_SIZE;
PBYTE pBufferLast;
//WAV_MSG((_T("[WAV] FillInputBuffer(%d)\n\r"), nBufferNumber));
__try
{
pBufferLast = m_InputDeviceContext.TransferBuffer(pBufferStart, pBufferEnd, NULL);
BytesTransferred = m_nInByte[nBufferNumber] = pBufferLast-pBufferStart;
if(nBufferNumber == INPUT_DMA_BUFFER0) // Input Buffer A
{
m_InputDMAStatus &= ~DMA_DONEA;
m_InputDMAStatus |= DMA_STRTA;
}
else // Input Buffer B
{
m_InputDMAStatus &= ~DMA_DONEB;
m_InputDMAStatus |= DMA_STRTB;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
WAV_ERR((_T("[WAV:ERR] FillInputBuffer() : Exception ccurs [%d]\n\r"), GetExceptionCode()));
}
return BytesTransferred;
}
void
HardwareContext::WriteCodecRegister(UCHAR Reg, USHORT Val)
{
#if (CPU_NAME == S3C6410)
// WM8580
// SFR[B15..B9], DATA[B8..B0]
// +------------------------+
// | B15...B9 B8.........B0 |
// +------------------------+
//
UCHAR command0, command1;
m_WM8580_SFR_Table[Reg] = Val;
#elif (CPU_NAME == S3C6400)
// WM8753
// SFR[B15..B9], DATA[B8..B0]
// +------------------------+
// | B15...B9 B8.........B0 |
// +------------------------+
//
UCHAR command0, command1;
m_WM8753_SFR_Table[Reg] = Val;
#endif
WAV_MSG((_T("[WAV] WriteCodecRegister(0x%02x, 0x%x)\n\r"), Reg, Val));
command0 = (UCHAR)(Reg<<1)|(UCHAR)((Val>>8)&1);
command1 = (UCHAR)(Val&0xFF);
HW_WriteRegisters((PUCHAR)&command1, command0, 1);
}
DWORD
HardwareContext::WriteCodecRegister2(UCHAR Reg, USHORT Val)
{
DWORD nReturned=0, bytes=0;
BOOL bRet = FALSE;
UCHAR buff[2];
IIC_IO_DESC IIC_Data;
#if (CPU_NAME == S3C6410)
// WM8580
// SFR[B15..B9], DATA[B8..B0]
// +------------------------+
// | B15...B9 B8.........B0 |
// +------------------------+
//
UCHAR command0, command1;
m_WM8580_SFR_Table[Reg] = Val;
#elif (CPU_NAME == S3C6400)
// WM8753
// SFR[B15..B9], DATA[B8..B0]
// +------------------------+
// | B15...B9 B8.........B0 |
// +------------------------+
//
UCHAR command0, command1;
m_WM8753_SFR_Table[Reg] = Val;
#endif
WAV_MSG((_T("[WAV] WriteCodecRegister2(0x%02x, 0x%x)\n\r"), Reg, Val));
buff[0] = command0 = (UCHAR)(Reg<<1)|(UCHAR)((Val>>8)&1);
buff[1] = command1 = (UCHAR)(Val&0xFF);
IIC_Data.SlaveAddress = CHIP_ID;
IIC_Data.Data = buff;
IIC_Data.Count = 2;
bRet = DeviceIoControl(m_hI2C,
IOCTL_IIC_WRITE,
&IIC_Data, sizeof(IIC_IO_DESC),
NULL, 0,
&bytes, NULL);
if (bRet == 0)
{
RETAILMSG(1, (TEXT("[HWCTXT] ERROR: Device I/O Control Request FAIL, 0x%08X\r\n"), GetLastError()));
nReturned = -1;
}
WAV_MSG((_T("[WAV] WriteCodecRegister2()-\n\r")));
return nReturned;
}
USHORT
HardwareContext::ReadCodecRegister(UCHAR Reg)
{
USHORT RegValue = 0;
#if (CPU_NAME == S3C6410)
//-----------------------------------------------------------------------------------------------------
// !!!!! Caution !!!!!
// WM8580 support write operation only.
// I write sfr data value onto internal table(m_WM8580_SFR_Table), on every write operation for backup.
// And To support read operation, I just return some value from internal table(m_WM8580_SFR_Table).
//-----------------------------------------------------------------------------------------------------
RegValue = m_WM8580_SFR_Table[(int)Reg];
#elif (CPU_NAME == S3C6400)
//-----------------------------------------------------------------------------------------------------
// !!!!! Caution !!!!!
// WM8753 support write operation only.
// I write sfr data value onto internal table(m_WM8753_SFR_Table), on every write operation for backup.
// And To support read operation, I just return some value from internal table(m_WM8753_SFR_Table).
//-----------------------------------------------------------------------------------------------------
RegValue = m_WM8753_SFR_Table[(int)Reg];
#endif
WAV_MSG((_T("[WAV] ReadCodecRegister(0x%02x) = 0x%03x\n\r"), Reg, RegValue));
return (USHORT)RegValue;
}
BOOL
HardwareContext::CodecPowerControl()
{
#if (CPU_NAME == S3C6400)
USHORT mRegValue;
#endif
#if 1
#if (CPU_NAME == S3C6410)
if( m_bInputDMARunning & m_bOutputDMARunning )
{
RETAILMSG(FALSE,(_T("Codec_channel() - In & Out\r\n")));
WriteCodecRegister(WM8580_PWRDN1, WM8580_ALL_POWER_ON); // ADC, DAC power up
}
else if( m_bInputDMARunning )
{
RETAILMSG(FALSE,(_T("Codec_channel() - In\r\n")));
WriteCodecRegister(WM8580_PWRDN1, WM8580_PWRDN1_ADCPD_ENABLE|WM8580_PWRDN1_DACPD_ALL_DISABLE); // ADC power up, DAC power down
}
else if( m_bOutputDMARunning )
{
RETAILMSG(FALSE,(_T("Codec_channel() - Out\r\n")));
WriteCodecRegister(WM8580_PWRDN1, WM8580_PWRDN1_DACPD_ALL_ENABLE|WM8580_PWRDN1_ADCPD_DISABLE); // DAC power up, ADC power down
}
else
{
RETAILMSG(FALSE,(_T("Codec_channel() - none\r\n")));
WriteCodecRegister(WM8580_PWRDN1, WM8580_PWRDN1_ADCPD_DISABLE|WM8580_PWRDN1_DACPD_ALL_DISABLE ); // ADC/DAC power down
}
#elif (CPU_NAME == S3C6400)
if( (m_bInputDMARunning == FALSE) && (m_bOutputDMARunning == FALSE) ) // Input / Output Off
{
WAV_MSG((_T("[WAV] CodecPowerControl() : CodecPowerControl() ADC & DAC All Off\n\r")));
mRegValue = ReadCodecRegister(WM8753_PWR_MGMT_1);
mRegValue = mRegValue & ~(WM8753_PWR1_VMIDSEL_MASK) | (WM8753_PWR1_VMIDSEL_DISABLE);
mRegValue |= (WM8753_PWR1_DIGENB); // MCLK is disabled
WriteCodecRegister(WM8753_PWR_MGMT_1, mRegValue); // Vmid/VREF power down
}
else
{
WAV_MSG((_T("[WAV] CodecPowerControl() : CodecPowerControl() ADC and/or DAC is On\n\r")));
mRegValue = ReadCodecRegister(WM8753_PWR_MGMT_1);
mRegValue = mRegValue & ~(WM8753_PWR1_VMIDSEL_MASK) | (WM8753_PWR1_VMIDSEL_50KOHM);
mRegValue &= ~(WM8753_PWR1_DIGENB); // MCLK is enabled
WriteCodecRegister(WM8753_PWR_MGMT_1, mRegValue); // Vmid/VREF power up
}
if( m_bOutputDMARunning ) // Output On
{
WAV_MSG((_T("[WAV] CodecPowerControl() : CodecPowerControl() DAC On\n\r")));
mRegValue = ReadCodecRegister(WM8753_PWR_MGMT_3);
mRegValue |= (WM8753_PWR3_LOUT1|WM8753_PWR3_ROUT1);
WriteCodecRegister(WM8753_PWR_MGMT_3, mRegValue); // DAC power up
}
else // Output Off
{
WAV_MSG((_T("[WAV] CodecPowerControl() : CodecPowerControl() DAC Off\n\r")));
mRegValue = ReadCodecRegister(WM8753_PWR_MGMT_3);
mRegValue &= ~(WM8753_PWR3_LOUT1|WM8753_PWR3_ROUT1);
WriteCodecRegister(WM8753_PWR_MGMT_3, mRegValue); // DAC power down
}
if( m_bInputDMARunning ) // Input On
{
WAV_MSG((_T("[WAV] CodecPowerControl() : CodecPowerControl() ADC On\n\r")));
m_shInputVolumeL = ReadCodecRegister(WM8753_LEFT_ADC_VOLUME);
m_shInputVolumeR = ReadCodecRegister(WM8753_RIGHT_ADC_VOLUME);
WriteCodecRegister(WM8753_LEFT_ADC_VOLUME, WM8753_ADCVOL_MUTE); // DAC power down
WriteCodecRegister(WM8753_RIGHT_ADC_VOLUME, WM8753_ADCVOL_MUTE); // DAC power down
}
else // Input Off
{
WAV_MSG((_T("[WAV] CodecPowerControl() : CodecPowerControl() ADC Off\n\r")));
WriteCodecRegister(WM8753_LEFT_ADC_VOLUME, m_shInputVolumeL); // DAC power down
WriteCodecRegister(WM8753_RIGHT_ADC_VOLUME, m_shInputVolumeR); // DAC power down
}
#endif
#endif
return(TRUE);
}
BOOL
HardwareContext::CodecMuteControl(DWORD channel, BOOL bMute)
{
#if (CPU_NAME == S3C6400)
USHORT volume;
#endif
#if 1
#if (CPU_NAME == S3C6410)
if(channel & DMA_CH_OUT)
{
if(bMute)
{
WriteCodecRegister(WM8580_DAC_CONTROL5, 0x010);
}
else
{
WriteCodecRegister(WM8580_DAC_CONTROL5, 0x000);
}
}
if(channel & DMA_CH_IN)
{
if(bMute)
{
WriteCodecRegister(WM8580_ADC_CONTROL1, 0x044);
}
else
{
WriteCodecRegister(WM8580_ADC_CONTROL1, 0x040);
}
}
#elif (CPU_NAME == S3C6400)
if((channel & DMA_CH_OUT ))// && !m_bOutputDMARunning )
{
if(bMute)
{
WAV_MSG((_T("[WAV] CodecMuteControl() : CH_OUT is muted\n\r")));
volume = ReadCodecRegister(WM8753_DAC_CONTROL);
volume |= WM8753_DAC_SOFT_MUTE;
WriteCodecRegister(WM8753_DAC_CONTROL, volume);
}
else
{
WAV_MSG((_T("[WAV] CodecMuteControl() : CH_OUT is un-muted\n\r")));
volume = ReadCodecRegister(WM8753_DAC_CONTROL);
volume &= ~WM8753_DAC_SOFT_MUTE;
WriteCodecRegister(WM8753_DAC_CONTROL, volume);
}
}
if( (channel & DMA_CH_IN))// && !m_bInputDMARunning )
{
if(bMute)
{
WAV_MSG((_T("[WAV] CodecMuteControl() : CH_IN is muted\n\r")));
volume = ReadCodecRegister(WM8753_LEFT_INPUT_VOLUME);
WriteCodecRegister(WM8753_LEFT_INPUT_VOLUME, volume|WM8753_INVOL_MUTE);
volume = ReadCodecRegister(WM8753_RIGHT_INPUT_VOLUME);
WriteCodecRegister(WM8753_RIGHT_INPUT_VOLUME, volume|WM8753_INVOL_MUTE);
}
else
{
WAV_MSG((_T("[WAV] CodecMuteControl() : CH_IN is un-muted\n\r")));
volume = ReadCodecRegister(WM8753_LEFT_INPUT_VOLUME);
WriteCodecRegister(WM8753_LEFT_INPUT_VOLUME, volume&~WM8753_INVOL_MUTE);
volume = ReadCodecRegister(WM8753_RIGHT_INPUT_VOLUME);
WriteCodecRegister(WM8753_RIGHT_INPUT_VOLUME, volume&~WM8753_INVOL_MUTE);
}
}
#endif
#endif
return(TRUE);
}
void HardwareContext::SetSpeakerEnable(BOOL bEnable)
{
// Code to turn speaker on/off here
return;
}
void CallInterruptThreadOutputDMA(HardwareContext *pHWContext)
{
pHWContext->InterruptThreadOutputDMA();
}
void CallInterruptThreadInputDMA(HardwareContext *pHWContext)
{
pHWContext->InterruptThreadInputDMA();
}
//
#if (CPU_NAME == S3C6410)
// Write WM8580 IIS Codec registers directly from our cache
#elif (CPU_NAME == S3C6400)
// Write WM8753 IIS Codec registers directly from our cache
#endif
//
DWORD HardwareContext::HW_WriteRegisters(
PUCHAR pBuff, // Optional buffer
UCHAR StartReg, // start register
DWORD nRegs // number of registers
)
{
DWORD dwErr=0,bytes;
UCHAR buff[2];
IIC_IO_DESC IIC_Data;
buff[0] = StartReg;
buff[1] = pBuff[0];
#if (CPU_NAME == S3C6410)
IIC_Data.SlaveAddress = WM8580_WRITE;
#elif (CPU_NAME == S3C6400)
IIC_Data.SlaveAddress = WM8753_WRITE;
#endif
IIC_Data.Data = buff;
IIC_Data.Count = 2;
WAV_MSG((_T("[WAV] HW_WriteRegisters()\r\n")));
// use iocontrol to write
if ( !DeviceIoControl(m_hI2C,
IOCTL_IIC_WRITE,
&IIC_Data, sizeof(IIC_IO_DESC),
NULL, 0,
&bytes, NULL) )
{
dwErr = GetLastError();
}
if ( dwErr )
{
WAV_ERR((_T("[WAV::ERR]I2CWrite ERROR: %u \r\n"), dwErr));
}
return dwErr;
}
DWORD HardwareContext::HW_ReadRegisters(
PUCHAR pBuff, // Optional buffer
UCHAR StartReg, // start register
DWORD nRegs // number of registers
)
{
DWORD dwErr=0;
DWORD bytes;
IIC_IO_DESC IIC_AddressData, IIC_Data;
#if (CPU_NAME == S3C6410)
IIC_AddressData.SlaveAddress = WM8580_READ;
#elif (CPU_NAME == S3C6400)
IIC_AddressData.SlaveAddress = WM8753_READ;
#endif
IIC_AddressData.Data = &StartReg;
IIC_AddressData.Count = 1;
#if (CPU_NAME == S3C6410)
IIC_Data.SlaveAddress = WM8580_READ;
#elif (CPU_NAME == S3C6400)
IIC_Data.SlaveAddress = WM8753_READ;
#endif
IIC_Data.Data = pBuff;
IIC_Data.Count = 1;
WAV_MSG((_T("[WAV] HW_ReadRegisters()\r\n")));
// use iocontrol to read
if ( !DeviceIoControl(m_hI2C,
IOCTL_IIC_READ,
&IIC_AddressData, sizeof(IIC_IO_DESC),
&IIC_Data, sizeof(IIC_IO_DESC),
&bytes, NULL) )
{
dwErr = GetLastError();
}
if ( dwErr )
{
WAV_ERR((_T("[WAV::ERR]I2CRead ERROR: %u \r\n"), dwErr));
}
return dwErr;
}
#if (CPU_NAME == S3C6410)
void HardwareContext::I2S_Init8580Driver()
{
int i;
WAV_MSG((_T("[WAV] +I2S_Init8580Driver()\n\r")));
// Initialize WM8580_SFR_Table data
for (i=0; i<WM8580_MAX_REGISTER_COUNT; i++)
{
m_WM8580_SFR_Table[i] = 0;
}
// Default setting value
for(i=0; i<(sizeof(WM8580_Codec_Init_Table)/sizeof(unsigned int)/2); i++)
{
WriteCodecRegister(WM8580_Codec_Init_Table[i][0], WM8580_Codec_Init_Table[i][1]);
}
}
#elif (CPU_NAME == S3C6400)
void HardwareContext::I2S_Init8753Driver()
{
int i;
WAV_MSG((_T("[WAV] +I2S_Init8753Driver()\n\r")));
// Initialize WM8753_SFR_Table data
for (i=0; i<WM8753_MAX_REGISTER_COUNT; i++)
m_WM8753_SFR_Table[i] = 0;
// Default setting value
//for(i=0; i<WM8753_MAX_REGISTER_COUNT; i++)
for(i=0; i<(sizeof(WM8753_Codec_Init_Table)/sizeof(unsigned int)/2); i++)
{
WriteCodecRegister(WM8753_Codec_Init_Table[i][0], WM8753_Codec_Init_Table[i][1]);
}
WAV_MSG((_T("[WAV] -I2S_Init8753Driver()\n\r")));
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?