power: supply: Add power_supply_set_input_current_limit_from_supplier helper
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@redhat.com> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
This commit is contained in:
committed by
Sebastian Reichel
parent
4f1e0cb788
commit
c3142dd8be
@@ -371,6 +371,47 @@ int power_supply_is_system_supplied(void)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
|
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)
|
int power_supply_set_battery_charged(struct power_supply *psy)
|
||||||
{
|
{
|
||||||
if (atomic_read(&psy->use_cnt) >= 0 &&
|
if (atomic_read(&psy->use_cnt) >= 0 &&
|
||||||
|
|||||||
@@ -332,6 +332,8 @@ extern int power_supply_get_battery_info(struct power_supply *psy,
|
|||||||
struct power_supply_battery_info *info);
|
struct power_supply_battery_info *info);
|
||||||
extern void power_supply_changed(struct power_supply *psy);
|
extern void power_supply_changed(struct power_supply *psy);
|
||||||
extern int power_supply_am_i_supplied(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);
|
extern int power_supply_set_battery_charged(struct power_supply *psy);
|
||||||
|
|
||||||
#ifdef CONFIG_POWER_SUPPLY
|
#ifdef CONFIG_POWER_SUPPLY
|
||||||
|
|||||||
Reference in New Issue
Block a user