diff options
author | David Brownell <david-b@pacbell.net> | 2007-08-08 12:11:32 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-09-23 15:51:30 -0400 |
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, | |||
323 | goto err; | 323 | goto err; |
324 | 324 | ||
325 | /* | 325 | /* |
326 | * For SPI, enable CRC as appropriate. | ||
327 | */ | ||
328 | if (mmc_host_is_spi(host)) { | ||
329 | err = mmc_spi_set_crc(host, use_spi_crc); | ||
330 | if (err) | ||
331 | goto err; | ||
332 | } | ||
333 | |||
334 | /* | ||
326 | * Fetch CID from card. | 335 | * Fetch CID from card. |
327 | */ | 336 | */ |
328 | err = mmc_all_send_cid(host, cid); | 337 | if (mmc_host_is_spi(host)) |
338 | err = mmc_send_cid(host, cid); | ||
339 | else | ||
340 | err = mmc_all_send_cid(host, cid); | ||
329 | if (err) | 341 | if (err) |
330 | goto err; | 342 | goto err; |
331 | 343 | ||
@@ -351,13 +363,15 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
351 | } | 363 | } |
352 | 364 | ||
353 | /* | 365 | /* |
354 | * Set card RCA. | 366 | * For native busses: get card RCA and quit open drain mode. |
355 | */ | 367 | */ |
356 | err = mmc_send_relative_addr(host, &card->rca); | 368 | if (!mmc_host_is_spi(host)) { |
357 | if (err) | 369 | err = mmc_send_relative_addr(host, &card->rca); |
358 | goto free_card; | 370 | if (err) |
371 | goto free_card; | ||
359 | 372 | ||
360 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); | 373 | mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); |
374 | } | ||
361 | 375 | ||
362 | if (!oldcard) { | 376 | if (!oldcard) { |
363 | /* | 377 | /* |
@@ -377,9 +391,11 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
377 | /* | 391 | /* |
378 | * Select card, as all following commands rely on that. | 392 | * Select card, as all following commands rely on that. |
379 | */ | 393 | */ |
380 | err = mmc_select_card(card); | 394 | if (!mmc_host_is_spi(host)) { |
381 | if (err) | 395 | err = mmc_select_card(card); |
382 | goto free_card; | 396 | if (err) |
397 | goto free_card; | ||
398 | } | ||
383 | 399 | ||
384 | if (!oldcard) { | 400 | if (!oldcard) { |
385 | /* | 401 | /* |
@@ -562,7 +578,8 @@ static void mmc_sd_suspend(struct mmc_host *host) | |||
562 | BUG_ON(!host->card); | 578 | BUG_ON(!host->card); |
563 | 579 | ||
564 | mmc_claim_host(host); | 580 | mmc_claim_host(host); |
565 | mmc_deselect_cards(host); | 581 | if (!mmc_host_is_spi(host)) |
582 | mmc_deselect_cards(host); | ||
566 | host->card->state &= ~MMC_STATE_HIGHSPEED; | 583 | host->card->state &= ~MMC_STATE_HIGHSPEED; |
567 | mmc_release_host(host); | 584 | mmc_release_host(host); |
568 | } | 585 | } |
@@ -623,6 +640,17 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr) | |||
623 | mmc_attach_bus(host, &mmc_sd_ops); | 640 | mmc_attach_bus(host, &mmc_sd_ops); |
624 | 641 | ||
625 | /* | 642 | /* |
643 | * We need to get OCR a different way for SPI. | ||
644 | */ | ||
645 | if (mmc_host_is_spi(host)) { | ||
646 | mmc_go_idle(host); | ||
647 | |||
648 | err = mmc_spi_read_ocr(host, 0, &ocr); | ||
649 | if (err) | ||
650 | goto err; | ||
651 | } | ||
652 | |||
653 | /* | ||
626 | * Sanity check the voltages that the card claims to | 654 | * Sanity check the voltages that the card claims to |
627 | * support. | 655 | * support. |
628 | */ | 656 | */ |