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

Commit 2b17fa28 authored by Romain Perier's avatar Romain Perier Committed by Mark Brown
Browse files

regulator: act8865: Add support to turn off all outputs



When the property "poweroff-source" is found in the
devicetree, the function pm_power_off is defined. This function sends the
rights bit fields to the global off control register. shutdown/poweroff
commands are now supported for hardware components which use these PMU.

Signed-off-by: default avatarRomain Perier <romain.perier@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent a4b4e046
Loading
Loading
Loading
Loading
+31 −0
Original line number Original line Diff line number Diff line
@@ -61,6 +61,8 @@
#define	ACT8846_REG12_VSET	0xa0
#define	ACT8846_REG12_VSET	0xa0
#define	ACT8846_REG12_CTRL	0xa1
#define	ACT8846_REG12_CTRL	0xa1
#define	ACT8846_REG13_CTRL	0xb1
#define	ACT8846_REG13_CTRL	0xb1
#define	ACT8846_GLB_OFF_CTRL	0xc3
#define	ACT8846_OFF_SYSMASK	0x18


/*
/*
 * ACT8865 Global Register Map.
 * ACT8865 Global Register Map.
@@ -84,6 +86,7 @@
#define	ACT8865_LDO3_CTRL	0x61
#define	ACT8865_LDO3_CTRL	0x61
#define	ACT8865_LDO4_VSET	0x64
#define	ACT8865_LDO4_VSET	0x64
#define	ACT8865_LDO4_CTRL	0x65
#define	ACT8865_LDO4_CTRL	0x65
#define	ACT8865_MSTROFF		0x20


/*
/*
 * Field Definitions.
 * Field Definitions.
@@ -98,6 +101,8 @@


struct act8865 {
struct act8865 {
	struct regmap *regmap;
	struct regmap *regmap;
	int off_reg;
	int off_mask;
};
};


static const struct regmap_config act8865_regmap_config = {
static const struct regmap_config act8865_regmap_config = {
@@ -275,6 +280,16 @@ static struct regulator_init_data
	return NULL;
	return NULL;
}
}


static struct i2c_client *act8865_i2c_client;
static void act8865_power_off(void)
{
	struct act8865 *act8865;

	act8865 = i2c_get_clientdata(act8865_i2c_client);
	regmap_write(act8865->regmap, act8865->off_reg, act8865->off_mask);
	while (1);
}

static int act8865_pmic_probe(struct i2c_client *client,
static int act8865_pmic_probe(struct i2c_client *client,
			      const struct i2c_device_id *i2c_id)
			      const struct i2c_device_id *i2c_id)
{
{
@@ -285,6 +300,7 @@ static int act8865_pmic_probe(struct i2c_client *client,
	int i, ret, num_regulators;
	int i, ret, num_regulators;
	struct act8865 *act8865;
	struct act8865 *act8865;
	unsigned long type;
	unsigned long type;
	int off_reg, off_mask;


	pdata = dev_get_platdata(dev);
	pdata = dev_get_platdata(dev);


@@ -304,10 +320,14 @@ static int act8865_pmic_probe(struct i2c_client *client,
	case ACT8846:
	case ACT8846:
		regulators = act8846_regulators;
		regulators = act8846_regulators;
		num_regulators = ARRAY_SIZE(act8846_regulators);
		num_regulators = ARRAY_SIZE(act8846_regulators);
		off_reg = ACT8846_GLB_OFF_CTRL;
		off_mask = ACT8846_OFF_SYSMASK;
		break;
		break;
	case ACT8865:
	case ACT8865:
		regulators = act8865_regulators;
		regulators = act8865_regulators;
		num_regulators = ARRAY_SIZE(act8865_regulators);
		num_regulators = ARRAY_SIZE(act8865_regulators);
		off_reg = ACT8865_SYS_CTRL;
		off_mask = ACT8865_MSTROFF;
		break;
		break;
	default:
	default:
		dev_err(dev, "invalid device id %lu\n", type);
		dev_err(dev, "invalid device id %lu\n", type);
@@ -345,6 +365,17 @@ static int act8865_pmic_probe(struct i2c_client *client,
		return ret;
		return ret;
	}
	}


	if (of_system_has_poweroff_source(dev->of_node)) {
		if (!pm_power_off) {
			act8865_i2c_client = client;
			act8865->off_reg = off_reg;
			act8865->off_mask = off_mask;
			pm_power_off = act8865_power_off;
		} else {
			dev_err(dev, "Failed to set poweroff capability, already defined\n");
		}
	}

	/* Finally register devices */
	/* Finally register devices */
	for (i = 0; i < num_regulators; i++) {
	for (i = 0; i < num_regulators; i++) {
		const struct regulator_desc *desc = &regulators[i];
		const struct regulator_desc *desc = &regulators[i];