// SPDX-License-Identifier: GPL-2.0
/*
 * RZ/G2L Pin Function Controller
 *
 * Copyright (C) 2021-2023 Renesas Electronics Corp.
 */

#include <common.h>
#include <asm-generic/gpio.h>
#include <asm/io.h>
#include <dm/device.h>
#include <dm/device_compat.h>
#include <renesas/rzg2l-pfc.h>

static void rzg2l_gpio_set(const struct rzg2l_pfc_data *data, u32 port, u8 pin,
			   bool value)
{
	if (value)
		setbits_8(data->base + P(port), BIT(pin));
	else
		clrbits_8(data->base + P(port), BIT(pin));
}

static int rzg2l_gpio_get_value(struct udevice *dev, unsigned int offset)
{
	const struct rzg2l_pfc_data *data =
		(const struct rzg2l_pfc_data *)dev_get_driver_data(dev);
	const u32 port = RZG2L_PINMUX_TO_PORT(offset);
	const u8 pin = RZG2L_PINMUX_TO_PIN(offset);
	u16 pm_state;

	pm_state = (readw(data->base + PM(port)) >> (pin * 2)) & PM_MASK;
	switch (pm_state) {
	case PM_INPUT:
		return !!(readb(data->base + PIN(port)) & BIT(pin));
	case PM_OUTPUT:
	case PM_OUTPUT_IEN:
		return !!(readb(data->base + P(port)) & BIT(pin));
	default:	/* PM_HIGH_Z */
		return 0;
	}
}

static int rzg2l_gpio_set_value(struct udevice *dev, unsigned int offset,
				int value)
{
	const struct rzg2l_pfc_data *data =
		(const struct rzg2l_pfc_data *)dev_get_driver_data(dev);
	const u32 port = RZG2L_PINMUX_TO_PORT(offset);
	const u8 pin = RZG2L_PINMUX_TO_PIN(offset);

	rzg2l_gpio_set(data, port, pin, (bool)value);
	return 0;
}

static void rzg2l_gpio_set_direction(const struct rzg2l_pfc_data *data,
				     u32 port, u8 pin, bool output)
{
	clrsetbits_le16(data->base + PM(port), PM_MASK << (pin * 2),
			(output ? PM_OUTPUT : PM_INPUT) << (pin * 2));
}

static int rzg2l_gpio_direction_input(struct udevice *dev, unsigned int offset)
{
	const struct rzg2l_pfc_data *data =
		(const struct rzg2l_pfc_data *)dev_get_driver_data(dev);
	const u32 port = RZG2L_PINMUX_TO_PORT(offset);
	const u8 pin = RZG2L_PINMUX_TO_PIN(offset);

	rzg2l_gpio_set_direction(data, port, pin, false);
	return 0;
}

static int rzg2l_gpio_direction_output(struct udevice *dev, unsigned int offset,
				       int value)
{
	const struct rzg2l_pfc_data *data =
		(const struct rzg2l_pfc_data *)dev_get_driver_data(dev);
	const u32 port = RZG2L_PINMUX_TO_PORT(offset);
	const u8 pin = RZG2L_PINMUX_TO_PIN(offset);

	rzg2l_gpio_set(data, port, pin, (bool)value);
	rzg2l_gpio_set_direction(data, port, pin, true);
	return 0;
}

static int rzg2l_gpio_request(struct udevice *dev, unsigned int offset,
			      const char *label)
{
	const struct rzg2l_pfc_data *data =
		(const struct rzg2l_pfc_data *)dev_get_driver_data(dev);
	const u32 port = RZG2L_PINMUX_TO_PORT(offset);
	const u8 pin = RZG2L_PINMUX_TO_PIN(offset);

	if (!rzg2l_port_validate(data, port, pin)) {
		dev_err(dev, "Invalid GPIO %u:%u\n", port, pin);
		return -EINVAL;
	}

	/* Select GPIO mode in PMC Register */
	clrbits_8(data->base + PMC(port), BIT(pin));

	return 0;
}

static int rzg2l_gpio_get_function(struct udevice *dev, unsigned int offset)
{
	const struct rzg2l_pfc_data *data =
		(const struct rzg2l_pfc_data *)dev_get_driver_data(dev);
	const u32 port = RZG2L_PINMUX_TO_PORT(offset);
	const u8 pin = RZG2L_PINMUX_TO_PIN(offset);
	u16 pm_state;
	u8 pmc_state;

	if (!rzg2l_port_validate(data, port, pin)) {
		/* This offset does not correspond to a valid GPIO pin. */
		return -ENOENT;
	}

	/* Check if the pin is in GPIO or function mode. */
	pmc_state = readb(data->base + PMC(port)) & BIT(pin);
	if (pmc_state)
		return GPIOF_FUNC;

	/* Check the pin direction. */
	pm_state = (readw(data->base + PM(port)) >> (pin * 2)) & PM_MASK;
	switch (pm_state) {
	case PM_INPUT:
		return GPIOF_INPUT;
	case PM_OUTPUT:
	case PM_OUTPUT_IEN:
		return GPIOF_OUTPUT;
	default:	/* PM_HIGH_Z */
		return GPIOF_UNUSED;
	}
}

static const struct dm_gpio_ops rzg2l_gpio_ops = {
	.direction_input	= rzg2l_gpio_direction_input,
	.direction_output	= rzg2l_gpio_direction_output,
	.get_value		= rzg2l_gpio_get_value,
	.set_value		= rzg2l_gpio_set_value,
	.request		= rzg2l_gpio_request,
	.get_function		= rzg2l_gpio_get_function,
};

static int rzg2l_gpio_probe(struct udevice *dev)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct ofnode_phandle_args args;
	int ret;

	uc_priv->bank_name = "rzg2l-pfc-gpio";
	ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), "gpio-ranges",
					     NULL, 3, 0, &args);
	if (ret < 0) {
		dev_err(dev, "Failed to parse gpio-ranges: %d\n", ret);
		return -EINVAL;
	}

	uc_priv->gpio_count = args.args[2];
	return rzg2l_pfc_enable(dev);
}

U_BOOT_DRIVER(rzg2l_pfc_gpio) = {
	.name		= "rzg2l-pfc-gpio",
	.id		= UCLASS_GPIO,
	.ops		= &rzg2l_gpio_ops,
	.probe		= rzg2l_gpio_probe,
};
