On Thu, May 5, 2011 at 2:48 AM, Arindam Nath <arindam.nath@xxxxxxx> wrote: > Host Controller v3.00 adds another Capabilities register. Apart > from other things, this new register indicates whether the Host > Controller supports SDR50, SDR104, and DDR50 UHS-I modes. The spec > doesn't mention about explicit support for SDR12 and SDR25 UHS-I > modes, so the Host Controller v3.00 should support them by default. > Also if the controller supports SDR104 mode, it will also support > SDR50 mode as well. So depending on the host support, we set the > corresponding MMC_CAP_* flags. One more new register. Host Control2 > is added in v3.00, which is used during Signal Voltage Switch > procedure described below. > > Since as per v3.00 spec, UHS-I supported hosts should set S18R > to 1, we set S18R (bit 24) of OCR before sending ACMD41. We also > need to set XPC (bit 28) of OCR in case the host can supply >150mA. > This support is indicated by the Maximum Current Capabilities > register of the Host Controller. > > If the response of ACMD41 has both CCS and S18A set, we start the > signal voltage switch procedure, which if successfull, will switch > the card from 3.3V signalling to 1.8V signalling. Signal voltage > switch procedure adds support for a new command CMD11 in the > Physical Layer Spec v3.01. As part of this procedure, we need to > set 1.8V Signalling Enable (bit 3) of Host Control2 register, which > if remains set after 5ms, means the switch to 1.8V signalling is > successfull. Otherwise, we clear bit 24 of OCR and retry the > initialization sequence. When we remove the card, and insert the > same or another card, we need to make sure that we start with 3.3V > signalling voltage. So we call mmc_set_signal_voltage() with > MMC_SIGNAL_VOLTAGE_330 set so that we are back to 3.3V signalling > voltage before we actually start initializing the card. > > Signed-off-by: Arindam Nath <arindam.nath@xxxxxxx> > Reviewed-by: Philip Rakity <prakity@xxxxxxxxxxx> > Tested-by: Philip Rakity <prakity@xxxxxxxxxxx> Acked-by: Zhangfei Gao<zhangfei.gao@xxxxxxxxxxx> Verified with Toshiba uhs card and general hs card, on mmp2 in SDMA mode. > --- > drivers/mmc/core/core.c | 34 ++++++++ > drivers/mmc/core/core.h | 1 + > drivers/mmc/core/sd.c | 36 ++++++++- > drivers/mmc/host/sdhci.c | 193 ++++++++++++++++++++++++++++++++++++++++++--- > drivers/mmc/host/sdhci.h | 18 ++++- > include/linux/mmc/host.h | 15 ++++ > include/linux/mmc/sd.h | 7 ++ > 7 files changed, 287 insertions(+), 17 deletions(-) > > diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c > index 1dbc185..ea5c28d 100644 > --- a/drivers/mmc/core/core.c > +++ b/drivers/mmc/core/core.c > @@ -942,6 +942,40 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) > return ocr; > } > > +int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) > +{ > + struct mmc_command cmd; > + int err = 0; > + > + BUG_ON(!host); > + > + /* > + * Send CMD11 only if the request is to switch the card to > + * 1.8V signalling. > + */ > + if (signal_voltage == MMC_SIGNAL_VOLTAGE_180) { > + memset(&cmd, 0, sizeof(struct mmc_command)); > + > + cmd.opcode = SD_SWITCH_VOLTAGE; > + cmd.arg = 0; > + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; > + > + err = mmc_wait_for_cmd(host, &cmd, 0); > + if (err) > + return err; > + > + if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) > + return -EIO; > + } > + > + host->ios.signal_voltage = signal_voltage; > + > + if (host->ops->start_signal_voltage_switch) > + err = host->ops->start_signal_voltage_switch(host, &host->ios); > + > + return err; > +} > + > /* > * Select timing parameters for host. > */ > diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h > index ca1fdde..7745dea 100644 > --- a/drivers/mmc/core/core.h > +++ b/drivers/mmc/core/core.h > @@ -41,6 +41,7 @@ void mmc_set_bus_width(struct mmc_host *host, unsigned int width); > void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width, > unsigned int ddr); > u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); > +int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); > void mmc_set_timing(struct mmc_host *host, unsigned int timing); > > static inline void mmc_delay(unsigned int ms) > diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c > index 6dac89f..b0cd285 100644 > --- a/drivers/mmc/core/sd.c > +++ b/drivers/mmc/core/sd.c > @@ -403,6 +403,7 @@ struct device_type sd_type = { > int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) > { > int err; > + u32 rocr; > > /* > * Since we're changing the OCR value, we seem to > @@ -420,12 +421,38 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid) > */ > err = mmc_send_if_cond(host, ocr); > if (!err) > - ocr |= 1 << 30; > + ocr |= SD_OCR_CCS; > > - err = mmc_send_app_op_cond(host, ocr, NULL); > + /* > + * If the host supports one of UHS-I modes, request the card > + * to switch to 1.8V signaling level. > + */ > + if (host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | > + MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)) > + ocr |= SD_OCR_S18R; > + > + /* If the host can supply more than 150mA, XPC should be set to 1. */ > + if (host->caps & (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 | > + MMC_CAP_SET_XPC_180)) > + ocr |= SD_OCR_XPC; > + > +try_again: > + err = mmc_send_app_op_cond(host, ocr, &rocr); > if (err) > return err; > > + /* > + * In case CCS and S18A in the response is set, start Signal Voltage > + * Switch procedure. SPI mode doesn't support CMD11. > + */ > + if (!mmc_host_is_spi(host) && ((rocr & 0x41000000) == 0x41000000)) { > + err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); > + if (err) { > + ocr &= ~SD_OCR_S18R; > + goto try_again; > + } > + } > + > if (mmc_host_is_spi(host)) > err = mmc_send_cid(host, cid); > else > @@ -773,6 +800,11 @@ int mmc_attach_sd(struct mmc_host *host) > BUG_ON(!host); > WARN_ON(!host->claimed); > > + /* Make sure we are at 3.3V signalling voltage */ > + err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); > + if (err) > + return err; > + > err = mmc_send_app_op_cond(host, 0, &ocr); > if (err) > return err; > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c > index e5cfe70..52faa50 100644 > --- a/drivers/mmc/host/sdhci.c > +++ b/drivers/mmc/host/sdhci.c > @@ -83,6 +83,8 @@ static void sdhci_dumpregs(struct sdhci_host *host) > printk(KERN_DEBUG DRIVER_NAME ": Cmd: 0x%08x | Max curr: 0x%08x\n", > sdhci_readw(host, SDHCI_COMMAND), > sdhci_readl(host, SDHCI_MAX_CURRENT)); > + printk(KERN_DEBUG DRIVER_NAME ": Host ctl2: 0x%08x\n", > + sdhci_readw(host, SDHCI_HOST_CONTROL2)); > > if (host->flags & SDHCI_USE_ADMA) > printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n", > @@ -1323,11 +1325,115 @@ out: > spin_unlock_irqrestore(&host->lock, flags); > } > > +static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, > + struct mmc_ios *ios) > +{ > + struct sdhci_host *host; > + u8 pwr; > + u16 clk, ctrl; > + u32 present_state; > + > + host = mmc_priv(mmc); > + > + /* > + * Signal Voltage Switching is only applicable for Host Controllers > + * v3.00 and above. > + */ > + if (host->version < SDHCI_SPEC_300) > + return 0; > + > + /* > + * We first check whether the request is to set signalling voltage > + * to 3.3V. If so, we change the voltage to 3.3V and return quickly. > + */ > + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); > + if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) { > + /* Set 1.8V Signal Enable in the Host Control2 register to 0 */ > + ctrl &= ~SDHCI_CTRL_VDD_180; > + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); > + > + /* Wait for 5ms */ > + usleep_range(5000, 5500); > + > + /* 3.3V regulator output should be stable within 5 ms */ > + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); > + if (!(ctrl & SDHCI_CTRL_VDD_180)) > + return 0; > + else { > + printk(KERN_INFO DRIVER_NAME ": Switching to 3.3V " > + "signalling voltage failed\n"); > + return -EIO; > + } > + } else if (!(ctrl & SDHCI_CTRL_VDD_180) && > + (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) { > + /* Stop SDCLK */ > + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); > + clk &= ~SDHCI_CLOCK_CARD_EN; > + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); > + > + /* Check whether DAT[3:0] is 0000 */ > + present_state = sdhci_readl(host, SDHCI_PRESENT_STATE); > + if (!((present_state & SDHCI_DATA_LVL_MASK) >> > + SDHCI_DATA_LVL_SHIFT)) { > + /* > + * Enable 1.8V Signal Enable in the Host Control2 > + * register > + */ > + ctrl |= SDHCI_CTRL_VDD_180; > + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); > + > + /* Wait for 5ms */ > + usleep_range(5000, 5500); > + > + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); > + if (ctrl & SDHCI_CTRL_VDD_180) { > + /* Provide SDCLK again and wait for 1ms*/ > + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); > + clk |= SDHCI_CLOCK_CARD_EN; > + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); > + usleep_range(1000, 1500); > + > + /* > + * If DAT[3:0] level is 1111b, then the card > + * was successfully switched to 1.8V signaling. > + */ > + present_state = sdhci_readl(host, > + SDHCI_PRESENT_STATE); > + if ((present_state & SDHCI_DATA_LVL_MASK) == > + SDHCI_DATA_LVL_MASK) { > + return 0; > + } > + } > + } > + > + /* > + * If we are here, that means the switch to 1.8V signaling > + * failed. We power cycle the card, and retry initialization > + * sequence by setting S18R to 0. > + */ > + pwr = sdhci_readb(host, SDHCI_POWER_CONTROL); > + pwr &= ~SDHCI_POWER_ON; > + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); > + > + /* Wait for 1ms as per the spec */ > + usleep_range(1000, 1500); > + pwr |= SDHCI_POWER_ON; > + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); > + > + printk(KERN_INFO DRIVER_NAME ": Switching to 1.8V signalling " > + "voltage failed, retrying with S18R set to 0\n"); > + return -EAGAIN; > + } else > + /* No signal voltage switch required */ > + return 0; > +} > + > static const struct mmc_host_ops sdhci_ops = { > .request = sdhci_request, > .set_ios = sdhci_set_ios, > .get_ro = sdhci_get_ro, > .enable_sdio_irq = sdhci_enable_sdio_irq, > + .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, > }; > > /*****************************************************************************\ > @@ -1808,7 +1914,9 @@ EXPORT_SYMBOL_GPL(sdhci_alloc_host); > int sdhci_add_host(struct sdhci_host *host) > { > struct mmc_host *mmc; > - unsigned int caps, ocr_avail; > + u32 caps[2]; > + u32 max_current_caps; > + unsigned int ocr_avail; > int ret; > > WARN_ON(host == NULL); > @@ -1831,12 +1939,15 @@ int sdhci_add_host(struct sdhci_host *host) > host->version); > } > > - caps = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps : > + caps[0] = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps : > sdhci_readl(host, SDHCI_CAPABILITIES); > > + caps[1] = (host->version >= SDHCI_SPEC_300) ? > + sdhci_readl(host, SDHCI_CAPABILITIES_1) : 0; > + > if (host->quirks & SDHCI_QUIRK_FORCE_DMA) > host->flags |= SDHCI_USE_SDMA; > - else if (!(caps & SDHCI_CAN_DO_SDMA)) > + else if (!(caps[0] & SDHCI_CAN_DO_SDMA)) > DBG("Controller doesn't have SDMA capability\n"); > else > host->flags |= SDHCI_USE_SDMA; > @@ -1847,7 +1958,8 @@ int sdhci_add_host(struct sdhci_host *host) > host->flags &= ~SDHCI_USE_SDMA; > } > > - if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2)) > + if ((host->version >= SDHCI_SPEC_200) && > + (caps[0] & SDHCI_CAN_DO_ADMA2)) > host->flags |= SDHCI_USE_ADMA; > > if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) && > @@ -1897,10 +2009,10 @@ int sdhci_add_host(struct sdhci_host *host) > } > > if (host->version >= SDHCI_SPEC_300) > - host->max_clk = (caps & SDHCI_CLOCK_V3_BASE_MASK) > + host->max_clk = (caps[0] & SDHCI_CLOCK_V3_BASE_MASK) > >> SDHCI_CLOCK_BASE_SHIFT; > else > - host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK) > + host->max_clk = (caps[0] & SDHCI_CLOCK_BASE_MASK) > >> SDHCI_CLOCK_BASE_SHIFT; > > host->max_clk *= 1000000; > @@ -1916,7 +2028,7 @@ int sdhci_add_host(struct sdhci_host *host) > } > > host->timeout_clk = > - (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; > + (caps[0] & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; > if (host->timeout_clk == 0) { > if (host->ops->get_timeout_clock) { > host->timeout_clk = host->ops->get_timeout_clock(host); > @@ -1928,7 +2040,7 @@ int sdhci_add_host(struct sdhci_host *host) > return -ENODEV; > } > } > - if (caps & SDHCI_TIMEOUT_CLK_UNIT) > + if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT) > host->timeout_clk *= 1000; > > /* > @@ -1955,21 +2067,76 @@ int sdhci_add_host(struct sdhci_host *host) > if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) > mmc->caps |= MMC_CAP_4_BIT_DATA; > > - if (caps & SDHCI_CAN_DO_HISPD) > + if (caps[0] & SDHCI_CAN_DO_HISPD) > mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; > > if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) && > mmc_card_is_removable(mmc)) > mmc->caps |= MMC_CAP_NEEDS_POLL; > > + /* UHS-I mode(s) supported by the host controller. */ > + if (host->version >= SDHCI_SPEC_300) > + mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25; > + > + /* SDR104 supports also implies SDR50 support */ > + if (caps[1] & SDHCI_SUPPORT_SDR104) > + mmc->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50; > + else if (caps[1] & SDHCI_SUPPORT_SDR50) > + mmc->caps |= MMC_CAP_UHS_SDR50; > + > + if (caps[1] & SDHCI_SUPPORT_DDR50) > + mmc->caps |= MMC_CAP_UHS_DDR50; > + > ocr_avail = 0; > - if (caps & SDHCI_CAN_VDD_330) > + /* > + * According to SD Host Controller spec v3.00, if the Host System > + * can afford more than 150mA, Host Driver should set XPC to 1. Also > + * the value is meaningful only if Voltage Support in the Capabilities > + * register is set. The actual current value is 4 times the register > + * value. > + */ > + max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT); > + > + if (caps[0] & SDHCI_CAN_VDD_330) { > + int max_current_330; > + > ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34; > - if (caps & SDHCI_CAN_VDD_300) > + > + max_current_330 = ((max_current_caps & > + SDHCI_MAX_CURRENT_330_MASK) >> > + SDHCI_MAX_CURRENT_330_SHIFT) * > + SDHCI_MAX_CURRENT_MULTIPLIER; > + > + if (max_current_330 > 150) > + mmc->caps |= MMC_CAP_SET_XPC_330; > + } > + if (caps[0] & SDHCI_CAN_VDD_300) { > + int max_current_300; > + > ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31; > - if (caps & SDHCI_CAN_VDD_180) > + > + max_current_300 = ((max_current_caps & > + SDHCI_MAX_CURRENT_300_MASK) >> > + SDHCI_MAX_CURRENT_300_SHIFT) * > + SDHCI_MAX_CURRENT_MULTIPLIER; > + > + if (max_current_300 > 150) > + mmc->caps |= MMC_CAP_SET_XPC_300; > + } > + if (caps[0] & SDHCI_CAN_VDD_180) { > + int max_current_180; > + > ocr_avail |= MMC_VDD_165_195; > > + max_current_180 = ((max_current_caps & > + SDHCI_MAX_CURRENT_180_MASK) >> > + SDHCI_MAX_CURRENT_180_SHIFT) * > + SDHCI_MAX_CURRENT_MULTIPLIER; > + > + if (max_current_180 > 150) > + mmc->caps |= MMC_CAP_SET_XPC_180; > + } > + > mmc->ocr_avail = ocr_avail; > mmc->ocr_avail_sdio = ocr_avail; > if (host->ocr_avail_sdio) > @@ -2029,7 +2196,7 @@ int sdhci_add_host(struct sdhci_host *host) > if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) { > mmc->max_blk_size = 2; > } else { > - mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> > + mmc->max_blk_size = (caps[0] & SDHCI_MAX_BLOCK_MASK) >> > SDHCI_MAX_BLOCK_SHIFT; > if (mmc->max_blk_size >= 3) { > printk(KERN_WARNING "%s: Invalid maximum block size, " > diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h > index c6e25a7..5cba2fe 100644 > --- a/drivers/mmc/host/sdhci.h > +++ b/drivers/mmc/host/sdhci.h > @@ -68,6 +68,8 @@ > #define SDHCI_DATA_AVAILABLE 0x00000800 > #define SDHCI_CARD_PRESENT 0x00010000 > #define SDHCI_WRITE_PROTECT 0x00080000 > +#define SDHCI_DATA_LVL_MASK 0x00F00000 > +#define SDHCI_DATA_LVL_SHIFT 20 > > #define SDHCI_HOST_CONTROL 0x28 > #define SDHCI_CTRL_LED 0x01 > @@ -146,7 +148,8 @@ > > #define SDHCI_ACMD12_ERR 0x3C > > -/* 3E-3F reserved */ > +#define SDHCI_HOST_CONTROL2 0x3E > +#define SDHCI_CTRL_VDD_180 0x0008 > > #define SDHCI_CAPABILITIES 0x40 > #define SDHCI_TIMEOUT_CLK_MASK 0x0000003F > @@ -167,9 +170,20 @@ > #define SDHCI_CAN_VDD_180 0x04000000 > #define SDHCI_CAN_64BIT 0x10000000 > > +#define SDHCI_SUPPORT_SDR50 0x00000001 > +#define SDHCI_SUPPORT_SDR104 0x00000002 > +#define SDHCI_SUPPORT_DDR50 0x00000004 > + > #define SDHCI_CAPABILITIES_1 0x44 > > -#define SDHCI_MAX_CURRENT 0x48 > +#define SDHCI_MAX_CURRENT 0x48 > +#define SDHCI_MAX_CURRENT_330_MASK 0x0000FF > +#define SDHCI_MAX_CURRENT_330_SHIFT 0 > +#define SDHCI_MAX_CURRENT_300_MASK 0x00FF00 > +#define SDHCI_MAX_CURRENT_300_SHIFT 8 > +#define SDHCI_MAX_CURRENT_180_MASK 0xFF0000 > +#define SDHCI_MAX_CURRENT_180_SHIFT 16 > +#define SDHCI_MAX_CURRENT_MULTIPLIER 4 > > /* 4C-4F reserved for more max current */ > > diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h > index 0fffa5c..bde5a0b 100644 > --- a/include/linux/mmc/host.h > +++ b/include/linux/mmc/host.h > @@ -56,6 +56,11 @@ struct mmc_ios { > #define MMC_SDR_MODE 0 > #define MMC_1_2V_DDR_MODE 1 > #define MMC_1_8V_DDR_MODE 2 > + > + unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */ > + > +#define MMC_SIGNAL_VOLTAGE_330 0 > +#define MMC_SIGNAL_VOLTAGE_180 1 > }; > > struct mmc_host_ops { > @@ -117,6 +122,8 @@ struct mmc_host_ops { > > /* optional callback for HC quirks */ > void (*init_card)(struct mmc_host *host, struct mmc_card *card); > + > + int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); > }; > > struct mmc_card; > @@ -173,6 +180,14 @@ struct mmc_host { > /* DDR mode at 1.2V */ > #define MMC_CAP_POWER_OFF_CARD (1 << 13) /* Can power off after boot */ > #define MMC_CAP_BUS_WIDTH_TEST (1 << 14) /* CMD14/CMD19 bus width ok */ > +#define MMC_CAP_UHS_SDR12 (1 << 15) /* Host supports UHS SDR12 mode */ > +#define MMC_CAP_UHS_SDR25 (1 << 16) /* Host supports UHS SDR25 mode */ > +#define MMC_CAP_UHS_SDR50 (1 << 17) /* Host supports UHS SDR50 mode */ > +#define MMC_CAP_UHS_SDR104 (1 << 18) /* Host supports UHS SDR104 mode */ > +#define MMC_CAP_UHS_DDR50 (1 << 19) /* Host supports UHS DDR50 mode */ > +#define MMC_CAP_SET_XPC_330 (1 << 20) /* Host supports >150mA current at 3.3V */ > +#define MMC_CAP_SET_XPC_300 (1 << 21) /* Host supports >150mA current at 3.0V */ > +#define MMC_CAP_SET_XPC_180 (1 << 22) /* Host supports >150mA current at 1.8V */ > > mmc_pm_flag_t pm_caps; /* supported pm features */ > > diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h > index 3fd85e0..c648878 100644 > --- a/include/linux/mmc/sd.h > +++ b/include/linux/mmc/sd.h > @@ -17,6 +17,7 @@ > /* This is basically the same command as for MMC with some quirks. */ > #define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ > #define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ > +#define SD_SWITCH_VOLTAGE 11 /* ac R1 */ > > /* class 10 */ > #define SD_SWITCH 6 /* adtc [31:0] See below R1 */ > @@ -32,6 +33,12 @@ > #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ > #define SD_APP_SEND_SCR 51 /* adtc R1 */ > > +/* OCR bit definitions */ > +#define SD_OCR_S18R (1 << 24) /* 1.8V switching request */ > +#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */ > +#define SD_OCR_XPC (1 << 28) /* SDXC power control */ > +#define SD_OCR_CCS (1 << 30) /* Card Capacity Status */ > + > /* > * SD_SWITCH argument format: > * > -- > 1.7.1 > > -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html