Add Sample I2C Library for Baytrail I2C Controller.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei  <david.wei@intel.com>
Reviewed-by: Tim He <time.he@intel.com> 


git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17546 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
David Wei 2015-06-02 01:47:57 +00:00 committed by zwei4
parent c85bc0c9d4
commit 4e5220964b
12 changed files with 2437 additions and 0 deletions

View File

@ -0,0 +1,64 @@
/** @file
Interface Definitions for I2C Lib.
Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that 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 <Uefi.h>
#include <Library/IoLib.h>
#ifndef I2C_LIB_HEADER_H
#define I2C_LIB_HEADER_H
/**
Reads a Byte from I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be read
@param Offset Offset from which the data has to be read
@param ReadBytes Number of bytes to be read
@param *ReadBuffer Address to which the value read has to be stored
@return EFI_SUCCESS If the byte value has been successfully read
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS
ByteReadI2C(
IN UINT8 BusNo,
IN UINT8 SlaveAddress,
IN UINT8 Offset,
IN UINTN ReadBytes,
OUT UINT8 *ReadBuffer
);
/**
Writes a Byte to I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be written
@param Offset Offset from which the data has to be written
@param WriteBytes Number of bytes to be written
@param *Byte Address to which the value written is stored
@return EFI_SUCCESS If the byte value has been successfully read
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS ByteWriteI2C(
IN UINT8 BusNo,
IN UINT8 SlaveAddress,
IN UINT8 Offset,
IN UINTN WriteBytes,
IN UINT8 *WriteBuffer
);
#endif

View File

@ -0,0 +1,741 @@
/** @file
Functions for accessing I2C registers.
Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that 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 <Library/DebugLib.h>
#include <Library/TimerLib.h>
#include <PchRegs/PchRegsPcu.h>
#include <PchRegs.h>
#include <PlatformBaseAddresses.h>
#include <PchRegs/PchRegsLpss.h>
#include <Library/I2CLib.h>
#include <Protocol/GlobalNvsArea.h>
#include <Library/UefiBootServicesTableLib.h>
#include <I2CRegs.h>
#define GLOBAL_NVS_OFFSET(Field) (UINTN)((CHAR8*)&((EFI_GLOBAL_NVS_AREA*)0)->Field - (CHAR8*)0)
#define PCIEX_BASE_ADDRESS 0xE0000000
#define PCI_EXPRESS_BASE_ADDRESS ((VOID *) (UINTN) PCIEX_BASE_ADDRESS)
#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
((UINTN)PCI_EXPRESS_BASE_ADDRESS + \
(UINTN)(Bus << 20) + \
(UINTN)(Device << 15) + \
(UINTN)(Function << 12) + \
(UINTN)(Register) \
)
#define PCI_D31F0_REG_BASE PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
typedef struct _LPSS_PCI_DEVICE_INFO {
UINTN Segment;
UINTN BusNum;
UINTN DeviceNum;
UINTN FunctionNum;
UINTN Bar0;
UINTN Bar1;
} LPSS_PCI_DEVICE_INFO;
LPSS_PCI_DEVICE_INFO mLpssPciDeviceList[] = {
{0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_DMAC1, PCI_FUNCTION_NUMBER_PCH_LPSS_DMAC, 0xFE900000, 0xFE908000},
{0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C, PCI_FUNCTION_NUMBER_PCH_LPSS_I2C0, 0xFE910000, 0xFE918000},
{0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C, PCI_FUNCTION_NUMBER_PCH_LPSS_I2C1, 0xFE920000, 0xFE928000},
{0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C, PCI_FUNCTION_NUMBER_PCH_LPSS_I2C2, 0xFE930000, 0xFE938000},
{0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C, PCI_FUNCTION_NUMBER_PCH_LPSS_I2C3, 0xFE940000, 0xFE948000},
{0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C, PCI_FUNCTION_NUMBER_PCH_LPSS_I2C4, 0xFE950000, 0xFE958000},
{0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C, PCI_FUNCTION_NUMBER_PCH_LPSS_I2C5, 0xFE960000, 0xFE968000},
{0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C, PCI_FUNCTION_NUMBER_PCH_LPSS_I2C6, 0xFE970000, 0xFE978000}
};
#define LPSS_PCI_DEVICE_NUMBER sizeof(mLpssPciDeviceList)/sizeof(LPSS_PCI_DEVICE_INFO)
STATIC UINTN mI2CBaseAddress = 0;
STATIC UINT16 mI2CSlaveAddress = 0;
UINT16 mI2cMode=B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE ;
UINTN mI2cNvsBaseAddress[] = {
GLOBAL_NVS_OFFSET(LDMA2Addr),
GLOBAL_NVS_OFFSET(I2C1Addr),
GLOBAL_NVS_OFFSET(I2C2Addr),
GLOBAL_NVS_OFFSET(I2C3Addr),
GLOBAL_NVS_OFFSET(I2C4Addr),
GLOBAL_NVS_OFFSET(I2C5Addr),
GLOBAL_NVS_OFFSET(I2C6Addr),
GLOBAL_NVS_OFFSET(I2C7Addr)
};
/**
This function get I2Cx controller base address (BAR0).
@param I2cControllerIndex Bus Number of I2C controller.
@return I2C BAR.
**/
UINTN
GetI2cBarAddr(
IN UINT8 I2cControllerIndex
)
{
EFI_STATUS Status;
EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea;
UINTN AcpiBaseAddr;
UINTN PciMmBase=0;
ASSERT(gBS!=NULL);
Status = gBS->LocateProtocol (
&gEfiGlobalNvsAreaProtocolGuid,
NULL,
&GlobalNvsArea
);
//
// PCI mode from PEI ( Global NVS is not ready).
//
if (EFI_ERROR(Status)) {
DEBUG ((EFI_D_INFO, "GetI2cBarAddr() gEfiGlobalNvsAreaProtocolGuid:%r\n", Status));
//
// Global NVS is not ready.
//
return 0;
}
AcpiBaseAddr = *(UINTN*)((CHAR8*)GlobalNvsArea->Area + mI2cNvsBaseAddress[I2cControllerIndex + 1]);
//
//PCI mode from DXE (global NVS protocal) to LPSS OnReadytoBoot(swith to ACPI).
//
if(AcpiBaseAddr==0) {
PciMmBase = MmPciAddress (
mLpssPciDeviceList[I2cControllerIndex + 1].Segment,
mLpssPciDeviceList[I2cControllerIndex + 1].BusNum,
mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum,
mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum,
0
);
DEBUG((EFI_D_ERROR, "\nGetI2cBarAddr() I2C Device %x %x %x PciMmBase:%x\n", \
mLpssPciDeviceList[I2cControllerIndex + 1].BusNum, \
mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum, \
mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum, PciMmBase));
if (MmioRead32 (PciMmBase) != 0xFFFFFFFF) {
if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)& B_PCH_LPSS_I2C_STSCMD_MSE)) {
//
// Get the address allocted.
//
mLpssPciDeviceList[I2cControllerIndex + 1].Bar0=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR);
mLpssPciDeviceList[I2cControllerIndex + 1].Bar1=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR1);
}
}
AcpiBaseAddr =mLpssPciDeviceList[I2cControllerIndex+1].Bar0;
}
//
// ACPI mode from BDS: LPSS OnReadytoBoot
//
else {
DEBUG ((EFI_D_INFO, "GetI2cBarAddr() NVS Varialable is updated by this LIB or LPSS \n"));
}
DEBUG ((EFI_D_INFO, "GetI2cBarAddr() I2cControllerIndex+1 0x%x AcpiBaseAddr:0x%x \n", (I2cControllerIndex + 1), AcpiBaseAddr));
return AcpiBaseAddr;
}
/**
This function enables I2C controllers.
@param I2cControllerIndex Bus Number of I2C controllers.
@return Result of the I2C initialization.
**/
EFI_STATUS
ProgramPciLpssI2C (
IN UINT8 I2cControllerIndex
)
{
UINT32 PmcBase;
UINTN PciMmBase=0;
EFI_STATUS Status;
EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea;
UINT32 PmcFunctionDsiable[]= {
B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1,
B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2,
B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3,
B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4,
B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5,
B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6,
B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7
};
DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Start\n"));
//
// Set the VLV Function Disable Register to ZERO
//
PmcBase = MmioRead32 (PCI_D31F0_REG_BASE + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR;
if(MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS)&PmcFunctionDsiable[I2cControllerIndex]) {
DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End:I2C[%x] is disabled\n",I2cControllerIndex));
return EFI_NOT_READY;
}
DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C()------------I2cControllerIndex=%x,PMC=%x\n",I2cControllerIndex,MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS)));
{
PciMmBase = MmPciAddress (
mLpssPciDeviceList[I2cControllerIndex+1].Segment,
mLpssPciDeviceList[I2cControllerIndex+1].BusNum,
mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum,
mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum,
0
);
DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device %x %x %x PciMmBase:%x\n", \
mLpssPciDeviceList[I2cControllerIndex+1].BusNum, \
mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum, \
mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum, PciMmBase));
if (MmioRead32 (PciMmBase) != 0xFFFFFFFF) {
if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)& B_PCH_LPSS_I2C_STSCMD_MSE)) {
//
// Get the address allocted.
//
mLpssPciDeviceList[I2cControllerIndex+1].Bar0=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR);
mLpssPciDeviceList[I2cControllerIndex+1].Bar1=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR1);
DEBUG((EFI_D_ERROR, "ProgramPciLpssI2C() bar0:0x%x bar1:0x%x\n",mLpssPciDeviceList[I2cControllerIndex+1].Bar0, mLpssPciDeviceList[I2cControllerIndex+1].Bar1));
} else {
//
// Program BAR 0
//
ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & B_PCH_LPSS_I2C_BAR_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar0) && (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 != 0));
MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), (UINT32) (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & B_PCH_LPSS_I2C_BAR_BA));
//
// Program BAR 1
//
ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & B_PCH_LPSS_I2C_BAR1_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar1) && (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 != 0));
MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR1), (UINT32) (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & B_PCH_LPSS_I2C_BAR1_BA));
//
// Bus Master Enable & Memory Space Enable
//
MmioOr32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD), (UINT32) (B_PCH_LPSS_I2C_STSCMD_BME | B_PCH_LPSS_I2C_STSCMD_MSE));
ASSERT (MmioRead32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0) != 0xFFFFFFFF);
}
//
// Release Resets
//
MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + R_PCH_LPIO_I2C_MEM_RESETS,(B_PCH_LPIO_I2C_MEM_RESETS_FUNC | B_PCH_LPIO_I2C_MEM_RESETS_APB));
//
// Activate Clocks
//
MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + R_PCH_LPSS_I2C_MEM_PCP,0x80020003);//No use for A0
DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n"));
}
//
// BDS: already switched to ACPI mode
//
else {
ASSERT(gBS!=NULL);
Status = gBS->LocateProtocol (
&gEfiGlobalNvsAreaProtocolGuid,
NULL,
&GlobalNvsArea
);
if (EFI_ERROR(Status)) {
DEBUG ((EFI_D_INFO, "GetI2cBarAddr() gEfiGlobalNvsAreaProtocolGuid:%r\n", Status));
//
// gEfiGlobalNvsAreaProtocolGuid is not ready.
//
return 0;
}
mLpssPciDeviceList[I2cControllerIndex + 1].Bar0 = *(UINTN*)((CHAR8*)GlobalNvsArea->Area + mI2cNvsBaseAddress[I2cControllerIndex + 1]);
DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C(): is switched to ACPI 0x:%x \n",mLpssPciDeviceList[I2cControllerIndex + 1].Bar0));
}
}
DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End\n"));
return EFI_SUCCESS;
}
/**
Disable I2C Bus.
@param VOID.
@return Result of the I2C disabling.
**/
RETURN_STATUS
I2cDisable (
VOID
)
{
//
// 0.1 seconds
//
UINT32 NumTries = 10000;
MmioWrite32 ( mI2CBaseAddress + R_IC_ENABLE, 0 );
while ( 0 != ( MmioRead32 ( mI2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) {
MicroSecondDelay (10);
NumTries --;
if(0 == NumTries) {
return RETURN_NOT_READY;
}
}
return RETURN_SUCCESS;
}
/**
Enable I2C Bus.
@param VOID.
@return Result of the I2C disabling.
**/
RETURN_STATUS
I2cEnable (
VOID
)
{
//
// 0.1 seconds
//
UINT32 NumTries = 10000;
MmioWrite32 (mI2CBaseAddress + R_IC_ENABLE, 1);
while (0 == (MmioRead32 (mI2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) {
MicroSecondDelay (10);
NumTries --;
if(0 == NumTries){
return RETURN_NOT_READY;
}
}
return RETURN_SUCCESS;
}
/**
Enable I2C Bus.
@param VOID.
@return Result of the I2C enabling.
**/
RETURN_STATUS
I2cBusFrequencySet (
IN UINTN BusClockHertz
)
{
DEBUG((EFI_D_INFO,"InputFreq BusClockHertz: %d\r\n",BusClockHertz));
//
// Set the 100 KHz clock divider according to SV result and I2C spec
//
MmioWrite32 ( mI2CBaseAddress + R_IC_SS_SCL_HCNT, (UINT16)0x214 );
MmioWrite32 ( mI2CBaseAddress + R_IC_SS_SCL_LCNT, (UINT16)0x272 );
//
// Set the 400 KHz clock divider according to SV result and I2C spec
//
MmioWrite32 ( mI2CBaseAddress + R_IC_FS_SCL_HCNT, (UINT16)0x50 );
MmioWrite32 ( mI2CBaseAddress + R_IC_FS_SCL_LCNT, (UINT16)0xAD );
switch ( BusClockHertz ) {
case 100 * 1000:
MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x40);//100K
mI2cMode = V_SPEED_STANDARD;
break;
case 400 * 1000:
MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x32);//400K
mI2cMode = V_SPEED_FAST;
break;
default:
MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x09);//3.4M
mI2cMode = V_SPEED_HIGH;
}
//
// Select the frequency counter,
// Enable restart condition,
// Enable master FSM, disable slave FSM.
//
mI2cMode |= B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE;
return EFI_SUCCESS;
}
/**
Initializes the host controller to execute I2C commands.
@param I2cControllerIndex Index of I2C controller in LPSS device. 0 represents I2C0, which is PCI function 1 of LPSS device.
@return EFI_SUCCESS Opcode initialization on the I2C host controller completed.
@return EFI_DEVICE_ERROR Device error, operation failed.
**/
EFI_STATUS
I2CInit (
IN UINT8 I2cControllerIndex,
IN UINT16 SlaveAddress
)
{
EFI_STATUS Status=RETURN_SUCCESS;
UINT32 NumTries = 0;
UINTN GnvsI2cBarAddr=0;
//
// Verify the parameters
//
if ((1023 < SlaveAddress) || (6 < I2cControllerIndex)) {
Status = RETURN_INVALID_PARAMETER;
DEBUG((EFI_D_INFO,"I2CInit Exit with RETURN_INVALID_PARAMETER\r\n"));
return Status;
}
MmioWrite32 ( mI2CBaseAddress + R_IC_TAR, (UINT16)SlaveAddress );
mI2CSlaveAddress = SlaveAddress;
//
// 1.PEI: program and init ( before pci enumeration).
// 2.DXE:update address and re-init ( after pci enumeration).
// 3.BDS:update ACPI address and re-init ( after acpi mode is enabled).
//
if(mI2CBaseAddress == mLpssPciDeviceList[I2cControllerIndex + 1].Bar0) {
//
// I2CInit is already called.
//
GnvsI2cBarAddr=GetI2cBarAddr(I2cControllerIndex);
if((GnvsI2cBarAddr == 0)||(GnvsI2cBarAddr == mI2CBaseAddress)) {
DEBUG((EFI_D_INFO,"I2CInit Exit with mI2CBaseAddress:%x == [%x].Bar0\r\n",mI2CBaseAddress,I2cControllerIndex+1));
return RETURN_SUCCESS;
}
}
Status=ProgramPciLpssI2C(I2cControllerIndex);
if(Status!=EFI_SUCCESS) {
return Status;
}
mI2CBaseAddress = (UINT32) mLpssPciDeviceList[I2cControllerIndex + 1].Bar0;
DEBUG ((EFI_D_ERROR, "mI2CBaseAddress = 0x%x \n",mI2CBaseAddress));
//
// 1 seconds.
//
NumTries = 10000;
while ((1 == ( MmioRead32 ( mI2CBaseAddress + R_IC_STATUS) & STAT_MST_ACTIVITY ))) {
MicroSecondDelay(10);
NumTries --;
if(0 == NumTries) {
DEBUG((EFI_D_INFO, "Try timeout\r\n"));
return RETURN_DEVICE_ERROR;
}
}
Status = I2cDisable();
DEBUG((EFI_D_INFO, "I2cDisable Status = %r\r\n", Status));
I2cBusFrequencySet(400 * 1000);
MmioWrite32(mI2CBaseAddress + R_IC_INTR_MASK, 0x0);
if (0x7f < SlaveAddress )
SlaveAddress = ( SlaveAddress & 0x3ff ) | IC_TAR_10BITADDR_MASTER;
MmioWrite32 ( mI2CBaseAddress + R_IC_TAR, (UINT16)SlaveAddress );
MmioWrite32 ( mI2CBaseAddress + R_IC_RX_TL, 0);
MmioWrite32 ( mI2CBaseAddress + R_IC_TX_TL, 0 );
MmioWrite32 ( mI2CBaseAddress + R_IC_CON, mI2cMode);
Status = I2cEnable();
DEBUG((EFI_D_INFO, "I2cEnable Status = %r\r\n", Status));
MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT );
return EFI_SUCCESS;
}
/**
Reads a Byte from I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be read
@param Offset Offset from which the data has to be read
@param *Byte Address to which the value read has to be stored
@param Start Whether a RESTART is issued before the byte is sent or received
@param End Whether STOP is generated after a data byte is sent or received
@return EFI_SUCCESS IF the byte value has been successfully read
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS
ByteReadI2CBasic(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINTN ReadBytes,
OUT UINT8 *ReadBuffer,
IN UINT8 Start,
IN UINT8 End
)
{
EFI_STATUS Status;
UINT32 I2cStatus;
UINT16 ReceiveData;
UINT8 *ReceiveDataEnd;
UINT8 *ReceiveRequest;
UINT16 RawIntrStat;
UINT32 Count=0;
Status = EFI_SUCCESS;
ReceiveDataEnd = &ReadBuffer [ReadBytes];
if( ReadBytes ) {
ReceiveRequest = ReadBuffer;
DEBUG((EFI_D_INFO,"Read: ---------------%d bytes to RX\r\n",ReceiveDataEnd - ReceiveRequest));
while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd > ReadBuffer)) {
//
// Check for NACK
//
RawIntrStat = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_RawIntrStat);
if ( 0 != ( RawIntrStat & I2C_INTR_TX_ABRT )) {
MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT );
Status = RETURN_DEVICE_ERROR;
DEBUG((EFI_D_INFO,"TX ABRT ,%d bytes hasn't been transferred\r\n",ReceiveDataEnd - ReceiveRequest));
break;
}
//
// Determine if another byte was received
//
I2cStatus = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_STATUS);
if (0 != ( I2cStatus & STAT_RFNE )) {
ReceiveData = (UINT16)MmioRead32 ( mI2CBaseAddress + R_IC_DATA_CMD );
*ReadBuffer++ = (UINT8)ReceiveData;
DEBUG((EFI_D_INFO,"MmioRead32 ,1 byte 0x:%x is received\r\n",ReceiveData));
}
if(ReceiveDataEnd == ReceiveRequest) {
MicroSecondDelay ( FIFO_WRITE_DELAY );
DEBUG((EFI_D_INFO,"ReceiveDataEnd==ReceiveRequest------------%x\r\n",I2cStatus & STAT_RFNE));
Count++;
if(Count<1024) {
//
// To avoid sys hung without ul-pmc device on RVP,
// waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
//
continue;
} else {
break;
}
}
//
// Wait until a read request will fit.
//
if (0 == (I2cStatus & STAT_TFNF)) {
DEBUG((EFI_D_INFO,"Wait until a read request will fit\r\n"));
MicroSecondDelay (10);
continue;
}
//
// Issue the next read request.
//
if(End && Start) {
MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART|B_CMD_STOP);
} else if (!End && Start) {
MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART);
} else if (End && !Start) {
MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_STOP);
} else if (!End && !Start) {
MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD);
}
MicroSecondDelay (FIFO_WRITE_DELAY);
ReceiveRequest += 1;
}
}
return Status;
}
/**
Writes a Byte to I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be written
@param Offset Offset from which the data has to be read
@param *Byte Address to which the value written is stored
@param Start Whether a RESTART is issued before the byte is sent or received
@param End Whether STOP is generated after a data byte is sent or received
@return EFI_SUCCESS IF the byte value has been successfully written
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS ByteWriteI2CBasic(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINTN WriteBytes,
IN UINT8 *WriteBuffer,
IN UINT8 Start,
IN UINT8 End
)
{
EFI_STATUS Status;
UINT32 I2cStatus;
UINT8 *TransmitEnd;
UINT16 RawIntrStat;
UINT32 Count=0;
Status = EFI_SUCCESS;
Status=I2CInit(I2cControllerIndex, SlaveAddress);
if(Status!=EFI_SUCCESS)
return Status;
TransmitEnd = &WriteBuffer[WriteBytes];
if( WriteBytes ) {
DEBUG((EFI_D_INFO,"Write: --------------%d bytes to TX\r\n",TransmitEnd - WriteBuffer));
while (TransmitEnd > WriteBuffer) {
I2cStatus = MmioRead32 (mI2CBaseAddress + R_IC_STATUS);
RawIntrStat = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_RawIntrStat);
if (0 != ( RawIntrStat & I2C_INTR_TX_ABRT)) {
MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT);
Status = RETURN_DEVICE_ERROR;
DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
break;
}
if (0 == (I2cStatus & STAT_TFNF)) {
//
// If TX not full , will send cmd or continue to wait
//
MicroSecondDelay (FIFO_WRITE_DELAY);
continue;
}
if(End && Start) {
MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++)|B_CMD_RESTART|B_CMD_STOP);
} else if (!End && Start) {
MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++)|B_CMD_RESTART);
} else if (End && !Start) {
MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++)|B_CMD_STOP);
} else if (!End && !Start ) {
MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++));
}
//
// Add a small delay to work around some odd behavior being seen. Without this delay bytes get dropped.
//
MicroSecondDelay ( FIFO_WRITE_DELAY );//wait after send cmd
//
// Time out
//
while(1) {
RawIntrStat = MmioRead16 ( mI2CBaseAddress + R_IC_RawIntrStat );
if (0 != ( RawIntrStat & I2C_INTR_TX_ABRT)) {
MmioRead16 (mI2CBaseAddress + R_IC_CLR_TX_ABRT);
Status = RETURN_DEVICE_ERROR;
DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
}
if(0 == MmioRead16(mI2CBaseAddress + R_IC_TXFLR)) break;
MicroSecondDelay (FIFO_WRITE_DELAY);
Count++;
if(Count<1024) {
//
// to avoid sys hung without ul-pmc device on RVP.
// Waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
//
continue;
} else {
break;
}
}//while( 1 )
}
}
return Status;
}
/**
Reads a Byte from I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be read
@param Offset Offset from which the data has to be read
@param ReadBytes Number of bytes to be read
@param *ReadBuffer Address to which the value read has to be stored
@return EFI_SUCCESS IF the byte value has been successfully read
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS ByteReadI2C(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINT8 Offset,
IN UINTN ReadBytes,
OUT UINT8 *ReadBuffer
)
{
EFI_STATUS Status;
DEBUG ((EFI_D_INFO, "ByteReadI2C:---offset:0x%x\n",Offset));
Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress,1,&Offset,TRUE,FALSE);
Status = ByteReadI2CBasic(I2cControllerIndex, SlaveAddress,ReadBytes,ReadBuffer,TRUE,TRUE);
return Status;
}
/**
Writes a Byte to I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be written
@param Offset Offset from which the data has to be written
@param WriteBytes Number of bytes to be written
@param *Byte Address to which the value written is stored
@return EFI_SUCCESS IF the byte value has been successfully read
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS ByteWriteI2C(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINT8 Offset,
IN UINTN WriteBytes,
IN UINT8 *WriteBuffer
)
{
EFI_STATUS Status;
DEBUG ((EFI_D_INFO, "ByteWriteI2C:---offset/bytes/buf:0x%x,0x%x,0x%x,0x%x\n",Offset,WriteBytes,WriteBuffer,*WriteBuffer));
Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress,1,&Offset,TRUE,FALSE);
Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress,WriteBytes,WriteBuffer,FALSE,TRUE);
return Status;
}

View File

@ -0,0 +1,44 @@
## @file
# Instance of I2C Library.
#
# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
#
# 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 = I2CLib
FILE_GUID = 7f62bf44-2ba7-4c2d-9d4a-91c8906ff053
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = I2CLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources.common]
I2CLib.c
[LibraryClasses]
BaseLib
IoLib
TimerLib
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
Vlv2TbltDevicePkg/PlatformPkg.dec
Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
[Protocols]
gEfiGlobalNvsAreaProtocolGuid

View File

@ -0,0 +1,132 @@
/** @file
Register Definitions for I2C Driver/PEIM.
Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that 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 I2C_REGS_H
#define I2C_REGS_H
//
// FIFO write delay value.
//
#define FIFO_WRITE_DELAY 2
//
// MMIO Register Definitions.
//
#define R_IC_CON ( 0x00) // I2C Control
#define B_IC_RESTART_EN BIT5
#define B_IC_SLAVE_DISABLE BIT6
#define V_SPEED_STANDARD 0x02
#define V_SPEED_FAST 0x04
#define V_SPEED_HIGH 0x06
#define B_MASTER_MODE BIT0
#define R_IC_TAR ( 0x04) // I2C Target Address
#define IC_TAR_10BITADDR_MASTER BIT12
#define R_IC_SAR ( 0x08) // I2C Slave Address
#define R_IC_HS_MADDR ( 0x0C) // I2C HS MasterMode Code Address
#define R_IC_DATA_CMD ( 0x10) // I2C Rx/Tx Data Buffer and Command
#define B_READ_CMD BIT8 // 1 = read, 0 = write
#define B_CMD_STOP BIT9 // 1 = STOP
#define B_CMD_RESTART BIT10 // 1 = IC_RESTART_EN
#define V_WRITE_CMD_MASK ( 0xFF)
#define R_IC_SS_SCL_HCNT ( 0x14) // Standard Speed I2C Clock SCL High Count
#define R_IC_SS_SCL_LCNT ( 0x18) // Standard Speed I2C Clock SCL Low Count
#define R_IC_FS_SCL_HCNT ( 0x1C) // Full Speed I2C Clock SCL High Count
#define R_IC_FS_SCL_LCNT ( 0x20) // Full Speed I2C Clock SCL Low Count
#define R_IC_HS_SCL_HCNT ( 0x24) // High Speed I2C Clock SCL High Count
#define R_IC_HS_SCL_LCNT ( 0x28) // High Speed I2C Clock SCL Low Count
#define R_IC_INTR_STAT ( 0x2C) // I2C Inetrrupt Status
#define R_IC_INTR_MASK ( 0x30) // I2C Interrupt Mask
#define I2C_INTR_GEN_CALL BIT11 // General call received
#define I2C_INTR_START_DET BIT10
#define I2C_INTR_STOP_DET BIT9
#define I2C_INTR_ACTIVITY BIT8
#define I2C_INTR_TX_ABRT BIT6 // Set on NACK
#define I2C_INTR_TX_EMPTY BIT4
#define I2C_INTR_TX_OVER BIT3
#define I2C_INTR_RX_FULL BIT2 // Data bytes in RX FIFO over threshold
#define I2C_INTR_RX_OVER BIT1
#define I2C_INTR_RX_UNDER BIT0
#define R_IC_RawIntrStat ( 0x34) // I2C Raw Interrupt Status
#define R_IC_RX_TL ( 0x38) // I2C Receive FIFO Threshold
#define R_IC_TX_TL ( 0x3C) // I2C Transmit FIFO Threshold
#define R_IC_CLR_INTR ( 0x40) // Clear Combined and Individual Interrupts
#define R_IC_CLR_RX_UNDER ( 0x44) // Clear RX_UNDER Interrupt
#define R_IC_CLR_RX_OVER ( 0x48) // Clear RX_OVERinterrupt
#define R_IC_CLR_TX_OVER ( 0x4C) // Clear TX_OVER interrupt
#define R_IC_CLR_RD_REQ ( 0x50) // Clear RD_REQ interrupt
#define R_IC_CLR_TX_ABRT ( 0x54) // Clear TX_ABRT interrupt
#define R_IC_CLR_RX_DONE ( 0x58) // Clear RX_DONE interrupt
#define R_IC_CLR_ACTIVITY ( 0x5C) // Clear ACTIVITY interrupt
#define R_IC_CLR_STOP_DET ( 0x60) // Clear STOP_DET interrupt
#define R_IC_CLR_START_DET ( 0x64) // Clear START_DET interrupt
#define R_IC_CLR_GEN_CALL ( 0x68) // Clear GEN_CALL interrupt
#define R_IC_ENABLE ( 0x6C) // I2C Enable
#define R_IC_STATUS ( 0x70) // I2C Status
#define R_IC_SDA_HOLD ( 0x7C) // I2C IC_DEFAULT_SDA_HOLD//16bits
#define STAT_MST_ACTIVITY BIT5 // Master FSM Activity Status.
#define STAT_RFF BIT4 // RX FIFO is completely full
#define STAT_RFNE BIT3 // RX FIFO is not empty
#define STAT_TFE BIT2 // TX FIFO is completely empty
#define STAT_TFNF BIT1 // TX FIFO is not full
#define R_IC_TXFLR ( 0x74) // Transmit FIFO Level Register
#define R_IC_RXFLR ( 0x78) // Receive FIFO Level Register
#define R_IC_TX_ABRT_SOURCE ( 0x80) // I2C Transmit Abort Status Register
#define R_IC_SLV_DATA_NACK_ONLY ( 0x84) // Generate SLV_DATA_NACK Register
#define R_IC_DMA_CR ( 0x88) // DMA Control Register
#define R_IC_DMA_TDLR ( 0x8C) // DMA Transmit Data Level
#define R_IC_DMA_RDLR ( 0x90) // DMA Receive Data Level
#define R_IC_SDA_SETUP ( 0x94) // I2C SDA Setup Register
#define R_IC_ACK_GENERAL_CALL ( 0x98) // I2C ACK General Call Register
#define R_IC_ENABLE_STATUS ( 0x9C) // I2C Enable Status Register
#define R_IC_COMP_PARAM ( 0xF4) // Component Parameter Register
#define R_IC_COMP_VERSION ( 0xF8) // Component Version ID
#define R_IC_COMP_TYPE ( 0xFC) // Component Type
#define I2C_SS_SCL_HCNT_VALUE_100M 0x1DD
#define I2C_SS_SCL_LCNT_VALUE_100M 0x1E4
#define I2C_FS_SCL_HCNT_VALUE_100M 0x54
#define I2C_FS_SCL_LCNT_VALUE_100M 0x9a
#define I2C_HS_SCL_HCNT_VALUE_100M 0x7
#define I2C_HS_SCL_LCNT_VALUE_100M 0xE
#define IC_TAR_10BITADDR_MASTER BIT12
#define FIFO_SIZE 32
#define R_IC_INTR_STAT ( 0x2C) // I2c Inetrrupt Status
#define R_IC_INTR_MASK ( 0x30) // I2c Interrupt Mask
#define I2C_INTR_GEN_CALL BIT11 // General call received
#define I2C_INTR_START_DET BIT10
#define I2C_INTR_STOP_DET BIT9
#define I2C_INTR_ACTIVITY BIT8
#define I2C_INTR_TX_ABRT BIT6 // Set on NACK
#define I2C_INTR_TX_EMPTY BIT4
#define I2C_INTR_TX_OVER BIT3
#define I2C_INTR_RX_FULL BIT2 // Data bytes in RX FIFO over threshold
#define I2C_INTR_RX_OVER BIT1
#define I2C_INTR_RX_UNDER BIT0
#define R_PCH_LPIO_I2C_MEM_RESETS 0x804 // Software Reset
#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC BIT1 // Function Clock Domain Reset
#define B_PCH_LPIO_I2C_MEM_RESETS_APB BIT0 // APB Domain Reset
#define R_PCH_LPSS_I2C_MEM_PCP 0x800 // Private Clock Parameters
#endif

View File

@ -0,0 +1,50 @@
/** @file
Misc Registers Definition.
Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that 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 _I2C_ACCESS_H_
#define _I2C_ACCESS_H_
#include "I2CIoLibPei.h"
#define DEFAULT_PCI_BUS_NUMBER_PCH 0
#define PCI_DEVICE_NUMBER_PCH_LPC 31
#define PCI_FUNCTION_NUMBER_PCH_LPC 0
#define R_PCH_LPC_ACPI_BASE 0x40 // ABASE, 16bit
#define R_PCH_LPC_ACPI_BASEADR 0x400 // ABASE, 16bit
#define B_PCH_LPC_ACPI_BASE_EN BIT1 // Enable Bit
#define B_PCH_LPC_ACPI_BASE_BAR 0x0000FF80 // Base Address, 128 Bytes
#define V_PCH_ACPI_PM1_TMR_MAX_VAL 0x1000000 // The timer is 24 bit overflow
#define B_PCH_ACPI_PM1_TMR_VAL 0xFFFFFF // The timer value mask
#define R_PCH_ACPI_PM1_TMR 0x08 // Power Management 1 Timer
#define V_PCH_ACPI_PM1_TMR_FREQUENCY 3579545 // Timer Frequency
#define PchLpcPciCfg8(Register) I2CLibPeiMmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
#define PCIEX_BASE_ADDRESS 0xE0000000
#define PCI_EXPRESS_BASE_ADDRESS ((VOID *) (UINTN) PCIEX_BASE_ADDRESS)
#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
( (UINTN)PCI_EXPRESS_BASE_ADDRESS + \
(UINTN)(Bus << 20) + \
(UINTN)(Device << 15) + \
(UINTN)(Function << 12) + \
(UINTN)(Register) \
)
#endif

View File

@ -0,0 +1,52 @@
/** @file
MicroSecondDelay implementation of ACPI Timer.
Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that 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 "PiPei.h"
#include "I2CAccess.h"
#include "I2CDelayPei.h"
#include <Library/DebugLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Ppi/Stall.h>
/**
Stalls the CPU for at least the given number of microseconds.
Stalls the CPU for the number of microseconds specified by MicroSeconds.
@param MicroSeconds The minimum number of microseconds to delay.
@return EFI_STATUS
**/
EFI_STATUS
EFIAPI
MicroSecondDelay (
IN UINTN MicroSeconds
)
{
EFI_PEI_STALL_PPI *StallPpi;
EFI_STATUS Status;
CONST EFI_PEI_SERVICES **PeiServices;
PeiServices = GetPeiServicesTablePointer();
Status = (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, &StallPpi);
ASSERT(!EFI_ERROR(Status));
StallPpi->Stall (PeiServices, StallPpi, MicroSeconds);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,36 @@
/** @file
MicroSecondDelay implementation of ACPI Timer.
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
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 __I2C_DELAY_PEI__
#define __I2C_DELAY_PEI__
#include "PiPei.h"
/**
Stalls the CPU for at least the given number of microseconds.
Stalls the CPU for the number of microseconds specified by MicroSeconds.
@param MicroSeconds The minimum number of microseconds to delay.
@return MicroSeconds
**/
EFI_STATUS
EFIAPI
MicroSecondDelay (
IN UINTN MicroSeconds
);
#endif

View File

@ -0,0 +1,184 @@
/** @file
Functions for access I2C MMIO register.
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
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 <PiPei.h>
#include <Library/DebugLib.h>
#include <Library/PeiServicesTablePointerLib.h>
/**
Reads an 8-bit MMIO register.
Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
returned. This function must guarantee that all MMIO read and write
operations are serialized.
If 8-bit MMIO register operations are not supported, then ASSERT().
@param Address The MMIO register to read.
@return The value read.
**/
UINT8
EFIAPI
I2CLibPeiMmioRead8 (
IN UINTN Address
)
{
UINT8 Value;
Value = *(volatile UINT8*)Address;
return Value;
}
/**
Reads a 16-bit MMIO register.
Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
returned. This function must guarantee that all MMIO read and write
operations are serialized.
If 16-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 16-bit boundary, then ASSERT().
@param Address The MMIO register to read.
@return The value read.
**/
UINT16
EFIAPI
I2CLibPeiMmioRead16 (
IN UINTN Address
)
{
UINT16 Value;
ASSERT ((Address & 1) == 0);
Value = *(volatile UINT16*)Address;
return Value;
}
/**
Writes a 16-bit MMIO register.
Writes the 16-bit MMIO register specified by Address with the value specified
by Value and returns Value. This function must guarantee that all MMIO read
and write operations are serialized.
If 16-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 16-bit boundary, then ASSERT().
@param Address The MMIO register to write.
@param Value The value to write to the MMIO register.
@return Value.
**/
UINT16
EFIAPI
I2CLibPeiMmioWrite16 (
IN UINTN Address,
IN UINT16 Value
)
{
ASSERT ((Address & 1) == 0);
*(volatile UINT16*)Address = Value;
return Value;
}
/**
Reads a 32-bit MMIO register.
Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
returned. This function must guarantee that all MMIO read and write
operations are serialized.
If 32-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 32-bit boundary, then ASSERT().
@param Address The MMIO register to read.
@return The value read.
**/
UINT32
EFIAPI
I2CLibPeiMmioRead32 (
IN UINTN Address
)
{
UINT32 Value;
ASSERT ((Address & 3) == 0);
Value = *(volatile UINT32*)Address;
return Value;
}
/**
Writes a 32-bit MMIO register.
Writes the 32-bit MMIO register specified by Address with the value specified
by Value and returns Value. This function must guarantee that all MMIO read
and write operations are serialized.
If 32-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 32-bit boundary, then ASSERT().
@param Address The MMIO register to write.
@param Value The value to write to the MMIO register.
@return Value.
**/
UINT32
EFIAPI
I2CLibPeiMmioWrite32 (
IN UINTN Address,
IN UINT32 Value
)
{
ASSERT ((Address & 3) == 0);
*(volatile UINT32*)Address = Value;
return Value;
}
/**
OR a 32-bit MMIO register.
OR the 32-bit MMIO register specified by Address with the value specified
by Value and returns Value. This function must guarantee that all MMIO read
and write operations are serialized.
If 32-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 32-bit boundary, then ASSERT().
@param Address The MMIO register to write OR.
@param Value The value to OR to the MMIO register.
@return Value.
**/
UINT32
EFIAPI
I2CLibPeiMmioOr32 (
IN UINTN Address,
IN UINT32 OrData
)
{
return I2CLibPeiMmioWrite32 (Address, I2CLibPeiMmioRead32(Address) | OrData);
}

View File

@ -0,0 +1,159 @@
/** @file
Functions for access I2C MMIO register.
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
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 __I2C_IOLIB_PEI__
#define __I2C_IOLIB_PEI__
#include <PiPei.h>
/**
Reads an 8-bit MMIO register.
Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
returned. This function must guarantee that all MMIO read and write
operations are serialized.
If 8-bit MMIO register operations are not supported, then ASSERT().
@param Address The MMIO register to read.
@return The value read.
**/
UINT8
EFIAPI
I2CLibPeiMmioRead8 (
IN UINTN Address
);
/**
Reads a 16-bit MMIO register.
Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
returned. This function must guarantee that all MMIO read and write
operations are serialized.
If 16-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 16-bit boundary, then ASSERT().
@param Address The MMIO register to read.
@return The value read.
**/
UINT16
EFIAPI
I2CLibPeiMmioRead16 (
IN UINTN Address
);
/**
Writes a 16-bit MMIO register.
Writes the 16-bit MMIO register specified by Address with the value specified
by Value and returns Value. This function must guarantee that all MMIO read
and write operations are serialized.
If 16-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 16-bit boundary, then ASSERT().
@param Address The MMIO register to write.
@param Value The value to write to the MMIO register.
@return Value.
**/
UINT16
EFIAPI
I2CLibPeiMmioWrite16 (
IN UINTN Address,
IN UINT16 Value
);
/**
Reads a 32-bit MMIO register.
Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
returned. This function must guarantee that all MMIO read and write
operations are serialized.
If 32-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 32-bit boundary, then ASSERT().
@param Address The MMIO register to read.
@return The value read.
**/
UINT32
EFIAPI
I2CLibPeiMmioRead32 (
IN UINTN Address
);
/**
Writes a 32-bit MMIO register.
Writes the 32-bit MMIO register specified by Address with the value specified
by Value and returns Value. This function must guarantee that all MMIO read
and write operations are serialized.
If 32-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 32-bit boundary, then ASSERT().
@param Address The MMIO register to write.
@param Value The value to write to the MMIO register.
@return Value.
**/
UINT32
EFIAPI
I2CLibPeiMmioWrite32 (
IN UINTN Address,
IN UINT32 Value
);
/**
OR a 32-bit MMIO register.
OR the 32-bit MMIO register specified by Address with the value specified
by Value and returns Value. This function must guarantee that all MMIO read
and write operations are serialized.
If 32-bit MMIO register operations are not supported, then ASSERT().
If Address is not aligned on a 32-bit boundary, then ASSERT().
@param Address The MMIO register to write OR.
@param Value The value to OR to the MMIO register.
@return Value.
**/
UINT32
EFIAPI
I2CLibPeiMmioOr32 (
IN UINTN Address,
IN UINT32 OrData
);
#endif

View File

@ -0,0 +1,644 @@
/** @file
I2C PEI Lib Instance.
Copyright (c) 1999- 2015, Intel Corporation. All rights reserved.<BR>
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 "I2CDelayPei.h"
#include "I2CIoLibPei.h"
#include "I2CAccess.h"
#include "I2CLibPei.h"
#include <PlatformBaseAddresses.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/HobLib.h>
#include <PchRegs/PchRegsPcu.h>
#include <PchRegs/PchRegsLpss.h>
#define LPSS_PCI_DEVICE_NUMBER 8
#define R_PCH_LPIO_I2C_MEM_RESETS 0x804 // Software Reset
#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC BIT1 // Function Clock Domain Reset
#define B_PCH_LPIO_I2C_MEM_RESETS_APB BIT0 // APB Domain Reset
#define R_PCH_LPSS_I2C_MEM_PCP 0x800 // Private Clock Parameters
#define PEI_TEPM_LPSS_DMA_BAR 0xFE900000
#define PEI_TEPM_LPSS_I2C0_BAR 0xFE910000
#define PCI_CONFIG_SPACE_SIZE 0x10000
EFI_GUID mI2CPeiInitGuid = {
0x96DED71A, 0xB9E7, 0x4EAD, 0x96, 0x2C, 0x01, 0x69, 0x3C, 0xED, 0x2A, 0x64
};
UINT16 I2CGPIO[]= {
//
// 19.1.6 I2C0
// I2C0_SDA-OD-O - write 0x2003CC81 to IOBASE + 0x0210
// I2C0_SCL-OD-O - write 0x2003CC81 to IOBASE + 0x0200
//
0x0210,
0x0200,
//
// 19.1.7 I2C1
// I2C1_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01F0
// I2C1_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01E0
//
0x01F0,
0x01E0,
//
// 19.1.8 I2C2
// I2C2_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01D0
// I2C2_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01B0
//
0x01D0,
0x01B0,
//
// 19.1.9 I2C3
// I2C3_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0190
// I2C3_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01C0
//
0x0190,
0x01C0,
//
// 19.1.10 I2C4
// I2C4_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01A0
// I2C4_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0170
//
0x01A0,
0x0170,
//
// 19.1.11 I2C5
// I2C5_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0150
// I2C5_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0140
//
0x0150,
0x0140,
//
// 19.1.12 I2C6
// I2C6_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0180
// I2C6_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0160
//
0x0180,
0x0160
};
/**
Constructor of this library.
@param VOID
@return EFI_SUCCESS
**/
EFI_STATUS
EFIAPI
IntelI2CPeiLibConstructor (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
UINTN Index;
for (Index = 0; Index < sizeof(I2CGPIO)/sizeof(UINT16); Index ++) {
I2CLibPeiMmioWrite32(IO_BASE_ADDRESS+I2CGPIO[Index], 0x2003CC81);
}
return EFI_SUCCESS;
}
/**
Programe all I2C controllers on LPSS.
I2C0 is function 1 of LPSS. I2C1 is function 2 of LPSS, etc..
@param VOID
@return EFI_SUCCESS
**/
EFI_STATUS
ProgramPciLpssI2C (
VOID
)
{
UINT32 PmcBase;
UINT32 DevID;
UINTN PciMmBase=0;
UINTN Index;
UINTN Bar0;
UINTN Bar1;
DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() Start\n"));
//
// Set the VLV Function Disable Register to ZERO
//
PmcBase = I2CLibPeiMmioRead32(PciD31F0RegBase + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR;
if(I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)&
(B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2
| B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5
| B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7)) {
I2CLibPeiMmioWrite32(
PmcBase+R_PCH_PMC_FUNC_DIS,
I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)& \
~(B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2 \
| B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 \
| B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6|B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7)
);
DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() enable all I2C controllers\n"));
}
for(Index = 0; Index < LPSS_PCI_DEVICE_NUMBER; Index ++) {
PciMmBase = MmPciAddress (
0,
DEFAULT_PCI_BUS_NUMBER_PCH,
PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
Index,
0
);
DevID = I2CLibPeiMmioRead32(PciMmBase);
Bar0 = PEI_TEPM_LPSS_DMA_BAR + (Index * PCI_CONFIG_SPACE_SIZE);
Bar1 = Bar0 + 0x8000;
DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device Function=%x DevID=%08x\n", Index, DevID));
//
// Check if device present
//
if (DevID != 0xFFFFFFFF) {
if(!(I2CLibPeiMmioRead32 (PciMmBase + R_PCH_LPSS_I2C_STSCMD) & B_PCH_LPSS_I2C_STSCMD_MSE)) {
//
// Program BAR 0
//
I2CLibPeiMmioWrite32((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), (UINT32)(Bar0 & B_PCH_LPSS_I2C_BAR_BA));
DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x \n",I2CLibPeiMmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR)));
//
// Program BAR 1
//
I2CLibPeiMmioWrite32 ((UINTN)(PciMmBase + R_PCH_LPSS_I2C_BAR1), (UINT32)(Bar1 & B_PCH_LPSS_I2C_BAR1_BA));
DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x \n",I2CLibPeiMmioRead32(PciMmBase+R_PCH_LPSS_I2C_BAR1)));
//
// Bus Master Enable & Memory Space Enable
//
I2CLibPeiMmioWrite32((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD), (UINT32)(B_PCH_LPSS_I2C_STSCMD_BME | B_PCH_LPSS_I2C_STSCMD_MSE));
}
//
// Release Resets
//
I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPIO_I2C_MEM_RESETS, (B_PCH_LPIO_I2C_MEM_RESETS_FUNC | B_PCH_LPIO_I2C_MEM_RESETS_APB));
//
// Activate Clocks
//
I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPSS_I2C_MEM_PCP, 0x80020003);//No use for A0
DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n"));
}
}
DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() End\n"));
return EFI_SUCCESS;
}
/**
Disable I2C Bus.
@param I2cControllerIndex Index of I2C controller.
@return EFI_SUCCESS
**/
EFI_STATUS
I2cDisable (
IN UINT8 I2cControllerIndex
)
{
UINTN I2CBaseAddress;
UINT32 NumTries = 10000; // 0.1 seconds
I2CBaseAddress = (UINT32) PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE;
I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_ENABLE, 0);
while (0 != ( I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_ENABLE_STATUS ) & 1)) {
MicroSecondDelay (10);
NumTries --;
if(0 == NumTries) return EFI_NOT_READY;
}
return EFI_SUCCESS;
}
/**
Enable I2C Bus.
@param I2cControllerIndex Index of I2C controller.
@return EFI_SUCCESS
**/
EFI_STATUS
I2cEnable (
IN UINT8 I2cControllerIndex
)
{
UINTN I2CBaseAddress;
UINT32 NumTries = 10000; // 0.1 seconds
I2CBaseAddress = (UINT32) PEI_TEPM_LPSS_I2C0_BAR+ I2cControllerIndex * PCI_CONFIG_SPACE_SIZE;
I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_ENABLE, 1);
while (0 == ( I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_ENABLE_STATUS ) & 1)) {
MicroSecondDelay (10);
NumTries --;
if(0 == NumTries) return EFI_NOT_READY;
}
return EFI_SUCCESS;
}
/**
Set the I2C controller bus clock frequency.
@param[in] This Address of the library's I2C context structure
@param[in] PlatformData Address of the platform configuration data
@param[in] BusClockHertz New I2C bus clock frequency in Hertz
@retval RETURN_SUCCESS The bus frequency was set successfully.
@retval RETURN_UNSUPPORTED The controller does not support this frequency.
**/
EFI_STATUS
I2cBusFrequencySet (
IN UINTN I2CBaseAddress,
IN UINTN BusClockHertz,
IN UINT16 *I2cMode
)
{
DEBUG((EFI_D_INFO,"InputFreq BusClockHertz: %d\r\n",BusClockHertz));
*I2cMode = B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE;
//
// Set the 100 KHz clock divider
//
// From Table 10 of the I2C specification
//
// High: 4.00 uS
// Low: 4.70 uS
//
I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_SS_SCL_HCNT, (UINT16)0x214 );
I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_SS_SCL_LCNT, (UINT16)0x272 );
//
// Set the 400 KHz clock divider
//
// From Table 10 of the I2C specification
//
// High: 0.60 uS
// Low: 1.30 uS
//
I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_FS_SCL_HCNT, (UINT16)0x50 );
I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_FS_SCL_LCNT, (UINT16)0xAD );
switch ( BusClockHertz ) {
case 100 * 1000:
I2CLibPeiMmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x40);//100K
*I2cMode |= V_SPEED_STANDARD;
break;
case 400 * 1000:
I2CLibPeiMmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x32);//400K
*I2cMode |= V_SPEED_FAST;
break;
default:
I2CLibPeiMmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x09);//3.4M
*I2cMode |= V_SPEED_HIGH;
}
return EFI_SUCCESS;
}
/**
Initializes the host controller to execute I2C commands.
@param I2cControllerIndex Index of I2C controller in LPSS device. 0 represents I2C0, which is PCI function 1 of LPSS device.
@return EFI_SUCCESS Opcode initialization on the I2C host controller completed.
@return EFI_DEVICE_ERROR Device error, operation failed.
**/
EFI_STATUS
I2CInit (
UINT8 I2cControllerIndex,
UINT16 SlaveAddress
)
{
EFI_STATUS Status;
UINT32 NumTries = 0;
UINTN I2CBaseAddress;
UINT16 I2cMode;
UINTN PciMmBase=0;
PciMmBase = MmPciAddress (
0,
DEFAULT_PCI_BUS_NUMBER_PCH,
PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
(I2cControllerIndex + 1),
0
);
I2CBaseAddress = I2CLibPeiMmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR);
//
// Verify the parameters
//
if (1023 < SlaveAddress ) {
Status = EFI_INVALID_PARAMETER;
DEBUG((EFI_D_INFO,"I2cStartRequest Exit with Status %r\r\n", Status));
return Status;
}
if(I2CBaseAddress == (PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE)) {
return EFI_SUCCESS;
}
ProgramPciLpssI2C();
I2CBaseAddress = (UINT32) (PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE);
DEBUG ((EFI_D_ERROR, "I2CBaseAddress = 0x%x \n",I2CBaseAddress));
NumTries = 10000; // 1 seconds
while ((1 == ( I2CLibPeiMmioRead32 ( I2CBaseAddress + R_IC_STATUS) & STAT_MST_ACTIVITY ))) {
MicroSecondDelay(10);
NumTries --;
if(0 == NumTries)
return EFI_DEVICE_ERROR;
}
Status = I2cDisable (I2cControllerIndex);
DEBUG((EFI_D_INFO, "I2cDisable Status = %r\r\n", Status));
I2cBusFrequencySet(I2CBaseAddress, 400 * 1000, &I2cMode);//Set I2cMode
I2CLibPeiMmioWrite16(I2CBaseAddress + R_IC_INTR_MASK, 0x0);
if (0x7F < SlaveAddress) {
SlaveAddress = (SlaveAddress & 0x3ff ) | IC_TAR_10BITADDR_MASTER;
}
I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TAR, (UINT16) SlaveAddress );
I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_RX_TL, 0);
I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TX_TL, 0 );
I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_CON, I2cMode);
Status = I2cEnable(I2cControllerIndex);
DEBUG((EFI_D_INFO, "I2cEnable Status = %r\r\n", Status));
I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_CLR_TX_ABRT );
return EFI_SUCCESS;
}
/**
Reads a Byte from I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be read
@param Offset Offset from which the data has to be read
@param *Byte Address to which the value read has to be stored
@return EFI_SUCCESS If the byte value has been successfully read
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS ByteReadI2CBasic(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINTN ReadBytes,
OUT UINT8 *ReadBuffer,
IN UINT8 Start,
IN UINT8 End
)
{
EFI_STATUS Status;
UINT32 I2cStatus;
UINT16 ReceiveData;
UINT8 *ReceiveDataEnd;
UINT8 *ReceiveRequest;
UINT16 RawIntrStat;
UINTN I2CBaseAddress;
I2CBaseAddress = (UINT32)(PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE);
Status = EFI_SUCCESS;
I2CInit(I2cControllerIndex, SlaveAddress);
ReceiveDataEnd = &ReadBuffer [ReadBytes];
if(ReadBytes) {
ReceiveRequest = ReadBuffer;
DEBUG((EFI_D_INFO,"Read: ---------------%d bytes to RX\r\n",ReceiveDataEnd - ReceiveRequest));
while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd > ReadBuffer)) {
//
// Check for NACK
//
RawIntrStat = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_RawIntrStat );
if ( 0 != (RawIntrStat & I2C_INTR_TX_ABRT )) {
I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_CLR_TX_ABRT );
Status = RETURN_DEVICE_ERROR;
DEBUG((EFI_D_INFO,"TX ABRT ,%d bytes hasn't been transferred\r\n",ReceiveDataEnd - ReceiveRequest));
break;
}
//
// Determine if another byte was received
//
I2cStatus = I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_STATUS );
if ( 0 != ( I2cStatus & STAT_RFNE )) {
ReceiveData = I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_DATA_CMD );
*ReadBuffer++ = (UINT8)ReceiveData;
DEBUG((EFI_D_INFO,"MmioRead32 ,1 byte 0x:%x is received\r\n",ReceiveData));
}
if(ReceiveDataEnd==ReceiveRequest) {
//
// Waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
//
continue;
}
//
// Wait until a read request will fit
//
if ( 0 == ( I2cStatus & STAT_TFNF )) {
MicroSecondDelay ( 10 );
continue;
}
//
// Issue the next read request
//
if(End && Start ) {
I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART|B_CMD_STOP);
} else if (!End && Start ) {
I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART);
} else if (End && !Start ) {
I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_STOP);
} else if (!End && !Start ) {
I2CLibPeiMmioWrite16 ( I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD);
}
ReceiveRequest += 1;
}
}
return Status;
}
/**
Writes a Byte to I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be written
@param Offset Offset from which the data has to be read
@param *Byte Address to which the value written is stored
@return EFI_SUCCESS IF the byte value has been successfully written
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS
ByteWriteI2CBasic(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINTN WriteBytes,
IN UINT8 *WriteBuffer,
IN UINT8 Start,
IN UINT8 End
)
{
EFI_STATUS Status;
UINT32 I2cStatus;
UINT8 *TransmitEnd;
UINT16 RawIntrStat;
UINTN I2CBaseAddress;
I2CBaseAddress = (UINT32)PEI_TEPM_LPSS_I2C0_BAR+ I2cControllerIndex * PCI_CONFIG_SPACE_SIZE;
Status = EFI_SUCCESS;
I2CInit(I2cControllerIndex, SlaveAddress);
TransmitEnd = &WriteBuffer [WriteBytes];
if( WriteBytes ) {
DEBUG((EFI_D_INFO,"Write: --------------%d bytes to TX\r\n", TransmitEnd - WriteBuffer));
while ( TransmitEnd > WriteBuffer) {
I2cStatus = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_STATUS);
RawIntrStat = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_RawIntrStat);
if ( 0 != (RawIntrStat & I2C_INTR_TX_ABRT)) {
I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_CLR_TX_ABRT);
Status = RETURN_DEVICE_ERROR;
DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
break;
}
if (0 == ( I2cStatus & STAT_TFNF)) {
continue;
}
if(End && Start) {
I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++) | B_CMD_RESTART | B_CMD_STOP);
} else if (!End && Start ) {
I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++) | B_CMD_RESTART);
} else if (End && !Start ) {
I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++) | B_CMD_STOP);
} else if (!End && !Start ) {
I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++));
}
// Add a small delay to work around some odd behavior being seen. Without this delay bytes get dropped.
MicroSecondDelay ( FIFO_WRITE_DELAY );
}
}
if(EFI_ERROR(Status)) {
DEBUG((EFI_D_INFO,"I2cStartRequest Exit with Status %r\r\n",Status));
}
return Status;
}
/**
Reads a Byte from I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be read
@param Offset Offset from which the data has to be read
@param ReadBytes Number of bytes to be read
@param *ReadBuffer Address to which the value read has to be stored
@return EFI_SUCCESS IF the byte value has been successfully read
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS
ByteReadI2C(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINT8 Offset,
IN UINTN ReadBytes,
OUT UINT8 *ReadBuffer
)
{
EFI_STATUS Status;
DEBUG ((EFI_D_ERROR, "ByteReadI2C:---offset:0x%x\n",Offset));
Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, 1, &Offset,TRUE,FALSE);
Status = ByteReadI2CBasic(I2cControllerIndex, SlaveAddress, ReadBytes, ReadBuffer, TRUE, TRUE);
return Status;
}
/**
Writes a Byte to I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be written
@param Offset Offset from which the data has to be written
@param WriteBytes Number of bytes to be written
@param *Byte Address to which the value written is stored
@return EFI_SUCCESS IF the byte value has been successfully read
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS ByteWriteI2C(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINT8 Offset,
IN UINTN WriteBytes,
IN UINT8 *WriteBuffer
)
{
EFI_STATUS Status;
DEBUG ((EFI_D_ERROR, "ByteWriteI2C:---offset/bytes/buf:0x%x,0x%x,0x%x,0x%x\n",Offset,WriteBytes,WriteBuffer,*WriteBuffer));
Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, 1, &Offset, TRUE, FALSE);
Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, WriteBytes, WriteBuffer, FALSE, TRUE);
return Status;
}

View File

@ -0,0 +1,286 @@
/** @file
I2C PEI Lib Instance.
Copyright (c) 1999- 2015, Intel Corporation. All rights reserved.<BR>
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 I2C_PEI_REGS_H
#define I2C_PEI_REGS_H
#include "PiPei.h"
#define R_PCH_LPC_PMC_BASE 0x44
#define B_PCH_LPC_PMC_BASE_BAR 0xFFFFFE00
#define R_PCH_PMC_FUNC_DIS 0x34 // Function Disable Register
#define PCIEX_BASE_ADDRESS 0xE0000000
#define PciD31F0RegBase PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC7 BIT7 // LPSS SPI Disable
#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC6 BIT6 // LPSS HSUART #2 Disable
#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC5 BIT5 // LPSS HSUART #1 Disable
#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC4 BIT4 // LPSS I2S Disable
#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC3 BIT3 // LPSS PCM Disable
#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC2 BIT2 // LPSS I2C #2 Disable
#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC1 BIT1 // LPSS I2C #1 Disable
#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC0 BIT0 // LPSS DMA Disable
#define DEFAULT_PCI_BUS_NUMBER_PCH 0
#define R_PCH_LPSS_I2C_STSCMD 0x04 // Status & Command
#define B_PCH_LPSS_I2C_STSCMD_RMA BIT29 // RMA
#define B_PCH_LPSS_I2C_STSCMD_RCA BIT28 // RCA
#define B_PCH_LPSS_I2C_STSCMD_CAPLIST BIT20 // Capability List
#define B_PCH_LPSS_I2C_STSCMD_INTRSTS BIT19 // Interrupt Status
#define B_PCH_LPSS_I2C_STSCMD_INTRDIS BIT10 // Interrupt Disable
#define B_PCH_LPSS_I2C_STSCMD_SERREN BIT8 // SERR# Enable
#define B_PCH_LPSS_I2C_STSCMD_BME BIT2 // Bus Master Enable
#define B_PCH_LPSS_I2C_STSCMD_MSE BIT1 // Memory Space Enable
#define R_PCH_LPSS_I2C_BAR 0x10 // BAR
#define B_PCH_LPSS_I2C_BAR_BA 0xFFFFF000 // Base Address
#define B_PCH_LPSS_I2C_BAR_SI 0x00000FF0 // Size Indicator
#define B_PCH_LPSS_I2C_BAR_PF BIT3 // Prefetchable
#define B_PCH_LPSS_I2C_BAR_TYPE (BIT2 | BIT1) // Type
#define B_PCH_LPSS_I2C_BAR_MS BIT0 // Message Space
#define R_PCH_LPSS_I2C_BAR1 0x14 // BAR 1
#define B_PCH_LPSS_I2C_BAR1_BA 0xFFFFF000 // Base Address
#define B_PCH_LPSS_I2C_BAR1_SI 0x00000FF0 // Size Indicator
#define B_PCH_LPSS_I2C_BAR1_PF BIT3 // Prefetchable
#define B_PCH_LPSS_I2C_BAR1_TYPE (BIT2 | BIT1) // Type
#define B_PCH_LPSS_I2C_BAR1_MS BIT0 // Message Space
#define NUM_RETRIES 0xFFFF
//
// LPIO I2C Module Memory Space Registers
//
#define R_PCH_LPIO_I2C_MEM_RESETS 0x804 // Software Reset
#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC BIT1 // Function Clock Domain Reset
#define B_PCH_LPIO_I2C_MEM_RESETS_APB BIT0 // APB Domain Reset
#define R_PCH_LPSS_I2C_MEM_PCP 0x800 // Private Clock Parameters
#define bit(a) 1 << (a)
//
// MMIO Register Definitions
//
#define I2C0_REG_SPACE_ADDR_BASE 0xFF138000 //01K
#define R_IC_CON ( 0x00) // I2C Control
#define B_IC_RESTART_EN BIT5
#define B_IC_SLAVE_DISABLE BIT6
#define V_SPEED_STANDARD 0x02
#define V_SPEED_FAST 0x04
#define V_SPEED_HIGH 0x06
#define B_MASTER_MODE BIT0
#define R_IC_TAR ( 0x04) // I2C Target Address
#define IC_TAR_10BITADDR_MASTER BIT12
#define R_IC_SAR ( 0x08) // I2C Slave Address
#define R_IC_HS_MADDR ( 0x0C) // I2C HS MasterMode Code Address
#define R_IC_DATA_CMD ( 0x10) // I2C Rx/Tx Data Buffer and Command
#define B_READ_CMD BIT8 // 1 = read, 0 = write
#define B_CMD_STOP BIT9 // 1 = STOP
#define B_CMD_RESTART BIT10 // 1 = IC_RESTART_EN
#define V_WRITE_CMD_MASK ( 0xFF)
#define R_IC_SS_SCL_HCNT ( 0x14) // Standard Speed I2C Clock SCL High Count
#define R_IC_SS_SCL_LCNT ( 0x18) // Standard Speed I2C Clock SCL Low Count
#define R_IC_FS_SCL_HCNT ( 0x1C) // Full Speed I2C Clock SCL High Count
#define R_IC_FS_SCL_LCNT ( 0x20) // Full Speed I2C Clock SCL Low Count
#define R_IC_HS_SCL_HCNT ( 0x24) // High Speed I2C Clock SCL High Count
#define R_IC_HS_SCL_LCNT ( 0x28) // High Speed I2C Clock SCL Low Count
#define R_IC_INTR_STAT ( 0x2C) // I2C Inetrrupt Status
#define R_IC_INTR_MASK ( 0x30) // I2C Interrupt Mask
#define I2C_INTR_GEN_CALL BIT11 // General call received
#define I2C_INTR_START_DET BIT10
#define I2C_INTR_STOP_DET BIT9
#define I2C_INTR_ACTIVITY BIT8
#define I2C_INTR_TX_ABRT BIT6 // Set on NACK
#define I2C_INTR_TX_EMPTY BIT4
#define I2C_INTR_TX_OVER BIT3
#define I2C_INTR_RX_FULL BIT2 // Data bytes in RX FIFO over threshold
#define I2C_INTR_RX_OVER BIT1
#define I2C_INTR_RX_UNDER BIT0
#define R_IC_RawIntrStat ( 0x34) // I2C Raw Interrupt Status
#define R_IC_RX_TL ( 0x38) // I2C Receive FIFO Threshold
#define R_IC_TX_TL ( 0x3C) // I2C Transmit FIFO Threshold
#define R_IC_CLR_INTR ( 0x40) // Clear Combined and Individual Interrupts
#define R_IC_CLR_RX_UNDER ( 0x44) // Clear RX_UNDER Interrupt
#define R_IC_CLR_RX_OVER ( 0x48) // Clear RX_OVERinterrupt
#define R_IC_CLR_TX_OVER ( 0x4C) // Clear TX_OVER interrupt
#define R_IC_CLR_RD_REQ ( 0x50) // Clear RD_REQ interrupt
#define R_IC_CLR_TX_ABRT ( 0x54) // Clear TX_ABRT interrupt
#define R_IC_CLR_RX_DONE ( 0x58) // Clear RX_DONE interrupt
#define R_IC_CLR_ACTIVITY ( 0x5C) // Clear ACTIVITY interrupt
#define R_IC_CLR_STOP_DET ( 0x60) // Clear STOP_DET interrupt
#define R_IC_CLR_START_DET ( 0x64) // Clear START_DET interrupt
#define R_IC_CLR_GEN_CALL ( 0x68) // Clear GEN_CALL interrupt
#define R_IC_ENABLE ( 0x6C) // I2C Enable
#define R_IC_STATUS ( 0x70) // I2C Status
#define R_IC_SDA_HOLD ( 0x7C) // I2C IC_DEFAULT_SDA_HOLD//16bits
#define STAT_MST_ACTIVITY BIT5 // Master FSM Activity Status.
#define STAT_RFF BIT4 // RX FIFO is completely full
#define STAT_RFNE BIT3 // RX FIFO is not empty
#define STAT_TFE BIT2 // TX FIFO is completely empty
#define STAT_TFNF BIT1 // TX FIFO is not full
#define R_IC_TXFLR ( 0x74) // Transmit FIFO Level Register
#define R_IC_RXFLR ( 0x78) // Receive FIFO Level Register
#define R_IC_TX_ABRT_SOURCE ( 0x80) // I2C Transmit Abort Status Register
#define R_IC_SLV_DATA_NACK_ONLY ( 0x84) // Generate SLV_DATA_NACK Register
#define R_IC_DMA_CR ( 0x88) // DMA Control Register
#define R_IC_DMA_TDLR ( 0x8C) // DMA Transmit Data Level
#define R_IC_DMA_RDLR ( 0x90) // DMA Receive Data Level
#define R_IC_SDA_SETUP ( 0x94) // I2C SDA Setup Register
#define R_IC_ACK_GENERAL_CALL ( 0x98) // I2C ACK General Call Register
#define R_IC_ENABLE_STATUS ( 0x9C) // I2C Enable Status Register
#define R_IC_COMP_PARAM ( 0xF4) // Component Parameter Register
#define R_IC_COMP_VERSION ( 0xF8) // Component Version ID
#define R_IC_COMP_TYPE ( 0xFC) // Component Type
#define I2C_SS_SCL_HCNT_VALUE_100M 0x1DD
#define I2C_SS_SCL_LCNT_VALUE_100M 0x1E4
#define I2C_FS_SCL_HCNT_VALUE_100M 0x54
#define I2C_FS_SCL_LCNT_VALUE_100M 0x9a
#define I2C_HS_SCL_HCNT_VALUE_100M 0x7
#define I2C_HS_SCL_LCNT_VALUE_100M 0xE
//
// FIFO write workaround value.
//
#define FIFO_WRITE_DELAY 2
#define IC_TAR_10BITADDR_MASTER BIT12
#define FIFO_SIZE 32
#define R_IC_INTR_STAT ( 0x2C) // I2c Inetrrupt Status
#define R_IC_INTR_MASK ( 0x30) // I2c Interrupt Mask
#define I2C_INTR_GEN_CALL BIT11 // General call received
#define I2C_INTR_START_DET BIT10
#define I2C_INTR_STOP_DET BIT9
#define I2C_INTR_ACTIVITY BIT8
#define I2C_INTR_TX_ABRT BIT6 // Set on NACK
#define I2C_INTR_TX_EMPTY BIT4
#define I2C_INTR_TX_OVER BIT3
#define I2C_INTR_RX_FULL BIT2 // Data bytes in RX FIFO over threshold
#define I2C_INTR_RX_OVER BIT1
#define I2C_INTR_RX_UNDER BIT0
/**
Programe all I2C controllers on LPSS.
I2C0 is function 1 of LPSS. I2C1 is function 2 of LPSS, etc..
@param VOID
@return EFI_SUCCESS
**/
EFI_STATUS
ProgramPciLpssI2C (
VOID
);
/**
Reads a Byte from I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be read
@param Offset Offset from which the data has to be read
@param *Byte Address to which the value read has to be stored
@param Start Whether a RESTART is issued before the byte is sent or received
@param End Whether STOP is generated after a data byte is sent or received
@return EFI_SUCCESS If the byte value has been successfully read
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS
ByteReadI2CBasic(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINTN ReadBytes,
OUT UINT8 *ReadBuffer,
IN UINT8 Start,
IN UINT8 End
);
/**
Writes a Byte to I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be written
@param Offset Offset from which the data has to be read
@param *Byte Address to which the value written is stored
@param Start Whether a RESTART is issued before the byte is sent or received
@param End Whether STOP is generated after a data byte is sent or received
@return EFI_SUCCESS IF the byte value has been successfully written
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS
ByteWriteI2CBasic(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINTN WriteBytes,
IN UINT8 *WriteBuffer,
IN UINT8 Start,
IN UINT8 End
);
/**
Reads a Byte from I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be read
@param Offset Offset from which the data has to be read
@param ReadBytes Number of bytes to be read
@param *ReadBuffer Address to which the value read has to be stored
@return EFI_SUCCESS IF the byte value has been successfully read
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS
ByteReadI2C(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINT8 Offset,
IN UINTN ReadBytes,
OUT UINT8 *ReadBuffer
);
/**
Writes a Byte to I2C Device.
@param I2cControllerIndex I2C Bus no to which the I2C device has been connected
@param SlaveAddress Device Address from which the byte value has to be written
@param Offset Offset from which the data has to be written
@param WriteBytes Number of bytes to be written
@param *Byte Address to which the value written is stored
@return EFI_SUCCESS IF the byte value has been successfully read
@return EFI_DEVICE_ERROR Operation Failed, Device Error
**/
EFI_STATUS
ByteWriteI2C(
IN UINT8 I2cControllerIndex,
IN UINT8 SlaveAddress,
IN UINT8 Offset,
IN UINTN WriteBytes,
IN UINT8 *WriteBuffer
);
#endif

View File

@ -0,0 +1,45 @@
## @file
# Instance of I2C Library.
#
# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
#
# 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 = I2CLibPei
FILE_GUID = 8EF61509-890B-4FF2-B352-1C0E9CDDEC8B
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
LIBRARY_CLASS = LockBoxLib|PEIM
CONSTRUCTOR = IntelI2CPeiLibConstructor
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources.common]
I2CLibPei.c
I2CIoLibPei.c
[LibraryClasses]
TimerLib
[PPIs]
gEfiPeiStallPpiGuid
[Packages]
MdePkg/MdePkg.dec
Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec