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>
This commit is contained in:
parent
e480606ad4
commit
bad37e1ac6
2 changed files with 23 additions and 6 deletions
|
@ -2837,6 +2837,13 @@ int sdhci_add_host(struct sdhci_host *host)
|
||||||
SDHCI_RETUNING_MODE_SHIFT;
|
SDHCI_RETUNING_MODE_SHIFT;
|
||||||
|
|
||||||
ocr_avail = 0;
|
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
|
* 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
|
* 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.
|
* value.
|
||||||
*/
|
*/
|
||||||
max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT);
|
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) {
|
if (caps[0] & SDHCI_CAN_VDD_330) {
|
||||||
int max_current_330;
|
int max_current_330;
|
||||||
|
@ -2995,12 +3017,6 @@ int sdhci_add_host(struct sdhci_host *host)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto untasklet;
|
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);
|
sdhci_init(host, 0);
|
||||||
|
|
||||||
#ifdef CONFIG_MMC_DEBUG
|
#ifdef CONFIG_MMC_DEBUG
|
||||||
|
|
|
@ -205,6 +205,7 @@
|
||||||
#define SDHCI_CAPABILITIES_1 0x44
|
#define SDHCI_CAPABILITIES_1 0x44
|
||||||
|
|
||||||
#define SDHCI_MAX_CURRENT 0x48
|
#define SDHCI_MAX_CURRENT 0x48
|
||||||
|
#define SDHCI_MAX_CURRENT_LIMIT 0xFF
|
||||||
#define SDHCI_MAX_CURRENT_330_MASK 0x0000FF
|
#define SDHCI_MAX_CURRENT_330_MASK 0x0000FF
|
||||||
#define SDHCI_MAX_CURRENT_330_SHIFT 0
|
#define SDHCI_MAX_CURRENT_330_SHIFT 0
|
||||||
#define SDHCI_MAX_CURRENT_300_MASK 0x00FF00
|
#define SDHCI_MAX_CURRENT_300_MASK 0x00FF00
|
||||||
|
|
Loading…
Reference in a new issue