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 
27 EFI_SMBUS_HC_PROTOCOL *Smbus;
28 
29 EFI_STATUS
Read(IN EMBEDDED_EXTERNAL_DEVICE * This,IN UINTN Register,IN UINTN Length,OUT VOID * Buffer)30 Read (
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 
56 EFI_STATUS
Write(IN EMBEDDED_EXTERNAL_DEVICE * This,IN UINTN Register,IN UINTN Length,IN VOID * Buffer)57 Write (
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 
90 exit:
91   if (DeviceBuffer) {
92     FreePool(DeviceBuffer);
93   }
94 
95   return Status;
96 }
97 
98 EMBEDDED_EXTERNAL_DEVICE ExternalDevice = {
99   Read,
100   Write
101 };
102 
103 EFI_STATUS
TPS65950Initialize(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)104 TPS65950Initialize (
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