// SPDX-License-Identifier: GPL-2.0
/*
 * mt8532-afe-controls.c  --  Mediatek 8532 audio controls
 *
 * Copyright (c) 2020 MediaTek Inc.
 * Author: Wen Cai <wen.cai@mediatek.com>
 */

#include "mt8532-afe-controls.h"
#include "mt8532-afe-common.h"
#include "mt8532-reg.h"
#include "mt8532-afe-utils.h"
#include "../common/mtk-base-afe.h"
#include <sound/soc.h>
#include <linux/kernel.h>

#define ENUM_TO_STR(enum) #enum

#define MT8532_APLL_ADJUST_RANGE 163840
#define MT8532_AFE_MAX_FS 384000

enum mixer_control_func {
	CTRL_SINEGEN_LOOPBACK_MODE = 0,
	CTRL_SINEGEN_TIMING,
	CTRL_ETDM_IN_DATA_SRC,
	CTRL_ETDM_IN_SLAVE_MODE_SRC,
	CTRL_TDMOUT_CONN_SRC,
	CTRL_MULTI_IN_BCK_SEL,
	CTRL_MULTI_IN_LRCK_SEL,
	CTRL_MULTI_IN_SDATA0_SEL,
	CTRL_MULTI_IN_SDATA1_SEL,
	CTRL_MULTI_IN_SDATA2_SEL,
	CTRL_MULTI_IN_SDATA3_SEL,
	CTRL_MULTI_IN2_BCK_SEL,
	CTRL_MULTI_IN2_LRCK_SEL,
	CTRL_MULTI_IN2_SDATA0_SEL,
	CTRL_MULTI_IN2_SDATA1_SEL,
	CTRL_MULTI_IN2_SDATA2_SEL,
	CTRL_MULTI_IN2_SDATA3_SEL,
	CTRL_SPDIF_IN_PORT_SEL,
	CTRL_MULTI_IN_DATA_SRC,
	CTRL_ENGENSYS_DOMAIN,
	CTRL_ETDM_MOD,
	CTRL_ETDM_DSD_BIT,
	CTRL_ETDM_DSD_CLK,
	CTRL_AUDIO_IN_SEL,
	CTRL_APLL_TUNER_RANGE_SEL,
	CTRL_MULTI_IN_IRQ_MODE_SEL,
	CTRL_ETDM_OUT_DATA_SRC,
	CTRL_ETDM_OUT1_SDATA_SEL,
	CTRL_ETDM_OUT1_FORCE_ON_SEL,
	CTRL_ETDM_OUT2_FORCE_ON_SEL,
};

enum multi_in_data_src {
	MULTI_IN_FROM_SPLIN = 0,
	MULTI_IN_FROM_ETDM_OUT3,
	MULTI_IN_FROM_ETDM_IN2_EXT,
	MULTI_IN_FROM_EARC,
	MULTI_IN_FROM_HDMIRX,
	MULTI_IN_FROM_AUD2_HDMI,
};

enum sinegen_loopback_mode {
	SINEGEN_O02_O33_CM0 = 0,
	SINEGEN_O26_O27_UL9 = 0x11,
	SINEGEN_O40_O47_CM1 = 0x12,
	SINEGEN_O40_O41_UL2 = 0x16,
	SINEGEN_O00_O01_PCMTX = 0x17,
	SINEGEN_O36_O37_UL5 = 0x18,
	SINEGEN_O38_O39_UL10 = 0x1d,
	SINEGEN_UL3 = 0x1e,
	SINEGEN_O34_O35_UL4 = 0x1f,
	SINEGEN_O96_O97_GASRC0_IN = 0x25,
	SINEGEN_I40_I41,
	SINEGEN_I42_I47,
	SINEGEN_O00_O01,
	SINEGEN_O02_O03,
	SINEGEN_O04_O11,
	SINEGEN_O12_O13,
	SINEGEN_O14_O15,
	SINEGEN_O16_O17,
	SINEGEN_O20_O21,
	SINEGEN_O42_O43,
	SINEGEN_O44_O45,
	SINEGEN_O46_O47,
	SINEGEN_O48_O49,
	SINEGEN_O26_O41,
	SINEGEN_UL9,
	SINEGEN_UL2,
	SINEGEN_NONE,
};

enum sinegen_timing {
	SINEGEN_8K_A1 = 0,
	SINEGEN_12K_A1,
	SINEGEN_16K_A1,
	SINEGEN_24K_A1,
	SINEGEN_32K_A1,
	SINEGEN_48K_A1,
	SINEGEN_96K_A1,
	SINEGEN_192K_A1,
	SINEGEN_384K_A1,
	SINEGEN_ETDMOUT1_1X,
	SINEGEN_ETDMOUT2_1X,
	SINEGEN_ETDMOUT3_1X,
	SINEGEN_ETDMIN1_1X,
	SINEGEN_ETDMIN2_1X,
	SINEGEN_EXT_PCM_1X,
	SINEGEN_7D35K_A2,
	SINEGEN_11D025K_A2,
	SINEGEN_14D7K_A2,
	SINEGEN_22D05K_A2,
	SINEGEN_29D4K_A2,
	SINEGEN_44D1K_A2,
	SINEGEN_88D2K_A2,
	SINEGEN_176D4K_A2,
	SINEGEN_352D8K_A2,
	SINEGEN_ETDMIN1_NX,
	SINEGEN_ETDMIN2_NX,
	SINEGEN_8K_A3,
	SINEGEN_12K_A3,
	SINEGEN_16K_A3,
	SINEGEN_24K_A3,
	SINEGEN_32K_A3,
	SINEGEN_48K_A3,
	SINEGEN_96K_A3,
	SINEGEN_192K_A3,
	SINEGEN_384K_A3,
	SINEGEN_8K_A4,
	SINEGEN_12K_A4,
	SINEGEN_16K_A4,
	SINEGEN_24K_A4,
	SINEGEN_32K_A4,
	SINEGEN_48K_A4,
	SINEGEN_96K_A4,
	SINEGEN_192K_A4,
	SINEGEN_384K_A4,
	SINEGEN_SGEN_ERR,
};

enum etdm_in_data_src {
	ETDM_IN_FROM_PAD = 0,
	ETDM_IN_FROM_ETDM_OUT1,
	ETDM_IN_FROM_ETDM_OUT2,
	ETDM_IN_FROM_ETDM_OUT3,
};

enum etdm_out_data_src {
	ETDM_OUT_FROM_ETDM_OUT1,
	ETDM_OUT_FROM_ETDM_OUT2,
	ETDM_OUT_FROM_ETDM_OUT3,
};

enum etdm_in_slave_mode_src {
	ETDM_IN_SLAVE_FROM_SELF = 0,
	ETDM_IN_SLAVE_FROM_ETDM_OUT1,
	ETDM_IN_SLAVE_FROM_ETDM_OUT2,
	ETDM_IN_SLAVE_FROM_ETDM_OUT3,
};

enum tdmout_conn_src {
	I00 = 0,
	I01,
	I02,
	I03,
	I04,
	I05,
	I06,
	I07,
	I08,
	I09,
	I10,
	I11,
	I12,
	I13,
	I14,
	I15,
};

static const char *const etdm_mod_sel_func[] = {
	ENUM_TO_STR(PCM_MOD),
	ENUM_TO_STR(DSD_MOD),
};

static const char *const etdm_dsd_bit_sel_func[] = {
	ENUM_TO_STR(DSD_8_BIT),
	ENUM_TO_STR(DSD_16_BIT),
	ENUM_TO_STR(DSD_24_BIT),
	ENUM_TO_STR(DSD_32_BIT),
};

static const char *const etdm_dsd_clk_sel_func[] = {
	ENUM_TO_STR(DSD_2P8M),
	ENUM_TO_STR(DSD_5P6M),
	ENUM_TO_STR(DSD_11P2M),
};

static const char *const aud_in_sel_func[] = {
	ENUM_TO_STR(AUD_IN_NONE),
	ENUM_TO_STR(AUD_IN_EARC),
	ENUM_TO_STR(AUD_IN_SPDIF),
	ENUM_TO_STR(AUD_IN_HDMIRX),
};

static const char *const apll_tuner_range_sel_func[] = {
	ENUM_TO_STR(APLL_TUNER_RANGE_NONE),
	ENUM_TO_STR(APLL_TUNER_RANGE_10HZ),
	ENUM_TO_STR(APLL_TUNER_RANGE_20HZ),
	ENUM_TO_STR(APLL_TUNER_RANGE_30HZ),
	ENUM_TO_STR(APLL_TUNER_RANGE_40HZ),
	ENUM_TO_STR(APLL_TUNER_RANGE_48HZ),
	ENUM_TO_STR(APLL_TUNER_RANGE_50HZ),
	ENUM_TO_STR(APLL_TUNER_RANGE_60HZ),
	ENUM_TO_STR(APLL_TUNER_RANGE_96HZ),
};

static const char *const engen_apll_sel_func[] = {
	ENUM_TO_STR(FS_ENGEN_A1SYS),
	ENUM_TO_STR(FS_ENGEN_A2SYS),
	ENUM_TO_STR(FS_ENGEN_A3SYS),
	ENUM_TO_STR(FS_ENGEN_A4SYS),
	ENUM_TO_STR(FS_ENGEN_26M),
};

static const char *const multi_in_data_src_func[] = {
	ENUM_TO_STR(MULTI_IN_FROM_SPLIN),
	ENUM_TO_STR(MULTI_IN_FROM_ETDM_OUT3),
	ENUM_TO_STR(MULTI_IN_FROM_ETDM_IN2_EXT),
	ENUM_TO_STR(MULTI_IN_FROM_EARC),
	ENUM_TO_STR(MULTI_IN_FROM_HDMIRX),
	ENUM_TO_STR(MULTI_IN_FROM_AUD2_HDMI),
};

enum multi_in_irq_mode {
	MULTI_IN_IRQ_DIRECT_MODE = 0,
	MULTI_IN_IRQ_CNT_MODE,
};

static const char *const multi_in_irq_mode_sel[] = {
	ENUM_TO_STR(MULTI_IN_IRQ_DIRECT_MODE),
	ENUM_TO_STR(MULTI_IN_IRQ_CNT_MODE),
};

static const char *const etdm_out_data_src_func[] = {
	ENUM_TO_STR(ETDM_OUT_FROM_ETDM_OUT1),
	ENUM_TO_STR(ETDM_OUT_FROM_ETDM_OUT2),
	ENUM_TO_STR(ETDM_OUT_FROM_ETDM_OUT3),
};

static const char *const etdm_out1_force_on_sel_func[] = {
	ENUM_TO_STR(FORCE_ON_NONE),
	ENUM_TO_STR(FORCE_ON_48K),
	ENUM_TO_STR(FORCE_ON_96K),
	ENUM_TO_STR(FORCE_ON_192K),
	ENUM_TO_STR(FORCE_ON_44D1K),
    ENUM_TO_STR(FORCE_ON_88D2K),
};

static const char *const etdm_out2_force_on_sel_func[] = {
	ENUM_TO_STR(FORCE_ON_NONE),
	ENUM_TO_STR(FORCE_ON_48K),
	ENUM_TO_STR(FORCE_ON_96K),
	ENUM_TO_STR(FORCE_ON_192K),
};

static const char *const sinegen_loopback_mode_func[] = {
	ENUM_TO_STR(SINEGEN_I00_I01),
	ENUM_TO_STR(SINEGEN_I02_I03),
	ENUM_TO_STR(SINEGEN_I04_I11),
	ENUM_TO_STR(SINEGEN_I12_I19),
	ENUM_TO_STR(SINEGEN_I20_I21),
	ENUM_TO_STR(SINEGEN_I22_I29),
	ENUM_TO_STR(SINEGEN_I32_I33),
	ENUM_TO_STR(SINEGEN_I34_I35),
	ENUM_TO_STR(SINEGEN_I36_I37),
	ENUM_TO_STR(SINEGEN_I38_I39),
	ENUM_TO_STR(SINEGEN_I40_I41),
	ENUM_TO_STR(SINEGEN_I42_I47),
	ENUM_TO_STR(SINEGEN_O00_O01),
	ENUM_TO_STR(SINEGEN_O02_O03),
	ENUM_TO_STR(SINEGEN_O04_O11),
	ENUM_TO_STR(SINEGEN_O12_O13),
	ENUM_TO_STR(SINEGEN_O14_O15),
	ENUM_TO_STR(SINEGEN_O16_O17),
	ENUM_TO_STR(SINEGEN_O20_O21),
	ENUM_TO_STR(SINEGEN_O42_O43),
	ENUM_TO_STR(SINEGEN_O44_O45),
	ENUM_TO_STR(SINEGEN_O46_O47),
	ENUM_TO_STR(SINEGEN_O48_O49),
	ENUM_TO_STR(SINEGEN_O26_O41),
	ENUM_TO_STR(SINEGEN_UL9),
	ENUM_TO_STR(SINEGEN_UL2),
	ENUM_TO_STR(SINEGEN_NONE),
};

static const char *const sinegen_timing_func[] = {
	ENUM_TO_STR(SINEGEN_8K_A1),
	ENUM_TO_STR(SINEGEN_12K_A1),
	ENUM_TO_STR(SINEGEN_16K_A1),
	ENUM_TO_STR(SINEGEN_24K_A1),
	ENUM_TO_STR(SINEGEN_32K_A1),
	ENUM_TO_STR(SINEGEN_48K_A1),
	ENUM_TO_STR(SINEGEN_96K_A1),
	ENUM_TO_STR(SINEGEN_192K_A1),
	ENUM_TO_STR(SINEGEN_384K_A1),

	ENUM_TO_STR(SINEGEN_ETDMOUT1_1X),
	ENUM_TO_STR(SINEGEN_ETDMOUT2_1X),
	ENUM_TO_STR(SINEGEN_ETDMOUT3_1X),
	ENUM_TO_STR(SINEGEN_ETDMIN1_1X),
	ENUM_TO_STR(SINEGEN_ETDMIN2_1X),
	ENUM_TO_STR(SINEGEN_EXT_PCM_1X),

	ENUM_TO_STR(SINEGEN_7D35K_A2),
	ENUM_TO_STR(SINEGEN_11D025K_A2),
	ENUM_TO_STR(SINEGEN_14D7K_A2),
	ENUM_TO_STR(SINEGEN_22D05K_A2),
	ENUM_TO_STR(SINEGEN_29D4K_A2),
	ENUM_TO_STR(SINEGEN_44D1K_A2),
	ENUM_TO_STR(SINEGEN_88D2K_A2),
	ENUM_TO_STR(SINEGEN_176D4K_A2),
	ENUM_TO_STR(SINEGEN_352D8K_A2),

	ENUM_TO_STR(SINEGEN_ETDMIN1_NX),
	ENUM_TO_STR(SINEGEN_ETDMIN2_NX),

	ENUM_TO_STR(SINEGEN_8K_A3),
	ENUM_TO_STR(SINEGEN_12K_A3),
	ENUM_TO_STR(SINEGEN_16K_A3),
	ENUM_TO_STR(SINEGEN_24K_A3),
	ENUM_TO_STR(SINEGEN_32K_A3),
	ENUM_TO_STR(SINEGEN_48K_A3),
	ENUM_TO_STR(SINEGEN_96K_A3),
	ENUM_TO_STR(SINEGEN_192K_A3),
	ENUM_TO_STR(SINEGEN_384K_A3),
	ENUM_TO_STR(SINEGEN_8K_A4),
	ENUM_TO_STR(SINEGEN_12K_A4),
	ENUM_TO_STR(SINEGEN_16K_A4),
	ENUM_TO_STR(SINEGEN_24K_A4),
	ENUM_TO_STR(SINEGEN_32K_A4),
	ENUM_TO_STR(SINEGEN_48K_A4),
	ENUM_TO_STR(SINEGEN_96K_A4),
	ENUM_TO_STR(SINEGEN_192K_A4),
	ENUM_TO_STR(SINEGEN_384K_A4),
};

static const char *const etdm_in_data_src_func[] = {
	ENUM_TO_STR(ETDM_IN_FROM_PAD),
	ENUM_TO_STR(ETDM_IN_FROM_ETDM_OUT1),
	ENUM_TO_STR(ETDM_IN_FROM_ETDM_OUT2),
	ENUM_TO_STR(ETDM_IN_FROM_ETDM_OUT3),
};

static const char *const etdm_in_slave_mode_src_func[] = {
	ENUM_TO_STR(ETDM_IN_SLAVE_FROM_SELF),
	ENUM_TO_STR(ETDM_IN_SLAVE_FROM_ETDM_OUT1),
	ENUM_TO_STR(ETDM_IN_SLAVE_FROM_ETDM_OUT2),
	ENUM_TO_STR(ETDM_IN_SLAVE_FROM_ETDM_OUT3),
};

static const char *const tdmout_conn_src_func[] = {
	ENUM_TO_STR(I00),
	ENUM_TO_STR(I01),
	ENUM_TO_STR(I02),
	ENUM_TO_STR(I03),
	ENUM_TO_STR(I04),
	ENUM_TO_STR(I05),
	ENUM_TO_STR(I06),
	ENUM_TO_STR(I07),
	ENUM_TO_STR(I08),
	ENUM_TO_STR(I09),
	ENUM_TO_STR(I10),
	ENUM_TO_STR(I11),
	ENUM_TO_STR(I12),
	ENUM_TO_STR(I13),
	ENUM_TO_STR(I14),
	ENUM_TO_STR(I15),
};

static const char *const multi_in_bck_sel_func[] = {
	"SPLIN_BCK",
	"ETDM_IN2_SLAVE_BCK",
	"NO_BCK",
	"EARC_INT_BCK",
	"NO_BCK",
	"ETDM_OUT3_MASTER_BCK",
	"HDMIRX_INT_BCK",
	"AUD2_HDMI_BCK",
};

static const char *const multi_in_lrck_sel_func[] = {
	"SPLIN_LRCK",
	"ETDM_IN2_SLAVE_LRCK",
	"AUD2_HDMI_LRCK",
	"EARC_INT_LRCK",
	"AUD2_HDMI_SDATA4",
	"ETDM_OUT3_MASTER_LRCK",
	"HDMIRX_INT_LRCK",
	"ETDM_OUT3_SDATA4",
};

static const char *const multi_in_sdata_sel_func[] = {
	"SPLIN_SDATA",
	"ETDM_OUT3_SDATA",
	"ETDM_IN2_SDATA",
	"EARC_SDATA",
	"HDMIRX_INT_SDATA",
	"NO_SDATA",
	"AUD2_HDMI_SDATA",
};

static const char *const multi_in2_bck_sel_func[] = {
	"SPLIN_BCK",
	"ETDM_IN2_SLAVE_BCK",
	"SPLIN_BCK",
	"EARC_INT_BCK",
	"SPLIN_BCK",
	"ETDM_OUT3_MASTER_BCK",
	"HDMIRX_INT_BCK",
	"SPLIN_BCK",
};

static const char *const multi_in2_lrck_sel_func[] = {
	"SPLIN_LRCK",
	"ETDM_IN2_SLAVE_LRCK",
	"SPLIN_LRCK",
	"EARC_INT_LRCK",
	"SPLIN_LRCK",
	"ETDM_OUT3_MASTER_LRCK",
	"HDMIRX_INT_LRCK",
	"ETDM_OUT3_SDATA4",
};

static const char *const multi_in2_sdata_sel_func[] = {
	"SPLIN_SDATA",
	"ETDM_OUT3_SDATA",
	"ETDM_IN2_SDATA",
	"EARC_SDATA",
	"HDMIRX_INT_SDATA",
	"SPLIN_SDATA",
};

static const char *const spdif_in_port_sel_func[] = {
	ENUM_TO_STR(SPDIF_IN_PORT_NONE),
	ENUM_TO_STR(SPDIF_IN_PORT_OPT),
	ENUM_TO_STR(SPDIF_IN_PORT_COAXIAL),
	ENUM_TO_STR(SPDIF_IN_PORT_ARC),
};

static const struct soc_enum mt8532_afe_soc_enums[] = {
	[CTRL_MULTI_IN_DATA_SRC] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(multi_in_data_src_func),
				    multi_in_data_src_func),
	[CTRL_SINEGEN_LOOPBACK_MODE] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sinegen_loopback_mode_func),
				    sinegen_loopback_mode_func),
	[CTRL_SINEGEN_TIMING] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sinegen_timing_func),
				    sinegen_timing_func),
	[CTRL_ETDM_IN_DATA_SRC] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(etdm_in_data_src_func),
				    etdm_in_data_src_func),
	[CTRL_ETDM_IN_SLAVE_MODE_SRC] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(etdm_in_slave_mode_src_func),
				    etdm_in_slave_mode_src_func),
	[CTRL_TDMOUT_CONN_SRC] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdmout_conn_src_func),
				    tdmout_conn_src_func),
	[CTRL_MULTI_IN_BCK_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG0, 0,
			ARRAY_SIZE(multi_in_bck_sel_func),
			multi_in_bck_sel_func),
	[CTRL_MULTI_IN_LRCK_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG0, 3,
			ARRAY_SIZE(multi_in_lrck_sel_func),
			multi_in_lrck_sel_func),
	[CTRL_MULTI_IN_SDATA0_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG0, 6,
			ARRAY_SIZE(multi_in_sdata_sel_func),
			multi_in_sdata_sel_func),
	[CTRL_MULTI_IN_SDATA1_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG0, 9,
			ARRAY_SIZE(multi_in_sdata_sel_func),
			multi_in_sdata_sel_func),
	[CTRL_MULTI_IN_SDATA2_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG0, 12,
			ARRAY_SIZE(multi_in_sdata_sel_func),
			multi_in_sdata_sel_func),
	[CTRL_MULTI_IN_SDATA3_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG0, 15,
			ARRAY_SIZE(multi_in_sdata_sel_func),
			multi_in_sdata_sel_func),
	[CTRL_MULTI_IN2_BCK_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG2, 0,
			ARRAY_SIZE(multi_in2_bck_sel_func),
			multi_in2_bck_sel_func),
	[CTRL_MULTI_IN2_LRCK_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG2, 3,
			ARRAY_SIZE(multi_in2_lrck_sel_func),
			multi_in2_lrck_sel_func),
	[CTRL_MULTI_IN2_SDATA0_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG2, 6,
			ARRAY_SIZE(multi_in2_sdata_sel_func),
			multi_in2_sdata_sel_func),
	[CTRL_MULTI_IN2_SDATA1_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG2, 9,
			ARRAY_SIZE(multi_in2_sdata_sel_func),
			multi_in2_sdata_sel_func),
	[CTRL_MULTI_IN2_SDATA2_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG2, 12,
			ARRAY_SIZE(multi_in2_sdata_sel_func),
			multi_in2_sdata_sel_func),
	[CTRL_MULTI_IN2_SDATA3_SEL] =
		SOC_ENUM_SINGLE(AFE_LOOPBACK_CFG2, 15,
			ARRAY_SIZE(multi_in2_sdata_sel_func),
			multi_in2_sdata_sel_func),
	[CTRL_SPDIF_IN_PORT_SEL] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_in_port_sel_func),
				    spdif_in_port_sel_func),
	[CTRL_ENGENSYS_DOMAIN] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(engen_apll_sel_func),
				    engen_apll_sel_func),
	[CTRL_ETDM_MOD] =
			SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(etdm_mod_sel_func),
						etdm_mod_sel_func),
	[CTRL_ETDM_DSD_BIT] =
			SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(etdm_dsd_bit_sel_func),
						etdm_dsd_bit_sel_func),
	[CTRL_ETDM_DSD_CLK] =
			SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(etdm_dsd_clk_sel_func),
						etdm_dsd_clk_sel_func),
	[CTRL_AUDIO_IN_SEL] =
			SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(aud_in_sel_func),
						aud_in_sel_func),
	[CTRL_APLL_TUNER_RANGE_SEL] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(apll_tuner_range_sel_func),
					apll_tuner_range_sel_func),
	[CTRL_MULTI_IN_IRQ_MODE_SEL] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(multi_in_irq_mode_sel),
				multi_in_irq_mode_sel),
	[CTRL_ETDM_OUT_DATA_SRC] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(etdm_out_data_src_func),
					etdm_out_data_src_func),
	[CTRL_ETDM_OUT1_FORCE_ON_SEL] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(etdm_out1_force_on_sel_func),
				etdm_out1_force_on_sel_func),
	[CTRL_ETDM_OUT2_FORCE_ON_SEL] =
		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(etdm_out2_force_on_sel_func),
				etdm_out2_force_on_sel_func),
};

static int mt8532_afe_etdm_mod_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	const char *name = kcontrol->id.name;
	size_t i;
	unsigned int etdm_mod = PCM_MOD;
	struct {
		char *name;
		unsigned int val;
		unsigned int stream;
	} etdm_table[] = {
		{ "ETDM1_OUT",	MT8532_ETDM1, SNDRV_PCM_STREAM_PLAYBACK},
		{ "ETDM3_OUT",	MT8532_ETDM3, SNDRV_PCM_STREAM_PLAYBACK},
	};

	for (i = 0; i < ARRAY_SIZE(etdm_table); i++) {
		if (strstr(name, etdm_table[i].name)) {
			unsigned int id = etdm_table[i].val;
			unsigned int dir = etdm_table[i].stream;

			etdm_mod = afe_priv->etdm_data[id].dsd_mod[dir];
		}
	}
	ucontrol->value.integer.value[0] = etdm_mod;
	return 0;

}

static int mt8532_afe_etdm_mod_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	const char *name = kcontrol->id.name;
	size_t i;
	struct {
		char *name;
		unsigned int val;
		unsigned int stream;
	} etdm_table[] = {
		{ "ETDM1_OUT",	MT8532_ETDM1, SNDRV_PCM_STREAM_PLAYBACK},
		{ "ETDM3_OUT",	MT8532_ETDM3, SNDRV_PCM_STREAM_PLAYBACK},
	};

	for (i = 0; i < ARRAY_SIZE(etdm_table); i++) {
		if (strstr(name, etdm_table[i].name)) {
			unsigned int id = etdm_table[i].val;
			unsigned int dir = etdm_table[i].stream;

			afe_priv->etdm_data[id].dsd_mod[dir] =
				ucontrol->value.integer.value[0];
		}
	}
	return 0;
}

static int mt8532_afe_etdm_dsd_bit_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	const char *name = kcontrol->id.name;
	size_t i;
	unsigned int dsd_bit = DSD_8_BIT;
	struct {
		char *name;
		unsigned int val;
		unsigned int stream;
	} etdm_table[] = {
		{ "ETDM1_OUT",	MT8532_ETDM1, SNDRV_PCM_STREAM_PLAYBACK},
		{ "ETDM3_OUT",	MT8532_ETDM3, SNDRV_PCM_STREAM_PLAYBACK},
	};

	for (i = 0; i < ARRAY_SIZE(etdm_table); i++) {
		if (strstr(name, etdm_table[i].name)) {
			unsigned int id = etdm_table[i].val;
			unsigned int dir = etdm_table[i].stream;

			dsd_bit = afe_priv->etdm_data[id].dsd_bit[dir];
		}
	}
	ucontrol->value.integer.value[0] = dsd_bit;
	return 0;

}

static int mt8532_afe_etdm_dsd_bit_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	const char *name = kcontrol->id.name;
	size_t i;
	struct {
		char *name;
		unsigned int val;
		unsigned int stream;
	} etdm_table[] = {
		{ "ETDM1_OUT",	MT8532_ETDM1, SNDRV_PCM_STREAM_PLAYBACK},
		{ "ETDM3_OUT",	MT8532_ETDM3, SNDRV_PCM_STREAM_PLAYBACK},
	};

	for (i = 0; i < ARRAY_SIZE(etdm_table); i++) {
		if (strstr(name, etdm_table[i].name)) {
			unsigned int id = etdm_table[i].val;
			unsigned int dir = etdm_table[i].stream;

			afe_priv->etdm_data[id].dsd_bit[dir] =
				ucontrol->value.integer.value[0];
		}
	}
	return 0;
}

static int mt8532_afe_etdm_dsd_clk_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	const char *name = kcontrol->id.name;
	size_t i;
	unsigned int dsd_clk = DSD_2P8M;
	struct {
		char *name;
		unsigned int val;
		unsigned int stream;
	} etdm_table[] = {
		{ "ETDM1_OUT",	MT8532_ETDM1, SNDRV_PCM_STREAM_PLAYBACK},
		{ "ETDM3_OUT",	MT8532_ETDM3, SNDRV_PCM_STREAM_PLAYBACK},
	};

	for (i = 0; i < ARRAY_SIZE(etdm_table); i++) {
		if (strstr(name, etdm_table[i].name)) {
			unsigned int id = etdm_table[i].val;
			unsigned int dir = etdm_table[i].stream;

			dsd_clk = afe_priv->etdm_data[id].dsd_clk[dir];
		}
	}
	ucontrol->value.integer.value[0] = dsd_clk;
	return 0;

}

static int mt8532_afe_etdm_dsd_clk_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	const char *name = kcontrol->id.name;
	size_t i;
	struct {
		char *name;
		unsigned int val;
		unsigned int stream;
	} etdm_table[] = {
		{ "ETDM1_OUT",	MT8532_ETDM1, SNDRV_PCM_STREAM_PLAYBACK},
		{ "ETDM3_OUT",	MT8532_ETDM3, SNDRV_PCM_STREAM_PLAYBACK},
	};

	for (i = 0; i < ARRAY_SIZE(etdm_table); i++) {
		if (strstr(name, etdm_table[i].name)) {
			unsigned int id = etdm_table[i].val;
			unsigned int dir = etdm_table[i].stream;

			afe_priv->etdm_data[id].dsd_clk[dir] =
				ucontrol->value.integer.value[0];
		}
	}
	return 0;
}

static int mt8532_afe_aud_in_sel_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;

	ucontrol->value.integer.value[0] = afe_priv->aud_in_sel;

	return 0;
}

static int mt8532_afe_aud_in_sel_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	struct mt8532_afe_ext_clk_tune_data *clk_tune = &afe_priv->clk_tune;
	int fe = MT8532_AFE_MEMIF_DLM;
	int be = MT8532_AFE_IO_ETDM1_OUT;

	afe_priv->aud_in_sel = ucontrol->value.integer.value[0];
	dev_info(afe->dev, "%s aud_in_sel %d\n", __func__,
		afe_priv->aud_in_sel);
	if (afe_priv->aud_in_sel == AUD_IN_HDMIRX) {
		if (clk_tune->props[CLK_TUNE_MULTI_IN2].do_tune == false
			&& !afe_priv->use_masrc_fix_output_fs) {
			dev_info(afe->dev, "%s switch apll to hdminrx apll\n", __func__);
			afe_priv->fe_data[fe].fs_1xen_sys = FS_ENGEN_A3SYS;
			afe_priv->be_data[be].fs_1xen_sys = FS_ENGEN_A3SYS;
			mt8532_afe_enable_clk(afe,
					afe_priv->clocks[MT8532_CLK_TOP_A3SYSHP_SEL]);
			mt8532_afe_set_clk_parent(afe,
					afe_priv->clocks[MT8532_CLK_TOP_A3SYSHP_SEL],
					afe_priv->clocks[MT8532_CLK_TOP_HDMIRX_APLL_D6]);
		}
	} else if (afe_priv->aud_in_sel == AUD_IN_SPDIF) {
#ifdef SUPPORT_APLL_TUNER
		if (afe_priv->apll_tuner_range != APLL_TUNER_RANGE_NONE) {
			afe_priv->fe_data[fe].fs_1xen_sys = FS_ENGEN_A4SYS;
			afe_priv->be_data[be].fs_1xen_sys = FS_ENGEN_A4SYS;
		}
#endif
	} else if (afe_priv->aud_in_sel == AUD_IN_EARC) {
#ifdef SUPPORT_APLL_TUNER
		if (afe_priv->apll_tuner_range != APLL_TUNER_RANGE_NONE) {
			afe_priv->fe_data[fe].fs_1xen_sys = FS_ENGEN_A3SYS;
			afe_priv->be_data[be].fs_1xen_sys = FS_ENGEN_A3SYS;
		}
#endif
	} else if (afe_priv->aud_in_sel == AUD_IN_NONE) {
		afe_priv->fe_data[fe].fs_1xen_sys = FS_ENGEN_A1SYS;
		afe_priv->be_data[be].fs_1xen_sys = FS_ENGEN_A1SYS;
		mt8532_afe_enable_clk(afe,
			afe_priv->clocks[MT8532_CLK_TOP_A3SYSHP_SEL]);
		mt8532_afe_set_clk_parent(afe,
			afe_priv->clocks[MT8532_CLK_TOP_A3SYSHP_SEL],
			afe_priv->clocks[MT8532_CLK_TOP_APLL3_D4]);
	}
	return 0;
}

static int mt8532_afe_apll_tuner_range_sel_get(
	struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;

	ucontrol->value.integer.value[0] = afe_priv->apll_tuner_range;

	return 0;
}

static int mt8532_afe_apll_tuner_range_sel_put(
	struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;

	afe_priv->apll_tuner_range = ucontrol->value.integer.value[0];

	return 0;
}

static int mt8532_afe_engen_apll_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	const char *name = kcontrol->id.name;
	size_t i;
	unsigned int fs_1xen_sys = FS_ENGEN_A1SYS;
	struct {
		char *name;
		unsigned int val;
	} febe_table[] = {
		{ "DLM",	MT8532_AFE_MEMIF_DLM },
		{ "DL2",	MT8532_AFE_MEMIF_DL2 },
		{ "DL3",	MT8532_AFE_MEMIF_DL3 },
		{ "DL6",	MT8532_AFE_MEMIF_DL6 },
		{ "DL7",	MT8532_AFE_MEMIF_DL7 },
		{ "DL10",	MT8532_AFE_MEMIF_DL10 },
		{ "UL1",	MT8532_AFE_MEMIF_UL1 },
		{ "UL2",	MT8532_AFE_MEMIF_UL2 },
		{ "UL3",	MT8532_AFE_MEMIF_UL3 },
		{ "UL4",	MT8532_AFE_MEMIF_UL4 },
		{ "UL5",	MT8532_AFE_MEMIF_UL5 },
		{ "UL6",	MT8532_AFE_MEMIF_UL6 },
		{ "UL8",	MT8532_AFE_MEMIF_UL8 },
		{ "UL9",	MT8532_AFE_MEMIF_UL9 },
		{ "UL10",	MT8532_AFE_MEMIF_UL10 },
		{ "ETDM1_OUT",	MT8532_AFE_IO_ETDM1_OUT },
		{ "ETDM1_IN",	MT8532_AFE_IO_ETDM1_IN },
		{ "ETDM2_OUT",	MT8532_AFE_IO_ETDM2_OUT },
		{ "ETDM2_IN",	MT8532_AFE_IO_ETDM2_IN },
		{ "ETDM3_OUT",	MT8532_AFE_IO_ETDM3_OUT },
		{ "GASRC0", MT8532_AFE_IO_GASRC0 },
		{ "GASRC1", MT8532_AFE_IO_GASRC1 },
		{ "GASRC2", MT8532_AFE_IO_GASRC2 },
		{ "GASRC3", MT8532_AFE_IO_GASRC3 },
		{ "GASRC4", MT8532_AFE_IO_GASRC4 },
		{ "GASRC5", MT8532_AFE_IO_GASRC5 },
		{ "GASRC6", MT8532_AFE_IO_GASRC6 },
		{ "GASRC7", MT8532_AFE_IO_GASRC7 },
		{ "GASRC8", MT8532_AFE_IO_GASRC8 },
		{ "GASRC9", MT8532_AFE_IO_GASRC9 },
		{ "GASRC10",	MT8532_AFE_IO_GASRC10 },
		{ "GASRC11",	MT8532_AFE_IO_GASRC11 },
		{ "GASRC12",	MT8532_AFE_IO_GASRC12 },
		{ "GASRC13",	MT8532_AFE_IO_GASRC13 },
		{ "GASRC14",	MT8532_AFE_IO_GASRC14 },
		{ "GASRC15",	MT8532_AFE_IO_GASRC15 },
		{ "GASRC16",	MT8532_AFE_IO_GASRC16 },
		{ "GASRC17",	MT8532_AFE_IO_GASRC17 },
		{ "GASRC18",	MT8532_AFE_IO_GASRC18 },
		{ "GASRC19",	MT8532_AFE_IO_GASRC19 },
	};

	for (i = 0; i < ARRAY_SIZE(febe_table); i++) {
		if (strstr(name, febe_table[i].name)) {
			unsigned int id = febe_table[i].val;

			if (id < MT8532_AFE_MEMIF_NUM)
				fs_1xen_sys = afe_priv->fe_data[id].fs_1xen_sys;
			else
				fs_1xen_sys = afe_priv->be_data[id].fs_1xen_sys;
			break;
		}
	}
	ucontrol->value.integer.value[0] = fs_1xen_sys;
	return 0;

}


static int mt8532_afe_engen_apll_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	const char *name = kcontrol->id.name;
	size_t i;
	struct {
		char *name;
		unsigned int val;
	} febe_table[] = {
		{ "DLM",	MT8532_AFE_MEMIF_DLM },
		{ "DL2",	MT8532_AFE_MEMIF_DL2 },
		{ "DL3",	MT8532_AFE_MEMIF_DL3 },
		{ "DL6",	MT8532_AFE_MEMIF_DL6 },
		{ "DL7",	MT8532_AFE_MEMIF_DL7 },
		{ "DL10",	MT8532_AFE_MEMIF_DL10 },
		{ "UL1",	MT8532_AFE_MEMIF_UL1 },
		{ "UL2",	MT8532_AFE_MEMIF_UL2 },
		{ "UL3",	MT8532_AFE_MEMIF_UL3 },
		{ "UL4",	MT8532_AFE_MEMIF_UL4 },
		{ "UL5",	MT8532_AFE_MEMIF_UL5 },
		{ "UL6",	MT8532_AFE_MEMIF_UL6 },
		{ "UL8",	MT8532_AFE_MEMIF_UL8 },
		{ "UL9",	MT8532_AFE_MEMIF_UL9 },
		{ "UL10",	MT8532_AFE_MEMIF_UL10 },
		{ "ETDM1_OUT",	MT8532_AFE_IO_ETDM1_OUT },
		{ "ETDM1_IN",	MT8532_AFE_IO_ETDM1_IN },
		{ "ETDM2_OUT",	MT8532_AFE_IO_ETDM2_OUT },
		{ "ETDM2_IN",	MT8532_AFE_IO_ETDM2_IN },
		{ "ETDM3_OUT",	MT8532_AFE_IO_ETDM3_OUT },
		{ "GASRC0",	MT8532_AFE_IO_GASRC0 },
		{ "GASRC1",	MT8532_AFE_IO_GASRC1 },
		{ "GASRC2",	MT8532_AFE_IO_GASRC2 },
		{ "GASRC3",	MT8532_AFE_IO_GASRC3 },
		{ "GASRC4",	MT8532_AFE_IO_GASRC4 },
		{ "GASRC5",	MT8532_AFE_IO_GASRC5 },
		{ "GASRC6",	MT8532_AFE_IO_GASRC6 },
		{ "GASRC7",	MT8532_AFE_IO_GASRC7 },
		{ "GASRC8",	MT8532_AFE_IO_GASRC8 },
		{ "GASRC9",	MT8532_AFE_IO_GASRC9 },
		{ "GASRC10",	MT8532_AFE_IO_GASRC10 },
		{ "GASRC11",	MT8532_AFE_IO_GASRC11 },
		{ "GASRC12",	MT8532_AFE_IO_GASRC12 },
		{ "GASRC13",	MT8532_AFE_IO_GASRC13 },
		{ "GASRC14",	MT8532_AFE_IO_GASRC14 },
		{ "GASRC15",	MT8532_AFE_IO_GASRC15 },
		{ "GASRC16",	MT8532_AFE_IO_GASRC16 },
		{ "GASRC17",	MT8532_AFE_IO_GASRC17 },
		{ "GASRC18",	MT8532_AFE_IO_GASRC18 },
		{ "GASRC19",	MT8532_AFE_IO_GASRC19 },
	};

	for (i = 0; i < ARRAY_SIZE(febe_table); i++) {
		if (strstr(name, febe_table[i].name)) {
			unsigned int id = febe_table[i].val;

			if (id < MT8532_AFE_MEMIF_NUM)
				afe_priv->fe_data[id].fs_1xen_sys =
					ucontrol->value.integer.value[0];
			else
				afe_priv->be_data[id].fs_1xen_sys =
					ucontrol->value.integer.value[0];
			break;
		}
	}

	return 0;
}

static int mt8532_afe_singen_enable_get(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int val = 0;

	mt8532_afe_enable_main_clk(afe);

	regmap_read(afe->regmap, AFE_SINEGEN_CON0, &val);

	mt8532_afe_disable_main_clk(afe);

	ucontrol->value.integer.value[0] = (val & AFE_SINEGEN_CON0_EN);

	return 0;
}

static int mt8532_afe_singen_enable_put(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	mt8532_afe_enable_main_clk(afe);

	if (ucontrol->value.integer.value[0]) {
		mt8532_afe_enable_top_cg(afe, MT8532_TOP_CG_TML);

		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
				   AFE_SINEGEN_CON0_EN,
				   AFE_SINEGEN_CON0_EN);
	} else {
		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
				   AFE_SINEGEN_CON0_EN,
				   0x0);

		mt8532_afe_disable_top_cg(afe, MT8532_TOP_CG_TML);
	}

	mt8532_afe_disable_main_clk(afe);

	return 0;
}
#ifdef CURRENTLY_AUDIO_NOT_USE
static int mt8532_afe_sinegen_loopback_mode_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int mode;
	unsigned int val;

	mt8532_afe_enable_main_clk(afe);

	regmap_read(afe->regmap, AFE_SINEGEN_CON2, &val);

	mt8532_afe_disable_main_clk(afe);

	mode = (val & AFE_SINEGEN_CON2_MODE_MASK) >> 24;

	if (mode >= SINEGEN_NONE)
		mode = SINEGEN_NONE;

	ucontrol->value.integer.value[0] = mode;

	return 0;
}

static int mt8532_afe_sinegen_loopback_mode_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	unsigned int mode;
	unsigned int val;

	mode = ucontrol->value.integer.value[0];

	val = (mode << 24) & AFE_SINEGEN_CON2_MODE_MASK;

	mt8532_afe_enable_main_clk(afe);

	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON2,
			   AFE_SINEGEN_CON2_MODE_MASK, val);

	mt8532_afe_disable_main_clk(afe);

	return 0;
}
#endif
static int mt8532_afe_sinegen_timing_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	unsigned int timing = SINEGEN_8K_A1;
	unsigned int val = 0;
	unsigned int val2 = 0;

	mt8532_afe_enable_reg_rw_clk(afe);

	regmap_read(afe->regmap, AFE_SINEGEN_CON1, &val);
	regmap_read(afe->regmap, A3_A4_TIMING_SEL0, &val2);

	mt8532_afe_disable_reg_rw_clk(afe);

	val = (val & AFE_SINEGEN_CON1_TIMING_CH1_MASK) >> 16;
	val2 = (val2 & AFE_A3A4_TIMING_SEL0_SGEN_CH1_MASK) >> 2;

	switch (val) {
	case AFE_SINEGEN_CON1_TIMING_8K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_8K_A1;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A3)
			timing = SINEGEN_8K_A3;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A4)
			timing = SINEGEN_8K_A4;
		break;
	case AFE_SINEGEN_CON1_TIMING_12K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_12K_A1;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A3)
			timing = SINEGEN_12K_A3;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A4)
			timing = SINEGEN_12K_A4;
		break;
	case AFE_SINEGEN_CON1_TIMING_16K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_16K_A1;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A3)
			timing = SINEGEN_16K_A3;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A4)
			timing = SINEGEN_16K_A4;
		break;
	case AFE_SINEGEN_CON1_TIMING_24K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_24K_A1;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A3)
			timing = SINEGEN_24K_A3;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A4)
			timing = SINEGEN_24K_A4;
		break;
	case AFE_SINEGEN_CON1_TIMING_32K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_32K_A1;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A3)
			timing = SINEGEN_32K_A3;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A4)
			timing = SINEGEN_32K_A4;
		break;
	case AFE_SINEGEN_CON1_TIMING_48K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_48K_A1;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A3)
			timing = SINEGEN_48K_A3;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A4)
			timing = SINEGEN_48K_A4;
		break;
	case AFE_SINEGEN_CON1_TIMING_96K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_96K_A1;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A3)
			timing = SINEGEN_96K_A3;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A4)
			timing = SINEGEN_96K_A4;
		break;
	case AFE_SINEGEN_CON1_TIMING_192K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_192K_A1;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A3)
			timing = SINEGEN_192K_A3;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A4)
			timing = SINEGEN_192K_A4;
		break;
	case AFE_SINEGEN_CON1_TIMING_384K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_384K_A1;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A3)
			timing = SINEGEN_384K_A3;
		else if (val2 == AFE_A3A4_TIMING_SEL0_A4)
			timing = SINEGEN_384K_A4;
		break;
	case AFE_SINEGEN_CON1_TIMING_7D35K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_7D35K_A2;
		else
			timing = SINEGEN_SGEN_ERR;
		break;
	case AFE_SINEGEN_CON1_TIMING_11D025K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_11D025K_A2;
		else
			timing = SINEGEN_SGEN_ERR;
		break;
	case AFE_SINEGEN_CON1_TIMING_14D7K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_14D7K_A2;
		else
			timing = SINEGEN_SGEN_ERR;
		break;
	case AFE_SINEGEN_CON1_TIMING_22D05K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_22D05K_A2;
		else
			timing = SINEGEN_SGEN_ERR;
		break;
	case AFE_SINEGEN_CON1_TIMING_29D4K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_29D4K_A2;
		else
			timing = SINEGEN_SGEN_ERR;
		break;
	case AFE_SINEGEN_CON1_TIMING_44D1K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_44D1K_A2;
		else
			timing = SINEGEN_SGEN_ERR;
		break;
	case AFE_SINEGEN_CON1_TIMING_88D2K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_88D2K_A2;
		else
			timing = SINEGEN_SGEN_ERR;
		break;
	case AFE_SINEGEN_CON1_TIMING_176D4K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_176D4K_A2;
		else
			timing = SINEGEN_SGEN_ERR;
		break;
	case AFE_SINEGEN_CON1_TIMING_352D8K:
		if (val2 == AFE_A3A4_TIMING_SEL0_A1A2)
			timing = SINEGEN_352D8K_A2;
		else
			timing = SINEGEN_SGEN_ERR;
		break;
	default:
		timing = SINEGEN_8K_A1;
		break;
	}

	ucontrol->value.integer.value[0] = timing;

	return 0;
}

static int mt8532_afe_sinegen_timing_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	unsigned int timing;
	unsigned int val;
	unsigned int val2;

	timing = ucontrol->value.integer.value[0];

	switch (timing) {
	case SINEGEN_8K_A1:
		val = AFE_SINEGEN_CON1_TIMING_8K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_12K_A1:
		val = AFE_SINEGEN_CON1_TIMING_12K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_16K_A1:
		val = AFE_SINEGEN_CON1_TIMING_16K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_24K_A1:
		val = AFE_SINEGEN_CON1_TIMING_24K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_32K_A1:
		val = AFE_SINEGEN_CON1_TIMING_32K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_48K_A1:
		val = AFE_SINEGEN_CON1_TIMING_48K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_96K_A1:
		val = AFE_SINEGEN_CON1_TIMING_96K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_192K_A1:
		val = AFE_SINEGEN_CON1_TIMING_192K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_384K_A1:
		val = AFE_SINEGEN_CON1_TIMING_384K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_8K_A3:
		val = AFE_SINEGEN_CON1_TIMING_8K;
		val2 = AFE_A3A4_TIMING_SEL0_A3;
		break;
	case SINEGEN_12K_A3:
		val = AFE_SINEGEN_CON1_TIMING_12K;
		val2 = AFE_A3A4_TIMING_SEL0_A3;
		break;
	case SINEGEN_16K_A3:
		val = AFE_SINEGEN_CON1_TIMING_16K;
		val2 = AFE_A3A4_TIMING_SEL0_A3;
		break;
	case SINEGEN_24K_A3:
		val = AFE_SINEGEN_CON1_TIMING_24K;
		val2 = AFE_A3A4_TIMING_SEL0_A3;
		break;
	case SINEGEN_32K_A3:
		val = AFE_SINEGEN_CON1_TIMING_32K;
		val2 = AFE_A3A4_TIMING_SEL0_A3;
		break;
	case SINEGEN_48K_A3:
		val = AFE_SINEGEN_CON1_TIMING_48K;
		val2 = AFE_A3A4_TIMING_SEL0_A3;
		break;
	case SINEGEN_96K_A3:
		val = AFE_SINEGEN_CON1_TIMING_96K;
		val2 = AFE_A3A4_TIMING_SEL0_A3;
		break;
	case SINEGEN_192K_A3:
		val = AFE_SINEGEN_CON1_TIMING_192K;
		val2 = AFE_A3A4_TIMING_SEL0_A3;
		break;
	case SINEGEN_384K_A3:
		val = AFE_SINEGEN_CON1_TIMING_384K;
		val2 = AFE_A3A4_TIMING_SEL0_A3;
		break;
	case SINEGEN_8K_A4:
		val = AFE_SINEGEN_CON1_TIMING_8K;
		val2 = AFE_A3A4_TIMING_SEL0_A4;
		break;
	case SINEGEN_12K_A4:
		val = AFE_SINEGEN_CON1_TIMING_12K;
		val2 = AFE_A3A4_TIMING_SEL0_A4;
		break;
	case SINEGEN_16K_A4:
		val = AFE_SINEGEN_CON1_TIMING_16K;
		val2 = AFE_A3A4_TIMING_SEL0_A4;
		break;
	case SINEGEN_24K_A4:
		val = AFE_SINEGEN_CON1_TIMING_24K;
		val2 = AFE_A3A4_TIMING_SEL0_A4;
		break;
	case SINEGEN_32K_A4:
		val = AFE_SINEGEN_CON1_TIMING_32K;
		val2 = AFE_A3A4_TIMING_SEL0_A4;
		break;
	case SINEGEN_48K_A4:
		val = AFE_SINEGEN_CON1_TIMING_48K;
		val2 = AFE_A3A4_TIMING_SEL0_A4;
		break;
	case SINEGEN_96K_A4:
		val = AFE_SINEGEN_CON1_TIMING_96K;
		val2 = AFE_A3A4_TIMING_SEL0_A4;
		break;
	case SINEGEN_192K_A4:
		val = AFE_SINEGEN_CON1_TIMING_192K;
		val2 = AFE_A3A4_TIMING_SEL0_A4;
		break;
	case SINEGEN_384K_A4:
		val = AFE_SINEGEN_CON1_TIMING_384K;
		val2 = AFE_A3A4_TIMING_SEL0_A4;
		break;
	case SINEGEN_7D35K_A2:
		val = AFE_SINEGEN_CON1_TIMING_7D35K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_11D025K_A2:
		val = AFE_SINEGEN_CON1_TIMING_11D025K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_14D7K_A2:
		val = AFE_SINEGEN_CON1_TIMING_14D7K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_22D05K_A2:
		val = AFE_SINEGEN_CON1_TIMING_22D05K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_29D4K_A2:
		val = AFE_SINEGEN_CON1_TIMING_29D4K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_44D1K_A2:
		val = AFE_SINEGEN_CON1_TIMING_44D1K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_88D2K_A2:
		val = AFE_SINEGEN_CON1_TIMING_88D2K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_176D4K_A2:
		val = AFE_SINEGEN_CON1_TIMING_176D4K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	case SINEGEN_352D8K_A2:
		val = AFE_SINEGEN_CON1_TIMING_352D8K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	default:
		val = AFE_SINEGEN_CON1_TIMING_8K;
		val2 = AFE_A3A4_TIMING_SEL0_A1A2;
		break;
	}

	mt8532_afe_enable_reg_rw_clk(afe);

	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON1,
			   AFE_SINEGEN_CON1_TIMING_CH1_MASK |
			   AFE_SINEGEN_CON1_TIMING_CH2_MASK,
			   AFE_SINEGEN_CON1_TIMING_CH1(val) |
			   AFE_SINEGEN_CON1_TIMING_CH2(val));
	regmap_update_bits(afe->regmap, A3_A4_TIMING_SEL0,
			   AFE_A3A4_TIMING_SEL0_SGEN_CH1_MASK |
			   AFE_A3A4_TIMING_SEL0_SGEN_CH2_MASK,
			   AFE_A3A4_TIMING_SEL0_CH1(val2) |
			   AFE_A3A4_TIMING_SEL0_CH2(val2));

	mt8532_afe_disable_reg_rw_clk(afe);

	return 0;
}

static int mt8532_afe_ul8_sinegen_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	unsigned int val = 0;

	mt8532_afe_enable_main_clk(afe);

	regmap_read(afe->regmap, ASYS_TOP_CON, &val);

	mt8532_afe_disable_main_clk(afe);

	ucontrol->value.integer.value[0] = (val & ASYS_TCON_UL8_USE_SINEGEN);

	return 0;
}

static int mt8532_afe_masrc_fix_output_fs_enable_get(
		struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;

	ucontrol->value.integer.value[0] =
		afe_priv->use_masrc_fix_output_fs;

	return 0;
}

static int mt8532_afe_masrc_fix_output_fs_enable_put(
		struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;

	afe_priv->use_masrc_fix_output_fs =
		ucontrol->value.integer.value[0];

	return 0;
}

static int mt8532_afe_ul8_sinegen_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);


	mt8532_afe_enable_main_clk(afe);

	if (ucontrol->value.integer.value[0])
		regmap_update_bits(afe->regmap, ASYS_TOP_CON,
				   ASYS_TCON_UL8_USE_SINEGEN,
				   ASYS_TCON_UL8_USE_SINEGEN);
	else
		regmap_update_bits(afe->regmap, ASYS_TOP_CON,
				   ASYS_TCON_UL8_USE_SINEGEN,
				   0x0);

	mt8532_afe_disable_main_clk(afe);

	return 0;
}

static int mt8532_afe_mini_clk_en_get(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;

	ucontrol->value.integer.value[0] = priv->mini_clk_enable;
	return 0;
}

static int mt8532_afe_mini_clk_en_put(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;

	if (ucontrol->value.integer.value[0] != priv->mini_clk_enable) {
		if (ucontrol->value.integer.value[0]) {
			mt8532_afe_enable_reg_rw_clk(afe);
			priv->mini_clk_enable = 1;
		} else {
			mt8532_afe_disable_reg_rw_clk(afe);
			priv->mini_clk_enable = 0;
		}
	}

	return 0;
}

static int mt8532_afe_tdm_out1_sinegen_get(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	unsigned int val = 0;

	mt8532_afe_enable_reg_rw_clk(afe);

	regmap_read(afe->regmap, ETDM_COWORK_CON3, &val);

	mt8532_afe_disable_reg_rw_clk(afe);

	ucontrol->value.integer.value[0] =
		(val & ETDM_COWORK_CON3_OUT1_USE_SINEGEN);

	return 0;
}

static int mt8532_afe_tdm_out1_sinegen_put(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	mt8532_afe_enable_reg_rw_clk(afe);

	if (ucontrol->value.integer.value[0])
		regmap_update_bits(afe->regmap, ETDM_COWORK_CON3,
				   ETDM_COWORK_CON3_OUT1_USE_SINEGEN,
				   ETDM_COWORK_CON3_OUT1_USE_SINEGEN);
	else
		regmap_update_bits(afe->regmap, ETDM_COWORK_CON3,
				   ETDM_COWORK_CON3_OUT1_USE_SINEGEN,
				   0x0);

	mt8532_afe_disable_reg_rw_clk(afe);

	return 0;
}

static int mt8532_afe_tdm_out2_sinegen_get(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	unsigned int val = 0;

	mt8532_afe_enable_reg_rw_clk(afe);

	regmap_read(afe->regmap, ETDM_COWORK_CON3, &val);

	mt8532_afe_disable_reg_rw_clk(afe);

	ucontrol->value.integer.value[0] =
		(val & ETDM_COWORK_CON3_OUT2_USE_SINEGEN);

	return 0;
}

static int mt8532_afe_tdm_out2_sinegen_put(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	mt8532_afe_enable_reg_rw_clk(afe);

	if (ucontrol->value.integer.value[0])
		regmap_update_bits(afe->regmap, ETDM_COWORK_CON3,
				   ETDM_COWORK_CON3_OUT2_USE_SINEGEN,
				   ETDM_COWORK_CON3_OUT2_USE_SINEGEN);
	else
		regmap_update_bits(afe->regmap, ETDM_COWORK_CON3,
				   ETDM_COWORK_CON3_OUT2_USE_SINEGEN,
				   0x0);

	mt8532_afe_disable_reg_rw_clk(afe);

	return 0;
}

static int mt8532_afe_tdm_out3_sinegen_get(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	unsigned int val = 0;

	mt8532_afe_enable_reg_rw_clk(afe);

	regmap_read(afe->regmap, ETDM_COWORK_CON3, &val);

	mt8532_afe_disable_reg_rw_clk(afe);

	ucontrol->value.integer.value[0] =
		(val & ETDM_COWORK_CON3_OUT3_USE_SINEGEN);

	return 0;
}

static int mt8532_afe_tdm_out3_sinegen_put(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	mt8532_afe_enable_reg_rw_clk(afe);

	if (ucontrol->value.integer.value[0])
		regmap_update_bits(afe->regmap, ETDM_COWORK_CON3,
				   ETDM_COWORK_CON3_OUT3_USE_SINEGEN,
				   ETDM_COWORK_CON3_OUT3_USE_SINEGEN);
	else
		regmap_update_bits(afe->regmap, ETDM_COWORK_CON3,
				   ETDM_COWORK_CON3_OUT3_USE_SINEGEN,
				   0x0);

	mt8532_afe_disable_reg_rw_clk(afe);

	return 0;
}

static int mt8532_afe_multi_in_sinegen_get(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int val = 0;

	mt8532_afe_enable_reg_rw_clk(afe);

	regmap_read(afe->regmap, AFE_MPHONE_MULTI_CON2, &val);

	mt8532_afe_disable_reg_rw_clk(afe);

	ucontrol->value.integer.value[0] =
		(val & AFE_MPHONE_MULTI_CON2_DAC_EN) >> 18;

	return 0;
}

static int mt8532_afe_multi_in_sinegen_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	mt8532_afe_enable_reg_rw_clk(afe);

	if (ucontrol->value.integer.value[0])
		regmap_update_bits(afe->regmap, AFE_MPHONE_MULTI_CON2,
				AFE_MPHONE_MULTI_CON2_DAC_EN,
				AFE_MPHONE_MULTI_CON2_DAC_EN);
	else
		regmap_update_bits(afe->regmap, AFE_MPHONE_MULTI_CON2,
				AFE_MPHONE_MULTI_CON2_DAC_EN,
				0x0);

	mt8532_afe_disable_reg_rw_clk(afe);

	return 0;
}

static int mt8532_afe_multi_in2_sinegen_get(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int val = 0;

	mt8532_afe_enable_reg_rw_clk(afe);

	regmap_read(afe->regmap, AFE_MPHONE_MULTI2_CON2, &val);

	mt8532_afe_disable_reg_rw_clk(afe);

	ucontrol->value.integer.value[0] =
		(val & AFE_MPHONE_MULTI_CON2_DAC_EN) >> 18;

	return 0;
}

static int mt8532_afe_multi_in2_sinegen_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	mt8532_afe_enable_reg_rw_clk(afe);

	if (ucontrol->value.integer.value[0])
		regmap_update_bits(afe->regmap, AFE_MPHONE_MULTI2_CON2,
				AFE_MPHONE_MULTI_CON2_DAC_EN,
				AFE_MPHONE_MULTI_CON2_DAC_EN);
	else
		regmap_update_bits(afe->regmap, AFE_MPHONE_MULTI2_CON2,
				AFE_MPHONE_MULTI_CON2_DAC_EN,
				0x0);

	mt8532_afe_disable_reg_rw_clk(afe);

	return 0;
}

static int mt8532_afe_dmic_sinegen_enable_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	unsigned int val = 0;

	mt8532_afe_enable_reg_rw_clk(afe);
	regmap_read(afe->regmap, AFE_DMIC0_UL_SRC_CON1, &val);
	mt8532_afe_disable_reg_rw_clk(afe);
	ucontrol->value.integer.value[0] =
		(val & DMIC_UL_CON1_SGEN_EN) ? 1 : 0;

	return 0;
}

static int mt8532_afe_dmic_sinegen_enable_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	unsigned int val_cfg = 0;
	unsigned int val_en = 0;
	unsigned int read_val = 0;
	int i;
	unsigned int regs[] = {
		AFE_DMIC0_UL_SRC_CON1,
		AFE_DMIC1_UL_SRC_CON1,
		AFE_DMIC2_UL_SRC_CON1,
		AFE_DMIC3_UL_SRC_CON1,
	};

	val_cfg |= DMIC_UL_CON1_SGEN_CH2_AMP_DIV(6) |
		   DMIC_UL_CON1_SGEN_CH2_FREQ_DIV(1) |
		   DMIC_UL_CON1_SGEN_CH1_AMP_DIV(6) |
		   DMIC_UL_CON1_SGEN_CH1_FREQ_DIV(1);

	mt8532_afe_enable_reg_rw_clk(afe);
	regmap_read(afe->regmap, AFE_DMIC0_UL_SRC_CON0, &read_val);

	switch (read_val & (0x7 << 17)) {
	case DMIC_UL_CON0_VOCIE_MODE_8K:
		val_cfg |= DMIC_UL_CON1_SGEN_CH2_SINE_MODE(0) |
			   DMIC_UL_CON1_SGEN_CH1_SINE_MODE(0);
		break;
	case DMIC_UL_CON0_VOCIE_MODE_16K:
		val_cfg |= DMIC_UL_CON1_SGEN_CH2_SINE_MODE(3) |
			   DMIC_UL_CON1_SGEN_CH1_SINE_MODE(3);
		break;
	case DMIC_UL_CON0_VOCIE_MODE_32K:
		val_cfg |= DMIC_UL_CON1_SGEN_CH2_SINE_MODE(6) |
			   DMIC_UL_CON1_SGEN_CH1_SINE_MODE(6);
		break;
	case DMIC_UL_CON0_VOCIE_MODE_48K:
		val_cfg |= DMIC_UL_CON1_SGEN_CH2_SINE_MODE(8) |
			   DMIC_UL_CON1_SGEN_CH1_SINE_MODE(8);
		break;
	default:
		val_cfg |= DMIC_UL_CON1_SGEN_CH2_SINE_MODE(0) |
			   DMIC_UL_CON1_SGEN_CH1_SINE_MODE(0);
		break;
	}

	val_en |= DMIC_UL_CON1_SGEN_EN;

	if (ucontrol->value.integer.value[0]) {
		for (i = 0; i < ARRAY_SIZE(regs); i++)
			regmap_update_bits(afe->regmap, regs[i],
					   val_cfg | val_en,
					   val_cfg | val_en);
	} else {
		for (i = 0; i < ARRAY_SIZE(regs); i++)
			regmap_update_bits(afe->regmap, regs[i],
					   val_en,
					   0x0);
	}
	mt8532_afe_disable_reg_rw_clk(afe);

	return 0;
}


static int mt8532_afe_multi_in_data_source_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int src = MULTI_IN_FROM_SPLIN;
	unsigned int val = 0;

	mt8532_afe_enable_main_clk(afe);

	regmap_read(afe->regmap, AFE_LOOPBACK_CFG0, &val);

	mt8532_afe_disable_main_clk(afe);

	val = val & MULTI_IN_DAT0_SEL_MASK;

	if (val == MULTI_IN_DAT0_SEL_SPLIN)
		src = MULTI_IN_FROM_SPLIN;
	else if (val == MULTI_IN_DAT0_SEL_ETDM_OUT3)
		src = MULTI_IN_FROM_ETDM_OUT3;
	else if (val == MULTI_IN_DAT0_SEL_ETDM_IN2)
		src = MULTI_IN_FROM_ETDM_IN2_EXT;
	else if (val == MULTI_IN_DAT0_SEL_EARC)
		src = MULTI_IN_FROM_EARC;
	else if (val == MULTI_IN_DAT0_SEL_HDMIRX)
		src = MULTI_IN_FROM_HDMIRX;
	else if (val == MULTI_IN_DAT0_SEL_AUD2_HDMI)
		src = MULTI_IN_FROM_AUD2_HDMI;

	ucontrol->value.integer.value[0] = src;

	return 0;
}

static int mt8532_afe_multi_in_data_source_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int src;

	src = ucontrol->value.integer.value[0];

	mt8532_afe_enable_main_clk(afe);

	if (src == MULTI_IN_FROM_SPLIN)
		regmap_update_bits(afe->regmap, AFE_LOOPBACK_CFG0,
			   MULTI_IN_DAT0_SEL_MASK,
			   MULTI_IN_DAT0_SEL_SPLIN);
	else if (src == MULTI_IN_FROM_ETDM_OUT3)
		regmap_update_bits(afe->regmap, AFE_LOOPBACK_CFG0,
			   MULTI_IN_DAT0_SEL_MASK,
			   MULTI_IN_DAT0_SEL_ETDM_OUT3);
	else if (src == MULTI_IN_FROM_ETDM_IN2_EXT)
		regmap_update_bits(afe->regmap, AFE_LOOPBACK_CFG0,
			   MULTI_IN_DAT0_SEL_MASK,
			   MULTI_IN_DAT0_SEL_ETDM_IN2);
	else if (src == MULTI_IN_FROM_EARC)
		regmap_update_bits(afe->regmap, AFE_LOOPBACK_CFG0,
			   MULTI_IN_DAT0_SEL_MASK,
			   MULTI_IN_DAT0_SEL_EARC);
	else if (src == MULTI_IN_FROM_HDMIRX)
		regmap_update_bits(afe->regmap, AFE_LOOPBACK_CFG0,
			   MULTI_IN_DAT0_SEL_MASK,
			   MULTI_IN_DAT0_SEL_HDMIRX);
	else if (src == MULTI_IN_FROM_AUD2_HDMI)
		regmap_update_bits(afe->regmap, AFE_LOOPBACK_CFG0,
			   MULTI_IN_DAT0_SEL_MASK,
			   MULTI_IN_DAT0_SEL_AUD2_HDMI);

	mt8532_afe_disable_main_clk(afe);

	return 0;
}

static int mt8532_afe_etdm_in_data_source_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int src = ETDM_IN_FROM_PAD;
	unsigned int val = 0;

	if (!strcmp(kcontrol->id.name, "ETDM_IN1_Data_Source_Select")) {
		mt8532_afe_enable_main_clk(afe);
		regmap_read(afe->regmap, ETDM_COWORK_CON1, &val);
		mt8532_afe_disable_main_clk(afe);

		val = val & ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_MASK;

		if (val == ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_PAD)
			src = ETDM_IN_FROM_PAD;
		else if (val == ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_OUT1)
			src = ETDM_IN_FROM_ETDM_OUT1;
		else if (val == ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_OUT2)
			src = ETDM_IN_FROM_ETDM_OUT2;
		else if (val == ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_OUT3)
			src = ETDM_IN_FROM_ETDM_OUT3;
	} else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Data_Source_Select")) {
		mt8532_afe_enable_main_clk(afe);
		regmap_read(afe->regmap, ETDM_COWORK_CON3, &val);
		mt8532_afe_disable_main_clk(afe);
		val = val & ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_MASK;

		if (val == ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_PAD)
			src = ETDM_IN_FROM_PAD;
		else if (val == ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_OUT1)
			src = ETDM_IN_FROM_ETDM_OUT1;
		else if (val == ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_OUT2)
			src = ETDM_IN_FROM_ETDM_OUT2;
		else if (val == ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_OUT3)
			src = ETDM_IN_FROM_ETDM_OUT3;
	}

	ucontrol->value.integer.value[0] = src;

	return 0;
}

static int mt8532_afe_etdm_in_data_source_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	unsigned int src;

	src = ucontrol->value.integer.value[0];
	mt8532_afe_enable_main_clk(afe);

	if (!strcmp(kcontrol->id.name, "ETDM_IN1_Data_Source_Select")) {
		if (src == ETDM_IN_FROM_PAD)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON1,
				   ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_MASK |
				   ETDM_COWORK_CON1_TDM_IN1_DAT1_x_SEL_MASK,
				   ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_PAD |
				   ETDM_COWORK_CON1_TDM_IN1_DAT1_x_SEL_PAD);
		else if (src == ETDM_IN_FROM_ETDM_OUT1)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON1,
				   ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_MASK |
				   ETDM_COWORK_CON1_TDM_IN1_DAT1_x_SEL_MASK,
				   ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_OUT1 |
				   ETDM_COWORK_CON1_TDM_IN1_DAT1_x_SEL_OUT1);
		else if (src == ETDM_IN_FROM_ETDM_OUT2)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON1,
				   ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_MASK |
				   ETDM_COWORK_CON1_TDM_IN1_DAT1_x_SEL_MASK,
				   ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_OUT2 |
				   ETDM_COWORK_CON1_TDM_IN1_DAT1_x_SEL_OUT2);
		else if (src == ETDM_IN_FROM_ETDM_OUT3)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON1,
				   ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_MASK |
				   ETDM_COWORK_CON1_TDM_IN1_DAT1_x_SEL_MASK,
				   ETDM_COWORK_CON1_TDM_IN1_DAT0_SEL_OUT3 |
				   ETDM_COWORK_CON1_TDM_IN1_DAT1_x_SEL_OUT3);
	} else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Data_Source_Select")) {
		if (src == ETDM_IN_FROM_PAD)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON3,
				   ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_MASK |
				   ETDM_COWORK_CON3_TDM_IN2_DAT1_x_SEL_MASK,
				   ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_PAD |
				   ETDM_COWORK_CON3_TDM_IN2_DAT1_x_SEL_PAD);
		else if (src == ETDM_IN_FROM_ETDM_OUT1)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON3,
				   ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_MASK |
				   ETDM_COWORK_CON3_TDM_IN2_DAT1_x_SEL_MASK,
				   ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_OUT1 |
				   ETDM_COWORK_CON3_TDM_IN2_DAT1_x_SEL_OUT1);
		else if (src == ETDM_IN_FROM_ETDM_OUT2)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON3,
				   ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_MASK |
				   ETDM_COWORK_CON3_TDM_IN2_DAT1_x_SEL_MASK,
				   ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_OUT2 |
				   ETDM_COWORK_CON3_TDM_IN2_DAT1_x_SEL_OUT2);
		else if (src == ETDM_IN_FROM_ETDM_OUT3)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON3,
				   ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_MASK |
				   ETDM_COWORK_CON3_TDM_IN2_DAT1_x_SEL_MASK,
				   ETDM_COWORK_CON3_TDM_IN2_DAT0_SEL_OUT3 |
				   ETDM_COWORK_CON3_TDM_IN2_DAT1_x_SEL_OUT3);
	}

	mt8532_afe_disable_main_clk(afe);

	return 0;
}

static int mt8532_afe_etdm_in_slave_mode_src_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int src = ETDM_IN_SLAVE_FROM_SELF;
	unsigned int val = 0;

	if (!strcmp(kcontrol->id.name, "ETDM_IN1_Slave_Mode_Source_Select")) {
		mt8532_afe_enable_main_clk(afe);
		regmap_read(afe->regmap, ETDM_COWORK_CON1, &val);
		mt8532_afe_disable_main_clk(afe);
		val = val & ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_MASK;

		if (val == ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_SELF)
			src = ETDM_IN_SLAVE_FROM_SELF;
		else if (val == ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_OUT1_MAS)
			src = ETDM_IN_SLAVE_FROM_ETDM_OUT1;
		else if (val == ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_OUT2_MAS)
			src = ETDM_IN_SLAVE_FROM_ETDM_OUT2;
		else if (val == ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_OUT3_MAS)
			src = ETDM_IN_SLAVE_FROM_ETDM_OUT3;
	} else if (!strcmp(kcontrol->id.name,
			   "ETDM_IN2_Slave_Mode_Source_Select")) {
		mt8532_afe_enable_main_clk(afe);
		regmap_read(afe->regmap, ETDM_COWORK_CON2, &val);
		mt8532_afe_disable_main_clk(afe);
		val = val & ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_MASK;

		if (val == ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_SELF)
			src = ETDM_IN_SLAVE_FROM_SELF;
		else if (val == ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_OUT1_MAS)
			src = ETDM_IN_SLAVE_FROM_ETDM_OUT1;
		else if (val == ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_OUT2_MAS)
			src = ETDM_IN_SLAVE_FROM_ETDM_OUT2;
		else if (val == ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_OUT3_MAS)
			src = ETDM_IN_SLAVE_FROM_ETDM_OUT3;
	}

	ucontrol->value.integer.value[0] = src;

	return 0;
}

static int mt8532_afe_etdm_in_slave_mode_src_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int src;

	src = ucontrol->value.integer.value[0];
	mt8532_afe_enable_main_clk(afe);

	if (!strcmp(kcontrol->id.name, "ETDM_IN1_Slave_Mode_Source_Select")) {
		if (src == ETDM_IN_SLAVE_FROM_SELF)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON1,
				   ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_MASK,
				   ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_SELF);
		else if (src == ETDM_IN_SLAVE_FROM_ETDM_OUT1)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON1,
				   ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_MASK,
				   ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_OUT1_MAS);
		else if (src == ETDM_IN_SLAVE_FROM_ETDM_OUT2)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON1,
				   ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_MASK,
				   ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_OUT2_MAS);
		else if (src == ETDM_IN_SLAVE_FROM_ETDM_OUT3)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON1,
				   ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_MASK,
				   ETDM_COWORK_CON1_TDM_IN1_SLV_SEL_OUT3_MAS);
	} else if (!strcmp(kcontrol->id.name,
			"ETDM_IN2_Slave_Mode_Source_Select")) {
		if (src == ETDM_IN_SLAVE_FROM_SELF)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON2,
				   ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_MASK,
				   ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_SELF);
		else if (src == ETDM_IN_SLAVE_FROM_ETDM_OUT1)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON2,
				   ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_MASK,
				   ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_OUT1_MAS);
		else if (src == ETDM_IN_SLAVE_FROM_ETDM_OUT2)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON2,
				   ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_MASK,
				   ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_OUT2_MAS);
		else if (src == ETDM_IN_SLAVE_FROM_ETDM_OUT3)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON2,
				   ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_MASK,
				   ETDM_COWORK_CON2_TDM_IN2_SLV_SEL_OUT3_MAS);
	}
	mt8532_afe_disable_main_clk(afe);
	return 0;
}
#ifdef CURRENTLY_AUDIO_NOT_USE
static int mt8532_afe_pcm_loopback_get(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int val = 0;

	mt8532_afe_enable_main_clk(afe);

	regmap_read(afe->regmap, PCM_INTF_CON2, &val);

	mt8532_afe_disable_main_clk(afe);

	ucontrol->value.integer.value[0] = (val & PCM_INTF_CON2_LPBK_EN);

	return 0;
}

static int mt8532_afe_pcm_loopback_put(struct snd_kcontrol *kcontrol,
				       struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	mt8532_afe_enable_main_clk(afe);

	if (ucontrol->value.integer.value[0])
		regmap_update_bits(afe->regmap, PCM_INTF_CON2,
				   PCM_INTF_CON2_LPBK_EN,
				   PCM_INTF_CON2_LPBK_EN);
	else
		regmap_update_bits(afe->regmap, PCM_INTF_CON2,
				   PCM_INTF_CON2_LPBK_EN,
				   0x0);

	mt8532_afe_disable_main_clk(afe);

	return 0;
}
#endif

#ifdef CURRENTLY_AUDIO_NOT_USE
static int mt8532_afe_dmic_sinegen_enable_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int val = 0;

	mt8532_afe_enable_main_clk(afe);

	regmap_read(afe->regmap, AFE_DMIC0_UL_SRC_CON1, &val);

	mt8532_afe_disable_main_clk(afe);

	ucontrol->value.integer.value[0] =
		(val & DMIC_UL_CON1_SGEN_EN) ? 1 : 0;

	return 0;
}

static int mt8532_afe_dmic_sinegen_enable_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int val_cfg = 0;
	unsigned int val_en = 0;
	unsigned int read_val = 0;
	unsigned int regs[] = {
		AFE_DMIC0_UL_SRC_CON1,
		AFE_DMIC1_UL_SRC_CON1,
		AFE_DMIC2_UL_SRC_CON1,
		AFE_DMIC3_UL_SRC_CON1,
	};
	int i;

	mt8532_afe_enable_main_clk(afe);
	val_cfg |= DMIC_UL_CON1_SGEN_CH2_AMP_DIV(6) |
		   DMIC_UL_CON1_SGEN_CH2_FREQ_DIV(1) |
		   DMIC_UL_CON1_SGEN_CH1_AMP_DIV(6) |
		   DMIC_UL_CON1_SGEN_CH1_FREQ_DIV(1);

	regmap_read(afe->regmap, AFE_DMIC0_UL_SRC_CON0, &read_val);

	switch (read_val & (0x7 << 17)) {
	case DMIC_UL_CON0_VOCIE_MODE_8K:
		val_cfg |= DMIC_UL_CON1_SGEN_CH2_SINE_MODE(0) |
			   DMIC_UL_CON1_SGEN_CH1_SINE_MODE(0);
		break;
	case DMIC_UL_CON0_VOCIE_MODE_16K:
		val_cfg |= DMIC_UL_CON1_SGEN_CH2_SINE_MODE(3) |
			   DMIC_UL_CON1_SGEN_CH1_SINE_MODE(3);
		break;
	case DMIC_UL_CON0_VOCIE_MODE_32K:
		val_cfg |= DMIC_UL_CON1_SGEN_CH2_SINE_MODE(6) |
			   DMIC_UL_CON1_SGEN_CH1_SINE_MODE(6);
		break;
	case DMIC_UL_CON0_VOCIE_MODE_48K:
		val_cfg |= DMIC_UL_CON1_SGEN_CH2_SINE_MODE(8) |
			   DMIC_UL_CON1_SGEN_CH1_SINE_MODE(8);
		break;
	default:
		val_cfg |= DMIC_UL_CON1_SGEN_CH2_SINE_MODE(0) |
			   DMIC_UL_CON1_SGEN_CH1_SINE_MODE(0);
		break;
	}

	val_en |= DMIC_UL_CON1_SGEN_EN;

	if (ucontrol->value.integer.value[0]) {
		for (i = 0; i < ARRAY_SIZE(regs); i++)
			regmap_update_bits(afe->regmap, regs[i],
					   val_cfg | val_en,
					   val_cfg | val_en);
	} else {
		for (i = 0; i < ARRAY_SIZE(regs); i++)
			regmap_update_bits(afe->regmap, regs[i],
					   val_en,
					   0x0);
	}

	mt8532_afe_disable_main_clk(afe);

	return 0;
}

static int mt8532_afe_dmic_rampgen_enable_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int val = 0;

	mt8532_afe_enable_main_clk(afe);

	regmap_read(afe->regmap, DMIC_TOP_CON, &val);

	mt8532_afe_disable_main_clk(afe);

	ucontrol->value.integer.value[0] =
		(val & DMIC_TOP_CON_DMIC_SGEN_RAMPGEN_EN) ? 1 : 0;

	return 0;
}

static int mt8532_afe_dmic_rampgen_enable_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int val_cfg = 0;
	unsigned int val_en = 0;
	int i;
	unsigned int regs[] = {
		DMIC_TOP_CON,
		DMIC2_TOP_CON,
		DMIC3_TOP_CON,
		DMIC4_TOP_CON,
	};

	mt8532_afe_enable_main_clk(afe);

	val_cfg |= DMIC_TOP_CON_DMIC_SGEN_RAMPGEN_FREQ_DIV(0x1F);

	val_en |= DMIC_TOP_CON_DMIC_RAMPGEN_LON |
		  DMIC_TOP_CON_DMIC_RAMPGEN_RON |
		  DMIC_TOP_CON_DMIC_SGEN_RAMPGEN_EN;

	if (ucontrol->value.integer.value[0]) {
		for (i = 0; i < ARRAY_SIZE(regs); i++)
			regmap_update_bits(afe->regmap, regs[i],
					   val_cfg | val_en,
					   val_cfg | val_en);
	} else {
		for (i = 0; i < ARRAY_SIZE(regs); i++)
			regmap_update_bits(afe->regmap, regs[i],
					   val_en,
					   0x0);
	}

	mt8532_afe_disable_main_clk(afe);

	return 0;
}
#endif
#ifdef CURRENTLY_AUDIO_NOT_USE
static int mt8532_afe_gasrc_in_sinegen_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int val = 0;

	mt8532_afe_enable_main_clk(afe);

	regmap_read(afe->regmap, AFE_SINEGEN_CON1, &val);

	mt8532_afe_disable_main_clk(afe);

	ucontrol->value.integer.value[0] =
		(val & AFE_SINEGEN_CON1_GASRC_IN_SGEN);

	return 0;
}

static int mt8532_afe_gasrc_in_sinegen_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	mt8532_afe_enable_main_clk(afe);

	if (ucontrol->value.integer.value[0])
		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON1,
				   AFE_SINEGEN_CON1_GASRC_IN_SGEN,
				   AFE_SINEGEN_CON1_GASRC_IN_SGEN);
	else
		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON1,
				   AFE_SINEGEN_CON1_GASRC_IN_SGEN,
				   0x0);

	mt8532_afe_disable_main_clk(afe);

	return 0;
}

static int mt8532_afe_gasrc_out_sinegen_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int val = 0;

	mt8532_afe_enable_main_clk(afe);

	regmap_read(afe->regmap, AFE_SINEGEN_CON1, &val);

	mt8532_afe_disable_main_clk(afe);

	ucontrol->value.integer.value[0] =
		(val & AFE_SINEGEN_CON1_GASRC_OUT_SGEN);

	return 0;
}

static int mt8532_afe_gasrc_out_sinegen_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	mt8532_afe_enable_main_clk(afe);

	if (ucontrol->value.integer.value[0])
		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON1,
				   AFE_SINEGEN_CON1_GASRC_OUT_SGEN,
				   AFE_SINEGEN_CON1_GASRC_OUT_SGEN);
	else
		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON1,
				   AFE_SINEGEN_CON1_GASRC_OUT_SGEN,
				   0x0);

	mt8532_afe_disable_main_clk(afe);

	return 0;
}

static int get_tdmout_conn_reg_shift(char *name,
	unsigned int *reg, unsigned int *shift)
{
	int ret = 0;

	if (!strcmp(name, "TDMOUT_O00_Source_Select")) {
		*reg = AFE_TDMOUT_CONN0;
		*shift = 0;
	} else if (!strcmp(name, "TDMOUT_O01_Source_Select")) {
		*reg = AFE_TDMOUT_CONN0;
		*shift = 4;
	} else if (!strcmp(name, "TDMOUT_O02_Source_Select")) {
		*reg = AFE_TDMOUT_CONN0;
		*shift = 8;
	} else if (!strcmp(name, "TDMOUT_O03_Source_Select")) {
		*reg = AFE_TDMOUT_CONN0;
		*shift = 12;
	} else if (!strcmp(name, "TDMOUT_O04_Source_Select")) {
		*reg = AFE_TDMOUT_CONN0;
		*shift = 16;
	} else if (!strcmp(name, "TDMOUT_O05_Source_Select")) {
		*reg = AFE_TDMOUT_CONN0;
		*shift = 20;
	} else if (!strcmp(name, "TDMOUT_O06_Source_Select")) {
		*reg = AFE_TDMOUT_CONN0;
		*shift = 24;
	} else if (!strcmp(name, "TDMOUT_O07_Source_Select")) {
		*reg = AFE_TDMOUT_CONN0;
		*shift = 28;
	} else if (!strcmp(name, "TDMOUT_O08_Source_Select")) {
		*reg = AFE_TDMOUT_CONN1;
		*shift = 0;
	} else if (!strcmp(name, "TDMOUT_O09_Source_Select")) {
		*reg = AFE_TDMOUT_CONN1;
		*shift = 4;
	} else if (!strcmp(name, "TDMOUT_O10_Source_Select")) {
		*reg = AFE_TDMOUT_CONN1;
		*shift = 8;
	} else if (!strcmp(name, "TDMOUT_O11_Source_Select")) {
		*reg = AFE_TDMOUT_CONN1;
		*shift = 12;
	} else if (!strcmp(name, "TDMOUT_O12_Source_Select")) {
		*reg = AFE_TDMOUT_CONN1;
		*shift = 16;
	} else if (!strcmp(name, "TDMOUT_O13_Source_Select")) {
		*reg = AFE_TDMOUT_CONN1;
		*shift = 20;
	} else if (!strcmp(name, "TDMOUT_O14_Source_Select")) {
		*reg = AFE_TDMOUT_CONN1;
		*shift = 24;
	} else if (!strcmp(name, "TDMOUT_O15_Source_Select")) {
		*reg = AFE_TDMOUT_CONN1;
		*shift = 28;
	} else {
		ret = -1;
	}

	return ret;
}

static int mt8532_afe_tdm_conn_source_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int src;
	unsigned int reg;
	unsigned int shift;
	unsigned int val;
	int ret;

	ret = get_tdmout_conn_reg_shift(kcontrol->id.name, &reg, &shift);
	if (ret)
		return ret;

	mt8532_afe_enable_main_clk(afe);

	regmap_read(afe->regmap, reg, &val);

	mt8532_afe_disable_main_clk(afe);

	src = (val >> shift) & 0xf;

	ucontrol->value.integer.value[0] = src;

	return 0;
}

static int mt8532_afe_tdm_conn_source_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int src;
	unsigned int reg;
	unsigned int shift;
	int ret;

	src = ucontrol->value.integer.value[0];

	ret = get_tdmout_conn_reg_shift(kcontrol->id.name, &reg, &shift);
	if (ret)
		return ret;

	mt8532_afe_enable_main_clk(afe);

	regmap_update_bits(afe->regmap, reg, 0xf << shift, src << shift);

	mt8532_afe_disable_main_clk(afe);

	return 0;
}

static int mt8532_afe_spdif_output_iec61937_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	struct mt8532_control_data *data = &afe_priv->ctrl_data;

	ucontrol->value.integer.value[0] = data->spdif_output_iec61937;

	return 0;
}

static int mt8532_afe_spdif_output_iec61937_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	struct mt8532_control_data *data = &afe_priv->ctrl_data;

	data->spdif_output_iec61937 = (ucontrol->value.integer.value[0]) ?
				 true : false;

	dev_dbg(afe->dev, "%s iec61937 %d\n", __func__,
		data->spdif_output_iec61937);

	return 0;
}
#endif

static int mt8532_afe_spdif_in_port_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	struct mt8532_afe_private *afe_priv = afe->platform_priv;

	ucontrol->value.integer.value[0] = afe_priv->spdif_in_data.port;

	return 0;
}

static int mt8532_afe_spdif_in_port_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	unsigned int port = ucontrol->value.integer.value[0];

	dev_dbg(afe->dev, "%s port %u\n", __func__, port);

	mt8532_afe_handle_spdif_in_port_change(afe, port);

	return 0;
}

static int mt8532_afe_spdif_in_chs_data_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
	uinfo->count = 24;
	return 0;
}

static int mt8532_afe_spdif_in_chs_data_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	struct mt8532_spdif_in_data *spdif_in = &afe_priv->spdif_in_data;
	int i;

	if (spdif_in->port != SPDIF_IN_PORT_NONE) {
		mt8532_afe_enable_main_clk(afe);

		for (i = 0; i < SPDIF_CHSTS_NUM; i++)
			regmap_read(afe->regmap,
				    AFE_SPDIFIN_CHSTS1 + i * 4,
				    &spdif_in->subdata.ch_status[i]);

		mt8532_afe_disable_main_clk(afe);
	}

	memcpy((void *)ucontrol->value.bytes.data,
	       spdif_in->subdata.ch_status,
	       sizeof(spdif_in->subdata.ch_status));

	return 0;
}

static int mt8532_afe_spdif_in_rate_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 1;
	return 0;
}

static int mt8532_afe_spdif_in_rate_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);

	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	struct mt8532_spdif_in_data *spdif_in = &afe_priv->spdif_in_data;

	ucontrol->value.integer.value[0] = spdif_in->subdata.rate;

	return 0;
}

static int mt8532_afe_spdif_in_iec958_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
	uinfo->count = 1;
	return 0;
}

static int mt8532_afe_spdif_in_iec958_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	struct mt8532_spdif_in_data *spdif_in = &afe_priv->spdif_in_data;
	int i;

	if (spdif_in->port != SPDIF_IN_PORT_NONE) {
		mt8532_afe_enable_main_clk(afe);

		for (i = 0; i < 6; i++)
			regmap_read(afe->regmap,
				    AFE_SPDIFIN_CHSTS1 + i * 4,
				    &spdif_in->subdata.ch_status[i]);

		mt8532_afe_disable_main_clk(afe);
	} else {
		memset((void *)spdif_in->subdata.ch_status,
		       0xff, sizeof(spdif_in->subdata.ch_status));
	}

	memcpy((void *)ucontrol->value.iec958.status,
	       spdif_in->subdata.ch_status,
	       sizeof(spdif_in->subdata.ch_status));

	return 0;
}

static int mt8532_afe_spdif_in_stream_type_info(
	struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 1;
	return 0;
}

static int mt8532_afe_spdif_in_stream_type_get(
	struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int val = 0;

	mt8532_afe_enable_main_clk(afe);
	regmap_read(afe->regmap, AFE_MPHONE_MULTI_MON, &val);
	mt8532_afe_disable_main_clk(afe);

	if (val & AFE_MPHONE_MULTI_MON_DEC)
		val = val & AFE_MPHONE_MULTI_MON_ROUGH;
	else
		val = 0xff;

	ucontrol->value.integer.value[0] = val;

	return 0;
}

static int mt8532_afe_spdif_in_user_code_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = SPDIF_USERCODE_NUM;
	return 0;
}

static int mt8532_afe_spdif_in_user_code_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	struct mt8532_spdif_in_data *spdif_in = &afe_priv->spdif_in_data;
	int i;

	if (spdif_in->port != SPDIF_IN_PORT_NONE) {
		mt8532_afe_enable_main_clk(afe);
		for (i = 0; i < SPDIF_USERCODE_NUM; i++)
			regmap_read(afe->regmap,
				    SPDIFIN_USERCODE1 + i * 4,
				    &spdif_in->subdata.user_code[i]);

		mt8532_afe_disable_main_clk(afe);
	}

	memcpy((void *)ucontrol->value.bytes.data,
	       spdif_in->subdata.user_code,
	       sizeof(spdif_in->subdata.user_code));

	return 0;
}

static int mt8532_afe_spdif_in_information_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = sizeof(struct mt8532_spdif_in_subdata) /
			sizeof(unsigned int);

	return 0;
}

static unsigned int get_spdif_in_sample_rate(struct mtk_base_afe *afe)
{
	unsigned int val = 0, fs = 0;

	regmap_read(afe->regmap, AFE_SPDIFIN_INT_EXT2, &val);

	val &= AFE_SPDIFIN_INT_EXT2_ROUGH_FS_MASK;

	switch (val) {
	case AFE_SPDIFIN_INT_EXT2_FS_32K:
		fs = 32000;
		break;
	case AFE_SPDIFIN_INT_EXT2_FS_44D1K:
		fs = 44100;
		break;
	case AFE_SPDIFIN_INT_EXT2_FS_48K:
		fs = 48000;
		break;
	case AFE_SPDIFIN_INT_EXT2_FS_88D2K:
		fs = 88200;
		break;
	case AFE_SPDIFIN_INT_EXT2_FS_96K:
		fs = 96000;
		break;
	case AFE_SPDIFIN_INT_EXT2_FS_176D4K:
		fs = 176400;
		break;
	case AFE_SPDIFIN_INT_EXT2_FS_192K:
		fs = 192000;
		break;
	default:
		fs = 0;
		break;
	}

	return fs;
}

static int mt8532_afe_spdif_in_information_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	struct mt8532_spdif_in_data *spdif_in = &afe_priv->spdif_in_data;
	int i, index = 0;
	unsigned int stream_type = 0, register_val = 0, rate = 0;

	mt8532_afe_enable_main_clk(afe);
	rate = get_spdif_in_sample_rate(afe);
	ucontrol->value.integer.value[index++] = rate;

	for (i = 0; i < SPDIF_USERCODE_NUM; i++) {
		if (rate == 0)
			ucontrol->value.integer.value[index++] = 0xff;
		else {
			regmap_read(afe->regmap,
					SPDIFIN_USERCODE1 + i * 4,
					&register_val);
			ucontrol->value.integer.value[index++] = register_val;
		}
	}

	//channel status
	for (i = 0; i < SPDIF_CHSTS_NUM; i++) {
		if (rate == 0)
			ucontrol->value.integer.value[index++] = 0xff;
		else {
			regmap_read(afe->regmap,
					AFE_SPDIFIN_CHSTS1 + i * 4,
					&register_val);
			ucontrol->value.integer.value[index++] = register_val;
		}
	}

	regmap_read(afe->regmap, AFE_MPHONE_MULTI_MON, &stream_type);
	if (stream_type & AFE_MPHONE_MULTI_MON_DEC)
		stream_type = stream_type & AFE_MPHONE_MULTI_MON_ROUGH;

	ucontrol->value.integer.value[index] = stream_type;
	mt8532_afe_disable_main_clk(afe);

	return 0;
}

static int mt8532_afe_multi_in_information_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = sizeof(struct mt8532_multi_in_mon_info) /
		sizeof(unsigned int);

	return 0;
}

static int mt8532_afe_multi_in_information_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;
	struct mt8532_multi_in_mon_info *mon_info =
		&priv->multi_in_mon_info;
	int index = 0;

	ucontrol->value.integer.value[index++] = mon_info->rough_type;
	ucontrol->value.integer.value[index++] = mon_info->data_type;
	ucontrol->value.integer.value[index++] = mon_info->bitstream_number;
	ucontrol->value.integer.value[index++] = mon_info->pc_b12_to_b5;

	return 0;
}

static int mt8532_afe_multi_in2_information_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;
	struct mt8532_multi_in_mon_info *mon_info =
		&priv->multi_in2_mon_info;
	int index = 0;

	ucontrol->value.integer.value[index++] = mon_info->rough_type;
	ucontrol->value.integer.value[index++] = mon_info->data_type;
	ucontrol->value.integer.value[index++] = mon_info->bitstream_number;
	ucontrol->value.integer.value[index++] = mon_info->pc_b12_to_b5;

	return 0;
}

static int mt8532_apll1_clk_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;
	struct clk *clk;

	clk = priv->clocks[MT8532_CLK_APMIXED_APLL1];

	ucontrol->value.integer.value[0] = clk_get_rate(clk);
	return 0;
}

static int mt8532_apll1_clk_set(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;
	struct clk *clk;
	unsigned long rate, min;

	rate = ucontrol->value.integer.value[0];

	min = MT8532_APLL1_RATE - MT8532_APLL_ADJUST_RANGE;

	rate = max(rate, min);

	dev_dbg(afe->dev, "%s rate %lu\n", __func__, rate);

	clk = priv->clocks[MT8532_CLK_APMIXED_APLL1];

	clk_set_rate(clk, rate);

	return 0;
}

static int mt8532_source_fs_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;

	ucontrol->value.integer.value[0] = priv->source_fs;
 	return 0;
}

static int mt8532_source_fs_set(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;
	unsigned int rate, min;

	rate = ucontrol->value.integer.value[0];

	if (8000 <= rate <= 384000)
		priv->source_fs = rate;
	else
		dev_err(afe->dev, "%s rate %lu is invaild\n", __func__, rate);
	dev_dbg(afe->dev, "%s rate %lu\n", __func__, rate);

	return 0;
}

static int mt8532_afe_multi_in_irq_mode_sel_put(
		struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;

	priv->multi_in_data.irq_cnt_mode = ucontrol->value.integer.value[0];
	priv->multi_in2_data.irq_cnt_mode = ucontrol->value.integer.value[0];

	return 0;
}

static int mt8532_afe_multi_in_irq_mode_sel_get(
		struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;

	ucontrol->value.integer.value[0] = priv->multi_in_data.irq_cnt_mode;

	return 0;
}

static int mt8532_afe_multi_in_det_enable_get(
		struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;

	ucontrol->value.integer.value[0] =
		afe_priv->use_multi_in_det;

	return 0;
}

static int mt8532_afe_multi_in_det_enable_put(
		struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;

	afe_priv->use_multi_in_det =
		ucontrol->value.integer.value[0];

	return 0;
}

static int mt8532_apll2_clk_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;
	struct clk *clk;

	clk = priv->clocks[MT8532_CLK_APMIXED_APLL2];

	ucontrol->value.integer.value[0] = clk_get_rate(clk);
	return 0;
}

static int mt8532_apll2_clk_set(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	//struct snd_soc_platform *plat = snd_soc_kcontrol_platform(kcontrol);
	//struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(plat);
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;
	struct clk *clk;
	unsigned long rate, min;

	rate = ucontrol->value.integer.value[0];

	min = MT8532_APLL2_RATE - MT8532_APLL_ADJUST_RANGE;

	rate = max(rate, min);

	dev_dbg(afe->dev, "%s rate %lu\n", __func__, rate);

	clk = priv->clocks[MT8532_CLK_APMIXED_APLL2];

	clk_set_rate(clk, rate);

	return 0;
}

static int mt8532_afe_etdm_out_data_source_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int src = ETDM_IN_FROM_PAD;
	unsigned int val;

	if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Data_Source_Select")) {
		mt8532_afe_enable_main_clk(afe);
		regmap_read(afe->regmap, ETDM_COWORK_CON2, &val);
		mt8532_afe_disable_main_clk(afe);
		val = val & ETDM_COWORK_CON2_TDM_OUT3_DATA_SEL_MASK;
		if (val == ETDM_COWORK_CON2_TDM_OUT3_DATA_SEL_OUT1)
			src = ETDM_OUT_FROM_ETDM_OUT1;
		else if (val == ETDM_COWORK_CON2_TDM_OUT3_DATA_SEL_OUT2)
			src = ETDM_OUT_FROM_ETDM_OUT2;
	}

	ucontrol->value.integer.value[0] = src;
	return 0;
}

static int mt8532_afe_etdm_out_data_source_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int src;

	src = ucontrol->value.integer.value[0];

	mt8532_afe_enable_main_clk(afe);
	if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Data_Source_Select")) {
		if (src == ETDM_OUT_FROM_ETDM_OUT1)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON2,
			ETDM_COWORK_CON2_TDM_OUT3_DATA_SEL_MASK,
			ETDM_COWORK_CON2_TDM_OUT3_DATA_SEL_OUT1);
		else if (src == ETDM_OUT_FROM_ETDM_OUT2)
			regmap_update_bits(afe->regmap, ETDM_COWORK_CON2,
			ETDM_COWORK_CON2_TDM_OUT3_DATA_SEL_MASK,
			ETDM_COWORK_CON2_TDM_OUT3_DATA_SEL_OUT2);
	}

	mt8532_afe_disable_main_clk(afe);

	return 0;
}

static int mt8532_afe_acc_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 1;
	return 0;
}

static int mt8532_afe_acc_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	unsigned int acc = 0;

	mt8532_afe_enable_main_clk(afe);

	regmap_read(afe->regmap, ASYS_IRQ_MON2, &acc);

	mt8532_afe_disable_main_clk(afe);

	acc &= 0xffffff;

	acc = 0xffffff - acc + 1;

	acc &= 0xffffff;

	ucontrol->value.integer.value[0] = acc;
	return 0;
}

static int mt8532_afe_etdm_out1_sdata_sel_put(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_platform *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	const char *name = kcontrol->id.name;
	size_t i;
	struct {
		char *name;
		unsigned int reg;
		unsigned int offset;
		unsigned int len;
	} sdata_sel_table[] = {
		{ "Sdata0", ETDM_OUT1_CON3, 0, 4 },
		{ "Sdata1", ETDM_OUT1_CON3, 4, 4 },
		{ "Sdata2", ETDM_OUT1_CON3, 8, 4 },
		{ "Sdata3", ETDM_OUT1_CON3, 12, 4 },
		{ "Sdata4", ETDM_OUT1_CON3, 16, 4 },
		{ "Sdata5", ETDM_OUT1_CON3, 20, 4 },
		{ "Sdata6", ETDM_OUT1_CON3, 24, 4 },
		{ "Sdata7", ETDM_OUT1_CON3, 28, 4 },
	};
	unsigned int start_ch_sel = ucontrol->value.integer.value[0];

	for (i = 0; i < ARRAY_SIZE(sdata_sel_table); i++) {
		if (strstr(name, sdata_sel_table[i].name)) {
			mt8532_afe_enable_main_clk(afe);
			regmap_update_bits(afe->regmap, sdata_sel_table[i].reg,
				GENMASK(sdata_sel_table[i].offset
				+ sdata_sel_table[i].len - 1,
				sdata_sel_table[i].offset),
				start_ch_sel << sdata_sel_table[i].offset);
			mt8532_afe_disable_main_clk(afe);
			break;
		}
	}

	return 0;
}

static int mt8532_afe_etdm_out1_sdata_sel_get(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_platform *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	const char *name = kcontrol->id.name;
	size_t i;
	struct {
		char *name;
		unsigned int reg;
		unsigned int offset;
		unsigned int len;
	} sdata_sel_table[] = {
		{ "Sdata0", ETDM_OUT1_CON3, 0, 4 },
		{ "Sdata1", ETDM_OUT1_CON3, 4, 4 },
		{ "Sdata2", ETDM_OUT1_CON3, 8, 4 },
		{ "Sdata3", ETDM_OUT1_CON3, 12, 4 },
		{ "Sdata4", ETDM_OUT1_CON3, 16, 4 },
		{ "Sdata5", ETDM_OUT1_CON3, 20, 4 },
		{ "Sdata6", ETDM_OUT1_CON3, 24, 4 },
		{ "Sdata7", ETDM_OUT1_CON3, 28, 4 },
	};
	unsigned int val = 0, mask = 0;

	for (i = 0; i < ARRAY_SIZE(sdata_sel_table); i++) {
		if (strstr(name, sdata_sel_table[i].name)) {
			mt8532_afe_enable_main_clk(afe);
			regmap_read(afe->regmap, sdata_sel_table[i].reg, &val);
			mask = GENMASK(sdata_sel_table[i].offset
					+ sdata_sel_table[i].len - 1,
					sdata_sel_table[i].offset);
			val = (val & mask) >> sdata_sel_table[i].offset;
			mt8532_afe_disable_main_clk(afe);
			break;
		}
	}

	ucontrol->value.integer.value[0] = val;
	return 0;

}

static int mt8532_afe_etdm_out1_force_on_sel_put(
	struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_platform *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	struct mt8532_etdm_data *etdm_data;
	unsigned int etdm1_out_force_on = 0;
	int i = 0;

	struct {
			unsigned int type;
			unsigned int rate;
			unsigned int mclk;
		} force_on_table[] = {
			{FORCE_ON_NONE, 0,      0 },
			{FORCE_ON_48K,  48000,  12288000},
			{FORCE_ON_96K,  96000,  24576000},
			{FORCE_ON_192K, 192000, 49152000},
			{FORCE_ON_44D1K, 44100, 11289600},
            {FORCE_ON_88D2K, 88200, 22579200},
		};

	afe_priv->etdm1_out_force_on_sel = ucontrol->value.integer.value[0];
	dev_info(afe->dev, "%s etdm_out1_force_on %d\n", __func__,
		afe_priv->etdm1_out_force_on_sel);
	etdm_data = &afe_priv->etdm_data[MT8532_ETDM1];
	etdm1_out_force_on = afe_priv->etdm1_out_force_on_sel;

	if (etdm1_out_force_on == FORCE_ON_NONE) {
		if (etdm_data->force_on_status[SNDRV_PCM_STREAM_PLAYBACK]
				== true)
			mt8532_afe_etdm_out1_force_off(afe);
	} else {
		if (etdm_data->force_on_status[SNDRV_PCM_STREAM_PLAYBACK]
				== false) {
			mt8532_afe_etdm_out1_set_force_on(afe,
				force_on_table[etdm1_out_force_on].mclk,
				force_on_table[etdm1_out_force_on].rate);
		} else if (etdm_data->force_rate[SNDRV_PCM_STREAM_PLAYBACK]
			!= force_on_table[etdm1_out_force_on].rate) {
			mt8532_afe_etdm_out1_force_off(afe);
			mt8532_afe_etdm_out1_set_force_on(afe,
				force_on_table[etdm1_out_force_on].mclk,
				force_on_table[etdm1_out_force_on].rate);
		} else
			return 0;
	}
	return 0;
}

static int mt8532_afe_etdm_out1_force_on_sel_get(
	struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_platform *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;

	ucontrol->value.integer.value[0] = afe_priv->etdm1_out_force_on_sel;

	return 0;
}

static int mt8532_afe_etdm_out2_force_on_sel_put(
	struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_platform *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;
	struct mt8532_etdm_data *etdm_data;
	unsigned int etdm1_out_force_on = 0;
	int i = 0;

	struct {
			unsigned int type;
			unsigned int rate;
			unsigned int mclk;
		} force_on_table[] = {
			{FORCE_ON_NONE, 0,      0 },
			{FORCE_ON_48K,  48000,  12288000 },
			{FORCE_ON_96K,  96000,  24576000},
			{FORCE_ON_192K, 192000, 49152000 },
		};

	afe_priv->etdm1_out_force_on_sel = ucontrol->value.integer.value[0];
	dev_info(afe->dev, "%s etdm_out1_force_on %d\n", __func__,
		afe_priv->etdm1_out_force_on_sel);
	etdm_data = &afe_priv->etdm_data[MT8532_ETDM1];
	etdm1_out_force_on = afe_priv->etdm1_out_force_on_sel;

	if (etdm1_out_force_on == FORCE_ON_NONE) {
		if (etdm_data->force_on_status[SNDRV_PCM_STREAM_PLAYBACK]
				== true)
			mt8532_afe_etdm_out1_force_off(afe);
	} else {
		if (etdm_data->force_on_status[SNDRV_PCM_STREAM_PLAYBACK]
				== false) {
			mt8532_afe_etdm_out1_set_force_on(afe,
				force_on_table[etdm1_out_force_on].mclk,
				force_on_table[etdm1_out_force_on].rate);
		} else if (etdm_data->force_rate[SNDRV_PCM_STREAM_PLAYBACK]
			!= force_on_table[etdm1_out_force_on].rate) {
			mt8532_afe_etdm_out1_force_off(afe);
			mt8532_afe_etdm_out1_set_force_on(afe,
				force_on_table[etdm1_out_force_on].mclk,
				force_on_table[etdm1_out_force_on].rate);
		} else
			return 0;
	}
	return 0;
}

static int mt8532_afe_etdm_out2_force_on_sel_get(
	struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_platform *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;

	ucontrol->value.integer.value[0] = afe_priv->etdm1_out_force_on_sel;

	return 0;
}

static int mt8532_afe_ul2_odd_use_even_get(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;

	ucontrol->value.integer.value[0] = priv->ul2_odd_use_even;
	return 0;
}

static int mt8532_afe_ul2_odd_use_even_put(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *plat = snd_soc_kcontrol_component(kcontrol);
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(plat);
	struct mt8532_afe_private *priv = afe->platform_priv;

	if (ucontrol->value.integer.value[0] != priv->ul2_odd_use_even) {
		if (ucontrol->value.integer.value[0])
			priv->ul2_odd_use_even = 1;
		else
			priv->ul2_odd_use_even = 0;
	}

	dev_info(afe->dev, "%s ul2_odd_use_even %d, %d\n", __func__,
		priv->ul2_odd_use_even, ucontrol->value.integer.value[0]);
	return 0;
}

#define SND_SOC_CTL_RO(xname, xhandler_info, xhandler_get) \
{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
	.access = SNDRV_CTL_ELEM_ACCESS_READ | \
		  SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
	.info = xhandler_info, .get = xhandler_get }

static const struct snd_kcontrol_new mt8532_afe_controls[] = {
	SOC_ENUM_EXT("MULTI_IN_Data_Source_Select",
		     mt8532_afe_soc_enums[CTRL_MULTI_IN_DATA_SRC],
		     mt8532_afe_multi_in_data_source_get,
		     mt8532_afe_multi_in_data_source_put),
	SOC_ENUM("Multi_In_Bck_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_BCK_SEL]),
	SOC_ENUM("Multi_In_Lrck_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_LRCK_SEL]),
	SOC_ENUM("Multi_In_Sdata0_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_SDATA0_SEL]),
	SOC_ENUM("Multi_In_Sdata1_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_SDATA1_SEL]),
	SOC_ENUM("Multi_In_Sdata2_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_SDATA2_SEL]),
	SOC_ENUM("Multi_In_Sdata3_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_SDATA3_SEL]),
	SOC_ENUM("Multi_In2_Bck_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN2_BCK_SEL]),
	SOC_ENUM("Multi_In2_Lrck_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN2_LRCK_SEL]),
	SOC_ENUM("Multi_In2_Sdata0_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN2_SDATA0_SEL]),
	SOC_ENUM("Multi_In2_Sdata1_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN2_SDATA1_SEL]),
	SOC_ENUM("Multi_In2_Sdata2_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN2_SDATA2_SEL]),
	SOC_ENUM("Multi_In2_Sdata3_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN2_SDATA3_SEL]),
	SOC_SINGLE_BOOL_EXT("SineGen_Enable_Switch",
			    0,
			    mt8532_afe_singen_enable_get,
			    mt8532_afe_singen_enable_put),
#ifdef CURRENTLY_AUDIO_NOT_USE
	SOC_ENUM_EXT("SineGen_Loopback_Mode_Select",
		     mt8532_afe_soc_enums[CTRL_SINEGEN_LOOPBACK_MODE],
		     mt8532_afe_sinegen_loopback_mode_get,
		     mt8532_afe_sinegen_loopback_mode_put),
#endif
	SOC_ENUM_EXT("SineGen_Timing_Select",
		     mt8532_afe_soc_enums[CTRL_SINEGEN_TIMING],
		     mt8532_afe_sinegen_timing_get,
		     mt8532_afe_sinegen_timing_put),

	SOC_SINGLE_RANGE("SineGen_Amp_Div_Ch1",
			 AFE_SINEGEN_CON0, 5, 0, 7, 0),
	SOC_SINGLE_RANGE("SineGen_Amp_Div_Ch2",
			 AFE_SINEGEN_CON0, 17, 0, 7, 0),
	SOC_SINGLE_RANGE("SineGen_Freq_Div_Ch1",
			 AFE_SINEGEN_CON0, 0, 0, 31, 0),
	SOC_SINGLE_RANGE("SineGen_Freq_Div_Ch2",
			 AFE_SINEGEN_CON0, 12, 0, 31, 0),

	SOC_SINGLE_BOOL_EXT("Mini_Clk_En",
			    0,
			    mt8532_afe_mini_clk_en_get,
			    mt8532_afe_mini_clk_en_put),

	SOC_SINGLE_BOOL_EXT("ETDM_OUT1_SineGen_Select",
			    0,
			    mt8532_afe_tdm_out1_sinegen_get,
			    mt8532_afe_tdm_out1_sinegen_put),
	SOC_SINGLE_BOOL_EXT("ETDM_OUT2_SineGen_Select",
					0,
					mt8532_afe_tdm_out2_sinegen_get,
					mt8532_afe_tdm_out2_sinegen_put),
	SOC_SINGLE_BOOL_EXT("ETDM_OUT3_SineGen_Select",
					0,
					mt8532_afe_tdm_out3_sinegen_get,
					mt8532_afe_tdm_out3_sinegen_put),

	SOC_SINGLE_RANGE("Multi_In_SineGen_Amp_Div_Ch1",
			AFE_MPHONE_MULTI_CON2, 5, 0, 7, 0),
	SOC_SINGLE_RANGE("Multi_In_SineGen_Amp_Div_Ch2",
			AFE_MPHONE_MULTI_CON2, 13, 0, 7, 0),
	SOC_SINGLE_RANGE("Multi_In_SineGen_Freq_Div_Ch1",
			AFE_MPHONE_MULTI_CON2, 0, 0, 31, 0),
	SOC_SINGLE_RANGE("Multi_In_SineGen_Freq_Div_Ch2",
			AFE_MPHONE_MULTI_CON2, 8, 0, 31, 0),

	SOC_SINGLE_BOOL_EXT("Multi_In_SineGen_Enable",
			0,
			mt8532_afe_multi_in_sinegen_get,
			mt8532_afe_multi_in_sinegen_put),

	SOC_SINGLE_RANGE("Multi_In2_SineGen_Amp_Div_Ch1",
			AFE_MPHONE_MULTI2_CON2, 5, 0, 7, 0),
	SOC_SINGLE_RANGE("Multi_In2_SineGen_Amp_Div_Ch2",
			AFE_MPHONE_MULTI2_CON2, 13, 0, 7, 0),
	SOC_SINGLE_RANGE("Multi_In2_SineGen_Freq_Div_Ch1",
			AFE_MPHONE_MULTI2_CON2, 0, 0, 31, 0),
	SOC_SINGLE_RANGE("Multi_In2_SineGen_Freq_Div_Ch2",
			AFE_MPHONE_MULTI2_CON2, 8, 0, 31, 0),

	SOC_SINGLE_BOOL_EXT("Multi_In2_SineGen_Enable",
			0,
			mt8532_afe_multi_in2_sinegen_get,
			mt8532_afe_multi_in2_sinegen_put),

	SOC_SINGLE_BOOL_EXT("DMIC_SineGen_Enable",
			0,
			mt8532_afe_dmic_sinegen_enable_get,
			mt8532_afe_dmic_sinegen_enable_put),

	SOC_SINGLE_BOOL_EXT("UL8_SineGen_Select",
			    0,
			    mt8532_afe_ul8_sinegen_get,
			    mt8532_afe_ul8_sinegen_put),

	SOC_ENUM_EXT("ETDM_IN1_Data_Source_Select",
		     mt8532_afe_soc_enums[CTRL_ETDM_IN_DATA_SRC],
		     mt8532_afe_etdm_in_data_source_get,
		     mt8532_afe_etdm_in_data_source_put),
	SOC_ENUM_EXT("ETDM_IN1_Slave_Mode_Source_Select",
		     mt8532_afe_soc_enums[CTRL_ETDM_IN_SLAVE_MODE_SRC],
		     mt8532_afe_etdm_in_slave_mode_src_get,
		     mt8532_afe_etdm_in_slave_mode_src_put),

	SOC_ENUM_EXT("ETDM_IN2_Data_Source_Select",
		     mt8532_afe_soc_enums[CTRL_ETDM_IN_DATA_SRC],
		     mt8532_afe_etdm_in_data_source_get,
		     mt8532_afe_etdm_in_data_source_put),
	SOC_ENUM_EXT("ETDM_IN2_Slave_Mode_Source_Select",
		     mt8532_afe_soc_enums[CTRL_ETDM_IN_SLAVE_MODE_SRC],
		     mt8532_afe_etdm_in_slave_mode_src_get,
		     mt8532_afe_etdm_in_slave_mode_src_put),
#ifdef CURRENTLY_AUDIO_NOT_USE
	SOC_SINGLE_BOOL_EXT("PCM_Tx2Rx_Loopback_Switch",
			    0,
			    mt8532_afe_pcm_loopback_get,
			    mt8532_afe_pcm_loopback_put),
	SOC_SINGLE_BOOL_EXT("DMIC_SineGen_Enable_Switch",
		     0,
		     mt8532_afe_dmic_sinegen_enable_get,
		     mt8532_afe_dmic_sinegen_enable_put),
#ifdef CURRENTLY_AUDIO_NOT_USE
	SOC_SINGLE_BOOL_EXT("DMIC_RampGen_Enable_Switch",
		     0,
		     mt8532_afe_dmic_rampgen_enable_get,
		     mt8532_afe_dmic_rampgen_enable_put),
#endif
	SOC_SINGLE_BOOL_EXT("GASRC_In_SineGen_Select",
			    0,
			    mt8532_afe_gasrc_in_sinegen_get,
			    mt8532_afe_gasrc_in_sinegen_put),
	SOC_SINGLE_BOOL_EXT("GASRC_Out_SineGen_Select",
			    0,
			    mt8532_afe_gasrc_out_sinegen_get,
			    mt8532_afe_gasrc_out_sinegen_put),
	SOC_ENUM_EXT("TDMOUT_O00_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O01_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O02_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O03_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O04_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O05_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O06_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O07_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O08_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O09_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O10_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O11_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O12_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O13_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O14_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_ENUM_EXT("TDMOUT_O15_Source_Select",
		     mt8532_afe_soc_enums[CTRL_TDMOUT_CONN_SRC],
		     mt8532_afe_tdm_conn_source_get,
		     mt8532_afe_tdm_conn_source_put),
	SOC_SINGLE_BOOL_EXT("Spdif_Output_IEC61937_Switch",
			    0,
			    mt8532_afe_spdif_output_iec61937_get,
			    mt8532_afe_spdif_output_iec61937_put),
	SOC_ENUM("Multi_In_Bck_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_BCK_SEL]),
	SOC_ENUM("Multi_In_Lrck_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_LRCK_SEL]),
	SOC_ENUM("Multi_In_Sdata0_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_SDATA0_SEL]),
	SOC_ENUM("Multi_In_Sdata1_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_SDATA1_SEL]),
	SOC_ENUM("Multi_In_Sdata2_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_SDATA2_SEL]),
	SOC_ENUM("Multi_In_Sdata3_Select",
		 mt8532_afe_soc_enums[CTRL_MULTI_IN_SDATA3_SEL]),
#endif

	SOC_ENUM_EXT("Spdif_In_Port_Select",
		     mt8532_afe_soc_enums[CTRL_SPDIF_IN_PORT_SEL],
		     mt8532_afe_spdif_in_port_get,
		     mt8532_afe_spdif_in_port_put),
	SND_SOC_CTL_RO("Spdif_In_Channel_Status_Data",
		       mt8532_afe_spdif_in_chs_data_info,
		       mt8532_afe_spdif_in_chs_data_get),
	SND_SOC_CTL_RO(SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
		       mt8532_afe_spdif_in_iec958_info,
		       mt8532_afe_spdif_in_iec958_get),
	SND_SOC_CTL_RO("Spdif_In_Rate",
		       mt8532_afe_spdif_in_rate_info,
		       mt8532_afe_spdif_in_rate_get),
	SND_SOC_CTL_RO("Spdif_In_Stream_Type",
			mt8532_afe_spdif_in_stream_type_info,
			mt8532_afe_spdif_in_stream_type_get),
	SND_SOC_CTL_RO("Spdif_In_User_Code",
			mt8532_afe_spdif_in_user_code_info,
			mt8532_afe_spdif_in_user_code_get),
	SND_SOC_CTL_RO("Spdif_In_Info",
			mt8532_afe_spdif_in_information_info,
			mt8532_afe_spdif_in_information_get),
	SND_SOC_CTL_RO("Multi_In_Info",
			mt8532_afe_multi_in_information_info,
			mt8532_afe_multi_in_information_get),
	SND_SOC_CTL_RO("Multi_In2_Info",
			mt8532_afe_multi_in_information_info,
			mt8532_afe_multi_in2_information_get),
#ifdef CURRENTLY_AUDIO_NOT_USE
	SOC_SINGLE("Spdif_Out_to_Spdif_In_Loopback_Switch",
		   AFE_SPDIFIN_CFG1, 14, 1, 0),
#endif
	SOC_SINGLE_EXT("Apll_Clk_48_Domain", 0, 0,
		MT8532_APLL1_RATE + MT8532_APLL_ADJUST_RANGE, 0,
		mt8532_apll1_clk_get, mt8532_apll1_clk_set),
	SOC_SINGLE_EXT("Apll_Clk_44_Domain", 0, 0,
		MT8532_APLL2_RATE + MT8532_APLL_ADJUST_RANGE, 0,
		mt8532_apll2_clk_get, mt8532_apll2_clk_set),
	SOC_SINGLE_EXT("Source_FS", 0, 0,
		MT8532_AFE_MAX_FS, 0,
		mt8532_source_fs_get, mt8532_source_fs_set),
#ifdef CURRENTLY_AUDIO_NOT_USE
	SOC_ENUM_EXT("DL2_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
#endif

	SOC_ENUM_EXT("DL3_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("DL6_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("DL7_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("DL10_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("DLM_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("UL1_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("UL2_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("UL3_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("UL4_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("UL5_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("UL6_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("UL8_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("UL9_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("UL10_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),

	SOC_ENUM_EXT("GARC0_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC1_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC2_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC3_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC4_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC5_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC6_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC7_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC8_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC9_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC10_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC11_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC12_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC13_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC14_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC15_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC16_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC17_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC18_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("GARC19_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("ETDM1_OUT_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("ETDM1_IN_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("ETDM2_OUT_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("ETDM2_IN_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("ETDM3_OUT_Apll_Sel",
		     mt8532_afe_soc_enums[CTRL_ENGENSYS_DOMAIN],
		     mt8532_afe_engen_apll_get,
		     mt8532_afe_engen_apll_put),
	SOC_ENUM_EXT("ETDM1_OUT_MOD_Sel",
				 mt8532_afe_soc_enums[CTRL_ETDM_MOD],
				 mt8532_afe_etdm_mod_get,
				 mt8532_afe_etdm_mod_put),
	SOC_ENUM_EXT("ETDM3_OUT_MOD_Sel",
					 mt8532_afe_soc_enums[CTRL_ETDM_MOD],
					 mt8532_afe_etdm_mod_get,
					 mt8532_afe_etdm_mod_put),
	SOC_ENUM_EXT("ETDM1_OUT_DSD_BIT_Sel",
				 mt8532_afe_soc_enums[CTRL_ETDM_DSD_BIT],
				 mt8532_afe_etdm_dsd_bit_get,
				 mt8532_afe_etdm_dsd_bit_put),
	SOC_ENUM_EXT("ETDM3_OUT_DSD_BIT_Sel",
				mt8532_afe_soc_enums[CTRL_ETDM_DSD_BIT],
				mt8532_afe_etdm_dsd_bit_get,
				mt8532_afe_etdm_dsd_bit_put),
	SOC_ENUM_EXT("ETDM1_OUT_DSD_CLK_Sel",
				 mt8532_afe_soc_enums[CTRL_ETDM_DSD_CLK],
				 mt8532_afe_etdm_dsd_clk_get,
				 mt8532_afe_etdm_dsd_clk_put),
	SOC_ENUM_EXT("ETDM3_OUT_DSD_CLK_Sel",
				mt8532_afe_soc_enums[CTRL_ETDM_DSD_CLK],
				mt8532_afe_etdm_dsd_clk_get,
				mt8532_afe_etdm_dsd_clk_put),
	SOC_ENUM_EXT("Aud_In_Sel",
				mt8532_afe_soc_enums[CTRL_AUDIO_IN_SEL],
				mt8532_afe_aud_in_sel_get,
				mt8532_afe_aud_in_sel_put),
	SOC_ENUM_EXT("Apll_Tuner_Range_Sel",
			    mt8532_afe_soc_enums[CTRL_APLL_TUNER_RANGE_SEL],
				mt8532_afe_apll_tuner_range_sel_get,
				mt8532_afe_apll_tuner_range_sel_put),
	SOC_ENUM_EXT("Multi_In_Irq_Mode",
			mt8532_afe_soc_enums[CTRL_MULTI_IN_IRQ_MODE_SEL],
			mt8532_afe_multi_in_irq_mode_sel_get,
			mt8532_afe_multi_in_irq_mode_sel_put),
	SOC_SINGLE_BOOL_EXT("Multi_In_Det_En",
			0,
			mt8532_afe_multi_in_det_enable_get,
			mt8532_afe_multi_in_det_enable_put),
	SOC_SINGLE_BOOL_EXT("Masrc_Fix_Out_Fs_En",
			0,
			mt8532_afe_masrc_fix_output_fs_enable_get,
			mt8532_afe_masrc_fix_output_fs_enable_put),
	SOC_ENUM_EXT("ETDM_OUT3_Data_Source_Select",
			mt8532_afe_soc_enums[CTRL_ETDM_OUT_DATA_SRC],
			mt8532_afe_etdm_out_data_source_get,
			mt8532_afe_etdm_out_data_source_put),
	SND_SOC_CTL_RO("Audio_Clock_Counter",
		mt8532_afe_acc_info,
		mt8532_afe_acc_get),
	SOC_ENUM_EXT("Etdm_Out1_Sdata0_Sel",
			mt8532_afe_soc_enums[CTRL_ETDM_OUT1_SDATA_SEL],
			mt8532_afe_etdm_out1_sdata_sel_get,
			mt8532_afe_etdm_out1_sdata_sel_put),
	SOC_ENUM_EXT("Etdm_Out1_Sdata1_Sel",
			mt8532_afe_soc_enums[CTRL_ETDM_OUT1_SDATA_SEL],
			mt8532_afe_etdm_out1_sdata_sel_get,
			mt8532_afe_etdm_out1_sdata_sel_put),
	SOC_ENUM_EXT("Etdm_Out1_Sdata2_Sel",
			mt8532_afe_soc_enums[CTRL_ETDM_OUT1_SDATA_SEL],
			mt8532_afe_etdm_out1_sdata_sel_get,
			mt8532_afe_etdm_out1_sdata_sel_put),
	SOC_ENUM_EXT("Etdm_Out1_Sdata3_Sel",
			mt8532_afe_soc_enums[CTRL_ETDM_OUT1_SDATA_SEL],
			mt8532_afe_etdm_out1_sdata_sel_get,
			mt8532_afe_etdm_out1_sdata_sel_put),
	SOC_ENUM_EXT("Etdm_Out1_Sdata4_Sel",
			mt8532_afe_soc_enums[CTRL_ETDM_OUT1_SDATA_SEL],
			mt8532_afe_etdm_out1_sdata_sel_get,
			mt8532_afe_etdm_out1_sdata_sel_put),
	SOC_ENUM_EXT("Etdm_Out1_Sdata5_Sel",
			mt8532_afe_soc_enums[CTRL_ETDM_OUT1_SDATA_SEL],
			mt8532_afe_etdm_out1_sdata_sel_get,
			mt8532_afe_etdm_out1_sdata_sel_put),
	SOC_ENUM_EXT("Etdm_Out1_Sdata6_Sel",
			mt8532_afe_soc_enums[CTRL_ETDM_OUT1_SDATA_SEL],
			mt8532_afe_etdm_out1_sdata_sel_get,
			mt8532_afe_etdm_out1_sdata_sel_put),
	SOC_ENUM_EXT("Etdm_Out1_Force_On_Sel",
			mt8532_afe_soc_enums[CTRL_ETDM_OUT1_FORCE_ON_SEL],
			mt8532_afe_etdm_out1_force_on_sel_get,
			mt8532_afe_etdm_out1_force_on_sel_put),
	SOC_ENUM_EXT("Etdm_Out2_Force_On_Sel",
			mt8532_afe_soc_enums[CTRL_ETDM_OUT2_FORCE_ON_SEL],
			mt8532_afe_etdm_out2_force_on_sel_get,
			mt8532_afe_etdm_out2_force_on_sel_put),
	SOC_SINGLE_BOOL_EXT("UL2_Odd_Use_Even",
			0,
			mt8532_afe_ul2_odd_use_even_get,
			mt8532_afe_ul2_odd_use_even_put),
};


int mt8532_afe_add_controls(struct snd_soc_component *platform)
{
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(platform);
	struct mt8532_afe_private *afe_priv = afe->platform_priv;

	afe_priv->card = platform->card->snd_card;

	return snd_soc_add_component_controls(platform, mt8532_afe_controls,
					     ARRAY_SIZE(mt8532_afe_controls));
}

