Prechádzať zdrojové kódy

asoc: codecs: Implement codec driver for WSA884X

Driver implementation for WSA884X.
Use new script to generate register files.
Modify register naming convention.
Add wsa884x-reg-masks.h and wsa884x-reg-shifts.h
Reverting copyrights to 2019 for wsa884x.h file

Change-Id: Ic3652d6138a2f62ba59a36d4307c732ab6e8db89
Signed-off-by: Shazmaan Ali <[email protected]>
Junkai Cai 3 rokov pred
rodič
commit
179ce4f13f

+ 1 - 0
asoc/codecs/Kbuild

@@ -258,6 +258,7 @@ ifeq ($(KERNEL_BUILD), 1)
 	obj-y	+= bolero/
 	obj-y	+= lpass-cdc/
 	obj-y	+= wsa883x/
+	obj-y	+= wsa884x/
 	obj-y	+= rouleur/
 endif
 # Module information used by KBuild framework

+ 103 - 0
asoc/codecs/wsa884x/Kbuild

@@ -0,0 +1,103 @@
+# 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_LAHAINA), y)
+		include $(AUDIO_ROOT)/config/lahainaauto.conf
+		INCS    +=  -include $(AUDIO_ROOT)/config/lahainaautoconf.h
+	endif
+	ifeq ($(CONFIG_ARCH_WAIPIO), y)
+		include $(AUDIO_ROOT)/config/waipioauto.conf
+		INCS    +=  -include $(AUDIO_ROOT)/config/waipioautoconf.h
+	endif
+	ifeq ($(CONFIG_ARCH_LITO), y)
+		include $(AUDIO_ROOT)/config/litoauto.conf
+		INCS    +=  -include $(AUDIO_ROOT)/config/litoautoconf.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)
+
+############ WSA884X ############
+
+# for WSA884X Codec
+ifdef CONFIG_SND_SOC_WSA884X
+	WSA884X_OBJS += wsa884x.o
+	WSA884X_OBJS += wsa884x-regmap.o
+	WSA884X_OBJS += wsa884x-tables.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
+
+
+# Module information used by KBuild framework
+obj-$(CONFIG_SND_SOC_WSA884X) += wsa884x_dlkm.o
+wsa884x_dlkm-y := $(WSA884X_OBJS)
+
+# inject some build related information
+DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\"

+ 6 - 0
asoc/codecs/wsa884x/Makefile

@@ -0,0 +1,6 @@
+modules:
+	$(MAKE) -C $(KERNEL_SRC) M=$(M) modules $(KBUILD_OPTIONS) VERBOSE=1
+modules_install:
+	$(MAKE) M=$(M) -C $(KERNEL_SRC) modules_install
+clean:
+	$(MAKE) -C $(KERNEL_SRC) M=$(M) clean

+ 135 - 0
asoc/codecs/wsa884x/internal.h

@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef WSA884X_INTERNAL_H
+#define WSA884X_INTERNAL_H
+
+#include <asoc/wcd-irq.h>
+#include "wsa884x.h"
+#include "wsa884x-registers.h"
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#define SWR_SLV_MAX_REG_ADDR	0x2009
+#define SWR_SLV_START_REG_ADDR	0x40
+#define SWR_SLV_MAX_BUF_LEN	20
+#define BYTES_PER_LINE		12
+#define SWR_SLV_RD_BUF_LEN	8
+#define SWR_SLV_WR_BUF_LEN	32
+#define SWR_SLV_MAX_DEVICES	2
+#endif /* CONFIG_DEBUG_FS */
+
+#define WSA884X_DRV_NAME "wsa884x-codec"
+#define WSA884X_NUM_RETRY	5
+
+#define WSA884X_VERSION_ENTRY_SIZE 32
+#define WSA884X_VARIANT_ENTRY_SIZE 32
+
+#define WSA884X_VERSION_1_0 0
+#define WSA884X_VERSION_1_1 1
+
+enum {
+	G_21DB = 0,
+	G_19P5DB,
+	G_18DB,
+	G_16P5DB,
+	G_15DB,
+	G_13P5DB,
+	G_12DB,
+	G_10P5DB,
+	G_9DB,
+	G_7P5DB,
+	G_6DB,
+	G_4P5DB,
+	G_3DB,
+	G_1P5DB,
+	G_0DB,
+};
+
+enum {
+	DISABLE = 0,
+	ENABLE,
+};
+
+enum {
+	SWR_DAC_PORT,
+	SWR_COMP_PORT,
+	SWR_BOOST_PORT,
+	SWR_VISENSE_PORT,
+	SWR_CPS_PORT,
+	SWR_PBRPORT
+};
+
+struct wsa_ctrl_platform_data {
+	void *handle;
+	int (*update_wsa_event)(void *handle, u16 event, u32 data);
+	int (*register_notifier)(void *handle, struct notifier_block *nblock,
+				bool enable);
+};
+
+struct swr_port {
+	u8 port_id;
+	u8 ch_mask;
+	u32 ch_rate;
+	u8 num_ch;
+	u8 port_type;
+};
+
+extern struct regmap_config wsa884x_regmap_config;
+
+/*
+ * Private data Structure for wsa884x. All parameters related to
+ * WSA884X codec needs to be defined here.
+ */
+struct wsa884x_priv {
+	struct regmap *regmap;
+	struct device *dev;
+	struct swr_device *swr_slave;
+	struct snd_soc_component *component;
+	bool comp_enable;
+	bool visense_enable;
+	bool ext_vdd_spk;
+	bool dapm_bias_off;
+	struct swr_port port[WSA884X_MAX_SWR_PORTS];
+	int global_pa_cnt;
+	int dev_mode;
+	int comp_offset;
+	struct mutex res_lock;
+	struct snd_info_entry *entry;
+	struct snd_info_entry *version_entry;
+	struct snd_info_entry *variant_entry;
+	struct device_node *wsa_rst_np;
+	int pa_mute;
+	int curr_temp;
+	int variant;
+	int version;
+	u8 pa_gain;
+	struct irq_domain *virq;
+	struct wcd_irq_info irq_info;
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_dent;
+	struct dentry *debugfs_peek;
+	struct dentry *debugfs_poke;
+	struct dentry *debugfs_reg_dump;
+	unsigned int read_data;
+#endif
+	struct device_node *parent_np;
+	struct platform_device *parent_dev;
+	struct notifier_block parent_nblock;
+	void *handle;
+	int (*register_notifier)(void *handle,
+				struct notifier_block *nblock, bool enable);
+	struct cdc_regulator *regulator;
+	int num_supplies;
+	struct regulator_bulk_data *supplies;
+	unsigned long status_mask;
+	char *wsa884x_name_prefix;
+	struct snd_soc_dai_driver *dai_driver;
+	struct snd_soc_component_driver *driver;
+};
+
+#endif /* WSA884X_INTERNAL_H */

+ 87 - 0
asoc/codecs/wsa884x/wsa884x-reg-masks.h

@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef WSA884X_REG_MASKS_H
+#define WSA884X_REG_MASKS_H
+#include <linux/regmap.h>
+#include <linux/device.h>
+#include "wsa884x-registers.h"
+
+#define FIELD_MASK(register_name, field_name) \
+	WSA884X_##register_name##_##field_name##_MASK
+
+#define WSA884X_VBAT_SNS_BOP_FREQ_MASK 0x60
+#define WSA884X_ISENSE2_ISENSE_GAIN_CTL_MASK 0xe0
+#define WSA884X_ADC_2_ISNS_LOAD_STORED_MASK 0x40
+#define WSA884X_ADC_6_INTRLV_RST_OVRD_MASK 0x02
+#define WSA884X_ADC_7_EN_AZ_REG_MASK 0x04
+#define WSA884X_ADC_7_EN_SAR_REG_MASK 0x02
+#define WSA884X_CURRENT_LIMIT_CURRENT_LIMIT_OVRD_EN_MASK 0x80
+#define WSA884X_CURRENT_LIMIT_CURRENT_LIMIT_MASK 0x7c
+#define WSA884X_BOOST_MISC_SPKR_RDY_CTL_MASK 0x60
+#define WSA884X_CKWD_CTL_0_CKWD_FDIV_SEL_MASK 0x60
+#define WSA884X_CKWD_CTL_1_CKWD_VCOMP_VREF_SEL_MASK 0x1f
+#define WSA884X_CHIP_ID0_BYTE_0_MASK 0xff
+#define WSA884X_PA_FSM_EN_GLOBAL_PA_EN_MASK 0x01
+#define WSA884X_PA_FSM_BYP_CTL_PA_FSM_BYP_MASK 0x01
+#define WSA884X_PA_FSM_BYP0_TSADC_EN_MASK 0x80
+#define WSA884X_PA_FSM_BYP0_SPKR_PROT_EN_MASK 0x40
+#define WSA884X_PA_FSM_BYP0_D_UNMUTE_MASK 0x20
+#define WSA884X_PA_FSM_BYP0_BG_EN_MASK 0x04
+#define WSA884X_PA_FSM_BYP0_CLK_WD_EN_MASK 0x02
+#define WSA884X_PA_FSM_BYP0_DC_CAL_EN_MASK 0x01
+#define WSA884X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_MASK 0x01
+#define WSA884X_TEMP_CONFIG0_CTL_THRD_SAF2WAR_MASK 0x07
+#define WSA884X_TEMP_CONFIG1_CTL_THRD_WAR2SAF_MASK 0x07
+#define WSA884X_VBAT_THRM_FLT_CTL_VBAT_COEF_SEL_MASK 0x0e
+#define WSA884X_VBAT_THRM_FLT_CTL_VBAT_FLT_EN_MASK 0x01
+#define WSA884X_CDC_SPK_DSM_A2_0_COEF_A2_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_A2_1_COEF_A2_MASK 0x0f
+#define WSA884X_CDC_SPK_DSM_A3_0_COEF_A3_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_A3_1_COEF_A3_MASK 0x07
+#define WSA884X_CDC_SPK_DSM_A4_0_COEF_A4_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_A4_1_COEF_A4_MASK 0x03
+#define WSA884X_CDC_SPK_DSM_A5_0_COEF_A5_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_A5_1_COEF_A5_MASK 0x03
+#define WSA884X_CDC_SPK_DSM_A6_0_COEF_A6_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_A7_0_COEF_A7_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_C_0_COEF_C3_MASK 0xf0
+#define WSA884X_CDC_SPK_DSM_C_0_COEF_C2_MASK 0x0f
+#define WSA884X_CDC_SPK_DSM_C_1_COEF_C5_MASK 0xf0
+#define WSA884X_CDC_SPK_DSM_C_1_COEF_C4_MASK 0x0f
+#define WSA884X_CDC_SPK_DSM_C_2_COEF_C7_MASK 0xf0
+#define WSA884X_CDC_SPK_DSM_C_2_COEF_C6_MASK 0x0f
+#define WSA884X_CDC_SPK_DSM_C_3_COEF_C7_MASK 0x3f
+#define WSA884X_CDC_SPK_DSM_R1_SAT_LIMIT_R1_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_R2_SAT_LIMIT_R2_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_R3_SAT_LIMIT_R3_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_R4_SAT_LIMIT_R4_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_R5_SAT_LIMIT_R5_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_R6_SAT_LIMIT_R6_MASK 0xff
+#define WSA884X_CDC_SPK_DSM_R7_SAT_LIMIT_R7_MASK 0xff
+#define WSA884X_PDM_WD_CTL_PDM_WD_EN_MASK 0x01
+#define WSA884X_DRE_CTL_0_PROG_DELAY_MASK 0xf0
+#define WSA884X_DRE_CTL_0_OFFSET_MASK 0x07
+#define WSA884X_DRE_CTL_1_CSR_GAIN_MASK 0x3e
+#define WSA884X_DRE_CTL_1_CSR_GAIN_EN_MASK 0x01
+#define WSA884X_TAGC_CTL_THERMAL_THRESH_MASK 0x0e
+#define WSA884X_TAGC_CTL_THERMAL_AGC_EN_MASK 0x01
+#define WSA884X_TAGC_TIME_REL_TIME_MASK 0x30
+#define WSA884X_VAGC_CTL_VBAT_AGC_EN_MASK 0x01
+#define WSA884X_VAGC_TIME_REL_TIME_MASK 0x0c
+#define WSA884X_VAGC_TIME_HLD_TIME_MASK 0x03
+#define WSA884X_VAGC_ATTN_LVL_2_VBAT_ATTN_LVL_MASK 0x1f
+#define WSA884X_VAGC_ATTN_LVL_3_VBAT_ATTN_LVL_MASK 0x1f
+#define WSA884X_OTP_REG_0_WSA884X_ID_MASK 0x0f
+#define WSA884X_OTP_REG_1_LOW_TEMP_MSB_MASK 0xff
+#define WSA884X_OTP_REG_2_LOW_TEMP_LSB_MASK 0xc0
+#define WSA884X_OTP_REG_3_HIGH_TEMP_MSB_MASK 0xff
+#define WSA884X_OTP_REG_4_HIGH_TEMP_LSB_MASK 0xc0
+#define WSA884X_DRE_IDLE_DET_CTL_PA_OFF_FORCE_EN_MASK 0x40
+#define WSA884X_DRE_IDLE_DET_CTL_PDM_WD_FORCE_EN_MASK 0x20
+#define WSA884X_DRE_IDLE_DET_CTL_DRE_IDLE_FORCE_EN_MASK 0x10
+#define WSA884X_DRE_IDLE_DET_CTL_DRE_FORCE_VALUE_MASK 0x0f
+
+#endif /* WSA884X_REG_MASKS_H */

+ 87 - 0
asoc/codecs/wsa884x/wsa884x-reg-shifts.h

@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef WSA884X_REG_SHIFTS_H
+#define WSA884X_REG_SHIFTS_H
+#include <linux/regmap.h>
+#include <linux/device.h>
+#include "wsa884x-registers.h"
+
+#define FIELD_SHIFT(register_name, field_name) \
+	WSA884X_##register_name##_##field_name##_SHIFT
+
+#define WSA884X_VBAT_SNS_BOP_FREQ_SHIFT 0x05
+#define WSA884X_ISENSE2_ISENSE_GAIN_CTL_SHIFT 0x05
+#define WSA884X_ADC_2_ISNS_LOAD_STORED_SHIFT 0x06
+#define WSA884X_ADC_6_INTRLV_RST_OVRD_SHIFT 0x01
+#define WSA884X_ADC_7_EN_AZ_REG_SHIFT 0x02
+#define WSA884X_ADC_7_EN_SAR_REG_SHIFT 0x01
+#define WSA884X_CURRENT_LIMIT_CURRENT_LIMIT_OVRD_EN_SHIFT 0x07
+#define WSA884X_CURRENT_LIMIT_CURRENT_LIMIT_SHIFT 0x02
+#define WSA884X_BOOST_MISC_SPKR_RDY_CTL_SHIFT 0x05
+#define WSA884X_CKWD_CTL_0_CKWD_FDIV_SEL_SHIFT 0x05
+#define WSA884X_CKWD_CTL_1_CKWD_VCOMP_VREF_SEL_SHIFT 0x00
+#define WSA884X_CHIP_ID0_BYTE_0_SHIFT 0x00
+#define WSA884X_PA_FSM_EN_GLOBAL_PA_EN_SHIFT 0x00
+#define WSA884X_PA_FSM_BYP_CTL_PA_FSM_BYP_SHIFT 0x00
+#define WSA884X_PA_FSM_BYP0_TSADC_EN_SHIFT 0x07
+#define WSA884X_PA_FSM_BYP0_SPKR_PROT_EN_SHIFT 0x06
+#define WSA884X_PA_FSM_BYP0_D_UNMUTE_SHIFT 0x05
+#define WSA884X_PA_FSM_BYP0_BG_EN_SHIFT 0x02
+#define WSA884X_PA_FSM_BYP0_CLK_WD_EN_SHIFT 0x01
+#define WSA884X_PA_FSM_BYP0_DC_CAL_EN_SHIFT 0x00
+#define WSA884X_TADC_VALUE_CTL_TEMP_VALUE_RD_EN_SHIFT 0x00
+#define WSA884X_TEMP_CONFIG0_CTL_THRD_SAF2WAR_SHIFT 0x00
+#define WSA884X_TEMP_CONFIG1_CTL_THRD_WAR2SAF_SHIFT 0x00
+#define WSA884X_VBAT_THRM_FLT_CTL_VBAT_COEF_SEL_SHIFT 0x01
+#define WSA884X_VBAT_THRM_FLT_CTL_VBAT_FLT_EN_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_A2_0_COEF_A2_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_A2_1_COEF_A2_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_A3_0_COEF_A3_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_A3_1_COEF_A3_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_A4_0_COEF_A4_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_A4_1_COEF_A4_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_A5_0_COEF_A5_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_A5_1_COEF_A5_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_A6_0_COEF_A6_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_A7_0_COEF_A7_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_C_0_COEF_C3_SHIFT 0x04
+#define WSA884X_CDC_SPK_DSM_C_0_COEF_C2_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_C_1_COEF_C5_SHIFT 0x04
+#define WSA884X_CDC_SPK_DSM_C_1_COEF_C4_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_C_2_COEF_C7_SHIFT 0x04
+#define WSA884X_CDC_SPK_DSM_C_2_COEF_C6_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_C_3_COEF_C7_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_R1_SAT_LIMIT_R1_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_R2_SAT_LIMIT_R2_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_R3_SAT_LIMIT_R3_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_R4_SAT_LIMIT_R4_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_R5_SAT_LIMIT_R5_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_R6_SAT_LIMIT_R6_SHIFT 0x00
+#define WSA884X_CDC_SPK_DSM_R7_SAT_LIMIT_R7_SHIFT 0x00
+#define WSA884X_PDM_WD_CTL_PDM_WD_EN_SHIFT 0x00
+#define WSA884X_DRE_CTL_0_PROG_DELAY_SHIFT 0x04
+#define WSA884X_DRE_CTL_0_OFFSET_SHIFT 0x00
+#define WSA884X_DRE_CTL_1_CSR_GAIN_SHIFT 0x01
+#define WSA884X_DRE_CTL_1_CSR_GAIN_EN_SHIFT 0x00
+#define WSA884X_TAGC_CTL_THERMAL_THRESH_SHIFT 0x01
+#define WSA884X_TAGC_CTL_THERMAL_AGC_EN_SHIFT 0x00
+#define WSA884X_TAGC_TIME_REL_TIME_SHIFT 0x04
+#define WSA884X_VAGC_CTL_VBAT_AGC_EN_SHIFT 0x00
+#define WSA884X_VAGC_TIME_REL_TIME_SHIFT 0x02
+#define WSA884X_VAGC_TIME_HLD_TIME_SHIFT 0x00
+#define WSA884X_VAGC_ATTN_LVL_2_VBAT_ATTN_LVL_SHIFT 0x00
+#define WSA884X_VAGC_ATTN_LVL_3_VBAT_ATTN_LVL_SHIFT 0x00
+#define WSA884X_OTP_REG_0_WSA884X_ID_SHIFT 0x00
+#define WSA884X_OTP_REG_1_LOW_TEMP_MSB_SHIFT 0x00
+#define WSA884X_OTP_REG_2_LOW_TEMP_LSB_SHIFT 0x06
+#define WSA884X_OTP_REG_3_HIGH_TEMP_MSB_SHIFT 0x00
+#define WSA884X_OTP_REG_4_HIGH_TEMP_LSB_SHIFT 0x06
+#define WSA884X_DRE_IDLE_DET_CTL_PA_OFF_FORCE_EN_SHIFT 0x06
+#define WSA884X_DRE_IDLE_DET_CTL_PDM_WD_FORCE_EN_SHIFT 0x05
+#define WSA884X_DRE_IDLE_DET_CTL_DRE_IDLE_FORCE_EN_SHIFT 0x04
+#define WSA884X_DRE_IDLE_DET_CTL_DRE_FORCE_VALUE_SHIFT 0x00
+
+#endif /* WSA884X_REG_SHIFTS_H */

+ 529 - 0
asoc/codecs/wsa884x/wsa884x-registers.h

@@ -0,0 +1,529 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015, 2019-2021, The Linux Foundation. All rights reserved.
+ */
+
+
+#ifndef WSA884X_REGISTERS_H
+#define WSA884X_REGISTERS_H
+
+enum {
+	REG_NO_ACCESS,
+	RD_REG,
+	WR_REG,
+	RD_WR_REG,
+};
+
+#define WSA884X_BASE 0x0
+#define WSA884X_REG(reg)  (reg - WSA884X_BASE)
+
+#define WSA884X_BG_TSADC_BASE                  (WSA884X_BASE+0x01)
+#define WSA884X_BG_CTRL                        (WSA884X_BG_TSADC_BASE+0x00)
+#define WSA884X_ADC_CTRL                       (WSA884X_BG_TSADC_BASE+0x01)
+#define WSA884X_BOP1_PROG                      (WSA884X_BG_TSADC_BASE+0x02)
+#define WSA884X_BOP2_PROG                      (WSA884X_BG_TSADC_BASE+0x03)
+#define WSA884X_UVLO_PROG                      (WSA884X_BG_TSADC_BASE+0x04)
+#define WSA884X_UVLO_PROG1                     (WSA884X_BG_TSADC_BASE+0x05)
+#define WSA884X_SPARE_CTRL_0                   (WSA884X_BG_TSADC_BASE+0x06)
+#define WSA884X_SPARE_CTRL_1                   (WSA884X_BG_TSADC_BASE+0x07)
+#define WSA884X_SPARE_CTRL_2                   (WSA884X_BG_TSADC_BASE+0x08)
+#define WSA884X_SPARE_CTRL_3                   (WSA884X_BG_TSADC_BASE+0x09)
+#define WSA884X_REF_CTRL                       (WSA884X_BG_TSADC_BASE+0x0a)
+#define WSA884X_BG_TEST_CTL                    (WSA884X_BG_TSADC_BASE+0x0b)
+#define WSA884X_BG_BIAS                        (WSA884X_BG_TSADC_BASE+0x0c)
+#define WSA884X_ADC_PROG                       (WSA884X_BG_TSADC_BASE+0x0d)
+#define WSA884X_ADC_IREF_CTL                   (WSA884X_BG_TSADC_BASE+0x0e)
+#define WSA884X_ADC_ISENS_CTL                  (WSA884X_BG_TSADC_BASE+0x0f)
+#define WSA884X_ADC_CLK_CTL                    (WSA884X_BG_TSADC_BASE+0x10)
+#define WSA884X_ADC_TEST_CTL                   (WSA884X_BG_TSADC_BASE+0x11)
+#define WSA884X_ADC_BIAS                       (WSA884X_BG_TSADC_BASE+0x12)
+#define WSA884X_VBAT_SNS                       (WSA884X_BG_TSADC_BASE+0x13)
+#define WSA884X_DOUT_MSB                       (WSA884X_BG_TSADC_BASE+0x14)
+#define WSA884X_DOUT_LSB                       (WSA884X_BG_TSADC_BASE+0x15)
+#define WSA884X_BOP_ATEST_SEL                  (WSA884X_BG_TSADC_BASE+0x16)
+#define WSA884X_MISC0                          (WSA884X_BG_TSADC_BASE+0x17)
+#define WSA884X_MISC1                          (WSA884X_BG_TSADC_BASE+0x18)
+#define WSA884X_MISC2                          (WSA884X_BG_TSADC_BASE+0x19)
+#define WSA884X_MISC3                          (WSA884X_BG_TSADC_BASE+0x1a)
+#define WSA884X_SPARE_TSBG_0                   (WSA884X_BG_TSADC_BASE+0x1b)
+#define WSA884X_SPARE_TUNE_0                   (WSA884X_BG_TSADC_BASE+0x1c)
+#define WSA884X_SPARE_TUNE_1                   (WSA884X_BG_TSADC_BASE+0x1d)
+
+#define WSA884X_IVSENSE_BASE                   (WSA884X_BASE+0x20)
+#define WSA884X_VSENSE1                        (WSA884X_IVSENSE_BASE+0x00)
+#define WSA884X_ISENSE2                        (WSA884X_IVSENSE_BASE+0x01)
+#define WSA884X_SPARE_CTL_1                    (WSA884X_IVSENSE_BASE+0x02)
+#define WSA884X_SPARE_CTL_2                    (WSA884X_IVSENSE_BASE+0x03)
+#define WSA884X_SPARE_CTL_3                    (WSA884X_IVSENSE_BASE+0x04)
+#define WSA884X_SPARE_CTL_4                    (WSA884X_IVSENSE_BASE+0x05)
+#define WSA884X_EN                             (WSA884X_IVSENSE_BASE+0x06)
+#define WSA884X_OVERRIDE1                      (WSA884X_IVSENSE_BASE+0x07)
+#define WSA884X_OVERRIDE2                      (WSA884X_IVSENSE_BASE+0x08)
+#define WSA884X_ISENSE1                        (WSA884X_IVSENSE_BASE+0x09)
+#define WSA884X_ISENSE_CAL                     (WSA884X_IVSENSE_BASE+0x0a)
+#define WSA884X_MISC                           (WSA884X_IVSENSE_BASE+0x0b)
+#define WSA884X_ADC_0                          (WSA884X_IVSENSE_BASE+0x0c)
+#define WSA884X_ADC_1                          (WSA884X_IVSENSE_BASE+0x0d)
+#define WSA884X_ADC_2                          (WSA884X_IVSENSE_BASE+0x0e)
+#define WSA884X_ADC_3                          (WSA884X_IVSENSE_BASE+0x0f)
+#define WSA884X_ADC_4                          (WSA884X_IVSENSE_BASE+0x10)
+#define WSA884X_ADC_5                          (WSA884X_IVSENSE_BASE+0x11)
+#define WSA884X_ADC_6                          (WSA884X_IVSENSE_BASE+0x12)
+#define WSA884X_ADC_7                          (WSA884X_IVSENSE_BASE+0x13)
+#define WSA884X_STATUS                         (WSA884X_IVSENSE_BASE+0x14)
+#define WSA884X_IVSENSE_SPARE_TUNE_1           (WSA884X_IVSENSE_BASE+0x15)
+#define WSA884X_SPARE_TUNE_2                   (WSA884X_IVSENSE_BASE+0x16)
+#define WSA884X_SPARE_TUNE_3                   (WSA884X_IVSENSE_BASE+0x17)
+#define WSA884X_SPARE_TUNE_4                   (WSA884X_IVSENSE_BASE+0x18)
+
+#define WSA884X_SPK_TOP_BASE                   (WSA884X_BASE+0x40)
+#define WSA884X_TOP_CTRL1                      (WSA884X_SPK_TOP_BASE+0x00)
+#define WSA884X_CLIP_DET_CTRL1                 (WSA884X_SPK_TOP_BASE+0x01)
+#define WSA884X_CLIP_DET_CTRL2                 (WSA884X_SPK_TOP_BASE+0x02)
+#define WSA884X_DAC_CTRL1                      (WSA884X_SPK_TOP_BASE+0x03)
+#define WSA884X_DAC_VCM_CTRL_REG1              (WSA884X_SPK_TOP_BASE+0x04)
+#define WSA884X_DAC_VCM_CTRL_REG2              (WSA884X_SPK_TOP_BASE+0x05)
+#define WSA884X_DAC_VCM_CTRL_REG3              (WSA884X_SPK_TOP_BASE+0x06)
+#define WSA884X_DAC_VCM_CTRL_REG4              (WSA884X_SPK_TOP_BASE+0x07)
+#define WSA884X_DAC_VCM_CTRL_REG5              (WSA884X_SPK_TOP_BASE+0x08)
+#define WSA884X_DAC_VCM_CTRL_REG6              (WSA884X_SPK_TOP_BASE+0x09)
+#define WSA884X_PWM_CLK_CTL                    (WSA884X_SPK_TOP_BASE+0x0a)
+#define WSA884X_DRV_LF_LDO_SEL                 (WSA884X_SPK_TOP_BASE+0x0b)
+#define WSA884X_OCP_CTL                        (WSA884X_SPK_TOP_BASE+0x0c)
+#define WSA884X_PDRV_HS_CTL                    (WSA884X_SPK_TOP_BASE+0x0d)
+#define WSA884X_PDRV_LS_CTL                    (WSA884X_SPK_TOP_BASE+0x0e)
+#define WSA884X_SPK_TOP_SPARE_CTL_1            (WSA884X_SPK_TOP_BASE+0x0f)
+#define WSA884X_SPK_TOP_SPARE_CTL_2            (WSA884X_SPK_TOP_BASE+0x10)
+#define WSA884X_SPK_TOP_SPARE_CTL_3            (WSA884X_SPK_TOP_BASE+0x11)
+#define WSA884X_SPK_TOP_SPARE_CTL_4            (WSA884X_SPK_TOP_BASE+0x12)
+#define WSA884X_SPARE_CTL_5                    (WSA884X_SPK_TOP_BASE+0x13)
+#define WSA884X_DAC_EN_DEBUG_REG               (WSA884X_SPK_TOP_BASE+0x14)
+#define WSA884X_DAC_OPAMP_BIAS1_REG            (WSA884X_SPK_TOP_BASE+0x15)
+#define WSA884X_DAC_OPAMP_BIAS2_REG            (WSA884X_SPK_TOP_BASE+0x16)
+#define WSA884X_DAC_TUNE1                      (WSA884X_SPK_TOP_BASE+0x17)
+#define WSA884X_DAC_VOLTAGE_CTRL_REG           (WSA884X_SPK_TOP_BASE+0x18)
+#define WSA884X_ATEST1_REG                     (WSA884X_SPK_TOP_BASE+0x19)
+#define WSA884X_ATEST2_REG                     (WSA884X_SPK_TOP_BASE+0x1a)
+#define WSA884X_TOP_BIAS_REG1                  (WSA884X_SPK_TOP_BASE+0x1b)
+#define WSA884X_TOP_BIAS_REG2                  (WSA884X_SPK_TOP_BASE+0x1c)
+#define WSA884X_TOP_BIAS_REG3                  (WSA884X_SPK_TOP_BASE+0x1d)
+#define WSA884X_TOP_BIAS_REG4                  (WSA884X_SPK_TOP_BASE+0x1e)
+#define WSA884X_PWRSTG_DBG2                    (WSA884X_SPK_TOP_BASE+0x1f)
+#define WSA884X_DRV_LF_BLK_EN                  (WSA884X_SPK_TOP_BASE+0x20)
+#define WSA884X_DRV_LF_EN                      (WSA884X_SPK_TOP_BASE+0x21)
+#define WSA884X_DRV_LF_MASK_DCC_CTL            (WSA884X_SPK_TOP_BASE+0x22)
+#define WSA884X_DRV_LF_MISC_CTL1               (WSA884X_SPK_TOP_BASE+0x23)
+#define WSA884X_DRV_LF_REG_GAIN                (WSA884X_SPK_TOP_BASE+0x24)
+#define WSA884X_DRV_OS_CAL_CTL                 (WSA884X_SPK_TOP_BASE+0x25)
+#define WSA884X_DRV_OS_CAL_CTL1                (WSA884X_SPK_TOP_BASE+0x26)
+#define WSA884X_PWRSTG_DBG                     (WSA884X_SPK_TOP_BASE+0x27)
+#define WSA884X_BBM_CTL                        (WSA884X_SPK_TOP_BASE+0x28)
+#define WSA884X_TOP_MISC1                      (WSA884X_SPK_TOP_BASE+0x29)
+#define WSA884X_DAC_VCM_CTRL_REG7              (WSA884X_SPK_TOP_BASE+0x2a)
+#define WSA884X_TOP_BIAS_REG5                  (WSA884X_SPK_TOP_BASE+0x2b)
+#define WSA884X_DRV_LF_MISC_CTL2               (WSA884X_SPK_TOP_BASE+0x2c)
+#define WSA884X_SPK_TOP_SPARE_TUNE_2           (WSA884X_SPK_TOP_BASE+0x2d)
+#define WSA884X_SPK_TOP_SPARE_TUNE_3           (WSA884X_SPK_TOP_BASE+0x2e)
+#define WSA884X_SPK_TOP_SPARE_TUNE_4           (WSA884X_SPK_TOP_BASE+0x2f)
+#define WSA884X_SPARE_TUNE_5                   (WSA884X_SPK_TOP_BASE+0x30)
+#define WSA884X_SPARE_TUNE_6                   (WSA884X_SPK_TOP_BASE+0x31)
+#define WSA884X_SPARE_TUNE_7                   (WSA884X_SPK_TOP_BASE+0x32)
+#define WSA884X_SPARE_TUNE_8                   (WSA884X_SPK_TOP_BASE+0x33)
+#define WSA884X_SPARE_TUNE_9                   (WSA884X_SPK_TOP_BASE+0x34)
+#define WSA884X_SPARE_TUNE_10                  (WSA884X_SPK_TOP_BASE+0x35)
+#define WSA884X_PA_STATUS0                     (WSA884X_SPK_TOP_BASE+0x36)
+#define WSA884X_PA_STATUS1                     (WSA884X_SPK_TOP_BASE+0x37)
+#define WSA884X_PA_STATUS2                     (WSA884X_SPK_TOP_BASE+0x38)
+#define WSA884X_PA_STATUS3                     (WSA884X_SPK_TOP_BASE+0x39)
+#define WSA884X_PA_STATUS4                     (WSA884X_SPK_TOP_BASE+0x3a)
+#define WSA884X_PA_STATUS5                     (WSA884X_SPK_TOP_BASE+0x3b)
+#define WSA884X_SPARE_RO_1                     (WSA884X_SPK_TOP_BASE+0x3c)
+#define WSA884X_SPARE_RO_2                     (WSA884X_SPK_TOP_BASE+0x3d)
+#define WSA884X_SPARE_RO_3                     (WSA884X_SPK_TOP_BASE+0x3e)
+
+#define WSA884X_BOOST_BASE                     (WSA884X_BASE+0x90)
+#define WSA884X_STB_CTRL1                      (WSA884X_BOOST_BASE+0x00)
+#define WSA884X_CURRENT_LIMIT                  (WSA884X_BOOST_BASE+0x01)
+#define WSA884X_BYP_CTRL1                      (WSA884X_BOOST_BASE+0x02)
+#define WSA884X_SPARE_CTL_0                    (WSA884X_BOOST_BASE+0x03)
+#define WSA884X_BOOST_SPARE_CTL_1              (WSA884X_BOOST_BASE+0x04)
+#define WSA884X_SPARE_RO_0                     (WSA884X_BOOST_BASE+0x05)
+#define WSA884X_BOOST_SPARE_RO_1               (WSA884X_BOOST_BASE+0x06)
+#define WSA884X_IBIAS1                         (WSA884X_BOOST_BASE+0x07)
+#define WSA884X_IBIAS2                         (WSA884X_BOOST_BASE+0x08)
+#define WSA884X_IBIAS3                         (WSA884X_BOOST_BASE+0x09)
+#define WSA884X_EN_CTRL                        (WSA884X_BOOST_BASE+0x0a)
+#define WSA884X_STB_CTRL2                      (WSA884X_BOOST_BASE+0x0b)
+#define WSA884X_STB_CTRL3                      (WSA884X_BOOST_BASE+0x0c)
+#define WSA884X_STB_CTRL4                      (WSA884X_BOOST_BASE+0x0d)
+#define WSA884X_BYP_CTRL2                      (WSA884X_BOOST_BASE+0x0e)
+#define WSA884X_BYP_CTRL3                      (WSA884X_BOOST_BASE+0x0f)
+#define WSA884X_ZX_CTRL1                       (WSA884X_BOOST_BASE+0x10)
+#define WSA884X_ZX_CTRL2                       (WSA884X_BOOST_BASE+0x11)
+#define WSA884X_BLEEDER_CTRL                   (WSA884X_BOOST_BASE+0x12)
+#define WSA884X_BOOST_MISC                     (WSA884X_BOOST_BASE+0x13)
+#define WSA884X_PWRSTAGE_CTRL1                 (WSA884X_BOOST_BASE+0x14)
+#define WSA884X_PWRSTAGE_CTRL2                 (WSA884X_BOOST_BASE+0x15)
+#define WSA884X_PWRSTAGE_CTRL3                 (WSA884X_BOOST_BASE+0x16)
+#define WSA884X_PWRSTAGE_CTRL4                 (WSA884X_BOOST_BASE+0x17)
+#define WSA884X_MAXD_REG1                      (WSA884X_BOOST_BASE+0x18)
+#define WSA884X_MAXD_REG2                      (WSA884X_BOOST_BASE+0x19)
+#define WSA884X_ILIM_CTRL1                     (WSA884X_BOOST_BASE+0x1a)
+#define WSA884X_ILIM_CTRL2                     (WSA884X_BOOST_BASE+0x1b)
+#define WSA884X_TEST_CTRL1                     (WSA884X_BOOST_BASE+0x1c)
+#define WSA884X_TEST_CTRL2                     (WSA884X_BOOST_BASE+0x1d)
+#define WSA884X_SPARE1                         (WSA884X_BOOST_BASE+0x1e)
+#define WSA884X_BOOT_CAP_CHECK                 (WSA884X_BOOST_BASE+0x1f)
+
+#define WSA884X_PON_LDOL_BASE                  (WSA884X_BASE+0xb0)
+#define WSA884X_PON_CTL_0                      (WSA884X_PON_LDOL_BASE+0x00)
+#define WSA884X_PWRSAV_CTL                     (WSA884X_PON_LDOL_BASE+0x01)
+#define WSA884X_PON_LDOL_SPARE_CTL_0           (WSA884X_PON_LDOL_BASE+0x02)
+#define WSA884X_PON_LDOL_SPARE_CTL_1           (WSA884X_PON_LDOL_BASE+0x03)
+#define WSA884X_PON_LDOL_SPARE_CTL_2           (WSA884X_PON_LDOL_BASE+0x04)
+#define WSA884X_PON_LDOL_SPARE_CTL_3           (WSA884X_PON_LDOL_BASE+0x05)
+#define WSA884X_PON_CLT_1                      (WSA884X_PON_LDOL_BASE+0x06)
+#define WSA884X_PON_CTL_2                      (WSA884X_PON_LDOL_BASE+0x07)
+#define WSA884X_PON_CTL_3                      (WSA884X_PON_LDOL_BASE+0x08)
+#define WSA884X_CKWD_CTL_0                     (WSA884X_PON_LDOL_BASE+0x09)
+#define WSA884X_CKWD_CTL_1                     (WSA884X_PON_LDOL_BASE+0x0a)
+#define WSA884X_CKWD_CTL_2                     (WSA884X_PON_LDOL_BASE+0x0b)
+#define WSA884X_CKSK_CTL_0                     (WSA884X_PON_LDOL_BASE+0x0c)
+#define WSA884X_PADSW_CTL_0                    (WSA884X_PON_LDOL_BASE+0x0d)
+#define WSA884X_TEST_0                         (WSA884X_PON_LDOL_BASE+0x0e)
+#define WSA884X_TEST_1                         (WSA884X_PON_LDOL_BASE+0x0f)
+#define WSA884X_STATUS_0                       (WSA884X_PON_LDOL_BASE+0x10)
+#define WSA884X_STATUS_1                       (WSA884X_PON_LDOL_BASE+0x11)
+#define WSA884X_PON_LDOL_SPARE_TUNE_0          (WSA884X_PON_LDOL_BASE+0x12)
+#define WSA884X_PON_LDOL_SPARE_TUNE_1          (WSA884X_PON_LDOL_BASE+0x13)
+#define WSA884X_PON_LDOL_SPARE_TUNE_2          (WSA884X_PON_LDOL_BASE+0x14)
+#define WSA884X_PON_LDOL_SPARE_TUNE_3          (WSA884X_PON_LDOL_BASE+0x15)
+#define WSA884X_PON_LDOL_SPARE_TUNE_4          (WSA884X_PON_LDOL_BASE+0x16)
+
+#define WSA884X_DIG_CTRL0_BASE                 (WSA884X_BASE+0x400)
+#define WSA884X_DIG_CTRL0_PAGE                 (WSA884X_DIG_CTRL0_BASE+0x00)
+#define WSA884X_CHIP_ID0                       (WSA884X_DIG_CTRL0_BASE+0x01)
+#define WSA884X_CHIP_ID1                       (WSA884X_DIG_CTRL0_BASE+0x02)
+#define WSA884X_CHIP_ID2                       (WSA884X_DIG_CTRL0_BASE+0x03)
+#define WSA884X_CHIP_ID3                       (WSA884X_DIG_CTRL0_BASE+0x04)
+#define WSA884X_BUS_ID                         (WSA884X_DIG_CTRL0_BASE+0x05)
+#define WSA884X_CDC_RST_CTL                    (WSA884X_DIG_CTRL0_BASE+0x10)
+#define WSA884X_SWR_RESET_EN                   (WSA884X_DIG_CTRL0_BASE+0x14)
+#define WSA884X_TOP_CLK_CFG                    (WSA884X_DIG_CTRL0_BASE+0x18)
+#define WSA884X_SWR_CLK_RATE                   (WSA884X_DIG_CTRL0_BASE+0x19)
+#define WSA884X_CDC_PATH_MODE                  (WSA884X_DIG_CTRL0_BASE+0x1a)
+#define WSA884X_CDC_CLK_CTL                    (WSA884X_DIG_CTRL0_BASE+0x1c)
+#define WSA884X_PA_FSM_EN                      (WSA884X_DIG_CTRL0_BASE+0x30)
+#define WSA884X_PA_FSM_CTL0                    (WSA884X_DIG_CTRL0_BASE+0x31)
+#define WSA884X_PA_FSM_CTL1                    (WSA884X_DIG_CTRL0_BASE+0x32)
+#define WSA884X_PA_FSM_TIMER0                  (WSA884X_DIG_CTRL0_BASE+0x33)
+#define WSA884X_PA_FSM_TIMER1                  (WSA884X_DIG_CTRL0_BASE+0x34)
+#define WSA884X_PA_FSM_STA0                    (WSA884X_DIG_CTRL0_BASE+0x35)
+#define WSA884X_PA_FSM_STA1                    (WSA884X_DIG_CTRL0_BASE+0x36)
+#define WSA884X_PA_FSM_ERR_CTL                 (WSA884X_DIG_CTRL0_BASE+0x37)
+#define WSA884X_PA_FSM_ERR_COND0               (WSA884X_DIG_CTRL0_BASE+0x38)
+#define WSA884X_PA_FSM_ERR_COND1               (WSA884X_DIG_CTRL0_BASE+0x39)
+#define WSA884X_PA_FSM_MSK0                    (WSA884X_DIG_CTRL0_BASE+0x3a)
+#define WSA884X_PA_FSM_MSK1                    (WSA884X_DIG_CTRL0_BASE+0x3b)
+#define WSA884X_PA_FSM_BYP_CTL                 (WSA884X_DIG_CTRL0_BASE+0x3c)
+#define WSA884X_PA_FSM_BYP0                    (WSA884X_DIG_CTRL0_BASE+0x3d)
+#define WSA884X_PA_FSM_BYP1                    (WSA884X_DIG_CTRL0_BASE+0x3e)
+#define WSA884X_TADC_VALUE_CTL                 (WSA884X_DIG_CTRL0_BASE+0x50)
+#define WSA884X_TEMP_DETECT_CTL                (WSA884X_DIG_CTRL0_BASE+0x51)
+#define WSA884X_TEMP_DIN_MSB                   (WSA884X_DIG_CTRL0_BASE+0x52)
+#define WSA884X_TEMP_DIN_LSB                   (WSA884X_DIG_CTRL0_BASE+0x53)
+#define WSA884X_TEMP_DOUT_MSB                  (WSA884X_DIG_CTRL0_BASE+0x54)
+#define WSA884X_TEMP_DOUT_LSB                  (WSA884X_DIG_CTRL0_BASE+0x55)
+#define WSA884X_TEMP_CONFIG0                   (WSA884X_DIG_CTRL0_BASE+0x56)
+#define WSA884X_TEMP_CONFIG1                   (WSA884X_DIG_CTRL0_BASE+0x57)
+#define WSA884X_VBAT_THRM_FLT_CTL              (WSA884X_DIG_CTRL0_BASE+0x58)
+#define WSA884X_VBAT_CAL_CTL                   (WSA884X_DIG_CTRL0_BASE+0x59)
+#define WSA884X_VBAT_DIN_MSB                   (WSA884X_DIG_CTRL0_BASE+0x5a)
+#define WSA884X_VBAT_DIN_LSB                   (WSA884X_DIG_CTRL0_BASE+0x5b)
+#define WSA884X_VBAT_DOUT_MSB                  (WSA884X_DIG_CTRL0_BASE+0x5c)
+#define WSA884X_VBAT_DOUT_LSB                  (WSA884X_DIG_CTRL0_BASE+0x5d)
+#define WSA884X_VBAT_CAL_MSB                   (WSA884X_DIG_CTRL0_BASE+0x5e)
+#define WSA884X_VBAT_CAL_LSB                   (WSA884X_DIG_CTRL0_BASE+0x5f)
+#define WSA884X_UVLO_DEGLITCH_CTL              (WSA884X_DIG_CTRL0_BASE+0x60)
+#define WSA884X_BOP_DEGLITCH_CTL               (WSA884X_DIG_CTRL0_BASE+0x61)
+#define WSA884X_VBAT_ZONE_DETC_CTL             (WSA884X_DIG_CTRL0_BASE+0x64)
+#define WSA884X_CPS_CTL                        (WSA884X_DIG_CTRL0_BASE+0x68)
+#define WSA884X_CDC_RX_CTL                     (WSA884X_DIG_CTRL0_BASE+0x70)
+#define WSA884X_CDC_SPK_DSM_A1_0               (WSA884X_DIG_CTRL0_BASE+0x71)
+#define WSA884X_CDC_SPK_DSM_A1_1               (WSA884X_DIG_CTRL0_BASE+0x72)
+#define WSA884X_CDC_SPK_DSM_A2_0               (WSA884X_DIG_CTRL0_BASE+0x73)
+#define WSA884X_CDC_SPK_DSM_A2_1               (WSA884X_DIG_CTRL0_BASE+0x74)
+#define WSA884X_CDC_SPK_DSM_A3_0               (WSA884X_DIG_CTRL0_BASE+0x75)
+#define WSA884X_CDC_SPK_DSM_A3_1               (WSA884X_DIG_CTRL0_BASE+0x76)
+#define WSA884X_CDC_SPK_DSM_A4_0               (WSA884X_DIG_CTRL0_BASE+0x77)
+#define WSA884X_CDC_SPK_DSM_A4_1               (WSA884X_DIG_CTRL0_BASE+0x78)
+#define WSA884X_CDC_SPK_DSM_A5_0               (WSA884X_DIG_CTRL0_BASE+0x79)
+#define WSA884X_CDC_SPK_DSM_A5_1               (WSA884X_DIG_CTRL0_BASE+0x7a)
+#define WSA884X_CDC_SPK_DSM_A6_0               (WSA884X_DIG_CTRL0_BASE+0x7b)
+#define WSA884X_CDC_SPK_DSM_A7_0               (WSA884X_DIG_CTRL0_BASE+0x7c)
+#define WSA884X_CDC_SPK_DSM_C_0                (WSA884X_DIG_CTRL0_BASE+0x7d)
+#define WSA884X_CDC_SPK_DSM_C_1                (WSA884X_DIG_CTRL0_BASE+0x7e)
+#define WSA884X_CDC_SPK_DSM_C_2                (WSA884X_DIG_CTRL0_BASE+0x7f)
+#define WSA884X_CDC_SPK_DSM_C_3                (WSA884X_DIG_CTRL0_BASE+0x80)
+#define WSA884X_CDC_SPK_DSM_R1                 (WSA884X_DIG_CTRL0_BASE+0x81)
+#define WSA884X_CDC_SPK_DSM_R2                 (WSA884X_DIG_CTRL0_BASE+0x82)
+#define WSA884X_CDC_SPK_DSM_R3                 (WSA884X_DIG_CTRL0_BASE+0x83)
+#define WSA884X_CDC_SPK_DSM_R4                 (WSA884X_DIG_CTRL0_BASE+0x84)
+#define WSA884X_CDC_SPK_DSM_R5                 (WSA884X_DIG_CTRL0_BASE+0x85)
+#define WSA884X_CDC_SPK_DSM_R6                 (WSA884X_DIG_CTRL0_BASE+0x86)
+#define WSA884X_CDC_SPK_DSM_R7                 (WSA884X_DIG_CTRL0_BASE+0x87)
+#define WSA884X_CDC_SPK_GAIN_PDM_0             (WSA884X_DIG_CTRL0_BASE+0x88)
+#define WSA884X_CDC_SPK_GAIN_PDM_1             (WSA884X_DIG_CTRL0_BASE+0x89)
+#define WSA884X_CDC_SPK_GAIN_PDM_2             (WSA884X_DIG_CTRL0_BASE+0x8a)
+#define WSA884X_PDM_WD_CTL                     (WSA884X_DIG_CTRL0_BASE+0x8b)
+#define WSA884X_DEM_BYPASS_DATA0               (WSA884X_DIG_CTRL0_BASE+0x90)
+#define WSA884X_DEM_BYPASS_DATA1               (WSA884X_DIG_CTRL0_BASE+0x91)
+#define WSA884X_DEM_BYPASS_DATA2               (WSA884X_DIG_CTRL0_BASE+0x92)
+#define WSA884X_DEM_BYPASS_DATA3               (WSA884X_DIG_CTRL0_BASE+0x93)
+#define WSA884X_DRE_CTL_0                      (WSA884X_DIG_CTRL0_BASE+0xb0)
+#define WSA884X_DRE_CTL_1                      (WSA884X_DIG_CTRL0_BASE+0xb1)
+#define WSA884X_DRE_IDLE_DET_CTL               (WSA884X_DIG_CTRL0_BASE+0xb2)
+#define WSA884X_GAIN_RAMPING_CTL               (WSA884X_DIG_CTRL0_BASE+0xb8)
+#define WSA884X_GAIN_RAMPING_MIN               (WSA884X_DIG_CTRL0_BASE+0xb9)
+#define WSA884X_TAGC_CTL                       (WSA884X_DIG_CTRL0_BASE+0xc0)
+#define WSA884X_TAGC_TIME                      (WSA884X_DIG_CTRL0_BASE+0xc1)
+#define WSA884X_TAGC_FORCE_VAL                 (WSA884X_DIG_CTRL0_BASE+0xc2)
+#define WSA884X_VAGC_CTL                       (WSA884X_DIG_CTRL0_BASE+0xc8)
+#define WSA884X_VAGC_TIME                      (WSA884X_DIG_CTRL0_BASE+0xc9)
+#define WSA884X_VAGC_ATTN_LVL_1                (WSA884X_DIG_CTRL0_BASE+0xca)
+#define WSA884X_VAGC_ATTN_LVL_2                (WSA884X_DIG_CTRL0_BASE+0xcb)
+#define WSA884X_VAGC_ATTN_LVL_3                (WSA884X_DIG_CTRL0_BASE+0xcc)
+#define WSA884X_CLSH_CTL_0                     (WSA884X_DIG_CTRL0_BASE+0xd0)
+#define WSA884X_CLSH_CTL_1                     (WSA884X_DIG_CTRL0_BASE+0xd1)
+#define WSA884X_CLSH_V_HD_PA                   (WSA884X_DIG_CTRL0_BASE+0xd2)
+#define WSA884X_CLSH_V_PA_MIN                  (WSA884X_DIG_CTRL0_BASE+0xd3)
+#define WSA884X_CLSH_OVRD_VAL                  (WSA884X_DIG_CTRL0_BASE+0xd4)
+#define WSA884X_CLSH_HARD_MAX                  (WSA884X_DIG_CTRL0_BASE+0xd5)
+#define WSA884X_CLSH_SOFT_MAX                  (WSA884X_DIG_CTRL0_BASE+0xd6)
+#define WSA884X_CLSH_SIG_DP                    (WSA884X_DIG_CTRL0_BASE+0xd7)
+#define WSA884X_PBR_DELAY_CTL                  (WSA884X_DIG_CTRL0_BASE+0xd8)
+#define WSA884X_CLSH_SRL_MAX_PBR               (WSA884X_DIG_CTRL0_BASE+0xe0)
+#define WSA884X_CLSH_VTH1                      (WSA884X_DIG_CTRL0_BASE+0xe1)
+#define WSA884X_CLSH_VTH2                      (WSA884X_DIG_CTRL0_BASE+0xe2)
+#define WSA884X_CLSH_VTH3                      (WSA884X_DIG_CTRL0_BASE+0xe3)
+#define WSA884X_CLSH_VTH4                      (WSA884X_DIG_CTRL0_BASE+0xe4)
+#define WSA884X_CLSH_VTH5                      (WSA884X_DIG_CTRL0_BASE+0xe5)
+#define WSA884X_CLSH_VTH6                      (WSA884X_DIG_CTRL0_BASE+0xe6)
+#define WSA884X_CLSH_VTH7                      (WSA884X_DIG_CTRL0_BASE+0xe7)
+#define WSA884X_CLSH_VTH8                      (WSA884X_DIG_CTRL0_BASE+0xe8)
+#define WSA884X_CLSH_VTH9                      (WSA884X_DIG_CTRL0_BASE+0xe9)
+#define WSA884X_CLSH_VTH10                     (WSA884X_DIG_CTRL0_BASE+0xea)
+#define WSA884X_CLSH_VTH11                     (WSA884X_DIG_CTRL0_BASE+0xeb)
+#define WSA884X_CLSH_VTH12                     (WSA884X_DIG_CTRL0_BASE+0xec)
+#define WSA884X_CLSH_VTH13                     (WSA884X_DIG_CTRL0_BASE+0xed)
+#define WSA884X_CLSH_VTH14                     (WSA884X_DIG_CTRL0_BASE+0xee)
+#define WSA884X_CLSH_VTH15                     (WSA884X_DIG_CTRL0_BASE+0xef)
+
+#define WSA884X_DIG_CTRL1_BASE                 (WSA884X_BASE+0x500)
+#define WSA884X_DIG_CTRL1_PAGE                 (WSA884X_DIG_CTRL1_BASE+0x00)
+#define WSA884X_BST_CFG                        (WSA884X_DIG_CTRL1_BASE+0x01)
+#define WSA884X_ANA_WO_CTL_0                   (WSA884X_DIG_CTRL1_BASE+0x04)
+#define WSA884X_ANA_WO_CTL_1                   (WSA884X_DIG_CTRL1_BASE+0x05)
+#define WSA884X_PIN_CTL                        (WSA884X_DIG_CTRL1_BASE+0x10)
+#define WSA884X_PIN_CTL_OE                     (WSA884X_DIG_CTRL1_BASE+0x11)
+#define WSA884X_PIN_WDATA_IOPAD                (WSA884X_DIG_CTRL1_BASE+0x12)
+#define WSA884X_PIN_STATUS                     (WSA884X_DIG_CTRL1_BASE+0x13)
+#define WSA884X_I2C_SLAVE_CTL                  (WSA884X_DIG_CTRL1_BASE+0x14)
+#define WSA884X_SPMI_PAD_CTL0                  (WSA884X_DIG_CTRL1_BASE+0x15)
+#define WSA884X_SPMI_PAD_CTL1                  (WSA884X_DIG_CTRL1_BASE+0x16)
+#define WSA884X_SPMI_PAD_CTL2                  (WSA884X_DIG_CTRL1_BASE+0x17)
+#define WSA884X_MEM_CTL                        (WSA884X_DIG_CTRL1_BASE+0x18)
+#define WSA884X_SWR_HM_TEST0                   (WSA884X_DIG_CTRL1_BASE+0x19)
+#define WSA884X_SWR_HM_TEST1                   (WSA884X_DIG_CTRL1_BASE+0x1a)
+#define WSA884X_OTP_CTRL0                      (WSA884X_DIG_CTRL1_BASE+0x30)
+#define WSA884X_OTP_CTRL1                      (WSA884X_DIG_CTRL1_BASE+0x31)
+#define WSA884X_OTP_CTRL2                      (WSA884X_DIG_CTRL1_BASE+0x32)
+#define WSA884X_OTP_STAT                       (WSA884X_DIG_CTRL1_BASE+0x33)
+#define WSA884X_OTP_PRG_TCSP0                  (WSA884X_DIG_CTRL1_BASE+0x34)
+#define WSA884X_OTP_PRG_TCSP1                  (WSA884X_DIG_CTRL1_BASE+0x35)
+#define WSA884X_OTP_PRG_TPPS                   (WSA884X_DIG_CTRL1_BASE+0x36)
+#define WSA884X_OTP_PRG_TVPS                   (WSA884X_DIG_CTRL1_BASE+0x37)
+#define WSA884X_OTP_PRG_TVPH                   (WSA884X_DIG_CTRL1_BASE+0x38)
+#define WSA884X_OTP_PRG_TPPR0                  (WSA884X_DIG_CTRL1_BASE+0x39)
+#define WSA884X_OTP_PRG_TPPR1                  (WSA884X_DIG_CTRL1_BASE+0x3a)
+#define WSA884X_OTP_PRG_TPPH                   (WSA884X_DIG_CTRL1_BASE+0x3b)
+#define WSA884X_OTP_PRG_END                    (WSA884X_DIG_CTRL1_BASE+0x3c)
+#define WSA884X_WAVG_PLAY                      (WSA884X_DIG_CTRL1_BASE+0x40)
+#define WSA884X_WAVG_CTL                       (WSA884X_DIG_CTRL1_BASE+0x41)
+#define WSA884X_WAVG_LRA_PER_0                 (WSA884X_DIG_CTRL1_BASE+0x43)
+#define WSA884X_WAVG_LRA_PER_1                 (WSA884X_DIG_CTRL1_BASE+0x44)
+#define WSA884X_WAVG_DELTA_THETA_0             (WSA884X_DIG_CTRL1_BASE+0x45)
+#define WSA884X_WAVG_DELTA_THETA_1             (WSA884X_DIG_CTRL1_BASE+0x46)
+#define WSA884X_WAVG_DIRECT_AMP_0              (WSA884X_DIG_CTRL1_BASE+0x47)
+#define WSA884X_WAVG_DIRECT_AMP_1              (WSA884X_DIG_CTRL1_BASE+0x48)
+#define WSA884X_WAVG_PTRN_AMP0_0               (WSA884X_DIG_CTRL1_BASE+0x49)
+#define WSA884X_WAVG_PTRN_AMP0_1               (WSA884X_DIG_CTRL1_BASE+0x4a)
+#define WSA884X_WAVG_PTRN_AMP1_0               (WSA884X_DIG_CTRL1_BASE+0x4b)
+#define WSA884X_WAVG_PTRN_AMP1_1               (WSA884X_DIG_CTRL1_BASE+0x4c)
+#define WSA884X_WAVG_PTRN_AMP2_0               (WSA884X_DIG_CTRL1_BASE+0x4d)
+#define WSA884X_WAVG_PTRN_AMP2_1               (WSA884X_DIG_CTRL1_BASE+0x4e)
+#define WSA884X_WAVG_PTRN_AMP3_0               (WSA884X_DIG_CTRL1_BASE+0x4f)
+#define WSA884X_WAVG_PTRN_AMP3_1               (WSA884X_DIG_CTRL1_BASE+0x50)
+#define WSA884X_WAVG_PTRN_AMP4_0               (WSA884X_DIG_CTRL1_BASE+0x51)
+#define WSA884X_WAVG_PTRN_AMP4_1               (WSA884X_DIG_CTRL1_BASE+0x52)
+#define WSA884X_WAVG_PTRN_AMP5_0               (WSA884X_DIG_CTRL1_BASE+0x53)
+#define WSA884X_WAVG_PTRN_AMP5_1               (WSA884X_DIG_CTRL1_BASE+0x54)
+#define WSA884X_WAVG_PTRN_AMP6_0               (WSA884X_DIG_CTRL1_BASE+0x55)
+#define WSA884X_WAVG_PTRN_AMP6_1               (WSA884X_DIG_CTRL1_BASE+0x56)
+#define WSA884X_WAVG_PTRN_AMP7_0               (WSA884X_DIG_CTRL1_BASE+0x57)
+#define WSA884X_WAVG_PTRN_AMP7_1               (WSA884X_DIG_CTRL1_BASE+0x58)
+#define WSA884X_WAVG_PER_0_1                   (WSA884X_DIG_CTRL1_BASE+0x59)
+#define WSA884X_WAVG_PER_2_3                   (WSA884X_DIG_CTRL1_BASE+0x5a)
+#define WSA884X_WAVG_PER_4_5                   (WSA884X_DIG_CTRL1_BASE+0x5b)
+#define WSA884X_WAVG_PER_6_7                   (WSA884X_DIG_CTRL1_BASE+0x5c)
+#define WSA884X_WAVG_STA                       (WSA884X_DIG_CTRL1_BASE+0x5d)
+#define WSA884X_INTR_MODE                      (WSA884X_DIG_CTRL1_BASE+0x80)
+#define WSA884X_INTR_MASK0                     (WSA884X_DIG_CTRL1_BASE+0x81)
+#define WSA884X_INTR_MASK1                     (WSA884X_DIG_CTRL1_BASE+0x82)
+#define WSA884X_INTR_STATUS0                   (WSA884X_DIG_CTRL1_BASE+0x83)
+#define WSA884X_INTR_STATUS1                   (WSA884X_DIG_CTRL1_BASE+0x84)
+#define WSA884X_INTR_CLEAR0                    (WSA884X_DIG_CTRL1_BASE+0x85)
+#define WSA884X_INTR_CLEAR1                    (WSA884X_DIG_CTRL1_BASE+0x86)
+#define WSA884X_INTR_LEVEL0                    (WSA884X_DIG_CTRL1_BASE+0x87)
+#define WSA884X_INTR_LEVEL1                    (WSA884X_DIG_CTRL1_BASE+0x88)
+#define WSA884X_INTR_SET0                      (WSA884X_DIG_CTRL1_BASE+0x89)
+#define WSA884X_INTR_SET1                      (WSA884X_DIG_CTRL1_BASE+0x8a)
+#define WSA884X_INTR_TEST0                     (WSA884X_DIG_CTRL1_BASE+0x8b)
+#define WSA884X_INTR_TEST1                     (WSA884X_DIG_CTRL1_BASE+0x8c)
+#define WSA884X_PDM_TEST_MODE                  (WSA884X_DIG_CTRL1_BASE+0xc0)
+#define WSA884X_ATE_TEST_MODE                  (WSA884X_DIG_CTRL1_BASE+0xc1)
+#define WSA884X_PA_FSM_DBG                     (WSA884X_DIG_CTRL1_BASE+0xc2)
+#define WSA884X_DIG_DEBUG_MODE                 (WSA884X_DIG_CTRL1_BASE+0xc3)
+#define WSA884X_DIG_DEBUG_SEL                  (WSA884X_DIG_CTRL1_BASE+0xc4)
+#define WSA884X_DIG_DEBUG_EN                   (WSA884X_DIG_CTRL1_BASE+0xc5)
+#define WSA884X_TADC_DETECT_DBG_CTL            (WSA884X_DIG_CTRL1_BASE+0xc9)
+#define WSA884X_TADC_DEBUG_MSB                 (WSA884X_DIG_CTRL1_BASE+0xca)
+#define WSA884X_TADC_DEBUG_LSB                 (WSA884X_DIG_CTRL1_BASE+0xcb)
+#define WSA884X_SAMPLE_EDGE_SEL                (WSA884X_DIG_CTRL1_BASE+0xcc)
+#define WSA884X_SWR_EDGE_SEL                   (WSA884X_DIG_CTRL1_BASE+0xcd)
+#define WSA884X_TEST_MODE_CTL                  (WSA884X_DIG_CTRL1_BASE+0xce)
+#define WSA884X_IOPAD_CTL                      (WSA884X_DIG_CTRL1_BASE+0xcf)
+#define WSA884X_ANA_CSR_DBG_ADD                (WSA884X_DIG_CTRL1_BASE+0xd0)
+#define WSA884X_ANA_CSR_DBG_CTL                (WSA884X_DIG_CTRL1_BASE+0xd1)
+#define WSA884X_CLK_DBG_CTL                    (WSA884X_DIG_CTRL1_BASE+0xd2)
+#define WSA884X_SPARE_R                        (WSA884X_DIG_CTRL1_BASE+0xf0)
+#define WSA884X_SPARE_0                        (WSA884X_DIG_CTRL1_BASE+0xf1)
+#define WSA884X_SPARE_1                        (WSA884X_DIG_CTRL1_BASE+0xf2)
+#define WSA884X_SPARE_2                        (WSA884X_DIG_CTRL1_BASE+0xf3)
+#define WSA884X_SCODE                          (WSA884X_DIG_CTRL1_BASE+0xff)
+
+#define WSA884X_DIG_TRIM_BASE                  (WSA884X_BASE+0x800)
+#define WSA884X_DIG_TRIM_PAGE                  (WSA884X_DIG_TRIM_BASE+0x00)
+#define WSA884X_OTP_REG_0                      (WSA884X_DIG_TRIM_BASE+0x80)
+#define WSA884X_OTP_REG_1                      (WSA884X_DIG_TRIM_BASE+0x81)
+#define WSA884X_OTP_REG_2                      (WSA884X_DIG_TRIM_BASE+0x82)
+#define WSA884X_OTP_REG_3                      (WSA884X_DIG_TRIM_BASE+0x83)
+#define WSA884X_OTP_REG_4                      (WSA884X_DIG_TRIM_BASE+0x84)
+#define WSA884X_OTP_REG_5                      (WSA884X_DIG_TRIM_BASE+0x85)
+#define WSA884X_OTP_REG_6                      (WSA884X_DIG_TRIM_BASE+0x86)
+#define WSA884X_OTP_REG_7                      (WSA884X_DIG_TRIM_BASE+0x87)
+#define WSA884X_OTP_REG_8                      (WSA884X_DIG_TRIM_BASE+0x88)
+#define WSA884X_OTP_REG_9                      (WSA884X_DIG_TRIM_BASE+0x89)
+#define WSA884X_OTP_REG_10                     (WSA884X_DIG_TRIM_BASE+0x8a)
+#define WSA884X_OTP_REG_11                     (WSA884X_DIG_TRIM_BASE+0x8b)
+#define WSA884X_OTP_REG_12                     (WSA884X_DIG_TRIM_BASE+0x8c)
+#define WSA884X_OTP_REG_13                     (WSA884X_DIG_TRIM_BASE+0x8d)
+#define WSA884X_OTP_REG_14                     (WSA884X_DIG_TRIM_BASE+0x8e)
+#define WSA884X_OTP_REG_15                     (WSA884X_DIG_TRIM_BASE+0x8f)
+#define WSA884X_OTP_REG_16                     (WSA884X_DIG_TRIM_BASE+0x90)
+#define WSA884X_OTP_REG_17                     (WSA884X_DIG_TRIM_BASE+0x91)
+#define WSA884X_OTP_REG_18                     (WSA884X_DIG_TRIM_BASE+0x92)
+#define WSA884X_OTP_REG_19                     (WSA884X_DIG_TRIM_BASE+0x93)
+#define WSA884X_OTP_REG_20                     (WSA884X_DIG_TRIM_BASE+0x94)
+#define WSA884X_OTP_REG_21                     (WSA884X_DIG_TRIM_BASE+0x95)
+#define WSA884X_OTP_REG_22                     (WSA884X_DIG_TRIM_BASE+0x96)
+#define WSA884X_OTP_REG_23                     (WSA884X_DIG_TRIM_BASE+0x97)
+#define WSA884X_OTP_REG_24                     (WSA884X_DIG_TRIM_BASE+0x98)
+#define WSA884X_OTP_REG_25                     (WSA884X_DIG_TRIM_BASE+0x99)
+#define WSA884X_OTP_REG_26                     (WSA884X_DIG_TRIM_BASE+0x9a)
+#define WSA884X_OTP_REG_27                     (WSA884X_DIG_TRIM_BASE+0x9b)
+#define WSA884X_OTP_REG_28                     (WSA884X_DIG_TRIM_BASE+0x9c)
+#define WSA884X_OTP_REG_29                     (WSA884X_DIG_TRIM_BASE+0x9d)
+#define WSA884X_OTP_REG_30                     (WSA884X_DIG_TRIM_BASE+0x9e)
+#define WSA884X_OTP_REG_31                     (WSA884X_DIG_TRIM_BASE+0x9f)
+#define WSA884X_OTP_REG_32                     (WSA884X_DIG_TRIM_BASE+0xa0)
+#define WSA884X_OTP_REG_33                     (WSA884X_DIG_TRIM_BASE+0xa1)
+#define WSA884X_OTP_REG_34                     (WSA884X_DIG_TRIM_BASE+0xa2)
+#define WSA884X_OTP_REG_35                     (WSA884X_DIG_TRIM_BASE+0xa3)
+#define WSA884X_OTP_REG_36                     (WSA884X_DIG_TRIM_BASE+0xa4)
+#define WSA884X_OTP_REG_37                     (WSA884X_DIG_TRIM_BASE+0xa5)
+#define WSA884X_OTP_REG_38                     (WSA884X_DIG_TRIM_BASE+0xa6)
+#define WSA884X_OTP_REG_39                     (WSA884X_DIG_TRIM_BASE+0xa7)
+#define WSA884X_OTP_REG_40                     (WSA884X_DIG_TRIM_BASE+0xa8)
+#define WSA884X_OTP_REG_41                     (WSA884X_DIG_TRIM_BASE+0xa9)
+#define WSA884X_OTP_REG_63                     (WSA884X_DIG_TRIM_BASE+0xbf)
+
+#define WSA884X_EMEM_BASE                      (WSA884X_BASE+0x8c0)
+#define WSA884X_EMEM_0                         (WSA884X_EMEM_BASE+0x00)
+#define WSA884X_EMEM_1                         (WSA884X_EMEM_BASE+0x01)
+#define WSA884X_EMEM_2                         (WSA884X_EMEM_BASE+0x02)
+#define WSA884X_EMEM_3                         (WSA884X_EMEM_BASE+0x03)
+#define WSA884X_EMEM_4                         (WSA884X_EMEM_BASE+0x04)
+#define WSA884X_EMEM_5                         (WSA884X_EMEM_BASE+0x05)
+#define WSA884X_EMEM_6                         (WSA884X_EMEM_BASE+0x06)
+#define WSA884X_EMEM_7                         (WSA884X_EMEM_BASE+0x07)
+#define WSA884X_EMEM_8                         (WSA884X_EMEM_BASE+0x08)
+#define WSA884X_EMEM_9                         (WSA884X_EMEM_BASE+0x09)
+#define WSA884X_EMEM_10                        (WSA884X_EMEM_BASE+0x0a)
+#define WSA884X_EMEM_11                        (WSA884X_EMEM_BASE+0x0b)
+#define WSA884X_EMEM_12                        (WSA884X_EMEM_BASE+0x0c)
+#define WSA884X_EMEM_13                        (WSA884X_EMEM_BASE+0x0d)
+#define WSA884X_EMEM_14                        (WSA884X_EMEM_BASE+0x0e)
+#define WSA884X_EMEM_15                        (WSA884X_EMEM_BASE+0x0f)
+#define WSA884X_EMEM_16                        (WSA884X_EMEM_BASE+0x10)
+#define WSA884X_EMEM_17                        (WSA884X_EMEM_BASE+0x11)
+#define WSA884X_EMEM_18                        (WSA884X_EMEM_BASE+0x12)
+#define WSA884X_EMEM_19                        (WSA884X_EMEM_BASE+0x13)
+#define WSA884X_EMEM_20                        (WSA884X_EMEM_BASE+0x14)
+#define WSA884X_EMEM_21                        (WSA884X_EMEM_BASE+0x15)
+#define WSA884X_EMEM_22                        (WSA884X_EMEM_BASE+0x16)
+#define WSA884X_EMEM_23                        (WSA884X_EMEM_BASE+0x17)
+#define WSA884X_EMEM_24                        (WSA884X_EMEM_BASE+0x18)
+#define WSA884X_EMEM_25                        (WSA884X_EMEM_BASE+0x19)
+#define WSA884X_EMEM_26                        (WSA884X_EMEM_BASE+0x1a)
+#define WSA884X_EMEM_27                        (WSA884X_EMEM_BASE+0x1b)
+#define WSA884X_EMEM_28                        (WSA884X_EMEM_BASE+0x1c)
+#define WSA884X_EMEM_29                        (WSA884X_EMEM_BASE+0x1d)
+#define WSA884X_EMEM_30                        (WSA884X_EMEM_BASE+0x1e)
+#define WSA884X_EMEM_31                        (WSA884X_EMEM_BASE+0x1f)
+#define WSA884X_EMEM_32                        (WSA884X_EMEM_BASE+0x20)
+#define WSA884X_EMEM_33                        (WSA884X_EMEM_BASE+0x21)
+#define WSA884X_EMEM_34                        (WSA884X_EMEM_BASE+0x22)
+#define WSA884X_EMEM_35                        (WSA884X_EMEM_BASE+0x23)
+#define WSA884X_EMEM_36                        (WSA884X_EMEM_BASE+0x24)
+#define WSA884X_EMEM_37                        (WSA884X_EMEM_BASE+0x25)
+#define WSA884X_EMEM_38                        (WSA884X_EMEM_BASE+0x26)
+#define WSA884X_EMEM_39                        (WSA884X_EMEM_BASE+0x27)
+#define WSA884X_EMEM_40                        (WSA884X_EMEM_BASE+0x28)
+#define WSA884X_EMEM_41                        (WSA884X_EMEM_BASE+0x29)
+#define WSA884X_EMEM_42                        (WSA884X_EMEM_BASE+0x2a)
+#define WSA884X_EMEM_43                        (WSA884X_EMEM_BASE+0x2b)
+#define WSA884X_EMEM_44                        (WSA884X_EMEM_BASE+0x2c)
+#define WSA884X_EMEM_45                        (WSA884X_EMEM_BASE+0x2d)
+#define WSA884X_EMEM_46                        (WSA884X_EMEM_BASE+0x2e)
+#define WSA884X_EMEM_47                        (WSA884X_EMEM_BASE+0x2f)
+#define WSA884X_EMEM_48                        (WSA884X_EMEM_BASE+0x30)
+#define WSA884X_EMEM_49                        (WSA884X_EMEM_BASE+0x31)
+#define WSA884X_EMEM_50                        (WSA884X_EMEM_BASE+0x32)
+#define WSA884X_EMEM_51                        (WSA884X_EMEM_BASE+0x33)
+#define WSA884X_EMEM_52                        (WSA884X_EMEM_BASE+0x34)
+#define WSA884X_EMEM_53                        (WSA884X_EMEM_BASE+0x35)
+#define WSA884X_EMEM_54                        (WSA884X_EMEM_BASE+0x36)
+#define WSA884X_EMEM_55                        (WSA884X_EMEM_BASE+0x37)
+#define WSA884X_EMEM_56                        (WSA884X_EMEM_BASE+0x38)
+#define WSA884X_EMEM_57                        (WSA884X_EMEM_BASE+0x39)
+#define WSA884X_EMEM_58                        (WSA884X_EMEM_BASE+0x3a)
+#define WSA884X_EMEM_59                        (WSA884X_EMEM_BASE+0x3b)
+#define WSA884X_EMEM_60                        (WSA884X_EMEM_BASE+0x3c)
+#define WSA884X_EMEM_61                        (WSA884X_EMEM_BASE+0x3d)
+#define WSA884X_EMEM_62                        (WSA884X_EMEM_BASE+0x3e)
+#define WSA884X_EMEM_63                        (WSA884X_EMEM_BASE+0x3f)
+
+#define WSA884X_NUM_REGISTERS                  (WSA884X_EMEM_63+1)
+#define WSA884X_MAX_REGISTER                   (WSA884X_NUM_REGISTERS-1)
+
+#endif /* WSA884X_REGISTERS_H */

+ 544 - 0
asoc/codecs/wsa884x/wsa884x-regmap.c

@@ -0,0 +1,544 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/regmap.h>
+#include <linux/device.h>
+#include "wsa884x-registers.h"
+#include "wsa884x.h"
+
+extern const u8 wsa884x_reg_access[WSA884X_NUM_REGISTERS];
+
+static struct reg_default wsa884x_defaults[] = {
+	{WSA884X_BG_CTRL,                        0xa5},
+	{WSA884X_ADC_CTRL,                       0x00},
+	{WSA884X_BOP1_PROG,                      0x22},
+	{WSA884X_BOP2_PROG,                      0x44},
+	{WSA884X_UVLO_PROG,                      0x99},
+	{WSA884X_UVLO_PROG1,                     0x70},
+	{WSA884X_SPARE_CTRL_0,                   0x00},
+	{WSA884X_SPARE_CTRL_1,                   0x00},
+	{WSA884X_SPARE_CTRL_2,                   0x00},
+	{WSA884X_SPARE_CTRL_3,                   0x00},
+	{WSA884X_REF_CTRL,                       0xd2},
+	{WSA884X_BG_TEST_CTL,                    0x06},
+	{WSA884X_BG_BIAS,                        0xd7},
+	{WSA884X_ADC_PROG,                       0x08},
+	{WSA884X_ADC_IREF_CTL,                   0x57},
+	{WSA884X_ADC_ISENS_CTL,                  0x47},
+	{WSA884X_ADC_CLK_CTL,                    0x87},
+	{WSA884X_ADC_TEST_CTL,                   0x00},
+	{WSA884X_ADC_BIAS,                       0x51},
+	{WSA884X_VBAT_SNS,                       0xa0},
+	{WSA884X_DOUT_MSB,                       0x00},
+	{WSA884X_DOUT_LSB,                       0x00},
+	{WSA884X_BOP_ATEST_SEL,                  0x00},
+	{WSA884X_MISC0,                          0x04},
+	{WSA884X_MISC1,                          0x75},
+	{WSA884X_MISC2,                          0x00},
+	{WSA884X_MISC3,                          0x10},
+	{WSA884X_SPARE_TSBG_0,                   0x00},
+	{WSA884X_SPARE_TUNE_0,                   0x00},
+	{WSA884X_SPARE_TUNE_1,                   0x00},
+	{WSA884X_VSENSE1,                        0xe7},
+	{WSA884X_ISENSE2,                        0x27},
+	{WSA884X_SPARE_CTL_1,                    0x00},
+	{WSA884X_SPARE_CTL_2,                    0x00},
+	{WSA884X_SPARE_CTL_3,                    0x00},
+	{WSA884X_SPARE_CTL_4,                    0x00},
+	{WSA884X_EN,                             0x10},
+	{WSA884X_OVERRIDE1,                      0x00},
+	{WSA884X_OVERRIDE2,                      0x08},
+	{WSA884X_ISENSE1,                        0xd4},
+	{WSA884X_ISENSE_CAL,                     0x00},
+	{WSA884X_MISC,                           0x00},
+	{WSA884X_ADC_0,                          0x00},
+	{WSA884X_ADC_1,                          0x00},
+	{WSA884X_ADC_2,                          0x40},
+	{WSA884X_ADC_3,                          0x80},
+	{WSA884X_ADC_4,                          0x25},
+	{WSA884X_ADC_5,                          0x24},
+	{WSA884X_ADC_6,                          0x0a},
+	{WSA884X_ADC_7,                          0x81},
+	{WSA884X_STATUS,                         0x00},
+	{WSA884X_IVSENSE_SPARE_TUNE_1,           0x00},
+	{WSA884X_SPARE_TUNE_2,                   0x00},
+	{WSA884X_SPARE_TUNE_3,                   0x00},
+	{WSA884X_SPARE_TUNE_4,                   0x00},
+	{WSA884X_TOP_CTRL1,                      0xd3},
+	{WSA884X_CLIP_DET_CTRL1,                 0x7e},
+	{WSA884X_CLIP_DET_CTRL2,                 0x4c},
+	{WSA884X_DAC_CTRL1,                      0xa4},
+	{WSA884X_DAC_VCM_CTRL_REG1,              0x02},
+	{WSA884X_DAC_VCM_CTRL_REG2,              0x00},
+	{WSA884X_DAC_VCM_CTRL_REG3,              0x00},
+	{WSA884X_DAC_VCM_CTRL_REG4,              0x00},
+	{WSA884X_DAC_VCM_CTRL_REG5,              0x00},
+	{WSA884X_DAC_VCM_CTRL_REG6,              0x00},
+	{WSA884X_PWM_CLK_CTL,                    0x20},
+	{WSA884X_DRV_LF_LDO_SEL,                 0xaa},
+	{WSA884X_OCP_CTL,                        0xc6},
+	{WSA884X_PDRV_HS_CTL,                    0x52},
+	{WSA884X_PDRV_LS_CTL,                    0x4a},
+	{WSA884X_SPK_TOP_SPARE_CTL_1,            0x00},
+	{WSA884X_SPK_TOP_SPARE_CTL_2,            0x00},
+	{WSA884X_SPK_TOP_SPARE_CTL_3,            0x00},
+	{WSA884X_SPK_TOP_SPARE_CTL_4,            0x00},
+	{WSA884X_SPARE_CTL_5,                    0x00},
+	{WSA884X_DAC_EN_DEBUG_REG,               0x00},
+	{WSA884X_DAC_OPAMP_BIAS1_REG,            0x48},
+	{WSA884X_DAC_OPAMP_BIAS2_REG,            0x48},
+	{WSA884X_DAC_TUNE1,                      0x02},
+	{WSA884X_DAC_VOLTAGE_CTRL_REG,           0x05},
+	{WSA884X_ATEST1_REG,                     0x00},
+	{WSA884X_ATEST2_REG,                     0x00},
+	{WSA884X_TOP_BIAS_REG1,                  0x6a},
+	{WSA884X_TOP_BIAS_REG2,                  0x65},
+	{WSA884X_TOP_BIAS_REG3,                  0x55},
+	{WSA884X_TOP_BIAS_REG4,                  0xa9},
+	{WSA884X_PWRSTG_DBG2,                    0x21},
+	{WSA884X_DRV_LF_BLK_EN,                  0x0f},
+	{WSA884X_DRV_LF_EN,                      0x0a},
+	{WSA884X_DRV_LF_MASK_DCC_CTL,            0x08},
+	{WSA884X_DRV_LF_MISC_CTL1,               0x30},
+	{WSA884X_DRV_LF_REG_GAIN,                0x00},
+	{WSA884X_DRV_OS_CAL_CTL,                 0x00},
+	{WSA884X_DRV_OS_CAL_CTL1,                0x90},
+	{WSA884X_PWRSTG_DBG,                     0x08},
+	{WSA884X_BBM_CTL,                        0x92},
+	{WSA884X_TOP_MISC1,                      0x00},
+	{WSA884X_DAC_VCM_CTRL_REG7,              0x00},
+	{WSA884X_TOP_BIAS_REG5,                  0x15},
+	{WSA884X_DRV_LF_MISC_CTL2,               0x00},
+	{WSA884X_SPK_TOP_SPARE_TUNE_2,           0x00},
+	{WSA884X_SPK_TOP_SPARE_TUNE_3,           0x00},
+	{WSA884X_SPK_TOP_SPARE_TUNE_4,           0x00},
+	{WSA884X_SPARE_TUNE_5,                   0x00},
+	{WSA884X_SPARE_TUNE_6,                   0x00},
+	{WSA884X_SPARE_TUNE_7,                   0x00},
+	{WSA884X_SPARE_TUNE_8,                   0x00},
+	{WSA884X_SPARE_TUNE_9,                   0x00},
+	{WSA884X_SPARE_TUNE_10,                  0x00},
+	{WSA884X_PA_STATUS0,                     0x00},
+	{WSA884X_PA_STATUS1,                     0x00},
+	{WSA884X_PA_STATUS2,                     0x00},
+	{WSA884X_PA_STATUS3,                     0x00},
+	{WSA884X_PA_STATUS4,                     0x00},
+	{WSA884X_PA_STATUS5,                     0x00},
+	{WSA884X_SPARE_RO_1,                     0x00},
+	{WSA884X_SPARE_RO_2,                     0x00},
+	{WSA884X_SPARE_RO_3,                     0x00},
+	{WSA884X_STB_CTRL1,                      0x42},
+	{WSA884X_CURRENT_LIMIT,                  0x54},
+	{WSA884X_BYP_CTRL1,                      0x01},
+	{WSA884X_SPARE_CTL_0,                    0x00},
+	{WSA884X_BOOST_SPARE_CTL_1,              0x00},
+	{WSA884X_SPARE_RO_0,                     0x00},
+	{WSA884X_BOOST_SPARE_RO_1,               0x00},
+	{WSA884X_IBIAS1,                         0x00},
+	{WSA884X_IBIAS2,                         0x00},
+	{WSA884X_IBIAS3,                         0x00},
+	{WSA884X_EN_CTRL,                        0x42},
+	{WSA884X_STB_CTRL2,                      0x03},
+	{WSA884X_STB_CTRL3,                      0x3c},
+	{WSA884X_STB_CTRL4,                      0x30},
+	{WSA884X_BYP_CTRL2,                      0x97},
+	{WSA884X_BYP_CTRL3,                      0x11},
+	{WSA884X_ZX_CTRL1,                       0xf0},
+	{WSA884X_ZX_CTRL2,                       0x04},
+	{WSA884X_BLEEDER_CTRL,                   0x04},
+	{WSA884X_BOOST_MISC,                     0x62},
+	{WSA884X_PWRSTAGE_CTRL1,                 0x00},
+	{WSA884X_PWRSTAGE_CTRL2,                 0x31},
+	{WSA884X_PWRSTAGE_CTRL3,                 0x81},
+	{WSA884X_PWRSTAGE_CTRL4,                 0x5f},
+	{WSA884X_MAXD_REG1,                      0x00},
+	{WSA884X_MAXD_REG2,                      0x5b},
+	{WSA884X_ILIM_CTRL1,                     0xe2},
+	{WSA884X_ILIM_CTRL2,                     0x90},
+	{WSA884X_TEST_CTRL1,                     0x00},
+	{WSA884X_TEST_CTRL2,                     0x00},
+	{WSA884X_SPARE1,                         0x00},
+	{WSA884X_BOOT_CAP_CHECK,                 0x01},
+	{WSA884X_PON_CTL_0,                      0x12},
+	{WSA884X_PWRSAV_CTL,                     0xaa},
+	{WSA884X_PON_LDOL_SPARE_CTL_0,           0x00},
+	{WSA884X_PON_LDOL_SPARE_CTL_1,           0x00},
+	{WSA884X_PON_LDOL_SPARE_CTL_2,           0x00},
+	{WSA884X_PON_LDOL_SPARE_CTL_3,           0x00},
+	{WSA884X_PON_CLT_1,                      0xe1},
+	{WSA884X_PON_CTL_2,                      0x00},
+	{WSA884X_PON_CTL_3,                      0x70},
+	{WSA884X_CKWD_CTL_0,                     0x14},
+	{WSA884X_CKWD_CTL_1,                     0x3b},
+	{WSA884X_CKWD_CTL_2,                     0x00},
+	{WSA884X_CKSK_CTL_0,                     0x00},
+	{WSA884X_PADSW_CTL_0,                    0x00},
+	{WSA884X_TEST_0,                         0x00},
+	{WSA884X_TEST_1,                         0x00},
+	{WSA884X_STATUS_0,                       0x00},
+	{WSA884X_STATUS_1,                       0x00},
+	{WSA884X_PON_LDOL_SPARE_TUNE_0,          0x00},
+	{WSA884X_PON_LDOL_SPARE_TUNE_1,          0x00},
+	{WSA884X_PON_LDOL_SPARE_TUNE_2,          0x00},
+	{WSA884X_PON_LDOL_SPARE_TUNE_3,          0x00},
+	{WSA884X_PON_LDOL_SPARE_TUNE_4,          0x00},
+	{WSA884X_DIG_CTRL0_PAGE,                 0x00},
+	{WSA884X_CHIP_ID0,                       0x00},
+	{WSA884X_CHIP_ID1,                       0x00},
+	{WSA884X_CHIP_ID2,                       0x04},
+	{WSA884X_CHIP_ID3,                       0x02},
+	{WSA884X_BUS_ID,                         0x00},
+	{WSA884X_CDC_RST_CTL,                    0x01},
+	{WSA884X_SWR_RESET_EN,                   0x00},
+	{WSA884X_TOP_CLK_CFG,                    0x00},
+	{WSA884X_SWR_CLK_RATE,                   0x00},
+	{WSA884X_CDC_PATH_MODE,                  0x00},
+	{WSA884X_CDC_CLK_CTL,                    0x1f},
+	{WSA884X_PA_FSM_EN,                      0x00},
+	{WSA884X_PA_FSM_CTL0,                    0x00},
+	{WSA884X_PA_FSM_CTL1,                    0xfe},
+	{WSA884X_PA_FSM_TIMER0,                  0x80},
+	{WSA884X_PA_FSM_TIMER1,                  0x80},
+	{WSA884X_PA_FSM_STA0,                    0x00},
+	{WSA884X_PA_FSM_STA1,                    0x00},
+	{WSA884X_PA_FSM_ERR_CTL,                 0x00},
+	{WSA884X_PA_FSM_ERR_COND0,               0x00},
+	{WSA884X_PA_FSM_ERR_COND1,               0x00},
+	{WSA884X_PA_FSM_MSK0,                    0x00},
+	{WSA884X_PA_FSM_MSK1,                    0x00},
+	{WSA884X_PA_FSM_BYP_CTL,                 0x00},
+	{WSA884X_PA_FSM_BYP0,                    0x00},
+	{WSA884X_PA_FSM_BYP1,                    0x00},
+	{WSA884X_TADC_VALUE_CTL,                 0x03},
+	{WSA884X_TEMP_DETECT_CTL,                0x01},
+	{WSA884X_TEMP_DIN_MSB,                   0x00},
+	{WSA884X_TEMP_DIN_LSB,                   0x00},
+	{WSA884X_TEMP_DOUT_MSB,                  0x00},
+	{WSA884X_TEMP_DOUT_LSB,                  0x00},
+	{WSA884X_TEMP_CONFIG0,                   0x00},
+	{WSA884X_TEMP_CONFIG1,                   0x00},
+	{WSA884X_VBAT_THRM_FLT_CTL,              0x7f},
+	{WSA884X_VBAT_CAL_CTL,                   0x01},
+	{WSA884X_VBAT_DIN_MSB,                   0x00},
+	{WSA884X_VBAT_DIN_LSB,                   0x00},
+	{WSA884X_VBAT_DOUT_MSB,                  0x00},
+	{WSA884X_VBAT_DOUT_LSB,                  0x00},
+	{WSA884X_VBAT_CAL_MSB,                   0x00},
+	{WSA884X_VBAT_CAL_LSB,                   0x00},
+	{WSA884X_UVLO_DEGLITCH_CTL,              0x05},
+	{WSA884X_BOP_DEGLITCH_CTL,               0x05},
+	{WSA884X_VBAT_ZONE_DETC_CTL,             0x31},
+	{WSA884X_CPS_CTL,                        0x00},
+	{WSA884X_CDC_RX_CTL,                     0xfe},
+	{WSA884X_CDC_SPK_DSM_A1_0,               0x00},
+	{WSA884X_CDC_SPK_DSM_A1_1,               0x01},
+	{WSA884X_CDC_SPK_DSM_A2_0,               0x96},
+	{WSA884X_CDC_SPK_DSM_A2_1,               0x09},
+	{WSA884X_CDC_SPK_DSM_A3_0,               0xab},
+	{WSA884X_CDC_SPK_DSM_A3_1,               0x05},
+	{WSA884X_CDC_SPK_DSM_A4_0,               0x1c},
+	{WSA884X_CDC_SPK_DSM_A4_1,               0x02},
+	{WSA884X_CDC_SPK_DSM_A5_0,               0x17},
+	{WSA884X_CDC_SPK_DSM_A5_1,               0x02},
+	{WSA884X_CDC_SPK_DSM_A6_0,               0xaa},
+	{WSA884X_CDC_SPK_DSM_A7_0,               0xe3},
+	{WSA884X_CDC_SPK_DSM_C_0,                0x69},
+	{WSA884X_CDC_SPK_DSM_C_1,                0x54},
+	{WSA884X_CDC_SPK_DSM_C_2,                0x02},
+	{WSA884X_CDC_SPK_DSM_C_3,                0x15},
+	{WSA884X_CDC_SPK_DSM_R1,                 0xa4},
+	{WSA884X_CDC_SPK_DSM_R2,                 0xb5},
+	{WSA884X_CDC_SPK_DSM_R3,                 0x86},
+	{WSA884X_CDC_SPK_DSM_R4,                 0x85},
+	{WSA884X_CDC_SPK_DSM_R5,                 0xaa},
+	{WSA884X_CDC_SPK_DSM_R6,                 0xe2},
+	{WSA884X_CDC_SPK_DSM_R7,                 0x62},
+	{WSA884X_CDC_SPK_GAIN_PDM_0,             0x00},
+	{WSA884X_CDC_SPK_GAIN_PDM_1,             0xfc},
+	{WSA884X_CDC_SPK_GAIN_PDM_2,             0x05},
+	{WSA884X_PDM_WD_CTL,                     0x00},
+	{WSA884X_DEM_BYPASS_DATA0,               0x00},
+	{WSA884X_DEM_BYPASS_DATA1,               0x00},
+	{WSA884X_DEM_BYPASS_DATA2,               0x00},
+	{WSA884X_DEM_BYPASS_DATA3,               0x00},
+	{WSA884X_DRE_CTL_0,                      0x70},
+	{WSA884X_DRE_CTL_1,                      0x04},
+	{WSA884X_DRE_IDLE_DET_CTL,               0x2f},
+	{WSA884X_GAIN_RAMPING_CTL,               0x50},
+	{WSA884X_GAIN_RAMPING_MIN,               0x12},
+	{WSA884X_TAGC_CTL,                       0x15},
+	{WSA884X_TAGC_TIME,                      0xbc},
+	{WSA884X_TAGC_FORCE_VAL,                 0x00},
+	{WSA884X_VAGC_CTL,                       0x01},
+	{WSA884X_VAGC_TIME,                      0x0f},
+	{WSA884X_VAGC_ATTN_LVL_1,                0x03},
+	{WSA884X_VAGC_ATTN_LVL_2,                0x06},
+	{WSA884X_VAGC_ATTN_LVL_3,                0x09},
+	{WSA884X_CLSH_CTL_0,                     0x37},
+	{WSA884X_CLSH_CTL_1,                     0x81},
+	{WSA884X_CLSH_V_HD_PA,                   0x0c},
+	{WSA884X_CLSH_V_PA_MIN,                  0x00},
+	{WSA884X_CLSH_OVRD_VAL,                  0x00},
+	{WSA884X_CLSH_HARD_MAX,                  0xff},
+	{WSA884X_CLSH_SOFT_MAX,                  0xf5},
+	{WSA884X_CLSH_SIG_DP,                    0x00},
+	{WSA884X_PBR_DELAY_CTL,                  0x07},
+	{WSA884X_CLSH_SRL_MAX_PBR,               0x02},
+	{WSA884X_CLSH_VTH1,                      0x00},
+	{WSA884X_CLSH_VTH2,                      0x00},
+	{WSA884X_CLSH_VTH3,                      0x00},
+	{WSA884X_CLSH_VTH4,                      0x00},
+	{WSA884X_CLSH_VTH5,                      0x00},
+	{WSA884X_CLSH_VTH6,                      0x00},
+	{WSA884X_CLSH_VTH7,                      0x00},
+	{WSA884X_CLSH_VTH8,                      0x00},
+	{WSA884X_CLSH_VTH9,                      0x00},
+	{WSA884X_CLSH_VTH10,                     0x00},
+	{WSA884X_CLSH_VTH11,                     0x00},
+	{WSA884X_CLSH_VTH12,                     0x00},
+	{WSA884X_CLSH_VTH13,                     0x00},
+	{WSA884X_CLSH_VTH14,                     0x00},
+	{WSA884X_CLSH_VTH15,                     0x00},
+	{WSA884X_DIG_CTRL1_PAGE,                 0x00},
+	{WSA884X_BST_CFG,                        0x00},
+	{WSA884X_ANA_WO_CTL_0,                   0xe9},
+	{WSA884X_ANA_WO_CTL_1,                   0x00},
+	{WSA884X_PIN_CTL,                        0x04},
+	{WSA884X_PIN_CTL_OE,                     0x00},
+	{WSA884X_PIN_WDATA_IOPAD,                0x00},
+	{WSA884X_PIN_STATUS,                     0x00},
+	{WSA884X_I2C_SLAVE_CTL,                  0x00},
+	{WSA884X_SPMI_PAD_CTL0,                  0x2f},
+	{WSA884X_SPMI_PAD_CTL1,                  0x2f},
+	{WSA884X_SPMI_PAD_CTL2,                  0x2f},
+	{WSA884X_MEM_CTL,                        0x00},
+	{WSA884X_SWR_HM_TEST0,                   0x08},
+	{WSA884X_SWR_HM_TEST1,                   0x00},
+	{WSA884X_OTP_CTRL0,                      0x00},
+	{WSA884X_OTP_CTRL1,                      0x00},
+	{WSA884X_OTP_CTRL2,                      0x00},
+	{WSA884X_OTP_STAT,                       0x00},
+	{WSA884X_OTP_PRG_TCSP0,                  0x77},
+	{WSA884X_OTP_PRG_TCSP1,                  0x00},
+	{WSA884X_OTP_PRG_TPPS,                   0x47},
+	{WSA884X_OTP_PRG_TVPS,                   0x3b},
+	{WSA884X_OTP_PRG_TVPH,                   0x47},
+	{WSA884X_OTP_PRG_TPPR0,                  0x47},
+	{WSA884X_OTP_PRG_TPPR1,                  0x00},
+	{WSA884X_OTP_PRG_TPPH,                   0x47},
+	{WSA884X_OTP_PRG_END,                    0x47},
+	{WSA884X_WAVG_PLAY,                      0x00},
+	{WSA884X_WAVG_CTL,                       0x06},
+	{WSA884X_WAVG_LRA_PER_0,                 0xd1},
+	{WSA884X_WAVG_LRA_PER_1,                 0x00},
+	{WSA884X_WAVG_DELTA_THETA_0,             0xe6},
+	{WSA884X_WAVG_DELTA_THETA_1,             0x04},
+	{WSA884X_WAVG_DIRECT_AMP_0,              0x50},
+	{WSA884X_WAVG_DIRECT_AMP_1,              0x00},
+	{WSA884X_WAVG_PTRN_AMP0_0,               0x50},
+	{WSA884X_WAVG_PTRN_AMP0_1,               0x00},
+	{WSA884X_WAVG_PTRN_AMP1_0,               0x50},
+	{WSA884X_WAVG_PTRN_AMP1_1,               0x00},
+	{WSA884X_WAVG_PTRN_AMP2_0,               0x50},
+	{WSA884X_WAVG_PTRN_AMP2_1,               0x00},
+	{WSA884X_WAVG_PTRN_AMP3_0,               0x50},
+	{WSA884X_WAVG_PTRN_AMP3_1,               0x00},
+	{WSA884X_WAVG_PTRN_AMP4_0,               0x50},
+	{WSA884X_WAVG_PTRN_AMP4_1,               0x00},
+	{WSA884X_WAVG_PTRN_AMP5_0,               0x50},
+	{WSA884X_WAVG_PTRN_AMP5_1,               0x00},
+	{WSA884X_WAVG_PTRN_AMP6_0,               0x50},
+	{WSA884X_WAVG_PTRN_AMP6_1,               0x00},
+	{WSA884X_WAVG_PTRN_AMP7_0,               0x50},
+	{WSA884X_WAVG_PTRN_AMP7_1,               0x00},
+	{WSA884X_WAVG_PER_0_1,                   0x88},
+	{WSA884X_WAVG_PER_2_3,                   0x88},
+	{WSA884X_WAVG_PER_4_5,                   0x88},
+	{WSA884X_WAVG_PER_6_7,                   0x88},
+	{WSA884X_WAVG_STA,                       0x00},
+	{WSA884X_INTR_MODE,                      0x00},
+	{WSA884X_INTR_MASK0,                     0x90},
+	{WSA884X_INTR_MASK1,                     0x00},
+	{WSA884X_INTR_STATUS0,                   0x00},
+	{WSA884X_INTR_STATUS1,                   0x00},
+	{WSA884X_INTR_CLEAR0,                    0x00},
+	{WSA884X_INTR_CLEAR1,                    0x00},
+	{WSA884X_INTR_LEVEL0,                    0x04},
+	{WSA884X_INTR_LEVEL1,                    0x00},
+	{WSA884X_INTR_SET0,                      0x00},
+	{WSA884X_INTR_SET1,                      0x00},
+	{WSA884X_INTR_TEST0,                     0x00},
+	{WSA884X_INTR_TEST1,                     0x00},
+	{WSA884X_PDM_TEST_MODE,                  0x00},
+	{WSA884X_ATE_TEST_MODE,                  0x00},
+	{WSA884X_PA_FSM_DBG,                     0x00},
+	{WSA884X_DIG_DEBUG_MODE,                 0x00},
+	{WSA884X_DIG_DEBUG_SEL,                  0x00},
+	{WSA884X_DIG_DEBUG_EN,                   0x00},
+	{WSA884X_TADC_DETECT_DBG_CTL,            0x00},
+	{WSA884X_TADC_DEBUG_MSB,                 0x00},
+	{WSA884X_TADC_DEBUG_LSB,                 0x00},
+	{WSA884X_SAMPLE_EDGE_SEL,                0x7f},
+	{WSA884X_SWR_EDGE_SEL,                   0x00},
+	{WSA884X_TEST_MODE_CTL,                  0x05},
+	{WSA884X_IOPAD_CTL,                      0x00},
+	{WSA884X_ANA_CSR_DBG_ADD,                0x00},
+	{WSA884X_ANA_CSR_DBG_CTL,                0x12},
+	{WSA884X_CLK_DBG_CTL,                    0x00},
+	{WSA884X_SPARE_R,                        0x00},
+	{WSA884X_SPARE_0,                        0x00},
+	{WSA884X_SPARE_1,                        0x00},
+	{WSA884X_SPARE_2,                        0x00},
+	{WSA884X_SCODE,                          0x00},
+	{WSA884X_DIG_TRIM_PAGE,                  0x00},
+	{WSA884X_OTP_REG_0,                      0x05},
+	{WSA884X_OTP_REG_1,                      0x49},
+	{WSA884X_OTP_REG_2,                      0x80},
+	{WSA884X_OTP_REG_3,                      0xc9},
+	{WSA884X_OTP_REG_4,                      0x40},
+	{WSA884X_OTP_REG_5,                      0xff},
+	{WSA884X_OTP_REG_6,                      0xff},
+	{WSA884X_OTP_REG_7,                      0xff},
+	{WSA884X_OTP_REG_8,                      0xff},
+	{WSA884X_OTP_REG_9,                      0xff},
+	{WSA884X_OTP_REG_10,                     0xff},
+	{WSA884X_OTP_REG_11,                     0xff},
+	{WSA884X_OTP_REG_12,                     0xff},
+	{WSA884X_OTP_REG_13,                     0xff},
+	{WSA884X_OTP_REG_14,                     0xff},
+	{WSA884X_OTP_REG_15,                     0xff},
+	{WSA884X_OTP_REG_16,                     0xff},
+	{WSA884X_OTP_REG_17,                     0xff},
+	{WSA884X_OTP_REG_18,                     0xff},
+	{WSA884X_OTP_REG_19,                     0xff},
+	{WSA884X_OTP_REG_20,                     0xff},
+	{WSA884X_OTP_REG_21,                     0xff},
+	{WSA884X_OTP_REG_22,                     0xff},
+	{WSA884X_OTP_REG_23,                     0xff},
+	{WSA884X_OTP_REG_24,                     0x00},
+	{WSA884X_OTP_REG_25,                     0x22},
+	{WSA884X_OTP_REG_26,                     0x03},
+	{WSA884X_OTP_REG_27,                     0x00},
+	{WSA884X_OTP_REG_28,                     0x00},
+	{WSA884X_OTP_REG_29,                     0x00},
+	{WSA884X_OTP_REG_30,                     0x00},
+	{WSA884X_OTP_REG_31,                     0x8f},
+	{WSA884X_OTP_REG_32,                     0x00},
+	{WSA884X_OTP_REG_33,                     0xff},
+	{WSA884X_OTP_REG_34,                     0x0f},
+	{WSA884X_OTP_REG_35,                     0x12},
+	{WSA884X_OTP_REG_36,                     0x08},
+	{WSA884X_OTP_REG_37,                     0x1f},
+	{WSA884X_OTP_REG_38,                     0x0b},
+	{WSA884X_OTP_REG_39,                     0x00},
+	{WSA884X_OTP_REG_40,                     0x00},
+	{WSA884X_OTP_REG_41,                     0x00},
+	{WSA884X_OTP_REG_63,                     0x40},
+	{WSA884X_EMEM_0,                         0x00},
+	{WSA884X_EMEM_1,                         0x00},
+	{WSA884X_EMEM_2,                         0x00},
+	{WSA884X_EMEM_3,                         0x00},
+	{WSA884X_EMEM_4,                         0x00},
+	{WSA884X_EMEM_5,                         0x00},
+	{WSA884X_EMEM_6,                         0x00},
+	{WSA884X_EMEM_7,                         0x00},
+	{WSA884X_EMEM_8,                         0x00},
+	{WSA884X_EMEM_9,                         0x00},
+	{WSA884X_EMEM_10,                        0x00},
+	{WSA884X_EMEM_11,                        0x00},
+	{WSA884X_EMEM_12,                        0x00},
+	{WSA884X_EMEM_13,                        0x00},
+	{WSA884X_EMEM_14,                        0x00},
+	{WSA884X_EMEM_15,                        0x00},
+	{WSA884X_EMEM_16,                        0x00},
+	{WSA884X_EMEM_17,                        0x00},
+	{WSA884X_EMEM_18,                        0x00},
+	{WSA884X_EMEM_19,                        0x00},
+	{WSA884X_EMEM_20,                        0x00},
+	{WSA884X_EMEM_21,                        0x00},
+	{WSA884X_EMEM_22,                        0x00},
+	{WSA884X_EMEM_23,                        0x00},
+	{WSA884X_EMEM_24,                        0x00},
+	{WSA884X_EMEM_25,                        0x00},
+	{WSA884X_EMEM_26,                        0x00},
+	{WSA884X_EMEM_27,                        0x00},
+	{WSA884X_EMEM_28,                        0x00},
+	{WSA884X_EMEM_29,                        0x00},
+	{WSA884X_EMEM_30,                        0x00},
+	{WSA884X_EMEM_31,                        0x00},
+	{WSA884X_EMEM_32,                        0x00},
+	{WSA884X_EMEM_33,                        0x00},
+	{WSA884X_EMEM_34,                        0x00},
+	{WSA884X_EMEM_35,                        0x00},
+	{WSA884X_EMEM_36,                        0x00},
+	{WSA884X_EMEM_37,                        0x00},
+	{WSA884X_EMEM_38,                        0x00},
+	{WSA884X_EMEM_39,                        0x00},
+	{WSA884X_EMEM_40,                        0x00},
+	{WSA884X_EMEM_41,                        0x00},
+	{WSA884X_EMEM_42,                        0x00},
+	{WSA884X_EMEM_43,                        0x00},
+	{WSA884X_EMEM_44,                        0x00},
+	{WSA884X_EMEM_45,                        0x00},
+	{WSA884X_EMEM_46,                        0x00},
+	{WSA884X_EMEM_47,                        0x00},
+	{WSA884X_EMEM_48,                        0x00},
+	{WSA884X_EMEM_49,                        0x00},
+	{WSA884X_EMEM_50,                        0x00},
+	{WSA884X_EMEM_51,                        0x00},
+	{WSA884X_EMEM_52,                        0x00},
+	{WSA884X_EMEM_53,                        0x00},
+	{WSA884X_EMEM_54,                        0x00},
+	{WSA884X_EMEM_55,                        0x00},
+	{WSA884X_EMEM_56,                        0x00},
+	{WSA884X_EMEM_57,                        0x00},
+	{WSA884X_EMEM_58,                        0x00},
+	{WSA884X_EMEM_59,                        0x00},
+	{WSA884X_EMEM_60,                        0x00},
+	{WSA884X_EMEM_61,                        0x00},
+	{WSA884X_EMEM_62,                        0x00},
+	{WSA884X_EMEM_63,                        0x00},
+};
+
+static bool wsa884x_readable_register(struct device *dev, unsigned int reg)
+{
+	if (reg <= WSA884X_BASE)
+		return 0;
+
+	return wsa884x_reg_access[WSA884X_REG(reg)] & RD_REG;
+}
+
+static bool wsa884x_writeable_register(struct device *dev, unsigned int reg)
+{
+	if (reg <= WSA884X_BASE)
+		return 0;
+
+	return wsa884x_reg_access[WSA884X_REG(reg)] & WR_REG;
+}
+
+static bool wsa884x_volatile_register(struct device *dev, unsigned int reg)
+{
+	if (reg <= WSA884X_BASE)
+		return 0;
+
+	return ((wsa884x_reg_access[WSA884X_REG(reg)] & RD_REG) &&
+		!(wsa884x_reg_access[WSA884X_REG(reg)] & WR_REG));
+}
+
+
+struct regmap_config wsa884x_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 8,
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wsa884x_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wsa884x_defaults),
+	.max_register = WSA884X_MAX_REGISTER,
+	.volatile_reg = wsa884x_volatile_register,
+	.readable_reg = wsa884x_readable_register,
+	.writeable_reg = wsa884x_writeable_register,
+	.reg_format_endian = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian = REGMAP_ENDIAN_NATIVE,
+	.can_multi_write = true,
+};

+ 500 - 0
asoc/codecs/wsa884x/wsa884x-tables.c

@@ -0,0 +1,500 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/regmap.h>
+#include <linux/device.h>
+#include "wsa884x-registers.h"
+
+const u8 wsa884x_reg_access[WSA884X_NUM_REGISTERS] = {
+	[WSA884X_REG(WSA884X_BG_CTRL)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_CTRL)]                       = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BOP1_PROG)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BOP2_PROG)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_UVLO_PROG)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_UVLO_PROG1)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_CTRL_0)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_CTRL_1)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_CTRL_2)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_CTRL_3)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_REF_CTRL)]                       = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BG_TEST_CTL)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BG_BIAS)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_PROG)]                       = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_IREF_CTL)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_ISENS_CTL)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_CLK_CTL)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_TEST_CTL)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_BIAS)]                       = RD_WR_REG,
+	[WSA884X_REG(WSA884X_VBAT_SNS)]                       = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DOUT_MSB)]                       = RD_REG,
+	[WSA884X_REG(WSA884X_DOUT_LSB)]                       = RD_REG,
+	[WSA884X_REG(WSA884X_BOP_ATEST_SEL)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_MISC0)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_MISC1)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_MISC2)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_MISC3)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_TSBG_0)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_TUNE_0)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_TUNE_1)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_VSENSE1)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ISENSE2)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_CTL_1)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_CTL_2)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_CTL_3)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_CTL_4)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EN)]                             = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OVERRIDE1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OVERRIDE2)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ISENSE1)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ISENSE_CAL)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_MISC)]                           = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_0)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_1)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_2)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_3)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_4)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_5)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_6)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ADC_7)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_STATUS)]                         = RD_REG,
+	[WSA884X_REG(WSA884X_IVSENSE_SPARE_TUNE_1)]           = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_TUNE_2)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_TUNE_3)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_TUNE_4)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TOP_CTRL1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLIP_DET_CTRL1)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLIP_DET_CTRL2)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_CTRL1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_VCM_CTRL_REG1)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_VCM_CTRL_REG2)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_VCM_CTRL_REG3)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_VCM_CTRL_REG4)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_VCM_CTRL_REG5)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_VCM_CTRL_REG6)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PWM_CLK_CTL)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRV_LF_LDO_SEL)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OCP_CTL)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PDRV_HS_CTL)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PDRV_LS_CTL)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPK_TOP_SPARE_CTL_1)]            = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPK_TOP_SPARE_CTL_2)]            = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPK_TOP_SPARE_CTL_3)]            = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPK_TOP_SPARE_CTL_4)]            = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_CTL_5)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_EN_DEBUG_REG)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_OPAMP_BIAS1_REG)]            = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_OPAMP_BIAS2_REG)]            = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_TUNE1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_VOLTAGE_CTRL_REG)]           = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ATEST1_REG)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ATEST2_REG)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TOP_BIAS_REG1)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TOP_BIAS_REG2)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TOP_BIAS_REG3)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TOP_BIAS_REG4)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PWRSTG_DBG2)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRV_LF_BLK_EN)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRV_LF_EN)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRV_LF_MASK_DCC_CTL)]            = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRV_LF_MISC_CTL1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRV_LF_REG_GAIN)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRV_OS_CAL_CTL)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRV_OS_CAL_CTL1)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PWRSTG_DBG)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BBM_CTL)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TOP_MISC1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DAC_VCM_CTRL_REG7)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TOP_BIAS_REG5)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRV_LF_MISC_CTL2)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPK_TOP_SPARE_TUNE_2)]           = RD_REG,
+	[WSA884X_REG(WSA884X_SPK_TOP_SPARE_TUNE_3)]           = RD_REG,
+	[WSA884X_REG(WSA884X_SPK_TOP_SPARE_TUNE_4)]           = RD_REG,
+	[WSA884X_REG(WSA884X_SPARE_TUNE_5)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_SPARE_TUNE_6)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_SPARE_TUNE_7)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_SPARE_TUNE_8)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_SPARE_TUNE_9)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_SPARE_TUNE_10)]                  = RD_REG,
+	[WSA884X_REG(WSA884X_PA_STATUS0)]                     = RD_REG,
+	[WSA884X_REG(WSA884X_PA_STATUS1)]                     = RD_REG,
+	[WSA884X_REG(WSA884X_PA_STATUS2)]                     = RD_REG,
+	[WSA884X_REG(WSA884X_PA_STATUS3)]                     = RD_REG,
+	[WSA884X_REG(WSA884X_PA_STATUS4)]                     = RD_REG,
+	[WSA884X_REG(WSA884X_PA_STATUS5)]                     = RD_REG,
+	[WSA884X_REG(WSA884X_SPARE_RO_1)]                     = RD_REG,
+	[WSA884X_REG(WSA884X_SPARE_RO_2)]                     = RD_REG,
+	[WSA884X_REG(WSA884X_SPARE_RO_3)]                     = RD_REG,
+	[WSA884X_REG(WSA884X_STB_CTRL1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CURRENT_LIMIT)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BYP_CTRL1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_CTL_0)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BOOST_SPARE_CTL_1)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_RO_0)]                     = RD_REG,
+	[WSA884X_REG(WSA884X_BOOST_SPARE_RO_1)]               = RD_REG,
+	[WSA884X_REG(WSA884X_IBIAS1)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_IBIAS2)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_IBIAS3)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EN_CTRL)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_STB_CTRL2)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_STB_CTRL3)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_STB_CTRL4)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BYP_CTRL2)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BYP_CTRL3)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ZX_CTRL1)]                       = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ZX_CTRL2)]                       = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BLEEDER_CTRL)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BOOST_MISC)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PWRSTAGE_CTRL1)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PWRSTAGE_CTRL2)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PWRSTAGE_CTRL3)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PWRSTAGE_CTRL4)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_MAXD_REG1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_MAXD_REG2)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ILIM_CTRL1)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ILIM_CTRL2)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TEST_CTRL1)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TEST_CTRL2)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE1)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BOOT_CAP_CHECK)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_CTL_0)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PWRSAV_CTL)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_LDOL_SPARE_CTL_0)]           = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_LDOL_SPARE_CTL_1)]           = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_LDOL_SPARE_CTL_2)]           = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_LDOL_SPARE_CTL_3)]           = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_CLT_1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_CTL_2)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_CTL_3)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CKWD_CTL_0)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CKWD_CTL_1)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CKWD_CTL_2)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CKSK_CTL_0)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PADSW_CTL_0)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TEST_0)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TEST_1)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_STATUS_0)]                       = RD_REG,
+	[WSA884X_REG(WSA884X_STATUS_1)]                       = RD_REG,
+	[WSA884X_REG(WSA884X_PON_LDOL_SPARE_TUNE_0)]          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_LDOL_SPARE_TUNE_1)]          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_LDOL_SPARE_TUNE_2)]          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_LDOL_SPARE_TUNE_3)]          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PON_LDOL_SPARE_TUNE_4)]          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DIG_CTRL0_PAGE)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CHIP_ID0)]                       = RD_REG,
+	[WSA884X_REG(WSA884X_CHIP_ID1)]                       = RD_REG,
+	[WSA884X_REG(WSA884X_CHIP_ID2)]                       = RD_REG,
+	[WSA884X_REG(WSA884X_CHIP_ID3)]                       = RD_REG,
+	[WSA884X_REG(WSA884X_BUS_ID)]                         = RD_REG,
+	[WSA884X_REG(WSA884X_CDC_RST_CTL)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SWR_RESET_EN)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TOP_CLK_CFG)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SWR_CLK_RATE)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_PATH_MODE)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_CLK_CTL)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_EN)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_CTL0)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_CTL1)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_TIMER0)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_TIMER1)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_STA0)]                    = RD_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_STA1)]                    = RD_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_ERR_CTL)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_ERR_COND0)]               = RD_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_ERR_COND1)]               = RD_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_MSK0)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_MSK1)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_BYP_CTL)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_BYP0)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_BYP1)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TADC_VALUE_CTL)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TEMP_DETECT_CTL)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TEMP_DIN_MSB)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_TEMP_DIN_LSB)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_TEMP_DOUT_MSB)]                  = RD_REG,
+	[WSA884X_REG(WSA884X_TEMP_DOUT_LSB)]                  = RD_REG,
+	[WSA884X_REG(WSA884X_TEMP_CONFIG0)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TEMP_CONFIG1)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_VBAT_THRM_FLT_CTL)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_VBAT_CAL_CTL)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_VBAT_DIN_MSB)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_VBAT_DIN_LSB)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_VBAT_DOUT_MSB)]                  = RD_REG,
+	[WSA884X_REG(WSA884X_VBAT_DOUT_LSB)]                  = RD_REG,
+	[WSA884X_REG(WSA884X_VBAT_CAL_MSB)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_VBAT_CAL_LSB)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_UVLO_DEGLITCH_CTL)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BOP_DEGLITCH_CTL)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_VBAT_ZONE_DETC_CTL)]             = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CPS_CTL)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_RX_CTL)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A1_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A1_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A2_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A2_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A3_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A3_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A4_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A4_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A5_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A5_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A6_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_A7_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_C_0)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_C_1)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_C_2)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_C_3)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_R1)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_R2)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_R3)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_R4)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_R5)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_R6)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_DSM_R7)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_GAIN_PDM_0)]             = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_GAIN_PDM_1)]             = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CDC_SPK_GAIN_PDM_2)]             = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PDM_WD_CTL)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DEM_BYPASS_DATA0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DEM_BYPASS_DATA1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DEM_BYPASS_DATA2)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DEM_BYPASS_DATA3)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRE_CTL_0)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRE_CTL_1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DRE_IDLE_DET_CTL)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_GAIN_RAMPING_CTL)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_GAIN_RAMPING_MIN)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TAGC_CTL)]                       = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TAGC_TIME)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TAGC_FORCE_VAL)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_VAGC_CTL)]                       = RD_WR_REG,
+	[WSA884X_REG(WSA884X_VAGC_TIME)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_VAGC_ATTN_LVL_1)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_VAGC_ATTN_LVL_2)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_VAGC_ATTN_LVL_3)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_CTL_0)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_CTL_1)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_V_HD_PA)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_V_PA_MIN)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_OVRD_VAL)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_HARD_MAX)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_SOFT_MAX)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_SIG_DP)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PBR_DELAY_CTL)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_SRL_MAX_PBR)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH2)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH3)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH4)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH5)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH6)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH7)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH8)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH9)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH10)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH11)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH12)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH13)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH14)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLSH_VTH15)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DIG_CTRL1_PAGE)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_BST_CFG)]                        = RD_REG,
+	[WSA884X_REG(WSA884X_ANA_WO_CTL_0)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ANA_WO_CTL_1)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PIN_CTL)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PIN_CTL_OE)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PIN_WDATA_IOPAD)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PIN_STATUS)]                     = RD_REG,
+	[WSA884X_REG(WSA884X_I2C_SLAVE_CTL)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPMI_PAD_CTL0)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPMI_PAD_CTL1)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPMI_PAD_CTL2)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_MEM_CTL)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SWR_HM_TEST0)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SWR_HM_TEST1)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_OTP_CTRL0)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_CTRL1)]                      = RD_REG,
+	[WSA884X_REG(WSA884X_OTP_CTRL2)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_STAT)]                       = RD_REG,
+	[WSA884X_REG(WSA884X_OTP_PRG_TCSP0)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_PRG_TCSP1)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_PRG_TPPS)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_PRG_TVPS)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_PRG_TVPH)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_PRG_TPPR0)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_PRG_TPPR1)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_PRG_TPPH)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_PRG_END)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PLAY)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_CTL)]                       = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_LRA_PER_0)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_LRA_PER_1)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_DELTA_THETA_0)]             = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_DELTA_THETA_1)]             = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_DIRECT_AMP_0)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_DIRECT_AMP_1)]              = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP0_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP0_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP1_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP1_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP2_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP2_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP3_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP3_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP4_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP4_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP5_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP5_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP6_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP6_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP7_0)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PTRN_AMP7_1)]               = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PER_0_1)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PER_2_3)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PER_4_5)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_PER_6_7)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_WAVG_STA)]                       = RD_REG,
+	[WSA884X_REG(WSA884X_INTR_MODE)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_INTR_MASK0)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_INTR_MASK1)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_INTR_STATUS0)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_INTR_STATUS1)]                   = RD_REG,
+	[WSA884X_REG(WSA884X_INTR_CLEAR0)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_INTR_CLEAR1)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_INTR_LEVEL0)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_INTR_LEVEL1)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_INTR_SET0)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_INTR_SET1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_INTR_TEST0)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_INTR_TEST1)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_PDM_TEST_MODE)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ATE_TEST_MODE)]                  = RD_REG,
+	[WSA884X_REG(WSA884X_PA_FSM_DBG)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DIG_DEBUG_MODE)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DIG_DEBUG_SEL)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DIG_DEBUG_EN)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TADC_DETECT_DBG_CTL)]            = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TADC_DEBUG_MSB)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TADC_DEBUG_LSB)]                 = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SAMPLE_EDGE_SEL)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SWR_EDGE_SEL)]                   = RD_WR_REG,
+	[WSA884X_REG(WSA884X_TEST_MODE_CTL)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_IOPAD_CTL)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ANA_CSR_DBG_ADD)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_ANA_CSR_DBG_CTL)]                = RD_WR_REG,
+	[WSA884X_REG(WSA884X_CLK_DBG_CTL)]                    = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_R)]                        = RD_REG,
+	[WSA884X_REG(WSA884X_SPARE_0)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_1)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SPARE_2)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_SCODE)]                          = RD_WR_REG,
+	[WSA884X_REG(WSA884X_DIG_TRIM_PAGE)]                  = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_0)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_1)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_2)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_3)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_4)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_5)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_6)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_7)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_8)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_9)]                      = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_10)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_11)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_12)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_13)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_14)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_15)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_16)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_17)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_18)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_19)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_20)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_21)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_22)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_23)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_24)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_25)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_26)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_27)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_28)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_29)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_30)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_31)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_32)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_33)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_34)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_35)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_36)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_37)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_38)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_39)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_40)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_41)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_OTP_REG_63)]                     = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_0)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_1)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_2)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_3)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_4)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_5)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_6)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_7)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_8)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_9)]                         = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_10)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_11)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_12)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_13)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_14)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_15)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_16)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_17)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_18)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_19)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_20)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_21)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_22)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_23)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_24)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_25)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_26)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_27)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_28)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_29)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_30)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_31)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_32)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_33)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_34)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_35)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_36)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_37)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_38)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_39)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_40)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_41)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_42)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_43)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_44)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_45)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_46)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_47)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_48)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_49)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_50)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_51)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_52)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_53)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_54)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_55)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_56)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_57)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_58)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_59)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_60)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_61)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_62)]                        = RD_WR_REG,
+	[WSA884X_REG(WSA884X_EMEM_63)]                        = RD_WR_REG,
+};

+ 2032 - 0
asoc/codecs/wsa884x/wsa884x.c

@@ -0,0 +1,2032 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/printk.h>
+#include <linux/bitops.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/debugfs.h>
+#include <soc/soundwire.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <asoc/msm-cdc-pinctrl.h>
+#include <asoc/msm-cdc-supply.h>
+#include "wsa884x.h"
+#include "internal.h"
+#include "asoc/bolero-slave-internal.h"
+#include <linux/qti-regmap-debugfs.h>
+
+#define T1_TEMP -10
+#define T2_TEMP 150
+#define LOW_TEMP_THRESHOLD 5
+#define HIGH_TEMP_THRESHOLD 45
+#define TEMP_INVALID	0xFFFF
+#define WSA884X_TEMP_RETRY 3
+
+#define MAX_NAME_LEN	40
+#define WSA884X_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 WSA884X_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
+				SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)
+
+#define WSA884X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+		SNDRV_PCM_FMTBIT_S24_LE |\
+		SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+#define REG_FIELD_VALUE(register_name, field_name, value) \
+(WSA884X_##register_name, FIELD_MASK(register_name, field_name), \
+value << FIELD_SHIFT(register_name, field_name))
+
+enum {
+	WSA_4OHMS = 4,
+	WSA_8OHMS = 8,
+	WSA_16OHMS = 16,
+	WSA_32OHMS = 32,
+};
+
+struct wsa_temp_register {
+	u8 d1_msb;
+	u8 d1_lsb;
+	u8 d2_msb;
+	u8 d2_lsb;
+	u8 dmeas_msb;
+	u8 dmeas_lsb;
+};
+
+enum {
+	COMP_OFFSET0,
+	COMP_OFFSET1,
+	COMP_OFFSET2,
+	COMP_OFFSET3,
+	COMP_OFFSET4,
+};
+
+struct wsa_reg_mask_val {
+	u16 reg;
+	u8 mask;
+	u8 val;
+};
+
+static const struct wsa_reg_mask_val reg_init[] = {
+	{REG_FIELD_VALUE(PA_FSM_BYP_CTL, PA_FSM_BYP, 0x00)},
+	{REG_FIELD_VALUE(ISENSE2, ISENSE_GAIN_CTL, 0x02)},
+	{REG_FIELD_VALUE(ADC_6, INTRLV_RST_OVRD, 0x01)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_A2_0, COEF_A2, 0x0A)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_A2_0, COEF_A2, 0x0A)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_A2_1, COEF_A2, 0x08)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_A3_0, COEF_A3, 0xF3)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_A3_1, COEF_A3, 0x07)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_A4_0, COEF_A4, 0x79)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_A4_1, COEF_A4, 0x02)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_A5_0, COEF_A5, 0x0B)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_A5_1, COEF_A5, 0x02)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_A6_0, COEF_A6, 0x8A)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_A7_0, COEF_A7, 0x9B)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_C_0, COEF_C3, 0x06)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_C_0, COEF_C2, 0x08)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_C_1, COEF_C5, 0x05)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_C_1, COEF_C4, 0x04)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_C_2, COEF_C7, 0x0F)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_C_3, COEF_C7, 0x20)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_R1, SAT_LIMIT_R1, 0x83)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_R2, SAT_LIMIT_R2, 0x7F)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_R3, SAT_LIMIT_R3, 0x9D)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_R4, SAT_LIMIT_R4, 0x82)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_R5, SAT_LIMIT_R5, 0x8B)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_R6, SAT_LIMIT_R6, 0x9B)},
+	{REG_FIELD_VALUE(CDC_SPK_DSM_R7, SAT_LIMIT_R7, 0x3F)},
+	{REG_FIELD_VALUE(VBAT_SNS, BOP_FREQ, 0x01)},
+	{REG_FIELD_VALUE(DRE_CTL_0, PROG_DELAY, 0x09)},
+	{REG_FIELD_VALUE(DRE_IDLE_DET_CTL, DRE_IDLE_FORCE_EN, 0x00)},
+	{REG_FIELD_VALUE(CURRENT_LIMIT, CURRENT_LIMIT, 0x08)},
+	{REG_FIELD_VALUE(DRE_CTL_0, OFFSET, 0x02)},
+	{REG_FIELD_VALUE(VAGC_TIME, REL_TIME, 0x03)},
+	{REG_FIELD_VALUE(VAGC_TIME, HLD_TIME, 0x03)},
+	{REG_FIELD_VALUE(VAGC_ATTN_LVL_2, VBAT_ATTN_LVL, 0x01)},
+	{REG_FIELD_VALUE(VAGC_ATTN_LVL_3, VBAT_ATTN_LVL, 0x02)},
+	{REG_FIELD_VALUE(VAGC_CTL, VBAT_AGC_EN, 0x01)},
+	{REG_FIELD_VALUE(TAGC_CTL, THERMAL_THRESH, 0x05)},
+	{REG_FIELD_VALUE(TAGC_TIME, REL_TIME, 0x03)},
+	// {WSA884X_TAGC_E2E_GAIN, 0x1F, 0x02},???
+	{REG_FIELD_VALUE(TEMP_CONFIG0, CTL_THRD_SAF2WAR, 0x02)},
+	{REG_FIELD_VALUE(TEMP_CONFIG1, CTL_THRD_WAR2SAF, 0x02)},
+	{REG_FIELD_VALUE(OTP_REG_1, LOW_TEMP_MSB, 0x49)},
+	{REG_FIELD_VALUE(OTP_REG_2, LOW_TEMP_LSB, 0x02)},
+	{REG_FIELD_VALUE(OTP_REG_3, HIGH_TEMP_MSB, 0xC9)},
+	{REG_FIELD_VALUE(OTP_REG_4, HIGH_TEMP_LSB, 0x01)},
+	{REG_FIELD_VALUE(TAGC_CTL, THERMAL_AGC_EN, 0x01)},
+	{REG_FIELD_VALUE(ADC_2, ISNS_LOAD_STORED, 0x00)},
+	{REG_FIELD_VALUE(ADC_7, EN_AZ_REG, 0x01)},
+	{REG_FIELD_VALUE(ADC_7, EN_SAR_REG, 0x01)},
+	{REG_FIELD_VALUE(CKWD_CTL_0, CKWD_FDIV_SEL, 0x00)},
+	{REG_FIELD_VALUE(DRE_CTL_1, CSR_GAIN, 0x10)},
+	{REG_FIELD_VALUE(CKWD_CTL_1, CKWD_VCOMP_VREF_SEL, 0x1B)},
+	{REG_FIELD_VALUE(BOOST_MISC, SPKR_RDY_CTL, 0x03)},
+};
+
+static int wsa884x_handle_post_irq(void *data);
+static int wsa884x_get_temperature(struct snd_soc_component *component,
+				   int *temp);
+enum {
+	WSA8840 = 0,
+	WSA8845,
+	WSA8842,
+	WSA8845_V2 = 5,
+};
+
+enum {
+	SPKR_STATUS = 0,
+	WSA_SUPPLIES_LPM_MODE,
+	SPKR_ADIE_LB,
+};
+
+enum {
+	WSA884X_IRQ_INT_SAF2WAR = 0,
+	WSA884X_IRQ_INT_WAR2SAF,
+	WSA884X_IRQ_INT_DISABLE,
+	WSA884X_IRQ_INT_OCP,
+	WSA884X_IRQ_INT_CLIP,
+	WSA884X_IRQ_INT_PDM_WD,
+	WSA884X_IRQ_INT_CLK_WD,
+	WSA884X_IRQ_INT_INTR_PIN,
+	WSA884X_IRQ_INT_UVLO,
+	WSA884X_IRQ_INT_PA_ON_ERR,
+	WSA884X_NUM_IRQS,
+};
+
+static const struct regmap_irq wsa884x_irqs[WSA884X_NUM_IRQS] = {
+	REGMAP_IRQ_REG(WSA884X_IRQ_INT_SAF2WAR, 0, 0x01),
+	REGMAP_IRQ_REG(WSA884X_IRQ_INT_WAR2SAF, 0, 0x02),
+	REGMAP_IRQ_REG(WSA884X_IRQ_INT_DISABLE, 0, 0x04),
+	REGMAP_IRQ_REG(WSA884X_IRQ_INT_OCP, 0, 0x08),
+	REGMAP_IRQ_REG(WSA884X_IRQ_INT_CLIP, 0, 0x10),
+	REGMAP_IRQ_REG(WSA884X_IRQ_INT_PDM_WD, 0, 0x20),
+	REGMAP_IRQ_REG(WSA884X_IRQ_INT_CLK_WD, 0, 0x40),
+	REGMAP_IRQ_REG(WSA884X_IRQ_INT_INTR_PIN, 0, 0x80),
+	REGMAP_IRQ_REG(WSA884X_IRQ_INT_UVLO, 1, 0x01),
+	REGMAP_IRQ_REG(WSA884X_IRQ_INT_PA_ON_ERR, 1, 0x02),
+};
+
+static struct regmap_irq_chip wsa884x_regmap_irq_chip = {
+	.name = "wsa884x",
+	.irqs = wsa884x_irqs,
+	.num_irqs = ARRAY_SIZE(wsa884x_irqs),
+	.num_regs = 2,
+	.status_base = WSA884X_INTR_STATUS0,
+	.mask_base = WSA884X_INTR_MASK0,
+	.type_base = WSA884X_INTR_LEVEL0,
+	.ack_base = WSA884X_INTR_CLEAR0,
+	.use_ack = 1,
+	.runtime_pm = false,
+	.handle_post_irq = wsa884x_handle_post_irq,
+	.irq_drv_data = NULL,
+};
+
+static int wsa884x_handle_post_irq(void *data)
+{
+	struct wsa884x_priv *wsa884x = data;
+	u32 sts1 = 0, sts2 = 0;
+
+	regmap_read(wsa884x->regmap, WSA884X_INTR_STATUS0, &sts1);
+	regmap_read(wsa884x->regmap, WSA884X_INTR_STATUS1, &sts2);
+
+	wsa884x->swr_slave->slave_irq_pending =
+			((sts1 || sts2) ? true : false);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int codec_debug_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static int get_parameters(char *buf, u32 *param1, int num_of_par)
+{
+	char *token;
+	int base, cnt;
+
+	token = strsep(&buf, " ");
+	for (cnt = 0; cnt < num_of_par; cnt++) {
+		if (token) {
+			if ((token[1] == 'x') || (token[1] == 'X'))
+				base = 16;
+			else
+				base = 10;
+
+			if (kstrtou32(token, base, &param1[cnt]) != 0)
+				return -EINVAL;
+
+			token = strsep(&buf, " ");
+		} else {
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static bool is_swr_slave_reg_readable(int reg)
+{
+	int ret = true;
+
+	if (((reg > 0x46) && (reg < 0x4A)) ||
+	    ((reg > 0x4A) && (reg < 0x50)) ||
+	    ((reg > 0x55) && (reg < 0xD0)) ||
+	    ((reg > 0xD0) && (reg < 0xE0)) ||
+	    ((reg > 0xE0) && (reg < 0xF0)) ||
+	    ((reg > 0xF0) && (reg < 0x100)) ||
+	    ((reg > 0x105) && (reg < 0x120)) ||
+	    ((reg > 0x205) && (reg < 0x220)) ||
+	    ((reg > 0x305) && (reg < 0x320)) ||
+	    ((reg > 0x405) && (reg < 0x420)) ||
+	    ((reg > 0x128) && (reg < 0x130)) ||
+	    ((reg > 0x228) && (reg < 0x230)) ||
+	    ((reg > 0x328) && (reg < 0x330)) ||
+	    ((reg > 0x428) && (reg < 0x430)) ||
+	    ((reg > 0x138) && (reg < 0x205)) ||
+	    ((reg > 0x238) && (reg < 0x305)) ||
+	    ((reg > 0x338) && (reg < 0x405)) ||
+	    ((reg > 0x405) && (reg < 0xF00)) ||
+	    ((reg > 0xF05) && (reg < 0xF20)) ||
+	    ((reg > 0xF25) && (reg < 0xF30)) ||
+	    ((reg > 0xF35) && (reg < 0x2000)))
+		ret = false;
+
+	return ret;
+}
+
+static ssize_t swr_slave_reg_show(struct swr_device *pdev, char __user *ubuf,
+					size_t count, loff_t *ppos)
+{
+	int i, reg_val, len;
+	ssize_t total = 0;
+	char tmp_buf[SWR_SLV_MAX_BUF_LEN];
+
+	if (!ubuf || !ppos)
+		return 0;
+
+	for (i = (((int) *ppos/BYTES_PER_LINE) + SWR_SLV_START_REG_ADDR);
+		i <= SWR_SLV_MAX_REG_ADDR; i++) {
+		if (!is_swr_slave_reg_readable(i))
+			continue;
+		swr_read(pdev, pdev->dev_num, i, &reg_val, 1);
+		len = snprintf(tmp_buf, sizeof(tmp_buf), "0x%.3x: 0x%.2x\n", i,
+			       (reg_val & 0xFF));
+		if (len < 0) {
+			pr_err("%s: fail to fill the buffer\n", __func__);
+			total = -EFAULT;
+			goto copy_err;
+		}
+		if ((total + len) >= count - 1)
+			break;
+		if (copy_to_user((ubuf + total), tmp_buf, len)) {
+			pr_err("%s: fail to copy reg dump\n", __func__);
+			total = -EFAULT;
+			goto copy_err;
+		}
+		total += len;
+		*ppos += len;
+	}
+
+copy_err:
+	*ppos = SWR_SLV_MAX_REG_ADDR * BYTES_PER_LINE;
+	return total;
+}
+
+static ssize_t codec_debug_dump(struct file *file, char __user *ubuf,
+				size_t count, loff_t *ppos)
+{
+	struct swr_device *pdev;
+
+	if (!count || !file || !ppos || !ubuf)
+		return -EINVAL;
+
+	pdev = file->private_data;
+	if (!pdev)
+		return -EINVAL;
+
+	if (*ppos < 0)
+		return -EINVAL;
+
+	return swr_slave_reg_show(pdev, ubuf, count, ppos);
+}
+
+static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
+				size_t count, loff_t *ppos)
+{
+	char lbuf[SWR_SLV_RD_BUF_LEN];
+	struct swr_device *pdev = NULL;
+	struct wsa884x_priv *wsa884x = NULL;
+
+	if (!count || !file || !ppos || !ubuf)
+		return -EINVAL;
+
+	pdev = file->private_data;
+	if (!pdev)
+		return -EINVAL;
+
+	wsa884x = swr_get_dev_data(pdev);
+	if (!wsa884x)
+		return -EINVAL;
+
+	if (*ppos < 0)
+		return -EINVAL;
+
+	snprintf(lbuf, sizeof(lbuf), "0x%x\n",
+			(wsa884x->read_data & 0xFF));
+
+	return simple_read_from_buffer(ubuf, count, ppos, lbuf,
+					       strnlen(lbuf, 7));
+}
+
+static ssize_t codec_debug_peek_write(struct file *file,
+	const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+	char lbuf[SWR_SLV_WR_BUF_LEN];
+	int rc = 0;
+	u32 param[5];
+	struct swr_device *pdev = NULL;
+	struct wsa884x_priv *wsa884x = NULL;
+
+	if (!cnt || !file || !ppos || !ubuf)
+		return -EINVAL;
+
+	pdev = file->private_data;
+	if (!pdev)
+		return -EINVAL;
+
+	wsa884x = swr_get_dev_data(pdev);
+	if (!wsa884x)
+		return -EINVAL;
+
+	if (*ppos < 0)
+		return -EINVAL;
+
+	if (cnt > sizeof(lbuf) - 1)
+		return -EINVAL;
+
+	rc = copy_from_user(lbuf, ubuf, cnt);
+	if (rc)
+		return -EFAULT;
+
+	lbuf[cnt] = '\0';
+	rc = get_parameters(lbuf, param, 1);
+	if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) && (rc == 0)))
+		return -EINVAL;
+	swr_read(pdev, pdev->dev_num, param[0], &wsa884x->read_data, 1);
+	if (rc == 0)
+		rc = cnt;
+	else
+		pr_err("%s: rc = %d\n", __func__, rc);
+
+	return rc;
+}
+
+static ssize_t codec_debug_write(struct file *file,
+	const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+	char lbuf[SWR_SLV_WR_BUF_LEN];
+	int rc = 0;
+	u32 param[5];
+	struct swr_device *pdev;
+
+	if (!file || !ppos || !ubuf)
+		return -EINVAL;
+
+	pdev = file->private_data;
+	if (!pdev)
+		return -EINVAL;
+
+	if (cnt > sizeof(lbuf) - 1)
+		return -EINVAL;
+
+	rc = copy_from_user(lbuf, ubuf, cnt);
+	if (rc)
+		return -EFAULT;
+
+	lbuf[cnt] = '\0';
+	rc = get_parameters(lbuf, param, 2);
+	if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) &&
+		(param[1] <= 0xFF) && (rc == 0)))
+		return -EINVAL;
+	swr_write(pdev, pdev->dev_num, param[0], &param[1]);
+	if (rc == 0)
+		rc = cnt;
+	else
+		pr_err("%s: rc = %d\n", __func__, rc);
+
+	return rc;
+}
+
+static const struct file_operations codec_debug_write_ops = {
+	.open = codec_debug_open,
+	.write = codec_debug_write,
+};
+
+static const struct file_operations codec_debug_read_ops = {
+	.open = codec_debug_open,
+	.read = codec_debug_read,
+	.write = codec_debug_peek_write,
+};
+
+static const struct file_operations codec_debug_dump_ops = {
+	.open = codec_debug_open,
+	.read = codec_debug_dump,
+};
+#endif
+
+static void wsa884x_regcache_sync(struct wsa884x_priv *wsa884x)
+{
+	mutex_lock(&wsa884x->res_lock);
+	regcache_mark_dirty(wsa884x->regmap);
+	regcache_sync(wsa884x->regmap);
+	mutex_unlock(&wsa884x->res_lock);
+}
+
+static irqreturn_t wsa884x_saf2war_handle_irq(int irq, void *data)
+{
+	pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
+			   __func__, irq);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wsa884x_war2saf_handle_irq(int irq, void *data)
+{
+	pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
+			   __func__, irq);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wsa884x_otp_handle_irq(int irq, void *data)
+{
+	pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
+			   __func__, irq);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wsa884x_ocp_handle_irq(int irq, void *data)
+{
+	pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
+			   __func__, irq);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wsa884x_clip_handle_irq(int irq, void *data)
+{
+	pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
+			   __func__, irq);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wsa884x_pdm_wd_handle_irq(int irq, void *data)
+{
+	pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
+			   __func__, irq);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wsa884x_clk_wd_handle_irq(int irq, void *data)
+{
+	pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
+			   __func__, irq);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wsa884x_ext_int_handle_irq(int irq, void *data)
+{
+	pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
+			   __func__, irq);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wsa884x_uvlo_handle_irq(int irq, void *data)
+{
+	pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
+			   __func__, irq);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wsa884x_pa_on_err_handle_irq(int irq, void *data)
+{
+	pr_err_ratelimited("%s: interrupt for irq =%d triggered\n",
+			   __func__, irq);
+	return IRQ_HANDLED;
+}
+
+static const char * const wsa_dev_mode_text[] = {
+	"speaker", "receiver", "ultrasound"
+};
+
+static const struct soc_enum wsa_dev_mode_enum =
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_dev_mode_text), wsa_dev_mode_text);
+
+static int wsa_dev_mode_get(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	ucontrol->value.integer.value[0] = wsa884x->dev_mode;
+
+	dev_dbg(component->dev, "%s: mode = 0x%x\n", __func__,
+			wsa884x->dev_mode);
+
+	return 0;
+}
+
+static int wsa_dev_mode_put(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0]  = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+
+	wsa884x->dev_mode =  ucontrol->value.integer.value[0];
+
+	return 0;
+}
+
+static const char * const wsa_pa_gain_text[] = {
+	"G_18_DB", "G_16P5_DB", "G_15_DB", "G_13P5_DB", "G_12_DB", "G_10P5_DB",
+	"G_9_DB", "G_7P5_DB", "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB",
+	"G_0_DB"
+};
+
+static const struct soc_enum wsa_pa_gain_enum =
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_pa_gain_text), wsa_pa_gain_text);
+
+static int wsa_pa_gain_get(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	ucontrol->value.integer.value[0] = wsa884x->pa_gain;
+
+	dev_dbg(component->dev, "%s: PA gain = 0x%x\n", __func__,
+			wsa884x->pa_gain);
+
+	return 0;
+}
+
+static int wsa_pa_gain_put(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0]  = %ld\n",
+		__func__, ucontrol->value.integer.value[0]);
+
+	wsa884x->pa_gain =  ucontrol->value.integer.value[0];
+
+	return 0;
+}
+
+static int wsa884x_get_mute(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	ucontrol->value.integer.value[0] = wsa884x->pa_mute;
+
+	return 0;
+}
+
+static int wsa884x_set_mute(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+	int value = ucontrol->value.integer.value[0];
+
+	dev_dbg(component->dev, "%s: mute current %d, new %d\n",
+		__func__, wsa884x->pa_mute, value);
+
+	wsa884x->pa_mute = value;
+
+	return 0;
+}
+
+static int wsa_get_temp(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+			snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+	int temp = 0;
+
+	if (test_bit(SPKR_STATUS, &wsa884x->status_mask))
+		temp = wsa884x->curr_temp;
+	else
+		wsa884x_get_temperature(component, &temp);
+
+	ucontrol->value.integer.value[0] = temp;
+
+	return 0;
+}
+
+static ssize_t wsa884x_codec_version_read(struct snd_info_entry *entry,
+			       void *file_private_data, struct file *file,
+			       char __user *buf, size_t count, loff_t pos)
+{
+	struct wsa884x_priv *wsa884x;
+	char buffer[WSA884X_VERSION_ENTRY_SIZE];
+	int len = 0;
+
+	wsa884x = (struct wsa884x_priv *) entry->private_data;
+	if (!wsa884x) {
+		pr_err("%s: wsa884x priv is null\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (wsa884x->version) {
+	case WSA884X_VERSION_1_0:
+		len = snprintf(buffer, sizeof(buffer), "WSA884X_1_0\n");
+		break;
+	case WSA884X_VERSION_1_1:
+		len = snprintf(buffer, sizeof(buffer), "WSA884X_1_1\n");
+		break;
+	default:
+		len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
+		break;
+	}
+
+	return simple_read_from_buffer(buf, count, &pos, buffer, len);
+}
+
+static struct snd_info_entry_ops wsa884x_codec_info_ops = {
+	.read = wsa884x_codec_version_read,
+};
+
+static ssize_t wsa884x_variant_read(struct snd_info_entry *entry,
+				    void *file_private_data,
+				    struct file *file,
+				    char __user *buf, size_t count,
+				    loff_t pos)
+{
+	struct wsa884x_priv *wsa884x;
+	char buffer[WSA884X_VARIANT_ENTRY_SIZE];
+	int len = 0;
+
+	wsa884x = (struct wsa884x_priv *) entry->private_data;
+	if (!wsa884x) {
+		pr_err("%s: wsa884x priv is null\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (wsa884x->variant) {
+	case WSA8840:
+		len = snprintf(buffer, sizeof(buffer), "WSA8840\n");
+		break;
+	case WSA8845:
+	case WSA8845_V2:
+		len = snprintf(buffer, sizeof(buffer), "WSA8845\n");
+		break;
+	case WSA8842:
+		len = snprintf(buffer, sizeof(buffer), "WSA8842\n");
+		break;
+	default:
+		len = snprintf(buffer, sizeof(buffer), "UNDEFINED\n");
+		break;
+	}
+
+	return simple_read_from_buffer(buf, count, &pos, buffer, len);
+}
+
+static struct snd_info_entry_ops wsa884x_variant_ops = {
+	.read = wsa884x_variant_read,
+};
+
+/*
+ * wsa884x_codec_info_create_codec_entry - creates wsa884x module
+ * @codec_root: The parent directory
+ * @component: Codec instance
+ *
+ * Creates wsa884x module and version entry under the given
+ * parent directory.
+ *
+ * Return: 0 on success or negative error code on failure.
+ */
+int wsa884x_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
+					  struct snd_soc_component *component)
+{
+	struct snd_info_entry *version_entry;
+	struct snd_info_entry *variant_entry;
+	struct wsa884x_priv *wsa884x;
+	struct snd_soc_card *card;
+	char name[80];
+
+	if (!codec_root || !component)
+		return -EINVAL;
+
+	wsa884x = snd_soc_component_get_drvdata(component);
+	if (wsa884x->entry) {
+		dev_dbg(wsa884x->dev,
+			"%s:wsa884x module already created\n", __func__);
+		return 0;
+	}
+	card = component->card;
+
+	snprintf(name, sizeof(name), "%s.%llx", "wsa884x",
+		 wsa884x->swr_slave->addr);
+
+	wsa884x->entry = snd_info_create_module_entry(codec_root->module,
+						(const char *)name,
+						codec_root);
+	if (!wsa884x->entry) {
+		dev_dbg(component->dev, "%s: failed to create wsa884x entry\n",
+			__func__);
+		return -ENOMEM;
+	}
+	wsa884x->entry->mode = S_IFDIR | 0555;
+	if (snd_info_register(wsa884x->entry) < 0) {
+		snd_info_free_entry(wsa884x->entry);
+		return -ENOMEM;
+	}
+
+	version_entry = snd_info_create_card_entry(card->snd_card,
+						   "version",
+						   wsa884x->entry);
+	if (!version_entry) {
+		dev_dbg(component->dev, "%s: failed to create wsa884x version entry\n",
+			__func__);
+		snd_info_free_entry(wsa884x->entry);
+		return -ENOMEM;
+	}
+
+	version_entry->private_data = wsa884x;
+	version_entry->size = WSA884X_VERSION_ENTRY_SIZE;
+	version_entry->content = SNDRV_INFO_CONTENT_DATA;
+	version_entry->c.ops = &wsa884x_codec_info_ops;
+
+	if (snd_info_register(version_entry) < 0) {
+		snd_info_free_entry(version_entry);
+		snd_info_free_entry(wsa884x->entry);
+		return -ENOMEM;
+	}
+	wsa884x->version_entry = version_entry;
+
+	variant_entry = snd_info_create_card_entry(card->snd_card,
+						   "variant",
+						   wsa884x->entry);
+	if (!variant_entry) {
+		dev_dbg(component->dev,
+			"%s: failed to create wsa884x variant entry\n",
+			__func__);
+		snd_info_free_entry(version_entry);
+		snd_info_free_entry(wsa884x->entry);
+		return -ENOMEM;
+	}
+
+	variant_entry->private_data = wsa884x;
+	variant_entry->size = WSA884X_VARIANT_ENTRY_SIZE;
+	variant_entry->content = SNDRV_INFO_CONTENT_DATA;
+	variant_entry->c.ops = &wsa884x_variant_ops;
+
+	if (snd_info_register(variant_entry) < 0) {
+		snd_info_free_entry(variant_entry);
+		snd_info_free_entry(version_entry);
+		snd_info_free_entry(wsa884x->entry);
+		return -ENOMEM;
+	}
+	wsa884x->variant_entry = variant_entry;
+
+	return 0;
+}
+EXPORT_SYMBOL(wsa884x_codec_info_create_codec_entry);
+
+/*
+ * wsa884x_codec_get_dev_num - returns swr device number
+ * @component: Codec instance
+ *
+ * Return: swr device number on success or negative error
+ * code on failure.
+ */
+int wsa884x_codec_get_dev_num(struct snd_soc_component *component)
+{
+	struct wsa884x_priv *wsa884x;
+
+	if (!component)
+		return -EINVAL;
+
+	wsa884x = snd_soc_component_get_drvdata(component);
+	if (!wsa884x) {
+		pr_err("%s: wsa884x component is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	return wsa884x->swr_slave->dev_num;
+}
+EXPORT_SYMBOL(wsa884x_codec_get_dev_num);
+
+static int wsa884x_get_dev_num(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x;
+
+	if (!component)
+		return -EINVAL;
+
+	wsa884x = snd_soc_component_get_drvdata(component);
+	if (!wsa884x) {
+		pr_err("%s: wsa884x component is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	ucontrol->value.integer.value[0] = wsa884x->swr_slave->dev_num;
+	return 0;
+}
+
+static int wsa884x_get_compander(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	ucontrol->value.integer.value[0] = wsa884x->comp_enable;
+	return 0;
+}
+
+static int wsa884x_set_compander(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+	int value = ucontrol->value.integer.value[0];
+
+	dev_dbg(component->dev, "%s: Compander enable current %d, new %d\n",
+		 __func__, wsa884x->comp_enable, value);
+	wsa884x->comp_enable = value;
+	return 0;
+}
+
+static int wsa884x_get_comp_offset(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	ucontrol->value.integer.value[0] = wsa884x->comp_offset;
+	return 0;
+}
+
+static int wsa884x_set_comp_offset(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+	int value = ucontrol->value.integer.value[0];
+
+	dev_dbg(component->dev, "%s: comp_offset %d\n",
+		__func__, wsa884x->comp_offset);
+	wsa884x->comp_offset = value;
+	return 0;
+}
+
+static int wsa884x_get_visense(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	ucontrol->value.integer.value[0] = wsa884x->visense_enable;
+	return 0;
+}
+
+static int wsa884x_set_visense(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+	int value = ucontrol->value.integer.value[0];
+
+	dev_dbg(component->dev, "%s: VIsense enable current %d, new %d\n",
+		 __func__, wsa884x->visense_enable, value);
+	wsa884x->visense_enable = value;
+	return 0;
+}
+
+static int wsa884x_get_ext_vdd_spk(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	ucontrol->value.integer.value[0] = wsa884x->ext_vdd_spk;
+
+	return 0;
+}
+
+static int wsa884x_put_ext_vdd_spk(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+	int value = ucontrol->value.integer.value[0];
+
+	dev_dbg(component->dev, "%s: Ext VDD SPK enable current %d, new %d\n",
+		 __func__, wsa884x->ext_vdd_spk, value);
+	wsa884x->ext_vdd_spk = value;
+
+	return 0;
+}
+
+static const struct snd_kcontrol_new wsa884x_snd_controls[] = {
+	SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum,
+			wsa_pa_gain_get, wsa_pa_gain_put),
+
+	SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0,
+			wsa884x_get_mute, wsa884x_set_mute),
+
+	SOC_SINGLE_EXT("WSA Temp", SND_SOC_NOPM, 0, UINT_MAX, 0,
+			wsa_get_temp, NULL),
+
+	SOC_SINGLE_EXT("WSA Get DevNum", SND_SOC_NOPM, 0, UINT_MAX, 0,
+			wsa884x_get_dev_num, NULL),
+
+	SOC_ENUM_EXT("WSA MODE", wsa_dev_mode_enum,
+			wsa_dev_mode_get, wsa_dev_mode_put),
+
+	SOC_SINGLE_EXT("COMP Offset", SND_SOC_NOPM, 0, 4, 0,
+			wsa884x_get_comp_offset, wsa884x_set_comp_offset),
+
+	SOC_SINGLE_EXT("COMP Switch", SND_SOC_NOPM, 0, 1, 0,
+			wsa884x_get_compander, wsa884x_set_compander),
+
+	SOC_SINGLE_EXT("VISENSE Switch", SND_SOC_NOPM, 0, 1, 0,
+			wsa884x_get_visense, wsa884x_set_visense),
+
+	SOC_SINGLE_EXT("External VDD_SPK", SND_SOC_NOPM, 0, 1, 0,
+			wsa884x_get_ext_vdd_spk, wsa884x_put_ext_vdd_spk),
+};
+
+static const struct snd_kcontrol_new swr_dac_port[] = {
+	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static int wsa884x_set_port(struct snd_soc_component *component, int port_idx,
+			u8 *port_id, u8 *num_ch, u8 *ch_mask, u32 *ch_rate,
+			u8 *port_type)
+{
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	*port_id = wsa884x->port[port_idx].port_id;
+	*num_ch = wsa884x->port[port_idx].num_ch;
+	*ch_mask = wsa884x->port[port_idx].ch_mask;
+	*ch_rate = wsa884x->port[port_idx].ch_rate;
+	*port_type = wsa884x->port[port_idx].port_type;
+	return 0;
+}
+
+static int wsa884x_enable_swr_dac_port(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 wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+	u8 port_id[WSA884X_MAX_SWR_PORTS];
+	u8 num_ch[WSA884X_MAX_SWR_PORTS];
+	u8 ch_mask[WSA884X_MAX_SWR_PORTS];
+	u32 ch_rate[WSA884X_MAX_SWR_PORTS];
+	u8 port_type[WSA884X_MAX_SWR_PORTS];
+	u8 num_port = 0;
+
+	dev_dbg(component->dev, "%s: event %d name %s\n", __func__,
+		event, w->name);
+	if (wsa884x == NULL)
+		return -EINVAL;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		wsa884x_set_port(component, SWR_DAC_PORT,
+				&port_id[num_port], &num_ch[num_port],
+				&ch_mask[num_port], &ch_rate[num_port],
+				&port_type[num_port]);
+		++num_port;
+
+		if (wsa884x->comp_enable) {
+			wsa884x_set_port(component, SWR_COMP_PORT,
+					&port_id[num_port], &num_ch[num_port],
+					&ch_mask[num_port], &ch_rate[num_port],
+					&port_type[num_port]);
+			++num_port;
+		}
+		if (wsa884x->visense_enable) {
+			wsa884x_set_port(component, SWR_VISENSE_PORT,
+					&port_id[num_port], &num_ch[num_port],
+					&ch_mask[num_port], &ch_rate[num_port],
+					&port_type[num_port]);
+			++num_port;
+		}
+		swr_connect_port(wsa884x->swr_slave, &port_id[0], num_port,
+				&ch_mask[0], &ch_rate[0], &num_ch[0],
+					&port_type[0]);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		set_bit(SPKR_STATUS, &wsa884x->status_mask);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		wsa884x_set_port(component, SWR_DAC_PORT,
+				&port_id[num_port], &num_ch[num_port],
+				&ch_mask[num_port], &ch_rate[num_port],
+				&port_type[num_port]);
+		++num_port;
+
+		if (wsa884x->comp_enable) {
+			wsa884x_set_port(component, SWR_COMP_PORT,
+					&port_id[num_port], &num_ch[num_port],
+					&ch_mask[num_port], &ch_rate[num_port],
+					&port_type[num_port]);
+			++num_port;
+		}
+		if (wsa884x->visense_enable) {
+			wsa884x_set_port(component, SWR_VISENSE_PORT,
+					&port_id[num_port], &num_ch[num_port],
+					&ch_mask[num_port], &ch_rate[num_port],
+					&port_type[num_port]);
+			++num_port;
+		}
+		swr_disconnect_port(wsa884x->swr_slave, &port_id[0], num_port,
+				&ch_mask[0], &port_type[0]);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (swr_set_device_group(wsa884x->swr_slave, SWR_GROUP_NONE))
+			dev_err(component->dev,
+				"%s: set num ch failed\n", __func__);
+
+		swr_slvdev_datapath_control(wsa884x->swr_slave,
+					    wsa884x->swr_slave->dev_num,
+					    false);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int wsa884x_spkr_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);
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	dev_dbg(component->dev, "%s: %s %d\n", __func__, w->name, event);
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		swr_slvdev_datapath_control(wsa884x->swr_slave,
+					    wsa884x->swr_slave->dev_num,
+					    true);
+		/* Added delay as per HW sequence */
+		usleep_range(250, 300);
+		snd_soc_component_update_bits(component,
+			REG_FIELD_VALUE(DRE_CTL_1, CSR_GAIN_EN, 0x01));
+		/* Added delay as per HW sequence */
+		usleep_range(250, 300);
+		if (wsa884x->comp_enable)
+			snd_soc_component_update_bits(component,
+				REG_FIELD_VALUE(DRE_CTL_0, OFFSET,
+						wsa884x->comp_offset));
+		wcd_enable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_UVLO);
+		/* Force remove group */
+		swr_remove_from_group(wsa884x->swr_slave,
+				      wsa884x->swr_slave->dev_num);
+		snd_soc_component_update_bits(component,
+			REG_FIELD_VALUE(VBAT_THRM_FLT_CTL, VBAT_COEF_SEL, 0x03));
+		snd_soc_component_update_bits(component,
+			REG_FIELD_VALUE(VBAT_THRM_FLT_CTL, VBAT_FLT_EN, 0x01));
+		if (test_bit(SPKR_ADIE_LB, &wsa884x->status_mask))
+			snd_soc_component_update_bits(component,
+				REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x01));
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		if (!test_bit(SPKR_ADIE_LB, &wsa884x->status_mask))
+			wcd_disable_irq(&wsa884x->irq_info,
+					WSA884X_IRQ_INT_PDM_WD);
+		snd_soc_component_update_bits(component,
+			REG_FIELD_VALUE(VBAT_THRM_FLT_CTL, VBAT_FLT_EN, 0x00));
+		snd_soc_component_update_bits(component,
+			REG_FIELD_VALUE(VBAT_THRM_FLT_CTL, VBAT_COEF_SEL, 0x00));
+		snd_soc_component_update_bits(component,
+			REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x00));
+		snd_soc_component_update_bits(component,
+			REG_FIELD_VALUE(PDM_WD_CTL, PDM_WD_EN, 0x00));
+		wcd_disable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_UVLO);
+		clear_bit(SPKR_STATUS, &wsa884x->status_mask);
+		clear_bit(SPKR_ADIE_LB, &wsa884x->status_mask);
+		break;
+	}
+	return 0;
+}
+
+static const struct snd_soc_dapm_widget wsa884x_dapm_widgets[] = {
+	SND_SOC_DAPM_INPUT("IN"),
+	SND_SOC_DAPM_MIXER_E("SWR DAC_Port", SND_SOC_NOPM, 0, 0, swr_dac_port,
+		ARRAY_SIZE(swr_dac_port), wsa884x_enable_swr_dac_port,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SPK("SPKR", wsa884x_spkr_event),
+};
+
+static const struct snd_soc_dapm_route wsa884x_audio_map[] = {
+	{"SWR DAC_Port", "Switch", "IN"},
+	{"SPKR", NULL, "SWR DAC_Port"},
+};
+
+int wsa884x_set_channel_map(struct snd_soc_component *component, u8 *port,
+			    u8 num_port, unsigned int *ch_mask,
+			    unsigned int *ch_rate, u8 *port_type)
+{
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+	int i;
+
+	if (!port || !ch_mask || !ch_rate ||
+		(num_port > WSA884X_MAX_SWR_PORTS)) {
+		dev_err(component->dev,
+			"%s: Invalid port=%pK, ch_mask=%pK, ch_rate=%pK\n",
+			__func__, port, ch_mask, ch_rate);
+		return -EINVAL;
+	}
+	for (i = 0; i < num_port; i++) {
+		wsa884x->port[i].port_id = port[i];
+		wsa884x->port[i].ch_mask = ch_mask[i];
+		wsa884x->port[i].ch_rate = ch_rate[i];
+		wsa884x->port[i].num_ch = __sw_hweight8(ch_mask[i]);
+		if (port_type)
+			wsa884x->port[i].port_type = port_type[i];
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(wsa884x_set_channel_map);
+
+static void wsa884x_codec_init(struct snd_soc_component *component)
+{
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+	int i;
+
+	if (!wsa884x)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(reg_init); i++)
+		snd_soc_component_update_bits(component, reg_init[i].reg,
+					reg_init[i].mask, reg_init[i].val);
+
+	if (wsa884x->variant == WSA8840 || wsa884x->variant == WSA8842) {
+		snd_soc_component_update_bits(component,
+			REG_FIELD_VALUE(DRE_CTL_0, OFFSET, 0x03));
+		wsa884x->comp_offset = COMP_OFFSET3;
+	}
+}
+
+static int32_t wsa884x_temp_reg_read(struct snd_soc_component *component,
+				     struct wsa_temp_register *wsa_temp_reg)
+{
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	if (!wsa884x) {
+		dev_err(component->dev, "%s: wsa884x is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&wsa884x->res_lock);
+
+	snd_soc_component_update_bits(component,
+		REG_FIELD_VALUE(PA_FSM_BYP0, DC_CAL_EN, 0x01));
+	snd_soc_component_update_bits(component,
+		REG_FIELD_VALUE(PA_FSM_BYP0, BG_EN, 0x01));
+	snd_soc_component_update_bits(component,
+		REG_FIELD_VALUE(PA_FSM_BYP0, CLK_WD_EN, 0x01));
+	snd_soc_component_update_bits(component,
+		REG_FIELD_VALUE(PA_FSM_BYP0, TSADC_EN, 0x01));
+	snd_soc_component_update_bits(component,
+		REG_FIELD_VALUE(PA_FSM_BYP0, D_UNMUTE, 0x01));
+	snd_soc_component_update_bits(component,
+		REG_FIELD_VALUE(PA_FSM_BYP0, SPKR_PROT_EN, 0x01));
+
+	snd_soc_component_update_bits(component,
+		REG_FIELD_VALUE(TADC_VALUE_CTL, TEMP_VALUE_RD_EN, 0x00));
+	wsa_temp_reg->dmeas_msb = snd_soc_component_read(component,
+							WSA884X_TEMP_DIN_MSB);
+	wsa_temp_reg->dmeas_lsb = snd_soc_component_read(component,
+							WSA884X_TEMP_DIN_LSB);
+	snd_soc_component_update_bits(component,
+		REG_FIELD_VALUE(TADC_VALUE_CTL, TEMP_VALUE_RD_EN, 0x01));
+	wsa_temp_reg->d1_msb = snd_soc_component_read(component,
+						     WSA884X_OTP_REG_1);
+	wsa_temp_reg->d1_lsb = snd_soc_component_read(component,
+						     WSA884X_OTP_REG_2);
+	wsa_temp_reg->d2_msb = snd_soc_component_read(component,
+						     WSA884X_OTP_REG_3);
+	wsa_temp_reg->d2_lsb = snd_soc_component_read(component,
+						     WSA884X_OTP_REG_4);
+
+	snd_soc_component_update_bits(component,
+				     WSA884X_PA_FSM_BYP0, 0xE7, 0x00);
+	mutex_unlock(&wsa884x->res_lock);
+
+	return 0;
+}
+
+static int wsa884x_get_temperature(struct snd_soc_component *component,
+				   int *temp)
+{
+	struct wsa_temp_register reg;
+	int dmeas, d1, d2;
+	int ret = 0;
+	int temp_val = 0;
+	int t1 = T1_TEMP;
+	int t2 = T2_TEMP;
+	u8 retry = WSA884X_TEMP_RETRY;
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	if (!wsa884x)
+		return -EINVAL;
+
+	do {
+		ret = wsa884x_temp_reg_read(component, &reg);
+		if (ret) {
+			pr_err("%s: temp read failed: %d, current temp: %d\n",
+				__func__, ret, wsa884x->curr_temp);
+			if (temp)
+				*temp = wsa884x->curr_temp;
+			return 0;
+		}
+		/*
+		 * Temperature register values are expected to be in the
+		 * following range.
+		 * d1_msb  = 68 - 92 and d1_lsb  = 0, 64, 128, 192
+		 * d2_msb  = 185 -218 and  d2_lsb  = 0, 64, 128, 192
+		 */
+		if ((reg.d1_msb < 68 || reg.d1_msb > 92) ||
+		    (!(reg.d1_lsb == 0 || reg.d1_lsb == 64 || reg.d1_lsb == 128 ||
+			reg.d1_lsb == 192)) ||
+		    (reg.d2_msb < 185 || reg.d2_msb > 218) ||
+		    (!(reg.d2_lsb == 0 || reg.d2_lsb == 64 || reg.d2_lsb == 128 ||
+			reg.d2_lsb == 192))) {
+			printk_ratelimited("%s: Temperature registers[%d %d %d %d] are out of range\n",
+					   __func__, reg.d1_msb, reg.d1_lsb, reg.d2_msb,
+					   reg.d2_lsb);
+		}
+		dmeas = ((reg.dmeas_msb << 0x8) | reg.dmeas_lsb) >> 0x6;
+		d1 = ((reg.d1_msb << 0x8) | reg.d1_lsb) >> 0x6;
+		d2 = ((reg.d2_msb << 0x8) | reg.d2_lsb) >> 0x6;
+
+		if (d1 == d2)
+			temp_val = TEMP_INVALID;
+		else
+			temp_val = t1 + (((dmeas - d1) * (t2 - t1))/(d2 - d1));
+
+		if (temp_val <= LOW_TEMP_THRESHOLD ||
+			temp_val >= HIGH_TEMP_THRESHOLD) {
+			pr_debug("%s: T0: %d is out of range[%d, %d]\n", __func__,
+				 temp_val, LOW_TEMP_THRESHOLD, HIGH_TEMP_THRESHOLD);
+			if (retry--)
+				msleep(10);
+		} else {
+			break;
+		}
+	} while (retry);
+
+	wsa884x->curr_temp = temp_val;
+	if (temp)
+		*temp = temp_val;
+	pr_debug("%s: t0 measured: %d dmeas = %d, d1 = %d, d2 = %d\n",
+		  __func__, temp_val, dmeas, d1, d2);
+
+	return ret;
+}
+
+static int wsa884x_codec_probe(struct snd_soc_component *component)
+{
+	char w_name[MAX_NAME_LEN];
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+	struct swr_device *dev;
+	int variant = 0, version = 0;
+	struct snd_soc_dapm_context *dapm =
+			snd_soc_component_get_dapm(component);
+
+	if (!wsa884x)
+		return -EINVAL;
+
+	if (!component->name_prefix)
+		return -EINVAL;
+
+	snd_soc_component_init_regmap(component, wsa884x->regmap);
+
+	dev = wsa884x->swr_slave;
+	wsa884x->component = component;
+
+	variant = (snd_soc_component_read(component, WSA884X_OTP_REG_0)
+					 & FIELD_MASK(OTP_REG_0, WSA884X_ID));
+	wsa884x->variant = variant;
+
+	version = (snd_soc_component_read(component, WSA884X_CHIP_ID0)
+					& FIELD_MASK(CHIP_ID0, BYTE_0));
+
+	wsa884x->version = version;
+
+	wsa884x->comp_offset = COMP_OFFSET2;
+	wsa884x_codec_init(component);
+	wsa884x->global_pa_cnt = 0;
+
+	memset(w_name, 0, sizeof(w_name));
+	strlcpy(w_name, component->name_prefix, sizeof(w_name));
+	strlcat(w_name, " ", sizeof(w_name));
+	strlcat(w_name, wsa884x->dai_driver->playback.stream_name,
+				sizeof(w_name));
+	snd_soc_dapm_ignore_suspend(dapm, w_name);
+
+	memset(w_name, 0, sizeof(w_name));
+	strlcpy(w_name, component->name_prefix, sizeof(w_name));
+	strlcat(w_name, " IN", sizeof(w_name));
+	snd_soc_dapm_ignore_suspend(dapm, w_name);
+
+	memset(w_name, 0, sizeof(w_name));
+	strlcpy(w_name, component->name_prefix, sizeof(w_name));
+	strlcat(w_name, " SWR DAC_Port", sizeof(w_name));
+	snd_soc_dapm_ignore_suspend(dapm, w_name);
+
+	memset(w_name, 0, sizeof(w_name));
+	strlcpy(w_name, component->name_prefix, sizeof(w_name));
+	strlcat(w_name, " SPKR", sizeof(w_name));
+	snd_soc_dapm_ignore_suspend(dapm, w_name);
+
+	snd_soc_dapm_sync(dapm);
+
+	return 0;
+}
+
+static void wsa884x_codec_remove(struct snd_soc_component *component)
+{
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	if (!wsa884x)
+		return;
+
+	snd_soc_component_exit_regmap(component);
+
+	return;
+}
+
+static int wsa884x_soc_codec_suspend(struct snd_soc_component *component)
+{
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	if (!wsa884x)
+		return 0;
+
+	wsa884x->dapm_bias_off = true;
+	return 0;
+}
+
+static int wsa884x_soc_codec_resume(struct snd_soc_component *component)
+{
+	struct wsa884x_priv *wsa884x = snd_soc_component_get_drvdata(component);
+
+	if (!wsa884x)
+		return 0;
+
+	wsa884x->dapm_bias_off = false;
+	return 0;
+}
+
+static const struct snd_soc_component_driver soc_codec_dev_wsa884x_wsa = {
+	.name = "",
+	.probe = wsa884x_codec_probe,
+	.remove = wsa884x_codec_remove,
+	.controls = wsa884x_snd_controls,
+	.num_controls = ARRAY_SIZE(wsa884x_snd_controls),
+	.dapm_widgets = wsa884x_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(wsa884x_dapm_widgets),
+	.dapm_routes = wsa884x_audio_map,
+	.num_dapm_routes = ARRAY_SIZE(wsa884x_audio_map),
+	.suspend =  wsa884x_soc_codec_suspend,
+	.resume = wsa884x_soc_codec_resume,
+};
+
+static int wsa884x_gpio_ctrl(struct wsa884x_priv *wsa884x, bool enable)
+{
+	int ret = 0;
+
+	if (enable)
+		ret = msm_cdc_pinctrl_select_active_state(
+						wsa884x->wsa_rst_np);
+	else
+		ret = msm_cdc_pinctrl_select_sleep_state(
+						wsa884x->wsa_rst_np);
+	if (ret != 0)
+		dev_err(wsa884x->dev,
+			"%s: Failed to turn state %d; ret=%d\n",
+			__func__, enable, ret);
+
+	return ret;
+}
+
+static int wsa884x_swr_up(struct wsa884x_priv *wsa884x)
+{
+	int ret;
+
+	ret = wsa884x_gpio_ctrl(wsa884x, true);
+	if (ret)
+		dev_err(wsa884x->dev, "%s: Failed to enable gpio\n", __func__);
+
+	return ret;
+}
+
+static int wsa884x_swr_down(struct wsa884x_priv *wsa884x)
+{
+	int ret;
+
+	ret = wsa884x_gpio_ctrl(wsa884x, false);
+	if (ret)
+		dev_err(wsa884x->dev, "%s: Failed to disable gpio\n", __func__);
+
+	return ret;
+}
+
+static int wsa884x_swr_reset(struct wsa884x_priv *wsa884x)
+{
+	u8 retry = WSA884X_NUM_RETRY;
+	u8 devnum = 0;
+	struct swr_device *pdev;
+
+	pdev = wsa884x->swr_slave;
+	while (swr_get_logical_dev_num(pdev, pdev->addr, &devnum) && retry--) {
+		/* Retry after 1 msec delay */
+		usleep_range(1000, 1100);
+	}
+	pdev->dev_num = devnum;
+	wsa884x_regcache_sync(wsa884x);
+
+	return 0;
+}
+
+static int wsa884x_event_notify(struct notifier_block *nb,
+				unsigned long val, void *ptr)
+{
+	u16 event = (val & 0xffff);
+	struct wsa884x_priv *wsa884x = container_of(nb, struct wsa884x_priv,
+						    parent_nblock);
+
+	if (!wsa884x)
+		return -EINVAL;
+
+	switch (event) {
+	case BOLERO_SLV_EVT_PA_OFF_PRE_SSR:
+		if (test_bit(SPKR_STATUS, &wsa884x->status_mask))
+			snd_soc_component_update_bits(wsa884x->component,
+				REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x00));
+		wsa884x_swr_down(wsa884x);
+		break;
+
+	case BOLERO_SLV_EVT_SSR_UP:
+		wsa884x_swr_up(wsa884x);
+		/* Add delay to allow enumerate */
+		usleep_range(20000, 20010);
+		wsa884x_swr_reset(wsa884x);
+		break;
+
+	case BOLERO_SLV_EVT_PA_ON_POST_FSCLK:
+		if (test_bit(SPKR_STATUS, &wsa884x->status_mask)) {
+			snd_soc_component_update_bits(wsa884x->component,
+				REG_FIELD_VALUE(PDM_WD_CTL, PDM_WD_EN, 0x01));
+			snd_soc_component_update_bits(wsa884x->component,
+				REG_FIELD_VALUE(PA_FSM_EN, GLOBAL_PA_EN, 0x01));
+			wcd_enable_irq(&wsa884x->irq_info,
+					WSA884X_IRQ_INT_PDM_WD);
+			/* Added delay as per HW sequence */
+			usleep_range(3000, 3100);
+			snd_soc_component_update_bits(wsa884x->component,
+				REG_FIELD_VALUE(DRE_CTL_1, CSR_GAIN_EN, 0x00));
+			/* Added delay as per HW sequence */
+			usleep_range(5000, 5050);
+		}
+		break;
+	case BOLERO_SLV_EVT_PA_ON_POST_FSCLK_ADIE_LB:
+		if (test_bit(SPKR_STATUS, &wsa884x->status_mask))
+			set_bit(SPKR_ADIE_LB, &wsa884x->status_mask);
+		break;
+	default:
+		dev_dbg(wsa884x->dev, "%s: unknown event %d\n",
+			__func__, event);
+		break;
+	}
+
+	return 0;
+}
+
+static int wsa884x_enable_supplies(struct device *dev,
+				   struct wsa884x_priv *priv)
+{
+	int ret = 0;
+
+	/* Parse power supplies */
+	msm_cdc_get_power_supplies(dev, &priv->regulator,
+				   &priv->num_supplies);
+	if (!priv->regulator || (priv->num_supplies <= 0)) {
+		dev_err(dev, "%s: no power supplies defined\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = msm_cdc_init_supplies(dev, &priv->supplies,
+				    priv->regulator, priv->num_supplies);
+	if (!priv->supplies) {
+		dev_err(dev, "%s: Cannot init wsa supplies\n",
+			__func__);
+		return ret;
+	}
+
+	ret = msm_cdc_enable_static_supplies(dev, priv->supplies,
+					     priv->regulator,
+					     priv->num_supplies);
+	if (ret)
+		dev_err(dev, "%s: wsa static supply enable failed!\n",
+			__func__);
+
+	return ret;
+}
+
+static struct snd_soc_dai_driver wsa_dai[] = {
+	{
+		.name = "",
+		.playback = {
+			.stream_name = "",
+			.rates = WSA884X_RATES | WSA884X_FRAC_RATES,
+			.formats = WSA884X_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 2,
+		},
+	},
+};
+
+static int wsa884x_swr_probe(struct swr_device *pdev)
+{
+	int ret = 0, i = 0;
+	struct wsa884x_priv *wsa884x;
+	u8 devnum = 0;
+	bool pin_state_current = false;
+	struct wsa_ctrl_platform_data *plat_data = NULL;
+	struct snd_soc_component *component;
+	const char *wsa884x_name_prefix_of = NULL;
+	char buffer[MAX_NAME_LEN];
+	int dev_index = 0;
+
+	wsa884x = devm_kzalloc(&pdev->dev, sizeof(struct wsa884x_priv),
+			    GFP_KERNEL);
+	if (!wsa884x)
+		return -ENOMEM;
+
+	ret = wsa884x_enable_supplies(&pdev->dev, wsa884x);
+	if (ret) {
+		ret = -EPROBE_DEFER;
+		goto err;
+	}
+
+	wsa884x->wsa_rst_np = of_parse_phandle(pdev->dev.of_node,
+					     "qcom,spkr-sd-n-node", 0);
+	if (!wsa884x->wsa_rst_np) {
+		dev_dbg(&pdev->dev, "%s: pinctrl not defined\n", __func__);
+		goto err_supply;
+	}
+	swr_set_dev_data(pdev, wsa884x);
+	wsa884x->swr_slave = pdev;
+	pin_state_current = msm_cdc_pinctrl_get_state(wsa884x->wsa_rst_np);
+	wsa884x_gpio_ctrl(wsa884x, true);
+	/*
+	 * Add 5msec delay to provide sufficient time for
+	 * soundwire auto enumeration of slave devices as
+	 * per HW requirement.
+	 */
+	usleep_range(5000, 5010);
+	ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum);
+	if (ret) {
+		dev_dbg(&pdev->dev,
+			"%s get devnum %d for dev addr %lx failed\n",
+			__func__, devnum, pdev->addr);
+		ret = -EPROBE_DEFER;
+		goto err_supply;
+	}
+	pdev->dev_num = devnum;
+
+	wsa884x->regmap = devm_regmap_init_swr(pdev,
+					       &wsa884x_regmap_config);
+	if (IS_ERR(wsa884x->regmap)) {
+		ret = PTR_ERR(wsa884x->regmap);
+		dev_err(&pdev->dev, "%s: regmap_init failed %d\n",
+			__func__, ret);
+		goto dev_err;
+	}
+
+	devm_regmap_qti_debugfs_register(&pdev->dev, wsa884x->regmap);
+
+	/* Set all interrupts as edge triggered */
+	for (i = 0; i < wsa884x_regmap_irq_chip.num_regs; i++)
+		regmap_write(wsa884x->regmap, (WSA884X_INTR_LEVEL0 + i), 0);
+
+	wsa884x_regmap_irq_chip.irq_drv_data = wsa884x;
+	wsa884x->irq_info.wcd_regmap_irq_chip = &wsa884x_regmap_irq_chip;
+	wsa884x->irq_info.codec_name = "WSA884X";
+	wsa884x->irq_info.regmap = wsa884x->regmap;
+	wsa884x->irq_info.dev = &pdev->dev;
+	ret = wcd_irq_init(&wsa884x->irq_info, &wsa884x->virq);
+
+	if (ret) {
+		dev_err(wsa884x->dev, "%s: IRQ init failed: %d\n",
+			__func__, ret);
+		goto dev_err;
+	}
+
+	wcd_request_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_SAF2WAR,
+			"WSA SAF2WAR", wsa884x_saf2war_handle_irq, NULL);
+
+	wcd_disable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_SAF2WAR);
+
+	wcd_request_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_WAR2SAF,
+			"WSA WAR2SAF", wsa884x_war2saf_handle_irq, NULL);
+
+	wcd_disable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_WAR2SAF);
+
+	wcd_request_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_DISABLE,
+			"WSA OTP", wsa884x_otp_handle_irq, NULL);
+
+	wcd_disable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_DISABLE);
+
+	wcd_request_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_OCP,
+			"WSA OCP", wsa884x_ocp_handle_irq, NULL);
+
+	wcd_disable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_OCP);
+
+	wcd_request_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_CLIP,
+			"WSA CLIP", wsa884x_clip_handle_irq, NULL);
+
+	wcd_disable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_CLIP);
+
+	wcd_request_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_PDM_WD,
+			"WSA PDM WD", wsa884x_pdm_wd_handle_irq, NULL);
+
+	wcd_disable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_PDM_WD);
+
+	wcd_request_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_CLK_WD,
+			"WSA CLK WD", wsa884x_clk_wd_handle_irq, NULL);
+
+	wcd_disable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_CLK_WD);
+
+	wcd_request_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_INTR_PIN,
+			"WSA EXT INT", wsa884x_ext_int_handle_irq, NULL);
+
+	wcd_disable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_INTR_PIN);
+
+	/* Under Voltage Lock out (UVLO) interrupt handle */
+	wcd_request_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_UVLO,
+			"WSA UVLO", wsa884x_uvlo_handle_irq, NULL);
+
+	wcd_disable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_UVLO);
+
+	wcd_request_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_PA_ON_ERR,
+			"WSA PA ERR", wsa884x_pa_on_err_handle_irq, NULL);
+
+	wcd_disable_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_PA_ON_ERR);
+
+	ret = of_property_read_string(pdev->dev.of_node, "qcom,wsa-prefix",
+				&wsa884x_name_prefix_of);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"%s: Looking up %s property in node %s failed\n",
+			__func__, "qcom,wsa-prefix",
+			pdev->dev.of_node->full_name);
+		goto err_irq;
+	}
+
+	wsa884x->driver = devm_kzalloc(&pdev->dev,
+			sizeof(struct snd_soc_component_driver), GFP_KERNEL);
+	if (!wsa884x->driver) {
+		ret = -ENOMEM;
+		goto err_irq;
+	}
+
+	memcpy(wsa884x->driver, &soc_codec_dev_wsa884x_wsa,
+			sizeof(struct snd_soc_component_driver));
+
+	wsa884x->dai_driver = devm_kzalloc(&pdev->dev,
+				sizeof(struct snd_soc_dai_driver), GFP_KERNEL);
+	if (!wsa884x->dai_driver) {
+		ret = -ENOMEM;
+		goto err_mem;
+	}
+
+	memcpy(wsa884x->dai_driver, wsa_dai, sizeof(struct snd_soc_dai_driver));
+
+	/* Get last digit from HEX format */
+	dev_index = (int)((char)(pdev->addr & 0xF));
+
+	if (of_device_is_compatible(pdev->dev.of_node, "qcom,wsa884x_2"))
+		dev_index += 2;
+
+	snprintf(buffer, sizeof(buffer), "wsa-codec.%d", dev_index);
+	wsa884x->driver->name = kstrndup(buffer, strlen(buffer), GFP_KERNEL);
+
+	snprintf(buffer, sizeof(buffer), "wsa_rx%d", dev_index);
+	wsa884x->dai_driver->name =
+				kstrndup(buffer, strlen(buffer), GFP_KERNEL);
+
+	snprintf(buffer, sizeof(buffer), "WSA884X_AIF%d Playback", dev_index);
+	wsa884x->dai_driver->playback.stream_name =
+				kstrndup(buffer, strlen(buffer), GFP_KERNEL);
+
+	/* Number of DAI's used is 1 */
+	ret = snd_soc_register_component(&pdev->dev,
+				wsa884x->driver, wsa884x->dai_driver, 1);
+
+	wsa884x->wsa884x_name_prefix = kstrndup(wsa884x_name_prefix_of,
+			strlen(wsa884x_name_prefix_of), GFP_KERNEL);
+	component = snd_soc_lookup_component(&pdev->dev, wsa884x->driver->name);
+	if (!component) {
+		dev_err(&pdev->dev, "%s: component is NULL\n", __func__);
+		ret = -EINVAL;
+		goto err_mem;
+	}
+	component->name_prefix = wsa884x->wsa884x_name_prefix;
+
+	wsa884x->parent_np = of_parse_phandle(pdev->dev.of_node,
+					      "qcom,bolero-handle", 0);
+	if (!wsa884x->parent_np)
+		wsa884x->parent_np = of_parse_phandle(pdev->dev.of_node,
+					      "qcom,lpass-cdc-handle", 0);
+	if (wsa884x->parent_np) {
+		wsa884x->parent_dev =
+				of_find_device_by_node(wsa884x->parent_np);
+		if (wsa884x->parent_dev) {
+			plat_data = dev_get_platdata(&wsa884x->parent_dev->dev);
+			if (plat_data) {
+				wsa884x->parent_nblock.notifier_call =
+							wsa884x_event_notify;
+				if (plat_data->register_notifier)
+					plat_data->register_notifier(
+						plat_data->handle,
+						&wsa884x->parent_nblock,
+						true);
+				wsa884x->register_notifier =
+						plat_data->register_notifier;
+				wsa884x->handle = plat_data->handle;
+			} else {
+				dev_err(&pdev->dev, "%s: plat data not found\n",
+					__func__);
+			}
+		} else {
+			dev_err(&pdev->dev, "%s: parent dev not found\n",
+				__func__);
+		}
+	} else {
+		dev_info(&pdev->dev, "%s: parent node not found\n", __func__);
+	}
+
+	mutex_init(&wsa884x->res_lock);
+
+#ifdef CONFIG_DEBUG_FS
+	if (!wsa884x->debugfs_dent) {
+		wsa884x->debugfs_dent = debugfs_create_dir(
+					dev_name(&pdev->dev), 0);
+		if (!IS_ERR(wsa884x->debugfs_dent)) {
+			wsa884x->debugfs_peek =
+				debugfs_create_file("swrslave_peek",
+				S_IFREG | 0444,
+				wsa884x->debugfs_dent,
+				(void *) pdev,
+				&codec_debug_read_ops);
+
+		wsa884x->debugfs_poke =
+				debugfs_create_file("swrslave_poke",
+				S_IFREG | 0444,
+				wsa884x->debugfs_dent,
+				(void *) pdev,
+				&codec_debug_write_ops);
+
+		wsa884x->debugfs_reg_dump =
+				debugfs_create_file(
+				"swrslave_reg_dump",
+				S_IFREG | 0444,
+				wsa884x->debugfs_dent,
+				(void *) pdev,
+				&codec_debug_dump_ops);
+	}
+}
+#endif
+
+	return 0;
+
+err_mem:
+	kfree(wsa884x->wsa884x_name_prefix);
+	if (wsa884x->dai_driver) {
+		kfree(wsa884x->dai_driver->name);
+		kfree(wsa884x->dai_driver->playback.stream_name);
+		kfree(wsa884x->dai_driver);
+	}
+	if (wsa884x->driver) {
+		kfree(wsa884x->driver->name);
+		kfree(wsa884x->driver);
+	}
+err_irq:
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_SAF2WAR, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_WAR2SAF, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_DISABLE, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_OCP, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_CLIP, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_PDM_WD, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_CLK_WD, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_INTR_PIN, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_UVLO, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_PA_ON_ERR, NULL);
+	wcd_irq_exit(&wsa884x->irq_info, wsa884x->virq);
+dev_err:
+	if (pin_state_current == false)
+		wsa884x_gpio_ctrl(wsa884x, false);
+	swr_remove_device(pdev);
+err_supply:
+	msm_cdc_release_supplies(&pdev->dev, wsa884x->supplies,
+				 wsa884x->regulator,
+				 wsa884x->num_supplies);
+err:
+	swr_set_dev_data(pdev, NULL);
+	return ret;
+}
+
+static int wsa884x_swr_remove(struct swr_device *pdev)
+{
+	struct wsa884x_priv *wsa884x;
+
+	wsa884x = swr_get_dev_data(pdev);
+	if (!wsa884x) {
+		dev_err(&pdev->dev, "%s: wsa884x is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_SAF2WAR, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_WAR2SAF, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_DISABLE, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_OCP, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_CLIP, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_PDM_WD, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_CLK_WD, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_INTR_PIN, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_UVLO, NULL);
+	wcd_free_irq(&wsa884x->irq_info, WSA884X_IRQ_INT_PA_ON_ERR, NULL);
+
+	if (wsa884x->register_notifier)
+		wsa884x->register_notifier(wsa884x->handle,
+				&wsa884x->parent_nblock, false);
+#ifdef CONFIG_DEBUG_FS
+	debugfs_remove_recursive(wsa884x->debugfs_dent);
+	wsa884x->debugfs_dent = NULL;
+#endif
+	mutex_destroy(&wsa884x->res_lock);
+	snd_soc_unregister_component(&pdev->dev);
+	kfree(wsa884x->wsa884x_name_prefix);
+	if (wsa884x->dai_driver) {
+		kfree(wsa884x->dai_driver->name);
+		kfree(wsa884x->dai_driver->playback.stream_name);
+		kfree(wsa884x->dai_driver);
+	}
+	if (wsa884x->driver) {
+		kfree(wsa884x->driver->name);
+		kfree(wsa884x->driver);
+	}
+	msm_cdc_release_supplies(&pdev->dev, wsa884x->supplies,
+				 wsa884x->regulator,
+				 wsa884x->num_supplies);
+	swr_set_dev_data(pdev, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int wsa884x_swr_suspend(struct device *dev)
+{
+	struct wsa884x_priv *wsa884x = swr_get_dev_data(to_swr_device(dev));
+
+	if (!wsa884x) {
+		dev_err(dev, "%s: wsa884x private data is NULL\n", __func__);
+		return -EINVAL;
+	}
+	dev_dbg(dev, "%s: system suspend\n", __func__);
+	if (wsa884x->dapm_bias_off) {
+		msm_cdc_set_supplies_lpm_mode(dev, wsa884x->supplies,
+					wsa884x->regulator,
+					wsa884x->num_supplies,
+					true);
+		set_bit(WSA_SUPPLIES_LPM_MODE, &wsa884x->status_mask);
+	}
+	return 0;
+}
+
+static int wsa884x_swr_resume(struct device *dev)
+{
+	struct wsa884x_priv *wsa884x = swr_get_dev_data(to_swr_device(dev));
+
+	if (!wsa884x) {
+		dev_err(dev, "%s: wsa884x private data is NULL\n", __func__);
+		return -EINVAL;
+	}
+	if (test_bit(WSA_SUPPLIES_LPM_MODE, &wsa884x->status_mask)) {
+		msm_cdc_set_supplies_lpm_mode(dev, wsa884x->supplies,
+					wsa884x->regulator,
+					wsa884x->num_supplies,
+					false);
+		clear_bit(WSA_SUPPLIES_LPM_MODE, &wsa884x->status_mask);
+	}
+	dev_dbg(dev, "%s: system resume\n", __func__);
+	return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops wsa884x_swr_pm_ops = {
+	.suspend_late = wsa884x_swr_suspend,
+	.resume_early = wsa884x_swr_resume,
+};
+
+static const struct swr_device_id wsa884x_swr_id[] = {
+	{"wsa884x", 0},
+	{"wsa884x_2", 0},
+	{}
+};
+
+static const struct of_device_id wsa884x_swr_dt_match[] = {
+	{
+		.compatible = "qcom,wsa884x",
+	},
+	{
+		.compatible = "qcom,wsa884x_2",
+	},
+	{}
+};
+
+static struct swr_driver wsa884x_swr_driver = {
+	.driver = {
+		.name = "wsa884x",
+		.owner = THIS_MODULE,
+		.pm = &wsa884x_swr_pm_ops,
+		.of_match_table = wsa884x_swr_dt_match,
+	},
+	.probe = wsa884x_swr_probe,
+	.remove = wsa884x_swr_remove,
+	.id_table = wsa884x_swr_id,
+};
+
+static int __init wsa884x_swr_init(void)
+{
+	return swr_driver_register(&wsa884x_swr_driver);
+}
+
+static void __exit wsa884x_swr_exit(void)
+{
+	swr_driver_unregister(&wsa884x_swr_driver);
+}
+
+module_init(wsa884x_swr_init);
+module_exit(wsa884x_swr_exit);
+
+MODULE_DESCRIPTION("WSA884x codec driver");
+MODULE_LICENSE("GPL v2");

+ 49 - 0
asoc/codecs/wsa884x/wsa884x.h

@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _WSA884X_H
+#define _WSA884X_H
+
+#include <linux/regmap.h>
+#include <sound/soc.h>
+#include <sound/info.h>
+#include "wsa884x-registers.h"
+#include "wsa884x-reg-masks.h"
+#include "wsa884x-reg-shifts.h"
+
+
+#define WSA884X_MAX_SWR_PORTS   4
+
+#if IS_ENABLED(CONFIG_SND_SOC_WSA884X)
+int wsa884x_set_channel_map(struct snd_soc_component *component,
+				   u8 *port, u8 num_port, unsigned int *ch_mask,
+				   unsigned int *ch_rate, u8 *port_type);
+
+
+int wsa884x_codec_info_create_codec_entry(
+					struct snd_info_entry *codec_root,
+					struct snd_soc_component *component);
+int wsa884x_codec_get_dev_num(struct snd_soc_component *component);
+#else
+static int wsa884x_set_channel_map(struct snd_soc_component *component,
+				   u8 *port, u8 num_port, unsigned int *ch_mask,
+				   unsigned int *ch_rate, u8 *port_type)
+{
+	return 0;
+}
+
+static int wsa884x_codec_info_create_codec_entry(
+					struct snd_info_entry *codec_root,
+					struct snd_soc_component *component)
+{
+	return 0;
+}
+
+static int wsa884x_codec_get_dev_num(struct snd_soc_component *component)
+{
+	return 0;
+}
+#endif
+
+#endif /* _WSA884X_H */