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
Required properties:
- compatible: "pvs,pv88080".
- reg: I2C slave address, usually 0x49.
- compatible: Must be one of the following, depending on the
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
- 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
values listed below. The content of each sub-node is defined by the
standard binding for regulators; see regulator.txt.
BUCK1, BUCK2, and BUCK3.
BUCK1, BUCK2, BUCK3 and HVBUCK.
Optional properties:
- Any optional property defined in regulator.txt
Example
Example:
pmic: pv88080@49 {
compatible = "pvs,pv88080";
compatible = "pvs,pv88080-ba";
reg = <0x49>;
interrupt-parent = <&gpio>;
interrupts = <24 24>;
......@@ -45,5 +51,12 @@ Example
regulator-min-microamp = <1496000>;
regulator-max-microamp = <4189000>;
};
HVBUCK {
regulator-name = "hvbuck";
regulator-min-microvolt = < 5000>;
regulator-max-microvolt = <1275000>;
};
};
};
......@@ -13,7 +13,7 @@ Optional properties:
- regulator-allow-bypass: allow the regulator to go into bypass mode
- regulator-allow-set-load: allow the regulator performance level to be configured
- <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
initialised to zero (regulator-ramp-delay = <0>) for disabling ramp delay.
- regulator-enable-ramp-delay: The time taken, in microseconds, for the supply
......
......@@ -219,6 +219,7 @@ static int tps65218_probe(struct i2c_client *client,
struct tps65218 *tps;
const struct of_device_id *match;
int ret;
unsigned int chipid;
match = of_match_device(of_tps65218_match_table, &client->dev);
if (!match) {
......@@ -250,6 +251,14 @@ static int tps65218_probe(struct i2c_client *client,
if (ret < 0)
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,
&client->dev);
if (ret < 0)
......
......@@ -353,6 +353,14 @@ config REGULATOR_LTC3589
This enables support for the LTC3589, LTC3589-1, and LTC3589-2
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
tristate "Maxim 14577/77836 regulator"
depends on MFD_MAX14577
......@@ -820,7 +828,7 @@ config REGULATOR_TPS65912
This driver supports TPS65912 voltage regulator chip.
config REGULATOR_TPS80031
tristate "TI TPS80031/TPS80032 power regualtor driver"
tristate "TI TPS80031/TPS80032 power regulator driver"
depends on MFD_TPS80031
help
TPS80031/ TPS80032 Fully Integrated Power Management with Power
......
......@@ -47,6 +47,7 @@ obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o
obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o
obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o
obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
......
......@@ -679,24 +679,6 @@ static int drms_uA_update(struct regulator_dev *rdev)
!rdev->desc->ops->set_load)
return -EINVAL;
/* get output voltage */
output_uV = _regulator_get_voltage(rdev);
if (output_uV <= 0) {
rdev_err(rdev, "invalid output voltage found\n");
return -EINVAL;
}
/* get input voltage */
input_uV = 0;
if (rdev->supply)
input_uV = regulator_get_voltage(rdev->supply);
if (input_uV <= 0)
input_uV = rdev->constraints->input_uV;
if (input_uV <= 0) {
rdev_err(rdev, "invalid input voltage found\n");
return -EINVAL;
}
/* calc total requested load */
list_for_each_entry(sibling, &rdev->consumer_list, list)
current_uA += sibling->uA_load;
......@@ -709,6 +691,24 @@ static int drms_uA_update(struct regulator_dev *rdev)
if (err < 0)
rdev_err(rdev, "failed to set load %d\n", current_uA);
} else {
/* get output voltage */
output_uV = _regulator_get_voltage(rdev);
if (output_uV <= 0) {
rdev_err(rdev, "invalid output voltage found\n");
return -EINVAL;
}
/* get input voltage */
input_uV = 0;
if (rdev->supply)
input_uV = regulator_get_voltage(rdev->supply);
if (input_uV <= 0)
input_uV = rdev->constraints->input_uV;
if (input_uV <= 0) {
rdev_err(rdev, "invalid input voltage found\n");
return -EINVAL;
}
/* 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);
......@@ -2743,6 +2743,24 @@ static int _regulator_call_set_voltage_sel(struct regulator_dev *rdev,
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,
int min_uV, int max_uV)
{
......@@ -2751,6 +2769,8 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
int best_val = 0;
unsigned int selector;
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);
......@@ -2762,29 +2782,28 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
* info to call set_voltage_time_sel().
*/
if (_regulator_is_enabled(rdev) &&
rdev->desc->ops->set_voltage_time_sel &&
rdev->desc->ops->get_voltage_sel) {
old_selector = rdev->desc->ops->get_voltage_sel(rdev);
ops->set_voltage_time_sel && ops->get_voltage_sel) {
old_selector = ops->get_voltage_sel(rdev);
if (old_selector < 0)
return old_selector;
}
if (rdev->desc->ops->set_voltage) {
if (ops->set_voltage) {
ret = _regulator_call_set_voltage(rdev, min_uV, max_uV,
&selector);
if (ret >= 0) {
if (rdev->desc->ops->list_voltage)
best_val = rdev->desc->ops->list_voltage(rdev,
selector);
if (ops->list_voltage)
best_val = ops->list_voltage(rdev,
selector);
else
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);
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) {
selector = ret;
if (old_selector == selector)
......@@ -2800,34 +2819,50 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
ret = -EINVAL;
}
/* Call set_voltage_time_sel if successfully obtained old_selector */
if (ret == 0 && !rdev->constraints->ramp_disable && old_selector >= 0
&& old_selector != selector) {
if (ret)
goto out;
delay = rdev->desc->ops->set_voltage_time_sel(rdev,
old_selector, selector);
if (delay < 0) {
rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n",
delay);
delay = 0;
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);
}
}
/* Insert any necessary delays */
if (delay >= 1000) {
mdelay(delay / 1000);
udelay(delay % 1000);
} else if (delay) {
udelay(delay);
}
if (delay < 0) {
rdev_warn(rdev, "failed to get delay: %d\n", delay);
delay = 0;
}
if (ret == 0 && best_val >= 0) {
/* Insert any necessary delays */
if (delay >= 1000) {
mdelay(delay / 1000);
udelay(delay % 1000);
} else if (delay) {
udelay(delay);
}
if (best_val >= 0) {
unsigned long data = best_val;
_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
(void *)data);
}
out:
trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);
return ret;
......@@ -2998,9 +3033,13 @@ int regulator_set_voltage_time(struct regulator *regulator,
int voltage;
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 */
if (!ops->list_voltage || !ops->set_voltage_time_sel
|| !rdev->desc->n_voltages)
if (!ops->list_voltage || !rdev->desc->n_voltages)
return -EINVAL;
for (i = 0; i < rdev->desc->n_voltages; i++) {
......@@ -3039,19 +3078,8 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
unsigned int old_selector,
unsigned int new_selector)
{
unsigned int ramp_delay = 0;
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 */
if (!rdev->desc->ops->list_voltage)
return -EINVAL;
......@@ -3059,7 +3087,11 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
old_volt = rdev->desc->ops->list_voltage(rdev, old_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);
......@@ -3483,10 +3515,8 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
consumers[i].consumer = NULL;
for (i = 0; i < num_consumers; i++) {
consumers[i].consumer = _regulator_get(dev,
consumers[i].supply,
false,
!consumers[i].optional);
consumers[i].consumer = regulator_get(dev,
consumers[i].supply);
if (IS_ERR(consumers[i].consumer)) {
ret = PTR_ERR(consumers[i].consumer);
dev_err(dev, "Failed to get supply '%s': %d\n",
......
......@@ -75,24 +75,6 @@ static struct ux500_regulator_debug {
u8 *state_after_suspend;
} 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)
{
/* print power state count */
......
......@@ -164,11 +164,8 @@ int devm_regulator_bulk_get(struct device *dev, int num_consumers,
consumers[i].consumer = NULL;
for (i = 0; i < num_consumers; i++) {
consumers[i].consumer = _devm_regulator_get(dev,
consumers[i].supply,
consumers[i].optional ?
OPTIONAL_GET :
NORMAL_GET);
consumers[i].consumer = devm_regulator_get(dev,
consumers[i].supply);
if (IS_ERR(consumers[i].consumer)) {
ret = PTR_ERR(consumers[i].consumer);
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,
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)
{
struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
......
This diff is collapsed.
This diff is collapsed.
......@@ -17,55 +17,75 @@
#define __PV88080_REGISTERS_H__
/* System Control and Event Registers */
#define PV88080_REG_EVENT_A 0x04
#define PV88080_REG_MASK_A 0x09
#define PV88080_REG_MASK_B 0x0a
#define PV88080_REG_MASK_C 0x0b
/* Regulator Registers */
#define PV88080_REG_BUCK1_CONF0 0x27
#define PV88080_REG_BUCK1_CONF1 0x28
#define PV88080_REG_BUCK1_CONF2 0x59
#define PV88080_REG_BUCK1_CONF5 0x5c
#define PV88080_REG_BUCK2_CONF0 0x29
#define PV88080_REG_BUCK2_CONF1 0x2a
#define PV88080_REG_BUCK2_CONF2 0x61
#define PV88080_REG_BUCK2_CONF5 0x64
#define PV88080_REG_BUCK3_CONF0 0x2b
#define PV88080_REG_BUCK3_CONF1 0x2c
#define PV88080_REG_BUCK3_CONF2 0x69
#define PV88080_REG_BUCK3_CONF5 0x6c
#define PV88080_REG_EVENT_A 0x04
#define PV88080_REG_MASK_A 0x09
#define PV88080_REG_MASK_B 0x0A
#define PV88080_REG_MASK_C 0x0B
/* Regulator Registers - rev. AA */
#define PV88080AA_REG_HVBUCK_CONF1 0x2D
#define PV88080AA_REG_HVBUCK_CONF2 0x2E
#define PV88080AA_REG_BUCK1_CONF0 0x27
#define PV88080AA_REG_BUCK1_CONF1 0x28
#define PV88080AA_REG_BUCK1_CONF2 0x59
#define PV88080AA_REG_BUCK1_CONF5 0x5C
#define PV88080AA_REG_BUCK2_CONF0 0x29
#define PV88080AA_REG_BUCK2_CONF1 0x2A
#define PV88080AA_REG_BUCK2_CONF2 0x61
#define PV88080AA_REG_BUCK2_CONF5 0x64
#define PV88080AA_REG_BUCK3_CONF0 0x2B
#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) */
#define PV88080_E_VDD_FLT 0x01
#define PV88080_E_OVER_TEMP 0x02
#define PV88080_E_OVER_TEMP 0x02
/* PV88080_REG_MASK_A (addr=0x09) */
#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_VBUCK1_MASK 0x7F
/* PV88080_REG_BUCK2_CONF0 (addr=0x29) */
#define PV88080_VBUCK1_MASK 0x7F
/* PV88080_REG_BUCK2_CONF0 (addr=0x29|0x2D) */
#define PV88080_BUCK2_EN 0x80
#define PV88080_VBUCK2_MASK 0x7F
/* PV88080_REG_BUCK3_CONF0 (addr=0x2b) */
#define PV88080_VBUCK2_MASK 0x7F
/* PV88080_REG_BUCK3_CONF0 (addr=0x2B|0x30) */
#define PV88080_BUCK3_EN 0x80
#define PV88080_VBUCK3_MASK 0x7F
#define PV88080_VBUCK3_MASK 0x7F
/* PV88080_REG_BUCK1_CONF1 (addr=0x28) */
#define PV88080_BUCK1_ILIM_SHIFT 2
/* PV88080_REG_BUCK1_CONF1 (addr=0x28|0x2C) */
#define PV88080_BUCK1_ILIM_SHIFT 2
#define PV88080_BUCK1_ILIM_MASK 0x0C
#define PV88080_BUCK1_MODE_MASK 0x03
/* PV88080_REG_BUCK2_CONF1 (addr=0x2a) */
#define PV88080_BUCK2_ILIM_SHIFT 2
/* PV88080_REG_BUCK2_CONF1 (addr=0x2A|0x2F) */
#define PV88080_BUCK2_ILIM_SHIFT 2
#define PV88080_BUCK2_ILIM_MASK 0x0C
#define PV88080_BUCK2_MODE_MASK 0x03
/* PV88080_REG_BUCK3_CONF1 (addr=0x2c) */
#define PV88080_BUCK3_ILIM_SHIFT 2
/* PV88080_REG_BUCK3_CONF1 (addr=0x2C|0x32) */
#define PV88080_BUCK3_ILIM_SHIFT 2
#define PV88080_BUCK3_ILIM_MASK 0x0C
#define PV88080_BUCK3_MODE_MASK 0x03
......@@ -73,20 +93,26 @@
#define PV88080_BUCK_MODE_AUTO 0x01
#define PV88080_BUCK_MODE_SYNC 0x02
/* PV88080_REG_BUCK2_CONF2 (addr=0x61) */
/* PV88080_REG_BUCK3_CONF2 (addr=0x69) */
#define PV88080_BUCK_VDAC_RANGE_SHIFT 7
#define PV88080_BUCK_VDAC_RANGE_MASK 0x01
/* PV88080_REG_HVBUCK_CONF1 (addr=0x2D|0x33) */
#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_MASK 0x01
#define PV88080_BUCK_VDAC_RANGE_1 0x00
#define PV88080_BUCK_VDAC_RANGE_2 0x01
#define PV88080_BUCK_VDAC_RANGE_1 0x00
#define PV88080_BUCK_VDAC_RANGE_2 0x01
/* PV88080_REG_BUCK2_CONF5 (addr=0x64) */
/* PV88080_REG_BUCK3_CONF5 (addr=0x6c) */
#define PV88080_BUCK_VRANGE_GAIN_SHIFT 0
#define PV88080_BUCK_VRANGE_GAIN_MASK 0x01
/* PV88080_REG_BUCK2_CONF5 (addr=0x64|0x66) */
/* PV88080_REG_BUCK3_CONF5 (addr=0x6C|0x6F) */
#define PV88080_BUCK_VRANGE_GAIN_SHIFT 0
#define PV88080_BUCK_VRANGE_GAIN_MASK 0x01
#define PV88080_BUCK_VRANGE_GAIN_1 0x00
#define PV88080_BUCK_VRANGE_GAIN_2 0x01
#define PV88080_BUCK_VRANGE_GAIN_1 0x00
#define PV88080_BUCK_VRANGE_GAIN_2 0x01
#endif /* __PV88080_REGISTERS_H__ */
......@@ -10,7 +10,6 @@
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
......@@ -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 max_uV_duty = drvdata->continuous.max_uV_dutycycle;
unsigned int duty_unit = drvdata->continuous.dutycycle_unit;
unsigned int ramp_delay = rdev->constraints->ramp_delay;
int min_uV = rdev->constraints->min_uV;
int max_uV = rdev->constraints->max_uV;
int diff_uV = max_uV - min_uV;
struct pwm_state pstate;
int old_uV = pwm_regulator_get_voltage(rdev);
unsigned int diff_duty;
unsigned int dutycycle;
int ret;
......@@ -233,13 +230,6 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
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;
}
......
......@@ -533,8 +533,7 @@ static int rk808_regulator_probe(struct platform_device *pdev)
static struct platform_driver rk808_regulator_driver = {
.probe = rk808_regulator_probe,
.driver = {
.name = "rk808-regulator",
.owner = THIS_MODULE,
.name = "rk808-regulator"
},
};
......
......@@ -180,6 +180,14 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev)
if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1)
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 (rid == TPS65218_DCDC_3)
tps->info[rid]->strobe = 3;
......
......@@ -1111,6 +1111,12 @@ static int tps65910_probe(struct platform_device *pdev)
pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
pmic->ext_sleep_control = tps65910_ext_sleep_control;
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;
case TPS65911:
pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
......
......@@ -63,6 +63,11 @@
#define TPS65218_CHIPID_CHIP_MASK 0xF8
#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_AC BIT(4)
#define TPS65218_INT1_PB BIT(3)
......@@ -267,6 +272,7 @@ struct tps_info {
struct tps65218 {
struct device *dev;
unsigned int id;
u8 rev;
struct mutex tps_lock; /* lock guarding the data structure */
/* IRQ Data */
......
......@@ -140,8 +140,6 @@ struct regulator;
*
* @supply: The name of the supply. Initialised by the user before
* 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
* by the bulk API.
*
......@@ -151,7 +149,6 @@ struct regulator;
*/
struct regulator_bulk_data {
const char *supply;
bool optional;
struct regulator *consumer;
/* private: Internal use */
......
......@@ -113,10 +113,14 @@ struct regulator_linear_range {
* stabilise after being enabled, in microseconds.
* @set_ramp_delay: Set the ramp delay for the regulator. The driver should
* 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
* to stabilise after being set to a new value, in microseconds.
* The function provides the from and to voltage selector, the
* function should return the worst case.
* The function receives the from and to voltage selector as
* input, it should return the worst case.
* @set_soft_start: Enable soft start for the regulator.
*
* @set_suspend_voltage: Set the voltage for the regulator when the system
......@@ -168,6 +172,8 @@ struct regulator_ops {
/* Time taken to enable or set voltage on the regulator */
int (*enable_time) (struct regulator_dev *);
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 *,
unsigned int old_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