📄 tmdlao.c
字号:
if (instVars->boardAOConfig->startFunc)
{
err = instVars->boardAOConfig->startFunc(instVars->unitName);
}
aoEnableTRANS_ENABLEM(mmioBase);
return err;
}
/**************************************************************************************/
extern tmErrorCode_t tmdlAoInstanceConfig(Int instance, UInt32 command, Pointer parameter)
{
paoInstVars_t instVars = (paoInstVars_t) instance;
tmErrorCode_t err = TM_OK;
Float fOsclk;
ptmbslCoreSystemInfo_t SysInfo;
UInt32 mmioBase = instVars->boardAOConfig->mmioBase;
UInt8 cpuIndex;
DBG_ISR_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoInstanceConfig(%x,%x,%x)\n",instance, command, parameter));
tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
if (instVars->magic != AO_MAGIC)
return TMDL_ERR_AO_NOT_OWNER;
if (!instVars->initialized)
{
return TMDL_ERR_AO_INIT_REQUIRED;
}
/* get the processor type of the TriMedia CPU */
err = tmbslCoreGetSystemInfo(&SysInfo);
if (err) return err;
for(cpuIndex=0; cpuIndex < SysInfo->numCpu; cpuIndex++)
if(SysInfo->pCpuInfo[cpuIndex].cpuType == tmbslCoreCpuTypeTM) break;
switch(command)
{
/* This will set the power state of AO device after external
peripheral is set to that state */
case TMDL_CMD_AO_SET_POWERSTATE:
if (instVars->boardAOConfig->setPowerStateFunc)
{
err = instVars->boardAOConfig->setPowerStateFunc(instVars->unitName,
(tmPowerState_t)parameter);
if ( err == TM_OK)
{
if ((tmPowerState_t)parameter == tmPowerOn)
aoDisablePwrDwnM(mmioBase);
else
aoEnablePwrDwnM(mmioBase);
}
else
return err;
}
else
{
if ((tmPowerState_t)parameter == tmPowerOn)
aoDisablePwrDwnM(mmioBase);
else
aoEnablePwrDwnM(mmioBase);
}
return TM_OK;
/* This will get the power state of AO device */
case TMDL_CMD_AO_GET_POWERSTATE:
*((ptmPowerState_t)parameter) = aoGetPwrDwnM(mmioBase) ? tmPowerOff :
tmPowerOn;
return TM_OK;
/* This will set the sample rate of AO device before external
peripheral is set to that state */
case TMDL_CMD_AO_SET_SAMPLERATE:
if(!instVars->boardAOConfig->enableOsclk)
return TMDL_ERR_AO_OSCLK_NOT_ENABLED;
/* check validity of requested sample rate */
if ((*((Float*)parameter)) > (instVars->boardAOConfig->maxSRate*1.1f))
return TMDL_ERR_AO_SRATE_TOO_HIGH;
if ((*((Float*)parameter)) < (instVars->boardAOConfig->minSRate*0.9f))
return TMDL_ERR_AO_SRATE_TOO_LOW;
/*calculate the required oversampling clock */
fOsclk = instVars->boardAOConfig->osclkFactor * (*((Float*)parameter)); /* n X Fs */
/* set up the clock block */
if(err =(aoSetClock(instVars->unitName, mmioBase, fOsclk,
SysInfo->pCpuInfo[cpuIndex].cpuClockFreq)))
return err;
if (instVars->boardAOConfig->configFunc)
{
return instVars->boardAOConfig->configFunc(instVars->unitName,
TMBSL_CMD_AO_SET_SAMPLERATE, parameter);
}
return TM_OK;
/* This will get the sample rate of AO device */
case TMDL_CMD_AO_GET_SAMPLERATE:
if(!instVars->boardAOConfig->enableOsclk)
return TMDL_ERR_AO_OSCLK_NOT_ENABLED;
/* Get the Clock */
if(err =(aoGetClock(instVars->unitName, mmioBase, &fOsclk,
SysInfo->pCpuInfo[cpuIndex].cpuClockFreq)))
return err;
/* fs = fOsclk/n */
*((Float*)parameter) = (fOsclk/instVars->boardAOConfig->osclkFactor);
return TM_OK;
case TMDL_CMD_AO_SET_BUF1:
aoSetBASE1M(mmioBase, (UInt32)parameter);
return TM_OK;
case TMDL_CMD_AO_SET_BUF2:
aoSetBASE2M(mmioBase, (UInt32)parameter);
return TM_OK;
case TMDL_CMD_AO_SET_SIZE:
aoSetSIZEM(mmioBase, (UInt32)parameter);
return TM_OK;
case TMDL_CMD_AO_INT_STATE:
if((Bool)parameter)
{
MMIO(mmioBase + AO_CTL_OFFSET) = (MMIO(mmioBase + AO_CTL_OFFSET) | (instVars->intState));
}
else
{
instVars->intState = MMIO(mmioBase + AO_CTL_OFFSET) & (0xF << 4);
MMIO(mmioBase + AO_CTL_OFFSET) = (MMIO(mmioBase + AO_CTL_OFFSET) &
~(AO_BUF1_INTEN | AO_BUF2_INTEN | AO_UDR_INTEN | AO_HBE_INTEN));
}
return TM_OK;
/* If none of the command is understood then pass it on to BSL component */
default:
if (instVars->boardAOConfig->configFunc)
{
return instVars->boardAOConfig->configFunc(instVars->unitName,
command, parameter);
}
else
{
return TMDL_ERR_AO_UNSUPPORTED_COMMAND;
}
}
}
/**************************************************************************************/
extern tmErrorCode_t tmdlAoSetPowerState (Int instance, tmPowerState_t aoPowerState)
{
DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoSetPowerState(%x,%d)\n",instance, aoPowerState));
tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
return tmdlAoInstanceConfig(instance, TMDL_CMD_AO_SET_POWERSTATE, (Pointer)aoPowerState);
}
/**************************************************************************************/
extern tmErrorCode_t tmdlAoGetPowerState (Int instance, ptmPowerState_t pAoPowerState)
{
DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoGetPowerState(%x,%x)\n",instance, pAoPowerState));
tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
return tmdlAoInstanceConfig(instance, TMDL_CMD_AO_GET_POWERSTATE, pAoPowerState);
}
/**************************************************************************************/
/* Description: reset clock
* On return, transmission is disabled
* Be sure to set BASE and SIZE registers before enabling transmission
*/
extern tmErrorCode_t tmdlAoReset( Int instance )
{
paoInstVars_t instVars = (paoInstVars_t) instance;
UInt32 mmioBase = instVars->boardAOConfig->mmioBase;
UInt32 aoSerial;
UInt32 aoFraming;
UInt32 aoFreq;
UInt32 aoCtl;
UInt32 ix;
aoDisableTRANS_ENABLEM(mmioBase);
aoCtl = MMIO(mmioBase+AO_CTL_OFFSET);
aoSerial = MMIO(mmioBase+AO_SERIAL_OFFSET);
aoFraming = MMIO(mmioBase+AO_FRAMING_OFFSET);
aoFreq = MMIO(mmioBase+AO_FREQ_OFFSET);
/* set to system clock ( 27 MHz ) for soft aoRESETM() */
aoResetClock(instVars->unitName, mmioBase );
/* reset aoDevice */
aoRESETM(mmioBase);
/* wait for reset to complete */
for(ix = 0; ix < 100; ix++) {
if( MMIO(mmioBase+AO_CTL_OFFSET) != AO_RESET ) break;
}
DBG_ISR_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"tmdlAoReset ix=%d\n",ix));
/* set 90 KHz clock */
aoUnResetClock(instVars->unitName, mmioBase );
MMIO(mmioBase+AO_FREQ_OFFSET) = aoFreq;
MMIO(mmioBase+AO_SERIAL_OFFSET) = aoSerial;
MMIO(mmioBase+AO_FRAMING_OFFSET) = aoFraming;
MMIO(mmioBase+AO_CTL_OFFSET) = (aoCtl &(~AO_TRANS_ENABLE)); // keep trans dis
return TM_OK;
}
/*---------------------Private functions------------------------------------*/
static tmErrorCode_t getUnitIndex(tmUnitSelect_t unitName, Int *unitIndex)
{
UInt32 i;
for (i = 0; i < aoCaps.numberOfUnits; i++)
{
if (aoCaps.unitNumbers[i] == unitName)
{
*unitIndex = i;
DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Unit Index %d returned for unit Name %d\n", *unitIndex, unitName));
return TM_OK;
}
}
return TMDL_ERR_AO_NOT_AVAILABLE_IN_HW;
}
/**************************************************************************************/
/* This code is only executed once. */
static tmErrorCode_t prepareCapabilities(void)
{
UInt32 numberOfUnits, i;
tmbslAoConfig_t *AOConfig;
tmErrorCode_t err = TM_OK;
tmUnitSelect_t unitNumber = tmUnit0;
DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered prepareCapabilities()\n"));
if (aoInitDone)
return TM_OK;
tmosalSystemMutexEnter();
if ( aoCaps.numberOfUnits == 0 )
{
/* the number of units should not be contained in the board */
/* structure. Indeed, a developer might want to add a new unit */
/* without being able to modify the board config struct, since */
/* (s)he does not have access to the source */
if ((err= tmdlAoGetNumberOfUnits(&numberOfUnits)) != TM_OK)
goto prepareCapabilitiesExit;
if (numberOfUnits == 0)
{
err = TMDL_ERR_AO_NOT_AVAILABLE_IN_HW;
goto prepareCapabilitiesExit;
}
if( numberOfUnits > MAX_AO_UNITS )
{
err = TM_ERR_BAD_UNIT_NUMBER;
goto prepareCapabilitiesExit;
}
aoCaps.numberOfUnits = numberOfUnits;
memset(aoCaps.unitNumbers, 0x0, MAX_AO_UNITS * sizeof(tmUnitSelect_t));
memset(aoCaps.unitCapabilities, 0x0, MAX_AO_UNITS * sizeof(tmdlAoCapabilities_t));
i = 0;
while (i < aoCaps.numberOfUnits)
{
if (TM_OK != tmbslAoGetInterface(unitNumber, &AOConfig))
{
/* this unit number is not supported, check next */
unitNumber++;
continue;
}
aoCaps.unitNumbers[i] = unitNumber;
aoCaps.unitCapabilities[i].version.majorVersion = MAJOR_VERSION;
aoCaps.unitCapabilities[i].version.minorVersion = MINOR_VERSION;
aoCaps.unitCapabilities[i].version.buildVersion = BUILD_VERSION;
aoCaps.unitCapabilities[i].numSupportedInstances = 1;
aoCaps.unitCapabilities[i].numCurrentInstances = 0;
aoCaps.unitCapabilities[i].audioTypeFormats = AOConfig->audioTypeFormats;
aoCaps.unitCapabilities[i].audioSubtypeFormats = AOConfig->audioSubtypeFormats;
aoCaps.unitCapabilities[i].audioAdapters = AOConfig->audioAdapters;
aoCaps.unitCapabilities[i].maxSRate = (Float) AOConfig->maxSRate;
aoCaps.unitCapabilities[i].minSRate = (Float) AOConfig->minSRate;
aoCaps.unitCapabilities[i].mmioBase = AOConfig->mmioBase;
aoCaps.unitCapabilities[i].intName = AOConfig->intName;
if (AOConfig->codecName != Null)
{
strncpy(aoCaps.unitCapabilities[i].codecName, AOConfig->codecName, HAL_DEVICE_NAME_LENGTH);
}
unitNumber++;
i++;
}
aoInitDone = True;
}
prepareCapabilitiesExit:
tmosalSystemMutexExit();
return err;
}
/**************************************************************************************/
/* These functions are not to be used by newer implementations. This is provided for */
/* backward compatability. Philips may discontinue these functions at appropriate time*/
/**************************************************************************************/
extern tmErrorCode_t tmdlAoSetOutput(Int instance, tmAudioAnalogAdapter_t output)
{
DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoSetOutput(%x,%d)\n", instance,output));
tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
return tmdlAoInstanceConfig(instance, TMBSL_CMD_AO_SET_OUTPUT, (Pointer)output);
}
/**************************************************************************************/
extern tmErrorCode_t tmdlAoGetOutput(Int instance, tmAudioAnalogAdapter_t *output)
{
DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoGetOutput(%x,%x)\n", instance, output));
tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
return tmdlAoInstanceConfig(instance, TMBSL_CMD_AO_GET_OUTPUT, (Pointer)output);
}
/**************************************************************************************/
extern tmErrorCode_t tmdlAoSetVolume(Int instance, Int lGain, Int rGain)
{
tmAoMultiChParam_t info;
tmErrorCode_t err = TM_OK;
UInt32 vol[2];
DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoSetVolume(%x,%d,%d)\n", instance, lGain, rGain));
tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
vol[0] = lGain;
vol[1] = rGain;
info.channels = AO_BSL_MAIN_LEFT | AO_BSL_MAIN_RIGHT;
info.value = vol;
err = tmdlAoInstanceConfig(instance, TMBSL_CMD_AO_SET_VOLUME, (Pointer)&info);
return err;
}
/**************************************************************************************/
extern tmErrorCode_t tmdlAoGetVolume(Int instance, Int *lGain, Int *rGain)
{
tmAoMultiChParam_t info;
tmErrorCode_t err = TM_OK;
UInt32 vol[2];
DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoGetVolume(%x,%x,%x)\n", instance, lGain, rGain));
tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
info.channels = AO_BSL_MAIN_LEFT | AO_BSL_MAIN_RIGHT;
info.value = vol;
err = tmdlAoInstanceConfig(instance, TMBSL_CMD_AO_GET_VOLUME, (Pointer)&info);
if (err) return err;
*lGain = vol[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -