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

📄 sdio_bus_misc.c

📁 linux下的SDIO 驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC)) {            if (0 == cardReportedRate) {                    /* extract rate from CSD only if it was not set by earlier tests */                cardReportedRate = ConvertEncodedTransSpeed(                                GET_SD_CSD_TRANS_SPEED(pHcd->CardProperties.CardCSD));                    /* fall through and test for zero again */            }            if (cardReportedRate != 0) {                     /* adjust clock based on what the card can handle */                ADJUST_OPER_CLOCK(pBusMode,cardReportedRate);            } else {#ifdef DEBUG                    /* something is wrong with the CSD */                if (DBG_GET_DEBUG_LEVEL() >= SDDBG_TRACE) {                    SDLIB_PrintBuffer(pHcd->CardProperties.CardCSD,                                      MAX_CARD_RESPONSE_BYTES,                                      "SDIO Bus Driver: CSD Dump");                }#endif                    /* can't figure out the card rate, so set reasonable defaults */                if (pHcd->CardProperties.Flags & CARD_SD) {                    ADJUST_OPER_CLOCK(pBusMode,SD_MAX_BUS_CLOCK);                } else {                    ADJUST_OPER_CLOCK(pBusMode,MMC_MAX_BUS_CLOCK);                }            }        }#endif // CT_CONFIG_NO_SDMMC            /* note, we do SDIO card "after" SD in case this is a combo card */        if (pHcd->CardProperties.Flags & CARD_SDIO) {                /* read card capabilities */            status = Cmd52ReadByteCommon(pHcd->pPseudoDev,                                         SDIO_CARD_CAPS_REG,                                         &pHcd->CardProperties.SDIOCaps);            if (!SDIO_SUCCESS(status)) {                break;            }            DBG_PRINT(SDDBG_TRACE, ("SDIO Card Caps: 0x%X \n",pHcd->CardProperties.SDIOCaps));            if (pHcd->CardProperties.SDIOCaps & SDIO_CAPS_LOW_SPEED) {                    /* adjust max clock for LS device */                ADJUST_OPER_CLOCK(pBusMode,SDIO_LOW_SPEED_MAX_BUS_CLOCK);                    /* adjust bus if LS device does not support 4 bit mode */                if (!(pHcd->CardProperties.SDIOCaps & SDIO_CAPS_4BIT_LS)) {                    if (!spiMode) {                            /* low speed device does not support 4 bit mode, force us to 1 bit */                        SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags,                                               SDCONFIG_BUS_WIDTH_1_BIT);                    }                }            }                /* check if 1.2 card supports high speed mode, checking HCD as well*/            if (SDDEVICE_IS_SDIO_REV_GTEQ_1_20(pHcd->pPseudoDev) &&                (pHcd->Attributes & SDHCD_ATTRIB_SD_HIGH_SPEED) &&                !spiMode) {                UCHAR hsControl = 0;                status = Cmd52ReadByteCommon(pHcd->pPseudoDev,                                             SDIO_HS_CONTROL_REG,                                             &hsControl);                if (!SDIO_SUCCESS(status)) {                    DBG_PRINT(SDDBG_TRACE,                        ("SDIO Failed to read high speed control (%d) \n",status));                        /* reset status and continue */                    status = SDIO_STATUS_SUCCESS;                } else {                    if (hsControl & SDIO_HS_CONTROL_SHS) {                        DBG_PRINT(SDDBG_TRACE, ("SDIO Card Supports High Speed Mode\n"));                        pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_SD_HS;                    }                }            }            cardReportedRate = 0;            temp = sizeof(func0ext);            tplAddr = pHcd->CardProperties.CommonCISPtr;                /* get the FUNCE tuple */            status = SDLIB_FindTuple(pHcd->pPseudoDev,                                     CISTPL_FUNCE,                                     &tplAddr,                                     (PUINT8)&func0ext,                                     &temp);            if (!SDIO_SUCCESS(status) || (temp < sizeof(func0ext))) {                DBG_PRINT(SDDBG_WARN, ("SDIO Function 0 Ext. Tuple Missing (Got size:%d) \n", temp));                    /* reset status */                status = SDIO_STATUS_SUCCESS;            } else {                    /* convert encoded value to rate */                cardReportedRate = ConvertEncodedTransSpeed(func0ext.MaxTransSpeed);            }            if (cardReportedRate != 0) {                if (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) {                    if (cardReportedRate <= SD_MAX_BUS_CLOCK) {                        DBG_PRINT(SDDBG_WARN,                            ("SDIO Function tuple reports clock:%d Hz, with advertised High Speed support \n", cardReportedRate));                            /* back off high speed support */                        pBusMode->BusModeFlags &= ~SDCONFIG_BUS_MODE_SD_HS;                    }                } else {                    if (cardReportedRate > SD_MAX_BUS_CLOCK) {                        DBG_PRINT(SDDBG_WARN,                            ("SDIO Function tuple reports clock:%d Hz, without advertising High Speed support..using 25Mhz \n", cardReportedRate));                        cardReportedRate = SD_MAX_BUS_CLOCK;                    }                }                    /* adjust clock based on what the card can handle */                ADJUST_OPER_CLOCK(pBusMode,cardReportedRate);            } else {                    /* set a reasonable default */                ADJUST_OPER_CLOCK(pBusMode,SD_MAX_BUS_CLOCK);            }        }    } while (FALSE);    if (pReq != NULL) {        FreeRequest(pReq);    }    return status;}/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  SetOperationalBusMode - set operational bus mode  Input:  pDevice - pDevice that is requesting the change          pBusMode - operational bus mode  Output: pBusMode - on return will have the actual clock rate set  Return: status  Notes:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/SDIO_STATUS SetOperationalBusMode(PSDDEVICE                pDevice,                                  PSDCONFIG_BUS_MODE_DATA  pBusMode){    SDIO_STATUS     status = SDIO_STATUS_SUCCESS;    UCHAR           regData;    UINT32          arg;    UINT32          switcharg;    PSDHCD          pHcd = pDevice->pHcd;        /* synchronize access for updating bus mode settings */    status = SemaphorePendInterruptable(&pDevice->pHcd->ConfigureOpsSem);    if (!SDIO_SUCCESS(status)) {        return status;    }    do {        if (!IS_CARD_PRESENT(pHcd)) {                /* for an empty slot (a Pseudo dev was passed in) we still allow the                 * bus mode to be set for the card detect                 * polling */            status = _IssueConfig(pHcd,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));            }                /* nothing more to do */            break;        }        if ((pBusMode->BusModeFlags == SDDEVICE_GET_BUSMODE_FLAGS(pDevice)) &&            (pBusMode->ClockRate == SDDEVICE_GET_OPER_CLOCK(pDevice))) {            DBG_PRINT(SDDBG_TRACE,               ("SDIO Bus Driver: Bus mode already set, nothing to do\n"));            pBusMode->ActualClockRate = SDDEVICE_GET_OPER_CLOCK(pDevice);            break;        }#ifndef CT_CONFIG_NO_SDMMC        if (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_MMC_HS) {            if (!(pHcd->Attributes & SDHCD_ATTRIB_MMC_HIGH_SPEED)) {                status = SDIO_STATUS_INVALID_PARAMETER;                DBG_PRINT(SDDBG_ERROR,                        ("SDIO Bus Driver: HCD does not support MMC High Speed\n"));                break;            }        }#endif        if (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) {            if (!(pHcd->Attributes & SDHCD_ATTRIB_SD_HIGH_SPEED)) {                status = SDIO_STATUS_INVALID_PARAMETER;                DBG_PRINT(SDDBG_ERROR,                        ("SDIO Bus Driver: HCD does not support SD High Speed\n"));                break;            }        }#ifndef CT_CONFIG_NO_SDMMC            /* before we set the operational clock and mode, configure the clock for high             * speed mode on the card , if necessary */        if ((pHcd->CardProperties.Flags & CARD_MMC) &&            (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_MMC_HS) &&            !(SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_MMC_HS)) {            switcharg = MMC_SWITCH_BUILD_ARG(MMC_SWITCH_CMD_SET0,                                             MMC_SWITCH_WRITE_BYTE,                                             MMC_EXT_HS_TIMING_OFFSET,                                             MMC_EXT_HS_TIMING_ENABLE);            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 switch MMC High Speed Mode (arg:0x%X): %d \n",                                        switcharg, status));                break;            }            DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: High Speed MMC enabled (arg:0x%X)\n",                switcharg));        }#endif#ifndef CT_CONFIG_NO_SDMMC            /* before setting bus mode and clock in the HCD, switch card to high speed mode             * if necessary */        if ((pHcd->CardProperties.Flags & CARD_SD) &&            (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) &&            !(SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_SD_HS)) {            UINT32     arg;            PUINT8     pSwitchStatusBlock;            pSwitchStatusBlock = KernelAlloc(SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);            if (NULL == pSwitchStatusBlock) {                status = SDIO_STATUS_NO_RESOURCES;                break;            }                /* set high speed group */            arg = SD_SWITCH_FUNC_ARG_GROUP_SET(SD_SWITCH_HIGH_SPEED_GROUP,                                               SD_SWITCH_HIGH_SPEED_FUNC_NO);            DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Setting SD Card for High Speed mode (CMD6 arg:0x%X)\n",arg));                /* issue simple data transfer request to switch modes */            status = _IssueBusRequestBd(pHcd,                                        CMD6,                                        arg,                                        SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,                                        NULL,                                        pSwitchStatusBlock,                                        SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);            if (SDIO_SUCCESS(status)) {                ReorderBuffer(pSwitchStatusBlock,SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);                DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD High Speed Result, Got Max Current:%d mA, SwitchResult:0x%X \n",                      SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock),                      SDSwitchGetSwitchResult(pSwitchStatusBlock, SD_SWITCH_HIGH_SPEED_GROUP)));                if (SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock) == 0) {                    DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Error in Status Block after High Speed Switch (current==0) \n"));                    status = SDIO_STATUS_DEVICE_ERROR;                }                if (SDSwitchGetSwitchResult(pSwitchStatusBlock, SD_SWITCH_HIGH_SPEED_GROUP) !=                    SD_SWITCH_HIGH_SPEED_FUNC_NO) {                    DBG_PRINT(SDDBG_ERROR,                        ("SDIO Bus Driver: Error in Status Block after High Speed Switch (Group1 did not switch) \n"));                    status = SDIO_STATUS_DEVICE_ERROR;                }                if (SDIO_SUCCESS(status)) {                    DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD High Speed Mode Enabled \n"));                } else {                    SDLIB_PrintBuffer(pSwitchStatusBlock,                                      SD_SWITCH_FUNC_STATUS_BLOCK_BYTES,                                       "SDIO Bus Driver: SD Switch Status Block Error");                }            } else {                DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to Set SD High Speed Mode (%d) \n",status));            }            KernelFree(pSwitchStatusBlock);            if (!SDIO_SUCCESS(status)) {                break;            }        }#endif            /* enable/disable high speed mode for SDIO card */        if (pHcd->CardProperties.Flags & CARD_SDIO) {            BOOL doSet = TRUE;            if ((pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) &&                !(SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_SD_HS)) {                    /* enable */                regData = SDIO_HS_CONTROL_EHS;            } else if (!(pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) &&                       (SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_SD_HS)) {                    /* disable */                regData = 0;            } else {                    /* do nothing */                doSet = FALSE;            }

⌨️ 快捷键说明

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