/*
 *
 * (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_PCS5_PCS5 | GPIO_PAR_DSPI_PCS2_PCS2 |
	    GPIO_PAR_DSPI_PCS1_PCS1 | GPIO_PAR_DSPI_PCS0_PCS0 |
	    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 CFG_DSPI_DCTAR0
	dspi->dctar0 = CFG_DSPI_DCTAR0;
#endif
#ifdef CFG_DSPI_DCTAR1
	dspi->dctar1 = CFG_DSPI_DCTAR1;
#endif
#ifdef CFG_DSPI_DCTAR2
	dspi->dctar2 = CFG_DSPI_DCTAR2;
#endif
#ifdef CFG_DSPI_DCTAR3
	dspi->dctar3 = CFG_DSPI_DCTAR3;
#endif
#ifdef CFG_DSPI_DCTAR4
	dspi->dctar4 = CFG_DSPI_DCTAR4;
#endif
#ifdef CFG_DSPI_DCTAR5
	dspi->dctar5 = CFG_DSPI_DCTAR5;
#endif
#ifdef CFG_DSPI_DCTAR6
	dspi->dctar6 = CFG_DSPI_DCTAR6;
#endif
#ifdef CFG_DSPI_DCTAR7
	dspi->dctar7 = CFG_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)
{
	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)
{
}

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 */
