// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2017-2025 Arm Ltd.
 *
 * Generic DT driven Allwinner pinctrl driver routines.
 * Builds the pin tables from minimal driver information and pin groups
 * described in the DT. Then hands those tables of to the traditional
 * sunxi pinctrl driver.
 * sunxi_pinctrl_init() expects a table like shown below, previously spelled
 * out in a per-SoC .c file. This code generates this table, like so:
 *
 *  SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),	// code iterates over every implemented
 *				// pin, based on pins_per_bank[] array passed in
 *
 *    SUNXI_FUNCTION(0x0, "gpio_in"),	// always added, for every pin
 *    SUNXI_FUNCTION(0x1, "gpio_out"),	// always added, for every pin
 *
 *    SUNXI_FUNCTION(0x2, "mmc0"),	// based on pingroup found in DT:
 *				//   mmc0-pins {
 *				//       pins = "PF0", "PF1", ...
 *				//       function = "mmc0";
 *				//       allwinner,pinmux = <2>;
 *
 *    SUNXI_FUNCTION_IRQ_BANK(0x6, 4, 1)),	// derived by irq_bank_muxes[]
 *						// array passed in
 */

#include <linux/export.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include "pinctrl-sunxi.h"

#define INVALID_MUX	0xff

/*
 * Return the "index"th element from the "allwinner,pinmux" property. If the
 * property does not hold enough entries, return the last one instead.
 * For almost every group the pinmux value is actually the same, so this
 * allows to just list one value in the property.
 */
static u8 sunxi_pinctrl_dt_read_pinmux(const struct device_node *node,
				       int index)
{
	int ret, num_elems;
	u32 value;

	num_elems = of_property_count_u32_elems(node, "allwinner,pinmux");
	if (num_elems <= 0)
		return INVALID_MUX;

	if (index >= num_elems)
		index = num_elems - 1;

	ret = of_property_read_u32_index(node, "allwinner,pinmux", index,
					 &value);
	if (ret)
		return INVALID_MUX;

	return value;
}

/*
 * Allocate a table with a sunxi_desc_pin structure for every pin needed.
 * Fills in the respective pin names ("PA0") and their pin numbers.
 * Returns the pins array. We cannot use the member in *desc yet, as this
 * is marked as const, and we will need to change the array still.
 */
static struct sunxi_desc_pin *init_pins_table(struct device *dev,
					      const u8 *pins_per_bank,
					      struct sunxi_pinctrl_desc *desc)
{
	struct sunxi_desc_pin *pins, *cur_pin;
	int name_size = 0;
	int port_base = desc->pin_base / PINS_PER_BANK;
	char *pin_names, *cur_name;
	int i, j;

	/*
	 * Find the total number of pins.
	 * Also work out how much memory we need to store all the pin names.
	 */
	for (i = 0; i < SUNXI_PINCTRL_MAX_BANKS; i++) {
		desc->npins += pins_per_bank[i];
		if (pins_per_bank[i] < 10) {
			/* 4 bytes for "PXy\0" */
			name_size += pins_per_bank[i] * 4;
		} else {
			/* 4 bytes for each "PXy\0" */
			name_size += 10 * 4;

			/* 5 bytes for each "PXyy\0" */
			name_size += (pins_per_bank[i] - 10) * 5;
		}
	}

	if (desc->npins == 0) {
		dev_err(dev, "no ports defined\n");
		return ERR_PTR(-EINVAL);
	}

	pins = devm_kcalloc(dev, desc->npins, sizeof(*pins), GFP_KERNEL);
	if (!pins)
		return ERR_PTR(-ENOMEM);

	/* Allocate memory to store the name for every pin. */
	pin_names = devm_kmalloc(dev, name_size, GFP_KERNEL);
	if (!pin_names)
		return ERR_PTR(-ENOMEM);

	/* Fill the pins array with the name and the number for each pin. */
	cur_name = pin_names;
	cur_pin = pins;
	for (i = 0; i < SUNXI_PINCTRL_MAX_BANKS; i++) {
		for (j = 0; j < pins_per_bank[i]; j++, cur_pin++) {
			int nchars = sprintf(cur_name, "P%c%d",
					     port_base + 'A' + i, j);

			cur_pin->pin.number = (port_base + i) * PINS_PER_BANK + j;
			cur_pin->pin.name = cur_name;
			cur_name += nchars + 1;
		}
	}

	return pins;
}

/*
 * Work out the number of functions for each pin. This will visit every
 * child node of the pinctrl DT node to find all advertised functions.
 * Provide memory to hold the per-function information and assign it to
 * the pin table.
 * Fill in the GPIO in/out functions already (that every pin has), also add
 * an "irq" function at the end, for those pins in IRQ-capable ports.
 * We do not fill in the extra functions (those describe in DT nodes) yet.
 * We (ab)use the "variant" member in each pin to keep track of the number of
 * extra functions needed. At the end this will get reset to 2, so that we
 * can add extra function later, after the two GPIO functions.
 */
static int prepare_function_table(struct device *dev, struct device_node *pnode,
				  struct sunxi_desc_pin *pins, int npins,
				  unsigned pin_base, const u8 *irq_bank_muxes)
{
	struct device_node *node;
	struct property *prop;
	struct sunxi_desc_function *func;
	int num_funcs, irq_bank, last_bank, i;

	/*
	 * We need at least three functions per pin:
	 * - one for GPIO in
	 * - one for GPIO out
	 * - one for the sentinel signalling the end of the list
	 */
	num_funcs = 3 * npins;

	/*
	 * Add a function for each pin in a bank supporting interrupts.
	 * We temporarily (ab)use the variant field to store the number of
	 * functions per pin. This will be cleaned back to 0 before we hand
	 * over the whole structure to the generic sunxi pinctrl setup code.
	 */
	for (i = 0; i < npins; i++) {
		struct sunxi_desc_pin *pin = &pins[i];
		int bank = (pin->pin.number - pin_base) / PINS_PER_BANK;

		if (irq_bank_muxes[bank]) {
			pin->variant++;
			num_funcs++;
		}
	}

	/*
	 * Go over each pin group (every child of the pinctrl DT node) and
	 * add the number of special functions each pins has. Also update the
	 * total number of functions required.
	 * We might slightly overshoot here in case of double definitions.
	 */
	for_each_child_of_node(pnode, node) {
		const char *name;

		of_property_for_each_string(node, "pins", prop, name) {
			for (i = 0; i < npins; i++) {
				if (strcmp(pins[i].pin.name, name))
					continue;

				pins[i].variant++;
				num_funcs++;
				break;
			}
		}
	}

	/*
	 * Allocate the memory needed for the functions in one table.
	 * We later use pointers into this table to mark each pin.
	 */
	func = devm_kcalloc(dev, num_funcs, sizeof(*func), GFP_KERNEL);
	if (!func)
		return -ENOMEM;

	/*
	 * Assign the function's memory and fill in GPIOs, IRQ and a sentinel.
	 * The extra functions will be filled in later.
	 */
	irq_bank = 0;
	last_bank = 0;
	for (i = 0; i < npins; i++) {
		struct sunxi_desc_pin *pin = &pins[i];
		int bank = (pin->pin.number - pin_base) / PINS_PER_BANK;
		int lastfunc = pin->variant + 1;
		int irq_mux = irq_bank_muxes[bank];

		func[0].name = "gpio_in";
		func[0].muxval = 0;
		func[1].name = "gpio_out";
		func[1].muxval = 1;

		if (irq_mux) {
			if (bank > last_bank)
				irq_bank++;
			func[lastfunc].muxval = irq_mux;
			func[lastfunc].irqbank = irq_bank;
			func[lastfunc].irqnum = pin->pin.number % PINS_PER_BANK;
			func[lastfunc].name = "irq";
		}

		if (bank > last_bank)
			last_bank = bank;

		pin->functions = func;

		/* Skip over the other needed functions and the sentinel. */
		func += pin->variant + 3;

		/*
		 * Reset the value for filling in the remaining functions
		 * behind the GPIOs later.
		 */
		pin->variant = 2;
	}

	return 0;
}

/*
 * Iterate over all pins in a single group and add the function name and its
 * mux value to the respective pin.
 * The "variant" member is again used to temporarily track the number of
 * already added functions.
 */
static void fill_pin_function(struct device *dev, struct device_node *node,
			      struct sunxi_desc_pin *pins, int npins)
{
	const char *name, *funcname;
	struct sunxi_desc_function *func;
	struct property *prop;
	int pin, i, index;
	u8 muxval;

	if (of_property_read_string(node, "function", &funcname)) {
		dev_warn(dev, "missing \"function\" property\n");
		return;
	}

	index = 0;
	of_property_for_each_string(node, "pins", prop, name) {
		/* Find the index of this pin in our table. */
		for (pin = 0; pin < npins; pin++)
			if (!strcmp(pins[pin].pin.name, name))
				break;
		if (pin == npins) {
			dev_warn(dev, "%pOF: cannot find pin %s\n", node, name);
			index++;
			continue;
		}

		/* Read the associated mux value. */
		muxval = sunxi_pinctrl_dt_read_pinmux(node, index);
		if (muxval == INVALID_MUX) {
			dev_warn(dev, "%pOF: invalid mux value for pin %s\n",
				 node, name);
			index++;
			continue;
		}

		/*
		 * Check for double definitions by comparing the to-be-added
		 * function with already assigned ones.
		 * Ignore identical pairs (function name and mux value the
		 * same), but warn about conflicting assignments.
		 */
		for (i = 2; i < pins[pin].variant; i++) {
			func = &pins[pin].functions[i];

			/* Skip over totally unrelated functions. */
			if (strcmp(func->name, funcname) &&
			    func->muxval != muxval)
				continue;

			/* Ignore (but skip below) any identical functions. */
			if (!strcmp(func->name, funcname) &&
			    muxval == func->muxval)
				break;

			dev_warn(dev,
				 "pin %s: function %s redefined to mux %d\n",
				 name, funcname, muxval);
			break;
		}

		/* Skip any pins with that function already assigned. */
		if (i < pins[pin].variant) {
			index++;
			continue;
		}

		/* Assign function and muxval to the next free slot. */
		func = &pins[pin].functions[pins[pin].variant];
		func->muxval = muxval;
		func->name = funcname;

		pins[pin].variant++;
		index++;
	}
}

/*
 * Initialise the pinctrl table, by building it from driver provided
 * information: the number of pins per bank, the IRQ capable banks and their
 * IRQ mux value.
 * Then iterate over all pinctrl DT node children to enter the function name
 * and mux values for each mentioned pin.
 * At the end hand over this structure to the actual sunxi pinctrl driver.
 */
int sunxi_pinctrl_dt_table_init(struct platform_device *pdev,
				const u8 *pins_per_bank,
				const u8 *irq_bank_muxes,
				struct sunxi_pinctrl_desc *desc,
				unsigned long flags)
{
	struct device_node *pnode = pdev->dev.of_node, *node;
	struct sunxi_desc_pin *pins;
	int ret, i;

	pins = init_pins_table(&pdev->dev, pins_per_bank, desc);
	if (IS_ERR(pins))
		return PTR_ERR(pins);

	ret = prepare_function_table(&pdev->dev, pnode, pins, desc->npins,
				     desc->pin_base, irq_bank_muxes);
	if (ret)
		return ret;

	/*
	 * Now iterate over all groups and add the respective function name
	 * and mux values to each pin listed within.
	 */
	for_each_child_of_node(pnode, node)
		fill_pin_function(&pdev->dev, node, pins, desc->npins);

	/* Clear the temporary storage. */
	for (i = 0; i < desc->npins; i++)
		pins[i].variant = 0;

	desc->pins = pins;

	return sunxi_pinctrl_init_with_flags(pdev, desc, flags);
}
