/*
 * Copyright (c) 2014 Google, Inc
 *
 * (C) Copyright 2002
 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
 *
 * Influenced by code from:
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
#include <spi.h>
#include <asm/gpio.h>

DECLARE_GLOBAL_DATA_PTR;

struct soft_spi_platdata {
	struct gpio_desc cs;
	struct gpio_desc sclk;
	struct gpio_desc mosi;
	struct gpio_desc miso;
	int spi_delay_us;
	int flags;
};

#define SPI_MASTER_NO_RX        BIT(0)
#define SPI_MASTER_NO_TX        BIT(1)

struct soft_spi_priv {
	unsigned int mode;
};

static int soft_spi_scl(struct udevice *dev, int bit)
{
	struct udevice *bus = dev_get_parent(dev);
	struct soft_spi_platdata *plat = dev_get_platdata(bus);

	dm_gpio_set_value(&plat->sclk, bit);

	return 0;
}

static int soft_spi_sda(struct udevice *dev, int bit)
{
	struct udevice *bus = dev_get_parent(dev);
	struct soft_spi_platdata *plat = dev_get_platdata(bus);

	dm_gpio_set_value(&plat->mosi, bit);

	return 0;
}

static int soft_spi_cs_activate(struct udevice *dev)
{
	struct udevice *bus = dev_get_parent(dev);
	struct soft_spi_platdata *plat = dev_get_platdata(bus);

	dm_gpio_set_value(&plat->cs, 0);
	dm_gpio_set_value(&plat->sclk, 0);
	dm_gpio_set_value(&plat->cs, 1);

	return 0;
}

static int soft_spi_cs_deactivate(struct udevice *dev)
{
	struct udevice *bus = dev_get_parent(dev);
	struct soft_spi_platdata *plat = dev_get_platdata(bus);

	dm_gpio_set_value(&plat->cs, 0);

	return 0;
}

static int soft_spi_claim_bus(struct udevice *dev)
{
	/*
	 * Make sure the SPI clock is in idle state as defined for
	 * this slave.
	 */
	return soft_spi_scl(dev, 0);
}

static int soft_spi_release_bus(struct udevice *dev)
{
	/* Nothing to do */
	return 0;
}

/*-----------------------------------------------------------------------
 * SPI transfer
 *
 * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
 * "bitlen" bits in the SPI MISO port.  That's just the way SPI works.
 *
 * The source of the outgoing bits is the "dout" parameter and the
 * destination of the input bits is the "din" parameter.  Note that "dout"
 * and "din" can point to the same memory location, in which case the
 * input data overwrites the output data (since both are buffered by
 * temporary variables, this is OK).
 */
static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
			 const void *dout, void *din, unsigned long flags)
{
	struct udevice *bus = dev_get_parent(dev);
	struct soft_spi_priv *priv = dev_get_priv(bus);
	struct soft_spi_platdata *plat = dev_get_platdata(bus);
	uchar		tmpdin  = 0;
	uchar		tmpdout = 0;
	const u8	*txd = dout;
	u8		*rxd = din;
	int		cpha = priv->mode & SPI_CPHA;
	unsigned int	j;

	debug("spi_xfer: slave %s:%s dout %08X din %08X bitlen %u\n",
	      dev->parent->name, dev->name, *(uint *)txd, *(uint *)rxd,
	      bitlen);

	if (flags & SPI_XFER_BEGIN)
		soft_spi_cs_activate(dev);

	for (j = 0; j < bitlen; j++) {
		/*
		 * Check if it is time to work on a new byte.
		 */
		if ((j % 8) == 0) {
			if (txd)
				tmpdout = *txd++;
			else
				tmpdout = 0;
			if (j != 0) {
				if (rxd)
					*rxd++ = tmpdin;
			}
			tmpdin  = 0;
		}

		if (!cpha)
			soft_spi_scl(dev, 0);
		if ((plat->flags & SPI_MASTER_NO_TX) == 0)
			soft_spi_sda(dev, !!(tmpdout & 0x80));
		udelay(plat->spi_delay_us);
		if (cpha)
			soft_spi_scl(dev, 0);
		else
			soft_spi_scl(dev, 1);
		tmpdin	<<= 1;
		if ((plat->flags & SPI_MASTER_NO_RX) == 0)
			tmpdin	|= dm_gpio_get_value(&plat->miso);
		tmpdout	<<= 1;
		udelay(plat->spi_delay_us);
		if (cpha)
			soft_spi_scl(dev, 1);
	}
	/*
	 * If the number of bits isn't a multiple of 8, shift the last
	 * bits over to left-justify them.  Then store the last byte
	 * read in.
	 */
	if (rxd) {
		if ((bitlen % 8) != 0)
			tmpdin <<= 8 - (bitlen % 8);
		*rxd++ = tmpdin;
	}

	if (flags & SPI_XFER_END)
		soft_spi_cs_deactivate(dev);

	return 0;
}

static int soft_spi_set_speed(struct udevice *dev, unsigned int speed)
{
	/* Accept any speed */
	return 0;
}

static int soft_spi_set_mode(struct udevice *dev, unsigned int mode)
{
	struct soft_spi_priv *priv = dev_get_priv(dev);

	priv->mode = mode;

	return 0;
}

static const struct dm_spi_ops soft_spi_ops = {
	.claim_bus	= soft_spi_claim_bus,
	.release_bus	= soft_spi_release_bus,
	.xfer		= soft_spi_xfer,
	.set_speed	= soft_spi_set_speed,
	.set_mode	= soft_spi_set_mode,
};

static int soft_spi_ofdata_to_platdata(struct udevice *dev)
{
	struct soft_spi_platdata *plat = dev->platdata;
	const void *blob = gd->fdt_blob;
	int node = dev->of_offset;

	plat->spi_delay_us = fdtdec_get_int(blob, node, "spi-delay-us", 0);

	return 0;
}

static int soft_spi_probe(struct udevice *dev)
{
	struct spi_slave *slave = dev_get_parent_priv(dev);
	struct soft_spi_platdata *plat = dev->platdata;
	int cs_flags, clk_flags;
	int ret;

	cs_flags = (slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW;
	clk_flags = (slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0;

	if (gpio_request_by_name(dev, "cs-gpios", 0, &plat->cs,
				 GPIOD_IS_OUT | cs_flags) ||
	    gpio_request_by_name(dev, "gpio-sck", 0, &plat->sclk,
				 GPIOD_IS_OUT | clk_flags))
		return -EINVAL;

	ret = gpio_request_by_name(dev, "gpio-mosi", 0, &plat->mosi,
				   GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
	if (ret)
		plat->flags |= SPI_MASTER_NO_TX;

	ret = gpio_request_by_name(dev, "gpio-miso", 0, &plat->miso,
				   GPIOD_IS_IN);
	if (ret)
		plat->flags |= SPI_MASTER_NO_RX;

	if ((plat->flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX)) ==
	    (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX))
		return -EINVAL;

	return 0;
}

static const struct udevice_id soft_spi_ids[] = {
	{ .compatible = "spi-gpio" },
	{ }
};

U_BOOT_DRIVER(soft_spi) = {
	.name	= "soft_spi",
	.id	= UCLASS_SPI,
	.of_match = soft_spi_ids,
	.ops	= &soft_spi_ops,
	.ofdata_to_platdata = soft_spi_ofdata_to_platdata,
	.platdata_auto_alloc_size = sizeof(struct soft_spi_platdata),
	.priv_auto_alloc_size = sizeof(struct soft_spi_priv),
	.probe	= soft_spi_probe,
};
