3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Omap3530/Omap3530.h>
18 #include <Library/DebugLib.h>
19 #include <Library/IoLib.h>
20 #include <Library/UefiBootServicesTableLib.h>
22 #include <Protocol/SmbusHc.h>
24 #define MAX_RETRY 1000
37 while (++Retry
< MAX_RETRY
&& (MmioRead16(I2C_STAT
) & BB
) == 0x1);
39 if (Retry
== MAX_RETRY
) {
54 while(Retry
< MAX_RETRY
) {
55 if (MmioRead16(I2C_STAT
) & StatusBit
) {
56 //Clear particular status bit from Status register.
57 MmioOr16(I2C_STAT
, StatusBit
);
63 if (Retry
== MAX_RETRY
) {
76 //Program prescaler to obtain 12-MHz clock
77 MmioWrite16(I2C_PSC
, 0x0000);
79 //Program SCLL and SCLH
80 //NOTE: Following values are the register dump after U-Boot code executed.
81 //We need to figure out how its calculated based on the I2C functional clock and I2C_PSC.
82 MmioWrite16(I2C_SCLL
, 0x0035);
83 MmioWrite16(I2C_SCLH
, 0x0035);
85 //Take the I2C controller out of reset.
86 MmioOr16(I2C_CON
, I2C_EN
);
88 //Initialize the I2C controller.
90 //Set I2C controller in Master mode.
91 MmioOr16(I2C_CON
, MST
);
93 //Enable interrupts for receive/transmit mode.
94 MmioOr16(I2C_IE
, (XRDY_IE
| RRDY_IE
| ARDY_IE
| NACK_IE
));
107 //I2C bus status checking
108 Status
= WaitForBusBusy();
109 if (EFI_ERROR(Status
)) {
113 //Poll till Receive ready bit is set.
114 Status
= PollForStatus(RRDY
);
115 if (EFI_ERROR(Status
)) {
119 *Data
= MmioRead8(I2C_DATA
);
132 //I2C bus status checking
133 Status
= WaitForBusBusy();
134 if (EFI_ERROR(Status
)) {
139 //Poll till Transmit ready bit is set
140 Status
= PollForStatus(XRDY
);
141 if (EFI_ERROR(Status
)) {
145 MmioWrite8(I2C_DATA
, Data
);
147 //Wait and check if the NACK is not set.
149 if (MmioRead16(I2C_STAT
) & NACK
) {
150 return EFI_DEVICE_ERROR
;
164 EFI_STATUS Status
= EFI_SUCCESS
;
166 //Transfer configuration for receiving data.
167 MmioWrite16(I2C_CNT
, Length
);
168 //Need stop bit before sending data.
169 MmioWrite16(I2C_CON
, (I2C_EN
| MST
| STP
| STT
));
171 while (Index
< Length
) {
173 Status
= I2CReadOneByte(&Buffer
[Index
++]);
174 if (EFI_ERROR(Status
)) {
179 //Transfer completion
180 Status
= PollForStatus(ARDY
);
181 if (EFI_ERROR(Status
)) {
196 EFI_STATUS Status
= EFI_SUCCESS
;
198 //Transfer configuration for transmitting data
199 MmioWrite16(I2C_CNT
, Length
);
200 MmioWrite16(I2C_CON
, (I2C_EN
| TRX
| MST
| STT
| STP
));
202 while (Index
< Length
) {
204 Status
= I2CWriteOneByte(Buffer
[Index
++]);
205 if (EFI_ERROR(Status
)) {
210 //Transfer completion
211 Status
= PollForStatus(ARDY
);
212 if (EFI_ERROR(Status
)) {
225 IN CONST EFI_SMBUS_HC_PROTOCOL
*This
,
226 IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
,
227 IN CONST EFI_SMBUS_DEVICE_COMMAND Command
,
228 IN CONST EFI_SMBUS_OPERATION Operation
,
229 IN CONST BOOLEAN PecCheck
,
230 IN OUT UINTN
*Length
,
234 UINT8
*ByteBuffer
= Buffer
;
235 EFI_STATUS Status
= EFI_SUCCESS
;
236 UINT8 SlaveAddr
= (UINT8
)(SlaveAddress
.SmbusDeviceAddress
);
239 return EFI_UNSUPPORTED
;
242 if ((Operation
!= EfiSmbusWriteBlock
) && (Operation
!= EfiSmbusReadBlock
)) {
243 return EFI_UNSUPPORTED
;
246 //Set the Slave address.
247 MmioWrite16(I2C_SA
, SlaveAddr
);
249 if (Operation
== EfiSmbusReadBlock
) {
250 Status
= SmbusBlockRead(ByteBuffer
, *Length
);
251 } else if (Operation
== EfiSmbusWriteBlock
) {
252 Status
= SmbusBlockWrite(ByteBuffer
, *Length
);
261 IN CONST EFI_SMBUS_HC_PROTOCOL
*This
,
263 IN EFI_SMBUS_UDID
*SmbusUdid OPTIONAL
,
264 IN OUT EFI_SMBUS_DEVICE_ADDRESS
*SlaveAddress OPTIONAL
267 return EFI_UNSUPPORTED
;
274 IN CONST EFI_SMBUS_HC_PROTOCOL
*This
,
275 IN OUT UINTN
*Length
,
276 IN OUT EFI_SMBUS_DEVICE_MAP
**SmbusDeviceMap
279 return EFI_UNSUPPORTED
;
286 IN CONST EFI_SMBUS_HC_PROTOCOL
*This
,
287 IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
,
289 IN CONST EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
292 return EFI_UNSUPPORTED
;
295 EFI_SMBUS_HC_PROTOCOL SmbusProtocol
=
305 IN EFI_HANDLE ImageHandle
,
306 IN EFI_SYSTEM_TABLE
*SystemTable
309 EFI_HANDLE Handle
= NULL
;
312 //Configure I2C controller.
313 Status
= ConfigureI2c();
314 if (EFI_ERROR(Status
)) {
315 DEBUG ((EFI_D_ERROR
, "InitializeI2c fails.\n"));
319 // Install the SMBUS interface
320 Status
= gBS
->InstallMultipleProtocolInterfaces(&Handle
, &gEfiSmbusHcProtocolGuid
, &SmbusProtocol
, NULL
);
321 ASSERT_EFI_ERROR(Status
);