// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2014 Google, Inc
 */

#define LOG_CATEGORY UCLASS_SPI

#include <dm.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <spi.h>
#include <spi-mem.h>
#include <dm/device_compat.h>
#include <asm/global_data.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#include <dm/lists.h>
#include <dm/util.h>

DECLARE_GLOBAL_DATA_PTR;

#define SPI_DEFAULT_SPEED_HZ 100000

static int spi_set_speed_mode(struct udevice *bus, int speed, int mode)
{
	struct dm_spi_ops *ops;
	int ret;

	ops = spi_get_ops(bus);
	if (ops->set_speed)
		ret = ops->set_speed(bus, speed);
	else
		ret = -EINVAL;
	if (ret) {
		dev_err(bus, "Cannot set speed (err=%d)\n", ret);
		return ret;
	}

	if (ops->set_mode)
		ret = ops->set_mode(bus, mode);
	else
		ret = -EINVAL;
	if (ret) {
		dev_err(bus, "Cannot set mode (err=%d)\n", ret);
		return ret;
	}

	return 0;
}

int dm_spi_claim_bus(struct udevice *dev)
{
	struct udevice *bus = dev->parent;
	struct dm_spi_ops *ops = spi_get_ops(bus);
	struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
	struct spi_slave *slave = dev_get_parent_priv(dev);
	uint speed, mode;

	speed = slave->max_hz;
	mode = slave->mode;

	if (spi->max_hz) {
		if (speed)
			speed = min(speed, spi->max_hz);
		else
			speed = spi->max_hz;
	}
	if (!speed)
		speed = SPI_DEFAULT_SPEED_HZ;

	if (speed != spi->speed || mode != spi->mode) {
		int ret = spi_set_speed_mode(bus, speed, slave->mode);

		if (ret)
			return log_ret(ret);

		spi->speed = speed;
		spi->mode = mode;
	}

	return log_ret(ops->claim_bus ? ops->claim_bus(dev) : 0);
}

void dm_spi_release_bus(struct udevice *dev)
{
	struct udevice *bus = dev->parent;
	struct dm_spi_ops *ops = spi_get_ops(bus);

	if (ops->release_bus)
		ops->release_bus(dev);
}

int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
		const void *dout, void *din, unsigned long flags)
{
	struct udevice *bus = dev->parent;
	struct dm_spi_ops *ops = spi_get_ops(bus);

	if (bus->uclass->uc_drv->id != UCLASS_SPI)
		return -EOPNOTSUPP;
	if (!ops->xfer)
		return -ENOSYS;

	return ops->xfer(dev, bitlen, dout, din, flags);
}

int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep,
		    uint *offsetp)
{
	struct udevice *bus = dev->parent;
	struct dm_spi_ops *ops = spi_get_ops(bus);

	if (bus->uclass->uc_drv->id != UCLASS_SPI)
		return -EOPNOTSUPP;
	if (!ops->get_mmap)
		return -ENOSYS;

	return ops->get_mmap(dev, map_basep, map_sizep, offsetp);
}

int spi_claim_bus(struct spi_slave *slave)
{
	return log_ret(dm_spi_claim_bus(slave->dev));
}

void spi_release_bus(struct spi_slave *slave)
{
	dm_spi_release_bus(slave->dev);
}

int spi_set_speed(struct spi_slave *slave, uint hz)
{
	struct dm_spi_ops *ops;
	int ret;

	ops = spi_get_ops(slave->dev->parent);
	if (ops->set_speed)
		ret = ops->set_speed(slave->dev->parent, hz);
	else
		ret = -EINVAL;
	if (ret)
		dev_err(slave->dev, "Cannot set speed (err=%d)\n", ret);
	return ret;
}

int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
	     const void *dout, void *din, unsigned long flags)
{
	return dm_spi_xfer(slave->dev, bitlen, dout, din, flags);
}

int spi_write_then_read(struct spi_slave *slave, const u8 *opcode,
			size_t n_opcode, const u8 *txbuf, u8 *rxbuf,
			size_t n_buf)
{
	unsigned long flags = SPI_XFER_BEGIN;
	int ret;

	if (n_buf == 0)
		flags |= SPI_XFER_END;

	ret = spi_xfer(slave, n_opcode * 8, opcode, NULL, flags);
	if (ret) {
		dev_dbg(slave->dev,
			"spi: failed to send command (%zu bytes): %d\n",
			n_opcode, ret);
	} else if (n_buf != 0) {
		ret = spi_xfer(slave, n_buf * 8, txbuf, rxbuf, SPI_XFER_END);
		if (ret)
			dev_dbg(slave->dev,
				"spi: failed to transfer %zu bytes of data: %d\n",
				n_buf, ret);
	}

	return ret;
}

#if CONFIG_IS_ENABLED(OF_REAL)
static int spi_child_post_bind(struct udevice *dev)
{
	struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);

	if (!dev_has_ofnode(dev))
		return 0;

	return spi_slave_of_to_plat(dev, plat);
}
#endif

static int spi_post_probe(struct udevice *bus)
{
	if (CONFIG_IS_ENABLED(OF_REAL)) {
		struct dm_spi_bus *spi = dev_get_uclass_priv(bus);

		spi->max_hz = dev_read_u32_default(bus, "spi-max-frequency", 0);
	}

	return 0;
}

static int spi_child_pre_probe(struct udevice *dev)
{
	struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);
	struct spi_slave *slave = dev_get_parent_priv(dev);

	/*
	 * This is needed because we pass struct spi_slave around the place
	 * instead slave->dev (a struct udevice). So we have to have some
	 * way to access the slave udevice given struct spi_slave. Once we
	 * change the SPI API to use udevice instead of spi_slave, we can
	 * drop this.
	 */
	slave->dev = dev;

	slave->max_hz = plat->max_hz;
	slave->mode = plat->mode;
	slave->wordlen = SPI_DEFAULT_WORDLEN;

	return 0;
}

int spi_chip_select(struct udevice *dev)
{
	struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);

	return plat ? plat->cs[0] : -ENOENT;
}

int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp)
{
	struct dm_spi_ops *ops;
	struct spi_cs_info info;
	struct udevice *dev;
	int ret;

	/*
	 * Ask the driver. For the moment we don't have CS info.
	 * When we do we could provide the driver with a helper function
	 * to figure out what chip selects are valid, or just handle the
	 * request.
	 */
	ops = spi_get_ops(bus);
	if (ops->cs_info) {
		ret = ops->cs_info(bus, cs, &info);
	} else {
		/*
		 * We could assume there is at least one valid chip select.
		 * The driver didn't care enough to tell us.
		 */
		ret = 0;
	}

	if (ret) {
		dev_err(bus, "Invalid cs %d (err=%d)\n", cs, ret);
		return ret;
	}

	for (device_find_first_child(bus, &dev); dev;
	     device_find_next_child(&dev)) {
		struct dm_spi_slave_plat *plat;

		plat = dev_get_parent_plat(dev);
		dev_dbg(bus, "%s: plat=%p, cs=%d\n", __func__, plat, plat->cs[0]);
		if (plat->cs[0] == cs) {
			*devp = dev;
			return 0;
		}
	}

	return -ENODEV;
}

int spi_cs_is_valid(unsigned int busnum, unsigned int cs)
{
	struct spi_cs_info info;
	struct udevice *bus;
	int ret;

	ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, &bus);
	if (ret) {
		log_debug("%s: No bus %d\n", __func__, busnum);
		return ret;
	}

	return spi_cs_info(bus, cs, &info);
}

int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info)
{
	struct spi_cs_info local_info;
	int ret;

	if (!info)
		info = &local_info;

	/* If there is a device attached, return it */
	info->dev = NULL;
	ret = spi_find_chip_select(bus, cs, &info->dev);
	return ret == -ENODEV ? 0 : ret;
}

int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,
			struct udevice **devp)
{
	struct udevice *bus, *dev;
	int ret;

	ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, &bus);
	if (ret) {
		log_debug("%s: No bus %d\n", __func__, busnum);
		return ret;
	}
	ret = spi_find_chip_select(bus, cs, &dev);
	if (ret) {
		dev_dbg(bus, "%s: No cs %d\n", __func__, cs);
		return ret;
	}
	*busp = bus;
	*devp = dev;

	return ret;
}

int spi_get_bus_and_cs(int busnum, int cs, struct udevice **busp,
		       struct spi_slave **devp)
{
	struct udevice *bus, *dev;
	struct dm_spi_bus *bus_data;
	struct spi_slave *slave;
	int ret;

#if CONFIG_IS_ENABLED(OF_PLATDATA)
	ret = uclass_first_device_err(UCLASS_SPI, &bus);
#else
	ret = uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus);
#endif
	if (ret) {
		log_err("Invalid bus %d (err=%d)\n", busnum, ret);
		return ret;
	}
	ret = spi_find_chip_select(bus, cs, &dev);
	if (ret) {
		dev_err(bus, "Invalid chip select %d:%d (err=%d)\n", busnum, cs, ret);
		return ret;
	}

	if (!device_active(dev)) {
		struct spi_slave *slave;

		ret = device_probe(dev);
		if (ret)
			goto err;
		slave = dev_get_parent_priv(dev);
		slave->dev = dev;
	}

	slave = dev_get_parent_priv(dev);
	bus_data = dev_get_uclass_priv(bus);

	/*
	 * In case the operation speed is not yet established by
	 * dm_spi_claim_bus() ensure the bus is configured properly.
	 */
	if (!bus_data->speed) {
		ret = spi_claim_bus(slave);
		if (ret)
			goto err;
	}
	*busp = bus;
	*devp = slave;

	return 0;

err:
	log_debug("%s: Error path, device '%s'\n", __func__, dev->name);

	return ret;
}

int _spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
			const char *drv_name, const char *dev_name,
			struct udevice **busp, struct spi_slave **devp)
{
	struct udevice *bus, *dev;
	struct dm_spi_slave_plat *plat;
	struct dm_spi_bus *bus_data;
	struct spi_slave *slave;
	bool created = false;
	int ret;

#if CONFIG_IS_ENABLED(OF_PLATDATA)
	ret = uclass_first_device_err(UCLASS_SPI, &bus);
#else
	ret = uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus);
#endif
	if (ret) {
		log_err("Invalid bus %d (err=%d)\n", busnum, ret);
		return ret;
	}
	ret = spi_find_chip_select(bus, cs, &dev);

	/*
	 * If there is no such device, create one automatically. This means
	 * that we don't need a device tree node or platform data for the
	 * SPI flash chip - we will bind to the correct driver.
	 */
	if (ret == -ENODEV && drv_name) {
		dev_dbg(bus, "%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n",
			__func__, dev_name, busnum, cs, drv_name);
		ret = device_bind_driver(bus, drv_name, dev_name, &dev);
		if (ret) {
			dev_dbg(bus, "%s: Unable to bind driver (ret=%d)\n",
				__func__, ret);
			return ret;
		}
		plat = dev_get_parent_plat(dev);
		plat->cs[0] = cs;
		if (speed) {
			plat->max_hz = speed;
		} else {
			dev_warn(bus,
				 "Warning: SPI speed fallback to %u kHz\n",
				 SPI_DEFAULT_SPEED_HZ / 1000);
			plat->max_hz = SPI_DEFAULT_SPEED_HZ;
		}
		plat->mode = mode;
		created = true;
	} else if (ret) {
		dev_err(bus, "Invalid chip select %d:%d (err=%d)\n", busnum, cs, ret);
		return ret;
	} else if (dev) {
		plat = dev_get_parent_plat(dev);
	}

	if (!device_active(dev)) {
		struct spi_slave *slave;

		ret = device_probe(dev);
		if (ret)
			goto err;
		slave = dev_get_parent_priv(dev);
		slave->dev = dev;
	}

	slave = dev_get_parent_priv(dev);
	bus_data = dev_get_uclass_priv(bus);

#if CONFIG_IS_ENABLED(SPI_ADVANCE)
	if ((dev_read_bool(dev, "parallel-memories")) && !slave->multi_cs_cap) {
		dev_err(dev, "controller doesn't support multi CS\n");
		return -EINVAL;
	}
#endif
	/*
	 * In case the operation speed is not yet established by
	 * dm_spi_claim_bus() ensure the bus is configured properly.
	 */
	if (!bus_data->speed) {
		ret = spi_claim_bus(slave);
		if (ret)
			goto err;
	}

	/* In case bus frequency or mode changed, update it. */
	if ((speed && bus_data->speed && bus_data->speed != speed) ||
	    (plat && plat->mode != mode)) {
		ret = spi_set_speed_mode(bus, speed, mode);
		if (ret)
			goto err_speed_mode;
	}

	*busp = bus;
	*devp = slave;
	log_debug("%s: bus=%p, slave=%p\n", __func__, bus, *devp);

	return 0;

err_speed_mode:
	spi_release_bus(slave);
err:
	log_debug("%s: Error path, created=%d, device '%s'\n", __func__,
		  created, dev->name);
	if (created) {
		device_remove(dev, DM_REMOVE_NORMAL);
		device_unbind(dev);
	}

	return ret;
}

/* Compatibility function - to be removed */
struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
				  unsigned int speed, unsigned int mode)
{
	struct spi_slave *slave;
	struct udevice *dev;
	int ret;

	ret = _spi_get_bus_and_cs(busnum, cs, speed, mode, NULL, 0, &dev,
				  &slave);
	if (ret)
		return NULL;

	return slave;
}

void spi_free_slave(struct spi_slave *slave)
{
	device_remove(slave->dev, DM_REMOVE_NORMAL);
}

int spi_slave_of_to_plat(struct udevice *dev, struct dm_spi_slave_plat *plat)
{
	int mode = 0;
	int value;

#if CONFIG_IS_ENABLED(SPI_ADVANCE)
	int ret;

	ret = dev_read_u32_array(dev, "reg", plat->cs, SPI_CS_CNT_MAX);

	if (ret == -EOVERFLOW || ret == -FDT_ERR_BADLAYOUT) {
		dev_read_u32(dev, "reg", &plat->cs[0]);
	} else {
		dev_err(dev, "has no valid 'reg' property (%d)\n", ret);
		return ret;
	}
#else
	plat->cs[0] = dev_read_u32_default(dev, "reg", -1);
#endif

	plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency",
					    SPI_DEFAULT_SPEED_HZ);
	if (dev_read_bool(dev, "spi-cpol"))
		mode |= SPI_CPOL;
	if (dev_read_bool(dev, "spi-cpha"))
		mode |= SPI_CPHA;
	if (dev_read_bool(dev, "spi-cs-high"))
		mode |= SPI_CS_HIGH;
	if (dev_read_bool(dev, "spi-3wire"))
		mode |= SPI_3WIRE;
	if (dev_read_bool(dev, "spi-half-duplex"))
		mode |= SPI_PREAMBLE;

	/* Device DUAL/QUAD mode */
	value = dev_read_u32_default(dev, "spi-tx-bus-width", 1);
	switch (value) {
	case 1:
		break;
	case 2:
		mode |= SPI_TX_DUAL;
		break;
	case 4:
		mode |= SPI_TX_QUAD;
		break;
	case 8:
		mode |= SPI_TX_OCTAL;
		break;
	default:
		warn_non_xpl("spi-tx-bus-width %d not supported\n", value);
		break;
	}

	value = dev_read_u32_default(dev, "spi-rx-bus-width", 1);
	switch (value) {
	case 1:
		break;
	case 2:
		mode |= SPI_RX_DUAL;
		break;
	case 4:
		mode |= SPI_RX_QUAD;
		break;
	case 8:
		mode |= SPI_RX_OCTAL;
		break;
	default:
		warn_non_xpl("spi-rx-bus-width %d not supported\n", value);
		break;
	}

	plat->mode = mode;

	return 0;
}

UCLASS_DRIVER(spi) = {
	.id		= UCLASS_SPI,
	.name		= "spi",
	.flags		= DM_UC_FLAG_SEQ_ALIAS,
#if CONFIG_IS_ENABLED(OF_REAL)
	.post_bind	= dm_scan_fdt_dev,
#endif
	.post_probe	= spi_post_probe,
	.child_pre_probe = spi_child_pre_probe,
	.per_device_auto	= sizeof(struct dm_spi_bus),
	.per_child_auto	= sizeof(struct spi_slave),
	.per_child_plat_auto	= sizeof(struct dm_spi_slave_plat),
#if CONFIG_IS_ENABLED(OF_REAL)
	.child_post_bind = spi_child_post_bind,
#endif
};

UCLASS_DRIVER(spi_generic) = {
	.id		= UCLASS_SPI_GENERIC,
	.name		= "spi_generic",
};

U_BOOT_DRIVER(spi_generic_drv) = {
	.name		= "spi_generic_drv",
	.id		= UCLASS_SPI_GENERIC,
};
