ASoC: arizona: Add support for directly setting the FLL REFCLK
[deliverable/linux.git] / sound / soc / codecs / arizona.c
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_dbg(_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_dbg(_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 "ISRC1INT1",
145 "ISRC1INT2",
146 "ISRC1INT3",
147 "ISRC1INT4",
148 "ISRC1DEC1",
149 "ISRC1DEC2",
150 "ISRC1DEC3",
151 "ISRC1DEC4",
152 "ISRC2INT1",
153 "ISRC2INT2",
154 "ISRC2INT3",
155 "ISRC2INT4",
156 "ISRC2DEC1",
157 "ISRC2DEC2",
158 "ISRC2DEC3",
159 "ISRC2DEC4",
160 "ISRC3INT1",
161 "ISRC3INT2",
162 "ISRC3INT3",
163 "ISRC3INT4",
164 "ISRC3DEC1",
165 "ISRC3DEC2",
166 "ISRC3DEC3",
167 "ISRC3DEC4",
168 };
169 EXPORT_SYMBOL_GPL(arizona_mixer_texts);
170
171 int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
172 0x00, /* None */
173 0x04, /* Tone */
174 0x05,
175 0x06, /* Haptics */
176 0x08, /* AEC */
177 0x0c, /* Noise mixer */
178 0x0d, /* Comfort noise */
179 0x10, /* IN1L */
180 0x11,
181 0x12,
182 0x13,
183 0x14,
184 0x15,
185 0x16,
186 0x17,
187 0x20, /* AIF1RX1 */
188 0x21,
189 0x22,
190 0x23,
191 0x24,
192 0x25,
193 0x26,
194 0x27,
195 0x28, /* AIF2RX1 */
196 0x29,
197 0x30, /* AIF3RX1 */
198 0x31,
199 0x38, /* SLIMRX1 */
200 0x39,
201 0x3a,
202 0x3b,
203 0x3c,
204 0x3d,
205 0x3e,
206 0x3f,
207 0x50, /* EQ1 */
208 0x51,
209 0x52,
210 0x53,
211 0x58, /* DRC1L */
212 0x59,
213 0x5a,
214 0x5b,
215 0x60, /* LHPF1 */
216 0x61,
217 0x62,
218 0x63,
219 0x68, /* DSP1.1 */
220 0x69,
221 0x6a,
222 0x6b,
223 0x6c,
224 0x6d,
225 0x70, /* DSP2.1 */
226 0x71,
227 0x72,
228 0x73,
229 0x74,
230 0x75,
231 0x78, /* DSP3.1 */
232 0x79,
233 0x7a,
234 0x7b,
235 0x7c,
236 0x7d,
237 0x80, /* DSP4.1 */
238 0x81,
239 0x82,
240 0x83,
241 0x84,
242 0x85,
243 0x90, /* ASRC1L */
244 0x91,
245 0x92,
246 0x93,
247 0xa0, /* ISRC1INT1 */
248 0xa1,
249 0xa2,
250 0xa3,
251 0xa4, /* ISRC1DEC1 */
252 0xa5,
253 0xa6,
254 0xa7,
255 0xa8, /* ISRC2DEC1 */
256 0xa9,
257 0xaa,
258 0xab,
259 0xac, /* ISRC2INT1 */
260 0xad,
261 0xae,
262 0xaf,
263 0xb0, /* ISRC3DEC1 */
264 0xb1,
265 0xb2,
266 0xb3,
267 0xb4, /* ISRC3INT1 */
268 0xb5,
269 0xb6,
270 0xb7,
271 };
272 EXPORT_SYMBOL_GPL(arizona_mixer_values);
273
274 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
275 EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
276
277 static const char *arizona_vol_ramp_text[] = {
278 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
279 "15ms/6dB", "30ms/6dB",
280 };
281
282 const struct soc_enum arizona_in_vd_ramp =
283 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
284 ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
285 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
286
287 const struct soc_enum arizona_in_vi_ramp =
288 SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
289 ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
290 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
291
292 const struct soc_enum arizona_out_vd_ramp =
293 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
294 ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
295 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
296
297 const struct soc_enum arizona_out_vi_ramp =
298 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
299 ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
300 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
301
302 static const char *arizona_lhpf_mode_text[] = {
303 "Low-pass", "High-pass"
304 };
305
306 const struct soc_enum arizona_lhpf1_mode =
307 SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
308 arizona_lhpf_mode_text);
309 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
310
311 const struct soc_enum arizona_lhpf2_mode =
312 SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
313 arizona_lhpf_mode_text);
314 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
315
316 const struct soc_enum arizona_lhpf3_mode =
317 SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
318 arizona_lhpf_mode_text);
319 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
320
321 const struct soc_enum arizona_lhpf4_mode =
322 SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
323 arizona_lhpf_mode_text);
324 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
325
326 static const char *arizona_ng_hold_text[] = {
327 "30ms", "120ms", "250ms", "500ms",
328 };
329
330 const struct soc_enum arizona_ng_hold =
331 SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT,
332 4, arizona_ng_hold_text);
333 EXPORT_SYMBOL_GPL(arizona_ng_hold);
334
335 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
336 int event)
337 {
338 unsigned int reg;
339
340 if (w->shift % 2)
341 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
342 else
343 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
344
345 switch (event) {
346 case SND_SOC_DAPM_POST_PMU:
347 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
348 break;
349 case SND_SOC_DAPM_PRE_PMD:
350 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE,
351 ARIZONA_IN1L_MUTE);
352 break;
353 }
354
355 return 0;
356 }
357 EXPORT_SYMBOL_GPL(arizona_in_ev);
358
359 int arizona_out_ev(struct snd_soc_dapm_widget *w,
360 struct snd_kcontrol *kcontrol,
361 int event)
362 {
363 return 0;
364 }
365 EXPORT_SYMBOL_GPL(arizona_out_ev);
366
367 static unsigned int arizona_sysclk_48k_rates[] = {
368 6144000,
369 12288000,
370 24576000,
371 49152000,
372 73728000,
373 98304000,
374 147456000,
375 };
376
377 static unsigned int arizona_sysclk_44k1_rates[] = {
378 5644800,
379 11289600,
380 22579200,
381 45158400,
382 67737600,
383 90316800,
384 135475200,
385 };
386
387 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
388 unsigned int freq)
389 {
390 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
391 unsigned int reg;
392 unsigned int *rates;
393 int ref, div, refclk;
394
395 switch (clk) {
396 case ARIZONA_CLK_OPCLK:
397 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
398 refclk = priv->sysclk;
399 break;
400 case ARIZONA_CLK_ASYNC_OPCLK:
401 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
402 refclk = priv->asyncclk;
403 break;
404 default:
405 return -EINVAL;
406 }
407
408 if (refclk % 8000)
409 rates = arizona_sysclk_44k1_rates;
410 else
411 rates = arizona_sysclk_48k_rates;
412
413 for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
414 rates[ref] <= refclk; ref++) {
415 div = 1;
416 while (rates[ref] / div >= freq && div < 32) {
417 if (rates[ref] / div == freq) {
418 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
419 freq);
420 snd_soc_update_bits(codec, reg,
421 ARIZONA_OPCLK_DIV_MASK |
422 ARIZONA_OPCLK_SEL_MASK,
423 (div <<
424 ARIZONA_OPCLK_DIV_SHIFT) |
425 ref);
426 return 0;
427 }
428 div++;
429 }
430 }
431
432 dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
433 return -EINVAL;
434 }
435
436 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
437 int source, unsigned int freq, int dir)
438 {
439 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
440 struct arizona *arizona = priv->arizona;
441 char *name;
442 unsigned int reg;
443 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
444 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
445 unsigned int *clk;
446
447 switch (clk_id) {
448 case ARIZONA_CLK_SYSCLK:
449 name = "SYSCLK";
450 reg = ARIZONA_SYSTEM_CLOCK_1;
451 clk = &priv->sysclk;
452 mask |= ARIZONA_SYSCLK_FRAC;
453 break;
454 case ARIZONA_CLK_ASYNCCLK:
455 name = "ASYNCCLK";
456 reg = ARIZONA_ASYNC_CLOCK_1;
457 clk = &priv->asyncclk;
458 break;
459 case ARIZONA_CLK_OPCLK:
460 case ARIZONA_CLK_ASYNC_OPCLK:
461 return arizona_set_opclk(codec, clk_id, freq);
462 default:
463 return -EINVAL;
464 }
465
466 switch (freq) {
467 case 5644800:
468 case 6144000:
469 break;
470 case 11289600:
471 case 12288000:
472 val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT;
473 break;
474 case 22579200:
475 case 24576000:
476 val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT;
477 break;
478 case 45158400:
479 case 49152000:
480 val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
481 break;
482 case 67737600:
483 case 73728000:
484 val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT;
485 break;
486 case 90316800:
487 case 98304000:
488 val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT;
489 break;
490 case 135475200:
491 case 147456000:
492 val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT;
493 break;
494 case 0:
495 dev_dbg(arizona->dev, "%s cleared\n", name);
496 *clk = freq;
497 return 0;
498 default:
499 return -EINVAL;
500 }
501
502 *clk = freq;
503
504 if (freq % 6144000)
505 val |= ARIZONA_SYSCLK_FRAC;
506
507 dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
508
509 return regmap_update_bits(arizona->regmap, reg, mask, val);
510 }
511 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
512
513 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
514 {
515 struct snd_soc_codec *codec = dai->codec;
516 int lrclk, bclk, mode, base;
517
518 base = dai->driver->base;
519
520 lrclk = 0;
521 bclk = 0;
522
523 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
524 case SND_SOC_DAIFMT_DSP_A:
525 mode = 0;
526 break;
527 case SND_SOC_DAIFMT_I2S:
528 mode = 2;
529 break;
530 default:
531 arizona_aif_err(dai, "Unsupported DAI format %d\n",
532 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
533 return -EINVAL;
534 }
535
536 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
537 case SND_SOC_DAIFMT_CBS_CFS:
538 break;
539 case SND_SOC_DAIFMT_CBS_CFM:
540 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
541 break;
542 case SND_SOC_DAIFMT_CBM_CFS:
543 bclk |= ARIZONA_AIF1_BCLK_MSTR;
544 break;
545 case SND_SOC_DAIFMT_CBM_CFM:
546 bclk |= ARIZONA_AIF1_BCLK_MSTR;
547 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
548 break;
549 default:
550 arizona_aif_err(dai, "Unsupported master mode %d\n",
551 fmt & SND_SOC_DAIFMT_MASTER_MASK);
552 return -EINVAL;
553 }
554
555 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
556 case SND_SOC_DAIFMT_NB_NF:
557 break;
558 case SND_SOC_DAIFMT_IB_IF:
559 bclk |= ARIZONA_AIF1_BCLK_INV;
560 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
561 break;
562 case SND_SOC_DAIFMT_IB_NF:
563 bclk |= ARIZONA_AIF1_BCLK_INV;
564 break;
565 case SND_SOC_DAIFMT_NB_IF:
566 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
567 break;
568 default:
569 return -EINVAL;
570 }
571
572 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
573 ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
574 bclk);
575 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
576 ARIZONA_AIF1TX_LRCLK_INV |
577 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
578 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
579 ARIZONA_AIF1RX_LRCLK_INV |
580 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
581 snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
582 ARIZONA_AIF1_FMT_MASK, mode);
583
584 return 0;
585 }
586
587 static const int arizona_48k_bclk_rates[] = {
588 -1,
589 48000,
590 64000,
591 96000,
592 128000,
593 192000,
594 256000,
595 384000,
596 512000,
597 768000,
598 1024000,
599 1536000,
600 2048000,
601 3072000,
602 4096000,
603 6144000,
604 8192000,
605 12288000,
606 24576000,
607 };
608
609 static const unsigned int arizona_48k_rates[] = {
610 12000,
611 24000,
612 48000,
613 96000,
614 192000,
615 384000,
616 768000,
617 4000,
618 8000,
619 16000,
620 32000,
621 64000,
622 128000,
623 256000,
624 512000,
625 };
626
627 static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
628 .count = ARRAY_SIZE(arizona_48k_rates),
629 .list = arizona_48k_rates,
630 };
631
632 static const int arizona_44k1_bclk_rates[] = {
633 -1,
634 44100,
635 58800,
636 88200,
637 117600,
638 177640,
639 235200,
640 352800,
641 470400,
642 705600,
643 940800,
644 1411200,
645 1881600,
646 2822400,
647 3763200,
648 5644800,
649 7526400,
650 11289600,
651 22579200,
652 };
653
654 static const unsigned int arizona_44k1_rates[] = {
655 11025,
656 22050,
657 44100,
658 88200,
659 176400,
660 352800,
661 705600,
662 };
663
664 static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
665 .count = ARRAY_SIZE(arizona_44k1_rates),
666 .list = arizona_44k1_rates,
667 };
668
669 static int arizona_sr_vals[] = {
670 0,
671 12000,
672 24000,
673 48000,
674 96000,
675 192000,
676 384000,
677 768000,
678 0,
679 11025,
680 22050,
681 44100,
682 88200,
683 176400,
684 352800,
685 705600,
686 4000,
687 8000,
688 16000,
689 32000,
690 64000,
691 128000,
692 256000,
693 512000,
694 };
695
696 static int arizona_startup(struct snd_pcm_substream *substream,
697 struct snd_soc_dai *dai)
698 {
699 struct snd_soc_codec *codec = dai->codec;
700 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
701 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
702 const struct snd_pcm_hw_constraint_list *constraint;
703 unsigned int base_rate;
704
705 switch (dai_priv->clk) {
706 case ARIZONA_CLK_SYSCLK:
707 base_rate = priv->sysclk;
708 break;
709 case ARIZONA_CLK_ASYNCCLK:
710 base_rate = priv->asyncclk;
711 break;
712 default:
713 return 0;
714 }
715
716 if (base_rate == 0)
717 return 0;
718
719 if (base_rate % 8000)
720 constraint = &arizona_44k1_constraint;
721 else
722 constraint = &arizona_48k_constraint;
723
724 return snd_pcm_hw_constraint_list(substream->runtime, 0,
725 SNDRV_PCM_HW_PARAM_RATE,
726 constraint);
727 }
728
729 static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
730 struct snd_pcm_hw_params *params,
731 struct snd_soc_dai *dai)
732 {
733 struct snd_soc_codec *codec = dai->codec;
734 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
735 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
736 int base = dai->driver->base;
737 int i, sr_val;
738
739 /*
740 * We will need to be more flexible than this in future,
741 * currently we use a single sample rate for SYSCLK.
742 */
743 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
744 if (arizona_sr_vals[i] == params_rate(params))
745 break;
746 if (i == ARRAY_SIZE(arizona_sr_vals)) {
747 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
748 params_rate(params));
749 return -EINVAL;
750 }
751 sr_val = i;
752
753 switch (dai_priv->clk) {
754 case ARIZONA_CLK_SYSCLK:
755 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
756 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
757 if (base)
758 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
759 ARIZONA_AIF1_RATE_MASK, 0);
760 break;
761 case ARIZONA_CLK_ASYNCCLK:
762 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
763 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
764 if (base)
765 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
766 ARIZONA_AIF1_RATE_MASK,
767 8 << ARIZONA_AIF1_RATE_SHIFT);
768 break;
769 default:
770 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
771 return -EINVAL;
772 }
773
774 return 0;
775 }
776
777 static int arizona_hw_params(struct snd_pcm_substream *substream,
778 struct snd_pcm_hw_params *params,
779 struct snd_soc_dai *dai)
780 {
781 struct snd_soc_codec *codec = dai->codec;
782 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
783 struct arizona *arizona = priv->arizona;
784 int base = dai->driver->base;
785 const int *rates;
786 int i, ret;
787 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
788 int bclk, lrclk, wl, frame, bclk_target;
789
790 if (params_rate(params) % 8000)
791 rates = &arizona_44k1_bclk_rates[0];
792 else
793 rates = &arizona_48k_bclk_rates[0];
794
795 bclk_target = snd_soc_params_to_bclk(params);
796 if (chan_limit && chan_limit < params_channels(params)) {
797 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
798 bclk_target /= params_channels(params);
799 bclk_target *= chan_limit;
800 }
801
802 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
803 if (rates[i] >= bclk_target &&
804 rates[i] % params_rate(params) == 0) {
805 bclk = i;
806 break;
807 }
808 }
809 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
810 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
811 params_rate(params));
812 return -EINVAL;
813 }
814
815 lrclk = rates[bclk] / params_rate(params);
816
817 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
818 rates[bclk], rates[bclk] / lrclk);
819
820 wl = snd_pcm_format_width(params_format(params));
821 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
822
823 ret = arizona_hw_params_rate(substream, params, dai);
824 if (ret != 0)
825 return ret;
826
827 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
828 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
829 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
830 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
831 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
832 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
833 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
834 ARIZONA_AIF1TX_WL_MASK |
835 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
836 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
837 ARIZONA_AIF1RX_WL_MASK |
838 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
839
840 return 0;
841 }
842
843 static const char *arizona_dai_clk_str(int clk_id)
844 {
845 switch (clk_id) {
846 case ARIZONA_CLK_SYSCLK:
847 return "SYSCLK";
848 case ARIZONA_CLK_ASYNCCLK:
849 return "ASYNCCLK";
850 default:
851 return "Unknown clock";
852 }
853 }
854
855 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
856 int clk_id, unsigned int freq, int dir)
857 {
858 struct snd_soc_codec *codec = dai->codec;
859 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
860 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
861 struct snd_soc_dapm_route routes[2];
862
863 switch (clk_id) {
864 case ARIZONA_CLK_SYSCLK:
865 case ARIZONA_CLK_ASYNCCLK:
866 break;
867 default:
868 return -EINVAL;
869 }
870
871 if (clk_id == dai_priv->clk)
872 return 0;
873
874 if (dai->active) {
875 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
876 dai->id);
877 return -EBUSY;
878 }
879
880 dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
881 arizona_dai_clk_str(clk_id));
882
883 memset(&routes, 0, sizeof(routes));
884 routes[0].sink = dai->driver->capture.stream_name;
885 routes[1].sink = dai->driver->playback.stream_name;
886
887 routes[0].source = arizona_dai_clk_str(dai_priv->clk);
888 routes[1].source = arizona_dai_clk_str(dai_priv->clk);
889 snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
890
891 routes[0].source = arizona_dai_clk_str(clk_id);
892 routes[1].source = arizona_dai_clk_str(clk_id);
893 snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
894
895 dai_priv->clk = clk_id;
896
897 return snd_soc_dapm_sync(&codec->dapm);
898 }
899
900 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
901 {
902 struct snd_soc_codec *codec = dai->codec;
903 int base = dai->driver->base;
904 unsigned int reg;
905
906 if (tristate)
907 reg = ARIZONA_AIF1_TRI;
908 else
909 reg = 0;
910
911 return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
912 ARIZONA_AIF1_TRI, reg);
913 }
914
915 const struct snd_soc_dai_ops arizona_dai_ops = {
916 .startup = arizona_startup,
917 .set_fmt = arizona_set_fmt,
918 .hw_params = arizona_hw_params,
919 .set_sysclk = arizona_dai_set_sysclk,
920 .set_tristate = arizona_set_tristate,
921 };
922 EXPORT_SYMBOL_GPL(arizona_dai_ops);
923
924 int arizona_init_dai(struct arizona_priv *priv, int id)
925 {
926 struct arizona_dai_priv *dai_priv = &priv->dai[id];
927
928 dai_priv->clk = ARIZONA_CLK_SYSCLK;
929
930 return 0;
931 }
932 EXPORT_SYMBOL_GPL(arizona_init_dai);
933
934 static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
935 {
936 struct arizona_fll *fll = data;
937
938 arizona_fll_dbg(fll, "clock OK\n");
939
940 complete(&fll->ok);
941
942 return IRQ_HANDLED;
943 }
944
945 static struct {
946 unsigned int min;
947 unsigned int max;
948 u16 fratio;
949 int ratio;
950 } fll_fratios[] = {
951 { 0, 64000, 4, 16 },
952 { 64000, 128000, 3, 8 },
953 { 128000, 256000, 2, 4 },
954 { 256000, 1000000, 1, 2 },
955 { 1000000, 13500000, 0, 1 },
956 };
957
958 struct arizona_fll_cfg {
959 int n;
960 int theta;
961 int lambda;
962 int refdiv;
963 int outdiv;
964 int fratio;
965 };
966
967 static int arizona_calc_fll(struct arizona_fll *fll,
968 struct arizona_fll_cfg *cfg,
969 unsigned int Fref,
970 unsigned int Fout)
971 {
972 unsigned int target, div, gcd_fll;
973 int i, ratio;
974
975 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
976
977 /* Fref must be <=13.5MHz */
978 div = 1;
979 cfg->refdiv = 0;
980 while ((Fref / div) > 13500000) {
981 div *= 2;
982 cfg->refdiv++;
983
984 if (div > 8) {
985 arizona_fll_err(fll,
986 "Can't scale %dMHz in to <=13.5MHz\n",
987 Fref);
988 return -EINVAL;
989 }
990 }
991
992 /* Apply the division for our remaining calculations */
993 Fref /= div;
994
995 /* Fvco should be over the targt; don't check the upper bound */
996 div = 1;
997 while (Fout * div < 90000000 * fll->vco_mult) {
998 div++;
999 if (div > 7) {
1000 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1001 Fout);
1002 return -EINVAL;
1003 }
1004 }
1005 target = Fout * div / fll->vco_mult;
1006 cfg->outdiv = div;
1007
1008 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
1009
1010 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1011 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1012 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1013 cfg->fratio = fll_fratios[i].fratio;
1014 ratio = fll_fratios[i].ratio;
1015 break;
1016 }
1017 }
1018 if (i == ARRAY_SIZE(fll_fratios)) {
1019 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1020 Fref);
1021 return -EINVAL;
1022 }
1023
1024 cfg->n = target / (ratio * Fref);
1025
1026 if (target % (ratio * Fref)) {
1027 gcd_fll = gcd(target, ratio * Fref);
1028 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
1029
1030 cfg->theta = (target - (cfg->n * ratio * Fref))
1031 / gcd_fll;
1032 cfg->lambda = (ratio * Fref) / gcd_fll;
1033 } else {
1034 cfg->theta = 0;
1035 cfg->lambda = 0;
1036 }
1037
1038 /* Round down to 16bit range with cost of accuracy lost.
1039 * Denominator must be bigger than numerator so we only
1040 * take care of it.
1041 */
1042 while (cfg->lambda >= (1 << 16)) {
1043 cfg->theta >>= 1;
1044 cfg->lambda >>= 1;
1045 }
1046
1047 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
1048 cfg->n, cfg->theta, cfg->lambda);
1049 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1050 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
1051
1052 return 0;
1053
1054 }
1055
1056 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1057 struct arizona_fll_cfg *cfg, int source)
1058 {
1059 regmap_update_bits(arizona->regmap, base + 3,
1060 ARIZONA_FLL1_THETA_MASK, cfg->theta);
1061 regmap_update_bits(arizona->regmap, base + 4,
1062 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
1063 regmap_update_bits(arizona->regmap, base + 5,
1064 ARIZONA_FLL1_FRATIO_MASK,
1065 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
1066 regmap_update_bits(arizona->regmap, base + 6,
1067 ARIZONA_FLL1_CLK_REF_DIV_MASK |
1068 ARIZONA_FLL1_CLK_REF_SRC_MASK,
1069 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1070 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1071
1072 regmap_update_bits(arizona->regmap, base + 2,
1073 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1074 ARIZONA_FLL1_CTRL_UPD | cfg->n);
1075 }
1076
1077 static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1078 {
1079 struct arizona *arizona = fll->arizona;
1080 unsigned int reg;
1081 int ret;
1082
1083 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1084 if (ret != 0) {
1085 arizona_fll_err(fll, "Failed to read current state: %d\n",
1086 ret);
1087 return ret;
1088 }
1089
1090 return reg & ARIZONA_FLL1_ENA;
1091 }
1092
1093 static void arizona_enable_fll(struct arizona_fll *fll,
1094 struct arizona_fll_cfg *ref,
1095 struct arizona_fll_cfg *sync)
1096 {
1097 struct arizona *arizona = fll->arizona;
1098 int ret;
1099
1100 regmap_update_bits(arizona->regmap, fll->base + 5,
1101 ARIZONA_FLL1_OUTDIV_MASK,
1102 ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1103
1104 arizona_apply_fll(arizona, fll->base, ref, fll->ref_src);
1105 if (fll->sync_src >= 0)
1106 arizona_apply_fll(arizona, fll->base + 0x10, sync,
1107 fll->sync_src);
1108
1109 if (!arizona_is_enabled_fll(fll))
1110 pm_runtime_get(arizona->dev);
1111
1112 /* Clear any pending completions */
1113 try_wait_for_completion(&fll->ok);
1114
1115 regmap_update_bits(arizona->regmap, fll->base + 1,
1116 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1117 if (fll->sync_src >= 0)
1118 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1119 ARIZONA_FLL1_SYNC_ENA,
1120 ARIZONA_FLL1_SYNC_ENA);
1121
1122 ret = wait_for_completion_timeout(&fll->ok,
1123 msecs_to_jiffies(250));
1124 if (ret == 0)
1125 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1126 }
1127
1128 static void arizona_disable_fll(struct arizona_fll *fll)
1129 {
1130 struct arizona *arizona = fll->arizona;
1131 bool change;
1132
1133 regmap_update_bits_check(arizona->regmap, fll->base + 1,
1134 ARIZONA_FLL1_ENA, 0, &change);
1135 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1136 ARIZONA_FLL1_SYNC_ENA, 0);
1137
1138 if (change)
1139 pm_runtime_put_autosuspend(arizona->dev);
1140 }
1141
1142 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1143 unsigned int Fref, unsigned int Fout)
1144 {
1145 struct arizona_fll_cfg ref, sync;
1146 int ret;
1147
1148 if (source < 0)
1149 return -EINVAL;
1150
1151 if (fll->ref_src == source && fll->ref_freq == Fref &&
1152 fll->fout == Fout)
1153 return 0;
1154
1155 if (Fout) {
1156 ret = arizona_calc_fll(fll, &ref, Fref, Fout);
1157 if (ret != 0)
1158 return ret;
1159
1160 if (fll->sync_src >= 0) {
1161 ret = arizona_calc_fll(fll, &sync, fll->sync_freq, Fout);
1162 if (ret != 0)
1163 return ret;
1164 }
1165 }
1166
1167 fll->ref_src = source;
1168 fll->ref_freq = Fref;
1169 fll->fout = Fout;
1170
1171 if (Fout) {
1172 arizona_enable_fll(fll, &ref, &sync);
1173 } else {
1174 arizona_disable_fll(fll);
1175 }
1176
1177 return 0;
1178 }
1179 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1180
1181 int arizona_set_fll(struct arizona_fll *fll, int source,
1182 unsigned int Fref, unsigned int Fout)
1183 {
1184 struct arizona_fll_cfg ref, sync;
1185 int ret;
1186
1187 if (fll->ref_src < 0 || fll->ref_src == source) {
1188 if (fll->sync_src == -1 &&
1189 fll->ref_src == source && fll->ref_freq == Fref &&
1190 fll->fout == Fout)
1191 return 0;
1192
1193 if (Fout) {
1194 ret = arizona_calc_fll(fll, &ref, Fref, Fout);
1195 if (ret != 0)
1196 return ret;
1197 }
1198
1199 fll->sync_src = -1;
1200 fll->ref_src = source;
1201 fll->ref_freq = Fref;
1202 } else {
1203 if (fll->sync_src == source &&
1204 fll->sync_freq == Fref && fll->fout == Fout)
1205 return 0;
1206
1207 if (Fout) {
1208 ret = arizona_calc_fll(fll, &ref, fll->ref_freq, Fout);
1209 if (ret != 0)
1210 return ret;
1211
1212 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1213 if (ret != 0)
1214 return ret;
1215 }
1216
1217 fll->sync_src = source;
1218 fll->sync_freq = Fref;
1219 }
1220 fll->fout = Fout;
1221
1222 if (Fout) {
1223 arizona_enable_fll(fll, &ref, &sync);
1224 } else {
1225 arizona_disable_fll(fll);
1226 }
1227
1228 return 0;
1229 }
1230 EXPORT_SYMBOL_GPL(arizona_set_fll);
1231
1232 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1233 int ok_irq, struct arizona_fll *fll)
1234 {
1235 int ret;
1236 unsigned int val;
1237
1238 init_completion(&fll->ok);
1239
1240 fll->id = id;
1241 fll->base = base;
1242 fll->arizona = arizona;
1243 fll->sync_src = -1;
1244
1245 /* Configure default refclk to 32kHz if we have one */
1246 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1247 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1248 case ARIZONA_CLK_SRC_MCLK1:
1249 case ARIZONA_CLK_SRC_MCLK2:
1250 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
1251 break;
1252 default:
1253 fll->ref_src = -1;
1254 }
1255 fll->ref_freq = 32768;
1256
1257 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1258 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1259 "FLL%d clock OK", id);
1260
1261 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1262 arizona_fll_clock_ok, fll);
1263 if (ret != 0) {
1264 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
1265 id, ret);
1266 }
1267
1268 regmap_update_bits(arizona->regmap, fll->base + 1,
1269 ARIZONA_FLL1_FREERUN, 0);
1270
1271 return 0;
1272 }
1273 EXPORT_SYMBOL_GPL(arizona_init_fll);
1274
1275 /**
1276 * arizona_set_output_mode - Set the mode of the specified output
1277 *
1278 * @codec: Device to configure
1279 * @output: Output number
1280 * @diff: True to set the output to differential mode
1281 *
1282 * Some systems use external analogue switches to connect more
1283 * analogue devices to the CODEC than are supported by the device. In
1284 * some systems this requires changing the switched output from single
1285 * ended to differential mode dynamically at runtime, an operation
1286 * supported using this function.
1287 *
1288 * Most systems have a single static configuration and should use
1289 * platform data instead.
1290 */
1291 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
1292 {
1293 unsigned int reg, val;
1294
1295 if (output < 1 || output > 6)
1296 return -EINVAL;
1297
1298 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
1299
1300 if (diff)
1301 val = ARIZONA_OUT1_MONO;
1302 else
1303 val = 0;
1304
1305 return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
1306 }
1307 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
1308
1309 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1310 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1311 MODULE_LICENSE("GPL");
This page took 0.07239 seconds and 5 git commands to generate.