alder_lake_bios/Lcfc/LfcPkg/Library/BaseLfcEcLib/EcLib.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]//