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