summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc-dapm.h3
-rw-r--r--sound/soc/soc-dapm.c23
2 files changed, 24 insertions, 2 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index c96bf5ae80a..e1ef63d4a5c 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -320,6 +320,9 @@ struct device;
#define SND_SOC_DAPM_EVENT_OFF(e) \
(e & (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD))
+/* regulator widget flags */
+#define SND_SOC_DAPM_REGULATOR_BYPASS 0x1 /* bypass when disabled */
+
struct snd_soc_dapm_widget;
enum snd_soc_dapm_type;
struct snd_soc_dapm_path;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 873e6e76ee8..d0a4be38dc0 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1017,10 +1017,29 @@ EXPORT_SYMBOL_GPL(dapm_reg_event);
int dapm_regulator_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
- if (SND_SOC_DAPM_EVENT_ON(event))
+ int ret;
+
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
+ if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) {
+ ret = regulator_allow_bypass(w->regulator, true);
+ if (ret != 0)
+ dev_warn(w->dapm->dev,
+ "Failed to bypass %s: %d\n",
+ w->name, ret);
+ }
+
return regulator_enable(w->regulator);
- else
+ } else {
+ if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) {
+ ret = regulator_allow_bypass(w->regulator, false);
+ if (ret != 0)
+ dev_warn(w->dapm->dev,
+ "Failed to unbypass %s: %d\n",
+ w->name, ret);
+ }
+
return regulator_disable_deferred(w->regulator, w->shift);
+ }
}
EXPORT_SYMBOL_GPL(dapm_regulator_event);