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