~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/lpass-wsa-macro.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php