691 lines
21 KiB
C
691 lines
21 KiB
C
/*
|
|
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
|
* Copyright 2016-2020 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "fsl_dialog7212.h"
|
|
|
|
/*******************************************************************************
|
|
* Definitations
|
|
******************************************************************************/
|
|
/*! @brief da7212 reigster structure */
|
|
typedef struct _da7212_register_value
|
|
{
|
|
uint8_t addr;
|
|
uint8_t value;
|
|
} da7212_register_value_t;
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
/*!
|
|
* @brief DA7212 modify register.
|
|
*
|
|
* @param handle DA7212 handle structure.
|
|
* @param reg register address.
|
|
* @param mask register bits mask.
|
|
* @param value value to write.
|
|
* @return kStatus_Success, else failed.
|
|
*/
|
|
static status_t DA7212_ModifyRegister(da7212_handle_t *handle, uint8_t reg, uint8_t mask, uint8_t value);
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
static const da7212_register_value_t kInputRegisterSequence[kDA7212_Input_MAX][17] = {
|
|
/* DA7212_Input_AUX */
|
|
{
|
|
{DIALOG7212_MIXIN_L_SELECT, 0x01},
|
|
{DIALOG7212_MIXIN_R_SELECT, 0x01},
|
|
{DIALOG7212_CP_CTRL, 0xFD},
|
|
{DIALOG7212_AUX_L_CTRL, 0xB4},
|
|
{DIALOG7212_AUX_R_CTRL, 0xB0},
|
|
{DIALOG7212_MIC_1_CTRL, 0x04},
|
|
{DIALOG7212_MIC_2_CTRL, 0x04},
|
|
{DIALOG7212_MIXIN_L_CTRL, 0x88},
|
|
{DIALOG7212_MIXIN_R_CTRL, 0x88},
|
|
{DIALOG7212_ADC_L_CTRL, 0xA0},
|
|
{DIALOG7212_GAIN_RAMP_CTRL, 0x02},
|
|
{DIALOG7212_PC_COUNT, 0x02},
|
|
{DIALOG7212_CP_DELAY, 0x95},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0},
|
|
},
|
|
/* DA7212_Input_MIC1_Dig */
|
|
{
|
|
{DIALOG7212_MICBIAS_CTRL, 0xA9},
|
|
{DIALOG7212_CP_CTRL, 0xF1},
|
|
{DIALOG7212_MIXIN_L_SELECT, 0x80},
|
|
{DIALOG7212_MIXIN_R_SELECT, 0x80},
|
|
{DIALOG7212_SYSTEM_MODES_INPUT, 0xFE},
|
|
{DIALOG7212_SYSTEM_MODES_OUTPUT, 0xF7},
|
|
{DIALOG7212_MIC_CONFIG, 0x07},
|
|
{DIALOG7212_MIC_2_GAIN, 0x04},
|
|
{DIALOG7212_MIC_2_CTRL, 0x84},
|
|
{DIALOG7212_MIC_1_GAIN, 0x01},
|
|
{DIALOG7212_MIC_1_CTRL, 0x80},
|
|
{DIALOG7212_ADC_FILTERS1, 0x08},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0},
|
|
},
|
|
/* DA7212_Input_MIC1_An */
|
|
{
|
|
{DIALOG7212_MIXIN_L_SELECT, 0x02},
|
|
{DIALOG7212_MIXIN_R_SELECT, 0x04},
|
|
{DIALOG7212_MIC_1_GAIN, 0x03},
|
|
{DIALOG7212_CP_CTRL, 0xFD},
|
|
{DIALOG7212_MIXOUT_L_SELECT, 0x08},
|
|
{DIALOG7212_MIXOUT_R_SELECT, 0x08},
|
|
{DIALOG7212_AUX_R_CTRL, 0x40},
|
|
{DIALOG7212_MICBIAS_CTRL, 0x19},
|
|
{DIALOG7212_MIC_1_CTRL, 0x84},
|
|
{DIALOG7212_MIC_2_CTRL, 0x04},
|
|
{DIALOG7212_MIXIN_L_CTRL, 0x88},
|
|
{DIALOG7212_MIXIN_R_CTRL, 0x88},
|
|
{DIALOG7212_ADC_L_CTRL, 0xA0},
|
|
{DIALOG7212_GAIN_RAMP_CTRL, 0x02},
|
|
{DIALOG7212_PC_COUNT, 0x02},
|
|
{DIALOG7212_CP_DELAY, 0x95},
|
|
{0, 0},
|
|
},
|
|
/* DA7212_Input_MIC2 */
|
|
{
|
|
{DIALOG7212_MIXIN_L_SELECT, 0x04},
|
|
{DIALOG7212_MIXIN_R_SELECT, 0x02},
|
|
{DIALOG7212_MIC_2_GAIN, 0x04},
|
|
{DIALOG7212_CP_CTRL, 0xFD},
|
|
{DIALOG7212_AUX_R_CTRL, 0x40},
|
|
{DIALOG7212_MICBIAS_CTRL, 0x91},
|
|
{DIALOG7212_MIC_1_CTRL, 0x08},
|
|
{DIALOG7212_MIC_2_CTRL, 0x84},
|
|
{DIALOG7212_MIXIN_L_CTRL, 0x88},
|
|
{DIALOG7212_MIXIN_R_CTRL, 0x88},
|
|
{DIALOG7212_ADC_L_CTRL, 0xA0},
|
|
{DIALOG7212_GAIN_RAMP_CTRL, 0x02},
|
|
{DIALOG7212_PC_COUNT, 0x02},
|
|
{DIALOG7212_CP_DELAY, 0x95},
|
|
{0, 0},
|
|
{0, 0},
|
|
{0, 0},
|
|
}};
|
|
|
|
static const da7212_register_value_t kOutputRegisterSequence[kDA7212_Output_MAX][4] = {
|
|
/* DA7212_Output_HP */
|
|
{
|
|
{DIALOG7212_CP_CTRL, 0xF9},
|
|
{DIALOG7212_LINE_CTRL, 0},
|
|
{DIALOG7212_HP_L_CTRL, (DIALOG7212_HP_L_CTRL_AMP_EN_MASK | DIALOG7212_HP_L_CTRL_AMP_RAMP_EN_MASK |
|
|
DIALOG7212_HP_L_CTRL_AMP_ZC_EN_MASK | DIALOG7212_HP_L_CTRL_AMP_OE_MASK)},
|
|
{DIALOG7212_HP_R_CTRL, (DIALOG7212_HP_R_CTRL_AMP_EN_MASK | DIALOG7212_HP_R_CTRL_AMP_RAMP_EN_MASK |
|
|
DIALOG7212_HP_R_CTRL_AMP_ZC_EN_MASK | DIALOG7212_HP_R_CTRL_AMP_OE_MASK)},
|
|
},
|
|
/* DA7212_Output_SP */
|
|
{
|
|
{DIALOG7212_CP_CTRL, 0x3D},
|
|
{DIALOG7212_HP_L_CTRL, 0x40},
|
|
{DIALOG7212_HP_R_CTRL, 0x40},
|
|
{DIALOG7212_LINE_CTRL, 0xA8},
|
|
}};
|
|
|
|
static const da7212_register_value_t kInitRegisterSequence[DA7212_INIT_SIZE] = {
|
|
{
|
|
DIALOG7212_CIF_CTRL,
|
|
0x80,
|
|
},
|
|
{
|
|
DIALOG7212_DIG_ROUTING_DAI,
|
|
0x10,
|
|
},
|
|
{
|
|
DIALOG7212_SR,
|
|
DIALOG7212_SR_16KHZ,
|
|
},
|
|
{
|
|
DIALOG7212_REFERENCES,
|
|
DIALOG7212_REFERENCES_BIAS_EN_MASK,
|
|
},
|
|
{
|
|
DIALOG7212_PLL_FRAC_TOP,
|
|
CLEAR_REGISTER,
|
|
},
|
|
{
|
|
DIALOG7212_PLL_FRAC_BOT,
|
|
CLEAR_REGISTER,
|
|
},
|
|
{
|
|
DIALOG7212_PLL_INTEGER,
|
|
0x20,
|
|
},
|
|
{
|
|
DIALOG7212_PLL_CTRL,
|
|
0U,
|
|
},
|
|
{
|
|
DIALOG7212_DAI_CLK_MODE,
|
|
(DIALOG7212_DAI_BCLKS_PER_WCLK_BCLK64),
|
|
},
|
|
{
|
|
DIALOG7212_DAI_CTRL,
|
|
(DIALOG7212_DAI_EN_MASK | DIALOG7212_DAI_OE_MASK | DIALOG7212_DAI_WORD_LENGTH_16B |
|
|
DIALOG7212_DAI_FORMAT_I2S_MODE),
|
|
},
|
|
{
|
|
DIALOG7212_DIG_ROUTING_DAC,
|
|
(DIALOG7212_DIG_ROUTING_DAC_R_RSC_DAC_R | DIALOG7212_DIG_ROUTING_DAC_L_RSC_DAC_L),
|
|
},
|
|
{
|
|
DIALOG7212_CP_CTRL,
|
|
(DIALOG7212_CP_CTRL_EN_MASK | DIALOG7212_CP_CTRL_SMALL_SWIT_CH_FREQ_EN_MASK |
|
|
DIALOG7212_CP_CTRL_MCHANGE_OUTPUT | DIALOG7212_CP_CTRL_MOD_CPVDD_1 |
|
|
DIALOG7212_CP_CTRL_ANALOG_VLL_LV_BOOSTS_CP),
|
|
},
|
|
{
|
|
DIALOG7212_MIXOUT_L_SELECT,
|
|
(DIALOG7212_MIXOUT_L_SELECT_DAC_L_MASK),
|
|
},
|
|
{
|
|
DIALOG7212_MIXOUT_R_SELECT,
|
|
(DIALOG7212_MIXOUT_R_SELECT_DAC_R_MASK),
|
|
},
|
|
{
|
|
DIALOG7212_DAC_L_CTRL,
|
|
(DIALOG7212_DAC_L_CTRL_ADC_EN_MASK | DIALOG7212_DAC_L_CTRL_ADC_RAMP_EN_MASK),
|
|
},
|
|
{
|
|
DIALOG7212_DAC_R_CTRL,
|
|
(DIALOG7212_DAC_R_CTRL_ADC_EN_MASK | DIALOG7212_DAC_R_CTRL_ADC_RAMP_EN_MASK),
|
|
},
|
|
{
|
|
DIALOG7212_HP_L_CTRL,
|
|
(DIALOG7212_HP_L_CTRL_AMP_EN_MASK | DIALOG7212_HP_L_CTRL_AMP_RAMP_EN_MASK |
|
|
DIALOG7212_HP_L_CTRL_AMP_ZC_EN_MASK | DIALOG7212_HP_L_CTRL_AMP_OE_MASK),
|
|
},
|
|
{
|
|
DIALOG7212_HP_R_CTRL,
|
|
(DIALOG7212_HP_R_CTRL_AMP_EN_MASK | DIALOG7212_HP_R_CTRL_AMP_RAMP_EN_MASK |
|
|
DIALOG7212_HP_R_CTRL_AMP_ZC_EN_MASK | DIALOG7212_HP_R_CTRL_AMP_OE_MASK),
|
|
},
|
|
{
|
|
DIALOG7212_MIXOUT_L_CTRL,
|
|
(DIALOG7212_MIXOUT_L_CTRL_AMP_EN_MASK | DIALOG7212_MIXOUT_L_CTRL_AMP_SOFT_MIX_EN_MASK |
|
|
DIALOG7212_MIXOUT_L_CTRL_AMP_MIX_EN_MASK),
|
|
},
|
|
{
|
|
DIALOG7212_MIXOUT_R_CTRL,
|
|
(DIALOG7212_MIXOUT_R_CTRL_AMP_EN_MASK | DIALOG7212_MIXOUT_R_CTRL_AMP_SOFT_MIX_EN_MASK |
|
|
DIALOG7212_MIXOUT_R_CTRL_AMP_MIX_EN_MASK),
|
|
},
|
|
{
|
|
DIALOG7212_CP_VOL_THRESHOLD1,
|
|
DIALOG7212_CP_VOL_THRESHOLD1_VDD2(0x32),
|
|
},
|
|
{
|
|
DIALOG7212_SYSTEM_STATUS,
|
|
CLEAR_REGISTER,
|
|
},
|
|
{
|
|
DIALOG7212_DAC_L_GAIN,
|
|
(uint8_t)kDA7212_DACGainM6DB,
|
|
},
|
|
{
|
|
DIALOG7212_DAC_R_GAIN,
|
|
(uint8_t)kDA7212_DACGainM6DB,
|
|
},
|
|
{
|
|
DIALOG7212_MIXIN_L_SELECT,
|
|
DIALOG7212_MIXIN_L_SELECT_AUX_L_SEL_MASK,
|
|
},
|
|
{
|
|
DIALOG7212_MIXIN_R_SELECT,
|
|
DIALOG7212_MIXIN_R_SELECT_AUX_R_SEL_MASK,
|
|
},
|
|
{
|
|
DIALOG7212_MIXIN_L_GAIN,
|
|
DIALOG7212_MIXIN_L_AMP_GAIN(0x03),
|
|
},
|
|
{
|
|
DIALOG7212_MIXIN_R_GAIN,
|
|
DIALOG7212_MIXIN_R_AMP_GAIN(0x03),
|
|
},
|
|
{
|
|
DIALOG7212_ADC_L_GAIN,
|
|
DIALOG7212_ADC_L_DIGITAL_GAIN(0x6F),
|
|
},
|
|
{
|
|
DIALOG7212_ADC_R_GAIN,
|
|
DIALOG7212_ADC_R_DIGITAL_GAIN(0x6F),
|
|
},
|
|
{
|
|
DIALOG7212_AUX_L_CTRL,
|
|
DIALOG7212_AUX_L_CTRL_AMP_EN_MASK | DIALOG7212_AUX_L_CTRL_AMP_RAMP_EN_MASK |
|
|
DIALOG7212_AUX_L_CTRL_AMP_ZC_EN_MASK,
|
|
},
|
|
{
|
|
DIALOG7212_AUX_R_CTRL,
|
|
DIALOG7212_AUX_R_CTRL_AMP_EN_MASK | DIALOG7212_AUX_R_CTRL_AMP_RAMP_EN_MASK |
|
|
DIALOG7212_AUX_R_CTRL_AMP_ZC_EN_MASK,
|
|
},
|
|
{
|
|
DIALOG7212_MIXIN_L_CTRL,
|
|
DIALOG7212_MIXIN_L_CTRL_AMP_EN_MASK | DIALOG7212_MIXIN_L_CTRL_AMP_MIX_EN_MASK,
|
|
},
|
|
{
|
|
DIALOG7212_MIXIN_R_CTRL,
|
|
DIALOG7212_MIXIN_R_CTRL_AMP_EN_MASK | DIALOG7212_MIXIN_R_CTRL_AMP_MIX_EN_MASK,
|
|
},
|
|
{
|
|
DIALOG7212_ADC_L_CTRL,
|
|
DIALOG7212_ADC_L_CTRL_ADC_EN_MASK | DIALOG7212_ADC_L_CTRL_ADC_RAMP_EN_MASK,
|
|
},
|
|
{
|
|
DIALOG7212_ADC_R_CTRL,
|
|
DIALOG7212_ADC_R_CTRL_ADC_EN_MASK | DIALOG7212_ADC_R_CTRL_ADC_RAMP_EN_MASK,
|
|
},
|
|
};
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
status_t DA7212_WriteRegister(da7212_handle_t *handle, uint8_t u8Register, uint8_t u8RegisterData)
|
|
{
|
|
assert(handle->config);
|
|
assert(handle->config->slaveAddress != 0U);
|
|
|
|
uint8_t writeValue = u8RegisterData;
|
|
|
|
return CODEC_I2C_Send(handle->i2cHandle, handle->config->slaveAddress, u8Register, 1U, (uint8_t *)&writeValue, 1U);
|
|
}
|
|
|
|
status_t DA7212_ReadRegister(da7212_handle_t *handle, uint8_t u8Register, uint8_t *pu8RegisterData)
|
|
{
|
|
assert(handle->config);
|
|
assert(handle->config->slaveAddress != 0U);
|
|
|
|
return CODEC_I2C_Receive(handle->i2cHandle, handle->config->slaveAddress, u8Register, 1U,
|
|
(uint8_t *)pu8RegisterData, 1U);
|
|
}
|
|
|
|
static status_t DA7212_ModifyRegister(da7212_handle_t *handle, uint8_t reg, uint8_t mask, uint8_t value)
|
|
{
|
|
status_t result;
|
|
uint8_t regValue = 0;
|
|
|
|
result = DA7212_ReadRegister(handle, reg, ®Value);
|
|
if (result != kStatus_Success)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
regValue &= (uint8_t)~mask;
|
|
regValue |= value;
|
|
|
|
return DA7212_WriteRegister(handle, reg, regValue);
|
|
}
|
|
|
|
status_t DA7212_Init(da7212_handle_t *handle, da7212_config_t *codecConfig)
|
|
{
|
|
assert(codecConfig != NULL);
|
|
assert(handle != NULL);
|
|
|
|
uint32_t i = 0;
|
|
status_t error = kStatus_Success;
|
|
da7212_config_t *config = codecConfig;
|
|
uint32_t sysClock = config->format.mclk_HZ;
|
|
handle->config = config;
|
|
|
|
/* i2c bus initialization */
|
|
if (CODEC_I2C_Init(handle->i2cHandle, config->i2cConfig.codecI2CInstance, DA7212_I2C_BAUDRATE,
|
|
config->i2cConfig.codecI2CSourceClock) != (status_t)kStatus_HAL_I2cSuccess)
|
|
{
|
|
return kStatus_Fail;
|
|
}
|
|
|
|
/* If no config structure, use default settings */
|
|
for (i = 0; i < DA7212_INIT_SIZE; i++)
|
|
{
|
|
if ((DA7212_WriteRegister(handle, kInitRegisterSequence[i].addr, kInitRegisterSequence[i].value)) !=
|
|
kStatus_Success)
|
|
{
|
|
return kStatus_Fail;
|
|
}
|
|
}
|
|
|
|
if (config->isMaster)
|
|
{
|
|
/* clock configurations */
|
|
if ((DA7212_WriteRegister(handle, DIALOG7212_DAI_CLK_MODE,
|
|
(config->format.isBclkInvert ? 1U << 2U : 0U) | (1U << 7U))) != kStatus_Success)
|
|
{
|
|
return kStatus_Fail;
|
|
}
|
|
|
|
if (DA7212_SetMasterModeBits(handle, config->format.bitWidth) != kStatus_Success)
|
|
{
|
|
return kStatus_Fail;
|
|
}
|
|
}
|
|
|
|
/* Set DA7212 functionality */
|
|
if (config->dacSource == kDA7212_DACSourceADC)
|
|
{
|
|
if ((DA7212_WriteRegister(handle, DIALOG7212_DIG_ROUTING_DAC, 0x10)) != kStatus_Success)
|
|
{
|
|
return kStatus_Fail;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((DA7212_WriteRegister(handle, DIALOG7212_DIG_ROUTING_DAC, 0x32)) != kStatus_Success)
|
|
{
|
|
return kStatus_Fail;
|
|
}
|
|
}
|
|
|
|
/* Set the audio protocol */
|
|
if ((DA7212_WriteRegister(handle, DIALOG7212_DAI_CTRL,
|
|
(uint8_t)(DIALOG7212_DAI_EN_MASK | (uint8_t)(config->protocol)))) != kStatus_Success)
|
|
{
|
|
return kStatus_Fail;
|
|
}
|
|
|
|
if (codecConfig->sysClkSource == kDA7212_SysClkSourcePLL)
|
|
{
|
|
if (DA7212_SetPLLConfig(handle, codecConfig->pll) != kStatus_Success)
|
|
{
|
|
return kStatus_Fail;
|
|
}
|
|
|
|
sysClock = (uint32_t)(codecConfig->pll->outputClock_HZ);
|
|
}
|
|
|
|
DA7212_ChangeInput(handle, codecConfig->inputSource);
|
|
|
|
error = DA7212_ConfigAudioFormat(handle, sysClock, config->format.sampleRate, config->format.bitWidth);
|
|
|
|
return error;
|
|
}
|
|
|
|
status_t DA7212_SetPLLConfig(da7212_handle_t *handle, da7212_pll_config_t *config)
|
|
{
|
|
assert(config != NULL);
|
|
status_t retVal = kStatus_Success;
|
|
|
|
uint8_t indiv = 0, inputDiv = 0, regVal = 0;
|
|
uint64_t pllValue = 0;
|
|
uint32_t pllFractional;
|
|
uint8_t pllInteger;
|
|
uint8_t pllFracTop;
|
|
uint8_t pllFracBottom;
|
|
uint8_t pllEnMask = DIALOG7212_PLL_EN_MASK;
|
|
|
|
if (config->refClock_HZ == 32768U)
|
|
{
|
|
pllEnMask |= DIALOG7212_PLL_SRM_EN_MASK | DIALOG7212_PLL_32K_MODE_MASK;
|
|
indiv = DIALOG7212_PLL_INDIV_2_10MHZ;
|
|
inputDiv = 1;
|
|
}
|
|
/* Compute the PLL_INDIV and DIV value for sysClock */
|
|
else if ((config->refClock_HZ > 2000000U) && (config->refClock_HZ <= 10000000U))
|
|
{
|
|
indiv = DIALOG7212_PLL_INDIV_2_10MHZ;
|
|
inputDiv = 2;
|
|
}
|
|
else if ((config->refClock_HZ > 10000000U) && (config->refClock_HZ <= 20000000U))
|
|
{
|
|
indiv = DIALOG7212_PLL_INDIV_10_20MHZ;
|
|
inputDiv = 4;
|
|
}
|
|
else if ((config->refClock_HZ > 20000000U) && (config->refClock_HZ <= 40000000U))
|
|
{
|
|
indiv = DIALOG7212_PLL_INDIV_20_40MHZ;
|
|
inputDiv = 8;
|
|
}
|
|
else
|
|
{
|
|
indiv = DIALOG7212_PLL_INDIV_40_80MHZ;
|
|
inputDiv = 16;
|
|
}
|
|
|
|
/* PLL feedback divider is a Q13 value */
|
|
pllValue =
|
|
(uint64_t)(((uint64_t)((((uint64_t)config->outputClock_HZ * 8U) * inputDiv) << 13U)) / (config->refClock_HZ));
|
|
|
|
/* extract integer and fractional */
|
|
pllInteger = (uint8_t)(pllValue >> 13U);
|
|
pllFractional = (uint32_t)(pllValue - ((uint64_t)pllInteger << 13U));
|
|
pllFracTop = (uint8_t)(pllFractional >> 8U);
|
|
pllFracBottom = (uint8_t)(pllFractional & 0xFFU);
|
|
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_PLL_FRAC_TOP, pllFracTop);
|
|
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_PLL_FRAC_BOT, pllFracBottom);
|
|
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_PLL_INTEGER, pllInteger);
|
|
|
|
regVal = pllEnMask | indiv;
|
|
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_PLL_CTRL, regVal);
|
|
|
|
/* wait for PLL lock bits */
|
|
while ((regVal & 1U) == 0U)
|
|
{
|
|
retVal = DA7212_ReadRegister(handle, DIALOG7212_PLL_STATUS, ®Val);
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
status_t DA7212_SetProtocol(da7212_handle_t *handle, da7212_protocol_t protocol)
|
|
{
|
|
return DA7212_WriteRegister(handle, DIALOG7212_DAI_CTRL, (uint8_t)(DIALOG7212_DAI_EN_MASK | (uint8_t)protocol));
|
|
}
|
|
|
|
status_t DA7212_ConfigAudioFormat(da7212_handle_t *handle,
|
|
uint32_t masterClock_Hz,
|
|
uint32_t sampleRate_Hz,
|
|
uint32_t dataBits)
|
|
{
|
|
uint8_t regVal = 0;
|
|
status_t retVal = kStatus_Success;
|
|
|
|
switch (sampleRate_Hz)
|
|
{
|
|
case 8000:
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_SR, DIALOG7212_SR_8KHZ);
|
|
break;
|
|
case 11025:
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_SR, DIALOG7212_SR_11_025KHZ);
|
|
break;
|
|
case 12000:
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_SR, DIALOG7212_SR_12KHZ);
|
|
break;
|
|
case 16000:
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_SR, DIALOG7212_SR_16KHZ);
|
|
break;
|
|
case 22050:
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_SR, DIALOG7212_SR_22KHZ);
|
|
break;
|
|
case 24000:
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_SR, DIALOG7212_SR_24KHZ);
|
|
break;
|
|
case 32000:
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_SR, DIALOG7212_SR_32KHZ);
|
|
break;
|
|
case 44100:
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_SR, DIALOG7212_SR_44_1KHZ);
|
|
break;
|
|
case 48000:
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_SR, DIALOG7212_SR_48KHZ);
|
|
break;
|
|
case 88200:
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_SR, DIALOG7212_SR_88_2KHZ);
|
|
break;
|
|
case 96000:
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_SR, DIALOG7212_SR_96KHZ);
|
|
break;
|
|
default:
|
|
/* Avoid MISRA 16.4 violation */
|
|
break;
|
|
}
|
|
|
|
/* Set data bits of word */
|
|
retVal = DA7212_ReadRegister(handle, DIALOG7212_DAI_CTRL, ®Val);
|
|
regVal &= ~(uint8_t)DIALOG7212_DAI_WORD_LENGTH_MASK;
|
|
switch (dataBits)
|
|
{
|
|
case 16:
|
|
regVal |= (uint8_t)DIALOG7212_DAI_WORD_LENGTH_16B;
|
|
break;
|
|
case 20:
|
|
regVal |= (uint8_t)DIALOG7212_DAI_WORD_LENGTH_20B;
|
|
break;
|
|
case 24:
|
|
regVal |= (uint8_t)DIALOG7212_DAI_WORD_LENGTH_24B;
|
|
break;
|
|
case 32:
|
|
regVal |= (uint8_t)DIALOG7212_DAI_WORD_LENGTH_32B;
|
|
break;
|
|
default:
|
|
/* Avoid MISRA 16.4 violation */
|
|
break;
|
|
}
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_DAI_CTRL, regVal);
|
|
|
|
return retVal;
|
|
}
|
|
|
|
status_t DA7212_SetMasterModeBits(da7212_handle_t *handle, uint32_t bitWidth)
|
|
{
|
|
uint8_t regVal = 0U;
|
|
|
|
switch (bitWidth)
|
|
{
|
|
case 16:
|
|
regVal = 0U;
|
|
break;
|
|
case 32:
|
|
regVal = 1U;
|
|
break;
|
|
case 64:
|
|
regVal = 2U;
|
|
break;
|
|
case 128:
|
|
regVal = 3U;
|
|
break;
|
|
default:
|
|
assert(false);
|
|
break;
|
|
}
|
|
|
|
return DA7212_ModifyRegister(handle, DIALOG7212_DAI_CLK_MODE, 3, regVal);
|
|
}
|
|
|
|
void DA7212_ChangeInput(da7212_handle_t *handle, da7212_Input_t DA7212_Input)
|
|
{
|
|
uint32_t i = 0;
|
|
uint32_t seqSize = sizeof(kInputRegisterSequence[DA7212_Input]) / sizeof(da7212_register_value_t);
|
|
|
|
for (i = 0; i < seqSize; i++)
|
|
{
|
|
(void)DA7212_WriteRegister(handle, kInputRegisterSequence[DA7212_Input][i].addr,
|
|
kInputRegisterSequence[DA7212_Input][i].value);
|
|
}
|
|
}
|
|
|
|
void DA7212_ChangeOutput(da7212_handle_t *handle, da7212_Output_t DA7212_Output)
|
|
{
|
|
uint32_t i = 0;
|
|
uint32_t seqSize = sizeof(kOutputRegisterSequence[DA7212_Output]) / sizeof(da7212_register_value_t);
|
|
|
|
for (i = 0; i < seqSize; i++)
|
|
{
|
|
(void)DA7212_WriteRegister(handle, kOutputRegisterSequence[DA7212_Output][i].addr,
|
|
kOutputRegisterSequence[DA7212_Output][i].value);
|
|
}
|
|
}
|
|
|
|
void DA7212_ChangeHPVolume(da7212_handle_t *handle, da7212_volume_t volume)
|
|
{
|
|
(void)DA7212_WriteRegister(handle, DIALOG7212_DAC_L_GAIN, (uint8_t)volume);
|
|
(void)DA7212_WriteRegister(handle, DIALOG7212_DAC_R_GAIN, (uint8_t)volume);
|
|
}
|
|
|
|
void DA7212_Mute(da7212_handle_t *handle, bool isMuted)
|
|
{
|
|
uint8_t val = 0;
|
|
|
|
if (isMuted)
|
|
{
|
|
val = DA7212_DAC_MUTE_ENABLED;
|
|
}
|
|
else
|
|
{
|
|
val = DA7212_DAC_MUTE_DISABLED;
|
|
}
|
|
|
|
(void)DA7212_WriteRegister(handle, DIALOG7212_DAC_L_CTRL, val);
|
|
(void)DA7212_WriteRegister(handle, DIALOG7212_DAC_R_CTRL, val);
|
|
}
|
|
|
|
status_t DA7212_SetChannelVolume(da7212_handle_t *handle, uint32_t channel, uint32_t volume)
|
|
{
|
|
status_t retVal = kStatus_Success;
|
|
|
|
if (volume > DA7212_HEADPHONE_MAX_VOLUME_VALUE)
|
|
{
|
|
return kStatus_InvalidArgument;
|
|
}
|
|
|
|
if ((channel & (uint32_t)kDA7212_HeadphoneLeft) != 0U)
|
|
{
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_HP_L_GAIN, (uint8_t)volume);
|
|
}
|
|
|
|
if ((channel & (uint32_t)kDA7212_HeadphoneRight) != 0U)
|
|
{
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_HP_R_GAIN, (uint8_t)volume);
|
|
}
|
|
|
|
if ((channel & (uint32_t)kDA7212_Speaker) != 0U)
|
|
{
|
|
retVal = DA7212_WriteRegister(handle, DIALOG7212_LINE_GAIN, (uint8_t)volume);
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
status_t DA7212_SetChannelMute(da7212_handle_t *handle, uint32_t channel, bool isMute)
|
|
{
|
|
uint8_t regValue = isMute == true ? 0x40U : 0x80U;
|
|
status_t retVal = kStatus_Success;
|
|
|
|
if ((channel & (uint32_t)kDA7212_HeadphoneLeft) != 0U)
|
|
{
|
|
retVal = DA7212_ModifyRegister(handle, DIALOG7212_HP_L_CTRL, 0xC0U, regValue);
|
|
}
|
|
|
|
if ((channel & (uint32_t)kDA7212_HeadphoneRight) != 0U)
|
|
{
|
|
retVal = DA7212_ModifyRegister(handle, DIALOG7212_HP_R_CTRL, 0xC0U, regValue);
|
|
}
|
|
|
|
if ((channel & (uint32_t)kDA7212_Speaker) != 0U)
|
|
{
|
|
retVal = DA7212_ModifyRegister(handle, DIALOG7212_LINE_CTRL, 0xC0U, regValue);
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
status_t DA7212_Deinit(da7212_handle_t *handle)
|
|
{
|
|
return kStatus_Success;
|
|
}
|