mirror of https://github.com/acidanthera/audk.git
ArmPlatformPkg: Add PL061 GPIO driver
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11795 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
33e7c2abf4
commit
5a62a8b7f1
|
@ -0,0 +1,347 @@
|
|||
/** @file
|
||||
*
|
||||
* Copyright (c) 2011, ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are licensed and made available under the terms and conditions of the BSD License
|
||||
* which accompanies this distribution. The full text of the license may be found at
|
||||
* http://opensource.org/licenses/bsd-license.php
|
||||
*
|
||||
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
#include <Base.h>
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
|
||||
#include <Protocol/EmbeddedGpio.h>
|
||||
#include <ArmPlatform.h>
|
||||
#include <Drivers/PL061Gpio.h>
|
||||
|
||||
#define LOW_4_BITS 0x0000000F
|
||||
|
||||
BOOLEAN mPL061Initialized = FALSE;
|
||||
|
||||
/**
|
||||
Function implementations
|
||||
**/
|
||||
|
||||
EFI_STATUS
|
||||
PL061Identify (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
// Check if this is a PrimeCell Peripheral
|
||||
if( ( MmioRead8( PL061_GPIO_PCELL_ID0 ) != 0x0D )
|
||||
|| ( MmioRead8( PL061_GPIO_PCELL_ID1 ) != 0xF0 )
|
||||
|| ( MmioRead8( PL061_GPIO_PCELL_ID2 ) != 0x05 )
|
||||
|| ( MmioRead8( PL061_GPIO_PCELL_ID3 ) != 0xB1 ) ) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
// Check if this PrimeCell Peripheral is the PL061 GPIO
|
||||
if( ( MmioRead8( PL061_GPIO_PERIPH_ID0 ) != 0x61 )
|
||||
|| ( MmioRead8( PL061_GPIO_PERIPH_ID1 ) != 0x10 )
|
||||
|| ( ( MmioRead8( PL061_GPIO_PERIPH_ID2 ) & LOW_4_BITS ) != 0x04 )
|
||||
|| ( MmioRead8( PL061_GPIO_PERIPH_ID3 ) != 0x00 ) ) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PL061Initialize (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// Check if the PL061 GPIO module exists on board
|
||||
Status = PL061Identify();
|
||||
if (EFI_ERROR( Status )) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
// Do other hardware initialisation things here as required
|
||||
|
||||
// Disable Interrupts
|
||||
//if( MmioRead8( PL061_GPIO_IE_REG ) != 0 ) {
|
||||
// // Ensure interrupts are disabled
|
||||
//}
|
||||
|
||||
mPL061Initialized = TRUE;
|
||||
|
||||
EXIT:
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Routine Description:
|
||||
|
||||
Gets the state of a GPIO pin
|
||||
|
||||
Arguments:
|
||||
|
||||
This - pointer to protocol
|
||||
Gpio - which pin to read
|
||||
Value - state of the pin
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - GPIO state returned in Value
|
||||
EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Get (
|
||||
IN EMBEDDED_GPIO *This,
|
||||
IN EMBEDDED_GPIO_PIN Gpio,
|
||||
OUT UINTN *Value
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
|
||||
if( ( Value == NULL )
|
||||
|| ( Gpio > LAST_GPIO_PIN ) )
|
||||
{
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Initialize the hardware if not already done
|
||||
if( !mPL061Initialized ) {
|
||||
Status = PL061Initialize();
|
||||
if( EFI_ERROR(Status) ) {
|
||||
goto EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
if( MmioRead8( PL061_GPIO_DATA_REG ) & GPIO_PIN_MASK_HIGH_8BIT(Gpio) ) {
|
||||
*Value = 1;
|
||||
} else {
|
||||
*Value = 0;
|
||||
}
|
||||
|
||||
EXIT:
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Routine Description:
|
||||
|
||||
Sets the state of a GPIO pin
|
||||
|
||||
Arguments:
|
||||
|
||||
This - pointer to protocol
|
||||
Gpio - which pin to modify
|
||||
Mode - mode to set
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - GPIO set as requested
|
||||
EFI_UNSUPPORTED - Mode is not supported
|
||||
EFI_INVALID_PARAMETER - Gpio pin is out of range
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Set (
|
||||
IN EMBEDDED_GPIO *This,
|
||||
IN EMBEDDED_GPIO_PIN Gpio,
|
||||
IN EMBEDDED_GPIO_MODE Mode
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status = EFI_SUCCESS;
|
||||
|
||||
// Check for errors
|
||||
if( Gpio > LAST_GPIO_PIN ) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
// Initialize the hardware if not already done
|
||||
if( !mPL061Initialized ) {
|
||||
Status = PL061Initialize();
|
||||
if( EFI_ERROR(Status) ) {
|
||||
goto EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
case GPIO_MODE_INPUT:
|
||||
// Set the corresponding direction bit to LOW for input
|
||||
MmioAnd8( PL061_GPIO_DIR_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio) );
|
||||
break;
|
||||
|
||||
case GPIO_MODE_OUTPUT_0:
|
||||
// Set the corresponding data bit to LOW for 0
|
||||
MmioAnd8( PL061_GPIO_DATA_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio) );
|
||||
// Set the corresponding direction bit to HIGH for output
|
||||
MmioOr8( PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio) );
|
||||
break;
|
||||
|
||||
case GPIO_MODE_OUTPUT_1:
|
||||
// Set the corresponding data bit to HIGH for 1
|
||||
MmioOr8( PL061_GPIO_DATA_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio) );
|
||||
// Set the corresponding direction bit to HIGH for output
|
||||
MmioOr8( PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio) );
|
||||
break;
|
||||
|
||||
default:
|
||||
// Other modes are not supported
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
EXIT:
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Routine Description:
|
||||
|
||||
Gets the mode (function) of a GPIO pin
|
||||
|
||||
Arguments:
|
||||
|
||||
This - pointer to protocol
|
||||
Gpio - which pin
|
||||
Mode - pointer to output mode value
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - mode value retrieved
|
||||
EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetMode (
|
||||
IN EMBEDDED_GPIO *This,
|
||||
IN EMBEDDED_GPIO_PIN Gpio,
|
||||
OUT EMBEDDED_GPIO_MODE *Mode
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// Check for errors
|
||||
if( ( Mode == NULL )
|
||||
|| ( Gpio > LAST_GPIO_PIN ) ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Initialize the hardware if not already done
|
||||
if( !mPL061Initialized ) {
|
||||
Status = PL061Initialize();
|
||||
if( EFI_ERROR(Status) ) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if it is input or output
|
||||
if( MmioRead8( PL061_GPIO_DIR_REG ) & GPIO_PIN_MASK_HIGH_8BIT(Gpio) ) {
|
||||
// Pin set to output
|
||||
if( MmioRead8( PL061_GPIO_DATA_REG ) & GPIO_PIN_MASK_HIGH_8BIT(Gpio) ) {
|
||||
*Mode = GPIO_MODE_OUTPUT_1;
|
||||
} else {
|
||||
*Mode = GPIO_MODE_OUTPUT_0;
|
||||
}
|
||||
} else {
|
||||
// Pin set to input
|
||||
*Mode = GPIO_MODE_INPUT;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Routine Description:
|
||||
|
||||
Sets the pull-up / pull-down resistor of a GPIO pin
|
||||
|
||||
Arguments:
|
||||
|
||||
This - pointer to protocol
|
||||
Gpio - which pin
|
||||
Direction - pull-up, pull-down, or none
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_UNSUPPORTED - Can not perform the requested operation
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetPull (
|
||||
IN EMBEDDED_GPIO *This,
|
||||
IN EMBEDDED_GPIO_PIN Gpio,
|
||||
IN EMBEDDED_GPIO_PULL Direction
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
Protocol variable definition
|
||||
**/
|
||||
EMBEDDED_GPIO gGpio = {
|
||||
Get,
|
||||
Set,
|
||||
GetMode,
|
||||
SetPull
|
||||
};
|
||||
|
||||
/**
|
||||
Initialize the state information for the Embedded Gpio protocol.
|
||||
|
||||
@param ImageHandle of the loaded driver
|
||||
@param SystemTable Pointer to the System Table
|
||||
|
||||
@retval EFI_SUCCESS Protocol registered
|
||||
@retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
|
||||
@retval EFI_DEVICE_ERROR Hardware problems
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PL061InstallProtocol (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE Handle;
|
||||
|
||||
//
|
||||
// Make sure the Gpio protocol has not been installed in the system yet.
|
||||
//
|
||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEmbeddedGpioProtocolGuid);
|
||||
|
||||
// Install the Embedded GPIO Protocol onto a new handle
|
||||
Handle = NULL;
|
||||
Status = gBS->InstallMultipleProtocolInterfaces(
|
||||
&Handle,
|
||||
&gEmbeddedGpioProtocolGuid, &gGpio,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR(Status)) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/** @file
|
||||
*
|
||||
* Copyright (c) 2011, ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are licensed and made available under the terms and conditions of the BSD License
|
||||
* which accompanies this distribution. The full text of the license may be found at
|
||||
* http://opensource.org/licenses/bsd-license.php
|
||||
*
|
||||
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*
|
||||
**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = PL061GpioDxe
|
||||
FILE_GUID = 5c1997d7-8d45-4f21-af3c-2206b8ed8bec
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
|
||||
ENTRY_POINT = PL061InstallProtocol
|
||||
[Sources.common]
|
||||
PL061Gpio.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
ArmPkg/ArmPkg.dec
|
||||
ArmPlatformPkg/ArmPlatformPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
UefiRuntimeServicesTableLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
UefiDriverEntryPoint
|
||||
IoLib
|
||||
|
||||
[Guids]
|
||||
|
||||
[Protocols]
|
||||
gEmbeddedGpioProtocolGuid
|
||||
|
||||
|
||||
[Depex]
|
||||
TRUE
|
|
@ -0,0 +1,56 @@
|
|||
/** @file
|
||||
*
|
||||
* Copyright (c) 2011, ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are licensed and made available under the terms and conditions of the BSD License
|
||||
* which accompanies this distribution. The full text of the license may be found at
|
||||
* http://opensource.org/licenses/bsd-license.php
|
||||
*
|
||||
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
#ifndef __PL061_GPIO_H__
|
||||
#define __PL061_GPIO_H__
|
||||
|
||||
#include <Base.h>
|
||||
#include <Protocol/EmbeddedGpio.h>
|
||||
#include <ArmPlatform.h>
|
||||
|
||||
// SP805 Watchdog Registers
|
||||
#define PL061_GPIO_DATA_REG (PL061_GPIO_BASE + 0x000)
|
||||
#define PL061_GPIO_DIR_REG (PL061_GPIO_BASE + 0x400)
|
||||
#define PL061_GPIO_IS_REG (PL061_GPIO_BASE + 0x404)
|
||||
#define PL061_GPIO_IBE_REG (PL061_GPIO_BASE + 0x408)
|
||||
#define PL061_GPIO_IEV_REG (PL061_GPIO_BASE + 0x40C)
|
||||
#define PL061_GPIO_IE_REG (PL061_GPIO_BASE + 0x410)
|
||||
#define PL061_GPIO_RIS_REG (PL061_GPIO_BASE + 0x414)
|
||||
#define PL061_GPIO_MIS_REG (PL061_GPIO_BASE + 0x410)
|
||||
#define PL061_GPIO_IC_REG (PL061_GPIO_BASE + 0x41C)
|
||||
#define PL061_GPIO_AFSEL_REG (PL061_GPIO_BASE + 0x420)
|
||||
|
||||
#define PL061_GPIO_PERIPH_ID0 (PL061_GPIO_BASE + 0xFE0)
|
||||
#define PL061_GPIO_PERIPH_ID1 (PL061_GPIO_BASE + 0xFE4)
|
||||
#define PL061_GPIO_PERIPH_ID2 (PL061_GPIO_BASE + 0xFE8)
|
||||
#define PL061_GPIO_PERIPH_ID3 (PL061_GPIO_BASE + 0xFEC)
|
||||
|
||||
#define PL061_GPIO_PCELL_ID0 (PL061_GPIO_BASE + 0xFF0)
|
||||
#define PL061_GPIO_PCELL_ID1 (PL061_GPIO_BASE + 0xFF4)
|
||||
#define PL061_GPIO_PCELL_ID2 (PL061_GPIO_BASE + 0xFF8)
|
||||
#define PL061_GPIO_PCELL_ID3 (PL061_GPIO_BASE + 0xFFC)
|
||||
|
||||
|
||||
// GPIO pins are numbered 0..7
|
||||
#define LAST_GPIO_PIN 7
|
||||
|
||||
// All bits low except one bit high, native bit lenght
|
||||
#define GPIO_PIN_MASK(Pin) (1UL << ((UINTN)(Pin)))
|
||||
// All bits low except one bit high, restricted to 8 bits (i.e. ensures zeros above 8bits)
|
||||
#define GPIO_PIN_MASK_HIGH_8BIT(Pin) (GPIO_PIN_MASK(Pin) && 0xFF)
|
||||
// All bits high except one bit low, restricted to 8 bits (i.e. ensures zeros above 8bits)
|
||||
#define GPIO_PIN_MASK_LOW_8BIT(Pin) ((~GPIO_PIN_MASK(Pin)) && 0xFF)
|
||||
|
||||
#endif // __PL061_GPIO_H__
|
Loading…
Reference in New Issue