alder_lake_bios/Lcfc/LfcPkg/AcpiTable/Dsdt/Battery.asl

330 lines
11 KiB
Plaintext

//*****************************************************************************
//
// Copyright (c) 2012 - 2015, Hefei LCFC Information Technology Co.Ltd.
// And/or its affiliates. All rights reserved.
// Hefei LCFC Information Technology Co.Ltd. PROPRIETARY/CONFIDENTIAL.
// Use is subject to license terms.
//
//******************************************************************************
/*++
Abstract:
LCFC Battery common asl code definition, it's for all Hefei LBG projects.
History:
Date Name Version Change Notes
2014.07.29 Steven Wang V1.00 Initial Release.
2015.07.21 Steven Wang V1.01 Add OEM battery low and warning level policy value,
low = 4%, warning = %10.
2015.08.19 Steven Wang V1.02 Fixed the battery icon show empty issue in Lenovo setting.
2015.08.27 Steven Wang V1.03 Add ECAV for EC opregion access safely.
2015.10.23 Steven Wang V1.04 Add AMD support
2016.01.20 Steven Wang V1.05 Optimized battery information reading way from ACPI 62&66
to 68&6c, due to there is possibility that OS get the incorrect
value from EC by 62&66 when adding heavy loading, and cause unexpected
behavior.
2016.07.07 Steven Wang V1.06 When charging with battery capcity no full, average currency is 0, this is not normal status
need modify this value for Remaining Battery Life calculation from ACPI spec
2016.08.12 Steven Wang V1.07 Optimize the battery access method, due to 68 6C will conflict with some tool, change to 62 66
command method.
2018.04.01 Steven Wang V1.08 Fix the system battery charging to full time show 1 or 2 minutes issue when adding heavy loading w/ battery
capability not high
Module Name:
Battery.asl
Note:
You must take care about the prompt string "LCFCTODO:" and customize your
project.
--*/
Device(BAT0)
{
Name(_HID,EISAID("PNP0C0A"))
Name(_UID,0x01)
Name(_PCL,Package(0x01){
\_SB
})
Name(PBIF, Package() {
0x00000000, // Power Unit DWORD
0xFFFFFFFF, // Design Capacity DWORD, unknow capacity
0xFFFFFFFF, // Last Full Charge Capacity DWORD, unknow last full charged capacity
0x00000001, // Battery Technology DWORD
0xFFFFFFFF, // Design Voltage DWORD
0x00000000, // Design Capacity of Warning DWORD
0x00000000, // Design Capacity of Low DWORD
0x00000064, // Battery Capacity Granularity 1 DWORD
0x00000000, // Battery Capacity Granularity 2 DWORD
"LCFC", // Model Number ASCIIZ
"BAT20101001", // Serial Number ASCIIZ
"LiP", // Battery Type ASCIIZ
"LENOVO"}) // OEM Information ASCIIZ}
Name(XBIF, Package() {
0x00000001, // Revision Integer
0x00000000, // Power Unit DWORD
0xFFFFFFFF, // Design Capacity DWORD, unknow capacity
0xFFFFFFFF, // Last Full Charge Capacity DWORD, unknow last full charged capacity
0x00000001, // Battery Technology DWORD
0xFFFFFFFF, // Design Voltage DWORD
0x00000000, // Design Capacity of Warning DWORD
0x00000000, // Design Capacity of Low DWORD
0x00000000, // Cycle Count DWORD
95000, // Measurement Accuracy DWORD
0xFFFFFFFF, // Max Sampling Time DWORD (Unavailable)
0xFFFFFFFF, // Min Sampling Time DWORD (Unavailable)
1000, // Max Averaging Interval DWORD (MSFT No specific requirement. 1sec )
1000, // Min Averaging Interval DWORD (MSFT No specific requirement. 1sec )
0x00000064, // Battery Capacity Granularity 1 DWORD
0x00000000, // Battery Capacity Granularity 2 DWORD
"LCFC", // Model Number ASCIIZ
"BAT20101001", // Serial Number ASCIIZ
"LiP", // Battery Type ASCIIZ
"LENOVO", // OEM Information ASCIIZ
0x00000001}) // Battery Swapping Capability DWORD
Name(PBST,Package(0x04){
0x01,
0x0A90,
0x1000,
0x2A30
})
Method(_STA,0,NotSerialized)
{
If(LEqual(ECON,1))
{
If(EC0_SCOPE.EC0.ECAV){
If(LEqual(Acquire(EC0_SCOPE.EC0.LfcM, 0xA000),0x0)){
Store(EC0_SCOPE.EC0.BA1P,Local0)
Release(EC0_SCOPE.EC0.LfcM)
}
}
If(And(Local0,0x01))
{
Return(0x1F)
}
Else
{
Return(0x0F)
}
}
Else
{
Return(0x00)
}
}
Method(_BIF,0,NotSerialized)
{
If(LEqual(EC0_SCOPE.EC0.ECAV,1))
{
If(LEqual(Acquire(EC0_SCOPE.EC0.LfcM, 0xA000),0x0)){
Store(EC0_SCOPE.EC0.B1DC,Local0)
Multiply(Local0,10,Local0) // mWh(Units:10mWh)
Store(Local0,Index(PBIF,0x01))
Store(EC0_SCOPE.EC0.B1FC,Local0)
Multiply(Local0,10,Local0) // mWh(Units:10mWh)
Store(Local0,Index(PBIF,0x02))
Store(EC0_SCOPE.EC0.B1DV,Index(PBIF,0x04))
If(EC0_SCOPE.EC0.B1FC)
{
Store(Divide(Multiply(EC0_SCOPE.EC0.B1FC, 10),10), Index(PBIF,5))
Store(Divide(Multiply(EC0_SCOPE.EC0.B1DC, 10),100), Index(PBIF,7))
}
Store("", Index(PBIF, 0x09)) // Device Name or Model number
Store("", Index(PBIF, 0x0A)) // Serial Number
Store("", Index(PBIF, 0x0B)) // Device Chemistry
Store("", Index(PBIF, 0x0C)) // Manufaturer name
Name (BDNT, Buffer(9) {0x00})
Store(EC0_SCOPE.EC0.BDN0, BDNT)
Store(ToString(BDNT), Index(PBIF, 0x09)) // Device Name or Model number
//
// Serial Number
//
Store(EC0_SCOPE.EC0.B1SN, Local0)
//
// Prepare Buffer for Serial Number. Since it should be 0-0xFFFF,
// assume 5 bytes length
//
Name( SERN, Buffer(){0x20,0x20,0x20,0x20,0x20,0x00})
Store(4, Local2)
While(Local0) {
Divide(Local0, 10, Local1,Local0)
Add(Local1,0x30, Index(SERN,Local2))
Decrement(Local2)
}
Store(SERN, Index(PBIF, 0x0A)) // Serial Number
// Device chemistry
Name (DCH0, Buffer(10) {0x00})
Name (DCH1, "LION")
Name (DCH2, "LiP")
If (LEqual(EC0_SCOPE.EC0.B1TY, 1))
{
Store(DCH1, DCH0)
Store(ToString(DCH0), Index(PBIF, 0x0B))
}
Else
{
Store(DCH2, DCH0)
Store(ToString(DCH0), Index(PBIF, 0x0B))
}
Name (BMNT, Buffer(10) {0x00})
Store(EC0_SCOPE.EC0.BMN0, BMNT)
Store(ToString(BMNT), Index(PBIF, 0x0C)) // Manufaturer name
Release(EC0_SCOPE.EC0.LfcM)
}
}
Return(PBIF)
}
Method(_BIX,0,NotSerialized)
{
If(LEqual(EC0_SCOPE.EC0.ECAV,1))
{
If(LEqual(Acquire(EC0_SCOPE.EC0.LfcM, 0xA000),0x0)){
Store(EC0_SCOPE.EC0.B1DC,Local0)
Multiply(Local0,10,Local0) // mWh(Units:10mWh)
Store(Local0,Index(XBIF,0x02))
Store(EC0_SCOPE.EC0.B1FC,Local0)
Multiply(Local0,10,Local0) // mWh(Units:10mWh)
Store(Local0,Index(XBIF,0x03))
Store(EC0_SCOPE.EC0.B1DV,Index(XBIF,0x05))
If(EC0_SCOPE.EC0.B1FC)
{
Store(Divide(Multiply(EC0_SCOPE.EC0.B1FC, 10),10), Index(XBIF,6))
Store(Divide(Multiply(EC0_SCOPE.EC0.B1DC, 10),100), Index(XBIF,0x0E))
}
Store(EC0_SCOPE.EC0.B1CT,Index(XBIF,0x08)) //Cycle Count
Store("", Index(XBIF, 0x10)) // Device Name or Model number
Store("", Index(XBIF, 0x11)) // Serial Number
Store("", Index(XBIF, 0x12)) // Device Chemistry
Store("", Index(XBIF, 0x13)) // Manufaturer name
Name (BDNT, Buffer(9) {0x00})
Store(EC0_SCOPE.EC0.BDN0, BDNT)
Store(ToString(BDNT), Index(XBIF, 0x10)) // Device Name or Model number
//
// Serial Number
//
Store(EC0_SCOPE.EC0.B1SN, Local0)
//
// Prepare Buffer for Serial Number. Since it should be 0-0xFFFF,
// assume 5 bytes length
//
Name( SERN, Buffer(){0x20,0x20,0x20,0x20,0x20,0x00})
Store(4, Local2)
While(Local0) {
Divide(Local0, 10, Local1,Local0)
Add(Local1,0x30, Index(SERN,Local2))
Decrement(Local2)
}
Store(SERN, Index(XBIF, 0x11)) // Serial Number
// Device chemistry
Name (DCH0, Buffer(10) {0x00})
Name (DCH1, "LION")
Name (DCH2, "LiP")
If (LEqual(EC0_SCOPE.EC0.B1TY, 1))
{
Store(DCH1, DCH0)
Store(ToString(DCH0), Index(XBIF, 0x12))
}
Else
{
Store(DCH2, DCH0)
Store(ToString(DCH0), Index(XBIF, 0x12))
}
Name (BMNT, Buffer(10) {0x00})
Store(EC0_SCOPE.EC0.BMN0, BMNT)
Store(ToString(BMNT), Index(XBIF, 0x13)) // Manufaturer name
Release(EC0_SCOPE.EC0.LfcM)
}
}
Return(XBIF)
}
Name (OBST, 0) // Battery Status
Name (OBAC, 0) // Battery Average Current
Name (OBPR, 0) // Battery Present Rate
Name (OBRC, 0) // Battery Remaining Capacity
Name (OBPV, 0) // Battery Present Voltage
Method(_BST,0,NotSerialized)
{
If(LEqual(EC0_SCOPE.EC0.ECAV,1))
{
If(LEqual(Acquire(EC0_SCOPE.EC0.LfcM, 0xA000),0x0)){
Sleep(16)
Store(EC0_SCOPE.EC0.B1ST, Local0)
Store(DeRefOf(Index(PBST,0x00)), Local1)
switch(And(Local0,0x07))
{
case(0)
{
Store(And(Local1,0xF8),OBST)
}
case(1)
{
Store(Or(0x01,And(Local1,0xF8)),OBST)
}
case(2)
{
Store(Or(0x02,And(Local1,0xF8)),OBST)
}
case(4)
{
Store(Or(0x04,And(Local1,0xF8)),OBST)
}
}
Sleep(16)
Store(EC0_SCOPE.EC0.B1AC, OBAC)
If(And(OBST,0x01)) // Check discharging status
{
If(LNotEqual(OBAC,Zero))
{
Store(And(Not(OBAC),0x7FFF),OBAC)
}
} Else { // Charging status
If(LNotEqual(EC0_SCOPE.EC0.FBFG,1)) {
If(And(OBAC,0x8000)) {
// When charging with battery capacity no full w/heavy loading, the total system required power may be over the
// adapter output power,cause battery discharge to prevent the power overloading shutdown,
// the average currency is negative, need modify this value for Remaining Battery Life calculation from ACPI spec
// and the battery charging to full time calculation.
Store(0,OBAC)
}
}
}
Sleep(16)
Store(EC0_SCOPE.EC0.B1RC, OBRC)
Sleep(16)
Store(EC0_SCOPE.EC0.B1FV, OBPV)
Multiply(OBRC,10,OBRC) // mWh(Units:10mWh)
Store(Divide(Multiply(OBAC,OBPV),1000),OBPR) // Convert mAh and mV to mWh
Store(OBST,Index(PBST,0x00))
Store(OBPR,Index(PBST,0x01))
Store(OBRC,Index(PBST,0x02))
Store(OBPV,Index(PBST,0x03))
Release(EC0_SCOPE.EC0.LfcM)
}
}
Return(PBST)
}
}