1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Cirrus Logic CS48L32 audio DSP.
4 //
5 // Copyright (C) 2016-2018, 2020, 2022, 2025 Cirrus Logic, Inc. and
6 // Cirrus Logic International Semiconductor Ltd.
7
8 #include <dt-bindings/sound/cs48l32.h>
9 #include <linux/array_size.h>
10 #include <linux/build_bug.h>
11 #include <linux/clk.h>
12 #include <linux/container_of.h>
13 #include <linux/delay.h>
14 #include <linux/err.h>
15 #include <linux/gcd.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/minmax.h>
18 #include <linux/module.h>
19 #include <linux/of.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/property.h>
22 #include <linux/regmap.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/slab.h>
25 #include <linux/spi/spi.h>
26 #include <linux/string_choices.h>
27 #include <sound/cs48l32.h>
28 #include <sound/cs48l32_registers.h>
29 #include <sound/pcm.h>
30 #include <sound/pcm_params.h>
31 #include <sound/soc.h>
32 #include <sound/soc-component.h>
33 #include <sound/soc-dai.h>
34 #include <sound/soc-dapm.h>
35 #include <sound/tlv.h>
36
37 #include "cs48l32.h"
38
39 static const char * const cs48l32_core_supplies[] = { "vdd-a", "vdd-io" };
40
41 static const struct cs_dsp_region cs48l32_dsp1_regions[] = {
42 { .type = WMFW_HALO_PM_PACKED, .base = 0x3800000 },
43 { .type = WMFW_HALO_XM_PACKED, .base = 0x2000000 },
44 { .type = WMFW_ADSP2_XM, .base = 0x2800000 },
45 { .type = WMFW_HALO_YM_PACKED, .base = 0x2C00000 },
46 { .type = WMFW_ADSP2_YM, .base = 0x3400000 },
47 };
48
49 static const struct cs48l32_dsp_power_reg_block cs48l32_dsp1_sram_ext_regs[] = {
50 { CS48L32_DSP1_XM_SRAM_IBUS_SETUP_1, CS48L32_DSP1_XM_SRAM_IBUS_SETUP_24 },
51 { CS48L32_DSP1_YM_SRAM_IBUS_SETUP_1, CS48L32_DSP1_YM_SRAM_IBUS_SETUP_8 },
52 { CS48L32_DSP1_PM_SRAM_IBUS_SETUP_1, CS48L32_DSP1_PM_SRAM_IBUS_SETUP_7 },
53 };
54
55 static const unsigned int cs48l32_dsp1_sram_pwd_regs[] = {
56 CS48L32_DSP1_XM_SRAM_IBUS_SETUP_0,
57 CS48L32_DSP1_YM_SRAM_IBUS_SETUP_0,
58 CS48L32_DSP1_PM_SRAM_IBUS_SETUP_0,
59 };
60
61 static const struct cs48l32_dsp_power_regs cs48l32_dsp_sram_regs = {
62 .ext = cs48l32_dsp1_sram_ext_regs,
63 .n_ext = ARRAY_SIZE(cs48l32_dsp1_sram_ext_regs),
64 .pwd = cs48l32_dsp1_sram_pwd_regs,
65 .n_pwd = ARRAY_SIZE(cs48l32_dsp1_sram_pwd_regs),
66 };
67
68 static const char * const cs48l32_mixer_texts[] = {
69 "None",
70 "Tone Generator 1",
71 "Tone Generator 2",
72 "Noise Generator",
73 "IN1L",
74 "IN1R",
75 "IN2L",
76 "IN2R",
77 "ASP1RX1",
78 "ASP1RX2",
79 "ASP1RX3",
80 "ASP1RX4",
81 "ASP1RX5",
82 "ASP1RX6",
83 "ASP1RX7",
84 "ASP1RX8",
85 "ASP2RX1",
86 "ASP2RX2",
87 "ASP2RX3",
88 "ASP2RX4",
89 "ISRC1INT1",
90 "ISRC1INT2",
91 "ISRC1INT3",
92 "ISRC1INT4",
93 "ISRC1DEC1",
94 "ISRC1DEC2",
95 "ISRC1DEC3",
96 "ISRC1DEC4",
97 "ISRC2INT1",
98 "ISRC2INT2",
99 "ISRC2DEC1",
100 "ISRC2DEC2",
101 "ISRC3INT1",
102 "ISRC3INT2",
103 "ISRC3DEC1",
104 "ISRC3DEC2",
105 "EQ1",
106 "EQ2",
107 "EQ3",
108 "EQ4",
109 "DRC1L",
110 "DRC1R",
111 "DRC2L",
112 "DRC2R",
113 "LHPF1",
114 "LHPF2",
115 "LHPF3",
116 "LHPF4",
117 "Ultrasonic 1",
118 "Ultrasonic 2",
119 "DSP1.1",
120 "DSP1.2",
121 "DSP1.3",
122 "DSP1.4",
123 "DSP1.5",
124 "DSP1.6",
125 "DSP1.7",
126 "DSP1.8",
127 };
128
129 static unsigned int cs48l32_mixer_values[] = {
130 0x000, /* Silence (mute) */
131 0x004, /* Tone generator 1 */
132 0x005, /* Tone generator 2 */
133 0x00C, /* Noise Generator */
134 0x010, /* IN1L signal path */
135 0x011, /* IN1R signal path */
136 0x012, /* IN2L signal path */
137 0x013, /* IN2R signal path */
138 0x020, /* ASP1 RX1 */
139 0x021, /* ASP1 RX2 */
140 0x022, /* ASP1 RX3 */
141 0x023, /* ASP1 RX4 */
142 0x024, /* ASP1 RX5 */
143 0x025, /* ASP1 RX6 */
144 0x026, /* ASP1 RX7 */
145 0x027, /* ASP1 RX8 */
146 0x030, /* ASP2 RX1 */
147 0x031, /* ASP2 RX2 */
148 0x032, /* ASP2 RX3 */
149 0x033, /* ASP2 RX4 */
150 0x098, /* ISRC1 INT1 */
151 0x099, /* ISRC1 INT2 */
152 0x09a, /* ISRC1 INT3 */
153 0x09b, /* ISRC1 INT4 */
154 0x09C, /* ISRC1 DEC1 */
155 0x09D, /* ISRC1 DEC2 */
156 0x09e, /* ISRC1 DEC3 */
157 0x09f, /* ISRC1 DEC4 */
158 0x0A0, /* ISRC2 INT1 */
159 0x0A1, /* ISRC2 INT2 */
160 0x0A4, /* ISRC2 DEC1 */
161 0x0A5, /* ISRC2 DEC2 */
162 0x0A8, /* ISRC3 INT1 */
163 0x0A9, /* ISRC3 INT2 */
164 0x0AC, /* ISRC3 DEC1 */
165 0x0AD, /* ISRC3 DEC2 */
166 0x0B8, /* EQ1 */
167 0x0B9, /* EQ2 */
168 0x0BA, /* EQ3 */
169 0x0BB, /* EQ4 */
170 0x0C0, /* DRC1 Left */
171 0x0C1, /* DRC1 Right */
172 0x0C2, /* DRC2 Left */
173 0x0C3, /* DRC2 Right */
174 0x0C8, /* LHPF1 */
175 0x0C9, /* LHPF2 */
176 0x0CA, /* LHPF3 */
177 0x0CB, /* LHPF4 */
178 0x0D8, /* Ultrasonic 1 */
179 0x0D9, /* Ultrasonic 2 */
180 0x100, /* DSP1 channel 1 */
181 0x101, /* DSP1 channel 2 */
182 0x102, /* DSP1 channel 3 */
183 0x103, /* DSP1 channel 4 */
184 0x104, /* DSP1 channel 5 */
185 0x105, /* DSP1 channel 6 */
186 0x106, /* DSP1 channel 7 */
187 0x107, /* DSP1 channel 8 */
188 };
189 static_assert(ARRAY_SIZE(cs48l32_mixer_texts) == ARRAY_SIZE(cs48l32_mixer_values));
190 #define CS48L32_NUM_MIXER_INPUTS ARRAY_SIZE(cs48l32_mixer_values)
191
192 static const DECLARE_TLV_DB_SCALE(cs48l32_ana_tlv, 0, 100, 0);
193 static const DECLARE_TLV_DB_SCALE(cs48l32_eq_tlv, -1200, 100, 0);
194 static const DECLARE_TLV_DB_SCALE(cs48l32_digital_tlv, -6400, 50, 0);
195 static const DECLARE_TLV_DB_SCALE(cs48l32_noise_tlv, -10800, 600, 0);
196 static const DECLARE_TLV_DB_SCALE(cs48l32_mixer_tlv, -3200, 100, 0);
197 static const DECLARE_TLV_DB_SCALE(cs48l32_us_tlv, 0, 600, 0);
198
cs48l32_spin_sysclk(struct cs48l32_codec * cs48l32_codec)199 static void cs48l32_spin_sysclk(struct cs48l32_codec *cs48l32_codec)
200 {
201 struct cs48l32 *cs48l32 = &cs48l32_codec->core;
202 unsigned int val;
203 int ret, i;
204
205 /* Skip this if the chip is down */
206 if (pm_runtime_suspended(cs48l32->dev))
207 return;
208
209 /*
210 * Just read a register a few times to ensure the internal
211 * oscillator sends out some clocks.
212 */
213 for (i = 0; i < 4; i++) {
214 ret = regmap_read(cs48l32->regmap, CS48L32_DEVID, &val);
215 if (ret)
216 dev_err(cs48l32_codec->core.dev, "%s Failed to read register: %d (%d)\n",
217 __func__, ret, i);
218 }
219
220 udelay(300);
221 }
222
223 static const char * const cs48l32_rate_text[] = {
224 "Sample Rate 1", "Sample Rate 2", "Sample Rate 3", "Sample Rate 4",
225 };
226
227 static const unsigned int cs48l32_rate_val[] = {
228 0x0, 0x1, 0x2, 0x3,
229 };
230 static_assert(ARRAY_SIZE(cs48l32_rate_val) == ARRAY_SIZE(cs48l32_rate_text));
231
cs48l32_rate_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)232 static int cs48l32_rate_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
233 {
234 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
235 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
236 int ret;
237
238 /* Prevent any mixer mux changes while we do this */
239 mutex_lock(&cs48l32_codec->rate_lock);
240
241 /* The write must be guarded by a number of SYSCLK cycles */
242 cs48l32_spin_sysclk(cs48l32_codec);
243 ret = snd_soc_put_enum_double(kcontrol, ucontrol);
244 cs48l32_spin_sysclk(cs48l32_codec);
245
246 mutex_unlock(&cs48l32_codec->rate_lock);
247
248 return ret;
249 }
250
251 static const char * const cs48l32_sample_rate_text[] = {
252 "12kHz",
253 "24kHz",
254 "48kHz",
255 "96kHz",
256 "192kHz",
257 "384kHz",
258 "768kHz",
259 "11.025kHz",
260 "22.05kHz",
261 "44.1kHz",
262 "88.2kHz",
263 "176.4kHz",
264 "352.8kHz",
265 "705.6kHz",
266 "8kHz",
267 "16kHz",
268 "32kHz",
269 };
270
271 static const unsigned int cs48l32_sample_rate_val[] = {
272 0x01, /* 12kHz */
273 0x02, /* 24kHz */
274 0x03, /* 48kHz */
275 0x04, /* 96kHz */
276 0x05, /* 192kHz */
277 0x06, /* 384kHz */
278 0x07, /* 768kHz */
279 0x09, /* 11.025kHz */
280 0x0a, /* 22.05kHz */
281 0x0b, /* 44.1kHz */
282 0x0c, /* 88.2kHz */
283 0x0d, /* 176.4kHz */
284 0x0e, /* 352.8kHz */
285 0x0f, /* 705.6kHz */
286 0x11, /* 8kHz */
287 0x12, /* 16kHz */
288 0x13, /* 32kHz */
289 };
290 static_assert(ARRAY_SIZE(cs48l32_sample_rate_val) == ARRAY_SIZE(cs48l32_sample_rate_text));
291 #define CS48L32_SAMPLE_RATE_ENUM_SIZE ARRAY_SIZE(cs48l32_sample_rate_val)
292
293 static const struct soc_enum cs48l32_sample_rate[] = {
294 SOC_VALUE_ENUM_SINGLE(CS48L32_SAMPLE_RATE1,
295 CS48L32_SAMPLE_RATE_1_SHIFT,
296 CS48L32_SAMPLE_RATE_1_MASK >> CS48L32_SAMPLE_RATE_1_SHIFT,
297 CS48L32_SAMPLE_RATE_ENUM_SIZE,
298 cs48l32_sample_rate_text,
299 cs48l32_sample_rate_val),
300 SOC_VALUE_ENUM_SINGLE(CS48L32_SAMPLE_RATE2,
301 CS48L32_SAMPLE_RATE_1_SHIFT,
302 CS48L32_SAMPLE_RATE_1_MASK >> CS48L32_SAMPLE_RATE_1_SHIFT,
303 CS48L32_SAMPLE_RATE_ENUM_SIZE,
304 cs48l32_sample_rate_text,
305 cs48l32_sample_rate_val),
306 SOC_VALUE_ENUM_SINGLE(CS48L32_SAMPLE_RATE3,
307 CS48L32_SAMPLE_RATE_1_SHIFT,
308 CS48L32_SAMPLE_RATE_1_MASK >> CS48L32_SAMPLE_RATE_1_SHIFT,
309 CS48L32_SAMPLE_RATE_ENUM_SIZE,
310 cs48l32_sample_rate_text,
311 cs48l32_sample_rate_val),
312 SOC_VALUE_ENUM_SINGLE(CS48L32_SAMPLE_RATE4,
313 CS48L32_SAMPLE_RATE_1_SHIFT,
314 CS48L32_SAMPLE_RATE_1_MASK >> CS48L32_SAMPLE_RATE_1_SHIFT,
315 CS48L32_SAMPLE_RATE_ENUM_SIZE,
316 cs48l32_sample_rate_text,
317 cs48l32_sample_rate_val),
318 };
319
cs48l32_inmux_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)320 static int cs48l32_inmux_put(struct snd_kcontrol *kcontrol,
321 struct snd_ctl_elem_value *ucontrol)
322 {
323 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
324 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
325 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
326 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
327 unsigned int mux, src_val, in_type;
328 int ret;
329
330 mux = ucontrol->value.enumerated.item[0];
331 if (mux > 1)
332 return -EINVAL;
333
334 switch (e->reg) {
335 case CS48L32_IN1L_CONTROL1:
336 in_type = cs48l32_codec->in_type[0][mux];
337 break;
338 case CS48L32_IN1R_CONTROL1:
339 in_type = cs48l32_codec->in_type[1][mux];
340 break;
341 default:
342 return -EINVAL;
343 }
344
345 src_val = mux << e->shift_l;
346
347 if (in_type == CS48L32_IN_TYPE_SE)
348 src_val |= 1 << CS48L32_INx_SRC_SHIFT;
349
350 ret = snd_soc_component_update_bits(dapm->component,
351 e->reg,
352 CS48L32_INx_SRC_MASK,
353 src_val);
354 if (ret > 0)
355 snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL);
356
357 return ret;
358 }
359
360 static const char * const cs48l32_inmux_texts[] = {
361 "Analog 1", "Analog 2",
362 };
363
364 static SOC_ENUM_SINGLE_DECL(cs48l32_in1muxl_enum,
365 CS48L32_IN1L_CONTROL1,
366 CS48L32_INx_SRC_SHIFT + 1,
367 cs48l32_inmux_texts);
368
369 static SOC_ENUM_SINGLE_DECL(cs48l32_in1muxr_enum,
370 CS48L32_IN1R_CONTROL1,
371 CS48L32_INx_SRC_SHIFT + 1,
372 cs48l32_inmux_texts);
373
374 static const struct snd_kcontrol_new cs48l32_inmux[] = {
375 SOC_DAPM_ENUM_EXT("IN1L Mux", cs48l32_in1muxl_enum,
376 snd_soc_dapm_get_enum_double, cs48l32_inmux_put),
377 SOC_DAPM_ENUM_EXT("IN1R Mux", cs48l32_in1muxr_enum,
378 snd_soc_dapm_get_enum_double, cs48l32_inmux_put),
379 };
380
381 static const char * const cs48l32_dmode_texts[] = {
382 "Analog", "Digital",
383 };
384
cs48l32_dmode_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)385 static int cs48l32_dmode_put(struct snd_kcontrol *kcontrol,
386 struct snd_ctl_elem_value *ucontrol)
387 {
388 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
389 struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
390 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
391 unsigned int mode;
392 int ret, result;
393
394 mode = ucontrol->value.enumerated.item[0];
395 switch (mode) {
396 case 0:
397 ret = snd_soc_component_update_bits(component,
398 CS48L32_ADC1L_ANA_CONTROL1,
399 CS48L32_ADC1x_INT_ENA_FRC_MASK,
400 CS48L32_ADC1x_INT_ENA_FRC_MASK);
401 if (ret < 0) {
402 dev_err(component->dev,
403 "Failed to set ADC1L_INT_ENA_FRC: %d\n", ret);
404 return ret;
405 }
406
407 ret = snd_soc_component_update_bits(component,
408 CS48L32_ADC1R_ANA_CONTROL1,
409 CS48L32_ADC1x_INT_ENA_FRC_MASK,
410 CS48L32_ADC1x_INT_ENA_FRC_MASK);
411 if (ret < 0) {
412 dev_err(component->dev,
413 "Failed to set ADC1R_INT_ENA_FRC: %d\n", ret);
414 return ret;
415 }
416
417 result = snd_soc_component_update_bits(component,
418 e->reg,
419 BIT(CS48L32_IN1_MODE_SHIFT),
420 0);
421 if (result < 0) {
422 dev_err(component->dev, "Failed to set input mode: %d\n", result);
423 return result;
424 }
425
426 usleep_range(200, 300);
427
428 ret = snd_soc_component_update_bits(component,
429 CS48L32_ADC1L_ANA_CONTROL1,
430 CS48L32_ADC1x_INT_ENA_FRC_MASK,
431 0);
432 if (ret < 0) {
433 dev_err(component->dev,
434 "Failed to clear ADC1L_INT_ENA_FRC: %d\n", ret);
435 return ret;
436 }
437
438 ret = snd_soc_component_update_bits(component,
439 CS48L32_ADC1R_ANA_CONTROL1,
440 CS48L32_ADC1x_INT_ENA_FRC_MASK,
441 0);
442 if (ret < 0) {
443 dev_err(component->dev,
444 "Failed to clear ADC1R_INT_ENA_FRC: %d\n", ret);
445 return ret;
446 }
447
448 if (result > 0)
449 snd_soc_dapm_mux_update_power(dapm, kcontrol, mode, e, NULL);
450
451 return result;
452 case 1:
453 return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
454 default:
455 return -EINVAL;
456 }
457 }
458
459 static SOC_ENUM_SINGLE_DECL(cs48l32_in1dmode_enum,
460 CS48L32_INPUT1_CONTROL1,
461 CS48L32_IN1_MODE_SHIFT,
462 cs48l32_dmode_texts);
463
464 static const struct snd_kcontrol_new cs48l32_dmode_mux[] = {
465 SOC_DAPM_ENUM_EXT("IN1 Mode", cs48l32_in1dmode_enum,
466 snd_soc_dapm_get_enum_double, cs48l32_dmode_put),
467 };
468
469 static const char * const cs48l32_in_texts[] = {
470 "IN1L", "IN1R", "IN2L", "IN2R",
471 };
472 static_assert(ARRAY_SIZE(cs48l32_in_texts) == CS48L32_MAX_INPUT);
473
474 static const char * const cs48l32_us_freq_texts[] = {
475 "16-24kHz", "20-28kHz",
476 };
477
478 static const unsigned int cs48l32_us_freq_val[] = {
479 0x2, 0x3,
480 };
481
482 static const struct soc_enum cs48l32_us_freq[] = {
483 SOC_VALUE_ENUM_SINGLE(CS48L32_US1_CONTROL,
484 CS48L32_US1_FREQ_SHIFT,
485 CS48L32_US1_FREQ_MASK >> CS48L32_US1_FREQ_SHIFT,
486 ARRAY_SIZE(cs48l32_us_freq_val),
487 cs48l32_us_freq_texts,
488 cs48l32_us_freq_val),
489 SOC_VALUE_ENUM_SINGLE(CS48L32_US2_CONTROL,
490 CS48L32_US1_FREQ_SHIFT,
491 CS48L32_US1_FREQ_MASK >> CS48L32_US1_FREQ_SHIFT,
492 ARRAY_SIZE(cs48l32_us_freq_val),
493 cs48l32_us_freq_texts,
494 cs48l32_us_freq_val),
495 };
496
497 static const unsigned int cs48l32_us_in_val[] = {
498 0x0, 0x1, 0x2, 0x3,
499 };
500
501 static const struct soc_enum cs48l32_us_inmux_enum[] = {
502 SOC_VALUE_ENUM_SINGLE(CS48L32_US1_CONTROL,
503 CS48L32_US1_SRC_SHIFT,
504 CS48L32_US1_SRC_MASK >> CS48L32_US1_SRC_SHIFT,
505 ARRAY_SIZE(cs48l32_us_in_val),
506 cs48l32_in_texts,
507 cs48l32_us_in_val),
508 SOC_VALUE_ENUM_SINGLE(CS48L32_US2_CONTROL,
509 CS48L32_US1_SRC_SHIFT,
510 CS48L32_US1_SRC_MASK >> CS48L32_US1_SRC_SHIFT,
511 ARRAY_SIZE(cs48l32_us_in_val),
512 cs48l32_in_texts,
513 cs48l32_us_in_val),
514 };
515
516 static const struct snd_kcontrol_new cs48l32_us_inmux[] = {
517 SOC_DAPM_ENUM("Ultrasonic 1 Input", cs48l32_us_inmux_enum[0]),
518 SOC_DAPM_ENUM("Ultrasonic 2 Input", cs48l32_us_inmux_enum[1]),
519 };
520
521 static const char * const cs48l32_us_det_thr_texts[] = {
522 "-6dB", "-9dB", "-12dB", "-15dB", "-18dB", "-21dB", "-24dB", "-27dB",
523 };
524
525 static const struct soc_enum cs48l32_us_det_thr[] = {
526 SOC_ENUM_SINGLE(CS48L32_US1_DET_CONTROL,
527 CS48L32_US1_DET_THR_SHIFT,
528 ARRAY_SIZE(cs48l32_us_det_thr_texts),
529 cs48l32_us_det_thr_texts),
530 SOC_ENUM_SINGLE(CS48L32_US2_DET_CONTROL,
531 CS48L32_US1_DET_THR_SHIFT,
532 ARRAY_SIZE(cs48l32_us_det_thr_texts),
533 cs48l32_us_det_thr_texts),
534 };
535
536 static const char * const cs48l32_us_det_num_texts[] = {
537 "1 Sample",
538 "2 Samples",
539 "4 Samples",
540 "8 Samples",
541 "16 Samples",
542 "32 Samples",
543 "64 Samples",
544 "128 Samples",
545 "256 Samples",
546 "512 Samples",
547 "1024 Samples",
548 "2048 Samples",
549 "4096 Samples",
550 "8192 Samples",
551 "16384 Samples",
552 "32768 Samples",
553 };
554
555 static const struct soc_enum cs48l32_us_det_num[] = {
556 SOC_ENUM_SINGLE(CS48L32_US1_DET_CONTROL,
557 CS48L32_US1_DET_NUM_SHIFT,
558 ARRAY_SIZE(cs48l32_us_det_num_texts),
559 cs48l32_us_det_num_texts),
560 SOC_ENUM_SINGLE(CS48L32_US2_DET_CONTROL,
561 CS48L32_US1_DET_NUM_SHIFT,
562 ARRAY_SIZE(cs48l32_us_det_num_texts),
563 cs48l32_us_det_num_texts),
564 };
565
566 static const char * const cs48l32_us_det_hold_texts[] = {
567 "0 Samples",
568 "31 Samples",
569 "63 Samples",
570 "127 Samples",
571 "255 Samples",
572 "511 Samples",
573 "1023 Samples",
574 "2047 Samples",
575 "4095 Samples",
576 "8191 Samples",
577 "16383 Samples",
578 "32767 Samples",
579 "65535 Samples",
580 "131071 Samples",
581 "262143 Samples",
582 "524287 Samples",
583 };
584
585 static const struct soc_enum cs48l32_us_det_hold[] = {
586 SOC_ENUM_SINGLE(CS48L32_US1_DET_CONTROL,
587 CS48L32_US1_DET_HOLD_SHIFT,
588 ARRAY_SIZE(cs48l32_us_det_hold_texts),
589 cs48l32_us_det_hold_texts),
590 SOC_ENUM_SINGLE(CS48L32_US2_DET_CONTROL,
591 CS48L32_US1_DET_HOLD_SHIFT,
592 ARRAY_SIZE(cs48l32_us_det_hold_texts),
593 cs48l32_us_det_hold_texts),
594 };
595
596 static const struct soc_enum cs48l32_us_output_rate[] = {
597 SOC_VALUE_ENUM_SINGLE(CS48L32_US1_CONTROL,
598 CS48L32_US1_RATE_SHIFT,
599 CS48L32_US1_RATE_MASK >> CS48L32_US1_RATE_SHIFT,
600 ARRAY_SIZE(cs48l32_rate_text),
601 cs48l32_rate_text,
602 cs48l32_rate_val),
603 SOC_VALUE_ENUM_SINGLE(CS48L32_US2_CONTROL,
604 CS48L32_US1_RATE_SHIFT,
605 CS48L32_US1_RATE_MASK >> CS48L32_US1_RATE_SHIFT,
606 ARRAY_SIZE(cs48l32_rate_text),
607 cs48l32_rate_text,
608 cs48l32_rate_val),
609 };
610
611 static const char * const cs48l32_us_det_lpf_cut_texts[] = {
612 "1722Hz", "833Hz", "408Hz", "203Hz",
613 };
614
615 static const struct soc_enum cs48l32_us_det_lpf_cut[] = {
616 SOC_ENUM_SINGLE(CS48L32_US1_DET_CONTROL,
617 CS48L32_US1_DET_LPF_CUT_SHIFT,
618 ARRAY_SIZE(cs48l32_us_det_lpf_cut_texts),
619 cs48l32_us_det_lpf_cut_texts),
620 SOC_ENUM_SINGLE(CS48L32_US2_DET_CONTROL,
621 CS48L32_US1_DET_LPF_CUT_SHIFT,
622 ARRAY_SIZE(cs48l32_us_det_lpf_cut_texts),
623 cs48l32_us_det_lpf_cut_texts),
624 };
625
626 static const char * const cs48l32_us_det_dcy_texts[] = {
627 "0 ms", "0.79 ms", "1.58 ms", "3.16 ms", "6.33 ms", "12.67 ms", "25.34 ms", "50.69 ms",
628 };
629
630 static const struct soc_enum cs48l32_us_det_dcy[] = {
631 SOC_ENUM_SINGLE(CS48L32_US1_DET_CONTROL,
632 CS48L32_US1_DET_DCY_SHIFT,
633 ARRAY_SIZE(cs48l32_us_det_dcy_texts),
634 cs48l32_us_det_dcy_texts),
635 SOC_ENUM_SINGLE(CS48L32_US2_DET_CONTROL,
636 CS48L32_US1_DET_DCY_SHIFT,
637 ARRAY_SIZE(cs48l32_us_det_dcy_texts),
638 cs48l32_us_det_dcy_texts),
639 };
640
641 static const struct snd_kcontrol_new cs48l32_us_switch[] = {
642 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
643 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
644 };
645
646 static const char * const cs48l32_vol_ramp_text[] = {
647 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", "16ms/6dB", "32ms/6dB",
648 };
649
650 static SOC_ENUM_SINGLE_DECL(cs48l32_in_vd_ramp,
651 CS48L32_INPUT_VOL_CONTROL,
652 CS48L32_IN_VD_RAMP_SHIFT,
653 cs48l32_vol_ramp_text);
654
655 static SOC_ENUM_SINGLE_DECL(cs48l32_in_vi_ramp,
656 CS48L32_INPUT_VOL_CONTROL,
657 CS48L32_IN_VI_RAMP_SHIFT,
658 cs48l32_vol_ramp_text);
659
660 static const char * const cs48l32_in_hpf_cut_text[] = {
661 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
662 };
663
664 static SOC_ENUM_SINGLE_DECL(cs48l32_in_hpf_cut_enum,
665 CS48L32_INPUT_HPF_CONTROL,
666 CS48L32_IN_HPF_CUT_SHIFT,
667 cs48l32_in_hpf_cut_text);
668
669 static const char * const cs48l32_in_dmic_osr_text[] = {
670 "384kHz", "768kHz", "1.536MHz", "2.048MHz", "2.4576MHz", "3.072MHz", "6.144MHz",
671 };
672
673 static const struct soc_enum cs48l32_in_dmic_osr[] = {
674 SOC_ENUM_SINGLE(CS48L32_INPUT1_CONTROL1,
675 CS48L32_IN1_OSR_SHIFT,
676 ARRAY_SIZE(cs48l32_in_dmic_osr_text),
677 cs48l32_in_dmic_osr_text),
678 SOC_ENUM_SINGLE(CS48L32_INPUT2_CONTROL1,
679 CS48L32_IN1_OSR_SHIFT,
680 ARRAY_SIZE(cs48l32_in_dmic_osr_text),
681 cs48l32_in_dmic_osr_text),
682 };
683
cs48l32_is_input_enabled(struct snd_soc_component * component,unsigned int reg)684 static bool cs48l32_is_input_enabled(struct snd_soc_component *component,
685 unsigned int reg)
686 {
687 unsigned int input_active;
688
689 input_active = snd_soc_component_read(component, CS48L32_INPUT_CONTROL);
690 switch (reg) {
691 case CS48L32_IN1L_CONTROL1:
692 return input_active & BIT(CS48L32_IN1L_EN_SHIFT);
693 case CS48L32_IN1R_CONTROL1:
694 return input_active & BIT(CS48L32_IN1R_EN_SHIFT);
695 case CS48L32_IN2L_CONTROL1:
696 return input_active & BIT(CS48L32_IN2L_EN_SHIFT);
697 case CS48L32_IN2R_CONTROL1:
698 return input_active & BIT(CS48L32_IN2R_EN_SHIFT);
699 default:
700 return false;
701 }
702 }
703
cs48l32_in_rate_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)704 static int cs48l32_in_rate_put(struct snd_kcontrol *kcontrol,
705 struct snd_ctl_elem_value *ucontrol)
706 {
707 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
708 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
709 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
710 int ret;
711
712 snd_soc_dapm_mutex_lock(dapm);
713
714 /* Cannot change rate on an active input */
715 if (cs48l32_is_input_enabled(component, e->reg)) {
716 ret = -EBUSY;
717 goto exit;
718 }
719
720 ret = snd_soc_put_enum_double(kcontrol, ucontrol);
721 exit:
722 snd_soc_dapm_mutex_unlock(dapm);
723
724 return ret;
725 }
726
727 static const struct soc_enum cs48l32_input_rate[] = {
728 SOC_VALUE_ENUM_SINGLE(CS48L32_IN1L_CONTROL1,
729 CS48L32_INx_RATE_SHIFT,
730 CS48L32_INx_RATE_MASK >> CS48L32_INx_RATE_SHIFT,
731 ARRAY_SIZE(cs48l32_rate_text),
732 cs48l32_rate_text,
733 cs48l32_rate_val),
734 SOC_VALUE_ENUM_SINGLE(CS48L32_IN1R_CONTROL1,
735 CS48L32_INx_RATE_SHIFT,
736 CS48L32_INx_RATE_MASK >> CS48L32_INx_RATE_SHIFT,
737 ARRAY_SIZE(cs48l32_rate_text),
738 cs48l32_rate_text,
739 cs48l32_rate_val),
740 SOC_VALUE_ENUM_SINGLE(CS48L32_IN2L_CONTROL1,
741 CS48L32_INx_RATE_SHIFT,
742 CS48L32_INx_RATE_MASK >> CS48L32_INx_RATE_SHIFT,
743 ARRAY_SIZE(cs48l32_rate_text),
744 cs48l32_rate_text,
745 cs48l32_rate_val),
746 SOC_VALUE_ENUM_SINGLE(CS48L32_IN2R_CONTROL1,
747 CS48L32_INx_RATE_SHIFT,
748 CS48L32_INx_RATE_MASK >> CS48L32_INx_RATE_SHIFT,
749 ARRAY_SIZE(cs48l32_rate_text),
750 cs48l32_rate_text,
751 cs48l32_rate_val),
752 };
753
cs48l32_low_power_mode_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)754 static int cs48l32_low_power_mode_put(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
756 {
757 struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
758 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
759 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
760 int ret;
761
762 snd_soc_dapm_mutex_lock(dapm);
763
764 /* Cannot change rate on an active input */
765 if (cs48l32_is_input_enabled(component, mc->reg)) {
766 ret = -EBUSY;
767 goto exit;
768 }
769
770 ret = snd_soc_put_volsw(kcontrol, ucontrol);
771
772 exit:
773 snd_soc_dapm_mutex_unlock(dapm);
774 return ret;
775 }
776
777 static const struct soc_enum noise_gen_rate =
778 SOC_VALUE_ENUM_SINGLE(CS48L32_COMFORT_NOISE_GENERATOR,
779 CS48L32_NOISE_GEN_RATE_SHIFT,
780 CS48L32_NOISE_GEN_RATE_MASK >> CS48L32_NOISE_GEN_RATE_SHIFT,
781 ARRAY_SIZE(cs48l32_rate_text),
782 cs48l32_rate_text,
783 cs48l32_rate_val);
784
785 static const char * const cs48l32_auxpdm_freq_texts[] = {
786 "3.072MHz", "2.048MHz", "1.536MHz", "768kHz",
787 };
788
789 static SOC_ENUM_SINGLE_DECL(cs48l32_auxpdm1_freq,
790 CS48L32_AUXPDM1_CONTROL1,
791 CS48L32_AUXPDM1_FREQ_SHIFT,
792 cs48l32_auxpdm_freq_texts);
793
794 static SOC_ENUM_SINGLE_DECL(cs48l32_auxpdm2_freq,
795 CS48L32_AUXPDM2_CONTROL1,
796 CS48L32_AUXPDM1_FREQ_SHIFT,
797 cs48l32_auxpdm_freq_texts);
798
799 static const char * const cs48l32_auxpdm_src_texts[] = {
800 "Analog", "IN1 Digital", "IN2 Digital",
801 };
802
803 static SOC_ENUM_SINGLE_DECL(cs48l32_auxpdm1_in,
804 CS48L32_AUXPDM_CTRL2,
805 CS48L32_AUXPDMDAT1_SRC_SHIFT,
806 cs48l32_auxpdm_src_texts);
807
808 static SOC_ENUM_SINGLE_DECL(cs48l32_auxpdm2_in,
809 CS48L32_AUXPDM_CTRL2,
810 CS48L32_AUXPDMDAT2_SRC_SHIFT,
811 cs48l32_auxpdm_src_texts);
812
813 static const struct snd_kcontrol_new cs48l32_auxpdm_inmux[] = {
814 SOC_DAPM_ENUM("AUXPDM1 Input", cs48l32_auxpdm1_in),
815 SOC_DAPM_ENUM("AUXPDM2 Input", cs48l32_auxpdm2_in),
816 };
817
818 static const unsigned int cs48l32_auxpdm_analog_in_val[] = {
819 0x0, 0x1,
820 };
821
822 static const struct soc_enum cs48l32_auxpdm_analog_inmux_enum[] = {
823 SOC_VALUE_ENUM_SINGLE(CS48L32_AUXPDM1_CONTROL1,
824 CS48L32_AUXPDM1_SRC_SHIFT,
825 CS48L32_AUXPDM1_SRC_MASK >> CS48L32_AUXPDM1_SRC_SHIFT,
826 ARRAY_SIZE(cs48l32_auxpdm_analog_in_val),
827 cs48l32_in_texts,
828 cs48l32_auxpdm_analog_in_val),
829 SOC_VALUE_ENUM_SINGLE(CS48L32_AUXPDM2_CONTROL1,
830 CS48L32_AUXPDM1_SRC_SHIFT,
831 CS48L32_AUXPDM1_SRC_MASK >> CS48L32_AUXPDM1_SRC_SHIFT,
832 ARRAY_SIZE(cs48l32_auxpdm_analog_in_val),
833 cs48l32_in_texts,
834 cs48l32_auxpdm_analog_in_val),
835 };
836
837 static const struct snd_kcontrol_new cs48l32_auxpdm_analog_inmux[] = {
838 SOC_DAPM_ENUM("AUXPDM1 Analog Input", cs48l32_auxpdm_analog_inmux_enum[0]),
839 SOC_DAPM_ENUM("AUXPDM2 Analog Input", cs48l32_auxpdm_analog_inmux_enum[1]),
840 };
841
842 static const struct snd_kcontrol_new cs48l32_auxpdm_switch[] = {
843 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
844 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
845 };
846
847 static const struct soc_enum cs48l32_isrc_fsh[] = {
848 SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC1_CONTROL1,
849 CS48L32_ISRC1_FSH_SHIFT,
850 CS48L32_ISRC1_FSH_MASK >> CS48L32_ISRC1_FSH_SHIFT,
851 ARRAY_SIZE(cs48l32_rate_text),
852 cs48l32_rate_text,
853 cs48l32_rate_val),
854 SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC2_CONTROL1,
855 CS48L32_ISRC1_FSH_SHIFT,
856 CS48L32_ISRC1_FSH_MASK >> CS48L32_ISRC1_FSH_SHIFT,
857 ARRAY_SIZE(cs48l32_rate_text),
858 cs48l32_rate_text,
859 cs48l32_rate_val),
860 SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC3_CONTROL1,
861 CS48L32_ISRC1_FSH_SHIFT,
862 CS48L32_ISRC1_FSH_MASK >> CS48L32_ISRC1_FSH_SHIFT,
863 ARRAY_SIZE(cs48l32_rate_text),
864 cs48l32_rate_text,
865 cs48l32_rate_val),
866 };
867
868 static const struct soc_enum cs48l32_isrc_fsl[] = {
869 SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC1_CONTROL1,
870 CS48L32_ISRC1_FSL_SHIFT,
871 CS48L32_ISRC1_FSL_MASK >> CS48L32_ISRC1_FSL_SHIFT,
872 ARRAY_SIZE(cs48l32_rate_text),
873 cs48l32_rate_text,
874 cs48l32_rate_val),
875 SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC2_CONTROL1,
876 CS48L32_ISRC1_FSL_SHIFT,
877 CS48L32_ISRC1_FSL_MASK >> CS48L32_ISRC1_FSL_SHIFT,
878 ARRAY_SIZE(cs48l32_rate_text),
879 cs48l32_rate_text,
880 cs48l32_rate_val),
881 SOC_VALUE_ENUM_SINGLE(CS48L32_ISRC3_CONTROL1,
882 CS48L32_ISRC1_FSL_SHIFT,
883 CS48L32_ISRC1_FSL_MASK >> CS48L32_ISRC1_FSL_SHIFT,
884 ARRAY_SIZE(cs48l32_rate_text),
885 cs48l32_rate_text,
886 cs48l32_rate_val),
887 };
888
889 static const struct soc_enum cs48l32_fx_rate =
890 SOC_VALUE_ENUM_SINGLE(CS48L32_FX_SAMPLE_RATE,
891 CS48L32_FX_RATE_SHIFT,
892 CS48L32_FX_RATE_MASK >> CS48L32_FX_RATE_SHIFT,
893 ARRAY_SIZE(cs48l32_rate_text),
894 cs48l32_rate_text,
895 cs48l32_rate_val);
896
897 static const char * const cs48l32_lhpf_mode_text[] = {
898 "Low-pass", "High-pass"
899 };
900
901 static const struct soc_enum cs48l32_lhpf_mode[] = {
902 SOC_ENUM_SINGLE(CS48L32_LHPF_CONTROL2, 0,
903 ARRAY_SIZE(cs48l32_lhpf_mode_text), cs48l32_lhpf_mode_text),
904 SOC_ENUM_SINGLE(CS48L32_LHPF_CONTROL2, 1,
905 ARRAY_SIZE(cs48l32_lhpf_mode_text), cs48l32_lhpf_mode_text),
906 SOC_ENUM_SINGLE(CS48L32_LHPF_CONTROL2, 2,
907 ARRAY_SIZE(cs48l32_lhpf_mode_text), cs48l32_lhpf_mode_text),
908 SOC_ENUM_SINGLE(CS48L32_LHPF_CONTROL2, 3,
909 ARRAY_SIZE(cs48l32_lhpf_mode_text), cs48l32_lhpf_mode_text),
910 };
911
cs48l32_lhpf_coeff_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)912 static int cs48l32_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
913 struct snd_ctl_elem_value *ucontrol)
914 {
915 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
916 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
917 __be32 *data = (__be32 *)ucontrol->value.bytes.data;
918 s16 val = (s16)be32_to_cpu(*data);
919
920 if (abs(val) > CS48L32_LHPF_MAX_COEFF) {
921 dev_err(cs48l32_codec->core.dev, "Rejecting unstable LHPF coefficients\n");
922 return -EINVAL;
923 }
924
925 return snd_soc_bytes_put(kcontrol, ucontrol);
926 }
927
928 static const char * const cs48l32_eq_mode_text[] = {
929 "Low-pass", "High-pass",
930 };
931
932 static const struct soc_enum cs48l32_eq_mode[] = {
933 SOC_ENUM_SINGLE(CS48L32_EQ_CONTROL2, 0,
934 ARRAY_SIZE(cs48l32_eq_mode_text),
935 cs48l32_eq_mode_text),
936 SOC_ENUM_SINGLE(CS48L32_EQ_CONTROL2, 1,
937 ARRAY_SIZE(cs48l32_eq_mode_text),
938 cs48l32_eq_mode_text),
939 SOC_ENUM_SINGLE(CS48L32_EQ_CONTROL2, 2,
940 ARRAY_SIZE(cs48l32_eq_mode_text),
941 cs48l32_eq_mode_text),
942 SOC_ENUM_SINGLE(CS48L32_EQ_CONTROL2, 3,
943 ARRAY_SIZE(cs48l32_eq_mode_text),
944 cs48l32_eq_mode_text),
945 };
946
cs48l32_eq_mode_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)947 static int cs48l32_eq_mode_get(struct snd_kcontrol *kcontrol,
948 struct snd_ctl_elem_value *ucontrol)
949 {
950 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
951 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
952 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
953 unsigned int item;
954
955 item = snd_soc_enum_val_to_item(e, cs48l32_codec->eq_mode[e->shift_l]);
956 ucontrol->value.enumerated.item[0] = item;
957
958 return 0;
959 }
960
cs48l32_eq_mode_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)961 static int cs48l32_eq_mode_put(struct snd_kcontrol *kcontrol,
962 struct snd_ctl_elem_value *ucontrol)
963 {
964 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
965 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
966 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
967 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
968 unsigned int *item = ucontrol->value.enumerated.item;
969 unsigned int val;
970 bool changed = false;
971
972 if (item[0] >= e->items)
973 return -EINVAL;
974
975 val = snd_soc_enum_item_to_val(e, item[0]);
976
977 snd_soc_dapm_mutex_lock(dapm);
978 if (cs48l32_codec->eq_mode[e->shift_l] != val) {
979 cs48l32_codec->eq_mode[e->shift_l] = val;
980 changed = true;
981 }
982 snd_soc_dapm_mutex_unlock(dapm);
983
984 return changed;
985 }
986
cs48l32_eq_coeff_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)987 static int cs48l32_eq_coeff_info(struct snd_kcontrol *kcontrol,
988 struct snd_ctl_elem_info *uinfo)
989 {
990 struct cs48l32_eq_control *ctl = (void *) kcontrol->private_value;
991
992 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
993 uinfo->count = 1;
994 uinfo->value.integer.min = 0;
995 uinfo->value.integer.max = ctl->max;
996
997 return 0;
998 }
999
cs48l32_eq_coeff_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1000 static int cs48l32_eq_coeff_get(struct snd_kcontrol *kcontrol,
1001 struct snd_ctl_elem_value *ucontrol)
1002 {
1003 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1004 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1005 struct cs48l32_eq_control *params = (void *)kcontrol->private_value;
1006 __be16 *coeffs;
1007 unsigned int coeff_idx;
1008 int block_idx;
1009
1010 block_idx = ((int) params->block_base - (int) CS48L32_EQ1_BAND1_COEFF1);
1011 block_idx /= (CS48L32_EQ2_BAND1_COEFF1 - CS48L32_EQ1_BAND1_COEFF1);
1012
1013 coeffs = &cs48l32_codec->eq_coefficients[block_idx][0];
1014 coeff_idx = (params->reg - params->block_base) / 2;
1015
1016 /* High __be16 is in [coeff_idx] and low __be16 in [coeff_idx + 1] */
1017 if (params->shift == 0)
1018 coeff_idx++;
1019
1020 ucontrol->value.integer.value[0] = be16_to_cpu(coeffs[coeff_idx]);
1021
1022 return 0;
1023 }
1024
cs48l32_eq_coeff_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1025 static int cs48l32_eq_coeff_put(struct snd_kcontrol *kcontrol,
1026 struct snd_ctl_elem_value *ucontrol)
1027 {
1028 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1029 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1030 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1031 struct cs48l32_eq_control *params = (void *)kcontrol->private_value;
1032 __be16 *coeffs;
1033 unsigned int coeff_idx;
1034 int block_idx;
1035
1036 block_idx = ((int) params->block_base - (int) CS48L32_EQ1_BAND1_COEFF1);
1037 block_idx /= (CS48L32_EQ2_BAND1_COEFF1 - CS48L32_EQ1_BAND1_COEFF1);
1038
1039 coeffs = &cs48l32_codec->eq_coefficients[block_idx][0];
1040 coeff_idx = (params->reg - params->block_base) / 2;
1041
1042 /* Put high __be16 in [coeff_idx] and low __be16 in [coeff_idx + 1] */
1043 if (params->shift == 0)
1044 coeff_idx++;
1045
1046 snd_soc_dapm_mutex_lock(dapm);
1047 coeffs[coeff_idx] = cpu_to_be16(ucontrol->value.integer.value[0]);
1048 snd_soc_dapm_mutex_unlock(dapm);
1049
1050 return 0;
1051 }
1052
1053 static const struct snd_kcontrol_new cs48l32_drc_activity_output_mux[] = {
1054 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
1055 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
1056 };
1057
1058 static const struct snd_kcontrol_new cs48l32_dsp_trigger_output_mux[] = {
1059 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
1060 };
1061
cs48l32_dsp_rate_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1062 static int cs48l32_dsp_rate_get(struct snd_kcontrol *kcontrol,
1063 struct snd_ctl_elem_value *ucontrol)
1064 {
1065 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1066 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1067 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
1068 unsigned int cached_rate;
1069 const unsigned int rate_num = e->mask;
1070 int item;
1071
1072 if (rate_num >= ARRAY_SIZE(cs48l32_codec->dsp_dma_rates))
1073 return -EINVAL;
1074
1075 cached_rate = cs48l32_codec->dsp_dma_rates[rate_num];
1076 item = snd_soc_enum_val_to_item(e, cached_rate);
1077 ucontrol->value.enumerated.item[0] = item;
1078
1079 return 0;
1080 }
1081
cs48l32_dsp_rate_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1082 static int cs48l32_dsp_rate_put(struct snd_kcontrol *kcontrol,
1083 struct snd_ctl_elem_value *ucontrol)
1084 {
1085 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1086 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1087 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1088 struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
1089 const unsigned int rate_num = e->mask;
1090 const unsigned int item = ucontrol->value.enumerated.item[0];
1091 unsigned int val;
1092 bool changed = false;
1093
1094 if (item >= e->items)
1095 return -EINVAL;
1096
1097 if (rate_num >= ARRAY_SIZE(cs48l32_codec->dsp_dma_rates))
1098 return -EINVAL;
1099
1100 val = snd_soc_enum_item_to_val(e, item);
1101
1102 snd_soc_dapm_mutex_lock(dapm);
1103 if (cs48l32_codec->dsp_dma_rates[rate_num] != val) {
1104 cs48l32_codec->dsp_dma_rates[rate_num] = val;
1105 changed = true;
1106 }
1107 snd_soc_dapm_mutex_unlock(dapm);
1108
1109 return changed;
1110 }
1111
1112 static const struct soc_enum cs48l32_dsp_rate_enum[] = {
1113 /* RX rates */
1114 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1115 0,
1116 ARRAY_SIZE(cs48l32_rate_text),
1117 cs48l32_rate_text, cs48l32_rate_val),
1118 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1119 1,
1120 ARRAY_SIZE(cs48l32_rate_text),
1121 cs48l32_rate_text, cs48l32_rate_val),
1122 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1123 2,
1124 ARRAY_SIZE(cs48l32_rate_text),
1125 cs48l32_rate_text, cs48l32_rate_val),
1126 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1127 3,
1128 ARRAY_SIZE(cs48l32_rate_text),
1129 cs48l32_rate_text, cs48l32_rate_val),
1130 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1131 4,
1132 ARRAY_SIZE(cs48l32_rate_text),
1133 cs48l32_rate_text, cs48l32_rate_val),
1134 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1135 5,
1136 ARRAY_SIZE(cs48l32_rate_text),
1137 cs48l32_rate_text, cs48l32_rate_val),
1138 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1139 6,
1140 ARRAY_SIZE(cs48l32_rate_text),
1141 cs48l32_rate_text, cs48l32_rate_val),
1142 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1143 7,
1144 ARRAY_SIZE(cs48l32_rate_text),
1145 cs48l32_rate_text, cs48l32_rate_val),
1146 /* TX rates */
1147 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1148 8,
1149 ARRAY_SIZE(cs48l32_rate_text),
1150 cs48l32_rate_text, cs48l32_rate_val),
1151 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1152 9,
1153 ARRAY_SIZE(cs48l32_rate_text),
1154 cs48l32_rate_text, cs48l32_rate_val),
1155 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1156 10,
1157 ARRAY_SIZE(cs48l32_rate_text),
1158 cs48l32_rate_text, cs48l32_rate_val),
1159 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1160 11,
1161 ARRAY_SIZE(cs48l32_rate_text),
1162 cs48l32_rate_text, cs48l32_rate_val),
1163 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1164 12,
1165 ARRAY_SIZE(cs48l32_rate_text),
1166 cs48l32_rate_text, cs48l32_rate_val),
1167 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1168 13,
1169 ARRAY_SIZE(cs48l32_rate_text),
1170 cs48l32_rate_text, cs48l32_rate_val),
1171 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1172 14,
1173 ARRAY_SIZE(cs48l32_rate_text),
1174 cs48l32_rate_text, cs48l32_rate_val),
1175 SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0,
1176 15,
1177 ARRAY_SIZE(cs48l32_rate_text),
1178 cs48l32_rate_text, cs48l32_rate_val),
1179 };
1180
cs48l32_dsp_pre_run(struct wm_adsp * dsp)1181 static int cs48l32_dsp_pre_run(struct wm_adsp *dsp)
1182 {
1183 struct cs48l32_codec *cs48l32_codec = container_of(dsp, struct cs48l32_codec, dsp);
1184 unsigned int reg;
1185 const u8 *rate = cs48l32_codec->dsp_dma_rates;
1186 int i;
1187
1188 reg = dsp->cs_dsp.base + CS48L32_HALO_SAMPLE_RATE_RX1;
1189 for (i = 0; i < CS48L32_DSP_N_RX_CHANNELS; ++i) {
1190 regmap_update_bits(dsp->cs_dsp.regmap, reg, CS48L32_HALO_DSP_RATE_MASK, *rate);
1191 reg += 8;
1192 rate++;
1193 }
1194
1195 reg = dsp->cs_dsp.base + CS48L32_HALO_SAMPLE_RATE_TX1;
1196 for (i = 0; i < CS48L32_DSP_N_TX_CHANNELS; ++i) {
1197 regmap_update_bits(dsp->cs_dsp.regmap, reg, CS48L32_HALO_DSP_RATE_MASK, *rate);
1198 reg += 8;
1199 rate++;
1200 }
1201
1202 usleep_range(300, 600);
1203
1204 return 0;
1205 }
1206
cs48l32_dsp_memory_disable(struct cs48l32_codec * cs48l32_codec,const struct cs48l32_dsp_power_regs * regs)1207 static void cs48l32_dsp_memory_disable(struct cs48l32_codec *cs48l32_codec,
1208 const struct cs48l32_dsp_power_regs *regs)
1209 {
1210 struct regmap *regmap = cs48l32_codec->core.regmap;
1211 int i, j, ret;
1212
1213 for (i = 0; i < regs->n_pwd; ++i) {
1214 ret = regmap_write(regmap, regs->pwd[i], 0);
1215 if (ret)
1216 goto err;
1217 }
1218
1219 for (i = 0; i < regs->n_ext; ++i) {
1220 for (j = regs->ext[i].start; j <= regs->ext[i].end; j += 4) {
1221 ret = regmap_write(regmap, j, 0);
1222 if (ret)
1223 goto err;
1224 }
1225 }
1226
1227 return;
1228
1229 err:
1230 dev_warn(cs48l32_codec->core.dev, "Failed to write SRAM enables (%d)\n", ret);
1231 }
1232
cs48l32_dsp_memory_enable(struct cs48l32_codec * cs48l32_codec,const struct cs48l32_dsp_power_regs * regs)1233 static int cs48l32_dsp_memory_enable(struct cs48l32_codec *cs48l32_codec,
1234 const struct cs48l32_dsp_power_regs *regs)
1235 {
1236 struct regmap *regmap = cs48l32_codec->core.regmap;
1237 int i, j, ret;
1238
1239 /* disable power-off */
1240 for (i = 0; i < regs->n_ext; ++i) {
1241 for (j = regs->ext[i].start; j <= regs->ext[i].end; j += 4) {
1242 ret = regmap_write(regmap, j, 0x3);
1243 if (ret)
1244 goto err;
1245 }
1246 }
1247
1248 /* power-up the banks in sequence */
1249 for (i = 0; i < regs->n_pwd; ++i) {
1250 ret = regmap_write(regmap, regs->pwd[i], 0x1);
1251 if (ret)
1252 goto err;
1253
1254 udelay(1); /* allow bank to power-up */
1255
1256 ret = regmap_write(regmap, regs->pwd[i], 0x3);
1257 if (ret)
1258 goto err;
1259
1260 udelay(1); /* allow bank to power-up */
1261 }
1262
1263 return 0;
1264
1265 err:
1266 dev_err(cs48l32_codec->core.dev, "Failed to write SRAM enables (%d)\n", ret);
1267 cs48l32_dsp_memory_disable(cs48l32_codec, regs);
1268
1269 return ret;
1270 }
1271
cs48l32_dsp_freq_update(struct snd_soc_dapm_widget * w,unsigned int freq_reg,unsigned int freqsel_reg)1272 static int cs48l32_dsp_freq_update(struct snd_soc_dapm_widget *w, unsigned int freq_reg,
1273 unsigned int freqsel_reg)
1274 {
1275 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1276 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1277 struct regmap *regmap = cs48l32_codec->core.regmap;
1278 struct wm_adsp *dsp = &cs48l32_codec->dsp;
1279 int ret;
1280 unsigned int freq, freq_sel, freq_sts;
1281
1282 if (!freq_reg)
1283 return -EINVAL;
1284
1285 ret = regmap_read(regmap, freq_reg, &freq);
1286 if (ret) {
1287 dev_err(component->dev, "Failed to read #%x: %d\n", freq_reg, ret);
1288 return ret;
1289 }
1290
1291 if (freqsel_reg) {
1292 freq_sts = (freq & CS48L32_SYSCLK_FREQ_STS_MASK) >> CS48L32_SYSCLK_FREQ_STS_SHIFT;
1293
1294 ret = regmap_read(regmap, freqsel_reg, &freq_sel);
1295 if (ret) {
1296 dev_err(component->dev, "Failed to read #%x: %d\n", freqsel_reg, ret);
1297 return ret;
1298 }
1299 freq_sel = (freq_sel & CS48L32_SYSCLK_FREQ_MASK) >> CS48L32_SYSCLK_FREQ_SHIFT;
1300
1301 if (freq_sts != freq_sel) {
1302 dev_err(component->dev, "SYSCLK FREQ (#%x) != FREQ STS (#%x)\n",
1303 freq_sel, freq_sts);
1304 return -ETIMEDOUT;
1305 }
1306 }
1307
1308 freq &= CS48L32_DSP_CLK_FREQ_MASK;
1309 freq >>= CS48L32_DSP_CLK_FREQ_SHIFT;
1310
1311 ret = regmap_write(dsp->cs_dsp.regmap,
1312 dsp->cs_dsp.base + CS48L32_DSP_CLOCK_FREQ_OFFS, freq);
1313 if (ret) {
1314 dev_err(component->dev, "Failed to set HALO clock freq: %d\n", ret);
1315 return ret;
1316 }
1317
1318 return 0;
1319 }
1320
cs48l32_dsp_freq_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1321 static int cs48l32_dsp_freq_ev(struct snd_soc_dapm_widget *w,
1322 struct snd_kcontrol *kcontrol, int event)
1323 {
1324 switch (event) {
1325 case SND_SOC_DAPM_POST_PMU:
1326 return cs48l32_dsp_freq_update(w, CS48L32_SYSTEM_CLOCK2, CS48L32_SYSTEM_CLOCK1);
1327 default:
1328 return 0;
1329 }
1330 }
1331
cs48l32_irq(int irq,void * data)1332 static irqreturn_t cs48l32_irq(int irq, void *data)
1333 {
1334 static const unsigned int eint1_regs[] = {
1335 CS48L32_IRQ1_EINT_9, CS48L32_IRQ1_MASK_9,
1336 CS48L32_IRQ1_EINT_7, CS48L32_IRQ1_MASK_7
1337 };
1338 u32 reg_vals[4];
1339 struct cs48l32_codec *cs48l32_codec = data;
1340 struct regmap *regmap = cs48l32_codec->core.regmap;
1341 irqreturn_t result = IRQ_NONE;
1342 unsigned int eint_pending;
1343 int i, ret;
1344
1345 static_assert(ARRAY_SIZE(eint1_regs) == ARRAY_SIZE(reg_vals));
1346
1347 ret = pm_runtime_resume_and_get(cs48l32_codec->core.dev);
1348 if (ret) {
1349 dev_warn(cs48l32_codec->core.dev, "irq could not get pm runtime: %d\n", ret);
1350 return IRQ_NONE;
1351 }
1352
1353 ret = regmap_read(regmap, CS48L32_IRQ1_STATUS, &eint_pending);
1354 if (ret) {
1355 dev_warn(cs48l32_codec->core.dev, "Read IRQ1_STATUS failed: %d\n", ret);
1356 return IRQ_NONE;
1357 }
1358 if ((eint_pending & CS48L32_IRQ1_STS_MASK) == 0)
1359 goto out;
1360
1361 ret = regmap_multi_reg_read(regmap, eint1_regs, reg_vals, ARRAY_SIZE(reg_vals));
1362 if (ret) {
1363 dev_warn(cs48l32_codec->core.dev, "Read IRQ regs failed: %d\n", ret);
1364 return IRQ_NONE;
1365 }
1366
1367 for (i = 0; i < ARRAY_SIZE(reg_vals); i += 2) {
1368 reg_vals[i] &= ~reg_vals[i + 1];
1369 regmap_write(regmap, eint1_regs[i], reg_vals[i]);
1370 }
1371
1372 if (reg_vals[0] & CS48L32_DSP1_IRQ0_EINT1_MASK)
1373 wm_adsp_compr_handle_irq(&cs48l32_codec->dsp);
1374
1375 if (reg_vals[2] & CS48L32_DSP1_MPU_ERR_EINT1_MASK) {
1376 dev_warn(cs48l32_codec->core.dev, "MPU err IRQ\n");
1377 wm_halo_bus_error(irq, &cs48l32_codec->dsp);
1378 }
1379
1380 if (reg_vals[2] & CS48L32_DSP1_WDT_EXPIRE_EINT1_MASK) {
1381 dev_warn(cs48l32_codec->core.dev, "WDT expire IRQ\n");
1382 wm_halo_wdt_expire(irq, &cs48l32_codec->dsp);
1383 }
1384
1385 result = IRQ_HANDLED;
1386
1387 out:
1388 pm_runtime_put_autosuspend(cs48l32_codec->core.dev);
1389
1390 return result;
1391 }
1392
cs48l32_get_dspclk_setting(struct cs48l32_codec * cs48l32_codec,unsigned int freq,int src,unsigned int * val)1393 static int cs48l32_get_dspclk_setting(struct cs48l32_codec *cs48l32_codec, unsigned int freq,
1394 int src, unsigned int *val)
1395 {
1396 freq /= 15625; /* convert to 1/64ths of 1MHz */
1397 *val |= freq << CS48L32_DSP_CLK_FREQ_SHIFT;
1398
1399 return 0;
1400 }
1401
cs48l32_get_sysclk_setting(unsigned int freq)1402 static int cs48l32_get_sysclk_setting(unsigned int freq)
1403 {
1404 switch (freq) {
1405 case 0:
1406 case 5644800:
1407 case 6144000:
1408 return CS48L32_SYSCLK_RATE_6MHZ;
1409 case 11289600:
1410 case 12288000:
1411 return CS48L32_SYSCLK_RATE_12MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1412 case 22579200:
1413 case 24576000:
1414 return CS48L32_SYSCLK_RATE_24MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1415 case 45158400:
1416 case 49152000:
1417 return CS48L32_SYSCLK_RATE_49MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1418 case 90316800:
1419 case 98304000:
1420 return CS48L32_SYSCLK_RATE_98MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1421 default:
1422 return -EINVAL;
1423 }
1424 }
1425
cs48l32_set_pdm_fllclk(struct snd_soc_component * component,int source)1426 static int cs48l32_set_pdm_fllclk(struct snd_soc_component *component, int source)
1427 {
1428 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1429 struct regmap *regmap = cs48l32_codec->core.regmap;
1430 unsigned int val;
1431
1432 switch (source) {
1433 case CS48L32_PDMCLK_SRC_IN1_PDMCLK:
1434 case CS48L32_PDMCLK_SRC_IN2_PDMCLK:
1435 case CS48L32_PDMCLK_SRC_IN3_PDMCLK:
1436 case CS48L32_PDMCLK_SRC_IN4_PDMCLK:
1437 case CS48L32_PDMCLK_SRC_AUXPDM1_CLK:
1438 case CS48L32_PDMCLK_SRC_AUXPDM2_CLK:
1439 val = source << CS48L32_PDM_FLLCLK_SRC_SHIFT;
1440 break;
1441 default:
1442 dev_err(cs48l32_codec->core.dev, "Invalid PDM FLLCLK src %d\n", source);
1443 return -EINVAL;
1444 }
1445
1446 return regmap_update_bits(regmap, CS48L32_INPUT_CONTROL2,
1447 CS48L32_PDM_FLLCLK_SRC_MASK, val);
1448 }
1449
cs48l32_set_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)1450 static int cs48l32_set_sysclk(struct snd_soc_component *component, int clk_id, int source,
1451 unsigned int freq, int dir)
1452 {
1453 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1454 struct regmap *regmap = cs48l32_codec->core.regmap;
1455 char *name;
1456 unsigned int reg;
1457 unsigned int mask = CS48L32_SYSCLK_SRC_MASK;
1458 unsigned int val = source << CS48L32_SYSCLK_SRC_SHIFT;
1459 int clk_freq_sel, *clk;
1460
1461 switch (clk_id) {
1462 case CS48L32_CLK_SYSCLK_1:
1463 name = "SYSCLK";
1464 reg = CS48L32_SYSTEM_CLOCK1;
1465 clk = &cs48l32_codec->sysclk;
1466 clk_freq_sel = cs48l32_get_sysclk_setting(freq);
1467 mask |= CS48L32_SYSCLK_FREQ_MASK | CS48L32_SYSCLK_FRAC_MASK;
1468 break;
1469 case CS48L32_CLK_DSPCLK:
1470 name = "DSPCLK";
1471 reg = CS48L32_DSP_CLOCK1;
1472 clk = &cs48l32_codec->dspclk;
1473 clk_freq_sel = cs48l32_get_dspclk_setting(cs48l32_codec, freq, source, &val);
1474 mask |= CS48L32_DSP_CLK_FREQ_MASK;
1475 break;
1476 case CS48L32_CLK_PDM_FLLCLK:
1477 return cs48l32_set_pdm_fllclk(component, source);
1478 default:
1479 return -EINVAL;
1480 }
1481
1482 if (clk_freq_sel < 0) {
1483 dev_err(cs48l32_codec->core.dev, "Failed to get %s setting for %dHZ\n", name, freq);
1484 return clk_freq_sel;
1485 }
1486
1487 *clk = freq;
1488
1489 if (freq == 0) {
1490 dev_dbg(cs48l32_codec->core.dev, "%s cleared\n", name);
1491 return 0;
1492 }
1493
1494 val |= clk_freq_sel;
1495
1496 if (freq % 6144000)
1497 val |= CS48L32_SYSCLK_FRAC_MASK;
1498
1499 dev_dbg(cs48l32_codec->core.dev, "%s set to %uHz", name, freq);
1500
1501 return regmap_update_bits(regmap, reg, mask, val);
1502 }
1503
cs48l32_is_enabled_fll(struct cs48l32_fll * fll,int base)1504 static int cs48l32_is_enabled_fll(struct cs48l32_fll *fll, int base)
1505 {
1506 struct regmap *regmap = fll->codec->core.regmap;
1507 unsigned int reg;
1508 int ret;
1509
1510 ret = regmap_read(regmap, base + CS48L32_FLL_CONTROL1_OFFS, ®);
1511 if (ret != 0) {
1512 cs48l32_fll_err(fll, "Failed to read current state: %d\n", ret);
1513 return ret;
1514 }
1515
1516 return reg & CS48L32_FLL_EN_MASK;
1517 }
1518
cs48l32_wait_for_fll(struct cs48l32_fll * fll,bool requested)1519 static int cs48l32_wait_for_fll(struct cs48l32_fll *fll, bool requested)
1520 {
1521 struct regmap *regmap = fll->codec->core.regmap;
1522 unsigned int val = 0;
1523 int i;
1524
1525 cs48l32_fll_dbg(fll, "Waiting for FLL...\n");
1526
1527 for (i = 0; i < 30; i++) {
1528 regmap_read(regmap, fll->sts_addr, &val);
1529 if (!!(val & fll->sts_mask) == requested)
1530 return 0;
1531
1532 switch (i) {
1533 case 0 ... 5:
1534 usleep_range(75, 125);
1535 break;
1536 case 6 ... 20:
1537 usleep_range(750, 1250);
1538 break;
1539 default:
1540 fsleep(20000);
1541 break;
1542 }
1543 }
1544
1545 cs48l32_fll_warn(fll, "Timed out waiting for %s\n", requested ? "lock" : "unlock");
1546
1547 return -ETIMEDOUT;
1548 }
1549
cs48l32_fllhj_disable(struct cs48l32_fll * fll)1550 static int cs48l32_fllhj_disable(struct cs48l32_fll *fll)
1551 {
1552 struct cs48l32 *cs48l32 = &fll->codec->core;
1553 bool change;
1554
1555 cs48l32_fll_dbg(fll, "Disabling FLL\n");
1556
1557 /*
1558 * Disable lockdet, but don't set ctrl_upd update bit. This allows the
1559 * lock status bit to clear as normal, but should the FLL be enabled
1560 * again due to a control clock being required, the lock won't re-assert
1561 * as the FLL config registers are automatically applied when the FLL
1562 * enables.
1563 */
1564 regmap_set_bits(cs48l32->regmap,
1565 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1566 CS48L32_FLL_HOLD_MASK);
1567 regmap_clear_bits(cs48l32->regmap,
1568 fll->base + CS48L32_FLL_CONTROL2_OFFS,
1569 CS48L32_FLL_LOCKDET_MASK);
1570 regmap_set_bits(cs48l32->regmap,
1571 fll->base + CS48L32_FLL_CONTROL5_OFFS,
1572 CS48L32_FLL_FRC_INTEG_UPD_MASK);
1573 regmap_update_bits_check(cs48l32->regmap,
1574 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1575 CS48L32_FLL_EN_MASK,
1576 0,
1577 &change);
1578
1579 cs48l32_wait_for_fll(fll, false);
1580
1581 /*
1582 * ctrl_up gates the writes to all the fll's registers, setting it to 0
1583 * here ensures that after a runtime suspend/resume cycle when one
1584 * enables the fll then ctrl_up is the last bit that is configured
1585 * by the fll enable code rather than the cache sync operation which
1586 * would have updated it much earlier before writing out all fll
1587 * registers
1588 */
1589 regmap_clear_bits(cs48l32->regmap,
1590 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1591 CS48L32_FLL_CTRL_UPD_MASK);
1592
1593 if (change)
1594 pm_runtime_put_autosuspend(cs48l32->dev);
1595
1596 return 0;
1597 }
1598
cs48l32_fllhj_apply(struct cs48l32_fll * fll,int fin)1599 static int cs48l32_fllhj_apply(struct cs48l32_fll *fll, int fin)
1600 {
1601 struct regmap *regmap = fll->codec->core.regmap;
1602 int refdiv, fref, fout, lockdet_thr, fbdiv, fllgcd;
1603 bool frac = false;
1604 unsigned int fll_n, min_n, max_n, ratio, theta, lambda, hp;
1605 unsigned int gains, num;
1606
1607 cs48l32_fll_dbg(fll, "fin=%d, fout=%d\n", fin, fll->fout);
1608
1609 for (refdiv = 0; refdiv < 4; refdiv++) {
1610 if ((fin / (1 << refdiv)) <= CS48L32_FLLHJ_MAX_THRESH)
1611 break;
1612 }
1613
1614 fref = fin / (1 << refdiv);
1615 fout = fll->fout;
1616 frac = fout % fref;
1617
1618 /*
1619 * Use simple heuristic approach to find a configuration that
1620 * should work for most input clocks.
1621 */
1622 if (fref < CS48L32_FLLHJ_LOW_THRESH) {
1623 lockdet_thr = 2;
1624 gains = CS48L32_FLLHJ_LOW_GAINS;
1625
1626 if (frac)
1627 fbdiv = 256;
1628 else
1629 fbdiv = 4;
1630 } else if (fref < CS48L32_FLLHJ_MID_THRESH) {
1631 lockdet_thr = 8;
1632 gains = CS48L32_FLLHJ_MID_GAINS;
1633 fbdiv = (frac) ? 16 : 2;
1634 } else {
1635 lockdet_thr = 8;
1636 gains = CS48L32_FLLHJ_HIGH_GAINS;
1637 fbdiv = 1;
1638 }
1639 /* Use high performance mode for fractional configurations. */
1640 if (frac) {
1641 hp = 3;
1642 min_n = CS48L32_FLLHJ_FRAC_MIN_N;
1643 max_n = CS48L32_FLLHJ_FRAC_MAX_N;
1644 } else {
1645 if (fref < CS48L32_FLLHJ_LP_INT_MODE_THRESH)
1646 hp = 0;
1647 else
1648 hp = 1;
1649
1650 min_n = CS48L32_FLLHJ_INT_MIN_N;
1651 max_n = CS48L32_FLLHJ_INT_MAX_N;
1652 }
1653
1654 ratio = fout / fref;
1655
1656 cs48l32_fll_dbg(fll, "refdiv=%d, fref=%d, frac:%d\n", refdiv, fref, frac);
1657
1658 while (ratio / fbdiv < min_n) {
1659 fbdiv /= 2;
1660 if (fbdiv < min_n) {
1661 cs48l32_fll_err(fll, "FBDIV (%u) < minimum N (%u)\n", fbdiv, min_n);
1662 return -EINVAL;
1663 }
1664 }
1665 while (frac && (ratio / fbdiv > max_n)) {
1666 fbdiv *= 2;
1667 if (fbdiv >= 1024) {
1668 cs48l32_fll_err(fll, "FBDIV (%u) >= 1024\n", fbdiv);
1669 return -EINVAL;
1670 }
1671 }
1672
1673 cs48l32_fll_dbg(fll, "lockdet=%d, hp=#%x, fbdiv:%d\n", lockdet_thr, hp, fbdiv);
1674
1675 /* Calculate N.K values */
1676 fllgcd = gcd(fout, fbdiv * fref);
1677 num = fout / fllgcd;
1678 lambda = (fref * fbdiv) / fllgcd;
1679 fll_n = num / lambda;
1680 theta = num % lambda;
1681
1682 cs48l32_fll_dbg(fll, "fll_n=%d, gcd=%d, theta=%d, lambda=%d\n",
1683 fll_n, fllgcd, theta, lambda);
1684
1685 /* Some sanity checks before any registers are written. */
1686 if (fll_n < min_n || fll_n > max_n) {
1687 cs48l32_fll_err(fll, "N not in valid %s mode range %d-%d: %d\n",
1688 frac ? "fractional" : "integer", min_n, max_n, fll_n);
1689 return -EINVAL;
1690 }
1691 if (fbdiv < 1 || (frac && fbdiv >= 1024) || (!frac && fbdiv >= 256)) {
1692 cs48l32_fll_err(fll, "Invalid fbdiv for %s mode (%u)\n",
1693 frac ? "fractional" : "integer", fbdiv);
1694 return -EINVAL;
1695 }
1696
1697 /* clear the ctrl_upd bit to guarantee we write to it later. */
1698 regmap_update_bits(regmap,
1699 fll->base + CS48L32_FLL_CONTROL2_OFFS,
1700 CS48L32_FLL_LOCKDET_THR_MASK |
1701 CS48L32_FLL_PHASEDET_MASK |
1702 CS48L32_FLL_REFCLK_DIV_MASK |
1703 CS48L32_FLL_N_MASK |
1704 CS48L32_FLL_CTRL_UPD_MASK,
1705 (lockdet_thr << CS48L32_FLL_LOCKDET_THR_SHIFT) |
1706 (1 << CS48L32_FLL_PHASEDET_SHIFT) |
1707 (refdiv << CS48L32_FLL_REFCLK_DIV_SHIFT) |
1708 (fll_n << CS48L32_FLL_N_SHIFT));
1709
1710 regmap_update_bits(regmap,
1711 fll->base + CS48L32_FLL_CONTROL3_OFFS,
1712 CS48L32_FLL_LAMBDA_MASK |
1713 CS48L32_FLL_THETA_MASK,
1714 (lambda << CS48L32_FLL_LAMBDA_SHIFT) |
1715 (theta << CS48L32_FLL_THETA_SHIFT));
1716
1717 regmap_update_bits(regmap,
1718 fll->base + CS48L32_FLL_CONTROL4_OFFS,
1719 (0xffff << CS48L32_FLL_FD_GAIN_COARSE_SHIFT) |
1720 CS48L32_FLL_HP_MASK |
1721 CS48L32_FLL_FB_DIV_MASK,
1722 (gains << CS48L32_FLL_FD_GAIN_COARSE_SHIFT) |
1723 (hp << CS48L32_FLL_HP_SHIFT) |
1724 (fbdiv << CS48L32_FLL_FB_DIV_SHIFT));
1725
1726 return 0;
1727 }
1728
cs48l32_fllhj_enable(struct cs48l32_fll * fll)1729 static int cs48l32_fllhj_enable(struct cs48l32_fll *fll)
1730 {
1731 struct cs48l32 *cs48l32 = &fll->codec->core;
1732 int already_enabled = cs48l32_is_enabled_fll(fll, fll->base);
1733 int ret;
1734
1735 if (already_enabled < 0)
1736 return already_enabled;
1737
1738 if (!already_enabled)
1739 pm_runtime_get_sync(cs48l32->dev);
1740
1741 cs48l32_fll_dbg(fll, "Enabling FLL, initially %s\n",
1742 str_enabled_disabled(already_enabled));
1743
1744 /* FLLn_HOLD must be set before configuring any registers */
1745 regmap_set_bits(cs48l32->regmap,
1746 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1747 CS48L32_FLL_HOLD_MASK);
1748
1749 /* Apply refclk */
1750 ret = cs48l32_fllhj_apply(fll, fll->ref_freq);
1751 if (ret) {
1752 cs48l32_fll_err(fll, "Failed to set FLL: %d\n", ret);
1753 goto out;
1754 }
1755 regmap_update_bits(cs48l32->regmap,
1756 fll->base + CS48L32_FLL_CONTROL2_OFFS,
1757 CS48L32_FLL_REFCLK_SRC_MASK,
1758 fll->ref_src << CS48L32_FLL_REFCLK_SRC_SHIFT);
1759
1760 regmap_set_bits(cs48l32->regmap,
1761 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1762 CS48L32_FLL_EN_MASK);
1763
1764 out:
1765 regmap_set_bits(cs48l32->regmap,
1766 fll->base + CS48L32_FLL_CONTROL2_OFFS,
1767 CS48L32_FLL_LOCKDET_MASK);
1768
1769 regmap_set_bits(cs48l32->regmap,
1770 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1771 CS48L32_FLL_CTRL_UPD_MASK);
1772
1773 /* Release the hold so that flln locks to external frequency */
1774 regmap_clear_bits(cs48l32->regmap,
1775 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1776 CS48L32_FLL_HOLD_MASK);
1777
1778 if (!already_enabled)
1779 cs48l32_wait_for_fll(fll, true);
1780
1781 return 0;
1782 }
1783
cs48l32_fllhj_validate(struct cs48l32_fll * fll,unsigned int ref_in,unsigned int fout)1784 static int cs48l32_fllhj_validate(struct cs48l32_fll *fll,
1785 unsigned int ref_in,
1786 unsigned int fout)
1787 {
1788 if (fout && !ref_in) {
1789 cs48l32_fll_err(fll, "fllout set without valid input clk\n");
1790 return -EINVAL;
1791 }
1792
1793 if (fll->fout && fout != fll->fout) {
1794 cs48l32_fll_err(fll, "Can't change output on active FLL\n");
1795 return -EINVAL;
1796 }
1797
1798 if (ref_in / CS48L32_FLL_MAX_REFDIV > CS48L32_FLLHJ_MAX_THRESH) {
1799 cs48l32_fll_err(fll, "Can't scale %dMHz to <=13MHz\n", ref_in);
1800 return -EINVAL;
1801 }
1802
1803 if (fout > CS48L32_FLL_MAX_FOUT) {
1804 cs48l32_fll_err(fll, "Fout=%dMHz exceeds maximum %dMHz\n",
1805 fout, CS48L32_FLL_MAX_FOUT);
1806 return -EINVAL;
1807 }
1808
1809 return 0;
1810 }
1811
cs48l32_fllhj_set_refclk(struct cs48l32_fll * fll,int source,unsigned int fin,unsigned int fout)1812 static int cs48l32_fllhj_set_refclk(struct cs48l32_fll *fll, int source,
1813 unsigned int fin, unsigned int fout)
1814 {
1815 int ret = 0;
1816
1817 if (fll->ref_src == source && fll->ref_freq == fin && fll->fout == fout)
1818 return 0;
1819
1820 if (fin && fout && cs48l32_fllhj_validate(fll, fin, fout))
1821 return -EINVAL;
1822
1823 fll->ref_src = source;
1824 fll->ref_freq = fin;
1825 fll->fout = fout;
1826
1827 if (fout)
1828 ret = cs48l32_fllhj_enable(fll);
1829 else
1830 cs48l32_fllhj_disable(fll);
1831
1832 return ret;
1833 }
1834
cs48l32_init_fll(struct cs48l32_fll * fll)1835 static int cs48l32_init_fll(struct cs48l32_fll *fll)
1836 {
1837 fll->ref_src = CS48L32_FLL_SRC_NONE;
1838
1839 return 0;
1840 }
1841
cs48l32_set_fll(struct snd_soc_component * component,int fll_id,int source,unsigned int fref,unsigned int fout)1842 static int cs48l32_set_fll(struct snd_soc_component *component, int fll_id,
1843 int source, unsigned int fref, unsigned int fout)
1844 {
1845 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1846
1847 switch (fll_id) {
1848 case CS48L32_FLL1_REFCLK:
1849 break;
1850 default:
1851 return -EINVAL;
1852 }
1853
1854 return cs48l32_fllhj_set_refclk(&cs48l32_codec->fll, source, fref, fout);
1855 }
1856
cs48l32_asp_dai_probe(struct snd_soc_dai * dai)1857 static int cs48l32_asp_dai_probe(struct snd_soc_dai *dai)
1858 {
1859 struct snd_soc_component *component = dai->component;
1860 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1861 struct regmap *regmap = cs48l32_codec->core.regmap;
1862 unsigned int pin_reg, last_pin_reg, hiz_reg;
1863
1864 switch (dai->id) {
1865 case 1:
1866 pin_reg = CS48L32_GPIO3_CTRL1;
1867 hiz_reg = CS48L32_ASP1_CONTROL3;
1868 break;
1869 case 2:
1870 pin_reg = CS48L32_GPIO7_CTRL1;
1871 hiz_reg = CS48L32_ASP2_CONTROL3;
1872 break;
1873 default:
1874 return -EINVAL;
1875 }
1876
1877 for (last_pin_reg = pin_reg + 12; pin_reg <= last_pin_reg; ++pin_reg)
1878 regmap_clear_bits(regmap, pin_reg, CS48L32_GPIOX_CTRL1_FN_MASK);
1879
1880 /* DOUT high-impendance when not transmitting */
1881 regmap_set_bits(regmap, hiz_reg, CS48L32_ASP_DOUT_HIZ_MASK);
1882
1883 return 0;
1884 }
1885
cs48l32_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)1886 static int cs48l32_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1887 {
1888 struct snd_soc_component *component = dai->component;
1889 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1890 struct regmap *regmap = cs48l32_codec->core.regmap;
1891 unsigned int val = 0U;
1892 unsigned int base = dai->driver->base;
1893 unsigned int mask = CS48L32_ASP_FMT_MASK | CS48L32_ASP_BCLK_INV_MASK |
1894 CS48L32_ASP_BCLK_MSTR_MASK |
1895 CS48L32_ASP_FSYNC_INV_MASK |
1896 CS48L32_ASP_FSYNC_MSTR_MASK;
1897
1898 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1899 case SND_SOC_DAIFMT_DSP_A:
1900 val |= (CS48L32_ASP_FMT_DSP_MODE_A << CS48L32_ASP_FMT_SHIFT);
1901 break;
1902 case SND_SOC_DAIFMT_DSP_B:
1903 if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_BP_FP) {
1904 cs48l32_asp_err(dai, "DSP_B cannot be clock consumer\n");
1905 return -EINVAL;
1906 }
1907 val |= (CS48L32_ASP_FMT_DSP_MODE_B << CS48L32_ASP_FMT_SHIFT);
1908 break;
1909 case SND_SOC_DAIFMT_I2S:
1910 val |= (CS48L32_ASP_FMT_I2S_MODE << CS48L32_ASP_FMT_SHIFT);
1911 break;
1912 case SND_SOC_DAIFMT_LEFT_J:
1913 if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_BP_FP) {
1914 cs48l32_asp_err(dai, "LEFT_J cannot be clock consumer\n");
1915 return -EINVAL;
1916 }
1917 val |= (CS48L32_ASP_FMT_LEFT_JUSTIFIED_MODE << CS48L32_ASP_FMT_SHIFT);
1918 break;
1919 default:
1920 cs48l32_asp_err(dai, "Unsupported DAI format %d\n",
1921 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1922 return -EINVAL;
1923 }
1924
1925 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
1926 case SND_SOC_DAIFMT_BC_FC:
1927 break;
1928 case SND_SOC_DAIFMT_BC_FP:
1929 val |= CS48L32_ASP_FSYNC_MSTR_MASK;
1930 break;
1931 case SND_SOC_DAIFMT_BP_FC:
1932 val |= CS48L32_ASP_BCLK_MSTR_MASK;
1933 break;
1934 case SND_SOC_DAIFMT_BP_FP:
1935 val |= CS48L32_ASP_BCLK_MSTR_MASK;
1936 val |= CS48L32_ASP_FSYNC_MSTR_MASK;
1937 break;
1938 default:
1939 cs48l32_asp_err(dai, "Unsupported clock direction %d\n",
1940 fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK);
1941 return -EINVAL;
1942 }
1943
1944 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1945 case SND_SOC_DAIFMT_NB_NF:
1946 break;
1947 case SND_SOC_DAIFMT_IB_IF:
1948 val |= CS48L32_ASP_BCLK_INV_MASK;
1949 val |= CS48L32_ASP_FSYNC_INV_MASK;
1950 break;
1951 case SND_SOC_DAIFMT_IB_NF:
1952 val |= CS48L32_ASP_BCLK_INV_MASK;
1953 break;
1954 case SND_SOC_DAIFMT_NB_IF:
1955 val |= CS48L32_ASP_FSYNC_INV_MASK;
1956 break;
1957 default:
1958 return -EINVAL;
1959 }
1960
1961 regmap_update_bits(regmap, base + CS48L32_ASP_CONTROL2, mask, val);
1962
1963 return 0;
1964 }
1965
1966 static const struct {
1967 u32 freq;
1968 u32 id;
1969 } cs48l32_sclk_rates[] = {
1970 { 128000, 12 },
1971 { 176400, 13 },
1972 { 192000, 14 },
1973 { 256000, 15 },
1974 { 352800, 16 },
1975 { 384000, 17 },
1976 { 512000, 18 },
1977 { 705600, 19 },
1978 { 768000, 21 },
1979 { 1024000, 23 },
1980 { 1411200, 25 },
1981 { 1536000, 27 },
1982 { 2048000, 29 },
1983 { 2822400, 31 },
1984 { 3072000, 33 },
1985 { 4096000, 36 },
1986 { 5644800, 38 },
1987 { 6144000, 40 },
1988 { 8192000, 47 },
1989 { 11289600, 49 },
1990 { 12288000, 51 },
1991 { 22579200, 57 },
1992 { 24576000, 59 },
1993 };
1994
1995 #define CS48L32_48K_RATE_MASK 0x0e00fe
1996 #define CS48L32_44K1_RATE_MASK 0x00fe00
1997 #define CS48L32_RATE_MASK (CS48L32_48K_RATE_MASK | CS48L32_44K1_RATE_MASK)
1998
1999 static const unsigned int cs48l32_sr_vals[] = {
2000 0,
2001 12000, /* CS48L32_48K_RATE_MASK */
2002 24000, /* CS48L32_48K_RATE_MASK */
2003 48000, /* CS48L32_48K_RATE_MASK */
2004 96000, /* CS48L32_48K_RATE_MASK */
2005 192000, /* CS48L32_48K_RATE_MASK */
2006 384000, /* CS48L32_48K_RATE_MASK */
2007 768000, /* CS48L32_48K_RATE_MASK */
2008 0,
2009 11025, /* CS48L32_44K1_RATE_MASK */
2010 22050, /* CS48L32_44K1_RATE_MASK */
2011 44100, /* CS48L32_44K1_RATE_MASK */
2012 88200, /* CS48L32_44K1_RATE_MASK */
2013 176400, /* CS48L32_44K1_RATE_MASK */
2014 352800, /* CS48L32_44K1_RATE_MASK */
2015 705600, /* CS48L32_44K1_RATE_MASK */
2016 0,
2017 8000, /* CS48L32_48K_RATE_MASK */
2018 16000, /* CS48L32_48K_RATE_MASK */
2019 32000, /* CS48L32_48K_RATE_MASK */
2020 };
2021
2022 static const struct snd_pcm_hw_constraint_list cs48l32_constraint = {
2023 .count = ARRAY_SIZE(cs48l32_sr_vals),
2024 .list = cs48l32_sr_vals,
2025 };
2026
cs48l32_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)2027 static int cs48l32_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
2028 {
2029 struct snd_soc_component *component = dai->component;
2030 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2031 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1];
2032 unsigned int base_rate;
2033
2034 if (!substream->runtime)
2035 return 0;
2036
2037 switch (dai_priv->clk) {
2038 case CS48L32_CLK_SYSCLK_1:
2039 case CS48L32_CLK_SYSCLK_2:
2040 case CS48L32_CLK_SYSCLK_3:
2041 case CS48L32_CLK_SYSCLK_4:
2042 base_rate = cs48l32_codec->sysclk;
2043 break;
2044 default:
2045 return 0;
2046 }
2047
2048 if (base_rate == 0)
2049 dai_priv->constraint.mask = CS48L32_RATE_MASK;
2050 else if (base_rate % 4000)
2051 dai_priv->constraint.mask = CS48L32_44K1_RATE_MASK;
2052 else
2053 dai_priv->constraint.mask = CS48L32_48K_RATE_MASK;
2054
2055 return snd_pcm_hw_constraint_list(substream->runtime, 0,
2056 SNDRV_PCM_HW_PARAM_RATE,
2057 &dai_priv->constraint);
2058 }
2059
cs48l32_hw_params_rate(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)2060 static int cs48l32_hw_params_rate(struct snd_pcm_substream *substream,
2061 struct snd_pcm_hw_params *params,
2062 struct snd_soc_dai *dai)
2063 {
2064 struct snd_soc_component *component = dai->component;
2065 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2066 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1];
2067 unsigned int sr_val, sr_reg, rate;
2068
2069 rate = params_rate(params);
2070 for (sr_val = 0; sr_val < ARRAY_SIZE(cs48l32_sr_vals); sr_val++)
2071 if (cs48l32_sr_vals[sr_val] == rate)
2072 break;
2073
2074 if (sr_val == ARRAY_SIZE(cs48l32_sr_vals)) {
2075 cs48l32_asp_err(dai, "Unsupported sample rate %dHz\n", rate);
2076 return -EINVAL;
2077 }
2078
2079 switch (dai_priv->clk) {
2080 case CS48L32_CLK_SYSCLK_1:
2081 sr_reg = CS48L32_SAMPLE_RATE1;
2082 break;
2083 case CS48L32_CLK_SYSCLK_2:
2084 sr_reg = CS48L32_SAMPLE_RATE2;
2085 break;
2086 case CS48L32_CLK_SYSCLK_3:
2087 sr_reg = CS48L32_SAMPLE_RATE3;
2088 break;
2089 case CS48L32_CLK_SYSCLK_4:
2090 sr_reg = CS48L32_SAMPLE_RATE4;
2091 break;
2092 default:
2093 return -EINVAL;
2094 }
2095
2096 snd_soc_component_update_bits(component, sr_reg, CS48L32_SAMPLE_RATE_1_MASK, sr_val);
2097
2098 return 0;
2099 }
2100
cs48l32_asp_cfg_changed(struct snd_soc_component * component,unsigned int base,unsigned int sclk,unsigned int slotws,unsigned int dataw)2101 static bool cs48l32_asp_cfg_changed(struct snd_soc_component *component,
2102 unsigned int base, unsigned int sclk,
2103 unsigned int slotws, unsigned int dataw)
2104 {
2105 unsigned int val;
2106
2107 val = snd_soc_component_read(component, base + CS48L32_ASP_CONTROL1);
2108 if (sclk != (val & CS48L32_ASP_BCLK_FREQ_MASK))
2109 return true;
2110
2111 val = snd_soc_component_read(component, base + CS48L32_ASP_CONTROL2);
2112 if (slotws != (val & (CS48L32_ASP_RX_WIDTH_MASK | CS48L32_ASP_TX_WIDTH_MASK)))
2113 return true;
2114
2115 val = snd_soc_component_read(component, base + CS48L32_ASP_DATA_CONTROL1);
2116 if (dataw != (val & (CS48L32_ASP_TX_WL_MASK)))
2117 return true;
2118
2119 val = snd_soc_component_read(component, base + CS48L32_ASP_DATA_CONTROL5);
2120 if (dataw != (val & (CS48L32_ASP_RX_WL_MASK)))
2121 return true;
2122
2123 return false;
2124 }
2125
cs48l32_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)2126 static int cs48l32_hw_params(struct snd_pcm_substream *substream,
2127 struct snd_pcm_hw_params *params,
2128 struct snd_soc_dai *dai)
2129 {
2130 struct snd_soc_component *component = dai->component;
2131 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2132 struct regmap *regmap = cs48l32_codec->core.regmap;
2133 int base = dai->driver->base;
2134 int dai_id = dai->id - 1;
2135 unsigned int rate = params_rate(params);
2136 unsigned int dataw = snd_pcm_format_width(params_format(params));
2137 unsigned int asp_state = 0;
2138 int sclk, sclk_target;
2139 unsigned int slotw, n_slots, n_slots_multiple, val;
2140 int i, ret;
2141
2142 cs48l32_asp_dbg(dai, "hwparams in: ch:%u dataw:%u rate:%u\n",
2143 params_channels(params), dataw, rate);
2144 /*
2145 * The following calculations hold only under the assumption that
2146 * symmetric_[rates|channels|samplebits] are set to 1
2147 */
2148 if (cs48l32_codec->tdm_slots[dai_id]) {
2149 n_slots = cs48l32_codec->tdm_slots[dai_id];
2150 slotw = cs48l32_codec->tdm_width[dai_id];
2151 } else {
2152 n_slots = params_channels(params);
2153 slotw = dataw;
2154 }
2155
2156 val = snd_soc_component_read(component, base + CS48L32_ASP_CONTROL2);
2157 val = (val & CS48L32_ASP_FMT_MASK) >> CS48L32_ASP_FMT_SHIFT;
2158 if (val == CS48L32_ASP_FMT_I2S_MODE)
2159 n_slots_multiple = 2;
2160 else
2161 n_slots_multiple = 1;
2162
2163 sclk_target = snd_soc_tdm_params_to_bclk(params, slotw, n_slots, n_slots_multiple);
2164 if (sclk_target < 0) {
2165 cs48l32_asp_err(dai, "Invalid parameters\n");
2166 return sclk_target;
2167 }
2168
2169 for (i = 0; i < ARRAY_SIZE(cs48l32_sclk_rates); i++) {
2170 if ((cs48l32_sclk_rates[i].freq >= sclk_target) &&
2171 (cs48l32_sclk_rates[i].freq % rate == 0)) {
2172 sclk = cs48l32_sclk_rates[i].id;
2173 break;
2174 }
2175 }
2176 if (i == ARRAY_SIZE(cs48l32_sclk_rates)) {
2177 cs48l32_asp_err(dai, "Unsupported sample rate %dHz\n", rate);
2178 return -EINVAL;
2179 }
2180
2181 cs48l32_asp_dbg(dai, "hwparams out: n_slots:%u dataw:%u slotw:%u bclk:%u bclkid:%u\n",
2182 n_slots, dataw, slotw, sclk_target, sclk);
2183
2184 slotw = (slotw << CS48L32_ASP_TX_WIDTH_SHIFT) |
2185 (slotw << CS48L32_ASP_RX_WIDTH_SHIFT);
2186
2187 if (!cs48l32_asp_cfg_changed(component, base, sclk, slotw, dataw))
2188 return cs48l32_hw_params_rate(substream, params, dai);
2189
2190 /* ASP must be disabled while changing configuration */
2191 asp_state = snd_soc_component_read(component, base + CS48L32_ASP_ENABLES1);
2192 regmap_clear_bits(regmap, base + CS48L32_ASP_ENABLES1, 0xff00ff);
2193
2194 ret = cs48l32_hw_params_rate(substream, params, dai);
2195 if (ret != 0)
2196 goto restore_asp;
2197
2198 regmap_update_bits_async(regmap,
2199 base + CS48L32_ASP_CONTROL1,
2200 CS48L32_ASP_BCLK_FREQ_MASK,
2201 sclk);
2202 regmap_update_bits_async(regmap,
2203 base + CS48L32_ASP_CONTROL2,
2204 CS48L32_ASP_RX_WIDTH_MASK | CS48L32_ASP_TX_WIDTH_MASK,
2205 slotw);
2206 regmap_update_bits_async(regmap,
2207 base + CS48L32_ASP_DATA_CONTROL1,
2208 CS48L32_ASP_TX_WL_MASK,
2209 dataw);
2210 regmap_update_bits(regmap,
2211 base + CS48L32_ASP_DATA_CONTROL5,
2212 CS48L32_ASP_RX_WL_MASK,
2213 dataw);
2214
2215 restore_asp:
2216 /* Restore ASP TX/RX enable state */
2217 regmap_update_bits(regmap,
2218 base + CS48L32_ASP_ENABLES1,
2219 0xff00ff,
2220 asp_state);
2221 return ret;
2222 }
2223
cs48l32_dai_clk_str(int clk_id)2224 static const char *cs48l32_dai_clk_str(int clk_id)
2225 {
2226 switch (clk_id) {
2227 case CS48L32_CLK_SYSCLK_1:
2228 case CS48L32_CLK_SYSCLK_2:
2229 case CS48L32_CLK_SYSCLK_3:
2230 case CS48L32_CLK_SYSCLK_4:
2231 return "SYSCLK";
2232 default:
2233 return "Unknown clock";
2234 }
2235 }
2236
cs48l32_dai_set_sysclk(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)2237 static int cs48l32_dai_set_sysclk(struct snd_soc_dai *dai,
2238 int clk_id, unsigned int freq, int dir)
2239 {
2240 struct snd_soc_component *component = dai->component;
2241 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2242 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1];
2243 unsigned int base = dai->driver->base;
2244 unsigned int current_asp_rate, target_asp_rate;
2245 bool change_rate_domain = false;
2246 int ret;
2247
2248 if (clk_id == dai_priv->clk)
2249 return 0;
2250
2251 if (snd_soc_dai_active(dai)) {
2252 cs48l32_asp_err(dai, "Can't change clock on active DAI\n");
2253 return -EBUSY;
2254 }
2255
2256 switch (clk_id) {
2257 case CS48L32_CLK_SYSCLK_1:
2258 target_asp_rate = 0U << CS48L32_ASP_RATE_SHIFT;
2259 break;
2260 case CS48L32_CLK_SYSCLK_2:
2261 target_asp_rate = 1U << CS48L32_ASP_RATE_SHIFT;
2262 break;
2263 case CS48L32_CLK_SYSCLK_3:
2264 target_asp_rate = 2U << CS48L32_ASP_RATE_SHIFT;
2265 break;
2266 case CS48L32_CLK_SYSCLK_4:
2267 target_asp_rate = 3U << CS48L32_ASP_RATE_SHIFT;
2268 break;
2269 default:
2270 return -EINVAL;
2271 }
2272
2273 dai_priv->clk = clk_id;
2274 cs48l32_asp_dbg(dai, "Setting to %s\n", cs48l32_dai_clk_str(clk_id));
2275
2276 if (base) {
2277 ret = regmap_read(cs48l32_codec->core.regmap,
2278 base + CS48L32_ASP_CONTROL1,
2279 ¤t_asp_rate);
2280 if (ret != 0) {
2281 cs48l32_asp_err(dai, "Failed to check rate: %d\n", ret);
2282 return ret;
2283 }
2284
2285 if ((current_asp_rate & CS48L32_ASP_RATE_MASK) !=
2286 (target_asp_rate & CS48L32_ASP_RATE_MASK)) {
2287 change_rate_domain = true;
2288
2289 mutex_lock(&cs48l32_codec->rate_lock);
2290 /* Guard the rate change with SYSCLK cycles */
2291 cs48l32_spin_sysclk(cs48l32_codec);
2292 }
2293
2294 snd_soc_component_update_bits(component, base + CS48L32_ASP_CONTROL1,
2295 CS48L32_ASP_RATE_MASK, target_asp_rate);
2296
2297 if (change_rate_domain) {
2298 cs48l32_spin_sysclk(cs48l32_codec);
2299 mutex_unlock(&cs48l32_codec->rate_lock);
2300 }
2301 }
2302
2303 return 0;
2304 }
2305
cs48l32_set_channels_to_mask(struct snd_soc_dai * dai,unsigned int base,int channels,unsigned int mask)2306 static void cs48l32_set_channels_to_mask(struct snd_soc_dai *dai,
2307 unsigned int base,
2308 int channels, unsigned int mask)
2309 {
2310 struct snd_soc_component *component = dai->component;
2311 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2312 struct regmap *regmap = cs48l32_codec->core.regmap;
2313 int slot, i, j = 0, shift;
2314 unsigned int frame_ctls[2] = {0, 0};
2315
2316 for (i = 0; i < channels; ++i) {
2317 slot = ffs(mask) - 1;
2318 if (slot < 0)
2319 return;
2320
2321 if (i - (j * 4) >= 4) {
2322 ++j;
2323 if (j >= 2)
2324 break;
2325 }
2326
2327 shift = (8 * (i - j * 4));
2328
2329 frame_ctls[j] |= slot << shift;
2330
2331 mask &= ~(1 << slot); /* ? mask ^= 1 << slot ? */
2332 }
2333
2334 regmap_write(regmap, base, frame_ctls[0]);
2335 regmap_write(regmap, base + 0x4, frame_ctls[1]);
2336
2337 if (mask)
2338 cs48l32_asp_warn(dai, "Too many channels in TDM mask\n");
2339 }
2340
cs48l32_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)2341 static int cs48l32_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
2342 unsigned int rx_mask, int slots, int slot_width)
2343 {
2344 struct snd_soc_component *component = dai->component;
2345 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2346 int base = dai->driver->base;
2347 int rx_max_chan = dai->driver->playback.channels_max;
2348 int tx_max_chan = dai->driver->capture.channels_max;
2349
2350 /* Only support TDM for the physical ASPs */
2351 if (dai->id > CS48L32_MAX_ASP)
2352 return -EINVAL;
2353
2354 if (slots == 0) {
2355 tx_mask = (1 << tx_max_chan) - 1;
2356 rx_mask = (1 << rx_max_chan) - 1;
2357 }
2358
2359 cs48l32_set_channels_to_mask(dai, base + CS48L32_ASP_FRAME_CONTROL1,
2360 tx_max_chan, tx_mask);
2361 cs48l32_set_channels_to_mask(dai, base + CS48L32_ASP_FRAME_CONTROL5,
2362 rx_max_chan, rx_mask);
2363
2364 cs48l32_codec->tdm_width[dai->id - 1] = slot_width;
2365 cs48l32_codec->tdm_slots[dai->id - 1] = slots;
2366
2367 return 0;
2368 }
2369
2370 static const struct snd_soc_dai_ops cs48l32_dai_ops = {
2371 .probe = &cs48l32_asp_dai_probe,
2372 .startup = &cs48l32_startup,
2373 .set_fmt = &cs48l32_set_fmt,
2374 .set_tdm_slot = &cs48l32_set_tdm_slot,
2375 .hw_params = &cs48l32_hw_params,
2376 .set_sysclk = &cs48l32_dai_set_sysclk,
2377 };
2378
cs48l32_sysclk_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)2379 static int cs48l32_sysclk_ev(struct snd_soc_dapm_widget *w,
2380 struct snd_kcontrol *kcontrol, int event)
2381 {
2382 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2383 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2384
2385 cs48l32_spin_sysclk(cs48l32_codec);
2386
2387 return 0;
2388 }
2389
cs48l32_in_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)2390 static int cs48l32_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event)
2391 {
2392 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2393 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2394 unsigned int reg;
2395
2396 if (w->shift % 2)
2397 reg = CS48L32_IN1L_CONTROL2;
2398 else
2399 reg = CS48L32_IN1R_CONTROL2;
2400
2401 reg += (w->shift / 2) * (CS48L32_IN2L_CONTROL2 - CS48L32_IN1L_CONTROL2);
2402
2403 switch (event) {
2404 case SND_SOC_DAPM_PRE_PMU:
2405 switch (w->shift) {
2406 case CS48L32_IN1L_EN_SHIFT:
2407 snd_soc_component_update_bits(component,
2408 CS48L32_ADC1L_ANA_CONTROL1,
2409 CS48L32_ADC1x_INT_ENA_FRC_MASK,
2410 CS48L32_ADC1x_INT_ENA_FRC_MASK);
2411 break;
2412 case CS48L32_IN1R_EN_SHIFT:
2413 snd_soc_component_update_bits(component,
2414 CS48L32_ADC1R_ANA_CONTROL1,
2415 CS48L32_ADC1x_INT_ENA_FRC_MASK,
2416 CS48L32_ADC1x_INT_ENA_FRC_MASK);
2417 break;
2418 default:
2419 break;
2420 }
2421 cs48l32_codec->in_up_pending++;
2422 break;
2423 case SND_SOC_DAPM_POST_PMU:
2424 usleep_range(200, 300);
2425
2426 switch (w->shift) {
2427 case CS48L32_IN1L_EN_SHIFT:
2428 snd_soc_component_update_bits(component,
2429 CS48L32_ADC1L_ANA_CONTROL1,
2430 CS48L32_ADC1x_INT_ENA_FRC_MASK,
2431 0);
2432 break;
2433 case CS48L32_IN1R_EN_SHIFT:
2434 snd_soc_component_update_bits(component,
2435 CS48L32_ADC1R_ANA_CONTROL1,
2436 CS48L32_ADC1x_INT_ENA_FRC_MASK,
2437 0);
2438 break;
2439
2440 default:
2441 break;
2442 }
2443 cs48l32_codec->in_up_pending--;
2444 snd_soc_component_update_bits(component, reg, CS48L32_INx_MUTE_MASK, 0);
2445
2446 /* Uncached write-only register, no need for update_bits */
2447 if (!cs48l32_codec->in_up_pending) {
2448 snd_soc_component_write(component, cs48l32_codec->in_vu_reg,
2449 CS48L32_IN_VU_MASK);
2450 }
2451 break;
2452 case SND_SOC_DAPM_PRE_PMD:
2453 snd_soc_component_update_bits(component, reg,
2454 CS48L32_INx_MUTE_MASK, CS48L32_INx_MUTE_MASK);
2455 snd_soc_component_write(component, cs48l32_codec->in_vu_reg,
2456 CS48L32_IN_VU_MASK);
2457 break;
2458 default:
2459 break;
2460 }
2461
2462 return 0;
2463 }
2464
cs48l32_in_put_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2465 static int cs48l32_in_put_volsw(struct snd_kcontrol *kcontrol,
2466 struct snd_ctl_elem_value *ucontrol)
2467 {
2468 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2469 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2470 int ret;
2471
2472 ret = snd_soc_put_volsw(kcontrol, ucontrol);
2473 if (ret < 0)
2474 return ret;
2475
2476 /*
2477 * Uncached write-only register, no need for update_bits.
2478 * Will fail if codec is off but that will be handled by cs48l32_in_ev
2479 */
2480 snd_soc_component_write(component, cs48l32_codec->in_vu_reg, CS48L32_IN_VU);
2481
2482 return ret;
2483 }
2484
cs48l32_eq_filter_unstable(bool mode,__be16 in_a,__be16 in_b)2485 static bool cs48l32_eq_filter_unstable(bool mode, __be16 in_a, __be16 in_b)
2486 {
2487 s16 a = be16_to_cpu(in_a);
2488 s16 b = be16_to_cpu(in_b);
2489
2490 if (!mode)
2491 return abs(a) > CS48L32_EQ_MAX_COEFF;
2492
2493 if (abs(b) > CS48L32_EQ_MAX_COEFF)
2494 return true;
2495
2496 if (abs((a << 16) / (CS48L32_EQ_MAX_COEFF + 1 - b)) >= ((CS48L32_EQ_MAX_COEFF + 1) << 4))
2497 return true;
2498
2499 return false;
2500 }
2501
cs48l32_eq_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)2502 static int cs48l32_eq_ev(struct snd_soc_dapm_widget *w,
2503 struct snd_kcontrol *kcontrol, int event)
2504 {
2505 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2506 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2507 struct regmap *regmap = cs48l32_codec->core.regmap;
2508 unsigned int mode = cs48l32_codec->eq_mode[w->shift];
2509 unsigned int reg;
2510 __be16 *data = &cs48l32_codec->eq_coefficients[w->shift][0];
2511 int ret = 0;
2512
2513 reg = CS48L32_EQ1_BAND1_COEFF1;
2514 reg += w->shift * (CS48L32_EQ2_BAND1_COEFF1 - CS48L32_EQ1_BAND1_COEFF1);
2515
2516 switch (event) {
2517 case SND_SOC_DAPM_PRE_PMU:
2518 if (cs48l32_eq_filter_unstable(!!mode, data[1], data[0]) ||
2519 cs48l32_eq_filter_unstable(true, data[7], data[6]) ||
2520 cs48l32_eq_filter_unstable(true, data[13], data[12]) ||
2521 cs48l32_eq_filter_unstable(true, data[19], data[18]) ||
2522 cs48l32_eq_filter_unstable(false, data[25], data[24])) {
2523 dev_err(cs48l32_codec->core.dev, "Rejecting unstable EQ coefficients.\n");
2524 ret = -EINVAL;
2525 } else {
2526 ret = regmap_raw_write(regmap, reg, data, CS48L32_EQ_BLOCK_SZ);
2527 if (ret < 0) {
2528 dev_err(cs48l32_codec->core.dev,
2529 "Error writing EQ coefficients: %d\n", ret);
2530 goto out;
2531 }
2532
2533 ret = snd_soc_component_update_bits(component,
2534 CS48L32_EQ_CONTROL2,
2535 w->mask,
2536 mode << w->shift);
2537 if (ret < 0) {
2538 dev_err(cs48l32_codec->core.dev,
2539 "Error writing EQ mode: %d\n", ret);
2540 }
2541 }
2542 break;
2543 default:
2544 break;
2545 }
2546
2547 out:
2548 return ret;
2549 }
2550
2551 static const struct snd_kcontrol_new cs48l32_snd_controls[] = {
2552 SOC_ENUM("IN1 OSR", cs48l32_in_dmic_osr[0]),
2553 SOC_ENUM("IN2 OSR", cs48l32_in_dmic_osr[1]),
2554
2555 SOC_SINGLE_RANGE_TLV("IN1L Volume", CS48L32_IN1L_CONTROL2,
2556 CS48L32_INx_PGA_VOL_SHIFT, 0x40, 0x5f, 0, cs48l32_ana_tlv),
2557 SOC_SINGLE_RANGE_TLV("IN1R Volume", CS48L32_IN1R_CONTROL2,
2558 CS48L32_INx_PGA_VOL_SHIFT, 0x40, 0x5f, 0, cs48l32_ana_tlv),
2559
2560 SOC_ENUM("IN HPF Cutoff Frequency", cs48l32_in_hpf_cut_enum),
2561
2562 SOC_SINGLE_EXT("IN1L LP Switch", CS48L32_IN1L_CONTROL1, CS48L32_INx_LP_MODE_SHIFT,
2563 1, 0, snd_soc_get_volsw, cs48l32_low_power_mode_put),
2564 SOC_SINGLE_EXT("IN1R LP Switch", CS48L32_IN1R_CONTROL1, CS48L32_INx_LP_MODE_SHIFT,
2565 1, 0, snd_soc_get_volsw, cs48l32_low_power_mode_put),
2566
2567 SOC_SINGLE("IN1L HPF Switch", CS48L32_IN1L_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2568 SOC_SINGLE("IN1R HPF Switch", CS48L32_IN1R_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2569 SOC_SINGLE("IN2L HPF Switch", CS48L32_IN2L_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2570 SOC_SINGLE("IN2R HPF Switch", CS48L32_IN2R_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2571
2572 SOC_SINGLE_EXT_TLV("IN1L Digital Volume", CS48L32_IN1L_CONTROL2,
2573 CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2574 cs48l32_in_put_volsw, cs48l32_digital_tlv),
2575 SOC_SINGLE_EXT_TLV("IN1R Digital Volume", CS48L32_IN1R_CONTROL2,
2576 CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2577 cs48l32_in_put_volsw, cs48l32_digital_tlv),
2578 SOC_SINGLE_EXT_TLV("IN2L Digital Volume", CS48L32_IN2L_CONTROL2,
2579 CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2580 cs48l32_in_put_volsw, cs48l32_digital_tlv),
2581 SOC_SINGLE_EXT_TLV("IN2R Digital Volume", CS48L32_IN2R_CONTROL2,
2582 CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2583 cs48l32_in_put_volsw, cs48l32_digital_tlv),
2584
2585 SOC_ENUM("Input Ramp Up", cs48l32_in_vi_ramp),
2586 SOC_ENUM("Input Ramp Down", cs48l32_in_vd_ramp),
2587
2588 CS48L32_RATE_ENUM("Ultrasonic 1 Rate", cs48l32_us_output_rate[0]),
2589 CS48L32_RATE_ENUM("Ultrasonic 2 Rate", cs48l32_us_output_rate[1]),
2590
2591 SOC_ENUM("Ultrasonic 1 Freq", cs48l32_us_freq[0]),
2592 SOC_ENUM("Ultrasonic 2 Freq", cs48l32_us_freq[1]),
2593
2594 SOC_SINGLE_TLV("Ultrasonic 1 Volume", CS48L32_US1_CONTROL, CS48L32_US1_GAIN_SHIFT,
2595 3, 0, cs48l32_us_tlv),
2596 SOC_SINGLE_TLV("Ultrasonic 2 Volume", CS48L32_US2_CONTROL, CS48L32_US1_GAIN_SHIFT,
2597 3, 0, cs48l32_us_tlv),
2598
2599 SOC_ENUM("Ultrasonic 1 Detect Threshold", cs48l32_us_det_thr[0]),
2600 SOC_ENUM("Ultrasonic 2 Detect Threshold", cs48l32_us_det_thr[1]),
2601
2602 SOC_ENUM("Ultrasonic 1 Detect Pulse Length", cs48l32_us_det_num[0]),
2603 SOC_ENUM("Ultrasonic 2 Detect Pulse Length", cs48l32_us_det_num[1]),
2604
2605 SOC_ENUM("Ultrasonic 1 Detect Hold", cs48l32_us_det_hold[0]),
2606 SOC_ENUM("Ultrasonic 2 Detect Hold", cs48l32_us_det_hold[1]),
2607
2608 SOC_ENUM("Ultrasonic 1 Detect Decay", cs48l32_us_det_dcy[0]),
2609 SOC_ENUM("Ultrasonic 2 Detect Decay", cs48l32_us_det_dcy[1]),
2610
2611 SOC_SINGLE("Ultrasonic 1 Detect LPF Switch",
2612 CS48L32_US1_DET_CONTROL, CS48L32_US1_DET_LPF_SHIFT, 1, 0),
2613 SOC_SINGLE("Ultrasonic 2 Detect LPF Switch",
2614 CS48L32_US2_DET_CONTROL, CS48L32_US1_DET_LPF_SHIFT, 1, 0),
2615
2616 SOC_ENUM("Ultrasonic 1 Detect LPF Cut-off", cs48l32_us_det_lpf_cut[0]),
2617 SOC_ENUM("Ultrasonic 2 Detect LPF Cut-off", cs48l32_us_det_lpf_cut[1]),
2618
2619 CS48L32_MIXER_CONTROLS("EQ1", CS48L32_EQ1_INPUT1),
2620 CS48L32_MIXER_CONTROLS("EQ2", CS48L32_EQ2_INPUT1),
2621 CS48L32_MIXER_CONTROLS("EQ3", CS48L32_EQ3_INPUT1),
2622 CS48L32_MIXER_CONTROLS("EQ4", CS48L32_EQ4_INPUT1),
2623
2624 SOC_ENUM_EXT("EQ1 Mode", cs48l32_eq_mode[0], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2625
2626 CS48L32_EQ_COEFF_CONTROLS(EQ1),
2627
2628 SOC_SINGLE_TLV("EQ1 B1 Volume", CS48L32_EQ1_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2629 SOC_SINGLE_TLV("EQ1 B2 Volume", CS48L32_EQ1_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2630 SOC_SINGLE_TLV("EQ1 B3 Volume", CS48L32_EQ1_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2631 SOC_SINGLE_TLV("EQ1 B4 Volume", CS48L32_EQ1_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2632 SOC_SINGLE_TLV("EQ1 B5 Volume", CS48L32_EQ1_GAIN2, 0, 24, 0, cs48l32_eq_tlv),
2633
2634 SOC_ENUM_EXT("EQ2 Mode", cs48l32_eq_mode[1], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2635 CS48L32_EQ_COEFF_CONTROLS(EQ2),
2636 SOC_SINGLE_TLV("EQ2 B1 Volume", CS48L32_EQ2_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2637 SOC_SINGLE_TLV("EQ2 B2 Volume", CS48L32_EQ2_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2638 SOC_SINGLE_TLV("EQ2 B3 Volume", CS48L32_EQ2_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2639 SOC_SINGLE_TLV("EQ2 B4 Volume", CS48L32_EQ2_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2640 SOC_SINGLE_TLV("EQ2 B5 Volume", CS48L32_EQ2_GAIN2, 0, 24, 0, cs48l32_eq_tlv),
2641
2642 SOC_ENUM_EXT("EQ3 Mode", cs48l32_eq_mode[2], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2643 CS48L32_EQ_COEFF_CONTROLS(EQ3),
2644 SOC_SINGLE_TLV("EQ3 B1 Volume", CS48L32_EQ3_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2645 SOC_SINGLE_TLV("EQ3 B2 Volume", CS48L32_EQ3_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2646 SOC_SINGLE_TLV("EQ3 B3 Volume", CS48L32_EQ3_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2647 SOC_SINGLE_TLV("EQ3 B4 Volume", CS48L32_EQ3_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2648 SOC_SINGLE_TLV("EQ3 B5 Volume", CS48L32_EQ3_GAIN2, 0, 24, 0, cs48l32_eq_tlv),
2649
2650 SOC_ENUM_EXT("EQ4 Mode", cs48l32_eq_mode[3], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2651 CS48L32_EQ_COEFF_CONTROLS(EQ4),
2652 SOC_SINGLE_TLV("EQ4 B1 Volume", CS48L32_EQ4_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2653 SOC_SINGLE_TLV("EQ4 B2 Volume", CS48L32_EQ4_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2654 SOC_SINGLE_TLV("EQ4 B3 Volume", CS48L32_EQ4_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2655 SOC_SINGLE_TLV("EQ4 B4 Volume", CS48L32_EQ4_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2656 SOC_SINGLE_TLV("EQ4 B5 Volume", CS48L32_EQ4_GAIN2, 0, 24, 0, cs48l32_eq_tlv),
2657
2658 CS48L32_MIXER_CONTROLS("DRC1L", CS48L32_DRC1L_INPUT1),
2659 CS48L32_MIXER_CONTROLS("DRC1R", CS48L32_DRC1R_INPUT1),
2660 CS48L32_MIXER_CONTROLS("DRC2L", CS48L32_DRC2L_INPUT1),
2661 CS48L32_MIXER_CONTROLS("DRC2R", CS48L32_DRC2R_INPUT1),
2662
2663 SND_SOC_BYTES_MASK("DRC1 Coefficients", CS48L32_DRC1_CONTROL1, 4,
2664 BIT(CS48L32_DRC1R_EN_SHIFT) | BIT(CS48L32_DRC1L_EN_SHIFT)),
2665 SND_SOC_BYTES_MASK("DRC2 Coefficients", CS48L32_DRC2_CONTROL1, 4,
2666 BIT(CS48L32_DRC1R_EN_SHIFT) | BIT(CS48L32_DRC1L_EN_SHIFT)),
2667
2668 CS48L32_MIXER_CONTROLS("LHPF1", CS48L32_LHPF1_INPUT1),
2669 CS48L32_MIXER_CONTROLS("LHPF2", CS48L32_LHPF2_INPUT1),
2670 CS48L32_MIXER_CONTROLS("LHPF3", CS48L32_LHPF3_INPUT1),
2671 CS48L32_MIXER_CONTROLS("LHPF4", CS48L32_LHPF4_INPUT1),
2672
2673 CS48L32_LHPF_CONTROL("LHPF1 Coefficients", CS48L32_LHPF1_COEFF),
2674 CS48L32_LHPF_CONTROL("LHPF2 Coefficients", CS48L32_LHPF2_COEFF),
2675 CS48L32_LHPF_CONTROL("LHPF3 Coefficients", CS48L32_LHPF3_COEFF),
2676 CS48L32_LHPF_CONTROL("LHPF4 Coefficients", CS48L32_LHPF4_COEFF),
2677
2678 SOC_ENUM("LHPF1 Mode", cs48l32_lhpf_mode[0]),
2679 SOC_ENUM("LHPF2 Mode", cs48l32_lhpf_mode[1]),
2680 SOC_ENUM("LHPF3 Mode", cs48l32_lhpf_mode[2]),
2681 SOC_ENUM("LHPF4 Mode", cs48l32_lhpf_mode[3]),
2682
2683 CS48L32_RATE_CONTROL("Sample Rate 1", 1),
2684 CS48L32_RATE_CONTROL("Sample Rate 2", 2),
2685 CS48L32_RATE_CONTROL("Sample Rate 3", 3),
2686 CS48L32_RATE_CONTROL("Sample Rate 4", 4),
2687
2688 CS48L32_RATE_ENUM("FX Rate", cs48l32_fx_rate),
2689
2690 CS48L32_RATE_ENUM("ISRC1 FSL", cs48l32_isrc_fsl[0]),
2691 CS48L32_RATE_ENUM("ISRC2 FSL", cs48l32_isrc_fsl[1]),
2692 CS48L32_RATE_ENUM("ISRC3 FSL", cs48l32_isrc_fsl[2]),
2693 CS48L32_RATE_ENUM("ISRC1 FSH", cs48l32_isrc_fsh[0]),
2694 CS48L32_RATE_ENUM("ISRC2 FSH", cs48l32_isrc_fsh[1]),
2695 CS48L32_RATE_ENUM("ISRC3 FSH", cs48l32_isrc_fsh[2]),
2696
2697 SOC_ENUM("AUXPDM1 Rate", cs48l32_auxpdm1_freq),
2698 SOC_ENUM("AUXPDM2 Rate", cs48l32_auxpdm2_freq),
2699
2700 SOC_ENUM_EXT("IN1L Rate", cs48l32_input_rate[0], snd_soc_get_enum_double, cs48l32_in_rate_put),
2701 SOC_ENUM_EXT("IN1R Rate", cs48l32_input_rate[1], snd_soc_get_enum_double, cs48l32_in_rate_put),
2702 SOC_ENUM_EXT("IN2L Rate", cs48l32_input_rate[2], snd_soc_get_enum_double, cs48l32_in_rate_put),
2703 SOC_ENUM_EXT("IN2R Rate", cs48l32_input_rate[3], snd_soc_get_enum_double, cs48l32_in_rate_put),
2704
2705 CS48L32_RATE_ENUM("Noise Generator Rate", noise_gen_rate),
2706
2707 SOC_SINGLE_TLV("Noise Generator Volume", CS48L32_COMFORT_NOISE_GENERATOR,
2708 CS48L32_NOISE_GEN_GAIN_SHIFT, 0x12, 0, cs48l32_noise_tlv),
2709
2710 CS48L32_MIXER_CONTROLS("ASP1TX1", CS48L32_ASP1TX1_INPUT1),
2711 CS48L32_MIXER_CONTROLS("ASP1TX2", CS48L32_ASP1TX2_INPUT1),
2712 CS48L32_MIXER_CONTROLS("ASP1TX3", CS48L32_ASP1TX3_INPUT1),
2713 CS48L32_MIXER_CONTROLS("ASP1TX4", CS48L32_ASP1TX4_INPUT1),
2714 CS48L32_MIXER_CONTROLS("ASP1TX5", CS48L32_ASP1TX5_INPUT1),
2715 CS48L32_MIXER_CONTROLS("ASP1TX6", CS48L32_ASP1TX6_INPUT1),
2716 CS48L32_MIXER_CONTROLS("ASP1TX7", CS48L32_ASP1TX7_INPUT1),
2717 CS48L32_MIXER_CONTROLS("ASP1TX8", CS48L32_ASP1TX8_INPUT1),
2718
2719 CS48L32_MIXER_CONTROLS("ASP2TX1", CS48L32_ASP2TX1_INPUT1),
2720 CS48L32_MIXER_CONTROLS("ASP2TX2", CS48L32_ASP2TX2_INPUT1),
2721 CS48L32_MIXER_CONTROLS("ASP2TX3", CS48L32_ASP2TX3_INPUT1),
2722 CS48L32_MIXER_CONTROLS("ASP2TX4", CS48L32_ASP2TX4_INPUT1),
2723
2724 WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
2725
2726 CS48L32_MIXER_CONTROLS("DSP1RX1", CS48L32_DSP1RX1_INPUT1),
2727 CS48L32_MIXER_CONTROLS("DSP1RX2", CS48L32_DSP1RX2_INPUT1),
2728 CS48L32_MIXER_CONTROLS("DSP1RX3", CS48L32_DSP1RX3_INPUT1),
2729 CS48L32_MIXER_CONTROLS("DSP1RX4", CS48L32_DSP1RX4_INPUT1),
2730 CS48L32_MIXER_CONTROLS("DSP1RX5", CS48L32_DSP1RX5_INPUT1),
2731 CS48L32_MIXER_CONTROLS("DSP1RX6", CS48L32_DSP1RX6_INPUT1),
2732 CS48L32_MIXER_CONTROLS("DSP1RX7", CS48L32_DSP1RX7_INPUT1),
2733 CS48L32_MIXER_CONTROLS("DSP1RX8", CS48L32_DSP1RX8_INPUT1),
2734
2735 WM_ADSP_FW_CONTROL("DSP1", 0),
2736
2737 CS48L32_DSP_RATE_CONTROL("DSP1RX1", 0),
2738 CS48L32_DSP_RATE_CONTROL("DSP1RX2", 1),
2739 CS48L32_DSP_RATE_CONTROL("DSP1RX3", 2),
2740 CS48L32_DSP_RATE_CONTROL("DSP1RX4", 3),
2741 CS48L32_DSP_RATE_CONTROL("DSP1RX5", 4),
2742 CS48L32_DSP_RATE_CONTROL("DSP1RX6", 5),
2743 CS48L32_DSP_RATE_CONTROL("DSP1RX7", 6),
2744 CS48L32_DSP_RATE_CONTROL("DSP1RX8", 7),
2745 CS48L32_DSP_RATE_CONTROL("DSP1TX1", 8),
2746 CS48L32_DSP_RATE_CONTROL("DSP1TX2", 9),
2747 CS48L32_DSP_RATE_CONTROL("DSP1TX3", 10),
2748 CS48L32_DSP_RATE_CONTROL("DSP1TX4", 11),
2749 CS48L32_DSP_RATE_CONTROL("DSP1TX5", 12),
2750 CS48L32_DSP_RATE_CONTROL("DSP1TX6", 13),
2751 CS48L32_DSP_RATE_CONTROL("DSP1TX7", 14),
2752 CS48L32_DSP_RATE_CONTROL("DSP1TX8", 15),
2753 };
2754
2755 CS48L32_MIXER_ENUMS(EQ1, CS48L32_EQ1_INPUT1);
2756 CS48L32_MIXER_ENUMS(EQ2, CS48L32_EQ2_INPUT1);
2757 CS48L32_MIXER_ENUMS(EQ3, CS48L32_EQ3_INPUT1);
2758 CS48L32_MIXER_ENUMS(EQ4, CS48L32_EQ4_INPUT1);
2759
2760 CS48L32_MIXER_ENUMS(DRC1L, CS48L32_DRC1L_INPUT1);
2761 CS48L32_MIXER_ENUMS(DRC1R, CS48L32_DRC1R_INPUT1);
2762 CS48L32_MIXER_ENUMS(DRC2L, CS48L32_DRC2L_INPUT1);
2763 CS48L32_MIXER_ENUMS(DRC2R, CS48L32_DRC2R_INPUT1);
2764
2765 CS48L32_MIXER_ENUMS(LHPF1, CS48L32_LHPF1_INPUT1);
2766 CS48L32_MIXER_ENUMS(LHPF2, CS48L32_LHPF2_INPUT1);
2767 CS48L32_MIXER_ENUMS(LHPF3, CS48L32_LHPF3_INPUT1);
2768 CS48L32_MIXER_ENUMS(LHPF4, CS48L32_LHPF4_INPUT1);
2769
2770 CS48L32_MIXER_ENUMS(ASP1TX1, CS48L32_ASP1TX1_INPUT1);
2771 CS48L32_MIXER_ENUMS(ASP1TX2, CS48L32_ASP1TX2_INPUT1);
2772 CS48L32_MIXER_ENUMS(ASP1TX3, CS48L32_ASP1TX3_INPUT1);
2773 CS48L32_MIXER_ENUMS(ASP1TX4, CS48L32_ASP1TX4_INPUT1);
2774 CS48L32_MIXER_ENUMS(ASP1TX5, CS48L32_ASP1TX5_INPUT1);
2775 CS48L32_MIXER_ENUMS(ASP1TX6, CS48L32_ASP1TX6_INPUT1);
2776 CS48L32_MIXER_ENUMS(ASP1TX7, CS48L32_ASP1TX7_INPUT1);
2777 CS48L32_MIXER_ENUMS(ASP1TX8, CS48L32_ASP1TX8_INPUT1);
2778
2779 CS48L32_MIXER_ENUMS(ASP2TX1, CS48L32_ASP2TX1_INPUT1);
2780 CS48L32_MIXER_ENUMS(ASP2TX2, CS48L32_ASP2TX2_INPUT1);
2781 CS48L32_MIXER_ENUMS(ASP2TX3, CS48L32_ASP2TX3_INPUT1);
2782 CS48L32_MIXER_ENUMS(ASP2TX4, CS48L32_ASP2TX4_INPUT1);
2783
2784 CS48L32_MUX_ENUMS(ISRC1INT1, CS48L32_ISRC1INT1_INPUT1);
2785 CS48L32_MUX_ENUMS(ISRC1INT2, CS48L32_ISRC1INT2_INPUT1);
2786 CS48L32_MUX_ENUMS(ISRC1INT3, CS48L32_ISRC1INT3_INPUT1);
2787 CS48L32_MUX_ENUMS(ISRC1INT4, CS48L32_ISRC1INT4_INPUT1);
2788
2789 CS48L32_MUX_ENUMS(ISRC1DEC1, CS48L32_ISRC1DEC1_INPUT1);
2790 CS48L32_MUX_ENUMS(ISRC1DEC2, CS48L32_ISRC1DEC2_INPUT1);
2791 CS48L32_MUX_ENUMS(ISRC1DEC3, CS48L32_ISRC1DEC3_INPUT1);
2792 CS48L32_MUX_ENUMS(ISRC1DEC4, CS48L32_ISRC1DEC4_INPUT1);
2793
2794 CS48L32_MUX_ENUMS(ISRC2INT1, CS48L32_ISRC2INT1_INPUT1);
2795 CS48L32_MUX_ENUMS(ISRC2INT2, CS48L32_ISRC2INT2_INPUT1);
2796
2797 CS48L32_MUX_ENUMS(ISRC2DEC1, CS48L32_ISRC2DEC1_INPUT1);
2798 CS48L32_MUX_ENUMS(ISRC2DEC2, CS48L32_ISRC2DEC2_INPUT1);
2799
2800 CS48L32_MUX_ENUMS(ISRC3INT1, CS48L32_ISRC3INT1_INPUT1);
2801 CS48L32_MUX_ENUMS(ISRC3INT2, CS48L32_ISRC3INT2_INPUT1);
2802
2803 CS48L32_MUX_ENUMS(ISRC3DEC1, CS48L32_ISRC3DEC1_INPUT1);
2804 CS48L32_MUX_ENUMS(ISRC3DEC2, CS48L32_ISRC3DEC2_INPUT1);
2805
2806 CS48L32_MIXER_ENUMS(DSP1RX1, CS48L32_DSP1RX1_INPUT1);
2807 CS48L32_MIXER_ENUMS(DSP1RX2, CS48L32_DSP1RX2_INPUT1);
2808 CS48L32_MIXER_ENUMS(DSP1RX3, CS48L32_DSP1RX3_INPUT1);
2809 CS48L32_MIXER_ENUMS(DSP1RX4, CS48L32_DSP1RX4_INPUT1);
2810 CS48L32_MIXER_ENUMS(DSP1RX5, CS48L32_DSP1RX5_INPUT1);
2811 CS48L32_MIXER_ENUMS(DSP1RX6, CS48L32_DSP1RX6_INPUT1);
2812 CS48L32_MIXER_ENUMS(DSP1RX7, CS48L32_DSP1RX7_INPUT1);
2813 CS48L32_MIXER_ENUMS(DSP1RX8, CS48L32_DSP1RX8_INPUT1);
2814
cs48l32_dsp_mem_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)2815 static int cs48l32_dsp_mem_ev(struct snd_soc_dapm_widget *w,
2816 struct snd_kcontrol *kcontrol, int event)
2817 {
2818 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2819 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2820
2821 switch (event) {
2822 case SND_SOC_DAPM_POST_PMU:
2823 return cs48l32_dsp_memory_enable(cs48l32_codec, &cs48l32_dsp_sram_regs);
2824 case SND_SOC_DAPM_PRE_PMD:
2825 cs48l32_dsp_memory_disable(cs48l32_codec, &cs48l32_dsp_sram_regs);
2826 return 0;
2827 default:
2828 return 0;
2829 }
2830 }
2831
2832 static const struct snd_soc_dapm_widget cs48l32_dapm_widgets[] = {
2833 SND_SOC_DAPM_SUPPLY("SYSCLK", CS48L32_SYSTEM_CLOCK1, CS48L32_SYSCLK_EN_SHIFT, 0,
2834 cs48l32_sysclk_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2835
2836 SND_SOC_DAPM_REGULATOR_SUPPLY("vdd-cp", 20, 0),
2837
2838 SND_SOC_DAPM_SUPPLY("VOUT_MIC", CS48L32_CHARGE_PUMP1, CS48L32_CP2_EN_SHIFT, 0, NULL, 0),
2839 SND_SOC_DAPM_SUPPLY("VOUT_MIC_REGULATED", CS48L32_CHARGE_PUMP1, CS48L32_CP2_BYPASS_SHIFT,
2840 1, NULL, 0),
2841 SND_SOC_DAPM_SUPPLY("MICBIAS1", CS48L32_MICBIAS_CTRL1, CS48L32_MICB1_EN_SHIFT, 0, NULL, 0),
2842 SND_SOC_DAPM_SUPPLY("MICBIAS1A", CS48L32_MICBIAS_CTRL5, CS48L32_MICB1A_EN_SHIFT, 0, NULL, 0),
2843 SND_SOC_DAPM_SUPPLY("MICBIAS1B", CS48L32_MICBIAS_CTRL5, CS48L32_MICB1B_EN_SHIFT, 0, NULL, 0),
2844 SND_SOC_DAPM_SUPPLY("MICBIAS1C", CS48L32_MICBIAS_CTRL5, CS48L32_MICB1C_EN_SHIFT, 0, NULL, 0),
2845
2846 SND_SOC_DAPM_SUPPLY("DSP1MEM", SND_SOC_NOPM, 0, 0, cs48l32_dsp_mem_ev,
2847 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2848
2849 CS48L32_DSP_FREQ_WIDGET_EV("DSP1", 0, cs48l32_dsp_freq_ev),
2850
2851 SND_SOC_DAPM_SIGGEN("TONE"),
2852 SND_SOC_DAPM_SIGGEN("NOISE"),
2853
2854 SND_SOC_DAPM_INPUT("IN1LN_1"),
2855 SND_SOC_DAPM_INPUT("IN1LN_2"),
2856 SND_SOC_DAPM_INPUT("IN1LP_1"),
2857 SND_SOC_DAPM_INPUT("IN1LP_2"),
2858 SND_SOC_DAPM_INPUT("IN1RN_1"),
2859 SND_SOC_DAPM_INPUT("IN1RN_2"),
2860 SND_SOC_DAPM_INPUT("IN1RP_1"),
2861 SND_SOC_DAPM_INPUT("IN1RP_2"),
2862 SND_SOC_DAPM_INPUT("IN1_PDMCLK"),
2863 SND_SOC_DAPM_INPUT("IN1_PDMDATA"),
2864
2865 SND_SOC_DAPM_INPUT("IN2_PDMCLK"),
2866 SND_SOC_DAPM_INPUT("IN2_PDMDATA"),
2867
2868 SND_SOC_DAPM_MUX("Ultrasonic 1 Input", SND_SOC_NOPM, 0, 0, &cs48l32_us_inmux[0]),
2869 SND_SOC_DAPM_MUX("Ultrasonic 2 Input", SND_SOC_NOPM, 0, 0, &cs48l32_us_inmux[1]),
2870
2871 SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
2872 SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
2873
2874 SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),
2875
2876 SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &cs48l32_inmux[0]),
2877 SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &cs48l32_inmux[1]),
2878
2879 SND_SOC_DAPM_MUX("IN1L Mode", SND_SOC_NOPM, 0, 0, &cs48l32_dmode_mux[0]),
2880 SND_SOC_DAPM_MUX("IN1R Mode", SND_SOC_NOPM, 0, 0, &cs48l32_dmode_mux[0]),
2881
2882 SND_SOC_DAPM_AIF_OUT("ASP1TX1", NULL, 0, CS48L32_ASP1_ENABLES1, 0, 0),
2883 SND_SOC_DAPM_AIF_OUT("ASP1TX2", NULL, 1, CS48L32_ASP1_ENABLES1, 1, 0),
2884 SND_SOC_DAPM_AIF_OUT("ASP1TX3", NULL, 2, CS48L32_ASP1_ENABLES1, 2, 0),
2885 SND_SOC_DAPM_AIF_OUT("ASP1TX4", NULL, 3, CS48L32_ASP1_ENABLES1, 3, 0),
2886 SND_SOC_DAPM_AIF_OUT("ASP1TX5", NULL, 4, CS48L32_ASP1_ENABLES1, 4, 0),
2887 SND_SOC_DAPM_AIF_OUT("ASP1TX6", NULL, 5, CS48L32_ASP1_ENABLES1, 5, 0),
2888 SND_SOC_DAPM_AIF_OUT("ASP1TX7", NULL, 6, CS48L32_ASP1_ENABLES1, 6, 0),
2889 SND_SOC_DAPM_AIF_OUT("ASP1TX8", NULL, 7, CS48L32_ASP1_ENABLES1, 7, 0),
2890
2891 SND_SOC_DAPM_AIF_OUT("ASP2TX1", NULL, 0, CS48L32_ASP2_ENABLES1, 0, 0),
2892 SND_SOC_DAPM_AIF_OUT("ASP2TX2", NULL, 1, CS48L32_ASP2_ENABLES1, 1, 0),
2893 SND_SOC_DAPM_AIF_OUT("ASP2TX3", NULL, 2, CS48L32_ASP2_ENABLES1, 2, 0),
2894 SND_SOC_DAPM_AIF_OUT("ASP2TX4", NULL, 3, CS48L32_ASP2_ENABLES1, 3, 0),
2895
2896 SND_SOC_DAPM_SWITCH("AUXPDM1 Output", CS48L32_AUXPDM_CONTROL1, 0, 0, &cs48l32_auxpdm_switch[0]),
2897 SND_SOC_DAPM_SWITCH("AUXPDM2 Output", CS48L32_AUXPDM_CONTROL1, 1, 0, &cs48l32_auxpdm_switch[1]),
2898
2899 SND_SOC_DAPM_MUX("AUXPDM1 Input", SND_SOC_NOPM, 0, 0, &cs48l32_auxpdm_inmux[0]),
2900 SND_SOC_DAPM_MUX("AUXPDM2 Input", SND_SOC_NOPM, 0, 0, &cs48l32_auxpdm_inmux[1]),
2901
2902 SND_SOC_DAPM_MUX("AUXPDM1 Analog Input", SND_SOC_NOPM, 0, 0,
2903 &cs48l32_auxpdm_analog_inmux[0]),
2904 SND_SOC_DAPM_MUX("AUXPDM2 Analog Input", SND_SOC_NOPM, 0, 0,
2905 &cs48l32_auxpdm_analog_inmux[1]),
2906
2907 SND_SOC_DAPM_SWITCH("Ultrasonic 1 Detect", CS48L32_US_CONTROL,
2908 CS48L32_US1_DET_EN_SHIFT, 0, &cs48l32_us_switch[0]),
2909 SND_SOC_DAPM_SWITCH("Ultrasonic 2 Detect", CS48L32_US_CONTROL,
2910 CS48L32_US1_DET_EN_SHIFT, 0, &cs48l32_us_switch[1]),
2911
2912 /*
2913 * mux_in widgets : arranged in the order of sources
2914 * specified in CS48L32_MIXER_INPUT_ROUTES
2915 */
2916 SND_SOC_DAPM_PGA("Tone Generator 1", CS48L32_TONE_GENERATOR1, 0, 0, NULL, 0),
2917 SND_SOC_DAPM_PGA("Tone Generator 2", CS48L32_TONE_GENERATOR1, 1, 0, NULL, 0),
2918
2919 SND_SOC_DAPM_PGA("Noise Generator", CS48L32_COMFORT_NOISE_GENERATOR,
2920 CS48L32_NOISE_GEN_EN_SHIFT, 0, NULL, 0),
2921
2922 SND_SOC_DAPM_PGA_E("IN1L PGA", CS48L32_INPUT_CONTROL, CS48L32_IN1L_EN_SHIFT,
2923 0, NULL, 0, cs48l32_in_ev,
2924 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2925 SND_SOC_DAPM_PGA_E("IN1R PGA", CS48L32_INPUT_CONTROL, CS48L32_IN1R_EN_SHIFT,
2926 0, NULL, 0, cs48l32_in_ev,
2927 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2928 SND_SOC_DAPM_PGA_E("IN2L PGA", CS48L32_INPUT_CONTROL, CS48L32_IN2L_EN_SHIFT,
2929 0, NULL, 0, cs48l32_in_ev,
2930 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2931 SND_SOC_DAPM_PGA_E("IN2R PGA", CS48L32_INPUT_CONTROL, CS48L32_IN2R_EN_SHIFT,
2932 0, NULL, 0, cs48l32_in_ev,
2933 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2934
2935 SND_SOC_DAPM_AIF_IN("ASP1RX1", NULL, 0, CS48L32_ASP1_ENABLES1, 16, 0),
2936 SND_SOC_DAPM_AIF_IN("ASP1RX2", NULL, 1, CS48L32_ASP1_ENABLES1, 17, 0),
2937 SND_SOC_DAPM_AIF_IN("ASP1RX3", NULL, 2, CS48L32_ASP1_ENABLES1, 18, 0),
2938 SND_SOC_DAPM_AIF_IN("ASP1RX4", NULL, 3, CS48L32_ASP1_ENABLES1, 19, 0),
2939 SND_SOC_DAPM_AIF_IN("ASP1RX5", NULL, 4, CS48L32_ASP1_ENABLES1, 20, 0),
2940 SND_SOC_DAPM_AIF_IN("ASP1RX6", NULL, 5, CS48L32_ASP1_ENABLES1, 21, 0),
2941 SND_SOC_DAPM_AIF_IN("ASP1RX7", NULL, 6, CS48L32_ASP1_ENABLES1, 22, 0),
2942 SND_SOC_DAPM_AIF_IN("ASP1RX8", NULL, 7, CS48L32_ASP1_ENABLES1, 23, 0),
2943
2944 SND_SOC_DAPM_AIF_IN("ASP2RX1", NULL, 0, CS48L32_ASP2_ENABLES1, 16, 0),
2945 SND_SOC_DAPM_AIF_IN("ASP2RX2", NULL, 1, CS48L32_ASP2_ENABLES1, 17, 0),
2946 SND_SOC_DAPM_AIF_IN("ASP2RX3", NULL, 2, CS48L32_ASP2_ENABLES1, 18, 0),
2947 SND_SOC_DAPM_AIF_IN("ASP2RX4", NULL, 3, CS48L32_ASP2_ENABLES1, 19, 0),
2948
2949 SND_SOC_DAPM_PGA("ISRC1DEC1", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC1_EN_SHIFT, 0, NULL, 0),
2950 SND_SOC_DAPM_PGA("ISRC1DEC2", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC2_EN_SHIFT, 0, NULL, 0),
2951 SND_SOC_DAPM_PGA("ISRC1DEC3", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC3_EN_SHIFT, 0, NULL, 0),
2952 SND_SOC_DAPM_PGA("ISRC1DEC4", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC4_EN_SHIFT, 0, NULL, 0),
2953
2954 SND_SOC_DAPM_PGA("ISRC1INT1", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT1_EN_SHIFT, 0, NULL, 0),
2955 SND_SOC_DAPM_PGA("ISRC1INT2", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT2_EN_SHIFT, 0, NULL, 0),
2956 SND_SOC_DAPM_PGA("ISRC1INT3", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT3_EN_SHIFT, 0, NULL, 0),
2957 SND_SOC_DAPM_PGA("ISRC1INT4", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT4_EN_SHIFT, 0, NULL, 0),
2958
2959 SND_SOC_DAPM_PGA("ISRC2DEC1", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_DEC1_EN_SHIFT, 0, NULL, 0),
2960 SND_SOC_DAPM_PGA("ISRC2DEC2", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_DEC2_EN_SHIFT, 0, NULL, 0),
2961
2962 SND_SOC_DAPM_PGA("ISRC2INT1", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_INT1_EN_SHIFT, 0, NULL, 0),
2963 SND_SOC_DAPM_PGA("ISRC2INT2", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_INT2_EN_SHIFT, 0, NULL, 0),
2964
2965 SND_SOC_DAPM_PGA("ISRC3DEC1", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_DEC1_EN_SHIFT, 0, NULL, 0),
2966 SND_SOC_DAPM_PGA("ISRC3DEC2", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_DEC2_EN_SHIFT, 0, NULL, 0),
2967
2968 SND_SOC_DAPM_PGA("ISRC3INT1", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_INT1_EN_SHIFT, 0, NULL, 0),
2969 SND_SOC_DAPM_PGA("ISRC3INT2", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_INT2_EN_SHIFT, 0, NULL, 0),
2970
2971 SND_SOC_DAPM_PGA_E("EQ1", CS48L32_EQ_CONTROL1, 0, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2972 SND_SOC_DAPM_PGA_E("EQ2", CS48L32_EQ_CONTROL1, 1, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2973 SND_SOC_DAPM_PGA_E("EQ3", CS48L32_EQ_CONTROL1, 2, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2974 SND_SOC_DAPM_PGA_E("EQ4", CS48L32_EQ_CONTROL1, 3, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2975
2976 SND_SOC_DAPM_PGA("DRC1L", CS48L32_DRC1_CONTROL1, CS48L32_DRC1L_EN_SHIFT, 0, NULL, 0),
2977 SND_SOC_DAPM_PGA("DRC1R", CS48L32_DRC1_CONTROL1, CS48L32_DRC1R_EN_SHIFT, 0, NULL, 0),
2978 SND_SOC_DAPM_PGA("DRC2L", CS48L32_DRC2_CONTROL1, CS48L32_DRC1L_EN_SHIFT, 0, NULL, 0),
2979 SND_SOC_DAPM_PGA("DRC2R", CS48L32_DRC2_CONTROL1, CS48L32_DRC1R_EN_SHIFT, 0, NULL, 0),
2980
2981 SND_SOC_DAPM_PGA("LHPF1", CS48L32_LHPF_CONTROL1, 0, 0, NULL, 0),
2982 SND_SOC_DAPM_PGA("LHPF2", CS48L32_LHPF_CONTROL1, 1, 0, NULL, 0),
2983 SND_SOC_DAPM_PGA("LHPF3", CS48L32_LHPF_CONTROL1, 2, 0, NULL, 0),
2984 SND_SOC_DAPM_PGA("LHPF4", CS48L32_LHPF_CONTROL1, 3, 0, NULL, 0),
2985
2986 SND_SOC_DAPM_PGA("Ultrasonic 1", CS48L32_US_CONTROL, 0, 0, NULL, 0),
2987 SND_SOC_DAPM_PGA("Ultrasonic 2", CS48L32_US_CONTROL, 1, 0, NULL, 0),
2988
2989 WM_ADSP2("DSP1", 0, wm_adsp_early_event),
2990
2991 /* end of ordered widget list */
2992
2993 CS48L32_MIXER_WIDGETS(EQ1, "EQ1"),
2994 CS48L32_MIXER_WIDGETS(EQ2, "EQ2"),
2995 CS48L32_MIXER_WIDGETS(EQ3, "EQ3"),
2996 CS48L32_MIXER_WIDGETS(EQ4, "EQ4"),
2997
2998 CS48L32_MIXER_WIDGETS(DRC1L, "DRC1L"),
2999 CS48L32_MIXER_WIDGETS(DRC1R, "DRC1R"),
3000 CS48L32_MIXER_WIDGETS(DRC2L, "DRC2L"),
3001 CS48L32_MIXER_WIDGETS(DRC2R, "DRC2R"),
3002
3003 SND_SOC_DAPM_SWITCH("DRC1 Activity Output", SND_SOC_NOPM, 0, 0,
3004 &cs48l32_drc_activity_output_mux[0]),
3005 SND_SOC_DAPM_SWITCH("DRC2 Activity Output", SND_SOC_NOPM, 0, 0,
3006 &cs48l32_drc_activity_output_mux[1]),
3007
3008 CS48L32_MIXER_WIDGETS(LHPF1, "LHPF1"),
3009 CS48L32_MIXER_WIDGETS(LHPF2, "LHPF2"),
3010 CS48L32_MIXER_WIDGETS(LHPF3, "LHPF3"),
3011 CS48L32_MIXER_WIDGETS(LHPF4, "LHPF4"),
3012
3013 CS48L32_MIXER_WIDGETS(ASP1TX1, "ASP1TX1"),
3014 CS48L32_MIXER_WIDGETS(ASP1TX2, "ASP1TX2"),
3015 CS48L32_MIXER_WIDGETS(ASP1TX3, "ASP1TX3"),
3016 CS48L32_MIXER_WIDGETS(ASP1TX4, "ASP1TX4"),
3017 CS48L32_MIXER_WIDGETS(ASP1TX5, "ASP1TX5"),
3018 CS48L32_MIXER_WIDGETS(ASP1TX6, "ASP1TX6"),
3019 CS48L32_MIXER_WIDGETS(ASP1TX7, "ASP1TX7"),
3020 CS48L32_MIXER_WIDGETS(ASP1TX8, "ASP1TX8"),
3021
3022 CS48L32_MIXER_WIDGETS(ASP2TX1, "ASP2TX1"),
3023 CS48L32_MIXER_WIDGETS(ASP2TX2, "ASP2TX2"),
3024 CS48L32_MIXER_WIDGETS(ASP2TX3, "ASP2TX3"),
3025 CS48L32_MIXER_WIDGETS(ASP2TX4, "ASP2TX4"),
3026
3027 CS48L32_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
3028 CS48L32_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
3029 CS48L32_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
3030 CS48L32_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
3031
3032 CS48L32_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
3033 CS48L32_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
3034 CS48L32_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
3035 CS48L32_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
3036
3037 CS48L32_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
3038 CS48L32_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
3039
3040 CS48L32_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
3041 CS48L32_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
3042
3043 CS48L32_MUX_WIDGETS(ISRC3DEC1, "ISRC3DEC1"),
3044 CS48L32_MUX_WIDGETS(ISRC3DEC2, "ISRC3DEC2"),
3045
3046 CS48L32_MUX_WIDGETS(ISRC3INT1, "ISRC3INT1"),
3047 CS48L32_MUX_WIDGETS(ISRC3INT2, "ISRC3INT2"),
3048
3049 CS48L32_MIXER_WIDGETS(DSP1RX1, "DSP1RX1"),
3050 CS48L32_MIXER_WIDGETS(DSP1RX2, "DSP1RX2"),
3051 CS48L32_MIXER_WIDGETS(DSP1RX3, "DSP1RX3"),
3052 CS48L32_MIXER_WIDGETS(DSP1RX4, "DSP1RX4"),
3053 CS48L32_MIXER_WIDGETS(DSP1RX5, "DSP1RX5"),
3054 CS48L32_MIXER_WIDGETS(DSP1RX6, "DSP1RX6"),
3055 CS48L32_MIXER_WIDGETS(DSP1RX7, "DSP1RX7"),
3056 CS48L32_MIXER_WIDGETS(DSP1RX8, "DSP1RX8"),
3057
3058 SND_SOC_DAPM_SWITCH("DSP1 Trigger Output", SND_SOC_NOPM, 0, 0,
3059 &cs48l32_dsp_trigger_output_mux[0]),
3060
3061 SND_SOC_DAPM_OUTPUT("AUXPDM1_CLK"),
3062 SND_SOC_DAPM_OUTPUT("AUXPDM1_DOUT"),
3063 SND_SOC_DAPM_OUTPUT("AUXPDM2_CLK"),
3064 SND_SOC_DAPM_OUTPUT("AUXPDM2_DOUT"),
3065
3066 SND_SOC_DAPM_OUTPUT("MICSUPP"),
3067
3068 SND_SOC_DAPM_OUTPUT("Ultrasonic Dummy Output"),
3069 };
3070
3071 static const struct snd_soc_dapm_route cs48l32_dapm_routes[] = {
3072 { "IN1LN_1", NULL, "SYSCLK" },
3073 { "IN1LN_2", NULL, "SYSCLK" },
3074 { "IN1LP_1", NULL, "SYSCLK" },
3075 { "IN1LP_2", NULL, "SYSCLK" },
3076 { "IN1RN_1", NULL, "SYSCLK" },
3077 { "IN1RN_2", NULL, "SYSCLK" },
3078 { "IN1RP_1", NULL, "SYSCLK" },
3079 { "IN1RP_2", NULL, "SYSCLK" },
3080
3081 { "IN1_PDMCLK", NULL, "SYSCLK" },
3082 { "IN1_PDMDATA", NULL, "SYSCLK" },
3083 { "IN2_PDMCLK", NULL, "SYSCLK" },
3084 { "IN2_PDMDATA", NULL, "SYSCLK" },
3085
3086 { "DSP1 Preloader", NULL, "DSP1MEM" },
3087 { "DSP1", NULL, "DSP1FREQ" },
3088
3089 { "Audio Trace DSP", NULL, "DSP1" },
3090 { "Voice Ctrl DSP", NULL, "DSP1" },
3091
3092 { "VOUT_MIC_REGULATED", NULL, "VOUT_MIC" },
3093 { "MICBIAS1", NULL, "VOUT_MIC_REGULATED" },
3094 { "MICBIAS1A", NULL, "MICBIAS1" },
3095 { "MICBIAS1B", NULL, "MICBIAS1" },
3096 { "MICBIAS1C", NULL, "MICBIAS1" },
3097
3098 { "Tone Generator 1", NULL, "SYSCLK" },
3099 { "Tone Generator 2", NULL, "SYSCLK" },
3100 { "Noise Generator", NULL, "SYSCLK" },
3101
3102 { "Tone Generator 1", NULL, "TONE" },
3103 { "Tone Generator 2", NULL, "TONE" },
3104 { "Noise Generator", NULL, "NOISE" },
3105
3106 { "ASP1 Capture", NULL, "ASP1TX1" },
3107 { "ASP1 Capture", NULL, "ASP1TX2" },
3108 { "ASP1 Capture", NULL, "ASP1TX3" },
3109 { "ASP1 Capture", NULL, "ASP1TX4" },
3110 { "ASP1 Capture", NULL, "ASP1TX5" },
3111 { "ASP1 Capture", NULL, "ASP1TX6" },
3112 { "ASP1 Capture", NULL, "ASP1TX7" },
3113 { "ASP1 Capture", NULL, "ASP1TX8" },
3114
3115 { "ASP1RX1", NULL, "ASP1 Playback" },
3116 { "ASP1RX2", NULL, "ASP1 Playback" },
3117 { "ASP1RX3", NULL, "ASP1 Playback" },
3118 { "ASP1RX4", NULL, "ASP1 Playback" },
3119 { "ASP1RX5", NULL, "ASP1 Playback" },
3120 { "ASP1RX6", NULL, "ASP1 Playback" },
3121 { "ASP1RX7", NULL, "ASP1 Playback" },
3122 { "ASP1RX8", NULL, "ASP1 Playback" },
3123
3124 { "ASP2 Capture", NULL, "ASP2TX1" },
3125 { "ASP2 Capture", NULL, "ASP2TX2" },
3126 { "ASP2 Capture", NULL, "ASP2TX3" },
3127 { "ASP2 Capture", NULL, "ASP2TX4" },
3128
3129 { "ASP2RX1", NULL, "ASP2 Playback" },
3130 { "ASP2RX2", NULL, "ASP2 Playback" },
3131 { "ASP2RX3", NULL, "ASP2 Playback" },
3132 { "ASP2RX4", NULL, "ASP2 Playback" },
3133
3134 { "ASP1 Playback", NULL, "SYSCLK" },
3135 { "ASP2 Playback", NULL, "SYSCLK" },
3136
3137 { "ASP1 Capture", NULL, "SYSCLK" },
3138 { "ASP2 Capture", NULL, "SYSCLK" },
3139
3140 { "IN1L Mux", "Analog 1", "IN1LN_1" },
3141 { "IN1L Mux", "Analog 2", "IN1LN_2" },
3142 { "IN1L Mux", "Analog 1", "IN1LP_1" },
3143 { "IN1L Mux", "Analog 2", "IN1LP_2" },
3144 { "IN1R Mux", "Analog 1", "IN1RN_1" },
3145 { "IN1R Mux", "Analog 2", "IN1RN_2" },
3146 { "IN1R Mux", "Analog 1", "IN1RP_1" },
3147 { "IN1R Mux", "Analog 2", "IN1RP_2" },
3148
3149 { "IN1L PGA", NULL, "IN1L Mode" },
3150 { "IN1R PGA", NULL, "IN1R Mode" },
3151
3152 { "IN1L Mode", "Analog", "IN1L Mux" },
3153 { "IN1R Mode", "Analog", "IN1R Mux" },
3154
3155 { "IN1L Mode", "Digital", "IN1_PDMCLK" },
3156 { "IN1L Mode", "Digital", "IN1_PDMDATA" },
3157 { "IN1R Mode", "Digital", "IN1_PDMCLK" },
3158 { "IN1R Mode", "Digital", "IN1_PDMDATA" },
3159
3160 { "IN1L PGA", NULL, "VOUT_MIC" },
3161 { "IN1R PGA", NULL, "VOUT_MIC" },
3162
3163 { "IN2L PGA", NULL, "VOUT_MIC" },
3164 { "IN2R PGA", NULL, "VOUT_MIC" },
3165
3166 { "IN2L PGA", NULL, "IN2_PDMCLK" },
3167 { "IN2R PGA", NULL, "IN2_PDMCLK" },
3168 { "IN2L PGA", NULL, "IN2_PDMDATA" },
3169 { "IN2R PGA", NULL, "IN2_PDMDATA" },
3170
3171 { "Ultrasonic 1", NULL, "Ultrasonic 1 Input" },
3172 { "Ultrasonic 2", NULL, "Ultrasonic 2 Input" },
3173
3174 { "Ultrasonic 1 Input", "IN1L", "IN1L PGA" },
3175 { "Ultrasonic 1 Input", "IN1R", "IN1R PGA" },
3176 { "Ultrasonic 1 Input", "IN2L", "IN2L PGA" },
3177 { "Ultrasonic 1 Input", "IN2R", "IN2R PGA" },
3178
3179 { "Ultrasonic 2 Input", "IN1L", "IN1L PGA" },
3180 { "Ultrasonic 2 Input", "IN1R", "IN1R PGA" },
3181 { "Ultrasonic 2 Input", "IN2L", "IN2L PGA" },
3182 { "Ultrasonic 2 Input", "IN2R", "IN2R PGA" },
3183
3184 { "Ultrasonic 1 Detect", "Switch", "Ultrasonic 1 Input" },
3185 { "Ultrasonic 2 Detect", "Switch", "Ultrasonic 2 Input" },
3186
3187 { "Ultrasonic Dummy Output", NULL, "Ultrasonic 1 Detect" },
3188 { "Ultrasonic Dummy Output", NULL, "Ultrasonic 2 Detect" },
3189
3190 CS48L32_MIXER_ROUTES("ASP1TX1", "ASP1TX1"),
3191 CS48L32_MIXER_ROUTES("ASP1TX2", "ASP1TX2"),
3192 CS48L32_MIXER_ROUTES("ASP1TX3", "ASP1TX3"),
3193 CS48L32_MIXER_ROUTES("ASP1TX4", "ASP1TX4"),
3194 CS48L32_MIXER_ROUTES("ASP1TX5", "ASP1TX5"),
3195 CS48L32_MIXER_ROUTES("ASP1TX6", "ASP1TX6"),
3196 CS48L32_MIXER_ROUTES("ASP1TX7", "ASP1TX7"),
3197 CS48L32_MIXER_ROUTES("ASP1TX8", "ASP1TX8"),
3198
3199 CS48L32_MIXER_ROUTES("ASP2TX1", "ASP2TX1"),
3200 CS48L32_MIXER_ROUTES("ASP2TX2", "ASP2TX2"),
3201 CS48L32_MIXER_ROUTES("ASP2TX3", "ASP2TX3"),
3202 CS48L32_MIXER_ROUTES("ASP2TX4", "ASP2TX4"),
3203
3204 CS48L32_MIXER_ROUTES("EQ1", "EQ1"),
3205 CS48L32_MIXER_ROUTES("EQ2", "EQ2"),
3206 CS48L32_MIXER_ROUTES("EQ3", "EQ3"),
3207 CS48L32_MIXER_ROUTES("EQ4", "EQ4"),
3208
3209 CS48L32_MIXER_ROUTES("DRC1L", "DRC1L"),
3210 CS48L32_MIXER_ROUTES("DRC1R", "DRC1R"),
3211 CS48L32_MIXER_ROUTES("DRC2L", "DRC2L"),
3212 CS48L32_MIXER_ROUTES("DRC2R", "DRC2R"),
3213
3214 CS48L32_MIXER_ROUTES("LHPF1", "LHPF1"),
3215 CS48L32_MIXER_ROUTES("LHPF2", "LHPF2"),
3216 CS48L32_MIXER_ROUTES("LHPF3", "LHPF3"),
3217 CS48L32_MIXER_ROUTES("LHPF4", "LHPF4"),
3218
3219 CS48L32_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
3220 CS48L32_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
3221 CS48L32_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
3222 CS48L32_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
3223
3224 CS48L32_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
3225 CS48L32_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
3226 CS48L32_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
3227 CS48L32_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
3228
3229 CS48L32_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
3230 CS48L32_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
3231
3232 CS48L32_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
3233 CS48L32_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
3234
3235 CS48L32_MUX_ROUTES("ISRC3INT1", "ISRC3INT1"),
3236 CS48L32_MUX_ROUTES("ISRC3INT2", "ISRC3INT2"),
3237
3238 CS48L32_MUX_ROUTES("ISRC3DEC1", "ISRC3DEC1"),
3239 CS48L32_MUX_ROUTES("ISRC3DEC2", "ISRC3DEC2"),
3240
3241 CS48L32_DSP_ROUTES_1_8_SYSCLK("DSP1"),
3242
3243 { "DSP Trigger Out", NULL, "DSP1 Trigger Output" },
3244
3245 { "DSP1 Trigger Output", "Switch", "DSP1" },
3246
3247 { "AUXPDM1 Analog Input", "IN1L", "IN1L PGA" },
3248 { "AUXPDM1 Analog Input", "IN1R", "IN1R PGA" },
3249
3250 { "AUXPDM2 Analog Input", "IN1L", "IN1L PGA" },
3251 { "AUXPDM2 Analog Input", "IN1R", "IN1R PGA" },
3252
3253 { "AUXPDM1 Input", "Analog", "AUXPDM1 Analog Input" },
3254 { "AUXPDM1 Input", "IN1 Digital", "IN1L PGA" },
3255 { "AUXPDM1 Input", "IN1 Digital", "IN1R PGA" },
3256 { "AUXPDM1 Input", "IN2 Digital", "IN2L PGA" },
3257 { "AUXPDM1 Input", "IN2 Digital", "IN2R PGA" },
3258
3259 { "AUXPDM2 Input", "Analog", "AUXPDM2 Analog Input" },
3260 { "AUXPDM2 Input", "IN1 Digital", "IN1L PGA" },
3261 { "AUXPDM2 Input", "IN1 Digital", "IN1R PGA" },
3262 { "AUXPDM2 Input", "IN2 Digital", "IN2L PGA" },
3263 { "AUXPDM2 Input", "IN2 Digital", "IN2R PGA" },
3264
3265 { "AUXPDM1 Output", "Switch", "AUXPDM1 Input" },
3266 { "AUXPDM1_CLK", NULL, "AUXPDM1 Output" },
3267 { "AUXPDM1_DOUT", NULL, "AUXPDM1 Output" },
3268
3269 { "AUXPDM2 Output", "Switch", "AUXPDM2 Input" },
3270 { "AUXPDM2_CLK", NULL, "AUXPDM2 Output" },
3271 { "AUXPDM2_DOUT", NULL, "AUXPDM2 Output" },
3272
3273 { "MICSUPP", NULL, "SYSCLK" },
3274
3275 { "DRC1 Signal Activity", NULL, "DRC1 Activity Output" },
3276 { "DRC2 Signal Activity", NULL, "DRC2 Activity Output" },
3277 { "DRC1 Activity Output", "Switch", "DRC1L" },
3278 { "DRC1 Activity Output", "Switch", "DRC1R" },
3279 { "DRC2 Activity Output", "Switch", "DRC2L" },
3280 { "DRC2 Activity Output", "Switch", "DRC2R" },
3281 };
3282
cs48l32_compr_open(struct snd_soc_component * component,struct snd_compr_stream * stream)3283 static int cs48l32_compr_open(struct snd_soc_component *component,
3284 struct snd_compr_stream *stream)
3285 {
3286 struct snd_soc_pcm_runtime *rtd = stream->private_data;
3287 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3288
3289 if (strcmp(snd_soc_rtd_to_codec(rtd, 0)->name, "cs48l32-dsp-trace") &&
3290 strcmp(snd_soc_rtd_to_codec(rtd, 0)->name, "cs48l32-dsp-voicectrl")) {
3291 dev_err(cs48l32_codec->core.dev, "No suitable compressed stream for DAI '%s'\n",
3292 snd_soc_rtd_to_codec(rtd, 0)->name);
3293 return -EINVAL;
3294 }
3295
3296 return wm_adsp_compr_open(&cs48l32_codec->dsp, stream);
3297 }
3298
3299 static const struct snd_compress_ops cs48l32_compress_ops = {
3300 .open = &cs48l32_compr_open,
3301 .free = &wm_adsp_compr_free,
3302 .set_params = &wm_adsp_compr_set_params,
3303 .get_caps = &wm_adsp_compr_get_caps,
3304 .trigger = &wm_adsp_compr_trigger,
3305 .pointer = &wm_adsp_compr_pointer,
3306 .copy = &wm_adsp_compr_copy,
3307 };
3308
3309 static const struct snd_soc_dai_ops cs48l32_compress_dai_ops = {
3310 .compress_new = snd_soc_new_compress,
3311 };
3312
3313 static struct snd_soc_dai_driver cs48l32_dai[] = {
3314 {
3315 .name = "cs48l32-asp1",
3316 .id = 1,
3317 .base = CS48L32_ASP1_ENABLES1,
3318 .playback = {
3319 .stream_name = "ASP1 Playback",
3320 .channels_min = 1,
3321 .channels_max = 8,
3322 .rates = CS48L32_RATES,
3323 .formats = CS48L32_FORMATS,
3324 },
3325 .capture = {
3326 .stream_name = "ASP1 Capture",
3327 .channels_min = 1,
3328 .channels_max = 8,
3329 .rates = CS48L32_RATES,
3330 .formats = CS48L32_FORMATS,
3331 },
3332 .ops = &cs48l32_dai_ops,
3333 .symmetric_rate = 1,
3334 .symmetric_sample_bits = 1,
3335 },
3336 {
3337 .name = "cs48l32-asp2",
3338 .id = 2,
3339 .base = CS48L32_ASP2_ENABLES1,
3340 .playback = {
3341 .stream_name = "ASP2 Playback",
3342 .channels_min = 1,
3343 .channels_max = 4,
3344 .rates = CS48L32_RATES,
3345 .formats = CS48L32_FORMATS,
3346 },
3347 .capture = {
3348 .stream_name = "ASP2 Capture",
3349 .channels_min = 1,
3350 .channels_max = 4,
3351 .rates = CS48L32_RATES,
3352 .formats = CS48L32_FORMATS,
3353 },
3354 .ops = &cs48l32_dai_ops,
3355 .symmetric_rate = 1,
3356 .symmetric_sample_bits = 1,
3357 },
3358 {
3359 .name = "cs48l32-cpu-trace",
3360 .id = 3,
3361 .capture = {
3362 .stream_name = "Audio Trace CPU",
3363 .channels_min = 1,
3364 .channels_max = 8,
3365 .rates = CS48L32_RATES,
3366 .formats = CS48L32_FORMATS,
3367 },
3368 .ops = &cs48l32_compress_dai_ops,
3369 },
3370 {
3371 .name = "cs48l32-dsp-trace",
3372 .id = 4,
3373 .capture = {
3374 .stream_name = "Audio Trace DSP",
3375 .channels_min = 1,
3376 .channels_max = 8,
3377 .rates = CS48L32_RATES,
3378 .formats = CS48L32_FORMATS,
3379 },
3380 },
3381 {
3382 .name = "cs48l32-cpu-voicectrl",
3383 .id = 5,
3384 .capture = {
3385 .stream_name = "Voice Ctrl CPU",
3386 .channels_min = 1,
3387 .channels_max = 8,
3388 .rates = CS48L32_RATES,
3389 .formats = CS48L32_FORMATS,
3390 },
3391 .ops = &cs48l32_compress_dai_ops,
3392 },
3393 {
3394 .name = "cs48l32-dsp-voicectrl",
3395 .id = 6,
3396 .capture = {
3397 .stream_name = "Voice Ctrl DSP",
3398 .channels_min = 1,
3399 .channels_max = 8,
3400 .rates = CS48L32_RATES,
3401 .formats = CS48L32_FORMATS,
3402 },
3403 },
3404 };
3405
cs48l32_init_inputs(struct snd_soc_component * component)3406 static int cs48l32_init_inputs(struct snd_soc_component *component)
3407 {
3408 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3409 struct regmap *regmap = cs48l32_codec->core.regmap;
3410 unsigned int ana_mode_l, ana_mode_r, dig_mode;
3411 int i;
3412
3413 /*
3414 * Initialize input modes from the A settings. For muxed inputs the
3415 * B settings will be applied if the mux is changed
3416 */
3417 switch (cs48l32_codec->in_type[0][0]) {
3418 default:
3419 case CS48L32_IN_TYPE_DIFF:
3420 ana_mode_l = 0;
3421 break;
3422 case CS48L32_IN_TYPE_SE:
3423 ana_mode_l = 1 << CS48L32_INx_SRC_SHIFT;
3424 break;
3425 }
3426
3427 switch (cs48l32_codec->in_type[1][0]) {
3428 default:
3429 case CS48L32_IN_TYPE_DIFF:
3430 ana_mode_r = 0;
3431 break;
3432 case CS48L32_IN_TYPE_SE:
3433 ana_mode_r = 1 << CS48L32_INx_SRC_SHIFT;
3434 break;
3435 }
3436
3437 dev_dbg(cs48l32_codec->core.dev, "IN1_1 Analogue mode=#%x,#%x\n",
3438 ana_mode_l, ana_mode_r);
3439
3440 regmap_update_bits(regmap,
3441 CS48L32_IN1L_CONTROL1,
3442 CS48L32_INx_SRC_MASK,
3443 ana_mode_l);
3444
3445 regmap_update_bits(regmap,
3446 CS48L32_IN1R_CONTROL1,
3447 CS48L32_INx_SRC_MASK,
3448 ana_mode_r);
3449
3450 for (i = 0; i < ARRAY_SIZE(cs48l32_codec->pdm_sup); i++) {
3451 dig_mode = cs48l32_codec->pdm_sup[i] << CS48L32_IN1_PDM_SUP_SHIFT;
3452
3453 dev_dbg(cs48l32_codec->core.dev, "IN%d PDM_SUP=#%x\n", i + 1, dig_mode);
3454
3455 regmap_update_bits(regmap,
3456 CS48L32_INPUT1_CONTROL1 + (i * 0x40),
3457 CS48L32_IN1_PDM_SUP_MASK, dig_mode);
3458 }
3459
3460 return 0;
3461 }
3462
cs48l32_init_dai(struct cs48l32_codec * cs48l32_codec,int id)3463 static int cs48l32_init_dai(struct cs48l32_codec *cs48l32_codec, int id)
3464 {
3465 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[id];
3466
3467 dai_priv->clk = CS48L32_CLK_SYSCLK_1;
3468 dai_priv->constraint = cs48l32_constraint;
3469
3470 return 0;
3471 }
3472
cs48l32_init_eq(struct cs48l32_codec * cs48l32_codec)3473 static int cs48l32_init_eq(struct cs48l32_codec *cs48l32_codec)
3474 {
3475 struct regmap *regmap = cs48l32_codec->core.regmap;
3476 unsigned int reg = CS48L32_EQ1_BAND1_COEFF1, mode;
3477 __be16 *data;
3478 int i, ret;
3479
3480 ret = regmap_read(regmap, CS48L32_EQ_CONTROL2, &mode);
3481 if (ret < 0) {
3482 dev_err(cs48l32_codec->core.dev, "Error reading EQ mode: %d\n", ret);
3483 goto out;
3484 }
3485
3486 for (i = 0; i < 4; ++i) {
3487 cs48l32_codec->eq_mode[i] = (mode >> i) & 0x1;
3488
3489 data = &cs48l32_codec->eq_coefficients[i][0];
3490 ret = regmap_raw_read(regmap, reg + (i * 68), data,
3491 CS48L32_EQ_BLOCK_SZ);
3492 if (ret < 0) {
3493 dev_err(cs48l32_codec->core.dev,
3494 "Error reading EQ coefficients: %d\n", ret);
3495 goto out;
3496 }
3497 }
3498
3499 out:
3500 return ret;
3501 }
3502
cs48l32_component_probe(struct snd_soc_component * component)3503 static int cs48l32_component_probe(struct snd_soc_component *component)
3504 {
3505 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3506 int i, ret;
3507
3508 snd_soc_component_init_regmap(component, cs48l32_codec->core.regmap);
3509
3510 ret = cs48l32_init_inputs(component);
3511 if (ret)
3512 return ret;
3513
3514 for (i = 0; i < ARRAY_SIZE(cs48l32_dai); i++)
3515 cs48l32_init_dai(cs48l32_codec, i);
3516
3517 ret = cs48l32_init_eq(cs48l32_codec);
3518 if (ret)
3519 return ret;
3520
3521 wm_adsp2_component_probe(&cs48l32_codec->dsp, component);
3522
3523 /* Unmask DSP IRQs */
3524 regmap_clear_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_7,
3525 CS48L32_DSP1_MPU_ERR_EINT1_MASK | CS48L32_DSP1_WDT_EXPIRE_EINT1_MASK);
3526 regmap_clear_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_9,
3527 CS48L32_DSP1_IRQ0_EINT1_MASK);
3528
3529 return 0;
3530 }
3531
cs48l32_component_remove(struct snd_soc_component * component)3532 static void cs48l32_component_remove(struct snd_soc_component *component)
3533 {
3534 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3535
3536 /* Mask DSP IRQs */
3537 regmap_set_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_7,
3538 CS48L32_DSP1_MPU_ERR_EINT1_MASK | CS48L32_DSP1_WDT_EXPIRE_EINT1_MASK);
3539 regmap_set_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_9,
3540 CS48L32_DSP1_IRQ0_EINT1_MASK);
3541
3542 wm_adsp2_component_remove(&cs48l32_codec->dsp, component);
3543 }
3544
3545 static const struct snd_soc_component_driver cs48l32_soc_component_drv = {
3546 .probe = &cs48l32_component_probe,
3547 .remove = &cs48l32_component_remove,
3548 .set_sysclk = &cs48l32_set_sysclk,
3549 .set_pll = &cs48l32_set_fll,
3550 .name = "cs48l32-codec",
3551 .compress_ops = &cs48l32_compress_ops,
3552 .controls = cs48l32_snd_controls,
3553 .num_controls = ARRAY_SIZE(cs48l32_snd_controls),
3554 .dapm_widgets = cs48l32_dapm_widgets,
3555 .num_dapm_widgets = ARRAY_SIZE(cs48l32_dapm_widgets),
3556 .dapm_routes = cs48l32_dapm_routes,
3557 .num_dapm_routes = ARRAY_SIZE(cs48l32_dapm_routes),
3558 .use_pmdown_time = 1,
3559 .endianness = 1,
3560 };
3561
cs48l32_prop_read_u32_array(struct cs48l32_codec * cs48l32_codec,const char * propname,u32 * dest,int n_max)3562 static int cs48l32_prop_read_u32_array(struct cs48l32_codec *cs48l32_codec,
3563 const char *propname,
3564 u32 *dest,
3565 int n_max)
3566 {
3567 struct cs48l32 *cs48l32 = &cs48l32_codec->core;
3568 int ret;
3569
3570 ret = device_property_read_u32_array(cs48l32->dev, propname, dest, n_max);
3571 if (ret == -EINVAL)
3572 return -ENOENT;
3573
3574 if (ret < 0)
3575 return dev_err_probe(cs48l32->dev, ret, "%s malformed\n", propname);
3576
3577 return 0;
3578 }
3579
cs48l32_prop_get_in_type(struct cs48l32_codec * cs48l32_codec)3580 static void cs48l32_prop_get_in_type(struct cs48l32_codec *cs48l32_codec)
3581 {
3582 const char *propname = "cirrus,in-type";
3583 u32 tmp[CS48L32_MAX_ANALOG_INPUT * CS48L32_MAX_IN_MUX_WAYS];
3584 int i, in_idx, mux_way_idx, ret;
3585
3586 static_assert(ARRAY_SIZE(tmp) ==
3587 ARRAY_SIZE(cs48l32_codec->in_type) * ARRAY_SIZE(cs48l32_codec->in_type[0]));
3588
3589 ret = cs48l32_prop_read_u32_array(cs48l32_codec, propname, tmp, ARRAY_SIZE(tmp));
3590 if (ret < 0)
3591 return;
3592
3593 in_idx = 0;
3594 mux_way_idx = 0;
3595 for (i = 0; i < ARRAY_SIZE(tmp); ++i) {
3596 switch (tmp[i]) {
3597 case CS48L32_IN_TYPE_DIFF:
3598 case CS48L32_IN_TYPE_SE:
3599 cs48l32_codec->in_type[in_idx][mux_way_idx] = tmp[i];
3600 break;
3601 default:
3602 dev_warn(cs48l32_codec->core.dev, "Illegal %s value %d ignored\n",
3603 propname, tmp[i]);
3604 break;
3605 }
3606
3607 /*
3608 * Property array is [mux_way][in_channel]. Swap to
3609 * [in_channel][mux_way] for convenience.
3610 */
3611 if (++in_idx == ARRAY_SIZE(cs48l32_codec->in_type)) {
3612 in_idx = 0;
3613 ++mux_way_idx;
3614 }
3615 }
3616 }
3617
cs48l32_prop_get_pdm_sup(struct cs48l32_codec * cs48l32_codec)3618 static void cs48l32_prop_get_pdm_sup(struct cs48l32_codec *cs48l32_codec)
3619 {
3620 const char *propname = "cirrus,pdm-sup";
3621 u32 tmp[CS48L32_MAX_ANALOG_INPUT];
3622 int i;
3623
3624 static_assert(ARRAY_SIZE(tmp) == ARRAY_SIZE(cs48l32_codec->pdm_sup));
3625
3626 cs48l32_prop_read_u32_array(cs48l32_codec, propname, tmp, ARRAY_SIZE(tmp));
3627
3628 for (i = 0; i < ARRAY_SIZE(cs48l32_codec->pdm_sup); i++) {
3629 switch (tmp[i]) {
3630 case CS48L32_PDM_SUP_VOUT_MIC:
3631 case CS48L32_PDM_SUP_MICBIAS1:
3632 cs48l32_codec->pdm_sup[i] = tmp[i];
3633 break;
3634 default:
3635 dev_warn(cs48l32_codec->core.dev, "Illegal %s value %d ignored\n",
3636 propname, cs48l32_codec->pdm_sup[i]);
3637 break;
3638 }
3639 }
3640 }
3641
cs48l32_handle_properties(struct cs48l32_codec * cs48l32_codec)3642 static void cs48l32_handle_properties(struct cs48l32_codec *cs48l32_codec)
3643 {
3644 cs48l32_prop_get_in_type(cs48l32_codec);
3645 cs48l32_prop_get_pdm_sup(cs48l32_codec);
3646 }
3647
cs48l32_request_interrupt(struct cs48l32_codec * cs48l32_codec)3648 static int cs48l32_request_interrupt(struct cs48l32_codec *cs48l32_codec)
3649 {
3650 int irq = cs48l32_codec->core.irq;
3651 int ret;
3652
3653 if (irq < 1)
3654 return 0;
3655
3656 /*
3657 * Don't use devm because this must be freed before destroying the
3658 * rest of the driver
3659 */
3660 ret = request_threaded_irq(irq, NULL, cs48l32_irq,
3661 IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW,
3662 "cs48l32", cs48l32_codec);
3663 if (ret)
3664 return dev_err_probe(cs48l32_codec->core.dev, ret, "Failed to get IRQ\n");
3665
3666 return 0;
3667 }
3668
cs48l32_create_codec_component(struct cs48l32_codec * cs48l32_codec)3669 static int cs48l32_create_codec_component(struct cs48l32_codec *cs48l32_codec)
3670 {
3671 struct wm_adsp *dsp;
3672 int ret;
3673
3674 ASSERT_STRUCT_OFFSET(struct cs48l32_codec, dsp, 0);
3675 static_assert(ARRAY_SIZE(cs48l32_dai) == ARRAY_SIZE(cs48l32_codec->dai));
3676
3677 cs48l32_handle_properties(cs48l32_codec);
3678
3679 dsp = &cs48l32_codec->dsp;
3680 dsp->part = "cs48l32";
3681 dsp->cs_dsp.num = 1;
3682 dsp->cs_dsp.type = WMFW_HALO;
3683 dsp->cs_dsp.rev = 0;
3684 dsp->cs_dsp.dev = cs48l32_codec->core.dev;
3685 dsp->cs_dsp.regmap = cs48l32_codec->core.regmap;
3686 dsp->cs_dsp.base = CS48L32_DSP1_CLOCK_FREQ;
3687 dsp->cs_dsp.base_sysinfo = CS48L32_DSP1_SYS_INFO_ID;
3688 dsp->cs_dsp.mem = cs48l32_dsp1_regions;
3689 dsp->cs_dsp.num_mems = ARRAY_SIZE(cs48l32_dsp1_regions);
3690 dsp->pre_run = cs48l32_dsp_pre_run;
3691
3692 ret = wm_halo_init(dsp);
3693 if (ret != 0)
3694 return ret;
3695
3696 cs48l32_codec->fll.codec = cs48l32_codec;
3697 cs48l32_codec->fll.id = 1;
3698 cs48l32_codec->fll.base = CS48L32_FLL1_CONTROL1;
3699 cs48l32_codec->fll.sts_addr = CS48L32_IRQ1_STS_6;
3700 cs48l32_codec->fll.sts_mask = CS48L32_FLL1_LOCK_STS1_MASK;
3701 cs48l32_init_fll(&cs48l32_codec->fll);
3702
3703 ret = cs48l32_request_interrupt(cs48l32_codec);
3704 if (ret)
3705 goto err_dsp;
3706
3707 ret = devm_snd_soc_register_component(cs48l32_codec->core.dev,
3708 &cs48l32_soc_component_drv,
3709 cs48l32_dai,
3710 ARRAY_SIZE(cs48l32_dai));
3711 if (ret < 0) {
3712 dev_err_probe(cs48l32_codec->core.dev, ret, "Failed to register component\n");
3713 goto err_dsp;
3714 }
3715
3716 return 0;
3717
3718 err_dsp:
3719 wm_adsp2_remove(&cs48l32_codec->dsp);
3720
3721 return ret;
3722 }
3723
cs48l32_wait_for_boot(struct cs48l32 * cs48l32)3724 static int cs48l32_wait_for_boot(struct cs48l32 *cs48l32)
3725 {
3726 unsigned int val;
3727 int ret;
3728
3729 ret = regmap_read_poll_timeout(cs48l32->regmap, CS48L32_IRQ1_EINT_2, val,
3730 ((val < 0xffffffff) && (val & CS48L32_BOOT_DONE_EINT1_MASK)),
3731 1000, CS48L32_BOOT_TIMEOUT_US);
3732 if (ret) {
3733 dev_err(cs48l32->dev, "BOOT_DONE timed out\n");
3734 return -ETIMEDOUT;
3735 }
3736
3737 ret = regmap_read(cs48l32->regmap, CS48L32_MCU_CTRL1, &val);
3738 if (ret) {
3739 dev_err(cs48l32->dev, "Failed to read MCU_CTRL1: %d\n", ret);
3740 return ret;
3741 }
3742
3743 if (val & BIT(CS48L32_MCU_STS_SHIFT)) {
3744 dev_err(cs48l32->dev, "MCU boot failed\n");
3745 return -EIO;
3746 }
3747
3748 pm_runtime_mark_last_busy(cs48l32->dev);
3749
3750 return 0;
3751 }
3752
cs48l32_soft_reset(struct cs48l32 * cs48l32)3753 static int cs48l32_soft_reset(struct cs48l32 *cs48l32)
3754 {
3755 int ret;
3756
3757 ret = regmap_write(cs48l32->regmap, CS48L32_SFT_RESET, CS48L32_SFT_RESET_MAGIC);
3758 if (ret != 0) {
3759 dev_err(cs48l32->dev, "Failed to write soft reset: %d\n", ret);
3760 return ret;
3761 }
3762
3763 usleep_range(CS48L32_SOFT_RESET_US, CS48L32_SOFT_RESET_US + 1000);
3764
3765 return 0;
3766 }
3767
cs48l32_enable_hard_reset(struct cs48l32 * cs48l32)3768 static void cs48l32_enable_hard_reset(struct cs48l32 *cs48l32)
3769 {
3770 if (cs48l32->reset_gpio)
3771 gpiod_set_raw_value_cansleep(cs48l32->reset_gpio, 0);
3772 }
3773
cs48l32_disable_hard_reset(struct cs48l32 * cs48l32)3774 static void cs48l32_disable_hard_reset(struct cs48l32 *cs48l32)
3775 {
3776 if (cs48l32->reset_gpio) {
3777 gpiod_set_raw_value_cansleep(cs48l32->reset_gpio, 1);
3778 usleep_range(CS48L32_HARD_RESET_MIN_US, CS48L32_HARD_RESET_MIN_US + 1000);
3779 }
3780 }
3781
cs48l32_runtime_resume(struct device * dev)3782 static int cs48l32_runtime_resume(struct device *dev)
3783 {
3784 struct cs48l32_codec *cs48l32_codec = dev_get_drvdata(dev);
3785 struct cs48l32 *cs48l32 = &cs48l32_codec->core;
3786 unsigned int val;
3787 int ret;
3788
3789 ret = regulator_enable(cs48l32->vdd_d);
3790 if (ret) {
3791 dev_err(cs48l32->dev, "Failed to enable VDD_D: %d\n", ret);
3792 return ret;
3793 }
3794
3795 usleep_range(CS48L32_SOFT_RESET_US, CS48L32_SOFT_RESET_US + 1000);
3796
3797 regcache_cache_only(cs48l32->regmap, false);
3798
3799 ret = cs48l32_wait_for_boot(cs48l32);
3800 if (ret)
3801 goto err;
3802
3803 /* Check whether registers reset during suspend */
3804 regmap_read(cs48l32->regmap, CS48L32_CTRL_IF_DEBUG3, &val);
3805 if (!val)
3806 regcache_mark_dirty(cs48l32->regmap);
3807 else
3808 dev_dbg(cs48l32->dev, "Did not reset during suspend\n");
3809
3810 ret = regcache_sync(cs48l32->regmap);
3811 if (ret) {
3812 dev_err(cs48l32->dev, "Failed to restore register cache\n");
3813 goto err;
3814 }
3815
3816 return 0;
3817
3818 err:
3819 regcache_cache_only(cs48l32->regmap, true);
3820 regulator_disable(cs48l32->vdd_d);
3821
3822 return ret;
3823 }
3824
cs48l32_runtime_suspend(struct device * dev)3825 static int cs48l32_runtime_suspend(struct device *dev)
3826 {
3827 struct cs48l32_codec *cs48l32_codec = dev_get_drvdata(dev);
3828 struct cs48l32 *cs48l32 = &cs48l32_codec->core;
3829
3830 /* Flag to detect if the registers reset during suspend */
3831 regmap_write(cs48l32->regmap, CS48L32_CTRL_IF_DEBUG3, 1);
3832
3833 regcache_cache_only(cs48l32->regmap, true);
3834 regulator_disable(cs48l32->vdd_d);
3835
3836 return 0;
3837 }
3838
3839 static const struct dev_pm_ops cs48l32_pm_ops = {
3840 RUNTIME_PM_OPS(cs48l32_runtime_suspend, cs48l32_runtime_resume, NULL)
3841 };
3842
cs48l32_configure_clk32k(struct cs48l32 * cs48l32)3843 static int cs48l32_configure_clk32k(struct cs48l32 *cs48l32)
3844 {
3845 int ret = 0;
3846
3847 ret = clk_prepare_enable(cs48l32->mclk1);
3848 if (ret)
3849 return dev_err_probe(cs48l32->dev, ret, "Failed to enable 32k clock\n");
3850
3851 ret = regmap_update_bits(cs48l32->regmap, CS48L32_CLOCK32K,
3852 CS48L32_CLK_32K_EN_MASK | CS48L32_CLK_32K_SRC_MASK,
3853 CS48L32_CLK_32K_EN_MASK | CS48L32_32K_MCLK1);
3854 if (ret) {
3855 clk_disable_unprepare(cs48l32->mclk1);
3856 return dev_err_probe(cs48l32->dev, ret, "Failed to init 32k clock\n");
3857 }
3858
3859 return 0;
3860 }
3861
cs48l32_get_clocks(struct cs48l32 * cs48l32)3862 static int cs48l32_get_clocks(struct cs48l32 *cs48l32)
3863 {
3864 cs48l32->mclk1 = devm_clk_get_optional(cs48l32->dev, "mclk1");
3865 if (IS_ERR(cs48l32->mclk1))
3866 return dev_err_probe(cs48l32->dev, PTR_ERR(cs48l32->mclk1),
3867 "Failed to get mclk1\n");
3868
3869 return 0;
3870 }
3871
cs48l32_get_reset_gpio(struct cs48l32 * cs48l32)3872 static int cs48l32_get_reset_gpio(struct cs48l32 *cs48l32)
3873 {
3874 struct gpio_desc *reset;
3875
3876 reset = devm_gpiod_get_optional(cs48l32->dev, "reset", GPIOD_OUT_LOW);
3877 if (IS_ERR(reset))
3878 return dev_err_probe(cs48l32->dev, PTR_ERR(reset), "Failed to request /RESET\n");
3879
3880 /* ACPI can override the GPIOD_OUT_LOW so ensure it starts low */
3881 gpiod_set_raw_value_cansleep(reset, 0);
3882
3883 cs48l32->reset_gpio = reset;
3884
3885 return 0;
3886 }
3887
cs48l32_spi_probe(struct spi_device * spi)3888 static int cs48l32_spi_probe(struct spi_device *spi)
3889 {
3890 struct device *dev = &spi->dev;
3891 struct cs48l32_codec *cs48l32_codec;
3892 struct cs48l32 *cs48l32;
3893 unsigned int hwid, rev, otp_rev;
3894 int i, ret;
3895
3896 cs48l32_codec = devm_kzalloc(&spi->dev, sizeof(*cs48l32_codec), GFP_KERNEL);
3897 if (!cs48l32_codec)
3898 return -ENOMEM;
3899
3900 cs48l32 = &cs48l32_codec->core;
3901 cs48l32->dev = dev;
3902 cs48l32->irq = spi->irq;
3903 mutex_init(&cs48l32_codec->rate_lock);
3904 cs48l32_codec->in_vu_reg = CS48L32_INPUT_CONTROL3;
3905
3906 dev_set_drvdata(cs48l32->dev, cs48l32_codec);
3907
3908 ret = cs48l32_create_regmap(spi, cs48l32);
3909 if (ret)
3910 return dev_err_probe(&spi->dev, ret, "Failed to allocate regmap\n");
3911
3912 regcache_cache_only(cs48l32->regmap, true);
3913
3914 ret = cs48l32_get_reset_gpio(cs48l32);
3915 if (ret)
3916 return ret;
3917
3918 ret = cs48l32_get_clocks(cs48l32);
3919 if (ret)
3920 return ret;
3921
3922 static_assert(ARRAY_SIZE(cs48l32_core_supplies) == ARRAY_SIZE(cs48l32->core_supplies));
3923 for (i = 0; i < ARRAY_SIZE(cs48l32->core_supplies); i++)
3924 cs48l32->core_supplies[i].supply = cs48l32_core_supplies[i];
3925
3926 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs48l32->core_supplies),
3927 cs48l32->core_supplies);
3928 if (ret)
3929 return dev_err_probe(dev, ret, "Failed to request core supplies\n");
3930
3931 cs48l32->vdd_d = devm_regulator_get(cs48l32->dev, "vdd-d");
3932 if (IS_ERR(cs48l32->vdd_d))
3933 return dev_err_probe(dev, PTR_ERR(cs48l32->vdd_d), "Failed to request vdd-d\n");
3934
3935 ret = regulator_bulk_enable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies);
3936 if (ret)
3937 return dev_err_probe(dev, ret, "Failed to enable core supplies\n");
3938
3939 ret = regulator_enable(cs48l32->vdd_d);
3940 if (ret) {
3941 dev_err(dev, "Failed to enable vdd-d: %d\n", ret);
3942 goto err_enable;
3943 }
3944
3945 cs48l32_disable_hard_reset(cs48l32);
3946
3947 regcache_cache_only(cs48l32->regmap, false);
3948
3949 /* If we don't have a reset GPIO use a soft reset */
3950 if (!cs48l32->reset_gpio) {
3951 ret = cs48l32_soft_reset(cs48l32);
3952 if (ret)
3953 goto err_reset;
3954 }
3955
3956 ret = cs48l32_wait_for_boot(cs48l32);
3957 if (ret) {
3958 dev_err(cs48l32->dev, "Device failed initial boot: %d\n", ret);
3959 goto err_reset;
3960 }
3961
3962 ret = regmap_read(cs48l32->regmap, CS48L32_DEVID, &hwid);
3963 if (ret) {
3964 dev_err(dev, "Failed to read ID register: %d\n", ret);
3965 goto err_reset;
3966 }
3967 hwid &= CS48L32_DEVID_MASK;
3968
3969 switch (hwid) {
3970 case CS48L32_SILICON_ID:
3971 break;
3972 default:
3973 ret = -ENODEV;
3974 dev_err_probe(cs48l32->dev, ret, "Unknown device ID: %#x\n", hwid);
3975 goto err_reset;
3976 }
3977
3978 ret = regmap_read(cs48l32->regmap, CS48L32_REVID, &rev);
3979 if (ret) {
3980 dev_err(dev, "Failed to read revision register: %d\n", ret);
3981 goto err_reset;
3982 }
3983 rev &= CS48L32_AREVID_MASK | CS48L32_MTLREVID_MASK;
3984
3985 ret = regmap_read(cs48l32->regmap, CS48L32_OTPID, &otp_rev);
3986 if (ret) {
3987 dev_err(dev, "Failed to read OTP revision register: %d\n", ret);
3988 goto err_reset;
3989 }
3990 otp_rev &= CS48L32_OTPID_MASK;
3991
3992 dev_info(dev, "CS48L%x revision %X%u OTP%u\n", hwid & 0xff,
3993 rev >> CS48L32_AREVID_SHIFT, rev & CS48L32_MTLREVID_MASK, otp_rev);
3994
3995 /* Apply hardware patch */
3996 ret = cs48l32_apply_patch(cs48l32);
3997 if (ret) {
3998 dev_err(cs48l32->dev, "Failed to apply patch %d\n", ret);
3999 goto err_reset;
4000 }
4001
4002 /* BOOT_DONE interrupt is unmasked by default, so mask it */
4003 ret = regmap_set_bits(cs48l32->regmap, CS48L32_IRQ1_MASK_2, CS48L32_BOOT_DONE_EINT1_MASK);
4004
4005 ret = cs48l32_configure_clk32k(cs48l32);
4006 if (ret)
4007 goto err_reset;
4008
4009 pm_runtime_set_active(cs48l32->dev);
4010 pm_runtime_set_autosuspend_delay(cs48l32->dev, 100);
4011 pm_runtime_use_autosuspend(cs48l32->dev);
4012 pm_runtime_enable(cs48l32->dev);
4013
4014 ret = cs48l32_create_codec_component(cs48l32_codec);
4015 if (ret)
4016 goto err_clk32k;
4017
4018 return 0;
4019
4020 err_clk32k:
4021 clk_disable_unprepare(cs48l32->mclk1);
4022 err_reset:
4023 cs48l32_enable_hard_reset(cs48l32);
4024 regulator_disable(cs48l32->vdd_d);
4025 err_enable:
4026 regulator_bulk_disable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies);
4027
4028 return ret;
4029 }
4030
cs48l32_spi_remove(struct spi_device * spi)4031 static void cs48l32_spi_remove(struct spi_device *spi)
4032 {
4033 struct cs48l32_codec *cs48l32_codec = spi_get_drvdata(spi);
4034 struct cs48l32 *cs48l32 = &cs48l32_codec->core;
4035
4036 /* Remove IRQ handler before destroying anything else */
4037 if (cs48l32->irq >= 1)
4038 free_irq(cs48l32->irq, cs48l32_codec);
4039
4040 pm_runtime_disable(cs48l32->dev);
4041 regulator_disable(cs48l32->vdd_d);
4042 clk_disable_unprepare(cs48l32->mclk1);
4043 cs48l32_enable_hard_reset(cs48l32);
4044 regulator_bulk_disable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies);
4045
4046 mutex_destroy(&cs48l32_codec->rate_lock);
4047 }
4048
4049 static const struct of_device_id cs48l32_of_match[] = {
4050 { .compatible = "cirrus,cs48l32", },
4051 {},
4052 };
4053
4054 static const struct spi_device_id cs48l32_spi_ids[] = {
4055 { "cs48l32", },
4056 { },
4057 };
4058 MODULE_DEVICE_TABLE(spi, cs48l32_spi_ids);
4059
4060 static struct spi_driver cs48l32_spi_driver = {
4061 .driver = {
4062 .name = "cs48l32",
4063 .pm = pm_ptr(&cs48l32_pm_ops),
4064 .of_match_table = cs48l32_of_match,
4065 },
4066 .probe = &cs48l32_spi_probe,
4067 .remove = &cs48l32_spi_remove,
4068 .id_table = cs48l32_spi_ids,
4069 };
4070 module_spi_driver(cs48l32_spi_driver);
4071
4072 MODULE_DESCRIPTION("CS48L32 ASoC codec driver");
4073 MODULE_AUTHOR("Stuart Henderson <stuarth@opensource.cirrus.com>");
4074 MODULE_AUTHOR("Piotr Stankiewicz <piotrs@opensource.cirrus.com>");
4075 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
4076 MODULE_LICENSE("GPL");
4077