Bme replacement


[edit] Introduction

BME Replacement is a project aiming to bring proper FOSS replacement to Maemo's BME bits. It consists of both kernel and userland bits, cooperating, and make use of data provided by build-in hardware bq27x00 chip.

Unlike vanilla BME, replacement fully support USB hostmode, via usbmode.

[edit] Prerequisities

Kernel which provides bq2415x_charger, bq27x00_battery and rx51_battery modules. It also need to have "glue" between bq2415x_charger and monolitic musb driver. In practice, it means kernel-power52 or above (See: Kernel_Power)

[edit] Current state


.debs are available from:

It works for everyday usage, but some major problems were found, see below.


According to Estel, these bugs aren't present anymore. Compare 1 2 --marmistrz 16:13, 25 October 2014 (UTC)

[edit] Problems/bugs and proposed solutions

[edit] 1. Premature shutdown

Device is shutting down at EDV1 voltage, not allowing bq27x00 chip to calibrate capacity. Calibrating require device to be *at or below* EDV1 for 15 seconds straight - going above even for a split second resets timer, so another straight 15 seconds is required.

Proposed solutions

1. gconf value, that allow power users to change voltage, at which device shutdowns to any arbitrary value.

This is preferred solution, as some devices are more like to have problems with GSM chip restarting at low voltage, even around EDV1 3248 mV. People with such problems, that prefer GSM stability over calibration, could bump voltage threshold, to avoid problems. OTOH, people with less picky devices and/or dual-cell setups, could decrease limit, getting more from their batteries.

This method can be also augmented by solution 2, for "default" shutdown threshold.

1.a gconf value plus guard time use a timer plus frequent probing to ensure the voltage stays below the threshold set by gconf. This is the recommended method since the whole shutdown shouldn't get triggered by sub-second "brownouts" caused by power consumption spikes. A suggested guard time is 30..60s, a suggested sampling frequency for voltage is 1/s, though the hardware has limited support for such high sampling frequencies of voltage - further evaluation needed. Other alternative concepts like average over moving window (again window size: 30..60s) might be worth to consider.

Note that the high sampling frequency is only needed during the guard time. For moving window average this complicates the design a fair bit.


2. Using EDV1 flag, instead of EDV1 voltage, as trigger to shut device down. EDV1 *flag* being set, means, that device was just calibrated - it spares need complicated replication of 15 sec. calibration timer, mentioned in problem description.

EDV1 flag can be read from /sys/class/power_supply/bq24150a-0/registers address 0x55 0x0A, divided by 2.

2.a In case of EDV1 flag being not available*, fallback to using 3150 mV as shutdown threshold. Rationale: 3150 mV shouldn't cause GSM chip restarts on devices, where 3248 mV haven't caused it already.

It doesn't guarantee calibration, as it require 15 seconds *straight* below 3248 mV (EDV1 voltage), and 3150 mV might be just momentary low voltage spike. But, it is better than current implementation, which permits calibration *ever* - and, after all, it is just theoretical fallback for hyphotetical, non-existing kernel.

* theoretical possibility with custom kernels, that fullfill basic requiments, but don't feed all data - currently, no such kernel exist


  • Pali: Add two gconf values. First (bool) to enable shutdown device at EDV1 flag, second (int) to shutdown device at specified <= voltage. Default values: bool = true and int = 3150 (as suggested)

[edit] 2. Battery applet showing wrong value for capacity

From the #maemo-ssu irclog:

[14:15] <kerio> 2) instead of showing wildly inaccurate data, it's preferrable to show nothing, or a message indicating that data is unavailable

[14:16] <kerio> 3) f[censored] rx51-battery, given 2) there's no reason whatsoever to use it (except the temperature thing, but that's for dsme and pulseaudio, not for the battery/charging)

[14:17] <kerio> 4) bq27200 is our lord, bq27200 is our ruler, bq27200 is our saviour - when calibrated, /everything/ should be grabbed from bq27200 and that's it - percentages, capacity (when full and at the moment)

  • Pali: add gconf value (int) for using maximal (design) capacity from rx51_battery in battery applet. 0 - never, 1 - when not calibrated, 2 - always. Default value 1.
  • Pali: What battery applet should show (as maximal capacity) when gconf value is 0 and battery is not calibrated?

A: of course the LMD from bq27200 wich most likely still is better than anything else available. Please note that "CI" doesn't mean there are usually bogus values in bq27200, it might as well mean "32 cycles since last learning cycle, LMD of (example) 1314mAh is maybe not correct anymore since battery aged and it might be 5mAh less now". Still 1314 is probably way better than whatever else you might get from any other location on device. --joerg_rw 20:56, 27 March 2013 (UTC)

[edit] 3. bq27x00_battery sysfs node reports -ENODATA when not calibrated

It is a very serious problem, as CI flag (calibration needed) is set, when >32 charging cycles since last calibration. This result in dropping data, even if it is perfectly correct.

CI flag is set also, when battery isn't inserted into device for few minutes (in some devices, even few seconds).

In both cases, all scripts/programs that depends on those sysfsnodes breaks, due to "data read error". Also, -ENODATA is wrong, as in fact, chip report value for LMD (Last Measured Discharge) it is ILMD, default value of 2056 mAh. It should be provided by sysfs node, even, if not accurate - in any case, it's better than -ENODATA or "read error".

Proposed solutions

1. Fixing module, to always report value via sysfs node, as provided by hardware. Also, modifying those BME replacement bits, that require correct data, to watch for CI flag.


  • Pali: ...all scripts/programs that depends on those sysfsnodes breaks, due to "data read error". ... - bug in programs open/read syscall could fail and set some errno value (see manpages for read and open)

A: we don't need to read registers of bq27200, what we need are proper decoded data from bq27200 available in sysfs nodes like /CI etc. This is perfectly allowable even for power-supply according to readme excerpts shadowjk digged up. Usage of I2C_SLAVE_FORCE is strongly deprecated, since there is no justification why direct register read/write should be allowed when bq27200 has a proper comprehensive feature-complete driver. --joerg_rw 21:06, 27 March 2013 (UTC)

  • Pali: question what should power supply function return to power supply interface when data are/could be incorrect is for power supply kernel maintainer. TODO: add link for mailinglist (lkml) discussion about it.
  • Proposal from Kerio on this: hald-addon-bme should provide a way to know if bq27k is calibrated or not, and the battery applet should show a "(CI)" whenever it's not; should always come from rx51-battery, other data should always come from bq27k (with the implicit message that if it's uncalibrated, it might be inaccurate); the battery applet should have three modes: a mode where it does *the same thing as stock*, without showing anything at all (default for CSSU stable maybe?), a mode (default on CSSU testing, maybe?) where it prefers to calculate against the battery design reported by rx51-battery, and a mode where it calculates against the last full charge as reported by bq27k, regardless of calibration (but showing the CI indicator next to the charge/full charge report)
    • Pali: I do not agree, there should be only one version of bme replacement, not N versions with different preconfigured modes.

there's no sane rationale in using for anything. User isn't interested in charge relative to what battery been able to store when it been new. This would result in battery never reaching 100%, which for sure is odd! Rather user is interested when battery has reached 100% of capacity it can store right now - and that's LMD, not --joerg_rw 21:11, 27 March 2013 (UTC)