From fcfd714cac86026d77c397e3f52740ab2eb76566 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megi@xff.cz>
Date: Thu, 10 Nov 2022 20:05:58 +0100
Subject: power: supply: axp20x-battery: Add support for
 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN

Report total battery capacity.

Signed-off-by: Ondrej Jirman <megi@xff.cz>
---
 drivers/power/supply/axp20x_battery.c | 30 +++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c
index ba7c45e4bf10..9b4b1b8d09b1 100644
--- a/drivers/power/supply/axp20x_battery.c
+++ b/drivers/power/supply/axp20x_battery.c
@@ -127,6 +127,7 @@ struct axp20x_batt_ps {
 	/* Maximum constant charge current */
 	unsigned int max_ccc;
 	const struct axp_data	*data;
+	struct power_supply_battery_info *info;
 };
 
 static int axp20x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
@@ -460,6 +461,16 @@ static int axp20x_battery_get_prop(struct power_supply *psy,
 
 		break;
 
+	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+		val->intval = 0;
+		if (axp20x_batt->info)
+			val->intval = axp20x_batt->info->energy_full_design_uwh;
+		return 0;
+
+	case POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN:
+		val->intval = 0;
+		return 0;
+
 	default:
 		return -EINVAL;
 	}
@@ -914,6 +925,8 @@ static enum power_supply_property axp20x_battery_props[] = {
 	POWER_SUPPLY_PROP_VOLTAGE_MIN,
 	POWER_SUPPLY_PROP_VOLTAGE_OCV,
 	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+	POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
 };
 
 static enum power_supply_property axp717_battery_props[] = {
@@ -1213,12 +1226,18 @@ static const struct of_device_id axp20x_battery_ps_id[] = {
 };
 MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id);
 
+static void axp20x_put_battery_info(void *data)
+{
+	struct axp20x_batt_ps *axp20x_batt = data;
+
+	power_supply_put_battery_info(axp20x_batt->batt, axp20x_batt->info);
+}
+
 static int axp20x_power_probe(struct platform_device *pdev)
 {
 	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
 	struct axp20x_batt_ps *axp20x_batt;
 	struct power_supply_config psy_cfg = {};
-	struct power_supply_battery_info *info;
 	struct device *dev = &pdev->dev;
 	const struct axp_irq_data *irq_data;
 	int irq, ret;
@@ -1256,9 +1275,12 @@ static int axp20x_power_probe(struct platform_device *pdev)
 
 	axp20x_batt->health = POWER_SUPPLY_HEALTH_GOOD;
 
-	if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) {
-		axp20x_batt->data->set_bat_info(pdev, axp20x_batt, info);
-		power_supply_put_battery_info(axp20x_batt->batt, info);
+	if (!power_supply_get_battery_info(axp20x_batt->batt, &axp20x_batt->info)) {
+		axp20x_batt->data->set_bat_info(pdev, axp20x_batt, axp20x_batt->info);
+
+		ret = devm_add_action_or_reset(&pdev->dev, axp20x_put_battery_info, axp20x_batt);
+		if (ret)
+			return ret;
 	}
 
 	/* Request irqs after registering, as irqs may trigger immediately */
-- 
2.35.3

