Thread (25 messages) flat view 25 messages, 6 authors, 2016-02-11
STALE3856d REVIEWED: 2 (0M)

2 review trailers.

[PATCH 3/4] spi: bcm2835aux: set up spi-mode before asserting cs-gpio

From: Martin Sperl <hidden>
Date: 2016-02-11 18:06:43
Also in: linux-spi

quoted hunk ↗ jump to hunk
On 09.02.2016, at 19:10, stephanolbrich at gmx.de wrote:

From: Stephan Olbrich <redacted>

When using reverse polarity for clock (spi-cpol) on a device
the clock line gets altered after chip-select has been asserted
resulting in an additional clock beat, which confuses hardware.

To avoid this situation this patch moves the setup of polarity
(spi-cpol and spi-cpha) outside of the chip-select into
prepare_message, which is run prior to asserting chip-select.

Signed-off-by: Stephan Olbrich <redacted>
---
drivers/spi/spi-bcm2835aux.c | 54 +++++++++++++++++++++++++++++++-------------
1 file changed, 38 insertions(+), 16 deletions(-)
diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c
index d2f0067..b90aa34 100644
--- a/drivers/spi/spi-bcm2835aux.c
+++ b/drivers/spi/spi-bcm2835aux.c
@@ -218,9 +218,9 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
			BCM2835_AUX_SPI_CNTL1_IDLE);
	}

-	/* and if rx_len is 0 then wake up completion and disable spi */
+	/* and if rx_len is 0 then disable interrupts and wake up completion */
	if (!bs->rx_len) {
-		bcm2835aux_spi_reset_hw(bs);
+		bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
		complete(&master->xfer_completion);
	}
@@ -313,9 +313,6 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
		}
	}

-	/* Transfer complete - reset SPI HW */
-	bcm2835aux_spi_reset_hw(bs);
-
	/* and return without waiting for completion */
	return 0;
}
@@ -336,10 +333,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
	 * resulting (potentially) in more interrupts when transferring
	 * more than 12 bytes
	 */
-	bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE |
-		      BCM2835_AUX_SPI_CNTL0_VAR_WIDTH |
-		      BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
-	bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN;

	/* set clock */
	spi_hz = tfr->speed_hz;
@@ -358,13 +351,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
Note that here you need to explicitly mask out the clock!
otherwise spi messages with different clock speeds will fill up the 
bitfield of the clock divider with the wrong values.

This has not happened before because the values were re-computed every time
now we defer it to prepare
@@ -348,17 +345,12 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *
        } else { /* the slowest we can go */
                speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX;
        }
+	/* mask out old speed from previous spi_transfer */
+       bs->cntl[0] &= ~BCM2835_AUX_SPI_CNTL0_SPEED;
+	/* set the new speed */
        bs->cntl[0] |= speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT;
	spi_used_hz = clk_hz / (2 * (speed + 1));

-	/* handle all the modes */
-	if (spi->mode & SPI_CPOL)
-		bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL;
-	if (spi->mode & SPI_CPHA)
-		bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT |
-			       BCM2835_AUX_SPI_CNTL0_CPHA_IN;
-
	/* set transmit buffers and length */
	bs->tx_buf = tfr->tx_buf;
	bs->rx_buf = tfr->rx_buf;

quoted hunk ↗ jump to hunk
@@ -388,6 +374,40 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
	return bcm2835aux_spi_transfer_one_irq(master, spi, tfr);
}

+
+static int bcm2835aux_spi_unprepare_message(struct spi_master *master,
+					    struct spi_message *msg)
+{
+	struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+
+	bcm2835aux_spi_reset_hw(bs);
+
+	return 0;
+}
+
I was wondering a long time why we would need this - but after
some experimentation it became clear: with auxspi disabled driving
the gates so they go into their default states (low) before GPIO-cs
is de-asserted.

It may be worth mentioning that fact - others might wonder as
well later later.

With the above in place:
Reviewed-by: Martin Sperl <redacted>
Tested-by: Martin Sperl <redacted>

Martin
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help