# B10B3-EOC-AUDIT — what CHG_STATUS 00 / USB path 01 really is (read-only/offline) Date: 2026-10-03. No PMIC writes, nothing built or loaded. Sources: b10/b10a/b10a-live1/live2/mon1/mon2, logs/b10/b10b3/baseline-b9c-classA.txt, t1-mon.txt, t1-final-state.txt, ram1-*, B10B-0/1/2 logs, operator meter notes; downstream qpnp-linear-charger.c (LBC), qpnp-charger.c (SMBB), qpnp-vm-bms.c @7f1748ce; LK pm8x41; upstream pm8916_lbc. (BD = MISC BOOT_DONE 0x1642 bit7.) ## 1. All observed 00/01 events and long charges | # | boot / mode | start of charge | 00/01 observed | time to 00/01 | VBAT at the stop | context | |---|---|---|---|---|---|---| | A | cache B9C-era, class A, **BD=0**, IBAT field 90 mA | SBL1 03:59:27 | between uptime 2622 and 2682 s | **43.7–44.7 min** | ≈4.176 V (FIFO 14683 ×284.4 µV), after ≈22 min in CV (CHG_STATUS 03/07) | B10A 60-min monitor; meter 0.2 A → 0.01 A | | B | cache, class A 02:42/02:44, **BD=0** | ≈02:42–02:44 | stuck at 02:53 boot (meter 0.01 A from ≈02:55) | ≤ ≈13 min | battery near full (≈4.14 V after relaxation) | **confounded**: USB replug ≈02:50 + class-B reboot 02:51 + power-off 02:53 | | C | cache B9C today, class A, **BD=0** | 14:39:20 | already 00/01 at uptime 3278 s | **≤ 54.6 min** (exact unknown) | **≈3.83 V** (FIFO 13458–13463, on battery) — far from full | baseline before B10B-3 ram1; ram1 probe saw 3.81 V | | D | RAM fastboot, **BD=1**, IBAT_MAX 450 mA, VDD_MAX 4.00 V (B10B-3T t1) | probe ≈15:59 | **never** | > 95 min incl. **≈80 min CV** at 4.00 V | VADC 3.986–3.994 V (CV), input 0.19–0.22 A, Wi-Fi off last 15 min: 0.149 A | test stopped (no EOC) | | E | RAM fastboot, BD=1, IBAT 90 mA (B10B-0 ram1) | 05:32 | not observed (battery fell to 3.7 V in 7.7 h; never reached CV) | — | — | no regs logged at the end | | F | RAM fastboot, BD=1, 450 mA (B10B-2, B10B-3 ram1) | — | never (11 / 7 min runs) | — | — | — | ## 2. Register picture (CHGR/USB/MISC, only the differing registers) | reg | A charging (CV, BD0) | A stopped (BD0, ≈4.14 V) | C stopped (BD0, 3.83 V) | D CV (BD1, 4.00 V) | |---|---|---|---|---| | 0x1009 CHG_STATUS | 03 | **00** | **00** | 03 | | 0x100b | 43 | 43 | **03** | 43 | | 0x1010 CHGR RT | 01 | 01 | **00** | 21 | | 0x1308 USB path | 02 | **01** | **01** | 02 | | 0x1044/45/49/61 | 00/0a/90/1d | same | same | 04/04/a0/7f (driver) | Unchanged in all four: 0x1040 VDD_MAX, 0x1041, 0x1047 VIN_MIN, 0x104a CHG_FAILED 00, **0x105b 09**, 0x1060 80, 0x10ee 00, 0x1309 90, 0x1310 03, **0x134e 00, 0x134f 03**, BAT_IF. CHG_FAILED was never set → none of the stops was the CHG safety timer (SBL: 120 min) as recorded by hardware. VBAT_DET-like comparator: CHGR RT bit0 together with 0x100b bit6 is 1 at VBAT ≥ ≈3.93 V and 0 at ≤ ≈3.90 V (VADC; B10B-0/2/3 samples 3.75–3.82 V → 0, 3.927–4.2 V → 1). In C the charger stayed off at 3.83 V with this bit = 0 → **no autonomous VBAT_DET recharge in hardware**. ## 3. Source facts - Downstream LBC probe: writes **BOOT_DONE**, and when USB is present writes **USB_ENUM_T_STOP (0x134E) = 0x00** ("enum stop"); disables HW iterm (0x105B bit3 = 0) unless `charger-detect-eoc`; VBAT_DET override 0; charger WDOG off. EOC on stock = BMS SOC 100 → software. - Downstream SMBB (PM8941): `ENUM_T_STOP_BIT = BIT(0)` of 0x4E, set to **1** to stop the USB enumeration timer. The LBC semantics of 0x134E are not documented (downstream writes 0, the register reads 00 here) → cannot decide from source whether the enum timer runs. - LK (lk1st/lk2nd, stock-derived): no LBC charging/enum code; sets BOOT_DONE only in fastboot (`target_fastboot_init`). - Upstream pm8916_lbc: sets neither BOOT_DONE nor ENUM_T_STOP, does not touch 0x105B. - 0x105B = 0x09: bit3 = iterm comparator enable (downstream mask); bits 2:0 = 1 → presumably the iterm threshold code (value not documented). ## 4. Conclusions 1. **00/01 is not proven to be hardware end of charge.** Case C proves that 00/01 also occurs with a clearly non-full battery (≈3.83 V, below the VBAT_DET-like comparator). So 00/01 = "charger latched off", cause not unique. 2. The only BD=0 stops with a known time (A: 43.7–44.7 min; C: ≤ 54.6 min) are consistent with a **≈45-min stop in the BOOT_DONE = 0 (pre-software) mode** — e.g. a USB-enumeration / boot-charging timeout — independent of VBAT. A fell inside a CV phase, so A alone could also be a real EOC; C cannot. B is confounded by replug/reboots. This is a hypothesis with 2 data points; not proven. 3. With **BOOT_DONE = 1** (the state any Linux driver should create, as downstream does) no stop occurred in > 95 min including ≈80 min CV at 4.00 V, with or without Wi-Fi. Either the HW iterm EOC does not fire while the modem draws ≈0.15–0.2 A (LBC has no separate battery-current sense; VPH = VBAT), or its threshold is far lower than reached in 80 min. **A genuine current-based EOC has not been observed at all.** 4. Verified levers: VDD_MAX programming (charger regulated at 4.00 V and 4.20 V), IBAT_MAX (90 vs 450 mA), CHG_EN 0→1 edge releases a 00/01 latch, timer programming/readback. **Not a lever:** CHG_EN = 0 does not stop the charger. 5. Therefore 00/01 must not be used as the production TERMINATED criterion (agreed), and a recharge state machine built on a hardware EOC that does not occur in BD=1 mode would never leave CHARGING. ## 5. Proposal: new end-of-charge criterion / B10B-3 design update (for decision, nothing built) Principle: do not depend on an undocumented hardware EOC; control the float voltage, which is a verified lever. - Driver sets **BOOT_DONE** at probe (as downstream) so the ≈45-min BD=0 stop (hypothesis) cannot occur in production; keep IBAT_MAX 450 mA. - **Two-level VDD_MAX state machine (software EOC by CV time, stop by lowering the float):** - CHARGING: VDD_MAX 4.20 V. When CHG_STATUS shows the CV loop (bit1) continuously for T_cv (proposal 60 min, with VADC VBAT ≥ 4.15 V) → FULL. - FULL/FLOAT: program **VDD_MAX = 4.05 V** (0x02). The charger stops pushing current into the battery while VBAT > 4.05 V; the modem load drains it to 4.05 V; then the charger holds 4.05 V and powers the board from USB. No reliance on 00/01, no CHG_EN tricks. - Re-top-up (optional): after N hours in FLOAT or if VBAT < 4.00 V for 3×30 s (shouldn't happen while USB is valid) → back to 4.20 V CHARGING. - Simplest variant to consider: permanent float at 4.05–4.10 V (no top-up cycles at all) — closest to "battery not kept at 4.20 V". - Disable the HW iterm comparator (0x105B bit3 = 0, as stock) only if it is shown to latch in BD=1 mode — currently it never fired; leave as is. - Safety timer: must be checked against a long CV/float — if the timer counts CV time, a 512-min expiry would stop float charging after 8.5 h (→ board on battery). Needs a test (test-only DTB with a short timeout, e.g. 8 min, while in CV) before deciding: either re-arm on every CHARGING↔FLOAT transition or keep FAULT-latch. - Keep 00/01 only as a diagnostic: if it appears (e.g. BD=0 timer), log it and restart with the verified edge. - Tests needed (each RAM-only, separate GO): T-a: class-A **cache** boot (BD=0), meter + read-only logging, start VBAT ≈3.8–3.9 V → does 00/01 come at ≈45 min independent of VBAT? (timer proof) T-b: RAM BD=1 with a 8-min test timeout while in CV → does the safety timer expire in CV (CHG_FAILED)? T-c: RAM BD=1, battery in CV at the higher level, program a lower VDD_MAX (e.g. 4.20 → 4.05) → expected: USB input drops to ≈0.01 A (board on battery, VBAT falls), then rises to the board load (~0.15–0.2 A) once VBAT reaches the new float and the charger holds it.