This patch adds the driver of altera spi controller, which is also used as epcs/spi flash controller.
With the spi_flash driver, they can replace the epcs driver at cpu/nios2/epcs.c. Signed-off-by: Thomas Chou <tho...@wytron.com.tw> --- drivers/spi/Makefile | 1 + drivers/spi/altera_spi.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/altera_spi.c diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index f112ed0..dfcbb8b 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libspi.a +COBJS-$(CONFIG_ALTERA_SPI) += altera_spi.o COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c new file mode 100644 index 0000000..72097a6 --- /dev/null +++ b/drivers/spi/altera_spi.c @@ -0,0 +1,103 @@ +/* + * Altera SPI driver + * + * Copyright (C) 2010 Thomas Chou <tho...@wytron.com.tw> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <common.h> +#include <asm/io.h> +#include <malloc.h> +#include <spi.h> + +#define ALTERA_SPI_RXDATA 0 +#define ALTERA_SPI_TXDATA 4 +#define ALTERA_SPI_STATUS 8 +#define ALTERA_SPI_CONTROL 12 +#define ALTERA_SPI_SLAVE_SEL 20 + +#define ALTERA_SPI_STATUS_ROE_MSK (0x8) +#define ALTERA_SPI_STATUS_TOE_MSK (0x10) +#define ALTERA_SPI_STATUS_TMT_MSK (0x20) +#define ALTERA_SPI_STATUS_TRDY_MSK (0x40) +#define ALTERA_SPI_STATUS_RRDY_MSK (0x80) +#define ALTERA_SPI_STATUS_E_MSK (0x100) + +#define ALTERA_SPI_CONTROL_IROE_MSK (0x8) +#define ALTERA_SPI_CONTROL_ITOE_MSK (0x10) +#define ALTERA_SPI_CONTROL_ITRDY_MSK (0x40) +#define ALTERA_SPI_CONTROL_IRRDY_MSK (0x80) +#define ALTERA_SPI_CONTROL_IE_MSK (0x100) +#define ALTERA_SPI_CONTROL_SSO_MSK (0x400) + +void spi_init(void) +{ + /* empty read buffer */ + if (readl(CONFIG_SYS_SPI_BASE + ALTERA_SPI_STATUS) & + ALTERA_SPI_STATUS_RRDY_MSK) + readl(CONFIG_SYS_SPI_BASE + ALTERA_SPI_RXDATA); + return; +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct spi_slave *slave; + + slave = malloc(sizeof(struct spi_slave)); + if (!slave) + return NULL; + + slave->bus = bus; + slave->cs = cs; + + return slave; +} + +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) +{ + return; +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + int i, iter = bitlen >> 3; + const uchar *txp = dout; + uchar *rxp = din; + uchar d; + + if (flags & SPI_XFER_BEGIN) { + writel(1 << slave->cs, + CONFIG_SYS_SPI_BASE + ALTERA_SPI_SLAVE_SEL); + writel(ALTERA_SPI_CONTROL_SSO_MSK, + CONFIG_SYS_SPI_BASE + ALTERA_SPI_CONTROL); + } + + for (i = 0; i < iter; i++) { + writel(txp ? txp[i] : 0, + CONFIG_SYS_SPI_BASE + ALTERA_SPI_TXDATA); + while (!(readl(CONFIG_SYS_SPI_BASE + ALTERA_SPI_STATUS) & + ALTERA_SPI_STATUS_RRDY_MSK)) + ; + d = readl(CONFIG_SYS_SPI_BASE + ALTERA_SPI_RXDATA); + if (rxp) + rxp[i] = d; + } + if (flags & SPI_XFER_END) + writel(0, CONFIG_SYS_SPI_BASE + ALTERA_SPI_CONTROL); + + return 0; +} -- 1.6.6.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot