// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2013 - 2018 Xilinx, Michal Simek
 */

#include <common.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <linux/list.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <dm.h>
#include <dt-bindings/gpio/gpio.h>

#define XILINX_GPIO_MAX_BANK	2

/* Gpio simple map */
struct gpio_regs {
	u32 gpiodata;
	u32 gpiodir;
};

struct xilinx_gpio_platdata {
	struct gpio_regs *regs;
	int bank_max[XILINX_GPIO_MAX_BANK];
	int bank_input[XILINX_GPIO_MAX_BANK];
	int bank_output[XILINX_GPIO_MAX_BANK];
	u32 dout_default[XILINX_GPIO_MAX_BANK];
};

struct xilinx_gpio_privdata {
	u32 output_val[XILINX_GPIO_MAX_BANK];
};

static int xilinx_gpio_get_bank_pin(unsigned offset, u32 *bank_num,
				    u32 *bank_pin_num, struct udevice *dev)
{
	struct xilinx_gpio_platdata *plat = dev_get_platdata(dev);
	u32 bank, max_pins;
	/* the first gpio is 0 not 1 */
	u32 pin_num = offset;

	for (bank = 0; bank < XILINX_GPIO_MAX_BANK; bank++) {
		max_pins = plat->bank_max[bank];
		if (pin_num < max_pins) {
			debug("%s: found at bank 0x%x pin 0x%x\n", __func__,
			      bank, pin_num);
			*bank_num = bank;
			*bank_pin_num = pin_num;
			return 0;
		}
		pin_num -= max_pins;
	}

	return -EINVAL;
}

static int xilinx_gpio_set_value(struct udevice *dev, unsigned offset,
				 int value)
{
	struct xilinx_gpio_platdata *plat = dev_get_platdata(dev);
	struct xilinx_gpio_privdata *priv = dev_get_priv(dev);
	int val, ret;
	u32 bank, pin;

	ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev);
	if (ret)
		return ret;

	val = priv->output_val[bank];

	debug("%s: regs: %lx, value: %x, gpio: %x, bank %x, pin %x, out %x\n",
	      __func__, (ulong)plat->regs, value, offset, bank, pin, val);

	if (value)
		val = val | (1 << pin);
	else
		val = val & ~(1 << pin);

	writel(val, &plat->regs->gpiodata + bank * 2);

	priv->output_val[bank] = val;

	return 0;
};

static int xilinx_gpio_get_value(struct udevice *dev, unsigned offset)
{
	struct xilinx_gpio_platdata *plat = dev_get_platdata(dev);
	struct xilinx_gpio_privdata *priv = dev_get_priv(dev);
	int val, ret;
	u32 bank, pin;

	ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev);
	if (ret)
		return ret;

	debug("%s: regs: %lx, gpio: %x, bank %x, pin %x\n", __func__,
	      (ulong)plat->regs, offset, bank, pin);

	if (plat->bank_output[bank]) {
		debug("%s: Read saved output value\n", __func__);
		val = priv->output_val[bank];
	} else {
		debug("%s: Read input value from reg\n", __func__);
		val = readl(&plat->regs->gpiodata + bank * 2);
	}

	val = !!(val & (1 << pin));

	return val;
};

static int xilinx_gpio_get_function(struct udevice *dev, unsigned offset)
{
	struct xilinx_gpio_platdata *plat = dev_get_platdata(dev);
	int val, ret;
	u32 bank, pin;

	ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev);
	if (ret)
		return ret;

	/* Check if all pins are inputs */
	if (plat->bank_input[bank])
		return GPIOF_INPUT;

	/* Check if all pins are outputs */
	if (plat->bank_output[bank])
		return GPIOF_OUTPUT;

	/* FIXME test on dual */
	val = readl(&plat->regs->gpiodir + bank * 2);
	val = !(val & (1 << pin));

	/* input is 1 in reg but GPIOF_INPUT is 0 */
	/* output is 0 in reg but GPIOF_OUTPUT is 1 */

	return val;
}

static int xilinx_gpio_direction_output(struct udevice *dev, unsigned offset,
					int value)
{
	struct xilinx_gpio_platdata *plat = dev_get_platdata(dev);
	int val, ret;
	u32 bank, pin;

	ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev);
	if (ret)
		return ret;

	/* can't change it if all is input by default */
	if (plat->bank_input[bank])
		return -EINVAL;

	xilinx_gpio_set_value(dev, offset, value);

	if (!plat->bank_output[bank]) {
		val = readl(&plat->regs->gpiodir + bank * 2);
		val = val & ~(1 << pin);
		writel(val, &plat->regs->gpiodir + bank * 2);
	}

	return 0;
}

static int xilinx_gpio_direction_input(struct udevice *dev, unsigned offset)
{
	struct xilinx_gpio_platdata *plat = dev_get_platdata(dev);
	int val, ret;
	u32 bank, pin;

	ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev);
	if (ret)
		return ret;

	/* Already input */
	if (plat->bank_input[bank])
		return 0;

	/* can't change it if all is output by default */
	if (plat->bank_output[bank])
		return -EINVAL;

	val = readl(&plat->regs->gpiodir + bank * 2);
	val = val | (1 << pin);
	writel(val, &plat->regs->gpiodir + bank * 2);

	return 0;
}

static int xilinx_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
			     struct ofnode_phandle_args *args)
{
	struct xilinx_gpio_platdata *plat = dev_get_platdata(dev);

	desc->offset = args->args[0];

	debug("%s: argc: %x, [0]: %x, [1]: %x, [2]: %x\n", __func__,
	      args->args_count, args->args[0], args->args[1], args->args[2]);

	/*
	 * The second cell is channel offset:
	 *  0 is first channel, 8 is second channel
	 *
	 * U-Boot driver just combine channels together that's why simply
	 * add amount of pins in second channel if present.
	 */
	if (args->args[1]) {
		if (!plat->bank_max[1]) {
			printf("%s: %s has no second channel\n",
			       __func__, dev->name);
			return -EINVAL;
		}

		desc->offset += plat->bank_max[0];
	}

	/* The third cell is optional */
	if (args->args_count > 2)
		desc->flags = (args->args[2] &
			       GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0);

	debug("%s: offset %x, flags %lx\n",
	      __func__, desc->offset, desc->flags);
	return 0;
}

static const struct dm_gpio_ops xilinx_gpio_ops = {
	.direction_input = xilinx_gpio_direction_input,
	.direction_output = xilinx_gpio_direction_output,
	.get_value = xilinx_gpio_get_value,
	.set_value = xilinx_gpio_set_value,
	.get_function = xilinx_gpio_get_function,
	.xlate = xilinx_gpio_xlate,
};

static int xilinx_gpio_probe(struct udevice *dev)
{
	struct xilinx_gpio_platdata *plat = dev_get_platdata(dev);
	struct xilinx_gpio_privdata *priv = dev_get_priv(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	const void *label_ptr;

	label_ptr = dev_read_prop(dev, "label", NULL);
	if (label_ptr) {
		uc_priv->bank_name = strdup(label_ptr);
		if (!uc_priv->bank_name)
			return -ENOMEM;
	} else {
		uc_priv->bank_name = dev->name;
	}

	uc_priv->gpio_count = plat->bank_max[0] + plat->bank_max[1];

	priv->output_val[0] = plat->dout_default[0];

	if (plat->bank_max[1])
		priv->output_val[1] = plat->dout_default[1];

	return 0;
}

static int xilinx_gpio_ofdata_to_platdata(struct udevice *dev)
{
	struct xilinx_gpio_platdata *plat = dev_get_platdata(dev);
	int is_dual;

	plat->regs = (struct gpio_regs *)dev_read_addr(dev);

	plat->bank_max[0] = dev_read_u32_default(dev, "xlnx,gpio-width", 0);
	plat->bank_input[0] = dev_read_u32_default(dev, "xlnx,all-inputs", 0);
	plat->bank_output[0] = dev_read_u32_default(dev, "xlnx,all-outputs", 0);
	plat->dout_default[0] = dev_read_u32_default(dev, "xlnx,dout-default",
						     0);

	is_dual = dev_read_u32_default(dev, "xlnx,is-dual", 0);
	if (is_dual) {
		plat->bank_max[1] = dev_read_u32_default(dev,
							 "xlnx,gpio2-width", 0);
		plat->bank_input[1] = dev_read_u32_default(dev,
						"xlnx,all-inputs-2", 0);
		plat->bank_output[1] = dev_read_u32_default(dev,
						"xlnx,all-outputs-2", 0);
		plat->dout_default[1] = dev_read_u32_default(dev,
						"xlnx,dout-default-2", 0);
	}

	return 0;
}

static const struct udevice_id xilinx_gpio_ids[] = {
	{ .compatible = "xlnx,xps-gpio-1.00.a",},
	{ }
};

U_BOOT_DRIVER(xilinx_gpio) = {
	.name = "xlnx_gpio",
	.id = UCLASS_GPIO,
	.ops = &xilinx_gpio_ops,
	.of_match = xilinx_gpio_ids,
	.ofdata_to_platdata = xilinx_gpio_ofdata_to_platdata,
	.probe = xilinx_gpio_probe,
	.plat_auto	= sizeof(struct xilinx_gpio_platdata),
	.priv_auto	= sizeof(struct xilinx_gpio_privdata),
};
