1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

regulator: Fixes for v6.14

A couple of fixes that have come in during the merge window, one that
 operates the TPS6287x devices more within the design spec and can
 prevent current surges when changing voltages and another more trivial
 one for error message formatting.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmeaIvMACgkQJNaLcl1U
 h9B1uQf/a+9sU3VTS9gtSsxj6cN61Bd6TZTigwldCpD/Pxls11dUh0v9Anh53I5n
 G7HvhkF8BUDM4Et8ycLiwAPYaQOR72J1UTi7bx27CZvAllLMByYtav3LHDK7gR8H
 3yrkEZEVRM/yIEWr5TqAkDrErcNswP+7lpiyKCTGtraZ5d5Um74A7Twb8W82edYr
 NYV9BgUoHRjWoGRz43AD7Vs7t9mGLPoRQmA/41w38Yh8HwXmcFfxRy0WLqR2V8o9
 OAeh3fGFMfr3BmXweXgdeHS27q5wBxGcN2CyCny25XTeIChpdH3YBMj35GeaQZdM
 EZoAtjt1h04rG+cMk7qlgBfT5cDhMg==
 =6NN+
 -----END PGP SIGNATURE-----

Merge tag 'regulator-fix-v6.14-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator fixes from Mark Brown:
 "A couple of fixes that have come in during the merge window: one that
  operates the TPS6287x devices more within the design spec and can
  prevent current surges when changing voltages and another more trivial
  one for error message formatting"

* tag 'regulator-fix-v6.14-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
  regulator: core: Add missing newline character
  regulator: TPS6287X: Use min/max uV to get VRANGE
This commit is contained in:
Linus Torvalds 2025-01-29 11:56:55 -08:00
commit ebbb8be421
2 changed files with 58 additions and 1 deletions

View file

@ -5033,7 +5033,7 @@ int _regulator_bulk_get(struct device *dev, int num_consumers,
consumers[i].supply, get_type);
if (IS_ERR(consumers[i].consumer)) {
ret = dev_err_probe(dev, PTR_ERR(consumers[i].consumer),
"Failed to get supply '%s'",
"Failed to get supply '%s'\n",
consumers[i].supply);
consumers[i].consumer = NULL;
goto err;

View file

@ -44,10 +44,35 @@ static const unsigned int tps6287x_voltage_range_sel[] = {
0x0, 0x1, 0x2, 0x3
};
static const unsigned int tps6287x_voltage_range_prefix[] = {
0x000, 0x100, 0x200, 0x300
};
static const unsigned int tps6287x_ramp_table[] = {
10000, 5000, 1250, 500
};
struct tps6287x_reg_data {
int range;
};
static int tps6287x_best_range(struct regulator_config *config, const struct regulator_desc *desc)
{
const struct linear_range *r;
int i;
if (!config->init_data->constraints.apply_uV)
return -1;
for (i = 0; i < desc->n_linear_ranges; i++) {
r = &desc->linear_ranges[i];
if (r->min <= config->init_data->constraints.min_uV &&
config->init_data->constraints.max_uV <= linear_range_get_max_value(r))
return i;
}
return -1;
}
static int tps6287x_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
unsigned int val;
@ -91,6 +116,28 @@ static unsigned int tps6287x_of_map_mode(unsigned int mode)
}
}
static int tps6287x_map_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
{
struct tps6287x_reg_data *data = (struct tps6287x_reg_data *)rdev->reg_data;
struct linear_range selected_range;
int selector, voltage;
if (!data || data->range == -1)
return regulator_map_voltage_pickable_linear_range(rdev, min_uV, max_uV);
selected_range = rdev->desc->linear_ranges[data->range];
selector = DIV_ROUND_UP(min_uV - selected_range.min, selected_range.step);
if (selector < selected_range.min_sel || selector > selected_range.max_sel)
return -EINVAL;
selector |= tps6287x_voltage_range_prefix[data->range];
voltage = rdev->desc->ops->list_voltage(rdev, selector);
if (voltage < min_uV || voltage > max_uV)
return -EINVAL;
return selector;
}
static const struct regulator_ops tps6287x_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -100,6 +147,7 @@ static const struct regulator_ops tps6287x_regulator_ops = {
.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
.set_voltage_sel = regulator_set_voltage_sel_pickable_regmap,
.list_voltage = regulator_list_voltage_pickable_linear_range,
.map_voltage = tps6287x_map_voltage,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
};
@ -130,8 +178,14 @@ static int tps6287x_i2c_probe(struct i2c_client *i2c)
{
struct device *dev = &i2c->dev;
struct regulator_config config = {};
struct tps6287x_reg_data *reg_data;
struct regulator_dev *rdev;
reg_data = devm_kzalloc(dev, sizeof(struct tps6287x_reg_data), GFP_KERNEL);
if (!reg_data)
return -ENOMEM;
config.regmap = devm_regmap_init_i2c(i2c, &tps6287x_regmap_config);
if (IS_ERR(config.regmap)) {
dev_err(dev, "Failed to init i2c\n");
@ -143,12 +197,15 @@ static int tps6287x_i2c_probe(struct i2c_client *i2c)
config.init_data = of_get_regulator_init_data(dev, dev->of_node,
&tps6287x_reg);
reg_data->range = tps6287x_best_range(&config, &tps6287x_reg);
rdev = devm_regulator_register(dev, &tps6287x_reg, &config);
if (IS_ERR(rdev)) {
dev_err(dev, "Failed to register regulator\n");
return PTR_ERR(rdev);
}
rdev->reg_data = (void *)reg_data;
dev_dbg(dev, "Probed regulator\n");
return 0;