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 (Platform/Marvell/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.
|