/*************************************************************************** * 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(); } bool board_audio_tone_generator(bool en, int16_t vol, uint16_t freq) { if (!en) { /* Stop beep */ if (cxd56_audio_stop_beep() != 0) { return false; } } if (0 != freq) { /* Set beep frequency parameter */ if (cxd56_audio_set_beep_freq(freq) != 0) { return false; } } if (255 != vol) { /* Set beep volume parameter */ if (cxd56_audio_set_beep_vol(vol) != 0) { return false; } } if (en) { /* Play beep */ if (cxd56_audio_play_beep() != 0) { return false; } } return true; }