#include <sound/pcm_params.h>
+#include <linux/amlogic/pm.h>
+
#include "loopback.h"
#include "loopback_hw.h"
#include "loopback_match_table.c"
#include "tdm_hw.h"
#include "pdm_hw.h"
+#include "vad.h"
+
#define DRV_NAME "loopback"
/*#define __PTM_PDM_CLK__*/
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
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();
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 */
&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,
.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);
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");
int rate, int channels, int bitdepth)
{
int ret = 0;
+
/* TODO: for test */
if (vad_in_kernel_test) {
-
if (vad_wakeup_count < 50)
return 0;
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;
}
}
#ifdef __VAD_DUMP_DATA__
+ set_fs(KERNEL_DS);
vfs_write(p_vad->fp, p_vad->buf, read_bytes, &p_vad->pos);
#endif
}
p_vad->fs = get_fs();
p_vad->pos = 0;
- set_fs(KERNEL_DS);
#endif
} else if (p_vad->level == LEVEL_USER)