audio: auge: add loopback + vad [1/1]
authorXing Wang <xing.wang@amlogic.com>
Fri, 30 Aug 2019 06:33:50 +0000 (14:33 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Thu, 5 Sep 2019 05:29:35 +0000 (22:29 -0700)
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>
sound/soc/amlogic/auge/loopback.c
sound/soc/amlogic/auge/loopback_hw.c
sound/soc/amlogic/auge/loopback_hw.h
sound/soc/amlogic/auge/vad.c
sound/soc/amlogic/auge/vad.h
sound/soc/amlogic/auge/vad_hw.c
sound/soc/amlogic/auge/vad_hw.h

index 767f720..d8b1fb0 100644 (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);
 
index 0508769..8b23f13 100644 (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);
+}
index 776299a..a64afc4 100644 (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
index 5f09029..be941b5 100644 (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)
index f3964a3..610179a 100644 (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);
index ba9b2d5..c9b7259 100644 (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);
+}
index af0659c..2e22168 100644 (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