diff options
Diffstat (limited to 'sound/soc/codecs/arizona.h')
| -rw-r--r-- | sound/soc/codecs/arizona.h | 223 |
1 files changed, 185 insertions, 38 deletions
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index b60b08ccc1d0..ecd8890eefc1 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -1,19 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * arizona.h - Wolfson Arizona class device shared support * * Copyright 2012 Wolfson Microelectronics plc * * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef _ASOC_ARIZONA_H #define _ASOC_ARIZONA_H #include <linux/completion.h> +#include <linux/notifier.h> +#include <linux/mfd/arizona/core.h> #include <sound/soc.h> @@ -57,14 +56,21 @@ #define ARIZONA_CLK_98MHZ 5 #define ARIZONA_CLK_147MHZ 6 -#define ARIZONA_MAX_DAI 6 +#define ARIZONA_MAX_DAI 10 #define ARIZONA_MAX_ADSP 4 -struct arizona; +#define ARIZONA_DVFS_SR1_RQ 0x001 +#define ARIZONA_DVFS_ADSP1_RQ 0x100 + +/* Notifier events */ +#define ARIZONA_NOTIFY_VOICE_TRIGGER 0x1 + struct wm_adsp; struct arizona_dai_priv { int clk; + + struct snd_pcm_hw_constraint_list constraint; }; struct arizona_priv { @@ -77,15 +83,65 @@ struct arizona_priv { int num_inputs; unsigned int in_pending; - unsigned int spk_ena:2; - unsigned int spk_ena_pending:1; + unsigned int out_up_pending; + unsigned int out_up_delay; + unsigned int out_down_pending; + unsigned int out_down_delay; + + unsigned int dvfs_reqs; + struct mutex dvfs_lock; + bool dvfs_cached; + + /* Variables used by arizona-jack.c code */ + struct mutex lock; + struct delayed_work hpdet_work; + struct delayed_work micd_detect_work; + struct delayed_work micd_timeout_work; + struct snd_soc_jack *jack; + struct regulator *micvdd; + struct gpio_desc *micd_pol_gpio; + + u16 last_jackdet; + + int micd_mode; + const struct arizona_micd_config *micd_modes; + int micd_num_modes; + + int micd_button_mask; + const struct arizona_micd_range *micd_ranges; + int num_micd_ranges; + + bool micd_reva; + bool micd_clamp; + + bool hpdet_active; + bool hpdet_done; + bool hpdet_retried; + + bool mic; + bool detecting; + + int num_hpdet_res; + unsigned int hpdet_res[3]; + + int jack_flips; + int hpdet_ip_version; +}; + +struct arizona_voice_trigger_info { + int core; }; -#define ARIZONA_NUM_MIXER_INPUTS 99 +#define ARIZONA_NUM_MIXER_INPUTS 104 extern const unsigned int arizona_mixer_tlv[]; -extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS]; -extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; +extern const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS]; +extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; + +#define ARIZONA_GAINMUX_CONTROLS(name, base) \ + SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \ + ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \ + arizona_mixer_tlv) #define ARIZONA_MIXER_CONTROLS(name, base) \ SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \ @@ -102,12 +158,12 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; arizona_mixer_tlv) #define ARIZONA_MUX_ENUM_DECL(name, reg) \ - SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \ - arizona_mixer_texts, arizona_mixer_values) + SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL( \ + name, reg, 0, 0xff, arizona_mixer_texts, arizona_mixer_values) #define ARIZONA_MUX_CTL_DECL(name) \ const struct snd_kcontrol_new name##_mux = \ - SOC_DAPM_VALUE_ENUM("Route", name##_enum) + SOC_DAPM_ENUM("Route", name##_enum) #define ARIZONA_MUX_ENUMS(name, base_reg) \ static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \ @@ -128,7 +184,7 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40) #define ARIZONA_MUX(name, ctrl) \ - SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) #define ARIZONA_MUX_WIDGETS(name, name_str) \ ARIZONA_MUX(name_str " Input", &name##_mux) @@ -150,7 +206,8 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \ ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux) -#define ARIZONA_MUX_ROUTES(name) \ +#define ARIZONA_MUX_ROUTES(widget, name) \ + { widget, NULL, name " Input" }, \ ARIZONA_MIXER_INPUT_ROUTES(name " Input") #define ARIZONA_MIXER_ROUTES(widget, name) \ @@ -165,6 +222,9 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") #define ARIZONA_DSP_ROUTES(name) \ + { name, NULL, name " Preloader"}, \ + { name " Preloader", NULL, "SYSCLK" }, \ + { name " Preload", NULL, name " Preloader"}, \ { name, NULL, name " Aux 1" }, \ { name, NULL, name " Aux 2" }, \ { name, NULL, name " Aux 3" }, \ @@ -180,11 +240,34 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MIXER_ROUTES(name, name "L"), \ ARIZONA_MIXER_ROUTES(name, name "R") +#define ARIZONA_EQ_CONTROL(xname, xbase) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \ + .put = arizona_eq_coeff_put, .private_value = \ + ((unsigned long)&(struct soc_bytes) { .base = xbase, \ + .num_regs = 20, .mask = ~ARIZONA_EQ1_B1_MODE }) } + +#define ARIZONA_LHPF_CONTROL(xname, xbase) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \ + .put = arizona_lhpf_coeff_put, .private_value = \ + ((unsigned long)&(struct soc_bytes) { .base = xbase, \ + .num_regs = 1 }) } + #define ARIZONA_RATE_ENUM_SIZE 4 -extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; -extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE]; +#define ARIZONA_SAMPLE_RATE_ENUM_SIZE 14 + +/* SND_JACK_* mask for supported cable/switch types */ +#define ARIZONA_JACK_MASK (SND_JACK_HEADSET | SND_JACK_LINEOUT | SND_JACK_MECHANICAL) + +extern const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; +extern const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE]; +extern const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE]; +extern const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE]; extern const struct soc_enum arizona_isrc_fsl[]; +extern const struct soc_enum arizona_isrc_fsh[]; +extern const struct soc_enum arizona_asrc_rate1; extern const struct soc_enum arizona_in_vi_ramp; extern const struct soc_enum arizona_in_vd_ramp; @@ -198,19 +281,35 @@ extern const struct soc_enum arizona_lhpf3_mode; extern const struct soc_enum arizona_lhpf4_mode; extern const struct soc_enum arizona_ng_hold; +extern const struct soc_enum arizona_in_hpf_cut_enum; +extern const struct soc_enum arizona_in_dmic_osr[]; + +extern const struct snd_kcontrol_new arizona_adsp2_rate_controls[]; + +extern const struct soc_enum arizona_anc_input_src[]; +extern const struct soc_enum arizona_anc_ng_enum; +extern const struct soc_enum arizona_output_anc_src[]; -extern int arizona_in_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event); -extern int arizona_out_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event); -extern int arizona_hp_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event); +extern const struct snd_kcontrol_new arizona_voice_trigger_switch[]; -extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, - int source, unsigned int freq, int dir); +int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event); +int arizona_out_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event); +int arizona_hp_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event); +int arizona_anc_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event); + +int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +int arizona_clk_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event); +int arizona_set_sysclk(struct snd_soc_component *component, int clk_id, int source, + unsigned int freq, int dir); extern const struct snd_soc_dai_ops arizona_dai_ops; extern const struct snd_soc_dai_ops arizona_simple_dai_ops; @@ -222,7 +321,6 @@ struct arizona_fll { int id; unsigned int base; unsigned int vco_mult; - struct completion ok; unsigned int fout; int sync_src; @@ -234,18 +332,67 @@ struct arizona_fll { char clock_ok_name[ARIZONA_FLL_NAME_LEN]; }; -extern int arizona_init_fll(struct arizona *arizona, int id, int base, - int lock_irq, int ok_irq, struct arizona_fll *fll); -extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source, - unsigned int Fref, unsigned int Fout); -extern int arizona_set_fll(struct arizona_fll *fll, int source, +int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags); +int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags); +int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); +void arizona_init_dvfs(struct arizona_priv *priv); + +int arizona_init_fll(struct arizona *arizona, int id, int base, + int lock_irq, int ok_irq, struct arizona_fll *fll); +int arizona_set_fll_refclk(struct arizona_fll *fll, int source, unsigned int Fref, unsigned int Fout); +int arizona_set_fll(struct arizona_fll *fll, int source, + unsigned int Fref, unsigned int Fout); + +int arizona_init_spk(struct snd_soc_component *component); +int arizona_init_gpio(struct snd_soc_component *component); +int arizona_init_mono(struct snd_soc_component *component); + +int arizona_init_common(struct arizona *arizona); +int arizona_init_vol_limit(struct arizona *arizona); -extern int arizona_init_spk(struct snd_soc_codec *codec); +int arizona_init_spk_irqs(struct arizona *arizona); +int arizona_free_spk_irqs(struct arizona *arizona); -extern int arizona_init_dai(struct arizona_priv *priv, int dai); +int arizona_init_dai(struct arizona_priv *priv, int id); -int arizona_set_output_mode(struct snd_soc_codec *codec, int output, +int arizona_set_output_mode(struct snd_soc_component *component, int output, bool diff); +bool arizona_input_analog(struct snd_soc_component *component, int shift); + +const char *arizona_sample_rate_val_to_name(unsigned int rate_val); + +static inline int arizona_register_notifier(struct snd_soc_component *component, + struct notifier_block *nb, + int (*notify) + (struct notifier_block *nb, + unsigned long action, void *data)) +{ + struct arizona_priv *priv = snd_soc_component_get_drvdata(component); + struct arizona *arizona = priv->arizona; + + nb->notifier_call = notify; + + return blocking_notifier_chain_register(&arizona->notifier, nb); +} + +static inline int arizona_unregister_notifier(struct snd_soc_component *component, + struct notifier_block *nb) +{ + struct arizona_priv *priv = snd_soc_component_get_drvdata(component); + struct arizona *arizona = priv->arizona; + + return blocking_notifier_chain_unregister(&arizona->notifier, nb); +} + +int arizona_of_get_audio_pdata(struct arizona *arizona); + +int arizona_jack_codec_dev_probe(struct arizona_priv *info, struct device *dev); +int arizona_jack_codec_dev_remove(struct arizona_priv *info); + +int arizona_jack_set_jack(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data); + #endif |
