diff mbox series

[v2,4/9] power: supply: max77693: Expose CURRENT_MAX property

Message ID 20240715-max77693-charger-extcon-v2-4-0838ffbb18c3@gmail.com
State New
Headers show
Series power: supply: max77693: Toggle charging/OTG based on extcon status | expand

Commit Message

Artur Weber July 15, 2024, 12:55 p.m. UTC
There are two charger current limit registers:

- Fast charge current limit (which controls current going from the
  charger to the battery);
- CHGIN input current limit (which controls current going into the
  charger through the cable).

Both of them are aggregated in the CHARGER regulator. Add a property
that allows for reading the current limit from userspace.

Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
---
Changes in v2:
- Adapted to both current limits being managed in the CHARGER regulator
---
 drivers/power/supply/max77693_charger.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
diff mbox series

Patch

diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c
index 2001e12c9f7d..0d53f61d58ba 100644
--- a/drivers/power/supply/max77693_charger.c
+++ b/drivers/power/supply/max77693_charger.c
@@ -9,6 +9,7 @@ 
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
 #include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
 #include <linux/mfd/max77693.h>
 #include <linux/mfd/max77693-common.h>
 #include <linux/mfd/max77693-private.h>
@@ -21,6 +22,7 @@  struct max77693_charger {
 	struct device		*dev;
 	struct max77693_dev	*max77693;
 	struct power_supply	*charger;
+	struct regulator	*regu;
 
 	u32 constant_volt;
 	u32 min_system_volt;
@@ -197,12 +199,33 @@  static int max77693_get_online(struct regmap *regmap, int *val)
 	return 0;
 }
 
+/*
+ * There are *two* current limit registers:
+ * - CHGIN limit, which limits the input current from the external charger;
+ * - Fast charge current limit, which limits the current going to the battery.
+ * Both are managed by the CHARGER regulator.
+ */
+
+static int max77693_get_current_limit(struct max77693_charger *chg, int *val)
+{
+	int ret;
+
+	ret = regulator_get_current_limit(chg->regu);
+	if (ret < 0)
+		return ret;
+
+	*val = ret;
+
+	return 0;
+}
+
 static enum power_supply_property max77693_charger_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_CHARGE_TYPE,
 	POWER_SUPPLY_PROP_HEALTH,
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_CURRENT_MAX,
 	POWER_SUPPLY_PROP_MODEL_NAME,
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
@@ -231,6 +254,9 @@  static int max77693_charger_get_property(struct power_supply *psy,
 	case POWER_SUPPLY_PROP_ONLINE:
 		ret = max77693_get_online(regmap, &val->intval);
 		break;
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		ret = max77693_get_current_limit(chg, &val->intval);
+		break;
 	case POWER_SUPPLY_PROP_MODEL_NAME:
 		val->strval = max77693_charger_model;
 		break;
@@ -680,6 +706,12 @@  static int max77693_charger_probe(struct platform_device *pdev)
 	chg->dev = &pdev->dev;
 	chg->max77693 = max77693;
 
+	/* This gets the CHARGER regulator from the parent MAX77693 device */
+	chg->regu = devm_regulator_get(chg->dev, "CHARGER");
+	if (IS_ERR(chg->regu))
+		return dev_err_probe(&pdev->dev, PTR_ERR(chg->regu),
+				     "failed to get charger regulator\n");
+
 	ret = max77693_dt_init(&pdev->dev, chg);
 	if (ret)
 		return ret;