lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <f1337654-ff69-4489-840a-a1b38efb7f74@oss.qualcomm.com>
Date: Thu, 29 May 2025 11:05:56 +0100
From: Srinivas Kandagatla <srinivas.kandagatla@....qualcomm.com>
To: Alexey Klimov <alexey.klimov@...aro.org>,
        Srinivas Kandagatla <srini@...nel.org>,
        Mark Brown <broonie@...nel.org>, linux-sound@...r.kernel.org
Cc: Liam Girdwood <lgirdwood@...il.com>, Rob Herring <robh@...nel.org>,
        Krzysztof Kozlowski <krzk+dt@...nel.org>,
        Krzysztof Kozlowski <krzysztof.kozlowski@...aro.org>,
        Conor Dooley <conor+dt@...nel.org>,
        Bjorn Andersson <andersson@...nel.org>,
        Dmitry Baryshkov <lumag@...nel.org>,
        Konrad Dybcio <konradybcio@...nel.org>,
        Konrad Dybcio <konrad.dybcio@....qualcomm.com>,
        Jaroslav Kysela <perex@...ex.cz>, Takashi Iwai <tiwai@...e.com>,
        linux-arm-msm@...r.kernel.org, devicetree@...r.kernel.org,
        linux-kernel@...r.kernel.org, linux-gpio@...r.kernel.org
Subject: Re: [PATCH v3 05/12] ASoC: codecs: wsa881x: split into common and
 soundwire drivers



On 5/22/25 6:40 PM, Alexey Klimov wrote:
> This is required in order to introduce wsa881x driver that works
> in analog mode and is configurable via i2c only.
> Functional changes, if any, are kept to be minimal and common
> parts or parts that can be shared are moved into wsa881x-common
> helper driver.
> The regmap config structure now contains 0x3000 offset as required
> by soundwire spec.
> 
> While at this, also fix the typo in WSA881X_ADC_EN_SEL_IBIAS
> register name and rename wsa881x_set_sdw_stream() to
> wsa881x_set_stream() and update registers description in the
> header and use the new defines in wsa881x_init_common() and
> in wsa881x_digital_mute().
> 
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski@...aro.org>
> Cc: Srinivas Kandagatla <srini@...nel.org>
> Signed-off-by: Alexey Klimov <alexey.klimov@...aro.org>
> ---
>  sound/soc/codecs/Kconfig          |   4 +
>  sound/soc/codecs/Makefile         |   2 +
>  sound/soc/codecs/wsa881x-common.c | 193 +++++++++++++++
>  sound/soc/codecs/wsa881x-common.h | 458 +++++++++++++++++++++++++++++++++++
>  sound/soc/codecs/wsa881x.c        | 493 +-------------------------------------

How about we have something like wsa881x.c wsa881x-sdw.c wsa881x-i2c.c ?


>  5 files changed, 669 insertions(+), 481 deletions(-)
> 
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index 8fe795504dbb5c91881e9de10f676c9d151b42d3..ba6e4504b5e9951203bd61fae894e86e9d40048e 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -2543,10 +2543,14 @@ config SND_SOC_WM9713
>  	select REGMAP_AC97
>  	select AC97_BUS_COMPAT if AC97_BUS_NEW
>  
> +config SND_SOC_WSA881X_COMMON
> +	tristate
> +
>  config SND_SOC_WSA881X
>  	tristate "WSA881X Codec"
>  	depends on SOUNDWIRE
>  	select REGMAP_SOUNDWIRE
> +	select SND_SOC_WSA881X_COMMON
>  	help
>  	  This enables support for Qualcomm WSA8810/WSA8815 Class-D
>  	  Smart Speaker Amplifier.
> diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
> index c92824713df0690998b76d43fcbe7c6e93dd5dd2..212d419cfe3c0fbd5d4e475e5d81c69ef930b3e1 100644
> --- a/sound/soc/codecs/Makefile
> +++ b/sound/soc/codecs/Makefile
> @@ -406,6 +406,7 @@ snd-soc-wm9712-y := wm9712.o
>  snd-soc-wm9713-y := wm9713.o
>  snd-soc-wm-hubs-y := wm_hubs.o
>  snd-soc-wsa881x-y := wsa881x.o
> +snd-soc-wsa881x-common-y := wsa881x-common.o
>  snd-soc-wsa883x-y := wsa883x.o
>  snd-soc-wsa884x-y := wsa884x.o
>  snd-soc-zl38060-y := zl38060.o
> @@ -835,6 +836,7 @@ obj-$(CONFIG_SND_SOC_WM9713)	+= snd-soc-wm9713.o
>  obj-$(CONFIG_SND_SOC_WM_ADSP)	+= snd-soc-wm-adsp.o
>  obj-$(CONFIG_SND_SOC_WM_HUBS)	+= snd-soc-wm-hubs.o
>  obj-$(CONFIG_SND_SOC_WSA881X)	+= snd-soc-wsa881x.o
> +obj-$(CONFIG_SND_SOC_WSA881X_COMMON)	+= snd-soc-wsa881x-common.o
>  obj-$(CONFIG_SND_SOC_WSA883X)	+= snd-soc-wsa883x.o
>  obj-$(CONFIG_SND_SOC_WSA884X)	+= snd-soc-wsa884x.o
>  obj-$(CONFIG_SND_SOC_ZL38060)	+= snd-soc-zl38060.o
> diff --git a/sound/soc/codecs/wsa881x-common.c b/sound/soc/codecs/wsa881x-common.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..fbc431bd059544505647688db0d09e407589e330
> --- /dev/null
> +++ b/sound/soc/codecs/wsa881x-common.c
> @@ -0,0 +1,193 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2024 Linaro Ltd
> + */
> +
> +#include <linux/gpio/consumer.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <sound/soc.h>
> +
> +#include "wsa881x-common.h"
> +
> +int wsa881x_set_stream(struct snd_soc_dai *dai, void *stream, int direction)
> +{
> +#if IS_ENABLED(CONFIG_SND_SOC_WSA881X)
> +	struct wsa881x_priv *wsa881x = dev_get_drvdata(dai->dev);
> +
> +	wsa881x->sruntime = stream;
> +#endif
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(wsa881x_set_stream);
> +
> +int wsa881x_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
> +{
> +	struct snd_soc_component *component = dai->component;
> +
> +	return snd_soc_component_update_bits(component,
> +					     WSA881X_SPKR_DRV_EN,
> +					     WSA881X_SPKR_DRV_EN_CLASS_PA_MASK,
> +					     mute ?
> +					     WSA881X_SPKR_DRV_EN_CLASS_PA_DIS :
> +					     WSA881X_SPKR_DRV_EN_CLASS_PA_EN);
> +}
> +EXPORT_SYMBOL_GPL(wsa881x_digital_mute);
> +
> +void wsa881x_init_common(struct wsa881x_priv *wsa881x)
> +{
> +	struct regmap *rm = wsa881x->regmap;
> +	unsigned int val = 0;
> +
> +	/* Bring out of analog reset */
> +	regmap_update_bits(rm, WSA881X_CDC_RST_CTL,
> +			   WSA881X_CDC_RST_CTL_ANA_RST,
> +			   WSA881X_CDC_RST_CTL_ANA_RST);
> +
> +	/* Bring out of digital reset */
> +	regmap_update_bits(rm, WSA881X_CDC_RST_CTL,
> +			   WSA881X_CDC_RST_CTL_DIG_RST,
> +			   WSA881X_CDC_RST_CTL_DIG_RST);
> +	regmap_update_bits(rm, WSA881X_CLOCK_CONFIG,
> +			   WSA881X_CLOCK_SCLK_SDM_DEM_DIV2_EN,
> +			   WSA881X_CLOCK_SCLK_SDM_DEM_DIV2_EN);
> +	regmap_update_bits(rm, WSA881X_SPKR_OCP_CTL,
> +			   WSA881X_SPKR_OCP_CTL_RDAC_CLK_DIV2_MASK,
> +			   FIELD_PREP(WSA881X_SPKR_OCP_CTL_RDAC_CLK_DIV2_MASK,
> +				      WSA881X_SPKR_OCP_CTL_RDAC_CLK_DIV2));
> +	regmap_update_bits(rm, WSA881X_SPKR_MISC_CTL1,
> +			   WSA881X_SPKR_MISC_CTL1_DTIME_MASK,
> +			   FIELD_PREP(WSA881X_SPKR_MISC_CTL1_DTIME_MASK,
> +				      WSA881X_SPKR_MISC_CTL1_40NS));
> +	regmap_update_bits(rm, WSA881X_SPKR_MISC_CTL1,
> +			   WSA881X_SPKR_MISC_CTL1_SLEW_RATE_MASK,
> +			   FIELD_PREP(WSA881X_SPKR_MISC_CTL1_SLEW_RATE_MASK,
> +				      WSA881X_SPKR_MISC_CTL1_60NS));
> +	regmap_update_bits(rm, WSA881X_SPKR_BIAS_INT,
> +			   WSA881X_SPKR_BIAS_INT_FULL_MASK,
> +			   0x0);
> +	regmap_update_bits(rm, WSA881X_SPKR_PA_INT,
> +			   WSA881X_SPKR_PA_INT_COMP_CURR_MASK,
> +			   FIELD_PREP(WSA881X_SPKR_PA_INT_COMP_CURR_MASK,
> +				      WSA881X_SPKR_PA_INT_COMP_CURR_2UA0));
> +	regmap_update_bits(rm, WSA881X_SPKR_PA_INT,
> +			   WSA881X_SPKR_PA_INT_LDO_CURR_MASK,
> +			   FIELD_PREP(WSA881X_SPKR_PA_INT_LDO_CURR_MASK,
> +				      WSA881X_SPKR_PA_INT_LDO_CURR_5UA0));
> +	regmap_update_bits(rm, WSA881X_BOOST_LOOP_STABILITY,
> +			   WSA881X_BOOST_LOOP_STAB_COMP_RES_MASK,
> +			   FIELD_PREP(WSA881X_BOOST_LOOP_STAB_COMP_RES_MASK,
> +				      WSA881X_BOOST_LOOP_STAB_COMP_RES_400K));
> +	regmap_update_bits(rm, WSA881X_BOOST_MISC2_CTL,
> +			   WSA881X_BOOST_MISC2_CTL_FULL_MASK,
> +			   WSA881X_BOOST_MISC2_CTL_RST);
> +	regmap_update_bits(rm, WSA881X_BOOST_START_CTL,
> +			   WSA881X_BOOST_START_CTL_FAST_TRAN_MASK,
> +			   WSA881X_BOOST_START_CTL_FAST_TRAN_EN);
> +	regmap_update_bits(rm, WSA881X_BOOST_START_CTL,
> +			   WSA881X_BOOST_START_CTL_PULSE_SKIP_MASK,
> +			   FIELD_PREP(WSA881X_BOOST_START_CTL_PULSE_SKIP_MASK,
> +				      WSA881X_BOOST_START_CTL_PULSE_SKIP_50MA));
> +	regmap_update_bits(rm, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB,
> +			   WSA881X_BOOST_SLOPE_ERR_CURR_MASK,
> +			   FIELD_PREP(WSA881X_BOOST_SLOPE_ERR_CURR_MASK,
> +				      WSA881X_BOOST_SLOPE_ERR_CURR_11UA));
> +	regmap_update_bits(rm, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB,
> +			   WSA881X_BOOST_SLOPE_ISENSE_FB_MASK,
> +			   FIELD_PREP(WSA881X_BOOST_SLOPE_ISENSE_FB_MASK,
> +				      WSA881X_BOOST_SLOPE_ISENSE_FB_03));
> +
> +	regmap_read(rm, WSA881X_OTP_REG_0, &val);
> +	if (val)
> +		regmap_update_bits(rm,
> +			WSA881X_BOOST_PRESET_OUT1,
> +			WSA881X_BOOST_PRESET_OUT1_1ST_LVL_MASK,
> +			FIELD_PREP(WSA881X_BOOST_PRESET_OUT1_1ST_LVL_MASK,
> +				   WSA881X_BOOST_PRESET_OUT1_5V5));
> +
> +	regmap_update_bits(rm, WSA881X_BOOST_PRESET_OUT2,
> +			   WSA881X_BOOST_PRESET_OUT2_3RD_LVL_MASK,
> +			   FIELD_PREP(WSA881X_BOOST_PRESET_OUT2_3RD_LVL_MASK,
> +				      WSA881X_BOOST_PRESET_OUT2_9V));
> +	regmap_update_bits(rm, WSA881X_SPKR_DRV_EN,
> +			   WSA881X_SPKR_DRV_EN_INT_LDO_VOUT_MASK,
> +			   FIELD_PREP(WSA881X_SPKR_DRV_EN_INT_LDO_VOUT_MASK,
> +				      WSA881X_SPKR_DRV_EN_INT_LDO_VOUT_5V5));
> +	regmap_update_bits(rm, WSA881X_BOOST_CURRENT_LIMIT,
> +			   WSA881X_BOOST_CURRENT_LIMIT_SET_MASK,
> +			   FIELD_PREP(WSA881X_BOOST_CURRENT_LIMIT_SET_MASK,
> +				      WSA881X_BOOST_CURRENT_LIMIT_SET_4A));
> +	regmap_update_bits(rm, WSA881X_SPKR_OCP_CTL,
> +			   WSA881X_SPKR_OCP_CTL_CURR_LIMIT_MASK,
> +			   FIELD_PREP(WSA881X_SPKR_OCP_CTL_CURR_LIMIT_MASK,
> +				      WSA881X_SPKR_OCP_CTL_CURR_LIMIT_5A));
> +	regmap_update_bits(rm, WSA881X_SPKR_OCP_CTL,
> +			   WSA881X_SPKR_OCP_CTL_GLITCH_FLT_MASK,
> +			   FIELD_PREP(WSA881X_SPKR_OCP_CTL_GLITCH_FLT_MASK,
> +				      WSA881X_SPKR_OCP_CTL_GLITCH_FLT_128NS));
> +	regmap_update_bits(rm, WSA881X_OTP_REG_28,
> +			   WSA881X_OTP_REG_28_ISENSE_CAL_MASK,
> +			   FIELD_PREP(WSA881X_OTP_REG_28_ISENSE_CAL_MASK,
> +				      WSA881X_OTP_REG_28_ISENSE_CAL_RST_VAL));
> +	regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1,
> +			   WSA881X_BONGO_RESRV_REG1_TEMP_CMP_MASK,
> +			   WSA881X_BONGO_RESRV_REG1_TEMP_CMP_EN);
> +	regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1,
> +			   WSA881X_BONGO_RESRV_REG1_ISENSE_MASK,
> +			   FIELD_PREP(WSA881X_BONGO_RESRV_REG1_ISENSE_MASK,
> +				      WSA881X_BONGO_RESRV_REG1_ISENSE_RST_VAL));
> +	regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1,
> +			   WSA881X_BONGO_RESRV_REG1_ATEST_MASK,
> +			   WSA881X_BONGO_RESRV_REG1_ATEST_DIS);
> +	regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG2,
> +			   WSA881X_BONGO_RESRV_REG2_FULL_MASK,
> +			   WSA881X_BONGO_RESRV_REG2_RST_VAL);
> +}
> +EXPORT_SYMBOL_GPL(wsa881x_init_common);
> +
> +int wsa881x_probe_common(struct wsa881x_priv **wsa881x, struct device *dev)
> +{
> +	struct wsa881x_priv *wsa;
> +
> +	wsa = devm_kzalloc(dev, sizeof(*wsa), GFP_KERNEL);
> +	if (!wsa)
> +		return -ENOMEM;
> +
> +	wsa->dev = dev;
> +	wsa->sd_n = devm_gpiod_get_optional(dev, "powerdown",
> +					    GPIOD_FLAGS_BIT_NONEXCLUSIVE);
> +	if (IS_ERR(wsa->sd_n))
> +		return dev_err_probe(dev, PTR_ERR(wsa->sd_n),
> +				     "Shutdown Control GPIO not found\n");
> +	/*
> +	 * Backwards compatibility work-around.
> +	 *
> +	 * The SD_N GPIO is active low, however upstream DTS used always active
> +	 * high.  Changing the flag in driver and DTS will break backwards
> +	 * compatibility, so add a simple value inversion to work with both old
> +	 * and new DTS.
> +	 *
> +	 * This won't work properly with DTS using the flags properly in cases:
> +	 * 1. Old DTS with proper ACTIVE_LOW, however such case was broken
> +	 *    before as the driver required the active high.
> +	 * 2. New DTS with proper ACTIVE_HIGH (intended), which is rare case
> +	 *    (not existing upstream) but possible. This is the price of
> +	 *    backwards compatibility, therefore this hack should be removed at
> +	 *    some point.
> +	 */
> +	wsa->sd_n_val = gpiod_is_active_low(wsa->sd_n);
> +	if (!wsa->sd_n_val)
> +		dev_warn(dev,
> +			 "Using ACTIVE_HIGH for shutdown GPIO. Your DTB might be outdated or you use unsupported configuration for the GPIO.\n");
> +
> +	dev_set_drvdata(dev, wsa);
> +	gpiod_direction_output(wsa->sd_n, !wsa->sd_n_val);
> +
> +	*wsa881x = wsa;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(wsa881x_probe_common);
> +
> +MODULE_DESCRIPTION("WSA881x codec helper driver");
> +MODULE_LICENSE("GPL");
> diff --git a/sound/soc/codecs/wsa881x-common.h b/sound/soc/codecs/wsa881x-common.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..ab4ee5848b10fe6ca4160b7ff634e7e06b6e41e6
> --- /dev/null
> +++ b/sound/soc/codecs/wsa881x-common.h
> @@ -0,0 +1,458 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __WSA881x_COMMON_H__
> +#define __WSA881x_COMMON_H__
> +
> +#include <linux/soundwire/sdw.h>
> +#include <sound/soc.h>
> +
> +#define WSA881X_MAX_SWR_PORTS	4
> +
> +#define WSA881X_DIGITAL_BASE	0x0000
> +#define WSA881X_ANALOG_BASE	0x0100
> +
> +/* Digital register address space */
> +#define WSA881X_CHIP_ID0			(WSA881X_DIGITAL_BASE + 0x0000)
> +#define WSA881X_CHIP_ID1			(WSA881X_DIGITAL_BASE + 0x0001)
> +#define WSA881X_CHIP_ID2			(WSA881X_DIGITAL_BASE + 0x0002)
> +#define WSA881X_CHIP_ID3			(WSA881X_DIGITAL_BASE + 0x0003)
> +#define WSA881X_BUS_ID				(WSA881X_DIGITAL_BASE + 0x0004)
> +#define WSA881X_CDC_RST_CTL			(WSA881X_DIGITAL_BASE + 0x0005)
> +#define WSA881X_CDC_RST_CTL_ANA_RST		BIT(1)
> +#define WSA881X_CDC_RST_CTL_DIG_RST		BIT(0)
> +#define WSA881X_CDC_TOP_CLK_CTL			(WSA881X_DIGITAL_BASE + 0x0006)
> +#define WSA881X_CDC_ANA_CLK_CTL			(WSA881X_DIGITAL_BASE + 0x0007)
> +#define WSA881X_CDC_DIG_CLK_CTL			(WSA881X_DIGITAL_BASE + 0x0008)
> +#define WSA881X_CLOCK_CONFIG			(WSA881X_DIGITAL_BASE + 0x0009)
> +#define WSA881X_CLOCK_SCLK_SDM_DEM_DIV2_EN	BIT(4)
> +#define WSA881X_ANA_CTL				(WSA881X_DIGITAL_BASE + 0x000A)
> +#define WSA881X_SWR_RESET_EN			(WSA881X_DIGITAL_BASE + 0x000B)
> +#define WSA881X_RESET_CTL			(WSA881X_DIGITAL_BASE + 0x000C)
> +#define WSA881X_TADC_VALUE_CTL			(WSA881X_DIGITAL_BASE + 0x000F)
> +#define WSA881X_TEMP_DETECT_CTL			(WSA881X_DIGITAL_BASE + 0x0010)
> +#define WSA881X_TEMP_MSB			(WSA881X_DIGITAL_BASE + 0x0011)
> +#define WSA881X_TEMP_LSB			(WSA881X_DIGITAL_BASE + 0x0012)
> +#define WSA881X_TEMP_CONFIG0			(WSA881X_DIGITAL_BASE + 0x0013)
> +#define WSA881X_TEMP_CONFIG1			(WSA881X_DIGITAL_BASE + 0x0014)
> +#define WSA881X_CDC_CLIP_CTL			(WSA881X_DIGITAL_BASE + 0x0015)
> +#define WSA881X_SDM_PDM9_LSB			(WSA881X_DIGITAL_BASE + 0x0016)
> +#define WSA881X_SDM_PDM9_MSB			(WSA881X_DIGITAL_BASE + 0x0017)
> +#define WSA881X_CDC_RX_CTL			(WSA881X_DIGITAL_BASE + 0x0018)
> +#define WSA881X_DEM_BYPASS_DATA0		(WSA881X_DIGITAL_BASE + 0x0019)
> +#define WSA881X_DEM_BYPASS_DATA1		(WSA881X_DIGITAL_BASE + 0x001A)
> +#define WSA881X_DEM_BYPASS_DATA2		(WSA881X_DIGITAL_BASE + 0x001B)
> +#define WSA881X_DEM_BYPASS_DATA3		(WSA881X_DIGITAL_BASE + 0x001C)
> +#define WSA881X_OTP_CTRL0			(WSA881X_DIGITAL_BASE + 0x001D)
> +#define WSA881X_OTP_CTRL1			(WSA881X_DIGITAL_BASE + 0x001E)
> +#define WSA881X_HDRIVE_CTL_GROUP1		(WSA881X_DIGITAL_BASE + 0x001F)
> +#define WSA881X_INTR_MODE			(WSA881X_DIGITAL_BASE + 0x0020)
> +#define WSA881X_INTR_MASK			(WSA881X_DIGITAL_BASE + 0x0021)
> +#define WSA881X_INTR_STATUS			(WSA881X_DIGITAL_BASE + 0x0022)
> +#define WSA881X_INTR_CLEAR			(WSA881X_DIGITAL_BASE + 0x0023)
> +#define WSA881X_INTR_LEVEL			(WSA881X_DIGITAL_BASE + 0x0024)
> +#define WSA881X_INTR_SET			(WSA881X_DIGITAL_BASE + 0x0025)
> +#define WSA881X_INTR_TEST			(WSA881X_DIGITAL_BASE + 0x0026)
> +#define WSA881X_PDM_TEST_MODE			(WSA881X_DIGITAL_BASE + 0x0030)
> +#define WSA881X_ATE_TEST_MODE			(WSA881X_DIGITAL_BASE + 0x0031)
> +#define WSA881X_PIN_CTL_MODE			(WSA881X_DIGITAL_BASE + 0x0032)
> +#define WSA881X_PIN_CTL_OE			(WSA881X_DIGITAL_BASE + 0x0033)
> +#define WSA881X_PIN_WDATA_IOPAD			(WSA881X_DIGITAL_BASE + 0x0034)
> +#define WSA881X_PIN_STATUS			(WSA881X_DIGITAL_BASE + 0x0035)
> +#define WSA881X_DIG_DEBUG_MODE			(WSA881X_DIGITAL_BASE + 0x0037)
> +#define WSA881X_DIG_DEBUG_SEL			(WSA881X_DIGITAL_BASE + 0x0038)
> +#define WSA881X_DIG_DEBUG_EN			(WSA881X_DIGITAL_BASE + 0x0039)
> +#define WSA881X_SWR_HM_TEST1			(WSA881X_DIGITAL_BASE + 0x003B)
> +#define WSA881X_SWR_HM_TEST2			(WSA881X_DIGITAL_BASE + 0x003C)
> +#define WSA881X_TEMP_DETECT_DBG_CTL		(WSA881X_DIGITAL_BASE + 0x003D)
> +#define WSA881X_TEMP_DEBUG_MSB			(WSA881X_DIGITAL_BASE + 0x003E)
> +#define WSA881X_TEMP_DEBUG_LSB			(WSA881X_DIGITAL_BASE + 0x003F)
> +#define WSA881X_SAMPLE_EDGE_SEL			(WSA881X_DIGITAL_BASE + 0x0044)
> +#define WSA881X_IOPAD_CTL			(WSA881X_DIGITAL_BASE + 0x0045)
> +#define WSA881X_SPARE_0				(WSA881X_DIGITAL_BASE + 0x0050)
> +#define WSA881X_SPARE_1				(WSA881X_DIGITAL_BASE + 0x0051)
> +#define WSA881X_SPARE_2				(WSA881X_DIGITAL_BASE + 0x0052)
> +#define WSA881X_OTP_REG_0			(WSA881X_DIGITAL_BASE + 0x0080)
> +#define WSA881X_OTP_REG_1			(WSA881X_DIGITAL_BASE + 0x0081)
> +#define WSA881X_OTP_REG_2			(WSA881X_DIGITAL_BASE + 0x0082)
> +#define WSA881X_OTP_REG_3			(WSA881X_DIGITAL_BASE + 0x0083)
> +#define WSA881X_OTP_REG_4			(WSA881X_DIGITAL_BASE + 0x0084)
> +#define WSA881X_OTP_REG_5			(WSA881X_DIGITAL_BASE + 0x0085)
> +#define WSA881X_OTP_REG_6			(WSA881X_DIGITAL_BASE + 0x0086)
> +#define WSA881X_OTP_REG_7			(WSA881X_DIGITAL_BASE + 0x0087)
> +#define WSA881X_OTP_REG_8			(WSA881X_DIGITAL_BASE + 0x0088)
> +#define WSA881X_OTP_REG_9			(WSA881X_DIGITAL_BASE + 0x0089)
> +#define WSA881X_OTP_REG_10			(WSA881X_DIGITAL_BASE + 0x008A)
> +#define WSA881X_OTP_REG_11			(WSA881X_DIGITAL_BASE + 0x008B)
> +#define WSA881X_OTP_REG_12			(WSA881X_DIGITAL_BASE + 0x008C)
> +#define WSA881X_OTP_REG_13			(WSA881X_DIGITAL_BASE + 0x008D)
> +#define WSA881X_OTP_REG_14			(WSA881X_DIGITAL_BASE + 0x008E)
> +#define WSA881X_OTP_REG_15			(WSA881X_DIGITAL_BASE + 0x008F)
> +#define WSA881X_OTP_REG_16			(WSA881X_DIGITAL_BASE + 0x0090)
> +#define WSA881X_OTP_REG_17			(WSA881X_DIGITAL_BASE + 0x0091)
> +#define WSA881X_OTP_REG_18			(WSA881X_DIGITAL_BASE + 0x0092)
> +#define WSA881X_OTP_REG_19			(WSA881X_DIGITAL_BASE + 0x0093)
> +#define WSA881X_OTP_REG_20			(WSA881X_DIGITAL_BASE + 0x0094)
> +#define WSA881X_OTP_REG_21			(WSA881X_DIGITAL_BASE + 0x0095)
> +#define WSA881X_OTP_REG_22			(WSA881X_DIGITAL_BASE + 0x0096)
> +#define WSA881X_OTP_REG_23			(WSA881X_DIGITAL_BASE + 0x0097)
> +#define WSA881X_OTP_REG_24			(WSA881X_DIGITAL_BASE + 0x0098)
> +#define WSA881X_OTP_REG_25			(WSA881X_DIGITAL_BASE + 0x0099)
> +#define WSA881X_OTP_REG_26			(WSA881X_DIGITAL_BASE + 0x009A)
> +#define WSA881X_OTP_REG_27			(WSA881X_DIGITAL_BASE + 0x009B)
> +#define WSA881X_OTP_REG_28			(WSA881X_DIGITAL_BASE + 0x009C)
> +#define WSA881X_OTP_REG_28_ISENSE_CAL_MASK	GENMASK(5, 0)
> +#define WSA881X_OTP_REG_28_ISENSE_CAL_RST_VAL	(0x3A)
> +#define WSA881X_OTP_REG_29			(WSA881X_DIGITAL_BASE + 0x009D)
> +#define WSA881X_OTP_REG_30			(WSA881X_DIGITAL_BASE + 0x009E)
> +#define WSA881X_OTP_REG_31			(WSA881X_DIGITAL_BASE + 0x009F)
> +#define WSA881X_OTP_REG_63			(WSA881X_DIGITAL_BASE + 0x00BF)
> +
> +/* Analog Register address space */
> +#define WSA881X_BIAS_REF_CTRL			(WSA881X_ANALOG_BASE + 0x0000)
> +#define WSA881X_BIAS_TEST			(WSA881X_ANALOG_BASE + 0x0001)
> +#define WSA881X_BIAS_BIAS			(WSA881X_ANALOG_BASE + 0x0002)
> +#define WSA881X_TEMP_OP				(WSA881X_ANALOG_BASE + 0x0003)
> +#define WSA881X_TEMP_IREF_CTRL			(WSA881X_ANALOG_BASE + 0x0004)
> +#define WSA881X_TEMP_ISENS_CTRL			(WSA881X_ANALOG_BASE + 0x0005)
> +#define WSA881X_TEMP_CLK_CTRL			(WSA881X_ANALOG_BASE + 0x0006)
> +#define WSA881X_TEMP_TEST			(WSA881X_ANALOG_BASE + 0x0007)
> +#define WSA881X_TEMP_BIAS			(WSA881X_ANALOG_BASE + 0x0008)
> +#define WSA881X_TEMP_ADC_CTRL			(WSA881X_ANALOG_BASE + 0x0009)
> +#define WSA881X_TEMP_DOUT_MSB			(WSA881X_ANALOG_BASE + 0x000A)
> +#define WSA881X_TEMP_DOUT_LSB			(WSA881X_ANALOG_BASE + 0x000B)
> +#define WSA881X_ADC_EN_MODU_V			(WSA881X_ANALOG_BASE + 0x0010)
> +#define WSA881X_ADC_EN_MODU_I			(WSA881X_ANALOG_BASE + 0x0011)
> +#define WSA881X_ADC_EN_DET_TEST_V		(WSA881X_ANALOG_BASE + 0x0012)
> +#define WSA881X_ADC_EN_DET_TEST_I		(WSA881X_ANALOG_BASE + 0x0013)
> +#define WSA881X_ADC_SEL_IBIAS			(WSA881X_ANALOG_BASE + 0x0014)
> +#define WSA881X_ADC_EN_SEL_IBIAS		(WSA881X_ANALOG_BASE + 0x0015)
> +#define WSA881X_SPKR_DRV_EN			(WSA881X_ANALOG_BASE + 0x001A)
> +#define WSA881X_SPKR_DRV_EN_CLASS_PA_MASK	BIT(7)
> +#define WSA881X_SPKR_DRV_EN_CLASS_PA_DIS	0
> +#define WSA881X_SPKR_DRV_EN_CLASS_PA_EN		BIT(7)
> +#define WSA881X_SPKR_DRV_EN_INT_LDO_VOUT_MASK	BIT(3)
> +#define WSA881X_SPKR_DRV_EN_INT_LDO_VOUT_5V	0
> +#define WSA881X_SPKR_DRV_EN_INT_LDO_VOUT_5V5	1
> +#define WSA881X_SPKR_DRV_GAIN			(WSA881X_ANALOG_BASE + 0x001B)
> +#define WSA881X_PA_GAIN_SEL_MASK		BIT(3)
> +#define WSA881X_PA_GAIN_SEL_REG			BIT(3)
> +#define WSA881X_PA_GAIN_SEL_DRE			0
> +#define WSA881X_SPKR_PAG_GAIN_MASK		GENMASK(7, 4)
> +#define WSA881X_SPKR_DAC_CTL			(WSA881X_ANALOG_BASE + 0x001C)
> +#define WSA881X_SPKR_DRV_DBG			(WSA881X_ANALOG_BASE + 0x001D)
> +#define WSA881X_SPKR_PWRSTG_DBG			(WSA881X_ANALOG_BASE + 0x001E)
> +#define WSA881X_SPKR_OCP_CTL			(WSA881X_ANALOG_BASE + 0x001F)
> +#define WSA881X_SPKR_OCP_MASK			GENMASK(7, 6)
> +#define WSA881X_SPKR_OCP_CTL_CURR_LIMIT_MASK	GENMASK(5, 4)
> +#define WSA881X_SPKR_OCP_CTL_GLITCH_FLT_MASK	GENMASK(3, 2)
> +#define WSA881X_SPKR_OCP_CTL_CURR_LIMIT_5A	(BIT(1) | BIT(0))
> +#define WSA881X_SPKR_OCP_CTL_GLITCH_FLT_128NS	0
> +#define WSA881X_SPKR_OCP_CTL_RDAC_CLK_DIV2_MASK	BIT(1)
> +#define WSA881X_SPKR_OCP_CTL_RDAC_CLK_DIV2	1
> +#define WSA881X_SPKR_OCP_EN			BIT(7)
> +#define WSA881X_SPKR_OCP_HOLD			BIT(6)
> +#define WSA881X_SPKR_CLIP_CTL			(WSA881X_ANALOG_BASE + 0x0020)
> +#define WSA881X_SPKR_BBM_CTL			(WSA881X_ANALOG_BASE + 0x0021)
> +#define WSA881X_SPKR_MISC_CTL1			(WSA881X_ANALOG_BASE + 0x0022)
> +#define WSA881X_SPKR_MISC_CTL1_DTIME_MASK	GENMASK(7, 6)
> +#define WSA881X_SPKR_MISC_CTL1_SLEW_RATE_MASK	GENMASK(2, 1)
> +#define WSA881X_SPKR_MISC_CTL1_60NS		(BIT(1) | BIT(0))
> +#define WSA881X_SPKR_MISC_CTL1_40NS		BIT(1)
> +#define WSA881X_SPKR_MISC_CTL2			(WSA881X_ANALOG_BASE + 0x0023)
> +#define WSA881X_SPKR_BIAS_INT			(WSA881X_ANALOG_BASE + 0x0024)
> +#define WSA881X_SPKR_BIAS_INT_FULL_MASK		((u8)~0U)
> +#define WSA881X_SPKR_PA_INT			(WSA881X_ANALOG_BASE + 0x0025)
> +#define WSA881X_SPKR_PA_INT_COMP_CURR_MASK	GENMASK(7, 4)
> +#define WSA881X_SPKR_PA_INT_LDO_CURR_MASK	GENMASK(3, 1)
> +#define WSA881X_SPKR_PA_INT_COMP_CURR_2UA0	BIT(2)
> +#define WSA881X_SPKR_PA_INT_LDO_CURR_5UA0	(BIT(2) | BIT(1) | BIT(0))
> +#define WSA881X_SPKR_BIAS_CAL			(WSA881X_ANALOG_BASE + 0x0026)
> +#define WSA881X_SPKR_BIAS_PSRR			(WSA881X_ANALOG_BASE + 0x0027)
> +#define WSA881X_SPKR_STATUS1			(WSA881X_ANALOG_BASE + 0x0028)
> +#define WSA881X_SPKR_STATUS2			(WSA881X_ANALOG_BASE + 0x0029)
> +#define WSA881X_BOOST_EN_CTL			(WSA881X_ANALOG_BASE + 0x002A)
> +#define WSA881X_BOOST_EN_MASK			BIT(7)
> +#define WSA881X_BOOST_EN			BIT(7)
> +#define WSA881X_BOOST_CURRENT_LIMIT		(WSA881X_ANALOG_BASE + 0x002B)
> +#define WSA881X_BOOST_CURRENT_LIMIT_SET_MASK	GENMASK(3, 0)
> +#define WSA881X_BOOST_CURRENT_LIMIT_SET_4A	BIT(3)
> +#define WSA881X_BOOST_PS_CTL			(WSA881X_ANALOG_BASE + 0x002C)
> +#define WSA881X_BOOST_PRESET_OUT1		(WSA881X_ANALOG_BASE + 0x002D)
> +#define WSA881X_BOOST_PRESET_OUT1_1ST_LVL_MASK	GENMASK(7, 4)
> +#define WSA881X_BOOST_PRESET_OUT1_5V5		(BIT(2) | BIT(1) | BIT(0))
> +#define WSA881X_BOOST_PRESET_OUT2		(WSA881X_ANALOG_BASE + 0x002E)
> +#define WSA881X_BOOST_PRESET_OUT2_3RD_LVL_MASK	GENMASK(7, 4)
> +#define WSA881X_BOOST_PRESET_OUT2_9V		(BIT(1) | BIT(0))
> +#define WSA881X_BOOST_FORCE_OUT			(WSA881X_ANALOG_BASE + 0x002F)
> +#define WSA881X_BOOST_LDO_PROG			(WSA881X_ANALOG_BASE + 0x0030)
> +#define WSA881X_BOOST_SLOPE_COMP_ISENSE_FB	(WSA881X_ANALOG_BASE + 0x0031)
> +#define WSA881X_BOOST_SLOPE_ERR_CURR_MASK	GENMASK(3, 2)
> +#define WSA881X_BOOST_SLOPE_ISENSE_FB_MASK	GENMASK(1, 0)
> +#define WSA881X_BOOST_SLOPE_ERR_CURR_11UA	BIT(0)
> +#define WSA881X_BOOST_SLOPE_ISENSE_FB_03	0
> +#define WSA881X_BOOST_RON_CTL			(WSA881X_ANALOG_BASE + 0x0032)
> +#define WSA881X_BOOST_LOOP_STABILITY		(WSA881X_ANALOG_BASE + 0x0033)
> +#define WSA881X_BOOST_LOOP_STAB_COMP_RES_MASK	GENMASK(1, 0)
> +#define WSA881X_BOOST_LOOP_STAB_COMP_RES_400K	(BIT(1) | BIT(0))
> +#define WSA881X_BOOST_ZX_CTL			(WSA881X_ANALOG_BASE + 0x0034)
> +#define WSA881X_BOOST_START_CTL			(WSA881X_ANALOG_BASE + 0x0035)
> +#define WSA881X_BOOST_START_CTL_FAST_TRAN_MASK	BIT(7)
> +#define WSA881X_BOOST_START_CTL_PULSE_SKIP_MASK	GENMASK(1, 0)
> +#define WSA881X_BOOST_START_CTL_FAST_TRAN_EN	BIT(7)
> +#define WSA881X_BOOST_START_CTL_PULSE_SKIP_50MA	0
> +#define WSA881X_BOOST_MISC1_CTL			(WSA881X_ANALOG_BASE + 0x0036)
> +#define WSA881X_BOOST_MISC2_CTL			(WSA881X_ANALOG_BASE + 0x0037)
> +#define WSA881X_BOOST_MISC2_CTL_FULL_MASK	((u8)~0U)
> +#define WSA881X_BOOST_MISC2_CTL_RST		(BIT(4) | BIT(2))
> +#define WSA881X_BOOST_MISC3_CTL			(WSA881X_ANALOG_BASE + 0x0038)
> +#define WSA881X_BOOST_ATEST_CTL			(WSA881X_ANALOG_BASE + 0x0039)
> +#define WSA881X_SPKR_PROT_FE_GAIN		(WSA881X_ANALOG_BASE + 0x003A)
> +#define WSA881X_SPKR_PROT_FE_CM_LDO_SET		(WSA881X_ANALOG_BASE + 0x003B)
> +#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1	(WSA881X_ANALOG_BASE + 0x003C)
> +#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2	(WSA881X_ANALOG_BASE + 0x003D)
> +#define WSA881X_SPKR_PROT_ATEST1		(WSA881X_ANALOG_BASE + 0x003E)
> +#define WSA881X_SPKR_PROT_ATEST2		(WSA881X_ANALOG_BASE + 0x003F)
> +#define WSA881X_SPKR_PROT_FE_VSENSE_VCM		(WSA881X_ANALOG_BASE + 0x0040)
> +#define WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1	(WSA881X_ANALOG_BASE + 0x0041)
> +#define WSA881X_BONGO_RESRV_REG1		(WSA881X_ANALOG_BASE + 0x0042)
> +#define WSA881X_BONGO_RESRV_REG1_TEMP_CMP_MASK	BIT(7)
> +#define WSA881X_BONGO_RESRV_REG1_ISENSE_MASK	GENMASK(6, 1)
> +#define WSA881X_BONGO_RESRV_REG1_ATEST_MASK	BIT(0)
> +#define WSA881X_BONGO_RESRV_REG1_TEMP_CMP_EN	BIT(7)
> +#define WSA881X_BONGO_RESRV_REG1_ISENSE_RST_VAL	(BIT(4) | BIT(3) | BIT(0))
> +#define WSA881X_BONGO_RESRV_REG1_ATEST_DIS	0
> +#define WSA881X_BONGO_RESRV_REG2		(WSA881X_ANALOG_BASE + 0x0043)
> +#define WSA881X_BONGO_RESRV_REG2_FULL_MASK	((u8)~0U)
> +#define WSA881X_BONGO_RESRV_REG2_RST_VAL	(0x5)
> +#define WSA881X_SPKR_PROT_SAR			(WSA881X_ANALOG_BASE + 0x0044)
> +#define WSA881X_SPKR_STATUS3			(WSA881X_ANALOG_BASE + 0x0045)
> +
> +/*
> + * Private data Structure for wsa881x. All parameters related to
> + * WSA881X codec needs to be defined here.
> + */
> +struct wsa881x_priv {
> +	struct regmap *regmap;
> +	struct device *dev;
> +
> +#if IS_ENABLED(CONFIG_SND_SOC_WSA881X)
> +	/* Soundwire interface */
> +	struct sdw_slave *slave;
> +	struct sdw_stream_config sconfig;
> +	struct sdw_stream_runtime *sruntime;
> +	struct sdw_port_config port_config[WSA881X_MAX_SWR_PORTS];
> +	int active_ports;
> +	bool port_prepared[WSA881X_MAX_SWR_PORTS];
> +	bool port_enable[WSA881X_MAX_SWR_PORTS];
> +#endif
> +
> +	struct gpio_desc *sd_n;
> +	/*
> +	 * Logical state for SD_N GPIO: high for shutdown, low for enable.
> +	 * For backwards compatibility.
> +	 */
> +	unsigned int sd_n_val;
> +};
> +
> +void wsa881x_init_common(struct wsa881x_priv *wsa881x);
> +int wsa881x_probe_common(struct wsa881x_priv **wsa881x, struct device *dev);
> +int wsa881x_digital_mute(struct snd_soc_dai *dai, int mute, int stream);
> +int wsa881x_set_stream(struct snd_soc_dai *dai, void *stream, int direction);
> +
> +static inline bool wsa881x_readable_register(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case WSA881X_CHIP_ID0:
> +	case WSA881X_CHIP_ID1:
> +	case WSA881X_CHIP_ID2:
> +	case WSA881X_CHIP_ID3:
> +	case WSA881X_BUS_ID:
> +	case WSA881X_CDC_RST_CTL:
> +	case WSA881X_CDC_TOP_CLK_CTL:
> +	case WSA881X_CDC_ANA_CLK_CTL:
> +	case WSA881X_CDC_DIG_CLK_CTL:
> +	case WSA881X_CLOCK_CONFIG:
> +	case WSA881X_ANA_CTL:
> +	case WSA881X_SWR_RESET_EN:
> +	case WSA881X_RESET_CTL:
> +	case WSA881X_TADC_VALUE_CTL:
> +	case WSA881X_TEMP_DETECT_CTL:
> +	case WSA881X_TEMP_MSB:
> +	case WSA881X_TEMP_LSB:
> +	case WSA881X_TEMP_CONFIG0:
> +	case WSA881X_TEMP_CONFIG1:
> +	case WSA881X_CDC_CLIP_CTL:
> +	case WSA881X_SDM_PDM9_LSB:
> +	case WSA881X_SDM_PDM9_MSB:
> +	case WSA881X_CDC_RX_CTL:
> +	case WSA881X_DEM_BYPASS_DATA0:
> +	case WSA881X_DEM_BYPASS_DATA1:
> +	case WSA881X_DEM_BYPASS_DATA2:
> +	case WSA881X_DEM_BYPASS_DATA3:
> +	case WSA881X_OTP_CTRL0:
> +	case WSA881X_OTP_CTRL1:
> +	case WSA881X_HDRIVE_CTL_GROUP1:
> +	case WSA881X_INTR_MODE:
> +	case WSA881X_INTR_MASK:
> +	case WSA881X_INTR_STATUS:
> +	case WSA881X_INTR_CLEAR:
> +	case WSA881X_INTR_LEVEL:
> +	case WSA881X_INTR_SET:
> +	case WSA881X_INTR_TEST:
> +	case WSA881X_PDM_TEST_MODE:
> +	case WSA881X_ATE_TEST_MODE:
> +	case WSA881X_PIN_CTL_MODE:
> +	case WSA881X_PIN_CTL_OE:
> +	case WSA881X_PIN_WDATA_IOPAD:
> +	case WSA881X_PIN_STATUS:
> +	case WSA881X_DIG_DEBUG_MODE:
> +	case WSA881X_DIG_DEBUG_SEL:
> +	case WSA881X_DIG_DEBUG_EN:
> +	case WSA881X_SWR_HM_TEST1:
> +	case WSA881X_SWR_HM_TEST2:
> +	case WSA881X_TEMP_DETECT_DBG_CTL:
> +	case WSA881X_TEMP_DEBUG_MSB:
> +	case WSA881X_TEMP_DEBUG_LSB:
> +	case WSA881X_SAMPLE_EDGE_SEL:
> +	case WSA881X_IOPAD_CTL:
> +	case WSA881X_SPARE_0:
> +	case WSA881X_SPARE_1:
> +	case WSA881X_SPARE_2:
> +	case WSA881X_OTP_REG_0:
> +	case WSA881X_OTP_REG_1:
> +	case WSA881X_OTP_REG_2:
> +	case WSA881X_OTP_REG_3:
> +	case WSA881X_OTP_REG_4:
> +	case WSA881X_OTP_REG_5:
> +	case WSA881X_OTP_REG_6:
> +	case WSA881X_OTP_REG_7:
> +	case WSA881X_OTP_REG_8:
> +	case WSA881X_OTP_REG_9:
> +	case WSA881X_OTP_REG_10:
> +	case WSA881X_OTP_REG_11:
> +	case WSA881X_OTP_REG_12:
> +	case WSA881X_OTP_REG_13:
> +	case WSA881X_OTP_REG_14:
> +	case WSA881X_OTP_REG_15:
> +	case WSA881X_OTP_REG_16:
> +	case WSA881X_OTP_REG_17:
> +	case WSA881X_OTP_REG_18:
> +	case WSA881X_OTP_REG_19:
> +	case WSA881X_OTP_REG_20:
> +	case WSA881X_OTP_REG_21:
> +	case WSA881X_OTP_REG_22:
> +	case WSA881X_OTP_REG_23:
> +	case WSA881X_OTP_REG_24:
> +	case WSA881X_OTP_REG_25:
> +	case WSA881X_OTP_REG_26:
> +	case WSA881X_OTP_REG_27:
> +	case WSA881X_OTP_REG_28:
> +	case WSA881X_OTP_REG_29:
> +	case WSA881X_OTP_REG_30:
> +	case WSA881X_OTP_REG_31:
> +	case WSA881X_OTP_REG_63:
> +	case WSA881X_BIAS_REF_CTRL:
> +	case WSA881X_BIAS_TEST:
> +	case WSA881X_BIAS_BIAS:
> +	case WSA881X_TEMP_OP:
> +	case WSA881X_TEMP_IREF_CTRL:
> +	case WSA881X_TEMP_ISENS_CTRL:
> +	case WSA881X_TEMP_CLK_CTRL:
> +	case WSA881X_TEMP_TEST:
> +	case WSA881X_TEMP_BIAS:
> +	case WSA881X_TEMP_ADC_CTRL:
> +	case WSA881X_TEMP_DOUT_MSB:
> +	case WSA881X_TEMP_DOUT_LSB:
> +	case WSA881X_ADC_EN_MODU_V:
> +	case WSA881X_ADC_EN_MODU_I:
> +	case WSA881X_ADC_EN_DET_TEST_V:
> +	case WSA881X_ADC_EN_DET_TEST_I:
> +	case WSA881X_ADC_SEL_IBIAS:
> +	case WSA881X_ADC_EN_SEL_IBIAS:
> +	case WSA881X_SPKR_DRV_EN:
> +	case WSA881X_SPKR_DRV_GAIN:
> +	case WSA881X_SPKR_DAC_CTL:
> +	case WSA881X_SPKR_DRV_DBG:
> +	case WSA881X_SPKR_PWRSTG_DBG:
> +	case WSA881X_SPKR_OCP_CTL:
> +	case WSA881X_SPKR_CLIP_CTL:
> +	case WSA881X_SPKR_BBM_CTL:
> +	case WSA881X_SPKR_MISC_CTL1:
> +	case WSA881X_SPKR_MISC_CTL2:
> +	case WSA881X_SPKR_BIAS_INT:
> +	case WSA881X_SPKR_PA_INT:
> +	case WSA881X_SPKR_BIAS_CAL:
> +	case WSA881X_SPKR_BIAS_PSRR:
> +	case WSA881X_SPKR_STATUS1:
> +	case WSA881X_SPKR_STATUS2:
> +	case WSA881X_BOOST_EN_CTL:
> +	case WSA881X_BOOST_CURRENT_LIMIT:
> +	case WSA881X_BOOST_PS_CTL:
> +	case WSA881X_BOOST_PRESET_OUT1:
> +	case WSA881X_BOOST_PRESET_OUT2:
> +	case WSA881X_BOOST_FORCE_OUT:
> +	case WSA881X_BOOST_LDO_PROG:
> +	case WSA881X_BOOST_SLOPE_COMP_ISENSE_FB:
> +	case WSA881X_BOOST_RON_CTL:
> +	case WSA881X_BOOST_LOOP_STABILITY:
> +	case WSA881X_BOOST_ZX_CTL:
> +	case WSA881X_BOOST_START_CTL:
> +	case WSA881X_BOOST_MISC1_CTL:
> +	case WSA881X_BOOST_MISC2_CTL:
> +	case WSA881X_BOOST_MISC3_CTL:
> +	case WSA881X_BOOST_ATEST_CTL:
> +	case WSA881X_SPKR_PROT_FE_GAIN:
> +	case WSA881X_SPKR_PROT_FE_CM_LDO_SET:
> +	case WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1:
> +	case WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2:
> +	case WSA881X_SPKR_PROT_ATEST1:
> +	case WSA881X_SPKR_PROT_ATEST2:
> +	case WSA881X_SPKR_PROT_FE_VSENSE_VCM:
> +	case WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1:
> +	case WSA881X_BONGO_RESRV_REG1:
> +	case WSA881X_BONGO_RESRV_REG2:
> +	case WSA881X_SPKR_PROT_SAR:
> +	case WSA881X_SPKR_STATUS3:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +static inline bool wsa881x_volatile_register(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case WSA881X_CHIP_ID0:
> +	case WSA881X_CHIP_ID1:
> +	case WSA881X_CHIP_ID2:
> +	case WSA881X_CHIP_ID3:
> +	case WSA881X_BUS_ID:
> +	case WSA881X_TEMP_MSB:
> +	case WSA881X_TEMP_LSB:
> +	case WSA881X_SDM_PDM9_LSB:
> +	case WSA881X_SDM_PDM9_MSB:
> +	case WSA881X_OTP_CTRL1:
> +	case WSA881X_INTR_STATUS:
> +	case WSA881X_ATE_TEST_MODE:
> +	case WSA881X_PIN_STATUS:
> +	case WSA881X_SWR_HM_TEST2:
> +	case WSA881X_SPKR_STATUS1:
> +	case WSA881X_SPKR_STATUS2:
> +	case WSA881X_SPKR_STATUS3:
> +	case WSA881X_OTP_REG_0:
> +	case WSA881X_OTP_REG_1:
> +	case WSA881X_OTP_REG_2:
> +	case WSA881X_OTP_REG_3:
> +	case WSA881X_OTP_REG_4:
> +	case WSA881X_OTP_REG_5:
> +	case WSA881X_OTP_REG_31:
> +	case WSA881X_TEMP_DOUT_MSB:
> +	case WSA881X_TEMP_DOUT_LSB:
> +	case WSA881X_TEMP_OP:
> +	case WSA881X_SPKR_PROT_SAR:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +#endif /* __WSA881x_COMMON_H__ */
> diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c
> index 6627d2da372206eff879f8f3bd5fae9ddc0757d7..3fecc16590a1b0415d944684924f3d41ba3dabd2 100644
> --- a/sound/soc/codecs/wsa881x.c
> +++ b/sound/soc/codecs/wsa881x.c
> @@ -15,172 +15,7 @@
>  #include <sound/soc.h>
>  #include <sound/tlv.h>
>  
> -#define WSA881X_DIGITAL_BASE		0x3000
> -#define WSA881X_ANALOG_BASE		0x3100
> -
> -/* Digital register address space */
> -#define WSA881X_CHIP_ID0			(WSA881X_DIGITAL_BASE + 0x0000)
> -#define WSA881X_CHIP_ID1			(WSA881X_DIGITAL_BASE + 0x0001)
> -#define WSA881X_CHIP_ID2			(WSA881X_DIGITAL_BASE + 0x0002)
> -#define WSA881X_CHIP_ID3			(WSA881X_DIGITAL_BASE + 0x0003)
> -#define WSA881X_BUS_ID				(WSA881X_DIGITAL_BASE + 0x0004)
> -#define WSA881X_CDC_RST_CTL			(WSA881X_DIGITAL_BASE + 0x0005)
> -#define WSA881X_CDC_TOP_CLK_CTL			(WSA881X_DIGITAL_BASE + 0x0006)
> -#define WSA881X_CDC_ANA_CLK_CTL			(WSA881X_DIGITAL_BASE + 0x0007)
> -#define WSA881X_CDC_DIG_CLK_CTL			(WSA881X_DIGITAL_BASE + 0x0008)
> -#define WSA881X_CLOCK_CONFIG			(WSA881X_DIGITAL_BASE + 0x0009)
> -#define WSA881X_ANA_CTL				(WSA881X_DIGITAL_BASE + 0x000A)
> -#define WSA881X_SWR_RESET_EN			(WSA881X_DIGITAL_BASE + 0x000B)
> -#define WSA881X_RESET_CTL			(WSA881X_DIGITAL_BASE + 0x000C)
> -#define WSA881X_TADC_VALUE_CTL			(WSA881X_DIGITAL_BASE + 0x000F)
> -#define WSA881X_TEMP_DETECT_CTL			(WSA881X_DIGITAL_BASE + 0x0010)
> -#define WSA881X_TEMP_MSB			(WSA881X_DIGITAL_BASE + 0x0011)
> -#define WSA881X_TEMP_LSB			(WSA881X_DIGITAL_BASE + 0x0012)
> -#define WSA881X_TEMP_CONFIG0			(WSA881X_DIGITAL_BASE + 0x0013)
> -#define WSA881X_TEMP_CONFIG1			(WSA881X_DIGITAL_BASE + 0x0014)
> -#define WSA881X_CDC_CLIP_CTL			(WSA881X_DIGITAL_BASE + 0x0015)
> -#define WSA881X_SDM_PDM9_LSB			(WSA881X_DIGITAL_BASE + 0x0016)
> -#define WSA881X_SDM_PDM9_MSB			(WSA881X_DIGITAL_BASE + 0x0017)
> -#define WSA881X_CDC_RX_CTL			(WSA881X_DIGITAL_BASE + 0x0018)
> -#define WSA881X_DEM_BYPASS_DATA0		(WSA881X_DIGITAL_BASE + 0x0019)
> -#define WSA881X_DEM_BYPASS_DATA1		(WSA881X_DIGITAL_BASE + 0x001A)
> -#define WSA881X_DEM_BYPASS_DATA2		(WSA881X_DIGITAL_BASE + 0x001B)
> -#define WSA881X_DEM_BYPASS_DATA3		(WSA881X_DIGITAL_BASE + 0x001C)
> -#define WSA881X_OTP_CTRL0			(WSA881X_DIGITAL_BASE + 0x001D)
> -#define WSA881X_OTP_CTRL1			(WSA881X_DIGITAL_BASE + 0x001E)
> -#define WSA881X_HDRIVE_CTL_GROUP1		(WSA881X_DIGITAL_BASE + 0x001F)
> -#define WSA881X_INTR_MODE			(WSA881X_DIGITAL_BASE + 0x0020)
> -#define WSA881X_INTR_MASK			(WSA881X_DIGITAL_BASE + 0x0021)
> -#define WSA881X_INTR_STATUS			(WSA881X_DIGITAL_BASE + 0x0022)
> -#define WSA881X_INTR_CLEAR			(WSA881X_DIGITAL_BASE + 0x0023)
> -#define WSA881X_INTR_LEVEL			(WSA881X_DIGITAL_BASE + 0x0024)
> -#define WSA881X_INTR_SET			(WSA881X_DIGITAL_BASE + 0x0025)
> -#define WSA881X_INTR_TEST			(WSA881X_DIGITAL_BASE + 0x0026)
> -#define WSA881X_PDM_TEST_MODE			(WSA881X_DIGITAL_BASE + 0x0030)
> -#define WSA881X_ATE_TEST_MODE			(WSA881X_DIGITAL_BASE + 0x0031)
> -#define WSA881X_PIN_CTL_MODE			(WSA881X_DIGITAL_BASE + 0x0032)
> -#define WSA881X_PIN_CTL_OE			(WSA881X_DIGITAL_BASE + 0x0033)
> -#define WSA881X_PIN_WDATA_IOPAD			(WSA881X_DIGITAL_BASE + 0x0034)
> -#define WSA881X_PIN_STATUS			(WSA881X_DIGITAL_BASE + 0x0035)
> -#define WSA881X_DIG_DEBUG_MODE			(WSA881X_DIGITAL_BASE + 0x0037)
> -#define WSA881X_DIG_DEBUG_SEL			(WSA881X_DIGITAL_BASE + 0x0038)
> -#define WSA881X_DIG_DEBUG_EN			(WSA881X_DIGITAL_BASE + 0x0039)
> -#define WSA881X_SWR_HM_TEST1			(WSA881X_DIGITAL_BASE + 0x003B)
> -#define WSA881X_SWR_HM_TEST2			(WSA881X_DIGITAL_BASE + 0x003C)
> -#define WSA881X_TEMP_DETECT_DBG_CTL		(WSA881X_DIGITAL_BASE + 0x003D)
> -#define WSA881X_TEMP_DEBUG_MSB			(WSA881X_DIGITAL_BASE + 0x003E)
> -#define WSA881X_TEMP_DEBUG_LSB			(WSA881X_DIGITAL_BASE + 0x003F)
> -#define WSA881X_SAMPLE_EDGE_SEL			(WSA881X_DIGITAL_BASE + 0x0044)
> -#define WSA881X_IOPAD_CTL			(WSA881X_DIGITAL_BASE + 0x0045)
> -#define WSA881X_SPARE_0				(WSA881X_DIGITAL_BASE + 0x0050)
> -#define WSA881X_SPARE_1				(WSA881X_DIGITAL_BASE + 0x0051)
> -#define WSA881X_SPARE_2				(WSA881X_DIGITAL_BASE + 0x0052)
> -#define WSA881X_OTP_REG_0			(WSA881X_DIGITAL_BASE + 0x0080)
> -#define WSA881X_OTP_REG_1			(WSA881X_DIGITAL_BASE + 0x0081)
> -#define WSA881X_OTP_REG_2			(WSA881X_DIGITAL_BASE + 0x0082)
> -#define WSA881X_OTP_REG_3			(WSA881X_DIGITAL_BASE + 0x0083)
> -#define WSA881X_OTP_REG_4			(WSA881X_DIGITAL_BASE + 0x0084)
> -#define WSA881X_OTP_REG_5			(WSA881X_DIGITAL_BASE + 0x0085)
> -#define WSA881X_OTP_REG_6			(WSA881X_DIGITAL_BASE + 0x0086)
> -#define WSA881X_OTP_REG_7			(WSA881X_DIGITAL_BASE + 0x0087)
> -#define WSA881X_OTP_REG_8			(WSA881X_DIGITAL_BASE + 0x0088)
> -#define WSA881X_OTP_REG_9			(WSA881X_DIGITAL_BASE + 0x0089)
> -#define WSA881X_OTP_REG_10			(WSA881X_DIGITAL_BASE + 0x008A)
> -#define WSA881X_OTP_REG_11			(WSA881X_DIGITAL_BASE + 0x008B)
> -#define WSA881X_OTP_REG_12			(WSA881X_DIGITAL_BASE + 0x008C)
> -#define WSA881X_OTP_REG_13			(WSA881X_DIGITAL_BASE + 0x008D)
> -#define WSA881X_OTP_REG_14			(WSA881X_DIGITAL_BASE + 0x008E)
> -#define WSA881X_OTP_REG_15			(WSA881X_DIGITAL_BASE + 0x008F)
> -#define WSA881X_OTP_REG_16			(WSA881X_DIGITAL_BASE + 0x0090)
> -#define WSA881X_OTP_REG_17			(WSA881X_DIGITAL_BASE + 0x0091)
> -#define WSA881X_OTP_REG_18			(WSA881X_DIGITAL_BASE + 0x0092)
> -#define WSA881X_OTP_REG_19			(WSA881X_DIGITAL_BASE + 0x0093)
> -#define WSA881X_OTP_REG_20			(WSA881X_DIGITAL_BASE + 0x0094)
> -#define WSA881X_OTP_REG_21			(WSA881X_DIGITAL_BASE + 0x0095)
> -#define WSA881X_OTP_REG_22			(WSA881X_DIGITAL_BASE + 0x0096)
> -#define WSA881X_OTP_REG_23			(WSA881X_DIGITAL_BASE + 0x0097)
> -#define WSA881X_OTP_REG_24			(WSA881X_DIGITAL_BASE + 0x0098)
> -#define WSA881X_OTP_REG_25			(WSA881X_DIGITAL_BASE + 0x0099)
> -#define WSA881X_OTP_REG_26			(WSA881X_DIGITAL_BASE + 0x009A)
> -#define WSA881X_OTP_REG_27			(WSA881X_DIGITAL_BASE + 0x009B)
> -#define WSA881X_OTP_REG_28			(WSA881X_DIGITAL_BASE + 0x009C)
> -#define WSA881X_OTP_REG_29			(WSA881X_DIGITAL_BASE + 0x009D)
> -#define WSA881X_OTP_REG_30			(WSA881X_DIGITAL_BASE + 0x009E)
> -#define WSA881X_OTP_REG_31			(WSA881X_DIGITAL_BASE + 0x009F)
> -#define WSA881X_OTP_REG_63			(WSA881X_DIGITAL_BASE + 0x00BF)
> -
> -/* Analog Register address space */
> -#define WSA881X_BIAS_REF_CTRL			(WSA881X_ANALOG_BASE + 0x0000)
> -#define WSA881X_BIAS_TEST			(WSA881X_ANALOG_BASE + 0x0001)
> -#define WSA881X_BIAS_BIAS			(WSA881X_ANALOG_BASE + 0x0002)
> -#define WSA881X_TEMP_OP				(WSA881X_ANALOG_BASE + 0x0003)
> -#define WSA881X_TEMP_IREF_CTRL			(WSA881X_ANALOG_BASE + 0x0004)
> -#define WSA881X_TEMP_ISENS_CTRL			(WSA881X_ANALOG_BASE + 0x0005)
> -#define WSA881X_TEMP_CLK_CTRL			(WSA881X_ANALOG_BASE + 0x0006)
> -#define WSA881X_TEMP_TEST			(WSA881X_ANALOG_BASE + 0x0007)
> -#define WSA881X_TEMP_BIAS			(WSA881X_ANALOG_BASE + 0x0008)
> -#define WSA881X_TEMP_ADC_CTRL			(WSA881X_ANALOG_BASE + 0x0009)
> -#define WSA881X_TEMP_DOUT_MSB			(WSA881X_ANALOG_BASE + 0x000A)
> -#define WSA881X_TEMP_DOUT_LSB			(WSA881X_ANALOG_BASE + 0x000B)
> -#define WSA881X_ADC_EN_MODU_V			(WSA881X_ANALOG_BASE + 0x0010)
> -#define WSA881X_ADC_EN_MODU_I			(WSA881X_ANALOG_BASE + 0x0011)
> -#define WSA881X_ADC_EN_DET_TEST_V		(WSA881X_ANALOG_BASE + 0x0012)
> -#define WSA881X_ADC_EN_DET_TEST_I		(WSA881X_ANALOG_BASE + 0x0013)
> -#define WSA881X_ADC_SEL_IBIAS			(WSA881X_ANALOG_BASE + 0x0014)
> -#define WSA881X_ADC_EN_SEL_IBAIS		(WSA881X_ANALOG_BASE + 0x0015)
> -#define WSA881X_SPKR_DRV_EN			(WSA881X_ANALOG_BASE + 0x001A)
> -#define WSA881X_SPKR_DRV_GAIN			(WSA881X_ANALOG_BASE + 0x001B)
> -#define WSA881X_PA_GAIN_SEL_MASK		BIT(3)
> -#define WSA881X_PA_GAIN_SEL_REG			BIT(3)
> -#define WSA881X_PA_GAIN_SEL_DRE			0
> -#define WSA881X_SPKR_PAG_GAIN_MASK		GENMASK(7, 4)
> -#define WSA881X_SPKR_DAC_CTL			(WSA881X_ANALOG_BASE + 0x001C)
> -#define WSA881X_SPKR_DRV_DBG			(WSA881X_ANALOG_BASE + 0x001D)
> -#define WSA881X_SPKR_PWRSTG_DBG			(WSA881X_ANALOG_BASE + 0x001E)
> -#define WSA881X_SPKR_OCP_CTL			(WSA881X_ANALOG_BASE + 0x001F)
> -#define WSA881X_SPKR_OCP_MASK			GENMASK(7, 6)
> -#define WSA881X_SPKR_OCP_EN			BIT(7)
> -#define WSA881X_SPKR_OCP_HOLD			BIT(6)
> -#define WSA881X_SPKR_CLIP_CTL			(WSA881X_ANALOG_BASE + 0x0020)
> -#define WSA881X_SPKR_BBM_CTL			(WSA881X_ANALOG_BASE + 0x0021)
> -#define WSA881X_SPKR_MISC_CTL1			(WSA881X_ANALOG_BASE + 0x0022)
> -#define WSA881X_SPKR_MISC_CTL2			(WSA881X_ANALOG_BASE + 0x0023)
> -#define WSA881X_SPKR_BIAS_INT			(WSA881X_ANALOG_BASE + 0x0024)
> -#define WSA881X_SPKR_PA_INT			(WSA881X_ANALOG_BASE + 0x0025)
> -#define WSA881X_SPKR_BIAS_CAL			(WSA881X_ANALOG_BASE + 0x0026)
> -#define WSA881X_SPKR_BIAS_PSRR			(WSA881X_ANALOG_BASE + 0x0027)
> -#define WSA881X_SPKR_STATUS1			(WSA881X_ANALOG_BASE + 0x0028)
> -#define WSA881X_SPKR_STATUS2			(WSA881X_ANALOG_BASE + 0x0029)
> -#define WSA881X_BOOST_EN_CTL			(WSA881X_ANALOG_BASE + 0x002A)
> -#define WSA881X_BOOST_EN_MASK			BIT(7)
> -#define WSA881X_BOOST_EN			BIT(7)
> -#define WSA881X_BOOST_CURRENT_LIMIT		(WSA881X_ANALOG_BASE + 0x002B)
> -#define WSA881X_BOOST_PS_CTL			(WSA881X_ANALOG_BASE + 0x002C)
> -#define WSA881X_BOOST_PRESET_OUT1		(WSA881X_ANALOG_BASE + 0x002D)
> -#define WSA881X_BOOST_PRESET_OUT2		(WSA881X_ANALOG_BASE + 0x002E)
> -#define WSA881X_BOOST_FORCE_OUT			(WSA881X_ANALOG_BASE + 0x002F)
> -#define WSA881X_BOOST_LDO_PROG			(WSA881X_ANALOG_BASE + 0x0030)
> -#define WSA881X_BOOST_SLOPE_COMP_ISENSE_FB	(WSA881X_ANALOG_BASE + 0x0031)
> -#define WSA881X_BOOST_RON_CTL			(WSA881X_ANALOG_BASE + 0x0032)
> -#define WSA881X_BOOST_LOOP_STABILITY		(WSA881X_ANALOG_BASE + 0x0033)
> -#define WSA881X_BOOST_ZX_CTL			(WSA881X_ANALOG_BASE + 0x0034)
> -#define WSA881X_BOOST_START_CTL			(WSA881X_ANALOG_BASE + 0x0035)
> -#define WSA881X_BOOST_MISC1_CTL			(WSA881X_ANALOG_BASE + 0x0036)
> -#define WSA881X_BOOST_MISC2_CTL			(WSA881X_ANALOG_BASE + 0x0037)
> -#define WSA881X_BOOST_MISC3_CTL			(WSA881X_ANALOG_BASE + 0x0038)
> -#define WSA881X_BOOST_ATEST_CTL			(WSA881X_ANALOG_BASE + 0x0039)
> -#define WSA881X_SPKR_PROT_FE_GAIN		(WSA881X_ANALOG_BASE + 0x003A)
> -#define WSA881X_SPKR_PROT_FE_CM_LDO_SET		(WSA881X_ANALOG_BASE + 0x003B)
> -#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1	(WSA881X_ANALOG_BASE + 0x003C)
> -#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2	(WSA881X_ANALOG_BASE + 0x003D)
> -#define WSA881X_SPKR_PROT_ATEST1		(WSA881X_ANALOG_BASE + 0x003E)
> -#define WSA881X_SPKR_PROT_ATEST2		(WSA881X_ANALOG_BASE + 0x003F)
> -#define WSA881X_SPKR_PROT_FE_VSENSE_VCM		(WSA881X_ANALOG_BASE + 0x0040)
> -#define WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1	(WSA881X_ANALOG_BASE + 0x0041)
> -#define WSA881X_BONGO_RESRV_REG1		(WSA881X_ANALOG_BASE + 0x0042)
> -#define WSA881X_BONGO_RESRV_REG2		(WSA881X_ANALOG_BASE + 0x0043)
> -#define WSA881X_SPKR_PROT_SAR			(WSA881X_ANALOG_BASE + 0x0044)
> -#define WSA881X_SPKR_STATUS3			(WSA881X_ANALOG_BASE + 0x0045)
> +#include "wsa881x-common.h"
>  
>  #define SWRS_SCP_FRAME_CTRL_BANK(m)		(0x60 + 0x10 * (m))
>  #define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m)	(0xE0 + 0x10 * (m))
> @@ -191,7 +26,6 @@
>  #define SWR_SLV_RD_BUF_LEN	8
>  #define SWR_SLV_WR_BUF_LEN	32
>  #define SWR_SLV_MAX_DEVICES	2
> -#define WSA881X_MAX_SWR_PORTS   4
>  #define WSA881X_VERSION_ENTRY_SIZE 27
>  #define WSA881X_OCP_CTL_TIMER_SEC 2
>  #define WSA881X_OCP_CTL_TEMP_CELSIUS 25
> @@ -300,7 +134,7 @@ static struct reg_default wsa881x_defaults[] = {
>  	{ WSA881X_ADC_EN_MODU_I, 0x00 },
>  	{ WSA881X_ADC_EN_DET_TEST_V, 0x00 },
>  	{ WSA881X_ADC_EN_DET_TEST_I, 0x00 },
> -	{ WSA881X_ADC_EN_SEL_IBAIS, 0x10 },
> +	{ WSA881X_ADC_EN_SEL_IBIAS, 0x10 },
>  	{ WSA881X_SPKR_DRV_EN, 0x74 },
>  	{ WSA881X_SPKR_DRV_DBG, 0x15 },
>  	{ WSA881X_SPKR_PWRSTG_DBG, 0x00 },
> @@ -434,204 +268,8 @@ static const struct sdw_port_config wsa881x_pconfig[WSA881X_MAX_SWR_PORTS] = {
>  	},
>  };
>  
> -static bool wsa881x_readable_register(struct device *dev, unsigned int reg)
> -{
> -	switch (reg) {
> -	case WSA881X_CHIP_ID0:
> -	case WSA881X_CHIP_ID1:
> -	case WSA881X_CHIP_ID2:
> -	case WSA881X_CHIP_ID3:
> -	case WSA881X_BUS_ID:
> -	case WSA881X_CDC_RST_CTL:
> -	case WSA881X_CDC_TOP_CLK_CTL:
> -	case WSA881X_CDC_ANA_CLK_CTL:
> -	case WSA881X_CDC_DIG_CLK_CTL:
> -	case WSA881X_CLOCK_CONFIG:
> -	case WSA881X_ANA_CTL:
> -	case WSA881X_SWR_RESET_EN:
> -	case WSA881X_RESET_CTL:
> -	case WSA881X_TADC_VALUE_CTL:
> -	case WSA881X_TEMP_DETECT_CTL:
> -	case WSA881X_TEMP_MSB:
> -	case WSA881X_TEMP_LSB:
> -	case WSA881X_TEMP_CONFIG0:
> -	case WSA881X_TEMP_CONFIG1:
> -	case WSA881X_CDC_CLIP_CTL:
> -	case WSA881X_SDM_PDM9_LSB:
> -	case WSA881X_SDM_PDM9_MSB:
> -	case WSA881X_CDC_RX_CTL:
> -	case WSA881X_DEM_BYPASS_DATA0:
> -	case WSA881X_DEM_BYPASS_DATA1:
> -	case WSA881X_DEM_BYPASS_DATA2:
> -	case WSA881X_DEM_BYPASS_DATA3:
> -	case WSA881X_OTP_CTRL0:
> -	case WSA881X_OTP_CTRL1:
> -	case WSA881X_HDRIVE_CTL_GROUP1:
> -	case WSA881X_INTR_MODE:
> -	case WSA881X_INTR_MASK:
> -	case WSA881X_INTR_STATUS:
> -	case WSA881X_INTR_CLEAR:
> -	case WSA881X_INTR_LEVEL:
> -	case WSA881X_INTR_SET:
> -	case WSA881X_INTR_TEST:
> -	case WSA881X_PDM_TEST_MODE:
> -	case WSA881X_ATE_TEST_MODE:
> -	case WSA881X_PIN_CTL_MODE:
> -	case WSA881X_PIN_CTL_OE:
> -	case WSA881X_PIN_WDATA_IOPAD:
> -	case WSA881X_PIN_STATUS:
> -	case WSA881X_DIG_DEBUG_MODE:
> -	case WSA881X_DIG_DEBUG_SEL:
> -	case WSA881X_DIG_DEBUG_EN:
> -	case WSA881X_SWR_HM_TEST1:
> -	case WSA881X_SWR_HM_TEST2:
> -	case WSA881X_TEMP_DETECT_DBG_CTL:
> -	case WSA881X_TEMP_DEBUG_MSB:
> -	case WSA881X_TEMP_DEBUG_LSB:
> -	case WSA881X_SAMPLE_EDGE_SEL:
> -	case WSA881X_IOPAD_CTL:
> -	case WSA881X_SPARE_0:
> -	case WSA881X_SPARE_1:
> -	case WSA881X_SPARE_2:
> -	case WSA881X_OTP_REG_0:
> -	case WSA881X_OTP_REG_1:
> -	case WSA881X_OTP_REG_2:
> -	case WSA881X_OTP_REG_3:
> -	case WSA881X_OTP_REG_4:
> -	case WSA881X_OTP_REG_5:
> -	case WSA881X_OTP_REG_6:
> -	case WSA881X_OTP_REG_7:
> -	case WSA881X_OTP_REG_8:
> -	case WSA881X_OTP_REG_9:
> -	case WSA881X_OTP_REG_10:
> -	case WSA881X_OTP_REG_11:
> -	case WSA881X_OTP_REG_12:
> -	case WSA881X_OTP_REG_13:
> -	case WSA881X_OTP_REG_14:
> -	case WSA881X_OTP_REG_15:
> -	case WSA881X_OTP_REG_16:
> -	case WSA881X_OTP_REG_17:
> -	case WSA881X_OTP_REG_18:
> -	case WSA881X_OTP_REG_19:
> -	case WSA881X_OTP_REG_20:
> -	case WSA881X_OTP_REG_21:
> -	case WSA881X_OTP_REG_22:
> -	case WSA881X_OTP_REG_23:
> -	case WSA881X_OTP_REG_24:
> -	case WSA881X_OTP_REG_25:
> -	case WSA881X_OTP_REG_26:
> -	case WSA881X_OTP_REG_27:
> -	case WSA881X_OTP_REG_28:
> -	case WSA881X_OTP_REG_29:
> -	case WSA881X_OTP_REG_30:
> -	case WSA881X_OTP_REG_31:
> -	case WSA881X_OTP_REG_63:
> -	case WSA881X_BIAS_REF_CTRL:
> -	case WSA881X_BIAS_TEST:
> -	case WSA881X_BIAS_BIAS:
> -	case WSA881X_TEMP_OP:
> -	case WSA881X_TEMP_IREF_CTRL:
> -	case WSA881X_TEMP_ISENS_CTRL:
> -	case WSA881X_TEMP_CLK_CTRL:
> -	case WSA881X_TEMP_TEST:
> -	case WSA881X_TEMP_BIAS:
> -	case WSA881X_TEMP_ADC_CTRL:
> -	case WSA881X_TEMP_DOUT_MSB:
> -	case WSA881X_TEMP_DOUT_LSB:
> -	case WSA881X_ADC_EN_MODU_V:
> -	case WSA881X_ADC_EN_MODU_I:
> -	case WSA881X_ADC_EN_DET_TEST_V:
> -	case WSA881X_ADC_EN_DET_TEST_I:
> -	case WSA881X_ADC_SEL_IBIAS:
> -	case WSA881X_ADC_EN_SEL_IBAIS:
> -	case WSA881X_SPKR_DRV_EN:
> -	case WSA881X_SPKR_DRV_GAIN:
> -	case WSA881X_SPKR_DAC_CTL:
> -	case WSA881X_SPKR_DRV_DBG:
> -	case WSA881X_SPKR_PWRSTG_DBG:
> -	case WSA881X_SPKR_OCP_CTL:
> -	case WSA881X_SPKR_CLIP_CTL:
> -	case WSA881X_SPKR_BBM_CTL:
> -	case WSA881X_SPKR_MISC_CTL1:
> -	case WSA881X_SPKR_MISC_CTL2:
> -	case WSA881X_SPKR_BIAS_INT:
> -	case WSA881X_SPKR_PA_INT:
> -	case WSA881X_SPKR_BIAS_CAL:
> -	case WSA881X_SPKR_BIAS_PSRR:
> -	case WSA881X_SPKR_STATUS1:
> -	case WSA881X_SPKR_STATUS2:
> -	case WSA881X_BOOST_EN_CTL:
> -	case WSA881X_BOOST_CURRENT_LIMIT:
> -	case WSA881X_BOOST_PS_CTL:
> -	case WSA881X_BOOST_PRESET_OUT1:
> -	case WSA881X_BOOST_PRESET_OUT2:
> -	case WSA881X_BOOST_FORCE_OUT:
> -	case WSA881X_BOOST_LDO_PROG:
> -	case WSA881X_BOOST_SLOPE_COMP_ISENSE_FB:
> -	case WSA881X_BOOST_RON_CTL:
> -	case WSA881X_BOOST_LOOP_STABILITY:
> -	case WSA881X_BOOST_ZX_CTL:
> -	case WSA881X_BOOST_START_CTL:
> -	case WSA881X_BOOST_MISC1_CTL:
> -	case WSA881X_BOOST_MISC2_CTL:
> -	case WSA881X_BOOST_MISC3_CTL:
> -	case WSA881X_BOOST_ATEST_CTL:
> -	case WSA881X_SPKR_PROT_FE_GAIN:
> -	case WSA881X_SPKR_PROT_FE_CM_LDO_SET:
> -	case WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1:
> -	case WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2:
> -	case WSA881X_SPKR_PROT_ATEST1:
> -	case WSA881X_SPKR_PROT_ATEST2:
> -	case WSA881X_SPKR_PROT_FE_VSENSE_VCM:
> -	case WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1:
> -	case WSA881X_BONGO_RESRV_REG1:
> -	case WSA881X_BONGO_RESRV_REG2:
> -	case WSA881X_SPKR_PROT_SAR:
> -	case WSA881X_SPKR_STATUS3:
> -		return true;
> -	default:
> -		return false;
> -	}
> -}
> -
> -static bool wsa881x_volatile_register(struct device *dev, unsigned int reg)
> -{
> -	switch (reg) {
> -	case WSA881X_CHIP_ID0:
> -	case WSA881X_CHIP_ID1:
> -	case WSA881X_CHIP_ID2:
> -	case WSA881X_CHIP_ID3:
> -	case WSA881X_BUS_ID:
> -	case WSA881X_TEMP_MSB:
> -	case WSA881X_TEMP_LSB:
> -	case WSA881X_SDM_PDM9_LSB:
> -	case WSA881X_SDM_PDM9_MSB:
> -	case WSA881X_OTP_CTRL1:
> -	case WSA881X_INTR_STATUS:
> -	case WSA881X_ATE_TEST_MODE:
> -	case WSA881X_PIN_STATUS:
> -	case WSA881X_SWR_HM_TEST2:
> -	case WSA881X_SPKR_STATUS1:
> -	case WSA881X_SPKR_STATUS2:
> -	case WSA881X_SPKR_STATUS3:
> -	case WSA881X_OTP_REG_0:
> -	case WSA881X_OTP_REG_1:
> -	case WSA881X_OTP_REG_2:
> -	case WSA881X_OTP_REG_3:
> -	case WSA881X_OTP_REG_4:
> -	case WSA881X_OTP_REG_5:
> -	case WSA881X_OTP_REG_31:
> -	case WSA881X_TEMP_DOUT_MSB:
> -	case WSA881X_TEMP_DOUT_LSB:
> -	case WSA881X_TEMP_OP:
> -	case WSA881X_SPKR_PROT_SAR:
> -		return true;
> -	default:
> -		return false;
> -	}
> -}
> -
>  static const struct regmap_config wsa881x_regmap_config = {
> +	.reg_base = 0x3000,
>  	.reg_bits = 32,
>  	.val_bits = 8,
>  	.cache_type = REGCACHE_MAPLE,
> @@ -660,70 +298,15 @@ enum {
>  	G_0DB,
>  };
>  
> -/*
> - * Private data Structure for wsa881x. All parameters related to
> - * WSA881X codec needs to be defined here.
> - */
> -struct wsa881x_priv {
> -	struct regmap *regmap;
> -	struct device *dev;
> -	struct sdw_slave *slave;
> -	struct sdw_stream_config sconfig;
> -	struct sdw_stream_runtime *sruntime;
> -	struct sdw_port_config port_config[WSA881X_MAX_SWR_PORTS];
> -	struct gpio_desc *sd_n;
> -	/*
> -	 * Logical state for SD_N GPIO: high for shutdown, low for enable.
> -	 * For backwards compatibility.
> -	 */
> -	unsigned int sd_n_val;
> -	int active_ports;
> -	bool port_prepared[WSA881X_MAX_SWR_PORTS];
> -	bool port_enable[WSA881X_MAX_SWR_PORTS];
> -};
> -
>  static void wsa881x_init(struct wsa881x_priv *wsa881x)
>  {
> -	struct regmap *rm = wsa881x->regmap;
> -	unsigned int val = 0;
> -
>  	regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0,
>  			      ARRAY_SIZE(wsa881x_rev_2_0));
>  
>  	/* Enable software reset output from soundwire slave */
> -	regmap_update_bits(rm, WSA881X_SWR_RESET_EN, 0x07, 0x07);
> -
> -	/* Bring out of analog reset */
> -	regmap_update_bits(rm, WSA881X_CDC_RST_CTL, 0x02, 0x02);
> -
> -	/* Bring out of digital reset */
> -	regmap_update_bits(rm, WSA881X_CDC_RST_CTL, 0x01, 0x01);
> -	regmap_update_bits(rm, WSA881X_CLOCK_CONFIG, 0x10, 0x10);
> -	regmap_update_bits(rm, WSA881X_SPKR_OCP_CTL, 0x02, 0x02);
> -	regmap_update_bits(rm, WSA881X_SPKR_MISC_CTL1, 0xC0, 0x80);
> -	regmap_update_bits(rm, WSA881X_SPKR_MISC_CTL1, 0x06, 0x06);
> -	regmap_update_bits(rm, WSA881X_SPKR_BIAS_INT, 0xFF, 0x00);
> -	regmap_update_bits(rm, WSA881X_SPKR_PA_INT, 0xF0, 0x40);
> -	regmap_update_bits(rm, WSA881X_SPKR_PA_INT, 0x0E, 0x0E);
> -	regmap_update_bits(rm, WSA881X_BOOST_LOOP_STABILITY, 0x03, 0x03);
> -	regmap_update_bits(rm, WSA881X_BOOST_MISC2_CTL, 0xFF, 0x14);
> -	regmap_update_bits(rm, WSA881X_BOOST_START_CTL, 0x80, 0x80);
> -	regmap_update_bits(rm, WSA881X_BOOST_START_CTL, 0x03, 0x00);
> -	regmap_update_bits(rm, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x0C, 0x04);
> -	regmap_update_bits(rm, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x03, 0x00);
> -
> -	regmap_read(rm, WSA881X_OTP_REG_0, &val);
> -	if (val)
> -		regmap_update_bits(rm, WSA881X_BOOST_PRESET_OUT1, 0xF0, 0x70);
> -
> -	regmap_update_bits(rm, WSA881X_BOOST_PRESET_OUT2, 0xF0, 0x30);
> -	regmap_update_bits(rm, WSA881X_SPKR_DRV_EN, 0x08, 0x08);
> -	regmap_update_bits(rm, WSA881X_BOOST_CURRENT_LIMIT, 0x0F, 0x08);
> -	regmap_update_bits(rm, WSA881X_SPKR_OCP_CTL, 0x30, 0x30);
> -	regmap_update_bits(rm, WSA881X_SPKR_OCP_CTL, 0x0C, 0x00);
> -	regmap_update_bits(rm, WSA881X_OTP_REG_28, 0x3F, 0x3A);
> -	regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1, 0xFF, 0xB2);
> -	regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG2, 0xFF, 0x05);
> +	regmap_update_bits(wsa881x->regmap, WSA881X_SWR_RESET_EN, 0x07, 0x07);
> +
> +	wsa881x_init_common(wsa881x);
>  }
>  
>  static int wsa881x_component_probe(struct snd_soc_component *comp)
> @@ -932,7 +515,7 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w,
>  		if (wsa881x->port_prepared[WSA881X_PORT_VISENSE]) {
>  			wsa881x_visense_txfe_ctrl(comp, true);
>  			snd_soc_component_update_bits(comp,
> -						      WSA881X_ADC_EN_SEL_IBAIS,
> +						      WSA881X_ADC_EN_SEL_IBIAS,
>  						      0x07, 0x01);
>  			wsa881x_visense_adc_ctrl(comp, true);
>  		}
> @@ -1003,35 +586,11 @@ static int wsa881x_hw_free(struct snd_pcm_substream *substream,
>  	return 0;
>  }
>  
> -static int wsa881x_set_sdw_stream(struct snd_soc_dai *dai,
> -				  void *stream, int direction)
> -{
> -	struct wsa881x_priv *wsa881x = dev_get_drvdata(dai->dev);
> -
> -	wsa881x->sruntime = stream;
> -
> -	return 0;
> -}
> -
> -static int wsa881x_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
> -{
> -	struct wsa881x_priv *wsa881x = dev_get_drvdata(dai->dev);
> -
> -	if (mute)
> -		regmap_update_bits(wsa881x->regmap, WSA881X_SPKR_DRV_EN, 0x80,
> -				   0x00);
> -	else
> -		regmap_update_bits(wsa881x->regmap, WSA881X_SPKR_DRV_EN, 0x80,
> -				   0x80);
> -
> -	return 0;
> -}
> -
>  static const struct snd_soc_dai_ops wsa881x_dai_ops = {
>  	.hw_params = wsa881x_hw_params,
>  	.hw_free = wsa881x_hw_free,
>  	.mute_stream = wsa881x_digital_mute,
> -	.set_stream = wsa881x_set_sdw_stream,
> +	.set_stream = wsa881x_set_stream,
>  };
>  
>  static struct snd_soc_dai_driver wsa881x_dais[] = {
> @@ -1108,40 +667,13 @@ static int wsa881x_probe(struct sdw_slave *pdev,
>  {
>  	struct wsa881x_priv *wsa881x;
>  	struct device *dev = &pdev->dev;
> +	int ret;
>  
> -	wsa881x = devm_kzalloc(dev, sizeof(*wsa881x), GFP_KERNEL);
> -	if (!wsa881x)
> -		return -ENOMEM;
> -
> -	wsa881x->sd_n = devm_gpiod_get_optional(dev, "powerdown",
> -						GPIOD_FLAGS_BIT_NONEXCLUSIVE);
> -	if (IS_ERR(wsa881x->sd_n))
> -		return dev_err_probe(dev, PTR_ERR(wsa881x->sd_n),
> -				     "Shutdown Control GPIO not found\n");
> -
> -	/*
> -	 * Backwards compatibility work-around.
> -	 *
> -	 * The SD_N GPIO is active low, however upstream DTS used always active
> -	 * high.  Changing the flag in driver and DTS will break backwards
> -	 * compatibility, so add a simple value inversion to work with both old
> -	 * and new DTS.
> -	 *
> -	 * This won't work properly with DTS using the flags properly in cases:
> -	 * 1. Old DTS with proper ACTIVE_LOW, however such case was broken
> -	 *    before as the driver required the active high.
> -	 * 2. New DTS with proper ACTIVE_HIGH (intended), which is rare case
> -	 *    (not existing upstream) but possible. This is the price of
> -	 *    backwards compatibility, therefore this hack should be removed at
> -	 *    some point.
> -	 */
> -	wsa881x->sd_n_val = gpiod_is_active_low(wsa881x->sd_n);
> -	if (!wsa881x->sd_n_val)
> -		dev_warn(dev, "Using ACTIVE_HIGH for shutdown GPIO. Your DTB might be outdated or you use unsupported configuration for the GPIO.");
> +	ret = wsa881x_probe_common(&wsa881x, dev);
> +	if (ret)
> +		return ret;
>  
> -	dev_set_drvdata(dev, wsa881x);
>  	wsa881x->slave = pdev;
> -	wsa881x->dev = dev;
>  	wsa881x->sconfig.ch_count = 1;
>  	wsa881x->sconfig.bps = 1;
>  	wsa881x->sconfig.frame_rate = 48000;
> @@ -1151,7 +683,6 @@ static int wsa881x_probe(struct sdw_slave *pdev,
>  	pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop;
>  	pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
>  	pdev->prop.clk_stop_mode1 = true;
> -	gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val);
>  
>  	wsa881x->regmap = devm_regmap_init_sdw(pdev, &wsa881x_regmap_config);
>  	if (IS_ERR(wsa881x->regmap))
> 


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ