// SPDX-License-Identifier: GPL-2.0+
/*
 * Take drivers/gpio/gpio-74x164.c as reference.
 *
 * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver
 *
 * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
 *
 */

#include <errno.h>
#include <dm.h>
#include <fdtdec.h>
#include <malloc.h>
#include <asm/global_data.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <dt-bindings/gpio/gpio.h>
#include <spi.h>

DECLARE_GLOBAL_DATA_PTR;

/*
 * struct gen_74x164_chip - Data for 74Hx164
 *
 * @oe: OE pin
 * @nregs: number of registers
 * @buffer: buffer for chained chips
 */
#define GEN_74X164_NUMBER_GPIOS 8

struct gen_74x164_priv {
	struct gpio_desc oe;
	u32 nregs;
	/*
	 * Since the nregs are chained, every byte sent will make
	 * the previous byte shift to the next register in the
	 * chain. Thus, the first byte sent will end up in the last
	 * register at the end of the transfer. So, to have a logical
	 * numbering, store the bytes in reverse order.
	 */
	u8 *buffer;
};

static int gen_74x164_write_conf(struct udevice *dev)
{
	struct gen_74x164_priv *priv = dev_get_priv(dev);
	int ret;

	ret = dm_spi_claim_bus(dev);
	if (ret)
		return ret;

	ret = dm_spi_xfer(dev, priv->nregs * 8, priv->buffer, NULL,
			  SPI_XFER_BEGIN | SPI_XFER_END);

	dm_spi_release_bus(dev);

	return ret;
}

static int gen_74x164_get_value(struct udevice *dev, unsigned offset)
{
	struct gen_74x164_priv *priv = dev_get_priv(dev);
	uint bank = priv->nregs - 1 - offset / 8;
	uint pin = offset % 8;

	return (priv->buffer[bank] >> pin) & 0x1;
}

static int gen_74x164_set_value(struct udevice *dev, unsigned offset,
				int value)
{
	struct gen_74x164_priv *priv = dev_get_priv(dev);
	uint bank = priv->nregs - 1 - offset / 8;
	uint pin = offset % 8;
	int ret;

	if (value)
		priv->buffer[bank] |= 1 << pin;
	else
		priv->buffer[bank] &= ~(1 << pin);

	ret = gen_74x164_write_conf(dev);
	if (ret)
		return ret;

	return 0;
}

static int gen_74x164_direction_input(struct udevice *dev, unsigned offset)
{
	return -ENOSYS;
}

static int gen_74x164_direction_output(struct udevice *dev, unsigned offset,
				      int value)
{
	return gen_74x164_set_value(dev, offset, value);
}

static int gen_74x164_get_function(struct udevice *dev, unsigned offset)
{
	return GPIOF_OUTPUT;
}

static int gen_74x164_xlate(struct udevice *dev, struct gpio_desc *desc,
			    struct ofnode_phandle_args *args)
{
	desc->offset = args->args[0];
	desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;

	return 0;
}

static const struct dm_gpio_ops gen_74x164_ops = {
	.direction_input	= gen_74x164_direction_input,
	.direction_output	= gen_74x164_direction_output,
	.get_value		= gen_74x164_get_value,
	.set_value		= gen_74x164_set_value,
	.get_function		= gen_74x164_get_function,
	.xlate			= gen_74x164_xlate,
};

static int gen_74x164_probe(struct udevice *dev)
{
	struct gen_74x164_priv *priv = dev_get_priv(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	char *str, name[32];
	int ret;
	const void *fdt = gd->fdt_blob;
	int node = dev_of_offset(dev);

	snprintf(name, sizeof(name), "%s_", dev->name);
	str = strdup(name);
	if (!str)
		return -ENOMEM;

	/*
	 * See Linux kernel:
	 * Documentation/devicetree/bindings/gpio/gpio-74x164.txt
	 */
	priv->nregs = fdtdec_get_int(fdt, node, "registers-number", 1);
	priv->buffer = calloc(priv->nregs, sizeof(u8));
	if (!priv->buffer) {
		ret = -ENOMEM;
		goto free_str;
	}

	ret = fdtdec_get_byte_array(fdt, node, "registers-default",
				    priv->buffer, priv->nregs);
	if (ret)
		dev_dbg(dev, "No registers-default property\n");

	ret = gpio_request_by_name(dev, "oe-gpios", 0, &priv->oe,
				   GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
	if (ret) {
		dev_dbg(dev, "No oe-pins property\n");
	}

	uc_priv->bank_name = str;
	uc_priv->gpio_count = priv->nregs * 8;

	ret = gen_74x164_write_conf(dev);
	if (ret)
		goto free_buf;

	dev_dbg(dev, "%s is ready\n", dev->name);

	return 0;

free_buf:
	free(priv->buffer);
free_str:
	free(str);
	return ret;
}

static const struct udevice_id gen_74x164_ids[] = {
	{ .compatible = "fairchild,74hc595" },
	{ }
};

U_BOOT_DRIVER(74x164) = {
	.name		= "74x164",
	.id		= UCLASS_GPIO,
	.ops		= &gen_74x164_ops,
	.probe		= gen_74x164_probe,
	.priv_auto	= sizeof(struct gen_74x164_priv),
	.of_match	= gen_74x164_ids,
};
