📄 nim_audio.c
字号:
iicDirectionUnSelect(IIC_DIRECTION_NIM1);
return err;
}
/* called in aiClose(). Should leave audio input system shut down */
extern tmLibdevErr_t nim_AI1_Term(void)
{
return TMLIBDEV_OK;
}
/* called in aiStart(). */
extern tmLibdevErr_t nim_AI1_Start(void)
{
aiEnableCAP_ENABLEM(AI1_STATUS);
return TMLIBDEV_OK;
}
/* called in aiStop(). */
extern tmLibdevErr_t nim_AI1_Stop(void)
{
aiDisableCAP_ENABLEM(AI1_STATUS);
return TMLIBDEV_OK;
}
/* called from aiSetSampleRate(). */
extern tmLibdevErr_t nim_AI1_SetSrate(Float sRate)
{
Float val;
/* it's not possible to change the input rate for digital input */
if (nimAi1Input == aaaDigitalInput)
{
return TMLIBDEV_OK;
}
val = sRate * 256.0; /* oversampling clock is 256 * fs */
if (use9xMode)
{
val = 0.5 + (477218588.0 * (val / CPUClock)); /* 2**32 / 9 */
aiSetFREQM(AI1_STATUS, ((UInt) val) | 0x80000000);
}
else
{
val = 0.5 + (1431655765.0 * (val / CPUClock)); /* 2**32 / 3 */
aiSetFREQM(AI1_STATUS, (UInt) val);
}
return TMLIBDEV_OK;
}
/* called from aiGetSampleRate().
* Should return an accurate value from the hardware.
*/
extern tmLibdevErr_t nim_AI1_GetSrate(Float * sRate)
{
UInt iicd;
Int err = TMLIBDEV_OK;
tmAssert(sRate, TMLIBDEV_ERR_NULL_PARAMETER);
if (nimAi1Input == aaaDigitalInput)
{
err = iicDirectionSelect(IIC_DIRECTION_NIM1);
if (err != TMLIBDEV_OK)
return err;
err = iicReadReg(INPUT_IIC_EXPANDER_ADDRESS, -1, &iicd);
iicd |= NIM_TDA1315_IN_IIC_FREQUENCY_MASK;
iicd &= ~(NIM_TDA1315_IN_IIC_LOCK); /* hold lock low to mask it */
err |= iicWriteReg(INPUT_IIC_EXPANDER_ADDRESS, -1, iicd);
err |= iicReadReg(INPUT_IIC_EXPANDER_ADDRESS, -1, &iicd);
iicDirectionUnSelect(IIC_DIRECTION_NIM1);
if (err) return err;
switch (iicd & NIM_TDA1315_IN_IIC_FREQUENCY_MASK)
{
case NIM_TDA1315_IN_IIC_44100_HZ:
*sRate = 44100.0;
break;
case NIM_TDA1315_IN_IIC_48000_HZ:
*sRate = 48000.0;
break;
case NIM_TDA1315_IN_IIC_32000_HZ:
*sRate = 32000.0;
break;
default:
*sRate = 0.0;
break;
}
}
else
{
if (use9xMode)
{
*sRate = (Float) (MMIO(AI1_STATUS + AI_FREQ_OFFSET) & 0x7fffffff) * CPUClock / 477218588.0 / 256.0;
}
else
{
*sRate = (Float) MMIO(AI1_STATUS + AI_FREQ_OFFSET) * CPUClock / 1431655765.0 / 256.0;
}
}
return TMLIBDEV_OK;
}
/* called from aiSetInput() */
extern tmLibdevErr_t nim_AI1_SetInput(tmAudioAnalogAdapter_t input)
{
boardAIParam_t param;
UInt err;
static Bool capEnable = False;
UInt32 buf1 = MMIO(AI1_STATUS + AI_BASE1_OFFSET);
UInt32 buf2 = MMIO(AI1_STATUS + AI_BASE2_OFFSET);
UInt32 size = MMIO(AI1_STATUS + AI_SIZE_OFFSET);
UInt32 aiIntControl = MMIO(AI1_STATUS + AI_CTL_OFFSET) & (AI_BUF1_INTEN | AI_BUF2_INTEN | AI_OVR_INTEN | AI_HBE_INTEN);
/* check if we realy have to change the input */
if (input == nimAi1Input)
{
return TMLIBDEV_OK;
}
/* stop audio in */
if (MMIO(AI1_STATUS + AI_CTL_OFFSET) & AI_CAP_ENABLE)
{
aiDisableCAP_ENABLEM(AI1_STATUS);
capEnable = True;
}
param.audioTypeFormat = nimAi1AudioTypeFormat;
param.audioSubtypeFormat = nimAi1AudioSbtypeFormat;
param.sRate = nimAi1SRate;
param.size = nimAi1Size;
param.input = input;
nimAi1Input = input;
err = nim_AI1_Init(¶m);
/* restore MMIO registers */
MMIO(AI1_STATUS + AI_BASE1_OFFSET) = buf1;
MMIO(AI1_STATUS + AI_BASE2_OFFSET) = buf2;
MMIO(AI1_STATUS + AI_SIZE_OFFSET) = size;
MMIO(AI1_STATUS + AI_CTL_OFFSET) |= aiIntControl;
if (err)
{
return err;
}
if (capEnable)
{
aiEnableCAP_ENABLEM(AI1_STATUS);
}
return TMLIBDEV_OK;
}
/* called from aiGetInput() */
extern tmLibdevErr_t nim_AI1_GetInput(tmAudioAnalogAdapter_t * input)
{
tmAssert(input, TMLIBDEV_ERR_NULL_PARAMETER);
*input = nimAi1Input;
return TMLIBDEV_OK;
}
/* called from aiGetInputFormat */
extern tmLibdevErr_t nim_AI1_GetFormat(ptmAudioFormat_t inputFormat)
{
Float sRate;
Int err;
Char statusReg[2] = {0,0};
/* initialize the inputFormat */
inputFormat->size = sizeof(tmAudioFormat_t);
inputFormat->dataClass = avdcAudio;
inputFormat->dataType = atfNone;
inputFormat->dataSubtype = apfNone;
inputFormat->sampleRate = 0.0;
/* get sample rate, if sample rate is 0.0 -> TDA 1315 is not locked */
err = nim_AI1_GetSrate(&sRate);
if (err) return err;
if (sRate == 0.0)
{
return TMLIBDEV_OK;
}
inputFormat->sampleRate = sRate;
inputFormat->dataType = atfLinearPCM;
inputFormat->dataSubtype = apfStereo16;
#if 0
/* get channel status information */
err = iicDirectionSelect(IIC_DIRECTION_NIM1);
if (err != TMLIBDEV_OK)
return err;
inputL3Params.data = statusReg;
err = tda1315AccessL3(&inputL3Params, READ_CHANNEL_STATUS_REGISTER);
iicDirectionUnSelect(IIC_DIRECTION_NIM1);
if (err)
return err;
if ((statusReg[0] & TDA1315_L3_CHAN_STAT_DATA_MASK) == TDA1315_L3_CHAN_STAT_DATA)
{
inputFormat->dataType = atf1937;
inputFormat->dataSubtype = apfGeneric;
}
#endif
return TMLIBDEV_OK;
}
/* a backdoor to support features not forseen in the initial design */
extern tmLibdevErr_t nim_AI1_Config(UInt32 subaddr, Pointer value)
{
return TMLIBDEV_OK;
}
/***********************************************************************************************
*
* AI 2 support (used on TM2)
*
***********************************************************************************************/
static UInt nimAi2Input;
static UInt nimAi2AudioTypeFormat;
static UInt nimAi2AudioSbtypeFormat;
static Float nimAi2SRate;
static Int nimAi2Size;
/* function called in aiInstanceSetup(): On success, must leave
* the audio input system "stopped" but otherwise ready for action.
* MMIO setup will be done, as well as other board or codec specific
* actions like setting IIC control bits or initializing codec registers.
*/
extern tmLibdevErr_t nim_AI2_Init(boardAIParam_t *param)
{
UInt iicd;
Float val;
pprocCapabilities_t procCap;
Int err = TMLIBDEV_OK;
Bool nimBoardRevision2 = True;
UInt32 ID;
Char *boardName;
err = tsaBoardGetBoard(&ID, &boardName);
if (err)
return err;
/* get the clock frequency of the TriMedia CPU */
err = procGetCapabilities(&procCap);
if (err) return err;
CPUClock = (Float) procCap->cpuClockFrequency;
if (procCap->deviceID == PROC_DEVICE_TM1000) use9xMode = False;
else use9xMode = True;
err = iicDirectionSelect(IIC_DIRECTION_NIM2);
if (err != TMLIBDEV_OK)
return err;
err = iicReadReg(AUDIO_SELECT_ID_EXPANDER_ADDRESS, -1, &iicd);
if (err) nimBoardRevision2 = False;
/* set strobe to zero */
err = iicReadReg(VIDMUX_IIC_EXPANDER_ADDRESS, -1, &iicd);
iicd &= ~(NIM_INPUT_L3_STROBE);
err |= iicWriteReg(VIDMUX_IIC_EXPANDER_ADDRESS, -1, iicd);
if (err) goto nim_AI2_InitExit;
/* reset input iic expander */
iicd = 0xEC; /* disable both CS53331's */
err |= iicWriteReg(INPUT_IIC_EXPANDER_ADDRESS, -1, iicd);
if (err) goto nim_AI2_InitExit;
aiRESETM(AI2_STATUS);
/* clock freq is in hz. Math is 32 bit- should be 64 bit!
In the digital input mode the clock is only needed to use the L3 interface.
In this case is the TriMedia clock slave.
In the analog input mode the clocks are needed because the CS5331 is clock
slave. */
val = param->sRate * 256; /* 256 * sampleRate */
if (use9xMode)
{
val = 0.5 + (477218588.0 * (val / CPUClock)); /* 2**32 / 9 */
aiSetFREQM(AI2_STATUS, ((UInt) val) | 0x80000000);
}
else
{
val = 0.5 + (1431655765.0 * (val / CPUClock)); /* 2**32 / 3 */
aiSetFREQM(AI2_STATUS, (UInt) val);
}
if (param->input == aaaNone)
{
param->input = aaaLineInput; /* line input is the default */
}
switch (param->input)
{
#if 0 /* We can't support digital audio in on the current TM2 chips. */
case aaaDigitalInput: /* use TDA 1315 */
if (nimBoardRevision2)
{
err = iicReadReg(AUDIO_SELECT_ID_EXPANDER_ADDRESS, -1, &iicd);
tmAssert(err == TMLIBDEV_OK, err);
iicd &= ~NIM_AUDIO_SELECT_MASK;
iicd |= NIM_AUDIO_SELECT_DIGITAL;
err = iicWriteReg(AUDIO_SELECT_ID_EXPANDER_ADDRESS, -1, iicd);
tmAssert(err == TMLIBDEV_OK, err);
}
/* set a small value for the input DDS frequency to disable the CS5331 */
aiSetFREQM(AI2_STATUS, ((UInt) val & 0x7fffffff) >> 4);
/* set powerdown for input TDA1315 to zero (normal operation) */
err = iicReadReg(INPUT_IIC_EXPANDER_ADDRESS, -1, &iicd);
tmAssert(err == TMLIBDEV_OK, err);
iicd &= ~(NIM_TDA1315_IN_IIC_POWERDOWN);
/* Enable Analog audio input */
iicd &= ~(NIM_TDA1315_IN_IIC_TUNER_AUDIO | NIM_TDA1315_IN_IIC_ANALOG_AUDIO);
err = iicWriteReg(INPUT_IIC_EXPANDER_ADDRESS, -1, iicd);
tmAssert(err == TMLIBDEV_OK, err);
microsleep(1000);
/* initalize the tda1315 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -