Commit 5a9f228a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'regulator-v4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "This is an extremely quiet release for the regulator API, we've got a
  small set of bug fixes and minor feature enhancements for drivers plus
  a couple of more visible changes:

   - add support for ramp times in regulators that don't use selectors.

   - new driver for LTC3676"

* tag 'regulator-v4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
  regulator: dbx500: remove unused functions in dbx500-prcmu.c
  regulator: pv88080: Update regulator for PV88080 BB silicon support
  regulator: core: don't return error with inadequate reason
  regulator: tps65910: Work around silicon erratum SWCZ010
  regulator: core: Add set_voltage_time op
  regulator: core: Don't skip set_voltage_time when ramp delay disabled
  regulator: core: Simplify error flow in _regulator_do_set_voltage()
  regulator: core: Use local ops variable in _regulator_do_set_voltage()
  regulator: hi6421: mark hi6421_regulator_ldo_get_optimum_mode() static
  regulator: Kconfig: Fix typo
  regulator: bindings: Use the correct symbol for second
  regulator: Remove support for optional supplies in the bulk API
  regulator: Add LTC3676 support
  regulator: rk808: Delete owner assignment
  regulator: tps65218: do not disable DCDC3 during poweroff on broken PMICs
  mfd: tps65218: add version check to the PMIC probe
parents 808c2b05 2ed89d57
Linear Technology LTC3676 8-output regulators
Required properties:
- compatible: "lltc,ltc3676"
- reg: I2C slave address
Required child node:
- regulators: Contains eight regulator child nodes sw1, sw2, sw3, sw4,
ldo1, ldo2, ldo3, and ldo4, specifying the initialization data as
documented in Documentation/devicetree/bindings/regulator/regulator.txt.
Each regulator is defined using the standard binding for regulators. The
nodes for sw1, sw2, sw3, sw4, ldo1, ldo2 and ldo4 additionally need to specify
the resistor values of their external feedback voltage dividers:
Required properties (not on ldo3):
- lltc,fb-voltage-divider: An array of two integers containing the resistor
values R1 and R2 of the feedback voltage divider in ohms.
Regulators sw1, sw2, sw3, sw4 can regulate the feedback reference from:
412.5mV to 800mV in 12.5 mV steps. The output voltage thus ranges between
0.4125 * (1 + R1/R2) V and 0.8 * (1 + R1/R2) V.
Regulators ldo1, ldo2, and ldo4 have a fixed 0.725 V reference and thus output
0.725 * (1 + R1/R2) V. The ldo3 regulator is fixed to 1.8 V. The ldo1 standby
regulator can not be disabled and thus should have the regulator-always-on
property set.
Example:
ltc3676: pmic@3c {
compatible = "lltc,ltc3676";
reg = <0x3c>;
regulators {
sw1_reg: sw1 {
regulator-min-microvolt = <674400>;
regulator-max-microvolt = <1308000>;
lltc,fb-voltage-divider = <127000 200000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
sw2_reg: sw2 {
regulator-min-microvolt = <1033310>;
regulator-max-microvolt = <200400>;
lltc,fb-voltage-divider = <301000 200000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
sw3_reg: sw3 {
regulator-min-microvolt = <674400>;
regulator-max-microvolt = <130800>;
lltc,fb-voltage-divider = <127000 200000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
sw4_reg: sw4 {
regulator-min-microvolt = <868310>;
regulator-max-microvolt = <168400>;
lltc,fb-voltage-divider = <221000 200000>;
regulator-ramp-delay = <7000>;
regulator-boot-on;
regulator-always-on;
};
ldo2_reg: ldo2 {
regulator-min-microvolt = <2490375>;
regulator-max-microvolt = <2490375>;
lltc,fb-voltage-divider = <487000 200000>;
regulator-boot-on;
regulator-always-on;
};
ldo3_reg: ldo3 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
};
ldo4_reg: ldo4 {
regulator-min-microvolt = <3023250>;
regulator-max-microvolt = <3023250>;
lltc,fb-voltage-divider = <634000 200000>;
regulator-boot-on;
regulator-always-on;
};
};
};
* Powerventure Semiconductor PV88080 Voltage Regulator * Powerventure Semiconductor PV88080 Voltage Regulator
Required properties: Required properties:
- compatible: "pvs,pv88080". - compatible: Must be one of the following, depending on the
- reg: I2C slave address, usually 0x49. silicon version:
- "pvs,pv88080" (DEPRECATED)
- "pvs,pv88080-aa" for PV88080 AA or AB silicon
- "pvs,pv88080-ba" for PV88080 BA or BB silicon
NOTE: The use of the compatibles with no silicon version is deprecated.
- reg: I2C slave address, usually 0x49
- interrupts: the interrupt outputs of the controller - interrupts: the interrupt outputs of the controller
- regulators: A node that houses a sub-node for each regulator within the - regulators: A node that houses a sub-node for each regulator within the
device. Each sub-node is identified using the node's name, with valid device. Each sub-node is identified using the node's name, with valid
values listed below. The content of each sub-node is defined by the values listed below. The content of each sub-node is defined by the
standard binding for regulators; see regulator.txt. standard binding for regulators; see regulator.txt.
BUCK1, BUCK2, and BUCK3. BUCK1, BUCK2, BUCK3 and HVBUCK.
Optional properties: Optional properties:
- Any optional property defined in regulator.txt - Any optional property defined in regulator.txt
Example Example:
pmic: pv88080@49 { pmic: pv88080@49 {
compatible = "pvs,pv88080"; compatible = "pvs,pv88080-ba";
reg = <0x49>; reg = <0x49>;
interrupt-parent = <&gpio>; interrupt-parent = <&gpio>;
interrupts = <24 24>; interrupts = <24 24>;
...@@ -45,5 +51,12 @@ Example ...@@ -45,5 +51,12 @@ Example
regulator-min-microamp = <1496000>; regulator-min-microamp = <1496000>;
regulator-max-microamp = <4189000>; regulator-max-microamp = <4189000>;
}; };
HVBUCK {
regulator-name = "hvbuck";
regulator-min-microvolt = < 5000>;
regulator-max-microvolt = <1275000>;
};
}; };
}; };
...@@ -13,7 +13,7 @@ Optional properties: ...@@ -13,7 +13,7 @@ Optional properties:
- regulator-allow-bypass: allow the regulator to go into bypass mode - regulator-allow-bypass: allow the regulator to go into bypass mode
- regulator-allow-set-load: allow the regulator performance level to be configured - regulator-allow-set-load: allow the regulator performance level to be configured
- <name>-supply: phandle to the parent supply/regulator node - <name>-supply: phandle to the parent supply/regulator node
- regulator-ramp-delay: ramp delay for regulator(in uV/uS) - regulator-ramp-delay: ramp delay for regulator(in uV/us)
For hardware which supports disabling ramp rate, it should be explicitly For hardware which supports disabling ramp rate, it should be explicitly
initialised to zero (regulator-ramp-delay = <0>) for disabling ramp delay. initialised to zero (regulator-ramp-delay = <0>) for disabling ramp delay.
- regulator-enable-ramp-delay: The time taken, in microseconds, for the supply - regulator-enable-ramp-delay: The time taken, in microseconds, for the supply
......
...@@ -219,6 +219,7 @@ static int tps65218_probe(struct i2c_client *client, ...@@ -219,6 +219,7 @@ static int tps65218_probe(struct i2c_client *client,
struct tps65218 *tps; struct tps65218 *tps;
const struct of_device_id *match; const struct of_device_id *match;
int ret; int ret;
unsigned int chipid;
match = of_match_device(of_tps65218_match_table, &client->dev); match = of_match_device(of_tps65218_match_table, &client->dev);
if (!match) { if (!match) {
...@@ -250,6 +251,14 @@ static int tps65218_probe(struct i2c_client *client, ...@@ -250,6 +251,14 @@ static int tps65218_probe(struct i2c_client *client,
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = tps65218_reg_read(tps, TPS65218_REG_CHIPID, &chipid);
if (ret) {
dev_err(tps->dev, "Failed to read chipid: %d\n", ret);
return ret;
}
tps->rev = chipid & TPS65218_CHIPID_REV_MASK;
ret = of_platform_populate(client->dev.of_node, NULL, NULL, ret = of_platform_populate(client->dev.of_node, NULL, NULL,
&client->dev); &client->dev);
if (ret < 0) if (ret < 0)
......
...@@ -353,6 +353,14 @@ config REGULATOR_LTC3589 ...@@ -353,6 +353,14 @@ config REGULATOR_LTC3589
This enables support for the LTC3589, LTC3589-1, and LTC3589-2 This enables support for the LTC3589, LTC3589-1, and LTC3589-2
8-output regulators controlled via I2C. 8-output regulators controlled via I2C.
config REGULATOR_LTC3676
tristate "LTC3676 8-output voltage regulator"
depends on I2C
select REGMAP_I2C
help
This enables support for the LTC3676
8-output regulators controlled via I2C.
config REGULATOR_MAX14577 config REGULATOR_MAX14577
tristate "Maxim 14577/77836 regulator" tristate "Maxim 14577/77836 regulator"
depends on MFD_MAX14577 depends on MFD_MAX14577
...@@ -820,7 +828,7 @@ config REGULATOR_TPS65912 ...@@ -820,7 +828,7 @@ config REGULATOR_TPS65912
This driver supports TPS65912 voltage regulator chip. This driver supports TPS65912 voltage regulator chip.
config REGULATOR_TPS80031 config REGULATOR_TPS80031
tristate "TI TPS80031/TPS80032 power regualtor driver" tristate "TI TPS80031/TPS80032 power regulator driver"
depends on MFD_TPS80031 depends on MFD_TPS80031
help help
TPS80031/ TPS80032 Fully Integrated Power Management with Power TPS80031/ TPS80032 Fully Integrated Power Management with Power
......
...@@ -47,6 +47,7 @@ obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o ...@@ -47,6 +47,7 @@ obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o
obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o
obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o
obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
......
...@@ -679,6 +679,18 @@ static int drms_uA_update(struct regulator_dev *rdev) ...@@ -679,6 +679,18 @@ static int drms_uA_update(struct regulator_dev *rdev)
!rdev->desc->ops->set_load) !rdev->desc->ops->set_load)
return -EINVAL; return -EINVAL;
/* calc total requested load */
list_for_each_entry(sibling, &rdev->consumer_list, list)
current_uA += sibling->uA_load;
current_uA += rdev->constraints->system_load;
if (rdev->desc->ops->set_load) {
/* set the optimum mode for our new total regulator load */
err = rdev->desc->ops->set_load(rdev, current_uA);
if (err < 0)
rdev_err(rdev, "failed to set load %d\n", current_uA);
} else {
/* get output voltage */ /* get output voltage */
output_uV = _regulator_get_voltage(rdev); output_uV = _regulator_get_voltage(rdev);
if (output_uV <= 0) { if (output_uV <= 0) {
...@@ -697,18 +709,6 @@ static int drms_uA_update(struct regulator_dev *rdev) ...@@ -697,18 +709,6 @@ static int drms_uA_update(struct regulator_dev *rdev)
return -EINVAL; return -EINVAL;
} }
/* calc total requested load */
list_for_each_entry(sibling, &rdev->consumer_list, list)
current_uA += sibling->uA_load;
current_uA += rdev->constraints->system_load;
if (rdev->desc->ops->set_load) {
/* set the optimum mode for our new total regulator load */
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 */ /* now get the optimum mode for our new total regulator load */
mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV, mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV,
output_uV, current_uA); output_uV, current_uA);
...@@ -2743,6 +2743,24 @@ static int _regulator_call_set_voltage_sel(struct regulator_dev *rdev, ...@@ -2743,6 +2743,24 @@ static int _regulator_call_set_voltage_sel(struct regulator_dev *rdev,
return ret; return ret;
} }
static int _regulator_set_voltage_time(struct regulator_dev *rdev,
int old_uV, int new_uV)
{
unsigned int ramp_delay = 0;
if (rdev->constraints->ramp_delay)
ramp_delay = rdev->constraints->ramp_delay;
else if (rdev->desc->ramp_delay)
ramp_delay = rdev->desc->ramp_delay;
if (ramp_delay == 0) {
rdev_warn(rdev, "ramp_delay not set\n");
return 0;
}
return DIV_ROUND_UP(abs(new_uV - old_uV), ramp_delay);
}
static int _regulator_do_set_voltage(struct regulator_dev *rdev, static int _regulator_do_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV) int min_uV, int max_uV)
{ {
...@@ -2751,6 +2769,8 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, ...@@ -2751,6 +2769,8 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
int best_val = 0; int best_val = 0;
unsigned int selector; unsigned int selector;
int old_selector = -1; int old_selector = -1;
const struct regulator_ops *ops = rdev->desc->ops;
int old_uV = _regulator_get_voltage(rdev);
trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
...@@ -2762,29 +2782,28 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, ...@@ -2762,29 +2782,28 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
* info to call set_voltage_time_sel(). * info to call set_voltage_time_sel().
*/ */
if (_regulator_is_enabled(rdev) && if (_regulator_is_enabled(rdev) &&
rdev->desc->ops->set_voltage_time_sel && ops->set_voltage_time_sel && ops->get_voltage_sel) {
rdev->desc->ops->get_voltage_sel) { old_selector = ops->get_voltage_sel(rdev);
old_selector = rdev->desc->ops->get_voltage_sel(rdev);
if (old_selector < 0) if (old_selector < 0)
return old_selector; return old_selector;
} }
if (rdev->desc->ops->set_voltage) { if (ops->set_voltage) {
ret = _regulator_call_set_voltage(rdev, min_uV, max_uV, ret = _regulator_call_set_voltage(rdev, min_uV, max_uV,
&selector); &selector);
if (ret >= 0) { if (ret >= 0) {
if (rdev->desc->ops->list_voltage) if (ops->list_voltage)
best_val = rdev->desc->ops->list_voltage(rdev, best_val = ops->list_voltage(rdev,
selector); selector);
else else
best_val = _regulator_get_voltage(rdev); best_val = _regulator_get_voltage(rdev);
} }
} else if (rdev->desc->ops->set_voltage_sel) { } else if (ops->set_voltage_sel) {
ret = regulator_map_voltage(rdev, min_uV, max_uV); ret = regulator_map_voltage(rdev, min_uV, max_uV);
if (ret >= 0) { if (ret >= 0) {
best_val = rdev->desc->ops->list_voltage(rdev, ret); best_val = ops->list_voltage(rdev, ret);
if (min_uV <= best_val && max_uV >= best_val) { if (min_uV <= best_val && max_uV >= best_val) {
selector = ret; selector = ret;
if (old_selector == selector) if (old_selector == selector)
...@@ -2800,15 +2819,31 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, ...@@ -2800,15 +2819,31 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
ret = -EINVAL; ret = -EINVAL;
} }
/* Call set_voltage_time_sel if successfully obtained old_selector */ if (ret)
if (ret == 0 && !rdev->constraints->ramp_disable && old_selector >= 0 goto out;
&& old_selector != selector) {
if (ops->set_voltage_time_sel) {
/*
* Call set_voltage_time_sel if successfully obtained
* old_selector
*/
if (old_selector >= 0 && old_selector != selector)
delay = ops->set_voltage_time_sel(rdev, old_selector,
selector);
} else {
if (old_uV != best_val) {
if (ops->set_voltage_time)
delay = ops->set_voltage_time(rdev, old_uV,
best_val);
else
delay = _regulator_set_voltage_time(rdev,
old_uV,
best_val);
}
}
delay = rdev->desc->ops->set_voltage_time_sel(rdev,
old_selector, selector);
if (delay < 0) { if (delay < 0) {
rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", rdev_warn(rdev, "failed to get delay: %d\n", delay);
delay);
delay = 0; delay = 0;
} }
...@@ -2819,15 +2854,15 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, ...@@ -2819,15 +2854,15 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
} else if (delay) { } else if (delay) {
udelay(delay); udelay(delay);
} }
}
if (ret == 0 && best_val >= 0) { if (best_val >= 0) {
unsigned long data = best_val; unsigned long data = best_val;
_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
(void *)data); (void *)data);
} }
out:
trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val); trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);
return ret; return ret;
...@@ -2998,9 +3033,13 @@ int regulator_set_voltage_time(struct regulator *regulator, ...@@ -2998,9 +3033,13 @@ int regulator_set_voltage_time(struct regulator *regulator,
int voltage; int voltage;
int i; int i;
if (ops->set_voltage_time)
return ops->set_voltage_time(rdev, old_uV, new_uV);
else if (!ops->set_voltage_time_sel)
return _regulator_set_voltage_time(rdev, old_uV, new_uV);
/* Currently requires operations to do this */ /* Currently requires operations to do this */
if (!ops->list_voltage || !ops->set_voltage_time_sel if (!ops->list_voltage || !rdev->desc->n_voltages)
|| !rdev->desc->n_voltages)
return -EINVAL; return -EINVAL;
for (i = 0; i < rdev->desc->n_voltages; i++) { for (i = 0; i < rdev->desc->n_voltages; i++) {
...@@ -3039,19 +3078,8 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, ...@@ -3039,19 +3078,8 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
unsigned int old_selector, unsigned int old_selector,
unsigned int new_selector) unsigned int new_selector)
{ {
unsigned int ramp_delay = 0;
int old_volt, new_volt; int old_volt, new_volt;
if (rdev->constraints->ramp_delay)
ramp_delay = rdev->constraints->ramp_delay;
else if (rdev->desc->ramp_delay)
ramp_delay = rdev->desc->ramp_delay;
if (ramp_delay == 0) {
rdev_warn(rdev, "ramp_delay not set\n");
return 0;
}
/* sanity check */ /* sanity check */
if (!rdev->desc->ops->list_voltage) if (!rdev->desc->ops->list_voltage)
return -EINVAL; return -EINVAL;
...@@ -3059,7 +3087,11 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev, ...@@ -3059,7 +3087,11 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
old_volt = rdev->desc->ops->list_voltage(rdev, old_selector); old_volt = rdev->desc->ops->list_voltage(rdev, old_selector);
new_volt = rdev->desc->ops->list_voltage(rdev, new_selector); new_volt = rdev->desc->ops->list_voltage(rdev, new_selector);
return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay); if (rdev->desc->ops->set_voltage_time)
return rdev->desc->ops->set_voltage_time(rdev, old_volt,
new_volt);
else
return _regulator_set_voltage_time(rdev, old_volt, new_volt);
} }
EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel); EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel);
...@@ -3483,10 +3515,8 @@ int regulator_bulk_get(struct device *dev, int num_consumers, ...@@ -3483,10 +3515,8 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
consumers[i].consumer = NULL; consumers[i].consumer = NULL;
for (i = 0; i < num_consumers; i++) { for (i = 0; i < num_consumers; i++) {
consumers[i].consumer = _regulator_get(dev, consumers[i].consumer = regulator_get(dev,
consumers[i].supply, consumers[i].supply);
false,
!consumers[i].optional);
if (IS_ERR(consumers[i].consumer)) { if (IS_ERR(consumers[i].consumer)) {
ret = PTR_ERR(consumers[i].consumer); ret = PTR_ERR(consumers[i].consumer);
dev_err(dev, "Failed to get supply '%s': %d\n", dev_err(dev, "Failed to get supply '%s': %d\n",
......
...@@ -75,24 +75,6 @@ static struct ux500_regulator_debug { ...@@ -75,24 +75,6 @@ static struct ux500_regulator_debug {
u8 *state_after_suspend; u8 *state_after_suspend;
} rdebug; } rdebug;
void ux500_regulator_suspend_debug(void)
{
int i;
for (i = 0; i < rdebug.num_regulators; i++)
rdebug.state_before_suspend[i] =
rdebug.regulator_array[i].is_enabled;
}
void ux500_regulator_resume_debug(void)
{
int i;
for (i = 0; i < rdebug.num_regulators; i++)
rdebug.state_after_suspend[i] =
rdebug.regulator_array[i].is_enabled;
}
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)
{ {
/* print power state count */ /* print power state count */
......
...@@ -164,11 +164,8 @@ int devm_regulator_bulk_get(struct device *dev, int num_consumers, ...@@ -164,11 +164,8 @@ int devm_regulator_bulk_get(struct device *dev, int num_consumers,
consumers[i].consumer = NULL; consumers[i].consumer = NULL;
for (i = 0; i < num_consumers; i++) { for (i = 0; i < num_consumers; i++) {
consumers[i].consumer = _devm_regulator_get(dev, consumers[i].consumer = devm_regulator_get(dev,
consumers[i].supply, consumers[i].supply);
consumers[i].optional ?
OPTIONAL_GET :
NORMAL_GET);
if (IS_ERR(consumers[i].consumer)) { if (IS_ERR(consumers[i].consumer)) {
ret = PTR_ERR(consumers[i].consumer); ret = PTR_ERR(consumers[i].consumer);
dev_err(dev, "Failed to get supply '%s': %d\n", dev_err(dev, "Failed to get supply '%s': %d\n",
......
...@@ -477,7 +477,8 @@ static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev, ...@@ -477,7 +477,8 @@ static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev,
return 0; return 0;
} }
unsigned int hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev, static unsigned int
hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev,
int input_uV, int output_uV, int load_uA) int input_uV, int output_uV, int load_uA)
{ {
struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
......
This diff is collapsed.
This diff is collapsed.
...@@ -19,22 +19,40 @@ ...@@ -19,22 +19,40 @@
/* System Control and Event Registers */ /* System Control and Event Registers */
#define PV88080_REG_EVENT_A 0x04 #define PV88080_REG_EVENT_A 0x04
#define PV88080_REG_MASK_A 0x09 #define PV88080_REG_MASK_A 0x09
#define PV88080_REG_MASK_B 0x0a #define PV88080_REG_MASK_B 0x0A
#define PV88080_REG_MASK_C 0x0b #define PV88080_REG_MASK_C 0x0B
/* Regulator Registers */ /* Regulator Registers - rev. AA */
#define PV88080_REG_BUCK1_CONF0 0x27 #define PV88080AA_REG_HVBUCK_CONF1 0x2D
#define PV88080_REG_BUCK1_CONF1 0x28 #define PV88080AA_REG_HVBUCK_CONF2 0x2E
#define PV88080_REG_BUCK1_CONF2 0x59 #define PV88080AA_REG_BUCK1_CONF0 0x27
#define PV88080_REG_BUCK1_CONF5 0x5c #define PV88080AA_REG_BUCK1_CONF1 0x28
#define PV88080_REG_BUCK2_CONF0 0x29 #define PV88080AA_REG_BUCK1_CONF2 0x59
#define PV88080_REG_BUCK2_CONF1 0x2a #define PV88080AA_REG_BUCK1_CONF5 0x5C
#define PV88080_REG_BUCK2_CONF2 0x61 #define PV88080AA_REG_BUCK2_CONF0 0x29
#define PV88080_REG_BUCK2_CONF5 0x64 #define PV88080AA_REG_BUCK2_CONF1 0x2A
#define PV88080_REG_BUCK3_CONF0 0x2b #define PV88080AA_REG_BUCK2_CONF2 0x61
#define PV88080_REG_BUCK3_CONF1 0x2c #define PV88080AA_REG_BUCK2_CONF5 0x64
#define PV88080_REG_BUCK3_CONF2 0x69 #define PV88080AA_REG_BUCK3_CONF0 0x2B
#define PV88080_REG_BUCK3_CONF5 0x6c #define PV88080AA_REG_BUCK3_CONF1 0x2C
#define PV88080AA_REG_BUCK3_CONF2 0x69
#define PV88080AA_REG_BUCK3_CONF5 0x6C
/* Regulator Registers - rev. BA */
#define PV88080BA_REG_HVBUCK_CONF1 0x33
#define PV88080BA_REG_HVBUCK_CONF2 0x34
#define PV88080BA_REG_BUCK1_CONF0 0x2A
#define PV88080BA_REG_BUCK1_CONF1 0x2C
#define PV88080BA_REG_BUCK1_CONF2 0x5A
#define PV88080BA_REG_BUCK1_CONF5 0x5D
#define PV88080BA_REG_BUCK2_CONF0 0x2D
#define PV88080BA_REG_BUCK2_CONF1 0x2F
#define PV88080BA_REG_BUCK2_CONF2 0x63
#define PV88080BA_REG_BUCK2_CONF5 0x66
#define PV88080BA_REG_BUCK3_CONF0 0x30
#define PV88080BA_REG_BUCK3_CONF1 0x32
#define PV88080BA_REG_BUCK3_CONF2 0x6C
#define PV88080BA_REG_BUCK3_CONF5 0x6F
/* PV88080_REG_EVENT_A (addr=0x04) */ /* PV88080_REG_EVENT_A (addr=0x04) */
#define PV88080_E_VDD_FLT 0x01 #define PV88080_E_VDD_FLT 0x01
...@@ -44,27 +62,29 @@ ...@@ -44,27 +62,29 @@
#define PV88080_M_VDD_FLT 0x01 #define PV88080_M_VDD_FLT 0x01
#define PV88080_M_OVER_TEMP 0x02 #define PV88080_M_OVER_TEMP 0x02
/* PV88080_REG_BUCK1_CONF0 (addr=0x27) */ /* PV88080_REG_BUCK1_CONF0 (addr=0x27|0x2A) */
#define PV88080_BUCK1_EN 0x80 #define PV88080_BUCK1_EN 0x80
#define PV88080_VBUCK1_MASK 0x7F #define PV88080_VBUCK1_MASK 0x7F
/* PV88080_REG_BUCK2_CONF0 (addr=0x29) */
/* PV88080_REG_BUCK2_CONF0 (addr=0x29|0x2D) */
#define PV88080_BUCK2_EN 0x80 #define PV88080_BUCK2_EN 0x80
#define PV88080_VBUCK2_MASK 0x7F #define PV88080_VBUCK2_MASK 0x7F
/* PV88080_REG_BUCK3_CONF0 (addr=0x2b) */
/* PV88080_REG_BUCK3_CONF0 (addr=0x2B|0x30) */
#define PV88080_BUCK3_EN 0x80 #define PV88080_BUCK3_EN 0x80
#define PV88080_VBUCK3_MASK 0x7F #define PV88080_VBUCK3_MASK 0x7F
/* PV88080_REG_BUCK1_CONF1 (addr=0x28) */ /* PV88080_REG_BUCK1_CONF1 (addr=0x28|0x2C) */
#define PV88080_BUCK1_ILIM_SHIFT 2 #define PV88080_BUCK1_ILIM_SHIFT 2
#define PV88080_BUCK1_ILIM_MASK 0x0C #define PV88080_BUCK1_ILIM_MASK 0x0C
#define PV88080_BUCK1_MODE_MASK 0x03 #define PV88080_BUCK1_MODE_MASK 0x03
/* PV88080_REG_BUCK2_CONF1 (addr=0x2a) */ /* PV88080_REG_BUCK2_CONF1 (addr=0x2A|0x2F) */
#define PV88080_BUCK2_ILIM_SHIFT 2 #define PV88080_BUCK2_ILIM_SHIFT 2
#define PV88080_BUCK2_ILIM_MASK 0x0C #define PV88080_BUCK2_ILIM_MASK 0x0C
#define PV88080_BUCK2_MODE_MASK 0x03 #define PV88080_BUCK2_MODE_MASK 0x03
/* PV88080_REG_BUCK3_CONF1 (addr=0x2c) */ /* PV88080_REG_BUCK3_CONF1 (addr=0x2C|0x32) */
#define PV88080_BUCK3_ILIM_SHIFT 2 #define PV88080_BUCK3_ILIM_SHIFT 2
#define PV88080_BUCK3_ILIM_MASK 0x0C #define PV88080_BUCK3_ILIM_MASK 0x0C
#define PV88080_BUCK3_MODE_MASK 0x03 #define PV88080_BUCK3_MODE_MASK 0x03
...@@ -73,16 +93,22 @@ ...@@ -73,16 +93,22 @@
#define PV88080_BUCK_MODE_AUTO 0x01 #define PV88080_BUCK_MODE_AUTO 0x01
#define PV88080_BUCK_MODE_SYNC 0x02 #define PV88080_BUCK_MODE_SYNC 0x02
/* PV88080_REG_BUCK2_CONF2 (addr=0x61) */ /* PV88080_REG_HVBUCK_CONF1 (addr=0x2D|0x33) */
/* PV88080_REG_BUCK3_CONF2 (addr=0x69) */ #define PV88080_VHVBUCK_MASK 0xFF
/* PV88080_REG_HVBUCK_CONF1 (addr=0x2E|0x34) */
#define PV88080_HVBUCK_EN 0x01
/* PV88080_REG_BUCK2_CONF2 (addr=0x61|0x63) */
/* PV88080_REG_BUCK3_CONF2 (addr=0x69|0x6C) */
#define PV88080_BUCK_VDAC_RANGE_SHIFT 7 #define PV88080_BUCK_VDAC_RANGE_SHIFT 7
#define PV88080_BUCK_VDAC_RANGE_MASK 0x01 #define PV88080_BUCK_VDAC_RANGE_MASK 0x01
#define PV88080_BUCK_VDAC_RANGE_1 0x00 #define PV88080_BUCK_VDAC_RANGE_1 0x00
#define PV88080_BUCK_VDAC_RANGE_2 0x01 #define PV88080_BUCK_VDAC_RANGE_2 0x01
/* PV88080_REG_BUCK2_CONF5 (addr=0x64) */ /* PV88080_REG_BUCK2_CONF5 (addr=0x64|0x66) */
/* PV88080_REG_BUCK3_CONF5 (addr=0x6c) */ /* PV88080_REG_BUCK3_CONF5 (addr=0x6C|0x6F) */
#define PV88080_BUCK_VRANGE_GAIN_SHIFT 0 #define PV88080_BUCK_VRANGE_GAIN_SHIFT 0
#define PV88080_BUCK_VRANGE_GAIN_MASK 0x01 #define PV88080_BUCK_VRANGE_GAIN_MASK 0x01
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/delay.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/err.h> #include <linux/err.h>
...@@ -194,12 +193,10 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev, ...@@ -194,12 +193,10 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
unsigned int min_uV_duty = drvdata->continuous.min_uV_dutycycle; unsigned int min_uV_duty = drvdata->continuous.min_uV_dutycycle;
unsigned int max_uV_duty = drvdata->continuous.max_uV_dutycycle; unsigned int max_uV_duty = drvdata->continuous.max_uV_dutycycle;
unsigned int duty_unit = drvdata->continuous.dutycycle_unit; unsigned int duty_unit = drvdata->continuous.dutycycle_unit;
unsigned int ramp_delay = rdev->constraints->ramp_delay;
int min_uV = rdev->constraints->min_uV; int min_uV = rdev->constraints->min_uV;
int max_uV = rdev->constraints->max_uV; int max_uV = rdev->constraints->max_uV;
int diff_uV = max_uV - min_uV; int diff_uV = max_uV - min_uV;
struct pwm_state pstate; struct pwm_state pstate;
int old_uV = pwm_regulator_get_voltage(rdev);
unsigned int diff_duty; unsigned int diff_duty;
unsigned int dutycycle; unsigned int dutycycle;
int ret; int ret;
...@@ -233,13 +230,6 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev, ...@@ -233,13 +230,6 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
return ret; return ret;
} }
if ((ramp_delay == 0) || !pwm_regulator_is_enabled(rdev))
return 0;
/* Ramp delay is in uV/uS. Adjust to uS and delay */
ramp_delay = DIV_ROUND_UP(abs(req_min_uV - old_uV), ramp_delay);
usleep_range(ramp_delay, ramp_delay + DIV_ROUND_UP(ramp_delay, 10));
return 0; return 0;
} }
......
...@@ -533,8 +533,7 @@ static int rk808_regulator_probe(struct platform_device *pdev) ...@@ -533,8 +533,7 @@ static int rk808_regulator_probe(struct platform_device *pdev)
static struct platform_driver rk808_regulator_driver = { static struct platform_driver rk808_regulator_driver = {
.probe = rk808_regulator_probe, .probe = rk808_regulator_probe,
.driver = { .driver = {
.name = "rk808-regulator", .name = "rk808-regulator"
.owner = THIS_MODULE,
}, },
}; };
......
...@@ -180,6 +180,14 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev) ...@@ -180,6 +180,14 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev)
if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1)
return -EINVAL; return -EINVAL;
/*
* Certain revisions of TPS65218 will need to have DCDC3 regulator
* enabled always, otherwise an immediate system reboot will occur
* during poweroff.
*/
if (rid == TPS65218_DCDC_3 && tps->rev == TPS65218_REV_2_1)
return 0;
if (!tps->info[rid]->strobe) { if (!tps->info[rid]->strobe) {
if (rid == TPS65218_DCDC_3) if (rid == TPS65218_DCDC_3)
tps->info[rid]->strobe = 3; tps->info[rid]->strobe = 3;
......
...@@ -1111,6 +1111,12 @@ static int tps65910_probe(struct platform_device *pdev) ...@@ -1111,6 +1111,12 @@ static int tps65910_probe(struct platform_device *pdev)
pmic->num_regulators = ARRAY_SIZE(tps65910_regs); pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
pmic->ext_sleep_control = tps65910_ext_sleep_control; pmic->ext_sleep_control = tps65910_ext_sleep_control;
info = tps65910_regs; info = tps65910_regs;
/* Work around silicon erratum SWCZ010: output programmed
* voltage level can go higher than expected or crash
* Workaround: use no synchronization of DCDC clocks
*/
tps65910_reg_clear_bits(pmic->mfd, TPS65910_DCDCCTRL,
DCDCCTRL_DCDCCKSYNC_MASK);
break; break;
case TPS65911: case TPS65911:
pmic->get_ctrl_reg = &tps65911_get_ctrl_register; pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
......
...@@ -63,6 +63,11 @@ ...@@ -63,6 +63,11 @@
#define TPS65218_CHIPID_CHIP_MASK 0xF8 #define TPS65218_CHIPID_CHIP_MASK 0xF8
#define TPS65218_CHIPID_REV_MASK 0x07 #define TPS65218_CHIPID_REV_MASK 0x07
#define TPS65218_REV_1_0 0x0
#define TPS65218_REV_1_1 0x1
#define TPS65218_REV_2_0 0x2
#define TPS65218_REV_2_1 0x3
#define TPS65218_INT1_VPRG BIT(5) #define TPS65218_INT1_VPRG BIT(5)
#define TPS65218_INT1_AC BIT(4) #define TPS65218_INT1_AC BIT(4)
#define TPS65218_INT1_PB BIT(3) #define TPS65218_INT1_PB BIT(3)
...@@ -267,6 +272,7 @@ struct tps_info { ...@@ -267,6 +272,7 @@ struct tps_info {
struct tps65218 { struct tps65218 {
struct device *dev; struct device *dev;
unsigned int id; unsigned int id;
u8 rev;
struct mutex tps_lock; /* lock guarding the data structure */ struct mutex tps_lock; /* lock guarding the data structure */
/* IRQ Data */ /* IRQ Data */
......
...@@ -140,8 +140,6 @@ struct regulator; ...@@ -140,8 +140,6 @@ struct regulator;
* *
* @supply: The name of the supply. Initialised by the user before * @supply: The name of the supply. Initialised by the user before
* using the bulk regulator APIs. * using the bulk regulator APIs.
* @optional: The supply should be considered optional. Initialised by the user
* before using the bulk regulator APIs.
* @consumer: The regulator consumer for the supply. This will be managed * @consumer: The regulator consumer for the supply. This will be managed
* by the bulk API. * by the bulk API.
* *
...@@ -151,7 +149,6 @@ struct regulator; ...@@ -151,7 +149,6 @@ struct regulator;
*/ */
struct regulator_bulk_data { struct regulator_bulk_data {
const char *supply; const char *supply;
bool optional;
struct regulator *consumer; struct regulator *consumer;
/* private: Internal use */ /* private: Internal use */
......
...@@ -113,10 +113,14 @@ struct regulator_linear_range { ...@@ -113,10 +113,14 @@ struct regulator_linear_range {
* stabilise after being enabled, in microseconds. * stabilise after being enabled, in microseconds.
* @set_ramp_delay: Set the ramp delay for the regulator. The driver should * @set_ramp_delay: Set the ramp delay for the regulator. The driver should
* select ramp delay equal to or less than(closest) ramp_delay. * select ramp delay equal to or less than(closest) ramp_delay.
* @set_voltage_time: Time taken for the regulator voltage output voltage
* to stabilise after being set to a new value, in microseconds.
* The function receives the from and to voltage as input, it
* should return the worst case.
* @set_voltage_time_sel: Time taken for the regulator voltage output voltage * @set_voltage_time_sel: Time taken for the regulator voltage output voltage
* to stabilise after being set to a new value, in microseconds. * to stabilise after being set to a new value, in microseconds.
* The function provides the from and to voltage selector, the * The function receives the from and to voltage selector as
* function should return the worst case. * input, it should return the worst case.
* @set_soft_start: Enable soft start for the regulator. * @set_soft_start: Enable soft start for the regulator.
* *
* @set_suspend_voltage: Set the voltage for the regulator when the system * @set_suspend_voltage: Set the voltage for the regulator when the system
...@@ -168,6 +172,8 @@ struct regulator_ops { ...@@ -168,6 +172,8 @@ struct regulator_ops {
/* Time taken to enable or set voltage on the regulator */ /* Time taken to enable or set voltage on the regulator */
int (*enable_time) (struct regulator_dev *); int (*enable_time) (struct regulator_dev *);
int (*set_ramp_delay) (struct regulator_dev *, int ramp_delay); int (*set_ramp_delay) (struct regulator_dev *, int ramp_delay);
int (*set_voltage_time) (struct regulator_dev *, int old_uV,
int new_uV);
int (*set_voltage_time_sel) (struct regulator_dev *, int (*set_voltage_time_sel) (struct regulator_dev *,
unsigned int old_selector, unsigned int old_selector,
unsigned int new_selector); unsigned int new_selector);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment