📄 hwctxt_8_1.cpp
字号:
v_pAC97regs->AC_GLBCTRL = (1<<2);
Delay(10); //Sleep(5);
//Transfer data enable using AC-link
v_pAC97regs->AC_GLBCTRL = v_pAC97regs->AC_GLBCTRL | (1<<3);
Delay(10); //Sleep(5);
// Disable the Codec ready Interrupt Ajay
v_pAC97regs->AC_GLBCTRL = v_pAC97regs->AC_GLBCTRL | (1<<22);
Delay(10); //Sleep(5);
//while (!(v_pAC97regs->AC_GLBSTAT& 0x400000));
RETAILMSG(AC97_DEBUG,(_T("WAVEDEV_AC97::AC97 Codec Ready!\r\n")));
v_pAC97regs->AC_GLBCTRL &= ~(0x400000); // codec ready interrupt disable
Delay(10); //Sleep(5);
#if AC97_RECORD_MICIN
v_pAC97regs->AC_GLBCTRL = (v_pAC97regs->AC_GLBCTRL & ~(0x3f<<8)) | 0x2200; // PCM_OUT=DMA,PCM_IN=OFF,MIC=DMA;
#else
v_pAC97regs->AC_GLBCTRL = (v_pAC97regs->AC_GLBCTRL & ~(0x3f<<10)) | 0x2800; // PCM_OUT=DMA,PCM_IN=DMA,MIC=OFF;
#endif
RETAILMSG(AC97_DEBUG,(_T("WAVDEV_AC97::AC97_Init()--\r\n")));
return TRUE;
#endif
}
void ChangeSoundPath(DWORD dwSoundPath)
{
/* switch(dwSoundPath)
{
case SPEAKER:
RETAILMSG(1,(TEXT("ChangeSoundPath:: Sound Path Speaker, GPGDAT=%x \r\n"),v_pIOPregs->GPGDAT));
WriteCodecRegister(AC97_HEADPHONE_VOL, 0x0); // HP out volume 0db
WriteCodecRegister(AC97_OUT34_VOL,0x0); //for OUT3, OUT4 volume control
WriteCodecRegister(AC97_OUTPUT_SELECT,0x920a); //0x5b0a OUT3, OUT4 input source out3:INV1, Out4:INV4, HPL,HPR:unused
WriteCodecRegister(AC97_3D_CONTROL,0x8b00); // // INV1(HeadphoneR)INVV2(HeadPhoneL) low frq cutoff high frq cut off, 3d effect 0%
WriteCodecRegister(AC97_LOUDSPK_VOL,0x0); // Speaker volume on
WriteCodecRegister(AC97_MIC_SELECT, 0x1560); // only MIC2A select
//WriteCodecRegister(AC97_POWER_DOWN1, 0xf933); //all mixer power down except of headphone mixer
//WriteCodecRegister(AC97_POWER_DOWN2, 0xa67f); // speaker
break;
case HEADPHONE:
RETAILMSG(1,(TEXT("ChangeSoundPath:: Sound Path HeadPhone, GPGDAT=%x \r\n"),v_pIOPregs->GPGDAT));
WriteCodecRegister(AC97_OUT34_VOL,0x8080); //for OUT3, OUT4 volume control:mute
WriteCodecRegister(AC97_LOUDSPK_VOL,0x8080); // Speaker volume on
WriteCodecRegister(AC97_HEADPHONE_VOL, 0x0909); // HP out volume -13.5db
WriteCodecRegister(AC97_OUTPUT_SELECT,0x80a0); // OUT3, OUT4 : vmid, Only HPLR mixer selected
WriteCodecRegister(AC97_3D_CONTROL,0x0); // INV1,INV2:Zh low frq cutoff high frq cut off, 3d effect 0%
WriteCodecRegister(AC97_MIC_SELECT, 0x0560); // only MIC1 0x0f7f
//WriteCodecRegister(AC97_POWER_DOWN1, 0xf933); // headphone
//WriteCodecRegister(AC97_POWER_DOWN2, 0xb9ff); // headphone //Out3.4 disable
break;
default:
RETAILMSG(1,(TEXT("ChangeSoundPath:: Sound Path Invalid, GPGDAT=%x \r\n"),v_pIOPregs->GPGDAT));
break;
}*/
}
BOOL HardwareContext::Codec_channel()
{
// Kingfish2 AC97
if( m_InputDMARunning & m_OutputDMARunning )
{
RETAILMSG(AC97_DEBUG1,(_T("Codec_channel() - In & Out\r\n")));
WriteCodecRegister(AC97_POWER_CONTROL, AC97_PWR_D0); // ADC, DAC power up
if(g_SoundPath == SPEAKER)
{
// WriteCodecRegister(AC97_POWER_DOWN1, 0xa90d); // Speaker
// WriteCodecRegister(AC97_POWER_DOWN2, 0xa670); // Speaker
}
else if(g_SoundPath == HEADPHONE)
{
// WriteCodecRegister(AC97_POWER_DOWN1, 0xa903); // HeadPhone
// WriteCodecRegister(AC97_POWER_DOWN2, 0xb9f0); // Headphone
}
}
else if( m_InputDMARunning )
{
RETAILMSG(AC97_DEBUG1,(_T("Codec_channel() - In\r\n")));
WriteCodecRegister(AC97_POWER_CONTROL, AC97_PWR_PR1); // DAC power down
//WriteCodecRegister(AC97_POWER_DOWN1, 0xb9cf);
//WriteCodecRegister(AC97_POWER_DOWN2, 0xbff0);
}
else if( m_OutputDMARunning )
{
RETAILMSG(AC97_DEBUG1,(_T("Codec_channel() - Out\r\n")));
WriteCodecRegister(AC97_POWER_CONTROL, AC97_PWR_PR0); // ADC power down
if(g_SoundPath == SPEAKER)
{
//WriteCodecRegister(AC97_POWER_DOWN1, 0xf933); //all mixer power down except of headphone mixer
//WriteCodecRegister(AC97_POWER_DOWN2, 0xa67f); // speaker
}
else if(g_SoundPath == HEADPHONE)
{
//WriteCodecRegister(AC97_POWER_DOWN1, 0xf933); // headphone
//WriteCodecRegister(AC97_POWER_DOWN2, 0xb9ff); // headphone //Out3.4 disable
}
}
else
{
RETAILMSG(AC97_DEBUG1,(_T("Codec_channel() - none\r\n")));
WriteCodecRegister(AC97_POWER_CONTROL, AC97_PWR_PR1|AC97_PWR_PR0); // ADC/DAC power down
}
return(TRUE);
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function: InitCodec()
Description: Initializes the audio codec chip.
Notes: The audio codec chip is intialized for output mode
but powered down. To conserve battery life, the chip
is only powered up when the user starts playing a
file.
Specifically, the powerup/powerdown logic is done
in the AudioMute() function. If either of the
audio channels are unmuted, then the chip is powered
up; otherwise the chip is powered own.
Returns: Boolean indicating success
-------------------------------------------------------------------*/
#if 1 // 24a0 codec
BOOL HardwareContext::InitCodec()
{
USHORT CodecRead;
ULONG CodecVendorID, CodecRevision;
RETAILMSG(AC97_DEBUG, (TEXT("+++InitCodec\r\n")));
// write the Codec software reset
// 00h
WriteCodecRegister(AC97_RESET, 0x683F);
// Enable the VRA
// 2Ah
WriteCodecRegister(AC97_EXT_AUDIO_CONTROL, AC97_ENABLE_VRA);
WriteCodecRegister(AC97_PCM_DAC_RATE, 44100); // Write default Sample rate for DAC
WriteCodecRegister(AC97_PCM_ADC_RATE, 44100); // Write default Sample rate for DAC
// get the Vendor ID and revision
// 7Ch
CodecVendorID = ULONG(ReadCodecRegister( AC97_VENDOR_ID1 )) << 16;
// 7E
CodecRead = ReadCodecRegister( AC97_VENDOR_ID2 );
CodecVendorID |= ULONG(CodecRead) & 0x0000ff00;
CodecRevision = ULONG(CodecRead) & 0x000000ff;
RETAILMSG(AC97_DEBUG,(_T("Read Value from AC_GLBSTAT Reg. =>0x%x\n"), v_pAC97regs->AC_GLBSTAT));
RETAILMSG(AC97_DEBUG,(_T("Read Value from AC_GLBCTRL Reg. =>0x%x\n"), v_pAC97regs->AC_GLBCTRL));
RETAILMSG(AC97_DEBUG, (TEXT("STAC9766 Codec Vendor ID: %08x \r\n"), CodecVendorID)); //83847600
RETAILMSG(AC97_DEBUG, (TEXT("STAC9766 Codec Revision: %02x\r\n"), CodecRevision)); //66
if ( !( CodecVendorID == AC97_VENDOR_SIGMATEL && CodecRevision == 0x66))
{
// now power down the Analog section of the AC97
// and power it back up. This forces the Sigmatel
// to calibrate it's analog levels
// 26h
WriteCodecRegister(AC97_POWER_CONTROL, AC97_PWR_ANLOFF );
Delay(10); //Sleep(5);
RETAILMSG(AC97_DEBUG,(_T("WriteCodecRegister(AC97_POWER_CONTROL, AC97_PWR_ANLOFF)\r\n")));
}
// Turn Power on for sections
// 26h
WriteCodecRegister( AC97_POWER_CONTROL, AC97_PWR_D0 );
// Write the Analog reg
// 6Eh
//WriteCodecRegister( AC97_ANALOG_SPEC, 0x0000 );
// write HP Out Value
// 04h
WriteCodecRegister( AC97_HEADPHONE_VOL, 0x0404 ); //0x0202); //0x0404 );
// Mute unusing analog source except -------------------------------
// PCBEEP_VOL - 0ah
WriteCodecRegister( AC97_PCBEEP_VOL, 0x8000 );
// PHONE_VOL - 0ch
WriteCodecRegister( AC97_PHONE_VOL, 0x8000 );
// LINEIN_VOL - 10h
WriteCodecRegister( AC97_LINEIN_VOL, 0x8000 );
// CD_VOL - 12h
WriteCodecRegister( AC97_CD_VOL, 0x8000 );
// VIDEO_VOL - 14h
WriteCodecRegister( AC97_VIDEO_VOL, 0x8000 );
// AUX_VOL - 16h
WriteCodecRegister( AC97_AUX_VOL, 0x8000 );
// write the wave out volume
// 18h
WriteCodecRegister( AC97_PCMOUT_VOL, 0x0505 ); //0x0000 ); //0x0606 );
// Init MIC-IN configurations
// 20h
WriteCodecRegister( AC97_GENERAL_PURPOSE, 0x0000 ); //MIC1 Selected
#if AC97_RECORD_MICIN
// ADC Gain Control, 30dB
// BOOSTEN =1
// tmp = ReadCodecRegister(AC97_MIC_VOL) & ~(0x1<<6);
// WriteCodecRegister(AC97_MIC_VOL, tmp | (0x1<<6));
WriteCodecRegister( AC97_MIC_VOL, (1<<15)|(1<<6) ); // Mute & BOOTEN
//ADC Input Slot => left slot6, right slot9, MIC GAIN VAL=1
WriteCodecRegister( AC97_INTR_PAGE, 0x0 );
WriteCodecRegister( AC97_ANALOG_SPEC, 0x0020 );
//Left, Right => MIC
WriteCodecRegister( AC97_RECORD_SELECT, AC97_RECMUX_MIC );
// set up a default record gain
// 1Ch
//WriteCodecRegister( AC97_RECORD_GAIN, AC97_RECORD_GAIN_VAL );
WriteCodecRegister( AC97_RECORD_GAIN, 0x0909 );
#else
WriteCodecRegister( AC97_LINEIN_VOL, 0x8808 ); //For PCM In
//ADC Input Slot => left slot3, right slot4, MIC GAIN VAL=1
WriteCodecRegister( AC97_INTR_PAGE, 0x0 );
//Select Slots for ADC Data on AC Link Left=3 , Right=4
WriteCodecRegister( AC97_ANALOG_SPEC, 0x0000 ); //For PCM IN
//Left, Right => LineIn
WriteCodecRegister( AC97_RECORD_SELECT, AC97_RECMUX_LINE );// for PCM In
// set up a default record gain
// 1Ch
WriteCodecRegister( AC97_RECORD_GAIN, 0x0505 ); //For PCM In
#endif
// Now write High Pass Filter Bypass Control Register
// 78h
WriteCodecRegister( AC97_HPF_BYPASS, AC97_HIPASS_DISABLE );
RETAILMSG(AC97_DEBUG, (TEXT("---InitCodec\r\n")));
return(TRUE);
}
#else
BOOL HardwareContext::InitCodec()
{
// USHORT CodecRead;
// ULONG CodecVendorID, CodecRevision, Output_Volume;
AC97MSG( (TEXT("+++InitCodec\r\n")));
// write the Codec software reset
// 00h
WriteCodecRegister(AC97_RESET, 0x683F); // it should be expected to muting all analog sources.
v_pAC97regs->AC_GLBCTRL |= AC97_ACLINK_ON; //sync enable
Delay(100);
WriteCodecRegister(AC97_POWER_CONTROL, 0x0); // all power on
//WriteCodecRegister(AC97_POWER_CONTROL, (1<<8)); // all power on except ADC blcok
WriteCodecRegister(AC97_POWER_DOWN1,0); //for power management 0xe933 headphone
WriteCodecRegister(AC97_POWER_DOWN2, 0); // enable Mic bias 0xb9ff
// mute all analog mixer input
WriteCodecRegister(AC97_LOUDSPK_VOL, 0x8080); // Speaker volume Muted
WriteCodecRegister(AC97_HEADPHONE_VOL, 0x8080); // Headphone volume Muted
WriteCodecRegister(AC97_OUT34_VOL, 0x8080); // OUT34(receiver) Muted
WriteCodecRegister(AC97_LINEIN_VOL, 0xE808); // (PhoneIN)LineIn to all mixer Muted
WriteCodecRegister(AC97_PCBEEP_VOL, 0xaaa0); // PCBEEP Muted
WriteCodecRegister(AC97_VXDAC_VOL, 0xaaa0); // VxDACMuted
WriteCodecRegister(AC97_AUX_VOL, 0xaaa0); // AUXDAC Muted
WriteCodecRegister(AC97_MONO_VOL, 0xc880); // MonoVol Muted
WriteCodecRegister(AC97_EXT_AUDIO_CONTROL,AC97_ENABLE_VRA); //variable rate enable
WriteCodecRegister(AC97_PCM_DAC_RATE,AC97_PCM_DAC_RATE_44KHZ); //PCM DAC 44.1Khz
WriteCodecRegister(AC97_PCM_ADC_RATE,AC97_PCM_DAC_RATE_44KHZ); //PCM ADC 44.1Khz
WriteCodecRegister(AC97_ADD_FUNC2,0x2); //select ADC slot6/9
WriteCodecRegister(AC97_MIC_SELECT, 0x0f7f); //Only MIC1/MICA(external) +30db, Mic bias en 0.75AVDD
WriteCodecRegister(AC97_DACTONE_CONTROL,0x9213); //DAC Tone control
WriteCodecRegister(AC97_VXDAC_VOL,0xaaa0); //For Voice DAC control for Speaker, speaker mixer no mute and 0db gain
WriteCodecRegister(AC97_DAC_VOL,0x6404); //For DAC control for headphone mixer , speaker and mono mute, +6db
if(v_pIOPregs->GPGDAT & 1<<0)
{
RETAILMSG(1,(TEXT("CodecInit:: Initial Sound Path Speaker, GPGDAT=%x \r\n"),v_pIOPregs->GPGDAT));
g_SoundPath = SPEAKER;
WriteCodecRegister(AC97_HEADPHONE_VOL, 0x0); // HP out volume 0db
WriteCodecRegister(AC97_OUT34_VOL,0x0); //for OUT3, OUT4 volume control
WriteCodecRegister(AC97_OUTPUT_SELECT,0x920a); //0x5b0a OUT3, OUT4 input source out3:INV1, Out4:INV4, HPL,HPR:unused
WriteCodecRegister(AC97_3D_CONTROL,0x8b00); // // INV1(HeadphoneR)INVV2(HeadPhoneL) low frq cutoff high frq cut off, 3d effect 0%
WriteCodecRegister(AC97_LOUDSPK_VOL,0x0); // Speaker volume on
WriteCodecRegister(AC97_MIC_SELECT, 0x1f60); // only MIC2A select
// WriteCodecRegister(AC97_POWER_DOWN1,0xc); //Power down control for Speaker out
// WriteCodecRegister(AC97_POWER_DOWN2,0x6f0);
}
else
{
g_SoundPath = HEADPHONE;
RETAILMSG(1,(TEXT("CodecInit:: Initial Sound Path HeadPhone, GPGDAT=%x \r\n"),v_pIOPregs->GPGDAT));
WriteCodecRegister(AC97_HEADPHONE_VOL, 0x0909); // HP out volume -13.5db
WriteCodecRegister(AC97_OUT34_VOL,0x8080); //for OUT3, OUT4 volume control:mute
WriteCodecRegister(AC97_LOUDSPK_VOL,0x8080); // Speaker volume on
WriteCodecRegister(AC97_OUTPUT_SELECT,0x80a0); // OUT3, OUT4 : vmid, Only HPLR mixer selected
WriteCodecRegister(AC97_3D_CONTROL,0x0); // INV1,INV2:Zh low frq cutoff high frq cut off, 3d effect 0%
WriteCodecRegister(AC97_MIC_SELECT, 0x0f60); // only MIC1 0x0f7f
}
WriteCodecRegister(AC97_MIC_ROUTING, 0x00da); //mute mic to all mixer.
WriteCodecRegister(AC97_REC_ROUTING, 0xd640); //0x0140 0x4347
WriteCodecRegister(AC97_MIC_VOL, 0x0808); // Recording volume max
WriteCodecRegister(AC97_MIC_VOL, 0x0); // MIC volume max
AC97MSG( (TEXT("---InitCodec\r\n")));
WriteCodecRegister(AC97_POWER_CONTROL, AC97_PWR_PR1|AC97_PWR_PR0);
return(TRUE);
}
#endif
MMRESULT HardwareContext::SetOutputGain (DWORD 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.
// Kingfish2. I can't find output gain of CODEC
// WriteCodecRegister( AC97_RECORD_GAIN, AC97_RECORD_GAIN_VAL );
return MMSYSERR_NOERROR;
}
MMRESULT HardwareContext::SetOutputMute (BOOL fMute)
{
m_fOutputMute = fMute;
WriteCodecRegister(0x02, 0x8000); // OUT2 volume Muted. Kingfish2
return MMSYSERR_NOERROR;
}
BOOL HardwareContext::GetOutputMute (void)
{
return m_fOutputMute;
}
DWORD HardwareContext::GetOutputGain (void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -