aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-12-08 04:04:30 -0500
committerChris Ball <cjb@laptop.org>2011-01-08 22:48:04 -0500
commit8f230f454fe04ba326ffaead3a6b88dcf44eaf4b (patch)
tree9f5c43b48aa84131f7b94b44e4d500e0ec271ba0 /drivers/mmc/host
parent150ee73d1b35936aafc5fd3b39a7291b1f66de07 (diff)
mmc: Add support for JMicron 388 SD/MMC controller
JMicron 388 SD/MMC combo controller supports the 1.8V low-voltage for SD, but MMC doesn't work with the low-voltage, resulting in an error at probing. This patch adds the support for multiple voltage mask per device type, so that SD works with 1.8V while MMC forces 3.3V. Here new ocr_avail_* fields for each device are introduced, so that the actual OCR mask is switched dynamically. Also, the restriction of low-voltage in core/sd.c is removed when the bit is allowed explicitly via ocr_avail_sd mask. This patch was rewritten from scratch based on Aries' original code. Signed-off-by: Aries Lee <arieslee@jmicron.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Reviewed-by: Chris Ball <cjb@laptop.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/sdhci-pci.c47
-rw-r--r--drivers/mmc/host/sdhci.c23
2 files changed, 59 insertions, 11 deletions
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 831cf91b644a..d2638ffc4ed2 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -272,6 +272,7 @@ static int jmicron_pmos(struct sdhci_pci_chip *chip, int on)
272static int jmicron_probe(struct sdhci_pci_chip *chip) 272static int jmicron_probe(struct sdhci_pci_chip *chip)
273{ 273{
274 int ret; 274 int ret;
275 u16 mmcdev = 0;
275 276
276 if (chip->pdev->revision == 0) { 277 if (chip->pdev->revision == 0) {
277 chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR | 278 chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR |
@@ -293,12 +294,17 @@ static int jmicron_probe(struct sdhci_pci_chip *chip)
293 * 2. The MMC interface has a lower subfunction number 294 * 2. The MMC interface has a lower subfunction number
294 * than the SD interface. 295 * than the SD interface.
295 */ 296 */
296 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD) { 297 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD)
298 mmcdev = PCI_DEVICE_ID_JMICRON_JMB38X_MMC;
299 else if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD)
300 mmcdev = PCI_DEVICE_ID_JMICRON_JMB388_ESD;
301
302 if (mmcdev) {
297 struct pci_dev *sd_dev; 303 struct pci_dev *sd_dev;
298 304
299 sd_dev = NULL; 305 sd_dev = NULL;
300 while ((sd_dev = pci_get_device(PCI_VENDOR_ID_JMICRON, 306 while ((sd_dev = pci_get_device(PCI_VENDOR_ID_JMICRON,
301 PCI_DEVICE_ID_JMICRON_JMB38X_MMC, sd_dev)) != NULL) { 307 mmcdev, sd_dev)) != NULL) {
302 if ((PCI_SLOT(chip->pdev->devfn) == 308 if ((PCI_SLOT(chip->pdev->devfn) ==
303 PCI_SLOT(sd_dev->devfn)) && 309 PCI_SLOT(sd_dev->devfn)) &&
304 (chip->pdev->bus == sd_dev->bus)) 310 (chip->pdev->bus == sd_dev->bus))
@@ -358,11 +364,21 @@ static int jmicron_probe_slot(struct sdhci_pci_slot *slot)
358 slot->host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; 364 slot->host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
359 } 365 }
360 366
367 /* JM388 MMC doesn't support 1.8V while SD supports it */
368 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
369 slot->host->ocr_avail_sd = MMC_VDD_32_33 | MMC_VDD_33_34 |
370 MMC_VDD_29_30 | MMC_VDD_30_31 |
371 MMC_VDD_165_195; /* allow 1.8V */
372 slot->host->ocr_avail_mmc = MMC_VDD_32_33 | MMC_VDD_33_34 |
373 MMC_VDD_29_30 | MMC_VDD_30_31; /* no 1.8V for MMC */
374 }
375
361 /* 376 /*
362 * The secondary interface requires a bit set to get the 377 * The secondary interface requires a bit set to get the
363 * interrupts. 378 * interrupts.
364 */ 379 */
365 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) 380 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
381 slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
366 jmicron_enable_mmc(slot->host, 1); 382 jmicron_enable_mmc(slot->host, 1);
367 383
368 return 0; 384 return 0;
@@ -373,7 +389,8 @@ static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead)
373 if (dead) 389 if (dead)
374 return; 390 return;
375 391
376 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) 392 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
393 slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
377 jmicron_enable_mmc(slot->host, 0); 394 jmicron_enable_mmc(slot->host, 0);
378} 395}
379 396
@@ -381,7 +398,8 @@ static int jmicron_suspend(struct sdhci_pci_chip *chip, pm_message_t state)
381{ 398{
382 int i; 399 int i;
383 400
384 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) { 401 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
402 chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
385 for (i = 0;i < chip->num_slots;i++) 403 for (i = 0;i < chip->num_slots;i++)
386 jmicron_enable_mmc(chip->slots[i]->host, 0); 404 jmicron_enable_mmc(chip->slots[i]->host, 0);
387 } 405 }
@@ -393,7 +411,8 @@ static int jmicron_resume(struct sdhci_pci_chip *chip)
393{ 411{
394 int ret, i; 412 int ret, i;
395 413
396 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC) { 414 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
415 chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
397 for (i = 0;i < chip->num_slots;i++) 416 for (i = 0;i < chip->num_slots;i++)
398 jmicron_enable_mmc(chip->slots[i]->host, 1); 417 jmicron_enable_mmc(chip->slots[i]->host, 1);
399 } 418 }
@@ -582,6 +601,22 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
582 }, 601 },
583 602
584 { 603 {
604 .vendor = PCI_VENDOR_ID_JMICRON,
605 .device = PCI_DEVICE_ID_JMICRON_JMB388_SD,
606 .subvendor = PCI_ANY_ID,
607 .subdevice = PCI_ANY_ID,
608 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
609 },
610
611 {
612 .vendor = PCI_VENDOR_ID_JMICRON,
613 .device = PCI_DEVICE_ID_JMICRON_JMB388_ESD,
614 .subvendor = PCI_ANY_ID,
615 .subdevice = PCI_ANY_ID,
616 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
617 },
618
619 {
585 .vendor = PCI_VENDOR_ID_SYSKONNECT, 620 .vendor = PCI_VENDOR_ID_SYSKONNECT,
586 .device = 0x8000, 621 .device = 0x8000,
587 .subvendor = PCI_ANY_ID, 622 .subvendor = PCI_ANY_ID,
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 8a74fcbfe13b..55698864c2cd 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1739,7 +1739,7 @@ EXPORT_SYMBOL_GPL(sdhci_alloc_host);
1739int sdhci_add_host(struct sdhci_host *host) 1739int sdhci_add_host(struct sdhci_host *host)
1740{ 1740{
1741 struct mmc_host *mmc; 1741 struct mmc_host *mmc;
1742 unsigned int caps; 1742 unsigned int caps, ocr_avail;
1743 int ret; 1743 int ret;
1744 1744
1745 WARN_ON(host == NULL); 1745 WARN_ON(host == NULL);
@@ -1893,13 +1893,26 @@ int sdhci_add_host(struct sdhci_host *host)
1893 mmc_card_is_removable(mmc)) 1893 mmc_card_is_removable(mmc))
1894 mmc->caps |= MMC_CAP_NEEDS_POLL; 1894 mmc->caps |= MMC_CAP_NEEDS_POLL;
1895 1895
1896 mmc->ocr_avail = 0; 1896 ocr_avail = 0;
1897 if (caps & SDHCI_CAN_VDD_330) 1897 if (caps & SDHCI_CAN_VDD_330)
1898 mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34; 1898 ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34;
1899 if (caps & SDHCI_CAN_VDD_300) 1899 if (caps & SDHCI_CAN_VDD_300)
1900 mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31; 1900 ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31;
1901 if (caps & SDHCI_CAN_VDD_180) 1901 if (caps & SDHCI_CAN_VDD_180)
1902 mmc->ocr_avail |= MMC_VDD_165_195; 1902 ocr_avail |= MMC_VDD_165_195;
1903
1904 mmc->ocr_avail = ocr_avail;
1905 mmc->ocr_avail_sdio = ocr_avail;
1906 if (host->ocr_avail_sdio)
1907 mmc->ocr_avail_sdio &= host->ocr_avail_sdio;
1908 mmc->ocr_avail_sd = ocr_avail;
1909 if (host->ocr_avail_sd)
1910 mmc->ocr_avail_sd &= host->ocr_avail_sd;
1911 else /* normal SD controllers don't support 1.8V */
1912 mmc->ocr_avail_sd &= ~MMC_VDD_165_195;
1913 mmc->ocr_avail_mmc = ocr_avail;
1914 if (host->ocr_avail_mmc)
1915 mmc->ocr_avail_mmc &= host->ocr_avail_mmc;
1903 1916
1904 if (mmc->ocr_avail == 0) { 1917 if (mmc->ocr_avail == 0) {
1905 printk(KERN_ERR "%s: Hardware doesn't report any " 1918 printk(KERN_ERR "%s: Hardware doesn't report any "