|
@@ -22,6 +22,7 @@
|
|
|
#include <linux/pm_runtime.h>
|
|
|
#include <linux/regmap.h>
|
|
|
#include <linux/regulator/consumer.h>
|
|
|
+#include <linux/regulator/machine.h>
|
|
|
#include <linux/slab.h>
|
|
|
|
|
|
#include <linux/mfd/arizona/core.h>
|
|
@@ -347,6 +348,17 @@ static int arizona_runtime_resume(struct device *dev)
|
|
|
|
|
|
switch (arizona->type) {
|
|
|
case WM5102:
|
|
|
+ if (arizona->external_dcvdd) {
|
|
|
+ ret = regmap_update_bits(arizona->regmap,
|
|
|
+ ARIZONA_ISOLATION_CONTROL,
|
|
|
+ ARIZONA_ISOLATE_DCVDD1, 0);
|
|
|
+ if (ret != 0) {
|
|
|
+ dev_err(arizona->dev,
|
|
|
+ "Failed to connect DCVDD: %d\n", ret);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
ret = wm5102_patch(arizona);
|
|
|
if (ret != 0) {
|
|
|
dev_err(arizona->dev, "Failed to apply patch: %d\n",
|
|
@@ -368,6 +380,16 @@ static int arizona_runtime_resume(struct device *dev)
|
|
|
goto err;
|
|
|
}
|
|
|
|
|
|
+ if (arizona->external_dcvdd) {
|
|
|
+ ret = regmap_update_bits(arizona->regmap,
|
|
|
+ ARIZONA_ISOLATION_CONTROL,
|
|
|
+ ARIZONA_ISOLATE_DCVDD1, 0);
|
|
|
+ if (ret != 0) {
|
|
|
+ dev_err(arizona->dev,
|
|
|
+ "Failed to connect DCVDD: %d\n", ret);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -400,9 +422,22 @@ err:
|
|
|
static int arizona_runtime_suspend(struct device *dev)
|
|
|
{
|
|
|
struct arizona *arizona = dev_get_drvdata(dev);
|
|
|
+ int ret;
|
|
|
|
|
|
dev_dbg(arizona->dev, "Entering AoD mode\n");
|
|
|
|
|
|
+ if (arizona->external_dcvdd) {
|
|
|
+ ret = regmap_update_bits(arizona->regmap,
|
|
|
+ ARIZONA_ISOLATION_CONTROL,
|
|
|
+ ARIZONA_ISOLATE_DCVDD1,
|
|
|
+ ARIZONA_ISOLATE_DCVDD1);
|
|
|
+ if (ret != 0) {
|
|
|
+ dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n",
|
|
|
+ ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
regulator_disable(arizona->dcvdd);
|
|
|
regcache_cache_only(arizona->regmap, true);
|
|
|
regcache_mark_dirty(arizona->regmap);
|
|
@@ -771,6 +806,14 @@ int arizona_dev_init(struct arizona *arizona)
|
|
|
arizona->pdata.gpio_defaults[i]);
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * LDO1 can only be used to supply DCVDD so if it has no
|
|
|
+ * consumers then DCVDD is supplied externally.
|
|
|
+ */
|
|
|
+ if (arizona->pdata.ldo1 &&
|
|
|
+ arizona->pdata.ldo1->num_consumer_supplies == 0)
|
|
|
+ arizona->external_dcvdd = true;
|
|
|
+
|
|
|
pm_runtime_set_autosuspend_delay(arizona->dev, 100);
|
|
|
pm_runtime_use_autosuspend(arizona->dev);
|
|
|
pm_runtime_enable(arizona->dev);
|