Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
   1// SPDX-License-Identifier: GPL-2.0-only
   2// Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
   3
   4#include <linux/module.h>
   5#include <linux/init.h>
   6#include <linux/io.h>
   7#include <linux/of.h>
   8#include <linux/platform_device.h>
   9#include <linux/clk.h>
  10#include <linux/of_clk.h>
  11#include <linux/clk-provider.h>
  12#include <sound/soc.h>
  13#include <sound/soc-dapm.h>
  14#include <linux/pm_runtime.h>
  15#include <linux/of_platform.h>
  16#include <sound/tlv.h>
  17
  18#include "lpass-macro-common.h"
  19#include "lpass-wsa-macro.h"
  20
  21#define CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL	(0x0000)
  22#define CDC_WSA_MCLK_EN_MASK			BIT(0)
  23#define CDC_WSA_MCLK_ENABLE			BIT(0)
  24#define CDC_WSA_MCLK_DISABLE			0
  25#define CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL	(0x0004)
  26#define CDC_WSA_FS_CNT_EN_MASK			BIT(0)
  27#define CDC_WSA_FS_CNT_ENABLE			BIT(0)
  28#define CDC_WSA_FS_CNT_DISABLE			0
  29#define CDC_WSA_CLK_RST_CTRL_SWR_CONTROL	(0x0008)
  30#define CDC_WSA_SWR_CLK_EN_MASK			BIT(0)
  31#define CDC_WSA_SWR_CLK_ENABLE			BIT(0)
  32#define CDC_WSA_SWR_RST_EN_MASK			BIT(1)
  33#define CDC_WSA_SWR_RST_ENABLE			BIT(1)
  34#define CDC_WSA_SWR_RST_DISABLE			0
  35#define CDC_WSA_TOP_TOP_CFG0			(0x0080)
  36#define CDC_WSA_TOP_TOP_CFG1			(0x0084)
  37#define CDC_WSA_TOP_FREQ_MCLK			(0x0088)
  38#define CDC_WSA_TOP_DEBUG_BUS_SEL		(0x008C)
  39#define CDC_WSA_TOP_DEBUG_EN0			(0x0090)
  40#define CDC_WSA_TOP_DEBUG_EN1			(0x0094)
  41#define CDC_WSA_TOP_DEBUG_DSM_LB		(0x0098)
  42#define CDC_WSA_TOP_RX_I2S_CTL			(0x009C)
  43#define CDC_WSA_TOP_TX_I2S_CTL			(0x00A0)
  44#define CDC_WSA_TOP_I2S_CLK			(0x00A4)
  45#define CDC_WSA_TOP_I2S_RESET			(0x00A8)
  46#define CDC_WSA_RX_INP_MUX_RX_INT0_CFG0		(0x0100)
  47#define CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK	GENMASK(2, 0)
  48#define CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK	GENMASK(5, 3)
  49#define CDC_WSA_RX_INP_MUX_RX_INT0_CFG1		(0x0104)
  50#define CDC_WSA_RX_INTX_2_SEL_MASK		GENMASK(2, 0)
  51#define CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK	GENMASK(5, 3)
  52#define CDC_WSA_RX_INP_MUX_RX_INT1_CFG0		(0x0108)
  53#define CDC_WSA_RX_INP_MUX_RX_INT1_CFG1		(0x010C)
  54#define CDC_WSA_RX_INP_MUX_RX_MIX_CFG0		(0x0110)
  55#define CDC_WSA_RX_MIX_TX1_SEL_MASK		GENMASK(5, 3)
  56#define CDC_WSA_RX_MIX_TX1_SEL_SHFT		3
  57#define CDC_WSA_RX_MIX_TX0_SEL_MASK		GENMASK(2, 0)
  58#define CDC_WSA_RX_INP_MUX_RX_EC_CFG0		(0x0114)
  59#define CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0	(0x0118)
  60#define CDC_WSA_TX0_SPKR_PROT_PATH_CTL		(0x0244)
  61#define CDC_WSA_TX_SPKR_PROT_RESET_MASK		BIT(5)
  62#define CDC_WSA_TX_SPKR_PROT_RESET		BIT(5)
  63#define CDC_WSA_TX_SPKR_PROT_NO_RESET		0
  64#define CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK	BIT(4)
  65#define CDC_WSA_TX_SPKR_PROT_CLK_ENABLE		BIT(4)
  66#define CDC_WSA_TX_SPKR_PROT_CLK_DISABLE	0
  67#define CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK	GENMASK(3, 0)
  68#define CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K	0
  69#define CDC_WSA_TX0_SPKR_PROT_PATH_CFG0		(0x0248)
  70#define CDC_WSA_TX1_SPKR_PROT_PATH_CTL		(0x0264)
  71#define CDC_WSA_TX1_SPKR_PROT_PATH_CFG0		(0x0268)
  72#define CDC_WSA_TX2_SPKR_PROT_PATH_CTL		(0x0284)
  73#define CDC_WSA_TX2_SPKR_PROT_PATH_CFG0		(0x0288)
  74#define CDC_WSA_TX3_SPKR_PROT_PATH_CTL		(0x02A4)
  75#define CDC_WSA_TX3_SPKR_PROT_PATH_CFG0		(0x02A8)
  76#define CDC_WSA_INTR_CTRL_CFG			(0x0340)
  77#define CDC_WSA_INTR_CTRL_CLR_COMMIT		(0x0344)
  78#define CDC_WSA_INTR_CTRL_PIN1_MASK0		(0x0360)
  79#define CDC_WSA_INTR_CTRL_PIN1_STATUS0		(0x0368)
  80#define CDC_WSA_INTR_CTRL_PIN1_CLEAR0		(0x0370)
  81#define CDC_WSA_INTR_CTRL_PIN2_MASK0		(0x0380)
  82#define CDC_WSA_INTR_CTRL_PIN2_STATUS0		(0x0388)
  83#define CDC_WSA_INTR_CTRL_PIN2_CLEAR0		(0x0390)
  84#define CDC_WSA_INTR_CTRL_LEVEL0		(0x03C0)
  85#define CDC_WSA_INTR_CTRL_BYPASS0		(0x03C8)
  86#define CDC_WSA_INTR_CTRL_SET0			(0x03D0)
  87#define CDC_WSA_RX0_RX_PATH_CTL			(0x0400)
  88#define CDC_WSA_RX_PATH_CLK_EN_MASK		BIT(5)
  89#define CDC_WSA_RX_PATH_CLK_ENABLE		BIT(5)
  90#define CDC_WSA_RX_PATH_CLK_DISABLE		0
  91#define CDC_WSA_RX_PATH_PGA_MUTE_EN_MASK	BIT(4)
  92#define CDC_WSA_RX_PATH_PGA_MUTE_ENABLE		BIT(4)
  93#define CDC_WSA_RX_PATH_PGA_MUTE_DISABLE	0
  94#define CDC_WSA_RX0_RX_PATH_CFG0		(0x0404)
  95#define CDC_WSA_RX_PATH_COMP_EN_MASK		BIT(1)
  96#define CDC_WSA_RX_PATH_COMP_ENABLE		BIT(1)
  97#define CDC_WSA_RX_PATH_HD2_EN_MASK		BIT(2)
  98#define CDC_WSA_RX_PATH_HD2_ENABLE		BIT(2)
  99#define CDC_WSA_RX_PATH_SPKR_RATE_MASK		BIT(3)
 100#define CDC_WSA_RX_PATH_SPKR_RATE_FS_2P4_3P072	BIT(3)
 101#define CDC_WSA_RX0_RX_PATH_CFG1		(0x0408)
 102#define CDC_WSA_RX_PATH_SMART_BST_EN_MASK	BIT(0)
 103#define CDC_WSA_RX_PATH_SMART_BST_ENABLE	BIT(0)
 104#define CDC_WSA_RX_PATH_SMART_BST_DISABLE	0
 105#define CDC_WSA_RX0_RX_PATH_CFG2		(0x040C)
 106#define CDC_WSA_RX0_RX_PATH_CFG3		(0x0410)
 107#define CDC_WSA_RX_DC_DCOEFF_MASK		GENMASK(1, 0)
 108#define CDC_WSA_RX0_RX_VOL_CTL			(0x0414)
 109#define CDC_WSA_RX0_RX_PATH_MIX_CTL		(0x0418)
 110#define CDC_WSA_RX_PATH_MIX_CLK_EN_MASK		BIT(5)
 111#define CDC_WSA_RX_PATH_MIX_CLK_ENABLE		BIT(5)
 112#define CDC_WSA_RX_PATH_MIX_CLK_DISABLE		0
 113#define CDC_WSA_RX0_RX_PATH_MIX_CFG		(0x041C)
 114#define CDC_WSA_RX0_RX_VOL_MIX_CTL		(0x0420)
 115#define CDC_WSA_RX0_RX_PATH_SEC0		(0x0424)
 116#define CDC_WSA_RX0_RX_PATH_SEC1		(0x0428)
 117#define CDC_WSA_RX_PGA_HALF_DB_MASK		BIT(0)
 118#define CDC_WSA_RX_PGA_HALF_DB_ENABLE		BIT(0)
 119#define CDC_WSA_RX_PGA_HALF_DB_DISABLE		0
 120#define CDC_WSA_RX0_RX_PATH_SEC2		(0x042C)
 121#define CDC_WSA_RX0_RX_PATH_SEC3		(0x0430)
 122#define CDC_WSA_RX_PATH_HD2_SCALE_MASK		GENMASK(1, 0)
 123#define CDC_WSA_RX_PATH_HD2_ALPHA_MASK		GENMASK(5, 2)
 124#define CDC_WSA_RX0_RX_PATH_SEC5		(0x0438)
 125#define CDC_WSA_RX0_RX_PATH_SEC6		(0x043C)
 126#define CDC_WSA_RX0_RX_PATH_SEC7		(0x0440)
 127#define CDC_WSA_RX0_RX_PATH_MIX_SEC0		(0x0444)
 128#define CDC_WSA_RX0_RX_PATH_MIX_SEC1		(0x0448)
 129#define CDC_WSA_RX0_RX_PATH_DSMDEM_CTL		(0x044C)
 130#define CDC_WSA_RX_DSMDEM_CLK_EN_MASK		BIT(0)
 131#define CDC_WSA_RX_DSMDEM_CLK_ENABLE		BIT(0)
 132#define CDC_WSA_RX1_RX_PATH_CTL			(0x0480)
 133#define CDC_WSA_RX1_RX_PATH_CFG0		(0x0484)
 134#define CDC_WSA_RX1_RX_PATH_CFG1		(0x0488)
 135#define CDC_WSA_RX1_RX_PATH_CFG2		(0x048C)
 136#define CDC_WSA_RX1_RX_PATH_CFG3		(0x0490)
 137#define CDC_WSA_RX1_RX_VOL_CTL			(0x0494)
 138#define CDC_WSA_RX1_RX_PATH_MIX_CTL		(0x0498)
 139#define CDC_WSA_RX1_RX_PATH_MIX_CFG		(0x049C)
 140#define CDC_WSA_RX1_RX_VOL_MIX_CTL		(0x04A0)
 141#define CDC_WSA_RX1_RX_PATH_SEC0		(0x04A4)
 142#define CDC_WSA_RX1_RX_PATH_SEC1		(0x04A8)
 143#define CDC_WSA_RX1_RX_PATH_SEC2		(0x04AC)
 144#define CDC_WSA_RX1_RX_PATH_SEC3		(0x04B0)
 145#define CDC_WSA_RX1_RX_PATH_SEC5		(0x04B8)
 146#define CDC_WSA_RX1_RX_PATH_SEC6		(0x04BC)
 147#define CDC_WSA_RX1_RX_PATH_SEC7		(0x04C0)
 148#define CDC_WSA_RX1_RX_PATH_MIX_SEC0		(0x04C4)
 149#define CDC_WSA_RX1_RX_PATH_MIX_SEC1		(0x04C8)
 150#define CDC_WSA_RX1_RX_PATH_DSMDEM_CTL		(0x04CC)
 151#define CDC_WSA_BOOST0_BOOST_PATH_CTL		(0x0500)
 152#define CDC_WSA_BOOST_PATH_CLK_EN_MASK		BIT(4)
 153#define CDC_WSA_BOOST_PATH_CLK_ENABLE		BIT(4)
 154#define CDC_WSA_BOOST_PATH_CLK_DISABLE		0
 155#define CDC_WSA_BOOST0_BOOST_CTL		(0x0504)
 156#define CDC_WSA_BOOST0_BOOST_CFG1		(0x0508)
 157#define CDC_WSA_BOOST0_BOOST_CFG2		(0x050C)
 158#define CDC_WSA_BOOST1_BOOST_PATH_CTL		(0x0540)
 159#define CDC_WSA_BOOST1_BOOST_CTL		(0x0544)
 160#define CDC_WSA_BOOST1_BOOST_CFG1		(0x0548)
 161#define CDC_WSA_BOOST1_BOOST_CFG2		(0x054C)
 162#define CDC_WSA_COMPANDER0_CTL0			(0x0580)
 163#define CDC_WSA_COMPANDER_CLK_EN_MASK		BIT(0)
 164#define CDC_WSA_COMPANDER_CLK_ENABLE		BIT(0)
 165#define CDC_WSA_COMPANDER_SOFT_RST_MASK		BIT(1)
 166#define CDC_WSA_COMPANDER_SOFT_RST_ENABLE	BIT(1)
 167#define CDC_WSA_COMPANDER_HALT_MASK		BIT(2)
 168#define CDC_WSA_COMPANDER_HALT			BIT(2)
 169#define CDC_WSA_COMPANDER0_CTL1			(0x0584)
 170#define CDC_WSA_COMPANDER0_CTL2			(0x0588)
 171#define CDC_WSA_COMPANDER0_CTL3			(0x058C)
 172#define CDC_WSA_COMPANDER0_CTL4			(0x0590)
 173#define CDC_WSA_COMPANDER0_CTL5			(0x0594)
 174#define CDC_WSA_COMPANDER0_CTL6			(0x0598)
 175#define CDC_WSA_COMPANDER0_CTL7			(0x059C)
 176#define CDC_WSA_COMPANDER1_CTL0			(0x05C0)
 177#define CDC_WSA_COMPANDER1_CTL1			(0x05C4)
 178#define CDC_WSA_COMPANDER1_CTL2			(0x05C8)
 179#define CDC_WSA_COMPANDER1_CTL3			(0x05CC)
 180#define CDC_WSA_COMPANDER1_CTL4			(0x05D0)
 181#define CDC_WSA_COMPANDER1_CTL5			(0x05D4)
 182#define CDC_WSA_COMPANDER1_CTL6			(0x05D8)
 183#define CDC_WSA_COMPANDER1_CTL7			(0x05DC)
 184#define CDC_WSA_SOFTCLIP0_CRC			(0x0600)
 185#define CDC_WSA_SOFTCLIP_CLK_EN_MASK		BIT(0)
 186#define CDC_WSA_SOFTCLIP_CLK_ENABLE		BIT(0)
 187#define CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL		(0x0604)
 188#define CDC_WSA_SOFTCLIP_EN_MASK		BIT(0)
 189#define CDC_WSA_SOFTCLIP_ENABLE			BIT(0)
 190#define CDC_WSA_SOFTCLIP1_CRC			(0x0640)
 191#define CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL		(0x0644)
 192#define CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL	(0x0680)
 193#define CDC_WSA_EC_HQ_EC_CLK_EN_MASK		BIT(0)
 194#define CDC_WSA_EC_HQ_EC_CLK_ENABLE		BIT(0)
 195#define CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0		(0x0684)
 196#define CDC_WSA_EC_HQ_EC_REF_PCM_RATE_MASK	GENMASK(4, 1)
 197#define CDC_WSA_EC_HQ_EC_REF_PCM_RATE_48K	BIT(3)
 198#define CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL	(0x06C0)
 199#define CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0		(0x06C4)
 200#define CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL	(0x0700)
 201#define CDC_WSA_SPLINE_ASRC0_CTL0		(0x0704)
 202#define CDC_WSA_SPLINE_ASRC0_CTL1		(0x0708)
 203#define CDC_WSA_SPLINE_ASRC0_FIFO_CTL		(0x070C)
 204#define CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB	(0x0710)
 205#define CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB	(0x0714)
 206#define CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB	(0x0718)
 207#define CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB	(0x071C)
 208#define CDC_WSA_SPLINE_ASRC0_STATUS_FIFO		(0x0720)
 209#define CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL		(0x0740)
 210#define CDC_WSA_SPLINE_ASRC1_CTL0		(0x0744)
 211#define CDC_WSA_SPLINE_ASRC1_CTL1		(0x0748)
 212#define CDC_WSA_SPLINE_ASRC1_FIFO_CTL		(0x074C)
 213#define CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB (0x0750)
 214#define CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB (0x0754)
 215#define CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB (0x0758)
 216#define CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB (0x075C)
 217#define CDC_WSA_SPLINE_ASRC1_STATUS_FIFO	(0x0760)
 218#define WSA_MAX_OFFSET				(0x0760)
 219
 220#define WSA_MACRO_RX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
 221			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
 222			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
 223#define WSA_MACRO_RX_MIX_RATES (SNDRV_PCM_RATE_48000 |\
 224			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
 225#define WSA_MACRO_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
 226		SNDRV_PCM_FMTBIT_S24_LE |\
 227		SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
 228
 229#define WSA_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
 230			SNDRV_PCM_RATE_48000)
 231#define WSA_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
 232		SNDRV_PCM_FMTBIT_S24_LE |\
 233		SNDRV_PCM_FMTBIT_S24_3LE)
 234
 235#define NUM_INTERPOLATORS 2
 236#define WSA_NUM_CLKS_MAX	5
 237#define WSA_MACRO_MCLK_FREQ 19200000
 238#define WSA_MACRO_MUX_INP_MASK2 0x38
 239#define WSA_MACRO_MUX_CFG_OFFSET 0x8
 240#define WSA_MACRO_MUX_CFG1_OFFSET 0x4
 241#define WSA_MACRO_RX_COMP_OFFSET 0x40
 242#define WSA_MACRO_RX_SOFTCLIP_OFFSET 0x40
 243#define WSA_MACRO_RX_PATH_OFFSET 0x80
 244#define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10
 245#define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C
 246#define WSA_MACRO_FS_RATE_MASK 0x0F
 247#define WSA_MACRO_EC_MIX_TX0_MASK 0x03
 248#define WSA_MACRO_EC_MIX_TX1_MASK 0x18
 249#define WSA_MACRO_MAX_DMA_CH_PER_PORT 0x2
 250
 251enum {
 252	WSA_MACRO_GAIN_OFFSET_M1P5_DB,
 253	WSA_MACRO_GAIN_OFFSET_0_DB,
 254};
 255enum {
 256	WSA_MACRO_RX0 = 0,
 257	WSA_MACRO_RX1,
 258	WSA_MACRO_RX_MIX,
 259	WSA_MACRO_RX_MIX0 = WSA_MACRO_RX_MIX,
 260	WSA_MACRO_RX_MIX1,
 261	WSA_MACRO_RX_MAX,
 262};
 263
 264enum {
 265	WSA_MACRO_TX0 = 0,
 266	WSA_MACRO_TX1,
 267	WSA_MACRO_TX_MAX,
 268};
 269
 270enum {
 271	WSA_MACRO_EC0_MUX = 0,
 272	WSA_MACRO_EC1_MUX,
 273	WSA_MACRO_EC_MUX_MAX,
 274};
 275
 276enum {
 277	WSA_MACRO_COMP1, /* SPK_L */
 278	WSA_MACRO_COMP2, /* SPK_R */
 279	WSA_MACRO_COMP_MAX
 280};
 281
 282enum {
 283	WSA_MACRO_SOFTCLIP0, /* RX0 */
 284	WSA_MACRO_SOFTCLIP1, /* RX1 */
 285	WSA_MACRO_SOFTCLIP_MAX
 286};
 287
 288enum {
 289	INTn_1_INP_SEL_ZERO = 0,
 290	INTn_1_INP_SEL_RX0,
 291	INTn_1_INP_SEL_RX1,
 292	INTn_1_INP_SEL_RX2,
 293	INTn_1_INP_SEL_RX3,
 294	INTn_1_INP_SEL_DEC0,
 295	INTn_1_INP_SEL_DEC1,
 296};
 297
 298enum {
 299	INTn_2_INP_SEL_ZERO = 0,
 300	INTn_2_INP_SEL_RX0,
 301	INTn_2_INP_SEL_RX1,
 302	INTn_2_INP_SEL_RX2,
 303	INTn_2_INP_SEL_RX3,
 304};
 305
 306struct interp_sample_rate {
 307	int sample_rate;
 308	int rate_val;
 309};
 310
 311static struct interp_sample_rate int_prim_sample_rate_val[] = {
 312	{8000, 0x0},	/* 8K */
 313	{16000, 0x1},	/* 16K */
 314	{24000, -EINVAL},/* 24K */
 315	{32000, 0x3},	/* 32K */
 316	{48000, 0x4},	/* 48K */
 317	{96000, 0x5},	/* 96K */
 318	{192000, 0x6},	/* 192K */
 319	{384000, 0x7},	/* 384K */
 320	{44100, 0x8}, /* 44.1K */
 321};
 322
 323static struct interp_sample_rate int_mix_sample_rate_val[] = {
 324	{48000, 0x4},	/* 48K */
 325	{96000, 0x5},	/* 96K */
 326	{192000, 0x6},	/* 192K */
 327};
 328
 329enum {
 330	WSA_MACRO_AIF_INVALID = 0,
 331	WSA_MACRO_AIF1_PB,
 332	WSA_MACRO_AIF_MIX1_PB,
 333	WSA_MACRO_AIF_VI,
 334	WSA_MACRO_AIF_ECHO,
 335	WSA_MACRO_MAX_DAIS,
 336};
 337
 338struct wsa_macro {
 339	struct device *dev;
 340	int comp_enabled[WSA_MACRO_COMP_MAX];
 341	int ec_hq[WSA_MACRO_RX1 + 1];
 342	u16 prim_int_users[WSA_MACRO_RX1 + 1];
 343	u16 wsa_mclk_users;
 344	unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS];
 345	unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS];
 346	int rx_port_value[WSA_MACRO_RX_MAX];
 347	int ear_spkr_gain;
 348	int spkr_gain_offset;
 349	int spkr_mode;
 350	int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX];
 351	int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX];
 352	struct regmap *regmap;
 353	struct clk *mclk;
 354	struct clk *npl;
 355	struct clk *macro;
 356	struct clk *dcodec;
 357	struct clk *fsgen;
 358	struct clk_hw hw;
 359};
 360#define to_wsa_macro(_hw) container_of(_hw, struct wsa_macro, hw)
 361
 362static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
 363
 364static const char *const rx_text[] = {
 365	"ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1"
 366};
 367
 368static const char *const rx_mix_text[] = {
 369	"ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1"
 370};
 371
 372static const char *const rx_mix_ec_text[] = {
 373	"ZERO", "RX_MIX_TX0", "RX_MIX_TX1"
 374};
 375
 376static const char *const rx_mux_text[] = {
 377	"ZERO", "AIF1_PB", "AIF_MIX1_PB"
 378};
 379
 380static const char *const rx_sidetone_mix_text[] = {
 381	"ZERO", "SRC0"
 382};
 383
 384static const char * const wsa_macro_ear_spkr_pa_gain_text[] = {
 385	"G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB",
 386	"G_4_DB", "G_5_DB", "G_6_DB"
 387};
 388
 389static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum,
 390				wsa_macro_ear_spkr_pa_gain_text);
 391
 392/* RX INT0 */
 393static const struct soc_enum rx0_prim_inp0_chain_enum =
 394	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
 395		0, 7, rx_text);
 396
 397static const struct soc_enum rx0_prim_inp1_chain_enum =
 398	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,
 399		3, 7, rx_text);
 400
 401static const struct soc_enum rx0_prim_inp2_chain_enum =
 402	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
 403		3, 7, rx_text);
 404
 405static const struct soc_enum rx0_mix_chain_enum =
 406	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,
 407		0, 5, rx_mix_text);
 408
 409static const struct soc_enum rx0_sidetone_mix_enum =
 410	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text);
 411
 412static const struct snd_kcontrol_new rx0_prim_inp0_mux =
 413	SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum);
 414
 415static const struct snd_kcontrol_new rx0_prim_inp1_mux =
 416	SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum);
 417
 418static const struct snd_kcontrol_new rx0_prim_inp2_mux =
 419	SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum);
 420
 421static const struct snd_kcontrol_new rx0_mix_mux =
 422	SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum);
 423
 424static const struct snd_kcontrol_new rx0_sidetone_mix_mux =
 425	SOC_DAPM_ENUM("WSA_RX0 SIDETONE MIX Mux", rx0_sidetone_mix_enum);
 426
 427/* RX INT1 */
 428static const struct soc_enum rx1_prim_inp0_chain_enum =
 429	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
 430		0, 7, rx_text);
 431
 432static const struct soc_enum rx1_prim_inp1_chain_enum =
 433	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,
 434		3, 7, rx_text);
 435
 436static const struct soc_enum rx1_prim_inp2_chain_enum =
 437	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
 438		3, 7, rx_text);
 439
 440static const struct soc_enum rx1_mix_chain_enum =
 441	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,
 442		0, 5, rx_mix_text);
 443
 444static const struct snd_kcontrol_new rx1_prim_inp0_mux =
 445	SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum);
 446
 447static const struct snd_kcontrol_new rx1_prim_inp1_mux =
 448	SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum);
 449
 450static const struct snd_kcontrol_new rx1_prim_inp2_mux =
 451	SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum);
 452
 453static const struct snd_kcontrol_new rx1_mix_mux =
 454	SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum);
 455
 456static const struct soc_enum rx_mix_ec0_enum =
 457	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
 458		0, 3, rx_mix_ec_text);
 459
 460static const struct soc_enum rx_mix_ec1_enum =
 461	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,
 462		3, 3, rx_mix_ec_text);
 463
 464static const struct snd_kcontrol_new rx_mix_ec0_mux =
 465	SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum);
 466
 467static const struct snd_kcontrol_new rx_mix_ec1_mux =
 468	SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum);
 469
 470static const struct reg_default wsa_defaults[] = {
 471	/* WSA Macro */
 472	{ CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL, 0x00},
 473	{ CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},
 474	{ CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x00},
 475	{ CDC_WSA_TOP_TOP_CFG0, 0x00},
 476	{ CDC_WSA_TOP_TOP_CFG1, 0x00},
 477	{ CDC_WSA_TOP_FREQ_MCLK, 0x00},
 478	{ CDC_WSA_TOP_DEBUG_BUS_SEL, 0x00},
 479	{ CDC_WSA_TOP_DEBUG_EN0, 0x00},
 480	{ CDC_WSA_TOP_DEBUG_EN1, 0x00},
 481	{ CDC_WSA_TOP_DEBUG_DSM_LB, 0x88},
 482	{ CDC_WSA_TOP_RX_I2S_CTL, 0x0C},
 483	{ CDC_WSA_TOP_TX_I2S_CTL, 0x0C},
 484	{ CDC_WSA_TOP_I2S_CLK, 0x02},
 485	{ CDC_WSA_TOP_I2S_RESET, 0x00},
 486	{ CDC_WSA_RX_INP_MUX_RX_INT0_CFG0, 0x00},
 487	{ CDC_WSA_RX_INP_MUX_RX_INT0_CFG1, 0x00},
 488	{ CDC_WSA_RX_INP_MUX_RX_INT1_CFG0, 0x00},
 489	{ CDC_WSA_RX_INP_MUX_RX_INT1_CFG1, 0x00},
 490	{ CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, 0x00},
 491	{ CDC_WSA_RX_INP_MUX_RX_EC_CFG0, 0x00},
 492	{ CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, 0x00},
 493	{ CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x02},
 494	{ CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x00},
 495	{ CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x02},
 496	{ CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x00},
 497	{ CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x02},
 498	{ CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x00},
 499	{ CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x02},
 500	{ CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x00},
 501	{ CDC_WSA_INTR_CTRL_CFG, 0x00},
 502	{ CDC_WSA_INTR_CTRL_CLR_COMMIT, 0x00},
 503	{ CDC_WSA_INTR_CTRL_PIN1_MASK0, 0xFF},
 504	{ CDC_WSA_INTR_CTRL_PIN1_STATUS0, 0x00},
 505	{ CDC_WSA_INTR_CTRL_PIN1_CLEAR0, 0x00},
 506	{ CDC_WSA_INTR_CTRL_PIN2_MASK0, 0xFF},
 507	{ CDC_WSA_INTR_CTRL_PIN2_STATUS0, 0x00},
 508	{ CDC_WSA_INTR_CTRL_PIN2_CLEAR0, 0x00},
 509	{ CDC_WSA_INTR_CTRL_LEVEL0, 0x00},
 510	{ CDC_WSA_INTR_CTRL_BYPASS0, 0x00},
 511	{ CDC_WSA_INTR_CTRL_SET0, 0x00},
 512	{ CDC_WSA_RX0_RX_PATH_CTL, 0x04},
 513	{ CDC_WSA_RX0_RX_PATH_CFG0, 0x00},
 514	{ CDC_WSA_RX0_RX_PATH_CFG1, 0x64},
 515	{ CDC_WSA_RX0_RX_PATH_CFG2, 0x8F},
 516	{ CDC_WSA_RX0_RX_PATH_CFG3, 0x00},
 517	{ CDC_WSA_RX0_RX_VOL_CTL, 0x00},
 518	{ CDC_WSA_RX0_RX_PATH_MIX_CTL, 0x04},
 519	{ CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x7E},
 520	{ CDC_WSA_RX0_RX_VOL_MIX_CTL, 0x00},
 521	{ CDC_WSA_RX0_RX_PATH_SEC0, 0x04},
 522	{ CDC_WSA_RX0_RX_PATH_SEC1, 0x08},
 523	{ CDC_WSA_RX0_RX_PATH_SEC2, 0x00},
 524	{ CDC_WSA_RX0_RX_PATH_SEC3, 0x00},
 525	{ CDC_WSA_RX0_RX_PATH_SEC5, 0x00},
 526	{ CDC_WSA_RX0_RX_PATH_SEC6, 0x00},
 527	{ CDC_WSA_RX0_RX_PATH_SEC7, 0x00},
 528	{ CDC_WSA_RX0_RX_PATH_MIX_SEC0, 0x08},
 529	{ CDC_WSA_RX0_RX_PATH_MIX_SEC1, 0x00},
 530	{ CDC_WSA_RX0_RX_PATH_DSMDEM_CTL, 0x00},
 531	{ CDC_WSA_RX1_RX_PATH_CFG0, 0x00},
 532	{ CDC_WSA_RX1_RX_PATH_CFG1, 0x64},
 533	{ CDC_WSA_RX1_RX_PATH_CFG2, 0x8F},
 534	{ CDC_WSA_RX1_RX_PATH_CFG3, 0x00},
 535	{ CDC_WSA_RX1_RX_VOL_CTL, 0x00},
 536	{ CDC_WSA_RX1_RX_PATH_MIX_CTL, 0x04},
 537	{ CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x7E},
 538	{ CDC_WSA_RX1_RX_VOL_MIX_CTL, 0x00},
 539	{ CDC_WSA_RX1_RX_PATH_SEC0, 0x04},
 540	{ CDC_WSA_RX1_RX_PATH_SEC1, 0x08},
 541	{ CDC_WSA_RX1_RX_PATH_SEC2, 0x00},
 542	{ CDC_WSA_RX1_RX_PATH_SEC3, 0x00},
 543	{ CDC_WSA_RX1_RX_PATH_SEC5, 0x00},
 544	{ CDC_WSA_RX1_RX_PATH_SEC6, 0x00},
 545	{ CDC_WSA_RX1_RX_PATH_SEC7, 0x00},
 546	{ CDC_WSA_RX1_RX_PATH_MIX_SEC0, 0x08},
 547	{ CDC_WSA_RX1_RX_PATH_MIX_SEC1, 0x00},
 548	{ CDC_WSA_RX1_RX_PATH_DSMDEM_CTL, 0x00},
 549	{ CDC_WSA_BOOST0_BOOST_PATH_CTL, 0x00},
 550	{ CDC_WSA_BOOST0_BOOST_CTL, 0xD0},
 551	{ CDC_WSA_BOOST0_BOOST_CFG1, 0x89},
 552	{ CDC_WSA_BOOST0_BOOST_CFG2, 0x04},
 553	{ CDC_WSA_BOOST1_BOOST_PATH_CTL, 0x00},
 554	{ CDC_WSA_BOOST1_BOOST_CTL, 0xD0},
 555	{ CDC_WSA_BOOST1_BOOST_CFG1, 0x89},
 556	{ CDC_WSA_BOOST1_BOOST_CFG2, 0x04},
 557	{ CDC_WSA_COMPANDER0_CTL0, 0x60},
 558	{ CDC_WSA_COMPANDER0_CTL1, 0xDB},
 559	{ CDC_WSA_COMPANDER0_CTL2, 0xFF},
 560	{ CDC_WSA_COMPANDER0_CTL3, 0x35},
 561	{ CDC_WSA_COMPANDER0_CTL4, 0xFF},
 562	{ CDC_WSA_COMPANDER0_CTL5, 0x00},
 563	{ CDC_WSA_COMPANDER0_CTL6, 0x01},
 564	{ CDC_WSA_COMPANDER0_CTL7, 0x28},
 565	{ CDC_WSA_COMPANDER1_CTL0, 0x60},
 566	{ CDC_WSA_COMPANDER1_CTL1, 0xDB},
 567	{ CDC_WSA_COMPANDER1_CTL2, 0xFF},
 568	{ CDC_WSA_COMPANDER1_CTL3, 0x35},
 569	{ CDC_WSA_COMPANDER1_CTL4, 0xFF},
 570	{ CDC_WSA_COMPANDER1_CTL5, 0x00},
 571	{ CDC_WSA_COMPANDER1_CTL6, 0x01},
 572	{ CDC_WSA_COMPANDER1_CTL7, 0x28},
 573	{ CDC_WSA_SOFTCLIP0_CRC, 0x00},
 574	{ CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL, 0x38},
 575	{ CDC_WSA_SOFTCLIP1_CRC, 0x00},
 576	{ CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL, 0x38},
 577	{ CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL, 0x00},
 578	{ CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0, 0x01},
 579	{ CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL, 0x00},
 580	{ CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0, 0x01},
 581	{ CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL, 0x00},
 582	{ CDC_WSA_SPLINE_ASRC0_CTL0, 0x00},
 583	{ CDC_WSA_SPLINE_ASRC0_CTL1, 0x00},
 584	{ CDC_WSA_SPLINE_ASRC0_FIFO_CTL, 0xA8},
 585	{ CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00},
 586	{ CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00},
 587	{ CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00},
 588	{ CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00},
 589	{ CDC_WSA_SPLINE_ASRC0_STATUS_FIFO, 0x00},
 590	{ CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL, 0x00},
 591	{ CDC_WSA_SPLINE_ASRC1_CTL0, 0x00},
 592	{ CDC_WSA_SPLINE_ASRC1_CTL1, 0x00},
 593	{ CDC_WSA_SPLINE_ASRC1_FIFO_CTL, 0xA8},
 594	{ CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00},
 595	{ CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00},
 596	{ CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00},
 597	{ CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00},
 598	{ CDC_WSA_SPLINE_ASRC1_STATUS_FIFO, 0x00},
 599};
 600
 601static bool wsa_is_wronly_register(struct device *dev,
 602					unsigned int reg)
 603{
 604	switch (reg) {
 605	case CDC_WSA_INTR_CTRL_CLR_COMMIT:
 606	case CDC_WSA_INTR_CTRL_PIN1_CLEAR0:
 607	case CDC_WSA_INTR_CTRL_PIN2_CLEAR0:
 608		return true;
 609	}
 610
 611	return false;
 612}
 613
 614static bool wsa_is_rw_register(struct device *dev, unsigned int reg)
 615{
 616	switch (reg) {
 617	case CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL:
 618	case CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL:
 619	case CDC_WSA_CLK_RST_CTRL_SWR_CONTROL:
 620	case CDC_WSA_TOP_TOP_CFG0:
 621	case CDC_WSA_TOP_TOP_CFG1:
 622	case CDC_WSA_TOP_FREQ_MCLK:
 623	case CDC_WSA_TOP_DEBUG_BUS_SEL:
 624	case CDC_WSA_TOP_DEBUG_EN0:
 625	case CDC_WSA_TOP_DEBUG_EN1:
 626	case CDC_WSA_TOP_DEBUG_DSM_LB:
 627	case CDC_WSA_TOP_RX_I2S_CTL:
 628	case CDC_WSA_TOP_TX_I2S_CTL:
 629	case CDC_WSA_TOP_I2S_CLK:
 630	case CDC_WSA_TOP_I2S_RESET:
 631	case CDC_WSA_RX_INP_MUX_RX_INT0_CFG0:
 632	case CDC_WSA_RX_INP_MUX_RX_INT0_CFG1:
 633	case CDC_WSA_RX_INP_MUX_RX_INT1_CFG0:
 634	case CDC_WSA_RX_INP_MUX_RX_INT1_CFG1:
 635	case CDC_WSA_RX_INP_MUX_RX_MIX_CFG0:
 636	case CDC_WSA_RX_INP_MUX_RX_EC_CFG0:
 637	case CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0:
 638	case CDC_WSA_TX0_SPKR_PROT_PATH_CTL:
 639	case CDC_WSA_TX0_SPKR_PROT_PATH_CFG0:
 640	case CDC_WSA_TX1_SPKR_PROT_PATH_CTL:
 641	case CDC_WSA_TX1_SPKR_PROT_PATH_CFG0:
 642	case CDC_WSA_TX2_SPKR_PROT_PATH_CTL:
 643	case CDC_WSA_TX2_SPKR_PROT_PATH_CFG0:
 644	case CDC_WSA_TX3_SPKR_PROT_PATH_CTL:
 645	case CDC_WSA_TX3_SPKR_PROT_PATH_CFG0:
 646	case CDC_WSA_INTR_CTRL_CFG:
 647	case CDC_WSA_INTR_CTRL_PIN1_MASK0:
 648	case CDC_WSA_INTR_CTRL_PIN2_MASK0:
 649	case CDC_WSA_INTR_CTRL_LEVEL0:
 650	case CDC_WSA_INTR_CTRL_BYPASS0:
 651	case CDC_WSA_INTR_CTRL_SET0:
 652	case CDC_WSA_RX0_RX_PATH_CTL:
 653	case CDC_WSA_RX0_RX_PATH_CFG0:
 654	case CDC_WSA_RX0_RX_PATH_CFG1:
 655	case CDC_WSA_RX0_RX_PATH_CFG2:
 656	case CDC_WSA_RX0_RX_PATH_CFG3:
 657	case CDC_WSA_RX0_RX_VOL_CTL:
 658	case CDC_WSA_RX0_RX_PATH_MIX_CTL:
 659	case CDC_WSA_RX0_RX_PATH_MIX_CFG:
 660	case CDC_WSA_RX0_RX_VOL_MIX_CTL:
 661	case CDC_WSA_RX0_RX_PATH_SEC0:
 662	case CDC_WSA_RX0_RX_PATH_SEC1:
 663	case CDC_WSA_RX0_RX_PATH_SEC2:
 664	case CDC_WSA_RX0_RX_PATH_SEC3:
 665	case CDC_WSA_RX0_RX_PATH_SEC5:
 666	case CDC_WSA_RX0_RX_PATH_SEC6:
 667	case CDC_WSA_RX0_RX_PATH_SEC7:
 668	case CDC_WSA_RX0_RX_PATH_MIX_SEC0:
 669	case CDC_WSA_RX0_RX_PATH_MIX_SEC1:
 670	case CDC_WSA_RX0_RX_PATH_DSMDEM_CTL:
 671	case CDC_WSA_RX1_RX_PATH_CTL:
 672	case CDC_WSA_RX1_RX_PATH_CFG0:
 673	case CDC_WSA_RX1_RX_PATH_CFG1:
 674	case CDC_WSA_RX1_RX_PATH_CFG2:
 675	case CDC_WSA_RX1_RX_PATH_CFG3:
 676	case CDC_WSA_RX1_RX_VOL_CTL:
 677	case CDC_WSA_RX1_RX_PATH_MIX_CTL:
 678	case CDC_WSA_RX1_RX_PATH_MIX_CFG:
 679	case CDC_WSA_RX1_RX_VOL_MIX_CTL:
 680	case CDC_WSA_RX1_RX_PATH_SEC0:
 681	case CDC_WSA_RX1_RX_PATH_SEC1:
 682	case CDC_WSA_RX1_RX_PATH_SEC2:
 683	case CDC_WSA_RX1_RX_PATH_SEC3:
 684	case CDC_WSA_RX1_RX_PATH_SEC5:
 685	case CDC_WSA_RX1_RX_PATH_SEC6:
 686	case CDC_WSA_RX1_RX_PATH_SEC7:
 687	case CDC_WSA_RX1_RX_PATH_MIX_SEC0:
 688	case CDC_WSA_RX1_RX_PATH_MIX_SEC1:
 689	case CDC_WSA_RX1_RX_PATH_DSMDEM_CTL:
 690	case CDC_WSA_BOOST0_BOOST_PATH_CTL:
 691	case CDC_WSA_BOOST0_BOOST_CTL:
 692	case CDC_WSA_BOOST0_BOOST_CFG1:
 693	case CDC_WSA_BOOST0_BOOST_CFG2:
 694	case CDC_WSA_BOOST1_BOOST_PATH_CTL:
 695	case CDC_WSA_BOOST1_BOOST_CTL:
 696	case CDC_WSA_BOOST1_BOOST_CFG1:
 697	case CDC_WSA_BOOST1_BOOST_CFG2:
 698	case CDC_WSA_COMPANDER0_CTL0:
 699	case CDC_WSA_COMPANDER0_CTL1:
 700	case CDC_WSA_COMPANDER0_CTL2:
 701	case CDC_WSA_COMPANDER0_CTL3:
 702	case CDC_WSA_COMPANDER0_CTL4:
 703	case CDC_WSA_COMPANDER0_CTL5:
 704	case CDC_WSA_COMPANDER0_CTL7:
 705	case CDC_WSA_COMPANDER1_CTL0:
 706	case CDC_WSA_COMPANDER1_CTL1:
 707	case CDC_WSA_COMPANDER1_CTL2:
 708	case CDC_WSA_COMPANDER1_CTL3:
 709	case CDC_WSA_COMPANDER1_CTL4:
 710	case CDC_WSA_COMPANDER1_CTL5:
 711	case CDC_WSA_COMPANDER1_CTL7:
 712	case CDC_WSA_SOFTCLIP0_CRC:
 713	case CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL:
 714	case CDC_WSA_SOFTCLIP1_CRC:
 715	case CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL:
 716	case CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL:
 717	case CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0:
 718	case CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL:
 719	case CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0:
 720	case CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL:
 721	case CDC_WSA_SPLINE_ASRC0_CTL0:
 722	case CDC_WSA_SPLINE_ASRC0_CTL1:
 723	case CDC_WSA_SPLINE_ASRC0_FIFO_CTL:
 724	case CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL:
 725	case CDC_WSA_SPLINE_ASRC1_CTL0:
 726	case CDC_WSA_SPLINE_ASRC1_CTL1:
 727	case CDC_WSA_SPLINE_ASRC1_FIFO_CTL:
 728		return true;
 729	}
 730
 731	return false;
 732}
 733
 734static bool wsa_is_writeable_register(struct device *dev, unsigned int reg)
 735{
 736	bool ret;
 737
 738	ret = wsa_is_rw_register(dev, reg);
 739	if (!ret)
 740		return wsa_is_wronly_register(dev, reg);
 741
 742	return ret;
 743}
 744
 745static bool wsa_is_readable_register(struct device *dev, unsigned int reg)
 746{
 747	switch (reg) {
 748	case CDC_WSA_INTR_CTRL_CLR_COMMIT:
 749	case CDC_WSA_INTR_CTRL_PIN1_CLEAR0:
 750	case CDC_WSA_INTR_CTRL_PIN2_CLEAR0:
 751	case CDC_WSA_INTR_CTRL_PIN1_STATUS0:
 752	case CDC_WSA_INTR_CTRL_PIN2_STATUS0:
 753	case CDC_WSA_COMPANDER0_CTL6:
 754	case CDC_WSA_COMPANDER1_CTL6:
 755	case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB:
 756	case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB:
 757	case CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB:
 758	case CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB:
 759	case CDC_WSA_SPLINE_ASRC0_STATUS_FIFO:
 760	case CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB:
 761	case CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB:
 762	case CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB:
 763	case CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB:
 764	case CDC_WSA_SPLINE_ASRC1_STATUS_FIFO:
 765		return true;
 766	}
 767
 768	return wsa_is_rw_register(dev, reg);
 769}
 770
 771static bool wsa_is_volatile_register(struct device *dev, unsigned int reg)
 772{
 773	/* Update volatile list for rx/tx macros */
 774	switch (reg) {
 775	case CDC_WSA_INTR_CTRL_PIN1_STATUS0:
 776	case CDC_WSA_INTR_CTRL_PIN2_STATUS0:
 777	case CDC_WSA_COMPANDER0_CTL6:
 778	case CDC_WSA_COMPANDER1_CTL6:
 779	case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB:
 780	case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB:
 781	case CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB:
 782	case CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB:
 783	case CDC_WSA_SPLINE_ASRC0_STATUS_FIFO:
 784	case CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB:
 785	case CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB:
 786	case CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB:
 787	case CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB:
 788	case CDC_WSA_SPLINE_ASRC1_STATUS_FIFO:
 789		return true;
 790	}
 791	return false;
 792}
 793
 794static const struct regmap_config wsa_regmap_config = {
 795	.name = "wsa_macro",
 796	.reg_bits = 16,
 797	.val_bits = 32, /* 8 but with 32 bit read/write */
 798	.reg_stride = 4,
 799	.cache_type = REGCACHE_FLAT,
 800	.reg_defaults = wsa_defaults,
 801	.num_reg_defaults = ARRAY_SIZE(wsa_defaults),
 802	.max_register = WSA_MAX_OFFSET,
 803	.writeable_reg = wsa_is_writeable_register,
 804	.volatile_reg = wsa_is_volatile_register,
 805	.readable_reg = wsa_is_readable_register,
 806};
 807
 808/**
 809 * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost
 810 * settings based on speaker mode.
 811 *
 812 * @component: codec instance
 813 * @mode: Indicates speaker configuration mode.
 814 *
 815 * Returns 0 on success or -EINVAL on error.
 816 */
 817int wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode)
 818{
 819	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
 820
 821	wsa->spkr_mode = mode;
 822
 823	switch (mode) {
 824	case WSA_MACRO_SPKR_MODE_1:
 825		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00);
 826		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00);
 827		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00);
 828		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00);
 829		snd_soc_component_update_bits(component, CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44);
 830		snd_soc_component_update_bits(component, CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44);
 831		break;
 832	default:
 833		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80);
 834		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80);
 835		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01);
 836		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01);
 837		snd_soc_component_update_bits(component, CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58);
 838		snd_soc_component_update_bits(component, CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58);
 839		break;
 840	}
 841	return 0;
 842}
 843EXPORT_SYMBOL(wsa_macro_set_spkr_mode);
 844
 845static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
 846						u8 int_prim_fs_rate_reg_val,
 847						u32 sample_rate)
 848{
 849	u8 int_1_mix1_inp;
 850	u32 j, port;
 851	u16 int_mux_cfg0, int_mux_cfg1;
 852	u16 int_fs_reg;
 853	u8 inp0_sel, inp1_sel, inp2_sel;
 854	struct snd_soc_component *component = dai->component;
 855	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
 856
 857	for_each_set_bit(port, &wsa->active_ch_mask[dai->id], WSA_MACRO_RX_MAX) {
 858		int_1_mix1_inp = port;
 859		if ((int_1_mix1_inp < WSA_MACRO_RX0) || (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) {
 860			dev_err(component->dev,	"%s: Invalid RX port, Dai ID is %d\n",
 861				__func__, dai->id);
 862			return -EINVAL;
 863		}
 864
 865		int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0;
 866
 867		/*
 868		 * Loop through all interpolator MUX inputs and find out
 869		 * to which interpolator input, the cdc_dma rx port
 870		 * is connected
 871		 */
 872		for (j = 0; j < NUM_INTERPOLATORS; j++) {
 873			int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET;
 874			inp0_sel = snd_soc_component_read_field(component, int_mux_cfg0, 
 875								CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK);
 876			inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0, 
 877								CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK);
 878			inp2_sel = snd_soc_component_read_field(component, int_mux_cfg1,
 879								CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK);
 880
 881			if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
 882			    (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
 883			    (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) {
 884				int_fs_reg = CDC_WSA_RX0_RX_PATH_CTL +
 885					     WSA_MACRO_RX_PATH_OFFSET * j;
 886				/* sample_rate is in Hz */
 887				snd_soc_component_update_bits(component, int_fs_reg,
 888							      WSA_MACRO_FS_RATE_MASK,
 889							      int_prim_fs_rate_reg_val);
 890			}
 891			int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET;
 892		}
 893	}
 894
 895	return 0;
 896}
 897
 898static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
 899					       u8 int_mix_fs_rate_reg_val,
 900					       u32 sample_rate)
 901{
 902	u8 int_2_inp;
 903	u32 j, port;
 904	u16 int_mux_cfg1, int_fs_reg;
 905	u8 int_mux_cfg1_val;
 906	struct snd_soc_component *component = dai->component;
 907	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
 908
 909	for_each_set_bit(port, &wsa->active_ch_mask[dai->id], WSA_MACRO_RX_MAX) {
 910		int_2_inp = port;
 911		if ((int_2_inp < WSA_MACRO_RX0) || (int_2_inp > WSA_MACRO_RX_MIX1)) {
 912			dev_err(component->dev,	"%s: Invalid RX port, Dai ID is %d\n",
 913				__func__, dai->id);
 914			return -EINVAL;
 915		}
 916
 917		int_mux_cfg1 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;
 918		for (j = 0; j < NUM_INTERPOLATORS; j++) {
 919			int_mux_cfg1_val = snd_soc_component_read_field(component, int_mux_cfg1,
 920									CDC_WSA_RX_INTX_2_SEL_MASK);
 921
 922			if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) {
 923				int_fs_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL +
 924					WSA_MACRO_RX_PATH_OFFSET * j;
 925
 926				snd_soc_component_update_bits(component,
 927						      int_fs_reg,
 928						      WSA_MACRO_FS_RATE_MASK,
 929						      int_mix_fs_rate_reg_val);
 930			}
 931			int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET;
 932		}
 933	}
 934	return 0;
 935}
 936
 937static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai,
 938					   u32 sample_rate)
 939{
 940	int rate_val = 0;
 941	int i, ret;
 942
 943	/* set mixing path rate */
 944	for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {
 945		if (sample_rate == int_mix_sample_rate_val[i].sample_rate) {
 946			rate_val = int_mix_sample_rate_val[i].rate_val;
 947			break;
 948		}
 949	}
 950	if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) || (rate_val < 0))
 951		goto prim_rate;
 952
 953	ret = wsa_macro_set_mix_interpolator_rate(dai, (u8) rate_val, sample_rate);
 954	if (ret < 0)
 955		return ret;
 956prim_rate:
 957	/* set primary path sample rate */
 958	for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {
 959		if (sample_rate == int_prim_sample_rate_val[i].sample_rate) {
 960			rate_val = int_prim_sample_rate_val[i].rate_val;
 961			break;
 962		}
 963	}
 964	if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) || (rate_val < 0))
 965		return -EINVAL;
 966
 967	ret = wsa_macro_set_prim_interpolator_rate(dai, (u8) rate_val, sample_rate);
 968
 969	return ret;
 970}
 971
 972static int wsa_macro_hw_params(struct snd_pcm_substream *substream,
 973			       struct snd_pcm_hw_params *params,
 974			       struct snd_soc_dai *dai)
 975{
 976	struct snd_soc_component *component = dai->component;
 977	int ret;
 978
 979	switch (substream->stream) {
 980	case SNDRV_PCM_STREAM_PLAYBACK:
 981		ret = wsa_macro_set_interpolator_rate(dai, params_rate(params));
 982		if (ret) {
 983			dev_err(component->dev,
 984				"%s: cannot set sample rate: %u\n",
 985				__func__, params_rate(params));
 986			return ret;
 987		}
 988		break;
 989	default:
 990		break;
 991	}
 992	return 0;
 993}
 994
 995static int wsa_macro_get_channel_map(struct snd_soc_dai *dai,
 996				     unsigned int *tx_num, unsigned int *tx_slot,
 997				     unsigned int *rx_num, unsigned int *rx_slot)
 998{
 999	struct snd_soc_component *component = dai->component;
1000	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1001	u16 val, mask = 0, cnt = 0, temp;
1002
1003	switch (dai->id) {
1004	case WSA_MACRO_AIF_VI:
1005		*tx_slot = wsa->active_ch_mask[dai->id];
1006		*tx_num = wsa->active_ch_cnt[dai->id];
1007		break;
1008	case WSA_MACRO_AIF1_PB:
1009	case WSA_MACRO_AIF_MIX1_PB:
1010		for_each_set_bit(temp, &wsa->active_ch_mask[dai->id],
1011					WSA_MACRO_RX_MAX) {
1012			mask |= (1 << temp);
1013			if (++cnt == WSA_MACRO_MAX_DMA_CH_PER_PORT)
1014				break;
1015		}
1016		if (mask & 0x0C)
1017			mask = mask >> 0x2;
1018		*rx_slot = mask;
1019		*rx_num = cnt;
1020		break;
1021	case WSA_MACRO_AIF_ECHO:
1022		val = snd_soc_component_read(component, CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
1023		if (val & WSA_MACRO_EC_MIX_TX1_MASK) {
1024			mask |= 0x2;
1025			cnt++;
1026		}
1027		if (val & WSA_MACRO_EC_MIX_TX0_MASK) {
1028			mask |= 0x1;
1029			cnt++;
1030		}
1031		*tx_slot = mask;
1032		*tx_num = cnt;
1033		break;
1034	default:
1035		dev_err(component->dev, "%s: Invalid AIF\n", __func__);
1036		break;
1037	}
1038	return 0;
1039}
1040
1041static const struct snd_soc_dai_ops wsa_macro_dai_ops = {
1042	.hw_params = wsa_macro_hw_params,
1043	.get_channel_map = wsa_macro_get_channel_map,
1044};
1045
1046static struct snd_soc_dai_driver wsa_macro_dai[] = {
1047	{
1048		.name = "wsa_macro_rx1",
1049		.id = WSA_MACRO_AIF1_PB,
1050		.playback = {
1051			.stream_name = "WSA_AIF1 Playback",
1052			.rates = WSA_MACRO_RX_RATES,
1053			.formats = WSA_MACRO_RX_FORMATS,
1054			.rate_max = 384000,
1055			.rate_min = 8000,
1056			.channels_min = 1,
1057			.channels_max = 2,
1058		},
1059		.ops = &wsa_macro_dai_ops,
1060	},
1061	{
1062		.name = "wsa_macro_rx_mix",
1063		.id = WSA_MACRO_AIF_MIX1_PB,
1064		.playback = {
1065			.stream_name = "WSA_AIF_MIX1 Playback",
1066			.rates = WSA_MACRO_RX_MIX_RATES,
1067			.formats = WSA_MACRO_RX_FORMATS,
1068			.rate_max = 192000,
1069			.rate_min = 48000,
1070			.channels_min = 1,
1071			.channels_max = 2,
1072		},
1073		.ops = &wsa_macro_dai_ops,
1074	},
1075	{
1076		.name = "wsa_macro_vifeedback",
1077		.id = WSA_MACRO_AIF_VI,
1078		.capture = {
1079			.stream_name = "WSA_AIF_VI Capture",
1080			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
1081			.formats = WSA_MACRO_RX_FORMATS,
1082			.rate_max = 48000,
1083			.rate_min = 8000,
1084			.channels_min = 1,
1085			.channels_max = 4,
1086		},
1087		.ops = &wsa_macro_dai_ops,
1088	},
1089	{
1090		.name = "wsa_macro_echo",
1091		.id = WSA_MACRO_AIF_ECHO,
1092		.capture = {
1093			.stream_name = "WSA_AIF_ECHO Capture",
1094			.rates = WSA_MACRO_ECHO_RATES,
1095			.formats = WSA_MACRO_ECHO_FORMATS,
1096			.rate_max = 48000,
1097			.rate_min = 8000,
1098			.channels_min = 1,
1099			.channels_max = 2,
1100		},
1101		.ops = &wsa_macro_dai_ops,
1102	},
1103};
1104
1105static void wsa_macro_mclk_enable(struct wsa_macro *wsa, bool mclk_enable)
1106{
1107	struct regmap *regmap = wsa->regmap;
1108
1109	if (mclk_enable) {
1110		if (wsa->wsa_mclk_users == 0) {
1111			regcache_mark_dirty(regmap);
1112			regcache_sync(regmap);
1113			/* 9.6MHz MCLK, set value 0x00 if other frequency */
1114			regmap_update_bits(regmap, CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01);
1115			regmap_update_bits(regmap,
1116					   CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
1117					   CDC_WSA_MCLK_EN_MASK,
1118					   CDC_WSA_MCLK_ENABLE);
1119			regmap_update_bits(regmap,
1120					   CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
1121					   CDC_WSA_FS_CNT_EN_MASK,
1122					   CDC_WSA_FS_CNT_ENABLE);
1123		}
1124		wsa->wsa_mclk_users++;
1125	} else {
1126		if (wsa->wsa_mclk_users <= 0) {
1127			dev_err(wsa->dev, "clock already disabled\n");
1128			wsa->wsa_mclk_users = 0;
1129			return;
1130		}
1131		wsa->wsa_mclk_users--;
1132		if (wsa->wsa_mclk_users == 0) {
1133			regmap_update_bits(regmap,
1134					   CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,
1135					   CDC_WSA_FS_CNT_EN_MASK,
1136					   CDC_WSA_FS_CNT_DISABLE);
1137			regmap_update_bits(regmap,
1138					   CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,
1139					   CDC_WSA_MCLK_EN_MASK,
1140					   CDC_WSA_MCLK_DISABLE);
1141		}
1142	}
1143}
1144
1145static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,
1146				struct snd_kcontrol *kcontrol, int event)
1147{
1148	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1149	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1150
1151	wsa_macro_mclk_enable(wsa, event == SND_SOC_DAPM_PRE_PMU);
1152	return 0;
1153}
1154
1155static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
1156					struct snd_kcontrol *kcontrol,
1157					int event)
1158{
1159	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1160	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1161	u32 tx_reg0, tx_reg1;
1162
1163	if (test_bit(WSA_MACRO_TX0, &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
1164		tx_reg0 = CDC_WSA_TX0_SPKR_PROT_PATH_CTL;
1165		tx_reg1 = CDC_WSA_TX1_SPKR_PROT_PATH_CTL;
1166	} else if (test_bit(WSA_MACRO_TX1, &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
1167		tx_reg0 = CDC_WSA_TX2_SPKR_PROT_PATH_CTL;
1168		tx_reg1 = CDC_WSA_TX3_SPKR_PROT_PATH_CTL;
1169	}
1170
1171	switch (event) {
1172	case SND_SOC_DAPM_POST_PMU:
1173			/* Enable V&I sensing */
1174		snd_soc_component_update_bits(component, tx_reg0,
1175					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,
1176					      CDC_WSA_TX_SPKR_PROT_RESET);
1177		snd_soc_component_update_bits(component, tx_reg1,
1178					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,
1179					      CDC_WSA_TX_SPKR_PROT_RESET);
1180		snd_soc_component_update_bits(component, tx_reg0,
1181					      CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK,
1182					      CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K);
1183		snd_soc_component_update_bits(component, tx_reg1,
1184					      CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK,
1185					      CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K);
1186		snd_soc_component_update_bits(component, tx_reg0,
1187					      CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
1188					      CDC_WSA_TX_SPKR_PROT_CLK_ENABLE);
1189		snd_soc_component_update_bits(component, tx_reg1,
1190					      CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
1191					      CDC_WSA_TX_SPKR_PROT_CLK_ENABLE);
1192		snd_soc_component_update_bits(component, tx_reg0,
1193					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,
1194					      CDC_WSA_TX_SPKR_PROT_NO_RESET);
1195		snd_soc_component_update_bits(component, tx_reg1,
1196					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,
1197					      CDC_WSA_TX_SPKR_PROT_NO_RESET);
1198		break;
1199	case SND_SOC_DAPM_POST_PMD:
1200		/* Disable V&I sensing */
1201		snd_soc_component_update_bits(component, tx_reg0,
1202					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,
1203					      CDC_WSA_TX_SPKR_PROT_RESET);
1204		snd_soc_component_update_bits(component, tx_reg1,
1205					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,
1206					      CDC_WSA_TX_SPKR_PROT_RESET);
1207		snd_soc_component_update_bits(component, tx_reg0,
1208					      CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
1209					      CDC_WSA_TX_SPKR_PROT_CLK_DISABLE);
1210		snd_soc_component_update_bits(component, tx_reg1,
1211					      CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,
1212					      CDC_WSA_TX_SPKR_PROT_CLK_DISABLE);
1213		break;
1214	}
1215
1216	return 0;
1217}
1218
1219static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
1220				     struct snd_kcontrol *kcontrol, int event)
1221{
1222	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1223	u16 path_reg, gain_reg;
1224	int val;
1225
1226	switch (w->shift) {
1227	case WSA_MACRO_RX_MIX0:
1228		path_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL;
1229		gain_reg = CDC_WSA_RX0_RX_VOL_MIX_CTL;
1230		break;
1231	case WSA_MACRO_RX_MIX1:
1232		path_reg = CDC_WSA_RX1_RX_PATH_MIX_CTL;
1233		gain_reg = CDC_WSA_RX1_RX_VOL_MIX_CTL;
1234		break;
1235	default:
1236		return 0;
1237	}
1238
1239	switch (event) {
1240	case SND_SOC_DAPM_POST_PMU:
1241		val = snd_soc_component_read(component, gain_reg);
1242		snd_soc_component_write(component, gain_reg, val);
1243		break;
1244	case SND_SOC_DAPM_POST_PMD:
1245		snd_soc_component_update_bits(component, path_reg,
1246					      CDC_WSA_RX_PATH_MIX_CLK_EN_MASK,
1247					      CDC_WSA_RX_PATH_MIX_CLK_DISABLE);
1248		break;
1249	}
1250
1251	return 0;
1252}
1253
1254static void wsa_macro_hd2_control(struct snd_soc_component *component,
1255				  u16 reg, int event)
1256{
1257	u16 hd2_scale_reg;
1258	u16 hd2_enable_reg;
1259
1260	if (reg == CDC_WSA_RX0_RX_PATH_CTL) {
1261		hd2_scale_reg = CDC_WSA_RX0_RX_PATH_SEC3;
1262		hd2_enable_reg = CDC_WSA_RX0_RX_PATH_CFG0;
1263	}
1264	if (reg == CDC_WSA_RX1_RX_PATH_CTL) {
1265		hd2_scale_reg = CDC_WSA_RX1_RX_PATH_SEC3;
1266		hd2_enable_reg = CDC_WSA_RX1_RX_PATH_CFG0;
1267	}
1268
1269	if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
1270		snd_soc_component_update_bits(component, hd2_scale_reg,
1271					      CDC_WSA_RX_PATH_HD2_ALPHA_MASK,
1272					      0x10);
1273		snd_soc_component_update_bits(component, hd2_scale_reg,
1274					      CDC_WSA_RX_PATH_HD2_SCALE_MASK,
1275					      0x1);
1276		snd_soc_component_update_bits(component, hd2_enable_reg,
1277					      CDC_WSA_RX_PATH_HD2_EN_MASK,
1278					      CDC_WSA_RX_PATH_HD2_ENABLE);
1279	}
1280
1281	if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
1282		snd_soc_component_update_bits(component, hd2_enable_reg,
1283					      CDC_WSA_RX_PATH_HD2_EN_MASK, 0);
1284		snd_soc_component_update_bits(component, hd2_scale_reg,
1285					      CDC_WSA_RX_PATH_HD2_SCALE_MASK,
1286					      0);
1287		snd_soc_component_update_bits(component, hd2_scale_reg,
1288					      CDC_WSA_RX_PATH_HD2_ALPHA_MASK,
1289					      0);
1290	}
1291}
1292
1293static int wsa_macro_config_compander(struct snd_soc_component *component,
1294				      int comp, int event)
1295{
1296	u16 comp_ctl0_reg, rx_path_cfg0_reg;
1297	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1298
1299	if (!wsa->comp_enabled[comp])
1300		return 0;
1301
1302	comp_ctl0_reg = CDC_WSA_COMPANDER0_CTL0 +
1303					(comp * WSA_MACRO_RX_COMP_OFFSET);
1304	rx_path_cfg0_reg = CDC_WSA_RX0_RX_PATH_CFG0 +
1305					(comp * WSA_MACRO_RX_PATH_OFFSET);
1306
1307	if (SND_SOC_DAPM_EVENT_ON(event)) {
1308		/* Enable Compander Clock */
1309		snd_soc_component_update_bits(component, comp_ctl0_reg,
1310					      CDC_WSA_COMPANDER_CLK_EN_MASK,
1311					      CDC_WSA_COMPANDER_CLK_ENABLE);
1312		snd_soc_component_update_bits(component, comp_ctl0_reg,
1313					      CDC_WSA_COMPANDER_SOFT_RST_MASK,
1314					      CDC_WSA_COMPANDER_SOFT_RST_ENABLE);
1315		snd_soc_component_update_bits(component, comp_ctl0_reg,
1316					      CDC_WSA_COMPANDER_SOFT_RST_MASK,
1317					      0);
1318		snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1319					      CDC_WSA_RX_PATH_COMP_EN_MASK,
1320					      CDC_WSA_RX_PATH_COMP_ENABLE);
1321	}
1322
1323	if (SND_SOC_DAPM_EVENT_OFF(event)) {
1324		snd_soc_component_update_bits(component, comp_ctl0_reg,
1325					      CDC_WSA_COMPANDER_HALT_MASK,
1326					      CDC_WSA_COMPANDER_HALT);
1327		snd_soc_component_update_bits(component, rx_path_cfg0_reg,
1328					      CDC_WSA_RX_PATH_COMP_EN_MASK, 0);
1329		snd_soc_component_update_bits(component, comp_ctl0_reg,
1330					      CDC_WSA_COMPANDER_SOFT_RST_MASK,
1331					      CDC_WSA_COMPANDER_SOFT_RST_ENABLE);
1332		snd_soc_component_update_bits(component, comp_ctl0_reg,
1333					      CDC_WSA_COMPANDER_SOFT_RST_MASK,
1334					      0);
1335		snd_soc_component_update_bits(component, comp_ctl0_reg,
1336					      CDC_WSA_COMPANDER_CLK_EN_MASK, 0);
1337		snd_soc_component_update_bits(component, comp_ctl0_reg,
1338					      CDC_WSA_COMPANDER_HALT_MASK, 0);
1339	}
1340
1341	return 0;
1342}
1343
1344static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component,
1345					 struct wsa_macro *wsa,
1346					 int path,
1347					 bool enable)
1348{
1349	u16 softclip_clk_reg = CDC_WSA_SOFTCLIP0_CRC +
1350			(path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1351	u8 softclip_mux_mask = (1 << path);
1352	u8 softclip_mux_value = (1 << path);
1353
1354	if (enable) {
1355		if (wsa->softclip_clk_users[path] == 0) {
1356			snd_soc_component_update_bits(component,
1357						softclip_clk_reg,
1358						CDC_WSA_SOFTCLIP_CLK_EN_MASK,
1359						CDC_WSA_SOFTCLIP_CLK_ENABLE);
1360			snd_soc_component_update_bits(component,
1361				CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1362				softclip_mux_mask, softclip_mux_value);
1363		}
1364		wsa->softclip_clk_users[path]++;
1365	} else {
1366		wsa->softclip_clk_users[path]--;
1367		if (wsa->softclip_clk_users[path] == 0) {
1368			snd_soc_component_update_bits(component,
1369						softclip_clk_reg,
1370						CDC_WSA_SOFTCLIP_CLK_EN_MASK,
1371						0);
1372			snd_soc_component_update_bits(component,
1373				CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,
1374				softclip_mux_mask, 0x00);
1375		}
1376	}
1377}
1378
1379static int wsa_macro_config_softclip(struct snd_soc_component *component,
1380				     int path, int event)
1381{
1382	u16 softclip_ctrl_reg;
1383	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1384	int softclip_path = 0;
1385
1386	if (path == WSA_MACRO_COMP1)
1387		softclip_path = WSA_MACRO_SOFTCLIP0;
1388	else if (path == WSA_MACRO_COMP2)
1389		softclip_path = WSA_MACRO_SOFTCLIP1;
1390
1391	if (!wsa->is_softclip_on[softclip_path])
1392		return 0;
1393
1394	softclip_ctrl_reg = CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +
1395				(softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET);
1396
1397	if (SND_SOC_DAPM_EVENT_ON(event)) {
1398		/* Enable Softclip clock and mux */
1399		wsa_macro_enable_softclip_clk(component, wsa, softclip_path,
1400					      true);
1401		/* Enable Softclip control */
1402		snd_soc_component_update_bits(component, softclip_ctrl_reg,
1403					      CDC_WSA_SOFTCLIP_EN_MASK,
1404					      CDC_WSA_SOFTCLIP_ENABLE);
1405	}
1406
1407	if (SND_SOC_DAPM_EVENT_OFF(event)) {
1408		snd_soc_component_update_bits(component, softclip_ctrl_reg,
1409					      CDC_WSA_SOFTCLIP_EN_MASK, 0);
1410		wsa_macro_enable_softclip_clk(component, wsa, softclip_path,
1411					      false);
1412	}
1413
1414	return 0;
1415}
1416
1417static bool wsa_macro_adie_lb(struct snd_soc_component *component,
1418			      int interp_idx)
1419{
1420	u16 int_mux_cfg0,  int_mux_cfg1;
1421	u8 int_n_inp0, int_n_inp1, int_n_inp2;
1422
1423	int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8;
1424	int_mux_cfg1 = int_mux_cfg0 + 4;
1425
1426	int_n_inp0 = snd_soc_component_read_field(component, int_mux_cfg0,
1427						  CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK);
1428	if (int_n_inp0 == INTn_1_INP_SEL_DEC0 ||
1429		int_n_inp0 == INTn_1_INP_SEL_DEC1)
1430		return true;
1431
1432	int_n_inp1 = snd_soc_component_read_field(component, int_mux_cfg0,
1433						  CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK);
1434	if (int_n_inp1 == INTn_1_INP_SEL_DEC0 ||
1435		int_n_inp1 == INTn_1_INP_SEL_DEC1)
1436		return true;
1437
1438	int_n_inp2 = snd_soc_component_read_field(component, int_mux_cfg1,
1439						  CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK);
1440	if (int_n_inp2 == INTn_1_INP_SEL_DEC0 ||
1441		int_n_inp2 == INTn_1_INP_SEL_DEC1)
1442		return true;
1443
1444	return false;
1445}
1446
1447static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w,
1448				      struct snd_kcontrol *kcontrol,
1449				      int event)
1450{
1451	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1452	u16 reg;
1453
1454	reg = CDC_WSA_RX0_RX_PATH_CTL + WSA_MACRO_RX_PATH_OFFSET * w->shift;
1455	switch (event) {
1456	case SND_SOC_DAPM_PRE_PMU:
1457		if (wsa_macro_adie_lb(component, w->shift)) {
1458			snd_soc_component_update_bits(component, reg,
1459					     CDC_WSA_RX_PATH_CLK_EN_MASK,
1460					     CDC_WSA_RX_PATH_CLK_ENABLE);
1461		}
1462		break;
1463	default:
1464		break;
1465	}
1466	return 0;
1467}
1468
1469static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)
1470{
1471	u16 prim_int_reg = 0;
1472
1473	switch (reg) {
1474	case CDC_WSA_RX0_RX_PATH_CTL:
1475	case CDC_WSA_RX0_RX_PATH_MIX_CTL:
1476		prim_int_reg = CDC_WSA_RX0_RX_PATH_CTL;
1477		*ind = 0;
1478		break;
1479	case CDC_WSA_RX1_RX_PATH_CTL:
1480	case CDC_WSA_RX1_RX_PATH_MIX_CTL:
1481		prim_int_reg = CDC_WSA_RX1_RX_PATH_CTL;
1482		*ind = 1;
1483		break;
1484	}
1485
1486	return prim_int_reg;
1487}
1488
1489static int wsa_macro_enable_prim_interpolator(struct snd_soc_component *component,
1490					      u16 reg, int event)
1491{
1492	u16 prim_int_reg;
1493	u16 ind = 0;
1494	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1495
1496	prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind);
1497
1498	switch (event) {
1499	case SND_SOC_DAPM_PRE_PMU:
1500		wsa->prim_int_users[ind]++;
1501		if (wsa->prim_int_users[ind] == 1) {
1502			snd_soc_component_update_bits(component,
1503						      prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET,
1504						      CDC_WSA_RX_DC_DCOEFF_MASK,
1505						      0x3);
1506			snd_soc_component_update_bits(component, prim_int_reg,
1507					CDC_WSA_RX_PATH_PGA_MUTE_EN_MASK,
1508					CDC_WSA_RX_PATH_PGA_MUTE_ENABLE);
1509			wsa_macro_hd2_control(component, prim_int_reg, event);
1510			snd_soc_component_update_bits(component,
1511				prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1512				CDC_WSA_RX_DSMDEM_CLK_EN_MASK,
1513				CDC_WSA_RX_DSMDEM_CLK_ENABLE);
1514		}
1515		if ((reg != prim_int_reg) &&
1516		    ((snd_soc_component_read(
1517				component, prim_int_reg)) & 0x10))
1518			snd_soc_component_update_bits(component, reg,
1519					0x10, 0x10);
1520		break;
1521	case SND_SOC_DAPM_POST_PMD:
1522		wsa->prim_int_users[ind]--;
1523		if (wsa->prim_int_users[ind] == 0) {
1524			snd_soc_component_update_bits(component,
1525				prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,
1526				CDC_WSA_RX_DSMDEM_CLK_EN_MASK, 0);
1527			wsa_macro_hd2_control(component, prim_int_reg, event);
1528		}
1529		break;
1530	}
1531
1532	return 0;
1533}
1534
1535static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
1536					  struct wsa_macro *wsa,
1537					  int event, int gain_reg)
1538{
1539	int comp_gain_offset, val;
1540
1541	switch (wsa->spkr_mode) {
1542	/* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */
1543	case WSA_MACRO_SPKR_MODE_1:
1544		comp_gain_offset = -12;
1545		break;
1546	/* Default case compander gain is 15 dB */
1547	default:
1548		comp_gain_offset = -15;
1549		break;
1550	}
1551
1552	switch (event) {
1553	case SND_SOC_DAPM_POST_PMU:
1554		/* Apply ear spkr gain only if compander is enabled */
1555		if (wsa->comp_enabled[WSA_MACRO_COMP1] &&
1556		    (gain_reg == CDC_WSA_RX0_RX_VOL_CTL) &&
1557		    (wsa->ear_spkr_gain != 0)) {
1558			/* For example, val is -8(-12+5-1) for 4dB of gain */
1559			val = comp_gain_offset + wsa->ear_spkr_gain - 1;
1560			snd_soc_component_write(component, gain_reg, val);
1561		}
1562		break;
1563	case SND_SOC_DAPM_POST_PMD:
1564		/*
1565		 * Reset RX0 volume to 0 dB if compander is enabled and
1566		 * ear_spkr_gain is non-zero.
1567		 */
1568		if (wsa->comp_enabled[WSA_MACRO_COMP1] &&
1569		    (gain_reg == CDC_WSA_RX0_RX_VOL_CTL) &&
1570		    (wsa->ear_spkr_gain != 0)) {
1571			snd_soc_component_write(component, gain_reg, 0x0);
1572		}
1573		break;
1574	}
1575
1576	return 0;
1577}
1578
1579static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,
1580					 struct snd_kcontrol *kcontrol,
1581					 int event)
1582{
1583	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1584	u16 gain_reg;
1585	u16 reg;
1586	int val;
1587	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1588
1589	if (w->shift == WSA_MACRO_COMP1) {
1590		reg = CDC_WSA_RX0_RX_PATH_CTL;
1591		gain_reg = CDC_WSA_RX0_RX_VOL_CTL;
1592	} else if (w->shift == WSA_MACRO_COMP2) {
1593		reg = CDC_WSA_RX1_RX_PATH_CTL;
1594		gain_reg = CDC_WSA_RX1_RX_VOL_CTL;
1595	}
1596
1597	switch (event) {
1598	case SND_SOC_DAPM_PRE_PMU:
1599		/* Reset if needed */
1600		wsa_macro_enable_prim_interpolator(component, reg, event);
1601		break;
1602	case SND_SOC_DAPM_POST_PMU:
1603		wsa_macro_config_compander(component, w->shift, event);
1604		wsa_macro_config_softclip(component, w->shift, event);
1605		/* apply gain after int clk is enabled */
1606		if ((wsa->spkr_gain_offset == WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
1607		    (wsa->comp_enabled[WSA_MACRO_COMP1] ||
1608		     wsa->comp_enabled[WSA_MACRO_COMP2])) {
1609			snd_soc_component_update_bits(component,
1610					CDC_WSA_RX0_RX_PATH_SEC1,
1611					CDC_WSA_RX_PGA_HALF_DB_MASK,
1612					CDC_WSA_RX_PGA_HALF_DB_ENABLE);
1613			snd_soc_component_update_bits(component,
1614					CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1615					CDC_WSA_RX_PGA_HALF_DB_MASK,
1616					CDC_WSA_RX_PGA_HALF_DB_ENABLE);
1617			snd_soc_component_update_bits(component,
1618					CDC_WSA_RX1_RX_PATH_SEC1,
1619					CDC_WSA_RX_PGA_HALF_DB_MASK,
1620					CDC_WSA_RX_PGA_HALF_DB_ENABLE);
1621			snd_soc_component_update_bits(component,
1622					CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1623					CDC_WSA_RX_PGA_HALF_DB_MASK,
1624					CDC_WSA_RX_PGA_HALF_DB_ENABLE);
1625		}
1626		val = snd_soc_component_read(component, gain_reg);
1627		snd_soc_component_write(component, gain_reg, val);
1628		wsa_macro_config_ear_spkr_gain(component, wsa,
1629						event, gain_reg);
1630		break;
1631	case SND_SOC_DAPM_POST_PMD:
1632		wsa_macro_config_compander(component, w->shift, event);
1633		wsa_macro_config_softclip(component, w->shift, event);
1634		wsa_macro_enable_prim_interpolator(component, reg, event);
1635		if ((wsa->spkr_gain_offset == WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&
1636		    (wsa->comp_enabled[WSA_MACRO_COMP1] ||
1637		     wsa->comp_enabled[WSA_MACRO_COMP2])) {
1638			snd_soc_component_update_bits(component,
1639					CDC_WSA_RX0_RX_PATH_SEC1,
1640					CDC_WSA_RX_PGA_HALF_DB_MASK,
1641					CDC_WSA_RX_PGA_HALF_DB_DISABLE);
1642			snd_soc_component_update_bits(component,
1643					CDC_WSA_RX0_RX_PATH_MIX_SEC0,
1644					CDC_WSA_RX_PGA_HALF_DB_MASK,
1645					CDC_WSA_RX_PGA_HALF_DB_DISABLE);
1646			snd_soc_component_update_bits(component,
1647					CDC_WSA_RX1_RX_PATH_SEC1,
1648					CDC_WSA_RX_PGA_HALF_DB_MASK,
1649					CDC_WSA_RX_PGA_HALF_DB_DISABLE);
1650			snd_soc_component_update_bits(component,
1651					CDC_WSA_RX1_RX_PATH_MIX_SEC0,
1652					CDC_WSA_RX_PGA_HALF_DB_MASK,
1653					CDC_WSA_RX_PGA_HALF_DB_DISABLE);
1654		}
1655		wsa_macro_config_ear_spkr_gain(component, wsa,
1656						event, gain_reg);
1657		break;
1658	}
1659
1660	return 0;
1661}
1662
1663static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,
1664				     struct snd_kcontrol *kcontrol,
1665				     int event)
1666{
1667	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1668	u16 boost_path_ctl, boost_path_cfg1;
1669	u16 reg, reg_mix;
1670
1671	if (!snd_soc_dapm_widget_name_cmp(w, "WSA_RX INT0 CHAIN")) {
1672		boost_path_ctl = CDC_WSA_BOOST0_BOOST_PATH_CTL;
1673		boost_path_cfg1 = CDC_WSA_RX0_RX_PATH_CFG1;
1674		reg = CDC_WSA_RX0_RX_PATH_CTL;
1675		reg_mix = CDC_WSA_RX0_RX_PATH_MIX_CTL;
1676	} else if (!snd_soc_dapm_widget_name_cmp(w, "WSA_RX INT1 CHAIN")) {
1677		boost_path_ctl = CDC_WSA_BOOST1_BOOST_PATH_CTL;
1678		boost_path_cfg1 = CDC_WSA_RX1_RX_PATH_CFG1;
1679		reg = CDC_WSA_RX1_RX_PATH_CTL;
1680		reg_mix = CDC_WSA_RX1_RX_PATH_MIX_CTL;
1681	} else {
1682		dev_warn(component->dev, "Incorrect widget name in the driver\n");
1683		return -EINVAL;
1684	}
1685
1686	switch (event) {
1687	case SND_SOC_DAPM_PRE_PMU:
1688		snd_soc_component_update_bits(component, boost_path_cfg1,
1689					      CDC_WSA_RX_PATH_SMART_BST_EN_MASK,
1690					      CDC_WSA_RX_PATH_SMART_BST_ENABLE);
1691		snd_soc_component_update_bits(component, boost_path_ctl,
1692					      CDC_WSA_BOOST_PATH_CLK_EN_MASK,
1693					      CDC_WSA_BOOST_PATH_CLK_ENABLE);
1694		if ((snd_soc_component_read(component, reg_mix)) & 0x10)
1695			snd_soc_component_update_bits(component, reg_mix,
1696						0x10, 0x00);
1697		break;
1698	case SND_SOC_DAPM_POST_PMU:
1699		snd_soc_component_update_bits(component, reg, 0x10, 0x00);
1700		break;
1701	case SND_SOC_DAPM_POST_PMD:
1702		snd_soc_component_update_bits(component, boost_path_ctl,
1703					      CDC_WSA_BOOST_PATH_CLK_EN_MASK,
1704					      CDC_WSA_BOOST_PATH_CLK_DISABLE);
1705		snd_soc_component_update_bits(component, boost_path_cfg1,
1706					      CDC_WSA_RX_PATH_SMART_BST_EN_MASK,
1707					      CDC_WSA_RX_PATH_SMART_BST_DISABLE);
1708		break;
1709	}
1710
1711	return 0;
1712}
1713
1714static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
1715				 struct snd_kcontrol *kcontrol,
1716				 int event)
1717{
1718	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1719	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1720	u16 val, ec_tx, ec_hq_reg;
1721
1722	val = snd_soc_component_read(component, CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);
1723
1724	switch (w->shift) {
1725	case WSA_MACRO_EC0_MUX:
1726		val = val & CDC_WSA_RX_MIX_TX0_SEL_MASK;
1727		ec_tx = val - 1;
1728		break;
1729	case WSA_MACRO_EC1_MUX:
1730		val = val & CDC_WSA_RX_MIX_TX1_SEL_MASK;
1731		ec_tx = (val >> CDC_WSA_RX_MIX_TX1_SEL_SHFT) - 1;
1732		break;
1733	default:
1734		dev_err(component->dev,	"%s: Invalid shift %u\n",
1735			__func__, w->shift);
1736		return -EINVAL;
1737	}
1738
1739	if (wsa->ec_hq[ec_tx]) {
1740		ec_hq_reg = CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +	0x40 * ec_tx;
1741		snd_soc_component_update_bits(component, ec_hq_reg,
1742					     CDC_WSA_EC_HQ_EC_CLK_EN_MASK,
1743					     CDC_WSA_EC_HQ_EC_CLK_ENABLE);
1744		ec_hq_reg = CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 + 0x40 * ec_tx;
1745		/* default set to 48k */
1746		snd_soc_component_update_bits(component, ec_hq_reg,
1747				      CDC_WSA_EC_HQ_EC_REF_PCM_RATE_MASK,
1748				      CDC_WSA_EC_HQ_EC_REF_PCM_RATE_48K);
1749	}
1750
1751	return 0;
1752}
1753
1754static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,
1755			       struct snd_ctl_elem_value *ucontrol)
1756{
1757
1758	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1759	int ec_tx = ((struct soc_mixer_control *) kcontrol->private_value)->shift;
1760	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1761
1762	ucontrol->value.integer.value[0] = wsa->ec_hq[ec_tx];
1763
1764	return 0;
1765}
1766
1767static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,
1768			       struct snd_ctl_elem_value *ucontrol)
1769{
1770	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1771	int ec_tx = ((struct soc_mixer_control *) kcontrol->private_value)->shift;
1772	int value = ucontrol->value.integer.value[0];
1773	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1774
1775	wsa->ec_hq[ec_tx] = value;
1776
1777	return 0;
1778}
1779
1780static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
1781				   struct snd_ctl_elem_value *ucontrol)
1782{
1783
1784	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1785	int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift;
1786	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1787
1788	ucontrol->value.integer.value[0] = wsa->comp_enabled[comp];
1789	return 0;
1790}
1791
1792static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol,
1793				   struct snd_ctl_elem_value *ucontrol)
1794{
1795	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1796	int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift;
1797	int value = ucontrol->value.integer.value[0];
1798	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1799
1800	wsa->comp_enabled[comp] = value;
1801
1802	return 0;
1803}
1804
1805static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
1806					  struct snd_ctl_elem_value *ucontrol)
1807{
1808	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1809	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1810
1811	ucontrol->value.integer.value[0] = wsa->ear_spkr_gain;
1812
1813	return 0;
1814}
1815
1816static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
1817					  struct snd_ctl_elem_value *ucontrol)
1818{
1819	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1820	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1821
1822	wsa->ear_spkr_gain =  ucontrol->value.integer.value[0];
1823
1824	return 0;
1825}
1826
1827static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,
1828				struct snd_ctl_elem_value *ucontrol)
1829{
1830	struct snd_soc_dapm_widget *widget =
1831		snd_soc_dapm_kcontrol_widget(kcontrol);
1832	struct snd_soc_component *component =
1833				snd_soc_dapm_to_component(widget->dapm);
1834	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1835
1836	ucontrol->value.integer.value[0] =
1837			wsa->rx_port_value[widget->shift];
1838	return 0;
1839}
1840
1841static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
1842				struct snd_ctl_elem_value *ucontrol)
1843{
1844	struct snd_soc_dapm_widget *widget =
1845		snd_soc_dapm_kcontrol_widget(kcontrol);
1846	struct snd_soc_component *component =
1847				snd_soc_dapm_to_component(widget->dapm);
1848	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1849	struct snd_soc_dapm_update *update = NULL;
1850	u32 rx_port_value = ucontrol->value.integer.value[0];
1851	u32 bit_input;
1852	u32 aif_rst;
1853	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1854
1855	aif_rst = wsa->rx_port_value[widget->shift];
1856	if (!rx_port_value) {
1857		if (aif_rst == 0)
1858			return 0;
1859		if (aif_rst >= WSA_MACRO_RX_MAX) {
1860			dev_err(component->dev, "%s: Invalid AIF reset\n", __func__);
1861			return 0;
1862		}
1863	}
1864	wsa->rx_port_value[widget->shift] = rx_port_value;
1865
1866	bit_input = widget->shift;
1867
1868	switch (rx_port_value) {
1869	case 0:
1870		if (wsa->active_ch_cnt[aif_rst]) {
1871			clear_bit(bit_input,
1872				  &wsa->active_ch_mask[aif_rst]);
1873			wsa->active_ch_cnt[aif_rst]--;
1874		}
1875		break;
1876	case 1:
1877	case 2:
1878		set_bit(bit_input,
1879			&wsa->active_ch_mask[rx_port_value]);
1880		wsa->active_ch_cnt[rx_port_value]++;
1881		break;
1882	default:
1883		dev_err(component->dev,
1884			"%s: Invalid AIF_ID for WSA RX MUX %d\n",
1885			__func__, rx_port_value);
1886		return -EINVAL;
1887	}
1888
1889	snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
1890					rx_port_value, e, update);
1891	return 0;
1892}
1893
1894static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,
1895					  struct snd_ctl_elem_value *ucontrol)
1896{
1897	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1898	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1899	int path = ((struct soc_mixer_control *)kcontrol->private_value)->shift;
1900
1901	ucontrol->value.integer.value[0] = wsa->is_softclip_on[path];
1902
1903	return 0;
1904}
1905
1906static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,
1907					  struct snd_ctl_elem_value *ucontrol)
1908{
1909	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1910	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1911	int path = ((struct soc_mixer_control *) kcontrol->private_value)->shift;
1912
1913	wsa->is_softclip_on[path] =  ucontrol->value.integer.value[0];
1914
1915	return 0;
1916}
1917
1918static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {
1919	SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,
1920		     wsa_macro_ear_spkr_pa_gain_get,
1921		     wsa_macro_ear_spkr_pa_gain_put),
1922	SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,
1923			WSA_MACRO_SOFTCLIP0, 1, 0,
1924			wsa_macro_soft_clip_enable_get,
1925			wsa_macro_soft_clip_enable_put),
1926	SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,
1927			WSA_MACRO_SOFTCLIP1, 1, 0,
1928			wsa_macro_soft_clip_enable_get,
1929			wsa_macro_soft_clip_enable_put),
1930
1931	SOC_SINGLE_S8_TLV("WSA_RX0 Digital Volume", CDC_WSA_RX0_RX_VOL_CTL,
1932			  -84, 40, digital_gain),
1933	SOC_SINGLE_S8_TLV("WSA_RX1 Digital Volume", CDC_WSA_RX1_RX_VOL_CTL,
1934			  -84, 40, digital_gain),
1935
1936	SOC_SINGLE("WSA_RX0 Digital Mute", CDC_WSA_RX0_RX_PATH_CTL, 4, 1, 0),
1937	SOC_SINGLE("WSA_RX1 Digital Mute", CDC_WSA_RX1_RX_PATH_CTL, 4, 1, 0),
1938	SOC_SINGLE("WSA_RX0_MIX Digital Mute", CDC_WSA_RX0_RX_PATH_MIX_CTL, 4,
1939		   1, 0),
1940	SOC_SINGLE("WSA_RX1_MIX Digital Mute", CDC_WSA_RX1_RX_PATH_MIX_CTL, 4,
1941		   1, 0),
1942	SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
1943		       wsa_macro_get_compander, wsa_macro_set_compander),
1944	SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
1945		       wsa_macro_get_compander, wsa_macro_set_compander),
1946	SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0, 1, 0,
1947		       wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
1948	SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1, 1, 0,
1949		       wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),
1950};
1951
1952static const struct soc_enum rx_mux_enum =
1953	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);
1954
1955static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {
1956	SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,
1957			  wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
1958	SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,
1959			  wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
1960	SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,
1961			  wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
1962	SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,
1963			  wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),
1964};
1965
1966static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
1967				       struct snd_ctl_elem_value *ucontrol)
1968{
1969	struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol);
1970	struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm);
1971	struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
1972	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1973	u32 spk_tx_id = mixer->shift;
1974	u32 dai_id = widget->shift;
1975
1976	if (test_bit(spk_tx_id, &wsa->active_ch_mask[dai_id]))
1977		ucontrol->value.integer.value[0] = 1;
1978	else
1979		ucontrol->value.integer.value[0] = 0;
1980
1981	return 0;
1982}
1983
1984static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
1985				       struct snd_ctl_elem_value *ucontrol)
1986{
1987	struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol);
1988	struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm);
1989	struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
1990	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
1991	u32 enable = ucontrol->value.integer.value[0];
1992	u32 spk_tx_id = mixer->shift;
1993
1994	if (enable) {
1995		if (spk_tx_id == WSA_MACRO_TX0 &&
1996			!test_bit(WSA_MACRO_TX0,
1997				&wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
1998			set_bit(WSA_MACRO_TX0,
1999				&wsa->active_ch_mask[WSA_MACRO_AIF_VI]);
2000			wsa->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2001		}
2002		if (spk_tx_id == WSA_MACRO_TX1 &&
2003			!test_bit(WSA_MACRO_TX1,
2004				&wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
2005			set_bit(WSA_MACRO_TX1,
2006				&wsa->active_ch_mask[WSA_MACRO_AIF_VI]);
2007			wsa->active_ch_cnt[WSA_MACRO_AIF_VI]++;
2008		}
2009	} else {
2010		if (spk_tx_id == WSA_MACRO_TX0 &&
2011			test_bit(WSA_MACRO_TX0,
2012				&wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
2013			clear_bit(WSA_MACRO_TX0,
2014				&wsa->active_ch_mask[WSA_MACRO_AIF_VI]);
2015			wsa->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2016		}
2017		if (spk_tx_id == WSA_MACRO_TX1 &&
2018			test_bit(WSA_MACRO_TX1,
2019				&wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
2020			clear_bit(WSA_MACRO_TX1,
2021				&wsa->active_ch_mask[WSA_MACRO_AIF_VI]);
2022			wsa->active_ch_cnt[WSA_MACRO_AIF_VI]--;
2023		}
2024	}
2025	snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
2026
2027	return 0;
2028}
2029
2030static const struct snd_kcontrol_new aif_vi_mixer[] = {
2031	SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,
2032			wsa_macro_vi_feed_mixer_get,
2033			wsa_macro_vi_feed_mixer_put),
2034	SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,
2035			wsa_macro_vi_feed_mixer_get,
2036			wsa_macro_vi_feed_mixer_put),
2037};
2038
2039static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {
2040	SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,
2041			    SND_SOC_NOPM, 0, 0),
2042	SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,
2043			    SND_SOC_NOPM, 0, 0),
2044
2045	SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,
2046			       SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,
2047			       wsa_macro_enable_vi_feedback,
2048			       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2049	SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,
2050			     SND_SOC_NOPM, 0, 0),
2051
2052	SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,
2053			   0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),
2054	SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,
2055			   WSA_MACRO_EC0_MUX, 0,
2056			   &rx_mix_ec0_mux, wsa_macro_enable_echo,
2057			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2058	SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,
2059			   WSA_MACRO_EC1_MUX, 0,
2060			   &rx_mix_ec1_mux, wsa_macro_enable_echo,
2061			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2062
2063	SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,
2064			 &rx_mux[WSA_MACRO_RX0]),
2065	SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,
2066			 &rx_mux[WSA_MACRO_RX1]),
2067	SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,
2068			 &rx_mux[WSA_MACRO_RX_MIX0]),
2069	SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,
2070			 &rx_mux[WSA_MACRO_RX_MIX1]),
2071
2072	SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2073	SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2074	SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),
2075	SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
2076
2077	SND_SOC_DAPM_MUX("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0, &rx0_prim_inp0_mux),
2078	SND_SOC_DAPM_MUX("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0, &rx0_prim_inp1_mux),
2079	SND_SOC_DAPM_MUX("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, &rx0_prim_inp2_mux),
2080	SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX0,
2081			   0, &rx0_mix_mux, wsa_macro_enable_mix_path,
2082			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2083	SND_SOC_DAPM_MUX("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, &rx1_prim_inp0_mux),
2084	SND_SOC_DAPM_MUX("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0, &rx1_prim_inp1_mux),
2085	SND_SOC_DAPM_MUX("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, &rx1_prim_inp2_mux),
2086	SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX1,
2087			   0, &rx1_mix_mux, wsa_macro_enable_mix_path,
2088			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2089
2090	SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0,
2091			     wsa_macro_enable_main_path, SND_SOC_DAPM_PRE_PMU),
2092	SND_SOC_DAPM_MIXER_E("WSA_RX INT1 MIX", SND_SOC_NOPM, 1, 0, NULL, 0,
2093			     wsa_macro_enable_main_path, SND_SOC_DAPM_PRE_PMU),
2094
2095	SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2096	SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
2097
2098	SND_SOC_DAPM_MUX("WSA_RX0 INT0 SIDETONE MIX", CDC_WSA_RX0_RX_PATH_CFG1,
2099			 4, 0, &rx0_sidetone_mix_mux),
2100
2101	SND_SOC_DAPM_INPUT("WSA SRC0_INP"),
2102	SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),
2103	SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),
2104
2105	SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,
2106			     WSA_MACRO_COMP1, 0, NULL, 0,
2107			     wsa_macro_enable_interpolator,
2108			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2109			     SND_SOC_DAPM_POST_PMD),
2110
2111	SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,
2112			     WSA_MACRO_COMP2, 0, NULL, 0,
2113			     wsa_macro_enable_interpolator,
2114			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2115			     SND_SOC_DAPM_POST_PMD),
2116
2117	SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,
2118			     NULL, 0, wsa_macro_spk_boost_event,
2119			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2120			     SND_SOC_DAPM_POST_PMD),
2121
2122	SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,
2123			     NULL, 0, wsa_macro_spk_boost_event,
2124			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2125			     SND_SOC_DAPM_POST_PMD),
2126
2127	SND_SOC_DAPM_INPUT("VIINPUT_WSA"),
2128	SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),
2129	SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),
2130
2131	SND_SOC_DAPM_SUPPLY("WSA_RX0_CLK", CDC_WSA_RX0_RX_PATH_CTL, 5, 0, NULL, 0),
2132	SND_SOC_DAPM_SUPPLY("WSA_RX1_CLK", CDC_WSA_RX1_RX_PATH_CTL, 5, 0, NULL, 0),
2133	SND_SOC_DAPM_SUPPLY("WSA_RX_MIX0_CLK", CDC_WSA_RX0_RX_PATH_MIX_CTL, 5, 0, NULL, 0),
2134	SND_SOC_DAPM_SUPPLY("WSA_RX_MIX1_CLK", CDC_WSA_RX1_RX_PATH_MIX_CTL, 5, 0, NULL, 0),
2135	SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,
2136			      wsa_macro_mclk_event,
2137			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2138};
2139
2140static const struct snd_soc_dapm_route wsa_audio_map[] = {
2141	/* VI Feedback */
2142	{"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},
2143	{"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},
2144	{"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},
2145	{"WSA AIF_VI", NULL, "WSA_MCLK"},
2146
2147	{"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2148	{"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},
2149	{"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2150	{"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},
2151	{"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},
2152	{"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},
2153	{"WSA AIF_ECHO", NULL, "WSA_MCLK"},
2154
2155	{"WSA AIF1 PB", NULL, "WSA_MCLK"},
2156	{"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},
2157
2158	{"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2159	{"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2160	{"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},
2161	{"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},
2162
2163	{"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2164	{"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2165	{"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2166	{"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},
2167
2168	{"WSA RX0", NULL, "WSA RX0 MUX"},
2169	{"WSA RX1", NULL, "WSA RX1 MUX"},
2170	{"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},
2171	{"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},
2172
2173	{"WSA RX0", NULL, "WSA_RX0_CLK"},
2174	{"WSA RX1", NULL, "WSA_RX1_CLK"},
2175	{"WSA RX_MIX0", NULL, "WSA_RX_MIX0_CLK"},
2176	{"WSA RX_MIX1", NULL, "WSA_RX_MIX1_CLK"},
2177
2178	{"WSA_RX0 INP0", "RX0", "WSA RX0"},
2179	{"WSA_RX0 INP0", "RX1", "WSA RX1"},
2180	{"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},
2181	{"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},
2182	{"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},
2183	{"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},
2184	{"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},
2185
2186	{"WSA_RX0 INP1", "RX0", "WSA RX0"},
2187	{"WSA_RX0 INP1", "RX1", "WSA RX1"},
2188	{"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},
2189	{"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},
2190	{"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},
2191	{"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},
2192	{"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},
2193
2194	{"WSA_RX0 INP2", "RX0", "WSA RX0"},
2195	{"WSA_RX0 INP2", "RX1", "WSA RX1"},
2196	{"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},
2197	{"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},
2198	{"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},
2199	{"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},
2200	{"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},
2201
2202	{"WSA_RX0 MIX INP", "RX0", "WSA RX0"},
2203	{"WSA_RX0 MIX INP", "RX1", "WSA RX1"},
2204	{"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2205	{"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2206	{"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},
2207
2208	{"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},
2209	{"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},
2210	{"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},
2211	{"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},
2212	{"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},
2213
2214	{"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},
2215	{"WSA_SPK1 OUT", NULL, "WSA_MCLK"},
2216
2217	{"WSA_RX1 INP0", "RX0", "WSA RX0"},
2218	{"WSA_RX1 INP0", "RX1", "WSA RX1"},
2219	{"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},
2220	{"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},
2221	{"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},
2222	{"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},
2223	{"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},
2224
2225	{"WSA_RX1 INP1", "RX0", "WSA RX0"},
2226	{"WSA_RX1 INP1", "RX1", "WSA RX1"},
2227	{"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},
2228	{"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},
2229	{"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},
2230	{"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},
2231	{"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},
2232
2233	{"WSA_RX1 INP2", "RX0", "WSA RX0"},
2234	{"WSA_RX1 INP2", "RX1", "WSA RX1"},
2235	{"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},
2236	{"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},
2237	{"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},
2238	{"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},
2239	{"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},
2240
2241	{"WSA_RX1 MIX INP", "RX0", "WSA RX0"},
2242	{"WSA_RX1 MIX INP", "RX1", "WSA RX1"},
2243	{"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},
2244	{"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},
2245	{"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},
2246
2247	{"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},
2248	{"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},
2249
2250	{"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},
2251	{"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},
2252	{"WSA_SPK2 OUT", NULL, "WSA_MCLK"},
2253};
2254
2255static int wsa_swrm_clock(struct wsa_macro *wsa, bool enable)
2256{
2257	struct regmap *regmap = wsa->regmap;
2258
2259	if (enable) {
2260		int ret;
2261
2262		ret = clk_prepare_enable(wsa->mclk);
2263		if (ret) {
2264			dev_err(wsa->dev, "failed to enable mclk\n");
2265			return ret;
2266		}
2267		wsa_macro_mclk_enable(wsa, true);
2268
2269		regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2270				   CDC_WSA_SWR_CLK_EN_MASK,
2271				   CDC_WSA_SWR_CLK_ENABLE);
2272
2273	} else {
2274		regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2275				   CDC_WSA_SWR_CLK_EN_MASK, 0);
2276		wsa_macro_mclk_enable(wsa, false);
2277		clk_disable_unprepare(wsa->mclk);
2278	}
2279
2280	return 0;
2281}
2282
2283static int wsa_macro_component_probe(struct snd_soc_component *comp)
2284{
2285	struct wsa_macro *wsa = snd_soc_component_get_drvdata(comp);
2286
2287	snd_soc_component_init_regmap(comp, wsa->regmap);
2288
2289	wsa->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_M1P5_DB;
2290
2291	/* set SPKR rate to FS_2P4_3P072 */
2292	snd_soc_component_update_bits(comp, CDC_WSA_RX0_RX_PATH_CFG1,
2293				CDC_WSA_RX_PATH_SPKR_RATE_MASK,
2294				CDC_WSA_RX_PATH_SPKR_RATE_FS_2P4_3P072);
2295
2296	snd_soc_component_update_bits(comp, CDC_WSA_RX1_RX_PATH_CFG1,
2297				CDC_WSA_RX_PATH_SPKR_RATE_MASK,
2298				CDC_WSA_RX_PATH_SPKR_RATE_FS_2P4_3P072);
2299
2300	wsa_macro_set_spkr_mode(comp, WSA_MACRO_SPKR_MODE_1);
2301
2302	return 0;
2303}
2304
2305static int swclk_gate_enable(struct clk_hw *hw)
2306{
2307	return wsa_swrm_clock(to_wsa_macro(hw), true);
2308}
2309
2310static void swclk_gate_disable(struct clk_hw *hw)
2311{
2312	wsa_swrm_clock(to_wsa_macro(hw), false);
2313}
2314
2315static int swclk_gate_is_enabled(struct clk_hw *hw)
2316{
2317	struct wsa_macro *wsa = to_wsa_macro(hw);
2318	int ret, val;
2319
2320	regmap_read(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, &val);
2321	ret = val & BIT(0);
2322
2323	return ret;
2324}
2325
2326static unsigned long swclk_recalc_rate(struct clk_hw *hw,
2327				       unsigned long parent_rate)
2328{
2329	return parent_rate / 2;
2330}
2331
2332static const struct clk_ops swclk_gate_ops = {
2333	.prepare = swclk_gate_enable,
2334	.unprepare = swclk_gate_disable,
2335	.is_enabled = swclk_gate_is_enabled,
2336	.recalc_rate = swclk_recalc_rate,
2337};
2338
2339static int wsa_macro_register_mclk_output(struct wsa_macro *wsa)
2340{
2341	struct device *dev = wsa->dev;
2342	const char *parent_clk_name;
2343	struct clk_hw *hw;
2344	struct clk_init_data init;
2345	int ret;
2346
2347	if (wsa->npl)
2348		parent_clk_name = __clk_get_name(wsa->npl);
2349	else
2350		parent_clk_name = __clk_get_name(wsa->mclk);
2351
2352	init.name = "mclk";
2353	of_property_read_string(dev_of_node(dev), "clock-output-names",
2354				&init.name);
2355	init.ops = &swclk_gate_ops;
2356	init.flags = 0;
2357	init.parent_names = &parent_clk_name;
2358	init.num_parents = 1;
2359	wsa->hw.init = &init;
2360	hw = &wsa->hw;
2361	ret = clk_hw_register(wsa->dev, hw);
2362	if (ret)
2363		return ret;
2364
2365	return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
2366}
2367
2368static const struct snd_soc_component_driver wsa_macro_component_drv = {
2369	.name = "WSA MACRO",
2370	.probe = wsa_macro_component_probe,
2371	.controls = wsa_macro_snd_controls,
2372	.num_controls = ARRAY_SIZE(wsa_macro_snd_controls),
2373	.dapm_widgets = wsa_macro_dapm_widgets,
2374	.num_dapm_widgets = ARRAY_SIZE(wsa_macro_dapm_widgets),
2375	.dapm_routes = wsa_audio_map,
2376	.num_dapm_routes = ARRAY_SIZE(wsa_audio_map),
2377};
2378
2379static int wsa_macro_probe(struct platform_device *pdev)
2380{
2381	struct device *dev = &pdev->dev;
2382	struct wsa_macro *wsa;
2383	kernel_ulong_t flags;
2384	void __iomem *base;
2385	int ret;
2386
2387	flags = (kernel_ulong_t)device_get_match_data(dev);
2388
2389	wsa = devm_kzalloc(dev, sizeof(*wsa), GFP_KERNEL);
2390	if (!wsa)
2391		return -ENOMEM;
2392
2393	wsa->macro = devm_clk_get_optional(dev, "macro");
2394	if (IS_ERR(wsa->macro))
2395		return dev_err_probe(dev, PTR_ERR(wsa->macro), "unable to get macro clock\n");
2396
2397	wsa->dcodec = devm_clk_get_optional(dev, "dcodec");
2398	if (IS_ERR(wsa->dcodec))
2399		return dev_err_probe(dev, PTR_ERR(wsa->dcodec), "unable to get dcodec clock\n");
2400
2401	wsa->mclk = devm_clk_get(dev, "mclk");
2402	if (IS_ERR(wsa->mclk))
2403		return dev_err_probe(dev, PTR_ERR(wsa->mclk), "unable to get mclk clock\n");
2404
2405	if (flags & LPASS_MACRO_FLAG_HAS_NPL_CLOCK) {
2406		wsa->npl = devm_clk_get(dev, "npl");
2407		if (IS_ERR(wsa->npl))
2408			return dev_err_probe(dev, PTR_ERR(wsa->npl), "unable to get npl clock\n");
2409	}
2410
2411	wsa->fsgen = devm_clk_get(dev, "fsgen");
2412	if (IS_ERR(wsa->fsgen))
2413		return dev_err_probe(dev, PTR_ERR(wsa->fsgen), "unable to get fsgen clock\n");
2414
2415	base = devm_platform_ioremap_resource(pdev, 0);
2416	if (IS_ERR(base))
2417		return PTR_ERR(base);
2418
2419	wsa->regmap = devm_regmap_init_mmio(dev, base, &wsa_regmap_config);
2420	if (IS_ERR(wsa->regmap))
2421		return PTR_ERR(wsa->regmap);
2422
2423	dev_set_drvdata(dev, wsa);
2424
2425	wsa->dev = dev;
2426
2427	/* set MCLK and NPL rates */
2428	clk_set_rate(wsa->mclk, WSA_MACRO_MCLK_FREQ);
2429	clk_set_rate(wsa->npl, WSA_MACRO_MCLK_FREQ);
2430
2431	ret = clk_prepare_enable(wsa->macro);
2432	if (ret)
2433		goto err;
2434
2435	ret = clk_prepare_enable(wsa->dcodec);
2436	if (ret)
2437		goto err_dcodec;
2438
2439	ret = clk_prepare_enable(wsa->mclk);
2440	if (ret)
2441		goto err_mclk;
2442
2443	ret = clk_prepare_enable(wsa->npl);
2444	if (ret)
2445		goto err_npl;
2446
2447	ret = clk_prepare_enable(wsa->fsgen);
2448	if (ret)
2449		goto err_fsgen;
2450
2451	/* reset swr ip */
2452	regmap_update_bits(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2453			   CDC_WSA_SWR_RST_EN_MASK, CDC_WSA_SWR_RST_ENABLE);
2454
2455	regmap_update_bits(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2456			   CDC_WSA_SWR_CLK_EN_MASK, CDC_WSA_SWR_CLK_ENABLE);
2457
2458	/* Bring out of reset */
2459	regmap_update_bits(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
2460			   CDC_WSA_SWR_RST_EN_MASK, CDC_WSA_SWR_RST_DISABLE);
2461
2462	ret = devm_snd_soc_register_component(dev, &wsa_macro_component_drv,
2463					      wsa_macro_dai,
2464					      ARRAY_SIZE(wsa_macro_dai));
2465	if (ret)
2466		goto err_clkout;
2467
2468	pm_runtime_set_autosuspend_delay(dev, 3000);
2469	pm_runtime_use_autosuspend(dev);
2470	pm_runtime_mark_last_busy(dev);
2471	pm_runtime_set_active(dev);
2472	pm_runtime_enable(dev);
2473
2474	ret = wsa_macro_register_mclk_output(wsa);
2475	if (ret)
2476		goto err_clkout;
2477
2478	return 0;
2479
2480err_clkout:
2481	clk_disable_unprepare(wsa->fsgen);
2482err_fsgen:
2483	clk_disable_unprepare(wsa->npl);
2484err_npl:
2485	clk_disable_unprepare(wsa->mclk);
2486err_mclk:
2487	clk_disable_unprepare(wsa->dcodec);
2488err_dcodec:
2489	clk_disable_unprepare(wsa->macro);
2490err:
2491	return ret;
2492
2493}
2494
2495static void wsa_macro_remove(struct platform_device *pdev)
2496{
2497	struct wsa_macro *wsa = dev_get_drvdata(&pdev->dev);
2498
2499	clk_disable_unprepare(wsa->macro);
2500	clk_disable_unprepare(wsa->dcodec);
2501	clk_disable_unprepare(wsa->mclk);
2502	clk_disable_unprepare(wsa->npl);
2503	clk_disable_unprepare(wsa->fsgen);
2504}
2505
2506static int __maybe_unused wsa_macro_runtime_suspend(struct device *dev)
2507{
2508	struct wsa_macro *wsa = dev_get_drvdata(dev);
2509
2510	regcache_cache_only(wsa->regmap, true);
2511	regcache_mark_dirty(wsa->regmap);
2512
2513	clk_disable_unprepare(wsa->fsgen);
2514	clk_disable_unprepare(wsa->npl);
2515	clk_disable_unprepare(wsa->mclk);
2516
2517	return 0;
2518}
2519
2520static int __maybe_unused wsa_macro_runtime_resume(struct device *dev)
2521{
2522	struct wsa_macro *wsa = dev_get_drvdata(dev);
2523	int ret;
2524
2525	ret = clk_prepare_enable(wsa->mclk);
2526	if (ret) {
2527		dev_err(dev, "unable to prepare mclk\n");
2528		return ret;
2529	}
2530
2531	ret = clk_prepare_enable(wsa->npl);
2532	if (ret) {
2533		dev_err(dev, "unable to prepare mclkx2\n");
2534		goto err_npl;
2535	}
2536
2537	ret = clk_prepare_enable(wsa->fsgen);
2538	if (ret) {
2539		dev_err(dev, "unable to prepare fsgen\n");
2540		goto err_fsgen;
2541	}
2542
2543	regcache_cache_only(wsa->regmap, false);
2544	regcache_sync(wsa->regmap);
2545
2546	return 0;
2547err_fsgen:
2548	clk_disable_unprepare(wsa->npl);
2549err_npl:
2550	clk_disable_unprepare(wsa->mclk);
2551
2552	return ret;
2553}
2554
2555static const struct dev_pm_ops wsa_macro_pm_ops = {
2556	SET_RUNTIME_PM_OPS(wsa_macro_runtime_suspend, wsa_macro_runtime_resume, NULL)
2557};
2558
2559static const struct of_device_id wsa_macro_dt_match[] = {
2560	{
2561		.compatible = "qcom,sc7280-lpass-wsa-macro",
2562		.data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,
2563	}, {
2564		.compatible = "qcom,sm8250-lpass-wsa-macro",
2565		.data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,
2566	}, {
2567		.compatible = "qcom,sm8450-lpass-wsa-macro",
2568		.data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,
2569	}, {
2570		.compatible = "qcom,sm8550-lpass-wsa-macro",
2571	}, {
2572		.compatible = "qcom,sc8280xp-lpass-wsa-macro",
2573		.data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,
2574	},
2575	{}
2576};
2577MODULE_DEVICE_TABLE(of, wsa_macro_dt_match);
2578
2579static struct platform_driver wsa_macro_driver = {
2580	.driver = {
2581		.name = "wsa_macro",
2582		.of_match_table = wsa_macro_dt_match,
2583		.pm = &wsa_macro_pm_ops,
2584	},
2585	.probe = wsa_macro_probe,
2586	.remove_new = wsa_macro_remove,
2587};
2588
2589module_platform_driver(wsa_macro_driver);
2590MODULE_DESCRIPTION("WSA macro driver");
2591MODULE_LICENSE("GPL");