summaryrefslogtreecommitdiff
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 92894d9cac19..a5fb4d404c99 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -35,6 +35,7 @@
#include <linux/debugfs.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -72,6 +73,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
static int dapm_up_seq[] = {
[snd_soc_dapm_pre] = 0,
[snd_soc_dapm_regulator_supply] = 1,
+ [snd_soc_dapm_pinctrl] = 1,
[snd_soc_dapm_clock_supply] = 1,
[snd_soc_dapm_supply] = 2,
[snd_soc_dapm_micbias] = 3,
@@ -121,6 +123,7 @@ static int dapm_down_seq[] = {
[snd_soc_dapm_dai_link] = 11,
[snd_soc_dapm_supply] = 12,
[snd_soc_dapm_clock_supply] = 13,
+ [snd_soc_dapm_pinctrl] = 13,
[snd_soc_dapm_regulator_supply] = 13,
[snd_soc_dapm_post] = 14,
};
@@ -1290,6 +1293,31 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
EXPORT_SYMBOL_GPL(dapm_regulator_event);
/*
+ * Handler for pinctrl widget.
+ */
+int dapm_pinctrl_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_dapm_pinctrl_priv *priv = w->priv;
+ struct pinctrl *p = w->pinctrl;
+ struct pinctrl_state *s;
+
+ if (!p || !priv)
+ return -EIO;
+
+ if (SND_SOC_DAPM_EVENT_ON(event))
+ s = pinctrl_lookup_state(p, priv->active_state);
+ else
+ s = pinctrl_lookup_state(p, priv->sleep_state);
+
+ if (IS_ERR(s))
+ return PTR_ERR(s);
+
+ return pinctrl_select_state(p, s);
+}
+EXPORT_SYMBOL_GPL(dapm_pinctrl_event);
+
+/*
* Handler for clock supply widget.
*/
int dapm_clock_event(struct snd_soc_dapm_widget *w,
@@ -1902,6 +1930,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
break;
case snd_soc_dapm_supply:
case snd_soc_dapm_regulator_supply:
+ case snd_soc_dapm_pinctrl:
case snd_soc_dapm_clock_supply:
case snd_soc_dapm_micbias:
if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
@@ -2315,6 +2344,7 @@ static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt,
case snd_soc_dapm_mixer_named_ctl:
case snd_soc_dapm_supply:
case snd_soc_dapm_regulator_supply:
+ case snd_soc_dapm_pinctrl:
case snd_soc_dapm_clock_supply:
if (w->name)
count += sprintf(buf + count, "%s: %s\n",
@@ -3464,6 +3494,17 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
w->name, ret);
}
break;
+ case snd_soc_dapm_pinctrl:
+ w->pinctrl = devm_pinctrl_get(dapm->dev);
+ if (IS_ERR_OR_NULL(w->pinctrl)) {
+ ret = PTR_ERR(w->pinctrl);
+ if (ret == -EPROBE_DEFER)
+ return ERR_PTR(ret);
+ dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
+ w->name, ret);
+ return NULL;
+ }
+ break;
case snd_soc_dapm_clock_supply:
#ifdef CONFIG_CLKDEV_LOOKUP
w->clk = devm_clk_get(dapm->dev, w->name);
@@ -3543,6 +3584,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
break;
case snd_soc_dapm_supply:
case snd_soc_dapm_regulator_supply:
+ case snd_soc_dapm_pinctrl:
case snd_soc_dapm_clock_supply:
case snd_soc_dapm_kcontrol:
w->is_supply = 1;