• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_read32(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_read32(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_read32(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 		default:
1038 			break;
1039 		}
1040 		break;
1041 	case SND_SOC_DAPM_POST_PMD:
1042 		switch (w->shift) {
1043 		case ARIZONA_OUT1L_ENA_SHIFT:
1044 		case ARIZONA_OUT1R_ENA_SHIFT:
1045 		case ARIZONA_OUT2L_ENA_SHIFT:
1046 		case ARIZONA_OUT2R_ENA_SHIFT:
1047 		case ARIZONA_OUT3L_ENA_SHIFT:
1048 		case ARIZONA_OUT3R_ENA_SHIFT:
1049 		case ARIZONA_OUT4L_ENA_SHIFT:
1050 		case ARIZONA_OUT4R_ENA_SHIFT:
1051 			priv->out_down_pending--;
1052 			if (!priv->out_down_pending && priv->out_down_delay) {
1053 				dev_dbg(component->dev, "Power down delay: %d\n",
1054 					priv->out_down_delay);
1055 				msleep(priv->out_down_delay);
1056 				priv->out_down_delay = 0;
1057 			}
1058 			break;
1059 		default:
1060 			break;
1061 		}
1062 		break;
1063 	default:
1064 		break;
1065 	}
1066 
1067 	return 0;
1068 }
1069 EXPORT_SYMBOL_GPL(arizona_out_ev);
1070 
arizona_hp_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1071 int arizona_hp_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
1072 		  int event)
1073 {
1074 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1075 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1076 	struct arizona *arizona = priv->arizona;
1077 	unsigned int mask = 1 << w->shift;
1078 	unsigned int val;
1079 
1080 	switch (event) {
1081 	case SND_SOC_DAPM_POST_PMU:
1082 		val = mask;
1083 		break;
1084 	case SND_SOC_DAPM_PRE_PMD:
1085 		val = 0;
1086 		break;
1087 	case SND_SOC_DAPM_PRE_PMU:
1088 	case SND_SOC_DAPM_POST_PMD:
1089 		return arizona_out_ev(w, kcontrol, event);
1090 	default:
1091 		return -EINVAL;
1092 	}
1093 
1094 	/* Store the desired state for the HP outputs */
1095 	priv->arizona->hp_ena &= ~mask;
1096 	priv->arizona->hp_ena |= val;
1097 
1098 	/* Force off if HPDET clamp is active */
1099 	if (priv->arizona->hpdet_clamp)
1100 		val = 0;
1101 
1102 	regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
1103 				 mask, val);
1104 
1105 	return arizona_out_ev(w, kcontrol, event);
1106 }
1107 EXPORT_SYMBOL_GPL(arizona_hp_ev);
1108 
arizona_dvfs_enable(struct snd_soc_component * component)1109 static int arizona_dvfs_enable(struct snd_soc_component *component)
1110 {
1111 	const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1112 	struct arizona *arizona = priv->arizona;
1113 	int ret;
1114 
1115 	ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
1116 	if (ret) {
1117 		dev_err(component->dev, "Failed to boost DCVDD: %d\n", ret);
1118 		return ret;
1119 	}
1120 
1121 	ret = regmap_update_bits(arizona->regmap,
1122 				 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1123 				 ARIZONA_SUBSYS_MAX_FREQ,
1124 				 ARIZONA_SUBSYS_MAX_FREQ);
1125 	if (ret) {
1126 		dev_err(component->dev, "Failed to enable subsys max: %d\n", ret);
1127 		regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1128 		return ret;
1129 	}
1130 
1131 	return 0;
1132 }
1133 
arizona_dvfs_disable(struct snd_soc_component * component)1134 static int arizona_dvfs_disable(struct snd_soc_component *component)
1135 {
1136 	const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1137 	struct arizona *arizona = priv->arizona;
1138 	int ret;
1139 
1140 	ret = regmap_update_bits(arizona->regmap,
1141 				 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1142 				 ARIZONA_SUBSYS_MAX_FREQ, 0);
1143 	if (ret) {
1144 		dev_err(component->dev, "Failed to disable subsys max: %d\n", ret);
1145 		return ret;
1146 	}
1147 
1148 	ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1149 	if (ret) {
1150 		dev_err(component->dev, "Failed to unboost DCVDD: %d\n", ret);
1151 		return ret;
1152 	}
1153 
1154 	return 0;
1155 }
1156 
arizona_dvfs_up(struct snd_soc_component * component,unsigned int flags)1157 int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags)
1158 {
1159 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1160 	int ret = 0;
1161 
1162 	mutex_lock(&priv->dvfs_lock);
1163 
1164 	if (!priv->dvfs_cached && !priv->dvfs_reqs) {
1165 		ret = arizona_dvfs_enable(component);
1166 		if (ret)
1167 			goto err;
1168 	}
1169 
1170 	priv->dvfs_reqs |= flags;
1171 err:
1172 	mutex_unlock(&priv->dvfs_lock);
1173 	return ret;
1174 }
1175 EXPORT_SYMBOL_GPL(arizona_dvfs_up);
1176 
arizona_dvfs_down(struct snd_soc_component * component,unsigned int flags)1177 int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags)
1178 {
1179 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1180 	unsigned int old_reqs;
1181 	int ret = 0;
1182 
1183 	mutex_lock(&priv->dvfs_lock);
1184 
1185 	old_reqs = priv->dvfs_reqs;
1186 	priv->dvfs_reqs &= ~flags;
1187 
1188 	if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
1189 		ret = arizona_dvfs_disable(component);
1190 
1191 	mutex_unlock(&priv->dvfs_lock);
1192 	return ret;
1193 }
1194 EXPORT_SYMBOL_GPL(arizona_dvfs_down);
1195 
arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1196 int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
1197 			   struct snd_kcontrol *kcontrol, int event)
1198 {
1199 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1200 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1201 	int ret = 0;
1202 
1203 	mutex_lock(&priv->dvfs_lock);
1204 
1205 	switch (event) {
1206 	case SND_SOC_DAPM_POST_PMU:
1207 		if (priv->dvfs_reqs)
1208 			ret = arizona_dvfs_enable(component);
1209 
1210 		priv->dvfs_cached = false;
1211 		break;
1212 	case SND_SOC_DAPM_PRE_PMD:
1213 		/* We must ensure DVFS is disabled before the codec goes into
1214 		 * suspend so that we are never in an illegal state of DVFS
1215 		 * enabled without enough DCVDD
1216 		 */
1217 		priv->dvfs_cached = true;
1218 
1219 		if (priv->dvfs_reqs)
1220 			ret = arizona_dvfs_disable(component);
1221 		break;
1222 	default:
1223 		break;
1224 	}
1225 
1226 	mutex_unlock(&priv->dvfs_lock);
1227 	return ret;
1228 }
1229 EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
1230 
arizona_init_dvfs(struct arizona_priv * priv)1231 void arizona_init_dvfs(struct arizona_priv *priv)
1232 {
1233 	mutex_init(&priv->dvfs_lock);
1234 }
1235 EXPORT_SYMBOL_GPL(arizona_init_dvfs);
1236 
arizona_anc_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1237 int arizona_anc_ev(struct snd_soc_dapm_widget *w,
1238 		   struct snd_kcontrol *kcontrol,
1239 		   int event)
1240 {
1241 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1242 	unsigned int val;
1243 
1244 	switch (event) {
1245 	case SND_SOC_DAPM_POST_PMU:
1246 		val = 1 << w->shift;
1247 		break;
1248 	case SND_SOC_DAPM_PRE_PMD:
1249 		val = 1 << (w->shift + 1);
1250 		break;
1251 	default:
1252 		return 0;
1253 	}
1254 
1255 	snd_soc_component_write(component, ARIZONA_CLOCK_CONTROL, val);
1256 
1257 	return 0;
1258 }
1259 EXPORT_SYMBOL_GPL(arizona_anc_ev);
1260 
1261 static unsigned int arizona_opclk_ref_48k_rates[] = {
1262 	6144000,
1263 	12288000,
1264 	24576000,
1265 	49152000,
1266 };
1267 
1268 static unsigned int arizona_opclk_ref_44k1_rates[] = {
1269 	5644800,
1270 	11289600,
1271 	22579200,
1272 	45158400,
1273 };
1274 
arizona_set_opclk(struct snd_soc_component * component,unsigned int clk,unsigned int freq)1275 static int arizona_set_opclk(struct snd_soc_component *component,
1276 			     unsigned int clk, unsigned int freq)
1277 {
1278 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1279 	unsigned int reg;
1280 	unsigned int *rates;
1281 	int ref, div, refclk;
1282 
1283 	switch (clk) {
1284 	case ARIZONA_CLK_OPCLK:
1285 		reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
1286 		refclk = priv->sysclk;
1287 		break;
1288 	case ARIZONA_CLK_ASYNC_OPCLK:
1289 		reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
1290 		refclk = priv->asyncclk;
1291 		break;
1292 	default:
1293 		return -EINVAL;
1294 	}
1295 
1296 	if (refclk % 8000)
1297 		rates = arizona_opclk_ref_44k1_rates;
1298 	else
1299 		rates = arizona_opclk_ref_48k_rates;
1300 
1301 	for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
1302 	     rates[ref] <= refclk; ref++) {
1303 		div = 1;
1304 		while (rates[ref] / div >= freq && div < 32) {
1305 			if (rates[ref] / div == freq) {
1306 				dev_dbg(component->dev, "Configured %dHz OPCLK\n",
1307 					freq);
1308 				snd_soc_component_update_bits(component, reg,
1309 						    ARIZONA_OPCLK_DIV_MASK |
1310 						    ARIZONA_OPCLK_SEL_MASK,
1311 						    (div <<
1312 						     ARIZONA_OPCLK_DIV_SHIFT) |
1313 						    ref);
1314 				return 0;
1315 			}
1316 			div++;
1317 		}
1318 	}
1319 
1320 	dev_err(component->dev, "Unable to generate %dHz OPCLK\n", freq);
1321 	return -EINVAL;
1322 }
1323 
arizona_clk_ev(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1324 int arizona_clk_ev(struct snd_soc_dapm_widget *w,
1325 		   struct snd_kcontrol *kcontrol, int event)
1326 {
1327 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1328 	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
1329 	unsigned int val;
1330 	int clk_idx;
1331 	int ret;
1332 
1333 	ret = regmap_read(arizona->regmap, w->reg, &val);
1334 	if (ret) {
1335 		dev_err(component->dev, "Failed to check clock source: %d\n", ret);
1336 		return ret;
1337 	}
1338 
1339 	val = (val & ARIZONA_SYSCLK_SRC_MASK) >> ARIZONA_SYSCLK_SRC_SHIFT;
1340 
1341 	switch (val) {
1342 	case ARIZONA_CLK_SRC_MCLK1:
1343 		clk_idx = ARIZONA_MCLK1;
1344 		break;
1345 	case ARIZONA_CLK_SRC_MCLK2:
1346 		clk_idx = ARIZONA_MCLK2;
1347 		break;
1348 	default:
1349 		return 0;
1350 	}
1351 
1352 	switch (event) {
1353 	case SND_SOC_DAPM_PRE_PMU:
1354 		return clk_prepare_enable(arizona->mclk[clk_idx]);
1355 	case SND_SOC_DAPM_POST_PMD:
1356 		clk_disable_unprepare(arizona->mclk[clk_idx]);
1357 		return 0;
1358 	default:
1359 		return 0;
1360 	}
1361 }
1362 EXPORT_SYMBOL_GPL(arizona_clk_ev);
1363 
arizona_set_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)1364 int arizona_set_sysclk(struct snd_soc_component *component, int clk_id,
1365 		       int source, unsigned int freq, int dir)
1366 {
1367 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1368 	struct arizona *arizona = priv->arizona;
1369 	char *name;
1370 	unsigned int reg;
1371 	unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
1372 	unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
1373 	int *clk;
1374 
1375 	switch (clk_id) {
1376 	case ARIZONA_CLK_SYSCLK:
1377 		name = "SYSCLK";
1378 		reg = ARIZONA_SYSTEM_CLOCK_1;
1379 		clk = &priv->sysclk;
1380 		mask |= ARIZONA_SYSCLK_FRAC;
1381 		break;
1382 	case ARIZONA_CLK_ASYNCCLK:
1383 		name = "ASYNCCLK";
1384 		reg = ARIZONA_ASYNC_CLOCK_1;
1385 		clk = &priv->asyncclk;
1386 		break;
1387 	case ARIZONA_CLK_OPCLK:
1388 	case ARIZONA_CLK_ASYNC_OPCLK:
1389 		return arizona_set_opclk(component, clk_id, freq);
1390 	default:
1391 		return -EINVAL;
1392 	}
1393 
1394 	switch (freq) {
1395 	case  5644800:
1396 	case  6144000:
1397 		break;
1398 	case 11289600:
1399 	case 12288000:
1400 		val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1401 		break;
1402 	case 22579200:
1403 	case 24576000:
1404 		val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1405 		break;
1406 	case 45158400:
1407 	case 49152000:
1408 		val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1409 		break;
1410 	case 67737600:
1411 	case 73728000:
1412 		val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1413 		break;
1414 	case 90316800:
1415 	case 98304000:
1416 		val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1417 		break;
1418 	case 135475200:
1419 	case 147456000:
1420 		val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1421 		break;
1422 	case 0:
1423 		dev_dbg(arizona->dev, "%s cleared\n", name);
1424 		*clk = freq;
1425 		return 0;
1426 	default:
1427 		return -EINVAL;
1428 	}
1429 
1430 	*clk = freq;
1431 
1432 	if (freq % 6144000)
1433 		val |= ARIZONA_SYSCLK_FRAC;
1434 
1435 	dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
1436 
1437 	return regmap_update_bits(arizona->regmap, reg, mask, val);
1438 }
1439 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
1440 
arizona_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)1441 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1442 {
1443 	struct snd_soc_component *component = dai->component;
1444 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1445 	struct arizona *arizona = priv->arizona;
1446 	int lrclk, bclk, mode, base;
1447 
1448 	base = dai->driver->base;
1449 
1450 	lrclk = 0;
1451 	bclk = 0;
1452 
1453 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1454 	case SND_SOC_DAIFMT_DSP_A:
1455 		mode = ARIZONA_FMT_DSP_MODE_A;
1456 		break;
1457 	case SND_SOC_DAIFMT_DSP_B:
1458 		if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1459 				!= SND_SOC_DAIFMT_CBM_CFM) {
1460 			arizona_aif_err(dai, "DSP_B not valid in slave mode\n");
1461 			return -EINVAL;
1462 		}
1463 		mode = ARIZONA_FMT_DSP_MODE_B;
1464 		break;
1465 	case SND_SOC_DAIFMT_I2S:
1466 		mode = ARIZONA_FMT_I2S_MODE;
1467 		break;
1468 	case SND_SOC_DAIFMT_LEFT_J:
1469 		if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1470 				!= SND_SOC_DAIFMT_CBM_CFM) {
1471 			arizona_aif_err(dai, "LEFT_J not valid in slave mode\n");
1472 			return -EINVAL;
1473 		}
1474 		mode = ARIZONA_FMT_LEFT_JUSTIFIED_MODE;
1475 		break;
1476 	default:
1477 		arizona_aif_err(dai, "Unsupported DAI format %d\n",
1478 				fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1479 		return -EINVAL;
1480 	}
1481 
1482 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1483 	case SND_SOC_DAIFMT_CBS_CFS:
1484 		break;
1485 	case SND_SOC_DAIFMT_CBS_CFM:
1486 		lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1487 		break;
1488 	case SND_SOC_DAIFMT_CBM_CFS:
1489 		bclk |= ARIZONA_AIF1_BCLK_MSTR;
1490 		break;
1491 	case SND_SOC_DAIFMT_CBM_CFM:
1492 		bclk |= ARIZONA_AIF1_BCLK_MSTR;
1493 		lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1494 		break;
1495 	default:
1496 		arizona_aif_err(dai, "Unsupported master mode %d\n",
1497 				fmt & SND_SOC_DAIFMT_MASTER_MASK);
1498 		return -EINVAL;
1499 	}
1500 
1501 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1502 	case SND_SOC_DAIFMT_NB_NF:
1503 		break;
1504 	case SND_SOC_DAIFMT_IB_IF:
1505 		bclk |= ARIZONA_AIF1_BCLK_INV;
1506 		lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1507 		break;
1508 	case SND_SOC_DAIFMT_IB_NF:
1509 		bclk |= ARIZONA_AIF1_BCLK_INV;
1510 		break;
1511 	case SND_SOC_DAIFMT_NB_IF:
1512 		lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1513 		break;
1514 	default:
1515 		return -EINVAL;
1516 	}
1517 
1518 	regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
1519 				 ARIZONA_AIF1_BCLK_INV |
1520 				 ARIZONA_AIF1_BCLK_MSTR,
1521 				 bclk);
1522 	regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
1523 				 ARIZONA_AIF1TX_LRCLK_INV |
1524 				 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
1525 	regmap_update_bits_async(arizona->regmap,
1526 				 base + ARIZONA_AIF_RX_PIN_CTRL,
1527 				 ARIZONA_AIF1RX_LRCLK_INV |
1528 				 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
1529 	regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
1530 			   ARIZONA_AIF1_FMT_MASK, mode);
1531 
1532 	return 0;
1533 }
1534 
1535 static const int arizona_48k_bclk_rates[] = {
1536 	-1,
1537 	48000,
1538 	64000,
1539 	96000,
1540 	128000,
1541 	192000,
1542 	256000,
1543 	384000,
1544 	512000,
1545 	768000,
1546 	1024000,
1547 	1536000,
1548 	2048000,
1549 	3072000,
1550 	4096000,
1551 	6144000,
1552 	8192000,
1553 	12288000,
1554 	24576000,
1555 };
1556 
1557 static const int arizona_44k1_bclk_rates[] = {
1558 	-1,
1559 	44100,
1560 	58800,
1561 	88200,
1562 	117600,
1563 	177640,
1564 	235200,
1565 	352800,
1566 	470400,
1567 	705600,
1568 	940800,
1569 	1411200,
1570 	1881600,
1571 	2822400,
1572 	3763200,
1573 	5644800,
1574 	7526400,
1575 	11289600,
1576 	22579200,
1577 };
1578 
1579 static const unsigned int arizona_sr_vals[] = {
1580 	0,
1581 	12000,
1582 	24000,
1583 	48000,
1584 	96000,
1585 	192000,
1586 	384000,
1587 	768000,
1588 	0,
1589 	11025,
1590 	22050,
1591 	44100,
1592 	88200,
1593 	176400,
1594 	352800,
1595 	705600,
1596 	4000,
1597 	8000,
1598 	16000,
1599 	32000,
1600 	64000,
1601 	128000,
1602 	256000,
1603 	512000,
1604 };
1605 
1606 #define ARIZONA_48K_RATE_MASK	0x0F003E
1607 #define ARIZONA_44K1_RATE_MASK	0x003E00
1608 #define ARIZONA_RATE_MASK	(ARIZONA_48K_RATE_MASK | ARIZONA_44K1_RATE_MASK)
1609 
1610 static const struct snd_pcm_hw_constraint_list arizona_constraint = {
1611 	.count	= ARRAY_SIZE(arizona_sr_vals),
1612 	.list	= arizona_sr_vals,
1613 };
1614 
arizona_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)1615 static int arizona_startup(struct snd_pcm_substream *substream,
1616 			   struct snd_soc_dai *dai)
1617 {
1618 	struct snd_soc_component *component = dai->component;
1619 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1620 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1621 	unsigned int base_rate;
1622 
1623 	if (!substream->runtime)
1624 		return 0;
1625 
1626 	switch (dai_priv->clk) {
1627 	case ARIZONA_CLK_SYSCLK:
1628 		base_rate = priv->sysclk;
1629 		break;
1630 	case ARIZONA_CLK_ASYNCCLK:
1631 		base_rate = priv->asyncclk;
1632 		break;
1633 	default:
1634 		return 0;
1635 	}
1636 
1637 	if (base_rate == 0)
1638 		dai_priv->constraint.mask = ARIZONA_RATE_MASK;
1639 	else if (base_rate % 8000)
1640 		dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK;
1641 	else
1642 		dai_priv->constraint.mask = ARIZONA_48K_RATE_MASK;
1643 
1644 	return snd_pcm_hw_constraint_list(substream->runtime, 0,
1645 					  SNDRV_PCM_HW_PARAM_RATE,
1646 					  &dai_priv->constraint);
1647 }
1648 
arizona_wm5102_set_dac_comp(struct snd_soc_component * component,unsigned int rate)1649 static void arizona_wm5102_set_dac_comp(struct snd_soc_component *component,
1650 					unsigned int rate)
1651 {
1652 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1653 	struct arizona *arizona = priv->arizona;
1654 	struct reg_sequence dac_comp[] = {
1655 		{ 0x80, 0x3 },
1656 		{ ARIZONA_DAC_COMP_1, 0 },
1657 		{ ARIZONA_DAC_COMP_2, 0 },
1658 		{ 0x80, 0x0 },
1659 	};
1660 
1661 	mutex_lock(&arizona->dac_comp_lock);
1662 
1663 	dac_comp[1].def = arizona->dac_comp_coeff;
1664 	if (rate >= 176400)
1665 		dac_comp[2].def = arizona->dac_comp_enabled;
1666 
1667 	mutex_unlock(&arizona->dac_comp_lock);
1668 
1669 	regmap_multi_reg_write(arizona->regmap,
1670 			       dac_comp,
1671 			       ARRAY_SIZE(dac_comp));
1672 }
1673 
arizona_hw_params_rate(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)1674 static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1675 				  struct snd_pcm_hw_params *params,
1676 				  struct snd_soc_dai *dai)
1677 {
1678 	struct snd_soc_component *component = dai->component;
1679 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1680 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1681 	int base = dai->driver->base;
1682 	int i, sr_val, ret;
1683 
1684 	/*
1685 	 * We will need to be more flexible than this in future,
1686 	 * currently we use a single sample rate for SYSCLK.
1687 	 */
1688 	for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1689 		if (arizona_sr_vals[i] == params_rate(params))
1690 			break;
1691 	if (i == ARRAY_SIZE(arizona_sr_vals)) {
1692 		arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1693 				params_rate(params));
1694 		return -EINVAL;
1695 	}
1696 	sr_val = i;
1697 
1698 	switch (priv->arizona->type) {
1699 	case WM5102:
1700 	case WM8997:
1701 		if (arizona_sr_vals[sr_val] >= 88200)
1702 			ret = arizona_dvfs_up(component, ARIZONA_DVFS_SR1_RQ);
1703 		else
1704 			ret = arizona_dvfs_down(component, ARIZONA_DVFS_SR1_RQ);
1705 
1706 		if (ret) {
1707 			arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
1708 			return ret;
1709 		}
1710 		break;
1711 	default:
1712 		break;
1713 	}
1714 
1715 	switch (dai_priv->clk) {
1716 	case ARIZONA_CLK_SYSCLK:
1717 		switch (priv->arizona->type) {
1718 		case WM5102:
1719 			arizona_wm5102_set_dac_comp(component,
1720 						    params_rate(params));
1721 			break;
1722 		default:
1723 			break;
1724 		}
1725 
1726 		snd_soc_component_update_bits(component, ARIZONA_SAMPLE_RATE_1,
1727 					      ARIZONA_SAMPLE_RATE_1_MASK,
1728 					      sr_val);
1729 		if (base)
1730 			snd_soc_component_update_bits(component,
1731 					base + ARIZONA_AIF_RATE_CTRL,
1732 					ARIZONA_AIF1_RATE_MASK, 0);
1733 		break;
1734 	case ARIZONA_CLK_ASYNCCLK:
1735 		snd_soc_component_update_bits(component,
1736 					      ARIZONA_ASYNC_SAMPLE_RATE_1,
1737 					      ARIZONA_ASYNC_SAMPLE_RATE_1_MASK,
1738 					      sr_val);
1739 		if (base)
1740 			snd_soc_component_update_bits(component,
1741 					base + ARIZONA_AIF_RATE_CTRL,
1742 					ARIZONA_AIF1_RATE_MASK,
1743 					8 << ARIZONA_AIF1_RATE_SHIFT);
1744 		break;
1745 	default:
1746 		arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1747 		return -EINVAL;
1748 	}
1749 
1750 	return 0;
1751 }
1752 
arizona_aif_cfg_changed(struct snd_soc_component * component,int base,int bclk,int lrclk,int frame)1753 static bool arizona_aif_cfg_changed(struct snd_soc_component *component,
1754 				    int base, int bclk, int lrclk, int frame)
1755 {
1756 	int val;
1757 
1758 	val = snd_soc_component_read32(component, base + ARIZONA_AIF_BCLK_CTRL);
1759 	if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
1760 		return true;
1761 
1762 	val = snd_soc_component_read32(component, base + ARIZONA_AIF_TX_BCLK_RATE);
1763 	if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
1764 		return true;
1765 
1766 	val = snd_soc_component_read32(component, base + ARIZONA_AIF_FRAME_CTRL_1);
1767 	if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
1768 			     ARIZONA_AIF1TX_SLOT_LEN_MASK)))
1769 		return true;
1770 
1771 	return false;
1772 }
1773 
arizona_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)1774 static int arizona_hw_params(struct snd_pcm_substream *substream,
1775 			     struct snd_pcm_hw_params *params,
1776 			     struct snd_soc_dai *dai)
1777 {
1778 	struct snd_soc_component *component = dai->component;
1779 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1780 	struct arizona *arizona = priv->arizona;
1781 	int base = dai->driver->base;
1782 	const int *rates;
1783 	int i, ret, val;
1784 	int channels = params_channels(params);
1785 	int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1786 	int tdm_width = arizona->tdm_width[dai->id - 1];
1787 	int tdm_slots = arizona->tdm_slots[dai->id - 1];
1788 	int bclk, lrclk, wl, frame, bclk_target;
1789 	bool reconfig;
1790 	unsigned int aif_tx_state, aif_rx_state;
1791 
1792 	if (params_rate(params) % 4000)
1793 		rates = &arizona_44k1_bclk_rates[0];
1794 	else
1795 		rates = &arizona_48k_bclk_rates[0];
1796 
1797 	wl = params_width(params);
1798 
1799 	if (tdm_slots) {
1800 		arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
1801 				tdm_slots, tdm_width);
1802 		bclk_target = tdm_slots * tdm_width * params_rate(params);
1803 		channels = tdm_slots;
1804 	} else {
1805 		bclk_target = snd_soc_params_to_bclk(params);
1806 		tdm_width = wl;
1807 	}
1808 
1809 	if (chan_limit && chan_limit < channels) {
1810 		arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1811 		bclk_target /= channels;
1812 		bclk_target *= chan_limit;
1813 	}
1814 
1815 	/* Force multiple of 2 channels for I2S mode */
1816 	val = snd_soc_component_read32(component, base + ARIZONA_AIF_FORMAT);
1817 	val &= ARIZONA_AIF1_FMT_MASK;
1818 	if ((channels & 1) && (val == ARIZONA_FMT_I2S_MODE)) {
1819 		arizona_aif_dbg(dai, "Forcing stereo mode\n");
1820 		bclk_target /= channels;
1821 		bclk_target *= channels + 1;
1822 	}
1823 
1824 	for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1825 		if (rates[i] >= bclk_target &&
1826 		    rates[i] % params_rate(params) == 0) {
1827 			bclk = i;
1828 			break;
1829 		}
1830 	}
1831 	if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1832 		arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1833 				params_rate(params));
1834 		return -EINVAL;
1835 	}
1836 
1837 	lrclk = rates[bclk] / params_rate(params);
1838 
1839 	arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1840 			rates[bclk], rates[bclk] / lrclk);
1841 
1842 	frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
1843 
1844 	reconfig = arizona_aif_cfg_changed(component, base, bclk, lrclk, frame);
1845 
1846 	if (reconfig) {
1847 		/* Save AIF TX/RX state */
1848 		aif_tx_state = snd_soc_component_read32(component,
1849 					    base + ARIZONA_AIF_TX_ENABLES);
1850 		aif_rx_state = snd_soc_component_read32(component,
1851 					    base + ARIZONA_AIF_RX_ENABLES);
1852 		/* Disable AIF TX/RX before reconfiguring it */
1853 		regmap_update_bits_async(arizona->regmap,
1854 					 base + ARIZONA_AIF_TX_ENABLES,
1855 					 0xff, 0x0);
1856 		regmap_update_bits(arizona->regmap,
1857 				   base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
1858 	}
1859 
1860 	ret = arizona_hw_params_rate(substream, params, dai);
1861 	if (ret != 0)
1862 		goto restore_aif;
1863 
1864 	if (reconfig) {
1865 		regmap_update_bits_async(arizona->regmap,
1866 					 base + ARIZONA_AIF_BCLK_CTRL,
1867 					 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1868 		regmap_update_bits_async(arizona->regmap,
1869 					 base + ARIZONA_AIF_TX_BCLK_RATE,
1870 					 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1871 		regmap_update_bits_async(arizona->regmap,
1872 					 base + ARIZONA_AIF_RX_BCLK_RATE,
1873 					 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1874 		regmap_update_bits_async(arizona->regmap,
1875 					 base + ARIZONA_AIF_FRAME_CTRL_1,
1876 					 ARIZONA_AIF1TX_WL_MASK |
1877 					 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1878 		regmap_update_bits(arizona->regmap,
1879 				   base + ARIZONA_AIF_FRAME_CTRL_2,
1880 				   ARIZONA_AIF1RX_WL_MASK |
1881 				   ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1882 	}
1883 
1884 restore_aif:
1885 	if (reconfig) {
1886 		/* Restore AIF TX/RX state */
1887 		regmap_update_bits_async(arizona->regmap,
1888 					 base + ARIZONA_AIF_TX_ENABLES,
1889 					 0xff, aif_tx_state);
1890 		regmap_update_bits(arizona->regmap,
1891 				   base + ARIZONA_AIF_RX_ENABLES,
1892 				   0xff, aif_rx_state);
1893 	}
1894 	return ret;
1895 }
1896 
arizona_dai_clk_str(int clk_id)1897 static const char *arizona_dai_clk_str(int clk_id)
1898 {
1899 	switch (clk_id) {
1900 	case ARIZONA_CLK_SYSCLK:
1901 		return "SYSCLK";
1902 	case ARIZONA_CLK_ASYNCCLK:
1903 		return "ASYNCCLK";
1904 	default:
1905 		return "Unknown clock";
1906 	}
1907 }
1908 
arizona_dai_set_sysclk(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)1909 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1910 				  int clk_id, unsigned int freq, int dir)
1911 {
1912 	struct snd_soc_component *component = dai->component;
1913 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1914 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1915 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1916 	struct snd_soc_dapm_route routes[2];
1917 
1918 	switch (clk_id) {
1919 	case ARIZONA_CLK_SYSCLK:
1920 	case ARIZONA_CLK_ASYNCCLK:
1921 		break;
1922 	default:
1923 		return -EINVAL;
1924 	}
1925 
1926 	if (clk_id == dai_priv->clk)
1927 		return 0;
1928 
1929 	if (dai->active) {
1930 		dev_err(component->dev, "Can't change clock on active DAI %d\n",
1931 			dai->id);
1932 		return -EBUSY;
1933 	}
1934 
1935 	dev_dbg(component->dev, "Setting AIF%d to %s\n", dai->id + 1,
1936 		arizona_dai_clk_str(clk_id));
1937 
1938 	memset(&routes, 0, sizeof(routes));
1939 	routes[0].sink = dai->driver->capture.stream_name;
1940 	routes[1].sink = dai->driver->playback.stream_name;
1941 
1942 	routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1943 	routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1944 	snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
1945 
1946 	routes[0].source = arizona_dai_clk_str(clk_id);
1947 	routes[1].source = arizona_dai_clk_str(clk_id);
1948 	snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
1949 
1950 	dai_priv->clk = clk_id;
1951 
1952 	return snd_soc_dapm_sync(dapm);
1953 }
1954 
arizona_set_tristate(struct snd_soc_dai * dai,int tristate)1955 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1956 {
1957 	struct snd_soc_component *component = dai->component;
1958 	int base = dai->driver->base;
1959 	unsigned int reg;
1960 
1961 	if (tristate)
1962 		reg = ARIZONA_AIF1_TRI;
1963 	else
1964 		reg = 0;
1965 
1966 	return snd_soc_component_update_bits(component,
1967 					     base + ARIZONA_AIF_RATE_CTRL,
1968 					     ARIZONA_AIF1_TRI, reg);
1969 }
1970 
arizona_set_channels_to_mask(struct snd_soc_dai * dai,unsigned int base,int channels,unsigned int mask)1971 static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
1972 					 unsigned int base,
1973 					 int channels, unsigned int mask)
1974 {
1975 	struct snd_soc_component *component = dai->component;
1976 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1977 	struct arizona *arizona = priv->arizona;
1978 	int slot, i;
1979 
1980 	for (i = 0; i < channels; ++i) {
1981 		slot = ffs(mask) - 1;
1982 		if (slot < 0)
1983 			return;
1984 
1985 		regmap_write(arizona->regmap, base + i, slot);
1986 
1987 		mask &= ~(1 << slot);
1988 	}
1989 
1990 	if (mask)
1991 		arizona_aif_warn(dai, "Too many channels in TDM mask\n");
1992 }
1993 
arizona_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)1994 static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1995 				unsigned int rx_mask, int slots, int slot_width)
1996 {
1997 	struct snd_soc_component *component = dai->component;
1998 	struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1999 	struct arizona *arizona = priv->arizona;
2000 	int base = dai->driver->base;
2001 	int rx_max_chan = dai->driver->playback.channels_max;
2002 	int tx_max_chan = dai->driver->capture.channels_max;
2003 
2004 	/* Only support TDM for the physical AIFs */
2005 	if (dai->id > ARIZONA_MAX_AIF)
2006 		return -ENOTSUPP;
2007 
2008 	if (slots == 0) {
2009 		tx_mask = (1 << tx_max_chan) - 1;
2010 		rx_mask = (1 << rx_max_chan) - 1;
2011 	}
2012 
2013 	arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3,
2014 				     tx_max_chan, tx_mask);
2015 	arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11,
2016 				     rx_max_chan, rx_mask);
2017 
2018 	arizona->tdm_width[dai->id - 1] = slot_width;
2019 	arizona->tdm_slots[dai->id - 1] = slots;
2020 
2021 	return 0;
2022 }
2023 
2024 const struct snd_soc_dai_ops arizona_dai_ops = {
2025 	.startup = arizona_startup,
2026 	.set_fmt = arizona_set_fmt,
2027 	.set_tdm_slot = arizona_set_tdm_slot,
2028 	.hw_params = arizona_hw_params,
2029 	.set_sysclk = arizona_dai_set_sysclk,
2030 	.set_tristate = arizona_set_tristate,
2031 };
2032 EXPORT_SYMBOL_GPL(arizona_dai_ops);
2033 
2034 const struct snd_soc_dai_ops arizona_simple_dai_ops = {
2035 	.startup = arizona_startup,
2036 	.hw_params = arizona_hw_params_rate,
2037 	.set_sysclk = arizona_dai_set_sysclk,
2038 };
2039 EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
2040 
arizona_init_dai(struct arizona_priv * priv,int id)2041 int arizona_init_dai(struct arizona_priv *priv, int id)
2042 {
2043 	struct arizona_dai_priv *dai_priv = &priv->dai[id];
2044 
2045 	dai_priv->clk = ARIZONA_CLK_SYSCLK;
2046 	dai_priv->constraint = arizona_constraint;
2047 
2048 	return 0;
2049 }
2050 EXPORT_SYMBOL_GPL(arizona_init_dai);
2051 
2052 static struct {
2053 	unsigned int min;
2054 	unsigned int max;
2055 	u16 fratio;
2056 	int ratio;
2057 } fll_fratios[] = {
2058 	{       0,    64000, 4, 16 },
2059 	{   64000,   128000, 3,  8 },
2060 	{  128000,   256000, 2,  4 },
2061 	{  256000,  1000000, 1,  2 },
2062 	{ 1000000, 13500000, 0,  1 },
2063 };
2064 
2065 static const unsigned int pseudo_fref_max[ARIZONA_FLL_MAX_FRATIO] = {
2066 	13500000,
2067 	 6144000,
2068 	 6144000,
2069 	 3072000,
2070 	 3072000,
2071 	 2822400,
2072 	 2822400,
2073 	 1536000,
2074 	 1536000,
2075 	 1536000,
2076 	 1536000,
2077 	 1536000,
2078 	 1536000,
2079 	 1536000,
2080 	 1536000,
2081 	  768000,
2082 };
2083 
2084 static struct {
2085 	unsigned int min;
2086 	unsigned int max;
2087 	u16 gain;
2088 } fll_gains[] = {
2089 	{       0,   256000, 0 },
2090 	{  256000,  1000000, 2 },
2091 	{ 1000000, 13500000, 4 },
2092 };
2093 
2094 struct arizona_fll_cfg {
2095 	int n;
2096 	unsigned int theta;
2097 	unsigned int lambda;
2098 	int refdiv;
2099 	int outdiv;
2100 	int fratio;
2101 	int gain;
2102 };
2103 
arizona_validate_fll(struct arizona_fll * fll,unsigned int Fref,unsigned int Fout)2104 static int arizona_validate_fll(struct arizona_fll *fll,
2105 				unsigned int Fref,
2106 				unsigned int Fout)
2107 {
2108 	unsigned int Fvco_min;
2109 
2110 	if (fll->fout && Fout != fll->fout) {
2111 		arizona_fll_err(fll,
2112 				"Can't change output on active FLL\n");
2113 		return -EINVAL;
2114 	}
2115 
2116 	if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
2117 		arizona_fll_err(fll,
2118 				"Can't scale %dMHz in to <=13.5MHz\n",
2119 				Fref);
2120 		return -EINVAL;
2121 	}
2122 
2123 	Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
2124 	if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
2125 		arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
2126 				Fout);
2127 		return -EINVAL;
2128 	}
2129 
2130 	return 0;
2131 }
2132 
arizona_find_fratio(unsigned int Fref,int * fratio)2133 static int arizona_find_fratio(unsigned int Fref, int *fratio)
2134 {
2135 	int i;
2136 
2137 	/* Find an appropriate FLL_FRATIO */
2138 	for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
2139 		if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
2140 			if (fratio)
2141 				*fratio = fll_fratios[i].fratio;
2142 			return fll_fratios[i].ratio;
2143 		}
2144 	}
2145 
2146 	return -EINVAL;
2147 }
2148 
arizona_calc_fratio(struct arizona_fll * fll,struct arizona_fll_cfg * cfg,unsigned int target,unsigned int Fref,bool sync)2149 static int arizona_calc_fratio(struct arizona_fll *fll,
2150 			       struct arizona_fll_cfg *cfg,
2151 			       unsigned int target,
2152 			       unsigned int Fref, bool sync)
2153 {
2154 	int init_ratio, ratio;
2155 	int refdiv, div;
2156 
2157 	/* Fref must be <=13.5MHz, find initial refdiv */
2158 	div = 1;
2159 	cfg->refdiv = 0;
2160 	while (Fref > ARIZONA_FLL_MAX_FREF) {
2161 		div *= 2;
2162 		Fref /= 2;
2163 		cfg->refdiv++;
2164 
2165 		if (div > ARIZONA_FLL_MAX_REFDIV)
2166 			return -EINVAL;
2167 	}
2168 
2169 	/* Find an appropriate FLL_FRATIO */
2170 	init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
2171 	if (init_ratio < 0) {
2172 		arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
2173 				Fref);
2174 		return init_ratio;
2175 	}
2176 
2177 	switch (fll->arizona->type) {
2178 	case WM5102:
2179 	case WM8997:
2180 		return init_ratio;
2181 	case WM5110:
2182 	case WM8280:
2183 		if (fll->arizona->rev < 3 || sync)
2184 			return init_ratio;
2185 		break;
2186 	default:
2187 		if (sync)
2188 			return init_ratio;
2189 		break;
2190 	}
2191 
2192 	cfg->fratio = init_ratio - 1;
2193 
2194 	/* Adjust FRATIO/refdiv to avoid integer mode if possible */
2195 	refdiv = cfg->refdiv;
2196 
2197 	arizona_fll_dbg(fll, "pseudo: initial ratio=%u fref=%u refdiv=%u\n",
2198 			init_ratio, Fref, refdiv);
2199 
2200 	while (div <= ARIZONA_FLL_MAX_REFDIV) {
2201 		/* start from init_ratio because this may already give a
2202 		 * fractional N.K
2203 		 */
2204 		for (ratio = init_ratio; ratio > 0; ratio--) {
2205 			if (target % (ratio * Fref)) {
2206 				cfg->refdiv = refdiv;
2207 				cfg->fratio = ratio - 1;
2208 				arizona_fll_dbg(fll,
2209 					"pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2210 					Fref, refdiv, div, ratio);
2211 				return ratio;
2212 			}
2213 		}
2214 
2215 		for (ratio = init_ratio + 1; ratio <= ARIZONA_FLL_MAX_FRATIO;
2216 		     ratio++) {
2217 			if ((ARIZONA_FLL_VCO_CORNER / 2) /
2218 			    (fll->vco_mult * ratio) < Fref) {
2219 				arizona_fll_dbg(fll, "pseudo: hit VCO corner\n");
2220 				break;
2221 			}
2222 
2223 			if (Fref > pseudo_fref_max[ratio - 1]) {
2224 				arizona_fll_dbg(fll,
2225 					"pseudo: exceeded max fref(%u) for ratio=%u\n",
2226 					pseudo_fref_max[ratio - 1],
2227 					ratio);
2228 				break;
2229 			}
2230 
2231 			if (target % (ratio * Fref)) {
2232 				cfg->refdiv = refdiv;
2233 				cfg->fratio = ratio - 1;
2234 				arizona_fll_dbg(fll,
2235 					"pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2236 					Fref, refdiv, div, ratio);
2237 				return ratio;
2238 			}
2239 		}
2240 
2241 		div *= 2;
2242 		Fref /= 2;
2243 		refdiv++;
2244 		init_ratio = arizona_find_fratio(Fref, NULL);
2245 		arizona_fll_dbg(fll,
2246 				"pseudo: change fref=%u refdiv=%d(%d) ratio=%u\n",
2247 				Fref, refdiv, div, init_ratio);
2248 	}
2249 
2250 	arizona_fll_warn(fll, "Falling back to integer mode operation\n");
2251 	return cfg->fratio + 1;
2252 }
2253 
arizona_calc_fll(struct arizona_fll * fll,struct arizona_fll_cfg * cfg,unsigned int Fref,bool sync)2254 static int arizona_calc_fll(struct arizona_fll *fll,
2255 			    struct arizona_fll_cfg *cfg,
2256 			    unsigned int Fref, bool sync)
2257 {
2258 	unsigned int target, div, gcd_fll;
2259 	int i, ratio;
2260 
2261 	arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
2262 
2263 	/* Fvco should be over the targt; don't check the upper bound */
2264 	div = ARIZONA_FLL_MIN_OUTDIV;
2265 	while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
2266 		div++;
2267 		if (div > ARIZONA_FLL_MAX_OUTDIV)
2268 			return -EINVAL;
2269 	}
2270 	target = fll->fout * div / fll->vco_mult;
2271 	cfg->outdiv = div;
2272 
2273 	arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
2274 
2275 	/* Find an appropriate FLL_FRATIO and refdiv */
2276 	ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
2277 	if (ratio < 0)
2278 		return ratio;
2279 
2280 	/* Apply the division for our remaining calculations */
2281 	Fref = Fref / (1 << cfg->refdiv);
2282 
2283 	cfg->n = target / (ratio * Fref);
2284 
2285 	if (target % (ratio * Fref)) {
2286 		gcd_fll = gcd(target, ratio * Fref);
2287 		arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
2288 
2289 		cfg->theta = (target - (cfg->n * ratio * Fref))
2290 			/ gcd_fll;
2291 		cfg->lambda = (ratio * Fref) / gcd_fll;
2292 	} else {
2293 		cfg->theta = 0;
2294 		cfg->lambda = 0;
2295 	}
2296 
2297 	/* Round down to 16bit range with cost of accuracy lost.
2298 	 * Denominator must be bigger than numerator so we only
2299 	 * take care of it.
2300 	 */
2301 	while (cfg->lambda >= (1 << 16)) {
2302 		cfg->theta >>= 1;
2303 		cfg->lambda >>= 1;
2304 	}
2305 
2306 	for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
2307 		if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
2308 			cfg->gain = fll_gains[i].gain;
2309 			break;
2310 		}
2311 	}
2312 	if (i == ARRAY_SIZE(fll_gains)) {
2313 		arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
2314 				Fref);
2315 		return -EINVAL;
2316 	}
2317 
2318 	arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
2319 			cfg->n, cfg->theta, cfg->lambda);
2320 	arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n",
2321 			cfg->fratio, ratio, cfg->outdiv,
2322 			cfg->refdiv, 1 << cfg->refdiv);
2323 	arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
2324 
2325 	return 0;
2326 }
2327 
arizona_apply_fll(struct arizona * arizona,unsigned int base,struct arizona_fll_cfg * cfg,int source,bool sync)2328 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
2329 			      struct arizona_fll_cfg *cfg, int source,
2330 			      bool sync)
2331 {
2332 	regmap_update_bits_async(arizona->regmap, base + 3,
2333 				 ARIZONA_FLL1_THETA_MASK, cfg->theta);
2334 	regmap_update_bits_async(arizona->regmap, base + 4,
2335 				 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
2336 	regmap_update_bits_async(arizona->regmap, base + 5,
2337 				 ARIZONA_FLL1_FRATIO_MASK,
2338 				 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
2339 	regmap_update_bits_async(arizona->regmap, base + 6,
2340 				 ARIZONA_FLL1_CLK_REF_DIV_MASK |
2341 				 ARIZONA_FLL1_CLK_REF_SRC_MASK,
2342 				 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
2343 				 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
2344 
2345 	if (sync) {
2346 		regmap_update_bits(arizona->regmap, base + 0x7,
2347 				   ARIZONA_FLL1_GAIN_MASK,
2348 				   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2349 	} else {
2350 		regmap_update_bits(arizona->regmap, base + 0x5,
2351 				   ARIZONA_FLL1_OUTDIV_MASK,
2352 				   cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
2353 		regmap_update_bits(arizona->regmap, base + 0x9,
2354 				   ARIZONA_FLL1_GAIN_MASK,
2355 				   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2356 	}
2357 
2358 	regmap_update_bits_async(arizona->regmap, base + 2,
2359 				 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
2360 				 ARIZONA_FLL1_CTRL_UPD | cfg->n);
2361 }
2362 
arizona_is_enabled_fll(struct arizona_fll * fll,int base)2363 static int arizona_is_enabled_fll(struct arizona_fll *fll, int base)
2364 {
2365 	struct arizona *arizona = fll->arizona;
2366 	unsigned int reg;
2367 	int ret;
2368 
2369 	ret = regmap_read(arizona->regmap, base + 1, &reg);
2370 	if (ret != 0) {
2371 		arizona_fll_err(fll, "Failed to read current state: %d\n",
2372 				ret);
2373 		return ret;
2374 	}
2375 
2376 	return reg & ARIZONA_FLL1_ENA;
2377 }
2378 
arizona_set_fll_clks(struct arizona_fll * fll,int base,bool ena)2379 static int arizona_set_fll_clks(struct arizona_fll *fll, int base, bool ena)
2380 {
2381 	struct arizona *arizona = fll->arizona;
2382 	unsigned int val;
2383 	struct clk *clk;
2384 	int ret;
2385 
2386 	ret = regmap_read(arizona->regmap, base + 6, &val);
2387 	if (ret != 0) {
2388 		arizona_fll_err(fll, "Failed to read current source: %d\n",
2389 				ret);
2390 		return ret;
2391 	}
2392 
2393 	val &= ARIZONA_FLL1_CLK_REF_SRC_MASK;
2394 	val >>= ARIZONA_FLL1_CLK_REF_SRC_SHIFT;
2395 
2396 	switch (val) {
2397 	case ARIZONA_FLL_SRC_MCLK1:
2398 		clk = arizona->mclk[ARIZONA_MCLK1];
2399 		break;
2400 	case ARIZONA_FLL_SRC_MCLK2:
2401 		clk = arizona->mclk[ARIZONA_MCLK2];
2402 		break;
2403 	default:
2404 		return 0;
2405 	}
2406 
2407 	if (ena) {
2408 		return clk_prepare_enable(clk);
2409 	} else {
2410 		clk_disable_unprepare(clk);
2411 		return 0;
2412 	}
2413 }
2414 
arizona_enable_fll(struct arizona_fll * fll)2415 static int arizona_enable_fll(struct arizona_fll *fll)
2416 {
2417 	struct arizona *arizona = fll->arizona;
2418 	bool use_sync = false;
2419 	int already_enabled = arizona_is_enabled_fll(fll, fll->base);
2420 	int sync_enabled = arizona_is_enabled_fll(fll, fll->base + 0x10);
2421 	struct arizona_fll_cfg cfg;
2422 	int i;
2423 	unsigned int val;
2424 
2425 	if (already_enabled < 0)
2426 		return already_enabled;
2427 	if (sync_enabled < 0)
2428 		return sync_enabled;
2429 
2430 	if (already_enabled) {
2431 		/* Facilitate smooth refclk across the transition */
2432 		regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2433 				   ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2434 		udelay(32);
2435 		regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2436 					 ARIZONA_FLL1_GAIN_MASK, 0);
2437 
2438 		if (arizona_is_enabled_fll(fll, fll->base + 0x10) > 0)
2439 			arizona_set_fll_clks(fll, fll->base + 0x10, false);
2440 		arizona_set_fll_clks(fll, fll->base, false);
2441 	}
2442 
2443 	/*
2444 	 * If we have both REFCLK and SYNCCLK then enable both,
2445 	 * otherwise apply the SYNCCLK settings to REFCLK.
2446 	 */
2447 	if (fll->ref_src >= 0 && fll->ref_freq &&
2448 	    fll->ref_src != fll->sync_src) {
2449 		arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
2450 
2451 		/* Ref path hardcodes lambda to 65536 when sync is on */
2452 		if (fll->sync_src >= 0 && cfg.lambda)
2453 			cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
2454 
2455 		arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
2456 				  false);
2457 		if (fll->sync_src >= 0) {
2458 			arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
2459 
2460 			arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
2461 					  fll->sync_src, true);
2462 			use_sync = true;
2463 		}
2464 	} else if (fll->sync_src >= 0) {
2465 		arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
2466 
2467 		arizona_apply_fll(arizona, fll->base, &cfg,
2468 				  fll->sync_src, false);
2469 
2470 		regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2471 					 ARIZONA_FLL1_SYNC_ENA, 0);
2472 	} else {
2473 		arizona_fll_err(fll, "No clocks provided\n");
2474 		return -EINVAL;
2475 	}
2476 
2477 	if (already_enabled && !!sync_enabled != use_sync)
2478 		arizona_fll_warn(fll, "Synchroniser changed on active FLL\n");
2479 
2480 	/*
2481 	 * Increase the bandwidth if we're not using a low frequency
2482 	 * sync source.
2483 	 */
2484 	if (use_sync && fll->sync_freq > 100000)
2485 		regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2486 					 ARIZONA_FLL1_SYNC_BW, 0);
2487 	else
2488 		regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2489 					 ARIZONA_FLL1_SYNC_BW,
2490 					 ARIZONA_FLL1_SYNC_BW);
2491 
2492 	if (!already_enabled)
2493 		pm_runtime_get_sync(arizona->dev);
2494 
2495 	if (use_sync) {
2496 		arizona_set_fll_clks(fll, fll->base + 0x10, true);
2497 		regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2498 					 ARIZONA_FLL1_SYNC_ENA,
2499 					 ARIZONA_FLL1_SYNC_ENA);
2500 	}
2501 	arizona_set_fll_clks(fll, fll->base, true);
2502 	regmap_update_bits_async(arizona->regmap, fll->base + 1,
2503 				 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
2504 
2505 	if (already_enabled)
2506 		regmap_update_bits_async(arizona->regmap, fll->base + 1,
2507 					 ARIZONA_FLL1_FREERUN, 0);
2508 
2509 	arizona_fll_dbg(fll, "Waiting for FLL lock...\n");
2510 	val = 0;
2511 	for (i = 0; i < 15; i++) {
2512 		if (i < 5)
2513 			usleep_range(200, 400);
2514 		else
2515 			msleep(20);
2516 
2517 		regmap_read(arizona->regmap,
2518 			    ARIZONA_INTERRUPT_RAW_STATUS_5,
2519 			    &val);
2520 		if (val & (ARIZONA_FLL1_CLOCK_OK_STS << (fll->id - 1)))
2521 			break;
2522 	}
2523 	if (i == 15)
2524 		arizona_fll_warn(fll, "Timed out waiting for lock\n");
2525 	else
2526 		arizona_fll_dbg(fll, "FLL locked (%d polls)\n", i);
2527 
2528 	return 0;
2529 }
2530 
arizona_disable_fll(struct arizona_fll * fll)2531 static void arizona_disable_fll(struct arizona_fll *fll)
2532 {
2533 	struct arizona *arizona = fll->arizona;
2534 	bool ref_change, sync_change;
2535 
2536 	regmap_update_bits_async(arizona->regmap, fll->base + 1,
2537 				 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2538 	regmap_update_bits_check(arizona->regmap, fll->base + 1,
2539 				 ARIZONA_FLL1_ENA, 0, &ref_change);
2540 	regmap_update_bits_check(arizona->regmap, fll->base + 0x11,
2541 				 ARIZONA_FLL1_SYNC_ENA, 0, &sync_change);
2542 	regmap_update_bits_async(arizona->regmap, fll->base + 1,
2543 				 ARIZONA_FLL1_FREERUN, 0);
2544 
2545 	if (sync_change)
2546 		arizona_set_fll_clks(fll, fll->base + 0x10, false);
2547 
2548 	if (ref_change) {
2549 		arizona_set_fll_clks(fll, fll->base, false);
2550 		pm_runtime_put_autosuspend(arizona->dev);
2551 	}
2552 }
2553 
arizona_set_fll_refclk(struct arizona_fll * fll,int source,unsigned int Fref,unsigned int Fout)2554 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
2555 			   unsigned int Fref, unsigned int Fout)
2556 {
2557 	int ret = 0;
2558 
2559 	if (fll->ref_src == source && fll->ref_freq == Fref)
2560 		return 0;
2561 
2562 	if (fll->fout && Fref > 0) {
2563 		ret = arizona_validate_fll(fll, Fref, fll->fout);
2564 		if (ret != 0)
2565 			return ret;
2566 	}
2567 
2568 	fll->ref_src = source;
2569 	fll->ref_freq = Fref;
2570 
2571 	if (fll->fout && Fref > 0)
2572 		ret = arizona_enable_fll(fll);
2573 
2574 	return ret;
2575 }
2576 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
2577 
arizona_set_fll(struct arizona_fll * fll,int source,unsigned int Fref,unsigned int Fout)2578 int arizona_set_fll(struct arizona_fll *fll, int source,
2579 		    unsigned int Fref, unsigned int Fout)
2580 {
2581 	int ret = 0;
2582 
2583 	if (fll->sync_src == source &&
2584 	    fll->sync_freq == Fref && fll->fout == Fout)
2585 		return 0;
2586 
2587 	if (Fout) {
2588 		if (fll->ref_src >= 0) {
2589 			ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
2590 			if (ret != 0)
2591 				return ret;
2592 		}
2593 
2594 		ret = arizona_validate_fll(fll, Fref, Fout);
2595 		if (ret != 0)
2596 			return ret;
2597 	}
2598 
2599 	fll->sync_src = source;
2600 	fll->sync_freq = Fref;
2601 	fll->fout = Fout;
2602 
2603 	if (Fout)
2604 		ret = arizona_enable_fll(fll);
2605 	else
2606 		arizona_disable_fll(fll);
2607 
2608 	return ret;
2609 }
2610 EXPORT_SYMBOL_GPL(arizona_set_fll);
2611 
arizona_init_fll(struct arizona * arizona,int id,int base,int lock_irq,int ok_irq,struct arizona_fll * fll)2612 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
2613 		     int ok_irq, struct arizona_fll *fll)
2614 {
2615 	unsigned int val;
2616 
2617 	fll->id = id;
2618 	fll->base = base;
2619 	fll->arizona = arizona;
2620 	fll->sync_src = ARIZONA_FLL_SRC_NONE;
2621 
2622 	/* Configure default refclk to 32kHz if we have one */
2623 	regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
2624 	switch (val & ARIZONA_CLK_32K_SRC_MASK) {
2625 	case ARIZONA_CLK_SRC_MCLK1:
2626 	case ARIZONA_CLK_SRC_MCLK2:
2627 		fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
2628 		break;
2629 	default:
2630 		fll->ref_src = ARIZONA_FLL_SRC_NONE;
2631 	}
2632 	fll->ref_freq = 32768;
2633 
2634 	snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
2635 	snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
2636 		 "FLL%d clock OK", id);
2637 
2638 	regmap_update_bits(arizona->regmap, fll->base + 1,
2639 			   ARIZONA_FLL1_FREERUN, 0);
2640 
2641 	return 0;
2642 }
2643 EXPORT_SYMBOL_GPL(arizona_init_fll);
2644 
2645 /**
2646  * arizona_set_output_mode - Set the mode of the specified output
2647  *
2648  * @component: Device to configure
2649  * @output: Output number
2650  * @diff: True to set the output to differential mode
2651  *
2652  * Some systems use external analogue switches to connect more
2653  * analogue devices to the CODEC than are supported by the device.  In
2654  * some systems this requires changing the switched output from single
2655  * ended to differential mode dynamically at runtime, an operation
2656  * supported using this function.
2657  *
2658  * Most systems have a single static configuration and should use
2659  * platform data instead.
2660  */
arizona_set_output_mode(struct snd_soc_component * component,int output,bool diff)2661 int arizona_set_output_mode(struct snd_soc_component *component, int output,
2662 			    bool diff)
2663 {
2664 	unsigned int reg, val;
2665 
2666 	if (output < 1 || output > 6)
2667 		return -EINVAL;
2668 
2669 	reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
2670 
2671 	if (diff)
2672 		val = ARIZONA_OUT1_MONO;
2673 	else
2674 		val = 0;
2675 
2676 	return snd_soc_component_update_bits(component, reg,
2677 					     ARIZONA_OUT1_MONO, val);
2678 }
2679 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
2680 
2681 static const struct soc_enum arizona_adsp2_rate_enum[] = {
2682 	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
2683 			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2684 			      ARIZONA_RATE_ENUM_SIZE,
2685 			      arizona_rate_text, arizona_rate_val),
2686 	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
2687 			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2688 			      ARIZONA_RATE_ENUM_SIZE,
2689 			      arizona_rate_text, arizona_rate_val),
2690 	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
2691 			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2692 			      ARIZONA_RATE_ENUM_SIZE,
2693 			      arizona_rate_text, arizona_rate_val),
2694 	SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
2695 			      ARIZONA_DSP1_RATE_SHIFT, 0xf,
2696 			      ARIZONA_RATE_ENUM_SIZE,
2697 			      arizona_rate_text, arizona_rate_val),
2698 };
2699 
2700 const struct snd_kcontrol_new arizona_adsp2_rate_controls[] = {
2701 	SOC_ENUM("DSP1 Rate", arizona_adsp2_rate_enum[0]),
2702 	SOC_ENUM("DSP2 Rate", arizona_adsp2_rate_enum[1]),
2703 	SOC_ENUM("DSP3 Rate", arizona_adsp2_rate_enum[2]),
2704 	SOC_ENUM("DSP4 Rate", arizona_adsp2_rate_enum[3]),
2705 };
2706 EXPORT_SYMBOL_GPL(arizona_adsp2_rate_controls);
2707 
arizona_eq_filter_unstable(bool mode,__be16 _a,__be16 _b)2708 static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
2709 {
2710 	s16 a = be16_to_cpu(_a);
2711 	s16 b = be16_to_cpu(_b);
2712 
2713 	if (!mode) {
2714 		return abs(a) >= 4096;
2715 	} else {
2716 		if (abs(b) >= 4096)
2717 			return true;
2718 
2719 		return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
2720 	}
2721 }
2722 
arizona_eq_coeff_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2723 int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
2724 			 struct snd_ctl_elem_value *ucontrol)
2725 {
2726 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2727 	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
2728 	struct soc_bytes *params = (void *)kcontrol->private_value;
2729 	unsigned int val;
2730 	__be16 *data;
2731 	int len;
2732 	int ret;
2733 
2734 	len = params->num_regs * regmap_get_val_bytes(arizona->regmap);
2735 
2736 	data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
2737 	if (!data)
2738 		return -ENOMEM;
2739 
2740 	data[0] &= cpu_to_be16(ARIZONA_EQ1_B1_MODE);
2741 
2742 	if (arizona_eq_filter_unstable(!!data[0], data[1], data[2]) ||
2743 	    arizona_eq_filter_unstable(true, data[4], data[5]) ||
2744 	    arizona_eq_filter_unstable(true, data[8], data[9]) ||
2745 	    arizona_eq_filter_unstable(true, data[12], data[13]) ||
2746 	    arizona_eq_filter_unstable(false, data[16], data[17])) {
2747 		dev_err(arizona->dev, "Rejecting unstable EQ coefficients\n");
2748 		ret = -EINVAL;
2749 		goto out;
2750 	}
2751 
2752 	ret = regmap_read(arizona->regmap, params->base, &val);
2753 	if (ret != 0)
2754 		goto out;
2755 
2756 	val &= ~ARIZONA_EQ1_B1_MODE;
2757 	data[0] |= cpu_to_be16(val);
2758 
2759 	ret = regmap_raw_write(arizona->regmap, params->base, data, len);
2760 
2761 out:
2762 	kfree(data);
2763 	return ret;
2764 }
2765 EXPORT_SYMBOL_GPL(arizona_eq_coeff_put);
2766 
arizona_lhpf_coeff_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2767 int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
2768 			   struct snd_ctl_elem_value *ucontrol)
2769 {
2770 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2771 	struct arizona *arizona = dev_get_drvdata(component->dev->parent);
2772 	__be16 *data = (__be16 *)ucontrol->value.bytes.data;
2773 	s16 val = be16_to_cpu(*data);
2774 
2775 	if (abs(val) >= 4096) {
2776 		dev_err(arizona->dev, "Rejecting unstable LHPF coefficients\n");
2777 		return -EINVAL;
2778 	}
2779 
2780 	return snd_soc_bytes_put(kcontrol, ucontrol);
2781 }
2782 EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
2783 
arizona_of_get_audio_pdata(struct arizona * arizona)2784 int arizona_of_get_audio_pdata(struct arizona *arizona)
2785 {
2786 	struct arizona_pdata *pdata = &arizona->pdata;
2787 	struct device_node *np = arizona->dev->of_node;
2788 	struct property *prop;
2789 	const __be32 *cur;
2790 	u32 val;
2791 	u32 pdm_val[ARIZONA_MAX_PDM_SPK];
2792 	int ret;
2793 	int count = 0;
2794 
2795 	count = 0;
2796 	of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) {
2797 		if (count == ARRAY_SIZE(pdata->inmode))
2798 			break;
2799 
2800 		pdata->inmode[count] = val;
2801 		count++;
2802 	}
2803 
2804 	count = 0;
2805 	of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) {
2806 		if (count == ARRAY_SIZE(pdata->dmic_ref))
2807 			break;
2808 
2809 		pdata->dmic_ref[count] = val;
2810 		count++;
2811 	}
2812 
2813 	count = 0;
2814 	of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) {
2815 		if (count == ARRAY_SIZE(pdata->out_mono))
2816 			break;
2817 
2818 		pdata->out_mono[count] = !!val;
2819 		count++;
2820 	}
2821 
2822 	count = 0;
2823 	of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) {
2824 		if (count == ARRAY_SIZE(pdata->max_channels_clocked))
2825 			break;
2826 
2827 		pdata->max_channels_clocked[count] = val;
2828 		count++;
2829 	}
2830 
2831 	count = 0;
2832 	of_property_for_each_u32(np, "wlf,out-volume-limit", prop, cur, val) {
2833 		if (count == ARRAY_SIZE(pdata->out_vol_limit))
2834 			break;
2835 
2836 		pdata->out_vol_limit[count] = val;
2837 		count++;
2838 	}
2839 
2840 	ret = of_property_read_u32_array(np, "wlf,spk-fmt",
2841 					 pdm_val, ARRAY_SIZE(pdm_val));
2842 
2843 	if (ret >= 0)
2844 		for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
2845 			pdata->spk_fmt[count] = pdm_val[count];
2846 
2847 	ret = of_property_read_u32_array(np, "wlf,spk-mute",
2848 					 pdm_val, ARRAY_SIZE(pdm_val));
2849 
2850 	if (ret >= 0)
2851 		for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
2852 			pdata->spk_mute[count] = pdm_val[count];
2853 
2854 	return 0;
2855 }
2856 EXPORT_SYMBOL_GPL(arizona_of_get_audio_pdata);
2857 
2858 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2859 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2860 MODULE_LICENSE("GPL");
2861