/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
 * Copyright (c) 2021 MediaTek Inc.
 */

#ifndef _AUDIO_LOOPBACK_H
#define _AUDIO_LOOPBACK_H
//------------------------------------------------------------------------------
//  Include Files
//------------------------------------------------------------------------------
#include "sound/asound.h"
#include "audio_loopback_dma.h"
//------------------------------------------------------------------------------
// Enumerate And Structure
//------------------------------------------------------------------------------
enum {
	LOOPBACK_REG_AEC_SIGEN_ONOFF = 0,
	LOOPBACK_REG_PCM_SLAVE_ACTIVE_ONOFF,
	LOOPBACK_REG_PCM_SLAVE_FORMAT,
	LOOPBACK_REG_PCM_SLAVE_RATE,
	LOOPBACK_REG_PCM_SLAVE_CHANNELS,
	LOOPBACK_REG_PCM_CAPTURE_SOURCE,
	LOOPBACK_REG_PCM_CHANNEL_LAYOUT,
	LOOPBACK_REG_LEN,
};

enum {
	LOOPBACK_FROM_SPEAKER = 0,
	LOOPBACK_FROM_ADC2,
	LOOPBACK_FROM_ADC1,
	LOOPBACK_FROM_I2S_RX_2CH,
	LOOPBACK_FROM_I2S_RX_4CH,
	LOOPBACK_FROM_I2S_RX_8CH,
	LOOPBACK_FROM_DIGITAL_OUT_8CH,
	LOOPBACK_FROM_PASSTHROUGH_8CH,
	LOOPBACK_FROM_MAX,
};

enum {
	CMD_STOP = 0,
	CMD_START,
	CMD_PAUSE,
	CMD_PAUSE_RELEASE,
	CMD_PREPARE,
	CMD_SUSPEND,
	CMD_RESUME,
};

enum {
	TIMER_WAIT_EVENT,
	TIMER_TRIGGER_EVENT,
	TIMER_STOP_EVENT,
};

/* Define a Monitor data structure */
struct mtk_monitor_struct {
	unsigned int monitor_status;
	unsigned int expiration_counter;
	snd_pcm_uframes_t last_appl_ptr;
	snd_pcm_uframes_t last_hw_ptr;
};

/* Define a Runtime data structure */
struct mtk_runtime_struct {
	struct snd_pcm_substream *substream;
	struct mtk_monitor_struct monitor;
	struct timer_list timer;
	wait_queue_head_t kthread_waitq;
	struct mutex kthread_lock;
	spinlock_t spin_lock;
	int timer_notify;
};

struct mtk_snd_loopback {
	struct device *dev;
	struct snd_card *card;
	struct snd_pcm *pcm;
	struct audio_loopback_dma_struct aec_dma_buf;
	struct audio_loopback_dma_struct dsp_dma_buf;
	struct audio_loopback_dma_struct dsp_pb_dma_buf;
	struct mem_info aec_mem_info;
	struct mem_info dsp_mem_info;
	struct mem_info dsp_pb_mem_info;
	struct mtk_copy_buffer_struct capture_buf;
	struct mtk_copy_buffer_struct playback_buf;
	struct mtk_runtime_struct dev_runtime;
	struct mtk_runtime_struct dev_play_runtime;
	struct task_struct *play_task;
	struct task_struct *capture_task;
	struct timespec64 pcm_capture_ts;
	struct mutex loopback_pcm_lock;
	struct list_head list;

	uint32_t slt_test_config;
	int dsp_mixing_mode;
	int dsp_capture_source;
	int i2s_input_channel;
	int i2s_input_layout;
	int aec_max_channel;
	int dsp_max_channel;
	int dsp_channels_num;
	int *dsp_channel_list;

	u32 aec_dma_offset;
	u32 aec_dma_size;
	u32 dsp_dma_offset;
	u32 dsp_dma_size;
	u32 dsp_pb_dma_offset;
	u32 dsp_pb_dma_size;

	//capture case
	bool loopback_aec_enabled;
	bool loopback_aec_bypass;

	//pcm status
	bool loopback_pcm_running;
	bool loopback_pcm_xrun;
	bool loopback_pcm_sw_running;
	bool loopback_pcm_sw_running_stopped;
	bool loopback_pcm_playback_running;
};

#endif /* _AUDIO_LOOPBACK_H */
