Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 77bd70e9 authored by Mark Brown's avatar Mark Brown Committed by Samuel Ortiz
Browse files

mfd: Don't suspend WM8994 if the CODEC is not suspended



ASoC supports keeping the audio subsysetm active over suspend in order
to support use cases such as audio passthrough from a cellular modem
with the main CPU suspended. Ensure that we don't power down the CODEC
when this is happening by checking to see if VMID is up and skipping
suspend and resume when it is. If the CODEC has suspended then it'll
turn VMID off before the core suspend() gets called.

Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent 73ee6524
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -246,6 +246,16 @@ static int wm8994_suspend(struct device *dev)
	struct wm8994 *wm8994 = dev_get_drvdata(dev);
	int ret;

	/* Don't actually go through with the suspend if the CODEC is
	 * still active (eg, for audio passthrough from CP. */
	ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1);
	if (ret < 0) {
		dev_err(dev, "Failed to read power status: %d\n", ret);
	} else if (ret & WM8994_VMID_SEL_MASK) {
		dev_dbg(dev, "CODEC still active, ignoring suspend\n");
		return 0;
	}

	/* GPIO configuration state is saved here since we may be configuring
	 * the GPIO alternate functions even if we're not using the gpiolib
	 * driver for them.
@@ -261,6 +271,8 @@ static int wm8994_suspend(struct device *dev)
	if (ret < 0)
		dev_err(dev, "Failed to save LDO registers: %d\n", ret);

	wm8994->suspended = true;

	ret = regulator_bulk_disable(wm8994->num_supplies,
				     wm8994->supplies);
	if (ret != 0) {
@@ -276,6 +288,10 @@ static int wm8994_resume(struct device *dev)
	struct wm8994 *wm8994 = dev_get_drvdata(dev);
	int ret;

	/* We may have lied to the PM core about suspending */
	if (!wm8994->suspended)
		return 0;

	ret = regulator_bulk_enable(wm8994->num_supplies,
				    wm8994->supplies);
	if (ret != 0) {
@@ -298,6 +314,8 @@ static int wm8994_resume(struct device *dev)
	if (ret < 0)
		dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);

	wm8994->suspended = false;

	return 0;
}
#endif
+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ struct wm8994 {
	u16 irq_masks_cache[WM8994_NUM_IRQ_REGS];

	/* Used over suspend/resume */
	bool suspended;
	u16 ldo_regs[WM8994_NUM_LDO_REGS];
	u16 gpio_regs[WM8994_NUM_GPIO_REGS];