2 * arizona.c - Wolfson Arizona class device shared support
4 * Copyright 2012 Wolfson Microelectronics plc
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>
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>
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,
87 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
88 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
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");
100 regmap_update_bits_async(arizona->regmap,
101 ARIZONA_OUTPUT_ENABLES_1,
102 1 << w->shift, 1 << w->shift);
104 case SND_SOC_DAPM_PRE_PMD:
105 regmap_update_bits_async(arizona->regmap,
106 ARIZONA_OUTPUT_ENABLES_1,
113 return arizona_out_ev(w, kcontrol, event);
116 static irqreturn_t arizona_thermal_warn(int irq, void *data)
118 struct arizona *arizona = data;
122 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
125 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
127 } else if (val & ARIZONA_SPK_OVERHEAT_WARN_STS) {
128 dev_crit(arizona->dev, "Thermal warning\n");
134 static irqreturn_t arizona_thermal_shutdown(int irq, void *data)
136 struct arizona *arizona = data;
140 ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3,
143 dev_err(arizona->dev, "Failed to read thermal status: %d\n",
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,
150 ARIZONA_OUT4R_ENA, 0);
152 dev_crit(arizona->dev,
153 "Failed to disable speaker outputs: %d\n",
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;
179 ret = snd_soc_dapm_new_controls(dapm, &arizona_spkl, 1);
183 switch (arizona->type) {
189 ret = snd_soc_dapm_new_controls(dapm, &arizona_spkr, 1);
197 EXPORT_SYMBOL_GPL(arizona_init_spk);
199 int arizona_init_spk_irqs(struct arizona *arizona)
203 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT_WARN,
204 "Thermal warning", arizona_thermal_warn,
207 dev_err(arizona->dev,
208 "Failed to get thermal warning IRQ: %d\n",
211 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_OVERHEAT,
212 "Thermal shutdown", arizona_thermal_shutdown,
215 dev_err(arizona->dev,
216 "Failed to get thermal shutdown IRQ: %d\n",
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);
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;
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);
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;
266 switch (arizona->type) {
269 snd_soc_component_disable_pin(component,
270 "DRC2 Signal Activity");
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");
284 case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
285 snd_soc_component_enable_pin(component,
286 "DRC2 Signal Activity");
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;
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;
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,
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,
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) {
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;
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;
366 regmap_update_bits(arizona->regmap,
367 ARIZONA_IN1L_CONTROL + (i * 8),
373 EXPORT_SYMBOL_GPL(arizona_init_common);
375 int arizona_init_vol_limit(struct arizona *arizona)
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]);
389 EXPORT_SYMBOL_GPL(arizona_init_vol_limit);
391 const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
497 EXPORT_SYMBOL_GPL(arizona_mixer_texts);
499 unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
506 0x0c, /* Noise mixer */
507 0x0d, /* Comfort noise */
580 0xa0, /* ISRC1INT1 */
584 0xa4, /* ISRC1DEC1 */
588 0xa8, /* ISRC2DEC1 */
592 0xac, /* ISRC2INT1 */
596 0xb0, /* ISRC3DEC1 */
600 0xb4, /* ISRC3INT1 */
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)
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];
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] = {
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,
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,
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,
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,
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,
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[] = {
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);
896 for (i = 0; i < priv->num_inputs; i++)
897 snd_soc_update_bits(codec,
898 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
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,
914 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
915 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
919 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
921 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
924 case SND_SOC_DAPM_PRE_PMU:
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 */
932 if (priv->in_pending == 0) {
934 arizona_in_set_vu(codec, 1);
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);
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);
946 arizona_in_set_vu(codec, 0);
954 EXPORT_SYMBOL_GPL(arizona_in_ev);
956 int arizona_out_ev(struct snd_soc_dapm_widget *w,
957 struct snd_kcontrol *kcontrol,
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;
965 case SND_SOC_DAPM_PRE_PMU:
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;
976 case ARIZONA_OUT4L_ENA_SHIFT:
977 case ARIZONA_OUT4R_ENA_SHIFT:
978 priv->out_up_pending++;
979 switch (arizona->type) {
984 priv->out_up_delay += 10;
992 case SND_SOC_DAPM_POST_PMU:
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;
1015 case SND_SOC_DAPM_PRE_PMD:
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++;
1026 case ARIZONA_OUT4L_ENA_SHIFT:
1027 case ARIZONA_OUT4R_ENA_SHIFT:
1028 priv->out_down_pending++;
1029 switch (arizona->type) {
1035 priv->out_down_delay += 5;
1038 priv->out_down_delay++;
1045 case SND_SOC_DAPM_POST_PMD:
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;
1073 EXPORT_SYMBOL_GPL(arizona_out_ev);
1075 int arizona_hp_ev(struct snd_soc_dapm_widget *w,
1076 struct snd_kcontrol *kcontrol,
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;
1086 case SND_SOC_DAPM_POST_PMU:
1089 case SND_SOC_DAPM_PRE_PMD:
1092 case SND_SOC_DAPM_PRE_PMU:
1093 case SND_SOC_DAPM_POST_PMD:
1094 return arizona_out_ev(w, kcontrol, event);
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)
1107 regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1,
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;
1120 ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
1122 dev_err(codec->dev, "Failed to boost DCVDD: %d\n", ret);
1126 ret = regmap_update_bits(arizona->regmap,
1127 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1128 ARIZONA_SUBSYS_MAX_FREQ,
1129 ARIZONA_SUBSYS_MAX_FREQ);
1131 dev_err(codec->dev, "Failed to enable subsys max: %d\n", ret);
1132 regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
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;
1145 ret = regmap_update_bits(arizona->regmap,
1146 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
1147 ARIZONA_SUBSYS_MAX_FREQ, 0);
1149 dev_err(codec->dev, "Failed to disable subsys max: %d\n", ret);
1153 ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
1155 dev_err(codec->dev, "Failed to unboost DCVDD: %d\n", ret);
1162 int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags)
1164 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1167 mutex_lock(&priv->dvfs_lock);
1169 if (!priv->dvfs_cached && !priv->dvfs_reqs) {
1170 ret = arizona_dvfs_enable(codec);
1175 priv->dvfs_reqs |= flags;
1177 mutex_unlock(&priv->dvfs_lock);
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;
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);
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);
1208 mutex_lock(&priv->dvfs_lock);
1211 case SND_SOC_DAPM_POST_PMU:
1212 if (priv->dvfs_reqs)
1213 ret = arizona_dvfs_enable(codec);
1215 priv->dvfs_cached = false;
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);
1231 mutex_unlock(&priv->dvfs_lock);
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,
1246 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1250 case SND_SOC_DAPM_POST_PMU:
1251 val = 1 << w->shift;
1253 case SND_SOC_DAPM_PRE_PMD:
1254 val = 1 << (w->shift + 1);
1260 snd_soc_write(codec, ARIZONA_CLOCK_CONTROL, val);
1264 EXPORT_SYMBOL_GPL(arizona_anc_ev);
1266 static unsigned int arizona_opclk_ref_48k_rates[] = {
1273 static unsigned int arizona_opclk_ref_44k1_rates[] = {
1280 static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
1283 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1285 unsigned int *rates;
1286 int ref, div, refclk;
1289 case ARIZONA_CLK_OPCLK:
1290 reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
1291 refclk = priv->sysclk;
1293 case ARIZONA_CLK_ASYNC_OPCLK:
1294 reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
1295 refclk = priv->asyncclk;
1302 rates = arizona_opclk_ref_44k1_rates;
1304 rates = arizona_opclk_ref_48k_rates;
1306 for (ref = 0; ref < ARRAY_SIZE(arizona_opclk_ref_48k_rates) &&
1307 rates[ref] <= refclk; ref++) {
1309 while (rates[ref] / div >= freq && div < 32) {
1310 if (rates[ref] / div == freq) {
1311 dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
1313 snd_soc_update_bits(codec, reg,
1314 ARIZONA_OPCLK_DIV_MASK |
1315 ARIZONA_OPCLK_SEL_MASK,
1317 ARIZONA_OPCLK_DIV_SHIFT) |
1325 dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
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);
1338 ret = regmap_read(arizona->regmap, w->reg, &val);
1340 dev_err(codec->dev, "Failed to check clock source: %d\n", ret);
1344 val = (val & ARIZONA_SYSCLK_SRC_MASK) >> ARIZONA_SYSCLK_SRC_SHIFT;
1347 case ARIZONA_CLK_SRC_MCLK1:
1348 clk_idx = ARIZONA_MCLK1;
1350 case ARIZONA_CLK_SRC_MCLK2:
1351 clk_idx = ARIZONA_MCLK2;
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]);
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;
1376 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
1377 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
1381 case ARIZONA_CLK_SYSCLK:
1383 reg = ARIZONA_SYSTEM_CLOCK_1;
1384 clk = &priv->sysclk;
1385 mask |= ARIZONA_SYSCLK_FRAC;
1387 case ARIZONA_CLK_ASYNCCLK:
1389 reg = ARIZONA_ASYNC_CLOCK_1;
1390 clk = &priv->asyncclk;
1392 case ARIZONA_CLK_OPCLK:
1393 case ARIZONA_CLK_ASYNC_OPCLK:
1394 return arizona_set_opclk(codec, clk_id, freq);
1405 val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1409 val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1413 val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1417 val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1421 val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1425 val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT;
1428 dev_dbg(arizona->dev, "%s cleared\n", name);
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;
1458 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1459 case SND_SOC_DAIFMT_DSP_A:
1460 mode = ARIZONA_FMT_DSP_MODE_A;
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");
1468 mode = ARIZONA_FMT_DSP_MODE_B;
1470 case SND_SOC_DAIFMT_I2S:
1471 mode = ARIZONA_FMT_I2S_MODE;
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");
1479 mode = ARIZONA_FMT_LEFT_JUSTIFIED_MODE;
1482 arizona_aif_err(dai, "Unsupported DAI format %d\n",
1483 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1487 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1488 case SND_SOC_DAIFMT_CBS_CFS:
1490 case SND_SOC_DAIFMT_CBS_CFM:
1491 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1493 case SND_SOC_DAIFMT_CBM_CFS:
1494 bclk |= ARIZONA_AIF1_BCLK_MSTR;
1496 case SND_SOC_DAIFMT_CBM_CFM:
1497 bclk |= ARIZONA_AIF1_BCLK_MSTR;
1498 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
1501 arizona_aif_err(dai, "Unsupported master mode %d\n",
1502 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1506 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1507 case SND_SOC_DAIFMT_NB_NF:
1509 case SND_SOC_DAIFMT_IB_IF:
1510 bclk |= ARIZONA_AIF1_BCLK_INV;
1511 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1513 case SND_SOC_DAIFMT_IB_NF:
1514 bclk |= ARIZONA_AIF1_BCLK_INV;
1516 case SND_SOC_DAIFMT_NB_IF:
1517 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
1523 regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL,
1524 ARIZONA_AIF1_BCLK_INV |
1525 ARIZONA_AIF1_BCLK_MSTR,
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);
1540 static const int arizona_48k_bclk_rates[] = {
1562 static const int arizona_44k1_bclk_rates[] = {
1584 static const unsigned int arizona_sr_vals[] = {
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)
1631 switch (dai_priv->clk) {
1632 case ARIZONA_CLK_SYSCLK:
1633 base_rate = priv->sysclk;
1635 case ARIZONA_CLK_ASYNCCLK:
1636 base_rate = priv->asyncclk;
1643 dai_priv->constraint.mask = ARIZONA_RATE_MASK;
1644 else if (base_rate % 8000)
1645 dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK;
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,
1657 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1658 struct arizona *arizona = priv->arizona;
1659 struct reg_sequence dac_comp[] = {
1661 { ARIZONA_DAC_COMP_1, 0 },
1662 { ARIZONA_DAC_COMP_2, 0 },
1666 mutex_lock(&arizona->dac_comp_lock);
1668 dac_comp[1].def = arizona->dac_comp_coeff;
1670 dac_comp[2].def = arizona->dac_comp_enabled;
1672 mutex_unlock(&arizona->dac_comp_lock);
1674 regmap_multi_reg_write(arizona->regmap,
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;
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))
1696 if (i == ARRAY_SIZE(arizona_sr_vals)) {
1697 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1698 params_rate(params));
1703 switch (priv->arizona->type) {
1706 if (arizona_sr_vals[sr_val] >= 88200)
1707 ret = arizona_dvfs_up(codec, ARIZONA_DVFS_SR1_RQ);
1709 ret = arizona_dvfs_down(codec, ARIZONA_DVFS_SR1_RQ);
1712 arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
1720 switch (dai_priv->clk) {
1721 case ARIZONA_CLK_SYSCLK:
1722 switch (priv->arizona->type) {
1724 arizona_wm5102_set_dac_comp(codec,
1725 params_rate(params));
1731 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
1732 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
1734 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1735 ARIZONA_AIF1_RATE_MASK, 0);
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);
1741 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
1742 ARIZONA_AIF1_RATE_MASK,
1743 8 << ARIZONA_AIF1_RATE_SHIFT);
1746 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
1753 static bool arizona_aif_cfg_changed(struct snd_soc_codec *codec,
1754 int base, int bclk, int lrclk, int frame)
1758 val = snd_soc_read(codec, base + ARIZONA_AIF_BCLK_CTRL);
1759 if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
1762 val = snd_soc_read(codec, base + ARIZONA_AIF_TX_BCLK_RATE);
1763 if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
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)))
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;
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;
1790 unsigned int aif_tx_state, aif_rx_state;
1792 if (params_rate(params) % 4000)
1793 rates = &arizona_44k1_bclk_rates[0];
1795 rates = &arizona_48k_bclk_rates[0];
1797 wl = params_width(params);
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;
1805 bclk_target = snd_soc_params_to_bclk(params);
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) {
1831 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
1832 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
1833 params_rate(params));
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);
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);
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);
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);
1896 static const char *arizona_dai_clk_str(int clk_id)
1899 case ARIZONA_CLK_SYSCLK:
1901 case ARIZONA_CLK_ASYNCCLK:
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];
1918 case ARIZONA_CLK_SYSCLK:
1919 case ARIZONA_CLK_ASYNCCLK:
1925 if (clk_id == dai_priv->clk)
1929 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
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;
1961 reg = ARIZONA_AIF1_TRI;
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,
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;
1978 for (i = 0; i < channels; ++i) {
1979 slot = ffs(mask) - 1;
1983 regmap_write(arizona->regmap, base + i, slot);
1985 mask &= ~(1 << slot);
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)
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;
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;
2048 EXPORT_SYMBOL_GPL(arizona_init_dai);
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] = {
2088 { 256000, 1000000, 2 },
2089 { 1000000, 13500000, 4 },
2092 struct arizona_fll_cfg {
2095 unsigned int lambda;
2102 static int arizona_validate_fll(struct arizona_fll *fll,
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");
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",
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",
2131 static int arizona_find_fratio(unsigned int Fref, int *fratio)
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) {
2139 *fratio = fll_fratios[i].fratio;
2140 return fll_fratios[i].ratio;
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;
2155 /* Fref must be <=13.5MHz, find initial refdiv */
2158 while (Fref > ARIZONA_FLL_MAX_FREF) {
2163 if (div > ARIZONA_FLL_MAX_REFDIV)
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",
2175 switch (fll->arizona->type) {
2181 if (fll->arizona->rev < 3 || sync)
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
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);
2213 for (ratio = init_ratio + 1; ratio <= ARIZONA_FLL_MAX_FRATIO;
2215 if ((ARIZONA_FLL_VCO_CORNER / 2) /
2216 (fll->vco_mult * ratio) < Fref) {
2217 arizona_fll_dbg(fll, "pseudo: hit VCO corner\n");
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],
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);
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;
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) {
2265 if (div > ARIZONA_FLL_MAX_OUTDIV)
2268 target = fll->fout * div / fll->vco_mult;
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);
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))
2289 cfg->lambda = (ratio * Fref) / gcd_fll;
2295 /* Round down to 16bit range with cost of accuracy lost.
2296 * Denominator must be bigger than numerator so we only
2299 while (cfg->lambda >= (1 << 16)) {
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;
2310 if (i == ARRAY_SIZE(fll_gains)) {
2311 arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n",
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);
2327 static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
2328 struct arizona_fll_cfg *cfg, int source,
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);
2345 regmap_update_bits(arizona->regmap, base + 0x7,
2346 ARIZONA_FLL1_GAIN_MASK,
2347 cfg->gain << ARIZONA_FLL1_GAIN_SHIFT);
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;
2368 ret = regmap_read(arizona->regmap, base + 1, ®);
2370 arizona_fll_err(fll, "Failed to read current state: %d\n",
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;
2385 ret = regmap_read(arizona->regmap, base + 6, &val);
2387 arizona_fll_err(fll, "Failed to read current source: %d\n",
2392 val &= ARIZONA_FLL1_CLK_REF_SRC_MASK;
2393 val >>= ARIZONA_FLL1_CLK_REF_SRC_SHIFT;
2396 case ARIZONA_FLL_SRC_MCLK1:
2397 clk = arizona->mclk[ARIZONA_MCLK1];
2399 case ARIZONA_FLL_SRC_MCLK2:
2400 clk = arizona->mclk[ARIZONA_MCLK2];
2407 return clk_prepare_enable(clk);
2409 clk_disable_unprepare(clk);
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;
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);
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,
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);
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);
2472 arizona_fll_err(fll, "No clocks provided\n");
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
2483 if (use_sync && fll->sync_freq > 100000)
2484 regmap_update_bits_async(arizona->regmap, fll->base + 0x17,
2485 ARIZONA_FLL1_SYNC_BW, 0);
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);
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");
2510 for (i = 0; i < 15; i++) {
2512 usleep_range(200, 400);
2516 regmap_read(arizona->regmap,
2517 ARIZONA_INTERRUPT_RAW_STATUS_5,
2519 if (val & (ARIZONA_FLL1_CLOCK_OK_STS << (fll->id - 1)))
2523 arizona_fll_warn(fll, "Timed out waiting for lock\n");
2525 arizona_fll_dbg(fll, "FLL locked (%d polls)\n", i);
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);
2545 arizona_set_fll_clks(fll, fll->base + 0x10, false);
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)
2558 if (fll->ref_src == source && fll->ref_freq == Fref)
2561 if (fll->fout && Fref > 0) {
2562 ret = arizona_validate_fll(fll, Fref, fll->fout);
2567 fll->ref_src = source;
2568 fll->ref_freq = Fref;
2570 if (fll->fout && Fref > 0) {
2571 ret = arizona_enable_fll(fll);
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)
2583 if (fll->sync_src == source &&
2584 fll->sync_freq == Fref && fll->fout == Fout)
2588 if (fll->ref_src >= 0) {
2589 ret = arizona_validate_fll(fll, fll->ref_freq, Fout);
2594 ret = arizona_validate_fll(fll, Fref, Fout);
2599 fll->sync_src = source;
2600 fll->sync_freq = Fref;
2604 ret = arizona_enable_fll(fll);
2606 arizona_disable_fll(fll);
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)
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;
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);
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)
2668 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
2671 val = ARIZONA_OUT1_MONO;
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);
2712 return abs(a) >= 4096;
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;
2732 len = params->num_regs * regmap_get_val_bytes(arizona->regmap);
2734 data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
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");
2750 ret = regmap_read(arizona->regmap, params->base, &val);
2754 val &= ~ARIZONA_EQ1_B1_MODE;
2755 data[0] |= cpu_to_be16(val);
2757 ret = regmap_raw_write(arizona->regmap, params->base, data, len);
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");
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;
2789 u32 pdm_val[ARIZONA_MAX_PDM_SPK];
2794 of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) {
2795 if (count == ARRAY_SIZE(pdata->inmode))
2798 pdata->inmode[count] = val;
2803 of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) {
2804 if (count == ARRAY_SIZE(pdata->dmic_ref))
2807 pdata->dmic_ref[count] = val;
2812 of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) {
2813 if (count == ARRAY_SIZE(pdata->out_mono))
2816 pdata->out_mono[count] = !!val;
2821 of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) {
2822 if (count == ARRAY_SIZE(pdata->max_channels_clocked))
2825 pdata->max_channels_clocked[count] = val;
2830 of_property_for_each_u32(np, "wlf,out-volume-limit", prop, cur, val) {
2831 if (count == ARRAY_SIZE(pdata->out_vol_limit))
2834 pdata->out_vol_limit[count] = val;
2838 ret = of_property_read_u32_array(np, "wlf,spk-fmt",
2839 pdm_val, ARRAY_SIZE(pdm_val));
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));
2849 for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
2850 pdata->spk_mute[count] = pdm_val[count];
2854 EXPORT_SYMBOL_GPL(arizona_of_get_audio_pdata);
2856 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
2858 MODULE_LICENSE("GPL");