mirror of https://github.com/acidanthera/audk.git
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:
parent
c85bc0c9d4
commit
4e5220964b
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue