/*
 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <clk.h>
#include <dm.h>
#include <errno.h>
#include <asm/gpio.h>
#include <asm/io.h>

#define GPIO_IOINTSEL	0x00	/* General IO/Interrupt Switching Register */
#define GPIO_INOUTSEL	0x04	/* General Input/Output Switching Register */
#define GPIO_OUTDT	0x08	/* General Output Register */
#define GPIO_INDT	0x0c	/* General Input Register */
#define GPIO_INTDT	0x10	/* Interrupt Display Register */
#define GPIO_INTCLR	0x14	/* Interrupt Clear Register */
#define GPIO_INTMSK	0x18	/* Interrupt Mask Register */
#define GPIO_MSKCLR	0x1c	/* Interrupt Mask Clear Register */
#define GPIO_POSNEG	0x20	/* Positive/Negative Logic Select Register */
#define GPIO_EDGLEVEL	0x24	/* Edge/level Select Register */
#define GPIO_FILONOFF	0x28	/* Chattering Prevention On/Off Register */
#define GPIO_BOTHEDGE	0x4c	/* One Edge/Both Edge Select Register */

#define RCAR_MAX_GPIO_PER_BANK		32

DECLARE_GLOBAL_DATA_PTR;

struct rcar_gpio_priv {
	void __iomem *regs;
};

static int rcar_gpio_get_value(struct udevice *dev, unsigned offset)
{
	struct rcar_gpio_priv *priv = dev_get_priv(dev);
	const u32 bit = BIT(offset);

	/*
	 * Testing on r8a7790 shows that INDT does not show correct pin state
	 * when configured as output, so use OUTDT in case of output pins.
	 */
	if (readl(priv->regs + GPIO_INOUTSEL) & bit)
		return !!(readl(priv->regs + GPIO_OUTDT) & bit);
	else
		return !!(readl(priv->regs + GPIO_INDT) & bit);
}

static int rcar_gpio_set_value(struct udevice *dev, unsigned offset,
			       int value)
{
	struct rcar_gpio_priv *priv = dev_get_priv(dev);

	if (value)
		setbits_le32(priv->regs + GPIO_OUTDT, BIT(offset));
	else
		clrbits_le32(priv->regs + GPIO_OUTDT, BIT(offset));

	return 0;
}

static void rcar_gpio_set_direction(void __iomem *regs, unsigned offset,
				    bool output)
{
	/*
	 * follow steps in the GPIO documentation for
	 * "Setting General Output Mode" and
	 * "Setting General Input Mode"
	 */

	/* Configure postive logic in POSNEG */
	clrbits_le32(regs + GPIO_POSNEG, BIT(offset));

	/* Select "General Input/Output Mode" in IOINTSEL */
	clrbits_le32(regs + GPIO_IOINTSEL, BIT(offset));

	/* Select Input Mode or Output Mode in INOUTSEL */
	if (output)
		setbits_le32(regs + GPIO_INOUTSEL, BIT(offset));
	else
		clrbits_le32(regs + GPIO_INOUTSEL, BIT(offset));
}

static int rcar_gpio_direction_input(struct udevice *dev, unsigned offset)
{
	struct rcar_gpio_priv *priv = dev_get_priv(dev);

	rcar_gpio_set_direction(priv->regs, offset, false);

	return 0;
}

static int rcar_gpio_direction_output(struct udevice *dev, unsigned offset,
				      int value)
{
	struct rcar_gpio_priv *priv = dev_get_priv(dev);

	/* write GPIO value to output before selecting output mode of pin */
	rcar_gpio_set_value(dev, offset, value);
	rcar_gpio_set_direction(priv->regs, offset, true);

	return 0;
}

static int rcar_gpio_get_function(struct udevice *dev, unsigned offset)
{
	struct rcar_gpio_priv *priv = dev_get_priv(dev);

	if (readl(priv->regs + GPIO_INOUTSEL) & BIT(offset))
		return GPIOF_OUTPUT;
	else
		return GPIOF_INPUT;
}

static const struct dm_gpio_ops rcar_gpio_ops = {
	.direction_input	= rcar_gpio_direction_input,
	.direction_output	= rcar_gpio_direction_output,
	.get_value		= rcar_gpio_get_value,
	.set_value		= rcar_gpio_set_value,
	.get_function		= rcar_gpio_get_function,
};

static int rcar_gpio_probe(struct udevice *dev)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct rcar_gpio_priv *priv = dev_get_priv(dev);
	struct fdtdec_phandle_args args;
	struct clk clk;
	int node = dev_of_offset(dev);
	int ret;

	priv->regs = (void __iomem *)devfdt_get_addr(dev);
	uc_priv->bank_name = dev->name;

	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, node, "gpio-ranges",
					     NULL, 3, 0, &args);
	uc_priv->gpio_count = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK;

	ret = clk_get_by_index(dev, 0, &clk);
	if (ret < 0) {
		dev_err(dev, "Failed to get GPIO bank clock\n");
		return ret;
	}

	ret = clk_enable(&clk);
	clk_free(&clk);
	if (ret) {
		dev_err(dev, "Failed to enable GPIO bank clock\n");
		return ret;
	}

	return 0;
}

static const struct udevice_id rcar_gpio_ids[] = {
	{ .compatible = "renesas,gpio-r8a7795" },
	{ .compatible = "renesas,gpio-r8a7796" },
	{ /* sentinel */ }
};

U_BOOT_DRIVER(rcar_gpio) = {
	.name	= "rcar-gpio",
	.id	= UCLASS_GPIO,
	.of_match = rcar_gpio_ids,
	.ops	= &rcar_gpio_ops,
	.priv_auto_alloc_size = sizeof(struct rcar_gpio_priv),
	.probe	= rcar_gpio_probe,
};
