]> Pileus Git - ~andy/linux/blob - sound/soc/codecs/arizona.c
ASoC: arizona: Add signal activity output for DRC
[~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/delay.h>
14 #include <linux/gcd.h>
15 #include <linux/module.h>
16 #include <linux/pm_runtime.h>
17 #include <sound/pcm.h>
18 #include <sound/pcm_params.h>
19 #include <sound/tlv.h>
20
21 #include <linux/mfd/arizona/core.h>
22 #include <linux/mfd/arizona/gpio.h>
23 #include <linux/mfd/arizona/registers.h>
24
25 #include "arizona.h"
26
27 #define ARIZONA_AIF_BCLK_CTRL                   0x00
28 #define ARIZONA_AIF_TX_PIN_CTRL                 0x01
29 #define ARIZONA_AIF_RX_PIN_CTRL                 0x02
30 #define ARIZONA_AIF_RATE_CTRL                   0x03
31 #define ARIZONA_AIF_FORMAT                      0x04
32 #define ARIZONA_AIF_TX_BCLK_RATE                0x05
33 #define ARIZONA_AIF_RX_BCLK_RATE                0x06
34 #define ARIZONA_AIF_FRAME_CTRL_1                0x07
35 #define ARIZONA_AIF_FRAME_CTRL_2                0x08
36 #define ARIZONA_AIF_FRAME_CTRL_3                0x09
37 #define ARIZONA_AIF_FRAME_CTRL_4                0x0A
38 #define ARIZONA_AIF_FRAME_CTRL_5                0x0B
39 #define ARIZONA_AIF_FRAME_CTRL_6                0x0C
40 #define ARIZONA_AIF_FRAME_CTRL_7                0x0D
41 #define ARIZONA_AIF_FRAME_CTRL_8                0x0E
42 #define ARIZONA_AIF_FRAME_CTRL_9                0x0F
43 #define ARIZONA_AIF_FRAME_CTRL_10               0x10
44 #define ARIZONA_AIF_FRAME_CTRL_11               0x11
45 #define ARIZONA_AIF_FRAME_CTRL_12               0x12
46 #define ARIZONA_AIF_FRAME_CTRL_13               0x13
47 #define ARIZONA_AIF_FRAME_CTRL_14               0x14
48 #define ARIZONA_AIF_FRAME_CTRL_15               0x15
49 #define ARIZONA_AIF_FRAME_CTRL_16               0x16
50 #define ARIZONA_AIF_FRAME_CTRL_17               0x17
51 #define ARIZONA_AIF_FRAME_CTRL_18               0x18
52 #define ARIZONA_AIF_TX_ENABLES                  0x19
53 #define ARIZONA_AIF_RX_ENABLES                  0x1A
54 #define ARIZONA_AIF_FORCE_WRITE                 0x1B
55
56 #define arizona_fll_err(_fll, fmt, ...) \
57         dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
58 #define arizona_fll_warn(_fll, fmt, ...) \
59         dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
60 #define arizona_fll_dbg(_fll, fmt, ...) \
61         dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
62
63 #define arizona_aif_err(_dai, fmt, ...) \
64         dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
65 #define arizona_aif_warn(_dai, fmt, ...) \
66         dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
67 #define arizona_aif_dbg(_dai, fmt, ...) \
68         dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
69
70 static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
71                           struct snd_kcontrol *kcontrol,
72                           int event)
73 {
74         struct snd_soc_codec *codec = w->codec;
75         struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
76         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
77         bool manual_ena = false;
78         int val;
79
80         switch (arizona->type) {
81         case WM5102:
82                 switch (arizona->rev) {
83                 case 0:
84                         break;
85                 default:
86                         manual_ena = true;
87                         break;
88                 }
89         default:
90                 break;
91         }
92
93         switch (event) {
94         case SND_SOC_DAPM_PRE_PMU:
95                 if (!priv->spk_ena && manual_ena) {
96                         snd_soc_write(codec, 0x4f5, 0x25a);
97                         priv->spk_ena_pending = true;
98                 }
99                 break;
100         case SND_SOC_DAPM_POST_PMU:
101                 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
102                 if (val & ARIZONA_SPK_SHUTDOWN_STS) {
103                         dev_crit(arizona->dev,
104                                  "Speaker not enabled due to temperature\n");
105                         return -EBUSY;
106                 }
107
108                 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
109                                     1 << w->shift, 1 << w->shift);
110
111                 if (priv->spk_ena_pending) {
112                         msleep(75);
113                         snd_soc_write(codec, 0x4f5, 0xda);
114                         priv->spk_ena_pending = false;
115                         priv->spk_ena++;
116                 }
117                 break;
118         case SND_SOC_DAPM_PRE_PMD:
119                 if (manual_ena) {
120                         priv->spk_ena--;
121                         if (!priv->spk_ena)
122                                 snd_soc_write(codec, 0x4f5, 0x25a);
123                 }
124
125                 snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1,
126                                     1 << w->shift, 0);
127                 break;
128         case SND_SOC_DAPM_POST_PMD:
129                 if (manual_ena) {
130                         if (!priv->spk_ena)
131                                 snd_soc_write(codec, 0x4f5, 0x0da);
132                 }
133                 break;
134         }
135
136         return 0;
137 }
138
139 static irqreturn_t arizona_thermal_warn(int irq, void *data)
140 {
141         struct arizona *arizona = data;
142         unsigned int val;
143         int ret;
144
145         ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
146                           &val);
147         if (ret != 0) {
148                 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
149                         ret);
150         } else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) {
151                 dev_crit(arizona->dev, "Thermal warning\n");
152         }
153
154         return IRQ_HANDLED;
155 }
156
157 static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
158 {
159         struct arizona *arizona = data;
160         unsigned int val;
161         int ret;
162
163         ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
164                           &val);
165         if (ret != 0) {
166                 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
167                         ret);
168         } else if (val & ARIZONA_SPK_SHUTDOWN_STS) {
169                 dev_crit(arizona->dev, "Thermal shutdown\n");
170                 ret = regmap_update_bits(arizona->regmap,
171                                          ARIZONA_OUTPUT_ENABLES_1,
172                                          ARIZONA_OUT4L_ENA |
173                                          ARIZONA_OUT4R_ENA, 0);
174                 if (ret != 0)
175                         dev_crit(arizona->dev,
176                                  "Failed to disable speaker outputs: %d\n",
177                                  ret);
178         }
179
180         return IRQ_HANDLED;
181 }
182
183 static const struct snd_soc_dapm_widget arizona_spkl =
184         SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
185                            ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
186                            SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
187
188 static const struct snd_soc_dapm_widget arizona_spkr =
189         SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
190                            ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
191                            SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
192
193 int arizona_init_spk(struct snd_soc_codec *codec)
194 {
195         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
196         struct arizona *arizona = priv->arizona;
197         int ret;
198
199         ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1);
200         if (ret != 0)
201                 return ret;
202
203         ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkr, 1);
204         if (ret != 0)
205                 return ret;
206
207         ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN,
208                                   "Thermal warning", arizona_thermal_warn,
209                                   arizona);
210         if (ret != 0)
211                 dev_err(arizona->dev,
212                         "Failed to get thermal warning IRQ: %d\n",
213                         ret);
214
215         ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN,
216                                   "Thermal shutdown", arizona_thermal_shutdown,
217                                   arizona);
218         if (ret != 0)
219                 dev_err(arizona->dev,
220                         "Failed to get thermal shutdown IRQ: %d\n",
221                         ret);
222
223         return 0;
224 }
225 EXPORT_SYMBOL_GPL(arizona_init_spk);
226
227 int arizona_init_gpio(struct snd_soc_codec *codec)
228 {
229         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
230         struct arizona *arizona = priv->arizona;
231         int i;
232
233         switch (arizona->type) {
234         case WM5110:
235                 snd_soc_dapm_disable_pin(&codec->dapm, "DRC2 Signal Activity");
236         }
237
238         snd_soc_dapm_disable_pin(&codec->dapm, "DRC1 Signal Activity");
239
240         for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
241                 switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
242                 case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
243                         snd_soc_dapm_enable_pin(&codec->dapm,
244                                                 "DRC1 Signal Activity");
245                         break;
246                 case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
247                         snd_soc_dapm_enable_pin(&codec->dapm,
248                                                 "DRC2 Signal Activity");
249                         break;
250                 default:
251                         break;
252                 }
253         }
254
255         return 0;
256 }
257 EXPORT_SYMBOL_GPL(arizona_init_gpio);
258
259 const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
260         "None",
261         "Tone Generator 1",
262         "Tone Generator 2",
263         "Haptics",
264         "AEC",
265         "Mic Mute Mixer",
266         "Noise Generator",
267         "IN1L",
268         "IN1R",
269         "IN2L",
270         "IN2R",
271         "IN3L",
272         "IN3R",
273         "IN4L",
274         "IN4R",
275         "AIF1RX1",
276         "AIF1RX2",
277         "AIF1RX3",
278         "AIF1RX4",
279         "AIF1RX5",
280         "AIF1RX6",
281         "AIF1RX7",
282         "AIF1RX8",
283         "AIF2RX1",
284         "AIF2RX2",
285         "AIF3RX1",
286         "AIF3RX2",
287         "SLIMRX1",
288         "SLIMRX2",
289         "SLIMRX3",
290         "SLIMRX4",
291         "SLIMRX5",
292         "SLIMRX6",
293         "SLIMRX7",
294         "SLIMRX8",
295         "EQ1",
296         "EQ2",
297         "EQ3",
298         "EQ4",
299         "DRC1L",
300         "DRC1R",
301         "DRC2L",
302         "DRC2R",
303         "LHPF1",
304         "LHPF2",
305         "LHPF3",
306         "LHPF4",
307         "DSP1.1",
308         "DSP1.2",
309         "DSP1.3",
310         "DSP1.4",
311         "DSP1.5",
312         "DSP1.6",
313         "DSP2.1",
314         "DSP2.2",
315         "DSP2.3",
316         "DSP2.4",
317         "DSP2.5",
318         "DSP2.6",
319         "DSP3.1",
320         "DSP3.2",
321         "DSP3.3",
322         "DSP3.4",
323         "DSP3.5",
324         "DSP3.6",
325         "DSP4.1",
326         "DSP4.2",
327         "DSP4.3",
328         "DSP4.4",
329         "DSP4.5",
330         "DSP4.6",
331         "ASRC1L",
332         "ASRC1R",
333         "ASRC2L",
334         "ASRC2R",
335         "ISRC1INT1",
336         "ISRC1INT2",
337         "ISRC1INT3",
338         "ISRC1INT4",
339         "ISRC1DEC1",
340         "ISRC1DEC2",
341         "ISRC1DEC3",
342         "ISRC1DEC4",
343         "ISRC2INT1",
344         "ISRC2INT2",
345         "ISRC2INT3",
346         "ISRC2INT4",
347         "ISRC2DEC1",
348         "ISRC2DEC2",
349         "ISRC2DEC3",
350         "ISRC2DEC4",
351         "ISRC3INT1",
352         "ISRC3INT2",
353         "ISRC3INT3",
354         "ISRC3INT4",
355         "ISRC3DEC1",
356         "ISRC3DEC2",
357         "ISRC3DEC3",
358         "ISRC3DEC4",
359 };
360 EXPORT_SYMBOL_GPL(arizona_mixer_texts);
361
362 int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
363         0x00,  /* None */
364         0x04,  /* Tone */
365         0x05,
366         0x06,  /* Haptics */
367         0x08,  /* AEC */
368         0x0c,  /* Noise mixer */
369         0x0d,  /* Comfort noise */
370         0x10,  /* IN1L */
371         0x11,
372         0x12,
373         0x13,
374         0x14,
375         0x15,
376         0x16,
377         0x17,
378         0x20,  /* AIF1RX1 */
379         0x21,
380         0x22,
381         0x23,
382         0x24,
383         0x25,
384         0x26,
385         0x27,
386         0x28,  /* AIF2RX1 */
387         0x29,
388         0x30,  /* AIF3RX1 */
389         0x31,
390         0x38,  /* SLIMRX1 */
391         0x39,
392         0x3a,
393         0x3b,
394         0x3c,
395         0x3d,
396         0x3e,
397         0x3f,
398         0x50,  /* EQ1 */
399         0x51,
400         0x52,
401         0x53,
402         0x58,  /* DRC1L */
403         0x59,
404         0x5a,
405         0x5b,
406         0x60,  /* LHPF1 */
407         0x61,
408         0x62,
409         0x63,
410         0x68,  /* DSP1.1 */
411         0x69,
412         0x6a,
413         0x6b,
414         0x6c,
415         0x6d,
416         0x70,  /* DSP2.1 */
417         0x71,
418         0x72,
419         0x73,
420         0x74,
421         0x75,
422         0x78,  /* DSP3.1 */
423         0x79,
424         0x7a,
425         0x7b,
426         0x7c,
427         0x7d,
428         0x80,  /* DSP4.1 */
429         0x81,
430         0x82,
431         0x83,
432         0x84,
433         0x85,
434         0x90,  /* ASRC1L */
435         0x91,
436         0x92,
437         0x93,
438         0xa0,  /* ISRC1INT1 */
439         0xa1,
440         0xa2,
441         0xa3,
442         0xa4,  /* ISRC1DEC1 */
443         0xa5,
444         0xa6,
445         0xa7,
446         0xa8,  /* ISRC2DEC1 */
447         0xa9,
448         0xaa,
449         0xab,
450         0xac,  /* ISRC2INT1 */
451         0xad,
452         0xae,
453         0xaf,
454         0xb0,  /* ISRC3DEC1 */
455         0xb1,
456         0xb2,
457         0xb3,
458         0xb4,  /* ISRC3INT1 */
459         0xb5,
460         0xb6,
461         0xb7,
462 };
463 EXPORT_SYMBOL_GPL(arizona_mixer_values);
464
465 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
466 EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
467
468 const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
469         "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
470 };
471 EXPORT_SYMBOL_GPL(arizona_rate_text);
472
473 const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
474         0, 1, 2, 8,
475 };
476 EXPORT_SYMBOL_GPL(arizona_rate_val);
477
478
479 const struct soc_enum arizona_isrc_fsl[] = {
480         SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
481                               ARIZONA_ISRC1_FSL_SHIFT, 0xf,
482                               ARIZONA_RATE_ENUM_SIZE,
483                               arizona_rate_text, arizona_rate_val),
484         SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
485                               ARIZONA_ISRC2_FSL_SHIFT, 0xf,
486                               ARIZONA_RATE_ENUM_SIZE,
487                               arizona_rate_text, arizona_rate_val),
488         SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
489                               ARIZONA_ISRC3_FSL_SHIFT, 0xf,
490                               ARIZONA_RATE_ENUM_SIZE,
491                               arizona_rate_text, arizona_rate_val),
492 };
493 EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
494
495 static const char *arizona_vol_ramp_text[] = {
496         "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
497         "15ms/6dB", "30ms/6dB",
498 };
499
500 const struct soc_enum arizona_in_vd_ramp =
501         SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
502                         ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
503 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
504
505 const struct soc_enum arizona_in_vi_ramp =
506         SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
507                         ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
508 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
509
510 const struct soc_enum arizona_out_vd_ramp =
511         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
512                         ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
513 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
514
515 const struct soc_enum arizona_out_vi_ramp =
516         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
517                         ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
518 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
519
520 static const char *arizona_lhpf_mode_text[] = {
521         "Low-pass", "High-pass"
522 };
523
524 const struct soc_enum arizona_lhpf1_mode =
525         SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
526                         arizona_lhpf_mode_text);
527 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
528
529 const struct soc_enum arizona_lhpf2_mode =
530         SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
531                         arizona_lhpf_mode_text);
532 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
533
534 const struct soc_enum arizona_lhpf3_mode =
535         SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
536                         arizona_lhpf_mode_text);
537 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
538
539 const struct soc_enum arizona_lhpf4_mode =
540         SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
541                         arizona_lhpf_mode_text);
542 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
543
544 static const char *arizona_ng_hold_text[] = {
545         "30ms", "120ms", "250ms", "500ms",
546 };
547
548 const struct soc_enum arizona_ng_hold =
549         SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT,
550                         4, arizona_ng_hold_text);
551 EXPORT_SYMBOL_GPL(arizona_ng_hold);
552
553 static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
554 {
555         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
556         unsigned int val;
557         int i;
558
559         if (ena)
560                 val = ARIZONA_IN_VU;
561         else
562                 val = 0;
563
564         for (i = 0; i < priv->num_inputs; i++)
565                 snd_soc_update_bits(codec,
566                                     ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
567                                     ARIZONA_IN_VU, val);
568 }
569
570 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
571                   int event)
572 {
573         struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
574         unsigned int reg;
575
576         if (w->shift % 2)
577                 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
578         else
579                 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
580
581         switch (event) {
582         case SND_SOC_DAPM_PRE_PMU:
583                 priv->in_pending++;
584                 break;
585         case SND_SOC_DAPM_POST_PMU:
586                 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
587
588                 /* If this is the last input pending then allow VU */
589                 priv->in_pending--;
590                 if (priv->in_pending == 0) {
591                         msleep(1);
592                         arizona_in_set_vu(w->codec, 1);
593                 }
594                 break;
595         case SND_SOC_DAPM_PRE_PMD:
596                 snd_soc_update_bits(w->codec, reg,
597                                     ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
598                                     ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
599                 break;
600         case SND_SOC_DAPM_POST_PMD:
601                 /* Disable volume updates if no inputs are enabled */
602                 reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
603                 if (reg == 0)
604                         arizona_in_set_vu(w->codec, 0);
605         }
606
607         return 0;
608 }
609 EXPORT_SYMBOL_GPL(arizona_in_ev);
610
611 int arizona_out_ev(struct snd_soc_dapm_widget *w,
612                    struct snd_kcontrol *kcontrol,
613                    int event)
614 {
615         switch (event) {
616         case SND_SOC_DAPM_POST_PMU:
617                 switch (w->shift) {
618                 case ARIZONA_OUT1L_ENA_SHIFT:
619                 case ARIZONA_OUT1R_ENA_SHIFT:
620                 case ARIZONA_OUT2L_ENA_SHIFT:
621                 case ARIZONA_OUT2R_ENA_SHIFT:
622                 case ARIZONA_OUT3L_ENA_SHIFT:
623                 case ARIZONA_OUT3R_ENA_SHIFT:
624                         msleep(17);
625                         break;
626
627                 default:
628                         break;
629                 }
630                 break;
631         }
632
633         return 0;
634 }
635 EXPORT_SYMBOL_GPL(arizona_out_ev);
636
637 int arizona_hp_ev(struct snd_soc_dapm_widget *w,
638                    struct snd_kcontrol *kcontrol,
639                    int event)
640 {
641         struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
642         unsigned int mask = 1 << w->shift;
643         unsigned int val;
644
645         switch (event) {
646         case SND_SOC_DAPM_POST_PMU:
647                 val = mask;
648                 break;
649         case SND_SOC_DAPM_PRE_PMD:
650                 val = 0;
651                 break;
652         default:
653                 return -EINVAL;
654         }
655
656         /* Store the desired state for the HP outputs */
657         priv->arizona->hp_ena &= ~mask;
658         priv->arizona->hp_ena |= val;
659
660         /* Force off if HPDET magic is active */
661         if (priv->arizona->hpdet_magic)
662                 val = 0;
663
664         snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val);
665
666         return arizona_out_ev(w, kcontrol, event);
667 }
668 EXPORT_SYMBOL_GPL(arizona_hp_ev);
669
670 static unsigned int arizona_sysclk_48k_rates[] = {
671         6144000,
672         12288000,
673         24576000,
674         49152000,
675         73728000,
676         98304000,
677         147456000,
678 };
679
680 static unsigned int arizona_sysclk_44k1_rates[] = {
681         5644800,
682         11289600,
683         22579200,
684         45158400,
685         67737600,
686         90316800,
687         135475200,
688 };
689
690 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
691                              unsigned int freq)
692 {
693         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
694         unsigned int reg;
695         unsigned int *rates;
696         int ref, div, refclk;
697
698         switch (clk) {
699         case ARIZONA_CLK_OPCLK:
700                 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
701                 refclk = priv->sysclk;
702                 break;
703         case ARIZONA_CLK_ASYNC_OPCLK:
704                 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
705                 refclk = priv->asyncclk;
706                 break;
707         default:
708                 return -EINVAL;
709         }
710
711         if (refclk % 8000)
712                 rates = arizona_sysclk_44k1_rates;
713         else
714                 rates = arizona_sysclk_48k_rates;
715
716         for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
717                      rates[ref] <= refclk; ref++) {
718                 div = 1;
719                 while (rates[ref] / div >= freq && div < 32) {
720                         if (rates[ref] / div == freq) {
721                                 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
722                                         freq);
723                                 snd_soc_update_bits(codec, reg,
724                                                     ARIZONA_OPCLK_DIV_MASK |
725                                                     ARIZONA_OPCLK_SEL_MASK,
726                                                     (div <<
727                                                      ARIZONA_OPCLK_DIV_SHIFT) |
728                                                     ref);
729                                 return 0;
730                         }
731                         div++;
732                 }
733         }
734
735         dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
736         return -EINVAL;
737 }
738
739 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
740                        int source, unsigned int freq, int dir)
741 {
742         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
743         struct arizona *arizona = priv->arizona;
744         char *name;
745         unsigned int reg;
746         unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
747         unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
748         unsigned int *clk;
749
750         switch (clk_id) {
751         case ARIZONA_CLK_SYSCLK:
752                 name = "SYSCLK";
753                 reg = ARIZONA_SYSTEM_CLOCK_1;
754                 clk = &priv->sysclk;
755                 mask |= ARIZONA_SYSCLK_FRAC;
756                 break;
757         case ARIZONA_CLK_ASYNCCLK:
758                 name = "ASYNCCLK";
759                 reg = ARIZONA_ASYNC_CLOCK_1;
760                 clk = &priv->asyncclk;
761                 break;
762         case ARIZONA_CLK_OPCLK:
763         case ARIZONA_CLK_ASYNC_OPCLK:
764                 return arizona_set_opclk(codec, clk_id, freq);
765         default:
766                 return -EINVAL;
767         }
768
769         switch (freq) {
770         case  5644800:
771         case  6144000:
772                 break;
773         case 11289600:
774         case 12288000:
775                 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
776                 break;
777         case 22579200:
778         case 24576000:
779                 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
780                 break;
781         case 45158400:
782         case 49152000:
783                 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
784                 break;
785         case 67737600:
786         case 73728000:
787                 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
788                 break;
789         case 90316800:
790         case 98304000:
791                 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
792                 break;
793         case 135475200:
794         case 147456000:
795                 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
796                 break;
797         case 0:
798                 dev_dbg(arizona->dev, "%s cleared\n", name);
799                 *clk = freq;
800                 return 0;
801         default:
802                 return -EINVAL;
803         }
804
805         *clk = freq;
806
807         if (freq % 6144000)
808                 val |= ARIZONA_SYSCLK_FRAC;
809
810         dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
811
812         return regmap_update_bits(arizona->regmap, reg, mask, val);
813 }
814 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
815
816 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
817 {
818         struct snd_soc_codec *codec = dai->codec;
819         int lrclk, bclk, mode, base;
820
821         base = dai->driver->base;
822
823         lrclk = 0;
824         bclk = 0;
825
826         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
827         case SND_SOC_DAIFMT_DSP_A:
828                 mode = 0;
829                 break;
830         case SND_SOC_DAIFMT_I2S:
831                 mode = 2;
832                 break;
833         default:
834                 arizona_aif_err(dai, "Unsupported DAI format %d\n",
835                                 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
836                 return -EINVAL;
837         }
838
839         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
840         case SND_SOC_DAIFMT_CBS_CFS:
841                 break;
842         case SND_SOC_DAIFMT_CBS_CFM:
843                 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
844                 break;
845         case SND_SOC_DAIFMT_CBM_CFS:
846                 bclk |= ARIZONA_AIF1_BCLK_MSTR;
847                 break;
848         case SND_SOC_DAIFMT_CBM_CFM:
849                 bclk |= ARIZONA_AIF1_BCLK_MSTR;
850                 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
851                 break;
852         default:
853                 arizona_aif_err(dai, "Unsupported master mode %d\n",
854                                 fmt & SND_SOC_DAIFMT_MASTER_MASK);
855                 return -EINVAL;
856         }
857
858         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
859         case SND_SOC_DAIFMT_NB_NF:
860                 break;
861         case SND_SOC_DAIFMT_IB_IF:
862                 bclk |= ARIZONA_AIF1_BCLK_INV;
863                 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
864                 break;
865         case SND_SOC_DAIFMT_IB_NF:
866                 bclk |= ARIZONA_AIF1_BCLK_INV;
867                 break;
868         case SND_SOC_DAIFMT_NB_IF:
869                 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
870                 break;
871         default:
872                 return -EINVAL;
873         }
874
875         snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
876                             ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
877                             bclk);
878         snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
879                             ARIZONA_AIF1TX_LRCLK_INV |
880                             ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
881         snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
882                             ARIZONA_AIF1RX_LRCLK_INV |
883                             ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
884         snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
885                             ARIZONA_AIF1_FMT_MASK, mode);
886
887         return 0;
888 }
889
890 static const int arizona_48k_bclk_rates[] = {
891         -1,
892         48000,
893         64000,
894         96000,
895         128000,
896         192000,
897         256000,
898         384000,
899         512000,
900         768000,
901         1024000,
902         1536000,
903         2048000,
904         3072000,
905         4096000,
906         6144000,
907         8192000,
908         12288000,
909         24576000,
910 };
911
912 static const unsigned int arizona_48k_rates[] = {
913         12000,
914         24000,
915         48000,
916         96000,
917         192000,
918         384000,
919         768000,
920         4000,
921         8000,
922         16000,
923         32000,
924         64000,
925         128000,
926         256000,
927         512000,
928 };
929
930 static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
931         .count  = ARRAY_SIZE(arizona_48k_rates),
932         .list   = arizona_48k_rates,
933 };
934
935 static const int arizona_44k1_bclk_rates[] = {
936         -1,
937         44100,
938         58800,
939         88200,
940         117600,
941         177640,
942         235200,
943         352800,
944         470400,
945         705600,
946         940800,
947         1411200,
948         1881600,
949         2822400,
950         3763200,
951         5644800,
952         7526400,
953         11289600,
954         22579200,
955 };
956
957 static const unsigned int arizona_44k1_rates[] = {
958         11025,
959         22050,
960         44100,
961         88200,
962         176400,
963         352800,
964         705600,
965 };
966
967 static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
968         .count  = ARRAY_SIZE(arizona_44k1_rates),
969         .list   = arizona_44k1_rates,
970 };
971
972 static int arizona_sr_vals[] = {
973         0,
974         12000,
975         24000,
976         48000,
977         96000,
978         192000,
979         384000,
980         768000,
981         0,
982         11025,
983         22050,
984         44100,
985         88200,
986         176400,
987         352800,
988         705600,
989         4000,
990         8000,
991         16000,
992         32000,
993         64000,
994         128000,
995         256000,
996         512000,
997 };
998
999 static int arizona_startup(struct snd_pcm_substream *substream,
1000                            struct snd_soc_dai *dai)
1001 {
1002         struct snd_soc_codec *codec = dai->codec;
1003         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1004         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1005         const struct snd_pcm_hw_constraint_list *constraint;
1006         unsigned int base_rate;
1007
1008         switch (dai_priv->clk) {
1009         case ARIZONA_CLK_SYSCLK:
1010                 base_rate = priv->sysclk;
1011                 break;
1012         case ARIZONA_CLK_ASYNCCLK:
1013                 base_rate = priv->asyncclk;
1014                 break;
1015         default:
1016                 return 0;
1017         }
1018
1019         if (base_rate == 0)
1020                 return 0;
1021
1022         if (base_rate % 8000)
1023                 constraint = &arizona_44k1_constraint;
1024         else
1025                 constraint = &arizona_48k_constraint;
1026
1027         return snd_pcm_hw_constraint_list(substream->runtime, 0,
1028                                           SNDRV_PCM_HW_PARAM_RATE,
1029                                           constraint);
1030 }
1031
1032 static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1033                                   struct snd_pcm_hw_params *params,
1034                                   struct snd_soc_dai *dai)
1035 {
1036         struct snd_soc_codec *codec = dai->codec;
1037         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1038         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1039         int base = dai->driver->base;
1040         int i, sr_val;
1041
1042         /*
1043          * We will need to be more flexible than this in future,
1044          * currently we use a single sample rate for SYSCLK.
1045          */
1046         for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1047                 if (arizona_sr_vals[i] == params_rate(params))
1048                         break;
1049         if (i == ARRAY_SIZE(arizona_sr_vals)) {
1050                 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1051                                 params_rate(params));
1052                 return -EINVAL;
1053         }
1054         sr_val = i;
1055
1056         switch (dai_priv->clk) {
1057         case ARIZONA_CLK_SYSCLK:
1058                 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
1059                                     ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
1060                 if (base)
1061                         snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1062                                             ARIZONA_AIF1_RATE_MASK, 0);
1063                 break;
1064         case ARIZONA_CLK_ASYNCCLK:
1065                 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
1066                                     ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
1067                 if (base)
1068                         snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1069                                             ARIZONA_AIF1_RATE_MASK,
1070                                             8 << ARIZONA_AIF1_RATE_SHIFT);
1071                 break;
1072         default:
1073                 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1074                 return -EINVAL;
1075         }
1076
1077         return 0;
1078 }
1079
1080 static int arizona_hw_params(struct snd_pcm_substream *substream,
1081                              struct snd_pcm_hw_params *params,
1082                              struct snd_soc_dai *dai)
1083 {
1084         struct snd_soc_codec *codec = dai->codec;
1085         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1086         struct arizona *arizona = priv->arizona;
1087         int base = dai->driver->base;
1088         const int *rates;
1089         int i, ret, val;
1090         int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1091         int bclk, lrclk, wl, frame, bclk_target;
1092
1093         if (params_rate(params) % 8000)
1094                 rates = &arizona_44k1_bclk_rates[0];
1095         else
1096                 rates = &arizona_48k_bclk_rates[0];
1097
1098         bclk_target = snd_soc_params_to_bclk(params);
1099         if (chan_limit && chan_limit < params_channels(params)) {
1100                 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1101                 bclk_target /= params_channels(params);
1102                 bclk_target *= chan_limit;
1103         }
1104
1105         /* Force stereo for I2S mode */
1106         val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1107         if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) {
1108                 arizona_aif_dbg(dai, "Forcing stereo mode\n");
1109                 bclk_target *= 2;
1110         }
1111
1112         for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1113                 if (rates[i] >= bclk_target &&
1114                     rates[i] % params_rate(params) == 0) {
1115                         bclk = i;
1116                         break;
1117                 }
1118         }
1119         if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1120                 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1121                                 params_rate(params));
1122                 return -EINVAL;
1123         }
1124
1125         lrclk = rates[bclk] / params_rate(params);
1126
1127         arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1128                         rates[bclk], rates[bclk] / lrclk);
1129
1130         wl = snd_pcm_format_width(params_format(params));
1131         frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
1132
1133         ret = arizona_hw_params_rate(substream, params, dai);
1134         if (ret != 0)
1135                 return ret;
1136
1137         snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
1138                             ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1139         snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
1140                             ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1141         snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
1142                             ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1143         snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
1144                             ARIZONA_AIF1TX_WL_MASK |
1145                             ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1146         snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
1147                             ARIZONA_AIF1RX_WL_MASK |
1148                             ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1149
1150         return 0;
1151 }
1152
1153 static const char *arizona_dai_clk_str(int clk_id)
1154 {
1155         switch (clk_id) {
1156         case ARIZONA_CLK_SYSCLK:
1157                 return "SYSCLK";
1158         case ARIZONA_CLK_ASYNCCLK:
1159                 return "ASYNCCLK";
1160         default:
1161                 return "Unknown clock";
1162         }
1163 }
1164
1165 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1166                                   int clk_id, unsigned int freq, int dir)
1167 {
1168         struct snd_soc_codec *codec = dai->codec;
1169         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1170         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1171         struct snd_soc_dapm_route routes[2];
1172
1173         switch (clk_id) {
1174         case ARIZONA_CLK_SYSCLK:
1175         case ARIZONA_CLK_ASYNCCLK:
1176                 break;
1177         default:
1178                 return -EINVAL;
1179         }
1180
1181         if (clk_id == dai_priv->clk)
1182                 return 0;
1183
1184         if (dai->active) {
1185                 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
1186                         dai->id);
1187                 return -EBUSY;
1188         }
1189
1190         dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
1191                 arizona_dai_clk_str(clk_id));
1192
1193         memset(&routes, 0, sizeof(routes));
1194         routes[0].sink = dai->driver->capture.stream_name;
1195         routes[1].sink = dai->driver->playback.stream_name;
1196
1197         routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1198         routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1199         snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1200
1201         routes[0].source = arizona_dai_clk_str(clk_id);
1202         routes[1].source = arizona_dai_clk_str(clk_id);
1203         snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
1204
1205         dai_priv->clk = clk_id;
1206
1207         return snd_soc_dapm_sync(&codec->dapm);
1208 }
1209
1210 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1211 {
1212         struct snd_soc_codec *codec = dai->codec;
1213         int base = dai->driver->base;
1214         unsigned int reg;
1215
1216         if (tristate)
1217                 reg = ARIZONA_AIF1_TRI;
1218         else
1219                 reg = 0;
1220
1221         return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1222                                    ARIZONA_AIF1_TRI, reg);
1223 }
1224
1225 const struct snd_soc_dai_ops arizona_dai_ops = {
1226         .startup = arizona_startup,
1227         .set_fmt = arizona_set_fmt,
1228         .hw_params = arizona_hw_params,
1229         .set_sysclk = arizona_dai_set_sysclk,
1230         .set_tristate = arizona_set_tristate,
1231 };
1232 EXPORT_SYMBOL_GPL(arizona_dai_ops);
1233
1234 const struct snd_soc_dai_ops arizona_simple_dai_ops = {
1235         .startup = arizona_startup,
1236         .hw_params = arizona_hw_params_rate,
1237         .set_sysclk = arizona_dai_set_sysclk,
1238 };
1239 EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
1240
1241 int arizona_init_dai(struct arizona_priv *priv, int id)
1242 {
1243         struct arizona_dai_priv *dai_priv = &priv->dai[id];
1244
1245         dai_priv->clk = ARIZONA_CLK_SYSCLK;
1246
1247         return 0;
1248 }
1249 EXPORT_SYMBOL_GPL(arizona_init_dai);
1250
1251 static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
1252 {
1253         struct arizona_fll *fll = data;
1254
1255         arizona_fll_dbg(fll, "clock OK\n");
1256
1257         complete(&fll->ok);
1258
1259         return IRQ_HANDLED;
1260 }
1261
1262 static struct {
1263         unsigned int min;
1264         unsigned int max;
1265         u16 fratio;
1266         int ratio;
1267 } fll_fratios[] = {
1268         {       0,    64000, 4, 16 },
1269         {   64000,   128000, 3,  8 },
1270         {  128000,   256000, 2,  4 },
1271         {  256000,  1000000, 1,  2 },
1272         { 1000000, 13500000, 0,  1 },
1273 };
1274
1275 static struct {
1276         unsigned int min;
1277         unsigned int max;
1278         u16 gain;
1279 } fll_gains[] = {
1280         {       0,   256000, 0 },
1281         {  256000,  1000000, 2 },
1282         { 1000000, 13500000, 4 },
1283 };
1284
1285 struct arizona_fll_cfg {
1286         int n;
1287         int theta;
1288         int lambda;
1289         int refdiv;
1290         int outdiv;
1291         int fratio;
1292         int gain;
1293 };
1294
1295 static int arizona_calc_fll(struct arizona_fll *fll,
1296                             struct arizona_fll_cfg *cfg,
1297                             unsigned int Fref,
1298                             unsigned int Fout)
1299 {
1300         unsigned int target, div, gcd_fll;
1301         int i, ratio;
1302
1303         arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
1304
1305         /* Fref must be <=13.5MHz */
1306         div = 1;
1307         cfg->refdiv = 0;
1308         while ((Fref / div) > 13500000) {
1309                 div *= 2;
1310                 cfg->refdiv++;
1311
1312                 if (div > 8) {
1313                         arizona_fll_err(fll,
1314                                         "Can't scale %dMHz in to <=13.5MHz\n",
1315                                         Fref);
1316                         return -EINVAL;
1317                 }
1318         }
1319
1320         /* Apply the division for our remaining calculations */
1321         Fref /= div;
1322
1323         /* Fvco should be over the targt; don't check the upper bound */
1324         div = 1;
1325         while (Fout * div < 90000000 * fll->vco_mult) {
1326                 div++;
1327                 if (div > 7) {
1328                         arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1329                                         Fout);
1330                         return -EINVAL;
1331                 }
1332         }
1333         target = Fout * div / fll->vco_mult;
1334         cfg->outdiv = div;
1335
1336         arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
1337
1338         /* Find an appropraite FLL_FRATIO and factor it out of the target */
1339         for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1340                 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1341                         cfg->fratio = fll_fratios[i].fratio;
1342                         ratio = fll_fratios[i].ratio;
1343                         break;
1344                 }
1345         }
1346         if (i == ARRAY_SIZE(fll_fratios)) {
1347                 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1348                                 Fref);
1349                 return -EINVAL;
1350         }
1351
1352         for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
1353                 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
1354                         cfg->gain = fll_gains[i].gain;
1355                         break;
1356                 }
1357         }
1358         if (i == ARRAY_SIZE(fll_gains)) {
1359                 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
1360                                 Fref);
1361                 return -EINVAL;
1362         }
1363
1364         cfg->n = target / (ratio * Fref);
1365
1366         if (target % (ratio * Fref)) {
1367                 gcd_fll = gcd(target, ratio * Fref);
1368                 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
1369
1370                 cfg->theta = (target - (cfg->n * ratio * Fref))
1371                         / gcd_fll;
1372                 cfg->lambda = (ratio * Fref) / gcd_fll;
1373         } else {
1374                 cfg->theta = 0;
1375                 cfg->lambda = 0;
1376         }
1377
1378         /* Round down to 16bit range with cost of accuracy lost.
1379          * Denominator must be bigger than numerator so we only
1380          * take care of it.
1381          */
1382         while (cfg->lambda >= (1 << 16)) {
1383                 cfg->theta >>= 1;
1384                 cfg->lambda >>= 1;
1385         }
1386
1387         arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
1388                         cfg->n, cfg->theta, cfg->lambda);
1389         arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
1390                         cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
1391         arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);
1392
1393         return 0;
1394
1395 }
1396
1397 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
1398                               struct arizona_fll_cfg *cfg, int source,
1399                               bool sync)
1400 {
1401         regmap_update_bits(arizona->regmap, base + 3,
1402                            ARIZONA_FLL1_THETA_MASK, cfg->theta);
1403         regmap_update_bits(arizona->regmap, base + 4,
1404                            ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
1405         regmap_update_bits(arizona->regmap, base + 5,
1406                            ARIZONA_FLL1_FRATIO_MASK,
1407                            cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
1408         regmap_update_bits(arizona->regmap, base + 6,
1409                            ARIZONA_FLL1_CLK_REF_DIV_MASK |
1410                            ARIZONA_FLL1_CLK_REF_SRC_MASK,
1411                            cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
1412                            source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
1413
1414         if (sync)
1415                 regmap_update_bits(arizona->regmap, base + 0x7,
1416                                    ARIZONA_FLL1_GAIN_MASK,
1417                                    cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1418         else
1419                 regmap_update_bits(arizona->regmap, base + 0x9,
1420                                    ARIZONA_FLL1_GAIN_MASK,
1421                                    cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
1422
1423         regmap_update_bits(arizona->regmap, base + 2,
1424                            ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
1425                            ARIZONA_FLL1_CTRL_UPD | cfg->n);
1426 }
1427
1428 static bool arizona_is_enabled_fll(struct arizona_fll *fll)
1429 {
1430         struct arizona *arizona = fll->arizona;
1431         unsigned int reg;
1432         int ret;
1433
1434         ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
1435         if (ret != 0) {
1436                 arizona_fll_err(fll, "Failed to read current state: %d\n",
1437                                 ret);
1438                 return ret;
1439         }
1440
1441         return reg & ARIZONA_FLL1_ENA;
1442 }
1443
1444 static void arizona_enable_fll(struct arizona_fll *fll,
1445                               struct arizona_fll_cfg *ref,
1446                               struct arizona_fll_cfg *sync)
1447 {
1448         struct arizona *arizona = fll->arizona;
1449         int ret;
1450
1451         /*
1452          * If we have both REFCLK and SYNCCLK then enable both,
1453          * otherwise apply the SYNCCLK settings to REFCLK.
1454          */
1455         if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) {
1456                 regmap_update_bits(arizona->regmap, fll->base + 5,
1457                                    ARIZONA_FLL1_OUTDIV_MASK,
1458                                    ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1459
1460                 arizona_apply_fll(arizona, fll->base, ref, fll->ref_src,
1461                                   false);
1462                 if (fll->sync_src >= 0)
1463                         arizona_apply_fll(arizona, fll->base + 0x10, sync,
1464                                           fll->sync_src, true);
1465         } else if (fll->sync_src >= 0) {
1466                 regmap_update_bits(arizona->regmap, fll->base + 5,
1467                                    ARIZONA_FLL1_OUTDIV_MASK,
1468                                    sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
1469
1470                 arizona_apply_fll(arizona, fll->base, sync,
1471                                   fll->sync_src, false);
1472
1473                 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1474                                    ARIZONA_FLL1_SYNC_ENA, 0);
1475         } else {
1476                 arizona_fll_err(fll, "No clocks provided\n");
1477                 return;
1478         }
1479
1480         /*
1481          * Increase the bandwidth if we're not using a low frequency
1482          * sync source.
1483          */
1484         if (fll->sync_src >= 0 && fll->sync_freq > 100000)
1485                 regmap_update_bits(arizona->regmap, fll->base + 0x17,
1486                                    ARIZONA_FLL1_SYNC_BW, 0);
1487         else
1488                 regmap_update_bits(arizona->regmap, fll->base + 0x17,
1489                                    ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW);
1490
1491         if (!arizona_is_enabled_fll(fll))
1492                 pm_runtime_get(arizona->dev);
1493
1494         /* Clear any pending completions */
1495         try_wait_for_completion(&fll->ok);
1496
1497         regmap_update_bits(arizona->regmap, fll->base + 1,
1498                            ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
1499         if (fll->ref_src >= 0 && fll->sync_src >= 0 &&
1500             fll->ref_src != fll->sync_src)
1501                 regmap_update_bits(arizona->regmap, fll->base + 0x11,
1502                                    ARIZONA_FLL1_SYNC_ENA,
1503                                    ARIZONA_FLL1_SYNC_ENA);
1504
1505         ret = wait_for_completion_timeout(&fll->ok,
1506                                           msecs_to_jiffies(250));
1507         if (ret == 0)
1508                 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1509 }
1510
1511 static void arizona_disable_fll(struct arizona_fll *fll)
1512 {
1513         struct arizona *arizona = fll->arizona;
1514         bool change;
1515
1516         regmap_update_bits_check(arizona->regmap, fll->base + 1,
1517                                  ARIZONA_FLL1_ENA, 0, &change);
1518         regmap_update_bits(arizona->regmap, fll->base + 0x11,
1519                            ARIZONA_FLL1_SYNC_ENA, 0);
1520
1521         if (change)
1522                 pm_runtime_put_autosuspend(arizona->dev);
1523 }
1524
1525 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
1526                            unsigned int Fref, unsigned int Fout)
1527 {
1528         struct arizona_fll_cfg ref, sync;
1529         int ret;
1530
1531         if (fll->ref_src == source && fll->ref_freq == Fref)
1532                 return 0;
1533
1534         if (fll->fout && Fref > 0) {
1535                 ret = arizona_calc_fll(fll, &ref, Fref, fll->fout);
1536                 if (ret != 0)
1537                         return ret;
1538
1539                 if (fll->sync_src >= 0) {
1540                         ret = arizona_calc_fll(fll, &sync, fll->sync_freq,
1541                                                fll->fout);
1542                         if (ret != 0)
1543                                 return ret;
1544                 }
1545         }
1546
1547         fll->ref_src = source;
1548         fll->ref_freq = Fref;
1549
1550         if (fll->fout && Fref > 0) {
1551                 arizona_enable_fll(fll, &ref, &sync);
1552         }
1553
1554         return 0;
1555 }
1556 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
1557
1558 int arizona_set_fll(struct arizona_fll *fll, int source,
1559                     unsigned int Fref, unsigned int Fout)
1560 {
1561         struct arizona_fll_cfg ref, sync;
1562         int ret;
1563
1564         if (fll->sync_src == source &&
1565             fll->sync_freq == Fref && fll->fout == Fout)
1566                 return 0;
1567
1568         if (Fout) {
1569                 if (fll->ref_src >= 0) {
1570                         ret = arizona_calc_fll(fll, &ref, fll->ref_freq,
1571                                                Fout);
1572                         if (ret != 0)
1573                                 return ret;
1574                 }
1575
1576                 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
1577                 if (ret != 0)
1578                         return ret;
1579         }
1580
1581         fll->sync_src = source;
1582         fll->sync_freq = Fref;
1583         fll->fout = Fout;
1584
1585         if (Fout) {
1586                 arizona_enable_fll(fll, &ref, &sync);
1587         } else {
1588                 arizona_disable_fll(fll);
1589         }
1590
1591         return 0;
1592 }
1593 EXPORT_SYMBOL_GPL(arizona_set_fll);
1594
1595 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1596                      int ok_irq, struct arizona_fll *fll)
1597 {
1598         int ret;
1599         unsigned int val;
1600
1601         init_completion(&fll->ok);
1602
1603         fll->id = id;
1604         fll->base = base;
1605         fll->arizona = arizona;
1606         fll->sync_src = ARIZONA_FLL_SRC_NONE;
1607
1608         /* Configure default refclk to 32kHz if we have one */
1609         regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
1610         switch (val & ARIZONA_CLK_32K_SRC_MASK) {
1611         case ARIZONA_CLK_SRC_MCLK1:
1612         case ARIZONA_CLK_SRC_MCLK2:
1613                 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
1614                 break;
1615         default:
1616                 fll->ref_src = ARIZONA_FLL_SRC_NONE;
1617         }
1618         fll->ref_freq = 32768;
1619
1620         snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
1621         snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1622                  "FLL%d clock OK", id);
1623
1624         ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1625                                   arizona_fll_clock_ok, fll);
1626         if (ret != 0) {
1627                 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
1628                         id, ret);
1629         }
1630
1631         regmap_update_bits(arizona->regmap, fll->base + 1,
1632                            ARIZONA_FLL1_FREERUN, 0);
1633
1634         return 0;
1635 }
1636 EXPORT_SYMBOL_GPL(arizona_init_fll);
1637
1638 /**
1639  * arizona_set_output_mode - Set the mode of the specified output
1640  *
1641  * @codec: Device to configure
1642  * @output: Output number
1643  * @diff: True to set the output to differential mode
1644  *
1645  * Some systems use external analogue switches to connect more
1646  * analogue devices to the CODEC than are supported by the device.  In
1647  * some systems this requires changing the switched output from single
1648  * ended to differential mode dynamically at runtime, an operation
1649  * supported using this function.
1650  *
1651  * Most systems have a single static configuration and should use
1652  * platform data instead.
1653  */
1654 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
1655 {
1656         unsigned int reg, val;
1657
1658         if (output < 1 || output > 6)
1659                 return -EINVAL;
1660
1661         reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
1662
1663         if (diff)
1664                 val = ARIZONA_OUT1_MONO;
1665         else
1666                 val = 0;
1667
1668         return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
1669 }
1670 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
1671
1672 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1673 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1674 MODULE_LICENSE("GPL");