summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/arizona.h
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/arizona.h')
-rw-r--r--sound/soc/codecs/arizona.h223
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