From: Philip Rakity Date: Mon, 28 May 2012 01:36:44 +0000 (-0700) Subject: mmc: sdhci: if MAX_CURRENT is 0, try getting current from regulator X-Git-Tag: v3.12-rc1~2735^2~25 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bad37e1ac6b1a73ed30702b24a45c27c4f53aada;p=kernel%2Fkernel-generic.git mmc: sdhci: if MAX_CURRENT is 0, try getting current from regulator The sd host controller spec indicates the the MAX_CURRENT value may be returned as 0. In this case other methods need to be used to return the current. If 0 is returned and there is a regulator, ask the regulator for how much current is available. Signed-off-by: Philip Rakity Signed-off-by: Mark F. Brown Reviewed-by: Aaron Lu Signed-off-by: Chris Ball --- diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f4b8b4d..a0853d0 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2837,6 +2837,13 @@ int sdhci_add_host(struct sdhci_host *host) SDHCI_RETUNING_MODE_SHIFT; ocr_avail = 0; + + host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); + if (IS_ERR(host->vmmc)) { + pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); + host->vmmc = NULL; + } + /* * 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 @@ -2845,6 +2852,21 @@ int sdhci_add_host(struct sdhci_host *host) * value. */ max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT); + if (!max_current_caps && host->vmmc) { + u32 curr = regulator_get_current_limit(host->vmmc); + if (curr > 0) { + + /* convert to SDHCI_MAX_CURRENT format */ + curr = curr/1000; /* convert to mA */ + curr = curr/SDHCI_MAX_CURRENT_MULTIPLIER; + + curr = min_t(u32, curr, SDHCI_MAX_CURRENT_LIMIT); + max_current_caps = + (curr << SDHCI_MAX_CURRENT_330_SHIFT) | + (curr << SDHCI_MAX_CURRENT_300_SHIFT) | + (curr << SDHCI_MAX_CURRENT_180_SHIFT); + } + } if (caps[0] & SDHCI_CAN_VDD_330) { int max_current_330; @@ -2995,12 +3017,6 @@ int sdhci_add_host(struct sdhci_host *host) if (ret) goto untasklet; - host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); - if (IS_ERR(host->vmmc)) { - pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); - host->vmmc = NULL; - } - sdhci_init(host, 0); #ifdef CONFIG_MMC_DEBUG diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index f761f23..97653ea 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -205,6 +205,7 @@ #define SDHCI_CAPABILITIES_1 0x44 #define SDHCI_MAX_CURRENT 0x48 +#define SDHCI_MAX_CURRENT_LIMIT 0xFF #define SDHCI_MAX_CURRENT_330_MASK 0x0000FF #define SDHCI_MAX_CURRENT_330_SHIFT 0 #define SDHCI_MAX_CURRENT_300_MASK 0x00FF00