Skip to content

rk817: correct the fuel gauge across boot and sleep - #3305

Draft
Jacob-Matthew-Cook wants to merge 2 commits into
ROCKNIX:nextfrom
Jacob-Matthew-Cook:rk817-fuel-gauge-kernel
Draft

Jacob-Matthew-Cook wants to merge 2 commits into
ROCKNIX:nextfrom
Jacob-Matthew-Cook:rk817-fuel-gauge-kernel

Conversation

@Jacob-Matthew-Cook

@Jacob-Matthew-Cook Jacob-Matthew-Cook commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

@macromorgan @porschemad911 — flagging early since 001 and 002 are Chris's patches (002 co-developed), and the rk817 driver is his upstream.

  • 001 — NVRAM soc misread (Chris Morgan). The stored value runs 0..100000, but the bounds check truncates at 10000, so a full battery reads back as 10%. Fixes: the original driver commit.
  • 002 — boot soc resolved from the counter (Chris Morgan, co-developed). The boot value comes from PWRON_VOL when OFF_CNT reads three or more and from the columb counter otherwise, and both fail in the field. PWRON_VOL samples at the power-on instant, so a power-on caused by plugging in a charger samples under charge current — on an RG353M it read above the pack's maximum design voltage while the pack sat at 74%, and an RG DS was seen holding 2.63V while running. A negative counter was clamped to zero and reported 0%. The counter keeps counting while the system is off, so resolve from it first.
  • 005 — gauge corrected across sleep (mine). The counter is erratic while the system sleeps: one 15 minute sleep on an RG353M charging at 1.4A registered 69% of the metered charge, another 139%, and a charge that finished during sleep still showed the pre-sleep percentage at wake. The correcting signals are gone by the time the driver runs again — RELAX_STS clears once the wakeup load exceeds the relax threshold (300mA, less than an idle UI draws) and CHARGE_FINISH disappears while the charger re-detects its input. Stamp boottime, charge, current and charging state at suspend; recompute from that evidence at resume.

Split out of #3220 at @porschemad911's suggestion, so each change is independently reviewable rather than one oversized PR. Every file here is unchanged from #3220 and has been hardware-tested on the affected devices; that PR itemizes every change and carries the full test record. Authorship and sign-offs are carried in the patch files themselves.

Testing

  • Kernel patches (001/002/005) validated on an RG353M, reading kernel values over SSH rather than the UI.
  • This is v4 of the fuel gauge work, simplified after Chris's review — the boot ladder was reduced to counter-first and FG_INIT dropped.
  • voltage_ocv semantics confirmed on hardware by @macromorgan; suspend/resume confirmed under Rockchip BL31.
  • Sleep-blindness, the dead relax gate, invisible CHARGE_FINISH and the reboot-at-full re-anchor were each measured directly.
  • Off-charge test: saved at 74% and charged 1.5 hours powered off, the RG353M booted with the counter at full — which is what disproved the earlier v3 premise that the counter cannot count while powered off.
  • Patches apply at strict zero fuzz (-F0) to both consumer kernels of the shared Rockchip tree (7.0.2 RK3566/76, 7.1.2 RK3326).
  • Full test record is in RK3326/RK3566: battery, SD card and suspend/resume fixes #3220, where this was developed; the files here are unchanged from it.

Additional Context


AI Usage

Did you use AI tools to help write this code? PARTIALLY

Three rk817 patches.
001 and 002 are Chris Morgan's, 002 co-developed; 005 is mine. All
carry their authorship in the patch files.

001, NVRAM soc misread: the stored value runs 0..100000 but the bounds
check truncates at 10000, so a full battery reads back as 10%.

002, boot soc resolved from the counter: the boot value comes from
PWRON_VOL when OFF_CNT reads three or more and from the columb counter
otherwise, and both fail in the field. PWRON_VOL samples at the
power-on instant, so a power-on caused by plugging in a charger samples
under charge current - on an RG353M it read above the pack's maximum
design voltage while the pack sat at 74%. A negative counter was
clamped to zero and reported 0%. The counter keeps counting while the
system is off, so resolve from it first.

005, gauge corrected across sleep: the counter is erratic while the
system sleeps - one 15 minute sleep registered 69% of the metered
charge and another 139%. The signals that could correct it are gone by
the time the driver runs again: RELAX_STS clears once the wakeup load
exceeds the relax threshold, and CHARGE_FINISH disappears while the
charger re-detects its input. Stamp boottime, charge, current and
charging state at suspend, and recompute from that evidence at resume.

Split out of ROCKNIX#3220.
On an RG353M a sleep dropped the charge from 90% to 70%, both following
reboots came up at about 40%, and a gauge reset restored 70%. The
counter was wrong, but nothing records whether it went wrong in the
sleep or across the reboot. Log the counter, saved soc, fcc and battery
voltage at boot, and at resume the counter before and after the sleep
with the battery and relax voltages, as the BSP logs its saved and
present capacity at boot.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNwUueUVhNqodU1izyxqAK
beebono pushed a commit to beebono/distribution that referenced this pull request Sep 15, 2026
The GKD Pixel2 battery script shut the device down when the gauge
read 0 %. The rk817 gauge can read 0 % erroneously (a false boot value,
recoverable only with 'factoryreset rk817-fuelgauge'), and then the
script powers the device off on every boot: a boot loop, from tying the
safety cutoff to the very number it is meant to guard against. The
gauge can equally stick high while the pack is genuinely empty and
never cut off at all.

Compare voltage_avg against the dts cutoff (voltage-min-design, 3.4 V)
instead, both read at runtime, and require six consecutive samples
below it (3 s at the 0.5 s loop cadence) so momentary load sag does
not trigger it. Unreadable voltage counts as empty so a sysfs failure
cannot disable the protection. LED colours are unchanged.

Split out of ROCKNIX#3305.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNwUueUVhNqodU1izyxqAK
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

Successfully merging this pull request may close these issues.

1 participant