3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Omap3530/Omap3530.h>
12 #include <Library/DebugLib.h>
13 #include <Library/IoLib.h>
14 #include <Library/UefiBootServicesTableLib.h>
16 #include <Protocol/SmbusHc.h>
18 #define MAX_RETRY 1000
31 while (++Retry
< MAX_RETRY
&& (MmioRead16(I2C_STAT
) & BB
) == 0x1);
33 if (Retry
== MAX_RETRY
) {
48 while(Retry
< MAX_RETRY
) {
49 if (MmioRead16(I2C_STAT
) & StatusBit
) {
50 //Clear particular status bit from Status register.
51 MmioOr16(I2C_STAT
, StatusBit
);
57 if (Retry
== MAX_RETRY
) {
70 //Program prescaler to obtain 12-MHz clock
71 MmioWrite16(I2C_PSC
, 0x0000);
73 //Program SCLL and SCLH
74 //NOTE: Following values are the register dump after U-Boot code executed.
75 //We need to figure out how its calculated based on the I2C functional clock and I2C_PSC.
76 MmioWrite16(I2C_SCLL
, 0x0035);
77 MmioWrite16(I2C_SCLH
, 0x0035);
79 //Take the I2C controller out of reset.
80 MmioOr16(I2C_CON
, I2C_EN
);
82 //Initialize the I2C controller.
84 //Set I2C controller in Master mode.
85 MmioOr16(I2C_CON
, MST
);
87 //Enable interrupts for receive/transmit mode.
88 MmioOr16(I2C_IE
, (XRDY_IE
| RRDY_IE
| ARDY_IE
| NACK_IE
));
101 //I2C bus status checking
102 Status
= WaitForBusBusy();
103 if (EFI_ERROR(Status
)) {
107 //Poll till Receive ready bit is set.
108 Status
= PollForStatus(RRDY
);
109 if (EFI_ERROR(Status
)) {
113 *Data
= MmioRead8(I2C_DATA
);
126 //I2C bus status checking
127 Status
= WaitForBusBusy();
128 if (EFI_ERROR(Status
)) {
133 //Poll till Transmit ready bit is set
134 Status
= PollForStatus(XRDY
);
135 if (EFI_ERROR(Status
)) {
139 MmioWrite8(I2C_DATA
, Data
);
141 //Wait and check if the NACK is not set.
143 if (MmioRead16(I2C_STAT
) & NACK
) {
144 return EFI_DEVICE_ERROR
;
158 EFI_STATUS Status
= EFI_SUCCESS
;
160 //Transfer configuration for receiving data.
161 MmioWrite16(I2C_CNT
, Length
);
162 //Need stop bit before sending data.
163 MmioWrite16(I2C_CON
, (I2C_EN
| MST
| STP
| STT
));
165 while (Index
< Length
) {
167 Status
= I2CReadOneByte(&Buffer
[Index
++]);
168 if (EFI_ERROR(Status
)) {
173 //Transfer completion
174 Status
= PollForStatus(ARDY
);
175 if (EFI_ERROR(Status
)) {
190 EFI_STATUS Status
= EFI_SUCCESS
;
192 //Transfer configuration for transmitting data
193 MmioWrite16(I2C_CNT
, Length
);
194 MmioWrite16(I2C_CON
, (I2C_EN
| TRX
| MST
| STT
| STP
));
196 while (Index
< Length
) {
198 Status
= I2CWriteOneByte(Buffer
[Index
++]);
199 if (EFI_ERROR(Status
)) {
204 //Transfer completion
205 Status
= PollForStatus(ARDY
);
206 if (EFI_ERROR(Status
)) {
219 IN CONST EFI_SMBUS_HC_PROTOCOL
*This
,
220 IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
,
221 IN CONST EFI_SMBUS_DEVICE_COMMAND Command
,
222 IN CONST EFI_SMBUS_OPERATION Operation
,
223 IN CONST BOOLEAN PecCheck
,
224 IN OUT UINTN
*Length
,
228 UINT8
*ByteBuffer
= Buffer
;
229 EFI_STATUS Status
= EFI_SUCCESS
;
230 UINT8 SlaveAddr
= (UINT8
)(SlaveAddress
.SmbusDeviceAddress
);
233 return EFI_UNSUPPORTED
;
236 if ((Operation
!= EfiSmbusWriteBlock
) && (Operation
!= EfiSmbusReadBlock
)) {
237 return EFI_UNSUPPORTED
;
240 //Set the Slave address.
241 MmioWrite16(I2C_SA
, SlaveAddr
);
243 if (Operation
== EfiSmbusReadBlock
) {
244 Status
= SmbusBlockRead(ByteBuffer
, *Length
);
245 } else if (Operation
== EfiSmbusWriteBlock
) {
246 Status
= SmbusBlockWrite(ByteBuffer
, *Length
);
255 IN CONST EFI_SMBUS_HC_PROTOCOL
*This
,
257 IN EFI_SMBUS_UDID
*SmbusUdid OPTIONAL
,
258 IN OUT EFI_SMBUS_DEVICE_ADDRESS
*SlaveAddress OPTIONAL
261 return EFI_UNSUPPORTED
;
268 IN CONST EFI_SMBUS_HC_PROTOCOL
*This
,
269 IN OUT UINTN
*Length
,
270 IN OUT EFI_SMBUS_DEVICE_MAP
**SmbusDeviceMap
273 return EFI_UNSUPPORTED
;
280 IN CONST EFI_SMBUS_HC_PROTOCOL
*This
,
281 IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
,
283 IN CONST EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
286 return EFI_UNSUPPORTED
;
289 EFI_SMBUS_HC_PROTOCOL SmbusProtocol
=
299 IN EFI_HANDLE ImageHandle
,
300 IN EFI_SYSTEM_TABLE
*SystemTable
303 EFI_HANDLE Handle
= NULL
;
306 //Configure I2C controller.
307 Status
= ConfigureI2c();
308 if (EFI_ERROR(Status
)) {
309 DEBUG ((EFI_D_ERROR
, "InitializeI2c fails.\n"));
313 // Install the SMBUS interface
314 Status
= gBS
->InstallMultipleProtocolInterfaces(&Handle
, &gEfiSmbusHcProtocolGuid
, &SmbusProtocol
, NULL
);
315 ASSERT_EFI_ERROR(Status
);