⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdio_bus_misc.c

📁 linux下的SDIO 驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    UINT32                             tplAddr;    struct SDIO_FUNC_EXT_COMMON_TPL    func0ext;    UINT8                              scrRegister[SD_SCR_BYTES];    SD_BUSCLOCK_RATE                   cardReportedRate = 0;    PSDREQUEST                         pReq = NULL;    BOOL                               spiMode = FALSE;    if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_SPI) {        spiMode = TRUE;    }    if (!spiMode) {            /* set highest bus mode bus driver is allowing (non-SPI), the code below will               * adjust to lower or equal settings */        pBusMode->BusModeFlags = pBusContext->DefaultBusMode;    }        /* set operational parameters */    pBusMode->ClockRate = pBusContext->DefaultOperClock;    pHcd->CardProperties.OperBlockLenLimit = pBusContext->DefaultOperBlockLen;    pHcd->CardProperties.OperBlockCountLimit = pBusContext->DefaultOperBlockCount;        /* adjust operational block counts and length to match HCD */    ADJUST_OPER_BLOCK_LEN(&pHcd->CardProperties,pHcd->MaxBytesPerBlock);    ADJUST_OPER_BLOCK_COUNT(&pHcd->CardProperties,pHcd->MaxBlocksPerTrans);        /* limit operational clock to the max clock rate */    ADJUST_OPER_CLOCK(pBusMode,pHcd->MaxClockRate);    if (!spiMode) {            /* check HCD bus mode */        if (!(pHcd->Attributes & SDHCD_ATTRIB_BUS_4BIT) ||            ((pHcd->CardProperties.Flags & CARD_SDIO) &&             (pHcd->Attributes & SDHCD_ATTRIB_NO_4BIT_IRQ)) ) {            if (pHcd->Attributes & SDHCD_ATTRIB_BUS_4BIT) {                DBG_PRINT(SDDBG_WARN,                ("SDIO Card Detected, but host does not support IRQs in 4 bit mode - dropping to 1 bit. \n"));            }                /* force to 1 bit mode */            SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);        }    }        /* now do various card inquiries to drop the bus mode or clock         * none of these checks can raise the bus mode or clock higher that what         * was initialized above */    do {#ifndef CT_CONFIG_NO_SDMMC        if (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC)) {                /* allocate a request for response data we'll need */            pReq = AllocateRequest();            if (NULL == pReq) {                status = SDIO_STATUS_NO_RESOURCES;                break;            }        }        if (!spiMode && (pHcd->CardProperties.Flags & CARD_MMC)) {                /* MMC cards all run in 1 bit mode */            SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);        }        if (pHcd->CardProperties.Flags & CARD_SD) {            DBG_ASSERT(pReq != NULL);            DBG_PRINT(SDDBG_TRACE, ("Getting SCR from SD Card..\n"));                /* read SCR (requires data transfer) to get supported modes */            status = _IssueBusRequestBd(pHcd,ACMD51,0,                                        SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_APP_CMD |                                        SDREQ_FLAGS_DATA_TRANS,                                        pReq,&scrRegister,SD_SCR_BYTES);            if (!SDIO_SUCCESS(status)) {                DBG_PRINT(SDDBG_WARN, ("SD card does not have SCR. \n"));                if (!spiMode) {                        /* switch it to 1 bit mode */                    SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);                }                status = SDIO_STATUS_SUCCESS;            } else {                    /* we have to reorder this buffer since the SCR is sent MSB first on the data                     * data bus */                ReorderBuffer(scrRegister,SD_SCR_BYTES);                    /* got the SCR */                DBG_PRINT(SDDBG_TRACE, ("SD SCR StructRev:0x%X, Flags:0x%X \n",                        GET_SD_SCR_STRUCT_VER(scrRegister),                        GET_SD_SCR_BUSWIDTHS_FLAGS(scrRegister)));                    /* set the revision */                switch (GET_SD_SCR_SDSPEC_VER(scrRegister)) {                    case SCR_SD_SPEC_1_00:                        DBG_PRINT(SDDBG_TRACE, ("SD Spec Revision 1.01 \n"));                        pHcd->CardProperties.SD_MMC_Revision = SD_REVISION_1_01;                        break;                    case SCR_SD_SPEC_1_10:                        DBG_PRINT(SDDBG_TRACE, ("SD Spec Revision 1.10 \n"));                        pHcd->CardProperties.SD_MMC_Revision = SD_REVISION_1_10;                        break;                    default:                        DBG_PRINT(SDDBG_WARN, ("SD Spec Revision is greater than 1.10 \n"));                        pHcd->CardProperties.SD_MMC_Revision = SD_REVISION_1_10;                        break;                }                if (!(GET_SD_SCR_BUSWIDTHS(scrRegister) & SCR_BUS_SUPPORTS_4_BIT)) {                    if (!spiMode) {                        DBG_PRINT(SDDBG_WARN, ("SD SCR reports 1bit only Mode \n"));                            /* switch it to 1 bit mode */                        SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);                    }                }            }        }        if (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC)) {            DBG_ASSERT(pReq != NULL);                /* de-select the card in order to get the CSD */            status = SelectDeselectCard(pHcd,FALSE);            if (!SDIO_SUCCESS(status)) {                DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to deselect card before getting CSD \n"));                break;            }                /* Get CSD for SD or MMC cards */            if (spiMode) {                    /* in SPI mode, getting the CSD requires a read data transfer */                status = _IssueBusRequestBd(pHcd,CMD9,0,                                            SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,                                            pReq,                                            pHcd->CardProperties.CardCSD,                                            MAX_CSD_CID_BYTES);                if (SDIO_SUCCESS(status)) {                        /* when the CSD is sent over in SPI data mode, it comes to us in MSB first                         * and thus is not ordered correctly as defined in the SD spec */                    ReorderBuffer(pHcd->CardProperties.CardCSD,MAX_CSD_CID_BYTES);                }            } else {                status = _IssueSimpleBusRequest(pHcd,                                                CMD9,                                                (pHcd->CardProperties.RCA << 16),                                                SDREQ_FLAGS_RESP_R2,                                                pReq);                if (SDIO_SUCCESS(status)) {                        /* save the CSD */                    memcpy(pHcd->CardProperties.CardCSD,pReq->Response,MAX_CARD_RESPONSE_BYTES);                }            }            if (!SDIO_SUCCESS(status)) {                DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get CSD, Err:%d \n",                                        status));                break;            }                /* for MMC cards, the spec version is in the CSD */            if (pHcd->CardProperties.Flags & CARD_MMC) {                DBG_PRINT(SDDBG_TRACE, ("MMC Spec version : (0x%2.2X) \n",                            GET_MMC_SPEC_VERSION(pHcd->CardProperties.CardCSD)));                switch (GET_MMC_SPEC_VERSION(pHcd->CardProperties.CardCSD)) {                    case MMC_SPEC_1_0_TO_1_2:                    case MMC_SPEC_1_4:                    case MMC_SPEC_2_0_TO_2_2:                        DBG_PRINT(SDDBG_WARN, ("MMC Spec version less than 3.1 \n"));                        pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_1_0_2_2;                        break;                    case MMC_SPEC_3_1:                        DBG_PRINT(SDDBG_TRACE, ("MMC Spec version 3.1 \n"));                        pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_3_1;                        break;                    case MMC_SPEC_4_0_TO_4_1:                        DBG_PRINT(SDDBG_TRACE, ("MMC Spec version 4.0-4.1 \n"));                        pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_4_0;                        break;                    default:                        pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_3_1;                        DBG_PRINT(SDDBG_WARN, ("MMC Spec version greater than 4.1\n"));                        break;                }            }                /* re-select the card  */            status = SelectDeselectCard(pHcd,TRUE);            if (!SDIO_SUCCESS(status)) {                DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to re-select card after getting CSD \n"));                break;            }        }#endif // CT_CONFIG_NO_SDMMC#ifndef CT_CONFIG_NO_SDMMC        if ((pHcd->CardProperties.Flags & CARD_SD) &&            !(pHcd->CardProperties.Flags & CARD_SDIO) &&             SDDEVICE_IS_SD_REV_GTEQ_1_10(pHcd->pPseudoDev) &&             (pHcd->Attributes & SDHCD_ATTRIB_SD_HIGH_SPEED) &&             !spiMode)  {            UINT32 arg;            PUINT8 pSwitchStatusBlock = KernelAlloc(SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);            if (NULL == pSwitchStatusBlock) {                status = SDIO_STATUS_NO_RESOURCES;                break;            }            arg = SD_SWITCH_FUNC_ARG_GROUP_CHECK(SD_SWITCH_HIGH_SPEED_GROUP,                                                 SD_SWITCH_HIGH_SPEED_FUNC_NO);                /* for 1.10 SD cards, check if high speed mode is supported */            DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Checking SD Card for switchable functions (CMD6 arg:0x%X)\n",arg));                /* issue simple data transfer request to read the switch status */            status = _IssueBusRequestBd(pHcd,                                        CMD6,                                        arg,                                        SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,                                        pReq,                                        pSwitchStatusBlock,                                        SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);            if (SDIO_SUCCESS(status)) {                UINT16 switchGroupMask;                    /* need to reorder this since cards send this MSB first */                ReorderBuffer(pSwitchStatusBlock,SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);                switchGroupMask = SD_SWITCH_FUNC_STATUS_GET_GRP_BIT_MASK(pSwitchStatusBlock,SD_SWITCH_HIGH_SPEED_GROUP);                DBG_PRINT(SDDBG_TRACE, ("SD Card Switch Status Group1 Mask:0x%X Max Current:%d\n",                        switchGroupMask, SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock) ));                if (SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock) == 0) {                    DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: SD Switch Status block has zero max current \n"));                    SDLIB_PrintBuffer(pSwitchStatusBlock,                                      SD_SWITCH_FUNC_STATUS_BLOCK_BYTES,                                      "SDIO Bus Driver: SD Switch Status Block Error");                } else {                        /* check HS support */                    if (switchGroupMask & (1 << SD_SWITCH_HIGH_SPEED_FUNC_NO)) {                        DBG_PRINT(SDDBG_TRACE, ("SD Card Supports High Speed Mode\n"));                            /* set the rate, this will override the CSD value */                        cardReportedRate = SD_HS_MAX_BUS_CLOCK;                        pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_SD_HS;                    }                }            } else {                DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get SD Switch Status block (%d)\n", status));                    /* just fall through, we'll handle this like a normal SD card */                status = SDIO_STATUS_SUCCESS;            }            KernelFree(pSwitchStatusBlock);        }#endif // CT_CONFIG_NO_SDMMC#ifndef CT_CONFIG_NO_SDMMC        if ((pHcd->CardProperties.Flags & CARD_MMC) &&             SDDEVICE_IS_MMC_REV_GTEQ_4_0(pHcd->pPseudoDev) &&             (pHcd->Attributes & SDHCD_ATTRIB_MMC_HIGH_SPEED) &&             !spiMode)  {                /* for MMC cards, get the Extended CSD to get the High speed and                 * wide bus paramaters */            PUINT8 pExtData = KernelAlloc(MMC_EXT_CSD_SIZE);            if (NULL == pExtData) {                status = SDIO_STATUS_NO_RESOURCES;                break;            }                /* issue simple data transfer request to read the extended CSD */            status = _IssueBusRequestBd(pHcd,MMC_CMD8,0,                                        SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,                                        pReq,                                        pExtData,                                        MMC_EXT_CSD_SIZE);            if (SDIO_SUCCESS(status)) {                 DBG_PRINT(SDDBG_TRACE, ("MMC Ext CSD Version: 0x%X Card Type: 0x%X\n",                        pExtData[MMC_EXT_VER_OFFSET],pExtData[MMC_EXT_CARD_TYPE_OFFSET]));                    /* check HS support */                if (pExtData[MMC_EXT_CARD_TYPE_OFFSET] & MMC_EXT_CARD_TYPE_HS_52) {                        /* try 52 Mhz */                    cardReportedRate = 52000000;                    pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_MMC_HS;                } else if (pExtData[MMC_EXT_CARD_TYPE_OFFSET] & MMC_EXT_CARD_TYPE_HS_26) {                        /* try 26MHZ */                    cardReportedRate = 26000000;                    pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_MMC_HS;                } else {                        /* doesn't report high speed capable */                    cardReportedRate = 0;                }                if (cardReportedRate && !spiMode) {                        /* figure out the bus mode */                    if (pHcd->Attributes & SDHCD_ATTRIB_BUS_MMC8BIT) {                        SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_MMC8_BIT);                    } else if (pHcd->Attributes & SDHCD_ATTRIB_BUS_4BIT) {                        SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_4_BIT);                    } else {                        /* we leave it to default to 1 bit mode */                    }                }            } else {                DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get MMC Extended CSD \n"));                    /* just fall through, we'll do without the extended information                     * and run it like a legacy MMC card */                status = SDIO_STATUS_SUCCESS;            }            KernelFree(pExtData);        }#endif // CT_CONFIG_NO_SDMMC#ifndef CT_CONFIG_NO_SDMMC

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -