|
@@ -442,12 +442,33 @@ static int arizona_runtime_resume(struct device *dev)
|
|
|
|
|
|
dev_dbg(arizona->dev, "Leaving AoD mode\n");
|
|
|
|
|
|
+ if (arizona->has_fully_powered_off) {
|
|
|
+ dev_dbg(arizona->dev, "Re-enabling core supplies\n");
|
|
|
+
|
|
|
+ ret = regulator_bulk_enable(arizona->num_core_supplies,
|
|
|
+ arizona->core_supplies);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(dev, "Failed to enable core supplies: %d\n",
|
|
|
+ ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
ret = regulator_enable(arizona->dcvdd);
|
|
|
if (ret != 0) {
|
|
|
dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
|
|
|
+ if (arizona->has_fully_powered_off)
|
|
|
+ regulator_bulk_disable(arizona->num_core_supplies,
|
|
|
+ arizona->core_supplies);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+ if (arizona->has_fully_powered_off) {
|
|
|
+ arizona_disable_reset(arizona);
|
|
|
+ enable_irq(arizona->irq);
|
|
|
+ arizona->has_fully_powered_off = false;
|
|
|
+ }
|
|
|
+
|
|
|
regcache_cache_only(arizona->regmap, false);
|
|
|
|
|
|
switch (arizona->type) {
|
|
@@ -508,6 +529,14 @@ static int arizona_runtime_resume(struct device *dev)
|
|
|
goto err;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ ret = wm5110_apply_sleep_patch(arizona);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(arizona->dev,
|
|
|
+ "Failed to re-apply sleep patch: %d\n",
|
|
|
+ ret);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
break;
|
|
|
default:
|
|
|
ret = arizona_wait_for_boot(arizona);
|
|
@@ -545,10 +574,17 @@ err:
|
|
|
static int arizona_runtime_suspend(struct device *dev)
|
|
|
{
|
|
|
struct arizona *arizona = dev_get_drvdata(dev);
|
|
|
+ unsigned int val;
|
|
|
int ret;
|
|
|
|
|
|
dev_dbg(arizona->dev, "Entering AoD mode\n");
|
|
|
|
|
|
+ ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(dev, "Failed to check jack det status: %d\n", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
if (arizona->external_dcvdd) {
|
|
|
ret = regmap_update_bits(arizona->regmap,
|
|
|
ARIZONA_ISOLATION_CONTROL,
|
|
@@ -559,33 +595,58 @@ static int arizona_runtime_suspend(struct device *dev)
|
|
|
ret);
|
|
|
return ret;
|
|
|
}
|
|
|
- } else {
|
|
|
- switch (arizona->type) {
|
|
|
- case WM5110:
|
|
|
- case WM8280:
|
|
|
- /*
|
|
|
- * As this is only called for the internal regulator
|
|
|
- * (where we know voltage ranges available) it is ok
|
|
|
- * to request an exact range.
|
|
|
- */
|
|
|
- ret = regulator_set_voltage(arizona->dcvdd,
|
|
|
- 1175000, 1175000);
|
|
|
- if (ret < 0) {
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (arizona->type) {
|
|
|
+ case WM5110:
|
|
|
+ case WM8280:
|
|
|
+ if (arizona->external_dcvdd)
|
|
|
+ break;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * As this is only called for the internal regulator
|
|
|
+ * (where we know voltage ranges available) it is ok
|
|
|
+ * to request an exact range.
|
|
|
+ */
|
|
|
+ ret = regulator_set_voltage(arizona->dcvdd, 1175000, 1175000);
|
|
|
+ if (ret < 0) {
|
|
|
+ dev_err(arizona->dev,
|
|
|
+ "Failed to set suspend voltage: %d\n", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case WM5102:
|
|
|
+ if (!(val & ARIZONA_JD1_ENA)) {
|
|
|
+ ret = regmap_write(arizona->regmap,
|
|
|
+ ARIZONA_WRITE_SEQUENCER_CTRL_3, 0x0);
|
|
|
+ if (ret) {
|
|
|
dev_err(arizona->dev,
|
|
|
- "Failed to set suspend voltage: %d\n",
|
|
|
+ "Failed to clear write sequencer: %d\n",
|
|
|
ret);
|
|
|
return ret;
|
|
|
}
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
}
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
regcache_cache_only(arizona->regmap, true);
|
|
|
regcache_mark_dirty(arizona->regmap);
|
|
|
regulator_disable(arizona->dcvdd);
|
|
|
|
|
|
+ /* Allow us to completely power down if no jack detection */
|
|
|
+ if (!(val & ARIZONA_JD1_ENA)) {
|
|
|
+ dev_dbg(arizona->dev, "Fully powering off\n");
|
|
|
+
|
|
|
+ arizona->has_fully_powered_off = true;
|
|
|
+
|
|
|
+ disable_irq(arizona->irq);
|
|
|
+ arizona_enable_reset(arizona);
|
|
|
+ regulator_bulk_disable(arizona->num_core_supplies,
|
|
|
+ arizona->core_supplies);
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
#endif
|