aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <drzeus-list@drzeus.cx>2005-09-06 18:18:55 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 19:57:51 -0400
commitf218278a456b3c272b480443c89004c3d2a49f18 (patch)
tree8d9558816488311e06a7ad2434e342418f2c79d5
parenta9c4342beb4cd28b3a05c3401195e2536c37c150 (diff)
[PATCH] sd: SD 4-bit bus
Infrastructure for 4-bit bus transfers with SD cards. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx> Cc: Russell King <rmk@arm.linux.org.uk> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/mmc/mmc.c36
-rw-r--r--include/linux/mmc/host.h9
-rw-r--r--include/linux/mmc/protocol.h7
3 files changed, 52 insertions, 0 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 21d4fb3314f8..6414f071a2a4 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -335,6 +335,40 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card)
335 if (err != MMC_ERR_NONE) 335 if (err != MMC_ERR_NONE)
336 return err; 336 return err;
337 337
338 /*
339 * Default bus width is 1 bit.
340 */
341 host->ios.bus_width = MMC_BUS_WIDTH_1;
342
343 /*
344 * We can only change the bus width of the selected
345 * card so therefore we have to put the handling
346 * here.
347 */
348 if (host->caps & MMC_CAP_4_BIT_DATA) {
349 /*
350 * The card is in 1 bit mode by default so
351 * we only need to change if it supports the
352 * wider version.
353 */
354 if (mmc_card_sd(card) &&
355 (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
356 struct mmc_command cmd;
357 cmd.opcode = SD_APP_SET_BUS_WIDTH;
358 cmd.arg = SD_BUS_WIDTH_4;
359 cmd.flags = MMC_RSP_R1;
360
361 err = mmc_wait_for_app_cmd(host, card->rca, &cmd,
362 CMD_RETRIES);
363 if (err != MMC_ERR_NONE)
364 return err;
365
366 host->ios.bus_width = MMC_BUS_WIDTH_4;
367 }
368 }
369
370 host->ops->set_ios(host, &host->ios);
371
338 return MMC_ERR_NONE; 372 return MMC_ERR_NONE;
339} 373}
340 374
@@ -653,6 +687,7 @@ static void mmc_power_up(struct mmc_host *host)
653 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; 687 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
654 host->ios.chip_select = MMC_CS_DONTCARE; 688 host->ios.chip_select = MMC_CS_DONTCARE;
655 host->ios.power_mode = MMC_POWER_UP; 689 host->ios.power_mode = MMC_POWER_UP;
690 host->ios.bus_width = MMC_BUS_WIDTH_1;
656 host->ops->set_ios(host, &host->ios); 691 host->ops->set_ios(host, &host->ios);
657 692
658 mmc_delay(1); 693 mmc_delay(1);
@@ -671,6 +706,7 @@ static void mmc_power_off(struct mmc_host *host)
671 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; 706 host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
672 host->ios.chip_select = MMC_CS_DONTCARE; 707 host->ios.chip_select = MMC_CS_DONTCARE;
673 host->ios.power_mode = MMC_POWER_OFF; 708 host->ios.power_mode = MMC_POWER_OFF;
709 host->ios.bus_width = MMC_BUS_WIDTH_1;
674 host->ops->set_ios(host, &host->ios); 710 host->ops->set_ios(host, &host->ios);
675} 711}
676 712
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 8c5f71376e41..6014160d9c06 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -57,6 +57,11 @@ struct mmc_ios {
57#define MMC_POWER_OFF 0 57#define MMC_POWER_OFF 0
58#define MMC_POWER_UP 1 58#define MMC_POWER_UP 1
59#define MMC_POWER_ON 2 59#define MMC_POWER_ON 2
60
61 unsigned char bus_width; /* data bus width */
62
63#define MMC_BUS_WIDTH_1 0
64#define MMC_BUS_WIDTH_4 2
60}; 65};
61 66
62struct mmc_host_ops { 67struct mmc_host_ops {
@@ -77,6 +82,10 @@ struct mmc_host {
77 unsigned int f_max; 82 unsigned int f_max;
78 u32 ocr_avail; 83 u32 ocr_avail;
79 84
85 unsigned long caps; /* Host capabilities */
86
87#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */
88
80 /* host specific block data */ 89 /* host specific block data */
81 unsigned int max_seg_size; /* see blk_queue_max_segment_size */ 90 unsigned int max_seg_size; /* see blk_queue_max_segment_size */
82 unsigned short max_hw_segs; /* see blk_queue_max_hw_segments */ 91 unsigned short max_hw_segs; /* see blk_queue_max_hw_segments */
diff --git a/include/linux/mmc/protocol.h b/include/linux/mmc/protocol.h
index 896342817b97..f819cae92266 100644
--- a/include/linux/mmc/protocol.h
+++ b/include/linux/mmc/protocol.h
@@ -236,5 +236,12 @@ struct _mmc_csd {
236#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */ 236#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
237#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 */ 237#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 */
238 238
239
240/*
241 * SD bus widths
242 */
243#define SD_BUS_WIDTH_1 0
244#define SD_BUS_WIDTH_4 2
245
239#endif /* MMC_MMC_PROTOCOL_H */ 246#endif /* MMC_MMC_PROTOCOL_H */
240 247