+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <Uefi.h>\r
-#include <Omap3530/Omap3530.h>\r
-\r
-#include <Library/DebugLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-\r
-#include <Protocol/SmbusHc.h>\r
-\r
-#define MAX_RETRY 1000\r
-\r
-//\r
-// Internal Functions\r
-//\r
-STATIC\r
-EFI_STATUS\r
-WaitForBusBusy (\r
- VOID\r
- )\r
-{\r
- UINTN Retry = 0;\r
-\r
- while (++Retry < MAX_RETRY && (MmioRead16(I2C_STAT) & BB) == 0x1);\r
-\r
- if (Retry == MAX_RETRY) {\r
- return EFI_TIMEOUT;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-PollForStatus(\r
- UINT16 StatusBit\r
- )\r
-{\r
- UINTN Retry = 0;\r
-\r
- while(Retry < MAX_RETRY) {\r
- if (MmioRead16(I2C_STAT) & StatusBit) {\r
- //Clear particular status bit from Status register.\r
- MmioOr16(I2C_STAT, StatusBit);\r
- break;\r
- }\r
- Retry++;\r
- }\r
-\r
- if (Retry == MAX_RETRY) {\r
- return EFI_TIMEOUT;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-ConfigureI2c (\r
- VOID\r
- )\r
-{\r
- //Program prescaler to obtain 12-MHz clock\r
- MmioWrite16(I2C_PSC, 0x0000);\r
-\r
- //Program SCLL and SCLH\r
- //NOTE: Following values are the register dump after U-Boot code executed.\r
- //We need to figure out how its calculated based on the I2C functional clock and I2C_PSC.\r
- MmioWrite16(I2C_SCLL, 0x0035);\r
- MmioWrite16(I2C_SCLH, 0x0035);\r
-\r
- //Take the I2C controller out of reset.\r
- MmioOr16(I2C_CON, I2C_EN);\r
-\r
- //Initialize the I2C controller.\r
-\r
- //Set I2C controller in Master mode.\r
- MmioOr16(I2C_CON, MST);\r
-\r
- //Enable interrupts for receive/transmit mode.\r
- MmioOr16(I2C_IE, (XRDY_IE | RRDY_IE | ARDY_IE | NACK_IE));\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-I2CReadOneByte (\r
- UINT8 *Data\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //I2C bus status checking\r
- Status = WaitForBusBusy();\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- //Poll till Receive ready bit is set.\r
- Status = PollForStatus(RRDY);\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- *Data = MmioRead8(I2C_DATA);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-I2CWriteOneByte (\r
- UINT8 Data\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //I2C bus status checking\r
- Status = WaitForBusBusy();\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- //Data transfer\r
- //Poll till Transmit ready bit is set\r
- Status = PollForStatus(XRDY);\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- MmioWrite8(I2C_DATA, Data);\r
-\r
- //Wait and check if the NACK is not set.\r
- gBS->Stall(1000);\r
- if (MmioRead16(I2C_STAT) & NACK) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-SmbusBlockRead (\r
- OUT UINT8 *Buffer,\r
- IN UINTN Length\r
- )\r
-{\r
- UINTN Index = 0;\r
- EFI_STATUS Status = EFI_SUCCESS;\r
-\r
- //Transfer configuration for receiving data.\r
- MmioWrite16(I2C_CNT, Length);\r
- //Need stop bit before sending data.\r
- MmioWrite16(I2C_CON, (I2C_EN | MST | STP | STT));\r
-\r
- while (Index < Length) {\r
- //Read a byte\r
- Status = I2CReadOneByte(&Buffer[Index++]);\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //Transfer completion\r
- Status = PollForStatus(ARDY);\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-SmbusBlockWrite (\r
- IN UINT8 *Buffer,\r
- IN UINTN Length\r
- )\r
-{\r
- UINTN Index = 0;\r
- EFI_STATUS Status = EFI_SUCCESS;\r
-\r
- //Transfer configuration for transmitting data\r
- MmioWrite16(I2C_CNT, Length);\r
- MmioWrite16(I2C_CON, (I2C_EN | TRX | MST | STT | STP));\r
-\r
- while (Index < Length) {\r
- //Send a byte\r
- Status = I2CWriteOneByte(Buffer[Index++]);\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //Transfer completion\r
- Status = PollForStatus(ARDY);\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-//\r
-// Public Functions.\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-SmbusExecute (\r
- IN CONST EFI_SMBUS_HC_PROTOCOL *This,\r
- IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,\r
- IN CONST EFI_SMBUS_DEVICE_COMMAND Command,\r
- IN CONST EFI_SMBUS_OPERATION Operation,\r
- IN CONST BOOLEAN PecCheck,\r
- IN OUT UINTN *Length,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- UINT8 *ByteBuffer = Buffer;\r
- EFI_STATUS Status = EFI_SUCCESS;\r
- UINT8 SlaveAddr = (UINT8)(SlaveAddress.SmbusDeviceAddress);\r
-\r
- if (PecCheck) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if ((Operation != EfiSmbusWriteBlock) && (Operation != EfiSmbusReadBlock)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //Set the Slave address.\r
- MmioWrite16(I2C_SA, SlaveAddr);\r
-\r
- if (Operation == EfiSmbusReadBlock) {\r
- Status = SmbusBlockRead(ByteBuffer, *Length);\r
- } else if (Operation == EfiSmbusWriteBlock) {\r
- Status = SmbusBlockWrite(ByteBuffer, *Length);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SmbusArpDevice (\r
- IN CONST EFI_SMBUS_HC_PROTOCOL *This,\r
- IN BOOLEAN ArpAll,\r
- IN EFI_SMBUS_UDID *SmbusUdid OPTIONAL,\r
- IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL\r
- )\r
-{\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SmbusGetArpMap (\r
- IN CONST EFI_SMBUS_HC_PROTOCOL *This,\r
- IN OUT UINTN *Length,\r
- IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap\r
- )\r
-{\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SmbusNotify (\r
- IN CONST EFI_SMBUS_HC_PROTOCOL *This,\r
- IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,\r
- IN CONST UINTN Data,\r
- IN CONST EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction\r
- )\r
-{\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_SMBUS_HC_PROTOCOL SmbusProtocol =\r
-{\r
- SmbusExecute,\r
- SmbusArpDevice,\r
- SmbusGetArpMap,\r
- SmbusNotify\r
-};\r
-\r
-EFI_STATUS\r
-InitializeSmbus (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_HANDLE Handle = NULL;\r
- EFI_STATUS Status;\r
-\r
- //Configure I2C controller.\r
- Status = ConfigureI2c();\r
- if (EFI_ERROR(Status)) {\r
- DEBUG ((EFI_D_ERROR, "InitializeI2c fails.\n"));\r
- return Status;\r
- }\r
-\r
- // Install the SMBUS interface\r
- Status = gBS->InstallMultipleProtocolInterfaces(&Handle, &gEfiSmbusHcProtocolGuid, &SmbusProtocol, NULL);\r
- ASSERT_EFI_ERROR(Status);\r
-\r
- return Status;\r
-}\r
-\r