xref: /linux/sound/soc/codecs/wm8958-dsp2.c (revision e5c91aac491def6ab3f90c4cc246e3fcb0f8f058)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * wm8958-dsp2.c  --  WM8958 DSP2 support
4  *
5  * Copyright 2011 Wolfson Microelectronics plc
6  *
7  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
8  */
9 
10 #include <linux/cleanup.h>
11 #include <linux/module.h>
12 #include <linux/moduleparam.h>
13 #include <linux/init.h>
14 #include <linux/delay.h>
15 #include <linux/pm.h>
16 #include <linux/i2c.h>
17 #include <linux/platform_device.h>
18 #include <linux/slab.h>
19 #include <sound/soc.h>
20 #include <sound/initval.h>
21 #include <sound/tlv.h>
22 #include <trace/events/asoc.h>
23 
24 #include <linux/mfd/wm8994/core.h>
25 #include <linux/mfd/wm8994/registers.h>
26 #include <linux/mfd/wm8994/pdata.h>
27 #include <linux/mfd/wm8994/gpio.h>
28 
29 #include <linux/unaligned.h>
30 
31 #include "wm8994.h"
32 
33 #define WM_FW_BLOCK_INFO 0xff
34 #define WM_FW_BLOCK_PM   0x00
35 #define WM_FW_BLOCK_X    0x01
36 #define WM_FW_BLOCK_Y    0x02
37 #define WM_FW_BLOCK_Z    0x03
38 #define WM_FW_BLOCK_I    0x06
39 #define WM_FW_BLOCK_A    0x08
40 #define WM_FW_BLOCK_C    0x0c
41 
42 static int wm8958_dsp2_fw(struct snd_soc_component *component, const char *name,
43 			  const struct firmware *fw, bool check)
44 {
45 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
46 	u64 data64;
47 	u32 data32;
48 	const u8 *data;
49 	char *str;
50 	size_t block_len, len;
51 	int ret = 0;
52 
53 	/* Suppress unneeded downloads */
54 	if (wm8994->cur_fw == fw)
55 		return 0;
56 
57 	if (fw->size < 32) {
58 		dev_err(component->dev, "%s: firmware too short (%zd bytes)\n",
59 			name, fw->size);
60 		goto err;
61 	}
62 
63 	if (memcmp(fw->data, "WMFW", 4) != 0) {
64 		data32 = get_unaligned_be32(fw->data);
65 		dev_err(component->dev, "%s: firmware has bad file magic %08x\n",
66 			name, data32);
67 		goto err;
68 	}
69 
70 	len = get_unaligned_be32(fw->data + 4);
71 	data32 = get_unaligned_be32(fw->data + 8);
72 
73 	if ((data32 >> 24) & 0xff) {
74 		dev_err(component->dev, "%s: unsupported firmware version %d\n",
75 			name, (data32 >> 24) & 0xff);
76 		goto err;
77 	}
78 	if ((data32 & 0xffff) != 8958) {
79 		dev_err(component->dev, "%s: unsupported target device %d\n",
80 			name, data32 & 0xffff);
81 		goto err;
82 	}
83 	if (((data32 >> 16) & 0xff) != 0xc) {
84 		dev_err(component->dev, "%s: unsupported target core %d\n",
85 			name, (data32 >> 16) & 0xff);
86 		goto err;
87 	}
88 
89 	if (check) {
90 		data64 = get_unaligned_be64(fw->data + 24);
91 		dev_info(component->dev, "%s timestamp %llx\n",  name, data64);
92 	} else {
93 		snd_soc_component_write(component, 0x102, 0x2);
94 		snd_soc_component_write(component, 0x900, 0x2);
95 	}
96 
97 	data = fw->data + len;
98 	len = fw->size - len;
99 	while (len) {
100 		if (len < 12) {
101 			dev_err(component->dev, "%s short data block of %zd\n",
102 				name, len);
103 			goto err;
104 		}
105 
106 		block_len = get_unaligned_be32(data + 4);
107 		if (block_len + 8 > len) {
108 			dev_err(component->dev, "%zd byte block longer than file\n",
109 				block_len);
110 			goto err;
111 		}
112 		if (block_len == 0) {
113 			dev_err(component->dev, "Zero length block\n");
114 			goto err;
115 		}
116 
117 		data32 = get_unaligned_be32(data);
118 
119 		switch ((data32 >> 24) & 0xff) {
120 		case WM_FW_BLOCK_INFO:
121 			/* Informational text */
122 			if (!check)
123 				break;
124 
125 			str = kzalloc(block_len + 1, GFP_KERNEL);
126 			if (str) {
127 				memcpy(str, data + 8, block_len);
128 				dev_info(component->dev, "%s: %s\n", name, str);
129 				kfree(str);
130 			} else {
131 				dev_err(component->dev, "Out of memory\n");
132 			}
133 			break;
134 		case WM_FW_BLOCK_PM:
135 		case WM_FW_BLOCK_X:
136 		case WM_FW_BLOCK_Y:
137 		case WM_FW_BLOCK_Z:
138 		case WM_FW_BLOCK_I:
139 		case WM_FW_BLOCK_A:
140 		case WM_FW_BLOCK_C:
141 			dev_dbg(component->dev, "%s: %zd bytes of %x@%x\n", name,
142 				block_len, (data32 >> 24) & 0xff,
143 				data32 & 0xffffff);
144 
145 			if (check)
146 				break;
147 
148 			data32 &= 0xffffff;
149 
150 			wm8994_bulk_write(wm8994->wm8994,
151 					  data32 & 0xffffff,
152 					  block_len / 2,
153 					  (void *)(data + 8));
154 
155 			break;
156 		default:
157 			dev_warn(component->dev, "%s: unknown block type %d\n",
158 				 name, (data32 >> 24) & 0xff);
159 			break;
160 		}
161 
162 		/* Round up to the next 32 bit word */
163 		block_len += block_len % 4;
164 
165 		data += block_len + 8;
166 		len -= block_len + 8;
167 	}
168 
169 	if (!check) {
170 		dev_dbg(component->dev, "%s: download done\n", name);
171 		wm8994->cur_fw = fw;
172 	} else {
173 		dev_info(component->dev, "%s: got firmware\n", name);
174 	}
175 
176 	goto ok;
177 
178 err:
179 	ret = -EINVAL;
180 ok:
181 	if (!check) {
182 		snd_soc_component_write(component, 0x900, 0x0);
183 		snd_soc_component_write(component, 0x102, 0x0);
184 	}
185 
186 	return ret;
187 }
188 
189 static void wm8958_dsp_start_mbc(struct snd_soc_component *component, int path)
190 {
191 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
192 	struct wm8994 *control = wm8994->wm8994;
193 	int i;
194 
195 	/* If the DSP is already running then noop */
196 	if (snd_soc_component_read(component, WM8958_DSP2_PROGRAM) & WM8958_DSP2_ENA)
197 		return;
198 
199 	/* If we have MBC firmware download it */
200 	if (wm8994->mbc)
201 		wm8958_dsp2_fw(component, "MBC", wm8994->mbc, false);
202 
203 	snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM,
204 			    WM8958_DSP2_ENA, WM8958_DSP2_ENA);
205 
206 	/* If we've got user supplied MBC settings use them */
207 	if (control->pdata.num_mbc_cfgs) {
208 		struct wm8958_mbc_cfg *cfg
209 			= &control->pdata.mbc_cfgs[wm8994->mbc_cfg];
210 
211 		for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
212 			snd_soc_component_write(component, i + WM8958_MBC_BAND_1_K_1,
213 				      cfg->coeff_regs[i]);
214 
215 		for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
216 			snd_soc_component_write(component,
217 				      i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
218 				      cfg->cutoff_regs[i]);
219 	}
220 
221 	/* Run the DSP */
222 	snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL,
223 		      WM8958_DSP2_RUNR);
224 
225 	/* And we're off! */
226 	snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG,
227 			    WM8958_MBC_ENA |
228 			    WM8958_MBC_SEL_MASK,
229 			    path << WM8958_MBC_SEL_SHIFT |
230 			    WM8958_MBC_ENA);
231 }
232 
233 static void wm8958_dsp_start_vss(struct snd_soc_component *component, int path)
234 {
235 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
236 	struct wm8994 *control = wm8994->wm8994;
237 	int i, ena;
238 
239 	if (wm8994->mbc_vss)
240 		wm8958_dsp2_fw(component, "MBC+VSS", wm8994->mbc_vss, false);
241 
242 	snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM,
243 			    WM8958_DSP2_ENA, WM8958_DSP2_ENA);
244 
245 	/* If we've got user supplied settings use them */
246 	if (control->pdata.num_mbc_cfgs) {
247 		struct wm8958_mbc_cfg *cfg
248 			= &control->pdata.mbc_cfgs[wm8994->mbc_cfg];
249 
250 		for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++)
251 			snd_soc_component_write(component, i + 0x2800,
252 				      cfg->combined_regs[i]);
253 	}
254 
255 	if (control->pdata.num_vss_cfgs) {
256 		struct wm8958_vss_cfg *cfg
257 			= &control->pdata.vss_cfgs[wm8994->vss_cfg];
258 
259 		for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
260 			snd_soc_component_write(component, i + 0x2600, cfg->regs[i]);
261 	}
262 
263 	if (control->pdata.num_vss_hpf_cfgs) {
264 		struct wm8958_vss_hpf_cfg *cfg
265 			= &control->pdata.vss_hpf_cfgs[wm8994->vss_hpf_cfg];
266 
267 		for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
268 			snd_soc_component_write(component, i + 0x2400, cfg->regs[i]);
269 	}
270 
271 	/* Run the DSP */
272 	snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL,
273 		      WM8958_DSP2_RUNR);
274 
275 	/* Enable the algorithms we've selected */
276 	ena = 0;
277 	if (wm8994->mbc_ena[path])
278 		ena |= 0x8;
279 	if (wm8994->hpf2_ena[path])
280 		ena |= 0x4;
281 	if (wm8994->hpf1_ena[path])
282 		ena |= 0x2;
283 	if (wm8994->vss_ena[path])
284 		ena |= 0x1;
285 
286 	snd_soc_component_write(component, 0x2201, ena);
287 
288 	/* Switch the DSP into the data path */
289 	snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG,
290 			    WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
291 			    path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
292 }
293 
294 static void wm8958_dsp_start_enh_eq(struct snd_soc_component *component, int path)
295 {
296 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
297 	struct wm8994 *control = wm8994->wm8994;
298 	int i;
299 
300 	wm8958_dsp2_fw(component, "ENH_EQ", wm8994->enh_eq, false);
301 
302 	snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM,
303 			    WM8958_DSP2_ENA, WM8958_DSP2_ENA);
304 
305 	/* If we've got user supplied settings use them */
306 	if (control->pdata.num_enh_eq_cfgs) {
307 		struct wm8958_enh_eq_cfg *cfg
308 			= &control->pdata.enh_eq_cfgs[wm8994->enh_eq_cfg];
309 
310 		for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
311 			snd_soc_component_write(component, i + 0x2200,
312 				      cfg->regs[i]);
313 	}
314 
315 	/* Run the DSP */
316 	snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL,
317 		      WM8958_DSP2_RUNR);
318 
319 	/* Switch the DSP into the data path */
320 	snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG,
321 			    WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
322 			    path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
323 }
324 
325 static void wm8958_dsp_apply(struct snd_soc_component *component, int path, int start)
326 {
327 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
328 	int pwr_reg = snd_soc_component_read(component, WM8994_POWER_MANAGEMENT_5);
329 	int ena, reg, aif;
330 
331 	switch (path) {
332 	case 0:
333 		pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
334 		aif = 0;
335 		break;
336 	case 1:
337 		pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
338 		aif = 0;
339 		break;
340 	case 2:
341 		pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
342 		aif = 1;
343 		break;
344 	default:
345 		WARN(1, "Invalid path %d\n", path);
346 		return;
347 	}
348 
349 	/* Do we have both an active AIF and an active algorithm? */
350 	ena = wm8994->mbc_ena[path] || wm8994->vss_ena[path] ||
351 		wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path] ||
352 		wm8994->enh_eq_ena[path];
353 	if (!pwr_reg)
354 		ena = 0;
355 
356 	reg = snd_soc_component_read(component, WM8958_DSP2_PROGRAM);
357 
358 	dev_dbg(component->dev, "DSP path %d %d startup: %d, power: %x, DSP: %x\n",
359 		path, wm8994->dsp_active, start, pwr_reg, reg);
360 
361 	if (start && ena) {
362 		/* If the DSP is already running then noop */
363 		if (reg & WM8958_DSP2_ENA)
364 			return;
365 
366 		/* If either AIFnCLK is not yet enabled postpone */
367 		if (!(snd_soc_component_read(component, WM8994_AIF1_CLOCKING_1)
368 		      & WM8994_AIF1CLK_ENA_MASK) &&
369 		    !(snd_soc_component_read(component, WM8994_AIF2_CLOCKING_1)
370 		      & WM8994_AIF2CLK_ENA_MASK))
371 			return;
372 
373 		/* Switch the clock over to the appropriate AIF */
374 		snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
375 				    WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
376 				    aif << WM8958_DSP2CLK_SRC_SHIFT |
377 				    WM8958_DSP2CLK_ENA);
378 
379 		if (wm8994->enh_eq_ena[path])
380 			wm8958_dsp_start_enh_eq(component, path);
381 		else if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] ||
382 		    wm8994->hpf2_ena[path])
383 			wm8958_dsp_start_vss(component, path);
384 		else if (wm8994->mbc_ena[path])
385 			wm8958_dsp_start_mbc(component, path);
386 
387 		wm8994->dsp_active = path;
388 
389 		dev_dbg(component->dev, "DSP running in path %d\n", path);
390 	}
391 
392 	if (!start && wm8994->dsp_active == path) {
393 		/* If the DSP is already stopped then noop */
394 		if (!(reg & WM8958_DSP2_ENA))
395 			return;
396 
397 		snd_soc_component_update_bits(component, WM8958_DSP2_CONFIG,
398 				    WM8958_MBC_ENA, 0);
399 		snd_soc_component_write(component, WM8958_DSP2_EXECCONTROL,
400 			      WM8958_DSP2_STOP);
401 		snd_soc_component_update_bits(component, WM8958_DSP2_PROGRAM,
402 				    WM8958_DSP2_ENA, 0);
403 		snd_soc_component_update_bits(component, WM8994_CLOCKING_1,
404 				    WM8958_DSP2CLK_ENA, 0);
405 
406 		wm8994->dsp_active = -1;
407 
408 		dev_dbg(component->dev, "DSP stopped\n");
409 	}
410 }
411 
412 int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
413 		  struct snd_kcontrol *kcontrol, int event)
414 {
415 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
416 	struct wm8994 *control = dev_get_drvdata(component->dev->parent);
417 	int i;
418 
419 	if (control->type != WM8958)
420 		return 0;
421 
422 	switch (event) {
423 	case SND_SOC_DAPM_POST_PMU:
424 	case SND_SOC_DAPM_PRE_PMU:
425 		for (i = 0; i < 3; i++)
426 			wm8958_dsp_apply(component, i, 1);
427 		break;
428 	case SND_SOC_DAPM_POST_PMD:
429 	case SND_SOC_DAPM_PRE_PMD:
430 		for (i = 0; i < 3; i++)
431 			wm8958_dsp_apply(component, i, 0);
432 		break;
433 	}
434 
435 	return 0;
436 }
437 
438 /* Check if DSP2 is in use on another AIF */
439 static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif)
440 {
441 	int i;
442 
443 	for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
444 		if (i == aif)
445 			continue;
446 		if (wm8994->mbc_ena[i] || wm8994->vss_ena[i] ||
447 		    wm8994->hpf1_ena[i] || wm8994->hpf2_ena[i])
448 			return 1;
449 	}
450 
451 	return 0;
452 }
453 
454 static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
455 			       struct snd_ctl_elem_value *ucontrol)
456 {
457 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
458 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
459 	struct wm8994 *control = wm8994->wm8994;
460 	int value = ucontrol->value.enumerated.item[0];
461 	int reg;
462 
463 	/* Don't allow on the fly reconfiguration */
464 	reg = snd_soc_component_read(component, WM8994_CLOCKING_1);
465 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
466 		return -EBUSY;
467 
468 	if (value >= control->pdata.num_mbc_cfgs)
469 		return -EINVAL;
470 
471 	wm8994->mbc_cfg = value;
472 
473 	return 0;
474 }
475 
476 static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
477 			       struct snd_ctl_elem_value *ucontrol)
478 {
479 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
480 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
481 
482 	ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
483 
484 	return 0;
485 }
486 
487 static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
488 			   struct snd_ctl_elem_info *uinfo)
489 {
490 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
491 	uinfo->count = 1;
492 	uinfo->value.integer.min = 0;
493 	uinfo->value.integer.max = 1;
494 	return 0;
495 }
496 
497 static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
498 			  struct snd_ctl_elem_value *ucontrol)
499 {
500 	int mbc = kcontrol->private_value;
501 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
502 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
503 
504 	ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
505 
506 	return 0;
507 }
508 
509 static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
510 			  struct snd_ctl_elem_value *ucontrol)
511 {
512 	int mbc = kcontrol->private_value;
513 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
514 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
515 
516 	if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0])
517 		return 0;
518 
519 	if (ucontrol->value.integer.value[0] > 1)
520 		return -EINVAL;
521 
522 	if (wm8958_dsp2_busy(wm8994, mbc)) {
523 		dev_dbg(component->dev, "DSP2 active on %d already\n", mbc);
524 		return -EBUSY;
525 	}
526 
527 	if (wm8994->enh_eq_ena[mbc])
528 		return -EBUSY;
529 
530 	wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
531 
532 	wm8958_dsp_apply(component, mbc, wm8994->mbc_ena[mbc]);
533 
534 	return 1;
535 }
536 
537 #define WM8958_MBC_SWITCH(xname, xval) {\
538 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
539 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
540 	.info = wm8958_mbc_info, \
541 	.get = wm8958_mbc_get, .put = wm8958_mbc_put, \
542 	.private_value = xval }
543 
544 static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol,
545 			       struct snd_ctl_elem_value *ucontrol)
546 {
547 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
548 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
549 	struct wm8994 *control = wm8994->wm8994;
550 	int value = ucontrol->value.enumerated.item[0];
551 	int reg;
552 
553 	/* Don't allow on the fly reconfiguration */
554 	reg = snd_soc_component_read(component, WM8994_CLOCKING_1);
555 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
556 		return -EBUSY;
557 
558 	if (value >= control->pdata.num_vss_cfgs)
559 		return -EINVAL;
560 
561 	wm8994->vss_cfg = value;
562 
563 	return 0;
564 }
565 
566 static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol,
567 			       struct snd_ctl_elem_value *ucontrol)
568 {
569 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
570 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
571 
572 	ucontrol->value.enumerated.item[0] = wm8994->vss_cfg;
573 
574 	return 0;
575 }
576 
577 static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol,
578 				   struct snd_ctl_elem_value *ucontrol)
579 {
580 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
581 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
582 	struct wm8994 *control = wm8994->wm8994;
583 	int value = ucontrol->value.enumerated.item[0];
584 	int reg;
585 
586 	/* Don't allow on the fly reconfiguration */
587 	reg = snd_soc_component_read(component, WM8994_CLOCKING_1);
588 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
589 		return -EBUSY;
590 
591 	if (value >= control->pdata.num_vss_hpf_cfgs)
592 		return -EINVAL;
593 
594 	wm8994->vss_hpf_cfg = value;
595 
596 	return 0;
597 }
598 
599 static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol,
600 				   struct snd_ctl_elem_value *ucontrol)
601 {
602 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
603 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
604 
605 	ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg;
606 
607 	return 0;
608 }
609 
610 static int wm8958_vss_info(struct snd_kcontrol *kcontrol,
611 			   struct snd_ctl_elem_info *uinfo)
612 {
613 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
614 	uinfo->count = 1;
615 	uinfo->value.integer.min = 0;
616 	uinfo->value.integer.max = 1;
617 	return 0;
618 }
619 
620 static int wm8958_vss_get(struct snd_kcontrol *kcontrol,
621 			  struct snd_ctl_elem_value *ucontrol)
622 {
623 	int vss = kcontrol->private_value;
624 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
625 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
626 
627 	ucontrol->value.integer.value[0] = wm8994->vss_ena[vss];
628 
629 	return 0;
630 }
631 
632 static int wm8958_vss_put(struct snd_kcontrol *kcontrol,
633 			  struct snd_ctl_elem_value *ucontrol)
634 {
635 	int vss = kcontrol->private_value;
636 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
637 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
638 
639 	if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0])
640 		return 0;
641 
642 	if (ucontrol->value.integer.value[0] > 1)
643 		return -EINVAL;
644 
645 	if (!wm8994->mbc_vss)
646 		return -ENODEV;
647 
648 	if (wm8958_dsp2_busy(wm8994, vss)) {
649 		dev_dbg(component->dev, "DSP2 active on %d already\n", vss);
650 		return -EBUSY;
651 	}
652 
653 	if (wm8994->enh_eq_ena[vss])
654 		return -EBUSY;
655 
656 	wm8994->vss_ena[vss] = ucontrol->value.integer.value[0];
657 
658 	wm8958_dsp_apply(component, vss, wm8994->vss_ena[vss]);
659 
660 	return 1;
661 }
662 
663 
664 #define WM8958_VSS_SWITCH(xname, xval) {\
665 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
666 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
667 	.info = wm8958_vss_info, \
668 	.get = wm8958_vss_get, .put = wm8958_vss_put, \
669 	.private_value = xval }
670 
671 static int wm8958_hpf_info(struct snd_kcontrol *kcontrol,
672 			   struct snd_ctl_elem_info *uinfo)
673 {
674 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
675 	uinfo->count = 1;
676 	uinfo->value.integer.min = 0;
677 	uinfo->value.integer.max = 1;
678 	return 0;
679 }
680 
681 static int wm8958_hpf_get(struct snd_kcontrol *kcontrol,
682 			  struct snd_ctl_elem_value *ucontrol)
683 {
684 	int hpf = kcontrol->private_value;
685 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
686 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
687 
688 	if (hpf < 3)
689 		ucontrol->value.integer.value[0] = wm8994->hpf1_ena[hpf % 3];
690 	else
691 		ucontrol->value.integer.value[0] = wm8994->hpf2_ena[hpf % 3];
692 
693 	return 0;
694 }
695 
696 static int wm8958_hpf_put(struct snd_kcontrol *kcontrol,
697 			  struct snd_ctl_elem_value *ucontrol)
698 {
699 	int hpf = kcontrol->private_value;
700 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
701 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
702 
703 	if (hpf < 3) {
704 		if (wm8994->hpf1_ena[hpf % 3] ==
705 		    ucontrol->value.integer.value[0])
706 			return 0;
707 	} else {
708 		if (wm8994->hpf2_ena[hpf % 3] ==
709 		    ucontrol->value.integer.value[0])
710 			return 0;
711 	}
712 
713 	if (ucontrol->value.integer.value[0] > 1)
714 		return -EINVAL;
715 
716 	if (!wm8994->mbc_vss)
717 		return -ENODEV;
718 
719 	if (wm8958_dsp2_busy(wm8994, hpf % 3)) {
720 		dev_dbg(component->dev, "DSP2 active on %d already\n", hpf);
721 		return -EBUSY;
722 	}
723 
724 	if (wm8994->enh_eq_ena[hpf % 3])
725 		return -EBUSY;
726 
727 	if (hpf < 3)
728 		wm8994->hpf1_ena[hpf % 3] = ucontrol->value.integer.value[0];
729 	else
730 		wm8994->hpf2_ena[hpf % 3] = ucontrol->value.integer.value[0];
731 
732 	wm8958_dsp_apply(component, hpf % 3, ucontrol->value.integer.value[0]);
733 
734 	return 1;
735 }
736 
737 #define WM8958_HPF_SWITCH(xname, xval) {\
738 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
739 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
740 	.info = wm8958_hpf_info, \
741 	.get = wm8958_hpf_get, .put = wm8958_hpf_put, \
742 	.private_value = xval }
743 
744 static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol,
745 				  struct snd_ctl_elem_value *ucontrol)
746 {
747 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
748 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
749 	struct wm8994 *control = wm8994->wm8994;
750 	int value = ucontrol->value.enumerated.item[0];
751 	int reg;
752 
753 	/* Don't allow on the fly reconfiguration */
754 	reg = snd_soc_component_read(component, WM8994_CLOCKING_1);
755 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
756 		return -EBUSY;
757 
758 	if (value >= control->pdata.num_enh_eq_cfgs)
759 		return -EINVAL;
760 
761 	wm8994->enh_eq_cfg = value;
762 
763 	return 0;
764 }
765 
766 static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol,
767 				  struct snd_ctl_elem_value *ucontrol)
768 {
769 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
770 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
771 
772 	ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg;
773 
774 	return 0;
775 }
776 
777 static int wm8958_enh_eq_info(struct snd_kcontrol *kcontrol,
778 			   struct snd_ctl_elem_info *uinfo)
779 {
780 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
781 	uinfo->count = 1;
782 	uinfo->value.integer.min = 0;
783 	uinfo->value.integer.max = 1;
784 	return 0;
785 }
786 
787 static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol,
788 			  struct snd_ctl_elem_value *ucontrol)
789 {
790 	int eq = kcontrol->private_value;
791 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
792 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
793 
794 	ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq];
795 
796 	return 0;
797 }
798 
799 static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol,
800 			  struct snd_ctl_elem_value *ucontrol)
801 {
802 	int eq = kcontrol->private_value;
803 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
804 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
805 
806 	if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0])
807 		return 0;
808 
809 	if (ucontrol->value.integer.value[0] > 1)
810 		return -EINVAL;
811 
812 	if (!wm8994->enh_eq)
813 		return -ENODEV;
814 
815 	if (wm8958_dsp2_busy(wm8994, eq)) {
816 		dev_dbg(component->dev, "DSP2 active on %d already\n", eq);
817 		return -EBUSY;
818 	}
819 
820 	if (wm8994->mbc_ena[eq] || wm8994->vss_ena[eq] ||
821 	    wm8994->hpf1_ena[eq] || wm8994->hpf2_ena[eq])
822 		return -EBUSY;
823 
824 	wm8994->enh_eq_ena[eq] = ucontrol->value.integer.value[0];
825 
826 	wm8958_dsp_apply(component, eq, ucontrol->value.integer.value[0]);
827 
828 	return 1;
829 }
830 
831 #define WM8958_ENH_EQ_SWITCH(xname, xval) {\
832 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
833 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
834 	.info = wm8958_enh_eq_info, \
835 	.get = wm8958_enh_eq_get, .put = wm8958_enh_eq_put, \
836 	.private_value = xval }
837 
838 static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = {
839 WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
840 WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
841 WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
842 };
843 
844 static const struct snd_kcontrol_new wm8958_vss_snd_controls[] = {
845 WM8958_VSS_SWITCH("AIF1DAC1 VSS Switch", 0),
846 WM8958_VSS_SWITCH("AIF1DAC2 VSS Switch", 1),
847 WM8958_VSS_SWITCH("AIF2DAC VSS Switch", 2),
848 WM8958_HPF_SWITCH("AIF1DAC1 HPF1 Switch", 0),
849 WM8958_HPF_SWITCH("AIF1DAC2 HPF1 Switch", 1),
850 WM8958_HPF_SWITCH("AIF2DAC HPF1 Switch", 2),
851 WM8958_HPF_SWITCH("AIF1DAC1 HPF2 Switch", 3),
852 WM8958_HPF_SWITCH("AIF1DAC2 HPF2 Switch", 4),
853 WM8958_HPF_SWITCH("AIF2DAC HPF2 Switch", 5),
854 };
855 
856 static const struct snd_kcontrol_new wm8958_enh_eq_snd_controls[] = {
857 WM8958_ENH_EQ_SWITCH("AIF1DAC1 Enhanced EQ Switch", 0),
858 WM8958_ENH_EQ_SWITCH("AIF1DAC2 Enhanced EQ Switch", 1),
859 WM8958_ENH_EQ_SWITCH("AIF2DAC Enhanced EQ Switch", 2),
860 };
861 
862 static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context)
863 {
864 	struct snd_soc_component *component = context;
865 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
866 
867 	if (fw && (wm8958_dsp2_fw(component, "ENH_EQ", fw, true) == 0)) {
868 		guard(mutex)(&wm8994->fw_lock);
869 		wm8994->enh_eq = fw;
870 	}
871 }
872 
873 static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context)
874 {
875 	struct snd_soc_component *component = context;
876 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
877 
878 	if (fw && (wm8958_dsp2_fw(component, "MBC+VSS", fw, true) == 0)) {
879 		guard(mutex)(&wm8994->fw_lock);
880 		wm8994->mbc_vss = fw;
881 	}
882 }
883 
884 static void wm8958_mbc_loaded(const struct firmware *fw, void *context)
885 {
886 	struct snd_soc_component *component = context;
887 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
888 
889 	if (fw && (wm8958_dsp2_fw(component, "MBC", fw, true) == 0)) {
890 		guard(mutex)(&wm8994->fw_lock);
891 		wm8994->mbc = fw;
892 	}
893 }
894 
895 void wm8958_dsp2_init(struct snd_soc_component *component)
896 {
897 	struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
898 	struct wm8994 *control = wm8994->wm8994;
899 	struct wm8994_pdata *pdata = &control->pdata;
900 	int ret, i;
901 
902 	wm8994->dsp_active = -1;
903 
904 	snd_soc_add_component_controls(component, wm8958_mbc_snd_controls,
905 			     ARRAY_SIZE(wm8958_mbc_snd_controls));
906 	snd_soc_add_component_controls(component, wm8958_vss_snd_controls,
907 			     ARRAY_SIZE(wm8958_vss_snd_controls));
908 	snd_soc_add_component_controls(component, wm8958_enh_eq_snd_controls,
909 			     ARRAY_SIZE(wm8958_enh_eq_snd_controls));
910 
911 
912 	/* We don't *require* firmware and don't want to delay boot */
913 	request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
914 				"wm8958_mbc.wfw", component->dev, GFP_KERNEL,
915 				component, wm8958_mbc_loaded);
916 	request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
917 				"wm8958_mbc_vss.wfw", component->dev, GFP_KERNEL,
918 				component, wm8958_mbc_vss_loaded);
919 	request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
920 				"wm8958_enh_eq.wfw", component->dev, GFP_KERNEL,
921 				component, wm8958_enh_eq_loaded);
922 
923 	if (pdata->num_mbc_cfgs) {
924 		struct snd_kcontrol_new mbc_control[] = {
925 			SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
926 				     wm8958_get_mbc_enum, wm8958_put_mbc_enum),
927 		};
928 
929 		/* We need an array of texts for the enum API */
930 		wm8994->mbc_texts = kmalloc_array(pdata->num_mbc_cfgs,
931 						  sizeof(char *),
932 						  GFP_KERNEL);
933 		if (!wm8994->mbc_texts)
934 			return;
935 
936 		for (i = 0; i < pdata->num_mbc_cfgs; i++)
937 			wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
938 
939 		wm8994->mbc_enum.items = pdata->num_mbc_cfgs;
940 		wm8994->mbc_enum.texts = wm8994->mbc_texts;
941 
942 		ret = snd_soc_add_component_controls(wm8994->hubs.component,
943 						 mbc_control, 1);
944 		if (ret != 0)
945 			dev_err(wm8994->hubs.component->dev,
946 				"Failed to add MBC mode controls: %d\n", ret);
947 	}
948 
949 	if (pdata->num_vss_cfgs) {
950 		struct snd_kcontrol_new vss_control[] = {
951 			SOC_ENUM_EXT("VSS Mode", wm8994->vss_enum,
952 				     wm8958_get_vss_enum, wm8958_put_vss_enum),
953 		};
954 
955 		/* We need an array of texts for the enum API */
956 		wm8994->vss_texts = kmalloc_array(pdata->num_vss_cfgs,
957 						  sizeof(char *),
958 						  GFP_KERNEL);
959 		if (!wm8994->vss_texts)
960 			return;
961 
962 		for (i = 0; i < pdata->num_vss_cfgs; i++)
963 			wm8994->vss_texts[i] = pdata->vss_cfgs[i].name;
964 
965 		wm8994->vss_enum.items = pdata->num_vss_cfgs;
966 		wm8994->vss_enum.texts = wm8994->vss_texts;
967 
968 		ret = snd_soc_add_component_controls(wm8994->hubs.component,
969 						 vss_control, 1);
970 		if (ret != 0)
971 			dev_err(wm8994->hubs.component->dev,
972 				"Failed to add VSS mode controls: %d\n", ret);
973 	}
974 
975 	if (pdata->num_vss_hpf_cfgs) {
976 		struct snd_kcontrol_new hpf_control[] = {
977 			SOC_ENUM_EXT("VSS HPF Mode", wm8994->vss_hpf_enum,
978 				     wm8958_get_vss_hpf_enum,
979 				     wm8958_put_vss_hpf_enum),
980 		};
981 
982 		/* We need an array of texts for the enum API */
983 		wm8994->vss_hpf_texts = kmalloc_array(pdata->num_vss_hpf_cfgs,
984 						      sizeof(char *),
985 						      GFP_KERNEL);
986 		if (!wm8994->vss_hpf_texts)
987 			return;
988 
989 		for (i = 0; i < pdata->num_vss_hpf_cfgs; i++)
990 			wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name;
991 
992 		wm8994->vss_hpf_enum.items = pdata->num_vss_hpf_cfgs;
993 		wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
994 
995 		ret = snd_soc_add_component_controls(wm8994->hubs.component,
996 						 hpf_control, 1);
997 		if (ret != 0)
998 			dev_err(wm8994->hubs.component->dev,
999 				"Failed to add VSS HPFmode controls: %d\n",
1000 				ret);
1001 	}
1002 
1003 	if (pdata->num_enh_eq_cfgs) {
1004 		struct snd_kcontrol_new eq_control[] = {
1005 			SOC_ENUM_EXT("Enhanced EQ Mode", wm8994->enh_eq_enum,
1006 				     wm8958_get_enh_eq_enum,
1007 				     wm8958_put_enh_eq_enum),
1008 		};
1009 
1010 		/* We need an array of texts for the enum API */
1011 		wm8994->enh_eq_texts = kmalloc_array(pdata->num_enh_eq_cfgs,
1012 						     sizeof(char *),
1013 						     GFP_KERNEL);
1014 		if (!wm8994->enh_eq_texts)
1015 			return;
1016 
1017 		for (i = 0; i < pdata->num_enh_eq_cfgs; i++)
1018 			wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name;
1019 
1020 		wm8994->enh_eq_enum.items = pdata->num_enh_eq_cfgs;
1021 		wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
1022 
1023 		ret = snd_soc_add_component_controls(wm8994->hubs.component,
1024 						 eq_control, 1);
1025 		if (ret != 0)
1026 			dev_err(wm8994->hubs.component->dev,
1027 				"Failed to add enhanced EQ controls: %d\n",
1028 				ret);
1029 	}
1030 }
1031