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