/*
 * 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>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 *
 */

#include <common.h>
#include <errno.h>
#include <dm.h>
#include <fdtdec.h>
#include <malloc.h>
#include <asm/gpio.h>
#include <asm/io.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 fdtdec_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;

	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_err(dev, "No oe-pins property\n");
		goto free_buf;
	}

	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_alloc_size = sizeof(struct gen_74x164_priv),
	.of_match	= gen_74x164_ids,
};
