Merge remote-tracking branch 'asoc/topic/fsl' into asoc-next
[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 int arizona_set_fll(struct arizona_fll *fll, int source,
1078 unsigned int Fref, unsigned int Fout)
1079 {
1080 struct arizona *arizona = fll->arizona;
1081 struct arizona_fll_cfg cfg, sync;
1082 unsigned int reg, val;
1083 int syncsrc;
1084 bool ena;
1085 int ret;
1086
1087 if (fll->fref == Fref && fll->fout == Fout)
1088 return 0;
1089
1090 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1091 if (ret != 0) {
1092 arizona_fll_err(fll, "Failed to read current state: %d\n",
1093 ret);
1094 return ret;
1095 }
1096 ena = reg & ARIZONA_FLL1_ENA;
1097
1098 if (Fout) {
1099 /* Do we have a 32kHz reference? */
1100 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1101 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1102 case ARIZONA_CLK_SRC_MCLK1:
1103 case ARIZONA_CLK_SRC_MCLK2:
1104 syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
1105 break;
1106 default:
1107 syncsrc = -1;
1108 }
1109
1110 if (source == syncsrc)
1111 syncsrc = -1;
1112
1113 if (syncsrc >= 0) {
1114 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1115 if (ret != 0)
1116 return ret;
1117
1118 ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
1119 if (ret != 0)
1120 return ret;
1121 } else {
1122 ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
1123 if (ret != 0)
1124 return ret;
1125 }
1126 } else {
1127 regmap_update_bits(arizona->regmap, fll->base + 1,
1128 ARIZONA_FLL1_ENA, 0);
1129 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1130 ARIZONA_FLL1_SYNC_ENA, 0);
1131
1132 if (ena)
1133 pm_runtime_put_autosuspend(arizona->dev);
1134
1135 fll->fref = Fref;
1136 fll->fout = Fout;
1137
1138 return 0;
1139 }
1140
1141 regmap_update_bits(arizona->regmap, fll->base + 5,
1142 ARIZONA_FLL1_OUTDIV_MASK,
1143 cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1144
1145 if (syncsrc >= 0) {
1146 arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
1147 arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
1148 } else {
1149 arizona_apply_fll(arizona, fll->base, &cfg, source);
1150 }
1151
1152 if (!ena)
1153 pm_runtime_get(arizona->dev);
1154
1155 /* Clear any pending completions */
1156 try_wait_for_completion(&fll->ok);
1157
1158 regmap_update_bits(arizona->regmap, fll->base + 1,
1159 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1160 if (syncsrc >= 0)
1161 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1162 ARIZONA_FLL1_SYNC_ENA,
1163 ARIZONA_FLL1_SYNC_ENA);
1164
1165 ret = wait_for_completion_timeout(&fll->ok,
1166 msecs_to_jiffies(250));
1167 if (ret == 0)
1168 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1169
1170 fll->fref = Fref;
1171 fll->fout = Fout;
1172
1173 return 0;
1174 }
1175 EXPORT_SYMBOL_GPL(arizona_set_fll);
1176
1177 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1178 int ok_irq, struct arizona_fll *fll)
1179 {
1180 int ret;
1181
1182 init_completion(&fll->ok);
1183
1184 fll->id = id;
1185 fll->base = base;
1186 fll->arizona = arizona;
1187
1188 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1189 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1190 "FLL%d clock OK", id);
1191
1192 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1193 arizona_fll_clock_ok, fll);
1194 if (ret != 0) {
1195 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
1196 id, ret);
1197 }
1198
1199 regmap_update_bits(arizona->regmap, fll->base + 1,
1200 ARIZONA_FLL1_FREERUN, 0);
1201
1202 return 0;
1203 }
1204 EXPORT_SYMBOL_GPL(arizona_init_fll);
1205
1206 /**
1207 * arizona_set_output_mode - Set the mode of the specified output
1208 *
1209 * @codec: Device to configure
1210 * @output: Output number
1211 * @diff: True to set the output to differential mode
1212 *
1213 * Some systems use external analogue switches to connect more
1214 * analogue devices to the CODEC than are supported by the device. In
1215 * some systems this requires changing the switched output from single
1216 * ended to differential mode dynamically at runtime, an operation
1217 * supported using this function.
1218 *
1219 * Most systems have a single static configuration and should use
1220 * platform data instead.
1221 */
1222 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
1223 {
1224 unsigned int reg, val;
1225
1226 if (output < 1 || output > 6)
1227 return -EINVAL;
1228
1229 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
1230
1231 if (diff)
1232 val = ARIZONA_OUT1_MONO;
1233 else
1234 val = 0;
1235
1236 return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
1237 }
1238 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
1239
1240 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1241 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1242 MODULE_LICENSE("GPL");
This page took 0.057464 seconds and 5 git commands to generate.