/*
 * Copyright (C) 2016 Socionext Inc.
 *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

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

#define UNIPHIER_GPIO_PORTS_PER_BANK	8

#define UNIPHIER_GPIO_REG_DATA		0	/* data */
#define UNIPHIER_GPIO_REG_DIR		4	/* direction (1:in, 0:out) */

struct uniphier_gpio_priv {
	void __iomem *base;
	char bank_name[16];
};

static void uniphier_gpio_offset_write(struct udevice *dev, unsigned offset,
				       unsigned reg, int value)
{
	struct uniphier_gpio_priv *priv = dev_get_priv(dev);
	u32 tmp;

	tmp = readl(priv->base + reg);
	if (value)
		tmp |= BIT(offset);
	else
		tmp &= ~BIT(offset);
	writel(tmp, priv->base + reg);
}

static int uniphier_gpio_offset_read(struct udevice *dev, unsigned offset,
				     unsigned reg)
{
	struct uniphier_gpio_priv *priv = dev_get_priv(dev);

	return !!(readl(priv->base + reg) & BIT(offset));
}

static int uniphier_gpio_direction_input(struct udevice *dev, unsigned offset)
{
	uniphier_gpio_offset_write(dev, offset, UNIPHIER_GPIO_REG_DIR, 1);

	return 0;
}

static int uniphier_gpio_direction_output(struct udevice *dev, unsigned offset,
					  int value)
{
	uniphier_gpio_offset_write(dev, offset, UNIPHIER_GPIO_REG_DATA, value);
	uniphier_gpio_offset_write(dev, offset, UNIPHIER_GPIO_REG_DIR, 0);

	return 0;
}

static int uniphier_gpio_get_value(struct udevice *dev, unsigned offset)
{
	return uniphier_gpio_offset_read(dev, offset, UNIPHIER_GPIO_REG_DATA);
}

static int uniphier_gpio_set_value(struct udevice *dev, unsigned offset,
				   int value)
{
	uniphier_gpio_offset_write(dev, offset, UNIPHIER_GPIO_REG_DATA, value);

	return 0;
}

static int uniphier_gpio_get_function(struct udevice *dev, unsigned offset)
{
	return uniphier_gpio_offset_read(dev, offset, UNIPHIER_GPIO_REG_DIR) ?
						GPIOF_INPUT : GPIOF_OUTPUT;
}

static const struct dm_gpio_ops uniphier_gpio_ops = {
	.direction_input	= uniphier_gpio_direction_input,
	.direction_output	= uniphier_gpio_direction_output,
	.get_value		= uniphier_gpio_get_value,
	.set_value		= uniphier_gpio_set_value,
	.get_function		= uniphier_gpio_get_function,
};

static int uniphier_gpio_probe(struct udevice *dev)
{
	struct uniphier_gpio_priv *priv = dev_get_priv(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	fdt_addr_t addr;
	unsigned int tmp;

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

	priv->base = devm_ioremap(dev, addr, SZ_8);
	if (!priv->base)
		return -ENOMEM;

	uc_priv->gpio_count = UNIPHIER_GPIO_PORTS_PER_BANK;

	tmp = (addr & 0xfff);

	/* Unfortunately, there is a register hole at offset 0x90-0x9f. */
	if (tmp > 0x90)
		tmp -= 0x10;

	snprintf(priv->bank_name, sizeof(priv->bank_name) - 1,
		 "port%d-", (tmp - 8) / 8);

	uc_priv->bank_name = priv->bank_name;

	return 0;
}

/* .data = the number of GPIO banks */
static const struct udevice_id uniphier_gpio_match[] = {
	{ .compatible = "socionext,uniphier-gpio" },
	{ /* sentinel */ }
};

U_BOOT_DRIVER(uniphier_gpio) = {
	.name	= "uniphier_gpio",
	.id	= UCLASS_GPIO,
	.of_match = uniphier_gpio_match,
	.probe	= uniphier_gpio_probe,
	.priv_auto_alloc_size = sizeof(struct uniphier_gpio_priv),
	.ops	= &uniphier_gpio_ops,
};
