1 /*
2  * Copyright (c) 2020-2023 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "sdio_if.h"
10 #include "hdf_base.h"
11 #include "hdf_log.h"
12 #include "mmc_sdio.h"
13 #include "osal_mem.h"
14 #include "securec.h"
15 
16 #define HDF_LOG_TAG sdio_if_c
17 
SdioDeviceGetFromHandle(DevHandle handle,struct SdioDevice ** sdio)18 static int32_t SdioDeviceGetFromHandle(DevHandle handle, struct SdioDevice **sdio)
19 {
20     struct MmcDevice *mmc = NULL;
21 
22     if (handle == NULL) {
23         HDF_LOGE("SdioDeviceGetFromHandle: handle is null!");
24         return HDF_ERR_INVALID_OBJECT;
25     }
26 
27     if (sdio == NULL) {
28         HDF_LOGE("SdioDeviceGetFromHandle: sdio is null!");
29         return HDF_ERR_INVALID_PARAM;
30     }
31 
32     mmc = MmcCntlrGetDevice((struct MmcCntlr *)handle);
33     if (mmc == NULL) {
34         HDF_LOGE("SdioDeviceGetFromHandle: mmc is null!");
35         return HDF_PLT_ERR_NO_DEV;
36     }
37     if (mmc->type != MMC_DEV_SDIO && mmc->type != MMC_DEV_COMBO) {
38         MmcDevicePut(mmc);
39         return HDF_PLT_ERR_DEV_TYPE;
40     }
41 
42     *sdio = (struct SdioDevice *)mmc;
43     return HDF_SUCCESS;
44 }
45 
SdioOpen(int16_t mmcBusNum,struct SdioFunctionConfig * config)46 DevHandle SdioOpen(int16_t mmcBusNum, struct SdioFunctionConfig *config)
47 {
48     int32_t ret;
49     struct MmcCntlr *cntlr = NULL;
50     struct SdioDevice *sdio = NULL;
51     DevHandle handle = NULL;
52 
53     if (config == NULL) {
54         HDF_LOGE("SdioOpen: config can't be null!");
55         return NULL;
56     }
57 
58     handle = MmcOpen(mmcBusNum);
59     if (handle == NULL) {
60         HDF_LOGE("SdioOpen: SdioGetCntlrByBusNum fail!");
61         return NULL;
62     }
63     cntlr = (struct MmcCntlr *)handle;
64     if (cntlr->ops != NULL && cntlr->ops->rescanSdioDev != NULL) {
65         ret = cntlr->ops->rescanSdioDev(cntlr);
66         if (ret != HDF_SUCCESS) {
67             HDF_LOGE("SdioOpen: sdio rescan fail, ret: %d!", ret);
68             MmcClose(handle);
69             return NULL;
70         }
71     }
72 
73     ret = SdioDeviceGetFromHandle(handle, &sdio);
74     if (ret != HDF_SUCCESS) {
75         HDF_LOGE("SdioOpen: get sdio dev fail, ret: %d!", ret);
76         MmcClose(handle);
77         return NULL;
78     }
79     ret = SdioDeviceFindFunction(sdio, config);
80     MmcDevicePut((struct MmcDevice *)sdio);
81     if (ret != HDF_SUCCESS) {
82         HDF_LOGE("SdioOpen: set function fail, ret: %d!", ret);
83         MmcClose(handle);
84         return NULL;
85     }
86 
87     return (DevHandle)cntlr;
88 }
89 
SdioClose(DevHandle handle)90 void SdioClose(DevHandle handle)
91 {
92     (void)handle;
93 }
94 
SdioReadBytes(DevHandle handle,uint8_t * data,uint32_t addr,uint32_t size)95 int32_t SdioReadBytes(DevHandle handle, uint8_t *data, uint32_t addr, uint32_t size)
96 {
97     int32_t ret;
98     struct SdioDevice *sdio = NULL;
99 
100     ret = SdioDeviceGetFromHandle(handle, &sdio);
101     if (ret != HDF_SUCCESS) {
102         HDF_LOGE("SdioReadBytes: get sdio dev fail, ret: %d!", ret);
103         return ret;
104     }
105     ret = SdioDeviceIncrAddrReadBytes(sdio, data, addr, size);
106     MmcDevicePut((struct MmcDevice *)sdio);
107     return ret;
108 }
109 
SdioWriteBytes(DevHandle handle,uint8_t * data,uint32_t addr,uint32_t size)110 int32_t SdioWriteBytes(DevHandle handle, uint8_t *data, uint32_t addr, uint32_t size)
111 {
112     int32_t ret;
113     struct SdioDevice *sdio = NULL;
114 
115     ret = SdioDeviceGetFromHandle(handle, &sdio);
116     if (ret != HDF_SUCCESS) {
117         HDF_LOGE("SdioWriteBytes: get sdio dev fail, ret: %d!", ret);
118         return ret;
119     }
120     ret = SdioDeviceIncrAddrWriteBytes(sdio, data, addr, size);
121     MmcDevicePut((struct MmcDevice *)sdio);
122     return ret;
123 }
124 
SdioReadBytesFromFixedAddr(DevHandle handle,uint8_t * data,uint32_t addr,uint32_t size,uint32_t scatterLen)125 int32_t SdioReadBytesFromFixedAddr(DevHandle handle, uint8_t *data,
126     uint32_t addr, uint32_t size, uint32_t scatterLen)
127 {
128     int32_t ret;
129     struct SdioDevice *sdio = NULL;
130 
131     ret = SdioDeviceGetFromHandle(handle, &sdio);
132     if (ret != HDF_SUCCESS) {
133         HDF_LOGE("SdioReadBytesFromFixedAddr: get sdio dev fail, ret: %d!", ret);
134         return ret;
135     }
136     ret = SdioDeviceFixedAddrReadBytes(sdio, data, addr, size, scatterLen);
137     MmcDevicePut((struct MmcDevice *)sdio);
138     return ret;
139 }
140 
SdioWriteBytesToFixedAddr(DevHandle handle,uint8_t * data,uint32_t addr,uint32_t size,uint32_t scatterLen)141 int32_t SdioWriteBytesToFixedAddr(DevHandle handle, uint8_t *data,
142     uint32_t addr, uint32_t size, uint32_t scatterLen)
143 {
144     int32_t ret;
145     struct SdioDevice *sdio = NULL;
146 
147     ret = SdioDeviceGetFromHandle(handle, &sdio);
148     if (ret != HDF_SUCCESS) {
149         HDF_LOGE("SdioWriteBytesToFixedAddr: get sdio dev fail, ret: %d!", ret);
150         return ret;
151     }
152     ret = SdioDeviceFixedAddrWriteBytes(sdio, data, addr, size, scatterLen);
153     MmcDevicePut((struct MmcDevice *)sdio);
154     return ret;
155 }
156 
SdioReadBytesFromFunc0(DevHandle handle,uint8_t * data,uint32_t addr,uint32_t size)157 int32_t SdioReadBytesFromFunc0(DevHandle handle, uint8_t *data, uint32_t addr, uint32_t size)
158 {
159     int32_t ret;
160     struct SdioDevice *sdio = NULL;
161 
162     ret = SdioDeviceGetFromHandle(handle, &sdio);
163     if (ret != HDF_SUCCESS) {
164         HDF_LOGE("SdioReadBytesFromFunc0: get sdio dev fail, ret: %d!", ret);
165         return ret;
166     }
167     ret = SdioDeviceFunc0ReadBytes(sdio, data, addr, size);
168     MmcDevicePut((struct MmcDevice *)sdio);
169     return ret;
170 }
171 
SdioWriteBytesToFunc0(DevHandle handle,uint8_t * data,uint32_t addr,uint32_t size)172 int32_t SdioWriteBytesToFunc0(DevHandle handle, uint8_t *data, uint32_t addr, uint32_t size)
173 {
174     int32_t ret;
175     struct SdioDevice *sdio = NULL;
176 
177     ret = SdioDeviceGetFromHandle(handle, &sdio);
178     if (ret != HDF_SUCCESS) {
179         HDF_LOGE("SdioWriteBytesToFunc0: get sdio dev fail, ret: %d!", ret);
180         return ret;
181     }
182     ret = SdioDeviceFunc0WriteBytes(sdio, data, addr, size);
183     MmcDevicePut((struct MmcDevice *)sdio);
184     return ret;
185 }
186 
SdioSetBlockSize(DevHandle handle,uint32_t blockSize)187 int32_t SdioSetBlockSize(DevHandle handle, uint32_t blockSize)
188 {
189     int32_t ret;
190     struct SdioDevice *sdio = NULL;
191 
192     ret = SdioDeviceGetFromHandle(handle, &sdio);
193     if (ret != HDF_SUCCESS) {
194         HDF_LOGE("SdioSetBlockSize: get sdio dev fail, ret: %d!", ret);
195         return ret;
196     }
197     ret = SdioDeviceSetBlockSize(sdio, blockSize);
198     MmcDevicePut((struct MmcDevice *)sdio);
199     return ret;
200 }
201 
SdioGetCommonInfo(DevHandle handle,SdioCommonInfo * info,SdioCommonInfoType infoType)202 int32_t SdioGetCommonInfo(DevHandle handle, SdioCommonInfo *info, SdioCommonInfoType infoType)
203 {
204     int32_t ret;
205     struct SdioDevice *sdio = NULL;
206 
207     ret = SdioDeviceGetFromHandle(handle, &sdio);
208     if (ret != HDF_SUCCESS) {
209         HDF_LOGE("SdioGetCommonInfo: get sdio dev fail, ret: %d!", ret);
210         return ret;
211     }
212     ret = SdioDeviceGetCommonInfo(sdio, info, infoType);
213     MmcDevicePut((struct MmcDevice *)sdio);
214     return ret;
215 }
216 
SdioSetCommonInfo(DevHandle handle,SdioCommonInfo * info,SdioCommonInfoType infoType)217 int32_t SdioSetCommonInfo(DevHandle handle, SdioCommonInfo *info, SdioCommonInfoType infoType)
218 {
219     int32_t ret;
220     struct SdioDevice *sdio = NULL;
221 
222     ret = SdioDeviceGetFromHandle(handle, &sdio);
223     if (ret != HDF_SUCCESS) {
224         HDF_LOGE("SdioSetCommonInfo: get sdio dev fail, ret: %d!", ret);
225         return ret;
226     }
227     ret = SdioDeviceSetCommonInfo(sdio, info, infoType);
228     MmcDevicePut((struct MmcDevice *)sdio);
229     return ret;
230 }
231 
SdioFlushData(DevHandle handle)232 int32_t SdioFlushData(DevHandle handle)
233 {
234     int32_t ret;
235     struct SdioDevice *sdio = NULL;
236 
237     ret = SdioDeviceGetFromHandle(handle, &sdio);
238     if (ret != HDF_SUCCESS) {
239         HDF_LOGE("SdioFlushData: get sdio dev fail, ret: %d!", ret);
240         return ret;
241     }
242     ret = SdioDeviceFlushData(sdio);
243     MmcDevicePut((struct MmcDevice *)sdio);
244     return ret;
245 }
246 
SdioClaimHost(DevHandle handle)247 void SdioClaimHost(DevHandle handle)
248 {
249     int32_t ret;
250     struct SdioDevice *sdio = NULL;
251 
252     ret = SdioDeviceGetFromHandle(handle, &sdio);
253     if (ret != HDF_SUCCESS) {
254         HDF_LOGE("SdioClaimHost: get sdio dev fail, ret: %d!", ret);
255         return;
256     }
257     ret = SdioDeviceClaimHost(sdio);
258     if (ret != HDF_SUCCESS) {
259         HDF_LOGE("SdioClaimHost: claim host fail, ret: %d!", ret);
260     }
261     MmcDevicePut((struct MmcDevice *)sdio);
262 }
263 
SdioReleaseHost(DevHandle handle)264 void SdioReleaseHost(DevHandle handle)
265 {
266     int32_t ret;
267     struct SdioDevice *sdio = NULL;
268 
269     ret = SdioDeviceGetFromHandle(handle, &sdio);
270     if (ret != HDF_SUCCESS) {
271         HDF_LOGE("SdioReleaseHost: get sdio dev fail, ret: %d!", ret);
272         return;
273     }
274     ret = SdioDeviceReleaseHost(sdio);
275     if (ret != HDF_SUCCESS) {
276         HDF_LOGE("SdioReleaseHost: claim host fail, ret: %d!", ret);
277     }
278     MmcDevicePut((struct MmcDevice *)sdio);
279 }
280 
SdioEnableFunc(DevHandle handle)281 int32_t SdioEnableFunc(DevHandle handle)
282 {
283     int32_t ret;
284     struct SdioDevice *sdio = NULL;
285 
286     ret = SdioDeviceGetFromHandle(handle, &sdio);
287     if (ret != HDF_SUCCESS) {
288         HDF_LOGE("SdioEnableFunc: get sdio dev fail, ret: %d!", ret);
289         return ret;
290     }
291     ret = SdioDeviceEnableFunc(sdio);
292     MmcDevicePut((struct MmcDevice *)sdio);
293     return ret;
294 }
295 
SdioDisableFunc(DevHandle handle)296 int32_t SdioDisableFunc(DevHandle handle)
297 {
298     int32_t ret;
299     struct SdioDevice *sdio = NULL;
300 
301     ret = SdioDeviceGetFromHandle(handle, &sdio);
302     if (ret != HDF_SUCCESS) {
303         HDF_LOGE("SdioDisableFunc: get sdio dev fail, ret: %d!", ret);
304         return ret;
305     }
306     ret = SdioDeviceDisableFunc(sdio);
307     MmcDevicePut((struct MmcDevice *)sdio);
308     return ret;
309 }
310 
SdioClaimIrq(DevHandle handle,SdioIrqHandler * irqHandler)311 int32_t SdioClaimIrq(DevHandle handle, SdioIrqHandler *irqHandler)
312 {
313     int32_t ret;
314     struct SdioDevice *sdio = NULL;
315 
316     ret = SdioDeviceGetFromHandle(handle, &sdio);
317     if (ret != HDF_SUCCESS) {
318         HDF_LOGE("SdioClaimIrq: get sdio dev fail, ret: %d!", ret);
319         return ret;
320     }
321     ret = SdioDeviceClaimIrq(sdio, irqHandler);
322     MmcDevicePut((struct MmcDevice *)sdio);
323     return ret;
324 }
325 
SdioReleaseIrq(DevHandle handle)326 int32_t SdioReleaseIrq(DevHandle handle)
327 {
328     int32_t ret;
329     struct SdioDevice *sdio = NULL;
330 
331     ret = SdioDeviceGetFromHandle(handle, &sdio);
332     if (ret != HDF_SUCCESS) {
333         HDF_LOGE("SdioReleaseIrq: get sdio dev fail, ret: %d!", ret);
334         return ret;
335     }
336     ret = SdioDeviceReleaseIrq(sdio);
337     MmcDevicePut((struct MmcDevice *)sdio);
338     return ret;
339 }
340