1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 5 * 6 *******************************************************************************/ 7 8 #include <drv_types.h> 9 #include <rtw_debug.h> 10 11 static bool rtw_sdio_claim_host_needed(struct sdio_func *func) 12 { 13 struct dvobj_priv *dvobj = sdio_get_drvdata(func); 14 struct sdio_data *sdio_data = &dvobj->intf_data; 15 16 if (sdio_data->sys_sdio_irq_thd && sdio_data->sys_sdio_irq_thd == current) 17 return false; 18 return true; 19 } 20 21 inline void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, void *thd_hdl) 22 { 23 struct sdio_data *sdio_data = &dvobj->intf_data; 24 25 sdio_data->sys_sdio_irq_thd = thd_hdl; 26 } 27 28 /* 29 * Return: 30 *0 Success 31 *others Fail 32 */ 33 s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) 34 { 35 struct adapter *padapter; 36 struct dvobj_priv *psdiodev; 37 struct sdio_data *psdio; 38 39 int err = 0, i; 40 struct sdio_func *func; 41 42 padapter = pintfhdl->padapter; 43 psdiodev = pintfhdl->pintf_dev; 44 psdio = &psdiodev->intf_data; 45 46 if (padapter->bSurpriseRemoved) 47 return err; 48 49 func = psdio->func; 50 51 for (i = 0; i < cnt; i++) { 52 pdata[i] = sdio_readb(func, addr + i, &err); 53 if (err) 54 break; 55 } 56 return err; 57 } 58 59 /* 60 * Return: 61 *0 Success 62 *others Fail 63 */ 64 s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) 65 { 66 struct adapter *padapter; 67 struct dvobj_priv *psdiodev; 68 struct sdio_data *psdio; 69 70 int err = 0; 71 struct sdio_func *func; 72 bool claim_needed; 73 74 padapter = pintfhdl->padapter; 75 psdiodev = pintfhdl->pintf_dev; 76 psdio = &psdiodev->intf_data; 77 78 if (padapter->bSurpriseRemoved) 79 return err; 80 81 func = psdio->func; 82 claim_needed = rtw_sdio_claim_host_needed(func); 83 84 if (claim_needed) 85 sdio_claim_host(func); 86 err = _sd_cmd52_read(pintfhdl, addr, cnt, pdata); 87 if (claim_needed) 88 sdio_release_host(func); 89 return err; 90 } 91 92 /* 93 * Return: 94 *0 Success 95 *others Fail 96 */ 97 s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) 98 { 99 struct adapter *padapter; 100 struct dvobj_priv *psdiodev; 101 struct sdio_data *psdio; 102 103 int err = 0, i; 104 struct sdio_func *func; 105 106 padapter = pintfhdl->padapter; 107 psdiodev = pintfhdl->pintf_dev; 108 psdio = &psdiodev->intf_data; 109 110 if (padapter->bSurpriseRemoved) 111 return err; 112 113 func = psdio->func; 114 115 for (i = 0; i < cnt; i++) { 116 sdio_writeb(func, pdata[i], addr + i, &err); 117 if (err) 118 break; 119 } 120 return err; 121 } 122 123 /* 124 * Return: 125 *0 Success 126 *others Fail 127 */ 128 s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata) 129 { 130 struct adapter *padapter; 131 struct dvobj_priv *psdiodev; 132 struct sdio_data *psdio; 133 134 int err = 0; 135 struct sdio_func *func; 136 bool claim_needed; 137 138 padapter = pintfhdl->padapter; 139 psdiodev = pintfhdl->pintf_dev; 140 psdio = &psdiodev->intf_data; 141 142 if (padapter->bSurpriseRemoved) 143 return err; 144 145 func = psdio->func; 146 claim_needed = rtw_sdio_claim_host_needed(func); 147 148 if (claim_needed) 149 sdio_claim_host(func); 150 err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata); 151 if (claim_needed) 152 sdio_release_host(func); 153 return err; 154 } 155 156 u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err) 157 { 158 struct adapter *padapter; 159 struct dvobj_priv *psdiodev; 160 struct sdio_data *psdio; 161 162 u8 v = 0; 163 struct sdio_func *func; 164 bool claim_needed; 165 166 padapter = pintfhdl->padapter; 167 psdiodev = pintfhdl->pintf_dev; 168 psdio = &psdiodev->intf_data; 169 170 if (padapter->bSurpriseRemoved) 171 return v; 172 173 func = psdio->func; 174 claim_needed = rtw_sdio_claim_host_needed(func); 175 176 if (claim_needed) 177 sdio_claim_host(func); 178 v = sdio_readb(func, addr, err); 179 if (claim_needed) 180 sdio_release_host(func); 181 return v; 182 } 183 184 u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err) 185 { 186 struct adapter *padapter; 187 struct dvobj_priv *psdiodev; 188 struct sdio_data *psdio; 189 u32 v = 0; 190 struct sdio_func *func; 191 bool claim_needed; 192 193 padapter = pintfhdl->padapter; 194 psdiodev = pintfhdl->pintf_dev; 195 psdio = &psdiodev->intf_data; 196 197 if (padapter->bSurpriseRemoved) 198 return v; 199 200 func = psdio->func; 201 claim_needed = rtw_sdio_claim_host_needed(func); 202 203 if (claim_needed) 204 sdio_claim_host(func); 205 v = sdio_readl(func, addr, err); 206 if (claim_needed) 207 sdio_release_host(func); 208 209 if (err && *err) { 210 int i; 211 212 *err = 0; 213 for (i = 0; i < SD_IO_TRY_CNT; i++) { 214 if (claim_needed) 215 sdio_claim_host(func); 216 v = sdio_readl(func, addr, err); 217 if (claim_needed) 218 sdio_release_host(func); 219 220 if (*err == 0) { 221 rtw_reset_continual_io_error(psdiodev); 222 break; 223 } else { 224 if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) 225 padapter->bSurpriseRemoved = true; 226 227 if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { 228 padapter->bSurpriseRemoved = true; 229 break; 230 } 231 } 232 } 233 } 234 return v; 235 } 236 237 void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err) 238 { 239 struct adapter *padapter; 240 struct dvobj_priv *psdiodev; 241 struct sdio_data *psdio; 242 struct sdio_func *func; 243 bool claim_needed; 244 245 padapter = pintfhdl->padapter; 246 psdiodev = pintfhdl->pintf_dev; 247 psdio = &psdiodev->intf_data; 248 249 if (padapter->bSurpriseRemoved) 250 return; 251 252 func = psdio->func; 253 claim_needed = rtw_sdio_claim_host_needed(func); 254 255 if (claim_needed) 256 sdio_claim_host(func); 257 sdio_writeb(func, v, addr, err); 258 if (claim_needed) 259 sdio_release_host(func); 260 } 261 262 void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err) 263 { 264 struct adapter *padapter; 265 struct dvobj_priv *psdiodev; 266 struct sdio_data *psdio; 267 struct sdio_func *func; 268 bool claim_needed; 269 270 padapter = pintfhdl->padapter; 271 psdiodev = pintfhdl->pintf_dev; 272 psdio = &psdiodev->intf_data; 273 274 if (padapter->bSurpriseRemoved) 275 return; 276 277 func = psdio->func; 278 claim_needed = rtw_sdio_claim_host_needed(func); 279 280 if (claim_needed) 281 sdio_claim_host(func); 282 sdio_writel(func, v, addr, err); 283 if (claim_needed) 284 sdio_release_host(func); 285 286 if (err && *err) { 287 int i; 288 289 *err = 0; 290 for (i = 0; i < SD_IO_TRY_CNT; i++) { 291 if (claim_needed) 292 sdio_claim_host(func); 293 sdio_writel(func, v, addr, err); 294 if (claim_needed) 295 sdio_release_host(func); 296 if (*err == 0) { 297 rtw_reset_continual_io_error(psdiodev); 298 break; 299 } else { 300 if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) 301 padapter->bSurpriseRemoved = true; 302 303 if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { 304 padapter->bSurpriseRemoved = true; 305 break; 306 } 307 } 308 } 309 310 } 311 } 312 313 /* 314 * Use CMD53 to read data from SDIO device. 315 * This function MUST be called after sdio_claim_host() or 316 * in SDIO ISR(host had been claimed). 317 * 318 * Parameters: 319 *psdio pointer of SDIO_DATA 320 *addr address to read 321 *cnt amount to read 322 *pdata pointer to put data, this should be a "DMA:able scratch buffer"! 323 * 324 * Return: 325 *0 Success 326 *others Fail 327 */ 328 s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 329 { 330 struct adapter *padapter; 331 struct dvobj_priv *psdiodev; 332 struct sdio_data *psdio; 333 334 int err = -EPERM; 335 struct sdio_func *func; 336 337 padapter = pintfhdl->padapter; 338 psdiodev = pintfhdl->pintf_dev; 339 psdio = &psdiodev->intf_data; 340 341 if (padapter->bSurpriseRemoved) 342 return err; 343 344 func = psdio->func; 345 346 if (unlikely((cnt == 1) || (cnt == 2))) { 347 int i; 348 u8 *pbuf = pdata; 349 350 for (i = 0; i < cnt; i++) { 351 *(pbuf + i) = sdio_readb(func, addr + i, &err); 352 353 if (err) 354 break; 355 } 356 return err; 357 } 358 359 err = sdio_memcpy_fromio(func, pdata, addr, cnt); 360 361 return err; 362 } 363 364 /* 365 * Use CMD53 to read data from SDIO device. 366 * 367 * Parameters: 368 *psdio pointer of SDIO_DATA 369 *addr address to read 370 *cnt amount to read 371 *pdata pointer to put data, this should be a "DMA:able scratch buffer"! 372 * 373 * Return: 374 *0 Success 375 *others Fail 376 */ 377 s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 378 { 379 struct adapter *padapter; 380 struct dvobj_priv *psdiodev; 381 struct sdio_data *psdio; 382 383 struct sdio_func *func; 384 bool claim_needed; 385 s32 err = -EPERM; 386 387 padapter = pintfhdl->padapter; 388 psdiodev = pintfhdl->pintf_dev; 389 psdio = &psdiodev->intf_data; 390 391 if (padapter->bSurpriseRemoved) 392 return err; 393 394 func = psdio->func; 395 claim_needed = rtw_sdio_claim_host_needed(func); 396 397 if (claim_needed) 398 sdio_claim_host(func); 399 err = _sd_read(pintfhdl, addr, cnt, pdata); 400 if (claim_needed) 401 sdio_release_host(func); 402 return err; 403 } 404 405 /* 406 * Use CMD53 to write data to SDIO device. 407 * This function MUST be called after sdio_claim_host() or 408 * in SDIO ISR(host had been claimed). 409 * 410 * Parameters: 411 *psdio pointer of SDIO_DATA 412 *addr address to write 413 *cnt amount to write 414 *pdata data pointer, this should be a "DMA:able scratch buffer"! 415 * 416 * Return: 417 *0 Success 418 *others Fail 419 */ 420 s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 421 { 422 struct adapter *padapter; 423 struct dvobj_priv *psdiodev; 424 struct sdio_data *psdio; 425 426 struct sdio_func *func; 427 u32 size; 428 s32 err = -EPERM; 429 430 padapter = pintfhdl->padapter; 431 psdiodev = pintfhdl->pintf_dev; 432 psdio = &psdiodev->intf_data; 433 434 if (padapter->bSurpriseRemoved) 435 return err; 436 437 func = psdio->func; 438 /* size = sdio_align_size(func, cnt); */ 439 440 if (unlikely((cnt == 1) || (cnt == 2))) { 441 int i; 442 u8 *pbuf = pdata; 443 444 for (i = 0; i < cnt; i++) { 445 sdio_writeb(func, *(pbuf + i), addr + i, &err); 446 if (err) 447 break; 448 } 449 450 return err; 451 } 452 453 size = cnt; 454 err = sdio_memcpy_toio(func, addr, pdata, size); 455 456 return err; 457 } 458 459 /* 460 * Use CMD53 to write data to SDIO device. 461 * 462 * Parameters: 463 * psdio pointer of SDIO_DATA 464 * addr address to write 465 * cnt amount to write 466 * pdata data pointer, this should be a "DMA:able scratch buffer"! 467 * 468 * Return: 469 * 0 Success 470 * others Fail 471 */ 472 s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata) 473 { 474 struct adapter *padapter; 475 struct dvobj_priv *psdiodev; 476 struct sdio_data *psdio; 477 struct sdio_func *func; 478 bool claim_needed; 479 s32 err = -EPERM; 480 481 padapter = pintfhdl->padapter; 482 psdiodev = pintfhdl->pintf_dev; 483 psdio = &psdiodev->intf_data; 484 485 if (padapter->bSurpriseRemoved) 486 return err; 487 488 func = psdio->func; 489 claim_needed = rtw_sdio_claim_host_needed(func); 490 491 if (claim_needed) 492 sdio_claim_host(func); 493 err = _sd_write(pintfhdl, addr, cnt, pdata); 494 if (claim_needed) 495 sdio_release_host(func); 496 return err; 497 } 498