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

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
...@@ -246,6 +246,16 @@ static int wm8994_suspend(struct device *dev) ...@@ -246,6 +246,16 @@ static int wm8994_suspend(struct device *dev)
struct wm8994 *wm8994 = dev_get_drvdata(dev); struct wm8994 *wm8994 = dev_get_drvdata(dev);
int ret; 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 /* GPIO configuration state is saved here since we may be configuring
* the GPIO alternate functions even if we're not using the gpiolib * the GPIO alternate functions even if we're not using the gpiolib
* driver for them. * driver for them.
...@@ -261,6 +271,8 @@ static int wm8994_suspend(struct device *dev) ...@@ -261,6 +271,8 @@ static int wm8994_suspend(struct device *dev)
if (ret < 0) if (ret < 0)
dev_err(dev, "Failed to save LDO registers: %d\n", ret); dev_err(dev, "Failed to save LDO registers: %d\n", ret);
wm8994->suspended = true;
ret = regulator_bulk_disable(wm8994->num_supplies, ret = regulator_bulk_disable(wm8994->num_supplies,
wm8994->supplies); wm8994->supplies);
if (ret != 0) { if (ret != 0) {
...@@ -276,6 +288,10 @@ static int wm8994_resume(struct device *dev) ...@@ -276,6 +288,10 @@ static int wm8994_resume(struct device *dev)
struct wm8994 *wm8994 = dev_get_drvdata(dev); struct wm8994 *wm8994 = dev_get_drvdata(dev);
int ret; int ret;
/* We may have lied to the PM core about suspending */
if (!wm8994->suspended)
return 0;
ret = regulator_bulk_enable(wm8994->num_supplies, ret = regulator_bulk_enable(wm8994->num_supplies,
wm8994->supplies); wm8994->supplies);
if (ret != 0) { if (ret != 0) {
...@@ -298,6 +314,8 @@ static int wm8994_resume(struct device *dev) ...@@ -298,6 +314,8 @@ static int wm8994_resume(struct device *dev)
if (ret < 0) if (ret < 0)
dev_err(dev, "Failed to restore GPIO registers: %d\n", ret); dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
wm8994->suspended = false;
return 0; return 0;
} }
#endif #endif
......
...@@ -71,6 +71,7 @@ struct wm8994 { ...@@ -71,6 +71,7 @@ struct wm8994 {
u16 irq_masks_cache[WM8994_NUM_IRQ_REGS]; u16 irq_masks_cache[WM8994_NUM_IRQ_REGS];
/* Used over suspend/resume */ /* Used over suspend/resume */
bool suspended;
u16 ldo_regs[WM8994_NUM_LDO_REGS]; u16 ldo_regs[WM8994_NUM_LDO_REGS];
u16 gpio_regs[WM8994_NUM_GPIO_REGS]; u16 gpio_regs[WM8994_NUM_GPIO_REGS];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment