- LBC supervisor v1..v4 (linux/patches/b10b3-lbc-supervisor-v3.patch + b10/b10b3/lbc-v3-to-v4-fault-clamp.diff): CHARGING 4.20 V/450 mA -> HOLD 4.05 V after 60 min CV -> battery -> new cycle on USB insert; FAULT = VDD_MAX 4.00 V clamp - RAM tests C/B/D/D2/D3/D4 (safety timer only ends fast charge), B10B-4 actuator audit (VDD_MAX works, USB_SUSP does not), B10B-5 FAULT clamp regression, production run, warm reboot via PON reboot reason - cache = B10B-5 c3732515 (HW EDL write, readback + full partition verify), class-A persistent validation - test-only hooks/images are not part of the production kernel; images with the AP PSK are not published
14 KiB
B10A-RESULT — battery / charger / power-management audit (read-only)
Date: 2026-10-03. Board: Aurora JZ08AU-XPA-7J-R3, running the operational baseline (aboot lk1st-b9l 15208dbb,
cache B9C b9ce13c9, kernel 7.2.7-aurora-b9c #9), USB connected to 480s, boot = class B (PON_REASON1 = USB_CHG).
Nothing was changed: no build, no eMMC/cache write, no PMIC/regulator/GPIO writes, no ADC conversion trigger, no reboot.
Live data = sysfs/debugfs reads + PM8916 regmap debugfs reads (b10/b10a/b10a-probe.sh, b10a-trend.sh, b10a-pm.sh).
Raw data: b10/b10a/b10a-live1.txt (full dump), b10/b10a/b10a-trend1.txt (30 s trend). Stock sources:
android/power_supply.txt, dt/dtb_01.dts, partitions/{boot,aboot,sbl1}.bin.
Main findings
- Hardware: PM8916 internal linear charger (LBC) + PM8916 VM-BMS (voltage-mode fuel gauge, no coulomb counter).
No external charger/gauge IC (stock DT has no I²C charger/gauge;
CHG_OPTION 0x1008 = 0x80= PMIC charger in use). Upstream Linux 7.2 has drivers for both:CHARGER_PM8916_LBC(qcom,pm8916-lbc) andBATTERY_PM8916_BMS_VM(qcom,pm8916-bms-vm); both nodes exist inpm8916.dtsiwithstatus = "disabled". Neither is built today. - Today nobody manages charging in Linux.
/sys/class/power_supplyis empty, IIO=n (no VADC, no PMIC temp-alarm thermal zone). The charger runs on whatever SBL1/PMIC defaults leave in the registers: CHG_EN = 1, VDD_MAX = 4.200 V, IBAT_MAX = 90 mA (field = 0, the minimum), IBAT_SAFE = 990 mA, safety timer ON (raw 0x1d), battery present, battery temp OK, USBIN valid. - SBL1
batt_voltage≈4.2 Vis not a state-of-charge indicator. With USB present the LBC is in CV at VDD_MAX, so the reading is clamped at ≈4.19–4.20 V. Boots where SBL1 ran before USB was attached (R2 T3C/T4A, R3A: battery first) show 3.99–4.10 V. Stock era (Android charging at 411 mA, SoC 24 %) showed 3.86–3.97 V. The memory note "batt_voltage ~4.2 V, so low charge is not the cause" (R2) therefore rests on a CV-clamped value. - Battery voltage is flat under Linux load: BMS FIFO = 14702±1 LSB over the whole trend, i.e. the charger holds CV. Either the board's load is below what the LBC delivers, or the 90 mA field does not limit total output as assumed. This cannot be resolved read-only (no current sense in VM-BMS) → needs a USB power meter (see next steps).
- USB gadget declares
MaxPower = 2 mA(configfsc.1/MaxPower 2, bmAttributes 0x80). Stock Android reportedusb CURRENT_MAX = 500000. A strict host/hub may limit the port; our board draws far more than 2 mA. - Power management (CPU):
psci_idlecpuidle with WFI +cpu-sleep-0(heavily used), menu governor; cpufreq schedutil 200/400/800/998.4 MHz; all 4 CPUs online; system suspend = s2idle only (not used). Thermal: tsens zones 43–45 °C; no PMIC die-temp zone (needs IIO + spmi-vadc).
Table
| Item | Stock (Android 3.10, stock LK) | Current (lk1st-b9l + Linux 7.2.7-b9c) | Status |
|---|---|---|---|
| Charger HW | PM8916 LBC qcom,qpnp-linear-charger (CHGR 0x1000, BAT_IF 0x1200, USB_CHGPTH 0x1300, MISC 0x1600) |
same HW, no driver (CHARGER_PM8916_LBC not set, DT node disabled) |
Unmanaged (SBL1/PMIC defaults) |
| Charge voltage | vddmax-mv = vddsafe-mv = 4200 |
VDD_MAX 0x08 = 4200 mV, VDD_SAFE 0x08 = 4200 mV | Same |
| Charge current | ibatsafe-ma 1440; thermal mitigation 1440/720/630/0; runtime = min(USB current_max 500, …); Android showed −411.6 mA (charging) |
IBAT_MAX 0x00 = 90 mA; IBAT_SAFE 0x0a = 990 mA | Lower than stock (field decode per upstream driver: 90 mA + 90 mA·n) |
| Input min (VIN_MIN) | vinmin-mv 4308 |
VIN_MIN is 0x1047 = 0x04 = 4308 mV (corrected in B10A-DRIVER-AUDIT; 0x1043 = 0x86 is something else) | Same as stock |
| Safety timer | tchg-mins 232 |
TCHG_MAX_EN 0x80, TCHG_MAX raw 0x1d | Enabled (value differs) |
| Temperature (JEITA) | cool 10.0 °C / warm 45.0 °C; 4100 mV + 360 mA in cool/warm; hot 25 % / cold 80 % BTC thresholds | BAT_IF RT temp_ok = 1; BTC regs 0x1248–0x124a = 0a 81 c0 | HW BTC active, no SW JEITA |
| Battery presence | batt-pres IRQ |
BAT_IF 0x1208 = 0x83 (present), RT bat_pres = 1 | OK |
| Termination / resume | chg-term-ua 100 mA, resume-soc 99 %, report-charger-eoc |
CHGR RT: chg_done 0, fast_chg 0, vbat_det_lo 1; CHG_STATUS 0x1009 = 0x03 | Open (no SW EOC/resume logic) |
| Fuel gauge | qcom,qpnp-vm-bms + userspace vm_bms daemon; battery palladium_1500mah (generic Qualcomm MTP profile, batt-id 75 kΩ), cutoff 3.4 V, max 4.2 V |
VM-BMS HW enabled (EN 0x4046 = 0x80, MODE 0x0a normal, FIFO len 5, S1/S2 10/7); no driver | No SoC in Linux |
| VBAT (BMS FIFO) | — | raw 14702 (stable); upstream ×300 µV ⇒ 4.41 V (implausible, > VDD_MAX); if CV = 4.200 V ⇒ ≈285.7 µV/LSB | Scale unverified (hypothesis; needs a reference) |
| BMS OCV reg (0x406a) | — | raw 0x37ff = 14335 (low byte 0xff suspicious) ⇒ 4.30 V (×300) / 4.095 V (×285.7) | Unreliable |
| VADC | qcom,qpnp-vadc with vbat_sns, vph_pwr, usb_in, die/chg temp, batt_therm, batt_id, xo_therm, pa_therm0 |
IIO=n; last conversion left by SBL1: CH 0x06 (VBAT_SNS) data 0x9826 | No ADC in Linux |
| USB/VBUS detect | msm_otg + usbin_valid IRQ |
extcon usb-detect@1300 USB=1; USB_CHGPTH RT usbin_valid = 1, coarse_det = 1; UDC configured, high-speed |
OK |
| USB current declared | power_supply usb CURRENT_MAX 500 mA | gadget MaxPower 2 mA | Mismatch |
| Charger mode boot | stock LK: cold boot + PON USB_CHG + no KPDPWR ⇒ androidboot.mode=charger ⇒ /charger + healthd -n + vm_bms |
lk1st boots Linux unconditionally (no charger-screen); B9L splash | Different by design |
| SBL1 | pm_sbl_chg (CHG_App_LUT, VBATT/USB_IN/BATT_ID/BATT_THERM), prints batt_voltage |
same SBL1 (unchanged) | Reference |
| PON / power-off | — | PON_REASON1 0x10 (USB_CHG), POFF2 0x80d = 0x20 (UVLO, latched after power cuts — see R2) | Known |
| Coin cell (0x2800) | — | COIN EN 0x2846 = 0x80, VSET 0x01, RSET 0x00 | Enabled; presence of a backup cell unknown (RTC resets on class A ⇒ probably none) |
| CPU idle/freq | — | psci_idle WFI + cpu-sleep-0, schedutil 200–998 MHz | OK |
| Thermal | pm8916_tz, bms, battery, tsens |
tsens only (5 zones, 43–45 °C) | PMIC/battery temp missing |
SBL1 batt_voltage history (from logs/uart)
| Period | Chain / power-on | batt_voltage (mV) |
|---|---|---|
| 2026-09-29 | stock chain, Android charging 411 mA | 3857–3975 |
| 2026-09-30 → 10-03 | lk1st + Linux, USB present at SBL1 | 4147–4202 (mostly 4186–4201) |
| 2026-10-02 R2 T3C/T4A, R3A | battery first, USB later (class A tests) | 3990–4101 |
Open questions (need the operator)
- Battery: real capacity/chemistry/label (stock DT profile is the generic
palladium_1500mah); is there a thermistor (BAT_IF temp_ok = 1 suggests BTC sees a valid value) and a batt-id resistor? - Actual current from USB: a USB power meter between 480s and the board (idle LTE, LTE traffic, Wi-Fi AP) would show whether the board is net-charging or discharging with IBAT_MAX = 90 mA.
- VBAT reference: one multimeter reading on the battery terminals would calibrate the BMS FIFO scale.
Next step (proposal, needs GO)
B10B (RAM-only, like B8B/B9B): kernel = b9c + IIO + QCOM_SPMI_VADC + QCOM_SPMI_TEMP_ALARM + BATTERY_PM8916_BMS_VM
CHARGER_PM8916_LBC; DT enablespm8916_bms/pm8916_chargerwith a conservativemonitored-battery(4.2 V, constant-charge current ≤ 500 mA, safe values from stock DT) andpm8916_vadc. Note: the LBC driver writes VDD_MAX/IBAT_MAX/TCHG at probe — that is a PMIC write and needs its own GO; an even safer first step is B10B-0 = VADC + temp-alarm + BMS only (BMS probe also writes its FIFO/interval/EN registers), charger untouched. USB gadget MaxPower → 500 mA is a separate tiny change for the next image.
Incident during the audit: board died at uptime ≈2148.7 s — RESOLVED: operator unplugged USB to insert a USB power meter
- UART (
logs/uart/b9l-bootcold1-20261003-020146.rawon 480s, tail saved asb10/b10a/b10a-death-uart-tail.txt) stops mid-line at 02:38:11 MSK (board epoch 1790984291), inside normal ModemManager debug output. No panic/oops/thermal/reset text, no SBL1 restart afterwards → abrupt power loss or a hard hang, not a kernel crash with a message. - USB NCM (18d1:d001) disappeared from 480s at the same time; no re-enumeration (no SBL/lk/fastboot) afterwards.
- The read-only trend was sleeping at that moment: last register read ≈uptime 2129 s, next due ≈2159 s (death ≈20 s after a read). The same reads had run 11 times before, and a full 3328-register dump earlier. The reads are therefore an unlikely cause, but it cannot be fully excluded.
- Only 3 of the 12 trend samples survived (the rest were in board RAM). Logger on 480s still running.
- Fits the open "flaky battery contact / UVLO" issue (R2, B9C cold1 "battery dropped") and the unmanaged charger state (IBAT_MAX 90 mA). Needs the operator: what does the board show (display/backlight on?), is the battery seated, is USB still powered?
Resolution: the operator confirmed the power loss was intentional (USB unplugged to insert a USB power meter). Not a board fault; the register reads are cleared.
Follow-up with a USB power meter (operator, 2026-10-03 02:45–03:01)
- Boot 02:44 (class A, RTC 3 s): meter 4.90–4.98 V, 0.15–0.20 A idle (LTE + Wi-Fi AP + display); max 0.41 A seen (the 0.024 A "min" was during manual replug; the meter shows max, not min). → 90 mA in IBAT_MAX does NOT cap USB input.
- Boot 02:53 (class B, RTC 533 s), CPU-load test
b10/b10a/b10a-load.sh(20 s idle, 60 s 4×yes, 30 s idle; CPU 998 MHz, tsens 44→71 °C, no throttling): meter stayed at 0.01 A the whole time — the board ran from the battery. BMS FIFO (raw): idle 14554 → load 14324/14308 → recovering 14498 (≈ −65…−70 mV under load at the 285.7 µV/LSB hypothesis). Data:b10a-load3.txt(b10a-load2.txt= same test, debugfs not mounted → no regs). - Register diff vs the first dump (
b10a-live2.txtvsb10a-live1.txt): CHG_STATUS 0x1009 03 → 00, USB_CHGPTH 0x1308 02 → 01, PON 0x807 88→c8, 0x80d 20→00; CHG_CTRL (0x90), IBAT_MAX, VDD_MAX, RT statuses (chg 01, bat 03, usb 03) unchanged; extcon USB=1, UDC configured. → USB is valid and CHG_EN = 1, but the LBC is currently not charging and not supplying the load. Hypothesis (unproven): LBC is in its post-"done"/maintenance state and waits for VBAT to fall below the resume (VBAT_DET) threshold; without a Linux driver nothing restarts charging. Bits of 0x1009/0x1308 are not decoded (no downstream source here).
30-min read-only monitor (03:03:52–03:34, b10/b10a/b10a-mon.sh, data b10a-mon1.txt)
31 samples, 60 s apart, uptime 630→2431 s, idle (LTE + Wi-Fi AP + display), operator watching the meter (≈0.01 A).
- Nothing in the charger changed: CHG_STATUS 0x1009..0x100b =
00 00 43, CHGR RT 0x1010 = 01, CHG_CTRL 0x90, VDD_MAX 0x08, IBAT_MAX 0x00, USB 0x1308/0x1309 =01 90, USB RT 0x1310 = 03, BAT_IF RT 0x1210 = 03 in all 31 samples. OCV reg constant 14376. - BMS FIFO falls linearly: 14530 → 14410 (−120 LSB / 30 min) ≈ −34 mV/30 min (≈ −70 mV/h at 285.7 µV/LSB; scale unverified). No step up, i.e. the LBC did not resume charging by itself within 30 min while VBAT went from ≈4.15 to ≈4.12 V.
- Consequence: in this state the board runs from the battery with USB plugged; it will eventually hit the cutoff/UVLO. Charging was active (meter 0.15–0.20 A) in the 02:02 and 02:44 boots and stopped after the manual replug before the 02:51/02:53 boots. What exactly puts the LBC into this state (replug sequence? charge-done latch?) and what the resume threshold is remains open.
Variant 1: full PMIC reset (operator, 03:57–03:59): charging restored
Operator: USB off, battery out ≥90 s, battery in, then USB through the meter. Boot 03:59:27 = class A (RTC 3 s), SBL1 batt_voltage=4165.
Meter: max 0.41 A while the kernel boots. Registers at uptime 45 s (b10a-classA1.txt): CHG_STATUS 0x1009 = 05, USB 0x1308 = 02 90,
RT 01/03/03, CTRL 0x90, VDD_MAX 0x08, IBAT_MAX 0x00; BMS OCV reg 14090 (≈4.03 V at 285.7 µV/LSB, taken at battery-only power-up).
→ The "stuck, not charging" state lives in the PMIC retained domain: class B boots kept it, a full POR cleared it.
Observed states: 0x1308 = 02 when charging, 01 when stuck (USB valid); 0x1009 = 03 (CV at 4.2 V, boot 02:02), 05 (now, below CV), 00 (stuck). Bit meaning not decoded.
60-min monitor while charging (04:01:08–05:02, b10a-mon2.txt): the LBC stops by itself after the CV phase
| uptime (s) | CHG_STATUS | 0x1308 | FIFO (raw) | meter | phase |
|---|---|---|---|---|---|
| 100–760 | 05 | 02 | 14484 → 14699 rising | ≈0.41 A | CC / input-limited |
| 760–1360 | 05 | 02 | frozen 14685–14699 (no FIFO updates) | — | — |
| 1360–2622 | 03 (sporadic 07/05) | 02 | 14667 → 14683, flat | ≈0.2 A, falling | CV at 4.2 V, taper |
| 2622→2682 (≈04:44, ~45 min after power-on) | 00 | 01 | step 14682 → 14538 (−144), then −4…−5 per min | 0.01 A | charger off, board on battery |
- Nobody touched the board. CHGR RT stayed 01 (no chg_done/chg_fail RT bit), USB RT 03, BAT RT 03, CTRL 0x90 throughout.
- The −144 LSB step is the CV source disappearing (≈ −41 mV at 285.7 µV/LSB); afterwards the same linear discharge as in the 30-min monitor.
- Conclusion: after the CV taper the LBC ends the charge cycle autonomously (charge-done/termination) and switches the whole USB path off, so the load moves to the battery. The 0x1009=00 / 0x1308=01 state from the 03:03 monitor is this same post-termination state, not a replug artefact. With no Linux driver nothing re-enables charging; in the 30-min monitor VBAT fell ≈30 mV without any hardware resume. Hypothesis: the downstream qpnp-linear-charger handled resume in software (vbat-det-lo IRQ → re-enable), so on stock the charger was restarted by the kernel. To be checked against the downstream source and the upstream pm8916_lbc before B10B.
- Charge cycle: from class-A power-on (OCV ≈4.03 V) to termination ≈45 min.