📄 sdio_bus_misc.c
字号:
if (doSet) { status = Cmd52WriteByteCommon(pDevice, SDIO_HS_CONTROL_REG, ®Data); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to %s HS mode in SDIO card : Err:%d\n", (SDIO_HS_CONTROL_EHS == regData) ? "enable":"disable" , status)); break; } else { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver:SDIO Card %s for High Speed mode \n", (SDIO_HS_CONTROL_EHS == regData) ? "enabled":"disabled" )); } } } /* use synchronize-with-bus request version, this may have been requested by a * function driver */ status = SDLIB_IssueConfig(pDevice, SDCONFIG_BUS_MODE_CTRL, pBusMode, sizeof(SDCONFIG_BUS_MODE_DATA)); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus mode in hcd : Err:%d \n", status)); break; } /* check requested bus width against the current mode */ if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_GET_BUSWIDTH(pHcd->CardProperties.BusMode)) { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Bus mode set, no width change\n")); break; } if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_SPI) { /* nothing more to do for SPI */ break; }#ifndef CT_CONFIG_NO_SDMMC /* set the bus width for SD and combo cards */ if (pHcd->CardProperties.Flags & CARD_SD) { if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) { /* turn off card detect resistor */ status = _IssueSimpleBusRequest(pHcd, ACMD42, 0, /* disable CD */ SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R1, NULL); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Failed to disable CD Res: %d \n", status)); /* this should be okay */ } arg = SD_ACMD6_BUS_WIDTH_4_BIT; } else { /* don't need to turn off CD in 1 bit mode, just set mode */ arg = SD_ACMD6_BUS_WIDTH_1_BIT; } /* set the bus width */ status = _IssueSimpleBusRequest(pHcd, ACMD6, arg, /* set bus mode */ SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R1, NULL); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus width: %d \n", status)); break; } }#endif /* set bus width for SDIO cards */ if (pHcd->CardProperties.Flags & CARD_SDIO) { /* default */ regData = CARD_DETECT_DISABLE | SDIO_BUS_WIDTH_1_BIT; if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) { /* turn off card detect resistor and set buswidth */ regData = CARD_DETECT_DISABLE | SDIO_BUS_WIDTH_4_BIT; DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Enabling 4 bit mode on card \n")); } else { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Enabling 1 bit mode on card \n")); } status = Cmd52WriteByteCommon(pDevice, SDIO_BUS_IF_REG, ®Data); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus mode in Card : Err:%d\n", status)); break; } /* check for 4-bit interrupt detect mode */ if ((SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) && (pHcd->CardProperties.SDIOCaps & SDIO_CAPS_INT_MULTI_BLK) && (pHcd->Attributes & SDHCD_ATTRIB_MULTI_BLK_IRQ)) { /* enable interrupts between blocks, this doesn't actually turn on interrupts * it merely allows interrupts to be asserted in the inter-block gap */ pHcd->CardProperties.SDIOCaps |= SDIO_CAPS_ENB_INT_MULTI_BLK; DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: 4-Bit Multi-blk Interrupt support enabled\n")); } else { /* make sure this is disabled */ pHcd->CardProperties.SDIOCaps &= ~SDIO_CAPS_ENB_INT_MULTI_BLK; } status = Cmd52WriteByteCommon(pDevice, SDIO_CARD_CAPS_REG, &pHcd->CardProperties.SDIOCaps); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to update Card Caps register Err:%d\n", status)); break; } } /* set data bus width for MMC */ if (pHcd->CardProperties.Flags & CARD_MMC) { UINT8 buswidth = 0; if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) { buswidth = MMC_EXT_BUS_WIDTH_4_BIT; } else if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_MMC8_BIT) { buswidth = MMC_EXT_BUS_WIDTH_8_BIT; } else { /* normal 1 bit mode .. nothing to do */ break; } /* now set the bus mode on the card */ switcharg = MMC_SWITCH_BUILD_ARG(MMC_SWITCH_CMD_SET0, MMC_SWITCH_WRITE_BYTE, MMC_EXT_BUS_WIDTH_OFFSET, buswidth); status = _IssueSimpleBusRequest(pHcd, MMC_CMD_SWITCH, switcharg, SDREQ_FLAGS_RESP_R1B, NULL); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set MMC bus width (arg:0x%X): %d \n", switcharg, status)); break; } if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: 4 bit MMC mode enabled (arg:0x%X) \n", switcharg)); } else if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_MMC8_BIT) { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: 8-Bit MMC mode enabled (arg:0x%X) \n", switcharg)); } } } while (FALSE); if (SDIO_SUCCESS(status)) { /* set the operating mode */ pHcd->CardProperties.BusMode = pBusMode->BusModeFlags; /* set the actual clock rate */ pHcd->CardProperties.OperBusClock = pBusMode->ActualClockRate; } SemaphorePost(&pDevice->pHcd->ConfigureOpsSem); return status;}/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CardInitSetup - setup host for card initialization Input: pHcd - HCD object Output: Return: Notes:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/SDIO_STATUS CardInitSetup(PSDHCD pHcd){ SDCONFIG_INIT_CLOCKS_DATA initClocks; SDCONFIG_BUS_MODE_DATA busMode; UINT32 OCRvalue; SDIO_STATUS status = SDIO_STATUS_SUCCESS; ZERO_OBJECT(initClocks); ZERO_OBJECT(busMode); /* setup defaults */ initClocks.NumberOfClocks = SDMMC_MIN_INIT_CLOCKS; busMode.ClockRate = SD_INIT_BUS_CLOCK; /* check for SPI only */ if (pHcd->Attributes & SDHCD_ATTRIB_BUS_SPI) { /* SPI cards startup in non-CRC mode with the exception of CMD0, the * HCDs must issue CMD0 with the correct CRC , the spec shows that a * CMD 0 sequence is 0x40,0x00,0x00,0x00,0x00,0x95 */ busMode.BusModeFlags = SDCONFIG_BUS_WIDTH_SPI | SDCONFIG_BUS_MODE_SPI_NO_CRC; } /* check if host supports 1 bit mode */ /* TODO : if host supports power switching, we can * could initialize cards in SPI mode first */ if (pHcd->Attributes & SDHCD_ATTRIB_BUS_1BIT) { busMode.BusModeFlags = SDCONFIG_BUS_WIDTH_1_BIT; } /* set initial VDD, starting at the highest allowable voltage and working * our way down */ if (pHcd->SlotVoltageCaps & SLOT_POWER_3_3V) { OCRvalue = SD_OCR_3_2_TO_3_3_VDD; } else if (pHcd->SlotVoltageCaps & SLOT_POWER_3_0V) { OCRvalue = SD_OCR_2_9_TO_3_0_VDD; } else if (pHcd->SlotVoltageCaps & SLOT_POWER_2_8V) { OCRvalue = SD_OCR_2_7_TO_2_8_VDD; } else if (pHcd->SlotVoltageCaps & SLOT_POWER_2_0V) { OCRvalue = SD_OCR_1_9_TO_2_0_VDD; } else if (pHcd->SlotVoltageCaps & SLOT_POWER_1_8V) { OCRvalue = SD_OCR_1_7_TO_1_8_VDD; } else if (pHcd->SlotVoltageCaps & SLOT_POWER_1_6V) { OCRvalue = SD_OCR_1_6_TO_1_7_VDD; } else { DBG_ASSERT(FALSE); OCRvalue = 0; } do { /* power up the card */ status = AdjustSlotPower(pHcd, &OCRvalue); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to adjust slot power \n")); break; } status = SetOperationalBusMode(pHcd->pPseudoDev,&busMode); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus mode \n")); break; } status = _IssueConfig(pHcd,SDCONFIG_SEND_INIT_CLOCKS,&initClocks,sizeof(initClocks)); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to send init clocks in hcd \n")); break; } } while(FALSE); return status;}/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SDInitializeCard - initialize card Input: pHcd - HCD object Output: pProperties - card properties Return: Notes:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/SDIO_STATUS SDInitializeCard(PSDHCD pHcd){ SDCONFIG_BUS_MODE_DATA busMode; SDIO_STATUS status = SDIO_STATUS_SUCCESS; PSDREQUEST pReq = NULL; UINT32 OCRvalue; UINT32 tplAddr; UINT8 temp; struct SDIO_MANFID_TPL manfid; SDCONFIG_WP_VALUE wpValue; UINT8 cisBuffer[3]; OCRvalue = 0; do { if (IS_HCD_BUS_MODE_SPI(pHcd)) { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Initializing card in SPI mode \n")); } else { DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Initializing card in MMC/SD mode \n")); } pReq = AllocateRequest(); if (NULL == pReq) { status = SDIO_STATUS_NO_RESOURCES; DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: failed to allocate bus request \n")); break; } memset(pReq, 0, sizeof(SDREQUEST)); status = CardInitSetup(pHcd); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to setup card \n")); break; }#ifndef CT_CONFIG_NO_SDMMC status = _IssueConfig(pHcd,SDCONFIG_GET_WP,&wpValue,sizeof(wpValue)); if (!SDIO_SUCCESS(status)) { DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: host doesn't support Write Protect \n")); } else { if (wpValue) { pHcd->CardProperties.Flags |= CARD_SD_WP; DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: SD WP switch is on \n")); } }#endif if (!(pHcd->Attributes & SDHCD_ATTRIB_SLOT_POLLING) && IS_HCD_BUS_MODE_SPI(pHcd)) { /* for non-slot polling HCDs operating in SPI mode * issue CMD0 to reset card state and to place the card * in SPI mode. If slot polling is used, the polling thread * will have already issued a CMD0 to place the card in SPI mode*/ if (IS_HC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -