Linux Audio

Check our new training course

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