nuttx/boards/arm/cxd56xx/drivers/audio/cxd56_audio_dma.c
Alin Jerpelea 15eddd29c8 cxd56xx improvements (#48) and various other fixes (#49)
Author: Alan Carvalho de Assis <acassis@gmail.com>

    Verify all .c and .h against nxstyle, fixed the Mixed cases

Author: Alin Jerpelea <alin.jerpelea@sony.com>

    cxd56xx improvements (#48)

    * arch: cxd56xx: Add size limitation for I2C SCU xfer

    This is a fw restriction, unroll loop because it can be transfer
    up to 16 bytes.

    * arch: cxd56xx: Fix lack of leave_critical_section

    add the missing leave_critical_section

    * arch: cxd56xx: Remove unnecessary file

    this header is duplicate and we can remove it

    * arch: cxd56xx: Cosmetic change

    remove space after function

    * arch: cxd56xx: update topreg registers

    the topreg registers are updated to match the cxd5602 HW

    * arch: cxd56xx: Add voltage setting for low battery notification

    Add voltage setting for low battery notification

    * arch: cxd56xx: Improve perfomance of SD card

    Improve a problem that the clock of SD Host Controller is lower than the
    expected value in SDR25 transfer mode.

    * arch: cxd56xx: Cosmetic changes

    cleanup to comply with coding standard

    * boards: cxd56xx: Cosmetic changes

    updates to comply with coding standard

    * boards: cxd56xx: Fix SD card cannot mount issue

    SD card cannot mount when connecting and disconnecting three times
    or more due to wrong state of parameter 'initialized'.

    This change enables to skip swtching initialized state when mount
    failed.
2020-01-07 18:29:52 -03:00

711 lines
19 KiB
C

/***************************************************************************
* boards/arm/cxd56xx/drivers/audio/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 <stdint.h>
#include <nuttx/arch.h>
#include <nuttx/config.h>
#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);
}
}
}