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

Commit d700b056 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull regulator updates from Mark Brown:
 "Another release, another set of regulator updates.  Not much of it is
  showing up in the code yet but there's been a lot of discussion going
  on about how to enhance the regulator API to work better with modern
  SoCs which have a microcontroller sitting between Linux and the
  hardware.

  I'm hopeful that'll start to come through into mainline for v4.2 but
  it's not quite there for v4.1 - what we do have (along with the usual
  small updates is) is:

   - work from Bjorn Andersson on refactoring the configuration of
     regulator loading interfaces to be useful for use with
     microcontrollers, the existing interfaces were never actually
     useful for anything as-is since nobody was willing to put enough
     data into public code.

   - a summary tree display in debugfs from Heiko Stübner.

   - support for act6000 regulators"

* tag 'regulator-v4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (34 commits)
  regulator: max8660: Handle empty regulator data
  regulator: output current-limit for all regulators in summary
  regulator: add a summary tree in debugfs
  regulator: qcom: Tidy up probe()
  regulator: qcom: Rework to single platform device
  regulator: qcom: Refactor of-parsing code
  regulator: qcom: Don't enable DRMS in driver
  regulator: max8660: fix assignment of pdata to data that becomes dead
  regulator: Defer lookup of supply to regulator_get
  mfd: max77693: Remove unused structures
  regulator: max77693: Let core parse DT and drop board files support
  regulator: Ensure unique regulator debugfs directory names
  regulator: stw481x: Remove unused fields from struct stw481x
  regulator: palmas: Add has_regen3 check for TPS659038
  regulator: constify of_device_id array
  regulator: fixes for regulator_set_optimum_mode name change
  regulator: Drop temporary regulator_set_optimum_mode wrapper
  usb: phy: phy-msm-usb: Rename regulator_set_optimum_mode
  usb: phy: ab8500-usb: Rename regulator_set_optimum_mode
  ufs: Rename of regulator_set_optimum_mode
  ...
parents 0055dc5b 4ec0853a
Loading
Loading
Loading
Loading
+26 −1
Original line number Original line Diff line number Diff line
@@ -2,13 +2,35 @@ ACT88xx regulators
-------------------
-------------------


Required properties:
Required properties:
- compatible: "active-semi,act8846" or "active-semi,act8865"
- compatible: "active-semi,act8846" or "active-semi,act8865" or "active-semi,act8600"
- reg: I2C slave address
- reg: I2C slave address


Optional properties:
Optional properties:
- system-power-controller: Telling whether or not this pmic is controlling
- system-power-controller: Telling whether or not this pmic is controlling
  the system power. See Documentation/devicetree/bindings/power/power-controller.txt .
  the system power. See Documentation/devicetree/bindings/power/power-controller.txt .


Optional input supply properties:
- for act8600:
  - vp1-supply: The input supply for DCDC_REG1
  - vp2-supply: The input supply for DCDC_REG2
  - vp3-supply: The input supply for DCDC_REG3
  - inl-supply: The input supply for LDO_REG5, LDO_REG6, LDO_REG7 and LDO_REG8
  SUDCDC_REG4, LDO_REG9 and LDO_REG10 do not have separate supplies.
- for act8846:
  - vp1-supply: The input supply for REG1
  - vp2-supply: The input supply for REG2
  - vp3-supply: The input supply for REG3
  - vp4-supply: The input supply for REG4
  - inl1-supply: The input supply for REG5, REG6 and REG7
  - inl2-supply: The input supply for REG8 and LDO_REG9
  - inl3-supply: The input supply for REG10, REG11 and REG12
- for act8865:
  - vp1-supply: The input supply for DCDC_REG1
  - vp2-supply: The input supply for DCDC_REG2
  - vp3-supply: The input supply for DCDC_REG3
  - inl45-supply: The input supply for LDO_REG1 and LDO_REG2
  - inl67-supply: The input supply for LDO_REG3 and LDO_REG4

Any standard regulator properties can be used to configure the single regulator.
Any standard regulator properties can be used to configure the single regulator.


The valid names for regulators are:
The valid names for regulators are:
@@ -16,6 +38,9 @@ The valid names for regulators are:
	REG1, REG2, REG3, REG4, REG5, REG6, REG7, REG8, REG9, REG10, REG11, REG12
	REG1, REG2, REG3, REG4, REG5, REG6, REG7, REG8, REG9, REG10, REG11, REG12
	- for act8865:
	- for act8865:
	DCDC_REG1, DCDC_REG2, DCDC_REG3, LDO_REG1, LDO_REG2, LDO_REG3, LDO_REG4.
	DCDC_REG1, DCDC_REG2, DCDC_REG3, LDO_REG1, LDO_REG2, LDO_REG3, LDO_REG4.
	- for act8600:
	DCDC_REG1, DCDC_REG2, DCDC_REG3, SUDCDC_REG4, LDO_REG5, LDO_REG6, LDO_REG7,
	LDO_REG8, LDO_REG9, LDO_REG10,


Example:
Example:
--------
--------
+1 −1
Original line number Original line Diff line number Diff line
@@ -137,7 +137,7 @@ Indirect operating mode control.
Consumer drivers can request a change in their supply regulator operating mode
Consumer drivers can request a change in their supply regulator operating mode
by calling :-
by calling :-


int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
int regulator_set_load(struct regulator *regulator, int load_uA);


This will cause the core to recalculate the total load on the regulator (based
This will cause the core to recalculate the total load on the regulator (based
on all its consumers) and change operating mode (if necessary and permitted)
on all its consumers) and change operating mode (if necessary and permitted)
+3 −3
Original line number Original line Diff line number Diff line
@@ -332,7 +332,7 @@ static int edp_regulator_enable(struct edp_ctrl *ctrl)
		goto vdda_set_fail;
		goto vdda_set_fail;
	}
	}


	ret = regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_ON_LOAD);
	ret = regulator_set_load(ctrl->vdda_vreg, VDDA_UA_ON_LOAD);
	if (ret < 0) {
	if (ret < 0) {
		pr_err("%s: vdda_vreg set regulator mode failed.\n", __func__);
		pr_err("%s: vdda_vreg set regulator mode failed.\n", __func__);
		goto vdda_set_fail;
		goto vdda_set_fail;
@@ -356,7 +356,7 @@ static int edp_regulator_enable(struct edp_ctrl *ctrl)
lvl_enable_fail:
lvl_enable_fail:
	regulator_disable(ctrl->vdda_vreg);
	regulator_disable(ctrl->vdda_vreg);
vdda_enable_fail:
vdda_enable_fail:
	regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD);
	regulator_set_load(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD);
vdda_set_fail:
vdda_set_fail:
	return ret;
	return ret;
}
}
@@ -365,7 +365,7 @@ static void edp_regulator_disable(struct edp_ctrl *ctrl)
{
{
	regulator_disable(ctrl->lvl_vreg);
	regulator_disable(ctrl->lvl_vreg);
	regulator_disable(ctrl->vdda_vreg);
	regulator_disable(ctrl->vdda_vreg);
	regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD);
	regulator_set_load(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD);
}
}


static int edp_gpio_config(struct edp_ctrl *ctrl)
static int edp_gpio_config(struct edp_ctrl *ctrl)
+2 −2
Original line number Original line Diff line number Diff line
@@ -346,10 +346,10 @@ int ufs_qcom_phy_cfg_vreg(struct phy *phy,
			goto out;
			goto out;
		}
		}
		uA_load = on ? vreg->max_uA : 0;
		uA_load = on ? vreg->max_uA : 0;
		ret = regulator_set_optimum_mode(reg, uA_load);
		ret = regulator_set_load(reg, uA_load);
		if (ret >= 0) {
		if (ret >= 0) {
			/*
			/*
			 * regulator_set_optimum_mode() returns new regulator
			 * regulator_set_load() returns new regulator
			 * mode upon success.
			 * mode upon success.
			 */
			 */
			ret = 0;
			ret = 0;
+140 −21
Original line number Original line Diff line number Diff line
@@ -28,6 +28,35 @@
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regmap.h>
#include <linux/regmap.h>


/*
 * ACT8600 Global Register Map.
 */
#define ACT8600_SYS_MODE	0x00
#define ACT8600_SYS_CTRL	0x01
#define ACT8600_DCDC1_VSET	0x10
#define ACT8600_DCDC1_CTRL	0x12
#define ACT8600_DCDC2_VSET	0x20
#define ACT8600_DCDC2_CTRL	0x22
#define ACT8600_DCDC3_VSET	0x30
#define ACT8600_DCDC3_CTRL	0x32
#define ACT8600_SUDCDC4_VSET	0x40
#define ACT8600_SUDCDC4_CTRL	0x41
#define ACT8600_LDO5_VSET	0x50
#define ACT8600_LDO5_CTRL	0x51
#define ACT8600_LDO6_VSET	0x60
#define ACT8600_LDO6_CTRL	0x61
#define ACT8600_LDO7_VSET	0x70
#define ACT8600_LDO7_CTRL	0x71
#define ACT8600_LDO8_VSET	0x80
#define ACT8600_LDO8_CTRL	0x81
#define ACT8600_LDO910_CTRL	0x91
#define ACT8600_APCH0		0xA1
#define ACT8600_APCH1		0xA8
#define ACT8600_APCH2		0xA9
#define ACT8600_APCH_STAT	0xAA
#define ACT8600_OTG0		0xB0
#define ACT8600_OTG1		0xB2

/*
/*
 * ACT8846 Global Register Map.
 * ACT8846 Global Register Map.
 */
 */
@@ -94,10 +123,15 @@
#define	ACT8865_ENA		0x80	/* ON - [7] */
#define	ACT8865_ENA		0x80	/* ON - [7] */
#define	ACT8865_VSEL_MASK	0x3F	/* VSET - [5:0] */
#define	ACT8865_VSEL_MASK	0x3F	/* VSET - [5:0] */



#define ACT8600_LDO10_ENA		0x40	/* ON - [6] */
#define ACT8600_SUDCDC_VSEL_MASK	0xFF	/* SUDCDC VSET - [7:0] */

/*
/*
 * ACT8865 voltage number
 * ACT8865 voltage number
 */
 */
#define	ACT8865_VOLTAGE_NUM	64
#define	ACT8865_VOLTAGE_NUM	64
#define ACT8600_SUDCDC_VOLTAGE_NUM	255


struct act8865 {
struct act8865 {
	struct regmap *regmap;
	struct regmap *regmap;
@@ -116,6 +150,13 @@ static const struct regulator_linear_range act8865_voltage_ranges[] = {
	REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000),
	REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000),
};
};


static const struct regulator_linear_range act8600_sudcdc_voltage_ranges[] = {
	REGULATOR_LINEAR_RANGE(3000000, 0, 63, 0),
	REGULATOR_LINEAR_RANGE(3000000, 64, 159, 100000),
	REGULATOR_LINEAR_RANGE(12600000, 160, 191, 200000),
	REGULATOR_LINEAR_RANGE(19000000, 191, 255, 400000),
};

static struct regulator_ops act8865_ops = {
static struct regulator_ops act8865_ops = {
	.list_voltage		= regulator_list_voltage_linear_range,
	.list_voltage		= regulator_list_voltage_linear_range,
	.map_voltage		= regulator_map_voltage_linear_range,
	.map_voltage		= regulator_map_voltage_linear_range,
@@ -126,9 +167,16 @@ static struct regulator_ops act8865_ops = {
	.is_enabled		= regulator_is_enabled_regmap,
	.is_enabled		= regulator_is_enabled_regmap,
};
};


#define ACT88xx_REG(_name, _family, _id, _vsel_reg)			\
static struct regulator_ops act8865_ldo_ops = {
	.enable			= regulator_enable_regmap,
	.disable		= regulator_disable_regmap,
	.is_enabled		= regulator_is_enabled_regmap,
};

#define ACT88xx_REG(_name, _family, _id, _vsel_reg, _supply)		\
	[_family##_ID_##_id] = {					\
	[_family##_ID_##_id] = {					\
		.name			= _name,			\
		.name			= _name,			\
		.supply_name		= _supply,			\
		.id			= _family##_ID_##_id,		\
		.id			= _family##_ID_##_id,		\
		.type			= REGULATOR_VOLTAGE,		\
		.type			= REGULATOR_VOLTAGE,		\
		.ops			= &act8865_ops,			\
		.ops			= &act8865_ops,			\
@@ -142,33 +190,80 @@ static struct regulator_ops act8865_ops = {
		.owner			= THIS_MODULE,			\
		.owner			= THIS_MODULE,			\
	}
	}


static const struct regulator_desc act8600_regulators[] = {
	ACT88xx_REG("DCDC1", ACT8600, DCDC1, VSET, "vp1"),
	ACT88xx_REG("DCDC2", ACT8600, DCDC2, VSET, "vp2"),
	ACT88xx_REG("DCDC3", ACT8600, DCDC3, VSET, "vp3"),
	{
		.name = "SUDCDC_REG4",
		.id = ACT8600_ID_SUDCDC4,
		.ops = &act8865_ops,
		.type = REGULATOR_VOLTAGE,
		.n_voltages = ACT8600_SUDCDC_VOLTAGE_NUM,
		.linear_ranges = act8600_sudcdc_voltage_ranges,
		.n_linear_ranges = ARRAY_SIZE(act8600_sudcdc_voltage_ranges),
		.vsel_reg = ACT8600_SUDCDC4_VSET,
		.vsel_mask = ACT8600_SUDCDC_VSEL_MASK,
		.enable_reg = ACT8600_SUDCDC4_CTRL,
		.enable_mask = ACT8865_ENA,
		.owner = THIS_MODULE,
	},
	ACT88xx_REG("LDO5", ACT8600, LDO5, VSET, "inl"),
	ACT88xx_REG("LDO6", ACT8600, LDO6, VSET, "inl"),
	ACT88xx_REG("LDO7", ACT8600, LDO7, VSET, "inl"),
	ACT88xx_REG("LDO8", ACT8600, LDO8, VSET, "inl"),
	{
		.name = "LDO_REG9",
		.id = ACT8600_ID_LDO9,
		.ops = &act8865_ldo_ops,
		.type = REGULATOR_VOLTAGE,
		.n_voltages = 1,
		.fixed_uV = 1800000,
		.enable_reg = ACT8600_LDO910_CTRL,
		.enable_mask = ACT8865_ENA,
		.owner = THIS_MODULE,
	},
	{
		.name = "LDO_REG10",
		.id = ACT8600_ID_LDO10,
		.ops = &act8865_ldo_ops,
		.type = REGULATOR_VOLTAGE,
		.n_voltages = 1,
		.fixed_uV = 1200000,
		.enable_reg = ACT8600_LDO910_CTRL,
		.enable_mask = ACT8600_LDO10_ENA,
		.owner = THIS_MODULE,
	},
};

static const struct regulator_desc act8846_regulators[] = {
static const struct regulator_desc act8846_regulators[] = {
	ACT88xx_REG("REG1", ACT8846, REG1, VSET),
	ACT88xx_REG("REG1", ACT8846, REG1, VSET, "vp1"),
	ACT88xx_REG("REG2", ACT8846, REG2, VSET0),
	ACT88xx_REG("REG2", ACT8846, REG2, VSET0, "vp2"),
	ACT88xx_REG("REG3", ACT8846, REG3, VSET0),
	ACT88xx_REG("REG3", ACT8846, REG3, VSET0, "vp3"),
	ACT88xx_REG("REG4", ACT8846, REG4, VSET0),
	ACT88xx_REG("REG4", ACT8846, REG4, VSET0, "vp4"),
	ACT88xx_REG("REG5", ACT8846, REG5, VSET),
	ACT88xx_REG("REG5", ACT8846, REG5, VSET, "inl1"),
	ACT88xx_REG("REG6", ACT8846, REG6, VSET),
	ACT88xx_REG("REG6", ACT8846, REG6, VSET, "inl1"),
	ACT88xx_REG("REG7", ACT8846, REG7, VSET),
	ACT88xx_REG("REG7", ACT8846, REG7, VSET, "inl1"),
	ACT88xx_REG("REG8", ACT8846, REG8, VSET),
	ACT88xx_REG("REG8", ACT8846, REG8, VSET, "inl2"),
	ACT88xx_REG("REG9", ACT8846, REG9, VSET),
	ACT88xx_REG("REG9", ACT8846, REG9, VSET, "inl2"),
	ACT88xx_REG("REG10", ACT8846, REG10, VSET),
	ACT88xx_REG("REG10", ACT8846, REG10, VSET, "inl3"),
	ACT88xx_REG("REG11", ACT8846, REG11, VSET),
	ACT88xx_REG("REG11", ACT8846, REG11, VSET, "inl3"),
	ACT88xx_REG("REG12", ACT8846, REG12, VSET),
	ACT88xx_REG("REG12", ACT8846, REG12, VSET, "inl3"),
};
};


static const struct regulator_desc act8865_regulators[] = {
static const struct regulator_desc act8865_regulators[] = {
	ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1),
	ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1, "vp1"),
	ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1),
	ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1, "vp2"),
	ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET1),
	ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET1, "vp3"),
	ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET),
	ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET, "inl45"),
	ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET),
	ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET, "inl45"),
	ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET),
	ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET, "inl67"),
	ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET),
	ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET, "inl67"),
};
};


#ifdef CONFIG_OF
#ifdef CONFIG_OF
static const struct of_device_id act8865_dt_ids[] = {
static const struct of_device_id act8865_dt_ids[] = {
	{ .compatible = "active-semi,act8600", .data = (void *)ACT8600 },
	{ .compatible = "active-semi,act8846", .data = (void *)ACT8846 },
	{ .compatible = "active-semi,act8846", .data = (void *)ACT8846 },
	{ .compatible = "active-semi,act8865", .data = (void *)ACT8865 },
	{ .compatible = "active-semi,act8865", .data = (void *)ACT8865 },
	{ }
	{ }
@@ -200,6 +295,19 @@ static struct of_regulator_match act8865_matches[] = {
	[ACT8865_ID_LDO4]	= { .name = "LDO_REG4"},
	[ACT8865_ID_LDO4]	= { .name = "LDO_REG4"},
};
};


static struct of_regulator_match act8600_matches[] = {
	[ACT8600_ID_DCDC1]	= { .name = "DCDC_REG1"},
	[ACT8600_ID_DCDC2]	= { .name = "DCDC_REG2"},
	[ACT8600_ID_DCDC3]	= { .name = "DCDC_REG3"},
	[ACT8600_ID_SUDCDC4]	= { .name = "SUDCDC_REG4"},
	[ACT8600_ID_LDO5]	= { .name = "LDO_REG5"},
	[ACT8600_ID_LDO6]	= { .name = "LDO_REG6"},
	[ACT8600_ID_LDO7]	= { .name = "LDO_REG7"},
	[ACT8600_ID_LDO8]	= { .name = "LDO_REG8"},
	[ACT8600_ID_LDO9]	= { .name = "LDO_REG9"},
	[ACT8600_ID_LDO10]	= { .name = "LDO_REG10"},
};

static int act8865_pdata_from_dt(struct device *dev,
static int act8865_pdata_from_dt(struct device *dev,
				 struct device_node **of_node,
				 struct device_node **of_node,
				 struct act8865_platform_data *pdata,
				 struct act8865_platform_data *pdata,
@@ -217,6 +325,10 @@ static int act8865_pdata_from_dt(struct device *dev,
	}
	}


	switch (type) {
	switch (type) {
	case ACT8600:
		matches = act8600_matches;
		num_matches = ARRAY_SIZE(act8600_matches);
		break;
	case ACT8846:
	case ACT8846:
		matches = act8846_matches;
		matches = act8846_matches;
		num_matches = ARRAY_SIZE(act8846_matches);
		num_matches = ARRAY_SIZE(act8846_matches);
@@ -317,6 +429,12 @@ static int act8865_pmic_probe(struct i2c_client *client,
	}
	}


	switch (type) {
	switch (type) {
	case ACT8600:
		regulators = act8600_regulators;
		num_regulators = ARRAY_SIZE(act8600_regulators);
		off_reg = -1;
		off_mask = -1;
		break;
	case ACT8846:
	case ACT8846:
		regulators = act8846_regulators;
		regulators = act8846_regulators;
		num_regulators = ARRAY_SIZE(act8846_regulators);
		num_regulators = ARRAY_SIZE(act8846_regulators);
@@ -366,7 +484,7 @@ static int act8865_pmic_probe(struct i2c_client *client,
	}
	}


	if (of_device_is_system_power_controller(dev->of_node)) {
	if (of_device_is_system_power_controller(dev->of_node)) {
		if (!pm_power_off) {
		if (!pm_power_off && (off_reg > 0)) {
			act8865_i2c_client = client;
			act8865_i2c_client = client;
			act8865->off_reg = off_reg;
			act8865->off_reg = off_reg;
			act8865->off_mask = off_mask;
			act8865->off_mask = off_mask;
@@ -402,6 +520,7 @@ static int act8865_pmic_probe(struct i2c_client *client,
}
}


static const struct i2c_device_id act8865_ids[] = {
static const struct i2c_device_id act8865_ids[] = {
	{ .name = "act8600", .driver_data = ACT8600 },
	{ .name = "act8846", .driver_data = ACT8846 },
	{ .name = "act8846", .driver_data = ACT8846 },
	{ .name = "act8865", .driver_data = ACT8865 },
	{ .name = "act8865", .driver_data = ACT8865 },
	{ },
	{ },
Loading