// SPDX-License-Identifier: GPL-2.0+
/*
 * SiFive GPIO driver
 *
 * Copyright (C) 2019 SiFive, Inc.
 */

#include <common.h>
#include <dm.h>
#include <asm/arch/gpio.h>
#include <asm/io.h>
#include <errno.h>
#include <asm/gpio.h>
#include <linux/bitops.h>

static int sifive_gpio_probe(struct udevice *dev)
{
	struct sifive_gpio_plat *plat = dev_get_plat(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	char name[18], *str;

	sprintf(name, "gpio@%4lx_", (uintptr_t)plat->base);
	str = strdup(name);
	if (!str)
		return -ENOMEM;
	uc_priv->bank_name = str;

	/*
	 * Use the gpio count mentioned in device tree,
	 * if not specified in dt, set NR_GPIOS as default
	 */
	uc_priv->gpio_count = dev_read_u32_default(dev, "ngpios", NR_GPIOS);

	return 0;
}

static void sifive_update_gpio_reg(void *bptr, u32 offset, bool value)
{
	void __iomem *ptr = (void __iomem *)bptr;

	u32 bit = BIT(offset);
	u32 old = readl(ptr);

	if (value)
		writel(old | bit, ptr);
	else
		writel(old & ~bit, ptr);
}

static int sifive_gpio_direction_input(struct udevice *dev, u32 offset)
{
	struct sifive_gpio_plat *plat = dev_get_plat(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);

	if (offset > uc_priv->gpio_count)
		return -EINVAL;

	/* Configure gpio direction as input */
	sifive_update_gpio_reg(plat->base + GPIO_INPUT_EN,  offset, true);
	sifive_update_gpio_reg(plat->base + GPIO_OUTPUT_EN, offset, false);

	return 0;
}

static int sifive_gpio_direction_output(struct udevice *dev, u32 offset,
					int value)
{
	struct sifive_gpio_plat *plat = dev_get_plat(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);

	if (offset > uc_priv->gpio_count)
		return -EINVAL;

	/* Configure gpio direction as output */
	sifive_update_gpio_reg(plat->base + GPIO_OUTPUT_EN, offset, true);
	sifive_update_gpio_reg(plat->base + GPIO_INPUT_EN,  offset, false);

	/* Set the output state of the pin */
	sifive_update_gpio_reg(plat->base + GPIO_OUTPUT_VAL, offset, value);

	return 0;
}

static int sifive_gpio_get_value(struct udevice *dev, u32 offset)
{
	struct sifive_gpio_plat *plat = dev_get_plat(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	int val;
	int dir;

	if (offset > uc_priv->gpio_count)
		return -EINVAL;

	/* Get direction of the pin */
	dir = !(readl(plat->base + GPIO_OUTPUT_EN) & BIT(offset));

	if (dir)
		val = readl(plat->base + GPIO_INPUT_VAL) & BIT(offset);
	else
		val = readl(plat->base + GPIO_OUTPUT_VAL) & BIT(offset);

	return val ? HIGH : LOW;
}

static int sifive_gpio_set_value(struct udevice *dev, u32 offset, int value)
{
	struct sifive_gpio_plat *plat = dev_get_plat(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);

	if (offset > uc_priv->gpio_count)
		return -EINVAL;

	sifive_update_gpio_reg(plat->base + GPIO_OUTPUT_VAL, offset, value);

	return 0;
}

static int sifive_gpio_get_function(struct udevice *dev, unsigned int offset)
{
	struct sifive_gpio_plat *plat = dev_get_plat(dev);
	u32	outdir, indir, val;
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);

	if (offset > uc_priv->gpio_count)
		return -1;

	/* Get direction of the pin */
	outdir = readl(plat->base + GPIO_OUTPUT_EN) & BIT(offset);
	indir  = readl(plat->base + GPIO_INPUT_EN) & BIT(offset);

	if (outdir)
		/* Pin at specified offset is configured as output */
		val = GPIOF_OUTPUT;
	else if (indir)
		/* Pin at specified offset is configured as input */
		val = GPIOF_INPUT;
	else
		/*The requested GPIO is not set as input or output */
		val = GPIOF_UNUSED;

	return val;
}

static const struct udevice_id sifive_gpio_match[] = {
	{ .compatible = "sifive,gpio0" },
	{ }
};

static const struct dm_gpio_ops sifive_gpio_ops = {
	.direction_input        = sifive_gpio_direction_input,
	.direction_output       = sifive_gpio_direction_output,
	.get_value              = sifive_gpio_get_value,
	.set_value              = sifive_gpio_set_value,
	.get_function		= sifive_gpio_get_function,
};

static int sifive_gpio_of_to_plat(struct udevice *dev)
{
	struct sifive_gpio_plat *plat = dev_get_plat(dev);
	fdt_addr_t addr;

	addr = dev_read_addr(dev);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	plat->base = (void *)addr;
	return 0;
}

U_BOOT_DRIVER(gpio_sifive) = {
	.name	= "gpio_sifive",
	.id	= UCLASS_GPIO,
	.of_match = sifive_gpio_match,
	.of_to_plat = of_match_ptr(sifive_gpio_of_to_plat),
	.plat_auto	= sizeof(struct sifive_gpio_plat),
	.ops	= &sifive_gpio_ops,
	.probe	= sifive_gpio_probe,
};
