xref: /openbmc/linux/sound/soc/codecs/arizona.c (revision 5bd8e16d)
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/gpio.h>
23 #include <linux/mfd/arizona/registers.h>
24 
25 #include "arizona.h"
26 
27 #define ARIZONA_AIF_BCLK_CTRL                   0x00
28 #define ARIZONA_AIF_TX_PIN_CTRL                 0x01
29 #define ARIZONA_AIF_RX_PIN_CTRL                 0x02
30 #define ARIZONA_AIF_RATE_CTRL                   0x03
31 #define ARIZONA_AIF_FORMAT                      0x04
32 #define ARIZONA_AIF_TX_BCLK_RATE                0x05
33 #define ARIZONA_AIF_RX_BCLK_RATE                0x06
34 #define ARIZONA_AIF_FRAME_CTRL_1                0x07
35 #define ARIZONA_AIF_FRAME_CTRL_2                0x08
36 #define ARIZONA_AIF_FRAME_CTRL_3                0x09
37 #define ARIZONA_AIF_FRAME_CTRL_4                0x0A
38 #define ARIZONA_AIF_FRAME_CTRL_5                0x0B
39 #define ARIZONA_AIF_FRAME_CTRL_6                0x0C
40 #define ARIZONA_AIF_FRAME_CTRL_7                0x0D
41 #define ARIZONA_AIF_FRAME_CTRL_8                0x0E
42 #define ARIZONA_AIF_FRAME_CTRL_9                0x0F
43 #define ARIZONA_AIF_FRAME_CTRL_10               0x10
44 #define ARIZONA_AIF_FRAME_CTRL_11               0x11
45 #define ARIZONA_AIF_FRAME_CTRL_12               0x12
46 #define ARIZONA_AIF_FRAME_CTRL_13               0x13
47 #define ARIZONA_AIF_FRAME_CTRL_14               0x14
48 #define ARIZONA_AIF_FRAME_CTRL_15               0x15
49 #define ARIZONA_AIF_FRAME_CTRL_16               0x16
50 #define ARIZONA_AIF_FRAME_CTRL_17               0x17
51 #define ARIZONA_AIF_FRAME_CTRL_18               0x18
52 #define ARIZONA_AIF_TX_ENABLES                  0x19
53 #define ARIZONA_AIF_RX_ENABLES                  0x1A
54 #define ARIZONA_AIF_FORCE_WRITE                 0x1B
55 
56 #define arizona_fll_err(_fll, fmt, ...) \
57 	dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
58 #define arizona_fll_warn(_fll, fmt, ...) \
59 	dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
60 #define arizona_fll_dbg(_fll, fmt, ...) \
61 	dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
62 
63 #define arizona_aif_err(_dai, fmt, ...) \
64 	dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
65 #define arizona_aif_warn(_dai, fmt, ...) \
66 	dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
67 #define arizona_aif_dbg(_dai, fmt, ...) \
68 	dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
69 
70 static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
71 			  struct snd_kcontrol *kcontrol,
72 			  int event)
73 {
74 	struct snd_soc_codec *codec = w->codec;
75 	struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
76 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
77 	bool manual_ena = false;
78 	int val;
79 
80 	switch (arizona->type) {
81 	case WM5102:
82 		switch (arizona->rev) {
83 		case 0:
84 			break;
85 		default:
86 			manual_ena = true;
87 			break;
88 		}
89 	default:
90 		break;
91 	}
92 
93 	switch (event) {
94 	case SND_SOC_DAPM_PRE_PMU:
95 		if (!priv->spk_ena && manual_ena) {
96 			snd_soc_write(codec, 0x4f5, 0x25a);
97 			priv->spk_ena_pending = true;
98 		}
99 		break;
100 	case SND_SOC_DAPM_POST_PMU:
101 		val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
102 		if (val & ARIZONA_SPK_SHUTDOWN_STS) {
103 			dev_crit(arizona->dev,
104 				 "Speaker not enabled due to temperature\n");
105 			return -EBUSY;
106 		}
107 
108 		snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
109 				    1 << w->shift, 1 << w->shift);
110 
111 		if (priv->spk_ena_pending) {
112 			msleep(75);
113 			snd_soc_write(codec, 0x4f5, 0xda);
114 			priv->spk_ena_pending = false;
115 			priv->spk_ena++;
116 		}
117 		break;
118 	case SND_SOC_DAPM_PRE_PMD:
119 		if (manual_ena) {
120 			priv->spk_ena--;
121 			if (!priv->spk_ena)
122 				snd_soc_write(codec, 0x4f5, 0x25a);
123 		}
124 
125 		snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
126 				    1 << w->shift, 0);
127 		break;
128 	case SND_SOC_DAPM_POST_PMD:
129 		if (manual_ena) {
130 			if (!priv->spk_ena)
131 				snd_soc_write(codec, 0x4f5, 0x0da);
132 		}
133 		break;
134 	}
135 
136 	return 0;
137 }
138 
139 static irqreturn_t arizona_thermal_warn(int irq, void *data)
140 {
141 	struct arizona *arizona = data;
142 	unsigned int val;
143 	int ret;
144 
145 	ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
146 			  &val);
147 	if (ret != 0) {
148 		dev_err(arizona->dev, "Failed to read thermal status: %d\n",
149 			ret);
150 	} else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) {
151 		dev_crit(arizona->dev, "Thermal warning\n");
152 	}
153 
154 	return IRQ_HANDLED;
155 }
156 
157 static irqreturn_t arizona_thermal_shutdown(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_SHUTDOWN_STS) {
169 		dev_crit(arizona->dev, "Thermal shutdown\n");
170 		ret = regmap_update_bits(arizona->regmap,
171 					 ARIZONA_OUTPUT_ENABLES_1,
172 					 ARIZONA_OUT4L_ENA |
173 					 ARIZONA_OUT4R_ENA, 0);
174 		if (ret != 0)
175 			dev_crit(arizona->dev,
176 				 "Failed to disable speaker outputs: %d\n",
177 				 ret);
178 	}
179 
180 	return IRQ_HANDLED;
181 }
182 
183 static const struct snd_soc_dapm_widget arizona_spkl =
184 	SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
185 			   ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
186 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
187 
188 static const struct snd_soc_dapm_widget arizona_spkr =
189 	SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
190 			   ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
191 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
192 
193 int arizona_init_spk(struct snd_soc_codec *codec)
194 {
195 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
196 	struct arizona *arizona = priv->arizona;
197 	int ret;
198 
199 	ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1);
200 	if (ret != 0)
201 		return ret;
202 
203 	switch (arizona->type) {
204 	case WM8997:
205 		break;
206 	default:
207 		ret = snd_soc_dapm_new_controls(&codec->dapm,
208 						&arizona_spkr, 1);
209 		if (ret != 0)
210 			return ret;
211 		break;
212 	}
213 
214 	ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN,
215 				  "Thermal warning", arizona_thermal_warn,
216 				  arizona);
217 	if (ret != 0)
218 		dev_err(arizona->dev,
219 			"Failed to get thermal warning IRQ: %d\n",
220 			ret);
221 
222 	ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN,
223 				  "Thermal shutdown", arizona_thermal_shutdown,
224 				  arizona);
225 	if (ret != 0)
226 		dev_err(arizona->dev,
227 			"Failed to get thermal shutdown IRQ: %d\n",
228 			ret);
229 
230 	return 0;
231 }
232 EXPORT_SYMBOL_GPL(arizona_init_spk);
233 
234 int arizona_init_gpio(struct snd_soc_codec *codec)
235 {
236 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
237 	struct arizona *arizona = priv->arizona;
238 	int i;
239 
240 	switch (arizona->type) {
241 	case WM5110:
242 		snd_soc_dapm_disable_pin(&codec->dapm, "DRC2 Signal Activity");
243 		break;
244 	default:
245 		break;
246 	}
247 
248 	snd_soc_dapm_disable_pin(&codec->dapm, "DRC1 Signal Activity");
249 
250 	for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
251 		switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
252 		case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
253 			snd_soc_dapm_enable_pin(&codec->dapm,
254 						"DRC1 Signal Activity");
255 			break;
256 		case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
257 			snd_soc_dapm_enable_pin(&codec->dapm,
258 						"DRC2 Signal Activity");
259 			break;
260 		default:
261 			break;
262 		}
263 	}
264 
265 	return 0;
266 }
267 EXPORT_SYMBOL_GPL(arizona_init_gpio);
268 
269 const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
270 	"None",
271 	"Tone Generator 1",
272 	"Tone Generator 2",
273 	"Haptics",
274 	"AEC",
275 	"Mic Mute Mixer",
276 	"Noise Generator",
277 	"IN1L",
278 	"IN1R",
279 	"IN2L",
280 	"IN2R",
281 	"IN3L",
282 	"IN3R",
283 	"IN4L",
284 	"IN4R",
285 	"AIF1RX1",
286 	"AIF1RX2",
287 	"AIF1RX3",
288 	"AIF1RX4",
289 	"AIF1RX5",
290 	"AIF1RX6",
291 	"AIF1RX7",
292 	"AIF1RX8",
293 	"AIF2RX1",
294 	"AIF2RX2",
295 	"AIF3RX1",
296 	"AIF3RX2",
297 	"SLIMRX1",
298 	"SLIMRX2",
299 	"SLIMRX3",
300 	"SLIMRX4",
301 	"SLIMRX5",
302 	"SLIMRX6",
303 	"SLIMRX7",
304 	"SLIMRX8",
305 	"EQ1",
306 	"EQ2",
307 	"EQ3",
308 	"EQ4",
309 	"DRC1L",
310 	"DRC1R",
311 	"DRC2L",
312 	"DRC2R",
313 	"LHPF1",
314 	"LHPF2",
315 	"LHPF3",
316 	"LHPF4",
317 	"DSP1.1",
318 	"DSP1.2",
319 	"DSP1.3",
320 	"DSP1.4",
321 	"DSP1.5",
322 	"DSP1.6",
323 	"DSP2.1",
324 	"DSP2.2",
325 	"DSP2.3",
326 	"DSP2.4",
327 	"DSP2.5",
328 	"DSP2.6",
329 	"DSP3.1",
330 	"DSP3.2",
331 	"DSP3.3",
332 	"DSP3.4",
333 	"DSP3.5",
334 	"DSP3.6",
335 	"DSP4.1",
336 	"DSP4.2",
337 	"DSP4.3",
338 	"DSP4.4",
339 	"DSP4.5",
340 	"DSP4.6",
341 	"ASRC1L",
342 	"ASRC1R",
343 	"ASRC2L",
344 	"ASRC2R",
345 	"ISRC1INT1",
346 	"ISRC1INT2",
347 	"ISRC1INT3",
348 	"ISRC1INT4",
349 	"ISRC1DEC1",
350 	"ISRC1DEC2",
351 	"ISRC1DEC3",
352 	"ISRC1DEC4",
353 	"ISRC2INT1",
354 	"ISRC2INT2",
355 	"ISRC2INT3",
356 	"ISRC2INT4",
357 	"ISRC2DEC1",
358 	"ISRC2DEC2",
359 	"ISRC2DEC3",
360 	"ISRC2DEC4",
361 	"ISRC3INT1",
362 	"ISRC3INT2",
363 	"ISRC3INT3",
364 	"ISRC3INT4",
365 	"ISRC3DEC1",
366 	"ISRC3DEC2",
367 	"ISRC3DEC3",
368 	"ISRC3DEC4",
369 };
370 EXPORT_SYMBOL_GPL(arizona_mixer_texts);
371 
372 int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
373 	0x00,  /* None */
374 	0x04,  /* Tone */
375 	0x05,
376 	0x06,  /* Haptics */
377 	0x08,  /* AEC */
378 	0x0c,  /* Noise mixer */
379 	0x0d,  /* Comfort noise */
380 	0x10,  /* IN1L */
381 	0x11,
382 	0x12,
383 	0x13,
384 	0x14,
385 	0x15,
386 	0x16,
387 	0x17,
388 	0x20,  /* AIF1RX1 */
389 	0x21,
390 	0x22,
391 	0x23,
392 	0x24,
393 	0x25,
394 	0x26,
395 	0x27,
396 	0x28,  /* AIF2RX1 */
397 	0x29,
398 	0x30,  /* AIF3RX1 */
399 	0x31,
400 	0x38,  /* SLIMRX1 */
401 	0x39,
402 	0x3a,
403 	0x3b,
404 	0x3c,
405 	0x3d,
406 	0x3e,
407 	0x3f,
408 	0x50,  /* EQ1 */
409 	0x51,
410 	0x52,
411 	0x53,
412 	0x58,  /* DRC1L */
413 	0x59,
414 	0x5a,
415 	0x5b,
416 	0x60,  /* LHPF1 */
417 	0x61,
418 	0x62,
419 	0x63,
420 	0x68,  /* DSP1.1 */
421 	0x69,
422 	0x6a,
423 	0x6b,
424 	0x6c,
425 	0x6d,
426 	0x70,  /* DSP2.1 */
427 	0x71,
428 	0x72,
429 	0x73,
430 	0x74,
431 	0x75,
432 	0x78,  /* DSP3.1 */
433 	0x79,
434 	0x7a,
435 	0x7b,
436 	0x7c,
437 	0x7d,
438 	0x80,  /* DSP4.1 */
439 	0x81,
440 	0x82,
441 	0x83,
442 	0x84,
443 	0x85,
444 	0x90,  /* ASRC1L */
445 	0x91,
446 	0x92,
447 	0x93,
448 	0xa0,  /* ISRC1INT1 */
449 	0xa1,
450 	0xa2,
451 	0xa3,
452 	0xa4,  /* ISRC1DEC1 */
453 	0xa5,
454 	0xa6,
455 	0xa7,
456 	0xa8,  /* ISRC2DEC1 */
457 	0xa9,
458 	0xaa,
459 	0xab,
460 	0xac,  /* ISRC2INT1 */
461 	0xad,
462 	0xae,
463 	0xaf,
464 	0xb0,  /* ISRC3DEC1 */
465 	0xb1,
466 	0xb2,
467 	0xb3,
468 	0xb4,  /* ISRC3INT1 */
469 	0xb5,
470 	0xb6,
471 	0xb7,
472 };
473 EXPORT_SYMBOL_GPL(arizona_mixer_values);
474 
475 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
476 EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
477 
478 const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
479 	"SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
480 };
481 EXPORT_SYMBOL_GPL(arizona_rate_text);
482 
483 const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
484 	0, 1, 2, 8,
485 };
486 EXPORT_SYMBOL_GPL(arizona_rate_val);
487 
488 
489 const struct soc_enum arizona_isrc_fsl[] = {
490 	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
491 			      ARIZONA_ISRC1_FSL_SHIFT, 0xf,
492 			      ARIZONA_RATE_ENUM_SIZE,
493 			      arizona_rate_text, arizona_rate_val),
494 	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
495 			      ARIZONA_ISRC2_FSL_SHIFT, 0xf,
496 			      ARIZONA_RATE_ENUM_SIZE,
497 			      arizona_rate_text, arizona_rate_val),
498 	SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
499 			      ARIZONA_ISRC3_FSL_SHIFT, 0xf,
500 			      ARIZONA_RATE_ENUM_SIZE,
501 			      arizona_rate_text, arizona_rate_val),
502 };
503 EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
504 
505 static const char *arizona_vol_ramp_text[] = {
506 	"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
507 	"15ms/6dB", "30ms/6dB",
508 };
509 
510 const struct soc_enum arizona_in_vd_ramp =
511 	SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
512 			ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
513 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
514 
515 const struct soc_enum arizona_in_vi_ramp =
516 	SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
517 			ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
518 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
519 
520 const struct soc_enum arizona_out_vd_ramp =
521 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
522 			ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
523 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
524 
525 const struct soc_enum arizona_out_vi_ramp =
526 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
527 			ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
528 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
529 
530 static const char *arizona_lhpf_mode_text[] = {
531 	"Low-pass", "High-pass"
532 };
533 
534 const struct soc_enum arizona_lhpf1_mode =
535 	SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
536 			arizona_lhpf_mode_text);
537 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
538 
539 const struct soc_enum arizona_lhpf2_mode =
540 	SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
541 			arizona_lhpf_mode_text);
542 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
543 
544 const struct soc_enum arizona_lhpf3_mode =
545 	SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
546 			arizona_lhpf_mode_text);
547 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
548 
549 const struct soc_enum arizona_lhpf4_mode =
550 	SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
551 			arizona_lhpf_mode_text);
552 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
553 
554 static const char *arizona_ng_hold_text[] = {
555 	"30ms", "120ms", "250ms", "500ms",
556 };
557 
558 const struct soc_enum arizona_ng_hold =
559 	SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT,
560 			4, arizona_ng_hold_text);
561 EXPORT_SYMBOL_GPL(arizona_ng_hold);
562 
563 static const char * const arizona_in_dmic_osr_text[] = {
564 	"1.536MHz", "3.072MHz", "6.144MHz",
565 };
566 
567 const struct soc_enum arizona_in_dmic_osr[] = {
568 	SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
569 			ARRAY_SIZE(arizona_in_dmic_osr_text),
570 			arizona_in_dmic_osr_text),
571 	SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
572 			ARRAY_SIZE(arizona_in_dmic_osr_text),
573 			arizona_in_dmic_osr_text),
574 	SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
575 			ARRAY_SIZE(arizona_in_dmic_osr_text),
576 			arizona_in_dmic_osr_text),
577 	SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
578 			ARRAY_SIZE(arizona_in_dmic_osr_text),
579 			arizona_in_dmic_osr_text),
580 };
581 EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
582 
583 static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
584 {
585 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
586 	unsigned int val;
587 	int i;
588 
589 	if (ena)
590 		val = ARIZONA_IN_VU;
591 	else
592 		val = 0;
593 
594 	for (i = 0; i < priv->num_inputs; i++)
595 		snd_soc_update_bits(codec,
596 				    ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
597 				    ARIZONA_IN_VU, val);
598 }
599 
600 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
601 		  int event)
602 {
603 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
604 	unsigned int reg;
605 
606 	if (w->shift % 2)
607 		reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
608 	else
609 		reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
610 
611 	switch (event) {
612 	case SND_SOC_DAPM_PRE_PMU:
613 		priv->in_pending++;
614 		break;
615 	case SND_SOC_DAPM_POST_PMU:
616 		snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
617 
618 		/* If this is the last input pending then allow VU */
619 		priv->in_pending--;
620 		if (priv->in_pending == 0) {
621 			msleep(1);
622 			arizona_in_set_vu(w->codec, 1);
623 		}
624 		break;
625 	case SND_SOC_DAPM_PRE_PMD:
626 		snd_soc_update_bits(w->codec, reg,
627 				    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
628 				    ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
629 		break;
630 	case SND_SOC_DAPM_POST_PMD:
631 		/* Disable volume updates if no inputs are enabled */
632 		reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
633 		if (reg == 0)
634 			arizona_in_set_vu(w->codec, 0);
635 	}
636 
637 	return 0;
638 }
639 EXPORT_SYMBOL_GPL(arizona_in_ev);
640 
641 int arizona_out_ev(struct snd_soc_dapm_widget *w,
642 		   struct snd_kcontrol *kcontrol,
643 		   int event)
644 {
645 	switch (event) {
646 	case SND_SOC_DAPM_POST_PMU:
647 		switch (w->shift) {
648 		case ARIZONA_OUT1L_ENA_SHIFT:
649 		case ARIZONA_OUT1R_ENA_SHIFT:
650 		case ARIZONA_OUT2L_ENA_SHIFT:
651 		case ARIZONA_OUT2R_ENA_SHIFT:
652 		case ARIZONA_OUT3L_ENA_SHIFT:
653 		case ARIZONA_OUT3R_ENA_SHIFT:
654 			msleep(17);
655 			break;
656 
657 		default:
658 			break;
659 		}
660 		break;
661 	}
662 
663 	return 0;
664 }
665 EXPORT_SYMBOL_GPL(arizona_out_ev);
666 
667 int arizona_hp_ev(struct snd_soc_dapm_widget *w,
668 		   struct snd_kcontrol *kcontrol,
669 		   int event)
670 {
671 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
672 	unsigned int mask = 1 << w->shift;
673 	unsigned int val;
674 
675 	switch (event) {
676 	case SND_SOC_DAPM_POST_PMU:
677 		val = mask;
678 		break;
679 	case SND_SOC_DAPM_PRE_PMD:
680 		val = 0;
681 		break;
682 	default:
683 		return -EINVAL;
684 	}
685 
686 	/* Store the desired state for the HP outputs */
687 	priv->arizona->hp_ena &= ~mask;
688 	priv->arizona->hp_ena |= val;
689 
690 	/* Force off if HPDET magic is active */
691 	if (priv->arizona->hpdet_magic)
692 		val = 0;
693 
694 	snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val);
695 
696 	return arizona_out_ev(w, kcontrol, event);
697 }
698 EXPORT_SYMBOL_GPL(arizona_hp_ev);
699 
700 static unsigned int arizona_sysclk_48k_rates[] = {
701 	6144000,
702 	12288000,
703 	24576000,
704 	49152000,
705 	73728000,
706 	98304000,
707 	147456000,
708 };
709 
710 static unsigned int arizona_sysclk_44k1_rates[] = {
711 	5644800,
712 	11289600,
713 	22579200,
714 	45158400,
715 	67737600,
716 	90316800,
717 	135475200,
718 };
719 
720 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
721 			     unsigned int freq)
722 {
723 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
724 	unsigned int reg;
725 	unsigned int *rates;
726 	int ref, div, refclk;
727 
728 	switch (clk) {
729 	case ARIZONA_CLK_OPCLK:
730 		reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
731 		refclk = priv->sysclk;
732 		break;
733 	case ARIZONA_CLK_ASYNC_OPCLK:
734 		reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
735 		refclk = priv->asyncclk;
736 		break;
737 	default:
738 		return -EINVAL;
739 	}
740 
741 	if (refclk % 8000)
742 		rates = arizona_sysclk_44k1_rates;
743 	else
744 		rates = arizona_sysclk_48k_rates;
745 
746 	for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
747 		     rates[ref] <= refclk; ref++) {
748 		div = 1;
749 		while (rates[ref] / div >= freq && div < 32) {
750 			if (rates[ref] / div == freq) {
751 				dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
752 					freq);
753 				snd_soc_update_bits(codec, reg,
754 						    ARIZONA_OPCLK_DIV_MASK |
755 						    ARIZONA_OPCLK_SEL_MASK,
756 						    (div <<
757 						     ARIZONA_OPCLK_DIV_SHIFT) |
758 						    ref);
759 				return 0;
760 			}
761 			div++;
762 		}
763 	}
764 
765 	dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
766 	return -EINVAL;
767 }
768 
769 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
770 		       int source, unsigned int freq, int dir)
771 {
772 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
773 	struct arizona *arizona = priv->arizona;
774 	char *name;
775 	unsigned int reg;
776 	unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
777 	unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
778 	unsigned int *clk;
779 
780 	switch (clk_id) {
781 	case ARIZONA_CLK_SYSCLK:
782 		name = "SYSCLK";
783 		reg = ARIZONA_SYSTEM_CLOCK_1;
784 		clk = &priv->sysclk;
785 		mask |= ARIZONA_SYSCLK_FRAC;
786 		break;
787 	case ARIZONA_CLK_ASYNCCLK:
788 		name = "ASYNCCLK";
789 		reg = ARIZONA_ASYNC_CLOCK_1;
790 		clk = &priv->asyncclk;
791 		break;
792 	case ARIZONA_CLK_OPCLK:
793 	case ARIZONA_CLK_ASYNC_OPCLK:
794 		return arizona_set_opclk(codec, clk_id, freq);
795 	default:
796 		return -EINVAL;
797 	}
798 
799 	switch (freq) {
800 	case  5644800:
801 	case  6144000:
802 		break;
803 	case 11289600:
804 	case 12288000:
805 		val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
806 		break;
807 	case 22579200:
808 	case 24576000:
809 		val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
810 		break;
811 	case 45158400:
812 	case 49152000:
813 		val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
814 		break;
815 	case 67737600:
816 	case 73728000:
817 		val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
818 		break;
819 	case 90316800:
820 	case 98304000:
821 		val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
822 		break;
823 	case 135475200:
824 	case 147456000:
825 		val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
826 		break;
827 	case 0:
828 		dev_dbg(arizona->dev, "%s cleared\n", name);
829 		*clk = freq;
830 		return 0;
831 	default:
832 		return -EINVAL;
833 	}
834 
835 	*clk = freq;
836 
837 	if (freq % 6144000)
838 		val |= ARIZONA_SYSCLK_FRAC;
839 
840 	dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
841 
842 	return regmap_update_bits(arizona->regmap, reg, mask, val);
843 }
844 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
845 
846 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
847 {
848 	struct snd_soc_codec *codec = dai->codec;
849 	int lrclk, bclk, mode, base;
850 
851 	base = dai->driver->base;
852 
853 	lrclk = 0;
854 	bclk = 0;
855 
856 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
857 	case SND_SOC_DAIFMT_DSP_A:
858 		mode = 0;
859 		break;
860 	case SND_SOC_DAIFMT_I2S:
861 		mode = 2;
862 		break;
863 	default:
864 		arizona_aif_err(dai, "Unsupported DAI format %d\n",
865 				fmt & SND_SOC_DAIFMT_FORMAT_MASK);
866 		return -EINVAL;
867 	}
868 
869 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
870 	case SND_SOC_DAIFMT_CBS_CFS:
871 		break;
872 	case SND_SOC_DAIFMT_CBS_CFM:
873 		lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
874 		break;
875 	case SND_SOC_DAIFMT_CBM_CFS:
876 		bclk |= ARIZONA_AIF1_BCLK_MSTR;
877 		break;
878 	case SND_SOC_DAIFMT_CBM_CFM:
879 		bclk |= ARIZONA_AIF1_BCLK_MSTR;
880 		lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
881 		break;
882 	default:
883 		arizona_aif_err(dai, "Unsupported master mode %d\n",
884 				fmt & SND_SOC_DAIFMT_MASTER_MASK);
885 		return -EINVAL;
886 	}
887 
888 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
889 	case SND_SOC_DAIFMT_NB_NF:
890 		break;
891 	case SND_SOC_DAIFMT_IB_IF:
892 		bclk |= ARIZONA_AIF1_BCLK_INV;
893 		lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
894 		break;
895 	case SND_SOC_DAIFMT_IB_NF:
896 		bclk |= ARIZONA_AIF1_BCLK_INV;
897 		break;
898 	case SND_SOC_DAIFMT_NB_IF:
899 		lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
900 		break;
901 	default:
902 		return -EINVAL;
903 	}
904 
905 	snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
906 			    ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
907 			    bclk);
908 	snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
909 			    ARIZONA_AIF1TX_LRCLK_INV |
910 			    ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
911 	snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
912 			    ARIZONA_AIF1RX_LRCLK_INV |
913 			    ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
914 	snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
915 			    ARIZONA_AIF1_FMT_MASK, mode);
916 
917 	return 0;
918 }
919 
920 static const int arizona_48k_bclk_rates[] = {
921 	-1,
922 	48000,
923 	64000,
924 	96000,
925 	128000,
926 	192000,
927 	256000,
928 	384000,
929 	512000,
930 	768000,
931 	1024000,
932 	1536000,
933 	2048000,
934 	3072000,
935 	4096000,
936 	6144000,
937 	8192000,
938 	12288000,
939 	24576000,
940 };
941 
942 static const unsigned int arizona_48k_rates[] = {
943 	12000,
944 	24000,
945 	48000,
946 	96000,
947 	192000,
948 	384000,
949 	768000,
950 	4000,
951 	8000,
952 	16000,
953 	32000,
954 	64000,
955 	128000,
956 	256000,
957 	512000,
958 };
959 
960 static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
961 	.count	= ARRAY_SIZE(arizona_48k_rates),
962 	.list	= arizona_48k_rates,
963 };
964 
965 static const int arizona_44k1_bclk_rates[] = {
966 	-1,
967 	44100,
968 	58800,
969 	88200,
970 	117600,
971 	177640,
972 	235200,
973 	352800,
974 	470400,
975 	705600,
976 	940800,
977 	1411200,
978 	1881600,
979 	2822400,
980 	3763200,
981 	5644800,
982 	7526400,
983 	11289600,
984 	22579200,
985 };
986 
987 static const unsigned int arizona_44k1_rates[] = {
988 	11025,
989 	22050,
990 	44100,
991 	88200,
992 	176400,
993 	352800,
994 	705600,
995 };
996 
997 static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
998 	.count	= ARRAY_SIZE(arizona_44k1_rates),
999 	.list	= arizona_44k1_rates,
1000 };
1001 
1002 static int arizona_sr_vals[] = {
1003 	0,
1004 	12000,
1005 	24000,
1006 	48000,
1007 	96000,
1008 	192000,
1009 	384000,
1010 	768000,
1011 	0,
1012 	11025,
1013 	22050,
1014 	44100,
1015 	88200,
1016 	176400,
1017 	352800,
1018 	705600,
1019 	4000,
1020 	8000,
1021 	16000,
1022 	32000,
1023 	64000,
1024 	128000,
1025 	256000,
1026 	512000,
1027 };
1028 
1029 static int arizona_startup(struct snd_pcm_substream *substream,
1030 			   struct snd_soc_dai *dai)
1031 {
1032 	struct snd_soc_codec *codec = dai->codec;
1033 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1034 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1035 	const struct snd_pcm_hw_constraint_list *constraint;
1036 	unsigned int base_rate;
1037 
1038 	switch (dai_priv->clk) {
1039 	case ARIZONA_CLK_SYSCLK:
1040 		base_rate = priv->sysclk;
1041 		break;
1042 	case ARIZONA_CLK_ASYNCCLK:
1043 		base_rate = priv->asyncclk;
1044 		break;
1045 	default:
1046 		return 0;
1047 	}
1048 
1049 	if (base_rate == 0)
1050 		return 0;
1051 
1052 	if (base_rate % 8000)
1053 		constraint = &arizona_44k1_constraint;
1054 	else
1055 		constraint = &arizona_48k_constraint;
1056 
1057 	return snd_pcm_hw_constraint_list(substream->runtime, 0,
1058 					  SNDRV_PCM_HW_PARAM_RATE,
1059 					  constraint);
1060 }
1061 
1062 static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1063 				  struct snd_pcm_hw_params *params,
1064 				  struct snd_soc_dai *dai)
1065 {
1066 	struct snd_soc_codec *codec = dai->codec;
1067 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1068 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1069 	int base = dai->driver->base;
1070 	int i, sr_val;
1071 
1072 	/*
1073 	 * We will need to be more flexible than this in future,
1074 	 * currently we use a single sample rate for SYSCLK.
1075 	 */
1076 	for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1077 		if (arizona_sr_vals[i] == params_rate(params))
1078 			break;
1079 	if (i == ARRAY_SIZE(arizona_sr_vals)) {
1080 		arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1081 				params_rate(params));
1082 		return -EINVAL;
1083 	}
1084 	sr_val = i;
1085 
1086 	switch (dai_priv->clk) {
1087 	case ARIZONA_CLK_SYSCLK:
1088 		snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
1089 				    ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
1090 		if (base)
1091 			snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1092 					    ARIZONA_AIF1_RATE_MASK, 0);
1093 		break;
1094 	case ARIZONA_CLK_ASYNCCLK:
1095 		snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
1096 				    ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
1097 		if (base)
1098 			snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1099 					    ARIZONA_AIF1_RATE_MASK,
1100 					    8 << ARIZONA_AIF1_RATE_SHIFT);
1101 		break;
1102 	default:
1103 		arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1104 		return -EINVAL;
1105 	}
1106 
1107 	return 0;
1108 }
1109 
1110 static int arizona_hw_params(struct snd_pcm_substream *substream,
1111 			     struct snd_pcm_hw_params *params,
1112 			     struct snd_soc_dai *dai)
1113 {
1114 	struct snd_soc_codec *codec = dai->codec;
1115 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1116 	struct arizona *arizona = priv->arizona;
1117 	int base = dai->driver->base;
1118 	const int *rates;
1119 	int i, ret, val;
1120 	int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1121 	int bclk, lrclk, wl, frame, bclk_target;
1122 
1123 	if (params_rate(params) % 8000)
1124 		rates = &arizona_44k1_bclk_rates[0];
1125 	else
1126 		rates = &arizona_48k_bclk_rates[0];
1127 
1128 	bclk_target = snd_soc_params_to_bclk(params);
1129 	if (chan_limit && chan_limit < params_channels(params)) {
1130 		arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1131 		bclk_target /= params_channels(params);
1132 		bclk_target *= chan_limit;
1133 	}
1134 
1135 	/* Force stereo for I2S mode */
1136 	val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1137 	if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) {
1138 		arizona_aif_dbg(dai, "Forcing stereo mode\n");
1139 		bclk_target *= 2;
1140 	}
1141 
1142 	for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1143 		if (rates[i] >= bclk_target &&
1144 		    rates[i] % params_rate(params) == 0) {
1145 			bclk = i;
1146 			break;
1147 		}
1148 	}
1149 	if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1150 		arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1151 				params_rate(params));
1152 		return -EINVAL;
1153 	}
1154 
1155 	lrclk = rates[bclk] / params_rate(params);
1156 
1157 	arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1158 			rates[bclk], rates[bclk] / lrclk);
1159 
1160 	wl = snd_pcm_format_width(params_format(params));
1161 	frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
1162 
1163 	ret = arizona_hw_params_rate(substream, params, dai);
1164 	if (ret != 0)
1165 		return ret;
1166 
1167 	snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
1168 			    ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1169 	snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
1170 			    ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1171 	snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
1172 			    ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1173 	snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
1174 			    ARIZONA_AIF1TX_WL_MASK |
1175 			    ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1176 	snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
1177 			    ARIZONA_AIF1RX_WL_MASK |
1178 			    ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1179 
1180 	return 0;
1181 }
1182 
1183 static const char *arizona_dai_clk_str(int clk_id)
1184 {
1185 	switch (clk_id) {
1186 	case ARIZONA_CLK_SYSCLK:
1187 		return "SYSCLK";
1188 	case ARIZONA_CLK_ASYNCCLK:
1189 		return "ASYNCCLK";
1190 	default:
1191 		return "Unknown clock";
1192 	}
1193 }
1194 
1195 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1196 				  int clk_id, unsigned int freq, int dir)
1197 {
1198 	struct snd_soc_codec *codec = dai->codec;
1199 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1200 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1201 	struct snd_soc_dapm_route routes[2];
1202 
1203 	switch (clk_id) {
1204 	case ARIZONA_CLK_SYSCLK:
1205 	case ARIZONA_CLK_ASYNCCLK:
1206 		break;
1207 	default:
1208 		return -EINVAL;
1209 	}
1210 
1211 	if (clk_id == dai_priv->clk)
1212 		return 0;
1213 
1214 	if (dai->active) {
1215 		dev_err(codec->dev, "Can't change clock on active DAI %d\n",
1216 			dai->id);
1217 		return -EBUSY;
1218 	}
1219 
1220 	dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
1221 		arizona_dai_clk_str(clk_id));
1222 
1223 	memset(&routes, 0, sizeof(routes));
1224 	routes[0].sink = dai->driver->capture.stream_name;
1225 	routes[1].sink = dai->driver->playback.stream_name;
1226 
1227 	routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1228 	routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1229 	snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1230 
1231 	routes[0].source = arizona_dai_clk_str(clk_id);
1232 	routes[1].source = arizona_dai_clk_str(clk_id);
1233 	snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1234 
1235 	dai_priv->clk = clk_id;
1236 
1237 	return snd_soc_dapm_sync(&codec->dapm);
1238 }
1239 
1240 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1241 {
1242 	struct snd_soc_codec *codec = dai->codec;
1243 	int base = dai->driver->base;
1244 	unsigned int reg;
1245 
1246 	if (tristate)
1247 		reg = ARIZONA_AIF1_TRI;
1248 	else
1249 		reg = 0;
1250 
1251 	return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1252 				   ARIZONA_AIF1_TRI, reg);
1253 }
1254 
1255 const struct snd_soc_dai_ops arizona_dai_ops = {
1256 	.startup = arizona_startup,
1257 	.set_fmt = arizona_set_fmt,
1258 	.hw_params = arizona_hw_params,
1259 	.set_sysclk = arizona_dai_set_sysclk,
1260 	.set_tristate = arizona_set_tristate,
1261 };
1262 EXPORT_SYMBOL_GPL(arizona_dai_ops);
1263 
1264 const struct snd_soc_dai_ops arizona_simple_dai_ops = {
1265 	.startup = arizona_startup,
1266 	.hw_params = arizona_hw_params_rate,
1267 	.set_sysclk = arizona_dai_set_sysclk,
1268 };
1269 EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
1270 
1271 int arizona_init_dai(struct arizona_priv *priv, int id)
1272 {
1273 	struct arizona_dai_priv *dai_priv = &priv->dai[id];
1274 
1275 	dai_priv->clk = ARIZONA_CLK_SYSCLK;
1276 
1277 	return 0;
1278 }
1279 EXPORT_SYMBOL_GPL(arizona_init_dai);
1280 
1281 static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
1282 {
1283 	struct arizona_fll *fll = data;
1284 
1285 	arizona_fll_dbg(fll, "clock OK\n");
1286 
1287 	complete(&fll->ok);
1288 
1289 	return IRQ_HANDLED;
1290 }
1291 
1292 static struct {
1293 	unsigned int min;
1294 	unsigned int max;
1295 	u16 fratio;
1296 	int ratio;
1297 } fll_fratios[] = {
1298 	{       0,    64000, 4, 16 },
1299 	{   64000,   128000, 3,  8 },
1300 	{  128000,   256000, 2,  4 },
1301 	{  256000,  1000000, 1,  2 },
1302 	{ 1000000, 13500000, 0,  1 },
1303 };
1304 
1305 static struct {
1306 	unsigned int min;
1307 	unsigned int max;
1308 	u16 gain;
1309 } fll_gains[] = {
1310 	{       0,   256000, 0 },
1311 	{  256000,  1000000, 2 },
1312 	{ 1000000, 13500000, 4 },
1313 };
1314 
1315 struct arizona_fll_cfg {
1316 	int n;
1317 	int theta;
1318 	int lambda;
1319 	int refdiv;
1320 	int outdiv;
1321 	int fratio;
1322 	int gain;
1323 };
1324 
1325 static int arizona_calc_fll(struct arizona_fll *fll,
1326 			    struct arizona_fll_cfg *cfg,
1327 			    unsigned int Fref,
1328 			    unsigned int Fout)
1329 {
1330 	unsigned int target, div, gcd_fll;
1331 	int i, ratio;
1332 
1333 	arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
1334 
1335 	/* Fref must be <=13.5MHz */
1336 	div = 1;
1337 	cfg->refdiv = 0;
1338 	while ((Fref / div) > 13500000) {
1339 		div *= 2;
1340 		cfg->refdiv++;
1341 
1342 		if (div > 8) {
1343 			arizona_fll_err(fll,
1344 					"Can't scale %dMHz in to <=13.5MHz\n",
1345 					Fref);
1346 			return -EINVAL;
1347 		}
1348 	}
1349 
1350 	/* Apply the division for our remaining calculations */
1351 	Fref /= div;
1352 
1353 	/* Fvco should be over the targt; don't check the upper bound */
1354 	div = 1;
1355 	while (Fout * div < 90000000 * fll->vco_mult) {
1356 		div++;
1357 		if (div > 7) {
1358 			arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1359 					Fout);
1360 			return -EINVAL;
1361 		}
1362 	}
1363 	target = Fout * div / fll->vco_mult;
1364 	cfg->outdiv = div;
1365 
1366 	arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
1367 
1368 	/* Find an appropraite FLL_FRATIO and factor it out of the target */
1369 	for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1370 		if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1371 			cfg->fratio = fll_fratios[i].fratio;
1372 			ratio = fll_fratios[i].ratio;
1373 			break;
1374 		}
1375 	}
1376 	if (i == ARRAY_SIZE(fll_fratios)) {
1377 		arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1378 				Fref);
1379 		return -EINVAL;
1380 	}
1381 
1382 	for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1383 		if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1384 			cfg->gain = fll_gains[i].gain;
1385 			break;
1386 		}
1387 	}
1388 	if (i == ARRAY_SIZE(fll_gains)) {
1389 		arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1390 				Fref);
1391 		return -EINVAL;
1392 	}
1393 
1394 	cfg->n = target / (ratio * Fref);
1395 
1396 	if (target % (ratio * Fref)) {
1397 		gcd_fll = gcd(target, ratio * Fref);
1398 		arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
1399 
1400 		cfg->theta = (target - (cfg->n * ratio * Fref))
1401 			/ gcd_fll;
1402 		cfg->lambda = (ratio * Fref) / gcd_fll;
1403 	} else {
1404 		cfg->theta = 0;
1405 		cfg->lambda = 0;
1406 	}
1407 
1408 	/* Round down to 16bit range with cost of accuracy lost.
1409 	 * Denominator must be bigger than numerator so we only
1410 	 * take care of it.
1411 	 */
1412 	while (cfg->lambda >= (1 << 16)) {
1413 		cfg->theta >>= 1;
1414 		cfg->lambda >>= 1;
1415 	}
1416 
1417 	arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
1418 			cfg->n, cfg->theta, cfg->lambda);
1419 	arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1420 			cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
1421 	arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
1422 
1423 	return 0;
1424 
1425 }
1426 
1427 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1428 			      struct arizona_fll_cfg *cfg, int source,
1429 			      bool sync)
1430 {
1431 	regmap_update_bits(arizona->regmap, base + 3,
1432 			   ARIZONA_FLL1_THETA_MASK, cfg->theta);
1433 	regmap_update_bits(arizona->regmap, base + 4,
1434 			   ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
1435 	regmap_update_bits(arizona->regmap, base + 5,
1436 			   ARIZONA_FLL1_FRATIO_MASK,
1437 			   cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
1438 	regmap_update_bits(arizona->regmap, base + 6,
1439 			   ARIZONA_FLL1_CLK_REF_DIV_MASK |
1440 			   ARIZONA_FLL1_CLK_REF_SRC_MASK,
1441 			   cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1442 			   source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1443 
1444 	if (sync)
1445 		regmap_update_bits(arizona->regmap, base + 0x7,
1446 				   ARIZONA_FLL1_GAIN_MASK,
1447 				   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1448 	else
1449 		regmap_update_bits(arizona->regmap, base + 0x9,
1450 				   ARIZONA_FLL1_GAIN_MASK,
1451 				   cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1452 
1453 	regmap_update_bits(arizona->regmap, base + 2,
1454 			   ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1455 			   ARIZONA_FLL1_CTRL_UPD | cfg->n);
1456 }
1457 
1458 static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1459 {
1460 	struct arizona *arizona = fll->arizona;
1461 	unsigned int reg;
1462 	int ret;
1463 
1464 	ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1465 	if (ret != 0) {
1466 		arizona_fll_err(fll, "Failed to read current state: %d\n",
1467 				ret);
1468 		return ret;
1469 	}
1470 
1471 	return reg & ARIZONA_FLL1_ENA;
1472 }
1473 
1474 static void arizona_enable_fll(struct arizona_fll *fll,
1475 			      struct arizona_fll_cfg *ref,
1476 			      struct arizona_fll_cfg *sync)
1477 {
1478 	struct arizona *arizona = fll->arizona;
1479 	int ret;
1480 
1481 	/*
1482 	 * If we have both REFCLK and SYNCCLK then enable both,
1483 	 * otherwise apply the SYNCCLK settings to REFCLK.
1484 	 */
1485 	if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) {
1486 		regmap_update_bits(arizona->regmap, fll->base + 5,
1487 				   ARIZONA_FLL1_OUTDIV_MASK,
1488 				   ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1489 
1490 		arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
1491 				  false);
1492 		if (fll->sync_src >= 0)
1493 			arizona_apply_fll(arizona, fll->base + 0x10, sync,
1494 					  fll->sync_src, true);
1495 	} else if (fll->sync_src >= 0) {
1496 		regmap_update_bits(arizona->regmap, fll->base + 5,
1497 				   ARIZONA_FLL1_OUTDIV_MASK,
1498 				   sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1499 
1500 		arizona_apply_fll(arizona, fll->base, sync,
1501 				  fll->sync_src, false);
1502 
1503 		regmap_update_bits(arizona->regmap, fll->base + 0x11,
1504 				   ARIZONA_FLL1_SYNC_ENA, 0);
1505 	} else {
1506 		arizona_fll_err(fll, "No clocks provided\n");
1507 		return;
1508 	}
1509 
1510 	/*
1511 	 * Increase the bandwidth if we're not using a low frequency
1512 	 * sync source.
1513 	 */
1514 	if (fll->sync_src >= 0 && fll->sync_freq > 100000)
1515 		regmap_update_bits(arizona->regmap, fll->base + 0x17,
1516 				   ARIZONA_FLL1_SYNC_BW, 0);
1517 	else
1518 		regmap_update_bits(arizona->regmap, fll->base + 0x17,
1519 				   ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW);
1520 
1521 	if (!arizona_is_enabled_fll(fll))
1522 		pm_runtime_get(arizona->dev);
1523 
1524 	/* Clear any pending completions */
1525 	try_wait_for_completion(&fll->ok);
1526 
1527 	regmap_update_bits(arizona->regmap, fll->base + 1,
1528 			   ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1529 	if (fll->ref_src >= 0 && fll->sync_src >= 0 &&
1530 	    fll->ref_src != fll->sync_src)
1531 		regmap_update_bits(arizona->regmap, fll->base + 0x11,
1532 				   ARIZONA_FLL1_SYNC_ENA,
1533 				   ARIZONA_FLL1_SYNC_ENA);
1534 
1535 	ret = wait_for_completion_timeout(&fll->ok,
1536 					  msecs_to_jiffies(250));
1537 	if (ret == 0)
1538 		arizona_fll_warn(fll, "Timed out waiting for lock\n");
1539 }
1540 
1541 static void arizona_disable_fll(struct arizona_fll *fll)
1542 {
1543 	struct arizona *arizona = fll->arizona;
1544 	bool change;
1545 
1546 	regmap_update_bits_check(arizona->regmap, fll->base + 1,
1547 				 ARIZONA_FLL1_ENA, 0, &change);
1548 	regmap_update_bits(arizona->regmap, fll->base + 0x11,
1549 			   ARIZONA_FLL1_SYNC_ENA, 0);
1550 
1551 	if (change)
1552 		pm_runtime_put_autosuspend(arizona->dev);
1553 }
1554 
1555 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1556 			   unsigned int Fref, unsigned int Fout)
1557 {
1558 	struct arizona_fll_cfg ref, sync;
1559 	int ret;
1560 
1561 	if (fll->ref_src == source && fll->ref_freq == Fref)
1562 		return 0;
1563 
1564 	if (fll->fout && Fref > 0) {
1565 		ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
1566 		if (ret != 0)
1567 			return ret;
1568 
1569 		if (fll->sync_src >= 0) {
1570 			ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
1571 					       fll->fout);
1572 			if (ret != 0)
1573 				return ret;
1574 		}
1575 	}
1576 
1577 	fll->ref_src = source;
1578 	fll->ref_freq = Fref;
1579 
1580 	if (fll->fout && Fref > 0) {
1581 		arizona_enable_fll(fll, &ref, &sync);
1582 	}
1583 
1584 	return 0;
1585 }
1586 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1587 
1588 int arizona_set_fll(struct arizona_fll *fll, int source,
1589 		    unsigned int Fref, unsigned int Fout)
1590 {
1591 	struct arizona_fll_cfg ref, sync;
1592 	int ret;
1593 
1594 	if (fll->sync_src == source &&
1595 	    fll->sync_freq == Fref && fll->fout == Fout)
1596 		return 0;
1597 
1598 	if (Fout) {
1599 		if (fll->ref_src >= 0) {
1600 			ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
1601 					       Fout);
1602 			if (ret != 0)
1603 				return ret;
1604 		}
1605 
1606 		ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1607 		if (ret != 0)
1608 			return ret;
1609 	}
1610 
1611 	fll->sync_src = source;
1612 	fll->sync_freq = Fref;
1613 	fll->fout = Fout;
1614 
1615 	if (Fout) {
1616 		arizona_enable_fll(fll, &ref, &sync);
1617 	} else {
1618 		arizona_disable_fll(fll);
1619 	}
1620 
1621 	return 0;
1622 }
1623 EXPORT_SYMBOL_GPL(arizona_set_fll);
1624 
1625 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1626 		     int ok_irq, struct arizona_fll *fll)
1627 {
1628 	int ret;
1629 	unsigned int val;
1630 
1631 	init_completion(&fll->ok);
1632 
1633 	fll->id = id;
1634 	fll->base = base;
1635 	fll->arizona = arizona;
1636 	fll->sync_src = ARIZONA_FLL_SRC_NONE;
1637 
1638 	/* Configure default refclk to 32kHz if we have one */
1639 	regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1640 	switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1641 	case ARIZONA_CLK_SRC_MCLK1:
1642 	case ARIZONA_CLK_SRC_MCLK2:
1643 		fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
1644 		break;
1645 	default:
1646 		fll->ref_src = ARIZONA_FLL_SRC_NONE;
1647 	}
1648 	fll->ref_freq = 32768;
1649 
1650 	snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1651 	snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1652 		 "FLL%d clock OK", id);
1653 
1654 	ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1655 				  arizona_fll_clock_ok, fll);
1656 	if (ret != 0) {
1657 		dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
1658 			id, ret);
1659 	}
1660 
1661 	regmap_update_bits(arizona->regmap, fll->base + 1,
1662 			   ARIZONA_FLL1_FREERUN, 0);
1663 
1664 	return 0;
1665 }
1666 EXPORT_SYMBOL_GPL(arizona_init_fll);
1667 
1668 /**
1669  * arizona_set_output_mode - Set the mode of the specified output
1670  *
1671  * @codec: Device to configure
1672  * @output: Output number
1673  * @diff: True to set the output to differential mode
1674  *
1675  * Some systems use external analogue switches to connect more
1676  * analogue devices to the CODEC than are supported by the device.  In
1677  * some systems this requires changing the switched output from single
1678  * ended to differential mode dynamically at runtime, an operation
1679  * supported using this function.
1680  *
1681  * Most systems have a single static configuration and should use
1682  * platform data instead.
1683  */
1684 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
1685 {
1686 	unsigned int reg, val;
1687 
1688 	if (output < 1 || output > 6)
1689 		return -EINVAL;
1690 
1691 	reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
1692 
1693 	if (diff)
1694 		val = ARIZONA_OUT1_MONO;
1695 	else
1696 		val = 0;
1697 
1698 	return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
1699 }
1700 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
1701 
1702 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1703 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1704 MODULE_LICENSE("GPL");
1705