mmc: sdhci: Allow caps[1] to be set via SDHCI_QUIRK_MISSING_CAPS
[linux-2.6-block.git] / drivers / mmc / host / sdhci.c
index e626732aff77d3ebd0563c3d1720da62aab6d7ff..206b52fec44351d38ff457b207e204af1046ed02 100644 (file)
@@ -680,8 +680,8 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
        }
 
        if (count >= 0xF) {
-               pr_warning("%s: Too large timeout 0x%x requested for CMD%d!\n",
-                          mmc_hostname(host->mmc), count, cmd->opcode);
+               DBG("%s: Too large timeout 0x%x requested for CMD%d!\n",
+                   mmc_hostname(host->mmc), count, cmd->opcode);
                count = 0xE;
        }
 
@@ -2584,7 +2584,7 @@ EXPORT_SYMBOL_GPL(sdhci_alloc_host);
 int sdhci_add_host(struct sdhci_host *host)
 {
        struct mmc_host *mmc;
-       u32 caps[2];
+       u32 caps[2] = {0, 0};
        u32 max_current_caps;
        unsigned int ocr_avail;
        int ret;
@@ -2614,8 +2614,10 @@ int sdhci_add_host(struct sdhci_host *host)
        caps[0] = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps :
                sdhci_readl(host, SDHCI_CAPABILITIES);
 
-       caps[1] = (host->version >= SDHCI_SPEC_300) ?
-               sdhci_readl(host, SDHCI_CAPABILITIES_1) : 0;
+       if (host->version >= SDHCI_SPEC_300)
+               caps[1] = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ?
+                       host->caps1 :
+                       sdhci_readl(host, SDHCI_CAPABILITIES_1);
 
        if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
                host->flags |= SDHCI_USE_SDMA;
@@ -2837,6 +2839,30 @@ 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;
+       }
+
+#ifdef CONFIG_REGULATOR
+       if (host->vmmc) {
+               ret = regulator_is_supported_voltage(host->vmmc, 3300000,
+                       3300000);
+               if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_330)))
+                       caps[0] &= ~SDHCI_CAN_VDD_330;
+               ret = regulator_is_supported_voltage(host->vmmc, 3000000,
+                       3000000);
+               if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_300)))
+                       caps[0] &= ~SDHCI_CAN_VDD_300;
+               ret = regulator_is_supported_voltage(host->vmmc, 1800000,
+                       1800000);
+               if ((ret <= 0) || (!(caps[0] & SDHCI_CAN_VDD_180)))
+                       caps[0] &= ~SDHCI_CAN_VDD_180;
+       }
+#endif /* CONFIG_REGULATOR */
+
        /*
         * 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 +2871,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;
@@ -2892,7 +2933,7 @@ int sdhci_add_host(struct sdhci_host *host)
                        mmc->caps |= MMC_CAP_MAX_CURRENT_600;
                else if (max_current_180 >= 400)
                        mmc->caps |= MMC_CAP_MAX_CURRENT_400;
-               else
+               else if (max_current_180 >= 200)
                        mmc->caps |= MMC_CAP_MAX_CURRENT_200;
        }
 
@@ -2995,12 +3036,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