0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _ASOC_ARIZONA_H
0011 #define _ASOC_ARIZONA_H
0012
0013 #include <linux/completion.h>
0014 #include <linux/notifier.h>
0015 #include <linux/mfd/arizona/core.h>
0016
0017 #include <sound/soc.h>
0018
0019 #include "wm_adsp.h"
0020
0021 #define ARIZONA_CLK_SYSCLK 1
0022 #define ARIZONA_CLK_ASYNCCLK 2
0023 #define ARIZONA_CLK_OPCLK 3
0024 #define ARIZONA_CLK_ASYNC_OPCLK 4
0025
0026 #define ARIZONA_CLK_SRC_MCLK1 0x0
0027 #define ARIZONA_CLK_SRC_MCLK2 0x1
0028 #define ARIZONA_CLK_SRC_FLL1 0x4
0029 #define ARIZONA_CLK_SRC_FLL2 0x5
0030 #define ARIZONA_CLK_SRC_AIF1BCLK 0x8
0031 #define ARIZONA_CLK_SRC_AIF2BCLK 0x9
0032 #define ARIZONA_CLK_SRC_AIF3BCLK 0xa
0033
0034 #define ARIZONA_FLL_SRC_NONE -1
0035 #define ARIZONA_FLL_SRC_MCLK1 0
0036 #define ARIZONA_FLL_SRC_MCLK2 1
0037 #define ARIZONA_FLL_SRC_SLIMCLK 3
0038 #define ARIZONA_FLL_SRC_FLL1 4
0039 #define ARIZONA_FLL_SRC_FLL2 5
0040 #define ARIZONA_FLL_SRC_AIF1BCLK 8
0041 #define ARIZONA_FLL_SRC_AIF2BCLK 9
0042 #define ARIZONA_FLL_SRC_AIF3BCLK 10
0043 #define ARIZONA_FLL_SRC_AIF1LRCLK 12
0044 #define ARIZONA_FLL_SRC_AIF2LRCLK 13
0045 #define ARIZONA_FLL_SRC_AIF3LRCLK 14
0046
0047 #define ARIZONA_MIXER_VOL_MASK 0x00FE
0048 #define ARIZONA_MIXER_VOL_SHIFT 1
0049 #define ARIZONA_MIXER_VOL_WIDTH 7
0050
0051 #define ARIZONA_CLK_6MHZ 0
0052 #define ARIZONA_CLK_12MHZ 1
0053 #define ARIZONA_CLK_24MHZ 2
0054 #define ARIZONA_CLK_49MHZ 3
0055 #define ARIZONA_CLK_73MHZ 4
0056 #define ARIZONA_CLK_98MHZ 5
0057 #define ARIZONA_CLK_147MHZ 6
0058
0059 #define ARIZONA_MAX_DAI 10
0060 #define ARIZONA_MAX_ADSP 4
0061
0062 #define ARIZONA_DVFS_SR1_RQ 0x001
0063 #define ARIZONA_DVFS_ADSP1_RQ 0x100
0064
0065
0066 #define ARIZONA_NOTIFY_VOICE_TRIGGER 0x1
0067
0068 struct wm_adsp;
0069
0070 struct arizona_dai_priv {
0071 int clk;
0072
0073 struct snd_pcm_hw_constraint_list constraint;
0074 };
0075
0076 struct arizona_priv {
0077 struct wm_adsp adsp[ARIZONA_MAX_ADSP];
0078 struct arizona *arizona;
0079 int sysclk;
0080 int asyncclk;
0081 struct arizona_dai_priv dai[ARIZONA_MAX_DAI];
0082
0083 int num_inputs;
0084 unsigned int in_pending;
0085
0086 unsigned int out_up_pending;
0087 unsigned int out_up_delay;
0088 unsigned int out_down_pending;
0089 unsigned int out_down_delay;
0090
0091 unsigned int dvfs_reqs;
0092 struct mutex dvfs_lock;
0093 bool dvfs_cached;
0094
0095
0096 struct mutex lock;
0097 struct delayed_work hpdet_work;
0098 struct delayed_work micd_detect_work;
0099 struct delayed_work micd_timeout_work;
0100 struct snd_soc_jack *jack;
0101 struct regulator *micvdd;
0102 struct gpio_desc *micd_pol_gpio;
0103
0104 u16 last_jackdet;
0105
0106 int micd_mode;
0107 const struct arizona_micd_config *micd_modes;
0108 int micd_num_modes;
0109
0110 int micd_button_mask;
0111 const struct arizona_micd_range *micd_ranges;
0112 int num_micd_ranges;
0113
0114 bool micd_reva;
0115 bool micd_clamp;
0116
0117 bool hpdet_active;
0118 bool hpdet_done;
0119 bool hpdet_retried;
0120
0121 bool mic;
0122 bool detecting;
0123
0124 int num_hpdet_res;
0125 unsigned int hpdet_res[3];
0126
0127 int jack_flips;
0128 int hpdet_ip_version;
0129 };
0130
0131 struct arizona_voice_trigger_info {
0132 int core;
0133 };
0134
0135 #define ARIZONA_NUM_MIXER_INPUTS 104
0136
0137 extern const unsigned int arizona_mixer_tlv[];
0138 extern const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
0139 extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
0140
0141 #define ARIZONA_GAINMUX_CONTROLS(name, base) \
0142 SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \
0143 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
0144 arizona_mixer_tlv)
0145
0146 #define ARIZONA_MIXER_CONTROLS(name, base) \
0147 SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \
0148 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
0149 arizona_mixer_tlv), \
0150 SOC_SINGLE_RANGE_TLV(name " Input 2 Volume", base + 3, \
0151 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
0152 arizona_mixer_tlv), \
0153 SOC_SINGLE_RANGE_TLV(name " Input 3 Volume", base + 5, \
0154 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
0155 arizona_mixer_tlv), \
0156 SOC_SINGLE_RANGE_TLV(name " Input 4 Volume", base + 7, \
0157 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
0158 arizona_mixer_tlv)
0159
0160 #define ARIZONA_MUX_ENUM_DECL(name, reg) \
0161 SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL( \
0162 name, reg, 0, 0xff, arizona_mixer_texts, arizona_mixer_values)
0163
0164 #define ARIZONA_MUX_CTL_DECL(name) \
0165 const struct snd_kcontrol_new name##_mux = \
0166 SOC_DAPM_ENUM("Route", name##_enum)
0167
0168 #define ARIZONA_MUX_ENUMS(name, base_reg) \
0169 static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \
0170 static ARIZONA_MUX_CTL_DECL(name)
0171
0172 #define ARIZONA_MIXER_ENUMS(name, base_reg) \
0173 ARIZONA_MUX_ENUMS(name##_in1, base_reg); \
0174 ARIZONA_MUX_ENUMS(name##_in2, base_reg + 2); \
0175 ARIZONA_MUX_ENUMS(name##_in3, base_reg + 4); \
0176 ARIZONA_MUX_ENUMS(name##_in4, base_reg + 6)
0177
0178 #define ARIZONA_DSP_AUX_ENUMS(name, base_reg) \
0179 ARIZONA_MUX_ENUMS(name##_aux1, base_reg); \
0180 ARIZONA_MUX_ENUMS(name##_aux2, base_reg + 8); \
0181 ARIZONA_MUX_ENUMS(name##_aux3, base_reg + 16); \
0182 ARIZONA_MUX_ENUMS(name##_aux4, base_reg + 24); \
0183 ARIZONA_MUX_ENUMS(name##_aux5, base_reg + 32); \
0184 ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40)
0185
0186 #define ARIZONA_MUX(name, ctrl) \
0187 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
0188
0189 #define ARIZONA_MUX_WIDGETS(name, name_str) \
0190 ARIZONA_MUX(name_str " Input", &name##_mux)
0191
0192 #define ARIZONA_MIXER_WIDGETS(name, name_str) \
0193 ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \
0194 ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \
0195 ARIZONA_MUX(name_str " Input 3", &name##_in3_mux), \
0196 ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \
0197 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
0198
0199 #define ARIZONA_DSP_WIDGETS(name, name_str) \
0200 ARIZONA_MIXER_WIDGETS(name##L, name_str "L"), \
0201 ARIZONA_MIXER_WIDGETS(name##R, name_str "R"), \
0202 ARIZONA_MUX(name_str " Aux 1", &name##_aux1_mux), \
0203 ARIZONA_MUX(name_str " Aux 2", &name##_aux2_mux), \
0204 ARIZONA_MUX(name_str " Aux 3", &name##_aux3_mux), \
0205 ARIZONA_MUX(name_str " Aux 4", &name##_aux4_mux), \
0206 ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \
0207 ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux)
0208
0209 #define ARIZONA_MUX_ROUTES(widget, name) \
0210 { widget, NULL, name " Input" }, \
0211 ARIZONA_MIXER_INPUT_ROUTES(name " Input")
0212
0213 #define ARIZONA_MIXER_ROUTES(widget, name) \
0214 { widget, NULL, name " Mixer" }, \
0215 { name " Mixer", NULL, name " Input 1" }, \
0216 { name " Mixer", NULL, name " Input 2" }, \
0217 { name " Mixer", NULL, name " Input 3" }, \
0218 { name " Mixer", NULL, name " Input 4" }, \
0219 ARIZONA_MIXER_INPUT_ROUTES(name " Input 1"), \
0220 ARIZONA_MIXER_INPUT_ROUTES(name " Input 2"), \
0221 ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \
0222 ARIZONA_MIXER_INPUT_ROUTES(name " Input 4")
0223
0224 #define ARIZONA_DSP_ROUTES(name) \
0225 { name, NULL, name " Preloader"}, \
0226 { name " Preloader", NULL, "SYSCLK" }, \
0227 { name " Preload", NULL, name " Preloader"}, \
0228 { name, NULL, name " Aux 1" }, \
0229 { name, NULL, name " Aux 2" }, \
0230 { name, NULL, name " Aux 3" }, \
0231 { name, NULL, name " Aux 4" }, \
0232 { name, NULL, name " Aux 5" }, \
0233 { name, NULL, name " Aux 6" }, \
0234 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \
0235 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \
0236 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \
0237 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \
0238 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \
0239 ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \
0240 ARIZONA_MIXER_ROUTES(name, name "L"), \
0241 ARIZONA_MIXER_ROUTES(name, name "R")
0242
0243 #define ARIZONA_EQ_CONTROL(xname, xbase) \
0244 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
0245 .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
0246 .put = arizona_eq_coeff_put, .private_value = \
0247 ((unsigned long)&(struct soc_bytes) { .base = xbase, \
0248 .num_regs = 20, .mask = ~ARIZONA_EQ1_B1_MODE }) }
0249
0250 #define ARIZONA_LHPF_CONTROL(xname, xbase) \
0251 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
0252 .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
0253 .put = arizona_lhpf_coeff_put, .private_value = \
0254 ((unsigned long)&(struct soc_bytes) { .base = xbase, \
0255 .num_regs = 1 }) }
0256
0257 #define ARIZONA_RATE_ENUM_SIZE 4
0258 #define ARIZONA_SAMPLE_RATE_ENUM_SIZE 14
0259
0260
0261 #define ARIZONA_JACK_MASK (SND_JACK_HEADSET | SND_JACK_LINEOUT | SND_JACK_MECHANICAL)
0262
0263 extern const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];
0264 extern const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE];
0265 extern const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE];
0266 extern const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE];
0267
0268 extern const struct soc_enum arizona_isrc_fsl[];
0269 extern const struct soc_enum arizona_isrc_fsh[];
0270 extern const struct soc_enum arizona_asrc_rate1;
0271
0272 extern const struct soc_enum arizona_in_vi_ramp;
0273 extern const struct soc_enum arizona_in_vd_ramp;
0274
0275 extern const struct soc_enum arizona_out_vi_ramp;
0276 extern const struct soc_enum arizona_out_vd_ramp;
0277
0278 extern const struct soc_enum arizona_lhpf1_mode;
0279 extern const struct soc_enum arizona_lhpf2_mode;
0280 extern const struct soc_enum arizona_lhpf3_mode;
0281 extern const struct soc_enum arizona_lhpf4_mode;
0282
0283 extern const struct soc_enum arizona_ng_hold;
0284 extern const struct soc_enum arizona_in_hpf_cut_enum;
0285 extern const struct soc_enum arizona_in_dmic_osr[];
0286
0287 extern const struct snd_kcontrol_new arizona_adsp2_rate_controls[];
0288
0289 extern const struct soc_enum arizona_anc_input_src[];
0290 extern const struct soc_enum arizona_anc_ng_enum;
0291 extern const struct soc_enum arizona_output_anc_src[];
0292
0293 extern const struct snd_kcontrol_new arizona_voice_trigger_switch[];
0294
0295 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
0296 int event);
0297 int arizona_out_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
0298 int event);
0299 int arizona_hp_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
0300 int event);
0301 int arizona_anc_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
0302 int event);
0303
0304 int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
0305 struct snd_ctl_elem_value *ucontrol);
0306 int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
0307 struct snd_ctl_elem_value *ucontrol);
0308
0309 int arizona_clk_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
0310 int event);
0311 int arizona_set_sysclk(struct snd_soc_component *component, int clk_id, int source,
0312 unsigned int freq, int dir);
0313
0314 extern const struct snd_soc_dai_ops arizona_dai_ops;
0315 extern const struct snd_soc_dai_ops arizona_simple_dai_ops;
0316
0317 #define ARIZONA_FLL_NAME_LEN 20
0318
0319 struct arizona_fll {
0320 struct arizona *arizona;
0321 int id;
0322 unsigned int base;
0323 unsigned int vco_mult;
0324
0325 unsigned int fout;
0326 int sync_src;
0327 unsigned int sync_freq;
0328 int ref_src;
0329 unsigned int ref_freq;
0330
0331 char lock_name[ARIZONA_FLL_NAME_LEN];
0332 char clock_ok_name[ARIZONA_FLL_NAME_LEN];
0333 };
0334
0335 int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags);
0336 int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags);
0337 int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
0338 struct snd_kcontrol *kcontrol, int event);
0339 void arizona_init_dvfs(struct arizona_priv *priv);
0340
0341 int arizona_init_fll(struct arizona *arizona, int id, int base,
0342 int lock_irq, int ok_irq, struct arizona_fll *fll);
0343 int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
0344 unsigned int Fref, unsigned int Fout);
0345 int arizona_set_fll(struct arizona_fll *fll, int source,
0346 unsigned int Fref, unsigned int Fout);
0347
0348 int arizona_init_spk(struct snd_soc_component *component);
0349 int arizona_init_gpio(struct snd_soc_component *component);
0350 int arizona_init_mono(struct snd_soc_component *component);
0351
0352 int arizona_init_common(struct arizona *arizona);
0353 int arizona_init_vol_limit(struct arizona *arizona);
0354
0355 int arizona_init_spk_irqs(struct arizona *arizona);
0356 int arizona_free_spk_irqs(struct arizona *arizona);
0357
0358 int arizona_init_dai(struct arizona_priv *priv, int id);
0359
0360 int arizona_set_output_mode(struct snd_soc_component *component, int output,
0361 bool diff);
0362
0363 bool arizona_input_analog(struct snd_soc_component *component, int shift);
0364
0365 const char *arizona_sample_rate_val_to_name(unsigned int rate_val);
0366
0367 static inline int arizona_register_notifier(struct snd_soc_component *component,
0368 struct notifier_block *nb,
0369 int (*notify)
0370 (struct notifier_block *nb,
0371 unsigned long action, void *data))
0372 {
0373 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
0374 struct arizona *arizona = priv->arizona;
0375
0376 nb->notifier_call = notify;
0377
0378 return blocking_notifier_chain_register(&arizona->notifier, nb);
0379 }
0380
0381 static inline int arizona_unregister_notifier(struct snd_soc_component *component,
0382 struct notifier_block *nb)
0383 {
0384 struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
0385 struct arizona *arizona = priv->arizona;
0386
0387 return blocking_notifier_chain_unregister(&arizona->notifier, nb);
0388 }
0389
0390 int arizona_of_get_audio_pdata(struct arizona *arizona);
0391
0392 int arizona_jack_codec_dev_probe(struct arizona_priv *info, struct device *dev);
0393 int arizona_jack_codec_dev_remove(struct arizona_priv *info);
0394
0395 int arizona_jack_set_jack(struct snd_soc_component *component,
0396 struct snd_soc_jack *jack, void *data);
0397
0398 #endif