330 lines
11 KiB
Plaintext
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)
|
|
}
|
|
}
|