Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

power: supply: axp20x_usb_power: replace current_max with input_current_limit

The current_max property is supposed to be read-only, and represent the
maximum current the supply can provide. input_current_limit is the
limit that is currently set, which is what we have here.

When determining what value to write to the register, we need to pick a
reasonable value if the requested limit doesn't exactly match one
supported by the hardware. If the requested limit is less than the
lowest value we can set, round up to the lowest value. Otherwise round
down to the nearest value supported by hardware.

Also add a dev field to the axp20x_usb_power struct, so we can use
dev_dbg and dev_err in more places.

Signed-off-by: Aren Moynihan <aren@peacevolution.org>
Link: https://lore.kernel.org/r/20240130203714.3020464-2-aren@peacevolution.org
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

authored by

Aren Moynihan and committed by
Sebastian Reichel
bec924d2 cad1e6df

+18 -11
+18 -11
drivers/power/supply/axp20x_usb_power.c
··· 59 59 }; 60 60 61 61 struct axp20x_usb_power { 62 + struct device *dev; 62 63 struct regmap *regmap; 63 64 struct regmap_field *curr_lim_fld; 64 65 struct regmap_field *vbus_valid_bit; ··· 161 160 162 161 val->intval = ret * 1700; /* 1 step = 1.7 mV */ 163 162 return 0; 164 - case POWER_SUPPLY_PROP_CURRENT_MAX: 163 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 165 164 ret = regmap_field_read(power->curr_lim_fld, &v); 166 165 if (ret) 167 166 return ret; ··· 257 256 return -EINVAL; 258 257 } 259 258 260 - static int axp20x_usb_power_set_current_max(struct axp20x_usb_power *power, int intval) 259 + static int axp20x_usb_power_set_input_current_limit(struct axp20x_usb_power *power, 260 + int intval) 261 261 { 262 + unsigned int reg; 262 263 const unsigned int max = GENMASK(power->axp_data->curr_lim_fld.msb, 263 264 power->axp_data->curr_lim_fld.lsb); 264 265 265 266 if (intval == -1) 266 267 return -EINVAL; 267 268 268 - for (unsigned int i = 0; i <= max; ++i) 269 - if (power->axp_data->curr_lim_table[i] == intval) 270 - return regmap_field_write(power->curr_lim_fld, i); 269 + for (reg = max - 1; reg > 0; reg--) 270 + if (power->axp_data->curr_lim_table[reg] <= intval) 271 + break; 271 272 272 - return -EINVAL; 273 + dev_dbg(power->dev, "setting input current limit reg to %d (%d uA), requested %d uA", 274 + reg, power->axp_data->curr_lim_table[reg], intval); 275 + 276 + return regmap_field_write(power->curr_lim_fld, reg); 273 277 } 274 278 275 279 static int axp20x_usb_power_set_property(struct power_supply *psy, ··· 293 287 case POWER_SUPPLY_PROP_VOLTAGE_MIN: 294 288 return axp20x_usb_power_set_voltage_min(power, val->intval); 295 289 296 - case POWER_SUPPLY_PROP_CURRENT_MAX: 297 - return axp20x_usb_power_set_current_max(power, val->intval); 290 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 291 + return axp20x_usb_power_set_input_current_limit(power, val->intval); 298 292 299 293 default: 300 294 return -EINVAL; ··· 319 313 return power->vbus_disable_bit != NULL; 320 314 321 315 return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN || 322 - psp == POWER_SUPPLY_PROP_CURRENT_MAX; 316 + psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT; 323 317 } 324 318 325 319 static enum power_supply_property axp20x_usb_power_properties[] = { ··· 328 322 POWER_SUPPLY_PROP_ONLINE, 329 323 POWER_SUPPLY_PROP_VOLTAGE_MIN, 330 324 POWER_SUPPLY_PROP_VOLTAGE_NOW, 331 - POWER_SUPPLY_PROP_CURRENT_MAX, 325 + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 332 326 POWER_SUPPLY_PROP_CURRENT_NOW, 333 327 }; 334 328 ··· 337 331 POWER_SUPPLY_PROP_PRESENT, 338 332 POWER_SUPPLY_PROP_ONLINE, 339 333 POWER_SUPPLY_PROP_VOLTAGE_MIN, 340 - POWER_SUPPLY_PROP_CURRENT_MAX, 334 + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 341 335 }; 342 336 343 337 static const struct power_supply_desc axp20x_usb_power_desc = { ··· 564 558 565 559 platform_set_drvdata(pdev, power); 566 560 561 + power->dev = &pdev->dev; 567 562 power->axp_data = axp_data; 568 563 power->regmap = axp20x->regmap; 569 564 power->num_irqs = axp_data->num_irq_names;