xref: /device/qemu/drivers/virtio/fakesdio.c (revision d6aed566)
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