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