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