/** @file
Copyright (c) 2017, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#define PDR(x) (SYNQUACER_GPIO_BASE + 4 * (GPIO_PIN (x) >> 3))
#define DDR(x) (SYNQUACER_GPIO_BASE + 0x10 + 4 * (GPIO_PIN (x) >> 3))
#define PFR(x) (SYNQUACER_GPIO_BASE + 0x20 + 4 * (GPIO_PIN (x) >> 3))
#define GPIO_BIT(x) (1U << (GPIO_PIN (x) % 8))
STATIC CONST UINTN mGpioPinCount = 32;
/**
Gets the state of a GPIO pin
@param This Pointer to protocol
@param Gpio Which pin to read
@param Value State of the pin
@retval EFI_SUCCESS GPIO state returned in Value
@retval EFI_INVALID_PARAMETER Value is NULL
@retval EFI_NOT_FOUND Pin does not exit
**/
STATIC
EFI_STATUS
EFIAPI
GpioGet (
IN EMBEDDED_GPIO_PPI *This,
IN EMBEDDED_GPIO_PIN Gpio,
OUT UINTN *Value
)
{
if (Value == NULL) {
return EFI_INVALID_PARAMETER;
}
if (GPIO_PORT (Gpio) > 0 || GPIO_PIN (Gpio) >= mGpioPinCount) {
return EFI_NOT_FOUND;
}
*Value = ((MmioRead32 (PDR (GPIO_PIN (Gpio))) & GPIO_BIT (Gpio)) != 0);
return EFI_SUCCESS;
}
/**
Sets the state of a GPIO pin
@param This Pointer to protocol
@param Gpio Which pin to modify
@param Mode Mode to set
@retval EFI_SUCCESS GPIO set as requested
@retval EFI_INVALID_PARAMETER Invalid mode
@retval EFI_NOT_FOUND Pin does not exit
**/
STATIC
EFI_STATUS
EFIAPI
GpioSet (
IN EMBEDDED_GPIO_PPI *This,
IN EMBEDDED_GPIO_PIN Gpio,
IN EMBEDDED_GPIO_MODE Mode
)
{
if (GPIO_PORT (Gpio) > 0 || GPIO_PIN (Gpio) >= mGpioPinCount) {
return EFI_NOT_FOUND;
}
switch (Mode) {
case GPIO_MODE_INPUT:
MmioAnd32 (DDR (GPIO_PIN (Gpio)), ~GPIO_BIT (Gpio));
break;
case GPIO_MODE_OUTPUT_0:
MmioOr32 (DDR (GPIO_PIN (Gpio)), GPIO_BIT (Gpio));
MmioAnd32 (PDR (GPIO_PIN (Gpio)), ~GPIO_BIT (Gpio));
break;
case GPIO_MODE_OUTPUT_1:
MmioOr32 (DDR (GPIO_PIN (Gpio)), GPIO_BIT (Gpio));
MmioOr32 (PDR (GPIO_PIN (Gpio)), GPIO_BIT (Gpio));
break;
default:
return EFI_INVALID_PARAMETER;
}
return EFI_SUCCESS;
}
/**
Gets the mode (function) of a GPIO pin
@param This Pointer to protocol
@param Gpio Which pin
@param Mode Pointer to output mode value
@retval EFI_SUCCESS Mode value retrieved
@retval EFI_INVALID_PARAMETER Mode is NULL
@retval EFI_NOT_FOUND Pin does not exit
**/
STATIC
EFI_STATUS
EFIAPI
GpioGetMode (
IN EMBEDDED_GPIO_PPI *This,
IN EMBEDDED_GPIO_PIN Gpio,
OUT EMBEDDED_GPIO_MODE *Mode
)
{
if (Mode == NULL) {
return EFI_INVALID_PARAMETER;
}
if (GPIO_PORT (Gpio) > 0 || GPIO_PIN (Gpio) >= mGpioPinCount) {
return EFI_NOT_FOUND;
}
if (!(MmioRead32 (DDR (GPIO_PIN (Gpio))) & GPIO_BIT (Gpio))) {
*Mode = GPIO_MODE_INPUT;
} else if (!(MmioRead32 (PDR (GPIO_PIN (Gpio))) & GPIO_BIT (Gpio))) {
*Mode = GPIO_MODE_OUTPUT_0;
} else {
*Mode = GPIO_MODE_OUTPUT_1;
}
return EFI_SUCCESS;
}
/**
Sets the pull-up / pull-down resistor of a GPIO pin
@param This Pointer to PPI
@param Gpio Port/pin index
@param Pull The pullup/pulldown mode to set
@retval EFI_SUCCESS Mode was set
@retval EFI_NOT_FOUND Pin does not exist
@retval EFI_UNSUPPORTED Action not supported
**/
STATIC
EFI_STATUS
EFIAPI
GpioSetPull (
IN EMBEDDED_GPIO_PPI *This,
IN EMBEDDED_GPIO_PIN Gpio,
IN EMBEDDED_GPIO_PULL Pull
)
{
if (Pull != GPIO_PULL_NONE) {
return EFI_UNSUPPORTED;
}
if (GPIO_PORT (Gpio) > 0 || GPIO_PIN (Gpio) >= mGpioPinCount) {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
STATIC EMBEDDED_GPIO_PPI mGpioPpi = {
GpioGet,
GpioSet,
GpioGetMode,
GpioSetPull,
};
STATIC CONST EFI_PEI_PPI_DESCRIPTOR mEmbeddedGpioPpiDescriptor = {
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gEdkiiEmbeddedGpioPpiGuid,
&mGpioPpi
};
EFI_STATUS
EFIAPI
SynQuacerGpioPeiEntryPoint (
IN EFI_PEI_FILE_HANDLE FfsHeader,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
return PeiServicesInstallPpi (&mEmbeddedGpioPpiDescriptor);
}