/*
 * (C) Copyright 2004, Li-Pro.Net <www.li-pro.net>
 * Stephan Linz <linz@li-pro.net>
 *
 * 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 <linux/ctype.h>

#if defined(CONFIG_NIOS_SPI)
#include <nios-io.h>
#include <spi.h>

#if !defined(CONFIG_SYS_NIOS_SPIBASE)
#error "*** CONFIG_SYS_NIOS_SPIBASE not defined ***"
#endif

#if !defined(CONFIG_SYS_NIOS_SPIBITS)
#error "*** CONFIG_SYS_NIOS_SPIBITS not defined ***"
#endif

#if (CONFIG_SYS_NIOS_SPIBITS != 8) && (CONFIG_SYS_NIOS_SPIBITS != 16)
#error "*** CONFIG_SYS_NIOS_SPIBITS should be either 8 or 16 ***"
#endif

static nios_spi_t	*spi	= (nios_spi_t *)CONFIG_SYS_NIOS_SPIBASE;

/* Warning:
 * You cannot enable DEBUG for early system initalization, i. e. when
 * this driver is used to read environment parameters like "baudrate"
 * from EEPROM which are used to initialize the serial port which is
 * needed to print the debug messages...
 */
#undef	DEBUG

#ifdef  DEBUG

#define	DPRINT(a)	printf a;
/* -----------------------------------------------
 * Helper functions to peek into tx and rx buffers
 * ----------------------------------------------- */
static const char * const hex_digit = "0123456789ABCDEF";

static char quickhex (int i)
{
	return hex_digit[i];
}

static void memdump (const void *pv, int num)
{
	int i;
	const unsigned char *pc = (const unsigned char *) pv;

	for (i = 0; i < num; i++)
		printf ("%c%c ", quickhex (pc[i] >> 4), quickhex (pc[i] & 0x0f));
	printf ("\t");
	for (i = 0; i < num; i++)
		printf ("%c", isprint (pc[i]) ? pc[i] : '.');
	printf ("\n");
}
#else   /* !DEBUG */

#define	DPRINT(a)
#define	memdump(p,n)

#endif  /* DEBUG */


struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
		unsigned int max_hz, unsigned int mode)
{
	struct spi_slave *slave;

	if (!spi_cs_is_valid(bus, cs))
		return NULL;

	slave = malloc(sizeof(struct spi_slave));
	if (!slave)
		return NULL;

	slave->bus = bus;
	slave->cs = cs;

	/* TODO: Add support for different modes and speeds */

	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)
{

}

/*
 * SPI transfer:
 *
 * See include/spi.h and http://www.altera.com/literature/ds/ds_nios_spi.pdf
 * for more informations.
 */
int spi_xfer(struct spi_slave *slave, int bitlen, const void *dout,
		void *din, unsigned long flags)
{
	const u8 *txd = dout;
	u8 *rxd = din;
	int j;

	DPRINT(("spi_xfer: slave %u:%u dout %08X din %08X bitlen %d\n",
		slave->bus, slave->cs, *(uint *)dout, *(uint *)din, bitlen));

	memdump(dout, (bitlen + 7) / 8);

	if (flags & SPI_XFER_BEGIN)
		spi_cs_activate(slave);

	if (!(flags & SPI_XFER_END) || bitlen > CONFIG_SYS_NIOS_SPIBITS) {
		/* leave chip select active */
		spi->control |= NIOS_SPI_SSO;
	}

	for (	j = 0;				/* count each byte in */
		j < ((bitlen + 7) / 8);		/* dout[] and din[] */

#if	(CONFIG_SYS_NIOS_SPIBITS == 8)
		j++) {

		while ((spi->status & NIOS_SPI_TRDY) == 0)
			;
		spi->txdata = (unsigned)(txd[j]);

		while ((spi->status & NIOS_SPI_RRDY) == 0)
			;
		rxd[j] = (unsigned char)(spi->rxdata & 0xff);

#elif	(CONFIG_SYS_NIOS_SPIBITS == 16)
		j++, j++) {

		while ((spi->status & NIOS_SPI_TRDY) == 0)
			;
		if ((j+1) < ((bitlen + 7) / 8))
			spi->txdata = (unsigned)((txd[j] << 8) | txd[j+1]);
		else
			spi->txdata = (unsigned)(txd[j] << 8);

		while ((spi->status & NIOS_SPI_RRDY) == 0)
			;
		rxd[j] = (unsigned char)((spi->rxdata >> 8) & 0xff);
		if ((j+1) < ((bitlen + 7) / 8))
			rxd[j+1] = (unsigned char)(spi->rxdata & 0xff);

#else
#error "*** unsupported value of CONFIG_SYS_NIOS_SPIBITS ***"
#endif

	}

	if (bitlen > CONFIG_SYS_NIOS_SPIBITS && (flags & SPI_XFER_END)) {
		spi->control &= ~NIOS_SPI_SSO;
	}

	if (flags & SPI_XFER_END)
		spi_cs_deactivate(slave);

	memdump(din, (bitlen + 7) / 8);

	return 0;
}

#endif /* CONFIG_NIOS_SPI */
