481 lines
10 KiB
C
481 lines
10 KiB
C
#include "Batt.h"
|
|
#include "LenovoChargingLogo.h"
|
|
#include <Lfc.h>
|
|
#include <Library/LfcEcLib.h>
|
|
|
|
//#if PRODUCT_YOGA
|
|
/*EFI_STATUS
|
|
EcAcpiStall (
|
|
IN UINTN Microseconds
|
|
)
|
|
{
|
|
gBS->Stall(15);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
WaitIBE (
|
|
IN UINT16 CommandPort
|
|
)
|
|
{
|
|
UINT8 CmdPort = 0;
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < KBC_TIME_OUT; Index++) {
|
|
CmdPort = IoRead8 (CommandPort);
|
|
if (!(CmdPort & KEY_IBF)) {
|
|
return EFI_SUCCESS;
|
|
} else {
|
|
EcAcpiStall(15);
|
|
}
|
|
}
|
|
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
EFI_STATUS
|
|
WaitOBF (
|
|
IN UINT16 CommandPort
|
|
)
|
|
{
|
|
UINT8 CmdPort = 0;
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < KBC_TIME_OUT; Index++) {
|
|
CmdPort = IoRead8 (CommandPort);
|
|
if (CmdPort & KEY_OBF) {
|
|
return EFI_SUCCESS;
|
|
} else {
|
|
EcAcpiStall(15);
|
|
}
|
|
}
|
|
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
EFI_STATUS
|
|
WaitOBE (
|
|
IN UINT16 CommandPort
|
|
)
|
|
{
|
|
UINT8 CmdPort = 0;
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < KBC_TIME_OUT; Index++) {
|
|
CmdPort = IoRead8 (CommandPort);
|
|
if (CmdPort & KEY_OBF) {
|
|
//Read data out from data port
|
|
IoRead8 (CommandPort - 4);
|
|
} else {
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EcCommand (
|
|
IN UINT16 CommandPort,
|
|
IN UINT16 DataPort,
|
|
IN UINTN NumOfReturnData,
|
|
IN UINT8 *ReturnData,
|
|
IN UINT8 Command,
|
|
IN UINTN NumOfArgs,
|
|
...
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
VA_LIST Marker;
|
|
UINT8 Index;
|
|
UINT8 *Data;
|
|
|
|
Status = WaitIBE (CommandPort);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = WaitOBE (CommandPort);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
//Send command
|
|
IoWrite8 (CommandPort, Command);
|
|
|
|
Status = WaitIBE (CommandPort);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (NumOfArgs > 0){
|
|
VA_START (Marker, NumOfArgs);
|
|
for(Index = 0; Index < NumOfArgs; Index++){
|
|
Data = VA_ARG (Marker, UINT8*);
|
|
//Send data
|
|
IoWrite8 (DataPort, *Data);
|
|
|
|
Status = WaitIBE (CommandPort);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
VA_END (Marker);
|
|
//Get return data
|
|
}
|
|
|
|
if (NumOfReturnData > 0) {
|
|
for (Index = 0; Index < NumOfReturnData; Index++) {
|
|
Status = WaitOBF (CommandPort);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
*(ReturnData + Index) = IoRead8 (DataPort);
|
|
}
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
|
|
EFI_STATUS
|
|
EcRamRead(
|
|
IN UINT8 Index,
|
|
OUT UINT8 *Data
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data8;
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
1,
|
|
&Data8,
|
|
EC_READ_ECRAM_CMD,
|
|
1,
|
|
&Index);
|
|
*Data = Data8;
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
GetBatteryPercentage (
|
|
IN OUT UINT8 *BatteryPercentage
|
|
)
|
|
{
|
|
UINT16 RemainingCap, FullChargeCap;
|
|
EFI_STATUS Status;
|
|
UINT8 Data1 = 1, Data2 = 1, Data3 = 1, Data4 = 1;
|
|
|
|
|
|
Status = EcRamRead (0x6B, &Data1);
|
|
Status = EcRamRead (0x6A, &Data2);
|
|
Status = EcRamRead (0x6D, &Data3);
|
|
Status = EcRamRead (0x6C, &Data4);
|
|
|
|
DebugL(L"Function(GetBatteryPercentage) Data1,2,3,4 =%d,%d,%d,%d\r\n", Data1,Data2,Data3,Data4);
|
|
|
|
RemainingCap = (((UINT16)(Data1))<<8) + (UINT16)Data2;
|
|
FullChargeCap = (((UINT16)(Data3))<<8) + (UINT16)Data4;
|
|
|
|
//If battery not exist or battery error
|
|
if (FullChargeCap == 0 || 100*RemainingCap/FullChargeCap > 100) {
|
|
//If error
|
|
*BatteryPercentage = 15;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
*BatteryPercentage = (UINT8)(100*RemainingCap/FullChargeCap);
|
|
//if (*BatteryPercentage >=20 && *BatteryPercentage <= 30) {
|
|
// *BatteryPercentage = 15; //Make it under 20 to meet flashit's error condition
|
|
//}
|
|
return EFI_SUCCESS;
|
|
}
|
|
*/
|
|
/*Get AC status.*/
|
|
/*
|
|
Offset(0x40),
|
|
RPWR, 1, //(0x40)EC power flag 1 CCCADIN
|
|
// 0x40.0 AC adapter Status
|
|
// 0 - Non AC adapter
|
|
// 1 - AC adapter exist
|
|
*/
|
|
/*EFI_STATUS
|
|
GetACStatus (
|
|
UINT8 * ACStatus
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data = 0;
|
|
*/
|
|
/*Get AC Status.*/
|
|
/* Status = EcRamRead (0x40, &Data );
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if((Data &0x01) == 0)
|
|
*ACStatus = AC_NON_EXIST;
|
|
else
|
|
*ACStatus = AC_EXIST;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
*/
|
|
/*Get battery status.*/
|
|
/*
|
|
Offset(0x60),
|
|
B1ST, 1, //(0x60)Battery 1 status1 flag
|
|
// 0x60.0
|
|
// 0 -
|
|
// 1 - Battery 1 exist
|
|
BATT, 1, // 0x60.1 CCCB1VA
|
|
// 0 -
|
|
// 1 - Battery 1 battery idetify OK
|
|
B1IC, 1, // 0x60.2
|
|
// 0 -
|
|
// 1 - battery 1 in any charge phase
|
|
B1FU, 1, // 0x60.3
|
|
// 0 -
|
|
// 1 - Battery 1 fully charged
|
|
B1DI, 1, // 0x60.4
|
|
// 0 -
|
|
// 1 - Battery 1 in discharging
|
|
B1DE, 1, // 0x60.5
|
|
// 0 -
|
|
// 1 - Battery 1 fully discharged
|
|
B1AN, 1, // 0x60.6
|
|
// 0 -
|
|
// 1 - battery 1 abnormal
|
|
, 1, // 0x60.7 Reserved
|
|
*/
|
|
EFI_STATUS
|
|
GetBattStatus (
|
|
UINT8 * BattStatus
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data = 0;
|
|
/*Get battery Status.*/
|
|
//Status = EcRamRead (0x60, &Data );
|
|
//if (EFI_ERROR(Status)) {
|
|
// return Status;
|
|
//}
|
|
//Get battery exist status
|
|
Status = LfcEcLibEcRamRead (0xBE, &Data );
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
if((Data &0x01) == 0x00){ //bit0 ->Set if 1st battery present BA1P
|
|
*BattStatus = BATT_NON_EXIST;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//Get battery abnormal
|
|
Status = LfcEcLibEcRamRead (0x07, &Data );
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
if((Data &0x20) == 0x20){ //bit5 ->1: indicates the main battery is bad. BBAD
|
|
*BattStatus = BATT_ABNORMAL;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//Check battery Discharging or charging
|
|
Status = LfcEcLibEcRamRead (0xC1, &Data );
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
if((Data &0x02) == 0x02){ //bit1 -> indicate battery charging B1ST
|
|
*BattStatus = BATT_CHARGING;
|
|
return EFI_SUCCESS;
|
|
}
|
|
if((Data &0x01) == 0x01){ //bit0 -> indicate battery discharging B1ST
|
|
*BattStatus = BATT_DISCHARGING;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//Check battery full charging or full discharging
|
|
Status = LfcEcLibEcRamRead (0x88, &Data );
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
if((Data &0x20) == 0x20){ // FBFG
|
|
*BattStatus = BATT_FULL_CHARGED;
|
|
return EFI_SUCCESS;
|
|
}
|
|
if((Data &0x10) == 0x10){ // FBDC
|
|
*BattStatus = BATT_FULL_DISCHARGED;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
if((Data &0x01) == 0){
|
|
*BattStatus = BATT_NON_EXIST;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if((Data &0x40) == 0x40){
|
|
*BattStatus = BATT_ABNORMAL;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if((Data &0x04) == 0x04){
|
|
*BattStatus = BATT_CHARGING;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if((Data &0x08) == 0x08){
|
|
*BattStatus = BATT_FULL_CHARGED;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if((Data &0x10) == 0x10){
|
|
*BattStatus = BATT_DISCHARGING;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if((Data &0x20) == 0x20){
|
|
*BattStatus = BATT_FULL_DISCHARGED;
|
|
return EFI_SUCCESS;
|
|
}
|
|
*/
|
|
*BattStatus = BATT_UNKNOWN_STATUS;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
#else
|
|
|
|
EFI_STATUS
|
|
GetBatteryPercentage (
|
|
IN OUT UINT8 *BatteryPercentage
|
|
)
|
|
{
|
|
*BatteryPercentage = 10;
|
|
return EFI_SUCCESS;
|
|
}
|
|
*/
|
|
|
|
/*Get AC status.*/
|
|
/*EFI_STATUS
|
|
GetACStatus (
|
|
UINT8 * ACStatus
|
|
)
|
|
{*/
|
|
/*Get AC Status.*/
|
|
/* *ACStatus = AC_NON_EXIST;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
*/
|
|
/*Get battery status.*/
|
|
/*EFI_STATUS
|
|
GetBattStatus (
|
|
UINT8 * BattStatus
|
|
)
|
|
{*/
|
|
/*Get battery Status.*/
|
|
/* *BattStatus = BATT_UNKNOWN_STATUS;
|
|
return EFI_SUCCESS;
|
|
}
|
|
*/
|
|
/*EFI_STATUS
|
|
GetBattStatus (
|
|
UINT8 * BattStatus
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data = 0;*/
|
|
/*Get battery Status.*/
|
|
//Status = EcRamRead (0x60, &Data );
|
|
//if (EFI_ERROR(Status)) {
|
|
// return Status;
|
|
//}
|
|
//Get battery exist status
|
|
/* Status = LfcEcLibEcRamRead (0xBE, &Data );
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
if((Data &0x01) == 0x00){ //bit0 ->Set if 1st battery present
|
|
*BattStatus = BATT_NON_EXIST;
|
|
return EFI_SUCCESS;
|
|
}
|
|
*/
|
|
/* //Get battery abnormal
|
|
Status = LfcEcLibEcRamRead (0x07, &Data );
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
if((Data &0x20) == 0x20){ //bit5 ->1: indicates the main battery is bad.
|
|
*BattStatus = BATT_ABNORMAL;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//Check battery Discharging or charging
|
|
Status = LfcEcLibEcRamRead (0xC1, &Data );
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
if((Data &0x02) == 0x02){ //bit1 -> indicate battery charging
|
|
*BattStatus = BATT_CHARGING;
|
|
return EFI_SUCCESS;
|
|
}
|
|
if((Data &0x01) == 0x01){ //bit0 -> indicate battery discharging
|
|
*BattStatus = BATT_DISCHARGING;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//Check battery full charging or full discharging
|
|
Status = LfcEcLibEcRamRead (0x88, &Data );
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
if((Data &0x20) == 0x20){
|
|
*BattStatus = BATT_FULL_CHARGED;
|
|
return EFI_SUCCESS;
|
|
}
|
|
if((Data &0x10) == 0x10){
|
|
*BattStatus = BATT_FULL_DISCHARGED;
|
|
return EFI_SUCCESS;
|
|
}
|
|
*/
|
|
/*
|
|
if((Data &0x01) == 0){
|
|
*BattStatus = BATT_NON_EXIST;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if((Data &0x40) == 0x40){
|
|
*BattStatus = BATT_ABNORMAL;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if((Data &0x04) == 0x04){
|
|
*BattStatus = BATT_CHARGING;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if((Data &0x08) == 0x08){
|
|
*BattStatus = BATT_FULL_CHARGED;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if((Data &0x10) == 0x10){
|
|
*BattStatus = BATT_DISCHARGING;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if((Data &0x20) == 0x20){
|
|
*BattStatus = BATT_FULL_DISCHARGED;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
*BattStatus = BATT_UNKNOWN_STATUS;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
*/
|