summaryrefslogtreecommitdiffstats
path: root/OptionRomPkg
diff options
context:
space:
mode:
Diffstat (limited to 'OptionRomPkg')
-rw-r--r--OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c433
-rw-r--r--OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h68
2 files changed, 501 insertions, 0 deletions
diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
new file mode 100644
index 0000000000..377a597646
--- /dev/null
+++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.c
@@ -0,0 +1,433 @@
+/** @file
+ I2C Bus implementation upon CirrusLogic.
+
+ Copyright (c) 2008 - 2009, Intel Corporation
+ All rights reserved. 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 "CirrusLogic5430.h"
+#include "CirrusLogic5430I2c.h"
+
+#define SEQ_ADDRESS_REGISTER 0x3c4
+#define SEQ_DATA_REGISTER 0x3c5
+
+#define I2C_CONTROL 0x08
+#define I2CDAT_IN 7
+#define I2CCLK_IN 2
+#define I2CDAT_OUT 1
+#define I2CCLK_OUT 0
+
+#define I2C_BUS_SPEED 100 //100kbps
+
+/**
+ PCI I/O byte write function.
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+ @param Address The bit map of I2C Data or I2C Clock pins.
+ @param Data The date to write.
+
+**/
+VOID
+I2cOutb (
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINTN Address,
+ UINT8 Data
+ )
+{
+ PciIo->Io.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Address,
+ 1,
+ &Data
+ );
+}
+/**
+ PCI I/O byte read function.
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+ @param Address The bit map of I2C Data or I2C Clock pins.
+
+ return byte value read from PCI I/O space.
+
+**/
+UINT8
+I2cInb (
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINTN Address
+ )
+{
+ UINT8 Data;
+
+ PciIo->Io.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Address,
+ 1,
+ &Data
+ );
+ return Data;
+}
+
+/**
+ Read status of I2C Data and I2C Clock Pins.
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+ @param Blt The bit map of I2C Data or I2C Clock pins.
+
+ @retval 0 Low on I2C Data or I2C Clock Pin.
+ @retval 1 High on I2C Data or I2C Clock Pin.
+
+**/
+UINT8
+I2cPinRead (
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINT8 Bit
+ )
+{
+ I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);
+ return (UINT8) ((I2cInb (PciIo, SEQ_DATA_REGISTER) >> Bit ) & 0xfe);
+}
+
+
+/**
+ Set/Clear I2C Data and I2C Clock Pins.
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+ @param Blt The bit map to controller I2C Data or I2C Clock pins.
+ @param Value 1 or 0 stands for Set or Clear I2C Data and I2C Clock Pins.
+
+**/
+VOID
+I2cPinWrite (
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINT8 Bit,
+ UINT8 Value
+ )
+{
+ UINT8 Byte;
+ I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);
+ Byte = (UINT8) (I2cInb (PciIo, SEQ_DATA_REGISTER) & (UINT8) ~(1 << Bit)) ;
+ Byte = (UINT8) (Byte | ((Value & 0x01) << Bit));
+ I2cOutb (PciIo, SEQ_DATA_REGISTER, (UINT8) (Byte | 0x40));
+ return;
+}
+
+/**
+ Read/write delay acoording to I2C Bus Speed.
+
+**/
+VOID
+I2cDelay (
+ VOID
+ )
+{
+ MicroSecondDelay (1000 / I2C_BUS_SPEED);
+}
+
+/**
+ Write a 8-bit data onto I2C Data Pin.
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+ @param Data The byte data to write.
+
+**/
+VOID
+I2cSendByte (
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINT8 Data
+ )
+{
+ UINTN Index;
+ //
+ // Send byte data onto I2C Bus
+ //
+ for (Index = 0; Index < 8; Index --) {
+ I2cPinWrite (PciIo, I2CDAT_OUT, (UINT8) (Data >> (7 - Index)));
+ I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+ I2cDelay ();
+ I2cPinWrite (PciIo, I2CCLK_OUT, 0);
+ }
+}
+
+/**
+ Read a 8-bit data from I2C Data Pin.
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+
+ Return the byte data read from I2C Data Pin.
+**/
+UINT8
+I2cReceiveByte (
+ EFI_PCI_IO_PROTOCOL *PciIo
+ )
+{
+ UINT8 Data;
+ UINTN Index;
+
+ Data = 0;
+ //
+ // Read byte data from I2C Bus
+ //
+ for (Index = 0; Index < 8; Index --) {
+ I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+ I2cDelay ();
+ Data = (UINT8) (Data << 1);
+ Data = (UINT8) (Data | I2cPinRead (PciIo, I2CDAT_IN));
+ I2cPinWrite (PciIo, I2CCLK_OUT, 0);
+ }
+
+ return Data;
+}
+
+/**
+ Receive an ACK signal from I2C Bus.
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+
+**/
+BOOLEAN
+I2cWaitAck (
+ EFI_PCI_IO_PROTOCOL *PciIo
+ )
+{
+ //
+ // Wait for ACK signal
+ //
+ I2cPinWrite (PciIo, I2CDAT_OUT, 1);
+ I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+ I2cDelay ();
+ if (I2cPinRead (PciIo, I2CDAT_IN) == 0) {
+ I2cPinWrite (PciIo, I2CDAT_OUT, 1);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Send an ACK signal onto I2C Bus.
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+
+**/
+VOID
+I2cSendAck (
+ EFI_PCI_IO_PROTOCOL *PciIo
+ )
+{
+ I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+ I2cPinWrite (PciIo, I2CDAT_OUT, 1);
+ I2cPinWrite (PciIo, I2CDAT_OUT, 0);
+ I2cPinWrite (PciIo, I2CCLK_OUT, 0);
+}
+
+/**
+ Start a I2C transfer on I2C Bus.
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+
+**/
+VOID
+I2cStart (
+ EFI_PCI_IO_PROTOCOL *PciIo
+ )
+{
+ //
+ // Init CLK and DAT pins
+ //
+ I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+ I2cPinWrite (PciIo, I2CDAT_OUT, 1);
+ //
+ // Start a I2C transfer, set SDA low from high, when SCL is high
+ //
+ I2cPinWrite (PciIo, I2CDAT_OUT, 0);
+ I2cPinWrite (PciIo, I2CCLK_OUT, 0);
+}
+
+/**
+ Stop a I2C transfer on I2C Bus.
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+
+**/
+VOID
+I2cStop (
+ EFI_PCI_IO_PROTOCOL *PciIo
+ )
+{
+ //
+ // Stop a I2C transfer, set SDA high from low, when SCL is high
+ //
+ I2cPinWrite (PciIo, I2CDAT_OUT, 0);
+ I2cPinWrite (PciIo, I2CCLK_OUT, 1);
+ I2cPinWrite (PciIo, I2CDAT_OUT, 1);
+}
+
+/**
+ Read one byte data on I2C Bus.
+
+ Read one byte data from the slave device connectet to I2C Bus.
+ If Data is NULL, then ASSERT().
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+ @param DeviceAddress Slave device's address.
+ @param RegisterAddress The register address on slave device.
+ @param Data The pointer to returned data if EFI_SUCCESS returned.
+
+ @retval EFI_DEVICE_ERROR
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+I2cReadByte (
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINT8 DeviceAddress,
+ UINT8 RegisterAddress,
+ UINT8 *Data
+ )
+{
+ ASSERT (Data != NULL);
+
+ //
+ // Start I2C transfer
+ //
+ I2cStart (PciIo);
+
+ //
+ // Send slave address with enabling write flag
+ //
+ I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));
+
+ //
+ // Wait for ACK signal
+ //
+ if (I2cWaitAck (PciIo) == FALSE) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Send register address
+ //
+ I2cSendByte (PciIo, RegisterAddress);
+
+ //
+ // Wait for ACK signal
+ //
+ if (I2cWaitAck (PciIo) == FALSE) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Send slave address with enabling read flag
+ //
+ I2cSendByte (PciIo, (UINT8) (DeviceAddress | 0x01));
+
+ //
+ // Wait for ACK signal
+ //
+ if (I2cWaitAck (PciIo) == FALSE) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Read byte data from I2C Bus
+ //
+ *Data = I2cReceiveByte (PciIo);
+
+ //
+ // Send ACK signal onto I2C Bus
+ //
+ I2cSendAck (PciIo);
+
+ //
+ // Stop a I2C transfer
+ //
+ I2cStop (PciIo);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write one byte data onto I2C Bus.
+
+ Write one byte data to the slave device connectet to I2C Bus.
+ If Data is NULL, then ASSERT().
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+ @param DeviceAddress Slave device's address.
+ @param RegisterAddress The register address on slave device.
+ @param Data The pointer to write data.
+
+ @retval EFI_DEVICE_ERROR
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+I2cWriteByte (
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINT8 DeviceAddress,
+ UINT8 RegisterAddress,
+ UINT8 *Data
+ )
+{
+ ASSERT (Data != NULL);
+
+ I2cStart (PciIo);
+ //
+ // Send slave address with enabling write flag
+ //
+ I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));
+
+ //
+ // Wait for ACK signal
+ //
+ if (I2cWaitAck (PciIo) == FALSE) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Send register address
+ //
+ I2cSendByte (PciIo, RegisterAddress);
+
+ //
+ // Wait for ACK signal
+ //
+ if (I2cWaitAck (PciIo) == FALSE) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Send byte data onto I2C Bus
+ //
+ I2cSendByte (PciIo, *Data);
+
+ //
+ // Wait for ACK signal
+ //
+ if (I2cWaitAck (PciIo) == FALSE) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Stop a I2C transfer
+ //
+ I2cStop (PciIo);
+
+ return EFI_SUCCESS;
+}
+
+
+
diff --git a/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
new file mode 100644
index 0000000000..b39f47f719
--- /dev/null
+++ b/OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430I2c.h
@@ -0,0 +1,68 @@
+/** @file
+ I2c Bus byte read/write functions.
+
+ Copyright (c) 2008 - 2009, Intel Corporation
+ All rights reserved. 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 _CIRRUS_LOGIC_I2C_H_
+#define _CIRRUS_LOGIC_I2C_H_
+
+#include <Protocol/PciIo.h>
+
+/**
+ Read one byte data on I2C Bus.
+
+ Read one byte data from the slave device connectet to I2C Bus.
+ If Data is NULL, then ASSERT().
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+ @param DeviceAddress Slave device's address.
+ @param RegisterAddress The register address on slave device.
+ @param Data The pointer to returned data if EFI_SUCCESS returned.
+
+ @retval EFI_DEVICE_ERROR
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+I2cReadByte (
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINT8 DeviceAddress,
+ UINT8 RegisterAddress,
+ UINT8 *Data
+ );
+
+/**
+ Write one byte data onto I2C Bus.
+
+ Write one byte data to the slave device connectet to I2C Bus.
+ If Data is NULL, then ASSERT().
+
+ @param PciIo The pointer to PCI_IO_PROTOCOL.
+ @param DeviceAddress Slave device's address.
+ @param RegisterAddress The register address on slave device.
+ @param Data The pointer to write data.
+
+ @retval EFI_DEVICE_ERROR
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EFIAPI
+I2cWriteByte (
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINT8 DeviceAddress,
+ UINT8 RegisterAddress,
+ UINT8 *Data
+ );
+
+#endif