+ if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) {
+ ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
+ if (ret != 0)
+ dev_err(d->dev,
+ "Failed to turn on bias: %d\n", ret);
+ }
+
+ /* If we're changing to all on or all off then prepare */
+ if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
+ (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
+ ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE);
+ if (ret != 0)
+ dev_err(d->dev,
+ "Failed to prepare bias: %d\n", ret);
+ }
+}
+
+/* Async callback run prior to DAPM sequences - brings to their final
+ * state.
+ */
+static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
+{
+ struct snd_soc_dapm_context *d = data;
+ int ret;
+
+ /* If we just powered the last thing off drop to standby bias */
+ if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) {
+ ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
+ if (ret != 0)
+ dev_err(d->dev, "Failed to apply standby bias: %d\n",
+ ret);
+ }
+
+ /* If we're in standby and can support bias off then do that */
+ if (d->bias_level == SND_SOC_BIAS_STANDBY && d->idle_bias_off) {
+ ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
+ if (ret != 0)
+ dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
+ }
+
+ /* If we just powered up then move to active bias */
+ if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
+ ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON);
+ if (ret != 0)
+ dev_err(d->dev, "Failed to apply active bias: %d\n",
+ ret);
+ }
+}