[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20170815200502.17339-9-hdegoede@redhat.com>
Date: Tue, 15 Aug 2017 22:04:56 +0200
From: Hans de Goede <hdegoede@...hat.com>
To: Wolfram Sang <wsa@...-dreams.de>,
Guenter Roeck <linux@...ck-us.net>,
Heikki Krogerus <heikki.krogerus@...ux.intel.com>,
Sebastian Reichel <sre@...nel.org>,
Darren Hart <dvhart@...radead.org>,
Andy Shevchenko <andy@...radead.org>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc: Hans de Goede <hdegoede@...hat.com>,
Liam Breck <liam@...workimprov.net>,
Tony Lindgren <tony@...mide.com>, linux-i2c@...r.kernel.org,
linux-pm@...r.kernel.org, platform-driver-x86@...r.kernel.org,
linux-kernel@...r.kernel.org, devel@...verdev.osuosl.org
Subject: [PATCH v2 08/14] 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@...hat.com>
---
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
Powered by blists - more mailing lists