
This patch adds a SPI driver for the PPC440EPx processor.
Signed-off-by: Steven A. Falco sfalco@harris.com --- Sorry - forgot the subject line, the first time.
cpu/ppc4xx/Makefile | 1 + cpu/ppc4xx/spi.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/4xx_spi.h | 50 ++++++++++++++++++++ 3 files changed, 179 insertions(+), 0 deletions(-) create mode 100644 cpu/ppc4xx/spi.c create mode 100644 include/4xx_spi.h
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile index 96ab5c6..bdebfb6 100644 --- a/cpu/ppc4xx/Makefile +++ b/cpu/ppc4xx/Makefile @@ -54,6 +54,7 @@ COBJS += iop480_uart.o COBJS += ndfc.o COBJS += sdram.o COBJS += speed.o +COBJS += spi.o COBJS += tlb.o COBJS += traps.o COBJS += usb.o diff --git a/cpu/ppc4xx/spi.c b/cpu/ppc4xx/spi.c new file mode 100644 index 0000000..572244b --- /dev/null +++ b/cpu/ppc4xx/spi.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008 Harris Corporation + * Author: Steven A. Falco sfalco@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 <4xx_spi.h> + +#if defined(CONFIG_HARD_SPI) + +void spi_init (void ) +{ + volatile u8 *cd = (volatile u8 *) SPI_CDM; + volatile u8 *md = (volatile u8 *) SPI_MODE; + + *cd = 0; /* Default to "go fast" */ + *md = SPI_MODE_SPE; /* Enable port */ +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + volatile u8 *md = (volatile u8 *) SPI_MODE; + volatile u8 *cd = (volatile u8 *) SPI_CDM; + 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; + + *cd = divisor; + + if (!(s = malloc(sizeof(struct spi_slave)))) + return NULL; + + if (mode & SPI_CPHA) + *md &= ~SPI_MODE_SCP; + else + *md |= SPI_MODE_SCP; + + if (mode & SPI_CPOL) + *md |= SPI_MODE_CI; + else + *md &= ~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) +{ +} + +#define GO *cr = SPI_CR_STR +#define TXWAIT while(*sr & SPI_SR_BSY) +#define RXWAIT while(!(*sr & SPI_SR_RBR)) + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + volatile u8 *cr = (volatile u8 *) SPI_CR; + volatile u8 *sr = (volatile u8 *) SPI_SR; + volatile u8 *tx = (volatile u8 *) SPI_TXD; + volatile u8 *rx = (volatile u8 *) SPI_RXD; + + 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++) { + TXWAIT; + *tx = *txd++; + GO; + RXWAIT; + *rxd++ = *rx; + } + + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); + + return 0; +} + +#endif /* CONFIG_HARD_SPI */ diff --git a/include/4xx_spi.h b/include/4xx_spi.h new file mode 100644 index 0000000..331de20 --- /dev/null +++ b/include/4xx_spi.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 Harris Corporation + * Author: Steven A. Falco sfalco@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_ + +#if defined(CONFIG_440EPX) +#define SPI_BASE_ADDR (CONFIG_SYS_PERIPHERAL_BASE + 0x00000900) +#endif + +#define SPI_REGISTERS_BASE_ADDRESS SPI_BASE_ADDR +#define SPI_MODE (SPI_REGISTERS_BASE_ADDRESS + 0x00) +#define SPI_RXD (SPI_REGISTERS_BASE_ADDRESS + 0x01) +#define SPI_TXD (SPI_REGISTERS_BASE_ADDRESS + 0x02) +#define SPI_CR (SPI_REGISTERS_BASE_ADDRESS + 0x03) +#define SPI_SR (SPI_REGISTERS_BASE_ADDRESS + 0x04) +#define SPI_CDM (SPI_REGISTERS_BASE_ADDRESS + 0x06) + +#define SPI_CR_STR (0x01) + +#define SPI_SR_RBR (0x01) +#define SPI_SR_BSY (0x02) + +#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) + +#endif /* _4xx_spi_h_ */