From: Hans de Goede Date: Thu, 6 Jan 2022 11:06:08 +0000 (+0100) Subject: power: supply: axp288_fuel_gauge: Add a no_current_sense_res module_param X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=210bc22c5d3d894cd032e0957035933945266d71;p=linux.git power: supply: axp288_fuel_gauge: Add a no_current_sense_res module_param Some boards with an AXP288 fuel-gauge appear to have a broken (approx. 2 milli-ohm instead of 10) current sense resistor. This makes the coulomb-counter part of the fuel-gauge useless, but the OCV based capacity reporting is still working. Add a no_current_sense_res module_param to disable use of the coulomb-counter using parts of the fuel-gauge to allow users to work around this. Note this is a module parameter and not done through DMI quirks, since this seems to be a defect on some boards, not something which all boards of the same model share. Signed-off-by: Hans de Goede Signed-off-by: Sebastian Reichel --- diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c index 53d0e82bbb3e3..dcedbc59732dd 100644 --- a/drivers/power/supply/axp288_fuel_gauge.c +++ b/drivers/power/supply/axp288_fuel_gauge.c @@ -88,6 +88,11 @@ #define AXP288_REG_UPDATE_INTERVAL (60 * HZ) #define AXP288_FG_INTR_NUM 6 + +static bool no_current_sense_res; +module_param(no_current_sense_res, bool, 0444); +MODULE_PARM_DESC(no_current_sense_res, "No (or broken) current sense resisitor"); + enum { QWBTU_IRQ = 0, WBTU_IRQ, @@ -137,12 +142,13 @@ static enum power_supply_property fuel_gauge_props[] = { POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_OCV, - POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN, POWER_SUPPLY_PROP_TECHNOLOGY, + /* The 3 props below are not used when no_current_sense_res is set */ POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, }; static int fuel_gauge_reg_readb(struct axp288_fg_info *info, int reg) @@ -224,7 +230,10 @@ static int fuel_gauge_update_registers(struct axp288_fg_info *info) goto out; info->pwr_stat = ret; - ret = fuel_gauge_reg_readb(info, AXP20X_FG_RES); + if (no_current_sense_res) + ret = fuel_gauge_reg_readb(info, AXP288_FG_OCV_CAP_REG); + else + ret = fuel_gauge_reg_readb(info, AXP20X_FG_RES); if (ret < 0) goto out; info->fg_res = ret; @@ -233,6 +242,14 @@ static int fuel_gauge_update_registers(struct axp288_fg_info *info) if (ret < 0) goto out; + ret = fuel_gauge_read_12bit_word(info, AXP288_FG_OCVH_REG); + if (ret < 0) + goto out; + info->ocv = ret; + + if (no_current_sense_res) + goto out_no_current_sense_res; + if (info->pwr_stat & PS_STAT_BAT_CHRG_DIR) { info->d_curr = 0; ret = iio_read_channel_raw(info->iio_channel[BAT_CHRG_CURR], &info->c_curr); @@ -245,11 +262,6 @@ static int fuel_gauge_update_registers(struct axp288_fg_info *info) goto out; } - ret = fuel_gauge_read_12bit_word(info, AXP288_FG_OCVH_REG); - if (ret < 0) - goto out; - info->ocv = ret; - ret = fuel_gauge_read_15bit_word(info, AXP288_FG_CC_MTR1_REG); if (ret < 0) goto out; @@ -260,6 +272,7 @@ static int fuel_gauge_update_registers(struct axp288_fg_info *info) goto out; info->fg_des_cap1 = ret; +out_no_current_sense_res: info->last_updated = jiffies; info->valid = 1; ret = 0; @@ -292,7 +305,7 @@ static void fuel_gauge_get_status(struct axp288_fg_info *info) * When this happens the AXP288 reports a not-charging status and * 0 mA discharge current. */ - if (fg_res < 90 || (pwr_stat & PS_STAT_BAT_CHRG_DIR)) + if (fg_res < 90 || (pwr_stat & PS_STAT_BAT_CHRG_DIR) || no_current_sense_res) goto not_full; if (curr == 0) { @@ -494,7 +507,7 @@ static void fuel_gauge_external_power_changed(struct power_supply *psy) power_supply_changed(info->bat); } -static const struct power_supply_desc fuel_gauge_desc = { +static struct power_supply_desc fuel_gauge_desc = { .name = DEV_NAME, .type = POWER_SUPPLY_TYPE_BATTERY, .properties = fuel_gauge_props, @@ -719,6 +732,8 @@ static int axp288_fuel_gauge_probe(struct platform_device *pdev) return ret; psy_cfg.drv_data = info; + if (no_current_sense_res) + fuel_gauge_desc.num_properties = ARRAY_SIZE(fuel_gauge_props) - 3; info->bat = devm_power_supply_register(dev, &fuel_gauge_desc, &psy_cfg); if (IS_ERR(info->bat)) { ret = PTR_ERR(info->bat);