/** @file
This file contains routines for GPIO native and chipset specific purpose
used by Reference Code only.
Copyright (c) 2019 Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "GpioNativePrivateLibInternal.h"
#include
#include
#include
/**
This function sets SerialIo I2C controller pins into native mode
@param[in] SerialIoI2cControllerNumber I2C controller
@param[in] GpioTermination GPIO termination type
@retval Status
**/
EFI_STATUS
GpioEnableSerialIoI2c (
IN UINT32 SerialIoI2cControllerNumber,
IN GPIO_ELECTRICAL_CONFIG GpioTermination
)
{
EFI_STATUS Status;
UINT32 Index;
GPIO_PAD_NATIVE_FUNCTION *I2cGpio;
GPIO_CONFIG GpioConfig;
GpioGetSerialIoI2cPins (
SerialIoI2cControllerNumber,
&I2cGpio
);
if (I2cGpio == NULL) {
return EFI_UNSUPPORTED;
}
ZeroMem(&GpioConfig, sizeof(GPIO_CONFIG));
GpioConfig.ElectricalConfig = GpioTermination;
for (Index = 0; Index < PCH_SERIAL_IO_PINS_PER_I2C_CONTROLLER; Index++) {
GpioConfig.PadMode = I2cGpio[Index].Mode;
Status = GpioSetPadConfig(I2cGpio[Index].Pad, &GpioConfig);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function sets SerialIo UART controller pins into native mode
@param[in] SerialIoUartControllerNumber UART controller
@param[in] HardwareFlowControl Hardware Flow control
@param[in] PinMuxing UART controller pin muxing
@retval Status
**/
EFI_STATUS
GpioEnableSerialIoUart (
IN UINT32 SerialIoUartControllerNumber,
IN BOOLEAN HardwareFlowControl,
IN UINT32 PinMuxing
)
{
EFI_STATUS Status;
UINT32 Index;
UINT32 PinsUsed;
GPIO_PAD_NATIVE_FUNCTION *UartGpio;
GpioGetSerialIoUartPins (
SerialIoUartControllerNumber,
HardwareFlowControl,
PinMuxing,
&UartGpio,
&PinsUsed
);
if (UartGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < PinsUsed; Index++) {
Status = GpioSetPadMode (UartGpio[Index].Pad, UartGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
GpioSetInputInversion (UartGpio[Index].Pad, 0);
}
return EFI_SUCCESS;
}
/**
This function sets SerialIo SPI controller pins into native mode
@param[in] SerialIoSpiControllerNumber SPI controller
@retval Status
**/
EFI_STATUS
GpioEnableSerialIoSpi (
IN UINT32 SerialIoSpiControllerNumber
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *SpiGpio;
UINT32 NumOfSpiPins;
GpioGetSerialIoSpiPins (
SerialIoSpiControllerNumber,
&SpiGpio,
&NumOfSpiPins
);
if (SpiGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < NumOfSpiPins; Index++) {
Status = GpioSetPadMode (SpiGpio[Index].Pad, SpiGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
GpioSetInputInversion (SpiGpio[Index].Pad, 0);
}
return EFI_SUCCESS;
}
/**
This function sets ISH I2C controller pins into native mode
@param[in] IshI2cControllerNumber I2C controller
@retval Status
**/
EFI_STATUS
GpioEnableIshI2c (
IN UINT32 IshI2cControllerNumber
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *I2cGpio;
GpioGetIshI2cPins (
IshI2cControllerNumber,
&I2cGpio
);
if (I2cGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < PCH_ISH_PINS_PER_I2C_CONTROLLER; Index++) {
Status = GpioSetPadMode (I2cGpio[Index].Pad, I2cGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function sets ISH UART controller pins into native mode
@param[in] IshUartControllerNumber UART controller
@retval Status
**/
EFI_STATUS
GpioEnableIshUart (
IN UINT32 IshUartControllerNumber
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *UartGpio;
GpioGetIshUartPins (
IshUartControllerNumber,
&UartGpio
);
if (UartGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < PCH_ISH_PINS_PER_UART_CONTROLLER; Index++) {
Status = GpioSetPadMode (UartGpio[Index].Pad, UartGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function sets ISH SPI controller pins into native mode
@param[in] IshSpiControllerNumber SPI controller
@retval Status
**/
EFI_STATUS
GpioEnableIshSpi (
IN UINT32 IshSpiControllerNumber
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *SpiGpio;
UINT32 NumOfSpiPins;
GpioGetIshSpiPins (
IshSpiControllerNumber,
&SpiGpio,
&NumOfSpiPins
);
if (SpiGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < NumOfSpiPins; Index++) {
Status = GpioSetPadMode (SpiGpio[Index].Pad, SpiGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function sets ISH GP pin into native mode
@param[in] IshGpPinNumber ISH GP pin number
@retval Status
**/
EFI_STATUS
GpioEnableIshGpPin (
IN UINT32 IshGpPinNumber
)
{
EFI_STATUS Status;
GPIO_PAD_NATIVE_FUNCTION IshGp;
GpioGetIshGpPin (
IshGpPinNumber,
&IshGp
);
Status = GpioSetPadMode (IshGp.Pad, IshGp.Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
}
/**
This function sets SCS SD card controller pins into native mode
@param[in] none
@retval Status
**/
EFI_STATUS
GpioEnableScsSdCard (
VOID
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *SdCardGpio;
UINT32 NumOfSdCardPins;
GPIO_CONFIG PwrEnConfig;
GpioGetScsSdCardPins (
&SdCardGpio,
&NumOfSdCardPins
);
if (SdCardGpio == NULL) {
return EFI_UNSUPPORTED;
}
//
// We need to leave the PWREN#
// GPIO pad unlocked since it is controlled at runtime
// by ACPI code. It is a work around for our SD card
// controller not respecting PWREN# invertion settings
// during D3. Since this pad will be in GPIO mode when
// SD controller is in D3 we need to set correct pad config.
//
GpioUnlockPadCfg (SdCardGpio[0].Pad);
GpioGetPadConfig (SdCardGpio[0].Pad, &PwrEnConfig);
PwrEnConfig.PadMode = SdCardGpio[0].Mode;
PwrEnConfig.Direction = GpioDirOut;
PwrEnConfig.HostSoftPadOwn = GpioHostOwnAcpi;
PwrEnConfig.InterruptConfig = GpioIntDis;
PwrEnConfig.PowerConfig = GpioHostDeepReset;
PwrEnConfig.LockConfig = GpioPadUnlock;
GpioSetPadConfig (SdCardGpio[0].Pad, &PwrEnConfig);
for (Index = 1; Index < NumOfSdCardPins; Index++) {
Status = GpioSetPadMode (SdCardGpio[Index].Pad, SdCardGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
//
// SD Card Pins GPP_G0 - G4 require Native Termination
// Index in mPch[Lp/H]ScsSdCardGpio (depends on mPch[Lp/H]ScsSdCardGpio internal organization):
// GPP_G0 = 1
// GPP_G4 = 5
//
if (Index >= 1 && Index <= 5) {
Status = GpioSetPadElectricalConfig (SdCardGpio[Index].Pad, GpioTermNative);
ASSERT_EFI_ERROR (Status);
}
}
return EFI_SUCCESS;
}
/**
This function enables SCS Sd Card controller card detect pin
@param[in] none
@retval Status
**/
EFI_STATUS
GpioEnableScsSdCardDetect (
VOID
)
{
GPIO_CONFIG PadConfig;
GPIO_PAD GpioPad;
ZeroMem (&PadConfig, sizeof (PadConfig));
///
/// vSD3_CD_B line is driven by GPPC_G_5_SD3_CDB
/// and is used for interrupt for card detect event.
/// GPPC_G_5_SD3_CDB cannot be used for interrupt because this pin
/// is in native mode.
///
GpioPad = GpioGetScsSdCardDetectPin ();
PadConfig.PadMode = GpioPadModeGpio;
PadConfig.Direction = GpioDirIn;
PadConfig.HostSoftPadOwn = GpioHostOwnGpio;
PadConfig.InterruptConfig = GpioIntBothEdge;
PadConfig.PowerConfig = GpioHostDeepReset;
// Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver mode.
GpioUnlockPadCfg (GpioPad);
return GpioSetPadConfig (GpioPad, &PadConfig);
}
/**
This function sets SCS eMMC controller pins into native mode
@param[in] none
@retval Status
**/
EFI_STATUS
GpioEnableScsEmmc (
VOID
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *EmmcGpio;
UINT32 NumOfEmmcPins;
GpioGetScsEmmcPins (
&EmmcGpio,
&NumOfEmmcPins
);
if (EmmcGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < NumOfEmmcPins; Index++) {
Status = GpioSetPadMode (EmmcGpio[Index].Pad, EmmcGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function sets HDA Link pins into native mode
@param[in] none
@retval Status
**/
EFI_STATUS
GpioEnableHdaLink (
VOID
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *HdaLinkGpio;
UINT32 NumOfHdaLinkPins;
GpioGetHdAudioLinkPins (
&HdaLinkGpio,
&NumOfHdaLinkPins
);
if (HdaLinkGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < NumOfHdaLinkPins; Index++) {
Status = GpioSetPadMode (HdaLinkGpio[Index].Pad, HdaLinkGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function sets HDA DMIC pins into native mode
@param[in] DmicNumber DMIC number
@retval Status
**/
EFI_STATUS
GpioEnableHdaDmic (
IN UINT32 DmicNumber
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *DmicGpio;
GpioGetHdaDmicPins (
DmicNumber,
&DmicGpio
);
if (DmicGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < PCH_GPIO_HDA_DMIC_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (DmicGpio[Index].Pad, DmicGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function sets HDA SSP interface pins into native mode
@param[in] SspInterfaceNumber SSPx interface number
@retval Status
**/
EFI_STATUS
GpioEnableHdaSsp (
IN UINT32 SspInterfaceNumber
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *SspGpio;
GpioGetHdaSspPins (
SspInterfaceNumber,
&SspGpio
);
if (SspGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < PCH_GPIO_HDA_SSP_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (SspGpio[Index].Pad, SspGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function sets HDA SoundWire interface pins into native mode
@param[in] SndwInterfaceNumber SNDWx interface number
@retval Status
**/
EFI_STATUS
GpioEnableHdaSndw (
IN UINT32 SndwInterfaceNumber
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *SndwGpio;
GpioGetHdaSndwPins (
SndwInterfaceNumber,
&SndwGpio
);
if (SndwGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < PCH_GPIO_HDA_SNDW_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (SndwGpio[Index].Pad, SndwGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function sets SMBUS controller pins into native mode
@param[in] none
@retval Status
**/
EFI_STATUS
GpioEnableSmbus (
VOID
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *SmbusGpio;
GpioGetSmbusPins (&SmbusGpio);
if (SmbusGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < PCH_GPIO_SMBUS_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (SmbusGpio[Index].Pad, SmbusGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function sets SATA DevSlp pins into native mode
@param[in] SataCtrlIndex SATA controller index
@param[in] SataPort SATA port number
@retval Status
**/
EFI_STATUS
GpioEnableSataDevSlpPin (
IN UINT32 SataCtrlIndex,
IN UINTN SataPort
)
{
GPIO_PAD_NATIVE_FUNCTION DevSlpGpio;
GpioGetSataDevSlpPin (
SataCtrlIndex,
SataPort,
&DevSlpGpio
);
GpioSetPadResetConfig (DevSlpGpio.Pad, GpioResumeReset);
return GpioSetPadMode (DevSlpGpio.Pad, DevSlpGpio.Mode);
}
/**
This function checks if SataDevSlp pin is in native mode
@param[in] SataCtrlIndex SATA controller index
@param[in] SataPort SATA port
@param[out] DevSlpPad DevSlpPad
This is an optional parameter and may be NULL.
@retval TRUE DevSlp is in native mode
FALSE DevSlp is not in native mode
**/
BOOLEAN
GpioIsSataDevSlpPinEnabled (
IN UINT32 SataCtrlIndex,
IN UINTN SataPort,
OUT GPIO_PAD *DevSlpPad OPTIONAL
)
{
GPIO_PAD_NATIVE_FUNCTION DevSlpNativePad;
GPIO_PAD_MODE GpioMode;
EFI_STATUS Status;
ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ());
GpioGetSataDevSlpPin (
SataCtrlIndex,
SataPort,
&DevSlpNativePad
);
Status = GpioGetPadMode (DevSlpNativePad.Pad, &GpioMode);
if (EFI_ERROR (Status) || (GpioMode != DevSlpNativePad.Mode)) {
if (DevSlpPad != NULL) {
*DevSlpPad = GPIO_PAD_NONE;
}
return FALSE;
} else {
if (DevSlpPad != NULL) {
*DevSlpPad = DevSlpNativePad.Pad;
}
return TRUE;
}
}
/**
This function sets SATAGPx pin into native mode
@param[in] SataCtrlIndex SATA controller index
@param[in] SataPort SATA port number
@retval Status
**/
EFI_STATUS
GpioEnableSataGpPin (
IN UINT32 SataCtrlIndex,
IN UINTN SataPort
)
{
GPIO_PAD_NATIVE_FUNCTION SataGpGpio;
GpioGetSataGpPin (
SataCtrlIndex,
SataPort,
&SataGpGpio
);
DEBUG_CODE_BEGIN ();
GPIO_PAD_MODE PadMode;
GpioGetPadMode (SataGpGpio.Pad, &PadMode);
if (PadMode == GpioPadModeNative1) {
DEBUG ((DEBUG_ERROR, "GPIO ERROR: Cannot enable SATAGP%d, %a already used for SATAXPCIE_%d\n",
SataPort,
GpioName (SataGpGpio.Pad),
SataPort));
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
DEBUG_CODE_END ();
return GpioSetPadMode (SataGpGpio.Pad, SataGpGpio.Mode);
}
/**
Returns a pad for given CLKREQ# index.
@param[in] ClkreqIndex CLKREQ# number
@return CLKREQ# pad.
**/
GPIO_PAD
GpioGetClkreqPad (
IN UINT32 ClkreqIndex
)
{
GPIO_PAD_NATIVE_FUNCTION ClkReqGpio;
GpioGetPcieClkReqPin (
ClkreqIndex,
&ClkReqGpio
);
return ClkReqGpio.Pad;
}
/**
Enables CLKREQ# pad in native mode.
@param[in] ClkreqIndex CLKREQ# number
@return none
**/
VOID
GpioEnableClkreq (
IN UINT32 ClkreqIndex
)
{
GPIO_CONFIG PadConfig;
GPIO_PAD_NATIVE_FUNCTION ClkReqGpio;
ZeroMem (&PadConfig, sizeof (PadConfig));
GpioGetPcieClkReqPin (
ClkreqIndex,
&ClkReqGpio
);
PadConfig.PadMode = ClkReqGpio.Mode;
PadConfig.Direction = GpioDirNone;
PadConfig.PowerConfig = GpioHostDeepReset;
DEBUG ((DEBUG_INFO, "Enabling CLKREQ%d\n", ClkreqIndex));
GpioSetPadConfig (ClkReqGpio.Pad, &PadConfig);
}
/**
This function sets HPD, VDDEN, BKLTEN and BKLTCTL pins into native mode for eDP Panel
@retval Status
**/
EFI_STATUS
GpioEnableEdpPins (
VOID
)
{
EFI_STATUS Status;
UINT32 Index;
GPIO_PAD_NATIVE_FUNCTION *EdpPins;
UINT32 EdpPinsNumber;
GpioGetEdpPins (
&EdpPins,
&EdpPinsNumber
);
if (EdpPins == NULL) {
return EFI_UNSUPPORTED;
}
//
// Configure HPD, VDD and BKLT Pins for eDP panel
//
for (Index = 0; Index < EdpPinsNumber; Index++) {
Status = GpioSetPadMode (EdpPins[Index].Pad, EdpPins[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function sets DDP pins into native mode
@param[in] DdpInterface DDPx interface
@retval Status
**/
EFI_STATUS
GpioEnableDpInterface (
IN GPIO_DDP DdpInterface
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *DdpGpio;
GpioGetDdpPins (
DdpInterface,
&DdpGpio
);
if (DdpGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < PCH_GPIO_DDP_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (DdpGpio[Index].Pad, DdpGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function configures GPIO connection between CNVi and CRF
@param[in] None
@retval Status
**/
EFI_STATUS
GpioConfigureCnviCrfConnection (
VOID
)
{
EFI_STATUS Status;
UINT32 Index;
GPIO_PAD_NATIVE_FUNCTION *CnviBriRgiExternalPad;
GpioGetCnvBriRgiPins (&CnviBriRgiExternalPad);
if (CnviBriRgiExternalPad == NULL) {
return EFI_UNSUPPORTED;
}
//
// Configure CNVi BRI and RGI buses for high speed communication with CRF
//
for (Index = 0; Index < PCH_GPIO_CNVI_BRI_RGI_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (CnviBriRgiExternalPad[Index].Pad, CnviBriRgiExternalPad[Index].Mode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
This function configures virtual GPIO connection for CNVi Bluetooth UART
@param[in] ConnectionType
@retval Status
**/
EFI_STATUS
GpioConfigureCnviBtUartConnection (
IN VGPIO_CNVI_BT_UART_CONNECTION_TYPE ConnectionType
)
{
EFI_STATUS Status;
UINT32 Index;
GPIO_PAD *VCnviBtUartPad;
GPIO_PAD_MODE VCnviBtUartPadMode;
GPIO_PAD *VUartForCnviBtPad;
GPIO_PAD_MODE VUartForCnviBtPadMode;
GPIO_PAD_NATIVE_FUNCTION *CnviBtUartExternalPad;
GpioGetCnviBtUartPins (
ConnectionType,
&VCnviBtUartPad,
&VCnviBtUartPadMode,
&VUartForCnviBtPad,
&VUartForCnviBtPadMode
);
if ((VCnviBtUartPad == NULL) ||
(VUartForCnviBtPad == NULL)) {
return EFI_UNSUPPORTED;
}
//
// Configure CNVi Bluetooth UART for certain connection
//
for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (VCnviBtUartPad[Index], VCnviBtUartPadMode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_UNSUPPORTED;
}
}
//
// Enable virtual connection for UART for Bluetooth
//
for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (VUartForCnviBtPad[Index], VUartForCnviBtPadMode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_UNSUPPORTED;
}
}
//
// Enable CNVi BT UART on external pads
//
if (ConnectionType == GpioCnviBtUartToExternalPads) {
GpioGetCnviBtUartExternalPins (&CnviBtUartExternalPad);
if (CnviBtUartExternalPad == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (CnviBtUartExternalPad[Index].Pad, CnviBtUartExternalPad[Index].Mode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_UNSUPPORTED;
}
}
}
return EFI_SUCCESS;
}
/**
This function configures virtual GPIO connection for CNVi Bluetooth I2S
@param[in] ConnectionType
@retval Status
**/
EFI_STATUS
GpioConfigureCnviBtI2sConnection (
IN VGPIO_CNVI_BT_I2S_CONNECTION_TYPE ConnectionType
)
{
EFI_STATUS Status;
UINT32 Index;
GPIO_PAD *VCnviBtI2sPad;
GPIO_PAD_MODE VCnviBtI2sPadMode;
GPIO_PAD *VSspForCnviBtPad;
GPIO_PAD_MODE VSspForCnviBtPadMode;
GPIO_PAD_NATIVE_FUNCTION *CnviBtI2sExternalPad;
GpioGetCnviBtI2sPins (
ConnectionType,
&VCnviBtI2sPad,
&VCnviBtI2sPadMode,
&VSspForCnviBtPad,
&VSspForCnviBtPadMode
);
if ((VCnviBtI2sPad == NULL) ||
(VSspForCnviBtPad == NULL)) {
return EFI_UNSUPPORTED;
}
//
// Configure CNVi Bluetooth I2S for certain connection
//
for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (VCnviBtI2sPad[Index], VCnviBtI2sPadMode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_UNSUPPORTED;
}
}
//
// Enable virtual connection for SSP for Bluetooth
//
for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (VSspForCnviBtPad[Index], VSspForCnviBtPadMode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_UNSUPPORTED;
}
}
//
// Enable CNV BT I2S on external pads
//
if (ConnectionType == (VGPIO_CNVI_BT_I2S_CONNECTION_TYPE) GpioCnviBtI2sToExternalPads) {
GpioGetCnviBtI2sExternalPins (&CnviBtI2sExternalPad);
if (CnviBtI2sExternalPad == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < PCH_GPIO_CNVI_SSP_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (CnviBtI2sExternalPad[Index].Pad, CnviBtI2sExternalPad[Index].Mode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_UNSUPPORTED;
}
}
}
return EFI_SUCCESS;
}
/**
This function configures virtual GPIO connection for CNVi MFUART1
@param[in] ConnectionType
@retval Status
**/
EFI_STATUS
GpioConfigureCnviMfUart1Connection (
IN VGPIO_CNVI_MF_UART1_CONNECTION_TYPE ConnectionType
)
{
EFI_STATUS Status;
UINT32 Index;
GPIO_PAD *VCnviMfUart1Pad;
GPIO_PAD_MODE VCnviMfUart1PadMode;
GPIO_PAD *VUartForCnviMfUart1Pad;
GPIO_PAD_MODE VUartForCnviMfUart1PadMode;
GPIO_PAD_NATIVE_FUNCTION *CnviMfUart1ExternalPad;
GpioGetCnviMfUart1Pins (
ConnectionType,
&VCnviMfUart1Pad,
&VCnviMfUart1PadMode,
&VUartForCnviMfUart1Pad,
&VUartForCnviMfUart1PadMode
);
if ((VCnviMfUart1Pad == NULL) ||
(VUartForCnviMfUart1Pad == NULL)) {
return EFI_UNSUPPORTED;
}
//
// Configure CNVi MFUART1 for certain connection
//
for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (VCnviMfUart1Pad[Index], VCnviMfUart1PadMode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_UNSUPPORTED;
}
}
//
// Enable virtual connection for MFUART1
//
for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (VUartForCnviMfUart1Pad[Index], VUartForCnviMfUart1PadMode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_UNSUPPORTED;
}
}
//
// Enable CNV MFUART1 on external pads
//
if (ConnectionType == GpioCnviMfUart1ToExternalPads) {
GpioGetCnviMfUart1ExternalPins (&CnviMfUart1ExternalPad);
if (CnviMfUart1ExternalPad == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < PCH_GPIO_CNVI_UART_NUMBER_OF_PINS; Index++) {
Status = GpioSetPadMode (CnviMfUart1ExternalPad[Index].Pad, CnviMfUart1ExternalPad[Index].Mode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_UNSUPPORTED;
}
}
}
return EFI_SUCCESS;
}
/**
This function sets CNVi Bluetooth Enable value
@param[in] Value CNVi BT enable value
0: Disable, 1: Enable
@retval Status
**/
EFI_STATUS
GpioSetCnviBtEnState (
IN UINT32 Value
)
{
EFI_STATUS Status;
GPIO_PAD CnviBtEnPad;
GPIO_CONFIG PadConfig;
ZeroMem (&PadConfig, sizeof (PadConfig));
PadConfig.PadMode = GpioPadModeGpio;
PadConfig.HostSoftPadOwn = GpioHostOwnGpio;
PadConfig.Direction = GpioDirOut;
if (Value == 1) {
PadConfig.OutputState = GpioOutHigh;
} else {
PadConfig.OutputState = GpioOutLow;
}
CnviBtEnPad = GpioGetCnviBtEnablePin ();
// Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver mode and it is GPO
GpioUnlockPadCfg (CnviBtEnPad);
GpioUnlockPadCfgTx (CnviBtEnPad);
Status = GpioSetPadConfig (CnviBtEnPad, &PadConfig);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
This function sets CNVi Bluetooth main host interface
@param[in] BtInterface CNVi BT Interface Select value
GpioCnviBtIfUart: UART, GpioCnviBtIfUsb: USB
@retval Status
**/
EFI_STATUS
GpioSetCnviBtInterface (
IN VGPIO_CNVI_BT_INTERFACE BtInterface
)
{
EFI_STATUS Status;
GPIO_CONFIG PadConfig;
ZeroMem (&PadConfig, sizeof (PadConfig));
PadConfig.PadMode = GpioPadModeGpio;
PadConfig.Direction = GpioDirOut;
if (BtInterface == GpioCnviBtIfUsb) {
PadConfig.OutputState = GpioOutHigh;
} else {
PadConfig.OutputState = GpioOutLow;
}
Status = GpioSetPadConfig (GpioGetCnviBtIfSelectPin (), &PadConfig);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
/**
This function sets CNVi Bluetooth Wireless Charging support
@param[in] BtWirelessCharging CNVi BT Wireless Charging support
0: Normal BT operation (no Wireless Charging support)
1: Enable BT Wireless Charging
@retval Status
**/
EFI_STATUS
GpioSetCnviBtWirelessCharging (
IN UINT32 BtWirelessCharging
)
{
EFI_STATUS Status;
GPIO_CONFIG CnviBtChargingPadConfig;
GPIO_PAD_NATIVE_FUNCTION A4WpPad;
ZeroMem (&CnviBtChargingPadConfig, sizeof (CnviBtChargingPadConfig));
CnviBtChargingPadConfig.PadMode = GpioPadModeGpio;
CnviBtChargingPadConfig.Direction = GpioDirOut;
if (BtWirelessCharging == 1) {
CnviBtChargingPadConfig.OutputState = GpioOutHigh;
GpioGetCnviA4WpPin (&A4WpPad);
Status = GpioSetPadMode (A4WpPad.Pad, A4WpPad.Mode);
ASSERT_EFI_ERROR (Status);
} else {
CnviBtChargingPadConfig.OutputState = GpioOutLow;
}
Status = GpioSetPadConfig (GpioGetCnviBtChargingPin (), &CnviBtChargingPadConfig);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
/**
This function enables and configures CNVi Bluetooth Host wake-up interrupt
@param[in] None
@retval Status
**/
EFI_STATUS
GpioConfigureCnviBtHostWakeInt (
VOID
)
{
EFI_STATUS Status;
GPIO_PAD CnviBtHostWakeIntPad;
GPIO_CONFIG PadConfig;
ZeroMem (&PadConfig, sizeof (PadConfig));
PadConfig.PadMode = GpioPadModeGpio;
PadConfig.Direction = GpioDirIn;
PadConfig.HostSoftPadOwn = GpioHostOwnGpio;
PadConfig.InterruptConfig = GpioIntEdge;
PadConfig.PowerConfig = GpioHostDeepReset;
CnviBtHostWakeIntPad = GpioGetCnviBtHostWakeIntPin ();
// Unlock GPIO pad due to Host Software Pad Ownership is GPIO Driver mode.
GpioUnlockPadCfg (CnviBtHostWakeIntPad);
Status = GpioSetPadConfig (CnviBtHostWakeIntPad, &PadConfig);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
/**
This function enables IMGU CLKOUT native pin
@param[in] None
@retval Status
**/
EFI_STATUS
GpioEnableImguClkOut (
VOID
)
{
EFI_STATUS Status;
UINTN Index;
GPIO_PAD_NATIVE_FUNCTION *ImguClkOutGpio;
UINT32 NoOfNativePins;
GpioGetImgClkOutPins (
&ImguClkOutGpio,
&NoOfNativePins
);
if (ImguClkOutGpio == NULL) {
return EFI_UNSUPPORTED;
}
for (Index = 0; Index < NoOfNativePins; Index++) {
Status = GpioSetPadMode (ImguClkOutGpio[Index].Pad, ImguClkOutGpio[Index].Mode);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
}
return EFI_SUCCESS;
}
/**
Power button debounce configuration
Debounce time can be specified in microseconds. Only certain values according
to below formula are supported:
DebounceTime = (2 ^ PADCFG_DW2.DEBOUNCE)*(glitch filter clock period).
RTC clock with f = 32 KHz is used for glitch filter.
DebounceTime = (2 ^ PADCFG_DW2.DEBOUNCE)*(31.25 us).
Supported DebounceTime values are following:
DebounceTime = 0 -> Debounce feature disabled
DebounceTime > 0 && < 250us -> Not supported
DebounceTime = 250us - 1024000us -> Supported range (DebounceTime = 250us * 2^n)
For values not supported by HW, they will be rounded down to closest supported one
@param[in] DebounceTime Debounce Time in microseconds
If Debounce Time = 0, Debouncer feature will be disabled
Function will set DebounceTime argument to rounded supported value
**/
VOID
GpioSetPwrBtnDebounceTimer (
IN UINT32 DebounceTime
)
{
GpioSetDebounceTimer (GpioGetPwrBtnPin (), &DebounceTime);
}
/**
Configure LPC GPIO
**/
VOID
LpcConfigureGpio (
VOID
)
{
GPIO_PAD GpioPad;
GpioPad = GpioGetLpcPin();
if (GpioPad == 0) {
return;
} else {
GpioSetPadElectricalConfig (GpioPad, GpioTermWpu20K);
}
}