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