mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-14 18:38:55 +00:00
536 lines
17 KiB
C
536 lines
17 KiB
C
/*
|
|
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Authors: dwj <weijie.ding@artinchip.com>
|
|
*/
|
|
|
|
#include "hal_audio.h"
|
|
|
|
int hal_audio_init(aic_audio_ctrl *codec)
|
|
{
|
|
int ret;
|
|
codec->reg_base = AUDIO_BASE;
|
|
codec->irq_num = AUDIO_IRQn;
|
|
codec->clk_id = CLK_CODEC;
|
|
|
|
ret = hal_clk_set_freq(codec->clk_id, DEFAULT_AUDIO_FREQ);
|
|
if (ret)
|
|
hal_log_err("Audio init set freq error!\n");
|
|
|
|
ret = hal_clk_enable_deassertrst_iter(codec->clk_id);
|
|
if (ret)
|
|
hal_log_err("Audio init error!\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
int hal_audio_uninit(aic_audio_ctrl *codec)
|
|
{
|
|
int ret;
|
|
|
|
ret = hal_clk_disable_assertrst(codec->clk_id);
|
|
if (ret)
|
|
hal_log_err("Audio uninit error!\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int hal_audio_get_hw_rate(aic_audio_ctrl *codec, uint32_t samplerate)
|
|
{
|
|
switch (samplerate)
|
|
{
|
|
case 48000:
|
|
case 44100:
|
|
return 0;
|
|
case 32000:
|
|
return 1;
|
|
case 24000:
|
|
case 22050:
|
|
return 2;
|
|
case 16000:
|
|
return 3;
|
|
case 12000:
|
|
case 11025:
|
|
return 4;
|
|
case 8000:
|
|
return 5;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
static uint32_t hal_audio_get_module_freq(aic_audio_ctrl *codec,
|
|
uint32_t samplerate)
|
|
{
|
|
uint32_t reg_val;
|
|
|
|
switch (samplerate)
|
|
{
|
|
case 48000:
|
|
case 32000:
|
|
case 24000:
|
|
case 16000:
|
|
case 12000:
|
|
case 8000:
|
|
/* Set playback module clock */
|
|
reg_val = readl(codec->reg_base + TX_PLAYBACK_CTRL_REG);
|
|
reg_val &= ~TX_CLK_MASK;
|
|
writel(reg_val, codec->reg_base + TX_PLAYBACK_CTRL_REG);
|
|
/* Set dmic module clock */
|
|
reg_val = readl(codec->reg_base + RX_DMIC_IF_CTRL_REG);
|
|
reg_val &= ~RX_DMIC_IF_RX_CLK_MASK;
|
|
writel(reg_val, codec->reg_base + RX_DMIC_IF_CTRL_REG);
|
|
/* Set amic module clock */
|
|
reg_val = readl(codec->reg_base + ADC_IF_CTRL_REG);
|
|
reg_val &= ~ADC_IF_CTRL_RX_CLK_FRE_MASK;
|
|
writel(reg_val, codec->reg_base + ADC_IF_CTRL_REG);
|
|
return 24576000;
|
|
case 44100:
|
|
case 22050:
|
|
case 11025:
|
|
/* Set playback module clock */
|
|
reg_val = readl(codec->reg_base + TX_PLAYBACK_CTRL_REG);
|
|
reg_val |= TX_CLK_22579KHZ;
|
|
writel(reg_val, codec->reg_base + TX_PLAYBACK_CTRL_REG);
|
|
/* set dmic module clock */
|
|
reg_val = readl(codec->reg_base + RX_DMIC_IF_CTRL_REG);
|
|
reg_val |= RX_DMIC_IF_RX_CLK_22579KHZ;
|
|
writel(reg_val, codec->reg_base + RX_DMIC_IF_CTRL_REG);
|
|
/* set amic module clock */
|
|
reg_val = readl(codec->reg_base + ADC_IF_CTRL_REG);
|
|
reg_val |= ADC_IF_CTRL_RX_CLK_22579KHZ;
|
|
writel(reg_val, codec->reg_base + ADC_IF_CTRL_REG);
|
|
return 22579200;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void hal_audio_set_samplerate(aic_audio_ctrl *codec, uint32_t samplerate)
|
|
{
|
|
int hw_rate;
|
|
uint32_t reg_val, module_freq;
|
|
unsigned int pclk_id;
|
|
|
|
hw_rate = hal_audio_get_hw_rate(codec, samplerate);
|
|
/* Set playback samplerate */
|
|
reg_val = readl(codec->reg_base + TX_PLAYBACK_CTRL_REG);
|
|
reg_val &= ~TX_FS_OUT_MASK;
|
|
reg_val |= TX_FS_OUT(hw_rate);
|
|
writel(reg_val, codec->reg_base + TX_PLAYBACK_CTRL_REG);
|
|
/* Set dmic samplerate */
|
|
reg_val = readl(codec->reg_base + RX_DMIC_IF_CTRL_REG);
|
|
reg_val &= ~RX_DMIC_IF_FS_IN_MASK;
|
|
reg_val |= RX_DMIC_IF_FS_IN(hw_rate);
|
|
writel(reg_val, codec->reg_base + RX_DMIC_IF_CTRL_REG);
|
|
/* Set amic samplerate */
|
|
reg_val = readl(codec->reg_base + ADC_IF_CTRL_REG);
|
|
reg_val &= ~ADC_IF_CTRL_FS_ADC_IN_MASK;
|
|
reg_val |= ADC_IF_CTRL_FS_ADC_IN(hw_rate);
|
|
writel(reg_val, codec->reg_base + ADC_IF_CTRL_REG);
|
|
module_freq = hal_audio_get_module_freq(codec, samplerate);
|
|
pclk_id = hal_clk_get_parent(codec->clk_id);
|
|
#ifdef AIC_AUDIO_DRV_V10
|
|
/* Set AudioCodec parent clock rate */
|
|
hal_clk_set_freq(pclk_id, module_freq * 20);
|
|
/* Set AudioCodec module clock rate */
|
|
hal_clk_set_rate(codec->clk_id, module_freq, module_freq * 20);
|
|
#elif defined(AIC_AUDIO_DRV_V11) || defined(AIC_AUDIO_DRV_V12)
|
|
/* Audio has the same frequency with AUDIO_SCLK */
|
|
hal_clk_set_freq(pclk_id, module_freq);
|
|
#endif
|
|
}
|
|
|
|
void hal_audio_set_playback_channel(aic_audio_ctrl *codec, uint32_t ch)
|
|
{
|
|
uint32_t reg_val;
|
|
|
|
if (ch == 1)
|
|
{
|
|
/* Enable TX ch0 */
|
|
reg_val = readl(codec->reg_base + TXFIFO_CTRL_REG);
|
|
reg_val &= ~TXFIFO_CH_MASK;
|
|
reg_val |= TXFIFO_CH0_EN;
|
|
writel(reg_val, codec->reg_base + TXFIFO_CTRL_REG);
|
|
}
|
|
else if (ch == 2)
|
|
{
|
|
/* Enable TX ch0 ch1 */
|
|
reg_val = readl(codec->reg_base + TXFIFO_CTRL_REG);
|
|
reg_val &= ~TXFIFO_CH_MASK;
|
|
reg_val |= (TXFIFO_CH0_EN | TXFIFO_CH1_EN);
|
|
writel(reg_val, codec->reg_base + TXFIFO_CTRL_REG);
|
|
}
|
|
}
|
|
|
|
void hal_audio_set_playback_by_spk0(aic_audio_ctrl *codec)
|
|
{
|
|
uint32_t reg_val;
|
|
|
|
/* Enable DVC3 */
|
|
reg_val = readl(codec->reg_base + TX_DVC_3_4_CTRL_REG);
|
|
reg_val &= ~TX_DVC3_MASK;
|
|
reg_val |= TX_DVC3_EN;
|
|
writel(reg_val, codec->reg_base + TX_DVC_3_4_CTRL_REG);
|
|
/* Enable IF0 */
|
|
reg_val = readl(codec->reg_base + TX_PLAYBACK_CTRL_REG);
|
|
reg_val &= ~TX_IF_CH0_MASK;
|
|
reg_val |= TX_PLAYBACK_IF_EN | TX_IF_CH0_EN;
|
|
writel(reg_val, codec->reg_base + TX_PLAYBACK_CTRL_REG);
|
|
/* Enable SDM0 */
|
|
reg_val = readl(codec->reg_base + TX_SDM_CTRL_REG);
|
|
reg_val &= ~TX_SDM_CH0_MASK;
|
|
reg_val |= TX_SDM_CH0_EN;
|
|
writel(reg_val, codec->reg_base + TX_SDM_CTRL_REG);
|
|
/* Configure MIXER audio path */
|
|
reg_val = readl(codec->reg_base + TX_MIXER_CTRL_REG);
|
|
reg_val &= ~TX_MIXER0_PATH_MASK;
|
|
reg_val |= TX_MIXER0_AUDOUTL_SEL | TX_MIXER0_AUDOUTR_SEL;
|
|
writel(reg_val, codec->reg_base + TX_MIXER_CTRL_REG);
|
|
/* Configure PWM0 single output */
|
|
reg_val = readl(codec->reg_base + TX_PWM_CTRL_REG);
|
|
reg_val &= ~TX_PWM0_MASK;
|
|
#ifdef AIC_AUDIO_PDM_MODULATION_MODE
|
|
reg_val |= TX_PWM0_EN | TX_PDM0_EN;
|
|
#else
|
|
reg_val |= TX_PWM0_EN;
|
|
#endif
|
|
writel(reg_val, codec->reg_base + TX_PWM_CTRL_REG);
|
|
}
|
|
|
|
void hal_audio_set_playback_by_spk1(aic_audio_ctrl *codec)
|
|
{
|
|
uint32_t reg_val;
|
|
|
|
/* Enable DVC4 */
|
|
reg_val = readl(codec->reg_base + TX_DVC_3_4_CTRL_REG);
|
|
reg_val &= ~TX_DVC4_MASK;
|
|
reg_val |= TX_DVC4_EN;
|
|
writel(reg_val, codec->reg_base + TX_DVC_3_4_CTRL_REG);
|
|
/* Enable IF1 */
|
|
reg_val = readl(codec->reg_base + TX_PLAYBACK_CTRL_REG);
|
|
reg_val &= ~TX_IF_CH1_MASK;
|
|
reg_val |= TX_PLAYBACK_IF_EN | TX_IF_CH1_EN;
|
|
writel(reg_val, codec->reg_base + TX_PLAYBACK_CTRL_REG);
|
|
/* Enable SDM1 */
|
|
reg_val = readl(codec->reg_base + TX_SDM_CTRL_REG);
|
|
reg_val &= ~TX_SDM_CH1_MASK;
|
|
reg_val |= TX_SDM_CH1_EN;
|
|
writel(reg_val, codec->reg_base + TX_SDM_CTRL_REG);
|
|
/* Configure MIXER audio path */
|
|
reg_val = readl(codec->reg_base + TX_MIXER_CTRL_REG);
|
|
reg_val &= ~TX_MIXER1_PATH_MASK;
|
|
reg_val |= TX_MIXER1_AUDOUTL_SEL | TX_MIXER1_AUDOUTR_SEL;
|
|
writel(reg_val, codec->reg_base + TX_MIXER_CTRL_REG);
|
|
/* Configure PWM1 single output */
|
|
reg_val = readl(codec->reg_base + TX_PWM_CTRL_REG);
|
|
reg_val &= ~TX_PWM1_MASK;
|
|
#ifdef AIC_AUDIO_PDM_MODULATION_MODE
|
|
reg_val |= TX_PWM1_EN | TX_PDM1_EN;
|
|
#else
|
|
reg_val |= TX_PWM1_EN;
|
|
#endif
|
|
writel(reg_val, codec->reg_base + TX_PWM_CTRL_REG);
|
|
}
|
|
|
|
void hal_audio_set_dmic_channel(aic_audio_ctrl *codec, uint32_t ch)
|
|
{
|
|
uint32_t reg_val;
|
|
|
|
if (ch == 1)
|
|
{
|
|
/* Enable HPF1 */
|
|
reg_val = readl(codec->reg_base + RX_HPF_1_2_CTRL_REG);
|
|
reg_val &= ~RX_HPF_MASK;
|
|
reg_val |= RX_HPF1_EN;
|
|
writel(reg_val, codec->reg_base + RX_HPF_1_2_CTRL_REG);
|
|
/* Enable DF1 and DMIC interface*/
|
|
reg_val = readl(codec->reg_base + RX_DMIC_IF_CTRL_REG);
|
|
reg_val &= ~RX_DMIC_IF_DEC_EN_MASK;
|
|
reg_val |= RX_DMIC_IF_DEC1_FLT | RX_DMIC_IF_EN;
|
|
writel(reg_val, codec->reg_base + RX_DMIC_IF_CTRL_REG);
|
|
/* Enable DVC1 */
|
|
reg_val = readl(codec->reg_base + RX_DVC_1_2_CTRL_REG);
|
|
reg_val &= ~RX_DVC_MASK;
|
|
reg_val |= RX_DVC1_EN;
|
|
writel(reg_val, codec->reg_base + RX_DVC_1_2_CTRL_REG);
|
|
/* Enable ch0 */
|
|
reg_val = readl(codec->reg_base + DMIC_RXFIFO_CTRL_REG);
|
|
reg_val &= ~DMIC_RXFIFO_CH_MASK;
|
|
reg_val |= DMIC_RXFIFO_CH0_EN;
|
|
writel(reg_val, codec->reg_base + DMIC_RXFIFO_CTRL_REG);
|
|
}
|
|
else if (ch == 2)
|
|
{
|
|
/* Enable HPF1_2 */
|
|
reg_val = readl(codec->reg_base + RX_HPF_1_2_CTRL_REG);
|
|
reg_val &= ~RX_HPF_MASK;
|
|
reg_val |= RX_HPF1_EN | RX_HPF2_EN;
|
|
writel(reg_val, codec->reg_base + RX_HPF_1_2_CTRL_REG);
|
|
/* Enable DF1_2 and DMIC interface*/
|
|
reg_val = readl(codec->reg_base + RX_DMIC_IF_CTRL_REG);
|
|
reg_val &= ~RX_DMIC_IF_DEC_EN_MASK;
|
|
reg_val |= RX_DMIC_IF_DEC1_FLT | RX_DMIC_IF_DEC2_FLT | RX_DMIC_IF_EN;
|
|
writel(reg_val, codec->reg_base + RX_DMIC_IF_CTRL_REG);
|
|
/* Enable DVC1 DVC2 */
|
|
reg_val = readl(codec->reg_base + RX_DVC_1_2_CTRL_REG);
|
|
reg_val |= RX_DVC_MASK;
|
|
writel(reg_val, codec->reg_base + RX_DVC_1_2_CTRL_REG);
|
|
/* Enable ch0 ch1 */
|
|
reg_val = readl(codec->reg_base + DMIC_RXFIFO_CTRL_REG);
|
|
reg_val |= DMIC_RXFIFO_CH_MASK;
|
|
writel(reg_val, codec->reg_base + DMIC_RXFIFO_CTRL_REG);
|
|
}
|
|
}
|
|
|
|
void hal_audio_set_amic_channel(aic_audio_ctrl *codec)
|
|
{
|
|
uint32_t reg_val;
|
|
|
|
/* Enable HPF0 */
|
|
reg_val = readl(codec->reg_base + ADC_HPF0_CTRL_REG);
|
|
reg_val |= ADC_HPF0_CTRL_HPF0_EN;
|
|
writel(reg_val, codec->reg_base + ADC_HPF0_CTRL_REG);
|
|
/* Enable MBIAS PGA ADC */
|
|
reg_val = readl(codec->reg_base + ADC_CTL1_REG);
|
|
reg_val |= ADC_CTL1_ADC_EN | ADC_CTL1_PGA_EN | ADC_CTL1_MBIAS_EN;
|
|
writel(reg_val, codec->reg_base + ADC_CTL1_REG);
|
|
/* Enable DF0 */
|
|
reg_val = readl(codec->reg_base + ADC_IF_CTRL_REG);
|
|
reg_val |= ADC_IF_CTRL_EN_DEC0_MASK;
|
|
writel(reg_val, codec->reg_base + ADC_IF_CTRL_REG);
|
|
/* Enable DVC0 */
|
|
reg_val = readl(codec->reg_base + ADC_DVC0_CTRL_REG);
|
|
reg_val |= ADC_DVC0_CTRL_DVC0_EN;
|
|
writel(reg_val, codec->reg_base + ADC_DVC0_CTRL_REG);
|
|
/* Enable amic channel */
|
|
reg_val = readl(codec->reg_base + ADC_RXFIFO_CTRL_REG);
|
|
reg_val |= ADC_RXFIFO_EN;
|
|
writel(reg_val, codec->reg_base + ADC_RXFIFO_CTRL_REG);
|
|
/* Set PGA CTRL */
|
|
reg_val = readl(codec->reg_base + ADC_CTL2_REG);
|
|
reg_val |= ADC_CTL2_PGA_GAIN_SEL;
|
|
writel(reg_val, codec->reg_base + ADC_CTL2_REG);
|
|
}
|
|
|
|
static void dma_transfer_period_callback(void *arg)
|
|
{
|
|
struct aic_audio_transfer_info *info;
|
|
aic_audio_ctrl *codec;
|
|
|
|
info = (struct aic_audio_transfer_info *)arg;
|
|
|
|
if (info->transfer_type == AUDIO_TRANSFER_TYPE_TX)
|
|
{
|
|
codec = container_of(info, aic_audio_ctrl, tx_info);
|
|
if (codec->callback)
|
|
codec->callback(codec, (void *)AUDIO_TX_PERIOD_INT);
|
|
}
|
|
else if (info->transfer_type == AUDIO_TRANSFER_TYPE_DMIC)
|
|
{
|
|
codec = container_of(info, aic_audio_ctrl, dmic_info);
|
|
if (codec->callback)
|
|
codec->callback(codec, (void *)AUDIO_RX_DMIC_PERIOD_INT);
|
|
}
|
|
else if (info->transfer_type == AUDIO_TRANSFER_TYPE_AMIC)
|
|
{
|
|
codec = container_of(info, aic_audio_ctrl, amic_info);
|
|
if (codec->callback)
|
|
codec->callback(codec, (void *)AUDIO_RX_AMIC_PERIOD_INT);
|
|
}
|
|
}
|
|
|
|
void hal_audio_playback_start(aic_audio_ctrl *codec)
|
|
{
|
|
struct dma_slave_config config;
|
|
struct aic_audio_transfer_info *info;
|
|
|
|
config.direction = DMA_MEM_TO_DEV;
|
|
config.dst_addr = codec->reg_base + TXFIFO_DATA_REG;
|
|
config.slave_id = 14;
|
|
config.src_maxburst = 1;
|
|
config.dst_maxburst = 1;
|
|
|
|
/* AudioCodec only support 16bit sample width */
|
|
if (codec->config.channel == 2)
|
|
{
|
|
config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
|
config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
|
}
|
|
else if (codec->config.channel == 1)
|
|
{
|
|
config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
|
config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
|
}
|
|
|
|
info = &codec->tx_info;
|
|
|
|
info->transfer_type = AUDIO_TRANSFER_TYPE_TX;
|
|
|
|
info->dma_chan = hal_request_dma_chan();
|
|
if (!info->dma_chan) {
|
|
hal_log_err("playback request dma channel error\n");
|
|
return;
|
|
}
|
|
|
|
hal_dma_chan_register_cb(info->dma_chan, dma_transfer_period_callback,
|
|
(void *)info);
|
|
hal_dma_chan_config(info->dma_chan, &config);
|
|
/* Configure DMA transfer */
|
|
hal_dma_chan_prep_cyclic(info->dma_chan, (ulong)info->buf_info.buf,
|
|
info->buf_info.buf_len, info->buf_info.period_len,
|
|
DMA_MEM_TO_DEV);
|
|
hal_dma_chan_start(info->dma_chan);
|
|
hal_audio_disable_fade(codec);
|
|
/* flush TXFIFO */
|
|
hal_audio_flush_tx_fifo(codec);
|
|
/* Enable TX global */
|
|
hal_audio_enable_tx_global(codec);
|
|
/* Enable AUDOUT DRQ */
|
|
hal_audio_tx_enable_drq(codec);
|
|
}
|
|
|
|
void hal_audio_dmic_start(aic_audio_ctrl *codec)
|
|
{
|
|
struct dma_slave_config config;
|
|
struct aic_audio_transfer_info *info;
|
|
|
|
config.direction = DMA_DEV_TO_MEM;
|
|
config.src_addr = codec->reg_base + DMIC_RXFIFO_DATA_REG;
|
|
config.slave_id = 14;
|
|
config.src_maxburst = 1;
|
|
config.dst_maxburst = 1;
|
|
|
|
/* AudioCodec only support 16bit sample width */
|
|
if (codec->config.channel == 2)
|
|
{
|
|
config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
|
config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
|
}
|
|
else if (codec->config.channel == 1)
|
|
{
|
|
config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
|
config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
|
}
|
|
|
|
info = &codec->dmic_info;
|
|
|
|
info->transfer_type = AUDIO_TRANSFER_TYPE_DMIC;
|
|
|
|
info->dma_chan = hal_request_dma_chan();
|
|
if (!info->dma_chan) {
|
|
hal_log_err("dmic request dma channel error\n");
|
|
return;
|
|
}
|
|
|
|
hal_dma_chan_register_cb(info->dma_chan, dma_transfer_period_callback,
|
|
(void *)info);
|
|
hal_dma_chan_config(info->dma_chan, &config);
|
|
/* Configure DMA transfer */
|
|
hal_dma_chan_prep_cyclic(info->dma_chan, (ulong)info->buf_info.buf,
|
|
info->buf_info.buf_len, info->buf_info.period_len,
|
|
DMA_DEV_TO_MEM);
|
|
hal_dma_chan_start(info->dma_chan);
|
|
/* flush DMIC FIFO */
|
|
hal_audio_flush_dmic_fifo(codec);
|
|
/* Enable RX global */
|
|
hal_audio_enable_rx_global(codec);
|
|
/* Enable DMIC ADOUT SHIFT */
|
|
hal_audio_enable_dmic_adout_shift(codec);
|
|
/* Enable DMIC DRQ */
|
|
hal_audio_dmic_enable_drq(codec);
|
|
}
|
|
|
|
void hal_audio_amic_start(aic_audio_ctrl *codec)
|
|
{
|
|
struct dma_slave_config config;
|
|
struct aic_audio_transfer_info *info;
|
|
|
|
config.direction = DMA_DEV_TO_MEM;
|
|
config.src_addr = codec->reg_base + ADC_RXFIFO_DATA_REG;
|
|
config.slave_id = 15;
|
|
config.src_maxburst = 1;
|
|
config.dst_maxburst = 1;
|
|
|
|
/* amic only support mono */
|
|
config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
|
config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
|
|
|
info = &codec->amic_info;
|
|
|
|
info->transfer_type = AUDIO_TRANSFER_TYPE_AMIC;
|
|
|
|
info->dma_chan = hal_request_dma_chan();
|
|
if (!info->dma_chan) {
|
|
hal_log_err("amic request dma channel error\n");
|
|
return;
|
|
}
|
|
|
|
hal_dma_chan_register_cb(info->dma_chan, dma_transfer_period_callback,
|
|
(void *)info);
|
|
|
|
hal_dma_chan_config(info->dma_chan, &config);
|
|
/* Configure DMA transfer */
|
|
hal_dma_chan_prep_cyclic(info->dma_chan, (ulong)info->buf_info.buf,
|
|
info->buf_info.buf_len, info->buf_info.period_len,
|
|
DMA_DEV_TO_MEM);
|
|
hal_dma_chan_start(info->dma_chan);
|
|
/* flush AMIC FIFO */
|
|
hal_audio_flush_amic_fifo(codec);
|
|
/* Enable RX global */
|
|
hal_audio_enable_rx_global(codec);
|
|
/* Enable DMIC DRQ */
|
|
hal_audio_amic_enable_drq(codec);
|
|
}
|
|
|
|
void hal_audio_playback_stop(aic_audio_ctrl *codec)
|
|
{
|
|
struct aic_audio_transfer_info *info;
|
|
|
|
info = &codec->tx_info;
|
|
|
|
hal_audio_tx_disable_drq(codec);
|
|
hal_audio_disable_tx_global(codec);
|
|
hal_dma_chan_stop(info->dma_chan);
|
|
hal_release_dma_chan(info->dma_chan);
|
|
}
|
|
|
|
void hal_audio_dmic_stop(aic_audio_ctrl *codec)
|
|
{
|
|
struct aic_audio_transfer_info *info;
|
|
|
|
info = &codec->dmic_info;
|
|
|
|
hal_audio_dmic_disable_drq(codec);
|
|
hal_audio_disable_rx_global(codec);
|
|
hal_dma_chan_stop(info->dma_chan);
|
|
hal_release_dma_chan(info->dma_chan);
|
|
}
|
|
|
|
void hal_audio_amic_stop(aic_audio_ctrl *codec)
|
|
{
|
|
struct aic_audio_transfer_info *info;
|
|
|
|
info = &codec->amic_info;
|
|
|
|
hal_audio_amic_disable_drq(codec);
|
|
hal_audio_disable_rx_global(codec);
|
|
hal_dma_chan_stop(info->dma_chan);
|
|
hal_release_dma_chan(info->dma_chan);
|
|
}
|
|
|
|
void hal_audio_attach_callback(aic_audio_ctrl *codec, audio_callback callback,
|
|
void *arg)
|
|
{
|
|
codec->callback = callback;
|
|
codec->arg = arg;
|
|
}
|
|
|
|
void hal_audio_detach_callback(aic_audio_ctrl *codec)
|
|
{
|
|
codec->callback = NULL;
|
|
codec->arg = NULL;
|
|
}
|