xref: /linux/sound/soc/codecs/arizona.c (revision 0d456bad36d42d16022be045c8a53ddbb59ee478)
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/gcd.h>
14 #include <linux/module.h>
15 #include <linux/pm_runtime.h>
16 #include <sound/pcm.h>
17 #include <sound/pcm_params.h>
18 #include <sound/tlv.h>
19 
20 #include <linux/mfd/arizona/core.h>
21 #include <linux/mfd/arizona/registers.h>
22 
23 #include "arizona.h"
24 
25 #define ARIZONA_AIF_BCLK_CTRL                   0x00
26 #define ARIZONA_AIF_TX_PIN_CTRL                 0x01
27 #define ARIZONA_AIF_RX_PIN_CTRL                 0x02
28 #define ARIZONA_AIF_RATE_CTRL                   0x03
29 #define ARIZONA_AIF_FORMAT                      0x04
30 #define ARIZONA_AIF_TX_BCLK_RATE                0x05
31 #define ARIZONA_AIF_RX_BCLK_RATE                0x06
32 #define ARIZONA_AIF_FRAME_CTRL_1                0x07
33 #define ARIZONA_AIF_FRAME_CTRL_2                0x08
34 #define ARIZONA_AIF_FRAME_CTRL_3                0x09
35 #define ARIZONA_AIF_FRAME_CTRL_4                0x0A
36 #define ARIZONA_AIF_FRAME_CTRL_5                0x0B
37 #define ARIZONA_AIF_FRAME_CTRL_6                0x0C
38 #define ARIZONA_AIF_FRAME_CTRL_7                0x0D
39 #define ARIZONA_AIF_FRAME_CTRL_8                0x0E
40 #define ARIZONA_AIF_FRAME_CTRL_9                0x0F
41 #define ARIZONA_AIF_FRAME_CTRL_10               0x10
42 #define ARIZONA_AIF_FRAME_CTRL_11               0x11
43 #define ARIZONA_AIF_FRAME_CTRL_12               0x12
44 #define ARIZONA_AIF_FRAME_CTRL_13               0x13
45 #define ARIZONA_AIF_FRAME_CTRL_14               0x14
46 #define ARIZONA_AIF_FRAME_CTRL_15               0x15
47 #define ARIZONA_AIF_FRAME_CTRL_16               0x16
48 #define ARIZONA_AIF_FRAME_CTRL_17               0x17
49 #define ARIZONA_AIF_FRAME_CTRL_18               0x18
50 #define ARIZONA_AIF_TX_ENABLES                  0x19
51 #define ARIZONA_AIF_RX_ENABLES                  0x1A
52 #define ARIZONA_AIF_FORCE_WRITE                 0x1B
53 
54 #define arizona_fll_err(_fll, fmt, ...) \
55 	dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
56 #define arizona_fll_warn(_fll, fmt, ...) \
57 	dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
58 #define arizona_fll_dbg(_fll, fmt, ...) \
59 	dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
60 
61 #define arizona_aif_err(_dai, fmt, ...) \
62 	dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
63 #define arizona_aif_warn(_dai, fmt, ...) \
64 	dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
65 #define arizona_aif_dbg(_dai, fmt, ...) \
66 	dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
67 
68 const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
69 	"None",
70 	"Tone Generator 1",
71 	"Tone Generator 2",
72 	"Haptics",
73 	"AEC",
74 	"Mic Mute Mixer",
75 	"Noise Generator",
76 	"IN1L",
77 	"IN1R",
78 	"IN2L",
79 	"IN2R",
80 	"IN3L",
81 	"IN3R",
82 	"IN4L",
83 	"IN4R",
84 	"AIF1RX1",
85 	"AIF1RX2",
86 	"AIF1RX3",
87 	"AIF1RX4",
88 	"AIF1RX5",
89 	"AIF1RX6",
90 	"AIF1RX7",
91 	"AIF1RX8",
92 	"AIF2RX1",
93 	"AIF2RX2",
94 	"AIF3RX1",
95 	"AIF3RX2",
96 	"SLIMRX1",
97 	"SLIMRX2",
98 	"SLIMRX3",
99 	"SLIMRX4",
100 	"SLIMRX5",
101 	"SLIMRX6",
102 	"SLIMRX7",
103 	"SLIMRX8",
104 	"EQ1",
105 	"EQ2",
106 	"EQ3",
107 	"EQ4",
108 	"DRC1L",
109 	"DRC1R",
110 	"DRC2L",
111 	"DRC2R",
112 	"LHPF1",
113 	"LHPF2",
114 	"LHPF3",
115 	"LHPF4",
116 	"DSP1.1",
117 	"DSP1.2",
118 	"DSP1.3",
119 	"DSP1.4",
120 	"DSP1.5",
121 	"DSP1.6",
122 	"DSP2.1",
123 	"DSP2.2",
124 	"DSP2.3",
125 	"DSP2.4",
126 	"DSP2.5",
127 	"DSP2.6",
128 	"DSP3.1",
129 	"DSP3.2",
130 	"DSP3.3",
131 	"DSP3.4",
132 	"DSP3.5",
133 	"DSP3.6",
134 	"DSP4.1",
135 	"DSP4.2",
136 	"DSP4.3",
137 	"DSP4.4",
138 	"DSP4.5",
139 	"DSP4.6",
140 	"ASRC1L",
141 	"ASRC1R",
142 	"ASRC2L",
143 	"ASRC2R",
144 };
145 EXPORT_SYMBOL_GPL(arizona_mixer_texts);
146 
147 int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
148 	0x00,  /* None */
149 	0x04,  /* Tone */
150 	0x05,
151 	0x06,  /* Haptics */
152 	0x08,  /* AEC */
153 	0x0c,  /* Noise mixer */
154 	0x0d,  /* Comfort noise */
155 	0x10,  /* IN1L */
156 	0x11,
157 	0x12,
158 	0x13,
159 	0x14,
160 	0x15,
161 	0x16,
162 	0x17,
163 	0x20,  /* AIF1RX1 */
164 	0x21,
165 	0x22,
166 	0x23,
167 	0x24,
168 	0x25,
169 	0x26,
170 	0x27,
171 	0x28,  /* AIF2RX1 */
172 	0x29,
173 	0x30,  /* AIF3RX1 */
174 	0x31,
175 	0x38,  /* SLIMRX1 */
176 	0x39,
177 	0x3a,
178 	0x3b,
179 	0x3c,
180 	0x3d,
181 	0x3e,
182 	0x3f,
183 	0x50,  /* EQ1 */
184 	0x51,
185 	0x52,
186 	0x53,
187 	0x58,  /* DRC1L */
188 	0x59,
189 	0x5a,
190 	0x5b,
191 	0x60,  /* LHPF1 */
192 	0x61,
193 	0x62,
194 	0x63,
195 	0x68,  /* DSP1.1 */
196 	0x69,
197 	0x6a,
198 	0x6b,
199 	0x6c,
200 	0x6d,
201 	0x70,  /* DSP2.1 */
202 	0x71,
203 	0x72,
204 	0x73,
205 	0x74,
206 	0x75,
207 	0x78,  /* DSP3.1 */
208 	0x79,
209 	0x7a,
210 	0x7b,
211 	0x7c,
212 	0x7d,
213 	0x80,  /* DSP4.1 */
214 	0x81,
215 	0x82,
216 	0x83,
217 	0x84,
218 	0x85,
219 	0x90,  /* ASRC1L */
220 	0x91,
221 	0x92,
222 	0x93,
223 };
224 EXPORT_SYMBOL_GPL(arizona_mixer_values);
225 
226 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
227 EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
228 
229 static const char *arizona_vol_ramp_text[] = {
230 	"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
231 	"15ms/6dB", "30ms/6dB",
232 };
233 
234 const struct soc_enum arizona_in_vd_ramp =
235 	SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
236 			ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
237 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
238 
239 const struct soc_enum arizona_in_vi_ramp =
240 	SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
241 			ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
242 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
243 
244 const struct soc_enum arizona_out_vd_ramp =
245 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
246 			ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
247 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
248 
249 const struct soc_enum arizona_out_vi_ramp =
250 	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
251 			ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
252 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
253 
254 static const char *arizona_lhpf_mode_text[] = {
255 	"Low-pass", "High-pass"
256 };
257 
258 const struct soc_enum arizona_lhpf1_mode =
259 	SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
260 			arizona_lhpf_mode_text);
261 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
262 
263 const struct soc_enum arizona_lhpf2_mode =
264 	SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
265 			arizona_lhpf_mode_text);
266 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
267 
268 const struct soc_enum arizona_lhpf3_mode =
269 	SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
270 			arizona_lhpf_mode_text);
271 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
272 
273 const struct soc_enum arizona_lhpf4_mode =
274 	SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
275 			arizona_lhpf_mode_text);
276 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
277 
278 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
279 		  int event)
280 {
281 	return 0;
282 }
283 EXPORT_SYMBOL_GPL(arizona_in_ev);
284 
285 int arizona_out_ev(struct snd_soc_dapm_widget *w,
286 		   struct snd_kcontrol *kcontrol,
287 		   int event)
288 {
289 	return 0;
290 }
291 EXPORT_SYMBOL_GPL(arizona_out_ev);
292 
293 static unsigned int arizona_sysclk_48k_rates[] = {
294 	6144000,
295 	12288000,
296 	24576000,
297 	49152000,
298 	73728000,
299 	98304000,
300 	147456000,
301 };
302 
303 static unsigned int arizona_sysclk_44k1_rates[] = {
304 	5644800,
305 	11289600,
306 	22579200,
307 	45158400,
308 	67737600,
309 	90316800,
310 	135475200,
311 };
312 
313 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
314 			     unsigned int freq)
315 {
316 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
317 	unsigned int reg;
318 	unsigned int *rates;
319 	int ref, div, refclk;
320 
321 	switch (clk) {
322 	case ARIZONA_CLK_OPCLK:
323 		reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
324 		refclk = priv->sysclk;
325 		break;
326 	case ARIZONA_CLK_ASYNC_OPCLK:
327 		reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
328 		refclk = priv->asyncclk;
329 		break;
330 	default:
331 		return -EINVAL;
332 	}
333 
334 	if (refclk % 8000)
335 		rates = arizona_sysclk_44k1_rates;
336 	else
337 		rates = arizona_sysclk_48k_rates;
338 
339 	for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
340 		     rates[ref] <= refclk; ref++) {
341 		div = 1;
342 		while (rates[ref] / div >= freq && div < 32) {
343 			if (rates[ref] / div == freq) {
344 				dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
345 					freq);
346 				snd_soc_update_bits(codec, reg,
347 						    ARIZONA_OPCLK_DIV_MASK |
348 						    ARIZONA_OPCLK_SEL_MASK,
349 						    (div <<
350 						     ARIZONA_OPCLK_DIV_SHIFT) |
351 						    ref);
352 				return 0;
353 			}
354 			div++;
355 		}
356 	}
357 
358 	dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
359 	return -EINVAL;
360 }
361 
362 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
363 		       int source, unsigned int freq, int dir)
364 {
365 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
366 	struct arizona *arizona = priv->arizona;
367 	char *name;
368 	unsigned int reg;
369 	unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
370 	unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
371 	unsigned int *clk;
372 
373 	switch (clk_id) {
374 	case ARIZONA_CLK_SYSCLK:
375 		name = "SYSCLK";
376 		reg = ARIZONA_SYSTEM_CLOCK_1;
377 		clk = &priv->sysclk;
378 		mask |= ARIZONA_SYSCLK_FRAC;
379 		break;
380 	case ARIZONA_CLK_ASYNCCLK:
381 		name = "ASYNCCLK";
382 		reg = ARIZONA_ASYNC_CLOCK_1;
383 		clk = &priv->asyncclk;
384 		break;
385 	case ARIZONA_CLK_OPCLK:
386 	case ARIZONA_CLK_ASYNC_OPCLK:
387 		return arizona_set_opclk(codec, clk_id, freq);
388 	default:
389 		return -EINVAL;
390 	}
391 
392 	switch (freq) {
393 	case  5644800:
394 	case  6144000:
395 		break;
396 	case 11289600:
397 	case 12288000:
398 		val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT;
399 		break;
400 	case 22579200:
401 	case 24576000:
402 		val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT;
403 		break;
404 	case 45158400:
405 	case 49152000:
406 		val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
407 		break;
408 	case 67737600:
409 	case 73728000:
410 		val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT;
411 		break;
412 	case 90316800:
413 	case 98304000:
414 		val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT;
415 		break;
416 	case 135475200:
417 	case 147456000:
418 		val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT;
419 		break;
420 	default:
421 		return -EINVAL;
422 	}
423 
424 	*clk = freq;
425 
426 	if (freq % 6144000)
427 		val |= ARIZONA_SYSCLK_FRAC;
428 
429 	dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
430 
431 	return regmap_update_bits(arizona->regmap, reg, mask, val);
432 }
433 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
434 
435 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
436 {
437 	struct snd_soc_codec *codec = dai->codec;
438 	int lrclk, bclk, mode, base;
439 
440 	base = dai->driver->base;
441 
442 	lrclk = 0;
443 	bclk = 0;
444 
445 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
446 	case SND_SOC_DAIFMT_DSP_A:
447 		mode = 0;
448 		break;
449 	case SND_SOC_DAIFMT_DSP_B:
450 		mode = 1;
451 		break;
452 	case SND_SOC_DAIFMT_I2S:
453 		mode = 2;
454 		break;
455 	case SND_SOC_DAIFMT_LEFT_J:
456 		mode = 3;
457 		break;
458 	default:
459 		arizona_aif_err(dai, "Unsupported DAI format %d\n",
460 				fmt & SND_SOC_DAIFMT_FORMAT_MASK);
461 		return -EINVAL;
462 	}
463 
464 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
465 	case SND_SOC_DAIFMT_CBS_CFS:
466 		break;
467 	case SND_SOC_DAIFMT_CBS_CFM:
468 		lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
469 		break;
470 	case SND_SOC_DAIFMT_CBM_CFS:
471 		bclk |= ARIZONA_AIF1_BCLK_MSTR;
472 		break;
473 	case SND_SOC_DAIFMT_CBM_CFM:
474 		bclk |= ARIZONA_AIF1_BCLK_MSTR;
475 		lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
476 		break;
477 	default:
478 		arizona_aif_err(dai, "Unsupported master mode %d\n",
479 				fmt & SND_SOC_DAIFMT_MASTER_MASK);
480 		return -EINVAL;
481 	}
482 
483 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
484 	case SND_SOC_DAIFMT_NB_NF:
485 		break;
486 	case SND_SOC_DAIFMT_IB_IF:
487 		bclk |= ARIZONA_AIF1_BCLK_INV;
488 		lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
489 		break;
490 	case SND_SOC_DAIFMT_IB_NF:
491 		bclk |= ARIZONA_AIF1_BCLK_INV;
492 		break;
493 	case SND_SOC_DAIFMT_NB_IF:
494 		lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
495 		break;
496 	default:
497 		return -EINVAL;
498 	}
499 
500 	snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
501 			    ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
502 			    bclk);
503 	snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
504 			    ARIZONA_AIF1TX_LRCLK_INV |
505 			    ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
506 	snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
507 			    ARIZONA_AIF1RX_LRCLK_INV |
508 			    ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
509 	snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
510 			    ARIZONA_AIF1_FMT_MASK, mode);
511 
512 	return 0;
513 }
514 
515 static const int arizona_48k_bclk_rates[] = {
516 	-1,
517 	48000,
518 	64000,
519 	96000,
520 	128000,
521 	192000,
522 	256000,
523 	384000,
524 	512000,
525 	768000,
526 	1024000,
527 	1536000,
528 	2048000,
529 	3072000,
530 	4096000,
531 	6144000,
532 	8192000,
533 	12288000,
534 	24576000,
535 };
536 
537 static const unsigned int arizona_48k_rates[] = {
538 	12000,
539 	24000,
540 	48000,
541 	96000,
542 	192000,
543 	384000,
544 	768000,
545 	4000,
546 	8000,
547 	16000,
548 	32000,
549 	64000,
550 	128000,
551 	256000,
552 	512000,
553 };
554 
555 static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
556 	.count	= ARRAY_SIZE(arizona_48k_rates),
557 	.list	= arizona_48k_rates,
558 };
559 
560 static const int arizona_44k1_bclk_rates[] = {
561 	-1,
562 	44100,
563 	58800,
564 	88200,
565 	117600,
566 	177640,
567 	235200,
568 	352800,
569 	470400,
570 	705600,
571 	940800,
572 	1411200,
573 	1881600,
574 	2822400,
575 	3763200,
576 	5644800,
577 	7526400,
578 	11289600,
579 	22579200,
580 };
581 
582 static const unsigned int arizona_44k1_rates[] = {
583 	11025,
584 	22050,
585 	44100,
586 	88200,
587 	176400,
588 	352800,
589 	705600,
590 };
591 
592 static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
593 	.count	= ARRAY_SIZE(arizona_44k1_rates),
594 	.list	= arizona_44k1_rates,
595 };
596 
597 static int arizona_sr_vals[] = {
598 	0,
599 	12000,
600 	24000,
601 	48000,
602 	96000,
603 	192000,
604 	384000,
605 	768000,
606 	0,
607 	11025,
608 	22050,
609 	44100,
610 	88200,
611 	176400,
612 	352800,
613 	705600,
614 	4000,
615 	8000,
616 	16000,
617 	32000,
618 	64000,
619 	128000,
620 	256000,
621 	512000,
622 };
623 
624 static int arizona_startup(struct snd_pcm_substream *substream,
625 			   struct snd_soc_dai *dai)
626 {
627 	struct snd_soc_codec *codec = dai->codec;
628 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
629 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
630 	const struct snd_pcm_hw_constraint_list *constraint;
631 	unsigned int base_rate;
632 
633 	switch (dai_priv->clk) {
634 	case ARIZONA_CLK_SYSCLK:
635 		base_rate = priv->sysclk;
636 		break;
637 	case ARIZONA_CLK_ASYNCCLK:
638 		base_rate = priv->asyncclk;
639 		break;
640 	default:
641 		return 0;
642 	}
643 
644 	if (base_rate % 8000)
645 		constraint = &arizona_44k1_constraint;
646 	else
647 		constraint = &arizona_48k_constraint;
648 
649 	return snd_pcm_hw_constraint_list(substream->runtime, 0,
650 					  SNDRV_PCM_HW_PARAM_RATE,
651 					  constraint);
652 }
653 
654 static int arizona_hw_params(struct snd_pcm_substream *substream,
655 			     struct snd_pcm_hw_params *params,
656 			     struct snd_soc_dai *dai)
657 {
658 	struct snd_soc_codec *codec = dai->codec;
659 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
660 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
661 	int base = dai->driver->base;
662 	const int *rates;
663 	int i;
664 	int bclk, lrclk, wl, frame, sr_val;
665 
666 	if (params_rate(params) % 8000)
667 		rates = &arizona_44k1_bclk_rates[0];
668 	else
669 		rates = &arizona_48k_bclk_rates[0];
670 
671 	for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
672 		if (rates[i] >= snd_soc_params_to_bclk(params) &&
673 		    rates[i] % params_rate(params) == 0) {
674 			bclk = i;
675 			break;
676 		}
677 	}
678 	if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
679 		arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
680 				params_rate(params));
681 		return -EINVAL;
682 	}
683 
684 	for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
685 		if (arizona_sr_vals[i] == params_rate(params))
686 			break;
687 	if (i == ARRAY_SIZE(arizona_sr_vals)) {
688 		arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
689 				params_rate(params));
690 		return -EINVAL;
691 	}
692 	sr_val = i;
693 
694 	lrclk = snd_soc_params_to_bclk(params) / params_rate(params);
695 
696 	arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
697 			rates[bclk], rates[bclk] / lrclk);
698 
699 	wl = snd_pcm_format_width(params_format(params));
700 	frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
701 
702 	/*
703 	 * We will need to be more flexible than this in future,
704 	 * currently we use a single sample rate for SYSCLK.
705 	 */
706 	switch (dai_priv->clk) {
707 	case ARIZONA_CLK_SYSCLK:
708 		snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
709 				    ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
710 		snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
711 				    ARIZONA_AIF1_RATE_MASK, 0);
712 		break;
713 	case ARIZONA_CLK_ASYNCCLK:
714 		snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
715 				    ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
716 		snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
717 				    ARIZONA_AIF1_RATE_MASK, 8);
718 		break;
719 	default:
720 		arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
721 		return -EINVAL;
722 	}
723 
724 	snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
725 			    ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
726 	snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
727 			    ARIZONA_AIF1TX_BCPF_MASK, lrclk);
728 	snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
729 			    ARIZONA_AIF1RX_BCPF_MASK, lrclk);
730 	snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
731 			    ARIZONA_AIF1TX_WL_MASK |
732 			    ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
733 	snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
734 			    ARIZONA_AIF1RX_WL_MASK |
735 			    ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
736 
737 	return 0;
738 }
739 
740 static const char *arizona_dai_clk_str(int clk_id)
741 {
742 	switch (clk_id) {
743 	case ARIZONA_CLK_SYSCLK:
744 		return "SYSCLK";
745 	case ARIZONA_CLK_ASYNCCLK:
746 		return "ASYNCCLK";
747 	default:
748 		return "Unknown clock";
749 	}
750 }
751 
752 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
753 				  int clk_id, unsigned int freq, int dir)
754 {
755 	struct snd_soc_codec *codec = dai->codec;
756 	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
757 	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
758 	struct snd_soc_dapm_route routes[2];
759 
760 	switch (clk_id) {
761 	case ARIZONA_CLK_SYSCLK:
762 	case ARIZONA_CLK_ASYNCCLK:
763 		break;
764 	default:
765 		return -EINVAL;
766 	}
767 
768 	if (clk_id == dai_priv->clk)
769 		return 0;
770 
771 	if (dai->active) {
772 		dev_err(codec->dev, "Can't change clock on active DAI %d\n",
773 			dai->id);
774 		return -EBUSY;
775 	}
776 
777 	dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
778 		arizona_dai_clk_str(clk_id));
779 
780 	memset(&routes, 0, sizeof(routes));
781 	routes[0].sink = dai->driver->capture.stream_name;
782 	routes[1].sink = dai->driver->playback.stream_name;
783 
784 	routes[0].source = arizona_dai_clk_str(dai_priv->clk);
785 	routes[1].source = arizona_dai_clk_str(dai_priv->clk);
786 	snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
787 
788 	routes[0].source = arizona_dai_clk_str(clk_id);
789 	routes[1].source = arizona_dai_clk_str(clk_id);
790 	snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
791 
792 	dai_priv->clk = clk_id;
793 
794 	return snd_soc_dapm_sync(&codec->dapm);
795 }
796 
797 const struct snd_soc_dai_ops arizona_dai_ops = {
798 	.startup = arizona_startup,
799 	.set_fmt = arizona_set_fmt,
800 	.hw_params = arizona_hw_params,
801 	.set_sysclk = arizona_dai_set_sysclk,
802 };
803 EXPORT_SYMBOL_GPL(arizona_dai_ops);
804 
805 int arizona_init_dai(struct arizona_priv *priv, int id)
806 {
807 	struct arizona_dai_priv *dai_priv = &priv->dai[id];
808 
809 	dai_priv->clk = ARIZONA_CLK_SYSCLK;
810 
811 	return 0;
812 }
813 EXPORT_SYMBOL_GPL(arizona_init_dai);
814 
815 static irqreturn_t arizona_fll_lock(int irq, void *data)
816 {
817 	struct arizona_fll *fll = data;
818 
819 	arizona_fll_dbg(fll, "Lock status changed\n");
820 
821 	complete(&fll->lock);
822 
823 	return IRQ_HANDLED;
824 }
825 
826 static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
827 {
828 	struct arizona_fll *fll = data;
829 
830 	arizona_fll_dbg(fll, "clock OK\n");
831 
832 	complete(&fll->ok);
833 
834 	return IRQ_HANDLED;
835 }
836 
837 static struct {
838 	unsigned int min;
839 	unsigned int max;
840 	u16 fratio;
841 	int ratio;
842 } fll_fratios[] = {
843 	{       0,    64000, 4, 16 },
844 	{   64000,   128000, 3,  8 },
845 	{  128000,   256000, 2,  4 },
846 	{  256000,  1000000, 1,  2 },
847 	{ 1000000, 13500000, 0,  1 },
848 };
849 
850 struct arizona_fll_cfg {
851 	int n;
852 	int theta;
853 	int lambda;
854 	int refdiv;
855 	int outdiv;
856 	int fratio;
857 };
858 
859 static int arizona_calc_fll(struct arizona_fll *fll,
860 			    struct arizona_fll_cfg *cfg,
861 			    unsigned int Fref,
862 			    unsigned int Fout)
863 {
864 	unsigned int target, div, gcd_fll;
865 	int i, ratio;
866 
867 	arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
868 
869 	/* Fref must be <=13.5MHz */
870 	div = 1;
871 	cfg->refdiv = 0;
872 	while ((Fref / div) > 13500000) {
873 		div *= 2;
874 		cfg->refdiv++;
875 
876 		if (div > 8) {
877 			arizona_fll_err(fll,
878 					"Can't scale %dMHz in to <=13.5MHz\n",
879 					Fref);
880 			return -EINVAL;
881 		}
882 	}
883 
884 	/* Apply the division for our remaining calculations */
885 	Fref /= div;
886 
887 	/* Fvco should be over the targt; don't check the upper bound */
888 	div = 1;
889 	while (Fout * div < 90000000 * fll->vco_mult) {
890 		div++;
891 		if (div > 7) {
892 			arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
893 					Fout);
894 			return -EINVAL;
895 		}
896 	}
897 	target = Fout * div / fll->vco_mult;
898 	cfg->outdiv = div;
899 
900 	arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
901 
902 	/* Find an appropraite FLL_FRATIO and factor it out of the target */
903 	for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
904 		if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
905 			cfg->fratio = fll_fratios[i].fratio;
906 			ratio = fll_fratios[i].ratio;
907 			break;
908 		}
909 	}
910 	if (i == ARRAY_SIZE(fll_fratios)) {
911 		arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
912 				Fref);
913 		return -EINVAL;
914 	}
915 
916 	cfg->n = target / (ratio * Fref);
917 
918 	if (target % Fref) {
919 		gcd_fll = gcd(target, ratio * Fref);
920 		arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
921 
922 		cfg->theta = (target - (cfg->n * ratio * Fref))
923 			/ gcd_fll;
924 		cfg->lambda = (ratio * Fref) / gcd_fll;
925 	} else {
926 		cfg->theta = 0;
927 		cfg->lambda = 0;
928 	}
929 
930 	arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
931 			cfg->n, cfg->theta, cfg->lambda);
932 	arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
933 			cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
934 
935 	return 0;
936 
937 }
938 
939 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
940 			      struct arizona_fll_cfg *cfg, int source)
941 {
942 	regmap_update_bits(arizona->regmap, base + 3,
943 			   ARIZONA_FLL1_THETA_MASK, cfg->theta);
944 	regmap_update_bits(arizona->regmap, base + 4,
945 			   ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
946 	regmap_update_bits(arizona->regmap, base + 5,
947 			   ARIZONA_FLL1_FRATIO_MASK,
948 			   cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
949 	regmap_update_bits(arizona->regmap, base + 6,
950 			   ARIZONA_FLL1_CLK_REF_DIV_MASK |
951 			   ARIZONA_FLL1_CLK_REF_SRC_MASK,
952 			   cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
953 			   source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
954 
955 	regmap_update_bits(arizona->regmap, base + 2,
956 			   ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
957 			   ARIZONA_FLL1_CTRL_UPD | cfg->n);
958 }
959 
960 int arizona_set_fll(struct arizona_fll *fll, int source,
961 		    unsigned int Fref, unsigned int Fout)
962 {
963 	struct arizona *arizona = fll->arizona;
964 	struct arizona_fll_cfg cfg, sync;
965 	unsigned int reg, val;
966 	int syncsrc;
967 	bool ena;
968 	int ret;
969 
970 	if (fll->fref == Fref && fll->fout == Fout)
971 		return 0;
972 
973 	ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
974 	if (ret != 0) {
975 		arizona_fll_err(fll, "Failed to read current state: %d\n",
976 				ret);
977 		return ret;
978 	}
979 	ena = reg & ARIZONA_FLL1_ENA;
980 
981 	if (Fout) {
982 		/* Do we have a 32kHz reference? */
983 		regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
984 		switch (val & ARIZONA_CLK_32K_SRC_MASK) {
985 		case ARIZONA_CLK_SRC_MCLK1:
986 		case ARIZONA_CLK_SRC_MCLK2:
987 			syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
988 			break;
989 		default:
990 			syncsrc = -1;
991 		}
992 
993 		if (source == syncsrc)
994 			syncsrc = -1;
995 
996 		if (syncsrc >= 0) {
997 			ret = arizona_calc_fll(fll, &sync, Fref, Fout);
998 			if (ret != 0)
999 				return ret;
1000 
1001 			ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
1002 			if (ret != 0)
1003 				return ret;
1004 		} else {
1005 			ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
1006 			if (ret != 0)
1007 				return ret;
1008 		}
1009 	} else {
1010 		regmap_update_bits(arizona->regmap, fll->base + 1,
1011 				   ARIZONA_FLL1_ENA, 0);
1012 		regmap_update_bits(arizona->regmap, fll->base + 0x11,
1013 				   ARIZONA_FLL1_SYNC_ENA, 0);
1014 
1015 		if (ena)
1016 			pm_runtime_put_autosuspend(arizona->dev);
1017 
1018 		fll->fref = Fref;
1019 		fll->fout = Fout;
1020 
1021 		return 0;
1022 	}
1023 
1024 	regmap_update_bits(arizona->regmap, fll->base + 5,
1025 			   ARIZONA_FLL1_OUTDIV_MASK,
1026 			   cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1027 
1028 	if (syncsrc >= 0) {
1029 		arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
1030 		arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
1031 	} else {
1032 		arizona_apply_fll(arizona, fll->base, &cfg, source);
1033 	}
1034 
1035 	if (!ena)
1036 		pm_runtime_get(arizona->dev);
1037 
1038 	/* Clear any pending completions */
1039 	try_wait_for_completion(&fll->ok);
1040 
1041 	regmap_update_bits(arizona->regmap, fll->base + 1,
1042 			   ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1043 	if (syncsrc >= 0)
1044 		regmap_update_bits(arizona->regmap, fll->base + 0x11,
1045 				   ARIZONA_FLL1_SYNC_ENA,
1046 				   ARIZONA_FLL1_SYNC_ENA);
1047 
1048 	ret = wait_for_completion_timeout(&fll->ok,
1049 					  msecs_to_jiffies(250));
1050 	if (ret == 0)
1051 		arizona_fll_warn(fll, "Timed out waiting for lock\n");
1052 
1053 	fll->fref = Fref;
1054 	fll->fout = Fout;
1055 
1056 	return 0;
1057 }
1058 EXPORT_SYMBOL_GPL(arizona_set_fll);
1059 
1060 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1061 		     int ok_irq, struct arizona_fll *fll)
1062 {
1063 	int ret;
1064 
1065 	init_completion(&fll->lock);
1066 	init_completion(&fll->ok);
1067 
1068 	fll->id = id;
1069 	fll->base = base;
1070 	fll->arizona = arizona;
1071 
1072 	snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1073 	snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1074 		 "FLL%d clock OK", id);
1075 
1076 	ret = arizona_request_irq(arizona, lock_irq, fll->lock_name,
1077 				  arizona_fll_lock, fll);
1078 	if (ret != 0) {
1079 		dev_err(arizona->dev, "Failed to get FLL%d lock IRQ: %d\n",
1080 			id, ret);
1081 	}
1082 
1083 	ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1084 				  arizona_fll_clock_ok, fll);
1085 	if (ret != 0) {
1086 		dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
1087 			id, ret);
1088 	}
1089 
1090 	return 0;
1091 }
1092 EXPORT_SYMBOL_GPL(arizona_init_fll);
1093 
1094 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1095 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1096 MODULE_LICENSE("GPL");
1097