regulator: Updates for v4.1
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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJVK+w1AAoJECTWi3JdVIfQeg0H/2ckXZEQWH/yzAz7JgAoSmVr +y8pvfNLOyOVVulFI0QBOaCAoyJNXNPNqDrkYaTykMIwX4y+weoDqfH/LMiGpnXl D3aAgdLPSWLTUMteCs9KIHesnOdjKclZUjnbskJgnmeMCW23WcX9T1lBVoLBVdlo p+oe287rhEwF6j2t63aLwFv8QGpamgVQ/8mXXs8EK7L5E3OO262SwLaXRBAtWk30 Eb68qXrbbkrDunEL6Hjggj5pFi93M4eNfQHpzVmjidvwz1g4JpLtWHW4XpQlXoHJ G2rlVwNFsyedT1MX2ByKhrIPu5kq5pt0/rjear34G3vuEnQm7vR3aW/38AOxffs= =t8gT -----END PGP SIGNATURE----- Merge tag 'regulator-v4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator 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 ...
This commit is contained in:
commit
d700b05671
|
@ -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:
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 },
|
||||||
{ },
|
{ },
|
||||||
|
|
|
@ -282,6 +282,9 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
|
||||||
arizona->external_dcvdd = true;
|
arizona->external_dcvdd = true;
|
||||||
|
|
||||||
ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config);
|
ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config);
|
||||||
|
|
||||||
|
of_node_put(config.of_node);
|
||||||
|
|
||||||
if (IS_ERR(ldo1->regulator)) {
|
if (IS_ERR(ldo1->regulator)) {
|
||||||
ret = PTR_ERR(ldo1->regulator);
|
ret = PTR_ERR(ldo1->regulator);
|
||||||
dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n",
|
dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n",
|
||||||
|
@ -289,8 +292,6 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
of_node_put(config.of_node);
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, ldo1);
|
platform_set_drvdata(pdev, ldo1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -284,6 +284,9 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
|
||||||
micsupp->regulator = devm_regulator_register(&pdev->dev,
|
micsupp->regulator = devm_regulator_register(&pdev->dev,
|
||||||
desc,
|
desc,
|
||||||
&config);
|
&config);
|
||||||
|
|
||||||
|
of_node_put(config.of_node);
|
||||||
|
|
||||||
if (IS_ERR(micsupp->regulator)) {
|
if (IS_ERR(micsupp->regulator)) {
|
||||||
ret = PTR_ERR(micsupp->regulator);
|
ret = PTR_ERR(micsupp->regulator);
|
||||||
dev_err(arizona->dev, "Failed to register mic supply: %d\n",
|
dev_err(arizona->dev, "Failed to register mic supply: %d\n",
|
||||||
|
@ -291,8 +294,6 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
of_node_put(config.of_node);
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, micsupp);
|
platform_set_drvdata(pdev, micsupp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -648,10 +648,12 @@ static int drms_uA_update(struct regulator_dev *rdev)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!rdev->desc->ops->get_optimum_mode)
|
if (!rdev->desc->ops->get_optimum_mode &&
|
||||||
|
!rdev->desc->ops->set_load)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!rdev->desc->ops->set_mode)
|
if (!rdev->desc->ops->set_mode &&
|
||||||
|
!rdev->desc->ops->set_load)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* get output voltage */
|
/* get output voltage */
|
||||||
|
@ -676,22 +678,29 @@ static int drms_uA_update(struct regulator_dev *rdev)
|
||||||
list_for_each_entry(sibling, &rdev->consumer_list, list)
|
list_for_each_entry(sibling, &rdev->consumer_list, list)
|
||||||
current_uA += sibling->uA_load;
|
current_uA += sibling->uA_load;
|
||||||
|
|
||||||
/* now get the optimum mode for our new total regulator load */
|
if (rdev->desc->ops->set_load) {
|
||||||
mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV,
|
/* set the optimum mode for our new total regulator load */
|
||||||
output_uV, current_uA);
|
err = rdev->desc->ops->set_load(rdev, current_uA);
|
||||||
|
if (err < 0)
|
||||||
|
rdev_err(rdev, "failed to set load %d\n", current_uA);
|
||||||
|
} else {
|
||||||
|
/* now get the optimum mode for our new total regulator load */
|
||||||
|
mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV,
|
||||||
|
output_uV, current_uA);
|
||||||
|
|
||||||
/* check the new mode is allowed */
|
/* check the new mode is allowed */
|
||||||
err = regulator_mode_constrain(rdev, &mode);
|
err = regulator_mode_constrain(rdev, &mode);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
|
rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
|
||||||
current_uA, input_uV, output_uV);
|
current_uA, input_uV, output_uV);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = rdev->desc->ops->set_mode(rdev, mode);
|
||||||
|
if (err < 0)
|
||||||
|
rdev_err(rdev, "failed to set optimum mode %x\n", mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = rdev->desc->ops->set_mode(rdev, mode);
|
|
||||||
if (err < 0)
|
|
||||||
rdev_err(rdev, "failed to set optimum mode %x\n", mode);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1316,6 +1325,54 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int regulator_resolve_supply(struct regulator_dev *rdev)
|
||||||
|
{
|
||||||
|
struct regulator_dev *r;
|
||||||
|
struct device *dev = rdev->dev.parent;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* No supply to resovle? */
|
||||||
|
if (!rdev->supply_name)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Supply already resolved? */
|
||||||
|
if (rdev->supply)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = regulator_dev_lookup(dev, rdev->supply_name, &ret);
|
||||||
|
if (ret == -ENODEV) {
|
||||||
|
/*
|
||||||
|
* No supply was specified for this regulator and
|
||||||
|
* there will never be one.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!r) {
|
||||||
|
dev_err(dev, "Failed to resolve %s-supply for %s\n",
|
||||||
|
rdev->supply_name, rdev->desc->name);
|
||||||
|
return -EPROBE_DEFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recursively resolve the supply of the supply */
|
||||||
|
ret = regulator_resolve_supply(r);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = set_supply(rdev, r);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Cascade always-on state to supply */
|
||||||
|
if (_regulator_is_enabled(rdev)) {
|
||||||
|
ret = regulator_enable(rdev->supply);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Internal regulator request function */
|
/* Internal regulator request function */
|
||||||
static struct regulator *_regulator_get(struct device *dev, const char *id,
|
static struct regulator *_regulator_get(struct device *dev, const char *id,
|
||||||
bool exclusive, bool allow_dummy)
|
bool exclusive, bool allow_dummy)
|
||||||
|
@ -1385,6 +1442,12 @@ found:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = regulator_resolve_supply(rdev);
|
||||||
|
if (ret < 0) {
|
||||||
|
regulator = ERR_PTR(ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!try_module_get(rdev->owner))
|
if (!try_module_get(rdev->owner))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -2998,7 +3061,7 @@ unsigned int regulator_get_mode(struct regulator *regulator)
|
||||||
EXPORT_SYMBOL_GPL(regulator_get_mode);
|
EXPORT_SYMBOL_GPL(regulator_get_mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* regulator_set_optimum_mode - set regulator optimum operating mode
|
* regulator_set_load - set regulator load
|
||||||
* @regulator: regulator source
|
* @regulator: regulator source
|
||||||
* @uA_load: load current
|
* @uA_load: load current
|
||||||
*
|
*
|
||||||
|
@ -3021,9 +3084,9 @@ EXPORT_SYMBOL_GPL(regulator_get_mode);
|
||||||
* DRMS will sum the total requested load on the regulator and change
|
* DRMS will sum the total requested load on the regulator and change
|
||||||
* to the most efficient operating mode if platform constraints allow.
|
* to the most efficient operating mode if platform constraints allow.
|
||||||
*
|
*
|
||||||
* Returns the new regulator mode or error.
|
* On error a negative errno is returned.
|
||||||
*/
|
*/
|
||||||
int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
|
int regulator_set_load(struct regulator *regulator, int uA_load)
|
||||||
{
|
{
|
||||||
struct regulator_dev *rdev = regulator->rdev;
|
struct regulator_dev *rdev = regulator->rdev;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -3035,7 +3098,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
|
EXPORT_SYMBOL_GPL(regulator_set_load);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* regulator_allow_bypass - allow the regulator to go into bypass mode
|
* regulator_allow_bypass - allow the regulator to go into bypass mode
|
||||||
|
@ -3499,7 +3562,18 @@ static struct class regulator_class = {
|
||||||
|
|
||||||
static void rdev_init_debugfs(struct regulator_dev *rdev)
|
static void rdev_init_debugfs(struct regulator_dev *rdev)
|
||||||
{
|
{
|
||||||
rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root);
|
struct device *parent = rdev->dev.parent;
|
||||||
|
const char *rname = rdev_get_name(rdev);
|
||||||
|
char name[NAME_MAX];
|
||||||
|
|
||||||
|
/* Avoid duplicate debugfs directory names */
|
||||||
|
if (parent && rname == rdev->desc->name) {
|
||||||
|
snprintf(name, sizeof(name), "%s-%s", dev_name(parent),
|
||||||
|
rname);
|
||||||
|
rname = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
rdev->debugfs = debugfs_create_dir(rname, debugfs_root);
|
||||||
if (!rdev->debugfs) {
|
if (!rdev->debugfs) {
|
||||||
rdev_warn(rdev, "Failed to create debugfs directory\n");
|
rdev_warn(rdev, "Failed to create debugfs directory\n");
|
||||||
return;
|
return;
|
||||||
|
@ -3533,7 +3607,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
|
||||||
struct regulator_dev *rdev;
|
struct regulator_dev *rdev;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
const char *supply = NULL;
|
|
||||||
|
|
||||||
if (regulator_desc == NULL || cfg == NULL)
|
if (regulator_desc == NULL || cfg == NULL)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
@ -3641,41 +3714,10 @@ regulator_register(const struct regulator_desc *regulator_desc,
|
||||||
goto scrub;
|
goto scrub;
|
||||||
|
|
||||||
if (init_data && init_data->supply_regulator)
|
if (init_data && init_data->supply_regulator)
|
||||||
supply = init_data->supply_regulator;
|
rdev->supply_name = init_data->supply_regulator;
|
||||||
else if (regulator_desc->supply_name)
|
else if (regulator_desc->supply_name)
|
||||||
supply = regulator_desc->supply_name;
|
rdev->supply_name = regulator_desc->supply_name;
|
||||||
|
|
||||||
if (supply) {
|
|
||||||
struct regulator_dev *r;
|
|
||||||
|
|
||||||
r = regulator_dev_lookup(dev, supply, &ret);
|
|
||||||
|
|
||||||
if (ret == -ENODEV) {
|
|
||||||
/*
|
|
||||||
* No supply was specified for this regulator and
|
|
||||||
* there will never be one.
|
|
||||||
*/
|
|
||||||
ret = 0;
|
|
||||||
goto add_dev;
|
|
||||||
} else if (!r) {
|
|
||||||
dev_err(dev, "Failed to find supply %s\n", supply);
|
|
||||||
ret = -EPROBE_DEFER;
|
|
||||||
goto scrub;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = set_supply(rdev, r);
|
|
||||||
if (ret < 0)
|
|
||||||
goto scrub;
|
|
||||||
|
|
||||||
/* Enable supply if rail is enabled */
|
|
||||||
if (_regulator_is_enabled(rdev)) {
|
|
||||||
ret = regulator_enable(rdev->supply);
|
|
||||||
if (ret < 0)
|
|
||||||
goto scrub;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
add_dev:
|
|
||||||
/* add consumers devices */
|
/* add consumers devices */
|
||||||
if (init_data) {
|
if (init_data) {
|
||||||
for (i = 0; i < init_data->num_consumer_supplies; i++) {
|
for (i = 0; i < init_data->num_consumer_supplies; i++) {
|
||||||
|
@ -3702,8 +3744,6 @@ unset_supplies:
|
||||||
unset_regulator_supplies(rdev);
|
unset_regulator_supplies(rdev);
|
||||||
|
|
||||||
scrub:
|
scrub:
|
||||||
if (rdev->supply)
|
|
||||||
_regulator_put(rdev->supply);
|
|
||||||
regulator_ena_gpio_free(rdev);
|
regulator_ena_gpio_free(rdev);
|
||||||
kfree(rdev->constraints);
|
kfree(rdev->constraints);
|
||||||
wash:
|
wash:
|
||||||
|
@ -3936,6 +3976,110 @@ static const struct file_operations supply_map_fops = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
static void regulator_summary_show_subtree(struct seq_file *s,
|
||||||
|
struct regulator_dev *rdev,
|
||||||
|
int level)
|
||||||
|
{
|
||||||
|
struct list_head *list = s->private;
|
||||||
|
struct regulator_dev *child;
|
||||||
|
struct regulation_constraints *c;
|
||||||
|
struct regulator *consumer;
|
||||||
|
|
||||||
|
if (!rdev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
seq_printf(s, "%*s%-*s %3d %4d %6d ",
|
||||||
|
level * 3 + 1, "",
|
||||||
|
30 - level * 3, rdev_get_name(rdev),
|
||||||
|
rdev->use_count, rdev->open_count, rdev->bypass_count);
|
||||||
|
|
||||||
|
seq_printf(s, "%5dmV ", _regulator_get_voltage(rdev) / 1000);
|
||||||
|
seq_printf(s, "%5dmA ", _regulator_get_current_limit(rdev) / 1000);
|
||||||
|
|
||||||
|
c = rdev->constraints;
|
||||||
|
if (c) {
|
||||||
|
switch (rdev->desc->type) {
|
||||||
|
case REGULATOR_VOLTAGE:
|
||||||
|
seq_printf(s, "%5dmV %5dmV ",
|
||||||
|
c->min_uV / 1000, c->max_uV / 1000);
|
||||||
|
break;
|
||||||
|
case REGULATOR_CURRENT:
|
||||||
|
seq_printf(s, "%5dmA %5dmA ",
|
||||||
|
c->min_uA / 1000, c->max_uA / 1000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
seq_puts(s, "\n");
|
||||||
|
|
||||||
|
list_for_each_entry(consumer, &rdev->consumer_list, list) {
|
||||||
|
if (consumer->dev->class == ®ulator_class)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
seq_printf(s, "%*s%-*s ",
|
||||||
|
(level + 1) * 3 + 1, "",
|
||||||
|
30 - (level + 1) * 3, dev_name(consumer->dev));
|
||||||
|
|
||||||
|
switch (rdev->desc->type) {
|
||||||
|
case REGULATOR_VOLTAGE:
|
||||||
|
seq_printf(s, "%37dmV %5dmV",
|
||||||
|
consumer->min_uV / 1000,
|
||||||
|
consumer->max_uV / 1000);
|
||||||
|
break;
|
||||||
|
case REGULATOR_CURRENT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
seq_puts(s, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(child, list, list) {
|
||||||
|
/* handle only non-root regulators supplied by current rdev */
|
||||||
|
if (!child->supply || child->supply->rdev != rdev)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
regulator_summary_show_subtree(s, child, level + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regulator_summary_show(struct seq_file *s, void *data)
|
||||||
|
{
|
||||||
|
struct list_head *list = s->private;
|
||||||
|
struct regulator_dev *rdev;
|
||||||
|
|
||||||
|
seq_puts(s, " regulator use open bypass voltage current min max\n");
|
||||||
|
seq_puts(s, "-------------------------------------------------------------------------------\n");
|
||||||
|
|
||||||
|
mutex_lock(®ulator_list_mutex);
|
||||||
|
|
||||||
|
list_for_each_entry(rdev, list, list) {
|
||||||
|
if (rdev->supply)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
regulator_summary_show_subtree(s, rdev, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(®ulator_list_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regulator_summary_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, regulator_summary_show, inode->i_private);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct file_operations regulator_summary_fops = {
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
.open = regulator_summary_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
static int __init regulator_init(void)
|
static int __init regulator_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -3949,6 +4093,9 @@ static int __init regulator_init(void)
|
||||||
debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
|
debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
|
||||||
&supply_map_fops);
|
&supply_map_fops);
|
||||||
|
|
||||||
|
debugfs_create_file("regulator_summary", 0444, debugfs_root,
|
||||||
|
®ulator_list, ®ulator_summary_fops);
|
||||||
|
|
||||||
regulator_dummy_init();
|
regulator_dummy_init();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -305,8 +305,7 @@ static irqreturn_t da9211_irq_handler(int irq, void *data)
|
||||||
|
|
||||||
if (reg_val & DA9211_E_OV_CURR_A) {
|
if (reg_val & DA9211_E_OV_CURR_A) {
|
||||||
regulator_notifier_call_chain(chip->rdev[0],
|
regulator_notifier_call_chain(chip->rdev[0],
|
||||||
REGULATOR_EVENT_OVER_CURRENT,
|
REGULATOR_EVENT_OVER_CURRENT, NULL);
|
||||||
rdev_get_drvdata(chip->rdev[0]));
|
|
||||||
|
|
||||||
err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
|
err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
|
||||||
DA9211_E_OV_CURR_A);
|
DA9211_E_OV_CURR_A);
|
||||||
|
@ -318,8 +317,7 @@ static irqreturn_t da9211_irq_handler(int irq, void *data)
|
||||||
|
|
||||||
if (reg_val & DA9211_E_OV_CURR_B) {
|
if (reg_val & DA9211_E_OV_CURR_B) {
|
||||||
regulator_notifier_call_chain(chip->rdev[1],
|
regulator_notifier_call_chain(chip->rdev[1],
|
||||||
REGULATOR_EVENT_OVER_CURRENT,
|
REGULATOR_EVENT_OVER_CURRENT, NULL);
|
||||||
rdev_get_drvdata(chip->rdev[1]));
|
|
||||||
|
|
||||||
err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
|
err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
|
||||||
DA9211_E_OV_CURR_B);
|
DA9211_E_OV_CURR_B);
|
||||||
|
@ -344,7 +342,7 @@ static int da9211_regulator_init(struct da9211 *chip)
|
||||||
|
|
||||||
ret = regmap_read(chip->regmap, DA9211_REG_CONFIG_E, &data);
|
ret = regmap_read(chip->regmap, DA9211_REG_CONFIG_E, &data);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(chip->dev, "Failed to read CONTROL_E reg: %d\n", ret);
|
dev_err(chip->dev, "Failed to read CONFIG_E reg: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,14 +95,9 @@ void ux500_regulator_resume_debug(void)
|
||||||
|
|
||||||
static int ux500_regulator_power_state_cnt_print(struct seq_file *s, void *p)
|
static int ux500_regulator_power_state_cnt_print(struct seq_file *s, void *p)
|
||||||
{
|
{
|
||||||
struct device *dev = s->private;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
/* print power state count */
|
/* print power state count */
|
||||||
err = seq_printf(s, "ux500-regulator power state count: %i\n",
|
seq_printf(s, "ux500-regulator power state count: %i\n",
|
||||||
power_state_active_get());
|
power_state_active_get());
|
||||||
if (err < 0)
|
|
||||||
dev_err(dev, "seq_printf overflow\n");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -124,19 +119,11 @@ static const struct file_operations ux500_regulator_power_state_cnt_fops = {
|
||||||
|
|
||||||
static int ux500_regulator_status_print(struct seq_file *s, void *p)
|
static int ux500_regulator_status_print(struct seq_file *s, void *p)
|
||||||
{
|
{
|
||||||
struct device *dev = s->private;
|
|
||||||
int err;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* print dump header */
|
/* print dump header */
|
||||||
err = seq_puts(s, "ux500-regulator status:\n");
|
seq_puts(s, "ux500-regulator status:\n");
|
||||||
if (err < 0)
|
seq_printf(s, "%31s : %8s : %8s\n", "current", "before", "after");
|
||||||
dev_err(dev, "seq_puts overflow\n");
|
|
||||||
|
|
||||||
err = seq_printf(s, "%31s : %8s : %8s\n", "current",
|
|
||||||
"before", "after");
|
|
||||||
if (err < 0)
|
|
||||||
dev_err(dev, "seq_printf overflow\n");
|
|
||||||
|
|
||||||
for (i = 0; i < rdebug.num_regulators; i++) {
|
for (i = 0; i < rdebug.num_regulators; i++) {
|
||||||
struct dbx500_regulator_info *info;
|
struct dbx500_regulator_info *info;
|
||||||
|
@ -144,12 +131,11 @@ static int ux500_regulator_status_print(struct seq_file *s, void *p)
|
||||||
info = &rdebug.regulator_array[i];
|
info = &rdebug.regulator_array[i];
|
||||||
|
|
||||||
/* print status */
|
/* print status */
|
||||||
err = seq_printf(s, "%20s : %8s : %8s : %8s\n", info->desc.name,
|
seq_printf(s, "%20s : %8s : %8s : %8s\n",
|
||||||
info->is_enabled ? "enabled" : "disabled",
|
info->desc.name,
|
||||||
rdebug.state_before_suspend[i] ? "enabled" : "disabled",
|
info->is_enabled ? "enabled" : "disabled",
|
||||||
rdebug.state_after_suspend[i] ? "enabled" : "disabled");
|
rdebug.state_before_suspend[i] ? "enabled" : "disabled",
|
||||||
if (err < 0)
|
rdebug.state_after_suspend[i] ? "enabled" : "disabled");
|
||||||
dev_err(dev, "seq_printf overflow\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -413,3 +413,88 @@ void devm_regulator_bulk_unregister_supply_alias(struct device *dev,
|
||||||
devm_regulator_unregister_supply_alias(dev, id[i]);
|
devm_regulator_unregister_supply_alias(dev, id[i]);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(devm_regulator_bulk_unregister_supply_alias);
|
EXPORT_SYMBOL_GPL(devm_regulator_bulk_unregister_supply_alias);
|
||||||
|
|
||||||
|
struct regulator_notifier_match {
|
||||||
|
struct regulator *regulator;
|
||||||
|
struct notifier_block *nb;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int devm_regulator_match_notifier(struct device *dev, void *res,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct regulator_notifier_match *match = res;
|
||||||
|
struct regulator_notifier_match *target = data;
|
||||||
|
|
||||||
|
return match->regulator == target->regulator && match->nb == target->nb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void devm_regulator_destroy_notifier(struct device *dev, void *res)
|
||||||
|
{
|
||||||
|
struct regulator_notifier_match *match = res;
|
||||||
|
|
||||||
|
regulator_unregister_notifier(match->regulator, match->nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* devm_regulator_register_notifier - Resource managed
|
||||||
|
* regulator_register_notifier
|
||||||
|
*
|
||||||
|
* @regulator: regulator source
|
||||||
|
* @nb: notifier block
|
||||||
|
*
|
||||||
|
* The notifier will be registers under the consumer device and be
|
||||||
|
* automatically be unregistered when the source device is unbound.
|
||||||
|
*/
|
||||||
|
int devm_regulator_register_notifier(struct regulator *regulator,
|
||||||
|
struct notifier_block *nb)
|
||||||
|
{
|
||||||
|
struct regulator_notifier_match *match;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
match = devres_alloc(devm_regulator_destroy_notifier,
|
||||||
|
sizeof(struct regulator_notifier_match),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!match)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
match->regulator = regulator;
|
||||||
|
match->nb = nb;
|
||||||
|
|
||||||
|
ret = regulator_register_notifier(regulator, nb);
|
||||||
|
if (ret < 0) {
|
||||||
|
devres_free(match);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
devres_add(regulator->dev, match);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(devm_regulator_register_notifier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* devm_regulator_unregister_notifier - Resource managed
|
||||||
|
* regulator_unregister_notifier()
|
||||||
|
*
|
||||||
|
* @regulator: regulator source
|
||||||
|
* @nb: notifier block
|
||||||
|
*
|
||||||
|
* Unregister a notifier registered with devm_regulator_register_notifier().
|
||||||
|
* Normally this function will not need to be called and the resource
|
||||||
|
* management code will ensure that the resource is freed.
|
||||||
|
*/
|
||||||
|
void devm_regulator_unregister_notifier(struct regulator *regulator,
|
||||||
|
struct notifier_block *nb)
|
||||||
|
{
|
||||||
|
struct regulator_notifier_match match;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
match.regulator = regulator;
|
||||||
|
match.nb = nb;
|
||||||
|
|
||||||
|
rc = devres_release(regulator->dev, devm_regulator_destroy_notifier,
|
||||||
|
devm_regulator_match_notifier, &match);
|
||||||
|
if (rc != 0)
|
||||||
|
WARN_ON(rc);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(devm_regulator_unregister_notifier);
|
||||||
|
|
|
@ -128,6 +128,8 @@ static struct regulator_ops max77693_charger_ops = {
|
||||||
#define regulator_desc_esafeout(_num) { \
|
#define regulator_desc_esafeout(_num) { \
|
||||||
.name = "ESAFEOUT"#_num, \
|
.name = "ESAFEOUT"#_num, \
|
||||||
.id = MAX77693_ESAFEOUT##_num, \
|
.id = MAX77693_ESAFEOUT##_num, \
|
||||||
|
.of_match = of_match_ptr("ESAFEOUT"#_num), \
|
||||||
|
.regulators_node = of_match_ptr("regulators"), \
|
||||||
.n_voltages = 4, \
|
.n_voltages = 4, \
|
||||||
.ops = &max77693_safeout_ops, \
|
.ops = &max77693_safeout_ops, \
|
||||||
.type = REGULATOR_VOLTAGE, \
|
.type = REGULATOR_VOLTAGE, \
|
||||||
|
@ -145,6 +147,8 @@ static const struct regulator_desc regulators[] = {
|
||||||
{
|
{
|
||||||
.name = "CHARGER",
|
.name = "CHARGER",
|
||||||
.id = MAX77693_CHARGER,
|
.id = MAX77693_CHARGER,
|
||||||
|
.of_match = of_match_ptr("CHARGER"),
|
||||||
|
.regulators_node = of_match_ptr("regulators"),
|
||||||
.ops = &max77693_charger_ops,
|
.ops = &max77693_charger_ops,
|
||||||
.type = REGULATOR_CURRENT,
|
.type = REGULATOR_CURRENT,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
@ -154,102 +158,23 @@ static const struct regulator_desc regulators[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_OF
|
|
||||||
static int max77693_pmic_dt_parse_rdata(struct device *dev,
|
|
||||||
struct max77693_regulator_data **rdata)
|
|
||||||
{
|
|
||||||
struct device_node *np;
|
|
||||||
struct of_regulator_match *rmatch;
|
|
||||||
struct max77693_regulator_data *tmp;
|
|
||||||
int i, matched = 0;
|
|
||||||
|
|
||||||
np = of_get_child_by_name(dev->parent->of_node, "regulators");
|
|
||||||
if (!np)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
rmatch = devm_kzalloc(dev,
|
|
||||||
sizeof(*rmatch) * ARRAY_SIZE(regulators), GFP_KERNEL);
|
|
||||||
if (!rmatch) {
|
|
||||||
of_node_put(np);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(regulators); i++)
|
|
||||||
rmatch[i].name = regulators[i].name;
|
|
||||||
|
|
||||||
matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(regulators));
|
|
||||||
of_node_put(np);
|
|
||||||
if (matched <= 0)
|
|
||||||
return matched;
|
|
||||||
*rdata = devm_kzalloc(dev, sizeof(**rdata) * matched, GFP_KERNEL);
|
|
||||||
if (!(*rdata))
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
tmp = *rdata;
|
|
||||||
|
|
||||||
for (i = 0; i < matched; i++) {
|
|
||||||
tmp->initdata = rmatch[i].init_data;
|
|
||||||
tmp->of_node = rmatch[i].of_node;
|
|
||||||
tmp->id = regulators[i].id;
|
|
||||||
tmp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return matched;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static int max77693_pmic_dt_parse_rdata(struct device *dev,
|
|
||||||
struct max77693_regulator_data **rdata)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_OF */
|
|
||||||
|
|
||||||
static int max77693_pmic_init_rdata(struct device *dev,
|
|
||||||
struct max77693_regulator_data **rdata)
|
|
||||||
{
|
|
||||||
struct max77693_platform_data *pdata;
|
|
||||||
int num_regulators = 0;
|
|
||||||
|
|
||||||
pdata = dev_get_platdata(dev->parent);
|
|
||||||
if (pdata) {
|
|
||||||
*rdata = pdata->regulators;
|
|
||||||
num_regulators = pdata->num_regulators;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(*rdata) && dev->parent->of_node)
|
|
||||||
num_regulators = max77693_pmic_dt_parse_rdata(dev, rdata);
|
|
||||||
|
|
||||||
return num_regulators;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int max77693_pmic_probe(struct platform_device *pdev)
|
static int max77693_pmic_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||||
struct max77693_regulator_data *rdata = NULL;
|
int i;
|
||||||
int num_rdata, i;
|
|
||||||
struct regulator_config config = { };
|
struct regulator_config config = { };
|
||||||
|
|
||||||
num_rdata = max77693_pmic_init_rdata(&pdev->dev, &rdata);
|
config.dev = iodev->dev;
|
||||||
if (!rdata || num_rdata <= 0) {
|
|
||||||
dev_err(&pdev->dev, "No init data supplied.\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
config.dev = &pdev->dev;
|
|
||||||
config.regmap = iodev->regmap;
|
config.regmap = iodev->regmap;
|
||||||
|
|
||||||
for (i = 0; i < num_rdata; i++) {
|
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
|
||||||
int id = rdata[i].id;
|
|
||||||
struct regulator_dev *rdev;
|
struct regulator_dev *rdev;
|
||||||
|
|
||||||
config.init_data = rdata[i].initdata;
|
|
||||||
config.of_node = rdata[i].of_node;
|
|
||||||
|
|
||||||
rdev = devm_regulator_register(&pdev->dev,
|
rdev = devm_regulator_register(&pdev->dev,
|
||||||
®ulators[id], &config);
|
®ulators[i], &config);
|
||||||
if (IS_ERR(rdev)) {
|
if (IS_ERR(rdev)) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"Failed to initialize regulator-%d\n", id);
|
"Failed to initialize regulator-%d\n", i);
|
||||||
return PTR_ERR(rdev);
|
return PTR_ERR(rdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,7 +382,7 @@ static int max8660_probe(struct i2c_client *client,
|
||||||
const struct i2c_device_id *i2c_id)
|
const struct i2c_device_id *i2c_id)
|
||||||
{
|
{
|
||||||
struct device *dev = &client->dev;
|
struct device *dev = &client->dev;
|
||||||
struct max8660_platform_data *pdata = dev_get_platdata(dev);
|
struct max8660_platform_data pdata_of, *pdata = dev_get_platdata(dev);
|
||||||
struct regulator_config config = { };
|
struct regulator_config config = { };
|
||||||
struct max8660 *max8660;
|
struct max8660 *max8660;
|
||||||
int boot_on, i, id, ret = -EINVAL;
|
int boot_on, i, id, ret = -EINVAL;
|
||||||
|
@ -391,7 +391,6 @@ static int max8660_probe(struct i2c_client *client,
|
||||||
|
|
||||||
if (dev->of_node && !pdata) {
|
if (dev->of_node && !pdata) {
|
||||||
const struct of_device_id *id;
|
const struct of_device_id *id;
|
||||||
struct max8660_platform_data pdata_of;
|
|
||||||
|
|
||||||
id = of_match_device(of_match_ptr(max8660_dt_ids), dev);
|
id = of_match_device(of_match_ptr(max8660_dt_ids), dev);
|
||||||
if (!id)
|
if (!id)
|
||||||
|
@ -443,9 +442,9 @@ static int max8660_probe(struct i2c_client *client,
|
||||||
for (i = 0; i < pdata->num_subdevs; i++) {
|
for (i = 0; i < pdata->num_subdevs; i++) {
|
||||||
|
|
||||||
if (!pdata->subdevs[i].platform_data)
|
if (!pdata->subdevs[i].platform_data)
|
||||||
return ret;
|
boot_on = false;
|
||||||
|
else
|
||||||
boot_on = pdata->subdevs[i].platform_data->constraints.boot_on;
|
boot_on = pdata->subdevs[i].platform_data->constraints.boot_on;
|
||||||
|
|
||||||
switch (pdata->subdevs[i].id) {
|
switch (pdata->subdevs[i].id) {
|
||||||
case MAX8660_V3:
|
case MAX8660_V3:
|
||||||
|
|
|
@ -916,6 +916,9 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic,
|
||||||
(id == PALMAS_REG_LDO6))
|
(id == PALMAS_REG_LDO6))
|
||||||
desc->enable_time = 2000;
|
desc->enable_time = 2000;
|
||||||
} else {
|
} else {
|
||||||
|
if (!ddata->has_regen3 && id == PALMAS_REG_REGEN3)
|
||||||
|
continue;
|
||||||
|
|
||||||
desc->n_voltages = 1;
|
desc->n_voltages = 1;
|
||||||
if (reg_init && reg_init->roof_floor)
|
if (reg_init && reg_init->roof_floor)
|
||||||
desc->ops = &palmas_ops_ext_control_extreg;
|
desc->ops = &palmas_ops_ext_control_extreg;
|
||||||
|
@ -1398,6 +1401,7 @@ static struct palmas_pmic_driver_data palmas_ddata = {
|
||||||
.ldo_begin = PALMAS_REG_LDO1,
|
.ldo_begin = PALMAS_REG_LDO1,
|
||||||
.ldo_end = PALMAS_REG_LDOUSB,
|
.ldo_end = PALMAS_REG_LDOUSB,
|
||||||
.max_reg = PALMAS_NUM_REGS,
|
.max_reg = PALMAS_NUM_REGS,
|
||||||
|
.has_regen3 = true,
|
||||||
.palmas_regs_info = palmas_generic_regs_info,
|
.palmas_regs_info = palmas_generic_regs_info,
|
||||||
.palmas_matches = palmas_matches,
|
.palmas_matches = palmas_matches,
|
||||||
.sleep_req_info = palma_sleep_req_info,
|
.sleep_req_info = palma_sleep_req_info,
|
||||||
|
@ -1411,6 +1415,7 @@ static struct palmas_pmic_driver_data tps65917_ddata = {
|
||||||
.ldo_begin = TPS65917_REG_LDO1,
|
.ldo_begin = TPS65917_REG_LDO1,
|
||||||
.ldo_end = TPS65917_REG_LDO5,
|
.ldo_end = TPS65917_REG_LDO5,
|
||||||
.max_reg = TPS65917_NUM_REGS,
|
.max_reg = TPS65917_NUM_REGS,
|
||||||
|
.has_regen3 = true,
|
||||||
.palmas_regs_info = tps65917_regs_info,
|
.palmas_regs_info = tps65917_regs_info,
|
||||||
.palmas_matches = tps65917_matches,
|
.palmas_matches = tps65917_matches,
|
||||||
.sleep_req_info = tps65917_sleep_req_info,
|
.sleep_req_info = tps65917_sleep_req_info,
|
||||||
|
@ -1505,7 +1510,7 @@ static void palmas_dt_to_pdata(struct device *dev,
|
||||||
pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator");
|
pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator");
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct of_device_id of_palmas_match_tbl[] = {
|
static const struct of_device_id of_palmas_match_tbl[] = {
|
||||||
{
|
{
|
||||||
.compatible = "ti,palmas-pmic",
|
.compatible = "ti,palmas-pmic",
|
||||||
.data = &palmas_ddata,
|
.data = &palmas_ddata,
|
||||||
|
@ -1572,9 +1577,11 @@ static int palmas_regulators_probe(struct platform_device *pdev)
|
||||||
if (!pmic)
|
if (!pmic)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (of_device_is_compatible(node, "ti,tps659038-pmic"))
|
if (of_device_is_compatible(node, "ti,tps659038-pmic")) {
|
||||||
palmas_generic_regs_info[PALMAS_REG_REGEN2].ctrl_addr =
|
palmas_generic_regs_info[PALMAS_REG_REGEN2].ctrl_addr =
|
||||||
TPS659038_REGEN2_CTRL;
|
TPS659038_REGEN2_CTRL;
|
||||||
|
palmas_ddata.has_regen3 = false;
|
||||||
|
}
|
||||||
|
|
||||||
pmic->dev = &pdev->dev;
|
pmic->dev = &pdev->dev;
|
||||||
pmic->palmas = palmas;
|
pmic->palmas = palmas;
|
||||||
|
|
|
@ -393,6 +393,28 @@ static int rpm_reg_is_enabled(struct regulator_dev *rdev)
|
||||||
return vreg->is_enabled;
|
return vreg->is_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rpm_reg_set_load(struct regulator_dev *rdev, int load_uA)
|
||||||
|
{
|
||||||
|
struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
|
||||||
|
const struct rpm_reg_parts *parts = vreg->parts;
|
||||||
|
const struct request_member *req = &parts->ia;
|
||||||
|
int load_mA = load_uA / 1000;
|
||||||
|
int max_mA = req->mask >> req->shift;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (req->mask == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (load_mA > max_mA)
|
||||||
|
load_mA = max_mA;
|
||||||
|
|
||||||
|
mutex_lock(&vreg->lock);
|
||||||
|
ret = rpm_reg_write(vreg, req, load_mA);
|
||||||
|
mutex_unlock(&vreg->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static struct regulator_ops uV_ops = {
|
static struct regulator_ops uV_ops = {
|
||||||
.list_voltage = regulator_list_voltage_linear_range,
|
.list_voltage = regulator_list_voltage_linear_range,
|
||||||
|
|
||||||
|
@ -402,6 +424,8 @@ static struct regulator_ops uV_ops = {
|
||||||
.enable = rpm_reg_uV_enable,
|
.enable = rpm_reg_uV_enable,
|
||||||
.disable = rpm_reg_uV_disable,
|
.disable = rpm_reg_uV_disable,
|
||||||
.is_enabled = rpm_reg_is_enabled,
|
.is_enabled = rpm_reg_is_enabled,
|
||||||
|
|
||||||
|
.set_load = rpm_reg_set_load,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct regulator_ops mV_ops = {
|
static struct regulator_ops mV_ops = {
|
||||||
|
@ -413,6 +437,8 @@ static struct regulator_ops mV_ops = {
|
||||||
.enable = rpm_reg_mV_enable,
|
.enable = rpm_reg_mV_enable,
|
||||||
.disable = rpm_reg_mV_disable,
|
.disable = rpm_reg_mV_disable,
|
||||||
.is_enabled = rpm_reg_is_enabled,
|
.is_enabled = rpm_reg_is_enabled,
|
||||||
|
|
||||||
|
.set_load = rpm_reg_set_load,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct regulator_ops switch_ops = {
|
static struct regulator_ops switch_ops = {
|
||||||
|
@ -581,31 +607,6 @@ static const struct qcom_rpm_reg smb208_smps = {
|
||||||
.supports_force_mode_bypass = false,
|
.supports_force_mode_bypass = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct of_device_id rpm_of_match[] = {
|
|
||||||
{ .compatible = "qcom,rpm-pm8058-pldo", .data = &pm8058_pldo },
|
|
||||||
{ .compatible = "qcom,rpm-pm8058-nldo", .data = &pm8058_nldo },
|
|
||||||
{ .compatible = "qcom,rpm-pm8058-smps", .data = &pm8058_smps },
|
|
||||||
{ .compatible = "qcom,rpm-pm8058-ncp", .data = &pm8058_ncp },
|
|
||||||
{ .compatible = "qcom,rpm-pm8058-switch", .data = &pm8058_switch },
|
|
||||||
|
|
||||||
{ .compatible = "qcom,rpm-pm8901-pldo", .data = &pm8901_pldo },
|
|
||||||
{ .compatible = "qcom,rpm-pm8901-nldo", .data = &pm8901_nldo },
|
|
||||||
{ .compatible = "qcom,rpm-pm8901-ftsmps", .data = &pm8901_ftsmps },
|
|
||||||
{ .compatible = "qcom,rpm-pm8901-switch", .data = &pm8901_switch },
|
|
||||||
|
|
||||||
{ .compatible = "qcom,rpm-pm8921-pldo", .data = &pm8921_pldo },
|
|
||||||
{ .compatible = "qcom,rpm-pm8921-nldo", .data = &pm8921_nldo },
|
|
||||||
{ .compatible = "qcom,rpm-pm8921-nldo1200", .data = &pm8921_nldo1200 },
|
|
||||||
{ .compatible = "qcom,rpm-pm8921-smps", .data = &pm8921_smps },
|
|
||||||
{ .compatible = "qcom,rpm-pm8921-ftsmps", .data = &pm8921_ftsmps },
|
|
||||||
{ .compatible = "qcom,rpm-pm8921-ncp", .data = &pm8921_ncp },
|
|
||||||
{ .compatible = "qcom,rpm-pm8921-switch", .data = &pm8921_switch },
|
|
||||||
|
|
||||||
{ .compatible = "qcom,rpm-smb208", .data = &smb208_smps },
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(of, rpm_of_match);
|
|
||||||
|
|
||||||
static int rpm_reg_set(struct qcom_rpm_reg *vreg,
|
static int rpm_reg_set(struct qcom_rpm_reg *vreg,
|
||||||
const struct request_member *req,
|
const struct request_member *req,
|
||||||
const int value)
|
const int value)
|
||||||
|
@ -619,7 +620,9 @@ static int rpm_reg_set(struct qcom_rpm_reg *vreg,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rpm_reg_of_parse_freq(struct device *dev, struct qcom_rpm_reg *vreg)
|
static int rpm_reg_of_parse_freq(struct device *dev,
|
||||||
|
struct device_node *node,
|
||||||
|
struct qcom_rpm_reg *vreg)
|
||||||
{
|
{
|
||||||
static const int freq_table[] = {
|
static const int freq_table[] = {
|
||||||
19200000, 9600000, 6400000, 4800000, 3840000, 3200000, 2740000,
|
19200000, 9600000, 6400000, 4800000, 3840000, 3200000, 2740000,
|
||||||
|
@ -633,7 +636,7 @@ static int rpm_reg_of_parse_freq(struct device *dev, struct qcom_rpm_reg *vreg)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
key = "qcom,switch-mode-frequency";
|
key = "qcom,switch-mode-frequency";
|
||||||
ret = of_property_read_u32(dev->of_node, key, &freq);
|
ret = of_property_read_u32(node, key, &freq);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "regulator requires %s property\n", key);
|
dev_err(dev, "regulator requires %s property\n", key);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -650,84 +653,40 @@ static int rpm_reg_of_parse_freq(struct device *dev, struct qcom_rpm_reg *vreg)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rpm_reg_probe(struct platform_device *pdev)
|
static int rpm_reg_of_parse(struct device_node *node,
|
||||||
|
const struct regulator_desc *desc,
|
||||||
|
struct regulator_config *config)
|
||||||
{
|
{
|
||||||
struct regulator_init_data *initdata;
|
struct qcom_rpm_reg *vreg = config->driver_data;
|
||||||
const struct qcom_rpm_reg *template;
|
struct device *dev = config->dev;
|
||||||
const struct of_device_id *match;
|
|
||||||
struct regulator_config config = { };
|
|
||||||
struct regulator_dev *rdev;
|
|
||||||
struct qcom_rpm_reg *vreg;
|
|
||||||
const char *key;
|
const char *key;
|
||||||
u32 force_mode;
|
u32 force_mode;
|
||||||
bool pwm;
|
bool pwm;
|
||||||
u32 val;
|
u32 val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
match = of_match_device(rpm_of_match, &pdev->dev);
|
|
||||||
template = match->data;
|
|
||||||
|
|
||||||
vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
|
|
||||||
if (!vreg) {
|
|
||||||
dev_err(&pdev->dev, "failed to allocate vreg\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
memcpy(vreg, template, sizeof(*vreg));
|
|
||||||
mutex_init(&vreg->lock);
|
|
||||||
vreg->dev = &pdev->dev;
|
|
||||||
vreg->desc.id = -1;
|
|
||||||
vreg->desc.owner = THIS_MODULE;
|
|
||||||
vreg->desc.type = REGULATOR_VOLTAGE;
|
|
||||||
vreg->desc.name = pdev->dev.of_node->name;
|
|
||||||
vreg->desc.supply_name = "vin";
|
|
||||||
|
|
||||||
vreg->rpm = dev_get_drvdata(pdev->dev.parent);
|
|
||||||
if (!vreg->rpm) {
|
|
||||||
dev_err(&pdev->dev, "unable to retrieve handle to rpm\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
|
|
||||||
&vreg->desc);
|
|
||||||
if (!initdata)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
key = "reg";
|
|
||||||
ret = of_property_read_u32(pdev->dev.of_node, key, &val);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(&pdev->dev, "failed to read %s\n", key);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
vreg->resource = val;
|
|
||||||
|
|
||||||
if ((vreg->parts->uV.mask || vreg->parts->mV.mask) &&
|
|
||||||
(!initdata->constraints.min_uV || !initdata->constraints.max_uV)) {
|
|
||||||
dev_err(&pdev->dev, "no voltage specified for regulator\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
key = "bias-pull-down";
|
key = "bias-pull-down";
|
||||||
if (of_property_read_bool(pdev->dev.of_node, key)) {
|
if (of_property_read_bool(node, key)) {
|
||||||
ret = rpm_reg_set(vreg, &vreg->parts->pd, 1);
|
ret = rpm_reg_set(vreg, &vreg->parts->pd, 1);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "%s is invalid", key);
|
dev_err(dev, "%s is invalid", key);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vreg->parts->freq.mask) {
|
if (vreg->parts->freq.mask) {
|
||||||
ret = rpm_reg_of_parse_freq(&pdev->dev, vreg);
|
ret = rpm_reg_of_parse_freq(dev, node, vreg);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vreg->parts->pm.mask) {
|
if (vreg->parts->pm.mask) {
|
||||||
key = "qcom,power-mode-hysteretic";
|
key = "qcom,power-mode-hysteretic";
|
||||||
pwm = !of_property_read_bool(pdev->dev.of_node, key);
|
pwm = !of_property_read_bool(node, key);
|
||||||
|
|
||||||
ret = rpm_reg_set(vreg, &vreg->parts->pm, pwm);
|
ret = rpm_reg_set(vreg, &vreg->parts->pm, pwm);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "failed to set power mode\n");
|
dev_err(dev, "failed to set power mode\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -736,11 +695,11 @@ static int rpm_reg_probe(struct platform_device *pdev)
|
||||||
force_mode = -1;
|
force_mode = -1;
|
||||||
|
|
||||||
key = "qcom,force-mode";
|
key = "qcom,force-mode";
|
||||||
ret = of_property_read_u32(pdev->dev.of_node, key, &val);
|
ret = of_property_read_u32(node, key, &val);
|
||||||
if (ret == -EINVAL) {
|
if (ret == -EINVAL) {
|
||||||
val = QCOM_RPM_FORCE_MODE_NONE;
|
val = QCOM_RPM_FORCE_MODE_NONE;
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
dev_err(&pdev->dev, "failed to read %s\n", key);
|
dev_err(dev, "failed to read %s\n", key);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,25 +734,192 @@ static int rpm_reg_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (force_mode == -1) {
|
if (force_mode == -1) {
|
||||||
dev_err(&pdev->dev, "invalid force mode\n");
|
dev_err(dev, "invalid force mode\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = rpm_reg_set(vreg, &vreg->parts->fm, force_mode);
|
ret = rpm_reg_set(vreg, &vreg->parts->fm, force_mode);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "failed to set force mode\n");
|
dev_err(dev, "failed to set force mode\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config.dev = &pdev->dev;
|
return 0;
|
||||||
config.init_data = initdata;
|
}
|
||||||
config.driver_data = vreg;
|
|
||||||
config.of_node = pdev->dev.of_node;
|
struct rpm_regulator_data {
|
||||||
rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config);
|
const char *name;
|
||||||
if (IS_ERR(rdev)) {
|
int resource;
|
||||||
dev_err(&pdev->dev, "can't register regulator\n");
|
const struct qcom_rpm_reg *template;
|
||||||
return PTR_ERR(rdev);
|
const char *supply;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rpm_regulator_data rpm_pm8058_regulators[] = {
|
||||||
|
{ "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" },
|
||||||
|
{ "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" },
|
||||||
|
{ "l2", QCOM_RPM_PM8058_LDO2, &pm8058_pldo, "vdd_l2_l11_l12" },
|
||||||
|
{ "l3", QCOM_RPM_PM8058_LDO3, &pm8058_pldo, "vdd_l3_l4_l5" },
|
||||||
|
{ "l4", QCOM_RPM_PM8058_LDO4, &pm8058_pldo, "vdd_l3_l4_l5" },
|
||||||
|
{ "l5", QCOM_RPM_PM8058_LDO5, &pm8058_pldo, "vdd_l3_l4_l5" },
|
||||||
|
{ "l6", QCOM_RPM_PM8058_LDO6, &pm8058_pldo, "vdd_l6_l7" },
|
||||||
|
{ "l7", QCOM_RPM_PM8058_LDO7, &pm8058_pldo, "vdd_l6_l7" },
|
||||||
|
{ "l8", QCOM_RPM_PM8058_LDO8, &pm8058_pldo, "vdd_l8" },
|
||||||
|
{ "l9", QCOM_RPM_PM8058_LDO9, &pm8058_pldo, "vdd_l9" },
|
||||||
|
{ "l10", QCOM_RPM_PM8058_LDO10, &pm8058_pldo, "vdd_l10" },
|
||||||
|
{ "l11", QCOM_RPM_PM8058_LDO11, &pm8058_pldo, "vdd_l2_l11_l12" },
|
||||||
|
{ "l12", QCOM_RPM_PM8058_LDO12, &pm8058_pldo, "vdd_l2_l11_l12" },
|
||||||
|
{ "l13", QCOM_RPM_PM8058_LDO13, &pm8058_pldo, "vdd_l13_l16" },
|
||||||
|
{ "l14", QCOM_RPM_PM8058_LDO14, &pm8058_pldo, "vdd_l14_l15" },
|
||||||
|
{ "l15", QCOM_RPM_PM8058_LDO15, &pm8058_pldo, "vdd_l14_l15" },
|
||||||
|
{ "l16", QCOM_RPM_PM8058_LDO16, &pm8058_pldo, "vdd_l13_l16" },
|
||||||
|
{ "l17", QCOM_RPM_PM8058_LDO17, &pm8058_pldo, "vdd_l17_l18" },
|
||||||
|
{ "l18", QCOM_RPM_PM8058_LDO18, &pm8058_pldo, "vdd_l17_l18" },
|
||||||
|
{ "l19", QCOM_RPM_PM8058_LDO19, &pm8058_pldo, "vdd_l19_l20" },
|
||||||
|
{ "l20", QCOM_RPM_PM8058_LDO20, &pm8058_pldo, "vdd_l19_l20" },
|
||||||
|
{ "l21", QCOM_RPM_PM8058_LDO21, &pm8058_nldo, "vdd_l21" },
|
||||||
|
{ "l22", QCOM_RPM_PM8058_LDO22, &pm8058_nldo, "vdd_l22" },
|
||||||
|
{ "l23", QCOM_RPM_PM8058_LDO23, &pm8058_nldo, "vdd_l23_l24_l25" },
|
||||||
|
{ "l24", QCOM_RPM_PM8058_LDO24, &pm8058_nldo, "vdd_l23_l24_l25" },
|
||||||
|
{ "l25", QCOM_RPM_PM8058_LDO25, &pm8058_nldo, "vdd_l23_l24_l25" },
|
||||||
|
|
||||||
|
{ "s0", QCOM_RPM_PM8058_SMPS0, &pm8058_smps, "vdd_s0" },
|
||||||
|
{ "s1", QCOM_RPM_PM8058_SMPS1, &pm8058_smps, "vdd_s1" },
|
||||||
|
{ "s2", QCOM_RPM_PM8058_SMPS2, &pm8058_smps, "vdd_s2" },
|
||||||
|
{ "s3", QCOM_RPM_PM8058_SMPS3, &pm8058_smps, "vdd_s3" },
|
||||||
|
{ "s4", QCOM_RPM_PM8058_SMPS4, &pm8058_smps, "vdd_s4" },
|
||||||
|
|
||||||
|
{ "lvs0", QCOM_RPM_PM8058_LVS0, &pm8058_switch, "vdd_l0_l1_lvs" },
|
||||||
|
{ "lvs1", QCOM_RPM_PM8058_LVS1, &pm8058_switch, "vdd_l0_l1_lvs" },
|
||||||
|
|
||||||
|
{ "ncp", QCOM_RPM_PM8058_NCP, &pm8058_ncp, "vdd_ncp" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rpm_regulator_data rpm_pm8901_regulators[] = {
|
||||||
|
{ "l0", QCOM_RPM_PM8901_LDO0, &pm8901_nldo, "vdd_l0" },
|
||||||
|
{ "l1", QCOM_RPM_PM8901_LDO1, &pm8901_pldo, "vdd_l1" },
|
||||||
|
{ "l2", QCOM_RPM_PM8901_LDO2, &pm8901_pldo, "vdd_l2" },
|
||||||
|
{ "l3", QCOM_RPM_PM8901_LDO3, &pm8901_pldo, "vdd_l3" },
|
||||||
|
{ "l4", QCOM_RPM_PM8901_LDO4, &pm8901_pldo, "vdd_l4" },
|
||||||
|
{ "l5", QCOM_RPM_PM8901_LDO5, &pm8901_pldo, "vdd_l5" },
|
||||||
|
{ "l6", QCOM_RPM_PM8901_LDO6, &pm8901_pldo, "vdd_l6" },
|
||||||
|
|
||||||
|
{ "s0", QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" },
|
||||||
|
{ "s1", QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" },
|
||||||
|
{ "s2", QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" },
|
||||||
|
{ "s3", QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" },
|
||||||
|
{ "s4", QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" },
|
||||||
|
|
||||||
|
{ "lvs0", QCOM_RPM_PM8901_LVS0, &pm8901_switch, "lvs0_in" },
|
||||||
|
{ "lvs1", QCOM_RPM_PM8901_LVS1, &pm8901_switch, "lvs1_in" },
|
||||||
|
{ "lvs2", QCOM_RPM_PM8901_LVS2, &pm8901_switch, "lvs2_in" },
|
||||||
|
{ "lvs3", QCOM_RPM_PM8901_LVS3, &pm8901_switch, "lvs3_in" },
|
||||||
|
|
||||||
|
{ "mvs", QCOM_RPM_PM8901_MVS, &pm8901_switch, "mvs_in" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rpm_regulator_data rpm_pm8921_regulators[] = {
|
||||||
|
{ "s1", QCOM_RPM_PM8921_SMPS1, &pm8921_smps, "vdd_s1" },
|
||||||
|
{ "s2", QCOM_RPM_PM8921_SMPS2, &pm8921_smps, "vdd_s2" },
|
||||||
|
{ "s3", QCOM_RPM_PM8921_SMPS3, &pm8921_smps },
|
||||||
|
{ "s4", QCOM_RPM_PM8921_SMPS4, &pm8921_smps, "vdd_s4" },
|
||||||
|
{ "s7", QCOM_RPM_PM8921_SMPS7, &pm8921_smps, "vdd_s7" },
|
||||||
|
{ "s8", QCOM_RPM_PM8921_SMPS8, &pm8921_smps, "vdd_s8" },
|
||||||
|
|
||||||
|
{ "l1", QCOM_RPM_PM8921_LDO1, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
|
||||||
|
{ "l2", QCOM_RPM_PM8921_LDO2, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
|
||||||
|
{ "l3", QCOM_RPM_PM8921_LDO3, &pm8921_pldo, "vdd_l3_l15_l17" },
|
||||||
|
{ "l4", QCOM_RPM_PM8921_LDO4, &pm8921_pldo, "vdd_l4_l14" },
|
||||||
|
{ "l5", QCOM_RPM_PM8921_LDO5, &pm8921_pldo, "vdd_l5_l8_l16" },
|
||||||
|
{ "l6", QCOM_RPM_PM8921_LDO6, &pm8921_pldo, "vdd_l6_l7" },
|
||||||
|
{ "l7", QCOM_RPM_PM8921_LDO7, &pm8921_pldo, "vdd_l6_l7" },
|
||||||
|
{ "l8", QCOM_RPM_PM8921_LDO8, &pm8921_pldo, "vdd_l5_l8_l16" },
|
||||||
|
{ "l9", QCOM_RPM_PM8921_LDO9, &pm8921_pldo, "vdd_l9_l11" },
|
||||||
|
{ "l10", QCOM_RPM_PM8921_LDO10, &pm8921_pldo, "vdd_l10_l22" },
|
||||||
|
{ "l11", QCOM_RPM_PM8921_LDO11, &pm8921_pldo, "vdd_l9_l11" },
|
||||||
|
{ "l12", QCOM_RPM_PM8921_LDO12, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
|
||||||
|
{ "l14", QCOM_RPM_PM8921_LDO14, &pm8921_pldo, "vdd_l4_l14" },
|
||||||
|
{ "l15", QCOM_RPM_PM8921_LDO15, &pm8921_pldo, "vdd_l3_l15_l17" },
|
||||||
|
{ "l16", QCOM_RPM_PM8921_LDO16, &pm8921_pldo, "vdd_l5_l8_l16" },
|
||||||
|
{ "l17", QCOM_RPM_PM8921_LDO17, &pm8921_pldo, "vdd_l3_l15_l17" },
|
||||||
|
{ "l18", QCOM_RPM_PM8921_LDO18, &pm8921_nldo, "vdd_l1_l2_l12_l18" },
|
||||||
|
{ "l21", QCOM_RPM_PM8921_LDO21, &pm8921_pldo, "vdd_l21_l23_l29" },
|
||||||
|
{ "l22", QCOM_RPM_PM8921_LDO22, &pm8921_pldo, "vdd_l10_l22" },
|
||||||
|
{ "l23", QCOM_RPM_PM8921_LDO23, &pm8921_pldo, "vdd_l21_l23_l29" },
|
||||||
|
{ "l24", QCOM_RPM_PM8921_LDO24, &pm8921_nldo1200, "vdd_l24" },
|
||||||
|
{ "l25", QCOM_RPM_PM8921_LDO25, &pm8921_nldo1200, "vdd_l25" },
|
||||||
|
{ "l26", QCOM_RPM_PM8921_LDO26, &pm8921_nldo1200, "vdd_l26" },
|
||||||
|
{ "l27", QCOM_RPM_PM8921_LDO27, &pm8921_nldo1200, "vdd_l27" },
|
||||||
|
{ "l28", QCOM_RPM_PM8921_LDO28, &pm8921_nldo1200, "vdd_l28" },
|
||||||
|
{ "l29", QCOM_RPM_PM8921_LDO29, &pm8921_pldo, "vdd_l21_l23_l29" },
|
||||||
|
|
||||||
|
{ "lvs1", QCOM_RPM_PM8921_LVS1, &pm8921_switch, "vin_lvs1_3_6" },
|
||||||
|
{ "lvs2", QCOM_RPM_PM8921_LVS2, &pm8921_switch, "vin_lvs2" },
|
||||||
|
{ "lvs3", QCOM_RPM_PM8921_LVS3, &pm8921_switch, "vin_lvs1_3_6" },
|
||||||
|
{ "lvs4", QCOM_RPM_PM8921_LVS4, &pm8921_switch, "vin_lvs4_5_7" },
|
||||||
|
{ "lvs5", QCOM_RPM_PM8921_LVS5, &pm8921_switch, "vin_lvs4_5_7" },
|
||||||
|
{ "lvs6", QCOM_RPM_PM8921_LVS6, &pm8921_switch, "vin_lvs1_3_6" },
|
||||||
|
{ "lvs7", QCOM_RPM_PM8921_LVS7, &pm8921_switch, "vin_lvs4_5_7" },
|
||||||
|
|
||||||
|
{ "usb-switch", QCOM_RPM_USB_OTG_SWITCH, &pm8921_switch, "vin_5vs" },
|
||||||
|
{ "hdmi-switch", QCOM_RPM_HDMI_SWITCH, &pm8921_switch, "vin_5vs" },
|
||||||
|
{ "ncp", QCOM_RPM_PM8921_NCP, &pm8921_ncp, "vdd_ncp" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id rpm_of_match[] = {
|
||||||
|
{ .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators },
|
||||||
|
{ .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators },
|
||||||
|
{ .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, rpm_of_match);
|
||||||
|
|
||||||
|
static int rpm_reg_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
const struct rpm_regulator_data *reg;
|
||||||
|
const struct of_device_id *match;
|
||||||
|
struct regulator_config config = { };
|
||||||
|
struct regulator_dev *rdev;
|
||||||
|
struct qcom_rpm_reg *vreg;
|
||||||
|
struct qcom_rpm *rpm;
|
||||||
|
|
||||||
|
rpm = dev_get_drvdata(pdev->dev.parent);
|
||||||
|
if (!rpm) {
|
||||||
|
dev_err(&pdev->dev, "unable to retrieve handle to rpm\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
match = of_match_device(rpm_of_match, &pdev->dev);
|
||||||
|
for (reg = match->data; reg->name; reg++) {
|
||||||
|
vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
|
||||||
|
if (!vreg)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
memcpy(vreg, reg->template, sizeof(*vreg));
|
||||||
|
mutex_init(&vreg->lock);
|
||||||
|
|
||||||
|
vreg->dev = &pdev->dev;
|
||||||
|
vreg->resource = reg->resource;
|
||||||
|
vreg->rpm = rpm;
|
||||||
|
|
||||||
|
vreg->desc.id = -1;
|
||||||
|
vreg->desc.owner = THIS_MODULE;
|
||||||
|
vreg->desc.type = REGULATOR_VOLTAGE;
|
||||||
|
vreg->desc.name = reg->name;
|
||||||
|
vreg->desc.supply_name = reg->supply;
|
||||||
|
vreg->desc.of_match = reg->name;
|
||||||
|
vreg->desc.of_parse_cb = rpm_reg_of_parse;
|
||||||
|
|
||||||
|
config.dev = &pdev->dev;
|
||||||
|
config.driver_data = vreg;
|
||||||
|
rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config);
|
||||||
|
if (IS_ERR(rdev)) {
|
||||||
|
dev_err(&pdev->dev, "failed to register %s\n", reg->name);
|
||||||
|
return PTR_ERR(rdev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -56,6 +56,7 @@ static int stw481x_vmmc_regulator_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct stw481x *stw481x = dev_get_platdata(&pdev->dev);
|
struct stw481x *stw481x = dev_get_platdata(&pdev->dev);
|
||||||
struct regulator_config config = { };
|
struct regulator_config config = { };
|
||||||
|
struct regulator_dev *rdev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* First disable the external VMMC if it's active */
|
/* First disable the external VMMC if it's active */
|
||||||
|
@ -75,12 +76,11 @@ static int stw481x_vmmc_regulator_probe(struct platform_device *pdev)
|
||||||
pdev->dev.of_node,
|
pdev->dev.of_node,
|
||||||
&vmmc_regulator);
|
&vmmc_regulator);
|
||||||
|
|
||||||
stw481x->vmmc_regulator = devm_regulator_register(&pdev->dev,
|
rdev = devm_regulator_register(&pdev->dev, &vmmc_regulator, &config);
|
||||||
&vmmc_regulator, &config);
|
if (IS_ERR(rdev)) {
|
||||||
if (IS_ERR(stw481x->vmmc_regulator)) {
|
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"error initializing STw481x VMMC regulator\n");
|
"error initializing STw481x VMMC regulator\n");
|
||||||
return PTR_ERR(stw481x->vmmc_regulator);
|
return PTR_ERR(rdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_info(&pdev->dev, "initialized STw481x VMMC regulator\n");
|
dev_info(&pdev->dev, "initialized STw481x VMMC regulator\n");
|
||||||
|
|
|
@ -1151,17 +1151,16 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
|
||||||
static irqreturn_t pmic_uv_handler(int irq, void *data)
|
static irqreturn_t pmic_uv_handler(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct regulator_dev *rdev = (struct regulator_dev *)data;
|
struct regulator_dev *rdev = (struct regulator_dev *)data;
|
||||||
struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
|
|
||||||
|
|
||||||
mutex_lock(&rdev->mutex);
|
mutex_lock(&rdev->mutex);
|
||||||
if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
|
if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
|
||||||
regulator_notifier_call_chain(rdev,
|
regulator_notifier_call_chain(rdev,
|
||||||
REGULATOR_EVENT_REGULATION_OUT,
|
REGULATOR_EVENT_REGULATION_OUT,
|
||||||
wm8350);
|
NULL);
|
||||||
else
|
else
|
||||||
regulator_notifier_call_chain(rdev,
|
regulator_notifier_call_chain(rdev,
|
||||||
REGULATOR_EVENT_UNDER_VOLTAGE,
|
REGULATOR_EVENT_UNDER_VOLTAGE,
|
||||||
wm8350);
|
NULL);
|
||||||
mutex_unlock(&rdev->mutex);
|
mutex_unlock(&rdev->mutex);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
|
|
@ -4225,22 +4225,15 @@ static struct scsi_host_template ufshcd_driver_template = {
|
||||||
static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg,
|
static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg,
|
||||||
int ua)
|
int ua)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret;
|
||||||
struct regulator *reg = vreg->reg;
|
|
||||||
const char *name = vreg->name;
|
|
||||||
|
|
||||||
BUG_ON(!vreg);
|
if (!vreg)
|
||||||
|
return 0;
|
||||||
|
|
||||||
ret = regulator_set_optimum_mode(reg, ua);
|
ret = regulator_set_load(vreg->reg, ua);
|
||||||
if (ret >= 0) {
|
if (ret < 0) {
|
||||||
/*
|
dev_err(dev, "%s: %s set load (ua=%d) failed, err=%d\n",
|
||||||
* regulator_set_optimum_mode() returns new regulator
|
__func__, vreg->name, ua, ret);
|
||||||
* mode upon success.
|
|
||||||
*/
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
dev_err(dev, "%s: %s set optimum mode(ua=%d) failed, err=%d\n",
|
|
||||||
__func__, name, ua, ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -4249,18 +4242,12 @@ static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg,
|
||||||
static inline int ufshcd_config_vreg_lpm(struct ufs_hba *hba,
|
static inline int ufshcd_config_vreg_lpm(struct ufs_hba *hba,
|
||||||
struct ufs_vreg *vreg)
|
struct ufs_vreg *vreg)
|
||||||
{
|
{
|
||||||
if (!vreg)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return ufshcd_config_vreg_load(hba->dev, vreg, UFS_VREG_LPM_LOAD_UA);
|
return ufshcd_config_vreg_load(hba->dev, vreg, UFS_VREG_LPM_LOAD_UA);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba,
|
static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba,
|
||||||
struct ufs_vreg *vreg)
|
struct ufs_vreg *vreg)
|
||||||
{
|
{
|
||||||
if (!vreg)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return ufshcd_config_vreg_load(hba->dev, vreg, vreg->max_uA);
|
return ufshcd_config_vreg_load(hba->dev, vreg, vreg->max_uA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,7 @@ static void ab8500_usb_regulator_enable(struct ab8500_usb *ab)
|
||||||
dev_err(ab->dev, "Failed to set the Vintcore to 1.3V, ret=%d\n",
|
dev_err(ab->dev, "Failed to set the Vintcore to 1.3V, ret=%d\n",
|
||||||
ret);
|
ret);
|
||||||
|
|
||||||
ret = regulator_set_optimum_mode(ab->v_ulpi, 28000);
|
ret = regulator_set_load(ab->v_ulpi, 28000);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n",
|
dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n",
|
||||||
ret);
|
ret);
|
||||||
|
@ -317,7 +317,7 @@ static void ab8500_usb_regulator_disable(struct ab8500_usb *ab)
|
||||||
ab->saved_v_ulpi, ret);
|
ab->saved_v_ulpi, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = regulator_set_optimum_mode(ab->v_ulpi, 0);
|
ret = regulator_set_load(ab->v_ulpi, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n",
|
dev_err(ab->dev, "Failed to set optimum mode (ret=%d)\n",
|
||||||
ret);
|
ret);
|
||||||
|
|
|
@ -142,27 +142,22 @@ static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, int on)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (on) {
|
if (on) {
|
||||||
ret = regulator_set_optimum_mode(motg->v1p8,
|
ret = regulator_set_load(motg->v1p8, USB_PHY_1P8_HPM_LOAD);
|
||||||
USB_PHY_1P8_HPM_LOAD);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("Could not set HPM for v1p8\n");
|
pr_err("Could not set HPM for v1p8\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = regulator_set_optimum_mode(motg->v3p3,
|
ret = regulator_set_load(motg->v3p3, USB_PHY_3P3_HPM_LOAD);
|
||||||
USB_PHY_3P3_HPM_LOAD);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("Could not set HPM for v3p3\n");
|
pr_err("Could not set HPM for v3p3\n");
|
||||||
regulator_set_optimum_mode(motg->v1p8,
|
regulator_set_load(motg->v1p8, USB_PHY_1P8_LPM_LOAD);
|
||||||
USB_PHY_1P8_LPM_LOAD);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = regulator_set_optimum_mode(motg->v1p8,
|
ret = regulator_set_load(motg->v1p8, USB_PHY_1P8_LPM_LOAD);
|
||||||
USB_PHY_1P8_LPM_LOAD);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
pr_err("Could not set LPM for v1p8\n");
|
pr_err("Could not set LPM for v1p8\n");
|
||||||
ret = regulator_set_optimum_mode(motg->v3p3,
|
ret = regulator_set_load(motg->v3p3, USB_PHY_3P3_LPM_LOAD);
|
||||||
USB_PHY_3P3_LPM_LOAD);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
pr_err("Could not set LPM for v3p3\n");
|
pr_err("Could not set LPM for v3p3\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#ifndef __LINUX_MFD_MAX77693_H
|
#ifndef __LINUX_MFD_MAX77693_H
|
||||||
#define __LINUX_MFD_MAX77693_H
|
#define __LINUX_MFD_MAX77693_H
|
||||||
|
|
||||||
/* MAX77686 regulator IDs */
|
/* MAX77693 regulator IDs */
|
||||||
enum max77693_regulators {
|
enum max77693_regulators {
|
||||||
MAX77693_ESAFEOUT1 = 0,
|
MAX77693_ESAFEOUT1 = 0,
|
||||||
MAX77693_ESAFEOUT2,
|
MAX77693_ESAFEOUT2,
|
||||||
|
@ -38,12 +38,6 @@ enum max77693_regulators {
|
||||||
MAX77693_REG_MAX,
|
MAX77693_REG_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct max77693_regulator_data {
|
|
||||||
int id;
|
|
||||||
struct regulator_init_data *initdata;
|
|
||||||
struct device_node *of_node;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct max77693_reg_data {
|
struct max77693_reg_data {
|
||||||
u8 addr;
|
u8 addr;
|
||||||
u8 data;
|
u8 data;
|
||||||
|
@ -103,10 +97,6 @@ struct max77693_led_platform_data {
|
||||||
/* MAX77693 */
|
/* MAX77693 */
|
||||||
|
|
||||||
struct max77693_platform_data {
|
struct max77693_platform_data {
|
||||||
/* regulator data */
|
|
||||||
struct max77693_regulator_data *regulators;
|
|
||||||
int num_regulators;
|
|
||||||
|
|
||||||
/* muic data */
|
/* muic data */
|
||||||
struct max77693_muic_platform_data *muic_data;
|
struct max77693_muic_platform_data *muic_data;
|
||||||
struct max77693_led_platform_data *led_data;
|
struct max77693_led_platform_data *led_data;
|
||||||
|
|
|
@ -117,6 +117,7 @@ struct palmas_pmic_driver_data {
|
||||||
int ldo_begin;
|
int ldo_begin;
|
||||||
int ldo_end;
|
int ldo_end;
|
||||||
int max_reg;
|
int max_reg;
|
||||||
|
bool has_regen3;
|
||||||
struct palmas_regs_info *palmas_regs_info;
|
struct palmas_regs_info *palmas_regs_info;
|
||||||
struct of_regulator_match *palmas_matches;
|
struct of_regulator_match *palmas_matches;
|
||||||
struct palmas_sleep_requestor_info *sleep_req_info;
|
struct palmas_sleep_requestor_info *sleep_req_info;
|
||||||
|
|
|
@ -41,15 +41,11 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct stw481x - state holder for the Stw481x drivers
|
* struct stw481x - state holder for the Stw481x drivers
|
||||||
* @mutex: mutex to serialize I2C accesses
|
|
||||||
* @i2c_client: corresponding I2C client
|
* @i2c_client: corresponding I2C client
|
||||||
* @regulator: regulator device for regulator children
|
|
||||||
* @map: regmap handle to access device registers
|
* @map: regmap handle to access device registers
|
||||||
*/
|
*/
|
||||||
struct stw481x {
|
struct stw481x {
|
||||||
struct mutex lock;
|
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct regulator_dev *vmmc_regulator;
|
|
||||||
struct regmap *map;
|
struct regmap *map;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,19 @@
|
||||||
|
|
||||||
#include <linux/regulator/machine.h>
|
#include <linux/regulator/machine.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ACT8600_ID_DCDC1,
|
||||||
|
ACT8600_ID_DCDC2,
|
||||||
|
ACT8600_ID_DCDC3,
|
||||||
|
ACT8600_ID_SUDCDC4,
|
||||||
|
ACT8600_ID_LDO5,
|
||||||
|
ACT8600_ID_LDO6,
|
||||||
|
ACT8600_ID_LDO7,
|
||||||
|
ACT8600_ID_LDO8,
|
||||||
|
ACT8600_ID_LDO9,
|
||||||
|
ACT8600_ID_LDO10,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ACT8865_ID_DCDC1,
|
ACT8865_ID_DCDC1,
|
||||||
ACT8865_ID_DCDC2,
|
ACT8865_ID_DCDC2,
|
||||||
|
@ -46,6 +59,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
ACT8600,
|
||||||
ACT8865,
|
ACT8865,
|
||||||
ACT8846,
|
ACT8846,
|
||||||
};
|
};
|
||||||
|
|
|
@ -114,7 +114,7 @@ struct regmap;
|
||||||
#define REGULATOR_EVENT_OVER_TEMP 0x10
|
#define REGULATOR_EVENT_OVER_TEMP 0x10
|
||||||
#define REGULATOR_EVENT_FORCE_DISABLE 0x20
|
#define REGULATOR_EVENT_FORCE_DISABLE 0x20
|
||||||
#define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
|
#define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
|
||||||
#define REGULATOR_EVENT_DISABLE 0x80
|
#define REGULATOR_EVENT_DISABLE 0x80
|
||||||
#define REGULATOR_EVENT_PRE_VOLTAGE_CHANGE 0x100
|
#define REGULATOR_EVENT_PRE_VOLTAGE_CHANGE 0x100
|
||||||
#define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200
|
#define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200
|
||||||
#define REGULATOR_EVENT_PRE_DISABLE 0x400
|
#define REGULATOR_EVENT_PRE_DISABLE 0x400
|
||||||
|
@ -238,7 +238,7 @@ int regulator_get_current_limit(struct regulator *regulator);
|
||||||
|
|
||||||
int regulator_set_mode(struct regulator *regulator, unsigned int mode);
|
int regulator_set_mode(struct regulator *regulator, unsigned int mode);
|
||||||
unsigned int regulator_get_mode(struct regulator *regulator);
|
unsigned int regulator_get_mode(struct regulator *regulator);
|
||||||
int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
|
int regulator_set_load(struct regulator *regulator, int load_uA);
|
||||||
|
|
||||||
int regulator_allow_bypass(struct regulator *regulator, bool allow);
|
int regulator_allow_bypass(struct regulator *regulator, bool allow);
|
||||||
|
|
||||||
|
@ -252,8 +252,12 @@ int regulator_list_hardware_vsel(struct regulator *regulator,
|
||||||
/* regulator notifier block */
|
/* regulator notifier block */
|
||||||
int regulator_register_notifier(struct regulator *regulator,
|
int regulator_register_notifier(struct regulator *regulator,
|
||||||
struct notifier_block *nb);
|
struct notifier_block *nb);
|
||||||
|
int devm_regulator_register_notifier(struct regulator *regulator,
|
||||||
|
struct notifier_block *nb);
|
||||||
int regulator_unregister_notifier(struct regulator *regulator,
|
int regulator_unregister_notifier(struct regulator *regulator,
|
||||||
struct notifier_block *nb);
|
struct notifier_block *nb);
|
||||||
|
void devm_regulator_unregister_notifier(struct regulator *regulator,
|
||||||
|
struct notifier_block *nb);
|
||||||
|
|
||||||
/* driver data - core doesn't touch */
|
/* driver data - core doesn't touch */
|
||||||
void *regulator_get_drvdata(struct regulator *regulator);
|
void *regulator_get_drvdata(struct regulator *regulator);
|
||||||
|
@ -479,8 +483,7 @@ static inline unsigned int regulator_get_mode(struct regulator *regulator)
|
||||||
return REGULATOR_MODE_NORMAL;
|
return REGULATOR_MODE_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int regulator_set_optimum_mode(struct regulator *regulator,
|
static inline int regulator_set_load(struct regulator *regulator, int load_uA)
|
||||||
int load_uA)
|
|
||||||
{
|
{
|
||||||
return REGULATOR_MODE_NORMAL;
|
return REGULATOR_MODE_NORMAL;
|
||||||
}
|
}
|
||||||
|
@ -515,12 +518,24 @@ static inline int regulator_register_notifier(struct regulator *regulator,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int devm_regulator_register_notifier(struct regulator *regulator,
|
||||||
|
struct notifier_block *nb)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int regulator_unregister_notifier(struct regulator *regulator,
|
static inline int regulator_unregister_notifier(struct regulator *regulator,
|
||||||
struct notifier_block *nb)
|
struct notifier_block *nb)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int devm_regulator_unregister_notifier(struct regulator *regulator,
|
||||||
|
struct notifier_block *nb)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void *regulator_get_drvdata(struct regulator *regulator)
|
static inline void *regulator_get_drvdata(struct regulator *regulator)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -98,6 +98,7 @@ struct regulator_linear_range {
|
||||||
* REGULATOR_STATUS value (or negative errno)
|
* REGULATOR_STATUS value (or negative errno)
|
||||||
* @get_optimum_mode: Get the most efficient operating mode for the regulator
|
* @get_optimum_mode: Get the most efficient operating mode for the regulator
|
||||||
* when running with the specified parameters.
|
* when running with the specified parameters.
|
||||||
|
* @set_load: Set the load for the regulator.
|
||||||
*
|
*
|
||||||
* @set_bypass: Set the regulator in bypass mode.
|
* @set_bypass: Set the regulator in bypass mode.
|
||||||
* @get_bypass: Get the regulator bypass mode state.
|
* @get_bypass: Get the regulator bypass mode state.
|
||||||
|
@ -167,6 +168,8 @@ struct regulator_ops {
|
||||||
/* get most efficient regulator operating mode for load */
|
/* get most efficient regulator operating mode for load */
|
||||||
unsigned int (*get_optimum_mode) (struct regulator_dev *, int input_uV,
|
unsigned int (*get_optimum_mode) (struct regulator_dev *, int input_uV,
|
||||||
int output_uV, int load_uA);
|
int output_uV, int load_uA);
|
||||||
|
/* set the load on the regulator */
|
||||||
|
int (*set_load)(struct regulator_dev *, int load_uA);
|
||||||
|
|
||||||
/* control and report on bypass mode */
|
/* control and report on bypass mode */
|
||||||
int (*set_bypass)(struct regulator_dev *dev, bool enable);
|
int (*set_bypass)(struct regulator_dev *dev, bool enable);
|
||||||
|
@ -367,6 +370,7 @@ struct regulator_dev {
|
||||||
struct device dev;
|
struct device dev;
|
||||||
struct regulation_constraints *constraints;
|
struct regulation_constraints *constraints;
|
||||||
struct regulator *supply; /* for tree */
|
struct regulator *supply; /* for tree */
|
||||||
|
const char *supply_name;
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
|
|
||||||
struct delayed_work disable_work;
|
struct delayed_work disable_work;
|
||||||
|
|
Loading…
Reference in New Issue