/** @file
  This file implements I2C Host Protocol which provides callers with the ability to
  do I/O transactions to all of the devices on the I2C bus.

  Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "I2cDxe.h"

EFI_DRIVER_BINDING_PROTOCOL gI2cHostDriverBinding = {
  I2cHostDriverSupported,
  I2cHostDriverStart,
  I2cHostDriverStop,
  0x10,
  NULL,
  NULL
};

//
// Driver name table
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mI2cHostDriverNameTable[] = {
  { "eng;en", L"I2c Host Driver" },
  { NULL , NULL }
};

//
// EFI Component Name Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gI2cHostComponentName = {
  (EFI_COMPONENT_NAME_GET_DRIVER_NAME) I2cHostComponentNameGetDriverName,
  (EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) I2cHostComponentNameGetControllerName,
  "eng"
};

//
// EFI Component Name 2 Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gI2cHostComponentName2 = {
  I2cHostComponentNameGetDriverName,
  I2cHostComponentNameGetControllerName,
  "en"
};

/**
  Retrieves a Unicode string that is the user readable name of the driver.

  This function retrieves the user readable name of a driver in the form of a
  Unicode string. If the driver specified by This has a user readable name in
  the language specified by Language, then a pointer to the driver name is
  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
  by This does not support the language specified by Language,
  then EFI_UNSUPPORTED is returned.

  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
                                EFI_COMPONENT_NAME_PROTOCOL instance.

  @param  Language[in]          A pointer to a Null-terminated ASCII string
                                array indicating the language. This is the
                                language of the driver name that the caller is
                                requesting, and it must match one of the
                                languages specified in SupportedLanguages. The
                                number of languages supported by a driver is up
                                to the driver writer. Language is specified
                                in RFC 4646 or ISO 639-2 language code format.

  @param  DriverName[out]       A pointer to the Unicode string to return.
                                This Unicode string is the name of the
                                driver specified by This in the language
                                specified by Language.

  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
                                This and the language specified by Language was
                                returned in DriverName.

  @retval EFI_INVALID_PARAMETER Language is NULL.

  @retval EFI_INVALID_PARAMETER DriverName is NULL.

  @retval EFI_UNSUPPORTED       The driver specified by This does not support
                                the language specified by Language.

**/
EFI_STATUS
EFIAPI
I2cHostComponentNameGetDriverName (
  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
  IN  CHAR8                        *Language,
  OUT CHAR16                       **DriverName
  )
{
  return LookupUnicodeString2 (
           Language,
           This->SupportedLanguages,
           mI2cHostDriverNameTable,
           DriverName,
           (BOOLEAN)(This != &gI2cHostComponentName2)
           );
}

/**
  Retrieves a Unicode string that is the user readable name of the controller
  that is being managed by a driver.

  This function retrieves the user readable name of the controller specified by
  ControllerHandle and ChildHandle in the form of a Unicode string. If the
  driver specified by This has a user readable name in the language specified by
  Language, then a pointer to the controller name is returned in ControllerName,
  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
  managing the controller specified by ControllerHandle and ChildHandle,
  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
  support the language specified by Language, then EFI_UNSUPPORTED is returned.

  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
                                EFI_COMPONENT_NAME_PROTOCOL instance.

  @param  ControllerHandle[in]  The handle of a controller that the driver
                                specified by This is managing.  This handle
                                specifies the controller whose name is to be
                                returned.

  @param  ChildHandle[in]       The handle of the child controller to retrieve
                                the name of.  This is an optional parameter that
                                may be NULL.  It will be NULL for device
                                drivers.  It will also be NULL for a bus drivers
                                that wish to retrieve the name of the bus
                                controller.  It will not be NULL for a bus
                                driver that wishes to retrieve the name of a
                                child controller.

  @param  Language[in]          A pointer to a Null-terminated ASCII string
                                array indicating the language.  This is the
                                language of the driver name that the caller is
                                requesting, and it must match one of the
                                languages specified in SupportedLanguages. The
                                number of languages supported by a driver is up
                                to the driver writer. Language is specified in
                                RFC 4646 or ISO 639-2 language code format.

  @param  ControllerName[out]   A pointer to the Unicode string to return.
                                This Unicode string is the name of the
                                controller specified by ControllerHandle and
                                ChildHandle in the language specified by
                                Language from the point of view of the driver
                                specified by This.

  @retval EFI_SUCCESS           The Unicode string for the user readable name in
                                the language specified by Language for the
                                driver specified by This was returned in
                                DriverName.

  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.

  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
                                EFI_HANDLE.

  @retval EFI_INVALID_PARAMETER Language is NULL.

  @retval EFI_INVALID_PARAMETER ControllerName is NULL.

  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
                                managing the controller specified by
                                ControllerHandle and ChildHandle.

  @retval EFI_UNSUPPORTED       The driver specified by This does not support
                                the language specified by Language.

**/
EFI_STATUS
EFIAPI
I2cHostComponentNameGetControllerName (
  IN  EFI_COMPONENT_NAME2_PROTOCOL                    *This,
  IN  EFI_HANDLE                                      ControllerHandle,
  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
  IN  CHAR8                                           *Language,
  OUT CHAR16                                          **ControllerName
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Tests to see if this driver supports a given controller. If a child device is provided,
  it further tests to see if this driver supports creating a handle for the specified child device.

  This function checks to see if the driver specified by This supports the device specified by
  ControllerHandle. Drivers will typically use the device path attached to
  ControllerHandle and/or the services from the bus I/O abstraction attached to
  ControllerHandle to determine if the driver supports ControllerHandle. This function
  may be called many times during platform initialization. In order to reduce boot times, the tests
  performed by this function must be very small, and take as little time as possible to execute. This
  function must not change the state of any hardware devices, and this function must be aware that the
  device specified by ControllerHandle may already be managed by the same driver or a
  different driver. This function must match its calls to AllocatePages() with FreePages(),
  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
  Since ControllerHandle may have been previously started by the same driver, if a protocol is
  already in the opened state, then it must not be closed with CloseProtocol(). This is required
  to guarantee the state of ControllerHandle is not modified by this function.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to test. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For bus drivers, if this parameter is not NULL, then
                                   the bus driver must determine if the bus controller specified
                                   by ControllerHandle and the child controller specified
                                   by RemainingDevicePath are both supported by this
                                   bus driver.

  @retval EFI_SUCCESS              The device specified by ControllerHandle and
                                   RemainingDevicePath is supported by the driver specified by This.
  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
                                   RemainingDevicePath is already being managed by the driver
                                   specified by This.
  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
                                   RemainingDevicePath is already being managed by a different
                                   driver or an application that requires exclusive access.
                                   Currently not implemented.
  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
                                   RemainingDevicePath is not supported by the driver specified by This.
**/
EFI_STATUS
EFIAPI
I2cHostDriverSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_I2C_MASTER_PROTOCOL                       *I2cMaster;
  EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL *I2cBusConfigurationManagement;
  EFI_STATUS                                    Status;

  //
  //  Locate I2C Bus Configuration Management Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiI2cBusConfigurationManagementProtocolGuid,
                  (VOID **)&I2cBusConfigurationManagement,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close the protocol because we don't use it here
  //
  gBS->CloseProtocol (
                  Controller,
                  &gEfiI2cBusConfigurationManagementProtocolGuid,
                  This->DriverBindingHandle,
                  Controller
                  );

  //
  //  Locate I2C Master Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiI2cMasterProtocolGuid,
                  (VOID **)&I2cMaster,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Starts a device controller or a bus controller.

  The Start() function is designed to be invoked from the EFI boot service ConnectController().
  As a result, much of the error checking on the parameters to Start() has been moved into this
  common boot service. It is legal to call Start() from other locations,
  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
     EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver specified by This must
     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to start. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For a bus driver, if this parameter is NULL, then handles
                                   for all the children of Controller are created by this driver.
                                   If this parameter is not NULL and the first Device Path Node is
                                   not the End of Device Path Node, then only the handle for the
                                   child device specified by the first Device Path Node of
                                   RemainingDevicePath is created by this driver.
                                   If the first Device Path Node of RemainingDevicePath is
                                   the End of Device Path Node, no child handle is created by this
                                   driver.

  @retval EFI_SUCCESS              The device was started.
  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
  @retval Others                   The driver failed to start the device.

**/
EFI_STATUS
EFIAPI
I2cHostDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL        *This,
  IN EFI_HANDLE                         Controller,
  IN EFI_DEVICE_PATH_PROTOCOL           *RemainingDevicePath
  )
{
  EFI_STATUS                                          Status;
  EFI_I2C_MASTER_PROTOCOL                             *I2cMaster;
  EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL       *I2cBusConfigurationManagement;
  I2C_HOST_CONTEXT                                    *I2cHostContext;

  I2cMaster                     = NULL;
  I2cHostContext                = NULL;
  I2cBusConfigurationManagement = NULL;

  //
  // Locate I2C Bus Configuration Management Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiI2cBusConfigurationManagementProtocolGuid,
                  (VOID **)&I2cBusConfigurationManagement,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "I2cHost: Open I2C bus configuration error, Status = %r\n", Status));
    return Status;
  }

  //
  // Locate I2C Master Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiI2cMasterProtocolGuid,
                  (VOID **)&I2cMaster,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "I2cHost: Open I2C master error, Status = %r\n", Status));
    goto Exit;
  }

  //
  // Allocate the I2C Host Context structure
  //
  I2cHostContext = AllocateZeroPool (sizeof (I2C_HOST_CONTEXT));
  if (I2cHostContext == NULL) {
    DEBUG ((EFI_D_ERROR, "I2cHost: there is no enough memory to allocate.\n"));
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  //
  // Initialize the context structure for the current I2C Controller
  //
  I2cHostContext->Signature                     = I2C_HOST_SIGNATURE;
  I2cHostContext->I2cMaster                     = I2cMaster;
  I2cHostContext->I2cBusConfigurationManagement = I2cBusConfigurationManagement;
  I2cHostContext->I2cBusConfiguration           = (UINTN) -1;
  InitializeListHead(&I2cHostContext->RequestList);

  //
  // Reset the controller
  //
  Status = I2cMaster->Reset (I2cMaster);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "I2cHost: I2C controller reset failed!\n"));
    goto Exit;
  }

  //
  // Create the I2C transaction complete event
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_I2C_SYNC,
                  I2cHostRequestCompleteEvent,
                  I2cHostContext,
                  &I2cHostContext->I2cEvent
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "I2cHost: create complete event error, Status = %r\n", Status));
    goto Exit;
  }

  //
  // Get the bus management event
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_I2C_SYNC,
                  I2cHostI2cBusConfigurationAvailable,
                  I2cHostContext,
                  &I2cHostContext->I2cBusConfigurationEvent
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "I2cHost: create bus available event error, Status = %r\n", Status));
    goto Exit;
  }

  //
  // Build the I2C host protocol for the current I2C controller
  //
  I2cHostContext->I2cHost.QueueRequest              = I2cHostQueueRequest;
  I2cHostContext->I2cHost.I2cControllerCapabilities = I2cMaster->I2cControllerCapabilities;

  //
  //  Install the driver protocol
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiI2cHostProtocolGuid,
                  &I2cHostContext->I2cHost,
                  NULL
                  );
Exit:
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "I2cHost: Start() function failed, Status = %r\n", Status));
    if (I2cBusConfigurationManagement != NULL) {
      gBS->CloseProtocol (
                      Controller,
                      &gEfiI2cBusConfigurationManagementProtocolGuid,
                      This->DriverBindingHandle,
                      Controller
                      );
    }

    if ((I2cHostContext != NULL) && (I2cHostContext->I2cEvent != NULL)) {
      gBS->CloseEvent (I2cHostContext->I2cEvent);
      I2cHostContext->I2cEvent = NULL;
    }

    if ((I2cHostContext != NULL) && (I2cHostContext->I2cBusConfigurationEvent != NULL)) {
      gBS->CloseEvent (I2cHostContext->I2cBusConfigurationEvent);
      I2cHostContext->I2cBusConfigurationEvent = NULL;
    }

    //
    //  Release the context structure upon failure
    //
    if (I2cHostContext != NULL) {
      FreePool (I2cHostContext);
    }
  }

  //
  //  Return the operation status.
  //
  return Status;
}

/**
  Stops a device controller or a bus controller.

  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
  As a result, much of the error checking on the parameters to Stop() has been moved
  into this common boot service. It is legal to call Stop() from other locations,
  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
     same driver's Start() function.
  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
     Start() function, and the Start() function must have called OpenProtocol() on
     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.

  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
                                support a bus specific I/O protocol for the driver
                                to use to stop the device.
  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
                                if NumberOfChildren is 0.

  @retval EFI_SUCCESS           The device was stopped.
  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.

**/
EFI_STATUS
EFIAPI
I2cHostDriverStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL       *This,
  IN  EFI_HANDLE                        Controller,
  IN  UINTN                             NumberOfChildren,
  IN  EFI_HANDLE                        *ChildHandleBuffer
  )
{
  EFI_STATUS                  Status;
  I2C_HOST_CONTEXT            *I2cHostContext;
  EFI_I2C_HOST_PROTOCOL       *I2cHost;
  EFI_TPL                     TplPrevious;

  TplPrevious = EfiGetCurrentTpl ();
  if (TplPrevious > TPL_I2C_SYNC) {
    DEBUG ((EFI_D_ERROR, "I2cHost: TPL %d is too high in Stop.\n", TplPrevious));
    return EFI_DEVICE_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiI2cHostProtocolGuid,
                  (VOID **) &I2cHost,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  I2cHostContext = I2C_HOST_CONTEXT_FROM_PROTOCOL (I2cHost);

  //
  // Raise TPL for critical section
  //
  TplPrevious = gBS->RaiseTPL (TPL_I2C_SYNC);

  //
  // If there is pending request or pending bus configuration, do not stop
  //
  Status = EFI_DEVICE_ERROR;
  if (( !I2cHostContext->I2cBusConfigurationManagementPending )
    && IsListEmpty (&I2cHostContext->RequestList)) {

    //
    //  Remove the I2C host protocol
    //
    Status = gBS->UninstallMultipleProtocolInterfaces (
                    Controller,
                    &gEfiI2cHostProtocolGuid,
                    I2cHost,
                    NULL
                    );
  }

  //
  // Leave critical section
  //
  gBS->RestoreTPL (TplPrevious);
  if (!EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           Controller,
           &gEfiI2cBusConfigurationManagementProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );

    //
    // Release I2c Host resources
    //
    if (I2cHostContext->I2cBusConfigurationEvent != NULL) {
      gBS->CloseEvent (I2cHostContext->I2cBusConfigurationEvent);
      I2cHostContext->I2cBusConfigurationEvent = NULL;
    }

    if (I2cHostContext->I2cEvent != NULL) {
      gBS->CloseEvent (I2cHostContext->I2cEvent);
      I2cHostContext->I2cEvent = NULL;
    }

    FreePool (I2cHostContext);
  }

  //
  //  Return the stop status
  //
  return Status;
}

/**
  Handle the I2C bus configuration available event

  This routine is called at TPL_I2C_SYNC.

  @param[in] Event    Address of an EFI_EVENT handle
  @param[in] Context  Address of an I2C_HOST_CONTEXT structure

**/
VOID
EFIAPI
I2cHostI2cBusConfigurationAvailable (
  IN EFI_EVENT Event,
  IN VOID *Context
  )
{
  I2C_HOST_CONTEXT            *I2cHostContext;
  EFI_I2C_MASTER_PROTOCOL     *I2cMaster;
  I2C_REQUEST                 *I2cRequest;
  LIST_ENTRY                  *EntryHeader;
  LIST_ENTRY                  *Entry;
  EFI_STATUS                  Status;

  //
  // Mark this I2C bus configuration management operation as complete
  //
  I2cHostContext = (I2C_HOST_CONTEXT *)Context;
  I2cMaster      = I2cHostContext->I2cMaster;
  ASSERT (I2cMaster != NULL);
  //
  // Clear flag to indicate I2C bus configuration is finished
  //
  I2cHostContext->I2cBusConfigurationManagementPending = FALSE;

  //
  //  Validate the completion status
  //
  if (EFI_ERROR (I2cHostContext->Status)) {
    //
    // Setting I2C bus configuration failed before
    //
    I2cHostRequestComplete (I2cHostContext, I2cHostContext->Status);

    //
    // Unknown I2C bus configuration
    // Force next operation to enable the I2C bus configuration
    //
    I2cHostContext->I2cBusConfiguration = (UINTN) -1;

    //
    // Do not continue current I2C request
    //
    return;
  }

  //
  // Get the first request in the link with FIFO order
  //
  EntryHeader = &I2cHostContext->RequestList;
  Entry = GetFirstNode (EntryHeader);
  I2cRequest = I2C_REQUEST_FROM_ENTRY (Entry);

  //
  // Update the I2C bus configuration of the current I2C request
  //
  I2cHostContext->I2cBusConfiguration = I2cRequest->I2cBusConfiguration;

  //
  // Start an I2C operation on the host, the status is returned by I2cHostContext->Status
  //
  Status = I2cMaster->StartRequest (
                        I2cMaster,
                        I2cRequest->SlaveAddress,
                        I2cRequest->RequestPacket,
                        I2cHostContext->I2cEvent,
                        &I2cHostContext->Status
                        );

  if (EFI_ERROR (Status)) {
    DEBUG((DEBUG_ERROR, "I2cHostI2cBusConfigurationAvailable: Error starting I2C operation, %r\n", Status));
  }
}

/**
  Complete the current request

  This routine is called at TPL_I2C_SYNC.

  @param[in] I2cHostContext  Address of an I2C_HOST_CONTEXT structure.
  @param[in] Status          Status of the I2C operation.

  @return This routine returns the input status value.

**/
EFI_STATUS
I2cHostRequestComplete (
  I2C_HOST_CONTEXT *I2cHostContext,
  EFI_STATUS       Status
  )
{
  I2C_REQUEST *I2cRequest;
  LIST_ENTRY  *EntryHeader;
  LIST_ENTRY  *Entry;

  //
  // Remove the current I2C request from the list
  //
  EntryHeader = &I2cHostContext->RequestList;
  Entry = GetFirstNode (EntryHeader);
  I2cRequest = I2C_REQUEST_FROM_ENTRY (Entry);

  //
  // Save the status for QueueRequest
  //
  if ( NULL != I2cRequest->Status ) {
    *I2cRequest->Status = Status;
  }

  //
  //  Notify the user of the I2C request completion
  //
  if ( NULL != I2cRequest->Event ) {
    gBS->SignalEvent (I2cRequest->Event);
  }

  //
  // Done with this request, remove the current request from list
  //
  RemoveEntryList (&I2cRequest->Link);
  FreePool (I2cRequest->RequestPacket);
  FreePool (I2cRequest);

  //
  // If there is more I2C request, start next one
  //
  if(!IsListEmpty (EntryHeader)) {
    I2cHostRequestEnable (I2cHostContext);
  }

  return Status;
}

/**
  Handle the bus available event

  This routine is called at TPL_I2C_SYNC.

  @param[in] Event    Address of an EFI_EVENT handle
  @param[in] Context  Address of an I2C_HOST_CONTEXT structure

**/
VOID
EFIAPI
I2cHostRequestCompleteEvent (
  IN EFI_EVENT Event,
  IN VOID *Context
  )
{
  I2C_HOST_CONTEXT *I2cHostContext;

  //
  // Handle the completion event
  //
  I2cHostContext = (I2C_HOST_CONTEXT *)Context;
  I2cHostRequestComplete (I2cHostContext, I2cHostContext->Status);
}

/**
  Enable access to the I2C bus configuration

  @param[in] I2cHostContext     Address of an I2C_HOST_CONTEXT structure

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval EFI_ABORTED           The request did not complete because the driver
                                was shutdown.
  @retval EFI_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size is too large.
  @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_NO_MAPPING        Invalid I2cBusConfiguration value
  @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_NOT_FOUND         I2C slave address exceeds maximum address
  @retval EFI_NOT_READY         I2C bus is busy or operation pending, wait for
                                the event and then read status.
  @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
I2cHostRequestEnable (
  I2C_HOST_CONTEXT *I2cHostContext
  )
{
  UINTN                                                 I2cBusConfiguration;
  CONST EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL   *I2cBusConfigurationManagement;
  I2C_REQUEST                                           *I2cRequest;
  EFI_STATUS                                            Status;
  EFI_TPL                                               TplPrevious;
  LIST_ENTRY                                            *EntryHeader;
  LIST_ENTRY                                            *Entry;

  //
  //  Assume pending request
  //
  Status = EFI_NOT_READY;

  I2cBusConfigurationManagement = I2cHostContext->I2cBusConfigurationManagement;

  //
  //  Validate the I2c bus configuration
  //
  EntryHeader = &I2cHostContext->RequestList;
  Entry       = GetFirstNode (EntryHeader);
  I2cRequest = I2C_REQUEST_FROM_ENTRY (Entry);

  I2cBusConfiguration = I2cRequest->I2cBusConfiguration;

  if (I2cHostContext->I2cBusConfiguration != I2cBusConfiguration ) {
    //
    // Set flag to indicate I2C bus configuration is in progress
    //
    I2cHostContext->I2cBusConfigurationManagementPending = TRUE;
    //
    //  Update bus configuration for this device's requesting bus configuration
    //
    Status = I2cBusConfigurationManagement->EnableI2cBusConfiguration (
                I2cBusConfigurationManagement,
                I2cBusConfiguration,
                I2cHostContext->I2cBusConfigurationEvent,
                &I2cHostContext->Status
                );
  } else {
    //
    //  I2C bus configuration is same, no need change configuration and start I2c transaction directly
    //
    TplPrevious = gBS->RaiseTPL ( TPL_I2C_SYNC );

    //
    //  Same I2C bus configuration
    //
    I2cHostContext->Status = EFI_SUCCESS;
    I2cHostI2cBusConfigurationAvailable (I2cHostContext->I2cBusConfigurationEvent, I2cHostContext);

    //
    //  Release the thread synchronization
    //
    gBS->RestoreTPL ( TplPrevious );
  }
  return Status;
}

/**
  Queue an I2C operation for execution on the I2C 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 consumers of this API are the I2C bus driver and
  on rare occasions the I2C test application.  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 layer uses the concept of I2C bus configurations to describe
  the I2C bus.  An I2C bus configuration is defined as a unique
  setting of the multiplexers and switches in the I2C bus which
  enable access to one or more I2C devices.  When using a switch
  to divide a bus, due to speed differences, the I2C platform layer
  would define an I2C bus configuration for the I2C devices on each
  side of the switch.  When using a multiplexer, the I2C platform
  layer defines an I2C bus configuration for each of the selector
  values required to control the multiplexer.  See Figure 1 in the
  <a href="http://www.nxp.com/documents/user_manual/UM10204.pdf">I<sup>2</sup>C
  Specification</a> for a complex I2C bus configuration.

  The I2C host driver processes all operations in FIFO order.  Prior to
  performing the operation, the I2C host driver calls the I2C platform
  driver to reconfigure the switches and multiplexers in the I2C bus
  enabling access to the specified I2C device.  The I2C platform driver
  also selects the maximum bus speed for the device.  After the I2C bus
  is configured, the I2C host driver calls the I2C port driver to
  initialize the I2C controller and start the I2C operation.

  @param[in] This             Address of an EFI_I2C_HOST_PROTOCOL instance.
  @param[in] I2cBusConfiguration  I2C bus configuration to access the I2C
                                  device.
  @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_BAD_BUFFER_SIZE   The WriteBytes or ReadBytes buffer size is too large.
  @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_NO_MAPPING        Invalid I2cBusConfiguration value
  @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_NOT_FOUND         I2C slave address 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_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
I2cHostQueueRequest (
  IN CONST EFI_I2C_HOST_PROTOCOL  *This,
  IN UINTN                        I2cBusConfiguration,
  IN UINTN                        SlaveAddress,
  IN EFI_EVENT                    Event            OPTIONAL,
  IN EFI_I2C_REQUEST_PACKET       *RequestPacket,
  OUT EFI_STATUS                  *I2cStatus       OPTIONAL
  )
{
  EFI_STATUS        Status;
  EFI_EVENT         SyncEvent;
  EFI_TPL           TplPrevious;
  I2C_REQUEST       *I2cRequest;
  I2C_HOST_CONTEXT  *I2cHostContext;
  BOOLEAN           FirstRequest;
  UINTN             RequestPacketSize;
  UINTN             StartBit;

  SyncEvent    = NULL;
  FirstRequest = FALSE;
  Status       = EFI_SUCCESS;

  if (RequestPacket == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if ((SlaveAddress & I2C_ADDRESSING_10_BIT) != 0) {
    //
    // 10-bit address, bits 0-9 are used for 10-bit I2C slave addresses,
    // bits 10-30 are reserved bits and must be zero
    //
    StartBit = 10;
  } else {
    //
    // 7-bit address, Bits 0-6 are used for 7-bit I2C slave addresses,
    // bits 7-30 are reserved bits and must be zero
    //
    StartBit = 7;
  }

  if (BitFieldRead32 ((UINT32)SlaveAddress, StartBit, 30) != 0) {
    //
    // Reserved bit set in the SlaveAddress parameter
    //
    return EFI_NOT_FOUND;
  }

  I2cHostContext = I2C_HOST_CONTEXT_FROM_PROTOCOL (This);

  if (Event == NULL) {
    //
    // For synchronous transaction, register an event used to wait for finishing synchronous transaction
    //
    Status = gBS->CreateEvent (
                0,
                TPL_I2C_SYNC,
                NULL,
                NULL,
                &SyncEvent
                );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // TPL should be at or below TPL_NOTIFY.
  // For synchronous requests this routine must be called at or below TPL_CALLBACK.
  //
  TplPrevious = EfiGetCurrentTpl ();
  if ((TplPrevious > TPL_I2C_SYNC) || ((Event == NULL) && (TplPrevious > TPL_CALLBACK))) {
    DEBUG ((EFI_D_ERROR, "ERROR - TPL %d is too high!\n", TplPrevious));
    return EFI_INVALID_PARAMETER;
  }

  //
  // Allocate the request structure
  //
  I2cRequest = AllocateZeroPool (sizeof (I2C_REQUEST));
  if (I2cRequest == NULL) {
    DEBUG ((EFI_D_ERROR, "WARNING - Failed to allocate I2C_REQUEST!\n"));
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Initialize the request
  //
  I2cRequest->Signature           = I2C_REQUEST_SIGNATURE;
  I2cRequest->I2cBusConfiguration = I2cBusConfiguration;
  I2cRequest->SlaveAddress        = SlaveAddress;
  I2cRequest->Event               = (Event == NULL) ? SyncEvent : Event;
  I2cRequest->Status              = I2cStatus;

  //
  // Copy request packet into private buffer, as RequestPacket may be freed during asynchronous transaction
  //
  RequestPacketSize = sizeof (UINTN) + RequestPacket->OperationCount * sizeof (EFI_I2C_OPERATION);
  I2cRequest->RequestPacket = AllocateZeroPool (RequestPacketSize);
  ASSERT (I2cRequest->RequestPacket != NULL);
  CopyMem (I2cRequest->RequestPacket, RequestPacket, RequestPacketSize);

  //
  // Synchronize with the other threads
  //
  gBS->RaiseTPL ( TPL_I2C_SYNC );

  FirstRequest = IsListEmpty (&I2cHostContext->RequestList);

  //
  // Insert new I2C request in the list
  //
  InsertTailList (&I2cHostContext->RequestList, &I2cRequest->Link);

  //
  // Release the thread synchronization
  //
  gBS->RestoreTPL (TplPrevious);

  if (FirstRequest) {
    //
    // Start the first I2C request, then the subsequent of I2C request will continue
    //
    Status = I2cHostRequestEnable (I2cHostContext);
  }

  if (Event != NULL) {
    //
    // For asynchronous, return EFI_SUCCESS indicating that the asynchronously I2C transaction was queued.
    // No real I2C operation status in I2cStatus
    //
    return EFI_SUCCESS;
  }

  //
  // For synchronous transaction, wait for the operation completion
  //
  do {
    Status = gBS->CheckEvent (SyncEvent);
  } while (Status == EFI_NOT_READY);

  //
  // Get the I2C operation status
  //
  Status = I2cHostContext->Status;

  //
  // Return the I2C operation status
  //
  if (I2cStatus != NULL) {
    *I2cStatus = Status;
  }

  //
  // Close the event if necessary
  //
  if (SyncEvent != NULL) {
    gBS->CloseEvent (SyncEvent);
  }

  return Status;
}

/**
  The user Entry Point for I2C host module. The user code starts with this function.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
  @param[in] SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
InitializeI2cHost(
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS              Status;

  //
  // Install driver model protocol(s).
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gI2cHostDriverBinding,
             ImageHandle,
             &gI2cHostComponentName,
             &gI2cHostComponentName2
             );
  ASSERT_EFI_ERROR (Status);
  return Status;
}

/**
  This is the unload handle for I2C host module.

  Disconnect the driver specified by ImageHandle from all the devices in the handle database.
  Uninstall all the protocols installed in the driver entry point.

  @param[in] ImageHandle           The drivers' driver image.

  @retval    EFI_SUCCESS           The image is unloaded.
  @retval    Others                Failed to unload the image.

**/
EFI_STATUS
EFIAPI
I2cHostUnload (
  IN EFI_HANDLE             ImageHandle
  )
{
  EFI_STATUS                        Status;
  EFI_HANDLE                        *DeviceHandleBuffer;
  UINTN                             DeviceHandleCount;
  UINTN                             Index;
  EFI_COMPONENT_NAME_PROTOCOL       *ComponentName;
  EFI_COMPONENT_NAME2_PROTOCOL      *ComponentName2;

  //
  // Get the list of all I2C Controller handles in the handle database.
  // If there is an error getting the list, then the unload
  // operation fails.
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiI2cHostProtocolGuid,
                  NULL,
                  &DeviceHandleCount,
                  &DeviceHandleBuffer
                  );

  if (!EFI_ERROR (Status)) {
    //
    // Disconnect the driver specified by ImageHandle from all
    // the devices in the handle database.
    //
    for (Index = 0; Index < DeviceHandleCount; Index++) {
      Status = gBS->DisconnectController (
                      DeviceHandleBuffer[Index],
                      ImageHandle,
                      NULL
                      );
      if (EFI_ERROR (Status)) {
        goto Done;
      }
    }
  }

  //
  // Uninstall all the protocols installed in the driver entry point
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  gI2cHostDriverBinding.DriverBindingHandle,
                  &gEfiDriverBindingProtocolGuid,
                  &gI2cHostDriverBinding,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Note we have to one by one uninstall the following protocols.
  // It's because some of them are optionally installed based on
  // the following PCD settings.
  //   gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable
  //   gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable
  //   gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable
  //   gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable
  //
  Status = gBS->HandleProtocol (
                  gI2cHostDriverBinding.DriverBindingHandle,
                  &gEfiComponentNameProtocolGuid,
                  (VOID **) &ComponentName
                  );
  if (!EFI_ERROR (Status)) {
    gBS->UninstallProtocolInterface (
           gI2cHostDriverBinding.DriverBindingHandle,
           &gEfiComponentNameProtocolGuid,
           ComponentName
           );
  }

  Status = gBS->HandleProtocol (
                  gI2cHostDriverBinding.DriverBindingHandle,
                  &gEfiComponentName2ProtocolGuid,
                  (VOID **) &ComponentName2
                  );
  if (!EFI_ERROR (Status)) {
    gBS->UninstallProtocolInterface (
           gI2cHostDriverBinding.DriverBindingHandle,
           &gEfiComponentName2ProtocolGuid,
           ComponentName2
           );
  }

  Status = EFI_SUCCESS;

Done:
  //
  // Free the buffer containing the list of handles from the handle database
  //
  if (DeviceHandleBuffer != NULL) {
    gBS->FreePool (DeviceHandleBuffer);
  }

  return Status;
}
