summaryrefslogtreecommitdiff
path: root/ArmPlatformPkg/Drivers
diff options
context:
space:
mode:
authoroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2011-06-11 11:23:39 +0000
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2011-06-11 11:23:39 +0000
commit5a62a8b7f19019e7aa8d26d30ed7b7a22fc2a6d0 (patch)
tree6fc82a7b73c775078b718a8e42f912b8b6580640 /ArmPlatformPkg/Drivers
parent33e7c2abf4852c98d13072102277170e198c5220 (diff)
ArmPlatformPkg: Add PL061 GPIO driver
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11795 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPlatformPkg/Drivers')
-rw-r--r--ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c347
-rw-r--r--ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf49
2 files changed, 396 insertions, 0 deletions
diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c
new file mode 100644
index 000000000..0e263c03a
--- /dev/null
+++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c
@@ -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;
+}
diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
new file mode 100644
index 000000000..53eebdaec
--- /dev/null
+++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
@@ -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