Contribute
Register

Battery state problem (10.11)

Status
Not open for further replies.
Joined
Jun 13, 2012
Messages
152
Motherboard
Lenovo Ideapad Y510P
CPU
i7 4700MQ
Graphics
HD4600
Mobile Phone
  1. Android
Hi all,

I have Lenovo Y510p and clean installed 10.11. I'm facing a battery problem where the it does not report the correct remaining time while charging. The state is correct, though, while discharging. Here's the steps I made:

1- I patched my native DSDT with the Y510p's battery patch available in Rehabman's repo
2- I have compared the native DSDT.dsl and the patched DSDT.dsl for SystemMemory differences and I can't see a real difference form the output:
Code:
<     OperationRegion (MBAR, SystemMemory, ((\_SB.PCI0.MHBR << 0x0F) + 0x5000), 0x1000)
>     OperationRegion (MBAR, SystemMemory, Add (ShiftLeft (\_SB.PCI0.MHBR, 0x0F), 0x5000), 0x1000)
<     OperationRegion (XHCP, SystemMemory, (PEBS + 0x000A0000), 0x0100)
>     OperationRegion (XHCP, SystemMemory, Add (PEBS, 0x000A0000), 0x0100)
3- Checked Method BSHK and added a case for _OSI ("Darwin") (everywhere)
Code:
If (LOr(_OSI ("Darwin"), _OSI ("Windows 2012")))
{
	Store (0x07DC, OSYS)
	Store (0x04, Local1)
}
4- I installed ACPIDebug.kext and patched my DSDT with debugging patches and added code to instrument _BST method while haunting for clues related to Amperage value:
Code:
Method (_BST, 0, NotSerialized)  // _BST: Battery Status
            {
                Name (PBST, Package (0x04)
                {
                    Zero, 
                    Ones, 
                    Ones, 
                    0x1770
                })
                Name (BAPR, Zero)
                Name (RECA, Zero)
                If (ECOK ())
                {
                    Store (^^EC0.BST0, Index (PBST, Zero))
                    \rmdt.p2("Battery State PBST[0] is", ^^EC0.BST0)
                    Sleep (0x0A)
                    Store (^^EC0.BAC0, Local4)
                    Subtract (0xFFFF, Local4, Local4)
                    If (^^EC0.BAM0)
                    {
                        Store (Local4, Index (PBST, One))
                        \rmdt.p2("BAPR is", BAPR)
                    }
                    Else
                    {
                        Store (Local4, BAPR)
                        Multiply (BAPR, 0x0A, BAPR)
                        Store (BAPR, Index (PBST, One))
                        \rmdt.p2("Battery Present Rate PBST[1] is", BAPR)
                    }

                    Sleep (0x0A)
                    If (^^EC0.BAM0)
                    {
                        Store (^^EC0.BRC0, Index (PBST, 0x02))
                    }
                    Else
                    {
                        Store (^^EC0.BRC0, RECA)
                        Multiply (RECA, 0x0A, RECA)
                        Store (RECA, Index (PBST, 0x02))
                        \rmdt.p2("Battery Remaining Capacity PBST[2] is", RECA)
                    }

                    Sleep (0x0A)
                    Store (^^EC0.BPV0, Index (PBST, 0x03))
                    \rmdt.p2("Battery Present Voltage PBST[3] is", ^^EC0.BPV0)
                    Sleep (0x0A)
                    If (LNotEqual (^^EC0.BDN0, BMDL))
                    {
                        Notify (BAT1, 0x81)
                    }
                }
                // Calculating Amperage
                // 1000 (dec) = 0x3E8 (hex)
                Store (0x3E8,Local7)
                Multiply (Local7, BAPR, Local7)
                Divide (Local7, ^^EC0.BDV0, Local6, Local7)
                \rmdt.p2 ("Amperage[mA] = 0x3E8 * PresentRate / DesignVoltage is", Local7)
                // End Calculating Amperage
                Return (PBST)
            }
5- I installed debug version of ACPIBatteryManager
6- This is the Amperage in mA at some point while charging (all reports the same value which is in the acceptable range according to ACPI specs):
Code:
System Information: Amperage (mA):	59208
ACPIBatteryManager: fCurrentRate(mA) = 59208
IOREG Amperage = 0xe748
Calculated: ACPIDebug: { "Amperage[mA] = 0x3E8 * PresentRate / DesignVoltage is", 0xe748, }


I really not sure why would the AvgTimeToFull in IOREG while charging be 0x0 or 0x1 (which reflect 0:00 or 0:01 in battery indicator on menu bar) . I'm attaching a copy of IOREG while charging, my native DSDT.dsl, my patched DSDT.dsl and part of the log.

Thanks in advance.
 

Attachments

  • ahmed_ais.zip
    647.7 KB · Views: 53
...

I really not sure why would the AvgTimeToFull in IOREG while charging be 0x0 or 0x1 (which reflect 0:00 or 0:01 in battery indicator on menu bar) . I'm attaching a copy of IOREG while charging, my native DSDT.dsl, my patched DSDT.dsl and part of the log.

A large Amperage (charging rate) would explain a short AvgTimeToFull.
 
That make sense but I don't find a reason why the amperage is high while charging.

1. The code in _BST is the same between patched and native.
2. The same code worked without patching in 10.10.
3. I removed Y510p battery patch and the problem remain.
4. I booted without a DSDT at all (setting DSDT = null) and still the problem exist.
5. I disassemble the tables using -dl

Since remaining time depend on amperage, and amperage depend directly on present rate as design voltage is constant. Now the present rate comes from ^^EC0.BAC0 after subtracting from 0xFFFF and multiplying by 0x0A to convert the raw data to mA (or mAh).
Code:
Store (^^EC0.BAC0, Local4)
Subtract (0xFFFF, Local4, Local4)
If (^^EC0.BAM0)
{
    // ^^EC0.BAM0 != 0    --> amps (not my case)
    Store (Local4, Index (PBST, One))
}
Else
{
    // ^^EC0.BAM0 == 0    --> watts (my case)
    Store (Local4, BAPR)
    Multiply (BAPR, 0x0A, BAPR)
    Store (BAPR, Index (PBST, One))
}
I don't have control over ^^EC0.BAC0 value nor I know where it originated from to see why it takes wrong values. BAC0 exists only once in _BST and once in EC0:
Code:
Scope (_SB.PCI0.LPCB)
{
    Device (EC0)
    {
        OperationRegion (ECMM, SystemMemory, 0xFF000000, 0x1000)
        Field (ECMM, AnyAcc, Lock, Preserve)
        {
            ......
            BAC0,   16,
            ......
        }
    }
}

Any clue?

Thanks.


EDIT:
These are some data tracing amperage calculations in _BST:

Discharging (OK)
Code:
ACPIDebug: { "Battery State PBST[0] is", 0x1, }
ACPIDebug: { "^^EC0.BAC0 before subtraction is", 0xfb65, }
ACPIDebug: { "^^EC0.BAC0 after subtraction is", 0x49a, }
ACPIDebug: { "Battery Present Rate PBST[1] is", 0x2e04, }     -===> this is ^^EC0.BAC0 after subtraction * 0xA
ACPIDebug: { "Amperage[mA] = 0x3E8 * PresentRate / DesignVoltage is", 0x442, }
Charging (Wrong)
Code:
ACPIDebug: { "Battery State PBST[0] is", 0x2, }
ACPIDebug: { "^^EC0.BAC0 before subtraction is", 0x638, }
ACPIDebug: { "^^EC0.BAC0 after subtraction is", 0xf9c7, }
ACPIDebug: { "Battery Present Rate PBST[1] is", 0x9c1c6, }     -===> this is ^^EC0.BAC0 after subtraction * 0xA
ACPIDebug: { "Amperage[mA] = 0x3E8 * PresentRate / DesignVoltage is", 0xe746, }

The code to generate these is:
Code:
Method (_BST, 0, NotSerialized)
{
    Name (PBST, Package (0x04)
    {
        Zero, 
        Ones, 
        Ones, 
        0x1770
    })
    Name (BAPR, Zero)
    Name (RECA, Zero)
    If (ECOK ())
    {
        Store (^^EC0.BST0, Index (PBST, Zero))
        \RMDT.P2 ("Battery State PBST[0] is", ^^EC0.BST0)
        Sleep (0x0A)
        Store (^^EC0.BAC0, Local4)
        \RMDT.P2 ("^^EC0.BAC0 before subtraction is", Local4)
        Subtract (0xFFFF, Local4, Local4)
        \RMDT.P2 ("^^EC0.BAC0 after subtraction is", Local4)
        If (^^EC0.BAM0)
        {
            Store (Local4, Index (PBST, One))
        }
        Else
        {
            Store (Local4, BAPR)
            Multiply (BAPR, 0x0A, BAPR)
            Store (BAPR, Index (PBST, One))
            \RMDT.P2 ("Battery Present Rate PBST[1] is", BAPR)
        }

        Sleep (0x0A)
        If (^^EC0.BAM0)
        {
            Store (^^EC0.BRC0, Index (PBST, 0x02))
        }
        Else
        {
            Store (^^EC0.BRC0, RECA)
            Multiply (RECA, 0x0A, RECA)
            Store (RECA, Index (PBST, 0x02))
        }

        Sleep (0x0A)
        Store (^^EC0.BPV0, Index (PBST, 0x03))
        Sleep (0x0A)
        If (LNotEqual (^^EC0.BDN0, BMDL))
        {
            Notify (BAT1, 0x81)
        }
    }

    Store (0x03E8, Local7)
    Multiply (Local7, BAPR, Local7)
    Divide (Local7, ^^EC0.BDV0, Local6, Local7)
    \RMDT.P2 ("Amperage[mA] = 0x3E8 * PresentRate / DesignVoltage is", Local7)
    Return (PBST)
}

And my battery's design voltage is 0x2A30 (10800).

EDIT2:
I also have a question: both IOREG and System Information should report signed amperage while ACPIBatteryManager debug and raw ACPI data would report unsigned amperage. Is this statement correct?

Thanks
 
That make sense but I don't find a reason why the amperage is high while charging.

1. The code in _BST is the same between patched and native.
2. The same code worked without patching in 10.10.
3. I removed Y510p battery patch and the problem remain.
4. I booted without a DSDT at all (setting DSDT = null) and still the problem exist.
5. I disassemble the tables using -dl

Since remaining time depend on amperage, and amperage depend directly on present rate as design voltage is constant. Now the present rate comes from ^^EC0.BAC0 after subtracting from 0xFFFF and multiplying by 0x0A to convert the raw data to mA (or mAh).
Code:
Store (^^EC0.BAC0, Local4)
Subtract (0xFFFF, Local4, Local4)
If (^^EC0.BAM0)
{
    // ^^EC0.BAM0 != 0    --> amps (not my case)
    Store (Local4, Index (PBST, One))
}
Else
{
    // ^^EC0.BAM0 == 0    --> watts (my case)
    Store (Local4, BAPR)
    Multiply (BAPR, 0x0A, BAPR)
    Store (BAPR, Index (PBST, One))
}
I don't have control over ^^EC0.BAC0 value nor I know where it originated from to see why it takes wrong values. BAC0 exists only once in _BST and once in EC0:
Code:
Scope (_SB.PCI0.LPCB)
{
    Device (EC0)
    {
        OperationRegion (ECMM, SystemMemory, 0xFF000000, 0x1000)
        Field (ECMM, AnyAcc, Lock, Preserve)
        {
            ......
            BAC0,   16,
            ......
        }
    }
}

Any clue?

Thanks.


EDIT:
These are some data tracing amperage calculations in _BST:

Discharging (OK)
Code:
ACPIDebug: { "Battery State PBST[0] is", 0x1, }
ACPIDebug: { "^^EC0.BAC0 before subtraction is", 0xfb65, }
ACPIDebug: { "^^EC0.BAC0 after subtraction is", 0x49a, }
ACPIDebug: { "Battery Present Rate PBST[1] is", 0x2e04, }     -===> this is ^^EC0.BAC0 after subtraction * 0xA
ACPIDebug: { "Amperage[mA] = 0x3E8 * PresentRate / DesignVoltage is", 0x442, }
Charging (Wrong)
Code:
ACPIDebug: { "Battery State PBST[0] is", 0x2, }
ACPIDebug: { "^^EC0.BAC0 before subtraction is", 0x638, }
ACPIDebug: { "^^EC0.BAC0 after subtraction is", 0xf9c7, }
ACPIDebug: { "Battery Present Rate PBST[1] is", 0x9c1c6, }     -===> this is ^^EC0.BAC0 after subtraction * 0xA
ACPIDebug: { "Amperage[mA] = 0x3E8 * PresentRate / DesignVoltage is", 0xe746, }

The code to generate these is:
Code:
Method (_BST, 0, NotSerialized)
{
    Name (PBST, Package (0x04)
    {
        Zero, 
        Ones, 
        Ones, 
        0x1770
    })
    Name (BAPR, Zero)
    Name (RECA, Zero)
    If (ECOK ())
    {
        Store (^^EC0.BST0, Index (PBST, Zero))
        \RMDT.P2 ("Battery State PBST[0] is", ^^EC0.BST0)
        Sleep (0x0A)
        Store (^^EC0.BAC0, Local4)
        \RMDT.P2 ("^^EC0.BAC0 before subtraction is", Local4)
        Subtract (0xFFFF, Local4, Local4)
        \RMDT.P2 ("^^EC0.BAC0 after subtraction is", Local4)
        If (^^EC0.BAM0)
        {
            Store (Local4, Index (PBST, One))
        }
        Else
        {
            Store (Local4, BAPR)
            Multiply (BAPR, 0x0A, BAPR)
            Store (BAPR, Index (PBST, One))
            \RMDT.P2 ("Battery Present Rate PBST[1] is", BAPR)
        }

        Sleep (0x0A)
        If (^^EC0.BAM0)
        {
            Store (^^EC0.BRC0, Index (PBST, 0x02))
        }
        Else
        {
            Store (^^EC0.BRC0, RECA)
            Multiply (RECA, 0x0A, RECA)
            Store (RECA, Index (PBST, 0x02))
        }

        Sleep (0x0A)
        Store (^^EC0.BPV0, Index (PBST, 0x03))
        Sleep (0x0A)
        If (LNotEqual (^^EC0.BDN0, BMDL))
        {
            Notify (BAT1, 0x81)
        }
    }

    Store (0x03E8, Local7)
    Multiply (Local7, BAPR, Local7)
    Divide (Local7, ^^EC0.BDV0, Local6, Local7)
    \RMDT.P2 ("Amperage[mA] = 0x3E8 * PresentRate / DesignVoltage is", Local7)
    Return (PBST)
}

And my battery's design voltage is 0x2A30 (10800).

EDIT2:
I also have a question: both IOREG and System Information should report signed amperage while ACPIBatteryManager debug and raw ACPI data would report unsigned amperage. Is this statement correct?

Thanks

The debug ACPIBatteryManager.kext can also be used for further debug your issue.

Amperage is signed in ioreg, not signed in ACPI.
 
The debug ACPIBatteryManager.kext can also be used for further debug your issue.

Thanks for the reply.

I'm currently using debug version of ACPIBatteryManager.kext for debugging but only to retrieve present rate and amperage. Any more hints on how to squeez more information that are useful for my case? I'm currently out of ideas.

I also do not know what has changed from 10.10 to 10.11 so the battery breaks like this (knowing that you confirmed many times that ACPIBatteryManager.kext works equally in both 10.10 and 10.11).
 
I thought to check the battery under Windows and unfortunately the problem exist in Windows too. This should mean it's hardware problem and has nothing to do with OSX/driver/DSDT.

Since the system (Windows or OSX) can successfully report the remaining capacity, cycles, and remaining time (while discharging), I think the problem is with the AC charger or the power socket that is malfunctioning and report wrong current rate.
 
I thought to check the battery under Windows and unfortunately the problem exist in Windows too. This should mean it's hardware problem and has nothing to do with OSX/driver/DSDT.

Since the system (Windows or OSX) can successfully report the remaining capacity, cycles, and remaining time (while discharging), I think the problem is with the AC charger or the power socket that is malfunctioning and report wrong current rate.

It would seem so... (problem unrelated to software...)

Did you try EC reset?
 
Did you try EC reset?

Sorry just saw your reply. I just rest EC and I will update once I test (battery was full so I have to discharge it a bit to test charging).
 
Status
Not open for further replies.
Back
Top