Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
[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_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_lhpf_mode_text[] = {
230 "Low-pass", "High-pass"
231 };
232
233 const struct soc_enum arizona_lhpf1_mode =
234 SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
235 arizona_lhpf_mode_text);
236 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
237
238 const struct soc_enum arizona_lhpf2_mode =
239 SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
240 arizona_lhpf_mode_text);
241 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
242
243 const struct soc_enum arizona_lhpf3_mode =
244 SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
245 arizona_lhpf_mode_text);
246 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
247
248 const struct soc_enum arizona_lhpf4_mode =
249 SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
250 arizona_lhpf_mode_text);
251 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
252
253 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
254 int event)
255 {
256 return 0;
257 }
258 EXPORT_SYMBOL_GPL(arizona_in_ev);
259
260 int arizona_out_ev(struct snd_soc_dapm_widget *w,
261 struct snd_kcontrol *kcontrol,
262 int event)
263 {
264 return 0;
265 }
266 EXPORT_SYMBOL_GPL(arizona_out_ev);
267
268 static unsigned int arizona_sysclk_48k_rates[] = {
269 6144000,
270 12288000,
271 22579200,
272 49152000,
273 73728000,
274 98304000,
275 147456000,
276 };
277
278 static unsigned int arizona_sysclk_44k1_rates[] = {
279 5644800,
280 11289600,
281 24576000,
282 45158400,
283 67737600,
284 90316800,
285 135475200,
286 };
287
288 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
289 unsigned int freq)
290 {
291 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
292 unsigned int reg;
293 unsigned int *rates;
294 int ref, div, refclk;
295
296 switch (clk) {
297 case ARIZONA_CLK_OPCLK:
298 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
299 refclk = priv->sysclk;
300 break;
301 case ARIZONA_CLK_ASYNC_OPCLK:
302 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
303 refclk = priv->asyncclk;
304 break;
305 default:
306 return -EINVAL;
307 }
308
309 if (refclk % 8000)
310 rates = arizona_sysclk_44k1_rates;
311 else
312 rates = arizona_sysclk_48k_rates;
313
314 for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
315 rates[ref] <= refclk; ref++) {
316 div = 1;
317 while (rates[ref] / div >= freq && div < 32) {
318 if (rates[ref] / div == freq) {
319 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
320 freq);
321 snd_soc_update_bits(codec, reg,
322 ARIZONA_OPCLK_DIV_MASK |
323 ARIZONA_OPCLK_SEL_MASK,
324 (div <<
325 ARIZONA_OPCLK_DIV_SHIFT) |
326 ref);
327 return 0;
328 }
329 div++;
330 }
331 }
332
333 dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
334 return -EINVAL;
335 }
336
337 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
338 int source, unsigned int freq, int dir)
339 {
340 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
341 struct arizona *arizona = priv->arizona;
342 char *name;
343 unsigned int reg;
344 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
345 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
346 unsigned int *clk;
347
348 switch (clk_id) {
349 case ARIZONA_CLK_SYSCLK:
350 name = "SYSCLK";
351 reg = ARIZONA_SYSTEM_CLOCK_1;
352 clk = &priv->sysclk;
353 mask |= ARIZONA_SYSCLK_FRAC;
354 break;
355 case ARIZONA_CLK_ASYNCCLK:
356 name = "ASYNCCLK";
357 reg = ARIZONA_ASYNC_CLOCK_1;
358 clk = &priv->asyncclk;
359 break;
360 case ARIZONA_CLK_OPCLK:
361 case ARIZONA_CLK_ASYNC_OPCLK:
362 return arizona_set_opclk(codec, clk_id, freq);
363 default:
364 return -EINVAL;
365 }
366
367 switch (freq) {
368 case 5644800:
369 case 6144000:
370 break;
371 case 11289600:
372 case 12288000:
373 val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT;
374 break;
375 case 22579200:
376 case 24576000:
377 val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT;
378 break;
379 case 45158400:
380 case 49152000:
381 val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
382 break;
383 default:
384 return -EINVAL;
385 }
386
387 *clk = freq;
388
389 if (freq % 6144000)
390 val |= ARIZONA_SYSCLK_FRAC;
391
392 dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
393
394 return regmap_update_bits(arizona->regmap, reg, mask, val);
395 }
396 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
397
398 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
399 {
400 struct snd_soc_codec *codec = dai->codec;
401 int lrclk, bclk, mode, base;
402
403 base = dai->driver->base;
404
405 lrclk = 0;
406 bclk = 0;
407
408 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
409 case SND_SOC_DAIFMT_DSP_A:
410 mode = 0;
411 break;
412 case SND_SOC_DAIFMT_DSP_B:
413 mode = 1;
414 break;
415 case SND_SOC_DAIFMT_I2S:
416 mode = 2;
417 break;
418 case SND_SOC_DAIFMT_LEFT_J:
419 mode = 3;
420 break;
421 default:
422 arizona_aif_err(dai, "Unsupported DAI format %d\n",
423 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
424 return -EINVAL;
425 }
426
427 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
428 case SND_SOC_DAIFMT_CBS_CFS:
429 break;
430 case SND_SOC_DAIFMT_CBS_CFM:
431 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
432 break;
433 case SND_SOC_DAIFMT_CBM_CFS:
434 bclk |= ARIZONA_AIF1_BCLK_MSTR;
435 break;
436 case SND_SOC_DAIFMT_CBM_CFM:
437 bclk |= ARIZONA_AIF1_BCLK_MSTR;
438 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
439 break;
440 default:
441 arizona_aif_err(dai, "Unsupported master mode %d\n",
442 fmt & SND_SOC_DAIFMT_MASTER_MASK);
443 return -EINVAL;
444 }
445
446 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
447 case SND_SOC_DAIFMT_NB_NF:
448 break;
449 case SND_SOC_DAIFMT_IB_IF:
450 bclk |= ARIZONA_AIF1_BCLK_INV;
451 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
452 break;
453 case SND_SOC_DAIFMT_IB_NF:
454 bclk |= ARIZONA_AIF1_BCLK_INV;
455 break;
456 case SND_SOC_DAIFMT_NB_IF:
457 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
458 break;
459 default:
460 return -EINVAL;
461 }
462
463 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
464 ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
465 bclk);
466 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
467 ARIZONA_AIF1TX_LRCLK_INV |
468 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
469 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
470 ARIZONA_AIF1RX_LRCLK_INV |
471 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
472 snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
473 ARIZONA_AIF1_FMT_MASK, mode);
474
475 return 0;
476 }
477
478 static const int arizona_48k_bclk_rates[] = {
479 -1,
480 48000,
481 64000,
482 96000,
483 128000,
484 192000,
485 256000,
486 384000,
487 512000,
488 768000,
489 1024000,
490 1536000,
491 2048000,
492 3072000,
493 4096000,
494 6144000,
495 8192000,
496 12288000,
497 24576000,
498 };
499
500 static const unsigned int arizona_48k_rates[] = {
501 12000,
502 24000,
503 48000,
504 96000,
505 192000,
506 384000,
507 768000,
508 4000,
509 8000,
510 16000,
511 32000,
512 64000,
513 128000,
514 256000,
515 512000,
516 };
517
518 static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
519 .count = ARRAY_SIZE(arizona_48k_rates),
520 .list = arizona_48k_rates,
521 };
522
523 static const int arizona_44k1_bclk_rates[] = {
524 -1,
525 44100,
526 58800,
527 88200,
528 117600,
529 177640,
530 235200,
531 352800,
532 470400,
533 705600,
534 940800,
535 1411200,
536 1881600,
537 2822400,
538 3763200,
539 5644800,
540 7526400,
541 11289600,
542 22579200,
543 };
544
545 static const unsigned int arizona_44k1_rates[] = {
546 11025,
547 22050,
548 44100,
549 88200,
550 176400,
551 352800,
552 705600,
553 };
554
555 static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
556 .count = ARRAY_SIZE(arizona_44k1_rates),
557 .list = arizona_44k1_rates,
558 };
559
560 static int arizona_sr_vals[] = {
561 0,
562 12000,
563 24000,
564 48000,
565 96000,
566 192000,
567 384000,
568 768000,
569 0,
570 11025,
571 22050,
572 44100,
573 88200,
574 176400,
575 352800,
576 705600,
577 4000,
578 8000,
579 16000,
580 32000,
581 64000,
582 128000,
583 256000,
584 512000,
585 };
586
587 static int arizona_startup(struct snd_pcm_substream *substream,
588 struct snd_soc_dai *dai)
589 {
590 struct snd_soc_codec *codec = dai->codec;
591 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
592 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
593 const struct snd_pcm_hw_constraint_list *constraint;
594 unsigned int base_rate;
595
596 switch (dai_priv->clk) {
597 case ARIZONA_CLK_SYSCLK:
598 base_rate = priv->sysclk;
599 break;
600 case ARIZONA_CLK_ASYNCCLK:
601 base_rate = priv->asyncclk;
602 break;
603 default:
604 return 0;
605 }
606
607 if (base_rate % 8000)
608 constraint = &arizona_44k1_constraint;
609 else
610 constraint = &arizona_48k_constraint;
611
612 return snd_pcm_hw_constraint_list(substream->runtime, 0,
613 SNDRV_PCM_HW_PARAM_RATE,
614 constraint);
615 }
616
617 static int arizona_hw_params(struct snd_pcm_substream *substream,
618 struct snd_pcm_hw_params *params,
619 struct snd_soc_dai *dai)
620 {
621 struct snd_soc_codec *codec = dai->codec;
622 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
623 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
624 int base = dai->driver->base;
625 const int *rates;
626 int i;
627 int bclk, lrclk, wl, frame, sr_val;
628
629 if (params_rate(params) % 8000)
630 rates = &arizona_44k1_bclk_rates[0];
631 else
632 rates = &arizona_48k_bclk_rates[0];
633
634 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
635 if (rates[i] >= snd_soc_params_to_bclk(params) &&
636 rates[i] % params_rate(params) == 0) {
637 bclk = i;
638 break;
639 }
640 }
641 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
642 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
643 params_rate(params));
644 return -EINVAL;
645 }
646
647 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
648 if (arizona_sr_vals[i] == params_rate(params))
649 break;
650 if (i == ARRAY_SIZE(arizona_sr_vals)) {
651 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
652 params_rate(params));
653 return -EINVAL;
654 }
655 sr_val = i;
656
657 lrclk = snd_soc_params_to_bclk(params) / params_rate(params);
658
659 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
660 rates[bclk], rates[bclk] / lrclk);
661
662 wl = snd_pcm_format_width(params_format(params));
663 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
664
665 /*
666 * We will need to be more flexible than this in future,
667 * currently we use a single sample rate for SYSCLK.
668 */
669 switch (dai_priv->clk) {
670 case ARIZONA_CLK_SYSCLK:
671 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
672 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
673 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
674 ARIZONA_AIF1_RATE_MASK, 0);
675 break;
676 case ARIZONA_CLK_ASYNCCLK:
677 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
678 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
679 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
680 ARIZONA_AIF1_RATE_MASK, 8);
681 break;
682 default:
683 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
684 return -EINVAL;
685 }
686
687 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
688 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
689 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
690 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
691 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
692 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
693 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
694 ARIZONA_AIF1TX_WL_MASK |
695 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
696 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
697 ARIZONA_AIF1RX_WL_MASK |
698 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
699
700 return 0;
701 }
702
703 static const char *arizona_dai_clk_str(int clk_id)
704 {
705 switch (clk_id) {
706 case ARIZONA_CLK_SYSCLK:
707 return "SYSCLK";
708 case ARIZONA_CLK_ASYNCCLK:
709 return "ASYNCCLK";
710 default:
711 return "Unknown clock";
712 }
713 }
714
715 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
716 int clk_id, unsigned int freq, int dir)
717 {
718 struct snd_soc_codec *codec = dai->codec;
719 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
720 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
721 struct snd_soc_dapm_route routes[2];
722
723 switch (clk_id) {
724 case ARIZONA_CLK_SYSCLK:
725 case ARIZONA_CLK_ASYNCCLK:
726 break;
727 default:
728 return -EINVAL;
729 }
730
731 if (clk_id == dai_priv->clk)
732 return 0;
733
734 if (dai->active) {
735 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
736 dai->id);
737 return -EBUSY;
738 }
739
740 memset(&routes, 0, sizeof(routes));
741 routes[0].sink = dai->driver->capture.stream_name;
742 routes[1].sink = dai->driver->playback.stream_name;
743
744 routes[0].source = arizona_dai_clk_str(dai_priv->clk);
745 routes[1].source = arizona_dai_clk_str(dai_priv->clk);
746 snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
747
748 routes[0].source = arizona_dai_clk_str(clk_id);
749 routes[1].source = arizona_dai_clk_str(clk_id);
750 snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
751
752 return snd_soc_dapm_sync(&codec->dapm);
753 }
754
755 const struct snd_soc_dai_ops arizona_dai_ops = {
756 .startup = arizona_startup,
757 .set_fmt = arizona_set_fmt,
758 .hw_params = arizona_hw_params,
759 .set_sysclk = arizona_dai_set_sysclk,
760 };
761 EXPORT_SYMBOL_GPL(arizona_dai_ops);
762
763 int arizona_init_dai(struct arizona_priv *priv, int id)
764 {
765 struct arizona_dai_priv *dai_priv = &priv->dai[id];
766
767 dai_priv->clk = ARIZONA_CLK_SYSCLK;
768
769 return 0;
770 }
771 EXPORT_SYMBOL_GPL(arizona_init_dai);
772
773 static irqreturn_t arizona_fll_lock(int irq, void *data)
774 {
775 struct arizona_fll *fll = data;
776
777 arizona_fll_dbg(fll, "Lock status changed\n");
778
779 complete(&fll->lock);
780
781 return IRQ_HANDLED;
782 }
783
784 static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
785 {
786 struct arizona_fll *fll = data;
787
788 arizona_fll_dbg(fll, "clock OK\n");
789
790 complete(&fll->ok);
791
792 return IRQ_HANDLED;
793 }
794
795 static struct {
796 unsigned int min;
797 unsigned int max;
798 u16 fratio;
799 int ratio;
800 } fll_fratios[] = {
801 { 0, 64000, 4, 16 },
802 { 64000, 128000, 3, 8 },
803 { 128000, 256000, 2, 4 },
804 { 256000, 1000000, 1, 2 },
805 { 1000000, 13500000, 0, 1 },
806 };
807
808 struct arizona_fll_cfg {
809 int n;
810 int theta;
811 int lambda;
812 int refdiv;
813 int outdiv;
814 int fratio;
815 };
816
817 static int arizona_calc_fll(struct arizona_fll *fll,
818 struct arizona_fll_cfg *cfg,
819 unsigned int Fref,
820 unsigned int Fout)
821 {
822 unsigned int target, div, gcd_fll;
823 int i, ratio;
824
825 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
826
827 /* Fref must be <=13.5MHz */
828 div = 1;
829 cfg->refdiv = 0;
830 while ((Fref / div) > 13500000) {
831 div *= 2;
832 cfg->refdiv++;
833
834 if (div > 8) {
835 arizona_fll_err(fll,
836 "Can't scale %dMHz in to <=13.5MHz\n",
837 Fref);
838 return -EINVAL;
839 }
840 }
841
842 /* Apply the division for our remaining calculations */
843 Fref /= div;
844
845 /* Fvco should be over the targt; don't check the upper bound */
846 div = 1;
847 while (Fout * div < 90000000 * fll->vco_mult) {
848 div++;
849 if (div > 7) {
850 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
851 Fout);
852 return -EINVAL;
853 }
854 }
855 target = Fout * div / fll->vco_mult;
856 cfg->outdiv = div;
857
858 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
859
860 /* Find an appropraite FLL_FRATIO and factor it out of the target */
861 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
862 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
863 cfg->fratio = fll_fratios[i].fratio;
864 ratio = fll_fratios[i].ratio;
865 break;
866 }
867 }
868 if (i == ARRAY_SIZE(fll_fratios)) {
869 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
870 Fref);
871 return -EINVAL;
872 }
873
874 cfg->n = target / (ratio * Fref);
875
876 if (target % Fref) {
877 gcd_fll = gcd(target, ratio * Fref);
878 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
879
880 cfg->theta = (target - (cfg->n * ratio * Fref))
881 / gcd_fll;
882 cfg->lambda = (ratio * Fref) / gcd_fll;
883 } else {
884 cfg->theta = 0;
885 cfg->lambda = 0;
886 }
887
888 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
889 cfg->n, cfg->theta, cfg->lambda);
890 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
891 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
892
893 return 0;
894
895 }
896
897 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
898 struct arizona_fll_cfg *cfg, int source)
899 {
900 regmap_update_bits(arizona->regmap, base + 3,
901 ARIZONA_FLL1_THETA_MASK, cfg->theta);
902 regmap_update_bits(arizona->regmap, base + 4,
903 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
904 regmap_update_bits(arizona->regmap, base + 5,
905 ARIZONA_FLL1_FRATIO_MASK,
906 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
907 regmap_update_bits(arizona->regmap, base + 6,
908 ARIZONA_FLL1_CLK_REF_DIV_MASK |
909 ARIZONA_FLL1_CLK_REF_SRC_MASK,
910 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
911 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
912
913 regmap_update_bits(arizona->regmap, base + 2,
914 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
915 ARIZONA_FLL1_CTRL_UPD | cfg->n);
916 }
917
918 int arizona_set_fll(struct arizona_fll *fll, int source,
919 unsigned int Fref, unsigned int Fout)
920 {
921 struct arizona *arizona = fll->arizona;
922 struct arizona_fll_cfg cfg, sync;
923 unsigned int reg, val;
924 int syncsrc;
925 bool ena;
926 int ret;
927
928 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
929 if (ret != 0) {
930 arizona_fll_err(fll, "Failed to read current state: %d\n",
931 ret);
932 return ret;
933 }
934 ena = reg & ARIZONA_FLL1_ENA;
935
936 if (Fout) {
937 /* Do we have a 32kHz reference? */
938 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
939 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
940 case ARIZONA_CLK_SRC_MCLK1:
941 case ARIZONA_CLK_SRC_MCLK2:
942 syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
943 break;
944 default:
945 syncsrc = -1;
946 }
947
948 if (source == syncsrc)
949 syncsrc = -1;
950
951 if (syncsrc >= 0) {
952 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
953 if (ret != 0)
954 return ret;
955
956 ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
957 if (ret != 0)
958 return ret;
959 } else {
960 ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
961 if (ret != 0)
962 return ret;
963 }
964 } else {
965 regmap_update_bits(arizona->regmap, fll->base + 1,
966 ARIZONA_FLL1_ENA, 0);
967 regmap_update_bits(arizona->regmap, fll->base + 0x11,
968 ARIZONA_FLL1_SYNC_ENA, 0);
969
970 if (ena)
971 pm_runtime_put_autosuspend(arizona->dev);
972
973 return 0;
974 }
975
976 regmap_update_bits(arizona->regmap, fll->base + 5,
977 ARIZONA_FLL1_OUTDIV_MASK,
978 cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
979
980 if (syncsrc >= 0) {
981 arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
982 arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
983 } else {
984 arizona_apply_fll(arizona, fll->base, &cfg, source);
985 }
986
987 if (!ena)
988 pm_runtime_get(arizona->dev);
989
990 /* Clear any pending completions */
991 try_wait_for_completion(&fll->ok);
992
993 regmap_update_bits(arizona->regmap, fll->base + 1,
994 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
995 if (syncsrc >= 0)
996 regmap_update_bits(arizona->regmap, fll->base + 0x11,
997 ARIZONA_FLL1_SYNC_ENA,
998 ARIZONA_FLL1_SYNC_ENA);
999
1000 ret = wait_for_completion_timeout(&fll->ok,
1001 msecs_to_jiffies(25));
1002 if (ret == 0)
1003 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1004
1005 return 0;
1006 }
1007 EXPORT_SYMBOL_GPL(arizona_set_fll);
1008
1009 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1010 int ok_irq, struct arizona_fll *fll)
1011 {
1012 int ret;
1013
1014 init_completion(&fll->lock);
1015 init_completion(&fll->ok);
1016
1017 fll->id = id;
1018 fll->base = base;
1019 fll->arizona = arizona;
1020
1021 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1022 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1023 "FLL%d clock OK", id);
1024
1025 ret = arizona_request_irq(arizona, lock_irq, fll->lock_name,
1026 arizona_fll_lock, fll);
1027 if (ret != 0) {
1028 dev_err(arizona->dev, "Failed to get FLL%d lock IRQ: %d\n",
1029 id, ret);
1030 }
1031
1032 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1033 arizona_fll_clock_ok, fll);
1034 if (ret != 0) {
1035 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
1036 id, ret);
1037 }
1038
1039 return 0;
1040 }
1041 EXPORT_SYMBOL_GPL(arizona_init_fll);
1042
1043 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1044 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1045 MODULE_LICENSE("GPL");
This page took 0.052345 seconds and 6 git commands to generate.