summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorTim Kryger <tim.kryger@gmail.com>2014-06-25 03:25:34 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2014-07-09 05:26:09 -0400
commit52221610dd84dc3e9196554f0292ca9e8ab3541d (patch)
tree637b2ea5465d7e8b1a08afb31d0ba1c497c3bebd /drivers/mmc
parent87a0f46a0e1c048ecf964e0ef020cca3d6daba2f (diff)
mmc: sdhci: Improve external VDD regulator support
A standard compliant SDHCI can itself supply VDD at 1.8, 3.0, or 3.3v. Several vendors ignore this and instead rely upon external regulators to supply VDD. While the external regulators typically can supply one of the standard SDHCI voltage levels, there is no real reason for this to be a hard requirement. This patch alters the SDHCI driver such that external VDD regulators that provide voltages other than the three mentioned above may be used so long as they can supply a voltage that meets the needs of the card. In the case that an external VDD regulator is provided, it is reasonable to ignore the voltage capabilities of the host controller and allow the external regulator to set the OCR mask. Additionally, there is no need to convert a VDD voltage request into one of the standard SDHCI voltage levels or program it in the host controller's power control register. Signed-off-by: Tim Kryger <tim.kryger@gmail.com> Tested-by: Sachin Kamat <spk.linux@gmail.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c23a87285a95..07a242675c0e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1226,6 +1226,13 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
1226 struct mmc_host *mmc = host->mmc; 1226 struct mmc_host *mmc = host->mmc;
1227 u8 pwr = 0; 1227 u8 pwr = 0;
1228 1228
1229 if (!IS_ERR(mmc->supply.vmmc)) {
1230 spin_unlock_irq(&host->lock);
1231 mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, vdd);
1232 spin_lock_irq(&host->lock);
1233 return;
1234 }
1235
1229 if (mode != MMC_POWER_OFF) { 1236 if (mode != MMC_POWER_OFF) {
1230 switch (1 << vdd) { 1237 switch (1 << vdd) {
1231 case MMC_VDD_165_195: 1238 case MMC_VDD_165_195:
@@ -1284,12 +1291,6 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
1284 if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) 1291 if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
1285 mdelay(10); 1292 mdelay(10);
1286 } 1293 }
1287
1288 if (!IS_ERR(mmc->supply.vmmc)) {
1289 spin_unlock_irq(&host->lock);
1290 mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, vdd);
1291 spin_lock_irq(&host->lock);
1292 }
1293} 1294}
1294 1295
1295/*****************************************************************************\ 1296/*****************************************************************************\
@@ -3092,8 +3093,9 @@ int sdhci_add_host(struct sdhci_host *host)
3092 SDHCI_MAX_CURRENT_MULTIPLIER; 3093 SDHCI_MAX_CURRENT_MULTIPLIER;
3093 } 3094 }
3094 3095
3096 /* If OCR set by external regulators, use it instead */
3095 if (mmc->ocr_avail) 3097 if (mmc->ocr_avail)
3096 ocr_avail &= mmc->ocr_avail; 3098 ocr_avail = mmc->ocr_avail;
3097 3099
3098 if (host->ocr_mask) 3100 if (host->ocr_mask)
3099 ocr_avail &= host->ocr_mask; 3101 ocr_avail &= host->ocr_mask;