summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2012-07-31 19:14:22 +0000
committerimp <imp@FreeBSD.org>2012-07-31 19:14:22 +0000
commite198ea51a0132a8c26a6b42d6723c82f0560871b (patch)
tree9e633562a111d14cc679ce750737af39fa18d7b7
parent3fbbc135fcae885279751f17af68a3f9b2f8bc12 (diff)
downloadFreeBSD-src-e198ea51a0132a8c26a6b42d6723c82f0560871b.zip
FreeBSD-src-e198ea51a0132a8c26a6b42d6723c82f0560871b.tar.gz
Allow chip selects other than 0. The SAM9260EK board
has its dataflash on CS1.
-rw-r--r--sys/arm/at91/at91_spi.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/arm/at91/at91_spi.c b/sys/arm/at91/at91_spi.c
index a81e0be..f01e984 100644
--- a/sys/arm/at91/at91_spi.c
+++ b/sys/arm/at91/at91_spi.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
+#include <arm/at91/at91var.h>
#include <arm/at91/at91_spireg.h>
#include <arm/at91/at91_pdcreg.h>
@@ -144,6 +145,7 @@ at91_spi_attach(device_t dev)
* memory and APB bandwidth.
* Also, currently we lack a way for lettting both the board and the
* slave devices take their maximum supported SPI clocks into account.
+ * Also, we hard-wire SPI mode to 3.
*/
csr = SPI_CSR_CPOL | (4 << 16) | (0xff << 8);
WR4(sc, SPI_CSR0, csr);
@@ -285,7 +287,10 @@ at91_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
*/
WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
-#ifdef SPI_CHIPSEL_SUPPORT
+ /*
+ * PSCDEC = 0 has a range of 0..3 for chip select. We
+ * don't support PSCDEC = 1 which has a range of 0..15.
+ */
if (cmd->cs < 0 || cmd->cs > 3) {
device_printf(dev,
"Invalid chip select %d requested by %s\n", cmd->cs,
@@ -293,18 +298,23 @@ at91_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
err = EINVAL;
goto out;
}
+
#ifdef SPI_CHIP_SELECT_HIGH_SUPPORT
+ /*
+ * The AT91RM9200 couldn't do CS high for CS 0. Other chips can, but we
+ * don't support that yet, or other spi modes.
+ */
if (at91_is_rm92() && cmd->cs == 0 &&
(cmd->flags & SPI_CHIP_SELECT_HIGH) != 0) {
device_printf(dev,
- "Invalid chip select high requested by %s\n",
+ "Invalid chip select high requested by %s for cs 0.\n",
device_get_nameunit(child));
err = EINVAL;
goto out;
}
#endif
- WR4(sc, SPI_MR, (RD4(sc, SPI_MR) & ~0x000f0000) | CS_TO_MR(cmd->cs));
-#endif
+ err = (RD4(sc, SPI_MR) & ~0x000f0000) | CS_TO_MR(cmd->cs);
+ WR4(sc, SPI_MR, err);
/*
* Set up the TX side of the transfer.
OpenPOWER on IntegriCloud