media: v4l: rcar_fdp1: Change platform dependency to ARCH_RENESAS
[linux/fpc-iii.git] / sound / soc / codecs / arizona.c
blob5727ea079ad7addd5e07408ebc3fc0b0e3a0f3ec
1 /*
2 * arizona.c - Wolfson Arizona class device shared support
4 * Copyright 2012 Wolfson Microelectronics plc
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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.
13 #include <linux/delay.h>
14 #include <linux/gcd.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/pm_runtime.h>
18 #include <sound/pcm.h>
19 #include <sound/pcm_params.h>
20 #include <sound/tlv.h>
22 #include <linux/mfd/arizona/core.h>
23 #include <linux/mfd/arizona/registers.h>
25 #include "arizona.h"
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
56 #define ARIZONA_FLL_VCO_CORNER 141900000
57 #define ARIZONA_FLL_MAX_FREF 13500000
58 #define ARIZONA_FLL_MIN_FVCO 90000000
59 #define ARIZONA_FLL_MAX_FRATIO 16
60 #define ARIZONA_FLL_MAX_REFDIV 8
61 #define ARIZONA_FLL_MIN_OUTDIV 2
62 #define ARIZONA_FLL_MAX_OUTDIV 7
64 #define ARIZONA_FMT_DSP_MODE_A 0
65 #define ARIZONA_FMT_DSP_MODE_B 1
66 #define ARIZONA_FMT_I2S_MODE 2
67 #define ARIZONA_FMT_LEFT_JUSTIFIED_MODE 3
69 #define arizona_fll_err(_fll, fmt, ...) \
70 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
71 #define arizona_fll_warn(_fll, fmt, ...) \
72 dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
73 #define arizona_fll_dbg(_fll, fmt, ...) \
74 dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
76 #define arizona_aif_err(_dai, fmt, ...) \
77 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
78 #define arizona_aif_warn(_dai, fmt, ...) \
79 dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
80 #define arizona_aif_dbg(_dai, fmt, ...) \
81 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
83 static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
84 struct snd_kcontrol *kcontrol,
85 int event)
87 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
88 struct arizona *arizona = dev_get_drvdata(component->dev->parent);
89 int val;
91 switch (event) {
92 case SND_SOC_DAPM_POST_PMU:
93 val = snd_soc_component_read32(component,
94 ARIZONA_INTERRUPT_RAW_STATUS_3);
95 if (val & ARIZONA_SPK_OVERHEAT_STS) {
96 dev_crit(arizona->dev,
97 "Speaker not enabled due to temperature\n");
98 return -EBUSY;
101 regmap_update_bits_async(arizona->regmap,
102 ARIZONA_OUTPUT_ENABLES_1,
103 1 << w->shift, 1 << w->shift);
104 break;
105 case SND_SOC_DAPM_PRE_PMD:
106 regmap_update_bits_async(arizona->regmap,
107 ARIZONA_OUTPUT_ENABLES_1,
108 1 << w->shift, 0);
109 break;
110 default:
111 break;
114 return arizona_out_ev(w, kcontrol, event);
117 static irqreturn_t arizona_thermal_warn(int irq, void *data)
119 struct arizona *arizona = data;
120 unsigned int val;
121 int ret;
123 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
124 &val);
125 if (ret != 0) {
126 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
127 ret);
128 } else if (val & ARIZONA_SPK_OVERHEAT_WARN_STS) {
129 dev_crit(arizona->dev, "Thermal warning\n");
132 return IRQ_HANDLED;
135 static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
137 struct arizona *arizona = data;
138 unsigned int val;
139 int ret;
141 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
142 &val);
143 if (ret != 0) {
144 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
145 ret);
146 } else if (val & ARIZONA_SPK_OVERHEAT_STS) {
147 dev_crit(arizona->dev, "Thermal shutdown\n");
148 ret = regmap_update_bits(arizona->regmap,
149 ARIZONA_OUTPUT_ENABLES_1,
150 ARIZONA_OUT4L_ENA |
151 ARIZONA_OUT4R_ENA, 0);
152 if (ret != 0)
153 dev_crit(arizona->dev,
154 "Failed to disable speaker outputs: %d\n",
155 ret);
158 return IRQ_HANDLED;
161 static const struct snd_soc_dapm_widget arizona_spkl =
162 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
163 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
164 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
165 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
167 static const struct snd_soc_dapm_widget arizona_spkr =
168 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
169 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
170 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
171 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
173 int arizona_init_spk(struct snd_soc_component *component)
175 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
176 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
177 struct arizona *arizona = priv->arizona;
178 int ret;
180 ret = snd_soc_dapm_new_controls(dapm, &arizona_spkl, 1);
181 if (ret != 0)
182 return ret;
184 switch (arizona->type) {
185 case WM8997:
186 case CS47L24:
187 case WM1831:
188 break;
189 default:
190 ret = snd_soc_dapm_new_controls(dapm, &arizona_spkr, 1);
191 if (ret != 0)
192 return ret;
193 break;
196 return 0;
198 EXPORT_SYMBOL_GPL(arizona_init_spk);
200 int arizona_init_spk_irqs(struct arizona *arizona)
202 int ret;
204 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN,
205 "Thermal warning", arizona_thermal_warn,
206 arizona);
207 if (ret != 0)
208 dev_err(arizona->dev,
209 "Failed to get thermal warning IRQ: %d\n",
210 ret);
212 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT,
213 "Thermal shutdown", arizona_thermal_shutdown,
214 arizona);
215 if (ret != 0)
216 dev_err(arizona->dev,
217 "Failed to get thermal shutdown IRQ: %d\n",
218 ret);
220 return 0;
222 EXPORT_SYMBOL_GPL(arizona_init_spk_irqs);
224 int arizona_free_spk_irqs(struct arizona *arizona)
226 arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN, arizona);
227 arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT, arizona);
229 return 0;
231 EXPORT_SYMBOL_GPL(arizona_free_spk_irqs);
233 static const struct snd_soc_dapm_route arizona_mono_routes[] = {
234 { "OUT1R", NULL, "OUT1L" },
235 { "OUT2R", NULL, "OUT2L" },
236 { "OUT3R", NULL, "OUT3L" },
237 { "OUT4R", NULL, "OUT4L" },
238 { "OUT5R", NULL, "OUT5L" },
239 { "OUT6R", NULL, "OUT6L" },
242 int arizona_init_mono(struct snd_soc_component *component)
244 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
245 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
246 struct arizona *arizona = priv->arizona;
247 int i;
249 for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
250 if (arizona->pdata.out_mono[i])
251 snd_soc_dapm_add_routes(dapm,
252 &arizona_mono_routes[i], 1);
255 return 0;
257 EXPORT_SYMBOL_GPL(arizona_init_mono);
259 int arizona_init_gpio(struct snd_soc_component *component)
261 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
262 struct arizona *arizona = priv->arizona;
263 int i;
265 switch (arizona->type) {
266 case WM5110:
267 case WM8280:
268 snd_soc_component_disable_pin(component,
269 "DRC2 Signal Activity");
270 break;
271 default:
272 break;
275 snd_soc_component_disable_pin(component, "DRC1 Signal Activity");
277 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
278 switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
279 case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
280 snd_soc_component_enable_pin(component,
281 "DRC1 Signal Activity");
282 break;
283 case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
284 snd_soc_component_enable_pin(component,
285 "DRC2 Signal Activity");
286 break;
287 default:
288 break;
292 return 0;
294 EXPORT_SYMBOL_GPL(arizona_init_gpio);
296 int arizona_init_common(struct arizona *arizona)
298 struct arizona_pdata *pdata = &arizona->pdata;
299 unsigned int val, mask;
300 int i;
302 BLOCKING_INIT_NOTIFIER_HEAD(&arizona->notifier);
304 for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
305 /* Default is 0 so noop with defaults */
306 if (pdata->out_mono[i])
307 val = ARIZONA_OUT1_MONO;
308 else
309 val = 0;
311 regmap_update_bits(arizona->regmap,
312 ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
313 ARIZONA_OUT1_MONO, val);
316 for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
317 if (pdata->spk_mute[i])
318 regmap_update_bits(arizona->regmap,
319 ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
320 ARIZONA_SPK1_MUTE_ENDIAN_MASK |
321 ARIZONA_SPK1_MUTE_SEQ1_MASK,
322 pdata->spk_mute[i]);
324 if (pdata->spk_fmt[i])
325 regmap_update_bits(arizona->regmap,
326 ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
327 ARIZONA_SPK1_FMT_MASK,
328 pdata->spk_fmt[i]);
331 for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
332 /* Default for both is 0 so noop with defaults */
333 val = pdata->dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT;
334 if (pdata->inmode[i] & ARIZONA_INMODE_DMIC)
335 val |= 1 << ARIZONA_IN1_MODE_SHIFT;
337 switch (arizona->type) {
338 case WM8998:
339 case WM1814:
340 regmap_update_bits(arizona->regmap,
341 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
342 ARIZONA_IN1L_SRC_SE_MASK,
343 (pdata->inmode[i] & ARIZONA_INMODE_SE)
344 << ARIZONA_IN1L_SRC_SE_SHIFT);
346 regmap_update_bits(arizona->regmap,
347 ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
348 ARIZONA_IN1R_SRC_SE_MASK,
349 (pdata->inmode[i] & ARIZONA_INMODE_SE)
350 << ARIZONA_IN1R_SRC_SE_SHIFT);
352 mask = ARIZONA_IN1_DMIC_SUP_MASK |
353 ARIZONA_IN1_MODE_MASK;
354 break;
355 default:
356 if (pdata->inmode[i] & ARIZONA_INMODE_SE)
357 val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;
359 mask = ARIZONA_IN1_DMIC_SUP_MASK |
360 ARIZONA_IN1_MODE_MASK |
361 ARIZONA_IN1_SINGLE_ENDED_MASK;
362 break;
365 regmap_update_bits(arizona->regmap,
366 ARIZONA_IN1L_CONTROL + (i * 8),
367 mask, val);
370 return 0;
372 EXPORT_SYMBOL_GPL(arizona_init_common);
374 int arizona_init_vol_limit(struct arizona *arizona)
376 int i;
378 for (i = 0; i < ARRAY_SIZE(arizona->pdata.out_vol_limit); ++i) {
379 if (arizona->pdata.out_vol_limit[i])
380 regmap_update_bits(arizona->regmap,
381 ARIZONA_DAC_VOLUME_LIMIT_1L + i * 4,
382 ARIZONA_OUT1L_VOL_LIM_MASK,
383 arizona->pdata.out_vol_limit[i]);
386 return 0;
388 EXPORT_SYMBOL_GPL(arizona_init_vol_limit);
390 const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
391 "None",
392 "Tone Generator 1",
393 "Tone Generator 2",
394 "Haptics",
395 "AEC",
396 "AEC2",
397 "Mic Mute Mixer",
398 "Noise Generator",
399 "IN1L",
400 "IN1R",
401 "IN2L",
402 "IN2R",
403 "IN3L",
404 "IN3R",
405 "IN4L",
406 "IN4R",
407 "AIF1RX1",
408 "AIF1RX2",
409 "AIF1RX3",
410 "AIF1RX4",
411 "AIF1RX5",
412 "AIF1RX6",
413 "AIF1RX7",
414 "AIF1RX8",
415 "AIF2RX1",
416 "AIF2RX2",
417 "AIF2RX3",
418 "AIF2RX4",
419 "AIF2RX5",
420 "AIF2RX6",
421 "AIF3RX1",
422 "AIF3RX2",
423 "SLIMRX1",
424 "SLIMRX2",
425 "SLIMRX3",
426 "SLIMRX4",
427 "SLIMRX5",
428 "SLIMRX6",
429 "SLIMRX7",
430 "SLIMRX8",
431 "EQ1",
432 "EQ2",
433 "EQ3",
434 "EQ4",
435 "DRC1L",
436 "DRC1R",
437 "DRC2L",
438 "DRC2R",
439 "LHPF1",
440 "LHPF2",
441 "LHPF3",
442 "LHPF4",
443 "DSP1.1",
444 "DSP1.2",
445 "DSP1.3",
446 "DSP1.4",
447 "DSP1.5",
448 "DSP1.6",
449 "DSP2.1",
450 "DSP2.2",
451 "DSP2.3",
452 "DSP2.4",
453 "DSP2.5",
454 "DSP2.6",
455 "DSP3.1",
456 "DSP3.2",
457 "DSP3.3",
458 "DSP3.4",
459 "DSP3.5",
460 "DSP3.6",
461 "DSP4.1",
462 "DSP4.2",
463 "DSP4.3",
464 "DSP4.4",
465 "DSP4.5",
466 "DSP4.6",
467 "ASRC1L",
468 "ASRC1R",
469 "ASRC2L",
470 "ASRC2R",
471 "ISRC1INT1",
472 "ISRC1INT2",
473 "ISRC1INT3",
474 "ISRC1INT4",
475 "ISRC1DEC1",
476 "ISRC1DEC2",
477 "ISRC1DEC3",
478 "ISRC1DEC4",
479 "ISRC2INT1",
480 "ISRC2INT2",
481 "ISRC2INT3",
482 "ISRC2INT4",
483 "ISRC2DEC1",
484 "ISRC2DEC2",
485 "ISRC2DEC3",
486 "ISRC2DEC4",
487 "ISRC3INT1",
488 "ISRC3INT2",
489 "ISRC3INT3",
490 "ISRC3INT4",
491 "ISRC3DEC1",
492 "ISRC3DEC2",
493 "ISRC3DEC3",
494 "ISRC3DEC4",
496 EXPORT_SYMBOL_GPL(arizona_mixer_texts);
498 unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
499 0x00, /* None */
500 0x04, /* Tone */
501 0x05,
502 0x06, /* Haptics */
503 0x08, /* AEC */
504 0x09, /* AEC2 */
505 0x0c, /* Noise mixer */
506 0x0d, /* Comfort noise */
507 0x10, /* IN1L */
508 0x11,
509 0x12,
510 0x13,
511 0x14,
512 0x15,
513 0x16,
514 0x17,
515 0x20, /* AIF1RX1 */
516 0x21,
517 0x22,
518 0x23,
519 0x24,
520 0x25,
521 0x26,
522 0x27,
523 0x28, /* AIF2RX1 */
524 0x29,
525 0x2a,
526 0x2b,
527 0x2c,
528 0x2d,
529 0x30, /* AIF3RX1 */
530 0x31,
531 0x38, /* SLIMRX1 */
532 0x39,
533 0x3a,
534 0x3b,
535 0x3c,
536 0x3d,
537 0x3e,
538 0x3f,
539 0x50, /* EQ1 */
540 0x51,
541 0x52,
542 0x53,
543 0x58, /* DRC1L */
544 0x59,
545 0x5a,
546 0x5b,
547 0x60, /* LHPF1 */
548 0x61,
549 0x62,
550 0x63,
551 0x68, /* DSP1.1 */
552 0x69,
553 0x6a,
554 0x6b,
555 0x6c,
556 0x6d,
557 0x70, /* DSP2.1 */
558 0x71,
559 0x72,
560 0x73,
561 0x74,
562 0x75,
563 0x78, /* DSP3.1 */
564 0x79,
565 0x7a,
566 0x7b,
567 0x7c,
568 0x7d,
569 0x80, /* DSP4.1 */
570 0x81,
571 0x82,
572 0x83,
573 0x84,
574 0x85,
575 0x90, /* ASRC1L */
576 0x91,
577 0x92,
578 0x93,
579 0xa0, /* ISRC1INT1 */
580 0xa1,
581 0xa2,
582 0xa3,
583 0xa4, /* ISRC1DEC1 */
584 0xa5,
585 0xa6,
586 0xa7,
587 0xa8, /* ISRC2DEC1 */
588 0xa9,
589 0xaa,
590 0xab,
591 0xac, /* ISRC2INT1 */
592 0xad,
593 0xae,
594 0xaf,
595 0xb0, /* ISRC3DEC1 */
596 0xb1,
597 0xb2,
598 0xb3,
599 0xb4, /* ISRC3INT1 */
600 0xb5,
601 0xb6,
602 0xb7,
604 EXPORT_SYMBOL_GPL(arizona_mixer_values);
606 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
607 EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
609 const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
610 "12kHz", "24kHz", "48kHz", "96kHz", "192kHz",
611 "11.025kHz", "22.05kHz", "44.1kHz", "88.2kHz", "176.4kHz",
612 "4kHz", "8kHz", "16kHz", "32kHz",
614 EXPORT_SYMBOL_GPL(arizona_sample_rate_text);
616 const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
617 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
618 0x10, 0x11, 0x12, 0x13,
620 EXPORT_SYMBOL_GPL(arizona_sample_rate_val);
622 const char *arizona_sample_rate_val_to_name(unsigned int rate_val)
624 int i;
626 for (i = 0; i < ARRAY_SIZE(arizona_sample_rate_val); ++i) {
627 if (arizona_sample_rate_val[i] == rate_val)
628 return arizona_sample_rate_text[i];
631 return "Illegal";
633 EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name);
635 const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
636 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
638 EXPORT_SYMBOL_GPL(arizona_rate_text);
640 const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
641 0, 1, 2, 8,
643 EXPORT_SYMBOL_GPL(arizona_rate_val);
645 const struct soc_enum arizona_isrc_fsh[] = {
646 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1,
647 ARIZONA_ISRC1_FSH_SHIFT, 0xf,
648 ARIZONA_RATE_ENUM_SIZE,
649 arizona_rate_text, arizona_rate_val),
650 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_1,
651 ARIZONA_ISRC2_FSH_SHIFT, 0xf,
652 ARIZONA_RATE_ENUM_SIZE,
653 arizona_rate_text, arizona_rate_val),
654 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_1,
655 ARIZONA_ISRC3_FSH_SHIFT, 0xf,
656 ARIZONA_RATE_ENUM_SIZE,
657 arizona_rate_text, arizona_rate_val),
659 EXPORT_SYMBOL_GPL(arizona_isrc_fsh);
661 const struct soc_enum arizona_isrc_fsl[] = {
662 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
663 ARIZONA_ISRC1_FSL_SHIFT, 0xf,
664 ARIZONA_RATE_ENUM_SIZE,
665 arizona_rate_text, arizona_rate_val),
666 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
667 ARIZONA_ISRC2_FSL_SHIFT, 0xf,
668 ARIZONA_RATE_ENUM_SIZE,
669 arizona_rate_text, arizona_rate_val),
670 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
671 ARIZONA_ISRC3_FSL_SHIFT, 0xf,
672 ARIZONA_RATE_ENUM_SIZE,
673 arizona_rate_text, arizona_rate_val),
675 EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
677 const struct soc_enum arizona_asrc_rate1 =
678 SOC_VALUE_ENUM_SINGLE(ARIZONA_ASRC_RATE1,
679 ARIZONA_ASRC_RATE1_SHIFT, 0xf,
680 ARIZONA_RATE_ENUM_SIZE - 1,
681 arizona_rate_text, arizona_rate_val);
682 EXPORT_SYMBOL_GPL(arizona_asrc_rate1);
684 static const char * const arizona_vol_ramp_text[] = {
685 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
686 "15ms/6dB", "30ms/6dB",
689 SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp,
690 ARIZONA_INPUT_VOLUME_RAMP,
691 ARIZONA_IN_VD_RAMP_SHIFT,
692 arizona_vol_ramp_text);
693 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
695 SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp,
696 ARIZONA_INPUT_VOLUME_RAMP,
697 ARIZONA_IN_VI_RAMP_SHIFT,
698 arizona_vol_ramp_text);
699 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
701 SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp,
702 ARIZONA_OUTPUT_VOLUME_RAMP,
703 ARIZONA_OUT_VD_RAMP_SHIFT,
704 arizona_vol_ramp_text);
705 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
707 SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp,
708 ARIZONA_OUTPUT_VOLUME_RAMP,
709 ARIZONA_OUT_VI_RAMP_SHIFT,
710 arizona_vol_ramp_text);
711 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
713 static const char * const arizona_lhpf_mode_text[] = {
714 "Low-pass", "High-pass"
717 SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode,
718 ARIZONA_HPLPF1_1,
719 ARIZONA_LHPF1_MODE_SHIFT,
720 arizona_lhpf_mode_text);
721 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
723 SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode,
724 ARIZONA_HPLPF2_1,
725 ARIZONA_LHPF2_MODE_SHIFT,
726 arizona_lhpf_mode_text);
727 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
729 SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode,
730 ARIZONA_HPLPF3_1,
731 ARIZONA_LHPF3_MODE_SHIFT,
732 arizona_lhpf_mode_text);
733 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
735 SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode,
736 ARIZONA_HPLPF4_1,
737 ARIZONA_LHPF4_MODE_SHIFT,
738 arizona_lhpf_mode_text);
739 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
741 static const char * const arizona_ng_hold_text[] = {
742 "30ms", "120ms", "250ms", "500ms",
745 SOC_ENUM_SINGLE_DECL(arizona_ng_hold,
746 ARIZONA_NOISE_GATE_CONTROL,
747 ARIZONA_NGATE_HOLD_SHIFT,
748 arizona_ng_hold_text);
749 EXPORT_SYMBOL_GPL(arizona_ng_hold);
751 static const char * const arizona_in_hpf_cut_text[] = {
752 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
755 SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum,
756 ARIZONA_HPF_CONTROL,
757 ARIZONA_IN_HPF_CUT_SHIFT,
758 arizona_in_hpf_cut_text);
759 EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
761 static const char * const arizona_in_dmic_osr_text[] = {
762 "1.536MHz", "3.072MHz", "6.144MHz", "768kHz",
765 const struct soc_enum arizona_in_dmic_osr[] = {
766 SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
767 ARRAY_SIZE(arizona_in_dmic_osr_text),
768 arizona_in_dmic_osr_text),
769 SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
770 ARRAY_SIZE(arizona_in_dmic_osr_text),
771 arizona_in_dmic_osr_text),
772 SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
773 ARRAY_SIZE(arizona_in_dmic_osr_text),
774 arizona_in_dmic_osr_text),
775 SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
776 ARRAY_SIZE(arizona_in_dmic_osr_text),
777 arizona_in_dmic_osr_text),
779 EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
781 static const char * const arizona_anc_input_src_text[] = {
782 "None", "IN1", "IN2", "IN3", "IN4",
785 static const char * const arizona_anc_channel_src_text[] = {
786 "None", "Left", "Right", "Combine",
789 const struct soc_enum arizona_anc_input_src[] = {
790 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
791 ARIZONA_IN_RXANCL_SEL_SHIFT,
792 ARRAY_SIZE(arizona_anc_input_src_text),
793 arizona_anc_input_src_text),
794 SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL,
795 ARIZONA_FCL_MIC_MODE_SEL_SHIFT,
796 ARRAY_SIZE(arizona_anc_channel_src_text),
797 arizona_anc_channel_src_text),
798 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
799 ARIZONA_IN_RXANCR_SEL_SHIFT,
800 ARRAY_SIZE(arizona_anc_input_src_text),
801 arizona_anc_input_src_text),
802 SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL,
803 ARIZONA_FCR_MIC_MODE_SEL_SHIFT,
804 ARRAY_SIZE(arizona_anc_channel_src_text),
805 arizona_anc_channel_src_text),
807 EXPORT_SYMBOL_GPL(arizona_anc_input_src);
809 static const char * const arizona_anc_ng_texts[] = {
810 "None",
811 "Internal",
812 "External",
815 SOC_ENUM_SINGLE_DECL(arizona_anc_ng_enum, SND_SOC_NOPM, 0,
816 arizona_anc_ng_texts);
817 EXPORT_SYMBOL_GPL(arizona_anc_ng_enum);
819 static const char * const arizona_output_anc_src_text[] = {
820 "None", "RXANCL", "RXANCR",
823 const struct soc_enum arizona_output_anc_src[] = {
824 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
825 ARIZONA_OUT1L_ANC_SRC_SHIFT,
826 ARRAY_SIZE(arizona_output_anc_src_text),
827 arizona_output_anc_src_text),
828 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1R,
829 ARIZONA_OUT1R_ANC_SRC_SHIFT,
830 ARRAY_SIZE(arizona_output_anc_src_text),
831 arizona_output_anc_src_text),
832 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
833 ARIZONA_OUT2L_ANC_SRC_SHIFT,
834 ARRAY_SIZE(arizona_output_anc_src_text),
835 arizona_output_anc_src_text),
836 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2R,
837 ARIZONA_OUT2R_ANC_SRC_SHIFT,
838 ARRAY_SIZE(arizona_output_anc_src_text),
839 arizona_output_anc_src_text),
840 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
841 ARIZONA_OUT3L_ANC_SRC_SHIFT,
842 ARRAY_SIZE(arizona_output_anc_src_text),
843 arizona_output_anc_src_text),
844 SOC_ENUM_SINGLE(ARIZONA_DAC_VOLUME_LIMIT_3R,
845 ARIZONA_OUT3R_ANC_SRC_SHIFT,
846 ARRAY_SIZE(arizona_output_anc_src_text),
847 arizona_output_anc_src_text),
848 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4L,
849 ARIZONA_OUT4L_ANC_SRC_SHIFT,
850 ARRAY_SIZE(arizona_output_anc_src_text),
851 arizona_output_anc_src_text),
852 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4R,
853 ARIZONA_OUT4R_ANC_SRC_SHIFT,
854 ARRAY_SIZE(arizona_output_anc_src_text),
855 arizona_output_anc_src_text),
856 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5L,
857 ARIZONA_OUT5L_ANC_SRC_SHIFT,
858 ARRAY_SIZE(arizona_output_anc_src_text),
859 arizona_output_anc_src_text),
860 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5R,
861 ARIZONA_OUT5R_ANC_SRC_SHIFT,
862 ARRAY_SIZE(arizona_output_anc_src_text),
863 arizona_output_anc_src_text),
864 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6L,
865 ARIZONA_OUT6L_ANC_SRC_SHIFT,
866 ARRAY_SIZE(arizona_output_anc_src_text),
867 arizona_output_anc_src_text),
868 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6R,
869 ARIZONA_OUT6R_ANC_SRC_SHIFT,
870 ARRAY_SIZE(arizona_output_anc_src_text),
871 arizona_output_anc_src_text),
873 EXPORT_SYMBOL_GPL(arizona_output_anc_src);
875 const struct snd_kcontrol_new arizona_voice_trigger_switch[] = {
876 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
877 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 1, 1, 0),
878 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 2, 1, 0),
879 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 3, 1, 0),
881 EXPORT_SYMBOL_GPL(arizona_voice_trigger_switch);
883 static void arizona_in_set_vu(struct snd_soc_component *component, int ena)
885 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
886 unsigned int val;
887 int i;
889 if (ena)
890 val = ARIZONA_IN_VU;
891 else
892 val = 0;
894 for (i = 0; i < priv->num_inputs; i++)
895 snd_soc_component_update_bits(component,
896 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
897 ARIZONA_IN_VU, val);
900 bool arizona_input_analog(struct snd_soc_component *component, int shift)
902 unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8);
903 unsigned int val = snd_soc_component_read32(component, reg);
905 return !(val & ARIZONA_IN1_MODE_MASK);
907 EXPORT_SYMBOL_GPL(arizona_input_analog);
909 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
910 int event)
912 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
913 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
914 unsigned int reg;
916 if (w->shift % 2)
917 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
918 else
919 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
921 switch (event) {
922 case SND_SOC_DAPM_PRE_PMU:
923 priv->in_pending++;
924 break;
925 case SND_SOC_DAPM_POST_PMU:
926 snd_soc_component_update_bits(component, reg,
927 ARIZONA_IN1L_MUTE, 0);
929 /* If this is the last input pending then allow VU */
930 priv->in_pending--;
931 if (priv->in_pending == 0) {
932 msleep(1);
933 arizona_in_set_vu(component, 1);
935 break;
936 case SND_SOC_DAPM_PRE_PMD:
937 snd_soc_component_update_bits(component, reg,
938 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
939 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
940 break;
941 case SND_SOC_DAPM_POST_PMD:
942 /* Disable volume updates if no inputs are enabled */
943 reg = snd_soc_component_read32(component, ARIZONA_INPUT_ENABLES);
944 if (reg == 0)
945 arizona_in_set_vu(component, 0);
946 break;
947 default:
948 break;
951 return 0;
953 EXPORT_SYMBOL_GPL(arizona_in_ev);
955 int arizona_out_ev(struct snd_soc_dapm_widget *w,
956 struct snd_kcontrol *kcontrol,
957 int event)
959 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
960 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
961 struct arizona *arizona = priv->arizona;
963 switch (event) {
964 case SND_SOC_DAPM_PRE_PMU:
965 switch (w->shift) {
966 case ARIZONA_OUT1L_ENA_SHIFT:
967 case ARIZONA_OUT1R_ENA_SHIFT:
968 case ARIZONA_OUT2L_ENA_SHIFT:
969 case ARIZONA_OUT2R_ENA_SHIFT:
970 case ARIZONA_OUT3L_ENA_SHIFT:
971 case ARIZONA_OUT3R_ENA_SHIFT:
972 priv->out_up_pending++;
973 priv->out_up_delay += 17;
974 break;
975 case ARIZONA_OUT4L_ENA_SHIFT:
976 case ARIZONA_OUT4R_ENA_SHIFT:
977 priv->out_up_pending++;
978 switch (arizona->type) {
979 case WM5102:
980 case WM8997:
981 break;
982 default:
983 priv->out_up_delay += 10;
984 break;
986 break;
987 default:
988 break;
990 break;
991 case SND_SOC_DAPM_POST_PMU:
992 switch (w->shift) {
993 case ARIZONA_OUT1L_ENA_SHIFT:
994 case ARIZONA_OUT1R_ENA_SHIFT:
995 case ARIZONA_OUT2L_ENA_SHIFT:
996 case ARIZONA_OUT2R_ENA_SHIFT:
997 case ARIZONA_OUT3L_ENA_SHIFT:
998 case ARIZONA_OUT3R_ENA_SHIFT:
999 case ARIZONA_OUT4L_ENA_SHIFT:
1000 case ARIZONA_OUT4R_ENA_SHIFT:
1001 priv->out_up_pending--;
1002 if (!priv->out_up_pending && priv->out_up_delay) {
1003 dev_dbg(component->dev, "Power up delay: %d\n",
1004 priv->out_up_delay);
1005 msleep(priv->out_up_delay);
1006 priv->out_up_delay = 0;
1008 break;
1010 default:
1011 break;
1013 break;
1014 case SND_SOC_DAPM_PRE_PMD:
1015 switch (w->shift) {
1016 case ARIZONA_OUT1L_ENA_SHIFT:
1017 case ARIZONA_OUT1R_ENA_SHIFT:
1018 case ARIZONA_OUT2L_ENA_SHIFT:
1019 case ARIZONA_OUT2R_ENA_SHIFT:
1020 case ARIZONA_OUT3L_ENA_SHIFT:
1021 case ARIZONA_OUT3R_ENA_SHIFT:
1022 priv->out_down_pending++;
1023 priv->out_down_delay++;
1024 break;
1025 case ARIZONA_OUT4L_ENA_SHIFT:
1026 case ARIZONA_OUT4R_ENA_SHIFT:
1027 priv->out_down_pending++;
1028 switch (arizona->type) {
1029 case WM5102:
1030 case WM8997:
1031 break;
1032 case WM8998:
1033 case WM1814:
1034 priv->out_down_delay += 5;
1035 break;
1036 default:
1037 priv->out_down_delay++;
1038 break;
1040 default:
1041 break;
1043 break;
1044 case SND_SOC_DAPM_POST_PMD:
1045 switch (w->shift) {
1046 case ARIZONA_OUT1L_ENA_SHIFT:
1047 case ARIZONA_OUT1R_ENA_SHIFT:
1048 case ARIZONA_OUT2L_ENA_SHIFT:
1049 case ARIZONA_OUT2R_ENA_SHIFT:
1050 case ARIZONA_OUT3L_ENA_SHIFT:
1051 case ARIZONA_OUT3R_ENA_SHIFT:
1052 case ARIZONA_OUT4L_ENA_SHIFT:
1053 case ARIZONA_OUT4R_ENA_SHIFT:
1054 priv->out_down_pending--;
1055 if (!priv->out_down_pending && priv->out_down_delay) {
1056 dev_dbg(component->dev, "Power down delay: %d\n",
1057 priv->out_down_delay);
1058 msleep(priv->out_down_delay);
1059 priv->out_down_delay = 0;
1061 break;
1062 default:
1063 break;
1065 break;
1066 default:
1067 break;
1070 return 0;
1072 EXPORT_SYMBOL_GPL(arizona_out_ev);
1074 int arizona_hp_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
1075 int event)
1077 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1078 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1079 struct arizona *arizona = priv->arizona;
1080 unsigned int mask = 1 << w->shift;
1081 unsigned int val;
1083 switch (event) {
1084 case SND_SOC_DAPM_POST_PMU:
1085 val = mask;
1086 break;
1087 case SND_SOC_DAPM_PRE_PMD:
1088 val = 0;
1089 break;
1090 case SND_SOC_DAPM_PRE_PMU:
1091 case SND_SOC_DAPM_POST_PMD:
1092 return arizona_out_ev(w, kcontrol, event);
1093 default:
1094 return -EINVAL;
1097 /* Store the desired state for the HP outputs */
1098 priv->arizona->hp_ena &= ~mask;
1099 priv->arizona->hp_ena |= val;
1101 /* Force off if HPDET clamp is active */
1102 if (priv->arizona->hpdet_clamp)
1103 val = 0;
1105 regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
1106 mask, val);
1108 return arizona_out_ev(w, kcontrol, event);
1110 EXPORT_SYMBOL_GPL(arizona_hp_ev);
1112 static int arizona_dvfs_enable(struct snd_soc_component *component)
1114 const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1115 struct arizona *arizona = priv->arizona;
1116 int ret;
1118 ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
1119 if (ret) {
1120 dev_err(component->dev, "Failed to boost DCVDD: %d\n", ret);
1121 return ret;
1124 ret = regmap_update_bits(arizona->regmap,
1125 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1126 ARIZONA_SUBSYS_MAX_FREQ,
1127 ARIZONA_SUBSYS_MAX_FREQ);
1128 if (ret) {
1129 dev_err(component->dev, "Failed to enable subsys max: %d\n", ret);
1130 regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1131 return ret;
1134 return 0;
1137 static int arizona_dvfs_disable(struct snd_soc_component *component)
1139 const struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1140 struct arizona *arizona = priv->arizona;
1141 int ret;
1143 ret = regmap_update_bits(arizona->regmap,
1144 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1145 ARIZONA_SUBSYS_MAX_FREQ, 0);
1146 if (ret) {
1147 dev_err(component->dev, "Failed to disable subsys max: %d\n", ret);
1148 return ret;
1151 ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1152 if (ret) {
1153 dev_err(component->dev, "Failed to unboost DCVDD: %d\n", ret);
1154 return ret;
1157 return 0;
1160 int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags)
1162 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1163 int ret = 0;
1165 mutex_lock(&priv->dvfs_lock);
1167 if (!priv->dvfs_cached && !priv->dvfs_reqs) {
1168 ret = arizona_dvfs_enable(component);
1169 if (ret)
1170 goto err;
1173 priv->dvfs_reqs |= flags;
1174 err:
1175 mutex_unlock(&priv->dvfs_lock);
1176 return ret;
1178 EXPORT_SYMBOL_GPL(arizona_dvfs_up);
1180 int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags)
1182 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1183 unsigned int old_reqs;
1184 int ret = 0;
1186 mutex_lock(&priv->dvfs_lock);
1188 old_reqs = priv->dvfs_reqs;
1189 priv->dvfs_reqs &= ~flags;
1191 if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
1192 ret = arizona_dvfs_disable(component);
1194 mutex_unlock(&priv->dvfs_lock);
1195 return ret;
1197 EXPORT_SYMBOL_GPL(arizona_dvfs_down);
1199 int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
1200 struct snd_kcontrol *kcontrol, int event)
1202 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1203 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1204 int ret = 0;
1206 mutex_lock(&priv->dvfs_lock);
1208 switch (event) {
1209 case SND_SOC_DAPM_POST_PMU:
1210 if (priv->dvfs_reqs)
1211 ret = arizona_dvfs_enable(component);
1213 priv->dvfs_cached = false;
1214 break;
1215 case SND_SOC_DAPM_PRE_PMD:
1216 /* We must ensure DVFS is disabled before the codec goes into
1217 * suspend so that we are never in an illegal state of DVFS
1218 * enabled without enough DCVDD
1220 priv->dvfs_cached = true;
1222 if (priv->dvfs_reqs)
1223 ret = arizona_dvfs_disable(component);
1224 break;
1225 default:
1226 break;
1229 mutex_unlock(&priv->dvfs_lock);
1230 return ret;
1232 EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
1234 void arizona_init_dvfs(struct arizona_priv *priv)
1236 mutex_init(&priv->dvfs_lock);
1238 EXPORT_SYMBOL_GPL(arizona_init_dvfs);
1240 int arizona_anc_ev(struct snd_soc_dapm_widget *w,
1241 struct snd_kcontrol *kcontrol,
1242 int event)
1244 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1245 unsigned int val;
1247 switch (event) {
1248 case SND_SOC_DAPM_POST_PMU:
1249 val = 1 << w->shift;
1250 break;
1251 case SND_SOC_DAPM_PRE_PMD:
1252 val = 1 << (w->shift + 1);
1253 break;
1254 default:
1255 return 0;
1258 snd_soc_component_write(component, ARIZONA_CLOCK_CONTROL, val);
1260 return 0;
1262 EXPORT_SYMBOL_GPL(arizona_anc_ev);
1264 static unsigned int arizona_opclk_ref_48k_rates[] = {
1265 6144000,
1266 12288000,
1267 24576000,
1268 49152000,
1271 static unsigned int arizona_opclk_ref_44k1_rates[] = {
1272 5644800,
1273 11289600,
1274 22579200,
1275 45158400,
1278 static int arizona_set_opclk(struct snd_soc_component *component,
1279 unsigned int clk, unsigned int freq)
1281 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1282 unsigned int reg;
1283 unsigned int *rates;
1284 int ref, div, refclk;
1286 switch (clk) {
1287 case ARIZONA_CLK_OPCLK:
1288 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
1289 refclk = priv->sysclk;
1290 break;
1291 case ARIZONA_CLK_ASYNC_OPCLK:
1292 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
1293 refclk = priv->asyncclk;
1294 break;
1295 default:
1296 return -EINVAL;
1299 if (refclk % 8000)
1300 rates = arizona_opclk_ref_44k1_rates;
1301 else
1302 rates = arizona_opclk_ref_48k_rates;
1304 for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
1305 rates[ref] <= refclk; ref++) {
1306 div = 1;
1307 while (rates[ref] / div >= freq && div < 32) {
1308 if (rates[ref] / div == freq) {
1309 dev_dbg(component->dev, "Configured %dHz OPCLK\n",
1310 freq);
1311 snd_soc_component_update_bits(component, reg,
1312 ARIZONA_OPCLK_DIV_MASK |
1313 ARIZONA_OPCLK_SEL_MASK,
1314 (div <<
1315 ARIZONA_OPCLK_DIV_SHIFT) |
1316 ref);
1317 return 0;
1319 div++;
1323 dev_err(component->dev, "Unable to generate %dHz OPCLK\n", freq);
1324 return -EINVAL;
1327 int arizona_clk_ev(struct snd_soc_dapm_widget *w,
1328 struct snd_kcontrol *kcontrol, int event)
1330 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1331 struct arizona *arizona = dev_get_drvdata(component->dev->parent);
1332 unsigned int val;
1333 int clk_idx;
1334 int ret;
1336 ret = regmap_read(arizona->regmap, w->reg, &val);
1337 if (ret) {
1338 dev_err(component->dev, "Failed to check clock source: %d\n", ret);
1339 return ret;
1342 val = (val & ARIZONA_SYSCLK_SRC_MASK) >> ARIZONA_SYSCLK_SRC_SHIFT;
1344 switch (val) {
1345 case ARIZONA_CLK_SRC_MCLK1:
1346 clk_idx = ARIZONA_MCLK1;
1347 break;
1348 case ARIZONA_CLK_SRC_MCLK2:
1349 clk_idx = ARIZONA_MCLK2;
1350 break;
1351 default:
1352 return 0;
1355 switch (event) {
1356 case SND_SOC_DAPM_PRE_PMU:
1357 return clk_prepare_enable(arizona->mclk[clk_idx]);
1358 case SND_SOC_DAPM_POST_PMD:
1359 clk_disable_unprepare(arizona->mclk[clk_idx]);
1360 return 0;
1361 default:
1362 return 0;
1365 EXPORT_SYMBOL_GPL(arizona_clk_ev);
1367 int arizona_set_sysclk(struct snd_soc_component *component, int clk_id,
1368 int source, unsigned int freq, int dir)
1370 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1371 struct arizona *arizona = priv->arizona;
1372 char *name;
1373 unsigned int reg;
1374 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
1375 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
1376 int *clk;
1378 switch (clk_id) {
1379 case ARIZONA_CLK_SYSCLK:
1380 name = "SYSCLK";
1381 reg = ARIZONA_SYSTEM_CLOCK_1;
1382 clk = &priv->sysclk;
1383 mask |= ARIZONA_SYSCLK_FRAC;
1384 break;
1385 case ARIZONA_CLK_ASYNCCLK:
1386 name = "ASYNCCLK";
1387 reg = ARIZONA_ASYNC_CLOCK_1;
1388 clk = &priv->asyncclk;
1389 break;
1390 case ARIZONA_CLK_OPCLK:
1391 case ARIZONA_CLK_ASYNC_OPCLK:
1392 return arizona_set_opclk(component, clk_id, freq);
1393 default:
1394 return -EINVAL;
1397 switch (freq) {
1398 case 5644800:
1399 case 6144000:
1400 break;
1401 case 11289600:
1402 case 12288000:
1403 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1404 break;
1405 case 22579200:
1406 case 24576000:
1407 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1408 break;
1409 case 45158400:
1410 case 49152000:
1411 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1412 break;
1413 case 67737600:
1414 case 73728000:
1415 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1416 break;
1417 case 90316800:
1418 case 98304000:
1419 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1420 break;
1421 case 135475200:
1422 case 147456000:
1423 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1424 break;
1425 case 0:
1426 dev_dbg(arizona->dev, "%s cleared\n", name);
1427 *clk = freq;
1428 return 0;
1429 default:
1430 return -EINVAL;
1433 *clk = freq;
1435 if (freq % 6144000)
1436 val |= ARIZONA_SYSCLK_FRAC;
1438 dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
1440 return regmap_update_bits(arizona->regmap, reg, mask, val);
1442 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
1444 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1446 struct snd_soc_component *component = dai->component;
1447 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1448 struct arizona *arizona = priv->arizona;
1449 int lrclk, bclk, mode, base;
1451 base = dai->driver->base;
1453 lrclk = 0;
1454 bclk = 0;
1456 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1457 case SND_SOC_DAIFMT_DSP_A:
1458 mode = ARIZONA_FMT_DSP_MODE_A;
1459 break;
1460 case SND_SOC_DAIFMT_DSP_B:
1461 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1462 != SND_SOC_DAIFMT_CBM_CFM) {
1463 arizona_aif_err(dai, "DSP_B not valid in slave mode\n");
1464 return -EINVAL;
1466 mode = ARIZONA_FMT_DSP_MODE_B;
1467 break;
1468 case SND_SOC_DAIFMT_I2S:
1469 mode = ARIZONA_FMT_I2S_MODE;
1470 break;
1471 case SND_SOC_DAIFMT_LEFT_J:
1472 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1473 != SND_SOC_DAIFMT_CBM_CFM) {
1474 arizona_aif_err(dai, "LEFT_J not valid in slave mode\n");
1475 return -EINVAL;
1477 mode = ARIZONA_FMT_LEFT_JUSTIFIED_MODE;
1478 break;
1479 default:
1480 arizona_aif_err(dai, "Unsupported DAI format %d\n",
1481 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1482 return -EINVAL;
1485 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1486 case SND_SOC_DAIFMT_CBS_CFS:
1487 break;
1488 case SND_SOC_DAIFMT_CBS_CFM:
1489 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1490 break;
1491 case SND_SOC_DAIFMT_CBM_CFS:
1492 bclk |= ARIZONA_AIF1_BCLK_MSTR;
1493 break;
1494 case SND_SOC_DAIFMT_CBM_CFM:
1495 bclk |= ARIZONA_AIF1_BCLK_MSTR;
1496 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1497 break;
1498 default:
1499 arizona_aif_err(dai, "Unsupported master mode %d\n",
1500 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1501 return -EINVAL;
1504 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1505 case SND_SOC_DAIFMT_NB_NF:
1506 break;
1507 case SND_SOC_DAIFMT_IB_IF:
1508 bclk |= ARIZONA_AIF1_BCLK_INV;
1509 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1510 break;
1511 case SND_SOC_DAIFMT_IB_NF:
1512 bclk |= ARIZONA_AIF1_BCLK_INV;
1513 break;
1514 case SND_SOC_DAIFMT_NB_IF:
1515 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1516 break;
1517 default:
1518 return -EINVAL;
1521 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
1522 ARIZONA_AIF1_BCLK_INV |
1523 ARIZONA_AIF1_BCLK_MSTR,
1524 bclk);
1525 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
1526 ARIZONA_AIF1TX_LRCLK_INV |
1527 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
1528 regmap_update_bits_async(arizona->regmap,
1529 base + ARIZONA_AIF_RX_PIN_CTRL,
1530 ARIZONA_AIF1RX_LRCLK_INV |
1531 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
1532 regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
1533 ARIZONA_AIF1_FMT_MASK, mode);
1535 return 0;
1538 static const int arizona_48k_bclk_rates[] = {
1540 48000,
1541 64000,
1542 96000,
1543 128000,
1544 192000,
1545 256000,
1546 384000,
1547 512000,
1548 768000,
1549 1024000,
1550 1536000,
1551 2048000,
1552 3072000,
1553 4096000,
1554 6144000,
1555 8192000,
1556 12288000,
1557 24576000,
1560 static const int arizona_44k1_bclk_rates[] = {
1562 44100,
1563 58800,
1564 88200,
1565 117600,
1566 177640,
1567 235200,
1568 352800,
1569 470400,
1570 705600,
1571 940800,
1572 1411200,
1573 1881600,
1574 2822400,
1575 3763200,
1576 5644800,
1577 7526400,
1578 11289600,
1579 22579200,
1582 static const unsigned int arizona_sr_vals[] = {
1584 12000,
1585 24000,
1586 48000,
1587 96000,
1588 192000,
1589 384000,
1590 768000,
1592 11025,
1593 22050,
1594 44100,
1595 88200,
1596 176400,
1597 352800,
1598 705600,
1599 4000,
1600 8000,
1601 16000,
1602 32000,
1603 64000,
1604 128000,
1605 256000,
1606 512000,
1609 #define ARIZONA_48K_RATE_MASK 0x0F003E
1610 #define ARIZONA_44K1_RATE_MASK 0x003E00
1611 #define ARIZONA_RATE_MASK (ARIZONA_48K_RATE_MASK | ARIZONA_44K1_RATE_MASK)
1613 static const struct snd_pcm_hw_constraint_list arizona_constraint = {
1614 .count = ARRAY_SIZE(arizona_sr_vals),
1615 .list = arizona_sr_vals,
1618 static int arizona_startup(struct snd_pcm_substream *substream,
1619 struct snd_soc_dai *dai)
1621 struct snd_soc_component *component = dai->component;
1622 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1623 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1624 unsigned int base_rate;
1626 if (!substream->runtime)
1627 return 0;
1629 switch (dai_priv->clk) {
1630 case ARIZONA_CLK_SYSCLK:
1631 base_rate = priv->sysclk;
1632 break;
1633 case ARIZONA_CLK_ASYNCCLK:
1634 base_rate = priv->asyncclk;
1635 break;
1636 default:
1637 return 0;
1640 if (base_rate == 0)
1641 dai_priv->constraint.mask = ARIZONA_RATE_MASK;
1642 else if (base_rate % 8000)
1643 dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK;
1644 else
1645 dai_priv->constraint.mask = ARIZONA_48K_RATE_MASK;
1647 return snd_pcm_hw_constraint_list(substream->runtime, 0,
1648 SNDRV_PCM_HW_PARAM_RATE,
1649 &dai_priv->constraint);
1652 static void arizona_wm5102_set_dac_comp(struct snd_soc_component *component,
1653 unsigned int rate)
1655 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1656 struct arizona *arizona = priv->arizona;
1657 struct reg_sequence dac_comp[] = {
1658 { 0x80, 0x3 },
1659 { ARIZONA_DAC_COMP_1, 0 },
1660 { ARIZONA_DAC_COMP_2, 0 },
1661 { 0x80, 0x0 },
1664 mutex_lock(&arizona->dac_comp_lock);
1666 dac_comp[1].def = arizona->dac_comp_coeff;
1667 if (rate >= 176400)
1668 dac_comp[2].def = arizona->dac_comp_enabled;
1670 mutex_unlock(&arizona->dac_comp_lock);
1672 regmap_multi_reg_write(arizona->regmap,
1673 dac_comp,
1674 ARRAY_SIZE(dac_comp));
1677 static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1678 struct snd_pcm_hw_params *params,
1679 struct snd_soc_dai *dai)
1681 struct snd_soc_component *component = dai->component;
1682 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1683 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1684 int base = dai->driver->base;
1685 int i, sr_val, ret;
1688 * We will need to be more flexible than this in future,
1689 * currently we use a single sample rate for SYSCLK.
1691 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1692 if (arizona_sr_vals[i] == params_rate(params))
1693 break;
1694 if (i == ARRAY_SIZE(arizona_sr_vals)) {
1695 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1696 params_rate(params));
1697 return -EINVAL;
1699 sr_val = i;
1701 switch (priv->arizona->type) {
1702 case WM5102:
1703 case WM8997:
1704 if (arizona_sr_vals[sr_val] >= 88200)
1705 ret = arizona_dvfs_up(component, ARIZONA_DVFS_SR1_RQ);
1706 else
1707 ret = arizona_dvfs_down(component, ARIZONA_DVFS_SR1_RQ);
1709 if (ret) {
1710 arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
1711 return ret;
1713 break;
1714 default:
1715 break;
1718 switch (dai_priv->clk) {
1719 case ARIZONA_CLK_SYSCLK:
1720 switch (priv->arizona->type) {
1721 case WM5102:
1722 arizona_wm5102_set_dac_comp(component,
1723 params_rate(params));
1724 break;
1725 default:
1726 break;
1729 snd_soc_component_update_bits(component, ARIZONA_SAMPLE_RATE_1,
1730 ARIZONA_SAMPLE_RATE_1_MASK,
1731 sr_val);
1732 if (base)
1733 snd_soc_component_update_bits(component,
1734 base + ARIZONA_AIF_RATE_CTRL,
1735 ARIZONA_AIF1_RATE_MASK, 0);
1736 break;
1737 case ARIZONA_CLK_ASYNCCLK:
1738 snd_soc_component_update_bits(component,
1739 ARIZONA_ASYNC_SAMPLE_RATE_1,
1740 ARIZONA_ASYNC_SAMPLE_RATE_1_MASK,
1741 sr_val);
1742 if (base)
1743 snd_soc_component_update_bits(component,
1744 base + ARIZONA_AIF_RATE_CTRL,
1745 ARIZONA_AIF1_RATE_MASK,
1746 8 << ARIZONA_AIF1_RATE_SHIFT);
1747 break;
1748 default:
1749 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1750 return -EINVAL;
1753 return 0;
1756 static bool arizona_aif_cfg_changed(struct snd_soc_component *component,
1757 int base, int bclk, int lrclk, int frame)
1759 int val;
1761 val = snd_soc_component_read32(component, base + ARIZONA_AIF_BCLK_CTRL);
1762 if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
1763 return true;
1765 val = snd_soc_component_read32(component, base + ARIZONA_AIF_TX_BCLK_RATE);
1766 if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
1767 return true;
1769 val = snd_soc_component_read32(component, base + ARIZONA_AIF_FRAME_CTRL_1);
1770 if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
1771 ARIZONA_AIF1TX_SLOT_LEN_MASK)))
1772 return true;
1774 return false;
1777 static int arizona_hw_params(struct snd_pcm_substream *substream,
1778 struct snd_pcm_hw_params *params,
1779 struct snd_soc_dai *dai)
1781 struct snd_soc_component *component = dai->component;
1782 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1783 struct arizona *arizona = priv->arizona;
1784 int base = dai->driver->base;
1785 const int *rates;
1786 int i, ret, val;
1787 int channels = params_channels(params);
1788 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1789 int tdm_width = arizona->tdm_width[dai->id - 1];
1790 int tdm_slots = arizona->tdm_slots[dai->id - 1];
1791 int bclk, lrclk, wl, frame, bclk_target;
1792 bool reconfig;
1793 unsigned int aif_tx_state, aif_rx_state;
1795 if (params_rate(params) % 4000)
1796 rates = &arizona_44k1_bclk_rates[0];
1797 else
1798 rates = &arizona_48k_bclk_rates[0];
1800 wl = params_width(params);
1802 if (tdm_slots) {
1803 arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
1804 tdm_slots, tdm_width);
1805 bclk_target = tdm_slots * tdm_width * params_rate(params);
1806 channels = tdm_slots;
1807 } else {
1808 bclk_target = snd_soc_params_to_bclk(params);
1809 tdm_width = wl;
1812 if (chan_limit && chan_limit < channels) {
1813 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1814 bclk_target /= channels;
1815 bclk_target *= chan_limit;
1818 /* Force multiple of 2 channels for I2S mode */
1819 val = snd_soc_component_read32(component, base + ARIZONA_AIF_FORMAT);
1820 val &= ARIZONA_AIF1_FMT_MASK;
1821 if ((channels & 1) && (val == ARIZONA_FMT_I2S_MODE)) {
1822 arizona_aif_dbg(dai, "Forcing stereo mode\n");
1823 bclk_target /= channels;
1824 bclk_target *= channels + 1;
1827 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1828 if (rates[i] >= bclk_target &&
1829 rates[i] % params_rate(params) == 0) {
1830 bclk = i;
1831 break;
1834 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1835 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1836 params_rate(params));
1837 return -EINVAL;
1840 lrclk = rates[bclk] / params_rate(params);
1842 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1843 rates[bclk], rates[bclk] / lrclk);
1845 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
1847 reconfig = arizona_aif_cfg_changed(component, base, bclk, lrclk, frame);
1849 if (reconfig) {
1850 /* Save AIF TX/RX state */
1851 aif_tx_state = snd_soc_component_read32(component,
1852 base + ARIZONA_AIF_TX_ENABLES);
1853 aif_rx_state = snd_soc_component_read32(component,
1854 base + ARIZONA_AIF_RX_ENABLES);
1855 /* Disable AIF TX/RX before reconfiguring it */
1856 regmap_update_bits_async(arizona->regmap,
1857 base + ARIZONA_AIF_TX_ENABLES,
1858 0xff, 0x0);
1859 regmap_update_bits(arizona->regmap,
1860 base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
1863 ret = arizona_hw_params_rate(substream, params, dai);
1864 if (ret != 0)
1865 goto restore_aif;
1867 if (reconfig) {
1868 regmap_update_bits_async(arizona->regmap,
1869 base + ARIZONA_AIF_BCLK_CTRL,
1870 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1871 regmap_update_bits_async(arizona->regmap,
1872 base + ARIZONA_AIF_TX_BCLK_RATE,
1873 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1874 regmap_update_bits_async(arizona->regmap,
1875 base + ARIZONA_AIF_RX_BCLK_RATE,
1876 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1877 regmap_update_bits_async(arizona->regmap,
1878 base + ARIZONA_AIF_FRAME_CTRL_1,
1879 ARIZONA_AIF1TX_WL_MASK |
1880 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1881 regmap_update_bits(arizona->regmap,
1882 base + ARIZONA_AIF_FRAME_CTRL_2,
1883 ARIZONA_AIF1RX_WL_MASK |
1884 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1887 restore_aif:
1888 if (reconfig) {
1889 /* Restore AIF TX/RX state */
1890 regmap_update_bits_async(arizona->regmap,
1891 base + ARIZONA_AIF_TX_ENABLES,
1892 0xff, aif_tx_state);
1893 regmap_update_bits(arizona->regmap,
1894 base + ARIZONA_AIF_RX_ENABLES,
1895 0xff, aif_rx_state);
1897 return ret;
1900 static const char *arizona_dai_clk_str(int clk_id)
1902 switch (clk_id) {
1903 case ARIZONA_CLK_SYSCLK:
1904 return "SYSCLK";
1905 case ARIZONA_CLK_ASYNCCLK:
1906 return "ASYNCCLK";
1907 default:
1908 return "Unknown clock";
1912 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1913 int clk_id, unsigned int freq, int dir)
1915 struct snd_soc_component *component = dai->component;
1916 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1917 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1918 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1919 struct snd_soc_dapm_route routes[2];
1921 switch (clk_id) {
1922 case ARIZONA_CLK_SYSCLK:
1923 case ARIZONA_CLK_ASYNCCLK:
1924 break;
1925 default:
1926 return -EINVAL;
1929 if (clk_id == dai_priv->clk)
1930 return 0;
1932 if (dai->active) {
1933 dev_err(component->dev, "Can't change clock on active DAI %d\n",
1934 dai->id);
1935 return -EBUSY;
1938 dev_dbg(component->dev, "Setting AIF%d to %s\n", dai->id + 1,
1939 arizona_dai_clk_str(clk_id));
1941 memset(&routes, 0, sizeof(routes));
1942 routes[0].sink = dai->driver->capture.stream_name;
1943 routes[1].sink = dai->driver->playback.stream_name;
1945 routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1946 routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1947 snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
1949 routes[0].source = arizona_dai_clk_str(clk_id);
1950 routes[1].source = arizona_dai_clk_str(clk_id);
1951 snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
1953 dai_priv->clk = clk_id;
1955 return snd_soc_dapm_sync(dapm);
1958 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1960 struct snd_soc_component *component = dai->component;
1961 int base = dai->driver->base;
1962 unsigned int reg;
1964 if (tristate)
1965 reg = ARIZONA_AIF1_TRI;
1966 else
1967 reg = 0;
1969 return snd_soc_component_update_bits(component,
1970 base + ARIZONA_AIF_RATE_CTRL,
1971 ARIZONA_AIF1_TRI, reg);
1974 static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
1975 unsigned int base,
1976 int channels, unsigned int mask)
1978 struct snd_soc_component *component = dai->component;
1979 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
1980 struct arizona *arizona = priv->arizona;
1981 int slot, i;
1983 for (i = 0; i < channels; ++i) {
1984 slot = ffs(mask) - 1;
1985 if (slot < 0)
1986 return;
1988 regmap_write(arizona->regmap, base + i, slot);
1990 mask &= ~(1 << slot);
1993 if (mask)
1994 arizona_aif_warn(dai, "Too many channels in TDM mask\n");
1997 static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1998 unsigned int rx_mask, int slots, int slot_width)
2000 struct snd_soc_component *component = dai->component;
2001 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
2002 struct arizona *arizona = priv->arizona;
2003 int base = dai->driver->base;
2004 int rx_max_chan = dai->driver->playback.channels_max;
2005 int tx_max_chan = dai->driver->capture.channels_max;
2007 /* Only support TDM for the physical AIFs */
2008 if (dai->id > ARIZONA_MAX_AIF)
2009 return -ENOTSUPP;
2011 if (slots == 0) {
2012 tx_mask = (1 << tx_max_chan) - 1;
2013 rx_mask = (1 << rx_max_chan) - 1;
2016 arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3,
2017 tx_max_chan, tx_mask);
2018 arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11,
2019 rx_max_chan, rx_mask);
2021 arizona->tdm_width[dai->id - 1] = slot_width;
2022 arizona->tdm_slots[dai->id - 1] = slots;
2024 return 0;
2027 const struct snd_soc_dai_ops arizona_dai_ops = {
2028 .startup = arizona_startup,
2029 .set_fmt = arizona_set_fmt,
2030 .set_tdm_slot = arizona_set_tdm_slot,
2031 .hw_params = arizona_hw_params,
2032 .set_sysclk = arizona_dai_set_sysclk,
2033 .set_tristate = arizona_set_tristate,
2035 EXPORT_SYMBOL_GPL(arizona_dai_ops);
2037 const struct snd_soc_dai_ops arizona_simple_dai_ops = {
2038 .startup = arizona_startup,
2039 .hw_params = arizona_hw_params_rate,
2040 .set_sysclk = arizona_dai_set_sysclk,
2042 EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
2044 int arizona_init_dai(struct arizona_priv *priv, int id)
2046 struct arizona_dai_priv *dai_priv = &priv->dai[id];
2048 dai_priv->clk = ARIZONA_CLK_SYSCLK;
2049 dai_priv->constraint = arizona_constraint;
2051 return 0;
2053 EXPORT_SYMBOL_GPL(arizona_init_dai);
2055 static struct {
2056 unsigned int min;
2057 unsigned int max;
2058 u16 fratio;
2059 int ratio;
2060 } fll_fratios[] = {
2061 { 0, 64000, 4, 16 },
2062 { 64000, 128000, 3, 8 },
2063 { 128000, 256000, 2, 4 },
2064 { 256000, 1000000, 1, 2 },
2065 { 1000000, 13500000, 0, 1 },
2068 static const unsigned int pseudo_fref_max[ARIZONA_FLL_MAX_FRATIO] = {
2069 13500000,
2070 6144000,
2071 6144000,
2072 3072000,
2073 3072000,
2074 2822400,
2075 2822400,
2076 1536000,
2077 1536000,
2078 1536000,
2079 1536000,
2080 1536000,
2081 1536000,
2082 1536000,
2083 1536000,
2084 768000,
2087 static struct {
2088 unsigned int min;
2089 unsigned int max;
2090 u16 gain;
2091 } fll_gains[] = {
2092 { 0, 256000, 0 },
2093 { 256000, 1000000, 2 },
2094 { 1000000, 13500000, 4 },
2097 struct arizona_fll_cfg {
2098 int n;
2099 unsigned int theta;
2100 unsigned int lambda;
2101 int refdiv;
2102 int outdiv;
2103 int fratio;
2104 int gain;
2107 static int arizona_validate_fll(struct arizona_fll *fll,
2108 unsigned int Fref,
2109 unsigned int Fout)
2111 unsigned int Fvco_min;
2113 if (fll->fout && Fout != fll->fout) {
2114 arizona_fll_err(fll,
2115 "Can't change output on active FLL\n");
2116 return -EINVAL;
2119 if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
2120 arizona_fll_err(fll,
2121 "Can't scale %dMHz in to <=13.5MHz\n",
2122 Fref);
2123 return -EINVAL;
2126 Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
2127 if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
2128 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
2129 Fout);
2130 return -EINVAL;
2133 return 0;
2136 static int arizona_find_fratio(unsigned int Fref, int *fratio)
2138 int i;
2140 /* Find an appropriate FLL_FRATIO */
2141 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
2142 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
2143 if (fratio)
2144 *fratio = fll_fratios[i].fratio;
2145 return fll_fratios[i].ratio;
2149 return -EINVAL;
2152 static int arizona_calc_fratio(struct arizona_fll *fll,
2153 struct arizona_fll_cfg *cfg,
2154 unsigned int target,
2155 unsigned int Fref, bool sync)
2157 int init_ratio, ratio;
2158 int refdiv, div;
2160 /* Fref must be <=13.5MHz, find initial refdiv */
2161 div = 1;
2162 cfg->refdiv = 0;
2163 while (Fref > ARIZONA_FLL_MAX_FREF) {
2164 div *= 2;
2165 Fref /= 2;
2166 cfg->refdiv++;
2168 if (div > ARIZONA_FLL_MAX_REFDIV)
2169 return -EINVAL;
2172 /* Find an appropriate FLL_FRATIO */
2173 init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
2174 if (init_ratio < 0) {
2175 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
2176 Fref);
2177 return init_ratio;
2180 switch (fll->arizona->type) {
2181 case WM5102:
2182 case WM8997:
2183 return init_ratio;
2184 case WM5110:
2185 case WM8280:
2186 if (fll->arizona->rev < 3 || sync)
2187 return init_ratio;
2188 break;
2189 default:
2190 if (sync)
2191 return init_ratio;
2192 break;
2195 cfg->fratio = init_ratio - 1;
2197 /* Adjust FRATIO/refdiv to avoid integer mode if possible */
2198 refdiv = cfg->refdiv;
2200 arizona_fll_dbg(fll, "pseudo: initial ratio=%u fref=%u refdiv=%u\n",
2201 init_ratio, Fref, refdiv);
2203 while (div <= ARIZONA_FLL_MAX_REFDIV) {
2204 /* start from init_ratio because this may already give a
2205 * fractional N.K
2207 for (ratio = init_ratio; ratio > 0; ratio--) {
2208 if (target % (ratio * Fref)) {
2209 cfg->refdiv = refdiv;
2210 cfg->fratio = ratio - 1;
2211 arizona_fll_dbg(fll,
2212 "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2213 Fref, refdiv, div, ratio);
2214 return ratio;
2218 for (ratio = init_ratio + 1; ratio <= ARIZONA_FLL_MAX_FRATIO;
2219 ratio++) {
2220 if ((ARIZONA_FLL_VCO_CORNER / 2) /
2221 (fll->vco_mult * ratio) < Fref) {
2222 arizona_fll_dbg(fll, "pseudo: hit VCO corner\n");
2223 break;
2226 if (Fref > pseudo_fref_max[ratio - 1]) {
2227 arizona_fll_dbg(fll,
2228 "pseudo: exceeded max fref(%u) for ratio=%u\n",
2229 pseudo_fref_max[ratio - 1],
2230 ratio);
2231 break;
2234 if (target % (ratio * Fref)) {
2235 cfg->refdiv = refdiv;
2236 cfg->fratio = ratio - 1;
2237 arizona_fll_dbg(fll,
2238 "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2239 Fref, refdiv, div, ratio);
2240 return ratio;
2244 div *= 2;
2245 Fref /= 2;
2246 refdiv++;
2247 init_ratio = arizona_find_fratio(Fref, NULL);
2248 arizona_fll_dbg(fll,
2249 "pseudo: change fref=%u refdiv=%d(%d) ratio=%u\n",
2250 Fref, refdiv, div, init_ratio);
2253 arizona_fll_warn(fll, "Falling back to integer mode operation\n");
2254 return cfg->fratio + 1;
2257 static int arizona_calc_fll(struct arizona_fll *fll,
2258 struct arizona_fll_cfg *cfg,
2259 unsigned int Fref, bool sync)
2261 unsigned int target, div, gcd_fll;
2262 int i, ratio;
2264 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
2266 /* Fvco should be over the targt; don't check the upper bound */
2267 div = ARIZONA_FLL_MIN_OUTDIV;
2268 while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
2269 div++;
2270 if (div > ARIZONA_FLL_MAX_OUTDIV)
2271 return -EINVAL;
2273 target = fll->fout * div / fll->vco_mult;
2274 cfg->outdiv = div;
2276 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
2278 /* Find an appropriate FLL_FRATIO and refdiv */
2279 ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
2280 if (ratio < 0)
2281 return ratio;
2283 /* Apply the division for our remaining calculations */
2284 Fref = Fref / (1 << cfg->refdiv);
2286 cfg->n = target / (ratio * Fref);
2288 if (target % (ratio * Fref)) {
2289 gcd_fll = gcd(target, ratio * Fref);
2290 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
2292 cfg->theta = (target - (cfg->n * ratio * Fref))
2293 / gcd_fll;
2294 cfg->lambda = (ratio * Fref) / gcd_fll;
2295 } else {
2296 cfg->theta = 0;
2297 cfg->lambda = 0;
2300 /* Round down to 16bit range with cost of accuracy lost.
2301 * Denominator must be bigger than numerator so we only
2302 * take care of it.
2304 while (cfg->lambda >= (1 << 16)) {
2305 cfg->theta >>= 1;
2306 cfg->lambda >>= 1;
2309 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
2310 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
2311 cfg->gain = fll_gains[i].gain;
2312 break;
2315 if (i == ARRAY_SIZE(fll_gains)) {
2316 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
2317 Fref);
2318 return -EINVAL;
2321 arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
2322 cfg->n, cfg->theta, cfg->lambda);
2323 arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n",
2324 cfg->fratio, ratio, cfg->outdiv,
2325 cfg->refdiv, 1 << cfg->refdiv);
2326 arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
2328 return 0;
2331 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
2332 struct arizona_fll_cfg *cfg, int source,
2333 bool sync)
2335 regmap_update_bits_async(arizona->regmap, base + 3,
2336 ARIZONA_FLL1_THETA_MASK, cfg->theta);
2337 regmap_update_bits_async(arizona->regmap, base + 4,
2338 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
2339 regmap_update_bits_async(arizona->regmap, base + 5,
2340 ARIZONA_FLL1_FRATIO_MASK,
2341 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
2342 regmap_update_bits_async(arizona->regmap, base + 6,
2343 ARIZONA_FLL1_CLK_REF_DIV_MASK |
2344 ARIZONA_FLL1_CLK_REF_SRC_MASK,
2345 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
2346 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
2348 if (sync) {
2349 regmap_update_bits(arizona->regmap, base + 0x7,
2350 ARIZONA_FLL1_GAIN_MASK,
2351 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2352 } else {
2353 regmap_update_bits(arizona->regmap, base + 0x5,
2354 ARIZONA_FLL1_OUTDIV_MASK,
2355 cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
2356 regmap_update_bits(arizona->regmap, base + 0x9,
2357 ARIZONA_FLL1_GAIN_MASK,
2358 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2361 regmap_update_bits_async(arizona->regmap, base + 2,
2362 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
2363 ARIZONA_FLL1_CTRL_UPD | cfg->n);
2366 static int arizona_is_enabled_fll(struct arizona_fll *fll, int base)
2368 struct arizona *arizona = fll->arizona;
2369 unsigned int reg;
2370 int ret;
2372 ret = regmap_read(arizona->regmap, base + 1, &reg);
2373 if (ret != 0) {
2374 arizona_fll_err(fll, "Failed to read current state: %d\n",
2375 ret);
2376 return ret;
2379 return reg & ARIZONA_FLL1_ENA;
2382 static int arizona_set_fll_clks(struct arizona_fll *fll, int base, bool ena)
2384 struct arizona *arizona = fll->arizona;
2385 unsigned int val;
2386 struct clk *clk;
2387 int ret;
2389 ret = regmap_read(arizona->regmap, base + 6, &val);
2390 if (ret != 0) {
2391 arizona_fll_err(fll, "Failed to read current source: %d\n",
2392 ret);
2393 return ret;
2396 val &= ARIZONA_FLL1_CLK_REF_SRC_MASK;
2397 val >>= ARIZONA_FLL1_CLK_REF_SRC_SHIFT;
2399 switch (val) {
2400 case ARIZONA_FLL_SRC_MCLK1:
2401 clk = arizona->mclk[ARIZONA_MCLK1];
2402 break;
2403 case ARIZONA_FLL_SRC_MCLK2:
2404 clk = arizona->mclk[ARIZONA_MCLK2];
2405 break;
2406 default:
2407 return 0;
2410 if (ena) {
2411 return clk_prepare_enable(clk);
2412 } else {
2413 clk_disable_unprepare(clk);
2414 return 0;
2418 static int arizona_enable_fll(struct arizona_fll *fll)
2420 struct arizona *arizona = fll->arizona;
2421 bool use_sync = false;
2422 int already_enabled = arizona_is_enabled_fll(fll, fll->base);
2423 int sync_enabled = arizona_is_enabled_fll(fll, fll->base + 0x10);
2424 struct arizona_fll_cfg cfg;
2425 int i;
2426 unsigned int val;
2428 if (already_enabled < 0)
2429 return already_enabled;
2430 if (sync_enabled < 0)
2431 return sync_enabled;
2433 if (already_enabled) {
2434 /* Facilitate smooth refclk across the transition */
2435 regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2436 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2437 udelay(32);
2438 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2439 ARIZONA_FLL1_GAIN_MASK, 0);
2441 if (arizona_is_enabled_fll(fll, fll->base + 0x10) > 0)
2442 arizona_set_fll_clks(fll, fll->base + 0x10, false);
2443 arizona_set_fll_clks(fll, fll->base, false);
2447 * If we have both REFCLK and SYNCCLK then enable both,
2448 * otherwise apply the SYNCCLK settings to REFCLK.
2450 if (fll->ref_src >= 0 && fll->ref_freq &&
2451 fll->ref_src != fll->sync_src) {
2452 arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
2454 /* Ref path hardcodes lambda to 65536 when sync is on */
2455 if (fll->sync_src >= 0 && cfg.lambda)
2456 cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
2458 arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
2459 false);
2460 if (fll->sync_src >= 0) {
2461 arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
2463 arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
2464 fll->sync_src, true);
2465 use_sync = true;
2467 } else if (fll->sync_src >= 0) {
2468 arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
2470 arizona_apply_fll(arizona, fll->base, &cfg,
2471 fll->sync_src, false);
2473 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2474 ARIZONA_FLL1_SYNC_ENA, 0);
2475 } else {
2476 arizona_fll_err(fll, "No clocks provided\n");
2477 return -EINVAL;
2480 if (already_enabled && !!sync_enabled != use_sync)
2481 arizona_fll_warn(fll, "Synchroniser changed on active FLL\n");
2484 * Increase the bandwidth if we're not using a low frequency
2485 * sync source.
2487 if (use_sync && fll->sync_freq > 100000)
2488 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2489 ARIZONA_FLL1_SYNC_BW, 0);
2490 else
2491 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2492 ARIZONA_FLL1_SYNC_BW,
2493 ARIZONA_FLL1_SYNC_BW);
2495 if (!already_enabled)
2496 pm_runtime_get_sync(arizona->dev);
2498 if (use_sync) {
2499 arizona_set_fll_clks(fll, fll->base + 0x10, true);
2500 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2501 ARIZONA_FLL1_SYNC_ENA,
2502 ARIZONA_FLL1_SYNC_ENA);
2504 arizona_set_fll_clks(fll, fll->base, true);
2505 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2506 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
2508 if (already_enabled)
2509 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2510 ARIZONA_FLL1_FREERUN, 0);
2512 arizona_fll_dbg(fll, "Waiting for FLL lock...\n");
2513 val = 0;
2514 for (i = 0; i < 15; i++) {
2515 if (i < 5)
2516 usleep_range(200, 400);
2517 else
2518 msleep(20);
2520 regmap_read(arizona->regmap,
2521 ARIZONA_INTERRUPT_RAW_STATUS_5,
2522 &val);
2523 if (val & (ARIZONA_FLL1_CLOCK_OK_STS << (fll->id - 1)))
2524 break;
2526 if (i == 15)
2527 arizona_fll_warn(fll, "Timed out waiting for lock\n");
2528 else
2529 arizona_fll_dbg(fll, "FLL locked (%d polls)\n", i);
2531 return 0;
2534 static void arizona_disable_fll(struct arizona_fll *fll)
2536 struct arizona *arizona = fll->arizona;
2537 bool ref_change, sync_change;
2539 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2540 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2541 regmap_update_bits_check(arizona->regmap, fll->base + 1,
2542 ARIZONA_FLL1_ENA, 0, &ref_change);
2543 regmap_update_bits_check(arizona->regmap, fll->base + 0x11,
2544 ARIZONA_FLL1_SYNC_ENA, 0, &sync_change);
2545 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2546 ARIZONA_FLL1_FREERUN, 0);
2548 if (sync_change)
2549 arizona_set_fll_clks(fll, fll->base + 0x10, false);
2551 if (ref_change) {
2552 arizona_set_fll_clks(fll, fll->base, false);
2553 pm_runtime_put_autosuspend(arizona->dev);
2557 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
2558 unsigned int Fref, unsigned int Fout)
2560 int ret = 0;
2562 if (fll->ref_src == source && fll->ref_freq == Fref)
2563 return 0;
2565 if (fll->fout && Fref > 0) {
2566 ret = arizona_validate_fll(fll, Fref, fll->fout);
2567 if (ret != 0)
2568 return ret;
2571 fll->ref_src = source;
2572 fll->ref_freq = Fref;
2574 if (fll->fout && Fref > 0)
2575 ret = arizona_enable_fll(fll);
2577 return ret;
2579 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
2581 int arizona_set_fll(struct arizona_fll *fll, int source,
2582 unsigned int Fref, unsigned int Fout)
2584 int ret = 0;
2586 if (fll->sync_src == source &&
2587 fll->sync_freq == Fref && fll->fout == Fout)
2588 return 0;
2590 if (Fout) {
2591 if (fll->ref_src >= 0) {
2592 ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
2593 if (ret != 0)
2594 return ret;
2597 ret = arizona_validate_fll(fll, Fref, Fout);
2598 if (ret != 0)
2599 return ret;
2602 fll->sync_src = source;
2603 fll->sync_freq = Fref;
2604 fll->fout = Fout;
2606 if (Fout)
2607 ret = arizona_enable_fll(fll);
2608 else
2609 arizona_disable_fll(fll);
2611 return ret;
2613 EXPORT_SYMBOL_GPL(arizona_set_fll);
2615 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
2616 int ok_irq, struct arizona_fll *fll)
2618 unsigned int val;
2620 fll->id = id;
2621 fll->base = base;
2622 fll->arizona = arizona;
2623 fll->sync_src = ARIZONA_FLL_SRC_NONE;
2625 /* Configure default refclk to 32kHz if we have one */
2626 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
2627 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
2628 case ARIZONA_CLK_SRC_MCLK1:
2629 case ARIZONA_CLK_SRC_MCLK2:
2630 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
2631 break;
2632 default:
2633 fll->ref_src = ARIZONA_FLL_SRC_NONE;
2635 fll->ref_freq = 32768;
2637 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
2638 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
2639 "FLL%d clock OK", id);
2641 regmap_update_bits(arizona->regmap, fll->base + 1,
2642 ARIZONA_FLL1_FREERUN, 0);
2644 return 0;
2646 EXPORT_SYMBOL_GPL(arizona_init_fll);
2649 * arizona_set_output_mode - Set the mode of the specified output
2651 * @component: Device to configure
2652 * @output: Output number
2653 * @diff: True to set the output to differential mode
2655 * Some systems use external analogue switches to connect more
2656 * analogue devices to the CODEC than are supported by the device. In
2657 * some systems this requires changing the switched output from single
2658 * ended to differential mode dynamically at runtime, an operation
2659 * supported using this function.
2661 * Most systems have a single static configuration and should use
2662 * platform data instead.
2664 int arizona_set_output_mode(struct snd_soc_component *component, int output,
2665 bool diff)
2667 unsigned int reg, val;
2669 if (output < 1 || output > 6)
2670 return -EINVAL;
2672 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
2674 if (diff)
2675 val = ARIZONA_OUT1_MONO;
2676 else
2677 val = 0;
2679 return snd_soc_component_update_bits(component, reg,
2680 ARIZONA_OUT1_MONO, val);
2682 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
2684 static const struct soc_enum arizona_adsp2_rate_enum[] = {
2685 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
2686 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2687 ARIZONA_RATE_ENUM_SIZE,
2688 arizona_rate_text, arizona_rate_val),
2689 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
2690 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2691 ARIZONA_RATE_ENUM_SIZE,
2692 arizona_rate_text, arizona_rate_val),
2693 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
2694 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2695 ARIZONA_RATE_ENUM_SIZE,
2696 arizona_rate_text, arizona_rate_val),
2697 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
2698 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2699 ARIZONA_RATE_ENUM_SIZE,
2700 arizona_rate_text, arizona_rate_val),
2703 const struct snd_kcontrol_new arizona_adsp2_rate_controls[] = {
2704 SOC_ENUM("DSP1 Rate", arizona_adsp2_rate_enum[0]),
2705 SOC_ENUM("DSP2 Rate", arizona_adsp2_rate_enum[1]),
2706 SOC_ENUM("DSP3 Rate", arizona_adsp2_rate_enum[2]),
2707 SOC_ENUM("DSP4 Rate", arizona_adsp2_rate_enum[3]),
2709 EXPORT_SYMBOL_GPL(arizona_adsp2_rate_controls);
2711 static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
2713 s16 a = be16_to_cpu(_a);
2714 s16 b = be16_to_cpu(_b);
2716 if (!mode) {
2717 return abs(a) >= 4096;
2718 } else {
2719 if (abs(b) >= 4096)
2720 return true;
2722 return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
2726 int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
2727 struct snd_ctl_elem_value *ucontrol)
2729 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2730 struct arizona *arizona = dev_get_drvdata(component->dev->parent);
2731 struct soc_bytes *params = (void *)kcontrol->private_value;
2732 unsigned int val;
2733 __be16 *data;
2734 int len;
2735 int ret;
2737 len = params->num_regs * regmap_get_val_bytes(arizona->regmap);
2739 data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
2740 if (!data)
2741 return -ENOMEM;
2743 data[0] &= cpu_to_be16(ARIZONA_EQ1_B1_MODE);
2745 if (arizona_eq_filter_unstable(!!data[0], data[1], data[2]) ||
2746 arizona_eq_filter_unstable(true, data[4], data[5]) ||
2747 arizona_eq_filter_unstable(true, data[8], data[9]) ||
2748 arizona_eq_filter_unstable(true, data[12], data[13]) ||
2749 arizona_eq_filter_unstable(false, data[16], data[17])) {
2750 dev_err(arizona->dev, "Rejecting unstable EQ coefficients\n");
2751 ret = -EINVAL;
2752 goto out;
2755 ret = regmap_read(arizona->regmap, params->base, &val);
2756 if (ret != 0)
2757 goto out;
2759 val &= ~ARIZONA_EQ1_B1_MODE;
2760 data[0] |= cpu_to_be16(val);
2762 ret = regmap_raw_write(arizona->regmap, params->base, data, len);
2764 out:
2765 kfree(data);
2766 return ret;
2768 EXPORT_SYMBOL_GPL(arizona_eq_coeff_put);
2770 int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
2771 struct snd_ctl_elem_value *ucontrol)
2773 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2774 struct arizona *arizona = dev_get_drvdata(component->dev->parent);
2775 __be16 *data = (__be16 *)ucontrol->value.bytes.data;
2776 s16 val = be16_to_cpu(*data);
2778 if (abs(val) >= 4096) {
2779 dev_err(arizona->dev, "Rejecting unstable LHPF coefficients\n");
2780 return -EINVAL;
2783 return snd_soc_bytes_put(kcontrol, ucontrol);
2785 EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
2787 int arizona_of_get_audio_pdata(struct arizona *arizona)
2789 struct arizona_pdata *pdata = &arizona->pdata;
2790 struct device_node *np = arizona->dev->of_node;
2791 struct property *prop;
2792 const __be32 *cur;
2793 u32 val;
2794 u32 pdm_val[ARIZONA_MAX_PDM_SPK];
2795 int ret;
2796 int count = 0;
2798 count = 0;
2799 of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) {
2800 if (count == ARRAY_SIZE(pdata->inmode))
2801 break;
2803 pdata->inmode[count] = val;
2804 count++;
2807 count = 0;
2808 of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) {
2809 if (count == ARRAY_SIZE(pdata->dmic_ref))
2810 break;
2812 pdata->dmic_ref[count] = val;
2813 count++;
2816 count = 0;
2817 of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) {
2818 if (count == ARRAY_SIZE(pdata->out_mono))
2819 break;
2821 pdata->out_mono[count] = !!val;
2822 count++;
2825 count = 0;
2826 of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) {
2827 if (count == ARRAY_SIZE(pdata->max_channels_clocked))
2828 break;
2830 pdata->max_channels_clocked[count] = val;
2831 count++;
2834 count = 0;
2835 of_property_for_each_u32(np, "wlf,out-volume-limit", prop, cur, val) {
2836 if (count == ARRAY_SIZE(pdata->out_vol_limit))
2837 break;
2839 pdata->out_vol_limit[count] = val;
2840 count++;
2843 ret = of_property_read_u32_array(np, "wlf,spk-fmt",
2844 pdm_val, ARRAY_SIZE(pdm_val));
2846 if (ret >= 0)
2847 for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
2848 pdata->spk_fmt[count] = pdm_val[count];
2850 ret = of_property_read_u32_array(np, "wlf,spk-mute",
2851 pdm_val, ARRAY_SIZE(pdm_val));
2853 if (ret >= 0)
2854 for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
2855 pdata->spk_mute[count] = pdm_val[count];
2857 return 0;
2859 EXPORT_SYMBOL_GPL(arizona_of_get_audio_pdata);
2861 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2862 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2863 MODULE_LICENSE("GPL");