X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fmmc%2Fcore%2Fsdio.c;h=87a50f456efc080c60fcce98717b780ddc1e9bc6;hb=45ff993d2b0b4c07038457cdf07ecf648abd3d78;hp=1fb36a340468803237224c18012feaa6317af5aa;hpb=1a632f8cdc33e7f8edca352164f0c96a75d08f08;p=linux-2.6-omap-h63xx.git diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 1fb36a34046..87a50f456ef 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -30,7 +30,7 @@ static int sdio_read_fbr(struct sdio_func *func) unsigned char data; ret = mmc_io_rw_direct(func->card, 0, 0, - func->num * 0x100 + SDIO_FBR_STD_IF, 0, &data); + SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data); if (ret) goto out; @@ -38,7 +38,7 @@ static int sdio_read_fbr(struct sdio_func *func) if (data == 0x0f) { ret = mmc_io_rw_direct(func->card, 0, 0, - func->num * 0x100 + SDIO_FBR_STD_IF_EXT, 0, &data); + SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF_EXT, 0, &data); if (ret) goto out; } @@ -138,6 +138,32 @@ out: return ret; } +static int sdio_enable_wide(struct mmc_card *card) +{ + int ret; + u8 ctrl; + + if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) + return 0; + + if (card->cccr.low_speed && !card->cccr.wide_bus) + return 0; + + ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); + if (ret) + return ret; + + ctrl |= SDIO_BUS_WIDTH_4BIT; + + ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); + if (ret) + return ret; + + mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); + + return 0; +} + /* * Host is being removed. Free up the current card. */ @@ -204,7 +230,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) struct mmc_card *card; BUG_ON(!host); - BUG_ON(!host->claimed); + WARN_ON(!host->claimed); mmc_attach_bus(host, &mmc_sdio_ops); @@ -243,6 +269,15 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) if (err) goto err; + /* + * For SPI, enable CRC as appropriate. + */ + if (mmc_host_is_spi(host)) { + err = mmc_spi_set_crc(host, use_spi_crc); + if (err) + goto err; + } + /* * The number of functions on the card is encoded inside * the ocr. @@ -264,20 +299,24 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) host->card = card; /* - * Set card RCA. + * For native busses: set card RCA and quit open drain mode. */ - err = mmc_send_relative_addr(host, &card->rca); - if (err) - goto remove; + if (!mmc_host_is_spi(host)) { + err = mmc_send_relative_addr(host, &card->rca); + if (err) + goto remove; - mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); + mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); + } /* * Select card, as all following commands rely on that. */ - err = mmc_select_card(card); - if (err) - goto remove; + if (!mmc_host_is_spi(host)) { + err = mmc_select_card(card); + if (err) + goto remove; + } /* * Read the common registers. @@ -293,6 +332,19 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) if (err) goto remove; + /* + * No support for high-speed yet, so just set + * the card's maximum speed. + */ + mmc_set_clock(host, card->cis.max_dtr); + + /* + * Switch to wider bus (if supported). + */ + err = sdio_enable_wide(card); + if (err) + goto remove; + /* * Initialize (but don't add) all present functions. */