diff options
author | David Brownell <david-b@pacbell.net> | 2007-08-08 09:11:32 -0700 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-09-23 21:51:30 +0200 |
commit | af51715079e7fb6b290e1881d63d815dc4de5011 (patch) | |
tree | 324e81b2346955f130dda8515f2ad4f4ce97c864 /drivers/mmc/core/sd.c | |
parent | 7213d175e3b6f6db60f843b72e88857a350e146a (diff) |
MMC core learns about SPI
Teach the MMC/SD/SDIO core about using SPI mode.
- Use mmc_host_is_spi() so enumeration works through SPI signaling
and protocols, not just the native versions.
- Provide the SPI response type flags with each request issued,
including requests from the new lock/unlock code.
- Understand that cmd->resp[0] and mmc_get_status() results for SPI
return different values than for "native" MMC/SD protocol; this
affects resetting, checking card lock status, and some others.
- Understand that some commands act a bit differently ... notably:
* OP_COND command doesn't return the OCR
* APP_CMD status doesn't have an R1_APP_CMD analogue
Those changes required some new and updated primitives:
- Provide utilities to access two SPI-only requests, and one
request that wasn't previously needed:
* mmc_spi_read_ocr() ... SPI only
* mmc_spi_set_crc() ... SPI only (override by module parm)
* mmc_send_cid() ... for use without broadcast mode
- Updated internal routines:
* Previous mmc_send_csd() modified into mmc_send_cxd_native();
it uses native "R2" responses, which include 16 bytes of data.
* Previous mmc_send_ext_csd() becomes new mmc_send_cxd_data()
helper for command-and-data access
* Bugfix to that mmc_send_cxd_data() code: dma-to-stack is
unsafe/nonportable, so kmalloc a bounce buffer instead.
- Modified mmc_send_ext_csd() now uses mmc_send_cxd_data() helper
- Modified mmc_send_csd(), and new mmc_spi_send_cid(), routines use
those helper routines based on whether they're native or SPI
The newest categories of cards supported by the MMC stack aren't expected
to work yet with SPI: MMC or SD cards with over 4GB data, and SDIO.
All those cards support SPI mode, so eventually they should work too.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/core/sd.c')
-rw-r--r-- | drivers/mmc/core/sd.c | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index c86588fdaae..d1c1e0f592f 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -323,9 +323,21 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, 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; + } + + /* * Fetch CID from card. */ - err = mmc_all_send_cid(host, cid); + if (mmc_host_is_spi(host)) + err = mmc_send_cid(host, cid); + else + err = mmc_all_send_cid(host, cid); if (err) goto err; @@ -351,13 +363,15 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, } /* - * Set card RCA. + * For native busses: get card RCA and quit open drain mode. */ - err = mmc_send_relative_addr(host, &card->rca); - if (err) - goto free_card; + if (!mmc_host_is_spi(host)) { + err = mmc_send_relative_addr(host, &card->rca); + if (err) + goto free_card; - mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); + mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); + } if (!oldcard) { /* @@ -377,9 +391,11 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, /* * Select card, as all following commands rely on that. */ - err = mmc_select_card(card); - if (err) - goto free_card; + if (!mmc_host_is_spi(host)) { + err = mmc_select_card(card); + if (err) + goto free_card; + } if (!oldcard) { /* @@ -562,7 +578,8 @@ static void mmc_sd_suspend(struct mmc_host *host) BUG_ON(!host->card); mmc_claim_host(host); - mmc_deselect_cards(host); + if (!mmc_host_is_spi(host)) + mmc_deselect_cards(host); host->card->state &= ~MMC_STATE_HIGHSPEED; mmc_release_host(host); } @@ -623,6 +640,17 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) mmc_attach_bus(host, &mmc_sd_ops); /* + * We need to get OCR a different way for SPI. + */ + if (mmc_host_is_spi(host)) { + mmc_go_idle(host); + + err = mmc_spi_read_ocr(host, 0, &ocr); + if (err) + goto err; + } + + /* * Sanity check the voltages that the card claims to * support. */ |