// 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;
}

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,
};

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,
};
