Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: add pic64gx "gpio2" pinmux driver

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 <conor.dooley@microchip.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Conor Dooley and committed by
Linus Walleij
38cf9d64 645f1095

+365
+8
drivers/pinctrl/Kconfig
··· 486 486 def_bool y if PIC32MZDA 487 487 select PINCTRL_PIC32 488 488 489 + config PINCTRL_PIC64GX 490 + bool "pic64gx gpio2 pinctrl driver" 491 + depends on ARCH_MICROCHIP || COMPILE_TEST 492 + select GENERIC_PINCONF 493 + default y 494 + help 495 + This selects the pinctrl driver for gpio2 on pic64gx. 496 + 489 497 config PINCTRL_PISTACHIO 490 498 bool "IMG Pistachio SoC pinctrl driver" 491 499 depends on OF && (MIPS || COMPILE_TEST)
+1
drivers/pinctrl/Makefile
··· 48 48 obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o 49 49 obj-$(CONFIG_PINCTRL_PEF2256) += pinctrl-pef2256.o 50 50 obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o 51 + obj-$(CONFIG_PINCTRL_PIC64GX) += pinctrl-pic64gx-gpio2.o 51 52 obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o 52 53 obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o 53 54 obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
+356
drivers/pinctrl/pinctrl-pic64gx-gpio2.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/bitfield.h> 4 + #include <linux/module.h> 5 + #include <linux/mfd/syscon.h> 6 + #include <linux/mod_devicetable.h> 7 + #include <linux/of.h> 8 + #include <linux/platform_device.h> 9 + #include <linux/regmap.h> 10 + #include <linux/seq_file.h> 11 + 12 + #include <linux/pinctrl/pinconf-generic.h> 13 + #include <linux/pinctrl/pinconf.h> 14 + #include <linux/pinctrl/pinctrl.h> 15 + #include <linux/pinctrl/pinmux.h> 16 + 17 + #include "pinctrl-utils.h" 18 + 19 + #define PIC64GX_PINMUX_REG 0x0 20 + 21 + static const struct regmap_config pic64gx_gpio2_regmap_config = { 22 + .reg_bits = 32, 23 + .reg_stride = 4, 24 + .val_bits = 32, 25 + .val_format_endian = REGMAP_ENDIAN_LITTLE, 26 + .max_register = 0x0, 27 + }; 28 + 29 + struct pic64gx_gpio2_pinctrl { 30 + struct pinctrl_dev *pctrl; 31 + struct device *dev; 32 + struct regmap *regmap; 33 + struct pinctrl_desc desc; 34 + }; 35 + 36 + struct pic64gx_gpio2_pin_group { 37 + const char *name; 38 + const unsigned int *pins; 39 + const unsigned int num_pins; 40 + u32 mask; 41 + u32 setting; 42 + }; 43 + 44 + struct pic64gx_gpio2_function { 45 + const char *name; 46 + const char * const *groups; 47 + const unsigned int num_groups; 48 + }; 49 + 50 + static const struct pinctrl_pin_desc pic64gx_gpio2_pins[] = { 51 + PINCTRL_PIN(0, "E14"), 52 + PINCTRL_PIN(1, "E15"), 53 + PINCTRL_PIN(2, "F16"), 54 + PINCTRL_PIN(3, "F17"), 55 + PINCTRL_PIN(4, "D19"), 56 + PINCTRL_PIN(5, "B18"), 57 + PINCTRL_PIN(6, "B10"), 58 + PINCTRL_PIN(7, "C14"), 59 + PINCTRL_PIN(8, "E18"), 60 + PINCTRL_PIN(9, "D18"), 61 + PINCTRL_PIN(10, "E19"), 62 + PINCTRL_PIN(11, "C7"), 63 + PINCTRL_PIN(12, "D6"), 64 + PINCTRL_PIN(13, "D7"), 65 + PINCTRL_PIN(14, "C9"), 66 + PINCTRL_PIN(15, "C10"), 67 + PINCTRL_PIN(16, "A5"), 68 + PINCTRL_PIN(17, "A6"), 69 + PINCTRL_PIN(18, "D8"), 70 + PINCTRL_PIN(19, "D9"), 71 + PINCTRL_PIN(20, "B8"), 72 + PINCTRL_PIN(21, "A8"), 73 + PINCTRL_PIN(22, "C12"), 74 + PINCTRL_PIN(23, "B12"), 75 + PINCTRL_PIN(24, "A11"), 76 + PINCTRL_PIN(25, "A10"), 77 + PINCTRL_PIN(26, "D11"), 78 + PINCTRL_PIN(27, "C11"), 79 + PINCTRL_PIN(28, "B9"), 80 + }; 81 + 82 + static const unsigned int pic64gx_gpio2_mdio0_pins[] = { 83 + 0, 1 84 + }; 85 + 86 + static const unsigned int pic64gx_gpio2_mdio1_pins[] = { 87 + 2, 3 88 + }; 89 + 90 + static const unsigned int pic64gx_gpio2_spi0_pins[] = { 91 + 4, 5, 10, 11 92 + }; 93 + 94 + static const unsigned int pic64gx_gpio2_can0_pins[] = { 95 + 6, 24, 28 96 + }; 97 + 98 + static const unsigned int pic64gx_gpio2_pcie_pins[] = { 99 + 7, 8, 9 100 + }; 101 + 102 + static const unsigned int pic64gx_gpio2_qspi_pins[] = { 103 + 12, 13, 14, 15, 16, 17 104 + }; 105 + 106 + static const unsigned int pic64gx_gpio2_uart3_pins[] = { 107 + 18, 19 108 + }; 109 + 110 + static const unsigned int pic64gx_gpio2_uart4_pins[] = { 111 + 20, 21 112 + }; 113 + 114 + static const unsigned int pic64gx_gpio2_can1_pins[] = { 115 + 22, 23, 25 116 + }; 117 + 118 + static const unsigned int pic64gx_gpio2_uart2_pins[] = { 119 + 26, 27 120 + }; 121 + 122 + #define PIC64GX_PINCTRL_GROUP(_name, _mask) { \ 123 + .name = "gpio_" #_name, \ 124 + .pins = pic64gx_gpio2_##_name##_pins, \ 125 + .num_pins = ARRAY_SIZE(pic64gx_gpio2_##_name##_pins), \ 126 + .mask = _mask, \ 127 + .setting = 0x0, \ 128 + }, { \ 129 + .name = #_name, \ 130 + .pins = pic64gx_gpio2_##_name##_pins, \ 131 + .num_pins = ARRAY_SIZE(pic64gx_gpio2_##_name##_pins), \ 132 + .mask = _mask, \ 133 + .setting = _mask, \ 134 + } 135 + 136 + static const struct pic64gx_gpio2_pin_group pic64gx_gpio2_pin_groups[] = { 137 + PIC64GX_PINCTRL_GROUP(mdio0, BIT(0) | BIT(1)), 138 + PIC64GX_PINCTRL_GROUP(mdio1, BIT(2) | BIT(3)), 139 + PIC64GX_PINCTRL_GROUP(spi0, BIT(4) | BIT(5) | BIT(10) | BIT(11)), 140 + PIC64GX_PINCTRL_GROUP(can0, BIT(6) | BIT(24) | BIT(28)), 141 + PIC64GX_PINCTRL_GROUP(pcie, BIT(7) | BIT(8) | BIT(9)), 142 + PIC64GX_PINCTRL_GROUP(qspi, GENMASK(17, 12)), 143 + PIC64GX_PINCTRL_GROUP(uart3, BIT(18) | BIT(19)), 144 + PIC64GX_PINCTRL_GROUP(uart4, BIT(20) | BIT(21)), 145 + PIC64GX_PINCTRL_GROUP(can1, BIT(22) | BIT(23) | BIT(25)), 146 + PIC64GX_PINCTRL_GROUP(uart2, BIT(26) | BIT(27)), 147 + }; 148 + 149 + static const char * const pic64gx_gpio2_gpio_groups[] = { 150 + "gpio_mdio0", "gpio_mdio1", "gpio_spi0", "gpio_can0", "gpio_pcie", 151 + "gpio_qspi", "gpio_uart3", "gpio_uart4", "gpio_can1", "gpio_uart2" 152 + }; 153 + 154 + static const char * const pic64gx_gpio2_mdio0_groups[] = { 155 + "mdio0" 156 + }; 157 + 158 + static const char * const pic64gx_gpio2_mdio1_groups[] = { 159 + "mdio1" 160 + }; 161 + 162 + static const char * const pic64gx_gpio2_spi0_groups[] = { 163 + "spi0" 164 + }; 165 + 166 + static const char * const pic64gx_gpio2_can0_groups[] = { 167 + "can0" 168 + }; 169 + 170 + static const char * const pic64gx_gpio2_pcie_groups[] = { 171 + "pcie" 172 + }; 173 + 174 + static const char * const pic64gx_gpio2_qspi_groups[] = { 175 + "qspi" 176 + }; 177 + 178 + static const char * const pic64gx_gpio2_uart3_groups[] = { 179 + "uart3" 180 + }; 181 + 182 + static const char * const pic64gx_gpio2_uart4_groups[] = { 183 + "uart4" 184 + }; 185 + 186 + static const char * const pic64gx_gpio2_can1_groups[] = { 187 + "can1" 188 + }; 189 + 190 + static const char * const pic64gx_gpio2_uart2_groups[] = { 191 + "uart2" 192 + }; 193 + 194 + #define PIC64GX_PINCTRL_FUNCTION(_name) { \ 195 + .name = #_name, \ 196 + .groups = pic64gx_gpio2_##_name##_groups, \ 197 + .num_groups = ARRAY_SIZE(pic64gx_gpio2_##_name##_groups), \ 198 + } 199 + 200 + static const struct pic64gx_gpio2_function pic64gx_gpio2_functions[] = { 201 + PIC64GX_PINCTRL_FUNCTION(gpio), 202 + PIC64GX_PINCTRL_FUNCTION(mdio0), 203 + PIC64GX_PINCTRL_FUNCTION(mdio1), 204 + PIC64GX_PINCTRL_FUNCTION(spi0), 205 + PIC64GX_PINCTRL_FUNCTION(can0), 206 + PIC64GX_PINCTRL_FUNCTION(pcie), 207 + PIC64GX_PINCTRL_FUNCTION(qspi), 208 + PIC64GX_PINCTRL_FUNCTION(uart3), 209 + PIC64GX_PINCTRL_FUNCTION(uart4), 210 + PIC64GX_PINCTRL_FUNCTION(can1), 211 + PIC64GX_PINCTRL_FUNCTION(uart2), 212 + }; 213 + 214 + static void pic64gx_gpio2_pin_dbg_show(struct pinctrl_dev *pctrl_dev, struct seq_file *seq, 215 + unsigned int pin) 216 + { 217 + struct pic64gx_gpio2_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); 218 + u32 val; 219 + 220 + regmap_read(pctrl->regmap, PIC64GX_PINMUX_REG, &val); 221 + val = (val & BIT(pin)) >> pin; 222 + seq_printf(seq, "pin: %u val: %x\n", pin, val); 223 + } 224 + 225 + static int pic64gx_gpio2_groups_count(struct pinctrl_dev *pctldev) 226 + { 227 + return ARRAY_SIZE(pic64gx_gpio2_pin_groups); 228 + } 229 + 230 + static const char *pic64gx_gpio2_group_name(struct pinctrl_dev *pctldev, unsigned int selector) 231 + { 232 + return pic64gx_gpio2_pin_groups[selector].name; 233 + } 234 + 235 + static int pic64gx_gpio2_group_pins(struct pinctrl_dev *pctldev, unsigned int selector, 236 + const unsigned int **pins, unsigned int *num_pins) 237 + { 238 + *pins = pic64gx_gpio2_pin_groups[selector].pins; 239 + *num_pins = pic64gx_gpio2_pin_groups[selector].num_pins; 240 + 241 + return 0; 242 + } 243 + 244 + static const struct pinctrl_ops pic64gx_gpio2_pinctrl_ops = { 245 + .get_groups_count = pic64gx_gpio2_groups_count, 246 + .get_group_name = pic64gx_gpio2_group_name, 247 + .get_group_pins = pic64gx_gpio2_group_pins, 248 + .dt_node_to_map = pinconf_generic_dt_node_to_map_all, 249 + .dt_free_map = pinctrl_utils_free_map, 250 + .pin_dbg_show = pic64gx_gpio2_pin_dbg_show, 251 + }; 252 + 253 + static int pic64gx_gpio2_pinmux_get_funcs_count(struct pinctrl_dev *pctldev) 254 + { 255 + return ARRAY_SIZE(pic64gx_gpio2_functions); 256 + } 257 + 258 + static const char *pic64gx_gpio2_pinmux_get_func_name(struct pinctrl_dev *pctldev, 259 + unsigned int selector) 260 + { 261 + return pic64gx_gpio2_functions[selector].name; 262 + } 263 + 264 + static int pic64gx_gpio2_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned int selector, 265 + const char * const **groups, 266 + unsigned int * const num_groups) 267 + { 268 + *groups = pic64gx_gpio2_functions[selector].groups; 269 + *num_groups = pic64gx_gpio2_functions[selector].num_groups; 270 + 271 + return 0; 272 + } 273 + 274 + static int pic64gx_gpio2_pinmux_set_mux(struct pinctrl_dev *pctrl_dev, unsigned int fsel, 275 + unsigned int gsel) 276 + { 277 + struct pic64gx_gpio2_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); 278 + struct device *dev = pctrl->dev; 279 + const struct pic64gx_gpio2_pin_group *group; 280 + const struct pic64gx_gpio2_function *function; 281 + 282 + group = &pic64gx_gpio2_pin_groups[gsel]; 283 + function = &pic64gx_gpio2_functions[fsel]; 284 + 285 + dev_dbg(dev, "Setting func %s mask %x setting %x\n", 286 + function->name, group->mask, group->setting); 287 + regmap_assign_bits(pctrl->regmap, PIC64GX_PINMUX_REG, group->mask, group->setting); 288 + 289 + return 0; 290 + } 291 + 292 + static const struct pinmux_ops pic64gx_gpio2_pinmux_ops = { 293 + .get_functions_count = pic64gx_gpio2_pinmux_get_funcs_count, 294 + .get_function_name = pic64gx_gpio2_pinmux_get_func_name, 295 + .get_function_groups = pic64gx_gpio2_pinmux_get_groups, 296 + .set_mux = pic64gx_gpio2_pinmux_set_mux, 297 + }; 298 + 299 + static int pic64gx_gpio2_probe(struct platform_device *pdev) 300 + { 301 + struct device *dev = &pdev->dev; 302 + struct pic64gx_gpio2_pinctrl *pctrl; 303 + void __iomem *base; 304 + 305 + pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); 306 + if (!pctrl) 307 + return -ENOMEM; 308 + 309 + base = devm_platform_ioremap_resource(pdev, 0); 310 + if (IS_ERR(base)) { 311 + dev_err(dev, "Failed get resource\n"); 312 + return PTR_ERR(base); 313 + } 314 + 315 + pctrl->regmap = devm_regmap_init_mmio(dev, base, &pic64gx_gpio2_regmap_config); 316 + if (IS_ERR(pctrl->regmap)) { 317 + dev_err(dev, "Failed to map regmap\n"); 318 + return PTR_ERR(pctrl->regmap); 319 + } 320 + 321 + pctrl->desc.name = dev_name(dev); 322 + pctrl->desc.pins = pic64gx_gpio2_pins; 323 + pctrl->desc.npins = ARRAY_SIZE(pic64gx_gpio2_pins); 324 + pctrl->desc.pctlops = &pic64gx_gpio2_pinctrl_ops; 325 + pctrl->desc.pmxops = &pic64gx_gpio2_pinmux_ops; 326 + pctrl->desc.owner = THIS_MODULE; 327 + 328 + pctrl->dev = dev; 329 + 330 + platform_set_drvdata(pdev, pctrl); 331 + 332 + pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &pctrl->desc, pctrl); 333 + if (IS_ERR(pctrl->pctrl)) 334 + return PTR_ERR(pctrl->pctrl); 335 + 336 + return 0; 337 + } 338 + 339 + static const struct of_device_id pic64gx_gpio2_of_match[] = { 340 + { .compatible = "microchip,pic64gx-pinctrl-gpio2" }, 341 + { } 342 + }; 343 + MODULE_DEVICE_TABLE(of, pic64gx_gpio2_of_match); 344 + 345 + static struct platform_driver pic64gx_gpio2_driver = { 346 + .driver = { 347 + .name = "pic64gx-pinctrl-gpio2", 348 + .of_match_table = pic64gx_gpio2_of_match, 349 + }, 350 + .probe = pic64gx_gpio2_probe, 351 + }; 352 + module_platform_driver(pic64gx_gpio2_driver); 353 + 354 + MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>"); 355 + MODULE_DESCRIPTION("pic64gx gpio2 pinctrl driver"); 356 + MODULE_LICENSE("GPL");