aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci-pci.c
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/sdhci-pci.c
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/sdhci-pci.c')
-rw-r--r--drivers/mmc/host/sdhci-pci.c47
1 files changed, 41 insertions, 6 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,