From 05d3f2343bf45649cfd4e3c4d825cb76c9d33248 Mon Sep 17 00:00:00 2001 From: Xing Wang Date: Fri, 30 Aug 2019 14:33:50 +0800 Subject: [PATCH] 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 --- sound/soc/amlogic/auge/loopback.c | 64 ++++++++++++++++++++++++++++++++++++ sound/soc/amlogic/auge/loopback_hw.c | 8 +++++ sound/soc/amlogic/auge/loopback_hw.h | 2 ++ sound/soc/amlogic/auge/vad.c | 21 ++++++++++-- sound/soc/amlogic/auge/vad.h | 2 ++ sound/soc/amlogic/auge/vad_hw.c | 6 ++++ sound/soc/amlogic/auge/vad_hw.h | 3 ++ 7 files changed, 103 insertions(+), 3 deletions(-) diff --git a/sound/soc/amlogic/auge/loopback.c b/sound/soc/amlogic/auge/loopback.c index 767f720..d8b1fb0 100644 --- a/sound/soc/amlogic/auge/loopback.c +++ b/sound/soc/amlogic/auge/loopback.c @@ -23,6 +23,8 @@ #include +#include + #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); diff --git a/sound/soc/amlogic/auge/loopback_hw.c b/sound/soc/amlogic/auge/loopback_hw.c index 0508769..8b23f13 100644 --- a/sound/soc/amlogic/auge/loopback_hw.c +++ b/sound/soc/amlogic/auge/loopback_hw.c @@ -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); +} diff --git a/sound/soc/amlogic/auge/loopback_hw.h b/sound/soc/amlogic/auge/loopback_hw.h index 776299a..a64afc4 100644 --- a/sound/soc/amlogic/auge/loopback_hw.h +++ b/sound/soc/amlogic/auge/loopback_hw.h @@ -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 diff --git a/sound/soc/amlogic/auge/vad.c b/sound/soc/amlogic/auge/vad.c index 5f09029..be941b5 100644 --- a/sound/soc/amlogic/auge/vad.c +++ b/sound/soc/amlogic/auge/vad.c @@ -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) diff --git a/sound/soc/amlogic/auge/vad.h b/sound/soc/amlogic/auge/vad.h index f3964a3..610179a 100644 --- a/sound/soc/amlogic/auge/vad.h +++ b/sound/soc/amlogic/auge/vad.h @@ -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); diff --git a/sound/soc/amlogic/auge/vad_hw.c b/sound/soc/amlogic/auge/vad_hw.c index ba9b2d5..c9b7259 100644 --- a/sound/soc/amlogic/auge/vad_hw.c +++ b/sound/soc/amlogic/auge/vad_hw.c @@ -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); +} diff --git a/sound/soc/amlogic/auge/vad_hw.h b/sound/soc/amlogic/auge/vad_hw.h index af0659c..2e22168 100644 --- a/sound/soc/amlogic/auge/vad_hw.h +++ b/sound/soc/amlogic/auge/vad_hw.h @@ -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 -- 2.7.4