Message ID | 20200729104913.627242-1-ml@embed.me.uk (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
Series | drivers: power: axp20x-battery: support setting charge_full_design | expand |
Hi, On Wed, Jul 29, 2020 at 11:49:13AM +0100, Jack Mitchell wrote: > Signed-off-by: Jack Mitchell <ml@embed.me.uk> > --- ^ missing long description Also the patch does not apply and needs to be rebased. -- Sebastian > drivers/power/supply/axp20x_battery.c | 39 +++++++++++++++++++++++++++ > 1 file changed, 39 insertions(+) > > diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c > index fe96f77bffa7..8ce4ebe7ccd5 100644 > --- a/drivers/power/supply/axp20x_battery.c > +++ b/drivers/power/supply/axp20x_battery.c > @@ -60,6 +60,7 @@ > > #define AXP20X_V_OFF_MASK GENMASK(2, 0) > > +#define AXP20X_BAT_MAX_CAP_VALID BIT(7) > > struct axp20x_batt_ps; > > @@ -86,6 +87,7 @@ struct axp20x_batt_ps { > struct axp20x_thermal_sensor sensor; > /* Maximum constant charge current */ > unsigned int max_ccc; > + unsigned int charge_full_design; > const struct axp_data *data; > }; > > @@ -260,6 +262,10 @@ static int axp20x_battery_get_prop(struct power_supply *psy, > val->intval = POWER_SUPPLY_HEALTH_GOOD; > break; > > + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: > + val->intval = axp20x_batt->charge_full_design; > + break; > + So it reports 0 instead of the hardware information before setting it once when no setup happens through DT? -- Sebastian > case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: > ret = axp20x_get_constant_charge_current(axp20x_batt, > &val->intval); > @@ -401,6 +407,30 @@ static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt, > AXP20X_CHRG_CTRL1_TGT_VOLT, val); > } > > +static int axp20x_set_charge_full_design(struct axp20x_batt_ps *axp_batt, > + int charge_full_uah) > +{ > + /* (Unit: 1.456mAh) */ > + int max_capacity_units = charge_full_uah / 1456; > + int ret; > + > + u8 max_capacity_msb = (max_capacity_units & 0x7F00) >> 8; > + u8 max_capacity_lsb = (max_capacity_units & 0xFF); > + > + axp_batt->charge_full_design = max_capacity_units * 1456; > + > + max_capacity_msb |= AXP20X_BAT_MAX_CAP_VALID; > + > + ret = regmap_write(axp_batt->regmap, AXP288_FG_DES_CAP0_REG, > + max_capacity_lsb); > + > + if (ret) > + return ret; > + > + return regmap_write(axp_batt->regmap, AXP288_FG_DES_CAP1_REG, > + max_capacity_msb); > +} > + > static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt, > int charge_current) > { > @@ -492,6 +522,7 @@ static enum power_supply_property axp20x_battery_props[] = { > POWER_SUPPLY_PROP_STATUS, > POWER_SUPPLY_PROP_VOLTAGE_NOW, > POWER_SUPPLY_PROP_CURRENT_NOW, > + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, > POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, > POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, > POWER_SUPPLY_PROP_HEALTH, > @@ -675,6 +706,7 @@ static int axp20x_power_probe(struct platform_device *pdev) > if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) { > int vmin = info.voltage_min_design_uv; > int ccc = info.constant_charge_current_max_ua; > + int cfd = info.charge_full_design_uah; > > if (vmin > 0 && axp20x_set_voltage_min_design(axp20x_batt, > vmin)) > @@ -692,6 +724,13 @@ static int axp20x_power_probe(struct platform_device *pdev) > axp20x_batt->max_ccc = ccc; > axp20x_set_constant_charge_current(axp20x_batt, ccc); > } > + > + if (cfd > 0 && axp20x_set_charge_full_design(axp20x_batt, > + cfd)) { > + dev_err(&pdev->dev, > + "couldn't set charge_full_design\n"); > + axp20x_batt->charge_full_design = 0; > + } > } > > error = axp20x_thermal_register_sensor(pdev, axp20x_batt); > -- > 2.28.0 >
diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c index fe96f77bffa7..8ce4ebe7ccd5 100644 --- a/drivers/power/supply/axp20x_battery.c +++ b/drivers/power/supply/axp20x_battery.c @@ -60,6 +60,7 @@ #define AXP20X_V_OFF_MASK GENMASK(2, 0) +#define AXP20X_BAT_MAX_CAP_VALID BIT(7) struct axp20x_batt_ps; @@ -86,6 +87,7 @@ struct axp20x_batt_ps { struct axp20x_thermal_sensor sensor; /* Maximum constant charge current */ unsigned int max_ccc; + unsigned int charge_full_design; const struct axp_data *data; }; @@ -260,6 +262,10 @@ static int axp20x_battery_get_prop(struct power_supply *psy, val->intval = POWER_SUPPLY_HEALTH_GOOD; break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + val->intval = axp20x_batt->charge_full_design; + break; + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: ret = axp20x_get_constant_charge_current(axp20x_batt, &val->intval); @@ -401,6 +407,30 @@ static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt, AXP20X_CHRG_CTRL1_TGT_VOLT, val); } +static int axp20x_set_charge_full_design(struct axp20x_batt_ps *axp_batt, + int charge_full_uah) +{ + /* (Unit: 1.456mAh) */ + int max_capacity_units = charge_full_uah / 1456; + int ret; + + u8 max_capacity_msb = (max_capacity_units & 0x7F00) >> 8; + u8 max_capacity_lsb = (max_capacity_units & 0xFF); + + axp_batt->charge_full_design = max_capacity_units * 1456; + + max_capacity_msb |= AXP20X_BAT_MAX_CAP_VALID; + + ret = regmap_write(axp_batt->regmap, AXP288_FG_DES_CAP0_REG, + max_capacity_lsb); + + if (ret) + return ret; + + return regmap_write(axp_batt->regmap, AXP288_FG_DES_CAP1_REG, + max_capacity_msb); +} + static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt, int charge_current) { @@ -492,6 +522,7 @@ static enum power_supply_property axp20x_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_HEALTH, @@ -675,6 +706,7 @@ static int axp20x_power_probe(struct platform_device *pdev) if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) { int vmin = info.voltage_min_design_uv; int ccc = info.constant_charge_current_max_ua; + int cfd = info.charge_full_design_uah; if (vmin > 0 && axp20x_set_voltage_min_design(axp20x_batt, vmin)) @@ -692,6 +724,13 @@ static int axp20x_power_probe(struct platform_device *pdev) axp20x_batt->max_ccc = ccc; axp20x_set_constant_charge_current(axp20x_batt, ccc); } + + if (cfd > 0 && axp20x_set_charge_full_design(axp20x_batt, + cfd)) { + dev_err(&pdev->dev, + "couldn't set charge_full_design\n"); + axp20x_batt->charge_full_design = 0; + } } error = axp20x_thermal_register_sensor(pdev, axp20x_batt);
Signed-off-by: Jack Mitchell <ml@embed.me.uk> --- drivers/power/supply/axp20x_battery.c | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)