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