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