// Method BTST is called to return battery status
// index 0: bitfield showing charging or not, bit 0 is discharging, bit 1 is charging, bit 2 is "error" bit
// index 1: present rate of charge/discharge
// index 2: battery remaining capacity
// index 3: battery present voltage
Method (BTST, 2, Serialized)
{
// Arg0 is the battery # we wish to get status of
ShiftLeft (One, Arg0, Local7)
BTDR (One)
If (LEqual (BSTA (Local7), 0x0F))
{
// this is some error condition
Store (Package (0x04)
{
Zero,
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF
}, Index (NBST, Arg0))
Return (0xFF)
}
// not sure what this is accomplishing, but it isn't related to our issue...
// some sort of lock while the code below runs
Acquire (BTMX, 0xFFFF)
If (Arg1)
{
Store (0xFF, NGBT)
}
Store (NGBT, Local0)
Release (BTMX)
// another error condition, don't think this is happening
// I think it is a check to see that there isn't a request for battery status
// on a battery that isn't even installed.
//
// it is kind of sketchy that in this case they return prematurely before undoing
// whatever lock they just did above...
If (LEqual (And (Local0, Local7), Zero))
{
Return (Zero)
}
// now we begin on the guts, grab a mutex for the EC
Acquire (ECMX, 0xFFFF)
If (ECRG)
{
// grab most of the raw data we need for this function from the EC
Store (Arg0, BSEL)
// charging/discharging status into Local0
Store (BST, Local0)
// present rate into Local3
Store (B1B2 (BPR0, BPR1), Local3)
// store current capacity and present voltage right into the result (index 2 and 3)
Store (B1B2 (BRC0, BRC1), Index (DerefOf (Index (NBST, Arg0)), 0x02))
Store (B1B2 (BPV0, BPV1), Index (DerefOf (Index (NBST, Arg0)), 0x03))
}
Release (ECMX)
// Method call to GACS has to do with getting AC status
// it does some stuff then returns ACST (AC "status")
// checking if AC status == 1
// This whole section is some kind of "sanity check"
If (LEqual (GACS (), One))
{
#if 1
// I added this here because I want to know if bit 0 of Local0 would normally be cleared
// status will have bit 8 set if we follow this path
// And note, the code below (original) is not compiled in.
if (And (Local0, 1)) { Store (Or (Local0, 0x100), Local0) }
#else
// logic here is something like ACST is 1, so can't be discharging (discharging is bit 0 of Local0)
// this makes sure bit0 is cleared if AC status is 1
And (0xFFFFFFFFFFFFFFFE, Local0, Local0)
#endif
}
Else
{
// similar thing going on here as above, but with charging bit...
// ie. not on AC power, so better not be charging...
// I set bit 9 of Local0 (status) just to see if this is happening normally
#if 1
if (And (Local0, 2)) { Store (Or (Local0, 0x200), Local0) }
#else
And (0xFFFFFFFFFFFFFFFD, Local0, Local0)
#endif
}
If (And (Local0, One))
{
Acquire (BTMX, 0xFFFF)
Store (Local7, NDCB)
Release (BTMX)
}
#if 1
// I put this in just because I wanted to see if the DSDT code I changed here is getting run.
// (way to make sure the DSDT I sent you gets copied to right place, and way to make sure, I'm
// right about this being the code called when getting ACPI battery status.
// Setting bit 4 of status (remember, only bits 0, 1, and 2 are used "officially")
Store (Or (Local0, 0x10), Local0)
#endif
// checking if "discharging"... special case code follows
If (And (Local0, One))
{
// this is kind of interesting, I guess HP can't trust the data coming from their controller,
// so they sanity check it here. must be between 0x190 and 0x1964 or...
// Local3 is present (discharge) rate here
If (LOr (LLess (Local3, 0x0190), LGreater (Local3, 0x1964)))
{
// not in right range, so grab data that they stored here last time
Store (DerefOf (Index (DerefOf (Index (NBST, Arg0)), One)),
Local5)
// then sanity check again,
If (LOr (LLess (Local5, 0x0190), LGreater (Local5, 0x1964)))
{
// and... oh crap, if still not in range, then store some arbitrary value for present charge
Store (0x0D7A, Local3)
#if 1
// and I wanted to know if this is happening so setting bit 5
Store (Or (Local0, 0x20), Local0)
#endif
}
Else
{
// this is the case where they use the last value that was within range as that is in Local5
Store (Local5, Local3)
#if 1
// and I also wanted to know if this is happening, so setting bit 6
Store (Or (Local0, 0x40), Local0)
#endif
}
}
}
Else
{
// this is the case of not discharging
// here they are looking at whether there is any charging status reported and if not...
If (LEqual (And (Local0, 0x02), Zero))
{
#if 1
// but... I do want to know when the code might have done this... so set bit 7
Store (Or (Local0, 0x80), Local0)
#else
// if no charging status reported, then better report "present charge" at 0
// I didn't want this to happen because I want to see what they report as present charge in the case
// of no charge or discharge state
Store (Zero, Local3)
#endif
}
}
// finally, it stores the results calculated by logic above...
Store (Local0, Index (DerefOf (Index (NBST, Arg0)), Zero))
Store (Local3, Index (DerefOf (Index (NBST, Arg0)), One))
// more manipulation of the BTMX/NGBT (must be some kind of "lock")
Acquire (BTMX, 0xFFFF)
And (NGBT, Not (Local7), NGBT)
Release (BTMX)
Return (Zero)
}