[U-Boot] [PATCH v3 1/2] ppc4xx: Add PPC4xx SPI driver
Steven A. Falco
sfalco at harris.com
Tue Dec 9 17:24:22 CET 2008
This patch adds an SPI driver for the 440EPx processor.
Tested on Sequoia.
Signed-off-by: Steven A. Falco <sfalco at harris.com>
---
Thanks for the comments.
I've added the in/out accessors, and included the other comments made by
reviewers (inlines, etc). The patch passes a checkpatch test.
drivers/spi/Makefile | 1 +
drivers/spi/ppc4xx_spi.c | 141 ++++++++++++++++++++++++++++++++++++++++++
include/asm-ppc/ppc4xx_spi.h | 58 +++++++++++++++++
3 files changed, 200 insertions(+), 0 deletions(-)
create mode 100644 drivers/spi/ppc4xx_spi.c
create mode 100644 include/asm-ppc/ppc4xx_spi.h
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 15e0f7a..a699760 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -28,6 +28,7 @@ LIB := $(obj)libspi.a
COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o
COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
+COBJS-$(CONFIG_PPC4xx_SPI) += ppc4xx_spi.o
COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
COBJS := $(COBJS-y)
diff --git a/drivers/spi/ppc4xx_spi.c b/drivers/spi/ppc4xx_spi.c
new file mode 100644
index 0000000..273f8c4
--- /dev/null
+++ b/drivers/spi/ppc4xx_spi.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2008 Harris Corporation
+ * Author: Steven A. Falco <sfalco at harris.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <spi.h>
+#include <malloc.h>
+
+#include <asm/io.h>
+#include <asm/ppc4xx_spi.h>
+
+void spi_init(void)
+{
+ spi4xx_t *spi = (spi4xx_t *) SPI_BASE_ADDR;
+
+ out_8(&spi->cdm, 0); /* Default to the highest speed */
+ out_8(&spi->mode, SPI_MODE_SPE); /* Enable the port */
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int mode)
+{
+ spi4xx_t *spi = (spi4xx_t *) SPI_BASE_ADDR;
+
+ ulong opb = get_OPB_freq();
+ ulong divisor;
+ struct spi_slave *s;
+
+ if (!spi_cs_is_valid(bus, cs))
+ return NULL;
+
+ divisor = ((opb + (max_hz * 4) - 1) / (max_hz * 4)) - 1;
+ if (divisor > 255)
+ return NULL;
+
+ out_8(&spi->cdm, divisor);
+
+ s = malloc(sizeof(struct spi_slave));
+ if (!s)
+ return NULL;
+
+ if (mode & SPI_CPHA)
+ clrbits_8(&spi->mode, SPI_MODE_SCP);
+ else
+ setbits_8(&spi->mode, SPI_MODE_SCP);
+
+ if (mode & SPI_CPOL)
+ setbits_8(&spi->mode, SPI_MODE_CI);
+ else
+ clrbits_8(&spi->mode, SPI_MODE_CI);
+
+ s->bus = bus;
+ s->cs = cs;
+
+ return s;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+ free(slave);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+ return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+}
+
+/* Start an 8-bit transaction. */
+static inline void spi_start(spi4xx_t *spi)
+{
+ out_8(&spi->cr, SPI_CR_STR);
+}
+
+/* Wait for the TX to be empty. */
+static inline void spi_tx_wait(spi4xx_t *spi)
+{
+ while (in_8(&spi->sr) & SPI_SR_BSY)
+ ;
+}
+
+/* Wait for the RX to have data. */
+static inline void spi_rx_wait(spi4xx_t *spi)
+{
+ while (!(in_8(&spi->sr) & SPI_SR_RBR))
+ ;
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ spi4xx_t *spi = (spi4xx_t *) SPI_BASE_ADDR;
+
+ const u8 *txd = dout;
+ u8 *rxd = din;
+ int ii;
+
+ if (flags & SPI_XFER_BEGIN)
+ spi_cs_activate(slave);
+
+ /* Do a byte at a time */
+ for (ii = 0; ii < ((bitlen + 7) / 8); ii++) {
+ /* Wait for room, then load the next byte. */
+ spi_tx_wait(spi);
+ out_8(&spi->txd, *txd++);
+
+ /* Send/receive 8 bits. */
+ spi_start(spi);
+
+ /* Wait for the incoming byte, then store it. */
+ spi_rx_wait(spi);
+ *rxd++ = in_8(&spi->rxd);
+ }
+
+ if (flags & SPI_XFER_END)
+ spi_cs_deactivate(slave);
+
+ return 0;
+}
diff --git a/include/asm-ppc/ppc4xx_spi.h b/include/asm-ppc/ppc4xx_spi.h
new file mode 100644
index 0000000..f908ef8
--- /dev/null
+++ b/include/asm-ppc/ppc4xx_spi.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 Harris Corporation
+ * Author: Steven A. Falco <sfalco at harris.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _4xx_spi_h_
+#define _4xx_spi_h_
+
+#include <asm/types.h>
+
+#if defined(CONFIG_440EPX) || \
+ defined(CONFIG_440GRX)
+#define SPI_BASE_ADDR (CONFIG_SYS_PERIPHERAL_BASE + 0x00000900)
+#endif
+
+/* Bits in the command register */
+#define SPI_CR_STR 0x01
+
+/* Bits in the status register */
+#define SPI_SR_RBR 0x01
+#define SPI_SR_BSY 0x02
+
+/* Bits in the mode register */
+#define SPI_MODE_IL 0x01
+#define SPI_MODE_CI 0x02
+#define SPI_MODE_RD 0x04
+#define SPI_MODE_SPE 0x08
+#define SPI_MODE_SCP 0x10
+
+typedef struct spi4xx {
+ u8 mode; /* mode register */
+ u8 rxd; /* receive register */
+ u8 txd; /* transmit register */
+ u8 cr; /* command register */
+ u8 sr; /* status register */
+ u8 res0; /* reserved */
+ u8 cdm; /* clock divisor */
+} spi4xx_t;
+
+#endif /* _4xx_spi_h_ */
--
1.6.0.2
More information about the U-Boot
mailing list