megi's PinePhone Development Log RSS


2020–09–20: Some ways to improve Pinephone safety

This is a follow up on some issues from the previous article. On surface, solutions to some of the previously presented issues can seem simple. Toggle a few registers in PMIC, and we're mostly done. Trouble is that safety mechanisms are barely ever triggered, by definition. Safety events occur rarely. That means that the mechanisms are not regularly tested, and it is not known that they work.

Also it's not clear which code's responsibility fixing the issues should be. Bootloader, or kernel, or userspace? Finally, there are a bunch of devils in the details, that complicate the upstreamability of any solution. And having fixes upstream is necessary to make sure they reach the most users.

Necessary minimum

Nevertheless, at least enabling some pre-existing PMIC functionality blindly is better than nothing, so that's precisely what I decided to do in p-boot. It's the easiest place to start resolving these issues for me personally, and for other p-boot users.

I fixed two issues:

I didn't measure the 3kOhm NTC used in Pinephone battery and third party batteries I bought. I just used a table from some random 3kOhm NTC spec on The Internet, that seemed like it could match. Hopefully it's close enough.

Trouble with the second fix is that it's a hard power cut-off, so data loss may occur when PMIC overheats. There are three fixed temperature levels in AXP803. On level 1 the charging is limited, on level 2 the interrupt is sent to SoC, on level 3 the PMIC shuts down if configured to do so (by default it keeps running, and this is what my p-boot fix changes). Ideally, the crossing of level 2 would be handled by Linux to make it safely shut down the system, and level 3 forced power cut-off would never happen. Arguably, if charging was source of the heating, crossing level 1 will lead to resolving the issue, so the next level will not be reached.

Suggested fixes elsewhere

These fixes will reach a very limited audience. It would be nice to have these fixes in U-Boot too, but that's not possible at the moment, because U-Boot doesn't have access to PMIC.

Other places to put the fix is to ATF or Linux kernel. That can reach more people faster, but there would have to be some generic mechanism to make the fix upstreamable, otherwise it will not reach people using the mainline Linux kernel or mainline ATF.

There are some ways to approach this:

First, the most generic solution would be to have a description of the battery in DT describing the Pinephone. Sadly, the current bindings don't include battery temperature limits.

Also converting from temperature to NTC resistance (which is necessary to determine the code word from ADC for the limits used by the temperature monitor logic in PMIC) is not straightforward. It is usually defined in NTC datasheet as a table. Do I have NTC datasheet? No. I bought the batteries online from some mobile phone service shop.

There are also equations that approximate the temperature – resistance relationship for the NTC, which could be used instead of a fixed table, if one knows the relevant coefficients. These can be calculated after measuring the NTC's resistance at a few temperature points when we lack the datasheet.

So generic solution may look like this:

Kernel also has support for NTC devices, so maybe NTC can be described outside of the battery node (even though it's part of the battery).

This may all fail to be upstreamed on one thing: the battery is user swappable, so it's arguably not part of the Pinephone, and describing it inside the pinephone DT will not be appropriate.

I don't have any plans implementing any of the above, atm. Maybe with the exception of adding a 4th approach to the fix to my Linux kernel (the easiest one ;)). I'd like to work on my multi-boot image. So these are mostly pointers for somebody else who'd like to tackle this.

Other issues

Fast charging is not necesary in many situations, so having it as a default is not great. User should be able to decide if he wants to trade off slower, safer charging and battery longetivity over speed. This tradeoff can be realized in many ways.

All this is already controllable from userspace via sysfs. Ideally there would be some charging monitoring daemon that would take into account users's wishes and select proper strategy for charging, based on preference for battery longetivity or speed.

There are several trade offs the deamon would be able to handle:

All this is decision making that doesn't belong to the kernel.

Similar daemon could monitor power usage of the phone and try to limit it to safer levels, or warn the user if that's not possible.