1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 *******************************************************************************/
15 #define _SDIO_OPS_LINUX_C_
17 #include <drv_types.h>
18 #include <rtw_debug.h>
20 static bool rtw_sdio_claim_host_needed(struct sdio_func *func)
22 struct dvobj_priv *dvobj = sdio_get_drvdata(func);
23 PSDIO_DATA sdio_data = &dvobj->intf_data;
25 if (sdio_data->sys_sdio_irq_thd && sdio_data->sys_sdio_irq_thd == current)
30 inline void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, void *thd_hdl)
32 PSDIO_DATA sdio_data = &dvobj->intf_data;
34 sdio_data->sys_sdio_irq_thd = thd_hdl;
37 u8 sd_f0_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
39 struct adapter *padapter;
40 struct dvobj_priv *psdiodev;
44 struct sdio_func *func;
47 padapter = pintfhdl->padapter;
48 psdiodev = pintfhdl->pintf_dev;
49 psdio = &psdiodev->intf_data;
51 if (padapter->bSurpriseRemoved) {
52 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
57 claim_needed = rtw_sdio_claim_host_needed(func);
60 sdio_claim_host(func);
61 v = sdio_f0_readb(func, addr, err);
63 sdio_release_host(func);
65 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, *err, addr);
74 s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
76 struct adapter *padapter;
77 struct dvobj_priv *psdiodev;
81 struct sdio_func *func;
83 padapter = pintfhdl->padapter;
84 psdiodev = pintfhdl->pintf_dev;
85 psdio = &psdiodev->intf_data;
87 if (padapter->bSurpriseRemoved) {
88 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
94 for (i = 0; i < cnt; i++) {
95 pdata[i] = sdio_readb(func, addr+i, &err);
97 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr+i);
109 s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
111 struct adapter *padapter;
112 struct dvobj_priv *psdiodev;
116 struct sdio_func *func;
119 padapter = pintfhdl->padapter;
120 psdiodev = pintfhdl->pintf_dev;
121 psdio = &psdiodev->intf_data;
123 if (padapter->bSurpriseRemoved) {
124 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
129 claim_needed = rtw_sdio_claim_host_needed(func);
132 sdio_claim_host(func);
133 err = _sd_cmd52_read(pintfhdl, addr, cnt, pdata);
135 sdio_release_host(func);
144 s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
146 struct adapter *padapter;
147 struct dvobj_priv *psdiodev;
151 struct sdio_func *func;
153 padapter = pintfhdl->padapter;
154 psdiodev = pintfhdl->pintf_dev;
155 psdio = &psdiodev->intf_data;
157 if (padapter->bSurpriseRemoved) {
158 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
164 for (i = 0; i < cnt; i++) {
165 sdio_writeb(func, pdata[i], addr+i, &err);
167 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, err, addr+i, pdata[i]);
179 s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
181 struct adapter *padapter;
182 struct dvobj_priv *psdiodev;
186 struct sdio_func *func;
189 padapter = pintfhdl->padapter;
190 psdiodev = pintfhdl->pintf_dev;
191 psdio = &psdiodev->intf_data;
193 if (padapter->bSurpriseRemoved) {
194 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
199 claim_needed = rtw_sdio_claim_host_needed(func);
202 sdio_claim_host(func);
203 err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata);
205 sdio_release_host(func);
209 u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
211 struct adapter *padapter;
212 struct dvobj_priv *psdiodev;
216 struct sdio_func *func;
219 padapter = pintfhdl->padapter;
220 psdiodev = pintfhdl->pintf_dev;
221 psdio = &psdiodev->intf_data;
223 if (padapter->bSurpriseRemoved) {
224 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
229 claim_needed = rtw_sdio_claim_host_needed(func);
232 sdio_claim_host(func);
233 v = sdio_readb(func, addr, err);
235 sdio_release_host(func);
237 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, *err, addr);
241 u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
243 struct adapter *padapter;
244 struct dvobj_priv *psdiodev;
247 struct sdio_func *func;
250 padapter = pintfhdl->padapter;
251 psdiodev = pintfhdl->pintf_dev;
252 psdio = &psdiodev->intf_data;
254 if (padapter->bSurpriseRemoved) {
255 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
260 claim_needed = rtw_sdio_claim_host_needed(func);
263 sdio_claim_host(func);
264 v = sdio_readl(func, addr, err);
266 sdio_release_host(func);
272 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x\n", __func__, *err, addr, v);
275 for (i = 0; i < SD_IO_TRY_CNT; i++)
277 if (claim_needed) sdio_claim_host(func);
278 v = sdio_readl(func, addr, err);
279 if (claim_needed) sdio_release_host(func);
282 rtw_reset_continual_io_error(psdiodev);
285 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
286 if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) {
287 padapter->bSurpriseRemoved = true;
290 if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
291 padapter->bSurpriseRemoved = true;
297 if (i == SD_IO_TRY_CNT)
298 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
300 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
306 void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err)
308 struct adapter *padapter;
309 struct dvobj_priv *psdiodev;
311 struct sdio_func *func;
314 padapter = pintfhdl->padapter;
315 psdiodev = pintfhdl->pintf_dev;
316 psdio = &psdiodev->intf_data;
318 if (padapter->bSurpriseRemoved) {
319 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
324 claim_needed = rtw_sdio_claim_host_needed(func);
327 sdio_claim_host(func);
328 sdio_writeb(func, v, addr, err);
330 sdio_release_host(func);
332 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, *err, addr, v);
335 void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err)
337 struct adapter *padapter;
338 struct dvobj_priv *psdiodev;
340 struct sdio_func *func;
343 padapter = pintfhdl->padapter;
344 psdiodev = pintfhdl->pintf_dev;
345 psdio = &psdiodev->intf_data;
347 if (padapter->bSurpriseRemoved) {
348 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
353 claim_needed = rtw_sdio_claim_host_needed(func);
356 sdio_claim_host(func);
357 sdio_writel(func, v, addr, err);
359 sdio_release_host(func);
365 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x\n", __func__, *err, addr, v);
368 for (i = 0; i < SD_IO_TRY_CNT; i++)
370 if (claim_needed) sdio_claim_host(func);
371 sdio_writel(func, v, addr, err);
372 if (claim_needed) sdio_release_host(func);
374 rtw_reset_continual_io_error(psdiodev);
377 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
378 if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) {
379 padapter->bSurpriseRemoved = true;
382 if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
383 padapter->bSurpriseRemoved = true;
389 if (i == SD_IO_TRY_CNT)
390 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i);
392 DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i);
397 * Use CMD53 to read data from SDIO device.
398 * This function MUST be called after sdio_claim_host() or
399 * in SDIO ISR(host had been claimed).
402 *psdio pointer of SDIO_DATA
403 *addr address to read
405 *pdata pointer to put data, this should be a "DMA:able scratch buffer"!
411 s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
413 struct adapter *padapter;
414 struct dvobj_priv *psdiodev;
418 struct sdio_func *func;
420 padapter = pintfhdl->padapter;
421 psdiodev = pintfhdl->pintf_dev;
422 psdio = &psdiodev->intf_data;
424 if (padapter->bSurpriseRemoved) {
425 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
431 if (unlikely((cnt == 1) || (cnt == 2)))
436 for (i = 0; i < cnt; i++)
438 *(pbuf+i) = sdio_readb(func, addr+i, &err);
441 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr);
448 err = sdio_memcpy_fromio(func, pdata, addr, cnt);
450 DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d\n", __func__, err, addr, cnt);
456 * Use CMD53 to read data from SDIO device.
459 *psdio pointer of SDIO_DATA
460 *addr address to read
462 *pdata pointer to put data, this should be a "DMA:able scratch buffer"!
468 s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
470 struct adapter *padapter;
471 struct dvobj_priv *psdiodev;
474 struct sdio_func *func;
478 padapter = pintfhdl->padapter;
479 psdiodev = pintfhdl->pintf_dev;
480 psdio = &psdiodev->intf_data;
482 if (padapter->bSurpriseRemoved) {
483 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
487 claim_needed = rtw_sdio_claim_host_needed(func);
490 sdio_claim_host(func);
491 err = _sd_read(pintfhdl, addr, cnt, pdata);
493 sdio_release_host(func);
498 * Use CMD53 to write data to SDIO device.
499 * This function MUST be called after sdio_claim_host() or
500 * in SDIO ISR(host had been claimed).
503 *psdio pointer of SDIO_DATA
504 *addr address to write
506 *pdata data pointer, this should be a "DMA:able scratch buffer"!
512 s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
514 struct adapter *padapter;
515 struct dvobj_priv *psdiodev;
518 struct sdio_func *func;
522 padapter = pintfhdl->padapter;
523 psdiodev = pintfhdl->pintf_dev;
524 psdio = &psdiodev->intf_data;
526 if (padapter->bSurpriseRemoved) {
527 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
532 /* size = sdio_align_size(func, cnt); */
534 if (unlikely((cnt == 1) || (cnt == 2)))
539 for (i = 0; i < cnt; i++)
541 sdio_writeb(func, *(pbuf+i), addr+i, &err);
543 DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, err, addr, *(pbuf+i));
552 err = sdio_memcpy_toio(func, addr, pdata, size);
554 DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d(%d)\n", __func__, err, addr, cnt, size);
560 * Use CMD53 to write data to SDIO device.
563 * psdio pointer of SDIO_DATA
564 * addr address to write
565 * cnt amount to write
566 * pdata data pointer, this should be a "DMA:able scratch buffer"!
572 s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
574 struct adapter *padapter;
575 struct dvobj_priv *psdiodev;
577 struct sdio_func *func;
581 padapter = pintfhdl->padapter;
582 psdiodev = pintfhdl->pintf_dev;
583 psdio = &psdiodev->intf_data;
585 if (padapter->bSurpriseRemoved) {
586 /* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
591 claim_needed = rtw_sdio_claim_host_needed(func);
594 sdio_claim_host(func);
595 err = _sd_write(pintfhdl, addr, cnt, pdata);
597 sdio_release_host(func);