This patch adds an SPI driver for the 440EPx processor.

Tested on Sequoia.

Signed-off-by: Steven A. Falco <[EMAIL PROTECTED]>
---
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 <[EMAIL PROTECTED]>
+ *
+ * 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 <[EMAIL PROTECTED]>
+ *
+ * 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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to