int ReinitSDIO(struct hif_device *device) { s32 err; struct mmc_host *host; struct mmc_card *card; struct sdio_func *func; u8 cmd52_resp; u32 clock; func = device->func; card = func->card; host = card->host; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ReinitSDIO \n")); sdio_claim_host(func); do { if (!device->is_suspend) { u32 resp; u16 rca; u32 i; int bit = fls(host->ocr_avail) - 1; /* emulate the mmc_power_up(...) */ host->ios.vdd = bit; host->ios.chip_select = MMC_CS_DONTCARE; host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; host->ios.power_mode = MMC_POWER_UP; host->ios.bus_width = MMC_BUS_WIDTH_1; host->ios.timing = MMC_TIMING_LEGACY; host->ops->set_ios(host, &host->ios); /* * This delay should be sufficient to allow the power supply * to reach the minimum voltage. */ msleep(2); host->ios.clock = host->f_min; host->ios.power_mode = MMC_POWER_ON; host->ops->set_ios(host, &host->ios); /* * This delay must be at least 74 clock sizes, or 1 ms, or the * time required to reach a stable voltage. */ msleep(2); /* Issue CMD0. Goto idle state */ host->ios.chip_select = MMC_CS_HIGH; host->ops->set_ios(host, &host->ios); msleep(1); err = IssueSDCommand(device, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | MMC_CMD_BC), NULL); host->ios.chip_select = MMC_CS_DONTCARE; host->ops->set_ios(host, &host->ios); msleep(1); host->use_spi_crc = 0; if (err) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD0 failed : %d \n",err)); break; } if (!host->ocr) { /* Issue CMD5, arg = 0 */ err = IssueSDCommand(device, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp); if (err) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err)); break; } host->ocr = resp; } /* Issue CMD5, arg = ocr. Wait till card is ready */ for (i=0;i<100;i++) { err = IssueSDCommand(device, SD_IO_SEND_OP_COND, host->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp); if (err) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err)); break; } if (resp & MMC_CARD_BUSY) { break; } msleep(10); } if ((i == 100) || (err)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: card in not ready : %d %d \n",i,err)); break; } /* Issue CMD3, get RCA */ err = IssueSDCommand(device, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 | MMC_CMD_BCR, &resp); if (err) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD3 failed : %d \n",err)); break; } rca = resp >> 16; host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; host->ops->set_ios(host, &host->ios); /* Issue CMD7, select card */ err = IssueSDCommand(device, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R1 | MMC_CMD_AC, NULL); if (err) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD7 failed : %d \n",err)); break; } } /* Enable high speed */ if (card->host->caps & MMC_CAP_SD_HIGHSPEED) { AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("ReinitSDIO: Set high speed mode\n")); err = Func0_CMD52ReadByte(card, SDIO_CCCR_SPEED, &cmd52_resp); if (err) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 read to CCCR speed register failed : %d \n",err)); card->state &= ~MMC_STATE_HIGHSPEED; /* no need to break */ } else { err = Func0_CMD52WriteByte(card, SDIO_CCCR_SPEED, (cmd52_resp | SDIO_SPEED_EHS)); if (err) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 write to CCCR speed register failed : %d \n",err)); break; } mmc_card_set_highspeed(card); host->ios.timing = MMC_TIMING_SD_HS; host->ops->set_ios(host, &host->ios); } } /* Set clock */ if (mmc_card_highspeed(card)) { clock = 50000000; } else { clock = card->cis.max_dtr; } if (clock > host->f_max) { clock = host->f_max; } host->ios.clock = clock; host->ops->set_ios(host, &host->ios); if (card->host->caps & MMC_CAP_4_BIT_DATA) { /* CMD52: Set bus width & disable card detect resistor */ err = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT); if (err) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 to set bus mode failed : %d \n",err)); break; } host->ios.bus_width = MMC_BUS_WIDTH_4; host->ops->set_ios(host, &host->ios); } } while (0);
static A_STATUS ReinitSDIO(HIF_DEVICE *device) { A_STATUS status = A_OK; SD_COMMAND_RESPONSE response; A_UINT32 ocr; int cardReadyRetry = 10; A_UINT16 rca; A_UINT8 cmd52Data; do { if (!IssueSDCommand(device->handle,0,0,NoResponse,NULL)) { break; } AR_DEBUG_PRINTF(DBG_TRACE,("Issuing first CMD5 ... \n")); /* issue CMD5, ARG=0 */ if (!IssueSDCommand(device->handle,5,0,ResponseR4,&response)) { AR_DEBUG_PRINTF(DBG_TRACE,("CMD5 FAILED, NO card detected \n")); break; } ocr = SD_SDIO_R4_GET_OCR(response.ResponseBuffer); AR_DEBUG_PRINTF(DBG_TRACE,("CMD5 success, OCR = 0x%X \n",ocr)); /* issue CMD5, ARG=0x00100000 repeatedly until card is ready */ while (cardReadyRetry) { if (!IssueSDCommand(device->handle, 5, 0x00100000, /* use 3.0 volts, although this really is a don't care */ ResponseR4, &response)) { AR_DEBUG_PRINTF(DBG_ERR,("CMD5 Failed \n")); cardReadyRetry = 0; break; } if (SD_SDIO_R4_IS_CARD_READY(response.ResponseBuffer)) { AR_DEBUG_PRINTF(DBG_TRACE,("SDIO Card is Ready! \n")); break; } cardReadyRetry--; Sleep(10); } if (cardReadyRetry == 0) { AR_DEBUG_PRINTF(DBG_ERR,("CMD5 Ready polling Expired \r\n")); break; } AR_DEBUG_PRINTF(DBG_TRACE,("Issuing CMD3 ... \n")); /* issue CMD3 */ if (!IssueSDCommand(device->handle,3,0,ResponseR6,&response)) { AR_DEBUG_PRINTF(DBG_ERR,("CMD3 FAILED \n")); break; } rca = SD_SDIO_R6_GET_RCA(response.ResponseBuffer); AR_DEBUG_PRINTF(DBG_TRACE,("Card RCA : 0x%X \n",rca)); AR_DEBUG_PRINTF(DBG_TRACE,("Issuing CMD7 ... \n")); /* issue CMD7 to select card */ if (!IssueSDCommand(device->handle, 7,(((A_UINT32)rca) << 16),ResponseR1b,&response)) { AR_DEBUG_PRINTF(DBG_ERR,("CMD7 FAILED \n")); break; } AR_DEBUG_PRINTF(DBG_TRACE,("Card is now selected! \n")); /* disable card detect resistor and restore operational bus width */ cmd52Data = CARD_DETECT_DISABLE; if (device->CardInterface.InterfaceMode == SD_INTERFACE_SD_4BIT) { /* enable 4-bit mode */ cmd52Data |= 0x2; } if (!IssueCMD52(device->handle, SDIO_BUS_IF_REG, 0, TRUE, &cmd52Data)) { AR_DEBUG_PRINTF(DBG_ERR,("Failed to set bus mode register \r\n")); break; } /* complete interface setup */ if (!SetupSDIOInterface(device)) { status = A_ERROR; } } while (FALSE); return status; }