1 /** @file
2 *
3 * Copyright (c) 2017, Linaro. All rights reserved.
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 <Library/BaseLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/DevicePathLib.h>
19 #include <Library/IoLib.h>
20 #include <Library/TimerLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiLib.h>
23 #include <Library/UefiRuntimeServicesTableLib.h>
24 #include <Library/UsbSerialNumberLib.h>
25
26 #include <Protocol/EmbeddedGpio.h>
27 #include <Protocol/PlatformDwMmc.h>
28
29 #include <Hi6220.h>
30
31 #define DETECT_SD_CARD 8 // GPIO 1_0
32
33 DW_MMC_HC_SLOT_CAP
34 DwMmcCapability[2] = {
35 {
36 .Ddr50 = 1,
37 .HighSpeed = 1,
38 .BusWidth = 8,
39 .SlotType = EmbeddedSlot,
40 .CardType = EmmcCardType,
41 .BaseClkFreq = 100000
42 }, {
43 .HighSpeed = 1,
44 .BusWidth = 4,
45 .SlotType = RemovableSlot,
46 .CardType = SdCardType,
47 .Voltage30 = 1,
48 .BaseClkFreq = 100000
49 }
50 };
51
52 EFI_STATUS
53 EFIAPI
HiKeyGetCapability(IN EFI_HANDLE Controller,IN UINT8 Slot,OUT DW_MMC_HC_SLOT_CAP * Capability)54 HiKeyGetCapability (
55 IN EFI_HANDLE Controller,
56 IN UINT8 Slot,
57 OUT DW_MMC_HC_SLOT_CAP *Capability
58 )
59 {
60 if (Capability == NULL) {
61 return EFI_INVALID_PARAMETER;
62 }
63 if (DwMmcCapability[0].Controller == 0) {
64 DwMmcCapability[0].Controller = Controller;
65 CopyMem (Capability, &DwMmcCapability[0], sizeof (DW_MMC_HC_SLOT_CAP));
66 } else if (DwMmcCapability[0].Controller == Controller) {
67 CopyMem (Capability, &DwMmcCapability[0], sizeof (DW_MMC_HC_SLOT_CAP));
68 } else if (DwMmcCapability[1].Controller == 0) {
69 DwMmcCapability[1].Controller = Controller;
70 CopyMem (Capability, &DwMmcCapability[1], sizeof (DW_MMC_HC_SLOT_CAP));
71 } else if (DwMmcCapability[1].Controller == Controller) {
72 CopyMem (Capability, &DwMmcCapability[1], sizeof (DW_MMC_HC_SLOT_CAP));
73 } else {
74 return EFI_INVALID_PARAMETER;
75 }
76 return EFI_SUCCESS;
77 }
78
79 BOOLEAN
80 EFIAPI
HiKeyCardDetect(IN EFI_HANDLE Controller,IN UINT8 Slot)81 HiKeyCardDetect (
82 IN EFI_HANDLE Controller,
83 IN UINT8 Slot
84 )
85 {
86 EFI_STATUS Status;
87 EMBEDDED_GPIO *Gpio;
88 UINTN Value;
89
90 if (DwMmcCapability[0].Controller == Controller) {
91 return TRUE;
92 } else if (DwMmcCapability[1].Controller == Controller) {
93 Status = gBS->LocateProtocol (&gEmbeddedGpioProtocolGuid, NULL, (VOID **)&Gpio);
94 if (EFI_ERROR (Status)) {
95 DEBUG ((DEBUG_ERROR, "Failed to get GPIO protocol: %r\n", Status));
96 return FALSE;
97 }
98 Status = Gpio->Set (Gpio, DETECT_SD_CARD, GPIO_MODE_INPUT);
99 if (EFI_ERROR (Status)) {
100 DEBUG ((DEBUG_ERROR, "Failed to sed GPIO as input mode: %r\n", Status));
101 return FALSE;
102 }
103 Status = Gpio->Get (Gpio, DETECT_SD_CARD, &Value);
104 if (EFI_ERROR (Status)) {
105 DEBUG ((DEBUG_ERROR, "Failed to get GPIO value: %r\n", Status));
106 return FALSE;
107 }
108 if (Value == 0) {
109 return TRUE;
110 }
111 return FALSE;
112 }
113 return FALSE;
114 }
115
116 PLATFORM_DW_MMC_PROTOCOL mDwMmcDevice = {
117 HiKeyGetCapability,
118 HiKeyCardDetect
119 };
120
121 EFI_STATUS
122 EFIAPI
HiKeyMmcEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)123 HiKeyMmcEntryPoint (
124 IN EFI_HANDLE ImageHandle,
125 IN EFI_SYSTEM_TABLE *SystemTable
126 )
127 {
128 EFI_STATUS Status;
129
130 Status = gBS->InstallProtocolInterface (
131 &ImageHandle,
132 &gPlatformDwMmcProtocolGuid,
133 EFI_NATIVE_INTERFACE,
134 &mDwMmcDevice
135 );
136 if (EFI_ERROR (Status)) {
137 return Status;
138 }
139 return Status;
140 }
141