📄 sdio_bus_misc.c
字号:
break; } } return status;}/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ PollCardReady - poll card till it's ready Input: pHcd - HCD object OCRValue - OCR value to poll with PollType - polling type (based on card type) Output: Return: Notes:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/SDIO_STATUS PollCardReady(PSDHCD pHcd, UINT32 OCRValue, CARD_INFO_FLAGS PollType){ INT cardReadyRetry; SDIO_STATUS status; PSDREQUEST pReq; if (!((PollType == CARD_SDIO) || (PollType == CARD_SD) || (PollType == CARD_MMC))) { DBG_ASSERT(FALSE); return SDIO_STATUS_INVALID_PARAMETER; } pReq = AllocateRequest(); if (NULL == pReq) { return SDIO_STATUS_NO_RESOURCES; } status = SDIO_STATUS_SUCCESS; cardReadyRetry = pBusContext->CardReadyPollingRetry; DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Polling card ready, Using OCR:0x%8.8X, Poll Type:0x%X\n", OCRValue,PollType)); /* now issue CMD with the actual OCR as an argument until the card is ready */ while (cardReadyRetry) { if (IS_HCD_BUS_MODE_SPI(pHcd) && !(PollType == CARD_SDIO)) {#ifndef CT_CONFIG_NO_SDMMC if (PollType == CARD_MMC) { /* under SPI mode for MMC cards, we need to issue CMD1 and * check the response for the "in-idle" bit */ status = _IssueSimpleBusRequest(pHcd, CMD1, 0, SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT, pReq); } else if (PollType == CARD_SD) { /* under SPI mode for SD cards, we need to issue ACMD41 and * check the response for the "in-idle" bit */ status = _IssueSimpleBusRequest(pHcd, ACMD41, 0, SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_SKIP_SPI_FILT, pReq); } else { DBG_ASSERT(FALSE); }#endif } else { /* for SD/MMC in native mode and SDIO (all modes) we need to read the OCR register */ /* read the OCR using the supplied OCR value as an argument, we don't care about the * actual OCR read-back, but we are interested in the response */ status = ReadOCR(pHcd,PollType,pReq,OCRValue,NULL); } if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to issue CMD to poll ready \n")); break; } if (PollType == CARD_SDIO) { if (IS_HCD_BUS_MODE_SPI(pHcd)) { if (SPI_SDIO_R4_IS_CARD_READY(pReq->Response)) { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SDIO Card Ready! (SPI) \n")); break; } } else { if (SD_SDIO_R4_IS_CARD_READY(pReq->Response)) { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SDIO Card Ready! \n")); break; } } } else if ((PollType == CARD_SD) || (PollType == CARD_MMC)) {#ifndef CT_CONFIG_NO_SDMMC if (IS_HCD_BUS_MODE_SPI(pHcd)) { /* check response when MMC or SD cards operate in SPI mode */ if (!(GET_SPI_R1_RESP_TOKEN(pReq->Response) & SPI_CS_STATE_IDLE)) { /* card is no longer in idle */ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD/MMC Card (SPI mode) is ready! \n")); break; } } else { /* check the OCR busy bit */ if (SD_R3_IS_CARD_READY(pReq->Response)) { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD/MMC (Native Mode) Card Ready! \n")); break; } }#endif } else { DBG_ASSERT(FALSE); } cardReadyRetry--; /* delay */ status = OSSleep(OCR_READY_CHECK_DELAY_MS); if (!SDIO_SUCCESS(status)){ break; } } if (0 == cardReadyRetry) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Card Ready timeout! \n")); status = SDIO_STATUS_DEVICE_ERROR; } FreeRequest(pReq); return status;}/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AdjustSlotPower - adjust slot power Input: pHcd - HCD object Output: pOCRvalue - ocr value to use Return: Notes:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/static SDIO_STATUS AdjustSlotPower(PSDHCD pHcd, UINT32 *pOCRvalue){ SDCONFIG_POWER_CTRL_DATA pwrSetting; SDIO_STATUS status = SDIO_STATUS_SUCCESS; ZERO_OBJECT(pwrSetting); DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Adjusting Slot Power, Requesting adjustment for OCR:0x%8.8X \n", *pOCRvalue)); do { pwrSetting.SlotPowerEnable = TRUE; /* get optimal power setting */ pwrSetting.SlotPowerVoltageMask = GetPowerSetting(pHcd, pOCRvalue); if (0 == pwrSetting.SlotPowerVoltageMask) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: No matching voltage for OCR \n")); status = SDIO_STATUS_DEVICE_ERROR; break; } DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Slot Pwr Mask 0x%X for OCR:0x%8.8X \n", pwrSetting.SlotPowerVoltageMask,*pOCRvalue)); status = _IssueConfig(pHcd,SDCONFIG_POWER_CTRL,&pwrSetting,sizeof(pwrSetting)); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set power in hcd \n")); break; } /* delay for power to settle */ OSSleep(pBusContext->PowerSettleDelay); /* save off for drivers */ pHcd->CardProperties.CardVoltage = pwrSetting.SlotPowerVoltageMask; } while (FALSE); return status;}/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ConvertEncodedTransSpeed - convert encoded TRANS_SPEED value to a clock rate Input: TransSpeedValue - encoded transfer speed value Output: Return: appropriate SD clock rate Notes: This function returns a rate of 0, if it could not be determined. This function can check tran speed values for SD,SDIO and MMC cards++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/static SD_BUSCLOCK_RATE ConvertEncodedTransSpeed(UINT8 TransSpeedValue){ SD_BUSCLOCK_RATE transfMul = 0; UINT8 timeVal = 0; switch (TransSpeedValue & TRANSFER_UNIT_MULTIPIER_MASK) { case 0: transfMul = 10000; break; case 1: transfMul = 100000; break; case 2: transfMul = 1000000; break; case 3: transfMul = 10000000; break; default: transfMul = 0; DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Card transfer multipler is wrong (val=0x%X)! \n", TransSpeedValue)); break; } switch ((TransSpeedValue & TIME_VALUE_MASK) >> TIME_VALUE_SHIFT) { case 1: timeVal = 10; break; case 2: timeVal = 12; break; case 3: timeVal = 13; break; case 4: timeVal = 15; break; case 5: timeVal = 20; break; case 6: timeVal = 25; break; case 7: timeVal = 30; break; case 8: timeVal = 35; break; case 9: timeVal = 40; break; case 10: timeVal = 45; break; case 11: timeVal = 50; break; case 12: timeVal = 55; break; case 13: timeVal = 60; break; case 14: timeVal = 70; break; case 15: timeVal = 80; break; default: timeVal = 0; DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Card time value is wrong (val=0x%X)! \n", TransSpeedValue)); break; } if ((transfMul != 0) && (timeVal != 0)) { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Card Reported Max: %d Hz (0x%X) \n", (timeVal*transfMul), TransSpeedValue)); return timeVal*transfMul; } return 0;}/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SelectDeselectCard - Select or deselect a card Input: pHcd - HCD object Select - select the card Output: Return: status Notes:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/static SDIO_STATUS SelectDeselectCard(PSDHCD pHcd, BOOL Select){ SDIO_STATUS status; if (IS_HCD_BUS_MODE_SPI(pHcd)) { /* SPI mode cards do not support selection */ status = SDIO_STATUS_SUCCESS; } else { if (!Select) { /* deselect, note that deselecting a card does not return a response */ status = _IssueSimpleBusRequest(pHcd, CMD7,0, SDREQ_FLAGS_NO_RESP,NULL); } else { /* select */ status = _IssueSimpleBusRequest(pHcd, CMD7,(pHcd->CardProperties.RCA << 16), SDREQ_FLAGS_RESP_R1B,NULL); } } if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Failed to %s card, RCA:0x%X Err:%d \n", (Select ? "Select":"Deselect"), pHcd->CardProperties.RCA, status)); } return status;}/* reorder a buffer by swapping MSB with LSB */static void ReorderBuffer(UINT8 *pBuffer, INT Bytes){ UINT8 *pEnd; UINT8 temp; DBG_ASSERT(!(Bytes & 1)); /* point to the end */ pEnd = &pBuffer[Bytes - 1]; /* divide in half */ Bytes = Bytes >> 1; while (Bytes) { temp = *pBuffer; /* swap bytes */ *pBuffer = *pEnd; *pEnd = temp; pBuffer++; pEnd--; Bytes--; }}#define ADJUST_OPER_CLOCK(pBusMode,Clock) \ (pBusMode)->ClockRate = min((SD_BUSCLOCK_RATE)(Clock),(pBusMode)->ClockRate)#define ADJUST_OPER_BLOCK_LEN(pCaps,Length) \ (pCaps)->OperBlockLenLimit = min((UINT16)(Length),(pCaps)->OperBlockLenLimit)#define ADJUST_OPER_BLOCK_COUNT(pCaps,Count) \ (pCaps)->OperBlockCountLimit = min((UINT16)(Count),(pCaps)->OperBlockCountLimit)/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ GetBusParameters - Get bus parameters for a card Input: pHcd - HCD object pBusMode - current bus mode on entry Output: pBusMode - new adjusted bus mode Return: status Notes:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/static SDIO_STATUS GetBusParameters(PSDHCD pHcd, PSDCONFIG_BUS_MODE_DATA pBusMode){ SDIO_STATUS status = SDIO_STATUS_SUCCESS; UINT8 temp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -