1/** @file
2
3  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
4
5  This program and the accompanying materials
6  are licensed and made available under the terms and conditions of the BSD License
7  which accompanies this distribution.  The full text of the license may be found at
8  http://opensource.org/licenses/bsd-license.php
9
10  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13**/
14
15#include <Uefi.h>
16
17#include <TPS65950.h>
18
19#include <Library/BaseMemoryLib.h>
20#include <Library/DebugLib.h>
21#include <Library/MemoryAllocationLib.h>
22#include <Library/UefiBootServicesTableLib.h>
23
24#include <Protocol/EmbeddedExternalDevice.h>
25#include <Protocol/SmbusHc.h>
26
27EFI_SMBUS_HC_PROTOCOL *Smbus;
28
29EFI_STATUS
30Read (
31  IN  EMBEDDED_EXTERNAL_DEVICE    *This,
32  IN  UINTN                       Register,
33  IN  UINTN                       Length,
34  OUT VOID                        *Buffer
35  )
36{
37  EFI_STATUS               Status;
38  EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
39  UINT8                    DeviceRegister;
40  UINTN                    DeviceRegisterLength = 1;
41
42  SlaveAddress.SmbusDeviceAddress = EXTERNAL_DEVICE_REGISTER_TO_SLAVE_ADDRESS(Register);
43  DeviceRegister = (UINT8)EXTERNAL_DEVICE_REGISTER_TO_REGISTER(Register);
44
45  //Write DeviceRegister.
46  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusWriteBlock, FALSE, &DeviceRegisterLength, &DeviceRegister);
47  if (EFI_ERROR(Status)) {
48    return Status;
49  }
50
51  //Read Data
52  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusReadBlock, FALSE, &Length, Buffer);
53  return Status;
54}
55
56EFI_STATUS
57Write (
58  IN EMBEDDED_EXTERNAL_DEVICE   *This,
59  IN UINTN                      Register,
60  IN UINTN                      Length,
61  IN VOID                       *Buffer
62  )
63{
64  EFI_STATUS               Status;
65  EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
66  UINT8                    DeviceRegister;
67  UINTN                    DeviceBufferLength = Length + 1;
68  UINT8                    *DeviceBuffer;
69
70  SlaveAddress.SmbusDeviceAddress = EXTERNAL_DEVICE_REGISTER_TO_SLAVE_ADDRESS(Register);
71  DeviceRegister = (UINT8)EXTERNAL_DEVICE_REGISTER_TO_REGISTER(Register);
72
73  //Prepare buffer for writing
74  DeviceBuffer = (UINT8 *)AllocatePool(DeviceBufferLength);
75  if (DeviceBuffer == NULL) {
76    Status = EFI_OUT_OF_RESOURCES;
77    goto exit;
78  }
79
80  //Set Device register followed by data to write.
81  DeviceBuffer[0] = DeviceRegister;
82  CopyMem(&DeviceBuffer[1], Buffer, Length);
83
84  //Write Data
85  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusWriteBlock, FALSE, &DeviceBufferLength, DeviceBuffer);
86  if (EFI_ERROR(Status)) {
87    goto exit;
88  }
89
90exit:
91  if (DeviceBuffer) {
92    FreePool(DeviceBuffer);
93  }
94
95  return Status;
96}
97
98EMBEDDED_EXTERNAL_DEVICE ExternalDevice = {
99  Read,
100  Write
101};
102
103EFI_STATUS
104TPS65950Initialize (
105  IN EFI_HANDLE         ImageHandle,
106  IN EFI_SYSTEM_TABLE   *SystemTable
107  )
108{
109  EFI_STATUS  Status;
110
111  Status = gBS->LocateProtocol(&gEfiSmbusHcProtocolGuid, NULL, (VOID **)&Smbus);
112  ASSERT_EFI_ERROR(Status);
113
114  Status = gBS->InstallMultipleProtocolInterfaces(&ImageHandle, &gEmbeddedExternalDeviceProtocolGuid, &ExternalDevice, NULL);
115  return Status;
116}
117