# B10B3-DESIGN — charger supervisor + safety timer > **Current design = section 8 (v3, CHARGE → HOLD → BATTERY → CHARGE).** Sections 2–7 (recharge-threshold model, v1/v2) are > superseded and kept only as history; their production values (recharge 4.05 V, TERMINATED = 00/01) are withdrawn. Date: 2026-10-03. Starting point (class A, SBL1 defaults, verified): IBAT_MAX 00 (90 mA), IBAT_SAFE 0a, CHG_CTRL 90, TCHG 80/1d (on, 120 min), VDD_MAX/SAFE 08 (4.20 V), IBATTERM 0x105B 09 (HW termination on), COMP_OVR1 00, BOOT_DONE 00. ## 1. What stock did (facts from downstream source/binding @7f1748ce and stock DT dtb_01) - Stock DT: `qcom,resume-soc = <99>`, no `charger-detect-eoc`, no `disable-vbatdet-based-recharge`, `tchg-mins = <232>`. - Recharge paths (all software): (a) SOC ≤ resume-soc (99 %) while USB present → CHG_EN; (b) VBAT_DET_LO IRQ → CHG_EN; (c) USB insert → CHG_EN (with VBAT_DET override so it charges even above VBAT_DET). - (a) needs the stock VM-BMS SOC. Translated through the stock (generic MTP "palladium_1500mah") OCV table at 25 °C: 100 % = 4167 mV, 95 % = 4112 mV → **99 % ≈ 4.156 V OCV**. That keeps the cell practically always near 4.2 V → **rejected** per your constraint. - (b) The LBC VBAT_DET level is not programmed by the stock driver and is not documented for PM8916 LBC (0x105D, the SMBB VBAT_DET register in LK, reads 00 here). Its threshold is unknown → cannot be adopted as a number. - EOC on stock was BMS-decided (HW iterm disabled). Disable = CHG_CTRL masked (bit7|bit0) → FORCE_BATT_ON (0x01); enable → CHG_ENABLE (0x80). ## 2. Proposed recharge threshold (voltage-based, VADC VBAT under load) Our facts: post-termination idle discharge on battery ≈ 70 mV/h (B10A); VADC VBAT σ ≈ 5–7 mV, LTE TX dips up to ≈ 30 mV; load ≈ 0.15–0.2 A → loaded VBAT ≈ OCV − 30…40 mV (R ≈ 0.2 Ω, estimate). | option | loaded VBAT restart | ≈ OCV | ≈ SOC on the stock generic table | time on battery after termination | |---|---|---|---|---| | A | 4.10 V | ≈ 4.13–4.14 V | ≈ 96–97 % | ≈ 0.5–1 h — close to "always near 4.2 V" | | **B (recommended)** | **4.05 V** | ≈ 4.08–4.09 V | ≈ 90–91 % | ≈ 1.5–2 h | | C | 4.00 V | ≈ 4.03–4.04 V | ≈ 83–85 % | ≈ 2.5–3 h | Hysteresis: termination happens at the 4.20 V CV point (HW iterm); restart only after VBAT < threshold in **3 consecutive 30 s samples** (filters TX dips). Gap 4.20 → 4.05 V = 150 mV. The generic-table SOC column is indicative only (real cell curve unknown). ## 3. Safety timer Upstream probe writes TCHG_MAX_EN 0x1060 = 0x00 (timer off). Patch: program it like downstream `qpnp_lbc_tchg_max_set()`: 0x1060 bit7 ← 0, **0x1061 TCHG_MAX ← minutes/4 − 1**, 0x1060 bit7 ← 1. Encoding: 4…512 min in 4-min steps. | value | 0x1061 | note | |---|---|---| | SBL default | 0x1d | 120 min | | stock DT | 0x39 | 232 min | | **proposed** | **0x7f** | **512 min = 8 h 32 min (hardware maximum)** | Why max: at 450 mA input minus ~0.15–0.2 A board load the cell gets ≈ 0.25–0.3 A; a deep charge of a 3000 mAh cell needs > 8.5 h, so a shorter timer would trip mid-charge. Recharge cycles (150 mV) take well under 1 h. Expiry → CHG_FAILED (0x104A bit7). Proposed policy: supervisor goes to **FAULT**, charger disabled, logged; **no automatic restart** (stock cleared CHG_FAILED automatically — not copied). FAULT is left only by USB re-insert or reboot. (Alternative for approval: one automatic re-arm if VBAT < 4.0 V, then FAULT.) Unverified: whether a CHG_EN 0→1 edge restarts the timer count (expected; will be logged). ## 4. Implementation (kernel only, no userspace register access) - `qcom-spmi-vadc.c`: VBAT_SNS `VADC_CHAN_NO_SCALE(VBAT_SNS, 1)` → `VADC_CHAN_VOLT(VBAT_SNS, 1, SCALE_DEFAULT)` (same as VSYS) → `in_voltage6_input` processed with the driver's own calibration (= the B10B-0 manual formula). - `pm8916_lbc.c`: - IIO consumer `io-channels = <&pm8916_vadc VADC_VBAT_SNS>`, `io-channel-names = "vbat"`. - threshold from simple-battery `re-charge-voltage-microvolt` (standard battery.yaml property; this kernel's core does not parse it into `charge_restart_voltage_uv`, so the driver reads it from the monitored-battery node itself). - timer from new DT `qcom,charge-timeout-minutes` (default 512 if absent), programmed as in §3; no more TCHG_MAX_EN = 0. - state machine in a delayed_work (30 s) + kicks from the existing usb_vbus IRQ: - **NO_USB**: USBIN not valid. On removal: charger disabled (stock-style 0x01). - **CHARGING**: CHG_CTRL 0xA0 (upstream value). If CHG_STATUS == 00 ∧ USB path 0x1308 == 01 ∧ USB valid for 2 polls (= the state observed after real HW termination in B10A) → **TERMINATED**. - **TERMINATED**: write disable (CHG_EN 0, FORCE_BATT_ON 1, as stock) so restart is a clean edge; poll VBAT; 3 × below threshold → **RECHARGE** = write 0xA0 → CHARGING. - **FAULT**: CHG_FAILED or VBAT > 4.25 V (defence) → disabled until USB re-insert/reboot. - USB insert (and probe with USB present): always enable (edge 0→1) → CHARGING, like stock's usbin path. A class-B reboot therefore never leaves the board on battery with USB present; the cost is one top-off per boot/insert. - observability: charger psy `status` (Charging / Not charging / Full) + `/sys/kernel/debug/pm8916_lbc/state` (state, VBAT, regs, counters, transitions) for the logger. - **test-only hook (RAM image only, debugfs)**: `force_terminate` (supervisor performs its normal TERMINATED action) and `recharge_threshold_uv` override. Not a register poke; removed/disabled for persistent integration. - DT (b10b2 + ): charger `io-channels`, `qcom,charge-timeout-minutes = <512>`; battery `re-charge-voltage-microvolt = `. ## 5. Test plan (RAM only, class A, USB meter in line, logger on 480s every 30 s) Battery now ≈ 3.85 V, i.e. below every production threshold, and reaching a real termination needs hours. Therefore: - Test 1/2 (recharge state machine, 2+ cycles): `force_terminate` at the current VBAT; set the **test** threshold to VBAT_at_terminate − 20 mV (debugfs override, documented as test value); real discharge under controlled load (4×`yes`, ≈ 0.4 A) until VBAT < test threshold → automatic restart without any command at that moment. Repeat ≥ 2×. Checks: meter, VADC VBAT, CHG_STATUS, CHG_CTRL, USB path, RT, temps. - USB unplug → insert in TERMINATED and in CHARGING. - class-B reboot from TERMINATED: `reboot` from the RAM image with RESET held → lk1st fastboot → same image again; supervisor must come up CHARGING (or TERMINATED→RECHARGE), never "USB present, charger off, no supervision". (Warm reboots occasionally hang in SBL — R2.) - Real HW termination: only if it happens naturally; reported separately. The production threshold is not exercised by Test 1/2 (battery below it) — reported as such. - Abort: logger ALERT VBAT > 4.22 V or PMIC > 60 °C (operator pulls USB), driver FAULT > 4.25 V, unexpected register diff, USB/LTE/Wi-Fi instability. ## 6. Decisions (operator, 2026-10-03) and build status - Production recharge threshold **4.05 V VADC VBAT**, 3 consecutive samples, 30 s period; no decisions from BMS-VM voltage. - Safety timer **512 min**, timeout → latched FAULT, charging off, no automatic restart; exit only USB remove/insert or reboot. - Test-only threshold current_VBAT − 20 mV via debugfs `test_recharge_uv` (RAM image only; not in DT/production config). - **Open item before persistent integration:** one real hardware termination → VBAT drop → CHG_EN 0→1 → real recharge (force_terminate proves the state machine, not the release of the hardware termination latch). - Built, NOT loaded: patch `linux/patches/b10b3-lbc-recharge-supervisor.patch` (sha256 499a45c4…), tree src-b10b3 (hardlinked copy of src with private copies of the 2 patched files), kernel `7.2.7-aurora-b10b3` (full build, no warnings), DTB `linux/dts/msm8916-jz08-aurora-b10b3.dts`, image `b10/b10b3/out/aurora-b10b3.img` c3c885d5 (`build-b10b3.sh`). - Note: upstream pm8916_lbc defines an unused `PM8916_LBC_CHGR_MAX_TIME 256`; downstream (Qualcomm) uses TCHG_MAX mask bits 6:0, max 512 min. The driver reads TCHG_MAX back after programming 0x7f and fails probe on mismatch (timer is re-enabled before the readback). ## 7. ram1 result and REDESIGN v2 (2026-10-03) ram1 (class-B warm reboot from B9C in its natural stop latch, RESET held → lk1st fastboot → b10b3 v1): - probe: timer 512 min (TCHG_MAX readback 0x7f, EN 80), threshold 4.05 V; **the probe restart edge CHG_CTRL 0x21 → 0xa0 released the latch that B9C had reached by itself** (CHG_STATUS 00 → 05, USB path 01 → 02, FAST_CHG_ON). Note: that B9C latch occurred at VBAT ≈ 3.81 V (not a full battery), in the non-BOOT_DONE mode — cause unknown. - USB meter 0.357 A charging. `force_terminate` wrote CHG_CTRL 0x21 (CHG_EN 0 + FORCE_BATT_ON): **meter stayed 0.358 A**, CHG_STATUS stayed 05, FAST_CHG_ON cleared, USB path 01, VBAT not falling (3.89 → 3.92 V). → **CHG_EN = 0 does not stop the charger** on this board/mode. Test stopped (unexpected charger state). Logs: ram1-mon.txt, ram1-actions.txt, ram1-final-state.txt, ram1/. Redesign v2 (operator decision; diff `b10/b10b3/lbc-v1-to-v2.diff`, full patch `linux/patches/b10b3-lbc-recharge-supervisor.patch` sha256 24c6c0d7…): - TERMINATED only from CHARGING when CHG_STATUS == 00 ∧ USB path bit1 == 0 for 2 polls (= the hardware end-of-charge latch). **No CHG_CTRL write on entering TERMINATED**, none on USB removal, none on FAULT. - recharge: after 3 × 30 s VADC VBAT < re-charge-voltage-microvolt → the verified sequence 0x21 → 20 ms → 0xa0. - USB insert / probe with USB: same verified sequence (+ CHG_FAILED clear). - FAULT (CHG_FAILED = safety-timer expiry, or VBAT > 4.25 V defence): latched, no restart, **no register write** (the hardware timer itself stops charging; there is no verified software stop). Exit only USB re-insert or reboot. - test hooks removed (no force_terminate, no test_recharge_uv); debugfs `state` read-only only. - accelerated test = separate TEST-ONLY DTB `msm8916-jz08-aurora-b10b3t.dts`: battery voltage-max-design **4.00 V** → VDD_MAX 0x00 (lowest LBC step: 4000 + 25 mV·n; 3.95 V not supported), re-charge **3.94 V**. Image `b10/b10b3/out-t/aurora-b10b3t.img` dfe2fae6. - production unchanged: DTB `msm8916-jz08-aurora-b10b3.dts` 4.20 V / 4.05 V / 450 mA / 512 min, image `b10/b10b3/out/aurora-b10b3.img` 5ba4d715 (same kernel as the test image). - Known gap: no verified way to *stop* charging from software (only the hardware latch and the hardware timer stop it). ## 8. DESIGN v3 — CHARGE → HOLD → BATTERY → CHARGE (operator decision 2026-10-03; nothing built) ### 8.1 Use case and facts it rests on Modem runs ≈4 h on battery, is then plugged into USB and must fully recharge; sometimes it stays on USB for a long time. Facts (B10A, B10B-2, B10B-3 ram1/t1, EOC audit): 00/01 is a latch, not an EOC (seen at 3.83 V and ≈45 min after class A with BOOT_DONE=0); with BOOT_DONE=1 no hardware EOC in ≈80 min CV; CHG_EN = 0 does not stop charging; verified levers = VDD_MAX, IBAT_MAX, CHG_EN 0→1 edge (releases 00/01), timer programming. Battery 3000 mAh, 3.8 V nominal, 4.35 V max (B10 capped at 4.20 V). **Withdrawn:** 00/01 as FULL/TERMINATED; recharge threshold 4.05 V; automatic discharge/recharge cycles; force_terminate. ### 8.2 States | state | registers written on entry | behaviour | |---|---|---| | NO_USB | **none** | board on battery; charger not touched | | CHARGING | on entry from NO_USB/probe: BOOT_DONE 0x1642 ← 0x80; VDD_MAX ← charge level (4.20 V = 0x08); IBAT_MAX checked/← 450 mA (0x04); verified restart CHG_CTRL 0x21 → 20 ms → 0xa0 (+ CHG_FAILED clear) | full charge cycle to 4.20 V on every USB insert | | HOLD | **only VDD_MAX ← hold level (4.05 V = 0x02)**; IBAT_MAX, CHG_CTRL, timer untouched | long stay on USB; VBAT goes down to ≈4.05 V, the USB path stays working and USB powers the board (meter ≈ board load 0.15–0.20 A on the shelf); no discharge/recharge cycles | | FAULT | **none** (logical only) | no restarts; dev_crit log; physical stop = **open blocker** | Transitions (poll 30 s + usb_vbus IRQ kick; all decisions on calibrated VADC VBAT, never on BMS-VM): - any → NO_USB: USBIN not valid (no write). - NO_USB/probe → CHARGING: USBIN valid (entry writes above). - CHARGING → HOLD: **CV criterion** held continuously for `cv-hold-minutes` (RAM test 1: 60 min; configurable, not final): per poll "in CV" = CHG_STATUS bit1 (VDD loop) set **and** VADC VBAT ≥ `full-min-voltage` (4.15 V). Because the LBC interleaves 05/07 with 03 during CV (B10A, t1), a single poll without bit1 does not reset the timer; **two consecutive** polls without bit1, or any poll with VBAT < 4.15 V, reset it. - CHARGING, 00/01 latch seen (2 polls): **not FULL** — log "latch in CHARGING", verified restart edge, stay CHARGING (counter n_latch). - HOLD → NO_USB on USB removal; NO_USB → CHARGING on insert (VDD_MAX back to 4.20 V + restart) → after hours on battery every insert recharges fully. - HOLD, 00/01 latch seen (USB valid, 2 polls): **verified restart edge 0x21 → 20 ms → 0xa0, VDD_MAX stays at the hold level, stay HOLD**, event logged (correction 2, 2026-10-03): with USB present the board must not silently move to battery. - CHARGING/HOLD → FAULT: VADC VBAT > 4.25 V, or CHG_FAILED (timer) — logical latch, restart forbidden, loud log. Exit: USB re-insert or reboot. ### 8.3 Parameters (DT, charger node unless noted) | parameter | production | source | |---|---|---| | charge level (VDD_MAX) | 4.20 V | battery `voltage-max-design-microvolt` (existing) | | IBAT_MAX | 450 mA (500 mA request) | `qcom,fast-charge-safe-current` (existing) | | hold level | 4.05 V (0x02) | new `aurora,hold-voltage-microvolt` | | full-min voltage | 4.15 V | new `aurora,full-min-voltage-microvolt` | | CV hold time | 60 min for the first RAM run, **not final** | new `aurora,cv-hold-minutes` | | safety timer | 512 min (unchanged until Test B) | `qcom,charge-timeout-minutes` | | OVP (logical FAULT) | 4.25 V | constant | `re-charge-voltage-microvolt` is no longer used (removed from the production DT in v3). ### 8.4 Open blockers (not hidden) 1. **No verified software emergency stop.** CHG_EN = 0 does not stop the LBC. FAULT is logical only (no restarts) until a physical stop is found and tested (candidates, each needs its own test: VDD_MAX to the 4.00 V minimum, IBAT_MAX to 90 mA, USB_SUSP 0x1347 bit0). 2. **Safety timer in HOLD** (Test B): if the hardware timer counts CV/HOLD time, a long HOLD ends with CHG_FAILED → board on battery. Production timer strategy unchanged (512 min, enabled) until Test B. 3. 60 min CV criterion is a first guess (no current sense, no hardware EOC). ### 8.5 Test C — HOLD mechanism (first, RAM only, separate GO) Goal: prove that lowering VDD_MAX at runtime stops the battery current, lets VBAT fall and then holds the new shelf. - Kernel = v3 driver (states above). **Test-only DTB** (accelerated, the battery is ≈4.0 V now): charge level **4.10 V** (VDD_MAX 0x04), hold level **4.00 V** (0x00, lowest LBC step), full-min **4.05 V**, cv-hold **5 min**, timer 512 min. Production DTB stays 4.20 / 4.05 / 4.15 V / 60 min. - Expected (correction 1, 2026-10-03): CHARGING (meter ≈0.35 A) → CV at 4.10 V (meter falls) → 5 min CV → HOLD: VDD_MAX 04 → 00 → VADC VBAT goes down to the hold level, the USB path stays working (USB valid, no 00/01), and **on the shelf the meter shows the board's own load ≈0.15–0.20 A**. A sustained ≈0.01 A on the shelf = suspected USB-path cut / board on battery → not PASS. Physical note (engineering expectation, to be observed, not a PASS criterion): VPH ≈ VBAT on this board (VADC ch6 vs ch7 differ by a few mV), i.e. no separate power path; while VBAT is still above the new VDD_MAX the charger cannot supply the board without exceeding it, so a transient phase with low USB input during the descent (4.10 → 4.00 V) is expected. It is logged and reported separately. - Log every 30 s: state, VADC VBAT, CHG_STATUS, CHGR/USB/BAT RT, USB path, CHG_CTRL, VDD_MAX, IBAT_MAX, TCHG, CHG_FAILED, BOOT_DONE, temps; meter by operator. - Checks: LTE/Wi-Fi/NCM/display alive, eMMC writes = 0, only the planned registers change (0x1040 on the HOLD transition). - Stop: VADC > 4.15 V (test level 4.10 + margin), PMIC > 60 °C, timer disabled, unexpected register writes. ### 8.6 Test B — safety timer in HOLD (only after Test C PASS, separate GO) Same v3 kernel, test-only DTB as Test C but `qcom,charge-timeout-minutes = 8` and cv-hold 2 min, so HOLD starts well before the timer would expire. Observe across the 8-min mark: TCHG regs, CHG_FAILED, USB path, CHG_STATUS, VADC VBAT, meter, board power. Questions: does the timer count in CV/HOLD; does CHG_FAILED set; does the path switch off; does the board drop to battery; would re-programming the timer on CHARGING → HOLD be safe. STOP after the result. **Run profile (2026-10-03, operator decision, variant A):** the battery is ≈4.00 V after Test C, so 4.10 V would leave ≈22 min of CC and the 8-min timer would expire in CHARGING, not in HOLD. This Test B run therefore uses the accelerated profile **4.05 V charge (VDD_MAX 0x02) / 4.00 V HOLD (0x00) / 4.03 V full-min / 2 min CV / 8 min timer (TCHG_MAX 0x01)**, IBAT_MAX 450 mA, same v3 kernel (driver unchanged). DTB `msm8916-jz08-aurora-b10b3b.dts`, image `b10/b10b3/out-b/aurora-b10b3b.img` 9e66466d (only the DTB differs from Test C). Timeline t = 0 at the driver probe (timer programming, dmesg `safety timer 8 min`). Monitor 10 s, EVDD 02/00, VMAX 4.15 V, PMIC 60 °C abort. Preceded by a verified class-A reset (`pre-testB-classA-check.txt`, `pre-testB-classA-dump.txt`, `pre-testB-vs-baseline-diff.txt`: RTC 3 s, no config register differs from the class-A baseline). ### 8.7 After Tests C and B Update this design (timer strategy, FAULT stop mechanism), then one full RAM run: USB insert → CHARGING 4.20 V/450 mA → CV ≥ 4.15 V for the CV time → HOLD 4.05 V → hours/controlled discharge without USB → USB insert → CHARGING 4.20 V. Persistent cache integration only by a separate GO. ### 8.8 Not doing now 00/01 as FULL; old recharge threshold 4.05 V; recharge cycles in HOLD; 4.35 V; > 450 mA; persistent integration; treating 60 min CV as final; claiming a software emergency stop. ### 8.9 v3 build (2026-10-03, not loaded) - Patch `linux/patches/b10b3-lbc-supervisor-v3.patch` (sha256 b6a74b8c…; spmi-vadc VBAT_SNS scaling + pm8916_lbc v3), v2→v3 diff `b10/b10b3/lbc-v2-to-v3.diff`; tree src-b10b3, kernel `7.2.7-aurora-b10b3` (incremental, no warnings). - Test C image `b10/b10b3/out-c/aurora-b10b3c.img` 5ff9dec0 (DTB `msm8916-jz08-aurora-b10b3c.dts`: 4.10 / 4.00 / 4.05 V / 5 min / 450 mA / 512 min). - Production v3 image `b10/b10b3/out/aurora-b10b3.img` b7dc34e9 (4.20 / 4.05 / 4.15 V / 60 min) — not for loading yet. - Driver changes v2→v3: states NO_USB/CHARGING/HOLD/FAULT; entry to CHARGING writes BOOT_DONE, VDD_MAX(charge), IBAT_MAX (only if different), CHG_FAILED clear, restart edge; HOLD writes only VDD_MAX(hold); 00/01 in CHARGING and HOLD → restart edge (no VDD_MAX change); FAULT logical + dev_crit; constant_charge_current writes only IBAT_MAX (under the supervisor lock, never VDD_MAX/CHG_CTRL); supervisor starts only after probe completed (supv_ready guard against an early usb_vbus IRQ); re-charge threshold and all test hooks removed. ### 8.10 After Test C PASS (2026-10-03, operator-accepted; B10B3-TESTC-RESULT.md) - HOLD works: after the transition VBAT goes to ≈4.00 V (test level), then USB carries the system and takes load steps; no VBAT rise. - Corrected expectation: board consumption on USB in HOLD ≈ **0.03–0.1 A** (not 0.15–0.20 A, which included charge current). - USB path 0x1308 = 01 alone does not mean charging is off; the latch is only **CHG_STATUS 00 + path 01**. - Thermal margin is small: PMIC **57.9 °C** (limit 60 °C) with charging + 4×CPU load → for enclosures/heat a derating is needed (e.g. lower IBAT_MAX above a PMIC temperature, or limit load) — to be designed, not implemented yet. - Cosmetic: debugfs `cv_s` keeps counting in HOLD (cv_since not cleared) — fix in the next build. - Before Test B: full class-A reset (LBC settings survive warm reboots). Test B only with a separate GO. ### 8.11 After Test B (2026-10-04, B10B3-TESTB-RESULT.md) - Variant-A profile (4.05 / 4.00 / 4.03 V, 2 min CV, 8 min timer): HOLD at t = 153.8 s; **no CHG_FAILED in CV/HOLD up to t = 1787 s** (≈ 3.7× timer); the USB path stayed alive after the timer mark (2×CPU load at t ≈ 22–27 min: VBAT held at 4.000 V, USB 0.08–0.10 A). A long HOLD is not ended by the timer → blocker 8.4/2 resolved for production in the observed sense; re-programming the timer on CHARGING → HOLD is **not needed**. - Not proven: that the timer fires at all (CC lasted ≈ 15–30 s; no positive control). The safety timer is not a verified protection; a positive-control test (expiry in a long CC) needs its own GO. FAULT stop (8.4/1) remains open. - Warm reboot with RESET held can end in a PMIC stage-3 reset (POFF_REASON2 STAGE3, RTC near 0) — harmless for RAM tests, note for classification. ### 8.12 After Test D (2026-10-04, B10B3-TESTD-RESULT.md) — NOT PASS / inconclusive - Test C profile + 8-min timer: VBAT reached 4.10 V at ≈ t 300 s (battery more charged than estimated), CV criterion before the mark → by the agreed rule not PASS. But the input current stayed at the CC level (USBIN sag unchanged, meter 0.42 A) until ≈ 8.5 min and **no CHG_FAILED** appeared at t = 480 s or up to t ≈ 843 s. The safety timer has still never been seen to fire (Tests B, D). - Untested explanations: timer counts only in a state with CHGR_RT FAST_CHG_ON (never set on this board), different TCHG_MAX encoding, or restart edge at CHARGING entry. Until a positive control exists, the timer must not be counted as a protection. - A RESET-held warm reboot regularly ends in a PMIC stage-3 reset here (0x080D = 0x80, RTC ≈ 5 s, RESET ≈ 12 s). ### 8.13 Safety timer and the two charge states (2026-10-04; T1DIAG, TESTD2, TESTD3, TESTD4 results) - FAST_CHG_ON (CHGR RT bit5) + USB path 02 = fast charge. Entered at the restart only when VBAT (VADC at INIT) ≤ 3.896 V; at ≥ 3.930 V the LBC charges in a non-fast state (FAST_CHG_ON 0, path 01) — independent of v2/v3 (D3 removed the only write difference; not the cause). - TCHG counts only in fast charge: Test D4 (unchanged Test D image, entry 3.794 V) → FAST_CHG_ON 1→0, path 02→01 exactly at 8 min; **current continued (0.41 A), CHG_FAILED never set (0x104A and RT bit6)**. The timer is therefore **not a charge-stop protection**; charging is bounded only by VDD_MAX regulation (and the HOLD logic). Production 512-min timer stays as is (harmless), but no design element may rely on it. - The supervisor's CHG_FAILED → FAULT path is never triggered by a TCHG expiry on this PMIC; detecting a "timer expired" event would need FAST_CHG_ON 1→0 in CHARGING (diagnostic only). - Open: HOLD → USB removal in v3 (one reset seen from the path-01 state); VBAT_DET threshold not documented (≈ 3.90–3.93 V observed). - 2026-10-04 addendum: USB pull from v3 HOLD — PASS (no reset; heartbeat continuous; HOLD→NO_USB→CHARGING on re-insert). After a fresh USB insertion the LBC entered FAST (path 02) even at 4.02 V, and the HOLD write (VDD_MAX below VBAT) ends FAST immediately (path 01). ### 8.14 Final RAM run (production profile) — B10 charging logic: RAM VALIDATED (2026-10-04, B10B3-RESULT.md) - Production profile 4.20 / 4.05 / 4.15 V / 60 min / 450 mA / 512 min, v3 driver (no D3), RAM only: criteria 1–6 and 8–10 PASS; HOLD shelf 4.033–4.056 V for ≈ 6.3 h, USB 0.1 A on the shelf; USB pull/insert from HOLD PASS; 0 ALERT/latch/FAULT; PMIC max 45.7 °C; eMMC writes 0. - **Warm reboot: PASS with scope limitation.** `reboot(RESTART2, "bootloader")` → lk1st fastboot without RESET (PON 0x88F[7:2]=2), no stage-3, RTC continuous. After a warm (PS_HOLD) reboot SBL re-initialises part of the charger (IBAT_MAX 00, IBAT_SAFE 0a, CHG_CTRL 90, TCHG 1d); the driver re-programs the production configuration at probe (VDD_MAX 4.20 V, IBAT_MAX 450 mA, CHG_CTRL 0xA0, timer 512 min, BOOT_DONE 1). Not tested: whether VDD_MAX = 4.05 V from HOLD survives a warm reboot — not a production requirement (every boot starts a new charge cycle). - **Withdrawn:** "charger settings survive class-B/warm reboots". Correct model: warm reboot → SBL partially re-initialises the charger → the driver always re-programs the production configuration. (Section 8.10's "LBC settings survive warm reboots" is superseded by this.) - Persistent cache integration only with a separate GO. ### 8.15 Cache candidate (2026-10-04, b10/b10b3/cache/B10B3-CACHE-CANDIDATE.md) — prepared, NOT written `cache-extlinux-b10b3.img` 86869061 = B9C recipe with only the kernel (7.2.7-aurora-b10b3, v3) and production DTB replaced; emulator PASS, RAM pretest (class A) PASS. **Blocker before persistent GO: no verified physical charge-stop actuator for FAULT; the safety timer does not stop charging.** Proposed B10B-4 (RAM only, separate GO): USB_SUSP / IBAT_MAX min / VDD_MAX min / combination. ### 8.16 B10B-4 actuator audit (2026-10-04, B10B4-RESULT.md; RAM, TEST-ONLY hook kernel) - USB_SUSP (0x1347 b0): NOT an actuator — only ends FAST (path 01), input 0.46 → 0.41 A, VBAT keeps rising. - **VDD_MAX → 4.00 V: working FAULT actuator while VBAT > 4.00 V** — input 0.000 A within < 1 s, VBAT falls, board on battery, reversible (charging resumes on VDD_MAX 08, non-fast until a USB re-insert). Below 4.00 V it caps charging at 4.00 V (not a stop). - IBAT_MAX → 90 mA: derating only (FAST kept, reversible). - No hard stop at any VBAT verified; VDD_MAX 0 + IBAT_MAX 0 combination untested. Integration into the driver = separate GO. ### 8.17 v4: FAULT safe clamp to 4.00 V (2026-10-04, B10B5-RESULT.md) On FAULT entry (CHG_FAILED or VBAT > 4.25 V) v4 writes only VDD_MAX = 0x00 (+ readback, dev_crit); FAULT stays latched until USB removal or reboot. This is a **safe clamp, not a guaranteed charge disconnect**: with VBAT > 4.00 V charging stops (USB input → 0, board on battery); with VBAT < 4.00 V the charger may still charge up to 4.00 V. USB_SUSP is not used; IBAT_MAX is not touched in FAULT. RAM regression (TEST OVP injection) PASS; production cache candidate `b10/b10b3/cache-v4/cache-extlinux-b10b5.img` c3732515 built, NOT written. - 2026-10-04: production v4 RAM smoke test PASS (out-v4/aurora-b10b5.img 386502d3); cache candidate c3732515 unchanged → READY FOR PERSISTENT GO (write = separate GO). ### 8.18 PERSISTENT (2026-10-04, logs/b10/b10b5/B10-RESULT.md) — B10 CLOSED Cache = b10b5 c3732515 (B10_CACHE_WRITE_VERIFIED, HW EDL); class-A autonomous boot validated (charger, VADC, LTE, Wi-Fi, NCM, display, USB re-insert, 15-min regression window clean). Rollback: b10/b10b5/B10-rollback.sh → B9C b9ce13c9. - 2026-10-04 final: cold2 class-A persistent validation PASS (charger production config, USB off/on → NO_USB/CHARGING/FAST, 15-min window clean, live cache c3732515 re-read). **B10 battery / charger / power management — CLOSED.** Production limitations: FAULT = safe clamp VDD_MAX 4.00 V (no guaranteed hard-off below 4.00 V); safety timer does not stop charging; no thermal derating; battery contact mechanically unreliable.