Skip to content

Commit

Permalink
Merge remote-tracking branches 'regulator/topic/of', 'regulator/topic…
Browse files Browse the repository at this point in the history
…/pv88080', 'regulator/topic/rk808', 'regulator/topic/set-voltage' and 'regulator/topic/tps65218' into regulator-next
  • Loading branch information
Mark Brown committed Sep 30, 2016
6 parents 81c383c + 1283b91 + 5ff00f6 + 556ae22 + 73e705b + 23a34f9 commit 2dfcb92
Show file tree
Hide file tree
Showing 11 changed files with 427 additions and 133 deletions.
23 changes: 18 additions & 5 deletions Documentation/devicetree/bindings/regulator/pv88080.txt
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
* 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>;
Expand Down Expand Up @@ -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>;
};
};
};

2 changes: 1 addition & 1 deletion Documentation/devicetree/bindings/regulator/regulator.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions drivers/mfd/tps65218.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
Expand Down
112 changes: 72 additions & 40 deletions drivers/regulator/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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);

Expand All @@ -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)
Expand All @@ -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;
}

/* Insert any necessary delays */
if (delay >= 1000) {
mdelay(delay / 1000);
udelay(delay % 1000);
} else if (delay) {
udelay(delay);
}

if (ret == 0 && best_val >= 0) {
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;
Expand Down Expand Up @@ -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++) {
Expand Down Expand Up @@ -3039,27 +3078,20 @@ 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;

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);

Expand Down
Loading

0 comments on commit 2dfcb92

Please sign in to comment.