nuttx/boards/arm/cxd56xx/drivers/audio/cxd56_audio.c

1351 lines
27 KiB
C
Raw Normal View History

/***************************************************************************
* 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 <nuttx/config.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <debug.h>
#include <arch/board/board.h>
#include <arch/chip/audio.h>
#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;
}