From b1fd9c50565b925b0fb7c74a9ec2485a1cf7d70b Mon Sep 17 00:00:00 2001 From: Philip Langdale Date: Sun, 29 Oct 2006 10:14:19 +0100 Subject: [PATCH] --- yaml --- r: 41442 b: refs/heads/master c: e45a1bd20fa5b920901879e85cdf5eda21f78d7c h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/mmc/mmc.c | 51 ++++++++++++++++++++++-------- trunk/include/linux/mmc/protocol.h | 5 +++ 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index 53fa4f142acf..5d19f95b8288 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bce40a36de574376f41f1ff3c4d212a7da2a3c90 +refs/heads/master: e45a1bd20fa5b920901879e85cdf5eda21f78d7c diff --git a/trunk/drivers/mmc/mmc.c b/trunk/drivers/mmc/mmc.c index 2d5b93000dee..1593a6a632cf 100644 --- a/trunk/drivers/mmc/mmc.c +++ b/trunk/drivers/mmc/mmc.c @@ -397,23 +397,23 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) return err; /* - * Default bus width is 1 bit. - */ - host->ios.bus_width = MMC_BUS_WIDTH_1; - - /* - * We can only change the bus width of the selected - * card so therefore we have to put the handling + * We can only change the bus width of SD cards when + * they are selected so we have to put the handling * here. + * + * The card is in 1 bit mode by default so + * we only need to change if it supports the + * wider version. */ - if (host->caps & MMC_CAP_4_BIT_DATA) { + if (mmc_card_sd(card) && + (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { + /* - * The card is in 1 bit mode by default so - * we only need to change if it supports the - * wider version. - */ - if (mmc_card_sd(card) && - (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { + * Default bus width is 1 bit. + */ + host->ios.bus_width = MMC_BUS_WIDTH_1; + + if (host->caps & MMC_CAP_4_BIT_DATA) { struct mmc_command cmd; cmd.opcode = SD_APP_SET_BUS_WIDTH; cmd.arg = SD_BUS_WIDTH_4; @@ -1055,6 +1055,29 @@ static void mmc_process_ext_csds(struct mmc_host *host) } mmc_card_set_highspeed(card); + + /* Check for host support for wide-bus modes. */ + if (!(host->caps & MMC_CAP_4_BIT_DATA)) { + continue; + } + + /* Activate 4-bit support. */ + cmd.opcode = MMC_SWITCH; + cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | + (EXT_CSD_BUS_WIDTH << 16) | + (EXT_CSD_BUS_WIDTH_4 << 8) | + EXT_CSD_CMD_SET_NORMAL; + cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; + + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); + if (err != MMC_ERR_NONE) { + printk("%s: failed to switch card to " + "mmc v4 4-bit bus mode.\n", + mmc_hostname(card->host)); + continue; + } + + host->ios.bus_width = MMC_BUS_WIDTH_4; } kfree(ext_csd); diff --git a/trunk/include/linux/mmc/protocol.h b/trunk/include/linux/mmc/protocol.h index 311b6547f561..45c51fd85786 100644 --- a/trunk/include/linux/mmc/protocol.h +++ b/trunk/include/linux/mmc/protocol.h @@ -256,6 +256,7 @@ struct _mmc_csd { * EXT_CSD fields */ +#define EXT_CSD_BUS_WIDTH 183 /* R/W */ #define EXT_CSD_HS_TIMING 185 /* R/W */ #define EXT_CSD_CARD_TYPE 196 /* RO */ @@ -270,6 +271,10 @@ struct _mmc_csd { #define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ #define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ +#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ +#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ +#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ + /* * MMC_SWITCH access modes */