Skip to content

Repository files navigation

ChargeSpeedAdjuster

ChargeSpeedAdjuster generates relaxed Xiaomi charging thermal profiles from the files supplied by the currently installed OS. It does not keep stock backups and does not copy generated files into Xiaomi's real configuration directory.

Boot design

  1. Magisk runs post-fs-data.sh after /data is available.
  2. edit.sh mounts the immutable vendor, ODM, and root block devices read-only, bypassing all active Magisk overlays.
  3. The generator inventories current immutable thermal-*.conf sources using ODM, vendor, then system precedence. AES block candidates must pass strict decryption and exact re-encryption; adjacent plaintext control files remain untouched.
  4. The source manifest, build identity, converter, and patcher are hashed.
  5. Changed sources are decrypted, schema-validated, patched, encrypted, and decrypted again to prove an exact crypto round trip.
  6. During installation, the validated files are staged under system/vendor/etc, reproducing v4.2's Magisk vendor-overlay coverage.
  7. During early boot, the overlay backing files are refreshed in place and the complete validated output directory is bind-mounted over /data/vendor/thermal/config. After Kitsune establishes its magic mounts, a late read-only check verifies every generated file byte-for-byte at /vendor/etc. This works whether Xiaomi's real writable profile directory is empty or already populated.
  8. After the overlays are verified, service.sh enables Xiaomi's wired and wireless thermal-removal controls, validates their readback, and listens for charging-path events so it can reassert a value if Xiaomi resets it.

If generation or early vendor-backing refresh fails, the writable profile directory is not mounted. The late visible-overlay audit records any mismatch in runtime/vendor-overlay.log. Magisk overlays and bind mounts disappear on reboot, so disabling or removing the module restores the real files automatically.

On a phone previously modified by v4.2, the real /data files may already contain v4.2's permanent copies. This redesign never writes another restoration over them. It generates clean mounted profiles from immutable current sources; an OS/vendor reset of the writable thermal cache is the safe way to remove that pre-existing legacy state.

Charging patch

Only charging-specific sections are considered. A section must have one of the known schemas:

  • algo_type monitor with device battery
  • algo_type sic with device thermal_fcc_override
  • algo_type monitor with device wireless_charge

The patcher retains v4.2 behavior where appropriate, but replaces its disabled FCC/SIC controller with an explicit relaxed curve:

  • In monitor/battery sections, the first trig and clr threshold lists are replaced by empty trig and clr fields.
  • In sic/thermal_fcc_override sections, the stock controller is replaced with the following battery-side current curve. Power figures use 4.3 V and are approximate; input power and displayed charger power are different.
Virtual temperature band Target FCC range Approx. battery power
Below 40 C Unregulated by this profile Up to 20.9 A Up to 90 W
40-41.3 C 40.5 C 9.3-16.28 A 50-70 W
41.3-43.5 C 42.5 C 6.98-13.95 A 40-60 W
43.5-44.5 C 44 C 4.65-11.63 A 30-50 W
44.5-47 C 45 C 3.5-9.3 A 15-40 W
47 C and above 47 C 2.33-6.98 A 10-30 W

Each transition clears 0.5 C below its trigger to avoid rapid band changes.

  • In monitor/wireless_charge sections, stock mitigation states use a dedicated wireless temperature curve:
Virtual temperature trigger Wireless mitigation state
42 C 0
43.3 C 705
44.5 C 1008
45.5 C 1413
47 C 1515

Each state clears 0.5 C below its trigger. These packed firmware states are not watts. Based on live measurements, state 0 is the least restrictive, 705/1008 held about 37 W, and 1413/1515 held about 32 W. 1515 is the strongest state observed in the current stock profiles, so FCC/SIC supplies the additional battery-current reduction at 47 C and above.

The temperatures used here come from Xiaomi's composite VIRTUAL-SENSOR0, not necessarily the battery temperature shown by Android. Unknown charging schemas fail generation instead of being guessed. CPU, GPU, modem, display, and emergency platform thermal controls are not modified.

Xiaomi's charging firmware also exposes independent wired and wireless thermal votes outside the encrypted profiles. The module sets both removal controls to 1; device testing shows that the mapped userspace wireless monitor continues to apply its wlscharge_control_limit states independently:

/sys/class/qcom-battery/thermal_remove
/sys/class/qcom-battery/wls_thermal_remove

Xiaomi can reset these controls when a charging path is detached or reconfigured. The service blocks on kernel USB/wireless power-supply events; it has no periodic polling timer and holds no wakelock. On a relevant event it checks immediately, then after one and three seconds to catch a delayed reset, and restores both controls to 1 only when needed. If the module is disabled, the event handler no longer reapplies the controls. Uninstall stops the listener and restores the controls to 0 immediately.

StepChgJeit is the battery firmware's temperature-, voltage-, and state-of-charge-dependent FCC/FV curve. On the tested Xiaomi 14 (houji), writing 1 to /sys/class/qcom-battery/remove_temp_limit does not bypass that curve: it makes the reported battery temperature jump to 50 C and causes StepChgJeit to impose its hot-battery FCC/FV limits. The module therefore leaves this property at its default 0; disabling or uninstalling the module also restores it to 0. Separate platform emergency thermal controls remain untouched.

The generated audit files are stored under the module's runtime directory:

  • source-manifest.txt: filename, selected source layer, and source SHA-256
  • source.signature: cache identity for the complete current source set
  • patch-manifest.txt: every patched or unchanged file and section
  • generator.log: generation and mount decisions
  • vendor-overlay.log: late byte-for-byte verification of /vendor/etc
  • charge-controls.log: driver thermal-removal writes and readback validation

If early profile generation/mounting, late vendor-overlay verification, charging-control setup, or event-time control restoration fails, the Magisk module description is prefixed with [MODULE INACTIVE]. Each boot stage owns its failure state, so a later successful stage cannot hide an unrelated failure. The marker is removed automatically after all recorded components recover.

The legacy thermal-bat binary is used only as a development reference. It is not run by the module and is removed from the installed module during installation.

Converter

The Xiaomi AES-CBC converter is source-controlled in tools/miui-thermal. Build the Android ARM64 binary with:

cd tools/miui-thermal
GOOS=android GOARCH=arm64 CGO_ENABLED=0 \
  go build -trimpath -buildvcs=false -ldflags='-s -w' -o ../../miui-thermal .

The converter uses the Xiaomi-compatible key and IV thermalopenssl.h, strict PKCS#7 padding validation, atomic output writes, and mode 0755 for newly created directories.

Publishing a release

  1. Set version= in module.prop to the intended release tag, for example version=v4.5, and commit the change.
  2. Create and push the matching tag: git tag v4.5 followed by git push origin v4.5.

The release workflow builds a minimal Magisk-installable ZIP, verifies its contents, creates a SHA-256 checksum, and publishes both files in a GitHub Release with generated release notes. A tag that does not exactly match module.prop is rejected.

About

Remove screen-on charging speed limit for Xiaomi phones

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages