]> git.karo-electronics.de Git - karo-tx-linux.git/blob - sound/soc/codecs/arizona.c
ASoC: arizona: Make logging of FLL calculations clearer
[karo-tx-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 struct {
1903         unsigned int min;
1904         unsigned int max;
1905         u16 gain;
1906 } fll_gains[] = {
1907         {       0,   256000, 0 },
1908         {  256000,  1000000, 2 },
1909         { 1000000, 13500000, 4 },
1910 };
1911
1912 struct arizona_fll_cfg {
1913         int n;
1914         int theta;
1915         int lambda;
1916         int refdiv;
1917         int outdiv;
1918         int fratio;
1919         int gain;
1920 };
1921
1922 static int arizona_validate_fll(struct arizona_fll *fll,
1923                                 unsigned int Fref,
1924                                 unsigned int Fout)
1925 {
1926         unsigned int Fvco_min;
1927
1928         if (fll->fout && Fout != fll->fout) {
1929                 arizona_fll_err(fll,
1930                                 "Can't change output on active FLL\n");
1931                 return -EINVAL;
1932         }
1933
1934         if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
1935                 arizona_fll_err(fll,
1936                                 "Can't scale %dMHz in to <=13.5MHz\n",
1937                                 Fref);
1938                 return -EINVAL;
1939         }
1940
1941         Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
1942         if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
1943                 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
1944                                 Fout);
1945                 return -EINVAL;
1946         }
1947
1948         return 0;
1949 }
1950
1951 static int arizona_find_fratio(unsigned int Fref, int *fratio)
1952 {
1953         int i;
1954
1955         /* Find an appropriate FLL_FRATIO */
1956         for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1957                 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1958                         if (fratio)
1959                                 *fratio = fll_fratios[i].fratio;
1960                         return fll_fratios[i].ratio;
1961                 }
1962         }
1963
1964         return -EINVAL;
1965 }
1966
1967 static int arizona_calc_fratio(struct arizona_fll *fll,
1968                                struct arizona_fll_cfg *cfg,
1969                                unsigned int target,
1970                                unsigned int Fref, bool sync)
1971 {
1972         int init_ratio, ratio;
1973         int refdiv, div;
1974
1975         /* Fref must be <=13.5MHz, find initial refdiv */
1976         div = 1;
1977         cfg->refdiv = 0;
1978         while (Fref > ARIZONA_FLL_MAX_FREF) {
1979                 div *= 2;
1980                 Fref /= 2;
1981                 cfg->refdiv++;
1982
1983                 if (div > ARIZONA_FLL_MAX_REFDIV)
1984                         return -EINVAL;
1985         }
1986
1987         /* Find an appropriate FLL_FRATIO */
1988         init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
1989         if (init_ratio < 0) {
1990                 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
1991                                 Fref);
1992                 return init_ratio;
1993         }
1994
1995         switch (fll->arizona->type) {
1996         case WM5102:
1997         case WM8997:
1998                 return init_ratio;
1999         case WM5110:
2000         case WM8280:
2001                 if (fll->arizona->rev < 3 || sync)
2002                         return init_ratio;
2003                 break;
2004         default:
2005                 if (sync)
2006                         return init_ratio;
2007                 break;
2008         }
2009
2010         cfg->fratio = init_ratio - 1;
2011
2012         /* Adjust FRATIO/refdiv to avoid integer mode if possible */
2013         refdiv = cfg->refdiv;
2014
2015         while (div <= ARIZONA_FLL_MAX_REFDIV) {
2016                 for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO;
2017                      ratio++) {
2018                         if ((ARIZONA_FLL_VCO_CORNER / 2) /
2019                             (fll->vco_mult * ratio) < Fref)
2020                                 break;
2021
2022                         if (target % (ratio * Fref)) {
2023                                 cfg->refdiv = refdiv;
2024                                 cfg->fratio = ratio - 1;
2025                                 return ratio;
2026                         }
2027                 }
2028
2029                 for (ratio = init_ratio - 1; ratio > 0; ratio--) {
2030                         if (target % (ratio * Fref)) {
2031                                 cfg->refdiv = refdiv;
2032                                 cfg->fratio = ratio - 1;
2033                                 return ratio;
2034                         }
2035                 }
2036
2037                 div *= 2;
2038                 Fref /= 2;
2039                 refdiv++;
2040                 init_ratio = arizona_find_fratio(Fref, NULL);
2041         }
2042
2043         arizona_fll_warn(fll, "Falling back to integer mode operation\n");
2044         return cfg->fratio + 1;
2045 }
2046
2047 static int arizona_calc_fll(struct arizona_fll *fll,
2048                             struct arizona_fll_cfg *cfg,
2049                             unsigned int Fref, bool sync)
2050 {
2051         unsigned int target, div, gcd_fll;
2052         int i, ratio;
2053
2054         arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
2055
2056         /* Fvco should be over the targt; don't check the upper bound */
2057         div = ARIZONA_FLL_MIN_OUTDIV;
2058         while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
2059                 div++;
2060                 if (div > ARIZONA_FLL_MAX_OUTDIV)
2061                         return -EINVAL;
2062         }
2063         target = fll->fout * div / fll->vco_mult;
2064         cfg->outdiv = div;
2065
2066         arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
2067
2068         /* Find an appropriate FLL_FRATIO and refdiv */
2069         ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
2070         if (ratio < 0)
2071                 return ratio;
2072
2073         /* Apply the division for our remaining calculations */
2074         Fref = Fref / (1 << cfg->refdiv);
2075
2076         cfg->n = target / (ratio * Fref);
2077
2078         if (target % (ratio * Fref)) {
2079                 gcd_fll = gcd(target, ratio * Fref);
2080                 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
2081
2082                 cfg->theta = (target - (cfg->n * ratio * Fref))
2083                         / gcd_fll;
2084                 cfg->lambda = (ratio * Fref) / gcd_fll;
2085         } else {
2086                 cfg->theta = 0;
2087                 cfg->lambda = 0;
2088         }
2089
2090         /* Round down to 16bit range with cost of accuracy lost.
2091          * Denominator must be bigger than numerator so we only
2092          * take care of it.
2093          */
2094         while (cfg->lambda >= (1 << 16)) {
2095                 cfg->theta >>= 1;
2096                 cfg->lambda >>= 1;
2097         }
2098
2099         for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
2100                 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
2101                         cfg->gain = fll_gains[i].gain;
2102                         break;
2103                 }
2104         }
2105         if (i == ARRAY_SIZE(fll_gains)) {
2106                 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
2107                                 Fref);
2108                 return -EINVAL;
2109         }
2110
2111         arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
2112                         cfg->n, cfg->theta, cfg->lambda);
2113         arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n",
2114                         cfg->fratio, ratio, cfg->outdiv,
2115                         cfg->refdiv, 1 << cfg->refdiv);
2116         arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
2117
2118         return 0;
2119
2120 }
2121
2122 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
2123                               struct arizona_fll_cfg *cfg, int source,
2124                               bool sync)
2125 {
2126         regmap_update_bits_async(arizona->regmap, base + 3,
2127                                  ARIZONA_FLL1_THETA_MASK, cfg->theta);
2128         regmap_update_bits_async(arizona->regmap, base + 4,
2129                                  ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
2130         regmap_update_bits_async(arizona->regmap, base + 5,
2131                                  ARIZONA_FLL1_FRATIO_MASK,
2132                                  cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
2133         regmap_update_bits_async(arizona->regmap, base + 6,
2134                                  ARIZONA_FLL1_CLK_REF_DIV_MASK |
2135                                  ARIZONA_FLL1_CLK_REF_SRC_MASK,
2136                                  cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
2137                                  source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
2138
2139         if (sync) {
2140                 regmap_update_bits(arizona->regmap, base + 0x7,
2141                                    ARIZONA_FLL1_GAIN_MASK,
2142                                    cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2143         } else {
2144                 regmap_update_bits(arizona->regmap, base + 0x5,
2145                                    ARIZONA_FLL1_OUTDIV_MASK,
2146                                    cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
2147                 regmap_update_bits(arizona->regmap, base + 0x9,
2148                                    ARIZONA_FLL1_GAIN_MASK,
2149                                    cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2150         }
2151
2152         regmap_update_bits_async(arizona->regmap, base + 2,
2153                                  ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
2154                                  ARIZONA_FLL1_CTRL_UPD | cfg->n);
2155 }
2156
2157 static int arizona_is_enabled_fll(struct arizona_fll *fll)
2158 {
2159         struct arizona *arizona = fll->arizona;
2160         unsigned int reg;
2161         int ret;
2162
2163         ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
2164         if (ret != 0) {
2165                 arizona_fll_err(fll, "Failed to read current state: %d\n",
2166                                 ret);
2167                 return ret;
2168         }
2169
2170         return reg & ARIZONA_FLL1_ENA;
2171 }
2172
2173 static int arizona_enable_fll(struct arizona_fll *fll)
2174 {
2175         struct arizona *arizona = fll->arizona;
2176         bool use_sync = false;
2177         int already_enabled = arizona_is_enabled_fll(fll);
2178         struct arizona_fll_cfg cfg;
2179         int i;
2180         unsigned int val;
2181
2182         if (already_enabled < 0)
2183                 return already_enabled;
2184
2185         if (already_enabled) {
2186                 /* Facilitate smooth refclk across the transition */
2187                 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2188                                          ARIZONA_FLL1_GAIN_MASK, 0);
2189                 regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2190                                    ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2191                 udelay(32);
2192         }
2193
2194         /*
2195          * If we have both REFCLK and SYNCCLK then enable both,
2196          * otherwise apply the SYNCCLK settings to REFCLK.
2197          */
2198         if (fll->ref_src >= 0 && fll->ref_freq &&
2199             fll->ref_src != fll->sync_src) {
2200                 arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
2201
2202                 arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
2203                                   false);
2204                 if (fll->sync_src >= 0) {
2205                         arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
2206
2207                         arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
2208                                           fll->sync_src, true);
2209                         use_sync = true;
2210                 }
2211         } else if (fll->sync_src >= 0) {
2212                 arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
2213
2214                 arizona_apply_fll(arizona, fll->base, &cfg,
2215                                   fll->sync_src, false);
2216
2217                 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2218                                          ARIZONA_FLL1_SYNC_ENA, 0);
2219         } else {
2220                 arizona_fll_err(fll, "No clocks provided\n");
2221                 return -EINVAL;
2222         }
2223
2224         /*
2225          * Increase the bandwidth if we're not using a low frequency
2226          * sync source.
2227          */
2228         if (use_sync && fll->sync_freq > 100000)
2229                 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2230                                          ARIZONA_FLL1_SYNC_BW, 0);
2231         else
2232                 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2233                                          ARIZONA_FLL1_SYNC_BW,
2234                                          ARIZONA_FLL1_SYNC_BW);
2235
2236         if (!already_enabled)
2237                 pm_runtime_get(arizona->dev);
2238
2239         regmap_update_bits_async(arizona->regmap, fll->base + 1,
2240                                  ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
2241         if (use_sync)
2242                 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2243                                          ARIZONA_FLL1_SYNC_ENA,
2244                                          ARIZONA_FLL1_SYNC_ENA);
2245
2246         if (already_enabled)
2247                 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2248                                          ARIZONA_FLL1_FREERUN, 0);
2249
2250         arizona_fll_dbg(fll, "Waiting for FLL lock...\n");
2251         val = 0;
2252         for (i = 0; i < 15; i++) {
2253                 if (i < 5)
2254                         usleep_range(200, 400);
2255                 else
2256                         msleep(20);
2257
2258                 regmap_read(arizona->regmap,
2259                             ARIZONA_INTERRUPT_RAW_STATUS_5,
2260                             &val);
2261                 if (val & (ARIZONA_FLL1_CLOCK_OK_STS << (fll->id - 1)))
2262                         break;
2263         }
2264         if (i == 15)
2265                 arizona_fll_warn(fll, "Timed out waiting for lock\n");
2266         else
2267                 arizona_fll_dbg(fll, "FLL locked (%d polls)\n", i);
2268
2269         return 0;
2270 }
2271
2272 static void arizona_disable_fll(struct arizona_fll *fll)
2273 {
2274         struct arizona *arizona = fll->arizona;
2275         bool change;
2276
2277         regmap_update_bits_async(arizona->regmap, fll->base + 1,
2278                                  ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2279         regmap_update_bits_check(arizona->regmap, fll->base + 1,
2280                                  ARIZONA_FLL1_ENA, 0, &change);
2281         regmap_update_bits(arizona->regmap, fll->base + 0x11,
2282                            ARIZONA_FLL1_SYNC_ENA, 0);
2283         regmap_update_bits_async(arizona->regmap, fll->base + 1,
2284                                  ARIZONA_FLL1_FREERUN, 0);
2285
2286         if (change)
2287                 pm_runtime_put_autosuspend(arizona->dev);
2288 }
2289
2290 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
2291                            unsigned int Fref, unsigned int Fout)
2292 {
2293         int ret = 0;
2294
2295         if (fll->ref_src == source && fll->ref_freq == Fref)
2296                 return 0;
2297
2298         if (fll->fout && Fref > 0) {
2299                 ret = arizona_validate_fll(fll, Fref, fll->fout);
2300                 if (ret != 0)
2301                         return ret;
2302         }
2303
2304         fll->ref_src = source;
2305         fll->ref_freq = Fref;
2306
2307         if (fll->fout && Fref > 0) {
2308                 ret = arizona_enable_fll(fll);
2309         }
2310
2311         return ret;
2312 }
2313 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
2314
2315 int arizona_set_fll(struct arizona_fll *fll, int source,
2316                     unsigned int Fref, unsigned int Fout)
2317 {
2318         int ret = 0;
2319
2320         if (fll->sync_src == source &&
2321             fll->sync_freq == Fref && fll->fout == Fout)
2322                 return 0;
2323
2324         if (Fout) {
2325                 if (fll->ref_src >= 0) {
2326                         ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
2327                         if (ret != 0)
2328                                 return ret;
2329                 }
2330
2331                 ret = arizona_validate_fll(fll, Fref, Fout);
2332                 if (ret != 0)
2333                         return ret;
2334         }
2335
2336         fll->sync_src = source;
2337         fll->sync_freq = Fref;
2338         fll->fout = Fout;
2339
2340         if (Fout)
2341                 ret = arizona_enable_fll(fll);
2342         else
2343                 arizona_disable_fll(fll);
2344
2345         return ret;
2346 }
2347 EXPORT_SYMBOL_GPL(arizona_set_fll);
2348
2349 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
2350                      int ok_irq, struct arizona_fll *fll)
2351 {
2352         unsigned int val;
2353
2354         fll->id = id;
2355         fll->base = base;
2356         fll->arizona = arizona;
2357         fll->sync_src = ARIZONA_FLL_SRC_NONE;
2358
2359         /* Configure default refclk to 32kHz if we have one */
2360         regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
2361         switch (val & ARIZONA_CLK_32K_SRC_MASK) {
2362         case ARIZONA_CLK_SRC_MCLK1:
2363         case ARIZONA_CLK_SRC_MCLK2:
2364                 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
2365                 break;
2366         default:
2367                 fll->ref_src = ARIZONA_FLL_SRC_NONE;
2368         }
2369         fll->ref_freq = 32768;
2370
2371         snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
2372         snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
2373                  "FLL%d clock OK", id);
2374
2375         regmap_update_bits(arizona->regmap, fll->base + 1,
2376                            ARIZONA_FLL1_FREERUN, 0);
2377
2378         return 0;
2379 }
2380 EXPORT_SYMBOL_GPL(arizona_init_fll);
2381
2382 /**
2383  * arizona_set_output_mode - Set the mode of the specified output
2384  *
2385  * @codec: Device to configure
2386  * @output: Output number
2387  * @diff: True to set the output to differential mode
2388  *
2389  * Some systems use external analogue switches to connect more
2390  * analogue devices to the CODEC than are supported by the device.  In
2391  * some systems this requires changing the switched output from single
2392  * ended to differential mode dynamically at runtime, an operation
2393  * supported using this function.
2394  *
2395  * Most systems have a single static configuration and should use
2396  * platform data instead.
2397  */
2398 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
2399 {
2400         unsigned int reg, val;
2401
2402         if (output < 1 || output > 6)
2403                 return -EINVAL;
2404
2405         reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
2406
2407         if (diff)
2408                 val = ARIZONA_OUT1_MONO;
2409         else
2410                 val = 0;
2411
2412         return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
2413 }
2414 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
2415
2416 static const struct soc_enum arizona_adsp2_rate_enum[] = {
2417         SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
2418                               ARIZONA_DSP1_RATE_SHIFT, 0xf,
2419                               ARIZONA_RATE_ENUM_SIZE,
2420                               arizona_rate_text, arizona_rate_val),
2421         SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
2422                               ARIZONA_DSP1_RATE_SHIFT, 0xf,
2423                               ARIZONA_RATE_ENUM_SIZE,
2424                               arizona_rate_text, arizona_rate_val),
2425         SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
2426                               ARIZONA_DSP1_RATE_SHIFT, 0xf,
2427                               ARIZONA_RATE_ENUM_SIZE,
2428                               arizona_rate_text, arizona_rate_val),
2429         SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
2430                               ARIZONA_DSP1_RATE_SHIFT, 0xf,
2431                               ARIZONA_RATE_ENUM_SIZE,
2432                               arizona_rate_text, arizona_rate_val),
2433 };
2434
2435 const struct snd_kcontrol_new arizona_adsp2_rate_controls[] = {
2436         SOC_ENUM("DSP1 Rate", arizona_adsp2_rate_enum[0]),
2437         SOC_ENUM("DSP2 Rate", arizona_adsp2_rate_enum[1]),
2438         SOC_ENUM("DSP3 Rate", arizona_adsp2_rate_enum[2]),
2439         SOC_ENUM("DSP4 Rate", arizona_adsp2_rate_enum[3]),
2440 };
2441 EXPORT_SYMBOL_GPL(arizona_adsp2_rate_controls);
2442
2443 static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
2444 {
2445         s16 a = be16_to_cpu(_a);
2446         s16 b = be16_to_cpu(_b);
2447
2448         if (!mode) {
2449                 return abs(a) >= 4096;
2450         } else {
2451                 if (abs(b) >= 4096)
2452                         return true;
2453
2454                 return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
2455         }
2456 }
2457
2458 int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
2459                          struct snd_ctl_elem_value *ucontrol)
2460 {
2461         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2462         struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
2463         struct soc_bytes *params = (void *)kcontrol->private_value;
2464         unsigned int val;
2465         __be16 *data;
2466         int len;
2467         int ret;
2468
2469         len = params->num_regs * regmap_get_val_bytes(arizona->regmap);
2470
2471         data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
2472         if (!data)
2473                 return -ENOMEM;
2474
2475         data[0] &= cpu_to_be16(ARIZONA_EQ1_B1_MODE);
2476
2477         if (arizona_eq_filter_unstable(!!data[0], data[1], data[2]) ||
2478             arizona_eq_filter_unstable(true, data[4], data[5]) ||
2479             arizona_eq_filter_unstable(true, data[8], data[9]) ||
2480             arizona_eq_filter_unstable(true, data[12], data[13]) ||
2481             arizona_eq_filter_unstable(false, data[16], data[17])) {
2482                 dev_err(arizona->dev, "Rejecting unstable EQ coefficients\n");
2483                 ret = -EINVAL;
2484                 goto out;
2485         }
2486
2487         ret = regmap_read(arizona->regmap, params->base, &val);
2488         if (ret != 0)
2489                 goto out;
2490
2491         val &= ~ARIZONA_EQ1_B1_MODE;
2492         data[0] |= cpu_to_be16(val);
2493
2494         ret = regmap_raw_write(arizona->regmap, params->base, data, len);
2495
2496 out:
2497         kfree(data);
2498         return ret;
2499 }
2500 EXPORT_SYMBOL_GPL(arizona_eq_coeff_put);
2501
2502 int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
2503                            struct snd_ctl_elem_value *ucontrol)
2504 {
2505         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2506         struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
2507         __be16 *data = (__be16 *)ucontrol->value.bytes.data;
2508         s16 val = be16_to_cpu(*data);
2509
2510         if (abs(val) >= 4096) {
2511                 dev_err(arizona->dev, "Rejecting unstable LHPF coefficients\n");
2512                 return -EINVAL;
2513         }
2514
2515         return snd_soc_bytes_put(kcontrol, ucontrol);
2516 }
2517 EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
2518
2519 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2520 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2521 MODULE_LICENSE("GPL");