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