I found this thread:
Maybe its enough to reflash the dtbo.img again to have the factory settings definition of the battery.
I found this thread:
Maybe its enough to reflash the dtbo.img again to have the factory settings definition of the battery.
solely refresh dtbo is not enough, I will have to rewrite the value of /sys/class/power/bms/charge_full when boot the machine, and possibily set this value to the max of battery,and make its permission to something like 400, otherwise bms will frequently rewrite this value to the old batteryās degraded full charge capacity value.
Hopefully it does it not. But there are other Values we must take care of like the mirrowed capacity_full and maybe others.
battery logic were hardcoded in kernelās part, most of them. I donāt know how does XA works like. Sony have their own process of release the lock of their BMS setting somehow, otherwise it could be difficult to just swapping and recalibrate the battery, I found all of the sources from their forum, and most of them said sony doesnāt allow user to do this by themselves, dtbo flash only solves the problem of charge_full_designed, for charge_full, they only can be modified by magisk, or most possibily, just memory or function hijack to replace this value. My way to solve this is replace dtbo, and echo value > charge_full, and locks its permission from rewrite. From dmesg I can still see a lot of capacity learning updates message, but it doesnāt being applied to a locked file. The best approach probably is to modify the kernel, or doing a kernel patch, to make everything working as expected, but it really consumes too much time for testing, I gave up for a best solutionā¦
Not quite sure, I guess this value were hardcoded and hard reseted with BMS board. I flashed back to android one time, using accubattery for calibrating, full discharge and full charge for 3 times, but the result varies quite large everytime. And tried using reset cache method for couple few times, like long press volume and power to reset the phone, all doesnāt help. I did using xposed to trace the value change of charge_full update last time as well. they always sending me a value of around 2000mah whereas my battery is indeed more than 4600mah even after depleted charge and so on. So i stopped testing because it really hurts the battery for these full depletes cycles.
I found some information that Emma once had the option for calibrating the battery. I connected my device, but all it offered was to flash stock Android; there was no option for battery calibration. Maybe this is related to older Xperia devices.
official ways if possible could be way better, i donāt have access to windows machine so donāt know if EMMA could have that directly or not.
The way how i locked the full_charge were coming from yet another way out is by patching this file for specific machine, see my reference link, after patches dtbo(write the correct battery info into the kernel), he patches this two methods somc_fg_gen4_restore_batt_aging_level_from_sram/somc_fg_gen4_set_batt_aging_level, basically are very small blocks of change, I didnāt dis-assmeble the patch
magiskboot hexpatch $DIRPATH/boot_0.img E243413968D647B9 0200805268D647B9
magiskboot hexpatch $DIRPATH/boot_0.img E00D0054A80240B9 E00D005408008052
But the main logic is pretty straight forward.
static int somc_fg_gen4_set_batt_aging_level(struct fg_dev *fg, int aging_level)
{
if (fg->max_batt_aging_level == BATT_AGING_LEVEL_NONE) {
pr_err(ācannot set batt aging level because somc batterydata node does not exists\nā);
return -EINVAL;
}
if (aging_level < 0 || aging_level > fg->max_batt_aging_level) {
pr_err("setting value is out of range\n");
return -EINVAL;
}
if (aging_level == fg->batt_aging_level)
return 0;
fg->profile_load_status = PROFILE_NOT_LOADED;
fg->requested_batt_aging_level = aging_level;
schedule_delayed_work(&fg->profile_load_work, 0);
return 0;
}
static void somc_fg_gen4_restore_batt_aging_level_from_sram(struct fg_dev *fg)
{
int rc;
u8 val;
fg->batt_aging_level = 0;
if (fg->max_batt_aging_level == BATT_AGING_LEVEL_NONE) {
fg_dbg(fg, FG_SOMC, "batt aging level is not restored\n");
return;
}
rc = fg_sram_read(fg, SOMC_AGING_LEVEL_WORD, SOMC_AGING_LEVEL_OFFSET,
&val, 1, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("failed to read batt aging level rc=%d\n", rc);
} else if (val > fg->max_batt_aging_level) {
pr_err("saved batt aging level is abnormal val=%d\n", val);
} else {
fg->batt_aging_level = val;
}
fg_dbg(fg, FG_SOMC, "batt aging level = %d\n", fg->batt_aging_level);
fg->requested_batt_aging_level = NO_REQUESTED_LEVEL;
}
I guess he directly passed 100 or 0 directly to trick the following process, but since SailfishOS looks like only cares about charge_full, so you donāt need to care those if simple cat and chmod works. Iām looking forward to give kernel patch a try as well, but just donāt feeling comfortable because is hard to remove or forgot what I have changed in the future.
Ref.
if your kernel have APatch support, you can directly writting kernel patch, or directly patch methods accordingly to the fg model you use,
P.S.
Disassemble a bit.
0x0000000000000000: E0 0D 00 54 b.eq #0x1bc
0x0000000000000004: 08 00 80 52 movz w8, #0
0x0000000000000000: 02 00 80 52 movz w2, #0
0x0000000000000004: 68 D6 47 B9 ldr w8, [x19, #0x7d4]
Heās just patched the fg->batt_aging_level to 0 probably.