mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
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:
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user