Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / sound / soc / codecs / madera.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Cirrus Logic Madera class codecs common support
4 //
5 // Copyright (C) 2015-2019 Cirrus Logic, Inc. and
6 //                         Cirrus Logic International Semiconductor Ltd.
7 //
8
9 #include <linux/delay.h>
10 #include <linux/gcd.h>
11 #include <linux/module.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/slab.h>
14 #include <sound/pcm.h>
15 #include <sound/pcm_params.h>
16 #include <sound/tlv.h>
17
18 #include <linux/irqchip/irq-madera.h>
19 #include <linux/mfd/madera/core.h>
20 #include <linux/mfd/madera/registers.h>
21 #include <linux/mfd/madera/pdata.h>
22 #include <sound/madera-pdata.h>
23
24 #include <dt-bindings/sound/madera.h>
25
26 #include "madera.h"
27
28 #define MADERA_AIF_BCLK_CTRL                    0x00
29 #define MADERA_AIF_TX_PIN_CTRL                  0x01
30 #define MADERA_AIF_RX_PIN_CTRL                  0x02
31 #define MADERA_AIF_RATE_CTRL                    0x03
32 #define MADERA_AIF_FORMAT                       0x04
33 #define MADERA_AIF_RX_BCLK_RATE                 0x06
34 #define MADERA_AIF_FRAME_CTRL_1                 0x07
35 #define MADERA_AIF_FRAME_CTRL_2                 0x08
36 #define MADERA_AIF_FRAME_CTRL_3                 0x09
37 #define MADERA_AIF_FRAME_CTRL_4                 0x0A
38 #define MADERA_AIF_FRAME_CTRL_5                 0x0B
39 #define MADERA_AIF_FRAME_CTRL_6                 0x0C
40 #define MADERA_AIF_FRAME_CTRL_7                 0x0D
41 #define MADERA_AIF_FRAME_CTRL_8                 0x0E
42 #define MADERA_AIF_FRAME_CTRL_9                 0x0F
43 #define MADERA_AIF_FRAME_CTRL_10                0x10
44 #define MADERA_AIF_FRAME_CTRL_11                0x11
45 #define MADERA_AIF_FRAME_CTRL_12                0x12
46 #define MADERA_AIF_FRAME_CTRL_13                0x13
47 #define MADERA_AIF_FRAME_CTRL_14                0x14
48 #define MADERA_AIF_FRAME_CTRL_15                0x15
49 #define MADERA_AIF_FRAME_CTRL_16                0x16
50 #define MADERA_AIF_FRAME_CTRL_17                0x17
51 #define MADERA_AIF_FRAME_CTRL_18                0x18
52 #define MADERA_AIF_TX_ENABLES                   0x19
53 #define MADERA_AIF_RX_ENABLES                   0x1A
54 #define MADERA_AIF_FORCE_WRITE                  0x1B
55
56 #define MADERA_DSP_CONFIG_1_OFFS                0x00
57 #define MADERA_DSP_CONFIG_2_OFFS                0x02
58
59 #define MADERA_DSP_CLK_SEL_MASK                 0x70000
60 #define MADERA_DSP_CLK_SEL_SHIFT                16
61
62 #define MADERA_DSP_RATE_MASK                    0x7800
63 #define MADERA_DSP_RATE_SHIFT                   11
64
65 #define MADERA_SYSCLK_6MHZ                      0
66 #define MADERA_SYSCLK_12MHZ                     1
67 #define MADERA_SYSCLK_24MHZ                     2
68 #define MADERA_SYSCLK_49MHZ                     3
69 #define MADERA_SYSCLK_98MHZ                     4
70
71 #define MADERA_DSPCLK_9MHZ                      0
72 #define MADERA_DSPCLK_18MHZ                     1
73 #define MADERA_DSPCLK_36MHZ                     2
74 #define MADERA_DSPCLK_73MHZ                     3
75 #define MADERA_DSPCLK_147MHZ                    4
76
77 #define MADERA_FLL_VCO_CORNER                   141900000
78 #define MADERA_FLL_MAX_FREF                     13500000
79 #define MADERA_FLL_MAX_N                        1023
80 #define MADERA_FLL_MIN_FOUT                     90000000
81 #define MADERA_FLL_MAX_FOUT                     100000000
82 #define MADERA_FLL_MAX_FRATIO                   16
83 #define MADERA_FLL_MAX_REFDIV                   8
84 #define MADERA_FLL_OUTDIV                       3
85 #define MADERA_FLL_VCO_MULT                     3
86 #define MADERA_FLLAO_MAX_FREF                   12288000
87 #define MADERA_FLLAO_MIN_N                      4
88 #define MADERA_FLLAO_MAX_N                      1023
89 #define MADERA_FLLAO_MAX_FBDIV                  254
90
91 #define MADERA_FLL_SYNCHRONISER_OFFS            0x10
92 #define CS47L35_FLL_SYNCHRONISER_OFFS           0xE
93 #define MADERA_FLL_CONTROL_1_OFFS               0x1
94 #define MADERA_FLL_CONTROL_2_OFFS               0x2
95 #define MADERA_FLL_CONTROL_3_OFFS               0x3
96 #define MADERA_FLL_CONTROL_4_OFFS               0x4
97 #define MADERA_FLL_CONTROL_5_OFFS               0x5
98 #define MADERA_FLL_CONTROL_6_OFFS               0x6
99 #define MADERA_FLL_CONTROL_7_OFFS               0x9
100 #define MADERA_FLL_EFS_2_OFFS                   0xA
101 #define MADERA_FLL_SYNCHRONISER_1_OFFS          0x1
102 #define MADERA_FLL_SYNCHRONISER_2_OFFS          0x2
103 #define MADERA_FLL_SYNCHRONISER_3_OFFS          0x3
104 #define MADERA_FLL_SYNCHRONISER_4_OFFS          0x4
105 #define MADERA_FLL_SYNCHRONISER_5_OFFS          0x5
106 #define MADERA_FLL_SYNCHRONISER_6_OFFS          0x6
107 #define MADERA_FLL_SYNCHRONISER_7_OFFS          0x7
108 #define MADERA_FLL_SPREAD_SPECTRUM_OFFS         0x9
109 #define MADERA_FLL_GPIO_CLOCK_OFFS              0xA
110
111 #define MADERA_FLLAO_CONTROL_1_OFFS             0x1
112 #define MADERA_FLLAO_CONTROL_2_OFFS             0x2
113 #define MADERA_FLLAO_CONTROL_3_OFFS             0x3
114 #define MADERA_FLLAO_CONTROL_4_OFFS             0x4
115 #define MADERA_FLLAO_CONTROL_5_OFFS             0x5
116 #define MADERA_FLLAO_CONTROL_6_OFFS             0x6
117 #define MADERA_FLLAO_CONTROL_7_OFFS             0x8
118 #define MADERA_FLLAO_CONTROL_8_OFFS             0xA
119 #define MADERA_FLLAO_CONTROL_9_OFFS             0xB
120 #define MADERA_FLLAO_CONTROL_10_OFFS            0xC
121 #define MADERA_FLLAO_CONTROL_11_OFFS            0xD
122
123 #define MADERA_FMT_DSP_MODE_A                   0
124 #define MADERA_FMT_DSP_MODE_B                   1
125 #define MADERA_FMT_I2S_MODE                     2
126 #define MADERA_FMT_LEFT_JUSTIFIED_MODE          3
127
128 #define madera_fll_err(_fll, fmt, ...) \
129         dev_err(_fll->madera->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
130 #define madera_fll_warn(_fll, fmt, ...) \
131         dev_warn(_fll->madera->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
132 #define madera_fll_dbg(_fll, fmt, ...) \
133         dev_dbg(_fll->madera->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
134
135 #define madera_aif_err(_dai, fmt, ...) \
136         dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
137 #define madera_aif_warn(_dai, fmt, ...) \
138         dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
139 #define madera_aif_dbg(_dai, fmt, ...) \
140         dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
141
142 static const int madera_dsp_bus_error_irqs[MADERA_MAX_ADSP] = {
143         MADERA_IRQ_DSP1_BUS_ERR,
144         MADERA_IRQ_DSP2_BUS_ERR,
145         MADERA_IRQ_DSP3_BUS_ERR,
146         MADERA_IRQ_DSP4_BUS_ERR,
147         MADERA_IRQ_DSP5_BUS_ERR,
148         MADERA_IRQ_DSP6_BUS_ERR,
149         MADERA_IRQ_DSP7_BUS_ERR,
150 };
151
152 static void madera_spin_sysclk(struct madera_priv *priv)
153 {
154         struct madera *madera = priv->madera;
155         unsigned int val;
156         int ret, i;
157
158         /* Skip this if the chip is down */
159         if (pm_runtime_suspended(madera->dev))
160                 return;
161
162         /*
163          * Just read a register a few times to ensure the internal
164          * oscillator sends out a few clocks.
165          */
166         for (i = 0; i < 4; i++) {
167                 ret = regmap_read(madera->regmap, MADERA_SOFTWARE_RESET, &val);
168                 if (ret)
169                         dev_err(madera->dev,
170                                 "Failed to read sysclk spin %d: %d\n", i, ret);
171         }
172
173         udelay(300);
174 }
175
176 int madera_sysclk_ev(struct snd_soc_dapm_widget *w,
177                      struct snd_kcontrol *kcontrol, int event)
178 {
179         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
180         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
181
182         madera_spin_sysclk(priv);
183
184         return 0;
185 }
186 EXPORT_SYMBOL_GPL(madera_sysclk_ev);
187
188 static int madera_check_speaker_overheat(struct madera *madera,
189                                          bool *warn, bool *shutdown)
190 {
191         unsigned int val;
192         int ret;
193
194         ret = regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_15, &val);
195         if (ret) {
196                 dev_err(madera->dev, "Failed to read thermal status: %d\n",
197                         ret);
198                 return ret;
199         }
200
201         *warn = val & MADERA_SPK_OVERHEAT_WARN_STS1;
202         *shutdown = val & MADERA_SPK_OVERHEAT_STS1;
203
204         return 0;
205 }
206
207 int madera_spk_ev(struct snd_soc_dapm_widget *w,
208                   struct snd_kcontrol *kcontrol, int event)
209 {
210         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
211         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
212         struct madera *madera = priv->madera;
213         bool warn, shutdown;
214         int ret;
215
216         switch (event) {
217         case SND_SOC_DAPM_POST_PMU:
218                 ret = madera_check_speaker_overheat(madera, &warn, &shutdown);
219                 if (ret)
220                         return ret;
221
222                 if (shutdown) {
223                         dev_crit(madera->dev,
224                                  "Speaker not enabled due to temperature\n");
225                         return -EBUSY;
226                 }
227
228                 regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1,
229                                    1 << w->shift, 1 << w->shift);
230                 break;
231         case SND_SOC_DAPM_PRE_PMD:
232                 regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1,
233                                    1 << w->shift, 0);
234                 break;
235         default:
236                 break;
237         }
238
239         return 0;
240 }
241 EXPORT_SYMBOL_GPL(madera_spk_ev);
242
243 static irqreturn_t madera_thermal_warn(int irq, void *data)
244 {
245         struct madera *madera = data;
246         bool warn, shutdown;
247         int ret;
248
249         ret = madera_check_speaker_overheat(madera, &warn, &shutdown);
250         if (ret || shutdown) { /* for safety attempt to shutdown on error */
251                 dev_crit(madera->dev, "Thermal shutdown\n");
252                 ret = regmap_update_bits(madera->regmap,
253                                          MADERA_OUTPUT_ENABLES_1,
254                                          MADERA_OUT4L_ENA |
255                                          MADERA_OUT4R_ENA, 0);
256                 if (ret != 0)
257                         dev_crit(madera->dev,
258                                  "Failed to disable speaker outputs: %d\n",
259                                  ret);
260         } else if (warn) {
261                 dev_alert(madera->dev, "Thermal warning\n");
262         } else {
263                 dev_info(madera->dev, "Spurious thermal warning\n");
264                 return IRQ_NONE;
265         }
266
267         return IRQ_HANDLED;
268 }
269
270 int madera_init_overheat(struct madera_priv *priv)
271 {
272         struct madera *madera = priv->madera;
273         struct device *dev = madera->dev;
274         int ret;
275
276         ret = madera_request_irq(madera, MADERA_IRQ_SPK_OVERHEAT_WARN,
277                                  "Thermal warning", madera_thermal_warn,
278                                  madera);
279         if (ret)
280                 dev_err(dev, "Failed to get thermal warning IRQ: %d\n", ret);
281
282         ret = madera_request_irq(madera, MADERA_IRQ_SPK_OVERHEAT,
283                                  "Thermal shutdown", madera_thermal_warn,
284                                  madera);
285         if (ret)
286                 dev_err(dev, "Failed to get thermal shutdown IRQ: %d\n", ret);
287
288         return 0;
289 }
290 EXPORT_SYMBOL_GPL(madera_init_overheat);
291
292 int madera_free_overheat(struct madera_priv *priv)
293 {
294         struct madera *madera = priv->madera;
295
296         madera_free_irq(madera, MADERA_IRQ_SPK_OVERHEAT_WARN, madera);
297         madera_free_irq(madera, MADERA_IRQ_SPK_OVERHEAT, madera);
298
299         return 0;
300 }
301 EXPORT_SYMBOL_GPL(madera_free_overheat);
302
303 int madera_core_init(struct madera_priv *priv)
304 {
305         int i;
306
307         /* trap undersized array initializers */
308         BUILD_BUG_ON(!madera_mixer_texts[MADERA_NUM_MIXER_INPUTS - 1]);
309         BUILD_BUG_ON(!madera_mixer_values[MADERA_NUM_MIXER_INPUTS - 1]);
310
311         mutex_init(&priv->rate_lock);
312
313         for (i = 0; i < MADERA_MAX_HP_OUTPUT; i++)
314                 priv->madera->out_clamp[i] = true;
315
316         return 0;
317 }
318 EXPORT_SYMBOL_GPL(madera_core_init);
319
320 int madera_core_free(struct madera_priv *priv)
321 {
322         mutex_destroy(&priv->rate_lock);
323
324         return 0;
325 }
326 EXPORT_SYMBOL_GPL(madera_core_free);
327
328 static void madera_debug_dump_domain_groups(const struct madera_priv *priv)
329 {
330         struct madera *madera = priv->madera;
331         int i;
332
333         for (i = 0; i < ARRAY_SIZE(priv->domain_group_ref); ++i)
334                 dev_dbg(madera->dev, "domain_grp_ref[%d]=%d\n", i,
335                         priv->domain_group_ref[i]);
336 }
337
338 int madera_domain_clk_ev(struct snd_soc_dapm_widget *w,
339                          struct snd_kcontrol *kcontrol,
340                          int event)
341 {
342         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
343         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
344         int dom_grp = w->shift;
345
346         if (dom_grp >= ARRAY_SIZE(priv->domain_group_ref)) {
347                 WARN(true, "%s dom_grp exceeds array size\n", __func__);
348                 return -EINVAL;
349         }
350
351         /*
352          * We can't rely on the DAPM mutex for locking because we need a lock
353          * that can safely be called in hw_params
354          */
355         mutex_lock(&priv->rate_lock);
356
357         switch (event) {
358         case SND_SOC_DAPM_PRE_PMU:
359                 dev_dbg(priv->madera->dev, "Inc ref on domain group %d\n",
360                         dom_grp);
361                 ++priv->domain_group_ref[dom_grp];
362                 break;
363         case SND_SOC_DAPM_POST_PMD:
364                 dev_dbg(priv->madera->dev, "Dec ref on domain group %d\n",
365                         dom_grp);
366                 --priv->domain_group_ref[dom_grp];
367                 break;
368         default:
369                 break;
370         }
371
372         madera_debug_dump_domain_groups(priv);
373
374         mutex_unlock(&priv->rate_lock);
375
376         return 0;
377 }
378 EXPORT_SYMBOL_GPL(madera_domain_clk_ev);
379
380 int madera_out1_demux_put(struct snd_kcontrol *kcontrol,
381                           struct snd_ctl_elem_value *ucontrol)
382 {
383         struct snd_soc_component *component =
384                 snd_soc_dapm_kcontrol_component(kcontrol);
385         struct snd_soc_dapm_context *dapm =
386                 snd_soc_dapm_kcontrol_dapm(kcontrol);
387         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
388         struct madera *madera = priv->madera;
389         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
390         unsigned int ep_sel, mux, change;
391         bool out_mono;
392         int ret;
393
394         if (ucontrol->value.enumerated.item[0] > e->items - 1)
395                 return -EINVAL;
396
397         mux = ucontrol->value.enumerated.item[0];
398
399         snd_soc_dapm_mutex_lock(dapm);
400
401         ep_sel = mux << MADERA_EP_SEL_SHIFT;
402
403         change = snd_soc_component_test_bits(component, MADERA_OUTPUT_ENABLES_1,
404                                              MADERA_EP_SEL_MASK,
405                                              ep_sel);
406         if (!change)
407                 goto end;
408
409         /* EP_SEL should not be modified while HP or EP driver is enabled */
410         ret = regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1,
411                                  MADERA_OUT1L_ENA | MADERA_OUT1R_ENA, 0);
412         if (ret)
413                 dev_warn(madera->dev, "Failed to disable outputs: %d\n", ret);
414
415         usleep_range(2000, 3000); /* wait for wseq to complete */
416
417         /* change demux setting */
418         if (madera->out_clamp[0])
419                 ret = regmap_update_bits(madera->regmap,
420                                          MADERA_OUTPUT_ENABLES_1,
421                                          MADERA_EP_SEL_MASK, ep_sel);
422         if (ret) {
423                 dev_err(madera->dev, "Failed to set OUT1 demux: %d\n", ret);
424         } else {
425                 /* apply correct setting for mono mode */
426                 if (!ep_sel && !madera->pdata.codec.out_mono[0])
427                         out_mono = false; /* stereo HP */
428                 else
429                         out_mono = true; /* EP or mono HP */
430
431                 ret = madera_set_output_mode(component, 1, out_mono);
432                 if (ret)
433                         dev_warn(madera->dev,
434                                  "Failed to set output mode: %d\n", ret);
435         }
436
437         /*
438          * if HPDET has disabled the clamp while switching to HPOUT
439          * OUT1 should remain disabled
440          */
441         if (ep_sel ||
442             (madera->out_clamp[0] && !madera->out_shorted[0])) {
443                 ret = regmap_update_bits(madera->regmap,
444                                          MADERA_OUTPUT_ENABLES_1,
445                                          MADERA_OUT1L_ENA | MADERA_OUT1R_ENA,
446                                          madera->hp_ena);
447                 if (ret)
448                         dev_warn(madera->dev,
449                                  "Failed to restore earpiece outputs: %d\n",
450                                  ret);
451                 else if (madera->hp_ena)
452                         msleep(34); /* wait for enable wseq */
453                 else
454                         usleep_range(2000, 3000); /* wait for disable wseq */
455         }
456
457 end:
458         snd_soc_dapm_mutex_unlock(dapm);
459
460         return snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL);
461 }
462 EXPORT_SYMBOL_GPL(madera_out1_demux_put);
463
464 int madera_out1_demux_get(struct snd_kcontrol *kcontrol,
465                           struct snd_ctl_elem_value *ucontrol)
466 {
467         struct snd_soc_component *component =
468                 snd_soc_dapm_kcontrol_component(kcontrol);
469         unsigned int val;
470         int ret;
471
472         ret = snd_soc_component_read(component, MADERA_OUTPUT_ENABLES_1, &val);
473         if (ret)
474                 return ret;
475
476         val &= MADERA_EP_SEL_MASK;
477         val >>= MADERA_EP_SEL_SHIFT;
478         ucontrol->value.enumerated.item[0] = val;
479
480         return 0;
481 }
482 EXPORT_SYMBOL_GPL(madera_out1_demux_get);
483
484 static int madera_inmux_put(struct snd_kcontrol *kcontrol,
485                             struct snd_ctl_elem_value *ucontrol)
486 {
487         struct snd_soc_component *component =
488                 snd_soc_dapm_kcontrol_component(kcontrol);
489         struct snd_soc_dapm_context *dapm =
490                 snd_soc_dapm_kcontrol_dapm(kcontrol);
491         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
492         struct madera *madera = priv->madera;
493         struct regmap *regmap = madera->regmap;
494         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
495         unsigned int mux, val, mask;
496         unsigned int inmode;
497         bool changed;
498         int ret;
499
500         mux = ucontrol->value.enumerated.item[0];
501         if (mux > 1)
502                 return -EINVAL;
503
504         val = mux << e->shift_l;
505         mask = (e->mask << e->shift_l) | MADERA_IN1L_SRC_SE_MASK;
506
507         switch (e->reg) {
508         case MADERA_ADC_DIGITAL_VOLUME_1L:
509                 inmode = madera->pdata.codec.inmode[0][2 * mux];
510                 break;
511         case MADERA_ADC_DIGITAL_VOLUME_1R:
512                 inmode = madera->pdata.codec.inmode[0][1 + (2 * mux)];
513                 break;
514         case MADERA_ADC_DIGITAL_VOLUME_2L:
515                 inmode = madera->pdata.codec.inmode[1][2 * mux];
516                 break;
517         case MADERA_ADC_DIGITAL_VOLUME_2R:
518                 inmode = madera->pdata.codec.inmode[1][1 + (2 * mux)];
519                 break;
520         default:
521                 return -EINVAL;
522         }
523
524         if (inmode & MADERA_INMODE_SE)
525                 val |= 1 << MADERA_IN1L_SRC_SE_SHIFT;
526
527         dev_dbg(madera->dev, "mux=%u reg=0x%x inmode=0x%x mask=0x%x val=0x%x\n",
528                 mux, e->reg, inmode, mask, val);
529
530         ret = regmap_update_bits_check(regmap, e->reg, mask, val, &changed);
531         if (ret < 0)
532                 return ret;
533
534         if (changed)
535                 return snd_soc_dapm_mux_update_power(dapm, kcontrol,
536                                                      mux, e, NULL);
537         else
538                 return 0;
539 }
540
541 static const char * const madera_inmux_texts[] = {
542         "A",
543         "B",
544 };
545
546 static SOC_ENUM_SINGLE_DECL(madera_in1muxl_enum,
547                             MADERA_ADC_DIGITAL_VOLUME_1L,
548                             MADERA_IN1L_SRC_SHIFT,
549                             madera_inmux_texts);
550
551 static SOC_ENUM_SINGLE_DECL(madera_in1muxr_enum,
552                             MADERA_ADC_DIGITAL_VOLUME_1R,
553                             MADERA_IN1R_SRC_SHIFT,
554                             madera_inmux_texts);
555
556 static SOC_ENUM_SINGLE_DECL(madera_in2muxl_enum,
557                             MADERA_ADC_DIGITAL_VOLUME_2L,
558                             MADERA_IN2L_SRC_SHIFT,
559                             madera_inmux_texts);
560
561 static SOC_ENUM_SINGLE_DECL(madera_in2muxr_enum,
562                             MADERA_ADC_DIGITAL_VOLUME_2R,
563                             MADERA_IN2R_SRC_SHIFT,
564                             madera_inmux_texts);
565
566 const struct snd_kcontrol_new madera_inmux[] = {
567         SOC_DAPM_ENUM_EXT("IN1L Mux", madera_in1muxl_enum,
568                           snd_soc_dapm_get_enum_double, madera_inmux_put),
569         SOC_DAPM_ENUM_EXT("IN1R Mux", madera_in1muxr_enum,
570                           snd_soc_dapm_get_enum_double, madera_inmux_put),
571         SOC_DAPM_ENUM_EXT("IN2L Mux", madera_in2muxl_enum,
572                           snd_soc_dapm_get_enum_double, madera_inmux_put),
573         SOC_DAPM_ENUM_EXT("IN2R Mux", madera_in2muxr_enum,
574                           snd_soc_dapm_get_enum_double, madera_inmux_put),
575 };
576 EXPORT_SYMBOL_GPL(madera_inmux);
577
578 static const char * const madera_dmode_texts[] = {
579         "Analog",
580         "Digital",
581 };
582
583 static SOC_ENUM_SINGLE_DECL(madera_in1dmode_enum,
584                             MADERA_IN1L_CONTROL,
585                             MADERA_IN1_MODE_SHIFT,
586                             madera_dmode_texts);
587
588 static SOC_ENUM_SINGLE_DECL(madera_in2dmode_enum,
589                             MADERA_IN2L_CONTROL,
590                             MADERA_IN2_MODE_SHIFT,
591                             madera_dmode_texts);
592
593 static SOC_ENUM_SINGLE_DECL(madera_in3dmode_enum,
594                             MADERA_IN3L_CONTROL,
595                             MADERA_IN3_MODE_SHIFT,
596                             madera_dmode_texts);
597
598 const struct snd_kcontrol_new madera_inmode[] = {
599         SOC_DAPM_ENUM("IN1 Mode", madera_in1dmode_enum),
600         SOC_DAPM_ENUM("IN2 Mode", madera_in2dmode_enum),
601         SOC_DAPM_ENUM("IN3 Mode", madera_in3dmode_enum),
602 };
603 EXPORT_SYMBOL_GPL(madera_inmode);
604
605 static bool madera_can_change_grp_rate(const struct madera_priv *priv,
606                                        unsigned int reg)
607 {
608         int count;
609
610         switch (reg) {
611         case MADERA_FX_CTRL1:
612                 count = priv->domain_group_ref[MADERA_DOM_GRP_FX];
613                 break;
614         case MADERA_ASRC1_RATE1:
615         case MADERA_ASRC1_RATE2:
616                 count = priv->domain_group_ref[MADERA_DOM_GRP_ASRC1];
617                 break;
618         case MADERA_ASRC2_RATE1:
619         case MADERA_ASRC2_RATE2:
620                 count = priv->domain_group_ref[MADERA_DOM_GRP_ASRC2];
621                 break;
622         case MADERA_ISRC_1_CTRL_1:
623         case MADERA_ISRC_1_CTRL_2:
624                 count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC1];
625                 break;
626         case MADERA_ISRC_2_CTRL_1:
627         case MADERA_ISRC_2_CTRL_2:
628                 count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC2];
629                 break;
630         case MADERA_ISRC_3_CTRL_1:
631         case MADERA_ISRC_3_CTRL_2:
632                 count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC3];
633                 break;
634         case MADERA_ISRC_4_CTRL_1:
635         case MADERA_ISRC_4_CTRL_2:
636                 count = priv->domain_group_ref[MADERA_DOM_GRP_ISRC4];
637                 break;
638         case MADERA_OUTPUT_RATE_1:
639                 count = priv->domain_group_ref[MADERA_DOM_GRP_OUT];
640                 break;
641         case MADERA_SPD1_TX_CONTROL:
642                 count = priv->domain_group_ref[MADERA_DOM_GRP_SPD];
643                 break;
644         case MADERA_DSP1_CONFIG_1:
645         case MADERA_DSP1_CONFIG_2:
646                 count = priv->domain_group_ref[MADERA_DOM_GRP_DSP1];
647                 break;
648         case MADERA_DSP2_CONFIG_1:
649         case MADERA_DSP2_CONFIG_2:
650                 count = priv->domain_group_ref[MADERA_DOM_GRP_DSP2];
651                 break;
652         case MADERA_DSP3_CONFIG_1:
653         case MADERA_DSP3_CONFIG_2:
654                 count = priv->domain_group_ref[MADERA_DOM_GRP_DSP3];
655                 break;
656         case MADERA_DSP4_CONFIG_1:
657         case MADERA_DSP4_CONFIG_2:
658                 count = priv->domain_group_ref[MADERA_DOM_GRP_DSP4];
659                 break;
660         case MADERA_DSP5_CONFIG_1:
661         case MADERA_DSP5_CONFIG_2:
662                 count = priv->domain_group_ref[MADERA_DOM_GRP_DSP5];
663                 break;
664         case MADERA_DSP6_CONFIG_1:
665         case MADERA_DSP6_CONFIG_2:
666                 count = priv->domain_group_ref[MADERA_DOM_GRP_DSP6];
667                 break;
668         case MADERA_DSP7_CONFIG_1:
669         case MADERA_DSP7_CONFIG_2:
670                 count = priv->domain_group_ref[MADERA_DOM_GRP_DSP7];
671                 break;
672         case MADERA_AIF1_RATE_CTRL:
673                 count = priv->domain_group_ref[MADERA_DOM_GRP_AIF1];
674                 break;
675         case MADERA_AIF2_RATE_CTRL:
676                 count = priv->domain_group_ref[MADERA_DOM_GRP_AIF2];
677                 break;
678         case MADERA_AIF3_RATE_CTRL:
679                 count = priv->domain_group_ref[MADERA_DOM_GRP_AIF3];
680                 break;
681         case MADERA_AIF4_RATE_CTRL:
682                 count = priv->domain_group_ref[MADERA_DOM_GRP_AIF4];
683                 break;
684         case MADERA_SLIMBUS_RATES_1:
685         case MADERA_SLIMBUS_RATES_2:
686         case MADERA_SLIMBUS_RATES_3:
687         case MADERA_SLIMBUS_RATES_4:
688         case MADERA_SLIMBUS_RATES_5:
689         case MADERA_SLIMBUS_RATES_6:
690         case MADERA_SLIMBUS_RATES_7:
691         case MADERA_SLIMBUS_RATES_8:
692                 count = priv->domain_group_ref[MADERA_DOM_GRP_SLIMBUS];
693                 break;
694         case MADERA_PWM_DRIVE_1:
695                 count = priv->domain_group_ref[MADERA_DOM_GRP_PWM];
696                 break;
697         default:
698                 return false;
699         }
700
701         dev_dbg(priv->madera->dev, "Rate reg 0x%x group ref %d\n", reg, count);
702
703         if (count)
704                 return false;
705         else
706                 return true;
707 }
708
709 static int madera_adsp_rate_get(struct snd_kcontrol *kcontrol,
710                                 struct snd_ctl_elem_value *ucontrol)
711 {
712         struct snd_soc_component *component =
713                 snd_soc_kcontrol_component(kcontrol);
714         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
715         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
716         unsigned int cached_rate;
717         const int adsp_num = e->shift_l;
718         int item;
719
720         mutex_lock(&priv->rate_lock);
721         cached_rate = priv->adsp_rate_cache[adsp_num];
722         mutex_unlock(&priv->rate_lock);
723
724         item = snd_soc_enum_val_to_item(e, cached_rate);
725         ucontrol->value.enumerated.item[0] = item;
726
727         return 0;
728 }
729
730 static int madera_adsp_rate_put(struct snd_kcontrol *kcontrol,
731                                 struct snd_ctl_elem_value *ucontrol)
732 {
733         struct snd_soc_component *component =
734                 snd_soc_kcontrol_component(kcontrol);
735         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
736         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
737         const int adsp_num = e->shift_l;
738         const unsigned int item = ucontrol->value.enumerated.item[0];
739         int ret;
740
741         if (item >= e->items)
742                 return -EINVAL;
743
744         /*
745          * We don't directly write the rate register here but we want to
746          * maintain consistent behaviour that rate domains cannot be changed
747          * while in use since this is a hardware requirement
748          */
749         mutex_lock(&priv->rate_lock);
750
751         if (!madera_can_change_grp_rate(priv, priv->adsp[adsp_num].base)) {
752                 dev_warn(priv->madera->dev,
753                          "Cannot change '%s' while in use by active audio paths\n",
754                          kcontrol->id.name);
755                 ret = -EBUSY;
756         } else {
757                 /* Volatile register so defer until the codec is powered up */
758                 priv->adsp_rate_cache[adsp_num] = e->values[item];
759                 ret = 0;
760         }
761
762         mutex_unlock(&priv->rate_lock);
763
764         return ret;
765 }
766
767 static const struct soc_enum madera_adsp_rate_enum[] = {
768         SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 0, 0xf, MADERA_RATE_ENUM_SIZE,
769                               madera_rate_text, madera_rate_val),
770         SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 1, 0xf, MADERA_RATE_ENUM_SIZE,
771                               madera_rate_text, madera_rate_val),
772         SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 2, 0xf, MADERA_RATE_ENUM_SIZE,
773                               madera_rate_text, madera_rate_val),
774         SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 3, 0xf, MADERA_RATE_ENUM_SIZE,
775                               madera_rate_text, madera_rate_val),
776         SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 4, 0xf, MADERA_RATE_ENUM_SIZE,
777                               madera_rate_text, madera_rate_val),
778         SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 5, 0xf, MADERA_RATE_ENUM_SIZE,
779                               madera_rate_text, madera_rate_val),
780         SOC_VALUE_ENUM_SINGLE(SND_SOC_NOPM, 6, 0xf, MADERA_RATE_ENUM_SIZE,
781                               madera_rate_text, madera_rate_val),
782 };
783
784 const struct snd_kcontrol_new madera_adsp_rate_controls[] = {
785         SOC_ENUM_EXT("DSP1 Rate", madera_adsp_rate_enum[0],
786                      madera_adsp_rate_get, madera_adsp_rate_put),
787         SOC_ENUM_EXT("DSP2 Rate", madera_adsp_rate_enum[1],
788                      madera_adsp_rate_get, madera_adsp_rate_put),
789         SOC_ENUM_EXT("DSP3 Rate", madera_adsp_rate_enum[2],
790                      madera_adsp_rate_get, madera_adsp_rate_put),
791         SOC_ENUM_EXT("DSP4 Rate", madera_adsp_rate_enum[3],
792                      madera_adsp_rate_get, madera_adsp_rate_put),
793         SOC_ENUM_EXT("DSP5 Rate", madera_adsp_rate_enum[4],
794                      madera_adsp_rate_get, madera_adsp_rate_put),
795         SOC_ENUM_EXT("DSP6 Rate", madera_adsp_rate_enum[5],
796                      madera_adsp_rate_get, madera_adsp_rate_put),
797         SOC_ENUM_EXT("DSP7 Rate", madera_adsp_rate_enum[6],
798                      madera_adsp_rate_get, madera_adsp_rate_put),
799 };
800 EXPORT_SYMBOL_GPL(madera_adsp_rate_controls);
801
802 static int madera_write_adsp_clk_setting(struct madera_priv *priv,
803                                          struct wm_adsp *dsp,
804                                          unsigned int freq)
805 {
806         unsigned int val;
807         unsigned int mask = MADERA_DSP_RATE_MASK;
808         int ret;
809
810         val = priv->adsp_rate_cache[dsp->num - 1] << MADERA_DSP_RATE_SHIFT;
811
812         switch (priv->madera->type) {
813         case CS47L35:
814         case CS47L85:
815         case WM1840:
816                 /* use legacy frequency registers */
817                 mask |= MADERA_DSP_CLK_SEL_MASK;
818                 val |= (freq << MADERA_DSP_CLK_SEL_SHIFT);
819                 break;
820         default:
821                 /* Configure exact dsp frequency */
822                 dev_dbg(priv->madera->dev, "Set DSP frequency to 0x%x\n", freq);
823
824                 ret = regmap_write(dsp->regmap,
825                                    dsp->base + MADERA_DSP_CONFIG_2_OFFS, freq);
826                 if (ret)
827                         goto err;
828                 break;
829         }
830
831         ret = regmap_update_bits(dsp->regmap,
832                                  dsp->base + MADERA_DSP_CONFIG_1_OFFS,
833                                  mask, val);
834         if (ret)
835                 goto err;
836
837         dev_dbg(priv->madera->dev, "Set DSP clocking to 0x%x\n", val);
838
839         return 0;
840
841 err:
842         dev_err(dsp->dev, "Failed to set DSP%d clock: %d\n", dsp->num, ret);
843
844         return ret;
845 }
846
847 int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num,
848                         unsigned int freq)
849 {
850         struct wm_adsp *dsp = &priv->adsp[dsp_num];
851         struct madera *madera = priv->madera;
852         unsigned int cur, new;
853         int ret;
854
855         /*
856          * This is called at a higher DAPM priority than the mux widgets so
857          * the muxes are still off at this point and it's safe to change
858          * the rate domain control.
859          * Also called at a lower DAPM priority than the domain group widgets
860          * so locking the reads of adsp_rate_cache is not necessary as we know
861          * changes are locked out by the domain_group_ref reference count.
862          */
863
864         ret = regmap_read(dsp->regmap,  dsp->base, &cur);
865         if (ret) {
866                 dev_err(madera->dev,
867                         "Failed to read current DSP rate: %d\n", ret);
868                 return ret;
869         }
870
871         cur &= MADERA_DSP_RATE_MASK;
872
873         new = priv->adsp_rate_cache[dsp->num - 1] << MADERA_DSP_RATE_SHIFT;
874
875         if (new == cur) {
876                 dev_dbg(madera->dev, "DSP rate not changed\n");
877                 return madera_write_adsp_clk_setting(priv, dsp, freq);
878         } else {
879                 dev_dbg(madera->dev, "DSP rate changed\n");
880
881                 /* The write must be guarded by a number of SYSCLK cycles */
882                 madera_spin_sysclk(priv);
883                 ret = madera_write_adsp_clk_setting(priv, dsp, freq);
884                 madera_spin_sysclk(priv);
885                 return ret;
886         }
887 }
888 EXPORT_SYMBOL_GPL(madera_set_adsp_clk);
889
890 int madera_rate_put(struct snd_kcontrol *kcontrol,
891                     struct snd_ctl_elem_value *ucontrol)
892 {
893         struct snd_soc_component *component =
894                 snd_soc_kcontrol_component(kcontrol);
895         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
896         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
897         unsigned int item = ucontrol->value.enumerated.item[0];
898         unsigned int val;
899         int ret;
900
901         if (item >= e->items)
902                 return -EINVAL;
903
904         /*
905          * Prevent the domain powering up while we're checking whether it's
906          * safe to change rate domain
907          */
908         mutex_lock(&priv->rate_lock);
909
910         ret = snd_soc_component_read(component, e->reg, &val);
911         if (ret < 0) {
912                 dev_warn(priv->madera->dev, "Failed to read 0x%x (%d)\n",
913                          e->reg, ret);
914                 goto out;
915         }
916         val >>= e->shift_l;
917         val &= e->mask;
918         if (snd_soc_enum_item_to_val(e, item) == val) {
919                 ret = 0;
920                 goto out;
921         }
922
923         if (!madera_can_change_grp_rate(priv, e->reg)) {
924                 dev_warn(priv->madera->dev,
925                          "Cannot change '%s' while in use by active audio paths\n",
926                          kcontrol->id.name);
927                 ret = -EBUSY;
928         } else {
929                 /* The write must be guarded by a number of SYSCLK cycles */
930                 madera_spin_sysclk(priv);
931                 ret = snd_soc_put_enum_double(kcontrol, ucontrol);
932                 madera_spin_sysclk(priv);
933         }
934 out:
935         mutex_unlock(&priv->rate_lock);
936
937         return ret;
938 }
939 EXPORT_SYMBOL_GPL(madera_rate_put);
940
941 static void madera_configure_input_mode(struct madera *madera)
942 {
943         unsigned int dig_mode, ana_mode_l, ana_mode_r;
944         int max_analogue_inputs, max_dmic_sup, i;
945
946         switch (madera->type) {
947         case CS47L35:
948                 max_analogue_inputs = 2;
949                 max_dmic_sup = 2;
950                 break;
951         case CS47L85:
952         case WM1840:
953                 max_analogue_inputs = 3;
954                 max_dmic_sup = 3;
955                 break;
956         case CS47L90:
957         case CS47L91:
958                 max_analogue_inputs = 2;
959                 max_dmic_sup = 2;
960                 break;
961         default:
962                 max_analogue_inputs = 2;
963                 max_dmic_sup = 4;
964                 break;
965         }
966
967         /*
968          * Initialize input modes from the A settings. For muxed inputs the
969          * B settings will be applied if the mux is changed
970          */
971         for (i = 0; i < max_dmic_sup; i++) {
972                 dev_dbg(madera->dev, "IN%d mode %u:%u:%u:%u\n", i + 1,
973                         madera->pdata.codec.inmode[i][0],
974                         madera->pdata.codec.inmode[i][1],
975                         madera->pdata.codec.inmode[i][2],
976                         madera->pdata.codec.inmode[i][3]);
977
978                 dig_mode = madera->pdata.codec.dmic_ref[i] <<
979                            MADERA_IN1_DMIC_SUP_SHIFT;
980
981                 switch (madera->pdata.codec.inmode[i][0]) {
982                 case MADERA_INMODE_DIFF:
983                         ana_mode_l = 0;
984                         break;
985                 case MADERA_INMODE_SE:
986                         ana_mode_l = 1 << MADERA_IN1L_SRC_SE_SHIFT;
987                         break;
988                 default:
989                         dev_warn(madera->dev,
990                                  "IN%dAL Illegal inmode %u ignored\n",
991                                  i + 1, madera->pdata.codec.inmode[i][0]);
992                         continue;
993                 }
994
995                 switch (madera->pdata.codec.inmode[i][1]) {
996                 case MADERA_INMODE_DIFF:
997                         ana_mode_r = 0;
998                         break;
999                 case MADERA_INMODE_SE:
1000                         ana_mode_r = 1 << MADERA_IN1R_SRC_SE_SHIFT;
1001                         break;
1002                 default:
1003                         dev_warn(madera->dev,
1004                                  "IN%dAR Illegal inmode %u ignored\n",
1005                                  i + 1, madera->pdata.codec.inmode[i][1]);
1006                         continue;
1007                 }
1008
1009                 dev_dbg(madera->dev,
1010                         "IN%dA DMIC mode=0x%x Analogue mode=0x%x,0x%x\n",
1011                         i + 1, dig_mode, ana_mode_l, ana_mode_r);
1012
1013                 regmap_update_bits(madera->regmap,
1014                                    MADERA_IN1L_CONTROL + (i * 8),
1015                                    MADERA_IN1_DMIC_SUP_MASK, dig_mode);
1016
1017                 if (i >= max_analogue_inputs)
1018                         continue;
1019
1020                 regmap_update_bits(madera->regmap,
1021                                    MADERA_ADC_DIGITAL_VOLUME_1L + (i * 8),
1022                                    MADERA_IN1L_SRC_SE_MASK, ana_mode_l);
1023
1024                 regmap_update_bits(madera->regmap,
1025                                    MADERA_ADC_DIGITAL_VOLUME_1R + (i * 8),
1026                                    MADERA_IN1R_SRC_SE_MASK, ana_mode_r);
1027         }
1028 }
1029
1030 int madera_init_inputs(struct snd_soc_component *component)
1031 {
1032         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
1033         struct madera *madera = priv->madera;
1034
1035         madera_configure_input_mode(madera);
1036
1037         return 0;
1038 }
1039 EXPORT_SYMBOL_GPL(madera_init_inputs);
1040
1041 static const struct snd_soc_dapm_route madera_mono_routes[] = {
1042         { "OUT1R", NULL, "OUT1L" },
1043         { "OUT2R", NULL, "OUT2L" },
1044         { "OUT3R", NULL, "OUT3L" },
1045         { "OUT4R", NULL, "OUT4L" },
1046         { "OUT5R", NULL, "OUT5L" },
1047         { "OUT6R", NULL, "OUT6L" },
1048 };
1049
1050 int madera_init_outputs(struct snd_soc_component *component, int n_mono_routes)
1051 {
1052         struct snd_soc_dapm_context *dapm =
1053                 snd_soc_component_get_dapm(component);
1054         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
1055         struct madera *madera = priv->madera;
1056         const struct madera_codec_pdata *pdata = &madera->pdata.codec;
1057         unsigned int val;
1058         int i;
1059
1060         if (n_mono_routes > MADERA_MAX_OUTPUT) {
1061                 dev_warn(madera->dev,
1062                          "Requested %d mono outputs, using maximum allowed %d\n",
1063                          n_mono_routes, MADERA_MAX_OUTPUT);
1064                 n_mono_routes = MADERA_MAX_OUTPUT;
1065         }
1066
1067         for (i = 0; i < n_mono_routes; i++) {
1068                 /* Default is 0 so noop with defaults */
1069                 if (pdata->out_mono[i]) {
1070                         val = MADERA_OUT1_MONO;
1071                         snd_soc_dapm_add_routes(dapm,
1072                                                 &madera_mono_routes[i], 1);
1073                 } else {
1074                         val = 0;
1075                 }
1076
1077                 regmap_update_bits(madera->regmap,
1078                                    MADERA_OUTPUT_PATH_CONFIG_1L + (i * 8),
1079                                    MADERA_OUT1_MONO, val);
1080
1081                 dev_dbg(madera->dev, "OUT%d mono=0x%x\n", i + 1, val);
1082         }
1083
1084         for (i = 0; i < MADERA_MAX_PDM_SPK; i++) {
1085                 dev_dbg(madera->dev, "PDM%d fmt=0x%x mute=0x%x\n", i + 1,
1086                         pdata->pdm_fmt[i], pdata->pdm_mute[i]);
1087
1088                 if (pdata->pdm_mute[i])
1089                         regmap_update_bits(madera->regmap,
1090                                            MADERA_PDM_SPK1_CTRL_1 + (i * 2),
1091                                            MADERA_SPK1_MUTE_ENDIAN_MASK |
1092                                            MADERA_SPK1_MUTE_SEQ1_MASK,
1093                                            pdata->pdm_mute[i]);
1094
1095                 if (pdata->pdm_fmt[i])
1096                         regmap_update_bits(madera->regmap,
1097                                            MADERA_PDM_SPK1_CTRL_2 + (i * 2),
1098                                            MADERA_SPK1_FMT_MASK,
1099                                            pdata->pdm_fmt[i]);
1100         }
1101
1102         return 0;
1103 }
1104 EXPORT_SYMBOL_GPL(madera_init_outputs);
1105
1106 int madera_init_bus_error_irq(struct madera_priv *priv, int dsp_num,
1107                               irq_handler_t handler)
1108 {
1109         struct madera *madera = priv->madera;
1110         int ret;
1111
1112         ret = madera_request_irq(madera,
1113                                  madera_dsp_bus_error_irqs[dsp_num],
1114                                  "ADSP2 bus error",
1115                                  handler,
1116                                  &priv->adsp[dsp_num]);
1117         if (ret)
1118                 dev_err(madera->dev,
1119                         "Failed to request DSP Lock region IRQ: %d\n", ret);
1120
1121         return ret;
1122 }
1123 EXPORT_SYMBOL_GPL(madera_init_bus_error_irq);
1124
1125 void madera_free_bus_error_irq(struct madera_priv *priv, int dsp_num)
1126 {
1127         struct madera *madera = priv->madera;
1128
1129         madera_free_irq(madera,
1130                         madera_dsp_bus_error_irqs[dsp_num],
1131                         &priv->adsp[dsp_num]);
1132 }
1133 EXPORT_SYMBOL_GPL(madera_free_bus_error_irq);
1134
1135 const char * const madera_mixer_texts[] = {
1136         "None",
1137         "Tone Generator 1",
1138         "Tone Generator 2",
1139         "Haptics",
1140         "AEC1",
1141         "AEC2",
1142         "Mic Mute Mixer",
1143         "Noise Generator",
1144         "IN1L",
1145         "IN1R",
1146         "IN2L",
1147         "IN2R",
1148         "IN3L",
1149         "IN3R",
1150         "IN4L",
1151         "IN4R",
1152         "IN5L",
1153         "IN5R",
1154         "IN6L",
1155         "IN6R",
1156         "AIF1RX1",
1157         "AIF1RX2",
1158         "AIF1RX3",
1159         "AIF1RX4",
1160         "AIF1RX5",
1161         "AIF1RX6",
1162         "AIF1RX7",
1163         "AIF1RX8",
1164         "AIF2RX1",
1165         "AIF2RX2",
1166         "AIF2RX3",
1167         "AIF2RX4",
1168         "AIF2RX5",
1169         "AIF2RX6",
1170         "AIF2RX7",
1171         "AIF2RX8",
1172         "AIF3RX1",
1173         "AIF3RX2",
1174         "AIF3RX3",
1175         "AIF3RX4",
1176         "AIF4RX1",
1177         "AIF4RX2",
1178         "SLIMRX1",
1179         "SLIMRX2",
1180         "SLIMRX3",
1181         "SLIMRX4",
1182         "SLIMRX5",
1183         "SLIMRX6",
1184         "SLIMRX7",
1185         "SLIMRX8",
1186         "EQ1",
1187         "EQ2",
1188         "EQ3",
1189         "EQ4",
1190         "DRC1L",
1191         "DRC1R",
1192         "DRC2L",
1193         "DRC2R",
1194         "LHPF1",
1195         "LHPF2",
1196         "LHPF3",
1197         "LHPF4",
1198         "DSP1.1",
1199         "DSP1.2",
1200         "DSP1.3",
1201         "DSP1.4",
1202         "DSP1.5",
1203         "DSP1.6",
1204         "DSP2.1",
1205         "DSP2.2",
1206         "DSP2.3",
1207         "DSP2.4",
1208         "DSP2.5",
1209         "DSP2.6",
1210         "DSP3.1",
1211         "DSP3.2",
1212         "DSP3.3",
1213         "DSP3.4",
1214         "DSP3.5",
1215         "DSP3.6",
1216         "DSP4.1",
1217         "DSP4.2",
1218         "DSP4.3",
1219         "DSP4.4",
1220         "DSP4.5",
1221         "DSP4.6",
1222         "DSP5.1",
1223         "DSP5.2",
1224         "DSP5.3",
1225         "DSP5.4",
1226         "DSP5.5",
1227         "DSP5.6",
1228         "DSP6.1",
1229         "DSP6.2",
1230         "DSP6.3",
1231         "DSP6.4",
1232         "DSP6.5",
1233         "DSP6.6",
1234         "DSP7.1",
1235         "DSP7.2",
1236         "DSP7.3",
1237         "DSP7.4",
1238         "DSP7.5",
1239         "DSP7.6",
1240         "ASRC1IN1L",
1241         "ASRC1IN1R",
1242         "ASRC1IN2L",
1243         "ASRC1IN2R",
1244         "ASRC2IN1L",
1245         "ASRC2IN1R",
1246         "ASRC2IN2L",
1247         "ASRC2IN2R",
1248         "ISRC1INT1",
1249         "ISRC1INT2",
1250         "ISRC1INT3",
1251         "ISRC1INT4",
1252         "ISRC1DEC1",
1253         "ISRC1DEC2",
1254         "ISRC1DEC3",
1255         "ISRC1DEC4",
1256         "ISRC2INT1",
1257         "ISRC2INT2",
1258         "ISRC2INT3",
1259         "ISRC2INT4",
1260         "ISRC2DEC1",
1261         "ISRC2DEC2",
1262         "ISRC2DEC3",
1263         "ISRC2DEC4",
1264         "ISRC3INT1",
1265         "ISRC3INT2",
1266         "ISRC3INT3",
1267         "ISRC3INT4",
1268         "ISRC3DEC1",
1269         "ISRC3DEC2",
1270         "ISRC3DEC3",
1271         "ISRC3DEC4",
1272         "ISRC4INT1",
1273         "ISRC4INT2",
1274         "ISRC4DEC1",
1275         "ISRC4DEC2",
1276         "DFC1",
1277         "DFC2",
1278         "DFC3",
1279         "DFC4",
1280         "DFC5",
1281         "DFC6",
1282         "DFC7",
1283         "DFC8",
1284 };
1285 EXPORT_SYMBOL_GPL(madera_mixer_texts);
1286
1287 const unsigned int madera_mixer_values[] = {
1288         0x00,   /* None */
1289         0x04,   /* Tone Generator 1 */
1290         0x05,   /* Tone Generator 2 */
1291         0x06,   /* Haptics */
1292         0x08,   /* AEC */
1293         0x09,   /* AEC2 */
1294         0x0c,   /* Noise mixer */
1295         0x0d,   /* Comfort noise */
1296         0x10,   /* IN1L */
1297         0x11,
1298         0x12,
1299         0x13,
1300         0x14,
1301         0x15,
1302         0x16,
1303         0x17,
1304         0x18,
1305         0x19,
1306         0x1A,
1307         0x1B,
1308         0x20,   /* AIF1RX1 */
1309         0x21,
1310         0x22,
1311         0x23,
1312         0x24,
1313         0x25,
1314         0x26,
1315         0x27,
1316         0x28,   /* AIF2RX1 */
1317         0x29,
1318         0x2a,
1319         0x2b,
1320         0x2c,
1321         0x2d,
1322         0x2e,
1323         0x2f,
1324         0x30,   /* AIF3RX1 */
1325         0x31,
1326         0x32,
1327         0x33,
1328         0x34,   /* AIF4RX1 */
1329         0x35,
1330         0x38,   /* SLIMRX1 */
1331         0x39,
1332         0x3a,
1333         0x3b,
1334         0x3c,
1335         0x3d,
1336         0x3e,
1337         0x3f,
1338         0x50,   /* EQ1 */
1339         0x51,
1340         0x52,
1341         0x53,
1342         0x58,   /* DRC1L */
1343         0x59,
1344         0x5a,
1345         0x5b,
1346         0x60,   /* LHPF1 */
1347         0x61,
1348         0x62,
1349         0x63,
1350         0x68,   /* DSP1.1 */
1351         0x69,
1352         0x6a,
1353         0x6b,
1354         0x6c,
1355         0x6d,
1356         0x70,   /* DSP2.1 */
1357         0x71,
1358         0x72,
1359         0x73,
1360         0x74,
1361         0x75,
1362         0x78,   /* DSP3.1 */
1363         0x79,
1364         0x7a,
1365         0x7b,
1366         0x7c,
1367         0x7d,
1368         0x80,   /* DSP4.1 */
1369         0x81,
1370         0x82,
1371         0x83,
1372         0x84,
1373         0x85,
1374         0x88,   /* DSP5.1 */
1375         0x89,
1376         0x8a,
1377         0x8b,
1378         0x8c,
1379         0x8d,
1380         0xc0,   /* DSP6.1 */
1381         0xc1,
1382         0xc2,
1383         0xc3,
1384         0xc4,
1385         0xc5,
1386         0xc8,   /* DSP7.1 */
1387         0xc9,
1388         0xca,
1389         0xcb,
1390         0xcc,
1391         0xcd,
1392         0x90,   /* ASRC1IN1L */
1393         0x91,
1394         0x92,
1395         0x93,
1396         0x94,   /* ASRC2IN1L */
1397         0x95,
1398         0x96,
1399         0x97,
1400         0xa0,   /* ISRC1INT1 */
1401         0xa1,
1402         0xa2,
1403         0xa3,
1404         0xa4,   /* ISRC1DEC1 */
1405         0xa5,
1406         0xa6,
1407         0xa7,
1408         0xa8,   /* ISRC2DEC1 */
1409         0xa9,
1410         0xaa,
1411         0xab,
1412         0xac,   /* ISRC2INT1 */
1413         0xad,
1414         0xae,
1415         0xaf,
1416         0xb0,   /* ISRC3DEC1 */
1417         0xb1,
1418         0xb2,
1419         0xb3,
1420         0xb4,   /* ISRC3INT1 */
1421         0xb5,
1422         0xb6,
1423         0xb7,
1424         0xb8,   /* ISRC4INT1 */
1425         0xb9,
1426         0xbc,   /* ISRC4DEC1 */
1427         0xbd,
1428         0xf8,   /* DFC1 */
1429         0xf9,
1430         0xfa,
1431         0xfb,
1432         0xfc,
1433         0xfd,
1434         0xfe,
1435         0xff,   /* DFC8 */
1436 };
1437 EXPORT_SYMBOL_GPL(madera_mixer_values);
1438
1439 const DECLARE_TLV_DB_SCALE(madera_ana_tlv, 0, 100, 0);
1440 EXPORT_SYMBOL_GPL(madera_ana_tlv);
1441
1442 const DECLARE_TLV_DB_SCALE(madera_eq_tlv, -1200, 100, 0);
1443 EXPORT_SYMBOL_GPL(madera_eq_tlv);
1444
1445 const DECLARE_TLV_DB_SCALE(madera_digital_tlv, -6400, 50, 0);
1446 EXPORT_SYMBOL_GPL(madera_digital_tlv);
1447
1448 const DECLARE_TLV_DB_SCALE(madera_noise_tlv, -13200, 600, 0);
1449 EXPORT_SYMBOL_GPL(madera_noise_tlv);
1450
1451 const DECLARE_TLV_DB_SCALE(madera_ng_tlv, -12000, 600, 0);
1452 EXPORT_SYMBOL_GPL(madera_ng_tlv);
1453
1454 const DECLARE_TLV_DB_SCALE(madera_mixer_tlv, -3200, 100, 0);
1455 EXPORT_SYMBOL_GPL(madera_mixer_tlv);
1456
1457 const char * const madera_rate_text[MADERA_RATE_ENUM_SIZE] = {
1458         "SYNCCLK rate 1", "SYNCCLK rate 2", "SYNCCLK rate 3",
1459         "ASYNCCLK rate 1", "ASYNCCLK rate 2",
1460 };
1461 EXPORT_SYMBOL_GPL(madera_rate_text);
1462
1463 const unsigned int madera_rate_val[MADERA_RATE_ENUM_SIZE] = {
1464         0x0, 0x1, 0x2, 0x8, 0x9,
1465 };
1466 EXPORT_SYMBOL_GPL(madera_rate_val);
1467
1468 static const char * const madera_dfc_width_text[MADERA_DFC_WIDTH_ENUM_SIZE] = {
1469         "8 bit", "16 bit", "20 bit", "24 bit", "32 bit",
1470 };
1471
1472 static const unsigned int madera_dfc_width_val[MADERA_DFC_WIDTH_ENUM_SIZE] = {
1473         7, 15, 19, 23, 31,
1474 };
1475
1476 static const char * const madera_dfc_type_text[MADERA_DFC_TYPE_ENUM_SIZE] = {
1477         "Fixed", "Unsigned Fixed", "Single Precision Floating",
1478         "Half Precision Floating", "Arm Alternative Floating",
1479 };
1480
1481 static const unsigned int madera_dfc_type_val[MADERA_DFC_TYPE_ENUM_SIZE] = {
1482         0, 1, 2, 4, 5,
1483 };
1484
1485 const struct soc_enum madera_dfc_width[] = {
1486         SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_RX,
1487                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1488                               MADERA_DFC1_RX_DATA_WIDTH_MASK >>
1489                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1490                               ARRAY_SIZE(madera_dfc_width_text),
1491                               madera_dfc_width_text,
1492                               madera_dfc_width_val),
1493         SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_TX,
1494                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1495                               MADERA_DFC1_TX_DATA_WIDTH_MASK >>
1496                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1497                               ARRAY_SIZE(madera_dfc_width_text),
1498                               madera_dfc_width_text,
1499                               madera_dfc_width_val),
1500         SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_RX,
1501                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1502                               MADERA_DFC1_RX_DATA_WIDTH_MASK >>
1503                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1504                               ARRAY_SIZE(madera_dfc_width_text),
1505                               madera_dfc_width_text,
1506                               madera_dfc_width_val),
1507         SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_TX,
1508                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1509                               MADERA_DFC1_TX_DATA_WIDTH_MASK >>
1510                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1511                               ARRAY_SIZE(madera_dfc_width_text),
1512                               madera_dfc_width_text,
1513                               madera_dfc_width_val),
1514         SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_RX,
1515                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1516                               MADERA_DFC1_RX_DATA_WIDTH_MASK >>
1517                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1518                               ARRAY_SIZE(madera_dfc_width_text),
1519                               madera_dfc_width_text,
1520                               madera_dfc_width_val),
1521         SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_TX,
1522                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1523                               MADERA_DFC1_TX_DATA_WIDTH_MASK >>
1524                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1525                               ARRAY_SIZE(madera_dfc_width_text),
1526                               madera_dfc_width_text,
1527                               madera_dfc_width_val),
1528         SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_RX,
1529                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1530                               MADERA_DFC1_RX_DATA_WIDTH_MASK >>
1531                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1532                               ARRAY_SIZE(madera_dfc_width_text),
1533                               madera_dfc_width_text,
1534                               madera_dfc_width_val),
1535         SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_TX,
1536                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1537                               MADERA_DFC1_TX_DATA_WIDTH_MASK >>
1538                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1539                               ARRAY_SIZE(madera_dfc_width_text),
1540                               madera_dfc_width_text,
1541                               madera_dfc_width_val),
1542         SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_RX,
1543                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1544                               MADERA_DFC1_RX_DATA_WIDTH_MASK >>
1545                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1546                               ARRAY_SIZE(madera_dfc_width_text),
1547                               madera_dfc_width_text,
1548                               madera_dfc_width_val),
1549         SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_TX,
1550                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1551                               MADERA_DFC1_TX_DATA_WIDTH_MASK >>
1552                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1553                               ARRAY_SIZE(madera_dfc_width_text),
1554                               madera_dfc_width_text,
1555                               madera_dfc_width_val),
1556         SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_RX,
1557                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1558                               MADERA_DFC1_RX_DATA_WIDTH_MASK >>
1559                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1560                               ARRAY_SIZE(madera_dfc_width_text),
1561                               madera_dfc_width_text,
1562                               madera_dfc_width_val),
1563         SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_TX,
1564                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1565                               MADERA_DFC1_TX_DATA_WIDTH_MASK >>
1566                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1567                               ARRAY_SIZE(madera_dfc_width_text),
1568                               madera_dfc_width_text,
1569                               madera_dfc_width_val),
1570         SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_RX,
1571                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1572                               MADERA_DFC1_RX_DATA_WIDTH_MASK >>
1573                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1574                               ARRAY_SIZE(madera_dfc_width_text),
1575                               madera_dfc_width_text,
1576                               madera_dfc_width_val),
1577         SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_TX,
1578                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1579                               MADERA_DFC1_TX_DATA_WIDTH_MASK >>
1580                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1581                               ARRAY_SIZE(madera_dfc_width_text),
1582                               madera_dfc_width_text,
1583                               madera_dfc_width_val),
1584         SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_RX,
1585                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1586                               MADERA_DFC1_RX_DATA_WIDTH_MASK >>
1587                               MADERA_DFC1_RX_DATA_WIDTH_SHIFT,
1588                               ARRAY_SIZE(madera_dfc_width_text),
1589                               madera_dfc_width_text,
1590                               madera_dfc_width_val),
1591         SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_TX,
1592                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1593                               MADERA_DFC1_TX_DATA_WIDTH_MASK >>
1594                               MADERA_DFC1_TX_DATA_WIDTH_SHIFT,
1595                               ARRAY_SIZE(madera_dfc_width_text),
1596                               madera_dfc_width_text,
1597                               madera_dfc_width_val),
1598 };
1599 EXPORT_SYMBOL_GPL(madera_dfc_width);
1600
1601 const struct soc_enum madera_dfc_type[] = {
1602         SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_RX,
1603                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1604                               MADERA_DFC1_RX_DATA_TYPE_MASK >>
1605                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1606                               ARRAY_SIZE(madera_dfc_type_text),
1607                               madera_dfc_type_text,
1608                               madera_dfc_type_val),
1609         SOC_VALUE_ENUM_SINGLE(MADERA_DFC1_TX,
1610                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1611                               MADERA_DFC1_TX_DATA_TYPE_MASK >>
1612                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1613                               ARRAY_SIZE(madera_dfc_type_text),
1614                               madera_dfc_type_text,
1615                               madera_dfc_type_val),
1616         SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_RX,
1617                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1618                               MADERA_DFC1_RX_DATA_TYPE_MASK >>
1619                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1620                               ARRAY_SIZE(madera_dfc_type_text),
1621                               madera_dfc_type_text,
1622                               madera_dfc_type_val),
1623         SOC_VALUE_ENUM_SINGLE(MADERA_DFC2_TX,
1624                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1625                               MADERA_DFC1_TX_DATA_TYPE_MASK >>
1626                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1627                               ARRAY_SIZE(madera_dfc_type_text),
1628                               madera_dfc_type_text,
1629                               madera_dfc_type_val),
1630         SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_RX,
1631                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1632                               MADERA_DFC1_RX_DATA_TYPE_MASK >>
1633                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1634                               ARRAY_SIZE(madera_dfc_type_text),
1635                               madera_dfc_type_text,
1636                               madera_dfc_type_val),
1637         SOC_VALUE_ENUM_SINGLE(MADERA_DFC3_TX,
1638                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1639                               MADERA_DFC1_TX_DATA_TYPE_MASK >>
1640                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1641                               ARRAY_SIZE(madera_dfc_type_text),
1642                               madera_dfc_type_text,
1643                               madera_dfc_type_val),
1644         SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_RX,
1645                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1646                               MADERA_DFC1_RX_DATA_TYPE_MASK >>
1647                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1648                               ARRAY_SIZE(madera_dfc_type_text),
1649                               madera_dfc_type_text,
1650                               madera_dfc_type_val),
1651         SOC_VALUE_ENUM_SINGLE(MADERA_DFC4_TX,
1652                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1653                               MADERA_DFC1_TX_DATA_TYPE_MASK >>
1654                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1655                               ARRAY_SIZE(madera_dfc_type_text),
1656                               madera_dfc_type_text,
1657                               madera_dfc_type_val),
1658         SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_RX,
1659                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1660                               MADERA_DFC1_RX_DATA_TYPE_MASK >>
1661                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1662                               ARRAY_SIZE(madera_dfc_type_text),
1663                               madera_dfc_type_text,
1664                               madera_dfc_type_val),
1665         SOC_VALUE_ENUM_SINGLE(MADERA_DFC5_TX,
1666                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1667                               MADERA_DFC1_TX_DATA_TYPE_MASK >>
1668                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1669                               ARRAY_SIZE(madera_dfc_type_text),
1670                               madera_dfc_type_text,
1671                               madera_dfc_type_val),
1672         SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_RX,
1673                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1674                               MADERA_DFC1_RX_DATA_TYPE_MASK >>
1675                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1676                               ARRAY_SIZE(madera_dfc_type_text),
1677                               madera_dfc_type_text,
1678                               madera_dfc_type_val),
1679         SOC_VALUE_ENUM_SINGLE(MADERA_DFC6_TX,
1680                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1681                               MADERA_DFC1_TX_DATA_TYPE_MASK >>
1682                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1683                               ARRAY_SIZE(madera_dfc_type_text),
1684                               madera_dfc_type_text,
1685                               madera_dfc_type_val),
1686         SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_RX,
1687                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1688                               MADERA_DFC1_RX_DATA_TYPE_MASK >>
1689                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1690                               ARRAY_SIZE(madera_dfc_type_text),
1691                               madera_dfc_type_text,
1692                               madera_dfc_type_val),
1693         SOC_VALUE_ENUM_SINGLE(MADERA_DFC7_TX,
1694                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1695                               MADERA_DFC1_TX_DATA_TYPE_MASK >>
1696                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1697                               ARRAY_SIZE(madera_dfc_type_text),
1698                               madera_dfc_type_text,
1699                               madera_dfc_type_val),
1700         SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_RX,
1701                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1702                               MADERA_DFC1_RX_DATA_TYPE_MASK >>
1703                               MADERA_DFC1_RX_DATA_TYPE_SHIFT,
1704                               ARRAY_SIZE(madera_dfc_type_text),
1705                               madera_dfc_type_text,
1706                               madera_dfc_type_val),
1707         SOC_VALUE_ENUM_SINGLE(MADERA_DFC8_TX,
1708                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1709                               MADERA_DFC1_TX_DATA_TYPE_MASK >>
1710                               MADERA_DFC1_TX_DATA_TYPE_SHIFT,
1711                               ARRAY_SIZE(madera_dfc_type_text),
1712                               madera_dfc_type_text,
1713                               madera_dfc_type_val),
1714 };
1715 EXPORT_SYMBOL_GPL(madera_dfc_type);
1716
1717 const struct soc_enum madera_isrc_fsh[] = {
1718         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_1_CTRL_1,
1719                               MADERA_ISRC1_FSH_SHIFT, 0xf,
1720                               MADERA_RATE_ENUM_SIZE,
1721                               madera_rate_text, madera_rate_val),
1722         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_2_CTRL_1,
1723                               MADERA_ISRC2_FSH_SHIFT, 0xf,
1724                               MADERA_RATE_ENUM_SIZE,
1725                               madera_rate_text, madera_rate_val),
1726         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_3_CTRL_1,
1727                               MADERA_ISRC3_FSH_SHIFT, 0xf,
1728                               MADERA_RATE_ENUM_SIZE,
1729                               madera_rate_text, madera_rate_val),
1730         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_4_CTRL_1,
1731                               MADERA_ISRC4_FSH_SHIFT, 0xf,
1732                               MADERA_RATE_ENUM_SIZE,
1733                               madera_rate_text, madera_rate_val),
1734
1735 };
1736 EXPORT_SYMBOL_GPL(madera_isrc_fsh);
1737
1738 const struct soc_enum madera_isrc_fsl[] = {
1739         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_1_CTRL_2,
1740                               MADERA_ISRC1_FSL_SHIFT, 0xf,
1741                               MADERA_RATE_ENUM_SIZE,
1742                               madera_rate_text, madera_rate_val),
1743         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_2_CTRL_2,
1744                               MADERA_ISRC2_FSL_SHIFT, 0xf,
1745                               MADERA_RATE_ENUM_SIZE,
1746                               madera_rate_text, madera_rate_val),
1747         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_3_CTRL_2,
1748                               MADERA_ISRC3_FSL_SHIFT, 0xf,
1749                               MADERA_RATE_ENUM_SIZE,
1750                               madera_rate_text, madera_rate_val),
1751         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_4_CTRL_2,
1752                               MADERA_ISRC4_FSL_SHIFT, 0xf,
1753                               MADERA_RATE_ENUM_SIZE,
1754                               madera_rate_text, madera_rate_val),
1755
1756 };
1757 EXPORT_SYMBOL_GPL(madera_isrc_fsl);
1758
1759 const struct soc_enum madera_asrc1_rate[] = {
1760         SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE1,
1761                               MADERA_ASRC1_RATE1_SHIFT, 0xf,
1762                               MADERA_SYNC_RATE_ENUM_SIZE,
1763                               madera_rate_text, madera_rate_val),
1764         SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE2,
1765                               MADERA_ASRC1_RATE1_SHIFT, 0xf,
1766                               MADERA_ASYNC_RATE_ENUM_SIZE,
1767                               madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
1768                               madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
1769
1770 };
1771 EXPORT_SYMBOL_GPL(madera_asrc1_rate);
1772
1773 const struct soc_enum madera_asrc2_rate[] = {
1774         SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE1,
1775                               MADERA_ASRC2_RATE1_SHIFT, 0xf,
1776                               MADERA_SYNC_RATE_ENUM_SIZE,
1777                               madera_rate_text, madera_rate_val),
1778         SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE2,
1779                               MADERA_ASRC2_RATE2_SHIFT, 0xf,
1780                               MADERA_ASYNC_RATE_ENUM_SIZE,
1781                               madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
1782                               madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
1783
1784 };
1785 EXPORT_SYMBOL_GPL(madera_asrc2_rate);
1786
1787 static const char * const madera_vol_ramp_text[] = {
1788         "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
1789         "15ms/6dB", "30ms/6dB",
1790 };
1791
1792 SOC_ENUM_SINGLE_DECL(madera_in_vd_ramp,
1793                      MADERA_INPUT_VOLUME_RAMP,
1794                      MADERA_IN_VD_RAMP_SHIFT,
1795                      madera_vol_ramp_text);
1796 EXPORT_SYMBOL_GPL(madera_in_vd_ramp);
1797
1798 SOC_ENUM_SINGLE_DECL(madera_in_vi_ramp,
1799                      MADERA_INPUT_VOLUME_RAMP,
1800                      MADERA_IN_VI_RAMP_SHIFT,
1801                      madera_vol_ramp_text);
1802 EXPORT_SYMBOL_GPL(madera_in_vi_ramp);
1803
1804 SOC_ENUM_SINGLE_DECL(madera_out_vd_ramp,
1805                      MADERA_OUTPUT_VOLUME_RAMP,
1806                      MADERA_OUT_VD_RAMP_SHIFT,
1807                      madera_vol_ramp_text);
1808 EXPORT_SYMBOL_GPL(madera_out_vd_ramp);
1809
1810 SOC_ENUM_SINGLE_DECL(madera_out_vi_ramp,
1811                      MADERA_OUTPUT_VOLUME_RAMP,
1812                      MADERA_OUT_VI_RAMP_SHIFT,
1813                      madera_vol_ramp_text);
1814 EXPORT_SYMBOL_GPL(madera_out_vi_ramp);
1815
1816 static const char * const madera_lhpf_mode_text[] = {
1817         "Low-pass", "High-pass"
1818 };
1819
1820 SOC_ENUM_SINGLE_DECL(madera_lhpf1_mode,
1821                      MADERA_HPLPF1_1,
1822                      MADERA_LHPF1_MODE_SHIFT,
1823                      madera_lhpf_mode_text);
1824 EXPORT_SYMBOL_GPL(madera_lhpf1_mode);
1825
1826 SOC_ENUM_SINGLE_DECL(madera_lhpf2_mode,
1827                      MADERA_HPLPF2_1,
1828                      MADERA_LHPF2_MODE_SHIFT,
1829                      madera_lhpf_mode_text);
1830 EXPORT_SYMBOL_GPL(madera_lhpf2_mode);
1831
1832 SOC_ENUM_SINGLE_DECL(madera_lhpf3_mode,
1833                      MADERA_HPLPF3_1,
1834                      MADERA_LHPF3_MODE_SHIFT,
1835                      madera_lhpf_mode_text);
1836 EXPORT_SYMBOL_GPL(madera_lhpf3_mode);
1837
1838 SOC_ENUM_SINGLE_DECL(madera_lhpf4_mode,
1839                      MADERA_HPLPF4_1,
1840                      MADERA_LHPF4_MODE_SHIFT,
1841                      madera_lhpf_mode_text);
1842 EXPORT_SYMBOL_GPL(madera_lhpf4_mode);
1843
1844 static const char * const madera_ng_hold_text[] = {
1845         "30ms", "120ms", "250ms", "500ms",
1846 };
1847
1848 SOC_ENUM_SINGLE_DECL(madera_ng_hold,
1849                      MADERA_NOISE_GATE_CONTROL,
1850                      MADERA_NGATE_HOLD_SHIFT,
1851                      madera_ng_hold_text);
1852 EXPORT_SYMBOL_GPL(madera_ng_hold);
1853
1854 static const char * const madera_in_hpf_cut_text[] = {
1855         "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
1856 };
1857
1858 SOC_ENUM_SINGLE_DECL(madera_in_hpf_cut_enum,
1859                      MADERA_HPF_CONTROL,
1860                      MADERA_IN_HPF_CUT_SHIFT,
1861                      madera_in_hpf_cut_text);
1862 EXPORT_SYMBOL_GPL(madera_in_hpf_cut_enum);
1863
1864 static const char * const madera_in_dmic_osr_text[MADERA_OSR_ENUM_SIZE] = {
1865         "384kHz", "768kHz", "1.536MHz", "3.072MHz", "6.144MHz",
1866 };
1867
1868 static const unsigned int madera_in_dmic_osr_val[MADERA_OSR_ENUM_SIZE] = {
1869         2, 3, 4, 5, 6,
1870 };
1871
1872 const struct soc_enum madera_in_dmic_osr[] = {
1873         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC1L_CONTROL, MADERA_IN1_OSR_SHIFT,
1874                               0x7, MADERA_OSR_ENUM_SIZE,
1875                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
1876         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC2L_CONTROL, MADERA_IN2_OSR_SHIFT,
1877                               0x7, MADERA_OSR_ENUM_SIZE,
1878                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
1879         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC3L_CONTROL, MADERA_IN3_OSR_SHIFT,
1880                               0x7, MADERA_OSR_ENUM_SIZE,
1881                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
1882         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC4L_CONTROL, MADERA_IN4_OSR_SHIFT,
1883                               0x7, MADERA_OSR_ENUM_SIZE,
1884                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
1885         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC5L_CONTROL, MADERA_IN5_OSR_SHIFT,
1886                               0x7, MADERA_OSR_ENUM_SIZE,
1887                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
1888         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC6L_CONTROL, MADERA_IN6_OSR_SHIFT,
1889                               0x7, MADERA_OSR_ENUM_SIZE,
1890                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
1891 };
1892 EXPORT_SYMBOL_GPL(madera_in_dmic_osr);
1893
1894 static const char * const madera_anc_input_src_text[] = {
1895         "None", "IN1", "IN2", "IN3", "IN4", "IN5", "IN6",
1896 };
1897
1898 static const char * const madera_anc_channel_src_text[] = {
1899         "None", "Left", "Right", "Combine",
1900 };
1901
1902 const struct soc_enum madera_anc_input_src[] = {
1903         SOC_ENUM_SINGLE(MADERA_ANC_SRC,
1904                         MADERA_IN_RXANCL_SEL_SHIFT,
1905                         ARRAY_SIZE(madera_anc_input_src_text),
1906                         madera_anc_input_src_text),
1907         SOC_ENUM_SINGLE(MADERA_FCL_ADC_REFORMATTER_CONTROL,
1908                         MADERA_FCL_MIC_MODE_SEL_SHIFT,
1909                         ARRAY_SIZE(madera_anc_channel_src_text),
1910                         madera_anc_channel_src_text),
1911         SOC_ENUM_SINGLE(MADERA_ANC_SRC,
1912                         MADERA_IN_RXANCR_SEL_SHIFT,
1913                         ARRAY_SIZE(madera_anc_input_src_text),
1914                         madera_anc_input_src_text),
1915         SOC_ENUM_SINGLE(MADERA_FCR_ADC_REFORMATTER_CONTROL,
1916                         MADERA_FCR_MIC_MODE_SEL_SHIFT,
1917                         ARRAY_SIZE(madera_anc_channel_src_text),
1918                         madera_anc_channel_src_text),
1919 };
1920 EXPORT_SYMBOL_GPL(madera_anc_input_src);
1921
1922 static const char * const madera_anc_ng_texts[] = {
1923         "None", "Internal", "External",
1924 };
1925
1926 SOC_ENUM_SINGLE_DECL(madera_anc_ng_enum, SND_SOC_NOPM, 0, madera_anc_ng_texts);
1927 EXPORT_SYMBOL_GPL(madera_anc_ng_enum);
1928
1929 static const char * const madera_out_anc_src_text[] = {
1930         "None", "RXANCL", "RXANCR",
1931 };
1932
1933 const struct soc_enum madera_output_anc_src[] = {
1934         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_1L,
1935                         MADERA_OUT1L_ANC_SRC_SHIFT,
1936                         ARRAY_SIZE(madera_out_anc_src_text),
1937                         madera_out_anc_src_text),
1938         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_1R,
1939                         MADERA_OUT1R_ANC_SRC_SHIFT,
1940                         ARRAY_SIZE(madera_out_anc_src_text),
1941                         madera_out_anc_src_text),
1942         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_2L,
1943                         MADERA_OUT2L_ANC_SRC_SHIFT,
1944                         ARRAY_SIZE(madera_out_anc_src_text),
1945                         madera_out_anc_src_text),
1946         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_2R,
1947                         MADERA_OUT2R_ANC_SRC_SHIFT,
1948                         ARRAY_SIZE(madera_out_anc_src_text),
1949                         madera_out_anc_src_text),
1950         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_3L,
1951                         MADERA_OUT3L_ANC_SRC_SHIFT,
1952                         ARRAY_SIZE(madera_out_anc_src_text),
1953                         madera_out_anc_src_text),
1954         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_3R,
1955                         MADERA_OUT3R_ANC_SRC_SHIFT,
1956                         ARRAY_SIZE(madera_out_anc_src_text),
1957                         madera_out_anc_src_text),
1958         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_4L,
1959                         MADERA_OUT4L_ANC_SRC_SHIFT,
1960                         ARRAY_SIZE(madera_out_anc_src_text),
1961                         madera_out_anc_src_text),
1962         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_4R,
1963                         MADERA_OUT4R_ANC_SRC_SHIFT,
1964                         ARRAY_SIZE(madera_out_anc_src_text),
1965                         madera_out_anc_src_text),
1966         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_5L,
1967                         MADERA_OUT5L_ANC_SRC_SHIFT,
1968                         ARRAY_SIZE(madera_out_anc_src_text),
1969                         madera_out_anc_src_text),
1970         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_5R,
1971                         MADERA_OUT5R_ANC_SRC_SHIFT,
1972                         ARRAY_SIZE(madera_out_anc_src_text),
1973                         madera_out_anc_src_text),
1974         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_6L,
1975                         MADERA_OUT6L_ANC_SRC_SHIFT,
1976                         ARRAY_SIZE(madera_out_anc_src_text),
1977                         madera_out_anc_src_text),
1978         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_6R,
1979                         MADERA_OUT6R_ANC_SRC_SHIFT,
1980                         ARRAY_SIZE(madera_out_anc_src_text),
1981                         madera_out_anc_src_text),
1982 };
1983 EXPORT_SYMBOL_GPL(madera_output_anc_src);
1984
1985 int madera_dfc_put(struct snd_kcontrol *kcontrol,
1986                    struct snd_ctl_elem_value *ucontrol)
1987 {
1988         struct snd_soc_component *component =
1989                 snd_soc_kcontrol_component(kcontrol);
1990         struct snd_soc_dapm_context *dapm =
1991                 snd_soc_component_get_dapm(component);
1992         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1993         unsigned int reg = e->reg;
1994         unsigned int val;
1995         int ret = 0;
1996
1997         reg = ((reg / 6) * 6) - 2;
1998
1999         snd_soc_dapm_mutex_lock(dapm);
2000
2001         ret = snd_soc_component_read(component, reg, &val);
2002         if (ret)
2003                 goto exit;
2004
2005         if (val & MADERA_DFC1_ENA) {
2006                 ret = -EBUSY;
2007                 dev_err(component->dev, "Can't change mode on an active DFC\n");
2008                 goto exit;
2009         }
2010
2011         ret = snd_soc_put_enum_double(kcontrol, ucontrol);
2012 exit:
2013         snd_soc_dapm_mutex_unlock(dapm);
2014
2015         return ret;
2016 }
2017 EXPORT_SYMBOL_GPL(madera_dfc_put);
2018
2019 int madera_lp_mode_put(struct snd_kcontrol *kcontrol,
2020                        struct snd_ctl_elem_value *ucontrol)
2021 {
2022         struct soc_mixer_control *mc =
2023                 (struct soc_mixer_control *)kcontrol->private_value;
2024         struct snd_soc_component *component =
2025                 snd_soc_kcontrol_component(kcontrol);
2026         struct snd_soc_dapm_context *dapm =
2027                 snd_soc_component_get_dapm(component);
2028         unsigned int val, mask;
2029         int ret;
2030
2031         snd_soc_dapm_mutex_lock(dapm);
2032
2033         /* Cannot change lp mode on an active input */
2034         ret = snd_soc_component_read(component, MADERA_INPUT_ENABLES, &val);
2035         if (ret)
2036                 goto exit;
2037         mask = (mc->reg - MADERA_ADC_DIGITAL_VOLUME_1L) / 4;
2038         mask ^= 0x1; /* Flip bottom bit for channel order */
2039
2040         if (val & (1 << mask)) {
2041                 ret = -EBUSY;
2042                 dev_err(component->dev,
2043                         "Can't change lp mode on an active input\n");
2044                 goto exit;
2045         }
2046
2047         ret = snd_soc_put_volsw(kcontrol, ucontrol);
2048
2049 exit:
2050         snd_soc_dapm_mutex_unlock(dapm);
2051
2052         return ret;
2053 }
2054 EXPORT_SYMBOL_GPL(madera_lp_mode_put);
2055
2056 const struct snd_kcontrol_new madera_dsp_trigger_output_mux[] = {
2057         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2058         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2059         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2060         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2061         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2062         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2063         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2064 };
2065 EXPORT_SYMBOL_GPL(madera_dsp_trigger_output_mux);
2066
2067 const struct snd_kcontrol_new madera_drc_activity_output_mux[] = {
2068         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2069         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2070 };
2071 EXPORT_SYMBOL_GPL(madera_drc_activity_output_mux);
2072
2073 static void madera_in_set_vu(struct madera_priv *priv, bool enable)
2074 {
2075         unsigned int val;
2076         int i, ret;
2077
2078         if (enable)
2079                 val = MADERA_IN_VU;
2080         else
2081                 val = 0;
2082
2083         for (i = 0; i < priv->num_inputs; i++) {
2084                 ret = regmap_update_bits(priv->madera->regmap,
2085                                          MADERA_ADC_DIGITAL_VOLUME_1L + (i * 4),
2086                                          MADERA_IN_VU, val);
2087                 if (ret)
2088                         dev_warn(priv->madera->dev,
2089                                  "Failed to modify VU bits: %d\n", ret);
2090         }
2091 }
2092
2093 int madera_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
2094                  int event)
2095 {
2096         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2097         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2098         unsigned int reg, val;
2099         int ret;
2100
2101         if (w->shift % 2)
2102                 reg = MADERA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
2103         else
2104                 reg = MADERA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
2105
2106         switch (event) {
2107         case SND_SOC_DAPM_PRE_PMU:
2108                 priv->in_pending++;
2109                 break;
2110         case SND_SOC_DAPM_POST_PMU:
2111                 priv->in_pending--;
2112                 snd_soc_component_update_bits(component, reg,
2113                                               MADERA_IN1L_MUTE, 0);
2114
2115                 /* If this is the last input pending then allow VU */
2116                 if (priv->in_pending == 0) {
2117                         usleep_range(1000, 3000);
2118                         madera_in_set_vu(priv, true);
2119                 }
2120                 break;
2121         case SND_SOC_DAPM_PRE_PMD:
2122                 snd_soc_component_update_bits(component, reg,
2123                                               MADERA_IN1L_MUTE | MADERA_IN_VU,
2124                                               MADERA_IN1L_MUTE | MADERA_IN_VU);
2125                 break;
2126         case SND_SOC_DAPM_POST_PMD:
2127                 /* Disable volume updates if no inputs are enabled */
2128                 ret = snd_soc_component_read(component, MADERA_INPUT_ENABLES,
2129                                              &val);
2130                 if (!ret && !val)
2131                         madera_in_set_vu(priv, false);
2132                 break;
2133         default:
2134                 break;
2135         }
2136
2137         return 0;
2138 }
2139 EXPORT_SYMBOL_GPL(madera_in_ev);
2140
2141 int madera_out_ev(struct snd_soc_dapm_widget *w,
2142                   struct snd_kcontrol *kcontrol, int event)
2143 {
2144         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2145         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2146         struct madera *madera = priv->madera;
2147         int out_up_delay;
2148
2149         switch (madera->type) {
2150         case CS47L90:
2151         case CS47L91:
2152                 out_up_delay = 6;
2153                 break;
2154         default:
2155                 out_up_delay = 17;
2156                 break;
2157         }
2158
2159         switch (event) {
2160         case SND_SOC_DAPM_PRE_PMU:
2161                 switch (w->shift) {
2162                 case MADERA_OUT1L_ENA_SHIFT:
2163                 case MADERA_OUT1R_ENA_SHIFT:
2164                 case MADERA_OUT2L_ENA_SHIFT:
2165                 case MADERA_OUT2R_ENA_SHIFT:
2166                 case MADERA_OUT3L_ENA_SHIFT:
2167                 case MADERA_OUT3R_ENA_SHIFT:
2168                         priv->out_up_pending++;
2169                         priv->out_up_delay += out_up_delay;
2170                         break;
2171                 default:
2172                         break;
2173                 }
2174                 break;
2175
2176         case SND_SOC_DAPM_POST_PMU:
2177                 switch (w->shift) {
2178                 case MADERA_OUT1L_ENA_SHIFT:
2179                 case MADERA_OUT1R_ENA_SHIFT:
2180                 case MADERA_OUT2L_ENA_SHIFT:
2181                 case MADERA_OUT2R_ENA_SHIFT:
2182                 case MADERA_OUT3L_ENA_SHIFT:
2183                 case MADERA_OUT3R_ENA_SHIFT:
2184                         priv->out_up_pending--;
2185                         if (!priv->out_up_pending) {
2186                                 msleep(priv->out_up_delay);
2187                                 priv->out_up_delay = 0;
2188                         }
2189                         break;
2190
2191                 default:
2192                         break;
2193                 }
2194                 break;
2195
2196         case SND_SOC_DAPM_PRE_PMD:
2197                 switch (w->shift) {
2198                 case MADERA_OUT1L_ENA_SHIFT:
2199                 case MADERA_OUT1R_ENA_SHIFT:
2200                 case MADERA_OUT2L_ENA_SHIFT:
2201                 case MADERA_OUT2R_ENA_SHIFT:
2202                 case MADERA_OUT3L_ENA_SHIFT:
2203                 case MADERA_OUT3R_ENA_SHIFT:
2204                         priv->out_down_pending++;
2205                         priv->out_down_delay++;
2206                         break;
2207                 default:
2208                         break;
2209                 }
2210                 break;
2211
2212         case SND_SOC_DAPM_POST_PMD:
2213                 switch (w->shift) {
2214                 case MADERA_OUT1L_ENA_SHIFT:
2215                 case MADERA_OUT1R_ENA_SHIFT:
2216                 case MADERA_OUT2L_ENA_SHIFT:
2217                 case MADERA_OUT2R_ENA_SHIFT:
2218                 case MADERA_OUT3L_ENA_SHIFT:
2219                 case MADERA_OUT3R_ENA_SHIFT:
2220                         priv->out_down_pending--;
2221                         if (!priv->out_down_pending) {
2222                                 msleep(priv->out_down_delay);
2223                                 priv->out_down_delay = 0;
2224                         }
2225                         break;
2226                 default:
2227                         break;
2228                 }
2229                 break;
2230         default:
2231                 break;
2232         }
2233
2234         return 0;
2235 }
2236 EXPORT_SYMBOL_GPL(madera_out_ev);
2237
2238 int madera_hp_ev(struct snd_soc_dapm_widget *w,
2239                  struct snd_kcontrol *kcontrol, int event)
2240 {
2241         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2242         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2243         struct madera *madera = priv->madera;
2244         unsigned int mask = 1 << w->shift;
2245         unsigned int out_num = w->shift / 2;
2246         unsigned int val;
2247         unsigned int ep_sel = 0;
2248
2249         switch (event) {
2250         case SND_SOC_DAPM_POST_PMU:
2251                 val = mask;
2252                 break;
2253         case SND_SOC_DAPM_PRE_PMD:
2254                 val = 0;
2255                 break;
2256         case SND_SOC_DAPM_PRE_PMU:
2257         case SND_SOC_DAPM_POST_PMD:
2258                 return madera_out_ev(w, kcontrol, event);
2259         default:
2260                 return 0;
2261         }
2262
2263         /* Store the desired state for the HP outputs */
2264         madera->hp_ena &= ~mask;
2265         madera->hp_ena |= val;
2266
2267         /* if OUT1 is routed to EPOUT, ignore HP clamp and impedance */
2268         regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
2269         ep_sel &= MADERA_EP_SEL_MASK;
2270
2271         /* Force off if HPDET has disabled the clamp for this output */
2272         if (!ep_sel &&
2273             (!madera->out_clamp[out_num] || madera->out_shorted[out_num]))
2274                 val = 0;
2275
2276         regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, mask, val);
2277
2278         return madera_out_ev(w, kcontrol, event);
2279 }
2280 EXPORT_SYMBOL_GPL(madera_hp_ev);
2281
2282 int madera_anc_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
2283                   int event)
2284 {
2285         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2286         unsigned int val;
2287
2288         switch (event) {
2289         case SND_SOC_DAPM_POST_PMU:
2290                 val = 1 << w->shift;
2291                 break;
2292         case SND_SOC_DAPM_PRE_PMD:
2293                 val = 1 << (w->shift + 1);
2294                 break;
2295         default:
2296                 return 0;
2297         }
2298
2299         snd_soc_component_write(component, MADERA_CLOCK_CONTROL, val);
2300
2301         return 0;
2302 }
2303 EXPORT_SYMBOL_GPL(madera_anc_ev);
2304
2305 static const unsigned int madera_opclk_ref_48k_rates[] = {
2306         6144000,
2307         12288000,
2308         24576000,
2309         49152000,
2310 };
2311
2312 static const unsigned int madera_opclk_ref_44k1_rates[] = {
2313         5644800,
2314         11289600,
2315         22579200,
2316         45158400,
2317 };
2318
2319 static int madera_set_opclk(struct snd_soc_component *component,
2320                             unsigned int clk, unsigned int freq)
2321 {
2322         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2323         unsigned int mask = MADERA_OPCLK_DIV_MASK | MADERA_OPCLK_SEL_MASK;
2324         unsigned int reg, val;
2325         const unsigned int *rates;
2326         int ref, div, refclk;
2327
2328         BUILD_BUG_ON(ARRAY_SIZE(madera_opclk_ref_48k_rates) !=
2329                      ARRAY_SIZE(madera_opclk_ref_44k1_rates));
2330
2331         switch (clk) {
2332         case MADERA_CLK_OPCLK:
2333                 reg = MADERA_OUTPUT_SYSTEM_CLOCK;
2334                 refclk = priv->sysclk;
2335                 break;
2336         case MADERA_CLK_ASYNC_OPCLK:
2337                 reg = MADERA_OUTPUT_ASYNC_CLOCK;
2338                 refclk = priv->asyncclk;
2339                 break;
2340         default:
2341                 return -EINVAL;
2342         }
2343
2344         if (refclk % 4000)
2345                 rates = madera_opclk_ref_44k1_rates;
2346         else
2347                 rates = madera_opclk_ref_48k_rates;
2348
2349         for (ref = 0; ref < ARRAY_SIZE(madera_opclk_ref_48k_rates); ++ref) {
2350                 if (rates[ref] > refclk)
2351                         continue;
2352
2353                 div = 2;
2354                 while ((rates[ref] / div >= freq) && (div <= 30)) {
2355                         if (rates[ref] / div == freq) {
2356                                 dev_dbg(component->dev, "Configured %dHz OPCLK\n",
2357                                         freq);
2358
2359                                 val = (div << MADERA_OPCLK_DIV_SHIFT) | ref;
2360
2361                                 snd_soc_component_update_bits(component, reg,
2362                                                               mask, val);
2363                                 return 0;
2364                         }
2365                         div += 2;
2366                 }
2367         }
2368
2369         dev_err(component->dev, "Unable to generate %dHz OPCLK\n", freq);
2370
2371         return -EINVAL;
2372 }
2373
2374 static int madera_get_sysclk_setting(unsigned int freq)
2375 {
2376         switch (freq) {
2377         case 0:
2378         case 5644800:
2379         case 6144000:
2380                 return 0;
2381         case 11289600:
2382         case 12288000:
2383                 return MADERA_SYSCLK_12MHZ << MADERA_SYSCLK_FREQ_SHIFT;
2384         case 22579200:
2385         case 24576000:
2386                 return MADERA_SYSCLK_24MHZ << MADERA_SYSCLK_FREQ_SHIFT;
2387         case 45158400:
2388         case 49152000:
2389                 return MADERA_SYSCLK_49MHZ << MADERA_SYSCLK_FREQ_SHIFT;
2390         case 90316800:
2391         case 98304000:
2392                 return MADERA_SYSCLK_98MHZ << MADERA_SYSCLK_FREQ_SHIFT;
2393         default:
2394                 return -EINVAL;
2395         }
2396 }
2397
2398 static int madera_get_legacy_dspclk_setting(struct madera *madera,
2399                                             unsigned int freq)
2400 {
2401         switch (freq) {
2402         case 0:
2403                 return 0;
2404         case 45158400:
2405         case 49152000:
2406                 switch (madera->type) {
2407                 case CS47L85:
2408                 case WM1840:
2409                         if (madera->rev < 3)
2410                                 return -EINVAL;
2411                         else
2412                                 return MADERA_SYSCLK_49MHZ <<
2413                                        MADERA_SYSCLK_FREQ_SHIFT;
2414                 default:
2415                         return -EINVAL;
2416                 }
2417         case 135475200:
2418         case 147456000:
2419                 return MADERA_DSPCLK_147MHZ << MADERA_DSP_CLK_FREQ_LEGACY_SHIFT;
2420         default:
2421                 return -EINVAL;
2422         }
2423 }
2424
2425 static int madera_get_dspclk_setting(struct madera *madera,
2426                                      unsigned int freq,
2427                                      unsigned int *clock_2_val)
2428 {
2429         switch (madera->type) {
2430         case CS47L35:
2431         case CS47L85:
2432         case WM1840:
2433                 *clock_2_val = 0; /* don't use MADERA_DSP_CLOCK_2 */
2434                 return madera_get_legacy_dspclk_setting(madera, freq);
2435         default:
2436                 if (freq > 150000000)
2437                         return -EINVAL;
2438
2439                 /* Use new exact frequency control */
2440                 *clock_2_val = freq / 15625; /* freq * (2^6) / (10^6) */
2441                 return 0;
2442         }
2443 }
2444
2445 int madera_set_sysclk(struct snd_soc_component *component, int clk_id,
2446                       int source, unsigned int freq, int dir)
2447 {
2448         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2449         struct madera *madera = priv->madera;
2450         char *name;
2451         unsigned int reg, clock_2_val = 0;
2452         unsigned int mask = MADERA_SYSCLK_FREQ_MASK | MADERA_SYSCLK_SRC_MASK;
2453         unsigned int val = source << MADERA_SYSCLK_SRC_SHIFT;
2454         int clk_freq_sel, *clk;
2455         int ret = 0;
2456
2457         switch (clk_id) {
2458         case MADERA_CLK_SYSCLK_1:
2459                 name = "SYSCLK";
2460                 reg = MADERA_SYSTEM_CLOCK_1;
2461                 clk = &priv->sysclk;
2462                 clk_freq_sel = madera_get_sysclk_setting(freq);
2463                 mask |= MADERA_SYSCLK_FRAC;
2464                 break;
2465         case MADERA_CLK_ASYNCCLK_1:
2466                 name = "ASYNCCLK";
2467                 reg = MADERA_ASYNC_CLOCK_1;
2468                 clk = &priv->asyncclk;
2469                 clk_freq_sel = madera_get_sysclk_setting(freq);
2470                 break;
2471         case MADERA_CLK_DSPCLK:
2472                 name = "DSPCLK";
2473                 reg = MADERA_DSP_CLOCK_1;
2474                 clk = &priv->dspclk;
2475                 clk_freq_sel = madera_get_dspclk_setting(madera, freq,
2476                                                          &clock_2_val);
2477                 break;
2478         case MADERA_CLK_OPCLK:
2479         case MADERA_CLK_ASYNC_OPCLK:
2480                 return madera_set_opclk(component, clk_id, freq);
2481         default:
2482                 return -EINVAL;
2483         }
2484
2485         if (clk_freq_sel < 0) {
2486                 dev_err(madera->dev,
2487                         "Failed to get clk setting for %dHZ\n", freq);
2488                 return clk_freq_sel;
2489         }
2490
2491         *clk = freq;
2492
2493         if (freq == 0) {
2494                 dev_dbg(madera->dev, "%s cleared\n", name);
2495                 return 0;
2496         }
2497
2498         val |= clk_freq_sel;
2499
2500         if (clock_2_val) {
2501                 ret = regmap_write(madera->regmap, MADERA_DSP_CLOCK_2,
2502                                    clock_2_val);
2503                 if (ret) {
2504                         dev_err(madera->dev,
2505                                 "Failed to write DSP_CONFIG2: %d\n", ret);
2506                         return ret;
2507                 }
2508
2509                 /*
2510                  * We're using the frequency setting in MADERA_DSP_CLOCK_2 so
2511                  * don't change the frequency select bits in MADERA_DSP_CLOCK_1
2512                  */
2513                 mask = MADERA_SYSCLK_SRC_MASK;
2514         }
2515
2516         if (freq % 6144000)
2517                 val |= MADERA_SYSCLK_FRAC;
2518
2519         dev_dbg(madera->dev, "%s set to %uHz\n", name, freq);
2520
2521         return regmap_update_bits(madera->regmap, reg, mask, val);
2522 }
2523 EXPORT_SYMBOL_GPL(madera_set_sysclk);
2524
2525 static int madera_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2526 {
2527         struct snd_soc_component *component = dai->component;
2528         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2529         struct madera *madera = priv->madera;
2530         int lrclk, bclk, mode, base;
2531
2532         base = dai->driver->base;
2533
2534         lrclk = 0;
2535         bclk = 0;
2536
2537         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2538         case SND_SOC_DAIFMT_DSP_A:
2539                 mode = MADERA_FMT_DSP_MODE_A;
2540                 break;
2541         case SND_SOC_DAIFMT_DSP_B:
2542                 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) !=
2543                     SND_SOC_DAIFMT_CBM_CFM) {
2544                         madera_aif_err(dai, "DSP_B not valid in slave mode\n");
2545                         return -EINVAL;
2546                 }
2547                 mode = MADERA_FMT_DSP_MODE_B;
2548                 break;
2549         case SND_SOC_DAIFMT_I2S:
2550                 mode = MADERA_FMT_I2S_MODE;
2551                 break;
2552         case SND_SOC_DAIFMT_LEFT_J:
2553                 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) !=
2554                     SND_SOC_DAIFMT_CBM_CFM) {
2555                         madera_aif_err(dai, "LEFT_J not valid in slave mode\n");
2556                         return -EINVAL;
2557                 }
2558                 mode = MADERA_FMT_LEFT_JUSTIFIED_MODE;
2559                 break;
2560         default:
2561                 madera_aif_err(dai, "Unsupported DAI format %d\n",
2562                                fmt & SND_SOC_DAIFMT_FORMAT_MASK);
2563                 return -EINVAL;
2564         }
2565
2566         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2567         case SND_SOC_DAIFMT_CBS_CFS:
2568                 break;
2569         case SND_SOC_DAIFMT_CBS_CFM:
2570                 lrclk |= MADERA_AIF1TX_LRCLK_MSTR;
2571                 break;
2572         case SND_SOC_DAIFMT_CBM_CFS:
2573                 bclk |= MADERA_AIF1_BCLK_MSTR;
2574                 break;
2575         case SND_SOC_DAIFMT_CBM_CFM:
2576                 bclk |= MADERA_AIF1_BCLK_MSTR;
2577                 lrclk |= MADERA_AIF1TX_LRCLK_MSTR;
2578                 break;
2579         default:
2580                 madera_aif_err(dai, "Unsupported master mode %d\n",
2581                                fmt & SND_SOC_DAIFMT_MASTER_MASK);
2582                 return -EINVAL;
2583         }
2584
2585         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2586         case SND_SOC_DAIFMT_NB_NF:
2587                 break;
2588         case SND_SOC_DAIFMT_IB_IF:
2589                 bclk |= MADERA_AIF1_BCLK_INV;
2590                 lrclk |= MADERA_AIF1TX_LRCLK_INV;
2591                 break;
2592         case SND_SOC_DAIFMT_IB_NF:
2593                 bclk |= MADERA_AIF1_BCLK_INV;
2594                 break;
2595         case SND_SOC_DAIFMT_NB_IF:
2596                 lrclk |= MADERA_AIF1TX_LRCLK_INV;
2597                 break;
2598         default:
2599                 madera_aif_err(dai, "Unsupported invert mode %d\n",
2600                                fmt & SND_SOC_DAIFMT_INV_MASK);
2601                 return -EINVAL;
2602         }
2603
2604         regmap_update_bits(madera->regmap, base + MADERA_AIF_BCLK_CTRL,
2605                            MADERA_AIF1_BCLK_INV | MADERA_AIF1_BCLK_MSTR,
2606                            bclk);
2607         regmap_update_bits(madera->regmap, base + MADERA_AIF_TX_PIN_CTRL,
2608                            MADERA_AIF1TX_LRCLK_INV | MADERA_AIF1TX_LRCLK_MSTR,
2609                            lrclk);
2610         regmap_update_bits(madera->regmap, base + MADERA_AIF_RX_PIN_CTRL,
2611                            MADERA_AIF1RX_LRCLK_INV | MADERA_AIF1RX_LRCLK_MSTR,
2612                            lrclk);
2613         regmap_update_bits(madera->regmap, base + MADERA_AIF_FORMAT,
2614                            MADERA_AIF1_FMT_MASK, mode);
2615
2616         return 0;
2617 }
2618
2619 static const int madera_48k_bclk_rates[] = {
2620         -1,
2621         48000,
2622         64000,
2623         96000,
2624         128000,
2625         192000,
2626         256000,
2627         384000,
2628         512000,
2629         768000,
2630         1024000,
2631         1536000,
2632         2048000,
2633         3072000,
2634         4096000,
2635         6144000,
2636         8192000,
2637         12288000,
2638         24576000,
2639 };
2640
2641 static const int madera_44k1_bclk_rates[] = {
2642         -1,
2643         44100,
2644         58800,
2645         88200,
2646         117600,
2647         177640,
2648         235200,
2649         352800,
2650         470400,
2651         705600,
2652         940800,
2653         1411200,
2654         1881600,
2655         2822400,
2656         3763200,
2657         5644800,
2658         7526400,
2659         11289600,
2660         22579200,
2661 };
2662
2663 static const unsigned int madera_sr_vals[] = {
2664         0,
2665         12000,
2666         24000,
2667         48000,
2668         96000,
2669         192000,
2670         384000,
2671         768000,
2672         0,
2673         11025,
2674         22050,
2675         44100,
2676         88200,
2677         176400,
2678         352800,
2679         705600,
2680         4000,
2681         8000,
2682         16000,
2683         32000,
2684         64000,
2685         128000,
2686         256000,
2687         512000,
2688 };
2689
2690 #define MADERA_192K_48K_RATE_MASK       0x0F003E
2691 #define MADERA_192K_44K1_RATE_MASK      0x003E00
2692 #define MADERA_192K_RATE_MASK           (MADERA_192K_48K_RATE_MASK | \
2693                                          MADERA_192K_44K1_RATE_MASK)
2694
2695 static const struct snd_pcm_hw_constraint_list madera_constraint = {
2696         .count  = ARRAY_SIZE(madera_sr_vals),
2697         .list   = madera_sr_vals,
2698 };
2699
2700 static int madera_startup(struct snd_pcm_substream *substream,
2701                           struct snd_soc_dai *dai)
2702 {
2703         struct snd_soc_component *component = dai->component;
2704         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2705         struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
2706         unsigned int base_rate;
2707
2708         if (!substream->runtime)
2709                 return 0;
2710
2711         switch (dai_priv->clk) {
2712         case MADERA_CLK_SYSCLK_1:
2713         case MADERA_CLK_SYSCLK_2:
2714         case MADERA_CLK_SYSCLK_3:
2715                 base_rate = priv->sysclk;
2716                 break;
2717         case MADERA_CLK_ASYNCCLK_1:
2718         case MADERA_CLK_ASYNCCLK_2:
2719                 base_rate = priv->asyncclk;
2720                 break;
2721         default:
2722                 return 0;
2723         }
2724
2725         if (base_rate == 0)
2726                 dai_priv->constraint.mask = MADERA_192K_RATE_MASK;
2727         else if (base_rate % 4000)
2728                 dai_priv->constraint.mask = MADERA_192K_44K1_RATE_MASK;
2729         else
2730                 dai_priv->constraint.mask = MADERA_192K_48K_RATE_MASK;
2731
2732         return snd_pcm_hw_constraint_list(substream->runtime, 0,
2733                                           SNDRV_PCM_HW_PARAM_RATE,
2734                                           &dai_priv->constraint);
2735 }
2736
2737 static int madera_hw_params_rate(struct snd_pcm_substream *substream,
2738                                  struct snd_pcm_hw_params *params,
2739                                  struct snd_soc_dai *dai)
2740 {
2741         struct snd_soc_component *component = dai->component;
2742         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2743         struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
2744         int base = dai->driver->base;
2745         int i, sr_val;
2746         unsigned int reg, cur, tar;
2747         int ret;
2748
2749         for (i = 0; i < ARRAY_SIZE(madera_sr_vals); i++)
2750                 if (madera_sr_vals[i] == params_rate(params))
2751                         break;
2752
2753         if (i == ARRAY_SIZE(madera_sr_vals)) {
2754                 madera_aif_err(dai, "Unsupported sample rate %dHz\n",
2755                                params_rate(params));
2756                 return -EINVAL;
2757         }
2758         sr_val = i;
2759
2760         switch (dai_priv->clk) {
2761         case MADERA_CLK_SYSCLK_1:
2762                 reg = MADERA_SAMPLE_RATE_1;
2763                 tar = 0 << MADERA_AIF1_RATE_SHIFT;
2764                 break;
2765         case MADERA_CLK_SYSCLK_2:
2766                 reg = MADERA_SAMPLE_RATE_2;
2767                 tar = 1 << MADERA_AIF1_RATE_SHIFT;
2768                 break;
2769         case MADERA_CLK_SYSCLK_3:
2770                 reg = MADERA_SAMPLE_RATE_3;
2771                 tar = 2 << MADERA_AIF1_RATE_SHIFT;
2772                 break;
2773         case MADERA_CLK_ASYNCCLK_1:
2774                 reg = MADERA_ASYNC_SAMPLE_RATE_1,
2775                 tar = 8 << MADERA_AIF1_RATE_SHIFT;
2776                 break;
2777         case MADERA_CLK_ASYNCCLK_2:
2778                 reg = MADERA_ASYNC_SAMPLE_RATE_2,
2779                 tar = 9 << MADERA_AIF1_RATE_SHIFT;
2780                 break;
2781         default:
2782                 madera_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
2783                 return -EINVAL;
2784         }
2785
2786         snd_soc_component_update_bits(component, reg, MADERA_SAMPLE_RATE_1_MASK,
2787                                       sr_val);
2788
2789         if (!base)
2790                 return 0;
2791
2792         ret = regmap_read(priv->madera->regmap,
2793                           base + MADERA_AIF_RATE_CTRL, &cur);
2794         if (ret != 0) {
2795                 madera_aif_err(dai, "Failed to check rate: %d\n", ret);
2796                 return ret;
2797         }
2798
2799         if ((cur & MADERA_AIF1_RATE_MASK) == (tar & MADERA_AIF1_RATE_MASK))
2800                 return 0;
2801
2802         mutex_lock(&priv->rate_lock);
2803
2804         if (!madera_can_change_grp_rate(priv, base + MADERA_AIF_RATE_CTRL)) {
2805                 madera_aif_warn(dai, "Cannot change rate while active\n");
2806                 ret = -EBUSY;
2807                 goto out;
2808         }
2809
2810         /* Guard the rate change with SYSCLK cycles */
2811         madera_spin_sysclk(priv);
2812         snd_soc_component_update_bits(component, base + MADERA_AIF_RATE_CTRL,
2813                                       MADERA_AIF1_RATE_MASK, tar);
2814         madera_spin_sysclk(priv);
2815
2816 out:
2817         mutex_unlock(&priv->rate_lock);
2818
2819         return ret;
2820 }
2821
2822 static int madera_aif_cfg_changed(struct snd_soc_component *component,
2823                                   int base, int bclk, int lrclk, int frame)
2824 {
2825         unsigned int val;
2826         int ret;
2827
2828         ret = snd_soc_component_read(component, base + MADERA_AIF_BCLK_CTRL,
2829                                      &val);
2830         if (ret)
2831                 return ret;
2832         if (bclk != (val & MADERA_AIF1_BCLK_FREQ_MASK))
2833                 return 1;
2834
2835         ret = snd_soc_component_read(component, base + MADERA_AIF_RX_BCLK_RATE,
2836                                      &val);
2837         if (ret)
2838                 return ret;
2839         if (lrclk != (val & MADERA_AIF1RX_BCPF_MASK))
2840                 return 1;
2841
2842         ret = snd_soc_component_read(component, base + MADERA_AIF_FRAME_CTRL_1,
2843                                      &val);
2844         if (ret)
2845                 return ret;
2846         if (frame != (val & (MADERA_AIF1TX_WL_MASK |
2847                              MADERA_AIF1TX_SLOT_LEN_MASK)))
2848                 return 1;
2849
2850         return 0;
2851 }
2852
2853 static int madera_hw_params(struct snd_pcm_substream *substream,
2854                             struct snd_pcm_hw_params *params,
2855                             struct snd_soc_dai *dai)
2856 {
2857         struct snd_soc_component *component = dai->component;
2858         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2859         struct madera *madera = priv->madera;
2860         int base = dai->driver->base;
2861         const int *rates;
2862         int i, ret;
2863         unsigned int val;
2864         unsigned int channels = params_channels(params);
2865         unsigned int rate = params_rate(params);
2866         unsigned int chan_limit =
2867                         madera->pdata.codec.max_channels_clocked[dai->id - 1];
2868         int tdm_width = priv->tdm_width[dai->id - 1];
2869         int tdm_slots = priv->tdm_slots[dai->id - 1];
2870         int bclk, lrclk, wl, frame, bclk_target, num_rates;
2871         int reconfig;
2872         unsigned int aif_tx_state = 0, aif_rx_state = 0;
2873
2874         if (rate % 4000) {
2875                 rates = &madera_44k1_bclk_rates[0];
2876                 num_rates = ARRAY_SIZE(madera_44k1_bclk_rates);
2877         } else {
2878                 rates = &madera_48k_bclk_rates[0];
2879                 num_rates = ARRAY_SIZE(madera_48k_bclk_rates);
2880         }
2881
2882         wl = snd_pcm_format_width(params_format(params));
2883
2884         if (tdm_slots) {
2885                 madera_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
2886                                tdm_slots, tdm_width);
2887                 bclk_target = tdm_slots * tdm_width * rate;
2888                 channels = tdm_slots;
2889         } else {
2890                 bclk_target = snd_soc_params_to_bclk(params);
2891                 tdm_width = wl;
2892         }
2893
2894         if (chan_limit && chan_limit < channels) {
2895                 madera_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
2896                 bclk_target /= channels;
2897                 bclk_target *= chan_limit;
2898         }
2899
2900         /* Force multiple of 2 channels for I2S mode */
2901         ret = snd_soc_component_read(component, base + MADERA_AIF_FORMAT, &val);
2902         if (ret)
2903                 return ret;
2904
2905         val &= MADERA_AIF1_FMT_MASK;
2906         if ((channels & 1) && val == MADERA_FMT_I2S_MODE) {
2907                 madera_aif_dbg(dai, "Forcing stereo mode\n");
2908                 bclk_target /= channels;
2909                 bclk_target *= channels + 1;
2910         }
2911
2912         for (i = 0; i < num_rates; i++) {
2913                 if (rates[i] >= bclk_target && rates[i] % rate == 0) {
2914                         bclk = i;
2915                         break;
2916                 }
2917         }
2918
2919         if (i == num_rates) {
2920                 madera_aif_err(dai, "Unsupported sample rate %dHz\n", rate);
2921                 return -EINVAL;
2922         }
2923
2924         lrclk = rates[bclk] / rate;
2925
2926         madera_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
2927                        rates[bclk], rates[bclk] / lrclk);
2928
2929         frame = wl << MADERA_AIF1TX_WL_SHIFT | tdm_width;
2930
2931         reconfig = madera_aif_cfg_changed(component, base, bclk, lrclk, frame);
2932         if (reconfig < 0)
2933                 return reconfig;
2934
2935         if (reconfig) {
2936                 /* Save AIF TX/RX state */
2937                 regmap_read(madera->regmap, base + MADERA_AIF_TX_ENABLES,
2938                             &aif_tx_state);
2939                 regmap_read(madera->regmap, base + MADERA_AIF_RX_ENABLES,
2940                             &aif_rx_state);
2941                 /* Disable AIF TX/RX before reconfiguring it */
2942                 regmap_update_bits(madera->regmap,
2943                                    base + MADERA_AIF_TX_ENABLES, 0xff, 0x0);
2944                 regmap_update_bits(madera->regmap,
2945                                    base + MADERA_AIF_RX_ENABLES, 0xff, 0x0);
2946         }
2947
2948         ret = madera_hw_params_rate(substream, params, dai);
2949         if (ret != 0)
2950                 goto restore_aif;
2951
2952         if (reconfig) {
2953                 regmap_update_bits(madera->regmap,
2954                                    base + MADERA_AIF_BCLK_CTRL,
2955                                    MADERA_AIF1_BCLK_FREQ_MASK, bclk);
2956                 regmap_update_bits(madera->regmap,
2957                                    base + MADERA_AIF_RX_BCLK_RATE,
2958                                    MADERA_AIF1RX_BCPF_MASK, lrclk);
2959                 regmap_update_bits(madera->regmap,
2960                                    base + MADERA_AIF_FRAME_CTRL_1,
2961                                    MADERA_AIF1TX_WL_MASK |
2962                                    MADERA_AIF1TX_SLOT_LEN_MASK, frame);
2963                 regmap_update_bits(madera->regmap,
2964                                    base + MADERA_AIF_FRAME_CTRL_2,
2965                                    MADERA_AIF1RX_WL_MASK |
2966                                    MADERA_AIF1RX_SLOT_LEN_MASK, frame);
2967         }
2968
2969 restore_aif:
2970         if (reconfig) {
2971                 /* Restore AIF TX/RX state */
2972                 regmap_update_bits(madera->regmap,
2973                                    base + MADERA_AIF_TX_ENABLES,
2974                                    0xff, aif_tx_state);
2975                 regmap_update_bits(madera->regmap,
2976                                    base + MADERA_AIF_RX_ENABLES,
2977                                    0xff, aif_rx_state);
2978         }
2979
2980         return ret;
2981 }
2982
2983 static int madera_is_syncclk(int clk_id)
2984 {
2985         switch (clk_id) {
2986         case MADERA_CLK_SYSCLK_1:
2987         case MADERA_CLK_SYSCLK_2:
2988         case MADERA_CLK_SYSCLK_3:
2989                 return 1;
2990         case MADERA_CLK_ASYNCCLK_1:
2991         case MADERA_CLK_ASYNCCLK_2:
2992                 return 0;
2993         default:
2994                 return -EINVAL;
2995         }
2996 }
2997
2998 static int madera_dai_set_sysclk(struct snd_soc_dai *dai,
2999                                  int clk_id, unsigned int freq, int dir)
3000 {
3001         struct snd_soc_component *component = dai->component;
3002         struct snd_soc_dapm_context *dapm =
3003                 snd_soc_component_get_dapm(component);
3004         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
3005         struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
3006         struct snd_soc_dapm_route routes[2];
3007         int is_sync;
3008
3009         is_sync = madera_is_syncclk(clk_id);
3010         if (is_sync < 0) {
3011                 dev_err(component->dev, "Illegal DAI clock id %d\n", clk_id);
3012                 return is_sync;
3013         }
3014
3015         if (is_sync == madera_is_syncclk(dai_priv->clk))
3016                 return 0;
3017
3018         if (dai->active) {
3019                 dev_err(component->dev, "Can't change clock on active DAI %d\n",
3020                         dai->id);
3021                 return -EBUSY;
3022         }
3023
3024         dev_dbg(component->dev, "Setting AIF%d to %s\n", dai->id,
3025                 is_sync ? "SYSCLK" : "ASYNCCLK");
3026
3027         /*
3028          * A connection to SYSCLK is always required, we only add and remove
3029          * a connection to ASYNCCLK
3030          */
3031         memset(&routes, 0, sizeof(routes));
3032         routes[0].sink = dai->driver->capture.stream_name;
3033         routes[1].sink = dai->driver->playback.stream_name;
3034         routes[0].source = "ASYNCCLK";
3035         routes[1].source = "ASYNCCLK";
3036
3037         if (is_sync)
3038                 snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
3039         else
3040                 snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
3041
3042         dai_priv->clk = clk_id;
3043
3044         return snd_soc_dapm_sync(dapm);
3045 }
3046
3047 static int madera_set_tristate(struct snd_soc_dai *dai, int tristate)
3048 {
3049         struct snd_soc_component *component = dai->component;
3050         int base = dai->driver->base;
3051         unsigned int reg;
3052         int ret;
3053
3054         if (tristate)
3055                 reg = MADERA_AIF1_TRI;
3056         else
3057                 reg = 0;
3058
3059         ret = snd_soc_component_update_bits(component,
3060                                             base + MADERA_AIF_RATE_CTRL,
3061                                             MADERA_AIF1_TRI, reg);
3062         if (ret < 0)
3063                 return ret;
3064         else
3065                 return 0;
3066 }
3067
3068 static void madera_set_channels_to_mask(struct snd_soc_dai *dai,
3069                                         unsigned int base,
3070                                         int channels, unsigned int mask)
3071 {
3072         struct snd_soc_component *component = dai->component;
3073         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
3074         struct madera *madera = priv->madera;
3075         int slot, i;
3076
3077         for (i = 0; i < channels; ++i) {
3078                 slot = ffs(mask) - 1;
3079                 if (slot < 0)
3080                         return;
3081
3082                 regmap_write(madera->regmap, base + i, slot);
3083
3084                 mask &= ~(1 << slot);
3085         }
3086
3087         if (mask)
3088                 madera_aif_warn(dai, "Too many channels in TDM mask\n");
3089 }
3090
3091 static int madera_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
3092                                unsigned int rx_mask, int slots, int slot_width)
3093 {
3094         struct snd_soc_component *component = dai->component;
3095         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
3096         int base = dai->driver->base;
3097         int rx_max_chan = dai->driver->playback.channels_max;
3098         int tx_max_chan = dai->driver->capture.channels_max;
3099
3100         /* Only support TDM for the physical AIFs */
3101         if (dai->id > MADERA_MAX_AIF)
3102                 return -ENOTSUPP;
3103
3104         if (slots == 0) {
3105                 tx_mask = (1 << tx_max_chan) - 1;
3106                 rx_mask = (1 << rx_max_chan) - 1;
3107         }
3108
3109         madera_set_channels_to_mask(dai, base + MADERA_AIF_FRAME_CTRL_3,
3110                                     tx_max_chan, tx_mask);
3111         madera_set_channels_to_mask(dai, base + MADERA_AIF_FRAME_CTRL_11,
3112                                     rx_max_chan, rx_mask);
3113
3114         priv->tdm_width[dai->id - 1] = slot_width;
3115         priv->tdm_slots[dai->id - 1] = slots;
3116
3117         return 0;
3118 }
3119
3120 const struct snd_soc_dai_ops madera_dai_ops = {
3121         .startup = &madera_startup,
3122         .set_fmt = &madera_set_fmt,
3123         .set_tdm_slot = &madera_set_tdm_slot,
3124         .hw_params = &madera_hw_params,
3125         .set_sysclk = &madera_dai_set_sysclk,
3126         .set_tristate = &madera_set_tristate,
3127 };
3128 EXPORT_SYMBOL_GPL(madera_dai_ops);
3129
3130 const struct snd_soc_dai_ops madera_simple_dai_ops = {
3131         .startup = &madera_startup,
3132         .hw_params = &madera_hw_params_rate,
3133         .set_sysclk = &madera_dai_set_sysclk,
3134 };
3135 EXPORT_SYMBOL_GPL(madera_simple_dai_ops);
3136
3137 int madera_init_dai(struct madera_priv *priv, int id)
3138 {
3139         struct madera_dai_priv *dai_priv = &priv->dai[id];
3140
3141         dai_priv->clk = MADERA_CLK_SYSCLK_1;
3142         dai_priv->constraint = madera_constraint;
3143
3144         return 0;
3145 }
3146 EXPORT_SYMBOL_GPL(madera_init_dai);
3147
3148 static const struct {
3149         unsigned int min;
3150         unsigned int max;
3151         u16 fratio;
3152         int ratio;
3153 } fll_sync_fratios[] = {
3154         {       0,    64000, 4, 16 },
3155         {   64000,   128000, 3,  8 },
3156         {  128000,   256000, 2,  4 },
3157         {  256000,  1000000, 1,  2 },
3158         { 1000000, 13500000, 0,  1 },
3159 };
3160
3161 static const unsigned int pseudo_fref_max[MADERA_FLL_MAX_FRATIO] = {
3162         13500000,
3163          6144000,
3164          6144000,
3165          3072000,
3166          3072000,
3167          2822400,
3168          2822400,
3169          1536000,
3170          1536000,
3171          1536000,
3172          1536000,
3173          1536000,
3174          1536000,
3175          1536000,
3176          1536000,
3177           768000,
3178 };
3179
3180 struct madera_fll_gains {
3181         unsigned int min;
3182         unsigned int max;
3183         int gain;               /* main gain */
3184         int alt_gain;           /* alternate integer gain */
3185 };
3186
3187 static const struct madera_fll_gains madera_fll_sync_gains[] = {
3188         {       0,   256000, 0, -1 },
3189         {  256000,  1000000, 2, -1 },
3190         { 1000000, 13500000, 4, -1 },
3191 };
3192
3193 static const struct madera_fll_gains madera_fll_main_gains[] = {
3194         {       0,   100000, 0, 2 },
3195         {  100000,   375000, 2, 2 },
3196         {  375000,   768000, 3, 2 },
3197         {  768001,  1500000, 3, 3 },
3198         { 1500000,  6000000, 4, 3 },
3199         { 6000000, 13500000, 5, 3 },
3200 };
3201
3202 static int madera_find_sync_fratio(unsigned int fref, int *fratio)
3203 {
3204         int i;
3205
3206         for (i = 0; i < ARRAY_SIZE(fll_sync_fratios); i++) {
3207                 if (fll_sync_fratios[i].min <= fref &&
3208                     fref <= fll_sync_fratios[i].max) {
3209                         if (fratio)
3210                                 *fratio = fll_sync_fratios[i].fratio;
3211
3212                         return fll_sync_fratios[i].ratio;
3213                 }
3214         }
3215
3216         return -EINVAL;
3217 }
3218
3219 static int madera_find_main_fratio(unsigned int fref, unsigned int fout,
3220                                    int *fratio)
3221 {
3222         int ratio = 1;
3223
3224         while ((fout / (ratio * fref)) > MADERA_FLL_MAX_N)
3225                 ratio++;
3226
3227         if (fratio)
3228                 *fratio = ratio - 1;
3229
3230         return ratio;
3231 }
3232
3233 static int madera_find_fratio(struct madera_fll *fll, unsigned int fref,
3234                               bool sync, int *fratio)
3235 {
3236         switch (fll->madera->type) {
3237         case CS47L35:
3238                 switch (fll->madera->rev) {
3239                 case 0:
3240                         /* rev A0 uses sync calculation for both loops */
3241                         return madera_find_sync_fratio(fref, fratio);
3242                 default:
3243                         if (sync)
3244                                 return madera_find_sync_fratio(fref, fratio);
3245                         else
3246                                 return madera_find_main_fratio(fref,
3247                                                                fll->fout,
3248                                                                fratio);
3249                 }
3250                 break;
3251         case CS47L85:
3252         case WM1840:
3253                 /* these use the same calculation for main and sync loops */
3254                 return madera_find_sync_fratio(fref, fratio);
3255         default:
3256                 if (sync)
3257                         return madera_find_sync_fratio(fref, fratio);
3258                 else
3259                         return madera_find_main_fratio(fref, fll->fout, fratio);
3260         }
3261 }
3262
3263 static int madera_calc_fratio(struct madera_fll *fll,
3264                               struct madera_fll_cfg *cfg,
3265                               unsigned int fref, bool sync)
3266 {
3267         int init_ratio, ratio;
3268         int refdiv, div;
3269
3270         /* fref must be <=13.5MHz, find initial refdiv */
3271         div = 1;
3272         cfg->refdiv = 0;
3273         while (fref > MADERA_FLL_MAX_FREF) {
3274                 div *= 2;
3275                 fref /= 2;
3276                 cfg->refdiv++;
3277
3278                 if (div > MADERA_FLL_MAX_REFDIV)
3279                         return -EINVAL;
3280         }
3281
3282         /* Find an appropriate FLL_FRATIO */
3283         init_ratio = madera_find_fratio(fll, fref, sync, &cfg->fratio);
3284         if (init_ratio < 0) {
3285                 madera_fll_err(fll, "Unable to find FRATIO for fref=%uHz\n",
3286                                fref);
3287                 return init_ratio;
3288         }
3289
3290         if (!sync)
3291                 cfg->fratio = init_ratio - 1;
3292
3293         switch (fll->madera->type) {
3294         case CS47L35:
3295                 switch (fll->madera->rev) {
3296                 case 0:
3297                         if (sync)
3298                                 return init_ratio;
3299                         break;
3300                 default:
3301                         return init_ratio;
3302                 }
3303                 break;
3304         case CS47L85:
3305         case WM1840:
3306                 if (sync)
3307                         return init_ratio;
3308                 break;
3309         default:
3310                 return init_ratio;
3311         }
3312
3313         /*
3314          * For CS47L35 rev A0, CS47L85 and WM1840 adjust FRATIO/refdiv to avoid
3315          * integer mode if possible
3316          */
3317         refdiv = cfg->refdiv;
3318
3319         while (div <= MADERA_FLL_MAX_REFDIV) {
3320                 /*
3321                  * start from init_ratio because this may already give a
3322                  * fractional N.K
3323                  */
3324                 for (ratio = init_ratio; ratio > 0; ratio--) {
3325                         if (fll->fout % (ratio * fref)) {
3326                                 cfg->refdiv = refdiv;
3327                                 cfg->fratio = ratio - 1;
3328                                 return ratio;
3329                         }
3330                 }
3331
3332                 for (ratio = init_ratio + 1; ratio <= MADERA_FLL_MAX_FRATIO;
3333                      ratio++) {
3334                         if ((MADERA_FLL_VCO_CORNER / 2) /
3335                             (MADERA_FLL_VCO_MULT * ratio) < fref)
3336                                 break;
3337
3338                         if (fref > pseudo_fref_max[ratio - 1])
3339                                 break;
3340
3341                         if (fll->fout % (ratio * fref)) {
3342                                 cfg->refdiv = refdiv;
3343                                 cfg->fratio = ratio - 1;
3344                                 return ratio;
3345                         }
3346                 }
3347
3348                 div *= 2;
3349                 fref /= 2;
3350                 refdiv++;
3351                 init_ratio = madera_find_fratio(fll, fref, sync, NULL);
3352         }
3353
3354         madera_fll_warn(fll, "Falling back to integer mode operation\n");
3355
3356         return cfg->fratio + 1;
3357 }
3358
3359 static int madera_find_fll_gain(struct madera_fll *fll,
3360                                 struct madera_fll_cfg *cfg,
3361                                 unsigned int fref,
3362                                 const struct madera_fll_gains *gains,
3363                                 int n_gains)
3364 {
3365         int i;
3366
3367         for (i = 0; i < n_gains; i++) {
3368                 if (gains[i].min <= fref && fref <= gains[i].max) {
3369                         cfg->gain = gains[i].gain;
3370                         cfg->alt_gain = gains[i].alt_gain;
3371                         return 0;
3372                 }
3373         }
3374
3375         madera_fll_err(fll, "Unable to find gain for fref=%uHz\n", fref);
3376
3377         return -EINVAL;
3378 }
3379
3380 static int madera_calc_fll(struct madera_fll *fll,
3381                            struct madera_fll_cfg *cfg,
3382                            unsigned int fref, bool sync)
3383 {
3384         unsigned int gcd_fll;
3385         const struct madera_fll_gains *gains;
3386         int n_gains;
3387         int ratio, ret;
3388
3389         madera_fll_dbg(fll, "fref=%u Fout=%u fvco=%u\n",
3390                        fref, fll->fout, fll->fout * MADERA_FLL_VCO_MULT);
3391
3392         /* Find an appropriate FLL_FRATIO and refdiv */
3393         ratio = madera_calc_fratio(fll, cfg, fref, sync);
3394         if (ratio < 0)
3395                 return ratio;
3396
3397         /* Apply the division for our remaining calculations */
3398         fref = fref / (1 << cfg->refdiv);
3399
3400         cfg->n = fll->fout / (ratio * fref);
3401
3402         if (fll->fout % (ratio * fref)) {
3403                 gcd_fll = gcd(fll->fout, ratio * fref);
3404                 madera_fll_dbg(fll, "GCD=%u\n", gcd_fll);
3405
3406                 cfg->theta = (fll->fout - (cfg->n * ratio * fref))
3407                         / gcd_fll;
3408                 cfg->lambda = (ratio * fref) / gcd_fll;
3409         } else {
3410                 cfg->theta = 0;
3411                 cfg->lambda = 0;
3412         }
3413
3414         /*
3415          * Round down to 16bit range with cost of accuracy lost.
3416          * Denominator must be bigger than numerator so we only
3417          * take care of it.
3418          */
3419         while (cfg->lambda >= (1 << 16)) {
3420                 cfg->theta >>= 1;
3421                 cfg->lambda >>= 1;
3422         }
3423
3424         switch (fll->madera->type) {
3425         case CS47L35:
3426                 switch (fll->madera->rev) {
3427                 case 0:
3428                         /* Rev A0 uses the sync gains for both loops */
3429                         gains = madera_fll_sync_gains;
3430                         n_gains = ARRAY_SIZE(madera_fll_sync_gains);
3431                         break;
3432                 default:
3433                         if (sync) {
3434                                 gains = madera_fll_sync_gains;
3435                                 n_gains = ARRAY_SIZE(madera_fll_sync_gains);
3436                         } else {
3437                                 gains = madera_fll_main_gains;
3438                                 n_gains = ARRAY_SIZE(madera_fll_main_gains);
3439                         }
3440                         break;
3441                 }
3442                 break;
3443         case CS47L85:
3444         case WM1840:
3445                 /* These use the sync gains for both loops */
3446                 gains = madera_fll_sync_gains;
3447                 n_gains = ARRAY_SIZE(madera_fll_sync_gains);
3448                 break;
3449         default:
3450                 if (sync) {
3451                         gains = madera_fll_sync_gains;
3452                         n_gains = ARRAY_SIZE(madera_fll_sync_gains);
3453                 } else {
3454                         gains = madera_fll_main_gains;
3455                         n_gains = ARRAY_SIZE(madera_fll_main_gains);
3456                 }
3457                 break;
3458         }
3459
3460         ret = madera_find_fll_gain(fll, cfg, fref, gains, n_gains);
3461         if (ret)
3462                 return ret;
3463
3464         madera_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
3465                        cfg->n, cfg->theta, cfg->lambda);
3466         madera_fll_dbg(fll, "FRATIO=0x%x(%d) REFCLK_DIV=0x%x(%d)\n",
3467                        cfg->fratio, ratio, cfg->refdiv, 1 << cfg->refdiv);
3468         madera_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
3469
3470         return 0;
3471 }
3472
3473 static bool madera_write_fll(struct madera *madera, unsigned int base,
3474                              struct madera_fll_cfg *cfg, int source,
3475                              bool sync, int gain)
3476 {
3477         bool change, fll_change;
3478
3479         fll_change = false;
3480         regmap_update_bits_check(madera->regmap,
3481                                  base + MADERA_FLL_CONTROL_3_OFFS,
3482                                  MADERA_FLL1_THETA_MASK,
3483                                  cfg->theta, &change);
3484         fll_change |= change;
3485         regmap_update_bits_check(madera->regmap,
3486                                  base + MADERA_FLL_CONTROL_4_OFFS,
3487                                  MADERA_FLL1_LAMBDA_MASK,
3488                                  cfg->lambda, &change);
3489         fll_change |= change;
3490         regmap_update_bits_check(madera->regmap,
3491                                  base + MADERA_FLL_CONTROL_5_OFFS,
3492                                  MADERA_FLL1_FRATIO_MASK,
3493                                  cfg->fratio << MADERA_FLL1_FRATIO_SHIFT,
3494                                  &change);
3495         fll_change |= change;
3496         regmap_update_bits_check(madera->regmap,
3497                                  base + MADERA_FLL_CONTROL_6_OFFS,
3498                                  MADERA_FLL1_REFCLK_DIV_MASK |
3499                                  MADERA_FLL1_REFCLK_SRC_MASK,
3500                                  cfg->refdiv << MADERA_FLL1_REFCLK_DIV_SHIFT |
3501                                  source << MADERA_FLL1_REFCLK_SRC_SHIFT,
3502                                  &change);
3503         fll_change |= change;
3504
3505         if (sync) {
3506                 regmap_update_bits_check(madera->regmap,
3507                                          base + MADERA_FLL_SYNCHRONISER_7_OFFS,
3508                                          MADERA_FLL1_GAIN_MASK,
3509                                          gain << MADERA_FLL1_GAIN_SHIFT,
3510                                          &change);
3511                 fll_change |= change;
3512         } else {
3513                 regmap_update_bits_check(madera->regmap,
3514                                          base + MADERA_FLL_CONTROL_7_OFFS,
3515                                          MADERA_FLL1_GAIN_MASK,
3516                                          gain << MADERA_FLL1_GAIN_SHIFT,
3517                                          &change);
3518                 fll_change |= change;
3519         }
3520
3521         regmap_update_bits_check(madera->regmap,
3522                                  base + MADERA_FLL_CONTROL_2_OFFS,
3523                                  MADERA_FLL1_CTRL_UPD | MADERA_FLL1_N_MASK,
3524                                  MADERA_FLL1_CTRL_UPD | cfg->n, &change);
3525         fll_change |= change;
3526
3527         return fll_change;
3528 }
3529
3530 static int madera_is_enabled_fll(struct madera_fll *fll, int base)
3531 {
3532         struct madera *madera = fll->madera;
3533         unsigned int reg;
3534         int ret;
3535
3536         ret = regmap_read(madera->regmap,
3537                           base + MADERA_FLL_CONTROL_1_OFFS, &reg);
3538         if (ret != 0) {
3539                 madera_fll_err(fll, "Failed to read current state: %d\n", ret);
3540                 return ret;
3541         }
3542
3543         return reg & MADERA_FLL1_ENA;
3544 }
3545
3546 static int madera_wait_for_fll(struct madera_fll *fll, bool requested)
3547 {
3548         struct madera *madera = fll->madera;
3549         unsigned int val = 0;
3550         bool status;
3551         int i;
3552
3553         madera_fll_dbg(fll, "Waiting for FLL...\n");
3554
3555         for (i = 0; i < 30; i++) {
3556                 regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_2, &val);
3557                 status = val & (MADERA_FLL1_LOCK_STS1 << (fll->id - 1));
3558                 if (status == requested)
3559                         return 0;
3560
3561                 switch (i) {
3562                 case 0 ... 5:
3563                         usleep_range(75, 125);
3564                         break;
3565                 case 11 ... 20:
3566                         usleep_range(750, 1250);
3567                         break;
3568                 default:
3569                         msleep(20);
3570                         break;
3571                 }
3572         }
3573
3574         madera_fll_warn(fll, "Timed out waiting for lock\n");
3575
3576         return -ETIMEDOUT;
3577 }
3578
3579 static bool madera_set_fll_phase_integrator(struct madera_fll *fll,
3580                                             struct madera_fll_cfg *ref_cfg,
3581                                             bool sync)
3582 {
3583         unsigned int val;
3584         bool reg_change;
3585
3586         if (!sync && ref_cfg->theta == 0)
3587                 val = (1 << MADERA_FLL1_PHASE_ENA_SHIFT) |
3588                       (2 << MADERA_FLL1_PHASE_GAIN_SHIFT);
3589         else
3590                 val = 2 << MADERA_FLL1_PHASE_GAIN_SHIFT;
3591
3592         regmap_update_bits_check(fll->madera->regmap,
3593                                  fll->base + MADERA_FLL_EFS_2_OFFS,
3594                                  MADERA_FLL1_PHASE_ENA_MASK |
3595                                  MADERA_FLL1_PHASE_GAIN_MASK,
3596                                  val, &reg_change);
3597
3598         return reg_change;
3599 }
3600
3601 static void madera_disable_fll(struct madera_fll *fll)
3602 {
3603         struct madera *madera = fll->madera;
3604         unsigned int sync_base;
3605         bool change;
3606
3607         switch (madera->type) {
3608         case CS47L35:
3609                 sync_base = fll->base + CS47L35_FLL_SYNCHRONISER_OFFS;
3610                 break;
3611         default:
3612                 sync_base = fll->base + MADERA_FLL_SYNCHRONISER_OFFS;
3613                 break;
3614         }
3615
3616         madera_fll_dbg(fll, "Disabling FLL\n");
3617
3618         regmap_update_bits(madera->regmap,
3619                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
3620                            MADERA_FLL1_FREERUN, MADERA_FLL1_FREERUN);
3621         regmap_update_bits_check(madera->regmap,
3622                                  fll->base + MADERA_FLL_CONTROL_1_OFFS,
3623                                  MADERA_FLL1_ENA, 0, &change);
3624         regmap_update_bits(madera->regmap,
3625                            sync_base + MADERA_FLL_SYNCHRONISER_1_OFFS,
3626                            MADERA_FLL1_SYNC_ENA, 0);
3627         regmap_update_bits(madera->regmap,
3628                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
3629                            MADERA_FLL1_FREERUN, 0);
3630
3631         madera_wait_for_fll(fll, false);
3632
3633         if (change)
3634                 pm_runtime_put_autosuspend(madera->dev);
3635 }
3636
3637 static int madera_enable_fll(struct madera_fll *fll)
3638 {
3639         struct madera *madera = fll->madera;
3640         bool have_sync = false;
3641         int already_enabled = madera_is_enabled_fll(fll, fll->base);
3642         int sync_enabled;
3643         struct madera_fll_cfg cfg;
3644         unsigned int sync_base;
3645         int gain, ret;
3646         bool fll_change = false;
3647
3648         if (already_enabled < 0)
3649                 return already_enabled; /* error getting current state */
3650
3651         if (fll->ref_src < 0 || fll->ref_freq == 0) {
3652                 madera_fll_err(fll, "No REFCLK\n");
3653                 ret = -EINVAL;
3654                 goto err;
3655         }
3656
3657         madera_fll_dbg(fll, "Enabling FLL, initially %s\n",
3658                        already_enabled ? "enabled" : "disabled");
3659
3660         if (fll->fout < MADERA_FLL_MIN_FOUT ||
3661             fll->fout > MADERA_FLL_MAX_FOUT) {
3662                 madera_fll_err(fll, "invalid fout %uHz\n", fll->fout);
3663                 ret = -EINVAL;
3664                 goto err;
3665         }
3666
3667         switch (madera->type) {
3668         case CS47L35:
3669                 sync_base = fll->base + CS47L35_FLL_SYNCHRONISER_OFFS;
3670                 break;
3671         default:
3672                 sync_base = fll->base + MADERA_FLL_SYNCHRONISER_OFFS;
3673                 break;
3674         }
3675
3676         sync_enabled = madera_is_enabled_fll(fll, sync_base);
3677         if (sync_enabled < 0)
3678                 return sync_enabled;
3679
3680         if (already_enabled) {
3681                 /* Facilitate smooth refclk across the transition */
3682                 regmap_update_bits(fll->madera->regmap,
3683                                    fll->base + MADERA_FLL_CONTROL_1_OFFS,
3684                                    MADERA_FLL1_FREERUN,
3685                                    MADERA_FLL1_FREERUN);
3686                 udelay(32);
3687                 regmap_update_bits(fll->madera->regmap,
3688                                    fll->base + MADERA_FLL_CONTROL_7_OFFS,
3689                                    MADERA_FLL1_GAIN_MASK, 0);
3690         }
3691
3692         /* Apply SYNCCLK setting */
3693         if (fll->sync_src >= 0) {
3694                 ret = madera_calc_fll(fll, &cfg, fll->sync_freq, true);
3695                 if (ret < 0)
3696                         goto err;
3697
3698                 fll_change |= madera_write_fll(madera, sync_base,
3699                                                &cfg, fll->sync_src,
3700                                                true, cfg.gain);
3701                 have_sync = true;
3702         }
3703
3704         if (already_enabled && !!sync_enabled != have_sync)
3705                 madera_fll_warn(fll, "Synchroniser changed on active FLL\n");
3706
3707         /* Apply REFCLK setting */
3708         ret = madera_calc_fll(fll, &cfg, fll->ref_freq, false);
3709         if (ret < 0)
3710                 goto err;
3711
3712         /* Ref path hardcodes lambda to 65536 when sync is on */
3713         if (have_sync && cfg.lambda)
3714                 cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
3715
3716         switch (fll->madera->type) {
3717         case CS47L35:
3718                 switch (fll->madera->rev) {
3719                 case 0:
3720                         gain = cfg.gain;
3721                         break;
3722                 default:
3723                         fll_change |=
3724                                 madera_set_fll_phase_integrator(fll, &cfg,
3725                                                                 have_sync);
3726                         if (!have_sync && cfg.theta == 0)
3727                                 gain = cfg.alt_gain;
3728                         else
3729                                 gain = cfg.gain;
3730                         break;
3731                 }
3732                 break;
3733         case CS47L85:
3734         case WM1840:
3735                 gain = cfg.gain;
3736                 break;
3737         default:
3738                 fll_change |= madera_set_fll_phase_integrator(fll, &cfg,
3739                                                               have_sync);
3740                 if (!have_sync && cfg.theta == 0)
3741                         gain = cfg.alt_gain;
3742                 else
3743                         gain = cfg.gain;
3744                 break;
3745         }
3746
3747         fll_change |= madera_write_fll(madera, fll->base,
3748                                        &cfg, fll->ref_src,
3749                                        false, gain);
3750
3751         /*
3752          * Increase the bandwidth if we're not using a low frequency
3753          * sync source.
3754          */
3755         if (have_sync && fll->sync_freq > 100000)
3756                 regmap_update_bits(madera->regmap,
3757                                    sync_base + MADERA_FLL_SYNCHRONISER_7_OFFS,
3758                                    MADERA_FLL1_SYNC_DFSAT_MASK, 0);
3759         else
3760                 regmap_update_bits(madera->regmap,
3761                                    sync_base + MADERA_FLL_SYNCHRONISER_7_OFFS,
3762                                    MADERA_FLL1_SYNC_DFSAT_MASK,
3763                                    MADERA_FLL1_SYNC_DFSAT);
3764
3765         if (!already_enabled)
3766                 pm_runtime_get_sync(madera->dev);
3767
3768         if (have_sync)
3769                 regmap_update_bits(madera->regmap,
3770                                    sync_base + MADERA_FLL_SYNCHRONISER_1_OFFS,
3771                                    MADERA_FLL1_SYNC_ENA,
3772                                    MADERA_FLL1_SYNC_ENA);
3773         regmap_update_bits(madera->regmap,
3774                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
3775                            MADERA_FLL1_ENA, MADERA_FLL1_ENA);
3776
3777         if (already_enabled)
3778                 regmap_update_bits(madera->regmap,
3779                                    fll->base + MADERA_FLL_CONTROL_1_OFFS,
3780                                    MADERA_FLL1_FREERUN, 0);
3781
3782         if (fll_change || !already_enabled)
3783                 madera_wait_for_fll(fll, true);
3784
3785         return 0;
3786
3787 err:
3788          /* In case of error don't leave the FLL running with an old config */
3789         madera_disable_fll(fll);
3790
3791         return ret;
3792 }
3793
3794 static int madera_apply_fll(struct madera_fll *fll)
3795 {
3796         if (fll->fout) {
3797                 return madera_enable_fll(fll);
3798         } else {
3799                 madera_disable_fll(fll);
3800                 return 0;
3801         }
3802 }
3803
3804 int madera_set_fll_syncclk(struct madera_fll *fll, int source,
3805                            unsigned int fref, unsigned int fout)
3806 {
3807         /*
3808          * fout is ignored, since the synchronizer is an optional extra
3809          * constraint on the Fout generated from REFCLK, so the Fout is
3810          * set when configuring REFCLK
3811          */
3812
3813         if (fll->sync_src == source && fll->sync_freq == fref)
3814                 return 0;
3815
3816         fll->sync_src = source;
3817         fll->sync_freq = fref;
3818
3819         return madera_apply_fll(fll);
3820 }
3821 EXPORT_SYMBOL_GPL(madera_set_fll_syncclk);
3822
3823 int madera_set_fll_refclk(struct madera_fll *fll, int source,
3824                           unsigned int fref, unsigned int fout)
3825 {
3826         int ret;
3827
3828         if (fll->ref_src == source &&
3829             fll->ref_freq == fref && fll->fout == fout)
3830                 return 0;
3831
3832         /*
3833          * Changes of fout on an enabled FLL aren't allowed except when
3834          * setting fout==0 to disable the FLL
3835          */
3836         if (fout && fout != fll->fout) {
3837                 ret = madera_is_enabled_fll(fll, fll->base);
3838                 if (ret < 0)
3839                         return ret;
3840
3841                 if (ret) {
3842                         madera_fll_err(fll, "Can't change Fout on active FLL\n");
3843                         return -EBUSY;
3844                 }
3845         }
3846
3847         fll->ref_src = source;
3848         fll->ref_freq = fref;
3849         fll->fout = fout;
3850
3851         return madera_apply_fll(fll);
3852 }
3853 EXPORT_SYMBOL_GPL(madera_set_fll_refclk);
3854
3855 int madera_init_fll(struct madera *madera, int id, int base,
3856                     struct madera_fll *fll)
3857 {
3858         fll->id = id;
3859         fll->base = base;
3860         fll->madera = madera;
3861         fll->ref_src = MADERA_FLL_SRC_NONE;
3862         fll->sync_src = MADERA_FLL_SRC_NONE;
3863
3864         regmap_update_bits(madera->regmap,
3865                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
3866                            MADERA_FLL1_FREERUN, 0);
3867
3868         return 0;
3869 }
3870 EXPORT_SYMBOL_GPL(madera_init_fll);
3871
3872 static const struct reg_sequence madera_fll_ao_32K_49M_patch[] = {
3873         { MADERA_FLLAO_CONTROL_2,  0x02EE },
3874         { MADERA_FLLAO_CONTROL_3,  0x0000 },
3875         { MADERA_FLLAO_CONTROL_4,  0x0001 },
3876         { MADERA_FLLAO_CONTROL_5,  0x0002 },
3877         { MADERA_FLLAO_CONTROL_6,  0x8001 },
3878         { MADERA_FLLAO_CONTROL_7,  0x0004 },
3879         { MADERA_FLLAO_CONTROL_8,  0x0077 },
3880         { MADERA_FLLAO_CONTROL_10, 0x06D8 },
3881         { MADERA_FLLAO_CONTROL_11, 0x0085 },
3882         { MADERA_FLLAO_CONTROL_2,  0x82EE },
3883 };
3884
3885 static const struct reg_sequence madera_fll_ao_32K_45M_patch[] = {
3886         { MADERA_FLLAO_CONTROL_2,  0x02B1 },
3887         { MADERA_FLLAO_CONTROL_3,  0x0001 },
3888         { MADERA_FLLAO_CONTROL_4,  0x0010 },
3889         { MADERA_FLLAO_CONTROL_5,  0x0002 },
3890         { MADERA_FLLAO_CONTROL_6,  0x8001 },
3891         { MADERA_FLLAO_CONTROL_7,  0x0004 },
3892         { MADERA_FLLAO_CONTROL_8,  0x0077 },
3893         { MADERA_FLLAO_CONTROL_10, 0x06D8 },
3894         { MADERA_FLLAO_CONTROL_11, 0x0005 },
3895         { MADERA_FLLAO_CONTROL_2,  0x82B1 },
3896 };
3897
3898 struct madera_fllao_patch {
3899         unsigned int fin;
3900         unsigned int fout;
3901         const struct reg_sequence *patch;
3902         unsigned int patch_size;
3903 };
3904
3905 static const struct madera_fllao_patch madera_fllao_settings[] = {
3906         {
3907                 .fin = 32768,
3908                 .fout = 49152000,
3909                 .patch = madera_fll_ao_32K_49M_patch,
3910                 .patch_size = ARRAY_SIZE(madera_fll_ao_32K_49M_patch),
3911
3912         },
3913         {
3914                 .fin = 32768,
3915                 .fout = 45158400,
3916                 .patch = madera_fll_ao_32K_45M_patch,
3917                 .patch_size = ARRAY_SIZE(madera_fll_ao_32K_45M_patch),
3918         },
3919 };
3920
3921 static int madera_enable_fll_ao(struct madera_fll *fll,
3922                                 const struct reg_sequence *patch,
3923                                 unsigned int patch_size)
3924 {
3925         struct madera *madera = fll->madera;
3926         int already_enabled = madera_is_enabled_fll(fll, fll->base);
3927         unsigned int val;
3928         int i;
3929
3930         if (already_enabled < 0)
3931                 return already_enabled;
3932
3933         if (!already_enabled)
3934                 pm_runtime_get_sync(madera->dev);
3935
3936         madera_fll_dbg(fll, "Enabling FLL_AO, initially %s\n",
3937                        already_enabled ? "enabled" : "disabled");
3938
3939         /* FLL_AO_HOLD must be set before configuring any registers */
3940         regmap_update_bits(fll->madera->regmap,
3941                            fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
3942                            MADERA_FLL_AO_HOLD, MADERA_FLL_AO_HOLD);
3943
3944         for (i = 0; i < patch_size; i++) {
3945                 val = patch[i].def;
3946
3947                 /* modify the patch to apply fll->ref_src as input clock */
3948                 if (patch[i].reg == MADERA_FLLAO_CONTROL_6) {
3949                         val &= ~MADERA_FLL_AO_REFCLK_SRC_MASK;
3950                         val |= (fll->ref_src << MADERA_FLL_AO_REFCLK_SRC_SHIFT)
3951                                 & MADERA_FLL_AO_REFCLK_SRC_MASK;
3952                 }
3953
3954                 regmap_write(madera->regmap, patch[i].reg, val);
3955         }
3956
3957         regmap_update_bits(madera->regmap,
3958                            fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
3959                            MADERA_FLL_AO_ENA, MADERA_FLL_AO_ENA);
3960
3961         /* Release the hold so that fll_ao locks to external frequency */
3962         regmap_update_bits(madera->regmap,
3963                            fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
3964                            MADERA_FLL_AO_HOLD, 0);
3965
3966         if (!already_enabled)
3967                 madera_wait_for_fll(fll, true);
3968
3969         return 0;
3970 }
3971
3972 static int madera_disable_fll_ao(struct madera_fll *fll)
3973 {
3974         struct madera *madera = fll->madera;
3975         bool change;
3976
3977         madera_fll_dbg(fll, "Disabling FLL_AO\n");
3978
3979         regmap_update_bits(madera->regmap,
3980                            fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
3981                            MADERA_FLL_AO_HOLD, MADERA_FLL_AO_HOLD);
3982         regmap_update_bits_check(madera->regmap,
3983                                  fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
3984                                  MADERA_FLL_AO_ENA, 0, &change);
3985
3986         madera_wait_for_fll(fll, false);
3987
3988         /*
3989          * ctrl_up gates the writes to all fll_ao register, setting it to 0
3990          * here ensures that after a runtime suspend/resume cycle when one
3991          * enables the fllao then ctrl_up is the last bit that is configured
3992          * by the fllao enable code rather than the cache sync operation which
3993          * would have updated it much earlier before writing out all fllao
3994          * registers
3995          */
3996         regmap_update_bits(madera->regmap,
3997                            fll->base + MADERA_FLLAO_CONTROL_2_OFFS,
3998                            MADERA_FLL_AO_CTRL_UPD_MASK, 0);
3999
4000         if (change)
4001                 pm_runtime_put_autosuspend(madera->dev);
4002
4003         return 0;
4004 }
4005
4006 int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
4007                              unsigned int fin, unsigned int fout)
4008 {
4009         int ret = 0;
4010         const struct reg_sequence *patch = NULL;
4011         int patch_size = 0;
4012         unsigned int i;
4013
4014         if (fll->ref_src == source &&
4015             fll->ref_freq == fin && fll->fout == fout)
4016                 return 0;
4017
4018         madera_fll_dbg(fll, "Change FLL_AO refclk to fin=%u fout=%u source=%d\n",
4019                        fin, fout, source);
4020
4021         if (fout && (fll->ref_freq != fin || fll->fout != fout)) {
4022                 for (i = 0; i < ARRAY_SIZE(madera_fllao_settings); i++) {
4023                         if (madera_fllao_settings[i].fin == fin &&
4024                             madera_fllao_settings[i].fout == fout)
4025                                 break;
4026                 }
4027
4028                 if (i == ARRAY_SIZE(madera_fllao_settings)) {
4029                         madera_fll_err(fll,
4030                                        "No matching configuration for FLL_AO\n");
4031                         return -EINVAL;
4032                 }
4033
4034                 patch = madera_fllao_settings[i].patch;
4035                 patch_size = madera_fllao_settings[i].patch_size;
4036         }
4037
4038         fll->ref_src = source;
4039         fll->ref_freq = fin;
4040         fll->fout = fout;
4041
4042         if (fout)
4043                 ret = madera_enable_fll_ao(fll, patch, patch_size);
4044         else
4045                 madera_disable_fll_ao(fll);
4046
4047         return ret;
4048 }
4049 EXPORT_SYMBOL_GPL(madera_set_fll_ao_refclk);
4050
4051 /**
4052  * madera_set_output_mode - Set the mode of the specified output
4053  *
4054  * @component: Device to configure
4055  * @output: Output number
4056  * @diff: True to set the output to differential mode
4057  *
4058  * Some systems use external analogue switches to connect more
4059  * analogue devices to the CODEC than are supported by the device.  In
4060  * some systems this requires changing the switched output from single
4061  * ended to differential mode dynamically at runtime, an operation
4062  * supported using this function.
4063  *
4064  * Most systems have a single static configuration and should use
4065  * platform data instead.
4066  */
4067 int madera_set_output_mode(struct snd_soc_component *component, int output,
4068                            bool differential)
4069 {
4070         unsigned int reg, val;
4071         int ret;
4072
4073         if (output < 1 || output > MADERA_MAX_OUTPUT)
4074                 return -EINVAL;
4075
4076         reg = MADERA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
4077
4078         if (differential)
4079                 val = MADERA_OUT1_MONO;
4080         else
4081                 val = 0;
4082
4083         ret = snd_soc_component_update_bits(component, reg, MADERA_OUT1_MONO,
4084                                             val);
4085         if (ret < 0)
4086                 return ret;
4087         else
4088                 return 0;
4089 }
4090 EXPORT_SYMBOL_GPL(madera_set_output_mode);
4091
4092 static bool madera_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
4093 {
4094         s16 a = be16_to_cpu(_a);
4095         s16 b = be16_to_cpu(_b);
4096
4097         if (!mode) {
4098                 return abs(a) >= 4096;
4099         } else {
4100                 if (abs(b) >= 4096)
4101                         return true;
4102
4103                 return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
4104         }
4105 }
4106
4107 int madera_eq_coeff_put(struct snd_kcontrol *kcontrol,
4108                         struct snd_ctl_elem_value *ucontrol)
4109 {
4110         struct snd_soc_component *component =
4111                 snd_soc_kcontrol_component(kcontrol);
4112         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
4113         struct madera *madera = priv->madera;
4114         struct soc_bytes *params = (void *)kcontrol->private_value;
4115         unsigned int val;
4116         __be16 *data;
4117         int len;
4118         int ret;
4119
4120         len = params->num_regs * regmap_get_val_bytes(madera->regmap);
4121
4122         data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
4123         if (!data)
4124                 return -ENOMEM;
4125
4126         data[0] &= cpu_to_be16(MADERA_EQ1_B1_MODE);
4127
4128         if (madera_eq_filter_unstable(!!data[0], data[1], data[2]) ||
4129             madera_eq_filter_unstable(true, data[4], data[5]) ||
4130             madera_eq_filter_unstable(true, data[8], data[9]) ||
4131             madera_eq_filter_unstable(true, data[12], data[13]) ||
4132             madera_eq_filter_unstable(false, data[16], data[17])) {
4133                 dev_err(madera->dev, "Rejecting unstable EQ coefficients\n");
4134                 ret = -EINVAL;
4135                 goto out;
4136         }
4137
4138         ret = regmap_read(madera->regmap, params->base, &val);
4139         if (ret != 0)
4140                 goto out;
4141
4142         val &= ~MADERA_EQ1_B1_MODE;
4143         data[0] |= cpu_to_be16(val);
4144
4145         ret = regmap_raw_write(madera->regmap, params->base, data, len);
4146
4147 out:
4148         kfree(data);
4149
4150         return ret;
4151 }
4152 EXPORT_SYMBOL_GPL(madera_eq_coeff_put);
4153
4154 int madera_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
4155                           struct snd_ctl_elem_value *ucontrol)
4156 {
4157         struct snd_soc_component *component =
4158                 snd_soc_kcontrol_component(kcontrol);
4159         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
4160         struct madera *madera = priv->madera;
4161         __be16 *data = (__be16 *)ucontrol->value.bytes.data;
4162         s16 val = be16_to_cpu(*data);
4163
4164         if (abs(val) >= 4096) {
4165                 dev_err(madera->dev, "Rejecting unstable LHPF coefficients\n");
4166                 return -EINVAL;
4167         }
4168
4169         return snd_soc_bytes_put(kcontrol, ucontrol);
4170 }
4171 EXPORT_SYMBOL_GPL(madera_lhpf_coeff_put);
4172
4173 MODULE_SOFTDEP("pre: madera");
4174 MODULE_DESCRIPTION("ASoC Cirrus Logic Madera codec support");
4175 MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
4176 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
4177 MODULE_LICENSE("GPL v2");