// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2016 Freescale Semiconductor, Inc.
 *
 * RGPIO2P driver for the Freescale i.MX7ULP.
 */

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

enum imx_rgpio2p_direction {
	IMX_RGPIO2P_DIRECTION_IN,
	IMX_RGPIO2P_DIRECTION_OUT,
};

#define GPIO_PER_BANK			32

struct imx_rgpio2p_data {
	struct gpio_regs *regs;
};

struct imx_rgpio2p_plat {
	int bank_index;
	struct gpio_regs *regs;
};

static int imx_rgpio2p_is_output(struct gpio_regs *regs, int offset)
{
	u32 val;

	val = readl(&regs->gpio_pddr);

	return val & (1 << offset) ? 1 : 0;
}

static void imx_rgpio2p_bank_direction(struct gpio_regs *regs, int offset,
				    enum imx_rgpio2p_direction direction)
{
	u32 l;

	l = readl(&regs->gpio_pddr);

	switch (direction) {
	case IMX_RGPIO2P_DIRECTION_OUT:
		l |= 1 << offset;
		break;
	case IMX_RGPIO2P_DIRECTION_IN:
		l &= ~(1 << offset);
	}
	writel(l, &regs->gpio_pddr);
}

static void imx_rgpio2p_bank_set_value(struct gpio_regs *regs, int offset,
				    int value)
{
	if (value)
		writel((1 << offset), &regs->gpio_psor);
	else
		writel((1 << offset), &regs->gpio_pcor);
}

static int imx_rgpio2p_bank_get_value(struct gpio_regs *regs, int offset)
{
	return (readl(&regs->gpio_pdir) >> offset) & 0x01;
}

static int  imx_rgpio2p_direction_input(struct udevice *dev, unsigned offset)
{
	struct imx_rgpio2p_data *bank = dev_get_priv(dev);

	/* Configure GPIO direction as input. */
	imx_rgpio2p_bank_direction(bank->regs, offset, IMX_RGPIO2P_DIRECTION_IN);

	return 0;
}

static int imx_rgpio2p_direction_output(struct udevice *dev, unsigned offset,
				       int value)
{
	struct imx_rgpio2p_data *bank = dev_get_priv(dev);

	/* Configure GPIO output value. */
	imx_rgpio2p_bank_set_value(bank->regs, offset, value);

	/* Configure GPIO direction as output. */
	imx_rgpio2p_bank_direction(bank->regs, offset, IMX_RGPIO2P_DIRECTION_OUT);

	return 0;
}

static int imx_rgpio2p_get_value(struct udevice *dev, unsigned offset)
{
	struct imx_rgpio2p_data *bank = dev_get_priv(dev);

	return imx_rgpio2p_bank_get_value(bank->regs, offset);
}

static int imx_rgpio2p_set_value(struct udevice *dev, unsigned offset,
				 int value)
{
	struct imx_rgpio2p_data *bank = dev_get_priv(dev);

	imx_rgpio2p_bank_set_value(bank->regs, offset, value);

	return 0;
}

static int imx_rgpio2p_get_function(struct udevice *dev, unsigned offset)
{
	struct imx_rgpio2p_data *bank = dev_get_priv(dev);

	/* GPIOF_FUNC is not implemented yet */
	if (imx_rgpio2p_is_output(bank->regs, offset))
		return GPIOF_OUTPUT;
	else
		return GPIOF_INPUT;
}

static const struct dm_gpio_ops imx_rgpio2p_ops = {
	.direction_input	= imx_rgpio2p_direction_input,
	.direction_output	= imx_rgpio2p_direction_output,
	.get_value		= imx_rgpio2p_get_value,
	.set_value		= imx_rgpio2p_set_value,
	.get_function		= imx_rgpio2p_get_function,
};

static int imx_rgpio2p_probe(struct udevice *dev)
{
	struct imx_rgpio2p_data *bank = dev_get_priv(dev);
	struct imx_rgpio2p_plat *plat = dev_get_platdata(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	int banknum;
	char name[18], *str;

	banknum = plat->bank_index;
	sprintf(name, "GPIO%d_", banknum + 1);
	str = strdup(name);
	if (!str)
		return -ENOMEM;
	uc_priv->bank_name = str;
	uc_priv->gpio_count = GPIO_PER_BANK;
	bank->regs = plat->regs;

	return 0;
}

static int imx_rgpio2p_bind(struct udevice *dev)
{
	struct imx_rgpio2p_plat *plat = dev->platdata;
	fdt_addr_t addr;

	/*
	 * If platdata already exsits, directly return.
	 * Actually only when DT is not supported, platdata
	 * is statically initialized in U_BOOT_DEVICES.Here
	 * will return.
	 */
	if (plat)
		return 0;

	addr = devfdt_get_addr_index(dev, 1);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	/*
	 * TODO:
	 * When every board is converted to driver model and DT is supported,
	 * this can be done by auto-alloc feature, but not using calloc
	 * to alloc memory for platdata.
	 *
	 * For example imx_rgpio2p_plat uses platform data rather than device
	 * tree.
	 *
	 * NOTE: DO NOT COPY this code if you are using device tree.
	 */
	plat = calloc(1, sizeof(*plat));
	if (!plat)
		return -ENOMEM;

	plat->regs = (struct gpio_regs *)addr;
	plat->bank_index = dev->req_seq;
	dev->platdata = plat;

	return 0;
}


static const struct udevice_id imx_rgpio2p_ids[] = {
	{ .compatible = "fsl,imx7ulp-gpio" },
	{ }
};

U_BOOT_DRIVER(imx_rgpio2p) = {
	.name	= "imx_rgpio2p",
	.id	= UCLASS_GPIO,
	.ops	= &imx_rgpio2p_ops,
	.probe	= imx_rgpio2p_probe,
	.priv_auto_alloc_size = sizeof(struct imx_rgpio2p_plat),
	.of_match = imx_rgpio2p_ids,
	.bind	= imx_rgpio2p_bind,
};

#if !CONFIG_IS_ENABLED(OF_CONTROL)
static const struct imx_rgpio2p_plat imx_plat[] = {
	{ 0, (struct gpio_regs *)RGPIO2P_GPIO1_BASE_ADDR },
	{ 1, (struct gpio_regs *)RGPIO2P_GPIO2_BASE_ADDR },
	{ 2, (struct gpio_regs *)RGPIO2P_GPIO3_BASE_ADDR },
	{ 3, (struct gpio_regs *)RGPIO2P_GPIO4_BASE_ADDR },
	{ 4, (struct gpio_regs *)RGPIO2P_GPIO5_BASE_ADDR },
	{ 5, (struct gpio_regs *)RGPIO2P_GPIO6_BASE_ADDR },
};

U_BOOT_DEVICES(imx_rgpio2ps) = {
	{ "imx_rgpio2p", &imx_plat[0] },
	{ "imx_rgpio2p", &imx_plat[1] },
	{ "imx_rgpio2p", &imx_plat[2] },
	{ "imx_rgpio2p", &imx_plat[3] },
	{ "imx_rgpio2p", &imx_plat[4] },
	{ "imx_rgpio2p", &imx_plat[5] },
};
#endif
