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"); 357