/* SPDX-License-Identifier: GPL-2.0-only */ Field(ERAM, ByteAcc, NoLock, Preserve) { Offset (0x38), B0ST, 4, /* Battery 0 state */ , 1, B0CH, 1, /* Battery 0 charging */ B0DI, 1, /* Battery 0 discharging */ B0PR, 1, /* Battery 0 present */ Offset (0x39), B1ST, 4, /* Battery 1 state */ , 1, B1CH, 1, /* Battery 1 charging, */ B1DI, 1, /* Battery 1 discharging,*/ B1PR, 1 /* Battery 1 present */ } /* EC Registers */ /* PAGE == 0x00 */ Field (ERAM, ByteAcc, NoLock, Preserve) { Offset(0xa0), BARC, 16, /* Battery remaining capacity */ BAFC, 16, /* Battery full charge capacity */ Offset(0xa8), BAPR, 16, /* Battery present rate */ BAVO, 16, /* Battery Voltage */ } /* PAGE == 0x01 */ Field (ERAM, ByteAcc, NoLock, Preserve) { Offset(0xa0), , 15, BAMA, 1, } /* PAGE == 0x02 */ Field (ERAM, ByteAcc, NoLock, Preserve) { Offset(0xa0), BADC, 16, /* Design Capacity */ BADV, 16, /* Design voltage */ , 16, , 16, , 16, BASN, 16, } /* PAGE == 0x04: Battery type */ Field (ERAM, ByteAcc, NoLock, Preserve) { Offset(0xa0), BATY, 32 } /* PAGE == 0x05: Battery OEM information */ Field (ERAM, ByteAcc, NoLock, Preserve) { Offset(0xa0), BAOE, 128 } /* PAGE == 0x06: Battery name */ Field (ERAM, ByteAcc, NoLock, Preserve) { Offset(0xa0), BANA, 128 } /* * Switches the battery information page (16 bytes ERAM @0xa0) with an * optional compile-time delay. * * Arg0: * bit7-4: Battery number * bit3-0: Information page number */ Method(BPAG, 1, NotSerialized) { PAGE = Arg0 #ifdef BATTERY_PAGE_DELAY_MS Sleep(BATTERY_PAGE_DELAY_MS) #endif } /* Arg0: Battery * Arg1: Battery Status Package * Arg2: charging * Arg3: discharging */ Method(BSTA, 4, NotSerialized) { Acquire(ECLK, 0xffff) Local0 = 0 ^BPAG(Arg0 | 1) Local1 = BAMA ^BPAG(Arg0) /* Battery dynamic information */ /* * Present rate is a 16bit signed int, positive while charging * and negative while discharging. */ Local2 = BAPR If (Arg2) // Charging { Local0 |= 2 } Else { If (Arg3) // Discharging { Local0 |= 1 // Negate present rate Local2 = 0x10000 - Local2 } Else // Full battery, force to 0 { Local2 = 0 } } /* * The present rate value must be positive now, if it is not we have an * EC bug or inconsistency and force the value to 0. */ If (Local2 >= 0x8000) { Local2 = 0 } Arg1 [0] = Local0 if (Local1) { Arg1 [2] = BARC * 10 Local2 *= BAVO Arg1 [1] = Local2 / 1000 } else { Arg1 [2] = BARC Arg1 [1] = Local2 } Arg1 [3] = BAVO Release(ECLK) Return (Arg1) } Method(BINF, 2, Serialized) { Acquire(ECLK, 0xffff) ^BPAG(Or(1, Arg1)) /* Battery 0 static information */ Arg0 [0] = BAMA ^ 1 Local0 = BAMA ^BPAG(Arg1) Local2 = BAFC ^BPAG(Arg1 | 2) Local1 = BADC if (Local0) { Local1 *= 10 Local2 *= 10 } Arg0 [1] = Local1 // Design Capacity Arg0 [2] = Local2 // Last full charge capacity Arg0 [4] = BADV // Design Voltage Local0 = Local2 % 20 // FIXME: Local0 not used Arg0 [5] = Local2 / 20 // Warning capacity Local0 = BASN Name (SERN, Buffer (0x06) { " " }) Local1 = 4 While (Local0) { Local2 = Local0 % 10 Local0 /= 10 SERN [Local1] = Local2 + 48 Local1-- } Arg0 [10] = SERN // Serial Number ^BPAG(Or(4, Arg1)) Name (TYPE, Buffer() { 0, 0, 0, 0, 0 }) TYPE = BATY Arg0 [11] = TYPE // Battery type ^BPAG(Arg1 | 5) Arg0 [12] = BAOE // OEM information ^BPAG(Arg1 | 6) Arg0 [9] = BANA // Model number Release(ECLK) Return (Arg0) } Device (BAT0) { Name (_HID, EisaId ("PNP0C0A")) Name (_UID, 0x00) Name (_PCL, Package () { \_SB }) Name (BATS, Package () { 0x00, // 0: PowerUnit: Report in mWh 0xFFFFFFFF, // 1: Design cap 0xFFFFFFFF, // 2: Last full charge cap 0x01, // 3: Battery Technology 10800, // 4: Design Voltage (mV) 0x00, // 5: Warning design capacity 200, // 6: Low design capacity 1, // 7: granularity1 1, // 8: granularity2 "", // 9: Model number "", // A: Serial number "", // B: Battery Type "" // C: OEM information }) Method (_BIF, 0, NotSerialized) { Return (BINF(BATS, 0)) } Name (BATI, Package () { 0, // Battery State // Bit 0 - discharge // Bit 1 - charge // Bit 2 - critical state 0, // Battery present Rate 0, // Battery remaining capacity 0 // Battery present voltage }) Method (_BST, 0, NotSerialized) { if (B0PR) { Return (BSTA(0, BATI, B0CH, B0DI)) } else { Return (Package () { 0, 0, 0, 0 }) } } Method (_STA, 0, NotSerialized) { if (B0PR) { Return (0x1f) } else { Return (0x0f) } } } Device (BAT1) { Name (_HID, EisaId ("PNP0C0A")) Name (_UID, 0x00) Name (_PCL, Package () { \_SB }) Name (BATS, Package () { 0x00, // 0: PowerUnit: Report in mWh 0xFFFFFFFF, // 1: Design cap 0xFFFFFFFF, // 2: Last full charge cap 0x01, // 3: Battery Technology 10800, // 4: Design Voltage (mV) 0x00, // 5: Warning design capacity 200, // 6: Low design capacity 1, // 7: granularity1 1, // 8: granularity2 "", // 9: Model number "", // A: Serial number "", // B: Battery Type "" // C: OEM information }) Method (_BIF, 0, NotSerialized) { Return (BINF(BATS, 0x10)) } Name (BATI, Package () { 0, // Battery State // Bit 0 - discharge // Bit 1 - charge // Bit 2 - critical state 0, // Battery present Rate 0, // Battery remaining capacity 0 // Battery present voltage }) Method (_BST, 0, NotSerialized) { if (B1PR) { Return (BSTA(0x10, BATI, B1CH, B1DI)) } else { Return (Package () { 0, 0, 0, 0 }) } } Method (_STA, 0, NotSerialized) { if (B1PR) { Return (0x1f) } else { Return (0x0f) } } } /* Battery 0 critical */ Method(_Q24, 0, NotSerialized) { Notify(BAT0, 0x80) } /* Battery 1 critical */ Method(_Q25, 0, NotSerialized) { Notify(BAT1, 0x80) } /* Battery 0 attach/detach */ Method(_Q4A, 0, NotSerialized) { Notify(BAT0, 0x81) } /* Battery 0 state change */ Method(_Q4B, 0, NotSerialized) { Notify(BAT0, 0x80) } /* Battery 1 attach/detach */ Method(_Q4C, 0, NotSerialized) { Notify(BAT1, 0x81) } /* Battery 1 state change */ Method(_Q4D, 0, NotSerialized) { Notify(BAT1, 0x80) }