/* * Copyright (c) 2015, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * \file platform_audio.c * * \brief Platform audio interface file. * * This file contains APIs for accessing DAC/ADC/DIR modules on audio daughter * card. * */ #include "platform_internal.h" #if (PLATFORM_AUDIO) /* DAC HW instance I2C slave address */ Uint8 gDacI2cAddr[PLATFORM_AUDIO_DAC_COUNT] = {PLATFORM_AUDIO_DAC0_ADDR, PLATFORM_AUDIO_DAC1_ADDR}; /* ADC HW instance I2C slave address */ Uint8 gAdcI2cAddr[PLATFORM_AUDIO_ADC_COUNT] = {PLATFORM_AUDIO_ADC0_ADDR, PLATFORM_AUDIO_ADC1_ADDR}; /** * \brief Initializes Audio module * * This function configures the system level setup required for * operation of the modules that are available on audio daughter card. * This function shall be called before calling any other platform * audio module functions. * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioInit(void) { uint8_t padCfg; uint8_t padMax; IFPRINT(platform_write("platformAudioInit Called \n")); /* Configure McASP0 lines */ /* MCASP0AMUTE, MCASP0ACLKR, MCASP0FSR, MCASP0AHCLKR MCASP0ACLKX, MCASP0FSX, MCASP0AHCLKX, MCASP0AXR[0:7] - PADCONFIG 169 to 183 */ padMax = 183; for (padCfg = 169; padCfg <= padMax; padCfg++) { pinMuxSetMode(padCfg, PADCONFIG_MUX_MODE_QUINARY); } /* MCASP0AXR[12:15] - PADCONFIG 188 to 191 */ padMax = 191; for (padCfg = 188; padCfg <= padMax; padCfg++) { pinMuxSetMode(padCfg, PADCONFIG_MUX_MODE_QUINARY); } /* Configure McASP1 lines */ /* MCASP1ACLKR, MCASP1FSR, MCASP1AHCLKR - PADCONFIG 152 to 154 */ padMax = 154; for (padCfg = 152; padCfg <= padMax; padCfg++) { pinMuxSetMode(padCfg, PADCONFIG_MUX_MODE_QUINARY); } /* MCASP1AHCLKX - PADCONFIG 157 */ pinMuxSetMode(157, PADCONFIG_MUX_MODE_QUINARY); /* MCASP1AXR[0:3] - PADCONFIG 159 to 162 */ padMax = 162; for (padCfg = 159; padCfg <= padMax; padCfg++) { pinMuxSetMode(padCfg, PADCONFIG_MUX_MODE_QUINARY); } /* MCASP1AXR9 - PADCONFIG 168 */ pinMuxSetMode(168, PADCONFIG_MUX_MODE_QUINARY); /* Configure McASP2 lines */ /* MCASP2AXR[1:5], MCASP2ACLKR, MCASP2FSR, MCASP2AHCLKR - PADCONFIG 140 to 147 */ padMax = 147; for (padCfg = 140; padCfg <= padMax; padCfg++) { pinMuxSetMode(padCfg, PADCONFIG_MUX_MODE_QUINARY); } /* MCASP2FSX - PADCONFIG 149 */ pinMuxSetMode(149, PADCONFIG_MUX_MODE_QUINARY); /* MCASP2ACLKX - PADCONFIG 151 */ pinMuxSetMode(151, PADCONFIG_MUX_MODE_QUINARY); /* Configure GPIO for McASP_CLK_SEL - GPIO0 132 & PADCONFIG 163 */ pinMuxSetMode(163, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SEL_GPIO, GPIO_OUT); /* Slect the clock source as DIR */ gpioSetOutput(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SEL_GPIO); /* Configure GPIO for McASP_CLK_SEL# - GPIO0 101 & PADCONFIG 110 */ pinMuxSetMode(110, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SELz_GPIO, GPIO_OUT); /* Slect the clock source as DIR */ //gpioClearOutput(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SELz_GPIO); gpioSetOutput(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SELz_GPIO); // Default configurations are set for McASP AHCLK driven by SoC /* Configure GPIO for PCM1690_RST# - GPIO1 10 & PADCONFIG 185 */ pinMuxSetMode(185, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_1, PLATFORM_AUDIO_PCM1690_RST_GPIO, GPIO_OUT); gpioClearOutput(GPIO_PORT_1, PLATFORM_AUDIO_PCM1690_RST_GPIO); platform_delay(1000); gpioSetOutput(GPIO_PORT_1, PLATFORM_AUDIO_PCM1690_RST_GPIO); /* Configure GPIO for McASP_CLK_SEL# - GPIO0 101 & PADCONFIG 110 */ pinMuxSetMode(114, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_0, PLATFORM_AUDIO_HSR_HMINTz_GPIO, GPIO_IN); /* Configure McASP AUXCLK source as AUDIO_OSCCLK */ hBootCfg->SERIALPORT_CLKCTL = 0; hBootCfg->OSC_CTL = 0x200; //SW2:SW1 = 01 (15 - 30 MHz) return (Platform_EOK); } /** * \brief Resets audio DAC * * This function toggles the GPIO signal connected to RST pin * of DAC module to generate DAC reset. * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioResetDac(void) { gpioClearOutput(GPIO_PORT_1, PLATFORM_AUDIO_PCM1690_RST_GPIO); platform_delay(1000); gpioSetOutput(GPIO_PORT_1, PLATFORM_AUDIO_PCM1690_RST_GPIO); /* Configure McASP AUXCLK source as AUDIO_OSCCLK */ hBootCfg->SERIALPORT_CLKCTL = 0; return (Platform_EOK); } /** * \brief Configures audio clock source * * McASP can receive clock from DIR module on daughter card or external * I2S device to operate DAC and ADC modules. This function configures * which clock source to use (DIR or I2S) for DAC and ADC operation * * \param clkSrc [IN] Clock source selection * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioSelectClkSrc(AudioClkSrc clkSrc) { IFPRINT(platform_write("platformAudioSelectClkSrc Called \n")); /* Configure GPIO for McASP_CLK_SEL - GPIO0 132 & PADCONFIG 163 */ pinMuxSetMode(163, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SEL_GPIO, GPIO_OUT); /* Configure GPIO for McASP_CLK_SEL# - GPIO0 101 & PADCONFIG 110 */ pinMuxSetMode(110, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SELz_GPIO, GPIO_OUT); if(clkSrc == AUDIO_CLK_SRC_DIR) { gpioSetOutput(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SEL_GPIO); gpioClearOutput(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SELz_GPIO); } else if(clkSrc == AUDIO_CLK_SRC_I2S) { gpioClearOutput(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SEL_GPIO); gpioSetOutput(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SELz_GPIO); } else if(clkSrc == AUDIO_CLK_SRC_OSC) { gpioSetOutput(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SEL_GPIO); gpioSetOutput(GPIO_PORT_0, PLATFORM_AUDIO_CLK_SELz_GPIO); } else { IFPRINT(platform_write("platformAudioSelectClkSrc : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } return (Platform_EOK); } #if (PLATFORM_AUDIO_ADC) /** * \brief Initializes ADC module * * This function configures the system level setup required for ADC * operation and initializes the ADC module with default values. * This function should be called before calling any other ADC functions. * * After executing this function, ADC module will be ready for audio * processing with default configuration. Default ADC configurations * can be changed using the other ADC APIs if required. * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to initialize * all the ADC devices available. * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioAdcInit(AdcDevId devId) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcInit Called \n")); if(!((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL))) { IFPRINT(platform_write("platformAudioAdcInit : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { retVal = pcm186xAdcInit(gAdcI2cAddr[id]); if(retVal) { IFPRINT(platform_write("platformAudioAdcInit : ADC Initialization Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_INIT; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Resets ADC module * * This function resets all the ADC module registers to their * HW default values. * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to reset * all the ADC devices available. * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioAdcReset(AdcDevId devId) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcReset Called \n")); if(!((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL))) { IFPRINT(platform_write("platformAudioAdcReset : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { retVal = pcm186xReset(gAdcI2cAddr[id]); if(retVal) { IFPRINT(platform_write("platformAudioAdcReset : ADC Reset Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures ADC gain value * * Range of the gain is exposed as percentage by this API. Gain * is indicated as percentage of maximum gain ranging from 0 to 100. * 0 indicates minimum gain and 100 indicates maximum gain. * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to apply the configuration * for all the ADC devices available. * * \param chanId [IN] Internal ADC channel Id * Use ADC_CH_ALL to set gain for all the * ADC channels * * \param gain [IN] Gain value; 0 to 100 * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioAdcSetGain(AdcDevId devId, AdcChanId chanId, uint8_t gain) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcSetGain Called \n")); if( !( ((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL)) && ((chanId >= ADC_CH1_LEFT) && (chanId <= ADC_CH_ALL)) && (gain <= 100) ) ) { IFPRINT(platform_write("platformAudioAdcSetGain : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { retVal = pcm186xSetVolume(gAdcI2cAddr[id], (Uint8)gain, (Uint8)chanId); if(retVal) { IFPRINT(platform_write("platformAudioAdcSetGain : ADC Access for Gain Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures ADC analog input selection for left channel * * Default input selection of ADC left channels can be modified using * this function. * * Default input selection for ADC left channels is listed below * CH1 LEFT - VINL1 * CH2 LEFT - VINL2 * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to apply the configuration * for all the ADC devices available. * * \param chanId [IN] Internal ADC channel Id * ADC_CH1_LEFT - Input selection for channel 1 left * ADC_CH2_LEFT - Input selection for channel 2 left * ADC_CH_ALL - Input selection for channel 1 & 2 left * * \param inputMux [IN] Input mux configuration * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioAdcSetLeftInputMux(AdcDevId devId, AdcChanId chanId, AdcLeftInputMux inputMux) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcSetLeftInputMux Called \n")); if( !( ((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL)) && ((chanId == ADC_CH1_LEFT) || (chanId == ADC_CH2_LEFT) || (chanId == ADC_CH_ALL)) && ((inputMux >= ADC_INL_NONE) && (inputMux <= ADC_INL_DIFF_VIN1P_VIN1M_VIN4P_VIN4M)) ) ) { IFPRINT(platform_write("platformAudioAdcSetLeftInputMux : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { if(chanId == ADC_CH_ALL) { retVal = pcm186xInputSel(gAdcI2cAddr[id], (Uint8)ADC_CH1_LEFT, (Uint8)inputMux); if(retVal) { IFPRINT(platform_write("platformAudioAdcSetLeftInputMux : ADC Access for Input Selection Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } retVal = pcm186xInputSel(gAdcI2cAddr[id], (Uint8)ADC_CH2_LEFT, (Uint8)inputMux); } else { retVal = pcm186xInputSel(gAdcI2cAddr[id], (Uint8)chanId, (Uint8)inputMux); } if(retVal) { IFPRINT(platform_write("platformAudioAdcSetLeftInputMux : ADC Access for Input Selection Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures ADC analog input selection for right channel * * Default input selection of ADC right channels can be modified using * this function * * Default input selection for ADC right channels is shown below * CH1 RIGHT - VINR1 * CH2_RIGHT - VINR2 * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to apply the configuration * for all the ADC devices available. * * \param chanId [IN] Internal ADC channel Id * ADC_CH1_RIGHT - Input selection for channel 1 right * ADC_CH2_RIGHT - Input selection for channel 2 right * ADC_CH_ALL - Input selection for channel 1 & 2 right * * \param inputMux [IN] Input mux configuration * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioAdcSetRightInputMux(AdcDevId devId, AdcChanId chanId, AdcRightInputMux inputMux) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcSetRightInputMux Called \n")); if( !( ((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL)) && ((chanId == ADC_CH1_RIGHT) || (chanId == ADC_CH2_RIGHT) || (chanId == ADC_CH_ALL)) && ((inputMux >= ADC_INR_NONE) && (inputMux <= ADC_INR_DIFF_VIN2P_VIN2M_VIN3P_VIN3M)) ) ) { IFPRINT(platform_write("platformAudioAdcSetRightInputMux : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { if(chanId == ADC_CH_ALL) { retVal = pcm186xInputSel(gAdcI2cAddr[id], (Uint8)ADC_CH1_RIGHT, (Uint8)inputMux); if(retVal) { IFPRINT(platform_write("platformAudioAdcSetRightInputMux : ADC Access for Input Selection Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } retVal = pcm186xInputSel(gAdcI2cAddr[id], (Uint8)ADC_CH2_RIGHT, (Uint8)inputMux); } else { retVal = pcm186xInputSel(gAdcI2cAddr[id], (Uint8)chanId, (Uint8)inputMux); } if(retVal) { IFPRINT(platform_write("platformAudioAdcSetRightInputMux : ADC Access for Input Selection Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief ADC audio interface data configuration * * This function configures serial audio interface data format and * receive PCM word length for ADC * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to apply the configuration * for all the ADC devices available. * * \param wLen [IN] ADC data word length * * \param format [IN] Audio data format * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioAdcDataConfig(AdcDevId devId, AdcRxWordLen wLen, AdcDataFormat format) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcDataConfig Called \n")); if( !( ((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL)) && ((wLen >= ADC_RX_WLEN_24BIT) && (wLen <= ADC_RX_WLEN_16BIT)) && ((format >= ADC_DATA_FORMAT_I2S) && (format <= ADC_DATA_FORMAT_TDM_DSP)) ) ) { IFPRINT(platform_write("platformAudioAdcDataConfig : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { retVal = pcm186xDataConfig(gAdcI2cAddr[id], (Uint8)format, (Uint8)wLen); if(retVal) { IFPRINT(platform_write("platformAudioAdcDataConfig : ADC Access for Data Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Enables/Disables ADC channel mute * * This function configures mute functionality of each ADC channel * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to apply the configuration * for all the ADC devices available. * * \param chanId [IN] Internal ADC channel Id * Use ADC_CH_ALL to apply mute configuration for * all the ADC channels * * \param muteEnable [IN] Flag to configure mute * 1 - Mute ADC channel * 0 - Unmute ADC channel * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioAdcMuteCtrl(AdcDevId devId, AdcChanId chanId, uint8_t muteEnable) { ADC_RET retVal; Uint8 chan; Uint8 id; IFPRINT(platform_write("platformAudioAdcMuteCtrl Called \n")); if( !( ((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL)) && ((chanId >= ADC_CH1_LEFT) && (chanId <= ADC_CH_ALL)) && ((muteEnable == 0) || (muteEnable == 1)) ) ) { IFPRINT(platform_write("platformAudioAdcMuteCtrl : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } if(chanId == ADC_CH_ALL) { chan = 0xF; } else { chan = (1 << chanId); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { retVal = pcm186xMuteChannel(gAdcI2cAddr[id], chan, (Uint8)muteEnable); if(retVal) { IFPRINT(platform_write("platformAudioAdcMuteCtrl : ADC Access for Mute Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures ADC MIC bias * * This function enables/disables MIC bias for analog MIC input * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to apply the configuration * for all the ADC devices available. * * \param micBiasEnable [IN] Mic Bias enable flag * 1 - Enable MIC Bias * 0 - Disable MIC Bias * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioAdcMicBiasCtrl(AdcDevId devId, uint8_t micBiasEnable) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcMicBiasCtrl Called \n")); if( !( ((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL)) && ((micBiasEnable == 0) || (micBiasEnable == 1)) ) ) { IFPRINT(platform_write("platformAudioAdcMicBiasCtrl : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { retVal = pcm186xMicBiasCtrl(gAdcI2cAddr[id], (Uint8)micBiasEnable); if(retVal) { IFPRINT(platform_write("platformAudioAdcMicBiasCtrl : ADC Access for Mic Bias Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures ADC power state * * This function enables/disables different power modes supported by ADC * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to apply the configuration * for all the ADC devices available. * * \param powState [IN] ADC power state to configure * * \param stateEnable [IN] Power state enable flag * 1 - Enables the power state * 0 - Disables the power state * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioAdcConfigPowState(AdcDevId devId, AdcPowerState powState, uint8_t stateEnable) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcConfigPowState Called \n")); if( !( ((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL)) && ((powState >= ADC_POWER_STATE_STANDBY) && (powState <= ADC_POWER_STATE_POWERDOWN)) && ((stateEnable == 0) || (stateEnable == 1)) ) ) { IFPRINT(platform_write("platformAudioAdcConfigPowState : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { retVal = pcm186xConfigPowState(gAdcI2cAddr[id], (Uint8)powState, (Uint8)stateEnable); if(retVal) { IFPRINT(platform_write("platformAudioAdcConfigPowState : ADC Access for Power State Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures ADC interrupts * * This function enables/disables different interrupts supported by ADC * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to apply the configuration * for all the ADC devices available. * * \param intId [IN] Interrupt Id to configure * Use to 'ADC_INTR_ALL' to configure all the * interrupts together * * \param intEnable [IN] Interrupt enable flag * 1 - Enables the interrupt * 0 - Disables the interrupt * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioAdcConfigIntr(AdcDevId devId, AdcIntr intId, uint8_t intEnable) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcConfigIntr Called \n")); if( !( ((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL)) && ((intId >= ADC_INTR_ENERGY_SENSE) && (intId <= ADC_INTR_ALL)) && ((intEnable == 0) || (intEnable == 1)) ) ) { IFPRINT(platform_write("platformAudioAdcConfigIntr : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { retVal = pcm186xSetIntr(gAdcI2cAddr[id], (Uint8)intId, (Uint8)intEnable); if(retVal) { IFPRINT(platform_write("platformAudioAdcConfigIntr : ADC Access for Intr Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Reads ADC interrupt status * * This function reads the status of different interrupts supported by ADC * * \param devId [IN] Device ID of ADC HW instance * * \param intId [IN] Interrupt Id to read the status * Use to 'ADC_INTR_ALL' to read status of all the * interrupts together * * \return Interrupt status * 1 - Interrupt occurred * 0 - No interrupt occurred * 0xFF - Error in reading interrupt */ uint8_t platformAudioAdcGetIntrStatus(AdcDevId devId, AdcIntr intId) { Uint8 retVal; IFPRINT(platform_write("platformAudioAdcGetIntrStatus Called \n")); if( !( ((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_1)) && ((intId >= ADC_INTR_ENERGY_SENSE) && (intId <= ADC_INTR_ALL)) ) ) { IFPRINT(platform_write("platformAudioAdcGetIntrStatus : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (1); } retVal = pcm186xGetIntrStatus(gAdcI2cAddr[devId]); if(retVal == 0xFF) { IFPRINT(platform_write("platformAudioAdcGetIntrStatus : ADC Access for Intr Status Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_STATUS; return ((uint8_t)retVal); } if(intId != ADC_INTR_ALL) { retVal = (retVal >> intId) & 0x1; } return (retVal); } /** * \brief Reads ADC status bits * * This function reads the value of different status functions supported * by ADC module (excluding interrupts). * * \param devId [IN] Device ID of ADC HW instance * * \param status [IN] Status function of which status to be read * * \return Value of status function or 0xFF in case of error * */ uint8_t platformAudioAdcGetStatus(AdcDevId devId, AdcStatus status) { Uint8 retVal; IFPRINT(platform_write("platformAudioAdcGetStatus Called \n")); if( !( ((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_1)) && ((status >= ADC_STATUS_POWER_STATE) && (status <= ADC_STATUS_LDO)) ) ) { IFPRINT(platform_write("platformAudioAdcGetStatus : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (1); } switch(status) { /* Current Power State of the device * 0x0 - Power Down * 0x1 - Wait clock stable * 0x2 - Release reset * 0x3 - Stand-by * 0x4 - Fade IN * 0x5 - Fade OUT * 0x9 - Sleep * 0xF - Run */ case ADC_STATUS_POWER_STATE: retVal = pcm186xGetPowerStateStatus(gAdcI2cAddr[devId]); break; /* Current Sampling Frequency * 0x0 - Out of range (Low) or LRCK Halt * 0x1 - 8kHz * 0x2 - 16kHz * 0x3 - 32-48kHz * 0x4 - 88.2-96kHz * 0x5 - 176.4-192kHz * 0x6 - Out of range (High) * 0x7 - Invalid Fs */ case ADC_STATUS_SAMPLING_FREQ: retVal = pcm186xGetSampleFreqStatus(gAdcI2cAddr[devId]); break; /* Current receiving BCK ratio * 0x0 - Out of range (L) or BCK Halt * 0x1 - 32 * 0x2 - 48 * 0x3 - 64 * 0x4 - 256 * 0x6 - Out of range (High) * 0x7 - Invalid BCK ratio or LRCK Halt */ case ADC_STATUS_BCK_RATIO: retVal = pcm186xGetBckRatioStatus(gAdcI2cAddr[devId]); break; /* Current SCK Ratio * 0x0 - Out of range (L) or SCK Halt * 0x1 - 128 * 0x2 - 256 * 0x3 - 384 * 0x4 - 512 * 0x5 - 768 * 0x6 - Out of range (High) * 0x7 - Invalid SCK ratio or LRCK Halt */ case ADC_STATUS_SCK_RATIO: retVal = pcm186xGetSckRatioStatus(gAdcI2cAddr[devId]); break; /* LRCK Halt Status * 0 - No Error * 1 - Halt */ case ADC_STATUS_LRCK_HALT: retVal = pcm186xGetLrckHltStatus(gAdcI2cAddr[devId]); break; /* BCK Halt Status * 0 - No Error * 1 - Halt */ case ADC_STATUS_BCK_HALT: retVal = pcm186xGetBckHltStatus(gAdcI2cAddr[devId]); break; /* SCK Halt Status * 0 - No Error * 1 - Halt */ case ADC_STATUS_SCK_HALT: retVal = pcm186xGetSckHltStatus(gAdcI2cAddr[devId]); break; /* LRCK Error Status * 0 - No Error * 1 - Error */ case ADC_STATUS_LRCK_ERR: retVal = pcm186xGetLrckErrStatus(gAdcI2cAddr[devId]); break; /* BCK Error Status * 0 - No Error * 1 - Error */ case ADC_STATUS_BCK_ERR: retVal = pcm186xGetBckErrStatus(gAdcI2cAddr[devId]); break; /* SCK Error Status * 0 - No Error * 1 - Error */ case ADC_STATUS_SCK_ERR: retVal = pcm186xGetSckErrStatus(gAdcI2cAddr[devId]); break; /* DVDD Status * 0 - Bad/Missing * 1 - Good */ case ADC_STATUS_DVDD: retVal = pcm186xGetDvddStatus(gAdcI2cAddr[devId]); break; /* AVDD Status * 0 - Bad/Missing * 1 - Good */ case ADC_STATUS_AVDD: retVal = pcm186xGetAvddStatus(gAdcI2cAddr[devId]); break; /* Digital LDO Status * 0 - Bad/Missing * 1 - Good */ case ADC_STATUS_LDO: retVal = pcm186xGetLdoStatus(gAdcI2cAddr[devId]); break; default: retVal = 0xFF; break; } if(retVal == 0xFF) { IFPRINT(platform_write("platformAudioAdcGetStatus : ADC Access for Get Status Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_STATUS; } return ((uint8_t)retVal); } /** * \brief ADC DSP channel configuration control * * This function configures the DSP module processing channels * supported by ADC * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to apply the configuration * for all the ADC devices available. * * \param chanCfg [IN] DSP channel configuration * * \return Platform_EOK on Success or error code * */ Platform_STATUS platformAudioAdcDspCtrl(AdcDevId devId, AdcDspChanCfg chanCfg) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcDspCtrl Called \n")); if( !( ((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL)) && ((chanCfg == ADC_DSP_PROC_4CHAN) || (chanCfg == ADC_DSP_PROC_2CHAN)) ) ) { IFPRINT(platform_write("platformAudioAdcDspCtrl : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { retVal = pcm186xDspCtrl(gAdcI2cAddr[id], (Uint8)chanCfg); if(retVal) { IFPRINT(platform_write("platformAudioAdcDspCtrl : ADC Access for DSP Chan Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Programs ADC DSP coefficients * * ADC module supports an internal DSP which performs additional audio * processing operations like mixing, LPF/HPF etc. * DSP coefficients can be programmed by this function. * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to apply the configuration * for all the ADC devices available. * * \param coeffRegAddr [IN] Address of DSP coefficient register * * \param dspCoeff [IN] Value of DSP coefficient * Lower 24 bits are written to DSP coeff register * * \return Platform_EOK on Success or error code * */ Platform_STATUS platformAudioAdcProgDspCoeff(AdcDevId devId, uint8_t coeffRegAddr, uint32_t dspCoeff) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcProgDspCoeff Called \n")); if(!((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL))) { IFPRINT(platform_write("platformAudioAdcProgDspCoeff : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { retVal = pcm186xProgDspCoeff(gAdcI2cAddr[id], (Uint8)coeffRegAddr, (Uint32)dspCoeff); if(retVal) { IFPRINT(platform_write("platformAudioAdcProgDspCoeff : ADC DSP Coefficient Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Displays ADC register programmed values * * This function is provided for debug purpose to read the value * of ADC registers. Values read from the ADC registers will be displayed * in CCS output window or serial terminal based on the system level * configuration for debug messages. * * \param devId [IN] Device ID of ADC HW instance * Use 'ADC_DEVICE_ALL' to read the register values * for all the ADC devices available. * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioAdcGetRegDump(AdcDevId devId) { ADC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioAdcGetRegDump Called \n")); if(!((devId >= ADC_DEVICE_0) && (devId <= ADC_DEVICE_ALL))) { IFPRINT(platform_write("platformAudioAdcGetRegDump : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = ADC_DEVICE_0; id < ADC_DEVICE_ALL; id++) { if((id == devId) || (devId == ADC_DEVICE_ALL)) { retVal = pcm186xRegDump(gAdcI2cAddr[id]); if(retVal) { IFPRINT(platform_write("platformAudioAdcGetRegDump : ADC Reg Read Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_STATUS; return (Platform_EFAIL); } } } return (Platform_EOK); } #endif /* #if (PLATFORM_AUDIO_ADC) */ #if (PLATFORM_AUDIO_DAC) /** * \brief Initializes DAC module * * This function configures the system level setup required for DAC * operation and initializes the DAC module with default values. * This function should be called before calling any other DAC functions. * * After executing this function, DAC module should be ready for audio * processing with default configuration. Default DAC configurations * can be changed using the other DAC APIs if required. * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to initialize * all the DAC devices available. * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacInit(DacDevId devId) { DAC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioDacInit Called \n")); if(!((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL))) { IFPRINT(platform_write("platformAudioDacInit : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { retVal = pcm169xDacInit(gDacI2cAddr[id]); if(retVal) { IFPRINT(platform_write("platformAudioDacInit : DAC Initialization Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_INIT; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Resets DAC module * * Resetting the DAC module restarts the re-synchronization between * system clock and sampling clock, and DAC operation. * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to reset * all the DAC devices available. * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacReset(DacDevId devId) { DAC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioDacReset Called \n")); /* Check input parameters */ if(!((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL))) { IFPRINT(platform_write("platformAudioDacReset : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { IFPRINT(platform_write("platformAudioDacReset : DAC Reset Failed \n")); retVal = pcm169xReset(gDacI2cAddr[id]); if(retVal) { platform_errno = PLATFORM_ERRNO_AUDIO; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures DAC Analog mute control * * DAC module supports AMUTE functionality which causes the DAC output * to cut-off from the digital input upon the occurrence of any events * which are configured by AMUTE control. * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \param muteCtrl [IN] Analog mute control event * * \param muteEnable [IN] Flag to configure AMUTE for given control event * 1 - Enable AMUTE control * 0 - Disable AMUTE control * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacAmuteCtrl(DacDevId devId, DacAmuteCtrl muteCtrl, uint8_t muteEnable) { DAC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioDacAmuteCtrl Called \n")); /* Check input parameters */ if( !( ((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL)) && ((muteCtrl >= DAC_AMUTE_CTRL_SCKI_LOST) && (muteCtrl <= DAC_AMUTE_CTRL_DAC_DISABLE_CMD)) && ((muteEnable == 0) || (muteEnable == 1)) ) ) { IFPRINT(platform_write("platformAudioDacAmuteCtrl : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { if(muteEnable == 1) { retVal = pcm169xEnableAmute(gDacI2cAddr[id], (Uint8)(1 << muteCtrl)); } else { retVal = pcm169xDisableAmute(gDacI2cAddr[id], (Uint8)(1 << muteCtrl)); } if(retVal) { IFPRINT(platform_write("platformAudioDacAmuteCtrl : DAC Access for AMUTE Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures DAC Audio sampling mode * * By default, DAC module sampling mode is configured for auto mode. * In Auto mode, the sampling mode is automatically set according to multiples * between the system clock and sampling clock. Single rate for 512 fS, 768 fS, * and 1152 fS, dual rate for 256 fS or 384 fS, and quad rate for 128 fS * and 192 fS. Setting the sampling mode is required only if auto mode * configurations are not suitable for the application. * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \param samplingMode [IN] DAC audio sampling mode * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacSetSamplingMode(DacDevId devId, DacSamplingMode samplingMode) { DAC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioDacSetSamplingMode Called \n")); /* Check input parameters */ if( !( ((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL)) && ((samplingMode >= DAC_SAMPLING_MODE_AUTO) && (samplingMode <= DAC_SAMPLING_MODE_QUAD_RATE)) ) ) { IFPRINT(platform_write("platformAudioDacSetSamplingMode : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { retVal = pcm169xSetSamplingMode(gDacI2cAddr[id], (Uint8)samplingMode); if(retVal) { IFPRINT(platform_write("platformAudioDacSetSamplingMode : DAC Access for Sampling Mode Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures DAC Audio interface data format * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \param dataFormat [IN] DAC audio data format * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacSetDataFormat(DacDevId devId, DacDataFormat dataFormat) { DAC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioDacSetDataFormat Called \n")); /* Check input parameters */ if( !( ((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL)) && ((dataFormat >= DAC_DATA_FORMAT_I2S) && (dataFormat <= DAC_DATA_FORMAT_24BIT_HS_LEFTJ_TDM)) ) ) { IFPRINT(platform_write("platformAudioDacSetDataFormat : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { retVal = pcm169xDataConfig(gDacI2cAddr[id], (Uint8)dataFormat); if(retVal) { IFPRINT(platform_write("platformAudioDacSetDataFormat : DAC Access for Data Format Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures DAC operation mode * * This function configures a particular DAC channel pair to be operating * normal or disabled. * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \param chanPair [IN] Internal DAC channel pair * Use DAC_CHANP_1_2 to DAC_CHANP_7_8 for * individual DAC channel pair configuration * Use DAC_CHANP_ALL to set operation mode * for all DAC channels * * \param opMode [IN] DAC operation mode * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacSetOpMode(DacDevId devId, DacChanPair chanPair, DacOpMode opMode) { DAC_RET retVal; Uint8 modeCtrl; Uint8 id; IFPRINT(platform_write("platformAudioDacSetOpMode Called \n")); /* Check input parameters */ if( !( ((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL)) && ((chanPair >= DAC_CHANP_1_2) && (chanPair <= DAC_CHANP_ALL)) && ((opMode == DAC_OPMODE_NORMAL) || (opMode == DAC_OPMODE_DISABLED)) ) ) { IFPRINT(platform_write("platformAudioDacSetOpMode : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } if(chanPair == DAC_CHANP_ALL) { modeCtrl = 0xF; } else { modeCtrl = (1 << chanPair); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { if(opMode == DAC_OPMODE_DISABLED) { retVal = pcm169xDisableDacOpeartion(gDacI2cAddr[id], modeCtrl); } else { retVal = pcm169xEnableDacOpeartion(gDacI2cAddr[id], modeCtrl); } if(retVal) { IFPRINT(platform_write("platformAudioDacSetOpMode : DAC Access for Opmode Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures DAC filter roll-off * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \param chanPair [IN] Internal DAC channel pair * Use DAC_CHANP_1_2 to DAC_CHANP_7_8 for * individual DAC channel pair configuration * Use DAC_CHANP_ALL to set filter roll-off * for all DAC channels * * \param rolloff [IN] Roll-off configuration * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacSetFilterRolloff(DacDevId devId, DacChanPair chanPair, DacFilterRolloff rolloff) { DAC_RET retVal; Uint8 chanId; Uint8 id; IFPRINT(platform_write("platformAudioDacSetFilterRolloff Called \n")); /* Check input parameters */ if( !( ((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL)) && ((chanPair >= DAC_CHANP_1_2) && (chanPair <= DAC_CHANP_ALL)) && ((rolloff >= DAC_FILTER_SHARP_ROLLOFF) && (rolloff <= DAC_FILTER_SLOW_ROLLOFF)) ) ) { IFPRINT(platform_write("platformAudioDacSetFilterRolloff : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } if(chanPair == DAC_CHANP_ALL) { chanId = 0xF; } else { chanId = (1 << chanPair); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { retVal = pcm169xSetFilterRolloff(gDacI2cAddr[id], chanId, (Uint8)rolloff); if(retVal) { IFPRINT(platform_write("platformAudioDacSetFilterRolloff : DAC Access for Filter Roll-off Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures phase of the DAC analog signal outputs * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \param chanId [IN] Internal DAC channel Id * Use DAC_CHAN_1 to DAC_CHAN_8 for individual * DAC channel configuration * Use DAC_CHAN_ALL to set output phase for all * DAC channels * * \param outPhase [IN] Output phase selection * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacSetOutputPhase(DacDevId devId, DacChanId chanId, DacOutputPhase outPhase) { DAC_RET retVal; Uint8 chan; Uint8 id; IFPRINT(platform_write("platformAudioDacSetOutputPhase Called \n")); /* Check input parameters */ if( !( ((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL)) && ((chanId >= DAC_CHAN_1) && (chanId <= DAC_CHAN_ALL)) && ((outPhase >= DAC_OUTPUT_PHASE_NORMAL) && (outPhase <= DAC_OUTPUT_PHASE_INVERTED)) ) ) { IFPRINT(platform_write("platformAudioDacSetOutputPhase : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } if(chanId == DAC_CHAN_ALL) { chan = 0xFF; } else { chan = (1 << chanId); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { retVal = pcm169xSetOutputPhase(gDacI2cAddr[id], chan, (Uint8)outPhase); if(retVal) { IFPRINT(platform_write("platformAudioDacSetOutputPhase : DAC Access for Output Phase Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Soft mute function control * * The Soft mute function allows mute/unmute of DAC output in gradual steps. * This configuration reduces pop and zipper noise during muting of the * DAC output. * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \param chanId [IN] Internal DAC channel Id * Use DAC_CHAN_1 to DAC_CHAN_8 for individual * DAC channel configuration * Use DAC_CHAN_ALL to mute/unmute all DAC * channels * * \param muteEnable [IN] Mute enable flag * 0 for unmute and 1 for mute * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacSoftMuteCtrl(DacDevId devId, DacChanId chanId, uint8_t muteEnable) { DAC_RET retVal; Uint8 chan; Uint8 id; IFPRINT(platform_write("platformAudioDacSoftMuteCtrl Called \n")); /* Check input parameters */ if( !( ((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL)) && ((chanId >= DAC_CHAN_1) && (chanId <= DAC_CHAN_ALL)) && ((muteEnable == 0) || (muteEnable == 1)) ) ) { IFPRINT(platform_write("platformAudioDacSoftMuteCtrl : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } if(chanId == DAC_CHAN_ALL) { chan = 0xFF; } else { chan = (1 << chanId); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { retVal = pcm169xSoftMuteCtrl(gDacI2cAddr[id], chan, muteEnable); if(retVal) { IFPRINT(platform_write("platformAudioDacSoftMuteCtrl : DAC Access for Soft Mute Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Sets attenuation mode * * DAC module supports two types of volume/attenuation dB range * which can be changed by setting attenuation mode. Volume range and fine * tuning will change based on the attenuation mode. * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \param attnMode [IN] Attenuation mode * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacSetAttnMode(DacDevId devId, DacAttnMode attnMode) { DAC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioDacSetAttnMode Called \n")); /* Check input parameters */ if( !( ((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL)) && ((attnMode >= DAC_ATTENUATION_FINE_STEP) && (attnMode <= DAC_ATTENUATION_WIDE_RANGE)) ) ) { IFPRINT(platform_write("platformAudioDacSetAttnMode : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { retVal = pcm169xSetAttnMode(gDacI2cAddr[id], (Uint8)attnMode); if(retVal) { IFPRINT(platform_write("platformAudioDacSetAttnMode : DAC Access for Attenuation Mode Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Function to control digital de-emphasis functionality * * Disables/Enables the various sampling frequencies of the digital * de-emphasis function. * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \param deempCtrl [IN] De-emphasis control options * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacDeempCtrl(DacDevId devId, DacDeempCtrl deempCtrl) { DAC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioDacDeempCtrl Called \n")); /* Check input parameters */ if( !( ((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL)) && ((deempCtrl >= DAC_DEEMP_DISABLE) && (deempCtrl <= DAC_DEEMP_32KHZ)) ) ) { IFPRINT(platform_write("platformAudioDacDeempCtrl : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { retVal = pcm169xDeempCtrl(gDacI2cAddr[id], (Uint8)deempCtrl); if(retVal) { IFPRINT(platform_write("platformAudioDacDeempCtrl : DAC Access for De-emphasis Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures DAC volume/attenuation * * Range of the volume is exposed as percentage by this API. Volume * is indicated as percentage of maximum value ranging from 0 to 100. * 0 to mute the volume and 100 to set maximum volume * * DAC module supports two types of volume/attenuation dB range * which can be changed using platformAudioDacSetAttnMode(). * Volume range and fine tuning will change based on the attenuation mode. * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \param chanId [IN] Internal DAC channel Id * Use DAC_CHAN_1 to DAC_CHAN_8 for individual * DAC channel configuration * Use DAC_CHAN_ALL to mute/unmute all DAC * channels * * \param volume [IN] Volume in percentage; 0 to 100 * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacSetVolume(DacDevId devId, DacChanId chanId, uint8_t volume) { DAC_RET retVal; Uint8 id; Uint8 chan; IFPRINT(platform_write("platformAudioDacSetVolume Called \n")); /* Check input parameters */ if( !( ((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL)) && ((chanId >= DAC_CHAN_1) && (chanId <= DAC_CHAN_ALL)) && (volume <= 100) ) ) { IFPRINT(platform_write("platformAudioDacSetVolume : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } if(chanId == DAC_CHAN_ALL) { chan = 0xF; } else { chan = chanId; } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { retVal = pcm169xSetVolume(gDacI2cAddr[id], (Uint8)volume, chan); if(retVal) { IFPRINT(platform_write("platformAudioDacSetVolume : DAC Access for Volume Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Configures DAC power-save mode * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \param PowerMode [IN] Power-save mode control * 0 - Enable power-save mode * 1 - Disable power-save mode * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacSetPowerMode(DacDevId devId, uint8_t PowerMode) { DAC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioDacSetPowerMode Called \n")); /* Check input parameters */ if( !( ((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL)) && ((PowerMode == 0) || (PowerMode == 1)) ) ) { IFPRINT(platform_write("platformAudioDacSetPowerMode : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { retVal = pcm169xSetPowerMode(gDacI2cAddr[id], PowerMode); if(retVal) { IFPRINT(platform_write("platformAudioDacSetPowerMode : DAC Access for Power-save Mode Config Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_CFG; return (Platform_EFAIL); } } } return (Platform_EOK); } /** * \brief Displays DAC register programmed values * * This function is provided for debug purpose to read the value * of DAC registers. Values read from the DAC registers will be displayed * in CCS output window or serial terminal based on the system level * configuration for debug messages. * * \param devId [IN] Device ID of DAC HW instance * Use 'DAC_DEVICE_ALL' to apply the configuration * for all the DAC devices available. * * \return Platform_EOK on Success or error code */ Platform_STATUS platformAudioDacGetRegDump(DacDevId devId) { DAC_RET retVal; Uint8 id; IFPRINT(platform_write("platformAudioDacGetRegDump Called \n")); if(!((devId >= DAC_DEVICE_0) && (devId <= DAC_DEVICE_ALL))) { IFPRINT(platform_write("platformAudioDacGetRegDump : Invalid Inputs\n")); platform_errno = PLATFORM_ERRNO_INVALID_ARGUMENT; return (Platform_EINVALID); } for (id = DAC_DEVICE_0; id < DAC_DEVICE_ALL; id++) { if((id == devId) || (devId == DAC_DEVICE_ALL)) { retVal = pcm169xRegDump(gDacI2cAddr[id]); if(retVal) { IFPRINT(platform_write("platformAudioDacGetRegDump : DAC Access for Reg Dump Failed \n")); platform_errno = PLATFORM_ERRNO_AUDIO_STATUS; return (Platform_EFAIL); } } } return (Platform_EOK); } #endif /* #if (PLATFORM_AUDIO_DAC) */ #if (PLATFORM_AUDIO_DIR) /** * \brief Initializes DIR module * * Configures GPIOs and other settings required for DIR module operation. * This function should be called before calling any other DIR functions. * * \return Platform_EOK on Success or error code * */ Platform_STATUS platformAudioDirInit(void) { IFPRINT(platform_write("platformAudioDirInit Called \n")); /* Configure each SOC_GPIO pin connected to DIR status lines as GPIO and input */ /* DIR RST signal - GPIO 1, pin 9 */ pinMuxSetMode(PLATFORM_AUDIO_DIR_RST_PADCFG, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_1, PLATFORM_AUDIO_DIR_RST_GPIO, GPIO_OUT); gpioSetOutput(GPIO_PORT_1, PLATFORM_AUDIO_DIR_RST_GPIO); /* DIR AUDIO signal - GPIO 0, pin 134 */ pinMuxSetMode(PLATFORM_AUDIO_DIR_AUDIO_PADCFG, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_0, PLATFORM_AUDIO_DIR_AUDIO_GPIO, GPIO_IN); /* DIR EMPH signal - GPIO 0, pin 135 */ pinMuxSetMode(PLATFORM_AUDIO_DIR_EMPH_PADCFG, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_0, PLATFORM_AUDIO_DIR_EMPH_GPIO, GPIO_IN); /* DIR ERROR signal - GPIO 0, pin 136 */ pinMuxSetMode(PLATFORM_AUDIO_DIR_ERR_PADCFG, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_0, PLATFORM_AUDIO_DIR_ERR_GPIO, GPIO_IN); /* DIR CLKST signal - GPIO 0, pin 133 */ pinMuxSetMode(PLATFORM_AUDIO_DIR_CLKST_PADCFG, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_0, PLATFORM_AUDIO_DIR_CLKST_GPIO, GPIO_IN); /* DIR FSOUT0 signal - GPIO 0, pin 124 */ pinMuxSetMode(PLATFORM_AUDIO_DIR_FSOUT0_PADCFG, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_0, PLATFORM_AUDIO_DIR_FSOUT0_GPIO, GPIO_IN); /* DIR FSOUT1 signal - GPIO 0, pin 15 */ pinMuxSetMode(PLATFORM_AUDIO_DIR_FSOUT1_PADCFG, PADCONFIG_MUX_MODE_QUATERNARY); gpioSetDirection(GPIO_PORT_0, PLATFORM_AUDIO_DIR_FSOUT1_GPIO, GPIO_IN); #if 0 /* Reset DIR */ gpioClearOutput(GPIO_PORT_1, PLATFORM_AUDIO_DIR_RST_GPIO); /* DIR Reset signal should be low for at least 100 ns. Adding a delay of 1usec */ platform_delay(1); gpioSetOutput(GPIO_PORT_1, PLATFORM_AUDIO_DIR_RST_GPIO); #endif return (Platform_EOK); } /** * \brief Resets DIR module * * \return Platform_EOK on Success or error code * */ Platform_STATUS platformAudioDirReset(void) { IFPRINT(platform_write("platformAudioDirReset Called \n")); gpioClearOutput(GPIO_PORT_1, PLATFORM_AUDIO_DIR_RST_GPIO); /* DIR Reset signal should be low for at least 100 ns. Adding a delay of 1usec */ platform_delay(1); gpioSetOutput(GPIO_PORT_1, PLATFORM_AUDIO_DIR_RST_GPIO); return(Platform_EOK); } /** * \brief Reads AUDIO output status value of the DIR * * DIR AUDIO output pin gives the audio sample word information * of the channel-status data bit 1 * * \return AUDIO pin output with below possible values * \n 0 - Audio sample word represents linear PCM samples * \n 1 - Audio sample word is used for other purposes */ int8_t platformAudioDirGetAudioStatus(void) { int8_t audio; IFPRINT(platform_write("platformAudioDirGetAudioStatus Called \n")); audio = gpioReadInput(GPIO_PORT_0, PLATFORM_AUDIO_DIR_AUDIO_GPIO); return(audio); } /** * \brief Reads EMPH output status value of the DIR * * DIR EMPH output pin gives the emphasis information of the * channel-status data bit 3. * * \return EMPH pin output with below possible values * \n 0 - Two audio channels without pre-emphasis * \n 1 - Two audio channels with 50 ms / 15 ms pre-emphasis */ int8_t platformAudioDirGetEmphStatus(void) { int8_t emph; IFPRINT(platform_write("platformAudioDirGetEmphStatus Called \n")); emph = gpioReadInput(GPIO_PORT_0, PLATFORM_AUDIO_DIR_EMPH_GPIO); return(emph); } /** * \brief Reads ERROR pin status value of the DIR * * DIR ERROR output pin gives the error state of data and parity errors. * * \return EMPH pin output with below possible values * \n 0 - Lock state of PLL and nondetection of parity error * \n 1 - Unlock state of PLL or detection of parity error */ int8_t platformAudioDirGetErrStatus(void) { int8_t err; IFPRINT(platform_write("platformAudioDirGetErrStatus Called \n")); err = gpioReadInput(GPIO_PORT_0, PLATFORM_AUDIO_DIR_ERR_GPIO); return(err); } /** * \brief Reads CLKST pin status value of the DIR * * DIR CLKST pin outputs the PLL status change between LOCK and UNLOCK. * The CLKST output pulse depends only on the status change of the PLL. * * \return EMPH pin output with below possible values * \n 0 - Lock state of PLL and nondetection of parity error * \n 1 - Unlock state of PLL or detection of parity error */ int8_t platformAudioDirGetClkStatus(void) { int8_t clk; IFPRINT(platform_write("platformAudioDirGetClkStatus Called \n")); clk = gpioReadInput(GPIO_PORT_0, PLATFORM_AUDIO_DIR_CLKST_GPIO); return(clk); } /** * \brief Reads FSOUT[1:0] output status value of the DIR * * The DIR module calculates the actual sampling frequency of the * biphase input signal and outputs its result through FSOUT[1:0] pins. * * \return FSOUT pin output with below possible values * \n 0 - Calculated Sampling Frequency Output is 43 kHz–45.2 kHz * \n 1 - Calculated Sampling Frequency Output is 46.8 kHz–49.2 kHz * \n 2 - Out of range or PLL unlocked * \n 3 - Calculated Sampling Frequency Output is 31.2 kHz–32.8 kHz */ int8_t platformAudioDirGetFsOut(void) { int8_t fsout; IFPRINT(platform_write("platformAudioDirGetFsOut Called \n")); fsout = gpioReadInput(GPIO_PORT_0, PLATFORM_AUDIO_DIR_FSOUT1_GPIO); fsout <<= 1; fsout |= gpioReadInput(GPIO_PORT_0, PLATFORM_AUDIO_DIR_FSOUT0_GPIO); return(fsout); } #endif /* #if (PLATFORM_AUDIO_DIR) */ #endif /* #if (PLATFORM_AUDIO) */ /* Nothing past this point */