📄 wavepdd.c
字号:
)
{
//
// Handle any power up/down issues here.
//
g_fInPowerHandler = TRUE;
//
// Reset to initial state of SoundCSR inside ASIC, clearing all interrupts.
// Speaker and CODEC are powered down.
if (!power_down)
{
g_pfnReadAc97 = ReadAC97Raw;
g_pfnWriteAc97 = WriteAC97Raw;
AudioPowerOn();
g_pfnReadAc97 = ReadAC97;
g_pfnWriteAc97 = WriteAC97;
}
else
{
g_pfnReadAc97 = ReadAC97Raw;
g_pfnWriteAc97 = WriteAC97Raw;
AudioPowerOff();
}
g_fInPowerHandler = FALSE;
}
//------------------------------------------------------------------------------------------------------------
// Function: AudioPowerOn
//
// Purpose: Routine for powering on Audio hardware. Do *all* register initializations (gpio, SSP, clocks, etc)
// but, do not init DMA.
//
// Warning: This may be called from within power handler, so should not make any system calls.
//
// Note:
//-------------------------------------------------------------------------------------------------------------
BOOL
AudioPowerOn()
{
//Basic Outline:
// configue the GPIO registers
// Set hardcoded values like variable rate audio
// Set the BCR values (for sandgate)
// Restore the state of the AC97 shadow registers from the WINCE registry
// if no registry values are found, then set the shadow registers to known defaults
// set key register values to the values from the shadow registers
// set volume
// set record select
// set EQ values (bass, treble, and mode
// Clear Audio Mute (output & input)
static int FirstTime=TRUE;
unsigned short int Ac97RegisterData=0;
unsigned short int FeatureCrs1Data=0;
static DWORD VendorId=0;
unsigned short int VidTemp=0;
DEBUGMSG(ZONE_VERBOSE, (TEXT( "+Audio PowerOn\r\n" )) );
if (!FirstTime)
{
ConfigureAC97Control();
}
//Force VRA (variable rate audio) to be on
if( !ShadowWriteAC97( EXTENDED_AUDIO_CTRL, VRA_ENABLED_MASK , DEV_AUDIO) ) // Enable Variable Rate Audio
DEBUGMSG(ZONE_ERROR, (TEXT( "-- Bad VRA Value \r\n") ) );
if( !ShadowWriteAC97( RECORD_SELECT, 0x0, DEV_AUDIO ) ) // default is AUDIO_MIC_INPUT_MONO
DEBUGMSG(ZONE_ERROR, (TEXT( "-- Bad RECORD_SELECT \r\n") ) );
//Set the output volume from the OS
AC97_SetVolume(v_nVolume); // this will write to the shadow register
//Set the record gain value
if( !ShadowWriteAC97( RECORD_GAIN, 0x0f0f, DEV_AUDIO ) ) //set to a well working value
DEBUGMSG(3, (TEXT( "-- Bad RECORD_GAIN \r\n") ) );
//Set the record gain value
if( !ShadowWriteAC97( FEATURE_CSR1, 0x5400, DEV_AUDIO ) ) //set bass & treble to a good sounding value
DEBUGMSG(3, (TEXT( "-- Bad FEATURE_CSR1 \r\n") ) );
//
//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)
//
ShadowReadAC97(VENDOR_ID1, &VidTemp, DEV_AUDIO); //ucb1400 doesn't use an ascii (that I can tell)
VendorId= (VidTemp <<16); //ffffffffssssssss // f=first ascii s = second ascii
ShadowReadAC97(VENDOR_ID2, &VidTemp, DEV_AUDIO);
VendorId |=VidTemp; //ttttttttrrrrrrrr //t = third ascii, r=rev #
VendorId &= 0xfffffff0;//trim of version number
//vendor specific
switch (VendorId)
{
case 0x50534300: //philips UCB1400
ShadowWriteAC97( FEATURE_CSR2, PWR_SMART_CODEC, DEV_AUDIO ); //enable smart mode
g_pfnReadAc97(RESET, (unsigned short *) &ResetCaps, DEV_TOUCH); // if it returns 0x2a it's rev 1b, if 0x2a0 it 2a
//
//CAREFULL, writing the FEATURE_CSR1 could mess up the touch screen
//
ShadowReadAC97( FEATURE_CSR1,&Ac97RegisterData,DEV_AUDIO); //get the audio shadow value
Ac97RegisterData = Ac97RegisterData & EQ_MASK; //get just EQ data
ShadowReadAC97( FEATURE_CSR1,&FeatureCrs1Data,DEV_AUDIO); //get the real codec register value
//mask off eq data
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
if (ResetCaps==REV_2A)
{
FeatureCrs1Data = FeatureCrs1Data | (unsigned short) HPEN_MASK; //turn on head phone
CodecType=UCB14002A;
}
else
CodecType=UCB14001B;
if( !ShadowWriteAC97( FEATURE_CSR1, FeatureCrs1Data, DEV_AUDIO ) ) //write out the result
DEBUGMSG(3, (TEXT( "-- Bad FEATURE_CRS1 \r\n") ) );
break;
default: //vanilla AC97
ShadowWriteAC97( PCM_OUT_VOL, 0x1f1f, DEV_AUDIO ); //AC97 set the PCM out value (not used on ucb1400)
break;
}
if (FirstTime)
FirstTime=FALSE;
AC97SetSampleRate(LastSampleRateOut,WAPI_OUT);
AC97SetSampleRate(LastSampleRateIn,WAPI_IN);
return (TRUE);
}
//------------------------------------------------------------------------------------------------------------
// Function: AudioPowerOff
//
// Purpose: Routine for powering down Audio hardware.
//-------------------------------------------------------------------------------------------------------------
VOID
AudioPowerOff()
{
//This may be called from within powerhandler, so should not make any system calls.
//Basic Outline
// Save the AC97 shadow register to the registry (not implemented)
// Mute record and playback to prevent problems.
// Set the BCR register values
// unconfigure the GPIO's
private_WaveOutStop();
AudioOutMute(TRUE);
AudioInMute(TRUE);
if (!UnConfigureAC97Control())
{
DEBUGCHK(0);
}
}
//------------------------------------------------------------------------------------------------------------
// Function: PDD_AudioMessage
//
// Purpose: Handle any custom WAVEIN or WAVEOUT messages
//
// Returns: DWORD -- Error Return from the function
//
//-------------------------------------------------------------------------------------------------------------
DWORD
PDD_AudioMessage(
UINT uMsg,
DWORD dwParam1,
DWORD dwParam2
)
{
unsigned short int MyData=0;
switch (uMsg)
{
/*
Disabled - these pose a security risk.
case WPDM_PRIVATE_WRITE_AC97:
if (!ShadowWriteAC97( (BYTE) dwParam1,(unsigned short int)dwParam2 , DEV_AUDIO ))
return(MMSYSERR_ERROR);
DEBUGMSG(ZONE_ERROR, (TEXT( "write %x %x \r\n" ),dwParam1,dwParam2 ) );
return (MMSYSERR_NOERROR);
break;
case WPDM_PRIVATE_READ_AC97:
if (!ShadowReadAC97( (BYTE) dwParam1, &MyData , DEV_AUDIO ))
return(MMSYSERR_ERROR);
DEBUGMSG(ZONE_ERROR, (TEXT( "read %x %x \r\n" ),dwParam1,MyData ));
if (dwParam2 != (unsigned short int) NULL)
* (unsigned short int *) dwParam2 = MyData;
return (MMSYSERR_NOERROR);
break;
*/
case WPDM_PRIVATE_DIAG_MSG:
switch (dwParam1)
{
case 0: // unused
return (MMSYSERR_NOERROR);
case 1: // reset the codec
ColdResetAC97Control();
AudioPowerOff();
AudioPowerOn();
return (MMSYSERR_NOERROR);
break;
default:
return (MMSYSERR_NOTSUPPORTED);
}
break;
}
return(MMSYSERR_NOTSUPPORTED);
}
//------------------------------------------------------------------------------------------------------------
// Function: PDD_AudioDeinitialize
//
// Purpose: This function turns off and disconnects the audio device
//-------------------------------------------------------------------------------------------------------------
VOID
PDD_AudioDeinitialize(
VOID
)
{
// Disable DMA input.
//
StopDmac(gInputSrc);
// Disable DMA output.
//
StopDmac(DMA_CH_OUT);
// Disable/clear DMA IN interrupts.
//
v_pDMARegs->dcsr[gInputSrc] &= ~DCSR_STOPIRQEN;
// Disable/clear DMA OUT interrupts.
//
v_pDMARegs->dcsr[DMA_CH_OUT] &= ~DCSR_STOPIRQEN;
// Power-off the audio controller.
//
AudioPowerOff();
// De-allocate the AClink.
//
DeInitializeACLink(g_fInPowerHandler, DEV_AUDIO);
// Free memory and mapped registers.
//
PddpAudioDeallocateVm();
}
//------------------------------------------------------------------------------------------------------------
// Function: GetMuteState
//
// Purpose: Get the Mute State from the Codec Shadow Register
//
// Returns: True if MUTE, false if no mute
//
//-------------------------------------------------------------------------------------------------------------
BOOL
IsMuted(BYTE Offset)
{
unsigned short int Ac97Data=0;
ShadowReadAC97(Offset,&Ac97Data,DEV_AUDIO); //read the current hardware volume
if (Ac97Data & MUTE_MASK)
return (TRUE);
else
return (FALSE);
}
//------------------------------------------------------------------------------------------------------------
// Function: AudioOutMute
//
// Purpose: Quick Mute the hardware with out effecting the stored volume value
//
// Returns: TRUE indicates success. FALSE indicates failure
//
//-------------------------------------------------------------------------------------------------------------
BOOL
AudioOutMute(
BOOL mute
)
{
BOOL retval = FALSE;
unsigned short int Ac97Data=0;
ShadowReadAC97(MASTER_VOLUME,&Ac97Data,DEV_AUDIO); //read the current hardware volume
if( mute )
{
Ac97Data=Ac97Data | MUTE_MASK; //set the mute bit
}
else
Ac97Data=Ac97Data & ~ MUTE_MASK; //clear the mute bit
return( ShadowWriteAC97(MASTER_VOLUME, Ac97Data, DEV_AUDIO) );
}
//------------------------------------------------------------------------------------------------------------
// Function: AudioInMute
//
// Purpose: Quick Mute the hardware input with out effecting the gain
//
// Returns: TRUE indicates success. FALSE indicates failure
//
//-------------------------------------------------------------------------------------------------------------
BOOL
AudioInMute(
BOOL mute
)
{
BOOL retval = FALSE;
unsigned short int Ac97Data=0;
ShadowReadAC97(RECORD_GAIN,&Ac97Data, DEV_AUDIO); //read the current hardware volume
if( mute )
{
Ac97Data=Ac97Data | MUTE_MASK; //set the mute bit
}
else
Ac97Data=Ac97Data & ~ MUTE_MASK; //clear the mute bit
return( ShadowWriteAC97(RECORD_GAIN, Ac97Data, DEV_AUDIO) );
}
//------------------------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -