?? hssi.c
字號:
//
// Copyright(C) Renesas Technology Corp. 1999-2005. All rights reserved.
//
// HSSIWaveDev Driver for ITS-DS7
//
//----------------------------------------------------------------------------
//
// FILE : HSSI.C
// CREATED : 1999.04.26 (for HD64465 on PFM-DS6)
// MODIFIED : 2005.03.08
// 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.06.15
// - Modified HSSI supported full duplex mode.
// 2004.09.01
// - Created release code for WCE5.0.
// 2004.02.25
// - Added wait for idle-state after SSI disabled.
// - Added waitSSIStatus.
// - Supported hardware volume control.
// - Modified CODEC setting processing into a common routine.
// - Removed software volume control.
// - Added private_SetDefaultVolume.
// - Moved UpdateInputSelect and private_SetMixerValue are moved from WAVEPDD.C.
// - Removed codec_updateRecordSelect.
// 2005.03.04
// - Moved private_AudioFillBuffer is moved from WaveOutpdd.c.
// - Moved private_WaveInContinue is moved from WaveInpdd.c.
// 2005.03.08
// - Modified transfer processing of a audio buffer.
// - Removed conv_sample,set_DMA_Buffer,get_DMA_Buffer.
// 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
// 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
// I2C_WriteCODEC
// I2C_ReadCODEC
// I2C_SetCODEC
// hssi2_dmastart
// hssi2_dmastop
// check_PlayInRec
// check_RecInPlay
// MuteSSI
// UpdateInputSelect
// private_SetMixerValue
// codec_updateRecordSelect
// codec_updateRecordGain
// private_SetDefaultVolume
// waitSSIStatus
#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 "ioctl_its_ds7.h"
#include "hssi.h"
#define I2C_STANDARD_SPEED // 100kHz
//#define I2C_WAIT_COUNT 50000 // 50ms
#define I2C_WAIT_COUNT 10000 // 10ms
#define SSI_VOL_SCALE (0x2E) // 0-46dB Attenuator(same HAC)
#define DUMPEXCEPTION() \
DEBUGMSG(ZONE_ERROR,(TEXT("Exception %d @ %s:%d\r\n"), GetExceptionCode(), __FILE__, __LINE__ ))
// SSI Base Address
static PBYTE pSSI0_RegBase; // page-base for register offsets
// SSI Registers
// Playback
static SSIControlRegister SSICR_TX;
static PVULONG pSSI_SR_TX; // SSI Status Register
static PVULONG pSSI_CR_TX; // TX SSI Control Register
static PVULONG pSSI_TDR; // SSI Transmit Data Register
// Recording
static SSIControlRegister SSICR_RX;
static PVULONG pSSI_SR_RX; // SSI Status Register
static PVULONG pSSI_CR_RX; // RX SSI Control Register
static PVULONG pSSI_RDR; // SSI Receive Data Register
static unsigned char ulDSPMode;
static unsigned char ulDACControl;
static unsigned int data_count;
// I2C address
static unsigned char CS4226_ReadADDR;
static unsigned char CS4226_WriteADDR;
// CODEC register
// Clock Mode Byte(01h)
static unsigned char CS4226_PLAY_CMB;
static unsigned char CS4226_REC_CMB;
// DSP Port Mode Byte(0Eh)
static unsigned char CS4226_PLAY_DSP_PMB;
static unsigned char CS4226_REC_DSP_PMB;
// Auxiliary Port Mode Byte(0Fh)
static unsigned char CS4226_PLAY_APMB;
static unsigned char CS4226_REC_APMB;
// DAC Control Byte(03h)
static unsigned char CS4226_PLAY_DACCB;
static unsigned char CS4226_REC_DACCB;
// ADC Control Byte(0Bh)
static unsigned char CS4226_ADCCB;
// SSI Serial Clock Output/Serial WS Output
static unsigned char SSI_PLAY_MODE;
static unsigned char SSI_REC_MODE;
extern PDMA_INFO pDMA_out; // DMA Register (for Playback)
extern PBYTE pAudioBufferBase; // Audio buffer
extern PBYTE pRecAudioBufferBase; // Audio buffer
// OpenFlag
extern int RecOpenFlag;
extern int PlayOpenFlag;
extern struct _global_volume
{
ULONG dwMasterVolume;
ULONG dwLineInVolume;
ULONG dwMicVolume;
BOOL fMasterMute;
BOOL fLineInMute;
BOOL fMicMute;
ULONG dwInputSelect;
} g_VolumeSettings;
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 ULONG v_nNextPage;
extern ULONG v_recPage;
extern ULONG dma_pagePhysicalAddress[2];
extern ULONG dma_pageRecPhysicalAddress[2];
extern LPWAVEFORMATEX lpFormat2;
BOOL I2C_WriteCODEC(HANDLE,unsigned char,unsigned char);
BYTE I2C_ReadCODEC(HANDLE,unsigned char,BOOL);
BOOL I2C_SetCODEC(unsigned char pI2Cdata[][2]);
void hssi2_dmastart();
void hssi2_dmastop();
void MuteSSI(BOOL);
void waitSSIStatus(PVULONG pSSI_SR, ULONG stat);
VOID codec_updateRecordGain( ULONG regval );
extern VOID private_waveOutSetVolume(ULONG volumeSetting);
/*****************************************************************************
* FUNCTION : get_CODEC_SAMPLING_RATE
* DESCRIPTION : Get CODEC SAMPLING RATE
* INPUTS : ch - DMA channel number
* OUTPUTS : Return Sampling Rate
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
ULONG
get_CODEC_SAMPLING_RATE(
int ch
)
{
// mono(SSI0)
if( ch == CH_TX_HSSI_1 ){
// return Hz11025; // for 11.025kHz
return Hz44100; // for 44.1kHz
}
// mono(SSI1)
else if( ch == CH_RX_HSSI_1 ){
// return Hz11025; // for 11.025kHz
return Hz44100; // for 44.1kHz
}
// stereo(SSI2,3)
else{
return Hz44100;
}
}
/*****************************************************************************
* FUNCTION : get_DMA_Buffer_Address
* DESCRIPTION : Get DMA Bufffer Address
* INPUTS : ch - DMA Channel Number
* n - Audio Number
* OUTPUTS : *adr - DMA Transfer Buffer Address
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
get_DMA_Buffer_Address(
int ch,
DWORD n,
ULONG *adr
)
{
// Playback(SSI0,SSI2)
if( ch == CH_TX_HSSI_1 || ch == CH_TX_HSSI_2 ){
*(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(SSI1,SSI3)
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;
}
DEBUGMSG(ZONE_TEST, (TEXT("get_DMA_Buffer_Address(ch:%d audiono:%d) : 0x%08x/%08x\r\n"), ch,n,*(adr + 0),*(adr + 1)));
}
/*****************************************************************************
* FUNCTION : get_DPTR
* DESCRIPTION : Get DMA DPTR Register Setting
* INPUTS : ch - DMA Channel Number
* OUTPUTS : Return DMA Port Number
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
DWORD
get_DPTR(
int ch
)
{
DWORD ret = DPTR_MASK;
// SSI0 Playback(mono)
if( ch == CH_TX_HSSI_1 ){
ret = DPTR_DDPT_HSSI0;
}
// SSI1 Recording(mono)
else if( ch == CH_RX_HSSI_1 ){
ret = DPTR_SDPT_HSSI1;
}
// SSI2 Playback(stereo)
else if( ch == CH_TX_HSSI_2 ){
ret = DPTR_DDPT_HSSI2;
}
// SSI3 Recording(stereo)
else if( ch == CH_RX_HSSI_2 ){
ret = DPTR_SDPT_HSSI3;
}
DEBUGMSG(ZONE_TEST, (TEXT("get_DPTR(ch:%d) : 0x%08x\r\n"), ch, ret));
return ret;
}
/*****************************************************************************
* FUNCTION : get_DSAR
* DESCRIPTION : Get DMA DSAR Register Setting
* INPUTS : ch - DMA Channel Number
* n - Audio Number
* page - Page Number
* OUTPUTS : Return Sorce Address
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
DWORD
get_DSAR(
int ch,
DWORD n,
int page
)
{
DWORD ret;
// DMA Ch = SSI0,SSI2 (for playing)
if( ch == CH_TX_HSSI_1 || ch == CH_TX_HSSI_2 ){
ret = AUDIO_P_BUFFER_BASE + (AUDIO_DMA_PAGE_SIZE * 2) * n + (AUDIO_DMA_PAGE_SIZE * page);
}
// DMA Ch = SSI1 (for recording)
else if( ch == CH_RX_HSSI_1 ){
ret = SSI1_REGBASE + SSI_RDR_OFFSET;
}
// DMA Ch = SSI3 (for recording)
else if( ch == CH_RX_HSSI_2 ){
ret = SSI3_REGBASE + SSI_RDR_OFFSET;
}
DEBUGMSG(ZONE_TEST, (TEXT("get_DSAR(ch:%d audiono:%d page:%d) : 0x%08x\r\n"), ch, n, page, ret));
return ret;
}
/*****************************************************************************
* FUNCTION : get_DDAR
* DESCRIPTION : Get DMA DDAR Register Setting
* INPUTS : ch - DMA Channel Number
* n - Audio Number
* page - Page Number
* OUTPUTS : Return Destination Address
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
DWORD
get_DDAR(
int ch,
DWORD n,
int page
)
{
DWORD ret;
// DMA Ch = SSI0 (for playing)
if( ch == CH_TX_HSSI_1 ){
ret = SSI0_REGBASE + SSI_TDR_OFFSET;
}
// DMA Ch = SSI2 (for playing)
else if( ch == CH_TX_HSSI_2 ){
ret = SSI2_REGBASE + SSI_TDR_OFFSET;
}
// DMA Ch = SSI1,SSI3 (for recording)
else if( ch == CH_RX_HSSI_1 || ch == CH_RX_HSSI_2 ){
ret = AUDIO_R_BUFFER_BASE + (AUDIO_DMA_PAGE_SIZE * 2) * n + (AUDIO_DMA_PAGE_SIZE * page);
}
DEBUGMSG(ZONE_TEST, (TEXT("get_DDAR(ch:%d audiono:%d page:%d) : 0x%08x\r\n"), ch, n, page, ret));
return ret;
}
/*****************************************************************************
* FUNCTION : get_DTCR
* DESCRIPTION : Get DMA DTCR Register Setting
* INPUTS : ch - DMA Channel Number
* n - Audio Number
* page - Page Number
* OUTPUTS : Return Transfer Count
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
DWORD
get_DTCR(
int ch,
DWORD n,
int page
)
{
DEBUGMSG(ZONE_TEST, (TEXT("get_DTCR(ch:%d audiono:%d page:%d) : 0x%08x\r\n"), ch, n, page, AUDIO_DMA_PAGE_SIZE / sizeof(ULONG)));
return AUDIO_DMA_PAGE_SIZE / sizeof(ULONG);
}
/*****************************************************************************
* FUNCTION : module_init
* DESCRIPTION : HSSI Initialize
* INPUTS : globals - DRIVER_GLOBALS Address
* i - Audio NUmber
* OUTPUTS : Return TRUE for success, FALSE for failure
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
BOOL
module_init(
PDRIVER_GLOBALS globals,
int i
)
{
BOOL ret = TRUE;
int ch;
PBYTE pSSI_RegBase; // page-base for register offsets
// SSI Reg
pSSI0_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
(PBYTE)SSI0_REGBASE,
(DWORD)SSI_REGSIZE,
"SSI_Init, pSSI_RegBase");
if (pSSI0_RegBase == NULL) {
RETAILMSG (1,(TEXT("SSI Virtual Alloc failure!\r\n")));
return FALSE;
}
ch = globals->aud[i].PLAY_CH - CH_TX_HSSI_1;
pSSI_RegBase = (PBYTE)(pSSI0_RegBase + (SSI_CH_REGBASE_OFFSET * ch));
pSSI_CR_TX = (PVULONG) ( pSSI_RegBase + SSI_CR_OFFSET );
pSSI_SR_TX = (PVULONG) ( pSSI_RegBase + SSI_SR_OFFSET );
pSSI_TDR = (PVULONG) ( pSSI_RegBase + SSI_TDR_OFFSET );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -