diff options
author | Philip Rakity <prakity@marvell.com> | 2012-05-27 21:36:44 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-07-21 00:02:22 -0400 |
commit | bad37e1ac6b1a73ed30702b24a45c27c4f53aada (patch) | |
tree | f296dfee6adbb7c7b781285cd447b3aed53fa0ed /drivers | |
parent | e480606ad43bb72fd82a9bd99cdcf21829a6e9c0 (diff) |
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 <prakity@marvell.com>
Signed-off-by: Mark F. Brown <mark.brown314@gmail.com>
Reviewed-by: Aaron Lu <aaron.lu@amd.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 28 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 1 |
2 files changed, 23 insertions, 6 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f4b8b4db3a9a..a0853d03b330 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) | |||
2837 | SDHCI_RETUNING_MODE_SHIFT; | 2837 | SDHCI_RETUNING_MODE_SHIFT; |
2838 | 2838 | ||
2839 | ocr_avail = 0; | 2839 | ocr_avail = 0; |
2840 | |||
2841 | host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); | ||
2842 | if (IS_ERR(host->vmmc)) { | ||
2843 | pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); | ||
2844 | host->vmmc = NULL; | ||
2845 | } | ||
2846 | |||
2840 | /* | 2847 | /* |
2841 | * According to SD Host Controller spec v3.00, if the Host System | 2848 | * According to SD Host Controller spec v3.00, if the Host System |
2842 | * can afford more than 150mA, Host Driver should set XPC to 1. Also | 2849 | * 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) | |||
2845 | * value. | 2852 | * value. |
2846 | */ | 2853 | */ |
2847 | max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT); | 2854 | max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT); |
2855 | if (!max_current_caps && host->vmmc) { | ||
2856 | u32 curr = regulator_get_current_limit(host->vmmc); | ||
2857 | if (curr > 0) { | ||
2858 | |||
2859 | /* convert to SDHCI_MAX_CURRENT format */ | ||
2860 | curr = curr/1000; /* convert to mA */ | ||
2861 | curr = curr/SDHCI_MAX_CURRENT_MULTIPLIER; | ||
2862 | |||
2863 | curr = min_t(u32, curr, SDHCI_MAX_CURRENT_LIMIT); | ||
2864 | max_current_caps = | ||
2865 | (curr << SDHCI_MAX_CURRENT_330_SHIFT) | | ||
2866 | (curr << SDHCI_MAX_CURRENT_300_SHIFT) | | ||
2867 | (curr << SDHCI_MAX_CURRENT_180_SHIFT); | ||
2868 | } | ||
2869 | } | ||
2848 | 2870 | ||
2849 | if (caps[0] & SDHCI_CAN_VDD_330) { | 2871 | if (caps[0] & SDHCI_CAN_VDD_330) { |
2850 | int max_current_330; | 2872 | int max_current_330; |
@@ -2995,12 +3017,6 @@ int sdhci_add_host(struct sdhci_host *host) | |||
2995 | if (ret) | 3017 | if (ret) |
2996 | goto untasklet; | 3018 | goto untasklet; |
2997 | 3019 | ||
2998 | host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); | ||
2999 | if (IS_ERR(host->vmmc)) { | ||
3000 | pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); | ||
3001 | host->vmmc = NULL; | ||
3002 | } | ||
3003 | |||
3004 | sdhci_init(host, 0); | 3020 | sdhci_init(host, 0); |
3005 | 3021 | ||
3006 | #ifdef CONFIG_MMC_DEBUG | 3022 | #ifdef CONFIG_MMC_DEBUG |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index f761f23d2a28..97653ea8942b 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -205,6 +205,7 @@ | |||
205 | #define SDHCI_CAPABILITIES_1 0x44 | 205 | #define SDHCI_CAPABILITIES_1 0x44 |
206 | 206 | ||
207 | #define SDHCI_MAX_CURRENT 0x48 | 207 | #define SDHCI_MAX_CURRENT 0x48 |
208 | #define SDHCI_MAX_CURRENT_LIMIT 0xFF | ||
208 | #define SDHCI_MAX_CURRENT_330_MASK 0x0000FF | 209 | #define SDHCI_MAX_CURRENT_330_MASK 0x0000FF |
209 | #define SDHCI_MAX_CURRENT_330_SHIFT 0 | 210 | #define SDHCI_MAX_CURRENT_330_SHIFT 0 |
210 | #define SDHCI_MAX_CURRENT_300_MASK 0x00FF00 | 211 | #define SDHCI_MAX_CURRENT_300_MASK 0x00FF00 |