Merge remote-tracking branches 'asoc/topic/ab8500', 'asoc/topic/adau17x1', 'asoc...
[cascardo/linux.git] / sound / soc / codecs / arizona.c
1 /*
2  * arizona.c - Wolfson Arizona class device shared support
3  *
4  * Copyright 2012 Wolfson Microelectronics plc
5  *
6  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/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/registers.h>
23
24 #include "arizona.h"
25
26 #define ARIZONA_AIF_BCLK_CTRL                   0x00
27 #define ARIZONA_AIF_TX_PIN_CTRL                 0x01
28 #define ARIZONA_AIF_RX_PIN_CTRL                 0x02
29 #define ARIZONA_AIF_RATE_CTRL                   0x03
30 #define ARIZONA_AIF_FORMAT                      0x04
31 #define ARIZONA_AIF_TX_BCLK_RATE                0x05
32 #define ARIZONA_AIF_RX_BCLK_RATE                0x06
33 #define ARIZONA_AIF_FRAME_CTRL_1                0x07
34 #define ARIZONA_AIF_FRAME_CTRL_2                0x08
35 #define ARIZONA_AIF_FRAME_CTRL_3                0x09
36 #define ARIZONA_AIF_FRAME_CTRL_4                0x0A
37 #define ARIZONA_AIF_FRAME_CTRL_5                0x0B
38 #define ARIZONA_AIF_FRAME_CTRL_6                0x0C
39 #define ARIZONA_AIF_FRAME_CTRL_7                0x0D
40 #define ARIZONA_AIF_FRAME_CTRL_8                0x0E
41 #define ARIZONA_AIF_FRAME_CTRL_9                0x0F
42 #define ARIZONA_AIF_FRAME_CTRL_10               0x10
43 #define ARIZONA_AIF_FRAME_CTRL_11               0x11
44 #define ARIZONA_AIF_FRAME_CTRL_12               0x12
45 #define ARIZONA_AIF_FRAME_CTRL_13               0x13
46 #define ARIZONA_AIF_FRAME_CTRL_14               0x14
47 #define ARIZONA_AIF_FRAME_CTRL_15               0x15
48 #define ARIZONA_AIF_FRAME_CTRL_16               0x16
49 #define ARIZONA_AIF_FRAME_CTRL_17               0x17
50 #define ARIZONA_AIF_FRAME_CTRL_18               0x18
51 #define ARIZONA_AIF_TX_ENABLES                  0x19
52 #define ARIZONA_AIF_RX_ENABLES                  0x1A
53 #define ARIZONA_AIF_FORCE_WRITE                 0x1B
54
55 #define ARIZONA_FLL_VCO_CORNER 141900000
56 #define ARIZONA_FLL_MAX_FREF   13500000
57 #define ARIZONA_FLL_MIN_FVCO   90000000
58 #define ARIZONA_FLL_MAX_FRATIO 16
59 #define ARIZONA_FLL_MAX_REFDIV 8
60 #define ARIZONA_FLL_MIN_OUTDIV 2
61 #define ARIZONA_FLL_MAX_OUTDIV 7
62
63 #define ARIZONA_FMT_DSP_MODE_A          0
64 #define ARIZONA_FMT_DSP_MODE_B          1
65 #define ARIZONA_FMT_I2S_MODE            2
66 #define ARIZONA_FMT_LEFT_JUSTIFIED_MODE 3
67
68 #define arizona_fll_err(_fll, fmt, ...) \
69         dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
70 #define arizona_fll_warn(_fll, fmt, ...) \
71         dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
72 #define arizona_fll_dbg(_fll, fmt, ...) \
73         dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
74
75 #define arizona_aif_err(_dai, fmt, ...) \
76         dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
77 #define arizona_aif_warn(_dai, fmt, ...) \
78         dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
79 #define arizona_aif_dbg(_dai, fmt, ...) \
80         dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
81
82 static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
83                           struct snd_kcontrol *kcontrol,
84                           int event)
85 {
86         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
87         struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
88         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
89         bool manual_ena = false;
90         int val;
91
92         switch (arizona->type) {
93         case WM5102:
94                 switch (arizona->rev) {
95                 case 0:
96                         break;
97                 default:
98                         manual_ena = true;
99                         break;
100                 }
101         default:
102                 break;
103         }
104
105         switch (event) {
106         case SND_SOC_DAPM_PRE_PMU:
107                 if (!priv->spk_ena && manual_ena) {
108                         regmap_write_async(arizona->regmap, 0x4f5, 0x25a);
109                         priv->spk_ena_pending = true;
110                 }
111                 break;
112         case SND_SOC_DAPM_POST_PMU:
113                 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
114                 if (val & ARIZONA_SPK_OVERHEAT_STS) {
115                         dev_crit(arizona->dev,
116                                  "Speaker not enabled due to temperature\n");
117                         return -EBUSY;
118                 }
119
120                 regmap_update_bits_async(arizona->regmap,
121                                          ARIZONA_OUTPUT_ENABLES_1,
122                                          1 << w->shift, 1 << w->shift);
123
124                 if (priv->spk_ena_pending) {
125                         msleep(75);
126                         regmap_write_async(arizona->regmap, 0x4f5, 0xda);
127                         priv->spk_ena_pending = false;
128                         priv->spk_ena++;
129                 }
130                 break;
131         case SND_SOC_DAPM_PRE_PMD:
132                 if (manual_ena) {
133                         priv->spk_ena--;
134                         if (!priv->spk_ena)
135                                 regmap_write_async(arizona->regmap,
136                                                    0x4f5, 0x25a);
137                 }
138
139                 regmap_update_bits_async(arizona->regmap,
140                                          ARIZONA_OUTPUT_ENABLES_1,
141                                          1 << w->shift, 0);
142                 break;
143         case SND_SOC_DAPM_POST_PMD:
144                 if (manual_ena) {
145                         if (!priv->spk_ena)
146                                 regmap_write_async(arizona->regmap,
147                                                    0x4f5, 0x0da);
148                 }
149                 break;
150         default:
151                 break;
152         }
153
154         return 0;
155 }
156
157 static irqreturn_t arizona_thermal_warn(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_OVERHEAT_WARN_STS) {
169                 dev_crit(arizona->dev, "Thermal warning\n");
170         }
171
172         return IRQ_HANDLED;
173 }
174
175 static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
176 {
177         struct arizona *arizona = data;
178         unsigned int val;
179         int ret;
180
181         ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
182                           &val);
183         if (ret != 0) {
184                 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
185                         ret);
186         } else if (val & ARIZONA_SPK_OVERHEAT_STS) {
187                 dev_crit(arizona->dev, "Thermal shutdown\n");
188                 ret = regmap_update_bits(arizona->regmap,
189                                          ARIZONA_OUTPUT_ENABLES_1,
190                                          ARIZONA_OUT4L_ENA |
191                                          ARIZONA_OUT4R_ENA, 0);
192                 if (ret != 0)
193                         dev_crit(arizona->dev,
194                                  "Failed to disable speaker outputs: %d\n",
195                                  ret);
196         }
197
198         return IRQ_HANDLED;
199 }
200
201 static const struct snd_soc_dapm_widget arizona_spkl =
202         SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
203                            ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
204                            SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
205
206 static const struct snd_soc_dapm_widget arizona_spkr =
207         SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
208                            ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
209                            SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU);
210
211 int arizona_init_spk(struct snd_soc_codec *codec)
212 {
213         struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
214         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
215         struct arizona *arizona = priv->arizona;
216         int ret;
217
218         ret = snd_soc_dapm_new_controls(dapm, &arizona_spkl, 1);
219         if (ret != 0)
220                 return ret;
221
222         switch (arizona->type) {
223         case WM8997:
224                 break;
225         default:
226                 ret = snd_soc_dapm_new_controls(dapm, &arizona_spkr, 1);
227                 if (ret != 0)
228                         return ret;
229                 break;
230         }
231
232         ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN,
233                                   "Thermal warning", arizona_thermal_warn,
234                                   arizona);
235         if (ret != 0)
236                 dev_err(arizona->dev,
237                         "Failed to get thermal warning IRQ: %d\n",
238                         ret);
239
240         ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT,
241                                   "Thermal shutdown", arizona_thermal_shutdown,
242                                   arizona);
243         if (ret != 0)
244                 dev_err(arizona->dev,
245                         "Failed to get thermal shutdown IRQ: %d\n",
246                         ret);
247
248         return 0;
249 }
250 EXPORT_SYMBOL_GPL(arizona_init_spk);
251
252 static const struct snd_soc_dapm_route arizona_mono_routes[] = {
253         { "OUT1R", NULL, "OUT1L" },
254         { "OUT2R", NULL, "OUT2L" },
255         { "OUT3R", NULL, "OUT3L" },
256         { "OUT4R", NULL, "OUT4L" },
257         { "OUT5R", NULL, "OUT5L" },
258         { "OUT6R", NULL, "OUT6L" },
259 };
260
261 int arizona_init_mono(struct snd_soc_codec *codec)
262 {
263         struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
264         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
265         struct arizona *arizona = priv->arizona;
266         int i;
267
268         for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
269                 if (arizona->pdata.out_mono[i])
270                         snd_soc_dapm_add_routes(dapm,
271                                                 &arizona_mono_routes[i], 1);
272         }
273
274         return 0;
275 }
276 EXPORT_SYMBOL_GPL(arizona_init_mono);
277
278 int arizona_init_gpio(struct snd_soc_codec *codec)
279 {
280         struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
281         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
282         struct arizona *arizona = priv->arizona;
283         int i;
284
285         switch (arizona->type) {
286         case WM5110:
287         case WM8280:
288                 snd_soc_dapm_disable_pin(dapm, "DRC2 Signal Activity");
289                 break;
290         default:
291                 break;
292         }
293
294         snd_soc_dapm_disable_pin(dapm, "DRC1 Signal Activity");
295
296         for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
297                 switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
298                 case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
299                         snd_soc_dapm_enable_pin(dapm, "DRC1 Signal Activity");
300                         break;
301                 case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
302                         snd_soc_dapm_enable_pin(dapm, "DRC2 Signal Activity");
303                         break;
304                 default:
305                         break;
306                 }
307         }
308
309         return 0;
310 }
311 EXPORT_SYMBOL_GPL(arizona_init_gpio);
312
313 const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
314         "None",
315         "Tone Generator 1",
316         "Tone Generator 2",
317         "Haptics",
318         "AEC",
319         "AEC2",
320         "Mic Mute Mixer",
321         "Noise Generator",
322         "IN1L",
323         "IN1R",
324         "IN2L",
325         "IN2R",
326         "IN3L",
327         "IN3R",
328         "IN4L",
329         "IN4R",
330         "AIF1RX1",
331         "AIF1RX2",
332         "AIF1RX3",
333         "AIF1RX4",
334         "AIF1RX5",
335         "AIF1RX6",
336         "AIF1RX7",
337         "AIF1RX8",
338         "AIF2RX1",
339         "AIF2RX2",
340         "AIF2RX3",
341         "AIF2RX4",
342         "AIF2RX5",
343         "AIF2RX6",
344         "AIF3RX1",
345         "AIF3RX2",
346         "SLIMRX1",
347         "SLIMRX2",
348         "SLIMRX3",
349         "SLIMRX4",
350         "SLIMRX5",
351         "SLIMRX6",
352         "SLIMRX7",
353         "SLIMRX8",
354         "EQ1",
355         "EQ2",
356         "EQ3",
357         "EQ4",
358         "DRC1L",
359         "DRC1R",
360         "DRC2L",
361         "DRC2R",
362         "LHPF1",
363         "LHPF2",
364         "LHPF3",
365         "LHPF4",
366         "DSP1.1",
367         "DSP1.2",
368         "DSP1.3",
369         "DSP1.4",
370         "DSP1.5",
371         "DSP1.6",
372         "DSP2.1",
373         "DSP2.2",
374         "DSP2.3",
375         "DSP2.4",
376         "DSP2.5",
377         "DSP2.6",
378         "DSP3.1",
379         "DSP3.2",
380         "DSP3.3",
381         "DSP3.4",
382         "DSP3.5",
383         "DSP3.6",
384         "DSP4.1",
385         "DSP4.2",
386         "DSP4.3",
387         "DSP4.4",
388         "DSP4.5",
389         "DSP4.6",
390         "ASRC1L",
391         "ASRC1R",
392         "ASRC2L",
393         "ASRC2R",
394         "ISRC1INT1",
395         "ISRC1INT2",
396         "ISRC1INT3",
397         "ISRC1INT4",
398         "ISRC1DEC1",
399         "ISRC1DEC2",
400         "ISRC1DEC3",
401         "ISRC1DEC4",
402         "ISRC2INT1",
403         "ISRC2INT2",
404         "ISRC2INT3",
405         "ISRC2INT4",
406         "ISRC2DEC1",
407         "ISRC2DEC2",
408         "ISRC2DEC3",
409         "ISRC2DEC4",
410         "ISRC3INT1",
411         "ISRC3INT2",
412         "ISRC3INT3",
413         "ISRC3INT4",
414         "ISRC3DEC1",
415         "ISRC3DEC2",
416         "ISRC3DEC3",
417         "ISRC3DEC4",
418 };
419 EXPORT_SYMBOL_GPL(arizona_mixer_texts);
420
421 unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
422         0x00,  /* None */
423         0x04,  /* Tone */
424         0x05,
425         0x06,  /* Haptics */
426         0x08,  /* AEC */
427         0x09,  /* AEC2 */
428         0x0c,  /* Noise mixer */
429         0x0d,  /* Comfort noise */
430         0x10,  /* IN1L */
431         0x11,
432         0x12,
433         0x13,
434         0x14,
435         0x15,
436         0x16,
437         0x17,
438         0x20,  /* AIF1RX1 */
439         0x21,
440         0x22,
441         0x23,
442         0x24,
443         0x25,
444         0x26,
445         0x27,
446         0x28,  /* AIF2RX1 */
447         0x29,
448         0x2a,
449         0x2b,
450         0x2c,
451         0x2d,
452         0x30,  /* AIF3RX1 */
453         0x31,
454         0x38,  /* SLIMRX1 */
455         0x39,
456         0x3a,
457         0x3b,
458         0x3c,
459         0x3d,
460         0x3e,
461         0x3f,
462         0x50,  /* EQ1 */
463         0x51,
464         0x52,
465         0x53,
466         0x58,  /* DRC1L */
467         0x59,
468         0x5a,
469         0x5b,
470         0x60,  /* LHPF1 */
471         0x61,
472         0x62,
473         0x63,
474         0x68,  /* DSP1.1 */
475         0x69,
476         0x6a,
477         0x6b,
478         0x6c,
479         0x6d,
480         0x70,  /* DSP2.1 */
481         0x71,
482         0x72,
483         0x73,
484         0x74,
485         0x75,
486         0x78,  /* DSP3.1 */
487         0x79,
488         0x7a,
489         0x7b,
490         0x7c,
491         0x7d,
492         0x80,  /* DSP4.1 */
493         0x81,
494         0x82,
495         0x83,
496         0x84,
497         0x85,
498         0x90,  /* ASRC1L */
499         0x91,
500         0x92,
501         0x93,
502         0xa0,  /* ISRC1INT1 */
503         0xa1,
504         0xa2,
505         0xa3,
506         0xa4,  /* ISRC1DEC1 */
507         0xa5,
508         0xa6,
509         0xa7,
510         0xa8,  /* ISRC2DEC1 */
511         0xa9,
512         0xaa,
513         0xab,
514         0xac,  /* ISRC2INT1 */
515         0xad,
516         0xae,
517         0xaf,
518         0xb0,  /* ISRC3DEC1 */
519         0xb1,
520         0xb2,
521         0xb3,
522         0xb4,  /* ISRC3INT1 */
523         0xb5,
524         0xb6,
525         0xb7,
526 };
527 EXPORT_SYMBOL_GPL(arizona_mixer_values);
528
529 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
530 EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
531
532 const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
533         "12kHz", "24kHz", "48kHz", "96kHz", "192kHz",
534         "11.025kHz", "22.05kHz", "44.1kHz", "88.2kHz", "176.4kHz",
535         "4kHz", "8kHz", "16kHz", "32kHz",
536 };
537 EXPORT_SYMBOL_GPL(arizona_sample_rate_text);
538
539 const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
540         0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
541         0x10, 0x11, 0x12, 0x13,
542 };
543 EXPORT_SYMBOL_GPL(arizona_sample_rate_val);
544
545 const char *arizona_sample_rate_val_to_name(unsigned int rate_val)
546 {
547         int i;
548
549         for (i = 0; i < ARRAY_SIZE(arizona_sample_rate_val); ++i) {
550                 if (arizona_sample_rate_val[i] == rate_val)
551                         return arizona_sample_rate_text[i];
552         }
553
554         return "Illegal";
555 }
556 EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name);
557
558 const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
559         "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
560 };
561 EXPORT_SYMBOL_GPL(arizona_rate_text);
562
563 const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
564         0, 1, 2, 8,
565 };
566 EXPORT_SYMBOL_GPL(arizona_rate_val);
567
568
569 const struct soc_enum arizona_isrc_fsh[] = {
570         SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1,
571                               ARIZONA_ISRC1_FSH_SHIFT, 0xf,
572                               ARIZONA_RATE_ENUM_SIZE,
573                               arizona_rate_text, arizona_rate_val),
574         SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_1,
575                               ARIZONA_ISRC2_FSH_SHIFT, 0xf,
576                               ARIZONA_RATE_ENUM_SIZE,
577                               arizona_rate_text, arizona_rate_val),
578         SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_1,
579                               ARIZONA_ISRC3_FSH_SHIFT, 0xf,
580                               ARIZONA_RATE_ENUM_SIZE,
581                               arizona_rate_text, arizona_rate_val),
582 };
583 EXPORT_SYMBOL_GPL(arizona_isrc_fsh);
584
585 const struct soc_enum arizona_isrc_fsl[] = {
586         SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
587                               ARIZONA_ISRC1_FSL_SHIFT, 0xf,
588                               ARIZONA_RATE_ENUM_SIZE,
589                               arizona_rate_text, arizona_rate_val),
590         SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
591                               ARIZONA_ISRC2_FSL_SHIFT, 0xf,
592                               ARIZONA_RATE_ENUM_SIZE,
593                               arizona_rate_text, arizona_rate_val),
594         SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
595                               ARIZONA_ISRC3_FSL_SHIFT, 0xf,
596                               ARIZONA_RATE_ENUM_SIZE,
597                               arizona_rate_text, arizona_rate_val),
598 };
599 EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
600
601 const struct soc_enum arizona_asrc_rate1 =
602         SOC_VALUE_ENUM_SINGLE(ARIZONA_ASRC_RATE1,
603                               ARIZONA_ASRC_RATE1_SHIFT, 0xf,
604                               ARIZONA_RATE_ENUM_SIZE - 1,
605                               arizona_rate_text, arizona_rate_val);
606 EXPORT_SYMBOL_GPL(arizona_asrc_rate1);
607
608 static const char *arizona_vol_ramp_text[] = {
609         "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
610         "15ms/6dB", "30ms/6dB",
611 };
612
613 SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp,
614                      ARIZONA_INPUT_VOLUME_RAMP,
615                      ARIZONA_IN_VD_RAMP_SHIFT,
616                      arizona_vol_ramp_text);
617 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
618
619 SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp,
620                      ARIZONA_INPUT_VOLUME_RAMP,
621                      ARIZONA_IN_VI_RAMP_SHIFT,
622                      arizona_vol_ramp_text);
623 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
624
625 SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp,
626                      ARIZONA_OUTPUT_VOLUME_RAMP,
627                      ARIZONA_OUT_VD_RAMP_SHIFT,
628                      arizona_vol_ramp_text);
629 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
630
631 SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp,
632                      ARIZONA_OUTPUT_VOLUME_RAMP,
633                      ARIZONA_OUT_VI_RAMP_SHIFT,
634                      arizona_vol_ramp_text);
635 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
636
637 static const char *arizona_lhpf_mode_text[] = {
638         "Low-pass", "High-pass"
639 };
640
641 SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode,
642                      ARIZONA_HPLPF1_1,
643                      ARIZONA_LHPF1_MODE_SHIFT,
644                      arizona_lhpf_mode_text);
645 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
646
647 SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode,
648                      ARIZONA_HPLPF2_1,
649                      ARIZONA_LHPF2_MODE_SHIFT,
650                      arizona_lhpf_mode_text);
651 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
652
653 SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode,
654                      ARIZONA_HPLPF3_1,
655                      ARIZONA_LHPF3_MODE_SHIFT,
656                      arizona_lhpf_mode_text);
657 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
658
659 SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode,
660                      ARIZONA_HPLPF4_1,
661                      ARIZONA_LHPF4_MODE_SHIFT,
662                      arizona_lhpf_mode_text);
663 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
664
665 static const char *arizona_ng_hold_text[] = {
666         "30ms", "120ms", "250ms", "500ms",
667 };
668
669 SOC_ENUM_SINGLE_DECL(arizona_ng_hold,
670                      ARIZONA_NOISE_GATE_CONTROL,
671                      ARIZONA_NGATE_HOLD_SHIFT,
672                      arizona_ng_hold_text);
673 EXPORT_SYMBOL_GPL(arizona_ng_hold);
674
675 static const char * const arizona_in_hpf_cut_text[] = {
676         "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
677 };
678
679 SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum,
680                      ARIZONA_HPF_CONTROL,
681                      ARIZONA_IN_HPF_CUT_SHIFT,
682                      arizona_in_hpf_cut_text);
683 EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
684
685 static const char * const arizona_in_dmic_osr_text[] = {
686         "1.536MHz", "3.072MHz", "6.144MHz", "768kHz",
687 };
688
689 const struct soc_enum arizona_in_dmic_osr[] = {
690         SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
691                         ARRAY_SIZE(arizona_in_dmic_osr_text),
692                         arizona_in_dmic_osr_text),
693         SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
694                         ARRAY_SIZE(arizona_in_dmic_osr_text),
695                         arizona_in_dmic_osr_text),
696         SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
697                         ARRAY_SIZE(arizona_in_dmic_osr_text),
698                         arizona_in_dmic_osr_text),
699         SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
700                         ARRAY_SIZE(arizona_in_dmic_osr_text),
701                         arizona_in_dmic_osr_text),
702 };
703 EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
704
705 static const char * const arizona_anc_input_src_text[] = {
706         "None", "IN1", "IN2", "IN3", "IN4",
707 };
708
709 static const char * const arizona_anc_channel_src_text[] = {
710         "None", "Left", "Right", "Combine",
711 };
712
713 const struct soc_enum arizona_anc_input_src[] = {
714         SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
715                         ARIZONA_IN_RXANCL_SEL_SHIFT,
716                         ARRAY_SIZE(arizona_anc_input_src_text),
717                         arizona_anc_input_src_text),
718         SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL,
719                         ARIZONA_FCL_MIC_MODE_SEL,
720                         ARRAY_SIZE(arizona_anc_channel_src_text),
721                         arizona_anc_channel_src_text),
722         SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
723                         ARIZONA_IN_RXANCR_SEL_SHIFT,
724                         ARRAY_SIZE(arizona_anc_input_src_text),
725                         arizona_anc_input_src_text),
726         SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL,
727                         ARIZONA_FCR_MIC_MODE_SEL,
728                         ARRAY_SIZE(arizona_anc_channel_src_text),
729                         arizona_anc_channel_src_text),
730 };
731 EXPORT_SYMBOL_GPL(arizona_anc_input_src);
732
733 static const char * const arizona_anc_ng_texts[] = {
734         "None",
735         "Internal",
736         "External",
737 };
738
739 SOC_ENUM_SINGLE_DECL(arizona_anc_ng_enum, SND_SOC_NOPM, 0,
740                      arizona_anc_ng_texts);
741 EXPORT_SYMBOL_GPL(arizona_anc_ng_enum);
742
743 static const char * const arizona_output_anc_src_text[] = {
744         "None", "RXANCL", "RXANCR",
745 };
746
747 const struct soc_enum arizona_output_anc_src[] = {
748         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
749                         ARIZONA_OUT1L_ANC_SRC_SHIFT,
750                         ARRAY_SIZE(arizona_output_anc_src_text),
751                         arizona_output_anc_src_text),
752         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1R,
753                         ARIZONA_OUT1R_ANC_SRC_SHIFT,
754                         ARRAY_SIZE(arizona_output_anc_src_text),
755                         arizona_output_anc_src_text),
756         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
757                         ARIZONA_OUT2L_ANC_SRC_SHIFT,
758                         ARRAY_SIZE(arizona_output_anc_src_text),
759                         arizona_output_anc_src_text),
760         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2R,
761                         ARIZONA_OUT2R_ANC_SRC_SHIFT,
762                         ARRAY_SIZE(arizona_output_anc_src_text),
763                         arizona_output_anc_src_text),
764         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
765                         ARIZONA_OUT3L_ANC_SRC_SHIFT,
766                         ARRAY_SIZE(arizona_output_anc_src_text),
767                         arizona_output_anc_src_text),
768         SOC_ENUM_SINGLE(ARIZONA_DAC_VOLUME_LIMIT_3R,
769                         ARIZONA_OUT3R_ANC_SRC_SHIFT,
770                         ARRAY_SIZE(arizona_output_anc_src_text),
771                         arizona_output_anc_src_text),
772         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4L,
773                         ARIZONA_OUT4L_ANC_SRC_SHIFT,
774                         ARRAY_SIZE(arizona_output_anc_src_text),
775                         arizona_output_anc_src_text),
776         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4R,
777                         ARIZONA_OUT4R_ANC_SRC_SHIFT,
778                         ARRAY_SIZE(arizona_output_anc_src_text),
779                         arizona_output_anc_src_text),
780         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5L,
781                         ARIZONA_OUT5L_ANC_SRC_SHIFT,
782                         ARRAY_SIZE(arizona_output_anc_src_text),
783                         arizona_output_anc_src_text),
784         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5R,
785                         ARIZONA_OUT5R_ANC_SRC_SHIFT,
786                         ARRAY_SIZE(arizona_output_anc_src_text),
787                         arizona_output_anc_src_text),
788         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6L,
789                         ARIZONA_OUT6L_ANC_SRC_SHIFT,
790                         ARRAY_SIZE(arizona_output_anc_src_text),
791                         arizona_output_anc_src_text),
792         SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6R,
793                         ARIZONA_OUT6R_ANC_SRC_SHIFT,
794                         ARRAY_SIZE(arizona_output_anc_src_text),
795                         arizona_output_anc_src_text),
796 };
797 EXPORT_SYMBOL_GPL(arizona_output_anc_src);
798
799 static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
800 {
801         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
802         unsigned int val;
803         int i;
804
805         if (ena)
806                 val = ARIZONA_IN_VU;
807         else
808                 val = 0;
809
810         for (i = 0; i < priv->num_inputs; i++)
811                 snd_soc_update_bits(codec,
812                                     ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
813                                     ARIZONA_IN_VU, val);
814 }
815
816 bool arizona_input_analog(struct snd_soc_codec *codec, int shift)
817 {
818         unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8);
819         unsigned int val = snd_soc_read(codec, reg);
820
821         return !(val & ARIZONA_IN1_MODE_MASK);
822 }
823 EXPORT_SYMBOL_GPL(arizona_input_analog);
824
825 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
826                   int event)
827 {
828         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
829         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
830         unsigned int reg;
831
832         if (w->shift % 2)
833                 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
834         else
835                 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
836
837         switch (event) {
838         case SND_SOC_DAPM_PRE_PMU:
839                 priv->in_pending++;
840                 break;
841         case SND_SOC_DAPM_POST_PMU:
842                 snd_soc_update_bits(codec, reg, ARIZONA_IN1L_MUTE, 0);
843
844                 /* If this is the last input pending then allow VU */
845                 priv->in_pending--;
846                 if (priv->in_pending == 0) {
847                         msleep(1);
848                         arizona_in_set_vu(codec, 1);
849                 }
850                 break;
851         case SND_SOC_DAPM_PRE_PMD:
852                 snd_soc_update_bits(codec, reg,
853                                     ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
854                                     ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
855                 break;
856         case SND_SOC_DAPM_POST_PMD:
857                 /* Disable volume updates if no inputs are enabled */
858                 reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES);
859                 if (reg == 0)
860                         arizona_in_set_vu(codec, 0);
861                 break;
862         default:
863                 break;
864         }
865
866         return 0;
867 }
868 EXPORT_SYMBOL_GPL(arizona_in_ev);
869
870 int arizona_out_ev(struct snd_soc_dapm_widget *w,
871                    struct snd_kcontrol *kcontrol,
872                    int event)
873 {
874         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
875         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
876
877         switch (event) {
878         case SND_SOC_DAPM_PRE_PMU:
879                 switch (w->shift) {
880                 case ARIZONA_OUT1L_ENA_SHIFT:
881                 case ARIZONA_OUT1R_ENA_SHIFT:
882                 case ARIZONA_OUT2L_ENA_SHIFT:
883                 case ARIZONA_OUT2R_ENA_SHIFT:
884                 case ARIZONA_OUT3L_ENA_SHIFT:
885                 case ARIZONA_OUT3R_ENA_SHIFT:
886                         priv->out_up_pending++;
887                         priv->out_up_delay += 17;
888                         break;
889                 default:
890                         break;
891                 }
892                 break;
893         case SND_SOC_DAPM_POST_PMU:
894                 switch (w->shift) {
895                 case ARIZONA_OUT1L_ENA_SHIFT:
896                 case ARIZONA_OUT1R_ENA_SHIFT:
897                 case ARIZONA_OUT2L_ENA_SHIFT:
898                 case ARIZONA_OUT2R_ENA_SHIFT:
899                 case ARIZONA_OUT3L_ENA_SHIFT:
900                 case ARIZONA_OUT3R_ENA_SHIFT:
901                         priv->out_up_pending--;
902                         if (!priv->out_up_pending) {
903                                 msleep(priv->out_up_delay);
904                                 priv->out_up_delay = 0;
905                         }
906                         break;
907
908                 default:
909                         break;
910                 }
911                 break;
912         case SND_SOC_DAPM_PRE_PMD:
913                 switch (w->shift) {
914                 case ARIZONA_OUT1L_ENA_SHIFT:
915                 case ARIZONA_OUT1R_ENA_SHIFT:
916                 case ARIZONA_OUT2L_ENA_SHIFT:
917                 case ARIZONA_OUT2R_ENA_SHIFT:
918                 case ARIZONA_OUT3L_ENA_SHIFT:
919                 case ARIZONA_OUT3R_ENA_SHIFT:
920                         priv->out_down_pending++;
921                         priv->out_down_delay++;
922                         break;
923                 default:
924                         break;
925                 }
926                 break;
927         case SND_SOC_DAPM_POST_PMD:
928                 switch (w->shift) {
929                 case ARIZONA_OUT1L_ENA_SHIFT:
930                 case ARIZONA_OUT1R_ENA_SHIFT:
931                 case ARIZONA_OUT2L_ENA_SHIFT:
932                 case ARIZONA_OUT2R_ENA_SHIFT:
933                 case ARIZONA_OUT3L_ENA_SHIFT:
934                 case ARIZONA_OUT3R_ENA_SHIFT:
935                         priv->out_down_pending--;
936                         if (!priv->out_down_pending) {
937                                 msleep(priv->out_down_delay);
938                                 priv->out_down_delay = 0;
939                         }
940                         break;
941                 default:
942                         break;
943                 }
944                 break;
945         default:
946                 break;
947         }
948
949         return 0;
950 }
951 EXPORT_SYMBOL_GPL(arizona_out_ev);
952
953 int arizona_hp_ev(struct snd_soc_dapm_widget *w,
954                    struct snd_kcontrol *kcontrol,
955                    int event)
956 {
957         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
958         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
959         struct arizona *arizona = priv->arizona;
960         unsigned int mask = 1 << w->shift;
961         unsigned int val;
962
963         switch (event) {
964         case SND_SOC_DAPM_POST_PMU:
965                 val = mask;
966                 break;
967         case SND_SOC_DAPM_PRE_PMD:
968                 val = 0;
969                 break;
970         case SND_SOC_DAPM_PRE_PMU:
971         case SND_SOC_DAPM_POST_PMD:
972                 return arizona_out_ev(w, kcontrol, event);
973         default:
974                 return -EINVAL;
975         }
976
977         /* Store the desired state for the HP outputs */
978         priv->arizona->hp_ena &= ~mask;
979         priv->arizona->hp_ena |= val;
980
981         /* Force off if HPDET clamp is active */
982         if (priv->arizona->hpdet_clamp)
983                 val = 0;
984
985         regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
986                                  mask, val);
987
988         return arizona_out_ev(w, kcontrol, event);
989 }
990 EXPORT_SYMBOL_GPL(arizona_hp_ev);
991
992 static int arizona_dvfs_enable(struct snd_soc_codec *codec)
993 {
994         const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
995         struct arizona *arizona = priv->arizona;
996         int ret;
997
998         ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
999         if (ret) {
1000                 dev_err(codec->dev, "Failed to boost DCVDD: %d\n", ret);
1001                 return ret;
1002         }
1003
1004         ret = regmap_update_bits(arizona->regmap,
1005                                  ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1006                                  ARIZONA_SUBSYS_MAX_FREQ,
1007                                  ARIZONA_SUBSYS_MAX_FREQ);
1008         if (ret) {
1009                 dev_err(codec->dev, "Failed to enable subsys max: %d\n", ret);
1010                 regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1011                 return ret;
1012         }
1013
1014         return 0;
1015 }
1016
1017 static int arizona_dvfs_disable(struct snd_soc_codec *codec)
1018 {
1019         const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1020         struct arizona *arizona = priv->arizona;
1021         int ret;
1022
1023         ret = regmap_update_bits(arizona->regmap,
1024                                  ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1025                                  ARIZONA_SUBSYS_MAX_FREQ, 0);
1026         if (ret) {
1027                 dev_err(codec->dev, "Failed to disable subsys max: %d\n", ret);
1028                 return ret;
1029         }
1030
1031         ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1032         if (ret) {
1033                 dev_err(codec->dev, "Failed to unboost DCVDD: %d\n", ret);
1034                 return ret;
1035         }
1036
1037         return 0;
1038 }
1039
1040 int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags)
1041 {
1042         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1043         int ret = 0;
1044
1045         mutex_lock(&priv->dvfs_lock);
1046
1047         if (!priv->dvfs_cached && !priv->dvfs_reqs) {
1048                 ret = arizona_dvfs_enable(codec);
1049                 if (ret)
1050                         goto err;
1051         }
1052
1053         priv->dvfs_reqs |= flags;
1054 err:
1055         mutex_unlock(&priv->dvfs_lock);
1056         return ret;
1057 }
1058 EXPORT_SYMBOL_GPL(arizona_dvfs_up);
1059
1060 int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags)
1061 {
1062         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1063         unsigned int old_reqs;
1064         int ret = 0;
1065
1066         mutex_lock(&priv->dvfs_lock);
1067
1068         old_reqs = priv->dvfs_reqs;
1069         priv->dvfs_reqs &= ~flags;
1070
1071         if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
1072                 ret = arizona_dvfs_disable(codec);
1073
1074         mutex_unlock(&priv->dvfs_lock);
1075         return ret;
1076 }
1077 EXPORT_SYMBOL_GPL(arizona_dvfs_down);
1078
1079 int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
1080                            struct snd_kcontrol *kcontrol, int event)
1081 {
1082         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1083         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1084         int ret = 0;
1085
1086         mutex_lock(&priv->dvfs_lock);
1087
1088         switch (event) {
1089         case SND_SOC_DAPM_POST_PMU:
1090                 if (priv->dvfs_reqs)
1091                         ret = arizona_dvfs_enable(codec);
1092
1093                 priv->dvfs_cached = false;
1094                 break;
1095         case SND_SOC_DAPM_PRE_PMD:
1096                 /* We must ensure DVFS is disabled before the codec goes into
1097                  * suspend so that we are never in an illegal state of DVFS
1098                  * enabled without enough DCVDD
1099                  */
1100                 priv->dvfs_cached = true;
1101
1102                 if (priv->dvfs_reqs)
1103                         ret = arizona_dvfs_disable(codec);
1104                 break;
1105         default:
1106                 break;
1107         }
1108
1109         mutex_unlock(&priv->dvfs_lock);
1110         return ret;
1111 }
1112 EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
1113
1114 void arizona_init_dvfs(struct arizona_priv *priv)
1115 {
1116         mutex_init(&priv->dvfs_lock);
1117 }
1118 EXPORT_SYMBOL_GPL(arizona_init_dvfs);
1119
1120 int arizona_anc_ev(struct snd_soc_dapm_widget *w,
1121                    struct snd_kcontrol *kcontrol,
1122                    int event)
1123 {
1124         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1125         unsigned int mask = 0x3 << w->shift;
1126         unsigned int val;
1127
1128         switch (event) {
1129         case SND_SOC_DAPM_POST_PMU:
1130                 val = 1 << w->shift;
1131                 break;
1132         case SND_SOC_DAPM_PRE_PMD:
1133                 val = 1 << (w->shift + 1);
1134                 break;
1135         default:
1136                 return 0;
1137         }
1138
1139         snd_soc_update_bits(codec, ARIZONA_CLOCK_CONTROL, mask, val);
1140
1141         return 0;
1142 }
1143 EXPORT_SYMBOL_GPL(arizona_anc_ev);
1144
1145 static unsigned int arizona_opclk_ref_48k_rates[] = {
1146         6144000,
1147         12288000,
1148         24576000,
1149         49152000,
1150 };
1151
1152 static unsigned int arizona_opclk_ref_44k1_rates[] = {
1153         5644800,
1154         11289600,
1155         22579200,
1156         45158400,
1157 };
1158
1159 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
1160                              unsigned int freq)
1161 {
1162         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1163         unsigned int reg;
1164         unsigned int *rates;
1165         int ref, div, refclk;
1166
1167         switch (clk) {
1168         case ARIZONA_CLK_OPCLK:
1169                 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
1170                 refclk = priv->sysclk;
1171                 break;
1172         case ARIZONA_CLK_ASYNC_OPCLK:
1173                 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
1174                 refclk = priv->asyncclk;
1175                 break;
1176         default:
1177                 return -EINVAL;
1178         }
1179
1180         if (refclk % 8000)
1181                 rates = arizona_opclk_ref_44k1_rates;
1182         else
1183                 rates = arizona_opclk_ref_48k_rates;
1184
1185         for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
1186                      rates[ref] <= refclk; ref++) {
1187                 div = 1;
1188                 while (rates[ref] / div >= freq && div < 32) {
1189                         if (rates[ref] / div == freq) {
1190                                 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
1191                                         freq);
1192                                 snd_soc_update_bits(codec, reg,
1193                                                     ARIZONA_OPCLK_DIV_MASK |
1194                                                     ARIZONA_OPCLK_SEL_MASK,
1195                                                     (div <<
1196                                                      ARIZONA_OPCLK_DIV_SHIFT) |
1197                                                     ref);
1198                                 return 0;
1199                         }
1200                         div++;
1201                 }
1202         }
1203
1204         dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
1205         return -EINVAL;
1206 }
1207
1208 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1209                        int source, unsigned int freq, int dir)
1210 {
1211         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1212         struct arizona *arizona = priv->arizona;
1213         char *name;
1214         unsigned int reg;
1215         unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
1216         unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
1217         int *clk;
1218
1219         switch (clk_id) {
1220         case ARIZONA_CLK_SYSCLK:
1221                 name = "SYSCLK";
1222                 reg = ARIZONA_SYSTEM_CLOCK_1;
1223                 clk = &priv->sysclk;
1224                 mask |= ARIZONA_SYSCLK_FRAC;
1225                 break;
1226         case ARIZONA_CLK_ASYNCCLK:
1227                 name = "ASYNCCLK";
1228                 reg = ARIZONA_ASYNC_CLOCK_1;
1229                 clk = &priv->asyncclk;
1230                 break;
1231         case ARIZONA_CLK_OPCLK:
1232         case ARIZONA_CLK_ASYNC_OPCLK:
1233                 return arizona_set_opclk(codec, clk_id, freq);
1234         default:
1235                 return -EINVAL;
1236         }
1237
1238         switch (freq) {
1239         case  5644800:
1240         case  6144000:
1241                 break;
1242         case 11289600:
1243         case 12288000:
1244                 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1245                 break;
1246         case 22579200:
1247         case 24576000:
1248                 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1249                 break;
1250         case 45158400:
1251         case 49152000:
1252                 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1253                 break;
1254         case 67737600:
1255         case 73728000:
1256                 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1257                 break;
1258         case 90316800:
1259         case 98304000:
1260                 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1261                 break;
1262         case 135475200:
1263         case 147456000:
1264                 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1265                 break;
1266         case 0:
1267                 dev_dbg(arizona->dev, "%s cleared\n", name);
1268                 *clk = freq;
1269                 return 0;
1270         default:
1271                 return -EINVAL;
1272         }
1273
1274         *clk = freq;
1275
1276         if (freq % 6144000)
1277                 val |= ARIZONA_SYSCLK_FRAC;
1278
1279         dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
1280
1281         return regmap_update_bits(arizona->regmap, reg, mask, val);
1282 }
1283 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
1284
1285 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1286 {
1287         struct snd_soc_codec *codec = dai->codec;
1288         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1289         struct arizona *arizona = priv->arizona;
1290         int lrclk, bclk, mode, base;
1291
1292         base = dai->driver->base;
1293
1294         lrclk = 0;
1295         bclk = 0;
1296
1297         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1298         case SND_SOC_DAIFMT_DSP_A:
1299                 mode = ARIZONA_FMT_DSP_MODE_A;
1300                 break;
1301         case SND_SOC_DAIFMT_DSP_B:
1302                 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1303                                 != SND_SOC_DAIFMT_CBM_CFM) {
1304                         arizona_aif_err(dai, "DSP_B not valid in slave mode\n");
1305                         return -EINVAL;
1306                 }
1307                 mode = ARIZONA_FMT_DSP_MODE_B;
1308                 break;
1309         case SND_SOC_DAIFMT_I2S:
1310                 mode = ARIZONA_FMT_I2S_MODE;
1311                 break;
1312         case SND_SOC_DAIFMT_LEFT_J:
1313                 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1314                                 != SND_SOC_DAIFMT_CBM_CFM) {
1315                         arizona_aif_err(dai, "LEFT_J not valid in slave mode\n");
1316                         return -EINVAL;
1317                 }
1318                 mode = ARIZONA_FMT_LEFT_JUSTIFIED_MODE;
1319                 break;
1320         default:
1321                 arizona_aif_err(dai, "Unsupported DAI format %d\n",
1322                                 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1323                 return -EINVAL;
1324         }
1325
1326         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1327         case SND_SOC_DAIFMT_CBS_CFS:
1328                 break;
1329         case SND_SOC_DAIFMT_CBS_CFM:
1330                 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1331                 break;
1332         case SND_SOC_DAIFMT_CBM_CFS:
1333                 bclk |= ARIZONA_AIF1_BCLK_MSTR;
1334                 break;
1335         case SND_SOC_DAIFMT_CBM_CFM:
1336                 bclk |= ARIZONA_AIF1_BCLK_MSTR;
1337                 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1338                 break;
1339         default:
1340                 arizona_aif_err(dai, "Unsupported master mode %d\n",
1341                                 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1342                 return -EINVAL;
1343         }
1344
1345         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1346         case SND_SOC_DAIFMT_NB_NF:
1347                 break;
1348         case SND_SOC_DAIFMT_IB_IF:
1349                 bclk |= ARIZONA_AIF1_BCLK_INV;
1350                 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1351                 break;
1352         case SND_SOC_DAIFMT_IB_NF:
1353                 bclk |= ARIZONA_AIF1_BCLK_INV;
1354                 break;
1355         case SND_SOC_DAIFMT_NB_IF:
1356                 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1357                 break;
1358         default:
1359                 return -EINVAL;
1360         }
1361
1362         regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
1363                                  ARIZONA_AIF1_BCLK_INV |
1364                                  ARIZONA_AIF1_BCLK_MSTR,
1365                                  bclk);
1366         regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
1367                                  ARIZONA_AIF1TX_LRCLK_INV |
1368                                  ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
1369         regmap_update_bits_async(arizona->regmap,
1370                                  base + ARIZONA_AIF_RX_PIN_CTRL,
1371                                  ARIZONA_AIF1RX_LRCLK_INV |
1372                                  ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
1373         regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
1374                            ARIZONA_AIF1_FMT_MASK, mode);
1375
1376         return 0;
1377 }
1378
1379 static const int arizona_48k_bclk_rates[] = {
1380         -1,
1381         48000,
1382         64000,
1383         96000,
1384         128000,
1385         192000,
1386         256000,
1387         384000,
1388         512000,
1389         768000,
1390         1024000,
1391         1536000,
1392         2048000,
1393         3072000,
1394         4096000,
1395         6144000,
1396         8192000,
1397         12288000,
1398         24576000,
1399 };
1400
1401 static const int arizona_44k1_bclk_rates[] = {
1402         -1,
1403         44100,
1404         58800,
1405         88200,
1406         117600,
1407         177640,
1408         235200,
1409         352800,
1410         470400,
1411         705600,
1412         940800,
1413         1411200,
1414         1881600,
1415         2822400,
1416         3763200,
1417         5644800,
1418         7526400,
1419         11289600,
1420         22579200,
1421 };
1422
1423 static const unsigned int arizona_sr_vals[] = {
1424         0,
1425         12000,
1426         24000,
1427         48000,
1428         96000,
1429         192000,
1430         384000,
1431         768000,
1432         0,
1433         11025,
1434         22050,
1435         44100,
1436         88200,
1437         176400,
1438         352800,
1439         705600,
1440         4000,
1441         8000,
1442         16000,
1443         32000,
1444         64000,
1445         128000,
1446         256000,
1447         512000,
1448 };
1449
1450 #define ARIZONA_48K_RATE_MASK   0x0F003E
1451 #define ARIZONA_44K1_RATE_MASK  0x003E00
1452 #define ARIZONA_RATE_MASK       (ARIZONA_48K_RATE_MASK | ARIZONA_44K1_RATE_MASK)
1453
1454 static const struct snd_pcm_hw_constraint_list arizona_constraint = {
1455         .count  = ARRAY_SIZE(arizona_sr_vals),
1456         .list   = arizona_sr_vals,
1457 };
1458
1459 static int arizona_startup(struct snd_pcm_substream *substream,
1460                            struct snd_soc_dai *dai)
1461 {
1462         struct snd_soc_codec *codec = dai->codec;
1463         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1464         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1465         unsigned int base_rate;
1466
1467         if (!substream->runtime)
1468                 return 0;
1469
1470         switch (dai_priv->clk) {
1471         case ARIZONA_CLK_SYSCLK:
1472                 base_rate = priv->sysclk;
1473                 break;
1474         case ARIZONA_CLK_ASYNCCLK:
1475                 base_rate = priv->asyncclk;
1476                 break;
1477         default:
1478                 return 0;
1479         }
1480
1481         if (base_rate == 0)
1482                 dai_priv->constraint.mask = ARIZONA_RATE_MASK;
1483         else if (base_rate % 8000)
1484                 dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK;
1485         else
1486                 dai_priv->constraint.mask = ARIZONA_48K_RATE_MASK;
1487
1488         return snd_pcm_hw_constraint_list(substream->runtime, 0,
1489                                           SNDRV_PCM_HW_PARAM_RATE,
1490                                           &dai_priv->constraint);
1491 }
1492
1493 static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec,
1494                                         unsigned int rate)
1495 {
1496         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1497         struct arizona *arizona = priv->arizona;
1498         struct reg_sequence dac_comp[] = {
1499                 { 0x80, 0x3 },
1500                 { ARIZONA_DAC_COMP_1, 0 },
1501                 { ARIZONA_DAC_COMP_2, 0 },
1502                 { 0x80, 0x0 },
1503         };
1504
1505         mutex_lock(&arizona->dac_comp_lock);
1506
1507         dac_comp[1].def = arizona->dac_comp_coeff;
1508         if (rate >= 176400)
1509                 dac_comp[2].def = arizona->dac_comp_enabled;
1510
1511         mutex_unlock(&arizona->dac_comp_lock);
1512
1513         regmap_multi_reg_write(arizona->regmap,
1514                                dac_comp,
1515                                ARRAY_SIZE(dac_comp));
1516 }
1517
1518 static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1519                                   struct snd_pcm_hw_params *params,
1520                                   struct snd_soc_dai *dai)
1521 {
1522         struct snd_soc_codec *codec = dai->codec;
1523         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1524         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1525         int base = dai->driver->base;
1526         int i, sr_val, ret;
1527
1528         /*
1529          * We will need to be more flexible than this in future,
1530          * currently we use a single sample rate for SYSCLK.
1531          */
1532         for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1533                 if (arizona_sr_vals[i] == params_rate(params))
1534                         break;
1535         if (i == ARRAY_SIZE(arizona_sr_vals)) {
1536                 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1537                                 params_rate(params));
1538                 return -EINVAL;
1539         }
1540         sr_val = i;
1541
1542         switch (priv->arizona->type) {
1543         case WM5102:
1544         case WM8997:
1545                 if (arizona_sr_vals[sr_val] >= 88200)
1546                         ret = arizona_dvfs_up(codec, ARIZONA_DVFS_SR1_RQ);
1547                 else
1548                         ret = arizona_dvfs_down(codec, ARIZONA_DVFS_SR1_RQ);
1549
1550                 if (ret) {
1551                         arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
1552                         return ret;
1553                 }
1554                 break;
1555         default:
1556                 break;
1557         }
1558
1559         switch (dai_priv->clk) {
1560         case ARIZONA_CLK_SYSCLK:
1561                 switch (priv->arizona->type) {
1562                 case WM5102:
1563                         arizona_wm5102_set_dac_comp(codec,
1564                                                     params_rate(params));
1565                         break;
1566                 default:
1567                         break;
1568                 }
1569
1570                 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
1571                                     ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
1572                 if (base)
1573                         snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1574                                             ARIZONA_AIF1_RATE_MASK, 0);
1575                 break;
1576         case ARIZONA_CLK_ASYNCCLK:
1577                 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
1578                                     ARIZONA_ASYNC_SAMPLE_RATE_1_MASK, sr_val);
1579                 if (base)
1580                         snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1581                                             ARIZONA_AIF1_RATE_MASK,
1582                                             8 << ARIZONA_AIF1_RATE_SHIFT);
1583                 break;
1584         default:
1585                 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1586                 return -EINVAL;
1587         }
1588
1589         return 0;
1590 }
1591
1592 static bool arizona_aif_cfg_changed(struct snd_soc_codec *codec,
1593                                     int base, int bclk, int lrclk, int frame)
1594 {
1595         int val;
1596
1597         val = snd_soc_read(codec, base + ARIZONA_AIF_BCLK_CTRL);
1598         if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
1599                 return true;
1600
1601         val = snd_soc_read(codec, base + ARIZONA_AIF_TX_BCLK_RATE);
1602         if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
1603                 return true;
1604
1605         val = snd_soc_read(codec, base + ARIZONA_AIF_FRAME_CTRL_1);
1606         if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
1607                              ARIZONA_AIF1TX_SLOT_LEN_MASK)))
1608                 return true;
1609
1610         return false;
1611 }
1612
1613 static int arizona_hw_params(struct snd_pcm_substream *substream,
1614                              struct snd_pcm_hw_params *params,
1615                              struct snd_soc_dai *dai)
1616 {
1617         struct snd_soc_codec *codec = dai->codec;
1618         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1619         struct arizona *arizona = priv->arizona;
1620         int base = dai->driver->base;
1621         const int *rates;
1622         int i, ret, val;
1623         int channels = params_channels(params);
1624         int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1625         int tdm_width = arizona->tdm_width[dai->id - 1];
1626         int tdm_slots = arizona->tdm_slots[dai->id - 1];
1627         int bclk, lrclk, wl, frame, bclk_target;
1628         bool reconfig;
1629         unsigned int aif_tx_state, aif_rx_state;
1630
1631         if (params_rate(params) % 4000)
1632                 rates = &arizona_44k1_bclk_rates[0];
1633         else
1634                 rates = &arizona_48k_bclk_rates[0];
1635
1636         wl = params_width(params);
1637
1638         if (tdm_slots) {
1639                 arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
1640                                 tdm_slots, tdm_width);
1641                 bclk_target = tdm_slots * tdm_width * params_rate(params);
1642                 channels = tdm_slots;
1643         } else {
1644                 bclk_target = snd_soc_params_to_bclk(params);
1645                 tdm_width = wl;
1646         }
1647
1648         if (chan_limit && chan_limit < channels) {
1649                 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1650                 bclk_target /= channels;
1651                 bclk_target *= chan_limit;
1652         }
1653
1654         /* Force multiple of 2 channels for I2S mode */
1655         val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1656         val &= ARIZONA_AIF1_FMT_MASK;
1657         if ((channels & 1) && (val == ARIZONA_FMT_I2S_MODE)) {
1658                 arizona_aif_dbg(dai, "Forcing stereo mode\n");
1659                 bclk_target /= channels;
1660                 bclk_target *= channels + 1;
1661         }
1662
1663         for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1664                 if (rates[i] >= bclk_target &&
1665                     rates[i] % params_rate(params) == 0) {
1666                         bclk = i;
1667                         break;
1668                 }
1669         }
1670         if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1671                 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1672                                 params_rate(params));
1673                 return -EINVAL;
1674         }
1675
1676         lrclk = rates[bclk] / params_rate(params);
1677
1678         arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1679                         rates[bclk], rates[bclk] / lrclk);
1680
1681         frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
1682
1683         reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame);
1684
1685         if (reconfig) {
1686                 /* Save AIF TX/RX state */
1687                 aif_tx_state = snd_soc_read(codec,
1688                                             base + ARIZONA_AIF_TX_ENABLES);
1689                 aif_rx_state = snd_soc_read(codec,
1690                                             base + ARIZONA_AIF_RX_ENABLES);
1691                 /* Disable AIF TX/RX before reconfiguring it */
1692                 regmap_update_bits_async(arizona->regmap,
1693                                     base + ARIZONA_AIF_TX_ENABLES, 0xff, 0x0);
1694                 regmap_update_bits(arizona->regmap,
1695                                     base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
1696         }
1697
1698         ret = arizona_hw_params_rate(substream, params, dai);
1699         if (ret != 0)
1700                 goto restore_aif;
1701
1702         if (reconfig) {
1703                 regmap_update_bits_async(arizona->regmap,
1704                                          base + ARIZONA_AIF_BCLK_CTRL,
1705                                          ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1706                 regmap_update_bits_async(arizona->regmap,
1707                                          base + ARIZONA_AIF_TX_BCLK_RATE,
1708                                          ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1709                 regmap_update_bits_async(arizona->regmap,
1710                                          base + ARIZONA_AIF_RX_BCLK_RATE,
1711                                          ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1712                 regmap_update_bits_async(arizona->regmap,
1713                                          base + ARIZONA_AIF_FRAME_CTRL_1,
1714                                          ARIZONA_AIF1TX_WL_MASK |
1715                                          ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1716                 regmap_update_bits(arizona->regmap,
1717                                    base + ARIZONA_AIF_FRAME_CTRL_2,
1718                                    ARIZONA_AIF1RX_WL_MASK |
1719                                    ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1720         }
1721
1722 restore_aif:
1723         if (reconfig) {
1724                 /* Restore AIF TX/RX state */
1725                 regmap_update_bits_async(arizona->regmap,
1726                                          base + ARIZONA_AIF_TX_ENABLES,
1727                                          0xff, aif_tx_state);
1728                 regmap_update_bits(arizona->regmap,
1729                                    base + ARIZONA_AIF_RX_ENABLES,
1730                                    0xff, aif_rx_state);
1731         }
1732         return ret;
1733 }
1734
1735 static const char *arizona_dai_clk_str(int clk_id)
1736 {
1737         switch (clk_id) {
1738         case ARIZONA_CLK_SYSCLK:
1739                 return "SYSCLK";
1740         case ARIZONA_CLK_ASYNCCLK:
1741                 return "ASYNCCLK";
1742         default:
1743                 return "Unknown clock";
1744         }
1745 }
1746
1747 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1748                                   int clk_id, unsigned int freq, int dir)
1749 {
1750         struct snd_soc_codec *codec = dai->codec;
1751         struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1752         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1753         struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1754         struct snd_soc_dapm_route routes[2];
1755
1756         switch (clk_id) {
1757         case ARIZONA_CLK_SYSCLK:
1758         case ARIZONA_CLK_ASYNCCLK:
1759                 break;
1760         default:
1761                 return -EINVAL;
1762         }
1763
1764         if (clk_id == dai_priv->clk)
1765                 return 0;
1766
1767         if (dai->active) {
1768                 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
1769                         dai->id);
1770                 return -EBUSY;
1771         }
1772
1773         dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
1774                 arizona_dai_clk_str(clk_id));
1775
1776         memset(&routes, 0, sizeof(routes));
1777         routes[0].sink = dai->driver->capture.stream_name;
1778         routes[1].sink = dai->driver->playback.stream_name;
1779
1780         routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1781         routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1782         snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
1783
1784         routes[0].source = arizona_dai_clk_str(clk_id);
1785         routes[1].source = arizona_dai_clk_str(clk_id);
1786         snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
1787
1788         dai_priv->clk = clk_id;
1789
1790         return snd_soc_dapm_sync(dapm);
1791 }
1792
1793 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1794 {
1795         struct snd_soc_codec *codec = dai->codec;
1796         int base = dai->driver->base;
1797         unsigned int reg;
1798
1799         if (tristate)
1800                 reg = ARIZONA_AIF1_TRI;
1801         else
1802                 reg = 0;
1803
1804         return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1805                                    ARIZONA_AIF1_TRI, reg);
1806 }
1807
1808 static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
1809                                          unsigned int base,
1810                                          int channels, unsigned int mask)
1811 {
1812         struct snd_soc_codec *codec = dai->codec;
1813         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1814         struct arizona *arizona = priv->arizona;
1815         int slot, i;
1816
1817         for (i = 0; i < channels; ++i) {
1818                 slot = ffs(mask) - 1;
1819                 if (slot < 0)
1820                         return;
1821
1822                 regmap_write(arizona->regmap, base + i, slot);
1823
1824                 mask &= ~(1 << slot);
1825         }
1826
1827         if (mask)
1828                 arizona_aif_warn(dai, "Too many channels in TDM mask\n");
1829 }
1830
1831 static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1832                                 unsigned int rx_mask, int slots, int slot_width)
1833 {
1834         struct snd_soc_codec *codec = dai->codec;
1835         struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1836         struct arizona *arizona = priv->arizona;
1837         int base = dai->driver->base;
1838         int rx_max_chan = dai->driver->playback.channels_max;
1839         int tx_max_chan = dai->driver->capture.channels_max;
1840
1841         /* Only support TDM for the physical AIFs */
1842         if (dai->id > ARIZONA_MAX_AIF)
1843                 return -ENOTSUPP;
1844
1845         if (slots == 0) {
1846                 tx_mask = (1 << tx_max_chan) - 1;
1847                 rx_mask = (1 << rx_max_chan) - 1;
1848         }
1849
1850         arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3,
1851                                      tx_max_chan, tx_mask);
1852         arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11,
1853                                      rx_max_chan, rx_mask);
1854
1855         arizona->tdm_width[dai->id - 1] = slot_width;
1856         arizona->tdm_slots[dai->id - 1] = slots;
1857
1858         return 0;
1859 }
1860
1861 const struct snd_soc_dai_ops arizona_dai_ops = {
1862         .startup = arizona_startup,
1863         .set_fmt = arizona_set_fmt,
1864         .set_tdm_slot = arizona_set_tdm_slot,
1865         .hw_params = arizona_hw_params,
1866         .set_sysclk = arizona_dai_set_sysclk,
1867         .set_tristate = arizona_set_tristate,
1868 };
1869 EXPORT_SYMBOL_GPL(arizona_dai_ops);
1870
1871 const struct snd_soc_dai_ops arizona_simple_dai_ops = {
1872         .startup = arizona_startup,
1873         .hw_params = arizona_hw_params_rate,
1874         .set_sysclk = arizona_dai_set_sysclk,
1875 };
1876 EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
1877
1878 int arizona_init_dai(struct arizona_priv *priv, int id)
1879 {
1880         struct arizona_dai_priv *dai_priv = &priv->dai[id];
1881
1882         dai_priv->clk = ARIZONA_CLK_SYSCLK;
1883         dai_priv->constraint = arizona_constraint;
1884
1885         return 0;
1886 }
1887 EXPORT_SYMBOL_GPL(arizona_init_dai);
1888
1889 static struct {
1890         unsigned int min;
1891         unsigned int max;
1892         u16 fratio;
1893         int ratio;
1894 } fll_fratios[] = {
1895         {       0,    64000, 4, 16 },
1896         {   64000,   128000, 3,  8 },
1897         {  128000,   256000, 2,  4 },
1898         {  256000,  1000000, 1,  2 },
1899         { 1000000, 13500000, 0,  1 },
1900 };
1901
1902 static const unsigned int pseudo_fref_max[ARIZONA_FLL_MAX_FRATIO] = {
1903         13500000,
1904          6144000,
1905          6144000,
1906          3072000,
1907          3072000,
1908          2822400,
1909          2822400,
1910          1536000,
1911          1536000,
1912          1536000,
1913          1536000,
1914          1536000,
1915          1536000,
1916          1536000,
1917          1536000,
1918           768000,
1919 };
1920
1921 static struct {
1922         unsigned int min;
1923         unsigned int max;
1924         u16 gain;
1925 } fll_gains[] = {
1926         {       0,   256000, 0 },
1927         {  256000,  1000000, 2 },
1928         { 1000000, 13500000, 4 },
1929 };
1930
1931 struct arizona_fll_cfg {
1932         int n;
1933         int theta;
1934         int lambda;
1935         int refdiv;
1936         int outdiv;
1937         int fratio;
1938         int gain;
1939 };
1940
1941 static int arizona_validate_fll(struct arizona_fll *fll,
1942                                 unsigned int Fref,
1943                                 unsigned int Fout)
1944 {
1945         unsigned int Fvco_min;
1946
1947         if (fll->fout && Fout != fll->fout) {
1948                 arizona_fll_err(fll,
1949                                 "Can't change output on active FLL\n");
1950                 return -EINVAL;
1951         }
1952
1953         if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
1954                 arizona_fll_err(fll,
1955                                 "Can't scale %dMHz in to <=13.5MHz\n",
1956                                 Fref);
1957                 return -EINVAL;
1958         }
1959
1960         Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
1961         if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
1962                 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1963                                 Fout);
1964                 return -EINVAL;
1965         }
1966
1967         return 0;
1968 }
1969
1970 static int arizona_find_fratio(unsigned int Fref, int *fratio)
1971 {
1972         int i;
1973
1974         /* Find an appropriate FLL_FRATIO */
1975         for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1976                 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1977                         if (fratio)
1978                                 *fratio = fll_fratios[i].fratio;
1979                         return fll_fratios[i].ratio;
1980                 }
1981         }
1982
1983         return -EINVAL;
1984 }
1985
1986 static int arizona_calc_fratio(struct arizona_fll *fll,
1987                                struct arizona_fll_cfg *cfg,
1988                                unsigned int target,
1989                                unsigned int Fref, bool sync)
1990 {
1991         int init_ratio, ratio;
1992         int refdiv, div;
1993
1994         /* Fref must be <=13.5MHz, find initial refdiv */
1995         div = 1;
1996         cfg->refdiv = 0;
1997         while (Fref > ARIZONA_FLL_MAX_FREF) {
1998                 div *= 2;
1999                 Fref /= 2;
2000                 cfg->refdiv++;
2001
2002                 if (div > ARIZONA_FLL_MAX_REFDIV)
2003                         return -EINVAL;
2004         }
2005
2006         /* Find an appropriate FLL_FRATIO */
2007         init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
2008         if (init_ratio < 0) {
2009                 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
2010                                 Fref);
2011                 return init_ratio;
2012         }
2013
2014         switch (fll->arizona->type) {
2015         case WM5102:
2016         case WM8997:
2017                 return init_ratio;
2018         case WM5110:
2019         case WM8280:
2020                 if (fll->arizona->rev < 3 || sync)
2021                         return init_ratio;
2022                 break;
2023         default:
2024                 if (sync)
2025                         return init_ratio;
2026                 break;
2027         }
2028
2029         cfg->fratio = init_ratio - 1;
2030
2031         /* Adjust FRATIO/refdiv to avoid integer mode if possible */
2032         refdiv = cfg->refdiv;
2033
2034         arizona_fll_dbg(fll, "pseudo: initial ratio=%u fref=%u refdiv=%u\n",
2035                         init_ratio, Fref, refdiv);
2036
2037         while (div <= ARIZONA_FLL_MAX_REFDIV) {
2038                 for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO;
2039                      ratio++) {
2040                         if ((ARIZONA_FLL_VCO_CORNER / 2) /
2041                             (fll->vco_mult * ratio) < Fref) {
2042                                 arizona_fll_dbg(fll, "pseudo: hit VCO corner\n");
2043                                 break;
2044                         }
2045
2046                         if (Fref > pseudo_fref_max[ratio - 1]) {
2047                                 arizona_fll_dbg(fll,
2048                                         "pseudo: exceeded max fref(%u) for ratio=%u\n",
2049                                         pseudo_fref_max[ratio - 1],
2050                                         ratio);
2051                                 break;
2052                         }
2053
2054                         if (target % (ratio * Fref)) {
2055                                 cfg->refdiv = refdiv;
2056                                 cfg->fratio = ratio - 1;
2057                                 arizona_fll_dbg(fll,
2058                                         "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2059                                         Fref, refdiv, div, ratio);
2060                                 return ratio;
2061                         }
2062                 }
2063
2064                 for (ratio = init_ratio - 1; ratio > 0; ratio--) {
2065                         if (target % (ratio * Fref)) {
2066                                 cfg->refdiv = refdiv;
2067                                 cfg->fratio = ratio - 1;
2068                                 arizona_fll_dbg(fll,
2069                                         "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2070                                         Fref, refdiv, div, ratio);
2071                                 return ratio;
2072                         }
2073                 }
2074
2075                 div *= 2;
2076                 Fref /= 2;
2077                 refdiv++;
2078                 init_ratio = arizona_find_fratio(Fref, NULL);
2079                 arizona_fll_dbg(fll,
2080                                 "pseudo: change fref=%u refdiv=%d(%d) ratio=%u\n",
2081                                 Fref, refdiv, div, init_ratio);
2082         }
2083
2084         arizona_fll_warn(fll, "Falling back to integer mode operation\n");
2085         return cfg->fratio + 1;
2086 }
2087
2088 static int arizona_calc_fll(struct arizona_fll *fll,
2089                             struct arizona_fll_cfg *cfg,
2090                             unsigned int Fref, bool sync)
2091 {
2092         unsigned int target, div, gcd_fll;
2093         int i, ratio;
2094
2095         arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
2096
2097         /* Fvco should be over the targt; don't check the upper bound */
2098         div = ARIZONA_FLL_MIN_OUTDIV;
2099         while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
2100                 div++;
2101                 if (div > ARIZONA_FLL_MAX_OUTDIV)
2102                         return -EINVAL;
2103         }
2104         target = fll->fout * div / fll->vco_mult;
2105         cfg->outdiv = div;
2106
2107         arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
2108
2109         /* Find an appropriate FLL_FRATIO and refdiv */
2110         ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
2111         if (ratio < 0)
2112                 return ratio;
2113
2114         /* Apply the division for our remaining calculations */
2115         Fref = Fref / (1 << cfg->refdiv);
2116
2117         cfg->n = target / (ratio * Fref);
2118
2119         if (target % (ratio * Fref)) {
2120                 gcd_fll = gcd(target, ratio * Fref);
2121                 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
2122
2123                 cfg->theta = (target - (cfg->n * ratio * Fref))
2124                         / gcd_fll;
2125                 cfg->lambda = (ratio * Fref) / gcd_fll;
2126         } else {
2127                 cfg->theta = 0;
2128                 cfg->lambda = 0;
2129         }
2130
2131         /* Round down to 16bit range with cost of accuracy lost.
2132          * Denominator must be bigger than numerator so we only
2133          * take care of it.
2134          */
2135         while (cfg->lambda >= (1 << 16)) {
2136                 cfg->theta >>= 1;
2137                 cfg->lambda >>= 1;
2138         }
2139
2140         for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
2141                 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
2142                         cfg->gain = fll_gains[i].gain;
2143                         break;
2144                 }
2145         }
2146         if (i == ARRAY_SIZE(fll_gains)) {
2147                 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
2148                                 Fref);
2149                 return -EINVAL;
2150         }
2151
2152         arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
2153                         cfg->n, cfg->theta, cfg->lambda);
2154         arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n",
2155                         cfg->fratio, ratio, cfg->outdiv,
2156                         cfg->refdiv, 1 << cfg->refdiv);
2157         arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
2158
2159         return 0;
2160
2161 }
2162
2163 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
2164                               struct arizona_fll_cfg *cfg, int source,
2165                               bool sync)
2166 {
2167         regmap_update_bits_async(arizona->regmap, base + 3,
2168                                  ARIZONA_FLL1_THETA_MASK, cfg->theta);
2169         regmap_update_bits_async(arizona->regmap, base + 4,
2170                                  ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
2171         regmap_update_bits_async(arizona->regmap, base + 5,
2172                                  ARIZONA_FLL1_FRATIO_MASK,
2173                                  cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
2174         regmap_update_bits_async(arizona->regmap, base + 6,
2175                                  ARIZONA_FLL1_CLK_REF_DIV_MASK |
2176                                  ARIZONA_FLL1_CLK_REF_SRC_MASK,
2177                                  cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
2178                                  source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
2179
2180         if (sync) {
2181                 regmap_update_bits(arizona->regmap, base + 0x7,
2182                                    ARIZONA_FLL1_GAIN_MASK,
2183                                    cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2184         } else {
2185                 regmap_update_bits(arizona->regmap, base + 0x5,
2186                                    ARIZONA_FLL1_OUTDIV_MASK,
2187                                    cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
2188                 regmap_update_bits(arizona->regmap, base + 0x9,
2189                                    ARIZONA_FLL1_GAIN_MASK,
2190                                    cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2191         }
2192
2193         regmap_update_bits_async(arizona->regmap, base + 2,
2194                                  ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
2195                                  ARIZONA_FLL1_CTRL_UPD | cfg->n);
2196 }
2197
2198 static int arizona_is_enabled_fll(struct arizona_fll *fll)
2199 {
2200         struct arizona *arizona = fll->arizona;
2201         unsigned int reg;
2202         int ret;
2203
2204         ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
2205         if (ret != 0) {
2206                 arizona_fll_err(fll, "Failed to read current state: %d\n",
2207                                 ret);
2208                 return ret;
2209         }
2210
2211         return reg & ARIZONA_FLL1_ENA;
2212 }
2213
2214 static int arizona_enable_fll(struct arizona_fll *fll)
2215 {
2216         struct arizona *arizona = fll->arizona;
2217         bool use_sync = false;
2218         int already_enabled = arizona_is_enabled_fll(fll);
2219         struct arizona_fll_cfg cfg;
2220         int i;
2221         unsigned int val;
2222
2223         if (already_enabled < 0)
2224                 return already_enabled;
2225
2226         if (already_enabled) {
2227                 /* Facilitate smooth refclk across the transition */
2228                 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2229                                          ARIZONA_FLL1_GAIN_MASK, 0);
2230                 regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2231                                    ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2232                 udelay(32);
2233         }
2234
2235         /*
2236          * If we have both REFCLK and SYNCCLK then enable both,
2237          * otherwise apply the SYNCCLK settings to REFCLK.
2238          */
2239         if (fll->ref_src >= 0 && fll->ref_freq &&
2240             fll->ref_src != fll->sync_src) {
2241                 arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
2242
2243                 arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
2244                                   false);
2245                 if (fll->sync_src >= 0) {
2246                         arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
2247
2248                         arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
2249                                           fll->sync_src, true);
2250                         use_sync = true;
2251                 }
2252         } else if (fll->sync_src >= 0) {
2253                 arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
2254
2255                 arizona_apply_fll(arizona, fll->base, &cfg,
2256                                   fll->sync_src, false);
2257
2258                 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2259                                          ARIZONA_FLL1_SYNC_ENA, 0);
2260         } else {
2261                 arizona_fll_err(fll, "No clocks provided\n");
2262                 return -EINVAL;
2263         }
2264
2265         /*
2266          * Increase the bandwidth if we're not using a low frequency
2267          * sync source.
2268          */
2269         if (use_sync && fll->sync_freq > 100000)
2270                 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2271                                          ARIZONA_FLL1_SYNC_BW, 0);
2272         else
2273                 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2274                                          ARIZONA_FLL1_SYNC_BW,
2275                                          ARIZONA_FLL1_SYNC_BW);
2276
2277         if (!already_enabled)
2278                 pm_runtime_get(arizona->dev);
2279
2280         regmap_update_bits_async(arizona->regmap, fll->base + 1,
2281                                  ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
2282         if (use_sync)
2283                 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2284                                          ARIZONA_FLL1_SYNC_ENA,
2285                                          ARIZONA_FLL1_SYNC_ENA);
2286
2287         if (already_enabled)
2288                 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2289                                          ARIZONA_FLL1_FREERUN, 0);
2290
2291         arizona_fll_dbg(fll, "Waiting for FLL lock...\n");
2292         val = 0;
2293         for (i = 0; i < 15; i++) {
2294                 if (i < 5)
2295                         usleep_range(200, 400);
2296                 else
2297                         msleep(20);
2298
2299                 regmap_read(arizona->regmap,
2300                             ARIZONA_INTERRUPT_RAW_STATUS_5,
2301                             &val);
2302                 if (val & (ARIZONA_FLL1_CLOCK_OK_STS << (fll->id - 1)))
2303                         break;
2304         }
2305         if (i == 15)
2306                 arizona_fll_warn(fll, "Timed out waiting for lock\n");
2307         else
2308                 arizona_fll_dbg(fll, "FLL locked (%d polls)\n", i);
2309
2310         return 0;
2311 }
2312
2313 static void arizona_disable_fll(struct arizona_fll *fll)
2314 {
2315         struct arizona *arizona = fll->arizona;
2316         bool change;
2317
2318         regmap_update_bits_async(arizona->regmap, fll->base + 1,
2319                                  ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2320         regmap_update_bits_check(arizona->regmap, fll->base + 1,
2321                                  ARIZONA_FLL1_ENA, 0, &change);
2322         regmap_update_bits(arizona->regmap, fll->base + 0x11,
2323                            ARIZONA_FLL1_SYNC_ENA, 0);
2324         regmap_update_bits_async(arizona->regmap, fll->base + 1,
2325                                  ARIZONA_FLL1_FREERUN, 0);
2326
2327         if (change)
2328                 pm_runtime_put_autosuspend(arizona->dev);
2329 }
2330
2331 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
2332                            unsigned int Fref, unsigned int Fout)
2333 {
2334         int ret = 0;
2335
2336         if (fll->ref_src == source && fll->ref_freq == Fref)
2337                 return 0;
2338
2339         if (fll->fout && Fref > 0) {
2340                 ret = arizona_validate_fll(fll, Fref, fll->fout);
2341                 if (ret != 0)
2342                         return ret;
2343         }
2344
2345         fll->ref_src = source;
2346         fll->ref_freq = Fref;
2347
2348         if (fll->fout && Fref > 0) {
2349                 ret = arizona_enable_fll(fll);
2350         }
2351
2352         return ret;
2353 }
2354 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
2355
2356 int arizona_set_fll(struct arizona_fll *fll, int source,
2357                     unsigned int Fref, unsigned int Fout)
2358 {
2359         int ret = 0;
2360
2361         if (fll->sync_src == source &&
2362             fll->sync_freq == Fref && fll->fout == Fout)
2363                 return 0;
2364
2365         if (Fout) {
2366                 if (fll->ref_src >= 0) {
2367                         ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
2368                         if (ret != 0)
2369                                 return ret;
2370                 }
2371
2372                 ret = arizona_validate_fll(fll, Fref, Fout);
2373                 if (ret != 0)
2374                         return ret;
2375         }
2376
2377         fll->sync_src = source;
2378         fll->sync_freq = Fref;
2379         fll->fout = Fout;
2380
2381         if (Fout)
2382                 ret = arizona_enable_fll(fll);
2383         else
2384                 arizona_disable_fll(fll);
2385
2386         return ret;
2387 }
2388 EXPORT_SYMBOL_GPL(arizona_set_fll);
2389
2390 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
2391                      int ok_irq, struct arizona_fll *fll)
2392 {
2393         unsigned int val;
2394
2395         fll->id = id;
2396         fll->base = base;
2397         fll->arizona = arizona;
2398         fll->sync_src = ARIZONA_FLL_SRC_NONE;
2399
2400         /* Configure default refclk to 32kHz if we have one */
2401         regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
2402         switch (val & ARIZONA_CLK_32K_SRC_MASK) {
2403         case ARIZONA_CLK_SRC_MCLK1:
2404         case ARIZONA_CLK_SRC_MCLK2:
2405                 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
2406                 break;
2407         default:
2408                 fll->ref_src = ARIZONA_FLL_SRC_NONE;
2409         }
2410         fll->ref_freq = 32768;
2411
2412         snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
2413         snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
2414                  "FLL%d clock OK", id);
2415
2416         regmap_update_bits(arizona->regmap, fll->base + 1,
2417                            ARIZONA_FLL1_FREERUN, 0);
2418
2419         return 0;
2420 }
2421 EXPORT_SYMBOL_GPL(arizona_init_fll);
2422
2423 /**
2424  * arizona_set_output_mode - Set the mode of the specified output
2425  *
2426  * @codec: Device to configure
2427  * @output: Output number
2428  * @diff: True to set the output to differential mode
2429  *
2430  * Some systems use external analogue switches to connect more
2431  * analogue devices to the CODEC than are supported by the device.  In
2432  * some systems this requires changing the switched output from single
2433  * ended to differential mode dynamically at runtime, an operation
2434  * supported using this function.
2435  *
2436  * Most systems have a single static configuration and should use
2437  * platform data instead.
2438  */
2439 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
2440 {
2441         unsigned int reg, val;
2442
2443         if (output < 1 || output > 6)
2444                 return -EINVAL;
2445
2446         reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
2447
2448         if (diff)
2449                 val = ARIZONA_OUT1_MONO;
2450         else
2451                 val = 0;
2452
2453         return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
2454 }
2455 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
2456
2457 static const struct soc_enum arizona_adsp2_rate_enum[] = {
2458         SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
2459                               ARIZONA_DSP1_RATE_SHIFT, 0xf,
2460                               ARIZONA_RATE_ENUM_SIZE,
2461                               arizona_rate_text, arizona_rate_val),
2462         SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
2463                               ARIZONA_DSP1_RATE_SHIFT, 0xf,
2464                               ARIZONA_RATE_ENUM_SIZE,
2465                               arizona_rate_text, arizona_rate_val),
2466         SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
2467                               ARIZONA_DSP1_RATE_SHIFT, 0xf,
2468                               ARIZONA_RATE_ENUM_SIZE,
2469                               arizona_rate_text, arizona_rate_val),
2470         SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
2471                               ARIZONA_DSP1_RATE_SHIFT, 0xf,
2472                               ARIZONA_RATE_ENUM_SIZE,
2473                               arizona_rate_text, arizona_rate_val),
2474 };
2475
2476 const struct snd_kcontrol_new arizona_adsp2_rate_controls[] = {
2477         SOC_ENUM("DSP1 Rate", arizona_adsp2_rate_enum[0]),
2478         SOC_ENUM("DSP2 Rate", arizona_adsp2_rate_enum[1]),
2479         SOC_ENUM("DSP3 Rate", arizona_adsp2_rate_enum[2]),
2480         SOC_ENUM("DSP4 Rate", arizona_adsp2_rate_enum[3]),
2481 };
2482 EXPORT_SYMBOL_GPL(arizona_adsp2_rate_controls);
2483
2484 static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
2485 {
2486         s16 a = be16_to_cpu(_a);
2487         s16 b = be16_to_cpu(_b);
2488
2489         if (!mode) {
2490                 return abs(a) >= 4096;
2491         } else {
2492                 if (abs(b) >= 4096)
2493                         return true;
2494
2495                 return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
2496         }
2497 }
2498
2499 int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
2500                          struct snd_ctl_elem_value *ucontrol)
2501 {
2502         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2503         struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
2504         struct soc_bytes *params = (void *)kcontrol->private_value;
2505         unsigned int val;
2506         __be16 *data;
2507         int len;
2508         int ret;
2509
2510         len = params->num_regs * regmap_get_val_bytes(arizona->regmap);
2511
2512         data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
2513         if (!data)
2514                 return -ENOMEM;
2515
2516         data[0] &= cpu_to_be16(ARIZONA_EQ1_B1_MODE);
2517
2518         if (arizona_eq_filter_unstable(!!data[0], data[1], data[2]) ||
2519             arizona_eq_filter_unstable(true, data[4], data[5]) ||
2520             arizona_eq_filter_unstable(true, data[8], data[9]) ||
2521             arizona_eq_filter_unstable(true, data[12], data[13]) ||
2522             arizona_eq_filter_unstable(false, data[16], data[17])) {
2523                 dev_err(arizona->dev, "Rejecting unstable EQ coefficients\n");
2524                 ret = -EINVAL;
2525                 goto out;
2526         }
2527
2528         ret = regmap_read(arizona->regmap, params->base, &val);
2529         if (ret != 0)
2530                 goto out;
2531
2532         val &= ~ARIZONA_EQ1_B1_MODE;
2533         data[0] |= cpu_to_be16(val);
2534
2535         ret = regmap_raw_write(arizona->regmap, params->base, data, len);
2536
2537 out:
2538         kfree(data);
2539         return ret;
2540 }
2541 EXPORT_SYMBOL_GPL(arizona_eq_coeff_put);
2542
2543 int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
2544                            struct snd_ctl_elem_value *ucontrol)
2545 {
2546         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2547         struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
2548         __be16 *data = (__be16 *)ucontrol->value.bytes.data;
2549         s16 val = be16_to_cpu(*data);
2550
2551         if (abs(val) >= 4096) {
2552                 dev_err(arizona->dev, "Rejecting unstable LHPF coefficients\n");
2553                 return -EINVAL;
2554         }
2555
2556         return snd_soc_bytes_put(kcontrol, ucontrol);
2557 }
2558 EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
2559
2560 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2561 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2562 MODULE_LICENSE("GPL");