alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/I2cMaster/Dxe/I2cMasterDxe.h

406 lines
13 KiB
C

/** @file
For I2C Master Driver
;******************************************************************************
;* Copyright (c) 2012 - 2014, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#ifndef _I2C_MASTER_DXE_H_
#define _I2C_MASTER_DXE_H_
#include <IndustryStandard/Pci.h>
#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PcdLib.h>
#include <Protocol/I2cEnumerate.h>
#include <I2cBusInstance.h>
#include <Protocol/I2cPlatformSpecific.h>
#include <I2cHidDeviceInfo.h>
#include "I2cRegs.h"
#include <PlatformDefinitions.h>
//
// Definitions
//
#define I2C_PRIVATE_DATA_SIGNATURE SIGNATURE_32('p','i','2','c')
#define MICROSECOND 10
#define MILLISECOND (1000 * MICROSECOND)
#define DEFAULT_CACHE_SIZE 0x100
#define I2C_HC_TYPE_PCI 0
#define I2C_HC_TYPE_MMIO 1
// //
// // CPU vendor definition
// //
// #define INTEL_VENDOR_ID 0x8086
// #define AMD_VENDOR_ID 0x1002
// #define VIA_VENDOR_ID 0x1106
#ifndef PCIEX_BASE_ADDRESS
#define PCIEX_BASE_ADDRESS 0xE0000000
#endif
#define FIFO_SIZE_IN_BYTES (UINT32)-1
#ifndef PCI_EXPRESS_BASE_ADDRESS
#define PCI_EXPRESS_BASE_ADDRESS ((VOID *) (UINTN) PCIEX_BASE_ADDRESS)
#endif
#ifndef MmPciAddress
#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
( (UINTN)PCI_EXPRESS_BASE_ADDRESS + \
(UINTN)(Bus << 20) + \
(UINTN)(Device << 15) + \
(UINTN)(Function << 12) + \
(UINTN)(Register) \
)
#endif
//
// Private Data Structures
//
#define I2C_PORT_CONTEXT_FROM_MASTER_PROTOCOL(a) CR (a, I2C_BUS_INSTANCE, MasterApi, I2C_PRIVATE_DATA_SIGNATURE)
#define I2C_PORT_CONTEXT_FROM_COFNIG_PROTOCOL(a) CR (a, I2C_BUS_INSTANCE, ConfigApi, I2C_PRIVATE_DATA_SIGNATURE)
#define I2C_ASYNC_CONTEXT_FROM_LINK(a) CR (a, I2C_ASYNC_NODE, Link, I2C_PRIVATE_DATA_SIGNATURE)
typedef struct {
UINT8 SlaveAddress;
UINT8 GpioIntPin;
UINT8 IntPinLevel;
UINT8 GpioController;
UINT16 HidDescReg;
UINT16 Devicetype;
UINT16 HostNum;
UINT16 SpeedOverrid;
}I2C_HID_DEV;
typedef struct {
UINT8 SlaveAddress;
UINT8 Reserved;
UINT16 Length;
UINT32 Command;
} CACHE_HEADER;
#define I2C_DEVICE_MODE_MMIO 1
#define I2C_DEVICE_MODE_PCI 2
#define I2C_DEVICE_MODE_ACPI 3
typedef struct {
PCI_DEVICE_PATH Pci;
EFI_DEVICE_PATH End;
}I2C_PCI_HC_DEV_PATH;
typedef struct {
MEMMAP_DEVICE_PATH Mmio;
EFI_DEVICE_PATH End;
}I2C_MEM_HC_DEV_PATH;
typedef
struct _I2C_ASYNC_NODE{
UINTN Signature;
LIST_ENTRY Link;
H2O_I2C_HID_DEVICE *I2cDev;
EFI_I2C_REQUEST_PACKET *RequestPacket;
EFI_EVENT Event;
EFI_STATUS *I2cStatus;
}I2C_ASYNC_NODE;
//
// I2C bus internal function
//
UINT8
I2cHcRead8 (
IN I2C_BUS_INSTANCE *Private,
IN UINT16 Offset
);
UINT16
I2cHcRead16 (
IN I2C_BUS_INSTANCE *Private,
IN UINT16 Offset
);
UINT32
I2cHcRead32 (
IN I2C_BUS_INSTANCE *Private,
IN UINT16 Offset
);
VOID
I2cHcWrite8 (
IN I2C_BUS_INSTANCE *Private,
IN UINT16 Offset,
IN UINT8 Data
);
VOID
I2cHcWrite16 (
IN I2C_BUS_INSTANCE *Private,
IN UINT16 Offset,
IN UINT16 Data
);
VOID
I2cHcWrite32 (
IN I2C_BUS_INSTANCE *Private,
IN UINT16 Offset,
IN UINT32 Data
);
BOOLEAN
I2cHardwareActive (
IN I2C_BUS_INSTANCE *Private
);
EFI_STATUS
TxAbortChk(
IN I2C_BUS_INSTANCE *Private
);
VOID
LocalIrqSave(
OUT UINT32 *eflags
);
VOID
LocalIrqRestore(
IN UINT32 eflags
);
VOID
I2cReset (
IN I2C_BUS_INSTANCE *Private
);
RETURN_STATUS
I2cStartRequest (
IN I2C_BUS_INSTANCE *Private,
IN UINTN SlaveAddress,
IN UINTN *WriteBytes,
IN UINT8 *WriteBuffer,
IN UINTN *ReadBytes,
OUT UINT8 *ReadBuffer,
IN BOOLEAN RepeatStart
);
EFI_STATUS
I2cPusAsyncQueue (
IN I2C_BUS_INSTANCE *I2cContext,
IN UINTN SlaveAddress,
IN EFI_I2C_REQUEST_PACKET *RequestPacket,
IN EFI_EVENT Event,
OUT EFI_STATUS *I2cStatus
);
EFI_STATUS
LocateI2cBase(
IN I2C_BUS_INSTANCE *Private,
OUT EFI_PHYSICAL_ADDRESS *Base0BackUp,
OUT UINT32 *PciCmdBackUp
);
VOID
FreeI2cBase(
IN I2C_BUS_INSTANCE *Private,
IN EFI_PHYSICAL_ADDRESS Base0Org,
IN UINT32 PciCmdOrg
);
//
// Publish protocol
//
/**
Set the I2C controller bus clock frequency.
This routine must be called at or below TPL_NOTIFY.
The software and controller do a best case effort of using the specified
frequency for the I2C bus. If the frequency does not match exactly then
the controller will use a slightly lower frequency for the I2C to avoid
exceeding the operating conditions for any of the I2C devices on the bus.
For example if 400 KHz was specified and the controller's divide network
only supports 402 KHz or 398 KHz then the controller would be set to 398
KHz. However if the desired frequency is 400 KHz and the controller only
supports 1 MHz and 100 KHz then this routine would return EFI_UNSUPPORTED.
@param[in] This Address of an EFI_I2C_MASTER_PROTOCOL
structure
@param[in] BusClockHertz New I2C bus clock frequency in Hertz
@retval EFI_SUCCESS The bus frequency was set successfully.
@retval EFI_UNSUPPORTED The controller does not support this frequency.
**/
EFI_STATUS
EFIAPI
I2cPortSetBusFrequency (
IN CONST EFI_I2C_MASTER_PROTOCOL *This,
IN OUT UINTN *BusClockHertz
);
/**
Reset the I2C controller and configure it for use
This routine must be called at or below TPL_NOTIFY.
The controller's I2C bus frequency is set to 100 KHz.
@param[in] This Address of an EFI_I2C_MASTER_PROTOCOL
structure
@retval EFI_SUCCESS The bus reset was set successfully.
**/
EFI_STATUS
I2cPortReset (
IN CONST EFI_I2C_MASTER_PROTOCOL *This
);
/**
Start an I2C operation on the controller
This routine must be called at or below TPL_NOTIFY. For synchronous
requests this routine must be called at or below TPL_CALLBACK.
N.B. The typical consumer of this API is the I2C host driver.
Extreme care must be taken by other consumers of this API to
prevent confusing the third party I2C drivers due to a state
change at the I2C device which the third party I2C drivers did
not initiate. I2C platform drivers may use this API within
these guidelines.
This function initiates an I2C operation on the controller.
N.B. This API supports only one operation, no queuing support
exists at this layer.
The operation is performed by selecting the I2C device with its slave
address and then sending all write data to the I2C device. If read data
is requested, a restart is sent followed by the slave address and then
the read data is clocked into the I2C controller and placed in the read
buffer. When the operation completes, the status value is returned and
then the event is set.
@param[in] This Address of an EFI_I2C_MASTER_PROTOCOL
structure
@param[in] SlaveAddress Address of the device on the I2C bus.
@param[in] Event Event to set for asynchronous operations,
NULL for synchronous operations
@param[in] RequestPacket Address of an EFI_I2C_REQUEST_PACKET
structure describing the I2C operation
@param[out] I2cStatus Optional buffer to receive the I2C operation
completion status
@retval EFI_SUCCESS The operation completed successfully.
@retval EFI_ABORTED The request did not complete because the driver
was shutdown.
@retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the operation.
This could indicate the slave device is not present.
@retval EFI_INVALID_PARAMETER RequestPacket is NULL
@retval EFI_INVALID_PARAMETER TPL is too high
@retval EFI_NOT_FOUND SlaveAddress exceeds maximum address
@retval EFI_NOT_READY I2C bus is busy or operation pending, wait for
the event and then read status pointed to by
the request packet.
@retval EFI_NO_RESPONSE The I2C device is not responding to the
slave address. EFI_DEVICE_ERROR may also be
returned if the controller can not distinguish
when the NACK occurred.
@retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C operation
@retval EFI_TIMEOUT The transaction did not complete within an internally
specified timeout period.
**/
EFI_STATUS
EFIAPI
I2cPortMasterStartRequest (
IN CONST EFI_I2C_MASTER_PROTOCOL *This,
IN UINTN SlaveAddress,
IN EFI_I2C_REQUEST_PACKET *RequestPacket,
IN EFI_EVENT Event OPTIONAL,
OUT EFI_STATUS *I2cStatus OPTIONAL
);
/**
Enable access to an I2C bus configuration.
This routine must be called at or below TPL_NOTIFY. For synchronous
requests this routine must be called at or below TPL_CALLBACK.
Reconfigure the switches and multiplexers in the I2C bus to enable
access to a specific I2C bus configuration. Also select the maximum
clock frequency for this I2C bus configuration.
This routine uses the I2C Master protocol to perform I2C transactions
on the local bus. This eliminates any recursion in the I2C stack for
configuration transactions on the same I2C bus. This works because the
local I2C bus is idle while the I2C bus configuration is being enabled.
If I2C transactions must be performed on other I2C busses, then the
EFI_I2C_HOST_PROTOCOL, the EFI_I2C_IO_PROTCOL, or a third party I2C
driver interface for a specific device must be used. This requirement
is because the I2C host protocol controls the flow of requests to the
I2C controller. Use the EFI_I2C_HOST_PROTOCOL when the I2C device is
not enumerated by the EFI_I2C_ENUMERATE_PROTOCOL. Use a protocol
produced by a third party driver when it is available or the
EFI_I2C_IO_PROTOCOL when the third party driver is not available but
the device is enumerated with the EFI_I2C_ENUMERATE_PROTOCOL.
When Event is NULL, EnableI2cBusConfiguration operates synchronously
and returns the I2C completion status as its return value.
@param[in] This Pointer to an EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL
structure.
@param[in] I2cBusConfiguration Index of an I2C bus configuration. All
values in the range of zero to N-1 are
valid where N is the total number of I2C
bus configurations for an I2C bus.
@param[in] Event Event to signal when the transaction is complete
@param[out] I2cStatus Buffer to receive the transaction status.
@return When Event is NULL, EnableI2cBusConfiguration operates synchrouously
and returns the I2C completion status as its return value. In this case it is
recommended to use NULL for I2cStatus. The values returned from
EnableI2cBusConfiguration are:
@retval EFI_SUCCESS The asynchronous bus configuration request
was successfully started when Event is not
NULL.
@retval EFI_SUCCESS The bus configuration request completed
successfully when Event is NULL.
@retval EFI_DEVICE_ERROR The bus configuration failed.
@retval EFI_NO_MAPPING Invalid I2cBusConfiguration value
**/
EFI_STATUS
EFIAPI
I2cBusConfiguration (
IN CONST EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL *This,
IN UINTN I2cBusConfiguration,
IN EFI_EVENT Event OPTIONAL,
IN EFI_STATUS *I2cStatus OPTIONAL
);
#endif