Home | History | Annotate | Download | only in MvI2cDxe
      1 /********************************************************************************
      2 Copyright (C) 2016 Marvell International Ltd.
      3 
      4 Marvell BSD License Option
      5 
      6 If you received this File from Marvell, you may opt to use, redistribute and/or
      7 modify this File under the following licensing terms.
      8 Redistribution and use in source and binary forms, with or without modification,
      9 are permitted provided that the following conditions are met:
     10 
     11 * Redistributions of source code must retain the above copyright notice,
     12   this list of conditions and the following disclaimer.
     13 
     14 * Redistributions in binary form must reproduce the above copyright
     15   notice, this list of conditions and the following disclaimer in the
     16   documentation and/or other materials provided with the distribution.
     17 
     18 * Neither the name of Marvell nor the names of its contributors may be
     19   used to endorse or promote products derived from this software without
     20   specific prior written permission.
     21 
     22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
     26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32 
     33 *******************************************************************************/
     34 
     35 #include <Protocol/I2cMaster.h>
     36 #include <Protocol/I2cEnumerate.h>
     37 #include <Protocol/I2cBusConfigurationManagement.h>
     38 #include <Protocol/DevicePath.h>
     39 
     40 #include <Library/BaseLib.h>
     41 #include <Library/IoLib.h>
     42 #include <Library/DebugLib.h>
     43 #include <Library/PcdLib.h>
     44 #include <Library/UefiLib.h>
     45 #include <Library/ParsePcdLib.h>
     46 #include <Library/MemoryAllocationLib.h>
     47 #include <Library/UefiBootServicesTableLib.h>
     48 
     49 #include "MvI2cDxe.h"
     50 
     51 STATIC MV_I2C_BAUD_RATE baud_rate;
     52 
     53 STATIC MV_I2C_DEVICE_PATH MvI2cDevicePathProtocol = {
     54   {
     55     {
     56       HARDWARE_DEVICE_PATH,
     57       HW_VENDOR_DP,
     58       {
     59   (UINT8) (sizeof(VENDOR_DEVICE_PATH)),
     60   (UINT8) (sizeof(VENDOR_DEVICE_PATH) >> 8),
     61       },
     62     },
     63     EFI_CALLER_ID_GUID
     64   },
     65   {
     66     END_DEVICE_PATH_TYPE,
     67     END_ENTIRE_DEVICE_PATH_SUBTYPE,
     68     {
     69       sizeof(EFI_DEVICE_PATH_PROTOCOL),
     70       0
     71     }
     72   }
     73 };
     74 
     75 STATIC
     76 UINT32
     77 I2C_READ(
     78   IN I2C_MASTER_CONTEXT *I2cMasterContext,
     79   IN UINTN off)
     80 {
     81   ASSERT (I2cMasterContext != NULL);
     82   return MmioRead32 (I2cMasterContext->BaseAddress + off);
     83 }
     84 
     85 STATIC
     86 EFI_STATUS
     87 I2C_WRITE (
     88   IN I2C_MASTER_CONTEXT *I2cMasterContext,
     89   IN UINTN off,
     90   IN UINT32 Value)
     91 {
     92   ASSERT (I2cMasterContext != NULL);
     93   return MmioWrite32 (I2cMasterContext->BaseAddress + off, Value);
     94 }
     95 
     96 EFI_STATUS
     97 EFIAPI
     98 MvI2cInitialiseController (
     99   IN EFI_HANDLE  ImageHandle,
    100   IN EFI_SYSTEM_TABLE  *SystemTable,
    101   IN EFI_PHYSICAL_ADDRESS BaseAddress
    102   )
    103 {
    104   EFI_STATUS Status;
    105   I2C_MASTER_CONTEXT *I2cMasterContext;
    106   STATIC INTN Bus = 0;
    107   MV_I2C_DEVICE_PATH *DevicePath;
    108 
    109   DevicePath = AllocateCopyPool (sizeof(MvI2cDevicePathProtocol),
    110                                  &MvI2cDevicePathProtocol);
    111   if (DevicePath == NULL) {
    112     DEBUG((DEBUG_ERROR, "MvI2cDxe: I2C device path allocation failed\n"));
    113     return EFI_OUT_OF_RESOURCES;
    114   }
    115   DevicePath->Guid.Guid.Data4[0] = Bus;
    116 
    117   /* if attachment succeeds, this gets freed at ExitBootServices */
    118   I2cMasterContext = AllocateZeroPool (sizeof (I2C_MASTER_CONTEXT));
    119   if (I2cMasterContext == NULL) {
    120     DEBUG((DEBUG_ERROR, "MvI2cDxe: I2C master context allocation failed\n"));
    121     return EFI_OUT_OF_RESOURCES;
    122   }
    123   I2cMasterContext->Signature = I2C_MASTER_SIGNATURE;
    124   I2cMasterContext->I2cMaster.Reset = MvI2cReset;
    125   I2cMasterContext->I2cMaster.StartRequest = MvI2cStartRequest;
    126   I2cMasterContext->I2cEnumerate.Enumerate = MvI2cEnumerate;
    127   I2cMasterContext->I2cBusConf.EnableI2cBusConfiguration = MvI2cEnableConf;
    128   I2cMasterContext->TclkFrequency = PcdGet32 (PcdI2cClockFrequency);
    129   I2cMasterContext->BaseAddress = BaseAddress;
    130   I2cMasterContext->Bus = Bus;
    131   /* I2cMasterContext->Lock is responsible for serializing I2C operations */
    132   EfiInitializeLock(&I2cMasterContext->Lock, TPL_NOTIFY);
    133 
    134   MvI2cCalBaudRate( I2cMasterContext,
    135                     PcdGet32 (PcdI2cBaudRate),
    136                     &baud_rate,
    137                     I2cMasterContext->TclkFrequency
    138                   );
    139 
    140   Status = gBS->InstallMultipleProtocolInterfaces(
    141       &I2cMasterContext->Controller,
    142       &gEfiI2cMasterProtocolGuid,
    143       &I2cMasterContext->I2cMaster,
    144       &gEfiI2cEnumerateProtocolGuid,
    145       &I2cMasterContext->I2cEnumerate,
    146       &gEfiI2cBusConfigurationManagementProtocolGuid,
    147       &I2cMasterContext->I2cBusConf,
    148       &gEfiDevicePathProtocolGuid,
    149       (EFI_DEVICE_PATH_PROTOCOL *) DevicePath,
    150       NULL);
    151 
    152   if (EFI_ERROR(Status)) {
    153     DEBUG((DEBUG_ERROR, "MvI2cDxe: Installing protocol interfaces failed!\n"));
    154     goto fail;
    155   }
    156   DEBUG((DEBUG_ERROR, "Succesfully installed controller %d at 0x%llx\n", Bus,
    157         I2cMasterContext->BaseAddress));
    158 
    159   Bus++;
    160 
    161   return EFI_SUCCESS;
    162 
    163 fail:
    164   FreePool(I2cMasterContext);
    165   return Status;
    166 }
    167 
    168 EFI_STATUS
    169 EFIAPI
    170 MvI2cInitialise (
    171   IN EFI_HANDLE  ImageHandle,
    172   IN EFI_SYSTEM_TABLE  *SystemTable
    173   )
    174 {
    175   EFI_STATUS Status;
    176   UINT32 BusCount;
    177   EFI_PHYSICAL_ADDRESS I2cBaseAddresses[PcdGet32 (PcdI2cBusCount)];
    178   INTN i;
    179 
    180   BusCount = PcdGet32 (PcdI2cBusCount);
    181   if (BusCount == 0)
    182     return EFI_SUCCESS;
    183 
    184   Status = ParsePcdString (
    185       (CHAR16 *) PcdGetPtr (PcdI2cBaseAddresses),
    186       BusCount,
    187       I2cBaseAddresses,
    188       NULL
    189       );
    190   if (EFI_ERROR(Status))
    191     return Status;
    192 
    193   for (i = 0; i < BusCount; i++) {
    194     Status = MvI2cInitialiseController(
    195         ImageHandle,
    196         SystemTable,
    197         I2cBaseAddresses[i]
    198         );
    199     if (EFI_ERROR(Status))
    200       return Status;
    201   }
    202 
    203   return Status;
    204 }
    205 
    206 STATIC
    207 VOID
    208 MvI2cControlClear (
    209   IN I2C_MASTER_CONTEXT *I2cMasterContext,
    210   IN UINT32 Mask)
    211 {
    212   UINT32 Value;
    213 
    214   /* clears given bits in I2C_CONTROL register */
    215   Value = I2C_READ(I2cMasterContext, I2C_CONTROL);
    216   Value &= ~Mask;
    217   I2C_WRITE(I2cMasterContext, I2C_CONTROL, Value);
    218 }
    219 
    220 STATIC
    221 VOID
    222 MvI2cControlSet (
    223   IN I2C_MASTER_CONTEXT *I2cMasterContext,
    224   IN UINT32 Mask)
    225 {
    226   UINT32 Value;
    227 
    228   /* sets given bits in I2C_CONTROL register */
    229   Value = I2C_READ(I2cMasterContext, I2C_CONTROL);
    230   Value |= Mask;
    231   I2C_WRITE(I2cMasterContext, I2C_CONTROL, Value);
    232 }
    233 
    234 STATIC
    235 VOID
    236 MvI2cClearIflg (
    237  IN I2C_MASTER_CONTEXT *I2cMasterContext
    238  )
    239 {
    240   gBS->Stall(I2C_OPERATION_TIMEOUT);
    241   MvI2cControlClear(I2cMasterContext, I2C_CONTROL_IFLG);
    242   gBS->Stall(I2C_OPERATION_TIMEOUT);
    243 }
    244 
    245 /* Timeout is given in us */
    246 STATIC
    247 UINTN
    248 MvI2cPollCtrl (
    249   IN I2C_MASTER_CONTEXT *I2cMasterContext,
    250   IN UINTN Timeout,
    251   IN UINT32 Mask)
    252 {
    253   Timeout /= 10;
    254   while (!(I2C_READ(I2cMasterContext, I2C_CONTROL) & Mask)) {
    255     gBS->Stall(10);
    256     if (--Timeout == 0)
    257       return (Timeout);
    258   }
    259   return (0);
    260 }
    261 
    262 /*
    263  * 'Timeout' is given in us. Note also that Timeout handling is not exact --
    264  * MvI2cLockedStart() total wait can be more than 2 x Timeout
    265  * (MvI2cPollCtrl() is called twice). 'Mask' can be either I2C_STATUS_START
    266  * or I2C_STATUS_RPTD_START
    267  */
    268 STATIC
    269 EFI_STATUS
    270 MvI2cLockedStart (
    271   IN I2C_MASTER_CONTEXT *I2cMasterContext,
    272   IN INT32 Mask,
    273   IN UINT8 Slave,
    274   IN UINTN Timeout
    275   )
    276 {
    277   UINTN ReadAccess, IflgSet = 0;
    278   UINT32 I2cStatus;
    279 
    280   if (Mask == I2C_STATUS_RPTD_START) {
    281     /* read IFLG to know if it should be cleared later */
    282     IflgSet = I2C_READ(I2cMasterContext, I2C_CONTROL) & I2C_CONTROL_IFLG;
    283   }
    284 
    285   MvI2cControlSet(I2cMasterContext, I2C_CONTROL_START);
    286 
    287   if (Mask == I2C_STATUS_RPTD_START && IflgSet) {
    288     DEBUG((DEBUG_INFO, "MvI2cDxe: IFLG set, clearing\n"));
    289     MvI2cClearIflg(I2cMasterContext);
    290   }
    291 
    292   /* Without this delay we Timeout checking IFLG if the Timeout is 0 */
    293   gBS->Stall(I2C_OPERATION_TIMEOUT);
    294 
    295   if (MvI2cPollCtrl(I2cMasterContext, Timeout, I2C_CONTROL_IFLG)) {
    296     DEBUG((DEBUG_ERROR, "MvI2cDxe: Timeout sending %sSTART condition\n",
    297         Mask == I2C_STATUS_START ? "" : "repeated "));
    298     return EFI_NO_RESPONSE;
    299   }
    300 
    301   I2cStatus = I2C_READ(I2cMasterContext, I2C_STATUS);
    302   if (I2cStatus != Mask) {
    303     DEBUG((DEBUG_ERROR, "MvI2cDxe: wrong I2cStatus (%02x) after sending %sSTART condition\n",
    304         I2cStatus, Mask == I2C_STATUS_START ? "" : "repeated "));
    305     return EFI_DEVICE_ERROR;
    306   }
    307 
    308   I2C_WRITE(I2cMasterContext, I2C_DATA, Slave);
    309   gBS->Stall(I2C_OPERATION_TIMEOUT);
    310   MvI2cClearIflg(I2cMasterContext);
    311 
    312   if (MvI2cPollCtrl(I2cMasterContext, Timeout, I2C_CONTROL_IFLG)) {
    313     DEBUG((DEBUG_ERROR, "MvI2cDxe: Timeout sending Slave address\n"));
    314     return EFI_NO_RESPONSE;
    315   }
    316 
    317   ReadAccess = (Slave & 0x1) ? 1 : 0;
    318   I2cStatus = I2C_READ(I2cMasterContext, I2C_STATUS);
    319   if (I2cStatus != (ReadAccess ?
    320       I2C_STATUS_ADDR_R_ACK : I2C_STATUS_ADDR_W_ACK)) {
    321     DEBUG((DEBUG_ERROR, "MvI2cDxe: no ACK (I2cStatus: %02x) after sending Slave address\n",
    322         I2cStatus));
    323     return EFI_NO_RESPONSE;
    324   }
    325 
    326   return EFI_SUCCESS;
    327 }
    328 
    329 #define  ABSSUB(a,b)  (((a) > (b)) ? (a) - (b) : (b) - (a))
    330 STATIC
    331 VOID
    332 MvI2cCalBaudRate (
    333   IN I2C_MASTER_CONTEXT *I2cMasterContext,
    334   IN CONST UINT32 target,
    335   IN OUT MV_I2C_BAUD_RATE *rate,
    336   UINT32 clk
    337   )
    338 {
    339   UINT32 cur, diff, diff0, baud;
    340   UINTN m, n, m0, n0;
    341 
    342   /* Read initial m0, n0 values from register */
    343   baud = I2C_READ(I2cMasterContext, I2C_BAUD_RATE);
    344   m0 = I2C_M_FROM_BAUD(baud);
    345   n0 = I2C_N_FROM_BAUD(baud);
    346   /* Calculate baud rate. */
    347   diff0 = 0xffffffff;
    348 
    349   for (n = 0; n < 8; n++) {
    350     for (m = 0; m < 16; m++) {
    351       cur = I2C_BAUD_RATE_RAW(clk,m,n);
    352       diff = ABSSUB(target, cur);
    353       if (diff < diff0) {
    354         m0 = m;
    355         n0 = n;
    356         diff0 = diff;
    357       }
    358     }
    359   }
    360   rate->raw = I2C_BAUD_RATE_RAW(clk, m0, n0);
    361   rate->param = I2C_BAUD_RATE_PARAM(m0, n0);
    362   rate->m = m0;
    363   rate->n = n0;
    364 }
    365 
    366 EFI_STATUS
    367 EFIAPI
    368 MvI2cReset (
    369   IN CONST EFI_I2C_MASTER_PROTOCOL *This
    370   )
    371 {
    372   UINT32 param;
    373   I2C_MASTER_CONTEXT *I2cMasterContext = I2C_SC_FROM_MASTER(This);
    374 
    375   param = baud_rate.param;
    376 
    377   EfiAcquireLock (&I2cMasterContext->Lock);
    378   I2C_WRITE(I2cMasterContext, I2C_SOFT_RESET, 0x0);
    379   gBS->Stall(2 * I2C_OPERATION_TIMEOUT);
    380   I2C_WRITE(I2cMasterContext, I2C_BAUD_RATE, param);
    381   I2C_WRITE(I2cMasterContext, I2C_CONTROL, I2C_CONTROL_I2CEN | I2C_CONTROL_ACK);
    382   gBS->Stall(I2C_OPERATION_TIMEOUT);
    383   EfiReleaseLock (&I2cMasterContext->Lock);
    384 
    385   return EFI_SUCCESS;
    386 }
    387 
    388 /*
    389  * Timeout is given in us
    390  */
    391 STATIC
    392 EFI_STATUS
    393 MvI2cRepeatedStart (
    394   IN I2C_MASTER_CONTEXT *I2cMasterContext,
    395   IN UINT8 Slave,
    396   IN UINTN Timeout
    397   )
    398 {
    399   EFI_STATUS Status;
    400 
    401   EfiAcquireLock (&I2cMasterContext->Lock);
    402   Status = MvI2cLockedStart(I2cMasterContext, I2C_STATUS_RPTD_START, Slave,
    403       Timeout);
    404   EfiReleaseLock (&I2cMasterContext->Lock);
    405 
    406   if (EFI_ERROR(Status)) {
    407     MvI2cStop(I2cMasterContext);
    408   }
    409   return Status;
    410 }
    411 
    412 /*
    413  * Timeout is given in us
    414  */
    415 STATIC
    416 EFI_STATUS
    417 MvI2cStart (
    418   IN I2C_MASTER_CONTEXT *I2cMasterContext,
    419   IN UINT8 Slave,
    420   IN UINTN Timeout
    421   )
    422 {
    423   EFI_STATUS Status;
    424 
    425   EfiAcquireLock (&I2cMasterContext->Lock);
    426   Status = MvI2cLockedStart(I2cMasterContext, I2C_STATUS_START, Slave, Timeout);
    427   EfiReleaseLock (&I2cMasterContext->Lock);
    428 
    429   if (EFI_ERROR(Status)) {
    430     MvI2cStop(I2cMasterContext);
    431   }
    432   return Status;
    433 }
    434 
    435 STATIC
    436 EFI_STATUS
    437 MvI2cStop (
    438   IN I2C_MASTER_CONTEXT *I2cMasterContext
    439   )
    440 {
    441   EfiAcquireLock (&I2cMasterContext->Lock);
    442   MvI2cControlSet(I2cMasterContext, I2C_CONTROL_STOP);
    443   gBS->Stall(I2C_OPERATION_TIMEOUT);
    444   MvI2cClearIflg(I2cMasterContext);
    445   EfiReleaseLock (&I2cMasterContext->Lock);
    446 
    447   return EFI_SUCCESS;
    448 }
    449 
    450 STATIC
    451 EFI_STATUS
    452 MvI2cRead (
    453   IN I2C_MASTER_CONTEXT *I2cMasterContext,
    454   IN OUT UINT8 *Buf,
    455   IN UINTN Length,
    456   IN OUT UINTN *read,
    457   IN UINTN last,
    458   IN UINTN delay
    459   )
    460 {
    461   UINT32 I2cStatus;
    462   UINTN LastByte;
    463   EFI_STATUS Status;
    464 
    465   EfiAcquireLock (&I2cMasterContext->Lock);
    466   *read = 0;
    467   while (*read < Length) {
    468     /*
    469      * Check if we are reading last byte of the last Buffer,
    470      * do not send ACK then, per I2C specs
    471      */
    472     LastByte = ((*read == Length - 1) && last) ? 1 : 0;
    473     if (LastByte)
    474       MvI2cControlClear(I2cMasterContext, I2C_CONTROL_ACK);
    475     else
    476       MvI2cControlSet(I2cMasterContext, I2C_CONTROL_ACK);
    477 
    478     gBS->Stall (I2C_OPERATION_TIMEOUT);
    479     MvI2cClearIflg(I2cMasterContext);
    480 
    481     if (MvI2cPollCtrl(I2cMasterContext, delay, I2C_CONTROL_IFLG)) {
    482       DEBUG((DEBUG_ERROR, "MvI2cDxe: Timeout reading data\n"));
    483       Status = EFI_NO_RESPONSE;
    484       goto out;
    485     }
    486 
    487     I2cStatus = I2C_READ(I2cMasterContext, I2C_STATUS);
    488     if (I2cStatus != (LastByte ?
    489         I2C_STATUS_DATA_RD_NOACK : I2C_STATUS_DATA_RD_ACK)) {
    490       DEBUG((DEBUG_ERROR, "MvI2cDxe: wrong I2cStatus (%02x) while reading\n", I2cStatus));
    491       Status = EFI_DEVICE_ERROR;
    492       goto out;
    493     }
    494 
    495     *Buf++ = I2C_READ(I2cMasterContext, I2C_DATA);
    496     (*read)++;
    497   }
    498   Status = EFI_SUCCESS;
    499 out:
    500   EfiReleaseLock (&I2cMasterContext->Lock);
    501   return (Status);
    502 }
    503 
    504 STATIC
    505 EFI_STATUS
    506 MvI2cWrite (
    507   IN I2C_MASTER_CONTEXT *I2cMasterContext,
    508   IN OUT CONST UINT8 *Buf,
    509   IN UINTN Length,
    510   IN OUT UINTN *Sent,
    511   IN UINTN Timeout
    512   )
    513 {
    514   UINT32 status;
    515   EFI_STATUS Status;
    516 
    517   EfiAcquireLock (&I2cMasterContext->Lock);
    518   *Sent = 0;
    519   while (*Sent < Length) {
    520     I2C_WRITE(I2cMasterContext, I2C_DATA, *Buf++);
    521 
    522     MvI2cClearIflg(I2cMasterContext);
    523     if (MvI2cPollCtrl(I2cMasterContext, Timeout, I2C_CONTROL_IFLG)) {
    524       DEBUG((DEBUG_ERROR, "MvI2cDxe: Timeout writing data\n"));
    525       Status = EFI_NO_RESPONSE;
    526       goto out;
    527     }
    528 
    529     status = I2C_READ(I2cMasterContext, I2C_STATUS);
    530     if (status != I2C_STATUS_DATA_WR_ACK) {
    531       DEBUG((DEBUG_ERROR, "MvI2cDxe: wrong status (%02x) while writing\n", status));
    532       Status = EFI_DEVICE_ERROR;
    533       goto out;
    534     }
    535     (*Sent)++;
    536   }
    537   Status = EFI_SUCCESS;
    538 out:
    539   EfiReleaseLock (&I2cMasterContext->Lock);
    540   return (Status);
    541 }
    542 
    543 /*
    544  * MvI2cStartRequest should be called only by I2cHost.
    545  * I2C device drivers ought to use EFI_I2C_IO_PROTOCOL instead.
    546  */
    547 STATIC
    548 EFI_STATUS
    549 MvI2cStartRequest (
    550   IN CONST EFI_I2C_MASTER_PROTOCOL *This,
    551   IN UINTN                         SlaveAddress,
    552   IN EFI_I2C_REQUEST_PACKET        *RequestPacket,
    553   IN EFI_EVENT                     Event      OPTIONAL,
    554   OUT EFI_STATUS                   *I2cStatus OPTIONAL
    555   )
    556 {
    557   UINTN Count;
    558   UINTN ReadMode;
    559   UINTN Transmitted;
    560   I2C_MASTER_CONTEXT *I2cMasterContext = I2C_SC_FROM_MASTER(This);
    561   EFI_I2C_OPERATION *Operation;
    562 
    563   ASSERT (RequestPacket != NULL);
    564   ASSERT (I2cMasterContext != NULL);
    565 
    566   for (Count = 0; Count < RequestPacket->OperationCount; Count++) {
    567     Operation = &RequestPacket->Operation[Count];
    568     ReadMode = Operation->Flags & I2C_FLAG_READ;
    569 
    570     if (Count == 0) {
    571       MvI2cStart ( I2cMasterContext,
    572                    (SlaveAddress << 1) | ReadMode,
    573                    I2C_TRANSFER_TIMEOUT
    574                  );
    575     } else if (!(Operation->Flags & I2C_FLAG_NORESTART)) {
    576       MvI2cRepeatedStart ( I2cMasterContext,
    577                            (SlaveAddress << 1) | ReadMode,
    578                            I2C_TRANSFER_TIMEOUT
    579                          );
    580     }
    581 
    582     if (ReadMode) {
    583       MvI2cRead ( I2cMasterContext,
    584                   Operation->Buffer,
    585                   Operation->LengthInBytes,
    586                   &Transmitted,
    587                   Count == 1,
    588                   I2C_TRANSFER_TIMEOUT
    589                  );
    590     } else {
    591       MvI2cWrite ( I2cMasterContext,
    592                    Operation->Buffer,
    593                    Operation->LengthInBytes,
    594                    &Transmitted,
    595                    I2C_TRANSFER_TIMEOUT
    596                   );
    597     }
    598     if (Count == RequestPacket->OperationCount - 1) {
    599       MvI2cStop ( I2cMasterContext );
    600     }
    601   }
    602 
    603   if (I2cStatus != NULL)
    604     I2cStatus = EFI_SUCCESS;
    605   if (Event != NULL)
    606     gBS->SignalEvent(Event);
    607   return EFI_SUCCESS;
    608 }
    609 
    610 STATIC CONST EFI_GUID DevGuid = I2C_GUID;
    611 
    612 #define I2C_DEVICE_INDEX(bus, address) (((address) & 0xffff) | (bus) << 16)
    613 #define I2C_DEVICE_ADDRESS(index) ((index) & 0xffff)
    614 
    615 STATIC
    616 EFI_STATUS
    617 MvI2cAllocDevice (
    618   IN UINT8 SlaveAddress,
    619   IN UINT8 Bus,
    620   IN OUT CONST EFI_I2C_DEVICE **Device
    621   )
    622 {
    623   EFI_STATUS Status;
    624   EFI_I2C_DEVICE *Dev;
    625   UINT32 *TmpSlaveArray;
    626   EFI_GUID *TmpGuidP;
    627 
    628   Status = gBS->AllocatePool ( EfiBootServicesData,
    629              sizeof(EFI_I2C_DEVICE),
    630              (VOID **) &Dev );
    631   if (EFI_ERROR(Status)) {
    632     DEBUG((DEBUG_ERROR, "MvI2cDxe: I2C device memory allocation failed\n"));
    633     return Status;
    634   }
    635   *Device = Dev;
    636   Dev->DeviceIndex = SlaveAddress;
    637   Dev->DeviceIndex = I2C_DEVICE_INDEX(Bus, SlaveAddress);
    638   Dev->SlaveAddressCount = 1;
    639   Dev->I2cBusConfiguration = 0;
    640   Status = gBS->AllocatePool ( EfiBootServicesData,
    641              sizeof(UINT32),
    642              (VOID **) &TmpSlaveArray);
    643   if (EFI_ERROR(Status)) {
    644     goto fail1;
    645   }
    646   TmpSlaveArray[0] = SlaveAddress;
    647   Dev->SlaveAddressArray = TmpSlaveArray;
    648 
    649   Status = gBS->AllocatePool ( EfiBootServicesData,
    650              sizeof(EFI_GUID),
    651              (VOID **) &TmpGuidP);
    652   if (EFI_ERROR(Status)) {
    653     goto fail2;
    654   }
    655   *TmpGuidP = DevGuid;
    656   Dev->DeviceGuid = TmpGuidP;
    657 
    658   DEBUG((DEBUG_INFO, "MvI2c: allocated device with address %x\n", (UINTN)SlaveAddress));
    659   return EFI_SUCCESS;
    660 
    661 fail2:
    662   FreePool(TmpSlaveArray);
    663 fail1:
    664   FreePool(Dev);
    665 
    666   return Status;
    667 }
    668 
    669 /*
    670  * It is called by I2cBus to enumerate devices on I2C bus. In this case,
    671  * enumeration is based on PCD configuration - all Slave addresses specified
    672  * in PCD get their corresponding EFI_I2C_DEVICE structures here.
    673  *
    674  * After enumeration succeeds, Supported() function of drivers that installed
    675  * DriverBinding protocol is called.
    676  */
    677 STATIC
    678 EFI_STATUS
    679 EFIAPI
    680 MvI2cEnumerate (
    681   IN CONST EFI_I2C_ENUMERATE_PROTOCOL *This,
    682   IN OUT CONST EFI_I2C_DEVICE         **Device
    683   )
    684 {
    685   UINT8 *DevicesPcd;
    686   UINT8 *DeviceBusPcd;
    687   UINTN Index, NextIndex, DevCount;
    688   UINT8 NextDeviceAddress;
    689   I2C_MASTER_CONTEXT *I2cMasterContext = I2C_SC_FROM_ENUMERATE(This);
    690 
    691   DevCount = PcdGetSize (PcdI2cSlaveAddresses);
    692   DevicesPcd = PcdGetPtr (PcdI2cSlaveAddresses);
    693   DeviceBusPcd = PcdGetPtr (PcdI2cSlaveBuses);
    694   if (*Device == NULL) {
    695     for (Index = 0; Index < DevCount ; Index++) {
    696       if (DeviceBusPcd[Index] != I2cMasterContext->Bus)
    697         continue;
    698       if (Index < DevCount)
    699         MvI2cAllocDevice (DevicesPcd[Index], I2cMasterContext->Bus, Device);
    700       return EFI_SUCCESS;
    701     }
    702   } else {
    703     /* Device is not NULL, so something was already allocated */
    704     for (Index = 0; Index < DevCount; Index++) {
    705       if (DeviceBusPcd[Index] != I2cMasterContext->Bus)
    706         continue;
    707       if (DevicesPcd[Index] == I2C_DEVICE_ADDRESS((*Device)->DeviceIndex)) {
    708         for (NextIndex = Index + 1; NextIndex < DevCount; NextIndex++) {
    709           if (DeviceBusPcd[NextIndex] != I2cMasterContext->Bus)
    710             continue;
    711           NextDeviceAddress = DevicesPcd[NextIndex];
    712           if (NextIndex < DevCount)
    713             MvI2cAllocDevice(NextDeviceAddress, I2cMasterContext->Bus, Device);
    714           return EFI_SUCCESS;
    715         }
    716       }
    717     }
    718     *Device = NULL;
    719     return EFI_SUCCESS;
    720   }
    721   return EFI_SUCCESS;
    722 }
    723 
    724 STATIC
    725 EFI_STATUS
    726 EFIAPI
    727 MvI2cEnableConf (
    728   IN CONST EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL *This,
    729   IN UINTN                                               I2cBusConfiguration,
    730   IN EFI_EVENT                                           Event      OPTIONAL,
    731   IN EFI_STATUS                                          *I2cStatus OPTIONAL
    732   )
    733 {
    734   /* do nothing */
    735   if (I2cStatus != NULL)
    736     I2cStatus = EFI_SUCCESS;
    737   if (Event != NULL)
    738     gBS->SignalEvent(Event);
    739   return EFI_SUCCESS;
    740 }
    741