📄 hwctxt.cpp
字号:
#if USE_I2S_INTERFACE
m_vpAudioRcvB-> dsadr= DMAC_IIS_AUDIO_RCV_FIFO; // destination address of the RcvB buffer
#else
m_vpAudioRcvB-> dsadr= DMAC_AC97_AUDIO_RCV_FIFO; // destination address of the RcvB buffer
#endif
m_vpAudioRcvB-> dcmd = CmdBuff.DcmdDword ; // size and cmd values of the RcvB buffer
return TRUE;
}
//------------------------------------------------------------------------------------------------------------
// Function: StopDmac
//
// Purpose: To stop DMA transmit
//-------------------------------------------------------------------------------------------------------------
void HardwareContext::StopDmac(int Channel)
{
m_pDMARegisters->dcsr[Channel] &= ~DCSR_RUN; //clear the run but
return;
}
//------------------------------------------------------------------------------------------------------------
// Function: ClearDmac
//
// Purpose: To clear DMA status
//-------------------------------------------------------------------------------------------------------------
VOID HardwareContext::ClearDmac(int Channel)
{
DWORD dwDCSR;
dwDCSR = m_pDMARegisters->dcsr[Channel];
if(dwDCSR & DCSR_STOPINTR)
{
dwDCSR &= ~DCSR_STOPIRQEN;
}
// Clear the status
m_pDMARegisters->dcsr[Channel] = dwDCSR;
return;
}
//------------------------------------------------------------------------------------------------------------
// Function: AC97SetSampleRate
//
// Purpose: Write the sample rate value to the ac97 codec
//-------------------------------------------------------------------------------------------------------------
BOOL HardwareContext::SetSampleRate(unsigned short int SampleRate, WAPI_INOUT apidir )
{
short int RetVal=TRUE;
unsigned short int value = 0;
switch(SampleRate)
{
case 8000:
value = KHZ08_000;
break;
case 11025:
value = KHZ11_025;
break;
case 16000:
value = KHZ16_000;
break;
case 22050:
value = KHZ22_050;
break;
case 32000:
value = KHZ32_000;
break;
case 44100:
value = KHZ44_100;
break;
case 48000:
value = KHZ48_000;
break;
default:
DEBUGCHK(0); //we sent a bad rate
RetVal=FALSE;
return (RetVal);
}
#if USE_I2S_INTERFACE
if (apidir == WAPI_IN)
{
RetVal=SetI2sSampleRate(SampleRate); //set the input sample rate
}
else
{
RetVal=SetI2sSampleRate(SampleRate); //set the output sample rate
}
#else
if (apidir == WAPI_IN)
RetVal=SafeWriteCodec((XLLP_UINT16_T)AUDIO_ADC_RATE,value , DEV_AUDIO); //set the input sample rate
else
RetVal=SafeWriteCodec((XLLP_UINT16_T)AUDIO_DAC_RATE,value , DEV_AUDIO); //set the output sample rate
#endif
return (RetVal);
}
void HardwareContext::DumpDmacRegs()
{
#if 0
int i;
DEBUGMSG(ZONE_ERROR, (TEXT( "gsr %x, posr %x, pocr %x, pisr %x, picr %x\r\n" ),
m_pAc97regs->GSR,
m_pAc97regs->POSR,
m_pAc97regs->POCR,
m_pAc97regs->PISR,
m_pAc97regs->PICR
) );
for (i=0; i< 16; i++)
DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->dcsr[%d] %x \r\n" ),i,m_pDMARegisters->dcsr[i] ) );
//skip rsvd section rsvd0[44];
DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->dint %x \r\n" ),m_pDMARegisters->dint ) );
//skip rsvd seciton rsvd1[3];
for (i=0; i< 39; i++)
DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->drcmr[%d] %x \r\n" ),i,m_pDMARegisters->drcmr[i] ) );
for (i=0; i<16; i++)
{
DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->ddg[%d].ddadr %x \r\n" ),i,m_pDMARegisters->ddg[i].ddadr ) );
DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->ddg[%d].dsadr %x \r\n" ),i,m_pDMARegisters->ddg[i].dsadr ) );
DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->ddg[%d].dtadr %x \r\n" ),i,m_pDMARegisters->ddg[i].dtadr ) );
DEBUGMSG(ZONE_ERROR, (TEXT( "m_pDMARegisters->ddg[%d].dcmd %x \r\n" ),i,m_pDMARegisters->ddg[i].dcmd ) );
}
#endif
}
void HardwareContext::InitCodec(void)
{
static DWORD VendorId=0;
unsigned short int VidTemp=0;
unsigned short int Ac97RegisterData=0;
unsigned short int FeatureCrs1Data=0;
DEBUGMSG(ZONE_INIT, (TEXT("HardwareContext::InitCodec++\r\n")));
//Get vendor ID
if(VendorId == 0)
{
SafeReadCodec(VENDOR_ID1, &VidTemp, DEV_AUDIO);
VendorId= (VidTemp <<16); //ffffffffssssssss // f=first ascii s = second ascii
SafeReadCodec(VENDOR_ID2, &VidTemp, DEV_AUDIO);
VendorId |=VidTemp; //ttttttttrrrrrrrr //t = third ascii, r=rev #
VendorId &= 0xfffffff0;//trim of version number
}
//
//compliant codecs such as Crystal require the PCM volume
//if it's a ucb1400 then don't write the PCM volume (although it shouldn't hurt)
//
//vendor specific
switch (VendorId)
{
case 0x50534300: //philips UCB1400
#if 0
SafeWriteCodec(FEATURE_CSR2, PWR_SMART_CODEC, DEV_AUDIO);
//
//CAREFULL, writing the FEATURE_CSR1 could mess up the touch screen
//
SafeReadCodec(FEATURE_CSR1,&Ac97RegisterData, DEV_AUDIO);
Ac97RegisterData = Ac97RegisterData & EQ_MASK; //get just EQ data
//Set bass and treble to a good sounding value
Ac97RegisterData = Ac97RegisterData | 0x5480;
SafeReadCodec(FEATURE_CSR1,&FeatureCrs1Data, DEV_AUDIO);
FeatureCrs1Data = FeatureCrs1Data & ~0x8000; // lob off reserved bit (must be 0)
FeatureCrs1Data = FeatureCrs1Data & ~EQ_MASK; // lob off eq data
FeatureCrs1Data = FeatureCrs1Data | Ac97RegisterData; // stored EQ data with actual Feature data
//comment out headphone enable to save power, use an app to turn it on instead
//HACK: If the capabiliters reads 0x2a0 it's rev 2a, if its 0x2a then its rev 1b.
SafeReadCodec(0, (UINT16 *)&m_ResetCaps, DEV_TOUCH);
if (m_ResetCaps==REV_2A)
{
FeatureCrs1Data = FeatureCrs1Data | (unsigned short) HPEN_MASK; //turn on head phone
m_CodecType=UCB14002A;
DEBUGMSG(ZONE_VERBOSE, (TEXT( "-- UCB14002A \r\n") ) );
}
else
{
m_CodecType=UCB14001B;
DEBUGMSG(ZONE_VERBOSE, (TEXT( "-- UCB14001b \r\n") ) );
}
// Enable DC filter and High Pass filter
FeatureCrs1Data = FeatureCrs1Data | 0x0018;
//Write the data back to CSR1
SafeWriteCodec(FEATURE_CSR1, FeatureCrs1Data, DEV_AUDIO);
//Force VRA (variable rate audio) to be on
SafeWriteCodec(EXTENDED_AUDIO_CTRL, VRA_ENABLED_MASK, DEV_AUDIO);
//Default is AUDIO_MIC_INPUT_MONO
SafeWriteCodec(RECORD_SELECT, 0, DEV_AUDIO);
//Set the output volume from the OS
SafeWriteCodec(MASTER_VOLUME, 0x0000, DEV_AUDIO);
//Set the record gain value. The ADC is 20-bit but AC97 PCDR register is only 16-bit.
//Setting to 0x0F0F might cause clipping.
SafeWriteCodec(RECORD_GAIN, 0x0808, DEV_AUDIO);
//Enable microphone Boost, but keep the line from mic to speakers muted.
SafeWriteCodec(MIC_VOLUME, 0x0040, DEV_AUDIO);
#endif
break;
case 0x10ec1000: //ALC5610
case 0x10ec2000: //ALC5620
case 0x10ec2100: //ALC5621
case 0x10ec2200: //ALC5622
case 0x10ec2300: //ALC5623
m_RTCodec->ChangeCodecPowerStatus(POWER_STATE_D1);
OSTDelayMilliSecTime(20);
m_RTCodec->InitRTCodecReg();
break;
default: //vanilla AC97
SafeWriteCodec(PCM_OUT_VOL, 0x1f1f, DEV_AUDIO);
DEBUGMSG(ZONE_VERBOSE, (TEXT( "-- vanilla AC97 \r\n") ) );
break;
}
return;
}
void HardwareContext::DeInitCodec(void)
{
DEBUGMSG(ZONE_INIT, (TEXT("HardwareContext::DeInitCodec\r\n")));
// Power down Codec
// SafeWriteCodec(XLLP_AC97_CR_POWERDOWN_CTRL_STAT, 0x1000, DEV_AUDIO);
return;
}
void HardwareContext::PowerDown()
{
m_Sleeping=TRUE;
DEBUGMSG(ZONE_FUNCTION | ZONE_VERBOSE, (TEXT("WaveDev2: PowerDown\r\n")));
m_RTCodec->ChangeCodecPowerStatus(POWER_STATE_D3);
m_OutputDMARunning=FALSE;
m_InputDMARunning=FALSE;
#if USE_I2S_INTERFACE
//Power down IIs link
UnConfigureI2SControl();
#else
// Power down AC97 link
UnConfigureAC97Control();
#endif
} // PowerDown()
void HardwareContext::PowerUp()
{
//Basic Outline:
// configue the GPIO registers
// Set hardcoded values like variable rate audio
// Set the BCR values (for sandgate)
// set volume
// set record select
// set EQ values (bass, treble, and mode
// Clear Audio Mute (output & input)
m_vpBLReg->misc_wr2 &= ~(0x1 << 2); // switch on the amplifier
#if USE_I2S_INTERFACE
// Initialize GPIO and enable IIS link
ConfigureI2SControl();
#else
// Initialize GPIO and power up AC97 link
ConfigureAC97Control();
#endif
// Clear DMA status
ClearDmac(m_RecordingChannel);
ClearDmac(m_PlaybackChannel);
InterruptDone(m_SysIntrAudioDMA);
if (TRUE == m_InPowerHandler)
{
m_Sleeping=FALSE;
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("Wavedev:HardwareContext::PowerUp: Done\r\n")));
}
// Control the hardware speaker enable
void HardwareContext::SetSpeakerEnable(BOOL bEnable)
{
// Code to turn speaker on/off here
return;
}
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// RecalcSpeakerEnable decides whether to enable the speaker or not.
// For now, it only looks at the m_bForceSpeaker variable, but it could
// also look at whether the headset is plugged in
// and/or whether we're in a voice call. Some mechanism would
// need to be implemented to inform the wave driver of changes in the state of
// these variables however.
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
void HardwareContext::RecalcSpeakerEnable()
{
SetSpeakerEnable(m_NumForcedSpeaker);
}
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// SetForceSpeaker is called from the device context to update the state of the
// m_bForceSpeaker variable.
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
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)
{
RecalcSpeakerEnable();
}
}
else
{
m_NumForcedSpeaker--;
if (m_NumForcedSpeaker==0)
{
RecalcSpeakerEnable();
}
}
return MMSYSERR_NOERROR;
}
short int HardwareContext::MsgWriteCodec(DWORD dwParam1,DWORD dwParam2)
{
DEBUGMSG(ZONE_VERBOSE, (TEXT( "write %x %x \r\n" ),dwParam1,dwParam2));
SafeWriteCodec((BYTE)dwParam1,(unsigned short int)dwParam2, DEV_AUDIO );
return (MMSYSERR_NOERROR);
}
short int HardwareContext::MsgReadCodec(DWORD dwParam1,DWORD dwParam2)
{
unsigned short int MyData=0;
DEBUGMSG(ZONE_VERBOSE, (TEXT( "read %x %x \r\n" ),dwParam1,MyData ));
SafeReadCodec((BYTE)dwParam1, &MyData, DEV_AUDIO);
if (dwParam2 != (unsigned short int) NULL)
* (unsigned short int *) dwParam2 = MyData;
return (MMSYSERR_NOERROR);
}
/*
#define RIL_AUDIO_NONE (0x00000000) // @constdefine No audio devices
#define RIL_AUDIO_HANDSET (0x00000001) // @constdefine Handset
#define RIL_AUDIO_SPEAKERPHONE (0x00000002) // @constdefine Speakerphone
#define RIL_AUDIO_HEADSET (0x00000003) // @constdefine Headset
#define RIL_AUDIO_CARKIT (0x00000004) // @constdefine Carkit
*/
BOOL HardwareContext::SetCfgHeadSet()
{
return TRUE;
}
BOOL HardwareContext::SetCfgHandSet()
{
return TRUE;
}
BOOL HardwareContext::SetCfgSpeakerPhone()
{
return TRUE;
}
BOOL HardwareContext::SetCfgCarKit()
{
return TRUE;
}
BOOL HardwareContext::SetCfgNone()
{
return TRUE;
}
//------------------------------------------------------------------------------------------------------------
// Function: MapDMADescriptors
//
// Purpose: Map the physical DMA Descriptors into virtual space
//
// Returns: TRUE indicates success. FALSE indicates failure
//
//-------------------------------------------------------------------------------------------------------------
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 = (DMADescriptorChannelType *) HalAllocateCommonBuffer(&Adapter, 0x20, &PA, FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -