Hi, On Thu, May 11, 2017 at 03:42:20PM +0200, Quentin Schulz wrote: > This adds the ability to set the maximum constant charge current, > supported by the battery, delivered by this battery power supply to the > battery. > > The maximum constant charge current set in DT will also set the default > constant charge current supplied by this supply. > > The actual user can modify the constant charge current within the range > of 0 to maximum constant charge current via sysfs. > The user can also modify the maximum constant charge current to widen > the range of possible constant charge current. While this seems quite > risky, a message is printed on the console to warn the user this might > damage the battery. The reason for letting the user change the maximum > constant charge current is for letting users change the battery and > thus, let them adjust the maximum constant charge current according to > what the battery can support. > > Signed-off-by: Quentin Schulz <quentin.schulz@xxxxxxxxxxxxxxxxxx> Thanks, queued. -- Sebastian > --- > drivers/power/supply/axp20x_battery.c | 78 +++++++++++++++++++++++++++++++---- > 1 file changed, 70 insertions(+), 8 deletions(-) > > diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c > index 66f530541735..7494f0f0eadb 100644 > --- a/drivers/power/supply/axp20x_battery.c > +++ b/drivers/power/supply/axp20x_battery.c > @@ -60,6 +60,8 @@ struct axp20x_batt_ps { > struct iio_channel *batt_chrg_i; > struct iio_channel *batt_dischrg_i; > struct iio_channel *batt_v; > + /* Maximum constant charge current */ > + unsigned int max_ccc; > u8 axp_id; > }; > > @@ -129,6 +131,14 @@ static void raw_to_constant_charge_current(struct axp20x_batt_ps *axp, int *val) > *val = *val * 150000 + 300000; > } > > +static void constant_charge_current_to_raw(struct axp20x_batt_ps *axp, int *val) > +{ > + if (axp->axp_id == AXP209_ID) > + *val = (*val - 300000) / 100000; > + else > + *val = (*val - 300000) / 150000; > +} > + > static int axp20x_get_constant_charge_current(struct axp20x_batt_ps *axp, > int *val) > { > @@ -221,9 +231,7 @@ static int axp20x_battery_get_prop(struct power_supply *psy, > break; > > case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: > - val->intval = AXP20X_CHRG_CTRL1_TGT_CURR; > - raw_to_constant_charge_current(axp20x_batt, &val->intval); > - > + val->intval = axp20x_batt->max_ccc; > break; > > case POWER_SUPPLY_PROP_CURRENT_NOW: > @@ -340,10 +348,10 @@ static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt, > static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt, > int charge_current) > { > - if (axp_batt->axp_id == AXP209_ID) > - charge_current = (charge_current - 300000) / 100000; > - else > - charge_current = (charge_current - 300000) / 150000; > + if (charge_current > axp_batt->max_ccc) > + return -EINVAL; > + > + constant_charge_current_to_raw(axp_batt, &charge_current); > > if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0) > return -EINVAL; > @@ -352,6 +360,36 @@ static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt, > AXP20X_CHRG_CTRL1_TGT_CURR, charge_current); > } > > +static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps *axp, > + int charge_current) > +{ > + bool lower_max = false; > + > + constant_charge_current_to_raw(axp, &charge_current); > + > + if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0) > + return -EINVAL; > + > + raw_to_constant_charge_current(axp, &charge_current); > + > + if (charge_current > axp->max_ccc) > + dev_warn(axp->dev, > + "Setting max constant charge current higher than previously defined. Note that increasing the constant charge current may damage your battery.\n"); > + else > + lower_max = true; > + > + axp->max_ccc = charge_current; > + > + if (lower_max) { > + int current_cc; > + > + axp20x_get_constant_charge_current(axp, ¤t_cc); > + if (current_cc > charge_current) > + axp20x_set_constant_charge_current(axp, charge_current); > + } > + > + return 0; > +} > static int axp20x_set_voltage_min_design(struct axp20x_batt_ps *axp_batt, > int min_voltage) > { > @@ -380,6 +418,9 @@ static int axp20x_battery_set_prop(struct power_supply *psy, > case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: > return axp20x_set_constant_charge_current(axp20x_batt, > val->intval); > + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: > + return axp20x_set_max_constant_charge_current(axp20x_batt, > + val->intval); > > default: > return -EINVAL; > @@ -405,7 +446,8 @@ static int axp20x_battery_prop_writeable(struct power_supply *psy, > { > return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN || > psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN || > - psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT; > + psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT || > + psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX; > } > > static const struct power_supply_desc axp20x_batt_ps_desc = { > @@ -487,13 +529,33 @@ 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; > > if (vmin > 0 && axp20x_set_voltage_min_design(axp20x_batt, > vmin)) > dev_err(&pdev->dev, > "couldn't set voltage_min_design\n"); > + > + /* Set max to unverified value to be able to set CCC */ > + axp20x_batt->max_ccc = ccc; > + > + if (ccc <= 0 || axp20x_set_constant_charge_current(axp20x_batt, > + ccc)) { > + dev_err(&pdev->dev, > + "couldn't set constant charge current from DT: fallback to minimum value\n"); > + ccc = 300000; > + axp20x_batt->max_ccc = ccc; > + axp20x_set_constant_charge_current(axp20x_batt, ccc); > + } > } > > + /* > + * Update max CCC to a valid value if battery info is present or set it > + * to current register value by default. > + */ > + axp20x_get_constant_charge_current(axp20x_batt, > + &axp20x_batt->max_ccc); > + > return 0; > } > > -- > 2.11.0 >
Attachment:
signature.asc
Description: PGP signature