浏览代码

ASoC: dapm: Allow regulators to bypass as well as disable when idle

Allow regulators managed via DAPM to make use of the bypass support that
has recently been added to the regulator API by setting a flag
SND_SOC_DAPM_REGULATOR_BYPASS. When this flag is set the regulator will
be put into bypass mode before being disabled, allowing the regulator to
fall into bypass mode if it can't be disabled due to other users.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Mark Brown 13 年之前
父节点
当前提交
c05b84d14b
共有 2 个文件被更改,包括 24 次插入2 次删除
  1. 3 0
      include/sound/soc-dapm.h
  2. 21 2
      sound/soc/soc-dapm.c

+ 3 - 0
include/sound/soc-dapm.h

@@ -320,6 +320,9 @@ struct device;
 #define SND_SOC_DAPM_EVENT_OFF(e)	\
 #define SND_SOC_DAPM_EVENT_OFF(e)	\
 	(e & (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD))
 	(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;
 struct snd_soc_dapm_widget;
 enum snd_soc_dapm_type;
 enum snd_soc_dapm_type;
 struct snd_soc_dapm_path;
 struct snd_soc_dapm_path;

+ 21 - 2
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,
 int dapm_regulator_event(struct snd_soc_dapm_widget *w,
 		   struct snd_kcontrol *kcontrol, int event)
 		   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);
 		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);
 		return regulator_disable_deferred(w->regulator, w->shift);
+	}
 }
 }
 EXPORT_SYMBOL_GPL(dapm_regulator_event);
 EXPORT_SYMBOL_GPL(dapm_regulator_event);