tylernguyen / x1c6-hackintosh

READMEs, OpenCore configurations, patches, and notes for the Thinkpad X1 Carbon 6th Gen 2018 Hackintosh
https://tylernguyen.github.io/x1c6-hackintosh/
The Unlicense
628 stars 110 forks source link

Laptop issue that fall asleep at low percantage but its still just turn off(possible solution) #126

Closed mhl221135 closed 3 years ago

mhl221135 commented 3 years ago

I came from t460s git and maybe you know a solution for this trouble? I noticed that the laptop issues a warning that it will fall asleep, but it does not fall asleep and turns off at a low capacity I think I found a solution, but I don't understand the code, maybe you can implement these fixes https://applelife.ru/threads/hibernate-pri-razrjade-batarei.2874421/ If you cannot translate something on this forum, I can help because this is my native language

usr-sse2 commented 3 years ago

Hello! I'm the author of that thread on AppleLife. As I don't have your DSDT, I'll try to explain my patch.

The first part is simple: add a sleep button device, if it isn't present. You can search your DSDT for PNP0C0E. It is usually called SLPB or SBTN. If it's not present, add the following code:

                    Device (SLPB)
                    {
                        Name (_HID, EisaId ("PNP0C0E"))  // _HID: Hardware ID
                        Method (_STA, 0, NotSerialized)  // _STA: Status
                        {
                            If (ECON == One)
                            {
                                Return (0x0F)
                            }

                            Return (Zero)
                        }
                    }

where ECON is a flag that the Embedded Controller is available (I copied the _STA method from the power button (PWRB or PBTN)), or an even simpler variant:

Device (SLPB)
{
    Name (_HID, EisaId ("PNP0C0E"))
    Name (_STA, 0x0F)
}

Put it into the same scope as the power button.

The second part is more difficult. You need to find your _BST (battery state) method and add Notify (SLPB, 0x80) under the following conditions:

  1. The system is running on battery.
  2. The remaining capacity is less than Design Capacity of Low.

_BST method fills and returns a package of the following structure:

So you can either get the values out of the returned package after it's filled (but before return) or trace where it's filled and use the same values. I have chosen the second way, so B1DI is the discharging flag and B1B2 (AARC, CARC) is the remaining capacity, and to calculate the Design Capacity of Low I did the same calculation that is done in _BIF, in my case, divided the full capacity B1B2 (AAFC, CAFC) by 20 (0x14), so the low capacity is 5% of full capacity. So, the condition is actually B1DI && B1B2(AARC, CARC) < B1B2(AAFC, CAFC) / 0x14. We can't write the division using / in ACPI Source Language, we have to use the Divide operator, which takes the dividend in first argument, divisor in second argument, stores the quotient to the third argument and the remainder to the fourth argument. Make sure to use either new local variables or existing ones that aren't used further.

The second way is equivalent, but more universal. We may just check already filled values. So, before the Return (PKG1) add:

If (PKG1 [Zero] & 0x01)
{
    // We still need to calculate the Design Capacity of Low
    Divide (B1B2 (AAFC, CAFC), 0x14, Local0, Local1)
    If (PKG1 [0x02] < Local0)
    {
        Notify (SLPB, 0x80)
    }
}

If the patch is done correctly, the warning should still be shown when the remaining capacity is less than Design Capacity of Warning (in my case 10%), but when it becomes less than Design Capacity of Low (5% in my case), the computer sleeps.

Упс, не заметил, что Вы из Украины и ответил на английском

antoniomcr96 commented 3 years ago

@usr-sse2 Divide should store the result to the fourth argument according to ACPI specs. image

Anyway thanks, I'll try. Nice idea. I have been using a script that checks the battery level every two minutes and goes to sleep if the level goes below 5%, but this is better

mhl221135 commented 3 years ago
ECON

Hello! I'm the author of that thread on AppleLife. As I don't have your DSDT, I'll try to explain my patch.

The first part is simple: add a sleep button device, if it isn't present. You can search your DSDT for PNP0C0E. It is usually called SLPB or SBTN. If it's not present, add the following code:

                    Device (SLPB)
                    {
                        Name (_HID, EisaId ("PNP0C0E"))  // _HID: Hardware ID
                        Method (_STA, 0, NotSerialized)  // _STA: Status
                        {
                            If (ECON == One)
                            {
                                Return (0x0F)
                            }

                            Return (Zero)
                        }
                    }

where ECON is a flag that the Embedded Controller is available (I copied the _STA method from the power button (PWRB or PBTN)), or an even simpler variant:

Device (SLPB)
{
    Name (_HID, EisaId ("PNP0C0E"))
    Name (_STA, 0x0F)
}

Put it into the same scope as the power button.

The second part is more difficult. You need to find your _BST (battery state) method and add Notify (SLPB, 0x80) under the following conditions:

  1. The system is running on battery.
  2. The remaining capacity is less than Design Capacity of Low.

_BST method fills and returns a package of the following structure:

  • Battery State (bit 0: discharging, bit 1: charging, bit 2: is in critical state)
  • Battery Present Rate
  • Battery Remaining Capacity
  • Battery Present Voltage

So you can either get the values out of the returned package after it's filled (but before return) or trace where it's filled and use the same values. I have chosen the second way, so B1DI is the discharging flag and B1B2 (AARC, CARC) is the remaining capacity, and to calculate the Design Capacity of Low I did the same calculation that is done in _BIF, in my case, divided the full capacity B1B2 (AAFC, CAFC) by 20 (0x14), so the low capacity is 5% of full capacity. So, the condition is actually B1DI && B1B2(AARC, CARC) < B1B2(AAFC, CAFC) / 0x14. We can't write the division using / in ACPI Source Language, we have to use the Divide operator, which takes the dividend in first argument, divisor in second argument, stores the quotient to the third argument and the remainder to the fourth argument. Make sure to use either new local variables or existing ones that aren't used further.

The second way is equivalent, but more universal. We may just check already filled values. So, before the Return (PKG1) add:

If (PKG1 [Zero] & 0x01)
{
    // We still need to calculate the Design Capacity of Low
    Divide (B1B2 (AAFC, CAFC), 0x14, Local0, Local1)
    If (PKG1 [0x02] < Local0)
    {
        Notify (SLPB, 0x80)
    }
}

If the patch is done correctly, the warning should still be shown when the remaining capacity is less than Design Capacity of Warning (in my case 10%), but when it becomes less than Design Capacity of Low (5% in my case), the computer sleeps.

Упс, не заметил, что Вы из Украины и ответил на английском

Я не очень разбираюсь в dsdt не могли бы вы помочь если я предоставлю свой DSDT? вот efi который я использую https://github.com/simprecicchiani/ThinkPad-T460s-macOS-OpenCore вот мои DSDT https://github.com/simprecicchiani/ThinkPad-T460s-macOS-OpenCore/issues/34#issuecomment-721554327

Заранее очень вам благодарен!)

cowpod commented 3 years ago

Is there a register or method to disconnect the battery, or is that device-specific?

On my laptop AC0 is 1 when AC is connected, or 0 if a battery is connected. As far as I know there is no dedicated battery status bit. This is probably irrelevant as setting it to 1 won't actually stop the battery from charging...

tylernguyen commented 3 years ago

Waiting on https://github.com/acidanthera/bugtracker/issues/1754

tylernguyen commented 2 years ago

@mhl221135

See https://github.com/acidanthera/HibernationFixup/releases/tag/1.4.4

I'm waiting for Monterey to cleanup the repo and retest everything.