Lines Matching +full:pinctrl +full:- +full:pin +full:- +full:array
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2017-2025 Arm Ltd.
5 * Generic DT driven Allwinner pinctrl driver routines.
6 * Builds the pin tables from minimal driver information and pin groups
8 * sunxi pinctrl driver.
10 * out in a per-SoC .c file. This code generates this table, like so:
13 * // pin, based on pins_per_bank[] array passed in
15 * SUNXI_FUNCTION(0x0, "gpio_in"), // always added, for every pin
16 * SUNXI_FUNCTION(0x1, "gpio_out"), // always added, for every pin
19 * // mmc0-pins {
25 * // array passed in
32 #include <linux/pinctrl/pinctrl.h>
36 #include "pinctrl-sunxi.h"
57 index = num_elems - 1; in sunxi_pinctrl_dt_read_pinmux()
68 * Allocate a table with a sunxi_desc_pin structure for every pin needed.
69 * Fills in the respective pin names ("PA0") and their pin numbers.
70 * Returns the pins array. We cannot use the member in *desc yet, as this
71 * is marked as const, and we will need to change the array still.
79 int port_base = desc->pin_base / PINS_PER_BANK; in init_pins_table()
85 * Also work out how much memory we need to store all the pin names. in init_pins_table()
88 desc->npins += pins_per_bank[i]; in init_pins_table()
97 name_size += (pins_per_bank[i] - 10) * 5; in init_pins_table()
101 if (desc->npins == 0) { in init_pins_table()
103 return ERR_PTR(-EINVAL); in init_pins_table()
106 pins = devm_kzalloc(dev, desc->npins * sizeof(*pins), GFP_KERNEL); in init_pins_table()
108 return ERR_PTR(-ENOMEM); in init_pins_table()
110 /* Allocate memory to store the name for every pin. */ in init_pins_table()
113 return ERR_PTR(-ENOMEM); in init_pins_table()
115 /* Fill the pins array with the name and the number for each pin. */ in init_pins_table()
123 cur_pin->pin.number = (port_base + i) * PINS_PER_BANK + j; in init_pins_table()
124 cur_pin->pin.name = cur_name; in init_pins_table()
133 * Work out the number of functions for each pin. This will visit every
134 * child node of the pinctrl DT node to find all advertised functions.
135 * Provide memory to hold the per-function information and assign it to
136 * the pin table.
137 * Fill in the GPIO in/out functions already (that every pin has), also add
138 * an "irq" function at the end, for those pins in IRQ-capable ports.
140 * We (ab)use the "variant" member in each pin to keep track of the number of
154 * We need at least three functions per pin: in prepare_function_table()
155 * - one for GPIO in in prepare_function_table()
156 * - one for GPIO out in prepare_function_table()
157 * - one for the sentinel signalling the end of the list in prepare_function_table()
162 * Add a function for each pin in a bank supporting interrupts. in prepare_function_table()
164 * functions per pin. This will be cleaned back to 0 before we hand in prepare_function_table()
165 * over the whole structure to the generic sunxi pinctrl setup code. in prepare_function_table()
168 struct sunxi_desc_pin *pin = &pins[i]; in prepare_function_table() local
169 int bank = pin->pin.number / PINS_PER_BANK; in prepare_function_table()
172 pin->variant++; in prepare_function_table()
178 * Go over each pin group (every child of the pinctrl DT node) and in prepare_function_table()
188 if (strcmp(pins[i].pin.name, name)) in prepare_function_table()
200 * We later use pointers into this table to mark each pin. in prepare_function_table()
204 return -ENOMEM; in prepare_function_table()
213 struct sunxi_desc_pin *pin = &pins[i]; in prepare_function_table() local
214 int bank = pin->pin.number / PINS_PER_BANK; in prepare_function_table()
215 int lastfunc = pin->variant + 1; in prepare_function_table()
228 func[lastfunc].irqnum = pin->pin.number % PINS_PER_BANK; in prepare_function_table()
235 pin->functions = func; in prepare_function_table()
238 func += pin->variant + 3; in prepare_function_table()
244 pin->variant = 2; in prepare_function_table()
252 * mux value to the respective pin.
262 int pin, i, index; in fill_pin_function() local
272 /* Find the index of this pin in our table. */ in fill_pin_function()
273 for (pin = 0; pin < npins; pin++) in fill_pin_function()
274 if (!strcmp(pins[pin].pin.name, name)) in fill_pin_function()
276 if (pin == npins) { in fill_pin_function()
277 dev_warn(dev, "%s: cannot find pin %s\n", in fill_pin_function()
286 dev_warn(dev, "%s: invalid mux value for pin %s\n", in fill_pin_function()
293 * Check for double definitions by comparing the to-be-added in fill_pin_function()
298 for (i = 2; i < pins[pin].variant; i++) { in fill_pin_function()
299 func = &pins[pin].functions[i]; in fill_pin_function()
302 if (strcmp(func->name, funcname) && in fill_pin_function()
303 func->muxval != muxval) in fill_pin_function()
307 if (!strcmp(func->name, funcname) && in fill_pin_function()
308 muxval == func->muxval) in fill_pin_function()
312 "pin %s: function %s redefined to mux %d\n", in fill_pin_function()
318 if (i < pins[pin].variant) { in fill_pin_function()
324 func = &pins[pin].functions[pins[pin].variant]; in fill_pin_function()
325 func->muxval = muxval; in fill_pin_function()
326 func->name = funcname; in fill_pin_function()
328 pins[pin].variant++; in fill_pin_function()
334 * Initialise the pinctrl table, by building it from driver provided
337 * Then iterate over all pinctrl DT node children to enter the function name
338 * and mux values for each mentioned pin.
339 * At the end hand over this structure to the actual sunxi pinctrl driver.
347 struct device_node *pnode = pdev->dev.of_node, *node; in sunxi_pinctrl_dt_table_init()
351 pins = init_pins_table(&pdev->dev, pins_per_bank, desc); in sunxi_pinctrl_dt_table_init()
355 ret = prepare_function_table(&pdev->dev, pnode, pins, desc->npins, in sunxi_pinctrl_dt_table_init()
362 * and mux values to each pin listed within. in sunxi_pinctrl_dt_table_init()
365 fill_pin_function(&pdev->dev, node, pins, desc->npins); in sunxi_pinctrl_dt_table_init()
368 for (i = 0; i < desc->npins; i++) in sunxi_pinctrl_dt_table_init()
371 desc->pins = pins; in sunxi_pinctrl_dt_table_init()