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