From nobody Fri Dec 19 20:37:36 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5102D301033; Tue, 14 Oct 2025 14:36:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760452596; cv=none; b=MOsxjwhyQ+Stm7rDWx7oMOa/EYAUaRcRLWoUjbHD8V7TNCyTony2+V+zgja74pfFe6yHVxJZuJosPcEQDnZ1HlMSnBrEmiAeRlelEJNyr6dIzpFVSf9Ny3lUBPNFEE4E9TOKd/fkbySdklnDb8uV77VaET5i5SKEl+0Q9nR58MM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760452596; c=relaxed/simple; bh=ThpuZ1xmK86i9CSvkP8swACLJKzVIWNqI7kp42HMWEU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jBiQGxK47BgU8wEvPjUSAOIxOL0By9m8ppFbNoxwHkUS92pTdWToLq8ZC03fO+WqlWg4qtIAa0LAfOa7o8Np1wXLTPRIuRc5C82pfMEnM39c0qrHT80WNpq39IGE97rgHQZIFVuG05xFrL5hIRJe7OXQd3oZzqqU6T0AJmp66uM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LtDT5ALN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LtDT5ALN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 00C4BC4CEE7; Tue, 14 Oct 2025 14:36:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760452595; bh=ThpuZ1xmK86i9CSvkP8swACLJKzVIWNqI7kp42HMWEU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LtDT5ALNKTlWiiD9eOgNUax2daYa5g5bgsqnxltGLKg4YTaSfN2H1n+Vev0eLhBhO oOyZHs7+T7Qr9R7YtiBferU7a+3p7zzjCH99JFR1Sbh3W/Ml0caQMeU8Ozx5ZHMVYY ELAwuVK53nEwrcFqX7fCyMU7youkp9PnCPfbcYXIC5btkXYITUhkaAsPHAhD37BtKJ ieES0yWIqSQy37pKnjEYuh0DoWnEFCRRJPiCj56xly/OCNBJoqt178agN6W4RLLqtZ MraO4lXdRf7ZQ2Y5Wb7nKlZOKtdzSsocEtVLQ6CwFrjhxk8AlHEUJC+QyzVdLAtt55 SvrXxAhDMUHyw== From: Conor Dooley To: linus.walleij@linaro.org Cc: conor@kernel.org, Conor Dooley , Rob Herring , Krzysztof Kozlowski , linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, Valentina.FernandezAlanis@microchip.com Subject: [PATCH v2 2/5] pinctrl: add pic64gx "gpio2" pinmux driver Date: Tue, 14 Oct 2025 15:35:35 +0100 Message-ID: <20251014-sprinkled-nimbly-345abb611f13@spud> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251014-retype-limit-e6cbe901aa07@spud> References: <20251014-retype-limit-e6cbe901aa07@spud> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=12157; i=conor.dooley@microchip.com; h=from:subject:message-id; bh=y+AagTDGpxq0ENd7j9vAGBiPQJqExmGI4w+MFEJMxVs=; b=owGbwMvMwCVWscWwfUFT0iXG02pJDBnv4s95VrfMTPwp4HjZ/EWT5o72G1cfPZ6obbXHw0q+Q 1CrO+5URykLgxgXg6yYIkvi7b4WqfV/XHY497yFmcPKBDKEgYtTACbSXsHwPzxL5im/XkXLm+tx HUL+NreuyjVdFmW50HbjKOstZekGaYZ/9lHyC8vX8v8//6E/cMOkmXt7p7If2JvavvjpW/aN7+u +sgMA X-Developer-Key: i=conor.dooley@microchip.com; a=openpgp; fpr=F9ECA03CF54F12CD01F1655722E2C55B37CF380C Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Conor Dooley The pic64gx has a second pinmux "downstream" of the iomux0 pinmux. The documentation for the SoC provides no name for this device, but it is used to swap pins between either GPIO controller #2 or select other functions, hence the "gpio2" name. Add a driver for it. Signed-off-by: Conor Dooley --- drivers/pinctrl/Kconfig | 7 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-pic64gx-gpio2.c | 357 ++++++++++++++++++++++++ 3 files changed, 365 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-pic64gx-gpio2.c diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 4f8507ebbdac..8b58f50d1184 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -486,6 +486,13 @@ config PINCTRL_PIC32MZDA def_bool y if PIC32MZDA select PINCTRL_PIC32 =20 +config PINCTRL_PIC64GX + bool "pic64gx gpio2 pinctrl driver" + depends on ARCH_MICROCHIP + default y + help + This selects the pinctrl driver for gpio2 on pic64gx. + config PINCTRL_PISTACHIO bool "IMG Pistachio SoC pinctrl driver" depends on OF && (MIPS || COMPILE_TEST) diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index e0cfb9b7c99b..f33976a6c91b 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_PINCTRL_OCELOT) +=3D pinctrl-ocelot.o obj-$(CONFIG_PINCTRL_PALMAS) +=3D pinctrl-palmas.o obj-$(CONFIG_PINCTRL_PEF2256) +=3D pinctrl-pef2256.o obj-$(CONFIG_PINCTRL_PIC32) +=3D pinctrl-pic32.o +obj-$(CONFIG_PINCTRL_PIC64GX) +=3D pinctrl-pic64gx-gpio2.o obj-$(CONFIG_PINCTRL_PISTACHIO) +=3D pinctrl-pistachio.o obj-$(CONFIG_PINCTRL_RK805) +=3D pinctrl-rk805.o obj-$(CONFIG_PINCTRL_ROCKCHIP) +=3D pinctrl-rockchip.o diff --git a/drivers/pinctrl/pinctrl-pic64gx-gpio2.c b/drivers/pinctrl/pinc= trl-pic64gx-gpio2.c new file mode 100644 index 000000000000..ecabef1cea0d --- /dev/null +++ b/drivers/pinctrl/pinctrl-pic64gx-gpio2.c @@ -0,0 +1,357 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "pinctrl-utils.h" + +#define PIC64GX_PINMUX_REG 0x0 + +static const struct regmap_config pic64gx_gpio2_regmap_config =3D { + .reg_bits =3D 32, + .reg_stride =3D 4, + .val_bits =3D 32, + .val_format_endian =3D REGMAP_ENDIAN_LITTLE, + .max_register =3D 0x0, +}; + +struct pic64gx_gpio2_pinctrl { + struct pinctrl_dev *pctrl; + struct device *dev; + struct regmap *regmap; + struct pinctrl_desc desc; +}; + +struct pic64gx_gpio2_pin_group { + const char *name; + const unsigned int *pins; + const unsigned int num_pins; + u32 mask; + u32 setting; +}; + +struct pic64gx_gpio2_function { + const char *name; + const char * const *groups; + const unsigned int num_groups; +}; + +static const struct pinctrl_pin_desc pic64gx_gpio2_pins[] =3D { + PINCTRL_PIN(0, "E14"), + PINCTRL_PIN(1, "E15"), + PINCTRL_PIN(2, "F16"), + PINCTRL_PIN(3, "F17"), + PINCTRL_PIN(4, "D19"), + PINCTRL_PIN(5, "B18"), + PINCTRL_PIN(6, "B10"), + PINCTRL_PIN(7, "C14"), + PINCTRL_PIN(8, "E18"), + PINCTRL_PIN(9, "D18"), + PINCTRL_PIN(10, "E19"), + PINCTRL_PIN(11, "C7"), + PINCTRL_PIN(12, "D6"), + PINCTRL_PIN(13, "D7"), + PINCTRL_PIN(14, "C9"), + PINCTRL_PIN(15, "C10"), + PINCTRL_PIN(16, "A5"), + PINCTRL_PIN(17, "A6"), + PINCTRL_PIN(18, "D8"), + PINCTRL_PIN(19, "D9"), + PINCTRL_PIN(20, "B8"), + PINCTRL_PIN(21, "A8"), + PINCTRL_PIN(22, "C12"), + PINCTRL_PIN(23, "B12"), + PINCTRL_PIN(24, "A11"), + PINCTRL_PIN(25, "A10"), + PINCTRL_PIN(26, "D11"), + PINCTRL_PIN(27, "C11"), + PINCTRL_PIN(28, "B9"), +}; + +static const unsigned int pic64gx_gpio2_mdio0_pins[] =3D { + 0, 1 +}; + +static const unsigned int pic64gx_gpio2_mdio1_pins[] =3D { + 2, 3 +}; + +static const unsigned int pic64gx_gpio2_spi0_pins[] =3D { + 4, 5, 10, 11 +}; + +static const unsigned int pic64gx_gpio2_can0_pins[] =3D { + 6, 24, 28 +}; + +static const unsigned int pic64gx_gpio2_pcie_pins[] =3D { + 7, 8, 9 +}; + +static const unsigned int pic64gx_gpio2_qspi_pins[] =3D { + 12, 13, 14, 15, 16, 17 +}; + +static const unsigned int pic64gx_gpio2_uart3_pins[] =3D { + 18, 19 +}; + +static const unsigned int pic64gx_gpio2_uart4_pins[] =3D { + 20, 21 +}; + +static const unsigned int pic64gx_gpio2_can1_pins[] =3D { + 22, 23, 25 +}; + +static const unsigned int pic64gx_gpio2_uart2_pins[] =3D { + 26, 27 +}; + +//TODO maybe a bit extra, but reduces the risk of adhd mistakes.. +#define PIC64GX_PINCTRL_GROUP(_name, _mask) { \ + .name =3D "gpio_" #_name, \ + .pins =3D pic64gx_gpio2_##_name##_pins, \ + .num_pins =3D ARRAY_SIZE(pic64gx_gpio2_##_name##_pins), \ + .mask =3D _mask, \ + .setting =3D 0x0, \ +}, { \ + .name =3D #_name, \ + .pins =3D pic64gx_gpio2_##_name##_pins, \ + .num_pins =3D ARRAY_SIZE(pic64gx_gpio2_##_name##_pins), \ + .mask =3D _mask, \ + .setting =3D _mask, \ +} + +static const struct pic64gx_gpio2_pin_group pic64gx_gpio2_pin_groups[] =3D= { + PIC64GX_PINCTRL_GROUP(mdio0, BIT(0) | BIT(1)), + PIC64GX_PINCTRL_GROUP(mdio1, BIT(2) | BIT(3)), + PIC64GX_PINCTRL_GROUP(spi0, BIT(4) | BIT(5) | BIT(10) | BIT(11)), + PIC64GX_PINCTRL_GROUP(can0, BIT(6) | BIT(24) | BIT(28)), + PIC64GX_PINCTRL_GROUP(pcie, BIT(7) | BIT(8) | BIT(9)), + PIC64GX_PINCTRL_GROUP(qspi, GENMASK(17, 12)), + PIC64GX_PINCTRL_GROUP(uart3, BIT(18) | BIT(19)), + PIC64GX_PINCTRL_GROUP(uart4, BIT(20) | BIT(21)), + PIC64GX_PINCTRL_GROUP(can1, BIT(22) | BIT(23) | BIT(25)), + PIC64GX_PINCTRL_GROUP(uart2, BIT(26) | BIT(27)), +}; + +static const char * const pic64gx_gpio2_gpio_groups[] =3D { + "gpio_mdio0", "gpio_mdio1", "gpio_spi0", "gpio_can0", "gpio_pcie", + "gpio_qspi", "gpio_uart3", "gpio_uart4", "gpio_can1", "gpio_uart2" +}; + +static const char * const pic64gx_gpio2_mdio0_groups[] =3D { + "mdio0" +}; + +static const char * const pic64gx_gpio2_mdio1_groups[] =3D { + "mdio1" +}; + +static const char * const pic64gx_gpio2_spi0_groups[] =3D { + "spi0" +}; + +static const char * const pic64gx_gpio2_can0_groups[] =3D { + "can0" +}; + +static const char * const pic64gx_gpio2_pcie_groups[] =3D { + "pcie" +}; + +static const char * const pic64gx_gpio2_qspi_groups[] =3D { + "qspi" +}; + +static const char * const pic64gx_gpio2_uart3_groups[] =3D { + "uart3" +}; + +static const char * const pic64gx_gpio2_uart4_groups[] =3D { + "uart4" +}; + +static const char * const pic64gx_gpio2_can1_groups[] =3D { + "can1" +}; + +static const char * const pic64gx_gpio2_uart2_groups[] =3D { + "uart2" +}; + +#define PIC64GX_PINCTRL_FUNCTION(_name) { \ + .name =3D #_name, \ + .groups =3D pic64gx_gpio2_##_name##_groups, \ + .num_groups =3D ARRAY_SIZE(pic64gx_gpio2_##_name##_groups), \ +} + +static const struct pic64gx_gpio2_function pic64gx_gpio2_functions[] =3D { + PIC64GX_PINCTRL_FUNCTION(gpio), + PIC64GX_PINCTRL_FUNCTION(mdio0), + PIC64GX_PINCTRL_FUNCTION(mdio1), + PIC64GX_PINCTRL_FUNCTION(spi0), + PIC64GX_PINCTRL_FUNCTION(can0), + PIC64GX_PINCTRL_FUNCTION(pcie), + PIC64GX_PINCTRL_FUNCTION(qspi), + PIC64GX_PINCTRL_FUNCTION(uart3), + PIC64GX_PINCTRL_FUNCTION(uart4), + PIC64GX_PINCTRL_FUNCTION(can1), + PIC64GX_PINCTRL_FUNCTION(uart2), +}; + +static void pic64gx_gpio2_pin_dbg_show(struct pinctrl_dev *pctrl_dev, stru= ct seq_file *seq, + unsigned int pin) +{ + struct pic64gx_gpio2_pinctrl *pctrl =3D pinctrl_dev_get_drvdata(pctrl_dev= ); + u32 val; + + regmap_read(pctrl->regmap, PIC64GX_PINMUX_REG, &val); + val =3D (val & BIT(pin)) >> pin; + seq_printf(seq, "pin: %u val: %x\n", pin, val); +} + +static int pic64gx_gpio2_groups_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(pic64gx_gpio2_pin_groups); +} + +static const char *pic64gx_gpio2_group_name(struct pinctrl_dev *pctldev, u= nsigned int selector) +{ + return pic64gx_gpio2_pin_groups[selector].name; +} + +static int pic64gx_gpio2_group_pins(struct pinctrl_dev *pctldev, unsigned = int selector, + const unsigned int **pins, unsigned int *num_pins) +{ + *pins =3D pic64gx_gpio2_pin_groups[selector].pins; + *num_pins =3D pic64gx_gpio2_pin_groups[selector].num_pins; + + return 0; +} + +static const struct pinctrl_ops pic64gx_gpio2_pinctrl_ops =3D { + .get_groups_count =3D pic64gx_gpio2_groups_count, + .get_group_name =3D pic64gx_gpio2_group_name, + .get_group_pins =3D pic64gx_gpio2_group_pins, + .dt_node_to_map =3D pinconf_generic_dt_node_to_map_all, + .dt_free_map =3D pinctrl_utils_free_map, + .pin_dbg_show =3D pic64gx_gpio2_pin_dbg_show, +}; + +static int pic64gx_gpio2_pinmux_get_funcs_count(struct pinctrl_dev *pctlde= v) +{ + return ARRAY_SIZE(pic64gx_gpio2_functions); +} + +static const char *pic64gx_gpio2_pinmux_get_func_name(struct pinctrl_dev *= pctldev, + unsigned int selector) +{ + return pic64gx_gpio2_functions[selector].name; +} + +static int pic64gx_gpio2_pinmux_get_groups(struct pinctrl_dev *pctldev, un= signed int selector, + const char * const **groups, + unsigned int * const num_groups) +{ + *groups =3D pic64gx_gpio2_functions[selector].groups; + *num_groups =3D pic64gx_gpio2_functions[selector].num_groups; + + return 0; +} + +static int pic64gx_gpio2_pinmux_set_mux(struct pinctrl_dev *pctrl_dev, uns= igned int fsel, + unsigned int gsel) +{ + struct pic64gx_gpio2_pinctrl *pctrl =3D pinctrl_dev_get_drvdata(pctrl_dev= ); + struct device *dev =3D pctrl->dev; + const struct pic64gx_gpio2_pin_group *group; + const struct pic64gx_gpio2_function *function; + + group =3D &pic64gx_gpio2_pin_groups[gsel]; + function =3D &pic64gx_gpio2_functions[fsel]; + + dev_dbg(dev, "Setting func %s mask %x setting %x\n", + function->name, group->mask, group->setting); + regmap_assign_bits(pctrl->regmap, PIC64GX_PINMUX_REG, group->mask, group-= >setting); + + return 0; +} + +static const struct pinmux_ops pic64gx_gpio2_pinmux_ops =3D { + .get_functions_count =3D pic64gx_gpio2_pinmux_get_funcs_count, + .get_function_name =3D pic64gx_gpio2_pinmux_get_func_name, + .get_function_groups =3D pic64gx_gpio2_pinmux_get_groups, + .set_mux =3D pic64gx_gpio2_pinmux_set_mux, +}; + +static int pic64gx_gpio2_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct pic64gx_gpio2_pinctrl *pctrl; + void __iomem *base; + + pctrl =3D devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); + if (!pctrl) + return -ENOMEM; + + base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) { + dev_err(dev, "Failed get resource\n"); + return PTR_ERR(base); + } + + pctrl->regmap =3D devm_regmap_init_mmio(dev, base, &pic64gx_gpio2_regmap_= config); + if (IS_ERR(pctrl->regmap)) { + dev_err(dev, "Failed to map regmap\n"); + return PTR_ERR(pctrl->regmap); + } + + pctrl->desc.name =3D dev_name(dev); + pctrl->desc.pins =3D pic64gx_gpio2_pins; + pctrl->desc.npins =3D ARRAY_SIZE(pic64gx_gpio2_pins); + pctrl->desc.pctlops =3D &pic64gx_gpio2_pinctrl_ops; + pctrl->desc.pmxops =3D &pic64gx_gpio2_pinmux_ops; + pctrl->desc.owner =3D THIS_MODULE; + + pctrl->dev =3D dev; + + platform_set_drvdata(pdev, pctrl); + + pctrl->pctrl =3D devm_pinctrl_register(&pdev->dev, &pctrl->desc, pctrl); + if (IS_ERR(pctrl->pctrl)) + return PTR_ERR(pctrl->pctrl); + + return 0; +} + +static const struct of_device_id pic64gx_gpio2_of_match[] =3D { + { .compatible =3D "microchip,pic64gx-pinctrl-gpio2" }, + { } +}; +MODULE_DEVICE_TABLE(of, pic64gx_gpio2_of_match); + +static struct platform_driver pic64gx_gpio2_driver =3D { + .driver =3D { + .name =3D "pic64gx-pinctrl-gpio2", + .of_match_table =3D pic64gx_gpio2_of_match, + }, + .probe =3D pic64gx_gpio2_probe, +}; +module_platform_driver(pic64gx_gpio2_driver); + +MODULE_AUTHOR("Conor Dooley "); +MODULE_DESCRIPTION("pic64gx gpio2 pinctrl driver"); +MODULE_LICENSE("GPL"); --=20 2.51.0