// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com>
 */

#include <asm/gpio.h>
#include <common.h>
#include <dm.h>
#include <dm/pinctrl.h>
#include <linux/io.h>
#include "pinctrl-meson-gx.h"

static void meson_gx_pinmux_disable_other_groups(struct meson_pinctrl *priv,
						 unsigned int pin,
						 int sel_group)
{
	struct meson_pmx_group *group;
	struct meson_gx_pmx_data *pmx_data;
	void __iomem *addr;
	int i, j;

	for (i = 0; i < priv->data->num_groups; i++) {
		group = &priv->data->groups[i];
		pmx_data = (struct meson_gx_pmx_data *)group->data;
		if (pmx_data->is_gpio || i == sel_group)
			continue;

		for (j = 0; j < group->num_pins; j++) {
			if (group->pins[j] == pin) {
				/* We have found a group using the pin */
				debug("pinmux: disabling %s\n", group->name);
				addr = priv->reg_mux + pmx_data->reg * 4;
				writel(readl(addr) & ~BIT(pmx_data->bit), addr);
			}
		}
	}
}

static int meson_gx_pinmux_group_set(struct udevice *dev,
				     unsigned int group_selector,
				     unsigned int func_selector)
{
	struct meson_pinctrl *priv = dev_get_priv(dev);
	const struct meson_pmx_group *group;
	const struct meson_pmx_func *func;
	struct meson_gx_pmx_data *pmx_data;
	void __iomem *addr;
	int i;

	group = &priv->data->groups[group_selector];
	pmx_data = (struct meson_gx_pmx_data *)group->data;
	func = &priv->data->funcs[func_selector];

	debug("pinmux: set group %s func %s\n", group->name, func->name);

	/*
	 * Disable groups using the same pins.
	 * The selected group is not disabled to avoid glitches.
	 */
	for (i = 0; i < group->num_pins; i++) {
		meson_gx_pinmux_disable_other_groups(priv,
						     group->pins[i],
						     group_selector);
	}

	/* Function 0 (GPIO) doesn't need any additional setting */
	if (func_selector) {
		addr = priv->reg_mux + pmx_data->reg * 4;
		writel(readl(addr) | BIT(pmx_data->bit), addr);
	}

	return 0;
}

static int meson_gx_pinmux_get(struct udevice *dev,
				      unsigned int selector,
				      char *buf, int size)
{
	struct meson_pinctrl *priv = dev_get_priv(dev);
	struct meson_pmx_group *group;
	struct meson_gx_pmx_data *pmx_data;
	void __iomem *addr;
	int i, j, pos = 0;
	unsigned int pin;
	u32 reg;

	pin = selector + priv->data->pin_base;

	for (i = 0; i < priv->data->num_groups; i++) {
		group = &priv->data->groups[i];
		pmx_data = (struct meson_gx_pmx_data *)group->data;
		if (pmx_data->is_gpio)
			continue;

		for (j = 0; j < group->num_pins; j++) {
			if (group->pins[j] == pin) {
				/* We have found a group using the pin */
				addr = priv->reg_mux + pmx_data->reg * 4;
				reg = readl(addr) & BIT(pmx_data->bit);
				if (reg) {
					pos += snprintf(buf + pos, size - pos,
							"%s ", group->name) - 1;
					return 0;
				}
			}
		}
	}

	/* Fallback, must be used as GPIO */
	snprintf(buf, size, "%s or Unknown",
		 priv->data->groups[selector].name);

	return 0;
}

const struct pinconf_param meson_gx_pinconf_params[] = {
	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
};

const struct pinctrl_ops meson_gx_pinctrl_ops = {
	.get_groups_count = meson_pinctrl_get_groups_count,
	.get_group_name = meson_pinctrl_get_group_name,
	.get_functions_count = meson_pinmux_get_functions_count,
	.get_function_name = meson_pinmux_get_function_name,
	.pinmux_group_set = meson_gx_pinmux_group_set,
	.set_state = pinctrl_generic_set_state,
	.pinconf_params = meson_gx_pinconf_params,
	.pinconf_num_params = ARRAY_SIZE(meson_gx_pinconf_params),
	.pinconf_set = meson_pinconf_set,
	.pinconf_group_set = meson_pinconf_group_set,
	.get_pin_name = meson_pinctrl_get_pin_name,
	.get_pins_count = meson_pinctrl_get_pins_count,
	.get_pin_muxing	= meson_gx_pinmux_get,
};

static const struct dm_gpio_ops meson_gx_gpio_ops = {
	.set_value = meson_gpio_set,
	.get_value = meson_gpio_get,
	.get_function = meson_gpio_get_direction,
	.direction_input = meson_gpio_direction_input,
	.direction_output = meson_gpio_direction_output,
};

const struct driver meson_gx_gpio_driver = {
	.name	= "meson-gx-gpio",
	.id	= UCLASS_GPIO,
	.probe	= meson_gpio_probe,
	.ops	= &meson_gx_gpio_ops,
};
