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