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