[Letux-kernel] [PATCH] power: supply: bq27xxx: do not report bogus zero values

H. Nikolaus Schaller hns at goldelico.com
Thu Feb 27 18:48:49 CET 2025


Another comment (in code section)

> Am 27.02.2025 um 18:14 schrieb H. Nikolaus Schaller <hns at goldelico.com>:
> 
> Hi,
> 
> 
>> Am 07.02.2025 um 22:51 schrieb Sicelo A. Mhlongo <absicsz at gmail.com>:
>> 
>> On the bq27x00 and bq27x10 variants, a number of conditions may reset the value
>> stored in the NAC register. This will cause capacity, energy, and charge to
>> report the value 0, even when the battery is full. On the other hand, the chip
>> also provides a flag, EDVF, which accurately detects the true battery empty
>> condition, when capacity, charge, and energy are really 0.  Therefore, discard
>> readings for these properties if their value is 0 while EDVF is unset.
>> 
>> Tested on the Nokia N900 with bq27200.
> 
> I finally found time to test this patch on the GTA04 which uses an OpenMoko HF08
> battery which comes with a built-in bq27000.
> 
> The result is that I can't read the /sys/class/power_supply/bq27000-battery/charge_now
> at all and always get EINVAL. Independently of the charge level reported without
> your patch.
> 
> If I remove this patch again, the values are reasonable as in all the years before.
> 
> What I don't know is how and to which values the EEPROM of the bq27000 has been
> factory programmed so that the HF08 battery maybehave differently from yours.
> 
> Finally, I am not aware of reports from GTA04 users that the value stored in the NAC
> register is being reset as you describe and capacity, energy and charge to be falsely
> reported as 0.
> 
> So please restrict this patch to the N900.
> 
> BR and thanks,
> Nikolaus
> 
>> Signed-off-by: Sicelo A. Mhlongo <absicsz at gmail.com>
>> ---
>> drivers/power/supply/bq27xxx_battery.c | 17 +++++++++++++++--
>> 1 file changed, 15 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
>> index 90a5bccfc6b9..df92f55c63f6 100644
>> --- a/drivers/power/supply/bq27xxx_battery.c
>> +++ b/drivers/power/supply/bq27xxx_battery.c
>> @@ -2115,6 +2115,10 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
>> break;
>> case POWER_SUPPLY_PROP_CAPACITY:
>> ret = bq27xxx_simple_value(di->cache.capacity, val);
>> + /* If 0 is reported, it is expected that EDVF is also set */
>> + if (!ret && di->opts & BQ27XXX_O_ZERO &&
>> +   !(di->cache.flags & BQ27000_FLAG_EDVF))
>> + return -EINVAL;

You write:

  Therefore, discard readings for these properties if their value is 0 while EDVF is unset.

but the 'val' is not checked at all. Only the error return value
'ret' of bq27xxx_simple_value() which is 0 if reading was ok.

So shouldn't that be:

+ if (!val->intval && di->opts & BQ27XXX_O_ZERO &&
+   !(di->cache.flags & BQ27000_FLAG_EDVF))
+ return -EINVAL;

This could explain why I always get an -EINVAL here since BQ27000_FLAG_EDVF is likely not set.

>> break;
>> case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
>> ret = bq27xxx_battery_capacity_level(di, val);
>> @@ -2138,10 +2142,15 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
>> val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
>> break;
>> case POWER_SUPPLY_PROP_CHARGE_NOW:
>> - if (di->regs[BQ27XXX_REG_NAC] != INVALID_REG_ADDR)
>> + if (di->regs[BQ27XXX_REG_NAC] != INVALID_REG_ADDR) {
>> ret = bq27xxx_battery_read_nac(di, val);
>> - else
>> + /* If 0 is reported, it is expected that EDVF is also set */
>> + if (!ret && di->opts & BQ27XXX_O_ZERO &&
>> +   !(di->cache.flags & BQ27000_FLAG_EDVF))
>> + return -EINVAL;
>> + } else {
>> ret = bq27xxx_battery_read_rc(di, val);
>> + }
>> break;
>> case POWER_SUPPLY_PROP_CHARGE_FULL:
>> ret = bq27xxx_battery_read_fcc(di, val);
>> @@ -2163,6 +2172,10 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
>> break;
>> case POWER_SUPPLY_PROP_ENERGY_NOW:
>> ret = bq27xxx_battery_read_energy(di, val);
>> + /* If 0 is reported, it is expected that EDVF is also set */
>> + if (!ret && di->opts & BQ27XXX_O_ZERO &&
>> +   !(di->cache.flags & BQ27000_FLAG_EDVF))
>> + return -EINVAL;
>> break;
>> case POWER_SUPPLY_PROP_POWER_AVG:
>> ret = bq27xxx_battery_pwr_avg(di, val);
>> -- 
>> 2.47.2
>> 
>> 
> 
> 



More information about the Letux-kernel mailing list