public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.6.17-rc3-omap] omap_uwire byteswap bugfix
@ 2006-05-03  5:15 David Brownell
  2006-05-04 14:53 ` Paul Mundt
  0 siblings, 1 reply; 4+ messages in thread
From: David Brownell @ 2006-05-03  5:15 UTC (permalink / raw)
  To: linux-omap-open-source

[-- Attachment #1: Type: text/plain, Size: 586 bytes --]

I mentioned a while back that my original omap_uwire code had some bugs
that came from a bogus optimization ... here's a patch fixing them.
(Please merge...)

The consequence of that bogus optimization is that some SPI protocol
drivers (layered on top of this driver) would get data in strange byte
orders.  Hence for example an ads7846 issue that Juha and Imre noticed,
but were trying to fix at the wrong level.  (So in a moment I'll post
a separate patch for that driver.)

Other drivers layered on top of omap_uwire may also need to revisit
how they've handled byte order.

- Dave


[-- Attachment #2: omap-uwire.patch --]
[-- Type: text/x-diff, Size: 2442 bytes --]

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: David Brownell <dbrownell@users.sourceforge.net>

Index: osk/drivers/spi/omap_uwire.c
===================================================================
--- osk.orig/drivers/spi/omap_uwire.c	2006-04-22 14:41:22.000000000 -0700
+++ osk/drivers/spi/omap_uwire.c	2006-05-02 18:37:24.000000000 -0700
@@ -196,6 +196,9 @@ static int uwire_txrx(struct spi_device 
 	if (t->tx_buf && t->rx_buf)
 		return -EPERM;
 
+	if (!bits)
+		bits = 8;
+
 	w = spi->chip_select << 10;
 	w |= CS_CMD;
 
@@ -206,18 +209,15 @@ static int uwire_txrx(struct spi_device 
 
 		/* write one or two bytes at a time */
 		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++;
-			if (len > 1 && (!bits || bits > 8)) {
-				if (!bits)
-					bits = 16;
+			if (bits > 8) {
 				bytes = 2;
 				val |= *buf++ << 8;
-			} else {
-				if (!bits || bits > 8)
-					bits = 8;
+			} else
 				bytes = 1;
-			}
 			val <<= 16 - bits;
 
 #ifdef	VERBOSE
@@ -253,15 +253,10 @@ static int uwire_txrx(struct spi_device 
 
 		/* read one or two bytes at a time */
 		while (len) {
-			if (len > 1 && (!bits || bits > 8)) {
-				if (!bits)
-					bits = 16;
+			if (bits > 8) {
 				bytes = 2;
-			} else {
-				if (!bits || bits > 8)
-					bits = 8;
+			} else
 				bytes = 1;
-			}
 
 			/* start read */
 			val = START | w | (bits << 0);
@@ -275,7 +270,9 @@ static int uwire_txrx(struct spi_device 
 						RDRB, 0))
 				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 &= (1 << bits) - 1;
 			*buf++ = (u8) val;
@@ -320,6 +317,12 @@ static int uwire_setup(struct spi_device
 		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;
 	 * standard nCS signaling;
 	 * don't treat DI=high as "not ready"

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-05-04 17:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-05-03  5:15 [PATCH 2.6.17-rc3-omap] omap_uwire byteswap bugfix David Brownell
2006-05-04 14:53 ` Paul Mundt
2006-05-04 15:18   ` David Brownell
2006-05-04 17:07     ` David Brownell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox