Skip to content

Commit

Permalink
mfd: Don't suspend WM8994 if the CODEC is not suspended
Browse files Browse the repository at this point in the history
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: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
  • Loading branch information
Mark Brown authored and Samuel Ortiz committed Mar 2, 2011
1 parent 73ee652 commit 77bd70e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
18 changes: 18 additions & 0 deletions drivers/mfd/wm8994-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions include/linux/mfd/wm8994/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down

0 comments on commit 77bd70e

Please sign in to comment.