1. Introduction
---------------
**MvEeprom** driver creates MARVELL_EEPROM_PROTOCOL, which
+is used for managing eeprom.
2. MvEeprom driver design
-------------------------
Every I2C device driver should implement EFI_DRIVER_BINDING_PROTOCOL and
consume EFI_I2C_IO_PROTOCOL for transactions on I2C bus. MvEeprom driver
additionally implements MARVELL_EEPROM_PROTOCOL.
2.1 EFI_DRIVER_BINDING_PROTOCOL
-------------------------------
Driver Binding protocol is extensively covered in UEFI documentation, as
it is not specific to I2C stack. The only difference is that Supported()
function should check if EFI_I2C_IO_PROTOCOL provides valid EFI_GUID and
DeviceIndex values.
Excerpt from MvEepromSupported():
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiI2cIoProtocolGuid,
(VOID **) &TmpI2cIo,
gImageHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR(Status)) {
return EFI_UNSUPPORTED;
}
/* get EEPROM devices' addresses from PCD */
EepromAddresses = PcdGetPtr (PcdEepromI2cAddresses);
if (EepromAddresses == 0) {
Status = EFI_UNSUPPORTED;
goto out;
}
Status = EFI_UNSUPPORTED;
for (i = 0; EepromAddresses[i] != '\0'; i++) {
/* I2C guid must fit and valid DeviceIndex must be provided */
if (CompareGuid(TmpI2cIo->DeviceGuid, &I2cGuid) &&
TmpI2cIo->DeviceIndex == EepromAddresses[i]) {
DEBUG((DEBUG_INFO, "A8kEepromSupported: attached to EEPROM device\n"));
Status = EFI_SUCCESS;
break;
}
}
2.2 EFI_I2C_IO_PROTOCOL
-----------------------
This protocol is provided by generic I2C stack. Multiple drivers can use IO
protocol at once, as queueing is implemented.
QueueRequest is a routine that queues an I2C transaction to the I2C
controller for execution on the I2C bus.
2.3 MARVELL_EEPROM_PROTOCOL
-----------------------
typedef struct _MARVELL_EEPROM_PROTOCOL MARVELL_EEPROM_PROTOCOL;
#define EEPROM_READ 0x1
#define EEPROM_WRITE 0x0
typedef
EFI_STATUS
(EFIAPI *EFI_EEPROM_TRANSFER) (
IN CONST MARVELL_EEPROM_PROTOCOL *This,
IN UINT16 Address,
IN UINT32 Length,
IN UINT8 *Buffer,
IN UINT8 Operation
);
struct _MARVELL_EEPROM_PROTOCOL {
EFI_EEPROM_TRANSFER Transfer;
UINT8 Identifier;
};
3. Adding new I2C slave device drivers
--------------------------------------
In order to support I2C slave device other than EEPROM, new driver should
be created. Required steps follow.
1. Create driver directory (OpenPlatformPkg/Drivers/I2c/Devices/...).
2. Create stubs of .inf and .c files (MvEeprom files are a reference),
include .inf file in platform .dsc and .fdf files.
3. Implement EFI_DRIVER_BINDING_PROTOCOL - Start(), Stop(), Supported()
functions' implementation is a must. EFI_DRIVER_BINDING_PROTOCOL
should be installed at driver's entry point.
4. Add I2C address of device to PcdI2cSlaveAddresses in .dsc file.
5. Test available EFI_I2C_IO_PROTOCOLs in Supported() - find instance
with valid GUID and DeviceIndex (I2C slave address).
6. Open EFI_I2C_IO_PROTOCOL for usage in Start(). After that, QueueRequest
function should be available.
7. Implement core functionality of driver (using QueueRequest to access I2C).
8. (not mandatory) Produce/consume additional protocols.