?? hac.c
字號:
//
// Copyright(C) Renesas Technology Corp. 1999-2005. All rights reserved.
//
// WaveDev Driver for ITS-DS7
//
//----------------------------------------------------------------------------
//
// FILE : HAC.C
// CREATED : 1999.04.26 (for HD64465 on PFM-DS6)
// MODIFIED : 2005.04.26
// AUTHOR : Renesas Technology Corp.
// HARDWARE : RENESAS ITS-DS7
// FUNCTION : MDD-PDD interface layer of waveform audio driver
// HISTORY :
// 2003.06.20
// - Created release code.
// (based on WaveDev driver for ITS-DS6 Ver.2.2.0 for WCE4.1)
// 2004.09.01
// - Created release codefor WCE5.0.
// 2005.02.25
// - Supported both left and right volume control.
// - Added private_SetDefaultVolume.
// - Moved UpdateInputSelect and private_SetMixerValue are moved from WAVEPDD.C.
// - Removed software volume control.
// 2005.03.04
// - Modified PCM data size from 20bit to 16bit Packed TX DMA.
// - Modified transfer processing of a audio buffer.
// - Moved private_AudioFillBuffer is moved from WaveOutpdd.c.
// - Moved private_WaveInContinue is moved from WaveInpdd.c.
// - Removed conv_sample,set_DMA_Buffer,get_DMA_Buffer.
// 2005.04.26
// - Modified PCM data size from 20bit to 16bit Packed RX DMA.
// Functions:
// get_CODEC_SAMPLING_RATE
// get_DMA_Buffer_Address
// get_DPTR
// get_DSAR
// get_DDAR
// get_DTCR
// module_init
// module_deinit
// codec_init
// module_txdmastart
// module_txstop
// module_rxdmastart
// module_rxstop
// module_txstart
// module_rxstart
// Wait_CSAR
// Wait_CSDR
// Wait_AddrRdy
// Wait_DataRdy
// Wait_Status
// Write_codec
// private_ChangeSampleRate
// private_ChangeRecSampleRate
// AudioFillBuffer_M8
// AudioFillBuffer_S8
// AudioFillBuffer_M16
// AudioFillBuffer_S16
// private_AudioFillBuffer
// AudioGetBuffer_M8
// AudioGetBuffer_S8
// AudioGetBuffer_M16
// AudioGetBuffer_S16
// private_WaveInContinue
// set_volume
// SetMute
// check_SamplesPerSec
// set_aud_index
// check_PlayInRec
// check_RecInPlay
// codec_updateRecordSelect
// codec_updateRecordGain
// UpdateInputSelect
// private_SetMixerValue
// private_SetDefaultVolume
#ifndef AC97_USE_MIC
#define AC97_USE_MIC 1
#endif
#ifndef AC97_USE_LINE_IN
#define AC97_USE_LINE_IN 0
#endif
#include <windows.h>
#include <types.h>
#include <memory.h>
#include <excpt.h>
#include <waveddsi.h>
#include <wavedbg.h>
#include <mmsystem.h>
#include <winbase.h>
#include "..\common\wavepdd.h"
#include "shx.h"
#include "sh7770.h"
#include "platform.h"
#include "drv_glob.h"
#include "oalintr.h"
#include "hac.h"
#define DUMPEXCEPTION() \
DEBUGMSG(ZONE_ERROR,(TEXT("Exception %d @ %s:%d\r\n"), GetExceptionCode(), __FILE__, __LINE__ ))
extern PWAVEFORMATEX g_pwfx[2];
extern PCM_TYPE g_pcmtype[2];
extern PDRIVER_GLOBALS pDriverGlobals; // Drivers Globals
extern DWORD AUDIO_NO; // Audio Driver No.
extern PBYTE pAudioBufferBase; // Audio buffer
extern PBYTE pRecAudioBufferBase; // Audio buffer
extern ULONG v_nNextPage;
extern ULONG v_recPage;
extern ULONG dma_pagePhysicalAddress[2];
extern ULONG dma_pageRecPhysicalAddress[2];
extern LPWAVEFORMATEX lpFormat2;
extern VOID private_waveOutSetVolume(ULONG volumeSetting);
extern VOID conv_sample(PCM_TYPE, ULONG *, ULONG *);
extern VOID set_DMA_Buffer( LONG,ULONG,ULONG,ULONG *,unsigned int,int,int *);
extern struct _global_volume
{
ULONG dwMasterVolume;
ULONG dwLineInVolume;
ULONG dwMicVolume;
BOOL fMasterMute;
BOOL fLineInMute;
BOOL fMicMute;
ULONG dwInputSelect;
} g_VolumeSettings;
#define AC97_RETRTY_MAX 20
/*****************************************************************************
* FUNCTION : get_CODEC_SAMPLING_RATE
* DESCRIPTION : Get CODEC SAMPLING RATE
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
ULONG
get_CODEC_SAMPLING_RATE(
int ch
)
{
if( ch == 0 ){
return (ulCurrentPlaySamplingRate >> 4);
}
else{
return (ulCurrentRecSamplingRate >> 4);
}
}
/*****************************************************************************
* FUNCTION : get_DMA_Buffer_Address
* DESCRIPTION : Get DMA Bufffer Address
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
get_DMA_Buffer_Address(
int ch,
DWORD n,
ULONG *adr
)
{
// Playback
if( ch == 0 ){
*(adr + 0) = AUDIO_P_BUFFER_BASE + (AUDIO_DMA_PAGE_SIZE * 2) * n;
*(adr + 1) = AUDIO_P_BUFFER_BASE + (AUDIO_DMA_PAGE_SIZE * 2) * n + AUDIO_DMA_PAGE_SIZE;
}
// Recording
else{
*(adr + 0) = AUDIO_R_BUFFER_BASE + (AUDIO_DMA_PAGE_SIZE * 2) * n;
*(adr + 1) = AUDIO_R_BUFFER_BASE + (AUDIO_DMA_PAGE_SIZE * 2) * n + AUDIO_DMA_PAGE_SIZE;
}
}
/*****************************************************************************
* FUNCTION : get_DPTR
* DESCRIPTION : Get DMA DPTR Register Setting
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
DWORD
get_DPTR(
int ch
)
{
DWORD ret = DPTR_MASK;
if( ch == 0 ){
ret = DPTR_DDPT_HAC;
}
else if( ch == 1 ){
ret = DPTR_SDPT_HAC;
}
return ret;
}
/*****************************************************************************
* FUNCTION : get_DSAR
* DESCRIPTION : Get DMA DSAR Register Setting
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
DWORD
get_DSAR(
int ch,
DWORD n,
int page
)
{
DWORD ret;
// DMA Ch = HAC (for playing)
if( ch == 0 ){
ret = AUDIO_P_BUFFER_BASE + (AUDIO_DMA_PAGE_SIZE * 2) * n + (AUDIO_DMA_PAGE_SIZE * page);
}
// DMA Ch = HAC (for recording)
else if( ch == 1 ){
ret = HAC_REGBASE + HAC_PCML_OFFSET;
}
return ret;
}
/*****************************************************************************
* FUNCTION : get_DDAR
* DESCRIPTION : Get DMA DDAR Register Setting
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
DWORD
get_DDAR(
int ch,
DWORD n,
int page
)
{
DWORD ret;
// DMA Ch = HAC (for playing)
if( ch == 0 ){
ret = HAC_REGBASE + HAC_PCML_OFFSET;
}
// DMA Ch = HAC (for recording)
else if( ch == 1 ){
ret = AUDIO_R_BUFFER_BASE + (AUDIO_DMA_PAGE_SIZE * 2) * n + (AUDIO_DMA_PAGE_SIZE * page);
}
return ret;
}
/*****************************************************************************
* FUNCTION : get_DTCR
* DESCRIPTION : Get DMA DTCR Register Setting
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
DWORD
get_DTCR(
int ch,
DWORD n,
int page
)
{
// DMA Ch = HAC (for recording)
if( ch == 1 ){
return HAC_R_DMA_PAGE_SIZE / sizeof(ULONG);
}
return AUDIO_DMA_PAGE_SIZE / sizeof(ULONG);
}
/*****************************************************************************
* FUNCTION : module_init
* DESCRIPTION : HAC Initialize
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
BOOL
module_init(
PDRIVER_GLOBALS globals,
int i
)
{
BOOL ret = TRUE;
pHAC_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
(PBYTE)HAC_REGBASE,
(DWORD)HAC_REGSIZE,
"PDD_AudioInitialize, pHAC_RegBase");
if (pHAC_RegBase == NULL) {
DEBUGMSG(ZONE_ERROR,(TEXT("Get HAC virtual memory failure !\r\n")));
return FALSE;
}
pHAC_CR = (PVULONG) (pHAC_RegBase + HAC_CR_OFFSET );
pHAC_CSAR = (PVULONG) (pHAC_RegBase + HAC_CSAR_OFFSET );
pHAC_CSDR = (PVULONG) (pHAC_RegBase + HAC_CSDR_OFFSET );
pHAC_PCML = (PVULONG) (pHAC_RegBase + HAC_PCML_OFFSET );
pHAC_PCMR = (PVULONG) (pHAC_RegBase + HAC_PCMR_OFFSET );
pHAC_TIER = (PVULONG) (pHAC_RegBase + HAC_TIER_OFFSET );
pHAC_TSR = (PVULONG) (pHAC_RegBase + HAC_TSR_OFFSET );
pHAC_RSR = (PVULONG) (pHAC_RegBase + HAC_RSR_OFFSET );
pHAC_ACR = (PVULONG) (pHAC_RegBase + HAC_ACR_OFFSET );
DEBUGMSG(ZONE_TEST, (TEXT("HAC_CR =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_CR )));
DEBUGMSG(ZONE_TEST, (TEXT("HAC_CSAR =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_CSAR )));
DEBUGMSG(ZONE_TEST, (TEXT("HAC_CSDR =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_CSDR )));
DEBUGMSG(ZONE_TEST, (TEXT("HAC_PCML =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_PCML )));
DEBUGMSG(ZONE_TEST, (TEXT("HAC_PCMR =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_PCMR )));
DEBUGMSG(ZONE_TEST, (TEXT("HAC_TIER =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_TIER )));
DEBUGMSG(ZONE_TEST, (TEXT("HAC_TSR =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_TSR )));
DEBUGMSG(ZONE_TEST, (TEXT("HAC_RSR =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_RSR )));
DEBUGMSG(ZONE_TEST, (TEXT("HAC_ACR =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_ACR )));
return ret;
}
/*****************************************************************************
* FUNCTION : module_deinit
* DESCRIPTION : HAC Deinitialize
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
module_deinit(
VOID
)
{
VirtualFree((PVOID)pHAC_RegBase, 0, MEM_RELEASE);
pHAC_RegBase = NULL;
}
/*****************************************************************************
* FUNCTION : codec_init
* DESCRIPTION : CODEC Initialize
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
BOOL
codec_init(
VOID
)
{
ULONG CR_VALUE;
ULONG CSDR_VALUE;
ULONG REG_VALUE;
ULONG Loop_n;
ULONG Loop_r;
Loop_r = 0;
reset_codec:
Loop_r++;
//Reset AC97
WRITE_REGISTER_ULONG((PULONG)pHAC_CR, (ULONG)HAC_CR_RESERVE ); // Set 0 before Reset
WRITE_REGISTER_ULONG((PULONG)pHAC_CR, (ULONG)(HAC_CR_CDRT|HAC_CR_RESERVE)); // Cold Reset for AC97
BusyWait(AdjustMicroSecondsToLoopCount( 100000 )); // wait 100ms
WRITE_REGISTER_ULONG((PULONG)pHAC_CR, (ULONG)(HAC_CR_ST|HAC_CR_RESERVE));
//Init_Codec
//AC_Init
REG_VALUE = HAC_ACR_TX12_ATOMIC | HAC_ACR_RESERVE;
WRITE_REGISTER_ULONG((PULONG)pHAC_ACR, (ULONG)REG_VALUE ); // slot1,2 ATOMIC = 1
//Codec Ready?
DEBUGMSG(ZONE_TEST, (TEXT("HAC_CR0 =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_CR )));
DEBUGMSG(ZONE_TEST, (TEXT("WAIT Codec Ready\r\n")));
Loop_n = 0;
CR_VALUE = (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_CR );
while(!( CR_VALUE & HAC_CR_CR )) { // Codec ready ?
BusyWait(AdjustMicroSecondsToLoopCount( 1000 )); // wait 1ms
Loop_n++;
if(Loop_n > 500){
DEBUGMSG(ZONE_ERROR, (TEXT("Error! Audio CODEC not ready! \r\n")));
goto error_ret4;
}
CR_VALUE = (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_CR );
}
DEBUGMSG(ZONE_INIT, (TEXT("codec ready!! \r\n")));
DEBUGMSG(ZONE_TEST, (TEXT("Loop no = %08x\r\n"), (ULONG)Loop_n));
//RX TX Valid Slot
DEBUGMSG(ZONE_TEST, (TEXT("WAIT ADC DAC ANL Ready?\r\n")));
Loop_n = 0;
if ( Wait_Status((ULONG)0x00026000) == FALSE ) goto error_ret4; // Read Power-Down Control/Status (Index 26h)
CSDR_VALUE = (ULONG)READ_REGISTER_ULONG((PULONG)pHAC_CSDR);
while( ( CSDR_VALUE & 0x000000f0 ) != 0x000000f0) {
BusyWait(AdjustMicroSecondsToLoopCount( 1000 )); // wait 1ms
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -