]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/blob - sound/soc/codecs/arizona.c
Merge remote-tracking branch 'tero/pm-linux-3.8.y' into av-3.8.y
[android-sdk/kernel-video.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  */
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>
20 #include <linux/mfd/arizona/core.h>
21 #include <linux/mfd/arizona/registers.h>
23 #include "arizona.h"
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
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__)
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__)
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);
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);
274 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
275 EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
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 };
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);
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);
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);
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);
302 static const char *arizona_lhpf_mode_text[] = {
303         "Low-pass", "High-pass"
304 };
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);
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);
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);
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);
326 static const char *arizona_ng_hold_text[] = {
327         "30ms", "120ms", "250ms", "500ms",
328 };
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);
335 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
336                   int event)
338         return 0;
340 EXPORT_SYMBOL_GPL(arizona_in_ev);
342 int arizona_out_ev(struct snd_soc_dapm_widget *w,
343                    struct snd_kcontrol *kcontrol,
344                    int event)
346         return 0;
348 EXPORT_SYMBOL_GPL(arizona_out_ev);
350 static unsigned int arizona_sysclk_48k_rates[] = {
351         6144000,
352         12288000,
353         24576000,
354         49152000,
355         73728000,
356         98304000,
357         147456000,
358 };
360 static unsigned int arizona_sysclk_44k1_rates[] = {
361         5644800,
362         11289600,
363         22579200,
364         45158400,
365         67737600,
366         90316800,
367         135475200,
368 };
370 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
371                              unsigned int freq)
373         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
374         unsigned int reg;
375         unsigned int *rates;
376         int ref, div, refclk;
378         switch (clk) {
379         case ARIZONA_CLK_OPCLK:
380                 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
381                 refclk = priv->sysclk;
382                 break;
383         case ARIZONA_CLK_ASYNC_OPCLK:
384                 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
385                 refclk = priv->asyncclk;
386                 break;
387         default:
388                 return -EINVAL;
389         }
391         if (refclk % 8000)
392                 rates = arizona_sysclk_44k1_rates;
393         else
394                 rates = arizona_sysclk_48k_rates;
396         for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
397                      rates[ref] <= refclk; ref++) {
398                 div = 1;
399                 while (rates[ref] / div >= freq && div < 32) {
400                         if (rates[ref] / div == freq) {
401                                 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
402                                         freq);
403                                 snd_soc_update_bits(codec, reg,
404                                                     ARIZONA_OPCLK_DIV_MASK |
405                                                     ARIZONA_OPCLK_SEL_MASK,
406                                                     (div <<
407                                                      ARIZONA_OPCLK_DIV_SHIFT) |
408                                                     ref);
409                                 return 0;
410                         }
411                         div++;
412                 }
413         }
415         dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
416         return -EINVAL;
419 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
420                        int source, unsigned int freq, int dir)
422         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
423         struct arizona *arizona = priv->arizona;
424         char *name;
425         unsigned int reg;
426         unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
427         unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
428         unsigned int *clk;
430         switch (clk_id) {
431         case ARIZONA_CLK_SYSCLK:
432                 name = "SYSCLK";
433                 reg = ARIZONA_SYSTEM_CLOCK_1;
434                 clk = &priv->sysclk;
435                 mask |= ARIZONA_SYSCLK_FRAC;
436                 break;
437         case ARIZONA_CLK_ASYNCCLK:
438                 name = "ASYNCCLK";
439                 reg = ARIZONA_ASYNC_CLOCK_1;
440                 clk = &priv->asyncclk;
441                 break;
442         case ARIZONA_CLK_OPCLK:
443         case ARIZONA_CLK_ASYNC_OPCLK:
444                 return arizona_set_opclk(codec, clk_id, freq);
445         default:
446                 return -EINVAL;
447         }
449         switch (freq) {
450         case  5644800:
451         case  6144000:
452                 break;
453         case 11289600:
454         case 12288000:
455                 val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT;
456                 break;
457         case 22579200:
458         case 24576000:
459                 val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT;
460                 break;
461         case 45158400:
462         case 49152000:
463                 val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
464                 break;
465         case 67737600:
466         case 73728000:
467                 val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT;
468                 break;
469         case 90316800:
470         case 98304000:
471                 val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT;
472                 break;
473         case 135475200:
474         case 147456000:
475                 val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT;
476                 break;
477         case 0:
478                 dev_dbg(arizona->dev, "%s cleared\n", name);
479                 *clk = freq;
480                 return 0;
481         default:
482                 return -EINVAL;
483         }
485         *clk = freq;
487         if (freq % 6144000)
488                 val |= ARIZONA_SYSCLK_FRAC;
490         dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
492         return regmap_update_bits(arizona->regmap, reg, mask, val);
494 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
496 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
498         struct snd_soc_codec *codec = dai->codec;
499         int lrclk, bclk, mode, base;
501         base = dai->driver->base;
503         lrclk = 0;
504         bclk = 0;
506         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
507         case SND_SOC_DAIFMT_DSP_A:
508                 mode = 0;
509                 break;
510         case SND_SOC_DAIFMT_I2S:
511                 mode = 2;
512                 break;
513         default:
514                 arizona_aif_err(dai, "Unsupported DAI format %d\n",
515                                 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
516                 return -EINVAL;
517         }
519         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
520         case SND_SOC_DAIFMT_CBS_CFS:
521                 break;
522         case SND_SOC_DAIFMT_CBS_CFM:
523                 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
524                 break;
525         case SND_SOC_DAIFMT_CBM_CFS:
526                 bclk |= ARIZONA_AIF1_BCLK_MSTR;
527                 break;
528         case SND_SOC_DAIFMT_CBM_CFM:
529                 bclk |= ARIZONA_AIF1_BCLK_MSTR;
530                 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
531                 break;
532         default:
533                 arizona_aif_err(dai, "Unsupported master mode %d\n",
534                                 fmt & SND_SOC_DAIFMT_MASTER_MASK);
535                 return -EINVAL;
536         }
538         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
539         case SND_SOC_DAIFMT_NB_NF:
540                 break;
541         case SND_SOC_DAIFMT_IB_IF:
542                 bclk |= ARIZONA_AIF1_BCLK_INV;
543                 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
544                 break;
545         case SND_SOC_DAIFMT_IB_NF:
546                 bclk |= ARIZONA_AIF1_BCLK_INV;
547                 break;
548         case SND_SOC_DAIFMT_NB_IF:
549                 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
550                 break;
551         default:
552                 return -EINVAL;
553         }
555         snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
556                             ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
557                             bclk);
558         snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
559                             ARIZONA_AIF1TX_LRCLK_INV |
560                             ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
561         snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
562                             ARIZONA_AIF1RX_LRCLK_INV |
563                             ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
564         snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
565                             ARIZONA_AIF1_FMT_MASK, mode);
567         return 0;
570 static const int arizona_48k_bclk_rates[] = {
571         -1,
572         48000,
573         64000,
574         96000,
575         128000,
576         192000,
577         256000,
578         384000,
579         512000,
580         768000,
581         1024000,
582         1536000,
583         2048000,
584         3072000,
585         4096000,
586         6144000,
587         8192000,
588         12288000,
589         24576000,
590 };
592 static const unsigned int arizona_48k_rates[] = {
593         12000,
594         24000,
595         48000,
596         96000,
597         192000,
598         384000,
599         768000,
600         4000,
601         8000,
602         16000,
603         32000,
604         64000,
605         128000,
606         256000,
607         512000,
608 };
610 static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
611         .count  = ARRAY_SIZE(arizona_48k_rates),
612         .list   = arizona_48k_rates,
613 };
615 static const int arizona_44k1_bclk_rates[] = {
616         -1,
617         44100,
618         58800,
619         88200,
620         117600,
621         177640,
622         235200,
623         352800,
624         470400,
625         705600,
626         940800,
627         1411200,
628         1881600,
629         2822400,
630         3763200,
631         5644800,
632         7526400,
633         11289600,
634         22579200,
635 };
637 static const unsigned int arizona_44k1_rates[] = {
638         11025,
639         22050,
640         44100,
641         88200,
642         176400,
643         352800,
644         705600,
645 };
647 static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
648         .count  = ARRAY_SIZE(arizona_44k1_rates),
649         .list   = arizona_44k1_rates,
650 };
652 static int arizona_sr_vals[] = {
653         0,
654         12000,
655         24000,
656         48000,
657         96000,
658         192000,
659         384000,
660         768000,
661         0,
662         11025,
663         22050,
664         44100,
665         88200,
666         176400,
667         352800,
668         705600,
669         4000,
670         8000,
671         16000,
672         32000,
673         64000,
674         128000,
675         256000,
676         512000,
677 };
679 static int arizona_startup(struct snd_pcm_substream *substream,
680                            struct snd_soc_dai *dai)
682         struct snd_soc_codec *codec = dai->codec;
683         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
684         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
685         const struct snd_pcm_hw_constraint_list *constraint;
686         unsigned int base_rate;
688         switch (dai_priv->clk) {
689         case ARIZONA_CLK_SYSCLK:
690                 base_rate = priv->sysclk;
691                 break;
692         case ARIZONA_CLK_ASYNCCLK:
693                 base_rate = priv->asyncclk;
694                 break;
695         default:
696                 return 0;
697         }
699         if (base_rate == 0)
700                 return 0;
702         if (base_rate % 8000)
703                 constraint = &arizona_44k1_constraint;
704         else
705                 constraint = &arizona_48k_constraint;
707         return snd_pcm_hw_constraint_list(substream->runtime, 0,
708                                           SNDRV_PCM_HW_PARAM_RATE,
709                                           constraint);
712 static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
713                                   struct snd_pcm_hw_params *params,
714                                   struct snd_soc_dai *dai)
716         struct snd_soc_codec *codec = dai->codec;
717         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
718         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
719         int base = dai->driver->base;
720         int i, sr_val;
722         /*
723          * We will need to be more flexible than this in future,
724          * currently we use a single sample rate for SYSCLK.
725          */
726         for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
727                 if (arizona_sr_vals[i] == params_rate(params))
728                         break;
729         if (i == ARRAY_SIZE(arizona_sr_vals)) {
730                 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
731                                 params_rate(params));
732                 return -EINVAL;
733         }
734         sr_val = i;
736         switch (dai_priv->clk) {
737         case ARIZONA_CLK_SYSCLK:
738                 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
739                                     ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
740                 if (base)
741                         snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
742                                             ARIZONA_AIF1_RATE_MASK, 0);
743                 break;
744         case ARIZONA_CLK_ASYNCCLK:
745                 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
746                                     ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
747                 if (base)
748                         snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
749                                             ARIZONA_AIF1_RATE_MASK,
750                                             8 << ARIZONA_AIF1_RATE_SHIFT);
751                 break;
752         default:
753                 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
754                 return -EINVAL;
755         }
757         return 0;
760 static int arizona_hw_params(struct snd_pcm_substream *substream,
761                              struct snd_pcm_hw_params *params,
762                              struct snd_soc_dai *dai)
764         struct snd_soc_codec *codec = dai->codec;
765         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
766         struct arizona *arizona = priv->arizona;
767         int base = dai->driver->base;
768         const int *rates;
769         int i, ret;
770         int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
771         int bclk, lrclk, wl, frame, bclk_target;
773         if (params_rate(params) % 8000)
774                 rates = &arizona_44k1_bclk_rates[0];
775         else
776                 rates = &arizona_48k_bclk_rates[0];
778         bclk_target = snd_soc_params_to_bclk(params);
779         if (chan_limit && chan_limit < params_channels(params)) {
780                 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
781                 bclk_target /= params_channels(params);
782                 bclk_target *= chan_limit;
783         }
785         for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
786                 if (rates[i] >= bclk_target &&
787                     rates[i] % params_rate(params) == 0) {
788                         bclk = i;
789                         break;
790                 }
791         }
792         if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
793                 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
794                                 params_rate(params));
795                 return -EINVAL;
796         }
798         lrclk = rates[bclk] / params_rate(params);
800         arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
801                         rates[bclk], rates[bclk] / lrclk);
803         wl = snd_pcm_format_width(params_format(params));
804         frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
806         ret = arizona_hw_params_rate(substream, params, dai);
807         if (ret != 0)
808                 return ret;
810         snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
811                             ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
812         snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
813                             ARIZONA_AIF1TX_BCPF_MASK, lrclk);
814         snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
815                             ARIZONA_AIF1RX_BCPF_MASK, lrclk);
816         snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
817                             ARIZONA_AIF1TX_WL_MASK |
818                             ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
819         snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
820                             ARIZONA_AIF1RX_WL_MASK |
821                             ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
823         return 0;
826 static const char *arizona_dai_clk_str(int clk_id)
828         switch (clk_id) {
829         case ARIZONA_CLK_SYSCLK:
830                 return "SYSCLK";
831         case ARIZONA_CLK_ASYNCCLK:
832                 return "ASYNCCLK";
833         default:
834                 return "Unknown clock";
835         }
838 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
839                                   int clk_id, unsigned int freq, int dir)
841         struct snd_soc_codec *codec = dai->codec;
842         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
843         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
844         struct snd_soc_dapm_route routes[2];
846         switch (clk_id) {
847         case ARIZONA_CLK_SYSCLK:
848         case ARIZONA_CLK_ASYNCCLK:
849                 break;
850         default:
851                 return -EINVAL;
852         }
854         if (clk_id == dai_priv->clk)
855                 return 0;
857         if (dai->active) {
858                 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
859                         dai->id);
860                 return -EBUSY;
861         }
863         dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
864                 arizona_dai_clk_str(clk_id));
866         memset(&routes, 0, sizeof(routes));
867         routes[0].sink = dai->driver->capture.stream_name;
868         routes[1].sink = dai->driver->playback.stream_name;
870         routes[0].source = arizona_dai_clk_str(dai_priv->clk);
871         routes[1].source = arizona_dai_clk_str(dai_priv->clk);
872         snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
874         routes[0].source = arizona_dai_clk_str(clk_id);
875         routes[1].source = arizona_dai_clk_str(clk_id);
876         snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
878         dai_priv->clk = clk_id;
880         return snd_soc_dapm_sync(&codec->dapm);
883 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
885         struct snd_soc_codec *codec = dai->codec;
886         int base = dai->driver->base;
887         unsigned int reg;
889         if (tristate)
890                 reg = ARIZONA_AIF1_TRI;
891         else
892                 reg = 0;
894         return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
895                                    ARIZONA_AIF1_TRI, reg);
898 const struct snd_soc_dai_ops arizona_dai_ops = {
899         .startup = arizona_startup,
900         .set_fmt = arizona_set_fmt,
901         .hw_params = arizona_hw_params,
902         .set_sysclk = arizona_dai_set_sysclk,
903         .set_tristate = arizona_set_tristate,
904 };
905 EXPORT_SYMBOL_GPL(arizona_dai_ops);
907 int arizona_init_dai(struct arizona_priv *priv, int id)
909         struct arizona_dai_priv *dai_priv = &priv->dai[id];
911         dai_priv->clk = ARIZONA_CLK_SYSCLK;
913         return 0;
915 EXPORT_SYMBOL_GPL(arizona_init_dai);
917 static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
919         struct arizona_fll *fll = data;
921         arizona_fll_dbg(fll, "clock OK\n");
923         complete(&fll->ok);
925         return IRQ_HANDLED;
928 static struct {
929         unsigned int min;
930         unsigned int max;
931         u16 fratio;
932         int ratio;
933 } fll_fratios[] = {
934         {       0,    64000, 4, 16 },
935         {   64000,   128000, 3,  8 },
936         {  128000,   256000, 2,  4 },
937         {  256000,  1000000, 1,  2 },
938         { 1000000, 13500000, 0,  1 },
939 };
941 struct arizona_fll_cfg {
942         int n;
943         int theta;
944         int lambda;
945         int refdiv;
946         int outdiv;
947         int fratio;
948 };
950 static int arizona_calc_fll(struct arizona_fll *fll,
951                             struct arizona_fll_cfg *cfg,
952                             unsigned int Fref,
953                             unsigned int Fout)
955         unsigned int target, div, gcd_fll;
956         int i, ratio;
958         arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
960         /* Fref must be <=13.5MHz */
961         div = 1;
962         cfg->refdiv = 0;
963         while ((Fref / div) > 13500000) {
964                 div *= 2;
965                 cfg->refdiv++;
967                 if (div > 8) {
968                         arizona_fll_err(fll,
969                                         "Can't scale %dMHz in to <=13.5MHz\n",
970                                         Fref);
971                         return -EINVAL;
972                 }
973         }
975         /* Apply the division for our remaining calculations */
976         Fref /= div;
978         /* Fvco should be over the targt; don't check the upper bound */
979         div = 1;
980         while (Fout * div < 90000000 * fll->vco_mult) {
981                 div++;
982                 if (div > 7) {
983                         arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
984                                         Fout);
985                         return -EINVAL;
986                 }
987         }
988         target = Fout * div / fll->vco_mult;
989         cfg->outdiv = div;
991         arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
993         /* Find an appropraite FLL_FRATIO and factor it out of the target */
994         for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
995                 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
996                         cfg->fratio = fll_fratios[i].fratio;
997                         ratio = fll_fratios[i].ratio;
998                         break;
999                 }
1000         }
1001         if (i == ARRAY_SIZE(fll_fratios)) {
1002                 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1003                                 Fref);
1004                 return -EINVAL;
1005         }
1007         cfg->n = target / (ratio * Fref);
1009         if (target % (ratio * Fref)) {
1010                 gcd_fll = gcd(target, ratio * Fref);
1011                 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
1013                 cfg->theta = (target - (cfg->n * ratio * Fref))
1014                         / gcd_fll;
1015                 cfg->lambda = (ratio * Fref) / gcd_fll;
1016         } else {
1017                 cfg->theta = 0;
1018                 cfg->lambda = 0;
1019         }
1021         /* Round down to 16bit range with cost of accuracy lost.
1022          * Denominator must be bigger than numerator so we only
1023          * take care of it.
1024          */
1025         while (cfg->lambda >= (1 << 16)) {
1026                 cfg->theta >>= 1;
1027                 cfg->lambda >>= 1;
1028         }
1030         arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
1031                         cfg->n, cfg->theta, cfg->lambda);
1032         arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1033                         cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
1035         return 0;
1039 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1040                               struct arizona_fll_cfg *cfg, int source)
1042         regmap_update_bits(arizona->regmap, base + 3,
1043                            ARIZONA_FLL1_THETA_MASK, cfg->theta);
1044         regmap_update_bits(arizona->regmap, base + 4,
1045                            ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
1046         regmap_update_bits(arizona->regmap, base + 5,
1047                            ARIZONA_FLL1_FRATIO_MASK,
1048                            cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
1049         regmap_update_bits(arizona->regmap, base + 6,
1050                            ARIZONA_FLL1_CLK_REF_DIV_MASK |
1051                            ARIZONA_FLL1_CLK_REF_SRC_MASK,
1052                            cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1053                            source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1055         regmap_update_bits(arizona->regmap, base + 2,
1056                            ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1057                            ARIZONA_FLL1_CTRL_UPD | cfg->n);
1060 int arizona_set_fll(struct arizona_fll *fll, int source,
1061                     unsigned int Fref, unsigned int Fout)
1063         struct arizona *arizona = fll->arizona;
1064         struct arizona_fll_cfg cfg, sync;
1065         unsigned int reg, val;
1066         int syncsrc;
1067         bool ena;
1068         int ret;
1070         if (fll->fref == Fref && fll->fout == Fout)
1071                 return 0;
1073         ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1074         if (ret != 0) {
1075                 arizona_fll_err(fll, "Failed to read current state: %d\n",
1076                                 ret);
1077                 return ret;
1078         }
1079         ena = reg & ARIZONA_FLL1_ENA;
1081         if (Fout) {
1082                 /* Do we have a 32kHz reference? */
1083                 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1084                 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1085                 case ARIZONA_CLK_SRC_MCLK1:
1086                 case ARIZONA_CLK_SRC_MCLK2:
1087                         syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
1088                         break;
1089                 default:
1090                         syncsrc = -1;
1091                 }
1093                 if (source == syncsrc)
1094                         syncsrc = -1;
1096                 if (syncsrc >= 0) {
1097                         ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1098                         if (ret != 0)
1099                                 return ret;
1101                         ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
1102                         if (ret != 0)
1103                                 return ret;
1104                 } else {
1105                         ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
1106                         if (ret != 0)
1107                                 return ret;
1108                 }
1109         } else {
1110                 regmap_update_bits(arizona->regmap, fll->base + 1,
1111                                    ARIZONA_FLL1_ENA, 0);
1112                 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1113                                    ARIZONA_FLL1_SYNC_ENA, 0);
1115                 if (ena)
1116                         pm_runtime_put_autosuspend(arizona->dev);
1118                 fll->fref = Fref;
1119                 fll->fout = Fout;
1121                 return 0;
1122         }
1124         regmap_update_bits(arizona->regmap, fll->base + 5,
1125                            ARIZONA_FLL1_OUTDIV_MASK,
1126                            cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1128         if (syncsrc >= 0) {
1129                 arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
1130                 arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
1131         } else {
1132                 arizona_apply_fll(arizona, fll->base, &cfg, source);
1133         }
1135         if (!ena)
1136                 pm_runtime_get(arizona->dev);
1138         /* Clear any pending completions */
1139         try_wait_for_completion(&fll->ok);
1141         regmap_update_bits(arizona->regmap, fll->base + 1,
1142                            ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1143         if (syncsrc >= 0)
1144                 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1145                                    ARIZONA_FLL1_SYNC_ENA,
1146                                    ARIZONA_FLL1_SYNC_ENA);
1148         ret = wait_for_completion_timeout(&fll->ok,
1149                                           msecs_to_jiffies(250));
1150         if (ret == 0)
1151                 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1153         fll->fref = Fref;
1154         fll->fout = Fout;
1156         return 0;
1158 EXPORT_SYMBOL_GPL(arizona_set_fll);
1160 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1161                      int ok_irq, struct arizona_fll *fll)
1163         int ret;
1165         init_completion(&fll->ok);
1167         fll->id = id;
1168         fll->base = base;
1169         fll->arizona = arizona;
1171         snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1172         snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1173                  "FLL%d clock OK", id);
1175         ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1176                                   arizona_fll_clock_ok, fll);
1177         if (ret != 0) {
1178                 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
1179                         id, ret);
1180         }
1182         regmap_update_bits(arizona->regmap, fll->base + 1,
1183                            ARIZONA_FLL1_FREERUN, 0);
1185         return 0;
1187 EXPORT_SYMBOL_GPL(arizona_init_fll);
1189 /**
1190  * arizona_set_output_mode - Set the mode of the specified output
1191  *
1192  * @codec: Device to configure
1193  * @output: Output number
1194  * @diff: True to set the output to differential mode
1195  *
1196  * Some systems use external analogue switches to connect more
1197  * analogue devices to the CODEC than are supported by the device.  In
1198  * some systems this requires changing the switched output from single
1199  * ended to differential mode dynamically at runtime, an operation
1200  * supported using this function.
1201  *
1202  * Most systems have a single static configuration and should use
1203  * platform data instead.
1204  */
1205 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
1207         unsigned int reg, val;
1209         if (output < 1 || output > 6)
1210                 return -EINVAL;
1212         reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
1214         if (diff)
1215                 val = ARIZONA_OUT1_MONO;
1216         else
1217                 val = 0;
1219         return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
1221 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
1223 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1224 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1225 MODULE_LICENSE("GPL");