static int sd_select_driver_type(struct mmc_card *card, u8 *status) { int host_drv_type = 0, card_drv_type = 0; int err; /* * If the host doesn't support any of the Driver Types A,C or D, * default Driver Type B is used. */ if (!(card->host->caps & (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C | MMC_CAP_DRIVER_TYPE_D))) return 0; if (card->host->caps & MMC_CAP_DRIVER_TYPE_A) { host_drv_type = MMC_SET_DRIVER_TYPE_A; if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A) card_drv_type = MMC_SET_DRIVER_TYPE_A; else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B) card_drv_type = MMC_SET_DRIVER_TYPE_B; else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C) card_drv_type = MMC_SET_DRIVER_TYPE_C; } else if (card->host->caps & MMC_CAP_DRIVER_TYPE_C) { host_drv_type = MMC_SET_DRIVER_TYPE_C; if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C) card_drv_type = MMC_SET_DRIVER_TYPE_C; } else if (!(card->host->caps & MMC_CAP_DRIVER_TYPE_D)) { /* * If we are here, that means only the default driver type * B is supported by the host. */ host_drv_type = MMC_SET_DRIVER_TYPE_B; if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B) card_drv_type = MMC_SET_DRIVER_TYPE_B; else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C) card_drv_type = MMC_SET_DRIVER_TYPE_C; } err = mmc_sd_switch(card, 1, 2, card_drv_type, status); if (err) return err; if ((status[15] & 0xF) != card_drv_type) { printk(KERN_WARNING "%s: Problem setting driver strength!\n", mmc_hostname(card->host)); return 0; } mmc_set_driver_type(card->host, host_drv_type); return 0; }
static int sd_select_driver_type(struct mmc_card *card, u8 *status) { int host_drv_type = SD_DRIVER_TYPE_B; int card_drv_type = SD_DRIVER_TYPE_B; int drive_strength; int err; /* * If the host doesn't support any of the Driver Types A,C or D, * or there is no board specific handler then default Driver * Type B is used. */ if (!(card->host->caps & (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C | MMC_CAP_DRIVER_TYPE_D))) return 0; if (!card->host->ops->select_drive_strength) return 0; if (card->host->caps & MMC_CAP_DRIVER_TYPE_A) host_drv_type |= SD_DRIVER_TYPE_A; if (card->host->caps & MMC_CAP_DRIVER_TYPE_C) host_drv_type |= SD_DRIVER_TYPE_C; if (card->host->caps & MMC_CAP_DRIVER_TYPE_D) host_drv_type |= SD_DRIVER_TYPE_D; if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A) card_drv_type |= SD_DRIVER_TYPE_A; if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C) card_drv_type |= SD_DRIVER_TYPE_C; if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_D) card_drv_type |= SD_DRIVER_TYPE_D; /* * The drive strength that the hardware can support * depends on the board design. Pass the appropriate * information and let the hardware specific code * return what is possible given the options */ drive_strength = card->host->ops->select_drive_strength( card->sw_caps.uhs_max_dtr, host_drv_type, card_drv_type); err = mmc_sd_switch(card, 1, 2, drive_strength, status); if (err) return err; if ((status[15] & 0xF) != drive_strength) { printk(KERN_WARNING "%s: Problem setting drive strength!\n", mmc_hostname(card->host)); return 0; } mmc_set_driver_type(card->host, drive_strength); return 0; }