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