// SPDX-License-Identifier: GPL-2.0 /* * Combined GPIO and pin controller support for Renesas RZ/A1 (r7s72100) SoC * * Copyright (C) 2017 Jacopo Mondi
*/
/* * This pin controller/gpio combined driver supports Renesas devices of RZ/A1 * family. * This includes SoCs which are sub- or super- sets of this particular line, * as RZ/A1H (r7s721000), RZ/A1M (r7s721010) and RZ/A1L (r7s721020).
*/
/* * rza1_bidir_pin - describe a single pin that needs bidir flag applied.
*/ struct rza1_bidir_pin {
u8 pin: 4;
u8 func: 4;
};
/* * rza1_bidir_entry - describe a list of pins that needs bidir flag applied. * Each struct rza1_bidir_entry describes a port.
*/ struct rza1_bidir_entry { constunsignedint npins; conststruct rza1_bidir_pin *pins;
};
/* * rza1_swio_pin - describe a single pin that needs swio flag applied.
*/ struct rza1_swio_pin {
u16 pin: 4;
u16 port: 4;
u16 func: 4;
u16 input: 1;
};
/* * rza1_swio_entry - describe a list of pins that needs swio flag applied
*/ struct rza1_swio_entry { constunsignedint npins; conststruct rza1_swio_pin *pins;
};
/* * rza1_pinmux_conf - group together bidir and swio pinmux flag tables
*/ struct rza1_pinmux_conf { conststruct rza1_bidir_entry *bidir_entries; conststruct rza1_swio_entry *swio_entries;
};
/* ---------------------------------------------------------------------------- * RZ/A1 types
*/ /** * struct rza1_mux_conf - describes a pin multiplexing operation * * @id: the pin identifier from 0 to RZA1_NPINS * @port: the port where pin sits on * @pin: pin id * @mux_func: alternate function id number * @mux_flags: alternate function flags * @value: output value to set the pin to
*/ struct rza1_mux_conf {
u16 id;
u8 port;
u8 pin;
u8 mux_func;
u8 mux_flags;
u8 value;
};
/** * struct rza1_port - describes a pin port * * This is mostly useful to lock register writes per-bank and not globally. * * @lock: protect access to HW registers * @id: port number * @base: logical address base * @pins: pins sitting on this port
*/ struct rza1_port {
spinlock_t lock; unsignedint id; void __iomem *base; struct pinctrl_pin_desc *pins;
};
/** * struct rza1_pinctrl - RZ pincontroller device * * @dev: parent device structure * @mutex: protect [pinctrl|pinmux]_generic functions * @base: logical address base * @nport: number of pin controller ports * @ports: pin controller banks * @pins: pin array for pinctrl core * @desc: pincontroller desc for pinctrl core * @pctl: pinctrl device * @data: device specific data
*/ struct rza1_pinctrl { struct device *dev;
/** * rza1_pin_reset() - reset a pin to default initial state * * Reset pin state disabling input buffer and bi-directional control, * and configure it as input port. * Note that pin is now configured with direction as input but with input * buffer disabled. This implies the pin value cannot be read in this state. * * @port: port where pin sits on * @pin: pin offset
*/ staticvoid rza1_pin_reset(struct rza1_port *port, unsignedint pin)
{ unsignedlong irqflags;
/** * rza1_pin_set_direction() - set I/O direction on a pin in port mode * * When running in output port mode keep PBDC enabled to allow reading the * pin value from PPR. * * @port: port where pin sits on * @pin: pin offset * @input: input enable/disable flag
*/ staticinlinevoid rza1_pin_set_direction(struct rza1_port *port, unsignedint pin, bool input)
{ unsignedlong irqflags;
/* SWIO pinmux flags coming from DT are high precedence */
mux_flags_from_table = rza1_pinmux_get_flags(port->id, pin, mux_func,
rza1_pctl); if (mux_flags)
mux_flags |= (mux_flags_from_table & MUX_FLAGS_BIDIR); else
mux_flags = mux_flags_from_table;
if (mux_flags & MUX_FLAGS_BIDIR)
rza1_set_bit(port, RZA1_PBDC_REG, pin, 1);
/* * Enable alternate function mode and select it. * * Be careful here: the pin mux sub-nodes in device tree * enumerate alternate functions from 1 to 8; * subtract 1 before using macros to match registers configuration * which expects numbers from 0 to 7 instead. * * ---------------------------------------------------- * Alternate mode selection table: * * PMC PFC PFCE PFCAE (mux_func - 1) * 1 0 0 0 0 * 1 1 0 0 1 * 1 0 1 0 2 * 1 1 1 0 3 * 1 0 0 1 4 * 1 1 0 1 5 * 1 0 1 1 6 * 1 1 1 1 7 * ----------------------------------------------------
*/
mux_func -= 1;
rza1_set_bit(port, RZA1_PFC_REG, pin, mux_func & MUX_FUNC_PFC_MASK);
rza1_set_bit(port, RZA1_PFCE_REG, pin, mux_func & MUX_FUNC_PFCE_MASK);
rza1_set_bit(port, RZA1_PFCEA_REG, pin, mux_func & MUX_FUNC_PFCEA_MASK);
/* * All alternate functions except a few need PIPCn = 1. * If PIPCn has to stay disabled (SW IO mode), configure PMn according * to I/O direction specified by pin configuration -after- PMC has been * set to one.
*/ if (mux_flags & (MUX_FLAGS_SWIO_INPUT | MUX_FLAGS_SWIO_OUTPUT))
rza1_set_bit(port, RZA1_PM_REG, pin,
mux_flags & MUX_FLAGS_SWIO_INPUT); else
rza1_set_bit(port, RZA1_PIPC_REG, pin, 1);
/** * rza1_gpio_request() - configure pin in port mode * * Configure a pin as gpio (port mode). * After reset, the pin is in input mode with input buffer disabled. * To use the pin as input or output, set_direction shall be called first * * @chip: gpio chip where the gpio sits on * @gpio: gpio offset
*/ staticint rza1_gpio_request(struct gpio_chip *chip, unsignedint gpio)
{ struct rza1_port *port = gpiochip_get_data(chip); int ret;
ret = pinctrl_gpio_request(chip, gpio); if (ret) return ret;
rza1_pin_reset(port, gpio);
return 0;
}
/** * rza1_gpio_free() - reset a pin * * Surprisingly, freeing a gpio is equivalent to requesting it. * Reset pin to port mode, with input buffer disabled. This overwrites all * port direction settings applied with set_direction * * @chip: gpio chip where the gpio sits on * @gpio: gpio offset
*/ staticvoid rza1_gpio_free(struct gpio_chip *chip, unsignedint gpio)
{ struct rza1_port *port = gpiochip_get_data(chip);
/* Set value before driving pin direction */
rza1_pin_set(port, gpio, value);
rza1_pin_set_direction(port, gpio, false);
return 0;
}
/** * rza1_gpio_get() - read a gpio pin value * * Read gpio pin value through PPR register. * Requires bi-directional mode to work when reading the value of a pin * in output mode * * @chip: gpio chip where the gpio sits on * @gpio: gpio offset
*/ staticint rza1_gpio_get(struct gpio_chip *chip, unsignedint gpio)
{ struct rza1_port *port = gpiochip_get_data(chip);
/** * rza1_dt_node_pin_count() - Count number of pins in a dt node or in all its * children sub-nodes * * @np: device tree node to parse
*/ staticint rza1_dt_node_pin_count(struct device_node *np)
{ struct property *of_pins; unsignedint npins;
/* * Collect pin configuration properties: they apply to all pins in * this sub-node
*/
ret = pinconf_generic_parse_dt_config(np, pctldev, &pin_configs,
&npin_configs); if (ret) {
dev_err(rza1_pctl->dev, "Unable to parse pin configuration options for %pOFn\n",
np); return ret;
}
/* * Create a mask with pinmux flags from pin configuration; * very few pins (TIOC[0-4][A|B|C|D] require SWIO direction * specified in device tree.
*/
pinmux_flags = 0; for (i = 0; i < npin_configs && pinmux_flags == 0; i++) switch (pinconf_to_config_param(pin_configs[i])) { case PIN_CONFIG_INPUT_ENABLE:
pinmux_flags |= MUX_FLAGS_SWIO_INPUT; break; case PIN_CONFIG_OUTPUT: /* for DT backwards compatibility */ case PIN_CONFIG_OUTPUT_ENABLE:
pinmux_flags |= MUX_FLAGS_SWIO_OUTPUT; break; default: break;
}
kfree(pin_configs);
/* Collect pin positions and their mux settings. */ for (i = 0; i < npins; ++i) {
u32 of_pinconf; struct rza1_mux_conf *mux_conf = &mux_confs[i];
ret = of_property_read_u32_index(np, prop_name, i, &of_pinconf); if (ret) return ret;
/* * Functions are made of 1 group only; * in fact, functions and groups are identical for this pin controller * except that functions carry an array of per-pin mux configuration * settings.
*/
mux_confs = devm_kcalloc(rza1_pctl->dev, npins, sizeof(*mux_confs),
GFP_KERNEL);
grpins = devm_kcalloc(rza1_pctl->dev, npins, sizeof(*grpins),
GFP_KERNEL);
fngrps = devm_kzalloc(rza1_pctl->dev, sizeof(*fngrps), GFP_KERNEL);
if (!mux_confs || !grpins || !fngrps) return -ENOMEM;
/* * Parse the pinmux node. * If the node does not contain "pinmux" property (-ENOENT) * that property shall be specified in all its children sub-nodes.
*/
mux_conf = &mux_confs[0];
grpin = &grpins[0];
ret = rza1_parse_pinmux_node(rza1_pctl, np, mux_conf, grpin); if (ret == -ENOENT)
for_each_child_of_node_scoped(np, child) {
ret = rza1_parse_pinmux_node(rza1_pctl, child, mux_conf,
grpin); if (ret < 0) return ret;
fsel = pinmux_generic_add_function(pctldev, grpname, fngrps, 1,
mux_confs); if (fsel < 0) {
ret = fsel; goto remove_group;
}
dev_info(rza1_pctl->dev, "Parsed function and group %s with %d pins\n",
grpname, npins);
/* Create map where to retrieve function and mux settings from */
*num_maps = 0;
*map = kzalloc(sizeof(**map), GFP_KERNEL); if (!*map) {
ret = -ENOMEM; goto remove_function;
}
/** * rza1_parse_gpiochip() - parse and register a gpio chip and pin range * * The gpio controller subnode shall provide a "gpio-ranges" list property as * defined by gpio device tree binding documentation. * * @rza1_pctl: RZ/A1 pin controller device * @fwnode: gpio-controller firmware node * @chip: gpio chip to register to gpiolib * @range: pin range to register to pinctrl core
*/ staticint rza1_parse_gpiochip(struct rza1_pinctrl *rza1_pctl, struct fwnode_handle *fwnode, struct gpio_chip *chip, struct pinctrl_gpio_range *range)
{ constchar *list_name = "gpio-ranges"; struct fwnode_reference_args args; unsignedint gpioport;
u32 pinctrl_base; int ret;
ret = fwnode_property_get_reference_args(fwnode, list_name, NULL, 3, 0, &args); if (ret) {
dev_err(rza1_pctl->dev, "Unable to parse %s list property\n",
list_name); return ret;
}
/* * Find out on which port this gpio-chip maps to by inspecting the * second argument of the "gpio-ranges" property.
*/
pinctrl_base = args.args[1];
gpioport = RZA1_PIN_ID_TO_PORT(pinctrl_base); if (gpioport >= RZA1_NPORTS) {
dev_err(rza1_pctl->dev, "Invalid values in property %s\n", list_name); return -EINVAL;
}
if (i % RZA1_PINS_PER_PORT == 0) { /* * Setup ports; * they provide per-port lock and logical base address.
*/ unsignedint port_id = RZA1_PIN_ID_TO_PORT(i);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.