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

power: supply: core: Add power_supply_battery_info and API

power_supply_get_battery_info() reads battery data from devicetree.
struct power_supply_battery_info provides battery data to drivers.
Its fields correspond to elements in enum power_supply_property.
Drivers may surface battery data in sysfs via corresponding
POWER_SUPPLY_PROP_* fields.

Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
Signed-off-by: Liam Breck <kernel@networkimprov.net>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

authored by

Liam Breck and committed by
Sebastian Reichel
c08b1f45 23067047

+91
+12
Documentation/power/power_supply_class.txt
··· 174 174 external_power_changed callback. 175 175 176 176 177 + Devicetree battery characteristics 178 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 179 + Drivers should call power_supply_get_battery_info() to obtain battery 180 + characteristics from a devicetree battery node, defined in 181 + Documentation/devicetree/bindings/power/supply/battery.txt. This is 182 + implemented in drivers/power/supply/bq27xxx_battery.c. 183 + 184 + Properties in struct power_supply_battery_info and their counterparts in the 185 + battery node have names corresponding to elements in enum power_supply_property, 186 + for naming consistency between sysfs attributes and battery node properties. 187 + 188 + 177 189 QA 178 190 ~~ 179 191 Q: Where is POWER_SUPPLY_PROP_XYZ attribute?
+57
drivers/power/supply/power_supply_core.c
··· 17 17 #include <linux/device.h> 18 18 #include <linux/notifier.h> 19 19 #include <linux/err.h> 20 + #include <linux/of.h> 20 21 #include <linux/power_supply.h> 21 22 #include <linux/thermal.h> 22 23 #include "power_supply.h" ··· 519 518 } 520 519 EXPORT_SYMBOL_GPL(devm_power_supply_get_by_phandle); 521 520 #endif /* CONFIG_OF */ 521 + 522 + int power_supply_get_battery_info(struct power_supply *psy, 523 + struct power_supply_battery_info *info) 524 + { 525 + struct device_node *battery_np; 526 + const char *value; 527 + int err; 528 + 529 + info->energy_full_design_uwh = -EINVAL; 530 + info->charge_full_design_uah = -EINVAL; 531 + info->voltage_min_design_uv = -EINVAL; 532 + info->precharge_current_ua = -EINVAL; 533 + info->charge_term_current_ua = -EINVAL; 534 + info->constant_charge_current_max_ua = -EINVAL; 535 + info->constant_charge_voltage_max_uv = -EINVAL; 536 + 537 + if (!psy->of_node) { 538 + dev_warn(&psy->dev, "%s currently only supports devicetree\n", 539 + __func__); 540 + return -ENXIO; 541 + } 542 + 543 + battery_np = of_parse_phandle(psy->of_node, "monitored-battery", 0); 544 + if (!battery_np) 545 + return -ENODEV; 546 + 547 + err = of_property_read_string(battery_np, "compatible", &value); 548 + if (err) 549 + return err; 550 + 551 + if (strcmp("simple-battery", value)) 552 + return -ENODEV; 553 + 554 + /* The property and field names below must correspond to elements 555 + * in enum power_supply_property. For reasoning, see 556 + * Documentation/power/power_supply_class.txt. 557 + */ 558 + 559 + of_property_read_u32(battery_np, "energy-full-design-microwatt-hours", 560 + &info->energy_full_design_uwh); 561 + of_property_read_u32(battery_np, "charge-full-design-microamp-hours", 562 + &info->charge_full_design_uah); 563 + of_property_read_u32(battery_np, "voltage-min-design-microvolt", 564 + &info->voltage_min_design_uv); 565 + of_property_read_u32(battery_np, "precharge-current-microamp", 566 + &info->precharge_current_ua); 567 + of_property_read_u32(battery_np, "charge-term-current-microamp", 568 + &info->charge_term_current_ua); 569 + of_property_read_u32(battery_np, "constant_charge_current_max_microamp", 570 + &info->constant_charge_current_max_ua); 571 + of_property_read_u32(battery_np, "constant_charge_voltage_max_microvolt", 572 + &info->constant_charge_voltage_max_uv); 573 + 574 + return 0; 575 + } 576 + EXPORT_SYMBOL_GPL(power_supply_get_battery_info); 522 577 523 578 int power_supply_get_property(struct power_supply *psy, 524 579 enum power_supply_property psp,
+22
include/linux/power_supply.h
··· 289 289 int use_for_apm; 290 290 }; 291 291 292 + /* 293 + * This is the recommended struct to manage static battery parameters, 294 + * populated by power_supply_get_battery_info(). Most platform drivers should 295 + * use these for consistency. 296 + * Its field names must correspond to elements in enum power_supply_property. 297 + * The default field value is -EINVAL. 298 + * Power supply class itself doesn't use this. 299 + */ 300 + 301 + struct power_supply_battery_info { 302 + int energy_full_design_uwh; /* microWatt-hours */ 303 + int charge_full_design_uah; /* microAmp-hours */ 304 + int voltage_min_design_uv; /* microVolts */ 305 + int precharge_current_ua; /* microAmps */ 306 + int charge_term_current_ua; /* microAmps */ 307 + int constant_charge_current_max_ua; /* microAmps */ 308 + int constant_charge_voltage_max_uv; /* microVolts */ 309 + }; 310 + 292 311 extern struct atomic_notifier_head power_supply_notifier; 293 312 extern int power_supply_reg_notifier(struct notifier_block *nb); 294 313 extern void power_supply_unreg_notifier(struct notifier_block *nb); ··· 326 307 devm_power_supply_get_by_phandle(struct device *dev, const char *property) 327 308 { return NULL; } 328 309 #endif /* CONFIG_OF */ 310 + 311 + extern int power_supply_get_battery_info(struct power_supply *psy, 312 + struct power_supply_battery_info *info); 329 313 extern void power_supply_changed(struct power_supply *psy); 330 314 extern int power_supply_am_i_supplied(struct power_supply *psy); 331 315 extern int power_supply_set_battery_charged(struct power_supply *psy);