aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorWolfgang Muees <wolfgang.mues@auerswald.de>2009-03-16 07:23:03 -0400
committerPierre Ossman <drzeus@drzeus.cx>2009-03-24 16:30:07 -0400
commitf079a8fc61e3dc35830f6abc58c21ae815ab4297 (patch)
tree20366f36bbe6e07d578e95ffa40bde583cb26706 /drivers/mmc
parente13bb3003a33df8f82cd027f8abfa5cd73f2eec0 (diff)
mmc_spi: adjust for delayed data token response
Some cards are not able to send the data token in time, but miss the time frame for some bits(!). So synchronize to the start of the token. Signed-off-by: Wolfgang Muees <wolfgang.mues@auerswald.de> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/mmc_spi.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 69e1442ff2e2..72f8bde4877a 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -612,6 +612,7 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
612 struct spi_device *spi = host->spi; 612 struct spi_device *spi = host->spi;
613 int status, i; 613 int status, i;
614 struct scratch *scratch = host->data; 614 struct scratch *scratch = host->data;
615 u32 pattern;
615 616
616 if (host->mmc->use_spi_crc) 617 if (host->mmc->use_spi_crc)
617 scratch->crc_val = cpu_to_be16( 618 scratch->crc_val = cpu_to_be16(
@@ -639,8 +640,27 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
639 * doesn't necessarily tell whether the write operation succeeded; 640 * doesn't necessarily tell whether the write operation succeeded;
640 * it just says if the transmission was ok and whether *earlier* 641 * it just says if the transmission was ok and whether *earlier*
641 * writes succeeded; see the standard. 642 * writes succeeded; see the standard.
643 *
644 * In practice, there are (even modern SDHC-)cards which are late
645 * in sending the response, and miss the time frame by a few bits,
646 * so we have to cope with this situation and check the response
647 * bit-by-bit. Arggh!!!
642 */ 648 */
643 switch (SPI_MMC_RESPONSE_CODE(scratch->status[0])) { 649 pattern = scratch->status[0] << 24;
650 pattern |= scratch->status[1] << 16;
651 pattern |= scratch->status[2] << 8;
652 pattern |= scratch->status[3];
653
654 /* First 3 bit of pattern are undefined */
655 pattern |= 0xE0000000;
656
657 /* left-adjust to leading 0 bit */
658 while (pattern & 0x80000000)
659 pattern <<= 1;
660 /* right-adjust for pattern matching. Code is in bit 4..0 now. */
661 pattern >>= 27;
662
663 switch (pattern) {
644 case SPI_RESPONSE_ACCEPTED: 664 case SPI_RESPONSE_ACCEPTED:
645 status = 0; 665 status = 0;
646 break; 666 break;
@@ -671,8 +691,9 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
671 /* Return when not busy. If we didn't collect that status yet, 691 /* Return when not busy. If we didn't collect that status yet,
672 * we'll need some more I/O. 692 * we'll need some more I/O.
673 */ 693 */
674 for (i = 1; i < sizeof(scratch->status); i++) { 694 for (i = 4; i < sizeof(scratch->status); i++) {
675 if (scratch->status[i] != 0) 695 /* card is non-busy if the most recent bit is 1 */
696 if (scratch->status[i] & 0x01)
676 return 0; 697 return 0;
677 } 698 }
678 return mmc_spi_wait_unbusy(host, timeout); 699 return mmc_spi_wait_unbusy(host, timeout);