summaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2022-01-06 12:06:08 +0100
committerSebastian Reichel <sebastian.reichel@collabora.com>2022-02-01 14:29:34 +0100
commit210bc22c5d3d894cd032e0957035933945266d71 (patch)
tree51bf659cc216de38f0536070bf2d7ac36fabc5b2 /drivers/power
parent30abb3d07929137bf72327560e1595508a692c4e (diff)
downloadlinux-210bc22c5d3d894cd032e0957035933945266d71.tar.bz2
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.c33
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);