]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/mmc/host/mmc_spi.c
Merge branch 'omap-pool'
[linux-2.6-omap-h63xx.git] / drivers / mmc / host / mmc_spi.c
index 87e211df68ac0dcdaf75c6aab9f4cce9ebad97ab..72f8bde4877a790f8d65f95450aae1723e521c84 100644 (file)
@@ -279,8 +279,11 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
                 * so it can always DMA directly into the target buffer.
                 * It'd probably be better to memcpy() the first chunk and
                 * avoid extra i/o calls...
+                *
+                * Note we check for more than 8 bytes, because in practice,
+                * some SD cards are slow...
                 */
-               for (i = 2; i < 9; i++) {
+               for (i = 2; i < 16; i++) {
                        value = mmc_spi_readbytes(host, 1);
                        if (value < 0)
                                goto done;
@@ -609,6 +612,7 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
        struct spi_device       *spi = host->spi;
        int                     status, i;
        struct scratch          *scratch = host->data;
+       u32                     pattern;
 
        if (host->mmc->use_spi_crc)
                scratch->crc_val = cpu_to_be16(
@@ -636,8 +640,27 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
         * doesn't necessarily tell whether the write operation succeeded;
         * it just says if the transmission was ok and whether *earlier*
         * writes succeeded; see the standard.
+        *
+        * In practice, there are (even modern SDHC-)cards which are late
+        * in sending the response, and miss the time frame by a few bits,
+        * so we have to cope with this situation and check the response
+        * bit-by-bit. Arggh!!!
         */
-       switch (SPI_MMC_RESPONSE_CODE(scratch->status[0])) {
+       pattern  = scratch->status[0] << 24;
+       pattern |= scratch->status[1] << 16;
+       pattern |= scratch->status[2] << 8;
+       pattern |= scratch->status[3];
+
+       /* First 3 bit of pattern are undefined */
+       pattern |= 0xE0000000;
+
+       /* left-adjust to leading 0 bit */
+       while (pattern & 0x80000000)
+               pattern <<= 1;
+       /* right-adjust for pattern matching. Code is in bit 4..0 now. */
+       pattern >>= 27;
+
+       switch (pattern) {
        case SPI_RESPONSE_ACCEPTED:
                status = 0;
                break;
@@ -668,8 +691,9 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
        /* Return when not busy.  If we didn't collect that status yet,
         * we'll need some more I/O.
         */
-       for (i = 1; i < sizeof(scratch->status); i++) {
-               if (scratch->status[i] != 0)
+       for (i = 4; i < sizeof(scratch->status); i++) {
+               /* card is non-busy if the most recent bit is 1 */
+               if (scratch->status[i] & 0x01)
                        return 0;
        }
        return mmc_spi_wait_unbusy(host, timeout);
@@ -1204,10 +1228,12 @@ static int mmc_spi_probe(struct spi_device *spi)
 
        /* MMC and SD specs only seem to care that sampling is on the
         * rising edge ... meaning SPI modes 0 or 3.  So either SPI mode
-        * should be legit.  We'll use mode 0 since it seems to be a
-        * bit less troublesome on some hardware ... unclear why.
+        * should be legit.  We'll use mode 0 since the steady state is 0,
+        * which is appropriate for hotplugging, unless the platform data
+        * specify mode 3 (if hardware is not compatible to mode 0).
         */
-       spi->mode = SPI_MODE_0;
+       if (spi->mode != SPI_MODE_3)
+               spi->mode = SPI_MODE_0;
        spi->bits_per_word = 8;
 
        status = spi_setup(spi);