Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Battery calibration issues after running Linux #6

Open
Adubbz opened this issue May 2, 2018 · 13 comments
Open

Battery calibration issues after running Linux #6

Adubbz opened this issue May 2, 2018 · 13 comments

Comments

@Adubbz
Copy link

Adubbz commented May 2, 2018

For starters, my apologies if this isn't the correct place to report this. Myself and others seem to be experiencing random shutdowns in games after running Linux when the battery gets to ~<50%. These shutdowns start happening on the home menu at ~<25%. At this point the switch won't turn on again without attaching a charger. Remaining on the home menu, turning the brightness all the way down, disabling sleep mode, setting the volume all the way down and enabling airplane mode appears to allow the switch to drain further. Although at ~<10% the shutdowns begin again.

Apparently pulling the battery and holding the power button for 15 seconds has addressed this for some people. Others have also suggested draining the battery to 0% and then charging it back up to 100% has worked, however very few have reported success after doing this, and those that did appear to have a different issue.

@Adubbz
Copy link
Author

Adubbz commented May 2, 2018

Also of note is that the system time/date is set to some point in 2035, although this is likely a separate issue

@SwtcR
Copy link
Contributor

SwtcR commented May 2, 2018

The time/date issue is normal. Linux keeps track of time using the hardware real-time clock directly, while Horizon instead stores an offset separately and never changes the hardware clock. By running Linux with NTP enabled, you change the hardware clock, and then Horizon gets the wrong time on the next boot. However, after Horizon syncs the clock again via the network, its offset will now be 0 (effectively), and from that point on Linux and Horizon should have synchronized clocks and the problem should not occur again. There may be some minor offsets as both Linux and Horizon correct clock drift independently, but periodic network sync in both OSes should keep things in check.

@tardyp
Copy link
Contributor

tardyp commented May 3, 2018

Documentation of the fuel gauge:
https://datasheets.maximintegrated.com/en/ds/MAX17047-MAX17050.pdf
Driver:
https://github.com/fail0verflow/switch-linux/blob/switch/drivers/power/supply/max17042_battery.c

Linux has code to modify the remaining battery percentage at boot at:
https://github.com/fail0verflow/switch-linux/blob/switch/drivers/power/supply/max17042_battery.c#L696
but only if it is enabled in platform_data
https://github.com/fail0verflow/switch-linux/blob/switch/drivers/power/supply/max17042_battery.c#L878

You can try and add a printk here to make sure that the registers are not written.

Then as per spec, the battery pourcentage is fully driven by fuel gauge, and read only by linux.
The calibration rehappens automatically if you let the battery charge for more than 100%.

@Adubbz
Copy link
Author

Adubbz commented May 3, 2018

That's a detail worth noting actually, I can confirm that my battery was at 100% with the cable still connected on a few occasions whilst using Linux. Perhaps this calibration has gone wrong somehow?

@0xdc
Copy link

0xdc commented May 5, 2018

So the kernel never gets to max17042_init_worker() because the battery driver is loaded before the charger due to built-in load order

[    0.411776] power_supply max170xx_battery: Not all required supplies found, defer probe
[    0.411805] max17042 1-0036: failed: power supply register
[    4.893795] power_supply max170xx_battery: max170xx_battery: Found supply : bq24190-charger

https://github.com/fail0verflow/switch-linux/blob/switch/drivers/power/supply/max17042_battery.c#L1081
https://github.com/fail0verflow/switch-linux/blob/switch/drivers/power/supply/Makefile#L49

Next, STATUS_POR_BIT is never set in the regmap. I couldn't figure out a way to enable it, but we can force this if statement to true:
https://github.com/fail0verflow/switch-linux/blob/switch/drivers/power/supply/max17042_battery.c#L1116

Finally, we have this line that has a couple of checks
https://github.com/fail0verflow/switch-linux/blob/switch/drivers/power/supply/max17042_battery.c#L878

enable_por_init isn't set by anything, but I added code to enable it via the devicetree. However, config_data has no code to initialise the struct and never has data. max17042_load_new_capacity_params requires bits from config_data and forcing the if causes the kernel to crash.

@perillamint
Copy link

perillamint commented Jun 28, 2018

It seems fuel gauge reports correct value. When I power cycle Switch using BQ24193 BATFET, it fixes "sudden shutdown" but battery percentage remains in the same value. Also, battery voltage doesn't look bad. It reports 3.7v.

I suspect this issue is a configuration issue on power system rather than fuel gauge issue.

@perillamint
Copy link

I spotted the difference of MAX77620 register status between HOS and Linux.

HOS wants MAX77620_REG_CNFGGLBL1 has 0x92 but Linux sets it to 0xFF. When I set MAX77620_REG_CNFGGLBL1 to 0x92, it fixes the "desync" problem

@CTCaer
Copy link

CTCaer commented Jul 1, 2018

CTCaer/hekate@9672650
CTCaer/hekate@7b97015

(2 commits because I forgot the driver changes..)

@natinusala
Copy link

u-boot and Linux side fixes :

https://gitlab.com/perillamint/switch-u-boot/commit/de3301b1f972ee4697c5d6903cb72f497bf07a02
https://gitlab.com/perillamint/switch-linux/commit/04b1850d56543c8aeb5cf52d3bf03eafbb5a1aa6

@perillamint
Copy link

Sorry, my previous patch for Linux disables LCD screen. Here is another dirty workaround.

https://gitlab.com/perillamint/switch-linux/commit/ce5c0d82c6555db14d3a872974aaf09ba0bc2a5a

This patch will prevent max77620-gpio driver is messing up CNFGGLBL1 reg in dirty way.

Root cause of this is, max77620-gpio driver thinks CNFGGLBL1 register is GPIO IRQ masking register and I don't know how to fix this properly because I don't have access to max77620 datasheet.

@perillamint
Copy link

Actuially, Nvidia tried to fix this issue by adding support for IRQ masking unsupported devices, which seems didn't got into mainline kernel

https://lkml.org/lkml/2013/2/21/166

@perillamint
Copy link

FYI, here is my write-up about discovering root cause of problem: https://blog.quendi.moe/2018/07/03/en-debugging-nintendo-switch-linux-power-management-battery-desync-edition/

@tardyp
Copy link
Contributor

tardyp commented Aug 3, 2018

Here is another fix as a fusee binary by @crystalseedgba

https://github.com/crystalseedgba/BatteryFix/blob/master/fusee/src/main.c

This one fixes the PMIC register, while @perillamint 's avoid to write it.
So you need to run the fix first and then run linux with uboot+linux patches.

@fail0verflow fail0verflow deleted a comment from cowkiller04 Jun 8, 2020
@fail0verflow fail0verflow deleted a comment from cowkiller04 Jun 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants