1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
6 *******************************************************************************/
7 #define _SDIO_OPS_LINUX_C_
10 #include <rtw_debug.h>
12 static bool rtw_sdio_claim_host_needed(struct sdio_func *func)
14 struct dvobj_priv *dvobj = sdio_get_drvdata(func);
15 struct sdio_data *sdio_data = &dvobj->intf_data;
17 if (sdio_data->sys_sdio_irq_thd && sdio_data->sys_sdio_irq_thd == current)
22 inline void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, void *thd_hdl)
24 struct sdio_data *sdio_data = &dvobj->intf_data;
26 sdio_data->sys_sdio_irq_thd = thd_hdl;
29 u8 sd_f0_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
31 struct adapter *padapter;
32 struct dvobj_priv *psdiodev;
33 struct sdio_data *psdio;
36 struct sdio_func *func;
39 padapter = pintfhdl->padapter;
40 psdiodev = pintfhdl->pintf_dev;
41 psdio = &psdiodev->intf_data;
43 if (padapter->bSurpriseRemoved) {
44 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
49 claim_needed = rtw_sdio_claim_host_needed(func);
52 sdio_claim_host(func);
53 v = sdio_f0_readb(func, addr, err);
55 sdio_release_host(func);
57 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, *err, addr);
66 s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
68 struct adapter *padapter;
69 struct dvobj_priv *psdiodev;
70 struct sdio_data *psdio;
73 struct sdio_func *func;
75 padapter = pintfhdl->padapter;
76 psdiodev = pintfhdl->pintf_dev;
77 psdio = &psdiodev->intf_data;
79 if (padapter->bSurpriseRemoved) {
80 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
86 for (i = 0; i < cnt; i++) {
87 pdata[i] = sdio_readb(func, addr + i, &err);
89 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr + i);
101 s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
103 struct adapter *padapter;
104 struct dvobj_priv *psdiodev;
105 struct sdio_data *psdio;
108 struct sdio_func *func;
111 padapter = pintfhdl->padapter;
112 psdiodev = pintfhdl->pintf_dev;
113 psdio = &psdiodev->intf_data;
115 if (padapter->bSurpriseRemoved) {
116 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
121 claim_needed = rtw_sdio_claim_host_needed(func);
124 sdio_claim_host(func);
125 err = _sd_cmd52_read(pintfhdl, addr, cnt, pdata);
127 sdio_release_host(func);
136 s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
138 struct adapter *padapter;
139 struct dvobj_priv *psdiodev;
140 struct sdio_data *psdio;
143 struct sdio_func *func;
145 padapter = pintfhdl->padapter;
146 psdiodev = pintfhdl->pintf_dev;
147 psdio = &psdiodev->intf_data;
149 if (padapter->bSurpriseRemoved) {
150 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
156 for (i = 0; i < cnt; i++) {
157 sdio_writeb(func, pdata[i], addr + i, &err);
159 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__,
160 err, addr + i, pdata[i]);
172 s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
174 struct adapter *padapter;
175 struct dvobj_priv *psdiodev;
176 struct sdio_data *psdio;
179 struct sdio_func *func;
182 padapter = pintfhdl->padapter;
183 psdiodev = pintfhdl->pintf_dev;
184 psdio = &psdiodev->intf_data;
186 if (padapter->bSurpriseRemoved) {
187 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
192 claim_needed = rtw_sdio_claim_host_needed(func);
195 sdio_claim_host(func);
196 err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata);
198 sdio_release_host(func);
202 u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
204 struct adapter *padapter;
205 struct dvobj_priv *psdiodev;
206 struct sdio_data *psdio;
209 struct sdio_func *func;
212 padapter = pintfhdl->padapter;
213 psdiodev = pintfhdl->pintf_dev;
214 psdio = &psdiodev->intf_data;
216 if (padapter->bSurpriseRemoved) {
217 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
222 claim_needed = rtw_sdio_claim_host_needed(func);
225 sdio_claim_host(func);
226 v = sdio_readb(func, addr, err);
228 sdio_release_host(func);
230 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, *err, addr);
234 u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
236 struct adapter *padapter;
237 struct dvobj_priv *psdiodev;
238 struct sdio_data *psdio;
240 struct sdio_func *func;
243 padapter = pintfhdl->padapter;
244 psdiodev = pintfhdl->pintf_dev;
245 psdio = &psdiodev->intf_data;
247 if (padapter->bSurpriseRemoved) {
248 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
253 claim_needed = rtw_sdio_claim_host_needed(func);
256 sdio_claim_host(func);
257 v = sdio_readl(func, addr, err);
259 sdio_release_host(func);
264 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x\n", __func__, *err, addr, v);
267 for (i = 0; i < SD_IO_TRY_CNT; i++) {
269 sdio_claim_host(func);
270 v = sdio_readl(func, addr, err);
272 sdio_release_host(func);
275 rtw_reset_continual_io_error(psdiodev);
278 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
279 if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
280 padapter->bSurpriseRemoved = true;
282 if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
283 padapter->bSurpriseRemoved = true;
289 if (i == SD_IO_TRY_CNT)
290 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
292 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
298 void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err)
300 struct adapter *padapter;
301 struct dvobj_priv *psdiodev;
302 struct sdio_data *psdio;
303 struct sdio_func *func;
306 padapter = pintfhdl->padapter;
307 psdiodev = pintfhdl->pintf_dev;
308 psdio = &psdiodev->intf_data;
310 if (padapter->bSurpriseRemoved) {
311 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
316 claim_needed = rtw_sdio_claim_host_needed(func);
319 sdio_claim_host(func);
320 sdio_writeb(func, v, addr, err);
322 sdio_release_host(func);
324 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, *err, addr, v);
327 void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err)
329 struct adapter *padapter;
330 struct dvobj_priv *psdiodev;
331 struct sdio_data *psdio;
332 struct sdio_func *func;
335 padapter = pintfhdl->padapter;
336 psdiodev = pintfhdl->pintf_dev;
337 psdio = &psdiodev->intf_data;
339 if (padapter->bSurpriseRemoved) {
340 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
345 claim_needed = rtw_sdio_claim_host_needed(func);
348 sdio_claim_host(func);
349 sdio_writel(func, v, addr, err);
351 sdio_release_host(func);
356 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x\n", __func__, *err, addr, v);
359 for (i = 0; i < SD_IO_TRY_CNT; i++) {
361 sdio_claim_host(func);
362 sdio_writel(func, v, addr, err);
364 sdio_release_host(func);
366 rtw_reset_continual_io_error(psdiodev);
369 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
370 if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
371 padapter->bSurpriseRemoved = true;
373 if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
374 padapter->bSurpriseRemoved = true;
380 if (i == SD_IO_TRY_CNT)
381 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i);
383 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i);
388 * Use CMD53 to read data from SDIO device.
389 * This function MUST be called after sdio_claim_host() or
390 * in SDIO ISR(host had been claimed).
393 *psdio pointer of SDIO_DATA
394 *addr address to read
396 *pdata pointer to put data, this should be a "DMA:able scratch buffer"!
402 s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
404 struct adapter *padapter;
405 struct dvobj_priv *psdiodev;
406 struct sdio_data *psdio;
409 struct sdio_func *func;
411 padapter = pintfhdl->padapter;
412 psdiodev = pintfhdl->pintf_dev;
413 psdio = &psdiodev->intf_data;
415 if (padapter->bSurpriseRemoved) {
416 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
422 if (unlikely((cnt == 1) || (cnt == 2))) {
426 for (i = 0; i < cnt; i++) {
427 *(pbuf + i) = sdio_readb(func, addr + i, &err);
430 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr);
437 err = sdio_memcpy_fromio(func, pdata, addr, cnt);
439 DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d\n", __func__, err, addr, cnt);
445 * Use CMD53 to read data from SDIO device.
448 *psdio pointer of SDIO_DATA
449 *addr address to read
451 *pdata pointer to put data, this should be a "DMA:able scratch buffer"!
457 s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
459 struct adapter *padapter;
460 struct dvobj_priv *psdiodev;
461 struct sdio_data *psdio;
463 struct sdio_func *func;
467 padapter = pintfhdl->padapter;
468 psdiodev = pintfhdl->pintf_dev;
469 psdio = &psdiodev->intf_data;
471 if (padapter->bSurpriseRemoved) {
472 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
476 claim_needed = rtw_sdio_claim_host_needed(func);
479 sdio_claim_host(func);
480 err = _sd_read(pintfhdl, addr, cnt, pdata);
482 sdio_release_host(func);
487 * Use CMD53 to write data to SDIO device.
488 * This function MUST be called after sdio_claim_host() or
489 * in SDIO ISR(host had been claimed).
492 *psdio pointer of SDIO_DATA
493 *addr address to write
495 *pdata data pointer, this should be a "DMA:able scratch buffer"!
501 s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
503 struct adapter *padapter;
504 struct dvobj_priv *psdiodev;
505 struct sdio_data *psdio;
507 struct sdio_func *func;
511 padapter = pintfhdl->padapter;
512 psdiodev = pintfhdl->pintf_dev;
513 psdio = &psdiodev->intf_data;
515 if (padapter->bSurpriseRemoved) {
516 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
521 /* size = sdio_align_size(func, cnt); */
523 if (unlikely((cnt == 1) || (cnt == 2))) {
527 for (i = 0; i < cnt; i++) {
528 sdio_writeb(func, *(pbuf + i), addr + i, &err);
530 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n",
531 __func__, err, addr, *(pbuf + i));
540 err = sdio_memcpy_toio(func, addr, pdata, size);
542 DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d(%d)\n", __func__, err, addr, cnt, size);
548 * Use CMD53 to write data to SDIO device.
551 * psdio pointer of SDIO_DATA
552 * addr address to write
553 * cnt amount to write
554 * pdata data pointer, this should be a "DMA:able scratch buffer"!
560 s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
562 struct adapter *padapter;
563 struct dvobj_priv *psdiodev;
564 struct sdio_data *psdio;
565 struct sdio_func *func;
569 padapter = pintfhdl->padapter;
570 psdiodev = pintfhdl->pintf_dev;
571 psdio = &psdiodev->intf_data;
573 if (padapter->bSurpriseRemoved) {
574 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
579 claim_needed = rtw_sdio_claim_host_needed(func);
582 sdio_claim_host(func);
583 err = _sd_write(pintfhdl, addr, cnt, pdata);
585 sdio_release_host(func);