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