[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