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