Commit 0b50a217 authored by David Brownell's avatar David Brownell Committed by Tony Lindgren

[PATCH] ARM: OMAP: omap_uwire byteswap bugfix

Get rid of broken optimization in MicroWire driver:  don't try to morph
consecutive single-byte operations into one (faster) two-byte operation.
This resolves some byteswap problems.  (And consequently allows fixing
some bugs in at least the OMAP version of the ads7846 driver...)

Also, reject LSB-first device modes; this controller doesn't support them.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 9d1ca153
...@@ -196,6 +196,9 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t) ...@@ -196,6 +196,9 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
if (t->tx_buf && t->rx_buf) if (t->tx_buf && t->rx_buf)
return -EPERM; return -EPERM;
if (!bits)
bits = 8;
w = spi->chip_select << 10; w = spi->chip_select << 10;
w |= CS_CMD; w |= CS_CMD;
...@@ -206,18 +209,15 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t) ...@@ -206,18 +209,15 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
/* write one or two bytes at a time */ /* write one or two bytes at a time */
while (len >= 1) { while (len >= 1) {
/* tx is msb-aligned */ /* tx bit 15 is first sent; we byteswap multibyte words
* (msb-first) on the way out from memory.
*/
val = *buf++; val = *buf++;
if (len > 1 && (!bits || bits > 8)) { if (bits > 8) {
if (!bits)
bits = 16;
bytes = 2; bytes = 2;
val |= *buf++ << 8; val |= *buf++ << 8;
} else { } else
if (!bits || bits > 8)
bits = 8;
bytes = 1; bytes = 1;
}
val <<= 16 - bits; val <<= 16 - bits;
#ifdef VERBOSE #ifdef VERBOSE
...@@ -253,15 +253,10 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t) ...@@ -253,15 +253,10 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
/* read one or two bytes at a time */ /* read one or two bytes at a time */
while (len) { while (len) {
if (len > 1 && (!bits || bits > 8)) { if (bits > 8) {
if (!bits)
bits = 16;
bytes = 2; bytes = 2;
} else { } else
if (!bits || bits > 8)
bits = 8;
bytes = 1; bytes = 1;
}
/* start read */ /* start read */
val = START | w | (bits << 0); val = START | w | (bits << 0);
...@@ -275,7 +270,9 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t) ...@@ -275,7 +270,9 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
RDRB, 0)) RDRB, 0))
goto eio; goto eio;
/* rx is lsb-aligned */ /* rx bit 0 is last received; multibyte words will
* be properly byteswapped on the way to memory.
*/
val = uwire_read_reg(UWIRE_RDR); val = uwire_read_reg(UWIRE_RDR);
val &= (1 << bits) - 1; val &= (1 << bits) - 1;
*buf++ = (u8) val; *buf++ = (u8) val;
...@@ -320,6 +317,12 @@ static int uwire_setup(struct spi_device *spi) ...@@ -320,6 +317,12 @@ static int uwire_setup(struct spi_device *spi)
goto done; goto done;
} }
if (spi->mode & SPI_LSB_FIRST) {
pr_debug("%s: lsb first?\n", spi->dev.bus_id);
status = -EINVAL;
goto done;
}
/* mode 0..3, clock inverted separately; /* mode 0..3, clock inverted separately;
* standard nCS signaling; * standard nCS signaling;
* don't treat DI=high as "not ready" * don't treat DI=high as "not ready"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment