diff options
| author | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2008-12-17 16:53:07 +0100 | 
|---|---|---|
| committer | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2008-12-17 16:53:07 +0100 | 
| commit | cb5473205206c7f14cbb1e747f28ec75b48826e2 (patch) | |
| tree | 8f4808d60917100b18a10b05230f7638a0a9bbcc /cpu/mcf5227x/dspi.c | |
| parent | baf449fc5ff96f071bb0e3789fd3265f6d4fd9a0 (diff) | |
| parent | 92c78a3bbcb2ce508b4bf1c4a1e0940406a024bb (diff) | |
| download | olio-uboot-2014.01-cb5473205206c7f14cbb1e747f28ec75b48826e2.tar.xz olio-uboot-2014.01-cb5473205206c7f14cbb1e747f28ec75b48826e2.zip | |
Merge branch 'fixes' into cleanups
Conflicts:
	board/atmel/atngw100/atngw100.c
	board/atmel/atstk1000/atstk1000.c
	cpu/at32ap/at32ap700x/gpio.c
	include/asm-avr32/arch-at32ap700x/clk.h
	include/configs/atngw100.h
	include/configs/atstk1002.h
	include/configs/atstk1003.h
	include/configs/atstk1004.h
	include/configs/atstk1006.h
	include/configs/favr-32-ezkit.h
	include/configs/hammerhead.h
	include/configs/mimc200.h
Diffstat (limited to 'cpu/mcf5227x/dspi.c')
| -rw-r--r-- | cpu/mcf5227x/dspi.c | 261 | 
1 files changed, 261 insertions, 0 deletions
| diff --git a/cpu/mcf5227x/dspi.c b/cpu/mcf5227x/dspi.c new file mode 100644 index 000000000..7f48f9184 --- /dev/null +++ b/cpu/mcf5227x/dspi.c @@ -0,0 +1,261 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.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> + +#if defined(CONFIG_CF_DSPI) +#include <asm/immap.h> + +void dspi_init(void) +{ +	volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; +	volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; + +	gpio->par_dspi = +	    GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT | +	    GPIO_PAR_DSPI_SCK_SCK; + +	dspi->dmcr = DSPI_DMCR_MSTR | DSPI_DMCR_CSIS7 | DSPI_DMCR_CSIS6 | +	    DSPI_DMCR_CSIS5 | DSPI_DMCR_CSIS4 | DSPI_DMCR_CSIS3 | +	    DSPI_DMCR_CSIS2 | DSPI_DMCR_CSIS1 | DSPI_DMCR_CSIS0 | +	    DSPI_DMCR_CRXF | DSPI_DMCR_CTXF; + +#ifdef CONFIG_SYS_DSPI_DCTAR0 +	dspi->dctar0 = CONFIG_SYS_DSPI_DCTAR0; +#endif +#ifdef CONFIG_SYS_DSPI_DCTAR1 +	dspi->dctar1 = CONFIG_SYS_DSPI_DCTAR1; +#endif +#ifdef CONFIG_SYS_DSPI_DCTAR2 +	dspi->dctar2 = CONFIG_SYS_DSPI_DCTAR2; +#endif +#ifdef CONFIG_SYS_DSPI_DCTAR3 +	dspi->dctar3 = CONFIG_SYS_DSPI_DCTAR3; +#endif +#ifdef CONFIG_SYS_DSPI_DCTAR4 +	dspi->dctar4 = CONFIG_SYS_DSPI_DCTAR4; +#endif +#ifdef CONFIG_SYS_DSPI_DCTAR5 +	dspi->dctar5 = CONFIG_SYS_DSPI_DCTAR5; +#endif +#ifdef CONFIG_SYS_DSPI_DCTAR6 +	dspi->dctar6 = CONFIG_SYS_DSPI_DCTAR6; +#endif +#ifdef CONFIG_SYS_DSPI_DCTAR7 +	dspi->dctar7 = CONFIG_SYS_DSPI_DCTAR7; +#endif +} + +void dspi_tx(int chipsel, u8 attrib, u16 data) +{ +	volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; + +	while ((dspi->dsr & 0x0000F000) >= 4) ; + +	dspi->dtfr = (attrib << 24) | ((1 << chipsel) << 16) | data; +} + +u16 dspi_rx(void) +{ +	volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; + +	while ((dspi->dsr & 0x000000F0) == 0) ; + +	return (dspi->drfr & 0xFFFF); +} + +#if defined(CONFIG_CMD_SPI) +void spi_init_f(void) +{ +} + +void spi_init_r(void) +{ +} + +void spi_init(void) +{ +	dspi_init(); +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, +				  unsigned int max_hz, unsigned int mode) +{ +	volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; +	struct spi_slave *slave; + +	slave = malloc(sizeof(struct spi_slave)); +	if (!slave) +		return NULL; + +	switch (cs) { +	case 0: +		gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0; +		gpio->par_dspi |= GPIO_PAR_DSPI_PCS0_PCS0; +		break; +	case 2: +		gpio->par_timer &= GPIO_PAR_TIMER_T2IN_MASK; +		gpio->par_timer |= GPIO_PAR_TIMER_T2IN_DSPIPCS2; +		break; +	} + +	slave->bus = bus; +	slave->cs = cs; + +	return slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ +	volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + +	switch (slave->cs) { +	case 0: +		gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0; +		break; +	case 2: +		gpio->par_timer &= GPIO_PAR_TIMER_T2IN_MASK; +		break; +	} + +	free(slave); +} + +int spi_claim_bus(struct spi_slave *slave) +{ +	return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, +	     void *din, unsigned long flags) +{ +	static int bWrite = 0; +	u8 *spi_rd, *spi_wr; +	int len = bitlen >> 3; + +	spi_rd = (u8 *) din; +	spi_wr = (u8 *) dout; + +	/* command handling */ +	if (((len == 4) || (len == 1) || (len == 5)) && (dout != NULL)) { +		switch (*spi_wr) { +		case 0x02:	/* Page Prog */ +			bWrite = 1; +			dspi_tx(slave->cs, 0x80, spi_wr[0]); +			dspi_rx(); +			dspi_tx(slave->cs, 0x80, spi_wr[1]); +			dspi_rx(); +			dspi_tx(slave->cs, 0x80, spi_wr[2]); +			dspi_rx(); +			dspi_tx(slave->cs, 0x80, spi_wr[3]); +			dspi_rx(); +			return 0; +		case 0x05:	/* Read Status */ +			if (len == 4) +				if ((spi_wr[1] == 0xFF) && (spi_wr[2] == 0xFF) +				    && (spi_wr[3] == 0xFF)) { +					dspi_tx(slave->cs, 0x80, *spi_wr); +					dspi_rx(); +				} +			return 0; +		case 0x06:	/* WREN */ +			dspi_tx(slave->cs, 0x00, *spi_wr); +			dspi_rx(); +			return 0; +		case 0x0B:	/* Fast read */ +			if ((len == 5) && (spi_wr[4] == 0)) { +				dspi_tx(slave->cs, 0x80, spi_wr[0]); +				dspi_rx(); +				dspi_tx(slave->cs, 0x80, spi_wr[1]); +				dspi_rx(); +				dspi_tx(slave->cs, 0x80, spi_wr[2]); +				dspi_rx(); +				dspi_tx(slave->cs, 0x80, spi_wr[3]); +				dspi_rx(); +				dspi_tx(slave->cs, 0x80, spi_wr[4]); +				dspi_rx(); +			} +			return 0; +		case 0x9F:	/* RDID */ +			dspi_tx(slave->cs, 0x80, *spi_wr); +			dspi_rx(); +			return 0; +		case 0xD8:	/* Sector erase */ +			if (len == 4) +				if ((spi_wr[2] == 0) && (spi_wr[3] == 0)) { +					dspi_tx(slave->cs, 0x80, spi_wr[0]); +					dspi_rx(); +					dspi_tx(slave->cs, 0x80, spi_wr[1]); +					dspi_rx(); +					dspi_tx(slave->cs, 0x80, spi_wr[2]); +					dspi_rx(); +					dspi_tx(slave->cs, 0x00, spi_wr[3]); +					dspi_rx(); +				} +			return 0; +		} +	} + +	if (bWrite) +		len--; + +	while (len--) { +		if (dout != NULL) { +			dspi_tx(slave->cs, 0x80, *spi_wr); +			dspi_rx(); +			spi_wr++; +		} + +		if (din != NULL) { +			dspi_tx(slave->cs, 0x80, 0); +			*spi_rd = dspi_rx(); +			spi_rd++; +		} +	} + +	if (flags == SPI_XFER_END) { +		if (bWrite) { +			dspi_tx(slave->cs, 0x00, *spi_wr); +			dspi_rx(); +			bWrite = 0; +		} else { +			dspi_tx(slave->cs, 0x00, 0); +			dspi_rx(); +		} +	} + +	return 0; +} +#endif				/* CONFIG_CMD_SPI */ + +#endif				/* CONFIG_CF_DSPI */ |