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