// SPDX-License-Identifier: GPL-2.0
/*
 *  Copyright (C) 2013 John Crispin <blogic@openwrt.org>
 */

#include <linux/module.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/machine.h>

#include <asm/mach-ralink/ralink_regs.h>
#include <asm/mach-ralink/pinmux.h>
#include <asm/mach-ralink/mt7620.h>

#include "core.h"
#include "pinctrl-utils.h"

#define SYSC_REG_GPIO_MODE	0x60
#define SYSC_REG_GPIO_MODE2	0x64

struct rt2880_priv {
	struct device *dev;

	struct pinctrl_pin_desc *pads;
	struct pinctrl_desc *desc;

	struct rt2880_pmx_func **func;
	int func_count;

	struct rt2880_pmx_group *groups;
	const char **group_names;
	int group_count;

	u8 *gpio;
	int max_pins;
};

static int rt2880_get_group_count(struct pinctrl_dev *pctrldev)
{
	struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);

	return p->group_count;
}

static const char *rt2880_get_group_name(struct pinctrl_dev *pctrldev,
					 unsigned int group)
{
	struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);

	return (group >= p->group_count) ? NULL : p->group_names[group];
}

static int rt2880_get_group_pins(struct pinctrl_dev *pctrldev,
				 unsigned int group,
				 const unsigned int **pins,
				 unsigned int *num_pins)
{
	struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);

	if (group >= p->group_count)
		return -EINVAL;

	*pins = p->groups[group].func[0].pins;
	*num_pins = p->groups[group].func[0].pin_count;

	return 0;
}

static int rt2880_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrldev,
					 struct device_node *np_config,
					 struct pinctrl_map **map,
					 unsigned int *num_maps)
{
	struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
	struct property *prop;
	const char *function_name, *group_name;
	int ret;
	int ngroups = 0;
	unsigned int reserved_maps = 0;

	for_each_node_with_property(np_config, "group")
		ngroups++;

	*map = NULL;
	ret = pinctrl_utils_reserve_map(pctrldev, map, &reserved_maps,
					num_maps, ngroups);
	if (ret) {
		dev_err(p->dev, "can't reserve map: %d\n", ret);
		return ret;
	}

	of_property_for_each_string(np_config, "group", prop, group_name) {
		ret = pinctrl_utils_add_map_mux(pctrldev, map, &reserved_maps,
						num_maps, group_name,
						function_name);
		if (ret) {
			dev_err(p->dev, "can't add map: %d\n", ret);
			return ret;
		}
	}

	return 0;
}

static const struct pinctrl_ops rt2880_pctrl_ops = {
	.get_groups_count	= rt2880_get_group_count,
	.get_group_name		= rt2880_get_group_name,
	.get_group_pins		= rt2880_get_group_pins,
	.dt_node_to_map		= rt2880_pinctrl_dt_node_to_map,
	.dt_free_map		= pinctrl_utils_free_map,
};

static int rt2880_pmx_func_count(struct pinctrl_dev *pctrldev)
{
	struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);

	return p->func_count;
}

static const char *rt2880_pmx_func_name(struct pinctrl_dev *pctrldev,
					unsigned int func)
{
	struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);

	return p->func[func]->name;
}

static int rt2880_pmx_group_get_groups(struct pinctrl_dev *pctrldev,
				       unsigned int func,
				       const char * const **groups,
				       unsigned int * const num_groups)
{
	struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);

	if (p->func[func]->group_count == 1)
		*groups = &p->group_names[p->func[func]->groups[0]];
	else
		*groups = p->group_names;

	*num_groups = p->func[func]->group_count;

	return 0;
}

static int rt2880_pmx_group_enable(struct pinctrl_dev *pctrldev,
				   unsigned int func, unsigned int group)
{
	struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
	u32 mode = 0;
	u32 reg = SYSC_REG_GPIO_MODE;
	int i;
	int shift;

	/* dont allow double use */
	if (p->groups[group].enabled) {
		dev_err(p->dev, "%s is already enabled\n",
			p->groups[group].name);
		return -EBUSY;
	}

	p->groups[group].enabled = 1;
	p->func[func]->enabled = 1;

	shift = p->groups[group].shift;
	if (shift >= 32) {
		shift -= 32;
		reg = SYSC_REG_GPIO_MODE2;
	}
	mode = rt_sysc_r32(reg);
	mode &= ~(p->groups[group].mask << shift);

	/* mark the pins as gpio */
	for (i = 0; i < p->groups[group].func[0].pin_count; i++)
		p->gpio[p->groups[group].func[0].pins[i]] = 1;

	/* function 0 is gpio and needs special handling */
	if (func == 0) {
		mode |= p->groups[group].gpio << shift;
	} else {
		for (i = 0; i < p->func[func]->pin_count; i++)
			p->gpio[p->func[func]->pins[i]] = 0;
		mode |= p->func[func]->value << shift;
	}
	rt_sysc_w32(mode, reg);

	return 0;
}

static int rt2880_pmx_group_gpio_request_enable(struct pinctrl_dev *pctrldev,
						struct pinctrl_gpio_range *range,
						unsigned int pin)
{
	struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);

	if (!p->gpio[pin]) {
		dev_err(p->dev, "pin %d is not set to gpio mux\n", pin);
		return -EINVAL;
	}

	return 0;
}

static const struct pinmux_ops rt2880_pmx_group_ops = {
	.get_functions_count	= rt2880_pmx_func_count,
	.get_function_name	= rt2880_pmx_func_name,
	.get_function_groups	= rt2880_pmx_group_get_groups,
	.set_mux		= rt2880_pmx_group_enable,
	.gpio_request_enable	= rt2880_pmx_group_gpio_request_enable,
};

static struct pinctrl_desc rt2880_pctrl_desc = {
	.owner		= THIS_MODULE,
	.name		= "rt2880-pinmux",
	.pctlops	= &rt2880_pctrl_ops,
	.pmxops		= &rt2880_pmx_group_ops,
};

static struct rt2880_pmx_func gpio_func = {
	.name = "gpio",
};

static int rt2880_pinmux_index(struct rt2880_priv *p)
{
	struct rt2880_pmx_func **f;
	struct rt2880_pmx_group *mux = p->groups;
	int i, j, c = 0;

	/* count the mux functions */
	while (mux->name) {
		p->group_count++;
		mux++;
	}

	/* allocate the group names array needed by the gpio function */
	p->group_names = devm_kcalloc(p->dev, p->group_count,
				      sizeof(char *), GFP_KERNEL);
	if (!p->group_names)
		return -1;

	for (i = 0; i < p->group_count; i++) {
		p->group_names[i] = p->groups[i].name;
		p->func_count += p->groups[i].func_count;
	}

	/* we have a dummy function[0] for gpio */
	p->func_count++;

	/* allocate our function and group mapping index buffers */
	f = p->func = devm_kcalloc(p->dev,
				   p->func_count,
				   sizeof(struct rt2880_pmx_func),
				   GFP_KERNEL);
	gpio_func.groups = devm_kcalloc(p->dev, p->group_count, sizeof(int),
					GFP_KERNEL);
	if (!f || !gpio_func.groups)
		return -1;

	/* add a backpointer to the function so it knows its group */
	gpio_func.group_count = p->group_count;
	for (i = 0; i < gpio_func.group_count; i++)
		gpio_func.groups[i] = i;

	f[c] = &gpio_func;
	c++;

	/* add remaining functions */
	for (i = 0; i < p->group_count; i++) {
		for (j = 0; j < p->groups[i].func_count; j++) {
			f[c] = &p->groups[i].func[j];
			f[c]->groups = devm_kzalloc(p->dev, sizeof(int),
						    GFP_KERNEL);
			f[c]->groups[0] = i;
			f[c]->group_count = 1;
			c++;
		}
	}
	return 0;
}

static int rt2880_pinmux_pins(struct rt2880_priv *p)
{
	int i, j;

	/*
	 * loop over the functions and initialize the pins array.
	 * also work out the highest pin used.
	 */
	for (i = 0; i < p->func_count; i++) {
		int pin;

		if (!p->func[i]->pin_count)
			continue;

		p->func[i]->pins = devm_kcalloc(p->dev,
						p->func[i]->pin_count,
						sizeof(int),
						GFP_KERNEL);
		for (j = 0; j < p->func[i]->pin_count; j++)
			p->func[i]->pins[j] = p->func[i]->pin_first + j;

		pin = p->func[i]->pin_first + p->func[i]->pin_count;
		if (pin > p->max_pins)
			p->max_pins = pin;
	}

	/* the buffer that tells us which pins are gpio */
	p->gpio = devm_kcalloc(p->dev, p->max_pins, sizeof(u8), GFP_KERNEL);
	/* the pads needed to tell pinctrl about our pins */
	p->pads = devm_kcalloc(p->dev, p->max_pins,
			       sizeof(struct pinctrl_pin_desc), GFP_KERNEL);
	if (!p->pads || !p->gpio) {
		dev_err(p->dev, "Failed to allocate gpio data\n");
		return -ENOMEM;
	}

	memset(p->gpio, 1, sizeof(u8) * p->max_pins);
	for (i = 0; i < p->func_count; i++) {
		if (!p->func[i]->pin_count)
			continue;

		for (j = 0; j < p->func[i]->pin_count; j++)
			p->gpio[p->func[i]->pins[j]] = 0;
	}

	/* pin 0 is always a gpio */
	p->gpio[0] = 1;

	/* set the pads */
	for (i = 0; i < p->max_pins; i++) {
		/* strlen("ioXY") + 1 = 5 */
		char *name = devm_kzalloc(p->dev, 5, GFP_KERNEL);

		if (!name)
			return -ENOMEM;
		snprintf(name, 5, "io%d", i);
		p->pads[i].number = i;
		p->pads[i].name = name;
	}
	p->desc->pins = p->pads;
	p->desc->npins = p->max_pins;

	return 0;
}

static int rt2880_pinmux_probe(struct platform_device *pdev)
{
	struct rt2880_priv *p;
	struct pinctrl_dev *dev;
	struct device_node *np;

	if (!rt2880_pinmux_data)
		return -ENOTSUPP;

	/* setup the private data */
	p = devm_kzalloc(&pdev->dev, sizeof(struct rt2880_priv), GFP_KERNEL);
	if (!p)
		return -ENOMEM;

	p->dev = &pdev->dev;
	p->desc = &rt2880_pctrl_desc;
	p->groups = rt2880_pinmux_data;
	platform_set_drvdata(pdev, p);

	/* init the device */
	if (rt2880_pinmux_index(p)) {
		dev_err(&pdev->dev, "failed to load index\n");
		return -EINVAL;
	}
	if (rt2880_pinmux_pins(p)) {
		dev_err(&pdev->dev, "failed to load pins\n");
		return -EINVAL;
	}
	dev = pinctrl_register(p->desc, &pdev->dev, p);
	if (IS_ERR(dev))
		return PTR_ERR(dev);

	/* finalize by adding gpio ranges for enables gpio controllers */
	for_each_compatible_node(np, NULL, "ralink,rt2880-gpio") {
		const __be32 *ngpio, *gpiobase;
		struct pinctrl_gpio_range *range;
		char *name;

		if (!of_device_is_available(np))
			continue;

		ngpio = of_get_property(np, "ralink,num-gpios", NULL);
		gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
		if (!ngpio || !gpiobase) {
			dev_err(&pdev->dev, "failed to load chip info\n");
			return -EINVAL;
		}

		range = devm_kzalloc(p->dev, sizeof(*range) + 4, GFP_KERNEL);
		range->name = name = (char *) &range[1];
		sprintf(name, "pio");
		range->npins = __be32_to_cpu(*ngpio);
		range->base = __be32_to_cpu(*gpiobase);
		range->pin_base = range->base;
		pinctrl_add_gpio_range(dev, range);
	}

	return 0;
}

static const struct of_device_id rt2880_pinmux_match[] = {
	{ .compatible = "ralink,rt2880-pinmux" },
	{},
};
MODULE_DEVICE_TABLE(of, rt2880_pinmux_match);

static struct platform_driver rt2880_pinmux_driver = {
	.probe = rt2880_pinmux_probe,
	.driver = {
		.name = "rt2880-pinmux",
		.of_match_table = rt2880_pinmux_match,
	},
};

int __init rt2880_pinmux_init(void)
{
	return platform_driver_register(&rt2880_pinmux_driver);
}

core_initcall_sync(rt2880_pinmux_init);
