diff mbox series

[3/3] RFC: power: supply: cpcap-battery: Implement capacity percentage

Message ID 20200119201124.29620-3-tony@atomide.com (mailing list archive)
State New, archived
Headers show
Series [1/3] RFC: power: supply: cpcap-battery: Add helper for rough capacity | expand

Commit Message

Tony Lindgren Jan. 19, 2020, 8:11 p.m. UTC
Based on the saved high and low states, we can estimate battery state
based on the coulomb counter:

# cat /sys/class/power_supply/battery/capacity
...

Note that this too should probably be updated to use ocv-capacity-table.

Also note that I have not verified the shown capacity is very accurate.

Cc: Merlijn Wajer <merlijn@wizzup.org>
Cc: Pavel Machek <pavel@ucw.cz>
Not-yet-Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/power/supply/cpcap-battery.c | 35 ++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c
--- a/drivers/power/supply/cpcap-battery.c
+++ b/drivers/power/supply/cpcap-battery.c
@@ -504,6 +504,15 @@  static int cpcap_battery_get_rough_capacity(struct cpcap_battery_ddata *ddata)
 	return capacity;
 }
 
+static int cpcap_battery_get_rough_percentage(struct cpcap_battery_ddata *ddata)
+{
+	int percentage = 0;
+
+	cpcap_battery_get_rough(ddata, NULL, &percentage);
+
+	return percentage;
+}
+
 static enum power_supply_property cpcap_battery_props[] = {
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_PRESENT,
@@ -518,6 +527,7 @@  static enum power_supply_property cpcap_battery_props[] = {
 	POWER_SUPPLY_PROP_CHARGE_COUNTER,
 	POWER_SUPPLY_PROP_POWER_NOW,
 	POWER_SUPPLY_PROP_POWER_AVG,
+	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
 	POWER_SUPPLY_PROP_SCOPE,
 	POWER_SUPPLY_PROP_TEMP,
@@ -528,10 +538,10 @@  static int cpcap_battery_get_property(struct power_supply *psy,
 				      union power_supply_propval *val)
 {
 	struct cpcap_battery_ddata *ddata = power_supply_get_drvdata(psy);
-	struct cpcap_battery_state_data *latest, *previous;
+	struct cpcap_battery_state_data *latest, *previous, *low, *high;
 	u32 sample;
 	s32 accumulator;
-	int cached;
+	int cached, delta, est;
 	s64 tmp;
 
 	cached = cpcap_battery_update_status(ddata);
@@ -608,6 +618,27 @@  static int cpcap_battery_get_property(struct power_supply *psy,
 		tmp *= ((latest->voltage + previous->voltage) / 20000);
 		val->intval = div64_s64(tmp, 100);
 		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		est = cpcap_battery_get_rough_percentage(ddata);
+		high = cpcap_battery_get_highest(ddata);
+		if (high->voltage) {
+			delta = latest->counter_uah - high->counter_uah;
+			val->intval = (ddata->config.info.charge_full_design -
+				       delta) * 100;
+			val->intval /= ddata->config.info.charge_full_design;
+			delta = abs(val->intval - est);
+			break;
+		}
+		low = cpcap_battery_get_lowest(ddata);
+		if (low->voltage) {
+			delta = low->counter_uah - latest->counter_uah;
+			val->intval = (delta * 100) /
+				ddata->config.info.charge_full_design;
+			delta = abs(val->intval - est);
+			break;
+		}
+		val->intval = est;
+		break;
 	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
 		val->intval = cpcap_battery_get_rough_capacity(ddata);
 		break;