cd /news/developer-tools/my-battery-charging-limit-fix-for-me… · home topics developer-tools article
[ARTICLE · art-72966] src=gist.github.com ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

My battery charging limit fix for MECHREVO Wujie 14XA

A developer fixed the battery charging limit function on the MECHREVO Wujie 14XA laptop by reverse-engineering the EC firmware with help from Codex and GPT-5.6 Sol. The bug occurs because the EC firmware always disables charging limit control due to invalid stored limit values. The workaround involves writing to live limit and state registers to enable the limit.

read3 min views28 publishedJul 14, 2026

This write-up documents how I fixed the Battery Charging Limit function on the MECHREVO Wujie 14XA (also known as the MechRevo Forza 14X

). I did this with the help of Codex and GPT-5.6 Sol.

A bug in the charge-limit control logic was partially fixed in EC firmware version 2.08.

However, even with the "latest" firmware, the charging limit still often fails to take effect on many models. EC versions 2.12 and 2.08 are bundled with BIOS versions N.1.14MRO50

and N.1.14MRO19

, respectively.

With Codex's help, I disassembled the EC firmware images and identified several important addresses in the controller:

Address Meaning Writable via ACPI Calls
0x07B9
The effective Live Limit, ranging from 1 to 100 percent Yes
0x087F
The Stored Limit No; it is above 0x07FF
0x0742[2]
The enable gate for the charging limit Yes
0x07C3 and 0x0770
State values that may have various effects, which are still unknown to us Yes

It seems that we should be able to control the limit simply by writing to 0x07B9

, right?

No! There is a caveat. The charging routine in the EC firmware works roughly as follows:

bool state_is(uint8_t value)
{
    return xram[0x07C3] == value ||
           xram[0x0770] == value;
}

// The following code is executed once per second.

bool limit_enabled = state_is(4) || state_is(5);

if (!limit_enabled) {
    uint8_t stored_limit = xram[0x087F] & 0x7f;

    if (stored_limit == 0 || stored_limit > 100) {
        disable_control();
        return;
    }
}

enable_control(); // Enable control using the Live Limit.
store_limit();    // Save the Live Limit as the Stored Limit.

For this laptop model, or at least for my unit, limit_enabled

is unfortunately always false

. The EC therefore checks stored_limit

, which is also an invalid value.

As a result, the EC always executes disable_control()

and returns. The Live Limit register is never read, which is why writing to 0x07B9 has no effect at all.

We seem to be stuck here because we cannot change the Stored Limit directly. Its address is greater than 0x07ff

, so it cannot be written through an ACPI call.

So, how can we fix this? The workaround is actually quite intuitive: we can change the State values!

Here is my plan:

  • Upgrade the BIOS/EC firmware to the latest version. Either N.1.14MRO50

orN.1.14MRO19

should work. - Write a value to the Live Limit. For example, set it to 60% with xram[0x07B9] <- 0x3C

. - Overwrite the State value with 4

by settingxram[0x07C3] <- 0x04

, so thatlimit_enabled

becomestrue

. - Optionally, wait for a second or so to allow the EC to execute store_limit()

. Then restore the original value of0x07C3

. - Read 0x087F

to verify whether the workaround worked.

This worked on my unit:

$ upower -i /org/freedesktop/UPower/devices/battery_BAT0
  native-path:          BAT0
  vendor:               OEM
  model:                standard
  serial:               00001
  power supply:         yes
  updated:              Wed Jul 15 02:34:42 2026 (6 seconds ago)
  has history:          yes
  has statistics:       yes
  battery
    present:             yes
    rechargeable:        yes
    state:               fully-charged
    warning-level:       none
    energy:              76.8768 Wh
    energy-empty:        0 Wh
    energy-full:         80.08 Wh
    energy-full-design:  80.08 Wh
    voltage-min-design:  15.4 V
    capacity-level:      Normal
    energy-rate:         0 W
    voltage:             16.232 V
    charge-cycles:       N/A
    percentage:          96%
    capacity:            100%
    technology:          lithium-ion
    icon-name:          'battery-full-charged-symbolic'

$ cat /sys/class/power_supply/BAT0/current_now
0

The battery is at 96% but is still reported as fully charged. The reported current is also zero.

The attachment is a simple script that automates this process. ⚠️ Review it carefully before running it!

This finding also explains something else. There are reports that flashing BIOS/EC firmware from another OEM with the same motherboard can resolve the issue. Those BIOS versions include a menu option for configuring the Stored Limit, which naturally breaks the deadlock.

In short, the root cause is that Mechrevo initializes the Stored Limit to an invalid value. And because of the EC's control logic, this leaves the system trapped in a state where writes to the Live Limit are effectively ignored.

Whether their engineers fully understand the hardware and firmware they are shipping is quite an interesting question.

── more in #developer-tools 4 stories · sorted by recency
── more on @mechrevo 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/my-battery-charging-…] indexed:0 read:3min 2026-07-14 ·