3114 lines
68 KiB
C
3114 lines
68 KiB
C
/*****************************************************************************
|
|
*
|
|
*
|
|
* 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.
|
|
*
|
|
*****************************************************************************/
|
|
/*
|
|
Data Name Version Description
|
|
2014.04.23 dahai.zhou v1.00 Initial release it for EDK2 projects
|
|
2014.07.22 dahai.zhou v1.01 Add new routine LfcEcLibTellEcDisOrUma
|
|
2014.07.23 dahai.zhou v1.10 Unify all routine name to LfcEcLibXxxxx
|
|
2014.08.28 dahai.zhou v1.11 Use PCD to save NOVO button and crisis status
|
|
2015.02.02 cissie.gu v1.12 Fix the issue that OS will hung up when we use PcdLcfcEcLibSupport whose type is PcdsDynamicEx in SMM mode in OS runtime.
|
|
2015.03.26 cissie.gu v1.13 Add function named LfcEcLibEnableEcPower.
|
|
Make both of the functions, LfcEcLibNotifyEcMachineSize and LfcEcLibTellEcDisOrUma,functional.
|
|
2015.04.17 cissie.gu v1.14 Add two funciotions,one named LfcEcLibSetAlwaysOnUsbMode for BIOS to notify EC change usb charge mode,
|
|
another one named LfcEcLibGetBatteryFirstUsedDate for battery to get System time.
|
|
2015.06.03 dahai.zhou v1.15 Update EcCommand routine, and modify all code that call it
|
|
2015.07.14 dahai.zhou v1.16 Update LfcEcLibGetBatteryPercentage to remove workaround for Insyde
|
|
2016.09.23 cissie.gu v1.17 To make all kind of keyboards fully functional,we notify EC with four KeyboardIDs.
|
|
*/
|
|
|
|
#include <Uefi.h>
|
|
#include <Lfc.h>
|
|
#include <Library/LfcEcLib.h>
|
|
//[-start-211014-BAIN000051-add]//
|
|
#ifdef LCFC_SUPPORT
|
|
#include <Library/TimerLib.h>
|
|
#endif
|
|
//[-end-211014-BAIN000051-add]//
|
|
//[-start-211104-YUNLEI0152-modify]//
|
|
#if defined(C770_SUPPORT)
|
|
#include <Library/CpuInfoFruLib.h>
|
|
#include <Register/CommonMsr.h>
|
|
#include <Library/OemSvcLfcPeiGetBoardID.h>
|
|
#endif
|
|
//[-end-211104-YUNLEI0152-modify]//
|
|
BOOLEAN mLcfcEcLibSupport = TRUE;
|
|
|
|
//[-start-211014-YUNLEI0142-add]////For use PackageTdp to distinguish CPU U15/U28 U15:15 U28:28
|
|
#if defined(C770_SUPPORT)
|
|
EFI_STATUS
|
|
OemSvcLfcGetCpuIdentifier(
|
|
OUT UINT8 *LfcCpuId
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT16 PackageTdp;
|
|
UINT16 PackageTdpWatt;
|
|
UINT16 TempPackageTdp;
|
|
UINT8 ProcessorPowerUnit;
|
|
MSR_PACKAGE_POWER_SKU_REGISTER PackagePowerSkuMsr;
|
|
MSR_PACKAGE_POWER_SKU_UNIT_REGISTER PackagePowerSkuUnitMsr;
|
|
PackagePowerSkuMsr.Uint64 = AsmReadMsr64 (MSR_PACKAGE_POWER_SKU);
|
|
PackagePowerSkuUnitMsr.Uint64 = AsmReadMsr64 (MSR_PACKAGE_POWER_SKU_UNIT);
|
|
ProcessorPowerUnit = (UINT8) (PackagePowerSkuUnitMsr.Bits.PwrUnit);
|
|
if (ProcessorPowerUnit == 0) {
|
|
ProcessorPowerUnit = 1;
|
|
} else {
|
|
ProcessorPowerUnit = (UINT8) LShiftU64 (2, (ProcessorPowerUnit - 1));
|
|
if (IsSimicsEnvironment () && ProcessorPowerUnit == 0) {
|
|
ProcessorPowerUnit = 1;
|
|
}
|
|
}
|
|
TempPackageTdp = (UINT16) PackagePowerSkuMsr.Bits.PkgTdp;
|
|
PackageTdpWatt = (UINT16) DivU64x32 (TempPackageTdp, ProcessorPowerUnit);
|
|
PackageTdp = (PackageTdpWatt * 100);
|
|
if ((TempPackageTdp % ProcessorPowerUnit) !=0) {
|
|
PackageTdp += ((TempPackageTdp % ProcessorPowerUnit) * 100) / ProcessorPowerUnit;
|
|
}
|
|
*LfcCpuId=(UINT8)(PackageTdp/100);
|
|
Status = EFI_SUCCESS;
|
|
return Status;
|
|
}
|
|
#endif
|
|
//[-end-211014-YUNLEI0142-add]
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BaseLfcEcLibConstructor (
|
|
VOID
|
|
)
|
|
{
|
|
mLcfcEcLibSupport = PcdGetBool (PcdLcfcEcLibSupport);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
WaitIBE (
|
|
IN UINT16 CommandPort
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Wait for input buffer empty
|
|
|
|
Arguments:
|
|
|
|
CommandState - the Io to read.
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS - input buffer empty.
|
|
|
|
--*/
|
|
{
|
|
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
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Wait for output buffer full
|
|
|
|
Arguments:
|
|
|
|
CommandState - the Io to read.
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS - output buffer full.
|
|
|
|
--*/
|
|
{
|
|
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
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Wait for output buffer empty
|
|
|
|
Arguments:
|
|
|
|
CommandState - the Io to read.
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS - output buffer empty.
|
|
|
|
--*/
|
|
{
|
|
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);
|
|
EcAcpiStall(15);
|
|
} 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,
|
|
...
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
This function send command and data to EC.
|
|
|
|
Arguments:
|
|
|
|
CommandPort - EC command port
|
|
|
|
DataPort - EC data port
|
|
|
|
NumOfReturnData - Number for return data, 0 will not return data
|
|
|
|
*ReturnData - Pointer to return data if NumOfReturnData > 0, caller must make sure there is enough space
|
|
|
|
Command - EC command
|
|
|
|
NumOfArgs - Number of variable arguments for EC data
|
|
|
|
... - Variable argument(s),each contain a UINT8 EC data
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS - Command successfully finish.
|
|
--*/
|
|
{
|
|
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
|
|
EcAcpiStall (
|
|
IN UINTN Microseconds
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
Waits for at least the given number of microseconds.
|
|
|
|
Arguments:
|
|
|
|
Microseconds - Desired length of time to wait
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS - If the desired amount of time passed.
|
|
--*/
|
|
{
|
|
UINTN Ticks;
|
|
UINTN Counts;
|
|
UINT32 CurrentTick;
|
|
UINT32 OriginalTick;
|
|
UINT32 RemainingTick;
|
|
|
|
if (Microseconds == 0) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
OriginalTick = IoRead32 (ACPI_TIMER_ADDR) & 0x00FFFFFF;
|
|
|
|
CurrentTick = OriginalTick;
|
|
|
|
//
|
|
// The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
|
|
//
|
|
Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
|
|
//
|
|
// The loops needed by timer overflow
|
|
//
|
|
Counts = Ticks / ACPI_TIMER_MAX_VALUE;
|
|
//
|
|
// remaining clocks within one loop
|
|
//
|
|
RemainingTick = Ticks % ACPI_TIMER_MAX_VALUE;
|
|
//
|
|
// not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
|
|
// one I/O operation, and maybe generate SMI
|
|
//
|
|
while (Counts != 0) {
|
|
CurrentTick = IoRead32 (ACPI_TIMER_ADDR) & 0x00FFFFFF;
|
|
|
|
if (CurrentTick <= OriginalTick) {
|
|
Counts--;
|
|
}
|
|
|
|
OriginalTick = CurrentTick;
|
|
}
|
|
|
|
while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) {
|
|
OriginalTick = CurrentTick;
|
|
CurrentTick = (IoRead32 (ACPI_TIMER_ADDR) & 0x00FFFFFF);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcCleanUpKbcAndEcBuffer (
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
Clean up KBC and EC buffer before hand off to OS, avoid abnormal
|
|
behavior in OS, such as KB no function, shutdown...
|
|
|
|
Arguments:
|
|
|
|
N/A
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS - If the desired amount of time passed.
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
//Clean up EC 60/64 buffer
|
|
Status = WaitIBE (KBC_CMD_STATE);
|
|
if (EFI_ERROR (Status)) {
|
|
LfcLibLogError (LFC_LOG_CLEAR_EC_BUFFER_6064_IBE_ERROR);
|
|
}
|
|
|
|
Status = WaitOBE (KBC_CMD_STATE);
|
|
if (EFI_ERROR (Status)) {
|
|
LfcLibLogError (LFC_LOG_CLEAR_EC_BUFFER_6064_OBE_ERROR);
|
|
}
|
|
|
|
//Clean up EC 62/66 buffer
|
|
Status = WaitIBE (EC_CMD_STATE);
|
|
if (EFI_ERROR (Status)) {
|
|
LfcLibLogError (LFC_LOG_CLEAR_EC_BUFFER_6266_IBE_ERROR);
|
|
}
|
|
|
|
Status = WaitOBE (EC_CMD_STATE);
|
|
if (EFI_ERROR (Status)) {
|
|
LfcLibLogError (LFC_LOG_CLEAR_EC_BUFFER_6266_OBE_ERROR);
|
|
}
|
|
|
|
//Clean up EC 68/6C buffer
|
|
Status = WaitIBE (EC_CMD_STATE2);
|
|
if (EFI_ERROR (Status)) {
|
|
LfcLibLogError (LFC_LOG_CLEAR_EC_BUFFER_686C_IBE_ERROR);
|
|
}
|
|
|
|
Status = WaitOBE (EC_CMD_STATE2);
|
|
if (EFI_ERROR (Status)) {
|
|
LfcLibLogError (LFC_LOG_CLEAR_EC_BUFFER_686C_OBE_ERROR);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
Routine Description :
|
|
Notify EC to keep power.
|
|
Suggest to use this function before do fullreset in case shutdown when do fullret under DC in.
|
|
BIT 7: For command use to cut power bit (for BIOS Use Only).
|
|
*/
|
|
EFI_STATUS
|
|
LfcEcLibEnableEcPower (
|
|
)
|
|
{
|
|
UINT8 Data;
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//Enable EC power
|
|
Status = LfcEcLibEcRamRead(0xA1, &Data);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Data |= BIT7; //Set BIT7
|
|
LfcEcLibEcRamWrite(0xA1,Data); // EECP
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
Routine Description :
|
|
Notify EC Not Keep Power.
|
|
Suggest to use this function before do fullreset in case shutdown when do fullret under DC in.
|
|
BIT 6: For command use to cut power bit (For App Use Only).
|
|
BIT 7: For command use to cut power bit (for BIOS Use Only).
|
|
*/
|
|
EFI_STATUS
|
|
LfcEcLibDisableEcPower (
|
|
VOID
|
|
)
|
|
{
|
|
UINT8 Data;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//Disable EC power
|
|
LfcEcLibEcRamRead(0xA1, &Data);
|
|
Data &= (UINT8)~(BIT6|BIT7); // Clear BIT6 and BIT7
|
|
LfcEcLibEcRamWrite(0xA1,Data); // CCPW, EECP
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibPowerStateIsAc (
|
|
OUT BOOLEAN *PowerStateIsAc
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 AcStatus = TRUE;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// Get AC State bit
|
|
//
|
|
Status = LfcEcLibEcRamRead (0xA3, &AcStatus);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if ((AcStatus & (1 << 7)) == 0) { // ADPT
|
|
*PowerStateIsAc = FALSE;
|
|
} else {
|
|
*PowerStateIsAc = TRUE;
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/*
|
|
ECMajorVersion = 0 before golden, = 1 after golden
|
|
ECMinorVersion = xx in A7ECxxWW, display it with %02d
|
|
ECTestVersion = 00 for formal EC, non-zero (yy) for test EC, should display A7ECxxWW(Tyy) if non-zero
|
|
*/
|
|
EFI_STATUS
|
|
LfcEcLibReadEcVersion(
|
|
IN OUT UINT8 *EcMajorVersion,
|
|
IN OUT UINT8 *EcMinorVersion,
|
|
IN OUT UINT8 *EcTestVersion
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = WaitIBE (EC_CMD_STATE);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = WaitOBE (EC_CMD_STATE);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
//Send command
|
|
IoWrite8 (EC_CMD_STATE, GET_EC_REVISION_CMD);
|
|
|
|
Status = WaitIBE (EC_CMD_STATE);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = WaitOBF (EC_CMD_STATE);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
*EcMajorVersion = IoRead8 (EC_DATA);
|
|
WaitOBF (EC_CMD_STATE);
|
|
*EcMinorVersion = IoRead8 (EC_DATA);
|
|
|
|
WaitOBF (EC_CMD_STATE);
|
|
*EcTestVersion = IoRead8 (EC_DATA);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibGetTouchpadID (
|
|
IN OUT UINT8 *TouchpadID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get touchpad ID from EC.
|
|
|
|
Arguments:
|
|
|
|
Offset Eeprom offset
|
|
TouchpadID 1 - PS/2 Touch Pad of Elantech
|
|
2 - PS/2 Touch Pad of Synaptics
|
|
3 - PS/2 Touch Pad of ALPS
|
|
Returns:
|
|
|
|
EFI_SUCCESS - Get touchpad ID Success
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data = 0;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = LfcEcLibEcRamRead (0x8B, &Data); // TPDV
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
*TouchpadID = Data;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
EFI_STATUS
|
|
LfcEcLibGetBatterySerial (
|
|
IN OUT UINT8 *DataLength,
|
|
IN OUT UINT8 *DataBuffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get Battery Serial from EC.
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS - Get Battery Serial Success
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
if (*DataLength < 4) {
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
Status = LfcEcLibEcRamRead (MANUFACTURE_DATE_1, &(DataBuffer[0])); // B1DA
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Status = LfcEcLibEcRamRead (MANUFACTURE_DATE_0, &(DataBuffer[1])); // B1DA
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Status = LfcEcLibEcRamRead (SERIAL_NUMBER_1, &(DataBuffer[2])); // B1SN
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Status = LfcEcLibEcRamRead (SERIAL_NUMBER_0, &(DataBuffer[3])); // B1SN
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
*DataLength = 4;
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibGetBatteryPercentage (
|
|
IN OUT UINT8 *BatteryPercentage
|
|
)
|
|
{
|
|
UINT16 RemainingCap, FullChargeCap;
|
|
EFI_STATUS Status;
|
|
UINT8 Data1 = 1, Data2 = 1, Data3 = 1, Data4 = 1;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = LfcEcLibEcRamRead (REMAINING_CAPACITY_1, &Data1); // B1RC
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Status = LfcEcLibEcRamRead (REMAINING_CAPACITY_0, &Data2); // B1RC
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Status = LfcEcLibEcRamRead (FULL_CHARGE_CAPACITY_1, &Data3); // B1FC
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Status = LfcEcLibEcRamRead (FULL_CHARGE_CAPACITY_0, &Data4); // B1FC
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
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_DEVICE_ERROR;
|
|
}
|
|
|
|
*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;
|
|
}
|
|
|
|
//[-start-201125-WITAID0021-modify]//
|
|
#if defined(C970_SUPPORT) || defined(C770_SUPPORT) || defined(S77014_SUPPORT) || defined(S77013_SUPPORT) || defined(S570_SUPPORT) || defined(S370_SUPPORT) || defined(S77014IAH_SUPPORT)
|
|
/*++
|
|
//
|
|
//KeyboardID, follow Lenovo Yx60 darfon spec V1.2 in future.
|
|
//But still keep here in order to keep compliance with previous projects
|
|
//
|
|
--*/
|
|
|
|
EFI_STATUS
|
|
LfcEcLibNotifyEcKeyboardId (
|
|
IN UINT8 KeyboardID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
switch (KeyboardID) {
|
|
case 0x00:
|
|
EcData = EC_ENG_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x01:
|
|
EcData = EC_GRE_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x02:
|
|
EcData = EC_EUR_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x03:
|
|
EcData = EC_KOP_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x04:
|
|
EcData = EC_TCH_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x05:
|
|
EcData = EC_RUS_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x06:
|
|
EcData = EC_ARA_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x07:
|
|
EcData = EC_HBW_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x08:
|
|
EcData = EC_THA_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x09:
|
|
EcData = EC_HIN_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x10:
|
|
//[-start-220802-QINGLIN0171-add]//
|
|
#if defined(C970_SUPPORT) || defined(C770_SUPPORT) || defined(S77014_SUPPORT) || defined(S77013_SUPPORT)
|
|
case 'K':
|
|
case 'U':
|
|
#endif
|
|
//[-end-220802-QINGLIN0171-add]//
|
|
EcData = EC_UKE_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x11:
|
|
EcData = EC_ITA_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x12:
|
|
EcData = EC_SPA_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x13:
|
|
EcData = EC_TUR_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x14:
|
|
EcData = EC_POR_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x15:
|
|
EcData = EC_LAS_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x16:
|
|
EcData = EC_FRE_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x17:
|
|
EcData = EC_NOR_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x18:
|
|
//[-start-220802-QINGLIN0171-add]//
|
|
#if defined(C970_SUPPORT) || defined(C770_SUPPORT) || defined(S77014_SUPPORT) || defined(S77013_SUPPORT)
|
|
case 'F':
|
|
#endif
|
|
//[-end-220802-QINGLIN0171-add]//
|
|
EcData = EC_FRA_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x19:
|
|
EcData = EC_GER_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x20:
|
|
//[-start-220802-QINGLIN0171-add]//
|
|
#if defined(C970_SUPPORT) || defined(C770_SUPPORT) || defined(S77014_SUPPORT) || defined(S77013_SUPPORT)
|
|
case 'B':
|
|
#endif
|
|
//[-end-220802-QINGLIN0171-add]//
|
|
EcData = EC_BRL_KEYBOARD_MATRIX;
|
|
break;
|
|
//[-start-220824-Skywang0824-add]//
|
|
case 0xA0:
|
|
EcData = EC_BRL_Alexa_KEYBOARD_MATRIX;
|
|
break;
|
|
//[-End-220824-Skywang0824-add]//
|
|
case 0x21:
|
|
EcData = EC_HUN_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x22:
|
|
EcData = EC_BEL_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x23:
|
|
EcData = EC_ILD_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x24:
|
|
EcData = EC_SLV_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x25:
|
|
EcData = EC_SWS_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x26:
|
|
EcData = EC_BUL_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x27:
|
|
EcData = EC_CZE_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x28:
|
|
EcData = EC_ARF_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x29:
|
|
//[-start-220802-QINGLIN0171-add]//
|
|
#if defined(C970_SUPPORT) || defined(C770_SUPPORT) || defined(S77014_SUPPORT) || defined(S77013_SUPPORT)
|
|
case 'P':
|
|
case 'J':
|
|
#endif
|
|
//[-end-220802-QINGLIN0171-add]//
|
|
EcData = EC_JPN_KEYBOARD_MATRIX;
|
|
break;
|
|
case 0x30:
|
|
EcData = EC_UKR_KEYBOARD_MATRIX;
|
|
break;
|
|
//[-start-220321-YUNLEI0163-modify]//
|
|
#ifdef LCFC_SUPPORT
|
|
case 0x31:
|
|
//[-start-220802-QINGLIN0171-add]//
|
|
#if defined(C970_SUPPORT) || defined(C770_SUPPORT) || defined(S77014_SUPPORT) || defined(S77013_SUPPORT)
|
|
case 'S':
|
|
#endif
|
|
//[-end-220802-QINGLIN0171-add]//
|
|
EcData = EC_USA_KEYBOARD_MATRIX;
|
|
break;
|
|
#endif
|
|
//[-end-220321-YUNLEI0163-modify]//
|
|
default:
|
|
|
|
EcData = EC_ENG_KEYBOARD_MATRIX;
|
|
|
|
break;
|
|
}
|
|
//[-start-220415-SHAONN0032-modify]//
|
|
Status = EcCommand (
|
|
#ifdef S370_SUPPORT
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
#else
|
|
KBC_CMD_STATE,
|
|
KBC_DATA,
|
|
#endif
|
|
//[-end-220415-SHAONN0032-modify]//
|
|
0,
|
|
NULL,
|
|
EC_SYSTEM_NOTIFI_DARFON_CMD,
|
|
1,
|
|
&EcData);
|
|
|
|
return Status;
|
|
}
|
|
#else
|
|
/*++
|
|
//
|
|
//KeyboardID, 'P' 'K' will be removed in future.
|
|
//But still keep here in order to keep compliance with previous projects
|
|
//
|
|
--*/
|
|
|
|
EFI_STATUS
|
|
LfcEcLibNotifyEcKeyboardId (
|
|
IN UINT8 KeyboardID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
switch (KeyboardID) {
|
|
case 'B':
|
|
EcData = EC_EX_KEYBOARD_MATRIX;
|
|
break;
|
|
case 'S':
|
|
EcData = EC_US_KEYBOARD_MATRIX;
|
|
break;
|
|
case 'P':
|
|
case 'J':
|
|
EcData = EC_JP_KEYBOARD_MATRIX;
|
|
break;
|
|
case 'K':
|
|
case 'U':
|
|
EcData = EC_UK_KEYBOARD_MATRIX;
|
|
break;
|
|
case 'F':
|
|
EcData = EC_FR_KEYBOARD_MATRIX;
|
|
break;
|
|
default:
|
|
EcData = EC_US_KEYBOARD_MATRIX;
|
|
break;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
KBC_CMD_STATE,
|
|
KBC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_SYSTEM_NOTIFI_CMD,
|
|
1,
|
|
&EcData);
|
|
|
|
return Status;
|
|
}
|
|
#endif
|
|
//[-end-201125-WITAID0021-modify]//
|
|
|
|
/*
|
|
Routine Description :
|
|
Notify EC the Board ID (Size).
|
|
Arguments:
|
|
MachineSize -Board ID (Size). Value:14 means 14"
|
|
15 means 15"
|
|
17 means 17"
|
|
Return:
|
|
EFI_STATUS Value: EFI_SUCCESS means success
|
|
EFI_DEVICE_ERROR means timeout
|
|
*/
|
|
EFI_STATUS
|
|
LfcEcLibNotifyEcMachineSize (
|
|
IN UINT8 MachineSize
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE2,
|
|
EC_DATA2,
|
|
0,
|
|
NULL,
|
|
EC_SYSTEM_NOTIFI_MACHINE_SIZE_CMD,
|
|
1,
|
|
&MachineSize);
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibEcReboot (
|
|
IN UINT16 CommandPort,
|
|
IN UINT16 DataPort
|
|
)
|
|
{
|
|
UINT8 EcData;
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
EcData = 0xF7;
|
|
Status = EcCommand (
|
|
CommandPort,
|
|
DataPort,
|
|
0,
|
|
NULL,
|
|
0x59,
|
|
1,
|
|
&EcData);
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibEcShutdown (
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to shutdown the machine.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Returns:
|
|
|
|
SUCCESS as passed
|
|
Others as failed
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
EcData = EC_SYSTEM_NOTIFI_CMD_SHUTDOWN;
|
|
Status = EcCommand (
|
|
KBC_CMD_STATE,
|
|
KBC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_SYSTEM_NOTIFI_CMD,
|
|
1,
|
|
&EcData
|
|
);
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibEcReset (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
EcData = 0x01;
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
0x40,
|
|
1,
|
|
&EcData
|
|
);
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibAcInOutBeepControl (
|
|
IN BOOLEAN EnableEcBeep
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to turn on or off power beep.
|
|
|
|
Arguments:
|
|
|
|
PowerBeepEnable - TRUE: Enable AC in/out beep
|
|
FALSE: Disable AC in/out beep
|
|
|
|
Returns:
|
|
|
|
SUCCESS as passed
|
|
Others as failed
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (EnableEcBeep) {
|
|
EcData = BEEP_ENABLE_DATA;
|
|
} else {
|
|
EcData = BEEP_DISABLE_DATA;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_HOOK_CMD,
|
|
1,
|
|
&EcData
|
|
);
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibSetHotKeyMode (
|
|
IN UINT8 HotKeyMode
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data = 0;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = LfcEcLibEcRamRead (0xa1, &Data);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (HotKeyMode) {
|
|
if (Data & BIT3) {
|
|
Data &= (UINT8)~BIT3;
|
|
Status = LfcEcLibEcRamWrite (0xa1, Data); // HKDB
|
|
if (EFI_ERROR (Status)) {
|
|
}
|
|
}
|
|
} else {
|
|
if ((Data & BIT3) != BIT3) {
|
|
Data |= BIT3;
|
|
Status = LfcEcLibEcRamWrite (0xa1, Data); // HKDB
|
|
if (EFI_ERROR (Status)) {
|
|
}
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibSetAlwaysOnUsbMode (
|
|
IN UINT8 AlwaysOnUsbMode
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data = 0;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
Status = LfcEcLibEcRamRead (0x8a, &Data);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
if (AlwaysOnUsbMode) {
|
|
if ((Data & BIT1) != BIT1) {
|
|
Data |= BIT1;
|
|
Status = LfcEcLibEcRamWrite (0x8a, Data); // UCHE
|
|
}
|
|
|
|
} else {
|
|
if (Data & BIT1) {
|
|
Data &= (UINT8)~BIT1;
|
|
Status = LfcEcLibEcRamWrite (0x8a, Data); // UCHE
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibSetChargeInBatteryMode (
|
|
IN UINT8 ChargeInBatteryMode
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData = 0;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = LfcEcLibEcRamRead(0x8a, &EcData);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
if (ChargeInBatteryMode) {
|
|
if ((EcData & BIT6) != BIT6) {
|
|
EcData |= (UINT8)BIT6; //BIT6
|
|
Status = LfcEcLibEcRamWrite (0x8a, EcData); // CIBM
|
|
}
|
|
} else {
|
|
if (EcData & BIT6) {
|
|
EcData &= (UINT8)~BIT6; //BIT6
|
|
Status = LfcEcLibEcRamWrite (0x8a, EcData); // CIBM
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibSetOneKayBattery (
|
|
IN UINT8 OneKeyBattery
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData=0;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
LfcEcLibEcRamRead(0x8C, &EcData);
|
|
//[-start-210702-Dongxu0008-modify]//
|
|
if (OneKeyBattery) {
|
|
EcData |= (UINT8)BIT5; //BIT5
|
|
} else {
|
|
EcData &= (UINT8)~BIT5; //BIT5
|
|
}
|
|
//[-end-210702-Dongxu0008-modify]//
|
|
Status = LfcEcLibEcRamWrite(0x8C,EcData); // QCBX
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibCheckEcDebugFlag(
|
|
IN UINT16 CommandPort,
|
|
IN UINT16 DataPort,
|
|
IN BOOLEAN *EcDebugFlag
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data;
|
|
UINT8 EcData = GET_EC_DEBUGFLAG_DATA;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
*EcDebugFlag = FALSE;
|
|
|
|
Status = EcCommand (
|
|
CommandPort,
|
|
DataPort,
|
|
1,
|
|
&Data,
|
|
GET_EC_DEBUGFLAG_CMD,
|
|
1,
|
|
&EcData
|
|
);
|
|
if(EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
// Debug Flag == TRUE
|
|
if (Data & EC_DEBUGFLAG_TRUE) {
|
|
*EcDebugFlag = TRUE;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibDumpEcPostCode (
|
|
IN UINT16 CommandPort,
|
|
IN UINT16 DataPort,
|
|
IN UINT8 *OemPostCode
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Index;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = WaitIBE (CommandPort);
|
|
if(EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = WaitOBE (CommandPort);
|
|
if(EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
//Send command
|
|
IoWrite8 (CommandPort, GET_EC_POSTCODE_CMD);
|
|
Status = WaitIBE (CommandPort);
|
|
if(EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
for ( Index = 0; Index < EC_POSTCODE_MAX_LENGTH; Index ++ ) {
|
|
Status = WaitOBF (CommandPort);
|
|
if(EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
OemPostCode[Index] = IoRead8 (DataPort);
|
|
}
|
|
|
|
{
|
|
UINT8 Index1, Current, Temp, Buffer[EC_POSTCODE_MAX_LENGTH];
|
|
|
|
// OemPostCode[0] is for EC post code current index
|
|
Current = OemPostCode[0];
|
|
// Copy OemPostCode to Buffer
|
|
CopyMem(Buffer + 1, OemPostCode + 1, (EC_POSTCODE_MAX_LENGTH - 1));//Replace for loops with EDKII CopyMem.
|
|
//for (Index = 1; Index < EC_POSTCODE_MAX_LENGTH; Index ++) {
|
|
// Buffer[Index] = OemPostCode[Index];
|
|
//}
|
|
// Sort OemPostCode
|
|
for (Index1 = 1; Index1 < EC_POSTCODE_MAX_LENGTH; Index1 ++) {
|
|
Temp = Current + Index1;
|
|
if (Temp > (EC_POSTCODE_MAX_LENGTH - 1)) Temp -= (EC_POSTCODE_MAX_LENGTH - 1);
|
|
OemPostCode[Index1] = Buffer[Temp];
|
|
}
|
|
OemPostCode[0] = EC_POSTCODE_MAX_LENGTH - 1;
|
|
}
|
|
|
|
Status = WaitOBE (CommandPort);
|
|
if(EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = WaitIBE (CommandPort);
|
|
return Status;
|
|
}
|
|
|
|
/*
|
|
Routine Description :
|
|
Notify EC the graphic configuration,Discrete or Uma.
|
|
Arguments:
|
|
Dis12Uma0 -graphic configuration. Value:0 means Uma
|
|
1 means external graphic card:Nvidia
|
|
2 means external graphic card:Amd
|
|
Return:
|
|
EFI_STATUS Value: EFI_SUCCESS means success
|
|
EFI_DEVICE_ERROR means timeout
|
|
*/
|
|
EFI_STATUS
|
|
LfcEcLibTellEcDisOrUma (
|
|
IN UINT8 Uma0Nv1Amd2
|
|
)
|
|
{
|
|
UINT8 EcData;
|
|
//[-start-211104-YUNLEI0152-add]//
|
|
#if defined(C770_SUPPORT)
|
|
UINT8 PTdpCpuIdentifier;
|
|
UINT8 Panel_Size;
|
|
OemSvcLfcGetBoardID(PANEL_SIZE, &Panel_Size);
|
|
OemSvcLfcGetCpuIdentifier(&PTdpCpuIdentifier);
|
|
#endif
|
|
//[-end-211104-YUNLEI0152-add]//
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
//[-start-211104-YUNLEI0152-modify]//
|
|
#if defined(C770_SUPPORT)
|
|
if (Uma0Nv1Amd2 == 0) {
|
|
if(Panel_Size==PANEL_SIZE_14)
|
|
{
|
|
if(PTdpCpuIdentifier==0x0f)
|
|
{
|
|
EcData = 0xf3; //14 UMA U15
|
|
}
|
|
else {
|
|
EcData = 0xf4; //14 UMA U28
|
|
}
|
|
}else{
|
|
EcData = 0xe7; //16 Uma U28
|
|
}
|
|
}
|
|
else{
|
|
EcData = 0xf2; //16 dis H45
|
|
}
|
|
#else
|
|
if (Uma0Nv1Amd2 == 0) {
|
|
EcData = 0xe7; //Uma
|
|
} else if (Uma0Nv1Amd2 == 1) {
|
|
EcData = 0xf0; //Dis&Nvidia
|
|
} else if (Uma0Nv1Amd2 == 2) {
|
|
EcData = 0xf1; //Dis&Amd
|
|
} else if (Uma0Nv1Amd2 == 4) {
|
|
EcData = 0xf2;
|
|
}
|
|
#endif
|
|
//[-end-211104-YUNLEI0152-modify]//
|
|
|
|
return EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_HOOK_CMD,
|
|
1,
|
|
&EcData
|
|
);
|
|
}
|
|
|
|
|
|
EFI_STATUS
|
|
LfcEcLibGetRecoverMode (
|
|
OUT BOOLEAN *RecoverMode
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Check whether is recovery mode
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
TRUE - indicate the boot mode is recovery mode.
|
|
FALSE- indicate thd boot mode is not recovery mode.
|
|
|
|
--*/
|
|
{
|
|
// Lenovo SPEC requires to use FN+R as the crisis hot key, but I think
|
|
// that Novo button is one good Crisis hot key during bring up life phase.
|
|
#ifdef L05_CRISIS_HOTKEY_NOVO
|
|
BOOLEAN NovoStatus;
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = LfcEcLibGetNovoStatus (&NovoStatus);
|
|
if (EFI_ERROR (Status)) {
|
|
NovoStatus = FALSE;
|
|
}
|
|
if (NovoStatus) {
|
|
*RecoverMode = TRUE;
|
|
return EFI_SUCCESS;
|
|
}
|
|
*RecoverMode = FALSE;
|
|
return EFI_SUCCESS;
|
|
#else
|
|
EFI_STATUS Status;
|
|
UINT8 Data;
|
|
UINT8 EcData = EC_CRITICAL_STATUS;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (PcdGet8 (PcdCrisisStatus) != 0xff) {
|
|
// Restore crisis status from PCD
|
|
*RecoverMode = (BOOLEAN) (PcdGet8 (PcdCrisisStatus));
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
1,
|
|
&Data,
|
|
EC_PLATFORM_CMD,
|
|
1,
|
|
&EcData);
|
|
if (EFI_ERROR (Status)) {
|
|
*RecoverMode = FALSE;
|
|
return Status;
|
|
}
|
|
|
|
if (Data == EC_CRITICAL_STATUS_CRISIS_MODE) {
|
|
*RecoverMode = TRUE;
|
|
} else {
|
|
*RecoverMode = FALSE;
|
|
}
|
|
|
|
// Save crisis status into PCD
|
|
PcdSet8S (PcdCrisisStatus, (UINT8) (*RecoverMode));
|
|
|
|
return EFI_SUCCESS;
|
|
#endif
|
|
}
|
|
|
|
|
|
/*++
|
|
Routine Description:
|
|
|
|
Novo Status detect
|
|
|
|
Arguments:
|
|
INPUT - NONE
|
|
|
|
OUTPUT
|
|
BOOLEAN - TRUE : Novo Key pressed, FALSE : Novo Key not pressed
|
|
|
|
Returns:
|
|
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibGetNovoStatus (
|
|
OUT BOOLEAN *NovoKeyStatus
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData;
|
|
UINT8 Data;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (PcdGet8 (PcdNovoButtonStatus) != 0xff) {
|
|
// Restore NOVO button status from PCD
|
|
*NovoKeyStatus = (BOOLEAN) (PcdGet8 (PcdNovoButtonStatus));
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
// Don't need this,EcCommand already use this mechanism.
|
|
// Status = WaitIBE (EC_CMD_STATE);
|
|
// if (EFI_ERROR(Status)) {
|
|
// return Status;
|
|
// }
|
|
//
|
|
// Status = WaitOBE (EC_CMD_STATE);
|
|
// if (EFI_ERROR(Status)) {
|
|
// return Status;
|
|
// }
|
|
|
|
EcData = EC_DETECT_NOVO;
|
|
Status = EcCommand (
|
|
KBC_CMD_STATE,
|
|
KBC_DATA,
|
|
1,
|
|
&Data,
|
|
EC_HOOK_CMD,
|
|
1,
|
|
&EcData);
|
|
if (!EFI_ERROR (Status)) {
|
|
if(Data == 0x01) {
|
|
*NovoKeyStatus = TRUE;
|
|
} else {
|
|
*NovoKeyStatus = FALSE;
|
|
}
|
|
// Save NOVO button status into PCD
|
|
PcdSet8S (PcdNovoButtonStatus, (UINT8) (*NovoKeyStatus));
|
|
|
|
return EFI_SUCCESS;
|
|
} else {
|
|
*NovoKeyStatus = FALSE;
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibGetBatteryFirstUsedDate (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
UINT8 Data;
|
|
UINT8 EcData;
|
|
UINT8 Temp;
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
// 1. Get EC Battery First Used ready flag
|
|
EcData = EC_BATTERY_FIRST_USE_GET_FLAG;
|
|
Status = EcCommand (
|
|
EC_CMD_STATE2,
|
|
EC_DATA2,
|
|
1,
|
|
&Data,
|
|
EC_BATTERY_FIRST_USE_DATE_STATUS_CMD ,
|
|
1,
|
|
&EcData
|
|
);
|
|
|
|
if (Data == 1) {
|
|
// 2. Get CMOS time and Set to EC
|
|
IoWrite8(0x70,0x09);//Year
|
|
Temp = IoRead8(0x71);
|
|
Temp = ((Temp >> 4) & 0x0F)*10 + (Temp & 0x0F) + 20;//from 1980
|
|
EcData = EC_BATTERY_FIRST_USE_GET_YEAR;
|
|
Status = EcCommand (
|
|
EC_CMD_STATE2,
|
|
EC_DATA2,
|
|
0,
|
|
NULL,
|
|
EC_BATTERY_FIRST_USE_GET_TIME ,
|
|
2,
|
|
&EcData,
|
|
&Temp
|
|
);
|
|
|
|
IoWrite8(0x70,0x08);//Month
|
|
Temp = IoRead8(0x71);
|
|
Temp = ((Temp >> 4) & 0x0F)*10 + (Temp & 0x0F);
|
|
EcData = EC_BATTERY_FIRST_USE_GET_MONTH;
|
|
Status = EcCommand (
|
|
EC_CMD_STATE2,
|
|
EC_DATA2,
|
|
0,
|
|
NULL,
|
|
EC_BATTERY_FIRST_USE_GET_TIME ,
|
|
2,
|
|
&EcData,
|
|
&Temp
|
|
);
|
|
|
|
IoWrite8(0x70,0x07);//Date
|
|
Temp = IoRead8(0x71);
|
|
Temp = ((Temp >> 4) & 0x0F)*10 + (Temp & 0x0F);
|
|
EcData = EC_BATTERY_FIRST_USE_GET_DATE;
|
|
Status = EcCommand (
|
|
EC_CMD_STATE2,
|
|
EC_DATA2,
|
|
0,
|
|
NULL,
|
|
EC_BATTERY_FIRST_USE_GET_TIME ,
|
|
2,
|
|
&EcData,
|
|
&Temp
|
|
);
|
|
|
|
// 3. Set EC Battery First Used ready
|
|
EcData = EC_BATTERY_FIRST_USE_SET_READY;
|
|
Status = EcCommand (
|
|
EC_CMD_STATE2,
|
|
EC_DATA2,
|
|
0,
|
|
NULL,
|
|
EC_BATTERY_FIRST_USE_DATE_STATUS_CMD,
|
|
1,
|
|
&EcData
|
|
);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibEcInit (
|
|
VOID
|
|
)
|
|
{
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibEcWait (
|
|
IN BOOLEAN EnableWrites
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Platform specific function to enable flash / hardware for OEM EC
|
|
|
|
Arguments:
|
|
EnableWrites - Boolean to enable/disable wait
|
|
|
|
Returns:
|
|
EFI_SUCCESS
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData = EC_ENTER_IDLE_MODE;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_SYSTEM_NOTIFI_CMD,
|
|
1,
|
|
&EcData);
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibEcIdle (
|
|
IN BOOLEAN EnableWrites
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Platform specific function to enable flash / hardware for OEM EC
|
|
|
|
Arguments:
|
|
EnableWrites - Boolean to enable/disable idle
|
|
|
|
Returns:
|
|
EFI_SUCCESS
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData = EC_ENTER_IDLE_MODE;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_SYSTEM_NOTIFI_CMD,
|
|
1,
|
|
&EcData);
|
|
return Status;
|
|
}
|
|
|
|
|
|
EFI_STATUS
|
|
LfcEcLibEcRamRead(
|
|
IN UINT8 Index,
|
|
OUT UINT8 *Data
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data8;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
1,
|
|
&Data8,
|
|
EC_READ_ECRAM_CMD,
|
|
1,
|
|
&Index);
|
|
*Data = Data8;
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibEcRamWrite(
|
|
IN UINT8 Index,
|
|
IN UINT8 Value
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_WRITE_ECRAM_CMD,
|
|
2,
|
|
&Index,
|
|
&Value);
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibEcAcpiMode (
|
|
IN BOOLEAN EnableEcMode
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (EnableEcMode) {
|
|
EcData = EC_ACPI_MODE_EN_DATA;
|
|
} else {
|
|
EcData = EC_ACPI_MODE_DIS_DATA;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_SYSTEM_NOTIFI_CMD,
|
|
1,
|
|
&EcData);
|
|
|
|
Status = LfcCleanUpKbcAndEcBuffer ();
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibSaveRestoreKbc (
|
|
IN BOOLEAN SaveRestoreFlag
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function either writes to or read from KBC IO registers.
|
|
|
|
Arguments:
|
|
|
|
SaveRestoreFlag - True: write data to SMM KBC IO.
|
|
False: read data from IO to global registers.
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS - if read or write is successful.
|
|
|
|
--*/
|
|
{
|
|
UINT8 KbdIrqState = 0;
|
|
UINT8 SaveKbdIrqState = 0;
|
|
EFI_STATUS Status;
|
|
static UINT8 KbcCmdByte;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (SaveRestoreFlag) {
|
|
//
|
|
// Restore Keyboard command byte
|
|
//
|
|
Status = EcCommand (
|
|
KBC_CMD_STATE,
|
|
KBC_DATA,
|
|
0,
|
|
NULL,
|
|
KBC_WRITE_CMD_BYTE,
|
|
1,
|
|
&KbcCmdByte);
|
|
} else {
|
|
// Disable KBD IRQ
|
|
KbdIrqState = IoRead8 (IRQ_8259_MASK);
|
|
SaveKbdIrqState = KbdIrqState;
|
|
KbdIrqState |= 2;
|
|
IoWrite8 (IRQ_8259_MASK, KbdIrqState);
|
|
|
|
Status = EcCommand (
|
|
KBC_CMD_STATE,
|
|
KBC_DATA,
|
|
1,
|
|
&KbcCmdByte,
|
|
KBC_READ_CMD_BYTE,
|
|
0);
|
|
IoWrite8 (IRQ_8259_MASK, SaveKbdIrqState);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibDisableKeyBoard (
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine will set 0xAD Command to EC and
|
|
EC will disable KeyBoard.
|
|
|
|
Arguments:
|
|
|
|
VOID
|
|
|
|
Returns:
|
|
|
|
SUCCESS as passed
|
|
Others as failed
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = WaitIBE (KEY_CMD_STATE);
|
|
IoWrite8 (KEY_CMD_STATE, 0xAD);
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibPowerButtonControl (
|
|
IN BOOLEAN EnablePowerButton
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to turn on or off Power Button 4s.
|
|
|
|
Arguments:
|
|
|
|
EnablePowerButton - TRUE: Enable Power Button
|
|
FALSE: Disable Power Button
|
|
|
|
Returns:
|
|
|
|
SUCCESS as passed
|
|
Others as failed
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (EnablePowerButton) {
|
|
EcData = ENABLE_POWER_BUTTON;
|
|
} else {
|
|
EcData = DISABLE_POWER_BUTTON;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_HOOK_CMD,
|
|
1,
|
|
&EcData
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/*++
|
|
Routine Description :
|
|
Notify EC to start to light shine.
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibStartLight(
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
EcData = 0xb7;
|
|
Status = EcCommand (
|
|
EC_CMD_STATE2,
|
|
EC_DATA2,
|
|
0,
|
|
NULL,
|
|
0x55,
|
|
1,
|
|
&EcData);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/*++
|
|
Routine Description :
|
|
Notify EC to stop to light shine.
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibStopLight(
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
EcData = 0xb8;
|
|
Status = EcCommand (
|
|
EC_CMD_STATE2,
|
|
EC_DATA2,
|
|
0,
|
|
NULL,
|
|
0x55,
|
|
1,
|
|
&EcData);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/*++
|
|
Routine Description:
|
|
|
|
This routine is used to get hotkey F2/F12 during POST.
|
|
|
|
Arguments:
|
|
|
|
Selection - 0x00: KEY_NONE
|
|
0x01: KEY_F2
|
|
0x02: KEY_F12
|
|
|
|
Returns:
|
|
|
|
SUCCESS as passed
|
|
Others as failed
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibGetHotkeyFromEc(
|
|
IN OUT HOTKEY_TYPE *Selection
|
|
)
|
|
{
|
|
UINT8 Data = 0x00;
|
|
UINT8 Value = 0x00;
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (PcdGet8 (PcdHotkeyStatus) != 0xff) {
|
|
// Restore NOVO button status from PCD
|
|
*Selection = (HOTKEY_TYPE)(PcdGet8 (PcdHotkeyStatus));
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Status = LfcEcLibEcRamRead (POST_HOTKEY, &Data);
|
|
|
|
if (Status == EFI_SUCCESS){
|
|
Value = Data & (BIT1|BIT0);
|
|
switch(Value) {
|
|
case 0:
|
|
*Selection = KEY_NONE;
|
|
break;
|
|
case 1:
|
|
*Selection = KEY_F2;
|
|
break;
|
|
case 2:
|
|
*Selection = KEY_F12;
|
|
break;
|
|
default:
|
|
//EC always return one key value at any time and remove other key value,
|
|
//so never jump into default.
|
|
// Do Nothing
|
|
break;
|
|
}
|
|
// Save Hotkey value into PCD
|
|
PcdSet8S (PcdHotkeyStatus, (UINT8)(*Selection));
|
|
|
|
if(Value) {
|
|
Data &= ~(BIT1|BIT0);
|
|
Status = LfcEcLibEcRamWrite (POST_HOTKEY, Data);
|
|
}
|
|
return Status;
|
|
} else {
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
// Set Max Fan speed while flash BIOS
|
|
EFI_STATUS
|
|
LfcEcLibNotifyFanMaxSpeed()
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Cmd;
|
|
UINT8 Data;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Cmd = 0x59;
|
|
Data = 0x77;
|
|
Status = EcCommand (
|
|
0x66,
|
|
0x62,
|
|
FALSE,
|
|
NULL,
|
|
Cmd,
|
|
1,
|
|
&Data);
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibSwapFnCtrlMode (
|
|
IN UINT8 SwapMode
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data = 0;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = LfcEcLibEcRamRead (0xa1, &Data);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (SwapMode) {
|
|
if ((Data & BIT0) != BIT0) {
|
|
Data |= BIT0;
|
|
Status = LfcEcLibEcRamWrite (0xa1, Data); // FPFC
|
|
}
|
|
} else {
|
|
if (Data & BIT0) {
|
|
Data &= (UINT8)~BIT0;
|
|
Status = LfcEcLibEcRamWrite (0xa1, Data); // FPFC
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibSetPerformanceMode (
|
|
IN UINT8 PerformanceMode
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 EcData = 0;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
LfcEcLibEcRamRead (0x1D, &EcData);
|
|
|
|
if (PerformanceMode == QUIET_MODE) { //Quiet Mode
|
|
EcData = QUIET_MODE;
|
|
} else if (PerformanceMode == HIGH_PERFORMANCE_MODE) { //High Performance mode
|
|
EcData = HIGH_PERFORMANCE_MODE;
|
|
} else { //Balance Mode
|
|
EcData = BALANCE_MODE;
|
|
}
|
|
Status = LfcEcLibEcRamWrite (0x1D,EcData); // SPMO
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibSetFlipToBootMode (
|
|
IN UINT8 L05FlipToBoot
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data = 0;
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
Status = LfcEcLibEcRamRead (0x8d, &Data);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
if (L05FlipToBoot) {
|
|
if ((Data & BIT0) != BIT0) {
|
|
Data |= BIT0;
|
|
Status = LfcEcLibEcRamWrite (0x8d, Data);
|
|
}
|
|
} else {
|
|
if (Data & BIT0) {
|
|
Data &= (UINT8)~BIT0;
|
|
Status = LfcEcLibEcRamWrite (0x8d, Data);
|
|
}
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
//[-start-211222-JOYID00009-add]//
|
|
#if defined(C970_SUPPORT) || defined(C770_SUPPORT) || defined(S77013_SUPPORT) || defined(S77014_SUPPORT) || defined(S77014IAH_SUPPORT)
|
|
|
|
EFI_STATUS
|
|
LfcEcLibEnableWatchDogForMemoryTrainning (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
0x1B,
|
|
0);
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibDisableWatchDogForMemoryTrainning (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
0x1C,
|
|
0);
|
|
|
|
return Status;
|
|
}
|
|
#endif
|
|
//[-end-211222-JOYID00009-add]//
|
|
|
|
EFI_STATUS
|
|
LfcEcLibGetBatteryTimerCount (
|
|
IN OUT UINT16 *BatteryTimerCount
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get Battery Timer Count from EC - hours.
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS - Get Battery Timer Count Success
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data0 = 0, Data1 = 0;
|
|
UINT16 Data;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = LfcEcLibEcRamRead (BATTERY_TIMER_COUNT_L, &Data0); // BACT
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
Status = LfcEcLibEcRamRead (BATTERY_TIMER_COUNT_H, &Data1); // BACT
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Data = (((UINT16)(Data1))<<8) + (UINT16)Data0;
|
|
|
|
//If battery timer count is 0 or full
|
|
if (Data == 0 || Data == 0xFFFF) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
*BatteryTimerCount = Data;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
//[-start-220210-Dongxu0040-Modify]//
|
|
EFI_STATUS
|
|
LfcCheckValidTool (
|
|
OUT UINT8 *Data
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data8,ECCommand;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
ECCommand = 0x7F;
|
|
Status = EcCommand (
|
|
EC_CMD_STATE2,
|
|
EC_DATA2,
|
|
1,
|
|
&Data8,
|
|
ECCommand,
|
|
0
|
|
);
|
|
|
|
*Data = Data8;
|
|
return Status;
|
|
}
|
|
|
|
//[-end-220210-Dongxu0040-Modify]//
|
|
EFI_STATUS
|
|
|
|
LNVEcBatterySetting (
|
|
IN UINT8 Function,
|
|
IN UINT8 Action,
|
|
IN UINT8 ExValue
|
|
)
|
|
{
|
|
UINT8 Status =0;
|
|
UINT8 CMDData1 = 0, CMDData2 = 0;
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
switch (Function) { //function
|
|
case 0x01: //ship mode
|
|
if(Action == 1){ //enable
|
|
CMDData1 = EC_ENABLE_SHIPMODE_DATA;
|
|
}
|
|
break;
|
|
case 0x02: //conversation mode
|
|
if(Action == 1){ //enable
|
|
CMDData1 = EC_ENTER_CONVERSATIONMODE_DATA;
|
|
} else if(Action == 0) { //disable
|
|
CMDData1 = EC_EXIT_CONVERSATIONMODE_DATA;
|
|
} else {
|
|
CMDData1 = EC_CHECK_CONVERSATIONMODE_DATA;
|
|
}
|
|
break;
|
|
case 0x03: //first use data
|
|
if(Action == 1){ //clear first use data
|
|
CMDData1 = EC_CLEAR_FIRSTUSEDATA_DATA;
|
|
} else if(Action == 0) { //read first use data
|
|
CMDData1 = EC_CHECK_FIRSTUSEDATA_DATA;
|
|
}
|
|
break;
|
|
case 0x04: //LED control
|
|
switch(Action){
|
|
case 0x01: //power led on
|
|
CMDData1 = EC_OSCONTROL_POWERLEDON;
|
|
break;
|
|
case 0x10: //power led off
|
|
CMDData1 = EC_OSCONTROL_POWERLEDOFF;
|
|
break;
|
|
case 0x02: //charge led on
|
|
CMDData1 = EC_OSCONTROL_CHARGELEDON;
|
|
break;
|
|
case 0x20: //charge led off
|
|
CMDData1 = EC_OSCONTROL_CHARGELEDOFF;
|
|
break;
|
|
case 0x03: //discharge led on
|
|
CMDData1 = EC_OSCONTROL_DISCHARGELEDON;
|
|
break;
|
|
case 0x30: //discharge led off
|
|
CMDData1 = EC_OSCONTROL_DISCHARGELEDOFF;
|
|
break;
|
|
case 0x04: //numlock led on
|
|
CMDData1 = EC_OSCONTROL_NUMLOCKLEDON;
|
|
break;
|
|
case 0x40: //numlock led off
|
|
CMDData1 = EC_OSCONTROL_NUMLOCKLEDOFF;
|
|
break;
|
|
case 0x05: //capslock led on
|
|
CMDData1 = EC_OSCONTROL_CPSLOCKLEDON;
|
|
break;
|
|
case 0x50: //capslock led off
|
|
CMDData1 = EC_OSCONTROL_CPSLOCKLEDOFF;
|
|
break;
|
|
case 0x06: //KB backlight led on
|
|
CMDData1 = EC_OSCONTROL_KBBACKLIGHTLEDON;
|
|
break;
|
|
case 0x60: //KB backlight led off
|
|
CMDData1 = EC_OSCONTROL_KBBACKLIGHTLEDOFF;
|
|
break;
|
|
case 0x07: //FP led1 on
|
|
CMDData1 = EC_OSCONTROL_FPLED1ON;
|
|
break;
|
|
case 0x70: //FP led1 off
|
|
CMDData1 = EC_OSCONTROL_FPLED1OFF;
|
|
break;
|
|
case 0x08: //FP led2 on
|
|
CMDData1 = EC_OSCONTROL_FPLED2ON;
|
|
break;
|
|
case 0x80: //FP led2 off
|
|
CMDData1 = EC_OSCONTROL_FPLED2OFF;
|
|
break;
|
|
case 0x09: //Fn Lock led on
|
|
CMDData1 = EC_OSCONTROL_FNLOCKLED1ON;
|
|
break;
|
|
case 0x90: //Fn Lock led off
|
|
CMDData1 = EC_OSCONTROL_FNLOCKLED1OFF;
|
|
break;
|
|
case 0x0A: //All led off
|
|
CMDData1 = EC_OSCONTROL_ALLLEDOFF;
|
|
break;
|
|
case 0xA0: //All led on
|
|
CMDData1 = EC_OSCONTROL_ALLLEDON;
|
|
break;
|
|
case 0x0B: //All led control right back to EC
|
|
CMDData1 = EC_ALLLEDCONTROL_BACKTOEC;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case 0x05: //get CPU/GPU temp
|
|
CMDData1 = EC_GETCPUGPU_TEMP;
|
|
switch(Action){
|
|
case 0x01: //get CPU temp
|
|
CMDData2 = EC_GETCPU_TEMP_EXVALUE;
|
|
break;
|
|
case 0x02: //get GPU temp
|
|
CMDData2 = EC_GETGPU_TEMP_EXVALUE;
|
|
break;
|
|
case 0x03: //get near CPU temp
|
|
CMDData2 = EC_NEARCPU_TEMP_EXVALUE;
|
|
break;
|
|
case 0x04: //get near GPU temp
|
|
CMDData2 = EC_NEARGPU_TEMP_EXVALUE;
|
|
break;
|
|
case 0x05: //get charge temp
|
|
CMDData2 = EC_CHARGE_TEMP_EXVALUE;
|
|
break;
|
|
case 0x06: //get Environment temp
|
|
CMDData2 = EC_ENVIRONMENT_TEMP_EXVALUE;
|
|
break;
|
|
case 0x07: //get SSD temp
|
|
CMDData2 = EC_GETSSD_TEMP_EXVALUE;
|
|
break;
|
|
case 0x08: //get RAM temp
|
|
CMDData2 = EC_GETRAM_TEMP_EXVALUE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case 0x06:
|
|
switch(Action){
|
|
case 01: //set fan1 speed
|
|
CMDData1 = EC_SETFAN1_SPEED;
|
|
break;
|
|
case 02: //set fan2 speed
|
|
CMDData1 = EC_SETFAN2_SPEED;
|
|
break;
|
|
case 03: //get fan1 speed
|
|
CMDData1 = EC_GETFAN_SPEED;
|
|
break;
|
|
case 04: //get fan2 speed
|
|
CMDData1 = EC_GETFAN_SPEED;
|
|
break;
|
|
case 05: //set fan speed auto
|
|
CMDData1 = EC_FANCONTROL_TOEC;
|
|
break;
|
|
case 06: //get fan num
|
|
CMDData1 = EC_GET_FANNUM;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case 0x07: //check AC/DC status
|
|
switch(Action){
|
|
case 01: //check AC/DC status
|
|
CMDData1 = EC_CHECK_ACDC_MODE;
|
|
break;
|
|
case 02: //AC enable
|
|
CMDData1 = EC_ENABLE_AC;
|
|
break;
|
|
case 03: //AC disable
|
|
CMDData1 = EC_DISABLE_AC;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case 0x08: //Set battery charge/discharge capacity
|
|
switch(Action){
|
|
case 01: //Battery charge to 100% then discharge to require capacity level and keep
|
|
CMDData1 = EC_CHARGE_CAP;
|
|
break;
|
|
case 02: //Battery charge or discharge to require capacity level directly and keep
|
|
CMDData1 = EC_CHARGE_DISCHARGE_CAP;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case 0x09://auto power on from MFG ship mode
|
|
CMDData1 = EC_AUTOPOWERON;
|
|
break;
|
|
case 0x0A://Lid control
|
|
switch(Action){
|
|
case 01: //Lid disable
|
|
CMDData1 = EC_LID_DISABLE;
|
|
break;
|
|
case 02: //Lid enable
|
|
CMDData1 = EC_LID_ENABLE;
|
|
break;
|
|
case 03: //read Lid status
|
|
CMDData1 = EC_LID_STATUS;
|
|
break;
|
|
case 04: //read Lid open status
|
|
CMDData1 = EC_GETLIDOPEN_STATUS;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case 0x0B://Backlight control
|
|
switch(Action){
|
|
case 01: //Backlight control disable
|
|
CMDData1 = EC_BKL_DISABLE;
|
|
break;
|
|
case 02: //Backlight control enable
|
|
CMDData1 = EC_BKL_ENABLE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case 0x0C:
|
|
switch(Action){
|
|
case 01: //Enable scancode for power button test, (Button press scancode set1: E0 05, Button release scancode set1: E0 85)
|
|
CMDData1 = EC_EN_SCAN_PWRBUTTON_TEST;
|
|
break;
|
|
case 02: //Disable scancode for power button test
|
|
CMDData1 = EC_DIS_SCAN_PWRBUTTON_TEST;
|
|
break;
|
|
case 03:
|
|
Status = IoRead8(0x60);
|
|
goto exit;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case 0x0D:
|
|
switch(Action){
|
|
case 01: //Watch dog disable
|
|
CMDData1 = EC_WATCHDOG_DIS;
|
|
break;
|
|
case 02: //watchdog enable
|
|
CMDData1 = EC_WATCHDOG_EN;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case 0x0E: //Get PD FW Version
|
|
CMDData1 = EC_GET_PD_VERSION;
|
|
break;
|
|
case 0xED: //read EC ram
|
|
LfcEcLibEcRamRead (Action, &Status);
|
|
goto exit;
|
|
break;
|
|
case 0xEE: //write EC ram
|
|
LfcEcLibEcRamWrite (ExValue,Action);
|
|
goto exit;
|
|
break;
|
|
case 0xEF://manual command
|
|
CMDData1 = Action;
|
|
CMDData2 = ExValue;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if(CMDData2 == 0) {
|
|
CMDData2 = ExValue;
|
|
}
|
|
EcCommand (
|
|
EC_CMD_STATE2,
|
|
EC_DATA2,
|
|
1,
|
|
&Status,
|
|
EC_TOOl_CMD,
|
|
2,
|
|
&CMDData1,
|
|
&CMDData2);
|
|
exit:
|
|
return Status;
|
|
}
|
|
//[-start-200821-BAIN000035-add]//
|
|
//[-start-210903-YUNLEI0129-modify]//
|
|
//[-start-210906-SHAONN0005-modify]//
|
|
//[-start-211110-GEORGE0021-modify]//
|
|
//#if defined(C970_SUPPORT) || defined(C770_SUPPORT) || defined(S370_SUPPORT) || defined(S570_SUPPORT)
|
|
#ifdef LCFC_SUPPORT
|
|
//[-end-211110-GEORGE0021-modify]//
|
|
EFI_STATUS
|
|
LfcEcLibNotifyThermalMax()
|
|
{
|
|
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
UINT8 Command = 0x59;
|
|
UINT8 Data = 0x77;
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
Command,
|
|
1,
|
|
&Data);
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibNotifyThermalMaxStop()
|
|
{
|
|
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
UINT8 Command = 0x59;
|
|
UINT8 Data = 0x76;
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
Command,
|
|
1,
|
|
&Data);
|
|
|
|
return Status;
|
|
}
|
|
#endif
|
|
//[-end-210906-SHAONN0005-modify]//
|
|
//[-end-210903-YUNLEI0129-modify]//
|
|
//[-end-200821-BAIN000035-add]//
|
|
|
|
//[-start-210929-SHAONN0010-add]//
|
|
#if defined(S370_SUPPORT)
|
|
EFI_STATUS
|
|
LfcEcLibNotifyEcProjectType (
|
|
IN UINT8 ProjectType
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
switch(ProjectType){
|
|
// case 0x00 :
|
|
// ProjectType = 0x00;
|
|
// break;
|
|
// case 0x01 :
|
|
// ProjectType = 0x10;
|
|
// break;
|
|
case 0x02 :
|
|
ProjectType = 0x20;
|
|
break;
|
|
case 0x03 :
|
|
ProjectType = 0x40;
|
|
break;
|
|
default:
|
|
ProjectType = 0x00;
|
|
break;
|
|
}
|
|
|
|
LfcEcLibEcRamWrite(0xA2,0x00);
|
|
Status = LfcEcLibEcRamWrite(0xA2,ProjectType);
|
|
|
|
return Status;
|
|
}
|
|
#endif
|
|
//[-end-210929-SHAONN0010-add]//
|
|
//[-start-211014-BAIN000051-add]//
|
|
//#ifdef LCFC_SUPPORT
|
|
//#if defined(C970_BSH_SUPPORT)
|
|
//[-start-21119-TAMT000032-modify]//
|
|
//[-start-211203-QINGLIN0125-modify]//
|
|
//[-start-211206-OWENWU0029-modify]//
|
|
//[-start-211214-Ching000017-modify]//
|
|
#if defined(C970_BSH_SUPPORT) || defined(C770_BSH_SUPPORT) || defined(S77014_BSH_SUPPORT) || defined(S370_BSH_SUPPORT) || defined(S570_BSH_SUPPORT) || defined(S77013_BSH_SUPPORT) || defined(S77014IAH_BSH_SUPPORT)
|
|
//[-end-211214-Ching000017-modify]//
|
|
//[-end-211206-OWENWU0029-modify]//
|
|
//[-end-211203-QINGLIN0125-modify]//
|
|
/*++
|
|
Routine Description :
|
|
Notify EC to Set WDT Flag (EC power Off/8S reset set 15S WD,time out set top-swap pin flag, EC reset and power on) for Self-healing.
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibSetWDTFlagForSelfHealing (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data;
|
|
|
|
Status = LfcEcLibEcRamRead(0x22,&Data);
|
|
Data = Data | 0x01; //Set Bit0 = 1
|
|
Status = LfcEcLibEcRamWrite(0x22,Data);
|
|
//[-start-211027-JAYAN00004-remove]//
|
|
// MicroSecondDelay(2000000);
|
|
//[-end-21119-TAMT000032-modify]//
|
|
//[-end-211027-JAYAN00004-remove]
|
|
|
|
return Status;
|
|
}
|
|
|
|
/*++
|
|
Routine Description :
|
|
Notify EC to Disable current WDT and next boot follow 81for Self-healing.
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibDisableCurrentWDTForSelfHealing (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data;
|
|
|
|
Status = LfcEcLibEcRamRead(0x22,&Data);
|
|
Data = Data | 0x02; //Set Bit1 = 1
|
|
Status = LfcEcLibEcRamWrite(0x22,Data);
|
|
//[-start-211027-JAYAN00004-remove]//
|
|
// MicroSecondDelay(2000000);
|
|
//[-end-211027-JAYAN00004-remove]
|
|
|
|
return Status;
|
|
}
|
|
|
|
/*++
|
|
Routine Description :
|
|
Notify EC to always clear the WDT flag for Self-healing.
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibClearWDTFlagForSelfHealing (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data;
|
|
|
|
Status = LfcEcLibEcRamRead(0x22,&Data);
|
|
Data &= ~BIT0; //Set Bit0 = 0
|
|
Status = LfcEcLibEcRamWrite(0x22,Data);
|
|
//[-start-211027-JAYAN00004-remove]//
|
|
// MicroSecondDelay(2000000);
|
|
//[-end-211027-JAYAN00004-remove]
|
|
|
|
return Status;
|
|
}
|
|
|
|
/*++
|
|
Routine Description :
|
|
Notify EC to Disable Top-swap pin and always clear the Top-swap flag for Self-healing.
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibDisableAndClearTopSwapForSelfHealing (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data;
|
|
|
|
Status = LfcEcLibEcRamRead(0x22,&Data);
|
|
Data = Data | 0x08; //Set Bit3 = 1
|
|
Status = LfcEcLibEcRamWrite(0x22,Data);
|
|
//[-start-211027-JAYAN00004-remove]//
|
|
// MicroSecondDelay(2000000);
|
|
//[-end-211027-JAYAN00004-remove]
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/*++
|
|
Routine Description :
|
|
Notify EC to clear cmos pin for Self-healing.
|
|
Byte: 0X48
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibClearCmosForSelfHealing (
|
|
VOID
|
|
)
|
|
//[-start-211223-BAIN000072-modify]//
|
|
//[-start-211223-QINGLIN0132-modify]//
|
|
{
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
UINT8 Data = 0x01;
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_SET_CLEAN_CMOS,
|
|
1,
|
|
&Data);
|
|
return Status;
|
|
}
|
|
//[-end-211223-QINGLIN0132-modify]//
|
|
//[-end-211223-BAIN000072-modify]//
|
|
#endif
|
|
//[-end-211014-BAIN000051-add]//
|
|
|
|
//[-start-211231-JOYID00010-add]
|
|
//[-start-220117-QINGLIN0146-modify]//
|
|
//[-start-220119-OWENWU0036-modify]//
|
|
#if defined(C970_SUPPORT) || defined(C770_SUPPORT) || defined(S77013_SUPPORT) || defined(S77014_SUPPORT) || defined(S370_SUPPORT) || defined(S570_SUPPORT) || defined(S77014IAH_SUPPORT)
|
|
EFI_STATUS
|
|
LfcEcLibStopWDT (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data;
|
|
|
|
Status = LfcEcLibEcRamRead(0x22,&Data);
|
|
Data = Data | 0x10;//Set Bit4 = 1
|
|
Status = LfcEcLibEcRamWrite(0x22,Data);
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibStartWDT (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data;
|
|
|
|
Status = LfcEcLibEcRamRead(0x22,&Data);
|
|
Data &= ~BIT4; //Set Bit4 = 0
|
|
Status = LfcEcLibEcRamWrite(0x22,Data);
|
|
|
|
return Status;
|
|
}
|
|
#endif
|
|
//[-end-220119-OWENWU0036-modify]//
|
|
//[-end-220117-QINGLIN0146-modify]//
|
|
//[-end-211231-JOYID00010-add]
|
|
|
|
//[-start-211109-BAIN000054-add]//
|
|
#if defined(C970_SUPPORT)||defined(C770_SUPPORT)||defined(S77013_SUPPORT)||defined(S77014_SUPPORT)||defined(S77014IAH_SUPPORT)
|
|
/*++
|
|
Routine Description:
|
|
This routine will set 0x1D Command to EC and
|
|
EC will Enable/Disable PD Controller Mode
|
|
|
|
Arguments:
|
|
PdControllerMode Set 0x00 Disable PD_1 Disable PD_2 Controller Mode
|
|
Set 0x01 Enable PD_1 Disable PD_2 Controller Mode
|
|
Set 0x02 Disable PD_1 Enable PD_2 Controller Mode
|
|
Set 0x03 Enable PD_1 Enable PD_2 Controller Mode
|
|
Returns:
|
|
EFI_SUCCESS Command executed successfully
|
|
Other Command executed failed
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibSetPdControllerMode(
|
|
IN UINT8 PdControllerMode
|
|
)
|
|
{
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_SET_PD_MODE_CMD,
|
|
1,
|
|
&PdControllerMode);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/*++
|
|
Routine Description:
|
|
This routine will set 0x1D Command to EC and
|
|
EC will Enable/Disable PD Controller Mode
|
|
|
|
Arguments:
|
|
PdControllerModeBuffer Get 0x00 PD_1 Disable PD_2 Disable Controller Mode
|
|
Get 0x01 PD_1 Enable PD_2 Disable Controller Mode
|
|
Get 0x02 PD_1 Disable PD_2 Enable Controller Mode
|
|
Get 0x03 PD_1 Enable PD_2 Enable Controller Mode
|
|
Returns:
|
|
EFI_SUCCESS Command executed successfully
|
|
Other Command executed failed
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibGetPdControllerMode(
|
|
OUT UINT8 *PdControllerMode
|
|
)
|
|
{
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
UINT8 EcData = 0;
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
1,
|
|
&EcData,
|
|
EC_GET_PD_MODE_CMD,
|
|
0);
|
|
|
|
*PdControllerMode = EcData;
|
|
|
|
return Status;
|
|
}
|
|
|
|
//[-start-211227-BAIN000077-add]//
|
|
/*++
|
|
Routine Description:
|
|
This routine will set 0x1F Command to EC execute compliance mode.
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibSetCOMPLMode(
|
|
)
|
|
{
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
UINT8 Data = 0x07;
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_SET_COMPL_MODE_CMD,
|
|
1,
|
|
&Data);
|
|
|
|
return Status;
|
|
}
|
|
//[-end-211227-BAIN000077-add]//
|
|
|
|
#endif
|
|
//[-end-211109-BAIN000054-add]//
|
|
|
|
//[-start-211220-BAIN000070-add]//
|
|
#ifdef LCFC_SUPPORT
|
|
EFI_STATUS
|
|
LfcEcLibSetRestWDGCMD(
|
|
)
|
|
{
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
|
|
Status = EcCommand (
|
|
KBC_CMD_STATE,
|
|
KBC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_SET_WDG_REST_CMD,
|
|
0);
|
|
return Status;
|
|
}
|
|
#endif
|
|
//[-end-211220-BAIN000070-add]//
|
|
|
|
//[-start-220104-Dongxu0040-add]//
|
|
EFI_STATUS
|
|
LfcEcLibi7i5(
|
|
IN UINT8 CpuType
|
|
)
|
|
{
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_CPU_TYPE_CMD,
|
|
1,
|
|
&CpuType);
|
|
|
|
return Status;
|
|
}
|
|
//[-end-220104-Dongxu0040-add]//
|
|
|
|
//[-start-220120-QINGLIN0151-add]//
|
|
#if defined(S370_SUPPORT)
|
|
/*++
|
|
Routine Description:
|
|
This routine will notify EC CPU type.
|
|
|
|
Arguments:
|
|
CpuType 1 Celeron
|
|
2 Pentium
|
|
3 i3
|
|
5 i5
|
|
7 i7
|
|
Returns:
|
|
EFI_SUCCESS Command executed successfully
|
|
Other Command executed failed
|
|
--*/
|
|
EFI_STATUS
|
|
LfcEcLibNotifyEcCpuType (
|
|
IN UINT8 CpuType
|
|
)
|
|
{
|
|
EFI_STATUS Status = EFI_SUCCESS;
|
|
UINT8 EcData8 = 0;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (CpuType == 0x07) { //i7
|
|
EcData8 = 0xC7;
|
|
} else if (CpuType == 0x05) { //i5
|
|
EcData8 = 0xC5;
|
|
} else if (CpuType == 0x03) { //i3
|
|
EcData8 = 0xC3;
|
|
} else if (CpuType == 0x02) { //Pentium
|
|
EcData8 = 0xC2;
|
|
} else if (CpuType == 0x01) { //Celeron
|
|
EcData8 = 0xC1;
|
|
}
|
|
|
|
Status = EcCommand (
|
|
EC_CMD_STATE,
|
|
EC_DATA,
|
|
0,
|
|
NULL,
|
|
EC_CPU_TYPE_CMD,
|
|
1,
|
|
&EcData8);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
EFI_STATUS
|
|
LfcEcLibSetUltraQuietMode (
|
|
IN UINT8 UltraQuietMode
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data = 0;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = LfcEcLibEcRamRead (0x8D, &Data);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (UltraQuietMode) {
|
|
if ((Data & BIT5) != BIT5) {
|
|
Data |= BIT5;
|
|
Status = LfcEcLibEcRamWrite (0x8D, Data);
|
|
}
|
|
} else {
|
|
if (Data & BIT5) {
|
|
Data &= (UINT8)~BIT5;
|
|
Status = LfcEcLibEcRamWrite (0x8D, Data);
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
LfcEcLibSwitchFoolProofFnCtrl (
|
|
IN UINT8 FoolProofFnCtrl
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data = 0;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = LfcEcLibEcRamRead (0xA1, &Data);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (FoolProofFnCtrl) {
|
|
if ((Data & BIT0) != BIT0) {
|
|
Data |= BIT0;
|
|
Status = LfcEcLibEcRamWrite (0xA1, Data);
|
|
}
|
|
} else {
|
|
if (Data & BIT0) {
|
|
Data &= (UINT8)~BIT0;
|
|
Status = LfcEcLibEcRamWrite (0xA1, Data);
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
#endif
|
|
//[-end-220120-QINGLIN0151-add]//
|
|
|
|
//[-start-220407-JEPLIUT219-add]//
|
|
#if defined(S570_SUPPORT)
|
|
/*----------------------------------------------------------------
|
|
@Brief : LfcEcLibGetAdapter65WAcOnlyMode
|
|
@Descrip: Get the EC flag when adapter is 45W 65W & None battery at power on.
|
|
@Input : none
|
|
@Output : 1 = Available 0 = none
|
|
--------------------------------------------------------------- -*/
|
|
EFI_STATUS
|
|
LfcEcLibGetAdapter65WAcOnlyMode (
|
|
OUT UINT8 * Adapter65WAc
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Data = 0;
|
|
|
|
if (!mLcfcEcLibSupport) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
Status = LfcEcLibEcRamRead (0x23, &Data);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (Data & BIT1) {
|
|
*Adapter65WAc = 1;
|
|
}
|
|
else {
|
|
*Adapter65WAc = 0;
|
|
}
|
|
return Status;
|
|
}
|
|
#endif
|
|
//[-end-220407-JEPLIUT219-add]//
|