11. Introduction 2--------------- 3**MvEeprom** driver creates MARVELL_EEPROM_PROTOCOL, which 4+is used for managing eeprom. 5 62. MvEeprom driver design 7------------------------- 8Every I2C device driver should implement EFI_DRIVER_BINDING_PROTOCOL and 9consume EFI_I2C_IO_PROTOCOL for transactions on I2C bus. MvEeprom driver 10additionally implements MARVELL_EEPROM_PROTOCOL. 11 12 2.1 EFI_DRIVER_BINDING_PROTOCOL 13 ------------------------------- 14 Driver Binding protocol is extensively covered in UEFI documentation, as 15 it is not specific to I2C stack. The only difference is that Supported() 16 function should check if EFI_I2C_IO_PROTOCOL provides valid EFI_GUID and 17 DeviceIndex values. 18 Excerpt from MvEepromSupported(): 19 20 Status = gBS->OpenProtocol ( 21 ControllerHandle, 22 &gEfiI2cIoProtocolGuid, 23 (VOID **) &TmpI2cIo, 24 gImageHandle, 25 ControllerHandle, 26 EFI_OPEN_PROTOCOL_BY_DRIVER 27 ); 28 if (EFI_ERROR(Status)) { 29 return EFI_UNSUPPORTED; 30 } 31 32 /* get EEPROM devices' addresses from PCD */ 33 EepromAddresses = PcdGetPtr (PcdEepromI2cAddresses); 34 if (EepromAddresses == 0) { 35 Status = EFI_UNSUPPORTED; 36 goto out; 37 } 38 39 Status = EFI_UNSUPPORTED; 40 for (i = 0; EepromAddresses[i] != '\0'; i++) { 41 /* I2C guid must fit and valid DeviceIndex must be provided */ 42 if (CompareGuid(TmpI2cIo->DeviceGuid, &I2cGuid) && 43 TmpI2cIo->DeviceIndex == EepromAddresses[i]) { 44 DEBUG((DEBUG_INFO, "A8kEepromSupported: attached to EEPROM device\n")); 45 Status = EFI_SUCCESS; 46 break; 47 } 48 } 49 50 2.2 EFI_I2C_IO_PROTOCOL 51 ----------------------- 52 This protocol is provided by generic I2C stack. Multiple drivers can use IO 53 protocol at once, as queueing is implemented. 54 55 QueueRequest is a routine that queues an I2C transaction to the I2C 56 controller for execution on the I2C bus. 57 58 2.3 MARVELL_EEPROM_PROTOCOL 59 ----------------------- 60 typedef struct _MARVELL_EEPROM_PROTOCOL MARVELL_EEPROM_PROTOCOL; 61 62 #define EEPROM_READ 0x1 63 #define EEPROM_WRITE 0x0 64 typedef 65 EFI_STATUS 66 (EFIAPI *EFI_EEPROM_TRANSFER) ( 67 IN CONST MARVELL_EEPROM_PROTOCOL *This, 68 IN UINT16 Address, 69 IN UINT32 Length, 70 IN UINT8 *Buffer, 71 IN UINT8 Operation 72 ); 73 74 struct _MARVELL_EEPROM_PROTOCOL { 75 EFI_EEPROM_TRANSFER Transfer; 76 UINT8 Identifier; 77 }; 78 793. Adding new I2C slave device drivers 80-------------------------------------- 81In order to support I2C slave device other than EEPROM, new driver should 82be created. Required steps follow. 83 84 1. Create driver directory (OpenPlatformPkg/Drivers/I2c/Devices/...). 85 2. Create stubs of .inf and .c files (MvEeprom files are a reference), 86 include .inf file in platform .dsc and .fdf files. 87 3. Implement EFI_DRIVER_BINDING_PROTOCOL - Start(), Stop(), Supported() 88 functions' implementation is a must. EFI_DRIVER_BINDING_PROTOCOL 89 should be installed at driver's entry point. 90 4. Add I2C address of device to PcdI2cSlaveAddresses in .dsc file. 91 5. Test available EFI_I2C_IO_PROTOCOLs in Supported() - find instance 92 with valid GUID and DeviceIndex (I2C slave address). 93 6. Open EFI_I2C_IO_PROTOCOL for usage in Start(). After that, QueueRequest 94 function should be available. 95 7. Implement core functionality of driver (using QueueRequest to access I2C). 96 8. (not mandatory) Produce/consume additional protocols. 97