📄 pmic_audio.cpp
字号:
}
}
if (rc != PMIC_ERROR)
{
reg_value = SET_BITS(regAUDIO_CODEC, CDCSSISEL, busID) |
SET_BITS(regAUDIO_CODEC, CDCFS, protocol) |
SET_BITS(regAUDIO_CODEC, CDCSM, masterSlave);
if (masterSlave == BUS_MASTER_MODE)
{
reg_value |= SET_BITS(regAUDIO_CODEC, CDCCLKEN, 1);
}
rc = pmic_write_reg(REG_AUDIO_CODEC, reg_value,
VCODEC_MASK | regAUDIO_CODEC.CDCFS.mask);
if (rc == PMIC_SUCCESS)
{
vCodec.busID = busID;
vCodec.protocol = protocol;
vCodec.masterSlave = masterSlave;
vCodec.numSlots = numSlots;
}
}
}
}
/* Exit critical section. */
up(mutex);
return rc;
}
/*!
* @brief Retrieve the current data bus protocol configuration.
*
* Retrieve the parameters that define the current audio data bus protocol.
*
* @param[in] handle Device handle from pmic_audio_open() call.
* @param[out] busID The data bus being used.
* @param[out] protocol The data bus protocol being used.
* @param[out] masterSlave The data bus timing mode being used.
* @param[out] numSlots The number of timeslots being used (if in
* master mode).
*
* @retval PMIC_SUCCESS If the protocol was successful retrieved.
* @retval PMIC_PARAMETER_ERROR If the handle is invalid.
*/
PMIC_STATUS PmicAudioGetProtocol(
const PMIC_AUDIO_HANDLE handle,
PMIC_AUDIO_DATA_BUS *const busID,
PMIC_AUDIO_BUS_PROTOCOL *const protocol,
PMIC_AUDIO_BUS_MODE *const masterSlave,
PMIC_AUDIO_NUMSLOTS *const numSlots)
{
PMIC_STATUS rc = PMIC_PARAMETER_ERROR;
if ((busID != (PMIC_AUDIO_DATA_BUS *)NULL) &&
(protocol != (PMIC_AUDIO_BUS_PROTOCOL *)NULL) &&
(masterSlave != (PMIC_AUDIO_BUS_MODE *)NULL) &&
(numSlots != (PMIC_AUDIO_NUMSLOTS *)NULL))
{
/* Enter a critical section so that we return a consistent state. */
down_interruptible(mutex);
if ((handle == stDAC.handle) &&
(stDAC.handleState == HANDLE_IN_USE))
{
*busID = stDAC.busID;
*protocol = stDAC.protocol;
*masterSlave = stDAC.masterSlave;
*numSlots = stDAC.numSlots;
rc = PMIC_SUCCESS;
}
else if ((handle == vCodec.handle) &&
(vCodec.handleState == HANDLE_IN_USE))
{
*busID = vCodec.busID;
*protocol = vCodec.protocol;
*masterSlave = vCodec.masterSlave;
*numSlots = vCodec.numSlots;
rc = PMIC_SUCCESS;
}
/* Exit critical section. */
up(mutex);
}
return rc;
}
/*!
* @brief Enable the Stereo DAC or the Voice CODEC.
*
* Explicitly enable the Stereo DAC or the Voice CODEC to begin audio
* playback or recording as required. This should only be done after
* successfully configuring all of the associated audio components (e.g.,
* microphones, amplifiers, etc.).
*
* Note that the timed delays used in this function are necessary to
* ensure reliable operation of the Voice CODEC and Stereo DAC. The
* Stereo DAC seems to be particularly sensitive and it has been observed
* to fail to generate the required master mode clock signals if it is
* not allowed enough time to initialize properly.
*
* @param[in] handle Device handle from pmic_audio_open() call.
*
* @retval PMIC_SUCCESS If the device was successful enabled.
* @retval PMIC_PARAMETER_ERROR If the handle is invalid.
* @retval PMIC_ERROR If the device could not be enabled.
*/
PMIC_STATUS PmicAudioEnable(
const PMIC_AUDIO_HANDLE handle)
{
const unsigned int AUDIO_BIAS_ENABLE = regRX0.BIASEN.mask;
const unsigned int STDAC_ENABLE = regSTEREO_DAC.STDCEN.mask |
regSTEREO_DAC.STDCRESET.mask;
const unsigned int VCODEC_ENABLE = regAUDIO_CODEC.CDCEN.mask |
regAUDIO_CODEC.CDCRESET.mask;
unsigned int reg_value = 0;
PMIC_STATUS rc = PMIC_PARAMETER_ERROR;
/* Use a critical section to ensure a consistent hardware state. */
down_interruptible(mutex);
if ((handle == stDAC.handle) && (stDAC.handleState == HANDLE_IN_USE))
{
/* Only set the audio bias enable if it is not already set. Since there
* is a significant delay associated with the audio bias ramp up, it is
* worth the effort to check first to see whether the audio bias has
* already been enabled. If so, then we can skip this step and its
* associated delay.
*/
pmic_read_reg(REG_RX0, ®_value);
if (!(reg_value & AUDIO_BIAS_ENABLE))
{
/* Must first set the audio bias bit to power up the audio
* circuits.
*/
pmic_write_reg(REG_RX0, AUDIO_BIAS_ENABLE, AUDIO_BIAS_ENABLE);
/* Pause for 150 ms to let the audio circuits ramp up. We must use
* TASK_UNINTERRUPTIBLE here because we want to delay for at least
* 150 ms.
*/
PmicAudioTimedDelay(150 * delay_1ms);
}
/* Also check if the Stereo DAC is already enabled and skip the register
* write and Stereo DAC enable delay if possible.
*/
pmic_read_reg(REG_STEREO_DAC, ®_value);
if (reg_value & STDAC_ENABLE)
{
/* The Stereo DAC is already enabled but we still need to reset
* the digital filter.
*/
rc = PmicAudioDigitalFilterReset(handle);
}
else
{
/* We must try to enable the Stereo DAC. */
rc = pmic_write_reg(REG_STEREO_DAC, STDAC_ENABLE, STDAC_ENABLE);
pmic_read_reg(REG_STEREO_DAC, ®_value);
if (!(reg_value & STDAC_ENABLE))
{
DEBUGMSG(ZONE_ERROR, (_T("Failed to enable the Stereo DAC\n")));
rc = PMIC_ERROR;
}
else
{
/* Pause for another 10 ms to let the hardware stabilize after
* enabling. We must use TASK_UNINTERRUPTIBLE here because we
* want to delay for at least 10 ms.
*/
PmicAudioTimedDelay(10 * delay_1ms);
}
}
}
else if ((handle == vCodec.handle) && (vCodec.handleState == HANDLE_IN_USE))
{
/* Only set the audio bias enable if it is not already set. Since there
* is a significant delay associated with the audio bias ramp up, it is
* worth the effort to check first to see whether the audio bias has
* already been enabled. If so, then we can skip this step and its
* associated delay.
*/
pmic_read_reg(REG_RX0, ®_value);
if (!(reg_value & AUDIO_BIAS_ENABLE))
{
/* Must first set the audio bias bit to power up the audio
* circuits.
*/
pmic_write_reg(REG_RX0, AUDIO_BIAS_ENABLE, AUDIO_BIAS_ENABLE);
/* Pause for 150 ms to let the audio circuits ramp up. We must use
* TASK_UNINTERRUPTIBLE here because we want to delay for at least
* 150 ms.
*/
PmicAudioTimedDelay(150 * delay_1ms);
}
/* Also check if the Voice CODEC is already enabled and skip the
* register write and Voice CODEC enable delay if possible.
*/
pmic_read_reg(REG_AUDIO_CODEC, ®_value);
if (reg_value & VCODEC_ENABLE)
{
/* The Voice CODEC is already enabled but we still need to reset
* the digital filter.
*/
rc = PmicAudioDigitalFilterReset(handle);
}
else
{
/* We must try to enable the Voice CODEC. */
rc = pmic_write_reg(REG_AUDIO_CODEC, VCODEC_ENABLE, VCODEC_ENABLE);
pmic_read_reg(REG_AUDIO_CODEC, ®_value);
if (!(reg_value & SET_BITS(regAUDIO_CODEC, CDCEN, 1)))
{
DEBUGMSG(ZONE_ERROR, (_T("Failed to enable the Voice ")
_T("CODEC\n")));
rc = PMIC_ERROR;
}
else
{
/* Pause for another 10 ms to let the hardware stabilize after
* enabling. We must use TASK_UNINTERRUPTIBLE here because we
* want to delay for at least 10 ms.
*/
PmicAudioTimedDelay(10 * delay_1ms);
}
}
}
/* Exit critical section. */
up(mutex);
return rc;
}
/*!
* @brief Disable the Stereo DAC or the Voice CODEC.
*
* Explicitly disable the Stereo DAC or the Voice CODEC to end audio
* playback or recording as required.
*
* @param[in] handle Device handle from pmic_audio_open() call.
*
* @retval PMIC_SUCCESS If the device was successful disabled.
* @retval PMIC_PARAMETER_ERROR If the handle is invalid.
* @retval PMIC_ERROR If the device could not be disabled.
*/
PMIC_STATUS PmicAudioDisable(
const PMIC_AUDIO_HANDLE handle)
{
PMIC_STATUS rc = PMIC_PARAMETER_ERROR;
const unsigned int AUDIO_BIAS_ENABLE = regRX0.BIASEN.mask;
const unsigned int STDAC_DISABLE = regSTEREO_DAC.STDCEN.mask;
const unsigned int VCODEC_DISABLE = regAUDIO_CODEC.CDCEN.mask;
/* Use a critical section to ensure a consistent hardware state. */
down_interruptible(mutex);
if ((handle == stDAC.handle) && (stDAC.handleState == HANDLE_IN_USE))
{
rc = pmic_write_reg(REG_STEREO_DAC, 0, STDAC_DISABLE);
}
else if ((handle == vCodec.handle) && (vCodec.handleState == HANDLE_IN_USE))
{
rc = pmic_write_reg(REG_AUDIO_CODEC, 0, VCODEC_DISABLE);
}
/* We can also power down all of the audio circuits to minimize power
* usage if no device handles are currently active.
*/
if ((stDAC.handleState == HANDLE_FREE) &&
(vCodec.handleState == HANDLE_FREE) &&
(extStereoIn.handleState == HANDLE_FREE))
{
/* Yes, we can power down all of the audio circuits. */
pmic_write_reg(REG_RX0, 0, AUDIO_BIAS_ENABLE);
}
/* Exit critical section. */
up(mutex);
return r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -