diff options
author | Hans de Goede <hdegoede@redhat.com> | 2022-01-06 12:06:08 +0100 |
---|---|---|
committer | Sebastian Reichel <sebastian.reichel@collabora.com> | 2022-02-01 14:29:34 +0100 |
commit | 210bc22c5d3d894cd032e0957035933945266d71 (patch) | |
tree | 51bf659cc216de38f0536070bf2d7ac36fabc5b2 /drivers/power | |
parent | 30abb3d07929137bf72327560e1595508a692c4e (diff) | |
download | linux-stable-210bc22c5d3d894cd032e0957035933945266d71.tar.gz linux-stable-210bc22c5d3d894cd032e0957035933945266d71.tar.bz2 linux-stable-210bc22c5d3d894cd032e0957035933945266d71.zip |
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 <hdegoede@redhat.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/supply/axp288_fuel_gauge.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c index 53d0e82bbb3e..dcedbc59732d 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); |