11e57a46299244793beb27e74be171d1540606999oliviermartin/** @file
21e57a46299244793beb27e74be171d1540606999oliviermartin
31e57a46299244793beb27e74be171d1540606999oliviermartin  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
43402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
51e57a46299244793beb27e74be171d1540606999oliviermartin  This program and the accompanying materials
61e57a46299244793beb27e74be171d1540606999oliviermartin  are licensed and made available under the terms and conditions of the BSD License
71e57a46299244793beb27e74be171d1540606999oliviermartin  which accompanies this distribution.  The full text of the license may be found at
81e57a46299244793beb27e74be171d1540606999oliviermartin  http://opensource.org/licenses/bsd-license.php
91e57a46299244793beb27e74be171d1540606999oliviermartin
101e57a46299244793beb27e74be171d1540606999oliviermartin  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
111e57a46299244793beb27e74be171d1540606999oliviermartin  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
121e57a46299244793beb27e74be171d1540606999oliviermartin
131e57a46299244793beb27e74be171d1540606999oliviermartin**/
141e57a46299244793beb27e74be171d1540606999oliviermartin
151e57a46299244793beb27e74be171d1540606999oliviermartin#include <Uefi.h>
161e57a46299244793beb27e74be171d1540606999oliviermartin
171e57a46299244793beb27e74be171d1540606999oliviermartin#include <TPS65950.h>
181e57a46299244793beb27e74be171d1540606999oliviermartin
191e57a46299244793beb27e74be171d1540606999oliviermartin#include <Library/BaseMemoryLib.h>
201e57a46299244793beb27e74be171d1540606999oliviermartin#include <Library/DebugLib.h>
211e57a46299244793beb27e74be171d1540606999oliviermartin#include <Library/MemoryAllocationLib.h>
221e57a46299244793beb27e74be171d1540606999oliviermartin#include <Library/UefiBootServicesTableLib.h>
231e57a46299244793beb27e74be171d1540606999oliviermartin
241e57a46299244793beb27e74be171d1540606999oliviermartin#include <Protocol/EmbeddedExternalDevice.h>
251e57a46299244793beb27e74be171d1540606999oliviermartin#include <Protocol/SmbusHc.h>
261e57a46299244793beb27e74be171d1540606999oliviermartin
271e57a46299244793beb27e74be171d1540606999oliviermartinEFI_SMBUS_HC_PROTOCOL *Smbus;
281e57a46299244793beb27e74be171d1540606999oliviermartin
291e57a46299244793beb27e74be171d1540606999oliviermartinEFI_STATUS
301e57a46299244793beb27e74be171d1540606999oliviermartinRead (
311e57a46299244793beb27e74be171d1540606999oliviermartin  IN  EMBEDDED_EXTERNAL_DEVICE    *This,
321e57a46299244793beb27e74be171d1540606999oliviermartin  IN  UINTN                       Register,
331e57a46299244793beb27e74be171d1540606999oliviermartin  IN  UINTN                       Length,
341e57a46299244793beb27e74be171d1540606999oliviermartin  OUT VOID                        *Buffer
351e57a46299244793beb27e74be171d1540606999oliviermartin  )
361e57a46299244793beb27e74be171d1540606999oliviermartin{
371e57a46299244793beb27e74be171d1540606999oliviermartin  EFI_STATUS               Status;
383402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
391e57a46299244793beb27e74be171d1540606999oliviermartin  UINT8                    DeviceRegister;
401e57a46299244793beb27e74be171d1540606999oliviermartin  UINTN                    DeviceRegisterLength = 1;
411e57a46299244793beb27e74be171d1540606999oliviermartin
421e57a46299244793beb27e74be171d1540606999oliviermartin  SlaveAddress.SmbusDeviceAddress = EXTERNAL_DEVICE_REGISTER_TO_SLAVE_ADDRESS(Register);
431e57a46299244793beb27e74be171d1540606999oliviermartin  DeviceRegister = (UINT8)EXTERNAL_DEVICE_REGISTER_TO_REGISTER(Register);
441e57a46299244793beb27e74be171d1540606999oliviermartin
451e57a46299244793beb27e74be171d1540606999oliviermartin  //Write DeviceRegister.
461e57a46299244793beb27e74be171d1540606999oliviermartin  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusWriteBlock, FALSE, &DeviceRegisterLength, &DeviceRegister);
471e57a46299244793beb27e74be171d1540606999oliviermartin  if (EFI_ERROR(Status)) {
481e57a46299244793beb27e74be171d1540606999oliviermartin    return Status;
491e57a46299244793beb27e74be171d1540606999oliviermartin  }
501e57a46299244793beb27e74be171d1540606999oliviermartin
511e57a46299244793beb27e74be171d1540606999oliviermartin  //Read Data
521e57a46299244793beb27e74be171d1540606999oliviermartin  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusReadBlock, FALSE, &Length, Buffer);
531e57a46299244793beb27e74be171d1540606999oliviermartin  return Status;
541e57a46299244793beb27e74be171d1540606999oliviermartin}
551e57a46299244793beb27e74be171d1540606999oliviermartin
561e57a46299244793beb27e74be171d1540606999oliviermartinEFI_STATUS
571e57a46299244793beb27e74be171d1540606999oliviermartinWrite (
581e57a46299244793beb27e74be171d1540606999oliviermartin  IN EMBEDDED_EXTERNAL_DEVICE   *This,
591e57a46299244793beb27e74be171d1540606999oliviermartin  IN UINTN                      Register,
601e57a46299244793beb27e74be171d1540606999oliviermartin  IN UINTN                      Length,
611e57a46299244793beb27e74be171d1540606999oliviermartin  IN VOID                       *Buffer
621e57a46299244793beb27e74be171d1540606999oliviermartin  )
631e57a46299244793beb27e74be171d1540606999oliviermartin{
641e57a46299244793beb27e74be171d1540606999oliviermartin  EFI_STATUS               Status;
653402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron  EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
661e57a46299244793beb27e74be171d1540606999oliviermartin  UINT8                    DeviceRegister;
671e57a46299244793beb27e74be171d1540606999oliviermartin  UINTN                    DeviceBufferLength = Length + 1;
681e57a46299244793beb27e74be171d1540606999oliviermartin  UINT8                    *DeviceBuffer;
691e57a46299244793beb27e74be171d1540606999oliviermartin
701e57a46299244793beb27e74be171d1540606999oliviermartin  SlaveAddress.SmbusDeviceAddress = EXTERNAL_DEVICE_REGISTER_TO_SLAVE_ADDRESS(Register);
711e57a46299244793beb27e74be171d1540606999oliviermartin  DeviceRegister = (UINT8)EXTERNAL_DEVICE_REGISTER_TO_REGISTER(Register);
721e57a46299244793beb27e74be171d1540606999oliviermartin
731e57a46299244793beb27e74be171d1540606999oliviermartin  //Prepare buffer for writing
741e57a46299244793beb27e74be171d1540606999oliviermartin  DeviceBuffer = (UINT8 *)AllocatePool(DeviceBufferLength);
751e57a46299244793beb27e74be171d1540606999oliviermartin  if (DeviceBuffer == NULL) {
761e57a46299244793beb27e74be171d1540606999oliviermartin    Status = EFI_OUT_OF_RESOURCES;
771e57a46299244793beb27e74be171d1540606999oliviermartin    goto exit;
781e57a46299244793beb27e74be171d1540606999oliviermartin  }
791e57a46299244793beb27e74be171d1540606999oliviermartin
801e57a46299244793beb27e74be171d1540606999oliviermartin  //Set Device register followed by data to write.
811e57a46299244793beb27e74be171d1540606999oliviermartin  DeviceBuffer[0] = DeviceRegister;
821e57a46299244793beb27e74be171d1540606999oliviermartin  CopyMem(&DeviceBuffer[1], Buffer, Length);
831e57a46299244793beb27e74be171d1540606999oliviermartin
841e57a46299244793beb27e74be171d1540606999oliviermartin  //Write Data
851e57a46299244793beb27e74be171d1540606999oliviermartin  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusWriteBlock, FALSE, &DeviceBufferLength, DeviceBuffer);
861e57a46299244793beb27e74be171d1540606999oliviermartin  if (EFI_ERROR(Status)) {
871e57a46299244793beb27e74be171d1540606999oliviermartin    goto exit;
881e57a46299244793beb27e74be171d1540606999oliviermartin  }
891e57a46299244793beb27e74be171d1540606999oliviermartin
901e57a46299244793beb27e74be171d1540606999oliviermartinexit:
911e57a46299244793beb27e74be171d1540606999oliviermartin  if (DeviceBuffer) {
921e57a46299244793beb27e74be171d1540606999oliviermartin    FreePool(DeviceBuffer);
931e57a46299244793beb27e74be171d1540606999oliviermartin  }
941e57a46299244793beb27e74be171d1540606999oliviermartin
951e57a46299244793beb27e74be171d1540606999oliviermartin  return Status;
961e57a46299244793beb27e74be171d1540606999oliviermartin}
971e57a46299244793beb27e74be171d1540606999oliviermartin
981e57a46299244793beb27e74be171d1540606999oliviermartinEMBEDDED_EXTERNAL_DEVICE ExternalDevice = {
991e57a46299244793beb27e74be171d1540606999oliviermartin  Read,
1001e57a46299244793beb27e74be171d1540606999oliviermartin  Write
1011e57a46299244793beb27e74be171d1540606999oliviermartin};
1021e57a46299244793beb27e74be171d1540606999oliviermartin
1031e57a46299244793beb27e74be171d1540606999oliviermartinEFI_STATUS
1041e57a46299244793beb27e74be171d1540606999oliviermartinTPS65950Initialize (
1051e57a46299244793beb27e74be171d1540606999oliviermartin  IN EFI_HANDLE         ImageHandle,
1061e57a46299244793beb27e74be171d1540606999oliviermartin  IN EFI_SYSTEM_TABLE   *SystemTable
1071e57a46299244793beb27e74be171d1540606999oliviermartin  )
1081e57a46299244793beb27e74be171d1540606999oliviermartin{
1091e57a46299244793beb27e74be171d1540606999oliviermartin  EFI_STATUS  Status;
1103402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
1111e57a46299244793beb27e74be171d1540606999oliviermartin  Status = gBS->LocateProtocol(&gEfiSmbusHcProtocolGuid, NULL, (VOID **)&Smbus);
1121e57a46299244793beb27e74be171d1540606999oliviermartin  ASSERT_EFI_ERROR(Status);
1133402aac7d985bf8a9f9d3c639f3fe93609380513Ronald Cron
1141e57a46299244793beb27e74be171d1540606999oliviermartin  Status = gBS->InstallMultipleProtocolInterfaces(&ImageHandle, &gEmbeddedExternalDeviceProtocolGuid, &ExternalDevice, NULL);
1151e57a46299244793beb27e74be171d1540606999oliviermartin  return Status;
1161e57a46299244793beb27e74be171d1540606999oliviermartin}
117