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