Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5927467d authored by Mark Brown's avatar Mark Brown
Browse files

mfd: arizona: Support use of external DCVDD



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: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent d781009c
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -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 @@ static int arizona_runtime_resume(struct device *dev)
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);
+2 −0
Original line number Diff line number Diff line
@@ -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;