aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorWolfgang Muees <wolfgang.mues@auerswald.de>2009-04-08 04:48:58 -0400
committerPierre Ossman <pierre@ossman.eu>2009-04-08 14:45:51 -0400
commitab5a643cf597f2214feb6ff7288c72589661bde1 (patch)
treeafa570e506d0b5eab61800d74bc3491dc3120664 /drivers/mmc
parenta8fe29d8bcdfbf85ba26c7f3522c4bdfbc83e71d (diff)
mmc_spi: support for non-byte-aligned cards
A very large subset of SD cards in the market send their responses and data non-byte-aligned. So add logic to the mmc spi driver to handle this mess. Signed-off-by: Wolfgang Muees <wolfgang.mues@auerswald.de> Signed-off-by: Pierre Ossman <pierre@ossman.eu>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/mmc_spi.c150
1 files changed, 112 insertions, 38 deletions
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index ed02ebd899d1..f48349d18c92 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -254,6 +254,10 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
254 u8 *cp = host->data->status; 254 u8 *cp = host->data->status;
255 u8 *end = cp + host->t.len; 255 u8 *end = cp + host->t.len;
256 int value = 0; 256 int value = 0;
257 int bitshift;
258 u8 leftover = 0;
259 unsigned short rotator;
260 int i;
257 char tag[32]; 261 char tag[32];
258 262
259 snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s", 263 snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s",
@@ -271,9 +275,8 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
271 275
272 /* Data block reads (R1 response types) may need more data... */ 276 /* Data block reads (R1 response types) may need more data... */
273 if (cp == end) { 277 if (cp == end) {
274 unsigned i;
275
276 cp = host->data->status; 278 cp = host->data->status;
279 end = cp+1;
277 280
278 /* Card sends N(CR) (== 1..8) bytes of all-ones then one 281 /* Card sends N(CR) (== 1..8) bytes of all-ones then one
279 * status byte ... and we already scanned 2 bytes. 282 * status byte ... and we already scanned 2 bytes.
@@ -298,20 +301,34 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
298 } 301 }
299 302
300checkstatus: 303checkstatus:
301 if (*cp & 0x80) { 304 bitshift = 0;
302 dev_dbg(&host->spi->dev, "%s: INVALID RESPONSE, %02x\n", 305 if (*cp & 0x80) {
303 tag, *cp); 306 /* Houston, we have an ugly card with a bit-shifted response */
304 value = -EBADR; 307 rotator = *cp++ << 8;
305 goto done; 308 /* read the next byte */
309 if (cp == end) {
310 value = mmc_spi_readbytes(host, 1);
311 if (value < 0)
312 goto done;
313 cp = host->data->status;
314 end = cp+1;
315 }
316 rotator |= *cp++;
317 while (rotator & 0x8000) {
318 bitshift++;
319 rotator <<= 1;
320 }
321 cmd->resp[0] = rotator >> 8;
322 leftover = rotator;
323 } else {
324 cmd->resp[0] = *cp++;
306 } 325 }
307
308 cmd->resp[0] = *cp++;
309 cmd->error = 0; 326 cmd->error = 0;
310 327
311 /* Status byte: the entire seven-bit R1 response. */ 328 /* Status byte: the entire seven-bit R1 response. */
312 if (cmd->resp[0] != 0) { 329 if (cmd->resp[0] != 0) {
313 if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS 330 if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS
314 | R1_SPI_ILLEGAL_COMMAND) 331 | R1_SPI_ILLEGAL_COMMAND)
315 & cmd->resp[0]) 332 & cmd->resp[0])
316 value = -EINVAL; 333 value = -EINVAL;
317 else if (R1_SPI_COM_CRC & cmd->resp[0]) 334 else if (R1_SPI_COM_CRC & cmd->resp[0])
@@ -339,12 +356,45 @@ checkstatus:
339 * SPI R5 == R1 + data byte; IO_RW_DIRECT 356 * SPI R5 == R1 + data byte; IO_RW_DIRECT
340 */ 357 */
341 case MMC_RSP_SPI_R2: 358 case MMC_RSP_SPI_R2:
342 cmd->resp[0] |= *cp << 8; 359 /* read the next byte */
360 if (cp == end) {
361 value = mmc_spi_readbytes(host, 1);
362 if (value < 0)
363 goto done;
364 cp = host->data->status;
365 end = cp+1;
366 }
367 if (bitshift) {
368 rotator = leftover << 8;
369 rotator |= *cp << bitshift;
370 cmd->resp[0] |= (rotator & 0xFF00);
371 } else {
372 cmd->resp[0] |= *cp << 8;
373 }
343 break; 374 break;
344 375
345 /* SPI R3, R4, or R7 == R1 + 4 bytes */ 376 /* SPI R3, R4, or R7 == R1 + 4 bytes */
346 case MMC_RSP_SPI_R3: 377 case MMC_RSP_SPI_R3:
347 cmd->resp[1] = get_unaligned_be32(cp); 378 rotator = leftover << 8;
379 cmd->resp[1] = 0;
380 for (i = 0; i < 4; i++) {
381 cmd->resp[1] <<= 8;
382 /* read the next byte */
383 if (cp == end) {
384 value = mmc_spi_readbytes(host, 1);
385 if (value < 0)
386 goto done;
387 cp = host->data->status;
388 end = cp+1;
389 }
390 if (bitshift) {
391 rotator |= *cp++ << bitshift;
392 cmd->resp[1] |= (rotator >> 8);
393 rotator <<= 8;
394 } else {
395 cmd->resp[1] |= *cp++;
396 }
397 }
348 break; 398 break;
349 399
350 /* SPI R1 == just one status byte */ 400 /* SPI R1 == just one status byte */
@@ -725,6 +775,8 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
725 struct spi_device *spi = host->spi; 775 struct spi_device *spi = host->spi;
726 int status; 776 int status;
727 struct scratch *scratch = host->data; 777 struct scratch *scratch = host->data;
778 unsigned int bitshift;
779 u8 leftover;
728 780
729 /* At least one SD card sends an all-zeroes byte when N(CX) 781 /* At least one SD card sends an all-zeroes byte when N(CX)
730 * applies, before the all-ones bytes ... just cope with that. 782 * applies, before the all-ones bytes ... just cope with that.
@@ -736,38 +788,60 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
736 if (status == 0xff || status == 0) 788 if (status == 0xff || status == 0)
737 status = mmc_spi_readtoken(host, timeout); 789 status = mmc_spi_readtoken(host, timeout);
738 790
739 if (status == SPI_TOKEN_SINGLE) { 791 if (status < 0) {
740 if (host->dma_dev) { 792 dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
741 dma_sync_single_for_device(host->dma_dev, 793 return status;
742 host->data_dma, sizeof(*scratch), 794 }
743 DMA_BIDIRECTIONAL);
744 dma_sync_single_for_device(host->dma_dev,
745 t->rx_dma, t->len,
746 DMA_FROM_DEVICE);
747 }
748 795
749 status = spi_sync(spi, &host->m); 796 /* The token may be bit-shifted...
797 * the first 0-bit precedes the data stream.
798 */
799 bitshift = 7;
800 while (status & 0x80) {
801 status <<= 1;
802 bitshift--;
803 }
804 leftover = status << 1;
750 805
751 if (host->dma_dev) { 806 if (host->dma_dev) {
752 dma_sync_single_for_cpu(host->dma_dev, 807 dma_sync_single_for_device(host->dma_dev,
753 host->data_dma, sizeof(*scratch), 808 host->data_dma, sizeof(*scratch),
754 DMA_BIDIRECTIONAL); 809 DMA_BIDIRECTIONAL);
755 dma_sync_single_for_cpu(host->dma_dev, 810 dma_sync_single_for_device(host->dma_dev,
756 t->rx_dma, t->len, 811 t->rx_dma, t->len,
757 DMA_FROM_DEVICE); 812 DMA_FROM_DEVICE);
758 } 813 }
759 814
760 } else { 815 status = spi_sync(spi, &host->m);
761 dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
762 816
763 /* we've read extra garbage, timed out, etc */ 817 if (host->dma_dev) {
764 if (status < 0) 818 dma_sync_single_for_cpu(host->dma_dev,
765 return status; 819 host->data_dma, sizeof(*scratch),
820 DMA_BIDIRECTIONAL);
821 dma_sync_single_for_cpu(host->dma_dev,
822 t->rx_dma, t->len,
823 DMA_FROM_DEVICE);
824 }
766 825
767 /* low four bits are an R2 subset, fifth seems to be 826 if (bitshift) {
768 * vendor specific ... map them all to generic error.. 827 /* Walk through the data and the crc and do
828 * all the magic to get byte-aligned data.
769 */ 829 */
770 return -EIO; 830 u8 *cp = t->rx_buf;
831 unsigned int len;
832 unsigned int bitright = 8 - bitshift;
833 u8 temp;
834 for (len = t->len; len; len--) {
835 temp = *cp;
836 *cp++ = leftover | (temp >> bitshift);
837 leftover = temp << bitright;
838 }
839 cp = (u8 *) &scratch->crc_val;
840 temp = *cp;
841 *cp++ = leftover | (temp >> bitshift);
842 leftover = temp << bitright;
843 temp = *cp;
844 *cp = leftover | (temp >> bitshift);
771 } 845 }
772 846
773 if (host->mmc->use_spi_crc) { 847 if (host->mmc->use_spi_crc) {