Sebastian Reichel <sebastian.reichel@xxxxxxxxxxxxx> writes: > Hi, > > On Tue, Jun 07, 2022 at 04:53:22PM +0100, Aidan MacDonald wrote: >> Add a table-based lookup method for constant charge current, >> which is necessary when the setting cannot be represented as >> a linear range. >> >> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@xxxxxxxxx> >> --- >> drivers/power/supply/axp20x_battery.c | 53 +++++++++++++++++++++------ >> 1 file changed, 41 insertions(+), 12 deletions(-) >> >> diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c >> index 9106077c0dbb..87fb958f2224 100644 >> --- a/drivers/power/supply/axp20x_battery.c >> +++ b/drivers/power/supply/axp20x_battery.c >> @@ -61,6 +61,7 @@ struct axp20x_batt_ps; >> struct axp_data { >> int ccc_scale; >> int ccc_offset; >> + const int *ccc_table; > > Please document the struct; especially the fact that ccc_table must > have a size of AXP20X_CHRG_CTRL1_TGT_CURR + 1. > > -- Sebastian > Thanks, I'll make sure to do that in v3. Regards, Aidan >> bool has_fg_valid; >> int (*get_max_voltage)(struct axp20x_batt_ps *batt, int *val); >> int (*set_max_voltage)(struct axp20x_batt_ps *batt, int val); >> @@ -176,7 +177,10 @@ static int axp20x_get_constant_charge_current(struct axp20x_batt_ps *axp, >> >> *val &= AXP20X_CHRG_CTRL1_TGT_CURR; >> >> - *val = *val * axp->data->ccc_scale + axp->data->ccc_offset; >> + if (axp->data->ccc_table) >> + *val = axp->data->ccc_table[*val]; >> + else >> + *val = *val * axp->data->ccc_scale + axp->data->ccc_offset; >> >> return 0; >> } >> @@ -389,16 +393,36 @@ static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt, >> AXP20X_CHRG_CTRL1_TGT_VOLT, val); >> } >> >> +static int axp20x_get_constant_charge_current_sel(struct axp20x_batt_ps *axp_batt, >> + int charge_current) >> +{ >> + int i; >> + >> + if (axp_batt->data->ccc_table) { >> + for (i = AXP20X_CHRG_CTRL1_TGT_CURR; i >= 0; --i) { >> + if (axp_batt->data->ccc_table[i] <= charge_current) >> + return i; >> + } >> + >> + return -EINVAL; >> + } >> + >> + i = (charge_current - axp_batt->data->ccc_offset) / axp_batt->data->ccc_scale; >> + >> + if (i > AXP20X_CHRG_CTRL1_TGT_CURR || i < 0) >> + return -EINVAL; >> + >> + return i; >> +} >> + >> static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt, >> int charge_current) >> { >> if (charge_current > axp_batt->max_ccc) >> return -EINVAL; >> >> - charge_current = (charge_current - axp_batt->data->ccc_offset) / >> - axp_batt->data->ccc_scale; >> - >> - if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0) >> + charge_current = axp20x_get_constant_charge_current_sel(axp_batt, charge_current); >> + if (charge_current < 0) >> return -EINVAL; >> >> return regmap_update_bits(axp_batt->regmap, AXP20X_CHRG_CTRL1, >> @@ -410,14 +434,14 @@ static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps *axp, >> { >> bool lower_max = false; >> >> - charge_current = (charge_current - axp->data->ccc_offset) / >> - axp->data->ccc_scale; >> - >> - if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0) >> + charge_current = axp20x_get_constant_charge_current_sel(axp, charge_current); >> + if (charge_current < 0) >> return -EINVAL; >> >> - charge_current = charge_current * axp->data->ccc_scale + >> - axp->data->ccc_offset; >> + if (axp->data->ccc_table) >> + charge_current = axp->data->ccc_table[charge_current]; >> + else >> + charge_current = charge_current * axp->data->ccc_scale + axp->data->ccc_offset; >> >> if (charge_current > axp->max_ccc) >> dev_warn(axp->dev, >> @@ -629,7 +653,12 @@ static int axp20x_power_probe(struct platform_device *pdev) >> ccc)) { >> dev_err(&pdev->dev, >> "couldn't set constant charge current from DT: fallback to minimum value\n"); >> - ccc = 300000; >> + >> + if (axp20x_batt->data->ccc_table) >> + ccc = axp20x_batt->data->ccc_table[0]; >> + else >> + ccc = axp20x_batt->data->ccc_offset; >> + >> axp20x_batt->max_ccc = ccc; >> axp20x_set_constant_charge_current(axp20x_batt, ccc); >> } >> -- >> 2.35.1 >>