diff --git a/arch/arm/include/cxd56xx/audio.h b/arch/arm/include/cxd56xx/audio.h new file mode 100644 index 00000000000..7653de2b929 --- /dev/null +++ b/arch/arm/include/cxd56xx/audio.h @@ -0,0 +1,946 @@ +/*************************************************************************** + * arch/arm/include/cxd56xx/audio.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/* audioutils Audio Utility + * + */ + +#ifndef __ARCH_ARM_INCLUDE_CXD56XX_CXD56_AUDIO_H +#define __ARCH_ARM_INCLUDE_CXD56XX_CXD56_AUDIO_H + +/* API Documents creater with Doxgen */ + +/* cxd56_audio_api Audio Driver API + * + * + * chip/cxd56_audio.h + * CXD5602 Audio Driver API + * CXD5602 Audio SW Team + */ + +/*************************************************************************** + * Included Files + ***************************************************************************/ + +#include +#include +#include + +/*************************************************************************** + * Pre-processor Definitions + ***************************************************************************/ + +/* Mic channel max. */ + +#define CXD56_AUDIO_MIC_CH_MAX 8 + +/* DNC binary size. */ + +#define CXD56_AUDIO_DNC_FW_SIZE 512 +#define CXD56_AUDIO_DNC_CFG_SIZE 128 + +/* DEQ band number. */ + +#define CXD56_AUDIO_DEQ_BAND_NUM 6 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* cxd56_audio common return code. */ + +#define CXD56_AUDIO_ECODE uint16_t + +#define CXD56_AUDIO_ECODE_OK 0x0000 +#define CXD56_AUDIO_ECODE_POW 0x1000 +#define CXD56_AUDIO_ECODE_FIL 0x2000 +#define CXD56_AUDIO_ECODE_MIC 0x3000 +#define CXD56_AUDIO_ECODE_VOL 0x4000 +#define CXD56_AUDIO_ECODE_DIG 0x5000 +#define CXD56_AUDIO_ECODE_BEP 0x6000 +#define CXD56_AUDIO_ECODE_INT 0x7000 +#define CXD56_AUDIO_ECODE_DMA 0x8000 +#define CXD56_AUDIO_ECODE_ANA 0x9000 +#define CXD56_AUDIO_ECODE_REG 0xA000 +#define CXD56_AUDIO_ECODE_CFG 0xB000 + +/* Error code of power */ + +#define CXD56_AUDIO_ECODE_POW_STATE (CXD56_AUDIO_ECODE_POW | 0x01) + +/* Error code of filter */ + +#define CXD56_AUDIO_ECODE_FIL_DNC_BIN (CXD56_AUDIO_ECODE_FIL | 0x01) + +/* Error code of mic */ + +#define CXD56_AUDIO_ECODE_MIC_NO_ANA (CXD56_AUDIO_ECODE_MIC | 0x01) +#define CXD56_AUDIO_ECODE_MIC_ARG_NULL (CXD56_AUDIO_ECODE_MIC | 0x02) + +/* Error code of volume */ + +#define CXD56_AUDIO_ECODE_VOL_ID (CXD56_AUDIO_ECODE_VOL | 0x01) +#define CXD56_AUDIO_ECODE_VOL_MAX (CXD56_AUDIO_ECODE_VOL | 0x02) +#define CXD56_AUDIO_ECODE_VOL_MIN (CXD56_AUDIO_ECODE_VOL | 0x03) + +/* Error code of digital */ + +/* Error code of beep */ + +#define CXD56_AUDIO_ECODE_BEP_FREQ_MAX (CXD56_AUDIO_ECODE_BEP | 0x01) +#define CXD56_AUDIO_ECODE_BEP_FREQ_MIN (CXD56_AUDIO_ECODE_BEP | 0x02) +#define CXD56_AUDIO_ECODE_BEP_VOL_MAX (CXD56_AUDIO_ECODE_BEP | 0x03) +#define CXD56_AUDIO_ECODE_BEP_VOL_MIN (CXD56_AUDIO_ECODE_BEP | 0x04) + +/* Error code of interrupt */ + +/* Error code of dma */ + +#define CXD56_AUDIO_ECODE_DMA_ARG_NULL (CXD56_AUDIO_ECODE_DMA | 0x01) +#define CXD56_AUDIO_ECODE_DMA_PATH_INV (CXD56_AUDIO_ECODE_DMA | 0x02) +#define CXD56_AUDIO_ECODE_DMA_PATH_COMB (CXD56_AUDIO_ECODE_DMA | 0x03) +#define CXD56_AUDIO_ECODE_DMA_PATH_DUP (CXD56_AUDIO_ECODE_DMA | 0x04) +#define CXD56_AUDIO_ECODE_DMA_PATH_MAX (CXD56_AUDIO_ECODE_DMA | 0x05) +#define CXD56_AUDIO_ECODE_DMA_HANDLE_NULL (CXD56_AUDIO_ECODE_DMA | 0x06) +#define CXD56_AUDIO_ECODE_DMA_HANDLE_INV (CXD56_AUDIO_ECODE_DMA | 0x07) +#define CXD56_AUDIO_ECODE_DMA_CH_NO_ENABLE (CXD56_AUDIO_ECODE_DMA | 0x08) +#define CXD56_AUDIO_ECODE_DMA_CH1_4_INV (CXD56_AUDIO_ECODE_DMA | 0x09) +#define CXD56_AUDIO_ECODE_DMA_CH5_8_INV (CXD56_AUDIO_ECODE_DMA | 0x0a) +#define CXD56_AUDIO_ECODE_DMA_SMP_TIMEOUT (CXD56_AUDIO_ECODE_DMA | 0x0b) +#define CXD56_AUDIO_ECODE_DMA_BUSY (CXD56_AUDIO_ECODE_DMA | 0x0c) + +#define CXD56_AUDIO_ECODE_DMA_CMPLT (CXD56_AUDIO_ECODE_DMA | 0x11) +#define CXD56_AUDIO_ECODE_DMA_TRANS (CXD56_AUDIO_ECODE_DMA | 0x12) +#define CXD56_AUDIO_ECODE_DMA_CMB (CXD56_AUDIO_ECODE_DMA | 0x13) + +/* Error code of analog */ + +#define CXD56_AUDIO_ECODE_ANA_DISABLE (CXD56_AUDIO_ECODE_ANA | 0x01) +#define CXD56_AUDIO_ECODE_ANA_PWON (CXD56_AUDIO_ECODE_ANA | 0x02) +#define CXD56_AUDIO_ECODE_ANA_PWOFF (CXD56_AUDIO_ECODE_ANA | 0x03) +#define CXD56_AUDIO_ECODE_ANA_CLK_EN (CXD56_AUDIO_ECODE_ANA | 0x04) +#define CXD56_AUDIO_ECODE_ANA_CHKID (CXD56_AUDIO_ECODE_ANA | 0x05) +#define CXD56_AUDIO_ECODE_ANA_SERIAL (CXD56_AUDIO_ECODE_ANA | 0x06) +#define CXD56_AUDIO_ECODE_ANA_PWON_MBIAS (CXD56_AUDIO_ECODE_ANA | 0x07) +#define CXD56_AUDIO_ECODE_ANA_PWON_INPUT (CXD56_AUDIO_ECODE_ANA | 0x08) +#define CXD56_AUDIO_ECODE_ANA_SET_SMASTER (CXD56_AUDIO_ECODE_ANA | 0x09) +#define CXD56_AUDIO_ECODE_ANA_PWON_OUTPUT (CXD56_AUDIO_ECODE_ANA | 0x0A) +#define CXD56_AUDIO_ECODE_ANA_PWOFF_INPUT (CXD56_AUDIO_ECODE_ANA | 0x0B) +#define CXD56_AUDIO_ECODE_ANA_PWOFF_OUTPUT (CXD56_AUDIO_ECODE_ANA | 0x0C) +#define CXD56_AUDIO_ECODE_ANA_ENABLE_OUTPUT (CXD56_AUDIO_ECODE_ANA | 0x0D) +#define CXD56_AUDIO_ECODE_ANA_DISABLE_OUTPUT (CXD56_AUDIO_ECODE_ANA | 0x0E) +#define CXD56_AUDIO_ECODE_ANA_SET_MICGAIN (CXD56_AUDIO_ECODE_ANA | 0x0F) +#define CXD56_AUDIO_ECODE_ANA_NOTIFY_MICBOOT (CXD56_AUDIO_ECODE_ANA | 0x10) + +/* Error code of register */ + +#define CXD56_AUDIO_ECODE_REG_AC (CXD56_AUDIO_ECODE_REG | 0x100) +#define CXD56_AUDIO_ECODE_REG_BCA (CXD56_AUDIO_ECODE_REG | 0x200) + +#define CXD56_AUDIO_ECODE_REG_AC_REVID (CXD56_AUDIO_ECODE_REG_AC | 0x01) +#define CXD56_AUDIO_ECODE_REG_AC_DEVID (CXD56_AUDIO_ECODE_REG_AC | 0x02) +#define CXD56_AUDIO_ECODE_REG_AC_MICMODE (CXD56_AUDIO_ECODE_REG_AC | 0x03) +#define CXD56_AUDIO_ECODE_REG_AC_ALCTGT (CXD56_AUDIO_ECODE_REG_AC | 0x04) +#define CXD56_AUDIO_ECODE_REG_AC_ALCKNEE (CXD56_AUDIO_ECODE_REG_AC | 0x05) +#define CXD56_AUDIO_ECODE_REG_AC_SPCLIMT (CXD56_AUDIO_ECODE_REG_AC | 0x06) +#define CXD56_AUDIO_ECODE_REG_AC_CLKMODE (CXD56_AUDIO_ECODE_REG_AC | 0x07) +#define CXD56_AUDIO_ECODE_REG_AC_SEL_INV (CXD56_AUDIO_ECODE_REG_AC | 0x08) +#define CXD56_AUDIO_ECODE_REG_AC_CSTE_VOL (CXD56_AUDIO_ECODE_REG_AC | 0x09) + +/* Error code of config */ + +#define CXD56_AUDIO_ECODE_CFG_CLK_MODE (CXD56_AUDIO_ECODE_CFG | 0x01) + +enum cxd56_audio_state_e +{ + /* Power OFF state */ + + CXD56_AUDIO_POWER_STATE_OFF = 0, + + /* Power ON state */ + + CXD56_AUDIO_POWER_STATE_ON +}; + +typedef enum cxd56_audio_state_e cxd56_audio_state_t; + +enum cxd56_audio_i2s_src_byp_e +{ + /* SRC bypass disable */ + + CXD56_AUDIO_I2S_BYP_DISABLE = 0, + + /* SRC bpass enable */ + + CXD56_AUDIO_I2S_BYP_ENABLE, +}; + +typedef enum cxd56_audio_i2s_src_byp_e cxd56_audio_i2s_src_byp_t; + +enum cxd56_audio_volid_e +{ + /* SDIN1_VOL */ + + CXD56_AUDIO_VOLID_MIXER_IN1 = 0, + + /* SDIN2_VOL */ + + CXD56_AUDIO_VOLID_MIXER_IN2, + + /* DAC_VOL */ + + CXD56_AUDIO_VOLID_MIXER_OUT +}; + +typedef enum cxd56_audio_volid_e cxd56_audio_volid_t; + +/* Select DNC type */ + +enum cxd56_audio_dnc_id_e +{ + /* Feed Back DNC */ + + CXD56_AUDIO_DNC_ID_FB = 0, + + /* Feed Forward DNC */ + + CXD56_AUDIO_DNC_ID_FF +}; + +typedef enum cxd56_audio_dnc_id_e cxd56_audio_dnc_id_t; + +/* Select dma path in */ + +enum cxd56_audio_dma_path_e +{ + /* Mic to memory */ + + CXD56_AUDIO_DMA_PATH_MIC_TO_MEM = 0, + + /* Memory to BUS I/F1 */ + + CXD56_AUDIO_DMA_PATH_MEM_TO_BUSIF1, + + /* Memory to BUS I/F2 */ + + CXD56_AUDIO_DMA_PATH_MEM_TO_BUSIF2, +}; + +typedef enum cxd56_audio_dma_path_e cxd56_audio_dma_path_t; + +/* Internal signal type */ + +enum cxd56_audio_signal_e +{ + /* MIC1 signal */ + + CXD56_AUDIO_SIG_MIC1, + + /* MIC2 signal */ + + CXD56_AUDIO_SIG_MIC2, + + /* MIC3 signal */ + + CXD56_AUDIO_SIG_MIC3, + + /* MIC4 signal */ + + CXD56_AUDIO_SIG_MIC4, + + /* I2S0 signal */ + + CXD56_AUDIO_SIG_I2S0, + + /* I2S1 signal */ + + CXD56_AUDIO_SIG_I2S1, + + /* BUS I/F1 signal */ + + CXD56_AUDIO_SIG_BUSIF1, + + /* BUS I/F2 signal */ + + CXD56_AUDIO_SIG_BUSIF2, + + /* MIX signal */ + + CXD56_AUDIO_SIG_MIX +}; + +typedef enum cxd56_audio_signal_e cxd56_audio_signal_t; + +/* DMAC ID to get in AS_SetAudioDataPath function */ + +enum cxd56_audio_dma_e +{ + /* AudioCodec input */ + + CXD56_AUDIO_DMAC_MIC = 0, + + /* I2S_OUT */ + + CXD56_AUDIO_DMAC_I2S0_DOWN, + + /* I2S2_OUT */ + + CXD56_AUDIO_DMAC_I2S1_DOWN +}; + +typedef enum cxd56_audio_dma_e cxd56_audio_dma_t; + +/* Select output device ID */ + +enum cxd56_audio_outdev_e +{ + CXD56_AUDIO_OUTDEV_OFF = 0, + CXD56_AUDIO_OUTDEV_SP, + CXD56_AUDIO_OUTDEV_I2S +}; + +typedef enum cxd56_audio_outdev_e cxd56_audio_outdev_t; + +enum cxd56_audio_clkmode_e +{ + CXD56_AUDIO_CLKMODE_NORMAL = 0, + CXD56_AUDIO_CLKMODE_HIRES, +}; + +typedef enum cxd56_audio_clkmode_e cxd56_audio_clkmode_t; + +enum cxd56_audio_dmafmt_e +{ + CXD56_AUDIO_DMA_FMT_LR = 0, + CXD56_AUDIO_DMA_FMT_RL, +}; + +typedef enum cxd56_audio_dmafmt_e cxd56_audio_dmafmt_t; + +enum cxd56_audio_samp_fmt_e +{ + CXD56_AUDIO_SAMP_FMT_24 = 0, + CXD56_AUDIO_SAMP_FMT_16 +}; + +typedef enum cxd56_audio_samp_fmt_e cxd56_audio_samp_fmt_t; + +enum cxd56_audio_dsr_rate_e +{ + CXD56_AUDIO_DSR_1STEP = 0x0, + CXD56_AUDIO_DSR_2STEP, + CXD56_AUDIO_DSR_4STEP, + CXD56_AUDIO_DSR_6STEP, + CXD56_AUDIO_DSR_8STEP, + CXD56_AUDIO_DSR_11STEP, + CXD56_AUDIO_DSR_12STEP, + CXD56_AUDIO_DSR_16STEP, +}; + +typedef enum cxd56_audio_dsr_rate_e cxd56_audio_dsr_rate_t; + +enum cxd56_audio_dma_state_e +{ + CXD56_AUDIO_DMA_STATE_REDY = 0x0, + CXD56_AUDIO_DMA_STATE_RUN, +}; + +typedef enum cxd56_audio_dma_state_e cxd56_audio_dma_state_t; + +enum cxd56_audio_micdev_e +{ + CXD56_AUDIO_MIC_DEV_NONE = 0, + CXD56_AUDIO_MIC_DEV_ANALOG, + CXD56_AUDIO_MIC_DEV_DIGITAL, + CXD56_AUDIO_MIC_DEV_ANADIG +}; + +typedef enum cxd56_audio_micdev_e cxd56_audio_micdev_t; + +enum cxd56_audio_sp_drv_e +{ + CXD56_AUDIO_SP_DRV_LINEOUT = 0, + CXD56_AUDIO_SP_DRV_1DRIVER, + CXD56_AUDIO_SP_DRV_2DRIVER, + CXD56_AUDIO_SP_DRV_4DRIVER +}; + +typedef enum cxd56_audio_sp_drv_e cxd56_audio_sp_drv_t; + +struct cxd56_audio_i2s_param_s +{ + uint32_t data_rate; + cxd56_audio_i2s_src_byp_t bypass_mode; +}; + +typedef struct cxd56_audio_i2s_param_s cxd56_audio_i2s_param_t; + +struct cxd56_audio_mic_gain_s +{ + int32_t gain[CXD56_AUDIO_MIC_CH_MAX]; +}; + +typedef struct cxd56_audio_mic_gain_s cxd56_audio_mic_gain_t; + +struct cxd56_audio_dnc_bin_s +{ + uint32_t firm[CXD56_AUDIO_DNC_FW_SIZE]; + uint32_t config[CXD56_AUDIO_DNC_CFG_SIZE]; +}; + +typedef struct cxd56_audio_dnc_bin_s cxd56_audio_dnc_bin_t; + +struct cxd56_audio_sel_s +{ + /* Whether to select with AU_DAT_SEL1 */ + + bool au_dat_sel1; + + /* Whether to select with AU_DAT_SEL2 */ + + bool au_dat_sel2; + + /* Whether to select with COD_INSEL2 */ + + bool cod_insel2; + + /* Whether to select with COD_INSEL3 */ + + bool cod_insel3; + + /* Whether to select with SRC1IN_SEL */ + + bool src1in_sel; + + /* Whether to select with SRC2IN_SEL */ + + bool src2in_sel; +}; + +typedef struct cxd56_audio_sel_s cxd56_audio_sel_t; + +struct cxd56_audio_deq_coef_func_s +{ + uint32_t b0; + uint32_t b1; + uint32_t b2; + uint32_t a0; + uint32_t a1; +}; + +typedef struct cxd56_audio_deq_coef_func_s cxd56_audio_deq_coef_func_t; + +struct cxd56_audio_deq_coef_s +{ + cxd56_audio_deq_coef_func_t coef[CXD56_AUDIO_DEQ_BAND_NUM]; +}; + +typedef struct cxd56_audio_deq_coef_s cxd56_audio_deq_coef_t; + +struct cxd56_audio_dma_mstate_s +{ + uint8_t start; + uint8_t err_setting; + uint8_t buf_state; +}; +typedef struct cxd56_audio_dma_mstate_s cxd56_audio_dma_mstate_t; + +/* DMAC transfer callback function */ + +typedef void (* cxd56_audio_dma_cb_t)(cxd56_audio_dma_t handle, + uint32_t code); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Power on Audio driver + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_poweron(void); + +/* Power off BaseBand driver + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_poweroff(void); + +/* Enable clear stereo + * + * sign_inv: Sign inversion(false: positive, true:negative) + * vol: volume, -825:-82.5dB, ... -195:-19.5dB, step:5 + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_en_cstereo(bool sign_inv, int16_t vol); + +/* Disable clear stereo + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_dis_cstereo(void); + +/* Power on DNC + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_poweron_dnc(void); + +/* Power off DNC + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_poweroff_dnc(void); + +/* Enable DNC + * + * id: target DNC device + * bin: firmware and configurator + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_en_dnc(cxd56_audio_dnc_id_t id, + FAR cxd56_audio_dnc_bin_t *bin); + +/* Disable DNC + * + * id: target DNC device + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_dis_dnc(cxd56_audio_dnc_id_t id); + +/* Disable DEQ + * + * coef: coef data + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_en_deq(FAR cxd56_audio_deq_coef_t *coef); + +/* Disable DEQ + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_dis_deq(void); + +/* Enable BaseBand driver input + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_en_input(void); + +/* Enable BaseBand driver output + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_en_output(void); + +/* Disable BaseBand driver input + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_dis_input(void); + +/* Disable BaseBand driver output + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_dis_output(void); + +/* Set speaker output status + * + * sp_out_en: Whether speaker output is done or not + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_set_spout(bool sp_out_en); + +/* Set volume + * + * id: target volume device id + * vol: volume[-1020:-102.0dB, ... 120:12.0dB] + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_set_vol(cxd56_audio_volid_t id, int16_t vol); + +/* Mute volume + * + * id: target volume device id + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_mute_vol(cxd56_audio_volid_t id); + +/* Unmute volume + * + * id: target volume device id + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_unmute_vol(cxd56_audio_volid_t id); + +/* mute volume with fade-out + * + * id: target volume device id + * wait: wait fade-out end + + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_mute_vol_fade(cxd56_audio_volid_t id, + bool wait); + +/* unmute volume with fade-in + * + * id: target volume device id + * wait: wait fade-in end + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_unmute_vol_fade(cxd56_audio_volid_t id, + bool wait); + +/* Set beep frequency parameter + * + * freq: beep frequency, 94:94Hz, ... 4085:4085Hz, step:1 + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_set_beep_freq(uint16_t freq); + +/* Set beep volume parameter + * + * vol: beep volume, -90:-90dB, ... 0:0dB, step:3, default:-12, + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_set_beep_vol(int16_t vol); + +/* Play beep + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_play_beep(void); + +/* Stop beep + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_stop_beep(void); + +/* Set MIC gain + * + * gain: MIC gain[Analog:0~210[dB*10], Digital:-7850~0[dB*100]] + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_set_micgain(FAR cxd56_audio_mic_gain_t *gain); + +/* Set DEQ table + * + * en: DEQ enable or disable + * deq: coef table + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_set_deq(bool en, + FAR cxd56_audio_deq_coef_t *deq); + +/* Get dma handle + * + * path: dma path type + * handle: dma handle + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_get_dmahandle(cxd56_audio_dma_path_t path, + FAR cxd56_audio_dma_t *handle); + +/* Free dma handle + * + * handle: Dma handle + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_free_dmahandle(FAR cxd56_audio_dma_t handle); + +/* Set internal data path + * + * sig: Internal singal type + * sel: Internal selector type + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_set_datapath(cxd56_audio_signal_t sig, + cxd56_audio_sel_t sel); + +/* Initialize dma transfer function + * + * handle: Dma handle + * fmt: sampling data format 24bits or 16bits + * ch_num: Channel data numbers in DMA data + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_init_dma(cxd56_audio_dma_t handle, + cxd56_audio_samp_fmt_t fmt, + FAR uint8_t *ch_num); + +/* Initialize dma transfer function + * + * handle: Dma handle + * cb: Call back function for notify dma state + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_set_dmacb(cxd56_audio_dma_t handle, + FAR cxd56_audio_dma_cb_t cb); + +/* Enable dma interrupt + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_en_dmaint(void); + +/* Disable dma interrupt + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_dis_dmaint(void); + +/* Clear dma error interrupt state + * + * handle: Dma handle + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_clear_dmaerrint(cxd56_audio_dma_t handle); + +/* Mask dma error interrupt + * + * handle: Dma handle + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_mask_dmaerrint(cxd56_audio_dma_t handle); + +/* Unmask dma error interrupt + * + * handle: Dma handle + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_unmask_dmaerrint(cxd56_audio_dma_t handle); + +/* Start dma transfer + * + * handle: Dma handle + * addr: data address + * sample: number of samples + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_start_dma(cxd56_audio_dma_t handle, + uint32_t addr, + uint32_t sample); + +/* Stop dma transfer + * + * handle: Dma handle + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_stop_dma(cxd56_audio_dma_t handle); + +/* Set audio clock mode + * + * mode: clock mode + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_set_clkmode(cxd56_audio_clkmode_t mode); + +/* Get audio clock mode + * + * cxd56_audio_clkmode_t clock mode + */ + +cxd56_audio_clkmode_t cxd56_audio_get_clkmode(void); + +/* Get data format type of dma + * + * cxd56_audio_dmafmt_t clock mode + */ + +cxd56_audio_dmafmt_t cxd56_audio_get_dmafmt(void); + +/* Get mic device type + * + * cxd56_audio_micdev_t mic device type + */ + +cxd56_audio_micdev_t cxd56_audio_get_micdev(void); + +/* Enable digital soft ramp rate control + * + * rate: Ramp rate + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_en_digsft(cxd56_audio_dsr_rate_t rate); + +/* Disable digital soft ramp rate control + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_dis_digsft(void); + +/* Enable I2S I/O + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_en_i2s_io(void); + +/* Disable I2S I/O + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_dis_i2s_io(void); + +/* Get audio driver status + * + * cxd56_audio_state_t value : current status + */ + +cxd56_audio_state_t cxd56_audio_get_status(void); + +/* Set audio speaker driver mode + * + * sp_driver: speaker driver mode + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_set_spdriver(cxd56_audio_sp_drv_t sp_driver); + +/* Get audio speaker driver mode + * + * cxd56_audio_sp_drv_t speaker driver mode + */ + +cxd56_audio_sp_drv_t cxd56_audio_get_spdriver(void); + +/* Set Mic mapping + * + * map mic mapping + * + * CXD56_AUDIO_ECODE return code + */ + +CXD56_AUDIO_ECODE cxd56_audio_set_micmap(uint32_t map); + +/* Get Mic mapping + * + * mic mapping + */ + +uint32_t cxd56_audio_get_micmap(void); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif /* __cplusplus */ + +#endif /* __ARCH_ARM_INCLUDE_CXD56XX_CXD56_AUDIO_H */ diff --git a/boards/arm/cxd56xx/common/src/Make.defs b/boards/arm/cxd56xx/common/src/Make.defs index a4f3c9e94ce..8d6fa0baa45 100644 --- a/boards/arm/cxd56xx/common/src/Make.defs +++ b/boards/arm/cxd56xx/common/src/Make.defs @@ -34,6 +34,10 @@ CSRCS += cxd56_boot.c +ifeq ($(CONFIG_CXD56_AUDIO), y) +CSRCS += cxd56_audio.c +endif + ifeq ($(CONFIG_BOARDCTL_UNIQUEID),y) CSRCS += cxd56_uid.c endif diff --git a/boards/arm/cxd56xx/common/src/cxd56_audio.c b/boards/arm/cxd56xx/common/src/cxd56_audio.c new file mode 100644 index 00000000000..1f1e6c58630 --- /dev/null +++ b/boards/arm/cxd56xx/common/src/cxd56_audio.c @@ -0,0 +1,390 @@ +/**************************************************************************** + * boards/arm/cxd56xx/common/src/cxd56_audio.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "up_arch.h" + +#include +#include "cxd56_pmic.h" +#include "cxd56_gpio.h" +#include "cxd56_pinconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Check if the following are defined in the board.h */ + +#ifndef CXD5247_XRST +# error "CXD5247_XRST must be defined in board.h !!" +#endif +#ifndef CXD5247_AVDD +# error "CXD5247_AVDD must be defined in board.h !!" +#endif +#ifndef CXD5247_DVDD +# error "CXD5247_DVDD must be defined in board.h !!" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: check_pin_i2s_mode + * + * Description: + * Check if the pin is I2S. + * + ****************************************************************************/ + +static bool check_pin_i2s_mode(uint32_t pin) +{ + bool res = false; + cxd56_pin_status_t pstat; + + if (cxd56_pin_status(pin, &pstat) >= 0) + { + if (pstat.mode == 1) + { + res = true; + } + } + + return res; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_aca_power_control + * + * Description: + * Power on/off the Aca device on the board. + * + ****************************************************************************/ + +int board_aca_power_control(int target, bool en) +{ + int ret = 0; + static int first = 1; + static bool avdd_on = false; + static bool dvdd_on = false; + + if (first) + { + /* gpio configuration (output disabled yet) */ + + cxd56_gpio_config(CXD5247_XRST, false); + + first = 0; + } + + if (en) + { + if (!dvdd_on && (target & CXD5247_DVDD)) + { + /* reset assert */ + + cxd56_gpio_write(CXD5247_XRST, false); + } + + /* power on */ + + if (!avdd_on && (target & CXD5247_AVDD)) + { + board_power_control(POWER_AUDIO_AVDD, true); + avdd_on = true; + } + if (!dvdd_on && (target & CXD5247_DVDD)) + { + board_power_control(POWER_AUDIO_DVDD, true); + dvdd_on = true; + + /* reset release */ + + cxd56_gpio_write(CXD5247_XRST, true); + } + } + else + { + if (dvdd_on && (target & CXD5247_DVDD)) + { + /* reset assert */ + + cxd56_gpio_write(CXD5247_XRST, false); + } + + /* power off */ + + if (avdd_on && (target & CXD5247_AVDD)) + { + board_power_control(POWER_AUDIO_AVDD, false); + avdd_on = false; + } + if (dvdd_on && (target & CXD5247_DVDD)) + { + board_power_control(POWER_AUDIO_DVDD, false); + dvdd_on = false; + } + } + return ret; +} + +/**************************************************************************** + * Name: board_aca_power_monitor + * + * Description: + * Get status of Power on/off the Aca device on the board. + * + ****************************************************************************/ + +bool board_aca_power_monitor(int target) +{ + bool avdd_stat = true; + bool dvdd_stat = true; + + if (target & CXD5247_AVDD) + { + avdd_stat = board_power_monitor(POWER_AUDIO_AVDD); + } + if (target & CXD5247_DVDD) + { + dvdd_stat = board_power_monitor(POWER_AUDIO_DVDD); + } + + return avdd_stat && dvdd_stat; +} + +#define MUTE_OFF_DELAY (1250 * 1000) /* ms */ +#define MUTE_ON_DELAY (150 * 1000) /* ms */ + +/**************************************************************************** + * Name: board_external_amp_mute_control + * + * Description: + * External Amp. Mute on/off. + * true: Mute on + * false: Mute off + * + ****************************************************************************/ + +int board_external_amp_mute_control(bool en) +{ + int ret = 0; + + if (en) + { + /* Mute ON */ + + ret = board_power_control(POWER_AUDIO_MUTE, false); + usleep(MUTE_ON_DELAY); + } + else + { + /* Mute OFF */ + + usleep(MUTE_OFF_DELAY); + ret = board_power_control(POWER_AUDIO_MUTE, true); + } + + return ret; +} + +/**************************************************************************** + * Name: board_external_amp_mute_monitor + * + * Description: + * Get External Amp. Mute status. + * true: Mute on + * false: Mute off + * + ****************************************************************************/ + +bool board_external_amp_mute_monitor(void) +{ + bool mute = board_power_monitor(POWER_AUDIO_MUTE); + return !mute; +} + +/**************************************************************************** + * Name: board_audio_i2s_enable + * + * Description: + * Enable I2S on the board. + * + ****************************************************************************/ + +void board_audio_i2s_enable(void) +{ +#ifdef CONFIG_CXD56_I2S0 + /* Select I2S0_BCK, I2S0_LRCK, I2S0_DATA_IN, I2S0_DATA_OUT. */ + +# ifdef CONFIG_CXD56_AUDIO_I2S_DEVICE_1_MASTER + /* I2S0 Master. */ + +# ifdef CONFIG_CXD56_AUDIO_I2S_LOWEMI_2MA + CXD56_PIN_CONFIGS(PINCONFS_I2S0_M_NORM); +# else + CXD56_PIN_CONFIGS(PINCONFS_I2S0_M_HIGH); +# endif +# else + /* I2S0 Slave. */ + +# ifdef CONFIG_CXD56_AUDIO_I2S_LOWEMI_2MA + CXD56_PIN_CONFIGS(PINCONFS_I2S0_S_NORM); +# else + CXD56_PIN_CONFIGS(PINCONFS_I2S0_S_HIGH); +# endif +# endif /* CONFIG_CXD56_AUDIO_I2S_DEVICE_1_MASTER */ +#endif /* CONFIG_CXD56_I2S0 */ + +#ifdef CONFIG_CXD56_I2S1 + /* Select I2S1_BCK, I2S1_LRCK, I2S1_DATA_IN, I2S1_DATA_OUT. */ + +# ifdef CONFIG_CXD56_AUDIO_I2S_DEVICE_2_MASTER + /* I2S1 Master. */ + +# ifdef CONFIG_CXD56_AUDIO_I2S_LOWEMI_2MA + CXD56_PIN_CONFIGS(PINCONFS_I2S1_M_NORM); +# else + CXD56_PIN_CONFIGS(PINCONFS_I2S1_M_HIGH); +# endif +# else + /* I2S1 Slave. */ + +# ifdef CONFIG_CXD56_AUDIO_I2S_LOWEMI_2MA + CXD56_PIN_CONFIGS(PINCONFS_I2S1_S_NORM); +# else + CXD56_PIN_CONFIGS(PINCONFS_I2S1_S_HIGH); +# endif +# endif /* CONFIG_CXD56_AUDIO_I2S_DEVICE_2_MASTER */ +#endif /* CONFIG_CXD56_I2S1 */ +} + +/**************************************************************************** + * Name: board_audio_i2s_disable + * + * Description: + * Dsiable I2S on the board. + * + ****************************************************************************/ + +void board_audio_i2s_disable(void) +{ +#ifdef CONFIG_CXD56_I2S0 + /* Select GPIO(P1v_00/01/02/03) */ + + if (check_pin_i2s_mode(PIN_I2S0_BCK)) + { + CXD56_PIN_CONFIGS(PINCONFS_I2S0_GPIO); + } +#endif + +#ifdef CONFIG_CXD56_I2S1 + /* Select GPIO(P1v_00/01/02/03) */ + + if (check_pin_i2s_mode(PIN_I2S1_BCK)) + { + CXD56_PIN_CONFIGS(PINCONFS_I2S1_GPIO); + } +#endif +} + +/**************************************************************************** + * Name: board_audio_initialize + * + * Description: + * Initialize audio I/O on the board. + * + ****************************************************************************/ + +void board_audio_initialize(void) +{ + /* Select MCLK. */ + +#ifndef CONFIG_CXD56_AUDIO_ANALOG_NONE + CXD56_PIN_CONFIGS(PINCONFS_MCLK); +#endif + + /* Select PDM_CLK, PDM_IN, PDM_OUT. */ + +#ifdef CONFIG_CXD56_AUDIO_PDM_LOWEMI_2MA + CXD56_PIN_CONFIGS(PINCONFS_PDM_NORM); +#else + CXD56_PIN_CONFIGS(PINCONFS_PDM_HIGH); +#endif +} + +/**************************************************************************** + * Name: board_audio_finalize + * + * Description: + * Finalize audio I/O on the board. + * + ****************************************************************************/ + +void board_audio_finalize(void) +{ + /* Select GPIO(P1x_00). */ + +#ifndef CONFIG_CXD56_AUDIO_ANALOG_NONE + CXD56_PIN_CONFIGS(PINCONFS_MCLK_GPIO); +#endif + + /* Select GPIO(P1y_00/01/02). */ + + CXD56_PIN_CONFIGS(PINCONFS_PDM_GPIO); + + /* Disable I2S. */ + + board_audio_i2s_disable(); +} diff --git a/boards/arm/cxd56xx/drivers/Kconfig b/boards/arm/cxd56xx/drivers/Kconfig index 84e3601a0da..db36ec74fb1 100644 --- a/boards/arm/cxd56xx/drivers/Kconfig +++ b/boards/arm/cxd56xx/drivers/Kconfig @@ -3,4 +3,5 @@ # see the file kconfig-language.txt in the NuttX tools repository. # +source "drivers/platform/audio/Kconfig" source "drivers/platform/sensors/Kconfig" diff --git a/boards/arm/cxd56xx/drivers/Make.defs b/boards/arm/cxd56xx/drivers/Make.defs index 816d87fdfef..2577225d1ef 100644 --- a/boards/arm/cxd56xx/drivers/Make.defs +++ b/boards/arm/cxd56xx/drivers/Make.defs @@ -33,4 +33,5 @@ # ############################################################################ +include platform$(DELIM)audio$(DELIM)Make.defs include platform$(DELIM)sensors$(DELIM)Make.defs diff --git a/boards/arm/cxd56xx/drivers/audio/Kconfig b/boards/arm/cxd56xx/drivers/audio/Kconfig new file mode 100644 index 00000000000..330e43f188a --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/Kconfig @@ -0,0 +1,429 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "Audio Options" + +menuconfig CXD56_AUDIO + bool "CXD56 Audio Driver" + default n + +if CXD56_AUDIO + +config CXD56_I2S0 + bool "I2S0" + default y + ---help--- + Enable I2S channel 0 + +config CXD56_I2S1 + bool "I2S1" + default n + ---help--- + Enable I2S channel 1 + +menu "Audio baseband config settings" + +choice + prompt "Audio analog block selection" + default CXD56_AUDIO_ANALOG_CXD5247 + +config CXD56_AUDIO_ANALOG_CXD5247 + bool "CXD5247" + +config CXD56_AUDIO_ANALOG_NONE + bool "System does not use audio analog block" +endchoice + +if CXD56_AUDIO_ANALOG_CXD5247 +menu "CXD5247 settings" +choice + prompt "X'tal frequency of the CXD5247" + default CXD56_AUDIO_XTAL_SEL_49_152MHZ + +config CXD56_AUDIO_XTAL_SEL_24_576MHZ + bool "24.576MHz" + +config CXD56_AUDIO_XTAL_SEL_49_152MHZ + bool "49.152MHz" +endchoice + +choice + prompt "MICBIAS voltage of the CXD5247" + default CXD56_AUDIO_MICBIAS_20V + +config CXD56_AUDIO_MICBIAS_20V + bool "2.0V" + +config CXD56_AUDIO_MICBIAS_28V + bool "2.8V" +endchoice + +config CXD56_AUDIO_MIC_CHANNEL_SEL + hex "MIC channel select map" + default 0xFFFF4321 + range 0 0xFFFFFFFF + ---help--- + This designates microphone input of the CXD5247 in matrix format. + One microphone can be assigned to multiple channels (CHs.) + (Example: When DMA transfer is performed in monaural mode, + AMIC1 is assigned to CH1 and CH2 and the same audio data is + transferred to the each channel) + +choice + prompt "Output drive strength of MCLKOUT selection" + default CXD56_AUDIO_MCLKOUT_WEAKEST + +config CXD56_AUDIO_MCLKOUT_WEAKEST + bool "2mA" + +config CXD56_AUDIO_MCLKOUT_WEAKER + bool "4mA" + +config CXD56_AUDIO_MCLKOUT_STRONGER + bool "6mA" + +config CXD56_AUDIO_MCLKOUT_STRONGEST + bool "8mA" +endchoice + +choice + prompt "Output drive strength of CLKOUT_DMIC selection" + default CXD56_AUDIO_CLKOUT_DMIC_WEAKEST + +config CXD56_AUDIO_CLKOUT_DMIC_WEAKEST + bool "2mA" + +config CXD56_AUDIO_CLKOUT_DMIC_WEAKER + bool "4mA" + +config CXD56_AUDIO_CLKOUT_DMIC_STRONGER + bool "6mA" + +config CXD56_AUDIO_CLKOUT_DMIC_STRONGEST + bool "8mA" +endchoice + +choice + prompt "Output drive strength of DA_DATA selection" + default CXD56_AUDIO_DA_DATA_WEAKEST + +config CXD56_AUDIO_DA_DATA_WEAKEST + bool "2mA" + +config CXD56_AUDIO_DA_DATA_WEAKER + bool "4mA" + +config CXD56_AUDIO_DA_DATA_STRONGER + bool "6mA" + +config CXD56_AUDIO_DA_DATA_STRONGEST + bool "8mA" +endchoice + +choice + prompt "Output drive strength of GPO_A selection" + default CXD56_AUDIO_GPO_A_WEAKEST + +config CXD56_AUDIO_GPO_A_WEAKEST + bool "2mA" + +config CXD56_AUDIO_GPO_A_WEAKER + bool "4mA" + +config CXD56_AUDIO_GPO_A_STRONGER + bool "6mA" + +config CXD56_AUDIO_GPO_A_STRONGEST + bool "8mA" +endchoice + +choice + prompt "Input source of Cascaded Integrator-Comb filter selection" + default CXD56_AUDIO_CIC_IN_SEL_CXD + +config CXD56_AUDIO_CIC_IN_SEL_CXD + bool "from CXD5247" + +config CXD56_AUDIO_CIC_IN_SEL_DMIC + bool "from DMIC" + +config CXD56_AUDIO_CIC_IN_SEL_NONE + bool "No Cascaded Integrator-Comb filter input" +endchoice + +choice + prompt "Drive currents of PDM signals" + default CXD56_AUDIO_PDM_LOWEMI_2MA + +config CXD56_AUDIO_PDM_LOWEMI_2MA + bool "2mA" + +config CXD56_AUDIO_PDM_LOWEMI_4MA + bool "4mA" +endchoice + +choice + prompt "HPADC mic bias selection" + default CXD56_AUDIO_HPADC_MIC_BIAS_OFF + ---help--- + This setting depends on a circuit board configration. + Set "Microphone bias is enabled" when a microphone connected to + HPADC should be applied with voltage from the CXD5247. + Otherwise, set "Microphone bias is disabled". + +config CXD56_AUDIO_HPADC_MIC_BIAS_ON + bool "Microphone bias is enabled" + +config CXD56_AUDIO_HPADC_MIC_BIAS_OFF + bool "Microphone bias is disabled" +endchoice + +choice + prompt "Version of the CXD5247" + default CXD56_CXD5247_VER_ES4 + +config CXD56_CXD5247_VER_ES2 + bool "ES Version 2.0" + +config CXD56_CXD5247_VER_ES3 + bool "ES Version 3.0" + +config CXD56_CXD5247_VER_ES4 + bool "ES Version 4.0" +endchoice + +if CXD56_CXD5247_VER_ES4 +choice + prompt "Speaker time split on drive selection" + default CXD56_AUDIO_SP_SPLIT_SHORTEST + +config CXD56_AUDIO_SP_SPLIT_SHORTEST + bool "shortest" + +config CXD56_AUDIO_SP_SPLIT_SHORT + bool "short" + +config CXD56_AUDIO_SP_SPLIT_LONG + bool "long" + +config CXD56_AUDIO_SP_SPLIT_LONGEST + bool "longest" +endchoice + +choice + prompt "Speaker drive mode selection" + default CXD56_AUDIO_SP_DRV_LINEOUT + +config CXD56_AUDIO_SP_DRV_4DRIVERT + bool "4Driver(SPK)" + +config CXD56_AUDIO_SP_DRV_2DRIVERT + bool "2Driver" + +config CXD56_AUDIO_SP_DRV_1DRIVERT + bool "1Driver(HP)" + +config CXD56_AUDIO_SP_DRV_LINEOUT + bool "Lineout" +endchoice +endif # CXD56_CXD5247_VER_ES4 +endmenu +endif # CXD56_AUDIO_ANALOG_CXD5247 + +menu "I2S settings" + +if CXD56_I2S0 +choice + prompt "I2S0 device mode selection" + default CXD56_AUDIO_I2S_DEVICE_1_SLAVE + ---help--- + This designates ports and clock modes that are connected + as interfaces for PCM signal input and output. + +config CXD56_AUDIO_I2S_DEVICE_1_SLAVE + bool "I2S0 Slave mode" + +config CXD56_AUDIO_I2S_DEVICE_1_MASTER + bool "I2S0 Master mode" +endchoice + +choice + prompt "I2S0 format type selection" + default CXD56_AUDIO_I2S_FORMAT_1_I2S + ---help--- + This designates the format of PCM signals on I2S. + +config CXD56_AUDIO_I2S_FORMAT_1_I2S + bool "I2S format" + +config CXD56_AUDIO_I2S_FORMAT_1_LEFT + bool "Left Justified format" +endchoice + +choice + prompt "I2S0 bypass mode selection" + default CXD56_AUDIO_I2S_BYPASS_MODE_1_DISABLE + ---help--- + This designates the bypass mode of the sampling rate converter. + To improve sound quality, set it to "Enable". + The bypass mode can be enable when audio clk_mode is Hi-Res mode, + and I2S device mode is master mode and rate is 192kHz(192000). + +config CXD56_AUDIO_I2S_BYPASS_MODE_1_ENABLE + bool "Enable bypass" + +config CXD56_AUDIO_I2S_BYPASS_MODE_1_DISABLE + bool "Disable bypass" +endchoice + +config CXD56_AUDIO_I2S_RATE_1 + int "I2S0 data rate" + default 48000 + range 48000 192000 + ---help--- + This designates input and output data rate of I2S. + The maximum rate is 192000. + +endif # CXD56_I2S0 + +if CXD56_I2S1 +choice + prompt "I2S1 device mode selection" + default CXD56_AUDIO_I2S_DEVICE_2_SLAVE + ---help--- + This designates ports and clock modes that are connected + as interfaces for PCM signal input and output. + +config CXD56_AUDIO_I2S_DEVICE_2_SLAVE + bool "I2S1 Slave mode" + +config CXD56_AUDIO_I2S_DEVICE_2_MASTER + bool "I2S1 Master mode" +endchoice + +choice + prompt "I2S1 format type selection" + default CXD56_AUDIO_I2S_FORMAT_2_I2S + ---help--- + This designates the format of PCM signals on I2S0. + +config CXD56_AUDIO_I2S_FORMAT_2_I2S + bool "I2S format" + +config CXD56_AUDIO_I2S_FORMAT_2_LEFT + bool "Left Justified format" +endchoice + +choice + prompt "I2S1 bypass mode selection" + default CXD56_AUDIO_I2S_BYPASS_MODE_2_DISABLE + ---help--- + This designates the bypass mode of the sampling rate converter. + To improve sound quality, set it to "Enable". + The bypass mode can be enable when audio clk_mode is Hi-Res mode, + and I2S device mode is master mode and rate is 192kHz(192000). + +config CXD56_AUDIO_I2S_BYPASS_MODE_2_ENABLE + bool "Enable bypass" + +config CXD56_AUDIO_I2S_BYPASS_MODE_2_DISABLE + bool "Disable bypass" +endchoice + +config CXD56_AUDIO_I2S_RATE_2 + int "I2S1 data rate" + default 48000 + range 48000 192000 + ---help--- + This designates input and output data rate of I2S1. + The maximum rate is 192000. + +endif # CXD56_I2S1 + +choice + prompt "Drive currents of I2S signals" + default CXD56_AUDIO_I2S_LOWEMI_2MA + +config CXD56_AUDIO_I2S_LOWEMI_2MA + bool "2mA" + +config CXD56_AUDIO_I2S_LOWEMI_4MA + bool "4mA" +endchoice +endmenu + +choice + prompt "ON/OFF of Automatic Level Control/Sound Pressure Counter selection" + default CXD56_AUDIO_ALC_SPC_SEL_OFF + +config CXD56_AUDIO_ALC_SPC_SEL_OFF + bool "All OFF" + +config CXD56_AUDIO_ALC_SPC_SEL_ALC + bool "Automatic Level Control ON" + +config CXD56_AUDIO_ALC_SPC_SEL_SPC + bool "Sound Pressure Counter ON" +endchoice + +if CXD56_AUDIO_ALC_SPC_SEL_ALC +menu "Automatic Level Control setting" +config CXD56_AUDIO_ALC_KNEE + int "Knee levels of Automatic Level Control.[(1/10)dB]" + default -40 + range -635 0 + ---help--- + This command sets integer values 10 times larger than knee levels of + Automatic Level Control. (step width: 0.5 dB) When a value within the + range in the table below with a number other than 0 or 5 in one's + place is designated, it will be regarded as a integer value round up + to zero or five in the one's place. For example, when "-24" is + designated, the value will be regarded as "-20". + +config CXD56_AUDIO_ALC_TARGET + int "Target level of Automatic Level Control.[dB]" + default 0 + range -63 0 +endmenu +endif # CXD56_AUDIO_ALC_SPC_SEL_ALC + +if CXD56_AUDIO_ALC_SPC_SEL_SPC +menu "Sound Pressure Conter setting" +config CXD56_AUDIO_SPC_LIMIT + int "Limit levels of Sound Pressure Counter.[(1/10)dB]" + default 0 + range -250 0 + ---help--- + This command sets integer values 10 times larger than limit levels of + Sound Pressure Counter. (step width: 0.5 dB) When a value within the + range in the table below with a number other than 0 or 5 in one's + place is designated, it will be regarded as a integer value round up + to zero or five in the one's place. For example, when "-24" is + designated, the value will be regarded as "-20". +endmenu +endif # CXD56_AUDIO_ALC_SPC_SEL_SPC + +choice + prompt "LR data format during DMA transfer" + default CXD56_AUDIO_DMA_DATA_FORMAT_RL + ---help--- + This sets the data arrangement of left channel and right channel in + the data format for 16 bit DMA transfer. + +config CXD56_AUDIO_DMA_DATA_FORMAT_LR + bool "allocate left channel data in most significant bit" + +config CXD56_AUDIO_DMA_DATA_FORMAT_RL + bool "allocate right channel data in most significant bit" +endchoice + +config CXD56_AUDIO_MIC_BOOT_WAIT + int "Wait time for mic booting.[msec]" + default 1100 + range 0 65535 + +endmenu + +endif # CXD56_AUDIO diff --git a/boards/arm/cxd56xx/drivers/audio/Make.defs b/boards/arm/cxd56xx/drivers/audio/Make.defs new file mode 100644 index 00000000000..94964b4d8a1 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/Make.defs @@ -0,0 +1,19 @@ +CSRCS += cxd56_audio.c +CSRCS += cxd56_audio_config.c +CSRCS += cxd56_audio_analog.c +CSRCS += cxd56_audio_power.c +CSRCS += cxd56_audio_filter.c +CSRCS += cxd56_audio_mic.c +CSRCS += cxd56_audio_volume.c +CSRCS += cxd56_audio_digital.c +CSRCS += cxd56_audio_beep.c +CSRCS += cxd56_audio_irq.c +CSRCS += cxd56_audio_dma.c +CSRCS += cxd56_audio_ac_reg.c +CSRCS += cxd56_audio_bca_reg.c +CSRCS += cxd56_audio_aca.c +CSRCS += cxd56_audio_pin.c + +DEPPATH += --dep-path platform$(DELIM)audio +VPATH += :platform$(DELIM)audio +CFLAGS += $(shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)platform$(DELIM)audio) diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio.c new file mode 100644 index 00000000000..dbe8616c047 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio.c @@ -0,0 +1,1305 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_power.h" +#include "cxd56_audio_filter.h" +#include "cxd56_audio_mic.h" +#include "cxd56_audio_volume.h" +#include "cxd56_audio_digital.h" +#include "cxd56_audio_beep.h" +#include "cxd56_audio_irq.h" +#include "cxd56_audio_dma.h" +#include "cxd56_audio_pin.h" +#include "cxd56_audio_analog.h" +#include "cxd56_audio_ac_reg.h" +#include "cxd56_audio_bca_reg.h" + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define AUDIO_DNC_ID_NUM (CXD56_AUDIO_DNC_ID_FF + 1) +#define AUDIO_VOL_ID_NUM (CXD56_AUDIO_VOLID_MIXER_OUT + 1) + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/*************************************************************************** + * Private Types + ****************************************************************************/ + +struct clear_stereo_param_s +{ + bool en; + bool sign_inv; + int16_t vol; +}; + +struct power_param_s +{ + bool dnc; +}; + +struct dnc_param_s +{ + bool en; + cxd56_audio_dnc_id_t id; + FAR cxd56_audio_dnc_bin_t *bin; +}; + +struct deq_param_s +{ + bool en; + FAR cxd56_audio_deq_coef_t *coef; +}; + +struct input_param_s +{ + bool en; + cxd56_audio_mic_gain_t gain; +}; + +struct output_param_s +{ + bool en; + bool ana_en; +}; + +struct vol_param_s +{ + cxd56_audio_volid_t id; + int16_t vol; + bool mute; +}; + +struct vol_beep_s +{ + bool en; + int16_t vol; + bool mute; + uint16_t freq; +}; + +struct data_path_s +{ + cxd56_audio_signal_t sig; + cxd56_audio_sel_t sel; +}; + +struct power_on_param_s +{ + struct clear_stereo_param_s cs; + struct power_param_s pw; + struct dnc_param_s dnc[AUDIO_DNC_ID_NUM]; + struct deq_param_s deq; + struct input_param_s input; + struct output_param_s output; + struct vol_param_s vol[AUDIO_VOL_ID_NUM]; + struct vol_beep_s beep; + struct data_path_s path; +}; + +/*************************************************************************** + * Private Data + ****************************************************************************/ + +/* Status of audio driver. */ + +static cxd56_audio_state_t g_status = CXD56_AUDIO_POWER_STATE_OFF; + +/* Parameter of poweron setting. */ + +static struct power_on_param_s g_pwon_param = +{ + .cs = + { + .en = false, + .sign_inv = false, + .vol = -825, + }, + .pw = + { + .dnc = false, + }, + .dnc[0] = + { + .en = false, + .id = 0, + .bin = NULL, + }, + .dnc[1] = + { + .en = false, + .id = 1, + .bin = NULL, + }, + .deq = + { + .en = false, + .coef = NULL, + }, + .input = + { + .en = false, + }, + .output = + { + .en = false, + .ana_en = false, + }, + .vol[0] = + { + .id = 0, + .vol = -1025, + .mute = false, + }, + .vol[1] = + { + .id = 1, + .vol = -1025, + .mute = false, + }, + .vol[2] = + { + .id = 2, + .vol = -1025, + .mute = false, + }, + .path = + { + .sig = CXD56_AUDIO_SIG_MIC1, + .sel.au_dat_sel1 = false, + .sel.au_dat_sel2 = false, + .sel.cod_insel2 = false, + .sel.cod_insel3 = false, + .sel.src1in_sel = false, + .sel.src2in_sel = false, + } +}; + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Public Functions + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_poweron(void) +{ + int i; + + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check status */ + + if (CXD56_AUDIO_POWER_STATE_OFF != g_status) + { + return CXD56_AUDIO_ECODE_POW_STATE; + } + + /* Initialize board I/O. */ + + board_audio_initialize(); + + /* Initialize config. */ + + cxd56_audio_config_init(); + + /* Power On analog block. */ + + ret = cxd56_audio_analog_poweron(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + /* Power On audio codec block. */ + + ret = cxd56_audio_power_on(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + /* Enable interrupt. */ + + cxd56_audio_irq_attach(); + cxd56_audio_irq_enable(); + + /* Update status. */ + + g_status = CXD56_AUDIO_POWER_STATE_ON; + + /* Set initialize parameter. */ + + if (g_pwon_param.cs.en) + { + ret = cxd56_audio_en_cstereo(g_pwon_param.cs.sign_inv, + g_pwon_param.cs.vol); + } + + if (g_pwon_param.pw.dnc) + { + for (i = 0; i < AUDIO_DNC_ID_NUM; i++) + { + if (g_pwon_param.dnc[i].en) + { + ret = cxd56_audio_en_dnc(g_pwon_param.dnc[i].id, + g_pwon_param.dnc[i].bin); + } + } + } + + if (g_pwon_param.deq.en) + { + cxd56_audio_filter_set_deq(g_pwon_param.deq.en, + g_pwon_param.deq.coef); + } + + if (g_pwon_param.input.en) + { + ret = cxd56_audio_en_input(); + } + + if (g_pwon_param.output.en) + { + ret = cxd56_audio_en_output(); + } + + for (i = 0; i < AUDIO_VOL_ID_NUM; i++) + { + ret = cxd56_audio_set_vol(g_pwon_param.vol[i].id, + g_pwon_param.vol[i].vol); + if (g_pwon_param.vol[i].mute) + { + ret = cxd56_audio_mute_vol(g_pwon_param.vol[i].id); + } + } + + ret = cxd56_audio_set_datapath(g_pwon_param.path.sig, + g_pwon_param.path.sel); + if (CXD56_AUDIO_ECODE_OK != ret) + { + g_status = CXD56_AUDIO_POWER_STATE_OFF; + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_poweroff(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check status */ + + if (CXD56_AUDIO_POWER_STATE_ON != g_status) + { + return CXD56_AUDIO_ECODE_POW_STATE; + } + + /* Power off audio codec block. */ + + ret = cxd56_audio_power_off(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + /* Power off analog block. */ + + ret = cxd56_audio_analog_poweroff(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + /* Disable interrupt. */ + + cxd56_audio_irq_disable(); + cxd56_audio_irq_detach(); + + /* Finalize board I/O. */ + + board_audio_finalize(); + + /* Update status. */ + + g_status = CXD56_AUDIO_POWER_STATE_OFF; + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_en_cstereo(bool sign_inv, int16_t vol) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.cs.en = true; + g_pwon_param.cs.sign_inv = sign_inv; + g_pwon_param.cs.vol = vol; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + ret = cxd56_audio_filter_set_cstereo(true, sign_inv, vol); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_dis_cstereo(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.cs.en = false; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + ret = cxd56_audio_filter_set_cstereo(false, false, 0); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_poweron_dnc(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.pw.dnc = true; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + cxd56_audio_filter_poweron_dnc(); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_poweroff_dnc(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.pw.dnc = false; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + cxd56_audio_filter_poweroff_dnc(); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_en_dnc(cxd56_audio_dnc_id_t id, + FAR cxd56_audio_dnc_bin_t *bin) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.dnc[id].en = true; + g_pwon_param.dnc[id].id = id; + g_pwon_param.dnc[id].bin = bin; + + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + cxd56_audio_filter_set_dnc(id, true, bin); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_dis_dnc(cxd56_audio_dnc_id_t id) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.dnc[id].en = false; + g_pwon_param.dnc[id].id = id; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + cxd56_audio_filter_set_dnc(id, false, NULL); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_en_deq(FAR cxd56_audio_deq_coef_t *coef) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.deq.en = true; + if (coef != NULL) + { + g_pwon_param.deq.coef = coef; + } + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + cxd56_audio_filter_set_deq(true, coef); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_dis_deq(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.deq.en = false; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + cxd56_audio_filter_set_deq(false, NULL); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_en_input(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_NONE + return CXD56_AUDIO_ECODE_MIC_NO_ANA; +#endif + + /* Save power on parameters. */ + + g_pwon_param.input.en = true; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + ret = cxd56_audio_analog_poweron_input(&g_pwon_param.input.gain); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + ret = cxd56_audio_mic_enable(&g_pwon_param.input.gain); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_en_output(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.output.en = true; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + +#ifndef CONFIG_CXD56_AUDIO_ANALOG_NONE + if (g_pwon_param.output.ana_en) + { + ret = cxd56_audio_analog_poweron_output(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + /* Enable S-Master. */ + + cxd56_audio_clkmode_t clk_mode = cxd56_audio_config_get_clkmode(); + cxd56_audio_ac_reg_poweron_smaster(clk_mode); + cxd56_audio_bca_reg_set_smaster(); + cxd56_audio_ac_reg_enable_smaster(); + } + else + { + ret = cxd56_audio_analog_poweroff_output(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + } +#endif + + ret = cxd56_audio_volume_unmute(CXD56_AUDIO_VOLID_MIXER_OUT); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_dis_input(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_NONE + return CXD56_AUDIO_ECODE_MIC_NO_ANA; +#endif + + /* Save power on parameters. */ + + g_pwon_param.input.en = false; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + ret = cxd56_audio_mic_disable(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + ret = cxd56_audio_analog_poweroff_input(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_dis_output(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.output.en = false; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + /* Mute output. */ + + ret = cxd56_audio_volume_mute(CXD56_AUDIO_VOLID_MIXER_OUT); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + +#ifndef CONFIG_CXD56_AUDIO_ANALOG_NONE + if (g_pwon_param.output.ana_en) + { + cxd56_audio_ac_reg_disable_smaster(); + cxd56_audio_ac_reg_poweroff_smaster(); + + ret = cxd56_audio_analog_poweroff_output(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + } +#endif + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_set_spout(bool sp_out_en) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + /* Save power on parameters. */ + + g_pwon_param.output.ana_en = sp_out_en; + return ret; + } + + g_pwon_param.output.ana_en = sp_out_en; + + /* Actual switching timing is when cxd56_audio_en_output() is executed. + * When calling this function, execute cxd56_audio_en_output(). + */ + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_set_vol(cxd56_audio_volid_t id, int16_t vol) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.vol[id].id = id; + g_pwon_param.vol[id].vol = vol; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + ret = cxd56_audio_volume_set(id, vol); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_mute_vol(cxd56_audio_volid_t id) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.vol[id].mute = true; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + ret = cxd56_audio_volume_mute(id); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_unmute_vol(cxd56_audio_volid_t id) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.vol[id].mute = false; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + ret = cxd56_audio_volume_unmute(id); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_mute_vol_fade(cxd56_audio_volid_t id, bool wait) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check error of state. PowerON state only. */ + + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return CXD56_AUDIO_ECODE_POW_STATE; + } + + ret = cxd56_audio_volume_mute_fade(id, wait); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_unmute_vol_fade(cxd56_audio_volid_t id, + bool wait) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check error of state. PowerON state only. */ + + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return CXD56_AUDIO_ECODE_POW_STATE; + } + + ret = cxd56_audio_volume_unmute_fade(id, wait); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_set_beep_freq(uint16_t freq) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.beep.freq = freq; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + ret = cxd56_audio_beep_set_freq(freq); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_set_beep_vol(int16_t vol) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.beep.vol = vol; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + ret = cxd56_audio_beep_set_vol(vol); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_play_beep(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.beep.en = true; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + cxd56_audio_beep_play(); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_stop_beep(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.beep.en = false; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + cxd56_audio_beep_stop(); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_set_micgain(FAR cxd56_audio_mic_gain_t *gain) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + if (gain == NULL) + { + return CXD56_AUDIO_ECODE_MIC_ARG_NULL; + } + + /* Save power on parameters. */ + + g_pwon_param.input.gain = *gain; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + /* Set analog mic gain. */ + + ret = cxd56_audio_analog_set_micgain(gain); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + /* Set digital mic gain. */ + + ret = cxd56_audio_mic_set_gain(gain); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_get_dmahandle(cxd56_audio_dma_path_t path, + FAR cxd56_audio_dma_t *handle) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check error of argument. */ + + if (handle == NULL) + { + return CXD56_AUDIO_ECODE_DMA_ARG_NULL; + } + + ret = cxd56_audio_dma_get_handle(path, handle); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + if (CXD56_AUDIO_DMA_PATH_MIC_TO_MEM == path) + { + ret = cxd56_audio_analog_wait_input_standby(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_free_dmahandle(FAR cxd56_audio_dma_t handle) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + ret = cxd56_audio_dma_free_handle(handle); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_set_datapath(cxd56_audio_signal_t sig, + cxd56_audio_sel_t sel) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Save power on parameters. */ + + g_pwon_param.path.sig = sig; + g_pwon_param.path.sel = sel; + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return ret; + } + + ret = cxd56_audio_ac_reg_set_selector(sig, sel); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + if (CXD56_AUDIO_SIG_MIC1 == sig || + CXD56_AUDIO_SIG_MIC2 == sig || + CXD56_AUDIO_SIG_MIC3 == sig || + CXD56_AUDIO_SIG_MIC4 == sig) + { + ret = cxd56_audio_analog_wait_input_standby(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + } + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_init_dma(cxd56_audio_dma_t handle, + cxd56_audio_samp_fmt_t fmt, + FAR uint8_t *ch_num) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check error of argument. */ + + if (ch_num == NULL) + { + return CXD56_AUDIO_ECODE_DMA_ARG_NULL; + } + + /* Check error of state. PowerON state only. */ + + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return CXD56_AUDIO_ECODE_POW_STATE; + } + + ret = cxd56_audio_dma_init(handle, fmt, ch_num); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_set_dmacb(cxd56_audio_dma_t handle, + FAR cxd56_audio_dma_cb_t cb) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check error of argument. */ + + if (cb == NULL) + { + return CXD56_AUDIO_ECODE_DMA_ARG_NULL; + } + + ret = cxd56_audio_dma_set_cb(handle, cb); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_get_dmamstate(cxd56_audio_dma_t handle, + FAR cxd56_audio_dma_mstate_t *state) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check error of argument. */ + + if (state == NULL) + { + return CXD56_AUDIO_ECODE_DMA_ARG_NULL; + } + + /* Check error of state. PowerON state only. */ + + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return CXD56_AUDIO_ECODE_POW_STATE; + } + + ret = cxd56_audio_dma_get_mstate(handle, state); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_en_dmaint(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + ret = cxd56_audio_dma_en_dmaint(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_dis_dmaint(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + ret = cxd56_audio_dma_dis_dmaint(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_clear_dmaerrint(cxd56_audio_dma_t handle) +{ + cxd56_audio_bca_reg_clear_err_int(handle); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_mask_dmaerrint(cxd56_audio_dma_t handle) +{ + cxd56_audio_bca_reg_mask_err_int(handle); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_unmask_dmaerrint(cxd56_audio_dma_t handle) +{ + cxd56_audio_bca_reg_unmask_err_int(handle); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_start_dma(cxd56_audio_dma_t handle, + uint32_t addr, + uint32_t sample) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check error of state. PowerON state only. */ + + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return CXD56_AUDIO_ECODE_POW_STATE; + } + + ret = cxd56_audio_dma_start(handle, addr, sample); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_stop_dma(cxd56_audio_dma_t handle) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check error of state. PowerON state only. */ + + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return CXD56_AUDIO_ECODE_POW_STATE; + } + + ret = cxd56_audio_dma_stop(handle); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_set_clkmode(cxd56_audio_clkmode_t mode) +{ + if ((CXD56_AUDIO_CFG_MCLK == CXD56_AUDIO_CFG_XTAL_24_576MHZ) && + (mode == CXD56_AUDIO_CLKMODE_HIRES)) + { + return CXD56_AUDIO_ECODE_CFG_CLK_MODE; + } + + cxd56_audio_config_set_clkmode(mode); + + return CXD56_AUDIO_ECODE_OK; +} + +cxd56_audio_clkmode_t cxd56_audio_get_clkmode(void) +{ + return cxd56_audio_config_get_clkmode(); +} + +cxd56_audio_dmafmt_t cxd56_audio_get_dmafmt(void) +{ + cxd56_audio_dmafmt_t fmt; + + if (CXD56_AUDIO_CFG_DMA_FORMAT == CXD56_AUDIO_CFG_DMA_FORMAT_LR) + { + fmt = CXD56_AUDIO_DMA_FMT_LR; + } + else + { + fmt = CXD56_AUDIO_DMA_FMT_RL; + } + + return fmt; +} + +cxd56_audio_micdev_t cxd56_audio_get_micdev(void) +{ + cxd56_audio_micdev_t micdev; + uint8_t cfg_micdev = cxd56_audio_config_get_micdev(); + + switch (cfg_micdev) + { + case CXD56_AUDIO_CFG_MIC_DEV_ANALOG: + micdev = CXD56_AUDIO_MIC_DEV_ANALOG; + break; + + case CXD56_AUDIO_CFG_MIC_DEV_DIGITAL: + micdev = CXD56_AUDIO_MIC_DEV_DIGITAL; + break; + + case CXD56_AUDIO_CFG_MIC_DEV_ANADIG: + micdev = CXD56_AUDIO_MIC_DEV_ANADIG; + break; + + default: + micdev = CXD56_AUDIO_MIC_DEV_NONE; + break; + } + + return micdev; +} + +CXD56_AUDIO_ECODE cxd56_audio_en_digsft(cxd56_audio_dsr_rate_t rate) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check error of state. PowerON state only. */ + + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return CXD56_AUDIO_ECODE_POW_STATE; + } + + cxd56_audio_ac_reg_set_dsrrate(rate); + cxd56_audio_ac_reg_enable_digsft(); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_dis_digsft(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check error of state. PowerON state only. */ + + if (g_status == CXD56_AUDIO_POWER_STATE_OFF) + { + return CXD56_AUDIO_ECODE_POW_STATE; + } + + cxd56_audio_ac_reg_disable_digsft(); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_en_i2s_io(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Enable I2S pin. */ + + cxd56_audio_pin_i2s_set(); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_dis_i2s_io(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Disable I2S pin. */ + + cxd56_audio_pin_i2s_unset(); + + return ret; +} + +cxd56_audio_state_t cxd56_audio_get_status(void) +{ + return g_status; +} + +CXD56_AUDIO_ECODE cxd56_audio_set_spdriver(cxd56_audio_sp_drv_t sp_driver) +{ + cxd56_audio_config_set_spdriver(sp_driver); + + return CXD56_AUDIO_ECODE_OK; +} + +cxd56_audio_sp_drv_t cxd56_audio_get_spdriver(void) +{ + return cxd56_audio_config_get_spdriver(); +} + +CXD56_AUDIO_ECODE cxd56_audio_set_micmap(uint32_t map) +{ + cxd56_audio_config_set_micmap(map); + + return CXD56_AUDIO_ECODE_OK; +} + +uint32_t cxd56_audio_get_micmap(void) +{ + return cxd56_audio_config_get_micmap(); +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_ac_reg.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_ac_reg.c new file mode 100644 index 00000000000..2ca10dc3321 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_ac_reg.c @@ -0,0 +1,1617 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_ac_reg.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_ac_reg.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define AC_REG_BASE (0x0c000000 + 0x02300000) + +#define AC_REVID 0x20 +#define AC_DEVICEID 0x02 + +#define DNC1_IRAM_BASE 0x3000 +#define DNC1_CRAM_BASE 0x3800 +#define DNC2_IRAM_BASE 0x3c00 +#define DNC2_CRAM_BASE 0x4400 + +#define MTBR_GAIN_MAX 0 +#define MTBR_GAIN_MIN -630 +#define MTBR_GAIN_MUTE -635 + +#define CIC_GAIN_MAX 0 +#define CIC_GAIN_MIN -7850 +#define CIC_GAIN_MUTE -7855 + +#define ALC_TARGET_MIN -63 +#define ALC_TARGET_MAX 0 + +#define ALC_KNEE_MIN -635 +#define ALC_KNEE_MAX 0 + +#define SPC_LIMIT_MIN -250 +#define SPC_LIMIT_MAX 0 + +#define DEQ_BAND_NUM 6 +#define DEQ_COEF_NUM 5 +#define DNC_IRAM_SIZE (256 * 2) +#define DNC_CRAM_SIZE 128 + +#define AC_CIC_NUM 4 +#define AC_CIC_MIC_CH_NUM 2 + +#define AC_REG_MAX_BIT 32 + +#define I2S_DATA_RATE_LOW 48000 +#define I2S_DATA_RATE_MID 96000 +#define I2S_DATA_RATE_HIGH 192000 + +#define CS_VOL_MAX -195 +#define CS_VOL_MIN -825 +#define CS_VOL_OFFSET 190 + +#define AU_DAT_SEL_MIC1 0 +#define AU_DAT_SEL_MIC2 1 +#define AU_DAT_SEL_MIC3 2 +#define AU_DAT_SEL_MIC4 3 +#define AU_DAT_SEL_BUSIF1 4 +#define AU_DAT_SEL_BUSIF2 4 + +#define COD_INSEL_SRC1 0 +#define COD_INSEL_SRC2 1 +#define COD_INSEL_AU_DAT_SEL1 2 +#define COD_INSEL_AU_DAT_SEL2 3 + +#define SRCIN_SEL_AU_DAT_SEL1 0 +#define SRCIN_SEL_AU_DAT_SEL2 1 +#define SRCIN_SEL_CODECDSP_MIX 3 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct audio_ac_reg_s +{ + uint32_t addr; + uint32_t pos; + uint32_t len; + uint32_t init; +}; + +const struct audio_ac_reg_s g_ac_reg[RI_REG_MAX_ENTRY] = +{ + {0x0000, 16, 8, 0x00000020}, /* REVID (0x10) */ + {0x0000, 24, 8, 0x00000002}, /* DEVICEID (0x01) */ + {0x0100, 4, 1, 0x00000001}, /* PDN_AMICEXT (0x01) */ + {0x0100, 5, 1, 0x00000001}, /* PDN_AMIC1 (0x01) */ + {0x0100, 6, 1, 0x00000001}, /* PDN_AMIC2 (0x01) */ + {0x0100, 8, 1, 0x00000001}, /* PDN_DAC (0x01) */ + {0x0100, 9, 1, 0x00000001}, /* PDN_LINEIN (0x01) */ + {0x0100, 10, 1, 0x00000001}, /* PDN_MIC (0x01) */ + {0x0100, 15, 1, 0x00000001}, /* PDN_DMIC (0x01) */ + {0x0100, 16, 1, 0x00000001}, /* PDN_DSPB (0x01) */ + {0x0100, 17, 1, 0x00000001}, /* PDN_ANC (0x01) */ + {0x0100, 18, 1, 0x00000001}, /* PDN_DNC1 (0x01) */ + {0x0100, 19, 1, 0x00000001}, /* PDN_DNC2 (0x01) */ + {0x0100, 20, 1, 0x00000001}, /* PDN_SMSTR (0x01) */ + {0x0100, 21, 1, 0x00000001}, /* PDN_DSPS2 (0x01) */ + {0x0100, 22, 1, 0x00000001}, /* PDN_DSPS1 (0x01) */ + {0x0100, 23, 1, 0x00000001}, /* PDN_DSPC (0x01) */ + {0x0104, 0, 1, 0x00000000}, /* FS_FS (0x00) */ + {0x0104, 16, 1, 0x00000000}, /* DECIM0_EN (0x00) */ + {0x0104, 17, 1, 0x00000000}, /* DECIM1_EN (0x00) */ + {0x0104, 18, 1, 0x00000000}, /* SDES_EN (0x00) */ + {0x0104, 19, 1, 0x00000000}, /* MCK_AHBMSTR_EN (0x00) */ + {0x0108, 16, 3, 0x00000000}, /* AU_DAT_SEL2 (0x00) */ + {0x0108, 20, 3, 0x00000000}, /* AU_DAT_SEL1 (0x00) */ + {0x0108, 24, 2, 0x00000000}, /* COD_INSEL3 (0x00) */ + {0x0108, 26, 2, 0x00000000}, /* COD_INSEL2 (0x00) */ + {0x0108, 28, 2, 0x00000000}, /* COD_INSEL1 (0x00) */ + {0x0200, 0, 3, 0x00000000}, /* DSR_RATE (0x00) */ + {0x0200, 12, 1, 0x00000001}, /* DIGSFT (0x01) */ + {0x0200, 16, 2, 0x00000001}, /* SRC1 (0x01) */ + {0x0200, 18, 2, 0x00000002}, /* SRC1IN_SEL (0x02) */ + {0x0200, 20, 2, 0x00000001}, /* SRC2 (0x01) */ + {0x0200, 22, 2, 0x00000002}, /* SRC2IN_SEL (0x02) */ + {0x0200, 26, 1, 0x00000001}, /* DIF2 (0x01) */ + {0x0200, 27, 1, 0x00000001}, /* DIF1 (0x01) */ + {0x0200, 28, 1, 0x00000000}, /* SD2MASTER (0x00) */ + {0x0200, 29, 1, 0x00000000}, /* SD1MASTER (0x00) */ + {0x0200, 30, 1, 0x00000000}, /* SDCK_OUTENX (0x00) */ + {0x0200, 31, 1, 0x00000000}, /* HI_RES_MODE (0x00) */ + {0x0204, 0, 2, 0x00000000}, /* HPF2_MODE (0x00) */ + {0x0204, 5, 1, 0x00000000}, /* CIC2IN_SWAP (0x00) */ + {0x0204, 6, 1, 0x00000000}, /* INV_DMIC2L (0x00) */ + {0x0204, 7, 1, 0x00000000}, /* INV_DMIC2R (0x00) */ + {0x0204, 8, 1, 0x00000000}, /* CIC2_GAIN_MODE (0x00) */ + {0x0204, 9, 1, 0x00000000}, /* CIC2IN_SEL (0x00) */ + {0x0204, 10, 1, 0x00000000}, /* ADC2_BOOST (0x00) */ + {0x0204, 14, 1, 0x00000000}, /* INV_AMIC2L (0x00) */ + {0x0204, 15, 1, 0x00000000}, /* INV_AMIC2R (0x00) */ + {0x0204, 16, 2, 0x00000000}, /* HPF1_MODE (0x00) */ + {0x0204, 21, 1, 0x00000000}, /* CIC1IN_SWAP (0x00) */ + {0x0204, 22, 1, 0x00000000}, /* INV_DMIC1L (0x00) */ + {0x0204, 23, 1, 0x00000000}, /* INV_DMIC1R (0x00) */ + {0x0204, 24, 1, 0x00000000}, /* CIC1_GAIN_MODE (0x00) */ + {0x0204, 25, 1, 0x00000000}, /* CIC1IN_SEL (0x00) */ + {0x0204, 26, 1, 0x00000000}, /* ADC1_BOOST (0x00) */ + {0x0204, 28, 2, 0x00000000}, /* ADC_FS (0x00) */ + {0x0204, 30, 1, 0x00000000}, /* INV_AMIC1L (0x00) */ + {0x0204, 31, 1, 0x00000000}, /* INV_AMIC1R (0x00) */ + {0x0208, 0, 2, 0x00000000}, /* HPF4_MODE (0x00) */ + {0x0208, 5, 1, 0x00000000}, /* CIC4IN_SWAP (0x00) */ + {0x0208, 6, 1, 0x00000000}, /* INV_DMIC4L (0x00) */ + {0x0208, 7, 1, 0x00000000}, /* INV_DMIC4R (0x00) */ + {0x0208, 9, 1, 0x00000000}, /* CIC4IN_SEL (0x00) */ + {0x0208, 10, 1, 0x00000000}, /* ADC4_BOOST (0x00) */ + {0x0208, 14, 1, 0x00000000}, /* INV_AMIC4L (0x00) */ + {0x0208, 15, 1, 0x00000000}, /* INV_AMIC4R (0x00) */ + {0x0208, 16, 2, 0x00000000}, /* HPF3_MODE (0x00) */ + {0x0208, 21, 1, 0x00000000}, /* CIC3IN_SWAP (0x00) */ + {0x0208, 22, 1, 0x00000000}, /* INV_DMIC3L (0x00) */ + {0x0208, 23, 1, 0x00000000}, /* INV_DMIC3R (0x00) */ + {0x0208, 25, 1, 0x00000000}, /* CIC3IN_SEL (0x00) */ + {0x0208, 26, 1, 0x00000000}, /* ADC_3_BOOST (0x00) */ + {0x0208, 30, 1, 0x00000000}, /* INV_AMIC3L (0x00) */ + {0x0208, 31, 1, 0x00000000}, /* INV_AMIC3R (0x00) */ + {0x020c, 0, 16, 0x00004000}, /* CIC1_RGAIN (0x4000) */ + {0x020c, 16, 16, 0x00004000}, /* CIC1_LGAIN (0x4000) */ + {0x0210, 0, 16, 0x00004000}, /* CIC2_RGAIN (0x4000) */ + {0x0210, 16, 16, 0x00004000}, /* CIC2_LGAIN (0x4000) */ + {0x0214, 0, 16, 0x00004000}, /* CIC3_RGAIN (0x4000) */ + {0x0214, 16, 16, 0x00004000}, /* CIC3_LGAIN (0x4000) */ + {0x0218, 0, 16, 0x00004000}, /* CIC4_RGAIN (0x4000) */ + {0x0218, 16, 16, 0x00004000}, /* CIC4_LGAIN (0x4000) */ + {0x021c, 8, 7, 0x00000000}, /* SPC_LIMIT (0x00) */ + {0x021c, 15, 1, 0x00000000}, /* SPC_EN (0x00) */ + {0x021c, 16, 7, 0x00000008}, /* ALC_KNEE (0x08) */ + {0x021c, 24, 6, 0x00000000}, /* ALCTARGET (0x00) */ + {0x021c, 30, 1, 0x00000001}, /* ALC_REC (0x01) */ + {0x021c, 31, 1, 0x00000000}, /* ALC_EN (0x00) */ + {0x0220, 16, 1, 0x00000000}, /* INV_ASP2R (0x00) */ + {0x0220, 17, 1, 0x00000000}, /* INV_ASP2L (0x00) */ + {0x0220, 18, 1, 0x00000000}, /* INV_ASP1R (0x00) */ + {0x0220, 19, 1, 0x00000000}, /* INV_ASP1L (0x00) */ + {0x0220, 29, 3, 0x00000004}, /* ARC (0x04) */ + {0x0224, 8, 24, 0x00800000}, /* ARC_VOL (0x800000) */ + {0x0228, 0, 7, 0x00000000}, /* CS_VOL (0x00) */ + {0x0228, 7, 1, 0x00000000}, /* CS_SIGN (0x00) */ + {0x0228, 8, 8, 0x00000033}, /* SDOUT_VOL (0x33) */ + {0x0228, 16, 8, 0x00000033}, /* SDIN2_VOL (0x33) */ + {0x0228, 24, 8, 0x00000033}, /* SDIN1_VOL (0x33) */ + {0x022c, 0, 1, 0x00000000}, /* SDIN1_EN (0x00) */ + {0x022c, 1, 1, 0x00000000}, /* SDIN2_EN (0x00) */ + {0x022c, 2, 1, 0x00000000}, /* SDOUT1_EN (0x00) */ + {0x022c, 3, 1, 0x00000000}, /* SDOUT2_EN (0x00) */ + {0x022c, 4, 1, 0x00000000}, /* MUTE_B (0x00) */ + {0x022c, 5, 1, 0x00000000}, /* BLF_EN (0x00) */ + {0x022c, 6, 1, 0x00000000}, /* TRANS_MODE (0x00) */ + {0x022c, 8, 8, 0x00000033}, /* DAC_VOL (0x33) */ + {0x022c, 16, 8, 0x00000033}, /* LINEIN_VOL (0x33) */ + {0x0230, 16, 5, 0x00000004}, /* BEEP_VOL (0x04) */ + {0x0230, 24, 6, 0x00000010}, /* BEEP_FREQ (0x10) */ + {0x0230, 31, 1, 0x00000000}, /* BEEP_ON (0x00) */ + {0x0234, 0, 1, 0x00000001}, /* M_SPCLKERR1 (0x01) */ + {0x0234, 1, 1, 0x00000001}, /* M_SPCLKERR2 (0x01) */ + {0x0240, 0, 7, 0x00000000}, /* ADC1L_VOL (0x00) */ + {0x0240, 8, 7, 0x00000000}, /* ADC1R_VOL (0x00) */ + {0x0240, 16, 7, 0x00000000}, /* ADC2L_VOL (0x00) */ + {0x0240, 24, 7, 0x00000000}, /* ADC2R_VOL (0x00) */ + {0x0300, 0, 8, 0x00000000}, /* SMS_INTIM (0x00) */ + {0x0304, 0, 3, 0x00000000}, /* DNC2_AVF (0x00) */ + {0x0304, 4, 1, 0x00000000}, /* DNC2_MONION1 (0x00) */ + {0x0304, 5, 1, 0x00000000}, /* DNC2_MONIEN1 (0x00) */ + {0x0304, 6, 1, 0x00000000}, /* DNC2_MONION0 (0x00) */ + {0x0304, 7, 1, 0x00000000}, /* DNC2_MONIEN0 (0x00) */ + {0x0304, 8, 3, 0x00000000}, /* DNC1_AVF (0x00) */ + {0x0304, 12, 1, 0x00000000}, /* DNC1_MONION1 (0x00) */ + {0x0304, 13, 1, 0x00000000}, /* DNC1_MONIEN1 (0x00) */ + {0x0304, 14, 1, 0x00000000}, /* DNC1_MONION0 (0x00) */ + {0x0304, 15, 1, 0x00000000}, /* DNC1_MONIEN0 (0x00) */ + {0x0304, 16, 3, 0x00000000}, /* DNC2_CFMD (0x00) */ + {0x0304, 20, 1, 0x00000000}, /* DNC2_ESS (0x00) */ + {0x0304, 21, 1, 0x00000000}, /* DNC2_ZWR (0x00) */ + {0x0304, 22, 1, 0x00000001}, /* DNC2_MUTE (0x01) */ + {0x0304, 23, 1, 0x00000000}, /* DNC2_START (0x00) */ + {0x0304, 24, 3, 0x00000000}, /* DNC1_CFMD (0x00) */ + {0x0304, 28, 1, 0x00000000}, /* DNC1_ESS (0x00) */ + {0x0304, 29, 1, 0x00000000}, /* DNC1_ZWR (0x00) */ + {0x0304, 30, 1, 0x00000001}, /* DNC1_MUTE (0x01) */ + {0x0304, 31, 1, 0x00000000}, /* DNC1_START (0x00) */ + {0x0308, 16, 1, 0x00000000}, /* DNC_STB (0x00) */ + {0x0308, 22, 2, 0x00000001}, /* DCMFS_34 (0x01) */ + {0x0308, 29, 1, 0x00000000}, /* DNC_512 (0x00) */ + {0x0308, 30, 2, 0x00000001}, /* DCMFS (0x01) */ + {0x030c, 0, 16, 0x00000000}, /* DNC1_CANVOL1 (0x0000) */ + {0x030c, 16, 16, 0x00000000}, /* DNC1_CANVOL0 (0x0000) */ + {0x0310, 0, 16, 0x00000000}, /* DNC2_CANVOL1 (0x0000) */ + {0x0310, 16, 16, 0x00000000}, /* DNC2_CANVOL0 (0x0000) */ + {0x0314, 0, 16, 0x00000000}, /* DNC1_MONVOL1 (0x0000) */ + {0x0314, 16, 16, 0x00000000}, /* DNC1_MONVOL0 (0x0000) */ + {0x0318, 0, 16, 0x00000000}, /* DNC2_MONVOL1 (0x0000) */ + {0x0318, 16, 16, 0x00000000}, /* DNC2_MONVOL0 (0x0000) */ + {0x031c, 0, 16, 0x00000000}, /* DNC1_ALGAIN1 (0x0000) */ + {0x031c, 16, 16, 0x00000000}, /* DNC1_ALGAIN0 (0x0000) */ + {0x0320, 0, 16, 0x00000000}, /* DNC2_ALGAIN1 (0x0000) */ + {0x0320, 16, 16, 0x00000000}, /* DNC2_ALGAIN0 (0x0000) */ + {0x0324, 24, 8, 0x00000000}, /* DNC_PHD (0x00) */ + {0x0328, 8, 5, 0x0000001f}, /* DNC1_LIMIYT (0x1f) */ + {0x0328, 15, 1, 0x00000000}, /* DNC1_LMTON0 (0x00) */ + {0x0328, 16, 5, 0x00000000}, /* DNC1_LIMITR (0x00) */ + {0x0328, 24, 5, 0x00000000}, /* DNC1_LIMITA (0x00) */ + {0x0328, 30, 2, 0x00000000}, /* DNC1_INSTMD (0x00) */ + {0x032c, 8, 5, 0x0000001f}, /* DNC2_LIMIYT (0x1f) */ + {0x032c, 15, 1, 0x00000000}, /* DNC2_LMTON0 (0x00) */ + {0x032c, 16, 5, 0x00000000}, /* DNC2_LIMITR (0x00) */ + {0x032c, 24, 5, 0x00000000}, /* DNC2_LIMITA (0x00) */ + {0x032c, 30, 2, 0x00000000}, /* DNC2_INSTMD (0x00) */ + {0x0330, 0, 16, 0x00000100}, /* ANC_FALVL (0x0100) */ + {0x0330, 24, 1, 0x00000000}, /* ANC_TST (0x00) */ + {0x0330, 25, 1, 0x00000000}, /* ANC_FATST (0x00) */ + {0x0330, 26, 1, 0x00000000}, /* ENVREG_RESET (0x00) */ + {0x0330, 30, 2, 0x00000000}, /* ANC_CHSEL (0x00) */ + {0x0334, 8, 2, 0x00000000}, /* ANC_TR (0x00) */ + {0x0334, 10, 2, 0x00000000}, /* ANC_TA (0x00) */ + {0x0334, 16, 1, 0x00000000}, /* ANC_SOUT (0x00) */ + {0x0334, 17, 3, 0x00000003}, /* ANC_FASPN (0x03) */ + {0x0334, 20, 1, 0x00000000}, /* ANC_ZWR (0x00) */ + {0x0334, 21, 1, 0x00000001}, /* ANC_MUTE (0x01) */ + {0x0334, 22, 1, 0x00000000}, /* ANC_START (0x00) */ + {0x0334, 23, 1, 0x00000000}, /* ANC_FASTART (0x00) */ + {0x0334, 24, 3, 0x00000000}, /* ANC_FAWTB (0x00) */ + {0x0334, 28, 3, 0x00000000}, /* ANC_FAWTA (0x00) */ + {0x0338, 0, 16, 0x00000000}, /* ANC_ENV1 (0x0000) */ + {0x0338, 16, 16, 0x00000000}, /* ANC_ENV0 (0x0000) */ + {0x033c, 8, 4, 0x00000000}, /* ANC_CURST (0x00) */ + {0x033c, 12, 2, 0x00000000}, /* ANC_FAST (0x00) */ + {0x033c, 16, 16, 0x00000000}, /* ANC_ENV2 (0x0000) */ + {0x0340, 0, 4, 0x00000000}, /* NS_AMMD (0x00) */ + {0x0340, 8, 8, 0x000000ff}, /* BPGAIN (0xff) */ + {0x0340, 16, 4, 0x00000000}, /* BPSEL (0x00) */ + {0x0340, 21, 1, 0x00000000}, /* NSDI (0x00) */ + {0x0340, 22, 1, 0x00000000}, /* NSII (0x00) */ + {0x0340, 23, 1, 0x00000000}, /* BPON (0x00) */ + {0x0340, 24, 3, 0x00000002}, /* NSMS (0x02) */ + {0x0340, 27, 1, 0x00000000}, /* CHSEL (0x00) */ + {0x0340, 29, 1, 0x00000000}, /* NSADJON (0x00) */ + {0x0340, 30, 1, 0x00000000}, /* NSX2 (0x00) */ + {0x0340, 31, 1, 0x00000001}, /* NSPMUTE (0x01) */ + {0x0344, 0, 20, 0x00000000}, /* NSDD (0x000000) */ + {0x0344, 20, 4, 0x00000000}, /* OUT2DLY (0x00) */ + {0x0348, 0, 20, 0x00000000}, /* NSAD (0x000000) */ + {0x0348, 20, 2, 0x00000001}, /* PWMMD (0x01) */ + {0x0348, 22, 2, 0x00000000}, /* NSAS (0x00) */ + {0x034c, 16, 8, 0x00000000}, /* NSADJ (0x00) */ + {0x034c, 24, 8, 0x00000000}, /* VCONT (0x00) */ + {0x0400, 0, 6, 0x00000000}, /* TEST_OUT (0x00) */ + {0x0400, 6, 1, 0x00000000}, /* RI_TEST_OUT_SEL0 (0x00) */ + {0x0400, 7, 1, 0x00000000}, /* RI_TEST_OUT_SEL1 (0x00) */ + {0x0400, 8, 8, 0x00000000}, /* TEST_IN (0x00) */ + {0x0400, 16, 1, 0x00000000}, /* S_RESET (0x00) */ + {0x0400, 19, 1, 0x00000001}, /* HALT_INHIBIT (0x01) */ + {0x0400, 21, 1, 0x00000000}, /* FSRDBGMD (0x00) */ + {0x0400, 22, 1, 0x00000000}, /* BEEP_TEST (0x00) */ + {0x0400, 23, 1, 0x00000000}, /* ARWPHSET (0x00) */ + {0x0400, 28, 1, 0x00000000}, /* DSPRAM4_CLR (0x00) */ + {0x0400, 29, 1, 0x00000000}, /* DSPRAM3_CLR (0x00) */ + {0x0400, 30, 1, 0x00000000}, /* DSPRAM2_CLR (0x00) */ + {0x0400, 31, 1, 0x00000000}, /* DSPRAM1_CLR (0x00) */ + {0x0404, 8, 7, 0x00000010}, /* ALC_DELAY (0x10) */ + {0x0404, 15, 1, 0x00000000}, /* ALC_ALG (0x00) */ + {0x0404, 16, 4, 0x00000000}, /* ARC_TIMER (0x00) */ + {0x0404, 20, 2, 0x00000002}, /* ARC_DLY (0x02) */ + {0x0404, 23, 1, 0x00000001}, /* SPC_AWEIGHT (0x01) */ + {0x0408, 0, 24, 0x00400000}, /* SPC_ALC_ATTACK (0x400000) */ + {0x040c, 0, 24, 0x00000100}, /* SPC_ALC_RELEASE (0x000100) */ + {0x0410, 0, 24, 0x000141b3}, /* ALC_LPF (0x0141b3) */ + {0x0414, 0, 24, 0x00000000}, /* SPC_ENERGY (0x000000) */ + {0x0418, 16, 16, 0x00000000}, /* W_RSRV (0x0000) */ + {0x041c, 0, 8, 0x00000000}, /* R_RSRV (0x00) */ + {0x0500, 0, 1, 0x00000000}, /* SER_MODE (0x00) */ + {0x0500, 16, 1, 0x00000000}, /* PDM_OUT_EN (0x00) */ + {0x0500, 24, 1, 0x00000000}, /* FS_CLK_EN (0x00) */ + {0x0504, 0, 3, 0x00000007}, /* SEL_OUT4_R (0x07) */ + {0x0504, 4, 3, 0x00000006}, /* SEL_OUT4_L (0x06) */ + {0x0504, 8, 3, 0x00000005}, /* SEL_OUT3_R (0x05) */ + {0x0504, 12, 3, 0x00000004}, /* SEL_OUT3_L (0x04) */ + {0x0504, 16, 3, 0x00000003}, /* SEL_OUT2_R (0x03) */ + {0x0504, 20, 3, 0x00000002}, /* SEL_OUT2_L (0x02) */ + {0x0504, 24, 3, 0x00000001}, /* SEL_OUT1_R (0x01) */ + {0x0504, 28, 3, 0x00000000}, /* SEL_OUT1_L (0x00) */ + {0x0580, 0, 1, 0x00000000}, /* OUTEN_MIC1L_B (0x00) */ + {0x0580, 1, 1, 0x00000000}, /* OUTEN_MIC1R_B (0x00) */ + {0x0580, 2, 1, 0x00000000}, /* OUTEN_MIC2L_B (0x00) */ + {0x0580, 3, 1, 0x00000000}, /* OUTEN_MIC2R_B (0x00) */ + {0x0580, 4, 1, 0x00000000}, /* OUTEN_MIC1L_A (0x00) */ + {0x0580, 5, 1, 0x00000000}, /* OUTEN_MIC1R_A (0x00) */ + {0x0580, 6, 1, 0x00000000}, /* OUTEN_MIC2L_A (0x00) */ + {0x0580, 7, 1, 0x00000000}, /* OUTEN_MIC2R_A (0x00) */ + {0x0580, 16, 2, 0x00000000}, /* SEL_OUTF (0x00) */ + {0x0580, 20, 1, 0x00000000}, /* SEL_INF (0x00) */ + {0x0580, 24, 1, 0x00000000}, /* SEL_DECIM (0x00) */ + {0x0600, 0, 24, 0x00200000}, /* DEQ_COEF_1B0 (0x200000) */ + {0x0600, 31, 1, 0x00000000}, /* DEQ_EN (0x00) */ + {0x0604, 0, 24, 0x00000000}, /* DEQ_COEF_1B1 (0x000000) */ + {0x0608, 0, 24, 0x00000000}, /* DEQ_COEF_1B2 (0x000000) */ + {0x060c, 0, 24, 0x00000000}, /* DEQ_COEF_1A1 (0x000000) */ + {0x0610, 0, 24, 0x00000000}, /* DEQ_COEF_1A2 (0x000000) */ + {0x0614, 0, 24, 0x00200000}, /* DEQ_COEF_2B0 (0x200000) */ + {0x0618, 0, 24, 0x00000000}, /* DEQ_COEF_2B1 (0x000000) */ + {0x061c, 0, 24, 0x00000000}, /* DEQ_COEF_2B2 (0x000000) */ + {0x0620, 0, 24, 0x00000000}, /* DEQ_COEF_2A1 (0x000000) */ + {0x0624, 0, 24, 0x00000000}, /* DEQ_COEF_2A2 (0x000000) */ + {0x0628, 0, 24, 0x00200000}, /* DEQ_COEF_3B0 (0x200000) */ + {0x062c, 0, 24, 0x00000000}, /* DEQ_COEF_3B1 (0x000000) */ + {0x0630, 0, 24, 0x00000000}, /* DEQ_COEF_3B2 (0x000000) */ + {0x0634, 0, 24, 0x00000000}, /* DEQ_COEF_3A1 (0x000000) */ + {0x0638, 0, 24, 0x00000000}, /* DEQ_COEF_3A2 (0x000000) */ + {0x063c, 0, 24, 0x00200000}, /* DEQ_COEF_4B0 (0x200000) */ + {0x0640, 0, 24, 0x00000000}, /* DEQ_COEF_4B1 (0x000000) */ + {0x0644, 0, 24, 0x00000000}, /* DEQ_COEF_4B2 (0x000000) */ + {0x0648, 0, 24, 0x00000000}, /* DEQ_COEF_4A1 (0x000000) */ + {0x064c, 0, 24, 0x00000000}, /* DEQ_COEF_4A2 (0x000000) */ + {0x0650, 0, 24, 0x00200000}, /* DEQ_COEF_5B0 (0x200000) */ + {0x0654, 0, 24, 0x00000000}, /* DEQ_COEF_5B1 (0x000000) */ + {0x0658, 0, 24, 0x00000000}, /* DEQ_COEF_5B2 (0x000000) */ + {0x065c, 0, 24, 0x00000000}, /* DEQ_COEF_5A1 (0x000000) */ + {0x0660, 0, 24, 0x00000000}, /* DEQ_COEF_5A2 (0x000000) */ + {0x0664, 0, 24, 0x00200000}, /* DEQ_COEF_6B0 (0x200000) */ + {0x0668, 0, 24, 0x00000000}, /* DEQ_COEF_6B1 (0x000000) */ + {0x066c, 0, 24, 0x00000000}, /* DEQ_COEF_6B2 (0x000000) */ + {0x0670, 0, 24, 0x00000000}, /* DEQ_COEF_6A1 (0x000000) */ + {0x0674, 0, 24, 0x00000000}, /* DEQ_COEF_6A2 (0x000000) */ + {0x0678, 0, 1, 0x00000000}, /* LR_SWAP1 (0x000000) */ + {0x0678, 1, 1, 0x00000000}, /* LR_SWAP2 (0x000000) */ + {0x0700, 0, 1, 0x00000000}, /* DUMMY_0 (0x00) */ + {0x0700, 1, 1, 0x00000000}, /* DUMMY_1 (0x00) */ + {0x0700, 2, 1, 0x00000000}, /* DUMMY_2 (0x00) */ + {0x0700, 3, 1, 0x00000000}, /* DUMMY_3 (0x00) */ + {0x0700, 4, 1, 0x00000000}, /* DUMMY_4 (0x00) */ + {0x0700, 5, 1, 0x00000000}, /* DUMMY_5 (0x00) */ + {0x0700, 6, 1, 0x00000000}, /* DUMMY_6 (0x00) */ + {0x0700, 7, 1, 0x00000000}, /* DUMMY_7 (0x00) */ + {0x0700, 8, 1, 0x00000000}, /* DUMMY_8 (0x00) */ + {0x0700, 9, 1, 0x00000000}, /* DUMMY_9 (0x00) */ + {0x0700, 10, 1, 0x00000000}, /* DUMMY_10 (0x00) */ + {0x0700, 11, 1, 0x00000000}, /* DUMMY_11 (0x00) */ + {0x0700, 12, 1, 0x00000000}, /* DUMMY_12 (0x00) */ + {0x0700, 13, 1, 0x00000000}, /* DUMMY_13 (0x00) */ + {0x0700, 14, 1, 0x00000000}, /* DUMMY_14 (0x00) */ + {0x0700, 15, 1, 0x00000000}, /* DUMMY_15 (0x00) */ + {0x0700, 16, 1, 0x00000000}, /* DUMMY_16 (0x00) */ + {0x0700, 17, 1, 0x00000000}, /* DUMMY_17 (0x00) */ + {0x0700, 18, 1, 0x00000000}, /* DUMMY_18 (0x00) */ + {0x0700, 19, 1, 0x00000000}, /* DUMMY_19 (0x00) */ + {0x0700, 20, 1, 0x00000000}, /* DUMMY_20 (0x00) */ + {0x0700, 21, 1, 0x00000000}, /* DUMMY_21 (0x00) */ + {0x0700, 22, 1, 0x00000000}, /* DUMMY_22 (0x00) */ + {0x0700, 23, 1, 0x00000000}, /* DUMMY_23 (0x00) */ + {0x0700, 24, 1, 0x00000000}, /* DUMMY_24 (0x00) */ + {0x0700, 25, 1, 0x00000000}, /* DUMMY_25 (0x00) */ + {0x0700, 26, 1, 0x00000000}, /* DUMMY_26 (0x00) */ + {0x0700, 27, 1, 0x00000000}, /* DUMMY_27 (0x00) */ + {0x0700, 28, 1, 0x00000000}, /* DUMMY_28 (0x00) */ + {0x0700, 29, 1, 0x00000000}, /* DUMMY_29 (0x00) */ + {0x0700, 30, 1, 0x00000000}, /* DUMMY_30 (0x00) */ + {0x0700, 31, 1, 0x00000000}, /* DUMMY_31 (0x00) */ + {0x0780, 0, 1, 0x00000000}, /* RAM_RW_EN (0x00) */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +uint32_t write_ac_reg(AC_REG_ID reg_id, uint32_t data) +{ + volatile uint32_t *addr; + uint32_t mask = (g_ac_reg[reg_id].len == AC_REG_MAX_BIT) ? + 0xffffffff : (1 << g_ac_reg[reg_id].len) - 1; + uint32_t curr; + + addr = (volatile uint32_t *)(AC_REG_BASE + g_ac_reg[reg_id].addr); + + curr = *addr & ~(mask << g_ac_reg[reg_id].pos); + *addr = curr | ((data & mask) << g_ac_reg[reg_id].pos); + + return 0; +} + +uint32_t read_ac_reg(AC_REG_ID reg_id) +{ + volatile uint32_t *addr; + uint32_t mask = (g_ac_reg[reg_id].len == AC_REG_MAX_BIT) ? + 0xffffffff : (1 << g_ac_reg[reg_id].len) - 1; + uint32_t data = 0; + + addr = (volatile uint32_t *)(AC_REG_BASE + g_ac_reg[reg_id].addr); + data = (*addr >> g_ac_reg[reg_id].pos) & mask; + + return data; +} + +uint32_t write32_ac_reg(uint32_t offset, uint32_t data) +{ + volatile uint32_t *addr; + + addr = (volatile uint32_t *)(AC_REG_BASE + offset); + *addr = data; + + return 0; +} + +uint32_t read32_ac_reg(uint32_t offset) +{ + volatile uint32_t *addr; + uint32_t data = 0; + + addr = (volatile uint32_t *)(AC_REG_BASE + offset); + data = *addr; + + return data; +} + +CXD56_AUDIO_ECODE set_alc_param(void) +{ + /* Set Alc mode play */ + + write_ac_reg(RI_ALC_REC, 0); + + /* Set Alc target. */ + + if (CXD56_AUDIO_CFG_ALC_TARGET < ALC_TARGET_MIN || + CXD56_AUDIO_CFG_ALC_TARGET > ALC_TARGET_MAX) + { + return CXD56_AUDIO_ECODE_REG_AC_ALCTGT; + } + + write_ac_reg(RI_ALCTARGET, -(CXD56_AUDIO_CFG_ALC_TARGET)); + + /* Set Alc knee point. */ + + if (CXD56_AUDIO_CFG_ALC_KNEE < ALC_KNEE_MIN || + CXD56_AUDIO_CFG_ALC_KNEE > ALC_KNEE_MAX) + { + return CXD56_AUDIO_ECODE_REG_AC_ALCKNEE; + } + + write_ac_reg(RI_ALC_KNEE, -(CXD56_AUDIO_CFG_ALC_KNEE) / 5); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE set_spc_param(void) +{ + /* Set Alc target. */ + + if (CXD56_AUDIO_CFG_SPC_LIMIT < SPC_LIMIT_MIN || + CXD56_AUDIO_CFG_SPC_LIMIT > SPC_LIMIT_MAX) + { + return CXD56_AUDIO_ECODE_REG_AC_SPCLIMT; + } + + write_ac_reg(RI_SPC_LIMIT, -(CXD56_AUDIO_CFG_SPC_LIMIT) / 5); + + return CXD56_AUDIO_ECODE_OK; +} + +void write_dnc_ram(uint32_t offset, uint32_t *data, uint32_t size) +{ + uint32_t i; + + for (i = 0; i < size; i++) + { + write32_ac_reg(offset + (i * 4), *(data + i)); + } +} + +void set_deq_coef(uint32_t reg_id, cxd56_audio_deq_coef_func_t *coef) +{ + uint32_t reg_addr = g_ac_reg[reg_id].addr; + + write32_ac_reg(reg_addr, coef->b0); + write32_ac_reg(reg_addr + 4, coef->b1); + write32_ac_reg(reg_addr + 8, coef->b2); + write32_ac_reg(reg_addr + 12, coef->a0); + write32_ac_reg(reg_addr + 16, coef->a1); +} + +static void set_cic_gain(uint8_t cic_num, + FAR cxd56_audio_mic_gain_t *gain) +{ + uint32_t val; + uint8_t write_num; + uint8_t i; + + const uint32_t cic_gain[CXD56_AUDIO_MIC_CH_MAX] = + { + RI_CIC1_LGAIN, + RI_CIC1_RGAIN, + RI_CIC2_LGAIN, + RI_CIC2_RGAIN, + RI_CIC3_LGAIN, + RI_CIC3_RGAIN, + RI_CIC4_LGAIN, + RI_CIC4_RGAIN + }; + + write_num = (CXD56_AUDIO_MIC_CH_MAX >= (cic_num * 2)) ? + (cic_num * 2) : CXD56_AUDIO_MIC_CH_MAX; + + for (i = 0; i < write_num; i++) + { + val = (uint32_t)(pow(10.0f, + ((float)gain->gain[i] / + 100.0f / 20.0f)) * 0x4000 + + 0x4000); + + write_ac_reg(cic_gain[i], val); + } +} + +static uint32_t get_data_rate(uint32_t rate) +{ + uint32_t data_rate; + + if (rate <= I2S_DATA_RATE_LOW) + { + data_rate = 1; + } + else if (rate <= I2S_DATA_RATE_MID) + { + data_rate = 2; + } + else + { + data_rate = 3; + } + + return data_rate; +} + +#ifdef CONFIG_CXD56_I2S0 +static void poweron_i2s0(void) +{ + /* Power on SRC1. */ + + write_ac_reg(RI_PDN_DSPS1, 0); + + /* Set I2S mode of SRC1. */ + + uint32_t is_master = + (CXD56_AUDIO_CFG_I2S1_MODE == CXD56_AUDIO_CFG_I2S_MODE_MASTER) ? 1 : 0; + + write_ac_reg(RI_SD1MASTER, is_master); + + /* Set I2S format of SRC1. */ + + uint32_t is_left = + (CXD56_AUDIO_CFG_I2S1_FORMAT == CXD56_AUDIO_CFG_I2S_FORMAT_LEFT) ? 1 : 0; + + write_ac_reg(RI_DIF1, is_left); + write_ac_reg(RI_LR_SWAP1, is_left); + + /* Set data rate of SRC1. */ + + uint32_t data_rate = get_data_rate(CXD56_AUDIO_CFG_I2S1_DATA_RATE); + write_ac_reg(RI_SRC1, data_rate); + + /* Set bypass mode of SRC1. */ + + uint32_t is_bypass = + (CXD56_AUDIO_CFG_I2S1_BYPASS == CXD56_AUDIO_CFG_I2S_BYPASS_ENABLE) ? 1 : 0; + + write_ac_reg(RI_TEST_OUT_SEL0, is_bypass); +} +#endif /* #ifdef CONFIG_CXD56_I2S0 */ + +#ifdef CONFIG_CXD56_I2S1 +static void poweron_i2s1(void) +{ + /* Power on SRC2. */ + + write_ac_reg(RI_PDN_DSPS2, 0); + + /* Set I2S mode of SRC2. */ + + uint32_t is_master = + (CXD56_AUDIO_CFG_I2S2_MODE == CXD56_AUDIO_CFG_I2S_MODE_MASTER) ? 1 : 0; + write_ac_reg(RI_SD2MASTER, is_master); + + /* Set I2S format of SRC2. */ + + uint32_t is_left = + (CXD56_AUDIO_CFG_I2S2_FORMAT == CXD56_AUDIO_CFG_I2S_FORMAT_LEFT) ? 1 : 0; + write_ac_reg(RI_DIF2, is_left); + write_ac_reg(RI_LR_SWAP2, is_left); + + /* Set data rate of SRC2. */ + + uint32_t data_rate = get_data_rate(CXD56_AUDIO_CFG_I2S2_DATA_RATE); + write_ac_reg(RI_SRC2, data_rate); + + /* Set bypass mode of SRC2. */ + + uint32_t is_bypass = + (CXD56_AUDIO_CFG_I2S2_BYPASS == CXD56_AUDIO_CFG_I2S_BYPASS_ENABLE) ? 1 : 0; + write_ac_reg(RI_TEST_OUT_SEL0, is_bypass); +} +#endif /* #ifdef CONFIG_CXD56_I2S1 */ + +static CXD56_AUDIO_ECODE set_au_dat_sel(AC_REG_ID ac_reg_id, + cxd56_audio_signal_t sig) +{ + uint32_t val = 0; + + switch (sig) + { + case CXD56_AUDIO_SIG_MIC1: + val = AU_DAT_SEL_MIC1; + break; + + case CXD56_AUDIO_SIG_MIC2: + val = AU_DAT_SEL_MIC2; + break; + + case CXD56_AUDIO_SIG_MIC3: + val = AU_DAT_SEL_MIC3; + break; + + case CXD56_AUDIO_SIG_MIC4: + val = AU_DAT_SEL_MIC4; + break; + + case CXD56_AUDIO_SIG_BUSIF1: + if (ac_reg_id == RI_AU_DAT_SEL1) + { + val = AU_DAT_SEL_BUSIF1; + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + break; + + case CXD56_AUDIO_SIG_BUSIF2: + if (ac_reg_id == RI_AU_DAT_SEL2) + { + val = AU_DAT_SEL_BUSIF2; + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + break; + + default: + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + + write_ac_reg(ac_reg_id, val); + + return CXD56_AUDIO_ECODE_OK; +} + +static CXD56_AUDIO_ECODE set_cod_insel(AC_REG_ID ac_reg_id, + cxd56_audio_signal_t sig, + cxd56_audio_sel_t sel) +{ + uint32_t val = 0; + + switch (sig) + { + case CXD56_AUDIO_SIG_MIC1: + case CXD56_AUDIO_SIG_MIC2: + case CXD56_AUDIO_SIG_MIC3: + case CXD56_AUDIO_SIG_MIC4: + if (sel.au_dat_sel1) + { + val = COD_INSEL_AU_DAT_SEL1; + } + else if(sel.au_dat_sel2) + { + val = COD_INSEL_AU_DAT_SEL2; + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + break; + + case CXD56_AUDIO_SIG_BUSIF1: + if (sel.au_dat_sel1) + { + val = COD_INSEL_AU_DAT_SEL1; + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + break; + + case CXD56_AUDIO_SIG_BUSIF2: + if (sel.au_dat_sel2) + { + val = COD_INSEL_AU_DAT_SEL2; + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + break; + + case CXD56_AUDIO_SIG_I2S0: + val = COD_INSEL_SRC1; + break; + + case CXD56_AUDIO_SIG_I2S1: + val = COD_INSEL_SRC2; + break; + + default: + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + + write_ac_reg(ac_reg_id, val); + + return CXD56_AUDIO_ECODE_OK; +} + +static CXD56_AUDIO_ECODE set_srcin_sel(AC_REG_ID ac_reg_id, + cxd56_audio_signal_t sig, + cxd56_audio_sel_t sel) +{ + uint32_t val = 0; + + switch (sig) + { + case CXD56_AUDIO_SIG_MIC1: + case CXD56_AUDIO_SIG_MIC2: + case CXD56_AUDIO_SIG_MIC3: + case CXD56_AUDIO_SIG_MIC4: + if (sel.au_dat_sel1) + { + val = SRCIN_SEL_AU_DAT_SEL1; + } + else if(sel.au_dat_sel2) + { + val = SRCIN_SEL_AU_DAT_SEL2; + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + break; + + case CXD56_AUDIO_SIG_BUSIF1: + if (sel.au_dat_sel1) + { + val = SRCIN_SEL_AU_DAT_SEL1; + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + break; + + case CXD56_AUDIO_SIG_BUSIF2: + if (sel.au_dat_sel2) + { + val = SRCIN_SEL_AU_DAT_SEL2; + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + break; + + case CXD56_AUDIO_SIG_MIX: + if ((read_ac_reg(RI_COD_INSEL2) == COD_INSEL_SRC1) + || (read_ac_reg(RI_COD_INSEL3) == COD_INSEL_SRC1)) + { + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + else + { + val = SRCIN_SEL_CODECDSP_MIX; + } + break; + + default: + return CXD56_AUDIO_ECODE_REG_AC_SEL_INV; + } + + write_ac_reg(ac_reg_id, val); + + return CXD56_AUDIO_ECODE_OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_checkid(void) +{ + if (read_ac_reg(RI_REVID) != AC_REVID) + { + return CXD56_AUDIO_ECODE_REG_AC_REVID; + } + if (read_ac_reg(RI_DEVICEID) != AC_DEVICEID) + { + return CXD56_AUDIO_ECODE_REG_AC_DEVID; + } + + return CXD56_AUDIO_ECODE_OK; +} + +void cxd56_audio_ac_reg_resetdsp(void) +{ + write_ac_reg(RI_S_RESET, 1); + write_ac_reg(RI_S_RESET, 0); + + /* Wait 20ms. */ + + up_mdelay(20); +} + +void cxd56_audio_ac_reg_initdsp(void) +{ + write_ac_reg(RI_PDN_DSPB, 0); + write_ac_reg(RI_PDN_DSPS2, 0); + write_ac_reg(RI_PDN_DSPS1, 0); + write_ac_reg(RI_PDN_DSPC, 0); + + write_ac_reg(RI_DSPRAM4_CLR, 1); + write_ac_reg(RI_DSPRAM2_CLR, 1); + write_ac_reg(RI_DSPRAM1_CLR, 1); + + /* Wait 512 cycle @24.576MHz */ + + up_mdelay(1); + + write_ac_reg(RI_DSPRAM4_CLR, 0); + write_ac_reg(RI_DSPRAM2_CLR, 0); + write_ac_reg(RI_DSPRAM1_CLR, 0); + + write_ac_reg(RI_PDN_DSPB, 1); + write_ac_reg(RI_PDN_DSPS2, 1); + write_ac_reg(RI_PDN_DSPS1, 1); + write_ac_reg(RI_PDN_DSPC, 1); + + write_ac_reg(RI_S_RESET, 1); + write_ac_reg(RI_S_RESET, 0); +} + +void cxd56_audio_ac_reg_poweron_sdes(void) +{ + write_ac_reg(RI_SDES_EN, 1); +} + +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_set_micmode(uint8_t mic_mode) +{ + switch(mic_mode) + { + case CXD56_AUDIO_CFG_MIC_MODE_128FS: + write_ac_reg(RI_FS_FS, 0); + write_ac_reg(RI_SER_MODE, 1); + write_ac_reg(RI_ADC_FS, 1); + break; + + case CXD56_AUDIO_CFG_MIC_MODE_64FS: + write_ac_reg(RI_FS_FS, 1); + write_ac_reg(RI_SER_MODE, 0); + write_ac_reg(RI_ADC_FS, 0); + break; + + default: + return CXD56_AUDIO_ECODE_REG_AC_MICMODE; + } + + write_ac_reg(RI_SEL_OUT1_L, 0); + write_ac_reg(RI_SEL_OUT1_R, 1); + write_ac_reg(RI_SEL_OUT2_L, 2); + write_ac_reg(RI_SEL_OUT2_R, 3); + write_ac_reg(RI_SEL_OUT3_L, 4); + write_ac_reg(RI_SEL_OUT3_R, 5); + write_ac_reg(RI_SEL_OUT4_L, 6); + write_ac_reg(RI_SEL_OUT4_R, 7); + + return CXD56_AUDIO_ECODE_OK; +} + +void cxd56_audio_ac_reg_poweron_codec(void) +{ + write_ac_reg(RI_PDN_DSPC, 0); + write_ac_reg(RI_DSR_RATE, 1); + write_ac_reg(RI_DIGSFT, 1); +} + +void cxd56_audio_ac_reg_poweroff_codec(void) +{ + /* Disable AHBMASTER. */ + + write_ac_reg(RI_MCK_AHBMSTR_EN, 0); + + /* Disable CODEC. */ + + write_ac_reg(RI_ALC_EN, 0); + write_ac_reg(RI_SPC_EN, 0); + write_ac_reg(RI_DEQ_EN, 0); + + /* Disable DNC. */ + + write_ac_reg(RI_DNC1_MUTE, 1); + write_ac_reg(RI_DNC2_MUTE, 1); + write_ac_reg(RI_DNC1_START, 0); + write_ac_reg(RI_DNC2_START, 0); + + /* Disable SRC. */ + + write_ac_reg(RI_SDIN1_EN, 0); + write_ac_reg(RI_SDIN2_EN, 0); + write_ac_reg(RI_SDOUT1_EN, 0); + write_ac_reg(RI_SDOUT2_EN, 0); + write_ac_reg(RI_SDCK_OUTENX, 1); + write_ac_reg(RI_BLF_EN, 0); + + /* Disable SDES. */ + + write_ac_reg(RI_PDM_OUT_EN, 0); + write_ac_reg(RI_FS_CLK_EN, 0); + write_ac_reg(RI_SDES_EN, 0); + + /* Power off SRC. */ + + write_ac_reg(RI_PDN_DSPS1, 1); + write_ac_reg(RI_PDN_DSPS2, 1); + write_ac_reg(RI_PDN_DSPB, 1); + + /* Power off CODEC. */ + + write_ac_reg(RI_PDN_DSPC, 1); + + /* Power off DNC. */ + + write_ac_reg(RI_PDN_DNC1, 1); + write_ac_reg(RI_PDN_DNC2, 1); + write_ac_reg(RI_PDN_ANC, 1); +} + +void cxd56_audio_ac_reg_enable_serialif(void) +{ + write_ac_reg(RI_FS_CLK_EN, 1); + write_ac_reg(RI_PDM_OUT_EN, 1); +} + +void cxd56_audio_ac_reg_init_selector(void) +{ + write_ac_reg(RI_AU_DAT_SEL1, AU_DAT_SEL_BUSIF1); + write_ac_reg(RI_AU_DAT_SEL2, AU_DAT_SEL_BUSIF2); + write_ac_reg(RI_COD_INSEL2, COD_INSEL_AU_DAT_SEL1); + write_ac_reg(RI_COD_INSEL3, COD_INSEL_AU_DAT_SEL2); + write_ac_reg(RI_SRC1IN_SEL, SRCIN_SEL_AU_DAT_SEL1); + write_ac_reg(RI_SRC2IN_SEL, SRCIN_SEL_AU_DAT_SEL2); +} + +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_set_alcspc(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Clear enable status. */ + + write_ac_reg(RI_ALC_EN, 0); + write_ac_reg(RI_SPC_EN, 0); + + if (CXD56_AUDIO_CFG_ALCSPC == CXD56_AUDIO_CFG_ALCSPC_ALC) + { + /* Set auto level control parameter. */ + + ret = set_alc_param(); + if (ret != CXD56_AUDIO_ECODE_OK) + { + return ret; + } + write_ac_reg(RI_ALC_EN, 1); + } + else if (CXD56_AUDIO_CFG_ALCSPC == CXD56_AUDIO_CFG_ALCSPC_SPC) + { + /* Set sound pressure conter */ + + ret = set_spc_param(); + if (ret != CXD56_AUDIO_ECODE_OK) + { + return ret; + } + write_ac_reg(RI_SPC_EN, 1); + } + + return ret; +} + +void cxd56_audio_ac_reg_poweron_dnc(void) +{ + write_ac_reg(RI_PDN_DNC1, 0); + write_ac_reg(RI_PDN_DNC2, 0); + write_ac_reg(RI_PDN_ANC, 0); +} + +void cxd56_audio_ac_reg_poweroff_dnc(void) +{ + write_ac_reg(RI_PDN_DNC1, 1); + write_ac_reg(RI_PDN_DNC2, 1); + write_ac_reg(RI_PDN_ANC, 1); + + /* Clear DNC SRAM. */ + + write_ac_reg(RI_DSPRAM3_CLR, 1); + + /* Wait 512 cycle @24.576MHz */ + + up_mdelay(1); + + write_ac_reg(RI_DSPRAM3_CLR, 0); +} + +void cxd56_audio_ac_reg_disable_dnc(cxd56_audio_dnc_id_t id) +{ + if (CXD56_AUDIO_DNC_ID_FB == id) + { + write_ac_reg(RI_DNC1_MUTE, 1); + write_ac_reg(RI_DNC1_START, 0); + } + else + { + write_ac_reg(RI_DNC2_MUTE, 1); + write_ac_reg(RI_DNC2_START, 0); + } +} + +void cxd56_audio_ac_reg_enable_dnc(cxd56_audio_dnc_id_t id) +{ + if (CXD56_AUDIO_DNC_ID_FB == id) + { + write_ac_reg(RI_DNC1_START, 1); + write_ac_reg(RI_DNC1_MUTE, 0); + } + else + { + write_ac_reg(RI_DNC2_START, 1); + write_ac_reg(RI_DNC2_MUTE, 0); + } +} + +void cxd56_audio_ac_reg_set_dncram(cxd56_audio_dnc_id_t id, + FAR cxd56_audio_dnc_bin_t *bin) +{ + uint32_t iram_reg; + uint32_t cram_reg; + + if (CXD56_AUDIO_DNC_ID_FB == id) + { + iram_reg = DNC1_IRAM_BASE; + cram_reg = DNC1_CRAM_BASE; + } + else + { + iram_reg = DNC2_IRAM_BASE; + cram_reg = DNC2_CRAM_BASE; + } + + write_ac_reg(RI_RAM_RW_EN, 1); + + /* Write to SRAM. */ + + write_dnc_ram(iram_reg, bin->firm, DNC_IRAM_SIZE); + write_dnc_ram(cram_reg, bin->config, DNC_CRAM_SIZE); + + write_ac_reg(RI_RAM_RW_EN, 0); +} + +void cxd56_audio_ac_reg_enable_deq(void) +{ + write_ac_reg(RI_DEQ_EN, 1); +} + +void cxd56_audio_ac_reg_disable_deq(void) +{ + write_ac_reg(RI_DEQ_EN, 0); +} + +void cxd56_audio_ac_reg_set_deq_param(FAR cxd56_audio_deq_coef_t *deq) +{ + set_deq_coef(RI_DEQ_COEF_1B0, &deq->coef[0]); + set_deq_coef(RI_DEQ_COEF_2B0, &deq->coef[1]); + set_deq_coef(RI_DEQ_COEF_3B0, &deq->coef[2]); + set_deq_coef(RI_DEQ_COEF_4B0, &deq->coef[3]); + set_deq_coef(RI_DEQ_COEF_5B0, &deq->coef[4]); + set_deq_coef(RI_DEQ_COEF_6B0, &deq->coef[5]); +} + +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_poweron_cic(uint8_t mic_in, + uint8_t mic_mode, + uint8_t cic_num, + FAR cxd56_audio_mic_gain_t *gain) +{ + /* Power on CIC. */ + + if (mic_in == CXD56_AUDIO_CFG_CIC_IN_SEL_CXD) + { + if (cic_num > 3) + { + write_ac_reg(RI_CIC4IN_SEL, 0); + write_ac_reg(RI_HPF4_MODE, 1); + } + if (cic_num > 2) + { + if (read_ac_reg(RI_PDN_AMICEXT) == 1) + { + write_ac_reg(RI_PDN_AMICEXT, 0); + } + write_ac_reg(RI_CIC3IN_SEL, 0); + write_ac_reg(RI_HPF3_MODE, 1); + } + if (cic_num > 1) + { + write_ac_reg(RI_PDN_AMIC2, 0); + write_ac_reg(RI_CIC2IN_SEL, 0); + write_ac_reg(RI_HPF2_MODE, 1); + write_ac_reg(RI_CIC2_GAIN_MODE, 1); + } + if (cic_num > 0) + { + write_ac_reg(RI_PDN_AMIC1, 0); + write_ac_reg(RI_CIC1IN_SEL, 0); + write_ac_reg(RI_HPF1_MODE, 1); + write_ac_reg(RI_CIC1_GAIN_MODE, 1); + } + } + else if(mic_in == CXD56_AUDIO_CFG_CIC_IN_SEL_DMICIF) + { + if (read_ac_reg(RI_PDN_DMIC) == 1) + { + write_ac_reg(RI_PDN_DMIC, 0); + } + + if (cic_num > 3) + { + write_ac_reg(RI_CIC4IN_SEL, 1); + write_ac_reg(RI_HPF4_MODE, 1); + } + if (cic_num > 2) + { + write_ac_reg(RI_CIC3IN_SEL, 1); + write_ac_reg(RI_HPF3_MODE, 1); + } + if (cic_num > 1) + { + write_ac_reg(RI_CIC2IN_SEL, 1); + write_ac_reg(RI_HPF2_MODE, 1); + write_ac_reg(RI_CIC2_GAIN_MODE, 1); + } + if (cic_num > 0) + { + write_ac_reg(RI_CIC1IN_SEL, 1); + write_ac_reg(RI_HPF1_MODE, 1); + write_ac_reg(RI_CIC1_GAIN_MODE, 1); + } + } + else + { + /* Do nothing. */ + } + + if (mic_mode == CXD56_AUDIO_CFG_MIC_MODE_128FS) + { + write_ac_reg(RI_ADC_FS, 1); + } + else if (mic_mode == CXD56_AUDIO_CFG_MIC_MODE_64FS) + { + write_ac_reg(RI_ADC_FS, 0); + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_MICMODE; + } + + set_cic_gain(cic_num, gain); + + return CXD56_AUDIO_ECODE_OK; +} + +void cxd56_audio_ac_reg_poweroff_cic(void) +{ + /* Power off CIC. */ + + write_ac_reg(RI_PDN_AMIC1, 1); + write_ac_reg(RI_PDN_AMIC2, 1); + write_ac_reg(RI_PDN_AMICEXT, 1); + write_ac_reg(RI_PDN_DMIC, 1); +} + +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_poweron_decim(uint8_t mic_mode, + uint8_t clk_mode) +{ + /* Enable AHBMASTER. + * Because the output of DecimationFilter is input to BusIF. + */ + + write_ac_reg(RI_MCK_AHBMSTR_EN, 1); + + /* Power on DECIM. */ + + write_ac_reg(RI_DECIM0_EN, 1); + + /* DECIM param */ + + if ((mic_mode == CXD56_AUDIO_CFG_MIC_MODE_64FS) && + (clk_mode == CXD56_AUDIO_CLKMODE_HIRES)) + { + write_ac_reg(RI_SEL_DECIM, 0); + } + else + { + write_ac_reg(RI_SEL_DECIM, 1); + } + + if (mic_mode == CXD56_AUDIO_CFG_MIC_MODE_128FS) + { + write_ac_reg(RI_SEL_INF, 1); + write_ac_reg(RI_DCMFS, 2); + write_ac_reg(RI_DCMFS_34, 2); + } + else if (mic_mode == CXD56_AUDIO_CFG_MIC_MODE_64FS) + { + write_ac_reg(RI_SEL_INF, 0); + write_ac_reg(RI_DCMFS, 1); + write_ac_reg(RI_DCMFS_34, 1); + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_MICMODE; + } + + if (clk_mode == CXD56_AUDIO_CLKMODE_NORMAL) + { + write_ac_reg(RI_SEL_OUTF, 0); + } + else if (clk_mode == CXD56_AUDIO_CLKMODE_HIRES) + { + write_ac_reg(RI_SEL_OUTF, 2); + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_CLKMODE; + } + + /* DECIM_SEL */ + + write_ac_reg(RI_OUTEN_MIC2R_A, ((0x0f >> 3) & 0x01)); + write_ac_reg(RI_OUTEN_MIC2L_A, ((0x0f >> 2) & 0x01)); + write_ac_reg(RI_OUTEN_MIC1R_A, ((0x0f >> 1) & 0x01)); + write_ac_reg(RI_OUTEN_MIC1L_A, ((0x0f >> 0) & 0x01)); + + write_ac_reg(RI_OUTEN_MIC2R_B, ((0x0f >> 3) & 0x01)); + write_ac_reg(RI_OUTEN_MIC2L_B, ((0x0f >> 2) & 0x01)); + write_ac_reg(RI_OUTEN_MIC1R_B, ((0x0f >> 1) & 0x01)); + write_ac_reg(RI_OUTEN_MIC1L_B, ((0x0f >> 0) & 0x01)); + + return CXD56_AUDIO_ECODE_OK; +} + +void cxd56_audio_ac_reg_poweroff_decim(void) +{ + write_ac_reg(RI_DECIM0_EN, 0); +} + +void cxd56_audio_ac_reg_poweron_smaster(uint8_t clk_mode) +{ + /* Power on S-Mster. */ + + write_ac_reg(RI_PDN_SMSTR, 0); + + /* Set NSDD. */ + + write_ac_reg(RI_NSDD, 0x07fb5); + + /* Set NSX2. */ + + if ((clk_mode == CXD56_AUDIO_CLKMODE_HIRES) && + (CXD56_AUDIO_CFG_MCLK == CXD56_AUDIO_CFG_XTAL_49_152MHZ)) + { + write_ac_reg(RI_NSX2, 1); + } + else + { + write_ac_reg(RI_NSX2, 0); + } +} + +void cxd56_audio_ac_reg_poweroff_smaster(void) +{ + write_ac_reg(RI_PDN_SMSTR, 1); +} + +void cxd56_audio_ac_reg_enable_smaster(void) +{ + write_ac_reg(RI_NSPMUTE, 0); +} + +void cxd56_audio_ac_reg_disable_smaster(void) +{ + write_ac_reg(RI_NSPMUTE, 1); +} + +void cxd56_audio_ac_reg_enable_beep(void) +{ + write_ac_reg(RI_BEEP_ON, 1); +} + +void cxd56_audio_ac_reg_disable_beep(void) +{ + write_ac_reg(RI_BEEP_ON, 0); +} + +void cxd56_audio_ac_reg_set_beep_freq(uint32_t freq) +{ + write_ac_reg(RI_BEEP_FREQ, freq); +} + +void cxd56_audio_ac_reg_set_beep_vol(uint32_t vol) +{ + write_ac_reg(RI_BEEP_VOL, vol); +} + +void cxd56_audio_ac_reg_set_cicgain(uint8_t cic_num, + FAR cxd56_audio_mic_gain_t *gain) +{ + set_cic_gain(cic_num, gain); +} + +void cxd56_audio_ac_reg_enable_digsft(void) +{ + write_ac_reg(RI_DIGSFT, 1); +} + +void cxd56_audio_ac_reg_disable_digsft(void) +{ + write_ac_reg(RI_DIGSFT, 0); +} + +void cxd56_audio_ac_reg_set_dsrrate(uint32_t rate) +{ + write_ac_reg(RI_DSR_RATE, rate); +} + +void cxd56_audio_ac_reg_set_seloutch(FAR cxd56_audio_ac_reg_seloutch_t *seloutch) +{ + write_ac_reg(RI_SEL_OUT1_L, seloutch->ch[0]); + write_ac_reg(RI_SEL_OUT1_R, seloutch->ch[1]); + write_ac_reg(RI_SEL_OUT2_L, seloutch->ch[2]); + write_ac_reg(RI_SEL_OUT2_R, seloutch->ch[3]); + write_ac_reg(RI_SEL_OUT3_L, seloutch->ch[4]); + write_ac_reg(RI_SEL_OUT3_R, seloutch->ch[5]); + write_ac_reg(RI_SEL_OUT4_L, seloutch->ch[6]); + write_ac_reg(RI_SEL_OUT4_R, seloutch->ch[7]); +} + +void cxd56_audio_ac_reg_enable_dma(void) +{ + write_ac_reg(RI_MCK_AHBMSTR_EN, 1); +} + +void cxd56_audio_ac_reg_poweron_i2s(uint8_t clk_mode) +{ +#ifdef CONFIG_CXD56_I2S0 + /* Power on I2S0 device. */ + + poweron_i2s0(); +#endif /* CONFIG_CXD56_I2S0 */ + +#ifdef CONFIG_CXD56_I2S1 + /* Power on I2S1 device. */ + + poweron_i2s1(); +#endif /* CONFIG_CXD56_I2S1 */ + + /* Power on output filter. */ + + write_ac_reg(RI_PDN_DSPB, 0); + + /* Set hi-res mode. */ + + uint32_t is_hires = + (clk_mode == CXD56_AUDIO_CLKMODE_HIRES) ? 1 : 0; + + write_ac_reg(RI_HI_RES_MODE, is_hires); + + /* Enable BLF block. */ + + write_ac_reg(RI_BLF_EN, 1); + + /* Disable auto mute of SRC. */ + + write_ac_reg(RI_ARWPHSET, 0); + + /* Enable clock halt of SRC. */ + + write_ac_reg(RI_HALT_INHIBIT, 0); +} + +void cxd56_audio_ac_reg_enable_i2s_src1(void) +{ + write_ac_reg(RI_SDIN1_EN, 1); + write_ac_reg(RI_SDOUT1_EN, 1); +} + +void cxd56_audio_ac_reg_enable_i2s_src2(void) +{ + write_ac_reg(RI_SDIN2_EN, 1); + write_ac_reg(RI_SDOUT2_EN, 1); +} + +void cxd56_audio_ac_reg_enable_i2s_bcklrckout(void) +{ + write_ac_reg(RI_SDCK_OUTENX, 0); +} + +void cxd56_audio_ac_reg_disable_i2s_bcklrckout(void) +{ + write_ac_reg(RI_SDCK_OUTENX, 1); +} + +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_set_selector(cxd56_audio_signal_t sig, + cxd56_audio_sel_t sel) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + if (sel.au_dat_sel1) + { + ret = set_au_dat_sel(RI_AU_DAT_SEL1, sig); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + } + + if (sel.au_dat_sel2) + { + ret = set_au_dat_sel(RI_AU_DAT_SEL2, sig); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + } + + if (sel.cod_insel2) + { + ret = set_cod_insel(RI_COD_INSEL2, sig, sel); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + } + + if (sel.cod_insel3) + { + ret = set_cod_insel(RI_COD_INSEL3, sig, sel); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + } + + if (sel.src1in_sel) + { + ret = set_srcin_sel(RI_SRC1IN_SEL, sig, sel); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + } + + if (sel.src2in_sel) + { + ret = set_srcin_sel(RI_SRC2IN_SEL, sig, sel); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_enable_cstereo(bool sign_inv, + int16_t vol) +{ + /* Set Clear Stereo data inverse. false: Positive, true: Negative */ + + write_ac_reg(RI_CS_SIGN, sign_inv); + + if ((CS_VOL_MIN <= vol) && (vol <= CS_VOL_MAX)) + { + uint32_t val = ((vol + CS_VOL_OFFSET) / 5) & 0x7f; + write_ac_reg(RI_CS_VOL, val); + } + else + { + return CXD56_AUDIO_ECODE_REG_AC_CSTE_VOL; + } + + return CXD56_AUDIO_ECODE_OK; +} + +void cxd56_audio_ac_reg_disable_cstereo(void) +{ + write_ac_reg(RI_CS_VOL, 0x00); +} + +void cxd56_audio_ac_reg_set_vol_sdin1(uint32_t vol) +{ + write_ac_reg(RI_SDIN1_VOL, vol); +} + +void cxd56_audio_ac_reg_set_vol_sdin2(uint32_t vol) +{ + write_ac_reg(RI_SDIN2_VOL, vol); +} + +void cxd56_audio_ac_reg_set_vol_dac(uint32_t vol) +{ + write_ac_reg(RI_DAC_VOL, vol); +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_ac_reg.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_ac_reg.h new file mode 100644 index 00000000000..4437d093c28 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_ac_reg.h @@ -0,0 +1,454 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_ac_reg.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_AC_REG_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_AC_REG_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +enum audio_codec_register_id_e +{ + RI_REVID = 0, + RI_DEVICEID, + RI_PDN_AMICEXT, + RI_PDN_AMIC1, + RI_PDN_AMIC2, + RI_PDN_DAC, + RI_PDN_LINEIN, + RI_PDN_MIC, + RI_PDN_DMIC, + RI_PDN_DSPB, + RI_PDN_ANC, + RI_PDN_DNC1, + RI_PDN_DNC2, + RI_PDN_SMSTR, + RI_PDN_DSPS2, + RI_PDN_DSPS1, + RI_PDN_DSPC, + RI_FS_FS, + RI_DECIM0_EN, + RI_DECIM1_EN, + RI_SDES_EN, + RI_MCK_AHBMSTR_EN, + RI_AU_DAT_SEL2, + RI_AU_DAT_SEL1, + RI_COD_INSEL3, + RI_COD_INSEL2, + RI_COD_INSEL1, + RI_DSR_RATE, + RI_DIGSFT, + RI_SRC1, + RI_SRC1IN_SEL, + RI_SRC2, + RI_SRC2IN_SEL, + RI_DIF2, + RI_DIF1, + RI_SD2MASTER, + RI_SD1MASTER, + RI_SDCK_OUTENX, + RI_HI_RES_MODE, + RI_HPF2_MODE, + RI_CIC2IN_SWAP, + RI_INV_DMIC2L, + RI_INV_DMIC2R, + RI_CIC2_GAIN_MODE, + RI_CIC2IN_SEL, + RI_ADC2_BOOST, + RI_INV_AMIC2L, + RI_INV_AMIC2R, + RI_HPF1_MODE, + RI_CIC1IN_SWAP, + RI_INV_DMIC1L, + RI_INV_DMIC1R, + RI_CIC1_GAIN_MODE, + RI_CIC1IN_SEL, + RI_ADC1_BOOST, + RI_ADC_FS, + RI_INV_AMIC1L, + RI_INV_AMIC1R, + RI_HPF4_MODE, + RI_CIC4IN_SWAP, + RI_INV_DMIC4L, + RI_INV_DMIC4R, + RI_CIC4IN_SEL, + RI_ADC4_BOOST, + RI_INV_AMIC4L, + RI_INV_AMIC4R, + RI_HPF3_MODE, + RI_CIC3IN_SWAP, + RI_INV_DMIC3L, + RI_INV_DMIC3R, + RI_CIC3IN_SEL, + RI_ADC_3_BOOST, + RI_INV_AMIC3L, + RI_INV_AMIC3R, + RI_CIC1_RGAIN, + RI_CIC1_LGAIN, + RI_CIC2_RGAIN, + RI_CIC2_LGAIN, + RI_CIC3_RGAIN, + RI_CIC3_LGAIN, + RI_CIC4_RGAIN, + RI_CIC4_LGAIN, + RI_SPC_LIMIT, + RI_SPC_EN, + RI_ALC_KNEE, + RI_ALCTARGET, + RI_ALC_REC, + RI_ALC_EN, + RI_INV_ASP2R, + RI_INV_ASP2L, + RI_INV_ASP1R, + RI_INV_ASP1L, + RI_ARC, + RI_ARC_VOL, + RI_CS_VOL, + RI_CS_SIGN, + RI_SDOUT_VOL, + RI_SDIN2_VOL, + RI_SDIN1_VOL, + RI_SDIN1_EN, + RI_SDIN2_EN, + RI_SDOUT1_EN, + RI_SDOUT2_EN, + RI_MUTE_B, + RI_BLF_EN, + RI_TRANS_MODE, + RI_DAC_VOL, + RI_LINEIN_VOL, + RI_BEEP_VOL, + RI_BEEP_FREQ, + RI_BEEP_ON, + RI_M_SPCLKERR1, + RI_M_SPCLKERR2, + RI_ADC1L_VOL, + RI_ADC1R_VOL, + RI_ADC2L_VOL, + RI_ADC2R_VOL, + RI_SMS_INTIM, + RI_DNC2_AVF, + RI_DNC2_MONION1, + RI_DNC2_MONIEN1, + RI_DNC2_MONION0, + RI_DNC2_MONIEN0, + RI_DNC1_AVF, + RI_DNC1_MONION1, + RI_DNC1_MONIEN1, + RI_DNC1_MONION0, + RI_DNC1_MONIEN0, + RI_DNC2_CFMD, + RI_DNC2_ESS, + RI_DNC2_ZWR, + RI_DNC2_MUTE, + RI_DNC2_START, + RI_DNC1_CFMD, + RI_DNC1_ESS, + RI_DNC1_ZWR, + RI_DNC1_MUTE, + RI_DNC1_START, + RI_DNC_STB, + RI_DCMFS_34, + RI_DNC_512, + RI_DCMFS, + RI_DNC1_CANVOL1, + RI_DNC1_CANVOL0, + RI_DNC2_CANVOL1, + RI_DNC2_CANVOL0, + RI_DNC1_MONVOL1, + RI_DNC1_MONVOL0, + RI_DNC2_MONVOL1, + RI_DNC2_MONVOL0, + RI_DNC1_ALGAIN1, + RI_DNC1_ALGAIN0, + RI_DNC2_ALGAIN1, + RI_DNC2_ALGAIN0, + RI_DNC_PHD, + RI_DNC1_LIMIYT, + RI_DNC1_LMTON0, + RI_DNC1_LIMITR, + RI_DNC1_LIMITA, + RI_DNC1_INSTMD, + RI_DNC2_LIMIYT, + RI_DNC2_LMTON0, + RI_DNC2_LIMITR, + RI_DNC2_LIMITA, + RI_DNC2_INSTMD, + RI_ANC_FALVL, + RI_ANC_TST, + RI_ANC_FATST, + RI_ENVREG_RESET, + RI_ANC_CHSEL, + RI_ANC_TR, + RI_ANC_TA, + RI_ANC_SOUT, + RI_ANC_FASPN, + RI_ANC_ZWR, + RI_ANC_MUTE, + RI_ANC_START, + RI_ANC_FASTART, + RI_ANC_FAWTB, + RI_ANC_FAWTA, + RI_ANC_ENV1, + RI_ANC_ENV0, + RI_ANC_CURST, + RI_ANC_FAST, + RI_ANC_ENV2, + RI_NS_AMMD, + RI_BPGAIN, + RI_BPSEL, + RI_NSDI, + RI_NSII, + RI_BPON, + RI_NSMS, + RI_CHSEL, + RI_NSADJON, + RI_NSX2, + RI_NSPMUTE, + RI_NSDD, + RI_OUT2DLY, + RI_NSAD, + RI_PWMMD, + RI_NSAS, + RI_NSADJ, + RI_VCONT, + RI_TEST_OUT, + RI_TEST_OUT_SEL0, + RI_TEST_OUT_SEL1, + RI_TEST_IN, + RI_S_RESET, + RI_HALT_INHIBIT, + RI_FSRDBGMD, + RI_BEEP_TEST, + RI_ARWPHSET, + RI_DSPRAM4_CLR, + RI_DSPRAM3_CLR, + RI_DSPRAM2_CLR, + RI_DSPRAM1_CLR, + RI_ALC_DELAY, + RI_ALC_ALG, + RI_ARC_TIMER, + RI_ARC_DLY, + RI_SPC_AWEIGHT, + RI_SPC_ALC_ATTACK, + RI_SPC_ALC_RELEASE, + RI_ALC_LPF, + RI_SPC_ENERGY, + RI_W_RSRV, + RI_R_RSRV, + RI_SER_MODE, + RI_PDM_OUT_EN, + RI_FS_CLK_EN, + RI_SEL_OUT4_R, + RI_SEL_OUT4_L, + RI_SEL_OUT3_R, + RI_SEL_OUT3_L, + RI_SEL_OUT2_R, + RI_SEL_OUT2_L, + RI_SEL_OUT1_R, + RI_SEL_OUT1_L, + RI_OUTEN_MIC1L_B, + RI_OUTEN_MIC1R_B, + RI_OUTEN_MIC2L_B, + RI_OUTEN_MIC2R_B, + RI_OUTEN_MIC1L_A, + RI_OUTEN_MIC1R_A, + RI_OUTEN_MIC2L_A, + RI_OUTEN_MIC2R_A, + RI_SEL_OUTF, + RI_SEL_INF, + RI_SEL_DECIM, + RI_DEQ_COEF_1B0, + RI_DEQ_EN, + RI_DEQ_COEF_1B1, + RI_DEQ_COEF_1B2, + RI_DEQ_COEF_1A1, + RI_DEQ_COEF_1A2, + RI_DEQ_COEF_2B0, + RI_DEQ_COEF_2B1, + RI_DEQ_COEF_2B2, + RI_DEQ_COEF_2A1, + RI_DEQ_COEF_2A2, + RI_DEQ_COEF_3B0, + RI_DEQ_COEF_3B1, + RI_DEQ_COEF_3B2, + RI_DEQ_COEF_3A1, + RI_DEQ_COEF_3A2, + RI_DEQ_COEF_4B0, + RI_DEQ_COEF_4B1, + RI_DEQ_COEF_4B2, + RI_DEQ_COEF_4A1, + RI_DEQ_COEF_4A2, + RI_DEQ_COEF_5B0, + RI_DEQ_COEF_5B1, + RI_DEQ_COEF_5B2, + RI_DEQ_COEF_5A1, + RI_DEQ_COEF_5A2, + RI_DEQ_COEF_6B0, + RI_DEQ_COEF_6B1, + RI_DEQ_COEF_6B2, + RI_DEQ_COEF_6A1, + RI_DEQ_COEF_6A2, + RI_LR_SWAP1, + RI_LR_SWAP2, + RI_DUMMY_0, + RI_DUMMY_1, + RI_DUMMY_2, + RI_DUMMY_3, + RI_DUMMY_4, + RI_DUMMY_5, + RI_DUMMY_6, + RI_DUMMY_7, + RI_DUMMY_8, + RI_DUMMY_9, + RI_DUMMY_10, + RI_DUMMY_11, + RI_DUMMY_12, + RI_DUMMY_13, + RI_DUMMY_14, + RI_DUMMY_15, + RI_DUMMY_16, + RI_DUMMY_17, + RI_DUMMY_18, + RI_DUMMY_19, + RI_DUMMY_20, + RI_DUMMY_21, + RI_DUMMY_22, + RI_DUMMY_23, + RI_DUMMY_24, + RI_DUMMY_25, + RI_DUMMY_26, + RI_DUMMY_27, + RI_DUMMY_28, + RI_DUMMY_29, + RI_DUMMY_30, + RI_DUMMY_31, + RI_RAM_RW_EN, + RI_REG_MAX_ENTRY +}; + +typedef enum audio_codec_register_id_e AC_REG_ID; + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +struct cxd56_audio_ac_reg_seloutch_s +{ + uint8_t ch[CXD56_AUDIO_MIC_CH_MAX]; +}; + +typedef struct cxd56_audio_ac_reg_seloutch_s cxd56_audio_ac_reg_seloutch_t; + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_checkid(void); +void cxd56_audio_ac_reg_resetdsp(void); +void cxd56_audio_ac_reg_initdsp(void); +void cxd56_audio_ac_reg_poweron_sdes(void); +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_set_micmode(uint8_t mic_mode); +void cxd56_audio_ac_reg_poweron_codec(void); +void cxd56_audio_ac_reg_poweroff_codec(void); +void cxd56_audio_ac_reg_enable_serialif(void); +void cxd56_audio_ac_reg_init_selector(void); +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_set_alcspc(void); +void cxd56_audio_ac_reg_poweron_dnc(void); +void cxd56_audio_ac_reg_poweroff_dnc(void); +void cxd56_audio_ac_reg_disable_dnc(cxd56_audio_dnc_id_t id); +void cxd56_audio_ac_reg_enable_dnc(cxd56_audio_dnc_id_t id); +void cxd56_audio_ac_reg_mute_dnc(cxd56_audio_dnc_id_t id); +void cxd56_audio_ac_reg_unmute_dnc(cxd56_audio_dnc_id_t id); +void cxd56_audio_ac_reg_set_dncram(cxd56_audio_dnc_id_t id, + FAR cxd56_audio_dnc_bin_t *bin); +void cxd56_audio_ac_reg_enable_deq(void); +void cxd56_audio_ac_reg_disable_deq(void); +void cxd56_audio_ac_reg_set_deq_param(FAR cxd56_audio_deq_coef_t *deq); +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_poweron_cic(uint8_t mic_in, + uint8_t mic_mode, + uint8_t cic_num, + FAR cxd56_audio_mic_gain_t *gain); +void cxd56_audio_ac_reg_poweroff_cic(void); +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_poweron_decim(uint8_t mic_mode, + uint8_t clk_mode); +void cxd56_audio_ac_reg_poweroff_decim(void); +void cxd56_audio_ac_reg_poweron_smaster(uint8_t clk_mode); +void cxd56_audio_ac_reg_poweroff_smaster(void); +void cxd56_audio_ac_reg_enable_smaster(void); +void cxd56_audio_ac_reg_disable_smaster(void); +void cxd56_audio_ac_reg_enable_beep(void); +void cxd56_audio_ac_reg_disable_beep(void); +void cxd56_audio_ac_reg_set_beep_freq(uint32_t freq); +void cxd56_audio_ac_reg_set_beep_vol(uint32_t vol); +void cxd56_audio_ac_reg_set_cicgain(uint8_t cic_num, + FAR cxd56_audio_mic_gain_t *gain); +void cxd56_audio_ac_reg_enable_digsft(void); +void cxd56_audio_ac_reg_disable_digsft(void); +void cxd56_audio_ac_reg_set_dsrrate(uint32_t rate); +void cxd56_audio_ac_reg_set_seloutch(FAR cxd56_audio_ac_reg_seloutch_t *seloutch); +void cxd56_audio_ac_reg_enable_dma(void); + +void cxd56_audio_ac_reg_poweron_i2s(uint8_t clk_mode); +void cxd56_audio_ac_reg_enable_i2s_src1(void); +void cxd56_audio_ac_reg_enable_i2s_src2(void); +void cxd56_audio_ac_reg_enable_i2s_bcklrckout(void); +void cxd56_audio_ac_reg_disable_i2s_bcklrckout(void); + +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_set_selector(cxd56_audio_signal_t sig, + cxd56_audio_sel_t sel); + +CXD56_AUDIO_ECODE cxd56_audio_ac_reg_enable_cstereo(bool sign_inv, + int16_t vol); +void cxd56_audio_ac_reg_disable_cstereo(void); +void cxd56_audio_ac_reg_set_vol_sdin1(uint32_t vol); +void cxd56_audio_ac_reg_set_vol_sdin2(uint32_t vol); +void cxd56_audio_ac_reg_set_vol_dac(uint32_t vol); +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_AC_REG_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_aca.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_aca.c new file mode 100644 index 00000000000..fbfdb91ba17 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_aca.c @@ -0,0 +1,801 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_aca.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_aca.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MIC_CH_BITNUM 4 +#define MIC_CH_BITMAP 0xf + +#define MIC_GAIN_MAX 150 +#define MIC_GAIN_MIN 0 + +#define PGA_GAIN_MAX 60 +#define PGA_GAIN_MIN 0 + +#define AS_VGAIN_MAX 60 +#define AS_VGAIN_MIN -95 + +typedef enum +{ + AS_ACA_OSC_UNKNOWN, + AS_ACA_OSC_24_576MHZ, /* 24.576MHz */ + AS_ACA_OSC_24_576MHZ_HIRES, /* 24.576MHz,Hi-Res */ + AS_ACA_OSC_49_152MHZ, /* 49.152MHz */ + AS_ACA_OSC_49_152MHZ_HIRES, /* 49.152MHz,Hi-Res */ + AS_ACA_OSC_MAX_ENTRY +} asAcaPulcoOscModeId; + +typedef enum +{ + AS_ACA_MIC_UNKNOWN, + AS_ACA_MIC_AMIC, /* Analog MIC */ + AS_ACA_MIC_DMIC, /* Digital MIC */ + AS_ACA_MIC_BOTH, /* Analog MIC and Digital MIC */ + AS_ACA_MIC_MAX_ENTRY +} asAcaPulcoMicDeviceId; + +typedef enum +{ + AS_ACA_MICBIAS_SEL_UNKNOWN, + AS_ACA_MICBIAS_SEL_2_0V, /* 2.0V */ + AS_ACA_MICBIAS_SEL_2_8V, /* 2.8V */ + AS_ACA_MICBIAS_SEL_MAX_ENTRY +} asAcaPulcoMicBiasSelId; + +typedef enum +{ + AS_ACA_IO_DS_UNKNOWN, + AS_ACA_IO_DS_WEAKEST, /* Weakest */ + AS_ACA_IO_DS_WEAKER, /* Weaker */ + AS_ACA_IO_DS_STRONGER, /* Stronger */ + AS_ACA_IO_DS_STRONGEST, /* Strongest */ + AS_ACA_IO_DS_MAX_ENTRY +} asAcaPulcoIoDsId; + +typedef enum +{ + AS_SMSTR_MODE_FS_UNKNOWN, + AS_SMSTR_MODE_FS_16, /* 16fs */ + AS_SMSTR_MODE_FS_32, /* 32fs */ + AS_SMSTR_MODE_FS_MAX_ENTRY +} asSmstrModeId; + +typedef enum +{ + AS_SMSTR_MCK_FS_UNKNOWN, + AS_SMSTR_MCK_FS_512, /* 512fs */ + AS_SMSTR_MCK_FS_1024, /* 1024fs */ + AS_SMSTR_MCK_FS_MAX_ENTRY +} asSmstrMckId; + +typedef enum +{ + AS_SMSTR_PWMMD_UNKNOWN, + AS_SMSTR_PWMMD_SINGLE, /* Single side */ + AS_SMSTR_PWMMD_BOTH, /* Both side */ + AS_SMSTR_PWMMD_SINGLE_ALTER, /* Single side alternating */ + AS_SMSTR_PWMMD_BOTH_ALTER, /* Both side alternating */ + AS_SMSTR_PWMMD_MAX_ENTRY +} asSmstrPwmModeId; + +typedef enum +{ + AS_SMSTR_CHSEL_UNKNOWN, + AS_SMSTR_CHSEL_NORMAL, /* Normal */ + AS_SMSTR_CHSEL_EXCHANGE, /* Exchange L and R */ + AS_SMSTR_CHSEL_MAX_ENTRY +} asSmstrChSelId; + +typedef enum +{ + AS_ACA_OUT_UNKNOWN, + AS_ACA_OUT_HP, /* Headphone output */ + AS_ACA_OUT_EP, /* Ear Speaker output */ + AS_ACA_OUT_PWM, /* PWM output */ + AS_ACA_OUT_HP_PWM, /* Headphone and PWM output */ + AS_ACA_OUT_EP_PWM, /* Ear Speaker and PWM output */ + AS_ACA_OUT_OFF, /* Disable output */ + AS_ACA_OUT_MAX_ENTRY +} asAcaPulcoOutDeviceId; + +typedef enum +{ + AS_ACA_PWMOUT_UNKNOWN, + AS_ACA_PWMOUT_OFF, /* Disable */ + AS_ACA_PWMOUT_LN, /* LN */ + AS_ACA_PWMOUT_LP, /* LP */ + AS_ACA_PWMOUT_RN, /* RN */ + AS_ACA_PWMOUT_RP, /* RP */ + AS_ACA_PWMOUT_MAX_ENTRY +} asAcaPulcoPwmOutId; + +typedef enum +{ + AS_ACA_SP_LOOP_MODE_UNKNOWN, + AS_ACA_SP_LOOP_MODE_ENABLE, + AS_ACA_SP_LOOP_MODE_DISABLE, + AS_ACA_SP_LOOP_MODE_MAX_ENTRY +} asAcaSpLoopModeId; + +typedef enum +{ + AS_ACA_SP_DELAY_SEL_UNKNOWN, + AS_ACA_SP_DELAY_SEL_NON, + AS_ACA_SP_DELAY_SEL_SHORT, + AS_ACA_SP_DELAY_SEL_MIDDLE, + AS_ACA_SP_DELAY_SEL_LONG, + AS_ACA_SP_DELAY_SEL_MAX_ENTRY +} asAcaSpDelaySelId; + +typedef enum +{ + AS_ACA_SP_DLY_FREE_UNKNOWN, + AS_ACA_SP_DLY_FREE_OFF, + AS_ACA_SP_DLY_FREE_ON, + AS_ACA_SP_DLY_FREE_MAX_ENTRY +} asAcaSpDlyFreeId; + +typedef enum +{ + AS_ACA_SP_SPLITON_SEL_UNKNOWN, + AS_ACA_SP_SPLITON_SEL_SHORTEST, + AS_ACA_SP_SPLITON_SEL_SHORT, + AS_ACA_SP_SPLITON_SEL_LONG, + AS_ACA_SP_SPLITON_SEL_LONGEST, + AS_ACA_SP_SPLITON_SEL_MAX_ENTRY +} asAcaSpSplitonSelId; + +typedef enum +{ + AS_ACA_SP_DRV_SEL_UNKNOWN, + AS_ACA_SP_DRV_SEL_4DRIVER, + AS_ACA_SP_DRV_SEL_2DRIVER, + AS_ACA_SP_DRV_SEL_1DRIVER, + AS_ACA_SP_DRV_SEL_LINEOUT, + AS_ACA_SP_DRV_SEL_MAX_ENTRY +} asAcaSpDrvSelId; + +typedef enum +{ + AS_ACA_SER_MODE_UNKNOWN, + AS_ACA_SER_MODE_8CH, /* 8ch */ + AS_ACA_SER_MODE_4CH, /* 4ch */ + AS_ACA_SER_MODE_MAX_ENTRY +} asAcaPulcoSerModeId; + +typedef enum +{ + AS_ACA_SER_FS_UNKNOWN, + AS_ACA_SER_FS_128, /* 128fs */ + AS_ACA_SER_FS_64, /* 64fs */ + AS_ACA_SER_FS_MAX_ENTRY +} asAcaPulcoSerFsId; + +typedef enum +{ + AS_ACA_SER_SEL_FIX0 = 0, + AS_ACA_SER_SEL_AMIC1 = 1, + AS_ACA_SER_SEL_AMIC2 = 2, + AS_ACA_SER_SEL_AMIC3 = 3, + AS_ACA_SER_SEL_AMIC4 = 4, + AS_ACA_SER_SEL_DMIC1 = 5, + AS_ACA_SER_SEL_DMIC2 = 6, + AS_ACA_SER_SEL_DMIC3 = 7, + AS_ACA_SER_SEL_DMIC4 = 8, + AS_ACA_SER_SEL_DMIC5 = 9, + AS_ACA_SER_SEL_DMIC6 = 10, + AS_ACA_SER_SEL_DMIC7 = 11, + AS_ACA_SER_SEL_DMIC8 = 12, + AS_ACA_SER_SEL_UNKNOWN = 15, + AS_ACA_SER_SEL_MAX_ENTRY = 16 +} asAcaPulcoSerSelChId; + +typedef enum +{ + AS_SDES_DES_SEL_UNKNOWN, + AS_SDES_DES_SEL_CH1, + AS_SDES_DES_SEL_CH2, + AS_SDES_DES_SEL_CH3, + AS_SDES_DES_SEL_CH4, + AS_SDES_DES_SEL_CH5, + AS_SDES_DES_SEL_CH6, + AS_SDES_DES_SEL_CH7, + AS_SDES_DES_SEL_CH8, + AS_SDES_DES_SEL_MAX_ENTRY +} asSdesDesSelOutId; + +typedef enum +{ + AS_ACA_CHECK_ID, + AS_ACA_POWER_ON_COMMON, + AS_ACA_POWER_ON_INPUT, + AS_ACA_POWER_ON_OUTPUT, + AS_ACA_SET_SERDES, + AS_ACA_SET_SMASTER, + AS_ACA_POWER_OFF_COMMON, + AS_ACA_POWER_OFF_INPUT, + AS_ACA_POWER_OFF_OUTPUT, + AS_ACA_POWER_ON_MICBIAS, + AS_ACA_POWER_OFF_MICBIAS, + AS_ACA_INIT_AMIC, + AS_ACA_SET_AMIC_BOOT_DONE, + AS_ACA_SET_OUTPUT_DEVICE, + AS_ACA_GET_REGISTER, + AS_ACA_SET_REGISTER, + AS_ACA_CONTROL_TYPE_NUM +} AsAcaControlType; + +typedef struct +{ + asAcaPulcoOscModeId oscMode; + asAcaPulcoMicDeviceId micDev; + asAcaPulcoIoDsId gpoDs; + asAcaPulcoIoDsId adDataDs; + asAcaPulcoIoDsId dmicClkDs; + asAcaPulcoIoDsId mclkDs; +} asAcaPulcoParam; + +typedef struct +{ + asAcaPulcoMicDeviceId micDev; + asAcaPulcoMicBiasSelId micBiasSel; + uint32_t micGain[4]; + uint32_t pgaGain[4]; + int32_t vgain[4]; +} asAcaPulcoInParam; + +typedef struct +{ + asSmstrModeId mode; + asSmstrMckId mckFs; + asSmstrPwmModeId pwmMode; + asSmstrChSelId chSel; + uint8_t out2Dly; +} asAcaPulcoSmstrParam; + +typedef struct +{ + asAcaPulcoOutDeviceId outDev; + asAcaPulcoPwmOutId pwmOut[2]; + asAcaSpDelaySelId spDelay; + asAcaSpLoopModeId loopMode; + asSmstrModeId mode; + asAcaSpDlyFreeId spDlyFree; + asAcaSpSplitonSelId spSpliton; + asAcaSpDrvSelId spDrv; +} asAcaPulcoOutParam; + +typedef struct +{ + uint32_t bank; + uint32_t addr; + uint32_t value; +} asAcaPulcoRegParam; + +typedef struct +{ + asAcaPulcoSerModeId serMode; + asAcaPulcoSerFsId serFs; + union + { + asAcaPulcoSerSelChId in[CXD56_AUDIO_MIC_CH_MAX]; + asSdesDesSelOutId out[CXD56_AUDIO_MIC_CH_MAX]; + } selCh; +} asSerDesParam; + +/* Select output device ID */ + +typedef enum +{ + /* output device none */ + + AS_OUT_DEV_OFF, + + /* output device speaker */ + + AS_OUT_DEV_SP, + + /* output device i2s */ + + AS_OUT_DEV_I2S, + AS_OUT_DEV_NUM +} asOutDeviceId; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +extern uint32_t AS_AcaControl(uint8_t type, uint32_t param); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void get_osc_mode(uint8_t cfg_mclk, asAcaPulcoOscModeId *osc) +{ + cxd56_audio_clkmode_t clk_mode = cxd56_audio_config_get_clkmode(); + + if (cfg_mclk == CXD56_AUDIO_CFG_XTAL_24_576MHZ) + { + if (clk_mode == CXD56_AUDIO_CLKMODE_HIRES) + { + *osc = AS_ACA_OSC_24_576MHZ_HIRES; + } + else + { + *osc = AS_ACA_OSC_24_576MHZ; + } + } + else + { + if (clk_mode == CXD56_AUDIO_CLKMODE_HIRES) + { + *osc = AS_ACA_OSC_49_152MHZ_HIRES; + } + else + { + *osc = AS_ACA_OSC_49_152MHZ; + } + } +} + +static void get_mic_dev(uint32_t cfg_mic, FAR asAcaPulcoMicDeviceId *dev) +{ + bool is_amic = false; + bool is_dmic = false; + uint8_t i; + + for (i = 0; i < CXD56_AUDIO_MIC_CH_MAX; i++) + { + uint8_t mic_sel; + mic_sel = (cfg_mic >> (i * MIC_CH_BITNUM)) & MIC_CH_BITMAP; + if ((mic_sel >= 1) && (mic_sel <= 4)) + { + is_amic = true; + } + else if ((mic_sel >= 5) && (mic_sel <= 12)) + { + is_dmic = true; + } + } + + if (is_amic && is_dmic) + { + *dev = AS_ACA_MIC_BOTH; + } + else if(is_amic) + { + *dev = AS_ACA_MIC_AMIC; + } + else + { + *dev = AS_ACA_MIC_DMIC; + } +} + +static void get_drv_str(uint8_t cfg_ds, FAR asAcaPulcoIoDsId *ds) +{ + switch (cfg_ds) + { + case CXD56_AUDIO_CFG_DS_WEAKEST: + *ds = AS_ACA_IO_DS_WEAKEST; + break; + + case CXD56_AUDIO_CFG_DS_WEAKER: + *ds = AS_ACA_IO_DS_WEAKER; + break; + + case CXD56_AUDIO_CFG_DS_STRONGER: + *ds = AS_ACA_IO_DS_STRONGER; + break; + + case CXD56_AUDIO_CFG_DS_STRONGEST: + *ds = AS_ACA_IO_DS_STRONGEST; + break; + + default: + *ds = AS_ACA_IO_DS_WEAKEST; + break; + } +} + +static void get_mic_bias(uint8_t cfg_bsel, FAR asAcaPulcoMicBiasSelId *bsel) +{ + switch (cfg_bsel) + { + case CXD56_AUDIO_CFG_MIC_BIAS_20V: + *bsel = AS_ACA_MICBIAS_SEL_2_0V; + break; + + case CXD56_AUDIO_CFG_MIC_BIAS_28V: + *bsel = AS_ACA_MICBIAS_SEL_2_8V; + break; + + default: + *bsel = AS_ACA_MICBIAS_SEL_2_0V; + break; + } +} + +static void get_sp_split_on(uint8_t cf_sp_spliton, FAR asAcaSpSplitonSelId *spSpliton) +{ + switch (cf_sp_spliton) + { + case CXD56_AUDIO_CFG_SP_SPLITON_LONGEST: + *spSpliton = AS_ACA_SP_SPLITON_SEL_LONGEST; + break; + + case CXD56_AUDIO_CFG_SP_SPLITON_LONG: + *spSpliton = AS_ACA_SP_SPLITON_SEL_LONG; + break; + + case CXD56_AUDIO_CFG_SP_SPLITON_SHORT: + *spSpliton = AS_ACA_SP_SPLITON_SEL_SHORT; + break; + + default: + *spSpliton = AS_ACA_SP_SPLITON_SEL_SHORTEST; + break; + } +} + +static void get_sp_driver(uint8_t cfg_sp_drv, FAR asAcaSpDrvSelId *spDrv) +{ + switch (cfg_sp_drv) + { + case CXD56_AUDIO_SP_DRV_LINEOUT: + *spDrv = AS_ACA_SP_DRV_SEL_LINEOUT; + break; + + case CXD56_AUDIO_SP_DRV_1DRIVER: + *spDrv = AS_ACA_SP_DRV_SEL_1DRIVER; + break; + + case CXD56_AUDIO_SP_DRV_2DRIVER: + *spDrv = AS_ACA_SP_DRV_SEL_2DRIVER; + break; + + default: + *spDrv = AS_ACA_SP_DRV_SEL_4DRIVER; + break; + } +} + +void get_pwon_param(asAcaPulcoParam *param) +{ + uint32_t mic_map = cxd56_audio_config_get_micmap(); + + get_osc_mode((uint8_t)CXD56_AUDIO_CFG_MCLK, ¶m->oscMode); + get_mic_dev(mic_map, ¶m->micDev); + get_drv_str((uint8_t)CXD56_AUDIO_CFG_GPO_A_DS, ¶m->gpoDs); + get_drv_str((uint8_t)CXD56_AUDIO_CFG_DA_DS, ¶m->adDataDs); + get_drv_str((uint8_t)CXD56_AUDIO_CFG_DMIC_CLK_DS, ¶m->dmicClkDs); + get_drv_str((uint8_t)CXD56_AUDIO_CFG_MCLKOUT_DS, ¶m->mclkDs); +} + +void get_serial_param(asSerDesParam *param) +{ + uint8_t mic_mode = cxd56_audio_config_get_micmode(); + uint32_t mic_map = cxd56_audio_config_get_micmap(); + uint8_t mic_sel = 0; + uint8_t i; + + if (CXD56_AUDIO_CFG_MIC_MODE_128FS == mic_mode) + { + param->serMode = AS_ACA_SER_MODE_4CH; + param->serFs = AS_ACA_SER_FS_128; + } + else + { + param->serMode = AS_ACA_SER_MODE_8CH; + param->serFs = AS_ACA_SER_FS_64; + } + + for (i = 0; i < CXD56_AUDIO_MIC_CH_MAX; i++) + { + mic_sel = (mic_map >> (i * MIC_CH_BITNUM)) & MIC_CH_BITMAP; + param->selCh.in[i] = (asAcaPulcoSerSelChId)mic_sel; + } +} + +void get_input_param(asAcaPulcoInParam *param, + FAR cxd56_audio_mic_gain_t *gain) +{ + uint8_t mic_sel; + uint8_t mic_id; + uint32_t mic_map = cxd56_audio_config_get_micmap(); + uint32_t pga_gain; + uint8_t i; + + memset((void *)param, 0, sizeof(asAcaPulcoInParam)); + + get_mic_dev(mic_map, ¶m->micDev); + + get_mic_bias((uint8_t)CXD56_AUDIO_CFG_MIC_BIAS, ¶m->micBiasSel); + + for (i = 0; i < CXD56_AUDIO_MIC_CH_MAX; i++) + { + mic_sel = (mic_map >> (i * MIC_CH_BITNUM)) & MIC_CH_BITMAP; + if ((mic_sel >= 1) && (mic_sel <= 4)) + { + mic_id = mic_sel - 1; + param->micGain[mic_id] = (gain->gain[i] >= MIC_GAIN_MAX) ? + MIC_GAIN_MAX : (gain->gain[i] / 30) * 30; + + pga_gain = gain->gain[i] - param->micGain[mic_id]; + param->pgaGain[mic_id] = (pga_gain >= PGA_GAIN_MAX) ? + PGA_GAIN_MAX : pga_gain; + } + } + +} + +void get_smaster_param(asAcaPulcoSmstrParam *param) +{ + cxd56_audio_clkmode_t clk_mode = cxd56_audio_config_get_clkmode(); + + if (clk_mode == CXD56_AUDIO_CLKMODE_HIRES) + { + param->mode = AS_SMSTR_MODE_FS_32; + param->mckFs = AS_SMSTR_MCK_FS_1024; + } + else + { + param->mode = AS_SMSTR_MODE_FS_16; + param->mckFs = AS_SMSTR_MCK_FS_512; + } + + param->chSel = AS_SMSTR_CHSEL_NORMAL; + param->out2Dly = 0x00; + + param->pwmMode = AS_SMSTR_PWMMD_BOTH; +} + +void get_pwon_out_param(asAcaPulcoOutParam *param) +{ + cxd56_audio_clkmode_t clk_mode = cxd56_audio_config_get_clkmode(); + + if (clk_mode == CXD56_AUDIO_CLKMODE_HIRES) + { + param->mode = AS_SMSTR_MODE_FS_32; + } + else + { + param->mode = AS_SMSTR_MODE_FS_16; + } + + param->outDev = AS_ACA_OUT_OFF; + param->pwmOut[0] = AS_ACA_PWMOUT_UNKNOWN; + param->pwmOut[1] = AS_ACA_PWMOUT_UNKNOWN; + param->spDelay = AS_ACA_SP_DELAY_SEL_UNKNOWN; + param->loopMode = AS_ACA_SP_LOOP_MODE_UNKNOWN; + param->spDlyFree = AS_ACA_SP_DLY_FREE_UNKNOWN; + + get_sp_split_on((uint8_t)CXD56_AUDIO_CFG_SP_SPLIT_ON, ¶m->spSpliton); + get_sp_driver((uint8_t)cxd56_audio_config_get_spdriver(), ¶m->spDrv); +} + +/*************************************************************************** + * Public Functions + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_aca_poweron(void) +{ + if (AS_AcaControl(AS_ACA_CHECK_ID, (uint32_t)NULL) != 0) + { + return CXD56_AUDIO_ECODE_ANA_CHKID; + } + + asAcaPulcoParam pwon_param; + get_pwon_param(&pwon_param); + + if (AS_AcaControl(AS_ACA_POWER_ON_COMMON, (uint32_t)&pwon_param) != 0) + { + return CXD56_AUDIO_ECODE_ANA_PWON; + } + + asSerDesParam serial_param; + get_serial_param(&serial_param); + + if (AS_AcaControl(AS_ACA_SET_SERDES, (uint32_t)&serial_param) != 0) + { + return CXD56_AUDIO_ECODE_ANA_SERIAL; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_poweroff(void) +{ + if (AS_AcaControl(AS_ACA_POWER_OFF_COMMON, (uint32_t)NULL) != 0) + { + return CXD56_AUDIO_ECODE_ANA_PWOFF; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_poweron_micbias(void) +{ + if (AS_AcaControl(AS_ACA_POWER_ON_MICBIAS, (uint32_t)NULL) != 0) + { + return CXD56_AUDIO_ECODE_ANA_PWON_MBIAS; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_poweron_input(FAR cxd56_audio_mic_gain_t *gain) +{ + asAcaPulcoInParam pwon_input_param; + + get_input_param(&pwon_input_param, gain); + + if (AS_AcaControl(AS_ACA_POWER_ON_INPUT, (uint32_t)&pwon_input_param) != 0) + { + return CXD56_AUDIO_ECODE_ANA_PWON_INPUT; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_set_smaster(void) +{ + asAcaPulcoSmstrParam smaster_param; + + get_smaster_param(&smaster_param); + + if (AS_AcaControl(AS_ACA_SET_SMASTER, (uint32_t)&smaster_param) != 0) + { + return CXD56_AUDIO_ECODE_ANA_SET_SMASTER; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_poweron_output(void) +{ + asAcaPulcoOutParam pwon_output_param; + + get_pwon_out_param(&pwon_output_param); + + if (AS_AcaControl(AS_ACA_POWER_ON_OUTPUT, (uint32_t)&pwon_output_param) != 0) + { + return CXD56_AUDIO_ECODE_ANA_PWON_OUTPUT; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_poweroff_input(void) +{ + if (AS_AcaControl(AS_ACA_POWER_OFF_INPUT, (uint32_t)NULL) != 0) + { + return CXD56_AUDIO_ECODE_ANA_PWOFF_INPUT; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_poweroff_output(void) +{ + if (AS_AcaControl(AS_ACA_POWER_OFF_OUTPUT, (uint32_t)NULL) != 0) + { + return CXD56_AUDIO_ECODE_ANA_PWOFF_OUTPUT; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_enable_output(void) +{ + if (AS_AcaControl(AS_ACA_SET_OUTPUT_DEVICE, (uint32_t)AS_OUT_DEV_SP) != 0) + { + return CXD56_AUDIO_ECODE_ANA_ENABLE_OUTPUT; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_disable_output(void) +{ + if (AS_AcaControl(AS_ACA_SET_OUTPUT_DEVICE, (uint32_t)AS_OUT_DEV_OFF) != 0) + { + return CXD56_AUDIO_ECODE_ANA_DISABLE_OUTPUT; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_set_micgain(FAR cxd56_audio_mic_gain_t *gain) +{ + asAcaPulcoInParam mic_gain_param; + + get_input_param(&mic_gain_param, gain); + + if (AS_AcaControl(AS_ACA_INIT_AMIC, (uint32_t)&mic_gain_param) != 0) + { + return CXD56_AUDIO_ECODE_ANA_SET_MICGAIN; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_notify_micbootdone(void) +{ + if (AS_AcaControl(AS_ACA_SET_AMIC_BOOT_DONE, (uint32_t)NULL) != 0) + { + return CXD56_AUDIO_ECODE_ANA_NOTIFY_MICBOOT; + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_read_reg(asAcaPulcoRegParam *param) +{ + AS_AcaControl(AS_ACA_GET_REGISTER, (uint32_t)param); + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_aca_write_reg(asAcaPulcoRegParam *param) +{ + AS_AcaControl(AS_ACA_SET_REGISTER, (uint32_t)param); + return CXD56_AUDIO_ECODE_OK; +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_aca.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_aca.h new file mode 100644 index 00000000000..730080503b3 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_aca.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_aca.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_ACA_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_ACA_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DNC1_IRAM_BASE 0x3000 +#define DNC1_CRAM_BASE 0x3800 +#define DNC2_IRAM_BASE 0x3c00 +#define DNC2_CRAM_BASE 0x4400 + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_aca_poweron(void); +CXD56_AUDIO_ECODE cxd56_audio_aca_poweroff(void); +CXD56_AUDIO_ECODE cxd56_audio_aca_poweron_micbias(void); +CXD56_AUDIO_ECODE cxd56_audio_aca_poweron_input(FAR cxd56_audio_mic_gain_t *gain); +CXD56_AUDIO_ECODE cxd56_audio_aca_set_smaster(void); +CXD56_AUDIO_ECODE cxd56_audio_aca_poweron_output(void); +CXD56_AUDIO_ECODE cxd56_audio_aca_poweroff_input(void); +CXD56_AUDIO_ECODE cxd56_audio_aca_poweroff_output(void); +CXD56_AUDIO_ECODE cxd56_audio_aca_enable_output(void); +CXD56_AUDIO_ECODE cxd56_audio_aca_disable_output(void); +CXD56_AUDIO_ECODE cxd56_audio_aca_set_micgain(FAR cxd56_audio_mic_gain_t *gain); +CXD56_AUDIO_ECODE cxd56_audio_aca_notify_micbootdone(void); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_ACA_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_analog.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_analog.c new file mode 100644 index 00000000000..488b8fcafc3 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_analog.c @@ -0,0 +1,309 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_analog.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_analog.h" +#include "cxd56_audio_aca.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define AUD_MCLK_EXT (0u<<16) /* External XTAL */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + + inline void cxd56_audio_clock_enable(uint32_t clk, uint32_t div); + inline void cxd56_audio_clock_disable(void); + inline bool cxd56_audio_clock_is_enabled(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +uint64_t g_mic_boot_start_time = 0x0ull; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void clear_mic_boot_time(void) +{ + g_mic_boot_start_time = 0x0ull; +} + +static void set_mic_boot_time(void) +{ + struct timespec start; + if (clock_gettime(CLOCK_REALTIME, &start) < 0) + { + g_mic_boot_start_time = 0x0ull; + return; + } + + g_mic_boot_start_time = (uint64_t)start.tv_sec * 1000 + + (uint64_t)start.tv_nsec / 1000000; +} + +static void wait_mic_boot_finish(void) +{ + if (g_mic_boot_start_time != 0x0ull) + { + struct timespec end; + if (clock_gettime(CLOCK_REALTIME, &end) < 0) + { + return; + } + uint64_t time = (uint64_t)end.tv_sec * 1000 + + (uint64_t)end.tv_nsec / 1000000 - + g_mic_boot_start_time; + + if (time < CXD56_AUDIO_MIC_BOOT_WAIT) + { + usleep((CXD56_AUDIO_MIC_BOOT_WAIT - time) * 1000); + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_analog_poweron(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_CXD5247 + if (board_aca_power_control(CXD5247_AVDD | CXD5247_DVDD, true) != 0) + { + return CXD56_AUDIO_ECODE_ANA_PWON; + } + + if (!board_aca_power_monitor(CXD5247_AVDD | CXD5247_DVDD)) + { + return CXD56_AUDIO_ECODE_ANA_PWON; + } + + ret = cxd56_audio_aca_poweron(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + cxd56_audio_clock_enable(AUD_MCLK_EXT, 0); + if (!cxd56_audio_clock_is_enabled()) + { + return CXD56_AUDIO_ECODE_ANA_CLK_EN; + } +#endif + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_analog_poweroff(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_CXD5247 + cxd56_audio_clock_disable(); + + ret = cxd56_audio_aca_poweroff(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + board_aca_power_control(CXD5247_AVDD | CXD5247_DVDD, false); +#endif + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_analog_poweron_input(FAR cxd56_audio_mic_gain_t *gain) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_CXD5247 + uint8_t mic_dev = cxd56_audio_config_get_micdev(); + + if ((mic_dev == CXD56_AUDIO_CFG_MIC_DEV_ANALOG) || + (mic_dev == CXD56_AUDIO_CFG_MIC_DEV_ANADIG)) + { + ret = cxd56_audio_aca_poweron_micbias(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + set_mic_boot_time(); + } + + ret = cxd56_audio_aca_poweron_input(gain); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } +#endif + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_analog_poweron_output(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_CXD5247 + + ret = cxd56_audio_aca_set_smaster(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + ret = cxd56_audio_aca_poweron_output(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } +#endif + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_analog_poweroff_input(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_CXD5247 + ret = cxd56_audio_aca_poweroff_input(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + clear_mic_boot_time(); +#endif + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_analog_poweroff_output(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_CXD5247 + ret = cxd56_audio_aca_poweroff_output(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } +#endif + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_analog_enable_output(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_CXD5247 + ret = cxd56_audio_aca_enable_output(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } +#endif + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_analog_disable_output(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_CXD5247 + ret = cxd56_audio_aca_disable_output(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } +#endif + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_analog_set_micgain(FAR cxd56_audio_mic_gain_t *gain) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_CXD5247 + + ret = cxd56_audio_aca_set_micgain(gain); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } +#endif + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_analog_wait_input_standby() +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + +#ifdef CONFIG_CXD56_AUDIO_ANALOG_CXD5247 + wait_mic_boot_finish(); + ret = cxd56_audio_aca_notify_micbootdone(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } +#endif + + return ret; +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_analog.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_analog.h new file mode 100644 index 00000000000..88b96464978 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_analog.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_analog.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_ANALOG_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_ANALOG_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_analog_poweron(void); +CXD56_AUDIO_ECODE cxd56_audio_analog_poweroff(void); +CXD56_AUDIO_ECODE cxd56_audio_analog_poweron_input(FAR cxd56_audio_mic_gain_t *gain); +CXD56_AUDIO_ECODE cxd56_audio_analog_poweron_output(void); +CXD56_AUDIO_ECODE cxd56_audio_analog_poweroff_input(void); +CXD56_AUDIO_ECODE cxd56_audio_analog_poweroff_output(void); +CXD56_AUDIO_ECODE cxd56_audio_analog_enable_output(void); +CXD56_AUDIO_ECODE cxd56_audio_analog_disable_output(void); +CXD56_AUDIO_ECODE cxd56_audio_analog_set_micgain(FAR cxd56_audio_mic_gain_t *gain); +CXD56_AUDIO_ECODE cxd56_audio_analog_wait_input_standby(void); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_ANALOG_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_bca_reg.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_bca_reg.c new file mode 100644 index 00000000000..e56826649c9 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_bca_reg.c @@ -0,0 +1,1197 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_bca_reg.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_bca_reg.h" + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BCA_REG_BASE (0x0c000000 + 0x02300000) + +#define TRANS_CH_NUM_MAX 8 +#define TRANS_CH_NUM_24BIT 8 +#define TRANS_CH_NUM_16BIT 4 +#define TRANS_CH_NO_SELECT 8 + +enum dma_i2s_in_sel_e +{ + I2S_IN_SEL_SRC1L = 0, + I2S_IN_SEL_SRC1R = 1, + I2S_IN_SEL_UNUSE +}; + +enum dma_i2s_out_sel_e +{ + I2S_OUT_SEL_SD1L = 0, + I2S_OUT_SEL_SD1R = 1, + I2S_OUT_SEL_UNUSE +}; + +#define BCA_REG_MAX_BIT 32 + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/*************************************************************************** + * Private Data + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +struct audio_bca_reg_s +{ + uint32_t addr; + uint32_t pos; + uint32_t len; + uint32_t init; +}; + +const struct audio_bca_reg_s g_bca_reg[BCA_REG_MAX_ENTRY] = +{ + {0x1000, 2, 30, 0x00000000}, /* Mic_In_start_adr (0x00000000) */ + {0x1004, 0, 32, 0x00000000}, /* Mic_In_sample_no (0x00000000) */ + {0x1008, 0, 2, 0x00000000}, /* Mic_In_rtd_trg (0x00) */ + {0x1008, 2, 1, 0x00000000}, /* Mic_In_nointr (0x00) */ + {0x100c, 0, 1, 0x00000000}, /* Mic_In_bitwt (0x00) */ + {0x1010, 0, 4, 0x00000000}, /* Mic_In_ch8_sel (0x00) */ + {0x1010, 4, 4, 0x00000000}, /* Mic_In_ch7_sel (0x00) */ + {0x1010, 8, 4, 0x00000000}, /* Mic_In_ch6_sel (0x00) */ + {0x1010, 12, 4, 0x00000000}, /* Mic_In_ch5_sel (0x00) */ + {0x1010, 16, 4, 0x00000000}, /* Mic_In_ch4_sel (0x00) */ + {0x1010, 20, 4, 0x00000000}, /* Mic_In_ch3_sel (0x00) */ + {0x1010, 24, 4, 0x00000000}, /* Mic_In_ch2_sel (0x00) */ + {0x1010, 28, 4, 0x00000000}, /* Mic_In_ch1_sel (0x00) */ + {0x1014, 0, 1, 0x00000000}, /* Mic_In_start (0x00) */ + {0x1014, 8, 8, 0x00000000}, /* Mic_In_error_setting (0x00) */ + {0x1014, 16, 4, 0x00000000}, /* Mic_In_monbuf (0x00) */ + {0x1080, 2, 30, 0x00000000}, /* I2s1_In_start_adr (0x00000000) */ + {0x1084, 0, 32, 0x00000000}, /* I2s1_In_sample_no (0x00000000) */ + {0x1088, 0, 2, 0x00000000}, /* I2s1_In_rtd_trg (0x00) */ + {0x1088, 2, 1, 0x00000000}, /* I2s1_In_nointr (0x00) */ + {0x108c, 0, 1, 0x00000000}, /* I2s1_In_bitwt (0x00) */ + {0x1090, 0, 2, 0x00000000}, /* I2s1_In_ch2_sel (0x00) */ + {0x1090, 4, 2, 0x00000000}, /* I2s1_In_ch1_sel (0x00) */ + {0x1094, 0, 1, 0x00000000}, /* I2s1_In_Mon_start (0x00) */ + {0x1094, 8, 8, 0x00000000}, /* I2s1_In_Mon_error_setting (0x00) */ + {0x1094, 16, 4, 0x00000000}, /* I2s1_In_Mon_monbuf (0x00) */ + {0x10a0, 2, 30, 0x00000000}, /* I2s2_In_start_adr (0x00000000) */ + {0x10a4, 0, 32, 0x00000000}, /* I2s2_In_sample_no (0x00000000) */ + {0x10a8, 0, 2, 0x00000000}, /* I2s2_In_rtd_trg (0x00) */ + {0x10a8, 2, 1, 0x00000000}, /* I2s2_In_nointr (0x00) */ + {0x10ac, 0, 1, 0x00000000}, /* I2s2_In_bitwt (0x00) */ + {0x10b0, 0, 2, 0x00000000}, /* I2s2_In_ch2_sel (0x00) */ + {0x10b0, 4, 2, 0x00000000}, /* I2s2_In_ch1_sel (0x00) */ + {0x10b4, 0, 1, 0x00000000}, /* I2s2_In_Mon_start (0x00) */ + {0x10b4, 8, 8, 0x00000000}, /* I2s2_In_Mon_error_setting (0x00) */ + {0x10b4, 16, 4, 0x00000000}, /* I2s2_In_Mon_monbuf (0x00) */ + {0x10c0, 2, 30, 0x00000000}, /* I2s1_Out_start_adr (0x00000000) */ + {0x10c4, 0, 32, 0x00000000}, /* I2s1_Out_sample_no (0x00000000) */ + {0x10c8, 0, 2, 0x00000000}, /* I2s1_Out_rtd_trg (0x00) */ + {0x10c8, 2, 1, 0x00000000}, /* I2s1_Out_nointr (0x00) */ + {0x10cc, 0, 1, 0x00000000}, /* I2s1_Out_bitwt (0x00) */ + {0x10d0, 0, 2, 0x00000000}, /* I2s1_Out_sd1_r_sel (0x00) */ + {0x10d0, 4, 2, 0x00000000}, /* I2s1_Out_sd1_l_sel (0x00) */ + {0x10d4, 0, 1, 0x00000000}, /* I2s1_Out_Mon_start (0x00) */ + {0x10d4, 8, 8, 0x00000000}, /* I2s1_Out_Mon_error_setting (0x00) */ + {0x10d4, 16, 4, 0x00000000}, /* I2s1_Out_Mon_monbuf (0x00) */ + {0x10e0, 2, 30, 0x00000000}, /* I2s2_Out_start_adr (0x00000000) */ + {0x10e4, 0, 32, 0x00000000}, /* I2s2_Out_sample_no (0x00000000) */ + {0x10e8, 0, 2, 0x00000000}, /* I2s2_Out_rtd_trg (0x00) */ + {0x10e8, 2, 1, 0x00000000}, /* I2s2_Out_nointr (0x00) */ + {0x10ec, 0, 1, 0x00000000}, /* I2s2_Out_bitwt (0x00) */ + {0x10f0, 0, 2, 0x00000000}, /* I2s2_Out_sd1_r_sel (0x00) */ + {0x10f0, 4, 2, 0x00000000}, /* I2s2_Out_sd1_l_sel (0x00) */ + {0x10f4, 0, 1, 0x00000000}, /* I2s2_Out_Mon_start (0x00) */ + {0x10f4, 8, 8, 0x00000000}, /* I2s2_Out_Mon_error_setting (0x00) */ + {0x10f4, 16, 4, 0x00000000}, /* I2s2_Out_Mon_monbuf (0x00) */ + {0x1110, 0, 1, 0x00000000}, /* I2s_ensel (0x00) */ + {0x1120, 0, 32, 0x00000000}, /* Mici_prdat_u (0x00000000) */ + {0x1130, 0, 32, 0x00000000}, /* I2s1_In_prdat_u (0x00000000) */ + {0x1134, 0, 32, 0x00000000}, /* I2s2_In_prdat_u (0x00000000) */ + {0x1138, 0, 32, 0x00000000}, /* I2s1_Out_prdat_d (0x00000000) */ + {0x113c, 0, 32, 0x00000000}, /* I2s2_Out_prdat_d (0x00000000) */ + {0x1140, 0, 1, 0x00000000}, /* Mic_Int_Ctrl_done_mic (0x00) */ + {0x1140, 1, 1, 0x00000000}, /* Mic_Int_Ctrl_err_mic (0x00) */ + {0x1140, 2, 1, 0x00000000}, /* Mic_Int_Ctrl_smp_mic (0x00) */ + {0x1140, 3, 1, 0x00000000}, /* Mic_Int_Ctrl_cmb_mic (0x00) */ + {0x1144, 0, 1, 0x00000000}, /* I2s1_Int_Ctrl_done_i2so (0x00) */ + {0x1144, 1, 1, 0x00000000}, /* I2s1_Int_Ctrl_err_i2so (0x00) */ + {0x1144, 2, 1, 0x00000000}, /* I2s1_Int_Ctrl_done_i2si (0x00) */ + {0x1144, 3, 1, 0x00000000}, /* I2s1_Int_Ctrl_err_i2si (0x00) */ + {0x1144, 4, 1, 0x00000000}, /* I2s1_Int_Ctrl_smp_i2s (0x00) */ + {0x1144, 5, 1, 0x00000000}, /* I2s1_Int_Ctrl_cmb_i2s (0x00) */ + {0x1148, 0, 1, 0x00000000}, /* I2s2_Int_Ctrl_done_i2so (0x00) */ + {0x1148, 1, 1, 0x00000000}, /* I2s2_Int_Ctrl_err_i2so (0x00) */ + {0x1148, 2, 1, 0x00000000}, /* I2s2_Int_Ctrl_done_i2si (0x00) */ + {0x1148, 3, 1, 0x00000000}, /* I2s2_Int_Ctrl_err_i2si (0x00) */ + {0x1148, 4, 1, 0x00000000}, /* I2s2_Int_Ctrl_smp_i2s (0x00) */ + {0x1148, 5, 1, 0x00000000}, /* I2s2_Int_Ctrl_cmb_i2s (0x00) */ + {0x114c, 0, 1, 0x00000001}, /* Mic_Int_Mask_done_mic (0x00) */ + {0x114c, 1, 1, 0x00000001}, /* Mic_Int_Mask_err_mic (0x00) */ + {0x114c, 2, 1, 0x00000001}, /* Mic_Int_Mask_smp_mic (0x00) */ + {0x114c, 3, 1, 0x00000001}, /* Mic_Int_Mask_cmb_mic (0x00) */ + {0x114c, 30, 1, 0x00000000}, /* Mic_Int_Mask_nostpmsk (0x00) */ + {0x114c, 31, 1, 0x00000000}, /* Mic_Int_Mask_srst_mic (0x00) */ + {0x1150, 0, 1, 0x00000001}, /* I2s1_Int_Mask_done_i2so (0x00) */ + {0x1150, 1, 1, 0x00000001}, /* I2s1_Int_Mask_err_i2so (0x00) */ + {0x1150, 2, 1, 0x00000001}, /* I2s1_Int_Mask_done_i2si (0x00) */ + {0x1150, 3, 1, 0x00000001}, /* I2s1_Int_Mask_err_i2si (0x00) */ + {0x1150, 4, 1, 0x00000001}, /* I2s1_Int_Mask_smp_i2s (0x00) */ + {0x1150, 5, 1, 0x00000001}, /* I2s1_Int_Mask_cmb_i2s (0x00) */ + {0x1150, 30, 1, 0x00000000}, /* I2s1_Int_Mask_nostpmsk_i2s (0x00) */ + {0x1150, 31, 1, 0x00000000}, /* I2s1_Int_Mask_srst_i2s (0x00) */ + {0x1154, 0, 1, 0x00000001}, /* I2s2_Int_Mask_done_i2so (0x00) */ + {0x1154, 1, 1, 0x00000001}, /* I2s2_Int_Mask_err_i2so (0x00) */ + {0x1154, 2, 1, 0x00000001}, /* I2s2_Int_Mask_done_i2si (0x00) */ + {0x1154, 3, 1, 0x00000001}, /* I2s2_Int_Mask_err_i2si (0x00) */ + {0x1154, 4, 1, 0x00000001}, /* I2s2_Int_Mask_smp_i2s (0x00) */ + {0x1154, 5, 1, 0x00000001}, /* I2s2_Int_Mask_cmb_i2s (0x00) */ + {0x1154, 30, 1, 0x00000000}, /* I2s2_Int_Mask_nostpmsk_i2s (0x00) */ + {0x1154, 31, 1, 0x00000000}, /* I2s2_Int_Mask_srst_i2s (0x00) */ + {0x1158, 0, 1, 0x00000001}, /* Int_m_hresp_err (0x01) */ + {0x1158, 8, 1, 0x00000001}, /* Int_m_I2s1_bck_err1 (0x01) */ + {0x1158, 9, 1, 0x00000001}, /* Int_m_I2s1_bck_err2 (0x01) */ + {0x1158, 10, 1, 0x00000001}, /* Int_m_anc_faint (0x01) */ + {0x1158, 17, 1, 0x00000001}, /* Int_m_ovf_smasl (0x01) */ + {0x1158, 18, 1, 0x00000001}, /* Int_m_ovf_smasr (0x01) */ + {0x1158, 21, 1, 0x00000001}, /* Int_m_ovf_dnc1l (0x01) */ + {0x1158, 22, 1, 0x00000001}, /* Int_m_ovf_dnc1r (0x01) */ + {0x1158, 23, 1, 0x00000001}, /* Int_m_ovf_dnc2l (0x01) */ + {0x1158, 24, 1, 0x00000001}, /* Int_m_ovf_dnc2r (0x01) */ + {0x115c, 0, 1, 0x00000000}, /* Int_clr_hresp_err (0x00) */ + {0x115c, 8, 1, 0x00000000}, /* Int_clr_I2s1_bck_err1 (0x00) */ + {0x115c, 9, 1, 0x00000000}, /* Int_clr_I2s1_bck_err2 (0x00) */ + {0x115c, 10, 1, 0x00000000}, /* Int_clr_anc_faint (0x00) */ + {0x115c, 17, 1, 0x00000000}, /* Int_clr_ovf_smasl (0x00) */ + {0x115c, 18, 1, 0x00000000}, /* Int_clr_ovf_smasr (0x00) */ + {0x115c, 21, 1, 0x00000000}, /* Int_clr_ovf_dnc1l (0x00) */ + {0x115c, 22, 1, 0x00000000}, /* Int_clr_ovf_dnc1r (0x00) */ + {0x115c, 23, 1, 0x00000000}, /* Int_clr_ovf_dnc2l (0x00) */ + {0x115c, 24, 1, 0x00000000}, /* Int_clr_ovf_dnc2r (0x00) */ + {0x1160, 0, 1, 0x00000000}, /* Int_hresp_err (0x00) */ + {0x1160, 8, 1, 0x00000000}, /* Int_i2s_bck_err1 (0x00) */ + {0x1160, 9, 1, 0x00000000}, /* Int_i2s_bck_err2 (0x00) */ + {0x1160, 10, 1, 0x00000000}, /* Int_anc_faint (0x00) */ + {0x1160, 17, 1, 0x00000000}, /* Int_ovf_smasl (0x00) */ + {0x1160, 18, 1, 0x00000000}, /* Int_ovf_smasr (0x00) */ + {0x1160, 21, 1, 0x00000000}, /* Int_ovf_dnc1l (0x00) */ + {0x1160, 22, 1, 0x00000000}, /* Int_ovf_dnc1r (0x00) */ + {0x1160, 23, 1, 0x00000000}, /* Int_ovf_dnc2l (0x00) */ + {0x1160, 24, 1, 0x00000000}, /* Int_ovf_dnc2r (0x00) */ + {0x1180, 8, 24, 0x00000000}, /* Dbg_Mic_ch1_data (0x00) */ + {0x1184, 8, 24, 0x00000000}, /* Dbg_Mic_ch2_data (0x00) */ + {0x1188, 8, 24, 0x00000000}, /* Dbg_Mic_ch3_data (0x00) */ + {0x118c, 8, 24, 0x00000000}, /* Dbg_Mic_ch4_data (0x00) */ + {0x1190, 8, 24, 0x00000000}, /* Dbg_Mic_ch5_data (0x00) */ + {0x1194, 8, 24, 0x00000000}, /* Dbg_Mic_ch6_data (0x00) */ + {0x1198, 8, 24, 0x00000000}, /* Dbg_Mic_ch7_data (0x00) */ + {0x119c, 8, 24, 0x00000000}, /* Dbg_Mic_ch8_data (0x00) */ + {0x11a0, 8, 24, 0x00000000}, /* Dbg_I2s1_u_ch1_data (0x00) */ + {0x11a4, 8, 24, 0x00000000}, /* Dbg_I2s1_u_ch2_data (0x00) */ + {0x11a8, 8, 24, 0x00000000}, /* Dbg_I2s1_d_ch1_data (0x00) */ + {0x11ac, 8, 24, 0x00000000}, /* Dbg_I2s1_d_ch2_data (0x00) */ + {0x11b0, 8, 24, 0x00000000}, /* Dbg_I2s2_u_ch1_data (0x00) */ + {0x11b4, 8, 24, 0x00000000}, /* Dbg_I2s2_u_ch2_data (0x00) */ + {0x11b8, 8, 24, 0x00000000}, /* Dbg_I2s2_d_ch1_data (0x00) */ + {0x11bc, 8, 24, 0x00000000}, /* Dbg_I2s2_d_ch2_data (0x00) */ + {0x11c0, 0, 1, 0x00000000}, /* Dbg_Ctrl_mic_dbg_en (0x00) */ + {0x11c0, 1, 1, 0x00000000}, /* Dbg_Ctrl_I2s1_dbg_u_en (0x00) */ + {0x11c0, 2, 1, 0x00000000}, /* Dbg_Ctrl_I2s1_dbg_d_en (0x00) */ + {0x11c0, 3, 1, 0x00000000}, /* Dbg_Ctrl_I2s2_dbg_u_en (0x00) */ + {0x11c0, 4, 1, 0x00000000}, /* Dbg_Ctrl_I2s2_dbg_d_en (0x00) */ + {0x11f0, 0, 1, 0x00000000}, /* Clk_En_ahbmstr_mic_en (0x00) */ + {0x11f0, 1, 1, 0x00000000}, /* Clk_En_ahbmstr_I2s1_en (0x00) */ + {0x11f0, 2, 1, 0x00000000}, /* Clk_En_ahbmstr_I2s2_en (0x00) */ + {0x11fc, 0, 8, 0x00000064}, /* Mclk_Mon_thresh (0x64) */ + {0x1730, 0, 32, 0x00000000}, /* AHB MASTER MIC MASK (0x00) */ + {0x1f30, 0, 32, 0x00000000}, /* AHB MASTER I2S1 MASK (0x00) */ + {0x2730, 0, 32, 0x00000000} /* AHB MASTER I2S2 MASK (0x00) */ +}; + +/*************************************************************************** + * Private Functions + ****************************************************************************/ + +uint32_t write_bca_reg(BCA_REG_ID reg_id, uint32_t data) +{ + volatile uint32_t *addr; + uint32_t curr; + uint32_t mask = (g_bca_reg[reg_id].len == BCA_REG_MAX_BIT) ? + 0xffffffff : (1 << g_bca_reg[reg_id].len) - 1; + + addr = (volatile uint32_t *)(BCA_REG_BASE + g_bca_reg[reg_id].addr); + + curr = *addr & ~(mask << g_bca_reg[reg_id].pos); + *addr = curr | ((data & mask) << g_bca_reg[reg_id].pos); + + return 0; +} + +uint32_t write_bca_reg_mask(BCA_REG_ID reg_id) +{ + volatile uint32_t *addr; + uint32_t mask = (g_bca_reg[reg_id].len == BCA_REG_MAX_BIT) ? + 0xffffffff : (1 << g_bca_reg[reg_id].len) - 1; + + addr = (volatile uint32_t *)(BCA_REG_BASE + g_bca_reg[reg_id].addr); + *addr = mask << g_bca_reg[reg_id].pos; + + return 0; +} + +uint32_t read_bca_reg(BCA_REG_ID reg_id) +{ + volatile uint32_t *addr; + uint32_t data = 0; + uint32_t mask = (g_bca_reg[reg_id].len == BCA_REG_MAX_BIT) ? + 0xffffffff : (1 << g_bca_reg[reg_id].len) - 1; + + addr = (volatile uint32_t *)(BCA_REG_BASE + g_bca_reg[reg_id].addr); + data = (*addr >> g_bca_reg[reg_id].pos) & mask; + + return data; +} + +uint32_t write32_bca_reg(uint32_t offset, uint32_t data) +{ + volatile uint32_t *addr; + + addr = (volatile uint32_t *)(BCA_REG_BASE + offset); + *addr = data; + + return 0; +} + +uint32_t read32_bca_reg(uint32_t offset) +{ + volatile uint32_t *addr; + uint32_t data = 0; + + addr = (volatile uint32_t *)(BCA_REG_BASE + offset); + data = *addr; + + return data; +} + +void enable_mic_in_fmt24(uint8_t mic_num) +{ + uint8_t i; + + BCA_REG_ID mic_ch_sell[TRANS_CH_NUM_MAX] = + { + BCA_Mic_In_ch1_sel, + BCA_Mic_In_ch2_sel, + BCA_Mic_In_ch3_sel, + BCA_Mic_In_ch4_sel, + BCA_Mic_In_ch5_sel, + BCA_Mic_In_ch6_sel, + BCA_Mic_In_ch7_sel, + BCA_Mic_In_ch8_sel + }; + + mic_num = (mic_num > TRANS_CH_NUM_24BIT) ? TRANS_CH_NUM_24BIT : mic_num; + + write_bca_reg(BCA_Mic_In_bitwt, 0); + + for (i = 0; i < mic_num; i++) + { + write_bca_reg(mic_ch_sell[i], i); + } + + for (i = mic_num; i < TRANS_CH_NUM_24BIT; i++) + { + write_bca_reg(mic_ch_sell[i], TRANS_CH_NO_SELECT); + } + + write_bca_reg(BCA_Clk_En_ahbmstr_mic_en, 1); + write_bca_reg(BCA_Mic_In_start_adr, 0x00000000); + write_bca_reg(BCA_Mic_In_sample_no, 0); +} + +void enable_mic_in_fmt16(uint8_t mic_num) +{ + uint8_t i; + + BCA_REG_ID mic_ch_sell[TRANS_CH_NUM_MAX] = + { + BCA_Mic_In_ch1_sel, + BCA_Mic_In_ch2_sel, + BCA_Mic_In_ch3_sel, + BCA_Mic_In_ch4_sel, + BCA_Mic_In_ch5_sel, + BCA_Mic_In_ch6_sel, + BCA_Mic_In_ch7_sel, + BCA_Mic_In_ch8_sel + }; + + mic_num = (mic_num > (TRANS_CH_NUM_16BIT * 2)) ? + TRANS_CH_NUM_16BIT : (mic_num + 1) / 2; + + write_bca_reg(BCA_Mic_In_bitwt, 1); + + for (i = 0; i < mic_num; i++) + { + write_bca_reg(mic_ch_sell[i], i); + } + + for (i = mic_num; i < TRANS_CH_NUM_MAX; i++) + { + write_bca_reg(mic_ch_sell[i], TRANS_CH_NO_SELECT); + } + + write_bca_reg(BCA_Clk_En_ahbmstr_mic_en, 1); + write_bca_reg(BCA_Mic_In_start_adr, 0x00000000); + write_bca_reg(BCA_Mic_In_sample_no, 0); +} + +void enable_i2s1_out_fmt24(void) +{ + write_bca_reg(BCA_I2s1_Out_sd1_l_sel, I2S_OUT_SEL_SD1L); + write_bca_reg(BCA_I2s1_Out_sd1_r_sel, I2S_OUT_SEL_SD1R); + write_bca_reg(BCA_I2s1_Out_bitwt, 0); + write_bca_reg(BCA_Clk_En_ahbmstr_I2s1_en, 1); + write_bca_reg(BCA_I2s1_Out_start_adr, 0x00000000); + write_bca_reg(BCA_I2s1_Out_sample_no, 0); +} + +void enable_i2s1_out_fmt16(void) +{ + write_bca_reg(BCA_I2s1_Out_sd1_l_sel, I2S_OUT_SEL_SD1L); + write_bca_reg(BCA_I2s1_Out_sd1_r_sel, I2S_OUT_SEL_SD1R); + write_bca_reg(BCA_I2s1_Out_bitwt, 1); + write_bca_reg(BCA_Clk_En_ahbmstr_I2s1_en, 1); + write_bca_reg(BCA_I2s1_Out_start_adr, 0x00000000); + write_bca_reg(BCA_I2s1_Out_sample_no, 0); +} + +void enable_i2s2_out_fmt24(void) +{ + write_bca_reg(BCA_I2s2_Out_sd1_l_sel, I2S_OUT_SEL_SD1L); + write_bca_reg(BCA_I2s2_Out_sd1_r_sel, I2S_OUT_SEL_SD1R); + write_bca_reg(BCA_I2s2_Out_bitwt, 0); + write_bca_reg(BCA_Clk_En_ahbmstr_I2s2_en, 1); + write_bca_reg(BCA_I2s2_Out_start_adr, 0x00000000); + write_bca_reg(BCA_I2s2_Out_sample_no, 0); +} + +void enable_i2s2_out_fmt16(void) +{ + write_bca_reg(BCA_I2s2_Out_sd1_l_sel, I2S_OUT_SEL_SD1L); + write_bca_reg(BCA_I2s2_Out_sd1_r_sel, I2S_OUT_SEL_SD1R); + write_bca_reg(BCA_I2s2_Out_bitwt, 1); + write_bca_reg(BCA_Clk_En_ahbmstr_I2s2_en, 1); + write_bca_reg(BCA_I2s2_Out_start_adr, 0x00000000); + write_bca_reg(BCA_I2s2_Out_sample_no, 0); +} + +/*************************************************************************** + * Public Functions + ****************************************************************************/ + +void cxd56_audio_bca_reg_clear_bck_err_int(void) +{ + write_bca_reg(BCA_Int_m_i2s1_bck_err1, 0); + write_bca_reg(BCA_Int_m_i2s1_bck_err2, 0); +} + +void cxd56_audio_bca_reg_set_smaster(void) +{ + write_bca_reg(BCA_Int_m_ovf_smasl, 0); + write_bca_reg(BCA_Int_m_ovf_smasr, 0); +} + +void cxd56_audio_bca_reg_set_datarate(uint8_t clk_mode) +{ + if (clk_mode == CXD56_AUDIO_CLKMODE_HIRES) + { + /* Set 4fs. */ + + write_bca_reg(BCA_I2s_ensel, 1); + } + else + { + /* Set 1fs. */ + + write_bca_reg(BCA_I2s_ensel, 0); + } +} + +void cxd56_audio_bca_reg_en_fmt24(cxd56_audio_dma_t handle, uint8_t ch_num) +{ + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + enable_mic_in_fmt24(ch_num); + break; + case CXD56_AUDIO_DMAC_I2S0_DOWN: + enable_i2s1_out_fmt24(); + break; + default: + enable_i2s2_out_fmt24(); + break; + } +} + +void cxd56_audio_bca_reg_en_fmt16(cxd56_audio_dma_t handle, uint8_t ch_num) +{ + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + enable_mic_in_fmt16(ch_num); + break; + case CXD56_AUDIO_DMAC_I2S0_DOWN: + enable_i2s1_out_fmt16(); + break; + default: + enable_i2s2_out_fmt16(); + break; + } +} + +void cxd56_audio_bca_reg_get_dma_mstate(cxd56_audio_dma_t handle, + FAR cxd56_audio_dma_mstate_t *state) +{ + BCA_REG_ID reg_id_start; + BCA_REG_ID reg_id_error; + BCA_REG_ID reg_id_monbuf; + + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id_start = BCA_Mic_In_start; + reg_id_error = BCA_Mic_In_error_setting; + reg_id_monbuf = BCA_Mic_In_monbuf; + break; + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id_start = BCA_I2s1_Out_Mon_start; + reg_id_error = BCA_I2s1_Out_Mon_error_setting; + reg_id_monbuf = BCA_I2s1_Out_Mon_monbuf; + break; + default: + reg_id_start = BCA_I2s2_Out_Mon_start; + reg_id_error = BCA_I2s2_Out_Mon_error_setting; + reg_id_monbuf = BCA_I2s2_Out_Mon_monbuf; + break; + } + state->start = (uint8_t)read_bca_reg(reg_id_start); + state->err_setting = (uint8_t)read_bca_reg(reg_id_error); + state->buf_state = (uint8_t)read_bca_reg(reg_id_monbuf); +} + +void cxd56_audio_bca_reg_en_bus_err_int(void) +{ + write_bca_reg(BCA_Int_m_hresp_err, 0); +} + +void cxd56_audio_bca_reg_dis_bus_err_int(void) +{ + write_bca_reg(BCA_Int_m_hresp_err, 1); +} + +uint32_t cxd56_audio_bca_reg_get_dma_done_state_mic(void) +{ + uint32_t int_ac = + read32_bca_reg(g_bca_reg[BCA_Mic_Int_Ctrl_done_mic].addr) + & ~(read32_bca_reg(g_bca_reg[BCA_Mic_Int_Mask_done_mic].addr)) + & 0x0f; + + return int_ac; +} + +uint32_t cxd56_audio_bca_reg_get_dma_done_state_i2s1(void) +{ + uint32_t int_i2s = + read32_bca_reg(g_bca_reg[BCA_I2s1_Int_Ctrl_done_i2so].addr) + & ~(read32_bca_reg(g_bca_reg[BCA_I2s1_Int_Mask_done_i2so].addr)) + & 0x3f; + + return int_i2s; +} + +uint32_t cxd56_audio_bca_reg_get_dma_done_state_i2s2(void) +{ + uint32_t int_i2s2 = + read32_bca_reg(g_bca_reg[BCA_I2s2_Int_Ctrl_done_i2so].addr) + & ~(read32_bca_reg(g_bca_reg[BCA_I2s2_Int_Mask_done_i2so].addr)) + & 0x3f; + + return int_i2s2; +} + +void cxd56_audio_bca_reg_clear_dma_done_state_mic(uint32_t value) +{ + write32_bca_reg(g_bca_reg[BCA_Mic_Int_Ctrl_done_mic].addr, value); +} + +void cxd56_audio_bca_reg_clear_dma_done_state_i2s1(uint32_t value) +{ + write32_bca_reg(g_bca_reg[BCA_I2s1_Int_Ctrl_done_i2so].addr, value); +} + +void cxd56_audio_bca_reg_clear_dma_done_state_i2s2(uint32_t value) +{ + write32_bca_reg(g_bca_reg[BCA_I2s2_Int_Ctrl_done_i2so].addr, value); +} + +void cxd56_audio_bca_reg_mask_done_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Mask_done_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Mask_done_i2so; + break; + + default: + reg_id = BCA_I2s2_Int_Mask_done_i2so; + break; + } + + write_bca_reg(reg_id, 1); +} + +void cxd56_audio_bca_reg_unmask_done_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Mask_done_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Mask_done_i2so; + break; + + default: + reg_id = BCA_I2s2_Int_Mask_done_i2so; + break; + } + + write_bca_reg(reg_id, 0); +} + +void cxd56_audio_bca_reg_clear_done_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Ctrl_done_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Ctrl_done_i2so; + break; + + default: + reg_id = BCA_I2s2_Int_Ctrl_done_i2so; + break; + } + + write_bca_reg_mask(reg_id); +} + +bool cxd56_audio_bca_reg_is_dma_fifo_empty(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_I2s1_In_rtd_trg; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_In_rtd_trg; + break; + + default: + reg_id = BCA_I2s2_Out_rtd_trg; + break; + } + + if(1 == read_bca_reg(reg_id)) + { + return true; + } + return false; +} + +void cxd56_audio_bca_reg_mask_err_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Mask_err_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Mask_err_i2so; + break; + + default: + reg_id = BCA_I2s2_Int_Mask_err_i2so; + break; + } + + write_bca_reg(reg_id, 1); +} + +void cxd56_audio_bca_reg_unmask_err_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Mask_err_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Mask_err_i2so; + break; + + default: + reg_id = BCA_I2s2_Int_Mask_err_i2so; + break; + } + + write_bca_reg(reg_id, 0); +} + +void cxd56_audio_bca_reg_clear_err_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Ctrl_err_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Ctrl_err_i2so; + break; + + default: + reg_id = BCA_I2s2_Int_Mask_err_i2so; + break; + } + + write_bca_reg_mask(reg_id); +} + +void cxd56_audio_bca_reg_mask_cmb_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Mask_cmb_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Mask_cmb_i2s; + break; + + default: + reg_id = BCA_I2s2_Int_Mask_cmb_i2s; + break; + } + + write_bca_reg(reg_id, 1); +} + +void cxd56_audio_bca_reg_unmask_cmb_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Mask_cmb_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Mask_cmb_i2s; + break; + + default: + reg_id = BCA_I2s2_Int_Mask_cmb_i2s; + break; + } + + write_bca_reg(reg_id, 0); +} + +void cxd56_audio_bca_reg_clear_cmb_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Ctrl_cmb_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Ctrl_cmb_i2s; + break; + + default: + reg_id = BCA_I2s2_Int_Ctrl_cmb_i2s; + break; + } + + write_bca_reg_mask(reg_id); +} + +uint32_t cxd56_audio_bca_reg_get_int_status(void) +{ + return read32_bca_reg(g_bca_reg[BCA_Int_hresp_err].addr); +} + +void cxd56_audio_bca_reg_clear_int_status(uint32_t int_au) +{ + write32_bca_reg(g_bca_reg[BCA_Int_clr_hresp_err].addr, int_au); +} + +void cxd56_audio_bca_reg_mask_bus_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = AHB_Master_Mic_Mask; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = AHB_Master_I2s1_Mask; + break; + + default: + reg_id = AHB_Master_I2s2_Mask; + break; + } + write_bca_reg(reg_id, 0); +} + +void cxd56_audio_bca_reg_unmask_bus_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + uint32_t val = 0; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = AHB_Master_Mic_Mask; + val = 0x00000303; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = AHB_Master_I2s1_Mask; + val = 0x00000202; + break; + + default: + reg_id = AHB_Master_I2s2_Mask; + val = 0x00000202; + break; + } + write_bca_reg(reg_id, val); +} + +void cxd56_audio_bca_reg_set_start_addr(cxd56_audio_dma_t handle, + uint32_t addr) +{ + BCA_REG_ID reg_id; + + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_In_start_adr; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Out_start_adr; + break; + + default: + reg_id = BCA_I2s2_Out_start_adr; + break; + } + + write_bca_reg(reg_id, addr >> 2); +} + +void cxd56_audio_bca_reg_set_sample_no(cxd56_audio_dma_t handle, + uint32_t sample) +{ + BCA_REG_ID reg_id; + + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_In_sample_no; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Out_sample_no; + break; + + default: + reg_id = BCA_I2s2_Out_sample_no; + break; + } + + write_bca_reg(reg_id, sample - 1); +} + +void cxd56_audio_bca_reg_start_dma(cxd56_audio_dma_t handle, + bool nointr) +{ + BCA_REG_ID reg_id; + uint32_t val = nointr ? 0x05 : 0x01; + + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_In_rtd_trg; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Out_rtd_trg; + break; + + default: + reg_id = BCA_I2s2_Out_rtd_trg; + break; + } + + write_bca_reg(reg_id, val); +} + +void cxd56_audio_bca_reg_stop_dma(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_In_rtd_trg; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Out_rtd_trg; + break; + + default: + reg_id = BCA_I2s2_Out_rtd_trg; + break; + } + + write_bca_reg(reg_id, 0x04); +} + +bool cxd56_audio_bca_reg_is_done_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Ctrl_done_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Ctrl_done_i2so; + break; + + default: + reg_id = BCA_I2s2_Int_Ctrl_done_i2so; + break; + } + + if (read_bca_reg(reg_id) == 0) + { + return false; + } + + return true; +} + +bool cxd56_audio_bca_reg_is_err_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Ctrl_err_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Ctrl_err_i2so; + break; + + default: + reg_id = BCA_I2s2_Int_Ctrl_err_i2so; + break; + } + + if (read_bca_reg(reg_id) == 0) + { + return false; + } + + return true; +} + +bool cxd56_audio_bca_reg_is_smp_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Ctrl_smp_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Ctrl_smp_i2s; + break; + + default: + reg_id = BCA_I2s2_Int_Ctrl_smp_i2s; + break; + } + + if (read_bca_reg(reg_id) == 0) + { + return false; + } + + return true; +} + +void cxd56_audio_bca_reg_mask_smp_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Mask_smp_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Mask_smp_i2s; + break; + + default: + reg_id = BCA_I2s1_Int_Mask_smp_i2s; + break; + } + write_bca_reg(reg_id, 1); +} + +void cxd56_audio_bca_reg_unmask_smp_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Mask_smp_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Mask_smp_i2s; + break; + + default: + reg_id = BCA_I2s1_Int_Mask_smp_i2s; + break; + } + + write_bca_reg(reg_id, 0); +} + +void cxd56_audio_bca_reg_clear_smp_int(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_Int_Ctrl_smp_mic; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Int_Ctrl_smp_i2s; + break; + + default: + reg_id = BCA_I2s2_Int_Ctrl_smp_i2s; + break; + } + + write_bca_reg_mask(reg_id); +} + +uint32_t cxd56_audio_bca_reg_get_mon_state_err(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_In_error_setting; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Out_Mon_error_setting; + break; + + default: + reg_id = BCA_I2s2_Out_Mon_error_setting; + break; + } + + return read_bca_reg(reg_id); +} + +uint32_t cxd56_audio_bca_reg_get_mon_state_start(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_In_start; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Out_Mon_start; + break; + + default: + reg_id = BCA_I2s2_Out_Mon_start; + break; + } + + return read_bca_reg(reg_id); +} + +uint32_t cxd56_audio_bca_reg_get_mon_state_buf(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_In_monbuf; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Out_Mon_monbuf; + break; + + default: + reg_id = BCA_I2s2_Out_Mon_monbuf; + break; + } + + return read_bca_reg(reg_id); +} + +uint32_t cxd56_audio_bca_reg_get_dma_state(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_In_rtd_trg; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Out_rtd_trg; + break; + + default: + reg_id = BCA_I2s2_Out_rtd_trg; + break; + } + + return read_bca_reg(reg_id); +} + +void cxd56_audio_bca_reg_reset_chsel(cxd56_audio_dma_t handle) +{ + BCA_REG_ID reg_id; + uint32_t chsel; + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + reg_id = BCA_Mic_In_ch8_sel; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + reg_id = BCA_I2s1_Out_sd1_r_sel; + break; + + default: + reg_id = BCA_I2s2_Out_sd1_r_sel; + break; + } + + chsel = read32_bca_reg(g_bca_reg[reg_id].addr); + + /* Clear ChSel. */ + + write32_bca_reg(g_bca_reg[reg_id].addr, 0xffffffff); + + /* Set ChSel. */ + + write32_bca_reg(g_bca_reg[reg_id].addr, chsel); +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_bca_reg.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_bca_reg.h new file mode 100644 index 00000000000..a4dacac0ec4 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_bca_reg.h @@ -0,0 +1,312 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_bca_reg.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_BCA_REG_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_BCA_REG_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +typedef enum +{ + BCA_Mic_In_start_adr, + BCA_Mic_In_sample_no, + BCA_Mic_In_rtd_trg, + BCA_Mic_In_nointr, + BCA_Mic_In_bitwt, + BCA_Mic_In_ch8_sel, + BCA_Mic_In_ch7_sel, + BCA_Mic_In_ch6_sel, + BCA_Mic_In_ch5_sel, + BCA_Mic_In_ch4_sel, + BCA_Mic_In_ch3_sel, + BCA_Mic_In_ch2_sel, + BCA_Mic_In_ch1_sel, + BCA_Mic_In_start, + BCA_Mic_In_error_setting, + BCA_Mic_In_monbuf, + BCA_I2s1_In_start_adr, + BCA_I2s1_In_sample_no, + BCA_I2s1_In_rtd_trg, + BCA_I2s1_In_nointr, + BCA_I2s1_In_bitwt, + BCA_I2s1_In_ch2_sel, + BCA_I2s1_In_ch1_sel, + BCA_I2s1_In_Mon_start, + BCA_I2s1_In_Mon_error_setting, + BCA_I2s1_In_Mon_monbuf, + BCA_I2s2_In_start_adr, + BCA_I2s2_In_sample_no, + BCA_I2s2_In_rtd_trg, + BCA_I2s2_In_nointr, + BCA_I2s2_In_bitwt, + BCA_I2s2_In_ch2_sel, + BCA_I2s2_In_ch1_sel, + BCA_I2s2_In_Mon_start, + BCA_I2s2_In_Mon_error_setting, + BCA_I2s2_In_Mon_monbuf, + BCA_I2s1_Out_start_adr, + BCA_I2s1_Out_sample_no, + BCA_I2s1_Out_rtd_trg, + BCA_I2s1_Out_nointr, + BCA_I2s1_Out_bitwt, + BCA_I2s1_Out_sd1_r_sel, + BCA_I2s1_Out_sd1_l_sel, + BCA_I2s1_Out_Mon_start, + BCA_I2s1_Out_Mon_error_setting, + BCA_I2s1_Out_Mon_monbuf, + BCA_I2s2_Out_start_adr, + BCA_I2s2_Out_sample_no, + BCA_I2s2_Out_rtd_trg, + BCA_I2s2_Out_nointr, + BCA_I2s2_Out_bitwt, + BCA_I2s2_Out_sd1_r_sel, + BCA_I2s2_Out_sd1_l_sel, + BCA_I2s2_Out_Mon_start, + BCA_I2s2_Out_Mon_error_setting, + BCA_I2s2_Out_Mon_monbuf, + BCA_I2s_ensel, + BCA_Mic_In_prdat_u, + BCA_I2s1_In_prdat_u, + BCA_I2s2_In_prdat_u, + BCA_I2s1_Out_prdat_d, + BCA_I2s2_Out_prdat_d, + BCA_Mic_Int_Ctrl_done_mic, + BCA_Mic_Int_Ctrl_err_mic, + BCA_Mic_Int_Ctrl_smp_mic, + BCA_Mic_Int_Ctrl_cmb_mic, + BCA_I2s1_Int_Ctrl_done_i2so, + BCA_I2s1_Int_Ctrl_err_i2so, + BCA_I2s1_Int_Ctrl_done_i2si, + BCA_I2s1_Int_Ctrl_err_i2si, + BCA_I2s1_Int_Ctrl_smp_i2s, + BCA_I2s1_Int_Ctrl_cmb_i2s, + BCA_I2s2_Int_Ctrl_done_i2so, + BCA_I2s2_Int_Ctrl_err_i2so, + BCA_I2s2_Int_Ctrl_done_i2si, + BCA_I2s2_Int_Ctrl_err_i2si, + BCA_I2s2_Int_Ctrl_smp_i2s, + BCA_I2s2_Int_Ctrl_cmb_i2s, + BCA_Mic_Int_Mask_done_mic, + BCA_Mic_Int_Mask_err_mic, + BCA_Mic_Int_Mask_smp_mic, + BCA_Mic_Int_Mask_cmb_mic, + BCA_Mic_Int_Mask_nostpmsk, + BCA_Mic_Int_Mask_srst_mic, + BCA_I2s1_Int_Mask_done_i2so, + BCA_I2s1_Int_Mask_err_i2so, + BCA_I2s1_Int_Mask_done_i2si, + BCA_I2s1_Int_Mask_err_i2si, + BCA_I2s1_Int_Mask_smp_i2s, + BCA_I2s1_Int_Mask_cmb_i2s, + BCA_I2s1_Int_Mask_nostpmsk, + BCA_I2s1_Int_Mask_srst_i2s, + BCA_I2s2_Int_Mask_done_i2so, + BCA_I2s2_Int_Mask_err_i2so, + BCA_I2s2_Int_Mask_done_i2si, + BCA_I2s2_Int_Mask_err_i2si, + BCA_I2s2_Int_Mask_smp_i2s, + BCA_I2s2_Int_Mask_cmb_i2s, + BCA_I2s2_Int_Mask_nostpmsk, + BCA_I2s2_Int_Mask_srst_i2s, + BCA_Int_m_hresp_err, + BCA_Int_m_i2s1_bck_err1, + BCA_Int_m_i2s1_bck_err2, + BCA_Int_m_anc_faint, + BCA_Int_m_ovf_smasl, + BCA_Int_m_ovf_smasr, + BCA_Int_m_ovf_dnc1l, + BCA_Int_m_ovf_dnc1r, + BCA_Int_m_ovf_dnc2l, + BCA_Int_m_ovf_dnc2r, + BCA_Int_clr_hresp_err, + BCA_Int_clr_i2s1_bck_err1, + BCA_Int_clr_i2S1_bck_err2, + BCA_Int_clr_anc_faint, + BCA_Int_clr_ovf_smasl, + BCA_Int_clr_ovf_smasr, + BCA_Int_clr_ovf_dnc1l, + BCA_Int_clr_ovf_dnc1r, + BCA_Int_clr_ovf_dnc2l, + BCA_Int_clr_ovf_dnc2r, + BCA_Int_hresp_err, + BCA_Int_i2s_bck_err1, + BCA_Int_i2s_bck_err2, + BCA_Int_anc_faint, + BCA_Int_ovf_smasl, + BCA_Int_ovf_smasr, + BCA_Int_ovf_dnc1l, + BCA_Int_ovf_dnc1r, + BCA_Int_ovf_dnc2l, + BCA_Int_ovf_dnc2r, + BCA_Dbg_Mic_ch1_data, + BCA_Dbg_Mic_ch2_data, + BCA_Dbg_Mic_ch3_data, + BCA_Dbg_Mic_ch4_data, + BCA_Dbg_Mic_ch5_data, + BCA_Dbg_Mic_ch6_data, + BCA_Dbg_Mic_ch7_data, + BCA_Dbg_Mic_ch8_data, + BCA_Dbg_I2s1_u_ch1_data, + BCA_Dbg_I2s1_u_ch2_data, + BCA_Dbg_I2s1_d_ch1_data, + BCA_Dbg_I2s1_d_ch2_data, + BCA_Dbg_I2s2_u_ch1_data, + BCA_Dbg_I2s2_u_ch2_data, + BCA_Dbg_I2s2_d_ch1_data, + BCA_Dbg_I2s2_d_ch2_data, + BCA_Dbg_Ctrl_mic_dbg_en, + BCA_Dbg_Ctrl_I2s1_dbg_u_en, + BCA_Dbg_Ctrl_I2s1_dbg_d_en, + BCA_Dbg_Ctrl_I2s2_dbg_u_en, + BCA_Dbg_Ctrl_I2s2_dbg_d_en, + BCA_Clk_En_ahbmstr_mic_en, + BCA_Clk_En_ahbmstr_I2s1_en, + BCA_Clk_En_ahbmstr_I2s2_en, + BCA_Mclk_Mon_thresh, + AHB_Master_Mic_Mask, + AHB_Master_I2s1_Mask, + AHB_Master_I2s2_Mask, + BCA_REG_MAX_ENTRY +} BCA_REG_ID; + +#define DMA_STATE_BIT_AC_DONE 1 +#define DMA_STATE_BIT_AC_ERR 2 +#define DMA_STATE_BIT_AC_CMB 8 +#define DMA_STATE_BIT_I2S_OUT_DONE 1 +#define DMA_STATE_BIT_I2S_OUT_ERR 2 +#define DMA_STATE_BIT_I2S_IN_DONE 4 +#define DMA_STATE_BIT_I2S_IN_ERR 8 +#define DMA_STATE_BIT_I2S_CMB 32 + +#define DMA_MSTATE_START 1 +#define DMA_MSTART_READY 0 + +#define DMA_MSTATE_ERR_OK +#define DMA_MSTATE_ERR_NO_ENABLE_CH 1 +#define DMA_MSTATE_ERR_CH1_4_INVALID 2 +#define DMA_MSTATE_ERR_CH5_8_INVALID 4 + +#define DMA_MSTATE_BUF_EMPTY 3 + +#define DMA_CMD_FIFO_NOT_FULL 1 + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void cxd56_audio_bca_reg_clear_bck_err_int(void); +void cxd56_audio_bca_reg_set_smaster(void); +void cxd56_audio_bca_reg_set_datarate(uint8_t clk_mode); + +void cxd56_audio_bca_reg_en_fmt24(cxd56_audio_dma_t handle, uint8_t ch_num); +void cxd56_audio_bca_reg_en_fmt16(cxd56_audio_dma_t handle, uint8_t ch_num); + +void cxd56_audio_bca_reg_en_bus_err_int(void); +void cxd56_audio_bca_reg_dis_bus_err_int(void); + +void cxd56_audio_bca_reg_get_dma_mstate(cxd56_audio_dma_t handle, + FAR cxd56_audio_dma_mstate_t *state); + +uint32_t cxd56_audio_bca_reg_get_dma_done_state_mic(void); +uint32_t cxd56_audio_bca_reg_get_dma_done_state_i2s1(void); +uint32_t cxd56_audio_bca_reg_get_dma_done_state_i2s2(void); + +void cxd56_audio_bca_reg_mask_done_int(cxd56_audio_dma_t handle); +void cxd56_audio_bca_reg_unmask_done_int(cxd56_audio_dma_t handle); +void cxd56_audio_bca_reg_clear_done_int(cxd56_audio_dma_t handle); + +void cxd56_audio_bca_reg_clear_dma_done_state_mic(uint32_t value); +void cxd56_audio_bca_reg_clear_dma_done_state_i2s1(uint32_t value); +void cxd56_audio_bca_reg_clear_dma_done_state_i2s2(uint32_t value); + +bool cxd56_audio_bca_reg_is_dma_fifo_empty(cxd56_audio_dma_t handle); + +void cxd56_audio_bca_reg_mask_err_int(cxd56_audio_dma_t handle); +void cxd56_audio_bca_reg_unmask_err_int(cxd56_audio_dma_t handle); +void cxd56_audio_bca_reg_clear_err_int(cxd56_audio_dma_t handle); + +void cxd56_audio_bca_reg_mask_cmb_int(cxd56_audio_dma_t handle); +void cxd56_audio_bca_reg_unmask_cmb_int(cxd56_audio_dma_t handle); +void cxd56_audio_bca_reg_clear_cmb_int(cxd56_audio_dma_t handle); + +uint32_t cxd56_audio_bca_reg_get_int_status(void); +void cxd56_audio_bca_reg_clear_int_status(uint32_t int_au); + +void cxd56_audio_bca_reg_mask_bus_int(cxd56_audio_dma_t handle); +void cxd56_audio_bca_reg_unmask_bus_int(cxd56_audio_dma_t handle); + +void cxd56_audio_bca_reg_set_start_addr(cxd56_audio_dma_t handle, + uint32_t addr); +void cxd56_audio_bca_reg_set_sample_no(cxd56_audio_dma_t handle, + uint32_t sample); +void cxd56_audio_bca_reg_start_dma(cxd56_audio_dma_t handle, + bool nointr); +void cxd56_audio_bca_reg_stop_dma(cxd56_audio_dma_t handle); + +bool cxd56_audio_bca_reg_is_done_int(cxd56_audio_dma_t handle); +bool cxd56_audio_bca_reg_is_err_int(cxd56_audio_dma_t handle); + +bool cxd56_audio_bca_reg_is_smp_int(cxd56_audio_dma_t handle); +void cxd56_audio_bca_reg_mask_smp_int(cxd56_audio_dma_t handle); +void cxd56_audio_bca_reg_unmask_smp_int(cxd56_audio_dma_t handle); +void cxd56_audio_bca_reg_clear_smp_int(cxd56_audio_dma_t handle); + +uint32_t cxd56_audio_bca_reg_get_mon_state_err(cxd56_audio_dma_t handle); +uint32_t cxd56_audio_bca_reg_get_mon_state_start(cxd56_audio_dma_t handle); +uint32_t cxd56_audio_bca_reg_get_mon_state_buf(cxd56_audio_dma_t handle); +uint32_t cxd56_audio_bca_reg_get_dma_state(cxd56_audio_dma_t handle); +void cxd56_audio_bca_reg_reset_chsel(cxd56_audio_dma_t handle); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_BCA_REG_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_beep.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_beep.c new file mode 100644 index 00000000000..363eb0d97ca --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_beep.c @@ -0,0 +1,209 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_beep.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_ac_reg.h" +#include "cxd56_audio_beep.h" + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Maximum frequency. */ + +#define FREQ_MAX 4085 + +/* Minimum frequency. */ + +#define FREQ_MIN 94 + +/* Maximum volume. */ + +#define VOL_MAX 0 + +/* Minimum volume. */ + +#define VOL_MIN -90 + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/*************************************************************************** + * Private Data + ****************************************************************************/ + +static bool g_beep = false; + +static const uint16_t g_beepfreqtable[] = +{ + 120, 127, 134, 142, 151, 160, 169, 180, 190, 201, 214, 226, + 240, 254, 269, 285, 302, 320, 339, 360, 381, 403, 428, 453, + 480, 509, 539, 571, 606, 642, 681, 719, 762, 810, 857, 910, + 965, 1021, 1079, 1143, 1215, 1289, 1362, 1444, 1536, 1627, 1714, 1829, + 1939, 2043, 2182, 2313, 2400, 2560, 2704, 2866, 3048, 3200, 3429, 3623, + 3840, 4085, 94 +}; + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Private Functions + ****************************************************************************/ + +uint32_t convert_freq(uint32_t freq) +{ + uint32_t prev; + uint32_t i; + + for (i = 0; i < sizeof(g_beepfreqtable) / sizeof(uint16_t); i++) + { + prev = (i + 62) % 63; + if (freq < g_beepfreqtable[i]) + { + if (prev == 62) + { + break; + } + else if(g_beepfreqtable[prev] <= freq) + { + break; + } + } + } + + return prev; +} + +/*************************************************************************** + * Public Functions + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_beep_set_freq(uint16_t freq) +{ + uint32_t conv_freq = 0; + + if (freq > FREQ_MAX) + { + return CXD56_AUDIO_ECODE_BEP_FREQ_MAX; + } + + if (freq < FREQ_MIN) + { + return CXD56_AUDIO_ECODE_BEP_FREQ_MIN; + } + + /* Mute beep. */ + + cxd56_audio_ac_reg_disable_beep(); + + /* Convert Frequency. */ + + conv_freq = convert_freq(freq); + + /* Set beep parameter. */ + + cxd56_audio_ac_reg_set_beep_freq(conv_freq); + + if (g_beep) + { + cxd56_audio_ac_reg_enable_beep(); + } + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_beep_set_vol(int16_t vol) +{ + uint32_t conv_vol = 0; + + if (vol > VOL_MAX) + { + return CXD56_AUDIO_ECODE_BEP_VOL_MAX; + } + + if (vol < VOL_MIN) + { + return CXD56_AUDIO_ECODE_BEP_VOL_MIN; + } + + /* Mute off. */ + + cxd56_audio_ac_reg_disable_beep(); + + /* Convert Volume. */ + + if (vol != 0) + { + conv_vol = -vol / 3; + } + else + { + conv_vol = 0; + } + + /* Set beep parameter. */ + + cxd56_audio_ac_reg_set_beep_vol(conv_vol); + + if (g_beep) + { + cxd56_audio_ac_reg_enable_beep(); + } + + return CXD56_AUDIO_ECODE_OK; +} + +void cxd56_audio_beep_play(void) +{ + g_beep = true; + + cxd56_audio_ac_reg_enable_beep(); +} + +void cxd56_audio_beep_stop(void) +{ + g_beep = false; + + cxd56_audio_ac_reg_disable_beep(); +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_beep.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_beep.h new file mode 100644 index 00000000000..b9e226ad54f --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_beep.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_beep.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_BEEP_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_BEEP_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_beep_set_freq(uint16_t freq); +CXD56_AUDIO_ECODE cxd56_audio_beep_set_vol(int16_t vol); +void cxd56_audio_beep_play(void); +void cxd56_audio_beep_stop(void); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_BEEP_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_config.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_config.c new file mode 100644 index 00000000000..f8088bc4327 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_config.c @@ -0,0 +1,197 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_config.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "cxd56_audio_config.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MIC_CH_BITNUM 4 +#define MIC_CH_BITMAP 0xf + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct cxd56_audio_cfg_s +{ + uint8_t mic_num; + uint8_t mic_dev; + uint8_t mic_mode; + uint32_t mic_map; + cxd56_audio_clkmode_t clk_mode; + cxd56_audio_sp_drv_t sp_driver; +}; +static struct cxd56_audio_cfg_s g_audio_cfg = +{ + 1, + CXD56_AUDIO_CFG_MIC_DEV_ANADIG, + CXD56_AUDIO_CFG_MIC_MODE_64FS, + CXD56_AUDIO_CFG_MIC, + CXD56_AUDIO_CLKMODE_NORMAL, + CXD56_AUDIO_CFG_SP_DRIVER +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void set_miccfg(void) +{ + bool is_amic = false; + bool is_dmic = false; + uint8_t mic_num = 0; + uint8_t mic_sel = 0; + uint8_t i; + + for (i = 0; i < CXD56_AUDIO_MIC_CH_MAX; i++) + { + mic_sel = (g_audio_cfg.mic_map >> (i * MIC_CH_BITNUM)) & + MIC_CH_BITMAP; + if ((mic_sel >= 1) && (mic_sel <= 4)) + { + is_amic = true; + mic_num++; + } + else if ((mic_sel >= 5) && (mic_sel <= 12)) + { + is_dmic = true; + mic_num++; + } + } + + /* Set mic number. */ + + g_audio_cfg.mic_num = mic_num; + + /* Set mic device type and mode. */ + + if (is_amic) + { + if(is_dmic) + { + g_audio_cfg.mic_dev = CXD56_AUDIO_CFG_MIC_DEV_ANADIG; + g_audio_cfg.mic_mode = CXD56_AUDIO_CFG_MIC_MODE_64FS; + } + else + { + g_audio_cfg.mic_dev = CXD56_AUDIO_CFG_MIC_DEV_ANALOG; + g_audio_cfg.mic_mode = CXD56_AUDIO_CFG_MIC_MODE_128FS; + } + } + else + { + if(is_dmic) + { + g_audio_cfg.mic_dev = CXD56_AUDIO_CFG_MIC_DEV_DIGITAL; + g_audio_cfg.mic_mode = CXD56_AUDIO_CFG_MIC_MODE_64FS; + } + else + { + g_audio_cfg.mic_dev = CXD56_AUDIO_CFG_MIC_DEV_NONE; + g_audio_cfg.mic_mode = CXD56_AUDIO_CFG_MIC_MODE_64FS; + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void cxd56_audio_config_init(void) +{ + /* Set mic config */ + + set_miccfg(); +} + +uint8_t cxd56_audio_config_get_micmode(void) +{ + return g_audio_cfg.mic_mode; +} + +uint8_t cxd56_audio_config_get_micdev(void) +{ + return g_audio_cfg.mic_dev; +} + +uint8_t cxd56_audio_config_get_micnum(void) +{ + return g_audio_cfg.mic_num; +} + +void cxd56_audio_config_set_spdriver(cxd56_audio_sp_drv_t sp_driver) +{ + g_audio_cfg.sp_driver = sp_driver; +} + +cxd56_audio_sp_drv_t cxd56_audio_config_get_spdriver(void) +{ + return g_audio_cfg.sp_driver; +} + +void cxd56_audio_config_set_clkmode(cxd56_audio_clkmode_t mode) +{ + g_audio_cfg.clk_mode = mode; +} + +cxd56_audio_clkmode_t cxd56_audio_config_get_clkmode(void) +{ + return g_audio_cfg.clk_mode; +} + +void cxd56_audio_config_set_micmap(uint32_t map) +{ + g_audio_cfg.mic_map = map; +} + +uint32_t cxd56_audio_config_get_micmap(void) +{ + return g_audio_cfg.mic_map; +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_config.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_config.h new file mode 100644 index 00000000000..ae12a3d6737 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_config.h @@ -0,0 +1,383 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_config.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_CONFIG_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_CONFIG_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +enum cxd56_audio_cfg_mic_mode_e +{ + CXD56_AUDIO_CFG_MIC_MODE_64FS = 0, + CXD56_AUDIO_CFG_MIC_MODE_128FS +}; + +enum cxd56_audio_cfg_mic_dev_e +{ + CXD56_AUDIO_CFG_MIC_DEV_NONE = 0, + CXD56_AUDIO_CFG_MIC_DEV_ANALOG, + CXD56_AUDIO_CFG_MIC_DEV_DIGITAL, + CXD56_AUDIO_CFG_MIC_DEV_ANADIG +}; + +enum cxd56_audio_cfg_mic_bias_e +{ + CXD56_AUDIO_CFG_MIC_BIAS_20V = 0, + CXD56_AUDIO_CFG_MIC_BIAS_28V +}; + +enum cxd56_audio_cfg_xtal_e +{ + CXD56_AUDIO_CFG_XTAL_24_576MHZ = 0, + CXD56_AUDIO_CFG_XTAL_49_152MHZ +}; + +enum cxd56_audio_cfg_ds_e +{ + CXD56_AUDIO_CFG_DS_WEAKEST = 0, + CXD56_AUDIO_CFG_DS_WEAKER, + CXD56_AUDIO_CFG_DS_STRONGER, + CXD56_AUDIO_CFG_DS_STRONGEST +}; + +enum cxd56_audio_cfg_i2s_mode_e +{ + CXD56_AUDIO_CFG_I2S_MODE_MASTER = 0, + CXD56_AUDIO_CFG_I2S_MODE_SLAVE +}; + +enum cxd56_audio_cfg_i2s_format_e +{ + CXD56_AUDIO_CFG_I2S_FORMAT_NORMAL = 0, + CXD56_AUDIO_CFG_I2S_FORMAT_LEFT +}; + +enum cxd56_audio_cfg_i2s_bypass_e +{ + CXD56_AUDIO_CFG_I2S_BYPASS_DISABLE = 0, + CXD56_AUDIO_CFG_I2S_BYPASS_ENABLE +}; + +enum cxd56_audio_cfg_cic_in_sel_e +{ + CXD56_AUDIO_CFG_CIC_IN_SEL_NONE = 0, + CXD56_AUDIO_CFG_CIC_IN_SEL_CXD, + CXD56_AUDIO_CFG_CIC_IN_SEL_DMICIF +}; + +enum cxd56_audio_cfg_alc_spc_sel_e +{ + CXD56_AUDIO_CFG_ALCSPC_NONE = 0, + CXD56_AUDIO_CFG_ALCSPC_ALC, + CXD56_AUDIO_CFG_ALCSPC_SPC +}; + +#define CXD56_AUDIO_CFG_SPC_LIMIT_DEFAULT 0 +#define CXD56_AUDIO_CFG_ALC_TARGET_DEFAULT 0 +#define CXD56_AUDIO_CFG_ALC_KNEE_DEFAULT 0 + +enum cxd56_audio_cfg_dma_formatl_e +{ + CXD56_AUDIO_CFG_DMA_FORMAT_LR = 0, + CXD56_AUDIO_CFG_DMA_FORMAT_RL +}; + +enum cxd56_audio_cfg_hpadc_mic_bias_e +{ + CXD56_AUDIO_CFG_HPADC_MIC_BIAS_OFF = 0, + CXD56_AUDIO_CFG_HPADC_MIC_BIAS_ON +}; + +enum cxd56_audio_cfg_sp_spliton_e +{ + CXD56_AUDIO_CFG_SP_SPLITON_LONGEST = 0, + CXD56_AUDIO_CFG_SP_SPLITON_LONG, + CXD56_AUDIO_CFG_SP_SPLITON_SHORT, + CXD56_AUDIO_CFG_SP_SPLITON_SHORTEST +}; + +/* Mic bias voltage select */ + +#if defined(CONFIG_CXD56_AUDIO_MICBIAS_20V) +# define CXD56_AUDIO_CFG_MIC_BIAS CXD56_AUDIO_CFG_MIC_BIAS_20V +#else +# define CXD56_AUDIO_CFG_MIC_BIAS CXD56_AUDIO_CFG_MIC_BIAS_28V +#endif + +/* Master clock select */ + +#if defined(CONFIG_CXD56_AUDIO_XTAL_SEL_49_152MHZ) +# define CXD56_AUDIO_CFG_MCLK CXD56_AUDIO_CFG_XTAL_49_152MHZ +#else +# define CXD56_AUDIO_CFG_MCLK CXD56_AUDIO_CFG_XTAL_24_576MHZ +#endif + +/* Mic select */ + +#define CXD56_AUDIO_CFG_MIC CONFIG_CXD56_AUDIO_MIC_CHANNEL_SEL + +/* Drive strength of global pin output-A */ + +#if defined(CONFIG_CXD56_AUDIO_GPO_A_WEAKEST) +# define CXD56_AUDIO_CFG_GPO_A_DS CXD56_AUDIO_CFG_DS_WEAKEST +#elif defined(CONFIG_CXD56_AUDIO_GPO_A_WEAKER) +# define CXD56_AUDIO_CFG_GPO_A_DS CXD56_AUDIO_CFG_DS_WEAKER +#elif defined(CONFIG_CXD56_AUDIO_GPO_A_STRONGER) +# define CXD56_AUDIO_CFG_GPO_A_DS CXD56_AUDIO_CFG_DS_STRONGER +#else +# define CXD56_AUDIO_CFG_GPO_A_DS CXD56_AUDIO_CFG_DS_STRONGEST +#endif + +/* Drive strength of D/A converted data */ + +#if defined(CONFIG_CXD56_AUDIO_DA_DATA_WEAKEST) +# define CXD56_AUDIO_CFG_DA_DS CXD56_AUDIO_CFG_DS_WEAKEST +#elif defined(CONFIG_CXD56_AUDIO_DA_DATA_WEAKER) +# define CXD56_AUDIO_CFG_DS_DS CXD56_AUDIO_CFG_DS_WEAKER +#elif defined(CONFIG_CXD56_AUDIO_DA_DATA_STRONGER) +# define CXD56_AUDIO_CFG_DA_DS CXD56_AUDIO_CFG_DS_STRONGER +#else +# define CXD56_AUDIO_CFG_DA_DS CXD56_AUDIO_CFG_DS_STRONGEST +#endif + +/* Drive strength of digital mic clock */ + +#if defined(CONFIG_CXD56_AUDIO_CLKOUT_DMIC_WEAKEST) +# define CXD56_AUDIO_CFG_DMIC_CLK_DS CXD56_AUDIO_CFG_DS_WEAKEST +#elif defined(CONFIG_CXD56_AUDIO_CLKOUT_DMIC_WEAKER) +# define CXD56_AUDIO_CFG_DMIC_CLK_DS CXD56_AUDIO_CFG_DS_WEAKER +#elif defined(CONFIG_CXD56_AUDIO_CLKOUT_DMIC_STRONGER) +# define CXD56_AUDIO_CFG_DMIC_CLK_DS CXD56_AUDIO_CFG_DS_STRONGER +#else +# define CXD56_AUDIO_CFG_DMIC_CLK_DS CXD56_AUDIO_CFG_DS_STRONGEST +#endif + +/* Drive strength of master clock */ + +#if defined(CONFIG_CXD56_AUDIO_MCLKOUT_WEAKEST) +# define CXD56_AUDIO_CFG_MCLKOUT_DS CXD56_AUDIO_CFG_DS_WEAKEST +#elif defined(CONFIG_CXD56_AUDIO_MCLKOUT_WEAKER) +# define CXD56_AUDIO_CFG_MCLKOUT_DS CXD56_AUDIO_CFG_DS_WEAKER +#elif defined(CONFIG_CXD56_AUDIO_MCLKOUT_STRONGER) +# define CXD56_AUDIO_CFG_MCLKOUT_DS CXD56_AUDIO_CFG_DS_STRONGER +#else +# define CXD56_AUDIO_CFG_MCLKOUT_DS CXD56_AUDIO_CFG_DS_STRONGEST +#endif + +/* I2S mode of I2S1 */ + +#if defined(CONFIG_CXD56_AUDIO_I2S_DEVICE_1_MASTER) +# define CXD56_AUDIO_CFG_I2S1_MODE CXD56_AUDIO_CFG_I2S_MODE_MASTER +#else +# define CXD56_AUDIO_CFG_I2S1_MODE CXD56_AUDIO_CFG_I2S_MODE_SLAVE +#endif + +/* I2S format of I2S1 */ + +#if defined(CONFIG_CXD56_AUDIO_I2S_FORMAT_1_LEFT) +# define CXD56_AUDIO_CFG_I2S1_FORMAT CXD56_AUDIO_CFG_I2S_FORMAT_LEFT +#else +# define CXD56_AUDIO_CFG_I2S1_FORMAT CXD56_AUDIO_CFG_I2S_FORMAT_NORMAL +#endif + +/* I2S bypass mode of I2S1 */ + +#if defined(CONFIG_CXD56_AUDIO_I2S_BYPASS_MODE_1_ENABLE) +# define CXD56_AUDIO_CFG_I2S1_BYPASS CXD56_AUDIO_CFG_I2S_BYPASS_ENABLE +#else +# define CXD56_AUDIO_CFG_I2S1_BYPASS CXD56_AUDIO_CFG_I2S_BYPASS_DISABLE +#endif + +/* I2S data rate of I2S1 */ + +#if defined(CONFIG_CXD56_I2S0) +# define CXD56_AUDIO_CFG_I2S1_DATA_RATE CONFIG_CXD56_AUDIO_I2S_RATE_1 +#else +# define CXD56_AUDIO_CFG_I2S1_DATA_RATE 0 +#endif + +/* I2S mode of I2S2 */ + +#if defined(CONFIG_CXD56_AUDIO_I2S_DEVICE_2_MASTER) +# define CXD56_AUDIO_CFG_I2S2_MODE CXD56_AUDIO_CFG_I2S_MODE_MASTER +#else +# define CXD56_AUDIO_CFG_I2S2_MODE CXD56_AUDIO_CFG_I2S_MODE_SLAVE +#endif + +/* I2S format of I2S2 */ + +#if defined(CONFIG_CXD56_AUDIO_I2S_FORMAT_2_LEFT) +# define CXD56_AUDIO_CFG_I2S2_FORMAT CXD56_AUDIO_CFG_I2S_FORMAT_LEFT +#else +# define CXD56_AUDIO_CFG_I2S2_FORMAT CXD56_AUDIO_CFG_I2S_FORMAT_NORMAL +#endif + +/* I2S bypass mode of I2S2 */ + +#if defined(CONFIG_CXD56_AUDIO_I2S_BYPASS_MODE_2_ENABLE) +# define CXD56_AUDIO_CFG_I2S2_BYPASS CXD56_AUDIO_CFG_I2S_BYPASS_ENABLE +#else +# define CXD56_AUDIO_CFG_I2S2_BYPASS CXD56_AUDIO_CFG_I2S_BYPASS_DISABLE +#endif + +/* I2S data rate of I2S2 */ + +#if defined(CONFIG_CXD56_I2S1) +# define CXD56_AUDIO_CFG_I2S2_DATA_RATE CONFIG_CXD56_AUDIO_I2S_RATE_2 +#else +# define CXD56_AUDIO_CFG_I2S2_DATA_RATE 0 +#endif + +/* CIC filter input path */ + +#if defined(CONFIG_CXD56_AUDIO_CIC_IN_SEL_CXD) +# define CXD56_AUDIO_CFG_CIC_IN CXD56_AUDIO_CFG_CIC_IN_SEL_CXD +#elif defined (CONFIG_CXD56_AUDIO_CIC_IN_SEL_DMIC) +# define CXD56_AUDIO_CFG_CIC_IN CXD56_AUDIO_CFG_CIC_IN_SEL_DMICIF +#else +# define CXD56_AUDIO_CFG_CIC_IN CXD56_AUDIO_CFG_CIC_IN_SEL_NONE +#endif + +/* Wait time of mic boot */ + +#define CXD56_AUDIO_MIC_BOOT_WAIT CONFIG_CXD56_AUDIO_MIC_BOOT_WAIT + +/* ALC and SPC filter select */ + +#if defined(CONFIG_CXD56_AUDIO_ALC_SPC_SEL_OFF) +# define CXD56_AUDIO_CFG_ALCSPC CXD56_AUDIO_CFG_ALCSPC_NONE +#elif defined (CONFIG_CXD56_AUDIO_ALC_SPC_SEL_ALC) +# define CXD56_AUDIO_CFG_ALCSPC CXD56_AUDIO_CFG_ALCSPC_ALC +#else +# define CXD56_AUDIO_CFG_ALCSPC CXD56_AUDIO_CFG_ALCSPC_SPC +#endif + +/* SPC limit level */ + +#if defined(CONFIG_CXD56_AUDIO_ALC_SPC_SEL_SPC) +# define CXD56_AUDIO_CFG_SPC_LIMIT CONFIG_CXD56_AUDIO_SPC_LIMIT +#else +# define CXD56_AUDIO_CFG_SPC_LIMIT CXD56_AUDIO_CFG_SPC_LIMIT_DEFAULT +#endif + +/* ALC target level */ + +#if defined(CONFIG_CXD56_AUDIO_ALC_SPC_SEL_ALC) +# define CXD56_AUDIO_CFG_ALC_TARGET CONFIG_CXD56_AUDIO_ALC_TARGET +#else +# define CXD56_AUDIO_CFG_ALC_TARGET CXD56_AUDIO_CFG_ALC_TARGET_DEFAULT +#endif + +/* ALC knee point */ + +#if defined(CONFIG_CXD56_AUDIO_ALC_SPC_SEL_ALC) +# define CXD56_AUDIO_CFG_ALC_KNEE CONFIG_CXD56_AUDIO_ALC_KNEE +#else +# define CXD56_AUDIO_CFG_ALC_KNEE CXD56_AUDIO_CFG_ALC_KNEE_DEFAULT +#endif + +/* DMA format */ + +#if defined(CONFIG_CXD56_AUDIO_DMA_DATA_FORMAT_LR) +# define CXD56_AUDIO_CFG_DMA_FORMAT CXD56_AUDIO_CFG_DMA_FORMAT_LR +#else +# define CXD56_AUDIO_CFG_DMA_FORMAT CXD56_AUDIO_CFG_DMA_FORMAT_RL +#endif + +/* Mic bias for HPADC */ + +#if defined(CONFIG_CXD56_AUDIO_HPADC_MIC_BIAS_ON) +# define CXD56_AUDIO_CFG_HPADC_MIC_BIAS CXD56_AUDIO_CFG_HPADC_MIC_BIAS_ON +#else +# define CXD56_AUDIO_CFG_HPADC_MIC_BIAS CXD56_AUDIO_CFG_HPADC_MIC_BIAS_OFF +#endif + +/* Speaker time split on drive */ + +#if defined(CONFIG_CXD56_AUDIO_SP_SPLIT_LONGEST) +# define CXD56_AUDIO_CFG_SP_SPLIT_ON CXD56_AUDIO_CFG_SP_SPLITON_LONGEST +#elif defined(CONFIG_CXD56_AUDIO_SP_SPLIT_LONG) +# define CXD56_AUDIO_CFG_SP_SPLIT_ON CXD56_AUDIO_CFG_SP_SPLITON_LONG +#elif defined(CONFIG_CXD56_AUDIO_SP_SPLIT_SHORT) +# define CXD56_AUDIO_CFG_SP_SPLIT_ON CXD56_AUDIO_CFG_SP_SPLITON_SHORT +#else +# define CXD56_AUDIO_CFG_SP_SPLIT_ON CXD56_AUDIO_CFG_SP_SPLITON_SHORTEST +#endif + +/* Speaker drive mode */ + +#if defined(CONFIG_CXD56_AUDIO_SP_DRV_LINEOUT) +# define CXD56_AUDIO_CFG_SP_DRIVER CXD56_AUDIO_SP_DRV_LINEOUT +#elif defined(CONFIG_CXD56_AUDIO_SP_DRV_1DRIVERT) +# define CXD56_AUDIO_CFG_SP_DRIVER CXD56_AUDIO_SP_DRV_1DRIVER +#elif defined(CONFIG_CXD56_AUDIO_SP_DRV_2DRIVERT) +# define CXD56_AUDIO_CFG_SP_DRIVER CXD56_AUDIO_SP_DRV_2DRIVER +#else +# define CXD56_AUDIO_CFG_SP_DRIVER CXD56_AUDIO_SP_DRV_4DRIVER +#endif + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void cxd56_audio_config_init(void); +uint8_t cxd56_audio_config_get_micmode(void); +uint8_t cxd56_audio_config_get_micdev(void); +uint8_t cxd56_audio_config_get_micnum(void); +void cxd56_audio_config_set_spdriver(cxd56_audio_sp_drv_t sp_driver); +cxd56_audio_sp_drv_t cxd56_audio_config_get_spdriver(void); +void cxd56_audio_config_set_clkmode(cxd56_audio_clkmode_t mode); +cxd56_audio_clkmode_t cxd56_audio_config_get_clkmode(void); +void cxd56_audio_config_set_micmap(uint32_t map); +uint32_t cxd56_audio_config_get_micmap(void); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_CONFIG_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_digital.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_digital.c new file mode 100644 index 00000000000..37b1f0f5b57 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_digital.c @@ -0,0 +1,115 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_digital.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_ac_reg.h" +#include "cxd56_audio_bca_reg.h" +#include "cxd56_audio_digital.h" + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/*************************************************************************** + * Private Data + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Private Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Functions + ****************************************************************************/ + +void cxd56_audio_digital_poweron(void) +{ +#if defined(CONFIG_CXD56_I2S0) || defined(CONFIG_CXD56_I2S1) + cxd56_audio_clkmode_t clk_mode = cxd56_audio_config_get_clkmode(); + + /* Clear interrupt status of bck_err. */ + + cxd56_audio_bca_reg_clear_bck_err_int(); + + /* PowerON i2s. */ + + cxd56_audio_ac_reg_poweron_i2s(clk_mode); +#endif /* defined(CONFIG_CXD56_I2S0) || defined(CONFIG_CXD56_I2S1) */ +} + +void cxd56_audio_digital_enable(void) +{ +#if defined(CONFIG_CXD56_I2S0) || defined(CONFIG_CXD56_I2S1) + +#ifdef CONFIG_CXD56_I2S0 + /* Enable I2S data input and output of SRC1 */ + + cxd56_audio_ac_reg_enable_i2s_src1(); +#endif /* CONFIG_CXD56_I2S0 */ + +#ifdef CONFIG_CXD56_I2S1 + /* Enable I2S data input and output of SRC2 */ + + cxd56_audio_ac_reg_enable_i2s_src2(); +#endif /* CONFIG_CXD56_I2S1 */ + + if ((CXD56_AUDIO_CFG_I2S1_MODE == CXD56_AUDIO_CFG_I2S_MODE_MASTER) || + (CXD56_AUDIO_CFG_I2S2_MODE == CXD56_AUDIO_CFG_I2S_MODE_MASTER)) + { + /* Enable BCK, LRCK output. */ + + cxd56_audio_ac_reg_enable_i2s_bcklrckout(); + } + else + { + cxd56_audio_ac_reg_disable_i2s_bcklrckout(); + } +#endif /* defined(CONFIG_CXD56_I2S0) || defined(CONFIG_CXD56_I2S1) */ +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_digital.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_digital.h new file mode 100644 index 00000000000..874750a0226 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_digital.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_digital.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_DIGITAL_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_DIGITAL_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void cxd56_audio_digital_poweron(void); +void cxd56_audio_digital_enable(void); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_DIGITAL_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_dma.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_dma.c new file mode 100644 index 00000000000..357a0999149 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_dma.c @@ -0,0 +1,707 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_dma.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_dma.h" +#include "cxd56_audio_mic.h" +#include "cxd56_audio_ac_reg.h" +#include "cxd56_audio_bca_reg.h" + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register type. */ + +enum audio_irq_reg_type_e +{ + INT_EN1_REG = 0, + INT_POL_REG, + INT_IRQ1_REG +}; + +/* INT_EN1 */ +#define CXD56_INTC_BASE 0xe0045000 +#define INT_EN1_REG_ADDR (CXD56_INTC_BASE + 0x10 + 3 * 4) +#define INT_EN1_BIT_AU0 6 +#define INT_EN1_BIT_AU1 7 +#define INT_EN1_BIT_AU2 8 +#define INT_EN1_BIT_AU3 9 + +/* INT_POL */ + +#define INT_POL_REG (CXD56_INTC_BASE + 0x20 + 3 * 4) +#define INT_POL_BIT_AU0 6 +#define INT_POL_BIT_AU1 7 +#define INT_POL_BIT_AU2 8 +#define INT_POL_BIT_AU3 9 + +/* INT_IRQ1 */ + +#define INT_IRQ1_REG_ADDR (CXD56_INTC_BASE + 0x30 + 3 * 4) +#define INT_IRQ1_BIT_AU0 6 +#define INT_IRQ1_BIT_AU1 7 +#define INT_IRQ1_BIT_AU2 8 +#define INT_IRQ1_BIT_AU3 9 + +#define DMA_HANDLE_MAX_NUM (CXD56_AUDIO_DMAC_I2S1_DOWN + 1) + +#define DMA_TIMEOUT_CNT 10000 +#define DMA_START_RETRY_CNT 10 +#define DMA_SMP_WAIT_HIRES 10 /* usec per sample. */ +#define DMA_SMP_WAIT_NORMALT 40 /* usec per sample. */ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/*************************************************************************** + * Private Data + ****************************************************************************/ + +static uint8_t g_dma_act_status = 0; +static cxd56_audio_dma_cb_t g_dma_cb[DMA_HANDLE_MAX_NUM]; + +static bool s_work_arroud_dmac[DMA_HANDLE_MAX_NUM] = +{ + true, + true, + true +}; + +/*************************************************************************** + * Private Macro + ****************************************************************************/ + +#define SET_DMA_ACT(_path_) g_dma_act_status |= (1 << _path_) +#define CLR_DMA_ACT(_path_) g_dma_act_status &= ~(1 << _path_) +#define IS_DMA_ACT(_path_) ((g_dma_act_status & (1 << _path_)) != 0) + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Private Functions + ****************************************************************************/ + +static uint32_t read_int_reg(uint32_t reg) +{ + volatile uint32_t *addr; + uint32_t data = 0; + + if (reg == INT_EN1_REG) + { + addr = (volatile uint32_t *)INT_EN1_REG_ADDR; + } + else if (reg == INT_IRQ1_REG) + { + addr = (volatile uint32_t *)INT_IRQ1_REG_ADDR; + } + else + { + addr = (volatile uint32_t *)INT_POL_REG; + } + + data = *addr; + + return data; +} + +static uint32_t write_int_reg(uint32_t reg, uint32_t data) +{ + volatile uint32_t *addr; + + if (reg == INT_EN1_REG) + { + addr = (volatile uint32_t *)INT_EN1_REG_ADDR; + *addr = data; + } + + return 0; +} + +static CXD56_AUDIO_ECODE get_dma_handle(cxd56_audio_dma_path_t path, + FAR cxd56_audio_dma_t *handle) +{ + switch (path) + { + case CXD56_AUDIO_DMA_PATH_MIC_TO_MEM: + *handle = CXD56_AUDIO_DMAC_MIC; + break; + + case CXD56_AUDIO_DMA_PATH_MEM_TO_BUSIF1: + *handle = CXD56_AUDIO_DMAC_I2S0_DOWN; + break; + + case CXD56_AUDIO_DMA_PATH_MEM_TO_BUSIF2: + *handle = CXD56_AUDIO_DMAC_I2S1_DOWN; + break; + + default: + return CXD56_AUDIO_ECODE_DMA_PATH_INV; + } + return CXD56_AUDIO_ECODE_OK; +} + +static CXD56_AUDIO_ECODE get_dma_path(cxd56_audio_dma_t handle, + FAR cxd56_audio_dma_path_t *path) +{ + switch (handle) + { + case CXD56_AUDIO_DMAC_MIC: + *path = CXD56_AUDIO_DMA_PATH_MIC_TO_MEM; + break; + + case CXD56_AUDIO_DMAC_I2S0_DOWN: + *path = CXD56_AUDIO_DMA_PATH_MEM_TO_BUSIF1; + break; + + case CXD56_AUDIO_DMAC_I2S1_DOWN: + *path = CXD56_AUDIO_DMA_PATH_MEM_TO_BUSIF2; + break; + + default: + return CXD56_AUDIO_ECODE_DMA_HANDLE_INV; + } + return CXD56_AUDIO_ECODE_OK; +} + +static CXD56_AUDIO_ECODE start_dma(cxd56_audio_dma_t handle) +{ + cxd56_audio_bca_reg_start_dma(handle, false); + + return CXD56_AUDIO_ECODE_OK; +} + +static CXD56_AUDIO_ECODE exec_dma_ch_sync_workaround( + cxd56_audio_dma_t handle) +{ + int timeout_cnt = 0; + int retry_cnt; + + cxd56_audio_clkmode_t clk_mode = cxd56_audio_config_get_clkmode(); + + /* Execute out-of-sync workaround. + * 1. Clear smp interrupt status + * 2. Read until smp interrupt state is true + * 3. Reset channel select setting + * 4. Start dma transfer + * It needs to be less than 9 us by the processing so far. + * If it does not fit below 9 us, err_int is generated, so retry. + */ + + /* Mask dma done interrupt. */ + + cxd56_audio_bca_reg_mask_done_int(handle); + + for (retry_cnt = 0; retry_cnt < DMA_START_RETRY_CNT; retry_cnt++) + { + /* Clear interrupt status */ + + cxd56_audio_bca_reg_clear_err_int(handle); + cxd56_audio_bca_reg_clear_smp_int(handle); + + /* Lock interrupt */ + + up_irq_disable(); + sched_lock(); + + /* Wait smp interrupt. */ + + for (timeout_cnt = 0; timeout_cnt < DMA_TIMEOUT_CNT; timeout_cnt++) + { + if (cxd56_audio_bca_reg_is_smp_int(handle)) + { + break; + } + } + if (timeout_cnt == DMA_TIMEOUT_CNT) + { + return CXD56_AUDIO_ECODE_DMA_SMP_TIMEOUT; + } + + /* Reset Channel select. */ + + cxd56_audio_bca_reg_reset_chsel(handle); + + /* Start dma. */ + + cxd56_audio_bca_reg_start_dma(handle, false); + + /* Unlock interrupt */ + + sched_unlock(); + up_irq_enable(); + + /* Wait for 1sample tramsfer. */ + + if (clk_mode == CXD56_AUDIO_CLKMODE_HIRES) + { + up_udelay(DMA_SMP_WAIT_HIRES); + } + else + { + up_udelay(DMA_SMP_WAIT_NORMALT); + } + + /* Check whether an error interrupt has occurred. */ + + if (cxd56_audio_bca_reg_is_err_int(handle)) + { + cxd56_audio_bca_reg_stop_dma(handle); + cxd56_audio_bca_reg_clear_err_int(handle); + + for (timeout_cnt = 0; timeout_cnt < DMA_TIMEOUT_CNT; timeout_cnt++) + { + if (DMA_MSTATE_BUF_EMPTY == + cxd56_audio_bca_reg_get_mon_state_buf(handle)) + { + if (cxd56_audio_bca_reg_is_done_int(handle)) + { + cxd56_audio_bca_reg_clear_done_int(handle); + break; + } + } + } + } + else + { + break; + } + } + + /* Unmask dma done interrupt. */ + + cxd56_audio_bca_reg_unmask_done_int(handle); + + return CXD56_AUDIO_ECODE_OK; +} + +static CXD56_AUDIO_ECODE start_dma_workaround(cxd56_audio_dma_t handle) +{ + /* There are two workarounds. + * One is a workaround in which the error interrupt of + * dma is incorrectly generated. + * The other is a workaround for the problem that the channel + * is out of sync. + * Because both require processing at the beginning of dma, + * call out workaround with out-of-sync from the workaround + * for interrupt error. + */ + + /* Execute error interrupt workaround. + * 1. Mask dma error interrupt + * 2. Wait 77 cycle after dma transfer starts + * 3. Clear interrupt status + * 4. Unmask dma error interrupt + */ + + cxd56_audio_bca_reg_mask_err_int(handle); + + /* Transfer start and wait processing of dma is done + * in out-of-sync workaround. + */ + + CXD56_AUDIO_ECODE ret = exec_dma_ch_sync_workaround(handle); + + cxd56_audio_bca_reg_clear_err_int(handle); + cxd56_audio_bca_reg_unmask_err_int(handle); + + return ret; +} + +/*************************************************************************** + * Public Functions + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_dma_get_handle(cxd56_audio_dma_path_t path, + FAR cxd56_audio_dma_t *handle) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Check error of argument */ + + if (handle == NULL) + { + return CXD56_AUDIO_ECODE_DMA_HANDLE_NULL; + } + + /* Check duplicate order */ + + if (IS_DMA_ACT(path)) + { + return CXD56_AUDIO_ECODE_DMA_PATH_DUP; + } + + ret = get_dma_handle(path, handle); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + SET_DMA_ACT(path); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_dma_free_handle(FAR cxd56_audio_dma_t handle) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + cxd56_audio_dma_path_t path; + + ret = get_dma_path(handle, &path); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + CLR_DMA_ACT(path); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_dma_init(cxd56_audio_dma_t handle, + cxd56_audio_samp_fmt_t fmt, + FAR uint8_t *ch_num) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + uint32_t ch_setting; + + cxd56_audio_ac_reg_enable_dma(); + + if (handle == CXD56_AUDIO_DMAC_MIC) + { + ret = cxd56_audio_mic_set_seloutch(*ch_num, fmt); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + } + else + { + /* Set Stereo channel number. */ + + *ch_num = 2; + } + + if (fmt == CXD56_AUDIO_SAMP_FMT_24) + { + cxd56_audio_bca_reg_en_fmt24(handle, *ch_num); + } + else + { + cxd56_audio_bca_reg_en_fmt16(handle, *ch_num); + } + + /* Clear interrupt state. */ + + cxd56_audio_bca_reg_clear_done_int(handle); + cxd56_audio_bca_reg_clear_err_int(handle); + cxd56_audio_bca_reg_clear_cmb_int(handle); + + /* Enable interrupt. */ + + cxd56_audio_bca_reg_unmask_done_int(handle); + + /* cxd56_audio_bca_reg_mask_done_int(handle); TODO: polling */ + + /* Enable interrupt. */ + + cxd56_audio_bca_reg_unmask_err_int(handle); + cxd56_audio_bca_reg_unmask_cmb_int(handle); + cxd56_audio_bca_reg_unmask_bus_int(handle); + + /* Check channel setting. */ + + ch_setting = cxd56_audio_bca_reg_get_mon_state_err(handle); + switch (ch_setting) + { + case DMA_MSTATE_ERR_NO_ENABLE_CH: + return CXD56_AUDIO_ECODE_DMA_CH_NO_ENABLE; + + case DMA_MSTATE_ERR_CH1_4_INVALID: + return CXD56_AUDIO_ECODE_DMA_CH1_4_INV; + + case DMA_MSTATE_ERR_CH5_8_INVALID: + return CXD56_AUDIO_ECODE_DMA_CH5_8_INV; + + default: + break; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_dma_set_cb(cxd56_audio_dma_t handle, + FAR cxd56_audio_dma_cb_t cb) +{ + g_dma_cb[handle] = cb; + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_dma_get_mstate(cxd56_audio_dma_t handle, + FAR cxd56_audio_dma_mstate_t *state) +{ + cxd56_audio_bca_reg_get_dma_mstate(handle, state); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_dma_en_dmaint(void) +{ + volatile uint32_t int_en; + + int_en = read_int_reg(INT_EN1_REG); + + int_en |= (1 << INT_EN1_BIT_AU0); + int_en |= (1 << INT_EN1_BIT_AU1); + int_en |= (1 << INT_EN1_BIT_AU2); + int_en |= (1 << INT_EN1_BIT_AU3); + + write_int_reg(INT_EN1_REG, int_en); + + /* Enalbe bus error interrupt. */ + + cxd56_audio_bca_reg_en_bus_err_int(); + + return CXD56_AUDIO_ECODE_OK; + +} + +CXD56_AUDIO_ECODE cxd56_audio_dma_dis_dmaint(void) +{ + volatile uint32_t int_en; + + int_en = read_int_reg(INT_EN1_REG); + + int_en &= ~(1 << INT_EN1_BIT_AU0); + int_en &= ~(1 << INT_EN1_BIT_AU1); + int_en &= ~(1 << INT_EN1_BIT_AU2); + int_en &= ~(1 << INT_EN1_BIT_AU3); + + write_int_reg(INT_EN1_REG, int_en); + + /* Disalbe bus error interrupt. */ + + cxd56_audio_bca_reg_dis_bus_err_int(); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_dma_start(cxd56_audio_dma_t handle, + uint32_t addr, + uint32_t sample) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + if (DMA_CMD_FIFO_NOT_FULL != cxd56_audio_bca_reg_get_dma_state(handle)) + { + return CXD56_AUDIO_ECODE_DMA_BUSY; + } + + cxd56_audio_bca_reg_set_start_addr(handle, addr); + cxd56_audio_bca_reg_set_sample_no(handle, sample); + + if (s_work_arroud_dmac[handle]) + { + s_work_arroud_dmac[handle] = false; + ret = start_dma_workaround(handle); + } + else + { + ret = start_dma(handle); + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_dma_stop(cxd56_audio_dma_t handle) +{ + cxd56_audio_bca_reg_stop_dma(handle); + s_work_arroud_dmac[handle] = true; + + return CXD56_AUDIO_ECODE_OK; +} + +void CXD56_audio_dma_int_handler(void) +{ + uint32_t int_irq = read_int_reg(INT_IRQ1_REG); + uint32_t int_ac = cxd56_audio_bca_reg_get_dma_done_state_mic(); + uint32_t int_i2s = cxd56_audio_bca_reg_get_dma_done_state_i2s1(); + uint32_t int_i2s2 = cxd56_audio_bca_reg_get_dma_done_state_i2s2(); + + /* AUDIO_INT_AC : check interruption from mic */ + + if ((int_irq & (1 << INT_IRQ1_BIT_AU0)) && (int_ac != 0)) + { + /* Clear interrupt. */ + + cxd56_audio_bca_reg_clear_dma_done_state_mic(int_ac); + + /* Check done complete state. */ + + if (int_ac & DMA_STATE_BIT_AC_DONE) + { + (*g_dma_cb[CXD56_AUDIO_DMAC_MIC])(CXD56_AUDIO_DMAC_MIC, + CXD56_AUDIO_ECODE_DMA_CMPLT); + } + + /* Check transfer err state. */ + + if (int_ac & DMA_STATE_BIT_AC_ERR) + { + cxd56_audio_bca_reg_mask_err_int(CXD56_AUDIO_DMAC_MIC); + + cxd56_audio_bca_reg_clear_err_int(CXD56_AUDIO_DMAC_MIC); + + (*g_dma_cb[CXD56_AUDIO_DMAC_MIC])(CXD56_AUDIO_DMAC_MIC, + CXD56_AUDIO_ECODE_DMA_TRANS); + } + + /* Check bus err state. */ + + if (int_ac & DMA_STATE_BIT_AC_CMB) + { + cxd56_audio_bca_reg_mask_cmb_int(CXD56_AUDIO_DMAC_MIC); + + cxd56_audio_bca_reg_clear_cmb_int(CXD56_AUDIO_DMAC_MIC); + + (*g_dma_cb[CXD56_AUDIO_DMAC_MIC])(CXD56_AUDIO_DMAC_MIC, + CXD56_AUDIO_ECODE_DMA_CMB); + } + } + + /* AUDIO_INT_I2S1 : check interruption from I2S-1 */ + + if ((int_irq & (1 << INT_IRQ1_BIT_AU1)) && (int_i2s != 0)) + { + /* Clear interrupt. */ + + cxd56_audio_bca_reg_clear_dma_done_state_i2s1(int_i2s); + + /* Check done complete state. */ + + if (int_i2s & DMA_STATE_BIT_I2S_OUT_DONE) + { + (*g_dma_cb[CXD56_AUDIO_DMAC_I2S0_DOWN])(CXD56_AUDIO_DMAC_I2S0_DOWN, + CXD56_AUDIO_ECODE_DMA_CMPLT); + } + + /* Check transfer err state. */ + + if (int_i2s & DMA_STATE_BIT_I2S_OUT_ERR) + { + cxd56_audio_bca_reg_mask_err_int(CXD56_AUDIO_DMAC_I2S0_DOWN); + + cxd56_audio_bca_reg_clear_err_int(CXD56_AUDIO_DMAC_I2S0_DOWN); + + (*g_dma_cb[CXD56_AUDIO_DMAC_I2S0_DOWN])(CXD56_AUDIO_DMAC_I2S0_DOWN, + CXD56_AUDIO_ECODE_DMA_TRANS); + } + + /* Check bus err state. */ + + if (int_i2s & DMA_STATE_BIT_I2S_CMB) + { + cxd56_audio_bca_reg_mask_cmb_int(CXD56_AUDIO_DMAC_I2S0_DOWN); + + cxd56_audio_bca_reg_clear_cmb_int(CXD56_AUDIO_DMAC_I2S0_DOWN); + + (*g_dma_cb[CXD56_AUDIO_DMAC_I2S0_DOWN])(CXD56_AUDIO_DMAC_I2S0_DOWN, + CXD56_AUDIO_ECODE_DMA_CMB); + } + } + + /* AUDIO_INT_I2S2 : check interruption from I2S-2 */ + + if ((int_irq & (1 << INT_IRQ1_BIT_AU2)) && (int_i2s2 != 0)) + { + /* Clear interrupt. */ + + cxd56_audio_bca_reg_clear_dma_done_state_i2s2(int_i2s2); + + /* Check done complete state. */ + + if (int_i2s2 & DMA_STATE_BIT_I2S_OUT_DONE) + { + (*g_dma_cb[CXD56_AUDIO_DMAC_I2S1_DOWN])(CXD56_AUDIO_DMAC_I2S1_DOWN, + CXD56_AUDIO_ECODE_DMA_CMPLT); + } + + /* Check transfer err state. */ + + if (int_i2s2 & DMA_STATE_BIT_I2S_OUT_ERR) + { + cxd56_audio_bca_reg_mask_err_int(CXD56_AUDIO_DMAC_I2S1_DOWN); + + cxd56_audio_bca_reg_clear_err_int(CXD56_AUDIO_DMAC_I2S1_DOWN); + + (*g_dma_cb[CXD56_AUDIO_DMAC_I2S1_DOWN])(CXD56_AUDIO_DMAC_I2S1_DOWN, + CXD56_AUDIO_ECODE_DMA_TRANS); + } + + /* Check bus err state. */ + + if (int_i2s2 & DMA_STATE_BIT_I2S_CMB) + { + cxd56_audio_bca_reg_mask_cmb_int(CXD56_AUDIO_DMAC_I2S1_DOWN); + + cxd56_audio_bca_reg_clear_cmb_int(CXD56_AUDIO_DMAC_I2S1_DOWN); + + (*g_dma_cb[CXD56_AUDIO_DMAC_I2S1_DOWN])(CXD56_AUDIO_DMAC_I2S1_DOWN, + CXD56_AUDIO_ECODE_DMA_CMB); + } + } + + if (int_irq & (1 << INT_IRQ1_BIT_AU3)) + { + uint32_t int_au = cxd56_audio_bca_reg_get_int_status(); + + if (int_au != 0) + { + cxd56_audio_bca_reg_clear_int_status(int_au); + } + } +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_dma.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_dma.h new file mode 100644 index 00000000000..25859210852 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_dma.h @@ -0,0 +1,81 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_dma.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_DMA_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_DMA_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_dma_get_handle(cxd56_audio_dma_path_t path, + FAR cxd56_audio_dma_t *handle); +CXD56_AUDIO_ECODE cxd56_audio_dma_free_handle(cxd56_audio_dma_t handle); +CXD56_AUDIO_ECODE cxd56_audio_dma_init(cxd56_audio_dma_t handle, + cxd56_audio_samp_fmt_t fmt, + FAR uint8_t *ch_num); +CXD56_AUDIO_ECODE cxd56_audio_dma_set_cb(cxd56_audio_dma_t handle, + FAR cxd56_audio_dma_cb_t cb); +CXD56_AUDIO_ECODE cxd56_audio_dma_get_mstate(cxd56_audio_dma_t handle, + FAR cxd56_audio_dma_mstate_t *state); +CXD56_AUDIO_ECODE cxd56_audio_dma_en_dmaint(void); +CXD56_AUDIO_ECODE cxd56_audio_dma_dis_dmaint(void); +CXD56_AUDIO_ECODE cxd56_audio_dma_start(cxd56_audio_dma_t handle, + uint32_t addr, + uint32_t sample); +CXD56_AUDIO_ECODE cxd56_audio_dma_stop(cxd56_audio_dma_t handle); +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_DMA_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_filter.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_filter.c new file mode 100644 index 00000000000..7b5c5f722f2 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_filter.c @@ -0,0 +1,140 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_filter.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_filter.h" +#include "cxd56_audio_ac_reg.h" + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/*************************************************************************** + * Private Data + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Private Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Functions + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_filter_set_cstereo(bool en, + bool sign_inv, + int16_t vol) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + if (en) + { + ret = cxd56_audio_ac_reg_enable_cstereo(sign_inv, vol); + } + else + { + cxd56_audio_ac_reg_disable_cstereo(); + } + + return ret; +} + +void cxd56_audio_filter_poweron_dnc(void) +{ + cxd56_audio_ac_reg_poweron_dnc(); +} + +void cxd56_audio_filter_poweroff_dnc(void) +{ + cxd56_audio_ac_reg_poweroff_dnc(); +} + +void cxd56_audio_filter_set_dnc(cxd56_audio_dnc_id_t id, + bool en, + FAR cxd56_audio_dnc_bin_t *bin) +{ + /* Desable DNC. */ + + cxd56_audio_ac_reg_disable_dnc(id); + + /* Set binary data to SRAM. */ + + if (bin != NULL) + { + cxd56_audio_ac_reg_set_dncram(id, bin); + } + + /* Enable DNC. */ + + if (en) + { + cxd56_audio_ac_reg_enable_dnc(id); + } +} + +void cxd56_audio_filter_set_deq(bool en, + FAR cxd56_audio_deq_coef_t *deq) +{ + /* Disable DEQ. */ + + cxd56_audio_ac_reg_disable_deq(); + + /* Set DEQ coef data to register. */ + + if (deq != NULL) + { + cxd56_audio_ac_reg_set_deq_param(deq); + } + + /* Enable DEQ. */ + + if (en) + { + cxd56_audio_ac_reg_enable_deq(); + } +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_filter.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_filter.h new file mode 100644 index 00000000000..f3fc2a45375 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_filter.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_filter.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_FILTER_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_FILTER_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_filter_set_cstereo(bool en, + bool sign_inv, + int16_t vol); +void cxd56_audio_filter_poweron_dnc(void); +void cxd56_audio_filter_poweroff_dnc(void); +void cxd56_audio_filter_set_dnc(cxd56_audio_dnc_id_t id, + bool en, + FAR cxd56_audio_dnc_bin_t *bin); +void cxd56_audio_filter_set_deq(bool en, + FAR cxd56_audio_deq_coef_t *deq); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_FILTER_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_irq.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_irq.c new file mode 100644 index 00000000000..69d7b8f58d2 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_irq.c @@ -0,0 +1,100 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_irq.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "cxd56_audio_irq.h" + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +extern void CXD56_audio_dma_int_handler(void); + +/*************************************************************************** + * Private Data + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Private Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Functions + ****************************************************************************/ + +void cxd56_audio_irq_attach(void) +{ + irq_attach(CXD56_IRQ_AUDIO_0, (xcpt_t)CXD56_audio_dma_int_handler, NULL); + irq_attach(CXD56_IRQ_AUDIO_1, (xcpt_t)CXD56_audio_dma_int_handler, NULL); + irq_attach(CXD56_IRQ_AUDIO_2, (xcpt_t)CXD56_audio_dma_int_handler, NULL); + irq_attach(CXD56_IRQ_AUDIO_3, (xcpt_t)CXD56_audio_dma_int_handler, NULL); +} + +void cxd56_audio_irq_detach(void) +{ + irq_detach(CXD56_IRQ_AUDIO_0); + irq_detach(CXD56_IRQ_AUDIO_1); + irq_detach(CXD56_IRQ_AUDIO_2); + irq_detach(CXD56_IRQ_AUDIO_3); +} + +void cxd56_audio_irq_enable(void) +{ + up_enable_irq(CXD56_IRQ_AUDIO_0); + up_enable_irq(CXD56_IRQ_AUDIO_1); + up_enable_irq(CXD56_IRQ_AUDIO_2); +} + +void cxd56_audio_irq_disable(void) +{ + up_disable_irq(CXD56_IRQ_AUDIO_0); + up_disable_irq(CXD56_IRQ_AUDIO_1); + up_disable_irq(CXD56_IRQ_AUDIO_2); +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_irq.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_irq.h new file mode 100644 index 00000000000..d8d6e0056f6 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_irq.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_irq.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_IRQ_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_IRQ_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void cxd56_audio_irq_attach(void); +void cxd56_audio_irq_detach(void); +void cxd56_audio_irq_enable(void); +void cxd56_audio_irq_disable(void); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_IRQ_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_mic.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_mic.c new file mode 100644 index 00000000000..1b360b12e6d --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_mic.c @@ -0,0 +1,229 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_mic.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_mic.h" +#include "cxd56_audio_ac_reg.h" + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CIC_NUM 4 +#define CIC_MIC_CH_NUM 2 + +#define MIC_CH_BITNUM 4 +#define MIC_CH_BITMAP 0xf + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/*************************************************************************** + * Private Data + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Private Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Functions + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_mic_enable(FAR cxd56_audio_mic_gain_t *gain) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + uint8_t mic_num; + uint8_t cic_num; + uint8_t mic_sel; + uint8_t mic_mode; + uint32_t mic_map; + cxd56_audio_mic_gain_t cic_gain; + cxd56_audio_clkmode_t clk_mode; + uint8_t i; + + /* Get mic number. */ + + mic_num = cxd56_audio_config_get_micnum(); + + /* Get CIC filter number. */ + + cic_num = (mic_num + 1) / CIC_MIC_CH_NUM; + + /* Get mic mode. */ + + mic_mode = cxd56_audio_config_get_micmode(); + + /* Set cic gain. */ + + mic_map = cxd56_audio_config_get_micmap(); + + for (i = 0; i < CXD56_AUDIO_MIC_CH_MAX; i++) + { + mic_sel = (mic_map >> (i * MIC_CH_BITNUM)) & + MIC_CH_BITMAP; + if ((mic_sel >= 1) && (mic_sel <= 4)) + { + cic_gain.gain[i] = 0; + } + else + { + cic_gain.gain[i] = gain->gain[i]; + } + } + + ret = cxd56_audio_ac_reg_poweron_cic(CXD56_AUDIO_CFG_CIC_IN, + mic_mode, + cic_num, + &cic_gain); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + clk_mode = cxd56_audio_config_get_clkmode(); + ret = cxd56_audio_ac_reg_poweron_decim(mic_mode, clk_mode); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_mic_disable(void) +{ + /* Disable DECIM. */ + + cxd56_audio_ac_reg_poweroff_decim(); + + /* Power off CIC. */ + + cxd56_audio_ac_reg_poweroff_cic(); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_mic_set_gain(FAR cxd56_audio_mic_gain_t *gain) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + uint8_t mic_num; + uint8_t cic_num; + uint8_t mic_sel; + uint32_t mic_map; + cxd56_audio_mic_gain_t cic_gain; + uint8_t i; + + /* Get mic number. */ + + mic_num = cxd56_audio_config_get_micnum(); + + /* Get CIC filter number. */ + + cic_num = (mic_num + 1) / CIC_MIC_CH_NUM; + + /* Set cic gain. */ + + mic_map = cxd56_audio_config_get_micmap(); + + for (i = 0; i < CXD56_AUDIO_MIC_CH_MAX; i++) + { + mic_sel = (mic_map >> (i * MIC_CH_BITNUM)) & + MIC_CH_BITMAP; + if ((mic_sel >= 1) && (mic_sel <= 4)) + { + cic_gain.gain[i] = 0; + } + else + { + cic_gain.gain[i] = gain->gain[i]; + } + } + + cxd56_audio_ac_reg_set_cicgain(cic_num, &cic_gain); + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_mic_set_seloutch(uint8_t dma_mic_num, + cxd56_audio_samp_fmt_t format) +{ + uint8_t i; + cxd56_audio_ac_reg_seloutch_t seloutch; + + if ((format == CXD56_AUDIO_SAMP_FMT_16) && + (CXD56_AUDIO_CFG_DMA_FORMAT == CXD56_AUDIO_CFG_DMA_FORMAT_RL)) + { + for (i = 0; i < CXD56_AUDIO_MIC_CH_MAX; i++) + { + seloutch.ch[i] = (i & 1) ? i - 1 : i + 1; + } + } + else + { + for (i = 0; i < CXD56_AUDIO_MIC_CH_MAX; i++) + { + seloutch.ch[i] = i; + } + } + + if ((format == CXD56_AUDIO_SAMP_FMT_16) && ((dma_mic_num & 1) == 1)) + { + if (CXD56_AUDIO_CFG_DMA_FORMAT == CXD56_AUDIO_CFG_DMA_FORMAT_LR) + { + seloutch.ch[dma_mic_num] = seloutch.ch[dma_mic_num - 1]; + } + else + { + seloutch.ch[dma_mic_num - 1] = seloutch.ch[dma_mic_num]; + } + } + + cxd56_audio_ac_reg_set_seloutch(&seloutch); + + return CXD56_AUDIO_ECODE_OK; +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_mic.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_mic.h new file mode 100644 index 00000000000..140179f80b7 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_mic.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_mic.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_MIC_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_MIC_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_mic_enable(FAR cxd56_audio_mic_gain_t *gain); +CXD56_AUDIO_ECODE cxd56_audio_mic_disable(void); +CXD56_AUDIO_ECODE cxd56_audio_mic_set_gain(FAR cxd56_audio_mic_gain_t *gain); +CXD56_AUDIO_ECODE cxd56_audio_mic_set_seloutch(uint8_t mic_num, + cxd56_audio_samp_fmt_t format); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_MIC_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_pin.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_pin.c new file mode 100644 index 00000000000..ef9bddacc6d --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_pin.c @@ -0,0 +1,60 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_pin.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "cxd56_audio_pin.h" + +/*************************************************************************** + * Public Functions + ****************************************************************************/ + +void cxd56_audio_pin_i2s_set(void) +{ + /* Enable I2S. */ + + board_audio_i2s_enable(); +} + +void cxd56_audio_pin_i2s_unset(void) +{ + /* Disable I2S. */ + + board_audio_i2s_disable(); +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_pin.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_pin.h new file mode 100644 index 00000000000..17f429b141c --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_pin.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_pin.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_PIN_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_PIN_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void cxd56_audio_pin_i2s_set(void); +void cxd56_audio_pin_i2s_unset(void); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_PIN_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_power.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_power.c new file mode 100644 index 00000000000..9fdd03a895f --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_power.c @@ -0,0 +1,138 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_power.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_power.h" +#include "cxd56_audio_digital.h" +#include "cxd56_audio_ac_reg.h" +#include "cxd56_audio_bca_reg.h" + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/*************************************************************************** + * Private Data + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Private Functions + ****************************************************************************/ + +static CXD56_AUDIO_ECODE power_on_codec(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + cxd56_audio_clkmode_t clk_mode = cxd56_audio_config_get_clkmode(); + + ret = cxd56_audio_ac_reg_checkid(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + cxd56_audio_ac_reg_initdsp(); + cxd56_audio_ac_reg_poweron_sdes(); + + uint8_t mic_mode = cxd56_audio_config_get_micmode(); + ret = cxd56_audio_ac_reg_set_micmode(mic_mode); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + cxd56_audio_ac_reg_poweron_codec(); + cxd56_audio_digital_poweron(); + cxd56_audio_ac_reg_resetdsp(); + cxd56_audio_digital_enable(); + cxd56_audio_ac_reg_enable_serialif(); + cxd56_audio_ac_reg_init_selector(); + + ret = cxd56_audio_ac_reg_set_alcspc(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + cxd56_audio_bca_reg_set_datarate(clk_mode); + + return ret; +} + +/*************************************************************************** + * Public Functions + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_power_on(void) +{ + CXD56_AUDIO_ECODE ret = CXD56_AUDIO_ECODE_OK; + + /* Power on audio codec block. */ + + ret = power_on_codec(); + if (CXD56_AUDIO_ECODE_OK != ret) + { + return ret; + } + + return ret; +} + +CXD56_AUDIO_ECODE cxd56_audio_power_off(void) +{ + /* Power off audio codec block. */ + + cxd56_audio_ac_reg_poweroff_codec(); + + return CXD56_AUDIO_ECODE_OK; +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_power.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_power.h new file mode 100644 index 00000000000..41b73abe11a --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_power.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_power.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_POWER_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_POWER_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_power_on(void); +CXD56_AUDIO_ECODE cxd56_audio_power_off(void); + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_POWER_H */ diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_volume.c b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_volume.c new file mode 100644 index 00000000000..9490a70a71b --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_volume.c @@ -0,0 +1,288 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_volume.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "cxd56_audio_config.h" +#include "cxd56_audio_ac_reg.h" +#include "cxd56_audio_analog.h" +#include "cxd56_audio_volume.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Number of volume device. */ + +#define VOLUME_NUM 3 + +/* Maximum value. */ + +#define VOLUME_MAX 120 + +/* Minimum value. */ + +#define VOLUME_MIN -1020 + +/* Mute volume. */ + +#define VOLUME_MUTE -1025 + +#define MUTE_BIT_API 0x01 +#define MUTE_BIT_FADE 0x02 +#define MUTE_VOL_REG 0x33 +#define VOL_WAIT_TIME 20 +#define VOL_TO_REG(vol) (((vol) / 5) & 0xff) +#define VOL_MUTE_TIME(vol, n_cycle) \ + (((VOL_TO_REG(vol) - MUTE_VOL_REG) & 0xff) * (n_cycle + 1) * 4 / 48 * 1000) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Type + ****************************************************************************/ + +struct set_vol_prm_s +{ + int16_t hold_vol; + uint8_t mute_bit; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct set_vol_prm_s g_volparam[VOLUME_NUM] = +{ + {VOLUME_MUTE, MUTE_BIT_API}, + {VOLUME_MUTE, MUTE_BIT_API}, + {VOLUME_MUTE, MUTE_BIT_API} +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static CXD56_AUDIO_ECODE set_mute(cxd56_audio_volid_t id, + bool wait, + uint8_t type) +{ + uint32_t waittime = 0; + + waittime = VOL_MUTE_TIME(g_volparam[id].hold_vol, 1); + + if (g_volparam[id].mute_bit == 0) + { + switch (id) + { + case CXD56_AUDIO_VOLID_MIXER_IN1: + cxd56_audio_ac_reg_set_vol_sdin1(MUTE_VOL_REG); + break; + + case CXD56_AUDIO_VOLID_MIXER_IN2: + cxd56_audio_ac_reg_set_vol_sdin2(MUTE_VOL_REG); + break; + + default: + cxd56_audio_ac_reg_set_vol_dac(MUTE_VOL_REG); + break; + } + } + + if (wait) + { + usleep(waittime); + } + + g_volparam[id].mute_bit |= type; + + if (g_volparam[CXD56_AUDIO_VOLID_MIXER_OUT].mute_bit != 0) + { + CXD56_AUDIO_ECODE ret = cxd56_audio_analog_disable_output(); + if (ret != CXD56_AUDIO_ECODE_OK) + { + return ret; + } + } + + return CXD56_AUDIO_ECODE_OK; +} + +static CXD56_AUDIO_ECODE set_unmute(cxd56_audio_volid_t id, + bool wait, + uint8_t type) +{ + uint32_t waittime = 0; + + g_volparam[id].mute_bit &= ~type; + + if (g_volparam[CXD56_AUDIO_VOLID_MIXER_OUT].mute_bit == 0) + { + CXD56_AUDIO_ECODE ret = cxd56_audio_analog_enable_output(); + if (ret != CXD56_AUDIO_ECODE_OK) + { + return ret; + } + } + + if (g_volparam[id].mute_bit == 0) + { + if (type == MUTE_BIT_API) + { + waittime = VOL_WAIT_TIME; + } + else + { + /* fade */ + + waittime = VOL_MUTE_TIME(g_volparam[id].hold_vol, 1); + } + + uint32_t vol = VOL_TO_REG(g_volparam[id].hold_vol); + + switch (id) + { + case CXD56_AUDIO_VOLID_MIXER_IN1: + cxd56_audio_ac_reg_set_vol_sdin1(vol); + break; + + case CXD56_AUDIO_VOLID_MIXER_IN2: + cxd56_audio_ac_reg_set_vol_sdin2(vol); + break; + + default: + cxd56_audio_ac_reg_set_vol_dac(vol); + break; + } + + if (wait) + { + usleep(waittime); + } + } + + return CXD56_AUDIO_ECODE_OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_volume_set(cxd56_audio_volid_t id, + int16_t vol) +{ + if (id >= VOLUME_NUM) + { + return CXD56_AUDIO_ECODE_VOL_ID; + } + + if (VOLUME_MIN > vol) + { + if (VOLUME_MUTE != vol) + { + return CXD56_AUDIO_ECODE_VOL_MIN; + } + } + if (VOLUME_MAX < vol) + { + return CXD56_AUDIO_ECODE_VOL_MAX; + } + + g_volparam[id].hold_vol = vol; + set_unmute(id, true, MUTE_BIT_API); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_volume_mute(cxd56_audio_volid_t id) +{ + if (id >= VOLUME_NUM) + { + return CXD56_AUDIO_ECODE_VOL_ID; + } + + set_mute(id, true, MUTE_BIT_API); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_volume_unmute(cxd56_audio_volid_t id) +{ + if (id >= VOLUME_NUM) + { + return CXD56_AUDIO_ECODE_VOL_ID; + } + + set_unmute(id, true, MUTE_BIT_API); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_volume_mute_fade(cxd56_audio_volid_t id, + bool wait) +{ + if (id >= VOLUME_NUM) + { + return CXD56_AUDIO_ECODE_VOL_ID; + } + + set_mute(id, wait, MUTE_BIT_FADE); + + return CXD56_AUDIO_ECODE_OK; +} + +CXD56_AUDIO_ECODE cxd56_audio_volume_unmute_fade(cxd56_audio_volid_t id, + bool wait) +{ + if (id >= VOLUME_NUM) + { + return CXD56_AUDIO_ECODE_VOL_ID; + } + + set_unmute(id, wait, MUTE_BIT_FADE); + + return CXD56_AUDIO_ECODE_OK; +} diff --git a/boards/arm/cxd56xx/drivers/audio/cxd56_audio_volume.h b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_volume.h new file mode 100644 index 00000000000..1511b8d15b6 --- /dev/null +++ b/boards/arm/cxd56xx/drivers/audio/cxd56_audio_volume.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * arch/arm/src/cxd56xx/cxd56_audio_volume.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_VOLUME_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_VOLUME_H + +/*************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/*************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/*************************************************************************** + * Public Types + ****************************************************************************/ + +/*************************************************************************** + * Public Data + ****************************************************************************/ + +/*************************************************************************** + * Inline Functions + ****************************************************************************/ + +/*************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +CXD56_AUDIO_ECODE cxd56_audio_volume_set(cxd56_audio_volid_t id, int16_t vol); +CXD56_AUDIO_ECODE cxd56_audio_volume_mute(cxd56_audio_volid_t id); +CXD56_AUDIO_ECODE cxd56_audio_volume_unmute(cxd56_audio_volid_t id); +CXD56_AUDIO_ECODE cxd56_audio_volume_mute_fade(cxd56_audio_volid_t id, + bool wait); +CXD56_AUDIO_ECODE cxd56_audio_volume_unmute_fade(cxd56_audio_volid_t id, + bool wait); +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_AUDIO_VOLUME_H */ diff --git a/boards/arm/cxd56xx/spresense/configs/audio/defconfig b/boards/arm/cxd56xx/spresense/configs/audio/defconfig index 372c312aaa4..ea699a68031 100644 --- a/boards/arm/cxd56xx/spresense/configs/audio/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/audio/defconfig @@ -21,6 +21,7 @@ CONFIG_BOARD_LOOPSPERMSEC=5434 CONFIG_BOOT_RUNFROMISRAM=y CONFIG_BUILTIN=y CONFIG_CLOCK_MONOTONIC=y +CONFIG_CXD56_AUDIO=y CONFIG_CXD56_BINARY=y CONFIG_CXD56_I2C0=y CONFIG_CXD56_I2C=y @@ -28,7 +29,6 @@ CONFIG_CXD56_SDIO=y CONFIG_CXD56_SPI4=y CONFIG_CXD56_SPI5=y CONFIG_CXD56_SPI=y -CONFIG_CXD56_AUDIO=y CONFIG_CXD56_USBDEV=y CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y @@ -42,6 +42,7 @@ CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_I2C=y +CONFIG_LIBM=y CONFIG_MAX_TASKS=16 CONFIG_MAX_WDOGPARMS=2 CONFIG_MMCSD=y @@ -70,6 +71,7 @@ CONFIG_SDCLONE_DISABLE=y CONFIG_SMARTFS_ALIGNED_ACCESS=y CONFIG_SMARTFS_MAXNAMLEN=30 CONFIG_SMARTFS_MULTI_ROOT_DIRS=y +CONFIG_SPECIFIC_DRIVERS=y CONFIG_SPI=y CONFIG_START_DAY=6 CONFIG_START_MONTH=12 diff --git a/boards/arm/cxd56xx/spresense/include/board.h b/boards/arm/cxd56xx/spresense/include/board.h index abb0846c8e1..e5630eba717 100644 --- a/boards/arm/cxd56xx/spresense/include/board.h +++ b/boards/arm/cxd56xx/spresense/include/board.h @@ -56,6 +56,7 @@ #include "cxd56_wdt.h" #include "cxd56_gpioif.h" +#include "cxd56_audio.h" #include "cxd56_ak09912.h" #include "cxd56_apds9930.h" #include "cxd56_apds9960.h" @@ -214,12 +215,13 @@ enum board_power_device POWER_AUDIO_DVDD = PMIC_LSW(2), POWER_FLASH = PMIC_LSW(3), - POWER_TCXO = PMIC_LSW(3), + POWER_TCXO = PMIC_LSW(4), POWER_LNA = PMIC_LSW(4), /* GPO */ - POWER_AUDIO_AVDD = PMIC_GPO(0), + POWER_AUDIO_AVDD = PMIC_GPO(1), + POWER_AUDIO_MUTE = PMIC_GPO(6), POWER_SENSOR_18V = PMIC_GPO(1), POWER_SENSOR_33V = PMIC_GPO(2), POWER_BMI160 = POWER_SENSOR_18V, diff --git a/boards/arm/cxd56xx/spresense/include/cxd56_audio.h b/boards/arm/cxd56xx/spresense/include/cxd56_audio.h new file mode 100644 index 00000000000..63274c9471f --- /dev/null +++ b/boards/arm/cxd56xx/spresense/include/cxd56_audio.h @@ -0,0 +1,160 @@ +/**************************************************************************** + * boards/arm/cxd56xx/spresense/include/cxd56_audio.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation 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. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_CXD56XX_SPRESENSE_INCLUDE_CXD56_AUDIO_H +#define __BOARDS_ARM_CXD56XX_SPRESENSE_INCLUDE_CXD56_AUDIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: board_aca_power_control + * + * Description: + * Power on/off the Aca device on the board. + * + ****************************************************************************/ + +int board_aca_power_control(int target, bool en); + +/**************************************************************************** + * Name: board_aca_power_monitor + * + * Description: + * Get status of Power on/off the Aca device on the board. + * + ****************************************************************************/ + +bool board_aca_power_monitor(int target); + +/**************************************************************************** + * Name: board_external_amp_mute_control + * + * Description: + * External Amp. Mute on/off. + * true: Mute on + * false: Mute off + * + ****************************************************************************/ + +int board_external_amp_mute_control(bool en); + +/**************************************************************************** + * Name: board_external_amp_mute_monitor + * + * Description: + * Get External Amp. Mute status. + * true: Mute on + * false: Mute off + * + ****************************************************************************/ + +bool board_external_amp_mute_monitor(void); + +/**************************************************************************** + * Name: board_audio_i2s_enable + * + * Description: + * Enable I2S on the board. + * Used by the audio driver. Do not use by users. + * + ****************************************************************************/ + +void board_audio_i2s_enable(void); + +/**************************************************************************** + * Name: board_audio_i2s_disable + * + * Description: + * Disable I2S on the board. + * Used by the audio driver. Do not use by users. + * + ****************************************************************************/ + +void board_audio_i2s_disable(void); + +/**************************************************************************** + * Name: board_audio_initialize + * + * Description: + * Initialize audio I/O on the board. + * Used by the audio driver. Do not use by users. + * + ****************************************************************************/ + +void board_audio_initialize(void); + +/**************************************************************************** + * Name: board_audio_finalize + * + * Description: + * Finalize audio I/O on the board. + * Used by the audio driver. Do not use by users. + * + ****************************************************************************/ + +void board_audio_finalize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_ARM_CXD56XX_SPRESENSE_INCLUDE_CXD56_AUDIO_H */