xref: /linux/sound/soc/codecs/arizona.c (revision f99e9306)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * arizona.c - Wolfson Arizona class device shared support
4  *
5  * Copyright 2012 Wolfson Microelectronics plc
6  *
7  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
8  */
9 
10 #include <linux/delay.h>
11 #include <linux/gcd.h>
12 #include <linux/module.h>
13 #include <linux/of.h>
14 #include <linux/pm_runtime.h>
15 #include <sound/pcm.h>
16 #include <sound/pcm_params.h>
17 #include <sound/tlv.h>
18 
19 #include <linux/mfd/arizona/core.h>
20 #include <linux/mfd/arizona/registers.h>
21 
22 #include "arizona.h"
23 
24 #define ARIZONA_AIF_BCLK_CTRL                   0x00
25 #define ARIZONA_AIF_TX_PIN_CTRL                 0x01
26 #define ARIZONA_AIF_RX_PIN_CTRL                 0x02
27 #define ARIZONA_AIF_RATE_CTRL                   0x03
28 #define ARIZONA_AIF_FORMAT                      0x04
29 #define ARIZONA_AIF_TX_BCLK_RATE                0x05
30 #define ARIZONA_AIF_RX_BCLK_RATE                0x06
31 #define ARIZONA_AIF_FRAME_CTRL_1                0x07
32 #define ARIZONA_AIF_FRAME_CTRL_2                0x08
33 #define ARIZONA_AIF_FRAME_CTRL_3                0x09
34 #define ARIZONA_AIF_FRAME_CTRL_4                0x0A
35 #define ARIZONA_AIF_FRAME_CTRL_5                0x0B
36 #define ARIZONA_AIF_FRAME_CTRL_6                0x0C
37 #define ARIZONA_AIF_FRAME_CTRL_7                0x0D
38 #define ARIZONA_AIF_FRAME_CTRL_8                0x0E
39 #define ARIZONA_AIF_FRAME_CTRL_9                0x0F
40 #define ARIZONA_AIF_FRAME_CTRL_10               0x10
41 #define ARIZONA_AIF_FRAME_CTRL_11               0x11
42 #define ARIZONA_AIF_FRAME_CTRL_12               0x12
43 #define ARIZONA_AIF_FRAME_CTRL_13               0x13
44 #define ARIZONA_AIF_FRAME_CTRL_14               0x14
45 #define ARIZONA_AIF_FRAME_CTRL_15               0x15
46 #define ARIZONA_AIF_FRAME_CTRL_16               0x16
47 #define ARIZONA_AIF_FRAME_CTRL_17               0x17
48 #define ARIZONA_AIF_FRAME_CTRL_18               0x18
49 #define ARIZONA_AIF_TX_ENABLES                  0x19
50 #define ARIZONA_AIF_RX_ENABLES                  0x1A
51 #define ARIZONA_AIF_FORCE_WRITE                 0x1B
52 
53 #define ARIZONA_FLL_VCO_CORNER 141900000
54 #define ARIZONA_FLL_MAX_FREF   13500000
55 #define ARIZONA_FLL_MIN_FVCO   90000000
56 #define ARIZONA_FLL_MAX_FRATIO 16
57 #define ARIZONA_FLL_MAX_REFDIV 8
58 #define ARIZONA_FLL_MIN_OUTDIV 2
59 #define ARIZONA_FLL_MAX_OUTDIV 7
60 
61 #define ARIZONA_FMT_DSP_MODE_A          0
62 #define ARIZONA_FMT_DSP_MODE_B          1
63 #define ARIZONA_FMT_I2S_MODE            2
64 #define ARIZONA_FMT_LEFT_JUSTIFIED_MODE 3
65 
66 #define arizona_fll_err(_fll, fmt, ...) \
67 	dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
68 #define arizona_fll_warn(_fll, fmt, ...) \
69 	dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
70 #define arizona_fll_dbg(_fll, fmt, ...) \
71 	dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
72 
73 #define arizona_aif_err(_dai, fmt, ...) \
74 	dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
75 #define arizona_aif_warn(_dai, fmt, ...) \
76 	dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
77 #define arizona_aif_dbg(_dai, fmt, ...) \
78 	dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
79 
arizona_spk_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)80 static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
81 			  struct snd_kcontrol *kcontrol,
82 			  int event)
83 {
84 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
85 	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
86 	int val;
87 
88 	switch (event) {
89 	case SND_SOC_DAPM_POST_PMU:
90 		val = snd_soc_component_read(component,
91 					       ARIZONA_INTERRUPT_RAW_STATUS_3);
92 		if (val & ARIZONA_SPK_OVERHEAT_STS) {
93 			dev_crit(arizona->dev,
94 				 "Speaker not enabled due to temperature\n");
95 			return -EBUSY;
96 		}
97 
98 		regmap_update_bits_async(arizona->regmap,
99 					 ARIZONA_OUTPUT_ENABLES_1,
100 					 1 << w->shift, 1 << w->shift);
101 		break;
102 	case SND_SOC_DAPM_PRE_PMD:
103 		regmap_update_bits_async(arizona->regmap,
104 					 ARIZONA_OUTPUT_ENABLES_1,
105 					 1 << w->shift, 0);
106 		break;
107 	default:
108 		break;
109 	}
110 
111 	return arizona_out_ev(w, kcontrol, event);
112 }
113 
arizona_thermal_warn(int irq,void * data)114 static irqreturn_t arizona_thermal_warn(int irq, void *data)
115 {
116 	struct arizona *arizona = data;
117 	unsigned int val;
118 	int ret;
119 
120 	ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
121 			  &val);
122 	if (ret != 0) {
123 		dev_err(arizona->dev, "Failed to read thermal status: %d\n",
124 			ret);
125 	} else if (val & ARIZONA_SPK_OVERHEAT_WARN_STS) {
126 		dev_crit(arizona->dev, "Thermal warning\n");
127 	}
128 
129 	return IRQ_HANDLED;
130 }
131 
arizona_thermal_shutdown(int irq,void * data)132 static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
133 {
134 	struct arizona *arizona = data;
135 	unsigned int val;
136 	int ret;
137 
138 	ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
139 			  &val);
140 	if (ret != 0) {
141 		dev_err(arizona->dev, "Failed to read thermal status: %d\n",
142 			ret);
143 	} else if (val & ARIZONA_SPK_OVERHEAT_STS) {
144 		dev_crit(arizona->dev, "Thermal shutdown\n");
145 		ret = regmap_update_bits(arizona->regmap,
146 					 ARIZONA_OUTPUT_ENABLES_1,
147 					 ARIZONA_OUT4L_ENA |
148 					 ARIZONA_OUT4R_ENA, 0);
149 		if (ret != 0)
150 			dev_crit(arizona->dev,
151 				 "Failed to disable speaker outputs: %d\n",
152 				 ret);
153 	}
154 
155 	return IRQ_HANDLED;
156 }
157 
158 static const struct snd_soc_dapm_widget arizona_spkl =
159 	SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
160 			   ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
161 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
162 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
163 
164 static const struct snd_soc_dapm_widget arizona_spkr =
165 	SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
166 			   ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
167 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
168 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
169 
arizona_init_spk(struct snd_soc_component * component)170 int arizona_init_spk(struct snd_soc_component *component)
171 {
172 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
173 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
174 	struct arizona *arizona = priv->arizona;
175 	int ret;
176 
177 	ret = snd_soc_dapm_new_controls(dapm, &arizona_spkl, 1);
178 	if (ret != 0)
179 		return ret;
180 
181 	switch (arizona->type) {
182 	case WM8997:
183 	case CS47L24:
184 	case WM1831:
185 		break;
186 	default:
187 		ret = snd_soc_dapm_new_controls(dapm, &arizona_spkr, 1);
188 		if (ret != 0)
189 			return ret;
190 		break;
191 	}
192 
193 	return 0;
194 }
195 EXPORT_SYMBOL_GPL(arizona_init_spk);
196 
arizona_init_spk_irqs(struct arizona * arizona)197 int arizona_init_spk_irqs(struct arizona *arizona)
198 {
199 	int ret;
200 
201 	ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN,
202 				  "Thermal warning", arizona_thermal_warn,
203 				  arizona);
204 	if (ret != 0)
205 		dev_err(arizona->dev,
206 			"Failed to get thermal warning IRQ: %d\n",
207 			ret);
208 
209 	ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT,
210 				  "Thermal shutdown", arizona_thermal_shutdown,
211 				  arizona);
212 	if (ret != 0)
213 		dev_err(arizona->dev,
214 			"Failed to get thermal shutdown IRQ: %d\n",
215 			ret);
216 
217 	return 0;
218 }
219 EXPORT_SYMBOL_GPL(arizona_init_spk_irqs);
220 
arizona_free_spk_irqs(struct arizona * arizona)221 int arizona_free_spk_irqs(struct arizona *arizona)
222 {
223 	arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN, arizona);
224 	arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT, arizona);
225 
226 	return 0;
227 }
228 EXPORT_SYMBOL_GPL(arizona_free_spk_irqs);
229 
230 static const struct snd_soc_dapm_route arizona_mono_routes[] = {
231 	{ "OUT1R", NULL, "OUT1L" },
232 	{ "OUT2R", NULL, "OUT2L" },
233 	{ "OUT3R", NULL, "OUT3L" },
234 	{ "OUT4R", NULL, "OUT4L" },
235 	{ "OUT5R", NULL, "OUT5L" },
236 	{ "OUT6R", NULL, "OUT6L" },
237 };
238 
arizona_init_mono(struct snd_soc_component * component)239 int arizona_init_mono(struct snd_soc_component *component)
240 {
241 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
242 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
243 	struct arizona *arizona = priv->arizona;
244 	int i;
245 
246 	for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
247 		if (arizona->pdata.out_mono[i])
248 			snd_soc_dapm_add_routes(dapm,
249 						&arizona_mono_routes[i], 1);
250 	}
251 
252 	return 0;
253 }
254 EXPORT_SYMBOL_GPL(arizona_init_mono);
255 
arizona_init_gpio(struct snd_soc_component * component)256 int arizona_init_gpio(struct snd_soc_component *component)
257 {
258 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
259 	struct arizona *arizona = priv->arizona;
260 	int i;
261 
262 	switch (arizona->type) {
263 	case WM5110:
264 	case WM8280:
265 		snd_soc_component_disable_pin(component,
266 					      "DRC2 Signal Activity");
267 		break;
268 	default:
269 		break;
270 	}
271 
272 	snd_soc_component_disable_pin(component, "DRC1 Signal Activity");
273 
274 	for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
275 		switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
276 		case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
277 			snd_soc_component_enable_pin(component,
278 						     "DRC1 Signal Activity");
279 			break;
280 		case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
281 			snd_soc_component_enable_pin(component,
282 						     "DRC2 Signal Activity");
283 			break;
284 		default:
285 			break;
286 		}
287 	}
288 
289 	return 0;
290 }
291 EXPORT_SYMBOL_GPL(arizona_init_gpio);
292 
arizona_init_common(struct arizona * arizona)293 int arizona_init_common(struct arizona *arizona)
294 {
295 	struct arizona_pdata *pdata = &arizona->pdata;
296 	unsigned int val, mask;
297 	int i;
298 
299 	BLOCKING_INIT_NOTIFIER_HEAD(&arizona->notifier);
300 
301 	for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
302 		/* Default is 0 so noop with defaults */
303 		if (pdata->out_mono[i])
304 			val = ARIZONA_OUT1_MONO;
305 		else
306 			val = 0;
307 
308 		regmap_update_bits(arizona->regmap,
309 				   ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
310 				   ARIZONA_OUT1_MONO, val);
311 	}
312 
313 	for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
314 		if (pdata->spk_mute[i])
315 			regmap_update_bits(arizona->regmap,
316 					   ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
317 					   ARIZONA_SPK1_MUTE_ENDIAN_MASK |
318 					   ARIZONA_SPK1_MUTE_SEQ1_MASK,
319 					   pdata->spk_mute[i]);
320 
321 		if (pdata->spk_fmt[i])
322 			regmap_update_bits(arizona->regmap,
323 					   ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
324 					   ARIZONA_SPK1_FMT_MASK,
325 					   pdata->spk_fmt[i]);
326 	}
327 
328 	for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
329 		/* Default for both is 0 so noop with defaults */
330 		val = pdata->dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT;
331 		if (pdata->inmode[i] & ARIZONA_INMODE_DMIC)
332 			val |= 1 << ARIZONA_IN1_MODE_SHIFT;
333 
334 		switch (arizona->type) {
335 		case WM8998:
336 		case WM1814:
337 			regmap_update_bits(arizona->regmap,
338 				ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
339 				ARIZONA_IN1L_SRC_SE_MASK,
340 				(pdata->inmode[i] & ARIZONA_INMODE_SE)
341 					<< ARIZONA_IN1L_SRC_SE_SHIFT);
342 
343 			regmap_update_bits(arizona->regmap,
344 				ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
345 				ARIZONA_IN1R_SRC_SE_MASK,
346 				(pdata->inmode[i] & ARIZONA_INMODE_SE)
347 					<< ARIZONA_IN1R_SRC_SE_SHIFT);
348 
349 			mask = ARIZONA_IN1_DMIC_SUP_MASK |
350 			       ARIZONA_IN1_MODE_MASK;
351 			break;
352 		default:
353 			if (pdata->inmode[i] & ARIZONA_INMODE_SE)
354 				val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;
355 
356 			mask = ARIZONA_IN1_DMIC_SUP_MASK |
357 			       ARIZONA_IN1_MODE_MASK |
358 			       ARIZONA_IN1_SINGLE_ENDED_MASK;
359 			break;
360 		}
361 
362 		regmap_update_bits(arizona->regmap,
363 				   ARIZONA_IN1L_CONTROL + (i * 8),
364 				   mask, val);
365 	}
366 
367 	return 0;
368 }
369 EXPORT_SYMBOL_GPL(arizona_init_common);
370 
arizona_init_vol_limit(struct arizona * arizona)371 int arizona_init_vol_limit(struct arizona *arizona)
372 {
373 	int i;
374 
375 	for (i = 0; i < ARRAY_SIZE(arizona->pdata.out_vol_limit); ++i) {
376 		if (arizona->pdata.out_vol_limit[i])
377 			regmap_update_bits(arizona->regmap,
378 					   ARIZONA_DAC_VOLUME_LIMIT_1L + i * 4,
379 					   ARIZONA_OUT1L_VOL_LIM_MASK,
380 					   arizona->pdata.out_vol_limit[i]);
381 	}
382 
383 	return 0;
384 }
385 EXPORT_SYMBOL_GPL(arizona_init_vol_limit);
386 
387 const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
388 	"None",
389 	"Tone Generator 1",
390 	"Tone Generator 2",
391 	"Haptics",
392 	"AEC",
393 	"AEC2",
394 	"Mic Mute Mixer",
395 	"Noise Generator",
396 	"IN1L",
397 	"IN1R",
398 	"IN2L",
399 	"IN2R",
400 	"IN3L",
401 	"IN3R",
402 	"IN4L",
403 	"IN4R",
404 	"AIF1RX1",
405 	"AIF1RX2",
406 	"AIF1RX3",
407 	"AIF1RX4",
408 	"AIF1RX5",
409 	"AIF1RX6",
410 	"AIF1RX7",
411 	"AIF1RX8",
412 	"AIF2RX1",
413 	"AIF2RX2",
414 	"AIF2RX3",
415 	"AIF2RX4",
416 	"AIF2RX5",
417 	"AIF2RX6",
418 	"AIF3RX1",
419 	"AIF3RX2",
420 	"SLIMRX1",
421 	"SLIMRX2",
422 	"SLIMRX3",
423 	"SLIMRX4",
424 	"SLIMRX5",
425 	"SLIMRX6",
426 	"SLIMRX7",
427 	"SLIMRX8",
428 	"EQ1",
429 	"EQ2",
430 	"EQ3",
431 	"EQ4",
432 	"DRC1L",
433 	"DRC1R",
434 	"DRC2L",
435 	"DRC2R",
436 	"LHPF1",
437 	"LHPF2",
438 	"LHPF3",
439 	"LHPF4",
440 	"DSP1.1",
441 	"DSP1.2",
442 	"DSP1.3",
443 	"DSP1.4",
444 	"DSP1.5",
445 	"DSP1.6",
446 	"DSP2.1",
447 	"DSP2.2",
448 	"DSP2.3",
449 	"DSP2.4",
450 	"DSP2.5",
451 	"DSP2.6",
452 	"DSP3.1",
453 	"DSP3.2",
454 	"DSP3.3",
455 	"DSP3.4",
456 	"DSP3.5",
457 	"DSP3.6",
458 	"DSP4.1",
459 	"DSP4.2",
460 	"DSP4.3",
461 	"DSP4.4",
462 	"DSP4.5",
463 	"DSP4.6",
464 	"ASRC1L",
465 	"ASRC1R",
466 	"ASRC2L",
467 	"ASRC2R",
468 	"ISRC1INT1",
469 	"ISRC1INT2",
470 	"ISRC1INT3",
471 	"ISRC1INT4",
472 	"ISRC1DEC1",
473 	"ISRC1DEC2",
474 	"ISRC1DEC3",
475 	"ISRC1DEC4",
476 	"ISRC2INT1",
477 	"ISRC2INT2",
478 	"ISRC2INT3",
479 	"ISRC2INT4",
480 	"ISRC2DEC1",
481 	"ISRC2DEC2",
482 	"ISRC2DEC3",
483 	"ISRC2DEC4",
484 	"ISRC3INT1",
485 	"ISRC3INT2",
486 	"ISRC3INT3",
487 	"ISRC3INT4",
488 	"ISRC3DEC1",
489 	"ISRC3DEC2",
490 	"ISRC3DEC3",
491 	"ISRC3DEC4",
492 };
493 EXPORT_SYMBOL_GPL(arizona_mixer_texts);
494 
495 unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
496 	0x00,  /* None */
497 	0x04,  /* Tone */
498 	0x05,
499 	0x06,  /* Haptics */
500 	0x08,  /* AEC */
501 	0x09,  /* AEC2 */
502 	0x0c,  /* Noise mixer */
503 	0x0d,  /* Comfort noise */
504 	0x10,  /* IN1L */
505 	0x11,
506 	0x12,
507 	0x13,
508 	0x14,
509 	0x15,
510 	0x16,
511 	0x17,
512 	0x20,  /* AIF1RX1 */
513 	0x21,
514 	0x22,
515 	0x23,
516 	0x24,
517 	0x25,
518 	0x26,
519 	0x27,
520 	0x28,  /* AIF2RX1 */
521 	0x29,
522 	0x2a,
523 	0x2b,
524 	0x2c,
525 	0x2d,
526 	0x30,  /* AIF3RX1 */
527 	0x31,
528 	0x38,  /* SLIMRX1 */
529 	0x39,
530 	0x3a,
531 	0x3b,
532 	0x3c,
533 	0x3d,
534 	0x3e,
535 	0x3f,
536 	0x50,  /* EQ1 */
537 	0x51,
538 	0x52,
539 	0x53,
540 	0x58,  /* DRC1L */
541 	0x59,
542 	0x5a,
543 	0x5b,
544 	0x60,  /* LHPF1 */
545 	0x61,
546 	0x62,
547 	0x63,
548 	0x68,  /* DSP1.1 */
549 	0x69,
550 	0x6a,
551 	0x6b,
552 	0x6c,
553 	0x6d,
554 	0x70,  /* DSP2.1 */
555 	0x71,
556 	0x72,
557 	0x73,
558 	0x74,
559 	0x75,
560 	0x78,  /* DSP3.1 */
561 	0x79,
562 	0x7a,
563 	0x7b,
564 	0x7c,
565 	0x7d,
566 	0x80,  /* DSP4.1 */
567 	0x81,
568 	0x82,
569 	0x83,
570 	0x84,
571 	0x85,
572 	0x90,  /* ASRC1L */
573 	0x91,
574 	0x92,
575 	0x93,
576 	0xa0,  /* ISRC1INT1 */
577 	0xa1,
578 	0xa2,
579 	0xa3,
580 	0xa4,  /* ISRC1DEC1 */
581 	0xa5,
582 	0xa6,
583 	0xa7,
584 	0xa8,  /* ISRC2DEC1 */
585 	0xa9,
586 	0xaa,
587 	0xab,
588 	0xac,  /* ISRC2INT1 */
589 	0xad,
590 	0xae,
591 	0xaf,
592 	0xb0,  /* ISRC3DEC1 */
593 	0xb1,
594 	0xb2,
595 	0xb3,
596 	0xb4,  /* ISRC3INT1 */
597 	0xb5,
598 	0xb6,
599 	0xb7,
600 };
601 EXPORT_SYMBOL_GPL(arizona_mixer_values);
602 
603 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
604 EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
605 
606 const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
607 	"12kHz", "24kHz", "48kHz", "96kHz", "192kHz",
608 	"11.025kHz", "22.05kHz", "44.1kHz", "88.2kHz", "176.4kHz",
609 	"4kHz", "8kHz", "16kHz", "32kHz",
610 };
611 EXPORT_SYMBOL_GPL(arizona_sample_rate_text);
612 
613 const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
614 	0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
615 	0x10, 0x11, 0x12, 0x13,
616 };
617 EXPORT_SYMBOL_GPL(arizona_sample_rate_val);
618 
arizona_sample_rate_val_to_name(unsigned int rate_val)619 const char *arizona_sample_rate_val_to_name(unsigned int rate_val)
620 {
621 	int i;
622 
623 	for (i = 0; i < ARRAY_SIZE(arizona_sample_rate_val); ++i) {
624 		if (arizona_sample_rate_val[i] == rate_val)
625 			return arizona_sample_rate_text[i];
626 	}
627 
628 	return "Illegal";
629 }
630 EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name);
631 
632 const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
633 	"SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
634 };
635 EXPORT_SYMBOL_GPL(arizona_rate_text);
636 
637 const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
638 	0, 1, 2, 8,
639 };
640 EXPORT_SYMBOL_GPL(arizona_rate_val);
641 
642 const struct soc_enum arizona_isrc_fsh[] = {
643 	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1,
644 			      ARIZONA_ISRC1_FSH_SHIFT, 0xf,
645 			      ARIZONA_RATE_ENUM_SIZE,
646 			      arizona_rate_text, arizona_rate_val),
647 	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_1,
648 			      ARIZONA_ISRC2_FSH_SHIFT, 0xf,
649 			      ARIZONA_RATE_ENUM_SIZE,
650 			      arizona_rate_text, arizona_rate_val),
651 	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_1,
652 			      ARIZONA_ISRC3_FSH_SHIFT, 0xf,
653 			      ARIZONA_RATE_ENUM_SIZE,
654 			      arizona_rate_text, arizona_rate_val),
655 };
656 EXPORT_SYMBOL_GPL(arizona_isrc_fsh);
657 
658 const struct soc_enum arizona_isrc_fsl[] = {
659 	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
660 			      ARIZONA_ISRC1_FSL_SHIFT, 0xf,
661 			      ARIZONA_RATE_ENUM_SIZE,
662 			      arizona_rate_text, arizona_rate_val),
663 	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
664 			      ARIZONA_ISRC2_FSL_SHIFT, 0xf,
665 			      ARIZONA_RATE_ENUM_SIZE,
666 			      arizona_rate_text, arizona_rate_val),
667 	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
668 			      ARIZONA_ISRC3_FSL_SHIFT, 0xf,
669 			      ARIZONA_RATE_ENUM_SIZE,
670 			      arizona_rate_text, arizona_rate_val),
671 };
672 EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
673 
674 const struct soc_enum arizona_asrc_rate1 =
675 	SOC_VALUE_ENUM_SINGLE(ARIZONA_ASRC_RATE1,
676 			      ARIZONA_ASRC_RATE1_SHIFT, 0xf,
677 			      ARIZONA_RATE_ENUM_SIZE - 1,
678 			      arizona_rate_text, arizona_rate_val);
679 EXPORT_SYMBOL_GPL(arizona_asrc_rate1);
680 
681 static const char * const arizona_vol_ramp_text[] = {
682 	"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
683 	"15ms/6dB", "30ms/6dB",
684 };
685 
686 SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp,
687 		     ARIZONA_INPUT_VOLUME_RAMP,
688 		     ARIZONA_IN_VD_RAMP_SHIFT,
689 		     arizona_vol_ramp_text);
690 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
691 
692 SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp,
693 		     ARIZONA_INPUT_VOLUME_RAMP,
694 		     ARIZONA_IN_VI_RAMP_SHIFT,
695 		     arizona_vol_ramp_text);
696 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
697 
698 SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp,
699 		     ARIZONA_OUTPUT_VOLUME_RAMP,
700 		     ARIZONA_OUT_VD_RAMP_SHIFT,
701 		     arizona_vol_ramp_text);
702 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
703 
704 SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp,
705 		     ARIZONA_OUTPUT_VOLUME_RAMP,
706 		     ARIZONA_OUT_VI_RAMP_SHIFT,
707 		     arizona_vol_ramp_text);
708 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
709 
710 static const char * const arizona_lhpf_mode_text[] = {
711 	"Low-pass", "High-pass"
712 };
713 
714 SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode,
715 		     ARIZONA_HPLPF1_1,
716 		     ARIZONA_LHPF1_MODE_SHIFT,
717 		     arizona_lhpf_mode_text);
718 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
719 
720 SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode,
721 		     ARIZONA_HPLPF2_1,
722 		     ARIZONA_LHPF2_MODE_SHIFT,
723 		     arizona_lhpf_mode_text);
724 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
725 
726 SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode,
727 		     ARIZONA_HPLPF3_1,
728 		     ARIZONA_LHPF3_MODE_SHIFT,
729 		     arizona_lhpf_mode_text);
730 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
731 
732 SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode,
733 		     ARIZONA_HPLPF4_1,
734 		     ARIZONA_LHPF4_MODE_SHIFT,
735 		     arizona_lhpf_mode_text);
736 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
737 
738 static const char * const arizona_ng_hold_text[] = {
739 	"30ms", "120ms", "250ms", "500ms",
740 };
741 
742 SOC_ENUM_SINGLE_DECL(arizona_ng_hold,
743 		     ARIZONA_NOISE_GATE_CONTROL,
744 		     ARIZONA_NGATE_HOLD_SHIFT,
745 		     arizona_ng_hold_text);
746 EXPORT_SYMBOL_GPL(arizona_ng_hold);
747 
748 static const char * const arizona_in_hpf_cut_text[] = {
749 	"2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
750 };
751 
752 SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum,
753 		     ARIZONA_HPF_CONTROL,
754 		     ARIZONA_IN_HPF_CUT_SHIFT,
755 		     arizona_in_hpf_cut_text);
756 EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
757 
758 static const char * const arizona_in_dmic_osr_text[] = {
759 	"1.536MHz", "3.072MHz", "6.144MHz", "768kHz",
760 };
761 
762 const struct soc_enum arizona_in_dmic_osr[] = {
763 	SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
764 			ARRAY_SIZE(arizona_in_dmic_osr_text),
765 			arizona_in_dmic_osr_text),
766 	SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
767 			ARRAY_SIZE(arizona_in_dmic_osr_text),
768 			arizona_in_dmic_osr_text),
769 	SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
770 			ARRAY_SIZE(arizona_in_dmic_osr_text),
771 			arizona_in_dmic_osr_text),
772 	SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
773 			ARRAY_SIZE(arizona_in_dmic_osr_text),
774 			arizona_in_dmic_osr_text),
775 };
776 EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
777 
778 static const char * const arizona_anc_input_src_text[] = {
779 	"None", "IN1", "IN2", "IN3", "IN4",
780 };
781 
782 static const char * const arizona_anc_channel_src_text[] = {
783 	"None", "Left", "Right", "Combine",
784 };
785 
786 const struct soc_enum arizona_anc_input_src[] = {
787 	SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
788 			ARIZONA_IN_RXANCL_SEL_SHIFT,
789 			ARRAY_SIZE(arizona_anc_input_src_text),
790 			arizona_anc_input_src_text),
791 	SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL,
792 			ARIZONA_FCL_MIC_MODE_SEL_SHIFT,
793 			ARRAY_SIZE(arizona_anc_channel_src_text),
794 			arizona_anc_channel_src_text),
795 	SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
796 			ARIZONA_IN_RXANCR_SEL_SHIFT,
797 			ARRAY_SIZE(arizona_anc_input_src_text),
798 			arizona_anc_input_src_text),
799 	SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL,
800 			ARIZONA_FCR_MIC_MODE_SEL_SHIFT,
801 			ARRAY_SIZE(arizona_anc_channel_src_text),
802 			arizona_anc_channel_src_text),
803 };
804 EXPORT_SYMBOL_GPL(arizona_anc_input_src);
805 
806 static const char * const arizona_anc_ng_texts[] = {
807 	"None",
808 	"Internal",
809 	"External",
810 };
811 
812 SOC_ENUM_SINGLE_DECL(arizona_anc_ng_enum, SND_SOC_NOPM, 0,
813 		     arizona_anc_ng_texts);
814 EXPORT_SYMBOL_GPL(arizona_anc_ng_enum);
815 
816 static const char * const arizona_output_anc_src_text[] = {
817 	"None", "RXANCL", "RXANCR",
818 };
819 
820 const struct soc_enum arizona_output_anc_src[] = {
821 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
822 			ARIZONA_OUT1L_ANC_SRC_SHIFT,
823 			ARRAY_SIZE(arizona_output_anc_src_text),
824 			arizona_output_anc_src_text),
825 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1R,
826 			ARIZONA_OUT1R_ANC_SRC_SHIFT,
827 			ARRAY_SIZE(arizona_output_anc_src_text),
828 			arizona_output_anc_src_text),
829 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
830 			ARIZONA_OUT2L_ANC_SRC_SHIFT,
831 			ARRAY_SIZE(arizona_output_anc_src_text),
832 			arizona_output_anc_src_text),
833 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2R,
834 			ARIZONA_OUT2R_ANC_SRC_SHIFT,
835 			ARRAY_SIZE(arizona_output_anc_src_text),
836 			arizona_output_anc_src_text),
837 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
838 			ARIZONA_OUT3L_ANC_SRC_SHIFT,
839 			ARRAY_SIZE(arizona_output_anc_src_text),
840 			arizona_output_anc_src_text),
841 	SOC_ENUM_SINGLE(ARIZONA_DAC_VOLUME_LIMIT_3R,
842 			ARIZONA_OUT3R_ANC_SRC_SHIFT,
843 			ARRAY_SIZE(arizona_output_anc_src_text),
844 			arizona_output_anc_src_text),
845 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4L,
846 			ARIZONA_OUT4L_ANC_SRC_SHIFT,
847 			ARRAY_SIZE(arizona_output_anc_src_text),
848 			arizona_output_anc_src_text),
849 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4R,
850 			ARIZONA_OUT4R_ANC_SRC_SHIFT,
851 			ARRAY_SIZE(arizona_output_anc_src_text),
852 			arizona_output_anc_src_text),
853 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5L,
854 			ARIZONA_OUT5L_ANC_SRC_SHIFT,
855 			ARRAY_SIZE(arizona_output_anc_src_text),
856 			arizona_output_anc_src_text),
857 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5R,
858 			ARIZONA_OUT5R_ANC_SRC_SHIFT,
859 			ARRAY_SIZE(arizona_output_anc_src_text),
860 			arizona_output_anc_src_text),
861 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6L,
862 			ARIZONA_OUT6L_ANC_SRC_SHIFT,
863 			ARRAY_SIZE(arizona_output_anc_src_text),
864 			arizona_output_anc_src_text),
865 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6R,
866 			ARIZONA_OUT6R_ANC_SRC_SHIFT,
867 			ARRAY_SIZE(arizona_output_anc_src_text),
868 			arizona_output_anc_src_text),
869 };
870 EXPORT_SYMBOL_GPL(arizona_output_anc_src);
871 
872 const struct snd_kcontrol_new arizona_voice_trigger_switch[] = {
873 	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
874 	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 1, 1, 0),
875 	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 2, 1, 0),
876 	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 3, 1, 0),
877 };
878 EXPORT_SYMBOL_GPL(arizona_voice_trigger_switch);
879 
arizona_in_set_vu(struct snd_soc_component * component,int ena)880 static void arizona_in_set_vu(struct snd_soc_component *component, int ena)
881 {
882 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
883 	unsigned int val;
884 	int i;
885 
886 	if (ena)
887 		val = ARIZONA_IN_VU;
888 	else
889 		val = 0;
890 
891 	for (i = 0; i < priv->num_inputs; i++)
892 		snd_soc_component_update_bits(component,
893 				    ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
894 				    ARIZONA_IN_VU, val);
895 }
896 
arizona_input_analog(struct snd_soc_component * component,int shift)897 bool arizona_input_analog(struct snd_soc_component *component, int shift)
898 {
899 	unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8);
900 	unsigned int val = snd_soc_component_read(component, reg);
901 
902 	return !(val & ARIZONA_IN1_MODE_MASK);
903 }
904 EXPORT_SYMBOL_GPL(arizona_input_analog);
905 
arizona_in_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)906 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
907 		  int event)
908 {
909 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
910 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
911 	unsigned int reg;
912 
913 	if (w->shift % 2)
914 		reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
915 	else
916 		reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
917 
918 	switch (event) {
919 	case SND_SOC_DAPM_PRE_PMU:
920 		priv->in_pending++;
921 		break;
922 	case SND_SOC_DAPM_POST_PMU:
923 		snd_soc_component_update_bits(component, reg,
924 					      ARIZONA_IN1L_MUTE, 0);
925 
926 		/* If this is the last input pending then allow VU */
927 		priv->in_pending--;
928 		if (priv->in_pending == 0) {
929 			msleep(1);
930 			arizona_in_set_vu(component, 1);
931 		}
932 		break;
933 	case SND_SOC_DAPM_PRE_PMD:
934 		snd_soc_component_update_bits(component, reg,
935 				    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
936 				    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
937 		break;
938 	case SND_SOC_DAPM_POST_PMD:
939 		/* Disable volume updates if no inputs are enabled */
940 		reg = snd_soc_component_read(component, ARIZONA_INPUT_ENABLES);
941 		if (reg == 0)
942 			arizona_in_set_vu(component, 0);
943 		break;
944 	default:
945 		break;
946 	}
947 
948 	return 0;
949 }
950 EXPORT_SYMBOL_GPL(arizona_in_ev);
951 
arizona_out_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)952 int arizona_out_ev(struct snd_soc_dapm_widget *w,
953 		   struct snd_kcontrol *kcontrol,
954 		   int event)
955 {
956 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
957 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
958 	struct arizona *arizona = priv->arizona;
959 
960 	switch (event) {
961 	case SND_SOC_DAPM_PRE_PMU:
962 		switch (w->shift) {
963 		case ARIZONA_OUT1L_ENA_SHIFT:
964 		case ARIZONA_OUT1R_ENA_SHIFT:
965 		case ARIZONA_OUT2L_ENA_SHIFT:
966 		case ARIZONA_OUT2R_ENA_SHIFT:
967 		case ARIZONA_OUT3L_ENA_SHIFT:
968 		case ARIZONA_OUT3R_ENA_SHIFT:
969 			priv->out_up_pending++;
970 			priv->out_up_delay += 17;
971 			break;
972 		case ARIZONA_OUT4L_ENA_SHIFT:
973 		case ARIZONA_OUT4R_ENA_SHIFT:
974 			priv->out_up_pending++;
975 			switch (arizona->type) {
976 			case WM5102:
977 			case WM8997:
978 				break;
979 			default:
980 				priv->out_up_delay += 10;
981 				break;
982 			}
983 			break;
984 		default:
985 			break;
986 		}
987 		break;
988 	case SND_SOC_DAPM_POST_PMU:
989 		switch (w->shift) {
990 		case ARIZONA_OUT1L_ENA_SHIFT:
991 		case ARIZONA_OUT1R_ENA_SHIFT:
992 		case ARIZONA_OUT2L_ENA_SHIFT:
993 		case ARIZONA_OUT2R_ENA_SHIFT:
994 		case ARIZONA_OUT3L_ENA_SHIFT:
995 		case ARIZONA_OUT3R_ENA_SHIFT:
996 		case ARIZONA_OUT4L_ENA_SHIFT:
997 		case ARIZONA_OUT4R_ENA_SHIFT:
998 			priv->out_up_pending--;
999 			if (!priv->out_up_pending && priv->out_up_delay) {
1000 				dev_dbg(component->dev, "Power up delay: %d\n",
1001 					priv->out_up_delay);
1002 				msleep(priv->out_up_delay);
1003 				priv->out_up_delay = 0;
1004 			}
1005 			break;
1006 
1007 		default:
1008 			break;
1009 		}
1010 		break;
1011 	case SND_SOC_DAPM_PRE_PMD:
1012 		switch (w->shift) {
1013 		case ARIZONA_OUT1L_ENA_SHIFT:
1014 		case ARIZONA_OUT1R_ENA_SHIFT:
1015 		case ARIZONA_OUT2L_ENA_SHIFT:
1016 		case ARIZONA_OUT2R_ENA_SHIFT:
1017 		case ARIZONA_OUT3L_ENA_SHIFT:
1018 		case ARIZONA_OUT3R_ENA_SHIFT:
1019 			priv->out_down_pending++;
1020 			priv->out_down_delay++;
1021 			break;
1022 		case ARIZONA_OUT4L_ENA_SHIFT:
1023 		case ARIZONA_OUT4R_ENA_SHIFT:
1024 			priv->out_down_pending++;
1025 			switch (arizona->type) {
1026 			case WM5102:
1027 			case WM8997:
1028 				break;
1029 			case WM8998:
1030 			case WM1814:
1031 				priv->out_down_delay += 5;
1032 				break;
1033 			default:
1034 				priv->out_down_delay++;
1035 				break;
1036 			}
1037 			break;
1038 		default:
1039 			break;
1040 		}
1041 		break;
1042 	case SND_SOC_DAPM_POST_PMD:
1043 		switch (w->shift) {
1044 		case ARIZONA_OUT1L_ENA_SHIFT:
1045 		case ARIZONA_OUT1R_ENA_SHIFT:
1046 		case ARIZONA_OUT2L_ENA_SHIFT:
1047 		case ARIZONA_OUT2R_ENA_SHIFT:
1048 		case ARIZONA_OUT3L_ENA_SHIFT:
1049 		case ARIZONA_OUT3R_ENA_SHIFT:
1050 		case ARIZONA_OUT4L_ENA_SHIFT:
1051 		case ARIZONA_OUT4R_ENA_SHIFT:
1052 			priv->out_down_pending--;
1053 			if (!priv->out_down_pending && priv->out_down_delay) {
1054 				dev_dbg(component->dev, "Power down delay: %d\n",
1055 					priv->out_down_delay);
1056 				msleep(priv->out_down_delay);
1057 				priv->out_down_delay = 0;
1058 			}
1059 			break;
1060 		default:
1061 			break;
1062 		}
1063 		break;
1064 	default:
1065 		break;
1066 	}
1067 
1068 	return 0;
1069 }
1070 EXPORT_SYMBOL_GPL(arizona_out_ev);
1071 
arizona_hp_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1072 int arizona_hp_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
1073 		  int event)
1074 {
1075 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1076 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1077 	struct arizona *arizona = priv->arizona;
1078 	unsigned int mask = 1 << w->shift;
1079 	unsigned int val;
1080 
1081 	switch (event) {
1082 	case SND_SOC_DAPM_POST_PMU:
1083 		val = mask;
1084 		break;
1085 	case SND_SOC_DAPM_PRE_PMD:
1086 		val = 0;
1087 		break;
1088 	case SND_SOC_DAPM_PRE_PMU:
1089 	case SND_SOC_DAPM_POST_PMD:
1090 		return arizona_out_ev(w, kcontrol, event);
1091 	default:
1092 		return -EINVAL;
1093 	}
1094 
1095 	/* Store the desired state for the HP outputs */
1096 	priv->arizona->hp_ena &= ~mask;
1097 	priv->arizona->hp_ena |= val;
1098 
1099 	/* Force off if HPDET clamp is active */
1100 	if (priv->arizona->hpdet_clamp)
1101 		val = 0;
1102 
1103 	regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
1104 				 mask, val);
1105 
1106 	return arizona_out_ev(w, kcontrol, event);
1107 }
1108 EXPORT_SYMBOL_GPL(arizona_hp_ev);
1109 
arizona_dvfs_enable(struct snd_soc_component * component)1110 static int arizona_dvfs_enable(struct snd_soc_component *component)
1111 {
1112 	const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1113 	struct arizona *arizona = priv->arizona;
1114 	int ret;
1115 
1116 	ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
1117 	if (ret) {
1118 		dev_err(component->dev, "Failed to boost DCVDD: %d\n", ret);
1119 		return ret;
1120 	}
1121 
1122 	ret = regmap_update_bits(arizona->regmap,
1123 				 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1124 				 ARIZONA_SUBSYS_MAX_FREQ,
1125 				 ARIZONA_SUBSYS_MAX_FREQ);
1126 	if (ret) {
1127 		dev_err(component->dev, "Failed to enable subsys max: %d\n", ret);
1128 		regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1129 		return ret;
1130 	}
1131 
1132 	return 0;
1133 }
1134 
arizona_dvfs_disable(struct snd_soc_component * component)1135 static int arizona_dvfs_disable(struct snd_soc_component *component)
1136 {
1137 	const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1138 	struct arizona *arizona = priv->arizona;
1139 	int ret;
1140 
1141 	ret = regmap_update_bits(arizona->regmap,
1142 				 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1143 				 ARIZONA_SUBSYS_MAX_FREQ, 0);
1144 	if (ret) {
1145 		dev_err(component->dev, "Failed to disable subsys max: %d\n", ret);
1146 		return ret;
1147 	}
1148 
1149 	ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1150 	if (ret) {
1151 		dev_err(component->dev, "Failed to unboost DCVDD: %d\n", ret);
1152 		return ret;
1153 	}
1154 
1155 	return 0;
1156 }
1157 
arizona_dvfs_up(struct snd_soc_component * component,unsigned int flags)1158 int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags)
1159 {
1160 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1161 	int ret = 0;
1162 
1163 	mutex_lock(&priv->dvfs_lock);
1164 
1165 	if (!priv->dvfs_cached && !priv->dvfs_reqs) {
1166 		ret = arizona_dvfs_enable(component);
1167 		if (ret)
1168 			goto err;
1169 	}
1170 
1171 	priv->dvfs_reqs |= flags;
1172 err:
1173 	mutex_unlock(&priv->dvfs_lock);
1174 	return ret;
1175 }
1176 EXPORT_SYMBOL_GPL(arizona_dvfs_up);
1177 
arizona_dvfs_down(struct snd_soc_component * component,unsigned int flags)1178 int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags)
1179 {
1180 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1181 	unsigned int old_reqs;
1182 	int ret = 0;
1183 
1184 	mutex_lock(&priv->dvfs_lock);
1185 
1186 	old_reqs = priv->dvfs_reqs;
1187 	priv->dvfs_reqs &= ~flags;
1188 
1189 	if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
1190 		ret = arizona_dvfs_disable(component);
1191 
1192 	mutex_unlock(&priv->dvfs_lock);
1193 	return ret;
1194 }
1195 EXPORT_SYMBOL_GPL(arizona_dvfs_down);
1196 
arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1197 int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
1198 			   struct snd_kcontrol *kcontrol, int event)
1199 {
1200 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1201 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1202 	int ret = 0;
1203 
1204 	mutex_lock(&priv->dvfs_lock);
1205 
1206 	switch (event) {
1207 	case SND_SOC_DAPM_POST_PMU:
1208 		if (priv->dvfs_reqs)
1209 			ret = arizona_dvfs_enable(component);
1210 
1211 		priv->dvfs_cached = false;
1212 		break;
1213 	case SND_SOC_DAPM_PRE_PMD:
1214 		/* We must ensure DVFS is disabled before the codec goes into
1215 		 * suspend so that we are never in an illegal state of DVFS
1216 		 * enabled without enough DCVDD
1217 		 */
1218 		priv->dvfs_cached = true;
1219 
1220 		if (priv->dvfs_reqs)
1221 			ret = arizona_dvfs_disable(component);
1222 		break;
1223 	default:
1224 		break;
1225 	}
1226 
1227 	mutex_unlock(&priv->dvfs_lock);
1228 	return ret;
1229 }
1230 EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
1231 
arizona_init_dvfs(struct arizona_priv * priv)1232 void arizona_init_dvfs(struct arizona_priv *priv)
1233 {
1234 	mutex_init(&priv->dvfs_lock);
1235 }
1236 EXPORT_SYMBOL_GPL(arizona_init_dvfs);
1237 
arizona_anc_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1238 int arizona_anc_ev(struct snd_soc_dapm_widget *w,
1239 		   struct snd_kcontrol *kcontrol,
1240 		   int event)
1241 {
1242 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1243 	unsigned int val;
1244 
1245 	switch (event) {
1246 	case SND_SOC_DAPM_POST_PMU:
1247 		val = 1 << w->shift;
1248 		break;
1249 	case SND_SOC_DAPM_PRE_PMD:
1250 		val = 1 << (w->shift + 1);
1251 		break;
1252 	default:
1253 		return 0;
1254 	}
1255 
1256 	snd_soc_component_write(component, ARIZONA_CLOCK_CONTROL, val);
1257 
1258 	return 0;
1259 }
1260 EXPORT_SYMBOL_GPL(arizona_anc_ev);
1261 
1262 static unsigned int arizona_opclk_ref_48k_rates[] = {
1263 	6144000,
1264 	12288000,
1265 	24576000,
1266 	49152000,
1267 };
1268 
1269 static unsigned int arizona_opclk_ref_44k1_rates[] = {
1270 	5644800,
1271 	11289600,
1272 	22579200,
1273 	45158400,
1274 };
1275 
arizona_set_opclk(struct snd_soc_component * component,unsigned int clk,unsigned int freq)1276 static int arizona_set_opclk(struct snd_soc_component *component,
1277 			     unsigned int clk, unsigned int freq)
1278 {
1279 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1280 	unsigned int reg;
1281 	unsigned int *rates;
1282 	int ref, div, refclk;
1283 
1284 	switch (clk) {
1285 	case ARIZONA_CLK_OPCLK:
1286 		reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
1287 		refclk = priv->sysclk;
1288 		break;
1289 	case ARIZONA_CLK_ASYNC_OPCLK:
1290 		reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
1291 		refclk = priv->asyncclk;
1292 		break;
1293 	default:
1294 		return -EINVAL;
1295 	}
1296 
1297 	if (refclk % 8000)
1298 		rates = arizona_opclk_ref_44k1_rates;
1299 	else
1300 		rates = arizona_opclk_ref_48k_rates;
1301 
1302 	for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
1303 	     rates[ref] <= refclk; ref++) {
1304 		div = 1;
1305 		while (rates[ref] / div >= freq && div < 32) {
1306 			if (rates[ref] / div == freq) {
1307 				dev_dbg(component->dev, "Configured %dHz OPCLK\n",
1308 					freq);
1309 				snd_soc_component_update_bits(component, reg,
1310 						    ARIZONA_OPCLK_DIV_MASK |
1311 						    ARIZONA_OPCLK_SEL_MASK,
1312 						    (div <<
1313 						     ARIZONA_OPCLK_DIV_SHIFT) |
1314 						    ref);
1315 				return 0;
1316 			}
1317 			div++;
1318 		}
1319 	}
1320 
1321 	dev_err(component->dev, "Unable to generate %dHz OPCLK\n", freq);
1322 	return -EINVAL;
1323 }
1324 
arizona_clk_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1325 int arizona_clk_ev(struct snd_soc_dapm_widget *w,
1326 		   struct snd_kcontrol *kcontrol, int event)
1327 {
1328 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1329 	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
1330 	unsigned int val;
1331 	int clk_idx;
1332 	int ret;
1333 
1334 	ret = regmap_read(arizona->regmap, w->reg, &val);
1335 	if (ret) {
1336 		dev_err(component->dev, "Failed to check clock source: %d\n", ret);
1337 		return ret;
1338 	}
1339 
1340 	val = (val & ARIZONA_SYSCLK_SRC_MASK) >> ARIZONA_SYSCLK_SRC_SHIFT;
1341 
1342 	switch (val) {
1343 	case ARIZONA_CLK_SRC_MCLK1:
1344 		clk_idx = ARIZONA_MCLK1;
1345 		break;
1346 	case ARIZONA_CLK_SRC_MCLK2:
1347 		clk_idx = ARIZONA_MCLK2;
1348 		break;
1349 	default:
1350 		return 0;
1351 	}
1352 
1353 	switch (event) {
1354 	case SND_SOC_DAPM_PRE_PMU:
1355 		return clk_prepare_enable(arizona->mclk[clk_idx]);
1356 	case SND_SOC_DAPM_POST_PMD:
1357 		clk_disable_unprepare(arizona->mclk[clk_idx]);
1358 		return 0;
1359 	default:
1360 		return 0;
1361 	}
1362 }
1363 EXPORT_SYMBOL_GPL(arizona_clk_ev);
1364 
arizona_set_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)1365 int arizona_set_sysclk(struct snd_soc_component *component, int clk_id,
1366 		       int source, unsigned int freq, int dir)
1367 {
1368 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1369 	struct arizona *arizona = priv->arizona;
1370 	char *name;
1371 	unsigned int reg;
1372 	unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
1373 	unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
1374 	int *clk;
1375 
1376 	switch (clk_id) {
1377 	case ARIZONA_CLK_SYSCLK:
1378 		name = "SYSCLK";
1379 		reg = ARIZONA_SYSTEM_CLOCK_1;
1380 		clk = &priv->sysclk;
1381 		mask |= ARIZONA_SYSCLK_FRAC;
1382 		break;
1383 	case ARIZONA_CLK_ASYNCCLK:
1384 		name = "ASYNCCLK";
1385 		reg = ARIZONA_ASYNC_CLOCK_1;
1386 		clk = &priv->asyncclk;
1387 		break;
1388 	case ARIZONA_CLK_OPCLK:
1389 	case ARIZONA_CLK_ASYNC_OPCLK:
1390 		return arizona_set_opclk(component, clk_id, freq);
1391 	default:
1392 		return -EINVAL;
1393 	}
1394 
1395 	switch (freq) {
1396 	case  5644800:
1397 	case  6144000:
1398 		break;
1399 	case 11289600:
1400 	case 12288000:
1401 		val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1402 		break;
1403 	case 22579200:
1404 	case 24576000:
1405 		val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1406 		break;
1407 	case 45158400:
1408 	case 49152000:
1409 		val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1410 		break;
1411 	case 67737600:
1412 	case 73728000:
1413 		val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1414 		break;
1415 	case 90316800:
1416 	case 98304000:
1417 		val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1418 		break;
1419 	case 135475200:
1420 	case 147456000:
1421 		val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1422 		break;
1423 	case 0:
1424 		dev_dbg(arizona->dev, "%s cleared\n", name);
1425 		*clk = freq;
1426 		return 0;
1427 	default:
1428 		return -EINVAL;
1429 	}
1430 
1431 	*clk = freq;
1432 
1433 	if (freq % 6144000)
1434 		val |= ARIZONA_SYSCLK_FRAC;
1435 
1436 	dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
1437 
1438 	return regmap_update_bits(arizona->regmap, reg, mask, val);
1439 }
1440 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
1441 
arizona_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)1442 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1443 {
1444 	struct snd_soc_component *component = dai->component;
1445 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1446 	struct arizona *arizona = priv->arizona;
1447 	int lrclk, bclk, mode, base;
1448 
1449 	base = dai->driver->base;
1450 
1451 	lrclk = 0;
1452 	bclk = 0;
1453 
1454 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1455 	case SND_SOC_DAIFMT_DSP_A:
1456 		mode = ARIZONA_FMT_DSP_MODE_A;
1457 		break;
1458 	case SND_SOC_DAIFMT_DSP_B:
1459 		if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1460 				!= SND_SOC_DAIFMT_CBM_CFM) {
1461 			arizona_aif_err(dai, "DSP_B not valid in slave mode\n");
1462 			return -EINVAL;
1463 		}
1464 		mode = ARIZONA_FMT_DSP_MODE_B;
1465 		break;
1466 	case SND_SOC_DAIFMT_I2S:
1467 		mode = ARIZONA_FMT_I2S_MODE;
1468 		break;
1469 	case SND_SOC_DAIFMT_LEFT_J:
1470 		if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1471 				!= SND_SOC_DAIFMT_CBM_CFM) {
1472 			arizona_aif_err(dai, "LEFT_J not valid in slave mode\n");
1473 			return -EINVAL;
1474 		}
1475 		mode = ARIZONA_FMT_LEFT_JUSTIFIED_MODE;
1476 		break;
1477 	default:
1478 		arizona_aif_err(dai, "Unsupported DAI format %d\n",
1479 				fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1480 		return -EINVAL;
1481 	}
1482 
1483 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1484 	case SND_SOC_DAIFMT_CBS_CFS:
1485 		break;
1486 	case SND_SOC_DAIFMT_CBS_CFM:
1487 		lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1488 		break;
1489 	case SND_SOC_DAIFMT_CBM_CFS:
1490 		bclk |= ARIZONA_AIF1_BCLK_MSTR;
1491 		break;
1492 	case SND_SOC_DAIFMT_CBM_CFM:
1493 		bclk |= ARIZONA_AIF1_BCLK_MSTR;
1494 		lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1495 		break;
1496 	default:
1497 		arizona_aif_err(dai, "Unsupported master mode %d\n",
1498 				fmt & SND_SOC_DAIFMT_MASTER_MASK);
1499 		return -EINVAL;
1500 	}
1501 
1502 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1503 	case SND_SOC_DAIFMT_NB_NF:
1504 		break;
1505 	case SND_SOC_DAIFMT_IB_IF:
1506 		bclk |= ARIZONA_AIF1_BCLK_INV;
1507 		lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1508 		break;
1509 	case SND_SOC_DAIFMT_IB_NF:
1510 		bclk |= ARIZONA_AIF1_BCLK_INV;
1511 		break;
1512 	case SND_SOC_DAIFMT_NB_IF:
1513 		lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1514 		break;
1515 	default:
1516 		return -EINVAL;
1517 	}
1518 
1519 	regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
1520 				 ARIZONA_AIF1_BCLK_INV |
1521 				 ARIZONA_AIF1_BCLK_MSTR,
1522 				 bclk);
1523 	regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
1524 				 ARIZONA_AIF1TX_LRCLK_INV |
1525 				 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
1526 	regmap_update_bits_async(arizona->regmap,
1527 				 base + ARIZONA_AIF_RX_PIN_CTRL,
1528 				 ARIZONA_AIF1RX_LRCLK_INV |
1529 				 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
1530 	regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
1531 			   ARIZONA_AIF1_FMT_MASK, mode);
1532 
1533 	return 0;
1534 }
1535 
1536 static const int arizona_48k_bclk_rates[] = {
1537 	-1,
1538 	48000,
1539 	64000,
1540 	96000,
1541 	128000,
1542 	192000,
1543 	256000,
1544 	384000,
1545 	512000,
1546 	768000,
1547 	1024000,
1548 	1536000,
1549 	2048000,
1550 	3072000,
1551 	4096000,
1552 	6144000,
1553 	8192000,
1554 	12288000,
1555 	24576000,
1556 };
1557 
1558 static const int arizona_44k1_bclk_rates[] = {
1559 	-1,
1560 	44100,
1561 	58800,
1562 	88200,
1563 	117600,
1564 	177640,
1565 	235200,
1566 	352800,
1567 	470400,
1568 	705600,
1569 	940800,
1570 	1411200,
1571 	1881600,
1572 	2822400,
1573 	3763200,
1574 	5644800,
1575 	7526400,
1576 	11289600,
1577 	22579200,
1578 };
1579 
1580 static const unsigned int arizona_sr_vals[] = {
1581 	0,
1582 	12000,
1583 	24000,
1584 	48000,
1585 	96000,
1586 	192000,
1587 	384000,
1588 	768000,
1589 	0,
1590 	11025,
1591 	22050,
1592 	44100,
1593 	88200,
1594 	176400,
1595 	352800,
1596 	705600,
1597 	4000,
1598 	8000,
1599 	16000,
1600 	32000,
1601 	64000,
1602 	128000,
1603 	256000,
1604 	512000,
1605 };
1606 
1607 #define ARIZONA_48K_RATE_MASK	0x0F003E
1608 #define ARIZONA_44K1_RATE_MASK	0x003E00
1609 #define ARIZONA_RATE_MASK	(ARIZONA_48K_RATE_MASK | ARIZONA_44K1_RATE_MASK)
1610 
1611 static const struct snd_pcm_hw_constraint_list arizona_constraint = {
1612 	.count	= ARRAY_SIZE(arizona_sr_vals),
1613 	.list	= arizona_sr_vals,
1614 };
1615 
arizona_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)1616 static int arizona_startup(struct snd_pcm_substream *substream,
1617 			   struct snd_soc_dai *dai)
1618 {
1619 	struct snd_soc_component *component = dai->component;
1620 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1621 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1622 	unsigned int base_rate;
1623 
1624 	if (!substream->runtime)
1625 		return 0;
1626 
1627 	switch (dai_priv->clk) {
1628 	case ARIZONA_CLK_SYSCLK:
1629 		base_rate = priv->sysclk;
1630 		break;
1631 	case ARIZONA_CLK_ASYNCCLK:
1632 		base_rate = priv->asyncclk;
1633 		break;
1634 	default:
1635 		return 0;
1636 	}
1637 
1638 	if (base_rate == 0)
1639 		dai_priv->constraint.mask = ARIZONA_RATE_MASK;
1640 	else if (base_rate % 8000)
1641 		dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK;
1642 	else
1643 		dai_priv->constraint.mask = ARIZONA_48K_RATE_MASK;
1644 
1645 	return snd_pcm_hw_constraint_list(substream->runtime, 0,
1646 					  SNDRV_PCM_HW_PARAM_RATE,
1647 					  &dai_priv->constraint);
1648 }
1649 
arizona_wm5102_set_dac_comp(struct snd_soc_component * component,unsigned int rate)1650 static void arizona_wm5102_set_dac_comp(struct snd_soc_component *component,
1651 					unsigned int rate)
1652 {
1653 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1654 	struct arizona *arizona = priv->arizona;
1655 	struct reg_sequence dac_comp[] = {
1656 		{ 0x80, 0x3 },
1657 		{ ARIZONA_DAC_COMP_1, 0 },
1658 		{ ARIZONA_DAC_COMP_2, 0 },
1659 		{ 0x80, 0x0 },
1660 	};
1661 
1662 	mutex_lock(&arizona->dac_comp_lock);
1663 
1664 	dac_comp[1].def = arizona->dac_comp_coeff;
1665 	if (rate >= 176400)
1666 		dac_comp[2].def = arizona->dac_comp_enabled;
1667 
1668 	mutex_unlock(&arizona->dac_comp_lock);
1669 
1670 	regmap_multi_reg_write(arizona->regmap,
1671 			       dac_comp,
1672 			       ARRAY_SIZE(dac_comp));
1673 }
1674 
arizona_hw_params_rate(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)1675 static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1676 				  struct snd_pcm_hw_params *params,
1677 				  struct snd_soc_dai *dai)
1678 {
1679 	struct snd_soc_component *component = dai->component;
1680 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1681 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1682 	int base = dai->driver->base;
1683 	int i, sr_val, ret;
1684 
1685 	/*
1686 	 * We will need to be more flexible than this in future,
1687 	 * currently we use a single sample rate for SYSCLK.
1688 	 */
1689 	for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1690 		if (arizona_sr_vals[i] == params_rate(params))
1691 			break;
1692 	if (i == ARRAY_SIZE(arizona_sr_vals)) {
1693 		arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1694 				params_rate(params));
1695 		return -EINVAL;
1696 	}
1697 	sr_val = i;
1698 
1699 	switch (priv->arizona->type) {
1700 	case WM5102:
1701 	case WM8997:
1702 		if (arizona_sr_vals[sr_val] >= 88200)
1703 			ret = arizona_dvfs_up(component, ARIZONA_DVFS_SR1_RQ);
1704 		else
1705 			ret = arizona_dvfs_down(component, ARIZONA_DVFS_SR1_RQ);
1706 
1707 		if (ret) {
1708 			arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
1709 			return ret;
1710 		}
1711 		break;
1712 	default:
1713 		break;
1714 	}
1715 
1716 	switch (dai_priv->clk) {
1717 	case ARIZONA_CLK_SYSCLK:
1718 		switch (priv->arizona->type) {
1719 		case WM5102:
1720 			arizona_wm5102_set_dac_comp(component,
1721 						    params_rate(params));
1722 			break;
1723 		default:
1724 			break;
1725 		}
1726 
1727 		snd_soc_component_update_bits(component, ARIZONA_SAMPLE_RATE_1,
1728 					      ARIZONA_SAMPLE_RATE_1_MASK,
1729 					      sr_val);
1730 		if (base)
1731 			snd_soc_component_update_bits(component,
1732 					base + ARIZONA_AIF_RATE_CTRL,
1733 					ARIZONA_AIF1_RATE_MASK, 0);
1734 		break;
1735 	case ARIZONA_CLK_ASYNCCLK:
1736 		snd_soc_component_update_bits(component,
1737 					      ARIZONA_ASYNC_SAMPLE_RATE_1,
1738 					      ARIZONA_ASYNC_SAMPLE_RATE_1_MASK,
1739 					      sr_val);
1740 		if (base)
1741 			snd_soc_component_update_bits(component,
1742 					base + ARIZONA_AIF_RATE_CTRL,
1743 					ARIZONA_AIF1_RATE_MASK,
1744 					8 << ARIZONA_AIF1_RATE_SHIFT);
1745 		break;
1746 	default:
1747 		arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1748 		return -EINVAL;
1749 	}
1750 
1751 	return 0;
1752 }
1753 
arizona_aif_cfg_changed(struct snd_soc_component * component,int base,int bclk,int lrclk,int frame)1754 static bool arizona_aif_cfg_changed(struct snd_soc_component *component,
1755 				    int base, int bclk, int lrclk, int frame)
1756 {
1757 	int val;
1758 
1759 	val = snd_soc_component_read(component, base + ARIZONA_AIF_BCLK_CTRL);
1760 	if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
1761 		return true;
1762 
1763 	val = snd_soc_component_read(component, base + ARIZONA_AIF_RX_BCLK_RATE);
1764 	if (lrclk != (val & ARIZONA_AIF1RX_BCPF_MASK))
1765 		return true;
1766 
1767 	val = snd_soc_component_read(component, base + ARIZONA_AIF_FRAME_CTRL_1);
1768 	if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
1769 			     ARIZONA_AIF1TX_SLOT_LEN_MASK)))
1770 		return true;
1771 
1772 	return false;
1773 }
1774 
arizona_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)1775 static int arizona_hw_params(struct snd_pcm_substream *substream,
1776 			     struct snd_pcm_hw_params *params,
1777 			     struct snd_soc_dai *dai)
1778 {
1779 	struct snd_soc_component *component = dai->component;
1780 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1781 	struct arizona *arizona = priv->arizona;
1782 	int base = dai->driver->base;
1783 	const int *rates;
1784 	int i, ret, val;
1785 	int channels = params_channels(params);
1786 	int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1787 	int tdm_width = arizona->tdm_width[dai->id - 1];
1788 	int tdm_slots = arizona->tdm_slots[dai->id - 1];
1789 	int bclk, lrclk, wl, frame, bclk_target;
1790 	bool reconfig;
1791 	unsigned int aif_tx_state, aif_rx_state;
1792 
1793 	if (params_rate(params) % 4000)
1794 		rates = &arizona_44k1_bclk_rates[0];
1795 	else
1796 		rates = &arizona_48k_bclk_rates[0];
1797 
1798 	wl = params_width(params);
1799 
1800 	if (tdm_slots) {
1801 		arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
1802 				tdm_slots, tdm_width);
1803 		bclk_target = tdm_slots * tdm_width * params_rate(params);
1804 		channels = tdm_slots;
1805 	} else {
1806 		bclk_target = snd_soc_params_to_bclk(params);
1807 		tdm_width = wl;
1808 	}
1809 
1810 	if (chan_limit && chan_limit < channels) {
1811 		arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1812 		bclk_target /= channels;
1813 		bclk_target *= chan_limit;
1814 	}
1815 
1816 	/* Force multiple of 2 channels for I2S mode */
1817 	val = snd_soc_component_read(component, base + ARIZONA_AIF_FORMAT);
1818 	val &= ARIZONA_AIF1_FMT_MASK;
1819 	if ((channels & 1) && (val == ARIZONA_FMT_I2S_MODE)) {
1820 		arizona_aif_dbg(dai, "Forcing stereo mode\n");
1821 		bclk_target /= channels;
1822 		bclk_target *= channels + 1;
1823 	}
1824 
1825 	for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1826 		if (rates[i] >= bclk_target &&
1827 		    rates[i] % params_rate(params) == 0) {
1828 			bclk = i;
1829 			break;
1830 		}
1831 	}
1832 	if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1833 		arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1834 				params_rate(params));
1835 		return -EINVAL;
1836 	}
1837 
1838 	lrclk = rates[bclk] / params_rate(params);
1839 
1840 	arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1841 			rates[bclk], rates[bclk] / lrclk);
1842 
1843 	frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
1844 
1845 	reconfig = arizona_aif_cfg_changed(component, base, bclk, lrclk, frame);
1846 
1847 	if (reconfig) {
1848 		/* Save AIF TX/RX state */
1849 		aif_tx_state = snd_soc_component_read(component,
1850 					    base + ARIZONA_AIF_TX_ENABLES);
1851 		aif_rx_state = snd_soc_component_read(component,
1852 					    base + ARIZONA_AIF_RX_ENABLES);
1853 		/* Disable AIF TX/RX before reconfiguring it */
1854 		regmap_update_bits_async(arizona->regmap,
1855 					 base + ARIZONA_AIF_TX_ENABLES,
1856 					 0xff, 0x0);
1857 		regmap_update_bits(arizona->regmap,
1858 				   base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
1859 	}
1860 
1861 	ret = arizona_hw_params_rate(substream, params, dai);
1862 	if (ret != 0)
1863 		goto restore_aif;
1864 
1865 	if (reconfig) {
1866 		regmap_update_bits_async(arizona->regmap,
1867 					 base + ARIZONA_AIF_BCLK_CTRL,
1868 					 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1869 		regmap_update_bits_async(arizona->regmap,
1870 					 base + ARIZONA_AIF_TX_BCLK_RATE,
1871 					 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1872 		regmap_update_bits_async(arizona->regmap,
1873 					 base + ARIZONA_AIF_RX_BCLK_RATE,
1874 					 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1875 		regmap_update_bits_async(arizona->regmap,
1876 					 base + ARIZONA_AIF_FRAME_CTRL_1,
1877 					 ARIZONA_AIF1TX_WL_MASK |
1878 					 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1879 		regmap_update_bits(arizona->regmap,
1880 				   base + ARIZONA_AIF_FRAME_CTRL_2,
1881 				   ARIZONA_AIF1RX_WL_MASK |
1882 				   ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1883 	}
1884 
1885 restore_aif:
1886 	if (reconfig) {
1887 		/* Restore AIF TX/RX state */
1888 		regmap_update_bits_async(arizona->regmap,
1889 					 base + ARIZONA_AIF_TX_ENABLES,
1890 					 0xff, aif_tx_state);
1891 		regmap_update_bits(arizona->regmap,
1892 				   base + ARIZONA_AIF_RX_ENABLES,
1893 				   0xff, aif_rx_state);
1894 	}
1895 	return ret;
1896 }
1897 
arizona_dai_clk_str(int clk_id)1898 static const char *arizona_dai_clk_str(int clk_id)
1899 {
1900 	switch (clk_id) {
1901 	case ARIZONA_CLK_SYSCLK:
1902 		return "SYSCLK";
1903 	case ARIZONA_CLK_ASYNCCLK:
1904 		return "ASYNCCLK";
1905 	default:
1906 		return "Unknown clock";
1907 	}
1908 }
1909 
arizona_dai_set_sysclk(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)1910 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1911 				  int clk_id, unsigned int freq, int dir)
1912 {
1913 	struct snd_soc_component *component = dai->component;
1914 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1915 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1916 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1917 	struct snd_soc_dapm_route routes[2];
1918 
1919 	switch (clk_id) {
1920 	case ARIZONA_CLK_SYSCLK:
1921 	case ARIZONA_CLK_ASYNCCLK:
1922 		break;
1923 	default:
1924 		return -EINVAL;
1925 	}
1926 
1927 	if (clk_id == dai_priv->clk)
1928 		return 0;
1929 
1930 	if (snd_soc_dai_active(dai)) {
1931 		dev_err(component->dev, "Can't change clock on active DAI %d\n",
1932 			dai->id);
1933 		return -EBUSY;
1934 	}
1935 
1936 	dev_dbg(component->dev, "Setting AIF%d to %s\n", dai->id + 1,
1937 		arizona_dai_clk_str(clk_id));
1938 
1939 	memset(&routes, 0, sizeof(routes));
1940 	routes[0].sink = dai->driver->capture.stream_name;
1941 	routes[1].sink = dai->driver->playback.stream_name;
1942 
1943 	routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1944 	routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1945 	snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
1946 
1947 	routes[0].source = arizona_dai_clk_str(clk_id);
1948 	routes[1].source = arizona_dai_clk_str(clk_id);
1949 	snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
1950 
1951 	dai_priv->clk = clk_id;
1952 
1953 	return snd_soc_dapm_sync(dapm);
1954 }
1955 
arizona_set_tristate(struct snd_soc_dai * dai,int tristate)1956 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1957 {
1958 	struct snd_soc_component *component = dai->component;
1959 	int base = dai->driver->base;
1960 	unsigned int reg;
1961 
1962 	if (tristate)
1963 		reg = ARIZONA_AIF1_TRI;
1964 	else
1965 		reg = 0;
1966 
1967 	return snd_soc_component_update_bits(component,
1968 					     base + ARIZONA_AIF_RATE_CTRL,
1969 					     ARIZONA_AIF1_TRI, reg);
1970 }
1971 
arizona_set_channels_to_mask(struct snd_soc_dai * dai,unsigned int base,int channels,unsigned int mask)1972 static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
1973 					 unsigned int base,
1974 					 int channels, unsigned int mask)
1975 {
1976 	struct snd_soc_component *component = dai->component;
1977 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1978 	struct arizona *arizona = priv->arizona;
1979 	int slot, i;
1980 
1981 	for (i = 0; i < channels; ++i) {
1982 		slot = ffs(mask) - 1;
1983 		if (slot < 0)
1984 			return;
1985 
1986 		regmap_write(arizona->regmap, base + i, slot);
1987 
1988 		mask &= ~(1 << slot);
1989 	}
1990 
1991 	if (mask)
1992 		arizona_aif_warn(dai, "Too many channels in TDM mask\n");
1993 }
1994 
arizona_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)1995 static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1996 				unsigned int rx_mask, int slots, int slot_width)
1997 {
1998 	struct snd_soc_component *component = dai->component;
1999 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
2000 	struct arizona *arizona = priv->arizona;
2001 	int base = dai->driver->base;
2002 	int rx_max_chan = dai->driver->playback.channels_max;
2003 	int tx_max_chan = dai->driver->capture.channels_max;
2004 
2005 	/* Only support TDM for the physical AIFs */
2006 	if (dai->id > ARIZONA_MAX_AIF)
2007 		return -ENOTSUPP;
2008 
2009 	if (slots == 0) {
2010 		tx_mask = (1 << tx_max_chan) - 1;
2011 		rx_mask = (1 << rx_max_chan) - 1;
2012 	}
2013 
2014 	arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3,
2015 				     tx_max_chan, tx_mask);
2016 	arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11,
2017 				     rx_max_chan, rx_mask);
2018 
2019 	arizona->tdm_width[dai->id - 1] = slot_width;
2020 	arizona->tdm_slots[dai->id - 1] = slots;
2021 
2022 	return 0;
2023 }
2024 
2025 const struct snd_soc_dai_ops arizona_dai_ops = {
2026 	.startup = arizona_startup,
2027 	.set_fmt = arizona_set_fmt,
2028 	.set_tdm_slot = arizona_set_tdm_slot,
2029 	.hw_params = arizona_hw_params,
2030 	.set_sysclk = arizona_dai_set_sysclk,
2031 	.set_tristate = arizona_set_tristate,
2032 };
2033 EXPORT_SYMBOL_GPL(arizona_dai_ops);
2034 
2035 const struct snd_soc_dai_ops arizona_simple_dai_ops = {
2036 	.startup = arizona_startup,
2037 	.hw_params = arizona_hw_params_rate,
2038 	.set_sysclk = arizona_dai_set_sysclk,
2039 };
2040 EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
2041 
arizona_init_dai(struct arizona_priv * priv,int id)2042 int arizona_init_dai(struct arizona_priv *priv, int id)
2043 {
2044 	struct arizona_dai_priv *dai_priv = &priv->dai[id];
2045 
2046 	dai_priv->clk = ARIZONA_CLK_SYSCLK;
2047 	dai_priv->constraint = arizona_constraint;
2048 
2049 	return 0;
2050 }
2051 EXPORT_SYMBOL_GPL(arizona_init_dai);
2052 
2053 static struct {
2054 	unsigned int min;
2055 	unsigned int max;
2056 	u16 fratio;
2057 	int ratio;
2058 } fll_fratios[] = {
2059 	{       0,    64000, 4, 16 },
2060 	{   64000,   128000, 3,  8 },
2061 	{  128000,   256000, 2,  4 },
2062 	{  256000,  1000000, 1,  2 },
2063 	{ 1000000, 13500000, 0,  1 },
2064 };
2065 
2066 static const unsigned int pseudo_fref_max[ARIZONA_FLL_MAX_FRATIO] = {
2067 	13500000,
2068 	 6144000,
2069 	 6144000,
2070 	 3072000,
2071 	 3072000,
2072 	 2822400,
2073 	 2822400,
2074 	 1536000,
2075 	 1536000,
2076 	 1536000,
2077 	 1536000,
2078 	 1536000,
2079 	 1536000,
2080 	 1536000,
2081 	 1536000,
2082 	  768000,
2083 };
2084 
2085 static struct {
2086 	unsigned int min;
2087 	unsigned int max;
2088 	u16 gain;
2089 } fll_gains[] = {
2090 	{       0,   256000, 0 },
2091 	{  256000,  1000000, 2 },
2092 	{ 1000000, 13500000, 4 },
2093 };
2094 
2095 struct arizona_fll_cfg {
2096 	int n;
2097 	unsigned int theta;
2098 	unsigned int lambda;
2099 	int refdiv;
2100 	int outdiv;
2101 	int fratio;
2102 	int gain;
2103 };
2104 
arizona_validate_fll(struct arizona_fll * fll,unsigned int Fref,unsigned int Fout)2105 static int arizona_validate_fll(struct arizona_fll *fll,
2106 				unsigned int Fref,
2107 				unsigned int Fout)
2108 {
2109 	unsigned int Fvco_min;
2110 
2111 	if (fll->fout && Fout != fll->fout) {
2112 		arizona_fll_err(fll,
2113 				"Can't change output on active FLL\n");
2114 		return -EINVAL;
2115 	}
2116 
2117 	if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
2118 		arizona_fll_err(fll,
2119 				"Can't scale %dMHz in to <=13.5MHz\n",
2120 				Fref);
2121 		return -EINVAL;
2122 	}
2123 
2124 	Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
2125 	if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
2126 		arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
2127 				Fout);
2128 		return -EINVAL;
2129 	}
2130 
2131 	return 0;
2132 }
2133 
arizona_find_fratio(unsigned int Fref,int * fratio)2134 static int arizona_find_fratio(unsigned int Fref, int *fratio)
2135 {
2136 	int i;
2137 
2138 	/* Find an appropriate FLL_FRATIO */
2139 	for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
2140 		if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
2141 			if (fratio)
2142 				*fratio = fll_fratios[i].fratio;
2143 			return fll_fratios[i].ratio;
2144 		}
2145 	}
2146 
2147 	return -EINVAL;
2148 }
2149 
arizona_calc_fratio(struct arizona_fll * fll,struct arizona_fll_cfg * cfg,unsigned int target,unsigned int Fref,bool sync)2150 static int arizona_calc_fratio(struct arizona_fll *fll,
2151 			       struct arizona_fll_cfg *cfg,
2152 			       unsigned int target,
2153 			       unsigned int Fref, bool sync)
2154 {
2155 	int init_ratio, ratio;
2156 	int refdiv, div;
2157 
2158 	/* Fref must be <=13.5MHz, find initial refdiv */
2159 	div = 1;
2160 	cfg->refdiv = 0;
2161 	while (Fref > ARIZONA_FLL_MAX_FREF) {
2162 		div *= 2;
2163 		Fref /= 2;
2164 		cfg->refdiv++;
2165 
2166 		if (div > ARIZONA_FLL_MAX_REFDIV)
2167 			return -EINVAL;
2168 	}
2169 
2170 	/* Find an appropriate FLL_FRATIO */
2171 	init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
2172 	if (init_ratio < 0) {
2173 		arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
2174 				Fref);
2175 		return init_ratio;
2176 	}
2177 
2178 	switch (fll->arizona->type) {
2179 	case WM5102:
2180 	case WM8997:
2181 		return init_ratio;
2182 	case WM5110:
2183 	case WM8280:
2184 		if (fll->arizona->rev < 3 || sync)
2185 			return init_ratio;
2186 		break;
2187 	default:
2188 		if (sync)
2189 			return init_ratio;
2190 		break;
2191 	}
2192 
2193 	cfg->fratio = init_ratio - 1;
2194 
2195 	/* Adjust FRATIO/refdiv to avoid integer mode if possible */
2196 	refdiv = cfg->refdiv;
2197 
2198 	arizona_fll_dbg(fll, "pseudo: initial ratio=%u fref=%u refdiv=%u\n",
2199 			init_ratio, Fref, refdiv);
2200 
2201 	while (div <= ARIZONA_FLL_MAX_REFDIV) {
2202 		/* start from init_ratio because this may already give a
2203 		 * fractional N.K
2204 		 */
2205 		for (ratio = init_ratio; ratio > 0; ratio--) {
2206 			if (target % (ratio * Fref)) {
2207 				cfg->refdiv = refdiv;
2208 				cfg->fratio = ratio - 1;
2209 				arizona_fll_dbg(fll,
2210 					"pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2211 					Fref, refdiv, div, ratio);
2212 				return ratio;
2213 			}
2214 		}
2215 
2216 		for (ratio = init_ratio + 1; ratio <= ARIZONA_FLL_MAX_FRATIO;
2217 		     ratio++) {
2218 			if ((ARIZONA_FLL_VCO_CORNER / 2) /
2219 			    (fll->vco_mult * ratio) < Fref) {
2220 				arizona_fll_dbg(fll, "pseudo: hit VCO corner\n");
2221 				break;
2222 			}
2223 
2224 			if (Fref > pseudo_fref_max[ratio - 1]) {
2225 				arizona_fll_dbg(fll,
2226 					"pseudo: exceeded max fref(%u) for ratio=%u\n",
2227 					pseudo_fref_max[ratio - 1],
2228 					ratio);
2229 				break;
2230 			}
2231 
2232 			if (target % (ratio * Fref)) {
2233 				cfg->refdiv = refdiv;
2234 				cfg->fratio = ratio - 1;
2235 				arizona_fll_dbg(fll,
2236 					"pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2237 					Fref, refdiv, div, ratio);
2238 				return ratio;
2239 			}
2240 		}
2241 
2242 		div *= 2;
2243 		Fref /= 2;
2244 		refdiv++;
2245 		init_ratio = arizona_find_fratio(Fref, NULL);
2246 		arizona_fll_dbg(fll,
2247 				"pseudo: change fref=%u refdiv=%d(%d) ratio=%u\n",
2248 				Fref, refdiv, div, init_ratio);
2249 	}
2250 
2251 	arizona_fll_warn(fll, "Falling back to integer mode operation\n");
2252 	return cfg->fratio + 1;
2253 }
2254 
arizona_calc_fll(struct arizona_fll * fll,struct arizona_fll_cfg * cfg,unsigned int Fref,bool sync)2255 static int arizona_calc_fll(struct arizona_fll *fll,
2256 			    struct arizona_fll_cfg *cfg,
2257 			    unsigned int Fref, bool sync)
2258 {
2259 	unsigned int target, div, gcd_fll;
2260 	int i, ratio;
2261 
2262 	arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
2263 
2264 	/* Fvco should be over the targt; don't check the upper bound */
2265 	div = ARIZONA_FLL_MIN_OUTDIV;
2266 	while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
2267 		div++;
2268 		if (div > ARIZONA_FLL_MAX_OUTDIV)
2269 			return -EINVAL;
2270 	}
2271 	target = fll->fout * div / fll->vco_mult;
2272 	cfg->outdiv = div;
2273 
2274 	arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
2275 
2276 	/* Find an appropriate FLL_FRATIO and refdiv */
2277 	ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
2278 	if (ratio < 0)
2279 		return ratio;
2280 
2281 	/* Apply the division for our remaining calculations */
2282 	Fref = Fref / (1 << cfg->refdiv);
2283 
2284 	cfg->n = target / (ratio * Fref);
2285 
2286 	if (target % (ratio * Fref)) {
2287 		gcd_fll = gcd(target, ratio * Fref);
2288 		arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
2289 
2290 		cfg->theta = (target - (cfg->n * ratio * Fref))
2291 			/ gcd_fll;
2292 		cfg->lambda = (ratio * Fref) / gcd_fll;
2293 	} else {
2294 		cfg->theta = 0;
2295 		cfg->lambda = 0;
2296 	}
2297 
2298 	/* Round down to 16bit range with cost of accuracy lost.
2299 	 * Denominator must be bigger than numerator so we only
2300 	 * take care of it.
2301 	 */
2302 	while (cfg->lambda >= (1 << 16)) {
2303 		cfg->theta >>= 1;
2304 		cfg->lambda >>= 1;
2305 	}
2306 
2307 	for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
2308 		if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
2309 			cfg->gain = fll_gains[i].gain;
2310 			break;
2311 		}
2312 	}
2313 	if (i == ARRAY_SIZE(fll_gains)) {
2314 		arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
2315 				Fref);
2316 		return -EINVAL;
2317 	}
2318 
2319 	arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
2320 			cfg->n, cfg->theta, cfg->lambda);
2321 	arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n",
2322 			cfg->fratio, ratio, cfg->outdiv,
2323 			cfg->refdiv, 1 << cfg->refdiv);
2324 	arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
2325 
2326 	return 0;
2327 }
2328 
arizona_apply_fll(struct arizona * arizona,unsigned int base,struct arizona_fll_cfg * cfg,int source,bool sync)2329 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
2330 			      struct arizona_fll_cfg *cfg, int source,
2331 			      bool sync)
2332 {
2333 	regmap_update_bits_async(arizona->regmap, base + 3,
2334 				 ARIZONA_FLL1_THETA_MASK, cfg->theta);
2335 	regmap_update_bits_async(arizona->regmap, base + 4,
2336 				 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
2337 	regmap_update_bits_async(arizona->regmap, base + 5,
2338 				 ARIZONA_FLL1_FRATIO_MASK,
2339 				 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
2340 	regmap_update_bits_async(arizona->regmap, base + 6,
2341 				 ARIZONA_FLL1_CLK_REF_DIV_MASK |
2342 				 ARIZONA_FLL1_CLK_REF_SRC_MASK,
2343 				 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
2344 				 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
2345 
2346 	if (sync) {
2347 		regmap_update_bits(arizona->regmap, base + 0x7,
2348 				   ARIZONA_FLL1_GAIN_MASK,
2349 				   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2350 	} else {
2351 		regmap_update_bits(arizona->regmap, base + 0x5,
2352 				   ARIZONA_FLL1_OUTDIV_MASK,
2353 				   cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
2354 		regmap_update_bits(arizona->regmap, base + 0x9,
2355 				   ARIZONA_FLL1_GAIN_MASK,
2356 				   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2357 	}
2358 
2359 	regmap_update_bits_async(arizona->regmap, base + 2,
2360 				 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
2361 				 ARIZONA_FLL1_CTRL_UPD | cfg->n);
2362 }
2363 
arizona_is_enabled_fll(struct arizona_fll * fll,int base)2364 static int arizona_is_enabled_fll(struct arizona_fll *fll, int base)
2365 {
2366 	struct arizona *arizona = fll->arizona;
2367 	unsigned int reg;
2368 	int ret;
2369 
2370 	ret = regmap_read(arizona->regmap, base + 1, &reg);
2371 	if (ret != 0) {
2372 		arizona_fll_err(fll, "Failed to read current state: %d\n",
2373 				ret);
2374 		return ret;
2375 	}
2376 
2377 	return reg & ARIZONA_FLL1_ENA;
2378 }
2379 
arizona_set_fll_clks(struct arizona_fll * fll,int base,bool ena)2380 static int arizona_set_fll_clks(struct arizona_fll *fll, int base, bool ena)
2381 {
2382 	struct arizona *arizona = fll->arizona;
2383 	unsigned int val;
2384 	struct clk *clk;
2385 	int ret;
2386 
2387 	ret = regmap_read(arizona->regmap, base + 6, &val);
2388 	if (ret != 0) {
2389 		arizona_fll_err(fll, "Failed to read current source: %d\n",
2390 				ret);
2391 		return ret;
2392 	}
2393 
2394 	val &= ARIZONA_FLL1_CLK_REF_SRC_MASK;
2395 	val >>= ARIZONA_FLL1_CLK_REF_SRC_SHIFT;
2396 
2397 	switch (val) {
2398 	case ARIZONA_FLL_SRC_MCLK1:
2399 		clk = arizona->mclk[ARIZONA_MCLK1];
2400 		break;
2401 	case ARIZONA_FLL_SRC_MCLK2:
2402 		clk = arizona->mclk[ARIZONA_MCLK2];
2403 		break;
2404 	default:
2405 		return 0;
2406 	}
2407 
2408 	if (ena) {
2409 		return clk_prepare_enable(clk);
2410 	} else {
2411 		clk_disable_unprepare(clk);
2412 		return 0;
2413 	}
2414 }
2415 
arizona_enable_fll(struct arizona_fll * fll)2416 static int arizona_enable_fll(struct arizona_fll *fll)
2417 {
2418 	struct arizona *arizona = fll->arizona;
2419 	bool use_sync = false;
2420 	int already_enabled = arizona_is_enabled_fll(fll, fll->base);
2421 	int sync_enabled = arizona_is_enabled_fll(fll, fll->base + 0x10);
2422 	struct arizona_fll_cfg cfg;
2423 	int i;
2424 	unsigned int val;
2425 
2426 	if (already_enabled < 0)
2427 		return already_enabled;
2428 	if (sync_enabled < 0)
2429 		return sync_enabled;
2430 
2431 	if (already_enabled) {
2432 		/* Facilitate smooth refclk across the transition */
2433 		regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2434 				   ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2435 		udelay(32);
2436 		regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2437 					 ARIZONA_FLL1_GAIN_MASK, 0);
2438 
2439 		if (arizona_is_enabled_fll(fll, fll->base + 0x10) > 0)
2440 			arizona_set_fll_clks(fll, fll->base + 0x10, false);
2441 		arizona_set_fll_clks(fll, fll->base, false);
2442 	}
2443 
2444 	/*
2445 	 * If we have both REFCLK and SYNCCLK then enable both,
2446 	 * otherwise apply the SYNCCLK settings to REFCLK.
2447 	 */
2448 	if (fll->ref_src >= 0 && fll->ref_freq &&
2449 	    fll->ref_src != fll->sync_src) {
2450 		arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
2451 
2452 		/* Ref path hardcodes lambda to 65536 when sync is on */
2453 		if (fll->sync_src >= 0 && cfg.lambda)
2454 			cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
2455 
2456 		arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
2457 				  false);
2458 		if (fll->sync_src >= 0) {
2459 			arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
2460 
2461 			arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
2462 					  fll->sync_src, true);
2463 			use_sync = true;
2464 		}
2465 	} else if (fll->sync_src >= 0) {
2466 		arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
2467 
2468 		arizona_apply_fll(arizona, fll->base, &cfg,
2469 				  fll->sync_src, false);
2470 
2471 		regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2472 					 ARIZONA_FLL1_SYNC_ENA, 0);
2473 	} else {
2474 		arizona_fll_err(fll, "No clocks provided\n");
2475 		return -EINVAL;
2476 	}
2477 
2478 	if (already_enabled && !!sync_enabled != use_sync)
2479 		arizona_fll_warn(fll, "Synchroniser changed on active FLL\n");
2480 
2481 	/*
2482 	 * Increase the bandwidth if we're not using a low frequency
2483 	 * sync source.
2484 	 */
2485 	if (use_sync && fll->sync_freq > 100000)
2486 		regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2487 					 ARIZONA_FLL1_SYNC_BW, 0);
2488 	else
2489 		regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2490 					 ARIZONA_FLL1_SYNC_BW,
2491 					 ARIZONA_FLL1_SYNC_BW);
2492 
2493 	if (!already_enabled)
2494 		pm_runtime_get_sync(arizona->dev);
2495 
2496 	if (use_sync) {
2497 		arizona_set_fll_clks(fll, fll->base + 0x10, true);
2498 		regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2499 					 ARIZONA_FLL1_SYNC_ENA,
2500 					 ARIZONA_FLL1_SYNC_ENA);
2501 	}
2502 	arizona_set_fll_clks(fll, fll->base, true);
2503 	regmap_update_bits_async(arizona->regmap, fll->base + 1,
2504 				 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
2505 
2506 	if (already_enabled)
2507 		regmap_update_bits_async(arizona->regmap, fll->base + 1,
2508 					 ARIZONA_FLL1_FREERUN, 0);
2509 
2510 	arizona_fll_dbg(fll, "Waiting for FLL lock...\n");
2511 	val = 0;
2512 	for (i = 0; i < 15; i++) {
2513 		if (i < 5)
2514 			usleep_range(200, 400);
2515 		else
2516 			msleep(20);
2517 
2518 		regmap_read(arizona->regmap,
2519 			    ARIZONA_INTERRUPT_RAW_STATUS_5,
2520 			    &val);
2521 		if (val & (ARIZONA_FLL1_CLOCK_OK_STS << (fll->id - 1)))
2522 			break;
2523 	}
2524 	if (i == 15)
2525 		arizona_fll_warn(fll, "Timed out waiting for lock\n");
2526 	else
2527 		arizona_fll_dbg(fll, "FLL locked (%d polls)\n", i);
2528 
2529 	return 0;
2530 }
2531 
arizona_disable_fll(struct arizona_fll * fll)2532 static void arizona_disable_fll(struct arizona_fll *fll)
2533 {
2534 	struct arizona *arizona = fll->arizona;
2535 	bool ref_change, sync_change;
2536 
2537 	regmap_update_bits_async(arizona->regmap, fll->base + 1,
2538 				 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2539 	regmap_update_bits_check(arizona->regmap, fll->base + 1,
2540 				 ARIZONA_FLL1_ENA, 0, &ref_change);
2541 	regmap_update_bits_check(arizona->regmap, fll->base + 0x11,
2542 				 ARIZONA_FLL1_SYNC_ENA, 0, &sync_change);
2543 	regmap_update_bits_async(arizona->regmap, fll->base + 1,
2544 				 ARIZONA_FLL1_FREERUN, 0);
2545 
2546 	if (sync_change)
2547 		arizona_set_fll_clks(fll, fll->base + 0x10, false);
2548 
2549 	if (ref_change) {
2550 		arizona_set_fll_clks(fll, fll->base, false);
2551 		pm_runtime_put_autosuspend(arizona->dev);
2552 	}
2553 }
2554 
arizona_set_fll_refclk(struct arizona_fll * fll,int source,unsigned int Fref,unsigned int Fout)2555 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
2556 			   unsigned int Fref, unsigned int Fout)
2557 {
2558 	int ret = 0;
2559 
2560 	if (fll->ref_src == source && fll->ref_freq == Fref)
2561 		return 0;
2562 
2563 	if (fll->fout && Fref > 0) {
2564 		ret = arizona_validate_fll(fll, Fref, fll->fout);
2565 		if (ret != 0)
2566 			return ret;
2567 	}
2568 
2569 	fll->ref_src = source;
2570 	fll->ref_freq = Fref;
2571 
2572 	if (fll->fout && Fref > 0)
2573 		ret = arizona_enable_fll(fll);
2574 
2575 	return ret;
2576 }
2577 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
2578 
arizona_set_fll(struct arizona_fll * fll,int source,unsigned int Fref,unsigned int Fout)2579 int arizona_set_fll(struct arizona_fll *fll, int source,
2580 		    unsigned int Fref, unsigned int Fout)
2581 {
2582 	int ret = 0;
2583 
2584 	if (fll->sync_src == source &&
2585 	    fll->sync_freq == Fref && fll->fout == Fout)
2586 		return 0;
2587 
2588 	if (Fout) {
2589 		if (fll->ref_src >= 0) {
2590 			ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
2591 			if (ret != 0)
2592 				return ret;
2593 		}
2594 
2595 		ret = arizona_validate_fll(fll, Fref, Fout);
2596 		if (ret != 0)
2597 			return ret;
2598 	}
2599 
2600 	fll->sync_src = source;
2601 	fll->sync_freq = Fref;
2602 	fll->fout = Fout;
2603 
2604 	if (Fout)
2605 		ret = arizona_enable_fll(fll);
2606 	else
2607 		arizona_disable_fll(fll);
2608 
2609 	return ret;
2610 }
2611 EXPORT_SYMBOL_GPL(arizona_set_fll);
2612 
arizona_init_fll(struct arizona * arizona,int id,int base,int lock_irq,int ok_irq,struct arizona_fll * fll)2613 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
2614 		     int ok_irq, struct arizona_fll *fll)
2615 {
2616 	unsigned int val;
2617 
2618 	fll->id = id;
2619 	fll->base = base;
2620 	fll->arizona = arizona;
2621 	fll->sync_src = ARIZONA_FLL_SRC_NONE;
2622 
2623 	/* Configure default refclk to 32kHz if we have one */
2624 	regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
2625 	switch (val & ARIZONA_CLK_32K_SRC_MASK) {
2626 	case ARIZONA_CLK_SRC_MCLK1:
2627 	case ARIZONA_CLK_SRC_MCLK2:
2628 		fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
2629 		break;
2630 	default:
2631 		fll->ref_src = ARIZONA_FLL_SRC_NONE;
2632 	}
2633 	fll->ref_freq = 32768;
2634 
2635 	snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
2636 	snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
2637 		 "FLL%d clock OK", id);
2638 
2639 	regmap_update_bits(arizona->regmap, fll->base + 1,
2640 			   ARIZONA_FLL1_FREERUN, 0);
2641 
2642 	return 0;
2643 }
2644 EXPORT_SYMBOL_GPL(arizona_init_fll);
2645 
2646 /**
2647  * arizona_set_output_mode - Set the mode of the specified output
2648  *
2649  * @component: Device to configure
2650  * @output: Output number
2651  * @diff: True to set the output to differential mode
2652  *
2653  * Some systems use external analogue switches to connect more
2654  * analogue devices to the CODEC than are supported by the device.  In
2655  * some systems this requires changing the switched output from single
2656  * ended to differential mode dynamically at runtime, an operation
2657  * supported using this function.
2658  *
2659  * Most systems have a single static configuration and should use
2660  * platform data instead.
2661  */
arizona_set_output_mode(struct snd_soc_component * component,int output,bool diff)2662 int arizona_set_output_mode(struct snd_soc_component *component, int output,
2663 			    bool diff)
2664 {
2665 	unsigned int reg, val;
2666 
2667 	if (output < 1 || output > 6)
2668 		return -EINVAL;
2669 
2670 	reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
2671 
2672 	if (diff)
2673 		val = ARIZONA_OUT1_MONO;
2674 	else
2675 		val = 0;
2676 
2677 	return snd_soc_component_update_bits(component, reg,
2678 					     ARIZONA_OUT1_MONO, val);
2679 }
2680 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
2681 
2682 static const struct soc_enum arizona_adsp2_rate_enum[] = {
2683 	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
2684 			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2685 			      ARIZONA_RATE_ENUM_SIZE,
2686 			      arizona_rate_text, arizona_rate_val),
2687 	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
2688 			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2689 			      ARIZONA_RATE_ENUM_SIZE,
2690 			      arizona_rate_text, arizona_rate_val),
2691 	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
2692 			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2693 			      ARIZONA_RATE_ENUM_SIZE,
2694 			      arizona_rate_text, arizona_rate_val),
2695 	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
2696 			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2697 			      ARIZONA_RATE_ENUM_SIZE,
2698 			      arizona_rate_text, arizona_rate_val),
2699 };
2700 
2701 const struct snd_kcontrol_new arizona_adsp2_rate_controls[] = {
2702 	SOC_ENUM("DSP1 Rate", arizona_adsp2_rate_enum[0]),
2703 	SOC_ENUM("DSP2 Rate", arizona_adsp2_rate_enum[1]),
2704 	SOC_ENUM("DSP3 Rate", arizona_adsp2_rate_enum[2]),
2705 	SOC_ENUM("DSP4 Rate", arizona_adsp2_rate_enum[3]),
2706 };
2707 EXPORT_SYMBOL_GPL(arizona_adsp2_rate_controls);
2708 
arizona_eq_filter_unstable(bool mode,__be16 _a,__be16 _b)2709 static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
2710 {
2711 	s16 a = be16_to_cpu(_a);
2712 	s16 b = be16_to_cpu(_b);
2713 
2714 	if (!mode) {
2715 		return abs(a) >= 4096;
2716 	} else {
2717 		if (abs(b) >= 4096)
2718 			return true;
2719 
2720 		return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
2721 	}
2722 }
2723 
arizona_eq_coeff_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2724 int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
2725 			 struct snd_ctl_elem_value *ucontrol)
2726 {
2727 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2728 	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
2729 	struct soc_bytes *params = (void *)kcontrol->private_value;
2730 	unsigned int val;
2731 	__be16 *data;
2732 	int len;
2733 	int ret;
2734 
2735 	len = params->num_regs * regmap_get_val_bytes(arizona->regmap);
2736 
2737 	data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
2738 	if (!data)
2739 		return -ENOMEM;
2740 
2741 	data[0] &= cpu_to_be16(ARIZONA_EQ1_B1_MODE);
2742 
2743 	if (arizona_eq_filter_unstable(!!data[0], data[1], data[2]) ||
2744 	    arizona_eq_filter_unstable(true, data[4], data[5]) ||
2745 	    arizona_eq_filter_unstable(true, data[8], data[9]) ||
2746 	    arizona_eq_filter_unstable(true, data[12], data[13]) ||
2747 	    arizona_eq_filter_unstable(false, data[16], data[17])) {
2748 		dev_err(arizona->dev, "Rejecting unstable EQ coefficients\n");
2749 		ret = -EINVAL;
2750 		goto out;
2751 	}
2752 
2753 	ret = regmap_read(arizona->regmap, params->base, &val);
2754 	if (ret != 0)
2755 		goto out;
2756 
2757 	val &= ~ARIZONA_EQ1_B1_MODE;
2758 	data[0] |= cpu_to_be16(val);
2759 
2760 	ret = regmap_raw_write(arizona->regmap, params->base, data, len);
2761 
2762 out:
2763 	kfree(data);
2764 	return ret;
2765 }
2766 EXPORT_SYMBOL_GPL(arizona_eq_coeff_put);
2767 
arizona_lhpf_coeff_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2768 int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
2769 			   struct snd_ctl_elem_value *ucontrol)
2770 {
2771 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2772 	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
2773 	__be16 *data = (__be16 *)ucontrol->value.bytes.data;
2774 	s16 val = be16_to_cpu(*data);
2775 
2776 	if (abs(val) >= 4096) {
2777 		dev_err(arizona->dev, "Rejecting unstable LHPF coefficients\n");
2778 		return -EINVAL;
2779 	}
2780 
2781 	return snd_soc_bytes_put(kcontrol, ucontrol);
2782 }
2783 EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
2784 
arizona_of_get_audio_pdata(struct arizona * arizona)2785 int arizona_of_get_audio_pdata(struct arizona *arizona)
2786 {
2787 	struct arizona_pdata *pdata = &arizona->pdata;
2788 	struct device_node *np = arizona->dev->of_node;
2789 	struct property *prop;
2790 	const __be32 *cur;
2791 	u32 val;
2792 	u32 pdm_val[ARIZONA_MAX_PDM_SPK];
2793 	int ret;
2794 	int count = 0;
2795 
2796 	count = 0;
2797 	of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) {
2798 		if (count == ARRAY_SIZE(pdata->inmode))
2799 			break;
2800 
2801 		pdata->inmode[count] = val;
2802 		count++;
2803 	}
2804 
2805 	count = 0;
2806 	of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) {
2807 		if (count == ARRAY_SIZE(pdata->dmic_ref))
2808 			break;
2809 
2810 		pdata->dmic_ref[count] = val;
2811 		count++;
2812 	}
2813 
2814 	count = 0;
2815 	of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) {
2816 		if (count == ARRAY_SIZE(pdata->out_mono))
2817 			break;
2818 
2819 		pdata->out_mono[count] = !!val;
2820 		count++;
2821 	}
2822 
2823 	count = 0;
2824 	of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) {
2825 		if (count == ARRAY_SIZE(pdata->max_channels_clocked))
2826 			break;
2827 
2828 		pdata->max_channels_clocked[count] = val;
2829 		count++;
2830 	}
2831 
2832 	count = 0;
2833 	of_property_for_each_u32(np, "wlf,out-volume-limit", prop, cur, val) {
2834 		if (count == ARRAY_SIZE(pdata->out_vol_limit))
2835 			break;
2836 
2837 		pdata->out_vol_limit[count] = val;
2838 		count++;
2839 	}
2840 
2841 	ret = of_property_read_u32_array(np, "wlf,spk-fmt",
2842 					 pdm_val, ARRAY_SIZE(pdm_val));
2843 
2844 	if (ret >= 0)
2845 		for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
2846 			pdata->spk_fmt[count] = pdm_val[count];
2847 
2848 	ret = of_property_read_u32_array(np, "wlf,spk-mute",
2849 					 pdm_val, ARRAY_SIZE(pdm_val));
2850 
2851 	if (ret >= 0)
2852 		for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
2853 			pdata->spk_mute[count] = pdm_val[count];
2854 
2855 	return 0;
2856 }
2857 EXPORT_SYMBOL_GPL(arizona_of_get_audio_pdata);
2858 
2859 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2860 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2861 MODULE_LICENSE("GPL");
2862