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_mark_last_busy(cs48l32_codec->core.dev);
1389 pm_runtime_put_autosuspend(cs48l32_codec->core.dev);
1390
1391 return result;
1392 }
1393
cs48l32_get_dspclk_setting(struct cs48l32_codec * cs48l32_codec,unsigned int freq,int src,unsigned int * val)1394 static int cs48l32_get_dspclk_setting(struct cs48l32_codec *cs48l32_codec, unsigned int freq,
1395 int src, unsigned int *val)
1396 {
1397 freq /= 15625; /* convert to 1/64ths of 1MHz */
1398 *val |= freq << CS48L32_DSP_CLK_FREQ_SHIFT;
1399
1400 return 0;
1401 }
1402
cs48l32_get_sysclk_setting(unsigned int freq)1403 static int cs48l32_get_sysclk_setting(unsigned int freq)
1404 {
1405 switch (freq) {
1406 case 0:
1407 case 5644800:
1408 case 6144000:
1409 return CS48L32_SYSCLK_RATE_6MHZ;
1410 case 11289600:
1411 case 12288000:
1412 return CS48L32_SYSCLK_RATE_12MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1413 case 22579200:
1414 case 24576000:
1415 return CS48L32_SYSCLK_RATE_24MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1416 case 45158400:
1417 case 49152000:
1418 return CS48L32_SYSCLK_RATE_49MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1419 case 90316800:
1420 case 98304000:
1421 return CS48L32_SYSCLK_RATE_98MHZ << CS48L32_SYSCLK_FREQ_SHIFT;
1422 default:
1423 return -EINVAL;
1424 }
1425 }
1426
cs48l32_set_pdm_fllclk(struct snd_soc_component * component,int source)1427 static int cs48l32_set_pdm_fllclk(struct snd_soc_component *component, int source)
1428 {
1429 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1430 struct regmap *regmap = cs48l32_codec->core.regmap;
1431 unsigned int val;
1432
1433 switch (source) {
1434 case CS48L32_PDMCLK_SRC_IN1_PDMCLK:
1435 case CS48L32_PDMCLK_SRC_IN2_PDMCLK:
1436 case CS48L32_PDMCLK_SRC_IN3_PDMCLK:
1437 case CS48L32_PDMCLK_SRC_IN4_PDMCLK:
1438 case CS48L32_PDMCLK_SRC_AUXPDM1_CLK:
1439 case CS48L32_PDMCLK_SRC_AUXPDM2_CLK:
1440 val = source << CS48L32_PDM_FLLCLK_SRC_SHIFT;
1441 break;
1442 default:
1443 dev_err(cs48l32_codec->core.dev, "Invalid PDM FLLCLK src %d\n", source);
1444 return -EINVAL;
1445 }
1446
1447 return regmap_update_bits(regmap, CS48L32_INPUT_CONTROL2,
1448 CS48L32_PDM_FLLCLK_SRC_MASK, val);
1449 }
1450
cs48l32_set_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)1451 static int cs48l32_set_sysclk(struct snd_soc_component *component, int clk_id, int source,
1452 unsigned int freq, int dir)
1453 {
1454 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1455 struct regmap *regmap = cs48l32_codec->core.regmap;
1456 char *name;
1457 unsigned int reg;
1458 unsigned int mask = CS48L32_SYSCLK_SRC_MASK;
1459 unsigned int val = source << CS48L32_SYSCLK_SRC_SHIFT;
1460 int clk_freq_sel, *clk;
1461
1462 switch (clk_id) {
1463 case CS48L32_CLK_SYSCLK_1:
1464 name = "SYSCLK";
1465 reg = CS48L32_SYSTEM_CLOCK1;
1466 clk = &cs48l32_codec->sysclk;
1467 clk_freq_sel = cs48l32_get_sysclk_setting(freq);
1468 mask |= CS48L32_SYSCLK_FREQ_MASK | CS48L32_SYSCLK_FRAC_MASK;
1469 break;
1470 case CS48L32_CLK_DSPCLK:
1471 name = "DSPCLK";
1472 reg = CS48L32_DSP_CLOCK1;
1473 clk = &cs48l32_codec->dspclk;
1474 clk_freq_sel = cs48l32_get_dspclk_setting(cs48l32_codec, freq, source, &val);
1475 mask |= CS48L32_DSP_CLK_FREQ_MASK;
1476 break;
1477 case CS48L32_CLK_PDM_FLLCLK:
1478 return cs48l32_set_pdm_fllclk(component, source);
1479 default:
1480 return -EINVAL;
1481 }
1482
1483 if (clk_freq_sel < 0) {
1484 dev_err(cs48l32_codec->core.dev, "Failed to get %s setting for %dHZ\n", name, freq);
1485 return clk_freq_sel;
1486 }
1487
1488 *clk = freq;
1489
1490 if (freq == 0) {
1491 dev_dbg(cs48l32_codec->core.dev, "%s cleared\n", name);
1492 return 0;
1493 }
1494
1495 val |= clk_freq_sel;
1496
1497 if (freq % 6144000)
1498 val |= CS48L32_SYSCLK_FRAC_MASK;
1499
1500 dev_dbg(cs48l32_codec->core.dev, "%s set to %uHz", name, freq);
1501
1502 return regmap_update_bits(regmap, reg, mask, val);
1503 }
1504
cs48l32_is_enabled_fll(struct cs48l32_fll * fll,int base)1505 static int cs48l32_is_enabled_fll(struct cs48l32_fll *fll, int base)
1506 {
1507 struct regmap *regmap = fll->codec->core.regmap;
1508 unsigned int reg;
1509 int ret;
1510
1511 ret = regmap_read(regmap, base + CS48L32_FLL_CONTROL1_OFFS, ®);
1512 if (ret != 0) {
1513 cs48l32_fll_err(fll, "Failed to read current state: %d\n", ret);
1514 return ret;
1515 }
1516
1517 return reg & CS48L32_FLL_EN_MASK;
1518 }
1519
cs48l32_wait_for_fll(struct cs48l32_fll * fll,bool requested)1520 static int cs48l32_wait_for_fll(struct cs48l32_fll *fll, bool requested)
1521 {
1522 struct regmap *regmap = fll->codec->core.regmap;
1523 unsigned int val = 0;
1524 int i;
1525
1526 cs48l32_fll_dbg(fll, "Waiting for FLL...\n");
1527
1528 for (i = 0; i < 30; i++) {
1529 regmap_read(regmap, fll->sts_addr, &val);
1530 if (!!(val & fll->sts_mask) == requested)
1531 return 0;
1532
1533 switch (i) {
1534 case 0 ... 5:
1535 usleep_range(75, 125);
1536 break;
1537 case 6 ... 20:
1538 usleep_range(750, 1250);
1539 break;
1540 default:
1541 fsleep(20000);
1542 break;
1543 }
1544 }
1545
1546 cs48l32_fll_warn(fll, "Timed out waiting for %s\n", requested ? "lock" : "unlock");
1547
1548 return -ETIMEDOUT;
1549 }
1550
cs48l32_fllhj_disable(struct cs48l32_fll * fll)1551 static int cs48l32_fllhj_disable(struct cs48l32_fll *fll)
1552 {
1553 struct cs48l32 *cs48l32 = &fll->codec->core;
1554 bool change;
1555
1556 cs48l32_fll_dbg(fll, "Disabling FLL\n");
1557
1558 /*
1559 * Disable lockdet, but don't set ctrl_upd update bit. This allows the
1560 * lock status bit to clear as normal, but should the FLL be enabled
1561 * again due to a control clock being required, the lock won't re-assert
1562 * as the FLL config registers are automatically applied when the FLL
1563 * enables.
1564 */
1565 regmap_set_bits(cs48l32->regmap,
1566 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1567 CS48L32_FLL_HOLD_MASK);
1568 regmap_clear_bits(cs48l32->regmap,
1569 fll->base + CS48L32_FLL_CONTROL2_OFFS,
1570 CS48L32_FLL_LOCKDET_MASK);
1571 regmap_set_bits(cs48l32->regmap,
1572 fll->base + CS48L32_FLL_CONTROL5_OFFS,
1573 CS48L32_FLL_FRC_INTEG_UPD_MASK);
1574 regmap_update_bits_check(cs48l32->regmap,
1575 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1576 CS48L32_FLL_EN_MASK,
1577 0,
1578 &change);
1579
1580 cs48l32_wait_for_fll(fll, false);
1581
1582 /*
1583 * ctrl_up gates the writes to all the fll's registers, setting it to 0
1584 * here ensures that after a runtime suspend/resume cycle when one
1585 * enables the fll then ctrl_up is the last bit that is configured
1586 * by the fll enable code rather than the cache sync operation which
1587 * would have updated it much earlier before writing out all fll
1588 * registers
1589 */
1590 regmap_clear_bits(cs48l32->regmap,
1591 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1592 CS48L32_FLL_CTRL_UPD_MASK);
1593
1594 if (change)
1595 pm_runtime_put_autosuspend(cs48l32->dev);
1596
1597 return 0;
1598 }
1599
cs48l32_fllhj_apply(struct cs48l32_fll * fll,int fin)1600 static int cs48l32_fllhj_apply(struct cs48l32_fll *fll, int fin)
1601 {
1602 struct regmap *regmap = fll->codec->core.regmap;
1603 int refdiv, fref, fout, lockdet_thr, fbdiv, fllgcd;
1604 bool frac = false;
1605 unsigned int fll_n, min_n, max_n, ratio, theta, lambda, hp;
1606 unsigned int gains, num;
1607
1608 cs48l32_fll_dbg(fll, "fin=%d, fout=%d\n", fin, fll->fout);
1609
1610 for (refdiv = 0; refdiv < 4; refdiv++) {
1611 if ((fin / (1 << refdiv)) <= CS48L32_FLLHJ_MAX_THRESH)
1612 break;
1613 }
1614
1615 fref = fin / (1 << refdiv);
1616 fout = fll->fout;
1617 frac = fout % fref;
1618
1619 /*
1620 * Use simple heuristic approach to find a configuration that
1621 * should work for most input clocks.
1622 */
1623 if (fref < CS48L32_FLLHJ_LOW_THRESH) {
1624 lockdet_thr = 2;
1625 gains = CS48L32_FLLHJ_LOW_GAINS;
1626
1627 if (frac)
1628 fbdiv = 256;
1629 else
1630 fbdiv = 4;
1631 } else if (fref < CS48L32_FLLHJ_MID_THRESH) {
1632 lockdet_thr = 8;
1633 gains = CS48L32_FLLHJ_MID_GAINS;
1634 fbdiv = (frac) ? 16 : 2;
1635 } else {
1636 lockdet_thr = 8;
1637 gains = CS48L32_FLLHJ_HIGH_GAINS;
1638 fbdiv = 1;
1639 }
1640 /* Use high performance mode for fractional configurations. */
1641 if (frac) {
1642 hp = 3;
1643 min_n = CS48L32_FLLHJ_FRAC_MIN_N;
1644 max_n = CS48L32_FLLHJ_FRAC_MAX_N;
1645 } else {
1646 if (fref < CS48L32_FLLHJ_LP_INT_MODE_THRESH)
1647 hp = 0;
1648 else
1649 hp = 1;
1650
1651 min_n = CS48L32_FLLHJ_INT_MIN_N;
1652 max_n = CS48L32_FLLHJ_INT_MAX_N;
1653 }
1654
1655 ratio = fout / fref;
1656
1657 cs48l32_fll_dbg(fll, "refdiv=%d, fref=%d, frac:%d\n", refdiv, fref, frac);
1658
1659 while (ratio / fbdiv < min_n) {
1660 fbdiv /= 2;
1661 if (fbdiv < min_n) {
1662 cs48l32_fll_err(fll, "FBDIV (%u) < minimum N (%u)\n", fbdiv, min_n);
1663 return -EINVAL;
1664 }
1665 }
1666 while (frac && (ratio / fbdiv > max_n)) {
1667 fbdiv *= 2;
1668 if (fbdiv >= 1024) {
1669 cs48l32_fll_err(fll, "FBDIV (%u) >= 1024\n", fbdiv);
1670 return -EINVAL;
1671 }
1672 }
1673
1674 cs48l32_fll_dbg(fll, "lockdet=%d, hp=#%x, fbdiv:%d\n", lockdet_thr, hp, fbdiv);
1675
1676 /* Calculate N.K values */
1677 fllgcd = gcd(fout, fbdiv * fref);
1678 num = fout / fllgcd;
1679 lambda = (fref * fbdiv) / fllgcd;
1680 fll_n = num / lambda;
1681 theta = num % lambda;
1682
1683 cs48l32_fll_dbg(fll, "fll_n=%d, gcd=%d, theta=%d, lambda=%d\n",
1684 fll_n, fllgcd, theta, lambda);
1685
1686 /* Some sanity checks before any registers are written. */
1687 if (fll_n < min_n || fll_n > max_n) {
1688 cs48l32_fll_err(fll, "N not in valid %s mode range %d-%d: %d\n",
1689 frac ? "fractional" : "integer", min_n, max_n, fll_n);
1690 return -EINVAL;
1691 }
1692 if (fbdiv < 1 || (frac && fbdiv >= 1024) || (!frac && fbdiv >= 256)) {
1693 cs48l32_fll_err(fll, "Invalid fbdiv for %s mode (%u)\n",
1694 frac ? "fractional" : "integer", fbdiv);
1695 return -EINVAL;
1696 }
1697
1698 /* clear the ctrl_upd bit to guarantee we write to it later. */
1699 regmap_update_bits(regmap,
1700 fll->base + CS48L32_FLL_CONTROL2_OFFS,
1701 CS48L32_FLL_LOCKDET_THR_MASK |
1702 CS48L32_FLL_PHASEDET_MASK |
1703 CS48L32_FLL_REFCLK_DIV_MASK |
1704 CS48L32_FLL_N_MASK |
1705 CS48L32_FLL_CTRL_UPD_MASK,
1706 (lockdet_thr << CS48L32_FLL_LOCKDET_THR_SHIFT) |
1707 (1 << CS48L32_FLL_PHASEDET_SHIFT) |
1708 (refdiv << CS48L32_FLL_REFCLK_DIV_SHIFT) |
1709 (fll_n << CS48L32_FLL_N_SHIFT));
1710
1711 regmap_update_bits(regmap,
1712 fll->base + CS48L32_FLL_CONTROL3_OFFS,
1713 CS48L32_FLL_LAMBDA_MASK |
1714 CS48L32_FLL_THETA_MASK,
1715 (lambda << CS48L32_FLL_LAMBDA_SHIFT) |
1716 (theta << CS48L32_FLL_THETA_SHIFT));
1717
1718 regmap_update_bits(regmap,
1719 fll->base + CS48L32_FLL_CONTROL4_OFFS,
1720 (0xffff << CS48L32_FLL_FD_GAIN_COARSE_SHIFT) |
1721 CS48L32_FLL_HP_MASK |
1722 CS48L32_FLL_FB_DIV_MASK,
1723 (gains << CS48L32_FLL_FD_GAIN_COARSE_SHIFT) |
1724 (hp << CS48L32_FLL_HP_SHIFT) |
1725 (fbdiv << CS48L32_FLL_FB_DIV_SHIFT));
1726
1727 return 0;
1728 }
1729
cs48l32_fllhj_enable(struct cs48l32_fll * fll)1730 static int cs48l32_fllhj_enable(struct cs48l32_fll *fll)
1731 {
1732 struct cs48l32 *cs48l32 = &fll->codec->core;
1733 int already_enabled = cs48l32_is_enabled_fll(fll, fll->base);
1734 int ret;
1735
1736 if (already_enabled < 0)
1737 return already_enabled;
1738
1739 if (!already_enabled)
1740 pm_runtime_get_sync(cs48l32->dev);
1741
1742 cs48l32_fll_dbg(fll, "Enabling FLL, initially %s\n",
1743 str_enabled_disabled(already_enabled));
1744
1745 /* FLLn_HOLD must be set before configuring any registers */
1746 regmap_set_bits(cs48l32->regmap,
1747 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1748 CS48L32_FLL_HOLD_MASK);
1749
1750 /* Apply refclk */
1751 ret = cs48l32_fllhj_apply(fll, fll->ref_freq);
1752 if (ret) {
1753 cs48l32_fll_err(fll, "Failed to set FLL: %d\n", ret);
1754 goto out;
1755 }
1756 regmap_update_bits(cs48l32->regmap,
1757 fll->base + CS48L32_FLL_CONTROL2_OFFS,
1758 CS48L32_FLL_REFCLK_SRC_MASK,
1759 fll->ref_src << CS48L32_FLL_REFCLK_SRC_SHIFT);
1760
1761 regmap_set_bits(cs48l32->regmap,
1762 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1763 CS48L32_FLL_EN_MASK);
1764
1765 out:
1766 regmap_set_bits(cs48l32->regmap,
1767 fll->base + CS48L32_FLL_CONTROL2_OFFS,
1768 CS48L32_FLL_LOCKDET_MASK);
1769
1770 regmap_set_bits(cs48l32->regmap,
1771 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1772 CS48L32_FLL_CTRL_UPD_MASK);
1773
1774 /* Release the hold so that flln locks to external frequency */
1775 regmap_clear_bits(cs48l32->regmap,
1776 fll->base + CS48L32_FLL_CONTROL1_OFFS,
1777 CS48L32_FLL_HOLD_MASK);
1778
1779 if (!already_enabled)
1780 cs48l32_wait_for_fll(fll, true);
1781
1782 return 0;
1783 }
1784
cs48l32_fllhj_validate(struct cs48l32_fll * fll,unsigned int ref_in,unsigned int fout)1785 static int cs48l32_fllhj_validate(struct cs48l32_fll *fll,
1786 unsigned int ref_in,
1787 unsigned int fout)
1788 {
1789 if (fout && !ref_in) {
1790 cs48l32_fll_err(fll, "fllout set without valid input clk\n");
1791 return -EINVAL;
1792 }
1793
1794 if (fll->fout && fout != fll->fout) {
1795 cs48l32_fll_err(fll, "Can't change output on active FLL\n");
1796 return -EINVAL;
1797 }
1798
1799 if (ref_in / CS48L32_FLL_MAX_REFDIV > CS48L32_FLLHJ_MAX_THRESH) {
1800 cs48l32_fll_err(fll, "Can't scale %dMHz to <=13MHz\n", ref_in);
1801 return -EINVAL;
1802 }
1803
1804 if (fout > CS48L32_FLL_MAX_FOUT) {
1805 cs48l32_fll_err(fll, "Fout=%dMHz exceeds maximum %dMHz\n",
1806 fout, CS48L32_FLL_MAX_FOUT);
1807 return -EINVAL;
1808 }
1809
1810 return 0;
1811 }
1812
cs48l32_fllhj_set_refclk(struct cs48l32_fll * fll,int source,unsigned int fin,unsigned int fout)1813 static int cs48l32_fllhj_set_refclk(struct cs48l32_fll *fll, int source,
1814 unsigned int fin, unsigned int fout)
1815 {
1816 int ret = 0;
1817
1818 if (fll->ref_src == source && fll->ref_freq == fin && fll->fout == fout)
1819 return 0;
1820
1821 if (fin && fout && cs48l32_fllhj_validate(fll, fin, fout))
1822 return -EINVAL;
1823
1824 fll->ref_src = source;
1825 fll->ref_freq = fin;
1826 fll->fout = fout;
1827
1828 if (fout)
1829 ret = cs48l32_fllhj_enable(fll);
1830 else
1831 cs48l32_fllhj_disable(fll);
1832
1833 return ret;
1834 }
1835
cs48l32_init_fll(struct cs48l32_fll * fll)1836 static int cs48l32_init_fll(struct cs48l32_fll *fll)
1837 {
1838 fll->ref_src = CS48L32_FLL_SRC_NONE;
1839
1840 return 0;
1841 }
1842
cs48l32_set_fll(struct snd_soc_component * component,int fll_id,int source,unsigned int fref,unsigned int fout)1843 static int cs48l32_set_fll(struct snd_soc_component *component, int fll_id,
1844 int source, unsigned int fref, unsigned int fout)
1845 {
1846 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1847
1848 switch (fll_id) {
1849 case CS48L32_FLL1_REFCLK:
1850 break;
1851 default:
1852 return -EINVAL;
1853 }
1854
1855 return cs48l32_fllhj_set_refclk(&cs48l32_codec->fll, source, fref, fout);
1856 }
1857
cs48l32_asp_dai_probe(struct snd_soc_dai * dai)1858 static int cs48l32_asp_dai_probe(struct snd_soc_dai *dai)
1859 {
1860 struct snd_soc_component *component = dai->component;
1861 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1862 struct regmap *regmap = cs48l32_codec->core.regmap;
1863 unsigned int pin_reg, last_pin_reg, hiz_reg;
1864
1865 switch (dai->id) {
1866 case 1:
1867 pin_reg = CS48L32_GPIO3_CTRL1;
1868 hiz_reg = CS48L32_ASP1_CONTROL3;
1869 break;
1870 case 2:
1871 pin_reg = CS48L32_GPIO7_CTRL1;
1872 hiz_reg = CS48L32_ASP2_CONTROL3;
1873 break;
1874 default:
1875 return -EINVAL;
1876 }
1877
1878 for (last_pin_reg = pin_reg + 12; pin_reg <= last_pin_reg; ++pin_reg)
1879 regmap_clear_bits(regmap, pin_reg, CS48L32_GPIOX_CTRL1_FN_MASK);
1880
1881 /* DOUT high-impendance when not transmitting */
1882 regmap_set_bits(regmap, hiz_reg, CS48L32_ASP_DOUT_HIZ_MASK);
1883
1884 return 0;
1885 }
1886
cs48l32_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)1887 static int cs48l32_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1888 {
1889 struct snd_soc_component *component = dai->component;
1890 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
1891 struct regmap *regmap = cs48l32_codec->core.regmap;
1892 unsigned int val = 0U;
1893 unsigned int base = dai->driver->base;
1894 unsigned int mask = CS48L32_ASP_FMT_MASK | CS48L32_ASP_BCLK_INV_MASK |
1895 CS48L32_ASP_BCLK_MSTR_MASK |
1896 CS48L32_ASP_FSYNC_INV_MASK |
1897 CS48L32_ASP_FSYNC_MSTR_MASK;
1898
1899 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1900 case SND_SOC_DAIFMT_DSP_A:
1901 val |= (CS48L32_ASP_FMT_DSP_MODE_A << CS48L32_ASP_FMT_SHIFT);
1902 break;
1903 case SND_SOC_DAIFMT_DSP_B:
1904 if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_BP_FP) {
1905 cs48l32_asp_err(dai, "DSP_B cannot be clock consumer\n");
1906 return -EINVAL;
1907 }
1908 val |= (CS48L32_ASP_FMT_DSP_MODE_B << CS48L32_ASP_FMT_SHIFT);
1909 break;
1910 case SND_SOC_DAIFMT_I2S:
1911 val |= (CS48L32_ASP_FMT_I2S_MODE << CS48L32_ASP_FMT_SHIFT);
1912 break;
1913 case SND_SOC_DAIFMT_LEFT_J:
1914 if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_BP_FP) {
1915 cs48l32_asp_err(dai, "LEFT_J cannot be clock consumer\n");
1916 return -EINVAL;
1917 }
1918 val |= (CS48L32_ASP_FMT_LEFT_JUSTIFIED_MODE << CS48L32_ASP_FMT_SHIFT);
1919 break;
1920 default:
1921 cs48l32_asp_err(dai, "Unsupported DAI format %d\n",
1922 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1923 return -EINVAL;
1924 }
1925
1926 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
1927 case SND_SOC_DAIFMT_BC_FC:
1928 break;
1929 case SND_SOC_DAIFMT_BC_FP:
1930 val |= CS48L32_ASP_FSYNC_MSTR_MASK;
1931 break;
1932 case SND_SOC_DAIFMT_BP_FC:
1933 val |= CS48L32_ASP_BCLK_MSTR_MASK;
1934 break;
1935 case SND_SOC_DAIFMT_BP_FP:
1936 val |= CS48L32_ASP_BCLK_MSTR_MASK;
1937 val |= CS48L32_ASP_FSYNC_MSTR_MASK;
1938 break;
1939 default:
1940 cs48l32_asp_err(dai, "Unsupported clock direction %d\n",
1941 fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK);
1942 return -EINVAL;
1943 }
1944
1945 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1946 case SND_SOC_DAIFMT_NB_NF:
1947 break;
1948 case SND_SOC_DAIFMT_IB_IF:
1949 val |= CS48L32_ASP_BCLK_INV_MASK;
1950 val |= CS48L32_ASP_FSYNC_INV_MASK;
1951 break;
1952 case SND_SOC_DAIFMT_IB_NF:
1953 val |= CS48L32_ASP_BCLK_INV_MASK;
1954 break;
1955 case SND_SOC_DAIFMT_NB_IF:
1956 val |= CS48L32_ASP_FSYNC_INV_MASK;
1957 break;
1958 default:
1959 return -EINVAL;
1960 }
1961
1962 regmap_update_bits(regmap, base + CS48L32_ASP_CONTROL2, mask, val);
1963
1964 return 0;
1965 }
1966
1967 static const struct {
1968 u32 freq;
1969 u32 id;
1970 } cs48l32_sclk_rates[] = {
1971 { 128000, 12 },
1972 { 176400, 13 },
1973 { 192000, 14 },
1974 { 256000, 15 },
1975 { 352800, 16 },
1976 { 384000, 17 },
1977 { 512000, 18 },
1978 { 705600, 19 },
1979 { 768000, 21 },
1980 { 1024000, 23 },
1981 { 1411200, 25 },
1982 { 1536000, 27 },
1983 { 2048000, 29 },
1984 { 2822400, 31 },
1985 { 3072000, 33 },
1986 { 4096000, 36 },
1987 { 5644800, 38 },
1988 { 6144000, 40 },
1989 { 8192000, 47 },
1990 { 11289600, 49 },
1991 { 12288000, 51 },
1992 { 22579200, 57 },
1993 { 24576000, 59 },
1994 };
1995
1996 #define CS48L32_48K_RATE_MASK 0x0e00fe
1997 #define CS48L32_44K1_RATE_MASK 0x00fe00
1998 #define CS48L32_RATE_MASK (CS48L32_48K_RATE_MASK | CS48L32_44K1_RATE_MASK)
1999
2000 static const unsigned int cs48l32_sr_vals[] = {
2001 0,
2002 12000, /* CS48L32_48K_RATE_MASK */
2003 24000, /* CS48L32_48K_RATE_MASK */
2004 48000, /* CS48L32_48K_RATE_MASK */
2005 96000, /* CS48L32_48K_RATE_MASK */
2006 192000, /* CS48L32_48K_RATE_MASK */
2007 384000, /* CS48L32_48K_RATE_MASK */
2008 768000, /* CS48L32_48K_RATE_MASK */
2009 0,
2010 11025, /* CS48L32_44K1_RATE_MASK */
2011 22050, /* CS48L32_44K1_RATE_MASK */
2012 44100, /* CS48L32_44K1_RATE_MASK */
2013 88200, /* CS48L32_44K1_RATE_MASK */
2014 176400, /* CS48L32_44K1_RATE_MASK */
2015 352800, /* CS48L32_44K1_RATE_MASK */
2016 705600, /* CS48L32_44K1_RATE_MASK */
2017 0,
2018 8000, /* CS48L32_48K_RATE_MASK */
2019 16000, /* CS48L32_48K_RATE_MASK */
2020 32000, /* CS48L32_48K_RATE_MASK */
2021 };
2022
2023 static const struct snd_pcm_hw_constraint_list cs48l32_constraint = {
2024 .count = ARRAY_SIZE(cs48l32_sr_vals),
2025 .list = cs48l32_sr_vals,
2026 };
2027
cs48l32_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)2028 static int cs48l32_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
2029 {
2030 struct snd_soc_component *component = dai->component;
2031 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2032 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1];
2033 unsigned int base_rate;
2034
2035 if (!substream->runtime)
2036 return 0;
2037
2038 switch (dai_priv->clk) {
2039 case CS48L32_CLK_SYSCLK_1:
2040 case CS48L32_CLK_SYSCLK_2:
2041 case CS48L32_CLK_SYSCLK_3:
2042 case CS48L32_CLK_SYSCLK_4:
2043 base_rate = cs48l32_codec->sysclk;
2044 break;
2045 default:
2046 return 0;
2047 }
2048
2049 if (base_rate == 0)
2050 dai_priv->constraint.mask = CS48L32_RATE_MASK;
2051 else if (base_rate % 4000)
2052 dai_priv->constraint.mask = CS48L32_44K1_RATE_MASK;
2053 else
2054 dai_priv->constraint.mask = CS48L32_48K_RATE_MASK;
2055
2056 return snd_pcm_hw_constraint_list(substream->runtime, 0,
2057 SNDRV_PCM_HW_PARAM_RATE,
2058 &dai_priv->constraint);
2059 }
2060
cs48l32_hw_params_rate(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)2061 static int cs48l32_hw_params_rate(struct snd_pcm_substream *substream,
2062 struct snd_pcm_hw_params *params,
2063 struct snd_soc_dai *dai)
2064 {
2065 struct snd_soc_component *component = dai->component;
2066 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2067 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1];
2068 unsigned int sr_val, sr_reg, rate;
2069
2070 rate = params_rate(params);
2071 for (sr_val = 0; sr_val < ARRAY_SIZE(cs48l32_sr_vals); sr_val++)
2072 if (cs48l32_sr_vals[sr_val] == rate)
2073 break;
2074
2075 if (sr_val == ARRAY_SIZE(cs48l32_sr_vals)) {
2076 cs48l32_asp_err(dai, "Unsupported sample rate %dHz\n", rate);
2077 return -EINVAL;
2078 }
2079
2080 switch (dai_priv->clk) {
2081 case CS48L32_CLK_SYSCLK_1:
2082 sr_reg = CS48L32_SAMPLE_RATE1;
2083 break;
2084 case CS48L32_CLK_SYSCLK_2:
2085 sr_reg = CS48L32_SAMPLE_RATE2;
2086 break;
2087 case CS48L32_CLK_SYSCLK_3:
2088 sr_reg = CS48L32_SAMPLE_RATE3;
2089 break;
2090 case CS48L32_CLK_SYSCLK_4:
2091 sr_reg = CS48L32_SAMPLE_RATE4;
2092 break;
2093 default:
2094 return -EINVAL;
2095 }
2096
2097 snd_soc_component_update_bits(component, sr_reg, CS48L32_SAMPLE_RATE_1_MASK, sr_val);
2098
2099 return 0;
2100 }
2101
cs48l32_asp_cfg_changed(struct snd_soc_component * component,unsigned int base,unsigned int sclk,unsigned int slotws,unsigned int dataw)2102 static bool cs48l32_asp_cfg_changed(struct snd_soc_component *component,
2103 unsigned int base, unsigned int sclk,
2104 unsigned int slotws, unsigned int dataw)
2105 {
2106 unsigned int val;
2107
2108 val = snd_soc_component_read(component, base + CS48L32_ASP_CONTROL1);
2109 if (sclk != (val & CS48L32_ASP_BCLK_FREQ_MASK))
2110 return true;
2111
2112 val = snd_soc_component_read(component, base + CS48L32_ASP_CONTROL2);
2113 if (slotws != (val & (CS48L32_ASP_RX_WIDTH_MASK | CS48L32_ASP_TX_WIDTH_MASK)))
2114 return true;
2115
2116 val = snd_soc_component_read(component, base + CS48L32_ASP_DATA_CONTROL1);
2117 if (dataw != (val & (CS48L32_ASP_TX_WL_MASK)))
2118 return true;
2119
2120 val = snd_soc_component_read(component, base + CS48L32_ASP_DATA_CONTROL5);
2121 if (dataw != (val & (CS48L32_ASP_RX_WL_MASK)))
2122 return true;
2123
2124 return false;
2125 }
2126
cs48l32_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)2127 static int cs48l32_hw_params(struct snd_pcm_substream *substream,
2128 struct snd_pcm_hw_params *params,
2129 struct snd_soc_dai *dai)
2130 {
2131 struct snd_soc_component *component = dai->component;
2132 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2133 struct regmap *regmap = cs48l32_codec->core.regmap;
2134 int base = dai->driver->base;
2135 int dai_id = dai->id - 1;
2136 unsigned int rate = params_rate(params);
2137 unsigned int dataw = snd_pcm_format_width(params_format(params));
2138 unsigned int asp_state = 0;
2139 int sclk, sclk_target;
2140 unsigned int slotw, n_slots, n_slots_multiple, val;
2141 int i, ret;
2142
2143 cs48l32_asp_dbg(dai, "hwparams in: ch:%u dataw:%u rate:%u\n",
2144 params_channels(params), dataw, rate);
2145 /*
2146 * The following calculations hold only under the assumption that
2147 * symmetric_[rates|channels|samplebits] are set to 1
2148 */
2149 if (cs48l32_codec->tdm_slots[dai_id]) {
2150 n_slots = cs48l32_codec->tdm_slots[dai_id];
2151 slotw = cs48l32_codec->tdm_width[dai_id];
2152 } else {
2153 n_slots = params_channels(params);
2154 slotw = dataw;
2155 }
2156
2157 val = snd_soc_component_read(component, base + CS48L32_ASP_CONTROL2);
2158 val = (val & CS48L32_ASP_FMT_MASK) >> CS48L32_ASP_FMT_SHIFT;
2159 if (val == CS48L32_ASP_FMT_I2S_MODE)
2160 n_slots_multiple = 2;
2161 else
2162 n_slots_multiple = 1;
2163
2164 sclk_target = snd_soc_tdm_params_to_bclk(params, slotw, n_slots, n_slots_multiple);
2165 if (sclk_target < 0) {
2166 cs48l32_asp_err(dai, "Invalid parameters\n");
2167 return sclk_target;
2168 }
2169
2170 for (i = 0; i < ARRAY_SIZE(cs48l32_sclk_rates); i++) {
2171 if ((cs48l32_sclk_rates[i].freq >= sclk_target) &&
2172 (cs48l32_sclk_rates[i].freq % rate == 0)) {
2173 sclk = cs48l32_sclk_rates[i].id;
2174 break;
2175 }
2176 }
2177 if (i == ARRAY_SIZE(cs48l32_sclk_rates)) {
2178 cs48l32_asp_err(dai, "Unsupported sample rate %dHz\n", rate);
2179 return -EINVAL;
2180 }
2181
2182 cs48l32_asp_dbg(dai, "hwparams out: n_slots:%u dataw:%u slotw:%u bclk:%u bclkid:%u\n",
2183 n_slots, dataw, slotw, sclk_target, sclk);
2184
2185 slotw = (slotw << CS48L32_ASP_TX_WIDTH_SHIFT) |
2186 (slotw << CS48L32_ASP_RX_WIDTH_SHIFT);
2187
2188 if (!cs48l32_asp_cfg_changed(component, base, sclk, slotw, dataw))
2189 return cs48l32_hw_params_rate(substream, params, dai);
2190
2191 /* ASP must be disabled while changing configuration */
2192 asp_state = snd_soc_component_read(component, base + CS48L32_ASP_ENABLES1);
2193 regmap_clear_bits(regmap, base + CS48L32_ASP_ENABLES1, 0xff00ff);
2194
2195 ret = cs48l32_hw_params_rate(substream, params, dai);
2196 if (ret != 0)
2197 goto restore_asp;
2198
2199 regmap_update_bits_async(regmap,
2200 base + CS48L32_ASP_CONTROL1,
2201 CS48L32_ASP_BCLK_FREQ_MASK,
2202 sclk);
2203 regmap_update_bits_async(regmap,
2204 base + CS48L32_ASP_CONTROL2,
2205 CS48L32_ASP_RX_WIDTH_MASK | CS48L32_ASP_TX_WIDTH_MASK,
2206 slotw);
2207 regmap_update_bits_async(regmap,
2208 base + CS48L32_ASP_DATA_CONTROL1,
2209 CS48L32_ASP_TX_WL_MASK,
2210 dataw);
2211 regmap_update_bits(regmap,
2212 base + CS48L32_ASP_DATA_CONTROL5,
2213 CS48L32_ASP_RX_WL_MASK,
2214 dataw);
2215
2216 restore_asp:
2217 /* Restore ASP TX/RX enable state */
2218 regmap_update_bits(regmap,
2219 base + CS48L32_ASP_ENABLES1,
2220 0xff00ff,
2221 asp_state);
2222 return ret;
2223 }
2224
cs48l32_dai_clk_str(int clk_id)2225 static const char *cs48l32_dai_clk_str(int clk_id)
2226 {
2227 switch (clk_id) {
2228 case CS48L32_CLK_SYSCLK_1:
2229 case CS48L32_CLK_SYSCLK_2:
2230 case CS48L32_CLK_SYSCLK_3:
2231 case CS48L32_CLK_SYSCLK_4:
2232 return "SYSCLK";
2233 default:
2234 return "Unknown clock";
2235 }
2236 }
2237
cs48l32_dai_set_sysclk(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)2238 static int cs48l32_dai_set_sysclk(struct snd_soc_dai *dai,
2239 int clk_id, unsigned int freq, int dir)
2240 {
2241 struct snd_soc_component *component = dai->component;
2242 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2243 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[dai->id - 1];
2244 unsigned int base = dai->driver->base;
2245 unsigned int current_asp_rate, target_asp_rate;
2246 bool change_rate_domain = false;
2247 int ret;
2248
2249 if (clk_id == dai_priv->clk)
2250 return 0;
2251
2252 if (snd_soc_dai_active(dai)) {
2253 cs48l32_asp_err(dai, "Can't change clock on active DAI\n");
2254 return -EBUSY;
2255 }
2256
2257 switch (clk_id) {
2258 case CS48L32_CLK_SYSCLK_1:
2259 target_asp_rate = 0U << CS48L32_ASP_RATE_SHIFT;
2260 break;
2261 case CS48L32_CLK_SYSCLK_2:
2262 target_asp_rate = 1U << CS48L32_ASP_RATE_SHIFT;
2263 break;
2264 case CS48L32_CLK_SYSCLK_3:
2265 target_asp_rate = 2U << CS48L32_ASP_RATE_SHIFT;
2266 break;
2267 case CS48L32_CLK_SYSCLK_4:
2268 target_asp_rate = 3U << CS48L32_ASP_RATE_SHIFT;
2269 break;
2270 default:
2271 return -EINVAL;
2272 }
2273
2274 dai_priv->clk = clk_id;
2275 cs48l32_asp_dbg(dai, "Setting to %s\n", cs48l32_dai_clk_str(clk_id));
2276
2277 if (base) {
2278 ret = regmap_read(cs48l32_codec->core.regmap,
2279 base + CS48L32_ASP_CONTROL1,
2280 ¤t_asp_rate);
2281 if (ret != 0) {
2282 cs48l32_asp_err(dai, "Failed to check rate: %d\n", ret);
2283 return ret;
2284 }
2285
2286 if ((current_asp_rate & CS48L32_ASP_RATE_MASK) !=
2287 (target_asp_rate & CS48L32_ASP_RATE_MASK)) {
2288 change_rate_domain = true;
2289
2290 mutex_lock(&cs48l32_codec->rate_lock);
2291 /* Guard the rate change with SYSCLK cycles */
2292 cs48l32_spin_sysclk(cs48l32_codec);
2293 }
2294
2295 snd_soc_component_update_bits(component, base + CS48L32_ASP_CONTROL1,
2296 CS48L32_ASP_RATE_MASK, target_asp_rate);
2297
2298 if (change_rate_domain) {
2299 cs48l32_spin_sysclk(cs48l32_codec);
2300 mutex_unlock(&cs48l32_codec->rate_lock);
2301 }
2302 }
2303
2304 return 0;
2305 }
2306
cs48l32_set_channels_to_mask(struct snd_soc_dai * dai,unsigned int base,int channels,unsigned int mask)2307 static void cs48l32_set_channels_to_mask(struct snd_soc_dai *dai,
2308 unsigned int base,
2309 int channels, unsigned int mask)
2310 {
2311 struct snd_soc_component *component = dai->component;
2312 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2313 struct regmap *regmap = cs48l32_codec->core.regmap;
2314 int slot, i, j = 0, shift;
2315 unsigned int frame_ctls[2] = {0, 0};
2316
2317 for (i = 0; i < channels; ++i) {
2318 slot = ffs(mask) - 1;
2319 if (slot < 0)
2320 return;
2321
2322 if (i - (j * 4) >= 4) {
2323 ++j;
2324 if (j >= 2)
2325 break;
2326 }
2327
2328 shift = (8 * (i - j * 4));
2329
2330 frame_ctls[j] |= slot << shift;
2331
2332 mask &= ~(1 << slot); /* ? mask ^= 1 << slot ? */
2333 }
2334
2335 regmap_write(regmap, base, frame_ctls[0]);
2336 regmap_write(regmap, base + 0x4, frame_ctls[1]);
2337
2338 if (mask)
2339 cs48l32_asp_warn(dai, "Too many channels in TDM mask\n");
2340 }
2341
cs48l32_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)2342 static int cs48l32_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
2343 unsigned int rx_mask, int slots, int slot_width)
2344 {
2345 struct snd_soc_component *component = dai->component;
2346 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2347 int base = dai->driver->base;
2348 int rx_max_chan = dai->driver->playback.channels_max;
2349 int tx_max_chan = dai->driver->capture.channels_max;
2350
2351 /* Only support TDM for the physical ASPs */
2352 if (dai->id > CS48L32_MAX_ASP)
2353 return -EINVAL;
2354
2355 if (slots == 0) {
2356 tx_mask = (1 << tx_max_chan) - 1;
2357 rx_mask = (1 << rx_max_chan) - 1;
2358 }
2359
2360 cs48l32_set_channels_to_mask(dai, base + CS48L32_ASP_FRAME_CONTROL1,
2361 tx_max_chan, tx_mask);
2362 cs48l32_set_channels_to_mask(dai, base + CS48L32_ASP_FRAME_CONTROL5,
2363 rx_max_chan, rx_mask);
2364
2365 cs48l32_codec->tdm_width[dai->id - 1] = slot_width;
2366 cs48l32_codec->tdm_slots[dai->id - 1] = slots;
2367
2368 return 0;
2369 }
2370
2371 static const struct snd_soc_dai_ops cs48l32_dai_ops = {
2372 .probe = &cs48l32_asp_dai_probe,
2373 .startup = &cs48l32_startup,
2374 .set_fmt = &cs48l32_set_fmt,
2375 .set_tdm_slot = &cs48l32_set_tdm_slot,
2376 .hw_params = &cs48l32_hw_params,
2377 .set_sysclk = &cs48l32_dai_set_sysclk,
2378 };
2379
cs48l32_sysclk_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)2380 static int cs48l32_sysclk_ev(struct snd_soc_dapm_widget *w,
2381 struct snd_kcontrol *kcontrol, int event)
2382 {
2383 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2384 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2385
2386 cs48l32_spin_sysclk(cs48l32_codec);
2387
2388 return 0;
2389 }
2390
cs48l32_in_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)2391 static int cs48l32_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event)
2392 {
2393 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2394 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2395 unsigned int reg;
2396
2397 if (w->shift % 2)
2398 reg = CS48L32_IN1L_CONTROL2;
2399 else
2400 reg = CS48L32_IN1R_CONTROL2;
2401
2402 reg += (w->shift / 2) * (CS48L32_IN2L_CONTROL2 - CS48L32_IN1L_CONTROL2);
2403
2404 switch (event) {
2405 case SND_SOC_DAPM_PRE_PMU:
2406 switch (w->shift) {
2407 case CS48L32_IN1L_EN_SHIFT:
2408 snd_soc_component_update_bits(component,
2409 CS48L32_ADC1L_ANA_CONTROL1,
2410 CS48L32_ADC1x_INT_ENA_FRC_MASK,
2411 CS48L32_ADC1x_INT_ENA_FRC_MASK);
2412 break;
2413 case CS48L32_IN1R_EN_SHIFT:
2414 snd_soc_component_update_bits(component,
2415 CS48L32_ADC1R_ANA_CONTROL1,
2416 CS48L32_ADC1x_INT_ENA_FRC_MASK,
2417 CS48L32_ADC1x_INT_ENA_FRC_MASK);
2418 break;
2419 default:
2420 break;
2421 }
2422 cs48l32_codec->in_up_pending++;
2423 break;
2424 case SND_SOC_DAPM_POST_PMU:
2425 usleep_range(200, 300);
2426
2427 switch (w->shift) {
2428 case CS48L32_IN1L_EN_SHIFT:
2429 snd_soc_component_update_bits(component,
2430 CS48L32_ADC1L_ANA_CONTROL1,
2431 CS48L32_ADC1x_INT_ENA_FRC_MASK,
2432 0);
2433 break;
2434 case CS48L32_IN1R_EN_SHIFT:
2435 snd_soc_component_update_bits(component,
2436 CS48L32_ADC1R_ANA_CONTROL1,
2437 CS48L32_ADC1x_INT_ENA_FRC_MASK,
2438 0);
2439 break;
2440
2441 default:
2442 break;
2443 }
2444 cs48l32_codec->in_up_pending--;
2445 snd_soc_component_update_bits(component, reg, CS48L32_INx_MUTE_MASK, 0);
2446
2447 /* Uncached write-only register, no need for update_bits */
2448 if (!cs48l32_codec->in_up_pending) {
2449 snd_soc_component_write(component, cs48l32_codec->in_vu_reg,
2450 CS48L32_IN_VU_MASK);
2451 }
2452 break;
2453 case SND_SOC_DAPM_PRE_PMD:
2454 snd_soc_component_update_bits(component, reg,
2455 CS48L32_INx_MUTE_MASK, CS48L32_INx_MUTE_MASK);
2456 snd_soc_component_write(component, cs48l32_codec->in_vu_reg,
2457 CS48L32_IN_VU_MASK);
2458 break;
2459 default:
2460 break;
2461 }
2462
2463 return 0;
2464 }
2465
cs48l32_in_put_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2466 static int cs48l32_in_put_volsw(struct snd_kcontrol *kcontrol,
2467 struct snd_ctl_elem_value *ucontrol)
2468 {
2469 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2470 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2471 int ret;
2472
2473 ret = snd_soc_put_volsw(kcontrol, ucontrol);
2474 if (ret < 0)
2475 return ret;
2476
2477 /*
2478 * Uncached write-only register, no need for update_bits.
2479 * Will fail if codec is off but that will be handled by cs48l32_in_ev
2480 */
2481 snd_soc_component_write(component, cs48l32_codec->in_vu_reg, CS48L32_IN_VU);
2482
2483 return ret;
2484 }
2485
cs48l32_eq_filter_unstable(bool mode,__be16 in_a,__be16 in_b)2486 static bool cs48l32_eq_filter_unstable(bool mode, __be16 in_a, __be16 in_b)
2487 {
2488 s16 a = be16_to_cpu(in_a);
2489 s16 b = be16_to_cpu(in_b);
2490
2491 if (!mode)
2492 return abs(a) > CS48L32_EQ_MAX_COEFF;
2493
2494 if (abs(b) > CS48L32_EQ_MAX_COEFF)
2495 return true;
2496
2497 if (abs((a << 16) / (CS48L32_EQ_MAX_COEFF + 1 - b)) >= ((CS48L32_EQ_MAX_COEFF + 1) << 4))
2498 return true;
2499
2500 return false;
2501 }
2502
cs48l32_eq_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)2503 static int cs48l32_eq_ev(struct snd_soc_dapm_widget *w,
2504 struct snd_kcontrol *kcontrol, int event)
2505 {
2506 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2507 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2508 struct regmap *regmap = cs48l32_codec->core.regmap;
2509 unsigned int mode = cs48l32_codec->eq_mode[w->shift];
2510 unsigned int reg;
2511 __be16 *data = &cs48l32_codec->eq_coefficients[w->shift][0];
2512 int ret = 0;
2513
2514 reg = CS48L32_EQ1_BAND1_COEFF1;
2515 reg += w->shift * (CS48L32_EQ2_BAND1_COEFF1 - CS48L32_EQ1_BAND1_COEFF1);
2516
2517 switch (event) {
2518 case SND_SOC_DAPM_PRE_PMU:
2519 if (cs48l32_eq_filter_unstable(!!mode, data[1], data[0]) ||
2520 cs48l32_eq_filter_unstable(true, data[7], data[6]) ||
2521 cs48l32_eq_filter_unstable(true, data[13], data[12]) ||
2522 cs48l32_eq_filter_unstable(true, data[19], data[18]) ||
2523 cs48l32_eq_filter_unstable(false, data[25], data[24])) {
2524 dev_err(cs48l32_codec->core.dev, "Rejecting unstable EQ coefficients.\n");
2525 ret = -EINVAL;
2526 } else {
2527 ret = regmap_raw_write(regmap, reg, data, CS48L32_EQ_BLOCK_SZ);
2528 if (ret < 0) {
2529 dev_err(cs48l32_codec->core.dev,
2530 "Error writing EQ coefficients: %d\n", ret);
2531 goto out;
2532 }
2533
2534 ret = snd_soc_component_update_bits(component,
2535 CS48L32_EQ_CONTROL2,
2536 w->mask,
2537 mode << w->shift);
2538 if (ret < 0) {
2539 dev_err(cs48l32_codec->core.dev,
2540 "Error writing EQ mode: %d\n", ret);
2541 }
2542 }
2543 break;
2544 default:
2545 break;
2546 }
2547
2548 out:
2549 return ret;
2550 }
2551
2552 static const struct snd_kcontrol_new cs48l32_snd_controls[] = {
2553 SOC_ENUM("IN1 OSR", cs48l32_in_dmic_osr[0]),
2554 SOC_ENUM("IN2 OSR", cs48l32_in_dmic_osr[1]),
2555
2556 SOC_SINGLE_RANGE_TLV("IN1L Volume", CS48L32_IN1L_CONTROL2,
2557 CS48L32_INx_PGA_VOL_SHIFT, 0x40, 0x5f, 0, cs48l32_ana_tlv),
2558 SOC_SINGLE_RANGE_TLV("IN1R Volume", CS48L32_IN1R_CONTROL2,
2559 CS48L32_INx_PGA_VOL_SHIFT, 0x40, 0x5f, 0, cs48l32_ana_tlv),
2560
2561 SOC_ENUM("IN HPF Cutoff Frequency", cs48l32_in_hpf_cut_enum),
2562
2563 SOC_SINGLE_EXT("IN1L LP Switch", CS48L32_IN1L_CONTROL1, CS48L32_INx_LP_MODE_SHIFT,
2564 1, 0, snd_soc_get_volsw, cs48l32_low_power_mode_put),
2565 SOC_SINGLE_EXT("IN1R LP Switch", CS48L32_IN1R_CONTROL1, CS48L32_INx_LP_MODE_SHIFT,
2566 1, 0, snd_soc_get_volsw, cs48l32_low_power_mode_put),
2567
2568 SOC_SINGLE("IN1L HPF Switch", CS48L32_IN1L_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2569 SOC_SINGLE("IN1R HPF Switch", CS48L32_IN1R_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2570 SOC_SINGLE("IN2L HPF Switch", CS48L32_IN2L_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2571 SOC_SINGLE("IN2R HPF Switch", CS48L32_IN2R_CONTROL1, CS48L32_INx_HPF_SHIFT, 1, 0),
2572
2573 SOC_SINGLE_EXT_TLV("IN1L Digital Volume", CS48L32_IN1L_CONTROL2,
2574 CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2575 cs48l32_in_put_volsw, cs48l32_digital_tlv),
2576 SOC_SINGLE_EXT_TLV("IN1R Digital Volume", CS48L32_IN1R_CONTROL2,
2577 CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2578 cs48l32_in_put_volsw, cs48l32_digital_tlv),
2579 SOC_SINGLE_EXT_TLV("IN2L Digital Volume", CS48L32_IN2L_CONTROL2,
2580 CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2581 cs48l32_in_put_volsw, cs48l32_digital_tlv),
2582 SOC_SINGLE_EXT_TLV("IN2R Digital Volume", CS48L32_IN2R_CONTROL2,
2583 CS48L32_INx_VOL_SHIFT, 0xbf, 0, snd_soc_get_volsw,
2584 cs48l32_in_put_volsw, cs48l32_digital_tlv),
2585
2586 SOC_ENUM("Input Ramp Up", cs48l32_in_vi_ramp),
2587 SOC_ENUM("Input Ramp Down", cs48l32_in_vd_ramp),
2588
2589 CS48L32_RATE_ENUM("Ultrasonic 1 Rate", cs48l32_us_output_rate[0]),
2590 CS48L32_RATE_ENUM("Ultrasonic 2 Rate", cs48l32_us_output_rate[1]),
2591
2592 SOC_ENUM("Ultrasonic 1 Freq", cs48l32_us_freq[0]),
2593 SOC_ENUM("Ultrasonic 2 Freq", cs48l32_us_freq[1]),
2594
2595 SOC_SINGLE_TLV("Ultrasonic 1 Volume", CS48L32_US1_CONTROL, CS48L32_US1_GAIN_SHIFT,
2596 3, 0, cs48l32_us_tlv),
2597 SOC_SINGLE_TLV("Ultrasonic 2 Volume", CS48L32_US2_CONTROL, CS48L32_US1_GAIN_SHIFT,
2598 3, 0, cs48l32_us_tlv),
2599
2600 SOC_ENUM("Ultrasonic 1 Detect Threshold", cs48l32_us_det_thr[0]),
2601 SOC_ENUM("Ultrasonic 2 Detect Threshold", cs48l32_us_det_thr[1]),
2602
2603 SOC_ENUM("Ultrasonic 1 Detect Pulse Length", cs48l32_us_det_num[0]),
2604 SOC_ENUM("Ultrasonic 2 Detect Pulse Length", cs48l32_us_det_num[1]),
2605
2606 SOC_ENUM("Ultrasonic 1 Detect Hold", cs48l32_us_det_hold[0]),
2607 SOC_ENUM("Ultrasonic 2 Detect Hold", cs48l32_us_det_hold[1]),
2608
2609 SOC_ENUM("Ultrasonic 1 Detect Decay", cs48l32_us_det_dcy[0]),
2610 SOC_ENUM("Ultrasonic 2 Detect Decay", cs48l32_us_det_dcy[1]),
2611
2612 SOC_SINGLE("Ultrasonic 1 Detect LPF Switch",
2613 CS48L32_US1_DET_CONTROL, CS48L32_US1_DET_LPF_SHIFT, 1, 0),
2614 SOC_SINGLE("Ultrasonic 2 Detect LPF Switch",
2615 CS48L32_US2_DET_CONTROL, CS48L32_US1_DET_LPF_SHIFT, 1, 0),
2616
2617 SOC_ENUM("Ultrasonic 1 Detect LPF Cut-off", cs48l32_us_det_lpf_cut[0]),
2618 SOC_ENUM("Ultrasonic 2 Detect LPF Cut-off", cs48l32_us_det_lpf_cut[1]),
2619
2620 CS48L32_MIXER_CONTROLS("EQ1", CS48L32_EQ1_INPUT1),
2621 CS48L32_MIXER_CONTROLS("EQ2", CS48L32_EQ2_INPUT1),
2622 CS48L32_MIXER_CONTROLS("EQ3", CS48L32_EQ3_INPUT1),
2623 CS48L32_MIXER_CONTROLS("EQ4", CS48L32_EQ4_INPUT1),
2624
2625 SOC_ENUM_EXT("EQ1 Mode", cs48l32_eq_mode[0], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2626
2627 CS48L32_EQ_COEFF_CONTROLS(EQ1),
2628
2629 SOC_SINGLE_TLV("EQ1 B1 Volume", CS48L32_EQ1_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2630 SOC_SINGLE_TLV("EQ1 B2 Volume", CS48L32_EQ1_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2631 SOC_SINGLE_TLV("EQ1 B3 Volume", CS48L32_EQ1_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2632 SOC_SINGLE_TLV("EQ1 B4 Volume", CS48L32_EQ1_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2633 SOC_SINGLE_TLV("EQ1 B5 Volume", CS48L32_EQ1_GAIN2, 0, 24, 0, cs48l32_eq_tlv),
2634
2635 SOC_ENUM_EXT("EQ2 Mode", cs48l32_eq_mode[1], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2636 CS48L32_EQ_COEFF_CONTROLS(EQ2),
2637 SOC_SINGLE_TLV("EQ2 B1 Volume", CS48L32_EQ2_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2638 SOC_SINGLE_TLV("EQ2 B2 Volume", CS48L32_EQ2_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2639 SOC_SINGLE_TLV("EQ2 B3 Volume", CS48L32_EQ2_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2640 SOC_SINGLE_TLV("EQ2 B4 Volume", CS48L32_EQ2_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2641 SOC_SINGLE_TLV("EQ2 B5 Volume", CS48L32_EQ2_GAIN2, 0, 24, 0, cs48l32_eq_tlv),
2642
2643 SOC_ENUM_EXT("EQ3 Mode", cs48l32_eq_mode[2], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2644 CS48L32_EQ_COEFF_CONTROLS(EQ3),
2645 SOC_SINGLE_TLV("EQ3 B1 Volume", CS48L32_EQ3_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2646 SOC_SINGLE_TLV("EQ3 B2 Volume", CS48L32_EQ3_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2647 SOC_SINGLE_TLV("EQ3 B3 Volume", CS48L32_EQ3_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2648 SOC_SINGLE_TLV("EQ3 B4 Volume", CS48L32_EQ3_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2649 SOC_SINGLE_TLV("EQ3 B5 Volume", CS48L32_EQ3_GAIN2, 0, 24, 0, cs48l32_eq_tlv),
2650
2651 SOC_ENUM_EXT("EQ4 Mode", cs48l32_eq_mode[3], cs48l32_eq_mode_get, cs48l32_eq_mode_put),
2652 CS48L32_EQ_COEFF_CONTROLS(EQ4),
2653 SOC_SINGLE_TLV("EQ4 B1 Volume", CS48L32_EQ4_GAIN1, 0, 24, 0, cs48l32_eq_tlv),
2654 SOC_SINGLE_TLV("EQ4 B2 Volume", CS48L32_EQ4_GAIN1, 8, 24, 0, cs48l32_eq_tlv),
2655 SOC_SINGLE_TLV("EQ4 B3 Volume", CS48L32_EQ4_GAIN1, 16, 24, 0, cs48l32_eq_tlv),
2656 SOC_SINGLE_TLV("EQ4 B4 Volume", CS48L32_EQ4_GAIN1, 24, 24, 0, cs48l32_eq_tlv),
2657 SOC_SINGLE_TLV("EQ4 B5 Volume", CS48L32_EQ4_GAIN2, 0, 24, 0, cs48l32_eq_tlv),
2658
2659 CS48L32_MIXER_CONTROLS("DRC1L", CS48L32_DRC1L_INPUT1),
2660 CS48L32_MIXER_CONTROLS("DRC1R", CS48L32_DRC1R_INPUT1),
2661 CS48L32_MIXER_CONTROLS("DRC2L", CS48L32_DRC2L_INPUT1),
2662 CS48L32_MIXER_CONTROLS("DRC2R", CS48L32_DRC2R_INPUT1),
2663
2664 SND_SOC_BYTES_MASK("DRC1 Coefficients", CS48L32_DRC1_CONTROL1, 4,
2665 BIT(CS48L32_DRC1R_EN_SHIFT) | BIT(CS48L32_DRC1L_EN_SHIFT)),
2666 SND_SOC_BYTES_MASK("DRC2 Coefficients", CS48L32_DRC2_CONTROL1, 4,
2667 BIT(CS48L32_DRC1R_EN_SHIFT) | BIT(CS48L32_DRC1L_EN_SHIFT)),
2668
2669 CS48L32_MIXER_CONTROLS("LHPF1", CS48L32_LHPF1_INPUT1),
2670 CS48L32_MIXER_CONTROLS("LHPF2", CS48L32_LHPF2_INPUT1),
2671 CS48L32_MIXER_CONTROLS("LHPF3", CS48L32_LHPF3_INPUT1),
2672 CS48L32_MIXER_CONTROLS("LHPF4", CS48L32_LHPF4_INPUT1),
2673
2674 CS48L32_LHPF_CONTROL("LHPF1 Coefficients", CS48L32_LHPF1_COEFF),
2675 CS48L32_LHPF_CONTROL("LHPF2 Coefficients", CS48L32_LHPF2_COEFF),
2676 CS48L32_LHPF_CONTROL("LHPF3 Coefficients", CS48L32_LHPF3_COEFF),
2677 CS48L32_LHPF_CONTROL("LHPF4 Coefficients", CS48L32_LHPF4_COEFF),
2678
2679 SOC_ENUM("LHPF1 Mode", cs48l32_lhpf_mode[0]),
2680 SOC_ENUM("LHPF2 Mode", cs48l32_lhpf_mode[1]),
2681 SOC_ENUM("LHPF3 Mode", cs48l32_lhpf_mode[2]),
2682 SOC_ENUM("LHPF4 Mode", cs48l32_lhpf_mode[3]),
2683
2684 CS48L32_RATE_CONTROL("Sample Rate 1", 1),
2685 CS48L32_RATE_CONTROL("Sample Rate 2", 2),
2686 CS48L32_RATE_CONTROL("Sample Rate 3", 3),
2687 CS48L32_RATE_CONTROL("Sample Rate 4", 4),
2688
2689 CS48L32_RATE_ENUM("FX Rate", cs48l32_fx_rate),
2690
2691 CS48L32_RATE_ENUM("ISRC1 FSL", cs48l32_isrc_fsl[0]),
2692 CS48L32_RATE_ENUM("ISRC2 FSL", cs48l32_isrc_fsl[1]),
2693 CS48L32_RATE_ENUM("ISRC3 FSL", cs48l32_isrc_fsl[2]),
2694 CS48L32_RATE_ENUM("ISRC1 FSH", cs48l32_isrc_fsh[0]),
2695 CS48L32_RATE_ENUM("ISRC2 FSH", cs48l32_isrc_fsh[1]),
2696 CS48L32_RATE_ENUM("ISRC3 FSH", cs48l32_isrc_fsh[2]),
2697
2698 SOC_ENUM("AUXPDM1 Rate", cs48l32_auxpdm1_freq),
2699 SOC_ENUM("AUXPDM2 Rate", cs48l32_auxpdm2_freq),
2700
2701 SOC_ENUM_EXT("IN1L Rate", cs48l32_input_rate[0], snd_soc_get_enum_double, cs48l32_in_rate_put),
2702 SOC_ENUM_EXT("IN1R Rate", cs48l32_input_rate[1], snd_soc_get_enum_double, cs48l32_in_rate_put),
2703 SOC_ENUM_EXT("IN2L Rate", cs48l32_input_rate[2], snd_soc_get_enum_double, cs48l32_in_rate_put),
2704 SOC_ENUM_EXT("IN2R Rate", cs48l32_input_rate[3], snd_soc_get_enum_double, cs48l32_in_rate_put),
2705
2706 CS48L32_RATE_ENUM("Noise Generator Rate", noise_gen_rate),
2707
2708 SOC_SINGLE_TLV("Noise Generator Volume", CS48L32_COMFORT_NOISE_GENERATOR,
2709 CS48L32_NOISE_GEN_GAIN_SHIFT, 0x12, 0, cs48l32_noise_tlv),
2710
2711 CS48L32_MIXER_CONTROLS("ASP1TX1", CS48L32_ASP1TX1_INPUT1),
2712 CS48L32_MIXER_CONTROLS("ASP1TX2", CS48L32_ASP1TX2_INPUT1),
2713 CS48L32_MIXER_CONTROLS("ASP1TX3", CS48L32_ASP1TX3_INPUT1),
2714 CS48L32_MIXER_CONTROLS("ASP1TX4", CS48L32_ASP1TX4_INPUT1),
2715 CS48L32_MIXER_CONTROLS("ASP1TX5", CS48L32_ASP1TX5_INPUT1),
2716 CS48L32_MIXER_CONTROLS("ASP1TX6", CS48L32_ASP1TX6_INPUT1),
2717 CS48L32_MIXER_CONTROLS("ASP1TX7", CS48L32_ASP1TX7_INPUT1),
2718 CS48L32_MIXER_CONTROLS("ASP1TX8", CS48L32_ASP1TX8_INPUT1),
2719
2720 CS48L32_MIXER_CONTROLS("ASP2TX1", CS48L32_ASP2TX1_INPUT1),
2721 CS48L32_MIXER_CONTROLS("ASP2TX2", CS48L32_ASP2TX2_INPUT1),
2722 CS48L32_MIXER_CONTROLS("ASP2TX3", CS48L32_ASP2TX3_INPUT1),
2723 CS48L32_MIXER_CONTROLS("ASP2TX4", CS48L32_ASP2TX4_INPUT1),
2724
2725 WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
2726
2727 CS48L32_MIXER_CONTROLS("DSP1RX1", CS48L32_DSP1RX1_INPUT1),
2728 CS48L32_MIXER_CONTROLS("DSP1RX2", CS48L32_DSP1RX2_INPUT1),
2729 CS48L32_MIXER_CONTROLS("DSP1RX3", CS48L32_DSP1RX3_INPUT1),
2730 CS48L32_MIXER_CONTROLS("DSP1RX4", CS48L32_DSP1RX4_INPUT1),
2731 CS48L32_MIXER_CONTROLS("DSP1RX5", CS48L32_DSP1RX5_INPUT1),
2732 CS48L32_MIXER_CONTROLS("DSP1RX6", CS48L32_DSP1RX6_INPUT1),
2733 CS48L32_MIXER_CONTROLS("DSP1RX7", CS48L32_DSP1RX7_INPUT1),
2734 CS48L32_MIXER_CONTROLS("DSP1RX8", CS48L32_DSP1RX8_INPUT1),
2735
2736 WM_ADSP_FW_CONTROL("DSP1", 0),
2737
2738 CS48L32_DSP_RATE_CONTROL("DSP1RX1", 0),
2739 CS48L32_DSP_RATE_CONTROL("DSP1RX2", 1),
2740 CS48L32_DSP_RATE_CONTROL("DSP1RX3", 2),
2741 CS48L32_DSP_RATE_CONTROL("DSP1RX4", 3),
2742 CS48L32_DSP_RATE_CONTROL("DSP1RX5", 4),
2743 CS48L32_DSP_RATE_CONTROL("DSP1RX6", 5),
2744 CS48L32_DSP_RATE_CONTROL("DSP1RX7", 6),
2745 CS48L32_DSP_RATE_CONTROL("DSP1RX8", 7),
2746 CS48L32_DSP_RATE_CONTROL("DSP1TX1", 8),
2747 CS48L32_DSP_RATE_CONTROL("DSP1TX2", 9),
2748 CS48L32_DSP_RATE_CONTROL("DSP1TX3", 10),
2749 CS48L32_DSP_RATE_CONTROL("DSP1TX4", 11),
2750 CS48L32_DSP_RATE_CONTROL("DSP1TX5", 12),
2751 CS48L32_DSP_RATE_CONTROL("DSP1TX6", 13),
2752 CS48L32_DSP_RATE_CONTROL("DSP1TX7", 14),
2753 CS48L32_DSP_RATE_CONTROL("DSP1TX8", 15),
2754 };
2755
2756 CS48L32_MIXER_ENUMS(EQ1, CS48L32_EQ1_INPUT1);
2757 CS48L32_MIXER_ENUMS(EQ2, CS48L32_EQ2_INPUT1);
2758 CS48L32_MIXER_ENUMS(EQ3, CS48L32_EQ3_INPUT1);
2759 CS48L32_MIXER_ENUMS(EQ4, CS48L32_EQ4_INPUT1);
2760
2761 CS48L32_MIXER_ENUMS(DRC1L, CS48L32_DRC1L_INPUT1);
2762 CS48L32_MIXER_ENUMS(DRC1R, CS48L32_DRC1R_INPUT1);
2763 CS48L32_MIXER_ENUMS(DRC2L, CS48L32_DRC2L_INPUT1);
2764 CS48L32_MIXER_ENUMS(DRC2R, CS48L32_DRC2R_INPUT1);
2765
2766 CS48L32_MIXER_ENUMS(LHPF1, CS48L32_LHPF1_INPUT1);
2767 CS48L32_MIXER_ENUMS(LHPF2, CS48L32_LHPF2_INPUT1);
2768 CS48L32_MIXER_ENUMS(LHPF3, CS48L32_LHPF3_INPUT1);
2769 CS48L32_MIXER_ENUMS(LHPF4, CS48L32_LHPF4_INPUT1);
2770
2771 CS48L32_MIXER_ENUMS(ASP1TX1, CS48L32_ASP1TX1_INPUT1);
2772 CS48L32_MIXER_ENUMS(ASP1TX2, CS48L32_ASP1TX2_INPUT1);
2773 CS48L32_MIXER_ENUMS(ASP1TX3, CS48L32_ASP1TX3_INPUT1);
2774 CS48L32_MIXER_ENUMS(ASP1TX4, CS48L32_ASP1TX4_INPUT1);
2775 CS48L32_MIXER_ENUMS(ASP1TX5, CS48L32_ASP1TX5_INPUT1);
2776 CS48L32_MIXER_ENUMS(ASP1TX6, CS48L32_ASP1TX6_INPUT1);
2777 CS48L32_MIXER_ENUMS(ASP1TX7, CS48L32_ASP1TX7_INPUT1);
2778 CS48L32_MIXER_ENUMS(ASP1TX8, CS48L32_ASP1TX8_INPUT1);
2779
2780 CS48L32_MIXER_ENUMS(ASP2TX1, CS48L32_ASP2TX1_INPUT1);
2781 CS48L32_MIXER_ENUMS(ASP2TX2, CS48L32_ASP2TX2_INPUT1);
2782 CS48L32_MIXER_ENUMS(ASP2TX3, CS48L32_ASP2TX3_INPUT1);
2783 CS48L32_MIXER_ENUMS(ASP2TX4, CS48L32_ASP2TX4_INPUT1);
2784
2785 CS48L32_MUX_ENUMS(ISRC1INT1, CS48L32_ISRC1INT1_INPUT1);
2786 CS48L32_MUX_ENUMS(ISRC1INT2, CS48L32_ISRC1INT2_INPUT1);
2787 CS48L32_MUX_ENUMS(ISRC1INT3, CS48L32_ISRC1INT3_INPUT1);
2788 CS48L32_MUX_ENUMS(ISRC1INT4, CS48L32_ISRC1INT4_INPUT1);
2789
2790 CS48L32_MUX_ENUMS(ISRC1DEC1, CS48L32_ISRC1DEC1_INPUT1);
2791 CS48L32_MUX_ENUMS(ISRC1DEC2, CS48L32_ISRC1DEC2_INPUT1);
2792 CS48L32_MUX_ENUMS(ISRC1DEC3, CS48L32_ISRC1DEC3_INPUT1);
2793 CS48L32_MUX_ENUMS(ISRC1DEC4, CS48L32_ISRC1DEC4_INPUT1);
2794
2795 CS48L32_MUX_ENUMS(ISRC2INT1, CS48L32_ISRC2INT1_INPUT1);
2796 CS48L32_MUX_ENUMS(ISRC2INT2, CS48L32_ISRC2INT2_INPUT1);
2797
2798 CS48L32_MUX_ENUMS(ISRC2DEC1, CS48L32_ISRC2DEC1_INPUT1);
2799 CS48L32_MUX_ENUMS(ISRC2DEC2, CS48L32_ISRC2DEC2_INPUT1);
2800
2801 CS48L32_MUX_ENUMS(ISRC3INT1, CS48L32_ISRC3INT1_INPUT1);
2802 CS48L32_MUX_ENUMS(ISRC3INT2, CS48L32_ISRC3INT2_INPUT1);
2803
2804 CS48L32_MUX_ENUMS(ISRC3DEC1, CS48L32_ISRC3DEC1_INPUT1);
2805 CS48L32_MUX_ENUMS(ISRC3DEC2, CS48L32_ISRC3DEC2_INPUT1);
2806
2807 CS48L32_MIXER_ENUMS(DSP1RX1, CS48L32_DSP1RX1_INPUT1);
2808 CS48L32_MIXER_ENUMS(DSP1RX2, CS48L32_DSP1RX2_INPUT1);
2809 CS48L32_MIXER_ENUMS(DSP1RX3, CS48L32_DSP1RX3_INPUT1);
2810 CS48L32_MIXER_ENUMS(DSP1RX4, CS48L32_DSP1RX4_INPUT1);
2811 CS48L32_MIXER_ENUMS(DSP1RX5, CS48L32_DSP1RX5_INPUT1);
2812 CS48L32_MIXER_ENUMS(DSP1RX6, CS48L32_DSP1RX6_INPUT1);
2813 CS48L32_MIXER_ENUMS(DSP1RX7, CS48L32_DSP1RX7_INPUT1);
2814 CS48L32_MIXER_ENUMS(DSP1RX8, CS48L32_DSP1RX8_INPUT1);
2815
cs48l32_dsp_mem_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)2816 static int cs48l32_dsp_mem_ev(struct snd_soc_dapm_widget *w,
2817 struct snd_kcontrol *kcontrol, int event)
2818 {
2819 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2820 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
2821
2822 switch (event) {
2823 case SND_SOC_DAPM_POST_PMU:
2824 return cs48l32_dsp_memory_enable(cs48l32_codec, &cs48l32_dsp_sram_regs);
2825 case SND_SOC_DAPM_PRE_PMD:
2826 cs48l32_dsp_memory_disable(cs48l32_codec, &cs48l32_dsp_sram_regs);
2827 return 0;
2828 default:
2829 return 0;
2830 }
2831 }
2832
2833 static const struct snd_soc_dapm_widget cs48l32_dapm_widgets[] = {
2834 SND_SOC_DAPM_SUPPLY("SYSCLK", CS48L32_SYSTEM_CLOCK1, CS48L32_SYSCLK_EN_SHIFT, 0,
2835 cs48l32_sysclk_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2836
2837 SND_SOC_DAPM_REGULATOR_SUPPLY("vdd-cp", 20, 0),
2838
2839 SND_SOC_DAPM_SUPPLY("VOUT_MIC", CS48L32_CHARGE_PUMP1, CS48L32_CP2_EN_SHIFT, 0, NULL, 0),
2840 SND_SOC_DAPM_SUPPLY("VOUT_MIC_REGULATED", CS48L32_CHARGE_PUMP1, CS48L32_CP2_BYPASS_SHIFT,
2841 1, NULL, 0),
2842 SND_SOC_DAPM_SUPPLY("MICBIAS1", CS48L32_MICBIAS_CTRL1, CS48L32_MICB1_EN_SHIFT, 0, NULL, 0),
2843 SND_SOC_DAPM_SUPPLY("MICBIAS1A", CS48L32_MICBIAS_CTRL5, CS48L32_MICB1A_EN_SHIFT, 0, NULL, 0),
2844 SND_SOC_DAPM_SUPPLY("MICBIAS1B", CS48L32_MICBIAS_CTRL5, CS48L32_MICB1B_EN_SHIFT, 0, NULL, 0),
2845 SND_SOC_DAPM_SUPPLY("MICBIAS1C", CS48L32_MICBIAS_CTRL5, CS48L32_MICB1C_EN_SHIFT, 0, NULL, 0),
2846
2847 SND_SOC_DAPM_SUPPLY("DSP1MEM", SND_SOC_NOPM, 0, 0, cs48l32_dsp_mem_ev,
2848 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2849
2850 CS48L32_DSP_FREQ_WIDGET_EV("DSP1", 0, cs48l32_dsp_freq_ev),
2851
2852 SND_SOC_DAPM_SIGGEN("TONE"),
2853 SND_SOC_DAPM_SIGGEN("NOISE"),
2854
2855 SND_SOC_DAPM_INPUT("IN1LN_1"),
2856 SND_SOC_DAPM_INPUT("IN1LN_2"),
2857 SND_SOC_DAPM_INPUT("IN1LP_1"),
2858 SND_SOC_DAPM_INPUT("IN1LP_2"),
2859 SND_SOC_DAPM_INPUT("IN1RN_1"),
2860 SND_SOC_DAPM_INPUT("IN1RN_2"),
2861 SND_SOC_DAPM_INPUT("IN1RP_1"),
2862 SND_SOC_DAPM_INPUT("IN1RP_2"),
2863 SND_SOC_DAPM_INPUT("IN1_PDMCLK"),
2864 SND_SOC_DAPM_INPUT("IN1_PDMDATA"),
2865
2866 SND_SOC_DAPM_INPUT("IN2_PDMCLK"),
2867 SND_SOC_DAPM_INPUT("IN2_PDMDATA"),
2868
2869 SND_SOC_DAPM_MUX("Ultrasonic 1 Input", SND_SOC_NOPM, 0, 0, &cs48l32_us_inmux[0]),
2870 SND_SOC_DAPM_MUX("Ultrasonic 2 Input", SND_SOC_NOPM, 0, 0, &cs48l32_us_inmux[1]),
2871
2872 SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
2873 SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
2874
2875 SND_SOC_DAPM_OUTPUT("DSP Trigger Out"),
2876
2877 SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &cs48l32_inmux[0]),
2878 SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &cs48l32_inmux[1]),
2879
2880 SND_SOC_DAPM_MUX("IN1L Mode", SND_SOC_NOPM, 0, 0, &cs48l32_dmode_mux[0]),
2881 SND_SOC_DAPM_MUX("IN1R Mode", SND_SOC_NOPM, 0, 0, &cs48l32_dmode_mux[0]),
2882
2883 SND_SOC_DAPM_AIF_OUT("ASP1TX1", NULL, 0, CS48L32_ASP1_ENABLES1, 0, 0),
2884 SND_SOC_DAPM_AIF_OUT("ASP1TX2", NULL, 1, CS48L32_ASP1_ENABLES1, 1, 0),
2885 SND_SOC_DAPM_AIF_OUT("ASP1TX3", NULL, 2, CS48L32_ASP1_ENABLES1, 2, 0),
2886 SND_SOC_DAPM_AIF_OUT("ASP1TX4", NULL, 3, CS48L32_ASP1_ENABLES1, 3, 0),
2887 SND_SOC_DAPM_AIF_OUT("ASP1TX5", NULL, 4, CS48L32_ASP1_ENABLES1, 4, 0),
2888 SND_SOC_DAPM_AIF_OUT("ASP1TX6", NULL, 5, CS48L32_ASP1_ENABLES1, 5, 0),
2889 SND_SOC_DAPM_AIF_OUT("ASP1TX7", NULL, 6, CS48L32_ASP1_ENABLES1, 6, 0),
2890 SND_SOC_DAPM_AIF_OUT("ASP1TX8", NULL, 7, CS48L32_ASP1_ENABLES1, 7, 0),
2891
2892 SND_SOC_DAPM_AIF_OUT("ASP2TX1", NULL, 0, CS48L32_ASP2_ENABLES1, 0, 0),
2893 SND_SOC_DAPM_AIF_OUT("ASP2TX2", NULL, 1, CS48L32_ASP2_ENABLES1, 1, 0),
2894 SND_SOC_DAPM_AIF_OUT("ASP2TX3", NULL, 2, CS48L32_ASP2_ENABLES1, 2, 0),
2895 SND_SOC_DAPM_AIF_OUT("ASP2TX4", NULL, 3, CS48L32_ASP2_ENABLES1, 3, 0),
2896
2897 SND_SOC_DAPM_SWITCH("AUXPDM1 Output", CS48L32_AUXPDM_CONTROL1, 0, 0, &cs48l32_auxpdm_switch[0]),
2898 SND_SOC_DAPM_SWITCH("AUXPDM2 Output", CS48L32_AUXPDM_CONTROL1, 1, 0, &cs48l32_auxpdm_switch[1]),
2899
2900 SND_SOC_DAPM_MUX("AUXPDM1 Input", SND_SOC_NOPM, 0, 0, &cs48l32_auxpdm_inmux[0]),
2901 SND_SOC_DAPM_MUX("AUXPDM2 Input", SND_SOC_NOPM, 0, 0, &cs48l32_auxpdm_inmux[1]),
2902
2903 SND_SOC_DAPM_MUX("AUXPDM1 Analog Input", SND_SOC_NOPM, 0, 0,
2904 &cs48l32_auxpdm_analog_inmux[0]),
2905 SND_SOC_DAPM_MUX("AUXPDM2 Analog Input", SND_SOC_NOPM, 0, 0,
2906 &cs48l32_auxpdm_analog_inmux[1]),
2907
2908 SND_SOC_DAPM_SWITCH("Ultrasonic 1 Detect", CS48L32_US_CONTROL,
2909 CS48L32_US1_DET_EN_SHIFT, 0, &cs48l32_us_switch[0]),
2910 SND_SOC_DAPM_SWITCH("Ultrasonic 2 Detect", CS48L32_US_CONTROL,
2911 CS48L32_US1_DET_EN_SHIFT, 0, &cs48l32_us_switch[1]),
2912
2913 /*
2914 * mux_in widgets : arranged in the order of sources
2915 * specified in CS48L32_MIXER_INPUT_ROUTES
2916 */
2917 SND_SOC_DAPM_PGA("Tone Generator 1", CS48L32_TONE_GENERATOR1, 0, 0, NULL, 0),
2918 SND_SOC_DAPM_PGA("Tone Generator 2", CS48L32_TONE_GENERATOR1, 1, 0, NULL, 0),
2919
2920 SND_SOC_DAPM_PGA("Noise Generator", CS48L32_COMFORT_NOISE_GENERATOR,
2921 CS48L32_NOISE_GEN_EN_SHIFT, 0, NULL, 0),
2922
2923 SND_SOC_DAPM_PGA_E("IN1L PGA", CS48L32_INPUT_CONTROL, CS48L32_IN1L_EN_SHIFT,
2924 0, NULL, 0, cs48l32_in_ev,
2925 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2926 SND_SOC_DAPM_PGA_E("IN1R PGA", CS48L32_INPUT_CONTROL, CS48L32_IN1R_EN_SHIFT,
2927 0, NULL, 0, cs48l32_in_ev,
2928 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2929 SND_SOC_DAPM_PGA_E("IN2L PGA", CS48L32_INPUT_CONTROL, CS48L32_IN2L_EN_SHIFT,
2930 0, NULL, 0, cs48l32_in_ev,
2931 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2932 SND_SOC_DAPM_PGA_E("IN2R PGA", CS48L32_INPUT_CONTROL, CS48L32_IN2R_EN_SHIFT,
2933 0, NULL, 0, cs48l32_in_ev,
2934 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
2935
2936 SND_SOC_DAPM_AIF_IN("ASP1RX1", NULL, 0, CS48L32_ASP1_ENABLES1, 16, 0),
2937 SND_SOC_DAPM_AIF_IN("ASP1RX2", NULL, 1, CS48L32_ASP1_ENABLES1, 17, 0),
2938 SND_SOC_DAPM_AIF_IN("ASP1RX3", NULL, 2, CS48L32_ASP1_ENABLES1, 18, 0),
2939 SND_SOC_DAPM_AIF_IN("ASP1RX4", NULL, 3, CS48L32_ASP1_ENABLES1, 19, 0),
2940 SND_SOC_DAPM_AIF_IN("ASP1RX5", NULL, 4, CS48L32_ASP1_ENABLES1, 20, 0),
2941 SND_SOC_DAPM_AIF_IN("ASP1RX6", NULL, 5, CS48L32_ASP1_ENABLES1, 21, 0),
2942 SND_SOC_DAPM_AIF_IN("ASP1RX7", NULL, 6, CS48L32_ASP1_ENABLES1, 22, 0),
2943 SND_SOC_DAPM_AIF_IN("ASP1RX8", NULL, 7, CS48L32_ASP1_ENABLES1, 23, 0),
2944
2945 SND_SOC_DAPM_AIF_IN("ASP2RX1", NULL, 0, CS48L32_ASP2_ENABLES1, 16, 0),
2946 SND_SOC_DAPM_AIF_IN("ASP2RX2", NULL, 1, CS48L32_ASP2_ENABLES1, 17, 0),
2947 SND_SOC_DAPM_AIF_IN("ASP2RX3", NULL, 2, CS48L32_ASP2_ENABLES1, 18, 0),
2948 SND_SOC_DAPM_AIF_IN("ASP2RX4", NULL, 3, CS48L32_ASP2_ENABLES1, 19, 0),
2949
2950 SND_SOC_DAPM_PGA("ISRC1DEC1", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC1_EN_SHIFT, 0, NULL, 0),
2951 SND_SOC_DAPM_PGA("ISRC1DEC2", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC2_EN_SHIFT, 0, NULL, 0),
2952 SND_SOC_DAPM_PGA("ISRC1DEC3", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC3_EN_SHIFT, 0, NULL, 0),
2953 SND_SOC_DAPM_PGA("ISRC1DEC4", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_DEC4_EN_SHIFT, 0, NULL, 0),
2954
2955 SND_SOC_DAPM_PGA("ISRC1INT1", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT1_EN_SHIFT, 0, NULL, 0),
2956 SND_SOC_DAPM_PGA("ISRC1INT2", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT2_EN_SHIFT, 0, NULL, 0),
2957 SND_SOC_DAPM_PGA("ISRC1INT3", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT3_EN_SHIFT, 0, NULL, 0),
2958 SND_SOC_DAPM_PGA("ISRC1INT4", CS48L32_ISRC1_CONTROL2, CS48L32_ISRC1_INT4_EN_SHIFT, 0, NULL, 0),
2959
2960 SND_SOC_DAPM_PGA("ISRC2DEC1", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_DEC1_EN_SHIFT, 0, NULL, 0),
2961 SND_SOC_DAPM_PGA("ISRC2DEC2", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_DEC2_EN_SHIFT, 0, NULL, 0),
2962
2963 SND_SOC_DAPM_PGA("ISRC2INT1", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_INT1_EN_SHIFT, 0, NULL, 0),
2964 SND_SOC_DAPM_PGA("ISRC2INT2", CS48L32_ISRC2_CONTROL2, CS48L32_ISRC1_INT2_EN_SHIFT, 0, NULL, 0),
2965
2966 SND_SOC_DAPM_PGA("ISRC3DEC1", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_DEC1_EN_SHIFT, 0, NULL, 0),
2967 SND_SOC_DAPM_PGA("ISRC3DEC2", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_DEC2_EN_SHIFT, 0, NULL, 0),
2968
2969 SND_SOC_DAPM_PGA("ISRC3INT1", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_INT1_EN_SHIFT, 0, NULL, 0),
2970 SND_SOC_DAPM_PGA("ISRC3INT2", CS48L32_ISRC3_CONTROL2, CS48L32_ISRC1_INT2_EN_SHIFT, 0, NULL, 0),
2971
2972 SND_SOC_DAPM_PGA_E("EQ1", CS48L32_EQ_CONTROL1, 0, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2973 SND_SOC_DAPM_PGA_E("EQ2", CS48L32_EQ_CONTROL1, 1, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2974 SND_SOC_DAPM_PGA_E("EQ3", CS48L32_EQ_CONTROL1, 2, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2975 SND_SOC_DAPM_PGA_E("EQ4", CS48L32_EQ_CONTROL1, 3, 0, NULL, 0, cs48l32_eq_ev, SND_SOC_DAPM_PRE_PMU),
2976
2977 SND_SOC_DAPM_PGA("DRC1L", CS48L32_DRC1_CONTROL1, CS48L32_DRC1L_EN_SHIFT, 0, NULL, 0),
2978 SND_SOC_DAPM_PGA("DRC1R", CS48L32_DRC1_CONTROL1, CS48L32_DRC1R_EN_SHIFT, 0, NULL, 0),
2979 SND_SOC_DAPM_PGA("DRC2L", CS48L32_DRC2_CONTROL1, CS48L32_DRC1L_EN_SHIFT, 0, NULL, 0),
2980 SND_SOC_DAPM_PGA("DRC2R", CS48L32_DRC2_CONTROL1, CS48L32_DRC1R_EN_SHIFT, 0, NULL, 0),
2981
2982 SND_SOC_DAPM_PGA("LHPF1", CS48L32_LHPF_CONTROL1, 0, 0, NULL, 0),
2983 SND_SOC_DAPM_PGA("LHPF2", CS48L32_LHPF_CONTROL1, 1, 0, NULL, 0),
2984 SND_SOC_DAPM_PGA("LHPF3", CS48L32_LHPF_CONTROL1, 2, 0, NULL, 0),
2985 SND_SOC_DAPM_PGA("LHPF4", CS48L32_LHPF_CONTROL1, 3, 0, NULL, 0),
2986
2987 SND_SOC_DAPM_PGA("Ultrasonic 1", CS48L32_US_CONTROL, 0, 0, NULL, 0),
2988 SND_SOC_DAPM_PGA("Ultrasonic 2", CS48L32_US_CONTROL, 1, 0, NULL, 0),
2989
2990 WM_ADSP2("DSP1", 0, wm_adsp_early_event),
2991
2992 /* end of ordered widget list */
2993
2994 CS48L32_MIXER_WIDGETS(EQ1, "EQ1"),
2995 CS48L32_MIXER_WIDGETS(EQ2, "EQ2"),
2996 CS48L32_MIXER_WIDGETS(EQ3, "EQ3"),
2997 CS48L32_MIXER_WIDGETS(EQ4, "EQ4"),
2998
2999 CS48L32_MIXER_WIDGETS(DRC1L, "DRC1L"),
3000 CS48L32_MIXER_WIDGETS(DRC1R, "DRC1R"),
3001 CS48L32_MIXER_WIDGETS(DRC2L, "DRC2L"),
3002 CS48L32_MIXER_WIDGETS(DRC2R, "DRC2R"),
3003
3004 SND_SOC_DAPM_SWITCH("DRC1 Activity Output", SND_SOC_NOPM, 0, 0,
3005 &cs48l32_drc_activity_output_mux[0]),
3006 SND_SOC_DAPM_SWITCH("DRC2 Activity Output", SND_SOC_NOPM, 0, 0,
3007 &cs48l32_drc_activity_output_mux[1]),
3008
3009 CS48L32_MIXER_WIDGETS(LHPF1, "LHPF1"),
3010 CS48L32_MIXER_WIDGETS(LHPF2, "LHPF2"),
3011 CS48L32_MIXER_WIDGETS(LHPF3, "LHPF3"),
3012 CS48L32_MIXER_WIDGETS(LHPF4, "LHPF4"),
3013
3014 CS48L32_MIXER_WIDGETS(ASP1TX1, "ASP1TX1"),
3015 CS48L32_MIXER_WIDGETS(ASP1TX2, "ASP1TX2"),
3016 CS48L32_MIXER_WIDGETS(ASP1TX3, "ASP1TX3"),
3017 CS48L32_MIXER_WIDGETS(ASP1TX4, "ASP1TX4"),
3018 CS48L32_MIXER_WIDGETS(ASP1TX5, "ASP1TX5"),
3019 CS48L32_MIXER_WIDGETS(ASP1TX6, "ASP1TX6"),
3020 CS48L32_MIXER_WIDGETS(ASP1TX7, "ASP1TX7"),
3021 CS48L32_MIXER_WIDGETS(ASP1TX8, "ASP1TX8"),
3022
3023 CS48L32_MIXER_WIDGETS(ASP2TX1, "ASP2TX1"),
3024 CS48L32_MIXER_WIDGETS(ASP2TX2, "ASP2TX2"),
3025 CS48L32_MIXER_WIDGETS(ASP2TX3, "ASP2TX3"),
3026 CS48L32_MIXER_WIDGETS(ASP2TX4, "ASP2TX4"),
3027
3028 CS48L32_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
3029 CS48L32_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
3030 CS48L32_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
3031 CS48L32_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
3032
3033 CS48L32_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
3034 CS48L32_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
3035 CS48L32_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
3036 CS48L32_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
3037
3038 CS48L32_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
3039 CS48L32_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
3040
3041 CS48L32_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
3042 CS48L32_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
3043
3044 CS48L32_MUX_WIDGETS(ISRC3DEC1, "ISRC3DEC1"),
3045 CS48L32_MUX_WIDGETS(ISRC3DEC2, "ISRC3DEC2"),
3046
3047 CS48L32_MUX_WIDGETS(ISRC3INT1, "ISRC3INT1"),
3048 CS48L32_MUX_WIDGETS(ISRC3INT2, "ISRC3INT2"),
3049
3050 CS48L32_MIXER_WIDGETS(DSP1RX1, "DSP1RX1"),
3051 CS48L32_MIXER_WIDGETS(DSP1RX2, "DSP1RX2"),
3052 CS48L32_MIXER_WIDGETS(DSP1RX3, "DSP1RX3"),
3053 CS48L32_MIXER_WIDGETS(DSP1RX4, "DSP1RX4"),
3054 CS48L32_MIXER_WIDGETS(DSP1RX5, "DSP1RX5"),
3055 CS48L32_MIXER_WIDGETS(DSP1RX6, "DSP1RX6"),
3056 CS48L32_MIXER_WIDGETS(DSP1RX7, "DSP1RX7"),
3057 CS48L32_MIXER_WIDGETS(DSP1RX8, "DSP1RX8"),
3058
3059 SND_SOC_DAPM_SWITCH("DSP1 Trigger Output", SND_SOC_NOPM, 0, 0,
3060 &cs48l32_dsp_trigger_output_mux[0]),
3061
3062 SND_SOC_DAPM_OUTPUT("AUXPDM1_CLK"),
3063 SND_SOC_DAPM_OUTPUT("AUXPDM1_DOUT"),
3064 SND_SOC_DAPM_OUTPUT("AUXPDM2_CLK"),
3065 SND_SOC_DAPM_OUTPUT("AUXPDM2_DOUT"),
3066
3067 SND_SOC_DAPM_OUTPUT("MICSUPP"),
3068
3069 SND_SOC_DAPM_OUTPUT("Ultrasonic Dummy Output"),
3070 };
3071
3072 static const struct snd_soc_dapm_route cs48l32_dapm_routes[] = {
3073 { "IN1LN_1", NULL, "SYSCLK" },
3074 { "IN1LN_2", NULL, "SYSCLK" },
3075 { "IN1LP_1", NULL, "SYSCLK" },
3076 { "IN1LP_2", NULL, "SYSCLK" },
3077 { "IN1RN_1", NULL, "SYSCLK" },
3078 { "IN1RN_2", NULL, "SYSCLK" },
3079 { "IN1RP_1", NULL, "SYSCLK" },
3080 { "IN1RP_2", NULL, "SYSCLK" },
3081
3082 { "IN1_PDMCLK", NULL, "SYSCLK" },
3083 { "IN1_PDMDATA", NULL, "SYSCLK" },
3084 { "IN2_PDMCLK", NULL, "SYSCLK" },
3085 { "IN2_PDMDATA", NULL, "SYSCLK" },
3086
3087 { "DSP1 Preloader", NULL, "DSP1MEM" },
3088 { "DSP1", NULL, "DSP1FREQ" },
3089
3090 { "Audio Trace DSP", NULL, "DSP1" },
3091 { "Voice Ctrl DSP", NULL, "DSP1" },
3092
3093 { "VOUT_MIC_REGULATED", NULL, "VOUT_MIC" },
3094 { "MICBIAS1", NULL, "VOUT_MIC_REGULATED" },
3095 { "MICBIAS1A", NULL, "MICBIAS1" },
3096 { "MICBIAS1B", NULL, "MICBIAS1" },
3097 { "MICBIAS1C", NULL, "MICBIAS1" },
3098
3099 { "Tone Generator 1", NULL, "SYSCLK" },
3100 { "Tone Generator 2", NULL, "SYSCLK" },
3101 { "Noise Generator", NULL, "SYSCLK" },
3102
3103 { "Tone Generator 1", NULL, "TONE" },
3104 { "Tone Generator 2", NULL, "TONE" },
3105 { "Noise Generator", NULL, "NOISE" },
3106
3107 { "ASP1 Capture", NULL, "ASP1TX1" },
3108 { "ASP1 Capture", NULL, "ASP1TX2" },
3109 { "ASP1 Capture", NULL, "ASP1TX3" },
3110 { "ASP1 Capture", NULL, "ASP1TX4" },
3111 { "ASP1 Capture", NULL, "ASP1TX5" },
3112 { "ASP1 Capture", NULL, "ASP1TX6" },
3113 { "ASP1 Capture", NULL, "ASP1TX7" },
3114 { "ASP1 Capture", NULL, "ASP1TX8" },
3115
3116 { "ASP1RX1", NULL, "ASP1 Playback" },
3117 { "ASP1RX2", NULL, "ASP1 Playback" },
3118 { "ASP1RX3", NULL, "ASP1 Playback" },
3119 { "ASP1RX4", NULL, "ASP1 Playback" },
3120 { "ASP1RX5", NULL, "ASP1 Playback" },
3121 { "ASP1RX6", NULL, "ASP1 Playback" },
3122 { "ASP1RX7", NULL, "ASP1 Playback" },
3123 { "ASP1RX8", NULL, "ASP1 Playback" },
3124
3125 { "ASP2 Capture", NULL, "ASP2TX1" },
3126 { "ASP2 Capture", NULL, "ASP2TX2" },
3127 { "ASP2 Capture", NULL, "ASP2TX3" },
3128 { "ASP2 Capture", NULL, "ASP2TX4" },
3129
3130 { "ASP2RX1", NULL, "ASP2 Playback" },
3131 { "ASP2RX2", NULL, "ASP2 Playback" },
3132 { "ASP2RX3", NULL, "ASP2 Playback" },
3133 { "ASP2RX4", NULL, "ASP2 Playback" },
3134
3135 { "ASP1 Playback", NULL, "SYSCLK" },
3136 { "ASP2 Playback", NULL, "SYSCLK" },
3137
3138 { "ASP1 Capture", NULL, "SYSCLK" },
3139 { "ASP2 Capture", NULL, "SYSCLK" },
3140
3141 { "IN1L Mux", "Analog 1", "IN1LN_1" },
3142 { "IN1L Mux", "Analog 2", "IN1LN_2" },
3143 { "IN1L Mux", "Analog 1", "IN1LP_1" },
3144 { "IN1L Mux", "Analog 2", "IN1LP_2" },
3145 { "IN1R Mux", "Analog 1", "IN1RN_1" },
3146 { "IN1R Mux", "Analog 2", "IN1RN_2" },
3147 { "IN1R Mux", "Analog 1", "IN1RP_1" },
3148 { "IN1R Mux", "Analog 2", "IN1RP_2" },
3149
3150 { "IN1L PGA", NULL, "IN1L Mode" },
3151 { "IN1R PGA", NULL, "IN1R Mode" },
3152
3153 { "IN1L Mode", "Analog", "IN1L Mux" },
3154 { "IN1R Mode", "Analog", "IN1R Mux" },
3155
3156 { "IN1L Mode", "Digital", "IN1_PDMCLK" },
3157 { "IN1L Mode", "Digital", "IN1_PDMDATA" },
3158 { "IN1R Mode", "Digital", "IN1_PDMCLK" },
3159 { "IN1R Mode", "Digital", "IN1_PDMDATA" },
3160
3161 { "IN1L PGA", NULL, "VOUT_MIC" },
3162 { "IN1R PGA", NULL, "VOUT_MIC" },
3163
3164 { "IN2L PGA", NULL, "VOUT_MIC" },
3165 { "IN2R PGA", NULL, "VOUT_MIC" },
3166
3167 { "IN2L PGA", NULL, "IN2_PDMCLK" },
3168 { "IN2R PGA", NULL, "IN2_PDMCLK" },
3169 { "IN2L PGA", NULL, "IN2_PDMDATA" },
3170 { "IN2R PGA", NULL, "IN2_PDMDATA" },
3171
3172 { "Ultrasonic 1", NULL, "Ultrasonic 1 Input" },
3173 { "Ultrasonic 2", NULL, "Ultrasonic 2 Input" },
3174
3175 { "Ultrasonic 1 Input", "IN1L", "IN1L PGA" },
3176 { "Ultrasonic 1 Input", "IN1R", "IN1R PGA" },
3177 { "Ultrasonic 1 Input", "IN2L", "IN2L PGA" },
3178 { "Ultrasonic 1 Input", "IN2R", "IN2R PGA" },
3179
3180 { "Ultrasonic 2 Input", "IN1L", "IN1L PGA" },
3181 { "Ultrasonic 2 Input", "IN1R", "IN1R PGA" },
3182 { "Ultrasonic 2 Input", "IN2L", "IN2L PGA" },
3183 { "Ultrasonic 2 Input", "IN2R", "IN2R PGA" },
3184
3185 { "Ultrasonic 1 Detect", "Switch", "Ultrasonic 1 Input" },
3186 { "Ultrasonic 2 Detect", "Switch", "Ultrasonic 2 Input" },
3187
3188 { "Ultrasonic Dummy Output", NULL, "Ultrasonic 1 Detect" },
3189 { "Ultrasonic Dummy Output", NULL, "Ultrasonic 2 Detect" },
3190
3191 CS48L32_MIXER_ROUTES("ASP1TX1", "ASP1TX1"),
3192 CS48L32_MIXER_ROUTES("ASP1TX2", "ASP1TX2"),
3193 CS48L32_MIXER_ROUTES("ASP1TX3", "ASP1TX3"),
3194 CS48L32_MIXER_ROUTES("ASP1TX4", "ASP1TX4"),
3195 CS48L32_MIXER_ROUTES("ASP1TX5", "ASP1TX5"),
3196 CS48L32_MIXER_ROUTES("ASP1TX6", "ASP1TX6"),
3197 CS48L32_MIXER_ROUTES("ASP1TX7", "ASP1TX7"),
3198 CS48L32_MIXER_ROUTES("ASP1TX8", "ASP1TX8"),
3199
3200 CS48L32_MIXER_ROUTES("ASP2TX1", "ASP2TX1"),
3201 CS48L32_MIXER_ROUTES("ASP2TX2", "ASP2TX2"),
3202 CS48L32_MIXER_ROUTES("ASP2TX3", "ASP2TX3"),
3203 CS48L32_MIXER_ROUTES("ASP2TX4", "ASP2TX4"),
3204
3205 CS48L32_MIXER_ROUTES("EQ1", "EQ1"),
3206 CS48L32_MIXER_ROUTES("EQ2", "EQ2"),
3207 CS48L32_MIXER_ROUTES("EQ3", "EQ3"),
3208 CS48L32_MIXER_ROUTES("EQ4", "EQ4"),
3209
3210 CS48L32_MIXER_ROUTES("DRC1L", "DRC1L"),
3211 CS48L32_MIXER_ROUTES("DRC1R", "DRC1R"),
3212 CS48L32_MIXER_ROUTES("DRC2L", "DRC2L"),
3213 CS48L32_MIXER_ROUTES("DRC2R", "DRC2R"),
3214
3215 CS48L32_MIXER_ROUTES("LHPF1", "LHPF1"),
3216 CS48L32_MIXER_ROUTES("LHPF2", "LHPF2"),
3217 CS48L32_MIXER_ROUTES("LHPF3", "LHPF3"),
3218 CS48L32_MIXER_ROUTES("LHPF4", "LHPF4"),
3219
3220 CS48L32_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
3221 CS48L32_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
3222 CS48L32_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
3223 CS48L32_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
3224
3225 CS48L32_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
3226 CS48L32_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
3227 CS48L32_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
3228 CS48L32_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
3229
3230 CS48L32_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
3231 CS48L32_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
3232
3233 CS48L32_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
3234 CS48L32_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
3235
3236 CS48L32_MUX_ROUTES("ISRC3INT1", "ISRC3INT1"),
3237 CS48L32_MUX_ROUTES("ISRC3INT2", "ISRC3INT2"),
3238
3239 CS48L32_MUX_ROUTES("ISRC3DEC1", "ISRC3DEC1"),
3240 CS48L32_MUX_ROUTES("ISRC3DEC2", "ISRC3DEC2"),
3241
3242 CS48L32_DSP_ROUTES_1_8_SYSCLK("DSP1"),
3243
3244 { "DSP Trigger Out", NULL, "DSP1 Trigger Output" },
3245
3246 { "DSP1 Trigger Output", "Switch", "DSP1" },
3247
3248 { "AUXPDM1 Analog Input", "IN1L", "IN1L PGA" },
3249 { "AUXPDM1 Analog Input", "IN1R", "IN1R PGA" },
3250
3251 { "AUXPDM2 Analog Input", "IN1L", "IN1L PGA" },
3252 { "AUXPDM2 Analog Input", "IN1R", "IN1R PGA" },
3253
3254 { "AUXPDM1 Input", "Analog", "AUXPDM1 Analog Input" },
3255 { "AUXPDM1 Input", "IN1 Digital", "IN1L PGA" },
3256 { "AUXPDM1 Input", "IN1 Digital", "IN1R PGA" },
3257 { "AUXPDM1 Input", "IN2 Digital", "IN2L PGA" },
3258 { "AUXPDM1 Input", "IN2 Digital", "IN2R PGA" },
3259
3260 { "AUXPDM2 Input", "Analog", "AUXPDM2 Analog Input" },
3261 { "AUXPDM2 Input", "IN1 Digital", "IN1L PGA" },
3262 { "AUXPDM2 Input", "IN1 Digital", "IN1R PGA" },
3263 { "AUXPDM2 Input", "IN2 Digital", "IN2L PGA" },
3264 { "AUXPDM2 Input", "IN2 Digital", "IN2R PGA" },
3265
3266 { "AUXPDM1 Output", "Switch", "AUXPDM1 Input" },
3267 { "AUXPDM1_CLK", NULL, "AUXPDM1 Output" },
3268 { "AUXPDM1_DOUT", NULL, "AUXPDM1 Output" },
3269
3270 { "AUXPDM2 Output", "Switch", "AUXPDM2 Input" },
3271 { "AUXPDM2_CLK", NULL, "AUXPDM2 Output" },
3272 { "AUXPDM2_DOUT", NULL, "AUXPDM2 Output" },
3273
3274 { "MICSUPP", NULL, "SYSCLK" },
3275
3276 { "DRC1 Signal Activity", NULL, "DRC1 Activity Output" },
3277 { "DRC2 Signal Activity", NULL, "DRC2 Activity Output" },
3278 { "DRC1 Activity Output", "Switch", "DRC1L" },
3279 { "DRC1 Activity Output", "Switch", "DRC1R" },
3280 { "DRC2 Activity Output", "Switch", "DRC2L" },
3281 { "DRC2 Activity Output", "Switch", "DRC2R" },
3282 };
3283
cs48l32_compr_open(struct snd_soc_component * component,struct snd_compr_stream * stream)3284 static int cs48l32_compr_open(struct snd_soc_component *component,
3285 struct snd_compr_stream *stream)
3286 {
3287 struct snd_soc_pcm_runtime *rtd = stream->private_data;
3288 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3289
3290 if (strcmp(snd_soc_rtd_to_codec(rtd, 0)->name, "cs48l32-dsp-trace") &&
3291 strcmp(snd_soc_rtd_to_codec(rtd, 0)->name, "cs48l32-dsp-voicectrl")) {
3292 dev_err(cs48l32_codec->core.dev, "No suitable compressed stream for DAI '%s'\n",
3293 snd_soc_rtd_to_codec(rtd, 0)->name);
3294 return -EINVAL;
3295 }
3296
3297 return wm_adsp_compr_open(&cs48l32_codec->dsp, stream);
3298 }
3299
3300 static const struct snd_compress_ops cs48l32_compress_ops = {
3301 .open = &cs48l32_compr_open,
3302 .free = &wm_adsp_compr_free,
3303 .set_params = &wm_adsp_compr_set_params,
3304 .get_caps = &wm_adsp_compr_get_caps,
3305 .trigger = &wm_adsp_compr_trigger,
3306 .pointer = &wm_adsp_compr_pointer,
3307 .copy = &wm_adsp_compr_copy,
3308 };
3309
3310 static const struct snd_soc_dai_ops cs48l32_compress_dai_ops = {
3311 .compress_new = snd_soc_new_compress,
3312 };
3313
3314 static struct snd_soc_dai_driver cs48l32_dai[] = {
3315 {
3316 .name = "cs48l32-asp1",
3317 .id = 1,
3318 .base = CS48L32_ASP1_ENABLES1,
3319 .playback = {
3320 .stream_name = "ASP1 Playback",
3321 .channels_min = 1,
3322 .channels_max = 8,
3323 .rates = CS48L32_RATES,
3324 .formats = CS48L32_FORMATS,
3325 },
3326 .capture = {
3327 .stream_name = "ASP1 Capture",
3328 .channels_min = 1,
3329 .channels_max = 8,
3330 .rates = CS48L32_RATES,
3331 .formats = CS48L32_FORMATS,
3332 },
3333 .ops = &cs48l32_dai_ops,
3334 .symmetric_rate = 1,
3335 .symmetric_sample_bits = 1,
3336 },
3337 {
3338 .name = "cs48l32-asp2",
3339 .id = 2,
3340 .base = CS48L32_ASP2_ENABLES1,
3341 .playback = {
3342 .stream_name = "ASP2 Playback",
3343 .channels_min = 1,
3344 .channels_max = 4,
3345 .rates = CS48L32_RATES,
3346 .formats = CS48L32_FORMATS,
3347 },
3348 .capture = {
3349 .stream_name = "ASP2 Capture",
3350 .channels_min = 1,
3351 .channels_max = 4,
3352 .rates = CS48L32_RATES,
3353 .formats = CS48L32_FORMATS,
3354 },
3355 .ops = &cs48l32_dai_ops,
3356 .symmetric_rate = 1,
3357 .symmetric_sample_bits = 1,
3358 },
3359 {
3360 .name = "cs48l32-cpu-trace",
3361 .id = 3,
3362 .capture = {
3363 .stream_name = "Audio Trace CPU",
3364 .channels_min = 1,
3365 .channels_max = 8,
3366 .rates = CS48L32_RATES,
3367 .formats = CS48L32_FORMATS,
3368 },
3369 .ops = &cs48l32_compress_dai_ops,
3370 },
3371 {
3372 .name = "cs48l32-dsp-trace",
3373 .id = 4,
3374 .capture = {
3375 .stream_name = "Audio Trace DSP",
3376 .channels_min = 1,
3377 .channels_max = 8,
3378 .rates = CS48L32_RATES,
3379 .formats = CS48L32_FORMATS,
3380 },
3381 },
3382 {
3383 .name = "cs48l32-cpu-voicectrl",
3384 .id = 5,
3385 .capture = {
3386 .stream_name = "Voice Ctrl CPU",
3387 .channels_min = 1,
3388 .channels_max = 8,
3389 .rates = CS48L32_RATES,
3390 .formats = CS48L32_FORMATS,
3391 },
3392 .ops = &cs48l32_compress_dai_ops,
3393 },
3394 {
3395 .name = "cs48l32-dsp-voicectrl",
3396 .id = 6,
3397 .capture = {
3398 .stream_name = "Voice Ctrl DSP",
3399 .channels_min = 1,
3400 .channels_max = 8,
3401 .rates = CS48L32_RATES,
3402 .formats = CS48L32_FORMATS,
3403 },
3404 },
3405 };
3406
cs48l32_init_inputs(struct snd_soc_component * component)3407 static int cs48l32_init_inputs(struct snd_soc_component *component)
3408 {
3409 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3410 struct regmap *regmap = cs48l32_codec->core.regmap;
3411 unsigned int ana_mode_l, ana_mode_r, dig_mode;
3412 int i;
3413
3414 /*
3415 * Initialize input modes from the A settings. For muxed inputs the
3416 * B settings will be applied if the mux is changed
3417 */
3418 switch (cs48l32_codec->in_type[0][0]) {
3419 default:
3420 case CS48L32_IN_TYPE_DIFF:
3421 ana_mode_l = 0;
3422 break;
3423 case CS48L32_IN_TYPE_SE:
3424 ana_mode_l = 1 << CS48L32_INx_SRC_SHIFT;
3425 break;
3426 }
3427
3428 switch (cs48l32_codec->in_type[1][0]) {
3429 default:
3430 case CS48L32_IN_TYPE_DIFF:
3431 ana_mode_r = 0;
3432 break;
3433 case CS48L32_IN_TYPE_SE:
3434 ana_mode_r = 1 << CS48L32_INx_SRC_SHIFT;
3435 break;
3436 }
3437
3438 dev_dbg(cs48l32_codec->core.dev, "IN1_1 Analogue mode=#%x,#%x\n",
3439 ana_mode_l, ana_mode_r);
3440
3441 regmap_update_bits(regmap,
3442 CS48L32_IN1L_CONTROL1,
3443 CS48L32_INx_SRC_MASK,
3444 ana_mode_l);
3445
3446 regmap_update_bits(regmap,
3447 CS48L32_IN1R_CONTROL1,
3448 CS48L32_INx_SRC_MASK,
3449 ana_mode_r);
3450
3451 for (i = 0; i < ARRAY_SIZE(cs48l32_codec->pdm_sup); i++) {
3452 dig_mode = cs48l32_codec->pdm_sup[i] << CS48L32_IN1_PDM_SUP_SHIFT;
3453
3454 dev_dbg(cs48l32_codec->core.dev, "IN%d PDM_SUP=#%x\n", i + 1, dig_mode);
3455
3456 regmap_update_bits(regmap,
3457 CS48L32_INPUT1_CONTROL1 + (i * 0x40),
3458 CS48L32_IN1_PDM_SUP_MASK, dig_mode);
3459 }
3460
3461 return 0;
3462 }
3463
cs48l32_init_dai(struct cs48l32_codec * cs48l32_codec,int id)3464 static int cs48l32_init_dai(struct cs48l32_codec *cs48l32_codec, int id)
3465 {
3466 struct cs48l32_dai_priv *dai_priv = &cs48l32_codec->dai[id];
3467
3468 dai_priv->clk = CS48L32_CLK_SYSCLK_1;
3469 dai_priv->constraint = cs48l32_constraint;
3470
3471 return 0;
3472 }
3473
cs48l32_init_eq(struct cs48l32_codec * cs48l32_codec)3474 static int cs48l32_init_eq(struct cs48l32_codec *cs48l32_codec)
3475 {
3476 struct regmap *regmap = cs48l32_codec->core.regmap;
3477 unsigned int reg = CS48L32_EQ1_BAND1_COEFF1, mode;
3478 __be16 *data;
3479 int i, ret;
3480
3481 ret = regmap_read(regmap, CS48L32_EQ_CONTROL2, &mode);
3482 if (ret < 0) {
3483 dev_err(cs48l32_codec->core.dev, "Error reading EQ mode: %d\n", ret);
3484 goto out;
3485 }
3486
3487 for (i = 0; i < 4; ++i) {
3488 cs48l32_codec->eq_mode[i] = (mode >> i) & 0x1;
3489
3490 data = &cs48l32_codec->eq_coefficients[i][0];
3491 ret = regmap_raw_read(regmap, reg + (i * 68), data,
3492 CS48L32_EQ_BLOCK_SZ);
3493 if (ret < 0) {
3494 dev_err(cs48l32_codec->core.dev,
3495 "Error reading EQ coefficients: %d\n", ret);
3496 goto out;
3497 }
3498 }
3499
3500 out:
3501 return ret;
3502 }
3503
cs48l32_component_probe(struct snd_soc_component * component)3504 static int cs48l32_component_probe(struct snd_soc_component *component)
3505 {
3506 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3507 int i, ret;
3508
3509 snd_soc_component_init_regmap(component, cs48l32_codec->core.regmap);
3510
3511 ret = cs48l32_init_inputs(component);
3512 if (ret)
3513 return ret;
3514
3515 for (i = 0; i < ARRAY_SIZE(cs48l32_dai); i++)
3516 cs48l32_init_dai(cs48l32_codec, i);
3517
3518 ret = cs48l32_init_eq(cs48l32_codec);
3519 if (ret)
3520 return ret;
3521
3522 wm_adsp2_component_probe(&cs48l32_codec->dsp, component);
3523
3524 /* Unmask DSP IRQs */
3525 regmap_clear_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_7,
3526 CS48L32_DSP1_MPU_ERR_EINT1_MASK | CS48L32_DSP1_WDT_EXPIRE_EINT1_MASK);
3527 regmap_clear_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_9,
3528 CS48L32_DSP1_IRQ0_EINT1_MASK);
3529
3530 return 0;
3531 }
3532
cs48l32_component_remove(struct snd_soc_component * component)3533 static void cs48l32_component_remove(struct snd_soc_component *component)
3534 {
3535 struct cs48l32_codec *cs48l32_codec = snd_soc_component_get_drvdata(component);
3536
3537 /* Mask DSP IRQs */
3538 regmap_set_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_7,
3539 CS48L32_DSP1_MPU_ERR_EINT1_MASK | CS48L32_DSP1_WDT_EXPIRE_EINT1_MASK);
3540 regmap_set_bits(cs48l32_codec->core.regmap, CS48L32_IRQ1_MASK_9,
3541 CS48L32_DSP1_IRQ0_EINT1_MASK);
3542
3543 wm_adsp2_component_remove(&cs48l32_codec->dsp, component);
3544 }
3545
3546 static const struct snd_soc_component_driver cs48l32_soc_component_drv = {
3547 .probe = &cs48l32_component_probe,
3548 .remove = &cs48l32_component_remove,
3549 .set_sysclk = &cs48l32_set_sysclk,
3550 .set_pll = &cs48l32_set_fll,
3551 .name = "cs48l32-codec",
3552 .compress_ops = &cs48l32_compress_ops,
3553 .controls = cs48l32_snd_controls,
3554 .num_controls = ARRAY_SIZE(cs48l32_snd_controls),
3555 .dapm_widgets = cs48l32_dapm_widgets,
3556 .num_dapm_widgets = ARRAY_SIZE(cs48l32_dapm_widgets),
3557 .dapm_routes = cs48l32_dapm_routes,
3558 .num_dapm_routes = ARRAY_SIZE(cs48l32_dapm_routes),
3559 .use_pmdown_time = 1,
3560 .endianness = 1,
3561 };
3562
cs48l32_prop_read_u32_array(struct cs48l32_codec * cs48l32_codec,const char * propname,u32 * dest,int n_max)3563 static int cs48l32_prop_read_u32_array(struct cs48l32_codec *cs48l32_codec,
3564 const char *propname,
3565 u32 *dest,
3566 int n_max)
3567 {
3568 struct cs48l32 *cs48l32 = &cs48l32_codec->core;
3569 int ret;
3570
3571 ret = device_property_read_u32_array(cs48l32->dev, propname, dest, n_max);
3572 if (ret == -EINVAL)
3573 return -ENOENT;
3574
3575 if (ret < 0)
3576 return dev_err_probe(cs48l32->dev, ret, "%s malformed\n", propname);
3577
3578 return 0;
3579 }
3580
cs48l32_prop_get_in_type(struct cs48l32_codec * cs48l32_codec)3581 static void cs48l32_prop_get_in_type(struct cs48l32_codec *cs48l32_codec)
3582 {
3583 const char *propname = "cirrus,in-type";
3584 u32 tmp[CS48L32_MAX_ANALOG_INPUT * CS48L32_MAX_IN_MUX_WAYS];
3585 int i, in_idx, mux_way_idx, ret;
3586
3587 static_assert(ARRAY_SIZE(tmp) ==
3588 ARRAY_SIZE(cs48l32_codec->in_type) * ARRAY_SIZE(cs48l32_codec->in_type[0]));
3589
3590 ret = cs48l32_prop_read_u32_array(cs48l32_codec, propname, tmp, ARRAY_SIZE(tmp));
3591 if (ret < 0)
3592 return;
3593
3594 in_idx = 0;
3595 mux_way_idx = 0;
3596 for (i = 0; i < ARRAY_SIZE(tmp); ++i) {
3597 switch (tmp[i]) {
3598 case CS48L32_IN_TYPE_DIFF:
3599 case CS48L32_IN_TYPE_SE:
3600 cs48l32_codec->in_type[in_idx][mux_way_idx] = tmp[i];
3601 break;
3602 default:
3603 dev_warn(cs48l32_codec->core.dev, "Illegal %s value %d ignored\n",
3604 propname, tmp[i]);
3605 break;
3606 }
3607
3608 /*
3609 * Property array is [mux_way][in_channel]. Swap to
3610 * [in_channel][mux_way] for convenience.
3611 */
3612 if (++in_idx == ARRAY_SIZE(cs48l32_codec->in_type)) {
3613 in_idx = 0;
3614 ++mux_way_idx;
3615 }
3616 }
3617 }
3618
cs48l32_prop_get_pdm_sup(struct cs48l32_codec * cs48l32_codec)3619 static void cs48l32_prop_get_pdm_sup(struct cs48l32_codec *cs48l32_codec)
3620 {
3621 const char *propname = "cirrus,pdm-sup";
3622 u32 tmp[CS48L32_MAX_ANALOG_INPUT];
3623 int i;
3624
3625 static_assert(ARRAY_SIZE(tmp) == ARRAY_SIZE(cs48l32_codec->pdm_sup));
3626
3627 cs48l32_prop_read_u32_array(cs48l32_codec, propname, tmp, ARRAY_SIZE(tmp));
3628
3629 for (i = 0; i < ARRAY_SIZE(cs48l32_codec->pdm_sup); i++) {
3630 switch (tmp[i]) {
3631 case CS48L32_PDM_SUP_VOUT_MIC:
3632 case CS48L32_PDM_SUP_MICBIAS1:
3633 cs48l32_codec->pdm_sup[i] = tmp[i];
3634 break;
3635 default:
3636 dev_warn(cs48l32_codec->core.dev, "Illegal %s value %d ignored\n",
3637 propname, cs48l32_codec->pdm_sup[i]);
3638 break;
3639 }
3640 }
3641 }
3642
cs48l32_handle_properties(struct cs48l32_codec * cs48l32_codec)3643 static void cs48l32_handle_properties(struct cs48l32_codec *cs48l32_codec)
3644 {
3645 cs48l32_prop_get_in_type(cs48l32_codec);
3646 cs48l32_prop_get_pdm_sup(cs48l32_codec);
3647 }
3648
cs48l32_request_interrupt(struct cs48l32_codec * cs48l32_codec)3649 static int cs48l32_request_interrupt(struct cs48l32_codec *cs48l32_codec)
3650 {
3651 int irq = cs48l32_codec->core.irq;
3652 int ret;
3653
3654 if (irq < 1)
3655 return 0;
3656
3657 /*
3658 * Don't use devm because this must be freed before destroying the
3659 * rest of the driver
3660 */
3661 ret = request_threaded_irq(irq, NULL, cs48l32_irq,
3662 IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW,
3663 "cs48l32", cs48l32_codec);
3664 if (ret)
3665 return dev_err_probe(cs48l32_codec->core.dev, ret, "Failed to get IRQ\n");
3666
3667 return 0;
3668 }
3669
cs48l32_create_codec_component(struct cs48l32_codec * cs48l32_codec)3670 static int cs48l32_create_codec_component(struct cs48l32_codec *cs48l32_codec)
3671 {
3672 struct wm_adsp *dsp;
3673 int ret;
3674
3675 ASSERT_STRUCT_OFFSET(struct cs48l32_codec, dsp, 0);
3676 static_assert(ARRAY_SIZE(cs48l32_dai) == ARRAY_SIZE(cs48l32_codec->dai));
3677
3678 cs48l32_handle_properties(cs48l32_codec);
3679
3680 dsp = &cs48l32_codec->dsp;
3681 dsp->part = "cs48l32";
3682 dsp->cs_dsp.num = 1;
3683 dsp->cs_dsp.type = WMFW_HALO;
3684 dsp->cs_dsp.rev = 0;
3685 dsp->cs_dsp.dev = cs48l32_codec->core.dev;
3686 dsp->cs_dsp.regmap = cs48l32_codec->core.regmap;
3687 dsp->cs_dsp.base = CS48L32_DSP1_CLOCK_FREQ;
3688 dsp->cs_dsp.base_sysinfo = CS48L32_DSP1_SYS_INFO_ID;
3689 dsp->cs_dsp.mem = cs48l32_dsp1_regions;
3690 dsp->cs_dsp.num_mems = ARRAY_SIZE(cs48l32_dsp1_regions);
3691 dsp->pre_run = cs48l32_dsp_pre_run;
3692
3693 ret = wm_halo_init(dsp);
3694 if (ret != 0)
3695 return ret;
3696
3697 cs48l32_codec->fll.codec = cs48l32_codec;
3698 cs48l32_codec->fll.id = 1;
3699 cs48l32_codec->fll.base = CS48L32_FLL1_CONTROL1;
3700 cs48l32_codec->fll.sts_addr = CS48L32_IRQ1_STS_6;
3701 cs48l32_codec->fll.sts_mask = CS48L32_FLL1_LOCK_STS1_MASK;
3702 cs48l32_init_fll(&cs48l32_codec->fll);
3703
3704 ret = cs48l32_request_interrupt(cs48l32_codec);
3705 if (ret)
3706 goto err_dsp;
3707
3708 ret = devm_snd_soc_register_component(cs48l32_codec->core.dev,
3709 &cs48l32_soc_component_drv,
3710 cs48l32_dai,
3711 ARRAY_SIZE(cs48l32_dai));
3712 if (ret < 0) {
3713 dev_err_probe(cs48l32_codec->core.dev, ret, "Failed to register component\n");
3714 goto err_dsp;
3715 }
3716
3717 return 0;
3718
3719 err_dsp:
3720 wm_adsp2_remove(&cs48l32_codec->dsp);
3721
3722 return ret;
3723 }
3724
cs48l32_wait_for_boot(struct cs48l32 * cs48l32)3725 static int cs48l32_wait_for_boot(struct cs48l32 *cs48l32)
3726 {
3727 unsigned int val;
3728 int ret;
3729
3730 ret = regmap_read_poll_timeout(cs48l32->regmap, CS48L32_IRQ1_EINT_2, val,
3731 ((val < 0xffffffff) && (val & CS48L32_BOOT_DONE_EINT1_MASK)),
3732 1000, CS48L32_BOOT_TIMEOUT_US);
3733 if (ret) {
3734 dev_err(cs48l32->dev, "BOOT_DONE timed out\n");
3735 return -ETIMEDOUT;
3736 }
3737
3738 ret = regmap_read(cs48l32->regmap, CS48L32_MCU_CTRL1, &val);
3739 if (ret) {
3740 dev_err(cs48l32->dev, "Failed to read MCU_CTRL1: %d\n", ret);
3741 return ret;
3742 }
3743
3744 if (val & BIT(CS48L32_MCU_STS_SHIFT)) {
3745 dev_err(cs48l32->dev, "MCU boot failed\n");
3746 return -EIO;
3747 }
3748
3749 pm_runtime_mark_last_busy(cs48l32->dev);
3750
3751 return 0;
3752 }
3753
cs48l32_soft_reset(struct cs48l32 * cs48l32)3754 static int cs48l32_soft_reset(struct cs48l32 *cs48l32)
3755 {
3756 int ret;
3757
3758 ret = regmap_write(cs48l32->regmap, CS48L32_SFT_RESET, CS48L32_SFT_RESET_MAGIC);
3759 if (ret != 0) {
3760 dev_err(cs48l32->dev, "Failed to write soft reset: %d\n", ret);
3761 return ret;
3762 }
3763
3764 usleep_range(CS48L32_SOFT_RESET_US, CS48L32_SOFT_RESET_US + 1000);
3765
3766 return 0;
3767 }
3768
cs48l32_enable_hard_reset(struct cs48l32 * cs48l32)3769 static void cs48l32_enable_hard_reset(struct cs48l32 *cs48l32)
3770 {
3771 if (cs48l32->reset_gpio)
3772 gpiod_set_raw_value_cansleep(cs48l32->reset_gpio, 0);
3773 }
3774
cs48l32_disable_hard_reset(struct cs48l32 * cs48l32)3775 static void cs48l32_disable_hard_reset(struct cs48l32 *cs48l32)
3776 {
3777 if (cs48l32->reset_gpio) {
3778 gpiod_set_raw_value_cansleep(cs48l32->reset_gpio, 1);
3779 usleep_range(CS48L32_HARD_RESET_MIN_US, CS48L32_HARD_RESET_MIN_US + 1000);
3780 }
3781 }
3782
cs48l32_runtime_resume(struct device * dev)3783 static int cs48l32_runtime_resume(struct device *dev)
3784 {
3785 struct cs48l32_codec *cs48l32_codec = dev_get_drvdata(dev);
3786 struct cs48l32 *cs48l32 = &cs48l32_codec->core;
3787 unsigned int val;
3788 int ret;
3789
3790 ret = regulator_enable(cs48l32->vdd_d);
3791 if (ret) {
3792 dev_err(cs48l32->dev, "Failed to enable VDD_D: %d\n", ret);
3793 return ret;
3794 }
3795
3796 usleep_range(CS48L32_SOFT_RESET_US, CS48L32_SOFT_RESET_US + 1000);
3797
3798 regcache_cache_only(cs48l32->regmap, false);
3799
3800 ret = cs48l32_wait_for_boot(cs48l32);
3801 if (ret)
3802 goto err;
3803
3804 /* Check whether registers reset during suspend */
3805 regmap_read(cs48l32->regmap, CS48L32_CTRL_IF_DEBUG3, &val);
3806 if (!val)
3807 regcache_mark_dirty(cs48l32->regmap);
3808 else
3809 dev_dbg(cs48l32->dev, "Did not reset during suspend\n");
3810
3811 ret = regcache_sync(cs48l32->regmap);
3812 if (ret) {
3813 dev_err(cs48l32->dev, "Failed to restore register cache\n");
3814 goto err;
3815 }
3816
3817 return 0;
3818
3819 err:
3820 regcache_cache_only(cs48l32->regmap, true);
3821 regulator_disable(cs48l32->vdd_d);
3822
3823 return ret;
3824 }
3825
cs48l32_runtime_suspend(struct device * dev)3826 static int cs48l32_runtime_suspend(struct device *dev)
3827 {
3828 struct cs48l32_codec *cs48l32_codec = dev_get_drvdata(dev);
3829 struct cs48l32 *cs48l32 = &cs48l32_codec->core;
3830
3831 /* Flag to detect if the registers reset during suspend */
3832 regmap_write(cs48l32->regmap, CS48L32_CTRL_IF_DEBUG3, 1);
3833
3834 regcache_cache_only(cs48l32->regmap, true);
3835 regulator_disable(cs48l32->vdd_d);
3836
3837 return 0;
3838 }
3839
3840 static const struct dev_pm_ops cs48l32_pm_ops = {
3841 RUNTIME_PM_OPS(cs48l32_runtime_suspend, cs48l32_runtime_resume, NULL)
3842 };
3843
cs48l32_configure_clk32k(struct cs48l32 * cs48l32)3844 static int cs48l32_configure_clk32k(struct cs48l32 *cs48l32)
3845 {
3846 int ret = 0;
3847
3848 ret = clk_prepare_enable(cs48l32->mclk1);
3849 if (ret)
3850 return dev_err_probe(cs48l32->dev, ret, "Failed to enable 32k clock\n");
3851
3852 ret = regmap_update_bits(cs48l32->regmap, CS48L32_CLOCK32K,
3853 CS48L32_CLK_32K_EN_MASK | CS48L32_CLK_32K_SRC_MASK,
3854 CS48L32_CLK_32K_EN_MASK | CS48L32_32K_MCLK1);
3855 if (ret) {
3856 clk_disable_unprepare(cs48l32->mclk1);
3857 return dev_err_probe(cs48l32->dev, ret, "Failed to init 32k clock\n");
3858 }
3859
3860 return 0;
3861 }
3862
cs48l32_get_clocks(struct cs48l32 * cs48l32)3863 static int cs48l32_get_clocks(struct cs48l32 *cs48l32)
3864 {
3865 cs48l32->mclk1 = devm_clk_get_optional(cs48l32->dev, "mclk1");
3866 if (IS_ERR(cs48l32->mclk1))
3867 return dev_err_probe(cs48l32->dev, PTR_ERR(cs48l32->mclk1),
3868 "Failed to get mclk1\n");
3869
3870 return 0;
3871 }
3872
cs48l32_get_reset_gpio(struct cs48l32 * cs48l32)3873 static int cs48l32_get_reset_gpio(struct cs48l32 *cs48l32)
3874 {
3875 struct gpio_desc *reset;
3876
3877 reset = devm_gpiod_get_optional(cs48l32->dev, "reset", GPIOD_OUT_LOW);
3878 if (IS_ERR(reset))
3879 return dev_err_probe(cs48l32->dev, PTR_ERR(reset), "Failed to request /RESET\n");
3880
3881 /* ACPI can override the GPIOD_OUT_LOW so ensure it starts low */
3882 gpiod_set_raw_value_cansleep(reset, 0);
3883
3884 cs48l32->reset_gpio = reset;
3885
3886 return 0;
3887 }
3888
cs48l32_spi_probe(struct spi_device * spi)3889 static int cs48l32_spi_probe(struct spi_device *spi)
3890 {
3891 struct device *dev = &spi->dev;
3892 struct cs48l32_codec *cs48l32_codec;
3893 struct cs48l32 *cs48l32;
3894 unsigned int hwid, rev, otp_rev;
3895 int i, ret;
3896
3897 cs48l32_codec = devm_kzalloc(&spi->dev, sizeof(*cs48l32_codec), GFP_KERNEL);
3898 if (!cs48l32_codec)
3899 return -ENOMEM;
3900
3901 cs48l32 = &cs48l32_codec->core;
3902 cs48l32->dev = dev;
3903 cs48l32->irq = spi->irq;
3904 mutex_init(&cs48l32_codec->rate_lock);
3905 cs48l32_codec->in_vu_reg = CS48L32_INPUT_CONTROL3;
3906
3907 dev_set_drvdata(cs48l32->dev, cs48l32_codec);
3908
3909 ret = cs48l32_create_regmap(spi, cs48l32);
3910 if (ret)
3911 return dev_err_probe(&spi->dev, ret, "Failed to allocate regmap\n");
3912
3913 regcache_cache_only(cs48l32->regmap, true);
3914
3915 ret = cs48l32_get_reset_gpio(cs48l32);
3916 if (ret)
3917 return ret;
3918
3919 ret = cs48l32_get_clocks(cs48l32);
3920 if (ret)
3921 return ret;
3922
3923 static_assert(ARRAY_SIZE(cs48l32_core_supplies) == ARRAY_SIZE(cs48l32->core_supplies));
3924 for (i = 0; i < ARRAY_SIZE(cs48l32->core_supplies); i++)
3925 cs48l32->core_supplies[i].supply = cs48l32_core_supplies[i];
3926
3927 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs48l32->core_supplies),
3928 cs48l32->core_supplies);
3929 if (ret)
3930 return dev_err_probe(dev, ret, "Failed to request core supplies\n");
3931
3932 cs48l32->vdd_d = devm_regulator_get(cs48l32->dev, "vdd-d");
3933 if (IS_ERR(cs48l32->vdd_d))
3934 return dev_err_probe(dev, PTR_ERR(cs48l32->vdd_d), "Failed to request vdd-d\n");
3935
3936 ret = regulator_bulk_enable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies);
3937 if (ret)
3938 return dev_err_probe(dev, ret, "Failed to enable core supplies\n");
3939
3940 ret = regulator_enable(cs48l32->vdd_d);
3941 if (ret) {
3942 dev_err(dev, "Failed to enable vdd-d: %d\n", ret);
3943 goto err_enable;
3944 }
3945
3946 cs48l32_disable_hard_reset(cs48l32);
3947
3948 regcache_cache_only(cs48l32->regmap, false);
3949
3950 /* If we don't have a reset GPIO use a soft reset */
3951 if (!cs48l32->reset_gpio) {
3952 ret = cs48l32_soft_reset(cs48l32);
3953 if (ret)
3954 goto err_reset;
3955 }
3956
3957 ret = cs48l32_wait_for_boot(cs48l32);
3958 if (ret) {
3959 dev_err(cs48l32->dev, "Device failed initial boot: %d\n", ret);
3960 goto err_reset;
3961 }
3962
3963 ret = regmap_read(cs48l32->regmap, CS48L32_DEVID, &hwid);
3964 if (ret) {
3965 dev_err(dev, "Failed to read ID register: %d\n", ret);
3966 goto err_reset;
3967 }
3968 hwid &= CS48L32_DEVID_MASK;
3969
3970 switch (hwid) {
3971 case CS48L32_SILICON_ID:
3972 break;
3973 default:
3974 ret = -ENODEV;
3975 dev_err_probe(cs48l32->dev, ret, "Unknown device ID: %#x\n", hwid);
3976 goto err_reset;
3977 }
3978
3979 ret = regmap_read(cs48l32->regmap, CS48L32_REVID, &rev);
3980 if (ret) {
3981 dev_err(dev, "Failed to read revision register: %d\n", ret);
3982 goto err_reset;
3983 }
3984 rev &= CS48L32_AREVID_MASK | CS48L32_MTLREVID_MASK;
3985
3986 ret = regmap_read(cs48l32->regmap, CS48L32_OTPID, &otp_rev);
3987 if (ret) {
3988 dev_err(dev, "Failed to read OTP revision register: %d\n", ret);
3989 goto err_reset;
3990 }
3991 otp_rev &= CS48L32_OTPID_MASK;
3992
3993 dev_info(dev, "CS48L%x revision %X%u OTP%u\n", hwid & 0xff,
3994 rev >> CS48L32_AREVID_SHIFT, rev & CS48L32_MTLREVID_MASK, otp_rev);
3995
3996 /* Apply hardware patch */
3997 ret = cs48l32_apply_patch(cs48l32);
3998 if (ret) {
3999 dev_err(cs48l32->dev, "Failed to apply patch %d\n", ret);
4000 goto err_reset;
4001 }
4002
4003 /* BOOT_DONE interrupt is unmasked by default, so mask it */
4004 ret = regmap_set_bits(cs48l32->regmap, CS48L32_IRQ1_MASK_2, CS48L32_BOOT_DONE_EINT1_MASK);
4005
4006 ret = cs48l32_configure_clk32k(cs48l32);
4007 if (ret)
4008 goto err_reset;
4009
4010 pm_runtime_set_active(cs48l32->dev);
4011 pm_runtime_set_autosuspend_delay(cs48l32->dev, 100);
4012 pm_runtime_use_autosuspend(cs48l32->dev);
4013 pm_runtime_enable(cs48l32->dev);
4014
4015 ret = cs48l32_create_codec_component(cs48l32_codec);
4016 if (ret)
4017 goto err_clk32k;
4018
4019 return 0;
4020
4021 err_clk32k:
4022 clk_disable_unprepare(cs48l32->mclk1);
4023 err_reset:
4024 cs48l32_enable_hard_reset(cs48l32);
4025 regulator_disable(cs48l32->vdd_d);
4026 err_enable:
4027 regulator_bulk_disable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies);
4028
4029 return ret;
4030 }
4031
cs48l32_spi_remove(struct spi_device * spi)4032 static void cs48l32_spi_remove(struct spi_device *spi)
4033 {
4034 struct cs48l32_codec *cs48l32_codec = spi_get_drvdata(spi);
4035 struct cs48l32 *cs48l32 = &cs48l32_codec->core;
4036
4037 /* Remove IRQ handler before destroying anything else */
4038 if (cs48l32->irq >= 1)
4039 free_irq(cs48l32->irq, cs48l32_codec);
4040
4041 pm_runtime_disable(cs48l32->dev);
4042 regulator_disable(cs48l32->vdd_d);
4043 clk_disable_unprepare(cs48l32->mclk1);
4044 cs48l32_enable_hard_reset(cs48l32);
4045 regulator_bulk_disable(ARRAY_SIZE(cs48l32->core_supplies), cs48l32->core_supplies);
4046
4047 mutex_destroy(&cs48l32_codec->rate_lock);
4048 }
4049
4050 static const struct of_device_id cs48l32_of_match[] = {
4051 { .compatible = "cirrus,cs48l32", },
4052 {},
4053 };
4054
4055 static const struct spi_device_id cs48l32_spi_ids[] = {
4056 { "cs48l32", },
4057 { },
4058 };
4059 MODULE_DEVICE_TABLE(spi, cs48l32_spi_ids);
4060
4061 static struct spi_driver cs48l32_spi_driver = {
4062 .driver = {
4063 .name = "cs48l32",
4064 .pm = pm_ptr(&cs48l32_pm_ops),
4065 .of_match_table = cs48l32_of_match,
4066 },
4067 .probe = &cs48l32_spi_probe,
4068 .remove = &cs48l32_spi_remove,
4069 .id_table = cs48l32_spi_ids,
4070 };
4071 module_spi_driver(cs48l32_spi_driver);
4072
4073 MODULE_DESCRIPTION("CS48L32 ASoC codec driver");
4074 MODULE_AUTHOR("Stuart Henderson <stuarth@opensource.cirrus.com>");
4075 MODULE_AUTHOR("Piotr Stankiewicz <piotrs@opensource.cirrus.com>");
4076 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
4077 MODULE_LICENSE("GPL");
4078