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: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
73ee6524d5
commit
77bd70e900
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
Loading…
Reference in a new issue