]> git.karo-electronics.de Git - linux-beck.git/commitdiff
mfd: arizona: Support use of external DCVDD
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Tue, 23 Apr 2013 18:44:16 +0000 (19:44 +0100)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 20 May 2013 13:13:37 +0000 (08:13 -0500)
When the device is used with an external DCVDD supply instead of the
internal LDO1 then an extra step is required when suspending and resuming
the device.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
drivers/mfd/arizona-core.c
include/linux/mfd/arizona/core.h

index d8d30c0a488d2be079f76f900cc10ce7b2a02af7..437f199fe5f26299371e515714e6c92f915760fd 100644 (file)
@@ -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);
index cc281368dc555f17d486b84fe1a3087f328bb880..f797bb9b8b56838458fe108c343bd4c5d6bde7f5 100644 (file)
@@ -95,6 +95,8 @@ struct arizona {
 
        struct arizona_pdata pdata;
 
+       unsigned int external_dcvdd:1;
+
        int irq;
        struct irq_domain *virq;
        struct regmap_irq_chip_data *aod_irq_chip;