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