cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

lpass-wsa-macro.c (82760B)


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