1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "device_resource_if.h" 17#include "mmc_corex.h" 18#include "mmc_sdio.h" 19#include "gpio_core.h" 20 21#define HDF_LOG_TAG sdio_adapter_c 22 23static int32_t FakeSdioSetBlockSize(struct SdioDevice *dev, uint32_t blockSize) 24{ 25 (void)dev; 26 (void)blockSize; 27 return HDF_SUCCESS; 28} 29 30static int32_t FakeSdioGetCommonInfo(struct SdioDevice *dev, SdioCommonInfo *info, uint32_t infoType) 31{ 32 if (info == NULL) { 33 HDF_LOGE("[%s]info is null", __func__); 34 return HDF_ERR_INVALID_PARAM; 35 } 36 if (infoType != SDIO_FUNC_INFO) { 37 HDF_LOGE("[%s]info type %u is not supported", __func__, infoType); 38 return HDF_ERR_NOT_SUPPORT; 39 } 40 41 info->funcInfo.enTimeout = 0; 42 info->funcInfo.funcNum = 1; 43 info->funcInfo.irqCap = 0; 44 info->funcInfo.data = NULL; 45 return HDF_SUCCESS; 46} 47 48static int32_t FakeSdioSetCommonInfo(struct SdioDevice *dev, SdioCommonInfo *info, uint32_t infoType) 49{ 50 (void)dev; 51 if (info == NULL) { 52 HDF_LOGE("[%s]info is null", __func__); 53 return HDF_ERR_INVALID_PARAM; 54 } 55 if (infoType != SDIO_FUNC_INFO) { 56 HDF_LOGE("[%s]info type %u is not supported", __func__, infoType); 57 return HDF_ERR_NOT_SUPPORT; 58 } 59 return HDF_SUCCESS; 60} 61 62static int32_t FakeSdioEnableFunc(struct SdioDevice *dev) 63{ 64 (void)dev; 65 return HDF_SUCCESS; 66} 67 68static int32_t FakeSdioFindFunc(struct SdioDevice *dev, struct SdioFunctionConfig *configData) 69{ 70 if (dev == NULL || configData == NULL) { 71 HDF_LOGE("[%s]dev or configData is NULL", __func__); 72 return HDF_ERR_INVALID_OBJECT; 73 } 74 return HDF_SUCCESS; 75} 76 77static struct SdioDeviceOps g_fakeSdioDeviceOps = { 78 .setBlockSize = FakeSdioSetBlockSize, 79 .getCommonInfo = FakeSdioGetCommonInfo, 80 .setCommonInfo = FakeSdioSetCommonInfo, 81 .enableFunc = FakeSdioEnableFunc, 82 .findFunc = FakeSdioFindFunc, 83}; 84 85static void FakeSdioDeleteCntlr(struct MmcCntlr *cntlr) 86{ 87 if (cntlr == NULL) { 88 return; 89 } 90 if (cntlr->curDev != NULL) { 91 MmcDeviceRemove(cntlr->curDev); 92 OsalMemFree(cntlr->curDev); 93 } 94 MmcCntlrRemove(cntlr); 95 OsalMemFree(cntlr); 96} 97 98static int32_t FakeSdioCntlrParse(struct MmcCntlr *cntlr, struct HdfDeviceObject *obj) 99{ 100 const struct DeviceResourceNode *node = NULL; 101 struct DeviceResourceIface *drsOps = NULL; 102 int32_t ret; 103 104 if (obj == NULL || cntlr == NULL) { 105 HDF_LOGE("[%s]input para is NULL", __func__); 106 return HDF_FAILURE; 107 } 108 109 node = obj->property; 110 if (node == NULL) { 111 HDF_LOGE("[%s]HdfDeviceObject property is NULL", __func__); 112 return HDF_FAILURE; 113 } 114 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 115 if (drsOps == NULL || drsOps->GetUint16 == NULL || drsOps->GetUint32 == NULL) { 116 HDF_LOGE("[%s]get HDF_CONFIG_SOURCE failed", __func__); 117 return HDF_FAILURE; 118 } 119 120 ret = drsOps->GetUint16(node, "hostId", &(cntlr->index), 0); 121 if (ret != HDF_SUCCESS) { 122 HDF_LOGE("[%s]read hostIndex failed: %d", __func__, ret); 123 return ret; 124 } 125 ret = drsOps->GetUint32(node, "devType", &(cntlr->devType), 0); 126 if (ret != HDF_SUCCESS) { 127 HDF_LOGE("[%s]read devType failed: %d", __func__, ret); 128 return ret; 129 } 130 131 return HDF_SUCCESS; 132} 133 134static int32_t FakeSdioRescan(struct MmcCntlr *cntlr) 135{ 136 if (cntlr == NULL) { 137 HDF_LOGE("[%s]cntlr is NULL", __func__); 138 return HDF_ERR_INVALID_OBJECT; 139 } 140 return HDF_SUCCESS; 141} 142 143static struct MmcCntlrOps g_fakeSdioCntlrOps = { 144 .rescanSdioDev = FakeSdioRescan, 145}; 146 147static int32_t FakeSdioBind(struct HdfDeviceObject *obj) 148{ 149 struct MmcCntlr *cntlr = NULL; 150 int32_t ret; 151 152 if (obj == NULL) { 153 HDF_LOGE("[%s]HdfDeviceObject is NULL", __func__); 154 return HDF_ERR_INVALID_OBJECT; 155 } 156 157 cntlr = OsalMemCalloc(sizeof(struct MmcCntlr)); 158 if (cntlr == NULL) { 159 HDF_LOGE("[%s]alloc MmcCntlr failed", __func__); 160 return HDF_ERR_MALLOC_FAIL; 161 } 162 163 cntlr->ops = &g_fakeSdioCntlrOps; 164 cntlr->hdfDevObj = obj; 165 obj->service = &cntlr->service; 166 if ((ret = FakeSdioCntlrParse(cntlr, obj)) != HDF_SUCCESS) { 167 goto ERR_OUT; 168 } 169 170 if ((ret = MmcCntlrAdd(cntlr, false)) != HDF_SUCCESS) { 171 HDF_LOGE("[%s]add MmcCntlr failed: %d", __func__, ret); 172 goto ERR_OUT; 173 } 174 175 if ((ret = MmcCntlrAllocDev(cntlr, (enum MmcDevType)cntlr->devType)) != HDF_SUCCESS) { 176 HDF_LOGE("[%s]alloc dev failed: %d", __func__, ret); 177 goto ERR_OUT; 178 } 179 MmcDeviceAddOps(cntlr->curDev, &g_fakeSdioDeviceOps); 180 181 return HDF_SUCCESS; 182 183ERR_OUT: 184 FakeSdioDeleteCntlr(cntlr); 185 return ret; 186} 187 188static int32_t FakeSdioInit(struct HdfDeviceObject *obj) 189{ 190 (void)obj; 191 return HDF_SUCCESS; 192} 193 194static void FakeSdioRelease(struct HdfDeviceObject *obj) 195{ 196 if (obj == NULL) { 197 return; 198 } 199 FakeSdioDeleteCntlr((struct MmcCntlr *)obj->service); 200} 201 202struct HdfDriverEntry g_fakeSdioEntry = { 203 .moduleVersion = 1, 204 .Bind = FakeSdioBind, 205 .Init = FakeSdioInit, 206 .Release = FakeSdioRelease, 207 .moduleName = "HDF_PLATFORM_SDIO", 208}; 209HDF_INIT(g_fakeSdioEntry); 210 211 212/* 213 * WIFI depends on SDIO & GPIO. HDF defined HdfWlanConfigSDIO interface, 214 * but user must implement it. Also, we add a dummy GPIO controller here. 215 */ 216 217static int32_t FakeGiopDummyOps0(struct GpioCntlr *cntlr, uint16_t local, uint16_t dir) 218{ 219 (void)cntlr; 220 (void)local; 221 (void)dir; 222 return HDF_SUCCESS; 223} 224 225static struct GpioMethod g_fakeGpioOps = { 226 .write = FakeGiopDummyOps0, 227 .setDir = FakeGiopDummyOps0, 228}; 229 230int32_t HdfWlanConfigSDIO(uint8_t busId) 231{ 232 (void)busId; 233 int32_t ret; 234 struct GpioCntlr *cntlr = OsalMemCalloc(sizeof(struct GpioCntlr)); 235 236 if (cntlr == NULL) { 237 HDF_LOGE("[%s]alloc memory failed", __func__); 238 return HDF_ERR_MALLOC_FAIL; 239 } 240 241 cntlr->count = 1; 242 cntlr->ops = &g_fakeGpioOps; 243 if ((ret = GpioCntlrAdd(cntlr)) != HDF_SUCCESS) { 244 OsalMemFree(cntlr); 245 } 246 247 return ret; 248} 249 250