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
					
				| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user