diff options
-rw-r--r-- | include/linux/mfd/arizona/core.h | 10 | ||||
-rw-r--r-- | sound/soc/codecs/arizona.c | 35 | ||||
-rw-r--r-- | sound/soc/codecs/arizona.h | 17 | ||||
-rw-r--r-- | sound/soc/codecs/cs47l24.c | 8 | ||||
-rw-r--r-- | sound/soc/codecs/wm5110.c | 8 |
5 files changed, 78 insertions, 0 deletions
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h index d55a42297d49..58ab4c0fe761 100644 --- a/include/linux/mfd/arizona/core.h +++ b/include/linux/mfd/arizona/core.h @@ -14,6 +14,7 @@ #define _WM_ARIZONA_CORE_H #include <linux/interrupt.h> +#include <linux/notifier.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/mfd/arizona/pdata.h> @@ -148,8 +149,17 @@ struct arizona { uint16_t dac_comp_coeff; uint8_t dac_comp_enabled; struct mutex dac_comp_lock; + + struct blocking_notifier_head notifier; }; +static inline int arizona_call_notifiers(struct arizona *arizona, + unsigned long event, + void *data) +{ + return blocking_notifier_call_chain(&arizona->notifier, event, data); +} + int arizona_clk32k_enable(struct arizona *arizona); int arizona_clk32k_disable(struct arizona *arizona); diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 664a8c044ffb..7f9ab92ffa91 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -324,6 +324,17 @@ int arizona_init_gpio(struct snd_soc_codec *codec) } EXPORT_SYMBOL_GPL(arizona_init_gpio); +int arizona_init_notifiers(struct snd_soc_codec *codec) +{ + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; + + BLOCKING_INIT_NOTIFIER_HEAD(&arizona->notifier); + + return 0; +} +EXPORT_SYMBOL_GPL(arizona_init_notifiers); + const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { "None", "Tone Generator 1", @@ -2573,6 +2584,30 @@ int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put); +int arizona_register_notifier(struct snd_soc_codec *codec, + struct notifier_block *nb, + int (*notify)(struct notifier_block *nb, + unsigned long action, void *data)) +{ + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; + + nb->notifier_call = notify; + + return blocking_notifier_chain_register(&arizona->notifier, nb); +} +EXPORT_SYMBOL_GPL(arizona_register_notifier); + +int arizona_unregister_notifier(struct snd_soc_codec *codec, + struct notifier_block *nb) +{ + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; + + return blocking_notifier_chain_unregister(&arizona->notifier, nb); +} +EXPORT_SYMBOL_GPL(arizona_unregister_notifier); + MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index ce0531b8c632..46862af7665e 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -63,6 +63,9 @@ #define ARIZONA_DVFS_SR1_RQ 0x001 #define ARIZONA_DVFS_ADSP1_RQ 0x100 +/* Notifier events */ +#define ARIZONA_NOTIFY_VOICE_TRIGGER 0x1 + struct arizona; struct wm_adsp; @@ -95,6 +98,10 @@ struct arizona_priv { bool dvfs_cached; }; +struct arizona_voice_trigger_info { + int core; +}; + #define ARIZONA_NUM_MIXER_INPUTS 104 extern const unsigned int arizona_mixer_tlv[]; @@ -306,6 +313,7 @@ extern int arizona_set_fll(struct arizona_fll *fll, int source, extern int arizona_init_spk(struct snd_soc_codec *codec); extern int arizona_init_gpio(struct snd_soc_codec *codec); extern int arizona_init_mono(struct snd_soc_codec *codec); +extern int arizona_init_notifiers(struct snd_soc_codec *codec); extern int arizona_free_spk(struct snd_soc_codec *codec); @@ -317,4 +325,13 @@ int arizona_set_output_mode(struct snd_soc_codec *codec, int output, extern bool arizona_input_analog(struct snd_soc_codec *codec, int shift); extern const char *arizona_sample_rate_val_to_name(unsigned int rate_val); + +extern int arizona_register_notifier(struct snd_soc_codec *codec, + struct notifier_block *nb, + int (*notify)(struct notifier_block *nb, + unsigned long action, + void *data)); +extern int arizona_unregister_notifier(struct snd_soc_codec *codec, + struct notifier_block *nb); + #endif diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index 5ec5a682d186..bbc8cf18ded0 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c @@ -1067,6 +1067,7 @@ static irqreturn_t cs47l24_adsp2_irq(int irq, void *data) { struct cs47l24_priv *priv = data; struct arizona *arizona = priv->core.arizona; + struct arizona_voice_trigger_info info; int serviced = 0; int i, ret; @@ -1074,6 +1075,12 @@ static irqreturn_t cs47l24_adsp2_irq(int irq, void *data) ret = wm_adsp_compr_handle_irq(&priv->core.adsp[i]); if (ret != -ENODEV) serviced++; + if (ret == WM_ADSP_COMPR_VOICE_TRIGGER) { + info.core = i; + arizona_call_notifiers(arizona, + ARIZONA_NOTIFY_VOICE_TRIGGER, + &info); + } } if (!serviced) { @@ -1096,6 +1103,7 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec) arizona_init_spk(codec); arizona_init_gpio(codec); arizona_init_mono(codec); + arizona_init_notifiers(codec); ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, "ADSP2 Compressed IRQ", cs47l24_adsp2_irq, diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index b5820e4d5471..83c48eca56f5 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -2222,6 +2222,7 @@ static irqreturn_t wm5110_adsp2_irq(int irq, void *data) { struct wm5110_priv *priv = data; struct arizona *arizona = priv->core.arizona; + struct arizona_voice_trigger_info info; int serviced = 0; int i, ret; @@ -2229,6 +2230,12 @@ static irqreturn_t wm5110_adsp2_irq(int irq, void *data) ret = wm_adsp_compr_handle_irq(&priv->core.adsp[i]); if (ret != -ENODEV) serviced++; + if (ret == WM_ADSP_COMPR_VOICE_TRIGGER) { + info.core = i; + arizona_call_notifiers(arizona, + ARIZONA_NOTIFY_VOICE_TRIGGER, + &info); + } } if (!serviced) { @@ -2251,6 +2258,7 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) arizona_init_spk(codec); arizona_init_gpio(codec); arizona_init_mono(codec); + arizona_init_notifiers(codec); ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, "ADSP2 Compressed IRQ", wm5110_adsp2_irq, |