?? hwctxt.cpp
字號:
m_vpAudioRcvA-> dcmd = CmdBuff.DcmdDword ; // size and cmd values of the RcvA buffer
//
// fill RcvB Descriptor
//
m_vpAudioRcvB-> ddadr= (UINT32)m_vpAudioRcvA_Physical ; // address of the next (RcvA) descriptor
m_vpAudioRcvB-> dtadr= (UINT32)(m_Input_pbDMA_PAGES_Physical[1]); // source address of the AC97 RcvB buffer
m_vpAudioRcvB-> dsadr= DMAC_AC97_AUDIO_RCV_FIFO; // destination address of the RcvB buffer
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 = XLLP_AC97_U14_DR_8000;
break;
case 11025:
value = XLLP_AC97_U14_DR_11025;
break;
case 16000:
value = XLLP_AC97_U14_DR_16000;
break;
case 22050:
value = XLLP_AC97_U14_DR_22050;
break;
case 32000:
value = XLLP_AC97_U14_DR_32000;
break;
case 44100:
value = XLLP_AC97_U14_DR_44100;
break;
case 48000:
value = XLLP_AC97_U14_DR_48000;
break;
default:
DEBUGCHK(0); //we sent a bad rate
RetVal=FALSE;
return (RetVal);
}
if (apidir == WAPI_IN)
RetVal=SafeWriteAC97((XLLP_UINT16_T)AUDIO_ADC_RATE,value , DEV_AUDIO); //set the input sample rate
else
RetVal=SafeWriteAC97((XLLP_UINT16_T)AUDIO_DAC_RATE,value , DEV_AUDIO); //set the output sample rate
return (RetVal);
}
void HardwareContext::DumpDmacRegs()
{
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 ) );
}
}
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)
{
SafeReadAC97(VENDOR_ID1, &VidTemp, DEV_AUDIO);
VendorId= (VidTemp <<16); //ffffffffssssssss // f=first ascii s = second ascii
SafeReadAC97(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
SafeWriteAC97(FEATURE_CSR2, PWR_SMART_CODEC, DEV_AUDIO);
//
//CAREFULL, writing the FEATURE_CSR1 could mess up the touch screen
//
SafeReadAC97(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;
SafeReadAC97(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.
SafeReadAC97(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
SafeWriteAC97(FEATURE_CSR1, FeatureCrs1Data, DEV_AUDIO);
//Force VRA (variable rate audio) to be on
SafeWriteAC97(EXTENDED_AUDIO_CTRL, VRA_ENABLED_MASK, DEV_AUDIO);
//Default is AUDIO_MIC_INPUT_MONO
SafeWriteAC97(RECORD_SELECT, 0, DEV_AUDIO);
//Set the output volume from the OS
SafeWriteAC97(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.
SafeWriteAC97(RECORD_GAIN, 0x0808, DEV_AUDIO);
//Enable microphone Boost, but keep the line from mic to speakers muted.
SafeWriteAC97(MIC_VOLUME, 0x0040, DEV_AUDIO);
break;
default: //vanilla AC97
SafeWriteAC97(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
// SafeWriteAC97(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")));
// Power down AC97 link
UnConfigureAC97Control();
} // 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
// Initialize GPIO and power up AC97 link
ConfigureAC97Control();
// 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::MsgWriteAC97(DWORD dwParam1,DWORD dwParam2)
{
DEBUGMSG(ZONE_VERBOSE, (TEXT( "write %x %x \r\n" ),dwParam1,dwParam2));
SafeWriteAC97((BYTE)dwParam1,(unsigned short int)dwParam2, DEV_AUDIO );
return (MMSYSERR_NOERROR);
}
short int HardwareContext::MsgReadAC97(DWORD dwParam1,DWORD dwParam2)
{
unsigned short int MyData=0;
DEBUGMSG(ZONE_VERBOSE, (TEXT( "read %x %x \r\n" ),dwParam1,MyData ));
SafeReadAC97((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
//
//-------------------------------------------------------------------------------------------------------------
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -