/*
 * Analog Devices SPI3 controller driver
 *
 * Copyright (c) 2011 Analog Devices Inc.
 *
 * 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.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <common.h>
#include <malloc.h>
#include <spi.h>

#include <asm/blackfin.h>
#include <asm/gpio.h>
#include <asm/portmux.h>
#include <asm/mach-common/bits/spi6xx.h>

struct bfin_spi_slave {
	struct spi_slave slave;
	u32 control, clock;
	struct bfin_spi_regs *regs;
	int cs_pol;
};

#define to_bfin_spi_slave(s) container_of(s, struct bfin_spi_slave, slave)

#define gpio_cs(cs) ((cs) - MAX_CTRL_CS)
#ifdef CONFIG_BFIN_SPI_GPIO_CS
# define is_gpio_cs(cs) ((cs) > MAX_CTRL_CS)
#else
# define is_gpio_cs(cs) 0
#endif

int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
	if (is_gpio_cs(cs))
		return gpio_is_valid(gpio_cs(cs));
	else
		return (cs >= 1 && cs <= MAX_CTRL_CS);
}

void spi_cs_activate(struct spi_slave *slave)
{
	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);

	if (is_gpio_cs(slave->cs)) {
		unsigned int cs = gpio_cs(slave->cs);
		gpio_set_value(cs, bss->cs_pol);
	} else {
		u32 ssel;
		ssel = bfin_read32(&bss->regs->ssel);
		ssel |= 1 << slave->cs;
		if (bss->cs_pol)
			ssel |= (1 << 8) << slave->cs;
		else
			ssel &= ~((1 << 8) << slave->cs);
		bfin_write32(&bss->regs->ssel, ssel);
	}

	SSYNC();
}

void spi_cs_deactivate(struct spi_slave *slave)
{
	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);

	if (is_gpio_cs(slave->cs)) {
		unsigned int cs = gpio_cs(slave->cs);
		gpio_set_value(cs, !bss->cs_pol);
	} else {
		u32 ssel;
		ssel = bfin_read32(&bss->regs->ssel);
		if (bss->cs_pol)
			ssel &= ~((1 << 8) << slave->cs);
		else
			ssel |= (1 << 8) << slave->cs;
		/* deassert cs */
		bfin_write32(&bss->regs->ssel, ssel);
		SSYNC();
		/* disable cs */
		ssel &= ~(1 << slave->cs);
		bfin_write32(&bss->regs->ssel, ssel);
	}

	SSYNC();
}

void spi_init()
{
}

#define SPI_PINS(n) \
	{ 0, P_SPI##n##_SCK, P_SPI##n##_MISO, P_SPI##n##_MOSI, 0 }
static unsigned short pins[][5] = {
#ifdef SPI0_REGBASE
	[0] = SPI_PINS(0),
#endif
#ifdef SPI1_REGBASE
	[1] = SPI_PINS(1),
#endif
#ifdef SPI2_REGBASE
	[2] = SPI_PINS(2),
#endif
};

#define SPI_CS_PINS(n) \
	{ \
		P_SPI##n##_SSEL1, P_SPI##n##_SSEL2, P_SPI##n##_SSEL3, \
		P_SPI##n##_SSEL4, P_SPI##n##_SSEL5, P_SPI##n##_SSEL6, \
		P_SPI##n##_SSEL7, \
	}
static const unsigned short cs_pins[][7] = {
#ifdef SPI0_REGBASE
	[0] = SPI_CS_PINS(0),
#endif
#ifdef SPI1_REGBASE
	[1] = SPI_CS_PINS(1),
#endif
#ifdef SPI2_REGBASE
	[2] = SPI_CS_PINS(2),
#endif
};

void spi_set_speed(struct spi_slave *slave, uint hz)
{
	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
	ulong sclk;
	u32 clock;

	sclk = get_sclk1();
	clock = sclk / hz;
	if (clock)
		clock--;
	bss->clock = clock;
}

struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
		unsigned int max_hz, unsigned int mode)
{
	struct bfin_spi_slave *bss;
	u32 reg_base;

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

	if (bus >= ARRAY_SIZE(pins) || pins[bus] == NULL) {
		debug("%s: invalid bus %u\n", __func__, bus);
		return NULL;
	}
	switch (bus) {
#ifdef SPI0_REGBASE
	case 0:
		reg_base = SPI0_REGBASE;
		break;
#endif
#ifdef SPI1_REGBASE
	case 1:
		reg_base = SPI1_REGBASE;
		break;
#endif
#ifdef SPI2_REGBASE
	case 2:
		reg_base = SPI2_REGBASE;
		break;
#endif
	default:
		return NULL;
	}

	bss = malloc(sizeof(*bss));
	if (!bss)
		return NULL;

	bss->slave.bus = bus;
	bss->slave.cs = cs;
	bss->regs = (struct bfin_spi_regs *)reg_base;
	bss->control = SPI_CTL_EN | SPI_CTL_MSTR;
	if (mode & SPI_CPHA)
		bss->control |= SPI_CTL_CPHA;
	if (mode & SPI_CPOL)
		bss->control |= SPI_CTL_CPOL;
	if (mode & SPI_LSB_FIRST)
		bss->control |= SPI_CTL_LSBF;
	bss->control &= ~SPI_CTL_ASSEL;
	bss->cs_pol = mode & SPI_CS_HIGH ? 1 : 0;
	spi_set_speed(&bss->slave, max_hz);

	return &bss->slave;
}

void spi_free_slave(struct spi_slave *slave)
{
	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
	free(bss);
}

int spi_claim_bus(struct spi_slave *slave)
{
	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);

	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);

	if (is_gpio_cs(slave->cs)) {
		unsigned int cs = gpio_cs(slave->cs);
		gpio_request(cs, "bfin-spi");
		gpio_direction_output(cs, !bss->cs_pol);
		pins[slave->bus][0] = P_DONTCARE;
	} else
		pins[slave->bus][0] = cs_pins[slave->bus][slave->cs - 1];
	peripheral_request_list(pins[slave->bus], "bfin-spi");

	bfin_write32(&bss->regs->control, bss->control);
	bfin_write32(&bss->regs->clock, bss->clock);
	bfin_write32(&bss->regs->delay, 0x0);
	bfin_write32(&bss->regs->rx_control, SPI_RXCTL_REN);
	bfin_write32(&bss->regs->tx_control, SPI_TXCTL_TEN | SPI_TXCTL_TTI);
	SSYNC();

	return 0;
}

void spi_release_bus(struct spi_slave *slave)
{
	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);

	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);

	peripheral_free_list(pins[slave->bus]);
	if (is_gpio_cs(slave->cs))
		gpio_free(gpio_cs(slave->cs));

	bfin_write32(&bss->regs->rx_control, 0x0);
	bfin_write32(&bss->regs->tx_control, 0x0);
	bfin_write32(&bss->regs->control, 0x0);
	SSYNC();
}

#ifndef CONFIG_BFIN_SPI_IDLE_VAL
# define CONFIG_BFIN_SPI_IDLE_VAL 0xff
#endif

static int spi_pio_xfer(struct bfin_spi_slave *bss, const u8 *tx, u8 *rx,
			uint bytes)
{
	/* discard invalid rx data and empty rfifo */
	while (!(bfin_read32(&bss->regs->status) & SPI_STAT_RFE))
		bfin_read32(&bss->regs->rfifo);

	while (bytes--) {
		u8 value = (tx ? *tx++ : CONFIG_BFIN_SPI_IDLE_VAL);
		debug("%s: tx:%x ", __func__, value);
		bfin_write32(&bss->regs->tfifo, value);
		SSYNC();
		while (bfin_read32(&bss->regs->status) & SPI_STAT_RFE)
			if (ctrlc())
				return -1;
		value = bfin_read32(&bss->regs->rfifo);
		if (rx)
			*rx++ = value;
		debug("rx:%x\n", value);
	}

	return 0;
}

int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
		void *din, unsigned long flags)
{
	struct bfin_spi_slave *bss = to_bfin_spi_slave(slave);
	const u8 *tx = dout;
	u8 *rx = din;
	uint bytes = bitlen / 8;
	int ret = 0;

	debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
		slave->bus, slave->cs, bitlen, bytes, flags);

	if (bitlen == 0)
		goto done;

	/* we can only do 8 bit transfers */
	if (bitlen % 8) {
		flags |= SPI_XFER_END;
		goto done;
	}

	if (flags & SPI_XFER_BEGIN)
		spi_cs_activate(slave);

	ret = spi_pio_xfer(bss, tx, rx, bytes);

 done:
	if (flags & SPI_XFER_END)
		spi_cs_deactivate(slave);

	return ret;
}
