128 lines
3.8 KiB
Diff
128 lines
3.8 KiB
Diff
From a801f9366cd3587696b9b2e2f072f93f771fbe14 Mon Sep 17 00:00:00 2001
|
|
From: Ondrej Jirman <megi@xff.cz>
|
|
Date: Wed, 16 Feb 2022 18:12:56 +0100
|
|
Subject: [PATCH 318/389] power: supply: ip5xxx: Report remaining battery
|
|
capacity
|
|
|
|
This uses OCV tables from device tree. Internal resistance value used
|
|
by the chip is not very precise. Use the value from DT, too.
|
|
|
|
Signed-off-by: Ondrej Jirman <megi@xff.cz>
|
|
---
|
|
drivers/power/supply/ip5xxx_power.c | 43 +++++++++++++++++++++++++++++
|
|
1 file changed, 43 insertions(+)
|
|
|
|
diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c
|
|
index 00221e9c0bfc..7f79644a976a 100644
|
|
--- a/drivers/power/supply/ip5xxx_power.c
|
|
+++ b/drivers/power/supply/ip5xxx_power.c
|
|
@@ -76,6 +76,8 @@
|
|
|
|
struct ip5xxx {
|
|
struct regmap *regmap;
|
|
+ struct power_supply_battery_info *bat;
|
|
+ int r_int;
|
|
bool initialized;
|
|
};
|
|
|
|
@@ -171,6 +173,8 @@ static const enum power_supply_property ip5xxx_battery_properties[] = {
|
|
POWER_SUPPLY_PROP_STATUS,
|
|
POWER_SUPPLY_PROP_CHARGE_TYPE,
|
|
POWER_SUPPLY_PROP_HEALTH,
|
|
+ POWER_SUPPLY_PROP_CAPACITY,
|
|
+ POWER_SUPPLY_PROP_CALIBRATE,
|
|
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
|
|
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
|
POWER_SUPPLY_PROP_VOLTAGE_OCV,
|
|
@@ -316,6 +320,7 @@ static int ip5xxx_battery_get_property(struct power_supply *psy,
|
|
struct ip5xxx *ip5xxx = power_supply_get_drvdata(psy);
|
|
int raw, ret, vmax;
|
|
unsigned int rval;
|
|
+ union power_supply_propval cur, vol;
|
|
|
|
ret = ip5xxx_initialize(psy);
|
|
if (ret)
|
|
@@ -331,6 +336,23 @@ static int ip5xxx_battery_get_property(struct power_supply *psy,
|
|
case POWER_SUPPLY_PROP_HEALTH:
|
|
return ip5xxx_battery_get_health(ip5xxx, &val->intval);
|
|
|
|
+ case POWER_SUPPLY_PROP_CAPACITY:
|
|
+ ret = ip5xxx_battery_get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &vol);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ ret = ip5xxx_battery_get_property(psy, POWER_SUPPLY_PROP_CURRENT_NOW, &cur);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ ret = power_supply_batinfo_ocv2cap(ip5xxx->bat,
|
|
+ vol.intval - cur.intval * ip5xxx->r_int / 1000, 20);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
+ val->intval = ret;
|
|
+ return 0;
|
|
+
|
|
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
|
|
return ip5xxx_battery_get_voltage_max(ip5xxx, &val->intval);
|
|
|
|
@@ -389,6 +411,10 @@ static int ip5xxx_battery_get_property(struct power_supply *psy,
|
|
val->intval = vmax + 14000 * 3;
|
|
return 0;
|
|
|
|
+ case POWER_SUPPLY_PROP_CALIBRATE:
|
|
+ val->intval = ip5xxx->r_int;
|
|
+ return 0;
|
|
+
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
@@ -472,6 +498,12 @@ static int ip5xxx_battery_set_property(struct power_supply *psy,
|
|
return ip5xxx_update_bits(ip5xxx, IP5XXX_CHG_CTL2,
|
|
IP5XXX_CHG_CTL2_CONST_VOLT_SEL, rval);
|
|
|
|
+ case POWER_SUPPLY_PROP_CALIBRATE:
|
|
+ if (val->intval < 0 || val->intval > 1000)
|
|
+ return -EINVAL;
|
|
+ ip5xxx->r_int = val->intval;
|
|
+ return 0;
|
|
+
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
@@ -482,6 +514,7 @@ static int ip5xxx_battery_property_is_writeable(struct power_supply *psy,
|
|
{
|
|
return psp == POWER_SUPPLY_PROP_STATUS ||
|
|
psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN ||
|
|
+ psp == POWER_SUPPLY_PROP_CALIBRATE ||
|
|
psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT ||
|
|
psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE;
|
|
}
|
|
@@ -592,6 +625,7 @@ static int ip5xxx_power_probe(struct i2c_client *client)
|
|
struct device *dev = &client->dev;
|
|
struct power_supply *psy;
|
|
struct ip5xxx *ip5xxx;
|
|
+ int ret;
|
|
|
|
ip5xxx = devm_kzalloc(dev, sizeof(*ip5xxx), GFP_KERNEL);
|
|
if (!ip5xxx)
|
|
@@ -612,6 +646,15 @@ static int ip5xxx_power_probe(struct i2c_client *client)
|
|
if (IS_ERR(psy))
|
|
return PTR_ERR(psy);
|
|
|
|
+ ret = power_supply_get_battery_info(psy, &ip5xxx->bat);
|
|
+ if (ret)
|
|
+ return dev_err_probe(dev, ret, "Failed to get battery info\n");
|
|
+
|
|
+ if (ip5xxx->bat->factory_internal_resistance_uohm >= 0)
|
|
+ ip5xxx->r_int = ip5xxx->bat->factory_internal_resistance_uohm / 1000;
|
|
+ else
|
|
+ ip5xxx->r_int = 120;
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--
|
|
2.35.3
|
|
|