Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[cris-mirror.git] / sound / soc / codecs / arizona.c
blobb3375e19598a8372dbedbb4e012cb343d5c0fbdb
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_codec *codec = snd_soc_dapm_to_codec(w->dapm);
88 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
89 int val;
91 switch (event) {
92 case SND_SOC_DAPM_POST_PMU:
93 val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3);
94 if (val & ARIZONA_SPK_OVERHEAT_STS) {
95 dev_crit(arizona->dev,
96 "Speaker not enabled due to temperature\n");
97 return -EBUSY;
100 regmap_update_bits_async(arizona->regmap,
101 ARIZONA_OUTPUT_ENABLES_1,
102 1 << w->shift, 1 << w->shift);
103 break;
104 case SND_SOC_DAPM_PRE_PMD:
105 regmap_update_bits_async(arizona->regmap,
106 ARIZONA_OUTPUT_ENABLES_1,
107 1 << w->shift, 0);
108 break;
109 default:
110 break;
113 return arizona_out_ev(w, kcontrol, event);
116 static irqreturn_t arizona_thermal_warn(int irq, void *data)
118 struct arizona *arizona = data;
119 unsigned int val;
120 int ret;
122 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
123 &val);
124 if (ret != 0) {
125 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
126 ret);
127 } else if (val & ARIZONA_SPK_OVERHEAT_WARN_STS) {
128 dev_crit(arizona->dev, "Thermal warning\n");
131 return IRQ_HANDLED;
134 static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
136 struct arizona *arizona = data;
137 unsigned int val;
138 int ret;
140 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
141 &val);
142 if (ret != 0) {
143 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
144 ret);
145 } else if (val & ARIZONA_SPK_OVERHEAT_STS) {
146 dev_crit(arizona->dev, "Thermal shutdown\n");
147 ret = regmap_update_bits(arizona->regmap,
148 ARIZONA_OUTPUT_ENABLES_1,
149 ARIZONA_OUT4L_ENA |
150 ARIZONA_OUT4R_ENA, 0);
151 if (ret != 0)
152 dev_crit(arizona->dev,
153 "Failed to disable speaker outputs: %d\n",
154 ret);
157 return IRQ_HANDLED;
160 static const struct snd_soc_dapm_widget arizona_spkl =
161 SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM,
162 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
163 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
164 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
166 static const struct snd_soc_dapm_widget arizona_spkr =
167 SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM,
168 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev,
169 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
170 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD);
172 int arizona_init_spk(struct snd_soc_codec *codec)
174 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
175 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
176 struct arizona *arizona = priv->arizona;
177 int ret;
179 ret = snd_soc_dapm_new_controls(dapm, &arizona_spkl, 1);
180 if (ret != 0)
181 return ret;
183 switch (arizona->type) {
184 case WM8997:
185 case CS47L24:
186 case WM1831:
187 break;
188 default:
189 ret = snd_soc_dapm_new_controls(dapm, &arizona_spkr, 1);
190 if (ret != 0)
191 return ret;
192 break;
195 return 0;
197 EXPORT_SYMBOL_GPL(arizona_init_spk);
199 int arizona_init_spk_irqs(struct arizona *arizona)
201 int ret;
203 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN,
204 "Thermal warning", arizona_thermal_warn,
205 arizona);
206 if (ret != 0)
207 dev_err(arizona->dev,
208 "Failed to get thermal warning IRQ: %d\n",
209 ret);
211 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT,
212 "Thermal shutdown", arizona_thermal_shutdown,
213 arizona);
214 if (ret != 0)
215 dev_err(arizona->dev,
216 "Failed to get thermal shutdown IRQ: %d\n",
217 ret);
219 return 0;
221 EXPORT_SYMBOL_GPL(arizona_init_spk_irqs);
223 int arizona_free_spk_irqs(struct arizona *arizona)
225 arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN, arizona);
226 arizona_free_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT, arizona);
228 return 0;
230 EXPORT_SYMBOL_GPL(arizona_free_spk_irqs);
232 static const struct snd_soc_dapm_route arizona_mono_routes[] = {
233 { "OUT1R", NULL, "OUT1L" },
234 { "OUT2R", NULL, "OUT2L" },
235 { "OUT3R", NULL, "OUT3L" },
236 { "OUT4R", NULL, "OUT4L" },
237 { "OUT5R", NULL, "OUT5L" },
238 { "OUT6R", NULL, "OUT6L" },
241 int arizona_init_mono(struct snd_soc_codec *codec)
243 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
244 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
245 struct arizona *arizona = priv->arizona;
246 int i;
248 for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
249 if (arizona->pdata.out_mono[i])
250 snd_soc_dapm_add_routes(dapm,
251 &arizona_mono_routes[i], 1);
254 return 0;
256 EXPORT_SYMBOL_GPL(arizona_init_mono);
258 int arizona_init_gpio(struct snd_soc_codec *codec)
260 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
261 struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
262 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
263 struct arizona *arizona = priv->arizona;
264 int i;
266 switch (arizona->type) {
267 case WM5110:
268 case WM8280:
269 snd_soc_component_disable_pin(component,
270 "DRC2 Signal Activity");
271 break;
272 default:
273 break;
276 snd_soc_component_disable_pin(component, "DRC1 Signal Activity");
278 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
279 switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
280 case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
281 snd_soc_component_enable_pin(component,
282 "DRC1 Signal Activity");
283 break;
284 case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
285 snd_soc_component_enable_pin(component,
286 "DRC2 Signal Activity");
287 break;
288 default:
289 break;
293 return 0;
295 EXPORT_SYMBOL_GPL(arizona_init_gpio);
297 int arizona_init_common(struct arizona *arizona)
299 struct arizona_pdata *pdata = &arizona->pdata;
300 unsigned int val, mask;
301 int i;
303 BLOCKING_INIT_NOTIFIER_HEAD(&arizona->notifier);
305 for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
306 /* Default is 0 so noop with defaults */
307 if (pdata->out_mono[i])
308 val = ARIZONA_OUT1_MONO;
309 else
310 val = 0;
312 regmap_update_bits(arizona->regmap,
313 ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
314 ARIZONA_OUT1_MONO, val);
317 for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
318 if (pdata->spk_mute[i])
319 regmap_update_bits(arizona->regmap,
320 ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
321 ARIZONA_SPK1_MUTE_ENDIAN_MASK |
322 ARIZONA_SPK1_MUTE_SEQ1_MASK,
323 pdata->spk_mute[i]);
325 if (pdata->spk_fmt[i])
326 regmap_update_bits(arizona->regmap,
327 ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
328 ARIZONA_SPK1_FMT_MASK,
329 pdata->spk_fmt[i]);
332 for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
333 /* Default for both is 0 so noop with defaults */
334 val = pdata->dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT;
335 if (pdata->inmode[i] & ARIZONA_INMODE_DMIC)
336 val |= 1 << ARIZONA_IN1_MODE_SHIFT;
338 switch (arizona->type) {
339 case WM8998:
340 case WM1814:
341 regmap_update_bits(arizona->regmap,
342 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
343 ARIZONA_IN1L_SRC_SE_MASK,
344 (pdata->inmode[i] & ARIZONA_INMODE_SE)
345 << ARIZONA_IN1L_SRC_SE_SHIFT);
347 regmap_update_bits(arizona->regmap,
348 ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
349 ARIZONA_IN1R_SRC_SE_MASK,
350 (pdata->inmode[i] & ARIZONA_INMODE_SE)
351 << ARIZONA_IN1R_SRC_SE_SHIFT);
353 mask = ARIZONA_IN1_DMIC_SUP_MASK |
354 ARIZONA_IN1_MODE_MASK;
355 break;
356 default:
357 if (pdata->inmode[i] & ARIZONA_INMODE_SE)
358 val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;
360 mask = ARIZONA_IN1_DMIC_SUP_MASK |
361 ARIZONA_IN1_MODE_MASK |
362 ARIZONA_IN1_SINGLE_ENDED_MASK;
363 break;
366 regmap_update_bits(arizona->regmap,
367 ARIZONA_IN1L_CONTROL + (i * 8),
368 mask, val);
371 return 0;
373 EXPORT_SYMBOL_GPL(arizona_init_common);
375 int arizona_init_vol_limit(struct arizona *arizona)
377 int i;
379 for (i = 0; i < ARRAY_SIZE(arizona->pdata.out_vol_limit); ++i) {
380 if (arizona->pdata.out_vol_limit[i])
381 regmap_update_bits(arizona->regmap,
382 ARIZONA_DAC_VOLUME_LIMIT_1L + i * 4,
383 ARIZONA_OUT1L_VOL_LIM_MASK,
384 arizona->pdata.out_vol_limit[i]);
387 return 0;
389 EXPORT_SYMBOL_GPL(arizona_init_vol_limit);
391 const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
392 "None",
393 "Tone Generator 1",
394 "Tone Generator 2",
395 "Haptics",
396 "AEC",
397 "AEC2",
398 "Mic Mute Mixer",
399 "Noise Generator",
400 "IN1L",
401 "IN1R",
402 "IN2L",
403 "IN2R",
404 "IN3L",
405 "IN3R",
406 "IN4L",
407 "IN4R",
408 "AIF1RX1",
409 "AIF1RX2",
410 "AIF1RX3",
411 "AIF1RX4",
412 "AIF1RX5",
413 "AIF1RX6",
414 "AIF1RX7",
415 "AIF1RX8",
416 "AIF2RX1",
417 "AIF2RX2",
418 "AIF2RX3",
419 "AIF2RX4",
420 "AIF2RX5",
421 "AIF2RX6",
422 "AIF3RX1",
423 "AIF3RX2",
424 "SLIMRX1",
425 "SLIMRX2",
426 "SLIMRX3",
427 "SLIMRX4",
428 "SLIMRX5",
429 "SLIMRX6",
430 "SLIMRX7",
431 "SLIMRX8",
432 "EQ1",
433 "EQ2",
434 "EQ3",
435 "EQ4",
436 "DRC1L",
437 "DRC1R",
438 "DRC2L",
439 "DRC2R",
440 "LHPF1",
441 "LHPF2",
442 "LHPF3",
443 "LHPF4",
444 "DSP1.1",
445 "DSP1.2",
446 "DSP1.3",
447 "DSP1.4",
448 "DSP1.5",
449 "DSP1.6",
450 "DSP2.1",
451 "DSP2.2",
452 "DSP2.3",
453 "DSP2.4",
454 "DSP2.5",
455 "DSP2.6",
456 "DSP3.1",
457 "DSP3.2",
458 "DSP3.3",
459 "DSP3.4",
460 "DSP3.5",
461 "DSP3.6",
462 "DSP4.1",
463 "DSP4.2",
464 "DSP4.3",
465 "DSP4.4",
466 "DSP4.5",
467 "DSP4.6",
468 "ASRC1L",
469 "ASRC1R",
470 "ASRC2L",
471 "ASRC2R",
472 "ISRC1INT1",
473 "ISRC1INT2",
474 "ISRC1INT3",
475 "ISRC1INT4",
476 "ISRC1DEC1",
477 "ISRC1DEC2",
478 "ISRC1DEC3",
479 "ISRC1DEC4",
480 "ISRC2INT1",
481 "ISRC2INT2",
482 "ISRC2INT3",
483 "ISRC2INT4",
484 "ISRC2DEC1",
485 "ISRC2DEC2",
486 "ISRC2DEC3",
487 "ISRC2DEC4",
488 "ISRC3INT1",
489 "ISRC3INT2",
490 "ISRC3INT3",
491 "ISRC3INT4",
492 "ISRC3DEC1",
493 "ISRC3DEC2",
494 "ISRC3DEC3",
495 "ISRC3DEC4",
497 EXPORT_SYMBOL_GPL(arizona_mixer_texts);
499 unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
500 0x00, /* None */
501 0x04, /* Tone */
502 0x05,
503 0x06, /* Haptics */
504 0x08, /* AEC */
505 0x09, /* AEC2 */
506 0x0c, /* Noise mixer */
507 0x0d, /* Comfort noise */
508 0x10, /* IN1L */
509 0x11,
510 0x12,
511 0x13,
512 0x14,
513 0x15,
514 0x16,
515 0x17,
516 0x20, /* AIF1RX1 */
517 0x21,
518 0x22,
519 0x23,
520 0x24,
521 0x25,
522 0x26,
523 0x27,
524 0x28, /* AIF2RX1 */
525 0x29,
526 0x2a,
527 0x2b,
528 0x2c,
529 0x2d,
530 0x30, /* AIF3RX1 */
531 0x31,
532 0x38, /* SLIMRX1 */
533 0x39,
534 0x3a,
535 0x3b,
536 0x3c,
537 0x3d,
538 0x3e,
539 0x3f,
540 0x50, /* EQ1 */
541 0x51,
542 0x52,
543 0x53,
544 0x58, /* DRC1L */
545 0x59,
546 0x5a,
547 0x5b,
548 0x60, /* LHPF1 */
549 0x61,
550 0x62,
551 0x63,
552 0x68, /* DSP1.1 */
553 0x69,
554 0x6a,
555 0x6b,
556 0x6c,
557 0x6d,
558 0x70, /* DSP2.1 */
559 0x71,
560 0x72,
561 0x73,
562 0x74,
563 0x75,
564 0x78, /* DSP3.1 */
565 0x79,
566 0x7a,
567 0x7b,
568 0x7c,
569 0x7d,
570 0x80, /* DSP4.1 */
571 0x81,
572 0x82,
573 0x83,
574 0x84,
575 0x85,
576 0x90, /* ASRC1L */
577 0x91,
578 0x92,
579 0x93,
580 0xa0, /* ISRC1INT1 */
581 0xa1,
582 0xa2,
583 0xa3,
584 0xa4, /* ISRC1DEC1 */
585 0xa5,
586 0xa6,
587 0xa7,
588 0xa8, /* ISRC2DEC1 */
589 0xa9,
590 0xaa,
591 0xab,
592 0xac, /* ISRC2INT1 */
593 0xad,
594 0xae,
595 0xaf,
596 0xb0, /* ISRC3DEC1 */
597 0xb1,
598 0xb2,
599 0xb3,
600 0xb4, /* ISRC3INT1 */
601 0xb5,
602 0xb6,
603 0xb7,
605 EXPORT_SYMBOL_GPL(arizona_mixer_values);
607 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
608 EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
610 const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
611 "12kHz", "24kHz", "48kHz", "96kHz", "192kHz",
612 "11.025kHz", "22.05kHz", "44.1kHz", "88.2kHz", "176.4kHz",
613 "4kHz", "8kHz", "16kHz", "32kHz",
615 EXPORT_SYMBOL_GPL(arizona_sample_rate_text);
617 const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
618 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
619 0x10, 0x11, 0x12, 0x13,
621 EXPORT_SYMBOL_GPL(arizona_sample_rate_val);
623 const char *arizona_sample_rate_val_to_name(unsigned int rate_val)
625 int i;
627 for (i = 0; i < ARRAY_SIZE(arizona_sample_rate_val); ++i) {
628 if (arizona_sample_rate_val[i] == rate_val)
629 return arizona_sample_rate_text[i];
632 return "Illegal";
634 EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name);
636 const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
637 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
639 EXPORT_SYMBOL_GPL(arizona_rate_text);
641 const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
642 0, 1, 2, 8,
644 EXPORT_SYMBOL_GPL(arizona_rate_val);
647 const struct soc_enum arizona_isrc_fsh[] = {
648 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1,
649 ARIZONA_ISRC1_FSH_SHIFT, 0xf,
650 ARIZONA_RATE_ENUM_SIZE,
651 arizona_rate_text, arizona_rate_val),
652 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_1,
653 ARIZONA_ISRC2_FSH_SHIFT, 0xf,
654 ARIZONA_RATE_ENUM_SIZE,
655 arizona_rate_text, arizona_rate_val),
656 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_1,
657 ARIZONA_ISRC3_FSH_SHIFT, 0xf,
658 ARIZONA_RATE_ENUM_SIZE,
659 arizona_rate_text, arizona_rate_val),
661 EXPORT_SYMBOL_GPL(arizona_isrc_fsh);
663 const struct soc_enum arizona_isrc_fsl[] = {
664 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2,
665 ARIZONA_ISRC1_FSL_SHIFT, 0xf,
666 ARIZONA_RATE_ENUM_SIZE,
667 arizona_rate_text, arizona_rate_val),
668 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2,
669 ARIZONA_ISRC2_FSL_SHIFT, 0xf,
670 ARIZONA_RATE_ENUM_SIZE,
671 arizona_rate_text, arizona_rate_val),
672 SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2,
673 ARIZONA_ISRC3_FSL_SHIFT, 0xf,
674 ARIZONA_RATE_ENUM_SIZE,
675 arizona_rate_text, arizona_rate_val),
677 EXPORT_SYMBOL_GPL(arizona_isrc_fsl);
679 const struct soc_enum arizona_asrc_rate1 =
680 SOC_VALUE_ENUM_SINGLE(ARIZONA_ASRC_RATE1,
681 ARIZONA_ASRC_RATE1_SHIFT, 0xf,
682 ARIZONA_RATE_ENUM_SIZE - 1,
683 arizona_rate_text, arizona_rate_val);
684 EXPORT_SYMBOL_GPL(arizona_asrc_rate1);
686 static const char * const arizona_vol_ramp_text[] = {
687 "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
688 "15ms/6dB", "30ms/6dB",
691 SOC_ENUM_SINGLE_DECL(arizona_in_vd_ramp,
692 ARIZONA_INPUT_VOLUME_RAMP,
693 ARIZONA_IN_VD_RAMP_SHIFT,
694 arizona_vol_ramp_text);
695 EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
697 SOC_ENUM_SINGLE_DECL(arizona_in_vi_ramp,
698 ARIZONA_INPUT_VOLUME_RAMP,
699 ARIZONA_IN_VI_RAMP_SHIFT,
700 arizona_vol_ramp_text);
701 EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
703 SOC_ENUM_SINGLE_DECL(arizona_out_vd_ramp,
704 ARIZONA_OUTPUT_VOLUME_RAMP,
705 ARIZONA_OUT_VD_RAMP_SHIFT,
706 arizona_vol_ramp_text);
707 EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
709 SOC_ENUM_SINGLE_DECL(arizona_out_vi_ramp,
710 ARIZONA_OUTPUT_VOLUME_RAMP,
711 ARIZONA_OUT_VI_RAMP_SHIFT,
712 arizona_vol_ramp_text);
713 EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
715 static const char * const arizona_lhpf_mode_text[] = {
716 "Low-pass", "High-pass"
719 SOC_ENUM_SINGLE_DECL(arizona_lhpf1_mode,
720 ARIZONA_HPLPF1_1,
721 ARIZONA_LHPF1_MODE_SHIFT,
722 arizona_lhpf_mode_text);
723 EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
725 SOC_ENUM_SINGLE_DECL(arizona_lhpf2_mode,
726 ARIZONA_HPLPF2_1,
727 ARIZONA_LHPF2_MODE_SHIFT,
728 arizona_lhpf_mode_text);
729 EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
731 SOC_ENUM_SINGLE_DECL(arizona_lhpf3_mode,
732 ARIZONA_HPLPF3_1,
733 ARIZONA_LHPF3_MODE_SHIFT,
734 arizona_lhpf_mode_text);
735 EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
737 SOC_ENUM_SINGLE_DECL(arizona_lhpf4_mode,
738 ARIZONA_HPLPF4_1,
739 ARIZONA_LHPF4_MODE_SHIFT,
740 arizona_lhpf_mode_text);
741 EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
743 static const char * const arizona_ng_hold_text[] = {
744 "30ms", "120ms", "250ms", "500ms",
747 SOC_ENUM_SINGLE_DECL(arizona_ng_hold,
748 ARIZONA_NOISE_GATE_CONTROL,
749 ARIZONA_NGATE_HOLD_SHIFT,
750 arizona_ng_hold_text);
751 EXPORT_SYMBOL_GPL(arizona_ng_hold);
753 static const char * const arizona_in_hpf_cut_text[] = {
754 "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz"
757 SOC_ENUM_SINGLE_DECL(arizona_in_hpf_cut_enum,
758 ARIZONA_HPF_CONTROL,
759 ARIZONA_IN_HPF_CUT_SHIFT,
760 arizona_in_hpf_cut_text);
761 EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum);
763 static const char * const arizona_in_dmic_osr_text[] = {
764 "1.536MHz", "3.072MHz", "6.144MHz", "768kHz",
767 const struct soc_enum arizona_in_dmic_osr[] = {
768 SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
769 ARRAY_SIZE(arizona_in_dmic_osr_text),
770 arizona_in_dmic_osr_text),
771 SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
772 ARRAY_SIZE(arizona_in_dmic_osr_text),
773 arizona_in_dmic_osr_text),
774 SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
775 ARRAY_SIZE(arizona_in_dmic_osr_text),
776 arizona_in_dmic_osr_text),
777 SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
778 ARRAY_SIZE(arizona_in_dmic_osr_text),
779 arizona_in_dmic_osr_text),
781 EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
783 static const char * const arizona_anc_input_src_text[] = {
784 "None", "IN1", "IN2", "IN3", "IN4",
787 static const char * const arizona_anc_channel_src_text[] = {
788 "None", "Left", "Right", "Combine",
791 const struct soc_enum arizona_anc_input_src[] = {
792 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
793 ARIZONA_IN_RXANCL_SEL_SHIFT,
794 ARRAY_SIZE(arizona_anc_input_src_text),
795 arizona_anc_input_src_text),
796 SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL,
797 ARIZONA_FCL_MIC_MODE_SEL_SHIFT,
798 ARRAY_SIZE(arizona_anc_channel_src_text),
799 arizona_anc_channel_src_text),
800 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
801 ARIZONA_IN_RXANCR_SEL_SHIFT,
802 ARRAY_SIZE(arizona_anc_input_src_text),
803 arizona_anc_input_src_text),
804 SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL,
805 ARIZONA_FCR_MIC_MODE_SEL_SHIFT,
806 ARRAY_SIZE(arizona_anc_channel_src_text),
807 arizona_anc_channel_src_text),
809 EXPORT_SYMBOL_GPL(arizona_anc_input_src);
811 static const char * const arizona_anc_ng_texts[] = {
812 "None",
813 "Internal",
814 "External",
817 SOC_ENUM_SINGLE_DECL(arizona_anc_ng_enum, SND_SOC_NOPM, 0,
818 arizona_anc_ng_texts);
819 EXPORT_SYMBOL_GPL(arizona_anc_ng_enum);
821 static const char * const arizona_output_anc_src_text[] = {
822 "None", "RXANCL", "RXANCR",
825 const struct soc_enum arizona_output_anc_src[] = {
826 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
827 ARIZONA_OUT1L_ANC_SRC_SHIFT,
828 ARRAY_SIZE(arizona_output_anc_src_text),
829 arizona_output_anc_src_text),
830 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1R,
831 ARIZONA_OUT1R_ANC_SRC_SHIFT,
832 ARRAY_SIZE(arizona_output_anc_src_text),
833 arizona_output_anc_src_text),
834 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
835 ARIZONA_OUT2L_ANC_SRC_SHIFT,
836 ARRAY_SIZE(arizona_output_anc_src_text),
837 arizona_output_anc_src_text),
838 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2R,
839 ARIZONA_OUT2R_ANC_SRC_SHIFT,
840 ARRAY_SIZE(arizona_output_anc_src_text),
841 arizona_output_anc_src_text),
842 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
843 ARIZONA_OUT3L_ANC_SRC_SHIFT,
844 ARRAY_SIZE(arizona_output_anc_src_text),
845 arizona_output_anc_src_text),
846 SOC_ENUM_SINGLE(ARIZONA_DAC_VOLUME_LIMIT_3R,
847 ARIZONA_OUT3R_ANC_SRC_SHIFT,
848 ARRAY_SIZE(arizona_output_anc_src_text),
849 arizona_output_anc_src_text),
850 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4L,
851 ARIZONA_OUT4L_ANC_SRC_SHIFT,
852 ARRAY_SIZE(arizona_output_anc_src_text),
853 arizona_output_anc_src_text),
854 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4R,
855 ARIZONA_OUT4R_ANC_SRC_SHIFT,
856 ARRAY_SIZE(arizona_output_anc_src_text),
857 arizona_output_anc_src_text),
858 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5L,
859 ARIZONA_OUT5L_ANC_SRC_SHIFT,
860 ARRAY_SIZE(arizona_output_anc_src_text),
861 arizona_output_anc_src_text),
862 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5R,
863 ARIZONA_OUT5R_ANC_SRC_SHIFT,
864 ARRAY_SIZE(arizona_output_anc_src_text),
865 arizona_output_anc_src_text),
866 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6L,
867 ARIZONA_OUT6L_ANC_SRC_SHIFT,
868 ARRAY_SIZE(arizona_output_anc_src_text),
869 arizona_output_anc_src_text),
870 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6R,
871 ARIZONA_OUT6R_ANC_SRC_SHIFT,
872 ARRAY_SIZE(arizona_output_anc_src_text),
873 arizona_output_anc_src_text),
875 EXPORT_SYMBOL_GPL(arizona_output_anc_src);
877 const struct snd_kcontrol_new arizona_voice_trigger_switch[] = {
878 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0),
879 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 1, 1, 0),
880 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 2, 1, 0),
881 SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 3, 1, 0),
883 EXPORT_SYMBOL_GPL(arizona_voice_trigger_switch);
885 static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
887 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
888 unsigned int val;
889 int i;
891 if (ena)
892 val = ARIZONA_IN_VU;
893 else
894 val = 0;
896 for (i = 0; i < priv->num_inputs; i++)
897 snd_soc_update_bits(codec,
898 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
899 ARIZONA_IN_VU, val);
902 bool arizona_input_analog(struct snd_soc_codec *codec, int shift)
904 unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8);
905 unsigned int val = snd_soc_read(codec, reg);
907 return !(val & ARIZONA_IN1_MODE_MASK);
909 EXPORT_SYMBOL_GPL(arizona_input_analog);
911 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
912 int event)
914 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
915 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
916 unsigned int reg;
918 if (w->shift % 2)
919 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
920 else
921 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
923 switch (event) {
924 case SND_SOC_DAPM_PRE_PMU:
925 priv->in_pending++;
926 break;
927 case SND_SOC_DAPM_POST_PMU:
928 snd_soc_update_bits(codec, reg, ARIZONA_IN1L_MUTE, 0);
930 /* If this is the last input pending then allow VU */
931 priv->in_pending--;
932 if (priv->in_pending == 0) {
933 msleep(1);
934 arizona_in_set_vu(codec, 1);
936 break;
937 case SND_SOC_DAPM_PRE_PMD:
938 snd_soc_update_bits(codec, reg,
939 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
940 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
941 break;
942 case SND_SOC_DAPM_POST_PMD:
943 /* Disable volume updates if no inputs are enabled */
944 reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES);
945 if (reg == 0)
946 arizona_in_set_vu(codec, 0);
947 break;
948 default:
949 break;
952 return 0;
954 EXPORT_SYMBOL_GPL(arizona_in_ev);
956 int arizona_out_ev(struct snd_soc_dapm_widget *w,
957 struct snd_kcontrol *kcontrol,
958 int event)
960 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
961 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
962 struct arizona *arizona = priv->arizona;
964 switch (event) {
965 case SND_SOC_DAPM_PRE_PMU:
966 switch (w->shift) {
967 case ARIZONA_OUT1L_ENA_SHIFT:
968 case ARIZONA_OUT1R_ENA_SHIFT:
969 case ARIZONA_OUT2L_ENA_SHIFT:
970 case ARIZONA_OUT2R_ENA_SHIFT:
971 case ARIZONA_OUT3L_ENA_SHIFT:
972 case ARIZONA_OUT3R_ENA_SHIFT:
973 priv->out_up_pending++;
974 priv->out_up_delay += 17;
975 break;
976 case ARIZONA_OUT4L_ENA_SHIFT:
977 case ARIZONA_OUT4R_ENA_SHIFT:
978 priv->out_up_pending++;
979 switch (arizona->type) {
980 case WM5102:
981 case WM8997:
982 break;
983 default:
984 priv->out_up_delay += 10;
985 break;
987 break;
988 default:
989 break;
991 break;
992 case SND_SOC_DAPM_POST_PMU:
993 switch (w->shift) {
994 case ARIZONA_OUT1L_ENA_SHIFT:
995 case ARIZONA_OUT1R_ENA_SHIFT:
996 case ARIZONA_OUT2L_ENA_SHIFT:
997 case ARIZONA_OUT2R_ENA_SHIFT:
998 case ARIZONA_OUT3L_ENA_SHIFT:
999 case ARIZONA_OUT3R_ENA_SHIFT:
1000 case ARIZONA_OUT4L_ENA_SHIFT:
1001 case ARIZONA_OUT4R_ENA_SHIFT:
1002 priv->out_up_pending--;
1003 if (!priv->out_up_pending && priv->out_up_delay) {
1004 dev_dbg(codec->dev, "Power up delay: %d\n",
1005 priv->out_up_delay);
1006 msleep(priv->out_up_delay);
1007 priv->out_up_delay = 0;
1009 break;
1011 default:
1012 break;
1014 break;
1015 case SND_SOC_DAPM_PRE_PMD:
1016 switch (w->shift) {
1017 case ARIZONA_OUT1L_ENA_SHIFT:
1018 case ARIZONA_OUT1R_ENA_SHIFT:
1019 case ARIZONA_OUT2L_ENA_SHIFT:
1020 case ARIZONA_OUT2R_ENA_SHIFT:
1021 case ARIZONA_OUT3L_ENA_SHIFT:
1022 case ARIZONA_OUT3R_ENA_SHIFT:
1023 priv->out_down_pending++;
1024 priv->out_down_delay++;
1025 break;
1026 case ARIZONA_OUT4L_ENA_SHIFT:
1027 case ARIZONA_OUT4R_ENA_SHIFT:
1028 priv->out_down_pending++;
1029 switch (arizona->type) {
1030 case WM5102:
1031 case WM8997:
1032 break;
1033 case WM8998:
1034 case WM1814:
1035 priv->out_down_delay += 5;
1036 break;
1037 default:
1038 priv->out_down_delay++;
1039 break;
1041 default:
1042 break;
1044 break;
1045 case SND_SOC_DAPM_POST_PMD:
1046 switch (w->shift) {
1047 case ARIZONA_OUT1L_ENA_SHIFT:
1048 case ARIZONA_OUT1R_ENA_SHIFT:
1049 case ARIZONA_OUT2L_ENA_SHIFT:
1050 case ARIZONA_OUT2R_ENA_SHIFT:
1051 case ARIZONA_OUT3L_ENA_SHIFT:
1052 case ARIZONA_OUT3R_ENA_SHIFT:
1053 case ARIZONA_OUT4L_ENA_SHIFT:
1054 case ARIZONA_OUT4R_ENA_SHIFT:
1055 priv->out_down_pending--;
1056 if (!priv->out_down_pending && priv->out_down_delay) {
1057 dev_dbg(codec->dev, "Power down delay: %d\n",
1058 priv->out_down_delay);
1059 msleep(priv->out_down_delay);
1060 priv->out_down_delay = 0;
1062 break;
1063 default:
1064 break;
1066 break;
1067 default:
1068 break;
1071 return 0;
1073 EXPORT_SYMBOL_GPL(arizona_out_ev);
1075 int arizona_hp_ev(struct snd_soc_dapm_widget *w,
1076 struct snd_kcontrol *kcontrol,
1077 int event)
1079 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1080 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1081 struct arizona *arizona = priv->arizona;
1082 unsigned int mask = 1 << w->shift;
1083 unsigned int val;
1085 switch (event) {
1086 case SND_SOC_DAPM_POST_PMU:
1087 val = mask;
1088 break;
1089 case SND_SOC_DAPM_PRE_PMD:
1090 val = 0;
1091 break;
1092 case SND_SOC_DAPM_PRE_PMU:
1093 case SND_SOC_DAPM_POST_PMD:
1094 return arizona_out_ev(w, kcontrol, event);
1095 default:
1096 return -EINVAL;
1099 /* Store the desired state for the HP outputs */
1100 priv->arizona->hp_ena &= ~mask;
1101 priv->arizona->hp_ena |= val;
1103 /* Force off if HPDET clamp is active */
1104 if (priv->arizona->hpdet_clamp)
1105 val = 0;
1107 regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
1108 mask, val);
1110 return arizona_out_ev(w, kcontrol, event);
1112 EXPORT_SYMBOL_GPL(arizona_hp_ev);
1114 static int arizona_dvfs_enable(struct snd_soc_codec *codec)
1116 const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1117 struct arizona *arizona = priv->arizona;
1118 int ret;
1120 ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
1121 if (ret) {
1122 dev_err(codec->dev, "Failed to boost DCVDD: %d\n", ret);
1123 return ret;
1126 ret = regmap_update_bits(arizona->regmap,
1127 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1128 ARIZONA_SUBSYS_MAX_FREQ,
1129 ARIZONA_SUBSYS_MAX_FREQ);
1130 if (ret) {
1131 dev_err(codec->dev, "Failed to enable subsys max: %d\n", ret);
1132 regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1133 return ret;
1136 return 0;
1139 static int arizona_dvfs_disable(struct snd_soc_codec *codec)
1141 const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1142 struct arizona *arizona = priv->arizona;
1143 int ret;
1145 ret = regmap_update_bits(arizona->regmap,
1146 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1147 ARIZONA_SUBSYS_MAX_FREQ, 0);
1148 if (ret) {
1149 dev_err(codec->dev, "Failed to disable subsys max: %d\n", ret);
1150 return ret;
1153 ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1154 if (ret) {
1155 dev_err(codec->dev, "Failed to unboost DCVDD: %d\n", ret);
1156 return ret;
1159 return 0;
1162 int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags)
1164 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1165 int ret = 0;
1167 mutex_lock(&priv->dvfs_lock);
1169 if (!priv->dvfs_cached && !priv->dvfs_reqs) {
1170 ret = arizona_dvfs_enable(codec);
1171 if (ret)
1172 goto err;
1175 priv->dvfs_reqs |= flags;
1176 err:
1177 mutex_unlock(&priv->dvfs_lock);
1178 return ret;
1180 EXPORT_SYMBOL_GPL(arizona_dvfs_up);
1182 int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags)
1184 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1185 unsigned int old_reqs;
1186 int ret = 0;
1188 mutex_lock(&priv->dvfs_lock);
1190 old_reqs = priv->dvfs_reqs;
1191 priv->dvfs_reqs &= ~flags;
1193 if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
1194 ret = arizona_dvfs_disable(codec);
1196 mutex_unlock(&priv->dvfs_lock);
1197 return ret;
1199 EXPORT_SYMBOL_GPL(arizona_dvfs_down);
1201 int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
1202 struct snd_kcontrol *kcontrol, int event)
1204 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1205 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1206 int ret = 0;
1208 mutex_lock(&priv->dvfs_lock);
1210 switch (event) {
1211 case SND_SOC_DAPM_POST_PMU:
1212 if (priv->dvfs_reqs)
1213 ret = arizona_dvfs_enable(codec);
1215 priv->dvfs_cached = false;
1216 break;
1217 case SND_SOC_DAPM_PRE_PMD:
1218 /* We must ensure DVFS is disabled before the codec goes into
1219 * suspend so that we are never in an illegal state of DVFS
1220 * enabled without enough DCVDD
1222 priv->dvfs_cached = true;
1224 if (priv->dvfs_reqs)
1225 ret = arizona_dvfs_disable(codec);
1226 break;
1227 default:
1228 break;
1231 mutex_unlock(&priv->dvfs_lock);
1232 return ret;
1234 EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
1236 void arizona_init_dvfs(struct arizona_priv *priv)
1238 mutex_init(&priv->dvfs_lock);
1240 EXPORT_SYMBOL_GPL(arizona_init_dvfs);
1242 int arizona_anc_ev(struct snd_soc_dapm_widget *w,
1243 struct snd_kcontrol *kcontrol,
1244 int event)
1246 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1247 unsigned int val;
1249 switch (event) {
1250 case SND_SOC_DAPM_POST_PMU:
1251 val = 1 << w->shift;
1252 break;
1253 case SND_SOC_DAPM_PRE_PMD:
1254 val = 1 << (w->shift + 1);
1255 break;
1256 default:
1257 return 0;
1260 snd_soc_write(codec, ARIZONA_CLOCK_CONTROL, val);
1262 return 0;
1264 EXPORT_SYMBOL_GPL(arizona_anc_ev);
1266 static unsigned int arizona_opclk_ref_48k_rates[] = {
1267 6144000,
1268 12288000,
1269 24576000,
1270 49152000,
1273 static unsigned int arizona_opclk_ref_44k1_rates[] = {
1274 5644800,
1275 11289600,
1276 22579200,
1277 45158400,
1280 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
1281 unsigned int freq)
1283 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1284 unsigned int reg;
1285 unsigned int *rates;
1286 int ref, div, refclk;
1288 switch (clk) {
1289 case ARIZONA_CLK_OPCLK:
1290 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
1291 refclk = priv->sysclk;
1292 break;
1293 case ARIZONA_CLK_ASYNC_OPCLK:
1294 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
1295 refclk = priv->asyncclk;
1296 break;
1297 default:
1298 return -EINVAL;
1301 if (refclk % 8000)
1302 rates = arizona_opclk_ref_44k1_rates;
1303 else
1304 rates = arizona_opclk_ref_48k_rates;
1306 for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
1307 rates[ref] <= refclk; ref++) {
1308 div = 1;
1309 while (rates[ref] / div >= freq && div < 32) {
1310 if (rates[ref] / div == freq) {
1311 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
1312 freq);
1313 snd_soc_update_bits(codec, reg,
1314 ARIZONA_OPCLK_DIV_MASK |
1315 ARIZONA_OPCLK_SEL_MASK,
1316 (div <<
1317 ARIZONA_OPCLK_DIV_SHIFT) |
1318 ref);
1319 return 0;
1321 div++;
1325 dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
1326 return -EINVAL;
1329 int arizona_clk_ev(struct snd_soc_dapm_widget *w,
1330 struct snd_kcontrol *kcontrol, int event)
1332 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1333 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
1334 unsigned int val;
1335 int clk_idx;
1336 int ret;
1338 ret = regmap_read(arizona->regmap, w->reg, &val);
1339 if (ret) {
1340 dev_err(codec->dev, "Failed to check clock source: %d\n", ret);
1341 return ret;
1344 val = (val & ARIZONA_SYSCLK_SRC_MASK) >> ARIZONA_SYSCLK_SRC_SHIFT;
1346 switch (val) {
1347 case ARIZONA_CLK_SRC_MCLK1:
1348 clk_idx = ARIZONA_MCLK1;
1349 break;
1350 case ARIZONA_CLK_SRC_MCLK2:
1351 clk_idx = ARIZONA_MCLK2;
1352 break;
1353 default:
1354 return 0;
1357 switch (event) {
1358 case SND_SOC_DAPM_PRE_PMU:
1359 return clk_prepare_enable(arizona->mclk[clk_idx]);
1360 case SND_SOC_DAPM_POST_PMD:
1361 clk_disable_unprepare(arizona->mclk[clk_idx]);
1362 return 0;
1363 default:
1364 return 0;
1367 EXPORT_SYMBOL_GPL(arizona_clk_ev);
1369 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1370 int source, unsigned int freq, int dir)
1372 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1373 struct arizona *arizona = priv->arizona;
1374 char *name;
1375 unsigned int reg;
1376 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
1377 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
1378 int *clk;
1380 switch (clk_id) {
1381 case ARIZONA_CLK_SYSCLK:
1382 name = "SYSCLK";
1383 reg = ARIZONA_SYSTEM_CLOCK_1;
1384 clk = &priv->sysclk;
1385 mask |= ARIZONA_SYSCLK_FRAC;
1386 break;
1387 case ARIZONA_CLK_ASYNCCLK:
1388 name = "ASYNCCLK";
1389 reg = ARIZONA_ASYNC_CLOCK_1;
1390 clk = &priv->asyncclk;
1391 break;
1392 case ARIZONA_CLK_OPCLK:
1393 case ARIZONA_CLK_ASYNC_OPCLK:
1394 return arizona_set_opclk(codec, clk_id, freq);
1395 default:
1396 return -EINVAL;
1399 switch (freq) {
1400 case 5644800:
1401 case 6144000:
1402 break;
1403 case 11289600:
1404 case 12288000:
1405 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1406 break;
1407 case 22579200:
1408 case 24576000:
1409 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1410 break;
1411 case 45158400:
1412 case 49152000:
1413 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1414 break;
1415 case 67737600:
1416 case 73728000:
1417 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1418 break;
1419 case 90316800:
1420 case 98304000:
1421 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1422 break;
1423 case 135475200:
1424 case 147456000:
1425 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1426 break;
1427 case 0:
1428 dev_dbg(arizona->dev, "%s cleared\n", name);
1429 *clk = freq;
1430 return 0;
1431 default:
1432 return -EINVAL;
1435 *clk = freq;
1437 if (freq % 6144000)
1438 val |= ARIZONA_SYSCLK_FRAC;
1440 dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
1442 return regmap_update_bits(arizona->regmap, reg, mask, val);
1444 EXPORT_SYMBOL_GPL(arizona_set_sysclk);
1446 static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1448 struct snd_soc_codec *codec = dai->codec;
1449 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1450 struct arizona *arizona = priv->arizona;
1451 int lrclk, bclk, mode, base;
1453 base = dai->driver->base;
1455 lrclk = 0;
1456 bclk = 0;
1458 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1459 case SND_SOC_DAIFMT_DSP_A:
1460 mode = ARIZONA_FMT_DSP_MODE_A;
1461 break;
1462 case SND_SOC_DAIFMT_DSP_B:
1463 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1464 != SND_SOC_DAIFMT_CBM_CFM) {
1465 arizona_aif_err(dai, "DSP_B not valid in slave mode\n");
1466 return -EINVAL;
1468 mode = ARIZONA_FMT_DSP_MODE_B;
1469 break;
1470 case SND_SOC_DAIFMT_I2S:
1471 mode = ARIZONA_FMT_I2S_MODE;
1472 break;
1473 case SND_SOC_DAIFMT_LEFT_J:
1474 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK)
1475 != SND_SOC_DAIFMT_CBM_CFM) {
1476 arizona_aif_err(dai, "LEFT_J not valid in slave mode\n");
1477 return -EINVAL;
1479 mode = ARIZONA_FMT_LEFT_JUSTIFIED_MODE;
1480 break;
1481 default:
1482 arizona_aif_err(dai, "Unsupported DAI format %d\n",
1483 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1484 return -EINVAL;
1487 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1488 case SND_SOC_DAIFMT_CBS_CFS:
1489 break;
1490 case SND_SOC_DAIFMT_CBS_CFM:
1491 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1492 break;
1493 case SND_SOC_DAIFMT_CBM_CFS:
1494 bclk |= ARIZONA_AIF1_BCLK_MSTR;
1495 break;
1496 case SND_SOC_DAIFMT_CBM_CFM:
1497 bclk |= ARIZONA_AIF1_BCLK_MSTR;
1498 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1499 break;
1500 default:
1501 arizona_aif_err(dai, "Unsupported master mode %d\n",
1502 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1503 return -EINVAL;
1506 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1507 case SND_SOC_DAIFMT_NB_NF:
1508 break;
1509 case SND_SOC_DAIFMT_IB_IF:
1510 bclk |= ARIZONA_AIF1_BCLK_INV;
1511 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1512 break;
1513 case SND_SOC_DAIFMT_IB_NF:
1514 bclk |= ARIZONA_AIF1_BCLK_INV;
1515 break;
1516 case SND_SOC_DAIFMT_NB_IF:
1517 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1518 break;
1519 default:
1520 return -EINVAL;
1523 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
1524 ARIZONA_AIF1_BCLK_INV |
1525 ARIZONA_AIF1_BCLK_MSTR,
1526 bclk);
1527 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL,
1528 ARIZONA_AIF1TX_LRCLK_INV |
1529 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
1530 regmap_update_bits_async(arizona->regmap,
1531 base + ARIZONA_AIF_RX_PIN_CTRL,
1532 ARIZONA_AIF1RX_LRCLK_INV |
1533 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
1534 regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT,
1535 ARIZONA_AIF1_FMT_MASK, mode);
1537 return 0;
1540 static const int arizona_48k_bclk_rates[] = {
1542 48000,
1543 64000,
1544 96000,
1545 128000,
1546 192000,
1547 256000,
1548 384000,
1549 512000,
1550 768000,
1551 1024000,
1552 1536000,
1553 2048000,
1554 3072000,
1555 4096000,
1556 6144000,
1557 8192000,
1558 12288000,
1559 24576000,
1562 static const int arizona_44k1_bclk_rates[] = {
1564 44100,
1565 58800,
1566 88200,
1567 117600,
1568 177640,
1569 235200,
1570 352800,
1571 470400,
1572 705600,
1573 940800,
1574 1411200,
1575 1881600,
1576 2822400,
1577 3763200,
1578 5644800,
1579 7526400,
1580 11289600,
1581 22579200,
1584 static const unsigned int arizona_sr_vals[] = {
1586 12000,
1587 24000,
1588 48000,
1589 96000,
1590 192000,
1591 384000,
1592 768000,
1594 11025,
1595 22050,
1596 44100,
1597 88200,
1598 176400,
1599 352800,
1600 705600,
1601 4000,
1602 8000,
1603 16000,
1604 32000,
1605 64000,
1606 128000,
1607 256000,
1608 512000,
1611 #define ARIZONA_48K_RATE_MASK 0x0F003E
1612 #define ARIZONA_44K1_RATE_MASK 0x003E00
1613 #define ARIZONA_RATE_MASK (ARIZONA_48K_RATE_MASK | ARIZONA_44K1_RATE_MASK)
1615 static const struct snd_pcm_hw_constraint_list arizona_constraint = {
1616 .count = ARRAY_SIZE(arizona_sr_vals),
1617 .list = arizona_sr_vals,
1620 static int arizona_startup(struct snd_pcm_substream *substream,
1621 struct snd_soc_dai *dai)
1623 struct snd_soc_codec *codec = dai->codec;
1624 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1625 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1626 unsigned int base_rate;
1628 if (!substream->runtime)
1629 return 0;
1631 switch (dai_priv->clk) {
1632 case ARIZONA_CLK_SYSCLK:
1633 base_rate = priv->sysclk;
1634 break;
1635 case ARIZONA_CLK_ASYNCCLK:
1636 base_rate = priv->asyncclk;
1637 break;
1638 default:
1639 return 0;
1642 if (base_rate == 0)
1643 dai_priv->constraint.mask = ARIZONA_RATE_MASK;
1644 else if (base_rate % 8000)
1645 dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK;
1646 else
1647 dai_priv->constraint.mask = ARIZONA_48K_RATE_MASK;
1649 return snd_pcm_hw_constraint_list(substream->runtime, 0,
1650 SNDRV_PCM_HW_PARAM_RATE,
1651 &dai_priv->constraint);
1654 static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec,
1655 unsigned int rate)
1657 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1658 struct arizona *arizona = priv->arizona;
1659 struct reg_sequence dac_comp[] = {
1660 { 0x80, 0x3 },
1661 { ARIZONA_DAC_COMP_1, 0 },
1662 { ARIZONA_DAC_COMP_2, 0 },
1663 { 0x80, 0x0 },
1666 mutex_lock(&arizona->dac_comp_lock);
1668 dac_comp[1].def = arizona->dac_comp_coeff;
1669 if (rate >= 176400)
1670 dac_comp[2].def = arizona->dac_comp_enabled;
1672 mutex_unlock(&arizona->dac_comp_lock);
1674 regmap_multi_reg_write(arizona->regmap,
1675 dac_comp,
1676 ARRAY_SIZE(dac_comp));
1679 static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
1680 struct snd_pcm_hw_params *params,
1681 struct snd_soc_dai *dai)
1683 struct snd_soc_codec *codec = dai->codec;
1684 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1685 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1686 int base = dai->driver->base;
1687 int i, sr_val, ret;
1690 * We will need to be more flexible than this in future,
1691 * currently we use a single sample rate for SYSCLK.
1693 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
1694 if (arizona_sr_vals[i] == params_rate(params))
1695 break;
1696 if (i == ARRAY_SIZE(arizona_sr_vals)) {
1697 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1698 params_rate(params));
1699 return -EINVAL;
1701 sr_val = i;
1703 switch (priv->arizona->type) {
1704 case WM5102:
1705 case WM8997:
1706 if (arizona_sr_vals[sr_val] >= 88200)
1707 ret = arizona_dvfs_up(codec, ARIZONA_DVFS_SR1_RQ);
1708 else
1709 ret = arizona_dvfs_down(codec, ARIZONA_DVFS_SR1_RQ);
1711 if (ret) {
1712 arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
1713 return ret;
1715 break;
1716 default:
1717 break;
1720 switch (dai_priv->clk) {
1721 case ARIZONA_CLK_SYSCLK:
1722 switch (priv->arizona->type) {
1723 case WM5102:
1724 arizona_wm5102_set_dac_comp(codec,
1725 params_rate(params));
1726 break;
1727 default:
1728 break;
1731 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
1732 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
1733 if (base)
1734 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1735 ARIZONA_AIF1_RATE_MASK, 0);
1736 break;
1737 case ARIZONA_CLK_ASYNCCLK:
1738 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
1739 ARIZONA_ASYNC_SAMPLE_RATE_1_MASK, sr_val);
1740 if (base)
1741 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1742 ARIZONA_AIF1_RATE_MASK,
1743 8 << ARIZONA_AIF1_RATE_SHIFT);
1744 break;
1745 default:
1746 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1747 return -EINVAL;
1750 return 0;
1753 static bool arizona_aif_cfg_changed(struct snd_soc_codec *codec,
1754 int base, int bclk, int lrclk, int frame)
1756 int val;
1758 val = snd_soc_read(codec, base + ARIZONA_AIF_BCLK_CTRL);
1759 if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
1760 return true;
1762 val = snd_soc_read(codec, base + ARIZONA_AIF_TX_BCLK_RATE);
1763 if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
1764 return true;
1766 val = snd_soc_read(codec, base + ARIZONA_AIF_FRAME_CTRL_1);
1767 if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
1768 ARIZONA_AIF1TX_SLOT_LEN_MASK)))
1769 return true;
1771 return false;
1774 static int arizona_hw_params(struct snd_pcm_substream *substream,
1775 struct snd_pcm_hw_params *params,
1776 struct snd_soc_dai *dai)
1778 struct snd_soc_codec *codec = dai->codec;
1779 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1780 struct arizona *arizona = priv->arizona;
1781 int base = dai->driver->base;
1782 const int *rates;
1783 int i, ret, val;
1784 int channels = params_channels(params);
1785 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
1786 int tdm_width = arizona->tdm_width[dai->id - 1];
1787 int tdm_slots = arizona->tdm_slots[dai->id - 1];
1788 int bclk, lrclk, wl, frame, bclk_target;
1789 bool reconfig;
1790 unsigned int aif_tx_state, aif_rx_state;
1792 if (params_rate(params) % 4000)
1793 rates = &arizona_44k1_bclk_rates[0];
1794 else
1795 rates = &arizona_48k_bclk_rates[0];
1797 wl = params_width(params);
1799 if (tdm_slots) {
1800 arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
1801 tdm_slots, tdm_width);
1802 bclk_target = tdm_slots * tdm_width * params_rate(params);
1803 channels = tdm_slots;
1804 } else {
1805 bclk_target = snd_soc_params_to_bclk(params);
1806 tdm_width = wl;
1809 if (chan_limit && chan_limit < channels) {
1810 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
1811 bclk_target /= channels;
1812 bclk_target *= chan_limit;
1815 /* Force multiple of 2 channels for I2S mode */
1816 val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
1817 val &= ARIZONA_AIF1_FMT_MASK;
1818 if ((channels & 1) && (val == ARIZONA_FMT_I2S_MODE)) {
1819 arizona_aif_dbg(dai, "Forcing stereo mode\n");
1820 bclk_target /= channels;
1821 bclk_target *= channels + 1;
1824 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
1825 if (rates[i] >= bclk_target &&
1826 rates[i] % params_rate(params) == 0) {
1827 bclk = i;
1828 break;
1831 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1832 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1833 params_rate(params));
1834 return -EINVAL;
1837 lrclk = rates[bclk] / params_rate(params);
1839 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
1840 rates[bclk], rates[bclk] / lrclk);
1842 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width;
1844 reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame);
1846 if (reconfig) {
1847 /* Save AIF TX/RX state */
1848 aif_tx_state = snd_soc_read(codec,
1849 base + ARIZONA_AIF_TX_ENABLES);
1850 aif_rx_state = snd_soc_read(codec,
1851 base + ARIZONA_AIF_RX_ENABLES);
1852 /* Disable AIF TX/RX before reconfiguring it */
1853 regmap_update_bits_async(arizona->regmap,
1854 base + ARIZONA_AIF_TX_ENABLES, 0xff, 0x0);
1855 regmap_update_bits(arizona->regmap,
1856 base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
1859 ret = arizona_hw_params_rate(substream, params, dai);
1860 if (ret != 0)
1861 goto restore_aif;
1863 if (reconfig) {
1864 regmap_update_bits_async(arizona->regmap,
1865 base + ARIZONA_AIF_BCLK_CTRL,
1866 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
1867 regmap_update_bits_async(arizona->regmap,
1868 base + ARIZONA_AIF_TX_BCLK_RATE,
1869 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
1870 regmap_update_bits_async(arizona->regmap,
1871 base + ARIZONA_AIF_RX_BCLK_RATE,
1872 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
1873 regmap_update_bits_async(arizona->regmap,
1874 base + ARIZONA_AIF_FRAME_CTRL_1,
1875 ARIZONA_AIF1TX_WL_MASK |
1876 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
1877 regmap_update_bits(arizona->regmap,
1878 base + ARIZONA_AIF_FRAME_CTRL_2,
1879 ARIZONA_AIF1RX_WL_MASK |
1880 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
1883 restore_aif:
1884 if (reconfig) {
1885 /* Restore AIF TX/RX state */
1886 regmap_update_bits_async(arizona->regmap,
1887 base + ARIZONA_AIF_TX_ENABLES,
1888 0xff, aif_tx_state);
1889 regmap_update_bits(arizona->regmap,
1890 base + ARIZONA_AIF_RX_ENABLES,
1891 0xff, aif_rx_state);
1893 return ret;
1896 static const char *arizona_dai_clk_str(int clk_id)
1898 switch (clk_id) {
1899 case ARIZONA_CLK_SYSCLK:
1900 return "SYSCLK";
1901 case ARIZONA_CLK_ASYNCCLK:
1902 return "ASYNCCLK";
1903 default:
1904 return "Unknown clock";
1908 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
1909 int clk_id, unsigned int freq, int dir)
1911 struct snd_soc_codec *codec = dai->codec;
1912 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1913 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1914 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1915 struct snd_soc_dapm_route routes[2];
1917 switch (clk_id) {
1918 case ARIZONA_CLK_SYSCLK:
1919 case ARIZONA_CLK_ASYNCCLK:
1920 break;
1921 default:
1922 return -EINVAL;
1925 if (clk_id == dai_priv->clk)
1926 return 0;
1928 if (dai->active) {
1929 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
1930 dai->id);
1931 return -EBUSY;
1934 dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
1935 arizona_dai_clk_str(clk_id));
1937 memset(&routes, 0, sizeof(routes));
1938 routes[0].sink = dai->driver->capture.stream_name;
1939 routes[1].sink = dai->driver->playback.stream_name;
1941 routes[0].source = arizona_dai_clk_str(dai_priv->clk);
1942 routes[1].source = arizona_dai_clk_str(dai_priv->clk);
1943 snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
1945 routes[0].source = arizona_dai_clk_str(clk_id);
1946 routes[1].source = arizona_dai_clk_str(clk_id);
1947 snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
1949 dai_priv->clk = clk_id;
1951 return snd_soc_dapm_sync(dapm);
1954 static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
1956 struct snd_soc_codec *codec = dai->codec;
1957 int base = dai->driver->base;
1958 unsigned int reg;
1960 if (tristate)
1961 reg = ARIZONA_AIF1_TRI;
1962 else
1963 reg = 0;
1965 return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1966 ARIZONA_AIF1_TRI, reg);
1969 static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
1970 unsigned int base,
1971 int channels, unsigned int mask)
1973 struct snd_soc_codec *codec = dai->codec;
1974 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1975 struct arizona *arizona = priv->arizona;
1976 int slot, i;
1978 for (i = 0; i < channels; ++i) {
1979 slot = ffs(mask) - 1;
1980 if (slot < 0)
1981 return;
1983 regmap_write(arizona->regmap, base + i, slot);
1985 mask &= ~(1 << slot);
1988 if (mask)
1989 arizona_aif_warn(dai, "Too many channels in TDM mask\n");
1992 static int arizona_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1993 unsigned int rx_mask, int slots, int slot_width)
1995 struct snd_soc_codec *codec = dai->codec;
1996 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1997 struct arizona *arizona = priv->arizona;
1998 int base = dai->driver->base;
1999 int rx_max_chan = dai->driver->playback.channels_max;
2000 int tx_max_chan = dai->driver->capture.channels_max;
2002 /* Only support TDM for the physical AIFs */
2003 if (dai->id > ARIZONA_MAX_AIF)
2004 return -ENOTSUPP;
2006 if (slots == 0) {
2007 tx_mask = (1 << tx_max_chan) - 1;
2008 rx_mask = (1 << rx_max_chan) - 1;
2011 arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3,
2012 tx_max_chan, tx_mask);
2013 arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11,
2014 rx_max_chan, rx_mask);
2016 arizona->tdm_width[dai->id - 1] = slot_width;
2017 arizona->tdm_slots[dai->id - 1] = slots;
2019 return 0;
2022 const struct snd_soc_dai_ops arizona_dai_ops = {
2023 .startup = arizona_startup,
2024 .set_fmt = arizona_set_fmt,
2025 .set_tdm_slot = arizona_set_tdm_slot,
2026 .hw_params = arizona_hw_params,
2027 .set_sysclk = arizona_dai_set_sysclk,
2028 .set_tristate = arizona_set_tristate,
2030 EXPORT_SYMBOL_GPL(arizona_dai_ops);
2032 const struct snd_soc_dai_ops arizona_simple_dai_ops = {
2033 .startup = arizona_startup,
2034 .hw_params = arizona_hw_params_rate,
2035 .set_sysclk = arizona_dai_set_sysclk,
2037 EXPORT_SYMBOL_GPL(arizona_simple_dai_ops);
2039 int arizona_init_dai(struct arizona_priv *priv, int id)
2041 struct arizona_dai_priv *dai_priv = &priv->dai[id];
2043 dai_priv->clk = ARIZONA_CLK_SYSCLK;
2044 dai_priv->constraint = arizona_constraint;
2046 return 0;
2048 EXPORT_SYMBOL_GPL(arizona_init_dai);
2050 static struct {
2051 unsigned int min;
2052 unsigned int max;
2053 u16 fratio;
2054 int ratio;
2055 } fll_fratios[] = {
2056 { 0, 64000, 4, 16 },
2057 { 64000, 128000, 3, 8 },
2058 { 128000, 256000, 2, 4 },
2059 { 256000, 1000000, 1, 2 },
2060 { 1000000, 13500000, 0, 1 },
2063 static const unsigned int pseudo_fref_max[ARIZONA_FLL_MAX_FRATIO] = {
2064 13500000,
2065 6144000,
2066 6144000,
2067 3072000,
2068 3072000,
2069 2822400,
2070 2822400,
2071 1536000,
2072 1536000,
2073 1536000,
2074 1536000,
2075 1536000,
2076 1536000,
2077 1536000,
2078 1536000,
2079 768000,
2082 static struct {
2083 unsigned int min;
2084 unsigned int max;
2085 u16 gain;
2086 } fll_gains[] = {
2087 { 0, 256000, 0 },
2088 { 256000, 1000000, 2 },
2089 { 1000000, 13500000, 4 },
2092 struct arizona_fll_cfg {
2093 int n;
2094 unsigned int theta;
2095 unsigned int lambda;
2096 int refdiv;
2097 int outdiv;
2098 int fratio;
2099 int gain;
2102 static int arizona_validate_fll(struct arizona_fll *fll,
2103 unsigned int Fref,
2104 unsigned int Fout)
2106 unsigned int Fvco_min;
2108 if (fll->fout && Fout != fll->fout) {
2109 arizona_fll_err(fll,
2110 "Can't change output on active FLL\n");
2111 return -EINVAL;
2114 if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
2115 arizona_fll_err(fll,
2116 "Can't scale %dMHz in to <=13.5MHz\n",
2117 Fref);
2118 return -EINVAL;
2121 Fvco_min = ARIZONA_FLL_MIN_FVCO * fll->vco_mult;
2122 if (Fout * ARIZONA_FLL_MAX_OUTDIV < Fvco_min) {
2123 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
2124 Fout);
2125 return -EINVAL;
2128 return 0;
2131 static int arizona_find_fratio(unsigned int Fref, int *fratio)
2133 int i;
2135 /* Find an appropriate FLL_FRATIO */
2136 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
2137 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
2138 if (fratio)
2139 *fratio = fll_fratios[i].fratio;
2140 return fll_fratios[i].ratio;
2144 return -EINVAL;
2147 static int arizona_calc_fratio(struct arizona_fll *fll,
2148 struct arizona_fll_cfg *cfg,
2149 unsigned int target,
2150 unsigned int Fref, bool sync)
2152 int init_ratio, ratio;
2153 int refdiv, div;
2155 /* Fref must be <=13.5MHz, find initial refdiv */
2156 div = 1;
2157 cfg->refdiv = 0;
2158 while (Fref > ARIZONA_FLL_MAX_FREF) {
2159 div *= 2;
2160 Fref /= 2;
2161 cfg->refdiv++;
2163 if (div > ARIZONA_FLL_MAX_REFDIV)
2164 return -EINVAL;
2167 /* Find an appropriate FLL_FRATIO */
2168 init_ratio = arizona_find_fratio(Fref, &cfg->fratio);
2169 if (init_ratio < 0) {
2170 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
2171 Fref);
2172 return init_ratio;
2175 switch (fll->arizona->type) {
2176 case WM5102:
2177 case WM8997:
2178 return init_ratio;
2179 case WM5110:
2180 case WM8280:
2181 if (fll->arizona->rev < 3 || sync)
2182 return init_ratio;
2183 break;
2184 default:
2185 if (sync)
2186 return init_ratio;
2187 break;
2190 cfg->fratio = init_ratio - 1;
2192 /* Adjust FRATIO/refdiv to avoid integer mode if possible */
2193 refdiv = cfg->refdiv;
2195 arizona_fll_dbg(fll, "pseudo: initial ratio=%u fref=%u refdiv=%u\n",
2196 init_ratio, Fref, refdiv);
2198 while (div <= ARIZONA_FLL_MAX_REFDIV) {
2199 /* start from init_ratio because this may already give a
2200 * fractional N.K
2202 for (ratio = init_ratio; ratio > 0; ratio--) {
2203 if (target % (ratio * Fref)) {
2204 cfg->refdiv = refdiv;
2205 cfg->fratio = ratio - 1;
2206 arizona_fll_dbg(fll,
2207 "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2208 Fref, refdiv, div, ratio);
2209 return ratio;
2213 for (ratio = init_ratio + 1; ratio <= ARIZONA_FLL_MAX_FRATIO;
2214 ratio++) {
2215 if ((ARIZONA_FLL_VCO_CORNER / 2) /
2216 (fll->vco_mult * ratio) < Fref) {
2217 arizona_fll_dbg(fll, "pseudo: hit VCO corner\n");
2218 break;
2221 if (Fref > pseudo_fref_max[ratio - 1]) {
2222 arizona_fll_dbg(fll,
2223 "pseudo: exceeded max fref(%u) for ratio=%u\n",
2224 pseudo_fref_max[ratio - 1],
2225 ratio);
2226 break;
2229 if (target % (ratio * Fref)) {
2230 cfg->refdiv = refdiv;
2231 cfg->fratio = ratio - 1;
2232 arizona_fll_dbg(fll,
2233 "pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
2234 Fref, refdiv, div, ratio);
2235 return ratio;
2239 div *= 2;
2240 Fref /= 2;
2241 refdiv++;
2242 init_ratio = arizona_find_fratio(Fref, NULL);
2243 arizona_fll_dbg(fll,
2244 "pseudo: change fref=%u refdiv=%d(%d) ratio=%u\n",
2245 Fref, refdiv, div, init_ratio);
2248 arizona_fll_warn(fll, "Falling back to integer mode operation\n");
2249 return cfg->fratio + 1;
2252 static int arizona_calc_fll(struct arizona_fll *fll,
2253 struct arizona_fll_cfg *cfg,
2254 unsigned int Fref, bool sync)
2256 unsigned int target, div, gcd_fll;
2257 int i, ratio;
2259 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, fll->fout);
2261 /* Fvco should be over the targt; don't check the upper bound */
2262 div = ARIZONA_FLL_MIN_OUTDIV;
2263 while (fll->fout * div < ARIZONA_FLL_MIN_FVCO * fll->vco_mult) {
2264 div++;
2265 if (div > ARIZONA_FLL_MAX_OUTDIV)
2266 return -EINVAL;
2268 target = fll->fout * div / fll->vco_mult;
2269 cfg->outdiv = div;
2271 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
2273 /* Find an appropriate FLL_FRATIO and refdiv */
2274 ratio = arizona_calc_fratio(fll, cfg, target, Fref, sync);
2275 if (ratio < 0)
2276 return ratio;
2278 /* Apply the division for our remaining calculations */
2279 Fref = Fref / (1 << cfg->refdiv);
2281 cfg->n = target / (ratio * Fref);
2283 if (target % (ratio * Fref)) {
2284 gcd_fll = gcd(target, ratio * Fref);
2285 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
2287 cfg->theta = (target - (cfg->n * ratio * Fref))
2288 / gcd_fll;
2289 cfg->lambda = (ratio * Fref) / gcd_fll;
2290 } else {
2291 cfg->theta = 0;
2292 cfg->lambda = 0;
2295 /* Round down to 16bit range with cost of accuracy lost.
2296 * Denominator must be bigger than numerator so we only
2297 * take care of it.
2299 while (cfg->lambda >= (1 << 16)) {
2300 cfg->theta >>= 1;
2301 cfg->lambda >>= 1;
2304 for (i = 0; i < ARRAY_SIZE(fll_gains); i++) {
2305 if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) {
2306 cfg->gain = fll_gains[i].gain;
2307 break;
2310 if (i == ARRAY_SIZE(fll_gains)) {
2311 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
2312 Fref);
2313 return -EINVAL;
2316 arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
2317 cfg->n, cfg->theta, cfg->lambda);
2318 arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n",
2319 cfg->fratio, ratio, cfg->outdiv,
2320 cfg->refdiv, 1 << cfg->refdiv);
2321 arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
2323 return 0;
2327 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
2328 struct arizona_fll_cfg *cfg, int source,
2329 bool sync)
2331 regmap_update_bits_async(arizona->regmap, base + 3,
2332 ARIZONA_FLL1_THETA_MASK, cfg->theta);
2333 regmap_update_bits_async(arizona->regmap, base + 4,
2334 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
2335 regmap_update_bits_async(arizona->regmap, base + 5,
2336 ARIZONA_FLL1_FRATIO_MASK,
2337 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
2338 regmap_update_bits_async(arizona->regmap, base + 6,
2339 ARIZONA_FLL1_CLK_REF_DIV_MASK |
2340 ARIZONA_FLL1_CLK_REF_SRC_MASK,
2341 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
2342 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
2344 if (sync) {
2345 regmap_update_bits(arizona->regmap, base + 0x7,
2346 ARIZONA_FLL1_GAIN_MASK,
2347 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2348 } else {
2349 regmap_update_bits(arizona->regmap, base + 0x5,
2350 ARIZONA_FLL1_OUTDIV_MASK,
2351 cfg->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
2352 regmap_update_bits(arizona->regmap, base + 0x9,
2353 ARIZONA_FLL1_GAIN_MASK,
2354 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
2357 regmap_update_bits_async(arizona->regmap, base + 2,
2358 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
2359 ARIZONA_FLL1_CTRL_UPD | cfg->n);
2362 static int arizona_is_enabled_fll(struct arizona_fll *fll, int base)
2364 struct arizona *arizona = fll->arizona;
2365 unsigned int reg;
2366 int ret;
2368 ret = regmap_read(arizona->regmap, base + 1, &reg);
2369 if (ret != 0) {
2370 arizona_fll_err(fll, "Failed to read current state: %d\n",
2371 ret);
2372 return ret;
2375 return reg & ARIZONA_FLL1_ENA;
2378 static int arizona_set_fll_clks(struct arizona_fll *fll, int base, bool ena)
2380 struct arizona *arizona = fll->arizona;
2381 unsigned int val;
2382 struct clk *clk;
2383 int ret;
2385 ret = regmap_read(arizona->regmap, base + 6, &val);
2386 if (ret != 0) {
2387 arizona_fll_err(fll, "Failed to read current source: %d\n",
2388 ret);
2389 return ret;
2392 val &= ARIZONA_FLL1_CLK_REF_SRC_MASK;
2393 val >>= ARIZONA_FLL1_CLK_REF_SRC_SHIFT;
2395 switch (val) {
2396 case ARIZONA_FLL_SRC_MCLK1:
2397 clk = arizona->mclk[ARIZONA_MCLK1];
2398 break;
2399 case ARIZONA_FLL_SRC_MCLK2:
2400 clk = arizona->mclk[ARIZONA_MCLK2];
2401 break;
2402 default:
2403 return 0;
2406 if (ena) {
2407 return clk_prepare_enable(clk);
2408 } else {
2409 clk_disable_unprepare(clk);
2410 return 0;
2414 static int arizona_enable_fll(struct arizona_fll *fll)
2416 struct arizona *arizona = fll->arizona;
2417 bool use_sync = false;
2418 int already_enabled = arizona_is_enabled_fll(fll, fll->base);
2419 int sync_enabled = arizona_is_enabled_fll(fll, fll->base + 0x10);
2420 struct arizona_fll_cfg cfg;
2421 int i;
2422 unsigned int val;
2424 if (already_enabled < 0)
2425 return already_enabled;
2426 if (sync_enabled < 0)
2427 return sync_enabled;
2429 if (already_enabled) {
2430 /* Facilitate smooth refclk across the transition */
2431 regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2432 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2433 udelay(32);
2434 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2435 ARIZONA_FLL1_GAIN_MASK, 0);
2437 if (arizona_is_enabled_fll(fll, fll->base + 0x10) > 0)
2438 arizona_set_fll_clks(fll, fll->base + 0x10, false);
2439 arizona_set_fll_clks(fll, fll->base, false);
2443 * If we have both REFCLK and SYNCCLK then enable both,
2444 * otherwise apply the SYNCCLK settings to REFCLK.
2446 if (fll->ref_src >= 0 && fll->ref_freq &&
2447 fll->ref_src != fll->sync_src) {
2448 arizona_calc_fll(fll, &cfg, fll->ref_freq, false);
2450 /* Ref path hardcodes lambda to 65536 when sync is on */
2451 if (fll->sync_src >= 0 && cfg.lambda)
2452 cfg.theta = (cfg.theta * (1 << 16)) / cfg.lambda;
2454 arizona_apply_fll(arizona, fll->base, &cfg, fll->ref_src,
2455 false);
2456 if (fll->sync_src >= 0) {
2457 arizona_calc_fll(fll, &cfg, fll->sync_freq, true);
2459 arizona_apply_fll(arizona, fll->base + 0x10, &cfg,
2460 fll->sync_src, true);
2461 use_sync = true;
2463 } else if (fll->sync_src >= 0) {
2464 arizona_calc_fll(fll, &cfg, fll->sync_freq, false);
2466 arizona_apply_fll(arizona, fll->base, &cfg,
2467 fll->sync_src, false);
2469 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2470 ARIZONA_FLL1_SYNC_ENA, 0);
2471 } else {
2472 arizona_fll_err(fll, "No clocks provided\n");
2473 return -EINVAL;
2476 if (already_enabled && !!sync_enabled != use_sync)
2477 arizona_fll_warn(fll, "Synchroniser changed on active FLL\n");
2480 * Increase the bandwidth if we're not using a low frequency
2481 * sync source.
2483 if (use_sync && fll->sync_freq > 100000)
2484 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2485 ARIZONA_FLL1_SYNC_BW, 0);
2486 else
2487 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2488 ARIZONA_FLL1_SYNC_BW,
2489 ARIZONA_FLL1_SYNC_BW);
2491 if (!already_enabled)
2492 pm_runtime_get_sync(arizona->dev);
2494 if (use_sync) {
2495 arizona_set_fll_clks(fll, fll->base + 0x10, true);
2496 regmap_update_bits_async(arizona->regmap, fll->base + 0x11,
2497 ARIZONA_FLL1_SYNC_ENA,
2498 ARIZONA_FLL1_SYNC_ENA);
2500 arizona_set_fll_clks(fll, fll->base, true);
2501 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2502 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
2504 if (already_enabled)
2505 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2506 ARIZONA_FLL1_FREERUN, 0);
2508 arizona_fll_dbg(fll, "Waiting for FLL lock...\n");
2509 val = 0;
2510 for (i = 0; i < 15; i++) {
2511 if (i < 5)
2512 usleep_range(200, 400);
2513 else
2514 msleep(20);
2516 regmap_read(arizona->regmap,
2517 ARIZONA_INTERRUPT_RAW_STATUS_5,
2518 &val);
2519 if (val & (ARIZONA_FLL1_CLOCK_OK_STS << (fll->id - 1)))
2520 break;
2522 if (i == 15)
2523 arizona_fll_warn(fll, "Timed out waiting for lock\n");
2524 else
2525 arizona_fll_dbg(fll, "FLL locked (%d polls)\n", i);
2527 return 0;
2530 static void arizona_disable_fll(struct arizona_fll *fll)
2532 struct arizona *arizona = fll->arizona;
2533 bool ref_change, sync_change;
2535 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2536 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2537 regmap_update_bits_check(arizona->regmap, fll->base + 1,
2538 ARIZONA_FLL1_ENA, 0, &ref_change);
2539 regmap_update_bits_check(arizona->regmap, fll->base + 0x11,
2540 ARIZONA_FLL1_SYNC_ENA, 0, &sync_change);
2541 regmap_update_bits_async(arizona->regmap, fll->base + 1,
2542 ARIZONA_FLL1_FREERUN, 0);
2544 if (sync_change)
2545 arizona_set_fll_clks(fll, fll->base + 0x10, false);
2547 if (ref_change) {
2548 arizona_set_fll_clks(fll, fll->base, false);
2549 pm_runtime_put_autosuspend(arizona->dev);
2553 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
2554 unsigned int Fref, unsigned int Fout)
2556 int ret = 0;
2558 if (fll->ref_src == source && fll->ref_freq == Fref)
2559 return 0;
2561 if (fll->fout && Fref > 0) {
2562 ret = arizona_validate_fll(fll, Fref, fll->fout);
2563 if (ret != 0)
2564 return ret;
2567 fll->ref_src = source;
2568 fll->ref_freq = Fref;
2570 if (fll->fout && Fref > 0) {
2571 ret = arizona_enable_fll(fll);
2574 return ret;
2576 EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
2578 int arizona_set_fll(struct arizona_fll *fll, int source,
2579 unsigned int Fref, unsigned int Fout)
2581 int ret = 0;
2583 if (fll->sync_src == source &&
2584 fll->sync_freq == Fref && fll->fout == Fout)
2585 return 0;
2587 if (Fout) {
2588 if (fll->ref_src >= 0) {
2589 ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
2590 if (ret != 0)
2591 return ret;
2594 ret = arizona_validate_fll(fll, Fref, Fout);
2595 if (ret != 0)
2596 return ret;
2599 fll->sync_src = source;
2600 fll->sync_freq = Fref;
2601 fll->fout = Fout;
2603 if (Fout)
2604 ret = arizona_enable_fll(fll);
2605 else
2606 arizona_disable_fll(fll);
2608 return ret;
2610 EXPORT_SYMBOL_GPL(arizona_set_fll);
2612 int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
2613 int ok_irq, struct arizona_fll *fll)
2615 unsigned int val;
2617 fll->id = id;
2618 fll->base = base;
2619 fll->arizona = arizona;
2620 fll->sync_src = ARIZONA_FLL_SRC_NONE;
2622 /* Configure default refclk to 32kHz if we have one */
2623 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
2624 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
2625 case ARIZONA_CLK_SRC_MCLK1:
2626 case ARIZONA_CLK_SRC_MCLK2:
2627 fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK;
2628 break;
2629 default:
2630 fll->ref_src = ARIZONA_FLL_SRC_NONE;
2632 fll->ref_freq = 32768;
2634 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
2635 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
2636 "FLL%d clock OK", id);
2638 regmap_update_bits(arizona->regmap, fll->base + 1,
2639 ARIZONA_FLL1_FREERUN, 0);
2641 return 0;
2643 EXPORT_SYMBOL_GPL(arizona_init_fll);
2646 * arizona_set_output_mode - Set the mode of the specified output
2648 * @codec: Device to configure
2649 * @output: Output number
2650 * @diff: True to set the output to differential mode
2652 * Some systems use external analogue switches to connect more
2653 * analogue devices to the CODEC than are supported by the device. In
2654 * some systems this requires changing the switched output from single
2655 * ended to differential mode dynamically at runtime, an operation
2656 * supported using this function.
2658 * Most systems have a single static configuration and should use
2659 * platform data instead.
2661 int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
2663 unsigned int reg, val;
2665 if (output < 1 || output > 6)
2666 return -EINVAL;
2668 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
2670 if (diff)
2671 val = ARIZONA_OUT1_MONO;
2672 else
2673 val = 0;
2675 return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
2677 EXPORT_SYMBOL_GPL(arizona_set_output_mode);
2679 static const struct soc_enum arizona_adsp2_rate_enum[] = {
2680 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1,
2681 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2682 ARIZONA_RATE_ENUM_SIZE,
2683 arizona_rate_text, arizona_rate_val),
2684 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1,
2685 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2686 ARIZONA_RATE_ENUM_SIZE,
2687 arizona_rate_text, arizona_rate_val),
2688 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1,
2689 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2690 ARIZONA_RATE_ENUM_SIZE,
2691 arizona_rate_text, arizona_rate_val),
2692 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1,
2693 ARIZONA_DSP1_RATE_SHIFT, 0xf,
2694 ARIZONA_RATE_ENUM_SIZE,
2695 arizona_rate_text, arizona_rate_val),
2698 const struct snd_kcontrol_new arizona_adsp2_rate_controls[] = {
2699 SOC_ENUM("DSP1 Rate", arizona_adsp2_rate_enum[0]),
2700 SOC_ENUM("DSP2 Rate", arizona_adsp2_rate_enum[1]),
2701 SOC_ENUM("DSP3 Rate", arizona_adsp2_rate_enum[2]),
2702 SOC_ENUM("DSP4 Rate", arizona_adsp2_rate_enum[3]),
2704 EXPORT_SYMBOL_GPL(arizona_adsp2_rate_controls);
2706 static bool arizona_eq_filter_unstable(bool mode, __be16 _a, __be16 _b)
2708 s16 a = be16_to_cpu(_a);
2709 s16 b = be16_to_cpu(_b);
2711 if (!mode) {
2712 return abs(a) >= 4096;
2713 } else {
2714 if (abs(b) >= 4096)
2715 return true;
2717 return (abs((a << 16) / (4096 - b)) >= 4096 << 4);
2721 int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
2722 struct snd_ctl_elem_value *ucontrol)
2724 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2725 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
2726 struct soc_bytes *params = (void *)kcontrol->private_value;
2727 unsigned int val;
2728 __be16 *data;
2729 int len;
2730 int ret;
2732 len = params->num_regs * regmap_get_val_bytes(arizona->regmap);
2734 data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
2735 if (!data)
2736 return -ENOMEM;
2738 data[0] &= cpu_to_be16(ARIZONA_EQ1_B1_MODE);
2740 if (arizona_eq_filter_unstable(!!data[0], data[1], data[2]) ||
2741 arizona_eq_filter_unstable(true, data[4], data[5]) ||
2742 arizona_eq_filter_unstable(true, data[8], data[9]) ||
2743 arizona_eq_filter_unstable(true, data[12], data[13]) ||
2744 arizona_eq_filter_unstable(false, data[16], data[17])) {
2745 dev_err(arizona->dev, "Rejecting unstable EQ coefficients\n");
2746 ret = -EINVAL;
2747 goto out;
2750 ret = regmap_read(arizona->regmap, params->base, &val);
2751 if (ret != 0)
2752 goto out;
2754 val &= ~ARIZONA_EQ1_B1_MODE;
2755 data[0] |= cpu_to_be16(val);
2757 ret = regmap_raw_write(arizona->regmap, params->base, data, len);
2759 out:
2760 kfree(data);
2761 return ret;
2763 EXPORT_SYMBOL_GPL(arizona_eq_coeff_put);
2765 int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
2766 struct snd_ctl_elem_value *ucontrol)
2768 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
2769 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
2770 __be16 *data = (__be16 *)ucontrol->value.bytes.data;
2771 s16 val = be16_to_cpu(*data);
2773 if (abs(val) >= 4096) {
2774 dev_err(arizona->dev, "Rejecting unstable LHPF coefficients\n");
2775 return -EINVAL;
2778 return snd_soc_bytes_put(kcontrol, ucontrol);
2780 EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
2782 int arizona_of_get_audio_pdata(struct arizona *arizona)
2784 struct arizona_pdata *pdata = &arizona->pdata;
2785 struct device_node *np = arizona->dev->of_node;
2786 struct property *prop;
2787 const __be32 *cur;
2788 u32 val;
2789 u32 pdm_val[ARIZONA_MAX_PDM_SPK];
2790 int ret;
2791 int count = 0;
2793 count = 0;
2794 of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) {
2795 if (count == ARRAY_SIZE(pdata->inmode))
2796 break;
2798 pdata->inmode[count] = val;
2799 count++;
2802 count = 0;
2803 of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) {
2804 if (count == ARRAY_SIZE(pdata->dmic_ref))
2805 break;
2807 pdata->dmic_ref[count] = val;
2808 count++;
2811 count = 0;
2812 of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) {
2813 if (count == ARRAY_SIZE(pdata->out_mono))
2814 break;
2816 pdata->out_mono[count] = !!val;
2817 count++;
2820 count = 0;
2821 of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) {
2822 if (count == ARRAY_SIZE(pdata->max_channels_clocked))
2823 break;
2825 pdata->max_channels_clocked[count] = val;
2826 count++;
2829 count = 0;
2830 of_property_for_each_u32(np, "wlf,out-volume-limit", prop, cur, val) {
2831 if (count == ARRAY_SIZE(pdata->out_vol_limit))
2832 break;
2834 pdata->out_vol_limit[count] = val;
2835 count++;
2838 ret = of_property_read_u32_array(np, "wlf,spk-fmt",
2839 pdm_val, ARRAY_SIZE(pdm_val));
2841 if (ret >= 0)
2842 for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
2843 pdata->spk_fmt[count] = pdm_val[count];
2845 ret = of_property_read_u32_array(np, "wlf,spk-mute",
2846 pdm_val, ARRAY_SIZE(pdm_val));
2848 if (ret >= 0)
2849 for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
2850 pdata->spk_mute[count] = pdm_val[count];
2852 return 0;
2854 EXPORT_SYMBOL_GPL(arizona_of_get_audio_pdata);
2856 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2857 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2858 MODULE_LICENSE("GPL");