aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2007-03-16 22:39:00 -0400
committerPierre Ossman <drzeus@drzeus.cx>2007-05-01 08:14:50 -0400
commit55556da01284af8c2174b786b3eca8e11301b656 (patch)
tree579e0dbd68021daee1ff0c5b400d9cdf71c6faf8
parent4be34c99a2f3aa90fa42e62c0918f07afb8a645b (diff)
MMC: Fix handling of low-voltage cards
Fix handling of low voltage MMC cards. The latest MMC and SD specs both agree that support for low-voltage operations is indicated by bit 7 in the OCR. The MMC spec states that the low voltage range is 1.65-1.95V while the SD spec leaves the actual voltage range undefined - meaning that there is still no such thing as a low voltage SD card. However, an old Sandisk spec implied that bits 7.0 represented voltages below 2.0V in 1V or 0.5V increments, and the code was accordingly written with that expectation. This confusion meant that host drivers attempting to support the typical low voltage (1.8V) would set the wrong bits in the host OCR mask (usually bits 5 and/or 6) resulting in the the low voltage mode never being used. This change corrects the low voltage range and adds sanity checks on the reserved bits (0-6) and for SD cards that claim to support low-voltage operations. Signed-off-by: Philip Langdale <philipl@overt.org> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
-rw-r--r--drivers/mmc/core/mmc.c11
-rw-r--r--drivers/mmc/core/sd.c18
-rw-r--r--drivers/mmc/host/sdhci.c5
-rw-r--r--include/linux/mmc/host.h9
4 files changed, 32 insertions, 11 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c528017d6128..c2e120b11bef 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -323,6 +323,17 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
323 323
324 mmc_attach_bus(host, &mmc_ops); 324 mmc_attach_bus(host, &mmc_ops);
325 325
326 /*
327 * Sanity check the voltages that the card claims to
328 * support.
329 */
330 if (ocr & 0x7F) {
331 printk(KERN_WARNING "%s: card claims to support voltages "
332 "below the defined range. These will be ignored.\n",
333 mmc_hostname(host));
334 ocr &= ~0x7F;
335 }
336
326 host->ocr = mmc_select_voltage(host, ocr); 337 host->ocr = mmc_select_voltage(host, ocr);
327 338
328 /* 339 /*
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 6c6beb48f3a8..fb18b301502e 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -297,6 +297,24 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
297 297
298 mmc_attach_bus(host, &mmc_sd_ops); 298 mmc_attach_bus(host, &mmc_sd_ops);
299 299
300 /*
301 * Sanity check the voltages that the card claims to
302 * support.
303 */
304 if (ocr & 0x7F) {
305 printk(KERN_WARNING "%s: card claims to support voltages "
306 "below the defined range. These will be ignored.\n",
307 mmc_hostname(host));
308 ocr &= ~0x7F;
309 }
310
311 if (ocr & MMC_VDD_165_195) {
312 printk(KERN_WARNING "%s: SD card claims to support the "
313 "incompletely defined 'low voltage range'. This "
314 "will be ignored.\n", mmc_hostname(host));
315 ocr &= ~MMC_VDD_165_195;
316 }
317
300 host->ocr = mmc_select_voltage(host, ocr); 318 host->ocr = mmc_select_voltage(host, ocr);
301 319
302 /* 320 /*
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a57f6a3d48d3..ff5bf73cdd25 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -659,8 +659,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
659 pwr = SDHCI_POWER_ON; 659 pwr = SDHCI_POWER_ON;
660 660
661 switch (1 << power) { 661 switch (1 << power) {
662 case MMC_VDD_17_18: 662 case MMC_VDD_165_195:
663 case MMC_VDD_18_19:
664 pwr |= SDHCI_POWER_180; 663 pwr |= SDHCI_POWER_180;
665 break; 664 break;
666 case MMC_VDD_29_30: 665 case MMC_VDD_29_30:
@@ -1280,7 +1279,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1280 if (caps & SDHCI_CAN_VDD_300) 1279 if (caps & SDHCI_CAN_VDD_300)
1281 mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31; 1280 mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31;
1282 if (caps & SDHCI_CAN_VDD_180) 1281 if (caps & SDHCI_CAN_VDD_180)
1283 mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19; 1282 mmc->ocr_avail |= MMC_VDD_165_195;
1284 1283
1285 if (mmc->ocr_avail == 0) { 1284 if (mmc->ocr_avail == 0) {
1286 printk(KERN_ERR "%s: Hardware doesn't report any " 1285 printk(KERN_ERR "%s: Hardware doesn't report any "
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 5a66d8a2bf17..b1350dfd3e91 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -65,14 +65,7 @@ struct mmc_host {
65 unsigned int f_max; 65 unsigned int f_max;
66 u32 ocr_avail; 66 u32 ocr_avail;
67 67
68#define MMC_VDD_145_150 0x00000001 /* VDD voltage 1.45 - 1.50 */ 68#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
69#define MMC_VDD_150_155 0x00000002 /* VDD voltage 1.50 - 1.55 */
70#define MMC_VDD_155_160 0x00000004 /* VDD voltage 1.55 - 1.60 */
71#define MMC_VDD_160_165 0x00000008 /* VDD voltage 1.60 - 1.65 */
72#define MMC_VDD_165_170 0x00000010 /* VDD voltage 1.65 - 1.70 */
73#define MMC_VDD_17_18 0x00000020 /* VDD voltage 1.7 - 1.8 */
74#define MMC_VDD_18_19 0x00000040 /* VDD voltage 1.8 - 1.9 */
75#define MMC_VDD_19_20 0x00000080 /* VDD voltage 1.9 - 2.0 */
76#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ 69#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
77#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */ 70#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */
78#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */ 71#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */