19b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** @file 29b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyI2C Library for Quark I2C Controller. 39b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyFollows I2C Controller setup instructions as detailed in 49b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyQuark DataSheet (doc id: 329676) Section 19.1/19.1.3. 59b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 69b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 79b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyCopyright (c) 2013-2015 Intel Corporation. 89b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 99b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyThis program and the accompanying materials 109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyare licensed and made available under the terms and conditions of the BSD License 119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneywhich accompanies this distribution. The full text of the license may be found at 129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyhttp://opensource.org/licenses/bsd-license.php 139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#include "CommonHeader.h" 209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The Called to Common Service Entry. 239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @return None. 259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyVOID 299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyI2cCommonServiceEntry ( 309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney OUT UINT16 *SaveCmdPtr, 319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney OUT UINT32 *SaveBar0Ptr 329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *SaveBar0Ptr = IohMmPci32 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0); 359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (((*SaveBar0Ptr) & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK) == 0) { 369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IohMmPci32(0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0) = 389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney FixedPcdGet32 (PcdIohI2cMmioBase) & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK; 399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // also Save Cmd Register, Setup by InitializeInternal later during xfers. 429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *SaveCmdPtr = IohMmPci16 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_CMD); 449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The Called on Common Service Exit. 499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @return None. 519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyVOID 549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyI2cCommonServiceExit ( 559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN CONST UINT16 SaveCmd, 569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN CONST UINT32 SaveBar0 579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if ((SaveBar0 & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK) == 0) { 619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IohMmPci16 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_CMD) = SaveCmd; 629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IohMmPci32 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0) = SaveBar0; 639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The GetI2CIoPortBaseAddress() function gets IO port base address of I2C Controller. 699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Always reads PCI configuration space to get MMIO base address of I2C Controller. 719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @return The IO port base address of I2C controller. 739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyUINTN 769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyGetI2CIoPortBaseAddress ( 779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney VOID 789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CIoPortBaseAddress; 819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Get I2C Memory Mapped registers base address. 849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CIoPortBaseAddress = IohMmPci32(0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0); 869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Make sure that the IO port base address has been properly set. 899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ASSERT (I2CIoPortBaseAddress != 0); 919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ASSERT (I2CIoPortBaseAddress != 0xFF); 929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return I2CIoPortBaseAddress; 949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The EnableI2CMmioSpace() function enables access to I2C MMIO space. 999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 1019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyVOID 1029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEnableI2CMmioSpace ( 1039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney VOID 1049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 1059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 1069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT8 PciCmd; 1079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Read PCICMD. Bus=0, Dev=0, Func=0, Reg=0x4 1109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney PciCmd = IohMmPci8(0, I2C_Bus, I2C_Device, I2C_Func, PCI_REG_PCICMD); 1129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Enable Bus Master(Bit2), MMIO Space(Bit1) & I/O Space(Bit0) 1159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney PciCmd |= 0x7; 1179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IohMmPci8(0, I2C_Bus, I2C_Device, I2C_Func, PCI_REG_PCICMD) = PciCmd; 1189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 1209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 1229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The DisableI2CController() functions disables I2C Controller. 1239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 1259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyVOID 1269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyDisableI2CController ( 1279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney VOID 1289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 1299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 1309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CIoPortBaseAddress; 1319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 Addr; 1329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 Data; 1339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT8 PollCount; 1349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney PollCount = 0; 1369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Get I2C Memory Mapped registers base address. 1399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CIoPortBaseAddress = GetI2CIoPortBaseAddress (); 1419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Disable the I2C Controller by setting IC_ENABLE.ENABLE to zero 1449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE; 1469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 1479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_ENABLE; 1489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 1499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Read the IC_ENABLE_STATUS.IC_EN Bit to check if Controller is disabled 1529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = 0xFF; 1549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE_STATUS; 1559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)) & I2C_REG_ENABLE_STATUS; 1569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney while (Data != 0) { 1579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Poll the IC_ENABLE_STATUS.IC_EN Bit to check if Controller is disabled, until timeout (TI2C_POLL*MAX_T_POLL_COUNT). 1599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney PollCount++; 1619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (PollCount >= MAX_T_POLL_COUNT) { 1629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 1639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 1649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MicroSecondDelay(TI2C_POLL); 1659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 1669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= I2C_REG_ENABLE_STATUS; 1679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 1689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Asset if controller does not enter Disabled state. 1719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ASSERT (PollCount < MAX_T_POLL_COUNT); 1739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Read IC_CLR_INTR register to automatically clear the combined interrupt, 1769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // all individual interrupts and the IC_TX_ABRT_SOURCE register. 1779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_CLR_INT; 1799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 1809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 1829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 1849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The EnableI2CController() function enables the I2C Controller. 1859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 1879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyVOID 1889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEnableI2CController ( 1899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney VOID 1909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 1919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 1929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CIoPortBaseAddress; 1939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 Addr; 1949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 Data; 1959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Get I2C Memory Mapped registers base address. 1989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CIoPortBaseAddress = GetI2CIoPortBaseAddress (); 2009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 2029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Enable the I2C Controller by setting IC_ENABLE.ENABLE to 1 2039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 2049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE; 2059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 2069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= B_I2C_REG_ENABLE; 2079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 2089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 2109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Clear overflow and abort error status bits before transactions. 2119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 2129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_OVER; 2139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 2149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_CLR_TX_OVER; 2159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 2169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_CLR_TX_ABRT; 2179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 2189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 2209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 2229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The WaitForStopDet() function waits until I2C STOP Condition occurs, 2239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney indicating transfer completion. 2249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_SUCCESS Stop detected. 2269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_TIMEOUT Timeout while waiting for stop condition. 2279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_ABORTED Tx abort signaled in HW status register. 2289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_DEVICE_ERROR Tx or Rx overflow detected. 2299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 2319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS 2329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyWaitForStopDet ( 2339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney VOID 2349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 2359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 2369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CIoPortBaseAddress; 2379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 Addr; 2389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 Data; 2399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 PollCount; 2409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EFI_STATUS Status; 2419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_SUCCESS; 2439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney PollCount = 0; 2459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 2479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Get I2C Memory Mapped registers base address. 2489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 2499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CIoPortBaseAddress = GetI2CIoPortBaseAddress (); 2509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 2529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Wait for STOP Detect. 2539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 2549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT; 2559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney do { 2579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 2589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if ((Data & I2C_REG_RAW_INTR_STAT_TX_ABRT) != 0) { 2599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_ABORTED; 2609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 2619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if ((Data & I2C_REG_RAW_INTR_STAT_TX_OVER) != 0) { 2639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_DEVICE_ERROR; 2649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 2659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if ((Data & I2C_REG_RAW_INTR_STAT_RX_OVER) != 0) { 2679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_DEVICE_ERROR; 2689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 2699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if ((Data & I2C_REG_RAW_INTR_STAT_STOP_DET) != 0) { 2719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_SUCCESS; 2729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 2739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MicroSecondDelay(TI2C_POLL); 2759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney PollCount++; 2769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (PollCount >= MAX_STOP_DET_POLL_COUNT) { 2779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_TIMEOUT; 2789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 2799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } while (TRUE); 2829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return Status; 2849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 2859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 2879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The InitializeInternal() function initialises internal I2C Controller 2899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney register values that are commonly required for I2C Write and Read transfers. 2909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param AddrMode I2C Addressing Mode: 7-bit or 10-bit address. 2929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_SUCCESS I2C Operation completed successfully. 2949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 2969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS 2979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyInitializeInternal ( 2989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN EFI_I2C_ADDR_MODE AddrMode 2999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 3009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 3019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CIoPortBaseAddress; 3029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN Addr; 3039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 Data; 3049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EFI_STATUS Status; 3059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_SUCCESS; 3079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Enable access to I2C Controller MMIO space. 3109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EnableI2CMmioSpace (); 3129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Disable I2C Controller initially 3159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DisableI2CController (); 3179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Get I2C Memory Mapped registers base address. 3209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CIoPortBaseAddress = GetI2CIoPortBaseAddress (); 3229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Clear START_DET 3259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_CLR_START_DET; 3279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 3289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_CLR_START_DET; 3299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 3309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Clear STOP_DET 3339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_CLR_STOP_DET; 3359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 3369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_CLR_STOP_DET; 3379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 3389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Set addressing mode to user defined (7 or 10 bit) and 3419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // speed mode to that defined by PCD (standard mode default). 3429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_CON; 3449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 3459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Set Addressing Mode 3469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (AddrMode == EfiI2CSevenBitAddrMode) { 3479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_CON_10BITADD_MASTER; 3489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } else { 3499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= B_I2C_REG_CON_10BITADD_MASTER; 3509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Set Speed Mode 3529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_CON_SPEED; 3539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (FeaturePcdGet (PcdI2CFastModeEnabled)) { 3549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= BIT2; 3559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } else { 3569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= BIT1; 3579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 3599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 3619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return Status; 3639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 3659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 3679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The WriteByte() function provides a standard way to execute a 3699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney standard single byte write to an IC2 device (without accessing 3709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney sub-addresses), as defined in the I2C Specification. 3719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param I2CAddress I2C Slave device address 3739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param Value The 8-bit value to write. 3749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_SUCCESS Transfer success. 3769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_UNSUPPORTED Unsupported input param. 3779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_TIMEOUT Timeout while waiting xfer. 3789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_ABORTED Controller aborted xfer. 3799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_DEVICE_ERROR Device error detected by controller. 3809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 3829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS 3839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI 3849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyWriteByte ( 3859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINTN I2CAddress, 3869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINT8 Value 3879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 3889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 3899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CIoPortBaseAddress; 3909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN Addr; 3919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 Data; 3929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EFI_STATUS Status; 3939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Get I2C Memory Mapped registers base address 3969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 3979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CIoPortBaseAddress = GetI2CIoPortBaseAddress (); 3989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Write to the IC_TAR register the address of the slave device to be addressed 4019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_TAR; 4039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 4049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_TAR; 4059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= I2CAddress; 4069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 4079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Enable the I2C Controller 4109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EnableI2CController (); 4129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Write the data and transfer direction to the IC_DATA_CMD register. 4159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Also specify that transfer should be terminated by STOP condition. 4169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD; 4189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 4199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= 0xFFFFFF00; 4209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= (UINT8)Value; 4219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_DATA_CMD_RW; 4229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= B_I2C_REG_DATA_CMD_STOP; 4239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 4249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Wait for transfer completion. 4279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = WaitForStopDet (); 4299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Ensure I2C Controller disabled. 4329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DisableI2CController(); 4349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return Status; 4369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 4379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 4399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The ReadByte() function provides a standard way to execute a 4419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney standard single byte read to an IC2 device (without accessing 4429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney sub-addresses), as defined in the I2C Specification. 4439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param I2CAddress I2C Slave device address 4459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param ReturnDataPtr Pointer to location to receive read byte. 4469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_SUCCESS Transfer success. 4489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_UNSUPPORTED Unsupported input param. 4499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_TIMEOUT Timeout while waiting xfer. 4509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_ABORTED Controller aborted xfer. 4519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_DEVICE_ERROR Device error detected by controller. 4529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 4549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS 4559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI 4569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyReadByte ( 4579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINTN I2CAddress, 4589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney OUT UINT8 *ReturnDataPtr 4599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 4609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 4619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CIoPortBaseAddress; 4629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN Addr; 4639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 Data; 4649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EFI_STATUS Status; 4659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Get I2C Memory Mapped registers base address. 4689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CIoPortBaseAddress = GetI2CIoPortBaseAddress (); 4709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Write to the IC_TAR register the address of the slave device to be addressed 4739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_TAR; 4759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 4769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_TAR; 4779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= I2CAddress; 4789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 4799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Enable the I2C Controller 4829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EnableI2CController (); 4849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Write transfer direction to the IC_DATA_CMD register and 4879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // specify that transfer should be terminated by STOP condition. 4889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD; 4909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 4919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= 0xFFFFFF00; 4929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= B_I2C_REG_DATA_CMD_RW; 4939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= B_I2C_REG_DATA_CMD_STOP; 4949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 4959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Wait for transfer completion 4989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 4999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = WaitForStopDet (); 5009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (!EFI_ERROR(Status)) { 5019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Clear RX underflow before reading IC_DATA_CMD. 5049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_UNDER; 5069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 5079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Obtain and return read data byte from RX buffer (IC_DATA_CMD[7:0]). 5109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD; 5129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 5139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= 0x000000FF; 5149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *ReturnDataPtr = (UINT8) Data; 5159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT; 5179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 5189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= I2C_REG_RAW_INTR_STAT_RX_UNDER; 5199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (Data != 0) { 5209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_DEVICE_ERROR; 5219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 5229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 5239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Ensure I2C Controller disabled. 5269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DisableI2CController (); 5289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return Status; 5309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 5319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 5339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The WriteMultipleByte() function provides a standard way to execute 5359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or 5369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney when writing block of data), as defined in the I2C Specification. 5379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param I2CAddress The I2C slave address of the device 5399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney with which to communicate. 5409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param WriteBuffer Contains the value of byte to be written to the 5429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2C slave device. 5439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param Length No. of bytes to be written. 5459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_SUCCESS Transfer success. 5479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_UNSUPPORTED Unsupported input param. 5489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_TIMEOUT Timeout while waiting xfer. 5499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_ABORTED Tx abort signaled in HW status register. 5509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_DEVICE_ERROR Tx overflow detected. 5519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 5539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS 5549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI 5559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyWriteMultipleByte ( 5569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINTN I2CAddress, 5579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINT8 *WriteBuffer, 5589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINTN Length 5599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 5609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 5619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CIoPortBaseAddress; 5629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN Index; 5639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN Addr; 5649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 Data; 5659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EFI_STATUS Status; 5669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (Length > I2C_FIFO_SIZE) { 5689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return EFI_UNSUPPORTED; // Routine does not handle xfers > fifo size. 5699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 5709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CIoPortBaseAddress = GetI2CIoPortBaseAddress (); 5729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Write to the IC_TAR register the address of the slave device to be addressed 5759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_TAR; 5779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 5789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_TAR; 5799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= I2CAddress; 5809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 5819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Enable the I2C Controller 5849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EnableI2CController (); 5869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Write the data and transfer direction to the IC_DATA_CMD register. 5899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Also specify that transfer should be terminated by STOP condition. 5909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 5919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD; 5929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (Index = 0; Index < Length; Index++) { 5939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 5949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= 0xFFFFFF00; 5959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= (UINT8)WriteBuffer[Index]; 5969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_DATA_CMD_RW; 5979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (Index == (Length-1)) { 5989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= B_I2C_REG_DATA_CMD_STOP; 5999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 6009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 6019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 6029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Wait for transfer completion 6059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = WaitForStopDet (); 6079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Ensure I2C Controller disabled. 6109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DisableI2CController (); 6129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return Status; 6139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 6149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 6169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The ReadMultipleByte() function provides a standard way to execute 6189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or 6199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney when reading block of data), as defined in the I2C Specification (I2C combined 6209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney write/read protocol). 6219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param I2CAddress The I2C slave address of the device 6239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney with which to communicate. 6249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param Buffer Contains the value of byte data written or read from the 6269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2C slave device. 6279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param WriteLength No. of bytes to be written. In this case data 6299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney written typically contains sub-address or sub-addresses 6309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney in Hi-Lo format, that need to be read (I2C combined 6319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney write/read protocol). 6329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param ReadLength No. of bytes to be read from I2C slave device. 6349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_SUCCESS Transfer success. 6369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_UNSUPPORTED Unsupported input param. 6379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_TIMEOUT Timeout while waiting xfer. 6389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_ABORTED Tx abort signaled in HW status register. 6399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_DEVICE_ERROR Rx underflow or Rx/Tx overflow detected. 6409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 6429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS 6439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI 6449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyReadMultipleByte ( 6459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINTN I2CAddress, 6469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN OUT UINT8 *Buffer, 6479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINTN WriteLength, 6489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINTN ReadLength 6499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 6509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 6519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CIoPortBaseAddress; 6529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN Index; 6539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN Addr; 6549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 Data; 6559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT8 PollCount; 6569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EFI_STATUS Status; 6579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (WriteLength > I2C_FIFO_SIZE || ReadLength > I2C_FIFO_SIZE) { 6599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return EFI_UNSUPPORTED; // Routine does not handle xfers > fifo size. 6609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 6619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CIoPortBaseAddress = GetI2CIoPortBaseAddress (); 6639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Write to the IC_TAR register the address of the slave device to be addressed 6669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_TAR; 6689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 6699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_TAR; 6709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= I2CAddress; 6719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 6729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Enable the I2C Controller 6759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EnableI2CController (); 6779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Write the data (sub-addresses) to the IC_DATA_CMD register. 6809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD; 6829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (Index = 0; Index < WriteLength; Index++) { 6839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 6849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= 0xFFFFFF00; 6859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= (UINT8)Buffer[Index]; 6869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= ~B_I2C_REG_DATA_CMD_RW; 6879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 6889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 6899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Issue Read Transfers for each byte (Restart issued when write/read bit changed). 6929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 6939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (Index = 0; Index < ReadLength; Index++) { 6949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 6959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= B_I2C_REG_DATA_CMD_RW; 6969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Issue a STOP for last read transfer. 6979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (Index == (ReadLength-1)) { 6989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data |= B_I2C_REG_DATA_CMD_STOP; 6999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 7009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *((volatile UINT32 *) (UINTN)(Addr)) = Data; 7019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 7029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Wait for STOP condition. 7059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = WaitForStopDet (); 7079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (!EFI_ERROR(Status)) { 7089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Poll Receive FIFO Buffer Level register until valid (upto MAX_T_POLL_COUNT times). 7119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = 0; 7139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney PollCount = 0; 7149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_RXFLR; 7159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 7169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney while ((Data != ReadLength) && (PollCount < MAX_T_POLL_COUNT)) { 7179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MicroSecondDelay(TI2C_POLL); 7189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney PollCount++; 7199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 7209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 7219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT; 7239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 7249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // If no timeout or device error then read rx data. 7279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (PollCount == MAX_T_POLL_COUNT) { 7299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_TIMEOUT; 7309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } else if ((Data & I2C_REG_RAW_INTR_STAT_RX_OVER) != 0) { 7319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_DEVICE_ERROR; 7329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } else { 7339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Clear RX underflow before reading IC_DATA_CMD. 7369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_UNDER; 7389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 7399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Read data. 7429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD; 7449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (Index = 0; Index < ReadLength; Index++) { 7459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 7469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= 0x000000FF; 7479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *(Buffer+Index) = (UINT8)Data; 7489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 7499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT; 7509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data = *((volatile UINT32 *) (UINTN)(Addr)); 7519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Data &= I2C_REG_RAW_INTR_STAT_RX_UNDER; 7529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (Data != 0) { 7539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_DEVICE_ERROR; 7549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } else { 7559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_SUCCESS; 7569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 7579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 7589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 7599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Ensure I2C Controller disabled. 7629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 7639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DisableI2CController (); 7649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return Status; 7669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 7679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 7699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The I2cWriteByte() function is a wrapper function for the WriteByte function. 7719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Provides a standard way to execute a standard single byte write to an IC2 device 7729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney (without accessing sub-addresses), as defined in the I2C Specification. 7739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param SlaveAddress The I2C slave address of the device 7759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney with which to communicate. 7769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param AddrMode I2C Addressing Mode: 7-bit or 10-bit address. 7789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param Buffer Contains the value of byte data to execute to the 7809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2C slave device. 7819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_SUCCESS Transfer success. 7849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_INVALID_PARAMETER This or Buffer pointers are invalid. 7859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_UNSUPPORTED Unsupported input param. 7869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_TIMEOUT Timeout while waiting xfer. 7879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_ABORTED Controller aborted xfer. 7889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_DEVICE_ERROR Device error detected by controller. 7899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 7919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS 7929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI 7939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyI2cWriteByte ( 7949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN EFI_I2C_DEVICE_ADDRESS SlaveAddress, 7959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN EFI_I2C_ADDR_MODE AddrMode, 7969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN OUT VOID *Buffer 7979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 7989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 7999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EFI_STATUS Status; 8009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CAddress; 8019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT16 SaveCmd; 8029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 SaveBar0; 8039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (Buffer == NULL) { 8059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return EFI_INVALID_PARAMETER; 8069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 8079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney SaveCmd = 0; 8089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney SaveBar0 = 0; 8099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2cCommonServiceEntry (&SaveCmd, &SaveBar0); 8119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_SUCCESS; 8139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CAddress = SlaveAddress.I2CDeviceAddress; 8159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = InitializeInternal (AddrMode); 8169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (!EFI_ERROR(Status)) { 8179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = WriteByte (I2CAddress, *(UINT8 *) Buffer); 8189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 8199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2cCommonServiceExit (SaveCmd, SaveBar0); 8219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return Status; 8229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 8239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 8259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The I2cReadByte() function is a wrapper function for the ReadByte function. 8279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Provides a standard way to execute a standard single byte read to an I2C device 8289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney (without accessing sub-addresses), as defined in the I2C Specification. 8299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param SlaveAddress The I2C slave address of the device 8319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney with which to communicate. 8329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param AddrMode I2C Addressing Mode: 7-bit or 10-bit address. 8349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param Buffer Contains the value of byte data read from the 8369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2C slave device. 8379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_SUCCESS Transfer success. 8409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_INVALID_PARAMETER This or Buffer pointers are invalid. 8419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_TIMEOUT Timeout while waiting xfer. 8429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_ABORTED Controller aborted xfer. 8439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_DEVICE_ERROR Device error detected by controller. 8449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 8479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS 8489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI 8499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyI2cReadByte ( 8509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN EFI_I2C_DEVICE_ADDRESS SlaveAddress, 8519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN EFI_I2C_ADDR_MODE AddrMode, 8529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN OUT VOID *Buffer 8539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 8549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 8559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EFI_STATUS Status; 8569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CAddress; 8579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT16 SaveCmd; 8589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 SaveBar0; 8599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (Buffer == NULL) { 8619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return EFI_INVALID_PARAMETER; 8629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 8639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney SaveCmd = 0; 8649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney SaveBar0 =0; 8659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2cCommonServiceEntry (&SaveCmd, &SaveBar0); 8679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_SUCCESS; 8699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CAddress = SlaveAddress.I2CDeviceAddress; 8719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = InitializeInternal (AddrMode); 8739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (!EFI_ERROR(Status)) { 8749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = ReadByte (I2CAddress, (UINT8 *) Buffer); 8759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 8769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2cCommonServiceExit (SaveCmd, SaveBar0); 8779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return Status; 8789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 8799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 8819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The I2cWriteMultipleByte() function is a wrapper function for the 8839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney WriteMultipleByte() function. Provides a standard way to execute multiple 8849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney byte writes to an I2C device (e.g. when accessing sub-addresses or writing 8859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney block of data), as defined in the I2C Specification. 8869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param SlaveAddress The I2C slave address of the device 8889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney with which to communicate. 8899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param AddrMode I2C Addressing Mode: 7-bit or 10-bit address. 8919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param Length No. of bytes to be written. 8939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param Buffer Contains the value of byte to be written to the 8959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2C slave device. 8969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_SUCCESS Transfer success. 8989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_INVALID_PARAMETER This, Length or Buffer pointers are invalid. 8999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_UNSUPPORTED Unsupported input param. 9009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_TIMEOUT Timeout while waiting xfer. 9019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_ABORTED Controller aborted xfer. 9029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_DEVICE_ERROR Device error detected by controller. 9039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 9059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS 9069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI 9079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyI2cWriteMultipleByte ( 9089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN EFI_I2C_DEVICE_ADDRESS SlaveAddress, 9099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN EFI_I2C_ADDR_MODE AddrMode, 9109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINTN *Length, 9119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN OUT VOID *Buffer 9129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 9139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 9149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EFI_STATUS Status; 9159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CAddress; 9169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT16 SaveCmd; 9179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 SaveBar0; 9189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (Buffer == NULL || Length == NULL) { 9209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return EFI_INVALID_PARAMETER; 9219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 9229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney SaveCmd = 0; 9239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney SaveBar0 =0; 9249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2cCommonServiceEntry (&SaveCmd, &SaveBar0); 9269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_SUCCESS; 9279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CAddress = SlaveAddress.I2CDeviceAddress; 9299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = InitializeInternal (AddrMode); 9319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (!EFI_ERROR(Status)) { 9329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = WriteMultipleByte (I2CAddress, Buffer, (*Length)); 9339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 9349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2cCommonServiceExit (SaveCmd, SaveBar0); 9369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return Status; 9379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 9389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/** 9409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney The I2cReadMultipleByte() function is a wrapper function for the ReadMultipleByte() function. 9429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Provides a standard way to execute multiple byte writes to an I2C device 9439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney (e.g. when accessing sub-addresses or when reading block of data), as defined 9449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney in the I2C Specification (I2C combined write/read protocol). 9459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param SlaveAddress The I2C slave address of the device 9479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney with which to communicate. 9489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param AddrMode I2C Addressing Mode: 7-bit or 10-bit address. 9509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param WriteLength No. of bytes to be written. In this case data 9529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney written typically contains sub-address or sub-addresses 9539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney in Hi-Lo format, that need to be read (I2C combined 9549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney write/read protocol). 9559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param ReadLength No. of bytes to be read from I2C slave device. 9579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @param Buffer Contains the value of byte data read from the 9599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2C slave device. 9609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_SUCCESS Transfer success. 9629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_INVALID_PARAMETER This, WriteLength, ReadLength or Buffer 9639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pointers are invalid. 9649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_UNSUPPORTED Unsupported input param. 9659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_TIMEOUT Timeout while waiting xfer. 9669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_ABORTED Controller aborted xfer. 9679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney @retval EFI_DEVICE_ERROR Device error detected by controller. 9689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney**/ 9709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFI_STATUS 9719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyEFIAPI 9729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael KinneyI2cReadMultipleByte ( 9739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN EFI_I2C_DEVICE_ADDRESS SlaveAddress, 9749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN EFI_I2C_ADDR_MODE AddrMode, 9759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINTN *WriteLength, 9769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN UINTN *ReadLength, 9779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney IN OUT VOID *Buffer 9789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ) 9799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 9809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney EFI_STATUS Status; 9819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINTN I2CAddress; 9829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT16 SaveCmd; 9839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney UINT32 SaveBar0; 9849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (Buffer == NULL || WriteLength == NULL || ReadLength == NULL) { 9869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return EFI_INVALID_PARAMETER; 9879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 9889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney SaveCmd = 0; 9899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney SaveBar0 =0; 9909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2cCommonServiceEntry (&SaveCmd, &SaveBar0); 9929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = EFI_SUCCESS; 9949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2CAddress = SlaveAddress.I2CDeviceAddress; 9969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = InitializeInternal (AddrMode); 9979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (!EFI_ERROR(Status)) { 9989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Status = ReadMultipleByte (I2CAddress, Buffer, (*WriteLength), (*ReadLength)); 9999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 10009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney I2cCommonServiceExit (SaveCmd, SaveBar0); 10019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return Status; 10029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 10039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 10049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1005