Browse Source

ASoC: Add driver support for lpass digital codec

Add driver support to enable lpass digital codec for
audio playback and capture usecases.

Change-Id: I3d31d31f340db79334700e8fd495f40479e0ec6c
Signed-off-by: Sudheer Papothi <[email protected]>
Sudheer Papothi 4 years ago
parent
commit
e3ab630202

+ 1 - 0
asoc/codecs/Kbuild

@@ -256,6 +256,7 @@ ifeq ($(KERNEL_BUILD), 1)
 	obj-y	+= wcd937x/
 	obj-y	+= wcd938x/
 	obj-y	+= bolero/
+	obj-y	+= lpass-cdc/
 	obj-y	+= wsa883x/
 	obj-y	+= rouleur/
 endif

+ 159 - 0
asoc/codecs/lpass-cdc/Kbuild

@@ -0,0 +1,159 @@
+# We can build either as part of a standalone Kernel build or as
+# an external module.  Determine which mechanism is being used
+ifeq ($(MODNAME),)
+	KERNEL_BUILD := 1
+else
+	KERNEL_BUILD := 0
+endif
+
+
+
+ifeq ($(KERNEL_BUILD), 1)
+	# These are configurable via Kconfig for kernel-based builds
+	# Need to explicitly configure for Android-based builds
+	AUDIO_BLD_DIR := $(shell pwd)/kernel/msm-5.4
+	AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
+endif
+
+ifeq ($(KERNEL_BUILD), 0)
+	ifeq ($(CONFIG_ARCH_SM6150), y)
+		include $(AUDIO_ROOT)/config/sm6150auto.conf
+		export
+		INCS    +=  -include $(AUDIO_ROOT)/config/sm6150autoconf.h
+	endif
+	ifeq ($(CONFIG_ARCH_TRINKET), y)
+		include $(AUDIO_ROOT)/config/sm6150auto.conf
+		export
+		INCS    +=  -include $(AUDIO_ROOT)/config/sm6150autoconf.h
+	endif
+	ifeq ($(CONFIG_ARCH_KONA), y)
+		include $(AUDIO_ROOT)/config/konaauto.conf
+		INCS    +=  -include $(AUDIO_ROOT)/config/konaautoconf.h
+	endif
+	ifeq ($(CONFIG_ARCH_LITO), y)
+		include $(AUDIO_ROOT)/config/litoauto.conf
+		export
+		INCS    +=  -include $(AUDIO_ROOT)/config/litoautoconf.h
+	endif
+	ifeq ($(CONFIG_ARCH_BENGAL), y)
+		include $(AUDIO_ROOT)/config/bengalauto.conf
+		export
+		INCS    +=  -include $(AUDIO_ROOT)/config/bengalautoconf.h
+	endif
+	ifeq ($(CONFIG_ARCH_QCS405), y)
+		include $(AUDIO_ROOT)/config/qcs405auto.conf
+		export
+		INCS    +=  -include $(AUDIO_ROOT)/config/qcs405autoconf.h
+	endif
+endif
+
+# As per target team, build is done as follows:
+# Defconfig : build with default flags
+# Slub      : defconfig  + CONFIG_SLUB_DEBUG := y +
+#	      CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y
+# Perf      : Using appropriate msmXXXX-perf_defconfig
+#
+# Shipment builds (user variants) should not have any debug feature
+# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds
+# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since
+# there is no other way to identify defconfig builds, QTI internal
+# representation of perf builds (identified using the string 'perf'),
+# is used to identify if the build is a slub or defconfig one. This
+# way no critical debug feature will be enabled for perf and shipment
+# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT
+# config.
+
+############ UAPI ############
+UAPI_DIR :=	uapi/audio
+UAPI_INC :=	-I$(AUDIO_ROOT)/include/$(UAPI_DIR)
+
+############ COMMON ############
+COMMON_DIR :=	include
+COMMON_INC :=	-I$(AUDIO_ROOT)/$(COMMON_DIR)
+
+############ LPASS_CDC ############
+
+# for LPASS_CDC Codec
+ifdef CONFIG_SND_SOC_LPASS_CDC
+	LPASS_CDC_OBJS += lpass-cdc.o
+	LPASS_CDC_OBJS += lpass-cdc-utils.o
+	LPASS_CDC_OBJS += lpass-cdc-regmap.o
+	LPASS_CDC_OBJS += lpass-cdc-tables.o
+	LPASS_CDC_OBJS += lpass-cdc-clk-rsc.o
+endif
+
+ifdef CONFIG_WSA_MACRO
+	WSA_OBJS += lpass-cdc-wsa-macro.o
+endif
+
+ifdef CONFIG_VA_MACRO
+	VA_OBJS += lpass-cdc-va-macro.o
+endif
+
+ifdef CONFIG_TX_MACRO
+	TX_OBJS += lpass-cdc-tx-macro.o
+endif
+
+ifdef CONFIG_RX_MACRO
+	RX_OBJS += lpass-cdc-rx-macro.o
+endif
+
+LINUX_INC +=	-Iinclude/linux
+
+INCS +=		$(COMMON_INC) \
+		$(UAPI_INC)
+
+EXTRA_CFLAGS += $(INCS)
+
+
+CDEFINES +=	-DANI_LITTLE_BYTE_ENDIAN \
+		-DANI_LITTLE_BIT_ENDIAN \
+		-DDOT11F_LITTLE_ENDIAN_HOST \
+		-DANI_COMPILER_TYPE_GCC \
+		-DANI_OS_TYPE_ANDROID=6 \
+		-DPTT_SOCK_SVC_ENABLE \
+		-Wall\
+		-Werror\
+		-D__linux__
+
+KBUILD_CPPFLAGS += $(CDEFINES)
+
+# Currently, for versions of gcc which support it, the kernel Makefile
+# is disabling the maybe-uninitialized warning.  Re-enable it for the
+# AUDIO driver.  Note that we must use EXTRA_CFLAGS here so that it
+# will override the kernel settings.
+ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y)
+EXTRA_CFLAGS += -Wmaybe-uninitialized
+endif
+#EXTRA_CFLAGS += -Wmissing-prototypes
+
+ifeq ($(call cc-option-yn, -Wheader-guard),y)
+EXTRA_CFLAGS += -Wheader-guard
+endif
+
+ifeq ($(KERNEL_BUILD), 0)
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers
+endif
+
+# Module information used by KBuild framework
+obj-$(CONFIG_SND_SOC_LPASS_CDC) += lpass_cdc_dlkm.o
+lpass_cdc_dlkm-y := $(LPASS_CDC_OBJS)
+
+obj-$(CONFIG_WSA_MACRO) += wsa_macro_dlkm.o
+wsa_macro_dlkm-y := $(WSA_OBJS)
+
+obj-$(CONFIG_VA_MACRO) += va_macro_dlkm.o
+va_macro_dlkm-y := $(VA_OBJS)
+
+obj-$(CONFIG_TX_MACRO) += tx_macro_dlkm.o
+tx_macro_dlkm-y := $(TX_OBJS)
+
+obj-$(CONFIG_RX_MACRO) += rx_macro_dlkm.o
+rx_macro_dlkm-y := $(RX_OBJS)
+
+# inject some build related information
+DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\"

+ 111 - 0
asoc/codecs/lpass-cdc/internal.h

@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _LPASS_CDC_INTERNAL_H
+#define _LPASS_CDC_INTERNAL_H
+
+#include "lpass-cdc-registers.h"
+
+#define LPASS_CDC_CHILD_DEVICES_MAX 6
+
+/* from lpass_cdc to WCD events */
+enum {
+	LPASS_CDC_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
+	LPASS_CDC_WCD_EVT_PA_OFF_PRE_SSR,
+	LPASS_CDC_WCD_EVT_SSR_DOWN,
+	LPASS_CDC_WCD_EVT_SSR_UP,
+	LPASS_CDC_WCD_EVT_PA_ON_POST_FSCLK,
+	LPASS_CDC_WCD_EVT_PA_ON_POST_FSCLK_ADIE_LB,
+};
+
+enum {
+	REG_NO_ACCESS,
+	RD_REG,
+	WR_REG,
+	RD_WR_REG
+};
+
+/* from WCD to lpass_cdc events */
+enum {
+	WCD_LPASS_CDC_EVT_RX_MUTE = 1, /* for RX mute/unmute */
+	WCD_LPASS_CDC_EVT_IMPED_TRUE,   /* for imped true */
+	WCD_LPASS_CDC_EVT_IMPED_FALSE,  /* for imped false */
+	WCD_LPASS_CDC_EVT_RX_COMPANDER_SOFT_RST,
+	WCD_LPASS_CDC_EVT_BCS_CLK_OFF,
+	WCD_LPASS_CDC_EVT_RX_PA_GAIN_UPDATE,
+	WCD_LPASS_CDC_EVT_HPHL_HD2_ENABLE, /* to enable hd2 config for hphl */
+	WCD_LPASS_CDC_EVT_HPHR_HD2_ENABLE, /* to enable hd2 config for hphr */
+};
+
+struct wcd_ctrl_platform_data {
+	void *handle;
+	int (*update_wcd_event)(void *handle, u16 event, u32 data);
+	int (*register_notifier)(void *handle,
+				 struct notifier_block *nblock,
+				 bool enable);
+};
+
+struct lpass_cdc_priv {
+	struct device *dev;
+	struct snd_soc_component *component;
+	struct regmap *regmap;
+	struct mutex io_lock;
+	struct mutex clk_lock;
+	struct mutex vote_lock;
+	bool va_without_decimation;
+	bool macros_supported[MAX_MACRO];
+	bool dev_up;
+	bool initial_boot;
+	struct macro_ops macro_params[MAX_MACRO];
+	struct snd_soc_dai_driver *lpass_cdc_dais;
+	u16 num_dais;
+	u16 num_macros_registered;
+	u16 num_macros;
+	u16 current_mclk_mux_macro[MAX_MACRO];
+	struct work_struct lpass_cdc_add_child_devices_work;
+	u32 version;
+	struct clk *lpass_core_hw_vote;
+	struct clk *lpass_audio_hw_vote;
+	int core_hw_vote_count;
+	int core_audio_vote_count;
+
+	/* Entry for version info */
+	struct snd_info_entry *entry;
+	struct snd_info_entry *version_entry;
+
+	int (*read_dev)(struct lpass_cdc_priv *priv,
+			u16 macro_id, u16 reg, u8 *val);
+	int (*write_dev)(struct lpass_cdc_priv *priv,
+			 u16 macro_id, u16 reg, u8 val);
+	struct platform_device *pdev_child_devices
+			[LPASS_CDC_CHILD_DEVICES_MAX];
+	u16 child_count;
+	struct wcd_ctrl_platform_data plat_data;
+	struct device *wcd_dev;
+	struct blocking_notifier_head notifier;
+	struct device *clk_dev;
+	rsc_clk_cb_t rsc_clk_cb;
+	s32 dmic_0_1_clk_cnt;
+	s32 dmic_2_3_clk_cnt;
+	s32 dmic_4_5_clk_cnt;
+	s32 dmic_6_7_clk_cnt;
+	u8 dmic_0_1_clk_div;
+	u8 dmic_2_3_clk_div;
+	u8 dmic_4_5_clk_div;
+	u8 dmic_6_7_clk_div;
+};
+
+struct regmap *lpass_cdc_regmap_init(struct device *dev,
+				  const struct regmap_config *config);
+int lpass_cdc_get_macro_id(bool va_no_dec_flag, u16 reg);
+
+extern const struct regmap_config lpass_cdc_regmap_config;
+extern u8 *lpass_cdc_reg_access[MAX_MACRO];
+extern u8 lpass_cdc_va_top_reg_access[LPASS_CDC_VA_MACRO_TOP_MAX];
+extern u8 lpass_cdc_va_reg_access_v2[LPASS_CDC_VA_MACRO_MAX];
+extern u8 lpass_cdc_va_reg_access_v3[LPASS_CDC_VA_MACRO_MAX];
+extern u8 lpass_cdc_tx_reg_access_v2[LPASS_CDC_TX_MACRO_MAX];
+extern const u16 macro_id_base_offset[MAX_MACRO];
+
+#endif

+ 768 - 0
asoc/codecs/lpass-cdc/lpass-cdc-clk-rsc.c

@@ -0,0 +1,768 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/of_platform.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include "lpass-cdc.h"
+#include "lpass-cdc-clk-rsc.h"
+
+#define DRV_NAME "lpass-cdc-clk-rsc"
+#define LPASS_CDC_CLK_NAME_LENGTH 30
+#define NPL_CLK_OFFSET (TX_NPL_CLK - TX_CORE_CLK)
+
+static char clk_src_name[MAX_CLK][LPASS_CDC_CLK_NAME_LENGTH] = {
+	"tx_core_clk",
+	"rx_core_clk",
+	"wsa_core_clk",
+	"va_core_clk",
+	"tx_npl_clk",
+	"rx_npl_clk",
+	"wsa_npl_clk",
+	"va_npl_clk",
+};
+
+struct lpass_cdc_clk_rsc {
+	struct device *dev;
+	struct mutex rsc_clk_lock;
+	struct mutex fs_gen_lock;
+	struct clk *clk[MAX_CLK];
+	int clk_cnt[MAX_CLK];
+	int reg_seq_en_cnt;
+	int va_tx_clk_cnt;
+	bool dev_up;
+	bool dev_up_gfmux;
+	u32 num_fs_reg;
+	u32 *fs_gen_seq;
+	int default_clk_id[MAX_CLK];
+	struct regmap *regmap;
+	char __iomem *rx_clk_muxsel;
+	char __iomem *wsa_clk_muxsel;
+	char __iomem *va_clk_muxsel;
+};
+
+static int lpass_cdc_clk_rsc_cb(struct device *dev, u16 event)
+{
+	struct lpass_cdc_clk_rsc *priv;
+
+	if (!dev) {
+		pr_err("%s: Invalid device pointer\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	priv = dev_get_drvdata(dev);
+	if (!priv) {
+		pr_err("%s: Invalid clk rsc priviate data\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&priv->rsc_clk_lock);
+	if (event == LPASS_CDC_MACRO_EVT_SSR_UP) {
+		priv->dev_up = true;
+	} else if (event == LPASS_CDC_MACRO_EVT_SSR_DOWN) {
+		priv->dev_up = false;
+		priv->dev_up_gfmux = false;
+	} else if (event == LPASS_CDC_MACRO_EVT_SSR_GFMUX_UP) {
+		priv->dev_up_gfmux = true;
+	}
+	mutex_unlock(&priv->rsc_clk_lock);
+
+	return 0;
+}
+
+static char __iomem *lpass_cdc_clk_rsc_get_clk_muxsel(struct lpass_cdc_clk_rsc *priv,
+						 int clk_id)
+{
+	switch (clk_id) {
+	case RX_CORE_CLK:
+		return priv->rx_clk_muxsel;
+	case WSA_CORE_CLK:
+		return priv->wsa_clk_muxsel;
+	case VA_CORE_CLK:
+		return priv->va_clk_muxsel;
+	case TX_CORE_CLK:
+	default:
+		dev_err_ratelimited(priv->dev, "%s: Invalid case\n", __func__);
+		break;
+	}
+
+	return NULL;
+}
+
+int lpass_cdc_rsc_clk_reset(struct device *dev, int clk_id)
+{
+	struct device *clk_dev = NULL;
+	struct lpass_cdc_clk_rsc *priv = NULL;
+	int count = 0;
+
+	if (!dev) {
+		pr_err("%s: dev is null %d\n", __func__);
+		return -EINVAL;
+	}
+
+	if (clk_id < 0 || clk_id >= MAX_CLK - NPL_CLK_OFFSET) {
+		pr_err("%s: Invalid clk_id: %d\n",
+			__func__, clk_id);
+		return -EINVAL;
+	}
+
+	clk_dev = lpass_cdc_get_rsc_clk_device_ptr(dev->parent);
+	if (!clk_dev) {
+		pr_err("%s: Invalid rsc clk device\n", __func__);
+		return -EINVAL;
+	}
+
+	priv = dev_get_drvdata(clk_dev);
+	if (!priv) {
+		pr_err("%s: Invalid rsc clk priviate data\n", __func__);
+		return -EINVAL;
+	}
+	mutex_lock(&priv->rsc_clk_lock);
+	while (__clk_is_enabled(priv->clk[clk_id])) {
+		clk_disable_unprepare(priv->clk[clk_id + NPL_CLK_OFFSET]);
+		clk_disable_unprepare(priv->clk[clk_id]);
+		count++;
+	}
+	dev_dbg(priv->dev,
+		"%s: clock reset after ssr, count %d\n", __func__, count);
+
+	trace_printk("%s: clock reset after ssr, count %d\n", __func__, count);
+	while (count--) {
+		clk_prepare_enable(priv->clk[clk_id]);
+		clk_prepare_enable(priv->clk[clk_id + NPL_CLK_OFFSET]);
+	}
+	mutex_unlock(&priv->rsc_clk_lock);
+	return 0;
+}
+EXPORT_SYMBOL(lpass_cdc_rsc_clk_reset);
+
+void lpass_cdc_clk_rsc_enable_all_clocks(struct device *dev, bool enable)
+{
+	struct device *clk_dev = NULL;
+	struct lpass_cdc_clk_rsc *priv = NULL;
+	int i = 0;
+
+	if (!dev) {
+		pr_err("%s: dev is null %d\n", __func__);
+		return;
+	}
+
+	clk_dev = lpass_cdc_get_rsc_clk_device_ptr(dev->parent);
+	if (!clk_dev) {
+		pr_err("%s: Invalid rsc clk device\n", __func__);
+		return;
+	}
+
+	priv = dev_get_drvdata(clk_dev);
+	if (!priv) {
+		pr_err("%s: Invalid rsc clk private data\n", __func__);
+		return;
+	}
+	mutex_lock(&priv->rsc_clk_lock);
+	for (i = 0; i < MAX_CLK - NPL_CLK_OFFSET; i++) {
+		if (enable) {
+			if (priv->clk[i])
+				clk_prepare_enable(priv->clk[i]);
+			if (priv->clk[i + NPL_CLK_OFFSET])
+				clk_prepare_enable(
+					priv->clk[i + NPL_CLK_OFFSET]);
+		} else {
+			if (priv->clk[i + NPL_CLK_OFFSET])
+				clk_disable_unprepare(
+					priv->clk[i + NPL_CLK_OFFSET]);
+			if (priv->clk[i])
+				clk_disable_unprepare(priv->clk[i]);
+		}
+	}
+	mutex_unlock(&priv->rsc_clk_lock);
+	return;
+}
+EXPORT_SYMBOL(lpass_cdc_clk_rsc_enable_all_clocks);
+
+static int lpass_cdc_clk_rsc_mux0_clk_request(struct lpass_cdc_clk_rsc *priv,
+					   int clk_id,
+					   bool enable)
+{
+	int ret = 0;
+
+	if (enable) {
+		/* Enable Requested Core clk */
+		if (priv->clk_cnt[clk_id] == 0) {
+			ret = clk_prepare_enable(priv->clk[clk_id]);
+			if (ret < 0) {
+				dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
+							__func__, clk_id);
+				goto done;
+			}
+			if (priv->clk[clk_id + NPL_CLK_OFFSET]) {
+				ret = clk_prepare_enable(
+					priv->clk[clk_id + NPL_CLK_OFFSET]);
+				if (ret < 0) {
+					dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
+						__func__,
+						clk_id + NPL_CLK_OFFSET);
+					goto err;
+				}
+			}
+		}
+		priv->clk_cnt[clk_id]++;
+	} else {
+		if (priv->clk_cnt[clk_id] <= 0) {
+			dev_err_ratelimited(priv->dev, "%s: clk_id: %d is already disabled\n",
+					__func__, clk_id);
+			priv->clk_cnt[clk_id] = 0;
+			goto done;
+		}
+		priv->clk_cnt[clk_id]--;
+		if (priv->clk_cnt[clk_id] == 0) {
+			if (priv->clk[clk_id + NPL_CLK_OFFSET])
+				clk_disable_unprepare(
+					priv->clk[clk_id + NPL_CLK_OFFSET]);
+			clk_disable_unprepare(priv->clk[clk_id]);
+		}
+	}
+	return ret;
+
+err:
+	clk_disable_unprepare(priv->clk[clk_id]);
+done:
+	return ret;
+}
+
+static int lpass_cdc_clk_rsc_mux1_clk_request(struct lpass_cdc_clk_rsc *priv,
+					   int clk_id,
+					   bool enable)
+{
+	char __iomem *clk_muxsel = NULL;
+	int ret = 0;
+	int default_clk_id = priv->default_clk_id[clk_id];
+	u32 muxsel = 0;
+
+	clk_muxsel = lpass_cdc_clk_rsc_get_clk_muxsel(priv, clk_id);
+	if (!clk_muxsel) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	if (enable) {
+		if (priv->clk_cnt[clk_id] == 0) {
+			if (clk_id != VA_CORE_CLK) {
+				ret = lpass_cdc_clk_rsc_mux0_clk_request(priv,
+								default_clk_id,
+								true);
+				if (ret < 0)
+					goto done;
+			}
+
+			ret = clk_prepare_enable(priv->clk[clk_id]);
+			if (ret < 0) {
+				dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
+					__func__, clk_id);
+				goto err_clk;
+			}
+			if (priv->clk[clk_id + NPL_CLK_OFFSET]) {
+				ret = clk_prepare_enable(
+					priv->clk[clk_id + NPL_CLK_OFFSET]);
+				if (ret < 0) {
+					dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
+						__func__,
+						clk_id + NPL_CLK_OFFSET);
+					goto err_npl_clk;
+				}
+			}
+
+			/*
+			 * Temp SW workaround to address a glitch issue of
+			 * VA GFMux instance responsible for switching from
+			 * TX MCLK to VA MCLK. This configuration would be taken
+			 * care in DSP itself
+			 */
+			if (clk_id != VA_CORE_CLK) {
+				if (priv->dev_up_gfmux) {
+					iowrite32(0x1, clk_muxsel);
+					muxsel = ioread32(clk_muxsel);
+					trace_printk("%s: muxsel value after enable: %d\n",
+							__func__, muxsel);
+				}
+				lpass_cdc_clk_rsc_mux0_clk_request(priv,
+							default_clk_id,
+							false);
+			}
+		}
+		priv->clk_cnt[clk_id]++;
+	} else {
+		if (priv->clk_cnt[clk_id] <= 0) {
+			dev_err_ratelimited(priv->dev, "%s: clk_id: %d is already disabled\n",
+				__func__, clk_id);
+			priv->clk_cnt[clk_id] = 0;
+			goto done;
+		}
+		priv->clk_cnt[clk_id]--;
+		if (priv->clk_cnt[clk_id] == 0) {
+			if (clk_id != VA_CORE_CLK) {
+				ret = lpass_cdc_clk_rsc_mux0_clk_request(priv,
+						default_clk_id, true);
+
+				if (!ret) {
+					/*
+					 * Temp SW workaround to address a glitch issue
+					 * of VA GFMux instance responsible for
+					 * switching from TX MCLK to VA MCLK.
+					 * This configuration would be taken
+					 * care in DSP itself.
+					 */
+					if (priv->dev_up_gfmux) {
+						iowrite32(0x0, clk_muxsel);
+						muxsel = ioread32(clk_muxsel);
+						trace_printk("%s: muxsel value after disable: %d\n",
+								__func__, muxsel);
+					}
+				}
+			}
+			if (priv->clk[clk_id + NPL_CLK_OFFSET])
+				clk_disable_unprepare(
+					priv->clk[clk_id + NPL_CLK_OFFSET]);
+			clk_disable_unprepare(priv->clk[clk_id]);
+
+			if (clk_id != VA_CORE_CLK) {
+				if (!ret)
+					lpass_cdc_clk_rsc_mux0_clk_request(priv,
+						default_clk_id, false);
+			}
+		}
+	}
+	return ret;
+
+err_npl_clk:
+	clk_disable_unprepare(priv->clk[clk_id]);
+
+err_clk:
+	if (clk_id != VA_CORE_CLK)
+		lpass_cdc_clk_rsc_mux0_clk_request(priv, default_clk_id, false);
+done:
+	return ret;
+}
+
+static int lpass_cdc_clk_rsc_check_and_update_va_clk(struct lpass_cdc_clk_rsc *priv,
+						  bool mux_switch,
+						  int clk_id,
+						  bool enable)
+{
+	int ret = 0;
+
+	if (enable) {
+		if (clk_id == VA_CORE_CLK && mux_switch) {
+			/*
+			 * Handle the following usecase scenarios during enable
+			 * 1. VA only, Active clk is VA_CORE_CLK
+			 * 2. record -> record + VA, Active clk is TX_CORE_CLK
+			 */
+			if (priv->clk_cnt[TX_CORE_CLK] == 0) {
+				ret = lpass_cdc_clk_rsc_mux1_clk_request(priv,
+							 VA_CORE_CLK, enable);
+				if (ret < 0)
+					goto err;
+			} else {
+				ret = lpass_cdc_clk_rsc_mux0_clk_request(priv,
+							TX_CORE_CLK, enable);
+				if (ret < 0)
+					goto err;
+				priv->va_tx_clk_cnt++;
+			}
+		} else if ((priv->clk_cnt[TX_CORE_CLK] > 0) &&
+			   (priv->clk_cnt[VA_CORE_CLK] > 0)) {
+			/*
+			 * Handle following concurrency scenario during enable
+			 * 1. VA-> Record+VA, Increment TX CLK and Disable VA
+			 * 2. VA-> Playback+VA, Increment TX CLK and Disable VA
+			 */
+			while (priv->clk_cnt[VA_CORE_CLK] > 0) {
+				ret = lpass_cdc_clk_rsc_mux0_clk_request(priv,
+							TX_CORE_CLK, true);
+				if (ret < 0)
+					goto err;
+
+				lpass_cdc_clk_rsc_mux1_clk_request(priv,
+							VA_CORE_CLK, false);
+				priv->va_tx_clk_cnt++;
+			}
+		}
+	} else {
+		if (clk_id == VA_CORE_CLK && mux_switch) {
+			/*
+			 * Handle the following usecase scenarios during disable
+			 * 1. VA only, disable VA_CORE_CLK
+			 * 2. Record + VA -> Record, decrement TX CLK count
+			 */
+			if (priv->clk_cnt[VA_CORE_CLK]) {
+				lpass_cdc_clk_rsc_mux1_clk_request(priv,
+							VA_CORE_CLK, enable);
+			} else if (priv->va_tx_clk_cnt) {
+				lpass_cdc_clk_rsc_mux0_clk_request(priv,
+							TX_CORE_CLK, enable);
+				priv->va_tx_clk_cnt--;
+			}
+		} else if (priv->va_tx_clk_cnt == priv->clk_cnt[TX_CORE_CLK]) {
+			/*
+			 * Handle the following usecase scenarios during disable
+			 * Record+VA-> VA: enable VA CLK, decrement TX CLK count
+			 */
+			while (priv->va_tx_clk_cnt) {
+				ret = lpass_cdc_clk_rsc_mux1_clk_request(priv,
+							VA_CORE_CLK, true);
+				if (ret < 0)
+					goto err;
+
+				lpass_cdc_clk_rsc_mux0_clk_request(priv,
+							TX_CORE_CLK, false);
+				priv->va_tx_clk_cnt--;
+			}
+		}
+	}
+
+err:
+	return ret;
+}
+
+/**
+ * lpass_cdc_clk_rsc_fs_gen_request - request to enable/disable fs generation
+ * sequence
+ *
+ * @dev: Macro device pointer
+ * @enable: enable or disable flag
+ */
+void lpass_cdc_clk_rsc_fs_gen_request(struct device *dev, bool enable)
+{
+	int i;
+	struct regmap *regmap;
+	struct device *clk_dev = NULL;
+	struct lpass_cdc_clk_rsc *priv = NULL;
+
+	if (!dev) {
+		pr_err("%s: dev is null %d\n", __func__);
+		return;
+	}
+	clk_dev = lpass_cdc_get_rsc_clk_device_ptr(dev->parent);
+	if (!clk_dev) {
+		pr_err("%s: Invalid rsc clk device\n", __func__);
+		return;
+	}
+	priv = dev_get_drvdata(clk_dev);
+	if (!priv) {
+		pr_err("%s: Invalid rsc clk priviate data\n", __func__);
+		return;
+	}
+	regmap = dev_get_regmap(priv->dev->parent, NULL);
+	if (!regmap) {
+		pr_err("%s: regmap is null\n", __func__);
+		return;
+	}
+	mutex_lock(&priv->fs_gen_lock);
+	if (enable) {
+		if (priv->reg_seq_en_cnt++ == 0) {
+			for (i = 0; i < (priv->num_fs_reg * 2); i += 2) {
+				dev_dbg(priv->dev, "%s: Register: %d, value: %d\n",
+					__func__, priv->fs_gen_seq[i],
+					priv->fs_gen_seq[i + 1]);
+				regmap_update_bits(regmap,
+						   priv->fs_gen_seq[i],
+						   priv->fs_gen_seq[i + 1],
+						   priv->fs_gen_seq[i + 1]);
+			}
+		}
+	} else {
+		if (priv->reg_seq_en_cnt <= 0) {
+			dev_err_ratelimited(priv->dev, "%s: req_seq_cnt: %d is already disabled\n",
+				__func__, priv->reg_seq_en_cnt);
+			priv->reg_seq_en_cnt = 0;
+			mutex_unlock(&priv->fs_gen_lock);
+			return;
+		}
+		if (--priv->reg_seq_en_cnt == 0) {
+			for (i = ((priv->num_fs_reg - 1) * 2); i >= 0; i -= 2) {
+				dev_dbg(priv->dev, "%s: Register: %d, value: %d\n",
+					__func__, priv->fs_gen_seq[i],
+					priv->fs_gen_seq[i + 1]);
+				regmap_update_bits(regmap, priv->fs_gen_seq[i],
+						priv->fs_gen_seq[i + 1], 0x0);
+			}
+		}
+	}
+	mutex_unlock(&priv->fs_gen_lock);
+}
+EXPORT_SYMBOL(lpass_cdc_clk_rsc_fs_gen_request);
+
+/**
+ * lpass_cdc_clk_rsc_request_clock - request for clock to
+ * enable/disable
+ *
+ * @dev: Macro device pointer.
+ * @default_clk_id: mux0 Core clock ID input.
+ * @clk_id_req: Core clock ID requested to enable/disable
+ * @enable: enable or disable clock flag
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int lpass_cdc_clk_rsc_request_clock(struct device *dev,
+				int default_clk_id,
+				int clk_id_req,
+				bool enable)
+{
+	int ret = 0;
+	struct device *clk_dev = NULL;
+	struct lpass_cdc_clk_rsc *priv = NULL;
+	bool mux_switch = false;
+
+	if (!dev) {
+		pr_err("%s: dev is null %d\n", __func__);
+		return -EINVAL;
+	}
+	if ((clk_id_req < 0 || clk_id_req >= MAX_CLK) &&
+		(default_clk_id < 0 || default_clk_id >= MAX_CLK)) {
+		pr_err("%s: Invalid clk_id_req: %d or default_clk_id: %d\n",
+				__func__, clk_id_req, default_clk_id);
+		return -EINVAL;
+	}
+	clk_dev = lpass_cdc_get_rsc_clk_device_ptr(dev->parent);
+	if (!clk_dev) {
+		pr_err("%s: Invalid rsc clk device\n", __func__);
+		return -EINVAL;
+	}
+	priv = dev_get_drvdata(clk_dev);
+	if (!priv) {
+		pr_err("%s: Invalid rsc clk priviate data\n", __func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&priv->rsc_clk_lock);
+	if (!priv->dev_up && enable) {
+		dev_err_ratelimited(priv->dev, "%s: SSR is in progress..\n",
+				__func__);
+		trace_printk("%s: SSR is in progress..\n", __func__);
+		ret = -EINVAL;
+		goto err;
+	}
+	priv->default_clk_id[clk_id_req] = default_clk_id;
+	if (default_clk_id != clk_id_req)
+		mux_switch = true;
+
+	if (mux_switch) {
+		if (clk_id_req != VA_CORE_CLK) {
+			ret = lpass_cdc_clk_rsc_mux1_clk_request(priv, clk_id_req,
+							enable);
+			if (ret < 0)
+				goto err;
+		}
+	} else {
+		ret = lpass_cdc_clk_rsc_mux0_clk_request(priv, clk_id_req, enable);
+		if (ret < 0)
+			goto err;
+	}
+
+	ret = lpass_cdc_clk_rsc_check_and_update_va_clk(priv, mux_switch,
+						 clk_id_req,
+						 enable);
+	if (ret < 0)
+		goto err;
+
+	dev_dbg(priv->dev, "%s: clk_cnt: %d for requested clk: %d, enable: %d\n",
+		__func__,  priv->clk_cnt[clk_id_req], clk_id_req,
+		enable);
+	trace_printk("%s: clk_cnt: %d for requested clk: %d, enable: %d\n",
+		__func__,  priv->clk_cnt[clk_id_req], clk_id_req,
+		enable);
+
+	mutex_unlock(&priv->rsc_clk_lock);
+
+	return 0;
+
+err:
+	mutex_unlock(&priv->rsc_clk_lock);
+	return ret;
+}
+EXPORT_SYMBOL(lpass_cdc_clk_rsc_request_clock);
+
+
+static int lpass_cdc_clk_rsc_probe(struct platform_device *pdev)
+{
+	int ret = 0, fs_gen_size, i, j;
+	const char **clk_name_array;
+	int clk_cnt;
+	struct clk *clk;
+	struct lpass_cdc_clk_rsc *priv = NULL;
+	u32 muxsel = 0;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct lpass_cdc_clk_rsc),
+			    GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	/* Get clk fs gen sequence from device tree */
+	if (!of_find_property(pdev->dev.of_node, "qcom,fs-gen-sequence",
+						  &fs_gen_size)) {
+		dev_err(&pdev->dev, "%s: unable to find qcom,fs-gen-sequence property\n",
+			__func__);
+		ret = -EINVAL;
+		goto err;
+	}
+	priv->num_fs_reg = fs_gen_size/(2 * sizeof(u32));
+	priv->fs_gen_seq = devm_kzalloc(&pdev->dev, fs_gen_size, GFP_KERNEL);
+	if (!priv->fs_gen_seq) {
+		ret = -ENOMEM;
+		goto err;
+	}
+	dev_dbg(&pdev->dev, "%s: num_fs_reg %d\n", __func__, priv->num_fs_reg);
+	/* Parse fs-gen-sequence */
+	ret = of_property_read_u32_array(pdev->dev.of_node,
+					 "qcom,fs-gen-sequence",
+					 priv->fs_gen_seq,
+					 priv->num_fs_reg * 2);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "%s: unable to parse fs-gen-sequence, ret = %d\n",
+			__func__, ret);
+		goto err;
+	}
+
+	/* Get clk details from device tree */
+	clk_cnt = of_property_count_strings(pdev->dev.of_node, "clock-names");
+	if (clk_cnt <= 0 || clk_cnt > MAX_CLK) {
+		dev_err(&pdev->dev, "%s: Invalid number of clocks %d",
+				__func__, clk_cnt);
+		ret = -EINVAL;
+		goto err;
+	}
+	clk_name_array = devm_kzalloc(&pdev->dev, clk_cnt * sizeof(char *),
+					  GFP_KERNEL);
+	if (!clk_name_array) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ret = of_property_read_string_array(pdev->dev.of_node, "clock-names",
+					clk_name_array, clk_cnt);
+
+	for (i = 0; i < MAX_CLK; i++) {
+		priv->clk[i] = NULL;
+		for (j = 0; j < clk_cnt; j++) {
+			if (!strcmp(clk_src_name[i], clk_name_array[j])) {
+				clk = devm_clk_get(&pdev->dev, clk_src_name[i]);
+				if (IS_ERR(clk)) {
+					ret = PTR_ERR(clk);
+					dev_err(&pdev->dev, "%s: clk get failed for %s with ret %d\n",
+						__func__, clk_src_name[i], ret);
+					goto err;
+				}
+				priv->clk[i] = clk;
+				dev_dbg(&pdev->dev, "%s: clk get success for clk name %s\n",
+						__func__, clk_src_name[i]);
+			}
+		}
+	}
+	ret = of_property_read_u32(pdev->dev.of_node,
+				 "qcom,rx_mclk_mode_muxsel", &muxsel);
+	if (ret) {
+		dev_dbg(&pdev->dev, "%s: could not find qcom,rx_mclk_mode_muxsel entry in dt\n",
+			__func__);
+	} else {
+		priv->rx_clk_muxsel = devm_ioremap(&pdev->dev, muxsel, 0x4);
+		if (!priv->rx_clk_muxsel) {
+			dev_err(&pdev->dev, "%s: ioremap failed for rx muxsel\n",
+				__func__);
+			return -ENOMEM;
+		}
+	}
+	ret = of_property_read_u32(pdev->dev.of_node,
+				"qcom,wsa_mclk_mode_muxsel", &muxsel);
+	if (ret) {
+		dev_dbg(&pdev->dev, "%s: could not find qcom,wsa_mclk_mode_muxsel entry in dt\n",
+			__func__);
+	} else {
+		priv->wsa_clk_muxsel = devm_ioremap(&pdev->dev, muxsel, 0x4);
+		if (!priv->wsa_clk_muxsel) {
+			dev_err(&pdev->dev, "%s: ioremap failed for wsa muxsel\n",
+				__func__);
+			return -ENOMEM;
+		}
+	}
+	ret = of_property_read_u32(pdev->dev.of_node,
+				 "qcom,va_mclk_mode_muxsel", &muxsel);
+	if (ret) {
+		dev_dbg(&pdev->dev, "%s: could not find qcom,va_mclk_mode_muxsel entry in dt\n",
+			__func__);
+	} else {
+		priv->va_clk_muxsel = devm_ioremap(&pdev->dev, muxsel, 0x4);
+		if (!priv->va_clk_muxsel) {
+			dev_err(&pdev->dev, "%s: ioremap failed for va muxsel\n",
+				__func__);
+			return -ENOMEM;
+		}
+	}
+
+	ret = lpass_cdc_register_res_clk(&pdev->dev, lpass_cdc_clk_rsc_cb);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "%s: Failed to register cb %d",
+				__func__, ret);
+		goto err;
+	}
+	priv->dev = &pdev->dev;
+	priv->dev_up = true;
+	priv->dev_up_gfmux = true;
+	mutex_init(&priv->rsc_clk_lock);
+	mutex_init(&priv->fs_gen_lock);
+	dev_set_drvdata(&pdev->dev, priv);
+
+err:
+	return ret;
+}
+
+static int lpass_cdc_clk_rsc_remove(struct platform_device *pdev)
+{
+	struct lpass_cdc_clk_rsc *priv = dev_get_drvdata(&pdev->dev);
+
+	lpass_cdc_unregister_res_clk(&pdev->dev);
+	of_platform_depopulate(&pdev->dev);
+	if (!priv)
+		return -EINVAL;
+	mutex_destroy(&priv->rsc_clk_lock);
+	mutex_destroy(&priv->fs_gen_lock);
+
+	return 0;
+}
+
+static const struct of_device_id lpass_cdc_clk_rsc_dt_match[] = {
+	{.compatible = "qcom,lpass-cdc-clk-rsc-mngr"},
+	{}
+};
+MODULE_DEVICE_TABLE(of, lpass_cdc_clk_rsc_dt_match);
+
+static struct platform_driver lpass_cdc_clk_rsc_mgr = {
+	.driver = {
+		.name = "lpass-cdc-clk-rsc-mngr",
+		.owner = THIS_MODULE,
+		.of_match_table = lpass_cdc_clk_rsc_dt_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = lpass_cdc_clk_rsc_probe,
+	.remove = lpass_cdc_clk_rsc_remove,
+};
+
+int lpass_cdc_clk_rsc_mgr_init(void)
+{
+	return platform_driver_register(&lpass_cdc_clk_rsc_mgr);
+}
+
+void lpass_cdc_clk_rsc_mgr_exit(void)
+{
+	platform_driver_unregister(&lpass_cdc_clk_rsc_mgr);
+}
+MODULE_DESCRIPTION("LPASS codec clock resource manager driver");
+MODULE_LICENSE("GPL v2");

+ 52 - 0
asoc/codecs/lpass-cdc/lpass-cdc-clk-rsc.h

@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef LPASS_CDC_CLK_RSC_H
+#define LPASS_CDC_CLK_RSC_H
+
+#include <linux/regmap.h>
+#include <dt-bindings/sound/qcom,lpass-cdc-clk-rsc.h>
+
+#if IS_ENABLED(CONFIG_SND_SOC_LPASS_CDC)
+int lpass_cdc_clk_rsc_mgr_init(void);
+void lpass_cdc_clk_rsc_mgr_exit(void);
+void lpass_cdc_clk_rsc_fs_gen_request(struct device *dev,
+						bool enable);
+int lpass_cdc_clk_rsc_request_clock(struct device *dev,
+				int default_clk_id,
+				int clk_id_req,
+				bool enable);
+int lpass_cdc_rsc_clk_reset(struct device *dev, int clk_id);
+void lpass_cdc_clk_rsc_enable_all_clocks(struct device *dev, bool enable);
+#else
+static inline void lpass_cdc_clk_rsc_fs_gen_request(struct device *dev,
+						bool enable)
+{
+}
+static inline int lpass_cdc_clk_rsc_mgr_init(void)
+{
+	return 0;
+}
+static inline void lpass_cdc_clk_rsc_mgr_exit(void)
+{
+}
+static inline int lpass_cdc_clk_rsc_request_clock(struct device *dev,
+				int default_clk_id,
+				int clk_id_req,
+				bool enable)
+{
+	return 0;
+}
+static inline int lpass_cdc_rsc_clk_reset(struct device *dev, int clk_id)
+{
+	return 0;
+}
+static inline void lpass_cdc_clk_rsc_enable_all_clocks(struct device *dev,
+						    bool enable)
+{
+	return;
+}
+#endif /* CONFIG_SND_SOC_LPASS_CDC */
+#endif /* LPASS_CDC_CLK_RSC_H */

+ 844 - 0
asoc/codecs/lpass-cdc/lpass-cdc-registers.h

@@ -0,0 +1,844 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _LPASS_CDC_REGISTERS_H
+#define _LPASS_CDC_REGISTERS_H
+
+#define TX_START_OFFSET 0x0000
+
+#define LPASS_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL (TX_START_OFFSET + 0x0000)
+#define LPASS_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL (TX_START_OFFSET + 0x0004)
+#define LPASS_CDC_TX_CLK_RST_CTRL_SWR_CONTROL	(TX_START_OFFSET + 0x0008)
+#define LPASS_CDC_TX_TOP_CSR_TOP_CFG0		(TX_START_OFFSET + 0x0080)
+#define LPASS_CDC_TX_TOP_CSR_ANC_CFG		(TX_START_OFFSET + 0x0084)
+#define LPASS_CDC_TX_TOP_CSR_SWR_CTRL		(TX_START_OFFSET + 0x0088)
+#define LPASS_CDC_TX_TOP_CSR_FREQ_MCLK		(TX_START_OFFSET + 0x0090)
+#define LPASS_CDC_TX_TOP_CSR_DEBUG_BUS		(TX_START_OFFSET + 0x0094)
+#define LPASS_CDC_TX_TOP_CSR_DEBUG_EN		(TX_START_OFFSET + 0x0098)
+#define LPASS_CDC_TX_TOP_CSR_TX_I2S_CTL	(TX_START_OFFSET + 0x00A4)
+#define LPASS_CDC_TX_TOP_CSR_I2S_CLK		(TX_START_OFFSET + 0x00A8)
+#define LPASS_CDC_TX_TOP_CSR_I2S_RESET		(TX_START_OFFSET + 0x00AC)
+#define LPASS_CDC_TX_TOP_CSR_SWR_DMIC0_CTL	(TX_START_OFFSET + 0x00C0)
+#define LPASS_CDC_TX_TOP_CSR_SWR_DMIC1_CTL	(TX_START_OFFSET + 0x00C4)
+#define LPASS_CDC_TX_TOP_CSR_SWR_DMIC2_CTL	(TX_START_OFFSET + 0x00C8)
+#define LPASS_CDC_TX_TOP_CSR_SWR_DMIC3_CTL	(TX_START_OFFSET + 0x00CC)
+#define LPASS_CDC_TX_TOP_CSR_SWR_AMIC0_CTL	(TX_START_OFFSET + 0x00D0)
+#define LPASS_CDC_TX_TOP_CSR_SWR_AMIC1_CTL	(TX_START_OFFSET + 0x00D4)
+#define LPASS_CDC_TX_TOP_CSR_SWR_MIC2_CTL	(TX_START_OFFSET + 0x00C0)
+#define LPASS_CDC_TX_TOP_CSR_SWR_MIC3_CTL	(TX_START_OFFSET + 0x00C4)
+#define LPASS_CDC_TX_TOP_CSR_SWR_MIC4_CTL	(TX_START_OFFSET + 0x00C8)
+#define LPASS_CDC_TX_TOP_CSR_SWR_MIC5_CTL	(TX_START_OFFSET + 0x00CC)
+#define LPASS_CDC_TX_TOP_CSR_SWR_MIC0_CTL	(TX_START_OFFSET + 0x00D0)
+#define LPASS_CDC_TX_TOP_CSR_SWR_MIC1_CTL	(TX_START_OFFSET + 0x00D4)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG0	(TX_START_OFFSET + 0x0100)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG1	(TX_START_OFFSET + 0x0104)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG0	(TX_START_OFFSET + 0x0108)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG1	(TX_START_OFFSET + 0x010C)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG0	(TX_START_OFFSET + 0x0110)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG1	(TX_START_OFFSET + 0x0114)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG0	(TX_START_OFFSET + 0x0118)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG1	(TX_START_OFFSET + 0x011C)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX4_CFG0	(TX_START_OFFSET + 0x0120)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX4_CFG1	(TX_START_OFFSET + 0x0124)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX5_CFG0	(TX_START_OFFSET + 0x0128)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX5_CFG1	(TX_START_OFFSET + 0x012C)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX6_CFG0	(TX_START_OFFSET + 0x0130)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX6_CFG1	(TX_START_OFFSET + 0x0134)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX7_CFG0	(TX_START_OFFSET + 0x0138)
+#define LPASS_CDC_TX_INP_MUX_ADC_MUX7_CFG1	(TX_START_OFFSET + 0x013C)
+#define LPASS_CDC_TX_ANC0_CLK_RESET_CTL	(TX_START_OFFSET + 0x0200)
+#define LPASS_CDC_TX_ANC0_MODE_1_CTL		(TX_START_OFFSET + 0x0204)
+#define LPASS_CDC_TX_ANC0_MODE_2_CTL		(TX_START_OFFSET + 0x0208)
+#define LPASS_CDC_TX_ANC0_FF_SHIFT		(TX_START_OFFSET + 0x020C)
+#define LPASS_CDC_TX_ANC0_FB_SHIFT		(TX_START_OFFSET + 0x0210)
+#define LPASS_CDC_TX_ANC0_LPF_FF_A_CTL	(TX_START_OFFSET + 0x0214)
+#define LPASS_CDC_TX_ANC0_LPF_FF_B_CTL	(TX_START_OFFSET + 0x0218)
+#define LPASS_CDC_TX_ANC0_LPF_FB_CTL	(TX_START_OFFSET + 0x021C)
+#define LPASS_CDC_TX_ANC0_SMLPF_CTL	(TX_START_OFFSET + 0x0220)
+#define LPASS_CDC_TX_ANC0_DCFLT_SHIFT_CTL	(TX_START_OFFSET + 0x0224)
+#define LPASS_CDC_TX_ANC0_IIR_ADAPT_CTL	(TX_START_OFFSET + 0x0228)
+#define LPASS_CDC_TX_ANC0_IIR_COEFF_1_CTL	(TX_START_OFFSET + 0x022C)
+#define LPASS_CDC_TX_ANC0_IIR_COEFF_2_CTL	(TX_START_OFFSET + 0x0230)
+#define LPASS_CDC_TX_ANC0_FF_A_GAIN_CTL	(TX_START_OFFSET + 0x0234)
+#define LPASS_CDC_TX_ANC0_FF_B_GAIN_CTL	(TX_START_OFFSET + 0x0238)
+#define LPASS_CDC_TX_ANC0_FB_GAIN_CTL	(TX_START_OFFSET + 0x023C)
+#define LPASS_CDC_TX0_TX_PATH_CTL	(TX_START_OFFSET + 0x0400)
+#define LPASS_CDC_TX0_TX_PATH_CFG0	(TX_START_OFFSET + 0x0404)
+#define LPASS_CDC_TX0_TX_PATH_CFG1	(TX_START_OFFSET + 0x0408)
+#define LPASS_CDC_TX0_TX_VOL_CTL	(TX_START_OFFSET + 0x040C)
+#define LPASS_CDC_TX0_TX_PATH_SEC0	(TX_START_OFFSET + 0x0410)
+#define LPASS_CDC_TX0_TX_PATH_SEC1	(TX_START_OFFSET + 0x0414)
+#define LPASS_CDC_TX0_TX_PATH_SEC2	(TX_START_OFFSET + 0x0418)
+#define LPASS_CDC_TX0_TX_PATH_SEC3	(TX_START_OFFSET + 0x041C)
+#define LPASS_CDC_TX0_TX_PATH_SEC4	(TX_START_OFFSET + 0x0420)
+#define LPASS_CDC_TX0_TX_PATH_SEC5	(TX_START_OFFSET + 0x0424)
+#define LPASS_CDC_TX0_TX_PATH_SEC6	(TX_START_OFFSET + 0x0428)
+#define LPASS_CDC_TX0_TX_PATH_SEC7	(TX_START_OFFSET + 0x042C)
+#define LPASS_CDC_TX1_TX_PATH_CTL	(TX_START_OFFSET + 0x0480)
+#define LPASS_CDC_TX1_TX_PATH_CFG0	(TX_START_OFFSET + 0x0484)
+#define LPASS_CDC_TX1_TX_PATH_CFG1	(TX_START_OFFSET + 0x0488)
+#define LPASS_CDC_TX1_TX_VOL_CTL	(TX_START_OFFSET + 0x048C)
+#define LPASS_CDC_TX1_TX_PATH_SEC0	(TX_START_OFFSET + 0x0490)
+#define LPASS_CDC_TX1_TX_PATH_SEC1	(TX_START_OFFSET + 0x0494)
+#define LPASS_CDC_TX1_TX_PATH_SEC2	(TX_START_OFFSET + 0x0498)
+#define LPASS_CDC_TX1_TX_PATH_SEC3	(TX_START_OFFSET + 0x049C)
+#define LPASS_CDC_TX1_TX_PATH_SEC4	(TX_START_OFFSET + 0x04A0)
+#define LPASS_CDC_TX1_TX_PATH_SEC5	(TX_START_OFFSET + 0x04A4)
+#define LPASS_CDC_TX1_TX_PATH_SEC6	(TX_START_OFFSET + 0x04A8)
+#define LPASS_CDC_TX2_TX_PATH_CTL	(TX_START_OFFSET + 0x0500)
+#define LPASS_CDC_TX2_TX_PATH_CFG0	(TX_START_OFFSET + 0x0504)
+#define LPASS_CDC_TX2_TX_PATH_CFG1	(TX_START_OFFSET + 0x0508)
+#define LPASS_CDC_TX2_TX_VOL_CTL	(TX_START_OFFSET + 0x050C)
+#define LPASS_CDC_TX2_TX_PATH_SEC0	(TX_START_OFFSET + 0x0510)
+#define LPASS_CDC_TX2_TX_PATH_SEC1	(TX_START_OFFSET + 0x0514)
+#define LPASS_CDC_TX2_TX_PATH_SEC2	(TX_START_OFFSET + 0x0518)
+#define LPASS_CDC_TX2_TX_PATH_SEC3	(TX_START_OFFSET + 0x051C)
+#define LPASS_CDC_TX2_TX_PATH_SEC4	(TX_START_OFFSET + 0x0520)
+#define LPASS_CDC_TX2_TX_PATH_SEC5	(TX_START_OFFSET + 0x0524)
+#define LPASS_CDC_TX2_TX_PATH_SEC6	(TX_START_OFFSET + 0x0528)
+#define LPASS_CDC_TX3_TX_PATH_CTL	(TX_START_OFFSET + 0x0580)
+#define LPASS_CDC_TX3_TX_PATH_CFG0	(TX_START_OFFSET + 0x0584)
+#define LPASS_CDC_TX3_TX_PATH_CFG1	(TX_START_OFFSET + 0x0588)
+#define LPASS_CDC_TX3_TX_VOL_CTL	(TX_START_OFFSET + 0x058C)
+#define LPASS_CDC_TX3_TX_PATH_SEC0	(TX_START_OFFSET + 0x0590)
+#define LPASS_CDC_TX3_TX_PATH_SEC1	(TX_START_OFFSET + 0x0594)
+#define LPASS_CDC_TX3_TX_PATH_SEC2	(TX_START_OFFSET + 0x0598)
+#define LPASS_CDC_TX3_TX_PATH_SEC3	(TX_START_OFFSET + 0x059C)
+#define LPASS_CDC_TX3_TX_PATH_SEC4	(TX_START_OFFSET + 0x05A0)
+#define LPASS_CDC_TX3_TX_PATH_SEC5	(TX_START_OFFSET + 0x05A4)
+#define LPASS_CDC_TX3_TX_PATH_SEC6	(TX_START_OFFSET + 0x05A8)
+#define LPASS_CDC_TX4_TX_PATH_CTL	(TX_START_OFFSET + 0x0600)
+#define LPASS_CDC_TX4_TX_PATH_CFG0	(TX_START_OFFSET + 0x0604)
+#define LPASS_CDC_TX4_TX_PATH_CFG1	(TX_START_OFFSET + 0x0608)
+#define LPASS_CDC_TX4_TX_VOL_CTL	(TX_START_OFFSET + 0x060C)
+#define LPASS_CDC_TX4_TX_PATH_SEC0	(TX_START_OFFSET + 0x0610)
+#define LPASS_CDC_TX4_TX_PATH_SEC1	(TX_START_OFFSET + 0x0614)
+#define LPASS_CDC_TX4_TX_PATH_SEC2	(TX_START_OFFSET + 0x0618)
+#define LPASS_CDC_TX4_TX_PATH_SEC3	(TX_START_OFFSET + 0x061C)
+#define LPASS_CDC_TX4_TX_PATH_SEC4	(TX_START_OFFSET + 0x0620)
+#define LPASS_CDC_TX4_TX_PATH_SEC5	(TX_START_OFFSET + 0x0624)
+#define LPASS_CDC_TX4_TX_PATH_SEC6	(TX_START_OFFSET + 0x0628)
+#define LPASS_CDC_TX5_TX_PATH_CTL	(TX_START_OFFSET + 0x0680)
+#define LPASS_CDC_TX5_TX_PATH_CFG0	(TX_START_OFFSET + 0x0684)
+#define LPASS_CDC_TX5_TX_PATH_CFG1	(TX_START_OFFSET + 0x0688)
+#define LPASS_CDC_TX5_TX_VOL_CTL	(TX_START_OFFSET + 0x068C)
+#define LPASS_CDC_TX5_TX_PATH_SEC0	(TX_START_OFFSET + 0x0690)
+#define LPASS_CDC_TX5_TX_PATH_SEC1	(TX_START_OFFSET + 0x0694)
+#define LPASS_CDC_TX5_TX_PATH_SEC2	(TX_START_OFFSET + 0x0698)
+#define LPASS_CDC_TX5_TX_PATH_SEC3	(TX_START_OFFSET + 0x069C)
+#define LPASS_CDC_TX5_TX_PATH_SEC4	(TX_START_OFFSET + 0x06A0)
+#define LPASS_CDC_TX5_TX_PATH_SEC5	(TX_START_OFFSET + 0x06A4)
+#define LPASS_CDC_TX5_TX_PATH_SEC6	(TX_START_OFFSET + 0x06A8)
+#define LPASS_CDC_TX6_TX_PATH_CTL	(TX_START_OFFSET + 0x0700)
+#define LPASS_CDC_TX6_TX_PATH_CFG0	(TX_START_OFFSET + 0x0704)
+#define LPASS_CDC_TX6_TX_PATH_CFG1	(TX_START_OFFSET + 0x0708)
+#define LPASS_CDC_TX6_TX_VOL_CTL	(TX_START_OFFSET + 0x070C)
+#define LPASS_CDC_TX6_TX_PATH_SEC0	(TX_START_OFFSET + 0x0710)
+#define LPASS_CDC_TX6_TX_PATH_SEC1	(TX_START_OFFSET + 0x0714)
+#define LPASS_CDC_TX6_TX_PATH_SEC2	(TX_START_OFFSET + 0x0718)
+#define LPASS_CDC_TX6_TX_PATH_SEC3	(TX_START_OFFSET + 0x071C)
+#define LPASS_CDC_TX6_TX_PATH_SEC4	(TX_START_OFFSET + 0x0720)
+#define LPASS_CDC_TX6_TX_PATH_SEC5	(TX_START_OFFSET + 0x0724)
+#define LPASS_CDC_TX6_TX_PATH_SEC6	(TX_START_OFFSET + 0x0728)
+#define LPASS_CDC_TX7_TX_PATH_CTL	(TX_START_OFFSET + 0x0780)
+#define LPASS_CDC_TX7_TX_PATH_CFG0	(TX_START_OFFSET + 0x0784)
+#define LPASS_CDC_TX7_TX_PATH_CFG1	(TX_START_OFFSET + 0x0788)
+#define LPASS_CDC_TX7_TX_VOL_CTL	(TX_START_OFFSET + 0x078C)
+#define LPASS_CDC_TX7_TX_PATH_SEC0	(TX_START_OFFSET + 0x0790)
+#define LPASS_CDC_TX7_TX_PATH_SEC1	(TX_START_OFFSET + 0x0794)
+#define LPASS_CDC_TX7_TX_PATH_SEC2	(TX_START_OFFSET + 0x0798)
+#define LPASS_CDC_TX7_TX_PATH_SEC3	(TX_START_OFFSET + 0x079C)
+#define LPASS_CDC_TX7_TX_PATH_SEC4	(TX_START_OFFSET + 0x07A0)
+#define LPASS_CDC_TX7_TX_PATH_SEC5	(TX_START_OFFSET + 0x07A4)
+#define LPASS_CDC_TX7_TX_PATH_SEC6	(TX_START_OFFSET + 0x07A8)
+#define TX_MAX_OFFSET			(TX_START_OFFSET + 0x07A8)
+
+#define LPASS_CDC_TX_MACRO_MAX 0x1EB /* 7A8/4 = 1EA + 1 */
+
+#define RX_START_OFFSET				0x1000
+#define LPASS_CDC_RX_TOP_TOP_CFG0		(RX_START_OFFSET + 0x0000)
+#define LPASS_CDC_RX_TOP_SWR_CTRL		(RX_START_OFFSET + 0x0008)
+#define LPASS_CDC_RX_TOP_DEBUG			(RX_START_OFFSET + 0x000C)
+#define LPASS_CDC_RX_TOP_DEBUG_BUS		(RX_START_OFFSET + 0x0010)
+#define LPASS_CDC_RX_TOP_DEBUG_EN0		(RX_START_OFFSET + 0x0014)
+#define LPASS_CDC_RX_TOP_DEBUG_EN1		(RX_START_OFFSET + 0x0018)
+#define LPASS_CDC_RX_TOP_DEBUG_EN2		(RX_START_OFFSET + 0x001C)
+#define LPASS_CDC_RX_TOP_HPHL_COMP_WR_LSB	(RX_START_OFFSET + 0x0020)
+#define LPASS_CDC_RX_TOP_HPHL_COMP_WR_MSB	(RX_START_OFFSET + 0x0024)
+#define LPASS_CDC_RX_TOP_HPHL_COMP_LUT		(RX_START_OFFSET + 0x0028)
+#define LPASS_CDC_RX_TOP_HPHL_COMP_RD_LSB	(RX_START_OFFSET + 0x002C)
+#define LPASS_CDC_RX_TOP_HPHL_COMP_RD_MSB	(RX_START_OFFSET + 0x0030)
+#define LPASS_CDC_RX_TOP_HPHR_COMP_WR_LSB	(RX_START_OFFSET + 0x0034)
+#define LPASS_CDC_RX_TOP_HPHR_COMP_WR_MSB	(RX_START_OFFSET + 0x0038)
+#define LPASS_CDC_RX_TOP_HPHR_COMP_LUT		(RX_START_OFFSET + 0x003C)
+#define LPASS_CDC_RX_TOP_HPHR_COMP_RD_LSB	(RX_START_OFFSET + 0x0040)
+#define LPASS_CDC_RX_TOP_HPHR_COMP_RD_MSB	(RX_START_OFFSET + 0x0044)
+#define LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG0	(RX_START_OFFSET + 0x0070)
+#define LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG1	(RX_START_OFFSET + 0x0074)
+#define LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG2	(RX_START_OFFSET + 0x0078)
+#define LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG3	(RX_START_OFFSET + 0x007C)
+#define LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG0	(RX_START_OFFSET + 0x0080)
+#define LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG1	(RX_START_OFFSET + 0x0084)
+#define LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG2	(RX_START_OFFSET + 0x0088)
+#define LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG3	(RX_START_OFFSET + 0x008C)
+#define LPASS_CDC_RX_TOP_RX_I2S_CTL		(RX_START_OFFSET + 0x0090)
+#define LPASS_CDC_RX_TOP_TX_I2S2_CTL		(RX_START_OFFSET + 0x0094)
+#define LPASS_CDC_RX_TOP_I2S_CLK		(RX_START_OFFSET + 0x0098)
+#define LPASS_CDC_RX_TOP_I2S_RESET		(RX_START_OFFSET + 0x009C)
+#define LPASS_CDC_RX_TOP_I2S_MUX		(RX_START_OFFSET + 0x00A0)
+#define LPASS_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL	(RX_START_OFFSET + 0x0100)
+#define LPASS_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL \
+						(RX_START_OFFSET + 0x0104)
+#define LPASS_CDC_RX_CLK_RST_CTRL_SWR_CONTROL	(RX_START_OFFSET + 0x0108)
+#define LPASS_CDC_RX_CLK_RST_CTRL_DSD_CONTROL	(RX_START_OFFSET + 0x010C)
+#define LPASS_CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL \
+						(RX_START_OFFSET + 0x0110)
+#define LPASS_CDC_RX_SOFTCLIP_CRC		(RX_START_OFFSET + 0x0140)
+#define LPASS_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL	(RX_START_OFFSET + 0x0144)
+#define LPASS_CDC_RX_INP_MUX_RX_INT0_CFG0	(RX_START_OFFSET + 0x0180)
+#define LPASS_CDC_RX_INP_MUX_RX_INT0_CFG1	(RX_START_OFFSET + 0x0184)
+#define LPASS_CDC_RX_INP_MUX_RX_INT1_CFG0	(RX_START_OFFSET + 0x0188)
+#define LPASS_CDC_RX_INP_MUX_RX_INT1_CFG1	(RX_START_OFFSET + 0x018C)
+#define LPASS_CDC_RX_INP_MUX_RX_INT2_CFG0	(RX_START_OFFSET + 0x0190)
+#define LPASS_CDC_RX_INP_MUX_RX_INT2_CFG1	(RX_START_OFFSET + 0x0194)
+#define LPASS_CDC_RX_INP_MUX_RX_MIX_CFG4	(RX_START_OFFSET + 0x0198)
+#define LPASS_CDC_RX_INP_MUX_RX_MIX_CFG5	(RX_START_OFFSET + 0x019C)
+#define LPASS_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0	(RX_START_OFFSET + 0x01A0)
+#define LPASS_CDC_RX_CLSH_CRC			(RX_START_OFFSET + 0x0200)
+#define LPASS_CDC_RX_CLSH_DLY_CTRL		(RX_START_OFFSET + 0x0204)
+#define LPASS_CDC_RX_CLSH_DECAY_CTRL		(RX_START_OFFSET + 0x0208)
+#define LPASS_CDC_RX_CLSH_HPH_V_PA		(RX_START_OFFSET + 0x020C)
+#define LPASS_CDC_RX_CLSH_EAR_V_PA		(RX_START_OFFSET + 0x0210)
+#define LPASS_CDC_RX_CLSH_HPH_V_HD		(RX_START_OFFSET + 0x0214)
+#define LPASS_CDC_RX_CLSH_EAR_V_HD		(RX_START_OFFSET + 0x0218)
+#define LPASS_CDC_RX_CLSH_K1_MSB		(RX_START_OFFSET + 0x021C)
+#define LPASS_CDC_RX_CLSH_K1_LSB		(RX_START_OFFSET + 0x0220)
+#define LPASS_CDC_RX_CLSH_K2_MSB		(RX_START_OFFSET + 0x0224)
+#define LPASS_CDC_RX_CLSH_K2_LSB		(RX_START_OFFSET + 0x0228)
+#define LPASS_CDC_RX_CLSH_IDLE_CTRL		(RX_START_OFFSET + 0x022C)
+#define LPASS_CDC_RX_CLSH_IDLE_HPH		(RX_START_OFFSET + 0x0230)
+#define LPASS_CDC_RX_CLSH_IDLE_EAR		(RX_START_OFFSET + 0x0234)
+#define LPASS_CDC_RX_CLSH_TEST0		(RX_START_OFFSET + 0x0238)
+#define LPASS_CDC_RX_CLSH_TEST1		(RX_START_OFFSET + 0x023C)
+#define LPASS_CDC_RX_CLSH_OVR_VREF		(RX_START_OFFSET + 0x0240)
+#define LPASS_CDC_RX_CLSH_CLSG_CTL		(RX_START_OFFSET + 0x0244)
+#define LPASS_CDC_RX_CLSH_CLSG_CFG1		(RX_START_OFFSET + 0x0248)
+#define LPASS_CDC_RX_CLSH_CLSG_CFG2		(RX_START_OFFSET + 0x024C)
+#define LPASS_CDC_RX_BCL_VBAT_PATH_CTL		(RX_START_OFFSET + 0x0280)
+#define LPASS_CDC_RX_BCL_VBAT_CFG		(RX_START_OFFSET + 0x0284)
+#define LPASS_CDC_RX_BCL_VBAT_ADC_CAL1		(RX_START_OFFSET + 0x0288)
+#define LPASS_CDC_RX_BCL_VBAT_ADC_CAL2		(RX_START_OFFSET + 0x028C)
+#define LPASS_CDC_RX_BCL_VBAT_ADC_CAL3		(RX_START_OFFSET + 0x0290)
+#define LPASS_CDC_RX_BCL_VBAT_PK_EST1		(RX_START_OFFSET + 0x0294)
+#define LPASS_CDC_RX_BCL_VBAT_PK_EST2		(RX_START_OFFSET + 0x0298)
+#define LPASS_CDC_RX_BCL_VBAT_PK_EST3		(RX_START_OFFSET + 0x029C)
+#define LPASS_CDC_RX_BCL_VBAT_RF_PROC1		(RX_START_OFFSET + 0x02A0)
+#define LPASS_CDC_RX_BCL_VBAT_RF_PROC2		(RX_START_OFFSET + 0x02A4)
+#define LPASS_CDC_RX_BCL_VBAT_TAC1		(RX_START_OFFSET + 0x02A8)
+#define LPASS_CDC_RX_BCL_VBAT_TAC2		(RX_START_OFFSET + 0x02AC)
+#define LPASS_CDC_RX_BCL_VBAT_TAC3		(RX_START_OFFSET + 0x02B0)
+#define LPASS_CDC_RX_BCL_VBAT_TAC4		(RX_START_OFFSET + 0x02B4)
+#define LPASS_CDC_RX_BCL_VBAT_GAIN_UPD1	(RX_START_OFFSET + 0x02B8)
+#define LPASS_CDC_RX_BCL_VBAT_GAIN_UPD2	(RX_START_OFFSET + 0x02BC)
+#define LPASS_CDC_RX_BCL_VBAT_GAIN_UPD3	(RX_START_OFFSET + 0x02C0)
+#define LPASS_CDC_RX_BCL_VBAT_GAIN_UPD4	(RX_START_OFFSET + 0x02C4)
+#define LPASS_CDC_RX_BCL_VBAT_GAIN_UPD5	(RX_START_OFFSET + 0x02C8)
+#define LPASS_CDC_RX_BCL_VBAT_DEBUG1		(RX_START_OFFSET + 0x02CC)
+#define LPASS_CDC_RX_BCL_VBAT_GAIN_UPD_MON	(RX_START_OFFSET + 0x02D0)
+#define LPASS_CDC_RX_BCL_VBAT_GAIN_MON_VAL	(RX_START_OFFSET + 0x02D4)
+#define LPASS_CDC_RX_BCL_VBAT_BAN		(RX_START_OFFSET + 0x02D8)
+#define LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1	(RX_START_OFFSET + 0x02DC)
+#define LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2	(RX_START_OFFSET + 0x02E0)
+#define LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3	(RX_START_OFFSET + 0x02E4)
+#define LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4	(RX_START_OFFSET + 0x02E8)
+#define LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5	(RX_START_OFFSET + 0x02EC)
+#define LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6	(RX_START_OFFSET + 0x02F0)
+#define LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7	(RX_START_OFFSET + 0x02F4)
+#define LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8	(RX_START_OFFSET + 0x02F8)
+#define LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9	(RX_START_OFFSET + 0x02FC)
+#define LPASS_CDC_RX_BCL_VBAT_ATTN1		(RX_START_OFFSET + 0x0300)
+#define LPASS_CDC_RX_BCL_VBAT_ATTN2		(RX_START_OFFSET + 0x0304)
+#define LPASS_CDC_RX_BCL_VBAT_ATTN3		(RX_START_OFFSET + 0x0308)
+#define LPASS_CDC_RX_BCL_VBAT_DECODE_CTL1	(RX_START_OFFSET + 0x030C)
+#define LPASS_CDC_RX_BCL_VBAT_DECODE_CTL2	(RX_START_OFFSET + 0x0310)
+#define LPASS_CDC_RX_BCL_VBAT_DECODE_CFG1	(RX_START_OFFSET + 0x0314)
+#define LPASS_CDC_RX_BCL_VBAT_DECODE_CFG2	(RX_START_OFFSET + 0x0318)
+#define LPASS_CDC_RX_BCL_VBAT_DECODE_CFG3	(RX_START_OFFSET + 0x031C)
+#define LPASS_CDC_RX_BCL_VBAT_DECODE_CFG4	(RX_START_OFFSET + 0x0320)
+#define LPASS_CDC_RX_BCL_VBAT_DECODE_ST	(RX_START_OFFSET + 0x0324)
+#define LPASS_CDC_RX_INTR_CTRL_CFG		(RX_START_OFFSET + 0x0340)
+#define LPASS_CDC_RX_INTR_CTRL_CLR_COMMIT	(RX_START_OFFSET + 0x0344)
+#define LPASS_CDC_RX_INTR_CTRL_PIN1_MASK0	(RX_START_OFFSET + 0x0360)
+#define LPASS_CDC_RX_INTR_CTRL_PIN1_STATUS0	(RX_START_OFFSET + 0x0368)
+#define LPASS_CDC_RX_INTR_CTRL_PIN1_CLEAR0	(RX_START_OFFSET + 0x0370)
+#define LPASS_CDC_RX_INTR_CTRL_PIN2_MASK0	(RX_START_OFFSET + 0x0380)
+#define LPASS_CDC_RX_INTR_CTRL_PIN2_STATUS0	(RX_START_OFFSET + 0x0388)
+#define LPASS_CDC_RX_INTR_CTRL_PIN2_CLEAR0	(RX_START_OFFSET + 0x0390)
+#define LPASS_CDC_RX_INTR_CTRL_LEVEL0		(RX_START_OFFSET + 0x03C0)
+#define LPASS_CDC_RX_INTR_CTRL_BYPASS0		(RX_START_OFFSET + 0x03C8)
+#define LPASS_CDC_RX_INTR_CTRL_SET0		(RX_START_OFFSET + 0x03D0)
+#define LPASS_CDC_RX_RX0_RX_PATH_CTL		(RX_START_OFFSET + 0x0400)
+#define LPASS_CDC_RX_RX0_RX_PATH_CFG0		(RX_START_OFFSET + 0x0404)
+#define LPASS_CDC_RX_RX0_RX_PATH_CFG1		(RX_START_OFFSET + 0x0408)
+#define LPASS_CDC_RX_RX0_RX_PATH_CFG2		(RX_START_OFFSET + 0x040C)
+#define LPASS_CDC_RX_RX0_RX_PATH_CFG3		(RX_START_OFFSET + 0x0410)
+#define LPASS_CDC_RX_RX0_RX_VOL_CTL		(RX_START_OFFSET + 0x0414)
+#define LPASS_CDC_RX_RX0_RX_PATH_MIX_CTL	(RX_START_OFFSET + 0x0418)
+#define LPASS_CDC_RX_RX0_RX_PATH_MIX_CFG	(RX_START_OFFSET + 0x041C)
+#define LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL	(RX_START_OFFSET + 0x0420)
+#define LPASS_CDC_RX_RX0_RX_PATH_SEC1		(RX_START_OFFSET + 0x0424)
+#define LPASS_CDC_RX_RX0_RX_PATH_SEC2		(RX_START_OFFSET + 0x0428)
+#define LPASS_CDC_RX_RX0_RX_PATH_SEC3		(RX_START_OFFSET + 0x042C)
+#define LPASS_CDC_RX_RX0_RX_PATH_SEC4		(RX_START_OFFSET + 0x0430)
+#define LPASS_CDC_RX_RX0_RX_PATH_SEC7		(RX_START_OFFSET + 0x0434)
+#define LPASS_CDC_RX_RX0_RX_PATH_MIX_SEC0	(RX_START_OFFSET + 0x0438)
+#define LPASS_CDC_RX_RX0_RX_PATH_MIX_SEC1	(RX_START_OFFSET + 0x043C)
+#define LPASS_CDC_RX_RX0_RX_PATH_DSM_CTL	(RX_START_OFFSET + 0x0440)
+#define LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA1	(RX_START_OFFSET + 0x0444)
+#define LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA2	(RX_START_OFFSET + 0x0448)
+#define LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA3	(RX_START_OFFSET + 0x044C)
+#define LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA4	(RX_START_OFFSET + 0x0450)
+#define LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA5	(RX_START_OFFSET + 0x0454)
+#define LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA6	(RX_START_OFFSET + 0x0458)
+#define LPASS_CDC_RX_RX1_RX_PATH_CTL		(RX_START_OFFSET + 0x0480)
+#define LPASS_CDC_RX_RX1_RX_PATH_CFG0		(RX_START_OFFSET + 0x0484)
+#define LPASS_CDC_RX_RX1_RX_PATH_CFG1		(RX_START_OFFSET + 0x0488)
+#define LPASS_CDC_RX_RX1_RX_PATH_CFG2		(RX_START_OFFSET + 0x048C)
+#define LPASS_CDC_RX_RX1_RX_PATH_CFG3		(RX_START_OFFSET + 0x0490)
+#define LPASS_CDC_RX_RX1_RX_VOL_CTL		(RX_START_OFFSET + 0x0494)
+#define LPASS_CDC_RX_RX1_RX_PATH_MIX_CTL	(RX_START_OFFSET + 0x0498)
+#define LPASS_CDC_RX_RX1_RX_PATH_MIX_CFG	(RX_START_OFFSET + 0x049C)
+#define LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL	(RX_START_OFFSET + 0x04A0)
+#define LPASS_CDC_RX_RX1_RX_PATH_SEC1		(RX_START_OFFSET + 0x04A4)
+#define LPASS_CDC_RX_RX1_RX_PATH_SEC2		(RX_START_OFFSET + 0x04A8)
+#define LPASS_CDC_RX_RX1_RX_PATH_SEC3		(RX_START_OFFSET + 0x04AC)
+#define LPASS_CDC_RX_RX1_RX_PATH_SEC4		(RX_START_OFFSET + 0x04B0)
+#define LPASS_CDC_RX_RX1_RX_PATH_SEC7		(RX_START_OFFSET + 0x04B4)
+#define LPASS_CDC_RX_RX1_RX_PATH_MIX_SEC0	(RX_START_OFFSET + 0x04B8)
+#define LPASS_CDC_RX_RX1_RX_PATH_MIX_SEC1	(RX_START_OFFSET + 0x04BC)
+#define LPASS_CDC_RX_RX1_RX_PATH_DSM_CTL	(RX_START_OFFSET + 0x04C0)
+#define LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA1	(RX_START_OFFSET + 0x04C4)
+#define LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA2	(RX_START_OFFSET + 0x04C8)
+#define LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA3	(RX_START_OFFSET + 0x04CC)
+#define LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA4	(RX_START_OFFSET + 0x04D0)
+#define LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA5	(RX_START_OFFSET + 0x04D4)
+#define LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA6	(RX_START_OFFSET + 0x04D8)
+#define LPASS_CDC_RX_RX2_RX_PATH_CTL		(RX_START_OFFSET + 0x0500)
+#define LPASS_CDC_RX_RX2_RX_PATH_CFG0		(RX_START_OFFSET + 0x0504)
+#define LPASS_CDC_RX_RX2_RX_PATH_CFG1		(RX_START_OFFSET + 0x0508)
+#define LPASS_CDC_RX_RX2_RX_PATH_CFG2		(RX_START_OFFSET + 0x050C)
+#define LPASS_CDC_RX_RX2_RX_PATH_CFG3		(RX_START_OFFSET + 0x0510)
+#define LPASS_CDC_RX_RX2_RX_VOL_CTL		(RX_START_OFFSET + 0x0514)
+#define LPASS_CDC_RX_RX2_RX_PATH_MIX_CTL	(RX_START_OFFSET + 0x0518)
+#define LPASS_CDC_RX_RX2_RX_PATH_MIX_CFG	(RX_START_OFFSET + 0x051C)
+#define LPASS_CDC_RX_RX2_RX_VOL_MIX_CTL	(RX_START_OFFSET + 0x0520)
+#define LPASS_CDC_RX_RX2_RX_PATH_SEC0		(RX_START_OFFSET + 0x0524)
+#define LPASS_CDC_RX_RX2_RX_PATH_SEC1		(RX_START_OFFSET + 0x0528)
+#define LPASS_CDC_RX_RX2_RX_PATH_SEC2		(RX_START_OFFSET + 0x052C)
+#define LPASS_CDC_RX_RX2_RX_PATH_SEC3		(RX_START_OFFSET + 0x0530)
+#define LPASS_CDC_RX_RX2_RX_PATH_SEC4		(RX_START_OFFSET + 0x0534)
+#define LPASS_CDC_RX_RX2_RX_PATH_SEC5		(RX_START_OFFSET + 0x0538)
+#define LPASS_CDC_RX_RX2_RX_PATH_SEC6		(RX_START_OFFSET + 0x053C)
+#define LPASS_CDC_RX_RX2_RX_PATH_SEC7		(RX_START_OFFSET + 0x0540)
+#define LPASS_CDC_RX_RX2_RX_PATH_MIX_SEC0	(RX_START_OFFSET + 0x0544)
+#define LPASS_CDC_RX_RX2_RX_PATH_MIX_SEC1	(RX_START_OFFSET + 0x0548)
+#define LPASS_CDC_RX_RX2_RX_PATH_DSM_CTL	(RX_START_OFFSET + 0x054C)
+#define LPASS_CDC_RX_IDLE_DETECT_PATH_CTL	(RX_START_OFFSET + 0x0780)
+#define LPASS_CDC_RX_IDLE_DETECT_CFG0		(RX_START_OFFSET + 0x0784)
+#define LPASS_CDC_RX_IDLE_DETECT_CFG1		(RX_START_OFFSET + 0x0788)
+#define LPASS_CDC_RX_IDLE_DETECT_CFG2		(RX_START_OFFSET + 0x078C)
+#define LPASS_CDC_RX_IDLE_DETECT_CFG3		(RX_START_OFFSET + 0x0790)
+#define LPASS_CDC_RX_COMPANDER0_CTL0		(RX_START_OFFSET + 0x0800)
+#define LPASS_CDC_RX_COMPANDER0_CTL1		(RX_START_OFFSET + 0x0804)
+#define LPASS_CDC_RX_COMPANDER0_CTL2		(RX_START_OFFSET + 0x0808)
+#define LPASS_CDC_RX_COMPANDER0_CTL3		(RX_START_OFFSET + 0x080C)
+#define LPASS_CDC_RX_COMPANDER0_CTL4		(RX_START_OFFSET + 0x0810)
+#define LPASS_CDC_RX_COMPANDER0_CTL5		(RX_START_OFFSET + 0x0814)
+#define LPASS_CDC_RX_COMPANDER0_CTL6		(RX_START_OFFSET + 0x0818)
+#define LPASS_CDC_RX_COMPANDER0_CTL7		(RX_START_OFFSET + 0x081C)
+#define LPASS_CDC_RX_COMPANDER1_CTL0		(RX_START_OFFSET + 0x0840)
+#define LPASS_CDC_RX_COMPANDER1_CTL1		(RX_START_OFFSET + 0x0844)
+#define LPASS_CDC_RX_COMPANDER1_CTL2		(RX_START_OFFSET + 0x0848)
+#define LPASS_CDC_RX_COMPANDER1_CTL3		(RX_START_OFFSET + 0x084C)
+#define LPASS_CDC_RX_COMPANDER1_CTL4		(RX_START_OFFSET + 0x0850)
+#define LPASS_CDC_RX_COMPANDER1_CTL5		(RX_START_OFFSET + 0x0854)
+#define LPASS_CDC_RX_COMPANDER1_CTL6		(RX_START_OFFSET + 0x0858)
+#define LPASS_CDC_RX_COMPANDER1_CTL7		(RX_START_OFFSET + 0x085C)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL \
+						(RX_START_OFFSET + 0x0A00)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL \
+						(RX_START_OFFSET + 0x0A04)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL \
+						(RX_START_OFFSET + 0x0A08)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL \
+						(RX_START_OFFSET + 0x0A0C)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL \
+						(RX_START_OFFSET + 0x0A10)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL \
+						(RX_START_OFFSET + 0x0A14)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL \
+						(RX_START_OFFSET + 0x0A18)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL \
+						(RX_START_OFFSET + 0x0A1C)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL \
+						(RX_START_OFFSET + 0x0A20)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_CTL	(RX_START_OFFSET + 0x0A24)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL \
+						(RX_START_OFFSET + 0x0A28)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL \
+						(RX_START_OFFSET + 0x0A2C)
+#define LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL \
+						(RX_START_OFFSET + 0x0A30)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL \
+						(RX_START_OFFSET + 0x0A80)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL \
+						(RX_START_OFFSET + 0x0A84)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL \
+						(RX_START_OFFSET + 0x0A88)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL \
+						(RX_START_OFFSET + 0x0A8C)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL \
+						(RX_START_OFFSET + 0x0A90)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL \
+						(RX_START_OFFSET + 0x0A94)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL \
+						(RX_START_OFFSET + 0x0A98)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL \
+						(RX_START_OFFSET + 0x0A9C)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL \
+						(RX_START_OFFSET + 0x0AA0)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_CTL	(RX_START_OFFSET + 0x0AA4)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL \
+						(RX_START_OFFSET + 0x0AA8)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL \
+						(RX_START_OFFSET + 0x0AAC)
+#define LPASS_CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL \
+						(RX_START_OFFSET + 0x0AB0)
+#define LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0	(RX_START_OFFSET + 0x0B00)
+#define LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1	(RX_START_OFFSET + 0x0B04)
+#define LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2	(RX_START_OFFSET + 0x0B08)
+#define LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3	(RX_START_OFFSET + 0x0B0C)
+#define LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0	(RX_START_OFFSET + 0x0B10)
+#define LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1	(RX_START_OFFSET + 0x0B14)
+#define LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2	(RX_START_OFFSET + 0x0B18)
+#define LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3	(RX_START_OFFSET + 0x0B1C)
+#define LPASS_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL \
+						(RX_START_OFFSET + 0x0B40)
+#define LPASS_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1 \
+						(RX_START_OFFSET + 0x0B44)
+#define LPASS_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL \
+						(RX_START_OFFSET + 0x0B50)
+#define LPASS_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1 \
+						(RX_START_OFFSET + 0x0B54)
+#define LPASS_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL \
+						(RX_START_OFFSET + 0x0C00)
+#define LPASS_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0	(RX_START_OFFSET + 0x0C04)
+#define LPASS_CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL \
+						(RX_START_OFFSET + 0x0C40)
+#define LPASS_CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0	(RX_START_OFFSET + 0x0C44)
+#define LPASS_CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL \
+						(RX_START_OFFSET + 0x0C80)
+#define LPASS_CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0	(RX_START_OFFSET + 0x0C84)
+#define LPASS_CDC_RX_EC_ASRC0_CLK_RST_CTL	(RX_START_OFFSET + 0x0D00)
+#define LPASS_CDC_RX_EC_ASRC0_CTL0		(RX_START_OFFSET + 0x0D04)
+#define LPASS_CDC_RX_EC_ASRC0_CTL1		(RX_START_OFFSET + 0x0D08)
+#define LPASS_CDC_RX_EC_ASRC0_FIFO_CTL		(RX_START_OFFSET + 0x0D0C)
+#define LPASS_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB \
+						(RX_START_OFFSET + 0x0D10)
+#define LPASS_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB \
+						(RX_START_OFFSET + 0x0D14)
+#define LPASS_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB \
+						(RX_START_OFFSET + 0x0D18)
+#define LPASS_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB \
+						(RX_START_OFFSET + 0x0D1C)
+#define LPASS_CDC_RX_EC_ASRC0_STATUS_FIFO	(RX_START_OFFSET + 0x0D20)
+#define LPASS_CDC_RX_EC_ASRC1_CLK_RST_CTL	(RX_START_OFFSET + 0x0D40)
+#define LPASS_CDC_RX_EC_ASRC1_CTL0		(RX_START_OFFSET + 0x0D44)
+#define LPASS_CDC_RX_EC_ASRC1_CTL1		(RX_START_OFFSET + 0x0D48)
+#define LPASS_CDC_RX_EC_ASRC1_FIFO_CTL		(RX_START_OFFSET + 0x0D4C)
+#define LPASS_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB \
+						(RX_START_OFFSET + 0x0D50)
+#define LPASS_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB \
+						(RX_START_OFFSET + 0x0D54)
+#define LPASS_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB \
+						(RX_START_OFFSET + 0x0D58)
+#define LPASS_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB \
+						(RX_START_OFFSET + 0x0D5C)
+#define LPASS_CDC_RX_EC_ASRC1_STATUS_FIFO	(RX_START_OFFSET + 0x0D60)
+#define LPASS_CDC_RX_EC_ASRC2_CLK_RST_CTL	(RX_START_OFFSET + 0x0D80)
+#define LPASS_CDC_RX_EC_ASRC2_CTL0		(RX_START_OFFSET + 0x0D84)
+#define LPASS_CDC_RX_EC_ASRC2_CTL1		(RX_START_OFFSET + 0x0D88)
+#define LPASS_CDC_RX_EC_ASRC2_FIFO_CTL		(RX_START_OFFSET + 0x0D8C)
+#define LPASS_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB \
+						(RX_START_OFFSET + 0x0D90)
+#define LPASS_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB \
+						(RX_START_OFFSET + 0x0D94)
+#define LPASS_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB \
+						(RX_START_OFFSET + 0x0D98)
+#define LPASS_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB \
+						(RX_START_OFFSET + 0x0D9C)
+#define LPASS_CDC_RX_EC_ASRC2_STATUS_FIFO	(RX_START_OFFSET + 0x0DA0)
+#define LPASS_CDC_RX_DSD0_PATH_CTL		(RX_START_OFFSET + 0x0F00)
+#define LPASS_CDC_RX_DSD0_CFG0			(RX_START_OFFSET + 0x0F04)
+#define LPASS_CDC_RX_DSD0_CFG1			(RX_START_OFFSET + 0x0F08)
+#define LPASS_CDC_RX_DSD0_CFG2			(RX_START_OFFSET + 0x0F0C)
+#define LPASS_CDC_RX_DSD1_PATH_CTL		(RX_START_OFFSET + 0x0F80)
+#define LPASS_CDC_RX_DSD1_CFG0			(RX_START_OFFSET + 0x0F84)
+#define LPASS_CDC_RX_DSD1_CFG1			(RX_START_OFFSET + 0x0F88)
+#define LPASS_CDC_RX_DSD1_CFG2			(RX_START_OFFSET + 0x0F8C)
+#define RX_MAX_OFFSET				(RX_START_OFFSET + 0x0F8C)
+
+#define LPASS_CDC_RX_MACRO_MAX 0x3E4 /* F8C/4 = 3E3 + 1 */
+
+/* WSA - macro#2 */
+#define WSA_START_OFFSET			0x2000
+#define LPASS_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL \
+						(WSA_START_OFFSET + 0x0000)
+#define LPASS_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL \
+						(WSA_START_OFFSET + 0x0004)
+#define LPASS_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL	(WSA_START_OFFSET + 0x0008)
+#define LPASS_CDC_WSA_TOP_TOP_CFG0		(WSA_START_OFFSET + 0x0080)
+#define LPASS_CDC_WSA_TOP_TOP_CFG1		(WSA_START_OFFSET + 0x0084)
+#define LPASS_CDC_WSA_TOP_FREQ_MCLK		(WSA_START_OFFSET + 0x0088)
+#define LPASS_CDC_WSA_TOP_DEBUG_BUS_SEL	(WSA_START_OFFSET + 0x008C)
+#define LPASS_CDC_WSA_TOP_DEBUG_EN0		(WSA_START_OFFSET + 0x0090)
+#define LPASS_CDC_WSA_TOP_DEBUG_EN1		(WSA_START_OFFSET + 0x0094)
+#define LPASS_CDC_WSA_TOP_DEBUG_DSM_LB		(WSA_START_OFFSET + 0x0098)
+#define LPASS_CDC_WSA_TOP_RX_I2S_CTL		(WSA_START_OFFSET + 0x009C)
+#define LPASS_CDC_WSA_TOP_TX_I2S_CTL		(WSA_START_OFFSET + 0x00A0)
+#define LPASS_CDC_WSA_TOP_I2S_CLK		(WSA_START_OFFSET + 0x00A4)
+#define LPASS_CDC_WSA_TOP_I2S_RESET		(WSA_START_OFFSET + 0x00A8)
+#define LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0	(WSA_START_OFFSET + 0x0100)
+#define LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1	(WSA_START_OFFSET + 0x0104)
+#define LPASS_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0	(WSA_START_OFFSET + 0x0108)
+#define LPASS_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1	(WSA_START_OFFSET + 0x010C)
+#define LPASS_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0	(WSA_START_OFFSET + 0x0110)
+#define LPASS_CDC_WSA_RX_INP_MUX_RX_EC_CFG0	(WSA_START_OFFSET + 0x0114)
+#define LPASS_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0	(WSA_START_OFFSET + 0x0118)
+/* VBAT registers  */
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL	(WSA_START_OFFSET + 0x0180)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_CFG	(WSA_START_OFFSET + 0x0184)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL1	(WSA_START_OFFSET + 0x0188)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL2	(WSA_START_OFFSET + 0x018C)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL3	(WSA_START_OFFSET + 0x0190)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_PK_EST1	(WSA_START_OFFSET + 0x0194)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_PK_EST2	(WSA_START_OFFSET + 0x0198)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_PK_EST3	(WSA_START_OFFSET + 0x019C)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_RF_PROC1	(WSA_START_OFFSET + 0x01A0)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_RF_PROC2	(WSA_START_OFFSET + 0x01A4)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC1	(WSA_START_OFFSET + 0x01A8)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC2	(WSA_START_OFFSET + 0x01AC)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC3	(WSA_START_OFFSET + 0x01B0)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC4	(WSA_START_OFFSET + 0x01B4)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD1	(WSA_START_OFFSET + 0x01B8)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD2	(WSA_START_OFFSET + 0x01BC)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD3	(WSA_START_OFFSET + 0x01C0)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD4	(WSA_START_OFFSET + 0x01C4)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD5	(WSA_START_OFFSET + 0x01C8)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_DEBUG1	(WSA_START_OFFSET + 0x01CC)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD_MON \
+						(WSA_START_OFFSET + 0x01D0)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL \
+						(WSA_START_OFFSET + 0x01D4)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BAN	(WSA_START_OFFSET + 0x01D8)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1 \
+						(WSA_START_OFFSET + 0x01DC)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2 \
+						(WSA_START_OFFSET + 0x01E0)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3 \
+						(WSA_START_OFFSET + 0x01E4)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4 \
+						(WSA_START_OFFSET + 0x01E8)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5 \
+						(WSA_START_OFFSET + 0x01EC)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6 \
+						(WSA_START_OFFSET + 0x01F0)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7 \
+						(WSA_START_OFFSET + 0x01F4)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8 \
+						(WSA_START_OFFSET + 0x01F8)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9 \
+						(WSA_START_OFFSET + 0x01FC)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN1	(WSA_START_OFFSET + 0x0200)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN2	(WSA_START_OFFSET + 0x0204)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN3	(WSA_START_OFFSET + 0x0208)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1 \
+						(WSA_START_OFFSET + 0x020C)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL2 \
+						(WSA_START_OFFSET + 0x0210)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1 \
+						(WSA_START_OFFSET + 0x0214)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2 \
+						(WSA_START_OFFSET + 0x0218)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3 \
+						(WSA_START_OFFSET + 0x021C)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4 \
+						(WSA_START_OFFSET + 0x0220)
+#define LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST	(WSA_START_OFFSET + 0x0224)
+#define LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CTL	(WSA_START_OFFSET + 0x0244)
+#define LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0	(WSA_START_OFFSET + 0x0248)
+#define LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CTL	(WSA_START_OFFSET + 0x0264)
+#define LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0	(WSA_START_OFFSET + 0x0268)
+#define LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CTL	(WSA_START_OFFSET + 0x0284)
+#define LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0	(WSA_START_OFFSET + 0x0288)
+#define LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CTL	(WSA_START_OFFSET + 0x02A4)
+#define LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0	(WSA_START_OFFSET + 0x02A8)
+#define LPASS_CDC_WSA_INTR_CTRL_CFG		(WSA_START_OFFSET + 0x0340)
+#define LPASS_CDC_WSA_INTR_CTRL_CLR_COMMIT	(WSA_START_OFFSET + 0x0344)
+#define LPASS_CDC_WSA_INTR_CTRL_PIN1_MASK0	(WSA_START_OFFSET + 0x0360)
+#define LPASS_CDC_WSA_INTR_CTRL_PIN1_STATUS0	(WSA_START_OFFSET + 0x0368)
+#define LPASS_CDC_WSA_INTR_CTRL_PIN1_CLEAR0	(WSA_START_OFFSET + 0x0370)
+#define LPASS_CDC_WSA_INTR_CTRL_PIN2_MASK0	(WSA_START_OFFSET + 0x0380)
+#define LPASS_CDC_WSA_INTR_CTRL_PIN2_STATUS0	(WSA_START_OFFSET + 0x0388)
+#define LPASS_CDC_WSA_INTR_CTRL_PIN2_CLEAR0	(WSA_START_OFFSET + 0x0390)
+#define LPASS_CDC_WSA_INTR_CTRL_LEVEL0		(WSA_START_OFFSET + 0x03C0)
+#define LPASS_CDC_WSA_INTR_CTRL_BYPASS0	(WSA_START_OFFSET + 0x03C8)
+#define LPASS_CDC_WSA_INTR_CTRL_SET0		(WSA_START_OFFSET + 0x03D0)
+#define LPASS_CDC_WSA_RX0_RX_PATH_CTL		(WSA_START_OFFSET + 0x0400)
+#define LPASS_CDC_WSA_RX0_RX_PATH_CFG0		(WSA_START_OFFSET + 0x0404)
+#define LPASS_CDC_WSA_RX0_RX_PATH_CFG1		(WSA_START_OFFSET + 0x0408)
+#define LPASS_CDC_WSA_RX0_RX_PATH_CFG2		(WSA_START_OFFSET + 0x040C)
+#define LPASS_CDC_WSA_RX0_RX_PATH_CFG3		(WSA_START_OFFSET + 0x0410)
+#define LPASS_CDC_WSA_RX0_RX_VOL_CTL		(WSA_START_OFFSET + 0x0414)
+#define LPASS_CDC_WSA_RX0_RX_PATH_MIX_CTL	(WSA_START_OFFSET + 0x0418)
+#define LPASS_CDC_WSA_RX0_RX_PATH_MIX_CFG	(WSA_START_OFFSET + 0x041C)
+#define LPASS_CDC_WSA_RX0_RX_VOL_MIX_CTL	(WSA_START_OFFSET + 0x0420)
+#define LPASS_CDC_WSA_RX0_RX_PATH_SEC0		(WSA_START_OFFSET + 0x0424)
+#define LPASS_CDC_WSA_RX0_RX_PATH_SEC1		(WSA_START_OFFSET + 0x0428)
+#define LPASS_CDC_WSA_RX0_RX_PATH_SEC2		(WSA_START_OFFSET + 0x042C)
+#define LPASS_CDC_WSA_RX0_RX_PATH_SEC3		(WSA_START_OFFSET + 0x0430)
+#define LPASS_CDC_WSA_RX0_RX_PATH_SEC5		(WSA_START_OFFSET + 0x0438)
+#define LPASS_CDC_WSA_RX0_RX_PATH_SEC6		(WSA_START_OFFSET + 0x043C)
+#define LPASS_CDC_WSA_RX0_RX_PATH_SEC7		(WSA_START_OFFSET + 0x0440)
+#define LPASS_CDC_WSA_RX0_RX_PATH_MIX_SEC0	(WSA_START_OFFSET + 0x0444)
+#define LPASS_CDC_WSA_RX0_RX_PATH_MIX_SEC1	(WSA_START_OFFSET + 0x0448)
+#define LPASS_CDC_WSA_RX0_RX_PATH_DSMDEM_CTL	(WSA_START_OFFSET + 0x044C)
+#define LPASS_CDC_WSA_RX1_RX_PATH_CTL		(WSA_START_OFFSET + 0x0480)
+#define LPASS_CDC_WSA_RX1_RX_PATH_CFG0		(WSA_START_OFFSET + 0x0484)
+#define LPASS_CDC_WSA_RX1_RX_PATH_CFG1		(WSA_START_OFFSET + 0x0488)
+#define LPASS_CDC_WSA_RX1_RX_PATH_CFG2		(WSA_START_OFFSET + 0x048C)
+#define LPASS_CDC_WSA_RX1_RX_PATH_CFG3		(WSA_START_OFFSET + 0x0490)
+#define LPASS_CDC_WSA_RX1_RX_VOL_CTL		(WSA_START_OFFSET + 0x0494)
+#define LPASS_CDC_WSA_RX1_RX_PATH_MIX_CTL	(WSA_START_OFFSET + 0x0498)
+#define LPASS_CDC_WSA_RX1_RX_PATH_MIX_CFG	(WSA_START_OFFSET + 0x049C)
+#define LPASS_CDC_WSA_RX1_RX_VOL_MIX_CTL	(WSA_START_OFFSET + 0x04A0)
+#define LPASS_CDC_WSA_RX1_RX_PATH_SEC0		(WSA_START_OFFSET + 0x04A4)
+#define LPASS_CDC_WSA_RX1_RX_PATH_SEC1		(WSA_START_OFFSET + 0x04A8)
+#define LPASS_CDC_WSA_RX1_RX_PATH_SEC2		(WSA_START_OFFSET + 0x04AC)
+#define LPASS_CDC_WSA_RX1_RX_PATH_SEC3		(WSA_START_OFFSET + 0x04B0)
+#define LPASS_CDC_WSA_RX1_RX_PATH_SEC5		(WSA_START_OFFSET + 0x04B8)
+#define LPASS_CDC_WSA_RX1_RX_PATH_SEC6		(WSA_START_OFFSET + 0x04BC)
+#define LPASS_CDC_WSA_RX1_RX_PATH_SEC7		(WSA_START_OFFSET + 0x04C0)
+#define LPASS_CDC_WSA_RX1_RX_PATH_MIX_SEC0	(WSA_START_OFFSET + 0x04C4)
+#define LPASS_CDC_WSA_RX1_RX_PATH_MIX_SEC1	(WSA_START_OFFSET + 0x04C8)
+#define LPASS_CDC_WSA_RX1_RX_PATH_DSMDEM_CTL	(WSA_START_OFFSET + 0x04CC)
+#define LPASS_CDC_WSA_BOOST0_BOOST_PATH_CTL	(WSA_START_OFFSET + 0x0500)
+#define LPASS_CDC_WSA_BOOST0_BOOST_CTL		(WSA_START_OFFSET + 0x0504)
+#define LPASS_CDC_WSA_BOOST0_BOOST_CFG1	(WSA_START_OFFSET + 0x0508)
+#define LPASS_CDC_WSA_BOOST0_BOOST_CFG2	(WSA_START_OFFSET + 0x050C)
+#define LPASS_CDC_WSA_BOOST1_BOOST_PATH_CTL	(WSA_START_OFFSET + 0x0540)
+#define LPASS_CDC_WSA_BOOST1_BOOST_CTL		(WSA_START_OFFSET + 0x0544)
+#define LPASS_CDC_WSA_BOOST1_BOOST_CFG1	(WSA_START_OFFSET + 0x0548)
+#define LPASS_CDC_WSA_BOOST1_BOOST_CFG2	(WSA_START_OFFSET + 0x054C)
+#define LPASS_CDC_WSA_COMPANDER0_CTL0		(WSA_START_OFFSET + 0x0580)
+#define LPASS_CDC_WSA_COMPANDER0_CTL1		(WSA_START_OFFSET + 0x0584)
+#define LPASS_CDC_WSA_COMPANDER0_CTL2		(WSA_START_OFFSET + 0x0588)
+#define LPASS_CDC_WSA_COMPANDER0_CTL3		(WSA_START_OFFSET + 0x058C)
+#define LPASS_CDC_WSA_COMPANDER0_CTL4		(WSA_START_OFFSET + 0x0590)
+#define LPASS_CDC_WSA_COMPANDER0_CTL5		(WSA_START_OFFSET + 0x0594)
+#define LPASS_CDC_WSA_COMPANDER0_CTL6		(WSA_START_OFFSET + 0x0598)
+#define LPASS_CDC_WSA_COMPANDER0_CTL7		(WSA_START_OFFSET + 0x059C)
+#define LPASS_CDC_WSA_COMPANDER1_CTL0		(WSA_START_OFFSET + 0x05C0)
+#define LPASS_CDC_WSA_COMPANDER1_CTL1		(WSA_START_OFFSET + 0x05C4)
+#define LPASS_CDC_WSA_COMPANDER1_CTL2		(WSA_START_OFFSET + 0x05C8)
+#define LPASS_CDC_WSA_COMPANDER1_CTL3		(WSA_START_OFFSET + 0x05CC)
+#define LPASS_CDC_WSA_COMPANDER1_CTL4		(WSA_START_OFFSET + 0x05D0)
+#define LPASS_CDC_WSA_COMPANDER1_CTL5		(WSA_START_OFFSET + 0x05D4)
+#define LPASS_CDC_WSA_COMPANDER1_CTL6		(WSA_START_OFFSET + 0x05D8)
+#define LPASS_CDC_WSA_COMPANDER1_CTL7		(WSA_START_OFFSET + 0x05DC)
+#define LPASS_CDC_WSA_SOFTCLIP0_CRC		(WSA_START_OFFSET + 0x0600)
+#define LPASS_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL	(WSA_START_OFFSET + 0x0604)
+#define LPASS_CDC_WSA_SOFTCLIP1_CRC		(WSA_START_OFFSET + 0x0640)
+#define LPASS_CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL	(WSA_START_OFFSET + 0x0644)
+#define LPASS_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL \
+						(WSA_START_OFFSET + 0x0680)
+#define LPASS_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0	(WSA_START_OFFSET + 0x0684)
+#define LPASS_CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL \
+						(WSA_START_OFFSET + 0x06C0)
+#define LPASS_CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0	(WSA_START_OFFSET + 0x06C4)
+#define LPASS_CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL	(WSA_START_OFFSET + 0x0700)
+#define LPASS_CDC_WSA_SPLINE_ASRC0_CTL0	(WSA_START_OFFSET + 0x0704)
+#define LPASS_CDC_WSA_SPLINE_ASRC0_CTL1	(WSA_START_OFFSET + 0x0708)
+#define LPASS_CDC_WSA_SPLINE_ASRC0_FIFO_CTL	(WSA_START_OFFSET + 0x070C)
+#define LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB \
+						(WSA_START_OFFSET + 0x0710)
+#define LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB \
+						(WSA_START_OFFSET + 0x0714)
+#define LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB \
+						(WSA_START_OFFSET + 0x0718)
+#define LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB \
+						(WSA_START_OFFSET + 0x071C)
+#define LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO	(WSA_START_OFFSET + 0x0720)
+#define LPASS_CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL	(WSA_START_OFFSET + 0x0740)
+#define LPASS_CDC_WSA_SPLINE_ASRC1_CTL0	(WSA_START_OFFSET + 0x0744)
+#define LPASS_CDC_WSA_SPLINE_ASRC1_CTL1	(WSA_START_OFFSET + 0x0748)
+#define LPASS_CDC_WSA_SPLINE_ASRC1_FIFO_CTL	(WSA_START_OFFSET + 0x074C)
+#define LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB \
+						(WSA_START_OFFSET + 0x0750)
+#define LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB \
+						(WSA_START_OFFSET + 0x0754)
+#define LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB \
+						(WSA_START_OFFSET + 0x0758)
+#define LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB \
+						(WSA_START_OFFSET + 0x075C)
+#define LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO	(WSA_START_OFFSET + 0x0760)
+#define WSA_MAX_OFFSET				(WSA_START_OFFSET + 0x0760)
+
+#define LPASS_CDC_WSA_MACRO_MAX 0x1D9 /* 0x760/4 = 0x1D8 + 1 registers */
+
+/* VA macro registers */
+#define VA_START_OFFSET				0x3000
+#define LPASS_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL	(VA_START_OFFSET + 0x0000)
+#define LPASS_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL \
+						(VA_START_OFFSET + 0x0004)
+#define LPASS_CDC_VA_CLK_RST_CTRL_SWR_CONTROL	(VA_START_OFFSET + 0x0008)
+#define LPASS_CDC_VA_TOP_CSR_TOP_CFG0		(VA_START_OFFSET + 0x0080)
+#define LPASS_CDC_VA_TOP_CSR_DMIC0_CTL		(VA_START_OFFSET + 0x0084)
+#define LPASS_CDC_VA_TOP_CSR_DMIC1_CTL		(VA_START_OFFSET + 0x0088)
+#define LPASS_CDC_VA_TOP_CSR_DMIC2_CTL		(VA_START_OFFSET + 0x008C)
+#define LPASS_CDC_VA_TOP_CSR_DMIC3_CTL		(VA_START_OFFSET + 0x0090)
+#define LPASS_CDC_VA_TOP_CSR_DMIC_CFG		(VA_START_OFFSET + 0x0094)
+#define LPASS_CDC_VA_TOP_CSR_DEBUG_BUS		(VA_START_OFFSET + 0x009C)
+#define LPASS_CDC_VA_TOP_CSR_DEBUG_EN		(VA_START_OFFSET + 0x00A0)
+#define LPASS_CDC_VA_TOP_CSR_TX_I2S_CTL	(VA_START_OFFSET + 0x00A4)
+#define LPASS_CDC_VA_TOP_CSR_I2S_CLK		(VA_START_OFFSET + 0x00A8)
+#define LPASS_CDC_VA_TOP_CSR_I2S_RESET		(VA_START_OFFSET + 0x00AC)
+#define LPASS_CDC_VA_TOP_CSR_CORE_ID_0		(VA_START_OFFSET + 0x00C0)
+#define LPASS_CDC_VA_TOP_CSR_CORE_ID_1		(VA_START_OFFSET + 0x00C4)
+#define LPASS_CDC_VA_TOP_CSR_CORE_ID_2		(VA_START_OFFSET + 0x00C8)
+#define LPASS_CDC_VA_TOP_CSR_CORE_ID_3		(VA_START_OFFSET + 0x00CC)
+#define VA_TOP_MAX_OFFSET			(VA_START_OFFSET + 0x00CC)
+
+#define LPASS_CDC_VA_MACRO_TOP_MAX 0x34 /* 0x0CC/4 = 0x33 + 1 = 0x34 */
+
+#define LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL0	(VA_START_OFFSET + 0x00D0)
+#define LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL1	(VA_START_OFFSET + 0x00D4)
+#define LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL2	(VA_START_OFFSET + 0x00D8)
+#define LPASS_CDC_VA_TOP_CSR_SWR_CTRL		(VA_START_OFFSET + 0x00DC)
+
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG0	(VA_START_OFFSET + 0x0100)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG1	(VA_START_OFFSET + 0x0104)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG0	(VA_START_OFFSET + 0x0108)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG1	(VA_START_OFFSET + 0x010C)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG0	(VA_START_OFFSET + 0x0110)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG1	(VA_START_OFFSET + 0x0114)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG0	(VA_START_OFFSET + 0x0118)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG1	(VA_START_OFFSET + 0x011C)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX4_CFG0	(VA_START_OFFSET + 0x0120)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX4_CFG1	(VA_START_OFFSET + 0x0124)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX5_CFG0	(VA_START_OFFSET + 0x0128)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX5_CFG1	(VA_START_OFFSET + 0x012C)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX6_CFG0	(VA_START_OFFSET + 0x0130)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX6_CFG1	(VA_START_OFFSET + 0x0134)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX7_CFG0	(VA_START_OFFSET + 0x0138)
+#define LPASS_CDC_VA_INP_MUX_ADC_MUX7_CFG1	(VA_START_OFFSET + 0x013C)
+
+#define LPASS_CDC_VA_TX0_TX_PATH_CTL	(VA_START_OFFSET + 0x0400)
+#define LPASS_CDC_VA_TX0_TX_PATH_CFG0	(VA_START_OFFSET + 0x0404)
+#define LPASS_CDC_VA_TX0_TX_PATH_CFG1	(VA_START_OFFSET + 0x0408)
+#define LPASS_CDC_VA_TX0_TX_VOL_CTL	(VA_START_OFFSET + 0x040C)
+#define LPASS_CDC_VA_TX0_TX_PATH_SEC0	(VA_START_OFFSET + 0x0410)
+#define LPASS_CDC_VA_TX0_TX_PATH_SEC1	(VA_START_OFFSET + 0x0414)
+#define LPASS_CDC_VA_TX0_TX_PATH_SEC2	(VA_START_OFFSET + 0x0418)
+#define LPASS_CDC_VA_TX0_TX_PATH_SEC3	(VA_START_OFFSET + 0x041C)
+#define LPASS_CDC_VA_TX0_TX_PATH_SEC4	(VA_START_OFFSET + 0x0420)
+#define LPASS_CDC_VA_TX0_TX_PATH_SEC5	(VA_START_OFFSET + 0x0424)
+#define LPASS_CDC_VA_TX0_TX_PATH_SEC6	(VA_START_OFFSET + 0x0428)
+#define LPASS_CDC_VA_TX0_TX_PATH_SEC7	(VA_START_OFFSET + 0x042C)
+#define LPASS_CDC_VA_TX1_TX_PATH_CTL	(VA_START_OFFSET + 0x0480)
+#define LPASS_CDC_VA_TX1_TX_PATH_CFG0	(VA_START_OFFSET + 0x0484)
+#define LPASS_CDC_VA_TX1_TX_PATH_CFG1	(VA_START_OFFSET + 0x0488)
+#define LPASS_CDC_VA_TX1_TX_VOL_CTL	(VA_START_OFFSET + 0x048C)
+#define LPASS_CDC_VA_TX1_TX_PATH_SEC0	(VA_START_OFFSET + 0x0490)
+#define LPASS_CDC_VA_TX1_TX_PATH_SEC1	(VA_START_OFFSET + 0x0494)
+#define LPASS_CDC_VA_TX1_TX_PATH_SEC2	(VA_START_OFFSET + 0x0498)
+#define LPASS_CDC_VA_TX1_TX_PATH_SEC3	(VA_START_OFFSET + 0x049C)
+#define LPASS_CDC_VA_TX1_TX_PATH_SEC4	(VA_START_OFFSET + 0x04A0)
+#define LPASS_CDC_VA_TX1_TX_PATH_SEC5	(VA_START_OFFSET + 0x04A4)
+#define LPASS_CDC_VA_TX1_TX_PATH_SEC6	(VA_START_OFFSET + 0x04A8)
+#define LPASS_CDC_VA_TX2_TX_PATH_CTL	(VA_START_OFFSET + 0x0500)
+#define LPASS_CDC_VA_TX2_TX_PATH_CFG0	(VA_START_OFFSET + 0x0504)
+#define LPASS_CDC_VA_TX2_TX_PATH_CFG1	(VA_START_OFFSET + 0x0508)
+#define LPASS_CDC_VA_TX2_TX_VOL_CTL	(VA_START_OFFSET + 0x050C)
+#define LPASS_CDC_VA_TX2_TX_PATH_SEC0	(VA_START_OFFSET + 0x0510)
+#define LPASS_CDC_VA_TX2_TX_PATH_SEC1	(VA_START_OFFSET + 0x0514)
+#define LPASS_CDC_VA_TX2_TX_PATH_SEC2	(VA_START_OFFSET + 0x0518)
+#define LPASS_CDC_VA_TX2_TX_PATH_SEC3	(VA_START_OFFSET + 0x051C)
+#define LPASS_CDC_VA_TX2_TX_PATH_SEC4	(VA_START_OFFSET + 0x0520)
+#define LPASS_CDC_VA_TX2_TX_PATH_SEC5	(VA_START_OFFSET + 0x0524)
+#define LPASS_CDC_VA_TX2_TX_PATH_SEC6	(VA_START_OFFSET + 0x0528)
+#define LPASS_CDC_VA_TX3_TX_PATH_CTL	(VA_START_OFFSET + 0x0580)
+#define LPASS_CDC_VA_TX3_TX_PATH_CFG0	(VA_START_OFFSET + 0x0584)
+#define LPASS_CDC_VA_TX3_TX_PATH_CFG1	(VA_START_OFFSET + 0x0588)
+#define LPASS_CDC_VA_TX3_TX_VOL_CTL	(VA_START_OFFSET + 0x058C)
+#define LPASS_CDC_VA_TX3_TX_PATH_SEC0	(VA_START_OFFSET + 0x0590)
+#define LPASS_CDC_VA_TX3_TX_PATH_SEC1	(VA_START_OFFSET + 0x0594)
+#define LPASS_CDC_VA_TX3_TX_PATH_SEC2	(VA_START_OFFSET + 0x0598)
+#define LPASS_CDC_VA_TX3_TX_PATH_SEC3	(VA_START_OFFSET + 0x059C)
+#define LPASS_CDC_VA_TX3_TX_PATH_SEC4	(VA_START_OFFSET + 0x05A0)
+#define LPASS_CDC_VA_TX3_TX_PATH_SEC5	(VA_START_OFFSET + 0x05A4)
+#define LPASS_CDC_VA_TX3_TX_PATH_SEC6	(VA_START_OFFSET + 0x05A8)
+#define LPASS_CDC_VA_TX4_TX_PATH_CTL	(VA_START_OFFSET + 0x0600)
+#define LPASS_CDC_VA_TX4_TX_PATH_CFG0	(VA_START_OFFSET + 0x0604)
+#define LPASS_CDC_VA_TX4_TX_PATH_CFG1	(VA_START_OFFSET + 0x0608)
+#define LPASS_CDC_VA_TX4_TX_VOL_CTL	(VA_START_OFFSET + 0x060C)
+#define LPASS_CDC_VA_TX4_TX_PATH_SEC0	(VA_START_OFFSET + 0x0610)
+#define LPASS_CDC_VA_TX4_TX_PATH_SEC1	(VA_START_OFFSET + 0x0614)
+#define LPASS_CDC_VA_TX4_TX_PATH_SEC2	(VA_START_OFFSET + 0x0618)
+#define LPASS_CDC_VA_TX4_TX_PATH_SEC3	(VA_START_OFFSET + 0x061C)
+#define LPASS_CDC_VA_TX4_TX_PATH_SEC4	(VA_START_OFFSET + 0x0620)
+#define LPASS_CDC_VA_TX4_TX_PATH_SEC5	(VA_START_OFFSET + 0x0624)
+#define LPASS_CDC_VA_TX4_TX_PATH_SEC6	(VA_START_OFFSET + 0x0628)
+#define LPASS_CDC_VA_TX5_TX_PATH_CTL	(VA_START_OFFSET + 0x0680)
+#define LPASS_CDC_VA_TX5_TX_PATH_CFG0	(VA_START_OFFSET + 0x0684)
+#define LPASS_CDC_VA_TX5_TX_PATH_CFG1	(VA_START_OFFSET + 0x0688)
+#define LPASS_CDC_VA_TX5_TX_VOL_CTL	(VA_START_OFFSET + 0x068C)
+#define LPASS_CDC_VA_TX5_TX_PATH_SEC0	(VA_START_OFFSET + 0x0690)
+#define LPASS_CDC_VA_TX5_TX_PATH_SEC1	(VA_START_OFFSET + 0x0694)
+#define LPASS_CDC_VA_TX5_TX_PATH_SEC2	(VA_START_OFFSET + 0x0698)
+#define LPASS_CDC_VA_TX5_TX_PATH_SEC3	(VA_START_OFFSET + 0x069C)
+#define LPASS_CDC_VA_TX5_TX_PATH_SEC4	(VA_START_OFFSET + 0x06A0)
+#define LPASS_CDC_VA_TX5_TX_PATH_SEC5	(VA_START_OFFSET + 0x06A4)
+#define LPASS_CDC_VA_TX5_TX_PATH_SEC6	(VA_START_OFFSET + 0x06A8)
+#define LPASS_CDC_VA_TX6_TX_PATH_CTL	(VA_START_OFFSET + 0x0700)
+#define LPASS_CDC_VA_TX6_TX_PATH_CFG0	(VA_START_OFFSET + 0x0704)
+#define LPASS_CDC_VA_TX6_TX_PATH_CFG1	(VA_START_OFFSET + 0x0708)
+#define LPASS_CDC_VA_TX6_TX_VOL_CTL	(VA_START_OFFSET + 0x070C)
+#define LPASS_CDC_VA_TX6_TX_PATH_SEC0	(VA_START_OFFSET + 0x0710)
+#define LPASS_CDC_VA_TX6_TX_PATH_SEC1	(VA_START_OFFSET + 0x0714)
+#define LPASS_CDC_VA_TX6_TX_PATH_SEC2	(VA_START_OFFSET + 0x0718)
+#define LPASS_CDC_VA_TX6_TX_PATH_SEC3	(VA_START_OFFSET + 0x071C)
+#define LPASS_CDC_VA_TX6_TX_PATH_SEC4	(VA_START_OFFSET + 0x0720)
+#define LPASS_CDC_VA_TX6_TX_PATH_SEC5	(VA_START_OFFSET + 0x0724)
+#define LPASS_CDC_VA_TX6_TX_PATH_SEC6	(VA_START_OFFSET + 0x0728)
+#define LPASS_CDC_VA_TX7_TX_PATH_CTL	(VA_START_OFFSET + 0x0780)
+#define LPASS_CDC_VA_TX7_TX_PATH_CFG0	(VA_START_OFFSET + 0x0784)
+#define LPASS_CDC_VA_TX7_TX_PATH_CFG1	(VA_START_OFFSET + 0x0788)
+#define LPASS_CDC_VA_TX7_TX_VOL_CTL	(VA_START_OFFSET + 0x078C)
+#define LPASS_CDC_VA_TX7_TX_PATH_SEC0	(VA_START_OFFSET + 0x0790)
+#define LPASS_CDC_VA_TX7_TX_PATH_SEC1	(VA_START_OFFSET + 0x0794)
+#define LPASS_CDC_VA_TX7_TX_PATH_SEC2	(VA_START_OFFSET + 0x0798)
+#define LPASS_CDC_VA_TX7_TX_PATH_SEC3	(VA_START_OFFSET + 0x079C)
+#define LPASS_CDC_VA_TX7_TX_PATH_SEC4	(VA_START_OFFSET + 0x07A0)
+#define LPASS_CDC_VA_TX7_TX_PATH_SEC5	(VA_START_OFFSET + 0x07A4)
+#define LPASS_CDC_VA_TX7_TX_PATH_SEC6	(VA_START_OFFSET + 0x07A8)
+#define VA_MAX_OFFSET			(VA_START_OFFSET + 0x07A8)
+
+#define LPASS_CDC_VA_MACRO_MAX 0x1EB /* 7A8/4 = 1EA + 1 = 1EB */
+
+#define LPASS_CDC_MAX_REGISTER VA_MAX_OFFSET
+
+#define LPASS_CDC_REG(reg)  (((reg) & 0x0FFF)/4)
+
+#endif

+ 873 - 0
asoc/codecs/lpass-cdc/lpass-cdc-regmap.c

@@ -0,0 +1,873 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/regmap.h>
+#include "lpass-cdc.h"
+#include "internal.h"
+
+static const struct reg_default lpass_cdc_defaults[] = {
+	/* TX Macro */
+	{ LPASS_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, 0x00 },
+	{ LPASS_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 },
+	{ LPASS_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_TOP_CFG0, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_ANC_CFG, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_SWR_CTRL, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_FREQ_MCLK, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_DEBUG_BUS, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_DEBUG_EN, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_TX_I2S_CTL, 0x0C},
+	{ LPASS_CDC_TX_TOP_CSR_I2S_CLK, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_I2S_RESET, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_SWR_DMIC0_CTL, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_SWR_DMIC1_CTL, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_SWR_DMIC2_CTL, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_SWR_DMIC3_CTL, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_SWR_AMIC0_CTL, 0x00},
+	{ LPASS_CDC_TX_TOP_CSR_SWR_AMIC1_CTL, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX4_CFG1, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX5_CFG1, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX6_CFG1, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0x00},
+	{ LPASS_CDC_TX_INP_MUX_ADC_MUX7_CFG1, 0x00},
+	{ LPASS_CDC_TX_ANC0_CLK_RESET_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_MODE_1_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_MODE_2_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_FF_SHIFT, 0x00},
+	{ LPASS_CDC_TX_ANC0_FB_SHIFT, 0x00},
+	{ LPASS_CDC_TX_ANC0_LPF_FF_A_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_LPF_FF_B_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_LPF_FB_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_SMLPF_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_DCFLT_SHIFT_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_IIR_ADAPT_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_IIR_COEFF_1_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_IIR_COEFF_2_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_FF_A_GAIN_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_FF_B_GAIN_CTL, 0x00},
+	{ LPASS_CDC_TX_ANC0_FB_GAIN_CTL, 0x00},
+	{ LPASS_CDC_TX0_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_TX0_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_TX0_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_TX0_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_TX0_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_TX0_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_TX0_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_TX0_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_TX0_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_TX0_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_TX0_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_TX0_TX_PATH_SEC7, 0x25},
+	{ LPASS_CDC_TX1_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_TX1_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_TX1_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_TX1_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_TX1_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_TX1_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_TX1_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_TX1_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_TX1_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_TX1_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_TX1_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_TX2_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_TX2_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_TX2_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_TX2_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_TX2_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_TX2_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_TX2_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_TX2_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_TX2_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_TX2_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_TX2_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_TX3_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_TX3_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_TX3_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_TX3_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_TX3_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_TX3_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_TX3_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_TX3_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_TX3_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_TX3_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_TX3_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_TX4_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_TX4_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_TX4_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_TX4_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_TX4_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_TX4_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_TX4_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_TX4_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_TX4_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_TX4_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_TX4_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_TX5_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_TX5_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_TX5_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_TX5_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_TX5_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_TX5_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_TX5_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_TX5_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_TX5_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_TX5_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_TX5_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_TX6_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_TX6_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_TX6_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_TX6_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_TX6_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_TX6_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_TX6_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_TX6_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_TX6_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_TX6_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_TX6_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_TX7_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_TX7_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_TX7_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_TX7_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_TX7_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_TX7_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_TX7_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_TX7_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_TX7_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_TX7_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_TX7_TX_PATH_SEC6, 0x00},
+
+	/* RX Macro */
+	{ LPASS_CDC_RX_TOP_TOP_CFG0, 0x00},
+	{ LPASS_CDC_RX_TOP_SWR_CTRL, 0x00},
+	{ LPASS_CDC_RX_TOP_DEBUG, 0x00},
+	{ LPASS_CDC_RX_TOP_DEBUG_BUS, 0x00},
+	{ LPASS_CDC_RX_TOP_DEBUG_EN0, 0x00},
+	{ LPASS_CDC_RX_TOP_DEBUG_EN1, 0x00},
+	{ LPASS_CDC_RX_TOP_DEBUG_EN2, 0x00},
+	{ LPASS_CDC_RX_TOP_HPHL_COMP_WR_LSB, 0x00},
+	{ LPASS_CDC_RX_TOP_HPHL_COMP_WR_MSB, 0x00},
+	{ LPASS_CDC_RX_TOP_HPHL_COMP_LUT, 0x00},
+	{ LPASS_CDC_RX_TOP_HPHL_COMP_RD_LSB, 0x00},
+	{ LPASS_CDC_RX_TOP_HPHL_COMP_RD_MSB, 0x00},
+	{ LPASS_CDC_RX_TOP_HPHR_COMP_WR_LSB, 0x00},
+	{ LPASS_CDC_RX_TOP_HPHR_COMP_WR_MSB, 0x00},
+	{ LPASS_CDC_RX_TOP_HPHR_COMP_LUT, 0x00},
+	{ LPASS_CDC_RX_TOP_HPHR_COMP_RD_LSB, 0x00},
+	{ LPASS_CDC_RX_TOP_HPHR_COMP_RD_MSB, 0x00},
+	{ LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG0, 0x11},
+	{ LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG1, 0x20},
+	{ LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG2, 0x00},
+	{ LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG3, 0x00},
+	{ LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG0, 0x11},
+	{ LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG1, 0x20},
+	{ LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG2, 0x00},
+	{ LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG3, 0x00},
+	{ LPASS_CDC_RX_TOP_RX_I2S_CTL, 0x0C},
+	{ LPASS_CDC_RX_TOP_TX_I2S2_CTL, 0x0C},
+	{ LPASS_CDC_RX_TOP_I2S_CLK, 0x0C},
+	{ LPASS_CDC_RX_TOP_I2S_RESET, 0x00},
+	{ LPASS_CDC_RX_TOP_I2S_MUX, 0x00},
+	{ LPASS_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x00},
+	{ LPASS_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},
+	{ LPASS_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, 0x00},
+	{ LPASS_CDC_RX_CLK_RST_CTRL_DSD_CONTROL, 0x00},
+	{ LPASS_CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x08},
+	{ LPASS_CDC_RX_SOFTCLIP_CRC, 0x00},
+	{ LPASS_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x38},
+	{ LPASS_CDC_RX_INP_MUX_RX_INT0_CFG0, 0x00},
+	{ LPASS_CDC_RX_INP_MUX_RX_INT0_CFG1, 0x00},
+	{ LPASS_CDC_RX_INP_MUX_RX_INT1_CFG0, 0x00},
+	{ LPASS_CDC_RX_INP_MUX_RX_INT1_CFG1, 0x00},
+	{ LPASS_CDC_RX_INP_MUX_RX_INT2_CFG0, 0x00},
+	{ LPASS_CDC_RX_INP_MUX_RX_INT2_CFG1, 0x00},
+	{ LPASS_CDC_RX_INP_MUX_RX_MIX_CFG4, 0x00},
+	{ LPASS_CDC_RX_INP_MUX_RX_MIX_CFG5, 0x00},
+	{ LPASS_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00},
+	{ LPASS_CDC_RX_CLSH_CRC, 0x00},
+	{ LPASS_CDC_RX_CLSH_DLY_CTRL, 0x03},
+	{ LPASS_CDC_RX_CLSH_DECAY_CTRL, 0x02},
+	{ LPASS_CDC_RX_CLSH_HPH_V_PA, 0x1C},
+	{ LPASS_CDC_RX_CLSH_EAR_V_PA, 0x39},
+	{ LPASS_CDC_RX_CLSH_HPH_V_HD, 0x0C},
+	{ LPASS_CDC_RX_CLSH_EAR_V_HD, 0x0C},
+	{ LPASS_CDC_RX_CLSH_K1_MSB, 0x01},
+	{ LPASS_CDC_RX_CLSH_K1_LSB, 0x00},
+	{ LPASS_CDC_RX_CLSH_K2_MSB, 0x00},
+	{ LPASS_CDC_RX_CLSH_K2_LSB, 0x80},
+	{ LPASS_CDC_RX_CLSH_IDLE_CTRL, 0x00},
+	{ LPASS_CDC_RX_CLSH_IDLE_HPH, 0x00},
+	{ LPASS_CDC_RX_CLSH_IDLE_EAR, 0x00},
+	{ LPASS_CDC_RX_CLSH_TEST0, 0x07},
+	{ LPASS_CDC_RX_CLSH_TEST1, 0x00},
+	{ LPASS_CDC_RX_CLSH_OVR_VREF, 0x00},
+	{ LPASS_CDC_RX_CLSH_CLSG_CTL, 0x02},
+	{ LPASS_CDC_RX_CLSH_CLSG_CFG1, 0x9A},
+	{ LPASS_CDC_RX_CLSH_CLSG_CFG2, 0x10},
+	{ LPASS_CDC_RX_BCL_VBAT_PATH_CTL, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_CFG, 0x10},
+	{ LPASS_CDC_RX_BCL_VBAT_ADC_CAL1, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_ADC_CAL2, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_ADC_CAL3, 0x04},
+	{ LPASS_CDC_RX_BCL_VBAT_PK_EST1, 0xE0},
+	{ LPASS_CDC_RX_BCL_VBAT_PK_EST2, 0x01},
+	{ LPASS_CDC_RX_BCL_VBAT_PK_EST3, 0x40},
+	{ LPASS_CDC_RX_BCL_VBAT_RF_PROC1, 0x2A},
+	{ LPASS_CDC_RX_BCL_VBAT_RF_PROC1, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_TAC1, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_TAC2, 0x18},
+	{ LPASS_CDC_RX_BCL_VBAT_TAC3, 0x18},
+	{ LPASS_CDC_RX_BCL_VBAT_TAC4, 0x03},
+	{ LPASS_CDC_RX_BCL_VBAT_GAIN_UPD1, 0x01},
+	{ LPASS_CDC_RX_BCL_VBAT_GAIN_UPD2, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_GAIN_UPD3, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_GAIN_UPD4, 0x64},
+	{ LPASS_CDC_RX_BCL_VBAT_GAIN_UPD5, 0x01},
+	{ LPASS_CDC_RX_BCL_VBAT_DEBUG1, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_GAIN_UPD_MON, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_GAIN_MON_VAL, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_BAN, 0x0C},
+	{ LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2, 0x77},
+	{ LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3, 0x01},
+	{ LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5, 0x4B},
+	{ LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7, 0x01},
+	{ LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_ATTN1, 0x04},
+	{ LPASS_CDC_RX_BCL_VBAT_ATTN2, 0x08},
+	{ LPASS_CDC_RX_BCL_VBAT_ATTN3, 0x0C},
+	{ LPASS_CDC_RX_BCL_VBAT_DECODE_CTL1, 0xE0},
+	{ LPASS_CDC_RX_BCL_VBAT_DECODE_CTL2, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_DECODE_CFG1, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_DECODE_CFG2, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_DECODE_CFG3, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_DECODE_CFG4, 0x00},
+	{ LPASS_CDC_RX_BCL_VBAT_DECODE_ST, 0x00},
+	{ LPASS_CDC_RX_INTR_CTRL_CFG, 0x00},
+	{ LPASS_CDC_RX_INTR_CTRL_CLR_COMMIT, 0x00},
+	{ LPASS_CDC_RX_INTR_CTRL_PIN1_MASK0, 0xFF},
+	{ LPASS_CDC_RX_INTR_CTRL_PIN1_STATUS0, 0x00},
+	{ LPASS_CDC_RX_INTR_CTRL_PIN1_CLEAR0, 0x00},
+	{ LPASS_CDC_RX_INTR_CTRL_PIN2_MASK0, 0xFF},
+	{ LPASS_CDC_RX_INTR_CTRL_PIN2_STATUS0, 0x00},
+	{ LPASS_CDC_RX_INTR_CTRL_PIN2_CLEAR0, 0x00},
+	{ LPASS_CDC_RX_INTR_CTRL_LEVEL0, 0x00},
+	{ LPASS_CDC_RX_INTR_CTRL_BYPASS0, 0x00},
+	{ LPASS_CDC_RX_INTR_CTRL_SET0, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_CTL, 0x04},
+	{ LPASS_CDC_RX_RX0_RX_PATH_CFG0, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_CFG1, 0x64},
+	{ LPASS_CDC_RX_RX0_RX_PATH_CFG2, 0x8F},
+	{ LPASS_CDC_RX_RX0_RX_PATH_CFG3, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_VOL_CTL, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_MIX_CTL, 0x04},
+	{ LPASS_CDC_RX_RX0_RX_PATH_MIX_CFG, 0x7E},
+	{ LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_SEC1, 0x08},
+	{ LPASS_CDC_RX_RX0_RX_PATH_SEC2, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_SEC3, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_SEC4, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_SEC7, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_MIX_SEC0, 0x08},
+	{ LPASS_CDC_RX_RX0_RX_PATH_MIX_SEC1, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_DSM_CTL, 0x08},
+	{ LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA1, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA2, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA3, 0x00},
+	{ LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA4, 0x55},
+	{ LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA5, 0x55},
+	{ LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA6, 0x55},
+	{ LPASS_CDC_RX_RX1_RX_PATH_CTL, 0x04},
+	{ LPASS_CDC_RX_RX1_RX_PATH_CFG0, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_PATH_CFG1, 0x64},
+	{ LPASS_CDC_RX_RX1_RX_PATH_CFG2, 0x8F},
+	{ LPASS_CDC_RX_RX1_RX_PATH_CFG3, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_VOL_CTL, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_PATH_MIX_CTL, 0x04},
+	{ LPASS_CDC_RX_RX1_RX_PATH_MIX_CFG, 0x7E},
+	{ LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_PATH_SEC1, 0x08},
+	{ LPASS_CDC_RX_RX1_RX_PATH_SEC2, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_PATH_SEC3, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_PATH_SEC4, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_PATH_SEC7, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_PATH_MIX_SEC0, 0x08},
+	{ LPASS_CDC_RX_RX1_RX_PATH_MIX_SEC1, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_PATH_DSM_CTL, 0x08},
+	{ LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA1, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA2, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA3, 0x00},
+	{ LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA4, 0x55},
+	{ LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA5, 0x55},
+	{ LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA6, 0x55},
+	{ LPASS_CDC_RX_RX2_RX_PATH_CTL, 0x04},
+	{ LPASS_CDC_RX_RX2_RX_PATH_CFG0, 0x00},
+	{ LPASS_CDC_RX_RX2_RX_PATH_CFG1, 0x64},
+	{ LPASS_CDC_RX_RX2_RX_PATH_CFG2, 0x8F},
+	{ LPASS_CDC_RX_RX2_RX_PATH_CFG3, 0x00},
+	{ LPASS_CDC_RX_RX2_RX_VOL_CTL, 0x00},
+	{ LPASS_CDC_RX_RX2_RX_PATH_MIX_CTL, 0x04},
+	{ LPASS_CDC_RX_RX2_RX_PATH_MIX_CFG, 0x7E},
+	{ LPASS_CDC_RX_RX2_RX_VOL_MIX_CTL, 0x00},
+	{ LPASS_CDC_RX_RX2_RX_PATH_SEC0, 0x04},
+	{ LPASS_CDC_RX_RX2_RX_PATH_SEC1, 0x08},
+	{ LPASS_CDC_RX_RX2_RX_PATH_SEC2, 0x00},
+	{ LPASS_CDC_RX_RX2_RX_PATH_SEC3, 0x00},
+	{ LPASS_CDC_RX_RX2_RX_PATH_SEC4, 0x00},
+	{ LPASS_CDC_RX_RX2_RX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_RX_RX2_RX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_RX_RX2_RX_PATH_SEC7, 0x00},
+	{ LPASS_CDC_RX_RX2_RX_PATH_MIX_SEC0, 0x08},
+	{ LPASS_CDC_RX_RX2_RX_PATH_MIX_SEC1, 0x00},
+	{ LPASS_CDC_RX_RX2_RX_PATH_DSM_CTL, 0x00},
+	{ LPASS_CDC_RX_IDLE_DETECT_PATH_CTL, 0x00},
+	{ LPASS_CDC_RX_IDLE_DETECT_CFG0, 0x07},
+	{ LPASS_CDC_RX_IDLE_DETECT_CFG1, 0x3C},
+	{ LPASS_CDC_RX_IDLE_DETECT_CFG2, 0x00},
+	{ LPASS_CDC_RX_IDLE_DETECT_CFG3, 0x00},
+	{ LPASS_CDC_RX_COMPANDER0_CTL0, 0x60},
+	{ LPASS_CDC_RX_COMPANDER0_CTL1, 0xDB},
+	{ LPASS_CDC_RX_COMPANDER0_CTL2, 0xFF},
+	{ LPASS_CDC_RX_COMPANDER0_CTL3, 0x35},
+	{ LPASS_CDC_RX_COMPANDER0_CTL4, 0xFF},
+	{ LPASS_CDC_RX_COMPANDER0_CTL5, 0x00},
+	{ LPASS_CDC_RX_COMPANDER0_CTL6, 0x01},
+	{ LPASS_CDC_RX_COMPANDER0_CTL7, 0x28},
+	{ LPASS_CDC_RX_COMPANDER1_CTL0, 0x60},
+	{ LPASS_CDC_RX_COMPANDER1_CTL1, 0xDB},
+	{ LPASS_CDC_RX_COMPANDER1_CTL2, 0xFF},
+	{ LPASS_CDC_RX_COMPANDER1_CTL3, 0x35},
+	{ LPASS_CDC_RX_COMPANDER1_CTL4, 0xFF},
+	{ LPASS_CDC_RX_COMPANDER1_CTL5, 0x00},
+	{ LPASS_CDC_RX_COMPANDER1_CTL6, 0x01},
+	{ LPASS_CDC_RX_COMPANDER1_CTL7, 0x28},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_CTL, 0x40},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_CTL, 0x40},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL, 0x00},
+	{ LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00},
+	{ LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0x00},
+	{ LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0x00},
+	{ LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0x00},
+	{ LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0x00},
+	{ LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0x00},
+	{ LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0x00},
+	{ LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04},
+	{ LPASS_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00},
+	{ LPASS_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, 0x04},
+	{ LPASS_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1, 0x00},
+	{ LPASS_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00},
+	{ LPASS_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01},
+	{ LPASS_CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00},
+	{ LPASS_CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01},
+	{ LPASS_CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL, 0x00},
+	{ LPASS_CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0, 0x01},
+	{ LPASS_CDC_RX_EC_ASRC0_CLK_RST_CTL, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC0_CTL0, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC0_CTL1, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC0_FIFO_CTL, 0xA8},
+	{ LPASS_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC0_STATUS_FIFO, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC1_CLK_RST_CTL, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC1_CTL0, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC1_CTL1, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC1_FIFO_CTL, 0xA8},
+	{ LPASS_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC1_STATUS_FIFO, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC2_CLK_RST_CTL, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC2_CTL0, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC2_CTL1, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC2_FIFO_CTL, 0xA8},
+	{ LPASS_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB, 0x00},
+	{ LPASS_CDC_RX_EC_ASRC2_STATUS_FIFO, 0x00},
+	{ LPASS_CDC_RX_DSD0_PATH_CTL, 0x00},
+	{ LPASS_CDC_RX_DSD0_CFG0, 0x00},
+	{ LPASS_CDC_RX_DSD0_CFG1, 0x62},
+	{ LPASS_CDC_RX_DSD0_CFG2, 0x96},
+	{ LPASS_CDC_RX_DSD1_PATH_CTL, 0x00},
+	{ LPASS_CDC_RX_DSD1_CFG0, 0x00},
+	{ LPASS_CDC_RX_DSD1_CFG1, 0x62},
+	{ LPASS_CDC_RX_DSD1_CFG2, 0x96},
+
+	/* WSA Macro */
+	{ LPASS_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL, 0x00},
+	{ LPASS_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},
+	{ LPASS_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x00},
+	{ LPASS_CDC_WSA_TOP_TOP_CFG0, 0x00},
+	{ LPASS_CDC_WSA_TOP_TOP_CFG1, 0x00},
+	{ LPASS_CDC_WSA_TOP_FREQ_MCLK, 0x00},
+	{ LPASS_CDC_WSA_TOP_DEBUG_BUS_SEL, 0x00},
+	{ LPASS_CDC_WSA_TOP_DEBUG_EN0, 0x00},
+	{ LPASS_CDC_WSA_TOP_DEBUG_EN1, 0x00},
+	{ LPASS_CDC_WSA_TOP_DEBUG_DSM_LB, 0x88},
+	{ LPASS_CDC_WSA_TOP_RX_I2S_CTL, 0x0C},
+	{ LPASS_CDC_WSA_TOP_TX_I2S_CTL, 0x0C},
+	{ LPASS_CDC_WSA_TOP_I2S_CLK, 0x02},
+	{ LPASS_CDC_WSA_TOP_I2S_RESET, 0x00},
+	{ LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0, 0x00},
+	{ LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1, 0x00},
+	{ LPASS_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0, 0x00},
+	{ LPASS_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1, 0x00},
+	{ LPASS_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, 0x00},
+	{ LPASS_CDC_WSA_RX_INP_MUX_RX_EC_CFG0, 0x00},
+	{ LPASS_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x10},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL1, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL2, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL3, 0x04},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_PK_EST1, 0xE0},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_PK_EST2, 0x01},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_PK_EST3, 0x40},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_RF_PROC1, 0x2A},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_RF_PROC2, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC1, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC2, 0x18},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC3, 0x18},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC4, 0x03},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD1, 0x01},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD2, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD3, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD4, 0x64},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD5, 0x01},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_DEBUG1, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD_MON, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BAN, 0x0C},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2, 0x77},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3, 0x01},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5, 0x4B},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7, 0x01},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN1, 0x04},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN2, 0x08},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN3, 0x0C},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0xE0},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL2, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0x00},
+	{ LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST, 0x00},
+	{ LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x02},
+	{ LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x00},
+	{ LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x02},
+	{ LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x00},
+	{ LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x02},
+	{ LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x00},
+	{ LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x02},
+	{ LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x00},
+	{ LPASS_CDC_WSA_INTR_CTRL_CFG, 0x00},
+	{ LPASS_CDC_WSA_INTR_CTRL_CLR_COMMIT, 0x00},
+	{ LPASS_CDC_WSA_INTR_CTRL_PIN1_MASK0, 0xFF},
+	{ LPASS_CDC_WSA_INTR_CTRL_PIN1_STATUS0, 0x00},
+	{ LPASS_CDC_WSA_INTR_CTRL_PIN1_CLEAR0, 0x00},
+	{ LPASS_CDC_WSA_INTR_CTRL_PIN2_MASK0, 0xFF},
+	{ LPASS_CDC_WSA_INTR_CTRL_PIN2_STATUS0, 0x00},
+	{ LPASS_CDC_WSA_INTR_CTRL_PIN2_CLEAR0, 0x00},
+	{ LPASS_CDC_WSA_INTR_CTRL_LEVEL0, 0x00},
+	{ LPASS_CDC_WSA_INTR_CTRL_BYPASS0, 0x00},
+	{ LPASS_CDC_WSA_INTR_CTRL_SET0, 0x00},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_CTL, 0x04},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_CFG0, 0x00},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_CFG1, 0x64},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_CFG2, 0x8F},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_CFG3, 0x00},
+	{ LPASS_CDC_WSA_RX0_RX_VOL_CTL, 0x00},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_MIX_CTL, 0x04},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x7E},
+	{ LPASS_CDC_WSA_RX0_RX_VOL_MIX_CTL, 0x00},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_SEC0, 0x04},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_SEC1, 0x08},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_SEC2, 0x00},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_SEC3, 0x00},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_SEC7, 0x00},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_MIX_SEC0, 0x08},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_MIX_SEC1, 0x00},
+	{ LPASS_CDC_WSA_RX0_RX_PATH_DSMDEM_CTL, 0x00},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_CFG0, 0x00},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_CFG1, 0x64},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_CFG2, 0x8F},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_CFG3, 0x00},
+	{ LPASS_CDC_WSA_RX1_RX_VOL_CTL, 0x00},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_MIX_CTL, 0x04},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x7E},
+	{ LPASS_CDC_WSA_RX1_RX_VOL_MIX_CTL, 0x00},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_SEC0, 0x04},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_SEC1, 0x08},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_SEC2, 0x00},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_SEC3, 0x00},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_SEC7, 0x00},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_MIX_SEC0, 0x08},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_MIX_SEC1, 0x00},
+	{ LPASS_CDC_WSA_RX1_RX_PATH_DSMDEM_CTL, 0x00},
+	{ LPASS_CDC_WSA_BOOST0_BOOST_PATH_CTL, 0x00},
+	{ LPASS_CDC_WSA_BOOST0_BOOST_CTL, 0xD0},
+	{ LPASS_CDC_WSA_BOOST0_BOOST_CFG1, 0x89},
+	{ LPASS_CDC_WSA_BOOST0_BOOST_CFG2, 0x04},
+	{ LPASS_CDC_WSA_BOOST1_BOOST_PATH_CTL, 0x00},
+	{ LPASS_CDC_WSA_BOOST1_BOOST_CTL, 0xD0},
+	{ LPASS_CDC_WSA_BOOST1_BOOST_CFG1, 0x89},
+	{ LPASS_CDC_WSA_BOOST1_BOOST_CFG2, 0x04},
+	{ LPASS_CDC_WSA_COMPANDER0_CTL0, 0x60},
+	{ LPASS_CDC_WSA_COMPANDER0_CTL1, 0xDB},
+	{ LPASS_CDC_WSA_COMPANDER0_CTL2, 0xFF},
+	{ LPASS_CDC_WSA_COMPANDER0_CTL3, 0x35},
+	{ LPASS_CDC_WSA_COMPANDER0_CTL4, 0xFF},
+	{ LPASS_CDC_WSA_COMPANDER0_CTL5, 0x00},
+	{ LPASS_CDC_WSA_COMPANDER0_CTL6, 0x01},
+	{ LPASS_CDC_WSA_COMPANDER0_CTL7, 0x28},
+	{ LPASS_CDC_WSA_COMPANDER1_CTL0, 0x60},
+	{ LPASS_CDC_WSA_COMPANDER1_CTL1, 0xDB},
+	{ LPASS_CDC_WSA_COMPANDER1_CTL2, 0xFF},
+	{ LPASS_CDC_WSA_COMPANDER1_CTL3, 0x35},
+	{ LPASS_CDC_WSA_COMPANDER1_CTL4, 0xFF},
+	{ LPASS_CDC_WSA_COMPANDER1_CTL5, 0x00},
+	{ LPASS_CDC_WSA_COMPANDER1_CTL6, 0x01},
+	{ LPASS_CDC_WSA_COMPANDER1_CTL7, 0x28},
+	{ LPASS_CDC_WSA_SOFTCLIP0_CRC, 0x00},
+	{ LPASS_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL, 0x38},
+	{ LPASS_CDC_WSA_SOFTCLIP1_CRC, 0x00},
+	{ LPASS_CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL, 0x38},
+	{ LPASS_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL, 0x00},
+	{ LPASS_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0, 0x01},
+	{ LPASS_CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL, 0x00},
+	{ LPASS_CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0, 0x01},
+	{ LPASS_CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC0_CTL0, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC0_CTL1, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC0_FIFO_CTL, 0xA8},
+	{ LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC1_CTL0, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC1_CTL1, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC1_FIFO_CTL, 0xA8},
+	{ LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00},
+	{ LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO, 0x00},
+
+	/* VA macro */
+	{ LPASS_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, 0x00},
+	{ LPASS_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},
+	{ LPASS_CDC_VA_CLK_RST_CTRL_SWR_CONTROL, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_TOP_CFG0, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_DMIC0_CTL, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_DMIC1_CTL, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_DMIC2_CTL, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_DMIC3_CTL, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_DMIC_CFG, 0x80},
+	{ LPASS_CDC_VA_TOP_CSR_DEBUG_BUS, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_DEBUG_EN, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_TX_I2S_CTL, 0x0C},
+	{ LPASS_CDC_VA_TOP_CSR_I2S_CLK, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_I2S_RESET, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_CORE_ID_0, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_CORE_ID_1, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_CORE_ID_2, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_CORE_ID_3, 0x00},
+	{ LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL0, 0xEE},
+	{ LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL1, 0xEE},
+	{ LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL2, 0xEE},
+	{ LPASS_CDC_VA_TOP_CSR_SWR_CTRL, 0x06},
+
+	/* VA core */
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG0, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG1, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG0, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG1, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG0, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG1, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG0, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG1, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX4_CFG0, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX4_CFG1, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX5_CFG0, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX5_CFG1, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX6_CFG0, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX6_CFG1, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX7_CFG0, 0x00},
+	{ LPASS_CDC_VA_INP_MUX_ADC_MUX7_CFG1, 0x00},
+	{ LPASS_CDC_VA_TX0_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_VA_TX0_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_VA_TX0_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_VA_TX0_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_VA_TX0_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_VA_TX0_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_VA_TX0_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_VA_TX0_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_VA_TX0_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_VA_TX0_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_VA_TX0_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_VA_TX0_TX_PATH_SEC7, 0x25},
+	{ LPASS_CDC_VA_TX1_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_VA_TX1_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_VA_TX1_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_VA_TX1_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_VA_TX1_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_VA_TX1_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_VA_TX1_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_VA_TX1_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_VA_TX1_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_VA_TX1_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_VA_TX1_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_VA_TX2_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_VA_TX2_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_VA_TX2_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_VA_TX2_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_VA_TX2_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_VA_TX2_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_VA_TX2_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_VA_TX2_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_VA_TX2_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_VA_TX2_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_VA_TX2_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_VA_TX3_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_VA_TX3_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_VA_TX3_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_VA_TX3_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_VA_TX3_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_VA_TX3_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_VA_TX3_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_VA_TX3_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_VA_TX3_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_VA_TX3_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_VA_TX3_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_VA_TX4_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_VA_TX4_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_VA_TX4_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_VA_TX4_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_VA_TX4_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_VA_TX4_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_VA_TX4_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_VA_TX4_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_VA_TX4_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_VA_TX4_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_VA_TX4_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_VA_TX5_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_VA_TX5_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_VA_TX5_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_VA_TX5_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_VA_TX5_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_VA_TX5_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_VA_TX5_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_VA_TX5_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_VA_TX5_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_VA_TX5_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_VA_TX5_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_VA_TX6_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_VA_TX6_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_VA_TX6_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_VA_TX6_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_VA_TX6_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_VA_TX6_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_VA_TX6_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_VA_TX6_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_VA_TX6_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_VA_TX6_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_VA_TX6_TX_PATH_SEC6, 0x00},
+	{ LPASS_CDC_VA_TX7_TX_PATH_CTL, 0x04},
+	{ LPASS_CDC_VA_TX7_TX_PATH_CFG0, 0x10},
+	{ LPASS_CDC_VA_TX7_TX_PATH_CFG1, 0x0B},
+	{ LPASS_CDC_VA_TX7_TX_VOL_CTL, 0x00},
+	{ LPASS_CDC_VA_TX7_TX_PATH_SEC0, 0x00},
+	{ LPASS_CDC_VA_TX7_TX_PATH_SEC1, 0x00},
+	{ LPASS_CDC_VA_TX7_TX_PATH_SEC2, 0x01},
+	{ LPASS_CDC_VA_TX7_TX_PATH_SEC3, 0x3C},
+	{ LPASS_CDC_VA_TX7_TX_PATH_SEC4, 0x20},
+	{ LPASS_CDC_VA_TX7_TX_PATH_SEC5, 0x00},
+	{ LPASS_CDC_VA_TX7_TX_PATH_SEC6, 0x00},
+};
+
+static bool lpass_cdc_is_readable_register(struct device *dev,
+					unsigned int reg)
+{
+	struct lpass_cdc_priv *priv = dev_get_drvdata(dev);
+	u16 reg_offset;
+	int macro_id;
+	u8 *reg_tbl = NULL;
+
+	if (!priv)
+		return false;
+
+	macro_id = lpass_cdc_get_macro_id(priv->va_without_decimation,
+				       reg);
+	if (macro_id < 0 || !priv->macros_supported[macro_id])
+		return false;
+
+	reg_tbl = lpass_cdc_reg_access[macro_id];
+	reg_offset = (reg - macro_id_base_offset[macro_id])/4;
+
+	if (reg_tbl)
+		return (reg_tbl[reg_offset] & RD_REG);
+
+	return false;
+}
+
+static bool lpass_cdc_is_writeable_register(struct device *dev,
+					 unsigned int reg)
+{
+	struct lpass_cdc_priv *priv = dev_get_drvdata(dev);
+	u16 reg_offset;
+	int macro_id;
+	const u8 *reg_tbl = NULL;
+
+	if (!priv)
+		return false;
+
+	macro_id = lpass_cdc_get_macro_id(priv->va_without_decimation,
+				       reg);
+	if (macro_id < 0 || !priv->macros_supported[macro_id])
+		return false;
+
+	reg_tbl = lpass_cdc_reg_access[macro_id];
+	reg_offset = (reg - macro_id_base_offset[macro_id])/4;
+
+	if (reg_tbl)
+		return (reg_tbl[reg_offset] & WR_REG);
+
+	return false;
+}
+
+static bool lpass_cdc_is_volatile_register(struct device *dev,
+					unsigned int reg)
+{
+	/* Update volatile list for rx/tx macros */
+	switch (reg) {
+	case LPASS_CDC_VA_TOP_CSR_CORE_ID_0:
+	case LPASS_CDC_VA_TOP_CSR_CORE_ID_1:
+	case LPASS_CDC_VA_TOP_CSR_CORE_ID_2:
+	case LPASS_CDC_VA_TOP_CSR_CORE_ID_3:
+	case LPASS_CDC_VA_TOP_CSR_DMIC0_CTL:
+	case LPASS_CDC_VA_TOP_CSR_DMIC1_CTL:
+	case LPASS_CDC_VA_TOP_CSR_DMIC2_CTL:
+	case LPASS_CDC_VA_TOP_CSR_DMIC3_CTL:
+	case LPASS_CDC_TX_TOP_CSR_SWR_DMIC0_CTL:
+	case LPASS_CDC_TX_TOP_CSR_SWR_DMIC1_CTL:
+	case LPASS_CDC_TX_TOP_CSR_SWR_DMIC2_CTL:
+	case LPASS_CDC_TX_TOP_CSR_SWR_DMIC3_CTL:
+	case LPASS_CDC_TX_TOP_CSR_SWR_MIC0_CTL:
+	case LPASS_CDC_TX_TOP_CSR_SWR_MIC1_CTL:
+	case LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL:
+	case LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST:
+	case LPASS_CDC_WSA_INTR_CTRL_PIN1_STATUS0:
+	case LPASS_CDC_WSA_INTR_CTRL_PIN2_STATUS0:
+	case LPASS_CDC_WSA_COMPANDER0_CTL6:
+	case LPASS_CDC_WSA_COMPANDER1_CTL6:
+	case LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB:
+	case LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB:
+	case LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB:
+	case LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB:
+	case LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO:
+	case LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB:
+	case LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB:
+	case LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB:
+	case LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB:
+	case LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO:
+	case LPASS_CDC_RX_TOP_HPHL_COMP_RD_LSB:
+	case LPASS_CDC_RX_TOP_HPHL_COMP_WR_LSB:
+	case LPASS_CDC_RX_TOP_HPHL_COMP_RD_MSB:
+	case LPASS_CDC_RX_TOP_HPHL_COMP_WR_MSB:
+	case LPASS_CDC_RX_TOP_HPHR_COMP_RD_LSB:
+	case LPASS_CDC_RX_TOP_HPHR_COMP_WR_LSB:
+	case LPASS_CDC_RX_TOP_HPHR_COMP_RD_MSB:
+	case LPASS_CDC_RX_TOP_HPHR_COMP_WR_MSB:
+	case LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG2:
+	case LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG2:
+	case LPASS_CDC_RX_BCL_VBAT_GAIN_MON_VAL:
+	case LPASS_CDC_RX_BCL_VBAT_DECODE_ST:
+	case LPASS_CDC_RX_INTR_CTRL_PIN1_STATUS0:
+	case LPASS_CDC_RX_INTR_CTRL_PIN2_STATUS0:
+	case LPASS_CDC_RX_COMPANDER0_CTL6:
+	case LPASS_CDC_RX_COMPANDER1_CTL6:
+	case LPASS_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB:
+	case LPASS_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB:
+	case LPASS_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB:
+	case LPASS_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB:
+	case LPASS_CDC_RX_EC_ASRC0_STATUS_FIFO:
+	case LPASS_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB:
+	case LPASS_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB:
+	case LPASS_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB:
+	case LPASS_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB:
+	case LPASS_CDC_RX_EC_ASRC1_STATUS_FIFO:
+	case LPASS_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB:
+	case LPASS_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB:
+	case LPASS_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB:
+	case LPASS_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB:
+	case LPASS_CDC_RX_EC_ASRC2_STATUS_FIFO:
+		return true;
+	}
+	return false;
+}
+
+const struct regmap_config lpass_cdc_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 8,
+	.reg_stride = 4,
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = lpass_cdc_defaults,
+	.num_reg_defaults = ARRAY_SIZE(lpass_cdc_defaults),
+	.max_register = LPASS_CDC_MAX_REGISTER,
+	.writeable_reg = lpass_cdc_is_writeable_register,
+	.volatile_reg = lpass_cdc_is_volatile_register,
+	.readable_reg = lpass_cdc_is_readable_register,
+};

+ 4302 - 0
asoc/codecs/lpass-cdc/lpass-cdc-rx-macro.c

@@ -0,0 +1,4302 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+#include <sound/soc.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <soc/swr-common.h>
+#include <soc/swr-wcd.h>
+
+#include <asoc/msm-cdc-pinctrl.h>
+#include "lpass-cdc.h"
+#include "lpass-cdc-registers.h"
+#include "lpass-cdc-clk-rsc.h"
+
+#define AUTO_SUSPEND_DELAY  50 /* delay in msec */
+#define LPASS_CDC_RX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
+			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
+			SNDRV_PCM_RATE_384000)
+/* Fractional Rates */
+#define LPASS_CDC_RX_MACRO_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
+				SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)
+
+#define LPASS_CDC_RX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+		SNDRV_PCM_FMTBIT_S24_LE |\
+		SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+#define LPASS_CDC_RX_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+			SNDRV_PCM_RATE_48000)
+#define LPASS_CDC_RX_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+		SNDRV_PCM_FMTBIT_S24_LE |\
+		SNDRV_PCM_FMTBIT_S24_3LE)
+
+#define SAMPLING_RATE_44P1KHZ   44100
+#define SAMPLING_RATE_88P2KHZ   88200
+#define SAMPLING_RATE_176P4KHZ  176400
+#define SAMPLING_RATE_352P8KHZ  352800
+
+#define LPASS_CDC_RX_MACRO_MAX_OFFSET 0x1000
+
+#define LPASS_CDC_RX_MACRO_MAX_DMA_CH_PER_PORT 2
+#define RX_SWR_STRING_LEN 80
+#define LPASS_CDC_RX_MACRO_CHILD_DEVICES_MAX 3
+
+#define LPASS_CDC_RX_MACRO_INTERP_MUX_NUM_INPUTS 3
+#define LPASS_CDC_RX_MACRO_SIDETONE_IIR_COEFF_MAX 5
+
+#define STRING(name) #name
+#define LPASS_CDC_RX_MACRO_DAPM_ENUM(name, reg, offset, text) \
+static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
+static const struct snd_kcontrol_new name##_mux = \
+		SOC_DAPM_ENUM(STRING(name), name##_enum)
+
+#define LPASS_CDC_RX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
+static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
+static const struct snd_kcontrol_new name##_mux = \
+		SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
+
+#define LPASS_CDC_RX_MACRO_DAPM_MUX(name, shift, kctl) \
+		SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
+
+#define LPASS_CDC_RX_MACRO_RX_PATH_OFFSET 0x80
+#define LPASS_CDC_RX_MACRO_COMP_OFFSET 0x40
+
+#define MAX_IMPED_PARAMS 6
+
+#define LPASS_CDC_RX_MACRO_EC_MIX_TX0_MASK 0xf0
+#define LPASS_CDC_RX_MACRO_EC_MIX_TX1_MASK 0x0f
+#define LPASS_CDC_RX_MACRO_EC_MIX_TX2_MASK 0x0f
+
+#define LPASS_CDC_RX_MACRO_GAIN_MAX_VAL 0x28
+#define LPASS_CDC_RX_MACRO_GAIN_VAL_UNITY 0x0
+/* Define macros to increase PA Gain by half */
+#define LPASS_CDC_RX_MACRO_MOD_GAIN (LPASS_CDC_RX_MACRO_GAIN_VAL_UNITY + 6)
+
+#define COMP_MAX_COEFF 25
+
+struct wcd_imped_val {
+	u32 imped_val;
+	u8 index;
+};
+
+static const struct wcd_imped_val imped_index[] = {
+	{4, 0},
+	{5, 1},
+	{6, 2},
+	{7, 3},
+	{8, 4},
+	{9, 5},
+	{10, 6},
+	{11, 7},
+	{12, 8},
+	{13, 9},
+};
+
+struct comp_coeff_val {
+	u8 lsb;
+	u8 msb;
+};
+
+enum {
+	HPH_ULP,
+	HPH_LOHIFI,
+	HPH_MODE_MAX,
+};
+
+static const struct comp_coeff_val
+			comp_coeff_table [HPH_MODE_MAX][COMP_MAX_COEFF] = {
+	{
+		{0x40, 0x00},
+		{0x4C, 0x00},
+		{0x5A, 0x00},
+		{0x6B, 0x00},
+		{0x7F, 0x00},
+		{0x97, 0x00},
+		{0xB3, 0x00},
+		{0xD5, 0x00},
+		{0xFD, 0x00},
+		{0x2D, 0x01},
+		{0x66, 0x01},
+		{0xA7, 0x01},
+		{0xF8, 0x01},
+		{0x57, 0x02},
+		{0xC7, 0x02},
+		{0x4B, 0x03},
+		{0xE9, 0x03},
+		{0xA3, 0x04},
+		{0x7D, 0x05},
+		{0x90, 0x06},
+		{0xD1, 0x07},
+		{0x49, 0x09},
+		{0x00, 0x0B},
+		{0x01, 0x0D},
+		{0x59, 0x0F},
+	},
+	{
+		{0x40, 0x00},
+		{0x4C, 0x00},
+		{0x5A, 0x00},
+		{0x6B, 0x00},
+		{0x80, 0x00},
+		{0x98, 0x00},
+		{0xB4, 0x00},
+		{0xD5, 0x00},
+		{0xFE, 0x00},
+		{0x2E, 0x01},
+		{0x66, 0x01},
+		{0xA9, 0x01},
+		{0xF8, 0x01},
+		{0x56, 0x02},
+		{0xC4, 0x02},
+		{0x4F, 0x03},
+		{0xF0, 0x03},
+		{0xAE, 0x04},
+		{0x8B, 0x05},
+		{0x8E, 0x06},
+		{0xBC, 0x07},
+		{0x56, 0x09},
+		{0x0F, 0x0B},
+		{0x13, 0x0D},
+		{0x6F, 0x0F},
+	},
+};
+
+struct lpass_cdc_rx_macro_reg_mask_val {
+	u16 reg;
+	u8 mask;
+	u8 val;
+};
+
+static const struct lpass_cdc_rx_macro_reg_mask_val imped_table[][MAX_IMPED_PARAMS] = {
+	{
+		{LPASS_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf2},
+		{LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf2},
+		{LPASS_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+		{LPASS_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf2},
+		{LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf2},
+		{LPASS_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+	},
+	{
+		{LPASS_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf4},
+		{LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf4},
+		{LPASS_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+		{LPASS_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf4},
+		{LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf4},
+		{LPASS_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+	},
+	{
+		{LPASS_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf7},
+		{LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf7},
+		{LPASS_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
+		{LPASS_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf7},
+		{LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7},
+		{LPASS_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
+	},
+	{
+		{LPASS_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf9},
+		{LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf9},
+		{LPASS_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+		{LPASS_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf9},
+		{LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9},
+		{LPASS_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+	},
+	{
+		{LPASS_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfa},
+		{LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfa},
+		{LPASS_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+		{LPASS_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfa},
+		{LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa},
+		{LPASS_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+	},
+	{
+		{LPASS_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfb},
+		{LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfb},
+		{LPASS_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+		{LPASS_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfb},
+		{LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb},
+		{LPASS_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+	},
+	{
+		{LPASS_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfc},
+		{LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfc},
+		{LPASS_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+		{LPASS_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfc},
+		{LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc},
+		{LPASS_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+	},
+	{
+		{LPASS_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
+		{LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
+		{LPASS_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
+		{LPASS_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
+		{LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
+		{LPASS_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
+	},
+	{
+		{LPASS_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
+		{LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
+		{LPASS_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
+		{LPASS_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
+		{LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
+		{LPASS_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
+	},
+};
+
+enum {
+	INTERP_HPHL,
+	INTERP_HPHR,
+	INTERP_AUX,
+	INTERP_MAX
+};
+
+enum {
+	LPASS_CDC_RX_MACRO_RX0,
+	LPASS_CDC_RX_MACRO_RX1,
+	LPASS_CDC_RX_MACRO_RX2,
+	LPASS_CDC_RX_MACRO_RX3,
+	LPASS_CDC_RX_MACRO_RX4,
+	LPASS_CDC_RX_MACRO_RX5,
+	LPASS_CDC_RX_MACRO_PORTS_MAX
+};
+
+enum {
+	LPASS_CDC_RX_MACRO_COMP1, /* HPH_L */
+	LPASS_CDC_RX_MACRO_COMP2, /* HPH_R */
+	LPASS_CDC_RX_MACRO_COMP_MAX
+};
+
+enum {
+	LPASS_CDC_RX_MACRO_EC0_MUX = 0,
+	LPASS_CDC_RX_MACRO_EC1_MUX,
+	LPASS_CDC_RX_MACRO_EC2_MUX,
+	LPASS_CDC_RX_MACRO_EC_MUX_MAX,
+};
+
+enum {
+	INTn_1_INP_SEL_ZERO = 0,
+	INTn_1_INP_SEL_DEC0,
+	INTn_1_INP_SEL_DEC1,
+	INTn_1_INP_SEL_IIR0,
+	INTn_1_INP_SEL_IIR1,
+	INTn_1_INP_SEL_RX0,
+	INTn_1_INP_SEL_RX1,
+	INTn_1_INP_SEL_RX2,
+	INTn_1_INP_SEL_RX3,
+	INTn_1_INP_SEL_RX4,
+	INTn_1_INP_SEL_RX5,
+};
+
+enum {
+	INTn_2_INP_SEL_ZERO = 0,
+	INTn_2_INP_SEL_RX0,
+	INTn_2_INP_SEL_RX1,
+	INTn_2_INP_SEL_RX2,
+	INTn_2_INP_SEL_RX3,
+	INTn_2_INP_SEL_RX4,
+	INTn_2_INP_SEL_RX5,
+};
+
+enum {
+	INTERP_MAIN_PATH,
+	INTERP_MIX_PATH,
+};
+
+/* Codec supports 2 IIR filters */
+enum {
+	IIR0 = 0,
+	IIR1,
+	IIR_MAX,
+};
+
+/* Each IIR has 5 Filter Stages */
+enum {
+	BAND1 = 0,
+	BAND2,
+	BAND3,
+	BAND4,
+	BAND5,
+	BAND_MAX,
+};
+
+struct lpass_cdc_rx_macro_idle_detect_config {
+	u8 hph_idle_thr;
+	u8 hph_idle_detect_en;
+};
+
+struct interp_sample_rate {
+	int sample_rate;
+	int rate_val;
+};
+
+static struct interp_sample_rate sr_val_tbl[] = {
+	{8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5},
+	{192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA},
+	{176400, 0xB}, {352800, 0xC},
+};
+
+struct lpass_cdc_rx_macro_bcl_pmic_params {
+	u8 id;
+	u8 sid;
+	u8 ppid;
+};
+
+static int lpass_cdc_rx_macro_hw_params(struct snd_pcm_substream *substream,
+			       struct snd_pcm_hw_params *params,
+			       struct snd_soc_dai *dai);
+static int lpass_cdc_rx_macro_get_channel_map(struct snd_soc_dai *dai,
+				unsigned int *tx_num, unsigned int *tx_slot,
+				unsigned int *rx_num, unsigned int *rx_slot);
+static int lpass_cdc_rx_macro_digital_mute(struct snd_soc_dai *dai, int mute);
+static int lpass_cdc_rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol);
+static int lpass_cdc_rx_macro_mux_get(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol);
+static int lpass_cdc_rx_macro_mux_put(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol);
+static int lpass_cdc_rx_macro_enable_interp_clk(struct snd_soc_component *component,
+				      int event, int interp_idx);
+
+/* Hold instance to soundwire platform device */
+struct rx_swr_ctrl_data {
+	struct platform_device *rx_swr_pdev;
+};
+
+struct rx_swr_ctrl_platform_data {
+	void *handle; /* holds codec private data */
+	int (*read)(void *handle, int reg);
+	int (*write)(void *handle, int reg, int val);
+	int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
+	int (*clk)(void *handle, bool enable);
+	int (*core_vote)(void *handle, bool enable);
+	int (*handle_irq)(void *handle,
+			  irqreturn_t (*swrm_irq_handler)(int irq,
+							  void *data),
+			  void *swrm_handle,
+			  int action);
+};
+
+enum {
+	RX_MACRO_AIF_INVALID = 0,
+	RX_MACRO_AIF1_PB,
+	RX_MACRO_AIF2_PB,
+	RX_MACRO_AIF3_PB,
+	RX_MACRO_AIF4_PB,
+	RX_MACRO_AIF_ECHO,
+	RX_MACRO_AIF5_PB,
+	RX_MACRO_AIF6_PB,
+	LPASS_CDC_RX_MACRO_MAX_DAIS,
+};
+
+enum {
+	RX_MACRO_AIF1_CAP = 0,
+	RX_MACRO_AIF2_CAP,
+	RX_MACRO_AIF3_CAP,
+	LPASS_CDC_RX_MACRO_MAX_AIF_CAP_DAIS
+};
+/*
+ * @dev: rx macro device pointer
+ * @comp_enabled: compander enable mixer value set
+ * @prim_int_users: Users of interpolator
+ * @rx_mclk_users: RX MCLK users count
+ * @vi_feed_value: VI sense mask
+ * @swr_clk_lock: to lock swr master clock operations
+ * @swr_ctrl_data: SoundWire data structure
+ * @swr_plat_data: Soundwire platform data
+ * @lpass_cdc_rx_macro_add_child_devices_work: work for adding child devices
+ * @rx_swr_gpio_p: used by pinctrl API
+ * @component: codec handle
+ */
+struct lpass_cdc_rx_macro_priv {
+	struct device *dev;
+	int comp_enabled[LPASS_CDC_RX_MACRO_COMP_MAX];
+	/* Main path clock users count */
+	int main_clk_users[INTERP_MAX];
+	int rx_port_value[LPASS_CDC_RX_MACRO_PORTS_MAX];
+	u16 prim_int_users[INTERP_MAX];
+	int rx_mclk_users;
+	int swr_clk_users;
+	bool dapm_mclk_enable;
+	bool reset_swr;
+	int clsh_users;
+	int rx_mclk_cnt;
+	bool is_native_on;
+	bool is_ear_mode_on;
+	bool dev_up;
+	bool hph_pwr_mode;
+	bool hph_hd2_mode;
+	struct mutex mclk_lock;
+	struct mutex swr_clk_lock;
+	struct rx_swr_ctrl_data *swr_ctrl_data;
+	struct rx_swr_ctrl_platform_data swr_plat_data;
+	struct work_struct lpass_cdc_rx_macro_add_child_devices_work;
+	struct device_node *rx_swr_gpio_p;
+	struct snd_soc_component *component;
+	unsigned long active_ch_mask[LPASS_CDC_RX_MACRO_MAX_DAIS];
+	unsigned long active_ch_cnt[LPASS_CDC_RX_MACRO_MAX_DAIS];
+	u16 bit_width[LPASS_CDC_RX_MACRO_MAX_DAIS];
+	char __iomem *rx_io_base;
+	char __iomem *rx_mclk_mode_muxsel;
+	struct lpass_cdc_rx_macro_idle_detect_config idle_det_cfg;
+	u8 sidetone_coeff_array[IIR_MAX][BAND_MAX]
+		[LPASS_CDC_RX_MACRO_SIDETONE_IIR_COEFF_MAX * 4];
+
+	struct platform_device *pdev_child_devices
+			[LPASS_CDC_RX_MACRO_CHILD_DEVICES_MAX];
+	int child_count;
+	int is_softclip_on;
+	int is_aux_hpf_on;
+	int softclip_clk_users;
+	struct lpass_cdc_rx_macro_bcl_pmic_params bcl_pmic_params;
+	u16 clk_id;
+	u16 default_clk_id;
+	int8_t rx0_gain_val;
+	int8_t rx1_gain_val;
+};
+
+static struct snd_soc_dai_driver lpass_cdc_rx_macro_dai[];
+static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
+
+static const char * const rx_int_mix_mux_text[] = {
+	"ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5"
+};
+
+static const char * const rx_prim_mix_text[] = {
+	"ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2",
+	"RX3", "RX4", "RX5"
+};
+
+static const char * const rx_sidetone_mix_text[] = {
+	"ZERO", "SRC0", "SRC1", "SRC_SUM"
+};
+
+static const char * const iir_inp_mux_text[] = {
+	"ZERO", "DEC0", "DEC1", "DEC2", "DEC3",
+	"RX0", "RX1", "RX2", "RX3", "RX4", "RX5"
+};
+
+static const char * const rx_int_dem_inp_mux_text[] = {
+	"NORMAL_DSM_OUT", "CLSH_DSM_OUT",
+};
+
+static const char * const rx_int0_1_interp_mux_text[] = {
+	"ZERO", "RX INT0_1 MIX1",
+};
+
+static const char * const rx_int1_1_interp_mux_text[] = {
+	"ZERO", "RX INT1_1 MIX1",
+};
+
+static const char * const rx_int2_1_interp_mux_text[] = {
+	"ZERO", "RX INT2_1 MIX1",
+};
+
+static const char * const rx_int0_2_interp_mux_text[] = {
+	"ZERO", "RX INT0_2 MUX",
+};
+
+static const char * const rx_int1_2_interp_mux_text[] = {
+	"ZERO", "RX INT1_2 MUX",
+};
+
+static const char * const rx_int2_2_interp_mux_text[] = {
+	"ZERO", "RX INT2_2 MUX",
+};
+
+static const char *const lpass_cdc_rx_macro_mux_text[] = {
+	"ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB"
+};
+
+static const char *const lpass_cdc_rx_macro_ear_mode_text[] = {"OFF", "ON"};
+static const struct soc_enum lpass_cdc_rx_macro_ear_mode_enum =
+	SOC_ENUM_SINGLE_EXT(2, lpass_cdc_rx_macro_ear_mode_text);
+
+static const char *const lpass_cdc_rx_macro_hph_hd2_mode_text[] = {"OFF", "ON"};
+static const struct soc_enum lpass_cdc_rx_macro_hph_hd2_mode_enum =
+	SOC_ENUM_SINGLE_EXT(2, lpass_cdc_rx_macro_hph_hd2_mode_text);
+
+static const char *const lpass_cdc_rx_macro_hph_pwr_mode_text[] = {"ULP", "LOHIFI"};
+static const struct soc_enum lpass_cdc_rx_macro_hph_pwr_mode_enum =
+	SOC_ENUM_SINGLE_EXT(2, lpass_cdc_rx_macro_hph_pwr_mode_text);
+
+static const char * const lpass_cdc_rx_macro_vbat_bcl_gsm_mode_text[] = {"OFF", "ON"};
+static const struct soc_enum lpass_cdc_rx_macro_vbat_bcl_gsm_mode_enum =
+	SOC_ENUM_SINGLE_EXT(2, lpass_cdc_rx_macro_vbat_bcl_gsm_mode_text);
+
+static const struct snd_kcontrol_new rx_int2_1_vbat_mix_switch[] = {
+	SOC_DAPM_SINGLE("RX AUX VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const char * const hph_idle_detect_text[] = {"OFF", "ON"};
+
+static SOC_ENUM_SINGLE_EXT_DECL(hph_idle_detect_enum, hph_idle_detect_text);
+
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int0_2, LPASS_CDC_RX_INP_MUX_RX_INT0_CFG1, 0,
+		rx_int_mix_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int1_2, LPASS_CDC_RX_INP_MUX_RX_INT1_CFG1, 0,
+		rx_int_mix_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int2_2, LPASS_CDC_RX_INP_MUX_RX_INT2_CFG1, 0,
+		rx_int_mix_mux_text);
+
+
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp0, LPASS_CDC_RX_INP_MUX_RX_INT0_CFG0, 0,
+		rx_prim_mix_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp1, LPASS_CDC_RX_INP_MUX_RX_INT0_CFG0, 4,
+		rx_prim_mix_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int0_1_mix_inp2, LPASS_CDC_RX_INP_MUX_RX_INT0_CFG1, 4,
+		rx_prim_mix_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp0, LPASS_CDC_RX_INP_MUX_RX_INT1_CFG0, 0,
+		rx_prim_mix_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp1, LPASS_CDC_RX_INP_MUX_RX_INT1_CFG0, 4,
+		rx_prim_mix_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int1_1_mix_inp2, LPASS_CDC_RX_INP_MUX_RX_INT1_CFG1, 4,
+		rx_prim_mix_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp0, LPASS_CDC_RX_INP_MUX_RX_INT2_CFG0, 0,
+		rx_prim_mix_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp1, LPASS_CDC_RX_INP_MUX_RX_INT2_CFG0, 4,
+		rx_prim_mix_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int2_1_mix_inp2, LPASS_CDC_RX_INP_MUX_RX_INT2_CFG1, 4,
+		rx_prim_mix_text);
+
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int0_mix2_inp, LPASS_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2,
+		rx_sidetone_mix_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int1_mix2_inp, LPASS_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4,
+		rx_sidetone_mix_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int2_mix2_inp, LPASS_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 6,
+		rx_sidetone_mix_text);
+
+LPASS_CDC_RX_MACRO_DAPM_ENUM(iir0_inp0, LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0,
+	iir_inp_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(iir0_inp1, LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0,
+	iir_inp_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(iir0_inp2, LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0,
+	iir_inp_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(iir0_inp3, LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0,
+	iir_inp_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(iir1_inp0, LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0,
+	iir_inp_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(iir1_inp1, LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0,
+	iir_inp_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(iir1_inp2, LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0,
+	iir_inp_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(iir1_inp3, LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0,
+	iir_inp_mux_text);
+
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int0_1_interp, SND_SOC_NOPM, 0,
+	rx_int0_1_interp_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int1_1_interp, SND_SOC_NOPM, 0,
+	rx_int1_1_interp_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int2_1_interp, SND_SOC_NOPM, 0,
+	rx_int2_1_interp_mux_text);
+
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int0_2_interp, SND_SOC_NOPM, 0,
+	rx_int0_2_interp_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int1_2_interp, SND_SOC_NOPM, 0,
+	rx_int1_2_interp_mux_text);
+LPASS_CDC_RX_MACRO_DAPM_ENUM(rx_int2_2_interp, SND_SOC_NOPM, 0,
+	rx_int2_2_interp_mux_text);
+
+LPASS_CDC_RX_MACRO_DAPM_ENUM_EXT(rx_int0_dem_inp, LPASS_CDC_RX_RX0_RX_PATH_CFG1, 0,
+	rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
+	lpass_cdc_rx_macro_int_dem_inp_mux_put);
+LPASS_CDC_RX_MACRO_DAPM_ENUM_EXT(rx_int1_dem_inp, LPASS_CDC_RX_RX1_RX_PATH_CFG1, 0,
+	rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
+	lpass_cdc_rx_macro_int_dem_inp_mux_put);
+
+LPASS_CDC_RX_MACRO_DAPM_ENUM_EXT(lpass_cdc_rx_macro_rx0, SND_SOC_NOPM, 0, lpass_cdc_rx_macro_mux_text,
+	lpass_cdc_rx_macro_mux_get, lpass_cdc_rx_macro_mux_put);
+LPASS_CDC_RX_MACRO_DAPM_ENUM_EXT(lpass_cdc_rx_macro_rx1, SND_SOC_NOPM, 0, lpass_cdc_rx_macro_mux_text,
+	lpass_cdc_rx_macro_mux_get, lpass_cdc_rx_macro_mux_put);
+LPASS_CDC_RX_MACRO_DAPM_ENUM_EXT(lpass_cdc_rx_macro_rx2, SND_SOC_NOPM, 0, lpass_cdc_rx_macro_mux_text,
+	lpass_cdc_rx_macro_mux_get, lpass_cdc_rx_macro_mux_put);
+LPASS_CDC_RX_MACRO_DAPM_ENUM_EXT(lpass_cdc_rx_macro_rx3, SND_SOC_NOPM, 0, lpass_cdc_rx_macro_mux_text,
+	lpass_cdc_rx_macro_mux_get, lpass_cdc_rx_macro_mux_put);
+LPASS_CDC_RX_MACRO_DAPM_ENUM_EXT(lpass_cdc_rx_macro_rx4, SND_SOC_NOPM, 0, lpass_cdc_rx_macro_mux_text,
+	lpass_cdc_rx_macro_mux_get, lpass_cdc_rx_macro_mux_put);
+LPASS_CDC_RX_MACRO_DAPM_ENUM_EXT(lpass_cdc_rx_macro_rx5, SND_SOC_NOPM, 0, lpass_cdc_rx_macro_mux_text,
+	lpass_cdc_rx_macro_mux_get, lpass_cdc_rx_macro_mux_put);
+
+static const char * const rx_echo_mux_text[] = {
+	"ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2"
+};
+
+static const struct soc_enum rx_mix_tx2_mux_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_RX_INP_MUX_RX_MIX_CFG5, 0, 4,
+			rx_echo_mux_text);
+
+static const struct snd_kcontrol_new rx_mix_tx2_mux =
+	SOC_DAPM_ENUM("RX MIX TX2_MUX Mux", rx_mix_tx2_mux_enum);
+
+static const struct soc_enum rx_mix_tx1_mux_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_RX_INP_MUX_RX_MIX_CFG4, 0, 4,
+			rx_echo_mux_text);
+
+static const struct snd_kcontrol_new rx_mix_tx1_mux =
+	SOC_DAPM_ENUM("RX MIX TX1_MUX Mux", rx_mix_tx1_mux_enum);
+
+static const struct soc_enum rx_mix_tx0_mux_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_RX_INP_MUX_RX_MIX_CFG4, 4, 4,
+			rx_echo_mux_text);
+
+static const struct snd_kcontrol_new rx_mix_tx0_mux =
+	SOC_DAPM_ENUM("RX MIX TX0_MUX Mux", rx_mix_tx0_mux_enum);
+
+static struct snd_soc_dai_ops lpass_cdc_rx_macro_dai_ops = {
+	.hw_params = lpass_cdc_rx_macro_hw_params,
+	.get_channel_map = lpass_cdc_rx_macro_get_channel_map,
+	.digital_mute = lpass_cdc_rx_macro_digital_mute,
+};
+
+static struct snd_soc_dai_driver lpass_cdc_rx_macro_dai[] = {
+	{
+		.name = "rx_macro_rx1",
+		.id = RX_MACRO_AIF1_PB,
+		.playback = {
+			.stream_name = "RX_MACRO_AIF1 Playback",
+			.rates = LPASS_CDC_RX_MACRO_RATES | LPASS_CDC_RX_MACRO_FRAC_RATES,
+			.formats = LPASS_CDC_RX_MACRO_FORMATS,
+			.rate_max = 384000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+		.ops = &lpass_cdc_rx_macro_dai_ops,
+	},
+	{
+		.name = "rx_macro_rx2",
+		.id = RX_MACRO_AIF2_PB,
+		.playback = {
+			.stream_name = "RX_MACRO_AIF2 Playback",
+			.rates = LPASS_CDC_RX_MACRO_RATES | LPASS_CDC_RX_MACRO_FRAC_RATES,
+			.formats = LPASS_CDC_RX_MACRO_FORMATS,
+			.rate_max = 384000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+		.ops = &lpass_cdc_rx_macro_dai_ops,
+	},
+	{
+		.name = "rx_macro_rx3",
+		.id = RX_MACRO_AIF3_PB,
+		.playback = {
+			.stream_name = "RX_MACRO_AIF3 Playback",
+			.rates = LPASS_CDC_RX_MACRO_RATES | LPASS_CDC_RX_MACRO_FRAC_RATES,
+			.formats = LPASS_CDC_RX_MACRO_FORMATS,
+			.rate_max = 384000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+		.ops = &lpass_cdc_rx_macro_dai_ops,
+	},
+	{
+		.name = "rx_macro_rx4",
+		.id = RX_MACRO_AIF4_PB,
+		.playback = {
+			.stream_name = "RX_MACRO_AIF4 Playback",
+			.rates = LPASS_CDC_RX_MACRO_RATES | LPASS_CDC_RX_MACRO_FRAC_RATES,
+			.formats = LPASS_CDC_RX_MACRO_FORMATS,
+			.rate_max = 384000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+		.ops = &lpass_cdc_rx_macro_dai_ops,
+	},
+	{
+		.name = "lpass_cdc_rx_macro_echo",
+		.id = RX_MACRO_AIF_ECHO,
+		.capture = {
+			.stream_name = "RX_AIF_ECHO Capture",
+			.rates = LPASS_CDC_RX_MACRO_ECHO_RATES,
+			.formats = LPASS_CDC_RX_MACRO_ECHO_FORMATS,
+			.rate_max = 48000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 3,
+		},
+		.ops = &lpass_cdc_rx_macro_dai_ops,
+	},
+	{
+		.name = "rx_macro_rx5",
+		.id = RX_MACRO_AIF5_PB,
+		.playback = {
+			.stream_name = "RX_MACRO_AIF5 Playback",
+			.rates = LPASS_CDC_RX_MACRO_RATES | LPASS_CDC_RX_MACRO_FRAC_RATES,
+			.formats = LPASS_CDC_RX_MACRO_FORMATS,
+			.rate_max = 384000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &lpass_cdc_rx_macro_dai_ops,
+	},
+	{
+		.name = "rx_macro_rx6",
+		.id = RX_MACRO_AIF6_PB,
+		.playback = {
+			.stream_name = "RX_MACRO_AIF6 Playback",
+			.rates = LPASS_CDC_RX_MACRO_RATES | LPASS_CDC_RX_MACRO_FRAC_RATES,
+			.formats = LPASS_CDC_RX_MACRO_FORMATS,
+			.rate_max = 384000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &lpass_cdc_rx_macro_dai_ops,
+	},
+};
+
+static int get_impedance_index(int imped)
+{
+	int i = 0;
+
+	if (imped < imped_index[i].imped_val) {
+		pr_debug("%s, detected impedance is less than %d Ohm\n",
+			__func__, imped_index[i].imped_val);
+		i = 0;
+		goto ret;
+	}
+	if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) {
+		pr_debug("%s, detected impedance is greater than %d Ohm\n",
+			__func__,
+			imped_index[ARRAY_SIZE(imped_index) - 1].imped_val);
+		i = ARRAY_SIZE(imped_index) - 1;
+		goto ret;
+	}
+	for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) {
+		if (imped >= imped_index[i].imped_val &&
+			imped < imped_index[i + 1].imped_val)
+			break;
+	}
+ret:
+	pr_debug("%s: selected impedance index = %d\n",
+			__func__, imped_index[i].index);
+	return imped_index[i].index;
+}
+
+/*
+ * lpass_cdc_rx_macro_wcd_clsh_imped_config -
+ * This function updates HPHL and HPHR gain settings
+ * according to the impedance value.
+ *
+ * @component: codec pointer handle
+ * @imped: impedance value of HPHL/R
+ * @reset: bool variable to reset registers when teardown
+ */
+static void lpass_cdc_rx_macro_wcd_clsh_imped_config(struct snd_soc_component *component,
+					   int imped, bool reset)
+{
+	int i;
+	int index = 0;
+	int table_size;
+
+	static const struct lpass_cdc_rx_macro_reg_mask_val
+				(*imped_table_ptr)[MAX_IMPED_PARAMS];
+
+	table_size = ARRAY_SIZE(imped_table);
+	imped_table_ptr = imped_table;
+	/* reset = 1, which means request is to reset the register values */
+	if (reset) {
+		for (i = 0; i < MAX_IMPED_PARAMS; i++)
+			snd_soc_component_update_bits(component,
+				imped_table_ptr[index][i].reg,
+				imped_table_ptr[index][i].mask, 0);
+		return;
+	}
+	index = get_impedance_index(imped);
+	if (index >= (ARRAY_SIZE(imped_index) - 1)) {
+		pr_debug("%s, impedance not in range = %d\n", __func__, imped);
+		return;
+	}
+	if (index >= table_size) {
+		pr_debug("%s, impedance index not in range = %d\n", __func__,
+			index);
+		return;
+	}
+	for (i = 0; i < MAX_IMPED_PARAMS; i++)
+		snd_soc_component_update_bits(component,
+				imped_table_ptr[index][i].reg,
+				imped_table_ptr[index][i].mask,
+				imped_table_ptr[index][i].val);
+}
+
+static bool lpass_cdc_rx_macro_get_data(struct snd_soc_component *component,
+			       struct device **rx_dev,
+			       struct lpass_cdc_rx_macro_priv **rx_priv,
+			       const char *func_name)
+{
+	*rx_dev = lpass_cdc_get_device_ptr(component->dev, RX_MACRO);
+
+	if (!(*rx_dev)) {
+		dev_err(component->dev,
+			"%s: null device for macro!\n", func_name);
+		return false;
+	}
+
+	*rx_priv = dev_get_drvdata((*rx_dev));
+	if (!(*rx_priv)) {
+		dev_err(component->dev,
+			"%s: priv is null for macro!\n", func_name);
+		return false;
+	}
+
+	if (!(*rx_priv)->component) {
+		dev_err(component->dev,
+			"%s: rx_priv component is not initialized!\n", func_name);
+		return false;
+	}
+
+	return true;
+}
+
+static int lpass_cdc_rx_macro_set_port_map(struct snd_soc_component *component,
+				u32 usecase, u32 size, void *data)
+{
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	struct swrm_port_config port_cfg;
+	int ret = 0;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	memset(&port_cfg, 0, sizeof(port_cfg));
+	port_cfg.uc = usecase;
+	port_cfg.size = size;
+	port_cfg.params = data;
+
+	if (rx_priv->swr_ctrl_data)
+		ret = swrm_wcd_notify(
+			rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+			SWR_SET_PORT_MAP, &port_cfg);
+
+	return ret;
+}
+
+static int lpass_cdc_rx_macro_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int val = 0;
+	unsigned short look_ahead_dly_reg =
+				LPASS_CDC_RX_RX0_RX_PATH_CFG0;
+
+	val = ucontrol->value.enumerated.item[0];
+	if (val >= e->items)
+		return -EINVAL;
+
+	dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
+		widget->name, val);
+
+	if (e->reg == LPASS_CDC_RX_RX0_RX_PATH_CFG1)
+		look_ahead_dly_reg = LPASS_CDC_RX_RX0_RX_PATH_CFG0;
+	else if (e->reg == LPASS_CDC_RX_RX1_RX_PATH_CFG1)
+		look_ahead_dly_reg = LPASS_CDC_RX_RX1_RX_PATH_CFG0;
+
+	/* Set Look Ahead Delay */
+	snd_soc_component_update_bits(component, look_ahead_dly_reg,
+			    0x08, (val ? 0x08 : 0x00));
+	/* Set DEM INP Select */
+	return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
+}
+
+static int lpass_cdc_rx_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
+					    u8 rate_reg_val,
+					    u32 sample_rate)
+{
+	u8 int_1_mix1_inp = 0;
+	u32 j = 0, port = 0;
+	u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
+	u16 int_fs_reg = 0;
+	u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
+	u8 inp0_sel = 0, inp1_sel = 0, inp2_sel = 0;
+	struct snd_soc_component *component = dai->component;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id],
+			 LPASS_CDC_RX_MACRO_PORTS_MAX) {
+		int_1_mix1_inp = port;
+		if ((int_1_mix1_inp < LPASS_CDC_RX_MACRO_RX0) ||
+			(int_1_mix1_inp > LPASS_CDC_RX_MACRO_PORTS_MAX)) {
+			pr_err("%s: Invalid RX port, Dai ID is %d\n",
+				__func__, dai->id);
+			return -EINVAL;
+		}
+
+		int_mux_cfg0 = LPASS_CDC_RX_INP_MUX_RX_INT0_CFG0;
+
+		/*
+		 * Loop through all interpolator MUX inputs and find out
+		 * to which interpolator input, the rx port
+		 * is connected
+		 */
+		for (j = 0; j < INTERP_MAX; j++) {
+			int_mux_cfg1 = int_mux_cfg0 + 4;
+
+			int_mux_cfg0_val = snd_soc_component_read32(
+						component, int_mux_cfg0);
+			int_mux_cfg1_val = snd_soc_component_read32(
+						component, int_mux_cfg1);
+			inp0_sel = int_mux_cfg0_val & 0x0F;
+			inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F;
+			inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F;
+			if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
+			    (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
+			    (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) {
+				int_fs_reg = LPASS_CDC_RX_RX0_RX_PATH_CTL +
+					     0x80 * j;
+				pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_1\n",
+					  __func__, dai->id, j);
+				pr_debug("%s: set INT%u_1 sample rate to %u\n",
+					__func__, j, sample_rate);
+				/* sample_rate is in Hz */
+				snd_soc_component_update_bits(component,
+						int_fs_reg,
+						0x0F, rate_reg_val);
+			}
+			int_mux_cfg0 += 8;
+		}
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
+					u8 rate_reg_val,
+					u32 sample_rate)
+{
+	u8 int_2_inp = 0;
+	u32 j = 0, port = 0;
+	u16 int_mux_cfg1 = 0, int_fs_reg = 0;
+	u8 int_mux_cfg1_val = 0;
+	struct snd_soc_component *component = dai->component;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	for_each_set_bit(port, &rx_priv->active_ch_mask[dai->id],
+			 LPASS_CDC_RX_MACRO_PORTS_MAX) {
+		int_2_inp = port;
+		if ((int_2_inp < LPASS_CDC_RX_MACRO_RX0) ||
+			(int_2_inp > LPASS_CDC_RX_MACRO_PORTS_MAX)) {
+			pr_err("%s: Invalid RX port, Dai ID is %d\n",
+				__func__, dai->id);
+			return -EINVAL;
+		}
+
+		int_mux_cfg1 = LPASS_CDC_RX_INP_MUX_RX_INT0_CFG1;
+		for (j = 0; j < INTERP_MAX; j++) {
+			int_mux_cfg1_val = snd_soc_component_read32(
+						component, int_mux_cfg1) &
+						0x0F;
+			if (int_mux_cfg1_val == int_2_inp +
+							INTn_2_INP_SEL_RX0) {
+				int_fs_reg = LPASS_CDC_RX_RX0_RX_PATH_MIX_CTL +
+						0x80 * j;
+				pr_debug("%s: AIF_PB DAI(%d) connected to INT%u_2\n",
+					  __func__, dai->id, j);
+				pr_debug("%s: set INT%u_2 sample rate to %u\n",
+					__func__, j, sample_rate);
+				snd_soc_component_update_bits(
+						component, int_fs_reg,
+						0x0F, rate_reg_val);
+			}
+			int_mux_cfg1 += 8;
+		}
+	}
+	return 0;
+}
+
+static bool lpass_cdc_rx_macro_is_fractional_sample_rate(u32 sample_rate)
+{
+	switch (sample_rate) {
+	case SAMPLING_RATE_44P1KHZ:
+	case SAMPLING_RATE_88P2KHZ:
+	case SAMPLING_RATE_176P4KHZ:
+	case SAMPLING_RATE_352P8KHZ:
+		return true;
+	default:
+		return false;
+	}
+	return false;
+}
+
+static int lpass_cdc_rx_macro_set_interpolator_rate(struct snd_soc_dai *dai,
+					  u32 sample_rate)
+{
+	struct snd_soc_component *component = dai->component;
+	int rate_val = 0;
+	int i = 0, ret = 0;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+
+	for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) {
+		if (sample_rate == sr_val_tbl[i].sample_rate) {
+			rate_val = sr_val_tbl[i].rate_val;
+			if (lpass_cdc_rx_macro_is_fractional_sample_rate(sample_rate))
+				rx_priv->is_native_on = true;
+			else
+				rx_priv->is_native_on = false;
+			break;
+		}
+	}
+	if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) {
+		dev_err(component->dev, "%s: Unsupported sample rate: %d\n",
+			__func__, sample_rate);
+		return -EINVAL;
+	}
+
+	ret = lpass_cdc_rx_macro_set_prim_interpolator_rate(dai, (u8)rate_val, sample_rate);
+	if (ret)
+		return ret;
+	ret = lpass_cdc_rx_macro_set_mix_interpolator_rate(dai, (u8)rate_val, sample_rate);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
+static int lpass_cdc_rx_macro_hw_params(struct snd_pcm_substream *substream,
+			       struct snd_pcm_hw_params *params,
+			       struct snd_soc_dai *dai)
+{
+	struct snd_soc_component *component = dai->component;
+	int ret = 0;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(component->dev,
+		"%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
+		 dai->name, dai->id, params_rate(params),
+		 params_channels(params));
+
+	switch (substream->stream) {
+	case SNDRV_PCM_STREAM_PLAYBACK:
+		ret = lpass_cdc_rx_macro_set_interpolator_rate(dai, params_rate(params));
+		if (ret) {
+			pr_err("%s: cannot set sample rate: %u\n",
+				__func__, params_rate(params));
+			return ret;
+		}
+		rx_priv->bit_width[dai->id] = params_width(params);
+		break;
+	case SNDRV_PCM_STREAM_CAPTURE:
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_get_channel_map(struct snd_soc_dai *dai,
+				unsigned int *tx_num, unsigned int *tx_slot,
+				unsigned int *rx_num, unsigned int *rx_slot)
+{
+	struct snd_soc_component *component = dai->component;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	unsigned int temp = 0, ch_mask = 0;
+	u16 val = 0, mask = 0, cnt = 0, i = 0;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	switch (dai->id) {
+	case RX_MACRO_AIF1_PB:
+	case RX_MACRO_AIF2_PB:
+	case RX_MACRO_AIF3_PB:
+	case RX_MACRO_AIF4_PB:
+		for_each_set_bit(temp, &rx_priv->active_ch_mask[dai->id],
+			 LPASS_CDC_RX_MACRO_PORTS_MAX) {
+			ch_mask |= (1 << temp);
+			if (++i == LPASS_CDC_RX_MACRO_MAX_DMA_CH_PER_PORT)
+				break;
+		}
+		/*
+		 * CDC_DMA_RX_0 port drives RX0/RX1 -- ch_mask 0x1/0x2/0x3
+		 * CDC_DMA_RX_1 port drives RX2/RX3 -- ch_mask 0x1/0x2/0x3
+		 * CDC_DMA_RX_2 port drives RX4     -- ch_mask 0x1
+		 * CDC_DMA_RX_3 port drives RX5     -- ch_mask 0x1
+		 * AIFn can pair to any CDC_DMA_RX_n port.
+		 * In general, below convention is used::
+		 * CDC_DMA_RX_0(AIF1)/CDC_DMA_RX_1(AIF2)/
+		 * CDC_DMA_RX_2(AIF3)/CDC_DMA_RX_3(AIF4)
+		 * Above is reflected in machine driver BE dailink
+		 */
+		if (ch_mask & 0x0C)
+			ch_mask = ch_mask >> 2;
+		if ((ch_mask & 0x10) || (ch_mask & 0x20))
+			ch_mask = 0x1;
+		*rx_slot = ch_mask;
+		*rx_num = rx_priv->active_ch_cnt[dai->id];
+		dev_dbg(rx_priv->dev,
+			"%s: dai->id:%d, ch_mask:0x%x, active_ch_cnt:%d active_mask: 0x%x\n",
+			__func__, dai->id, *rx_slot, *rx_num, rx_priv->active_ch_mask[dai->id]);
+		break;
+	case RX_MACRO_AIF5_PB:
+		*rx_slot = 0x1;
+		*rx_num = 0x01;
+		dev_dbg(rx_priv->dev,
+			"%s: dai->id:%d, ch_mask:0x%x, active_ch_cnt:%d\n",
+			__func__, dai->id, *rx_slot, *rx_num);
+		break;
+	case RX_MACRO_AIF6_PB:
+		*rx_slot = 0x1;
+		*rx_num = 0x01;
+		dev_dbg(rx_priv->dev,
+			"%s: dai->id:%d, ch_mask:0x%x, active_ch_cnt:%d\n",
+			__func__, dai->id, *rx_slot, *rx_num);
+		break;
+	case RX_MACRO_AIF_ECHO:
+		val = snd_soc_component_read32(component,
+			LPASS_CDC_RX_INP_MUX_RX_MIX_CFG4);
+		if (val & LPASS_CDC_RX_MACRO_EC_MIX_TX0_MASK) {
+			mask |= 0x1;
+			cnt++;
+		}
+		if (val & LPASS_CDC_RX_MACRO_EC_MIX_TX1_MASK) {
+			mask |= 0x2;
+			cnt++;
+		}
+		val = snd_soc_component_read32(component,
+			LPASS_CDC_RX_INP_MUX_RX_MIX_CFG5);
+		if (val & LPASS_CDC_RX_MACRO_EC_MIX_TX2_MASK) {
+			mask |= 0x4;
+			cnt++;
+		}
+		*tx_slot = mask;
+		*tx_num = cnt;
+		break;
+	default:
+		dev_err(rx_dev, "%s: Invalid AIF\n", __func__);
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_digital_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_component *component = dai->component;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	uint16_t j = 0, reg = 0, mix_reg = 0, dsm_reg = 0;
+	u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
+	u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
+
+	if (mute)
+		return 0;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	switch (dai->id) {
+	case RX_MACRO_AIF1_PB:
+	case RX_MACRO_AIF2_PB:
+	case RX_MACRO_AIF3_PB:
+	case RX_MACRO_AIF4_PB:
+	for (j = 0; j < INTERP_MAX; j++) {
+		reg = LPASS_CDC_RX_RX0_RX_PATH_CTL +
+				(j * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+		mix_reg = LPASS_CDC_RX_RX0_RX_PATH_MIX_CTL +
+				(j * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+		dsm_reg = LPASS_CDC_RX_RX0_RX_PATH_DSM_CTL +
+				(j * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+		if (j == INTERP_AUX)
+			dsm_reg = LPASS_CDC_RX_RX2_RX_PATH_DSM_CTL;
+		int_mux_cfg0 = LPASS_CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8;
+		int_mux_cfg1 = int_mux_cfg0 + 4;
+		int_mux_cfg0_val = snd_soc_component_read32(component,
+							int_mux_cfg0);
+		int_mux_cfg1_val = snd_soc_component_read32(component,
+							int_mux_cfg1);
+		if (snd_soc_component_read32(component, dsm_reg) & 0x01) {
+			if (int_mux_cfg0_val || (int_mux_cfg1_val & 0xF0))
+				snd_soc_component_update_bits(component,
+							reg, 0x20, 0x20);
+			if (int_mux_cfg1_val & 0x0F) {
+				snd_soc_component_update_bits(component,
+							reg, 0x20, 0x20);
+				snd_soc_component_update_bits(component,
+							mix_reg, 0x20, 0x20);
+			}
+		}
+	}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_mclk_enable(
+				struct lpass_cdc_rx_macro_priv *rx_priv,
+				bool mclk_enable, bool dapm)
+{
+	struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
+	int ret = 0;
+
+	if (regmap == NULL) {
+		dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	dev_dbg(rx_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
+		__func__, mclk_enable, dapm, rx_priv->rx_mclk_users);
+
+	mutex_lock(&rx_priv->mclk_lock);
+	if (mclk_enable) {
+		if (rx_priv->rx_mclk_users == 0) {
+			if (rx_priv->is_native_on)
+				rx_priv->clk_id = RX_CORE_CLK;
+			ret = lpass_cdc_clk_rsc_request_clock(rx_priv->dev,
+							   rx_priv->default_clk_id,
+							   rx_priv->clk_id,
+							   true);
+			if (ret < 0) {
+				dev_err(rx_priv->dev,
+					"%s: rx request clock enable failed\n",
+					__func__);
+				goto exit;
+			}
+			lpass_cdc_clk_rsc_fs_gen_request(rx_priv->dev,
+							true);
+			regcache_mark_dirty(regmap);
+			regcache_sync_region(regmap,
+					RX_START_OFFSET,
+					RX_MAX_OFFSET);
+			regmap_update_bits(regmap,
+				LPASS_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
+				0x01, 0x01);
+			regmap_update_bits(regmap,
+				LPASS_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
+				0x02, 0x02);
+			regmap_update_bits(regmap,
+				LPASS_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
+				0x02, 0x00);
+			regmap_update_bits(regmap,
+				LPASS_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
+				0x01, 0x01);
+		}
+		rx_priv->rx_mclk_users++;
+	} else {
+		if (rx_priv->rx_mclk_users <= 0) {
+			dev_err(rx_priv->dev, "%s: clock already disabled\n",
+				__func__);
+			rx_priv->rx_mclk_users = 0;
+			goto exit;
+		}
+		rx_priv->rx_mclk_users--;
+		if (rx_priv->rx_mclk_users == 0) {
+			regmap_update_bits(regmap,
+				LPASS_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
+				0x01, 0x00);
+			regmap_update_bits(regmap,
+				LPASS_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL,
+				0x02, 0x02);
+			regmap_update_bits(regmap,
+				LPASS_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
+				0x02, 0x00);
+			regmap_update_bits(regmap,
+				LPASS_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL,
+				0x01, 0x00);
+			lpass_cdc_clk_rsc_fs_gen_request(rx_priv->dev,
+			   false);
+			lpass_cdc_clk_rsc_request_clock(rx_priv->dev,
+						 rx_priv->default_clk_id,
+						 rx_priv->clk_id,
+						 false);
+			rx_priv->clk_id = rx_priv->default_clk_id;
+		}
+	}
+exit:
+	trace_printk("%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
+		__func__, mclk_enable, dapm, rx_priv->rx_mclk_users);
+	mutex_unlock(&rx_priv->mclk_lock);
+	return ret;
+}
+
+static int lpass_cdc_rx_macro_mclk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	int ret = 0;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	int mclk_freq = MCLK_FREQ;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(rx_dev, "%s: event = %d\n", __func__, event);
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (rx_priv->is_native_on)
+			mclk_freq = MCLK_FREQ_NATIVE;
+		if (rx_priv->swr_ctrl_data)
+			swrm_wcd_notify(
+				rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+				SWR_CLK_FREQ, &mclk_freq);
+		ret = lpass_cdc_rx_macro_mclk_enable(rx_priv, 1, true);
+		if (ret)
+			rx_priv->dapm_mclk_enable = false;
+		else
+			rx_priv->dapm_mclk_enable = true;
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (rx_priv->dapm_mclk_enable)
+			ret = lpass_cdc_rx_macro_mclk_enable(rx_priv, 0, true);
+		break;
+	default:
+		dev_err(rx_priv->dev,
+			"%s: invalid DAPM event %d\n", __func__, event);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static int lpass_cdc_rx_macro_event_handler(struct snd_soc_component *component,
+				  u16 event, u32 data)
+{
+	u16 reg = 0, reg_mix = 0, rx_idx = 0, mute = 0x0, val = 0;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	int ret = 0;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	switch (event) {
+	case LPASS_CDC_MACRO_EVT_RX_MUTE:
+		rx_idx = data >> 0x10;
+		mute = data & 0xffff;
+		val = mute ? 0x10 : 0x00;
+		reg = LPASS_CDC_RX_RX0_RX_PATH_CTL + (rx_idx *
+					LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+		reg_mix = LPASS_CDC_RX_RX0_RX_PATH_MIX_CTL + (rx_idx *
+					LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+		snd_soc_component_update_bits(component, reg,
+				0x10, val);
+		snd_soc_component_update_bits(component, reg_mix,
+				0x10, val);
+		break;
+	case LPASS_CDC_MACRO_EVT_RX_COMPANDER_SOFT_RST:
+		rx_idx = data >> 0x10;
+		if (rx_idx == INTERP_AUX)
+			goto done;
+		reg = LPASS_CDC_RX_COMPANDER0_CTL0 +
+				(rx_idx * LPASS_CDC_RX_MACRO_COMP_OFFSET);
+		snd_soc_component_write(component, reg,
+				snd_soc_component_read32(component, reg));
+		break;
+	case LPASS_CDC_MACRO_EVT_IMPED_TRUE:
+		lpass_cdc_rx_macro_wcd_clsh_imped_config(component, data, true);
+		break;
+	case LPASS_CDC_MACRO_EVT_IMPED_FALSE:
+		lpass_cdc_rx_macro_wcd_clsh_imped_config(component, data, false);
+		break;
+	case LPASS_CDC_MACRO_EVT_SSR_DOWN:
+		trace_printk("%s, enter SSR down\n", __func__);
+		rx_priv->dev_up = false;
+		if (rx_priv->swr_ctrl_data) {
+			swrm_wcd_notify(
+				rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+				SWR_DEVICE_SSR_DOWN, NULL);
+		}
+		if ((!pm_runtime_enabled(rx_dev) ||
+		     !pm_runtime_suspended(rx_dev))) {
+			ret = lpass_cdc_runtime_suspend(rx_dev);
+			if (!ret) {
+				pm_runtime_disable(rx_dev);
+				pm_runtime_set_suspended(rx_dev);
+				pm_runtime_enable(rx_dev);
+			}
+		}
+		break;
+	case LPASS_CDC_MACRO_EVT_PRE_SSR_UP:
+		/* enable&disable RX_CORE_CLK to reset GFMUX reg */
+		ret = lpass_cdc_clk_rsc_request_clock(rx_priv->dev,
+						rx_priv->default_clk_id,
+						RX_CORE_CLK, true);
+		if (ret < 0)
+			dev_err_ratelimited(rx_priv->dev,
+				"%s, failed to enable clk, ret:%d\n",
+				__func__, ret);
+		else
+			lpass_cdc_clk_rsc_request_clock(rx_priv->dev,
+						rx_priv->default_clk_id,
+						RX_CORE_CLK, false);
+		break;
+	case LPASS_CDC_MACRO_EVT_SSR_UP:
+		trace_printk("%s, enter SSR up\n", __func__);
+		rx_priv->dev_up = true;
+		/* reset swr after ssr/pdr */
+		rx_priv->reset_swr = true;
+
+		if (rx_priv->swr_ctrl_data)
+			swrm_wcd_notify(
+				rx_priv->swr_ctrl_data[0].rx_swr_pdev,
+				SWR_DEVICE_SSR_UP, NULL);
+		break;
+	case LPASS_CDC_MACRO_EVT_CLK_RESET:
+		lpass_cdc_rsc_clk_reset(rx_dev, RX_CORE_CLK);
+		break;
+	case LPASS_CDC_MACRO_EVT_RX_PA_GAIN_UPDATE:
+		rx_priv->rx0_gain_val = snd_soc_component_read32(component,
+					LPASS_CDC_RX_RX0_RX_VOL_CTL);
+		rx_priv->rx1_gain_val = snd_soc_component_read32(component,
+					LPASS_CDC_RX_RX1_RX_VOL_CTL);
+		if (data) {
+			/* Reduce gain by half only if its greater than -6DB */
+			if ((rx_priv->rx0_gain_val >= LPASS_CDC_RX_MACRO_GAIN_VAL_UNITY)
+			&& (rx_priv->rx0_gain_val <= LPASS_CDC_RX_MACRO_GAIN_MAX_VAL))
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_RX_RX0_RX_VOL_CTL, 0xFF,
+					(rx_priv->rx0_gain_val -
+					 LPASS_CDC_RX_MACRO_MOD_GAIN));
+			if ((rx_priv->rx1_gain_val >= LPASS_CDC_RX_MACRO_GAIN_VAL_UNITY)
+			&& (rx_priv->rx1_gain_val <= LPASS_CDC_RX_MACRO_GAIN_MAX_VAL))
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_RX_RX1_RX_VOL_CTL, 0xFF,
+					(rx_priv->rx1_gain_val -
+					 LPASS_CDC_RX_MACRO_MOD_GAIN));
+		}
+		else {
+			/* Reset gain value to default */
+			if ((rx_priv->rx0_gain_val >=
+			    (LPASS_CDC_RX_MACRO_GAIN_VAL_UNITY - LPASS_CDC_RX_MACRO_MOD_GAIN)) &&
+			    (rx_priv->rx0_gain_val <= (LPASS_CDC_RX_MACRO_GAIN_MAX_VAL -
+			    LPASS_CDC_RX_MACRO_MOD_GAIN)))
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_RX_RX0_RX_VOL_CTL, 0xFF,
+					(rx_priv->rx0_gain_val +
+					 LPASS_CDC_RX_MACRO_MOD_GAIN));
+			if ((rx_priv->rx1_gain_val >=
+			    (LPASS_CDC_RX_MACRO_GAIN_VAL_UNITY - LPASS_CDC_RX_MACRO_MOD_GAIN)) &&
+			    (rx_priv->rx1_gain_val <= (LPASS_CDC_RX_MACRO_GAIN_MAX_VAL -
+			    LPASS_CDC_RX_MACRO_MOD_GAIN)))
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_RX_RX1_RX_VOL_CTL, 0xFF,
+					(rx_priv->rx1_gain_val +
+					 LPASS_CDC_RX_MACRO_MOD_GAIN));
+		}
+		break;
+	case LPASS_CDC_MACRO_EVT_HPHL_HD2_ENABLE:
+		/* Enable hd2 config for hphl*/
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_RX0_RX_PATH_CFG0, 0x04, data);
+		break;
+	case LPASS_CDC_MACRO_EVT_HPHR_HD2_ENABLE:
+		/* Enable hd2 config for hphr*/
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_RX1_RX_PATH_CFG0, 0x04, data);
+		break;
+	}
+done:
+	return ret;
+}
+
+static int lpass_cdc_rx_macro_find_playback_dai_id_for_port(int port_id,
+						  struct lpass_cdc_rx_macro_priv *rx_priv)
+{
+	int i = 0;
+
+	for (i = RX_MACRO_AIF1_PB; i < LPASS_CDC_RX_MACRO_MAX_DAIS; i++) {
+		if (test_bit(port_id, &rx_priv->active_ch_mask[i]))
+			return i;
+	}
+
+	return -EINVAL;
+}
+
+static int lpass_cdc_rx_macro_set_idle_detect_thr(struct snd_soc_component *component,
+					struct lpass_cdc_rx_macro_priv *rx_priv,
+					int interp, int path_type)
+{
+	int port_id[4] = { 0, 0, 0, 0 };
+	int *port_ptr = NULL;
+	int num_ports = 0;
+	int bit_width = 0, i = 0;
+	int mux_reg = 0, mux_reg_val = 0;
+	int dai_id = 0, idle_thr = 0;
+
+	if ((interp != INTERP_HPHL) && (interp != INTERP_HPHR))
+		return 0;
+
+	if (!rx_priv->idle_det_cfg.hph_idle_detect_en)
+		return 0;
+
+	port_ptr = &port_id[0];
+	num_ports = 0;
+
+	/*
+	 * Read interpolator MUX input registers and find
+	 * which cdc_dma port is connected and store the port
+	 * numbers in port_id array.
+	 */
+	if (path_type == INTERP_MIX_PATH) {
+		mux_reg = LPASS_CDC_RX_INP_MUX_RX_INT0_CFG1 +
+						2 * interp;
+		mux_reg_val = snd_soc_component_read32(component, mux_reg) &
+				0x0f;
+
+		if ((mux_reg_val >= INTn_2_INP_SEL_RX0) &&
+		   (mux_reg_val <= INTn_2_INP_SEL_RX5)) {
+			*port_ptr++ = mux_reg_val - 1;
+			num_ports++;
+		}
+	}
+
+	if (path_type == INTERP_MAIN_PATH) {
+		mux_reg = LPASS_CDC_RX_INP_MUX_RX_INT1_CFG0 +
+			  2 * (interp - 1);
+		mux_reg_val = snd_soc_component_read32(component, mux_reg) &
+				0x0f;
+		i = LPASS_CDC_RX_MACRO_INTERP_MUX_NUM_INPUTS;
+
+		while (i) {
+			if ((mux_reg_val >= INTn_1_INP_SEL_RX0) &&
+			    (mux_reg_val <= INTn_1_INP_SEL_RX5)) {
+				*port_ptr++ = mux_reg_val -
+					INTn_1_INP_SEL_RX0;
+				num_ports++;
+			}
+			mux_reg_val =
+				(snd_soc_component_read32(component, mux_reg) &
+					0xf0) >> 4;
+			mux_reg += 1;
+			i--;
+		}
+	}
+
+	dev_dbg(component->dev, "%s: num_ports: %d, ports[%d %d %d %d]\n",
+		__func__, num_ports, port_id[0], port_id[1],
+		port_id[2], port_id[3]);
+
+	i = 0;
+	while (num_ports) {
+		dai_id = lpass_cdc_rx_macro_find_playback_dai_id_for_port(port_id[i++],
+								rx_priv);
+
+		if ((dai_id >= 0) && (dai_id < LPASS_CDC_RX_MACRO_MAX_DAIS)) {
+			dev_dbg(component->dev, "%s: dai_id: %d bit_width: %d\n",
+				__func__, dai_id,
+				rx_priv->bit_width[dai_id]);
+
+			if (rx_priv->bit_width[dai_id] > bit_width)
+				bit_width = rx_priv->bit_width[dai_id];
+		}
+		num_ports--;
+	}
+
+	switch (bit_width) {
+	case 16:
+		idle_thr = 0xff; /* F16 */
+		break;
+	case 24:
+	case 32:
+		idle_thr = 0x03; /* F22 */
+		break;
+	default:
+		idle_thr = 0x00;
+		break;
+	}
+
+	dev_dbg(component->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n",
+		__func__, idle_thr, rx_priv->idle_det_cfg.hph_idle_thr);
+
+	if ((rx_priv->idle_det_cfg.hph_idle_thr == 0) ||
+	    (idle_thr < rx_priv->idle_det_cfg.hph_idle_thr)) {
+		snd_soc_component_write(component,
+			LPASS_CDC_RX_IDLE_DETECT_CFG3, idle_thr);
+		rx_priv->idle_det_cfg.hph_idle_thr = idle_thr;
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	u16 gain_reg = 0, mix_reg = 0;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	if (w->shift >= INTERP_MAX) {
+		dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n",
+			__func__, w->shift, w->name);
+		return -EINVAL;
+	}
+
+	gain_reg = LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL +
+				(w->shift * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+	mix_reg = LPASS_CDC_RX_RX0_RX_PATH_MIX_CTL +
+				(w->shift * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+
+	dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		lpass_cdc_rx_macro_set_idle_detect_thr(component, rx_priv, w->shift,
+					INTERP_MIX_PATH);
+		lpass_cdc_rx_macro_enable_interp_clk(component, event, w->shift);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		snd_soc_component_write(component, gain_reg,
+			snd_soc_component_read32(component, gain_reg));
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* Clk Disable */
+		snd_soc_component_update_bits(component, mix_reg, 0x20, 0x00);
+		lpass_cdc_rx_macro_enable_interp_clk(component, event, w->shift);
+		/* Reset enable and disable */
+		snd_soc_component_update_bits(component, mix_reg, 0x40, 0x40);
+		snd_soc_component_update_bits(component, mix_reg, 0x40, 0x00);
+		break;
+	}
+
+	return 0;
+}
+
+static bool lpass_cdc_rx_macro_adie_lb(struct snd_soc_component *component,
+			     int interp_idx)
+{
+	u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
+	u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
+	u8 int_n_inp0 = 0, int_n_inp1 = 0, int_n_inp2 = 0;
+
+	int_mux_cfg0 = LPASS_CDC_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8;
+	int_mux_cfg1 = int_mux_cfg0 + 4;
+	int_mux_cfg0_val = snd_soc_component_read32(component, int_mux_cfg0);
+	int_mux_cfg1_val = snd_soc_component_read32(component, int_mux_cfg1);
+
+	int_n_inp0 = int_mux_cfg0_val & 0x0F;
+	if (int_n_inp0 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp0 == INTn_1_INP_SEL_DEC1 ||
+		int_n_inp0 == INTn_1_INP_SEL_IIR0 ||
+		int_n_inp0 == INTn_1_INP_SEL_IIR1)
+		return true;
+
+	int_n_inp1 = int_mux_cfg0_val >> 4;
+	if (int_n_inp1 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp1 == INTn_1_INP_SEL_DEC1 ||
+		int_n_inp1 == INTn_1_INP_SEL_IIR0 ||
+		int_n_inp1 == INTn_1_INP_SEL_IIR1)
+		return true;
+
+	int_n_inp2 = int_mux_cfg1_val >> 4;
+	if (int_n_inp2 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp2 == INTn_1_INP_SEL_DEC1 ||
+		int_n_inp2 == INTn_1_INP_SEL_IIR0 ||
+		int_n_inp2 == INTn_1_INP_SEL_IIR1)
+		return true;
+
+	return false;
+}
+
+static int lpass_cdc_rx_macro_enable_main_path(struct snd_soc_dapm_widget *w,
+					struct snd_kcontrol *kcontrol,
+					int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	u16 gain_reg = 0;
+	u16 reg = 0;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
+
+	if (w->shift >= INTERP_MAX) {
+		dev_err(component->dev, "%s: Invalid Interpolator value %d for name %s\n",
+			__func__, w->shift, w->name);
+		return -EINVAL;
+	}
+
+	reg = LPASS_CDC_RX_RX0_RX_PATH_CTL + (w->shift *
+						LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+	gain_reg = LPASS_CDC_RX_RX0_RX_VOL_CTL + (w->shift *
+						LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		lpass_cdc_rx_macro_set_idle_detect_thr(component, rx_priv, w->shift,
+						INTERP_MAIN_PATH);
+		lpass_cdc_rx_macro_enable_interp_clk(component, event, w->shift);
+		if (lpass_cdc_rx_macro_adie_lb(component, w->shift))
+			snd_soc_component_update_bits(component,
+						reg, 0x20, 0x20);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		snd_soc_component_write(component, gain_reg,
+			snd_soc_component_read32(component, gain_reg));
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		lpass_cdc_rx_macro_enable_interp_clk(component, event, w->shift);
+		break;
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_config_compander(struct snd_soc_component *component,
+				struct lpass_cdc_rx_macro_priv *rx_priv,
+				int interp_n, int event)
+{
+	int comp = 0;
+	u16 comp_ctl0_reg = 0, rx_path_cfg0_reg = 0, rx_path_cfg3_reg = 0;
+	u16 rx0_path_ctl_reg = 0;
+	u8 pcm_rate = 0, val = 0;
+
+	/* AUX does not have compander */
+	if (interp_n == INTERP_AUX)
+		return 0;
+
+	comp = interp_n;
+	dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
+		__func__, event, comp + 1, rx_priv->comp_enabled[comp]);
+
+	rx_path_cfg3_reg = LPASS_CDC_RX_RX0_RX_PATH_CFG3 +
+					(comp * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+	rx0_path_ctl_reg = LPASS_CDC_RX_RX0_RX_PATH_CTL +
+					(comp * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+	pcm_rate = (snd_soc_component_read32(component, rx0_path_ctl_reg)
+						& 0x0F);
+	if (pcm_rate < 0x06)
+		val = 0x03;
+	else if (pcm_rate < 0x08)
+		val = 0x01;
+	else if (pcm_rate < 0x0B)
+		val = 0x02;
+	else
+		val = 0x00;
+
+	if (SND_SOC_DAPM_EVENT_ON(event))
+		snd_soc_component_update_bits(component, rx_path_cfg3_reg,
+					0x03, val);
+	if (SND_SOC_DAPM_EVENT_OFF(event))
+		snd_soc_component_update_bits(component, rx_path_cfg3_reg,
+					0x03, 0x03);
+	if (!rx_priv->comp_enabled[comp])
+		return 0;
+
+	comp_ctl0_reg = LPASS_CDC_RX_COMPANDER0_CTL0 +
+					(comp * LPASS_CDC_RX_MACRO_COMP_OFFSET);
+	rx_path_cfg0_reg = LPASS_CDC_RX_RX0_RX_PATH_CFG0 +
+					(comp * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		/* Enable Compander Clock */
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+					0x01, 0x01);
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+					0x02, 0x02);
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+					0x02, 0x00);
+		snd_soc_component_update_bits(component, rx_path_cfg0_reg,
+					0x02, 0x02);
+	}
+
+	if (SND_SOC_DAPM_EVENT_OFF(event)) {
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+					0x04, 0x04);
+		snd_soc_component_update_bits(component, rx_path_cfg0_reg,
+					0x02, 0x00);
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+					0x01, 0x00);
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+					0x04, 0x00);
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_load_compander_coeff(struct snd_soc_component *component,
+					 struct lpass_cdc_rx_macro_priv *rx_priv,
+					 int interp_n, int event)
+{
+	int comp = 0;
+	u16 comp_coeff_lsb_reg = 0, comp_coeff_msb_reg = 0;
+	int i = 0;
+	int hph_pwr_mode = HPH_LOHIFI;
+
+	if (!rx_priv->comp_enabled[comp])
+		return 0;
+
+	if (interp_n == INTERP_HPHL) {
+		comp_coeff_lsb_reg = LPASS_CDC_RX_TOP_HPHL_COMP_WR_LSB;
+		comp_coeff_msb_reg = LPASS_CDC_RX_TOP_HPHL_COMP_WR_MSB;
+	} else if (interp_n == INTERP_HPHR) {
+		comp_coeff_lsb_reg = LPASS_CDC_RX_TOP_HPHR_COMP_WR_LSB;
+		comp_coeff_msb_reg = LPASS_CDC_RX_TOP_HPHR_COMP_WR_MSB;
+	} else {
+		/* compander coefficients are loaded only for hph path */
+		return 0;
+	}
+
+	comp = interp_n;
+	hph_pwr_mode = rx_priv->hph_pwr_mode;
+	dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
+		__func__, event, comp + 1, rx_priv->comp_enabled[comp]);
+
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		/* Load Compander Coeff */
+		for (i = 0; i < COMP_MAX_COEFF; i++) {
+			snd_soc_component_write(component, comp_coeff_lsb_reg,
+					comp_coeff_table[hph_pwr_mode][i].lsb);
+			snd_soc_component_write(component, comp_coeff_msb_reg,
+					comp_coeff_table[hph_pwr_mode][i].msb);
+		}
+	}
+
+	return 0;
+}
+
+static void lpass_cdc_rx_macro_enable_softclip_clk(struct snd_soc_component *component,
+					 struct lpass_cdc_rx_macro_priv *rx_priv,
+					 bool enable)
+{
+	if (enable) {
+		if (rx_priv->softclip_clk_users == 0)
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_SOFTCLIP_CRC,
+				0x01, 0x01);
+		rx_priv->softclip_clk_users++;
+	} else {
+		rx_priv->softclip_clk_users--;
+		if (rx_priv->softclip_clk_users == 0)
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_SOFTCLIP_CRC,
+				0x01, 0x00);
+	}
+}
+
+static int lpass_cdc_rx_macro_config_softclip(struct snd_soc_component *component,
+				struct lpass_cdc_rx_macro_priv *rx_priv,
+				int event)
+{
+	dev_dbg(component->dev, "%s: event %d, enabled %d\n",
+		__func__, event, rx_priv->is_softclip_on);
+
+	if (!rx_priv->is_softclip_on)
+		return 0;
+
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		/* Enable Softclip clock */
+		lpass_cdc_rx_macro_enable_softclip_clk(component, rx_priv, true);
+		/* Enable Softclip control */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x01);
+	}
+
+	if (SND_SOC_DAPM_EVENT_OFF(event)) {
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x01, 0x00);
+		lpass_cdc_rx_macro_enable_softclip_clk(component, rx_priv, false);
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_config_aux_hpf(struct snd_soc_component *component,
+				struct lpass_cdc_rx_macro_priv *rx_priv,
+				int event)
+{
+	dev_dbg(component->dev, "%s: event %d, enabled %d\n",
+		__func__, event, rx_priv->is_aux_hpf_on);
+
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		/* Update Aux HPF control */
+		if (!rx_priv->is_aux_hpf_on)
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_RX2_RX_PATH_CFG1, 0x04, 0x00);
+	}
+
+	if (SND_SOC_DAPM_EVENT_OFF(event)) {
+		/* Reset to default (HPF=ON) */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_RX2_RX_PATH_CFG1, 0x04, 0x04);
+	}
+
+	return 0;
+}
+
+
+static inline void
+lpass_cdc_rx_macro_enable_clsh_block(struct lpass_cdc_rx_macro_priv *rx_priv, bool enable)
+{
+	if ((enable && ++rx_priv->clsh_users == 1) ||
+	    (!enable && --rx_priv->clsh_users == 0))
+		snd_soc_component_update_bits(rx_priv->component,
+				LPASS_CDC_RX_CLSH_CRC, 0x01,
+				(u8) enable);
+	if (rx_priv->clsh_users < 0)
+		rx_priv->clsh_users = 0;
+	dev_dbg(rx_priv->dev, "%s: clsh_users %d, enable %d", __func__,
+		rx_priv->clsh_users, enable);
+}
+
+static int lpass_cdc_rx_macro_config_classh(struct snd_soc_component *component,
+				struct lpass_cdc_rx_macro_priv *rx_priv,
+				int interp_n, int event)
+{
+	if (SND_SOC_DAPM_EVENT_OFF(event)) {
+		lpass_cdc_rx_macro_enable_clsh_block(rx_priv, false);
+		return 0;
+	}
+
+	if (!SND_SOC_DAPM_EVENT_ON(event))
+		return 0;
+
+	lpass_cdc_rx_macro_enable_clsh_block(rx_priv, true);
+	if (interp_n == INTERP_HPHL ||
+		interp_n == INTERP_HPHR) {
+		/*
+		 * These K1 values depend on the Headphone Impedance
+		 * For now it is assumed to be 16 ohm
+		 */
+		snd_soc_component_update_bits(component,
+					LPASS_CDC_RX_CLSH_K1_LSB,
+					0xFF, 0xC0);
+		snd_soc_component_update_bits(component,
+					LPASS_CDC_RX_CLSH_K1_MSB,
+					0x0F, 0x00);
+	}
+	switch (interp_n) {
+	case INTERP_HPHL:
+		if (rx_priv->is_ear_mode_on)
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_CLSH_HPH_V_PA,
+				0x3F, 0x39);
+		else
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_CLSH_HPH_V_PA,
+				0x3F, 0x1C);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_CLSH_DECAY_CTRL,
+				0x07, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_RX0_RX_PATH_CFG0,
+				0x40, 0x40);
+		break;
+	case INTERP_HPHR:
+		if (rx_priv->is_ear_mode_on)
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_CLSH_HPH_V_PA,
+				0x3F, 0x39);
+		else
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_CLSH_HPH_V_PA,
+				0x3F, 0x1C);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_CLSH_DECAY_CTRL,
+				0x07, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_RX1_RX_PATH_CFG0,
+				0x40, 0x40);
+		break;
+	case INTERP_AUX:
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_RX2_RX_PATH_CFG0,
+				0x08, 0x08);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_RX2_RX_PATH_CFG0,
+				0x10, 0x10);
+		break;
+	}
+
+	return 0;
+}
+
+static void lpass_cdc_rx_macro_hd2_control(struct snd_soc_component *component,
+				 u16 interp_idx, int event)
+{
+	u16 hd2_scale_reg = 0;
+	u16 hd2_enable_reg = 0;
+
+	switch (interp_idx) {
+	case INTERP_HPHL:
+		hd2_scale_reg = LPASS_CDC_RX_RX0_RX_PATH_SEC3;
+		hd2_enable_reg = LPASS_CDC_RX_RX0_RX_PATH_CFG0;
+		break;
+	case INTERP_HPHR:
+		hd2_scale_reg = LPASS_CDC_RX_RX1_RX_PATH_SEC3;
+		hd2_enable_reg = LPASS_CDC_RX_RX1_RX_PATH_CFG0;
+		break;
+	}
+
+	if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
+		snd_soc_component_update_bits(component, hd2_scale_reg,
+				0x3C, 0x14);
+		snd_soc_component_update_bits(component, hd2_enable_reg,
+				0x04, 0x04);
+	}
+
+	if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
+		snd_soc_component_update_bits(component, hd2_enable_reg,
+				0x04, 0x00);
+		snd_soc_component_update_bits(component, hd2_scale_reg,
+				0x3C, 0x00);
+	}
+}
+
+static int lpass_cdc_rx_macro_hph_idle_detect_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	struct device *rx_dev = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] =
+		rx_priv->idle_det_cfg.hph_idle_detect_en;
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_hph_idle_detect_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	struct device *rx_dev = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	rx_priv->idle_det_cfg.hph_idle_detect_en =
+		ucontrol->value.integer.value[0];
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_get_compander(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	int comp = ((struct soc_multi_mixer_control *)
+		    kcontrol->private_value)->shift;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = rx_priv->comp_enabled[comp];
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_set_compander(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	int comp = ((struct soc_multi_mixer_control *)
+		    kcontrol->private_value)->shift;
+	int value = ucontrol->value.integer.value[0];
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
+		__func__, comp + 1, rx_priv->comp_enabled[comp], value);
+	rx_priv->comp_enabled[comp] = value;
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_mux_get(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] =
+			rx_priv->rx_port_value[widget->shift];
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_mux_put(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	struct snd_soc_dapm_update *update = NULL;
+	u32 rx_port_value = ucontrol->value.integer.value[0];
+	u32 aif_rst = 0;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	aif_rst = rx_priv->rx_port_value[widget->shift];
+	if (!rx_port_value) {
+		if (aif_rst == 0) {
+			dev_err(rx_dev, "%s:AIF reset already\n", __func__);
+			return 0;
+		}
+		if (aif_rst > RX_MACRO_AIF4_PB) {
+			dev_err(rx_dev, "%s: Invalid AIF reset\n", __func__);
+			return 0;
+		}
+	}
+	rx_priv->rx_port_value[widget->shift] = rx_port_value;
+
+	dev_dbg(rx_dev, "%s: mux input: %d, mux output: %d, aif_rst: %d\n",
+		__func__, rx_port_value, widget->shift, aif_rst);
+
+	switch (rx_port_value) {
+	case 0:
+		if (rx_priv->active_ch_cnt[aif_rst]) {
+			clear_bit(widget->shift,
+				&rx_priv->active_ch_mask[aif_rst]);
+			rx_priv->active_ch_cnt[aif_rst]--;
+		}
+		break;
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+		set_bit(widget->shift,
+			&rx_priv->active_ch_mask[rx_port_value]);
+		rx_priv->active_ch_cnt[rx_port_value]++;
+		break;
+	default:
+		dev_err(component->dev,
+			"%s:Invalid AIF_ID for LPASS_CDC_RX_MACRO MUX %d\n",
+			__func__, rx_port_value);
+		goto err;
+	}
+
+	snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
+					rx_port_value, e, update);
+	return 0;
+err:
+	return -EINVAL;
+}
+
+static int lpass_cdc_rx_macro_get_ear_mode(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = rx_priv->is_ear_mode_on;
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_put_ear_mode(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	rx_priv->is_ear_mode_on =
+			(!ucontrol->value.integer.value[0] ? false : true);
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_get_hph_hd2_mode(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = rx_priv->hph_hd2_mode;
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_put_hph_hd2_mode(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	rx_priv->hph_hd2_mode = ucontrol->value.integer.value[0];
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_get_hph_pwr_mode(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = rx_priv->hph_pwr_mode;
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_put_hph_pwr_mode(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	rx_priv->hph_pwr_mode = ucontrol->value.integer.value[0];
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+
+	ucontrol->value.integer.value[0] =
+		((snd_soc_component_read32(
+			component, LPASS_CDC_RX_BCL_VBAT_CFG) & 0x04) ?
+		  1 : 0);
+
+	dev_dbg(component->dev, "%s: value: %lu\n", __func__,
+		ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+
+	dev_dbg(component->dev, "%s: value: %lu\n", __func__,
+		ucontrol->value.integer.value[0]);
+
+	/* Set Vbat register configuration for GSM mode bit based on value */
+	if (ucontrol->value.integer.value[0])
+		snd_soc_component_update_bits(component,
+					LPASS_CDC_RX_BCL_VBAT_CFG,
+					0x04, 0x04);
+	else
+		snd_soc_component_update_bits(component,
+					LPASS_CDC_RX_BCL_VBAT_CFG,
+					0x04, 0x00);
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = rx_priv->is_softclip_on;
+
+	dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	rx_priv->is_softclip_on = ucontrol->value.integer.value[0];
+
+	dev_dbg(component->dev, "%s: soft clip enable = %d\n", __func__,
+		rx_priv->is_softclip_on);
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_aux_hpf_mode_get(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = rx_priv->is_aux_hpf_on;
+
+	dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_aux_hpf_mode_put(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	rx_priv->is_aux_hpf_on = ucontrol->value.integer.value[0];
+
+	dev_dbg(component->dev, "%s: aux hpf enable = %d\n", __func__,
+		rx_priv->is_aux_hpf_on);
+
+	return 0;
+}
+
+
+static int lpass_cdc_rx_macro_enable_vbat(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kcontrol,
+				 int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Enable clock for VBAT block */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x10);
+		/* Enable VBAT block */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_CFG, 0x01, 0x01);
+		/* Update interpolator with 384K path */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_RX2_RX_PATH_CFG1, 0x80, 0x80);
+		/* Update DSM FS rate */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_RX2_RX_PATH_SEC7, 0x02, 0x02);
+		/* Use attenuation mode */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_CFG, 0x02, 0x00);
+		/* BCL block needs softclip clock to be enabled */
+		lpass_cdc_rx_macro_enable_softclip_clk(component, rx_priv, true);
+		/* Enable VBAT at channel level */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_RX2_RX_PATH_CFG1, 0x02, 0x02);
+		/* Set the ATTK1 gain */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1,
+			0xFF, 0xFF);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2,
+			0xFF, 0x03);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3,
+			0xFF, 0x00);
+		/* Set the ATTK2 gain */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4,
+			0xFF, 0xFF);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5,
+			0xFF, 0x03);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6,
+			0xFF, 0x00);
+		/* Set the ATTK3 gain */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7,
+			0xFF, 0xFF);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8,
+			0xFF, 0x03);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9,
+			0xFF, 0x00);
+		break;
+
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_RX2_RX_PATH_CFG1,
+				0x80, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_RX2_RX_PATH_SEC7,
+				0x02, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_BCL_VBAT_CFG,
+				0x02, 0x02);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_RX2_RX_PATH_CFG1,
+				0x02, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1,
+				0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2,
+				0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3,
+				0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4,
+				0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5,
+				0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6,
+				0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7,
+				0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8,
+				0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9,
+				0xFF, 0x00);
+		lpass_cdc_rx_macro_enable_softclip_clk(component, rx_priv, false);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_CFG, 0x01, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_PATH_CTL, 0x10, 0x00);
+		break;
+	default:
+		dev_err(rx_dev, "%s: Invalid event %d\n", __func__, event);
+		break;
+	}
+	return 0;
+}
+
+static void lpass_cdc_rx_macro_idle_detect_control(struct snd_soc_component *component,
+					 struct lpass_cdc_rx_macro_priv *rx_priv,
+					 int interp, int event)
+{
+	int reg = 0, mask = 0, val = 0;
+
+	if (!rx_priv->idle_det_cfg.hph_idle_detect_en)
+		return;
+
+	if (interp == INTERP_HPHL) {
+		reg = LPASS_CDC_RX_IDLE_DETECT_PATH_CTL;
+		mask = 0x01;
+		val = 0x01;
+	}
+	if (interp == INTERP_HPHR) {
+		reg = LPASS_CDC_RX_IDLE_DETECT_PATH_CTL;
+		mask = 0x02;
+		val = 0x02;
+	}
+
+	if (reg && SND_SOC_DAPM_EVENT_ON(event))
+		snd_soc_component_update_bits(component, reg, mask, val);
+
+	if (reg && SND_SOC_DAPM_EVENT_OFF(event)) {
+		snd_soc_component_update_bits(component, reg, mask, 0x00);
+		rx_priv->idle_det_cfg.hph_idle_thr = 0;
+		snd_soc_component_write(component,
+				LPASS_CDC_RX_IDLE_DETECT_CFG3, 0x0);
+	}
+}
+
+static void lpass_cdc_rx_macro_hphdelay_lutbypass(struct snd_soc_component *component,
+					struct lpass_cdc_rx_macro_priv *rx_priv,
+					u16 interp_idx, int event)
+{
+	u16 hph_lut_bypass_reg = 0;
+	u16 hph_comp_ctrl7 = 0;
+
+	switch (interp_idx) {
+	case INTERP_HPHL:
+		hph_lut_bypass_reg = LPASS_CDC_RX_TOP_HPHL_COMP_LUT;
+		hph_comp_ctrl7 = LPASS_CDC_RX_COMPANDER0_CTL7;
+		break;
+	case INTERP_HPHR:
+		hph_lut_bypass_reg = LPASS_CDC_RX_TOP_HPHR_COMP_LUT;
+		hph_comp_ctrl7 = LPASS_CDC_RX_COMPANDER1_CTL7;
+		break;
+	default:
+		break;
+	}
+
+	if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) {
+		if (interp_idx == INTERP_HPHL) {
+			if (rx_priv->is_ear_mode_on)
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_RX_RX0_RX_PATH_CFG1,
+					0x02, 0x02);
+			else
+				snd_soc_component_update_bits(component,
+					hph_lut_bypass_reg,
+					0x80, 0x80);
+		} else {
+			snd_soc_component_update_bits(component,
+					hph_lut_bypass_reg,
+					0x80, 0x80);
+		}
+		if (rx_priv->hph_pwr_mode)
+			snd_soc_component_update_bits(component,
+					hph_comp_ctrl7,
+					0x20, 0x00);
+	}
+
+	if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
+		snd_soc_component_update_bits(component,
+					LPASS_CDC_RX_RX0_RX_PATH_CFG1,
+					0x02, 0x00);
+		snd_soc_component_update_bits(component, hph_lut_bypass_reg,
+					0x80, 0x00);
+		snd_soc_component_update_bits(component, hph_comp_ctrl7,
+					0x20, 0x20);
+	}
+}
+
+static int lpass_cdc_rx_macro_enable_interp_clk(struct snd_soc_component *component,
+				      int event, int interp_idx)
+{
+	u16 main_reg = 0, dsm_reg = 0, rx_cfg2_reg = 0;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!component) {
+		pr_err("%s: component is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	main_reg = LPASS_CDC_RX_RX0_RX_PATH_CTL +
+			(interp_idx * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+	dsm_reg = LPASS_CDC_RX_RX0_RX_PATH_DSM_CTL +
+			(interp_idx * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+	if (interp_idx == INTERP_AUX)
+		dsm_reg = LPASS_CDC_RX_RX2_RX_PATH_DSM_CTL;
+	rx_cfg2_reg = LPASS_CDC_RX_RX0_RX_PATH_CFG2 +
+			(interp_idx * LPASS_CDC_RX_MACRO_RX_PATH_OFFSET);
+
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		if (rx_priv->main_clk_users[interp_idx] == 0) {
+			/* Main path PGA mute enable */
+			snd_soc_component_update_bits(component, main_reg,
+					0x10, 0x10);
+			snd_soc_component_update_bits(component, dsm_reg,
+					0x01, 0x01);
+			snd_soc_component_update_bits(component, rx_cfg2_reg,
+					0x03, 0x03);
+			lpass_cdc_rx_macro_load_compander_coeff(component, rx_priv,
+						      interp_idx, event);
+			lpass_cdc_rx_macro_idle_detect_control(component, rx_priv,
+					interp_idx, event);
+			if (rx_priv->hph_hd2_mode)
+				lpass_cdc_rx_macro_hd2_control(
+					component, interp_idx, event);
+			lpass_cdc_rx_macro_hphdelay_lutbypass(component, rx_priv,
+						    interp_idx, event);
+			lpass_cdc_rx_macro_config_compander(component, rx_priv,
+						interp_idx, event);
+			if (interp_idx == INTERP_AUX) {
+				lpass_cdc_rx_macro_config_softclip(component, rx_priv,
+							event);
+				lpass_cdc_rx_macro_config_aux_hpf(component, rx_priv,
+							event);
+			}
+			lpass_cdc_rx_macro_config_classh(component, rx_priv,
+						interp_idx, event);
+		}
+		rx_priv->main_clk_users[interp_idx]++;
+	}
+
+	if (SND_SOC_DAPM_EVENT_OFF(event)) {
+		rx_priv->main_clk_users[interp_idx]--;
+		if (rx_priv->main_clk_users[interp_idx] <= 0) {
+			rx_priv->main_clk_users[interp_idx] = 0;
+			/* Main path PGA mute enable */
+			snd_soc_component_update_bits(component, main_reg,
+					0x10, 0x10);
+			/* Clk Disable */
+			snd_soc_component_update_bits(component, dsm_reg,
+						0x01, 0x00);
+			snd_soc_component_update_bits(component, main_reg,
+						0x20, 0x00);
+			/* Reset enable and disable */
+			snd_soc_component_update_bits(component, main_reg,
+						0x40, 0x40);
+			snd_soc_component_update_bits(component, main_reg,
+						0x40, 0x00);
+			/* Reset rate to 48K*/
+			snd_soc_component_update_bits(component, main_reg,
+						0x0F, 0x04);
+			snd_soc_component_update_bits(component, rx_cfg2_reg,
+						0x03, 0x00);
+			lpass_cdc_rx_macro_config_classh(component, rx_priv,
+						interp_idx, event);
+			lpass_cdc_rx_macro_config_compander(component, rx_priv,
+						interp_idx, event);
+			if (interp_idx ==  INTERP_AUX) {
+				lpass_cdc_rx_macro_config_softclip(component, rx_priv,
+							event);
+				lpass_cdc_rx_macro_config_aux_hpf(component, rx_priv,
+				event);
+			}
+			lpass_cdc_rx_macro_hphdelay_lutbypass(component, rx_priv,
+						interp_idx, event);
+			if (rx_priv->hph_hd2_mode)
+				lpass_cdc_rx_macro_hd2_control(component, interp_idx,
+						event);
+			lpass_cdc_rx_macro_idle_detect_control(component, rx_priv,
+					interp_idx, event);
+		}
+	}
+
+	dev_dbg(component->dev, "%s event %d main_clk_users %d\n",
+		__func__,  event, rx_priv->main_clk_users[interp_idx]);
+
+	return rx_priv->main_clk_users[interp_idx];
+}
+
+static int lpass_cdc_rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w,
+				  struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	u16 sidetone_reg = 0, fs_reg = 0;
+
+	dev_dbg(component->dev, "%s %d %d\n", __func__, event, w->shift);
+	sidetone_reg = LPASS_CDC_RX_RX0_RX_PATH_CFG1 +
+			LPASS_CDC_RX_MACRO_RX_PATH_OFFSET * (w->shift);
+	fs_reg = LPASS_CDC_RX_RX0_RX_PATH_CTL +
+			LPASS_CDC_RX_MACRO_RX_PATH_OFFSET * (w->shift);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		lpass_cdc_rx_macro_enable_interp_clk(component, event, w->shift);
+		snd_soc_component_update_bits(component, sidetone_reg,
+					0x10, 0x10);
+		snd_soc_component_update_bits(component, fs_reg,
+					0x20, 0x20);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_component_update_bits(component, sidetone_reg,
+					0x10, 0x00);
+		lpass_cdc_rx_macro_enable_interp_clk(component, event, w->shift);
+		break;
+	default:
+		break;
+	};
+	return 0;
+}
+
+static void lpass_cdc_rx_macro_restore_iir_coeff(struct lpass_cdc_rx_macro_priv *rx_priv, int iir_idx,
+				int band_idx)
+{
+	u16 reg_add = 0, coeff_idx = 0, idx = 0;
+	struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
+
+	if (regmap == NULL) {
+		dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
+		return;
+	}
+
+	regmap_write(regmap,
+		(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
+		(band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
+
+	reg_add = LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx;
+
+	/* 5 coefficients per band and 4 writes per coefficient */
+	for (coeff_idx = 0; coeff_idx < LPASS_CDC_RX_MACRO_SIDETONE_IIR_COEFF_MAX;
+		coeff_idx++) {
+		/* Four 8 bit values(one 32 bit) per coefficient */
+		regmap_write(regmap, reg_add,
+		rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
+		regmap_write(regmap, reg_add,
+		rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
+		regmap_write(regmap, reg_add,
+		rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
+		regmap_write(regmap, reg_add,
+		rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++]);
+	}
+}
+
+static int lpass_cdc_rx_macro_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+	/* IIR filter band registers are at integer multiples of 0x80 */
+	u16 iir_reg = LPASS_CDC_RX_SIDETONE_IIR0_IIR_CTL + 0x80 * iir_idx;
+
+	ucontrol->value.integer.value[0] = (
+				snd_soc_component_read32(component, iir_reg) &
+				(1 << band_idx)) != 0;
+
+	dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
+		iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[0]);
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+	bool iir_band_en_status = 0;
+	int value = ucontrol->value.integer.value[0];
+	u16 iir_reg = LPASS_CDC_RX_SIDETONE_IIR0_IIR_CTL + 0x80 * iir_idx;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	lpass_cdc_rx_macro_restore_iir_coeff(rx_priv, iir_idx, band_idx);
+
+	/* Mask first 5 bits, 6-8 are reserved */
+	snd_soc_component_update_bits(component, iir_reg, (1 << band_idx),
+			    (value << band_idx));
+
+	iir_band_en_status = ((snd_soc_component_read32(component, iir_reg) &
+			      (1 << band_idx)) != 0);
+	dev_dbg(component->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
+		iir_idx, band_idx, iir_band_en_status);
+	return 0;
+}
+
+static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
+				   int iir_idx, int band_idx,
+				   int coeff_idx)
+{
+	uint32_t value = 0;
+
+	/* Address does not automatically update if reading */
+	snd_soc_component_write(component,
+		(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
+		((band_idx * BAND_MAX + coeff_idx)
+		* sizeof(uint32_t)) & 0x7F);
+
+	value |= snd_soc_component_read32(component,
+		(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx));
+
+	snd_soc_component_write(component,
+		(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
+		((band_idx * BAND_MAX + coeff_idx)
+		* sizeof(uint32_t) + 1) & 0x7F);
+
+	value |= (snd_soc_component_read32(component,
+			       (LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
+				0x80 * iir_idx)) << 8);
+
+	snd_soc_component_write(component,
+		(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
+		((band_idx * BAND_MAX + coeff_idx)
+		* sizeof(uint32_t) + 2) & 0x7F);
+
+	value |= (snd_soc_component_read32(component,
+			       (LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
+				0x80 * iir_idx)) << 16);
+
+	snd_soc_component_write(component,
+		(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx),
+		((band_idx * BAND_MAX + coeff_idx)
+		* sizeof(uint32_t) + 3) & 0x7F);
+
+	/* Mask bits top 2 bits since they are reserved */
+	value |= ((snd_soc_component_read32(component,
+				(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL +
+				 16 * iir_idx)) & 0x3F) << 24);
+
+	return value;
+}
+
+static int lpass_cdc_rx_macro_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+
+	ucontrol->value.integer.value[0] =
+		get_iir_band_coeff(component, iir_idx, band_idx, 0);
+	ucontrol->value.integer.value[1] =
+		get_iir_band_coeff(component, iir_idx, band_idx, 1);
+	ucontrol->value.integer.value[2] =
+		get_iir_band_coeff(component, iir_idx, band_idx, 2);
+	ucontrol->value.integer.value[3] =
+		get_iir_band_coeff(component, iir_idx, band_idx, 3);
+	ucontrol->value.integer.value[4] =
+		get_iir_band_coeff(component, iir_idx, band_idx, 4);
+
+	dev_dbg(component->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
+		"%s: IIR #%d band #%d b1 = 0x%x\n"
+		"%s: IIR #%d band #%d b2 = 0x%x\n"
+		"%s: IIR #%d band #%d a1 = 0x%x\n"
+		"%s: IIR #%d band #%d a2 = 0x%x\n",
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[0],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[1],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[2],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[3],
+		__func__, iir_idx, band_idx,
+		(uint32_t)ucontrol->value.integer.value[4]);
+	return 0;
+}
+
+static void set_iir_band_coeff(struct snd_soc_component *component,
+			       int iir_idx, int band_idx,
+			       uint32_t value)
+{
+	snd_soc_component_write(component,
+		(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
+		(value & 0xFF));
+
+	snd_soc_component_write(component,
+		(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
+		(value >> 8) & 0xFF);
+
+	snd_soc_component_write(component,
+		(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
+		(value >> 16) & 0xFF);
+
+	/* Mask top 2 bits, 7-8 are reserved */
+	snd_soc_component_write(component,
+		(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx),
+		(value >> 24) & 0x3F);
+}
+
+static int lpass_cdc_rx_macro_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	int iir_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->reg;
+	int band_idx = ((struct soc_multi_mixer_control *)
+					kcontrol->private_value)->shift;
+	int coeff_idx, idx = 0;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	/*
+	 * Mask top bit it is reserved
+	 * Updates addr automatically for each B2 write
+	 */
+	snd_soc_component_write(component,
+		(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
+		(band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
+
+	/* Store the coefficients in sidetone coeff array */
+	for (coeff_idx = 0; coeff_idx < LPASS_CDC_RX_MACRO_SIDETONE_IIR_COEFF_MAX;
+		coeff_idx++) {
+		uint32_t value = ucontrol->value.integer.value[coeff_idx];
+
+		set_iir_band_coeff(component, iir_idx, band_idx, value);
+
+		/* Four 8 bit values(one 32 bit) per coefficient */
+		rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+								(value & 0xFF);
+		rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+							 (value >> 8) & 0xFF;
+		rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+							 (value >> 16) & 0xFF;
+		rx_priv->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+							 (value >> 24) & 0xFF;
+	}
+
+	pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
+		"%s: IIR #%d band #%d b1 = 0x%x\n"
+		"%s: IIR #%d band #%d b2 = 0x%x\n"
+		"%s: IIR #%d band #%d a1 = 0x%x\n"
+		"%s: IIR #%d band #%d a2 = 0x%x\n",
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(component, iir_idx, band_idx, 0),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(component, iir_idx, band_idx, 1),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(component, iir_idx, band_idx, 2),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(component, iir_idx, band_idx, 3),
+		__func__, iir_idx, band_idx,
+		get_iir_band_coeff(component, iir_idx, band_idx, 4));
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_set_iir_gain(struct snd_soc_dapm_widget *w,
+				    struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+
+	dev_dbg(component->dev, "%s: event = %d\n", __func__, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU: /* fall through */
+	case SND_SOC_DAPM_PRE_PMD:
+		if (strnstr(w->name, "IIR0", sizeof("IIR0"))) {
+			snd_soc_component_write(component,
+				LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL,
+			snd_soc_component_read32(component,
+				LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL));
+			snd_soc_component_write(component,
+				LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL,
+			snd_soc_component_read32(component,
+				LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL));
+			snd_soc_component_write(component,
+				LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL,
+			snd_soc_component_read32(component,
+				LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL));
+			snd_soc_component_write(component,
+				LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL,
+			snd_soc_component_read32(component,
+				LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL));
+		} else {
+			snd_soc_component_write(component,
+				LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL,
+			snd_soc_component_read32(component,
+				LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL));
+			snd_soc_component_write(component,
+				LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL,
+			snd_soc_component_read32(component,
+				LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL));
+			snd_soc_component_write(component,
+				LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL,
+			snd_soc_component_read32(component,
+				LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL));
+			snd_soc_component_write(component,
+				LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL,
+			snd_soc_component_read32(component,
+				LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL));
+		}
+		break;
+	}
+	return 0;
+}
+
+static const struct snd_kcontrol_new lpass_cdc_rx_macro_snd_controls[] = {
+	SOC_SINGLE_S8_TLV("RX_RX0 Digital Volume",
+			  LPASS_CDC_RX_RX0_RX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("RX_RX1 Digital Volume",
+			  LPASS_CDC_RX_RX1_RX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("RX_RX2 Digital Volume",
+			  LPASS_CDC_RX_RX2_RX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("RX_RX0 Mix Digital Volume",
+			  LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("RX_RX1 Mix Digital Volume",
+			  LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("RX_RX2 Mix Digital Volume",
+			  LPASS_CDC_RX_RX2_RX_VOL_MIX_CTL,
+			  -84, 40, digital_gain),
+
+	SOC_SINGLE_EXT("RX_COMP1 Switch", SND_SOC_NOPM, LPASS_CDC_RX_MACRO_COMP1, 1, 0,
+		lpass_cdc_rx_macro_get_compander, lpass_cdc_rx_macro_set_compander),
+	SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, LPASS_CDC_RX_MACRO_COMP2, 1, 0,
+		lpass_cdc_rx_macro_get_compander, lpass_cdc_rx_macro_set_compander),
+
+	SOC_ENUM_EXT("HPH Idle Detect", hph_idle_detect_enum,
+		lpass_cdc_rx_macro_hph_idle_detect_get, lpass_cdc_rx_macro_hph_idle_detect_put),
+
+	SOC_ENUM_EXT("RX_EAR Mode", lpass_cdc_rx_macro_ear_mode_enum,
+		lpass_cdc_rx_macro_get_ear_mode, lpass_cdc_rx_macro_put_ear_mode),
+
+	SOC_ENUM_EXT("RX_HPH HD2 Mode", lpass_cdc_rx_macro_hph_hd2_mode_enum,
+		lpass_cdc_rx_macro_get_hph_hd2_mode, lpass_cdc_rx_macro_put_hph_hd2_mode),
+
+	SOC_ENUM_EXT("RX_HPH_PWR_MODE", lpass_cdc_rx_macro_hph_pwr_mode_enum,
+		lpass_cdc_rx_macro_get_hph_pwr_mode, lpass_cdc_rx_macro_put_hph_pwr_mode),
+
+	SOC_ENUM_EXT("RX_GSM mode Enable", lpass_cdc_rx_macro_vbat_bcl_gsm_mode_enum,
+			lpass_cdc_rx_macro_vbat_bcl_gsm_mode_func_get,
+			lpass_cdc_rx_macro_vbat_bcl_gsm_mode_func_put),
+	SOC_SINGLE_EXT("RX_Softclip Enable", SND_SOC_NOPM, 0, 1, 0,
+		     lpass_cdc_rx_macro_soft_clip_enable_get,
+		     lpass_cdc_rx_macro_soft_clip_enable_put),
+	SOC_SINGLE_EXT("AUX_HPF Enable", SND_SOC_NOPM, 0, 1, 0,
+			lpass_cdc_rx_macro_aux_hpf_mode_get,
+			lpass_cdc_rx_macro_aux_hpf_mode_put),
+
+	SOC_SINGLE_S8_TLV("IIR0 INP0 Volume",
+		LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, -84, 40,
+		digital_gain),
+	SOC_SINGLE_S8_TLV("IIR0 INP1 Volume",
+		LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, -84, 40,
+		digital_gain),
+	SOC_SINGLE_S8_TLV("IIR0 INP2 Volume",
+		LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, -84, 40,
+		digital_gain),
+	SOC_SINGLE_S8_TLV("IIR0 INP3 Volume",
+		LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, -84, 40,
+		digital_gain),
+	SOC_SINGLE_S8_TLV("IIR1 INP0 Volume",
+		LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, -84, 40,
+		digital_gain),
+	SOC_SINGLE_S8_TLV("IIR1 INP1 Volume",
+		LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, -84, 40,
+		digital_gain),
+	SOC_SINGLE_S8_TLV("IIR1 INP2 Volume",
+		LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, -84, 40,
+		digital_gain),
+	SOC_SINGLE_S8_TLV("IIR1 INP3 Volume",
+		LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, -84, 40,
+		digital_gain),
+
+	SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_put),
+	SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_put),
+	SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_put),
+	SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_put),
+	SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_put),
+	SOC_SINGLE_EXT("IIR1 Enable Band1", IIR1, BAND1, 1, 0,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_put),
+	SOC_SINGLE_EXT("IIR1 Enable Band2", IIR1, BAND2, 1, 0,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_put),
+	SOC_SINGLE_EXT("IIR1 Enable Band3", IIR1, BAND3, 1, 0,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_put),
+	SOC_SINGLE_EXT("IIR1 Enable Band4", IIR1, BAND4, 1, 0,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_put),
+	SOC_SINGLE_EXT("IIR1 Enable Band5", IIR1, BAND5, 1, 0,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_enable_audio_mixer_put),
+
+	SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_put),
+	SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_put),
+	SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_put),
+	SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_put),
+	SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_put),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band1", IIR1, BAND1, 255, 0, 5,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_put),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band2", IIR1, BAND2, 255, 0, 5,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_put),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band3", IIR1, BAND3, 255, 0, 5,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_put),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band4", IIR1, BAND4, 255, 0, 5,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_put),
+	SOC_SINGLE_MULTI_EXT("IIR1 Band5", IIR1, BAND5, 255, 0, 5,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_get,
+		lpass_cdc_rx_macro_iir_band_audio_mixer_put),
+};
+
+static int lpass_cdc_rx_macro_enable_echo(struct snd_soc_dapm_widget *w,
+				struct snd_kcontrol *kcontrol,
+				int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	u16 val = 0, ec_hq_reg = 0;
+	int ec_tx = 0;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(rx_dev, "%s %d %s\n", __func__, event, w->name);
+
+	val = snd_soc_component_read32(component,
+			LPASS_CDC_RX_INP_MUX_RX_MIX_CFG4);
+	if (!(strcmp(w->name, "RX MIX TX0 MUX")))
+		ec_tx = ((val & 0xf0) >> 0x4) - 1;
+	else if (!(strcmp(w->name, "RX MIX TX1 MUX")))
+		ec_tx = (val & 0x0f) - 1;
+
+	val = snd_soc_component_read32(component,
+			LPASS_CDC_RX_INP_MUX_RX_MIX_CFG5);
+	if (!(strcmp(w->name, "RX MIX TX2 MUX")))
+		ec_tx = (val & 0x0f) - 1;
+
+	if (ec_tx < 0 || (ec_tx >= LPASS_CDC_RX_MACRO_EC_MUX_MAX)) {
+		dev_err(rx_dev, "%s: EC mix control not set correctly\n",
+			__func__);
+		return -EINVAL;
+	}
+	ec_hq_reg = LPASS_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL +
+			    0x40 * ec_tx;
+	snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
+	ec_hq_reg = LPASS_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 +
+				0x40 * ec_tx;
+	/* default set to 48k */
+	snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
+
+	return 0;
+}
+
+static const struct snd_soc_dapm_widget lpass_cdc_rx_macro_dapm_widgets[] = {
+	SND_SOC_DAPM_AIF_IN("RX AIF1 PB", "RX_MACRO_AIF1 Playback", 0,
+		SND_SOC_NOPM, 0, 0),
+
+	SND_SOC_DAPM_AIF_IN("RX AIF2 PB", "RX_MACRO_AIF2 Playback", 0,
+		SND_SOC_NOPM, 0, 0),
+
+	SND_SOC_DAPM_AIF_IN("RX AIF3 PB", "RX_MACRO_AIF3 Playback", 0,
+		SND_SOC_NOPM, 0, 0),
+
+	SND_SOC_DAPM_AIF_IN("RX AIF4 PB", "RX_MACRO_AIF4 Playback", 0,
+		SND_SOC_NOPM, 0, 0),
+
+	SND_SOC_DAPM_AIF_OUT("RX AIF_ECHO", "RX_AIF_ECHO Capture", 0,
+		SND_SOC_NOPM, 0, 0),
+
+	SND_SOC_DAPM_AIF_IN("RX AIF5 PB", "RX_MACRO_AIF5 Playback", 0,
+		SND_SOC_NOPM, 0, 0),
+
+	SND_SOC_DAPM_AIF_IN("RX AIF6 PB", "RX_MACRO_AIF6 Playback", 0,
+		SND_SOC_NOPM, 0, 0),
+
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX_MACRO RX0 MUX", LPASS_CDC_RX_MACRO_RX0, lpass_cdc_rx_macro_rx0),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX_MACRO RX1 MUX", LPASS_CDC_RX_MACRO_RX1, lpass_cdc_rx_macro_rx1),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX_MACRO RX2 MUX", LPASS_CDC_RX_MACRO_RX2, lpass_cdc_rx_macro_rx2),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX_MACRO RX3 MUX", LPASS_CDC_RX_MACRO_RX3, lpass_cdc_rx_macro_rx3),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX_MACRO RX4 MUX", LPASS_CDC_RX_MACRO_RX4, lpass_cdc_rx_macro_rx4),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX_MACRO RX5 MUX", LPASS_CDC_RX_MACRO_RX5, lpass_cdc_rx_macro_rx5),
+
+	SND_SOC_DAPM_MIXER("RX_RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX_RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX_RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX_RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX_RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX_RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	LPASS_CDC_RX_MACRO_DAPM_MUX("IIR0 INP0 MUX", 0, iir0_inp0),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("IIR0 INP1 MUX", 0, iir0_inp1),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("IIR0 INP2 MUX", 0, iir0_inp2),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("IIR0 INP3 MUX", 0, iir0_inp3),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("IIR1 INP0 MUX", 0, iir1_inp0),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("IIR1 INP1 MUX", 0, iir1_inp1),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("IIR1 INP2 MUX", 0, iir1_inp2),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("IIR1 INP3 MUX", 0, iir1_inp3),
+
+	SND_SOC_DAPM_MUX_E("RX MIX TX0 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_RX_MACRO_EC0_MUX, 0,
+			   &rx_mix_tx0_mux, lpass_cdc_rx_macro_enable_echo,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("RX MIX TX1 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_RX_MACRO_EC1_MUX, 0,
+			   &rx_mix_tx1_mux, lpass_cdc_rx_macro_enable_echo,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("RX MIX TX2 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_RX_MACRO_EC2_MUX, 0,
+			   &rx_mix_tx2_mux, lpass_cdc_rx_macro_enable_echo,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MIXER_E("IIR0", LPASS_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL,
+		4, 0, NULL, 0, lpass_cdc_rx_macro_set_iir_gain,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+	SND_SOC_DAPM_MIXER_E("IIR1", LPASS_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL,
+		4, 0, NULL, 0, lpass_cdc_rx_macro_set_iir_gain,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+	SND_SOC_DAPM_MIXER("SRC0", LPASS_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL,
+		4, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("SRC1", LPASS_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL,
+		4, 0, NULL, 0),
+
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT0 DEM MUX", 0, rx_int0_dem_inp),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT1 DEM MUX", 0, rx_int1_dem_inp),
+
+	SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0,
+		&rx_int0_2_mux, lpass_cdc_rx_macro_enable_mix_path,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0,
+		&rx_int1_2_mux, lpass_cdc_rx_macro_enable_mix_path,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", SND_SOC_NOPM, INTERP_AUX, 0,
+		&rx_int2_2_mux, lpass_cdc_rx_macro_enable_mix_path,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP0", 0, rx_int0_1_mix_inp0),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP1", 0, rx_int0_1_mix_inp1),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT0_1 MIX1 INP2", 0, rx_int0_1_mix_inp2),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP0", 0, rx_int1_1_mix_inp0),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP1", 0, rx_int1_1_mix_inp1),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT1_1 MIX1 INP2", 0, rx_int1_1_mix_inp2),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP0", 0, rx_int2_1_mix_inp0),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP1", 0, rx_int2_1_mix_inp1),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT2_1 MIX1 INP2", 0, rx_int2_1_mix_inp2),
+
+	SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_HPHL, 0,
+		&rx_int0_1_interp_mux, lpass_cdc_rx_macro_enable_main_path,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("RX INT1_1 INTERP", SND_SOC_NOPM, INTERP_HPHR, 0,
+		&rx_int1_1_interp_mux, lpass_cdc_rx_macro_enable_main_path,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("RX INT2_1 INTERP", SND_SOC_NOPM, INTERP_AUX, 0,
+		&rx_int2_1_interp_mux, lpass_cdc_rx_macro_enable_main_path,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT0_2 INTERP", 0, rx_int0_2_interp),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT1_2 INTERP", 0, rx_int1_2_interp),
+	LPASS_CDC_RX_MACRO_DAPM_MUX("RX INT2_2 INTERP", 0, rx_int2_2_interp),
+
+	SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_HPHL,
+		0, &rx_int0_mix2_inp_mux, lpass_cdc_rx_macro_enable_rx_path_clk,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("RX INT1 MIX2 INP", SND_SOC_NOPM, INTERP_HPHR,
+		0, &rx_int1_mix2_inp_mux, lpass_cdc_rx_macro_enable_rx_path_clk,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("RX INT2 MIX2 INP", SND_SOC_NOPM, INTERP_AUX,
+		0, &rx_int2_mix2_inp_mux, lpass_cdc_rx_macro_enable_rx_path_clk,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MIXER_E("RX INT2_1 VBAT", SND_SOC_NOPM,
+		0, 0, rx_int2_1_vbat_mix_switch,
+		ARRAY_SIZE(rx_int2_1_vbat_mix_switch),
+		lpass_cdc_rx_macro_enable_vbat,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_OUTPUT("HPHL_OUT"),
+	SND_SOC_DAPM_OUTPUT("HPHR_OUT"),
+	SND_SOC_DAPM_OUTPUT("AUX_OUT"),
+	SND_SOC_DAPM_OUTPUT("PCM_OUT"),
+
+	SND_SOC_DAPM_INPUT("RX_TX DEC0_INP"),
+	SND_SOC_DAPM_INPUT("RX_TX DEC1_INP"),
+	SND_SOC_DAPM_INPUT("RX_TX DEC2_INP"),
+	SND_SOC_DAPM_INPUT("RX_TX DEC3_INP"),
+
+	SND_SOC_DAPM_SUPPLY_S("RX_MCLK", 0, SND_SOC_NOPM, 0, 0,
+	lpass_cdc_rx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_route rx_audio_map[] = {
+	{"RX AIF1 PB", NULL, "RX_MCLK"},
+	{"RX AIF2 PB", NULL, "RX_MCLK"},
+	{"RX AIF3 PB", NULL, "RX_MCLK"},
+	{"RX AIF4 PB", NULL, "RX_MCLK"},
+
+	{"RX AIF6 PB", NULL, "RX_MCLK"},
+	{"PCM_OUT", NULL, "RX AIF6 PB"},
+
+	{"RX_MACRO RX0 MUX", "AIF1_PB", "RX AIF1 PB"},
+	{"RX_MACRO RX1 MUX", "AIF1_PB", "RX AIF1 PB"},
+	{"RX_MACRO RX2 MUX", "AIF1_PB", "RX AIF1 PB"},
+	{"RX_MACRO RX3 MUX", "AIF1_PB", "RX AIF1 PB"},
+	{"RX_MACRO RX4 MUX", "AIF1_PB", "RX AIF1 PB"},
+	{"RX_MACRO RX5 MUX", "AIF1_PB", "RX AIF1 PB"},
+
+	{"RX_MACRO RX0 MUX", "AIF2_PB", "RX AIF2 PB"},
+	{"RX_MACRO RX1 MUX", "AIF2_PB", "RX AIF2 PB"},
+	{"RX_MACRO RX2 MUX", "AIF2_PB", "RX AIF2 PB"},
+	{"RX_MACRO RX3 MUX", "AIF2_PB", "RX AIF2 PB"},
+	{"RX_MACRO RX4 MUX", "AIF2_PB", "RX AIF2 PB"},
+	{"RX_MACRO RX5 MUX", "AIF2_PB", "RX AIF2 PB"},
+
+	{"RX_MACRO RX0 MUX", "AIF3_PB", "RX AIF3 PB"},
+	{"RX_MACRO RX1 MUX", "AIF3_PB", "RX AIF3 PB"},
+	{"RX_MACRO RX2 MUX", "AIF3_PB", "RX AIF3 PB"},
+	{"RX_MACRO RX3 MUX", "AIF3_PB", "RX AIF3 PB"},
+	{"RX_MACRO RX4 MUX", "AIF3_PB", "RX AIF3 PB"},
+	{"RX_MACRO RX5 MUX", "AIF3_PB", "RX AIF3 PB"},
+
+	{"RX_MACRO RX0 MUX", "AIF4_PB", "RX AIF4 PB"},
+	{"RX_MACRO RX1 MUX", "AIF4_PB", "RX AIF4 PB"},
+	{"RX_MACRO RX2 MUX", "AIF4_PB", "RX AIF4 PB"},
+	{"RX_MACRO RX3 MUX", "AIF4_PB", "RX AIF4 PB"},
+	{"RX_MACRO RX4 MUX", "AIF4_PB", "RX AIF4 PB"},
+	{"RX_MACRO RX5 MUX", "AIF4_PB", "RX AIF4 PB"},
+
+	{"RX_RX0", NULL, "RX_MACRO RX0 MUX"},
+	{"RX_RX1", NULL, "RX_MACRO RX1 MUX"},
+	{"RX_RX2", NULL, "RX_MACRO RX2 MUX"},
+	{"RX_RX3", NULL, "RX_MACRO RX3 MUX"},
+	{"RX_RX4", NULL, "RX_MACRO RX4 MUX"},
+	{"RX_RX5", NULL, "RX_MACRO RX5 MUX"},
+
+	{"RX INT0_1 MIX1 INP0", "RX0", "RX_RX0"},
+	{"RX INT0_1 MIX1 INP0", "RX1", "RX_RX1"},
+	{"RX INT0_1 MIX1 INP0", "RX2", "RX_RX2"},
+	{"RX INT0_1 MIX1 INP0", "RX3", "RX_RX3"},
+	{"RX INT0_1 MIX1 INP0", "RX4", "RX_RX4"},
+	{"RX INT0_1 MIX1 INP0", "RX5", "RX_RX5"},
+	{"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"},
+	{"RX INT0_1 MIX1 INP0", "IIR1", "IIR1"},
+	{"RX INT0_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"},
+	{"RX INT0_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"},
+	{"RX INT0_1 MIX1 INP1", "RX0", "RX_RX0"},
+	{"RX INT0_1 MIX1 INP1", "RX1", "RX_RX1"},
+	{"RX INT0_1 MIX1 INP1", "RX2", "RX_RX2"},
+	{"RX INT0_1 MIX1 INP1", "RX3", "RX_RX3"},
+	{"RX INT0_1 MIX1 INP1", "RX4", "RX_RX4"},
+	{"RX INT0_1 MIX1 INP1", "RX5", "RX_RX5"},
+	{"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"},
+	{"RX INT0_1 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX INT0_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"},
+	{"RX INT0_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"},
+	{"RX INT0_1 MIX1 INP2", "RX0", "RX_RX0"},
+	{"RX INT0_1 MIX1 INP2", "RX1", "RX_RX1"},
+	{"RX INT0_1 MIX1 INP2", "RX2", "RX_RX2"},
+	{"RX INT0_1 MIX1 INP2", "RX3", "RX_RX3"},
+	{"RX INT0_1 MIX1 INP2", "RX4", "RX_RX4"},
+	{"RX INT0_1 MIX1 INP2", "RX5", "RX_RX5"},
+	{"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"},
+	{"RX INT0_1 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX INT0_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"},
+	{"RX INT0_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"},
+
+	{"RX INT1_1 MIX1 INP0", "RX0", "RX_RX0"},
+	{"RX INT1_1 MIX1 INP0", "RX1", "RX_RX1"},
+	{"RX INT1_1 MIX1 INP0", "RX2", "RX_RX2"},
+	{"RX INT1_1 MIX1 INP0", "RX3", "RX_RX3"},
+	{"RX INT1_1 MIX1 INP0", "RX4", "RX_RX4"},
+	{"RX INT1_1 MIX1 INP0", "RX5", "RX_RX5"},
+	{"RX INT1_1 MIX1 INP0", "IIR0", "IIR0"},
+	{"RX INT1_1 MIX1 INP0", "IIR1", "IIR1"},
+	{"RX INT1_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"},
+	{"RX INT1_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"},
+	{"RX INT1_1 MIX1 INP1", "RX0", "RX_RX0"},
+	{"RX INT1_1 MIX1 INP1", "RX1", "RX_RX1"},
+	{"RX INT1_1 MIX1 INP1", "RX2", "RX_RX2"},
+	{"RX INT1_1 MIX1 INP1", "RX3", "RX_RX3"},
+	{"RX INT1_1 MIX1 INP1", "RX4", "RX_RX4"},
+	{"RX INT1_1 MIX1 INP1", "RX5", "RX_RX5"},
+	{"RX INT1_1 MIX1 INP1", "IIR0", "IIR0"},
+	{"RX INT1_1 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX INT1_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"},
+	{"RX INT1_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"},
+	{"RX INT1_1 MIX1 INP2", "RX0", "RX_RX0"},
+	{"RX INT1_1 MIX1 INP2", "RX1", "RX_RX1"},
+	{"RX INT1_1 MIX1 INP2", "RX2", "RX_RX2"},
+	{"RX INT1_1 MIX1 INP2", "RX3", "RX_RX3"},
+	{"RX INT1_1 MIX1 INP2", "RX4", "RX_RX4"},
+	{"RX INT1_1 MIX1 INP2", "RX5", "RX_RX5"},
+	{"RX INT1_1 MIX1 INP2", "IIR0", "IIR0"},
+	{"RX INT1_1 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX INT1_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"},
+	{"RX INT1_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"},
+
+	{"RX INT2_1 MIX1 INP0", "RX0", "RX_RX0"},
+	{"RX INT2_1 MIX1 INP0", "RX1", "RX_RX1"},
+	{"RX INT2_1 MIX1 INP0", "RX2", "RX_RX2"},
+	{"RX INT2_1 MIX1 INP0", "RX3", "RX_RX3"},
+	{"RX INT2_1 MIX1 INP0", "RX4", "RX_RX4"},
+	{"RX INT2_1 MIX1 INP0", "RX5", "RX_RX5"},
+	{"RX INT2_1 MIX1 INP0", "IIR0", "IIR0"},
+	{"RX INT2_1 MIX1 INP0", "IIR1", "IIR1"},
+	{"RX INT2_1 MIX1 INP0", "DEC0", "RX_TX DEC0_INP"},
+	{"RX INT2_1 MIX1 INP0", "DEC1", "RX_TX DEC1_INP"},
+	{"RX INT2_1 MIX1 INP1", "RX0", "RX_RX0"},
+	{"RX INT2_1 MIX1 INP1", "RX1", "RX_RX1"},
+	{"RX INT2_1 MIX1 INP1", "RX2", "RX_RX2"},
+	{"RX INT2_1 MIX1 INP1", "RX3", "RX_RX3"},
+	{"RX INT2_1 MIX1 INP1", "RX4", "RX_RX4"},
+	{"RX INT2_1 MIX1 INP1", "RX5", "RX_RX5"},
+	{"RX INT2_1 MIX1 INP1", "IIR0", "IIR0"},
+	{"RX INT2_1 MIX1 INP1", "IIR1", "IIR1"},
+	{"RX INT2_1 MIX1 INP1", "DEC0", "RX_TX DEC0_INP"},
+	{"RX INT2_1 MIX1 INP1", "DEC1", "RX_TX DEC1_INP"},
+	{"RX INT2_1 MIX1 INP2", "RX0", "RX_RX0"},
+	{"RX INT2_1 MIX1 INP2", "RX1", "RX_RX1"},
+	{"RX INT2_1 MIX1 INP2", "RX2", "RX_RX2"},
+	{"RX INT2_1 MIX1 INP2", "RX3", "RX_RX3"},
+	{"RX INT2_1 MIX1 INP2", "RX4", "RX_RX4"},
+	{"RX INT2_1 MIX1 INP2", "RX5", "RX_RX5"},
+	{"RX INT2_1 MIX1 INP2", "IIR0", "IIR0"},
+	{"RX INT2_1 MIX1 INP2", "IIR1", "IIR1"},
+	{"RX INT2_1 MIX1 INP2", "DEC0", "RX_TX DEC0_INP"},
+	{"RX INT2_1 MIX1 INP2", "DEC1", "RX_TX DEC1_INP"},
+
+	{"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"},
+	{"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"},
+	{"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"},
+	{"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP0"},
+	{"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP1"},
+	{"RX INT1_1 MIX1", NULL, "RX INT1_1 MIX1 INP2"},
+	{"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP0"},
+	{"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP1"},
+	{"RX INT2_1 MIX1", NULL, "RX INT2_1 MIX1 INP2"},
+
+	{"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+	{"RX MIX TX0 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
+	{"RX MIX TX0 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
+	{"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+	{"RX MIX TX1 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
+	{"RX MIX TX1 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
+	{"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+	{"RX MIX TX2 MUX", "RX_MIX1", "RX INT1 SEC MIX"},
+	{"RX MIX TX2 MUX", "RX_MIX2", "RX INT2 SEC MIX"},
+	{"RX AIF_ECHO", NULL, "RX MIX TX0 MUX"},
+	{"RX AIF_ECHO", NULL, "RX MIX TX1 MUX"},
+	{"RX AIF_ECHO", NULL, "RX MIX TX2 MUX"},
+	{"RX AIF_ECHO", NULL, "RX_MCLK"},
+
+	/* Mixing path INT0 */
+	{"RX INT0_2 MUX", "RX0", "RX_RX0"},
+	{"RX INT0_2 MUX", "RX1", "RX_RX1"},
+	{"RX INT0_2 MUX", "RX2", "RX_RX2"},
+	{"RX INT0_2 MUX", "RX3", "RX_RX3"},
+	{"RX INT0_2 MUX", "RX4", "RX_RX4"},
+	{"RX INT0_2 MUX", "RX5", "RX_RX5"},
+	{"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"},
+	{"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"},
+
+	/* Mixing path INT1 */
+	{"RX INT1_2 MUX", "RX0", "RX_RX0"},
+	{"RX INT1_2 MUX", "RX1", "RX_RX1"},
+	{"RX INT1_2 MUX", "RX2", "RX_RX2"},
+	{"RX INT1_2 MUX", "RX3", "RX_RX3"},
+	{"RX INT1_2 MUX", "RX4", "RX_RX4"},
+	{"RX INT1_2 MUX", "RX5", "RX_RX5"},
+	{"RX INT1_2 INTERP", NULL, "RX INT1_2 MUX"},
+	{"RX INT1 SEC MIX", NULL, "RX INT1_2 INTERP"},
+
+	/* Mixing path INT2 */
+	{"RX INT2_2 MUX", "RX0", "RX_RX0"},
+	{"RX INT2_2 MUX", "RX1", "RX_RX1"},
+	{"RX INT2_2 MUX", "RX2", "RX_RX2"},
+	{"RX INT2_2 MUX", "RX3", "RX_RX3"},
+	{"RX INT2_2 MUX", "RX4", "RX_RX4"},
+	{"RX INT2_2 MUX", "RX5", "RX_RX5"},
+	{"RX INT2_2 INTERP", NULL, "RX INT2_2 MUX"},
+	{"RX INT2 SEC MIX", NULL, "RX INT2_2 INTERP"},
+
+	{"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"},
+	{"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"},
+	{"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"},
+	{"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"},
+	{"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 MIX2"},
+	{"HPHL_OUT", NULL, "RX INT0 DEM MUX"},
+	{"HPHL_OUT", NULL, "RX_MCLK"},
+
+	{"RX INT1_1 INTERP", NULL, "RX INT1_1 MIX1"},
+	{"RX INT1 SEC MIX", NULL, "RX INT1_1 INTERP"},
+	{"RX INT1 MIX2", NULL, "RX INT1 SEC MIX"},
+	{"RX INT1 MIX2", NULL, "RX INT1 MIX2 INP"},
+	{"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 MIX2"},
+	{"HPHR_OUT", NULL, "RX INT1 DEM MUX"},
+	{"HPHR_OUT", NULL, "RX_MCLK"},
+
+	{"RX INT2_1 INTERP", NULL, "RX INT2_1 MIX1"},
+
+	{"RX INT2_1 VBAT", "RX AUX VBAT Enable", "RX INT2_1 INTERP"},
+	{"RX INT2 SEC MIX", NULL, "RX INT2_1 VBAT"},
+
+	{"RX INT2 SEC MIX", NULL, "RX INT2_1 INTERP"},
+	{"RX INT2 MIX2", NULL, "RX INT2 SEC MIX"},
+	{"RX INT2 MIX2", NULL, "RX INT2 MIX2 INP"},
+	{"AUX_OUT", NULL, "RX INT2 MIX2"},
+	{"AUX_OUT", NULL, "RX_MCLK"},
+
+	{"IIR0", NULL, "RX_MCLK"},
+	{"IIR0", NULL, "IIR0 INP0 MUX"},
+	{"IIR0 INP0 MUX", "DEC0", "RX_TX DEC0_INP"},
+	{"IIR0 INP0 MUX", "DEC1", "RX_TX DEC1_INP"},
+	{"IIR0 INP0 MUX", "DEC2", "RX_TX DEC2_INP"},
+	{"IIR0 INP0 MUX", "DEC3", "RX_TX DEC3_INP"},
+	{"IIR0 INP0 MUX", "RX0", "RX_RX0"},
+	{"IIR0 INP0 MUX", "RX1", "RX_RX1"},
+	{"IIR0 INP0 MUX", "RX2", "RX_RX2"},
+	{"IIR0 INP0 MUX", "RX3", "RX_RX3"},
+	{"IIR0 INP0 MUX", "RX4", "RX_RX4"},
+	{"IIR0 INP0 MUX", "RX5", "RX_RX5"},
+	{"IIR0", NULL, "IIR0 INP1 MUX"},
+	{"IIR0 INP1 MUX", "DEC0", "RX_TX DEC0_INP"},
+	{"IIR0 INP1 MUX", "DEC1", "RX_TX DEC1_INP"},
+	{"IIR0 INP1 MUX", "DEC2", "RX_TX DEC2_INP"},
+	{"IIR0 INP1 MUX", "DEC3", "RX_TX DEC3_INP"},
+	{"IIR0 INP1 MUX", "RX0", "RX_RX0"},
+	{"IIR0 INP1 MUX", "RX1", "RX_RX1"},
+	{"IIR0 INP1 MUX", "RX2", "RX_RX2"},
+	{"IIR0 INP1 MUX", "RX3", "RX_RX3"},
+	{"IIR0 INP1 MUX", "RX4", "RX_RX4"},
+	{"IIR0 INP1 MUX", "RX5", "RX_RX5"},
+	{"IIR0", NULL, "IIR0 INP2 MUX"},
+	{"IIR0 INP2 MUX", "DEC0", "RX_TX DEC0_INP"},
+	{"IIR0 INP2 MUX", "DEC1", "RX_TX DEC1_INP"},
+	{"IIR0 INP2 MUX", "DEC2", "RX_TX DEC2_INP"},
+	{"IIR0 INP2 MUX", "DEC3", "RX_TX DEC3_INP"},
+	{"IIR0 INP2 MUX", "RX0", "RX_RX0"},
+	{"IIR0 INP2 MUX", "RX1", "RX_RX1"},
+	{"IIR0 INP2 MUX", "RX2", "RX_RX2"},
+	{"IIR0 INP2 MUX", "RX3", "RX_RX3"},
+	{"IIR0 INP2 MUX", "RX4", "RX_RX4"},
+	{"IIR0 INP2 MUX", "RX5", "RX_RX5"},
+	{"IIR0", NULL, "IIR0 INP3 MUX"},
+	{"IIR0 INP3 MUX", "DEC0", "RX_TX DEC0_INP"},
+	{"IIR0 INP3 MUX", "DEC1", "RX_TX DEC1_INP"},
+	{"IIR0 INP3 MUX", "DEC2", "RX_TX DEC2_INP"},
+	{"IIR0 INP3 MUX", "DEC3", "RX_TX DEC3_INP"},
+	{"IIR0 INP3 MUX", "RX0", "RX_RX0"},
+	{"IIR0 INP3 MUX", "RX1", "RX_RX1"},
+	{"IIR0 INP3 MUX", "RX2", "RX_RX2"},
+	{"IIR0 INP3 MUX", "RX3", "RX_RX3"},
+	{"IIR0 INP3 MUX", "RX4", "RX_RX4"},
+	{"IIR0 INP3 MUX", "RX5", "RX_RX5"},
+
+	{"IIR1", NULL, "RX_MCLK"},
+	{"IIR1", NULL, "IIR1 INP0 MUX"},
+	{"IIR1 INP0 MUX", "DEC0", "RX_TX DEC0_INP"},
+	{"IIR1 INP0 MUX", "DEC1", "RX_TX DEC1_INP"},
+	{"IIR1 INP0 MUX", "DEC2", "RX_TX DEC2_INP"},
+	{"IIR1 INP0 MUX", "DEC3", "RX_TX DEC3_INP"},
+	{"IIR1 INP0 MUX", "RX0", "RX_RX0"},
+	{"IIR1 INP0 MUX", "RX1", "RX_RX1"},
+	{"IIR1 INP0 MUX", "RX2", "RX_RX2"},
+	{"IIR1 INP0 MUX", "RX3", "RX_RX3"},
+	{"IIR1 INP0 MUX", "RX4", "RX_RX4"},
+	{"IIR1 INP0 MUX", "RX5", "RX_RX5"},
+	{"IIR1", NULL, "IIR1 INP1 MUX"},
+	{"IIR1 INP1 MUX", "DEC0", "RX_TX DEC0_INP"},
+	{"IIR1 INP1 MUX", "DEC1", "RX_TX DEC1_INP"},
+	{"IIR1 INP1 MUX", "DEC2", "RX_TX DEC2_INP"},
+	{"IIR1 INP1 MUX", "DEC3", "RX_TX DEC3_INP"},
+	{"IIR1 INP1 MUX", "RX0", "RX_RX0"},
+	{"IIR1 INP1 MUX", "RX1", "RX_RX1"},
+	{"IIR1 INP1 MUX", "RX2", "RX_RX2"},
+	{"IIR1 INP1 MUX", "RX3", "RX_RX3"},
+	{"IIR1 INP1 MUX", "RX4", "RX_RX4"},
+	{"IIR1 INP1 MUX", "RX5", "RX_RX5"},
+	{"IIR1", NULL, "IIR1 INP2 MUX"},
+	{"IIR1 INP2 MUX", "DEC0", "RX_TX DEC0_INP"},
+	{"IIR1 INP2 MUX", "DEC1", "RX_TX DEC1_INP"},
+	{"IIR1 INP2 MUX", "DEC2", "RX_TX DEC2_INP"},
+	{"IIR1 INP2 MUX", "DEC3", "RX_TX DEC3_INP"},
+	{"IIR1 INP2 MUX", "RX0", "RX_RX0"},
+	{"IIR1 INP2 MUX", "RX1", "RX_RX1"},
+	{"IIR1 INP2 MUX", "RX2", "RX_RX2"},
+	{"IIR1 INP2 MUX", "RX3", "RX_RX3"},
+	{"IIR1 INP2 MUX", "RX4", "RX_RX4"},
+	{"IIR1 INP2 MUX", "RX5", "RX_RX5"},
+	{"IIR1", NULL, "IIR1 INP3 MUX"},
+	{"IIR1 INP3 MUX", "DEC0", "RX_TX DEC0_INP"},
+	{"IIR1 INP3 MUX", "DEC1", "RX_TX DEC1_INP"},
+	{"IIR1 INP3 MUX", "DEC2", "RX_TX DEC2_INP"},
+	{"IIR1 INP3 MUX", "DEC3", "RX_TX DEC3_INP"},
+	{"IIR1 INP3 MUX", "RX0", "RX_RX0"},
+	{"IIR1 INP3 MUX", "RX1", "RX_RX1"},
+	{"IIR1 INP3 MUX", "RX2", "RX_RX2"},
+	{"IIR1 INP3 MUX", "RX3", "RX_RX3"},
+	{"IIR1 INP3 MUX", "RX4", "RX_RX4"},
+	{"IIR1 INP3 MUX", "RX5", "RX_RX5"},
+
+	{"SRC0", NULL, "IIR0"},
+	{"SRC1", NULL, "IIR1"},
+	{"RX INT0 MIX2 INP", "SRC0", "SRC0"},
+	{"RX INT0 MIX2 INP", "SRC1", "SRC1"},
+	{"RX INT1 MIX2 INP", "SRC0", "SRC0"},
+	{"RX INT1 MIX2 INP", "SRC1", "SRC1"},
+	{"RX INT2 MIX2 INP", "SRC0", "SRC0"},
+	{"RX INT2 MIX2 INP", "SRC1", "SRC1"},
+};
+
+static int lpass_cdc_rx_macro_core_vote(void *handle, bool enable)
+{
+	struct lpass_cdc_rx_macro_priv *rx_priv = (struct lpass_cdc_rx_macro_priv *) handle;
+
+	if (rx_priv == NULL) {
+		pr_err("%s: rx priv data is NULL\n", __func__);
+		return -EINVAL;
+	}
+	if (enable) {
+		pm_runtime_get_sync(rx_priv->dev);
+		pm_runtime_put_autosuspend(rx_priv->dev);
+		pm_runtime_mark_last_busy(rx_priv->dev);
+	}
+
+	if (lpass_cdc_check_core_votes(rx_priv->dev))
+		return 0;
+	else
+		return -EINVAL;
+}
+
+static int rx_swrm_clock(void *handle, bool enable)
+{
+	struct lpass_cdc_rx_macro_priv *rx_priv = (struct lpass_cdc_rx_macro_priv *) handle;
+	struct regmap *regmap = dev_get_regmap(rx_priv->dev->parent, NULL);
+	int ret = 0;
+
+	if (regmap == NULL) {
+		dev_err(rx_priv->dev, "%s: regmap is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&rx_priv->swr_clk_lock);
+
+	trace_printk("%s: swrm clock %s\n",
+			__func__, (enable ? "enable" : "disable"));
+	dev_dbg(rx_priv->dev, "%s: swrm clock %s\n",
+		__func__, (enable ? "enable" : "disable"));
+	if (enable) {
+		pm_runtime_get_sync(rx_priv->dev);
+		if (rx_priv->swr_clk_users == 0) {
+			ret = msm_cdc_pinctrl_select_active_state(
+						rx_priv->rx_swr_gpio_p);
+			if (ret < 0) {
+				dev_err(rx_priv->dev,
+					"%s: rx swr pinctrl enable failed\n",
+					__func__);
+				pm_runtime_mark_last_busy(rx_priv->dev);
+				pm_runtime_put_autosuspend(rx_priv->dev);
+				goto exit;
+			}
+			ret = lpass_cdc_rx_macro_mclk_enable(rx_priv, 1, true);
+			if (ret < 0) {
+				msm_cdc_pinctrl_select_sleep_state(
+						rx_priv->rx_swr_gpio_p);
+				dev_err(rx_priv->dev,
+					"%s: rx request clock enable failed\n",
+					__func__);
+				pm_runtime_mark_last_busy(rx_priv->dev);
+				pm_runtime_put_autosuspend(rx_priv->dev);
+				goto exit;
+			}
+			if (rx_priv->reset_swr)
+				regmap_update_bits(regmap,
+					LPASS_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
+					0x02, 0x02);
+			regmap_update_bits(regmap,
+				LPASS_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
+				0x01, 0x01);
+			if (rx_priv->reset_swr)
+				regmap_update_bits(regmap,
+					LPASS_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
+					0x02, 0x00);
+			rx_priv->reset_swr = false;
+		}
+		pm_runtime_mark_last_busy(rx_priv->dev);
+		pm_runtime_put_autosuspend(rx_priv->dev);
+		rx_priv->swr_clk_users++;
+	} else {
+		if (rx_priv->swr_clk_users <= 0) {
+			dev_err(rx_priv->dev,
+				"%s: rx swrm clock users already reset\n",
+				__func__);
+			rx_priv->swr_clk_users = 0;
+			goto exit;
+		}
+		rx_priv->swr_clk_users--;
+		if (rx_priv->swr_clk_users == 0) {
+			regmap_update_bits(regmap,
+				LPASS_CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
+				0x01, 0x00);
+			lpass_cdc_rx_macro_mclk_enable(rx_priv, 0, true);
+			ret = msm_cdc_pinctrl_select_sleep_state(
+						rx_priv->rx_swr_gpio_p);
+			if (ret < 0) {
+				dev_err(rx_priv->dev,
+					"%s: rx swr pinctrl disable failed\n",
+					__func__);
+				goto exit;
+			}
+		}
+	}
+	trace_printk("%s: swrm clock users %d\n",
+		__func__, rx_priv->swr_clk_users);
+	dev_dbg(rx_priv->dev, "%s: swrm clock users %d\n",
+		__func__, rx_priv->swr_clk_users);
+exit:
+	mutex_unlock(&rx_priv->swr_clk_lock);
+	return ret;
+}
+
+static const struct lpass_cdc_rx_macro_reg_mask_val
+				lpass_cdc_rx_macro_reg_init[] = {
+	{LPASS_CDC_RX_RX0_RX_PATH_SEC7, 0x07, 0x02},
+	{LPASS_CDC_RX_RX1_RX_PATH_SEC7, 0x07, 0x02},
+	{LPASS_CDC_RX_RX2_RX_PATH_SEC7, 0x07, 0x02},
+	{LPASS_CDC_RX_RX0_RX_PATH_CFG3, 0x03, 0x02},
+	{LPASS_CDC_RX_RX1_RX_PATH_CFG3, 0x03, 0x02},
+	{LPASS_CDC_RX_RX2_RX_PATH_CFG3, 0x03, 0x02},
+};
+
+static void lpass_cdc_rx_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
+{
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!component) {
+		pr_err("%s: NULL component pointer!\n", __func__);
+		return;
+	}
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return;
+
+	switch (rx_priv->bcl_pmic_params.id) {
+	case 0:
+		/* Enable ID0 to listen to respective PMIC group interrupts */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
+		/* Update MC_SID0 */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_DECODE_CFG1, 0x0F,
+			rx_priv->bcl_pmic_params.sid);
+		/* Update MC_PPID0 */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_DECODE_CFG2, 0xFF,
+			rx_priv->bcl_pmic_params.ppid);
+		break;
+	case 1:
+		/* Enable ID1 to listen to respective PMIC group interrupts */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
+		/* Update MC_SID1 */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_DECODE_CFG3, 0x0F,
+			rx_priv->bcl_pmic_params.sid);
+		/* Update MC_PPID1 */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_RX_BCL_VBAT_DECODE_CFG1, 0xFF,
+			rx_priv->bcl_pmic_params.ppid);
+		break;
+	default:
+		dev_err(rx_dev, "%s: PMIC ID is invalid %d\n",
+		       __func__, rx_priv->bcl_pmic_params.id);
+		break;
+	}
+}
+
+static int lpass_cdc_rx_macro_init(struct snd_soc_component *component)
+{
+	struct snd_soc_dapm_context *dapm =
+				snd_soc_component_get_dapm(component);
+	int ret = 0;
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	int i;
+
+	rx_dev = lpass_cdc_get_device_ptr(component->dev, RX_MACRO);
+	if (!rx_dev) {
+		dev_err(component->dev,
+			"%s: null device for macro!\n", __func__);
+		return -EINVAL;
+	}
+	rx_priv = dev_get_drvdata(rx_dev);
+	if (!rx_priv) {
+		dev_err(component->dev,
+			"%s: priv is null for macro!\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = snd_soc_dapm_new_controls(dapm, lpass_cdc_rx_macro_dapm_widgets,
+					ARRAY_SIZE(lpass_cdc_rx_macro_dapm_widgets));
+	if (ret < 0) {
+		dev_err(rx_dev, "%s: failed to add controls\n", __func__);
+		return ret;
+	}
+	ret = snd_soc_dapm_add_routes(dapm, rx_audio_map,
+					ARRAY_SIZE(rx_audio_map));
+	if (ret < 0) {
+		dev_err(rx_dev, "%s: failed to add routes\n", __func__);
+		return ret;
+	}
+	ret = snd_soc_dapm_new_widgets(dapm->card);
+	if (ret < 0) {
+		dev_err(rx_dev, "%s: failed to add widgets\n", __func__);
+		return ret;
+	}
+	ret = snd_soc_add_component_controls(component, lpass_cdc_rx_macro_snd_controls,
+				   ARRAY_SIZE(lpass_cdc_rx_macro_snd_controls));
+	if (ret < 0) {
+		dev_err(rx_dev, "%s: failed to add snd_ctls\n", __func__);
+		return ret;
+	}
+	rx_priv->dev_up = true;
+	rx_priv->rx0_gain_val = 0;
+	rx_priv->rx1_gain_val = 0;
+	snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF1 Playback");
+	snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF2 Playback");
+	snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF3 Playback");
+	snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF4 Playback");
+	snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF5 Playback");
+	snd_soc_dapm_ignore_suspend(dapm, "RX_MACRO_AIF6 Playback");
+	snd_soc_dapm_ignore_suspend(dapm, "HPHL_OUT");
+	snd_soc_dapm_ignore_suspend(dapm, "HPHR_OUT");
+	snd_soc_dapm_ignore_suspend(dapm, "AUX_OUT");
+	snd_soc_dapm_ignore_suspend(dapm, "PCM_OUT");
+	snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC0_INP");
+	snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC1_INP");
+	snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC2_INP");
+	snd_soc_dapm_ignore_suspend(dapm, "RX_TX DEC3_INP");
+	snd_soc_dapm_sync(dapm);
+
+	for (i = 0; i < ARRAY_SIZE(lpass_cdc_rx_macro_reg_init); i++)
+		snd_soc_component_update_bits(component,
+				lpass_cdc_rx_macro_reg_init[i].reg,
+				lpass_cdc_rx_macro_reg_init[i].mask,
+				lpass_cdc_rx_macro_reg_init[i].val);
+
+	rx_priv->component = component;
+	lpass_cdc_rx_macro_init_bcl_pmic_reg(component);
+
+	return 0;
+}
+
+static int lpass_cdc_rx_macro_deinit(struct snd_soc_component *component)
+{
+	struct device *rx_dev = NULL;
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+
+	if (!lpass_cdc_rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+		return -EINVAL;
+
+	rx_priv->component = NULL;
+
+	return 0;
+}
+
+static void lpass_cdc_rx_macro_add_child_devices(struct work_struct *work)
+{
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	struct platform_device *pdev = NULL;
+	struct device_node *node = NULL;
+	struct rx_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL;
+	int ret = 0;
+	u16 count = 0, ctrl_num = 0;
+	struct rx_swr_ctrl_platform_data *platdata = NULL;
+	char plat_dev_name[RX_SWR_STRING_LEN] = "";
+	bool rx_swr_master_node = false;
+
+	rx_priv = container_of(work, struct lpass_cdc_rx_macro_priv,
+			     lpass_cdc_rx_macro_add_child_devices_work);
+	if (!rx_priv) {
+		pr_err("%s: Memory for rx_priv does not exist\n",
+			__func__);
+		return;
+	}
+
+	if (!rx_priv->dev) {
+		pr_err("%s: RX device does not exist\n", __func__);
+		return;
+	}
+
+	if(!rx_priv->dev->of_node) {
+		dev_err(rx_priv->dev,
+			"%s: DT node for RX dev does not exist\n", __func__);
+		return;
+	}
+
+	platdata = &rx_priv->swr_plat_data;
+	rx_priv->child_count = 0;
+
+	for_each_available_child_of_node(rx_priv->dev->of_node, node) {
+		rx_swr_master_node = false;
+		if (strnstr(node->name, "rx_swr_master",
+				strlen("rx_swr_master")) != NULL)
+			rx_swr_master_node = true;
+
+		if(rx_swr_master_node)
+			strlcpy(plat_dev_name, "rx_swr_ctrl",
+				(RX_SWR_STRING_LEN - 1));
+		else
+			strlcpy(plat_dev_name, node->name,
+				(RX_SWR_STRING_LEN - 1));
+
+		pdev = platform_device_alloc(plat_dev_name, -1);
+		if (!pdev) {
+			dev_err(rx_priv->dev, "%s: pdev memory alloc failed\n",
+				__func__);
+			ret = -ENOMEM;
+			goto err;
+		}
+		pdev->dev.parent = rx_priv->dev;
+		pdev->dev.of_node = node;
+
+		if (rx_swr_master_node) {
+			ret = platform_device_add_data(pdev, platdata,
+						       sizeof(*platdata));
+			if (ret) {
+				dev_err(&pdev->dev,
+					"%s: cannot add plat data ctrl:%d\n",
+					__func__, ctrl_num);
+				goto fail_pdev_add;
+			}
+		}
+
+		ret = platform_device_add(pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"%s: Cannot add platform device\n",
+				__func__);
+			goto fail_pdev_add;
+		}
+
+		if (rx_swr_master_node) {
+			temp = krealloc(swr_ctrl_data,
+					(ctrl_num + 1) * sizeof(
+					struct rx_swr_ctrl_data),
+					GFP_KERNEL);
+			if (!temp) {
+				ret = -ENOMEM;
+				goto fail_pdev_add;
+			}
+			swr_ctrl_data = temp;
+			swr_ctrl_data[ctrl_num].rx_swr_pdev = pdev;
+			ctrl_num++;
+			dev_dbg(&pdev->dev,
+				"%s: Added soundwire ctrl device(s)\n",
+				__func__);
+			rx_priv->swr_ctrl_data = swr_ctrl_data;
+		}
+		if (rx_priv->child_count < LPASS_CDC_RX_MACRO_CHILD_DEVICES_MAX)
+			rx_priv->pdev_child_devices[
+					rx_priv->child_count++] = pdev;
+		else
+			goto err;
+	}
+	return;
+fail_pdev_add:
+	for (count = 0; count < rx_priv->child_count; count++)
+		platform_device_put(rx_priv->pdev_child_devices[count]);
+err:
+	return;
+}
+
+static void lpass_cdc_rx_macro_init_ops(struct macro_ops *ops, char __iomem *rx_io_base)
+{
+	memset(ops, 0, sizeof(struct macro_ops));
+	ops->init = lpass_cdc_rx_macro_init;
+	ops->exit = lpass_cdc_rx_macro_deinit;
+	ops->io_base = rx_io_base;
+	ops->dai_ptr = lpass_cdc_rx_macro_dai;
+	ops->num_dais = ARRAY_SIZE(lpass_cdc_rx_macro_dai);
+	ops->event_handler = lpass_cdc_rx_macro_event_handler;
+	ops->set_port_map = lpass_cdc_rx_macro_set_port_map;
+}
+
+static int lpass_cdc_rx_macro_probe(struct platform_device *pdev)
+{
+	struct macro_ops ops = {0};
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	u32 rx_base_addr = 0, muxsel = 0;
+	char __iomem *rx_io_base = NULL, *muxsel_io = NULL;
+	int ret = 0;
+	u8 bcl_pmic_params[3];
+	u32 default_clk_id = 0;
+	u32 is_used_rx_swr_gpio = 1;
+	const char *is_used_rx_swr_gpio_dt = "qcom,is-used-swr-gpio";
+
+	if (!lpass_cdc_is_va_macro_registered(&pdev->dev)) {
+		dev_err(&pdev->dev,
+			"%s: va-macro not registered yet, defer\n", __func__);
+		return -EPROBE_DEFER;
+	}
+
+	rx_priv = devm_kzalloc(&pdev->dev, sizeof(struct lpass_cdc_rx_macro_priv),
+			    GFP_KERNEL);
+	if (!rx_priv)
+		return -ENOMEM;
+
+	rx_priv->dev = &pdev->dev;
+	ret = of_property_read_u32(pdev->dev.of_node, "reg",
+				   &rx_base_addr);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
+			__func__, "reg");
+		return ret;
+	}
+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,rx_mclk_mode_muxsel",
+				   &muxsel);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
+			__func__, "reg");
+		return ret;
+	}
+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
+				   &default_clk_id);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
+			__func__, "qcom,default-clk-id");
+		default_clk_id = RX_CORE_CLK;
+	}
+	if (of_find_property(pdev->dev.of_node, is_used_rx_swr_gpio_dt,
+			     NULL)) {
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   is_used_rx_swr_gpio_dt,
+					   &is_used_rx_swr_gpio);
+		if (ret) {
+			dev_err(&pdev->dev, "%s: error reading %s in dt\n",
+				__func__, is_used_rx_swr_gpio_dt);
+			is_used_rx_swr_gpio = 1;
+		}
+	}
+	rx_priv->rx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
+					"qcom,rx-swr-gpios", 0);
+	if (!rx_priv->rx_swr_gpio_p && is_used_rx_swr_gpio) {
+		dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
+			__func__);
+		return -EINVAL;
+	}
+	if (msm_cdc_pinctrl_get_state(rx_priv->rx_swr_gpio_p) < 0 &&
+		is_used_rx_swr_gpio) {
+		dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
+			__func__);
+		return -EPROBE_DEFER;
+	}
+	msm_cdc_pinctrl_set_wakeup_capable(
+				rx_priv->rx_swr_gpio_p, false);
+
+	rx_io_base = devm_ioremap(&pdev->dev, rx_base_addr,
+				  LPASS_CDC_RX_MACRO_MAX_OFFSET);
+	if (!rx_io_base) {
+		dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
+		return -ENOMEM;
+	}
+	rx_priv->rx_io_base = rx_io_base;
+	muxsel_io = devm_ioremap(&pdev->dev, muxsel, 0x4);
+	if (!muxsel_io) {
+		dev_err(&pdev->dev, "%s: ioremap failed for muxsel\n",
+			__func__);
+		return -ENOMEM;
+	}
+	rx_priv->rx_mclk_mode_muxsel = muxsel_io;
+	rx_priv->reset_swr = true;
+	INIT_WORK(&rx_priv->lpass_cdc_rx_macro_add_child_devices_work,
+		  lpass_cdc_rx_macro_add_child_devices);
+	rx_priv->swr_plat_data.handle = (void *) rx_priv;
+	rx_priv->swr_plat_data.read = NULL;
+	rx_priv->swr_plat_data.write = NULL;
+	rx_priv->swr_plat_data.bulk_write = NULL;
+	rx_priv->swr_plat_data.clk = rx_swrm_clock;
+	rx_priv->swr_plat_data.core_vote = lpass_cdc_rx_macro_core_vote;
+	rx_priv->swr_plat_data.handle_irq = NULL;
+
+	ret = of_property_read_u8_array(pdev->dev.of_node,
+				"qcom,rx-bcl-pmic-params", bcl_pmic_params,
+				sizeof(bcl_pmic_params));
+	if (ret) {
+		dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
+			__func__, "qcom,rx-bcl-pmic-params");
+	} else {
+		rx_priv->bcl_pmic_params.id = bcl_pmic_params[0];
+		rx_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
+		rx_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
+	}
+	rx_priv->clk_id = default_clk_id;
+	rx_priv->default_clk_id  = default_clk_id;
+	ops.clk_id_req = rx_priv->clk_id;
+	ops.default_clk_id = default_clk_id;
+
+	rx_priv->is_aux_hpf_on = 1;
+
+	dev_set_drvdata(&pdev->dev, rx_priv);
+	mutex_init(&rx_priv->mclk_lock);
+	mutex_init(&rx_priv->swr_clk_lock);
+	lpass_cdc_rx_macro_init_ops(&ops, rx_io_base);
+
+	ret = lpass_cdc_register_macro(&pdev->dev, RX_MACRO, &ops);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"%s: register macro failed\n", __func__);
+		goto err_reg_macro;
+	}
+	schedule_work(&rx_priv->lpass_cdc_rx_macro_add_child_devices_work);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+	pm_suspend_ignore_children(&pdev->dev, true);
+	pm_runtime_enable(&pdev->dev);
+
+	return 0;
+
+err_reg_macro:
+	mutex_destroy(&rx_priv->mclk_lock);
+	mutex_destroy(&rx_priv->swr_clk_lock);
+	return ret;
+}
+
+static int lpass_cdc_rx_macro_remove(struct platform_device *pdev)
+{
+	struct lpass_cdc_rx_macro_priv *rx_priv = NULL;
+	u16 count = 0;
+
+	rx_priv = dev_get_drvdata(&pdev->dev);
+
+	if (!rx_priv)
+		return -EINVAL;
+
+	for (count = 0; count < rx_priv->child_count &&
+		count < LPASS_CDC_RX_MACRO_CHILD_DEVICES_MAX; count++)
+		platform_device_unregister(rx_priv->pdev_child_devices[count]);
+
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+	lpass_cdc_unregister_macro(&pdev->dev, RX_MACRO);
+	mutex_destroy(&rx_priv->mclk_lock);
+	mutex_destroy(&rx_priv->swr_clk_lock);
+	kfree(rx_priv->swr_ctrl_data);
+	return 0;
+}
+
+static const struct of_device_id lpass_cdc_rx_macro_dt_match[] = {
+	{.compatible = "qcom,lpass-cdc-rx-macro"},
+	{}
+};
+
+static const struct dev_pm_ops lpass_cdc_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(
+		pm_runtime_force_suspend,
+		pm_runtime_force_resume
+	)
+	SET_RUNTIME_PM_OPS(
+		lpass_cdc_runtime_suspend,
+		lpass_cdc_runtime_resume,
+		NULL
+	)
+};
+
+static struct platform_driver lpass_cdc_rx_macro_driver = {
+	.driver = {
+		.name = "lpass_cdc_rx_macro",
+		.owner = THIS_MODULE,
+		.pm = &lpass_cdc_dev_pm_ops,
+		.of_match_table = lpass_cdc_rx_macro_dt_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = lpass_cdc_rx_macro_probe,
+	.remove = lpass_cdc_rx_macro_remove,
+};
+
+module_platform_driver(lpass_cdc_rx_macro_driver);
+
+MODULE_DESCRIPTION("RX macro driver");
+MODULE_LICENSE("GPL v2");

+ 982 - 0
asoc/codecs/lpass-cdc/lpass-cdc-tables.c

@@ -0,0 +1,982 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include "lpass-cdc.h"
+#include "internal.h"
+
+u8 lpass_cdc_tx_reg_access[LPASS_CDC_TX_MACRO_MAX] = {
+	[LPASS_CDC_REG(LPASS_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_ANC_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_CTRL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_FREQ_MCLK)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_I2S_CLK)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_I2S_RESET)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_DMIC0_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_DMIC1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_DMIC2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_DMIC3_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_AMIC0_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_AMIC1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_CLK_RESET_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_MODE_1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_MODE_2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_FF_SHIFT)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_FB_SHIFT)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_LPF_FF_A_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_LPF_FF_B_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_LPF_FB_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_SMLPF_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_DCFLT_SHIFT_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_IIR_ADAPT_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_IIR_COEFF_1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_IIR_COEFF_2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_FF_A_GAIN_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_FF_B_GAIN_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_FB_GAIN_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX4_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX4_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX5_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX5_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX6_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX6_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX7_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX7_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX4_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX4_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX4_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX4_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX4_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX4_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX4_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX4_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX4_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX4_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX4_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX5_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX5_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX5_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX5_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX5_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX5_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX5_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX5_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX5_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX5_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX5_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX6_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX6_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX6_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX6_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX6_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX6_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX6_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX6_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX6_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX6_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX6_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX7_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX7_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX7_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX7_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX7_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX7_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX7_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX7_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX7_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX7_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX7_TX_PATH_SEC6)] = RD_WR_REG,
+};
+
+u8 lpass_cdc_tx_reg_access_v2[LPASS_CDC_TX_MACRO_MAX] = {
+	[LPASS_CDC_REG(LPASS_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_ANC_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_CTRL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_FREQ_MCLK)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_I2S_CLK)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_I2S_RESET)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_DMIC0_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_DMIC1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_DMIC2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_DMIC3_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_AMIC0_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_TOP_CSR_SWR_AMIC1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_CLK_RESET_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_MODE_1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_MODE_2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_FF_SHIFT)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_FB_SHIFT)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_LPF_FF_A_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_LPF_FF_B_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_LPF_FB_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_SMLPF_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_DCFLT_SHIFT_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_IIR_ADAPT_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_IIR_COEFF_1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_IIR_COEFF_2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_FF_A_GAIN_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_FF_B_GAIN_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_ANC0_FB_GAIN_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX0_TX_PATH_SEC7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX1_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX2_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_TX3_TX_PATH_SEC6)] = RD_WR_REG,
+};
+
+u8 lpass_cdc_rx_reg_access[LPASS_CDC_RX_MACRO_MAX] = {
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_TOP_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_SWR_CTRL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DEBUG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DEBUG_BUS)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DEBUG_EN0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DEBUG_EN1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DEBUG_EN2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_HPHL_COMP_WR_LSB)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_HPHL_COMP_WR_MSB)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_HPHL_COMP_LUT)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_HPHL_COMP_RD_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_HPHL_COMP_RD_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_HPHR_COMP_WR_LSB)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_HPHR_COMP_WR_MSB)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_HPHR_COMP_LUT)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_HPHR_COMP_RD_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_HPHR_COMP_RD_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG2)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DSD0_DEBUG_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG2)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_DSD1_DEBUG_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_RX_I2S_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_TX_I2S2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_I2S_CLK)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_I2S_RESET)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_TOP_I2S_MUX)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLK_RST_CTRL_DSD_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SOFTCLIP_CRC)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INP_MUX_RX_INT0_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INP_MUX_RX_INT0_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INP_MUX_RX_INT1_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INP_MUX_RX_INT1_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INP_MUX_RX_INT2_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INP_MUX_RX_INT2_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INP_MUX_RX_MIX_CFG4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INP_MUX_RX_MIX_CFG5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_CRC)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_DLY_CTRL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_DECAY_CTRL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_HPH_V_PA)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_EAR_V_PA)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_HPH_V_HD)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_EAR_V_HD)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_K1_MSB)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_K1_LSB)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_K2_MSB)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_K2_LSB)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_IDLE_CTRL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_IDLE_HPH)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_IDLE_EAR)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_TEST0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_TEST1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_OVR_VREF)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_CLSG_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_CLSG_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_CLSH_CLSG_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_ADC_CAL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_ADC_CAL2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_ADC_CAL3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_PK_EST1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_PK_EST2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_PK_EST3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_RF_PROC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_RF_PROC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_TAC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_TAC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_TAC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_TAC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_GAIN_UPD1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_GAIN_UPD2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_GAIN_UPD3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_GAIN_UPD4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_GAIN_UPD5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_DEBUG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_GAIN_UPD_MON)] = WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_GAIN_MON_VAL)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_BAN)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_ATTN1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_ATTN2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_ATTN3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_DECODE_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_DECODE_CTL2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_DECODE_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_DECODE_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_DECODE_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_DECODE_CFG4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_BCL_VBAT_DECODE_ST)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INTR_CTRL_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INTR_CTRL_CLR_COMMIT)] = WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INTR_CTRL_PIN1_MASK0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INTR_CTRL_PIN1_STATUS0)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INTR_CTRL_PIN1_CLEAR0)] = WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INTR_CTRL_PIN2_MASK0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INTR_CTRL_PIN2_STATUS0)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INTR_CTRL_PIN2_CLEAR0)] = WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INTR_CTRL_LEVEL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INTR_CTRL_BYPASS0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_INTR_CTRL_SET0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_MIX_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_MIX_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_VOL_MIX_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_SEC7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_MIX_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_MIX_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_DSM_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX0_RX_PATH_DSM_DATA6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_MIX_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_MIX_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_VOL_MIX_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_SEC7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_MIX_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_MIX_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_DSM_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX1_RX_PATH_DSM_DATA6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_MIX_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_MIX_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_VOL_MIX_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_SEC7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_MIX_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_MIX_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_RX2_RX_PATH_DSM_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IDLE_DETECT_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IDLE_DETECT_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IDLE_DETECT_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IDLE_DETECT_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IDLE_DETECT_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER0_CTL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER0_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER0_CTL2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER0_CTL3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER0_CTL4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER0_CTL5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER0_CTL6)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER0_CTL7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER1_CTL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER1_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER1_CTL2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER1_CTL3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER1_CTL4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER1_CTL5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER1_CTL6)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_COMPANDER1_CTL7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL)] =
+								RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL)] =
+								RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC0_CLK_RST_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC0_CTL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC0_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC0_FIFO_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC0_STATUS_FIFO)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC1_CLK_RST_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC1_CTL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC1_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC1_FIFO_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC1_STATUS_FIFO)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC2_CLK_RST_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC2_CTL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC2_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC2_FIFO_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_EC_ASRC2_STATUS_FIFO)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_DSD0_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_DSD0_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_DSD0_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_DSD0_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_DSD1_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_DSD1_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_DSD1_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_RX_DSD1_CFG2)] = RD_WR_REG,
+};
+
+u8 lpass_cdc_va_reg_access[LPASS_CDC_VA_MACRO_MAX] = {
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC3_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_I2S_CLK)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_I2S_RESET)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX4_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX4_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX5_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX5_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX6_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX6_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX7_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX7_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX4_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX4_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX4_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX4_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX4_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX4_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX4_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX4_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX4_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX4_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX4_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX5_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX5_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX5_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX5_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX5_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX5_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX5_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX5_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX5_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX5_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX5_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX6_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX6_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX6_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX6_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX6_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX6_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX6_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX6_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX6_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX6_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX6_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX7_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX7_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX7_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX7_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX7_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX7_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX7_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX7_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX7_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX7_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX7_TX_PATH_SEC6)] = RD_WR_REG,
+};
+
+u8 lpass_cdc_va_top_reg_access[LPASS_CDC_VA_MACRO_TOP_MAX] = {
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG,
+};
+
+u8 lpass_cdc_va_reg_access_v2[LPASS_CDC_VA_MACRO_MAX] = {
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC3_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_I2S_CLK)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_I2S_RESET)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_SWR_CTRL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC6)] = RD_WR_REG,
+};
+
+u8 lpass_cdc_va_reg_access_v3[LPASS_CDC_VA_MACRO_MAX] = {
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC2_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC3_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_I2S_CLK)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_I2S_RESET)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TOP_CSR_SWR_CTRL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX0_TX_PATH_SEC7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX1_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX2_TX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_VA_TX3_TX_PATH_SEC6)] = RD_WR_REG,
+};
+
+u8 lpass_cdc_wsa_reg_access[LPASS_CDC_WSA_MACRO_MAX] = {
+	[LPASS_CDC_REG(LPASS_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TOP_TOP_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TOP_TOP_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TOP_FREQ_MCLK)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TOP_DEBUG_BUS_SEL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TOP_DEBUG_EN0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TOP_DEBUG_EN1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TOP_DEBUG_DSM_LB)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TOP_RX_I2S_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TOP_TX_I2S_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TOP_I2S_CLK)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TOP_I2S_RESET)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX_INP_MUX_RX_EC_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_PK_EST1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_PK_EST2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_PK_EST3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_RF_PROC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_RF_PROC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_TAC4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_DEBUG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD_MON)] = WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BAN)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_INTR_CTRL_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_INTR_CTRL_CLR_COMMIT)] = WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_INTR_CTRL_PIN1_MASK0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_INTR_CTRL_PIN1_STATUS0)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_INTR_CTRL_PIN1_CLEAR0)] = WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_INTR_CTRL_PIN2_MASK0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_INTR_CTRL_PIN2_STATUS0)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_INTR_CTRL_PIN2_CLEAR0)] = WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_INTR_CTRL_LEVEL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_INTR_CTRL_BYPASS0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_INTR_CTRL_SET0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_MIX_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_MIX_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_VOL_MIX_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_SEC7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_MIX_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_MIX_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX0_RX_PATH_DSMDEM_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_CFG3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_VOL_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_MIX_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_MIX_CFG)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_VOL_MIX_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_SEC2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_SEC3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_SEC5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_SEC6)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_SEC7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_MIX_SEC0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_MIX_SEC1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_RX1_RX_PATH_DSMDEM_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_BOOST0_BOOST_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_BOOST0_BOOST_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_BOOST0_BOOST_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_BOOST0_BOOST_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_BOOST1_BOOST_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_BOOST1_BOOST_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_BOOST1_BOOST_CFG1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_BOOST1_BOOST_CFG2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER0_CTL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER0_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER0_CTL2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER0_CTL3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER0_CTL4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER0_CTL5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER0_CTL6)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER0_CTL7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER1_CTL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER1_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER1_CTL2)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER1_CTL3)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER1_CTL4)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER1_CTL5)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER1_CTL6)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_COMPANDER1_CTL7)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SOFTCLIP0_CRC)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SOFTCLIP1_CRC)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC0_CTL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC0_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC0_FIFO_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC1_CTL0)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC1_CTL1)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC1_FIFO_CTL)] = RD_WR_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB)] = RD_REG,
+	[LPASS_CDC_REG(LPASS_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO)] = RD_REG,
+};
+
+u8 *lpass_cdc_reg_access[MAX_MACRO] = {
+	[TX_MACRO] = lpass_cdc_tx_reg_access,
+	[RX_MACRO] = lpass_cdc_rx_reg_access,
+	[WSA_MACRO] = lpass_cdc_wsa_reg_access,
+	[VA_MACRO] = lpass_cdc_va_reg_access,
+};

+ 3518 - 0
asoc/codecs/lpass-cdc/lpass-cdc-tx-macro.c

@@ -0,0 +1,3518 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/pm_runtime.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <soc/swr-common.h>
+#include <soc/swr-wcd.h>
+#include <asoc/msm-cdc-pinctrl.h>
+#include "lpass-cdc.h"
+#include "lpass-cdc-registers.h"
+#include "lpass-cdc-clk-rsc.h"
+
+#define AUTO_SUSPEND_DELAY  50 /* delay in msec */
+#define LPASS_CDC_TX_MACRO_MAX_OFFSET 0x1000
+
+#define NUM_DECIMATORS 8
+
+#define LPASS_CDC_TX_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
+			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
+#define LPASS_CDC_TX_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+		SNDRV_PCM_FMTBIT_S24_LE |\
+		SNDRV_PCM_FMTBIT_S24_3LE)
+
+#define  TX_HPF_CUT_OFF_FREQ_MASK	0x60
+#define  CF_MIN_3DB_4HZ			0x0
+#define  CF_MIN_3DB_75HZ		0x1
+#define  CF_MIN_3DB_150HZ		0x2
+
+#define LPASS_CDC_TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0
+#define LPASS_CDC_TX_MACRO_MCLK_FREQ 9600000
+#define LPASS_CDC_TX_MACRO_TX_PATH_OFFSET 0x80
+#define LPASS_CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK 0xF
+#define LPASS_CDC_TX_MACRO_ADC_MUX_CFG_OFFSET 0x8
+#define LPASS_CDC_TX_MACRO_ADC_MODE_CFG0_SHIFT 1
+
+#define LPASS_CDC_TX_MACRO_DMIC_UNMUTE_DELAY_MS	40
+#define LPASS_CDC_TX_MACRO_AMIC_UNMUTE_DELAY_MS	100
+#define LPASS_CDC_TX_MACRO_DMIC_HPF_DELAY_MS	300
+#define LPASS_CDC_TX_MACRO_AMIC_HPF_DELAY_MS	300
+
+static int tx_unmute_delay = LPASS_CDC_TX_MACRO_DMIC_UNMUTE_DELAY_MS;
+module_param(tx_unmute_delay, int, 0664);
+MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
+
+static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
+
+static int lpass_cdc_tx_macro_hw_params(struct snd_pcm_substream *substream,
+			       struct snd_pcm_hw_params *params,
+			       struct snd_soc_dai *dai);
+static int lpass_cdc_tx_macro_get_channel_map(struct snd_soc_dai *dai,
+				unsigned int *tx_num, unsigned int *tx_slot,
+				unsigned int *rx_num, unsigned int *rx_slot);
+
+#define LPASS_CDC_TX_MACRO_SWR_STRING_LEN 80
+#define LPASS_CDC_TX_MACRO_CHILD_DEVICES_MAX 3
+
+/* Hold instance to soundwire platform device */
+struct lpass_cdc_tx_macro_swr_ctrl_data {
+	struct platform_device *tx_swr_pdev;
+};
+
+struct lpass_cdc_tx_macro_swr_ctrl_platform_data {
+	void *handle; /* holds codec private data */
+	int (*read)(void *handle, int reg);
+	int (*write)(void *handle, int reg, int val);
+	int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
+	int (*clk)(void *handle, bool enable);
+	int (*core_vote)(void *handle, bool enable);
+	int (*handle_irq)(void *handle,
+			  irqreturn_t (*swrm_irq_handler)(int irq,
+							  void *data),
+			  void *swrm_handle,
+			  int action);
+};
+
+enum {
+	LPASS_CDC_TX_MACRO_AIF_INVALID = 0,
+	LPASS_CDC_TX_MACRO_AIF1_CAP,
+	LPASS_CDC_TX_MACRO_AIF2_CAP,
+	LPASS_CDC_TX_MACRO_AIF3_CAP,
+	LPASS_CDC_TX_MACRO_MAX_DAIS
+};
+
+enum {
+	LPASS_CDC_TX_MACRO_DEC0,
+	LPASS_CDC_TX_MACRO_DEC1,
+	LPASS_CDC_TX_MACRO_DEC2,
+	LPASS_CDC_TX_MACRO_DEC3,
+	LPASS_CDC_TX_MACRO_DEC4,
+	LPASS_CDC_TX_MACRO_DEC5,
+	LPASS_CDC_TX_MACRO_DEC6,
+	LPASS_CDC_TX_MACRO_DEC7,
+	LPASS_CDC_TX_MACRO_DEC_MAX,
+};
+
+enum {
+	LPASS_CDC_TX_MACRO_CLK_DIV_2,
+	LPASS_CDC_TX_MACRO_CLK_DIV_3,
+	LPASS_CDC_TX_MACRO_CLK_DIV_4,
+	LPASS_CDC_TX_MACRO_CLK_DIV_6,
+	LPASS_CDC_TX_MACRO_CLK_DIV_8,
+	LPASS_CDC_TX_MACRO_CLK_DIV_16,
+};
+
+enum {
+	MSM_DMIC,
+	SWR_MIC,
+	ANC_FB_TUNE1
+};
+
+enum {
+	TX_MCLK,
+	VA_MCLK,
+};
+
+struct lpass_cdc_tx_macro_reg_mask_val {
+	u16 reg;
+	u8 mask;
+	u8 val;
+};
+
+struct tx_mute_work {
+	struct lpass_cdc_tx_macro_priv *tx_priv;
+	u32 decimator;
+	struct delayed_work dwork;
+};
+
+struct hpf_work {
+	struct lpass_cdc_tx_macro_priv *tx_priv;
+	u8 decimator;
+	u8 hpf_cut_off_freq;
+	struct delayed_work dwork;
+};
+
+struct lpass_cdc_tx_macro_priv {
+	struct device *dev;
+	bool dec_active[NUM_DECIMATORS];
+	int tx_mclk_users;
+	int swr_clk_users;
+	bool dapm_mclk_enable;
+	bool reset_swr;
+	struct mutex mclk_lock;
+	struct mutex swr_clk_lock;
+	struct snd_soc_component *component;
+	struct device_node *tx_swr_gpio_p;
+	struct lpass_cdc_tx_macro_swr_ctrl_data *swr_ctrl_data;
+	struct lpass_cdc_tx_macro_swr_ctrl_platform_data swr_plat_data;
+	struct work_struct lpass_cdc_tx_macro_add_child_devices_work;
+	struct hpf_work tx_hpf_work[NUM_DECIMATORS];
+	struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS];
+	u16 dmic_clk_div;
+	u32 version;
+	u32 is_used_tx_swr_gpio;
+	unsigned long active_ch_mask[LPASS_CDC_TX_MACRO_MAX_DAIS];
+	unsigned long active_ch_cnt[LPASS_CDC_TX_MACRO_MAX_DAIS];
+	char __iomem *tx_io_base;
+	struct platform_device *pdev_child_devices
+			[LPASS_CDC_TX_MACRO_CHILD_DEVICES_MAX];
+	int child_count;
+	int tx_swr_clk_cnt;
+	int va_swr_clk_cnt;
+	int va_clk_status;
+	int tx_clk_status;
+	bool bcs_enable;
+	int dec_mode[NUM_DECIMATORS];
+	int bcs_ch;
+	bool bcs_clk_en;
+	bool hs_slow_insert_complete;
+	int amic_sample_rate;
+	bool lpi_enable;
+	bool register_event_listener;
+};
+
+static bool lpass_cdc_tx_macro_get_data(struct snd_soc_component *component,
+			      struct device **tx_dev,
+			      struct lpass_cdc_tx_macro_priv **tx_priv,
+			      const char *func_name)
+{
+	*tx_dev = lpass_cdc_get_device_ptr(component->dev, TX_MACRO);
+	if (!(*tx_dev)) {
+		dev_err(component->dev,
+			"%s: null device for macro!\n", func_name);
+		return false;
+	}
+
+	*tx_priv = dev_get_drvdata((*tx_dev));
+	if (!(*tx_priv)) {
+		dev_err(component->dev,
+			"%s: priv is null for macro!\n", func_name);
+		return false;
+	}
+
+	if (!(*tx_priv)->component) {
+		dev_err(component->dev,
+			"%s: tx_priv->component not initialized!\n", func_name);
+		return false;
+	}
+
+	return true;
+}
+
+static int lpass_cdc_tx_macro_mclk_enable(
+				struct lpass_cdc_tx_macro_priv *tx_priv,
+				bool mclk_enable)
+{
+	struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
+	int ret = 0;
+
+	if (regmap == NULL) {
+		dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	dev_dbg(tx_priv->dev, "%s: mclk_enable = %u,clk_users= %d\n",
+		__func__, mclk_enable, tx_priv->tx_mclk_users);
+
+	mutex_lock(&tx_priv->mclk_lock);
+	if (mclk_enable) {
+		ret = lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
+						TX_CORE_CLK,
+						TX_CORE_CLK,
+						true);
+		if (ret < 0) {
+			dev_err_ratelimited(tx_priv->dev,
+				"%s: request clock enable failed\n",
+				__func__);
+			goto exit;
+		}
+		lpass_cdc_clk_rsc_fs_gen_request(tx_priv->dev,
+					true);
+		regcache_mark_dirty(regmap);
+		regcache_sync_region(regmap,
+				TX_START_OFFSET,
+				TX_MAX_OFFSET);
+		if (tx_priv->tx_mclk_users == 0) {
+			/* 9.6MHz MCLK, set value 0x00 if other frequency */
+			regmap_update_bits(regmap,
+				LPASS_CDC_TX_TOP_CSR_FREQ_MCLK, 0x01, 0x01);
+			regmap_update_bits(regmap,
+				LPASS_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
+				0x01, 0x01);
+			regmap_update_bits(regmap,
+				LPASS_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
+				0x01, 0x01);
+		}
+		tx_priv->tx_mclk_users++;
+	} else {
+		if (tx_priv->tx_mclk_users <= 0) {
+			dev_err(tx_priv->dev, "%s: clock already disabled\n",
+				__func__);
+			tx_priv->tx_mclk_users = 0;
+			goto exit;
+		}
+		tx_priv->tx_mclk_users--;
+		if (tx_priv->tx_mclk_users == 0) {
+			regmap_update_bits(regmap,
+				LPASS_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
+				0x01, 0x00);
+			regmap_update_bits(regmap,
+				LPASS_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
+				0x01, 0x00);
+		}
+
+		lpass_cdc_clk_rsc_fs_gen_request(tx_priv->dev,
+				false);
+		lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
+				 TX_CORE_CLK,
+				 TX_CORE_CLK,
+				 false);
+	}
+exit:
+	mutex_unlock(&tx_priv->mclk_lock);
+	return ret;
+}
+
+static int __lpass_cdc_tx_macro_mclk_enable(struct snd_soc_component *component,
+				  bool enable)
+{
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	return lpass_cdc_tx_macro_mclk_enable(tx_priv, enable);
+}
+
+static int lpass_cdc_tx_macro_va_swr_clk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	if (SND_SOC_DAPM_EVENT_ON(event))
+		++tx_priv->va_swr_clk_cnt;
+	if (SND_SOC_DAPM_EVENT_OFF(event))
+		--tx_priv->va_swr_clk_cnt;
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_tx_swr_clk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	if (SND_SOC_DAPM_EVENT_ON(event))
+		++tx_priv->tx_swr_clk_cnt;
+	if (SND_SOC_DAPM_EVENT_OFF(event))
+		--tx_priv->tx_swr_clk_cnt;
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	int ret = 0;
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(tx_dev, "%s: event = %d, lpi_enable = %d\n",
+		__func__, event, tx_priv->lpi_enable);
+
+	if (!tx_priv->lpi_enable)
+		return ret;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (tx_priv->lpi_enable) {
+			lpass_cdc_register_event_listener(component, true);
+			tx_priv->register_event_listener = true;
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (tx_priv->register_event_listener) {
+			tx_priv->register_event_listener = false;
+			lpass_cdc_register_event_listener(component, false);
+		}
+		break;
+	default:
+		dev_err(tx_priv->dev,
+			"%s: invalid DAPM event %d\n", __func__, event);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static int lpass_cdc_tx_macro_mclk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	int ret = 0;
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(tx_dev, "%s: event = %d\n", __func__, event);
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		ret = lpass_cdc_tx_macro_mclk_enable(tx_priv, 1);
+		if (ret)
+			tx_priv->dapm_mclk_enable = false;
+		else
+			tx_priv->dapm_mclk_enable = true;
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (tx_priv->dapm_mclk_enable)
+			ret = lpass_cdc_tx_macro_mclk_enable(tx_priv, 0);
+		break;
+	default:
+		dev_err(tx_priv->dev,
+			"%s: invalid DAPM event %d\n", __func__, event);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static int lpass_cdc_tx_macro_event_handler(struct snd_soc_component *component,
+				u16 event, u32 data)
+{
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	int ret = 0;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	switch (event) {
+	case LPASS_CDC_MACRO_EVT_SSR_DOWN:
+		trace_printk("%s, enter SSR down\n", __func__);
+		if (tx_priv->swr_ctrl_data) {
+			swrm_wcd_notify(
+				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+				SWR_DEVICE_SSR_DOWN, NULL);
+		}
+		if ((!pm_runtime_enabled(tx_dev) ||
+		     !pm_runtime_suspended(tx_dev))) {
+			ret = lpass_cdc_runtime_suspend(tx_dev);
+			if (!ret) {
+				pm_runtime_disable(tx_dev);
+				pm_runtime_set_suspended(tx_dev);
+				pm_runtime_enable(tx_dev);
+			}
+		}
+		break;
+	case LPASS_CDC_MACRO_EVT_SSR_UP:
+		trace_printk("%s, enter SSR up\n", __func__);
+		/* reset swr after ssr/pdr */
+		tx_priv->reset_swr = true;
+		if (tx_priv->swr_ctrl_data)
+			swrm_wcd_notify(
+				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+				SWR_DEVICE_SSR_UP, NULL);
+		break;
+	case LPASS_CDC_MACRO_EVT_CLK_RESET:
+		lpass_cdc_rsc_clk_reset(tx_dev, TX_CORE_CLK);
+		break;
+	case LPASS_CDC_MACRO_EVT_BCS_CLK_OFF:
+		if (tx_priv->bcs_clk_en)
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_TX0_TX_PATH_SEC7, 0x40, data << 6);
+		if (data)
+			tx_priv->hs_slow_insert_complete = true;
+		else
+			tx_priv->hs_slow_insert_complete = false;
+		break;
+	default:
+		pr_debug("%s Invalid Event\n", __func__);
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_reg_wake_irq(struct snd_soc_component *component,
+				 u32 data)
+{
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	u32 ipc_wakeup = data;
+	int ret = 0;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	if (tx_priv->swr_ctrl_data)
+		ret = swrm_wcd_notify(
+			tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+			SWR_REGISTER_WAKE_IRQ, &ipc_wakeup);
+
+	return ret;
+}
+
+static bool is_amic_enabled(struct snd_soc_component *component, int decimator)
+{
+	u16 adc_mux_reg = 0, adc_reg = 0;
+	u16 adc_n = LPASS_CDC_ADC_MAX;
+	bool ret = false;
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return ret;
+
+	adc_mux_reg = LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
+			LPASS_CDC_TX_MACRO_ADC_MUX_CFG_OFFSET * decimator;
+	if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) {
+		if (tx_priv->version == LPASS_CDC_VERSION_2_1)
+			return true;
+		adc_reg = LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
+			LPASS_CDC_TX_MACRO_ADC_MUX_CFG_OFFSET * decimator;
+		adc_n = snd_soc_component_read32(component, adc_reg) &
+				LPASS_CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK;
+		if (adc_n < LPASS_CDC_ADC_MAX)
+			return true;
+	}
+
+	return ret;
+}
+
+static void lpass_cdc_tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
+{
+	struct delayed_work *hpf_delayed_work = NULL;
+	struct hpf_work *hpf_work = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct snd_soc_component *component = NULL;
+	u16 dec_cfg_reg = 0, hpf_gate_reg = 0;
+	u8 hpf_cut_off_freq = 0;
+	u16 adc_reg = 0, adc_n = 0;
+
+	hpf_delayed_work = to_delayed_work(work);
+	hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
+	tx_priv = hpf_work->tx_priv;
+	component = tx_priv->component;
+	hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
+
+	dec_cfg_reg = LPASS_CDC_TX0_TX_PATH_CFG0 +
+			LPASS_CDC_TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
+	hpf_gate_reg = LPASS_CDC_TX0_TX_PATH_SEC2 +
+			LPASS_CDC_TX_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
+
+	dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
+		__func__, hpf_work->decimator, hpf_cut_off_freq);
+
+	if (is_amic_enabled(component, hpf_work->decimator)) {
+		adc_reg = LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
+			LPASS_CDC_TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
+		adc_n = snd_soc_component_read32(component, adc_reg) &
+				LPASS_CDC_TX_MACRO_SWR_MIC_MUX_SEL_MASK;
+		/* analog mic clear TX hold */
+		lpass_cdc_clear_amic_tx_hold(component->dev, adc_n);
+		snd_soc_component_update_bits(component,
+				dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
+				hpf_cut_off_freq << 5);
+		snd_soc_component_update_bits(component, hpf_gate_reg,
+						0x03, 0x02);
+		/* Add delay between toggle hpf gate based on sample rate */
+		switch(tx_priv->amic_sample_rate) {
+		case 8000:
+			usleep_range(125, 130);
+			break;
+		case 16000:
+			usleep_range(62, 65);
+			break;
+		case 32000:
+			usleep_range(31, 32);
+			break;
+		case 48000:
+			usleep_range(20, 21);
+			break;
+		case 96000:
+			usleep_range(10, 11);
+			break;
+		case 192000:
+			usleep_range(5, 6);
+			break;
+		default:
+			usleep_range(125, 130);
+		}
+		snd_soc_component_update_bits(component, hpf_gate_reg,
+						0x03, 0x01);
+	} else {
+		snd_soc_component_update_bits(component,
+				dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
+				hpf_cut_off_freq << 5);
+		snd_soc_component_update_bits(component, hpf_gate_reg,
+						0x02, 0x02);
+		/* Minimum 1 clk cycle delay is required as per HW spec */
+		usleep_range(1000, 1010);
+		snd_soc_component_update_bits(component, hpf_gate_reg,
+						0x02, 0x00);
+	}
+}
+
+static void lpass_cdc_tx_macro_mute_update_callback(struct work_struct *work)
+{
+	struct tx_mute_work *tx_mute_dwork = NULL;
+	struct snd_soc_component *component = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct delayed_work *delayed_work = NULL;
+	u16 tx_vol_ctl_reg = 0;
+	u8 decimator = 0;
+
+	delayed_work = to_delayed_work(work);
+	tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
+	tx_priv = tx_mute_dwork->tx_priv;
+	component = tx_priv->component;
+	decimator = tx_mute_dwork->decimator;
+
+	tx_vol_ctl_reg =
+		LPASS_CDC_TX0_TX_PATH_CTL +
+			LPASS_CDC_TX_MACRO_TX_PATH_OFFSET * decimator;
+	snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00);
+	dev_dbg(tx_priv->dev, "%s: decimator %u unmute\n",
+		__func__, decimator);
+}
+
+static int lpass_cdc_tx_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int val = 0;
+	u16 mic_sel_reg = 0;
+	u16 dmic_clk_reg = 0;
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	val = ucontrol->value.enumerated.item[0];
+	if (val > e->items - 1)
+		return -EINVAL;
+
+	dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
+		widget->name, val);
+
+	switch (e->reg) {
+	case LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG0:
+		mic_sel_reg = LPASS_CDC_TX0_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG0:
+		mic_sel_reg = LPASS_CDC_TX1_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG0:
+		mic_sel_reg = LPASS_CDC_TX2_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG0:
+		mic_sel_reg = LPASS_CDC_TX3_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_TX_INP_MUX_ADC_MUX4_CFG0:
+		mic_sel_reg = LPASS_CDC_TX4_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_TX_INP_MUX_ADC_MUX5_CFG0:
+		mic_sel_reg = LPASS_CDC_TX5_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_TX_INP_MUX_ADC_MUX6_CFG0:
+		mic_sel_reg = LPASS_CDC_TX6_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_TX_INP_MUX_ADC_MUX7_CFG0:
+		mic_sel_reg = LPASS_CDC_TX7_TX_PATH_CFG0;
+		break;
+	default:
+		dev_err(component->dev, "%s: e->reg: 0x%x not expected\n",
+			__func__, e->reg);
+		return -EINVAL;
+	}
+	if (strnstr(widget->name, "SMIC", strlen(widget->name))) {
+		if (val != 0) {
+			if (val < 5) {
+				snd_soc_component_update_bits(component,
+							mic_sel_reg,
+							1 << 7, 0x0 << 7);
+			} else {
+				snd_soc_component_update_bits(component,
+							mic_sel_reg,
+							1 << 7, 0x1 << 7);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_VA_TOP_CSR_DMIC_CFG,
+					0x80, 0x00);
+				dmic_clk_reg =
+					LPASS_CDC_TX_TOP_CSR_SWR_DMIC0_CTL +
+						((val - 5)/2) * 4;
+				snd_soc_component_update_bits(component,
+					dmic_clk_reg,
+					0x0E, tx_priv->dmic_clk_div << 0x1);
+			}
+		}
+	} else {
+		/* DMIC selected */
+		if (val != 0)
+			snd_soc_component_update_bits(component, mic_sel_reg,
+							1 << 7, 1 << 7);
+	}
+
+	return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
+}
+
+static int lpass_cdc_tx_macro_tx_mixer_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct soc_multi_mixer_control *mixer =
+		((struct soc_multi_mixer_control *)kcontrol->private_value);
+	u32 dai_id = widget->shift;
+	u32 dec_id = mixer->shift;
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	if (test_bit(dec_id, &tx_priv->active_ch_mask[dai_id]))
+		ucontrol->value.integer.value[0] = 1;
+	else
+		ucontrol->value.integer.value[0] = 0;
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct snd_soc_dapm_update *update = NULL;
+	struct soc_multi_mixer_control *mixer =
+		((struct soc_multi_mixer_control *)kcontrol->private_value);
+	u32 dai_id = widget->shift;
+	u32 dec_id = mixer->shift;
+	u32 enable = ucontrol->value.integer.value[0];
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	if (enable) {
+		set_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
+		tx_priv->active_ch_cnt[dai_id]++;
+	} else {
+		tx_priv->active_ch_cnt[dai_id]--;
+		clear_bit(dec_id, &tx_priv->active_ch_mask[dai_id]);
+	}
+	snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
+
+	return 0;
+}
+
+static inline int lpass_cdc_tx_macro_path_get(const char *wname,
+				    unsigned int *path_num)
+{
+	int ret = 0;
+	char *widget_name = NULL;
+	char *w_name = NULL;
+	char *path_num_char = NULL;
+	char *path_name = NULL;
+
+	widget_name = kstrndup(wname, 10, GFP_KERNEL);
+	if (!widget_name)
+		return -EINVAL;
+
+	w_name = widget_name;
+
+	path_name = strsep(&widget_name, " ");
+	if (!path_name) {
+		pr_err("%s: Invalid widget name = %s\n",
+			__func__, widget_name);
+		ret = -EINVAL;
+		goto err;
+	}
+	path_num_char = strpbrk(path_name, "01234567");
+	if (!path_num_char) {
+		pr_err("%s: tx path index not found\n",
+			__func__);
+		ret = -EINVAL;
+		goto err;
+	}
+	ret = kstrtouint(path_num_char, 10, path_num);
+	if (ret < 0)
+		pr_err("%s: Invalid tx path = %s\n",
+			__func__, w_name);
+
+err:
+	kfree(w_name);
+	return ret;
+}
+
+static int lpass_cdc_tx_macro_dec_mode_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct device *tx_dev = NULL;
+	int ret = 0;
+	int path = 0;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	ret = lpass_cdc_tx_macro_path_get(kcontrol->id.name, &path);
+	if (ret)
+		return ret;
+
+	ucontrol->value.integer.value[0] = tx_priv->dec_mode[path];
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct device *tx_dev = NULL;
+	int value = ucontrol->value.integer.value[0];
+	int ret = 0;
+	int path = 0;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	ret = lpass_cdc_tx_macro_path_get(kcontrol->id.name, &path);
+	if (ret)
+		return ret;
+
+	tx_priv->dec_mode[path] = value;
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_lpi_get(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = tx_priv->lpi_enable;
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_lpi_put(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	tx_priv->lpi_enable = ucontrol->value.integer.value[0];
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_bcs_ch_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct device *tx_dev = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.enumerated.item[0] = tx_priv->bcs_ch;
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_bcs_ch_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct device *tx_dev = NULL;
+	int value = ucontrol->value.enumerated.item[0];
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	tx_priv->bcs_ch = value;
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_get_bcs(struct snd_kcontrol *kcontrol,
+                            struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct device *tx_dev = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+	return -EINVAL;
+
+	ucontrol->value.integer.value[0] = tx_priv->bcs_enable;
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_set_bcs(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct device *tx_dev = NULL;
+	int value = ucontrol->value.integer.value[0];
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	tx_priv->bcs_enable = value;
+
+	return 0;
+}
+
+static const char * const bcs_ch_sel_mux_text[] = {
+	"SWR_MIC0", "SWR_MIC1", "SWR_MIC2", "SWR_MIC3",
+	"SWR_MIC4", "SWR_MIC5", "SWR_MIC6", "SWR_MIC7",
+	"SWR_MIC8", "SWR_MIC9", "SWR_MIC10", "SWR_MIC11",
+};
+
+static const struct soc_enum bcs_ch_sel_mux_enum =
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(bcs_ch_sel_mux_text),
+			    bcs_ch_sel_mux_text);
+
+static int lpass_cdc_tx_macro_get_bcs_ch_sel(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct device *tx_dev = NULL;
+	int value = 0;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	if (tx_priv->version == LPASS_CDC_VERSION_2_1)
+		value = (snd_soc_component_read32(component,
+			LPASS_CDC_VA_TOP_CSR_SWR_CTRL)) & 0x0F;
+	else if (tx_priv->version == LPASS_CDC_VERSION_2_0)
+		value = (snd_soc_component_read32(component,
+			LPASS_CDC_TX_TOP_CSR_SWR_CTRL)) & 0x0F;
+
+	ucontrol->value.integer.value[0] = value;
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_put_bcs_ch_sel(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct device *tx_dev = NULL;
+	int value;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	if (ucontrol->value.integer.value[0] < 0 ||
+	    ucontrol->value.integer.value[0] > ARRAY_SIZE(bcs_ch_sel_mux_text))
+		return -EINVAL;
+
+	value = ucontrol->value.integer.value[0];
+	if (tx_priv->version == LPASS_CDC_VERSION_2_1)
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F, value);
+	else if (tx_priv->version == LPASS_CDC_VERSION_2_0)
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_TX_TOP_CSR_SWR_CTRL, 0x0F, value);
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_enable_dmic(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	unsigned int dmic = 0;
+	int ret = 0;
+	char *wname = NULL;
+
+	wname = strpbrk(w->name, "01234567");
+	if (!wname) {
+		dev_err(component->dev, "%s: widget not found\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = kstrtouint(wname, 10, &dmic);
+	if (ret < 0) {
+		dev_err(component->dev, "%s: Invalid DMIC line on the codec\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	dev_dbg(component->dev, "%s: event %d DMIC%d\n",
+			__func__, event,  dmic);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		lpass_cdc_dmic_clk_enable(component, dmic, DMIC_TX, true);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		lpass_cdc_dmic_clk_enable(component, dmic, DMIC_TX, false);
+		break;
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	unsigned int decimator = 0;
+	u16 tx_vol_ctl_reg = 0;
+	u16 dec_cfg_reg = 0;
+	u16 hpf_gate_reg = 0;
+	u16 tx_gain_ctl_reg = 0;
+	u16 tx_fs_reg = 0;
+	u8 hpf_cut_off_freq = 0;
+	u16 adc_mux_reg = 0;
+	int hpf_delay = LPASS_CDC_TX_MACRO_DMIC_HPF_DELAY_MS;
+	int unmute_delay = LPASS_CDC_TX_MACRO_DMIC_UNMUTE_DELAY_MS;
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	decimator = w->shift;
+
+	dev_dbg(component->dev, "%s(): widget = %s decimator = %u\n", __func__,
+			w->name, decimator);
+
+	tx_vol_ctl_reg = LPASS_CDC_TX0_TX_PATH_CTL +
+				LPASS_CDC_TX_MACRO_TX_PATH_OFFSET * decimator;
+	hpf_gate_reg = LPASS_CDC_TX0_TX_PATH_SEC2 +
+				LPASS_CDC_TX_MACRO_TX_PATH_OFFSET * decimator;
+	dec_cfg_reg = LPASS_CDC_TX0_TX_PATH_CFG0 +
+				LPASS_CDC_TX_MACRO_TX_PATH_OFFSET * decimator;
+	tx_gain_ctl_reg = LPASS_CDC_TX0_TX_VOL_CTL +
+				LPASS_CDC_TX_MACRO_TX_PATH_OFFSET * decimator;
+	adc_mux_reg = LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
+			LPASS_CDC_TX_MACRO_ADC_MUX_CFG_OFFSET * decimator;
+	tx_fs_reg = LPASS_CDC_TX0_TX_PATH_CTL +
+				LPASS_CDC_TX_MACRO_TX_PATH_OFFSET * decimator;
+
+	tx_priv->amic_sample_rate = (snd_soc_component_read32(component,
+				     tx_fs_reg) & 0x0F);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_component_update_bits(component,
+			dec_cfg_reg, 0x06, tx_priv->dec_mode[decimator] <<
+			LPASS_CDC_TX_MACRO_ADC_MODE_CFG0_SHIFT);
+		/* Enable TX PGA Mute */
+		snd_soc_component_update_bits(component,
+			tx_vol_ctl_reg, 0x10, 0x10);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		snd_soc_component_update_bits(component,
+			tx_vol_ctl_reg, 0x20, 0x20);
+		if (!is_amic_enabled(component, decimator)) {
+			snd_soc_component_update_bits(component,
+				hpf_gate_reg, 0x01, 0x00);
+			/*
+		 	 * Minimum 1 clk cycle delay is required as per HW spec
+		 	 */
+			usleep_range(1000, 1010);
+		}
+		hpf_cut_off_freq = (
+			snd_soc_component_read32(component, dec_cfg_reg) &
+				TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
+
+		tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq =
+						hpf_cut_off_freq;
+
+		if (hpf_cut_off_freq != CF_MIN_3DB_150HZ)
+			snd_soc_component_update_bits(component, dec_cfg_reg,
+						TX_HPF_CUT_OFF_FREQ_MASK,
+						CF_MIN_3DB_150HZ << 5);
+
+		if (is_amic_enabled(component, decimator)) {
+			hpf_delay = LPASS_CDC_TX_MACRO_AMIC_HPF_DELAY_MS;
+			unmute_delay = LPASS_CDC_TX_MACRO_AMIC_UNMUTE_DELAY_MS;
+		}
+		if (tx_unmute_delay < unmute_delay)
+			tx_unmute_delay = unmute_delay;
+		/* schedule work queue to Remove Mute */
+		queue_delayed_work(system_freezable_wq,
+				   &tx_priv->tx_mute_dwork[decimator].dwork,
+				   msecs_to_jiffies(tx_unmute_delay));
+		if (tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq !=
+							CF_MIN_3DB_150HZ) {
+			queue_delayed_work(system_freezable_wq,
+				&tx_priv->tx_hpf_work[decimator].dwork,
+				msecs_to_jiffies(hpf_delay));
+			snd_soc_component_update_bits(component,
+					hpf_gate_reg, 0x03, 0x02);
+			if (!is_amic_enabled(component, decimator))
+				snd_soc_component_update_bits(component,
+					hpf_gate_reg, 0x03, 0x00);
+			snd_soc_component_update_bits(component,
+					hpf_gate_reg, 0x03, 0x01);
+			/*
+			 * 6ms delay is required as per HW spec
+			 */
+			usleep_range(6000, 6010);
+		}
+		/* apply gain after decimator is enabled */
+		snd_soc_component_write(component, tx_gain_ctl_reg,
+			      snd_soc_component_read32(component,
+					tx_gain_ctl_reg));
+		if (tx_priv->bcs_enable) {
+			if (tx_priv->version == LPASS_CDC_VERSION_2_1)
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F,
+					tx_priv->bcs_ch);
+			else if (tx_priv->version == LPASS_CDC_VERSION_2_0)
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_CTRL, 0xF0,
+					(tx_priv->bcs_ch << 4));
+
+			snd_soc_component_update_bits(component, dec_cfg_reg,
+					0x01, 0x01);
+			tx_priv->bcs_clk_en = true;
+			if (tx_priv->hs_slow_insert_complete)
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX0_TX_PATH_SEC7, 0x40,
+					0x40);
+		}
+		if (tx_priv->version == LPASS_CDC_VERSION_2_0) {
+			if (snd_soc_component_read32(component, adc_mux_reg)
+							& SWR_MIC) {
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_CTRL,
+					0x01, 0x01);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC0_CTL,
+					0x0E, 0x0C);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC1_CTL,
+					0x0E, 0x0C);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC2_CTL,
+					0x0E, 0x00);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC3_CTL,
+					0x0E, 0x00);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC4_CTL,
+					0x0E, 0x00);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC5_CTL,
+					0x0E, 0x00);
+			}
+		}
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		hpf_cut_off_freq =
+			tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq;
+		snd_soc_component_update_bits(component,
+				tx_vol_ctl_reg, 0x10, 0x10);
+		if (cancel_delayed_work_sync(
+		    &tx_priv->tx_hpf_work[decimator].dwork)) {
+			if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
+				snd_soc_component_update_bits(
+						component, dec_cfg_reg,
+						TX_HPF_CUT_OFF_FREQ_MASK,
+						hpf_cut_off_freq << 5);
+				if (is_amic_enabled(component, decimator))
+					snd_soc_component_update_bits(component,
+							hpf_gate_reg,
+							0x03, 0x02);
+				else
+					snd_soc_component_update_bits(component,
+							hpf_gate_reg,
+							0x03, 0x03);
+
+				/*
+				 * Minimum 1 clk cycle delay is required
+				 * as per HW spec
+				 */
+				usleep_range(1000, 1010);
+				snd_soc_component_update_bits(component,
+						hpf_gate_reg,
+						0x03, 0x01);
+			}
+		}
+		cancel_delayed_work_sync(
+				&tx_priv->tx_mute_dwork[decimator].dwork);
+
+		if (tx_priv->version == LPASS_CDC_VERSION_2_0) {
+			if (snd_soc_component_read32(component, adc_mux_reg)
+							& SWR_MIC)
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_CTRL,
+					0x01, 0x00);
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
+						0x20, 0x00);
+		snd_soc_component_update_bits(component,
+			dec_cfg_reg, 0x06, 0x00);
+		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
+						0x10, 0x00);
+		if (tx_priv->bcs_enable) {
+			snd_soc_component_update_bits(component, dec_cfg_reg,
+					0x01, 0x00);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00);
+			tx_priv->bcs_clk_en = false;
+			if (tx_priv->version == LPASS_CDC_VERSION_2_1)
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_VA_TOP_CSR_SWR_CTRL, 0x0F,
+					0x00);
+			else if (tx_priv->version == LPASS_CDC_VERSION_2_0)
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_CTRL, 0xF0,
+					0x00);
+		}
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_enable_micbias(struct snd_soc_dapm_widget *w,
+			struct snd_kcontrol *kcontrol, int event)
+{
+	return 0;
+}
+
+/* Cutoff frequency for high pass filter */
+static const char * const cf_text[] = {
+	"CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
+};
+
+static SOC_ENUM_SINGLE_DECL(cf_dec0_enum, LPASS_CDC_TX0_TX_PATH_CFG0, 5,
+							cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec1_enum, LPASS_CDC_TX1_TX_PATH_CFG0, 5,
+							cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec2_enum, LPASS_CDC_TX2_TX_PATH_CFG0, 5,
+							cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec3_enum, LPASS_CDC_TX3_TX_PATH_CFG0, 5,
+							cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec4_enum, LPASS_CDC_TX4_TX_PATH_CFG0, 5,
+							cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec5_enum, LPASS_CDC_TX5_TX_PATH_CFG0, 5,
+							cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec6_enum, LPASS_CDC_TX6_TX_PATH_CFG0, 5,
+							cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec7_enum, LPASS_CDC_TX7_TX_PATH_CFG0, 5,
+							cf_text);
+
+static int lpass_cdc_tx_macro_hw_params(struct snd_pcm_substream *substream,
+			   struct snd_pcm_hw_params *params,
+			   struct snd_soc_dai *dai)
+{
+	int tx_fs_rate = -EINVAL;
+	struct snd_soc_component *component = dai->component;
+	u32 decimator = 0;
+	u32 sample_rate = 0;
+	u16 tx_fs_reg = 0;
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
+		 dai->name, dai->id, params_rate(params),
+		 params_channels(params));
+
+	sample_rate = params_rate(params);
+	switch (sample_rate) {
+	case 8000:
+		tx_fs_rate = 0;
+		break;
+	case 16000:
+		tx_fs_rate = 1;
+		break;
+	case 32000:
+		tx_fs_rate = 3;
+		break;
+	case 48000:
+		tx_fs_rate = 4;
+		break;
+	case 96000:
+		tx_fs_rate = 5;
+		break;
+	case 192000:
+		tx_fs_rate = 6;
+		break;
+	case 384000:
+		tx_fs_rate = 7;
+		break;
+	default:
+		dev_err(component->dev, "%s: Invalid TX sample rate: %d\n",
+			__func__, params_rate(params));
+		return -EINVAL;
+	}
+	for_each_set_bit(decimator, &tx_priv->active_ch_mask[dai->id],
+			 LPASS_CDC_TX_MACRO_DEC_MAX) {
+		if (decimator >= 0) {
+			tx_fs_reg = LPASS_CDC_TX0_TX_PATH_CTL +
+				    LPASS_CDC_TX_MACRO_TX_PATH_OFFSET * decimator;
+			dev_dbg(component->dev, "%s: set DEC%u rate to %u\n",
+				__func__, decimator, sample_rate);
+			snd_soc_component_update_bits(component, tx_fs_reg,
+						0x0F, tx_fs_rate);
+		} else {
+			dev_err(component->dev,
+				"%s: ERROR: Invalid decimator: %d\n",
+				__func__, decimator);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_get_channel_map(struct snd_soc_dai *dai,
+				unsigned int *tx_num, unsigned int *tx_slot,
+				unsigned int *rx_num, unsigned int *rx_slot)
+{
+	struct snd_soc_component *component = dai->component;
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	switch (dai->id) {
+	case LPASS_CDC_TX_MACRO_AIF1_CAP:
+	case LPASS_CDC_TX_MACRO_AIF2_CAP:
+	case LPASS_CDC_TX_MACRO_AIF3_CAP:
+		*tx_slot = tx_priv->active_ch_mask[dai->id];
+		*tx_num = tx_priv->active_ch_cnt[dai->id];
+		break;
+	default:
+		dev_err(tx_dev, "%s: Invalid AIF\n", __func__);
+		break;
+	}
+	return 0;
+}
+
+static struct snd_soc_dai_ops lpass_cdc_tx_macro_dai_ops = {
+	.hw_params = lpass_cdc_tx_macro_hw_params,
+	.get_channel_map = lpass_cdc_tx_macro_get_channel_map,
+};
+
+static struct snd_soc_dai_driver lpass_cdc_tx_macro_dai[] = {
+	{
+		.name = "lpass_cdc_tx_macro_tx1",
+		.id = LPASS_CDC_TX_MACRO_AIF1_CAP,
+		.capture = {
+			.stream_name = "TX_AIF1 Capture",
+			.rates = LPASS_CDC_TX_MACRO_RATES,
+			.formats = LPASS_CDC_TX_MACRO_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 8,
+		},
+		.ops = &lpass_cdc_tx_macro_dai_ops,
+	},
+	{
+		.name = "lpass_cdc_tx_macro_tx2",
+		.id = LPASS_CDC_TX_MACRO_AIF2_CAP,
+		.capture = {
+			.stream_name = "TX_AIF2 Capture",
+			.rates = LPASS_CDC_TX_MACRO_RATES,
+			.formats = LPASS_CDC_TX_MACRO_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 8,
+		},
+		.ops = &lpass_cdc_tx_macro_dai_ops,
+	},
+	{
+		.name = "lpass_cdc_tx_macro_tx3",
+		.id = LPASS_CDC_TX_MACRO_AIF3_CAP,
+		.capture = {
+			.stream_name = "TX_AIF3 Capture",
+			.rates = LPASS_CDC_TX_MACRO_RATES,
+			.formats = LPASS_CDC_TX_MACRO_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 8,
+		},
+		.ops = &lpass_cdc_tx_macro_dai_ops,
+	},
+};
+
+#define STRING(name) #name
+#define LPASS_CDC_TX_MACRO_DAPM_ENUM(name, reg, offset, text) \
+static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
+static const struct snd_kcontrol_new name##_mux = \
+		SOC_DAPM_ENUM(STRING(name), name##_enum)
+
+#define LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
+static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
+static const struct snd_kcontrol_new name##_mux = \
+		SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
+
+#define LPASS_CDC_TX_MACRO_DAPM_MUX(name, shift, kctl) \
+		SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
+
+static const char * const adc_mux_text[] = {
+	"MSM_DMIC", "SWR_MIC", "ANC_FB_TUNE1"
+};
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM(tx_dec0, LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_TX_MACRO_DAPM_ENUM(tx_dec1, LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_TX_MACRO_DAPM_ENUM(tx_dec2, LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_TX_MACRO_DAPM_ENUM(tx_dec3, LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_TX_MACRO_DAPM_ENUM(tx_dec4, LPASS_CDC_TX_INP_MUX_ADC_MUX4_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_TX_MACRO_DAPM_ENUM(tx_dec5, LPASS_CDC_TX_INP_MUX_ADC_MUX5_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_TX_MACRO_DAPM_ENUM(tx_dec6, LPASS_CDC_TX_INP_MUX_ADC_MUX6_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_TX_MACRO_DAPM_ENUM(tx_dec7, LPASS_CDC_TX_INP_MUX_ADC_MUX7_CFG1,
+		   0, adc_mux_text);
+
+
+static const char * const dmic_mux_text[] = {
+	"ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3",
+	"DMIC4", "DMIC5", "DMIC6", "DMIC7"
+};
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_dmic0, LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_dmic1, LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_dmic2, LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_dmic3, LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_dmic4, LPASS_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_dmic5, LPASS_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_dmic6, LPASS_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_dmic7, LPASS_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+static const char * const smic_mux_text[] = {
+	"ZERO", "ADC0", "ADC1", "ADC2", "ADC3", "SWR_DMIC0",
+	"SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3", "SWR_DMIC4",
+	"SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7"
+};
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic0, LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic1, LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic2, LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic3, LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic4, LPASS_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic5, LPASS_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic6, LPASS_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic7, LPASS_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+static const char * const smic_mux_text_v2[] = {
+	"ZERO", "SWR_MIC0", "SWR_MIC1", "SWR_MIC2", "SWR_MIC3",
+	"SWR_MIC4", "SWR_MIC5", "SWR_MIC6", "SWR_MIC7",
+	"SWR_MIC8", "SWR_MIC9", "SWR_MIC10", "SWR_MIC11"
+};
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic0_v2, LPASS_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic1_v2, LPASS_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic2_v2, LPASS_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic3_v2, LPASS_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic4_v3, LPASS_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic5_v3, LPASS_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic6_v3, LPASS_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+LPASS_CDC_TX_MACRO_DAPM_ENUM_EXT(tx_smic7_v3, LPASS_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_tx_macro_put_dec_enum);
+
+static const char * const dec_mode_mux_text[] = {
+	"ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF",
+};
+
+static const struct soc_enum dec_mode_mux_enum =
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dec_mode_mux_text),
+			    dec_mode_mux_text);
+
+static const char * const bcs_ch_enum_text[] = {
+	"CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", "CH8", "CH9",
+	"CH10", "CH11",
+};
+
+static const struct soc_enum bcs_ch_enum =
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(bcs_ch_enum_text),
+			    bcs_ch_enum_text);
+
+static const struct snd_kcontrol_new tx_aif1_cap_mixer[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC0, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC1, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC2, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC3, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC4, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC5, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC6, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC7, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new tx_aif2_cap_mixer[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC0, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC1, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC2, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC3, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC4, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC5, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC6, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC7, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new tx_aif3_cap_mixer[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC0, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC1, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC2, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC3, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC4, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC5, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC6, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC7, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new tx_aif1_cap_mixer_v2[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC0, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC1, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC2, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC3, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new tx_aif2_cap_mixer_v2[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC0, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC1, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC2, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC3, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new tx_aif3_cap_mixer_v2[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC0, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC1, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC2, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_DEC3, 1, 0,
+			lpass_cdc_tx_macro_tx_mixer_get, lpass_cdc_tx_macro_tx_mixer_put),
+};
+
+static const struct snd_soc_dapm_widget lpass_cdc_tx_macro_dapm_widgets_common[] = {
+	SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_TX_MACRO_AIF1_CAP, 0),
+
+	SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_TX_MACRO_AIF2_CAP, 0),
+
+	SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_TX_MACRO_AIF3_CAP, 0),
+
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX0", 0, tx_dmic0),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX1", 0, tx_dmic1),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3),
+
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0_v2),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1_v2),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2_v2),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3_v2),
+
+	SND_SOC_DAPM_SUPPLY("TX MIC BIAS1", SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_micbias,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC0", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC2", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC3", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC4", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC5", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC6", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC7", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_INPUT("TX SWR_INPUT"),
+
+	SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC0, 0,
+			   &tx_dec0_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC1, 0,
+			   &tx_dec1_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC2, 0,
+			   &tx_dec2_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC3, 0,
+			   &tx_dec3_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0,
+	lpass_cdc_tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("TX_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
+			      lpass_cdc_tx_macro_swr_pwr_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_widget lpass_cdc_tx_macro_dapm_widgets_v2[] = {
+	SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_TX_MACRO_AIF1_CAP, 0,
+		tx_aif1_cap_mixer_v2, ARRAY_SIZE(tx_aif1_cap_mixer_v2)),
+
+	SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_TX_MACRO_AIF2_CAP, 0,
+		tx_aif2_cap_mixer_v2, ARRAY_SIZE(tx_aif2_cap_mixer_v2)),
+
+	SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_TX_MACRO_AIF3_CAP, 0,
+		tx_aif3_cap_mixer_v2, ARRAY_SIZE(tx_aif3_cap_mixer_v2)),
+};
+
+static const struct snd_soc_dapm_widget lpass_cdc_tx_macro_dapm_widgets_v3[] = {
+	SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_TX_MACRO_AIF1_CAP, 0,
+		tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)),
+
+	SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_TX_MACRO_AIF2_CAP, 0,
+		tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)),
+
+	SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_TX_MACRO_AIF3_CAP, 0,
+		tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)),
+
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX4", 0, tx_dmic4),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX5", 0, tx_dmic5),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7),
+
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4_v3),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5_v3),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6_v3),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX7", 0, tx_smic7_v3),
+
+	SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC4, 0,
+			   &tx_dec4_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC5, 0,
+			   &tx_dec5_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC6, 0,
+			   &tx_dec6_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC7, 0,
+			   &tx_dec7_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+			lpass_cdc_tx_macro_tx_swr_clk_event,
+			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+			lpass_cdc_tx_macro_va_swr_clk_event,
+			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_widget lpass_cdc_tx_macro_dapm_widgets[] = {
+	SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_TX_MACRO_AIF1_CAP, 0),
+
+	SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_TX_MACRO_AIF2_CAP, 0),
+
+	SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_TX_MACRO_AIF3_CAP, 0),
+
+	SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_AIF1_CAP, 0,
+		tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)),
+
+	SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_AIF2_CAP, 0,
+		tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)),
+
+	SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM, LPASS_CDC_TX_MACRO_AIF3_CAP, 0,
+		tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)),
+
+
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX0", 0, tx_dmic0),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX1", 0, tx_dmic1),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX4", 0, tx_dmic4),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX5", 0, tx_dmic5),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7),
+
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6),
+	LPASS_CDC_TX_MACRO_DAPM_MUX("TX SMIC MUX7", 0, tx_smic7),
+
+	SND_SOC_DAPM_SUPPLY("TX MIC BIAS1", SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_micbias,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_ADC_E("TX DMIC0", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC2", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC3", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC4", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC5", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC6", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("TX DMIC7", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_INPUT("TX SWR_ADC0"),
+	SND_SOC_DAPM_INPUT("TX SWR_ADC1"),
+	SND_SOC_DAPM_INPUT("TX SWR_ADC2"),
+	SND_SOC_DAPM_INPUT("TX SWR_ADC3"),
+	SND_SOC_DAPM_INPUT("TX SWR_DMIC0"),
+	SND_SOC_DAPM_INPUT("TX SWR_DMIC1"),
+	SND_SOC_DAPM_INPUT("TX SWR_DMIC2"),
+	SND_SOC_DAPM_INPUT("TX SWR_DMIC3"),
+	SND_SOC_DAPM_INPUT("TX SWR_DMIC4"),
+	SND_SOC_DAPM_INPUT("TX SWR_DMIC5"),
+	SND_SOC_DAPM_INPUT("TX SWR_DMIC6"),
+	SND_SOC_DAPM_INPUT("TX SWR_DMIC7"),
+
+	SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC0, 0,
+			   &tx_dec0_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC1, 0,
+			   &tx_dec1_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC2, 0,
+			   &tx_dec2_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC3, 0,
+			   &tx_dec3_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC4, 0,
+			   &tx_dec4_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC5, 0,
+			   &tx_dec5_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC6, 0,
+			   &tx_dec6_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM,
+			   LPASS_CDC_TX_MACRO_DEC7, 0,
+			   &tx_dec7_mux, lpass_cdc_tx_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0,
+	lpass_cdc_tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+			lpass_cdc_tx_macro_tx_swr_clk_event,
+			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+			lpass_cdc_tx_macro_va_swr_clk_event,
+			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_route tx_audio_map_common[] = {
+	{"TX_AIF1 CAP", NULL, "TX_MCLK"},
+	{"TX_AIF2 CAP", NULL, "TX_MCLK"},
+	{"TX_AIF3 CAP", NULL, "TX_MCLK"},
+
+	{"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"},
+	{"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"},
+	{"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"},
+
+	{"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"},
+
+	{"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"},
+
+	{"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"},
+
+	{"TX DEC0 MUX", NULL, "TX_MCLK"},
+	{"TX DEC1 MUX", NULL, "TX_MCLK"},
+	{"TX DEC2 MUX", NULL, "TX_MCLK"},
+	{"TX DEC3 MUX", NULL, "TX_MCLK"},
+
+	{"TX DEC0 MUX", "MSM_DMIC", "TX DMIC MUX0"},
+	{"TX DMIC MUX0", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX0", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX0", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX0", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX0", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX0", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX0", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX0", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"},
+	{"TX SMIC MUX0", "SWR_MIC0", "TX SWR_INPUT"},
+	{"TX SMIC MUX0", "SWR_MIC1", "TX SWR_INPUT"},
+	{"TX SMIC MUX0", "SWR_MIC2", "TX SWR_INPUT"},
+	{"TX SMIC MUX0", "SWR_MIC3", "TX SWR_INPUT"},
+	{"TX SMIC MUX0", "SWR_MIC4", "TX SWR_INPUT"},
+	{"TX SMIC MUX0", "SWR_MIC5", "TX SWR_INPUT"},
+	{"TX SMIC MUX0", "SWR_MIC6", "TX SWR_INPUT"},
+	{"TX SMIC MUX0", "SWR_MIC7", "TX SWR_INPUT"},
+	{"TX SMIC MUX0", "SWR_MIC8", "TX SWR_INPUT"},
+	{"TX SMIC MUX0", "SWR_MIC9", "TX SWR_INPUT"},
+	{"TX SMIC MUX0", "SWR_MIC10", "TX SWR_INPUT"},
+	{"TX SMIC MUX0", "SWR_MIC11", "TX SWR_INPUT"},
+
+	{"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"},
+	{"TX DMIC MUX1", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX1", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX1", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX1", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX1", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX1", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX1", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX1", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"},
+	{"TX SMIC MUX1", "SWR_MIC0", "TX SWR_INPUT"},
+	{"TX SMIC MUX1", "SWR_MIC1", "TX SWR_INPUT"},
+	{"TX SMIC MUX1", "SWR_MIC2", "TX SWR_INPUT"},
+	{"TX SMIC MUX1", "SWR_MIC3", "TX SWR_INPUT"},
+	{"TX SMIC MUX1", "SWR_MIC4", "TX SWR_INPUT"},
+	{"TX SMIC MUX1", "SWR_MIC5", "TX SWR_INPUT"},
+	{"TX SMIC MUX1", "SWR_MIC6", "TX SWR_INPUT"},
+	{"TX SMIC MUX1", "SWR_MIC7", "TX SWR_INPUT"},
+	{"TX SMIC MUX1", "SWR_MIC8", "TX SWR_INPUT"},
+	{"TX SMIC MUX1", "SWR_MIC9", "TX SWR_INPUT"},
+	{"TX SMIC MUX1", "SWR_MIC10", "TX SWR_INPUT"},
+	{"TX SMIC MUX1", "SWR_MIC11", "TX SWR_INPUT"},
+
+	{"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"},
+	{"TX DMIC MUX2", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX2", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX2", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX2", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX2", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX2", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX2", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX2", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"},
+	{"TX SMIC MUX2", "SWR_MIC0", "TX SWR_INPUT"},
+	{"TX SMIC MUX2", "SWR_MIC1", "TX SWR_INPUT"},
+	{"TX SMIC MUX2", "SWR_MIC2", "TX SWR_INPUT"},
+	{"TX SMIC MUX2", "SWR_MIC3", "TX SWR_INPUT"},
+	{"TX SMIC MUX2", "SWR_MIC4", "TX SWR_INPUT"},
+	{"TX SMIC MUX2", "SWR_MIC5", "TX SWR_INPUT"},
+	{"TX SMIC MUX2", "SWR_MIC6", "TX SWR_INPUT"},
+	{"TX SMIC MUX2", "SWR_MIC7", "TX SWR_INPUT"},
+	{"TX SMIC MUX2", "SWR_MIC8", "TX SWR_INPUT"},
+	{"TX SMIC MUX2", "SWR_MIC9", "TX SWR_INPUT"},
+	{"TX SMIC MUX2", "SWR_MIC10", "TX SWR_INPUT"},
+	{"TX SMIC MUX2", "SWR_MIC11", "TX SWR_INPUT"},
+
+	{"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"},
+	{"TX DMIC MUX3", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX3", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX3", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX3", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX3", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX3", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX3", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX3", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"},
+	{"TX SMIC MUX3", "SWR_MIC0", "TX SWR_INPUT"},
+	{"TX SMIC MUX3", "SWR_MIC1", "TX SWR_INPUT"},
+	{"TX SMIC MUX3", "SWR_MIC2", "TX SWR_INPUT"},
+	{"TX SMIC MUX3", "SWR_MIC3", "TX SWR_INPUT"},
+	{"TX SMIC MUX3", "SWR_MIC4", "TX SWR_INPUT"},
+	{"TX SMIC MUX3", "SWR_MIC5", "TX SWR_INPUT"},
+	{"TX SMIC MUX3", "SWR_MIC6", "TX SWR_INPUT"},
+	{"TX SMIC MUX3", "SWR_MIC7", "TX SWR_INPUT"},
+	{"TX SMIC MUX3", "SWR_MIC8", "TX SWR_INPUT"},
+	{"TX SMIC MUX3", "SWR_MIC9", "TX SWR_INPUT"},
+	{"TX SMIC MUX3", "SWR_MIC10", "TX SWR_INPUT"},
+	{"TX SMIC MUX3", "SWR_MIC11", "TX SWR_INPUT"},
+};
+
+static const struct snd_soc_dapm_route tx_audio_map_v3[] = {
+	{"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"},
+
+	{"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"},
+
+	{"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"},
+
+	{"TX DEC4 MUX", NULL, "TX_MCLK"},
+	{"TX DEC5 MUX", NULL, "TX_MCLK"},
+	{"TX DEC6 MUX", NULL, "TX_MCLK"},
+	{"TX DEC7 MUX", NULL, "TX_MCLK"},
+
+	{"TX DEC4 MUX", "MSM_DMIC", "TX DMIC MUX4"},
+	{"TX DMIC MUX4", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX4", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX4", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX4", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX4", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX4", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX4", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX4", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"},
+	{"TX SMIC MUX4", "SWR_MIC0", "TX SWR_INPUT"},
+	{"TX SMIC MUX4", "SWR_MIC1", "TX SWR_INPUT"},
+	{"TX SMIC MUX4", "SWR_MIC2", "TX SWR_INPUT"},
+	{"TX SMIC MUX4", "SWR_MIC3", "TX SWR_INPUT"},
+	{"TX SMIC MUX4", "SWR_MIC4", "TX SWR_INPUT"},
+	{"TX SMIC MUX4", "SWR_MIC5", "TX SWR_INPUT"},
+	{"TX SMIC MUX4", "SWR_MIC6", "TX SWR_INPUT"},
+	{"TX SMIC MUX4", "SWR_MIC7", "TX SWR_INPUT"},
+	{"TX SMIC MUX4", "SWR_MIC8", "TX SWR_INPUT"},
+	{"TX SMIC MUX4", "SWR_MIC9", "TX SWR_INPUT"},
+	{"TX SMIC MUX4", "SWR_MIC10", "TX SWR_INPUT"},
+	{"TX SMIC MUX4", "SWR_MIC11", "TX SWR_INPUT"},
+
+	{"TX DEC5 MUX", "MSM_DMIC", "TX DMIC MUX5"},
+	{"TX DMIC MUX5", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX5", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX5", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX5", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX5", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX5", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX5", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX5", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"},
+	{"TX SMIC MUX5", "SWR_MIC0", "TX SWR_INPUT"},
+	{"TX SMIC MUX5", "SWR_MIC1", "TX SWR_INPUT"},
+	{"TX SMIC MUX5", "SWR_MIC2", "TX SWR_INPUT"},
+	{"TX SMIC MUX5", "SWR_MIC3", "TX SWR_INPUT"},
+	{"TX SMIC MUX5", "SWR_MIC4", "TX SWR_INPUT"},
+	{"TX SMIC MUX5", "SWR_MIC5", "TX SWR_INPUT"},
+	{"TX SMIC MUX5", "SWR_MIC6", "TX SWR_INPUT"},
+	{"TX SMIC MUX5", "SWR_MIC7", "TX SWR_INPUT"},
+	{"TX SMIC MUX5", "SWR_MIC8", "TX SWR_INPUT"},
+	{"TX SMIC MUX5", "SWR_MIC9", "TX SWR_INPUT"},
+	{"TX SMIC MUX5", "SWR_MIC10", "TX SWR_INPUT"},
+	{"TX SMIC MUX5", "SWR_MIC11", "TX SWR_INPUT"},
+
+	{"TX DEC6 MUX", "MSM_DMIC", "TX DMIC MUX6"},
+	{"TX DMIC MUX6", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX6", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX6", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX6", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX6", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX6", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX6", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX6", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"},
+	{"TX SMIC MUX6", "SWR_MIC0", "TX SWR_INPUT"},
+	{"TX SMIC MUX6", "SWR_MIC1", "TX SWR_INPUT"},
+	{"TX SMIC MUX6", "SWR_MIC2", "TX SWR_INPUT"},
+	{"TX SMIC MUX6", "SWR_MIC3", "TX SWR_INPUT"},
+	{"TX SMIC MUX6", "SWR_MIC4", "TX SWR_INPUT"},
+	{"TX SMIC MUX6", "SWR_MIC5", "TX SWR_INPUT"},
+	{"TX SMIC MUX6", "SWR_MIC6", "TX SWR_INPUT"},
+	{"TX SMIC MUX6", "SWR_MIC7", "TX SWR_INPUT"},
+	{"TX SMIC MUX6", "SWR_MIC8", "TX SWR_INPUT"},
+	{"TX SMIC MUX6", "SWR_MIC9", "TX SWR_INPUT"},
+	{"TX SMIC MUX6", "SWR_MIC10", "TX SWR_INPUT"},
+	{"TX SMIC MUX6", "SWR_MIC11", "TX SWR_INPUT"},
+
+	{"TX DEC7 MUX", "MSM_DMIC", "TX DMIC MUX7"},
+	{"TX DMIC MUX7", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX7", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX7", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX7", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX7", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX7", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX7", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX7", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"},
+	{"TX SMIC MUX7", "SWR_MIC0", "TX SWR_INPUT"},
+	{"TX SMIC MUX7", "SWR_MIC1", "TX SWR_INPUT"},
+	{"TX SMIC MUX7", "SWR_MIC2", "TX SWR_INPUT"},
+	{"TX SMIC MUX7", "SWR_MIC3", "TX SWR_INPUT"},
+	{"TX SMIC MUX7", "SWR_MIC4", "TX SWR_INPUT"},
+	{"TX SMIC MUX7", "SWR_MIC5", "TX SWR_INPUT"},
+	{"TX SMIC MUX7", "SWR_MIC6", "TX SWR_INPUT"},
+	{"TX SMIC MUX7", "SWR_MIC7", "TX SWR_INPUT"},
+	{"TX SMIC MUX7", "SWR_MIC8", "TX SWR_INPUT"},
+	{"TX SMIC MUX7", "SWR_MIC9", "TX SWR_INPUT"},
+	{"TX SMIC MUX7", "SWR_MIC10", "TX SWR_INPUT"},
+	{"TX SMIC MUX7", "SWR_MIC11", "TX SWR_INPUT"},
+
+	{"TX SMIC MUX0", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX1", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX2", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX3", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX4", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX5", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX6", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX7", NULL, "TX_SWR_CLK"},
+
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+	{"TX SWR_INPUT", NULL, "TX_SWR_PWR"},
+};
+
+static const struct snd_soc_dapm_route tx_audio_map[] = {
+	{"TX_AIF1 CAP", NULL, "TX_MCLK"},
+	{"TX_AIF2 CAP", NULL, "TX_MCLK"},
+	{"TX_AIF3 CAP", NULL, "TX_MCLK"},
+
+	{"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"},
+	{"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"},
+	{"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"},
+
+	{"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"},
+	{"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"},
+
+	{"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"},
+	{"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"},
+
+	{"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"},
+	{"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"},
+
+	{"TX DEC0 MUX", NULL, "TX_MCLK"},
+	{"TX DEC1 MUX", NULL, "TX_MCLK"},
+	{"TX DEC2 MUX", NULL, "TX_MCLK"},
+	{"TX DEC3 MUX", NULL, "TX_MCLK"},
+	{"TX DEC4 MUX", NULL, "TX_MCLK"},
+	{"TX DEC5 MUX", NULL, "TX_MCLK"},
+	{"TX DEC6 MUX", NULL, "TX_MCLK"},
+	{"TX DEC7 MUX", NULL, "TX_MCLK"},
+
+	{"TX DEC0 MUX", "MSM_DMIC", "TX DMIC MUX0"},
+	{"TX DMIC MUX0", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX0", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX0", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX0", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX0", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX0", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX0", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX0", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"},
+	{"TX SMIC MUX0", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX0", "ADC0", "TX SWR_ADC0"},
+	{"TX SMIC MUX0", "ADC1", "TX SWR_ADC1"},
+	{"TX SMIC MUX0", "ADC2", "TX SWR_ADC2"},
+	{"TX SMIC MUX0", "ADC3", "TX SWR_ADC3"},
+	{"TX SMIC MUX0", "SWR_DMIC0", "TX SWR_DMIC0"},
+	{"TX SMIC MUX0", "SWR_DMIC1", "TX SWR_DMIC1"},
+	{"TX SMIC MUX0", "SWR_DMIC2", "TX SWR_DMIC2"},
+	{"TX SMIC MUX0", "SWR_DMIC3", "TX SWR_DMIC3"},
+	{"TX SMIC MUX0", "SWR_DMIC4", "TX SWR_DMIC4"},
+	{"TX SMIC MUX0", "SWR_DMIC5", "TX SWR_DMIC5"},
+	{"TX SMIC MUX0", "SWR_DMIC6", "TX SWR_DMIC6"},
+	{"TX SMIC MUX0", "SWR_DMIC7", "TX SWR_DMIC7"},
+
+	{"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"},
+	{"TX DMIC MUX1", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX1", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX1", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX1", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX1", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX1", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX1", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX1", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"},
+	{"TX SMIC MUX1", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX1", "ADC0", "TX SWR_ADC0"},
+	{"TX SMIC MUX1", "ADC1", "TX SWR_ADC1"},
+	{"TX SMIC MUX1", "ADC2", "TX SWR_ADC2"},
+	{"TX SMIC MUX1", "ADC3", "TX SWR_ADC3"},
+	{"TX SMIC MUX1", "SWR_DMIC0", "TX SWR_DMIC0"},
+	{"TX SMIC MUX1", "SWR_DMIC1", "TX SWR_DMIC1"},
+	{"TX SMIC MUX1", "SWR_DMIC2", "TX SWR_DMIC2"},
+	{"TX SMIC MUX1", "SWR_DMIC3", "TX SWR_DMIC3"},
+	{"TX SMIC MUX1", "SWR_DMIC4", "TX SWR_DMIC4"},
+	{"TX SMIC MUX1", "SWR_DMIC5", "TX SWR_DMIC5"},
+	{"TX SMIC MUX1", "SWR_DMIC6", "TX SWR_DMIC6"},
+	{"TX SMIC MUX1", "SWR_DMIC7", "TX SWR_DMIC7"},
+
+	{"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"},
+	{"TX DMIC MUX2", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX2", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX2", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX2", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX2", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX2", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX2", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX2", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"},
+	{"TX SMIC MUX2", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX2", "ADC0", "TX SWR_ADC0"},
+	{"TX SMIC MUX2", "ADC1", "TX SWR_ADC1"},
+	{"TX SMIC MUX2", "ADC2", "TX SWR_ADC2"},
+	{"TX SMIC MUX2", "ADC3", "TX SWR_ADC3"},
+	{"TX SMIC MUX2", "SWR_DMIC0", "TX SWR_DMIC0"},
+	{"TX SMIC MUX2", "SWR_DMIC1", "TX SWR_DMIC1"},
+	{"TX SMIC MUX2", "SWR_DMIC2", "TX SWR_DMIC2"},
+	{"TX SMIC MUX2", "SWR_DMIC3", "TX SWR_DMIC3"},
+	{"TX SMIC MUX2", "SWR_DMIC4", "TX SWR_DMIC4"},
+	{"TX SMIC MUX2", "SWR_DMIC5", "TX SWR_DMIC5"},
+	{"TX SMIC MUX2", "SWR_DMIC6", "TX SWR_DMIC6"},
+	{"TX SMIC MUX2", "SWR_DMIC7", "TX SWR_DMIC7"},
+
+	{"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"},
+	{"TX DMIC MUX3", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX3", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX3", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX3", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX3", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX3", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX3", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX3", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"},
+	{"TX SMIC MUX3", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX3", "ADC0", "TX SWR_ADC0"},
+	{"TX SMIC MUX3", "ADC1", "TX SWR_ADC1"},
+	{"TX SMIC MUX3", "ADC2", "TX SWR_ADC2"},
+	{"TX SMIC MUX3", "ADC3", "TX SWR_ADC3"},
+	{"TX SMIC MUX3", "SWR_DMIC0", "TX SWR_DMIC0"},
+	{"TX SMIC MUX3", "SWR_DMIC1", "TX SWR_DMIC1"},
+	{"TX SMIC MUX3", "SWR_DMIC2", "TX SWR_DMIC2"},
+	{"TX SMIC MUX3", "SWR_DMIC3", "TX SWR_DMIC3"},
+	{"TX SMIC MUX3", "SWR_DMIC4", "TX SWR_DMIC4"},
+	{"TX SMIC MUX3", "SWR_DMIC5", "TX SWR_DMIC5"},
+	{"TX SMIC MUX3", "SWR_DMIC6", "TX SWR_DMIC6"},
+	{"TX SMIC MUX3", "SWR_DMIC7", "TX SWR_DMIC7"},
+
+	{"TX DEC4 MUX", "MSM_DMIC", "TX DMIC MUX4"},
+	{"TX DMIC MUX4", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX4", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX4", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX4", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX4", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX4", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX4", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX4", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"},
+	{"TX SMIC MUX4", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX4", "ADC0", "TX SWR_ADC0"},
+	{"TX SMIC MUX4", "ADC1", "TX SWR_ADC1"},
+	{"TX SMIC MUX4", "ADC2", "TX SWR_ADC2"},
+	{"TX SMIC MUX4", "ADC3", "TX SWR_ADC3"},
+	{"TX SMIC MUX4", "SWR_DMIC0", "TX SWR_DMIC0"},
+	{"TX SMIC MUX4", "SWR_DMIC1", "TX SWR_DMIC1"},
+	{"TX SMIC MUX4", "SWR_DMIC2", "TX SWR_DMIC2"},
+	{"TX SMIC MUX4", "SWR_DMIC3", "TX SWR_DMIC3"},
+	{"TX SMIC MUX4", "SWR_DMIC4", "TX SWR_DMIC4"},
+	{"TX SMIC MUX4", "SWR_DMIC5", "TX SWR_DMIC5"},
+	{"TX SMIC MUX4", "SWR_DMIC6", "TX SWR_DMIC6"},
+	{"TX SMIC MUX4", "SWR_DMIC7", "TX SWR_DMIC7"},
+
+	{"TX DEC5 MUX", "MSM_DMIC", "TX DMIC MUX5"},
+	{"TX DMIC MUX5", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX5", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX5", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX5", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX5", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX5", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX5", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX5", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"},
+	{"TX SMIC MUX5", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX5", "ADC0", "TX SWR_ADC0"},
+	{"TX SMIC MUX5", "ADC1", "TX SWR_ADC1"},
+	{"TX SMIC MUX5", "ADC2", "TX SWR_ADC2"},
+	{"TX SMIC MUX5", "ADC3", "TX SWR_ADC3"},
+	{"TX SMIC MUX5", "SWR_DMIC0", "TX SWR_DMIC0"},
+	{"TX SMIC MUX5", "SWR_DMIC1", "TX SWR_DMIC1"},
+	{"TX SMIC MUX5", "SWR_DMIC2", "TX SWR_DMIC2"},
+	{"TX SMIC MUX5", "SWR_DMIC3", "TX SWR_DMIC3"},
+	{"TX SMIC MUX5", "SWR_DMIC4", "TX SWR_DMIC4"},
+	{"TX SMIC MUX5", "SWR_DMIC5", "TX SWR_DMIC5"},
+	{"TX SMIC MUX5", "SWR_DMIC6", "TX SWR_DMIC6"},
+	{"TX SMIC MUX5", "SWR_DMIC7", "TX SWR_DMIC7"},
+
+	{"TX DEC6 MUX", "MSM_DMIC", "TX DMIC MUX6"},
+	{"TX DMIC MUX6", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX6", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX6", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX6", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX6", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX6", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX6", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX6", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"},
+	{"TX SMIC MUX6", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX6", "ADC0", "TX SWR_ADC0"},
+	{"TX SMIC MUX6", "ADC1", "TX SWR_ADC1"},
+	{"TX SMIC MUX6", "ADC2", "TX SWR_ADC2"},
+	{"TX SMIC MUX6", "ADC3", "TX SWR_ADC3"},
+	{"TX SMIC MUX6", "SWR_DMIC0", "TX SWR_DMIC0"},
+	{"TX SMIC MUX6", "SWR_DMIC1", "TX SWR_DMIC1"},
+	{"TX SMIC MUX6", "SWR_DMIC2", "TX SWR_DMIC2"},
+	{"TX SMIC MUX6", "SWR_DMIC3", "TX SWR_DMIC3"},
+	{"TX SMIC MUX6", "SWR_DMIC4", "TX SWR_DMIC4"},
+	{"TX SMIC MUX6", "SWR_DMIC5", "TX SWR_DMIC5"},
+	{"TX SMIC MUX6", "SWR_DMIC6", "TX SWR_DMIC6"},
+	{"TX SMIC MUX6", "SWR_DMIC7", "TX SWR_DMIC7"},
+
+	{"TX DEC7 MUX", "MSM_DMIC", "TX DMIC MUX7"},
+	{"TX DMIC MUX7", "DMIC0", "TX DMIC0"},
+	{"TX DMIC MUX7", "DMIC1", "TX DMIC1"},
+	{"TX DMIC MUX7", "DMIC2", "TX DMIC2"},
+	{"TX DMIC MUX7", "DMIC3", "TX DMIC3"},
+	{"TX DMIC MUX7", "DMIC4", "TX DMIC4"},
+	{"TX DMIC MUX7", "DMIC5", "TX DMIC5"},
+	{"TX DMIC MUX7", "DMIC6", "TX DMIC6"},
+	{"TX DMIC MUX7", "DMIC7", "TX DMIC7"},
+
+	{"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"},
+	{"TX SMIC MUX7", NULL, "TX_SWR_CLK"},
+	{"TX SMIC MUX7", "ADC0", "TX SWR_ADC0"},
+	{"TX SMIC MUX7", "ADC1", "TX SWR_ADC1"},
+	{"TX SMIC MUX7", "ADC2", "TX SWR_ADC2"},
+	{"TX SMIC MUX7", "ADC3", "TX SWR_ADC3"},
+	{"TX SMIC MUX7", "SWR_DMIC0", "TX SWR_DMIC0"},
+	{"TX SMIC MUX7", "SWR_DMIC1", "TX SWR_DMIC1"},
+	{"TX SMIC MUX7", "SWR_DMIC2", "TX SWR_DMIC2"},
+	{"TX SMIC MUX7", "SWR_DMIC3", "TX SWR_DMIC3"},
+	{"TX SMIC MUX7", "SWR_DMIC4", "TX SWR_DMIC4"},
+	{"TX SMIC MUX7", "SWR_DMIC5", "TX SWR_DMIC5"},
+	{"TX SMIC MUX7", "SWR_DMIC6", "TX SWR_DMIC6"},
+	{"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"},
+};
+
+static const struct snd_kcontrol_new lpass_cdc_tx_macro_snd_controls_common[] = {
+	SOC_SINGLE_S8_TLV("TX_DEC0 Volume",
+			  LPASS_CDC_TX0_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC1 Volume",
+			  LPASS_CDC_TX1_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC2 Volume",
+			  LPASS_CDC_TX2_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC3 Volume",
+			  LPASS_CDC_TX3_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+
+	SOC_SINGLE_EXT("TX LPI Enable", 0, 0, 1, 0,
+		lpass_cdc_tx_macro_lpi_get, lpass_cdc_tx_macro_lpi_put),
+
+	SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0,
+		       lpass_cdc_tx_macro_get_bcs, lpass_cdc_tx_macro_set_bcs),
+
+	SOC_ENUM_EXT("BCS Channel", bcs_ch_enum,
+			lpass_cdc_tx_macro_bcs_ch_get, lpass_cdc_tx_macro_bcs_ch_put),
+
+	SOC_ENUM_EXT("BCS CH_SEL", bcs_ch_sel_mux_enum,
+			lpass_cdc_tx_macro_get_bcs_ch_sel, lpass_cdc_tx_macro_put_bcs_ch_sel),
+};
+
+static const struct snd_kcontrol_new lpass_cdc_tx_macro_snd_controls_v3[] = {
+	SOC_SINGLE_S8_TLV("TX_DEC4 Volume",
+			  LPASS_CDC_TX4_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC5 Volume",
+			  LPASS_CDC_TX5_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC6 Volume",
+			  LPASS_CDC_TX6_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC7 Volume",
+			  LPASS_CDC_TX7_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+
+	SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+};
+
+static const struct snd_kcontrol_new lpass_cdc_tx_macro_snd_controls[] = {
+	SOC_SINGLE_S8_TLV("TX_DEC0 Volume",
+			  LPASS_CDC_TX0_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC1 Volume",
+			  LPASS_CDC_TX1_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC2 Volume",
+			  LPASS_CDC_TX2_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC3 Volume",
+			  LPASS_CDC_TX3_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC4 Volume",
+			  LPASS_CDC_TX4_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC5 Volume",
+			  LPASS_CDC_TX5_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC6 Volume",
+			  LPASS_CDC_TX6_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("TX_DEC7 Volume",
+			  LPASS_CDC_TX7_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+
+	SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum,
+			lpass_cdc_tx_macro_dec_mode_get, lpass_cdc_tx_macro_dec_mode_put),
+	SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
+
+	SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
+
+	SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
+
+	SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
+
+	SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
+
+	SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
+
+	SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
+
+	SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
+
+	SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0,
+		       lpass_cdc_tx_macro_get_bcs, lpass_cdc_tx_macro_set_bcs),
+};
+
+static int lpass_cdc_tx_macro_register_event_listener(struct snd_soc_component *component,
+					    bool enable)
+{
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	int ret = 0;
+
+	if (!component)
+		return -EINVAL;
+
+	tx_dev = lpass_cdc_get_device_ptr(component->dev, TX_MACRO);
+	if (!tx_dev) {
+		dev_err(component->dev,
+			"%s: null device for macro!\n", __func__);
+		return -EINVAL;
+	}
+	tx_priv = dev_get_drvdata(tx_dev);
+	if (!tx_priv) {
+		dev_err(component->dev,
+			"%s: priv is null for macro!\n", __func__);
+		return -EINVAL;
+	}
+	if (tx_priv->swr_ctrl_data &&
+		(!tx_priv->tx_swr_clk_cnt || !tx_priv->va_swr_clk_cnt)) {
+		if (enable) {
+			ret = swrm_wcd_notify(
+				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+				SWR_REGISTER_WAKEUP, NULL);
+			msm_cdc_pinctrl_set_wakeup_capable(
+					tx_priv->tx_swr_gpio_p, false);
+		} else {
+			msm_cdc_pinctrl_set_wakeup_capable(
+					tx_priv->tx_swr_gpio_p, true);
+			ret = swrm_wcd_notify(
+				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+				SWR_DEREGISTER_WAKEUP, NULL);
+		}
+	}
+
+	return ret;
+}
+
+static int lpass_cdc_tx_macro_tx_va_mclk_enable(
+				struct lpass_cdc_tx_macro_priv *tx_priv,
+				struct regmap *regmap, int clk_type,
+				bool enable)
+{
+	int ret = 0, clk_tx_ret = 0;
+
+	trace_printk("%s: clock type %s, enable: %s tx_mclk_users: %d\n",
+		__func__, (clk_type ? "VA_MCLK" : "TX_MCLK"),
+		(enable ? "enable" : "disable"), tx_priv->tx_mclk_users);
+	dev_dbg(tx_priv->dev,
+		"%s: clock type %s, enable: %s tx_mclk_users: %d\n",
+		__func__, (clk_type ? "VA_MCLK" : "TX_MCLK"),
+		(enable ? "enable" : "disable"), tx_priv->tx_mclk_users);
+
+	if (enable) {
+		if (tx_priv->swr_clk_users == 0) {
+			trace_printk("%s: tx swr clk users 0\n", __func__);
+			ret = msm_cdc_pinctrl_select_active_state(
+						tx_priv->tx_swr_gpio_p);
+			if (ret < 0) {
+				dev_err_ratelimited(tx_priv->dev,
+					"%s: tx swr pinctrl enable failed\n",
+					__func__);
+				goto exit;
+			}
+		}
+
+		clk_tx_ret = lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
+						   TX_CORE_CLK,
+						   TX_CORE_CLK,
+						   true);
+		if (clk_type == TX_MCLK) {
+			trace_printk("%s: requesting TX_MCLK\n", __func__);
+			ret = lpass_cdc_tx_macro_mclk_enable(tx_priv, 1);
+			if (ret < 0) {
+				if (tx_priv->swr_clk_users == 0)
+					msm_cdc_pinctrl_select_sleep_state(
+							tx_priv->tx_swr_gpio_p);
+				dev_err_ratelimited(tx_priv->dev,
+					"%s: request clock enable failed\n",
+					__func__);
+				goto done;
+			}
+		}
+		if (clk_type == VA_MCLK) {
+			trace_printk("%s: requesting VA_MCLK\n", __func__);
+			ret = lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
+							   TX_CORE_CLK,
+							   VA_CORE_CLK,
+							   true);
+			if (ret < 0) {
+				if (tx_priv->swr_clk_users == 0)
+					msm_cdc_pinctrl_select_sleep_state(
+							tx_priv->tx_swr_gpio_p);
+				dev_err_ratelimited(tx_priv->dev,
+					"%s: swr request clk failed\n",
+					__func__);
+				goto done;
+			}
+			lpass_cdc_clk_rsc_fs_gen_request(tx_priv->dev,
+						  true);
+			if (tx_priv->tx_mclk_users == 0) {
+				regmap_update_bits(regmap,
+					LPASS_CDC_TX_TOP_CSR_FREQ_MCLK,
+					0x01, 0x01);
+				regmap_update_bits(regmap,
+					LPASS_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
+					0x01, 0x01);
+				regmap_update_bits(regmap,
+					LPASS_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
+					0x01, 0x01);
+			}
+			tx_priv->tx_mclk_users++;
+		}
+		if (tx_priv->swr_clk_users == 0) {
+			dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n",
+				__func__, tx_priv->reset_swr);
+			trace_printk("%s: reset_swr: %d\n",
+				__func__, tx_priv->reset_swr);
+			if (tx_priv->reset_swr)
+				regmap_update_bits(regmap,
+					LPASS_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
+					0x02, 0x02);
+			regmap_update_bits(regmap,
+				LPASS_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
+				0x01, 0x01);
+			if (tx_priv->reset_swr)
+				regmap_update_bits(regmap,
+					LPASS_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
+					0x02, 0x00);
+			tx_priv->reset_swr = false;
+		}
+		if (!clk_tx_ret)
+			ret = lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
+						   TX_CORE_CLK,
+						   TX_CORE_CLK,
+						   false);
+		tx_priv->swr_clk_users++;
+	} else {
+		if (tx_priv->swr_clk_users <= 0) {
+			dev_err_ratelimited(tx_priv->dev,
+				"tx swrm clock users already 0\n");
+			tx_priv->swr_clk_users = 0;
+			return 0;
+		}
+		clk_tx_ret = lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
+						   TX_CORE_CLK,
+						   TX_CORE_CLK,
+						   true);
+		tx_priv->swr_clk_users--;
+		if (tx_priv->swr_clk_users == 0)
+			regmap_update_bits(regmap,
+				LPASS_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
+				0x01, 0x00);
+		if (clk_type == TX_MCLK)
+			lpass_cdc_tx_macro_mclk_enable(tx_priv, 0);
+		if (clk_type == VA_MCLK) {
+			if (tx_priv->tx_mclk_users <= 0) {
+				dev_err(tx_priv->dev, "%s: clock already disabled\n",
+						__func__);
+				tx_priv->tx_mclk_users = 0;
+				goto tx_clk;
+			}
+			tx_priv->tx_mclk_users--;
+			if (tx_priv->tx_mclk_users == 0) {
+				regmap_update_bits(regmap,
+					LPASS_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
+					0x01, 0x00);
+				regmap_update_bits(regmap,
+					LPASS_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
+					0x01, 0x00);
+			}
+
+			lpass_cdc_clk_rsc_fs_gen_request(tx_priv->dev,
+						false);
+			ret = lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
+							   TX_CORE_CLK,
+							   VA_CORE_CLK,
+							   false);
+			if (ret < 0) {
+				dev_err_ratelimited(tx_priv->dev,
+					"%s: swr request clk failed\n",
+					__func__);
+				goto done;
+			}
+		}
+tx_clk:
+		if (!clk_tx_ret)
+			ret = lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
+						   TX_CORE_CLK,
+						   TX_CORE_CLK,
+						   false);
+		if (tx_priv->swr_clk_users == 0) {
+			ret = msm_cdc_pinctrl_select_sleep_state(
+						tx_priv->tx_swr_gpio_p);
+			if (ret < 0) {
+				dev_err_ratelimited(tx_priv->dev,
+					"%s: tx swr pinctrl disable failed\n",
+					__func__);
+				goto exit;
+			}
+		}
+	}
+	return 0;
+
+done:
+	if (!clk_tx_ret)
+		lpass_cdc_clk_rsc_request_clock(tx_priv->dev,
+				TX_CORE_CLK,
+				TX_CORE_CLK,
+				false);
+exit:
+	trace_printk("%s: exit\n", __func__);
+	return ret;
+}
+
+static int lpass_cdc_tx_macro_clk_div_get(struct snd_soc_component *component)
+{
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	return tx_priv->dmic_clk_div;
+}
+
+static int lpass_cdc_tx_macro_core_vote(void *handle, bool enable)
+{
+	struct lpass_cdc_tx_macro_priv *tx_priv = (struct lpass_cdc_tx_macro_priv *) handle;
+
+	if (tx_priv == NULL) {
+		pr_err("%s: tx priv data is NULL\n", __func__);
+		return -EINVAL;
+	}
+	if (enable) {
+		pm_runtime_get_sync(tx_priv->dev);
+		pm_runtime_put_autosuspend(tx_priv->dev);
+		pm_runtime_mark_last_busy(tx_priv->dev);
+	}
+
+	if (lpass_cdc_check_core_votes(tx_priv->dev))
+		return 0;
+	else
+		return -EINVAL;
+}
+
+static int lpass_cdc_tx_macro_swrm_clock(void *handle, bool enable)
+{
+	struct lpass_cdc_tx_macro_priv *tx_priv = (struct lpass_cdc_tx_macro_priv *) handle;
+	struct regmap *regmap = dev_get_regmap(tx_priv->dev->parent, NULL);
+	int ret = 0;
+
+	if (regmap == NULL) {
+		dev_err(tx_priv->dev, "%s: regmap is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&tx_priv->swr_clk_lock);
+	trace_printk("%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n",
+		__func__,
+		(enable ? "enable" : "disable"),
+		tx_priv->tx_swr_clk_cnt, tx_priv->va_swr_clk_cnt);
+	dev_dbg(tx_priv->dev,
+		"%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n",
+		__func__, (enable ? "enable" : "disable"),
+		tx_priv->tx_swr_clk_cnt, tx_priv->va_swr_clk_cnt);
+
+	if (enable) {
+		pm_runtime_get_sync(tx_priv->dev);
+		if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt) {
+			ret = lpass_cdc_tx_macro_tx_va_mclk_enable(tx_priv, regmap,
+							VA_MCLK, enable);
+			if (ret) {
+				pm_runtime_mark_last_busy(tx_priv->dev);
+				pm_runtime_put_autosuspend(tx_priv->dev);
+				goto done;
+			}
+			tx_priv->va_clk_status++;
+		} else {
+			ret = lpass_cdc_tx_macro_tx_va_mclk_enable(tx_priv, regmap,
+							TX_MCLK, enable);
+			if (ret) {
+				pm_runtime_mark_last_busy(tx_priv->dev);
+				pm_runtime_put_autosuspend(tx_priv->dev);
+				goto done;
+			}
+			tx_priv->tx_clk_status++;
+		}
+		pm_runtime_mark_last_busy(tx_priv->dev);
+		pm_runtime_put_autosuspend(tx_priv->dev);
+	} else {
+		if (tx_priv->va_clk_status && !tx_priv->tx_clk_status) {
+			ret = lpass_cdc_tx_macro_tx_va_mclk_enable(tx_priv, regmap,
+							VA_MCLK, enable);
+			if (ret)
+				goto done;
+			--tx_priv->va_clk_status;
+		} else if (!tx_priv->va_clk_status && tx_priv->tx_clk_status) {
+			ret = lpass_cdc_tx_macro_tx_va_mclk_enable(tx_priv, regmap,
+							TX_MCLK, enable);
+			if (ret)
+				goto done;
+			--tx_priv->tx_clk_status;
+		} else if (tx_priv->va_clk_status && tx_priv->tx_clk_status) {
+			if (!tx_priv->va_swr_clk_cnt && tx_priv->tx_swr_clk_cnt) {
+				ret = lpass_cdc_tx_macro_tx_va_mclk_enable(tx_priv, regmap,
+								VA_MCLK, enable);
+				if (ret)
+					goto done;
+				--tx_priv->va_clk_status;
+			} else {
+				ret = lpass_cdc_tx_macro_tx_va_mclk_enable(tx_priv, regmap,
+								TX_MCLK, enable);
+				if (ret)
+					goto done;
+				--tx_priv->tx_clk_status;
+			}
+
+		} else {
+			dev_dbg(tx_priv->dev,
+				"%s: Both clocks are disabled\n", __func__);
+		}
+	}
+
+	trace_printk("%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n",
+		__func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status,
+                tx_priv->va_clk_status);
+	dev_dbg(tx_priv->dev,
+		"%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n",
+		__func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status,
+		tx_priv->va_clk_status);
+done:
+	mutex_unlock(&tx_priv->swr_clk_lock);
+	return ret;
+}
+
+static int lpass_cdc_tx_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
+				      struct lpass_cdc_tx_macro_priv *tx_priv)
+{
+	u32 div_factor = LPASS_CDC_TX_MACRO_CLK_DIV_2;
+	u32 mclk_rate = LPASS_CDC_TX_MACRO_MCLK_FREQ;
+
+	if (dmic_sample_rate == LPASS_CDC_TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED ||
+	    mclk_rate % dmic_sample_rate != 0)
+		goto undefined_rate;
+
+	div_factor = mclk_rate / dmic_sample_rate;
+
+	switch (div_factor) {
+	case 2:
+		tx_priv->dmic_clk_div = LPASS_CDC_TX_MACRO_CLK_DIV_2;
+		break;
+	case 3:
+		tx_priv->dmic_clk_div = LPASS_CDC_TX_MACRO_CLK_DIV_3;
+		break;
+	case 4:
+		tx_priv->dmic_clk_div = LPASS_CDC_TX_MACRO_CLK_DIV_4;
+		break;
+	case 6:
+		tx_priv->dmic_clk_div = LPASS_CDC_TX_MACRO_CLK_DIV_6;
+		break;
+	case 8:
+		tx_priv->dmic_clk_div = LPASS_CDC_TX_MACRO_CLK_DIV_8;
+		break;
+	case 16:
+		tx_priv->dmic_clk_div = LPASS_CDC_TX_MACRO_CLK_DIV_16;
+		break;
+	default:
+		/* Any other DIV factor is invalid */
+		goto undefined_rate;
+	}
+
+	/* Valid dmic DIV factors */
+	dev_dbg(tx_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n",
+		__func__, div_factor, mclk_rate);
+
+	return dmic_sample_rate;
+
+undefined_rate:
+	dev_dbg(tx_priv->dev, "%s: Invalid rate %d, for mclk %d\n",
+		 __func__, dmic_sample_rate, mclk_rate);
+	dmic_sample_rate = LPASS_CDC_TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED;
+
+	return dmic_sample_rate;
+}
+
+static const struct lpass_cdc_tx_macro_reg_mask_val
+				lpass_cdc_tx_macro_reg_init[] = {
+	{LPASS_CDC_TX0_TX_PATH_SEC7, 0x3F, 0x0A},
+};
+
+static int lpass_cdc_tx_macro_init(struct snd_soc_component *component)
+{
+	struct snd_soc_dapm_context *dapm =
+			snd_soc_component_get_dapm(component);
+	int ret = 0, i = 0;
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	tx_dev = lpass_cdc_get_device_ptr(component->dev, TX_MACRO);
+	if (!tx_dev) {
+		dev_err(component->dev,
+			"%s: null device for macro!\n", __func__);
+		return -EINVAL;
+	}
+	tx_priv = dev_get_drvdata(tx_dev);
+	if (!tx_priv) {
+		dev_err(component->dev,
+			"%s: priv is null for macro!\n", __func__);
+		return -EINVAL;
+	}
+	tx_priv->lpi_enable = false;
+	tx_priv->register_event_listener = false;
+	tx_priv->version = lpass_cdc_get_version(tx_dev);
+	if (tx_priv->version >= LPASS_CDC_VERSION_2_0) {
+		ret = snd_soc_dapm_new_controls(dapm,
+				lpass_cdc_tx_macro_dapm_widgets_common,
+				ARRAY_SIZE(lpass_cdc_tx_macro_dapm_widgets_common));
+		if (ret < 0) {
+			dev_err(tx_dev, "%s: Failed to add controls\n",
+				__func__);
+			return ret;
+		}
+		if (tx_priv->version == LPASS_CDC_VERSION_2_1)
+			ret = snd_soc_dapm_new_controls(dapm,
+				lpass_cdc_tx_macro_dapm_widgets_v2,
+				ARRAY_SIZE(lpass_cdc_tx_macro_dapm_widgets_v2));
+		else if (tx_priv->version == LPASS_CDC_VERSION_2_0)
+			ret = snd_soc_dapm_new_controls(dapm,
+				lpass_cdc_tx_macro_dapm_widgets_v3,
+				ARRAY_SIZE(lpass_cdc_tx_macro_dapm_widgets_v3));
+		if (ret < 0) {
+			dev_err(tx_dev, "%s: Failed to add controls\n",
+				__func__);
+			return ret;
+		}
+	} else {
+		ret = snd_soc_dapm_new_controls(dapm, lpass_cdc_tx_macro_dapm_widgets,
+					ARRAY_SIZE(lpass_cdc_tx_macro_dapm_widgets));
+		if (ret < 0) {
+			dev_err(tx_dev, "%s: Failed to add controls\n",
+				__func__);
+			return ret;
+		}
+	}
+
+	if (tx_priv->version >= LPASS_CDC_VERSION_2_0) {
+		ret = snd_soc_dapm_add_routes(dapm,
+					tx_audio_map_common,
+					ARRAY_SIZE(tx_audio_map_common));
+		if (ret < 0) {
+			dev_err(tx_dev, "%s: Failed to add routes\n",
+				__func__);
+			return ret;
+		}
+		if (tx_priv->version == LPASS_CDC_VERSION_2_0)
+			ret = snd_soc_dapm_add_routes(dapm,
+					tx_audio_map_v3,
+					ARRAY_SIZE(tx_audio_map_v3));
+		if (ret < 0) {
+			dev_err(tx_dev, "%s: Failed to add routes\n",
+				__func__);
+			return ret;
+		}
+	} else {
+		ret = snd_soc_dapm_add_routes(dapm, tx_audio_map,
+					ARRAY_SIZE(tx_audio_map));
+		if (ret < 0) {
+			dev_err(tx_dev, "%s: Failed to add routes\n",
+				__func__);
+			return ret;
+		}
+	}
+
+	ret = snd_soc_dapm_new_widgets(dapm->card);
+	if (ret < 0) {
+		dev_err(tx_dev, "%s: Failed to add widgets\n", __func__);
+		return ret;
+	}
+
+	if (tx_priv->version >= LPASS_CDC_VERSION_2_0) {
+		ret = snd_soc_add_component_controls(component,
+			lpass_cdc_tx_macro_snd_controls_common,
+			ARRAY_SIZE(lpass_cdc_tx_macro_snd_controls_common));
+		if (ret < 0) {
+			dev_err(tx_dev, "%s: Failed to add snd_ctls\n",
+				__func__);
+			return ret;
+		}
+		if (tx_priv->version == LPASS_CDC_VERSION_2_0)
+			ret = snd_soc_add_component_controls(component,
+				lpass_cdc_tx_macro_snd_controls_v3,
+				ARRAY_SIZE(lpass_cdc_tx_macro_snd_controls_v3));
+		if (ret < 0) {
+			dev_err(tx_dev, "%s: Failed to add snd_ctls\n",
+				__func__);
+			return ret;
+		}
+	} else {
+		ret = snd_soc_add_component_controls(component,
+				lpass_cdc_tx_macro_snd_controls,
+				ARRAY_SIZE(lpass_cdc_tx_macro_snd_controls));
+		if (ret < 0) {
+			dev_err(tx_dev, "%s: Failed to add snd_ctls\n",
+				__func__);
+			return ret;
+		}
+	}
+
+	snd_soc_dapm_ignore_suspend(dapm, "TX_AIF1 Capture");
+	snd_soc_dapm_ignore_suspend(dapm, "TX_AIF2 Capture");
+	snd_soc_dapm_ignore_suspend(dapm, "TX_AIF3 Capture");
+	if (tx_priv->version >= LPASS_CDC_VERSION_2_0) {
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_INPUT");
+	} else {
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0");
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1");
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2");
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3");
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0");
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1");
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2");
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC3");
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC4");
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC5");
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC6");
+		snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC7");
+	}
+	snd_soc_dapm_sync(dapm);
+
+	for (i = 0; i < NUM_DECIMATORS; i++) {
+		tx_priv->tx_hpf_work[i].tx_priv = tx_priv;
+		tx_priv->tx_hpf_work[i].decimator = i;
+		INIT_DELAYED_WORK(&tx_priv->tx_hpf_work[i].dwork,
+			lpass_cdc_tx_macro_tx_hpf_corner_freq_callback);
+	}
+
+	for (i = 0; i < NUM_DECIMATORS; i++) {
+		tx_priv->tx_mute_dwork[i].tx_priv = tx_priv;
+		tx_priv->tx_mute_dwork[i].decimator = i;
+		INIT_DELAYED_WORK(&tx_priv->tx_mute_dwork[i].dwork,
+			  lpass_cdc_tx_macro_mute_update_callback);
+	}
+	tx_priv->component = component;
+
+	for (i = 0; i < ARRAY_SIZE(lpass_cdc_tx_macro_reg_init); i++)
+		snd_soc_component_update_bits(component,
+				lpass_cdc_tx_macro_reg_init[i].reg,
+				lpass_cdc_tx_macro_reg_init[i].mask,
+				lpass_cdc_tx_macro_reg_init[i].val);
+
+	return 0;
+}
+
+static int lpass_cdc_tx_macro_deinit(struct snd_soc_component *component)
+{
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	tx_priv->component = NULL;
+	return 0;
+}
+
+static void lpass_cdc_tx_macro_add_child_devices(struct work_struct *work)
+{
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct platform_device *pdev = NULL;
+	struct device_node *node = NULL;
+	struct lpass_cdc_tx_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL;
+	int ret = 0;
+	u16 count = 0, ctrl_num = 0;
+	struct lpass_cdc_tx_macro_swr_ctrl_platform_data *platdata = NULL;
+	char plat_dev_name[LPASS_CDC_TX_MACRO_SWR_STRING_LEN] = "";
+	bool tx_swr_master_node = false;
+
+	tx_priv = container_of(work, struct lpass_cdc_tx_macro_priv,
+			     lpass_cdc_tx_macro_add_child_devices_work);
+	if (!tx_priv) {
+		pr_err("%s: Memory for tx_priv does not exist\n",
+			__func__);
+		return;
+	}
+
+	if (!tx_priv->dev) {
+		pr_err("%s: tx dev does not exist\n", __func__);
+		return;
+	}
+
+	if (!tx_priv->dev->of_node) {
+		dev_err(tx_priv->dev,
+			"%s: DT node for tx_priv does not exist\n", __func__);
+		return;
+	}
+
+	platdata = &tx_priv->swr_plat_data;
+	tx_priv->child_count = 0;
+
+	for_each_available_child_of_node(tx_priv->dev->of_node, node) {
+		tx_swr_master_node = false;
+		if (strnstr(node->name, "tx_swr_master",
+                                strlen("tx_swr_master")) != NULL)
+			tx_swr_master_node = true;
+
+		if (tx_swr_master_node)
+			strlcpy(plat_dev_name, "tx_swr_ctrl",
+				(LPASS_CDC_TX_MACRO_SWR_STRING_LEN - 1));
+		else
+			strlcpy(plat_dev_name, node->name,
+				(LPASS_CDC_TX_MACRO_SWR_STRING_LEN - 1));
+
+		pdev = platform_device_alloc(plat_dev_name, -1);
+		if (!pdev) {
+			dev_err(tx_priv->dev, "%s: pdev memory alloc failed\n",
+				__func__);
+			ret = -ENOMEM;
+			goto err;
+		}
+		pdev->dev.parent = tx_priv->dev;
+		pdev->dev.of_node = node;
+
+		if (tx_swr_master_node) {
+			ret = platform_device_add_data(pdev, platdata,
+						       sizeof(*platdata));
+			if (ret) {
+				dev_err(&pdev->dev,
+					"%s: cannot add plat data ctrl:%d\n",
+					__func__, ctrl_num);
+				goto fail_pdev_add;
+			}
+		}
+
+		ret = platform_device_add(pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"%s: Cannot add platform device\n",
+				__func__);
+			goto fail_pdev_add;
+		}
+
+		if (tx_swr_master_node) {
+			temp = krealloc(swr_ctrl_data,
+					(ctrl_num + 1) * sizeof(
+					struct lpass_cdc_tx_macro_swr_ctrl_data),
+					GFP_KERNEL);
+			if (!temp) {
+				ret = -ENOMEM;
+				goto fail_pdev_add;
+			}
+			swr_ctrl_data = temp;
+			swr_ctrl_data[ctrl_num].tx_swr_pdev = pdev;
+			ctrl_num++;
+			dev_dbg(&pdev->dev,
+				"%s: Added soundwire ctrl device(s)\n",
+				__func__);
+			tx_priv->swr_ctrl_data = swr_ctrl_data;
+		}
+		if (tx_priv->child_count < LPASS_CDC_TX_MACRO_CHILD_DEVICES_MAX)
+			tx_priv->pdev_child_devices[
+					tx_priv->child_count++] = pdev;
+		else
+			goto err;
+	}
+	return;
+fail_pdev_add:
+	for (count = 0; count < tx_priv->child_count; count++)
+		platform_device_put(tx_priv->pdev_child_devices[count]);
+err:
+	return;
+}
+
+static int lpass_cdc_tx_macro_set_port_map(struct snd_soc_component *component,
+				u32 usecase, u32 size, void *data)
+{
+	struct device *tx_dev = NULL;
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	struct swrm_port_config port_cfg;
+	int ret = 0;
+
+	if (!lpass_cdc_tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+		return -EINVAL;
+
+	memset(&port_cfg, 0, sizeof(port_cfg));
+	port_cfg.uc = usecase;
+	port_cfg.size = size;
+	port_cfg.params = data;
+
+	if (tx_priv->swr_ctrl_data)
+		ret = swrm_wcd_notify(
+			tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+			SWR_SET_PORT_MAP, &port_cfg);
+
+	return ret;
+}
+
+static void lpass_cdc_tx_macro_init_ops(struct macro_ops *ops,
+			       char __iomem *tx_io_base)
+{
+	memset(ops, 0, sizeof(struct macro_ops));
+	ops->init = lpass_cdc_tx_macro_init;
+	ops->exit = lpass_cdc_tx_macro_deinit;
+	ops->io_base = tx_io_base;
+	ops->dai_ptr = lpass_cdc_tx_macro_dai;
+	ops->num_dais = ARRAY_SIZE(lpass_cdc_tx_macro_dai);
+	ops->event_handler = lpass_cdc_tx_macro_event_handler;
+	ops->reg_wake_irq = lpass_cdc_tx_macro_reg_wake_irq;
+	ops->set_port_map = lpass_cdc_tx_macro_set_port_map;
+	ops->clk_div_get = lpass_cdc_tx_macro_clk_div_get;
+	ops->reg_evt_listener = lpass_cdc_tx_macro_register_event_listener;
+	ops->clk_enable = __lpass_cdc_tx_macro_mclk_enable;
+}
+
+static int lpass_cdc_tx_macro_probe(struct platform_device *pdev)
+{
+	struct macro_ops ops = {0};
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	u32 tx_base_addr = 0, sample_rate = 0;
+	char __iomem *tx_io_base = NULL;
+	int ret = 0;
+	const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate";
+	u32 is_used_tx_swr_gpio = 1;
+	const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio";
+
+	if (!lpass_cdc_is_va_macro_registered(&pdev->dev)) {
+		dev_err(&pdev->dev,
+			"%s: va-macro not registered yet, defer\n", __func__);
+		return -EPROBE_DEFER;
+	}
+
+	tx_priv = devm_kzalloc(&pdev->dev, sizeof(struct lpass_cdc_tx_macro_priv),
+			    GFP_KERNEL);
+	if (!tx_priv)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, tx_priv);
+
+	tx_priv->dev = &pdev->dev;
+	ret = of_property_read_u32(pdev->dev.of_node, "reg",
+				   &tx_base_addr);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
+			__func__, "reg");
+		return ret;
+	}
+	dev_set_drvdata(&pdev->dev, tx_priv);
+	if (of_find_property(pdev->dev.of_node, is_used_tx_swr_gpio_dt,
+			     NULL)) {
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   is_used_tx_swr_gpio_dt,
+					   &is_used_tx_swr_gpio);
+		if (ret) {
+			dev_err(&pdev->dev, "%s: error reading %s in dt\n",
+				__func__, is_used_tx_swr_gpio_dt);
+			is_used_tx_swr_gpio = 1;
+		}
+	}
+	tx_priv->tx_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
+					"qcom,tx-swr-gpios", 0);
+	if (!tx_priv->tx_swr_gpio_p && is_used_tx_swr_gpio) {
+		dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
+			__func__);
+		return -EINVAL;
+	}
+	if (msm_cdc_pinctrl_get_state(tx_priv->tx_swr_gpio_p) < 0 &&
+			is_used_tx_swr_gpio) {
+		dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
+			__func__);
+		return -EPROBE_DEFER;
+	}
+
+	tx_io_base = devm_ioremap(&pdev->dev,
+				   tx_base_addr, LPASS_CDC_TX_MACRO_MAX_OFFSET);
+	if (!tx_io_base) {
+		dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
+		return -ENOMEM;
+	}
+	tx_priv->tx_io_base = tx_io_base;
+	ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate,
+				   &sample_rate);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"%s: could not find sample_rate entry in dt\n",
+			__func__);
+		tx_priv->dmic_clk_div = LPASS_CDC_TX_MACRO_CLK_DIV_2;
+	} else {
+		if (lpass_cdc_tx_macro_validate_dmic_sample_rate(
+		sample_rate, tx_priv) == LPASS_CDC_TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED)
+			return -EINVAL;
+	}
+	if (is_used_tx_swr_gpio) {
+		tx_priv->reset_swr = true;
+		INIT_WORK(&tx_priv->lpass_cdc_tx_macro_add_child_devices_work,
+			  lpass_cdc_tx_macro_add_child_devices);
+		tx_priv->swr_plat_data.handle = (void *) tx_priv;
+		tx_priv->swr_plat_data.read = NULL;
+		tx_priv->swr_plat_data.write = NULL;
+		tx_priv->swr_plat_data.bulk_write = NULL;
+		tx_priv->swr_plat_data.clk = lpass_cdc_tx_macro_swrm_clock;
+		tx_priv->swr_plat_data.core_vote = lpass_cdc_tx_macro_core_vote;
+		tx_priv->swr_plat_data.handle_irq = NULL;
+		mutex_init(&tx_priv->swr_clk_lock);
+	}
+	tx_priv->is_used_tx_swr_gpio = is_used_tx_swr_gpio;
+	mutex_init(&tx_priv->mclk_lock);
+	lpass_cdc_tx_macro_init_ops(&ops, tx_io_base);
+	ops.clk_id_req = TX_CORE_CLK;
+	ops.default_clk_id = TX_CORE_CLK;
+	ret = lpass_cdc_register_macro(&pdev->dev, TX_MACRO, &ops);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"%s: register macro failed\n", __func__);
+		goto err_reg_macro;
+	}
+	if (is_used_tx_swr_gpio)
+		schedule_work(&tx_priv->lpass_cdc_tx_macro_add_child_devices_work);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+	pm_suspend_ignore_children(&pdev->dev, true);
+	pm_runtime_enable(&pdev->dev);
+
+	return 0;
+err_reg_macro:
+	mutex_destroy(&tx_priv->mclk_lock);
+	if (is_used_tx_swr_gpio)
+		mutex_destroy(&tx_priv->swr_clk_lock);
+	return ret;
+}
+
+static int lpass_cdc_tx_macro_remove(struct platform_device *pdev)
+{
+	struct lpass_cdc_tx_macro_priv *tx_priv = NULL;
+	u16 count = 0;
+
+	tx_priv = platform_get_drvdata(pdev);
+
+	if (!tx_priv)
+		return -EINVAL;
+
+	if (tx_priv->is_used_tx_swr_gpio) {
+		if (tx_priv->swr_ctrl_data)
+			kfree(tx_priv->swr_ctrl_data);
+		for (count = 0; count < tx_priv->child_count &&
+			count < LPASS_CDC_TX_MACRO_CHILD_DEVICES_MAX; count++)
+			platform_device_unregister(
+				tx_priv->pdev_child_devices[count]);
+	}
+
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+	mutex_destroy(&tx_priv->mclk_lock);
+	if (tx_priv->is_used_tx_swr_gpio)
+		mutex_destroy(&tx_priv->swr_clk_lock);
+	lpass_cdc_unregister_macro(&pdev->dev, TX_MACRO);
+	return 0;
+}
+
+
+static const struct of_device_id lpass_cdc_tx_macro_dt_match[] = {
+	{.compatible = "qcom,lpass-cdc-tx-macro"},
+	{}
+};
+
+static const struct dev_pm_ops lpass_cdc_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(
+		pm_runtime_force_suspend,
+		pm_runtime_force_resume
+	)
+	SET_RUNTIME_PM_OPS(
+		lpass_cdc_runtime_suspend,
+		lpass_cdc_runtime_resume,
+		NULL
+	)
+};
+
+static struct platform_driver lpass_cdc_tx_macro_driver = {
+	.driver = {
+		.name = "lpass_cdc_tx_macro",
+		.owner = THIS_MODULE,
+		.pm = &lpass_cdc_dev_pm_ops,
+		.of_match_table = lpass_cdc_tx_macro_dt_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = lpass_cdc_tx_macro_probe,
+	.remove = lpass_cdc_tx_macro_remove,
+};
+
+module_platform_driver(lpass_cdc_tx_macro_driver);
+
+MODULE_DESCRIPTION("TX macro driver");
+MODULE_LICENSE("GPL v2");

+ 172 - 0
asoc/codecs/lpass-cdc/lpass-cdc-utils.c

@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/regmap.h>
+#include "lpass-cdc.h"
+#include "internal.h"
+
+#define REG_BYTES 2
+#define VAL_BYTES 1
+
+const u16 macro_id_base_offset[MAX_MACRO] = {
+	TX_START_OFFSET,
+	RX_START_OFFSET,
+	WSA_START_OFFSET,
+	VA_START_OFFSET,
+};
+
+int lpass_cdc_get_macro_id(bool va_no_dec_flag, u16 reg)
+{
+	if (reg >= TX_START_OFFSET
+		&& reg <= TX_MAX_OFFSET)
+		return TX_MACRO;
+	if (reg >= RX_START_OFFSET
+		&& reg <= RX_MAX_OFFSET)
+		return RX_MACRO;
+	if (reg >= WSA_START_OFFSET
+		&& reg <= WSA_MAX_OFFSET)
+		return WSA_MACRO;
+	if (!va_no_dec_flag &&
+		(reg >= VA_START_OFFSET &&
+		reg <= VA_MAX_OFFSET))
+		return VA_MACRO;
+	if (va_no_dec_flag &&
+		(reg >= VA_START_OFFSET &&
+		reg <= VA_TOP_MAX_OFFSET))
+		return VA_MACRO;
+
+	return -EINVAL;
+}
+
+static int regmap_bus_read(void *context, const void *reg, size_t reg_size,
+			   void *val, size_t val_size)
+{
+	struct device *dev = context;
+	struct lpass_cdc_priv *priv = dev_get_drvdata(dev);
+	u16 *reg_p;
+	u16 __reg;
+	int macro_id, i;
+	u8 temp = 0;
+	int ret = -EINVAL;
+
+	if (!priv) {
+		dev_err(dev, "%s: priv is NULL\n", __func__);
+		return ret;
+	}
+	if (!reg || !val) {
+		dev_err(dev, "%s: reg or val is NULL\n", __func__);
+		return ret;
+	}
+	if (reg_size != REG_BYTES) {
+		dev_err(dev, "%s: register size %zd bytes, not supported\n",
+			__func__, reg_size);
+		return ret;
+	}
+
+	reg_p = (u16 *)reg;
+	macro_id = lpass_cdc_get_macro_id(priv->va_without_decimation,
+					   reg_p[0]);
+	if (macro_id < 0 || !priv->macros_supported[macro_id])
+		return 0;
+
+	mutex_lock(&priv->io_lock);
+	for (i = 0; i < val_size; i++) {
+		__reg = (reg_p[0] + i * 4) - macro_id_base_offset[macro_id];
+		ret = priv->read_dev(priv, macro_id, __reg, &temp);
+		if (ret < 0) {
+			dev_err_ratelimited(dev,
+			"%s: Codec read failed (%d), reg: 0x%x, size:%zd\n",
+			__func__, ret, reg_p[0] + i * 4, val_size);
+			break;
+		}
+		((u8 *)val)[i] = temp;
+		dev_dbg(dev, "%s: Read 0x%02x from reg 0x%x\n",
+			__func__, temp, reg_p[0] + i * 4);
+	}
+	mutex_unlock(&priv->io_lock);
+
+	return ret;
+}
+
+static int regmap_bus_gather_write(void *context,
+				   const void *reg, size_t reg_size,
+				   const void *val, size_t val_size)
+{
+	struct device *dev = context;
+	struct lpass_cdc_priv *priv = dev_get_drvdata(dev);
+	u16 *reg_p;
+	u16 __reg;
+	int macro_id, i;
+	int ret = -EINVAL;
+
+	if (!priv) {
+		dev_err(dev, "%s: priv is NULL\n", __func__);
+		return ret;
+	}
+	if (!reg || !val) {
+		dev_err(dev, "%s: reg or val is NULL\n", __func__);
+		return ret;
+	}
+	if (reg_size != REG_BYTES) {
+		dev_err(dev, "%s: register size %zd bytes, not supported\n",
+			__func__, reg_size);
+		return ret;
+	}
+
+	reg_p = (u16 *)reg;
+	macro_id = lpass_cdc_get_macro_id(priv->va_without_decimation,
+					reg_p[0]);
+	if (macro_id < 0 || !priv->macros_supported[macro_id])
+		return 0;
+
+	mutex_lock(&priv->io_lock);
+	for (i = 0; i < val_size; i++) {
+		__reg = (reg_p[0] + i * 4) - macro_id_base_offset[macro_id];
+		ret = priv->write_dev(priv, macro_id, __reg, ((u8 *)val)[i]);
+		if (ret < 0) {
+			dev_err_ratelimited(dev,
+			"%s: Codec write failed (%d), reg:0x%x, size:%zd\n",
+			__func__, ret, reg_p[0] + i * 4, val_size);
+			break;
+		}
+		dev_dbg(dev, "Write %02x to reg 0x%x\n", ((u8 *)val)[i],
+			reg_p[0] + i * 4);
+	}
+	mutex_unlock(&priv->io_lock);
+	return ret;
+}
+
+static int regmap_bus_write(void *context, const void *data, size_t count)
+{
+	struct device *dev = context;
+	struct lpass_cdc_priv *priv = dev_get_drvdata(dev);
+
+	if (!priv)
+		return -EINVAL;
+
+	if (count < REG_BYTES) {
+		dev_err(dev, "%s: count %zd bytes < %d, not supported\n",
+			__func__, count, REG_BYTES);
+		return -EINVAL;
+	}
+
+	return regmap_bus_gather_write(context, data, REG_BYTES,
+				       data + REG_BYTES,
+				       count - REG_BYTES);
+}
+
+static struct regmap_bus regmap_bus_config = {
+	.write = regmap_bus_write,
+	.gather_write = regmap_bus_gather_write,
+	.read = regmap_bus_read,
+	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+struct regmap *lpass_cdc_regmap_init(struct device *dev,
+				      const struct regmap_config *config)
+{
+	return devm_regmap_init(dev, &regmap_bus_config, dev, config);
+}

+ 3268 - 0
asoc/codecs/lpass-cdc/lpass-cdc-va-macro.c

@@ -0,0 +1,3268 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <linux/pm_runtime.h>
+#include <asoc/msm-cdc-pinctrl.h>
+#include <soc/swr-common.h>
+#include <soc/swr-wcd.h>
+#include <dsp/digital-cdc-rsc-mgr.h>
+#include "lpass-cdc.h"
+#include "lpass-cdc-registers.h"
+#include "lpass-cdc-clk-rsc.h"
+
+/* pm runtime auto suspend timer in msecs */
+#define VA_AUTO_SUSPEND_DELAY          100 /* delay in msec */
+#define LPASS_CDC_VA_MACRO_MAX_OFFSET 0x1000
+
+#define LPASS_CDC_VA_MACRO_NUM_DECIMATORS 8
+
+#define LPASS_CDC_VA_MACRO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
+			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
+#define LPASS_CDC_VA_MACRO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+		SNDRV_PCM_FMTBIT_S24_LE |\
+		SNDRV_PCM_FMTBIT_S24_3LE)
+
+#define  TX_HPF_CUT_OFF_FREQ_MASK	0x60
+#define  CF_MIN_3DB_4HZ			0x0
+#define  CF_MIN_3DB_75HZ		0x1
+#define  CF_MIN_3DB_150HZ		0x2
+
+#define LPASS_CDC_VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED 0
+#define LPASS_CDC_VA_MACRO_MCLK_FREQ 9600000
+#define LPASS_CDC_VA_MACRO_TX_PATH_OFFSET 0x80
+#define LPASS_CDC_VA_MACRO_TX_DMIC_CLK_DIV_MASK 0x0E
+#define LPASS_CDC_VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01
+#define LPASS_CDC_VA_MACRO_SWR_MIC_MUX_SEL_MASK 0xF
+#define LPASS_CDC_VA_MACRO_ADC_MUX_CFG_OFFSET 0x8
+#define LPASS_CDC_VA_MACRO_ADC_MODE_CFG0_SHIFT 1
+
+#define LPASS_CDC_VA_TX_DMIC_UNMUTE_DELAY_MS       40
+#define LPASS_CDC_VA_TX_AMIC_UNMUTE_DELAY_MS       100
+#define LPASS_CDC_VA_TX_DMIC_HPF_DELAY_MS       300
+#define LPASS_CDC_VA_TX_AMIC_HPF_DELAY_MS       300
+#define MAX_RETRY_ATTEMPTS 500
+#define LPASS_CDC_VA_MACRO_SWR_STRING_LEN 80
+#define LPASS_CDC_VA_MACRO_CHILD_DEVICES_MAX 3
+
+static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
+static int va_tx_unmute_delay = LPASS_CDC_VA_TX_DMIC_UNMUTE_DELAY_MS;
+module_param(va_tx_unmute_delay, int, 0664);
+MODULE_PARM_DESC(va_tx_unmute_delay, "delay to unmute the tx path");
+
+enum {
+	LPASS_CDC_VA_MACRO_AIF_INVALID = 0,
+	LPASS_CDC_VA_MACRO_AIF1_CAP,
+	LPASS_CDC_VA_MACRO_AIF2_CAP,
+	LPASS_CDC_VA_MACRO_AIF3_CAP,
+	LPASS_CDC_VA_MACRO_MAX_DAIS,
+};
+
+enum {
+	LPASS_CDC_VA_MACRO_DEC0,
+	LPASS_CDC_VA_MACRO_DEC1,
+	LPASS_CDC_VA_MACRO_DEC2,
+	LPASS_CDC_VA_MACRO_DEC3,
+	LPASS_CDC_VA_MACRO_DEC4,
+	LPASS_CDC_VA_MACRO_DEC5,
+	LPASS_CDC_VA_MACRO_DEC6,
+	LPASS_CDC_VA_MACRO_DEC7,
+	LPASS_CDC_VA_MACRO_DEC_MAX,
+};
+
+enum {
+	LPASS_CDC_VA_MACRO_CLK_DIV_2,
+	LPASS_CDC_VA_MACRO_CLK_DIV_3,
+	LPASS_CDC_VA_MACRO_CLK_DIV_4,
+	LPASS_CDC_VA_MACRO_CLK_DIV_6,
+	LPASS_CDC_VA_MACRO_CLK_DIV_8,
+	LPASS_CDC_VA_MACRO_CLK_DIV_16,
+};
+
+enum {
+	MSM_DMIC,
+	SWR_MIC,
+};
+
+enum {
+	TX_MCLK,
+	VA_MCLK,
+};
+
+struct va_mute_work {
+	struct lpass_cdc_va_macro_priv *va_priv;
+	u32 decimator;
+	struct delayed_work dwork;
+};
+
+struct hpf_work {
+	struct lpass_cdc_va_macro_priv *va_priv;
+	u8 decimator;
+	u8 hpf_cut_off_freq;
+	struct delayed_work dwork;
+};
+
+/* Hold instance to soundwire platform device */
+struct lpass_cdc_va_macro_swr_ctrl_data {
+	struct platform_device *va_swr_pdev;
+};
+
+struct lpass_cdc_va_macro_swr_ctrl_platform_data {
+	void *handle; /* holds codec private data */
+	int (*read)(void *handle, int reg);
+	int (*write)(void *handle, int reg, int val);
+	int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
+	int (*clk)(void *handle, bool enable);
+	int (*core_vote)(void *handle, bool enable);
+	int (*handle_irq)(void *handle,
+			  irqreturn_t (*swrm_irq_handler)(int irq,
+							  void *data),
+			  void *swrm_handle,
+			  int action);
+};
+
+struct lpass_cdc_va_macro_priv {
+	struct device *dev;
+	bool dec_active[LPASS_CDC_VA_MACRO_NUM_DECIMATORS];
+	bool va_without_decimation;
+	struct clk *lpass_audio_hw_vote;
+	struct mutex mclk_lock;
+	struct mutex swr_clk_lock;
+	struct snd_soc_component *component;
+	struct hpf_work va_hpf_work[LPASS_CDC_VA_MACRO_NUM_DECIMATORS];
+	struct va_mute_work va_mute_dwork[LPASS_CDC_VA_MACRO_NUM_DECIMATORS];
+	unsigned long active_ch_mask[LPASS_CDC_VA_MACRO_MAX_DAIS];
+	unsigned long active_ch_cnt[LPASS_CDC_VA_MACRO_MAX_DAIS];
+	u16 dmic_clk_div;
+	u16 va_mclk_users;
+	int swr_clk_users;
+	bool reset_swr;
+	struct device_node *va_swr_gpio_p;
+	struct lpass_cdc_va_macro_swr_ctrl_data *swr_ctrl_data;
+	struct lpass_cdc_va_macro_swr_ctrl_platform_data swr_plat_data;
+	struct work_struct lpass_cdc_va_macro_add_child_devices_work;
+	int child_count;
+	u16 mclk_mux_sel;
+	char __iomem *va_io_base;
+	char __iomem *va_island_mode_muxsel;
+	struct platform_device *pdev_child_devices
+			[LPASS_CDC_VA_MACRO_CHILD_DEVICES_MAX];
+	struct regulator *micb_supply;
+	u32 micb_voltage;
+	u32 micb_current;
+	u32 version;
+	u32 is_used_va_swr_gpio;
+	int micb_users;
+	u16 default_clk_id;
+	u16 clk_id;
+	int tx_swr_clk_cnt;
+	int va_swr_clk_cnt;
+	int va_clk_status;
+	int tx_clk_status;
+	bool lpi_enable;
+	bool register_event_listener;
+	int dec_mode[LPASS_CDC_VA_MACRO_NUM_DECIMATORS];
+	int disable_afe_wakeup_event_listener;
+};
+
+static bool lpass_cdc_va_macro_get_data(struct snd_soc_component *component,
+			      struct device **va_dev,
+			      struct lpass_cdc_va_macro_priv **va_priv,
+			      const char *func_name)
+{
+	*va_dev = lpass_cdc_get_device_ptr(component->dev, VA_MACRO);
+	if (!(*va_dev)) {
+		dev_err(component->dev,
+			"%s: null device for macro!\n", func_name);
+		return false;
+	}
+	*va_priv = dev_get_drvdata((*va_dev));
+	if (!(*va_priv) || !(*va_priv)->component) {
+		dev_err(component->dev,
+			"%s: priv is null for macro!\n", func_name);
+		return false;
+	}
+	return true;
+}
+
+static int lpass_cdc_va_macro_clk_div_get(struct snd_soc_component *component)
+{
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	if ((va_priv->version >= LPASS_CDC_VERSION_2_0)
+		&& !va_priv->lpi_enable
+		&& (va_priv->dmic_clk_div == LPASS_CDC_VA_MACRO_CLK_DIV_16))
+		return LPASS_CDC_VA_MACRO_CLK_DIV_8;
+
+	return va_priv->dmic_clk_div;
+}
+
+static int lpass_cdc_va_macro_mclk_enable(
+			struct lpass_cdc_va_macro_priv *va_priv,
+			bool mclk_enable, bool dapm)
+{
+	struct regmap *regmap = dev_get_regmap(va_priv->dev->parent, NULL);
+	int ret = 0;
+
+	if (regmap == NULL) {
+		dev_err(va_priv->dev, "%s: regmap is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	dev_dbg(va_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
+		__func__, mclk_enable, dapm, va_priv->va_mclk_users);
+
+	mutex_lock(&va_priv->mclk_lock);
+	if (mclk_enable) {
+		ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+						   va_priv->default_clk_id,
+						   va_priv->clk_id,
+						   true);
+		if (ret < 0) {
+			dev_err(va_priv->dev,
+				"%s: va request clock en failed\n",
+				__func__);
+			goto exit;
+		}
+		lpass_cdc_clk_rsc_fs_gen_request(va_priv->dev,
+					      true);
+		if (va_priv->va_mclk_users == 0) {
+			regcache_mark_dirty(regmap);
+			regcache_sync_region(regmap,
+					VA_START_OFFSET,
+					VA_MAX_OFFSET);
+		}
+		va_priv->va_mclk_users++;
+	} else {
+		if (va_priv->va_mclk_users <= 0) {
+			dev_err(va_priv->dev, "%s: clock already disabled\n",
+			__func__);
+			va_priv->va_mclk_users = 0;
+			goto exit;
+		}
+		va_priv->va_mclk_users--;
+		lpass_cdc_clk_rsc_fs_gen_request(va_priv->dev,
+					  false);
+		lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+					va_priv->default_clk_id,
+					va_priv->clk_id,
+					false);
+	}
+exit:
+	mutex_unlock(&va_priv->mclk_lock);
+	return ret;
+}
+
+static int lpass_cdc_va_macro_event_handler(struct snd_soc_component *component,
+				  u16 event, u32 data)
+{
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+	int retry_cnt = MAX_RETRY_ATTEMPTS;
+	int ret = 0;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	switch (event) {
+	case LPASS_CDC_MACRO_EVT_WAIT_VA_CLK_RESET:
+		while ((va_priv->va_mclk_users != 0) && (retry_cnt != 0)) {
+			dev_dbg_ratelimited(va_dev, "%s:retry_cnt: %d\n",
+				__func__, retry_cnt);
+			/*
+			 * Userspace takes 10 seconds to close
+			 * the session when pcm_start fails due to concurrency
+			 * with PDR/SSR. Loop and check every 20ms till 10
+			 * seconds for va_mclk user count to get reset to 0
+			 * which ensures userspace teardown is done and SSR
+			 * powerup seq can proceed.
+			 */
+			msleep(20);
+			retry_cnt--;
+		}
+		if (retry_cnt == 0)
+			dev_err(va_dev,
+				"%s: va_mclk_users non-zero, SSR fail!!\n",
+				__func__);
+		break;
+	case LPASS_CDC_MACRO_EVT_PRE_SSR_UP:
+		/* enable&disable VA_CORE_CLK to reset GFMUX reg */
+		ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+						va_priv->default_clk_id,
+						VA_CORE_CLK, true);
+		if (ret < 0)
+			dev_err_ratelimited(va_priv->dev,
+				"%s, failed to enable clk, ret:%d\n",
+				__func__, ret);
+		else
+			lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+						va_priv->default_clk_id,
+						VA_CORE_CLK, false);
+		break;
+	case LPASS_CDC_MACRO_EVT_SSR_UP:
+		trace_printk("%s, enter SSR up\n", __func__);
+		/* reset swr after ssr/pdr */
+		va_priv->reset_swr = true;
+		if (va_priv->swr_ctrl_data)
+			swrm_wcd_notify(
+				va_priv->swr_ctrl_data[0].va_swr_pdev,
+				SWR_DEVICE_SSR_UP, NULL);
+		break;
+	case LPASS_CDC_MACRO_EVT_CLK_RESET:
+		lpass_cdc_rsc_clk_reset(va_dev, VA_CORE_CLK);
+		break;
+	case LPASS_CDC_MACRO_EVT_SSR_DOWN:
+		if (va_priv->swr_ctrl_data) {
+			swrm_wcd_notify(
+				va_priv->swr_ctrl_data[0].va_swr_pdev,
+				SWR_DEVICE_SSR_DOWN, NULL);
+		}
+		if ((!pm_runtime_enabled(va_dev) ||
+		     !pm_runtime_suspended(va_dev))) {
+			ret = lpass_cdc_runtime_suspend(va_dev);
+			if (!ret) {
+				pm_runtime_disable(va_dev);
+				pm_runtime_set_suspended(va_dev);
+				pm_runtime_enable(va_dev);
+			}
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_va_macro_swr_clk_event_v2(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(va_dev, "%s: event = %d\n", __func__, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		va_priv->va_swr_clk_cnt++;
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		va_priv->va_swr_clk_cnt--;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	int ret = 0;
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n",
+		__func__, event, va_priv->lpi_enable);
+
+	if (!va_priv->lpi_enable)
+		return ret;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		msm_cdc_pinctrl_set_wakeup_capable(
+				va_priv->va_swr_gpio_p, false);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		msm_cdc_pinctrl_set_wakeup_capable(
+				va_priv->va_swr_gpio_p, true);
+		break;
+	default:
+		dev_err(va_priv->dev,
+			"%s: invalid DAPM event %d\n", __func__, event);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static int lpass_cdc_va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	int ret = 0;
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n",
+		__func__, event, va_priv->lpi_enable);
+
+	if (!va_priv->lpi_enable)
+		return ret;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (va_priv->lpass_audio_hw_vote) {
+			ret = digital_cdc_rsc_mgr_hw_vote_enable(
+					va_priv->lpass_audio_hw_vote);
+			if (ret)
+				dev_err(va_dev,
+					"%s: lpass audio hw enable failed\n",
+					__func__);
+		}
+		if (va_priv->lpi_enable &&
+		    !va_priv->disable_afe_wakeup_event_listener) {
+			lpass_cdc_register_event_listener(component, true);
+			va_priv->register_event_listener = true;
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (va_priv->register_event_listener) {
+			va_priv->register_event_listener = false;
+			lpass_cdc_register_event_listener(component, false);
+		}
+		if (va_priv->lpass_audio_hw_vote)
+			digital_cdc_rsc_mgr_hw_vote_disable(
+				va_priv->lpass_audio_hw_vote);
+		break;
+	default:
+		dev_err(va_priv->dev,
+			"%s: invalid DAPM event %d\n", __func__, event);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static int lpass_cdc_va_macro_tx_swr_clk_event_v2(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	if (SND_SOC_DAPM_EVENT_ON(event))
+		++va_priv->tx_swr_clk_cnt;
+	if (SND_SOC_DAPM_EVENT_OFF(event))
+		--va_priv->tx_swr_clk_cnt;
+
+	return 0;
+}
+
+static int lpass_cdc_va_macro_mclk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	int ret = 0;
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(va_dev, "%s: event = %d\n", __func__, event);
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+						   va_priv->default_clk_id,
+						   TX_CORE_CLK,
+						   true);
+		if (!ret)
+			va_priv->tx_clk_status++;
+
+		if (va_priv->lpi_enable)
+			ret = lpass_cdc_va_macro_mclk_enable(va_priv, 1, true);
+		else
+			ret = lpass_cdc_tx_mclk_enable(component, 1);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (va_priv->lpi_enable)
+			lpass_cdc_va_macro_mclk_enable(va_priv, 0, true);
+		else
+			lpass_cdc_tx_mclk_enable(component, 0);
+
+		if (va_priv->tx_clk_status > 0) {
+			lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+					   va_priv->default_clk_id,
+					   TX_CORE_CLK,
+					   false);
+			va_priv->tx_clk_status--;
+		}
+		break;
+	default:
+		dev_err(va_priv->dev,
+			"%s: invalid DAPM event %d\n", __func__, event);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static int lpass_cdc_va_macro_tx_va_mclk_enable(
+				struct lpass_cdc_va_macro_priv *va_priv,
+				struct regmap *regmap, int clk_type,
+				bool enable)
+{
+	int ret = 0, clk_tx_ret = 0;
+
+	dev_dbg(va_priv->dev,
+		"%s: clock type %s, enable: %s tx_mclk_users: %d\n",
+		__func__, (clk_type ? "VA_MCLK" : "TX_MCLK"),
+		(enable ? "enable" : "disable"), va_priv->va_mclk_users);
+
+	if (enable) {
+		if (va_priv->swr_clk_users == 0)
+			msm_cdc_pinctrl_select_active_state(
+						va_priv->va_swr_gpio_p);
+		clk_tx_ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+						   TX_CORE_CLK,
+						   TX_CORE_CLK,
+						   true);
+		if (clk_type == TX_MCLK) {
+			ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+							   TX_CORE_CLK,
+							   TX_CORE_CLK,
+							   true);
+			if (ret < 0) {
+				if (va_priv->swr_clk_users == 0)
+					msm_cdc_pinctrl_select_sleep_state(
+							va_priv->va_swr_gpio_p);
+				dev_err_ratelimited(va_priv->dev,
+					"%s: swr request clk failed\n",
+					__func__);
+				goto done;
+			}
+			lpass_cdc_clk_rsc_fs_gen_request(va_priv->dev,
+						  true);
+		}
+		if (clk_type == VA_MCLK) {
+			ret = lpass_cdc_va_macro_mclk_enable(va_priv, 1, true);
+			if (ret < 0) {
+				if (va_priv->swr_clk_users == 0)
+					msm_cdc_pinctrl_select_sleep_state(
+							va_priv->va_swr_gpio_p);
+				dev_err_ratelimited(va_priv->dev,
+					"%s: request clock enable failed\n",
+					__func__);
+				goto done;
+			}
+		}
+		if (va_priv->swr_clk_users == 0) {
+			dev_dbg(va_priv->dev, "%s: reset_swr: %d\n",
+				__func__, va_priv->reset_swr);
+			if (va_priv->reset_swr)
+				regmap_update_bits(regmap,
+					LPASS_CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
+					0x02, 0x02);
+			regmap_update_bits(regmap,
+				LPASS_CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
+				0x01, 0x01);
+			if (va_priv->reset_swr)
+				regmap_update_bits(regmap,
+					LPASS_CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
+					0x02, 0x00);
+			va_priv->reset_swr = false;
+		}
+		if (!clk_tx_ret)
+			ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+						   TX_CORE_CLK,
+						   TX_CORE_CLK,
+						   false);
+		va_priv->swr_clk_users++;
+	} else {
+		if (va_priv->swr_clk_users <= 0) {
+			dev_err_ratelimited(va_priv->dev,
+				"va swrm clock users already 0\n");
+			va_priv->swr_clk_users = 0;
+			return 0;
+		}
+		clk_tx_ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+						   TX_CORE_CLK,
+						   TX_CORE_CLK,
+						   true);
+		va_priv->swr_clk_users--;
+		if (va_priv->swr_clk_users == 0)
+			regmap_update_bits(regmap,
+				LPASS_CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
+				0x01, 0x00);
+		if (clk_type == VA_MCLK)
+			lpass_cdc_va_macro_mclk_enable(va_priv, 0, true);
+		if (clk_type == TX_MCLK) {
+			lpass_cdc_clk_rsc_fs_gen_request(va_priv->dev,
+						  false);
+			ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+							   TX_CORE_CLK,
+							   TX_CORE_CLK,
+							   false);
+			if (ret < 0) {
+				dev_err_ratelimited(va_priv->dev,
+					"%s: swr request clk failed\n",
+					__func__);
+				goto done;
+			}
+		}
+		if (!clk_tx_ret)
+			ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+						   TX_CORE_CLK,
+						   TX_CORE_CLK,
+						   false);
+		if (va_priv->swr_clk_users == 0)
+			msm_cdc_pinctrl_select_sleep_state(
+						va_priv->va_swr_gpio_p);
+	}
+	return 0;
+
+done:
+	if (!clk_tx_ret)
+		lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+				TX_CORE_CLK,
+				TX_CORE_CLK,
+				false);
+	return ret;
+}
+
+static int lpass_cdc_va_macro_core_vote(void *handle, bool enable)
+{
+	struct lpass_cdc_va_macro_priv *va_priv =
+					(struct lpass_cdc_va_macro_priv *) handle;
+
+	if (va_priv == NULL) {
+		pr_err("%s: va priv data is NULL\n", __func__);
+		return -EINVAL;
+	}
+	if (enable) {
+		pm_runtime_get_sync(va_priv->dev);
+		pm_runtime_put_autosuspend(va_priv->dev);
+		pm_runtime_mark_last_busy(va_priv->dev);
+	}
+
+	if (lpass_cdc_check_core_votes(va_priv->dev))
+		return 0;
+	else
+		return -EINVAL;
+}
+
+static int lpass_cdc_va_macro_swrm_clock(void *handle, bool enable)
+{
+	struct lpass_cdc_va_macro_priv *va_priv =
+					(struct lpass_cdc_va_macro_priv *) handle;
+	struct regmap *regmap = dev_get_regmap(va_priv->dev->parent, NULL);
+	int ret = 0;
+
+	if (regmap == NULL) {
+		dev_err(va_priv->dev, "%s: regmap is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&va_priv->swr_clk_lock);
+	dev_dbg(va_priv->dev,
+		"%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n",
+		__func__, (enable ? "enable" : "disable"),
+		va_priv->tx_swr_clk_cnt, va_priv->va_swr_clk_cnt);
+
+	if (enable) {
+		pm_runtime_get_sync(va_priv->dev);
+		if (va_priv->va_swr_clk_cnt && !va_priv->tx_swr_clk_cnt) {
+			ret = lpass_cdc_va_macro_tx_va_mclk_enable(va_priv,
+						regmap, VA_MCLK, enable);
+			if (ret) {
+				pm_runtime_mark_last_busy(va_priv->dev);
+				pm_runtime_put_autosuspend(va_priv->dev);
+				goto done;
+			}
+			va_priv->va_clk_status++;
+		} else {
+			ret = lpass_cdc_va_macro_tx_va_mclk_enable(va_priv,
+						regmap, TX_MCLK, enable);
+			if (ret) {
+				pm_runtime_mark_last_busy(va_priv->dev);
+				pm_runtime_put_autosuspend(va_priv->dev);
+				goto done;
+			}
+			va_priv->tx_clk_status++;
+		}
+		pm_runtime_mark_last_busy(va_priv->dev);
+		pm_runtime_put_autosuspend(va_priv->dev);
+	} else {
+		if (va_priv->va_clk_status && !va_priv->tx_clk_status) {
+			ret = lpass_cdc_va_macro_tx_va_mclk_enable(va_priv,
+							regmap,
+							VA_MCLK, enable);
+			if (ret)
+				goto done;
+			--va_priv->va_clk_status;
+		} else if (!va_priv->va_clk_status && va_priv->tx_clk_status) {
+			ret = lpass_cdc_va_macro_tx_va_mclk_enable(va_priv,
+							regmap,
+							TX_MCLK, enable);
+			if (ret)
+				goto done;
+			--va_priv->tx_clk_status;
+		} else if (va_priv->va_clk_status && va_priv->tx_clk_status) {
+			if (!va_priv->va_swr_clk_cnt &&
+				va_priv->tx_swr_clk_cnt) {
+				ret = lpass_cdc_va_macro_tx_va_mclk_enable(
+							va_priv, regmap,
+							VA_MCLK, enable);
+				if (ret)
+					goto done;
+				--va_priv->va_clk_status;
+			} else {
+				ret = lpass_cdc_va_macro_tx_va_mclk_enable(
+							va_priv, regmap,
+							TX_MCLK, enable);
+				if (ret)
+					goto done;
+				--va_priv->tx_clk_status;
+			}
+
+		} else {
+			dev_dbg(va_priv->dev,
+				"%s: Both clocks are disabled\n", __func__);
+		}
+	}
+	dev_dbg(va_priv->dev,
+		"%s: swrm clock usr %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n",
+		__func__, va_priv->swr_clk_users, va_priv->tx_clk_status,
+		va_priv->va_clk_status);
+done:
+	mutex_unlock(&va_priv->swr_clk_lock);
+	return ret;
+}
+
+static bool is_amic_enabled(struct snd_soc_component *component, int decimator)
+{
+	u16 adc_mux_reg = 0, adc_reg = 0;
+	u16 adc_n = LPASS_CDC_ADC_MAX;
+	bool ret = false;
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return ret;
+
+	adc_mux_reg = LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG1 +
+			LPASS_CDC_VA_MACRO_ADC_MUX_CFG_OFFSET * decimator;
+	if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) {
+		if (va_priv->version == LPASS_CDC_VERSION_2_1)
+			return true;
+		adc_reg = LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG0 +
+			LPASS_CDC_VA_MACRO_ADC_MUX_CFG_OFFSET * decimator;
+		adc_n = snd_soc_component_read32(component, adc_reg) &
+				LPASS_CDC_VA_MACRO_SWR_MIC_MUX_SEL_MASK;
+		if (adc_n < LPASS_CDC_ADC_MAX)
+			return true;
+	}
+
+	return ret;
+}
+
+static void lpass_cdc_va_macro_tx_hpf_corner_freq_callback(
+						struct work_struct *work)
+{
+	struct delayed_work *hpf_delayed_work;
+	struct hpf_work *hpf_work;
+	struct lpass_cdc_va_macro_priv *va_priv;
+	struct snd_soc_component *component;
+	u16 dec_cfg_reg, hpf_gate_reg;
+	u8 hpf_cut_off_freq;
+	u16 adc_reg = 0, adc_n = 0;
+
+	hpf_delayed_work = to_delayed_work(work);
+	hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
+	va_priv = hpf_work->va_priv;
+	component = va_priv->component;
+	hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
+
+	dec_cfg_reg = LPASS_CDC_VA_TX0_TX_PATH_CFG0 +
+			LPASS_CDC_VA_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
+	hpf_gate_reg = LPASS_CDC_VA_TX0_TX_PATH_SEC2 +
+			LPASS_CDC_VA_MACRO_TX_PATH_OFFSET * hpf_work->decimator;
+
+	dev_dbg(va_priv->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
+		__func__, hpf_work->decimator, hpf_cut_off_freq);
+
+	if (is_amic_enabled(component, hpf_work->decimator)) {
+		adc_reg = LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG0 +
+			LPASS_CDC_VA_MACRO_ADC_MUX_CFG_OFFSET *
+			hpf_work->decimator;
+		adc_n = snd_soc_component_read32(component, adc_reg) &
+				LPASS_CDC_VA_MACRO_SWR_MIC_MUX_SEL_MASK;
+		/* analog mic clear TX hold */
+		lpass_cdc_clear_amic_tx_hold(component->dev, adc_n);
+		snd_soc_component_update_bits(component,
+				dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
+				hpf_cut_off_freq << 5);
+		snd_soc_component_update_bits(component, hpf_gate_reg,
+					      0x03, 0x02);
+		/* Minimum 1 clk cycle delay is required as per HW spec */
+		usleep_range(1000, 1010);
+		snd_soc_component_update_bits(component, hpf_gate_reg,
+					      0x03, 0x01);
+	} else {
+		snd_soc_component_update_bits(component,
+				dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
+				hpf_cut_off_freq << 5);
+		snd_soc_component_update_bits(component, hpf_gate_reg,
+					      0x02, 0x02);
+		/* Minimum 1 clk cycle delay is required as per HW spec */
+		usleep_range(1000, 1010);
+		snd_soc_component_update_bits(component, hpf_gate_reg,
+					      0x02, 0x00);
+	}
+}
+
+static void lpass_cdc_va_macro_mute_update_callback(struct work_struct *work)
+{
+	struct va_mute_work *va_mute_dwork;
+	struct snd_soc_component *component = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv;
+	struct delayed_work *delayed_work;
+	u16 tx_vol_ctl_reg, decimator;
+
+	delayed_work = to_delayed_work(work);
+	va_mute_dwork = container_of(delayed_work, struct va_mute_work, dwork);
+	va_priv = va_mute_dwork->va_priv;
+	component = va_priv->component;
+	decimator = va_mute_dwork->decimator;
+
+	tx_vol_ctl_reg =
+		LPASS_CDC_VA_TX0_TX_PATH_CTL +
+			LPASS_CDC_VA_MACRO_TX_PATH_OFFSET * decimator;
+	snd_soc_component_update_bits(component, tx_vol_ctl_reg, 0x10, 0x00);
+	dev_dbg(va_priv->dev, "%s: decimator %u unmute\n",
+		__func__, decimator);
+}
+
+static int lpass_cdc_va_macro_put_dec_enum(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int val;
+	u16 mic_sel_reg, dmic_clk_reg;
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	val = ucontrol->value.enumerated.item[0];
+	if (val > e->items - 1)
+		return -EINVAL;
+
+	dev_dbg(component->dev, "%s: wname: %s, val: 0x%x\n", __func__,
+		widget->name, val);
+
+	switch (e->reg) {
+	case LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG0:
+		mic_sel_reg = LPASS_CDC_VA_TX0_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG0:
+		mic_sel_reg = LPASS_CDC_VA_TX1_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG0:
+		mic_sel_reg = LPASS_CDC_VA_TX2_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG0:
+		mic_sel_reg = LPASS_CDC_VA_TX3_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_VA_INP_MUX_ADC_MUX4_CFG0:
+		mic_sel_reg = LPASS_CDC_VA_TX4_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_VA_INP_MUX_ADC_MUX5_CFG0:
+		mic_sel_reg = LPASS_CDC_VA_TX5_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_VA_INP_MUX_ADC_MUX6_CFG0:
+		mic_sel_reg = LPASS_CDC_VA_TX6_TX_PATH_CFG0;
+		break;
+	case LPASS_CDC_VA_INP_MUX_ADC_MUX7_CFG0:
+		mic_sel_reg = LPASS_CDC_VA_TX7_TX_PATH_CFG0;
+		break;
+	default:
+		dev_err(component->dev, "%s: e->reg: 0x%x not expected\n",
+			__func__, e->reg);
+		return -EINVAL;
+	}
+	if (strnstr(widget->name, "SMIC", strlen(widget->name))) {
+		if (val != 0) {
+			if (val < 5) {
+				snd_soc_component_update_bits(component,
+							mic_sel_reg,
+							1 << 7, 0x0 << 7);
+			} else {
+				snd_soc_component_update_bits(component,
+							mic_sel_reg,
+							1 << 7, 0x1 << 7);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_VA_TOP_CSR_DMIC_CFG,
+					0x80, 0x00);
+				dmic_clk_reg =
+					LPASS_CDC_TX_TOP_CSR_SWR_DMIC0_CTL +
+						((val - 5)/2) * 4;
+				snd_soc_component_update_bits(component,
+					dmic_clk_reg,
+					0x0E, va_priv->dmic_clk_div << 0x1);
+			}
+		}
+	} else {
+		/* DMIC selected */
+		if (val != 0)
+			snd_soc_component_update_bits(component, mic_sel_reg,
+					1 << 7, 1 << 7);
+	}
+
+	return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
+}
+
+static int lpass_cdc_va_macro_lpi_get(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = va_priv->lpi_enable;
+
+	return 0;
+}
+
+static int lpass_cdc_va_macro_lpi_put(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	va_priv->lpi_enable = ucontrol->value.integer.value[0];
+
+	return 0;
+}
+
+static int lpass_cdc_va_macro_tx_mixer_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct soc_multi_mixer_control *mixer =
+		((struct soc_multi_mixer_control *)kcontrol->private_value);
+	u32 dai_id = widget->shift;
+	u32 dec_id = mixer->shift;
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	if (test_bit(dec_id, &va_priv->active_ch_mask[dai_id]))
+		ucontrol->value.integer.value[0] = 1;
+	else
+		ucontrol->value.integer.value[0] = 0;
+	return 0;
+}
+
+static int lpass_cdc_va_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct snd_soc_dapm_update *update = NULL;
+	struct soc_multi_mixer_control *mixer =
+		((struct soc_multi_mixer_control *)kcontrol->private_value);
+	u32 dai_id = widget->shift;
+	u32 dec_id = mixer->shift;
+	u32 enable = ucontrol->value.integer.value[0];
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	if (enable) {
+		set_bit(dec_id, &va_priv->active_ch_mask[dai_id]);
+		va_priv->active_ch_cnt[dai_id]++;
+	} else {
+		clear_bit(dec_id, &va_priv->active_ch_mask[dai_id]);
+		va_priv->active_ch_cnt[dai_id]--;
+	}
+
+	snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
+
+	return 0;
+}
+
+static int lpass_cdc_va_macro_enable_dmic(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	unsigned int dmic = 0;
+	int ret = 0;
+	char *wname;
+
+	wname = strpbrk(w->name, "01234567");
+	if (!wname) {
+		dev_err(component->dev, "%s: widget not found\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = kstrtouint(wname, 10, &dmic);
+	if (ret < 0) {
+		dev_err(component->dev, "%s: Invalid DMIC line on the codec\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	dev_dbg(component->dev, "%s: event %d DMIC%d\n",
+		__func__, event,  dmic);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		lpass_cdc_dmic_clk_enable(component, dmic, DMIC_VA, true);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		lpass_cdc_dmic_clk_enable(component, dmic, DMIC_VA, false);
+		break;
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_va_macro_enable_dec(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	unsigned int decimator;
+	u16 tx_vol_ctl_reg, dec_cfg_reg, hpf_gate_reg;
+	u16 tx_gain_ctl_reg;
+	u8 hpf_cut_off_freq;
+	u16 adc_mux_reg = 0;
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+	int hpf_delay = LPASS_CDC_VA_TX_DMIC_HPF_DELAY_MS;
+	int unmute_delay = LPASS_CDC_VA_TX_DMIC_UNMUTE_DELAY_MS;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	decimator = w->shift;
+
+	dev_dbg(va_dev, "%s(): widget = %s decimator = %u\n", __func__,
+		w->name, decimator);
+
+	tx_vol_ctl_reg = LPASS_CDC_VA_TX0_TX_PATH_CTL +
+				LPASS_CDC_VA_MACRO_TX_PATH_OFFSET * decimator;
+	hpf_gate_reg = LPASS_CDC_VA_TX0_TX_PATH_SEC2 +
+				LPASS_CDC_VA_MACRO_TX_PATH_OFFSET * decimator;
+	dec_cfg_reg = LPASS_CDC_VA_TX0_TX_PATH_CFG0 +
+				LPASS_CDC_VA_MACRO_TX_PATH_OFFSET * decimator;
+	tx_gain_ctl_reg = LPASS_CDC_VA_TX0_TX_VOL_CTL +
+				LPASS_CDC_VA_MACRO_TX_PATH_OFFSET * decimator;
+	adc_mux_reg = LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG1 +
+			LPASS_CDC_VA_MACRO_ADC_MUX_CFG_OFFSET * decimator;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_component_update_bits(component,
+			dec_cfg_reg, 0x06, va_priv->dec_mode[decimator] <<
+			LPASS_CDC_VA_MACRO_ADC_MODE_CFG0_SHIFT);
+		/* Enable TX PGA Mute */
+		snd_soc_component_update_bits(component,
+				tx_vol_ctl_reg, 0x10, 0x10);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		/* Enable TX CLK */
+		snd_soc_component_update_bits(component,
+				tx_vol_ctl_reg, 0x20, 0x20);
+		if (!is_amic_enabled(component, decimator)) {
+			snd_soc_component_update_bits(component,
+				hpf_gate_reg, 0x01, 0x00);
+			/*
+		 	 * Minimum 1 clk cycle delay is required as per HW spec
+		 	 */
+			usleep_range(1000, 1010);
+		}
+		hpf_cut_off_freq = (snd_soc_component_read32(
+					component, dec_cfg_reg) &
+				   TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
+		va_priv->va_hpf_work[decimator].hpf_cut_off_freq =
+							hpf_cut_off_freq;
+
+		if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
+			snd_soc_component_update_bits(component, dec_cfg_reg,
+					    TX_HPF_CUT_OFF_FREQ_MASK,
+					    CF_MIN_3DB_150HZ << 5);
+		}
+		if (is_amic_enabled(component, decimator) < LPASS_CDC_ADC_MAX) {
+			hpf_delay = LPASS_CDC_VA_TX_AMIC_HPF_DELAY_MS;
+			unmute_delay = LPASS_CDC_VA_TX_AMIC_UNMUTE_DELAY_MS;
+			if (va_tx_unmute_delay < unmute_delay)
+				va_tx_unmute_delay = unmute_delay;
+		}
+		snd_soc_component_update_bits(component,
+				hpf_gate_reg, 0x03, 0x02);
+		if (!is_amic_enabled(component, decimator))
+			snd_soc_component_update_bits(component,
+				hpf_gate_reg, 0x03, 0x00);
+		/*
+		 * Minimum 1 clk cycle delay is required as per HW spec
+		 */
+		usleep_range(1000, 1010);
+		snd_soc_component_update_bits(component,
+			hpf_gate_reg, 0x03, 0x01);
+		/*
+		 * 6ms delay is required as per HW spec
+		 */
+		usleep_range(6000, 6010);
+		/* schedule work queue to Remove Mute */
+		queue_delayed_work(system_freezable_wq,
+				   &va_priv->va_mute_dwork[decimator].dwork,
+				   msecs_to_jiffies(va_tx_unmute_delay));
+		if (va_priv->va_hpf_work[decimator].hpf_cut_off_freq !=
+							CF_MIN_3DB_150HZ)
+			queue_delayed_work(system_freezable_wq,
+					&va_priv->va_hpf_work[decimator].dwork,
+					msecs_to_jiffies(hpf_delay));
+		/* apply gain after decimator is enabled */
+		snd_soc_component_write(component, tx_gain_ctl_reg,
+			snd_soc_component_read32(component, tx_gain_ctl_reg));
+		if (va_priv->version == LPASS_CDC_VERSION_2_0) {
+			if (snd_soc_component_read32(component, adc_mux_reg)
+							& SWR_MIC) {
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_CTRL,
+					0x01, 0x01);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC0_CTL,
+					0x0E, 0x0C);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC1_CTL,
+					0x0E, 0x0C);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC2_CTL,
+					0x0E, 0x00);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC3_CTL,
+					0x0E, 0x00);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC4_CTL,
+					0x0E, 0x00);
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_MIC5_CTL,
+					0x0E, 0x00);
+			}
+		}
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		hpf_cut_off_freq =
+			va_priv->va_hpf_work[decimator].hpf_cut_off_freq;
+		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
+					0x10, 0x10);
+		if (cancel_delayed_work_sync(
+		    &va_priv->va_hpf_work[decimator].dwork)) {
+			if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
+				snd_soc_component_update_bits(component,
+						dec_cfg_reg,
+						TX_HPF_CUT_OFF_FREQ_MASK,
+						hpf_cut_off_freq << 5);
+				if (is_amic_enabled(component, decimator))
+					snd_soc_component_update_bits(component,
+						hpf_gate_reg,
+						0x03, 0x02);
+				else
+					snd_soc_component_update_bits(component,
+						hpf_gate_reg,
+						0x03, 0x03);
+				/*
+				 * Minimum 1 clk cycle delay is required
+				 * as per HW spec
+				 */
+				usleep_range(1000, 1010);
+				snd_soc_component_update_bits(component,
+						hpf_gate_reg,
+						0x03, 0x01);
+			}
+		}
+		cancel_delayed_work_sync(
+				&va_priv->va_mute_dwork[decimator].dwork);
+		if (va_priv->version == LPASS_CDC_VERSION_2_0) {
+			if (snd_soc_component_read32(component, adc_mux_reg)
+							& SWR_MIC)
+				snd_soc_component_update_bits(component,
+					LPASS_CDC_TX_TOP_CSR_SWR_CTRL,
+					0x01, 0x00);
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* Disable TX CLK */
+		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
+					0x20, 0x00);
+		snd_soc_component_update_bits(component, tx_vol_ctl_reg,
+					0x10, 0x00);
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_va_macro_enable_tx(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+	int ret = 0;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(va_dev, "%s: event = %d\n", __func__, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		if (va_priv->tx_clk_status > 0) {
+			ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+						   va_priv->default_clk_id,
+						   TX_CORE_CLK,
+						   false);
+			va_priv->tx_clk_status--;
+		}
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		ret = lpass_cdc_clk_rsc_request_clock(va_priv->dev,
+						   va_priv->default_clk_id,
+						   TX_CORE_CLK,
+						   true);
+		if (!ret)
+			va_priv->tx_clk_status++;
+		break;
+	default:
+		dev_err(va_priv->dev,
+			"%s: invalid DAPM event %d\n", __func__, event);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int lpass_cdc_va_macro_enable_micbias(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+	int ret = 0;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	if (!va_priv->micb_supply) {
+		dev_err(va_dev,
+			"%s:regulator not provided in dtsi\n", __func__);
+		return -EINVAL;
+	}
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (va_priv->micb_users++ > 0)
+			return 0;
+		ret = regulator_set_voltage(va_priv->micb_supply,
+				      va_priv->micb_voltage,
+				      va_priv->micb_voltage);
+		if (ret) {
+			dev_err(va_dev, "%s: Setting voltage failed, err = %d\n",
+				__func__, ret);
+			return ret;
+		}
+		ret = regulator_set_load(va_priv->micb_supply,
+					 va_priv->micb_current);
+		if (ret) {
+			dev_err(va_dev, "%s: Setting current failed, err = %d\n",
+				__func__, ret);
+			return ret;
+		}
+		ret = regulator_enable(va_priv->micb_supply);
+		if (ret) {
+			dev_err(va_dev, "%s: regulator enable failed, err = %d\n",
+				__func__, ret);
+			return ret;
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (--va_priv->micb_users > 0)
+			return 0;
+		if (va_priv->micb_users < 0) {
+			va_priv->micb_users = 0;
+			dev_dbg(va_dev, "%s: regulator already disabled\n",
+				__func__);
+			return 0;
+		}
+		ret = regulator_disable(va_priv->micb_supply);
+		if (ret) {
+			dev_err(va_dev, "%s: regulator disable failed, err = %d\n",
+				__func__, ret);
+			return ret;
+		}
+		regulator_set_voltage(va_priv->micb_supply, 0,
+				va_priv->micb_voltage);
+		regulator_set_load(va_priv->micb_supply, 0);
+		break;
+	}
+	return 0;
+}
+
+static inline int lpass_cdc_va_macro_path_get(const char *wname,
+				    unsigned int *path_num)
+{
+	int ret = 0;
+	char *widget_name = NULL;
+	char *w_name = NULL;
+	char *path_num_char = NULL;
+	char *path_name = NULL;
+
+	widget_name = kstrndup(wname, 10, GFP_KERNEL);
+	if (!widget_name)
+		return -EINVAL;
+
+	w_name = widget_name;
+
+	path_name = strsep(&widget_name, " ");
+	if (!path_name) {
+		pr_err("%s: Invalid widget name = %s\n",
+			__func__, widget_name);
+		ret = -EINVAL;
+		goto err;
+	}
+	path_num_char = strpbrk(path_name, "01234567");
+	if (!path_num_char) {
+		pr_err("%s: va path index not found\n",
+			__func__);
+		ret = -EINVAL;
+		goto err;
+	}
+	ret = kstrtouint(path_num_char, 10, path_num);
+	if (ret < 0)
+		pr_err("%s: Invalid tx path = %s\n",
+			__func__, w_name);
+
+err:
+	kfree(w_name);
+	return ret;
+}
+
+static int lpass_cdc_va_macro_dec_mode_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_va_macro_priv *priv = NULL;
+	struct device *va_dev = NULL;
+	int ret = 0;
+	int path = 0;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev, &priv, __func__))
+		return -EINVAL;
+
+	ret = lpass_cdc_va_macro_path_get(kcontrol->id.name, &path);
+	if (ret)
+		return ret;
+
+	ucontrol->value.integer.value[0] = priv->dec_mode[path];
+
+	return 0;
+}
+
+static int lpass_cdc_va_macro_dec_mode_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct lpass_cdc_va_macro_priv *priv = NULL;
+	struct device *va_dev = NULL;
+	int value = ucontrol->value.integer.value[0];
+	int ret = 0;
+	int path = 0;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev, &priv, __func__))
+		return -EINVAL;
+
+	ret = lpass_cdc_va_macro_path_get(kcontrol->id.name, &path);
+	if (ret)
+		return ret;
+
+	priv->dec_mode[path] = value;
+
+	return 0;
+}
+
+static int lpass_cdc_va_macro_hw_params(struct snd_pcm_substream *substream,
+			   struct snd_pcm_hw_params *params,
+			   struct snd_soc_dai *dai)
+{
+	int tx_fs_rate = -EINVAL;
+	struct snd_soc_component *component = dai->component;
+	u32 decimator, sample_rate;
+	u16 tx_fs_reg = 0;
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(va_dev,
+		"%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
+		dai->name, dai->id, params_rate(params),
+		params_channels(params));
+
+	sample_rate = params_rate(params);
+	switch (sample_rate) {
+	case 8000:
+		tx_fs_rate = 0;
+		break;
+	case 16000:
+		tx_fs_rate = 1;
+		break;
+	case 32000:
+		tx_fs_rate = 3;
+		break;
+	case 48000:
+		tx_fs_rate = 4;
+		break;
+	case 96000:
+		tx_fs_rate = 5;
+		break;
+	case 192000:
+		tx_fs_rate = 6;
+		break;
+	case 384000:
+		tx_fs_rate = 7;
+		break;
+	default:
+		dev_err(va_dev, "%s: Invalid TX sample rate: %d\n",
+			__func__, params_rate(params));
+		return -EINVAL;
+	}
+	for_each_set_bit(decimator, &va_priv->active_ch_mask[dai->id],
+			 LPASS_CDC_VA_MACRO_DEC_MAX) {
+		if (decimator >= 0) {
+			tx_fs_reg = LPASS_CDC_VA_TX0_TX_PATH_CTL +
+				  LPASS_CDC_VA_MACRO_TX_PATH_OFFSET * decimator;
+			dev_dbg(va_dev, "%s: set DEC%u rate to %u\n",
+				__func__, decimator, sample_rate);
+			snd_soc_component_update_bits(component, tx_fs_reg,
+						0x0F, tx_fs_rate);
+		} else {
+			dev_err(va_dev,
+				"%s: ERROR: Invalid decimator: %d\n",
+				__func__, decimator);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int lpass_cdc_va_macro_get_channel_map(struct snd_soc_dai *dai,
+				unsigned int *tx_num, unsigned int *tx_slot,
+				unsigned int *rx_num, unsigned int *rx_slot)
+{
+	struct snd_soc_component *component = dai->component;
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	switch (dai->id) {
+	case LPASS_CDC_VA_MACRO_AIF1_CAP:
+	case LPASS_CDC_VA_MACRO_AIF2_CAP:
+	case LPASS_CDC_VA_MACRO_AIF3_CAP:
+		*tx_slot = va_priv->active_ch_mask[dai->id];
+		*tx_num = va_priv->active_ch_cnt[dai->id];
+		break;
+	default:
+		dev_err(va_dev, "%s: Invalid AIF\n", __func__);
+		break;
+	}
+	return 0;
+}
+
+static struct snd_soc_dai_ops lpass_cdc_va_macro_dai_ops = {
+	.hw_params = lpass_cdc_va_macro_hw_params,
+	.get_channel_map = lpass_cdc_va_macro_get_channel_map,
+};
+
+static struct snd_soc_dai_driver lpass_cdc_va_macro_dai[] = {
+	{
+		.name = "lpass_cdc_va_macro_tx1",
+		.id = LPASS_CDC_VA_MACRO_AIF1_CAP,
+		.capture = {
+			.stream_name = "VA_AIF1 Capture",
+			.rates = LPASS_CDC_VA_MACRO_RATES,
+			.formats = LPASS_CDC_VA_MACRO_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 8,
+		},
+		.ops = &lpass_cdc_va_macro_dai_ops,
+	},
+	{
+		.name = "lpass_cdc_va_macro_tx2",
+		.id = LPASS_CDC_VA_MACRO_AIF2_CAP,
+		.capture = {
+			.stream_name = "VA_AIF2 Capture",
+			.rates = LPASS_CDC_VA_MACRO_RATES,
+			.formats = LPASS_CDC_VA_MACRO_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 8,
+		},
+		.ops = &lpass_cdc_va_macro_dai_ops,
+	},
+	{
+		.name = "lpass_cdc_va_macro_tx3",
+		.id = LPASS_CDC_VA_MACRO_AIF3_CAP,
+		.capture = {
+			.stream_name = "VA_AIF3 Capture",
+			.rates = LPASS_CDC_VA_MACRO_RATES,
+			.formats = LPASS_CDC_VA_MACRO_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 8,
+		},
+		.ops = &lpass_cdc_va_macro_dai_ops,
+	},
+};
+
+#define STRING(name) #name
+#define LPASS_CDC_VA_MACRO_DAPM_ENUM(name, reg, offset, text) \
+static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
+static const struct snd_kcontrol_new name##_mux = \
+		SOC_DAPM_ENUM(STRING(name), name##_enum)
+
+#define LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
+static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
+static const struct snd_kcontrol_new name##_mux = \
+		SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
+
+#define LPASS_CDC_VA_MACRO_DAPM_MUX(name, shift, kctl) \
+		SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
+
+static const char * const adc_mux_text[] = {
+	"MSM_DMIC", "SWR_MIC"
+};
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM(va_dec0, LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_VA_MACRO_DAPM_ENUM(va_dec1, LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_VA_MACRO_DAPM_ENUM(va_dec2, LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_VA_MACRO_DAPM_ENUM(va_dec3, LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_VA_MACRO_DAPM_ENUM(va_dec4, LPASS_CDC_VA_INP_MUX_ADC_MUX4_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_VA_MACRO_DAPM_ENUM(va_dec5, LPASS_CDC_VA_INP_MUX_ADC_MUX5_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_VA_MACRO_DAPM_ENUM(va_dec6, LPASS_CDC_VA_INP_MUX_ADC_MUX6_CFG1,
+		   0, adc_mux_text);
+LPASS_CDC_VA_MACRO_DAPM_ENUM(va_dec7, LPASS_CDC_VA_INP_MUX_ADC_MUX7_CFG1,
+		   0, adc_mux_text);
+
+static const char * const dmic_mux_text[] = {
+	"ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3",
+	"DMIC4", "DMIC5", "DMIC6", "DMIC7"
+};
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_dmic0, LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_dmic1, LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_dmic2, LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_dmic3, LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_dmic4, LPASS_CDC_VA_INP_MUX_ADC_MUX4_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_dmic5, LPASS_CDC_VA_INP_MUX_ADC_MUX5_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_dmic6, LPASS_CDC_VA_INP_MUX_ADC_MUX6_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_dmic7, LPASS_CDC_VA_INP_MUX_ADC_MUX7_CFG0,
+			4, dmic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+static const char * const smic_mux_text[] = {
+	"ZERO", "ADC0", "ADC1", "ADC2", "ADC3",
+	"SWR_DMIC0", "SWR_DMIC1", "SWR_DMIC2", "SWR_DMIC3",
+	"SWR_DMIC4", "SWR_DMIC5", "SWR_DMIC6", "SWR_DMIC7"
+};
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic0, LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic1, LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic2, LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic3, LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic4, LPASS_CDC_VA_INP_MUX_ADC_MUX4_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic5, LPASS_CDC_VA_INP_MUX_ADC_MUX5_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic6, LPASS_CDC_VA_INP_MUX_ADC_MUX6_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic7, LPASS_CDC_VA_INP_MUX_ADC_MUX7_CFG0,
+			0, smic_mux_text, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+static const char * const smic_mux_text_v2[] = {
+	"ZERO", "SWR_MIC0", "SWR_MIC1", "SWR_MIC2", "SWR_MIC3",
+	"SWR_MIC4", "SWR_MIC5", "SWR_MIC6", "SWR_MIC7",
+	"SWR_MIC8", "SWR_MIC9", "SWR_MIC10", "SWR_MIC11"
+};
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic0_v2, LPASS_CDC_VA_INP_MUX_ADC_MUX0_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic1_v2, LPASS_CDC_VA_INP_MUX_ADC_MUX1_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic2_v3, LPASS_CDC_VA_INP_MUX_ADC_MUX2_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+LPASS_CDC_VA_MACRO_DAPM_ENUM_EXT(va_smic3_v3, LPASS_CDC_VA_INP_MUX_ADC_MUX3_CFG0,
+			0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+			lpass_cdc_va_macro_put_dec_enum);
+
+static const struct snd_kcontrol_new va_aif1_cap_mixer[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC0, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC1, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC2, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC3, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC4, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC5, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC6, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC7, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif2_cap_mixer[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC0, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC1, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC2, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC3, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC4, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC5, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC6, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC7, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif3_cap_mixer[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC0, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC1, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC2, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC3, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC4", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC4, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC5", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC5, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC6", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC6, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC7", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC7, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif1_cap_mixer_v2[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC0, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC1, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif2_cap_mixer_v2[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC0, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC1, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif3_cap_mixer_v2[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC0, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC1, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif1_cap_mixer_v3[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC0, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC1, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC2, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC3, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif2_cap_mixer_v3[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC0, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC1, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC2, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC3, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif3_cap_mixer_v3[] = {
+	SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC0, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC1, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC2, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+	SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC3, 1, 0,
+			lpass_cdc_va_macro_tx_mixer_get, lpass_cdc_va_macro_tx_mixer_put),
+};
+
+static const struct snd_soc_dapm_widget lpass_cdc_va_macro_dapm_widgets_common[] = {
+	SND_SOC_DAPM_AIF_OUT_E("VA_AIF1 CAP", "VA_AIF1 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_VA_MACRO_AIF1_CAP, 0,
+		lpass_cdc_va_macro_enable_tx, SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("VA_AIF2 CAP", "VA_AIF2 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_VA_MACRO_AIF2_CAP, 0,
+		lpass_cdc_va_macro_enable_tx, SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("VA_AIF3 CAP", "VA_AIF3 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_VA_MACRO_AIF3_CAP, 0,
+		lpass_cdc_va_macro_enable_tx, SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD),
+
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX0", 0, va_dmic0),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX1", 0, va_dmic1),
+
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX0", 0, va_smic0_v2),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX1", 0, va_smic1_v2),
+
+	SND_SOC_DAPM_INPUT("VA SWR_INPUT"),
+
+	SND_SOC_DAPM_SUPPLY("VA MIC BIAS1", SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_micbias,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC0", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC2", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC3", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC4", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC5", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC6", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC7", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("VA DEC0 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC0, 0,
+			   &va_dec0_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("VA DEC1 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC1, 0,
+			   &va_dec1_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
+			      lpass_cdc_va_macro_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_widget lpass_cdc_va_macro_dapm_widgets_v2[] = {
+	SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_VA_MACRO_AIF1_CAP, 0,
+		va_aif1_cap_mixer_v2, ARRAY_SIZE(va_aif1_cap_mixer_v2)),
+
+	SND_SOC_DAPM_MIXER("VA_AIF2_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_VA_MACRO_AIF2_CAP, 0,
+		va_aif2_cap_mixer_v2, ARRAY_SIZE(va_aif2_cap_mixer_v2)),
+
+	SND_SOC_DAPM_MIXER("VA_AIF3_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_VA_MACRO_AIF3_CAP, 0,
+		va_aif3_cap_mixer_v2, ARRAY_SIZE(va_aif3_cap_mixer_v2)),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
+			      lpass_cdc_va_macro_swr_pwr_event_v2,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+			      lpass_cdc_va_macro_tx_swr_clk_event_v2,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+			      lpass_cdc_va_macro_swr_clk_event_v2,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_widget lpass_cdc_va_macro_dapm_widgets_v3[] = {
+	SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_VA_MACRO_AIF1_CAP, 0,
+		va_aif1_cap_mixer_v3, ARRAY_SIZE(va_aif1_cap_mixer_v3)),
+
+	SND_SOC_DAPM_MIXER("VA_AIF2_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_VA_MACRO_AIF2_CAP, 0,
+		va_aif2_cap_mixer_v3, ARRAY_SIZE(va_aif2_cap_mixer_v3)),
+
+	SND_SOC_DAPM_MIXER("VA_AIF3_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_VA_MACRO_AIF3_CAP, 0,
+		va_aif3_cap_mixer_v3, ARRAY_SIZE(va_aif3_cap_mixer_v3)),
+
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX2", 0, va_dmic2),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX3", 0, va_dmic3),
+
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX2", 0, va_smic2_v3),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX3", 0, va_smic3_v3),
+
+	SND_SOC_DAPM_MUX_E("VA DEC2 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC2, 0,
+			   &va_dec2_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("VA DEC3 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC3, 0,
+			   &va_dec3_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
+			      lpass_cdc_va_macro_swr_pwr_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_widget lpass_cdc_va_macro_dapm_widgets[] = {
+	SND_SOC_DAPM_AIF_OUT_E("VA_AIF1 CAP", "VA_AIF1 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_VA_MACRO_AIF1_CAP, 0,
+		lpass_cdc_va_macro_enable_tx, SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("VA_AIF2 CAP", "VA_AIF2 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_VA_MACRO_AIF2_CAP, 0,
+		lpass_cdc_va_macro_enable_tx, SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("VA_AIF3 CAP", "VA_AIF3 Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_VA_MACRO_AIF3_CAP, 0,
+		lpass_cdc_va_macro_enable_tx, SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_VA_MACRO_AIF1_CAP, 0,
+		va_aif1_cap_mixer, ARRAY_SIZE(va_aif1_cap_mixer)),
+
+	SND_SOC_DAPM_MIXER("VA_AIF2_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_VA_MACRO_AIF2_CAP, 0,
+		va_aif2_cap_mixer, ARRAY_SIZE(va_aif2_cap_mixer)),
+
+	SND_SOC_DAPM_MIXER("VA_AIF3_CAP Mixer", SND_SOC_NOPM,
+		LPASS_CDC_VA_MACRO_AIF3_CAP, 0,
+		va_aif3_cap_mixer, ARRAY_SIZE(va_aif3_cap_mixer)),
+
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX0", 0, va_dmic0),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX1", 0, va_dmic1),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX2", 0, va_dmic2),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX3", 0, va_dmic3),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX4", 0, va_dmic4),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX5", 0, va_dmic5),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX6", 0, va_dmic6),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA DMIC MUX7", 0, va_dmic7),
+
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX0", 0, va_smic0),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX1", 0, va_smic1),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX2", 0, va_smic2),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX3", 0, va_smic3),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX4", 0, va_smic4),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX5", 0, va_smic5),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX6", 0, va_smic6),
+	LPASS_CDC_VA_MACRO_DAPM_MUX("VA SMIC MUX7", 0, va_smic7),
+
+	SND_SOC_DAPM_SUPPLY("VA MIC BIAS1", SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_micbias,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC0", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC2", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC3", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC4", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC5", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC6", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("VA DMIC7", NULL, SND_SOC_NOPM, 0, 0,
+		lpass_cdc_va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_INPUT("VA SWR_ADC0"),
+	SND_SOC_DAPM_INPUT("VA SWR_ADC1"),
+	SND_SOC_DAPM_INPUT("VA SWR_ADC2"),
+	SND_SOC_DAPM_INPUT("VA SWR_ADC3"),
+	SND_SOC_DAPM_INPUT("VA SWR_MIC0"),
+	SND_SOC_DAPM_INPUT("VA SWR_MIC1"),
+	SND_SOC_DAPM_INPUT("VA SWR_MIC2"),
+	SND_SOC_DAPM_INPUT("VA SWR_MIC3"),
+	SND_SOC_DAPM_INPUT("VA SWR_MIC4"),
+	SND_SOC_DAPM_INPUT("VA SWR_MIC5"),
+	SND_SOC_DAPM_INPUT("VA SWR_MIC6"),
+	SND_SOC_DAPM_INPUT("VA SWR_MIC7"),
+
+	SND_SOC_DAPM_MUX_E("VA DEC0 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC0, 0,
+			   &va_dec0_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("VA DEC1 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC1, 0,
+			   &va_dec1_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("VA DEC2 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC2, 0,
+			   &va_dec2_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("VA DEC3 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC3, 0,
+			   &va_dec3_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("VA DEC4 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC4, 0,
+			   &va_dec4_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("VA DEC5 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC5, 0,
+			   &va_dec5_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("VA DEC6 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC6, 0,
+			   &va_dec6_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX_E("VA DEC7 MUX", SND_SOC_NOPM, LPASS_CDC_VA_MACRO_DEC7, 0,
+			   &va_dec7_mux, lpass_cdc_va_macro_enable_dec,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
+			      lpass_cdc_va_macro_swr_pwr_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
+			      lpass_cdc_va_macro_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_widget lpass_cdc_va_macro_wod_dapm_widgets[] = {
+	SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
+			      lpass_cdc_va_macro_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_route va_audio_map_common[] = {
+	{"VA_AIF1 CAP", NULL, "VA_MCLK"},
+	{"VA_AIF2 CAP", NULL, "VA_MCLK"},
+	{"VA_AIF3 CAP", NULL, "VA_MCLK"},
+
+	{"VA_AIF1 CAP", NULL, "VA_AIF1_CAP Mixer"},
+	{"VA_AIF2 CAP", NULL, "VA_AIF2_CAP Mixer"},
+	{"VA_AIF3 CAP", NULL, "VA_AIF3_CAP Mixer"},
+
+	{"VA_AIF1_CAP Mixer", "DEC0", "VA DEC0 MUX"},
+	{"VA_AIF1_CAP Mixer", "DEC1", "VA DEC1 MUX"},
+
+	{"VA_AIF2_CAP Mixer", "DEC0", "VA DEC0 MUX"},
+	{"VA_AIF2_CAP Mixer", "DEC1", "VA DEC1 MUX"},
+
+	{"VA_AIF3_CAP Mixer", "DEC0", "VA DEC0 MUX"},
+	{"VA_AIF3_CAP Mixer", "DEC1", "VA DEC1 MUX"},
+
+	{"VA DEC0 MUX", "MSM_DMIC", "VA DMIC MUX0"},
+	{"VA DMIC MUX0", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX0", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX0", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX0", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX0", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX0", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX0", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX0", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC0 MUX", "SWR_MIC", "VA SMIC MUX0"},
+	{"VA SMIC MUX0", "SWR_MIC0", "VA SWR_INPUT"},
+	{"VA SMIC MUX0", "SWR_MIC1", "VA SWR_INPUT"},
+	{"VA SMIC MUX0", "SWR_MIC2", "VA SWR_INPUT"},
+	{"VA SMIC MUX0", "SWR_MIC3", "VA SWR_INPUT"},
+	{"VA SMIC MUX0", "SWR_MIC4", "VA SWR_INPUT"},
+	{"VA SMIC MUX0", "SWR_MIC5", "VA SWR_INPUT"},
+	{"VA SMIC MUX0", "SWR_MIC6", "VA SWR_INPUT"},
+	{"VA SMIC MUX0", "SWR_MIC7", "VA SWR_INPUT"},
+	{"VA SMIC MUX0", "SWR_MIC8", "VA SWR_INPUT"},
+	{"VA SMIC MUX0", "SWR_MIC9", "VA SWR_INPUT"},
+	{"VA SMIC MUX0", "SWR_MIC10", "VA SWR_INPUT"},
+	{"VA SMIC MUX0", "SWR_MIC11", "VA SWR_INPUT"},
+
+	{"VA DEC1 MUX", "MSM_DMIC", "VA DMIC MUX1"},
+	{"VA DMIC MUX1", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX1", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX1", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX1", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX1", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX1", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX1", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX1", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC1 MUX", "SWR_MIC", "VA SMIC MUX1"},
+	{"VA SMIC MUX1", "SWR_MIC0", "VA SWR_INPUT"},
+	{"VA SMIC MUX1", "SWR_MIC1", "VA SWR_INPUT"},
+	{"VA SMIC MUX1", "SWR_MIC2", "VA SWR_INPUT"},
+	{"VA SMIC MUX1", "SWR_MIC3", "VA SWR_INPUT"},
+	{"VA SMIC MUX1", "SWR_MIC4", "VA SWR_INPUT"},
+	{"VA SMIC MUX1", "SWR_MIC5", "VA SWR_INPUT"},
+	{"VA SMIC MUX1", "SWR_MIC6", "VA SWR_INPUT"},
+	{"VA SMIC MUX1", "SWR_MIC7", "VA SWR_INPUT"},
+	{"VA SMIC MUX1", "SWR_MIC8", "VA SWR_INPUT"},
+	{"VA SMIC MUX1", "SWR_MIC9", "VA SWR_INPUT"},
+	{"VA SMIC MUX1", "SWR_MIC10", "VA SWR_INPUT"},
+	{"VA SMIC MUX1", "SWR_MIC11", "VA SWR_INPUT"},
+
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
+
+};
+
+static const struct snd_soc_dapm_route va_audio_map_v3[] = {
+	{"VA_AIF1_CAP Mixer", "DEC2", "VA DEC2 MUX"},
+	{"VA_AIF1_CAP Mixer", "DEC3", "VA DEC3 MUX"},
+
+	{"VA_AIF2_CAP Mixer", "DEC2", "VA DEC2 MUX"},
+	{"VA_AIF2_CAP Mixer", "DEC3", "VA DEC3 MUX"},
+
+	{"VA_AIF3_CAP Mixer", "DEC2", "VA DEC2 MUX"},
+	{"VA_AIF3_CAP Mixer", "DEC3", "VA DEC3 MUX"},
+
+	{"VA DEC2 MUX", "MSM_DMIC", "VA DMIC MUX2"},
+	{"VA DMIC MUX2", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX2", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX2", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX2", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX2", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX2", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX2", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX2", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC2 MUX", "SWR_MIC", "VA SMIC MUX2"},
+	{"VA SMIC MUX2", "SWR_MIC0", "VA SWR_INPUT"},
+	{"VA SMIC MUX2", "SWR_MIC1", "VA SWR_INPUT"},
+	{"VA SMIC MUX2", "SWR_MIC2", "VA SWR_INPUT"},
+	{"VA SMIC MUX2", "SWR_MIC3", "VA SWR_INPUT"},
+	{"VA SMIC MUX2", "SWR_MIC4", "VA SWR_INPUT"},
+	{"VA SMIC MUX2", "SWR_MIC5", "VA SWR_INPUT"},
+	{"VA SMIC MUX2", "SWR_MIC6", "VA SWR_INPUT"},
+	{"VA SMIC MUX2", "SWR_MIC7", "VA SWR_INPUT"},
+	{"VA SMIC MUX2", "SWR_MIC8", "VA SWR_INPUT"},
+	{"VA SMIC MUX2", "SWR_MIC9", "VA SWR_INPUT"},
+	{"VA SMIC MUX2", "SWR_MIC10", "VA SWR_INPUT"},
+	{"VA SMIC MUX2", "SWR_MIC11", "VA SWR_INPUT"},
+
+	{"VA DEC3 MUX", "MSM_DMIC", "VA DMIC MUX3"},
+	{"VA DMIC MUX3", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX3", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX3", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX3", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX3", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX3", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX3", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX3", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC3 MUX", "SWR_MIC", "VA SMIC MUX3"},
+	{"VA SMIC MUX3", "SWR_MIC0", "VA SWR_INPUT"},
+	{"VA SMIC MUX3", "SWR_MIC1", "VA SWR_INPUT"},
+	{"VA SMIC MUX3", "SWR_MIC2", "VA SWR_INPUT"},
+	{"VA SMIC MUX3", "SWR_MIC3", "VA SWR_INPUT"},
+	{"VA SMIC MUX3", "SWR_MIC4", "VA SWR_INPUT"},
+	{"VA SMIC MUX3", "SWR_MIC5", "VA SWR_INPUT"},
+	{"VA SMIC MUX3", "SWR_MIC6", "VA SWR_INPUT"},
+	{"VA SMIC MUX3", "SWR_MIC7", "VA SWR_INPUT"},
+	{"VA SMIC MUX3", "SWR_MIC8", "VA SWR_INPUT"},
+	{"VA SMIC MUX3", "SWR_MIC9", "VA SWR_INPUT"},
+	{"VA SMIC MUX3", "SWR_MIC10", "VA SWR_INPUT"},
+	{"VA SMIC MUX3", "SWR_MIC11", "VA SWR_INPUT"},
+};
+
+static const struct snd_soc_dapm_route va_audio_map_v2[] = {
+	{"VA_AIF1 CAP", NULL, "VA_SWR_CLK"},
+	{"VA_AIF2 CAP", NULL, "VA_SWR_CLK"},
+	{"VA_AIF3 CAP", NULL, "VA_SWR_CLK"},
+};
+
+static const struct snd_soc_dapm_route va_audio_map[] = {
+	{"VA_AIF1 CAP", NULL, "VA_MCLK"},
+	{"VA_AIF2 CAP", NULL, "VA_MCLK"},
+	{"VA_AIF3 CAP", NULL, "VA_MCLK"},
+
+	{"VA_AIF1 CAP", NULL, "VA_AIF1_CAP Mixer"},
+	{"VA_AIF2 CAP", NULL, "VA_AIF2_CAP Mixer"},
+	{"VA_AIF3 CAP", NULL, "VA_AIF3_CAP Mixer"},
+
+	{"VA_AIF1_CAP Mixer", "DEC0", "VA DEC0 MUX"},
+	{"VA_AIF1_CAP Mixer", "DEC1", "VA DEC1 MUX"},
+	{"VA_AIF1_CAP Mixer", "DEC2", "VA DEC2 MUX"},
+	{"VA_AIF1_CAP Mixer", "DEC3", "VA DEC3 MUX"},
+	{"VA_AIF1_CAP Mixer", "DEC4", "VA DEC4 MUX"},
+	{"VA_AIF1_CAP Mixer", "DEC5", "VA DEC5 MUX"},
+	{"VA_AIF1_CAP Mixer", "DEC6", "VA DEC6 MUX"},
+	{"VA_AIF1_CAP Mixer", "DEC7", "VA DEC7 MUX"},
+
+	{"VA_AIF2_CAP Mixer", "DEC0", "VA DEC0 MUX"},
+	{"VA_AIF2_CAP Mixer", "DEC1", "VA DEC1 MUX"},
+	{"VA_AIF2_CAP Mixer", "DEC2", "VA DEC2 MUX"},
+	{"VA_AIF2_CAP Mixer", "DEC3", "VA DEC3 MUX"},
+	{"VA_AIF2_CAP Mixer", "DEC4", "VA DEC4 MUX"},
+	{"VA_AIF2_CAP Mixer", "DEC5", "VA DEC5 MUX"},
+	{"VA_AIF2_CAP Mixer", "DEC6", "VA DEC6 MUX"},
+	{"VA_AIF2_CAP Mixer", "DEC7", "VA DEC7 MUX"},
+
+	{"VA_AIF3_CAP Mixer", "DEC0", "VA DEC0 MUX"},
+	{"VA_AIF3_CAP Mixer", "DEC1", "VA DEC1 MUX"},
+	{"VA_AIF3_CAP Mixer", "DEC2", "VA DEC2 MUX"},
+	{"VA_AIF3_CAP Mixer", "DEC3", "VA DEC3 MUX"},
+	{"VA_AIF3_CAP Mixer", "DEC4", "VA DEC4 MUX"},
+	{"VA_AIF3_CAP Mixer", "DEC5", "VA DEC5 MUX"},
+	{"VA_AIF3_CAP Mixer", "DEC6", "VA DEC6 MUX"},
+	{"VA_AIF3_CAP Mixer", "DEC7", "VA DEC7 MUX"},
+
+	{"VA DEC0 MUX", "MSM_DMIC", "VA DMIC MUX0"},
+	{"VA DMIC MUX0", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX0", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX0", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX0", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX0", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX0", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX0", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX0", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC0 MUX", "SWR_MIC", "VA SMIC MUX0"},
+	{"VA SMIC MUX0", "ADC0", "VA SWR_ADC0"},
+	{"VA SMIC MUX0", "ADC1", "VA SWR_ADC1"},
+	{"VA SMIC MUX0", "ADC2", "VA SWR_ADC2"},
+	{"VA SMIC MUX0", "ADC3", "VA SWR_ADC3"},
+	{"VA SMIC MUX0", "SWR_DMIC0", "VA SWR_MIC0"},
+	{"VA SMIC MUX0", "SWR_DMIC1", "VA SWR_MIC1"},
+	{"VA SMIC MUX0", "SWR_DMIC2", "VA SWR_MIC2"},
+	{"VA SMIC MUX0", "SWR_DMIC3", "VA SWR_MIC3"},
+	{"VA SMIC MUX0", "SWR_DMIC4", "VA SWR_MIC4"},
+	{"VA SMIC MUX0", "SWR_DMIC5", "VA SWR_MIC5"},
+	{"VA SMIC MUX0", "SWR_DMIC6", "VA SWR_MIC6"},
+	{"VA SMIC MUX0", "SWR_DMIC7", "VA SWR_MIC7"},
+
+	{"VA DEC1 MUX", "MSM_DMIC", "VA DMIC MUX1"},
+	{"VA DMIC MUX1", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX1", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX1", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX1", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX1", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX1", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX1", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX1", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC1 MUX", "SWR_MIC", "VA SMIC MUX1"},
+	{"VA SMIC MUX1", "ADC0", "VA SWR_ADC0"},
+	{"VA SMIC MUX1", "ADC1", "VA SWR_ADC1"},
+	{"VA SMIC MUX1", "ADC2", "VA SWR_ADC2"},
+	{"VA SMIC MUX1", "ADC3", "VA SWR_ADC3"},
+	{"VA SMIC MUX1", "SWR_DMIC0", "VA SWR_MIC0"},
+	{"VA SMIC MUX1", "SWR_DMIC1", "VA SWR_MIC1"},
+	{"VA SMIC MUX1", "SWR_DMIC2", "VA SWR_MIC2"},
+	{"VA SMIC MUX1", "SWR_DMIC3", "VA SWR_MIC3"},
+	{"VA SMIC MUX1", "SWR_DMIC4", "VA SWR_MIC4"},
+	{"VA SMIC MUX1", "SWR_DMIC5", "VA SWR_MIC5"},
+	{"VA SMIC MUX1", "SWR_DMIC6", "VA SWR_MIC6"},
+	{"VA SMIC MUX1", "SWR_DMIC7", "VA SWR_MIC7"},
+
+	{"VA DEC2 MUX", "MSM_DMIC", "VA DMIC MUX2"},
+	{"VA DMIC MUX2", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX2", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX2", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX2", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX2", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX2", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX2", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX2", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC2 MUX", "SWR_MIC", "VA SMIC MUX2"},
+	{"VA SMIC MUX2", "ADC0", "VA SWR_ADC0"},
+	{"VA SMIC MUX2", "ADC1", "VA SWR_ADC1"},
+	{"VA SMIC MUX2", "ADC2", "VA SWR_ADC2"},
+	{"VA SMIC MUX2", "ADC3", "VA SWR_ADC3"},
+	{"VA SMIC MUX2", "SWR_DMIC0", "VA SWR_MIC0"},
+	{"VA SMIC MUX2", "SWR_DMIC1", "VA SWR_MIC1"},
+	{"VA SMIC MUX2", "SWR_DMIC2", "VA SWR_MIC2"},
+	{"VA SMIC MUX2", "SWR_DMIC3", "VA SWR_MIC3"},
+	{"VA SMIC MUX2", "SWR_DMIC4", "VA SWR_MIC4"},
+	{"VA SMIC MUX2", "SWR_DMIC5", "VA SWR_MIC5"},
+	{"VA SMIC MUX2", "SWR_DMIC6", "VA SWR_MIC6"},
+	{"VA SMIC MUX2", "SWR_DMIC7", "VA SWR_MIC7"},
+
+	{"VA DEC3 MUX", "MSM_DMIC", "VA DMIC MUX3"},
+	{"VA DMIC MUX3", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX3", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX3", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX3", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX3", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX3", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX3", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX3", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC3 MUX", "SWR_MIC", "VA SMIC MUX3"},
+	{"VA SMIC MUX3", "ADC0", "VA SWR_ADC0"},
+	{"VA SMIC MUX3", "ADC1", "VA SWR_ADC1"},
+	{"VA SMIC MUX3", "ADC2", "VA SWR_ADC2"},
+	{"VA SMIC MUX3", "ADC3", "VA SWR_ADC3"},
+	{"VA SMIC MUX3", "SWR_DMIC0", "VA SWR_MIC0"},
+	{"VA SMIC MUX3", "SWR_DMIC1", "VA SWR_MIC1"},
+	{"VA SMIC MUX3", "SWR_DMIC2", "VA SWR_MIC2"},
+	{"VA SMIC MUX3", "SWR_DMIC3", "VA SWR_MIC3"},
+	{"VA SMIC MUX3", "SWR_DMIC4", "VA SWR_MIC4"},
+	{"VA SMIC MUX3", "SWR_DMIC5", "VA SWR_MIC5"},
+	{"VA SMIC MUX3", "SWR_DMIC6", "VA SWR_MIC6"},
+	{"VA SMIC MUX3", "SWR_DMIC7", "VA SWR_MIC7"},
+
+	{"VA DEC4 MUX", "MSM_DMIC", "VA DMIC MUX4"},
+	{"VA DMIC MUX4", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX4", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX4", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX4", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX4", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX4", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX4", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX4", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC4 MUX", "SWR_MIC", "VA SMIC MUX4"},
+	{"VA SMIC MUX4", "ADC0", "VA SWR_ADC0"},
+	{"VA SMIC MUX4", "ADC1", "VA SWR_ADC1"},
+	{"VA SMIC MUX4", "ADC2", "VA SWR_ADC2"},
+	{"VA SMIC MUX4", "ADC3", "VA SWR_ADC3"},
+	{"VA SMIC MUX4", "SWR_DMIC0", "VA SWR_MIC0"},
+	{"VA SMIC MUX4", "SWR_DMIC1", "VA SWR_MIC1"},
+	{"VA SMIC MUX4", "SWR_DMIC2", "VA SWR_MIC2"},
+	{"VA SMIC MUX4", "SWR_DMIC3", "VA SWR_MIC3"},
+	{"VA SMIC MUX4", "SWR_DMIC4", "VA SWR_MIC4"},
+	{"VA SMIC MUX4", "SWR_DMIC5", "VA SWR_MIC5"},
+	{"VA SMIC MUX4", "SWR_DMIC6", "VA SWR_MIC6"},
+	{"VA SMIC MUX4", "SWR_DMIC7", "VA SWR_MIC7"},
+
+	{"VA DEC5 MUX", "MSM_DMIC", "VA DMIC MUX5"},
+	{"VA DMIC MUX5", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX5", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX5", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX5", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX5", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX5", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX5", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX5", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC5 MUX", "SWR_MIC", "VA SMIC MUX5"},
+	{"VA SMIC MUX5", "ADC0", "VA SWR_ADC0"},
+	{"VA SMIC MUX5", "ADC1", "VA SWR_ADC1"},
+	{"VA SMIC MUX5", "ADC2", "VA SWR_ADC2"},
+	{"VA SMIC MUX5", "ADC3", "VA SWR_ADC3"},
+	{"VA SMIC MUX5", "SWR_DMIC0", "VA SWR_MIC0"},
+	{"VA SMIC MUX5", "SWR_DMIC1", "VA SWR_MIC1"},
+	{"VA SMIC MUX5", "SWR_DMIC2", "VA SWR_MIC2"},
+	{"VA SMIC MUX5", "SWR_DMIC3", "VA SWR_MIC3"},
+	{"VA SMIC MUX5", "SWR_DMIC4", "VA SWR_MIC4"},
+	{"VA SMIC MUX5", "SWR_DMIC5", "VA SWR_MIC5"},
+	{"VA SMIC MUX5", "SWR_DMIC6", "VA SWR_MIC6"},
+	{"VA SMIC MUX5", "SWR_DMIC7", "VA SWR_MIC7"},
+
+	{"VA DEC6 MUX", "MSM_DMIC", "VA DMIC MUX6"},
+	{"VA DMIC MUX6", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX6", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX6", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX6", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX6", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX6", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX6", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX6", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC6 MUX", "SWR_MIC", "VA SMIC MUX6"},
+	{"VA SMIC MUX6", "ADC0", "VA SWR_ADC0"},
+	{"VA SMIC MUX6", "ADC1", "VA SWR_ADC1"},
+	{"VA SMIC MUX6", "ADC2", "VA SWR_ADC2"},
+	{"VA SMIC MUX6", "ADC3", "VA SWR_ADC3"},
+	{"VA SMIC MUX6", "SWR_DMIC0", "VA SWR_MIC0"},
+	{"VA SMIC MUX6", "SWR_DMIC1", "VA SWR_MIC1"},
+	{"VA SMIC MUX6", "SWR_DMIC2", "VA SWR_MIC2"},
+	{"VA SMIC MUX6", "SWR_DMIC3", "VA SWR_MIC3"},
+	{"VA SMIC MUX6", "SWR_DMIC4", "VA SWR_MIC4"},
+	{"VA SMIC MUX6", "SWR_DMIC5", "VA SWR_MIC5"},
+	{"VA SMIC MUX6", "SWR_DMIC6", "VA SWR_MIC6"},
+	{"VA SMIC MUX6", "SWR_DMIC7", "VA SWR_MIC7"},
+
+	{"VA DEC7 MUX", "MSM_DMIC", "VA DMIC MUX7"},
+	{"VA DMIC MUX7", "DMIC0", "VA DMIC0"},
+	{"VA DMIC MUX7", "DMIC1", "VA DMIC1"},
+	{"VA DMIC MUX7", "DMIC2", "VA DMIC2"},
+	{"VA DMIC MUX7", "DMIC3", "VA DMIC3"},
+	{"VA DMIC MUX7", "DMIC4", "VA DMIC4"},
+	{"VA DMIC MUX7", "DMIC5", "VA DMIC5"},
+	{"VA DMIC MUX7", "DMIC6", "VA DMIC6"},
+	{"VA DMIC MUX7", "DMIC7", "VA DMIC7"},
+
+	{"VA DEC7 MUX", "SWR_MIC", "VA SMIC MUX7"},
+	{"VA SMIC MUX7", "ADC0", "VA SWR_ADC0"},
+	{"VA SMIC MUX7", "ADC1", "VA SWR_ADC1"},
+	{"VA SMIC MUX7", "ADC2", "VA SWR_ADC2"},
+	{"VA SMIC MUX7", "ADC3", "VA SWR_ADC3"},
+	{"VA SMIC MUX7", "SWR_DMIC0", "VA SWR_MIC0"},
+	{"VA SMIC MUX7", "SWR_DMIC1", "VA SWR_MIC1"},
+	{"VA SMIC MUX7", "SWR_DMIC2", "VA SWR_MIC2"},
+	{"VA SMIC MUX7", "SWR_DMIC3", "VA SWR_MIC3"},
+	{"VA SMIC MUX7", "SWR_DMIC4", "VA SWR_MIC4"},
+	{"VA SMIC MUX7", "SWR_DMIC5", "VA SWR_MIC5"},
+	{"VA SMIC MUX7", "SWR_DMIC6", "VA SWR_MIC6"},
+	{"VA SMIC MUX7", "SWR_DMIC7", "VA SWR_MIC7"},
+
+	{"VA SWR_ADC0", NULL, "VA_SWR_PWR"},
+	{"VA SWR_ADC1", NULL, "VA_SWR_PWR"},
+	{"VA SWR_ADC2", NULL, "VA_SWR_PWR"},
+	{"VA SWR_ADC3", NULL, "VA_SWR_PWR"},
+	{"VA SWR_MIC0", NULL, "VA_SWR_PWR"},
+	{"VA SWR_MIC1", NULL, "VA_SWR_PWR"},
+	{"VA SWR_MIC2", NULL, "VA_SWR_PWR"},
+	{"VA SWR_MIC3", NULL, "VA_SWR_PWR"},
+	{"VA SWR_MIC4", NULL, "VA_SWR_PWR"},
+	{"VA SWR_MIC5", NULL, "VA_SWR_PWR"},
+	{"VA SWR_MIC6", NULL, "VA_SWR_PWR"},
+	{"VA SWR_MIC7", NULL, "VA_SWR_PWR"},
+};
+
+static const char * const dec_mode_mux_text[] = {
+	"ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF",
+};
+
+static const struct soc_enum dec_mode_mux_enum =
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dec_mode_mux_text),
+			    dec_mode_mux_text);
+
+static const struct snd_kcontrol_new lpass_cdc_va_macro_snd_controls[] = {
+	SOC_SINGLE_S8_TLV("VA_DEC0 Volume",
+			  LPASS_CDC_VA_TX0_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("VA_DEC1 Volume",
+			  LPASS_CDC_VA_TX1_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("VA_DEC2 Volume",
+			  LPASS_CDC_VA_TX2_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("VA_DEC3 Volume",
+			  LPASS_CDC_VA_TX3_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("VA_DEC4 Volume",
+			  LPASS_CDC_VA_TX4_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("VA_DEC5 Volume",
+			  LPASS_CDC_VA_TX5_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("VA_DEC6 Volume",
+			  LPASS_CDC_VA_TX6_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("VA_DEC7 Volume",
+			  LPASS_CDC_VA_TX7_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_EXT("LPI Enable", 0, 0, 1, 0,
+		lpass_cdc_va_macro_lpi_get, lpass_cdc_va_macro_lpi_put),
+
+	SOC_ENUM_EXT("VA_DEC0 MODE", dec_mode_mux_enum,
+			lpass_cdc_va_macro_dec_mode_get, lpass_cdc_va_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("VA_DEC1 MODE", dec_mode_mux_enum,
+			lpass_cdc_va_macro_dec_mode_get, lpass_cdc_va_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("VA_DEC2 MODE", dec_mode_mux_enum,
+			lpass_cdc_va_macro_dec_mode_get, lpass_cdc_va_macro_dec_mode_put),
+
+	SOC_ENUM_EXT("VA_DEC3 MODE", dec_mode_mux_enum,
+			lpass_cdc_va_macro_dec_mode_get, lpass_cdc_va_macro_dec_mode_put),
+};
+
+static const struct snd_kcontrol_new lpass_cdc_va_macro_snd_controls_common[] =
+{
+	SOC_SINGLE_S8_TLV("VA_DEC0 Volume",
+			  LPASS_CDC_VA_TX0_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("VA_DEC1 Volume",
+			  LPASS_CDC_VA_TX1_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_EXT("LPI Enable", 0, 0, 1, 0,
+		lpass_cdc_va_macro_lpi_get, lpass_cdc_va_macro_lpi_put),
+};
+
+static const struct snd_kcontrol_new lpass_cdc_va_macro_snd_controls_v3[] = {
+	SOC_SINGLE_S8_TLV("VA_DEC2 Volume",
+			  LPASS_CDC_VA_TX2_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("VA_DEC3 Volume",
+			  LPASS_CDC_VA_TX3_TX_VOL_CTL,
+			  -84, 40, digital_gain),
+};
+
+static int lpass_cdc_va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
+				      struct lpass_cdc_va_macro_priv *va_priv)
+{
+	u32 div_factor;
+	u32 mclk_rate = LPASS_CDC_VA_MACRO_MCLK_FREQ;
+
+	if (dmic_sample_rate == LPASS_CDC_VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED ||
+	    mclk_rate % dmic_sample_rate != 0)
+		goto undefined_rate;
+
+	div_factor = mclk_rate / dmic_sample_rate;
+
+	switch (div_factor) {
+	case 2:
+		va_priv->dmic_clk_div = LPASS_CDC_VA_MACRO_CLK_DIV_2;
+		break;
+	case 3:
+		va_priv->dmic_clk_div = LPASS_CDC_VA_MACRO_CLK_DIV_3;
+		break;
+	case 4:
+		va_priv->dmic_clk_div = LPASS_CDC_VA_MACRO_CLK_DIV_4;
+		break;
+	case 6:
+		va_priv->dmic_clk_div = LPASS_CDC_VA_MACRO_CLK_DIV_6;
+		break;
+	case 8:
+		va_priv->dmic_clk_div = LPASS_CDC_VA_MACRO_CLK_DIV_8;
+		break;
+	case 16:
+		va_priv->dmic_clk_div = LPASS_CDC_VA_MACRO_CLK_DIV_16;
+		break;
+	default:
+		/* Any other DIV factor is invalid */
+		goto undefined_rate;
+	}
+
+	/* Valid dmic DIV factors */
+	dev_dbg(va_priv->dev, "%s: DMIC_DIV = %u, mclk_rate = %u\n",
+		__func__, div_factor, mclk_rate);
+
+	return dmic_sample_rate;
+
+undefined_rate:
+	dev_dbg(va_priv->dev, "%s: Invalid rate %d, for mclk %d\n",
+		 __func__, dmic_sample_rate, mclk_rate);
+	dmic_sample_rate = LPASS_CDC_VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED;
+
+	return dmic_sample_rate;
+}
+
+static int lpass_cdc_va_macro_init(struct snd_soc_component *component)
+{
+	struct snd_soc_dapm_context *dapm =
+				snd_soc_component_get_dapm(component);
+	int ret, i;
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	va_dev = lpass_cdc_get_device_ptr(component->dev, VA_MACRO);
+	if (!va_dev) {
+		dev_err(component->dev,
+			"%s: null device for macro!\n", __func__);
+		return -EINVAL;
+	}
+	va_priv = dev_get_drvdata(va_dev);
+	if (!va_priv) {
+		dev_err(component->dev,
+			"%s: priv is null for macro!\n", __func__);
+		return -EINVAL;
+	}
+
+	va_priv->lpi_enable = false;
+	va_priv->register_event_listener = false;
+
+	if (va_priv->va_without_decimation) {
+		ret = snd_soc_dapm_new_controls(dapm,
+			lpass_cdc_va_macro_wod_dapm_widgets,
+			ARRAY_SIZE(lpass_cdc_va_macro_wod_dapm_widgets));
+		if (ret < 0) {
+			dev_err(va_dev,
+				"%s: Failed to add without dec controls\n",
+				__func__);
+			return ret;
+		}
+		va_priv->component = component;
+		return 0;
+	}
+
+	va_priv->version = lpass_cdc_get_version(va_dev);
+	if (va_priv->version >= LPASS_CDC_VERSION_2_0) {
+		ret = snd_soc_dapm_new_controls(dapm,
+			lpass_cdc_va_macro_dapm_widgets_common,
+			ARRAY_SIZE(lpass_cdc_va_macro_dapm_widgets_common));
+		if (ret < 0) {
+			dev_err(va_dev, "%s: Failed to add controls\n",
+				__func__);
+			return ret;
+		}
+		if (va_priv->version == LPASS_CDC_VERSION_2_1)
+			ret = snd_soc_dapm_new_controls(dapm,
+				lpass_cdc_va_macro_dapm_widgets_v2,
+				ARRAY_SIZE(lpass_cdc_va_macro_dapm_widgets_v2));
+		else if (va_priv->version == LPASS_CDC_VERSION_2_0)
+			ret = snd_soc_dapm_new_controls(dapm,
+				lpass_cdc_va_macro_dapm_widgets_v3,
+				ARRAY_SIZE(lpass_cdc_va_macro_dapm_widgets_v3));
+		if (ret < 0) {
+			dev_err(va_dev, "%s: Failed to add controls\n",
+				__func__);
+			return ret;
+		}
+	} else {
+		ret = snd_soc_dapm_new_controls(dapm,
+				lpass_cdc_va_macro_dapm_widgets,
+				ARRAY_SIZE(lpass_cdc_va_macro_dapm_widgets));
+		if (ret < 0) {
+			dev_err(va_dev, "%s: Failed to add controls\n",
+				__func__);
+			return ret;
+		}
+	}
+
+	if (va_priv->version >= LPASS_CDC_VERSION_2_0) {
+		ret = snd_soc_dapm_add_routes(dapm,
+					va_audio_map_common,
+					ARRAY_SIZE(va_audio_map_common));
+		if (ret < 0) {
+			dev_err(va_dev, "%s: Failed to add routes\n",
+				__func__);
+			return ret;
+		}
+		if (va_priv->version == LPASS_CDC_VERSION_2_0) {
+			ret = snd_soc_dapm_add_routes(dapm,
+					va_audio_map_v3,
+					ARRAY_SIZE(va_audio_map_v3));
+			if (ret < 0) {
+				dev_err(va_dev, "%s: Failed to add routes\n",
+					__func__);
+				return ret;
+			}
+		}
+		if (va_priv->version == LPASS_CDC_VERSION_2_1) {
+			ret = snd_soc_dapm_add_routes(dapm,
+					va_audio_map_v2,
+					ARRAY_SIZE(va_audio_map_v2));
+			if (ret < 0) {
+				dev_err(va_dev, "%s: Failed to add routes\n",
+					__func__);
+				return ret;
+			}
+		}
+	} else {
+		ret = snd_soc_dapm_add_routes(dapm, va_audio_map,
+					ARRAY_SIZE(va_audio_map));
+		if (ret < 0) {
+			dev_err(va_dev, "%s: Failed to add routes\n",
+				__func__);
+			return ret;
+		}
+	}
+
+	ret = snd_soc_dapm_new_widgets(dapm->card);
+	if (ret < 0) {
+		dev_err(va_dev, "%s: Failed to add widgets\n", __func__);
+		return ret;
+	}
+	if (va_priv->version >= LPASS_CDC_VERSION_2_0) {
+		ret = snd_soc_add_component_controls(component,
+			lpass_cdc_va_macro_snd_controls_common,
+			ARRAY_SIZE(lpass_cdc_va_macro_snd_controls_common));
+		if (ret < 0) {
+			dev_err(va_dev, "%s: Failed to add snd_ctls\n",
+				__func__);
+			return ret;
+		}
+		if (va_priv->version == LPASS_CDC_VERSION_2_0)
+			ret = snd_soc_add_component_controls(component,
+				lpass_cdc_va_macro_snd_controls_v3,
+				ARRAY_SIZE(lpass_cdc_va_macro_snd_controls_v3));
+		if (ret < 0) {
+			dev_err(va_dev, "%s: Failed to add snd_ctls\n",
+				__func__);
+			return ret;
+		}
+	} else {
+		ret = snd_soc_add_component_controls(component,
+				lpass_cdc_va_macro_snd_controls,
+				ARRAY_SIZE(lpass_cdc_va_macro_snd_controls));
+		if (ret < 0) {
+			dev_err(va_dev, "%s: Failed to add snd_ctls\n",
+				__func__);
+			return ret;
+		}
+	}
+
+	snd_soc_dapm_ignore_suspend(dapm, "VA_AIF1 Capture");
+	snd_soc_dapm_ignore_suspend(dapm, "VA_AIF2 Capture");
+	snd_soc_dapm_ignore_suspend(dapm, "VA_AIF3 Capture");
+	if (va_priv->version >= LPASS_CDC_VERSION_2_0) {
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_INPUT");
+	} else {
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC0");
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC1");
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC2");
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC3");
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC0");
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC1");
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC2");
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC3");
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC4");
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC5");
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC6");
+		snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC7");
+	}
+	snd_soc_dapm_sync(dapm);
+
+	for (i = 0; i < LPASS_CDC_VA_MACRO_NUM_DECIMATORS; i++) {
+		va_priv->va_hpf_work[i].va_priv = va_priv;
+		va_priv->va_hpf_work[i].decimator = i;
+		INIT_DELAYED_WORK(&va_priv->va_hpf_work[i].dwork,
+			lpass_cdc_va_macro_tx_hpf_corner_freq_callback);
+	}
+
+	for (i = 0; i < LPASS_CDC_VA_MACRO_NUM_DECIMATORS; i++) {
+		va_priv->va_mute_dwork[i].va_priv = va_priv;
+		va_priv->va_mute_dwork[i].decimator = i;
+		INIT_DELAYED_WORK(&va_priv->va_mute_dwork[i].dwork,
+			  lpass_cdc_va_macro_mute_update_callback);
+	}
+	va_priv->component = component;
+
+	if (va_priv->version == LPASS_CDC_VERSION_2_1) {
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL0, 0xEE, 0xCC);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL1, 0xEE, 0xCC);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_VA_TOP_CSR_SWR_MIC_CTL2, 0xEE, 0xCC);
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_va_macro_deinit(struct snd_soc_component *component)
+{
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					 &va_priv, __func__))
+		return -EINVAL;
+
+	va_priv->component = NULL;
+	return 0;
+}
+
+static void lpass_cdc_va_macro_add_child_devices(struct work_struct *work)
+{
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+	struct platform_device *pdev = NULL;
+	struct device_node *node = NULL;
+	struct lpass_cdc_va_macro_swr_ctrl_data *swr_ctrl_data = NULL;
+	struct lpass_cdc_va_macro_swr_ctrl_data *temp = NULL;
+	int ret = 0;
+	u16 count = 0, ctrl_num = 0;
+	struct lpass_cdc_va_macro_swr_ctrl_platform_data *platdata = NULL;
+	char plat_dev_name[LPASS_CDC_VA_MACRO_SWR_STRING_LEN] = "";
+	bool va_swr_master_node = false;
+
+	va_priv = container_of(work, struct lpass_cdc_va_macro_priv,
+			     lpass_cdc_va_macro_add_child_devices_work);
+	if (!va_priv) {
+		pr_err("%s: Memory for va_priv does not exist\n",
+			__func__);
+		return;
+	}
+
+	if (!va_priv->dev) {
+		pr_err("%s: VA dev does not exist\n", __func__);
+		return;
+	}
+
+	if (!va_priv->dev->of_node) {
+		dev_err(va_priv->dev,
+			"%s: DT node for va_priv does not exist\n", __func__);
+		return;
+	}
+
+	platdata = &va_priv->swr_plat_data;
+	va_priv->child_count = 0;
+
+	for_each_available_child_of_node(va_priv->dev->of_node, node) {
+		va_swr_master_node = false;
+		if (strnstr(node->name, "va_swr_master",
+                                strlen("va_swr_master")) != NULL)
+			va_swr_master_node = true;
+
+		if (va_swr_master_node)
+			strlcpy(plat_dev_name, "va_swr_ctrl",
+				(LPASS_CDC_VA_MACRO_SWR_STRING_LEN - 1));
+		else
+			strlcpy(plat_dev_name, node->name,
+				(LPASS_CDC_VA_MACRO_SWR_STRING_LEN - 1));
+
+		pdev = platform_device_alloc(plat_dev_name, -1);
+		if (!pdev) {
+			dev_err(va_priv->dev, "%s: pdev memory alloc failed\n",
+				__func__);
+			ret = -ENOMEM;
+			goto err;
+		}
+		pdev->dev.parent = va_priv->dev;
+		pdev->dev.of_node = node;
+
+		if (va_swr_master_node) {
+			ret = platform_device_add_data(pdev, platdata,
+						       sizeof(*platdata));
+			if (ret) {
+				dev_err(&pdev->dev,
+					"%s: cannot add plat data ctrl:%d\n",
+					__func__, ctrl_num);
+				goto fail_pdev_add;
+			}
+		}
+
+		ret = platform_device_add(pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"%s: Cannot add platform device\n",
+				__func__);
+			goto fail_pdev_add;
+		}
+
+		if (va_swr_master_node) {
+			temp = krealloc(swr_ctrl_data,
+					(ctrl_num + 1) * sizeof(
+					struct lpass_cdc_va_macro_swr_ctrl_data),
+					GFP_KERNEL);
+			if (!temp) {
+				ret = -ENOMEM;
+				goto fail_pdev_add;
+			}
+			swr_ctrl_data = temp;
+			swr_ctrl_data[ctrl_num].va_swr_pdev = pdev;
+			ctrl_num++;
+			dev_dbg(&pdev->dev,
+				"%s: Added soundwire ctrl device(s)\n",
+				__func__);
+			va_priv->swr_ctrl_data = swr_ctrl_data;
+		}
+		if (va_priv->child_count < LPASS_CDC_VA_MACRO_CHILD_DEVICES_MAX)
+			va_priv->pdev_child_devices[
+					va_priv->child_count++] = pdev;
+		else
+			goto err;
+	}
+	return;
+fail_pdev_add:
+	for (count = 0; count < va_priv->child_count; count++)
+		platform_device_put(va_priv->pdev_child_devices[count]);
+err:
+	return;
+}
+
+static int lpass_cdc_va_macro_set_port_map(struct snd_soc_component *component,
+				u32 usecase, u32 size, void *data)
+{
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+	struct swrm_port_config port_cfg;
+	int ret = 0;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev, &va_priv, __func__))
+		return -EINVAL;
+
+	memset(&port_cfg, 0, sizeof(port_cfg));
+	port_cfg.uc = usecase;
+	port_cfg.size = size;
+	port_cfg.params = data;
+
+	if (va_priv->swr_ctrl_data)
+		ret = swrm_wcd_notify(
+			va_priv->swr_ctrl_data[0].va_swr_pdev,
+			SWR_SET_PORT_MAP, &port_cfg);
+
+	return ret;
+}
+
+static int lpass_cdc_va_macro_reg_wake_irq(struct snd_soc_component *component,
+				 u32 data)
+{
+	struct device *va_dev = NULL;
+	struct lpass_cdc_va_macro_priv *va_priv = NULL;
+	u32 ipc_wakeup = data;
+	int ret = 0;
+
+	if (!lpass_cdc_va_macro_get_data(component, &va_dev,
+					&va_priv, __func__))
+		return -EINVAL;
+
+	if (va_priv->swr_ctrl_data)
+		ret = swrm_wcd_notify(
+			va_priv->swr_ctrl_data[0].va_swr_pdev,
+			SWR_REGISTER_WAKE_IRQ, &ipc_wakeup);
+
+	return ret;
+}
+
+static void lpass_cdc_va_macro_init_ops(struct macro_ops *ops,
+			      char __iomem *va_io_base,
+			      bool va_without_decimation)
+{
+	memset(ops, 0, sizeof(struct macro_ops));
+	if (!va_without_decimation) {
+		ops->dai_ptr = lpass_cdc_va_macro_dai;
+		ops->num_dais = ARRAY_SIZE(lpass_cdc_va_macro_dai);
+	} else {
+		ops->dai_ptr = NULL;
+		ops->num_dais = 0;
+	}
+	ops->init = lpass_cdc_va_macro_init;
+	ops->exit = lpass_cdc_va_macro_deinit;
+	ops->io_base = va_io_base;
+	ops->event_handler = lpass_cdc_va_macro_event_handler;
+	ops->set_port_map = lpass_cdc_va_macro_set_port_map;
+	ops->reg_wake_irq = lpass_cdc_va_macro_reg_wake_irq;
+	ops->clk_div_get = lpass_cdc_va_macro_clk_div_get;
+}
+
+static int lpass_cdc_va_macro_probe(struct platform_device *pdev)
+{
+	struct macro_ops ops;
+	struct lpass_cdc_va_macro_priv *va_priv;
+	u32 va_base_addr, sample_rate = 0;
+	char __iomem *va_io_base;
+	bool va_without_decimation = false;
+	const char *micb_supply_str = "va-vdd-micb-supply";
+	const char *micb_supply_str1 = "va-vdd-micb";
+	const char *micb_voltage_str = "qcom,va-vdd-micb-voltage";
+	const char *micb_current_str = "qcom,va-vdd-micb-current";
+	int ret = 0;
+	const char *dmic_sample_rate = "qcom,va-dmic-sample-rate";
+	u32 default_clk_id = 0;
+	struct clk *lpass_audio_hw_vote = NULL;
+	u32 is_used_va_swr_gpio = 0;
+	u32 disable_afe_wakeup_event_listener = 0;
+	const char *is_used_va_swr_gpio_dt = "qcom,is-used-swr-gpio";
+	const char *disable_afe_wakeup_event_listener_dt =
+			"qcom,disable-afe-wakeup-event-listener";
+
+	va_priv = devm_kzalloc(&pdev->dev, sizeof(struct lpass_cdc_va_macro_priv),
+			    GFP_KERNEL);
+	if (!va_priv)
+		return -ENOMEM;
+
+	va_priv->dev = &pdev->dev;
+	ret = of_property_read_u32(pdev->dev.of_node, "reg",
+				   &va_base_addr);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
+			__func__, "reg");
+		return ret;
+	}
+	va_without_decimation = of_property_read_bool(pdev->dev.parent->of_node,
+					"qcom,va-without-decimation");
+
+	va_priv->va_without_decimation = va_without_decimation;
+	ret = of_property_read_u32(pdev->dev.of_node, dmic_sample_rate,
+				   &sample_rate);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: could not find %d entry in dt\n",
+			__func__, sample_rate);
+		va_priv->dmic_clk_div = LPASS_CDC_VA_MACRO_CLK_DIV_2;
+	} else {
+		if (lpass_cdc_va_macro_validate_dmic_sample_rate(
+		sample_rate, va_priv) ==
+			LPASS_CDC_VA_MACRO_DMIC_SAMPLE_RATE_UNDEFINED)
+			return -EINVAL;
+	}
+
+	if (of_find_property(pdev->dev.of_node, is_used_va_swr_gpio_dt,
+			     NULL)) {
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   is_used_va_swr_gpio_dt,
+					   &is_used_va_swr_gpio);
+		if (ret) {
+			dev_err(&pdev->dev, "%s: error reading %s in dt\n",
+				__func__, is_used_va_swr_gpio_dt);
+			is_used_va_swr_gpio = 0;
+		}
+	}
+
+	if (of_find_property(pdev->dev.of_node,
+			     disable_afe_wakeup_event_listener_dt, NULL)) {
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   disable_afe_wakeup_event_listener_dt,
+					   &disable_afe_wakeup_event_listener);
+		if (ret)
+			dev_dbg(&pdev->dev, "%s: error reading %s in dt\n",
+				__func__, disable_afe_wakeup_event_listener_dt);
+	}
+	va_priv->disable_afe_wakeup_event_listener =
+			disable_afe_wakeup_event_listener;
+
+	va_priv->va_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
+					"qcom,va-swr-gpios", 0);
+	if (!va_priv->va_swr_gpio_p && is_used_va_swr_gpio) {
+		dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
+			__func__);
+		return -EINVAL;
+	}
+	if ((msm_cdc_pinctrl_get_state(va_priv->va_swr_gpio_p) < 0) &&
+		is_used_va_swr_gpio) {
+		dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
+			__func__);
+		return -EPROBE_DEFER;
+	}
+
+	va_io_base = devm_ioremap(&pdev->dev, va_base_addr,
+				  LPASS_CDC_VA_MACRO_MAX_OFFSET);
+	if (!va_io_base) {
+		dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
+		return -EINVAL;
+	}
+	va_priv->va_io_base = va_io_base;
+
+	lpass_audio_hw_vote = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote");
+	if (IS_ERR(lpass_audio_hw_vote)) {
+		ret = PTR_ERR(lpass_audio_hw_vote);
+		dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n",
+			__func__, "lpass_audio_hw_vote", ret);
+		lpass_audio_hw_vote = NULL;
+		ret = 0;
+	}
+	va_priv->lpass_audio_hw_vote = lpass_audio_hw_vote;
+
+	if (of_parse_phandle(pdev->dev.of_node, micb_supply_str, 0)) {
+		va_priv->micb_supply = devm_regulator_get(&pdev->dev,
+						micb_supply_str1);
+		if (IS_ERR(va_priv->micb_supply)) {
+			ret = PTR_ERR(va_priv->micb_supply);
+			dev_err(&pdev->dev,
+				"%s:Failed to get micbias supply for VA Mic %d\n",
+				__func__, ret);
+			return ret;
+		}
+		ret = of_property_read_u32(pdev->dev.of_node,
+					micb_voltage_str,
+					&va_priv->micb_voltage);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"%s:Looking up %s property in node %s failed\n",
+				__func__, micb_voltage_str,
+				pdev->dev.of_node->full_name);
+			return ret;
+		}
+		ret = of_property_read_u32(pdev->dev.of_node,
+					micb_current_str,
+					&va_priv->micb_current);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"%s:Looking up %s property in node %s failed\n",
+				__func__, micb_current_str,
+				pdev->dev.of_node->full_name);
+			return ret;
+		}
+	}
+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
+				   &default_clk_id);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
+			__func__, "qcom,default-clk-id");
+		default_clk_id = VA_CORE_CLK;
+	}
+	va_priv->clk_id = VA_CORE_CLK;
+	va_priv->default_clk_id = default_clk_id;
+
+	if (is_used_va_swr_gpio) {
+		va_priv->reset_swr = true;
+		INIT_WORK(&va_priv->lpass_cdc_va_macro_add_child_devices_work,
+			  lpass_cdc_va_macro_add_child_devices);
+		va_priv->swr_plat_data.handle = (void *) va_priv;
+		va_priv->swr_plat_data.read = NULL;
+		va_priv->swr_plat_data.write = NULL;
+		va_priv->swr_plat_data.bulk_write = NULL;
+		va_priv->swr_plat_data.clk = lpass_cdc_va_macro_swrm_clock;
+		va_priv->swr_plat_data.core_vote = lpass_cdc_va_macro_core_vote;
+		va_priv->swr_plat_data.handle_irq = NULL;
+		mutex_init(&va_priv->swr_clk_lock);
+	}
+	va_priv->is_used_va_swr_gpio = is_used_va_swr_gpio;
+
+	mutex_init(&va_priv->mclk_lock);
+	dev_set_drvdata(&pdev->dev, va_priv);
+	lpass_cdc_va_macro_init_ops(&ops, va_io_base, va_without_decimation);
+	ops.clk_id_req = va_priv->default_clk_id;
+	ops.default_clk_id = va_priv->default_clk_id;
+	ret = lpass_cdc_register_macro(&pdev->dev, VA_MACRO, &ops);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
+		goto reg_macro_fail;
+	}
+	if (is_used_va_swr_gpio)
+		schedule_work(&va_priv->lpass_cdc_va_macro_add_child_devices_work);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, VA_AUTO_SUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+	pm_suspend_ignore_children(&pdev->dev, true);
+	pm_runtime_enable(&pdev->dev);
+	return ret;
+
+reg_macro_fail:
+	mutex_destroy(&va_priv->mclk_lock);
+	if (is_used_va_swr_gpio)
+		mutex_destroy(&va_priv->swr_clk_lock);
+	return ret;
+}
+
+static int lpass_cdc_va_macro_remove(struct platform_device *pdev)
+{
+	struct lpass_cdc_va_macro_priv *va_priv;
+	int count = 0;
+
+	va_priv = dev_get_drvdata(&pdev->dev);
+
+	if (!va_priv)
+		return -EINVAL;
+	if (va_priv->is_used_va_swr_gpio) {
+		if (va_priv->swr_ctrl_data)
+			kfree(va_priv->swr_ctrl_data);
+		for (count = 0; count < va_priv->child_count &&
+			count < LPASS_CDC_VA_MACRO_CHILD_DEVICES_MAX; count++)
+			platform_device_unregister(
+				va_priv->pdev_child_devices[count]);
+	}
+
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+	lpass_cdc_unregister_macro(&pdev->dev, VA_MACRO);
+	mutex_destroy(&va_priv->mclk_lock);
+	if (va_priv->is_used_va_swr_gpio)
+		mutex_destroy(&va_priv->swr_clk_lock);
+	return 0;
+}
+
+
+static const struct of_device_id lpass_cdc_va_macro_dt_match[] = {
+	{.compatible = "qcom,lpass-cdc-va-macro"},
+	{}
+};
+
+static const struct dev_pm_ops lpass_cdc_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(
+		pm_runtime_force_suspend,
+		pm_runtime_force_resume
+	)
+	SET_RUNTIME_PM_OPS(
+		lpass_cdc_runtime_suspend,
+		lpass_cdc_runtime_resume,
+		NULL
+	)
+};
+
+static struct platform_driver lpass_cdc_va_macro_driver = {
+	.driver = {
+		.name = "lpass_cdc_va_macro",
+		.owner = THIS_MODULE,
+		.pm = &lpass_cdc_dev_pm_ops,
+		.of_match_table = lpass_cdc_va_macro_dt_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = lpass_cdc_va_macro_probe,
+	.remove = lpass_cdc_va_macro_remove,
+};
+
+module_platform_driver(lpass_cdc_va_macro_driver);
+
+MODULE_DESCRIPTION("LPASS codec VA macro driver");
+MODULE_LICENSE("GPL v2");

+ 3323 - 0
asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.c

@@ -0,0 +1,3323 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <soc/swr-common.h>
+#include <soc/swr-wcd.h>
+
+#include <asoc/msm-cdc-pinctrl.h>
+#include "lpass-cdc.h"
+#include "lpass-cdc-registers.h"
+#include "lpass-cdc-wsa-macro.h"
+#include "lpass-cdc-clk-rsc.h"
+
+#define AUTO_SUSPEND_DELAY  50 /* delay in msec */
+#define LPASS_CDC_WSA_MACRO_MAX_OFFSET 0x1000
+
+#define LPASS_CDC_WSA_MACRO_RX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
+			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
+#define LPASS_CDC_WSA_MACRO_RX_MIX_RATES (SNDRV_PCM_RATE_48000 |\
+			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
+#define LPASS_CDC_WSA_MACRO_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+		SNDRV_PCM_FMTBIT_S24_LE |\
+		SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+#define LPASS_CDC_WSA_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+			SNDRV_PCM_RATE_48000)
+#define LPASS_CDC_WSA_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+		SNDRV_PCM_FMTBIT_S24_LE |\
+		SNDRV_PCM_FMTBIT_S24_3LE)
+
+#define NUM_INTERPOLATORS 2
+
+#define LPASS_CDC_WSA_MACRO_MUX_INP_SHFT 0x3
+#define LPASS_CDC_WSA_MACRO_MUX_INP_MASK1 0x07
+#define LPASS_CDC_WSA_MACRO_MUX_INP_MASK2 0x38
+#define LPASS_CDC_WSA_MACRO_MUX_CFG_OFFSET 0x8
+#define LPASS_CDC_WSA_MACRO_MUX_CFG1_OFFSET 0x4
+#define LPASS_CDC_WSA_MACRO_RX_COMP_OFFSET 0x40
+#define LPASS_CDC_WSA_MACRO_RX_SOFTCLIP_OFFSET 0x40
+#define LPASS_CDC_WSA_MACRO_RX_PATH_OFFSET 0x80
+#define LPASS_CDC_WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10
+#define LPASS_CDC_WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C
+#define LPASS_CDC_WSA_MACRO_FS_RATE_MASK 0x0F
+#define LPASS_CDC_WSA_MACRO_EC_MIX_TX0_MASK 0x03
+#define LPASS_CDC_WSA_MACRO_EC_MIX_TX1_MASK 0x18
+
+#define LPASS_CDC_WSA_MACRO_MAX_DMA_CH_PER_PORT 0x2
+
+enum {
+	LPASS_CDC_WSA_MACRO_RX0 = 0,
+	LPASS_CDC_WSA_MACRO_RX1,
+	LPASS_CDC_WSA_MACRO_RX_MIX,
+	LPASS_CDC_WSA_MACRO_RX_MIX0 = LPASS_CDC_WSA_MACRO_RX_MIX,
+	LPASS_CDC_WSA_MACRO_RX_MIX1,
+	LPASS_CDC_WSA_MACRO_RX_MAX,
+};
+
+enum {
+	LPASS_CDC_WSA_MACRO_TX0 = 0,
+	LPASS_CDC_WSA_MACRO_TX1,
+	LPASS_CDC_WSA_MACRO_TX_MAX,
+};
+
+enum {
+	LPASS_CDC_WSA_MACRO_EC0_MUX = 0,
+	LPASS_CDC_WSA_MACRO_EC1_MUX,
+	LPASS_CDC_WSA_MACRO_EC_MUX_MAX,
+};
+
+enum {
+	LPASS_CDC_WSA_MACRO_COMP1, /* SPK_L */
+	LPASS_CDC_WSA_MACRO_COMP2, /* SPK_R */
+	LPASS_CDC_WSA_MACRO_COMP_MAX
+};
+
+enum {
+	LPASS_CDC_WSA_MACRO_SOFTCLIP0, /* RX0 */
+	LPASS_CDC_WSA_MACRO_SOFTCLIP1, /* RX1 */
+	LPASS_CDC_WSA_MACRO_SOFTCLIP_MAX
+};
+
+enum {
+	INTn_1_INP_SEL_ZERO = 0,
+	INTn_1_INP_SEL_RX0,
+	INTn_1_INP_SEL_RX1,
+	INTn_1_INP_SEL_RX2,
+	INTn_1_INP_SEL_RX3,
+	INTn_1_INP_SEL_DEC0,
+	INTn_1_INP_SEL_DEC1,
+};
+
+enum {
+	INTn_2_INP_SEL_ZERO = 0,
+	INTn_2_INP_SEL_RX0,
+	INTn_2_INP_SEL_RX1,
+	INTn_2_INP_SEL_RX2,
+	INTn_2_INP_SEL_RX3,
+};
+
+struct interp_sample_rate {
+	int sample_rate;
+	int rate_val;
+};
+
+/*
+ * Structure used to update codec
+ * register defaults after reset
+ */
+struct lpass_cdc_wsa_macro_reg_mask_val {
+	u16 reg;
+	u8 mask;
+	u8 val;
+};
+
+static struct interp_sample_rate int_prim_sample_rate_val[] = {
+	{8000, 0x0},	/* 8K */
+	{16000, 0x1},	/* 16K */
+	{24000, -EINVAL},/* 24K */
+	{32000, 0x3},	/* 32K */
+	{48000, 0x4},	/* 48K */
+	{96000, 0x5},	/* 96K */
+	{192000, 0x6},	/* 192K */
+	{384000, 0x7},	/* 384K */
+	{44100, 0x8}, /* 44.1K */
+};
+
+static struct interp_sample_rate int_mix_sample_rate_val[] = {
+	{48000, 0x4},	/* 48K */
+	{96000, 0x5},	/* 96K */
+	{192000, 0x6},	/* 192K */
+};
+
+#define LPASS_CDC_WSA_MACRO_SWR_STRING_LEN 80
+
+static int lpass_cdc_wsa_macro_hw_params(struct snd_pcm_substream *substream,
+			       struct snd_pcm_hw_params *params,
+			       struct snd_soc_dai *dai);
+static int lpass_cdc_wsa_macro_get_channel_map(struct snd_soc_dai *dai,
+				unsigned int *tx_num, unsigned int *tx_slot,
+				unsigned int *rx_num, unsigned int *rx_slot);
+static int lpass_cdc_wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute);
+/* Hold instance to soundwire platform device */
+struct lpass_cdc_wsa_macro_swr_ctrl_data {
+	struct platform_device *wsa_swr_pdev;
+};
+
+struct lpass_cdc_wsa_macro_swr_ctrl_platform_data {
+	void *handle; /* holds codec private data */
+	int (*read)(void *handle, int reg);
+	int (*write)(void *handle, int reg, int val);
+	int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
+	int (*clk)(void *handle, bool enable);
+	int (*core_vote)(void *handle, bool enable);
+	int (*handle_irq)(void *handle,
+			  irqreturn_t (*swrm_irq_handler)(int irq,
+							  void *data),
+			  void *swrm_handle,
+			  int action);
+};
+
+struct lpass_cdc_wsa_macro_bcl_pmic_params {
+	u8 id;
+	u8 sid;
+	u8 ppid;
+};
+
+enum {
+	LPASS_CDC_WSA_MACRO_AIF_INVALID = 0,
+	LPASS_CDC_WSA_MACRO_AIF1_PB,
+	LPASS_CDC_WSA_MACRO_AIF_MIX1_PB,
+	LPASS_CDC_WSA_MACRO_AIF_VI,
+	LPASS_CDC_WSA_MACRO_AIF_ECHO,
+	LPASS_CDC_WSA_MACRO_MAX_DAIS,
+};
+
+#define LPASS_CDC_WSA_MACRO_CHILD_DEVICES_MAX 3
+
+/*
+ * @dev: wsa macro device pointer
+ * @comp_enabled: compander enable mixer value set
+ * @ec_hq: echo HQ enable mixer value set
+ * @prim_int_users: Users of interpolator
+ * @wsa_mclk_users: WSA MCLK users count
+ * @swr_clk_users: SWR clk users count
+ * @vi_feed_value: VI sense mask
+ * @mclk_lock: to lock mclk operations
+ * @swr_clk_lock: to lock swr master clock operations
+ * @swr_ctrl_data: SoundWire data structure
+ * @swr_plat_data: Soundwire platform data
+ * @lpass_cdc_wsa_macro_add_child_devices_work: work for adding child devices
+ * @wsa_swr_gpio_p: used by pinctrl API
+ * @component: codec handle
+ * @rx_0_count: RX0 interpolation users
+ * @rx_1_count: RX1 interpolation users
+ * @active_ch_mask: channel mask for all AIF DAIs
+ * @active_ch_cnt: channel count of all AIF DAIs
+ * @rx_port_value: mixer ctl value of WSA RX MUXes
+ * @wsa_io_base: Base address of WSA macro addr space
+ */
+struct lpass_cdc_wsa_macro_priv {
+	struct device *dev;
+	int comp_enabled[LPASS_CDC_WSA_MACRO_COMP_MAX];
+	int ec_hq[LPASS_CDC_WSA_MACRO_RX1 + 1];
+	u16 prim_int_users[LPASS_CDC_WSA_MACRO_RX1 + 1];
+	u16 wsa_mclk_users;
+	u16 swr_clk_users;
+	bool dapm_mclk_enable;
+	bool reset_swr;
+	unsigned int vi_feed_value;
+	struct mutex mclk_lock;
+	struct mutex swr_clk_lock;
+	struct lpass_cdc_wsa_macro_swr_ctrl_data *swr_ctrl_data;
+	struct lpass_cdc_wsa_macro_swr_ctrl_platform_data swr_plat_data;
+	struct work_struct lpass_cdc_wsa_macro_add_child_devices_work;
+	struct device_node *wsa_swr_gpio_p;
+	struct snd_soc_component *component;
+	int rx_0_count;
+	int rx_1_count;
+	unsigned long active_ch_mask[LPASS_CDC_WSA_MACRO_MAX_DAIS];
+	unsigned long active_ch_cnt[LPASS_CDC_WSA_MACRO_MAX_DAIS];
+	int rx_port_value[LPASS_CDC_WSA_MACRO_RX_MAX];
+	char __iomem *wsa_io_base;
+	struct platform_device *pdev_child_devices
+			[LPASS_CDC_WSA_MACRO_CHILD_DEVICES_MAX];
+	int child_count;
+	int ear_spkr_gain;
+	int spkr_gain_offset;
+	int spkr_mode;
+	int is_softclip_on[LPASS_CDC_WSA_MACRO_SOFTCLIP_MAX];
+	int softclip_clk_users[LPASS_CDC_WSA_MACRO_SOFTCLIP_MAX];
+	struct lpass_cdc_wsa_macro_bcl_pmic_params bcl_pmic_params;
+	char __iomem *mclk_mode_muxsel;
+	u16 default_clk_id;
+	u32 pcm_rate_vi;
+	int wsa_digital_mute_status[LPASS_CDC_WSA_MACRO_RX_MAX];
+};
+
+static int lpass_cdc_wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
+					struct lpass_cdc_wsa_macro_priv *wsa_priv,
+					int event, int gain_reg);
+static struct snd_soc_dai_driver lpass_cdc_wsa_macro_dai[];
+static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
+
+static const char *const rx_text[] = {
+	"ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1"
+};
+
+static const char *const rx_mix_text[] = {
+	"ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1"
+};
+
+static const char *const rx_mix_ec_text[] = {
+	"ZERO", "RX_MIX_TX0", "RX_MIX_TX1"
+};
+
+static const char *const rx_mux_text[] = {
+	"ZERO", "AIF1_PB", "AIF_MIX1_PB"
+};
+
+static const char *const rx_sidetone_mix_text[] = {
+	"ZERO", "SRC0"
+};
+
+static const char * const lpass_cdc_wsa_macro_ear_spkr_pa_gain_text[] = {
+	"G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB",
+	"G_4_DB", "G_5_DB", "G_6_DB"
+};
+
+static const char * const lpass_cdc_wsa_macro_speaker_boost_stage_text[] = {
+	"NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
+};
+
+static const char * const lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_text[] = {
+	"OFF", "ON"
+};
+
+static const struct snd_kcontrol_new wsa_int0_vbat_mix_switch[] = {
+	SOC_DAPM_SINGLE("WSA RX0 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const struct snd_kcontrol_new wsa_int1_vbat_mix_switch[] = {
+	SOC_DAPM_SINGLE("WSA RX1 VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static SOC_ENUM_SINGLE_EXT_DECL(lpass_cdc_wsa_macro_ear_spkr_pa_gain_enum,
+				lpass_cdc_wsa_macro_ear_spkr_pa_gain_text);
+static SOC_ENUM_SINGLE_EXT_DECL(lpass_cdc_wsa_macro_spkr_boost_stage_enum,
+			lpass_cdc_wsa_macro_speaker_boost_stage_text);
+static SOC_ENUM_SINGLE_EXT_DECL(lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_enum,
+			lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_text);
+
+/* RX INT0 */
+static const struct soc_enum rx0_prim_inp0_chain_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
+		0, 7, rx_text);
+
+static const struct soc_enum rx0_prim_inp1_chain_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
+		3, 7, rx_text);
+
+static const struct soc_enum rx0_prim_inp2_chain_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
+		3, 7, rx_text);
+
+static const struct soc_enum rx0_mix_chain_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
+		0, 5, rx_mix_text);
+
+static const struct soc_enum rx0_sidetone_mix_enum =
+	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text);
+
+static const struct snd_kcontrol_new rx0_prim_inp0_mux =
+	SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum);
+
+static const struct snd_kcontrol_new rx0_prim_inp1_mux =
+	SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx0_prim_inp2_mux =
+	SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx0_mix_mux =
+	SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum);
+
+static const struct snd_kcontrol_new rx0_sidetone_mix_mux =
+	SOC_DAPM_ENUM("WSA_RX0 SIDETONE MIX Mux", rx0_sidetone_mix_enum);
+
+/* RX INT1 */
+static const struct soc_enum rx1_prim_inp0_chain_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
+		0, 7, rx_text);
+
+static const struct soc_enum rx1_prim_inp1_chain_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
+		3, 7, rx_text);
+
+static const struct soc_enum rx1_prim_inp2_chain_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
+		3, 7, rx_text);
+
+static const struct soc_enum rx1_mix_chain_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
+		0, 5, rx_mix_text);
+
+static const struct snd_kcontrol_new rx1_prim_inp0_mux =
+	SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum);
+
+static const struct snd_kcontrol_new rx1_prim_inp1_mux =
+	SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum);
+
+static const struct snd_kcontrol_new rx1_prim_inp2_mux =
+	SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum);
+
+static const struct snd_kcontrol_new rx1_mix_mux =
+	SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum);
+
+static const struct soc_enum rx_mix_ec0_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
+		0, 3, rx_mix_ec_text);
+
+static const struct soc_enum rx_mix_ec1_enum =
+	SOC_ENUM_SINGLE(LPASS_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
+		3, 3, rx_mix_ec_text);
+
+static const struct snd_kcontrol_new rx_mix_ec0_mux =
+	SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum);
+
+static const struct snd_kcontrol_new rx_mix_ec1_mux =
+	SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum);
+
+static struct snd_soc_dai_ops lpass_cdc_wsa_macro_dai_ops = {
+	.hw_params = lpass_cdc_wsa_macro_hw_params,
+	.get_channel_map = lpass_cdc_wsa_macro_get_channel_map,
+	.digital_mute = lpass_cdc_wsa_macro_digital_mute,
+};
+
+static struct snd_soc_dai_driver lpass_cdc_wsa_macro_dai[] = {
+	{
+		.name = "lpass_cdc_wsa_macro_rx1",
+		.id = LPASS_CDC_WSA_MACRO_AIF1_PB,
+		.playback = {
+			.stream_name = "WSA_AIF1 Playback",
+			.rates = LPASS_CDC_WSA_MACRO_RX_RATES,
+			.formats = LPASS_CDC_WSA_MACRO_RX_FORMATS,
+			.rate_max = 384000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+		.ops = &lpass_cdc_wsa_macro_dai_ops,
+	},
+	{
+		.name = "lpass_cdc_wsa_macro_rx_mix",
+		.id = LPASS_CDC_WSA_MACRO_AIF_MIX1_PB,
+		.playback = {
+			.stream_name = "WSA_AIF_MIX1 Playback",
+			.rates = LPASS_CDC_WSA_MACRO_RX_MIX_RATES,
+			.formats = LPASS_CDC_WSA_MACRO_RX_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 48000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+		.ops = &lpass_cdc_wsa_macro_dai_ops,
+	},
+	{
+		.name = "lpass_cdc_wsa_macro_vifeedback",
+		.id = LPASS_CDC_WSA_MACRO_AIF_VI,
+		.capture = {
+			.stream_name = "WSA_AIF_VI Capture",
+			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
+			.formats = LPASS_CDC_WSA_MACRO_RX_FORMATS,
+			.rate_max = 48000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &lpass_cdc_wsa_macro_dai_ops,
+	},
+	{
+		.name = "lpass_cdc_wsa_macro_echo",
+		.id = LPASS_CDC_WSA_MACRO_AIF_ECHO,
+		.capture = {
+			.stream_name = "WSA_AIF_ECHO Capture",
+			.rates = LPASS_CDC_WSA_MACRO_ECHO_RATES,
+			.formats = LPASS_CDC_WSA_MACRO_ECHO_FORMATS,
+			.rate_max = 48000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+		.ops = &lpass_cdc_wsa_macro_dai_ops,
+	},
+};
+
+static const struct lpass_cdc_wsa_macro_reg_mask_val
+				lpass_cdc_wsa_macro_spkr_default[] = {
+	{LPASS_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80},
+	{LPASS_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80},
+	{LPASS_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
+	{LPASS_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
+	{LPASS_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58},
+	{LPASS_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58},
+};
+
+static const struct lpass_cdc_wsa_macro_reg_mask_val
+				lpass_cdc_wsa_macro_spkr_mode1[] = {
+	{LPASS_CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00},
+	{LPASS_CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00},
+	{LPASS_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00},
+	{LPASS_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00},
+	{LPASS_CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44},
+	{LPASS_CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44},
+};
+
+static bool lpass_cdc_wsa_macro_get_data(struct snd_soc_component *component,
+			       struct device **wsa_dev,
+			       struct lpass_cdc_wsa_macro_priv **wsa_priv,
+			       const char *func_name)
+{
+	*wsa_dev = lpass_cdc_get_device_ptr(component->dev,
+							WSA_MACRO);
+	if (!(*wsa_dev)) {
+		dev_err(component->dev,
+			"%s: null device for macro!\n", func_name);
+		return false;
+	}
+	*wsa_priv = dev_get_drvdata((*wsa_dev));
+	if (!(*wsa_priv) || !(*wsa_priv)->component) {
+		dev_err(component->dev,
+			"%s: priv is null for macro!\n", func_name);
+		return false;
+	}
+	return true;
+}
+
+static int lpass_cdc_wsa_macro_set_port_map(struct snd_soc_component *component,
+				u32 usecase, u32 size, void *data)
+{
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	struct swrm_port_config port_cfg;
+	int ret = 0;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	memset(&port_cfg, 0, sizeof(port_cfg));
+	port_cfg.uc = usecase;
+	port_cfg.size = size;
+	port_cfg.params = data;
+
+	if (wsa_priv->swr_ctrl_data)
+		ret = swrm_wcd_notify(
+			wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+			SWR_SET_PORT_MAP, &port_cfg);
+
+	return ret;
+}
+
+/**
+ * lpass_cdc_wsa_macro_set_spkr_gain_offset - offset the speaker path
+ * gain with the given offset value.
+ *
+ * @component: codec instance
+ * @offset: Indicates speaker path gain offset value.
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int lpass_cdc_wsa_macro_set_spkr_gain_offset(struct snd_soc_component *component,
+				   int offset)
+{
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!component) {
+		pr_err("%s: NULL component pointer!\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	wsa_priv->spkr_gain_offset = offset;
+	return 0;
+}
+EXPORT_SYMBOL(lpass_cdc_wsa_macro_set_spkr_gain_offset);
+
+/**
+ * lpass_cdc_wsa_macro_set_spkr_mode - Configures speaker compander and smartboost
+ * settings based on speaker mode.
+ *
+ * @component: codec instance
+ * @mode: Indicates speaker configuration mode.
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int lpass_cdc_wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode)
+{
+	int i;
+	const struct lpass_cdc_wsa_macro_reg_mask_val *regs;
+	int size;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!component) {
+		pr_err("%s: NULL codec pointer!\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	switch (mode) {
+	case LPASS_CDC_WSA_MACRO_SPKR_MODE_1:
+		regs = lpass_cdc_wsa_macro_spkr_mode1;
+		size = ARRAY_SIZE(lpass_cdc_wsa_macro_spkr_mode1);
+		break;
+	default:
+		regs = lpass_cdc_wsa_macro_spkr_default;
+		size = ARRAY_SIZE(lpass_cdc_wsa_macro_spkr_default);
+		break;
+	}
+
+	wsa_priv->spkr_mode = mode;
+	for (i = 0; i < size; i++)
+		snd_soc_component_update_bits(component, regs[i].reg,
+				    regs[i].mask, regs[i].val);
+	return 0;
+}
+EXPORT_SYMBOL(lpass_cdc_wsa_macro_set_spkr_mode);
+
+static int lpass_cdc_wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
+					    u8 int_prim_fs_rate_reg_val,
+					    u32 sample_rate)
+{
+	u8 int_1_mix1_inp;
+	u32 j, port;
+	u16 int_mux_cfg0, int_mux_cfg1;
+	u16 int_fs_reg;
+	u8 int_mux_cfg0_val, int_mux_cfg1_val;
+	u8 inp0_sel, inp1_sel, inp2_sel;
+	struct snd_soc_component *component = dai->component;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
+			 LPASS_CDC_WSA_MACRO_RX_MAX) {
+		int_1_mix1_inp = port;
+		if ((int_1_mix1_inp < LPASS_CDC_WSA_MACRO_RX0) ||
+			(int_1_mix1_inp > LPASS_CDC_WSA_MACRO_RX_MIX1)) {
+			dev_err(wsa_dev,
+				"%s: Invalid RX port, Dai ID is %d\n",
+				__func__, dai->id);
+			return -EINVAL;
+		}
+
+		int_mux_cfg0 = LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0;
+
+		/*
+		 * Loop through all interpolator MUX inputs and find out
+		 * to which interpolator input, the cdc_dma rx port
+		 * is connected
+		 */
+		for (j = 0; j < NUM_INTERPOLATORS; j++) {
+			int_mux_cfg1 = int_mux_cfg0 + LPASS_CDC_WSA_MACRO_MUX_CFG1_OFFSET;
+
+			int_mux_cfg0_val = snd_soc_component_read32(component,
+							int_mux_cfg0);
+			int_mux_cfg1_val = snd_soc_component_read32(component,
+							int_mux_cfg1);
+			inp0_sel = int_mux_cfg0_val & LPASS_CDC_WSA_MACRO_MUX_INP_MASK1;
+			inp1_sel = (int_mux_cfg0_val >>
+					LPASS_CDC_WSA_MACRO_MUX_INP_SHFT) &
+					LPASS_CDC_WSA_MACRO_MUX_INP_MASK1;
+			inp2_sel = (int_mux_cfg1_val >>
+					LPASS_CDC_WSA_MACRO_MUX_INP_SHFT) &
+					LPASS_CDC_WSA_MACRO_MUX_INP_MASK1;
+			if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
+			    (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
+			    (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) {
+				int_fs_reg = LPASS_CDC_WSA_RX0_RX_PATH_CTL +
+					     LPASS_CDC_WSA_MACRO_RX_PATH_OFFSET * j;
+				dev_dbg(wsa_dev,
+					"%s: AIF_PB DAI(%d) connected to INT%u_1\n",
+					__func__, dai->id, j);
+				dev_dbg(wsa_dev,
+					"%s: set INT%u_1 sample rate to %u\n",
+					__func__, j, sample_rate);
+				/* sample_rate is in Hz */
+				snd_soc_component_update_bits(component,
+						int_fs_reg,
+						LPASS_CDC_WSA_MACRO_FS_RATE_MASK,
+						int_prim_fs_rate_reg_val);
+			}
+			int_mux_cfg0 += LPASS_CDC_WSA_MACRO_MUX_CFG_OFFSET;
+		}
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
+					u8 int_mix_fs_rate_reg_val,
+					u32 sample_rate)
+{
+	u8 int_2_inp;
+	u32 j, port;
+	u16 int_mux_cfg1, int_fs_reg;
+	u8 int_mux_cfg1_val;
+	struct snd_soc_component *component = dai->component;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+
+	for_each_set_bit(port, &wsa_priv->active_ch_mask[dai->id],
+			 LPASS_CDC_WSA_MACRO_RX_MAX) {
+		int_2_inp = port;
+		if ((int_2_inp < LPASS_CDC_WSA_MACRO_RX0) ||
+			(int_2_inp > LPASS_CDC_WSA_MACRO_RX_MIX1)) {
+			dev_err(wsa_dev,
+				"%s: Invalid RX port, Dai ID is %d\n",
+				__func__, dai->id);
+			return -EINVAL;
+		}
+
+		int_mux_cfg1 = LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;
+		for (j = 0; j < NUM_INTERPOLATORS; j++) {
+			int_mux_cfg1_val = snd_soc_component_read32(component,
+							int_mux_cfg1) &
+							LPASS_CDC_WSA_MACRO_MUX_INP_MASK1;
+			if (int_mux_cfg1_val == int_2_inp +
+							INTn_2_INP_SEL_RX0) {
+				int_fs_reg =
+					LPASS_CDC_WSA_RX0_RX_PATH_MIX_CTL +
+					LPASS_CDC_WSA_MACRO_RX_PATH_OFFSET * j;
+
+				dev_dbg(wsa_dev,
+					"%s: AIF_PB DAI(%d) connected to INT%u_2\n",
+					__func__, dai->id, j);
+				dev_dbg(wsa_dev,
+					"%s: set INT%u_2 sample rate to %u\n",
+					__func__, j, sample_rate);
+				snd_soc_component_update_bits(component,
+						int_fs_reg,
+						LPASS_CDC_WSA_MACRO_FS_RATE_MASK,
+						int_mix_fs_rate_reg_val);
+			}
+			int_mux_cfg1 += LPASS_CDC_WSA_MACRO_MUX_CFG_OFFSET;
+		}
+	}
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai,
+				       u32 sample_rate)
+{
+	int rate_val = 0;
+	int i, ret;
+
+	/* set mixing path rate */
+	for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
+		if (sample_rate ==
+				int_mix_sample_rate_val[i].sample_rate) {
+			rate_val =
+				int_mix_sample_rate_val[i].rate_val;
+			break;
+		}
+	}
+	if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) ||
+			(rate_val < 0))
+		goto prim_rate;
+	ret = lpass_cdc_wsa_macro_set_mix_interpolator_rate(dai,
+			(u8) rate_val, sample_rate);
+prim_rate:
+	/* set primary path sample rate */
+	for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
+		if (sample_rate ==
+				int_prim_sample_rate_val[i].sample_rate) {
+			rate_val =
+				int_prim_sample_rate_val[i].rate_val;
+			break;
+		}
+	}
+	if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) ||
+			(rate_val < 0))
+		return -EINVAL;
+	ret = lpass_cdc_wsa_macro_set_prim_interpolator_rate(dai,
+			(u8) rate_val, sample_rate);
+	return ret;
+}
+
+static int lpass_cdc_wsa_macro_hw_params(struct snd_pcm_substream *substream,
+			       struct snd_pcm_hw_params *params,
+			       struct snd_soc_dai *dai)
+{
+	struct snd_soc_component *component = dai->component;
+	int ret;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	wsa_priv = dev_get_drvdata(wsa_dev);
+	if (!wsa_priv)
+		return -EINVAL;
+
+	dev_dbg(component->dev,
+		"%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
+		 dai->name, dai->id, params_rate(params),
+		 params_channels(params));
+
+	switch (substream->stream) {
+	case SNDRV_PCM_STREAM_PLAYBACK:
+		ret = lpass_cdc_wsa_macro_set_interpolator_rate(dai, params_rate(params));
+		if (ret) {
+			dev_err(component->dev,
+				"%s: cannot set sample rate: %u\n",
+				__func__, params_rate(params));
+			return ret;
+		}
+		break;
+	case SNDRV_PCM_STREAM_CAPTURE:
+		if (dai->id == LPASS_CDC_WSA_MACRO_AIF_VI)
+			wsa_priv->pcm_rate_vi = params_rate(params);
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_get_channel_map(struct snd_soc_dai *dai,
+				unsigned int *tx_num, unsigned int *tx_slot,
+				unsigned int *rx_num, unsigned int *rx_slot)
+{
+	struct snd_soc_component *component = dai->component;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	u16 val = 0, mask = 0, cnt = 0, temp = 0;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	wsa_priv = dev_get_drvdata(wsa_dev);
+	if (!wsa_priv)
+		return -EINVAL;
+
+	switch (dai->id) {
+	case LPASS_CDC_WSA_MACRO_AIF_VI:
+		*tx_slot = wsa_priv->active_ch_mask[dai->id];
+		*tx_num = wsa_priv->active_ch_cnt[dai->id];
+		break;
+	case LPASS_CDC_WSA_MACRO_AIF1_PB:
+	case LPASS_CDC_WSA_MACRO_AIF_MIX1_PB:
+		for_each_set_bit(temp, &wsa_priv->active_ch_mask[dai->id],
+					LPASS_CDC_WSA_MACRO_RX_MAX) {
+			mask |= (1 << temp);
+			if (++cnt == LPASS_CDC_WSA_MACRO_MAX_DMA_CH_PER_PORT)
+				break;
+		}
+		if (mask & 0x0C)
+			mask = mask >> 0x2;
+		*rx_slot = mask;
+		*rx_num = cnt;
+		break;
+	case LPASS_CDC_WSA_MACRO_AIF_ECHO:
+		val = snd_soc_component_read32(component,
+			LPASS_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
+		if (val & LPASS_CDC_WSA_MACRO_EC_MIX_TX1_MASK) {
+			mask |= 0x2;
+			cnt++;
+		}
+		if (val & LPASS_CDC_WSA_MACRO_EC_MIX_TX0_MASK) {
+			mask |= 0x1;
+			cnt++;
+		}
+		*tx_slot = mask;
+		*tx_num = cnt;
+		break;
+	default:
+		dev_err(wsa_dev, "%s: Invalid AIF\n", __func__);
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_component *component = dai->component;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	uint16_t j = 0, reg = 0, mix_reg = 0, dsm_reg = 0;
+	u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
+	u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
+	bool adie_lb = false;
+
+	if (mute)
+		return 0;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	switch (dai->id) {
+	case LPASS_CDC_WSA_MACRO_AIF1_PB:
+	case LPASS_CDC_WSA_MACRO_AIF_MIX1_PB:
+	for (j = 0; j < NUM_INTERPOLATORS; j++) {
+		reg = LPASS_CDC_WSA_RX0_RX_PATH_CTL +
+				(j * LPASS_CDC_WSA_MACRO_RX_PATH_OFFSET);
+		mix_reg = LPASS_CDC_WSA_RX0_RX_PATH_MIX_CTL +
+				(j * LPASS_CDC_WSA_MACRO_RX_PATH_OFFSET);
+		dsm_reg = LPASS_CDC_WSA_RX0_RX_PATH_CTL +
+				(j * LPASS_CDC_WSA_MACRO_RX_PATH_OFFSET) +
+				LPASS_CDC_WSA_MACRO_RX_PATH_DSMDEM_OFFSET;
+		int_mux_cfg0 = LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + j * 8;
+		int_mux_cfg1 = int_mux_cfg0 + 4;
+		int_mux_cfg0_val = snd_soc_component_read32(component,
+							int_mux_cfg0);
+		int_mux_cfg1_val = snd_soc_component_read32(component,
+							int_mux_cfg1);
+		if (snd_soc_component_read32(component, dsm_reg) & 0x01) {
+			if (int_mux_cfg0_val || (int_mux_cfg1_val & 0x38))
+				snd_soc_component_update_bits(component, reg,
+							0x20, 0x20);
+			if (int_mux_cfg1_val & 0x07) {
+				snd_soc_component_update_bits(component, reg,
+							0x20, 0x20);
+				snd_soc_component_update_bits(component,
+						mix_reg, 0x20, 0x20);
+			}
+		}
+	}
+	lpass_cdc_wsa_pa_on(wsa_dev, adie_lb);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+static int lpass_cdc_wsa_macro_mclk_enable(
+				struct lpass_cdc_wsa_macro_priv *wsa_priv,
+				 bool mclk_enable, bool dapm)
+{
+	struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
+	int ret = 0;
+
+	if (regmap == NULL) {
+		dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	dev_dbg(wsa_priv->dev, "%s: mclk_enable = %u, dapm = %d clk_users= %d\n",
+		__func__, mclk_enable, dapm, wsa_priv->wsa_mclk_users);
+
+	mutex_lock(&wsa_priv->mclk_lock);
+	if (mclk_enable) {
+		if (wsa_priv->wsa_mclk_users == 0) {
+			ret = lpass_cdc_clk_rsc_request_clock(wsa_priv->dev,
+							wsa_priv->default_clk_id,
+							wsa_priv->default_clk_id,
+							true);
+			if (ret < 0) {
+				dev_err_ratelimited(wsa_priv->dev,
+					"%s: wsa request clock enable failed\n",
+					__func__);
+				goto exit;
+			}
+			lpass_cdc_clk_rsc_fs_gen_request(wsa_priv->dev,
+						  true);
+			regcache_mark_dirty(regmap);
+			regcache_sync_region(regmap,
+					WSA_START_OFFSET,
+					WSA_MAX_OFFSET);
+			/* 9.6MHz MCLK, set value 0x00 if other frequency */
+			regmap_update_bits(regmap,
+				LPASS_CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01);
+			regmap_update_bits(regmap,
+				LPASS_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
+				0x01, 0x01);
+			regmap_update_bits(regmap,
+				LPASS_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
+				0x01, 0x01);
+		}
+		wsa_priv->wsa_mclk_users++;
+	} else {
+		if (wsa_priv->wsa_mclk_users <= 0) {
+			dev_err(wsa_priv->dev, "%s: clock already disabled\n",
+			__func__);
+			wsa_priv->wsa_mclk_users = 0;
+			goto exit;
+		}
+		wsa_priv->wsa_mclk_users--;
+		if (wsa_priv->wsa_mclk_users == 0) {
+			regmap_update_bits(regmap,
+				LPASS_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
+				0x01, 0x00);
+			regmap_update_bits(regmap,
+				LPASS_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
+				0x01, 0x00);
+			lpass_cdc_clk_rsc_fs_gen_request(wsa_priv->dev,
+						  false);
+
+			lpass_cdc_clk_rsc_request_clock(wsa_priv->dev,
+						  wsa_priv->default_clk_id,
+						  wsa_priv->default_clk_id,
+						  false);
+		}
+	}
+exit:
+	mutex_unlock(&wsa_priv->mclk_lock);
+	return ret;
+}
+
+static int lpass_cdc_wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	int ret = 0;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(wsa_dev, "%s: event = %d\n", __func__, event);
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		ret = lpass_cdc_wsa_macro_mclk_enable(wsa_priv, 1, true);
+		if (ret)
+			wsa_priv->dapm_mclk_enable = false;
+		else
+			wsa_priv->dapm_mclk_enable = true;
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (wsa_priv->dapm_mclk_enable)
+			lpass_cdc_wsa_macro_mclk_enable(wsa_priv, 0, true);
+		break;
+	default:
+		dev_err(wsa_priv->dev,
+			"%s: invalid DAPM event %d\n", __func__, event);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static int lpass_cdc_wsa_macro_event_handler(struct snd_soc_component *component,
+				   u16 event, u32 data)
+{
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	int ret = 0;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	switch (event) {
+	case LPASS_CDC_MACRO_EVT_SSR_DOWN:
+		trace_printk("%s, enter SSR down\n", __func__);
+		if (wsa_priv->swr_ctrl_data) {
+			swrm_wcd_notify(
+				wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+				SWR_DEVICE_SSR_DOWN, NULL);
+		}
+		if ((!pm_runtime_enabled(wsa_dev) ||
+		     !pm_runtime_suspended(wsa_dev))) {
+			ret = lpass_cdc_runtime_suspend(wsa_dev);
+			if (!ret) {
+				pm_runtime_disable(wsa_dev);
+				pm_runtime_set_suspended(wsa_dev);
+				pm_runtime_enable(wsa_dev);
+			}
+		}
+		break;
+	case LPASS_CDC_MACRO_EVT_PRE_SSR_UP:
+		/* enable&disable WSA_CORE_CLK to reset GFMUX reg */
+		ret = lpass_cdc_clk_rsc_request_clock(wsa_priv->dev,
+						wsa_priv->default_clk_id,
+						WSA_CORE_CLK, true);
+		if (ret < 0)
+			dev_err_ratelimited(wsa_priv->dev,
+				"%s, failed to enable clk, ret:%d\n",
+				__func__, ret);
+		else
+			lpass_cdc_clk_rsc_request_clock(wsa_priv->dev,
+						wsa_priv->default_clk_id,
+						WSA_CORE_CLK, false);
+		break;
+	case LPASS_CDC_MACRO_EVT_SSR_UP:
+		trace_printk("%s, enter SSR up\n", __func__);
+		/* reset swr after ssr/pdr */
+		wsa_priv->reset_swr = true;
+		if (wsa_priv->swr_ctrl_data)
+			swrm_wcd_notify(
+				wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+				SWR_DEVICE_SSR_UP, NULL);
+		break;
+	case LPASS_CDC_MACRO_EVT_CLK_RESET:
+		lpass_cdc_rsc_clk_reset(wsa_dev, WSA_CORE_CLK);
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
+					struct snd_kcontrol *kcontrol,
+					int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	u8 val = 0x0;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	switch (wsa_priv->pcm_rate_vi) {
+		case 48000:
+			val = 0x04;
+			break;
+		case 24000:
+			val = 0x02;
+			break;
+		case 8000:
+		default:
+			val = 0x00;
+			break;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		if (test_bit(LPASS_CDC_WSA_MACRO_TX0,
+			&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI])) {
+			dev_dbg(wsa_dev, "%s: spkr1 enabled\n", __func__);
+			/* Enable V&I sensing */
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
+				0x20, 0x20);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
+				0x20, 0x20);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
+				0x0F, val);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
+				0x0F, val);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
+				0x10, 0x10);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
+				0x10, 0x10);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
+				0x20, 0x00);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
+				0x20, 0x00);
+		}
+		if (test_bit(LPASS_CDC_WSA_MACRO_TX1,
+			&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI])) {
+			dev_dbg(wsa_dev, "%s: spkr2 enabled\n", __func__);
+			/* Enable V&I sensing */
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
+				0x20, 0x20);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
+				0x20, 0x20);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
+				0x0F, val);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
+				0x0F, val);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
+				0x10, 0x10);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
+				0x10, 0x10);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
+				0x20, 0x00);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
+				0x20, 0x00);
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (test_bit(LPASS_CDC_WSA_MACRO_TX0,
+			&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI])) {
+			/* Disable V&I sensing */
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
+				0x20, 0x20);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
+				0x20, 0x20);
+			dev_dbg(wsa_dev, "%s: spkr1 disabled\n", __func__);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CTL,
+				0x10, 0x00);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CTL,
+				0x10, 0x00);
+		}
+		if (test_bit(LPASS_CDC_WSA_MACRO_TX1,
+			&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI])) {
+			/* Disable V&I sensing */
+			dev_dbg(wsa_dev, "%s: spkr2 disabled\n", __func__);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
+				0x20, 0x20);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
+				0x20, 0x20);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CTL,
+				0x10, 0x00);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CTL,
+				0x10, 0x00);
+		}
+		break;
+	}
+
+	return 0;
+}
+
+static void lpass_cdc_wsa_macro_hd2_control(struct snd_soc_component *component,
+				  u16 reg, int event)
+{
+	u16 hd2_scale_reg;
+	u16 hd2_enable_reg = 0;
+
+	if (reg == LPASS_CDC_WSA_RX0_RX_PATH_CTL) {
+		hd2_scale_reg = LPASS_CDC_WSA_RX0_RX_PATH_SEC3;
+		hd2_enable_reg = LPASS_CDC_WSA_RX0_RX_PATH_CFG0;
+	}
+	if (reg == LPASS_CDC_WSA_RX1_RX_PATH_CTL) {
+		hd2_scale_reg = LPASS_CDC_WSA_RX1_RX_PATH_SEC3;
+		hd2_enable_reg = LPASS_CDC_WSA_RX1_RX_PATH_CFG0;
+	}
+
+	if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
+		snd_soc_component_update_bits(component, hd2_scale_reg,
+						0x3C, 0x10);
+		snd_soc_component_update_bits(component, hd2_scale_reg,
+						0x03, 0x01);
+		snd_soc_component_update_bits(component, hd2_enable_reg,
+						0x04, 0x04);
+	}
+
+	if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
+		snd_soc_component_update_bits(component, hd2_enable_reg,
+						0x04, 0x00);
+		snd_soc_component_update_bits(component, hd2_scale_reg,
+						0x03, 0x00);
+		snd_soc_component_update_bits(component, hd2_scale_reg,
+						0x3C, 0x00);
+	}
+}
+
+static int lpass_cdc_wsa_macro_enable_swr(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	int ch_cnt;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
+		    !wsa_priv->rx_0_count)
+			wsa_priv->rx_0_count++;
+		if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
+		    !wsa_priv->rx_1_count)
+			wsa_priv->rx_1_count++;
+		ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
+
+		if (wsa_priv->swr_ctrl_data) {
+			swrm_wcd_notify(
+				wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+				SWR_DEVICE_UP, NULL);
+			swrm_wcd_notify(
+				wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+				SWR_SET_NUM_RX_CH, &ch_cnt);
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (!(strnstr(w->name, "RX0", sizeof("WSA_RX0"))) &&
+		    wsa_priv->rx_0_count)
+			wsa_priv->rx_0_count--;
+		if (!(strnstr(w->name, "RX1", sizeof("WSA_RX1"))) &&
+		    wsa_priv->rx_1_count)
+			wsa_priv->rx_1_count--;
+		ch_cnt = wsa_priv->rx_0_count + wsa_priv->rx_1_count;
+
+		if (wsa_priv->swr_ctrl_data)
+			swrm_wcd_notify(
+				wsa_priv->swr_ctrl_data[0].wsa_swr_pdev,
+				SWR_SET_NUM_RX_CH, &ch_cnt);
+		break;
+	}
+	dev_dbg(wsa_priv->dev, "%s: current swr ch cnt: %d\n",
+		__func__, wsa_priv->rx_0_count + wsa_priv->rx_1_count);
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
+		struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	u16 gain_reg;
+	int offset_val = 0;
+	int val = 0;
+
+	dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
+
+	if (!(strcmp(w->name, "WSA_RX0 MIX INP"))) {
+		gain_reg = LPASS_CDC_WSA_RX0_RX_VOL_MIX_CTL;
+	} else if (!(strcmp(w->name, "WSA_RX1 MIX INP"))) {
+		gain_reg = LPASS_CDC_WSA_RX1_RX_VOL_MIX_CTL;
+	} else {
+		dev_err(component->dev, "%s: No gain register avail for %s\n",
+			__func__, w->name);
+		return 0;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		lpass_cdc_wsa_macro_enable_swr(w, kcontrol, event);
+		val = snd_soc_component_read32(component, gain_reg);
+		val += offset_val;
+		snd_soc_component_write(component, gain_reg, val);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_component_update_bits(component,
+					w->reg, 0x20, 0x00);
+		lpass_cdc_wsa_macro_enable_swr(w, kcontrol, event);
+		break;
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_config_compander(struct snd_soc_component *component,
+				int comp, int event)
+{
+	u16 comp_ctl0_reg, rx_path_cfg0_reg;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(component->dev, "%s: event %d compander %d, enabled %d\n",
+		__func__, event, comp + 1, wsa_priv->comp_enabled[comp]);
+
+	if (!wsa_priv->comp_enabled[comp])
+		return 0;
+
+	comp_ctl0_reg = LPASS_CDC_WSA_COMPANDER0_CTL0 +
+					(comp * LPASS_CDC_WSA_MACRO_RX_COMP_OFFSET);
+	rx_path_cfg0_reg = LPASS_CDC_WSA_RX0_RX_PATH_CFG0 +
+					(comp * LPASS_CDC_WSA_MACRO_RX_PATH_OFFSET);
+
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		/* Enable Compander Clock */
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+						0x01, 0x01);
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+						0x02, 0x02);
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+						0x02, 0x00);
+		snd_soc_component_update_bits(component, rx_path_cfg0_reg,
+						0x02, 0x02);
+	}
+
+	if (SND_SOC_DAPM_EVENT_OFF(event)) {
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+						0x04, 0x04);
+		snd_soc_component_update_bits(component, rx_path_cfg0_reg,
+						0x02, 0x00);
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+						0x02, 0x02);
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+						0x02, 0x00);
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+						0x01, 0x00);
+		snd_soc_component_update_bits(component, comp_ctl0_reg,
+						0x04, 0x00);
+	}
+
+	return 0;
+}
+
+static void lpass_cdc_wsa_macro_enable_softclip_clk(struct snd_soc_component *component,
+					 struct lpass_cdc_wsa_macro_priv *wsa_priv,
+					 int path,
+					 bool enable)
+{
+	u16 softclip_clk_reg = LPASS_CDC_WSA_SOFTCLIP0_CRC +
+			(path * LPASS_CDC_WSA_MACRO_RX_SOFTCLIP_OFFSET);
+	u8 softclip_mux_mask = (1 << path);
+	u8 softclip_mux_value = (1 << path);
+
+	dev_dbg(component->dev, "%s: path %d, enable %d\n",
+		__func__, path, enable);
+	if (enable) {
+		if (wsa_priv->softclip_clk_users[path] == 0) {
+			snd_soc_component_update_bits(component,
+				softclip_clk_reg, 0x01, 0x01);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
+				softclip_mux_mask, softclip_mux_value);
+		}
+		wsa_priv->softclip_clk_users[path]++;
+	} else {
+		wsa_priv->softclip_clk_users[path]--;
+		if (wsa_priv->softclip_clk_users[path] == 0) {
+			snd_soc_component_update_bits(component,
+				softclip_clk_reg, 0x01, 0x00);
+			snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
+				softclip_mux_mask, 0x00);
+		}
+	}
+}
+
+static int lpass_cdc_wsa_macro_config_softclip(struct snd_soc_component *component,
+				int path, int event)
+{
+	u16 softclip_ctrl_reg = 0;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	int softclip_path = 0;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	if (path == LPASS_CDC_WSA_MACRO_COMP1)
+		softclip_path = LPASS_CDC_WSA_MACRO_SOFTCLIP0;
+	else if (path == LPASS_CDC_WSA_MACRO_COMP2)
+		softclip_path = LPASS_CDC_WSA_MACRO_SOFTCLIP1;
+
+	dev_dbg(component->dev, "%s: event %d path %d, enabled %d\n",
+		__func__, event, softclip_path,
+		wsa_priv->is_softclip_on[softclip_path]);
+
+	if (!wsa_priv->is_softclip_on[softclip_path])
+		return 0;
+
+	softclip_ctrl_reg = LPASS_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +
+				(softclip_path * LPASS_CDC_WSA_MACRO_RX_SOFTCLIP_OFFSET);
+
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		/* Enable Softclip clock and mux */
+		lpass_cdc_wsa_macro_enable_softclip_clk(component, wsa_priv,
+				softclip_path, true);
+		/* Enable Softclip control */
+		snd_soc_component_update_bits(component, softclip_ctrl_reg,
+				0x01, 0x01);
+	}
+
+	if (SND_SOC_DAPM_EVENT_OFF(event)) {
+		snd_soc_component_update_bits(component, softclip_ctrl_reg,
+				0x01, 0x00);
+		lpass_cdc_wsa_macro_enable_softclip_clk(component, wsa_priv,
+				softclip_path, false);
+	}
+
+	return 0;
+}
+
+static bool lpass_cdc_wsa_macro_adie_lb(struct snd_soc_component *component,
+			      int interp_idx)
+{
+	u16 int_mux_cfg0 = 0, int_mux_cfg1 = 0;
+	u8 int_mux_cfg0_val = 0, int_mux_cfg1_val = 0;
+	u8 int_n_inp0 = 0, int_n_inp1 = 0, int_n_inp2 = 0;
+
+	int_mux_cfg0 = LPASS_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8;
+	int_mux_cfg1 = int_mux_cfg0 + 4;
+	int_mux_cfg0_val = snd_soc_component_read32(component, int_mux_cfg0);
+	int_mux_cfg1_val = snd_soc_component_read32(component, int_mux_cfg1);
+
+	int_n_inp0 = int_mux_cfg0_val & 0x0F;
+	if (int_n_inp0 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp0 == INTn_1_INP_SEL_DEC1)
+		return true;
+
+	int_n_inp1 = int_mux_cfg0_val >> 4;
+	if (int_n_inp1 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp1 == INTn_1_INP_SEL_DEC1)
+		return true;
+
+	int_n_inp2 = int_mux_cfg1_val >> 4;
+	if (int_n_inp2 == INTn_1_INP_SEL_DEC0 ||
+		int_n_inp2 == INTn_1_INP_SEL_DEC1)
+		return true;
+
+	return false;
+}
+
+static int lpass_cdc_wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w,
+				      struct snd_kcontrol *kcontrol,
+				      int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	u16 reg = 0;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	bool adie_lb = false;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+
+	reg = LPASS_CDC_WSA_RX0_RX_PATH_CTL +
+			LPASS_CDC_WSA_MACRO_RX_PATH_OFFSET * w->shift;
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (lpass_cdc_wsa_macro_adie_lb(component, w->shift)) {
+			adie_lb = true;
+			snd_soc_component_update_bits(component,
+						reg, 0x20, 0x20);
+			lpass_cdc_wsa_pa_on(wsa_dev, adie_lb);
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
+{
+	u16 prim_int_reg = 0;
+
+	switch (reg) {
+	case LPASS_CDC_WSA_RX0_RX_PATH_CTL:
+	case LPASS_CDC_WSA_RX0_RX_PATH_MIX_CTL:
+		prim_int_reg = LPASS_CDC_WSA_RX0_RX_PATH_CTL;
+		*ind = 0;
+		break;
+	case LPASS_CDC_WSA_RX1_RX_PATH_CTL:
+	case LPASS_CDC_WSA_RX1_RX_PATH_MIX_CTL:
+		prim_int_reg = LPASS_CDC_WSA_RX1_RX_PATH_CTL;
+		*ind = 1;
+		break;
+	}
+
+	return prim_int_reg;
+}
+
+static int lpass_cdc_wsa_macro_enable_prim_interpolator(
+				struct snd_soc_component *component,
+				u16 reg, int event)
+{
+	u16 prim_int_reg;
+	u16 ind = 0;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	prim_int_reg = lpass_cdc_wsa_macro_interp_get_primary_reg(reg, &ind);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		wsa_priv->prim_int_users[ind]++;
+		if (wsa_priv->prim_int_users[ind] == 1) {
+			snd_soc_component_update_bits(component,
+				prim_int_reg + LPASS_CDC_WSA_MACRO_RX_PATH_CFG3_OFFSET,
+				0x03, 0x03);
+			snd_soc_component_update_bits(component, prim_int_reg,
+					    0x10, 0x10);
+			lpass_cdc_wsa_macro_hd2_control(component, prim_int_reg, event);
+			snd_soc_component_update_bits(component,
+				prim_int_reg + LPASS_CDC_WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
+				0x1, 0x1);
+		}
+		if ((reg != prim_int_reg) &&
+		    ((snd_soc_component_read32(
+				component, prim_int_reg)) & 0x10))
+			snd_soc_component_update_bits(component, reg,
+					0x10, 0x10);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		wsa_priv->prim_int_users[ind]--;
+		if (wsa_priv->prim_int_users[ind] == 0) {
+			snd_soc_component_update_bits(component, prim_int_reg,
+					1 << 0x5, 0 << 0x5);
+			snd_soc_component_update_bits(component,
+				prim_int_reg + LPASS_CDC_WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
+				0x1, 0x0);
+			snd_soc_component_update_bits(component, prim_int_reg,
+					0x40, 0x40);
+			snd_soc_component_update_bits(component, prim_int_reg,
+					0x40, 0x00);
+			lpass_cdc_wsa_macro_hd2_control(component, prim_int_reg, event);
+		}
+		break;
+	}
+
+	dev_dbg(component->dev, "%s: primary interpolator: INT%d, users: %d\n",
+		__func__, ind, wsa_priv->prim_int_users[ind]);
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,
+					 struct snd_kcontrol *kcontrol,
+					 int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	u16 gain_reg;
+	u16 reg;
+	int val;
+	int offset_val = 0;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(component->dev, "%s %d %s\n", __func__, event, w->name);
+
+	if (!(strcmp(w->name, "WSA_RX INT0 INTERP"))) {
+		reg = LPASS_CDC_WSA_RX0_RX_PATH_CTL;
+		gain_reg = LPASS_CDC_WSA_RX0_RX_VOL_CTL;
+	} else if (!(strcmp(w->name, "WSA_RX INT1 INTERP"))) {
+		reg = LPASS_CDC_WSA_RX1_RX_PATH_CTL;
+		gain_reg = LPASS_CDC_WSA_RX1_RX_VOL_CTL;
+	} else {
+		dev_err(component->dev, "%s: Interpolator reg not found\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Reset if needed */
+		lpass_cdc_wsa_macro_enable_prim_interpolator(component, reg, event);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		lpass_cdc_wsa_macro_config_compander(component, w->shift, event);
+		lpass_cdc_wsa_macro_config_softclip(component, w->shift, event);
+		/* apply gain after int clk is enabled */
+		if ((wsa_priv->spkr_gain_offset ==
+			LPASS_CDC_WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
+		    (wsa_priv->comp_enabled[LPASS_CDC_WSA_MACRO_COMP1] ||
+		     wsa_priv->comp_enabled[LPASS_CDC_WSA_MACRO_COMP2]) &&
+		    (gain_reg == LPASS_CDC_WSA_RX0_RX_VOL_CTL ||
+		     gain_reg == LPASS_CDC_WSA_RX1_RX_VOL_CTL)) {
+			snd_soc_component_update_bits(component,
+					LPASS_CDC_WSA_RX0_RX_PATH_SEC1,
+					0x01, 0x01);
+			snd_soc_component_update_bits(component,
+					LPASS_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
+					0x01, 0x01);
+			snd_soc_component_update_bits(component,
+					LPASS_CDC_WSA_RX1_RX_PATH_SEC1,
+					0x01, 0x01);
+			snd_soc_component_update_bits(component,
+					LPASS_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
+					0x01, 0x01);
+			offset_val = -2;
+		}
+		val = snd_soc_component_read32(component, gain_reg);
+		val += offset_val;
+		snd_soc_component_write(component, gain_reg, val);
+		lpass_cdc_wsa_macro_config_ear_spkr_gain(component, wsa_priv,
+						event, gain_reg);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		lpass_cdc_wsa_macro_config_compander(component, w->shift, event);
+		lpass_cdc_wsa_macro_config_softclip(component, w->shift, event);
+		lpass_cdc_wsa_macro_enable_prim_interpolator(component, reg, event);
+		if ((wsa_priv->spkr_gain_offset ==
+			LPASS_CDC_WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
+		    (wsa_priv->comp_enabled[LPASS_CDC_WSA_MACRO_COMP1] ||
+		     wsa_priv->comp_enabled[LPASS_CDC_WSA_MACRO_COMP2]) &&
+		    (gain_reg == LPASS_CDC_WSA_RX0_RX_VOL_CTL ||
+		     gain_reg == LPASS_CDC_WSA_RX1_RX_VOL_CTL)) {
+			snd_soc_component_update_bits(component,
+					LPASS_CDC_WSA_RX0_RX_PATH_SEC1,
+					0x01, 0x00);
+			snd_soc_component_update_bits(component,
+					LPASS_CDC_WSA_RX0_RX_PATH_MIX_SEC0,
+					0x01, 0x00);
+			snd_soc_component_update_bits(component,
+					LPASS_CDC_WSA_RX1_RX_PATH_SEC1,
+					0x01, 0x00);
+			snd_soc_component_update_bits(component,
+					LPASS_CDC_WSA_RX1_RX_PATH_MIX_SEC0,
+					0x01, 0x00);
+			offset_val = 2;
+			val = snd_soc_component_read32(component, gain_reg);
+			val += offset_val;
+			snd_soc_component_write(component, gain_reg, val);
+		}
+		lpass_cdc_wsa_macro_config_ear_spkr_gain(component, wsa_priv,
+						event, gain_reg);
+		break;
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
+					struct lpass_cdc_wsa_macro_priv *wsa_priv,
+					int event, int gain_reg)
+{
+	int comp_gain_offset, val;
+
+	switch (wsa_priv->spkr_mode) {
+	/* Compander gain in LPASS_CDC_WSA_MACRO_SPKR_MODE1 case is 12 dB */
+	case LPASS_CDC_WSA_MACRO_SPKR_MODE_1:
+		comp_gain_offset = -12;
+		break;
+	/* Default case compander gain is 15 dB */
+	default:
+		comp_gain_offset = -15;
+		break;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		/* Apply ear spkr gain only if compander is enabled */
+		if (wsa_priv->comp_enabled[LPASS_CDC_WSA_MACRO_COMP1] &&
+		    (gain_reg == LPASS_CDC_WSA_RX0_RX_VOL_CTL) &&
+		    (wsa_priv->ear_spkr_gain != 0)) {
+			/* For example, val is -8(-12+5-1) for 4dB of gain */
+			val = comp_gain_offset + wsa_priv->ear_spkr_gain - 1;
+			snd_soc_component_write(component, gain_reg, val);
+
+			dev_dbg(wsa_priv->dev, "%s: RX0 Volume %d dB\n",
+				__func__, val);
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/*
+		 * Reset RX0 volume to 0 dB if compander is enabled and
+		 * ear_spkr_gain is non-zero.
+		 */
+		if (wsa_priv->comp_enabled[LPASS_CDC_WSA_MACRO_COMP1] &&
+		    (gain_reg == LPASS_CDC_WSA_RX0_RX_VOL_CTL) &&
+		    (wsa_priv->ear_spkr_gain != 0)) {
+			snd_soc_component_write(component, gain_reg, 0x0);
+
+			dev_dbg(wsa_priv->dev, "%s: Reset RX0 Volume to 0 dB\n",
+				__func__);
+		}
+		break;
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
+				     struct snd_kcontrol *kcontrol,
+				     int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	u16 boost_path_ctl, boost_path_cfg1;
+	u16 reg, reg_mix;
+
+	dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
+
+	if (!strcmp(w->name, "WSA_RX INT0 CHAIN")) {
+		boost_path_ctl = LPASS_CDC_WSA_BOOST0_BOOST_PATH_CTL;
+		boost_path_cfg1 = LPASS_CDC_WSA_RX0_RX_PATH_CFG1;
+		reg = LPASS_CDC_WSA_RX0_RX_PATH_CTL;
+		reg_mix = LPASS_CDC_WSA_RX0_RX_PATH_MIX_CTL;
+	} else if (!strcmp(w->name, "WSA_RX INT1 CHAIN")) {
+		boost_path_ctl = LPASS_CDC_WSA_BOOST1_BOOST_PATH_CTL;
+		boost_path_cfg1 = LPASS_CDC_WSA_RX1_RX_PATH_CFG1;
+		reg = LPASS_CDC_WSA_RX1_RX_PATH_CTL;
+		reg_mix = LPASS_CDC_WSA_RX1_RX_PATH_MIX_CTL;
+	} else {
+		dev_err(component->dev, "%s: unknown widget: %s\n",
+			__func__, w->name);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_component_update_bits(component, boost_path_cfg1,
+						0x01, 0x01);
+		snd_soc_component_update_bits(component, boost_path_ctl,
+						0x10, 0x10);
+		if ((snd_soc_component_read32(component, reg_mix)) & 0x10)
+			snd_soc_component_update_bits(component, reg_mix,
+						0x10, 0x00);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		snd_soc_component_update_bits(component, reg, 0x10, 0x00);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_component_update_bits(component, boost_path_ctl,
+						0x10, 0x00);
+		snd_soc_component_update_bits(component, boost_path_cfg1,
+						0x01, 0x00);
+		break;
+	}
+
+	return 0;
+}
+
+
+static int lpass_cdc_wsa_macro_enable_vbat(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kcontrol,
+				 int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	u16 vbat_path_cfg = 0;
+	int softclip_path = 0;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(component->dev, "%s %s %d\n", __func__, w->name, event);
+	if (!strcmp(w->name, "WSA_RX INT0 VBAT")) {
+		vbat_path_cfg = LPASS_CDC_WSA_RX0_RX_PATH_CFG1;
+		softclip_path = LPASS_CDC_WSA_MACRO_SOFTCLIP0;
+	} else if (!strcmp(w->name, "WSA_RX INT1 VBAT")) {
+		vbat_path_cfg = LPASS_CDC_WSA_RX1_RX_PATH_CFG1;
+		softclip_path = LPASS_CDC_WSA_MACRO_SOFTCLIP1;
+	}
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Enable clock for VBAT block */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x10);
+		/* Enable VBAT block */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x01);
+		/* Update interpolator with 384K path */
+		snd_soc_component_update_bits(component, vbat_path_cfg,
+			0x80, 0x80);
+		/* Use attenuation mode */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x02, 0x00);
+		/*
+		 * BCL block needs softclip clock and mux config to be enabled
+		 */
+		lpass_cdc_wsa_macro_enable_softclip_clk(component, wsa_priv,
+					softclip_path, true);
+		/* Enable VBAT at channel level */
+		snd_soc_component_update_bits(component, vbat_path_cfg,
+				0x02, 0x02);
+		/* Set the ATTK1 gain */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
+			0xFF, 0xFF);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
+			0xFF, 0x03);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
+			0xFF, 0x00);
+		/* Set the ATTK2 gain */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
+			0xFF, 0xFF);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
+			0xFF, 0x03);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
+			0xFF, 0x00);
+		/* Set the ATTK3 gain */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
+			0xFF, 0xFF);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
+			0xFF, 0x03);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
+			0xFF, 0x00);
+		break;
+
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_component_update_bits(component, vbat_path_cfg,
+			0x80, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_CFG,
+			0x02, 0x02);
+		snd_soc_component_update_bits(component, vbat_path_cfg,
+			0x02, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1,
+			0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2,
+			0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3,
+			0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4,
+			0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5,
+			0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6,
+			0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7,
+			0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8,
+			0xFF, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9,
+			0xFF, 0x00);
+		lpass_cdc_wsa_macro_enable_softclip_clk(component, wsa_priv,
+			softclip_path, false);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x01, 0x00);
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x10, 0x00);
+		break;
+	default:
+		dev_err(wsa_dev, "%s: Invalid event %d\n", __func__, event);
+		break;
+	}
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kcontrol,
+				 int event)
+{
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(w->dapm);
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	u16 val, ec_tx = 0, ec_hq_reg;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(wsa_dev, "%s %d %s\n", __func__, event, w->name);
+
+	val = snd_soc_component_read32(component,
+				LPASS_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
+	if (!(strcmp(w->name, "WSA RX_MIX EC0_MUX")))
+		ec_tx = (val & 0x07) - 1;
+	else
+		ec_tx = ((val & 0x38) >> 0x3) - 1;
+
+	if (ec_tx < 0 || ec_tx >= (LPASS_CDC_WSA_MACRO_RX1 + 1)) {
+		dev_err(wsa_dev, "%s: EC mix control not set correctly\n",
+			__func__);
+		return -EINVAL;
+	}
+	if (wsa_priv->ec_hq[ec_tx]) {
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
+				0x1 << ec_tx, 0x1 << ec_tx);
+		ec_hq_reg = LPASS_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +
+							0x40 * ec_tx;
+		snd_soc_component_update_bits(component, ec_hq_reg, 0x01, 0x01);
+		ec_hq_reg = LPASS_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 +
+							0x40 * ec_tx;
+		/* default set to 48k */
+		snd_soc_component_update_bits(component, ec_hq_reg, 0x1E, 0x08);
+	}
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	int ec_tx = ((struct soc_multi_mixer_control *)
+		    kcontrol->private_value)->shift;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = wsa_priv->ec_hq[ec_tx];
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	int ec_tx = ((struct soc_multi_mixer_control *)
+		    kcontrol->private_value)->shift;
+	int value = ucontrol->value.integer.value[0];
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(wsa_dev, "%s: enable current %d, new %d\n",
+		__func__, wsa_priv->ec_hq[ec_tx], value);
+	wsa_priv->ec_hq[ec_tx] = value;
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_get_rx_mute_status(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	int wsa_rx_shift = ((struct soc_multi_mixer_control *)
+		       kcontrol->private_value)->shift;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] =
+		wsa_priv->wsa_digital_mute_status[wsa_rx_shift];
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	int value = ucontrol->value.integer.value[0];
+	int wsa_rx_shift = ((struct soc_multi_mixer_control *)
+			kcontrol->private_value)->shift;
+	int ret = 0;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	pm_runtime_get_sync(wsa_priv->dev);
+	switch (wsa_rx_shift) {
+	case 0:
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_RX0_RX_PATH_CTL,
+				0x10, value << 4);
+		break;
+	case 1:
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_RX1_RX_PATH_CTL,
+				0x10, value << 4);
+		break;
+	case 2:
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_RX0_RX_PATH_MIX_CTL,
+				0x10, value << 4);
+		break;
+	case 3:
+		snd_soc_component_update_bits(component,
+				LPASS_CDC_WSA_RX1_RX_PATH_MIX_CTL,
+				0x10, value << 4);
+		break;
+	default:
+		pr_err("%s: invalid argument rx_shift = %d\n", __func__,
+			wsa_rx_shift);
+		ret = -EINVAL;
+	}
+	pm_runtime_mark_last_busy(wsa_priv->dev);
+	pm_runtime_put_autosuspend(wsa_priv->dev);
+
+	dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n",
+		__func__, wsa_rx_shift, value);
+	wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value;
+
+	return ret;
+}
+
+static int lpass_cdc_wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	int comp = ((struct soc_multi_mixer_control *)
+		    kcontrol->private_value)->shift;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = wsa_priv->comp_enabled[comp];
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_set_compander(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	int comp = ((struct soc_multi_mixer_control *)
+		    kcontrol->private_value)->shift;
+	int value = ucontrol->value.integer.value[0];
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(component->dev, "%s: Compander %d enable current %d, new %d\n",
+		__func__, comp + 1, wsa_priv->comp_enabled[comp], value);
+	wsa_priv->comp_enabled[comp] = value;
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = wsa_priv->ear_spkr_gain;
+
+	dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	wsa_priv->ear_spkr_gain =  ucontrol->value.integer.value[0];
+
+	dev_dbg(component->dev, "%s: gain = %d\n", __func__,
+		wsa_priv->ear_spkr_gain);
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	u8 bst_state_max = 0;
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+
+	bst_state_max = snd_soc_component_read32(component,
+				LPASS_CDC_WSA_BOOST0_BOOST_CTL);
+	bst_state_max = (bst_state_max & 0x0c) >> 2;
+	ucontrol->value.integer.value[0] = bst_state_max;
+	dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0]  = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	u8 bst_state_max;
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+
+	dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0]  = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+	bst_state_max =  ucontrol->value.integer.value[0] << 2;
+	/* lpass_cdc does not need to limit the boost levels */
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	u8 bst_state_max = 0;
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+
+	bst_state_max = snd_soc_component_read32(component,
+				LPASS_CDC_WSA_BOOST1_BOOST_CTL);
+	bst_state_max = (bst_state_max & 0x0c) >> 2;
+	ucontrol->value.integer.value[0] = bst_state_max;
+	dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0]  = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	u8 bst_state_max;
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+
+	dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0]  = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+	bst_state_max =  ucontrol->value.integer.value[0] << 2;
+	/* lpass_cdc does not need to limit the boost levels */
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] =
+			wsa_priv->rx_port_value[widget->shift];
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	struct snd_soc_dapm_update *update = NULL;
+	u32 rx_port_value = ucontrol->value.integer.value[0];
+	u32 bit_input = 0;
+	u32 aif_rst;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	aif_rst = wsa_priv->rx_port_value[widget->shift];
+	if (!rx_port_value) {
+		if (aif_rst == 0) {
+			dev_err(wsa_dev, "%s: AIF reset already\n", __func__);
+			return 0;
+		}
+		if (aif_rst >= LPASS_CDC_WSA_MACRO_RX_MAX) {
+			dev_err(wsa_dev, "%s: Invalid AIF reset\n", __func__);
+			return 0;
+		}
+	}
+	wsa_priv->rx_port_value[widget->shift] = rx_port_value;
+
+	bit_input = widget->shift;
+
+	dev_dbg(wsa_dev,
+		"%s: mux input: %d, mux output: %d, bit: %d\n",
+		__func__, rx_port_value, widget->shift, bit_input);
+
+	switch (rx_port_value) {
+	case 0:
+		if (wsa_priv->active_ch_cnt[aif_rst]) {
+			clear_bit(bit_input,
+				  &wsa_priv->active_ch_mask[aif_rst]);
+			wsa_priv->active_ch_cnt[aif_rst]--;
+		}
+		break;
+	case 1:
+	case 2:
+		set_bit(bit_input,
+			&wsa_priv->active_ch_mask[rx_port_value]);
+		wsa_priv->active_ch_cnt[rx_port_value]++;
+		break;
+	default:
+		dev_err(wsa_dev,
+			"%s: Invalid AIF_ID for WSA RX MUX %d\n",
+			__func__, rx_port_value);
+		return -EINVAL;
+	}
+
+	snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
+					rx_port_value, e, update);
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_func_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+
+	ucontrol->value.integer.value[0] =
+	    ((snd_soc_component_read32(
+		component, LPASS_CDC_WSA_VBAT_BCL_VBAT_CFG) & 0x04) ?
+	    1 : 0);
+
+	dev_dbg(component->dev, "%s: value: %lu\n", __func__,
+		ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_func_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+
+	dev_dbg(component->dev, "%s: value: %lu\n", __func__,
+		ucontrol->value.integer.value[0]);
+
+	/* Set Vbat register configuration for GSM mode bit based on value */
+	if (ucontrol->value.integer.value[0])
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_CFG,
+			0x04, 0x04);
+	else
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_CFG,
+			0x04, 0x00);
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	int path = ((struct soc_multi_mixer_control *)
+		    kcontrol->private_value)->shift;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] = wsa_priv->is_softclip_on[path];
+
+	dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+	int path = ((struct soc_multi_mixer_control *)
+		    kcontrol->private_value)->shift;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	wsa_priv->is_softclip_on[path] =  ucontrol->value.integer.value[0];
+
+	dev_dbg(component->dev, "%s: soft clip enable for %d: %d\n", __func__,
+		path, wsa_priv->is_softclip_on[path]);
+
+	return 0;
+}
+
+static const struct snd_kcontrol_new lpass_cdc_wsa_macro_snd_controls[] = {
+	SOC_ENUM_EXT("EAR SPKR PA Gain", lpass_cdc_wsa_macro_ear_spkr_pa_gain_enum,
+		     lpass_cdc_wsa_macro_ear_spkr_pa_gain_get,
+		     lpass_cdc_wsa_macro_ear_spkr_pa_gain_put),
+	SOC_ENUM_EXT("SPKR Left Boost Max State",
+		lpass_cdc_wsa_macro_spkr_boost_stage_enum,
+		lpass_cdc_wsa_macro_spkr_left_boost_stage_get,
+		lpass_cdc_wsa_macro_spkr_left_boost_stage_put),
+	SOC_ENUM_EXT("SPKR Right Boost Max State",
+		lpass_cdc_wsa_macro_spkr_boost_stage_enum,
+		lpass_cdc_wsa_macro_spkr_right_boost_stage_get,
+		lpass_cdc_wsa_macro_spkr_right_boost_stage_put),
+	SOC_ENUM_EXT("GSM mode Enable", lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_enum,
+		     lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_func_get,
+		     lpass_cdc_wsa_macro_vbat_bcl_gsm_mode_func_put),
+	SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
+			LPASS_CDC_WSA_MACRO_SOFTCLIP0, 1, 0,
+			lpass_cdc_wsa_macro_soft_clip_enable_get,
+			lpass_cdc_wsa_macro_soft_clip_enable_put),
+	SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
+			LPASS_CDC_WSA_MACRO_SOFTCLIP1, 1, 0,
+			lpass_cdc_wsa_macro_soft_clip_enable_get,
+			lpass_cdc_wsa_macro_soft_clip_enable_put),
+	SOC_SINGLE_S8_TLV("WSA_RX0 Digital Volume",
+			  LPASS_CDC_WSA_RX0_RX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_S8_TLV("WSA_RX1 Digital Volume",
+			  LPASS_CDC_WSA_RX1_RX_VOL_CTL,
+			  -84, 40, digital_gain),
+	SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_RX0, 1,
+			0, lpass_cdc_wsa_macro_get_rx_mute_status,
+			lpass_cdc_wsa_macro_set_rx_mute_status),
+	SOC_SINGLE_EXT("WSA_RX1 Digital Mute", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_RX1, 1,
+			0, lpass_cdc_wsa_macro_get_rx_mute_status,
+			lpass_cdc_wsa_macro_set_rx_mute_status),
+	SOC_SINGLE_EXT("WSA_RX0_MIX Digital Mute", SND_SOC_NOPM,
+			LPASS_CDC_WSA_MACRO_RX_MIX0, 1, 0, lpass_cdc_wsa_macro_get_rx_mute_status,
+			lpass_cdc_wsa_macro_set_rx_mute_status),
+	SOC_SINGLE_EXT("WSA_RX1_MIX Digital Mute", SND_SOC_NOPM,
+			LPASS_CDC_WSA_MACRO_RX_MIX1, 1, 0, lpass_cdc_wsa_macro_get_rx_mute_status,
+			lpass_cdc_wsa_macro_set_rx_mute_status),
+	SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_COMP1, 1, 0,
+		lpass_cdc_wsa_macro_get_compander, lpass_cdc_wsa_macro_set_compander),
+	SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_COMP2, 1, 0,
+		lpass_cdc_wsa_macro_get_compander, lpass_cdc_wsa_macro_set_compander),
+	SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_RX0,
+			1, 0, lpass_cdc_wsa_macro_get_ec_hq, lpass_cdc_wsa_macro_set_ec_hq),
+	SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_RX1,
+			1, 0, lpass_cdc_wsa_macro_get_ec_hq, lpass_cdc_wsa_macro_set_ec_hq),
+};
+
+static const struct soc_enum rx_mux_enum =
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
+
+static const struct snd_kcontrol_new rx_mux[LPASS_CDC_WSA_MACRO_RX_MAX] = {
+	SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
+			  lpass_cdc_wsa_macro_rx_mux_get, lpass_cdc_wsa_macro_rx_mux_put),
+	SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
+			  lpass_cdc_wsa_macro_rx_mux_get, lpass_cdc_wsa_macro_rx_mux_put),
+	SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
+			  lpass_cdc_wsa_macro_rx_mux_get, lpass_cdc_wsa_macro_rx_mux_put),
+	SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
+			  lpass_cdc_wsa_macro_rx_mux_get, lpass_cdc_wsa_macro_rx_mux_put),
+};
+
+static int lpass_cdc_wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct soc_multi_mixer_control *mixer =
+		((struct soc_multi_mixer_control *)kcontrol->private_value);
+	u32 dai_id = widget->shift;
+	u32 spk_tx_id = mixer->shift;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	if (test_bit(spk_tx_id, &wsa_priv->active_ch_mask[dai_id]))
+		ucontrol->value.integer.value[0] = 1;
+	else
+		ucontrol->value.integer.value[0] = 0;
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget *widget =
+		snd_soc_dapm_kcontrol_widget(kcontrol);
+	struct snd_soc_component *component =
+				snd_soc_dapm_to_component(widget->dapm);
+	struct soc_multi_mixer_control *mixer =
+		((struct soc_multi_mixer_control *)kcontrol->private_value);
+	u32 spk_tx_id = mixer->shift;
+	u32 enable = ucontrol->value.integer.value[0];
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	wsa_priv->vi_feed_value = ucontrol->value.integer.value[0];
+
+	if (enable) {
+		if (spk_tx_id == LPASS_CDC_WSA_MACRO_TX0 &&
+			!test_bit(LPASS_CDC_WSA_MACRO_TX0,
+				&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI])) {
+			set_bit(LPASS_CDC_WSA_MACRO_TX0,
+				&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI]);
+			wsa_priv->active_ch_cnt[LPASS_CDC_WSA_MACRO_AIF_VI]++;
+		}
+		if (spk_tx_id == LPASS_CDC_WSA_MACRO_TX1 &&
+			!test_bit(LPASS_CDC_WSA_MACRO_TX1,
+				&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI])) {
+			set_bit(LPASS_CDC_WSA_MACRO_TX1,
+				&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI]);
+			wsa_priv->active_ch_cnt[LPASS_CDC_WSA_MACRO_AIF_VI]++;
+		}
+	} else {
+		if (spk_tx_id == LPASS_CDC_WSA_MACRO_TX0 &&
+			test_bit(LPASS_CDC_WSA_MACRO_TX0,
+				&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI])) {
+			clear_bit(LPASS_CDC_WSA_MACRO_TX0,
+				&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI]);
+			wsa_priv->active_ch_cnt[LPASS_CDC_WSA_MACRO_AIF_VI]--;
+		}
+		if (spk_tx_id == LPASS_CDC_WSA_MACRO_TX1 &&
+			test_bit(LPASS_CDC_WSA_MACRO_TX1,
+				&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI])) {
+			clear_bit(LPASS_CDC_WSA_MACRO_TX1,
+				&wsa_priv->active_ch_mask[LPASS_CDC_WSA_MACRO_AIF_VI]);
+			wsa_priv->active_ch_cnt[LPASS_CDC_WSA_MACRO_AIF_VI]--;
+		}
+	}
+	snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
+
+	return 0;
+}
+
+static const struct snd_kcontrol_new aif_vi_mixer[] = {
+	SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_TX0, 1, 0,
+			lpass_cdc_wsa_macro_vi_feed_mixer_get,
+			lpass_cdc_wsa_macro_vi_feed_mixer_put),
+	SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_TX1, 1, 0,
+			lpass_cdc_wsa_macro_vi_feed_mixer_get,
+			lpass_cdc_wsa_macro_vi_feed_mixer_put),
+};
+
+static const struct snd_soc_dapm_widget lpass_cdc_wsa_macro_dapm_widgets[] = {
+	SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
+		SND_SOC_NOPM, 0, 0),
+
+	SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
+		SND_SOC_NOPM, 0, 0),
+
+	SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
+		SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_AIF_VI, 0,
+		lpass_cdc_wsa_macro_enable_vi_feedback,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
+		SND_SOC_NOPM, 0, 0),
+
+	SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_AIF_VI,
+		0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
+	SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
+			LPASS_CDC_WSA_MACRO_EC0_MUX, 0,
+			&rx_mix_ec0_mux, lpass_cdc_wsa_macro_enable_echo,
+			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
+			LPASS_CDC_WSA_MACRO_EC1_MUX, 0,
+			&rx_mix_ec1_mux, lpass_cdc_wsa_macro_enable_echo,
+			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_RX0, 0,
+				&rx_mux[LPASS_CDC_WSA_MACRO_RX0]),
+	SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_RX1, 0,
+				&rx_mux[LPASS_CDC_WSA_MACRO_RX1]),
+	SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_RX_MIX0, 0,
+				&rx_mux[LPASS_CDC_WSA_MACRO_RX_MIX0]),
+	SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, LPASS_CDC_WSA_MACRO_RX_MIX1, 0,
+				&rx_mux[LPASS_CDC_WSA_MACRO_RX_MIX1]),
+
+	SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_MUX_E("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0,
+		&rx0_prim_inp0_mux, lpass_cdc_wsa_macro_enable_swr,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0,
+		&rx0_prim_inp1_mux, lpass_cdc_wsa_macro_enable_swr,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0,
+		&rx0_prim_inp2_mux, lpass_cdc_wsa_macro_enable_swr,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM,
+		0, 0, &rx0_mix_mux, lpass_cdc_wsa_macro_enable_mix_path,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0,
+		&rx1_prim_inp0_mux, lpass_cdc_wsa_macro_enable_swr,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx1_prim_inp1_mux, lpass_cdc_wsa_macro_enable_swr,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx1_prim_inp2_mux, lpass_cdc_wsa_macro_enable_swr,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM,
+		0, 0, &rx1_mix_mux, lpass_cdc_wsa_macro_enable_mix_path,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_PGA_E("WSA_RX INT0 MIX", SND_SOC_NOPM,
+			0, 0, NULL, 0, lpass_cdc_wsa_macro_enable_main_path,
+			SND_SOC_DAPM_PRE_PMU),
+	SND_SOC_DAPM_PGA_E("WSA_RX INT1 MIX", SND_SOC_NOPM,
+			1, 0, NULL, 0, lpass_cdc_wsa_macro_enable_main_path,
+			SND_SOC_DAPM_PRE_PMU),
+	SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_MUX_E("WSA_RX0 INT0 SIDETONE MIX",
+			   LPASS_CDC_WSA_RX0_RX_PATH_CFG1, 4, 0,
+			   &rx0_sidetone_mix_mux, lpass_cdc_wsa_macro_enable_swr,
+			  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_INPUT("WSA SRC0_INP"),
+
+	SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),
+	SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),
+
+	SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
+		LPASS_CDC_WSA_MACRO_COMP1, 0, NULL, 0, lpass_cdc_wsa_macro_enable_interpolator,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
+		LPASS_CDC_WSA_MACRO_COMP2, 0, NULL, 0, lpass_cdc_wsa_macro_enable_interpolator,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,
+		NULL, 0, lpass_cdc_wsa_macro_spk_boost_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
+		NULL, 0, lpass_cdc_wsa_macro_spk_boost_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MIXER_E("WSA_RX INT0 VBAT", SND_SOC_NOPM,
+		0, 0, wsa_int0_vbat_mix_switch,
+		ARRAY_SIZE(wsa_int0_vbat_mix_switch),
+		lpass_cdc_wsa_macro_enable_vbat,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MIXER_E("WSA_RX INT1 VBAT", SND_SOC_NOPM,
+		0, 0, wsa_int1_vbat_mix_switch,
+		ARRAY_SIZE(wsa_int1_vbat_mix_switch),
+		lpass_cdc_wsa_macro_enable_vbat,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
+
+	SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
+	SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
+
+	SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
+	lpass_cdc_wsa_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_route wsa_audio_map[] = {
+	/* VI Feedback */
+	{"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
+	{"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
+	{"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
+	{"WSA AIF_VI", NULL, "WSA_MCLK"},
+
+	{"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
+	{"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
+	{"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
+	{"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
+	{"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
+	{"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
+	{"WSA AIF_ECHO", NULL, "WSA_MCLK"},
+
+	{"WSA AIF1 PB", NULL, "WSA_MCLK"},
+	{"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
+
+	{"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
+	{"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
+	{"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
+	{"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
+
+	{"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
+	{"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
+	{"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
+	{"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
+
+	{"WSA RX0", NULL, "WSA RX0 MUX"},
+	{"WSA RX1", NULL, "WSA RX1 MUX"},
+	{"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
+	{"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
+
+	{"WSA_RX0 INP0", "RX0", "WSA RX0"},
+	{"WSA_RX0 INP0", "RX1", "WSA RX1"},
+	{"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
+	{"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
+	{"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},
+	{"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},
+	{"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
+
+	{"WSA_RX0 INP1", "RX0", "WSA RX0"},
+	{"WSA_RX0 INP1", "RX1", "WSA RX1"},
+	{"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
+	{"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
+	{"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},
+	{"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},
+	{"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
+
+	{"WSA_RX0 INP2", "RX0", "WSA RX0"},
+	{"WSA_RX0 INP2", "RX1", "WSA RX1"},
+	{"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
+	{"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
+	{"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},
+	{"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},
+	{"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
+
+	{"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
+	{"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
+	{"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
+	{"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
+	{"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
+
+	{"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
+	{"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
+	{"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
+	{"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
+	{"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
+
+	{"WSA_RX INT0 VBAT", "WSA RX0 VBAT Enable", "WSA_RX INT0 INTERP"},
+	{"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 VBAT"},
+
+	{"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
+	{"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
+
+	{"WSA_RX1 INP0", "RX0", "WSA RX0"},
+	{"WSA_RX1 INP0", "RX1", "WSA RX1"},
+	{"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
+	{"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
+	{"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},
+	{"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},
+	{"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
+
+	{"WSA_RX1 INP1", "RX0", "WSA RX0"},
+	{"WSA_RX1 INP1", "RX1", "WSA RX1"},
+	{"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
+	{"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
+	{"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},
+	{"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},
+	{"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
+
+	{"WSA_RX1 INP2", "RX0", "WSA RX0"},
+	{"WSA_RX1 INP2", "RX1", "WSA RX1"},
+	{"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
+	{"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
+	{"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},
+	{"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},
+	{"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
+
+	{"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
+	{"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
+	{"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
+	{"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
+	{"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
+
+	{"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
+	{"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
+
+	{"WSA_RX INT1 VBAT", "WSA RX1 VBAT Enable", "WSA_RX INT1 INTERP"},
+	{"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 VBAT"},
+
+	{"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
+	{"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
+	{"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
+};
+
+static const struct lpass_cdc_wsa_macro_reg_mask_val
+				lpass_cdc_wsa_macro_reg_init[] = {
+	{LPASS_CDC_WSA_BOOST0_BOOST_CFG1, 0x3F, 0x12},
+	{LPASS_CDC_WSA_BOOST0_BOOST_CFG2, 0x1C, 0x08},
+	{LPASS_CDC_WSA_COMPANDER0_CTL7, 0x1E, 0x0C},
+	{LPASS_CDC_WSA_BOOST1_BOOST_CFG1, 0x3F, 0x12},
+	{LPASS_CDC_WSA_BOOST1_BOOST_CFG2, 0x1C, 0x08},
+	{LPASS_CDC_WSA_COMPANDER1_CTL7, 0x1E, 0x0C},
+	{LPASS_CDC_WSA_BOOST0_BOOST_CTL, 0x70, 0x58},
+	{LPASS_CDC_WSA_BOOST1_BOOST_CTL, 0x70, 0x58},
+	{LPASS_CDC_WSA_RX0_RX_PATH_CFG1, 0x08, 0x08},
+	{LPASS_CDC_WSA_RX1_RX_PATH_CFG1, 0x08, 0x08},
+	{LPASS_CDC_WSA_TOP_TOP_CFG1, 0x02, 0x02},
+	{LPASS_CDC_WSA_TOP_TOP_CFG1, 0x01, 0x01},
+	{LPASS_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
+	{LPASS_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
+	{LPASS_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
+	{LPASS_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
+	{LPASS_CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01},
+	{LPASS_CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01},
+	{LPASS_CDC_WSA_RX0_RX_PATH_CFG0, 0x01, 0x01},
+	{LPASS_CDC_WSA_RX1_RX_PATH_CFG0, 0x01, 0x01},
+	{LPASS_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x01, 0x01},
+	{LPASS_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x01, 0x01},
+};
+
+static void lpass_cdc_wsa_macro_init_bcl_pmic_reg(struct snd_soc_component *component)
+{
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!component) {
+		pr_err("%s: NULL component pointer!\n", __func__);
+		return;
+	}
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return;
+
+	switch (wsa_priv->bcl_pmic_params.id) {
+	case 0:
+		/* Enable ID0 to listen to respective PMIC group interrupts */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x02, 0x02);
+		/* Update MC_SID0 */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x0F,
+			wsa_priv->bcl_pmic_params.sid);
+		/* Update MC_PPID0 */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0xFF,
+			wsa_priv->bcl_pmic_params.ppid);
+		break;
+	case 1:
+		/* Enable ID1 to listen to respective PMIC group interrupts */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0x01, 0x01);
+		/* Update MC_SID1 */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x0F,
+			wsa_priv->bcl_pmic_params.sid);
+		/* Update MC_PPID1 */
+		snd_soc_component_update_bits(component,
+			LPASS_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0xFF,
+			wsa_priv->bcl_pmic_params.ppid);
+		break;
+	default:
+		dev_err(wsa_dev, "%s: PMIC ID is invalid %d\n",
+		       __func__, wsa_priv->bcl_pmic_params.id);
+		break;
+	}
+}
+
+static void lpass_cdc_wsa_macro_init_reg(struct snd_soc_component *component)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(lpass_cdc_wsa_macro_reg_init); i++)
+		snd_soc_component_update_bits(component,
+				lpass_cdc_wsa_macro_reg_init[i].reg,
+				lpass_cdc_wsa_macro_reg_init[i].mask,
+				lpass_cdc_wsa_macro_reg_init[i].val);
+
+	lpass_cdc_wsa_macro_init_bcl_pmic_reg(component);
+}
+
+static int lpass_cdc_wsa_macro_core_vote(void *handle, bool enable)
+{
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = (struct lpass_cdc_wsa_macro_priv *) handle;
+
+	if (wsa_priv == NULL) {
+		pr_err("%s: wsa priv data is NULL\n", __func__);
+		return -EINVAL;
+	}
+	if (enable) {
+		pm_runtime_get_sync(wsa_priv->dev);
+		pm_runtime_put_autosuspend(wsa_priv->dev);
+		pm_runtime_mark_last_busy(wsa_priv->dev);
+	}
+
+	if (lpass_cdc_check_core_votes(wsa_priv->dev))
+		return 0;
+	else
+		return -EINVAL;
+}
+
+static int wsa_swrm_clock(void *handle, bool enable)
+{
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = (struct lpass_cdc_wsa_macro_priv *) handle;
+	struct regmap *regmap = dev_get_regmap(wsa_priv->dev->parent, NULL);
+	int ret = 0;
+
+	if (regmap == NULL) {
+		dev_err(wsa_priv->dev, "%s: regmap is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&wsa_priv->swr_clk_lock);
+
+	trace_printk("%s: %s swrm clock %s\n",
+		dev_name(wsa_priv->dev), __func__,
+		(enable ? "enable" : "disable"));
+	dev_dbg(wsa_priv->dev, "%s: swrm clock %s\n",
+		__func__, (enable ? "enable" : "disable"));
+	if (enable) {
+		pm_runtime_get_sync(wsa_priv->dev);
+		if (wsa_priv->swr_clk_users == 0) {
+			ret = msm_cdc_pinctrl_select_active_state(
+						wsa_priv->wsa_swr_gpio_p);
+			if (ret < 0) {
+				dev_err_ratelimited(wsa_priv->dev,
+					"%s: wsa swr pinctrl enable failed\n",
+					__func__);
+				pm_runtime_mark_last_busy(wsa_priv->dev);
+				pm_runtime_put_autosuspend(wsa_priv->dev);
+				goto exit;
+			}
+			ret = lpass_cdc_wsa_macro_mclk_enable(wsa_priv, 1, true);
+			if (ret < 0) {
+				msm_cdc_pinctrl_select_sleep_state(
+						wsa_priv->wsa_swr_gpio_p);
+				dev_err_ratelimited(wsa_priv->dev,
+					"%s: wsa request clock enable failed\n",
+					__func__);
+				pm_runtime_mark_last_busy(wsa_priv->dev);
+				pm_runtime_put_autosuspend(wsa_priv->dev);
+				goto exit;
+			}
+			if (wsa_priv->reset_swr)
+				regmap_update_bits(regmap,
+					LPASS_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
+					0x02, 0x02);
+			regmap_update_bits(regmap,
+				LPASS_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
+				0x01, 0x01);
+			if (wsa_priv->reset_swr)
+				regmap_update_bits(regmap,
+					LPASS_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
+					0x02, 0x00);
+			regmap_update_bits(regmap,
+				LPASS_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
+				0x1C, 0x0C);
+			wsa_priv->reset_swr = false;
+		}
+		wsa_priv->swr_clk_users++;
+		pm_runtime_mark_last_busy(wsa_priv->dev);
+		pm_runtime_put_autosuspend(wsa_priv->dev);
+	} else {
+		if (wsa_priv->swr_clk_users <= 0) {
+			dev_err(wsa_priv->dev, "%s: clock already disabled\n",
+			__func__);
+			wsa_priv->swr_clk_users = 0;
+			goto exit;
+		}
+		wsa_priv->swr_clk_users--;
+		if (wsa_priv->swr_clk_users == 0) {
+			regmap_update_bits(regmap,
+				LPASS_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
+				0x01, 0x00);
+			lpass_cdc_wsa_macro_mclk_enable(wsa_priv, 0, true);
+			ret = msm_cdc_pinctrl_select_sleep_state(
+						wsa_priv->wsa_swr_gpio_p);
+			if (ret < 0) {
+				dev_err_ratelimited(wsa_priv->dev,
+					"%s: wsa swr pinctrl disable failed\n",
+					__func__);
+				goto exit;
+			}
+		}
+	}
+	trace_printk("%s: %s swrm clock users: %d\n",
+		dev_name(wsa_priv->dev), __func__,
+		wsa_priv->swr_clk_users);
+	dev_dbg(wsa_priv->dev, "%s: swrm clock users %d\n",
+		__func__, wsa_priv->swr_clk_users);
+exit:
+	mutex_unlock(&wsa_priv->swr_clk_lock);
+	return ret;
+}
+
+static int lpass_cdc_wsa_macro_init(struct snd_soc_component *component)
+{
+	struct snd_soc_dapm_context *dapm =
+				snd_soc_component_get_dapm(component);
+	int ret;
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	wsa_dev = lpass_cdc_get_device_ptr(component->dev, WSA_MACRO);
+	if (!wsa_dev) {
+		dev_err(component->dev,
+			"%s: null device for macro!\n", __func__);
+		return -EINVAL;
+	}
+	wsa_priv = dev_get_drvdata(wsa_dev);
+	if (!wsa_priv) {
+		dev_err(component->dev,
+			"%s: priv is null for macro!\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = snd_soc_dapm_new_controls(dapm, lpass_cdc_wsa_macro_dapm_widgets,
+					ARRAY_SIZE(lpass_cdc_wsa_macro_dapm_widgets));
+	if (ret < 0) {
+		dev_err(wsa_dev, "%s: Failed to add controls\n", __func__);
+		return ret;
+	}
+
+	ret = snd_soc_dapm_add_routes(dapm, wsa_audio_map,
+					ARRAY_SIZE(wsa_audio_map));
+	if (ret < 0) {
+		dev_err(wsa_dev, "%s: Failed to add routes\n", __func__);
+		return ret;
+	}
+
+	ret = snd_soc_dapm_new_widgets(dapm->card);
+	if (ret < 0) {
+		dev_err(wsa_dev, "%s: Failed to add widgets\n", __func__);
+		return ret;
+	}
+
+	ret = snd_soc_add_component_controls(component, lpass_cdc_wsa_macro_snd_controls,
+				   ARRAY_SIZE(lpass_cdc_wsa_macro_snd_controls));
+	if (ret < 0) {
+		dev_err(wsa_dev, "%s: Failed to add snd_ctls\n", __func__);
+		return ret;
+	}
+	snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF1 Playback");
+	snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_MIX1 Playback");
+	snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_VI Capture");
+	snd_soc_dapm_ignore_suspend(dapm, "WSA_AIF_ECHO Capture");
+	snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK1 OUT");
+	snd_soc_dapm_ignore_suspend(dapm, "WSA_SPK2 OUT");
+	snd_soc_dapm_ignore_suspend(dapm, "VIINPUT_WSA");
+	snd_soc_dapm_ignore_suspend(dapm, "WSA SRC0_INP");
+	snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC0_INP");
+	snd_soc_dapm_ignore_suspend(dapm, "WSA_TX DEC1_INP");
+	snd_soc_dapm_sync(dapm);
+
+	wsa_priv->component = component;
+	wsa_priv->spkr_gain_offset = LPASS_CDC_WSA_MACRO_GAIN_OFFSET_0_DB;
+	lpass_cdc_wsa_macro_init_reg(component);
+
+	return 0;
+}
+
+static int lpass_cdc_wsa_macro_deinit(struct snd_soc_component *component)
+{
+	struct device *wsa_dev = NULL;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv = NULL;
+
+	if (!lpass_cdc_wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	wsa_priv->component = NULL;
+
+	return 0;
+}
+
+static void lpass_cdc_wsa_macro_add_child_devices(struct work_struct *work)
+{
+	struct lpass_cdc_wsa_macro_priv *wsa_priv;
+	struct platform_device *pdev;
+	struct device_node *node;
+	struct lpass_cdc_wsa_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
+	int ret;
+	u16 count = 0, ctrl_num = 0;
+	struct lpass_cdc_wsa_macro_swr_ctrl_platform_data *platdata;
+	char plat_dev_name[LPASS_CDC_WSA_MACRO_SWR_STRING_LEN];
+
+	wsa_priv = container_of(work, struct lpass_cdc_wsa_macro_priv,
+			     lpass_cdc_wsa_macro_add_child_devices_work);
+	if (!wsa_priv) {
+		pr_err("%s: Memory for wsa_priv does not exist\n",
+			__func__);
+		return;
+	}
+	if (!wsa_priv->dev || !wsa_priv->dev->of_node) {
+		dev_err(wsa_priv->dev,
+			"%s: DT node for wsa_priv does not exist\n", __func__);
+		return;
+	}
+
+	platdata = &wsa_priv->swr_plat_data;
+	wsa_priv->child_count = 0;
+
+	for_each_available_child_of_node(wsa_priv->dev->of_node, node) {
+		if (strnstr(node->name, "wsa_swr_master",
+				strlen("wsa_swr_master")) != NULL)
+			strlcpy(plat_dev_name, "wsa_swr_ctrl",
+				(LPASS_CDC_WSA_MACRO_SWR_STRING_LEN - 1));
+		else if (strnstr(node->name, "msm_cdc_pinctrl",
+				 strlen("msm_cdc_pinctrl")) != NULL)
+			strlcpy(plat_dev_name, node->name,
+				(LPASS_CDC_WSA_MACRO_SWR_STRING_LEN - 1));
+		else
+			continue;
+
+		pdev = platform_device_alloc(plat_dev_name, -1);
+		if (!pdev) {
+			dev_err(wsa_priv->dev, "%s: pdev memory alloc failed\n",
+				__func__);
+			ret = -ENOMEM;
+			goto err;
+		}
+		pdev->dev.parent = wsa_priv->dev;
+		pdev->dev.of_node = node;
+
+		if (strnstr(node->name, "wsa_swr_master",
+				strlen("wsa_swr_master")) != NULL) {
+			ret = platform_device_add_data(pdev, platdata,
+						       sizeof(*platdata));
+			if (ret) {
+				dev_err(&pdev->dev,
+					"%s: cannot add plat data ctrl:%d\n",
+					__func__, ctrl_num);
+				goto fail_pdev_add;
+			}
+		}
+
+		ret = platform_device_add(pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"%s: Cannot add platform device\n",
+				__func__);
+			goto fail_pdev_add;
+		}
+
+		if (!strcmp(node->name, "wsa_swr_master")) {
+			temp = krealloc(swr_ctrl_data,
+					(ctrl_num + 1) * sizeof(
+					struct lpass_cdc_wsa_macro_swr_ctrl_data),
+					GFP_KERNEL);
+			if (!temp) {
+				dev_err(&pdev->dev, "out of memory\n");
+				ret = -ENOMEM;
+				goto err;
+			}
+			swr_ctrl_data = temp;
+			swr_ctrl_data[ctrl_num].wsa_swr_pdev = pdev;
+			ctrl_num++;
+			dev_dbg(&pdev->dev,
+				"%s: Added soundwire ctrl device(s)\n",
+				__func__);
+			wsa_priv->swr_ctrl_data = swr_ctrl_data;
+		}
+		if (wsa_priv->child_count < LPASS_CDC_WSA_MACRO_CHILD_DEVICES_MAX)
+			wsa_priv->pdev_child_devices[
+					wsa_priv->child_count++] = pdev;
+		else
+			goto err;
+	}
+
+	return;
+fail_pdev_add:
+	for (count = 0; count < wsa_priv->child_count; count++)
+		platform_device_put(wsa_priv->pdev_child_devices[count]);
+err:
+	return;
+}
+
+static void lpass_cdc_wsa_macro_init_ops(struct macro_ops *ops,
+			       char __iomem *wsa_io_base)
+{
+	memset(ops, 0, sizeof(struct macro_ops));
+	ops->init = lpass_cdc_wsa_macro_init;
+	ops->exit = lpass_cdc_wsa_macro_deinit;
+	ops->io_base = wsa_io_base;
+	ops->dai_ptr = lpass_cdc_wsa_macro_dai;
+	ops->num_dais = ARRAY_SIZE(lpass_cdc_wsa_macro_dai);
+	ops->event_handler = lpass_cdc_wsa_macro_event_handler;
+	ops->set_port_map = lpass_cdc_wsa_macro_set_port_map;
+}
+
+static int lpass_cdc_wsa_macro_probe(struct platform_device *pdev)
+{
+	struct macro_ops ops;
+	struct lpass_cdc_wsa_macro_priv *wsa_priv;
+	u32 wsa_base_addr, default_clk_id;
+	char __iomem *wsa_io_base;
+	int ret = 0;
+	u8 bcl_pmic_params[3];
+	u32 is_used_wsa_swr_gpio = 1;
+	const char *is_used_wsa_swr_gpio_dt = "qcom,is-used-swr-gpio";
+
+	if (!lpass_cdc_is_va_macro_registered(&pdev->dev)) {
+		dev_err(&pdev->dev,
+			"%s: va-macro not registered yet, defer\n", __func__);
+		return -EPROBE_DEFER;
+	}
+
+	wsa_priv = devm_kzalloc(&pdev->dev, sizeof(struct lpass_cdc_wsa_macro_priv),
+				GFP_KERNEL);
+	if (!wsa_priv)
+		return -ENOMEM;
+
+	wsa_priv->dev = &pdev->dev;
+	ret = of_property_read_u32(pdev->dev.of_node, "reg",
+				   &wsa_base_addr);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
+			__func__, "reg");
+		return ret;
+	}
+	if (of_find_property(pdev->dev.of_node, is_used_wsa_swr_gpio_dt,
+			     NULL)) {
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   is_used_wsa_swr_gpio_dt,
+					   &is_used_wsa_swr_gpio);
+		if (ret) {
+			dev_err(&pdev->dev, "%s: error reading %s in dt\n",
+				__func__, is_used_wsa_swr_gpio_dt);
+			is_used_wsa_swr_gpio = 1;
+		}
+	}
+	wsa_priv->wsa_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
+					"qcom,wsa-swr-gpios", 0);
+	if (!wsa_priv->wsa_swr_gpio_p && is_used_wsa_swr_gpio) {
+		dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
+			__func__);
+		return -EINVAL;
+	}
+	if (msm_cdc_pinctrl_get_state(wsa_priv->wsa_swr_gpio_p) < 0 &&
+			is_used_wsa_swr_gpio) {
+		dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
+			__func__);
+		return -EPROBE_DEFER;
+	}
+	msm_cdc_pinctrl_set_wakeup_capable(
+				wsa_priv->wsa_swr_gpio_p, false);
+
+	wsa_io_base = devm_ioremap(&pdev->dev,
+				   wsa_base_addr, LPASS_CDC_WSA_MACRO_MAX_OFFSET);
+	if (!wsa_io_base) {
+		dev_err(&pdev->dev, "%s: ioremap failed\n", __func__);
+		return -EINVAL;
+	}
+	wsa_priv->wsa_io_base = wsa_io_base;
+	wsa_priv->reset_swr = true;
+	INIT_WORK(&wsa_priv->lpass_cdc_wsa_macro_add_child_devices_work,
+		  lpass_cdc_wsa_macro_add_child_devices);
+	wsa_priv->swr_plat_data.handle = (void *) wsa_priv;
+	wsa_priv->swr_plat_data.read = NULL;
+	wsa_priv->swr_plat_data.write = NULL;
+	wsa_priv->swr_plat_data.bulk_write = NULL;
+	wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
+	wsa_priv->swr_plat_data.core_vote = lpass_cdc_wsa_macro_core_vote;
+	wsa_priv->swr_plat_data.handle_irq = NULL;
+
+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
+				   &default_clk_id);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: could not find %s entry in dt\n",
+			__func__, "qcom,mux0-clk-id");
+		default_clk_id = WSA_CORE_CLK;
+	}
+
+	ret = of_property_read_u8_array(pdev->dev.of_node,
+				"qcom,wsa-bcl-pmic-params", bcl_pmic_params,
+				sizeof(bcl_pmic_params));
+	if (ret) {
+		dev_dbg(&pdev->dev, "%s: could not find %s entry in dt\n",
+			__func__, "qcom,wsa-bcl-pmic-params");
+	} else {
+		wsa_priv->bcl_pmic_params.id = bcl_pmic_params[0];
+		wsa_priv->bcl_pmic_params.sid = bcl_pmic_params[1];
+		wsa_priv->bcl_pmic_params.ppid = bcl_pmic_params[2];
+	}
+	wsa_priv->default_clk_id  = default_clk_id;
+
+	dev_set_drvdata(&pdev->dev, wsa_priv);
+	mutex_init(&wsa_priv->mclk_lock);
+	mutex_init(&wsa_priv->swr_clk_lock);
+	lpass_cdc_wsa_macro_init_ops(&ops, wsa_io_base);
+	ops.clk_id_req = wsa_priv->default_clk_id;
+	ops.default_clk_id = wsa_priv->default_clk_id;
+
+	ret = lpass_cdc_register_macro(&pdev->dev, WSA_MACRO, &ops);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
+		goto reg_macro_fail;
+	}
+	schedule_work(&wsa_priv->lpass_cdc_wsa_macro_add_child_devices_work);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+	pm_suspend_ignore_children(&pdev->dev, true);
+	pm_runtime_enable(&pdev->dev);
+
+	return ret;
+reg_macro_fail:
+	mutex_destroy(&wsa_priv->mclk_lock);
+	mutex_destroy(&wsa_priv->swr_clk_lock);
+	return ret;
+}
+
+static int lpass_cdc_wsa_macro_remove(struct platform_device *pdev)
+{
+	struct lpass_cdc_wsa_macro_priv *wsa_priv;
+	u16 count = 0;
+
+	wsa_priv = dev_get_drvdata(&pdev->dev);
+
+	if (!wsa_priv)
+		return -EINVAL;
+
+	for (count = 0; count < wsa_priv->child_count &&
+		count < LPASS_CDC_WSA_MACRO_CHILD_DEVICES_MAX; count++)
+		platform_device_unregister(wsa_priv->pdev_child_devices[count]);
+
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+	lpass_cdc_unregister_macro(&pdev->dev, WSA_MACRO);
+	mutex_destroy(&wsa_priv->mclk_lock);
+	mutex_destroy(&wsa_priv->swr_clk_lock);
+	return 0;
+}
+
+static const struct of_device_id lpass_cdc_wsa_macro_dt_match[] = {
+	{.compatible = "qcom,lpass-cdc-wsa-macro"},
+	{}
+};
+
+static const struct dev_pm_ops lpass_cdc_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(
+		pm_runtime_force_suspend,
+		pm_runtime_force_resume
+	)
+	SET_RUNTIME_PM_OPS(
+		lpass_cdc_runtime_suspend,
+		lpass_cdc_runtime_resume,
+		NULL
+	)
+};
+
+static struct platform_driver lpass_cdc_wsa_macro_driver = {
+	.driver = {
+		.name = "lpass_cdc_wsa_macro",
+		.owner = THIS_MODULE,
+		.pm = &lpass_cdc_dev_pm_ops,
+		.of_match_table = lpass_cdc_wsa_macro_dt_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = lpass_cdc_wsa_macro_probe,
+	.remove = lpass_cdc_wsa_macro_remove,
+};
+
+module_platform_driver(lpass_cdc_wsa_macro_driver);
+
+MODULE_DESCRIPTION("WSA macro driver");
+MODULE_LICENSE("GPL v2");

+ 41 - 0
asoc/codecs/lpass-cdc/lpass-cdc-wsa-macro.h

@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+#ifndef LPASS_CDC_WSA_MACRO_H
+#define LPASS_CDC_WSA_MACRO_H
+
+/*
+ * Selects compander and smart boost settings
+ * for a given speaker mode
+ */
+enum {
+	LPASS_CDC_WSA_MACRO_SPKR_MODE_DEFAULT,
+	LPASS_CDC_WSA_MACRO_SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */
+};
+
+/* Rx path gain offsets */
+enum {
+	LPASS_CDC_WSA_MACRO_GAIN_OFFSET_M1P5_DB,
+	LPASS_CDC_WSA_MACRO_GAIN_OFFSET_0_DB,
+};
+
+
+#if IS_ENABLED(CONFIG_WSA_MACRO)
+extern int lpass_cdc_wsa_macro_set_spkr_mode(struct snd_soc_component *component,
+				   int mode);
+extern int lpass_cdc_wsa_macro_set_spkr_gain_offset(struct snd_soc_component *component,
+					  int offset);
+#else /* CONFIG_WSA_MACRO */
+static inline int lpass_cdc_wsa_macro_set_spkr_mode(struct snd_soc_component *component,
+					  int mode)
+{
+	return 0;
+}
+static inline int lpass_cdc_wsa_macro_set_spkr_gain_offset(
+				struct snd_soc_component *component,
+				int offset)
+{
+	return 0;
+}
+#endif /* CONFIG_WSA_MACRO */
+#endif

+ 1546 - 0
asoc/codecs/lpass-cdc/lpass-cdc.c

@@ -0,0 +1,1546 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/of_platform.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <soc/snd_event.h>
+#include <linux/pm_runtime.h>
+#include <soc/swr-common.h>
+#include <dsp/digital-cdc-rsc-mgr.h>
+#include "lpass-cdc.h"
+#include "internal.h"
+#include "lpass-cdc-clk-rsc.h"
+
+#define DRV_NAME "lpass_cdc"
+
+#define LPASS_CDC_VERSION_ENTRY_SIZE 32
+#define LPASS_CDC_STRING_LEN 80
+
+static const struct snd_soc_component_driver lpass_cdc;
+
+/* pm runtime auto suspend timer in msecs */
+#define LPASS_CDC_AUTO_SUSPEND_DELAY          100 /* delay in msec */
+
+/* MCLK_MUX table for all macros */
+static u16 lpass_cdc_mclk_mux_tbl[MAX_MACRO][MCLK_MUX_MAX] = {
+	{TX_MACRO, VA_MACRO},
+	{TX_MACRO, RX_MACRO},
+	{TX_MACRO, WSA_MACRO},
+	{TX_MACRO, VA_MACRO},
+};
+
+static bool lpass_cdc_is_valid_codec_dev(struct device *dev);
+
+int lpass_cdc_set_port_map(struct snd_soc_component *component,
+			u32 size, void *data)
+{
+	struct lpass_cdc_priv *priv = NULL;
+	struct swr_mstr_port_map *map = NULL;
+	u16 idx;
+
+	if (!component || (size == 0) || !data)
+		return -EINVAL;
+
+	priv = snd_soc_component_get_drvdata(component);
+	if (!priv)
+		return -EINVAL;
+
+	if (!lpass_cdc_is_valid_codec_dev(priv->dev)) {
+		dev_err(priv->dev, "%s: invalid codec\n", __func__);
+		return -EINVAL;
+	}
+	map = (struct swr_mstr_port_map *)data;
+
+	for (idx = 0; idx < size; idx++) {
+		if (priv->macro_params[map->id].set_port_map)
+			priv->macro_params[map->id].set_port_map(component,
+						map->uc,
+						SWR_MSTR_PORT_LEN,
+						map->swr_port_params);
+		map += 1;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(lpass_cdc_set_port_map);
+
+static void lpass_cdc_ahb_write_device(char __iomem *io_base,
+				    u16 reg, u8 value)
+{
+	u32 temp = (u32)(value) & 0x000000FF;
+
+	iowrite32(temp, io_base + reg);
+}
+
+static void lpass_cdc_ahb_read_device(char __iomem *io_base,
+				   u16 reg, u8 *value)
+{
+	u32 temp;
+
+	temp = ioread32(io_base + reg);
+	*value = (u8)temp;
+}
+
+static int __lpass_cdc_reg_read(struct lpass_cdc_priv *priv,
+			     u16 macro_id, u16 reg, u8 *val)
+{
+	int ret = 0;
+
+	mutex_lock(&priv->clk_lock);
+	if (!priv->dev_up) {
+		dev_dbg_ratelimited(priv->dev,
+			"%s: SSR in progress, exit\n", __func__);
+		ret = -EINVAL;
+		goto ssr_err;
+	}
+
+	if (priv->macro_params[VA_MACRO].dev) {
+		pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev);
+		if (!lpass_cdc_check_core_votes(priv->macro_params[VA_MACRO].dev))
+			goto ssr_err;
+	}
+
+	if (priv->version < LPASS_CDC_VERSION_2_0) {
+		/* Request Clk before register access */
+		ret = lpass_cdc_clk_rsc_request_clock(priv->macro_params[macro_id].dev,
+				priv->macro_params[macro_id].default_clk_id,
+				priv->macro_params[macro_id].clk_id_req,
+				true);
+		if (ret < 0) {
+			dev_err_ratelimited(priv->dev,
+				"%s: Failed to enable clock, ret:%d\n",
+				__func__, ret);
+			goto err;
+		}
+	}
+
+	lpass_cdc_ahb_read_device(
+		priv->macro_params[macro_id].io_base, reg, val);
+
+	if (priv->version < LPASS_CDC_VERSION_2_0)
+		lpass_cdc_clk_rsc_request_clock(priv->macro_params[macro_id].dev,
+				priv->macro_params[macro_id].default_clk_id,
+				priv->macro_params[macro_id].clk_id_req,
+				false);
+
+err:
+	if (priv->macro_params[VA_MACRO].dev) {
+		pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev);
+		pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev);
+	}
+ssr_err:
+	mutex_unlock(&priv->clk_lock);
+	return ret;
+}
+
+static int __lpass_cdc_reg_write(struct lpass_cdc_priv *priv,
+			      u16 macro_id, u16 reg, u8 val)
+{
+	int ret = 0;
+
+	mutex_lock(&priv->clk_lock);
+	if (!priv->dev_up) {
+		dev_dbg_ratelimited(priv->dev,
+			"%s: SSR in progress, exit\n", __func__);
+		ret = -EINVAL;
+		goto ssr_err;
+	}
+	if (priv->macro_params[VA_MACRO].dev) {
+		pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev);
+		if (!lpass_cdc_check_core_votes(priv->macro_params[VA_MACRO].dev))
+			goto ssr_err;
+	}
+
+	if (priv->version < LPASS_CDC_VERSION_2_0) {
+		/* Request Clk before register access */
+		ret = lpass_cdc_clk_rsc_request_clock(priv->macro_params[macro_id].dev,
+				priv->macro_params[macro_id].default_clk_id,
+				priv->macro_params[macro_id].clk_id_req,
+				true);
+		if (ret < 0) {
+			dev_err_ratelimited(priv->dev,
+				"%s: Failed to enable clock, ret:%d\n",
+				__func__, ret);
+			goto err;
+		}
+	}
+
+	lpass_cdc_ahb_write_device(
+			priv->macro_params[macro_id].io_base, reg, val);
+
+	if (priv->version < LPASS_CDC_VERSION_2_0)
+		lpass_cdc_clk_rsc_request_clock(priv->macro_params[macro_id].dev,
+				priv->macro_params[macro_id].default_clk_id,
+				priv->macro_params[macro_id].clk_id_req,
+				false);
+
+err:
+	if (priv->macro_params[VA_MACRO].dev) {
+		pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev);
+		pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev);
+	}
+ssr_err:
+	mutex_unlock(&priv->clk_lock);
+	return ret;
+}
+
+static int lpass_cdc_update_wcd_event(void *handle, u16 event, u32 data)
+{
+	struct lpass_cdc_priv *priv = (struct lpass_cdc_priv *)handle;
+
+	if (!priv) {
+		pr_err("%s:Invalid lpass_cdc priv handle\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (event) {
+	case WCD_LPASS_CDC_EVT_RX_MUTE:
+		if (priv->macro_params[RX_MACRO].event_handler)
+			priv->macro_params[RX_MACRO].event_handler(
+				priv->component,
+				LPASS_CDC_MACRO_EVT_RX_MUTE, data);
+		break;
+	case WCD_LPASS_CDC_EVT_IMPED_TRUE:
+		if (priv->macro_params[RX_MACRO].event_handler)
+			priv->macro_params[RX_MACRO].event_handler(
+				priv->component,
+				LPASS_CDC_MACRO_EVT_IMPED_TRUE, data);
+		break;
+	case WCD_LPASS_CDC_EVT_IMPED_FALSE:
+		if (priv->macro_params[RX_MACRO].event_handler)
+			priv->macro_params[RX_MACRO].event_handler(
+				priv->component,
+				LPASS_CDC_MACRO_EVT_IMPED_FALSE, data);
+		break;
+	case WCD_LPASS_CDC_EVT_RX_COMPANDER_SOFT_RST:
+		if (priv->macro_params[RX_MACRO].event_handler)
+			priv->macro_params[RX_MACRO].event_handler(
+				priv->component,
+				LPASS_CDC_MACRO_EVT_RX_COMPANDER_SOFT_RST, data);
+		break;
+	case WCD_LPASS_CDC_EVT_BCS_CLK_OFF:
+		if (priv->macro_params[TX_MACRO].event_handler)
+			priv->macro_params[TX_MACRO].event_handler(
+				priv->component,
+				LPASS_CDC_MACRO_EVT_BCS_CLK_OFF, data);
+		break;
+	case WCD_LPASS_CDC_EVT_RX_PA_GAIN_UPDATE:
+		/* Update PA Gain only for lpass_cdc version 2.1 */
+		if (priv->version == LPASS_CDC_VERSION_2_1)
+			if (priv->macro_params[RX_MACRO].event_handler)
+				priv->macro_params[RX_MACRO].event_handler(
+					priv->component,
+					LPASS_CDC_MACRO_EVT_RX_PA_GAIN_UPDATE,
+					data);
+		break;
+	case WCD_LPASS_CDC_EVT_HPHL_HD2_ENABLE:
+		if (priv->macro_params[RX_MACRO].event_handler)
+			priv->macro_params[RX_MACRO].event_handler(
+				priv->component,
+				LPASS_CDC_MACRO_EVT_HPHL_HD2_ENABLE, data);
+		break;
+	case WCD_LPASS_CDC_EVT_HPHR_HD2_ENABLE:
+		if (priv->macro_params[RX_MACRO].event_handler)
+			priv->macro_params[RX_MACRO].event_handler(
+				priv->component,
+				LPASS_CDC_MACRO_EVT_HPHR_HD2_ENABLE, data);
+		break;
+	default:
+		dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n",
+			__func__, event);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int lpass_cdc_register_notifier(void *handle,
+					struct notifier_block *nblock,
+					bool enable)
+{
+	struct lpass_cdc_priv *priv = (struct lpass_cdc_priv *)handle;
+
+	if (!priv) {
+		pr_err("%s: lpass_cdc priv is null\n", __func__);
+		return -EINVAL;
+	}
+	if (enable)
+		return blocking_notifier_chain_register(&priv->notifier,
+							nblock);
+
+	return blocking_notifier_chain_unregister(&priv->notifier,
+						  nblock);
+}
+
+static void lpass_cdc_notifier_call(struct lpass_cdc_priv *priv,
+				     u32 data)
+{
+	dev_dbg(priv->dev, "%s: notifier call, data:%d\n", __func__, data);
+	blocking_notifier_call_chain(&priv->notifier,
+				     data, (void *)priv->wcd_dev);
+}
+
+static bool lpass_cdc_is_valid_child_dev(struct device *dev)
+{
+	if (of_device_is_compatible(dev->parent->of_node, "qcom,lpass-cdc"))
+		return true;
+
+	return false;
+}
+
+static bool lpass_cdc_is_valid_codec_dev(struct device *dev)
+{
+	if (of_device_is_compatible(dev->of_node, "qcom,lpass-cdc"))
+		return true;
+
+	return false;
+}
+
+/**
+ * lpass_cdc_clear_amic_tx_hold - clears AMIC register on analog codec
+ *
+ * @dev: lpass_cdc device ptr.
+ *
+ */
+void lpass_cdc_clear_amic_tx_hold(struct device *dev, u16 adc_n)
+{
+	struct lpass_cdc_priv *priv;
+	u16 event;
+	u16 amic = 0;
+
+	if (!dev) {
+		pr_err("%s: dev is null\n", __func__);
+		return;
+	}
+
+	if (!lpass_cdc_is_valid_codec_dev(dev)) {
+		pr_err("%s: invalid codec\n", __func__);
+		return;
+	}
+	priv = dev_get_drvdata(dev);
+	if (!priv) {
+		dev_err(dev, "%s: priv is null\n", __func__);
+		return;
+	}
+	event = LPASS_CDC_WCD_EVT_TX_CH_HOLD_CLEAR;
+	if (adc_n == LPASS_CDC_ADC0)
+		amic = 0x1;
+	else if (adc_n == LPASS_CDC_ADC1)
+		amic = 0x2;
+	else if (adc_n == LPASS_CDC_ADC2)
+		amic = 0x2;
+	else if (adc_n == LPASS_CDC_ADC3)
+		amic = 0x3;
+	else
+		return;
+
+	lpass_cdc_notifier_call(priv, (amic << 0x10 | event));
+}
+EXPORT_SYMBOL(lpass_cdc_clear_amic_tx_hold);
+
+/**
+ * lpass_cdc_get_device_ptr - Get child or macro device ptr
+ *
+ * @dev: lpass_cdc device ptr.
+ * @macro_id: ID of macro calling this API.
+ *
+ * Returns dev ptr on success or NULL on error.
+ */
+struct device *lpass_cdc_get_device_ptr(struct device *dev, u16 macro_id)
+{
+	struct lpass_cdc_priv *priv;
+
+	if (!dev) {
+		pr_err("%s: dev is null\n", __func__);
+		return NULL;
+	}
+
+	if (!lpass_cdc_is_valid_codec_dev(dev)) {
+		pr_err("%s: invalid codec\n", __func__);
+		return NULL;
+	}
+	priv = dev_get_drvdata(dev);
+	if (!priv || (macro_id >= MAX_MACRO)) {
+		dev_err(dev, "%s: priv is null or invalid macro\n", __func__);
+		return NULL;
+	}
+
+	return priv->macro_params[macro_id].dev;
+}
+EXPORT_SYMBOL(lpass_cdc_get_device_ptr);
+
+/**
+ * lpass_cdc_get_rsc_clk_device_ptr - Get rsc clk device ptr
+ *
+ * @dev: lpass_cdc device ptr.
+ *
+ * Returns dev ptr on success or NULL on error.
+ */
+struct device *lpass_cdc_get_rsc_clk_device_ptr(struct device *dev)
+{
+	struct lpass_cdc_priv *priv;
+
+	if (!dev) {
+		pr_err("%s: dev is null\n", __func__);
+		return NULL;
+	}
+
+	if (!lpass_cdc_is_valid_codec_dev(dev)) {
+		pr_err("%s: invalid codec\n", __func__);
+		return NULL;
+	}
+	priv = dev_get_drvdata(dev);
+	if (!priv) {
+		dev_err(dev, "%s: priv is null\n", __func__);
+		return NULL;
+	}
+
+	return priv->clk_dev;
+}
+EXPORT_SYMBOL(lpass_cdc_get_rsc_clk_device_ptr);
+
+static int lpass_cdc_copy_dais_from_macro(struct lpass_cdc_priv *priv)
+{
+	struct snd_soc_dai_driver *dai_ptr;
+	u16 macro_idx;
+
+	/* memcpy into lpass_cdc_dais all macro dais */
+	if (!priv->lpass_cdc_dais)
+		priv->lpass_cdc_dais = devm_kzalloc(priv->dev,
+						priv->num_dais *
+						sizeof(
+						struct snd_soc_dai_driver),
+						GFP_KERNEL);
+	if (!priv->lpass_cdc_dais)
+		return -ENOMEM;
+
+	dai_ptr = priv->lpass_cdc_dais;
+
+	for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
+		if (priv->macro_params[macro_idx].dai_ptr) {
+			memcpy(dai_ptr,
+			       priv->macro_params[macro_idx].dai_ptr,
+			       priv->macro_params[macro_idx].num_dais *
+			       sizeof(struct snd_soc_dai_driver));
+			dai_ptr += priv->macro_params[macro_idx].num_dais;
+		}
+	}
+	return 0;
+}
+
+/**
+ * lpass_cdc_register_res_clk - Registers rsc clk driver to lpass_cdc
+ *
+ * @dev: rsc clk device ptr.
+ * @rsc_clk_cb: event handler callback for notifications like SSR
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int lpass_cdc_register_res_clk(struct device *dev, rsc_clk_cb_t rsc_clk_cb)
+{
+	struct lpass_cdc_priv *priv;
+
+	if (!dev || !rsc_clk_cb) {
+		pr_err("%s: dev or rsc_clk_cb is null\n", __func__);
+		return -EINVAL;
+	}
+	if (!lpass_cdc_is_valid_child_dev(dev)) {
+		dev_err(dev, "%s: child device :%pK not added yet\n",
+			__func__, dev);
+		return -EINVAL;
+	}
+	priv = dev_get_drvdata(dev->parent);
+	if (!priv) {
+		dev_err(dev, "%s: priv is null\n", __func__);
+		return -EINVAL;
+	}
+
+	priv->clk_dev = dev;
+	priv->rsc_clk_cb = rsc_clk_cb;
+
+	return 0;
+}
+EXPORT_SYMBOL(lpass_cdc_register_res_clk);
+
+/**
+ * lpass_cdc_unregister_res_clk - Unregisters rsc clk driver from lpass_cdc
+ *
+ * @dev: resource clk device ptr.
+ */
+void lpass_cdc_unregister_res_clk(struct device *dev)
+{
+	struct lpass_cdc_priv *priv;
+
+	if (!dev) {
+		pr_err("%s: dev is NULL\n", __func__);
+		return;
+	}
+	if (!lpass_cdc_is_valid_child_dev(dev)) {
+		dev_err(dev, "%s: child device :%pK not added\n",
+			__func__, dev);
+		return;
+	}
+	priv = dev_get_drvdata(dev->parent);
+	if (!priv) {
+		dev_err(dev, "%s: priv is null\n", __func__);
+		return;
+	}
+
+	priv->clk_dev = NULL;
+	priv->rsc_clk_cb = NULL;
+}
+EXPORT_SYMBOL(lpass_cdc_unregister_res_clk);
+
+static u8 lpass_cdc_dmic_clk_div_get(struct snd_soc_component *component,
+				   int mode)
+{
+	struct lpass_cdc_priv* priv = snd_soc_component_get_drvdata(component);
+	int macro = (mode ? VA_MACRO : TX_MACRO);
+	int ret = 0;
+
+	if (priv->macro_params[macro].clk_div_get) {
+		ret = priv->macro_params[macro].clk_div_get(component);
+		if (ret > 0)
+			return ret;
+	}
+
+	return 1;
+}
+
+int lpass_cdc_dmic_clk_enable(struct snd_soc_component *component,
+			   u32 dmic, u32 tx_mode, bool enable)
+{
+	struct lpass_cdc_priv* priv = snd_soc_component_get_drvdata(component);
+	u8  dmic_clk_en = 0x01;
+	u16 dmic_clk_reg = 0;
+	s32 *dmic_clk_cnt = NULL;
+	u8 *dmic_clk_div = NULL;
+	u8 freq_change_mask = 0;
+	u8 clk_div = 0;
+
+	dev_dbg(component->dev, "%s: enable: %d, tx_mode:%d, dmic: %d\n",
+		__func__, enable, tx_mode, dmic);
+
+	switch (dmic) {
+	case 0:
+	case 1:
+		dmic_clk_cnt = &(priv->dmic_0_1_clk_cnt);
+		dmic_clk_div = &(priv->dmic_0_1_clk_div);
+		dmic_clk_reg = LPASS_CDC_VA_TOP_CSR_DMIC0_CTL;
+		freq_change_mask = 0x01;
+		break;
+	case 2:
+	case 3:
+		dmic_clk_cnt = &(priv->dmic_2_3_clk_cnt);
+		dmic_clk_div = &(priv->dmic_2_3_clk_div);
+		dmic_clk_reg = LPASS_CDC_VA_TOP_CSR_DMIC1_CTL;
+		freq_change_mask = 0x02;
+		break;
+	case 4:
+	case 5:
+		dmic_clk_cnt = &(priv->dmic_4_5_clk_cnt);
+		dmic_clk_div = &(priv->dmic_4_5_clk_div);
+		dmic_clk_reg = LPASS_CDC_VA_TOP_CSR_DMIC2_CTL;
+		freq_change_mask = 0x04;
+		break;
+	case 6:
+	case 7:
+		dmic_clk_cnt = &(priv->dmic_6_7_clk_cnt);
+		dmic_clk_div = &(priv->dmic_6_7_clk_div);
+		dmic_clk_reg = LPASS_CDC_VA_TOP_CSR_DMIC3_CTL;
+		freq_change_mask = 0x08;
+		break;
+	default:
+		dev_err(component->dev, "%s: Invalid DMIC Selection\n",
+			__func__);
+		return -EINVAL;
+	}
+	dev_dbg(component->dev, "%s: DMIC%d dmic_clk_cnt %d\n",
+			__func__, dmic, *dmic_clk_cnt);
+	if (enable) {
+		clk_div = lpass_cdc_dmic_clk_div_get(component, tx_mode);
+		(*dmic_clk_cnt)++;
+		if (*dmic_clk_cnt == 1) {
+			snd_soc_component_update_bits(component,
+					LPASS_CDC_VA_TOP_CSR_DMIC_CFG,
+					0x80, 0x00);
+			snd_soc_component_update_bits(component, dmic_clk_reg,
+						0x0E, clk_div << 0x1);
+			snd_soc_component_update_bits(component, dmic_clk_reg,
+					dmic_clk_en, dmic_clk_en);
+		} else {
+			if (*dmic_clk_div > clk_div) {
+				snd_soc_component_update_bits(component,
+						LPASS_CDC_VA_TOP_CSR_DMIC_CFG,
+						freq_change_mask, freq_change_mask);
+				snd_soc_component_update_bits(component, dmic_clk_reg,
+						0x0E, clk_div << 0x1);
+				snd_soc_component_update_bits(component,
+						LPASS_CDC_VA_TOP_CSR_DMIC_CFG,
+						freq_change_mask, 0x00);
+			} else {
+				clk_div = *dmic_clk_div;
+			}
+		}
+		*dmic_clk_div = clk_div;
+	} else {
+		(*dmic_clk_cnt)--;
+		if (*dmic_clk_cnt  == 0) {
+			snd_soc_component_update_bits(component, dmic_clk_reg,
+					dmic_clk_en, 0);
+			clk_div = 0;
+			snd_soc_component_update_bits(component, dmic_clk_reg,
+							0x0E, clk_div << 0x1);
+		} else {
+			clk_div = lpass_cdc_dmic_clk_div_get(component, tx_mode);
+			if (*dmic_clk_div > clk_div) {
+				clk_div = lpass_cdc_dmic_clk_div_get(component, !tx_mode);
+				snd_soc_component_update_bits(component,
+							LPASS_CDC_VA_TOP_CSR_DMIC_CFG,
+							freq_change_mask, freq_change_mask);
+				snd_soc_component_update_bits(component, dmic_clk_reg,
+								0x0E, clk_div << 0x1);
+				snd_soc_component_update_bits(component,
+							LPASS_CDC_VA_TOP_CSR_DMIC_CFG,
+							freq_change_mask, 0x00);
+			} else {
+				clk_div = *dmic_clk_div;
+			}
+		}
+		*dmic_clk_div = clk_div;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(lpass_cdc_dmic_clk_enable);
+
+bool lpass_cdc_is_va_macro_registered(struct device *dev)
+{
+	struct lpass_cdc_priv *priv;
+
+	if (!dev) {
+		pr_err("%s: dev is null\n", __func__);
+		return false;
+	}
+	if (!lpass_cdc_is_valid_child_dev(dev)) {
+		dev_err(dev, "%s: child device calling is not added yet\n",
+			__func__);
+		return false;
+	}
+	priv = dev_get_drvdata(dev->parent);
+	if (!priv) {
+		dev_err(dev, "%s: priv is null\n", __func__);
+		return false;
+	}
+	return priv->macros_supported[VA_MACRO];
+}
+EXPORT_SYMBOL(lpass_cdc_is_va_macro_registered);
+
+/**
+ * lpass_cdc_register_macro - Registers macro to lpass_cdc
+ *
+ * @dev: macro device ptr.
+ * @macro_id: ID of macro calling this API.
+ * @ops: macro params to register.
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int lpass_cdc_register_macro(struct device *dev, u16 macro_id,
+			  struct macro_ops *ops)
+{
+	struct lpass_cdc_priv *priv;
+	int ret = -EINVAL;
+
+	if (!dev || !ops) {
+		pr_err("%s: dev or ops is null\n", __func__);
+		return -EINVAL;
+	}
+	if (!lpass_cdc_is_valid_child_dev(dev)) {
+		dev_err(dev, "%s: child device for macro:%d not added yet\n",
+			__func__, macro_id);
+		return -EINVAL;
+	}
+	priv = dev_get_drvdata(dev->parent);
+	if (!priv || (macro_id >= MAX_MACRO)) {
+		dev_err(dev, "%s: priv is null or invalid macro\n", __func__);
+		return -EINVAL;
+	}
+
+	priv->macro_params[macro_id].clk_id_req = ops->clk_id_req;
+	priv->macro_params[macro_id].default_clk_id = ops->default_clk_id;
+	priv->macro_params[macro_id].init = ops->init;
+	priv->macro_params[macro_id].exit = ops->exit;
+	priv->macro_params[macro_id].io_base = ops->io_base;
+	priv->macro_params[macro_id].num_dais = ops->num_dais;
+	priv->macro_params[macro_id].dai_ptr = ops->dai_ptr;
+	priv->macro_params[macro_id].event_handler = ops->event_handler;
+	priv->macro_params[macro_id].set_port_map = ops->set_port_map;
+	priv->macro_params[macro_id].dev = dev;
+	priv->current_mclk_mux_macro[macro_id] =
+				lpass_cdc_mclk_mux_tbl[macro_id][MCLK_MUX0];
+	if (macro_id == TX_MACRO) {
+		priv->macro_params[macro_id].reg_wake_irq = ops->reg_wake_irq;
+		priv->macro_params[macro_id].reg_evt_listener =
+							ops->reg_evt_listener;
+		priv->macro_params[macro_id].clk_enable = ops->clk_enable;
+	}
+	if (macro_id == TX_MACRO || macro_id == VA_MACRO)
+		priv->macro_params[macro_id].clk_div_get = ops->clk_div_get;
+
+	if (priv->version == LPASS_CDC_VERSION_2_1) {
+		if (macro_id == VA_MACRO)
+			priv->macro_params[macro_id].reg_wake_irq =
+						ops->reg_wake_irq;
+	}
+	priv->num_dais += ops->num_dais;
+	priv->num_macros_registered++;
+	priv->macros_supported[macro_id] = true;
+
+	dev_info(dev, "%s: register macro successful:%d\n", __func__, macro_id);
+
+	if (priv->num_macros_registered == priv->num_macros) {
+		ret = lpass_cdc_copy_dais_from_macro(priv);
+		if (ret < 0) {
+			dev_err(dev, "%s: copy_dais failed\n", __func__);
+			return ret;
+		}
+		if (priv->macros_supported[TX_MACRO] == false) {
+			lpass_cdc_mclk_mux_tbl[WSA_MACRO][MCLK_MUX0] = WSA_MACRO;
+			priv->current_mclk_mux_macro[WSA_MACRO] = WSA_MACRO;
+			lpass_cdc_mclk_mux_tbl[VA_MACRO][MCLK_MUX0] = VA_MACRO;
+			priv->current_mclk_mux_macro[VA_MACRO] = VA_MACRO;
+		}
+		ret = snd_soc_register_component(dev->parent, &lpass_cdc,
+				priv->lpass_cdc_dais, priv->num_dais);
+		if (ret < 0) {
+			dev_err(dev, "%s: register codec failed\n", __func__);
+			return ret;
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(lpass_cdc_register_macro);
+
+/**
+ * lpass_cdc_unregister_macro - De-Register macro from lpass_cdc
+ *
+ * @dev: macro device ptr.
+ * @macro_id: ID of macro calling this API.
+ *
+ */
+void lpass_cdc_unregister_macro(struct device *dev, u16 macro_id)
+{
+	struct lpass_cdc_priv *priv;
+
+	if (!dev) {
+		pr_err("%s: dev is null\n", __func__);
+		return;
+	}
+	if (!lpass_cdc_is_valid_child_dev(dev)) {
+		dev_err(dev, "%s: macro:%d not in valid registered macro-list\n",
+			__func__, macro_id);
+		return;
+	}
+	priv = dev_get_drvdata(dev->parent);
+	if (!priv || (macro_id >= MAX_MACRO)) {
+		dev_err(dev, "%s: priv is null or invalid macro\n", __func__);
+		return;
+	}
+
+	priv->macro_params[macro_id].init = NULL;
+	priv->macro_params[macro_id].num_dais = 0;
+	priv->macro_params[macro_id].dai_ptr = NULL;
+	priv->macro_params[macro_id].event_handler = NULL;
+	priv->macro_params[macro_id].dev = NULL;
+	if (macro_id == TX_MACRO) {
+		priv->macro_params[macro_id].reg_wake_irq = NULL;
+		priv->macro_params[macro_id].reg_evt_listener = NULL;
+		priv->macro_params[macro_id].clk_enable = NULL;
+	}
+	if (macro_id == TX_MACRO || macro_id == VA_MACRO)
+		priv->macro_params[macro_id].clk_div_get = NULL;
+
+	priv->num_dais -= priv->macro_params[macro_id].num_dais;
+	priv->num_macros_registered--;
+
+	/* UNREGISTER CODEC HERE */
+	if (priv->num_macros - 1 == priv->num_macros_registered)
+		snd_soc_unregister_component(dev->parent);
+}
+EXPORT_SYMBOL(lpass_cdc_unregister_macro);
+
+void lpass_cdc_wsa_pa_on(struct device *dev, bool adie_lb)
+{
+	struct lpass_cdc_priv *priv;
+
+	if (!dev) {
+		pr_err("%s: dev is null\n", __func__);
+		return;
+	}
+	if (!lpass_cdc_is_valid_child_dev(dev)) {
+		dev_err(dev, "%s: not a valid child dev\n",
+			__func__);
+		return;
+	}
+	priv = dev_get_drvdata(dev->parent);
+	if (!priv) {
+		dev_err(dev, "%s: priv is null\n", __func__);
+		return;
+	}
+	if (adie_lb)
+		lpass_cdc_notifier_call(priv,
+			LPASS_CDC_WCD_EVT_PA_ON_POST_FSCLK_ADIE_LB);
+	else
+		lpass_cdc_notifier_call(priv,
+			LPASS_CDC_WCD_EVT_PA_ON_POST_FSCLK);
+}
+EXPORT_SYMBOL(lpass_cdc_wsa_pa_on);
+
+int lpass_cdc_get_version(struct device *dev)
+{
+	struct lpass_cdc_priv *priv;
+
+	if (!dev) {
+		pr_err("%s: dev is null\n", __func__);
+		return -EINVAL;
+	}
+	if (!lpass_cdc_is_valid_child_dev(dev)) {
+		dev_err(dev, "%s: child device for macro not added yet\n",
+			__func__);
+		return -EINVAL;
+	}
+	priv = dev_get_drvdata(dev->parent);
+	if (!priv) {
+		dev_err(dev, "%s: priv is null\n", __func__);
+		return -EINVAL;
+	}
+	return priv->version;
+}
+EXPORT_SYMBOL(lpass_cdc_get_version);
+
+static ssize_t lpass_cdc_version_read(struct snd_info_entry *entry,
+				   void *file_private_data,
+				   struct file *file,
+				   char __user *buf, size_t count,
+				   loff_t pos)
+{
+	struct lpass_cdc_priv *priv;
+	char buffer[LPASS_CDC_VERSION_ENTRY_SIZE];
+	int len = 0;
+
+	priv = (struct lpass_cdc_priv *) entry->private_data;
+	if (!priv) {
+		pr_err("%s: lpass_cdc priv is null\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (priv->version) {
+	case LPASS_CDC_VERSION_1_0:
+		len = snprintf(buffer, sizeof(buffer), "LPASS_CDC_1_0\n");
+		break;
+	case LPASS_CDC_VERSION_1_1:
+		len = snprintf(buffer, sizeof(buffer), "LPASS_CDC_1_1\n");
+		break;
+	case LPASS_CDC_VERSION_1_2:
+		len = snprintf(buffer, sizeof(buffer), "LPASS_CDC_1_2\n");
+		break;
+	case LPASS_CDC_VERSION_2_1:
+		len = snprintf(buffer, sizeof(buffer), "LPASS_CDC_2_1\n");
+		break;
+	default:
+		len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
+	}
+
+	return simple_read_from_buffer(buf, count, &pos, buffer, len);
+}
+
+static int lpass_cdc_ssr_enable(struct device *dev, void *data)
+{
+	struct lpass_cdc_priv *priv = data;
+	int macro_idx;
+
+	if (priv->initial_boot) {
+		priv->initial_boot = false;
+		return 0;
+	}
+
+	if (priv->rsc_clk_cb)
+		priv->rsc_clk_cb(priv->clk_dev, LPASS_CDC_MACRO_EVT_SSR_UP);
+
+	for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
+		if (priv->macro_params[macro_idx].event_handler)
+			priv->macro_params[macro_idx].event_handler(
+				priv->component,
+				LPASS_CDC_MACRO_EVT_CLK_RESET, 0x0);
+	}
+	trace_printk("%s: clk count reset\n", __func__);
+
+	if (priv->rsc_clk_cb)
+		priv->rsc_clk_cb(priv->clk_dev, LPASS_CDC_MACRO_EVT_SSR_GFMUX_UP);
+
+	for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
+		if (!priv->macro_params[macro_idx].event_handler)
+			continue;
+		priv->macro_params[macro_idx].event_handler(
+			priv->component,
+			LPASS_CDC_MACRO_EVT_PRE_SSR_UP, 0x0);
+	}
+
+	regcache_cache_only(priv->regmap, false);
+	mutex_lock(&priv->clk_lock);
+	priv->dev_up = true;
+	mutex_unlock(&priv->clk_lock);
+	regcache_mark_dirty(priv->regmap);
+	lpass_cdc_clk_rsc_enable_all_clocks(priv->clk_dev, true);
+	regcache_sync(priv->regmap);
+	/* Add a 100usec sleep to ensure last register write is done */
+	usleep_range(100,110);
+	lpass_cdc_clk_rsc_enable_all_clocks(priv->clk_dev, false);
+	trace_printk("%s: regcache_sync done\n", __func__);
+	/* call ssr event for supported macros */
+	for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
+		if (!priv->macro_params[macro_idx].event_handler)
+			continue;
+		priv->macro_params[macro_idx].event_handler(
+			priv->component,
+			LPASS_CDC_MACRO_EVT_SSR_UP, 0x0);
+	}
+	trace_printk("%s: SSR up events processed by all macros\n", __func__);
+	lpass_cdc_notifier_call(priv, LPASS_CDC_WCD_EVT_SSR_UP);
+	return 0;
+}
+
+static void lpass_cdc_ssr_disable(struct device *dev, void *data)
+{
+	struct lpass_cdc_priv *priv = data;
+	int macro_idx;
+
+	if (!priv->dev_up) {
+		dev_err_ratelimited(priv->dev,
+				    "%s: already disabled\n", __func__);
+		return;
+	}
+
+	lpass_cdc_notifier_call(priv, LPASS_CDC_WCD_EVT_PA_OFF_PRE_SSR);
+	regcache_cache_only(priv->regmap, true);
+
+	mutex_lock(&priv->clk_lock);
+	priv->dev_up = false;
+	mutex_unlock(&priv->clk_lock);
+	if (priv->rsc_clk_cb)
+		priv->rsc_clk_cb(priv->clk_dev, LPASS_CDC_MACRO_EVT_SSR_DOWN);
+	/* call ssr event for supported macros */
+	for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
+		if (!priv->macro_params[macro_idx].event_handler)
+			continue;
+		priv->macro_params[macro_idx].event_handler(
+			priv->component,
+			LPASS_CDC_MACRO_EVT_SSR_DOWN, 0x0);
+	}
+	lpass_cdc_notifier_call(priv, LPASS_CDC_WCD_EVT_SSR_DOWN);
+}
+
+static struct snd_info_entry_ops lpass_cdc_info_ops = {
+	.read = lpass_cdc_version_read,
+};
+
+static const struct snd_event_ops lpass_cdc_ssr_ops = {
+	.enable = lpass_cdc_ssr_enable,
+	.disable = lpass_cdc_ssr_disable,
+};
+
+/*
+ * lpass_cdc_info_create_codec_entry - creates lpass_cdc module
+ * @codec_root: The parent directory
+ * @component: Codec component instance
+ *
+ * Creates lpass_cdc module and version entry under the given
+ * parent directory.
+ *
+ * Return: 0 on success or negative error code on failure.
+ */
+int lpass_cdc_info_create_codec_entry(struct snd_info_entry *codec_root,
+				   struct snd_soc_component *component)
+{
+	struct snd_info_entry *version_entry;
+	struct lpass_cdc_priv *priv;
+	struct snd_soc_card *card;
+
+	if (!codec_root || !component)
+		return -EINVAL;
+
+	priv = snd_soc_component_get_drvdata(component);
+	if (priv->entry) {
+		dev_dbg(priv->dev,
+			"%s:lpass_cdc module already created\n", __func__);
+		return 0;
+	}
+	card = component->card;
+	priv->entry = snd_info_create_module_entry(codec_root->module,
+					     "lpass_cdc", codec_root);
+	if (!priv->entry) {
+		dev_dbg(component->dev, "%s: failed to create lpass_cdc entry\n",
+			__func__);
+		return -ENOMEM;
+	}
+	priv->entry->mode = S_IFDIR | 0555;
+	if (snd_info_register(priv->entry) < 0) {
+		snd_info_free_entry(priv->entry);
+		return -ENOMEM;
+	}
+
+	version_entry = snd_info_create_card_entry(card->snd_card,
+						   "version",
+						   priv->entry);
+	if (!version_entry) {
+		dev_err(component->dev, "%s: failed to create lpass_cdc version entry\n",
+			__func__);
+		snd_info_free_entry(priv->entry);
+		return -ENOMEM;
+	}
+
+	version_entry->private_data = priv;
+	version_entry->size = LPASS_CDC_VERSION_ENTRY_SIZE;
+	version_entry->content = SNDRV_INFO_CONTENT_DATA;
+	version_entry->c.ops = &lpass_cdc_info_ops;
+
+	if (snd_info_register(version_entry) < 0) {
+		snd_info_free_entry(version_entry);
+		snd_info_free_entry(priv->entry);
+		return -ENOMEM;
+	}
+	priv->version_entry = version_entry;
+
+	return 0;
+}
+EXPORT_SYMBOL(lpass_cdc_info_create_codec_entry);
+
+/**
+ * lpass_cdc_register_wake_irq - Register wake irq of Tx macro
+ *
+ * @component: codec component ptr.
+ * @ipc_wakeup: bool to identify ipc_wakeup to be used or HW interrupt line.
+ *
+ * Return: 0 on success or negative error code on failure.
+ */
+int lpass_cdc_register_wake_irq(struct snd_soc_component *component,
+			     u32 ipc_wakeup)
+{
+	struct lpass_cdc_priv *priv = NULL;
+
+	if (!component)
+		return -EINVAL;
+
+	priv = snd_soc_component_get_drvdata(component);
+	if (!priv)
+		return -EINVAL;
+
+	if (!lpass_cdc_is_valid_codec_dev(priv->dev)) {
+		dev_err(component->dev, "%s: invalid codec\n", __func__);
+		return -EINVAL;
+	}
+
+	if (priv->version == LPASS_CDC_VERSION_2_1) {
+		if (priv->macro_params[VA_MACRO].reg_wake_irq)
+			priv->macro_params[VA_MACRO].reg_wake_irq(
+					component, ipc_wakeup);
+	} else {
+		if (priv->macro_params[TX_MACRO].reg_wake_irq)
+			priv->macro_params[TX_MACRO].reg_wake_irq(
+					component, ipc_wakeup);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(lpass_cdc_register_wake_irq);
+
+/**
+ * lpass_cdc_tx_mclk_enable - Enable/Disable TX Macro mclk
+ *
+ * @component: pointer to codec component instance.
+ * @enable: set true to enable, otherwise false.
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int lpass_cdc_tx_mclk_enable(struct snd_soc_component *component,
+			  bool enable)
+{
+	struct lpass_cdc_priv *priv = NULL;
+	int ret = 0;
+
+	if (!component)
+		return -EINVAL;
+
+	priv = snd_soc_component_get_drvdata(component);
+	if (!priv)
+		return -EINVAL;
+
+	if (!lpass_cdc_is_valid_codec_dev(priv->dev)) {
+		dev_err(component->dev, "%s: invalid codec\n", __func__);
+		return -EINVAL;
+	}
+
+	if (priv->macro_params[TX_MACRO].clk_enable)
+		ret = priv->macro_params[TX_MACRO].clk_enable(component,
+								enable);
+
+	return ret;
+}
+EXPORT_SYMBOL(lpass_cdc_tx_mclk_enable);
+
+/**
+ * lpass_cdc_register_event_listener - Register/Deregister to event listener
+ *
+ * @component: pointer to codec component instance.
+ * @enable: when set to 1 registers to event listener otherwise, derigisters
+ *          from the event listener
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int lpass_cdc_register_event_listener(struct snd_soc_component *component,
+				   bool enable)
+{
+	struct lpass_cdc_priv *priv = NULL;
+	int ret = 0;
+
+	if (!component)
+		return -EINVAL;
+
+	priv = snd_soc_component_get_drvdata(component);
+	if (!priv)
+		return -EINVAL;
+
+	if (!lpass_cdc_is_valid_codec_dev(priv->dev)) {
+		dev_err(component->dev, "%s: invalid codec\n", __func__);
+		return -EINVAL;
+	}
+
+	if (priv->macro_params[TX_MACRO].reg_evt_listener)
+		ret = priv->macro_params[TX_MACRO].reg_evt_listener(component,
+								    enable);
+
+	return ret;
+}
+EXPORT_SYMBOL(lpass_cdc_register_event_listener);
+
+static int lpass_cdc_soc_codec_probe(struct snd_soc_component *component)
+{
+	struct lpass_cdc_priv *priv = dev_get_drvdata(component->dev);
+	int macro_idx, ret = 0;
+	u8 core_id_0 = 0, core_id_1 = 0;
+
+	snd_soc_component_init_regmap(component, priv->regmap);
+
+	if (!priv->version) {
+		/*
+		 * In order for the ADIE RTC to differentiate between targets
+		 * version info is used.
+		 * Assign 1.0 for target with only one macro
+		 * Assign 1.1 for target with two macros
+		 * Assign 1.2 for target with more than two macros
+		 */
+		if (priv->num_macros_registered == 1)
+			priv->version = LPASS_CDC_VERSION_1_0;
+		else if (priv->num_macros_registered == 2)
+			priv->version = LPASS_CDC_VERSION_1_1;
+		else if (priv->num_macros_registered > 2)
+			priv->version = LPASS_CDC_VERSION_1_2;
+	}
+
+	/* Assign lpass_cdc version */
+	core_id_0 = snd_soc_component_read32(component,
+					LPASS_CDC_VA_TOP_CSR_CORE_ID_0);
+	core_id_1 = snd_soc_component_read32(component,
+					LPASS_CDC_VA_TOP_CSR_CORE_ID_1);
+	if ((core_id_0 == 0x01) && (core_id_1 == 0x0F))
+		priv->version = LPASS_CDC_VERSION_2_0;
+	if ((core_id_0 == 0x02) && (core_id_1 == 0x0E))
+		priv->version = LPASS_CDC_VERSION_2_1;
+
+	/* call init for supported macros */
+	for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
+		if (priv->macro_params[macro_idx].init) {
+			ret = priv->macro_params[macro_idx].init(component);
+			if (ret < 0) {
+				dev_err(component->dev,
+					"%s: init for macro %d failed\n",
+					__func__, macro_idx);
+				goto err;
+			}
+		}
+	}
+	priv->component = component;
+
+	ret = snd_event_client_register(priv->dev, &lpass_cdc_ssr_ops, priv);
+	if (!ret) {
+		snd_event_notify(priv->dev, SND_EVENT_UP);
+	} else {
+		dev_err(component->dev,
+			"%s: Registration with SND event FWK failed ret = %d\n",
+			__func__, ret);
+		goto err;
+	}
+
+	dev_dbg(component->dev, "%s: lpass_cdc soc codec probe success\n",
+		__func__);
+err:
+	return ret;
+}
+
+static void lpass_cdc_soc_codec_remove(struct snd_soc_component *component)
+{
+	struct lpass_cdc_priv *priv = dev_get_drvdata(component->dev);
+	int macro_idx;
+
+	snd_event_client_deregister(priv->dev);
+	/* call exit for supported macros */
+	for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++)
+		if (priv->macro_params[macro_idx].exit)
+			priv->macro_params[macro_idx].exit(component);
+
+	return;
+}
+
+static const struct snd_soc_component_driver lpass_cdc = {
+	.name = DRV_NAME,
+	.probe = lpass_cdc_soc_codec_probe,
+	.remove = lpass_cdc_soc_codec_remove,
+};
+
+static void lpass_cdc_add_child_devices(struct work_struct *work)
+{
+	struct lpass_cdc_priv *priv;
+	bool split_codec = false;
+	struct platform_device *pdev;
+	struct device_node *node;
+	int ret = 0, count = 0;
+	struct wcd_ctrl_platform_data *platdata = NULL;
+	char plat_dev_name[LPASS_CDC_STRING_LEN] = "";
+
+	priv = container_of(work, struct lpass_cdc_priv,
+			    lpass_cdc_add_child_devices_work);
+	if (!priv) {
+		pr_err("%s: Memory for lpass_cdc priv does not exist\n",
+			__func__);
+		return;
+	}
+	if (!priv->dev || !priv->dev->of_node) {
+		dev_err(priv->dev, "%s: DT node for lpass_cdc does not exist\n",
+			__func__);
+		return;
+	}
+
+	platdata = &priv->plat_data;
+	priv->child_count = 0;
+
+	for_each_available_child_of_node(priv->dev->of_node, node) {
+		split_codec = false;
+		if (of_find_property(node, "qcom,split-codec", NULL)) {
+			split_codec = true;
+			dev_dbg(priv->dev, "%s: split codec slave exists\n",
+				__func__);
+		}
+
+		strlcpy(plat_dev_name, node->name,
+				(LPASS_CDC_STRING_LEN - 1));
+
+		pdev = platform_device_alloc(plat_dev_name, -1);
+		if (!pdev) {
+			dev_err(priv->dev, "%s: pdev memory alloc failed\n",
+				__func__);
+			ret = -ENOMEM;
+			goto err;
+		}
+		pdev->dev.parent = priv->dev;
+		pdev->dev.of_node = node;
+
+		priv->dev->platform_data = platdata;
+		if (split_codec)
+			priv->wcd_dev = &pdev->dev;
+
+		ret = platform_device_add(pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"%s: Cannot add platform device\n",
+				__func__);
+			platform_device_put(pdev);
+			goto fail_pdev_add;
+		}
+
+		if (priv->child_count < LPASS_CDC_CHILD_DEVICES_MAX)
+			priv->pdev_child_devices[priv->child_count++] = pdev;
+		else
+			goto err;
+	}
+	return;
+fail_pdev_add:
+	for (count = 0; count < priv->child_count; count++)
+		platform_device_put(priv->pdev_child_devices[count]);
+err:
+	return;
+}
+
+static int lpass_cdc_probe(struct platform_device *pdev)
+{
+	struct lpass_cdc_priv *priv;
+	u32 num_macros = 0;
+	int ret;
+	struct clk *lpass_core_hw_vote = NULL;
+	struct clk *lpass_audio_hw_vote = NULL;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct lpass_cdc_priv),
+			    GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,num-macros",
+				   &num_macros);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"%s:num-macros property not found\n",
+			__func__);
+		return ret;
+	}
+	priv->num_macros = num_macros;
+	if (priv->num_macros > MAX_MACRO) {
+		dev_err(&pdev->dev,
+			"%s:num_macros(%d) > MAX_MACRO(%d) than supported\n",
+			__func__, priv->num_macros, MAX_MACRO);
+		return -EINVAL;
+	}
+	priv->va_without_decimation = of_property_read_bool(pdev->dev.of_node,
+						"qcom,va-without-decimation");
+	if (priv->va_without_decimation)
+		lpass_cdc_reg_access[VA_MACRO] = lpass_cdc_va_top_reg_access;
+
+	ret = of_property_read_u32(pdev->dev.of_node,
+				"qcom,lpass-cdc-version", &priv->version);
+	if (ret) {
+		dev_dbg(&pdev->dev, "%s:lpass_cdc version not specified\n",
+			__func__);
+		ret = 0;
+	}
+	if (priv->version == LPASS_CDC_VERSION_2_1) {
+		lpass_cdc_reg_access[TX_MACRO] = lpass_cdc_tx_reg_access_v2;
+		lpass_cdc_reg_access[VA_MACRO] = lpass_cdc_va_reg_access_v2;
+	} else if (priv->version == LPASS_CDC_VERSION_2_0) {
+		lpass_cdc_reg_access[VA_MACRO] = lpass_cdc_va_reg_access_v3;
+	}
+
+	priv->dev = &pdev->dev;
+	priv->dev_up = true;
+	priv->initial_boot = true;
+	priv->regmap = lpass_cdc_regmap_init(priv->dev,
+					  &lpass_cdc_regmap_config);
+	if (IS_ERR_OR_NULL((void *)(priv->regmap))) {
+		dev_err(&pdev->dev, "%s:regmap init failed\n", __func__);
+		return -EINVAL;
+	}
+	priv->read_dev = __lpass_cdc_reg_read;
+	priv->write_dev = __lpass_cdc_reg_write;
+
+	priv->plat_data.handle = (void *) priv;
+	priv->plat_data.update_wcd_event = lpass_cdc_update_wcd_event;
+	priv->plat_data.register_notifier = lpass_cdc_register_notifier;
+
+	priv->core_hw_vote_count = 0;
+	priv->core_audio_vote_count = 0;
+
+	dev_set_drvdata(&pdev->dev, priv);
+	mutex_init(&priv->io_lock);
+	mutex_init(&priv->clk_lock);
+	mutex_init(&priv->vote_lock);
+	INIT_WORK(&priv->lpass_cdc_add_child_devices_work,
+		  lpass_cdc_add_child_devices);
+	schedule_work(&priv->lpass_cdc_add_child_devices_work);
+
+	/* Register LPASS core hw vote */
+	lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote");
+	if (IS_ERR(lpass_core_hw_vote)) {
+		ret = PTR_ERR(lpass_core_hw_vote);
+		dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n",
+			__func__, "lpass_core_hw_vote", ret);
+		lpass_core_hw_vote = NULL;
+		ret = 0;
+	}
+	priv->lpass_core_hw_vote = lpass_core_hw_vote;
+
+	/* Register LPASS audio hw vote */
+	lpass_audio_hw_vote = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote");
+	if (IS_ERR(lpass_audio_hw_vote)) {
+		ret = PTR_ERR(lpass_audio_hw_vote);
+		dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n",
+			__func__, "lpass_audio_hw_vote", ret);
+		lpass_audio_hw_vote = NULL;
+		ret = 0;
+	}
+	priv->lpass_audio_hw_vote = lpass_audio_hw_vote;
+
+	return 0;
+}
+
+static int lpass_cdc_remove(struct platform_device *pdev)
+{
+	struct lpass_cdc_priv *priv = dev_get_drvdata(&pdev->dev);
+
+	if (!priv)
+		return -EINVAL;
+
+	of_platform_depopulate(&pdev->dev);
+	mutex_destroy(&priv->io_lock);
+	mutex_destroy(&priv->clk_lock);
+	mutex_destroy(&priv->vote_lock);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+int lpass_cdc_runtime_resume(struct device *dev)
+{
+	struct lpass_cdc_priv *priv = dev_get_drvdata(dev->parent);
+	int ret = 0;
+
+	mutex_lock(&priv->vote_lock);
+	if (priv->lpass_core_hw_vote == NULL) {
+		dev_dbg(dev, "%s: Invalid lpass core hw node\n", __func__);
+		goto audio_vote;
+	}
+
+	if (priv->core_hw_vote_count == 0) {
+		ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_core_hw_vote);
+		if (ret < 0) {
+			dev_err(dev, "%s:lpass core hw enable failed\n",
+				__func__);
+			goto audio_vote;
+		}
+	}
+	priv->core_hw_vote_count++;
+	trace_printk("%s: hw vote count %d\n",
+		__func__, priv->core_hw_vote_count);
+
+audio_vote:
+	if (priv->lpass_audio_hw_vote == NULL) {
+		dev_dbg(dev, "%s: Invalid lpass audio hw node\n", __func__);
+		goto done;
+	}
+
+	if (priv->core_audio_vote_count == 0) {
+		ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_audio_hw_vote);
+		if (ret < 0) {
+			dev_err(dev, "%s:lpass audio hw enable failed\n",
+				__func__);
+			goto done;
+		}
+	}
+	priv->core_audio_vote_count++;
+	trace_printk("%s: audio vote count %d\n",
+		__func__, priv->core_audio_vote_count);
+
+done:
+	mutex_unlock(&priv->vote_lock);
+	pm_runtime_set_autosuspend_delay(priv->dev, LPASS_CDC_AUTO_SUSPEND_DELAY);
+	return 0;
+}
+EXPORT_SYMBOL(lpass_cdc_runtime_resume);
+
+int lpass_cdc_runtime_suspend(struct device *dev)
+{
+	struct lpass_cdc_priv *priv = dev_get_drvdata(dev->parent);
+
+	mutex_lock(&priv->vote_lock);
+	if (priv->lpass_core_hw_vote != NULL) {
+		if (--priv->core_hw_vote_count == 0)
+			digital_cdc_rsc_mgr_hw_vote_disable(
+					priv->lpass_core_hw_vote);
+		if (priv->core_hw_vote_count < 0)
+			priv->core_hw_vote_count = 0;
+	} else {
+		dev_dbg(dev, "%s: Invalid lpass core hw node\n",
+			__func__);
+	}
+	trace_printk("%s: hw vote count %d\n",
+		__func__, priv->core_hw_vote_count);
+
+	if (priv->lpass_audio_hw_vote != NULL) {
+		if (--priv->core_audio_vote_count == 0)
+			digital_cdc_rsc_mgr_hw_vote_disable(
+					priv->lpass_audio_hw_vote);
+		if (priv->core_audio_vote_count < 0)
+			priv->core_audio_vote_count = 0;
+	} else {
+		dev_dbg(dev, "%s: Invalid lpass audio hw node\n",
+			__func__);
+	}
+	trace_printk("%s: audio vote count %d\n",
+		__func__, priv->core_audio_vote_count);
+
+	mutex_unlock(&priv->vote_lock);
+	return 0;
+}
+EXPORT_SYMBOL(lpass_cdc_runtime_suspend);
+#endif /* CONFIG_PM */
+
+bool lpass_cdc_check_core_votes(struct device *dev)
+{
+	struct lpass_cdc_priv *priv = dev_get_drvdata(dev->parent);
+	bool ret = true;
+
+	mutex_lock(&priv->vote_lock);
+	if ((priv->lpass_core_hw_vote && !priv->core_hw_vote_count) ||
+		(priv->lpass_audio_hw_vote && !priv->core_audio_vote_count))
+		ret = false;
+	mutex_unlock(&priv->vote_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(lpass_cdc_check_core_votes);
+
+static const struct of_device_id lpass_cdc_dt_match[] = {
+	{.compatible = "qcom,lpass-cdc"},
+	{}
+};
+MODULE_DEVICE_TABLE(of, lpass_cdc_dt_match);
+
+static struct platform_driver lpass_cdc_drv = {
+	.driver = {
+		.name = "lpass-cdc",
+		.owner = THIS_MODULE,
+		.of_match_table = lpass_cdc_dt_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = lpass_cdc_probe,
+	.remove = lpass_cdc_remove,
+};
+
+static int lpass_cdc_drv_init(void)
+{
+	return platform_driver_register(&lpass_cdc_drv);
+}
+
+static void lpass_cdc_drv_exit(void)
+{
+	platform_driver_unregister(&lpass_cdc_drv);
+}
+
+static int __init lpass_cdc_init(void)
+{
+	lpass_cdc_drv_init();
+	lpass_cdc_clk_rsc_mgr_init();
+	return 0;
+}
+module_init(lpass_cdc_init);
+
+static void __exit lpass_cdc_exit(void)
+{
+	lpass_cdc_clk_rsc_mgr_exit();
+	lpass_cdc_drv_exit();
+}
+module_exit(lpass_cdc_exit);
+
+MODULE_DESCRIPTION("LPASS Codec driver");
+MODULE_LICENSE("GPL v2");

+ 206 - 0
asoc/codecs/lpass-cdc/lpass-cdc.h

@@ -0,0 +1,206 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef LPASS_CDC_H
+#define LPASS_CDC_H
+
+#include <sound/soc.h>
+#include <linux/regmap.h>
+
+#define LPASS_CDC_VERSION_1_0 0x0001
+#define LPASS_CDC_VERSION_1_1 0x0002
+#define LPASS_CDC_VERSION_1_2 0x0003
+#define LPASS_CDC_VERSION_2_0 0x0004
+#define LPASS_CDC_VERSION_2_1 0x0005
+
+enum {
+	START_MACRO,
+	TX_MACRO = START_MACRO,
+	RX_MACRO,
+	WSA_MACRO,
+	VA_MACRO,
+	MAX_MACRO
+};
+
+enum mclk_mux {
+	MCLK_MUX0,
+	MCLK_MUX1,
+	MCLK_MUX_MAX
+};
+
+enum {
+	LPASS_CDC_ADC0 = 1,
+	LPASS_CDC_ADC1,
+	LPASS_CDC_ADC2,
+	LPASS_CDC_ADC3,
+	LPASS_CDC_ADC_MAX
+};
+
+enum {
+	LPASS_CDC_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
+	LPASS_CDC_MACRO_EVT_IMPED_TRUE, /* for imped true */
+	LPASS_CDC_MACRO_EVT_IMPED_FALSE, /* for imped false */
+	LPASS_CDC_MACRO_EVT_SSR_DOWN,
+	LPASS_CDC_MACRO_EVT_SSR_UP,
+	LPASS_CDC_MACRO_EVT_WAIT_VA_CLK_RESET,
+	LPASS_CDC_MACRO_EVT_CLK_RESET,
+	LPASS_CDC_MACRO_EVT_REG_WAKE_IRQ,
+	LPASS_CDC_MACRO_EVT_RX_COMPANDER_SOFT_RST,
+	LPASS_CDC_MACRO_EVT_BCS_CLK_OFF,
+	LPASS_CDC_MACRO_EVT_SSR_GFMUX_UP,
+	LPASS_CDC_MACRO_EVT_PRE_SSR_UP,
+	LPASS_CDC_MACRO_EVT_RX_PA_GAIN_UPDATE,
+	LPASS_CDC_MACRO_EVT_HPHL_HD2_ENABLE, /* Enable HD2 cfg for HPHL */
+	LPASS_CDC_MACRO_EVT_HPHR_HD2_ENABLE, /* Enable HD2 cfg for HPHR */
+};
+
+enum {
+	DMIC_TX = 0,
+	DMIC_VA = 1,
+
+};
+
+struct macro_ops {
+	int (*init)(struct snd_soc_component *component);
+	int (*exit)(struct snd_soc_component *component);
+	u16 num_dais;
+	struct device *dev;
+	struct snd_soc_dai_driver *dai_ptr;
+	int (*mclk_fn)(struct device *dev, bool enable);
+	int (*event_handler)(struct snd_soc_component *component, u16 event,
+			     u32 data);
+	int (*reg_wake_irq)(struct snd_soc_component *component, u32 data);
+	int (*set_port_map)(struct snd_soc_component *component, u32 uc,
+			    u32 size, void *data);
+	int (*clk_div_get)(struct snd_soc_component *component);
+	int (*reg_evt_listener)(struct snd_soc_component *component, bool en);
+	int (*clk_enable)(struct snd_soc_component *c, bool en);
+	char __iomem *io_base;
+	u16 clk_id_req;
+	u16 default_clk_id;
+};
+
+typedef int (*rsc_clk_cb_t)(struct device *dev, u16 event);
+
+#if IS_ENABLED(CONFIG_SND_SOC_LPASS_CDC)
+int lpass_cdc_register_res_clk(struct device *dev, rsc_clk_cb_t cb);
+void lpass_cdc_unregister_res_clk(struct device *dev);
+bool lpass_cdc_is_va_macro_registered(struct device *dev);
+int lpass_cdc_register_macro(struct device *dev, u16 macro_id,
+			  struct macro_ops *ops);
+void lpass_cdc_unregister_macro(struct device *dev, u16 macro_id);
+struct device *lpass_cdc_get_device_ptr(struct device *dev, u16 macro_id);
+struct device *lpass_cdc_get_rsc_clk_device_ptr(struct device *dev);
+int lpass_cdc_info_create_codec_entry(
+		struct snd_info_entry *codec_root,
+		struct snd_soc_component *component);
+int lpass_cdc_register_wake_irq(struct snd_soc_component *component, u32 data);
+void lpass_cdc_clear_amic_tx_hold(struct device *dev, u16 adc_n);
+int lpass_cdc_runtime_resume(struct device *dev);
+int lpass_cdc_runtime_suspend(struct device *dev);
+int lpass_cdc_set_port_map(struct snd_soc_component *component, u32 size, void *data);
+int lpass_cdc_register_event_listener(struct snd_soc_component *component,
+				   bool enable);
+void lpass_cdc_wsa_pa_on(struct device *dev, bool adie_lb);
+bool lpass_cdc_check_core_votes(struct device *dev);
+int lpass_cdc_tx_mclk_enable(struct snd_soc_component *c, bool enable);
+int lpass_cdc_get_version(struct device *dev);
+int lpass_cdc_dmic_clk_enable(struct snd_soc_component *component,
+			   u32 dmic, u32 tx_mode, bool enable);
+#else
+static inline int lpass_cdc_register_res_clk(struct device *dev, rsc_clk_cb_t cb)
+{
+	return 0;
+}
+static inline void lpass_cdc_unregister_res_clk(struct device *dev)
+{
+}
+
+static bool lpass_cdc_is_va_macro_registered(struct device *dev)
+{
+	return false;
+}
+
+static inline int lpass_cdc_register_macro(struct device *dev,
+					u16 macro_id,
+					struct macro_ops *ops)
+{
+	return 0;
+}
+
+static inline void lpass_cdc_unregister_macro(struct device *dev, u16 macro_id)
+{
+}
+
+static inline struct device *lpass_cdc_get_device_ptr(struct device *dev,
+						   u16 macro_id)
+{
+	return NULL;
+}
+
+static int lpass_cdc_info_create_codec_entry(
+		struct snd_info_entry *codec_root,
+		struct snd_soc_component *component)
+{
+	return 0;
+}
+
+static inline void lpass_cdc_clear_amic_tx_hold(struct device *dev, u16 adc_n)
+{
+}
+
+static inline int lpass_cdc_register_wake_irq(struct snd_soc_component *component,
+					   u32 data)
+{
+	return 0;
+}
+
+static inline int lpass_cdc_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int lpass_cdc_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static inline int lpass_cdc_set_port_map(struct snd_soc_component *component,
+				u32 size, void *data)
+{
+	return 0;
+}
+
+static inline int lpass_cdc_register_event_listener(
+					struct snd_soc_component *component,
+					bool enable)
+{
+	return 0;
+}
+
+static void lpass_cdc_wsa_pa_on(struct device *dev, bool adie_lb)
+{
+}
+
+static inline bool lpass_cdc_check_core_votes(struct device *dev)
+{
+	return false;
+}
+
+static int lpass_cdc_get_version(struct device *dev)
+{
+	return 0;
+}
+
+static int lpass_cdc_dmic_clk_enable(struct snd_soc_component *component,
+			   u32 dmic, u32 tx_mode, bool enable)
+{
+	return 0;
+}
+static int lpass_cdc_tx_mclk_enable(struct snd_soc_component *c, bool enable)
+{
+	return 0;
+}
+#endif /* CONFIG_SND_SOC_LPASS_CDC */
+#endif /* LPASS_CDC_H */