⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmic_audio.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                }
            }

            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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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 + -