ASoC: Fix SND_SOC_ALL_CODECS imply misc fallout
[linux-2.6-microblaze.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 };
1908 EXPORT_SYMBOL_GPL(madera_isrc_fsh);
1909
1910 const struct soc_enum madera_isrc_fsl[] = {
1911         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_1_CTRL_2,
1912                               MADERA_ISRC1_FSL_SHIFT, 0xf,
1913                               MADERA_RATE_ENUM_SIZE,
1914                               madera_rate_text, madera_rate_val),
1915         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_2_CTRL_2,
1916                               MADERA_ISRC2_FSL_SHIFT, 0xf,
1917                               MADERA_RATE_ENUM_SIZE,
1918                               madera_rate_text, madera_rate_val),
1919         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_3_CTRL_2,
1920                               MADERA_ISRC3_FSL_SHIFT, 0xf,
1921                               MADERA_RATE_ENUM_SIZE,
1922                               madera_rate_text, madera_rate_val),
1923         SOC_VALUE_ENUM_SINGLE(MADERA_ISRC_4_CTRL_2,
1924                               MADERA_ISRC4_FSL_SHIFT, 0xf,
1925                               MADERA_RATE_ENUM_SIZE,
1926                               madera_rate_text, madera_rate_val),
1927
1928 };
1929 EXPORT_SYMBOL_GPL(madera_isrc_fsl);
1930
1931 const struct soc_enum madera_asrc1_rate[] = {
1932         SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE1,
1933                               MADERA_ASRC1_RATE1_SHIFT, 0xf,
1934                               MADERA_SYNC_RATE_ENUM_SIZE,
1935                               madera_rate_text, madera_rate_val),
1936         SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE2,
1937                               MADERA_ASRC1_RATE1_SHIFT, 0xf,
1938                               MADERA_ASYNC_RATE_ENUM_SIZE,
1939                               madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
1940                               madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
1941
1942 };
1943 EXPORT_SYMBOL_GPL(madera_asrc1_rate);
1944
1945 const struct soc_enum madera_asrc1_bidir_rate[] = {
1946         SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE1,
1947                               MADERA_ASRC1_RATE1_SHIFT, 0xf,
1948                               MADERA_RATE_ENUM_SIZE,
1949                               madera_rate_text, madera_rate_val),
1950         SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE2,
1951                               MADERA_ASRC1_RATE2_SHIFT, 0xf,
1952                               MADERA_RATE_ENUM_SIZE,
1953                               madera_rate_text, madera_rate_val),
1954 };
1955 EXPORT_SYMBOL_GPL(madera_asrc1_bidir_rate);
1956
1957 const struct soc_enum madera_asrc2_rate[] = {
1958         SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE1,
1959                               MADERA_ASRC2_RATE1_SHIFT, 0xf,
1960                               MADERA_SYNC_RATE_ENUM_SIZE,
1961                               madera_rate_text, madera_rate_val),
1962         SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE2,
1963                               MADERA_ASRC2_RATE2_SHIFT, 0xf,
1964                               MADERA_ASYNC_RATE_ENUM_SIZE,
1965                               madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
1966                               madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
1967
1968 };
1969 EXPORT_SYMBOL_GPL(madera_asrc2_rate);
1970
1971 static const char * const madera_vol_ramp_text[] = {
1972         "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
1973         "15ms/6dB", "30ms/6dB",
1974 };
1975
1976 SOC_ENUM_SINGLE_DECL(madera_in_vd_ramp,
1977                      MADERA_INPUT_VOLUME_RAMP,
1978                      MADERA_IN_VD_RAMP_SHIFT,
1979                      madera_vol_ramp_text);
1980 EXPORT_SYMBOL_GPL(madera_in_vd_ramp);
1981
1982 SOC_ENUM_SINGLE_DECL(madera_in_vi_ramp,
1983                      MADERA_INPUT_VOLUME_RAMP,
1984                      MADERA_IN_VI_RAMP_SHIFT,
1985                      madera_vol_ramp_text);
1986 EXPORT_SYMBOL_GPL(madera_in_vi_ramp);
1987
1988 SOC_ENUM_SINGLE_DECL(madera_out_vd_ramp,
1989                      MADERA_OUTPUT_VOLUME_RAMP,
1990                      MADERA_OUT_VD_RAMP_SHIFT,
1991                      madera_vol_ramp_text);
1992 EXPORT_SYMBOL_GPL(madera_out_vd_ramp);
1993
1994 SOC_ENUM_SINGLE_DECL(madera_out_vi_ramp,
1995                      MADERA_OUTPUT_VOLUME_RAMP,
1996                      MADERA_OUT_VI_RAMP_SHIFT,
1997                      madera_vol_ramp_text);
1998 EXPORT_SYMBOL_GPL(madera_out_vi_ramp);
1999
2000 static const char * const madera_lhpf_mode_text[] = {
2001         "Low-pass", "High-pass"
2002 };
2003
2004 SOC_ENUM_SINGLE_DECL(madera_lhpf1_mode,
2005                      MADERA_HPLPF1_1,
2006                      MADERA_LHPF1_MODE_SHIFT,
2007                      madera_lhpf_mode_text);
2008 EXPORT_SYMBOL_GPL(madera_lhpf1_mode);
2009
2010 SOC_ENUM_SINGLE_DECL(madera_lhpf2_mode,
2011                      MADERA_HPLPF2_1,
2012                      MADERA_LHPF2_MODE_SHIFT,
2013                      madera_lhpf_mode_text);
2014 EXPORT_SYMBOL_GPL(madera_lhpf2_mode);
2015
2016 SOC_ENUM_SINGLE_DECL(madera_lhpf3_mode,
2017                      MADERA_HPLPF3_1,
2018                      MADERA_LHPF3_MODE_SHIFT,
2019                      madera_lhpf_mode_text);
2020 EXPORT_SYMBOL_GPL(madera_lhpf3_mode);
2021
2022 SOC_ENUM_SINGLE_DECL(madera_lhpf4_mode,
2023                      MADERA_HPLPF4_1,
2024                      MADERA_LHPF4_MODE_SHIFT,
2025                      madera_lhpf_mode_text);
2026 EXPORT_SYMBOL_GPL(madera_lhpf4_mode);
2027
2028 static const char * const madera_ng_hold_text[] = {
2029         "30ms", "120ms", "250ms", "500ms",
2030 };
2031
2032 SOC_ENUM_SINGLE_DECL(madera_ng_hold,
2033                      MADERA_NOISE_GATE_CONTROL,
2034                      MADERA_NGATE_HOLD_SHIFT,
2035                      madera_ng_hold_text);
2036 EXPORT_SYMBOL_GPL(madera_ng_hold);
2037
2038 static const char * const madera_in_hpf_cut_text[] = {
2039         "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
2040 };
2041
2042 SOC_ENUM_SINGLE_DECL(madera_in_hpf_cut_enum,
2043                      MADERA_HPF_CONTROL,
2044                      MADERA_IN_HPF_CUT_SHIFT,
2045                      madera_in_hpf_cut_text);
2046 EXPORT_SYMBOL_GPL(madera_in_hpf_cut_enum);
2047
2048 static const char * const madera_in_dmic_osr_text[MADERA_OSR_ENUM_SIZE] = {
2049         "384kHz", "768kHz", "1.536MHz", "3.072MHz", "6.144MHz",
2050 };
2051
2052 static const unsigned int madera_in_dmic_osr_val[MADERA_OSR_ENUM_SIZE] = {
2053         2, 3, 4, 5, 6,
2054 };
2055
2056 const struct soc_enum madera_in_dmic_osr[] = {
2057         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC1L_CONTROL, MADERA_IN1_OSR_SHIFT,
2058                               0x7, MADERA_OSR_ENUM_SIZE,
2059                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
2060         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC2L_CONTROL, MADERA_IN2_OSR_SHIFT,
2061                               0x7, MADERA_OSR_ENUM_SIZE,
2062                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
2063         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC3L_CONTROL, MADERA_IN3_OSR_SHIFT,
2064                               0x7, MADERA_OSR_ENUM_SIZE,
2065                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
2066         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC4L_CONTROL, MADERA_IN4_OSR_SHIFT,
2067                               0x7, MADERA_OSR_ENUM_SIZE,
2068                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
2069         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC5L_CONTROL, MADERA_IN5_OSR_SHIFT,
2070                               0x7, MADERA_OSR_ENUM_SIZE,
2071                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
2072         SOC_VALUE_ENUM_SINGLE(MADERA_DMIC6L_CONTROL, MADERA_IN6_OSR_SHIFT,
2073                               0x7, MADERA_OSR_ENUM_SIZE,
2074                               madera_in_dmic_osr_text, madera_in_dmic_osr_val),
2075 };
2076 EXPORT_SYMBOL_GPL(madera_in_dmic_osr);
2077
2078 static const char * const madera_anc_input_src_text[] = {
2079         "None", "IN1", "IN2", "IN3", "IN4", "IN5", "IN6",
2080 };
2081
2082 static const char * const madera_anc_channel_src_text[] = {
2083         "None", "Left", "Right", "Combine",
2084 };
2085
2086 const struct soc_enum madera_anc_input_src[] = {
2087         SOC_ENUM_SINGLE(MADERA_ANC_SRC,
2088                         MADERA_IN_RXANCL_SEL_SHIFT,
2089                         ARRAY_SIZE(madera_anc_input_src_text),
2090                         madera_anc_input_src_text),
2091         SOC_ENUM_SINGLE(MADERA_FCL_ADC_REFORMATTER_CONTROL,
2092                         MADERA_FCL_MIC_MODE_SEL_SHIFT,
2093                         ARRAY_SIZE(madera_anc_channel_src_text),
2094                         madera_anc_channel_src_text),
2095         SOC_ENUM_SINGLE(MADERA_ANC_SRC,
2096                         MADERA_IN_RXANCR_SEL_SHIFT,
2097                         ARRAY_SIZE(madera_anc_input_src_text),
2098                         madera_anc_input_src_text),
2099         SOC_ENUM_SINGLE(MADERA_FCR_ADC_REFORMATTER_CONTROL,
2100                         MADERA_FCR_MIC_MODE_SEL_SHIFT,
2101                         ARRAY_SIZE(madera_anc_channel_src_text),
2102                         madera_anc_channel_src_text),
2103 };
2104 EXPORT_SYMBOL_GPL(madera_anc_input_src);
2105
2106 static const char * const madera_anc_ng_texts[] = {
2107         "None", "Internal", "External",
2108 };
2109
2110 SOC_ENUM_SINGLE_DECL(madera_anc_ng_enum, SND_SOC_NOPM, 0, madera_anc_ng_texts);
2111 EXPORT_SYMBOL_GPL(madera_anc_ng_enum);
2112
2113 static const char * const madera_out_anc_src_text[] = {
2114         "None", "RXANCL", "RXANCR",
2115 };
2116
2117 const struct soc_enum madera_output_anc_src[] = {
2118         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_1L,
2119                         MADERA_OUT1L_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_1R,
2123                         MADERA_OUT1R_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_2L,
2127                         MADERA_OUT2L_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_2R,
2131                         MADERA_OUT2R_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_3L,
2135                         MADERA_OUT3L_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_3R,
2139                         MADERA_OUT3R_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_4L,
2143                         MADERA_OUT4L_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_4R,
2147                         MADERA_OUT4R_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_5L,
2151                         MADERA_OUT5L_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_5R,
2155                         MADERA_OUT5R_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_6L,
2159                         MADERA_OUT6L_ANC_SRC_SHIFT,
2160                         ARRAY_SIZE(madera_out_anc_src_text),
2161                         madera_out_anc_src_text),
2162         SOC_ENUM_SINGLE(MADERA_OUTPUT_PATH_CONFIG_6R,
2163                         MADERA_OUT6R_ANC_SRC_SHIFT,
2164                         ARRAY_SIZE(madera_out_anc_src_text),
2165                         madera_out_anc_src_text),
2166 };
2167 EXPORT_SYMBOL_GPL(madera_output_anc_src);
2168
2169 int madera_dfc_put(struct snd_kcontrol *kcontrol,
2170                    struct snd_ctl_elem_value *ucontrol)
2171 {
2172         struct snd_soc_component *component =
2173                 snd_soc_kcontrol_component(kcontrol);
2174         struct snd_soc_dapm_context *dapm =
2175                 snd_soc_component_get_dapm(component);
2176         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2177         unsigned int reg = e->reg;
2178         unsigned int val;
2179         int ret = 0;
2180
2181         reg = ((reg / 6) * 6) - 2;
2182
2183         snd_soc_dapm_mutex_lock(dapm);
2184
2185         ret = snd_soc_component_read(component, reg, &val);
2186         if (ret)
2187                 goto exit;
2188
2189         if (val & MADERA_DFC1_ENA) {
2190                 ret = -EBUSY;
2191                 dev_err(component->dev, "Can't change mode on an active DFC\n");
2192                 goto exit;
2193         }
2194
2195         ret = snd_soc_put_enum_double(kcontrol, ucontrol);
2196 exit:
2197         snd_soc_dapm_mutex_unlock(dapm);
2198
2199         return ret;
2200 }
2201 EXPORT_SYMBOL_GPL(madera_dfc_put);
2202
2203 int madera_lp_mode_put(struct snd_kcontrol *kcontrol,
2204                        struct snd_ctl_elem_value *ucontrol)
2205 {
2206         struct soc_mixer_control *mc =
2207                 (struct soc_mixer_control *)kcontrol->private_value;
2208         struct snd_soc_component *component =
2209                 snd_soc_kcontrol_component(kcontrol);
2210         struct snd_soc_dapm_context *dapm =
2211                 snd_soc_component_get_dapm(component);
2212         unsigned int val, mask;
2213         int ret;
2214
2215         snd_soc_dapm_mutex_lock(dapm);
2216
2217         /* Cannot change lp mode on an active input */
2218         ret = snd_soc_component_read(component, MADERA_INPUT_ENABLES, &val);
2219         if (ret)
2220                 goto exit;
2221         mask = (mc->reg - MADERA_ADC_DIGITAL_VOLUME_1L) / 4;
2222         mask ^= 0x1; /* Flip bottom bit for channel order */
2223
2224         if (val & (1 << mask)) {
2225                 ret = -EBUSY;
2226                 dev_err(component->dev,
2227                         "Can't change lp mode on an active input\n");
2228                 goto exit;
2229         }
2230
2231         ret = snd_soc_put_volsw(kcontrol, ucontrol);
2232
2233 exit:
2234         snd_soc_dapm_mutex_unlock(dapm);
2235
2236         return ret;
2237 }
2238 EXPORT_SYMBOL_GPL(madera_lp_mode_put);
2239
2240 const struct snd_kcontrol_new madera_dsp_trigger_output_mux[] = {
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         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2245         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2246         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2247         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2248 };
2249 EXPORT_SYMBOL_GPL(madera_dsp_trigger_output_mux);
2250
2251 const struct snd_kcontrol_new madera_drc_activity_output_mux[] = {
2252         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2253         SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
2254 };
2255 EXPORT_SYMBOL_GPL(madera_drc_activity_output_mux);
2256
2257 static void madera_in_set_vu(struct madera_priv *priv, bool enable)
2258 {
2259         unsigned int val;
2260         int i, ret;
2261
2262         if (enable)
2263                 val = MADERA_IN_VU;
2264         else
2265                 val = 0;
2266
2267         for (i = 0; i < priv->num_inputs; i++) {
2268                 ret = regmap_update_bits(priv->madera->regmap,
2269                                          MADERA_ADC_DIGITAL_VOLUME_1L + (i * 4),
2270                                          MADERA_IN_VU, val);
2271                 if (ret)
2272                         dev_warn(priv->madera->dev,
2273                                  "Failed to modify VU bits: %d\n", ret);
2274         }
2275 }
2276
2277 int madera_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
2278                  int event)
2279 {
2280         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2281         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2282         unsigned int reg, val;
2283         int ret;
2284
2285         if (w->shift % 2)
2286                 reg = MADERA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
2287         else
2288                 reg = MADERA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
2289
2290         switch (event) {
2291         case SND_SOC_DAPM_PRE_PMU:
2292                 priv->in_pending++;
2293                 break;
2294         case SND_SOC_DAPM_POST_PMU:
2295                 priv->in_pending--;
2296                 snd_soc_component_update_bits(component, reg,
2297                                               MADERA_IN1L_MUTE, 0);
2298
2299                 /* If this is the last input pending then allow VU */
2300                 if (priv->in_pending == 0) {
2301                         usleep_range(1000, 3000);
2302                         madera_in_set_vu(priv, true);
2303                 }
2304                 break;
2305         case SND_SOC_DAPM_PRE_PMD:
2306                 snd_soc_component_update_bits(component, reg,
2307                                               MADERA_IN1L_MUTE | MADERA_IN_VU,
2308                                               MADERA_IN1L_MUTE | MADERA_IN_VU);
2309                 break;
2310         case SND_SOC_DAPM_POST_PMD:
2311                 /* Disable volume updates if no inputs are enabled */
2312                 ret = snd_soc_component_read(component, MADERA_INPUT_ENABLES,
2313                                              &val);
2314                 if (!ret && !val)
2315                         madera_in_set_vu(priv, false);
2316                 break;
2317         default:
2318                 break;
2319         }
2320
2321         return 0;
2322 }
2323 EXPORT_SYMBOL_GPL(madera_in_ev);
2324
2325 int madera_out_ev(struct snd_soc_dapm_widget *w,
2326                   struct snd_kcontrol *kcontrol, int event)
2327 {
2328         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2329         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2330         struct madera *madera = priv->madera;
2331         int out_up_delay;
2332
2333         switch (madera->type) {
2334         case CS47L90:
2335         case CS47L91:
2336         case CS42L92:
2337         case CS47L92:
2338         case CS47L93:
2339                 out_up_delay = 6;
2340                 break;
2341         default:
2342                 out_up_delay = 17;
2343                 break;
2344         }
2345
2346         switch (event) {
2347         case SND_SOC_DAPM_PRE_PMU:
2348                 switch (w->shift) {
2349                 case MADERA_OUT1L_ENA_SHIFT:
2350                 case MADERA_OUT1R_ENA_SHIFT:
2351                 case MADERA_OUT2L_ENA_SHIFT:
2352                 case MADERA_OUT2R_ENA_SHIFT:
2353                 case MADERA_OUT3L_ENA_SHIFT:
2354                 case MADERA_OUT3R_ENA_SHIFT:
2355                         priv->out_up_pending++;
2356                         priv->out_up_delay += out_up_delay;
2357                         break;
2358                 default:
2359                         break;
2360                 }
2361                 break;
2362
2363         case SND_SOC_DAPM_POST_PMU:
2364                 switch (w->shift) {
2365                 case MADERA_OUT1L_ENA_SHIFT:
2366                 case MADERA_OUT1R_ENA_SHIFT:
2367                 case MADERA_OUT2L_ENA_SHIFT:
2368                 case MADERA_OUT2R_ENA_SHIFT:
2369                 case MADERA_OUT3L_ENA_SHIFT:
2370                 case MADERA_OUT3R_ENA_SHIFT:
2371                         priv->out_up_pending--;
2372                         if (!priv->out_up_pending) {
2373                                 msleep(priv->out_up_delay);
2374                                 priv->out_up_delay = 0;
2375                         }
2376                         break;
2377
2378                 default:
2379                         break;
2380                 }
2381                 break;
2382
2383         case SND_SOC_DAPM_PRE_PMD:
2384                 switch (w->shift) {
2385                 case MADERA_OUT1L_ENA_SHIFT:
2386                 case MADERA_OUT1R_ENA_SHIFT:
2387                 case MADERA_OUT2L_ENA_SHIFT:
2388                 case MADERA_OUT2R_ENA_SHIFT:
2389                 case MADERA_OUT3L_ENA_SHIFT:
2390                 case MADERA_OUT3R_ENA_SHIFT:
2391                         priv->out_down_pending++;
2392                         priv->out_down_delay++;
2393                         break;
2394                 default:
2395                         break;
2396                 }
2397                 break;
2398
2399         case SND_SOC_DAPM_POST_PMD:
2400                 switch (w->shift) {
2401                 case MADERA_OUT1L_ENA_SHIFT:
2402                 case MADERA_OUT1R_ENA_SHIFT:
2403                 case MADERA_OUT2L_ENA_SHIFT:
2404                 case MADERA_OUT2R_ENA_SHIFT:
2405                 case MADERA_OUT3L_ENA_SHIFT:
2406                 case MADERA_OUT3R_ENA_SHIFT:
2407                         priv->out_down_pending--;
2408                         if (!priv->out_down_pending) {
2409                                 msleep(priv->out_down_delay);
2410                                 priv->out_down_delay = 0;
2411                         }
2412                         break;
2413                 default:
2414                         break;
2415                 }
2416                 break;
2417         default:
2418                 break;
2419         }
2420
2421         return 0;
2422 }
2423 EXPORT_SYMBOL_GPL(madera_out_ev);
2424
2425 int madera_hp_ev(struct snd_soc_dapm_widget *w,
2426                  struct snd_kcontrol *kcontrol, int event)
2427 {
2428         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2429         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2430         struct madera *madera = priv->madera;
2431         unsigned int mask = 1 << w->shift;
2432         unsigned int out_num = w->shift / 2;
2433         unsigned int val;
2434         unsigned int ep_sel = 0;
2435
2436         switch (event) {
2437         case SND_SOC_DAPM_POST_PMU:
2438                 val = mask;
2439                 break;
2440         case SND_SOC_DAPM_PRE_PMD:
2441                 val = 0;
2442                 break;
2443         case SND_SOC_DAPM_PRE_PMU:
2444         case SND_SOC_DAPM_POST_PMD:
2445                 return madera_out_ev(w, kcontrol, event);
2446         default:
2447                 return 0;
2448         }
2449
2450         /* Store the desired state for the HP outputs */
2451         madera->hp_ena &= ~mask;
2452         madera->hp_ena |= val;
2453
2454         switch (madera->type) {
2455         case CS42L92:
2456         case CS47L92:
2457         case CS47L93:
2458                 break;
2459         default:
2460                 /* if OUT1 is routed to EPOUT, ignore HP clamp and impedance */
2461                 regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
2462                 ep_sel &= MADERA_EP_SEL_MASK;
2463                 break;
2464         }
2465
2466         /* Force off if HPDET has disabled the clamp for this output */
2467         if (!ep_sel &&
2468             (!madera->out_clamp[out_num] || madera->out_shorted[out_num]))
2469                 val = 0;
2470
2471         regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, mask, val);
2472
2473         return madera_out_ev(w, kcontrol, event);
2474 }
2475 EXPORT_SYMBOL_GPL(madera_hp_ev);
2476
2477 int madera_anc_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
2478                   int event)
2479 {
2480         struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
2481         unsigned int val;
2482
2483         switch (event) {
2484         case SND_SOC_DAPM_POST_PMU:
2485                 val = 1 << w->shift;
2486                 break;
2487         case SND_SOC_DAPM_PRE_PMD:
2488                 val = 1 << (w->shift + 1);
2489                 break;
2490         default:
2491                 return 0;
2492         }
2493
2494         snd_soc_component_write(component, MADERA_CLOCK_CONTROL, val);
2495
2496         return 0;
2497 }
2498 EXPORT_SYMBOL_GPL(madera_anc_ev);
2499
2500 static const unsigned int madera_opclk_ref_48k_rates[] = {
2501         6144000,
2502         12288000,
2503         24576000,
2504         49152000,
2505 };
2506
2507 static const unsigned int madera_opclk_ref_44k1_rates[] = {
2508         5644800,
2509         11289600,
2510         22579200,
2511         45158400,
2512 };
2513
2514 static int madera_set_opclk(struct snd_soc_component *component,
2515                             unsigned int clk, unsigned int freq)
2516 {
2517         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2518         unsigned int mask = MADERA_OPCLK_DIV_MASK | MADERA_OPCLK_SEL_MASK;
2519         unsigned int reg, val;
2520         const unsigned int *rates;
2521         int ref, div, refclk;
2522
2523         BUILD_BUG_ON(ARRAY_SIZE(madera_opclk_ref_48k_rates) !=
2524                      ARRAY_SIZE(madera_opclk_ref_44k1_rates));
2525
2526         switch (clk) {
2527         case MADERA_CLK_OPCLK:
2528                 reg = MADERA_OUTPUT_SYSTEM_CLOCK;
2529                 refclk = priv->sysclk;
2530                 break;
2531         case MADERA_CLK_ASYNC_OPCLK:
2532                 reg = MADERA_OUTPUT_ASYNC_CLOCK;
2533                 refclk = priv->asyncclk;
2534                 break;
2535         default:
2536                 return -EINVAL;
2537         }
2538
2539         if (refclk % 4000)
2540                 rates = madera_opclk_ref_44k1_rates;
2541         else
2542                 rates = madera_opclk_ref_48k_rates;
2543
2544         for (ref = 0; ref < ARRAY_SIZE(madera_opclk_ref_48k_rates); ++ref) {
2545                 if (rates[ref] > refclk)
2546                         continue;
2547
2548                 div = 2;
2549                 while ((rates[ref] / div >= freq) && (div <= 30)) {
2550                         if (rates[ref] / div == freq) {
2551                                 dev_dbg(component->dev, "Configured %dHz OPCLK\n",
2552                                         freq);
2553
2554                                 val = (div << MADERA_OPCLK_DIV_SHIFT) | ref;
2555
2556                                 snd_soc_component_update_bits(component, reg,
2557                                                               mask, val);
2558                                 return 0;
2559                         }
2560                         div += 2;
2561                 }
2562         }
2563
2564         dev_err(component->dev, "Unable to generate %dHz OPCLK\n", freq);
2565
2566         return -EINVAL;
2567 }
2568
2569 static int madera_get_sysclk_setting(unsigned int freq)
2570 {
2571         switch (freq) {
2572         case 0:
2573         case 5644800:
2574         case 6144000:
2575                 return 0;
2576         case 11289600:
2577         case 12288000:
2578                 return MADERA_SYSCLK_12MHZ << MADERA_SYSCLK_FREQ_SHIFT;
2579         case 22579200:
2580         case 24576000:
2581                 return MADERA_SYSCLK_24MHZ << MADERA_SYSCLK_FREQ_SHIFT;
2582         case 45158400:
2583         case 49152000:
2584                 return MADERA_SYSCLK_49MHZ << MADERA_SYSCLK_FREQ_SHIFT;
2585         case 90316800:
2586         case 98304000:
2587                 return MADERA_SYSCLK_98MHZ << MADERA_SYSCLK_FREQ_SHIFT;
2588         default:
2589                 return -EINVAL;
2590         }
2591 }
2592
2593 static int madera_get_legacy_dspclk_setting(struct madera *madera,
2594                                             unsigned int freq)
2595 {
2596         switch (freq) {
2597         case 0:
2598                 return 0;
2599         case 45158400:
2600         case 49152000:
2601                 switch (madera->type) {
2602                 case CS47L85:
2603                 case WM1840:
2604                         if (madera->rev < 3)
2605                                 return -EINVAL;
2606                         else
2607                                 return MADERA_SYSCLK_49MHZ <<
2608                                        MADERA_SYSCLK_FREQ_SHIFT;
2609                 default:
2610                         return -EINVAL;
2611                 }
2612         case 135475200:
2613         case 147456000:
2614                 return MADERA_DSPCLK_147MHZ << MADERA_DSP_CLK_FREQ_LEGACY_SHIFT;
2615         default:
2616                 return -EINVAL;
2617         }
2618 }
2619
2620 static int madera_get_dspclk_setting(struct madera *madera,
2621                                      unsigned int freq,
2622                                      unsigned int *clock_2_val)
2623 {
2624         switch (madera->type) {
2625         case CS47L35:
2626         case CS47L85:
2627         case WM1840:
2628                 *clock_2_val = 0; /* don't use MADERA_DSP_CLOCK_2 */
2629                 return madera_get_legacy_dspclk_setting(madera, freq);
2630         default:
2631                 if (freq > 150000000)
2632                         return -EINVAL;
2633
2634                 /* Use new exact frequency control */
2635                 *clock_2_val = freq / 15625; /* freq * (2^6) / (10^6) */
2636                 return 0;
2637         }
2638 }
2639
2640 static int madera_set_outclk(struct snd_soc_component *component,
2641                              unsigned int source, unsigned int freq)
2642 {
2643         int div, div_inc, rate;
2644
2645         switch (source) {
2646         case MADERA_OUTCLK_SYSCLK:
2647                 dev_dbg(component->dev, "Configured OUTCLK to SYSCLK\n");
2648                 snd_soc_component_update_bits(component, MADERA_OUTPUT_RATE_1,
2649                                               MADERA_OUT_CLK_SRC_MASK, source);
2650                 return 0;
2651         case MADERA_OUTCLK_ASYNCCLK:
2652                 dev_dbg(component->dev, "Configured OUTCLK to ASYNCCLK\n");
2653                 snd_soc_component_update_bits(component, MADERA_OUTPUT_RATE_1,
2654                                               MADERA_OUT_CLK_SRC_MASK, source);
2655                 return 0;
2656         case MADERA_OUTCLK_MCLK1:
2657         case MADERA_OUTCLK_MCLK2:
2658         case MADERA_OUTCLK_MCLK3:
2659                 break;
2660         default:
2661                 return -EINVAL;
2662         }
2663
2664         if (freq % 4000)
2665                 rate = 5644800;
2666         else
2667                 rate = 6144000;
2668
2669         div = 1;
2670         div_inc = 0;
2671         while (div <= 8) {
2672                 if (freq / div == rate && !(freq % div)) {
2673                         dev_dbg(component->dev, "Configured %dHz OUTCLK\n", rate);
2674                         snd_soc_component_update_bits(component,
2675                                 MADERA_OUTPUT_RATE_1,
2676                                 MADERA_OUT_EXT_CLK_DIV_MASK |
2677                                 MADERA_OUT_CLK_SRC_MASK,
2678                                 (div_inc << MADERA_OUT_EXT_CLK_DIV_SHIFT) |
2679                                 source);
2680                         return 0;
2681                 }
2682                 div_inc++;
2683                 div *= 2;
2684         }
2685
2686         dev_err(component->dev,
2687                 "Unable to generate %dHz OUTCLK from %dHz MCLK\n",
2688                 rate, freq);
2689         return -EINVAL;
2690 }
2691
2692 int madera_set_sysclk(struct snd_soc_component *component, int clk_id,
2693                       int source, unsigned int freq, int dir)
2694 {
2695         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2696         struct madera *madera = priv->madera;
2697         char *name;
2698         unsigned int reg, clock_2_val = 0;
2699         unsigned int mask = MADERA_SYSCLK_FREQ_MASK | MADERA_SYSCLK_SRC_MASK;
2700         unsigned int val = source << MADERA_SYSCLK_SRC_SHIFT;
2701         int clk_freq_sel, *clk;
2702         int ret = 0;
2703
2704         switch (clk_id) {
2705         case MADERA_CLK_SYSCLK_1:
2706                 name = "SYSCLK";
2707                 reg = MADERA_SYSTEM_CLOCK_1;
2708                 clk = &priv->sysclk;
2709                 clk_freq_sel = madera_get_sysclk_setting(freq);
2710                 mask |= MADERA_SYSCLK_FRAC;
2711                 break;
2712         case MADERA_CLK_ASYNCCLK_1:
2713                 name = "ASYNCCLK";
2714                 reg = MADERA_ASYNC_CLOCK_1;
2715                 clk = &priv->asyncclk;
2716                 clk_freq_sel = madera_get_sysclk_setting(freq);
2717                 break;
2718         case MADERA_CLK_DSPCLK:
2719                 name = "DSPCLK";
2720                 reg = MADERA_DSP_CLOCK_1;
2721                 clk = &priv->dspclk;
2722                 clk_freq_sel = madera_get_dspclk_setting(madera, freq,
2723                                                          &clock_2_val);
2724                 break;
2725         case MADERA_CLK_OPCLK:
2726         case MADERA_CLK_ASYNC_OPCLK:
2727                 return madera_set_opclk(component, clk_id, freq);
2728         case MADERA_CLK_OUTCLK:
2729                 return madera_set_outclk(component, source, freq);
2730         default:
2731                 return -EINVAL;
2732         }
2733
2734         if (clk_freq_sel < 0) {
2735                 dev_err(madera->dev,
2736                         "Failed to get clk setting for %dHZ\n", freq);
2737                 return clk_freq_sel;
2738         }
2739
2740         *clk = freq;
2741
2742         if (freq == 0) {
2743                 dev_dbg(madera->dev, "%s cleared\n", name);
2744                 return 0;
2745         }
2746
2747         val |= clk_freq_sel;
2748
2749         if (clock_2_val) {
2750                 ret = regmap_write(madera->regmap, MADERA_DSP_CLOCK_2,
2751                                    clock_2_val);
2752                 if (ret) {
2753                         dev_err(madera->dev,
2754                                 "Failed to write DSP_CONFIG2: %d\n", ret);
2755                         return ret;
2756                 }
2757
2758                 /*
2759                  * We're using the frequency setting in MADERA_DSP_CLOCK_2 so
2760                  * don't change the frequency select bits in MADERA_DSP_CLOCK_1
2761                  */
2762                 mask = MADERA_SYSCLK_SRC_MASK;
2763         }
2764
2765         if (freq % 6144000)
2766                 val |= MADERA_SYSCLK_FRAC;
2767
2768         dev_dbg(madera->dev, "%s set to %uHz\n", name, freq);
2769
2770         return regmap_update_bits(madera->regmap, reg, mask, val);
2771 }
2772 EXPORT_SYMBOL_GPL(madera_set_sysclk);
2773
2774 static int madera_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2775 {
2776         struct snd_soc_component *component = dai->component;
2777         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2778         struct madera *madera = priv->madera;
2779         int lrclk, bclk, mode, base;
2780
2781         base = dai->driver->base;
2782
2783         lrclk = 0;
2784         bclk = 0;
2785
2786         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2787         case SND_SOC_DAIFMT_DSP_A:
2788                 mode = MADERA_FMT_DSP_MODE_A;
2789                 break;
2790         case SND_SOC_DAIFMT_DSP_B:
2791                 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) !=
2792                     SND_SOC_DAIFMT_CBM_CFM) {
2793                         madera_aif_err(dai, "DSP_B not valid in slave mode\n");
2794                         return -EINVAL;
2795                 }
2796                 mode = MADERA_FMT_DSP_MODE_B;
2797                 break;
2798         case SND_SOC_DAIFMT_I2S:
2799                 mode = MADERA_FMT_I2S_MODE;
2800                 break;
2801         case SND_SOC_DAIFMT_LEFT_J:
2802                 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) !=
2803                     SND_SOC_DAIFMT_CBM_CFM) {
2804                         madera_aif_err(dai, "LEFT_J not valid in slave mode\n");
2805                         return -EINVAL;
2806                 }
2807                 mode = MADERA_FMT_LEFT_JUSTIFIED_MODE;
2808                 break;
2809         default:
2810                 madera_aif_err(dai, "Unsupported DAI format %d\n",
2811                                fmt & SND_SOC_DAIFMT_FORMAT_MASK);
2812                 return -EINVAL;
2813         }
2814
2815         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2816         case SND_SOC_DAIFMT_CBS_CFS:
2817                 break;
2818         case SND_SOC_DAIFMT_CBS_CFM:
2819                 lrclk |= MADERA_AIF1TX_LRCLK_MSTR;
2820                 break;
2821         case SND_SOC_DAIFMT_CBM_CFS:
2822                 bclk |= MADERA_AIF1_BCLK_MSTR;
2823                 break;
2824         case SND_SOC_DAIFMT_CBM_CFM:
2825                 bclk |= MADERA_AIF1_BCLK_MSTR;
2826                 lrclk |= MADERA_AIF1TX_LRCLK_MSTR;
2827                 break;
2828         default:
2829                 madera_aif_err(dai, "Unsupported master mode %d\n",
2830                                fmt & SND_SOC_DAIFMT_MASTER_MASK);
2831                 return -EINVAL;
2832         }
2833
2834         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2835         case SND_SOC_DAIFMT_NB_NF:
2836                 break;
2837         case SND_SOC_DAIFMT_IB_IF:
2838                 bclk |= MADERA_AIF1_BCLK_INV;
2839                 lrclk |= MADERA_AIF1TX_LRCLK_INV;
2840                 break;
2841         case SND_SOC_DAIFMT_IB_NF:
2842                 bclk |= MADERA_AIF1_BCLK_INV;
2843                 break;
2844         case SND_SOC_DAIFMT_NB_IF:
2845                 lrclk |= MADERA_AIF1TX_LRCLK_INV;
2846                 break;
2847         default:
2848                 madera_aif_err(dai, "Unsupported invert mode %d\n",
2849                                fmt & SND_SOC_DAIFMT_INV_MASK);
2850                 return -EINVAL;
2851         }
2852
2853         regmap_update_bits(madera->regmap, base + MADERA_AIF_BCLK_CTRL,
2854                            MADERA_AIF1_BCLK_INV | MADERA_AIF1_BCLK_MSTR,
2855                            bclk);
2856         regmap_update_bits(madera->regmap, base + MADERA_AIF_TX_PIN_CTRL,
2857                            MADERA_AIF1TX_LRCLK_INV | MADERA_AIF1TX_LRCLK_MSTR,
2858                            lrclk);
2859         regmap_update_bits(madera->regmap, base + MADERA_AIF_RX_PIN_CTRL,
2860                            MADERA_AIF1RX_LRCLK_INV | MADERA_AIF1RX_LRCLK_MSTR,
2861                            lrclk);
2862         regmap_update_bits(madera->regmap, base + MADERA_AIF_FORMAT,
2863                            MADERA_AIF1_FMT_MASK, mode);
2864
2865         return 0;
2866 }
2867
2868 static const int madera_48k_bclk_rates[] = {
2869         -1,
2870         48000,
2871         64000,
2872         96000,
2873         128000,
2874         192000,
2875         256000,
2876         384000,
2877         512000,
2878         768000,
2879         1024000,
2880         1536000,
2881         2048000,
2882         3072000,
2883         4096000,
2884         6144000,
2885         8192000,
2886         12288000,
2887         24576000,
2888 };
2889
2890 static const int madera_44k1_bclk_rates[] = {
2891         -1,
2892         44100,
2893         58800,
2894         88200,
2895         117600,
2896         177640,
2897         235200,
2898         352800,
2899         470400,
2900         705600,
2901         940800,
2902         1411200,
2903         1881600,
2904         2822400,
2905         3763200,
2906         5644800,
2907         7526400,
2908         11289600,
2909         22579200,
2910 };
2911
2912 static const unsigned int madera_sr_vals[] = {
2913         0,
2914         12000,
2915         24000,
2916         48000,
2917         96000,
2918         192000,
2919         384000,
2920         768000,
2921         0,
2922         11025,
2923         22050,
2924         44100,
2925         88200,
2926         176400,
2927         352800,
2928         705600,
2929         4000,
2930         8000,
2931         16000,
2932         32000,
2933         64000,
2934         128000,
2935         256000,
2936         512000,
2937 };
2938
2939 #define MADERA_192K_48K_RATE_MASK       0x0F003E
2940 #define MADERA_192K_44K1_RATE_MASK      0x003E00
2941 #define MADERA_192K_RATE_MASK           (MADERA_192K_48K_RATE_MASK | \
2942                                          MADERA_192K_44K1_RATE_MASK)
2943 #define MADERA_384K_48K_RATE_MASK       0x0F007E
2944 #define MADERA_384K_44K1_RATE_MASK      0x007E00
2945 #define MADERA_384K_RATE_MASK           (MADERA_384K_48K_RATE_MASK | \
2946                                          MADERA_384K_44K1_RATE_MASK)
2947
2948 static const struct snd_pcm_hw_constraint_list madera_constraint = {
2949         .count  = ARRAY_SIZE(madera_sr_vals),
2950         .list   = madera_sr_vals,
2951 };
2952
2953 static int madera_startup(struct snd_pcm_substream *substream,
2954                           struct snd_soc_dai *dai)
2955 {
2956         struct snd_soc_component *component = dai->component;
2957         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
2958         struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
2959         struct madera *madera = priv->madera;
2960         unsigned int base_rate;
2961
2962         if (!substream->runtime)
2963                 return 0;
2964
2965         switch (dai_priv->clk) {
2966         case MADERA_CLK_SYSCLK_1:
2967         case MADERA_CLK_SYSCLK_2:
2968         case MADERA_CLK_SYSCLK_3:
2969                 base_rate = priv->sysclk;
2970                 break;
2971         case MADERA_CLK_ASYNCCLK_1:
2972         case MADERA_CLK_ASYNCCLK_2:
2973                 base_rate = priv->asyncclk;
2974                 break;
2975         default:
2976                 return 0;
2977         }
2978
2979         switch (madera->type) {
2980         case CS42L92:
2981         case CS47L92:
2982         case CS47L93:
2983                 if (base_rate == 0)
2984                         dai_priv->constraint.mask = MADERA_384K_RATE_MASK;
2985                 else if (base_rate % 4000)
2986                         dai_priv->constraint.mask = MADERA_384K_44K1_RATE_MASK;
2987                 else
2988                         dai_priv->constraint.mask = MADERA_384K_48K_RATE_MASK;
2989                 break;
2990         default:
2991                 if (base_rate == 0)
2992                         dai_priv->constraint.mask = MADERA_192K_RATE_MASK;
2993                 else if (base_rate % 4000)
2994                         dai_priv->constraint.mask = MADERA_192K_44K1_RATE_MASK;
2995                 else
2996                         dai_priv->constraint.mask = MADERA_192K_48K_RATE_MASK;
2997                 break;
2998         }
2999
3000         return snd_pcm_hw_constraint_list(substream->runtime, 0,
3001                                           SNDRV_PCM_HW_PARAM_RATE,
3002                                           &dai_priv->constraint);
3003 }
3004
3005 static int madera_hw_params_rate(struct snd_pcm_substream *substream,
3006                                  struct snd_pcm_hw_params *params,
3007                                  struct snd_soc_dai *dai)
3008 {
3009         struct snd_soc_component *component = dai->component;
3010         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
3011         struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
3012         int base = dai->driver->base;
3013         int i, sr_val;
3014         unsigned int reg, cur, tar;
3015         int ret;
3016
3017         for (i = 0; i < ARRAY_SIZE(madera_sr_vals); i++)
3018                 if (madera_sr_vals[i] == params_rate(params))
3019                         break;
3020
3021         if (i == ARRAY_SIZE(madera_sr_vals)) {
3022                 madera_aif_err(dai, "Unsupported sample rate %dHz\n",
3023                                params_rate(params));
3024                 return -EINVAL;
3025         }
3026         sr_val = i;
3027
3028         switch (dai_priv->clk) {
3029         case MADERA_CLK_SYSCLK_1:
3030                 reg = MADERA_SAMPLE_RATE_1;
3031                 tar = 0 << MADERA_AIF1_RATE_SHIFT;
3032                 break;
3033         case MADERA_CLK_SYSCLK_2:
3034                 reg = MADERA_SAMPLE_RATE_2;
3035                 tar = 1 << MADERA_AIF1_RATE_SHIFT;
3036                 break;
3037         case MADERA_CLK_SYSCLK_3:
3038                 reg = MADERA_SAMPLE_RATE_3;
3039                 tar = 2 << MADERA_AIF1_RATE_SHIFT;
3040                 break;
3041         case MADERA_CLK_ASYNCCLK_1:
3042                 reg = MADERA_ASYNC_SAMPLE_RATE_1,
3043                 tar = 8 << MADERA_AIF1_RATE_SHIFT;
3044                 break;
3045         case MADERA_CLK_ASYNCCLK_2:
3046                 reg = MADERA_ASYNC_SAMPLE_RATE_2,
3047                 tar = 9 << MADERA_AIF1_RATE_SHIFT;
3048                 break;
3049         default:
3050                 madera_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
3051                 return -EINVAL;
3052         }
3053
3054         snd_soc_component_update_bits(component, reg, MADERA_SAMPLE_RATE_1_MASK,
3055                                       sr_val);
3056
3057         if (!base)
3058                 return 0;
3059
3060         ret = regmap_read(priv->madera->regmap,
3061                           base + MADERA_AIF_RATE_CTRL, &cur);
3062         if (ret != 0) {
3063                 madera_aif_err(dai, "Failed to check rate: %d\n", ret);
3064                 return ret;
3065         }
3066
3067         if ((cur & MADERA_AIF1_RATE_MASK) == (tar & MADERA_AIF1_RATE_MASK))
3068                 return 0;
3069
3070         mutex_lock(&priv->rate_lock);
3071
3072         if (!madera_can_change_grp_rate(priv, base + MADERA_AIF_RATE_CTRL)) {
3073                 madera_aif_warn(dai, "Cannot change rate while active\n");
3074                 ret = -EBUSY;
3075                 goto out;
3076         }
3077
3078         /* Guard the rate change with SYSCLK cycles */
3079         madera_spin_sysclk(priv);
3080         snd_soc_component_update_bits(component, base + MADERA_AIF_RATE_CTRL,
3081                                       MADERA_AIF1_RATE_MASK, tar);
3082         madera_spin_sysclk(priv);
3083
3084 out:
3085         mutex_unlock(&priv->rate_lock);
3086
3087         return ret;
3088 }
3089
3090 static int madera_aif_cfg_changed(struct snd_soc_component *component,
3091                                   int base, int bclk, int lrclk, int frame)
3092 {
3093         unsigned int val;
3094         int ret;
3095
3096         ret = snd_soc_component_read(component, base + MADERA_AIF_BCLK_CTRL,
3097                                      &val);
3098         if (ret)
3099                 return ret;
3100         if (bclk != (val & MADERA_AIF1_BCLK_FREQ_MASK))
3101                 return 1;
3102
3103         ret = snd_soc_component_read(component, base + MADERA_AIF_RX_BCLK_RATE,
3104                                      &val);
3105         if (ret)
3106                 return ret;
3107         if (lrclk != (val & MADERA_AIF1RX_BCPF_MASK))
3108                 return 1;
3109
3110         ret = snd_soc_component_read(component, base + MADERA_AIF_FRAME_CTRL_1,
3111                                      &val);
3112         if (ret)
3113                 return ret;
3114         if (frame != (val & (MADERA_AIF1TX_WL_MASK |
3115                              MADERA_AIF1TX_SLOT_LEN_MASK)))
3116                 return 1;
3117
3118         return 0;
3119 }
3120
3121 static int madera_hw_params(struct snd_pcm_substream *substream,
3122                             struct snd_pcm_hw_params *params,
3123                             struct snd_soc_dai *dai)
3124 {
3125         struct snd_soc_component *component = dai->component;
3126         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
3127         struct madera *madera = priv->madera;
3128         int base = dai->driver->base;
3129         const int *rates;
3130         int i, ret;
3131         unsigned int val;
3132         unsigned int channels = params_channels(params);
3133         unsigned int rate = params_rate(params);
3134         unsigned int chan_limit =
3135                         madera->pdata.codec.max_channels_clocked[dai->id - 1];
3136         int tdm_width = priv->tdm_width[dai->id - 1];
3137         int tdm_slots = priv->tdm_slots[dai->id - 1];
3138         int bclk, lrclk, wl, frame, bclk_target, num_rates;
3139         int reconfig;
3140         unsigned int aif_tx_state = 0, aif_rx_state = 0;
3141
3142         if (rate % 4000) {
3143                 rates = &madera_44k1_bclk_rates[0];
3144                 num_rates = ARRAY_SIZE(madera_44k1_bclk_rates);
3145         } else {
3146                 rates = &madera_48k_bclk_rates[0];
3147                 num_rates = ARRAY_SIZE(madera_48k_bclk_rates);
3148         }
3149
3150         wl = snd_pcm_format_width(params_format(params));
3151
3152         if (tdm_slots) {
3153                 madera_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
3154                                tdm_slots, tdm_width);
3155                 bclk_target = tdm_slots * tdm_width * rate;
3156                 channels = tdm_slots;
3157         } else {
3158                 bclk_target = snd_soc_params_to_bclk(params);
3159                 tdm_width = wl;
3160         }
3161
3162         if (chan_limit && chan_limit < channels) {
3163                 madera_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
3164                 bclk_target /= channels;
3165                 bclk_target *= chan_limit;
3166         }
3167
3168         /* Force multiple of 2 channels for I2S mode */
3169         ret = snd_soc_component_read(component, base + MADERA_AIF_FORMAT, &val);
3170         if (ret)
3171                 return ret;
3172
3173         val &= MADERA_AIF1_FMT_MASK;
3174         if ((channels & 1) && val == MADERA_FMT_I2S_MODE) {
3175                 madera_aif_dbg(dai, "Forcing stereo mode\n");
3176                 bclk_target /= channels;
3177                 bclk_target *= channels + 1;
3178         }
3179
3180         for (i = 0; i < num_rates; i++) {
3181                 if (rates[i] >= bclk_target && rates[i] % rate == 0) {
3182                         bclk = i;
3183                         break;
3184                 }
3185         }
3186
3187         if (i == num_rates) {
3188                 madera_aif_err(dai, "Unsupported sample rate %dHz\n", rate);
3189                 return -EINVAL;
3190         }
3191
3192         lrclk = rates[bclk] / rate;
3193
3194         madera_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
3195                        rates[bclk], rates[bclk] / lrclk);
3196
3197         frame = wl << MADERA_AIF1TX_WL_SHIFT | tdm_width;
3198
3199         reconfig = madera_aif_cfg_changed(component, base, bclk, lrclk, frame);
3200         if (reconfig < 0)
3201                 return reconfig;
3202
3203         if (reconfig) {
3204                 /* Save AIF TX/RX state */
3205                 regmap_read(madera->regmap, base + MADERA_AIF_TX_ENABLES,
3206                             &aif_tx_state);
3207                 regmap_read(madera->regmap, base + MADERA_AIF_RX_ENABLES,
3208                             &aif_rx_state);
3209                 /* Disable AIF TX/RX before reconfiguring it */
3210                 regmap_update_bits(madera->regmap,
3211                                    base + MADERA_AIF_TX_ENABLES, 0xff, 0x0);
3212                 regmap_update_bits(madera->regmap,
3213                                    base + MADERA_AIF_RX_ENABLES, 0xff, 0x0);
3214         }
3215
3216         ret = madera_hw_params_rate(substream, params, dai);
3217         if (ret != 0)
3218                 goto restore_aif;
3219
3220         if (reconfig) {
3221                 regmap_update_bits(madera->regmap,
3222                                    base + MADERA_AIF_BCLK_CTRL,
3223                                    MADERA_AIF1_BCLK_FREQ_MASK, bclk);
3224                 regmap_update_bits(madera->regmap,
3225                                    base + MADERA_AIF_RX_BCLK_RATE,
3226                                    MADERA_AIF1RX_BCPF_MASK, lrclk);
3227                 regmap_update_bits(madera->regmap,
3228                                    base + MADERA_AIF_FRAME_CTRL_1,
3229                                    MADERA_AIF1TX_WL_MASK |
3230                                    MADERA_AIF1TX_SLOT_LEN_MASK, frame);
3231                 regmap_update_bits(madera->regmap,
3232                                    base + MADERA_AIF_FRAME_CTRL_2,
3233                                    MADERA_AIF1RX_WL_MASK |
3234                                    MADERA_AIF1RX_SLOT_LEN_MASK, frame);
3235         }
3236
3237 restore_aif:
3238         if (reconfig) {
3239                 /* Restore AIF TX/RX state */
3240                 regmap_update_bits(madera->regmap,
3241                                    base + MADERA_AIF_TX_ENABLES,
3242                                    0xff, aif_tx_state);
3243                 regmap_update_bits(madera->regmap,
3244                                    base + MADERA_AIF_RX_ENABLES,
3245                                    0xff, aif_rx_state);
3246         }
3247
3248         return ret;
3249 }
3250
3251 static int madera_is_syncclk(int clk_id)
3252 {
3253         switch (clk_id) {
3254         case MADERA_CLK_SYSCLK_1:
3255         case MADERA_CLK_SYSCLK_2:
3256         case MADERA_CLK_SYSCLK_3:
3257                 return 1;
3258         case MADERA_CLK_ASYNCCLK_1:
3259         case MADERA_CLK_ASYNCCLK_2:
3260                 return 0;
3261         default:
3262                 return -EINVAL;
3263         }
3264 }
3265
3266 static int madera_dai_set_sysclk(struct snd_soc_dai *dai,
3267                                  int clk_id, unsigned int freq, int dir)
3268 {
3269         struct snd_soc_component *component = dai->component;
3270         struct snd_soc_dapm_context *dapm =
3271                 snd_soc_component_get_dapm(component);
3272         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
3273         struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
3274         struct snd_soc_dapm_route routes[2];
3275         int is_sync;
3276
3277         is_sync = madera_is_syncclk(clk_id);
3278         if (is_sync < 0) {
3279                 dev_err(component->dev, "Illegal DAI clock id %d\n", clk_id);
3280                 return is_sync;
3281         }
3282
3283         if (is_sync == madera_is_syncclk(dai_priv->clk))
3284                 return 0;
3285
3286         if (dai->active) {
3287                 dev_err(component->dev, "Can't change clock on active DAI %d\n",
3288                         dai->id);
3289                 return -EBUSY;
3290         }
3291
3292         dev_dbg(component->dev, "Setting AIF%d to %s\n", dai->id,
3293                 is_sync ? "SYSCLK" : "ASYNCCLK");
3294
3295         /*
3296          * A connection to SYSCLK is always required, we only add and remove
3297          * a connection to ASYNCCLK
3298          */
3299         memset(&routes, 0, sizeof(routes));
3300         routes[0].sink = dai->driver->capture.stream_name;
3301         routes[1].sink = dai->driver->playback.stream_name;
3302         routes[0].source = "ASYNCCLK";
3303         routes[1].source = "ASYNCCLK";
3304
3305         if (is_sync)
3306                 snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
3307         else
3308                 snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
3309
3310         dai_priv->clk = clk_id;
3311
3312         return snd_soc_dapm_sync(dapm);
3313 }
3314
3315 static int madera_set_tristate(struct snd_soc_dai *dai, int tristate)
3316 {
3317         struct snd_soc_component *component = dai->component;
3318         int base = dai->driver->base;
3319         unsigned int reg;
3320         int ret;
3321
3322         if (tristate)
3323                 reg = MADERA_AIF1_TRI;
3324         else
3325                 reg = 0;
3326
3327         ret = snd_soc_component_update_bits(component,
3328                                             base + MADERA_AIF_RATE_CTRL,
3329                                             MADERA_AIF1_TRI, reg);
3330         if (ret < 0)
3331                 return ret;
3332         else
3333                 return 0;
3334 }
3335
3336 static void madera_set_channels_to_mask(struct snd_soc_dai *dai,
3337                                         unsigned int base,
3338                                         int channels, unsigned int mask)
3339 {
3340         struct snd_soc_component *component = dai->component;
3341         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
3342         struct madera *madera = priv->madera;
3343         int slot, i;
3344
3345         for (i = 0; i < channels; ++i) {
3346                 slot = ffs(mask) - 1;
3347                 if (slot < 0)
3348                         return;
3349
3350                 regmap_write(madera->regmap, base + i, slot);
3351
3352                 mask &= ~(1 << slot);
3353         }
3354
3355         if (mask)
3356                 madera_aif_warn(dai, "Too many channels in TDM mask\n");
3357 }
3358
3359 static int madera_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
3360                                unsigned int rx_mask, int slots, int slot_width)
3361 {
3362         struct snd_soc_component *component = dai->component;
3363         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
3364         int base = dai->driver->base;
3365         int rx_max_chan = dai->driver->playback.channels_max;
3366         int tx_max_chan = dai->driver->capture.channels_max;
3367
3368         /* Only support TDM for the physical AIFs */
3369         if (dai->id > MADERA_MAX_AIF)
3370                 return -ENOTSUPP;
3371
3372         if (slots == 0) {
3373                 tx_mask = (1 << tx_max_chan) - 1;
3374                 rx_mask = (1 << rx_max_chan) - 1;
3375         }
3376
3377         madera_set_channels_to_mask(dai, base + MADERA_AIF_FRAME_CTRL_3,
3378                                     tx_max_chan, tx_mask);
3379         madera_set_channels_to_mask(dai, base + MADERA_AIF_FRAME_CTRL_11,
3380                                     rx_max_chan, rx_mask);
3381
3382         priv->tdm_width[dai->id - 1] = slot_width;
3383         priv->tdm_slots[dai->id - 1] = slots;
3384
3385         return 0;
3386 }
3387
3388 const struct snd_soc_dai_ops madera_dai_ops = {
3389         .startup = &madera_startup,
3390         .set_fmt = &madera_set_fmt,
3391         .set_tdm_slot = &madera_set_tdm_slot,
3392         .hw_params = &madera_hw_params,
3393         .set_sysclk = &madera_dai_set_sysclk,
3394         .set_tristate = &madera_set_tristate,
3395 };
3396 EXPORT_SYMBOL_GPL(madera_dai_ops);
3397
3398 const struct snd_soc_dai_ops madera_simple_dai_ops = {
3399         .startup = &madera_startup,
3400         .hw_params = &madera_hw_params_rate,
3401         .set_sysclk = &madera_dai_set_sysclk,
3402 };
3403 EXPORT_SYMBOL_GPL(madera_simple_dai_ops);
3404
3405 int madera_init_dai(struct madera_priv *priv, int id)
3406 {
3407         struct madera_dai_priv *dai_priv = &priv->dai[id];
3408
3409         dai_priv->clk = MADERA_CLK_SYSCLK_1;
3410         dai_priv->constraint = madera_constraint;
3411
3412         return 0;
3413 }
3414 EXPORT_SYMBOL_GPL(madera_init_dai);
3415
3416 static const struct {
3417         unsigned int min;
3418         unsigned int max;
3419         u16 fratio;
3420         int ratio;
3421 } fll_sync_fratios[] = {
3422         {       0,    64000, 4, 16 },
3423         {   64000,   128000, 3,  8 },
3424         {  128000,   256000, 2,  4 },
3425         {  256000,  1000000, 1,  2 },
3426         { 1000000, 13500000, 0,  1 },
3427 };
3428
3429 static const unsigned int pseudo_fref_max[MADERA_FLL_MAX_FRATIO] = {
3430         13500000,
3431          6144000,
3432          6144000,
3433          3072000,
3434          3072000,
3435          2822400,
3436          2822400,
3437          1536000,
3438          1536000,
3439          1536000,
3440          1536000,
3441          1536000,
3442          1536000,
3443          1536000,
3444          1536000,
3445           768000,
3446 };
3447
3448 struct madera_fll_gains {
3449         unsigned int min;
3450         unsigned int max;
3451         int gain;               /* main gain */
3452         int alt_gain;           /* alternate integer gain */
3453 };
3454
3455 static const struct madera_fll_gains madera_fll_sync_gains[] = {
3456         {       0,   256000, 0, -1 },
3457         {  256000,  1000000, 2, -1 },
3458         { 1000000, 13500000, 4, -1 },
3459 };
3460
3461 static const struct madera_fll_gains madera_fll_main_gains[] = {
3462         {       0,   100000, 0, 2 },
3463         {  100000,   375000, 2, 2 },
3464         {  375000,   768000, 3, 2 },
3465         {  768001,  1500000, 3, 3 },
3466         { 1500000,  6000000, 4, 3 },
3467         { 6000000, 13500000, 5, 3 },
3468 };
3469
3470 static int madera_find_sync_fratio(unsigned int fref, int *fratio)
3471 {
3472         int i;
3473
3474         for (i = 0; i < ARRAY_SIZE(fll_sync_fratios); i++) {
3475                 if (fll_sync_fratios[i].min <= fref &&
3476                     fref <= fll_sync_fratios[i].max) {
3477                         if (fratio)
3478                                 *fratio = fll_sync_fratios[i].fratio;
3479
3480                         return fll_sync_fratios[i].ratio;
3481                 }
3482         }
3483
3484         return -EINVAL;
3485 }
3486
3487 static int madera_find_main_fratio(unsigned int fref, unsigned int fout,
3488                                    int *fratio)
3489 {
3490         int ratio = 1;
3491
3492         while ((fout / (ratio * fref)) > MADERA_FLL_MAX_N)
3493                 ratio++;
3494
3495         if (fratio)
3496                 *fratio = ratio - 1;
3497
3498         return ratio;
3499 }
3500
3501 static int madera_find_fratio(struct madera_fll *fll, unsigned int fref,
3502                               bool sync, int *fratio)
3503 {
3504         switch (fll->madera->type) {
3505         case CS47L35:
3506                 switch (fll->madera->rev) {
3507                 case 0:
3508                         /* rev A0 uses sync calculation for both loops */
3509                         return madera_find_sync_fratio(fref, fratio);
3510                 default:
3511                         if (sync)
3512                                 return madera_find_sync_fratio(fref, fratio);
3513                         else
3514                                 return madera_find_main_fratio(fref,
3515                                                                fll->fout,
3516                                                                fratio);
3517                 }
3518                 break;
3519         case CS47L85:
3520         case WM1840:
3521                 /* these use the same calculation for main and sync loops */
3522                 return madera_find_sync_fratio(fref, fratio);
3523         default:
3524                 if (sync)
3525                         return madera_find_sync_fratio(fref, fratio);
3526                 else
3527                         return madera_find_main_fratio(fref, fll->fout, fratio);
3528         }
3529 }
3530
3531 static int madera_calc_fratio(struct madera_fll *fll,
3532                               struct madera_fll_cfg *cfg,
3533                               unsigned int fref, bool sync)
3534 {
3535         int init_ratio, ratio;
3536         int refdiv, div;
3537
3538         /* fref must be <=13.5MHz, find initial refdiv */
3539         div = 1;
3540         cfg->refdiv = 0;
3541         while (fref > MADERA_FLL_MAX_FREF) {
3542                 div *= 2;
3543                 fref /= 2;
3544                 cfg->refdiv++;
3545
3546                 if (div > MADERA_FLL_MAX_REFDIV)
3547                         return -EINVAL;
3548         }
3549
3550         /* Find an appropriate FLL_FRATIO */
3551         init_ratio = madera_find_fratio(fll, fref, sync, &cfg->fratio);
3552         if (init_ratio < 0) {
3553                 madera_fll_err(fll, "Unable to find FRATIO for fref=%uHz\n",
3554                                fref);
3555                 return init_ratio;
3556         }
3557
3558         if (!sync)
3559                 cfg->fratio = init_ratio - 1;
3560
3561         switch (fll->madera->type) {
3562         case CS47L35:
3563                 switch (fll->madera->rev) {
3564                 case 0:
3565                         if (sync)
3566                                 return init_ratio;
3567                         break;
3568                 default:
3569                         return init_ratio;
3570                 }
3571                 break;
3572         case CS47L85:
3573         case WM1840:
3574                 if (sync)
3575                         return init_ratio;
3576                 break;
3577         default:
3578                 return init_ratio;
3579         }
3580
3581         /*
3582          * For CS47L35 rev A0, CS47L85 and WM1840 adjust FRATIO/refdiv to avoid
3583          * integer mode if possible
3584          */
3585         refdiv = cfg->refdiv;
3586
3587         while (div <= MADERA_FLL_MAX_REFDIV) {
3588                 /*
3589                  * start from init_ratio because this may already give a
3590                  * fractional N.K
3591                  */
3592                 for (ratio = init_ratio; ratio > 0; ratio--) {
3593                         if (fll->fout % (ratio * fref)) {
3594                                 cfg->refdiv = refdiv;
3595                                 cfg->fratio = ratio - 1;
3596                                 return ratio;
3597                         }
3598                 }
3599
3600                 for (ratio = init_ratio + 1; ratio <= MADERA_FLL_MAX_FRATIO;
3601                      ratio++) {
3602                         if ((MADERA_FLL_VCO_CORNER / 2) /
3603                             (MADERA_FLL_VCO_MULT * ratio) < fref)
3604                                 break;
3605
3606                         if (fref > pseudo_fref_max[ratio - 1])
3607                                 break;
3608
3609                         if (fll->fout % (ratio * fref)) {
3610                                 cfg->refdiv = refdiv;
3611                                 cfg->fratio = ratio - 1;
3612                                 return ratio;
3613                         }
3614                 }
3615
3616                 div *= 2;
3617                 fref /= 2;
3618                 refdiv++;
3619                 init_ratio = madera_find_fratio(fll, fref, sync, NULL);
3620         }
3621
3622         madera_fll_warn(fll, "Falling back to integer mode operation\n");
3623
3624         return cfg->fratio + 1;
3625 }
3626
3627 static int madera_find_fll_gain(struct madera_fll *fll,
3628                                 struct madera_fll_cfg *cfg,
3629                                 unsigned int fref,
3630                                 const struct madera_fll_gains *gains,
3631                                 int n_gains)
3632 {
3633         int i;
3634
3635         for (i = 0; i < n_gains; i++) {
3636                 if (gains[i].min <= fref && fref <= gains[i].max) {
3637                         cfg->gain = gains[i].gain;
3638                         cfg->alt_gain = gains[i].alt_gain;
3639                         return 0;
3640                 }
3641         }
3642
3643         madera_fll_err(fll, "Unable to find gain for fref=%uHz\n", fref);
3644
3645         return -EINVAL;
3646 }
3647
3648 static int madera_calc_fll(struct madera_fll *fll,
3649                            struct madera_fll_cfg *cfg,
3650                            unsigned int fref, bool sync)
3651 {
3652         unsigned int gcd_fll;
3653         const struct madera_fll_gains *gains;
3654         int n_gains;
3655         int ratio, ret;
3656
3657         madera_fll_dbg(fll, "fref=%u Fout=%u fvco=%u\n",
3658                        fref, fll->fout, fll->fout * MADERA_FLL_VCO_MULT);
3659
3660         /* Find an appropriate FLL_FRATIO and refdiv */
3661         ratio = madera_calc_fratio(fll, cfg, fref, sync);
3662         if (ratio < 0)
3663                 return ratio;
3664
3665         /* Apply the division for our remaining calculations */
3666         fref = fref / (1 << cfg->refdiv);
3667
3668         cfg->n = fll->fout / (ratio * fref);
3669
3670         if (fll->fout % (ratio * fref)) {
3671                 gcd_fll = gcd(fll->fout, ratio * fref);
3672                 madera_fll_dbg(fll, "GCD=%u\n", gcd_fll);
3673
3674                 cfg->theta = (fll->fout - (cfg->n * ratio * fref))
3675                         / gcd_fll;
3676                 cfg->lambda = (ratio * fref) / gcd_fll;
3677         } else {
3678                 cfg->theta = 0;
3679                 cfg->lambda = 0;
3680         }
3681
3682         /*
3683          * Round down to 16bit range with cost of accuracy lost.
3684          * Denominator must be bigger than numerator so we only
3685          * take care of it.
3686          */
3687         while (cfg->lambda >= (1 << 16)) {
3688                 cfg->theta >>= 1;
3689                 cfg->lambda >>= 1;
3690         }
3691
3692         switch (fll->madera->type) {
3693         case CS47L35:
3694                 switch (fll->madera->rev) {
3695                 case 0:
3696                         /* Rev A0 uses the sync gains for both loops */
3697                         gains = madera_fll_sync_gains;
3698                         n_gains = ARRAY_SIZE(madera_fll_sync_gains);
3699                         break;
3700                 default:
3701                         if (sync) {
3702                                 gains = madera_fll_sync_gains;
3703                                 n_gains = ARRAY_SIZE(madera_fll_sync_gains);
3704                         } else {
3705                                 gains = madera_fll_main_gains;
3706                                 n_gains = ARRAY_SIZE(madera_fll_main_gains);
3707                         }
3708                         break;
3709                 }
3710                 break;
3711         case CS47L85:
3712         case WM1840:
3713                 /* These use the sync gains for both loops */
3714                 gains = madera_fll_sync_gains;
3715                 n_gains = ARRAY_SIZE(madera_fll_sync_gains);
3716                 break;
3717         default:
3718                 if (sync) {
3719                         gains = madera_fll_sync_gains;
3720                         n_gains = ARRAY_SIZE(madera_fll_sync_gains);
3721                 } else {
3722                         gains = madera_fll_main_gains;
3723                         n_gains = ARRAY_SIZE(madera_fll_main_gains);
3724                 }
3725                 break;
3726         }
3727
3728         ret = madera_find_fll_gain(fll, cfg, fref, gains, n_gains);
3729         if (ret)
3730                 return ret;
3731
3732         madera_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
3733                        cfg->n, cfg->theta, cfg->lambda);
3734         madera_fll_dbg(fll, "FRATIO=0x%x(%d) REFCLK_DIV=0x%x(%d)\n",
3735                        cfg->fratio, ratio, cfg->refdiv, 1 << cfg->refdiv);
3736         madera_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
3737
3738         return 0;
3739 }
3740
3741 static bool madera_write_fll(struct madera *madera, unsigned int base,
3742                              struct madera_fll_cfg *cfg, int source,
3743                              bool sync, int gain)
3744 {
3745         bool change, fll_change;
3746
3747         fll_change = false;
3748         regmap_update_bits_check(madera->regmap,
3749                                  base + MADERA_FLL_CONTROL_3_OFFS,
3750                                  MADERA_FLL1_THETA_MASK,
3751                                  cfg->theta, &change);
3752         fll_change |= change;
3753         regmap_update_bits_check(madera->regmap,
3754                                  base + MADERA_FLL_CONTROL_4_OFFS,
3755                                  MADERA_FLL1_LAMBDA_MASK,
3756                                  cfg->lambda, &change);
3757         fll_change |= change;
3758         regmap_update_bits_check(madera->regmap,
3759                                  base + MADERA_FLL_CONTROL_5_OFFS,
3760                                  MADERA_FLL1_FRATIO_MASK,
3761                                  cfg->fratio << MADERA_FLL1_FRATIO_SHIFT,
3762                                  &change);
3763         fll_change |= change;
3764         regmap_update_bits_check(madera->regmap,
3765                                  base + MADERA_FLL_CONTROL_6_OFFS,
3766                                  MADERA_FLL1_REFCLK_DIV_MASK |
3767                                  MADERA_FLL1_REFCLK_SRC_MASK,
3768                                  cfg->refdiv << MADERA_FLL1_REFCLK_DIV_SHIFT |
3769                                  source << MADERA_FLL1_REFCLK_SRC_SHIFT,
3770                                  &change);
3771         fll_change |= change;
3772
3773         if (sync) {
3774                 regmap_update_bits_check(madera->regmap,
3775                                          base + MADERA_FLL_SYNCHRONISER_7_OFFS,
3776                                          MADERA_FLL1_GAIN_MASK,
3777                                          gain << MADERA_FLL1_GAIN_SHIFT,
3778                                          &change);
3779                 fll_change |= change;
3780         } else {
3781                 regmap_update_bits_check(madera->regmap,
3782                                          base + MADERA_FLL_CONTROL_7_OFFS,
3783                                          MADERA_FLL1_GAIN_MASK,
3784                                          gain << MADERA_FLL1_GAIN_SHIFT,
3785                                          &change);
3786                 fll_change |= change;
3787         }
3788
3789         regmap_update_bits_check(madera->regmap,
3790                                  base + MADERA_FLL_CONTROL_2_OFFS,
3791                                  MADERA_FLL1_CTRL_UPD | MADERA_FLL1_N_MASK,
3792                                  MADERA_FLL1_CTRL_UPD | cfg->n, &change);
3793         fll_change |= change;
3794
3795         return fll_change;
3796 }
3797
3798 static int madera_is_enabled_fll(struct madera_fll *fll, int base)
3799 {
3800         struct madera *madera = fll->madera;
3801         unsigned int reg;
3802         int ret;
3803
3804         ret = regmap_read(madera->regmap,
3805                           base + MADERA_FLL_CONTROL_1_OFFS, &reg);
3806         if (ret != 0) {
3807                 madera_fll_err(fll, "Failed to read current state: %d\n", ret);
3808                 return ret;
3809         }
3810
3811         return reg & MADERA_FLL1_ENA;
3812 }
3813
3814 static int madera_wait_for_fll(struct madera_fll *fll, bool requested)
3815 {
3816         struct madera *madera = fll->madera;
3817         unsigned int val = 0;
3818         bool status;
3819         int i;
3820
3821         madera_fll_dbg(fll, "Waiting for FLL...\n");
3822
3823         for (i = 0; i < 30; i++) {
3824                 regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_2, &val);
3825                 status = val & (MADERA_FLL1_LOCK_STS1 << (fll->id - 1));
3826                 if (status == requested)
3827                         return 0;
3828
3829                 switch (i) {
3830                 case 0 ... 5:
3831                         usleep_range(75, 125);
3832                         break;
3833                 case 11 ... 20:
3834                         usleep_range(750, 1250);
3835                         break;
3836                 default:
3837                         msleep(20);
3838                         break;
3839                 }
3840         }
3841
3842         madera_fll_warn(fll, "Timed out waiting for lock\n");
3843
3844         return -ETIMEDOUT;
3845 }
3846
3847 static bool madera_set_fll_phase_integrator(struct madera_fll *fll,
3848                                             struct madera_fll_cfg *ref_cfg,
3849                                             bool sync)
3850 {
3851         unsigned int val;
3852         bool reg_change;
3853
3854         if (!sync && ref_cfg->theta == 0)
3855                 val = (1 << MADERA_FLL1_PHASE_ENA_SHIFT) |
3856                       (2 << MADERA_FLL1_PHASE_GAIN_SHIFT);
3857         else
3858                 val = 2 << MADERA_FLL1_PHASE_GAIN_SHIFT;
3859
3860         regmap_update_bits_check(fll->madera->regmap,
3861                                  fll->base + MADERA_FLL_EFS_2_OFFS,
3862                                  MADERA_FLL1_PHASE_ENA_MASK |
3863                                  MADERA_FLL1_PHASE_GAIN_MASK,
3864                                  val, &reg_change);
3865
3866         return reg_change;
3867 }
3868
3869 static int madera_set_fll_clks_reg(struct madera_fll *fll, bool ena,
3870                                    unsigned int reg, unsigned int mask,
3871                                    unsigned int shift)
3872 {
3873         struct madera *madera = fll->madera;
3874         unsigned int src;
3875         struct clk *clk;
3876         int ret;
3877
3878         ret = regmap_read(madera->regmap, reg, &src);
3879         if (ret != 0) {
3880                 madera_fll_err(fll, "Failed to read current source: %d\n",
3881                                ret);
3882                 return ret;
3883         }
3884
3885         src = (src & mask) >> shift;
3886
3887         switch (src) {
3888         case MADERA_FLL_SRC_MCLK1:
3889                 clk = madera->mclk[MADERA_MCLK1].clk;
3890                 break;
3891         case MADERA_FLL_SRC_MCLK2:
3892                 clk = madera->mclk[MADERA_MCLK2].clk;
3893                 break;
3894         case MADERA_FLL_SRC_MCLK3:
3895                 clk = madera->mclk[MADERA_MCLK3].clk;
3896                 break;
3897         default:
3898                 return 0;
3899         }
3900
3901         if (ena) {
3902                 return clk_prepare_enable(clk);
3903         } else {
3904                 clk_disable_unprepare(clk);
3905                 return 0;
3906         }
3907 }
3908
3909 static inline int madera_set_fll_clks(struct madera_fll *fll, int base, bool ena)
3910 {
3911         return madera_set_fll_clks_reg(fll, ena,
3912                                        base + MADERA_FLL_CONTROL_6_OFFS,
3913                                        MADERA_FLL1_REFCLK_SRC_MASK,
3914                                        MADERA_FLL1_REFCLK_DIV_SHIFT);
3915 }
3916
3917 static inline int madera_set_fllao_clks(struct madera_fll *fll, int base, bool ena)
3918 {
3919         return madera_set_fll_clks_reg(fll, ena,
3920                                        base + MADERA_FLLAO_CONTROL_6_OFFS,
3921                                        MADERA_FLL_AO_REFCLK_SRC_MASK,
3922                                        MADERA_FLL_AO_REFCLK_SRC_SHIFT);
3923 }
3924
3925 static inline int madera_set_fllhj_clks(struct madera_fll *fll, int base, bool ena)
3926 {
3927         return madera_set_fll_clks_reg(fll, ena,
3928                                        base + MADERA_FLL_CONTROL_1_OFFS,
3929                                        CS47L92_FLL1_REFCLK_SRC_MASK,
3930                                        CS47L92_FLL1_REFCLK_SRC_SHIFT);
3931 }
3932
3933 static void madera_disable_fll(struct madera_fll *fll)
3934 {
3935         struct madera *madera = fll->madera;
3936         unsigned int sync_base;
3937         bool ref_change, sync_change;
3938
3939         switch (madera->type) {
3940         case CS47L35:
3941                 sync_base = fll->base + CS47L35_FLL_SYNCHRONISER_OFFS;
3942                 break;
3943         default:
3944                 sync_base = fll->base + MADERA_FLL_SYNCHRONISER_OFFS;
3945                 break;
3946         }
3947
3948         madera_fll_dbg(fll, "Disabling FLL\n");
3949
3950         regmap_update_bits(madera->regmap,
3951                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
3952                            MADERA_FLL1_FREERUN, MADERA_FLL1_FREERUN);
3953         regmap_update_bits_check(madera->regmap,
3954                                  fll->base + MADERA_FLL_CONTROL_1_OFFS,
3955                                  MADERA_FLL1_ENA, 0, &ref_change);
3956         regmap_update_bits_check(madera->regmap,
3957                                  sync_base + MADERA_FLL_SYNCHRONISER_1_OFFS,
3958                                  MADERA_FLL1_SYNC_ENA, 0, &sync_change);
3959         regmap_update_bits(madera->regmap,
3960                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
3961                            MADERA_FLL1_FREERUN, 0);
3962
3963         madera_wait_for_fll(fll, false);
3964
3965         if (sync_change)
3966                 madera_set_fll_clks(fll, sync_base, false);
3967
3968         if (ref_change) {
3969                 madera_set_fll_clks(fll, fll->base, false);
3970                 pm_runtime_put_autosuspend(madera->dev);
3971         }
3972 }
3973
3974 static int madera_enable_fll(struct madera_fll *fll)
3975 {
3976         struct madera *madera = fll->madera;
3977         bool have_sync = false;
3978         int already_enabled = madera_is_enabled_fll(fll, fll->base);
3979         int sync_enabled;
3980         struct madera_fll_cfg cfg;
3981         unsigned int sync_base;
3982         int gain, ret;
3983         bool fll_change = false;
3984
3985         if (already_enabled < 0)
3986                 return already_enabled; /* error getting current state */
3987
3988         if (fll->ref_src < 0 || fll->ref_freq == 0) {
3989                 madera_fll_err(fll, "No REFCLK\n");
3990                 ret = -EINVAL;
3991                 goto err;
3992         }
3993
3994         madera_fll_dbg(fll, "Enabling FLL, initially %s\n",
3995                        already_enabled ? "enabled" : "disabled");
3996
3997         if (fll->fout < MADERA_FLL_MIN_FOUT ||
3998             fll->fout > MADERA_FLL_MAX_FOUT) {
3999                 madera_fll_err(fll, "invalid fout %uHz\n", fll->fout);
4000                 ret = -EINVAL;
4001                 goto err;
4002         }
4003
4004         switch (madera->type) {
4005         case CS47L35:
4006                 sync_base = fll->base + CS47L35_FLL_SYNCHRONISER_OFFS;
4007                 break;
4008         default:
4009                 sync_base = fll->base + MADERA_FLL_SYNCHRONISER_OFFS;
4010                 break;
4011         }
4012
4013         sync_enabled = madera_is_enabled_fll(fll, sync_base);
4014         if (sync_enabled < 0)
4015                 return sync_enabled;
4016
4017         if (already_enabled) {
4018                 /* Facilitate smooth refclk across the transition */
4019                 regmap_update_bits(fll->madera->regmap,
4020                                    fll->base + MADERA_FLL_CONTROL_1_OFFS,
4021                                    MADERA_FLL1_FREERUN,
4022                                    MADERA_FLL1_FREERUN);
4023                 udelay(32);
4024                 regmap_update_bits(fll->madera->regmap,
4025                                    fll->base + MADERA_FLL_CONTROL_7_OFFS,
4026                                    MADERA_FLL1_GAIN_MASK, 0);
4027
4028                 if (sync_enabled > 0)
4029                         madera_set_fll_clks(fll, sync_base, false);
4030                 madera_set_fll_clks(fll, fll->base, false);
4031         }
4032
4033         /* Apply SYNCCLK setting */
4034         if (fll->sync_src >= 0) {
4035                 ret = madera_calc_fll(fll, &cfg, fll->sync_freq, true);
4036                 if (ret < 0)
4037                         goto err;
4038
4039                 fll_change |= madera_write_fll(madera, sync_base,
4040                                                &cfg, fll->sync_src,
4041                                                true, cfg.gain);
4042                 have_sync = true;
4043         }
4044
4045         if (already_enabled && !!sync_enabled != have_sync)
4046                 madera_fll_warn(fll, "Synchroniser changed on active FLL\n");
4047
4048         /* Apply REFCLK setting */
4049         ret = madera_calc_fll(fll, &cfg, fll->ref_freq, false);
4050         if (ret < 0)
4051                 goto err;
4052
4053         /* Ref path hardcodes lambda to 65536 when sync is on */
4054         if (have_sync && cfg.lambda)
4055                 cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
4056
4057         switch (fll->madera->type) {
4058         case CS47L35:
4059                 switch (fll->madera->rev) {
4060                 case 0:
4061                         gain = cfg.gain;
4062                         break;
4063                 default:
4064                         fll_change |=
4065                                 madera_set_fll_phase_integrator(fll, &cfg,
4066                                                                 have_sync);
4067                         if (!have_sync && cfg.theta == 0)
4068                                 gain = cfg.alt_gain;
4069                         else
4070                                 gain = cfg.gain;
4071                         break;
4072                 }
4073                 break;
4074         case CS47L85:
4075         case WM1840:
4076                 gain = cfg.gain;
4077                 break;
4078         default:
4079                 fll_change |= madera_set_fll_phase_integrator(fll, &cfg,
4080                                                               have_sync);
4081                 if (!have_sync && cfg.theta == 0)
4082                         gain = cfg.alt_gain;
4083                 else
4084                         gain = cfg.gain;
4085                 break;
4086         }
4087
4088         fll_change |= madera_write_fll(madera, fll->base,
4089                                        &cfg, fll->ref_src,
4090                                        false, gain);
4091
4092         /*
4093          * Increase the bandwidth if we're not using a low frequency
4094          * sync source.
4095          */
4096         if (have_sync && fll->sync_freq > 100000)
4097                 regmap_update_bits(madera->regmap,
4098                                    sync_base + MADERA_FLL_SYNCHRONISER_7_OFFS,
4099                                    MADERA_FLL1_SYNC_DFSAT_MASK, 0);
4100         else
4101                 regmap_update_bits(madera->regmap,
4102                                    sync_base + MADERA_FLL_SYNCHRONISER_7_OFFS,
4103                                    MADERA_FLL1_SYNC_DFSAT_MASK,
4104                                    MADERA_FLL1_SYNC_DFSAT);
4105
4106         if (!already_enabled)
4107                 pm_runtime_get_sync(madera->dev);
4108
4109         if (have_sync) {
4110                 madera_set_fll_clks(fll, sync_base, true);
4111                 regmap_update_bits(madera->regmap,
4112                                    sync_base + MADERA_FLL_SYNCHRONISER_1_OFFS,
4113                                    MADERA_FLL1_SYNC_ENA,
4114                                    MADERA_FLL1_SYNC_ENA);
4115         }
4116
4117         madera_set_fll_clks(fll, fll->base, true);
4118         regmap_update_bits(madera->regmap,
4119                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
4120                            MADERA_FLL1_ENA, MADERA_FLL1_ENA);
4121
4122         if (already_enabled)
4123                 regmap_update_bits(madera->regmap,
4124                                    fll->base + MADERA_FLL_CONTROL_1_OFFS,
4125                                    MADERA_FLL1_FREERUN, 0);
4126
4127         if (fll_change || !already_enabled)
4128                 madera_wait_for_fll(fll, true);
4129
4130         return 0;
4131
4132 err:
4133          /* In case of error don't leave the FLL running with an old config */
4134         madera_disable_fll(fll);
4135
4136         return ret;
4137 }
4138
4139 static int madera_apply_fll(struct madera_fll *fll)
4140 {
4141         if (fll->fout) {
4142                 return madera_enable_fll(fll);
4143         } else {
4144                 madera_disable_fll(fll);
4145                 return 0;
4146         }
4147 }
4148
4149 int madera_set_fll_syncclk(struct madera_fll *fll, int source,
4150                            unsigned int fref, unsigned int fout)
4151 {
4152         /*
4153          * fout is ignored, since the synchronizer is an optional extra
4154          * constraint on the Fout generated from REFCLK, so the Fout is
4155          * set when configuring REFCLK
4156          */
4157
4158         if (fll->sync_src == source && fll->sync_freq == fref)
4159                 return 0;
4160
4161         fll->sync_src = source;
4162         fll->sync_freq = fref;
4163
4164         return madera_apply_fll(fll);
4165 }
4166 EXPORT_SYMBOL_GPL(madera_set_fll_syncclk);
4167
4168 int madera_set_fll_refclk(struct madera_fll *fll, int source,
4169                           unsigned int fref, unsigned int fout)
4170 {
4171         int ret;
4172
4173         if (fll->ref_src == source &&
4174             fll->ref_freq == fref && fll->fout == fout)
4175                 return 0;
4176
4177         /*
4178          * Changes of fout on an enabled FLL aren't allowed except when
4179          * setting fout==0 to disable the FLL
4180          */
4181         if (fout && fout != fll->fout) {
4182                 ret = madera_is_enabled_fll(fll, fll->base);
4183                 if (ret < 0)
4184                         return ret;
4185
4186                 if (ret) {
4187                         madera_fll_err(fll, "Can't change Fout on active FLL\n");
4188                         return -EBUSY;
4189                 }
4190         }
4191
4192         fll->ref_src = source;
4193         fll->ref_freq = fref;
4194         fll->fout = fout;
4195
4196         return madera_apply_fll(fll);
4197 }
4198 EXPORT_SYMBOL_GPL(madera_set_fll_refclk);
4199
4200 int madera_init_fll(struct madera *madera, int id, int base,
4201                     struct madera_fll *fll)
4202 {
4203         fll->id = id;
4204         fll->base = base;
4205         fll->madera = madera;
4206         fll->ref_src = MADERA_FLL_SRC_NONE;
4207         fll->sync_src = MADERA_FLL_SRC_NONE;
4208
4209         regmap_update_bits(madera->regmap,
4210                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
4211                            MADERA_FLL1_FREERUN, 0);
4212
4213         return 0;
4214 }
4215 EXPORT_SYMBOL_GPL(madera_init_fll);
4216
4217 static const struct reg_sequence madera_fll_ao_32K_49M_patch[] = {
4218         { MADERA_FLLAO_CONTROL_2,  0x02EE },
4219         { MADERA_FLLAO_CONTROL_3,  0x0000 },
4220         { MADERA_FLLAO_CONTROL_4,  0x0001 },
4221         { MADERA_FLLAO_CONTROL_5,  0x0002 },
4222         { MADERA_FLLAO_CONTROL_6,  0x8001 },
4223         { MADERA_FLLAO_CONTROL_7,  0x0004 },
4224         { MADERA_FLLAO_CONTROL_8,  0x0077 },
4225         { MADERA_FLLAO_CONTROL_10, 0x06D8 },
4226         { MADERA_FLLAO_CONTROL_11, 0x0085 },
4227         { MADERA_FLLAO_CONTROL_2,  0x82EE },
4228 };
4229
4230 static const struct reg_sequence madera_fll_ao_32K_45M_patch[] = {
4231         { MADERA_FLLAO_CONTROL_2,  0x02B1 },
4232         { MADERA_FLLAO_CONTROL_3,  0x0001 },
4233         { MADERA_FLLAO_CONTROL_4,  0x0010 },
4234         { MADERA_FLLAO_CONTROL_5,  0x0002 },
4235         { MADERA_FLLAO_CONTROL_6,  0x8001 },
4236         { MADERA_FLLAO_CONTROL_7,  0x0004 },
4237         { MADERA_FLLAO_CONTROL_8,  0x0077 },
4238         { MADERA_FLLAO_CONTROL_10, 0x06D8 },
4239         { MADERA_FLLAO_CONTROL_11, 0x0005 },
4240         { MADERA_FLLAO_CONTROL_2,  0x82B1 },
4241 };
4242
4243 struct madera_fllao_patch {
4244         unsigned int fin;
4245         unsigned int fout;
4246         const struct reg_sequence *patch;
4247         unsigned int patch_size;
4248 };
4249
4250 static const struct madera_fllao_patch madera_fllao_settings[] = {
4251         {
4252                 .fin = 32768,
4253                 .fout = 49152000,
4254                 .patch = madera_fll_ao_32K_49M_patch,
4255                 .patch_size = ARRAY_SIZE(madera_fll_ao_32K_49M_patch),
4256
4257         },
4258         {
4259                 .fin = 32768,
4260                 .fout = 45158400,
4261                 .patch = madera_fll_ao_32K_45M_patch,
4262                 .patch_size = ARRAY_SIZE(madera_fll_ao_32K_45M_patch),
4263         },
4264 };
4265
4266 static int madera_enable_fll_ao(struct madera_fll *fll,
4267                                 const struct reg_sequence *patch,
4268                                 unsigned int patch_size)
4269 {
4270         struct madera *madera = fll->madera;
4271         int already_enabled = madera_is_enabled_fll(fll, fll->base);
4272         unsigned int val;
4273         int i;
4274
4275         if (already_enabled < 0)
4276                 return already_enabled;
4277
4278         if (!already_enabled)
4279                 pm_runtime_get_sync(madera->dev);
4280
4281         madera_fll_dbg(fll, "Enabling FLL_AO, initially %s\n",
4282                        already_enabled ? "enabled" : "disabled");
4283
4284         /* FLL_AO_HOLD must be set before configuring any registers */
4285         regmap_update_bits(fll->madera->regmap,
4286                            fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
4287                            MADERA_FLL_AO_HOLD, MADERA_FLL_AO_HOLD);
4288
4289         if (already_enabled)
4290                 madera_set_fllao_clks(fll, fll->base, false);
4291
4292         for (i = 0; i < patch_size; i++) {
4293                 val = patch[i].def;
4294
4295                 /* modify the patch to apply fll->ref_src as input clock */
4296                 if (patch[i].reg == MADERA_FLLAO_CONTROL_6) {
4297                         val &= ~MADERA_FLL_AO_REFCLK_SRC_MASK;
4298                         val |= (fll->ref_src << MADERA_FLL_AO_REFCLK_SRC_SHIFT)
4299                                 & MADERA_FLL_AO_REFCLK_SRC_MASK;
4300                 }
4301
4302                 regmap_write(madera->regmap, patch[i].reg, val);
4303         }
4304
4305         madera_set_fllao_clks(fll, fll->base, true);
4306
4307         regmap_update_bits(madera->regmap,
4308                            fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
4309                            MADERA_FLL_AO_ENA, MADERA_FLL_AO_ENA);
4310
4311         /* Release the hold so that fll_ao locks to external frequency */
4312         regmap_update_bits(madera->regmap,
4313                            fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
4314                            MADERA_FLL_AO_HOLD, 0);
4315
4316         if (!already_enabled)
4317                 madera_wait_for_fll(fll, true);
4318
4319         return 0;
4320 }
4321
4322 static int madera_disable_fll_ao(struct madera_fll *fll)
4323 {
4324         struct madera *madera = fll->madera;
4325         bool change;
4326
4327         madera_fll_dbg(fll, "Disabling FLL_AO\n");
4328
4329         regmap_update_bits(madera->regmap,
4330                            fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
4331                            MADERA_FLL_AO_HOLD, MADERA_FLL_AO_HOLD);
4332         regmap_update_bits_check(madera->regmap,
4333                                  fll->base + MADERA_FLLAO_CONTROL_1_OFFS,
4334                                  MADERA_FLL_AO_ENA, 0, &change);
4335
4336         madera_wait_for_fll(fll, false);
4337
4338         /*
4339          * ctrl_up gates the writes to all fll_ao register, setting it to 0
4340          * here ensures that after a runtime suspend/resume cycle when one
4341          * enables the fllao then ctrl_up is the last bit that is configured
4342          * by the fllao enable code rather than the cache sync operation which
4343          * would have updated it much earlier before writing out all fllao
4344          * registers
4345          */
4346         regmap_update_bits(madera->regmap,
4347                            fll->base + MADERA_FLLAO_CONTROL_2_OFFS,
4348                            MADERA_FLL_AO_CTRL_UPD_MASK, 0);
4349
4350         if (change) {
4351                 madera_set_fllao_clks(fll, fll->base, false);
4352                 pm_runtime_put_autosuspend(madera->dev);
4353         }
4354
4355         return 0;
4356 }
4357
4358 int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
4359                              unsigned int fin, unsigned int fout)
4360 {
4361         int ret = 0;
4362         const struct reg_sequence *patch = NULL;
4363         int patch_size = 0;
4364         unsigned int i;
4365
4366         if (fll->ref_src == source &&
4367             fll->ref_freq == fin && fll->fout == fout)
4368                 return 0;
4369
4370         madera_fll_dbg(fll, "Change FLL_AO refclk to fin=%u fout=%u source=%d\n",
4371                        fin, fout, source);
4372
4373         if (fout && (fll->ref_freq != fin || fll->fout != fout)) {
4374                 for (i = 0; i < ARRAY_SIZE(madera_fllao_settings); i++) {
4375                         if (madera_fllao_settings[i].fin == fin &&
4376                             madera_fllao_settings[i].fout == fout)
4377                                 break;
4378                 }
4379
4380                 if (i == ARRAY_SIZE(madera_fllao_settings)) {
4381                         madera_fll_err(fll,
4382                                        "No matching configuration for FLL_AO\n");
4383                         return -EINVAL;
4384                 }
4385
4386                 patch = madera_fllao_settings[i].patch;
4387                 patch_size = madera_fllao_settings[i].patch_size;
4388         }
4389
4390         fll->ref_src = source;
4391         fll->ref_freq = fin;
4392         fll->fout = fout;
4393
4394         if (fout)
4395                 ret = madera_enable_fll_ao(fll, patch, patch_size);
4396         else
4397                 madera_disable_fll_ao(fll);
4398
4399         return ret;
4400 }
4401 EXPORT_SYMBOL_GPL(madera_set_fll_ao_refclk);
4402
4403 static int madera_fllhj_disable(struct madera_fll *fll)
4404 {
4405         struct madera *madera = fll->madera;
4406         bool change;
4407
4408         madera_fll_dbg(fll, "Disabling FLL\n");
4409
4410         /* Disable lockdet, but don't set ctrl_upd update but.  This allows the
4411          * lock status bit to clear as normal, but should the FLL be enabled
4412          * again due to a control clock being required, the lock won't re-assert
4413          * as the FLL config registers are automatically applied when the FLL
4414          * enables.
4415          */
4416         regmap_update_bits(madera->regmap,
4417                            fll->base + MADERA_FLL_CONTROL_11_OFFS,
4418                            MADERA_FLL1_LOCKDET_MASK, 0);
4419         regmap_update_bits(madera->regmap,
4420                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
4421                            MADERA_FLL1_HOLD_MASK, MADERA_FLL1_HOLD_MASK);
4422         regmap_update_bits_check(madera->regmap,
4423                                  fll->base + MADERA_FLL_CONTROL_1_OFFS,
4424                                  MADERA_FLL1_ENA_MASK, 0, &change);
4425
4426         madera_wait_for_fll(fll, false);
4427
4428         /* ctrl_up gates the writes to all the fll's registers, setting it to 0
4429          * here ensures that after a runtime suspend/resume cycle when one
4430          * enables the fll then ctrl_up is the last bit that is configured
4431          * by the fll enable code rather than the cache sync operation which
4432          * would have updated it much earlier before writing out all fll
4433          * registers
4434          */
4435         regmap_update_bits(madera->regmap,
4436                            fll->base + MADERA_FLL_CONTROL_2_OFFS,
4437                            MADERA_FLL1_CTRL_UPD_MASK, 0);
4438
4439         if (change) {
4440                 madera_set_fllhj_clks(fll, fll->base, false);
4441                 pm_runtime_put_autosuspend(madera->dev);
4442         }
4443
4444         return 0;
4445 }
4446
4447 static int madera_fllhj_apply(struct madera_fll *fll, int fin)
4448 {
4449         struct madera *madera = fll->madera;
4450         int refdiv, fref, fout, lockdet_thr, fbdiv, hp, fast_clk, fllgcd;
4451         bool frac = false;
4452         unsigned int fll_n, min_n, max_n, ratio, theta, lambda;
4453         unsigned int gains, val, num;
4454
4455         madera_fll_dbg(fll, "fin=%d, fout=%d\n", fin, fll->fout);
4456
4457         for (refdiv = 0; refdiv < 4; refdiv++)
4458                 if ((fin / (1 << refdiv)) <= MADERA_FLLHJ_MAX_THRESH)
4459                         break;
4460
4461         fref = fin / (1 << refdiv);
4462
4463         /* Use simple heuristic approach to find a configuration that
4464          * should work for most input clocks.
4465          */
4466         fast_clk = 0;
4467         fout = fll->fout;
4468         frac = fout % fref;
4469
4470         if (fref < MADERA_FLLHJ_LOW_THRESH) {
4471                 lockdet_thr = 2;
4472                 gains = MADERA_FLLHJ_LOW_GAINS;
4473                 if (frac)
4474                         fbdiv = 256;
4475                 else
4476                         fbdiv = 4;
4477         } else if (fref < MADERA_FLLHJ_MID_THRESH) {
4478                 lockdet_thr = 8;
4479                 gains = MADERA_FLLHJ_MID_GAINS;
4480                 fbdiv = 1;
4481         } else {
4482                 lockdet_thr = 8;
4483                 gains = MADERA_FLLHJ_HIGH_GAINS;
4484                 fbdiv = 1;
4485                 /* For high speed input clocks, enable 300MHz fast oscillator
4486                  * when we're in fractional divider mode.
4487                  */
4488                 if (frac) {
4489                         fast_clk = 0x3;
4490                         fout = fll->fout * 6;
4491                 }
4492         }
4493         /* Use high performance mode for fractional configurations. */
4494         if (frac) {
4495                 hp = 0x3;
4496                 min_n = MADERA_FLLHJ_FRAC_MIN_N;
4497                 max_n = MADERA_FLLHJ_FRAC_MAX_N;
4498         } else {
4499                 hp = 0x0;
4500                 min_n = MADERA_FLLHJ_INT_MIN_N;
4501                 max_n = MADERA_FLLHJ_INT_MAX_N;
4502         }
4503
4504         ratio = fout / fref;
4505
4506         madera_fll_dbg(fll, "refdiv=%d, fref=%d, frac:%d\n",
4507                        refdiv, fref, frac);
4508
4509         while (ratio / fbdiv < min_n) {
4510                 fbdiv /= 2;
4511                 if (fbdiv < 1) {
4512                         madera_fll_err(fll, "FBDIV (%d) must be >= 1\n", fbdiv);
4513                         return -EINVAL;
4514                 }
4515         }
4516         while (frac && (ratio / fbdiv > max_n)) {
4517                 fbdiv *= 2;
4518                 if (fbdiv >= 1024) {
4519                         madera_fll_err(fll, "FBDIV (%u) >= 1024\n", fbdiv);
4520                         return -EINVAL;
4521                 }
4522         }
4523
4524         madera_fll_dbg(fll, "lockdet=%d, hp=0x%x, fbdiv:%d\n",
4525                        lockdet_thr, hp, fbdiv);
4526
4527         /* Calculate N.K values */
4528         fllgcd = gcd(fout, fbdiv * fref);
4529         num = fout / fllgcd;
4530         lambda = (fref * fbdiv) / fllgcd;
4531         fll_n = num / lambda;
4532         theta = num % lambda;
4533
4534         madera_fll_dbg(fll, "fll_n=%d, gcd=%d, theta=%d, lambda=%d\n",
4535                        fll_n, fllgcd, theta, lambda);
4536
4537         /* Some sanity checks before any registers are written. */
4538         if (fll_n < min_n || fll_n > max_n) {
4539                 madera_fll_err(fll, "N not in valid %s mode range %d-%d: %d\n",
4540                                frac ? "fractional" : "integer", min_n, max_n,
4541                                fll_n);
4542                 return -EINVAL;
4543         }
4544         if (fbdiv < 1 || (frac && fbdiv >= 1024) || (!frac && fbdiv >= 256)) {
4545                 madera_fll_err(fll, "Invalid fbdiv for %s mode (%u)\n",
4546                                frac ? "fractional" : "integer", fbdiv);
4547                 return -EINVAL;
4548         }
4549
4550         /* clear the ctrl_upd bit to guarantee we write to it later. */
4551         regmap_write(madera->regmap,
4552                      fll->base + MADERA_FLL_CONTROL_2_OFFS,
4553                      fll_n << MADERA_FLL1_N_SHIFT);
4554         regmap_update_bits(madera->regmap,
4555                            fll->base + MADERA_FLL_CONTROL_3_OFFS,
4556                            MADERA_FLL1_THETA_MASK,
4557                            theta << MADERA_FLL1_THETA_SHIFT);
4558         regmap_update_bits(madera->regmap,
4559                            fll->base + MADERA_FLL_CONTROL_4_OFFS,
4560                            MADERA_FLL1_LAMBDA_MASK,
4561                            lambda << MADERA_FLL1_LAMBDA_SHIFT);
4562         regmap_update_bits(madera->regmap,
4563                            fll->base + MADERA_FLL_CONTROL_5_OFFS,
4564                            MADERA_FLL1_FB_DIV_MASK,
4565                            fbdiv << MADERA_FLL1_FB_DIV_SHIFT);
4566         regmap_update_bits(madera->regmap,
4567                            fll->base + MADERA_FLL_CONTROL_6_OFFS,
4568                            MADERA_FLL1_REFCLK_DIV_MASK,
4569                            refdiv << MADERA_FLL1_REFCLK_DIV_SHIFT);
4570         regmap_update_bits(madera->regmap,
4571                            fll->base + MADERA_FLL_GAIN_OFFS,
4572                            0xffff,
4573                            gains);
4574         val = hp << MADERA_FLL1_HP_SHIFT;
4575         val |= 1 << MADERA_FLL1_PHASEDET_ENA_SHIFT;
4576         regmap_update_bits(madera->regmap,
4577                            fll->base + MADERA_FLL_CONTROL_10_OFFS,
4578                            MADERA_FLL1_HP_MASK | MADERA_FLL1_PHASEDET_ENA_MASK,
4579                            val);
4580         regmap_update_bits(madera->regmap,
4581                            fll->base + MADERA_FLL_CONTROL_11_OFFS,
4582                            MADERA_FLL1_LOCKDET_THR_MASK,
4583                            lockdet_thr << MADERA_FLL1_LOCKDET_THR_SHIFT);
4584         regmap_update_bits(madera->regmap,
4585                            fll->base + MADERA_FLL1_DIGITAL_TEST_1_OFFS,
4586                            MADERA_FLL1_SYNC_EFS_ENA_MASK |
4587                            MADERA_FLL1_CLK_VCO_FAST_SRC_MASK,
4588                            fast_clk);
4589
4590         return 0;
4591 }
4592
4593 static int madera_fllhj_enable(struct madera_fll *fll)
4594 {
4595         struct madera *madera = fll->madera;
4596         int already_enabled = madera_is_enabled_fll(fll, fll->base);
4597         int ret;
4598
4599         if (already_enabled < 0)
4600                 return already_enabled;
4601
4602         if (!already_enabled)
4603                 pm_runtime_get_sync(madera->dev);
4604
4605         madera_fll_dbg(fll, "Enabling FLL, initially %s\n",
4606                        already_enabled ? "enabled" : "disabled");
4607
4608         /* FLLn_HOLD must be set before configuring any registers */
4609         regmap_update_bits(fll->madera->regmap,
4610                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
4611                            MADERA_FLL1_HOLD_MASK,
4612                            MADERA_FLL1_HOLD_MASK);
4613
4614         if (already_enabled)
4615                 madera_set_fllhj_clks(fll, fll->base, false);
4616
4617         /* Apply refclk */
4618         ret = madera_fllhj_apply(fll, fll->ref_freq);
4619         if (ret) {
4620                 madera_fll_err(fll, "Failed to set FLL: %d\n", ret);
4621                 goto out;
4622         }
4623         regmap_update_bits(madera->regmap,
4624                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
4625                            CS47L92_FLL1_REFCLK_SRC_MASK,
4626                            fll->ref_src << CS47L92_FLL1_REFCLK_SRC_SHIFT);
4627
4628         madera_set_fllhj_clks(fll, fll->base, true);
4629
4630         regmap_update_bits(madera->regmap,
4631                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
4632                            MADERA_FLL1_ENA_MASK,
4633                            MADERA_FLL1_ENA_MASK);
4634
4635 out:
4636         regmap_update_bits(madera->regmap,
4637                            fll->base + MADERA_FLL_CONTROL_11_OFFS,
4638                            MADERA_FLL1_LOCKDET_MASK,
4639                            MADERA_FLL1_LOCKDET_MASK);
4640
4641         regmap_update_bits(madera->regmap,
4642                            fll->base + MADERA_FLL_CONTROL_2_OFFS,
4643                            MADERA_FLL1_CTRL_UPD_MASK,
4644                            MADERA_FLL1_CTRL_UPD_MASK);
4645
4646         /* Release the hold so that flln locks to external frequency */
4647         regmap_update_bits(madera->regmap,
4648                            fll->base + MADERA_FLL_CONTROL_1_OFFS,
4649                            MADERA_FLL1_HOLD_MASK,
4650                            0);
4651
4652         if (!already_enabled)
4653                 madera_wait_for_fll(fll, true);
4654
4655         return 0;
4656 }
4657
4658 static int madera_fllhj_validate(struct madera_fll *fll,
4659                                  unsigned int ref_in,
4660                                  unsigned int fout)
4661 {
4662         if (fout && !ref_in) {
4663                 madera_fll_err(fll, "fllout set without valid input clk\n");
4664                 return -EINVAL;
4665         }
4666
4667         if (fll->fout && fout != fll->fout) {
4668                 madera_fll_err(fll, "Can't change output on active FLL\n");
4669                 return -EINVAL;
4670         }
4671
4672         if (ref_in / MADERA_FLL_MAX_REFDIV > MADERA_FLLHJ_MAX_THRESH) {
4673                 madera_fll_err(fll, "Can't scale %dMHz to <=13MHz\n", ref_in);
4674                 return -EINVAL;
4675         }
4676
4677         return 0;
4678 }
4679
4680 int madera_fllhj_set_refclk(struct madera_fll *fll, int source,
4681                             unsigned int fin, unsigned int fout)
4682 {
4683         int ret = 0;
4684
4685         /* To remain consistent with previous FLLs, we expect fout to be
4686          * provided in the form of the required sysclk rate, which is
4687          * 2x the calculated fll out.
4688          */
4689         if (fout)
4690                 fout /= 2;
4691
4692         if (fll->ref_src == source && fll->ref_freq == fin &&
4693             fll->fout == fout)
4694                 return 0;
4695
4696         if (fin && fout && madera_fllhj_validate(fll, fin, fout))
4697                 return -EINVAL;
4698
4699         fll->ref_src = source;
4700         fll->ref_freq = fin;
4701         fll->fout = fout;
4702
4703         if (fout)
4704                 ret = madera_fllhj_enable(fll);
4705         else
4706                 madera_fllhj_disable(fll);
4707
4708         return ret;
4709 }
4710 EXPORT_SYMBOL_GPL(madera_fllhj_set_refclk);
4711
4712 /**
4713  * madera_set_output_mode - Set the mode of the specified output
4714  *
4715  * @component: Device to configure
4716  * @output: Output number
4717  * @differential: True to set the output to differential mode
4718  *
4719  * Some systems use external analogue switches to connect more
4720  * analogue devices to the CODEC than are supported by the device.  In
4721  * some systems this requires changing the switched output from single
4722  * ended to differential mode dynamically at runtime, an operation
4723  * supported using this function.
4724  *
4725  * Most systems have a single static configuration and should use
4726  * platform data instead.
4727  */
4728 int madera_set_output_mode(struct snd_soc_component *component, int output,
4729                            bool differential)
4730 {
4731         unsigned int reg, val;
4732         int ret;
4733
4734         if (output < 1 || output > MADERA_MAX_OUTPUT)
4735                 return -EINVAL;
4736
4737         reg = MADERA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
4738
4739         if (differential)
4740                 val = MADERA_OUT1_MONO;
4741         else
4742                 val = 0;
4743
4744         ret = snd_soc_component_update_bits(component, reg, MADERA_OUT1_MONO,
4745                                             val);
4746         if (ret < 0)
4747                 return ret;
4748         else
4749                 return 0;
4750 }
4751 EXPORT_SYMBOL_GPL(madera_set_output_mode);
4752
4753 static bool madera_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
4754 {
4755         s16 a = be16_to_cpu(_a);
4756         s16 b = be16_to_cpu(_b);
4757
4758         if (!mode) {
4759                 return abs(a) >= 4096;
4760         } else {
4761                 if (abs(b) >= 4096)
4762                         return true;
4763
4764                 return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
4765         }
4766 }
4767
4768 int madera_eq_coeff_put(struct snd_kcontrol *kcontrol,
4769                         struct snd_ctl_elem_value *ucontrol)
4770 {
4771         struct snd_soc_component *component =
4772                 snd_soc_kcontrol_component(kcontrol);
4773         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
4774         struct madera *madera = priv->madera;
4775         struct soc_bytes *params = (void *)kcontrol->private_value;
4776         unsigned int val;
4777         __be16 *data;
4778         int len;
4779         int ret;
4780
4781         len = params->num_regs * regmap_get_val_bytes(madera->regmap);
4782
4783         data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
4784         if (!data)
4785                 return -ENOMEM;
4786
4787         data[0] &= cpu_to_be16(MADERA_EQ1_B1_MODE);
4788
4789         if (madera_eq_filter_unstable(!!data[0], data[1], data[2]) ||
4790             madera_eq_filter_unstable(true, data[4], data[5]) ||
4791             madera_eq_filter_unstable(true, data[8], data[9]) ||
4792             madera_eq_filter_unstable(true, data[12], data[13]) ||
4793             madera_eq_filter_unstable(false, data[16], data[17])) {
4794                 dev_err(madera->dev, "Rejecting unstable EQ coefficients\n");
4795                 ret = -EINVAL;
4796                 goto out;
4797         }
4798
4799         ret = regmap_read(madera->regmap, params->base, &val);
4800         if (ret != 0)
4801                 goto out;
4802
4803         val &= ~MADERA_EQ1_B1_MODE;
4804         data[0] |= cpu_to_be16(val);
4805
4806         ret = regmap_raw_write(madera->regmap, params->base, data, len);
4807
4808 out:
4809         kfree(data);
4810
4811         return ret;
4812 }
4813 EXPORT_SYMBOL_GPL(madera_eq_coeff_put);
4814
4815 int madera_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
4816                           struct snd_ctl_elem_value *ucontrol)
4817 {
4818         struct snd_soc_component *component =
4819                 snd_soc_kcontrol_component(kcontrol);
4820         struct madera_priv *priv = snd_soc_component_get_drvdata(component);
4821         struct madera *madera = priv->madera;
4822         __be16 *data = (__be16 *)ucontrol->value.bytes.data;
4823         s16 val = be16_to_cpu(*data);
4824
4825         if (abs(val) >= 4096) {
4826                 dev_err(madera->dev, "Rejecting unstable LHPF coefficients\n");
4827                 return -EINVAL;
4828         }
4829
4830         return snd_soc_bytes_put(kcontrol, ucontrol);
4831 }
4832 EXPORT_SYMBOL_GPL(madera_lhpf_coeff_put);
4833
4834 MODULE_SOFTDEP("pre: madera");
4835 MODULE_DESCRIPTION("ASoC Cirrus Logic Madera codec support");
4836 MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
4837 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
4838 MODULE_LICENSE("GPL v2");