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