]> Pileus Git - ~andy/linux/blob - sound/soc/codecs/arizona.c
powerpc: Add length setting to set_dawr
[~andy/linux] / 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_I2S:
450                 mode = 2;
451                 break;
452         default:
453                 arizona_aif_err(dai, "Unsupported DAI format %d\n",
454                                 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
455                 return -EINVAL;
456         }
457
458         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
459         case SND_SOC_DAIFMT_CBS_CFS:
460                 break;
461         case SND_SOC_DAIFMT_CBS_CFM:
462                 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
463                 break;
464         case SND_SOC_DAIFMT_CBM_CFS:
465                 bclk |= ARIZONA_AIF1_BCLK_MSTR;
466                 break;
467         case SND_SOC_DAIFMT_CBM_CFM:
468                 bclk |= ARIZONA_AIF1_BCLK_MSTR;
469                 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
470                 break;
471         default:
472                 arizona_aif_err(dai, "Unsupported master mode %d\n",
473                                 fmt & SND_SOC_DAIFMT_MASTER_MASK);
474                 return -EINVAL;
475         }
476
477         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
478         case SND_SOC_DAIFMT_NB_NF:
479                 break;
480         case SND_SOC_DAIFMT_IB_IF:
481                 bclk |= ARIZONA_AIF1_BCLK_INV;
482                 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
483                 break;
484         case SND_SOC_DAIFMT_IB_NF:
485                 bclk |= ARIZONA_AIF1_BCLK_INV;
486                 break;
487         case SND_SOC_DAIFMT_NB_IF:
488                 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
489                 break;
490         default:
491                 return -EINVAL;
492         }
493
494         snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
495                             ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
496                             bclk);
497         snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
498                             ARIZONA_AIF1TX_LRCLK_INV |
499                             ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
500         snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
501                             ARIZONA_AIF1RX_LRCLK_INV |
502                             ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
503         snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
504                             ARIZONA_AIF1_FMT_MASK, mode);
505
506         return 0;
507 }
508
509 static const int arizona_48k_bclk_rates[] = {
510         -1,
511         48000,
512         64000,
513         96000,
514         128000,
515         192000,
516         256000,
517         384000,
518         512000,
519         768000,
520         1024000,
521         1536000,
522         2048000,
523         3072000,
524         4096000,
525         6144000,
526         8192000,
527         12288000,
528         24576000,
529 };
530
531 static const unsigned int arizona_48k_rates[] = {
532         12000,
533         24000,
534         48000,
535         96000,
536         192000,
537         384000,
538         768000,
539         4000,
540         8000,
541         16000,
542         32000,
543         64000,
544         128000,
545         256000,
546         512000,
547 };
548
549 static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
550         .count  = ARRAY_SIZE(arizona_48k_rates),
551         .list   = arizona_48k_rates,
552 };
553
554 static const int arizona_44k1_bclk_rates[] = {
555         -1,
556         44100,
557         58800,
558         88200,
559         117600,
560         177640,
561         235200,
562         352800,
563         470400,
564         705600,
565         940800,
566         1411200,
567         1881600,
568         2822400,
569         3763200,
570         5644800,
571         7526400,
572         11289600,
573         22579200,
574 };
575
576 static const unsigned int arizona_44k1_rates[] = {
577         11025,
578         22050,
579         44100,
580         88200,
581         176400,
582         352800,
583         705600,
584 };
585
586 static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
587         .count  = ARRAY_SIZE(arizona_44k1_rates),
588         .list   = arizona_44k1_rates,
589 };
590
591 static int arizona_sr_vals[] = {
592         0,
593         12000,
594         24000,
595         48000,
596         96000,
597         192000,
598         384000,
599         768000,
600         0,
601         11025,
602         22050,
603         44100,
604         88200,
605         176400,
606         352800,
607         705600,
608         4000,
609         8000,
610         16000,
611         32000,
612         64000,
613         128000,
614         256000,
615         512000,
616 };
617
618 static int arizona_startup(struct snd_pcm_substream *substream,
619                            struct snd_soc_dai *dai)
620 {
621         struct snd_soc_codec *codec = dai->codec;
622         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
623         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
624         const struct snd_pcm_hw_constraint_list *constraint;
625         unsigned int base_rate;
626
627         switch (dai_priv->clk) {
628         case ARIZONA_CLK_SYSCLK:
629                 base_rate = priv->sysclk;
630                 break;
631         case ARIZONA_CLK_ASYNCCLK:
632                 base_rate = priv->asyncclk;
633                 break;
634         default:
635                 return 0;
636         }
637
638         if (base_rate % 8000)
639                 constraint = &arizona_44k1_constraint;
640         else
641                 constraint = &arizona_48k_constraint;
642
643         return snd_pcm_hw_constraint_list(substream->runtime, 0,
644                                           SNDRV_PCM_HW_PARAM_RATE,
645                                           constraint);
646 }
647
648 static int arizona_hw_params(struct snd_pcm_substream *substream,
649                              struct snd_pcm_hw_params *params,
650                              struct snd_soc_dai *dai)
651 {
652         struct snd_soc_codec *codec = dai->codec;
653         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
654         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
655         int base = dai->driver->base;
656         const int *rates;
657         int i;
658         int bclk, lrclk, wl, frame, sr_val;
659
660         if (params_rate(params) % 8000)
661                 rates = &arizona_44k1_bclk_rates[0];
662         else
663                 rates = &arizona_48k_bclk_rates[0];
664
665         for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
666                 if (rates[i] >= snd_soc_params_to_bclk(params) &&
667                     rates[i] % params_rate(params) == 0) {
668                         bclk = i;
669                         break;
670                 }
671         }
672         if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
673                 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
674                                 params_rate(params));
675                 return -EINVAL;
676         }
677
678         for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
679                 if (arizona_sr_vals[i] == params_rate(params))
680                         break;
681         if (i == ARRAY_SIZE(arizona_sr_vals)) {
682                 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
683                                 params_rate(params));
684                 return -EINVAL;
685         }
686         sr_val = i;
687
688         lrclk = snd_soc_params_to_bclk(params) / params_rate(params);
689
690         arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
691                         rates[bclk], rates[bclk] / lrclk);
692
693         wl = snd_pcm_format_width(params_format(params));
694         frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
695
696         /*
697          * We will need to be more flexible than this in future,
698          * currently we use a single sample rate for SYSCLK.
699          */
700         switch (dai_priv->clk) {
701         case ARIZONA_CLK_SYSCLK:
702                 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
703                                     ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
704                 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
705                                     ARIZONA_AIF1_RATE_MASK, 0);
706                 break;
707         case ARIZONA_CLK_ASYNCCLK:
708                 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
709                                     ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
710                 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
711                                     ARIZONA_AIF1_RATE_MASK,
712                                     8 << ARIZONA_AIF1_RATE_SHIFT);
713                 break;
714         default:
715                 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
716                 return -EINVAL;
717         }
718
719         snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
720                             ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
721         snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
722                             ARIZONA_AIF1TX_BCPF_MASK, lrclk);
723         snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
724                             ARIZONA_AIF1RX_BCPF_MASK, lrclk);
725         snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
726                             ARIZONA_AIF1TX_WL_MASK |
727                             ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
728         snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
729                             ARIZONA_AIF1RX_WL_MASK |
730                             ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
731
732         return 0;
733 }
734
735 static const char *arizona_dai_clk_str(int clk_id)
736 {
737         switch (clk_id) {
738         case ARIZONA_CLK_SYSCLK:
739                 return "SYSCLK";
740         case ARIZONA_CLK_ASYNCCLK:
741                 return "ASYNCCLK";
742         default:
743                 return "Unknown clock";
744         }
745 }
746
747 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
748                                   int clk_id, unsigned int freq, int dir)
749 {
750         struct snd_soc_codec *codec = dai->codec;
751         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
752         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
753         struct snd_soc_dapm_route routes[2];
754
755         switch (clk_id) {
756         case ARIZONA_CLK_SYSCLK:
757         case ARIZONA_CLK_ASYNCCLK:
758                 break;
759         default:
760                 return -EINVAL;
761         }
762
763         if (clk_id == dai_priv->clk)
764                 return 0;
765
766         if (dai->active) {
767                 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
768                         dai->id);
769                 return -EBUSY;
770         }
771
772         dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
773                 arizona_dai_clk_str(clk_id));
774
775         memset(&routes, 0, sizeof(routes));
776         routes[0].sink = dai->driver->capture.stream_name;
777         routes[1].sink = dai->driver->playback.stream_name;
778
779         routes[0].source = arizona_dai_clk_str(dai_priv->clk);
780         routes[1].source = arizona_dai_clk_str(dai_priv->clk);
781         snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
782
783         routes[0].source = arizona_dai_clk_str(clk_id);
784         routes[1].source = arizona_dai_clk_str(clk_id);
785         snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
786
787         dai_priv->clk = clk_id;
788
789         return snd_soc_dapm_sync(&codec->dapm);
790 }
791
792 const struct snd_soc_dai_ops arizona_dai_ops = {
793         .startup = arizona_startup,
794         .set_fmt = arizona_set_fmt,
795         .hw_params = arizona_hw_params,
796         .set_sysclk = arizona_dai_set_sysclk,
797 };
798 EXPORT_SYMBOL_GPL(arizona_dai_ops);
799
800 int arizona_init_dai(struct arizona_priv *priv, int id)
801 {
802         struct arizona_dai_priv *dai_priv = &priv->dai[id];
803
804         dai_priv->clk = ARIZONA_CLK_SYSCLK;
805
806         return 0;
807 }
808 EXPORT_SYMBOL_GPL(arizona_init_dai);
809
810 static irqreturn_t arizona_fll_lock(int irq, void *data)
811 {
812         struct arizona_fll *fll = data;
813
814         arizona_fll_dbg(fll, "Lock status changed\n");
815
816         complete(&fll->lock);
817
818         return IRQ_HANDLED;
819 }
820
821 static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
822 {
823         struct arizona_fll *fll = data;
824
825         arizona_fll_dbg(fll, "clock OK\n");
826
827         complete(&fll->ok);
828
829         return IRQ_HANDLED;
830 }
831
832 static struct {
833         unsigned int min;
834         unsigned int max;
835         u16 fratio;
836         int ratio;
837 } fll_fratios[] = {
838         {       0,    64000, 4, 16 },
839         {   64000,   128000, 3,  8 },
840         {  128000,   256000, 2,  4 },
841         {  256000,  1000000, 1,  2 },
842         { 1000000, 13500000, 0,  1 },
843 };
844
845 struct arizona_fll_cfg {
846         int n;
847         int theta;
848         int lambda;
849         int refdiv;
850         int outdiv;
851         int fratio;
852 };
853
854 static int arizona_calc_fll(struct arizona_fll *fll,
855                             struct arizona_fll_cfg *cfg,
856                             unsigned int Fref,
857                             unsigned int Fout)
858 {
859         unsigned int target, div, gcd_fll;
860         int i, ratio;
861
862         arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
863
864         /* Fref must be <=13.5MHz */
865         div = 1;
866         cfg->refdiv = 0;
867         while ((Fref / div) > 13500000) {
868                 div *= 2;
869                 cfg->refdiv++;
870
871                 if (div > 8) {
872                         arizona_fll_err(fll,
873                                         "Can't scale %dMHz in to <=13.5MHz\n",
874                                         Fref);
875                         return -EINVAL;
876                 }
877         }
878
879         /* Apply the division for our remaining calculations */
880         Fref /= div;
881
882         /* Fvco should be over the targt; don't check the upper bound */
883         div = 1;
884         while (Fout * div < 90000000 * fll->vco_mult) {
885                 div++;
886                 if (div > 7) {
887                         arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
888                                         Fout);
889                         return -EINVAL;
890                 }
891         }
892         target = Fout * div / fll->vco_mult;
893         cfg->outdiv = div;
894
895         arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
896
897         /* Find an appropraite FLL_FRATIO and factor it out of the target */
898         for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
899                 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
900                         cfg->fratio = fll_fratios[i].fratio;
901                         ratio = fll_fratios[i].ratio;
902                         break;
903                 }
904         }
905         if (i == ARRAY_SIZE(fll_fratios)) {
906                 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
907                                 Fref);
908                 return -EINVAL;
909         }
910
911         cfg->n = target / (ratio * Fref);
912
913         if (target % Fref) {
914                 gcd_fll = gcd(target, ratio * Fref);
915                 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
916
917                 cfg->theta = (target - (cfg->n * ratio * Fref))
918                         / gcd_fll;
919                 cfg->lambda = (ratio * Fref) / gcd_fll;
920         } else {
921                 cfg->theta = 0;
922                 cfg->lambda = 0;
923         }
924
925         arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
926                         cfg->n, cfg->theta, cfg->lambda);
927         arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
928                         cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
929
930         return 0;
931
932 }
933
934 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
935                               struct arizona_fll_cfg *cfg, int source)
936 {
937         regmap_update_bits(arizona->regmap, base + 3,
938                            ARIZONA_FLL1_THETA_MASK, cfg->theta);
939         regmap_update_bits(arizona->regmap, base + 4,
940                            ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
941         regmap_update_bits(arizona->regmap, base + 5,
942                            ARIZONA_FLL1_FRATIO_MASK,
943                            cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
944         regmap_update_bits(arizona->regmap, base + 6,
945                            ARIZONA_FLL1_CLK_REF_DIV_MASK |
946                            ARIZONA_FLL1_CLK_REF_SRC_MASK,
947                            cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
948                            source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
949
950         regmap_update_bits(arizona->regmap, base + 2,
951                            ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
952                            ARIZONA_FLL1_CTRL_UPD | cfg->n);
953 }
954
955 int arizona_set_fll(struct arizona_fll *fll, int source,
956                     unsigned int Fref, unsigned int Fout)
957 {
958         struct arizona *arizona = fll->arizona;
959         struct arizona_fll_cfg cfg, sync;
960         unsigned int reg, val;
961         int syncsrc;
962         bool ena;
963         int ret;
964
965         if (fll->fref == Fref && fll->fout == Fout)
966                 return 0;
967
968         ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
969         if (ret != 0) {
970                 arizona_fll_err(fll, "Failed to read current state: %d\n",
971                                 ret);
972                 return ret;
973         }
974         ena = reg & ARIZONA_FLL1_ENA;
975
976         if (Fout) {
977                 /* Do we have a 32kHz reference? */
978                 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
979                 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
980                 case ARIZONA_CLK_SRC_MCLK1:
981                 case ARIZONA_CLK_SRC_MCLK2:
982                         syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
983                         break;
984                 default:
985                         syncsrc = -1;
986                 }
987
988                 if (source == syncsrc)
989                         syncsrc = -1;
990
991                 if (syncsrc >= 0) {
992                         ret = arizona_calc_fll(fll, &sync, Fref, Fout);
993                         if (ret != 0)
994                                 return ret;
995
996                         ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
997                         if (ret != 0)
998                                 return ret;
999                 } else {
1000                         ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
1001                         if (ret != 0)
1002                                 return ret;
1003                 }
1004         } else {
1005                 regmap_update_bits(arizona->regmap, fll->base + 1,
1006                                    ARIZONA_FLL1_ENA, 0);
1007                 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1008                                    ARIZONA_FLL1_SYNC_ENA, 0);
1009
1010                 if (ena)
1011                         pm_runtime_put_autosuspend(arizona->dev);
1012
1013                 fll->fref = Fref;
1014                 fll->fout = Fout;
1015
1016                 return 0;
1017         }
1018
1019         regmap_update_bits(arizona->regmap, fll->base + 5,
1020                            ARIZONA_FLL1_OUTDIV_MASK,
1021                            cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1022
1023         if (syncsrc >= 0) {
1024                 arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
1025                 arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
1026         } else {
1027                 arizona_apply_fll(arizona, fll->base, &cfg, source);
1028         }
1029
1030         if (!ena)
1031                 pm_runtime_get(arizona->dev);
1032
1033         /* Clear any pending completions */
1034         try_wait_for_completion(&fll->ok);
1035
1036         regmap_update_bits(arizona->regmap, fll->base + 1,
1037                            ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1038         if (syncsrc >= 0)
1039                 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1040                                    ARIZONA_FLL1_SYNC_ENA,
1041                                    ARIZONA_FLL1_SYNC_ENA);
1042
1043         ret = wait_for_completion_timeout(&fll->ok,
1044                                           msecs_to_jiffies(250));
1045         if (ret == 0)
1046                 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1047
1048         fll->fref = Fref;
1049         fll->fout = Fout;
1050
1051         return 0;
1052 }
1053 EXPORT_SYMBOL_GPL(arizona_set_fll);
1054
1055 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1056                      int ok_irq, struct arizona_fll *fll)
1057 {
1058         int ret;
1059
1060         init_completion(&fll->lock);
1061         init_completion(&fll->ok);
1062
1063         fll->id = id;
1064         fll->base = base;
1065         fll->arizona = arizona;
1066
1067         snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1068         snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1069                  "FLL%d clock OK", id);
1070
1071         ret = arizona_request_irq(arizona, lock_irq, fll->lock_name,
1072                                   arizona_fll_lock, fll);
1073         if (ret != 0) {
1074                 dev_err(arizona->dev, "Failed to get FLL%d lock IRQ: %d\n",
1075                         id, ret);
1076         }
1077
1078         ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1079                                   arizona_fll_clock_ok, fll);
1080         if (ret != 0) {
1081                 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
1082                         id, ret);
1083         }
1084
1085         return 0;
1086 }
1087 EXPORT_SYMBOL_GPL(arizona_init_fll);
1088
1089 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1090 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1091 MODULE_LICENSE("GPL");