Commit c7868249 authored by Guido Gunther's avatar Guido Gunther Committed by Angus Ainslie (Purism)

bq25890: Provide battery capacity infomation

Use the current battery voltage and an ocv table to provide
battery capacity information.
Signed-off-by: Guido Gunther's avatarGuido Günther <agx@sigxcpu.org>
parent 80552e3a
......@@ -97,6 +97,10 @@ struct bq25890_device {
struct bq25890_init_data init_data;
struct bq25890_state state;
/* ocv capacity table */
struct power_supply_battery_ocv_table *cap_table;
int table_len;
struct mutex lock; /* protect state data */
};
......@@ -368,7 +372,7 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
int ret;
int ret, ocv;
struct bq25890_device *bq = power_supply_get_drvdata(psy);
struct bq25890_state state;
......@@ -455,7 +459,6 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
val->intval = bq25890_find_val(bq->init_data.vreg, TBL_VREG);
break;
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
val->intval = bq25890_find_val(bq->init_data.iterm, TBL_ITERM);
break;
......@@ -469,6 +472,21 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
val->intval = 2304000 + ret * 20000;
break;
case POWER_SUPPLY_PROP_CAPACITY:
if (!bq->cap_table)
return -EINVAL;
ret = bq25890_field_read(bq, F_SYSV); /* read measured value */
if (ret < 0)
return ret;
/* converted_val = 2.304V + ADC_val * 20mV (table 10.3.15) */
ocv = 2304000 + ret * 20000;
val->intval = power_supply_ocv2cap_simple(bq->cap_table, bq->table_len,
ocv);
dev_info(bq->dev, "Capacity for %d is %d%%", ocv, val->intval);
break;
default:
return -EINVAL;
}
......@@ -680,6 +698,7 @@ static enum power_supply_property bq25890_power_supply_props[] = {
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CAPACITY,
};
static char *bq25890_charger_supplied_to[] = {
......@@ -700,6 +719,7 @@ static int bq25890_power_supply_init(struct bq25890_device *bq)
psy_cfg.supplied_to = bq25890_charger_supplied_to;
psy_cfg.num_supplicants = ARRAY_SIZE(bq25890_charger_supplied_to);
psy_cfg.of_node = bq->dev->of_node;
bq->charger = power_supply_register(bq->dev, &bq25890_power_supply_desc,
&psy_cfg);
......@@ -827,6 +847,37 @@ static int bq25890_fw_probe(struct bq25890_device *bq)
return 0;
}
static int bq25890_battery_init(struct bq25890_device *bq)
{
struct power_supply_battery_ocv_table *table;
struct power_supply_battery_info info = {};
int ret;
/* battery information is optional */
ret = power_supply_get_battery_info(bq->charger, &info);
if (ret < 0) {
dev_info(bq->dev, "No battery found: %d", ret);
return 0;
}
/* We use a single OCV table at 20 C */
table = power_supply_find_ocv2cap_table(&info, 20, &bq->table_len);
if (!table)
return -EINVAL;
bq->cap_table = devm_kmemdup(bq->dev, table,
bq->table_len * sizeof(*table),
GFP_KERNEL);
if (!bq->cap_table) {
power_supply_put_battery_info(bq->charger, &info);
return -ENOMEM;
}
power_supply_put_battery_info(bq->charger, &info);
return 0;
}
static int bq25890_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
......@@ -926,8 +977,16 @@ static int bq25890_probe(struct i2c_client *client,
goto irq_fail;
}
ret = bq25890_battery_init(bq);
if (ret < 0) {
dev_err(dev, "Failed get battery information\n");
goto battery_fail;
}
return 0;
battery_fail:
power_supply_unregister(bq->charger);
irq_fail:
if (!IS_ERR_OR_NULL(bq->usb_phy))
usb_unregister_notifier(bq->usb_phy, &bq->usb_nb);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment