Hi, On Tue, Aug 15, 2017 at 10:04:56PM +0200, Hans de Goede wrote: > On some devices the USB Type-C port power (USB PD 2.0) negotiation is > done by a separate port-controller IC, while the current limit is > controlled through another (charger) IC. > > It has been decided to model this by modelling the external Type-C > power brick (adapter/charger) as a power-supply class device which > supplies the charger-IC, with its voltage-now and current-max representing > the negotiated voltage and max current draw. > > This commit adds a power_supply_set_input_current_limit_from_supplier > helper function which charger power-supply drivers can call to get > the max-current from their supplier and have this applied > through their set_property call-back to their input-current-limit. > > Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> Thanks, queued. -- Sebastian > drivers/power/supply/power_supply_core.c | 41 ++++++++++++++++++++++++++++++++ > include/linux/power_supply.h | 2 ++ > 2 files changed, 43 insertions(+) > > diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c > index 0741fce..3f92574 100644 > --- a/drivers/power/supply/power_supply_core.c > +++ b/drivers/power/supply/power_supply_core.c > @@ -375,6 +375,47 @@ int power_supply_is_system_supplied(void) > } > EXPORT_SYMBOL_GPL(power_supply_is_system_supplied); > > +static int __power_supply_get_supplier_max_current(struct device *dev, > + void *data) > +{ > + union power_supply_propval ret = {0,}; > + struct power_supply *epsy = dev_get_drvdata(dev); > + struct power_supply *psy = data; > + > + if (__power_supply_is_supplied_by(epsy, psy)) > + if (!epsy->desc->get_property(epsy, > + POWER_SUPPLY_PROP_CURRENT_MAX, > + &ret)) > + return ret.intval; > + > + return 0; > +} > + > +int power_supply_set_input_current_limit_from_supplier(struct power_supply *psy) > +{ > + union power_supply_propval val = {0,}; > + int curr; > + > + if (!psy->desc->set_property) > + return -EINVAL; > + > + /* > + * This function is not intended for use with a supply with multiple > + * suppliers, we simply pick the first supply to report a non 0 > + * max-current. > + */ > + curr = class_for_each_device(power_supply_class, NULL, psy, > + __power_supply_get_supplier_max_current); > + if (curr <= 0) > + return (curr == 0) ? -ENODEV : curr; > + > + val.intval = curr; > + > + return psy->desc->set_property(psy, > + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val); > +} > +EXPORT_SYMBOL_GPL(power_supply_set_input_current_limit_from_supplier); > + > int power_supply_set_battery_charged(struct power_supply *psy) > { > if (atomic_read(&psy->use_cnt) >= 0 && > diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h > index de89066..79e90b3 100644 > --- a/include/linux/power_supply.h > +++ b/include/linux/power_supply.h > @@ -332,6 +332,8 @@ extern int power_supply_get_battery_info(struct power_supply *psy, > struct power_supply_battery_info *info); > extern void power_supply_changed(struct power_supply *psy); > extern int power_supply_am_i_supplied(struct power_supply *psy); > +extern int power_supply_set_input_current_limit_from_supplier( > + struct power_supply *psy); > extern int power_supply_set_battery_charged(struct power_supply *psy); > > #ifdef CONFIG_POWER_SUPPLY > -- > 2.9.4 >
Attachment:
signature.asc
Description: PGP signature