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

pinctrl: tangier: Introduce Intel Tangier driver

Intel Tangier implements the common pinctrl functionalities for
Merrifield and Moorefield platforms.

Signed-off-by: Raag Jadav <raag.jadav@intel.com>
Link: https://lore.kernel.org/r/20230814054033.12004-2-raag.jadav@intel.com
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

authored by

Raag Jadav and committed by
Andy Shevchenko
79433559 06c2afb8

+700
+1
drivers/pinctrl/intel/Kconfig
··· 187 187 This pinctrl driver provides an interface that allows configuring 188 188 of Intel Tiger Lake PCH pins and using them as GPIOs. 189 189 190 + source "drivers/pinctrl/intel/Kconfig.tng" 190 191 endmenu
+17
drivers/pinctrl/intel/Kconfig.tng
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # Intel Tangier and compatible pin control drivers 3 + 4 + if X86_INTEL_MID || COMPILE_TEST 5 + 6 + config PINCTRL_TANGIER 7 + tristate 8 + select PINMUX 9 + select PINCONF 10 + select GENERIC_PINCONF 11 + help 12 + This is a library driver for Intel Tangier pin controller and to 13 + be selected and used by respective compatible platform drivers. 14 + 15 + If built as a module its name will be pinctrl-tangier. 16 + 17 + endif
+1
drivers/pinctrl/intel/Makefile
··· 4 4 obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o 5 5 obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o 6 6 obj-$(CONFIG_PINCTRL_LYNXPOINT) += pinctrl-lynxpoint.o 7 + obj-$(CONFIG_PINCTRL_TANGIER) += pinctrl-tangier.o 7 8 obj-$(CONFIG_PINCTRL_MERRIFIELD) += pinctrl-merrifield.o 8 9 obj-$(CONFIG_PINCTRL_MOOREFIELD) += pinctrl-moorefield.o 9 10 obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o
+589
drivers/pinctrl/intel/pinctrl-tangier.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Intel Tangier pinctrl driver 4 + * 5 + * Copyright (C) 2016, 2023 Intel Corporation 6 + * 7 + * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 8 + * Raag Jadav <raag.jadav@intel.com> 9 + */ 10 + 11 + #include <linux/bits.h> 12 + #include <linux/device.h> 13 + #include <linux/err.h> 14 + #include <linux/errno.h> 15 + #include <linux/export.h> 16 + #include <linux/io.h> 17 + #include <linux/module.h> 18 + #include <linux/overflow.h> 19 + #include <linux/platform_device.h> 20 + #include <linux/property.h> 21 + #include <linux/seq_file.h> 22 + #include <linux/spinlock.h> 23 + #include <linux/types.h> 24 + 25 + #include <linux/pinctrl/pinconf-generic.h> 26 + #include <linux/pinctrl/pinconf.h> 27 + #include <linux/pinctrl/pinctrl.h> 28 + #include <linux/pinctrl/pinmux.h> 29 + 30 + #include "../core.h" 31 + #include "pinctrl-intel.h" 32 + #include "pinctrl-tangier.h" 33 + 34 + #define SLEW_OFFSET 0x000 35 + #define BUFCFG_OFFSET 0x100 36 + #define MISC_OFFSET 0x300 37 + 38 + #define BUFCFG_PINMODE_SHIFT 0 39 + #define BUFCFG_PINMODE_MASK GENMASK(2, 0) 40 + #define BUFCFG_PINMODE_GPIO 0 41 + #define BUFCFG_PUPD_VAL_SHIFT 4 42 + #define BUFCFG_PUPD_VAL_MASK GENMASK(5, 4) 43 + #define BUFCFG_PUPD_VAL_2K 0 44 + #define BUFCFG_PUPD_VAL_20K 1 45 + #define BUFCFG_PUPD_VAL_50K 2 46 + #define BUFCFG_PUPD_VAL_910 3 47 + #define BUFCFG_PU_EN BIT(8) 48 + #define BUFCFG_PD_EN BIT(9) 49 + #define BUFCFG_Px_EN_MASK GENMASK(9, 8) 50 + #define BUFCFG_SLEWSEL BIT(10) 51 + #define BUFCFG_OVINEN BIT(12) 52 + #define BUFCFG_OVINEN_EN BIT(13) 53 + #define BUFCFG_OVINEN_MASK GENMASK(13, 12) 54 + #define BUFCFG_OVOUTEN BIT(14) 55 + #define BUFCFG_OVOUTEN_EN BIT(15) 56 + #define BUFCFG_OVOUTEN_MASK GENMASK(15, 14) 57 + #define BUFCFG_INDATAOV_VAL BIT(16) 58 + #define BUFCFG_INDATAOV_EN BIT(17) 59 + #define BUFCFG_INDATAOV_MASK GENMASK(17, 16) 60 + #define BUFCFG_OUTDATAOV_VAL BIT(18) 61 + #define BUFCFG_OUTDATAOV_EN BIT(19) 62 + #define BUFCFG_OUTDATAOV_MASK GENMASK(19, 18) 63 + #define BUFCFG_OD_EN BIT(21) 64 + 65 + #define pin_to_bufno(f, p) ((p) - (f)->pin_base) 66 + 67 + static const struct tng_family *tng_get_family(struct tng_pinctrl *tp, 68 + unsigned int pin) 69 + { 70 + const struct tng_family *family; 71 + unsigned int i; 72 + 73 + for (i = 0; i < tp->nfamilies; i++) { 74 + family = &tp->families[i]; 75 + if (pin >= family->pin_base && 76 + pin < family->pin_base + family->npins) 77 + return family; 78 + } 79 + 80 + dev_warn(tp->dev, "failed to find family for pin %u\n", pin); 81 + return NULL; 82 + } 83 + 84 + static bool tng_buf_available(struct tng_pinctrl *tp, unsigned int pin) 85 + { 86 + const struct tng_family *family; 87 + 88 + family = tng_get_family(tp, pin); 89 + if (!family) 90 + return false; 91 + 92 + return !family->protected; 93 + } 94 + 95 + static void __iomem *tng_get_bufcfg(struct tng_pinctrl *tp, unsigned int pin) 96 + { 97 + const struct tng_family *family; 98 + unsigned int bufno; 99 + 100 + family = tng_get_family(tp, pin); 101 + if (!family) 102 + return NULL; 103 + 104 + bufno = pin_to_bufno(family, pin); 105 + return family->regs + BUFCFG_OFFSET + bufno * 4; 106 + } 107 + 108 + static int tng_read_bufcfg(struct tng_pinctrl *tp, unsigned int pin, u32 *value) 109 + { 110 + void __iomem *bufcfg; 111 + 112 + if (!tng_buf_available(tp, pin)) 113 + return -EBUSY; 114 + 115 + bufcfg = tng_get_bufcfg(tp, pin); 116 + *value = readl(bufcfg); 117 + 118 + return 0; 119 + } 120 + 121 + static void tng_update_bufcfg(struct tng_pinctrl *tp, unsigned int pin, 122 + u32 bits, u32 mask) 123 + { 124 + void __iomem *bufcfg; 125 + u32 value; 126 + 127 + bufcfg = tng_get_bufcfg(tp, pin); 128 + 129 + value = readl(bufcfg); 130 + value = (value & ~mask) | (bits & mask); 131 + writel(value, bufcfg); 132 + } 133 + 134 + static int tng_get_groups_count(struct pinctrl_dev *pctldev) 135 + { 136 + struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev); 137 + 138 + return tp->ngroups; 139 + } 140 + 141 + static const char *tng_get_group_name(struct pinctrl_dev *pctldev, 142 + unsigned int group) 143 + { 144 + struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev); 145 + 146 + return tp->groups[group].grp.name; 147 + } 148 + 149 + static int tng_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, 150 + const unsigned int **pins, unsigned int *npins) 151 + { 152 + struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev); 153 + 154 + *pins = tp->groups[group].grp.pins; 155 + *npins = tp->groups[group].grp.npins; 156 + return 0; 157 + } 158 + 159 + static void tng_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, 160 + unsigned int pin) 161 + { 162 + struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev); 163 + u32 value, mode; 164 + int ret; 165 + 166 + ret = tng_read_bufcfg(tp, pin, &value); 167 + if (ret) { 168 + seq_puts(s, "not available"); 169 + return; 170 + } 171 + 172 + mode = (value & BUFCFG_PINMODE_MASK) >> BUFCFG_PINMODE_SHIFT; 173 + if (mode == BUFCFG_PINMODE_GPIO) 174 + seq_puts(s, "GPIO "); 175 + else 176 + seq_printf(s, "mode %d ", mode); 177 + 178 + seq_printf(s, "0x%08x", value); 179 + } 180 + 181 + static const struct pinctrl_ops tng_pinctrl_ops = { 182 + .get_groups_count = tng_get_groups_count, 183 + .get_group_name = tng_get_group_name, 184 + .get_group_pins = tng_get_group_pins, 185 + .pin_dbg_show = tng_pin_dbg_show, 186 + }; 187 + 188 + static int tng_get_functions_count(struct pinctrl_dev *pctldev) 189 + { 190 + struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev); 191 + 192 + return tp->nfunctions; 193 + } 194 + 195 + static const char *tng_get_function_name(struct pinctrl_dev *pctldev, 196 + unsigned int function) 197 + { 198 + struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev); 199 + 200 + return tp->functions[function].func.name; 201 + } 202 + 203 + static int tng_get_function_groups(struct pinctrl_dev *pctldev, 204 + unsigned int function, 205 + const char * const **groups, 206 + unsigned int * const ngroups) 207 + { 208 + struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev); 209 + 210 + *groups = tp->functions[function].func.groups; 211 + *ngroups = tp->functions[function].func.ngroups; 212 + return 0; 213 + } 214 + 215 + static int tng_pinmux_set_mux(struct pinctrl_dev *pctldev, 216 + unsigned int function, 217 + unsigned int group) 218 + { 219 + struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev); 220 + const struct intel_pingroup *grp = &tp->groups[group]; 221 + u32 bits = grp->mode << BUFCFG_PINMODE_SHIFT; 222 + u32 mask = BUFCFG_PINMODE_MASK; 223 + unsigned long flags; 224 + unsigned int i; 225 + 226 + /* 227 + * All pins in the groups needs to be accessible and writable 228 + * before we can enable the mux for this group. 229 + */ 230 + for (i = 0; i < grp->grp.npins; i++) { 231 + if (!tng_buf_available(tp, grp->grp.pins[i])) 232 + return -EBUSY; 233 + } 234 + 235 + /* Now enable the mux setting for each pin in the group */ 236 + raw_spin_lock_irqsave(&tp->lock, flags); 237 + for (i = 0; i < grp->grp.npins; i++) 238 + tng_update_bufcfg(tp, grp->grp.pins[i], bits, mask); 239 + raw_spin_unlock_irqrestore(&tp->lock, flags); 240 + 241 + return 0; 242 + } 243 + 244 + static int tng_gpio_request_enable(struct pinctrl_dev *pctldev, 245 + struct pinctrl_gpio_range *range, 246 + unsigned int pin) 247 + { 248 + struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev); 249 + u32 bits = BUFCFG_PINMODE_GPIO << BUFCFG_PINMODE_SHIFT; 250 + u32 mask = BUFCFG_PINMODE_MASK; 251 + unsigned long flags; 252 + 253 + if (!tng_buf_available(tp, pin)) 254 + return -EBUSY; 255 + 256 + raw_spin_lock_irqsave(&tp->lock, flags); 257 + tng_update_bufcfg(tp, pin, bits, mask); 258 + raw_spin_unlock_irqrestore(&tp->lock, flags); 259 + 260 + return 0; 261 + } 262 + 263 + static const struct pinmux_ops tng_pinmux_ops = { 264 + .get_functions_count = tng_get_functions_count, 265 + .get_function_name = tng_get_function_name, 266 + .get_function_groups = tng_get_function_groups, 267 + .set_mux = tng_pinmux_set_mux, 268 + .gpio_request_enable = tng_gpio_request_enable, 269 + }; 270 + 271 + static int tng_config_get(struct pinctrl_dev *pctldev, unsigned int pin, 272 + unsigned long *config) 273 + { 274 + struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev); 275 + enum pin_config_param param = pinconf_to_config_param(*config); 276 + u32 value, term; 277 + u16 arg = 0; 278 + int ret; 279 + 280 + ret = tng_read_bufcfg(tp, pin, &value); 281 + if (ret) 282 + return -ENOTSUPP; 283 + 284 + term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT; 285 + 286 + switch (param) { 287 + case PIN_CONFIG_BIAS_DISABLE: 288 + if (value & BUFCFG_Px_EN_MASK) 289 + return -EINVAL; 290 + break; 291 + 292 + case PIN_CONFIG_BIAS_PULL_UP: 293 + if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PU_EN) 294 + return -EINVAL; 295 + 296 + switch (term) { 297 + case BUFCFG_PUPD_VAL_910: 298 + arg = 910; 299 + break; 300 + case BUFCFG_PUPD_VAL_2K: 301 + arg = 2000; 302 + break; 303 + case BUFCFG_PUPD_VAL_20K: 304 + arg = 20000; 305 + break; 306 + case BUFCFG_PUPD_VAL_50K: 307 + arg = 50000; 308 + break; 309 + } 310 + 311 + break; 312 + 313 + case PIN_CONFIG_BIAS_PULL_DOWN: 314 + if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PD_EN) 315 + return -EINVAL; 316 + 317 + switch (term) { 318 + case BUFCFG_PUPD_VAL_910: 319 + arg = 910; 320 + break; 321 + case BUFCFG_PUPD_VAL_2K: 322 + arg = 2000; 323 + break; 324 + case BUFCFG_PUPD_VAL_20K: 325 + arg = 20000; 326 + break; 327 + case BUFCFG_PUPD_VAL_50K: 328 + arg = 50000; 329 + break; 330 + } 331 + 332 + break; 333 + 334 + case PIN_CONFIG_DRIVE_PUSH_PULL: 335 + if (value & BUFCFG_OD_EN) 336 + return -EINVAL; 337 + break; 338 + 339 + case PIN_CONFIG_DRIVE_OPEN_DRAIN: 340 + if (!(value & BUFCFG_OD_EN)) 341 + return -EINVAL; 342 + break; 343 + 344 + case PIN_CONFIG_SLEW_RATE: 345 + if (value & BUFCFG_SLEWSEL) 346 + arg = 1; 347 + break; 348 + 349 + default: 350 + return -ENOTSUPP; 351 + } 352 + 353 + *config = pinconf_to_config_packed(param, arg); 354 + return 0; 355 + } 356 + 357 + static int tng_config_set_pin(struct tng_pinctrl *tp, unsigned int pin, 358 + unsigned long config) 359 + { 360 + unsigned int param = pinconf_to_config_param(config); 361 + unsigned int arg = pinconf_to_config_argument(config); 362 + u32 mask, term, value = 0; 363 + unsigned long flags; 364 + 365 + switch (param) { 366 + case PIN_CONFIG_BIAS_DISABLE: 367 + mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; 368 + break; 369 + 370 + case PIN_CONFIG_BIAS_PULL_UP: 371 + /* Set default strength value in case none is given */ 372 + if (arg == 1) 373 + arg = 20000; 374 + 375 + switch (arg) { 376 + case 50000: 377 + term = BUFCFG_PUPD_VAL_50K; 378 + break; 379 + case 20000: 380 + term = BUFCFG_PUPD_VAL_20K; 381 + break; 382 + case 2000: 383 + term = BUFCFG_PUPD_VAL_2K; 384 + break; 385 + default: 386 + return -EINVAL; 387 + } 388 + 389 + mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; 390 + value = BUFCFG_PU_EN | (term << BUFCFG_PUPD_VAL_SHIFT); 391 + break; 392 + 393 + case PIN_CONFIG_BIAS_PULL_DOWN: 394 + /* Set default strength value in case none is given */ 395 + if (arg == 1) 396 + arg = 20000; 397 + 398 + switch (arg) { 399 + case 50000: 400 + term = BUFCFG_PUPD_VAL_50K; 401 + break; 402 + case 20000: 403 + term = BUFCFG_PUPD_VAL_20K; 404 + break; 405 + case 2000: 406 + term = BUFCFG_PUPD_VAL_2K; 407 + break; 408 + default: 409 + return -EINVAL; 410 + } 411 + 412 + mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; 413 + value = BUFCFG_PD_EN | (term << BUFCFG_PUPD_VAL_SHIFT); 414 + break; 415 + 416 + case PIN_CONFIG_DRIVE_PUSH_PULL: 417 + mask = BUFCFG_OD_EN; 418 + break; 419 + 420 + case PIN_CONFIG_DRIVE_OPEN_DRAIN: 421 + mask = BUFCFG_OD_EN; 422 + value = BUFCFG_OD_EN; 423 + break; 424 + 425 + case PIN_CONFIG_SLEW_RATE: 426 + mask = BUFCFG_SLEWSEL; 427 + if (arg) 428 + value = BUFCFG_SLEWSEL; 429 + break; 430 + 431 + default: 432 + return -EINVAL; 433 + } 434 + 435 + raw_spin_lock_irqsave(&tp->lock, flags); 436 + tng_update_bufcfg(tp, pin, value, mask); 437 + raw_spin_unlock_irqrestore(&tp->lock, flags); 438 + 439 + return 0; 440 + } 441 + 442 + static int tng_config_set(struct pinctrl_dev *pctldev, unsigned int pin, 443 + unsigned long *configs, unsigned int nconfigs) 444 + { 445 + struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev); 446 + unsigned int i; 447 + int ret; 448 + 449 + if (!tng_buf_available(tp, pin)) 450 + return -ENOTSUPP; 451 + 452 + for (i = 0; i < nconfigs; i++) { 453 + switch (pinconf_to_config_param(configs[i])) { 454 + case PIN_CONFIG_BIAS_DISABLE: 455 + case PIN_CONFIG_BIAS_PULL_UP: 456 + case PIN_CONFIG_BIAS_PULL_DOWN: 457 + case PIN_CONFIG_DRIVE_PUSH_PULL: 458 + case PIN_CONFIG_DRIVE_OPEN_DRAIN: 459 + case PIN_CONFIG_SLEW_RATE: 460 + ret = tng_config_set_pin(tp, pin, configs[i]); 461 + if (ret) 462 + return ret; 463 + break; 464 + 465 + default: 466 + return -ENOTSUPP; 467 + } 468 + } 469 + 470 + return 0; 471 + } 472 + 473 + static int tng_config_group_get(struct pinctrl_dev *pctldev, 474 + unsigned int group, unsigned long *config) 475 + { 476 + const unsigned int *pins; 477 + unsigned int npins; 478 + int ret; 479 + 480 + ret = tng_get_group_pins(pctldev, group, &pins, &npins); 481 + if (ret) 482 + return ret; 483 + 484 + return tng_config_get(pctldev, pins[0], config); 485 + } 486 + 487 + static int tng_config_group_set(struct pinctrl_dev *pctldev, 488 + unsigned int group, unsigned long *configs, 489 + unsigned int num_configs) 490 + { 491 + const unsigned int *pins; 492 + unsigned int npins; 493 + int i, ret; 494 + 495 + ret = tng_get_group_pins(pctldev, group, &pins, &npins); 496 + if (ret) 497 + return ret; 498 + 499 + for (i = 0; i < npins; i++) { 500 + ret = tng_config_set(pctldev, pins[i], configs, num_configs); 501 + if (ret) 502 + return ret; 503 + } 504 + 505 + return 0; 506 + } 507 + 508 + static const struct pinconf_ops tng_pinconf_ops = { 509 + .is_generic = true, 510 + .pin_config_get = tng_config_get, 511 + .pin_config_set = tng_config_set, 512 + .pin_config_group_get = tng_config_group_get, 513 + .pin_config_group_set = tng_config_group_set, 514 + }; 515 + 516 + static const struct pinctrl_desc tng_pinctrl_desc = { 517 + .pctlops = &tng_pinctrl_ops, 518 + .pmxops = &tng_pinmux_ops, 519 + .confops = &tng_pinconf_ops, 520 + .owner = THIS_MODULE, 521 + }; 522 + 523 + static int tng_pinctrl_probe(struct platform_device *pdev, 524 + const struct tng_pinctrl *data) 525 + { 526 + struct device *dev = &pdev->dev; 527 + struct tng_family *families; 528 + struct tng_pinctrl *tp; 529 + size_t families_len; 530 + void __iomem *regs; 531 + unsigned int i; 532 + 533 + tp = devm_kmemdup(dev, data, sizeof(*data), GFP_KERNEL); 534 + if (!tp) 535 + return -ENOMEM; 536 + 537 + tp->dev = dev; 538 + raw_spin_lock_init(&tp->lock); 539 + 540 + regs = devm_platform_ioremap_resource(pdev, 0); 541 + if (IS_ERR(regs)) 542 + return PTR_ERR(regs); 543 + 544 + /* 545 + * Make a copy of the families which we can use to hold pointers 546 + * to the registers. 547 + */ 548 + families_len = size_mul(sizeof(*families), tp->nfamilies); 549 + families = devm_kmemdup(dev, tp->families, families_len, GFP_KERNEL); 550 + if (!families) 551 + return -ENOMEM; 552 + 553 + /* Splice memory resource by chunk per family */ 554 + for (i = 0; i < tp->nfamilies; i++) { 555 + struct tng_family *family = &families[i]; 556 + 557 + family->regs = regs + family->barno * TNG_FAMILY_LEN; 558 + } 559 + 560 + tp->families = families; 561 + tp->pctldesc = tng_pinctrl_desc; 562 + tp->pctldesc.name = dev_name(dev); 563 + tp->pctldesc.pins = tp->pins; 564 + tp->pctldesc.npins = tp->npins; 565 + 566 + tp->pctldev = devm_pinctrl_register(dev, &tp->pctldesc, tp); 567 + if (IS_ERR(tp->pctldev)) 568 + return dev_err_probe(dev, PTR_ERR(tp->pctldev), 569 + "failed to register pinctrl driver\n"); 570 + 571 + return 0; 572 + } 573 + 574 + int devm_tng_pinctrl_probe(struct platform_device *pdev) 575 + { 576 + const struct tng_pinctrl *data; 577 + 578 + data = device_get_match_data(&pdev->dev); 579 + if (!data) 580 + return -ENODATA; 581 + 582 + return tng_pinctrl_probe(pdev, data); 583 + } 584 + EXPORT_SYMBOL_NS_GPL(devm_tng_pinctrl_probe, PINCTRL_TANGIER); 585 + 586 + MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); 587 + MODULE_AUTHOR("Raag Jadav <raag.jadav@intel.com>"); 588 + MODULE_DESCRIPTION("Intel Tangier pinctrl driver"); 589 + MODULE_LICENSE("GPL");
+92
drivers/pinctrl/intel/pinctrl-tangier.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Intel Tangier pinctrl functions 4 + * 5 + * Copyright (C) 2016, 2023 Intel Corporation 6 + * 7 + * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 8 + * Raag Jadav <raag.jadav@intel.com> 9 + */ 10 + 11 + #ifndef PINCTRL_TANGIER_H 12 + #define PINCTRL_TANGIER_H 13 + 14 + #include <linux/spinlock_types.h> 15 + #include <linux/types.h> 16 + 17 + #include <linux/pinctrl/pinctrl.h> 18 + 19 + #include "pinctrl-intel.h" 20 + 21 + struct device; 22 + struct platform_device; 23 + 24 + #define TNG_FAMILY_NR 64 25 + #define TNG_FAMILY_LEN 0x400 26 + 27 + /** 28 + * struct tng_family - Tangier pin family description 29 + * @barno: MMIO BAR number where registers for this family reside 30 + * @pin_base: Starting pin of pins in this family 31 + * @npins: Number of pins in this family 32 + * @protected: True if family is protected by access 33 + * @regs: Family specific common registers 34 + */ 35 + struct tng_family { 36 + unsigned int barno; 37 + unsigned int pin_base; 38 + size_t npins; 39 + bool protected; 40 + void __iomem *regs; 41 + }; 42 + 43 + #define TNG_FAMILY(b, s, e) \ 44 + { \ 45 + .barno = (b), \ 46 + .pin_base = (s), \ 47 + .npins = (e) - (s) + 1, \ 48 + } 49 + 50 + #define TNG_FAMILY_PROTECTED(b, s, e) \ 51 + { \ 52 + .barno = (b), \ 53 + .pin_base = (s), \ 54 + .npins = (e) - (s) + 1, \ 55 + .protected = true, \ 56 + } 57 + 58 + /** 59 + * struct tng_pinctrl - Tangier pinctrl private structure 60 + * @dev: Pointer to the device structure 61 + * @lock: Lock to serialize register access 62 + * @pctldesc: Pin controller description 63 + * @pctldev: Pointer to the pin controller device 64 + * @families: Array of families this pinctrl handles 65 + * @nfamilies: Number of families in the array 66 + * @functions: Array of functions 67 + * @nfunctions: Number of functions in the array 68 + * @groups: Array of pin groups 69 + * @ngroups: Number of groups in the array 70 + * @pins: Array of pins this pinctrl controls 71 + * @npins: Number of pins in the array 72 + */ 73 + struct tng_pinctrl { 74 + struct device *dev; 75 + raw_spinlock_t lock; 76 + struct pinctrl_desc pctldesc; 77 + struct pinctrl_dev *pctldev; 78 + 79 + /* Pin controller configuration */ 80 + const struct tng_family *families; 81 + size_t nfamilies; 82 + const struct intel_function *functions; 83 + size_t nfunctions; 84 + const struct intel_pingroup *groups; 85 + size_t ngroups; 86 + const struct pinctrl_pin_desc *pins; 87 + size_t npins; 88 + }; 89 + 90 + int devm_tng_pinctrl_probe(struct platform_device *pdev); 91 + 92 + #endif /* PINCTRL_TANGIER_H */