audio: auge: add loopback + vad [1/1]

PD#TV-8989

Problem:
loopback with datain pdm, no vad to wakeup

Solution:
loopback with pdmin still works when entry freeze mode
vad works in two channel mode, mapping pdm ch0 & ch1 to vad
add channel num to loopback for vad

Verify:
x301

Change-Id: Ied244292bf2a2f668bb5a2216ec6a12964a46663
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
This commit is contained in:
Xing Wang
2019-08-30 14:33:50 +08:00
committed by Tao Zeng
parent 94f77912be
commit 05d3f2343b
7 changed files with 103 additions and 3 deletions

View File

@@ -23,6 +23,8 @@
#include <sound/pcm_params.h>
#include <linux/amlogic/pm.h>
#include "loopback.h"
#include "loopback_hw.h"
#include "loopback_match_table.c"
@@ -30,6 +32,8 @@
#include "tdm_hw.h"
#include "pdm_hw.h"
#include "vad.h"
#define DRV_NAME "loopback"
/*#define __PTM_PDM_CLK__*/
@@ -649,6 +653,10 @@ static int loopback_dai_prepare(
struct toddr_fmt fmt;
unsigned int src;
if (vad_lb_is_running(p_loopback->id) &&
pm_audio_is_suspend())
return 0;
if (p_loopback->id == 0)
src = LOOPBACK_A;
else
@@ -745,6 +753,14 @@ static int loopback_dai_trigger(
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
if (ss->stream == SNDRV_PCM_STREAM_CAPTURE) {
if (vad_lb_is_running(p_loopback->id) &&
pm_audio_is_suspend()) {
pm_audio_set_suspend(false);
/* VAD switch to alsa buffer */
vad_update_buffer(0);
break;
}
dev_info(ss->pcm->card->dev, "Loopback Capture enable\n");
pdm_fifo_reset();
@@ -765,6 +781,13 @@ static int loopback_dai_trigger(
if (ss->stream == SNDRV_PCM_STREAM_CAPTURE) {
bool toddr_stopped = false;
if (vad_lb_is_running(p_loopback->id) &&
pm_audio_is_suspend()) {
/* switch to VAD buffer */
vad_update_buffer(1);
break;
}
pdm_enable(0);
/* loopback */
@@ -1424,6 +1447,45 @@ static int loopback_platform_probe(struct platform_device *pdev)
&loopback_platform_drv);
}
static int loopback_platform_suspend(
struct platform_device *pdev, pm_message_t state)
{
struct loopback *p_loopback = dev_get_drvdata(&pdev->dev);
pr_info("%s\n", __func__);
/* whether in freeze */
if (is_pm_freeze_mode() &&
vad_lb_is_running(p_loopback->id)) {
lb_set_chnum_en(p_loopback->id, true);
vad_lb_force_two_channel(true);
pr_info("%s, Entry in freeze, p_loopback:%p\n",
__func__, p_loopback);
}
return 0;
}
static int loopback_platform_resume(
struct platform_device *pdev)
{
struct loopback *p_loopback = dev_get_drvdata(&pdev->dev);
pr_info("%s\n", __func__);
/* whether in freeze mode */
if (is_pm_freeze_mode() &&
vad_lb_is_running(p_loopback->id)) {
pr_info("%s, Exist from freeze, p_loopback:%p\n",
__func__, p_loopback);
lb_set_chnum_en(p_loopback->id, false);
vad_lb_force_two_channel(false);
}
return 0;
}
static struct platform_driver loopback_platform_driver = {
.driver = {
.name = DRV_NAME,
@@ -1431,6 +1493,8 @@ static struct platform_driver loopback_platform_driver = {
.of_match_table = of_match_ptr(loopback_device_id),
},
.probe = loopback_platform_probe,
.suspend = loopback_platform_suspend,
.resume = loopback_platform_resume,
};
module_platform_driver(loopback_platform_driver);

View File

@@ -216,3 +216,11 @@ void lb_enable(int id, bool enable)
audiobus_update_bits(reg, 0x1 << 31, enable << 31);
}
void lb_set_chnum_en(int id, bool en)
{
int offset = EE_AUDIO_LB_B_CTRL0 - EE_AUDIO_LB_A_CTRL0;
int reg = EE_AUDIO_LB_A_CTRL0 + offset * id;
audiobus_update_bits(reg, 0x1 << 27, en << 27);
}

View File

@@ -69,4 +69,6 @@ extern void lb_set_datalb_cfg(int id, struct data_cfg *datalb_cfg);
extern void lb_enable(int id, bool enable);
void lb_set_chnum_en(int id, bool en);
#endif

View File

@@ -207,6 +207,21 @@ bool vad_pdm_is_running(void)
return false;
}
bool vad_lb_is_running(int lb_id)
{
int vad_src = (lb_id == 0) ? VAD_SRC_LOOPBACK_A : VAD_SRC_LOOPBACK_B;
if (vad_is_enable() && vad_src_check(vad_src))
return true;
return false;
}
void vad_lb_force_two_channel(bool en)
{
vad_set_two_channel_en(en);
}
static void vad_notify_user_space(struct vad *p_vad)
{
pr_info("Notify to wake up user space\n");
@@ -252,9 +267,9 @@ static int vad_transfer_data_to_algorithm(
int rate, int channels, int bitdepth)
{
int ret = 0;
/* TODO: for test */
if (vad_in_kernel_test) {
if (vad_wakeup_count < 50)
return 0;
@@ -308,7 +323,7 @@ static int vad_engine_check(struct vad *p_vad)
read_bytes = frame_count * chnum * bytes_per_sample;
if (bytes < read_bytes) {
pr_debug("%s line:%d, %d bytes, need more data\n",
pr_warn("%s line:%d, %d bytes, need more data\n",
__func__, __LINE__, bytes);
return 0;
}
@@ -350,6 +365,7 @@ static int vad_engine_check(struct vad *p_vad)
}
#ifdef __VAD_DUMP_DATA__
set_fs(KERNEL_DS);
vfs_write(p_vad->fp, p_vad->buf, read_bytes, &p_vad->pos);
#endif
@@ -483,7 +499,6 @@ static int vad_init(struct vad *p_vad)
}
p_vad->fs = get_fs();
p_vad->pos = 0;
set_fs(KERNEL_DS);
#endif
} else if (p_vad->level == LEVEL_USER)

View File

@@ -36,6 +36,8 @@ extern int vad_transfer_chunk_data(unsigned long data, int frames);
extern bool vad_tdm_is_running(int tdm_idx);
extern bool vad_pdm_is_running(void);
bool vad_lb_is_running(int lb_id);
void vad_lb_force_two_channel(bool en);
extern void vad_enable(bool enable);
extern void vad_set_toddr_info(struct toddr *to);

View File

@@ -112,3 +112,9 @@ void vad_force_clk_to_oscin(bool force)
{
audiobus_update_bits(EE_AUDIO_CLK_VAD_CTRL, 0x1 << 30, force << 30);
}
void vad_set_two_channel_en(bool en)
{
/* two_channel_en */
vad_update_bits(VAD_TOP_CTRL0, 0x1 << 20, en << 20);
}

View File

@@ -37,4 +37,7 @@ extern void vad_set_in(void);
extern void vad_set_enable(bool enable);
extern void vad_force_clk_to_oscin(bool force);
void vad_set_two_channel_en(bool en);
#endif