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