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