Lines Matching +full:pin +full:- +full:val
1 // SPDX-License-Identifier: GPL-2.0+
8 * pinctrl-nomadik.c, please see original file for copyright information
9 * pinctrl-tegra.c, please see original file for copyright information
32 #include <linux/pinctrl/pinconf-generic.h>
39 #include <dt-bindings/pinctrl/bcm2835.h>
41 #define MODULE_NAME "pinctrl-bcm2835"
49 #define GPSET0 0x1c /* Pin Output Set */
50 #define GPCLR0 0x28 /* Pin Output Clear */
51 #define GPLEV0 0x34 /* Pin Level */
52 #define GPEDS0 0x40 /* Pin Event Detect Status */
53 #define GPREN0 0x4c /* Pin Rising Edge Detect Enable */
54 #define GPFEN0 0x58 /* Pin Falling Edge Detect Enable */
55 #define GPHEN0 0x64 /* Pin High Detect Enable */
56 #define GPLEN0 0x70 /* Pin Low Detect Enable */
57 #define GPAREN0 0x7c /* Pin Async Rising Edge Detect */
58 #define GPAFEN0 0x88 /* Pin Async Falling Edge Detect */
59 #define GPPUD 0x94 /* Pin Pull-up/down Enable */
60 #define GPPUDCLK0 0x98 /* Pin Pull-up/down Enable Clock */
61 #define GP_GPIO_PUP_PDN_CNTRL_REG0 0xe4 /* 2711 Pin Pull-up/down select */
161 /* one pin per group */
241 [IRQ_TYPE_EDGE_RISING] = "edge-rising",
242 [IRQ_TYPE_EDGE_FALLING] = "edge-falling",
243 [IRQ_TYPE_EDGE_BOTH] = "edge-both",
244 [IRQ_TYPE_LEVEL_HIGH] = "level-high",
245 [IRQ_TYPE_LEVEL_LOW] = "level-low",
250 MODULE_PARM_DESC(persist_gpio_outputs, "Enable GPIO_OUT persistence when pin is freed");
254 return readl(pc->base + reg); in bcm2835_gpio_rd()
258 u32 val) in bcm2835_gpio_wr() argument
260 writel(val, pc->base + reg); in bcm2835_gpio_wr()
279 struct bcm2835_pinctrl *pc, unsigned pin) in bcm2835_pinctrl_fsel_get() argument
281 u32 val = bcm2835_gpio_rd(pc, FSEL_REG(pin)); in bcm2835_pinctrl_fsel_get() local
282 enum bcm2835_fsel status = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK; in bcm2835_pinctrl_fsel_get()
284 dev_dbg(pc->dev, "get %08x (%u => %s)\n", val, pin, in bcm2835_pinctrl_fsel_get()
291 struct bcm2835_pinctrl *pc, unsigned pin, in bcm2835_pinctrl_fsel_set() argument
294 u32 val; in bcm2835_pinctrl_fsel_set() local
298 spin_lock_irqsave(&pc->fsel_lock, flags); in bcm2835_pinctrl_fsel_set()
299 val = bcm2835_gpio_rd(pc, FSEL_REG(pin)); in bcm2835_pinctrl_fsel_set()
300 cur = (val >> FSEL_SHIFT(pin)) & BCM2835_FSEL_MASK; in bcm2835_pinctrl_fsel_set()
302 dev_dbg(pc->dev, "read %08x (%u => %s)\n", val, pin, in bcm2835_pinctrl_fsel_set()
310 val &= ~(BCM2835_FSEL_MASK << FSEL_SHIFT(pin)); in bcm2835_pinctrl_fsel_set()
311 val |= BCM2835_FSEL_GPIO_IN << FSEL_SHIFT(pin); in bcm2835_pinctrl_fsel_set()
313 dev_dbg(pc->dev, "trans %08x (%u <= %s)\n", val, pin, in bcm2835_pinctrl_fsel_set()
315 bcm2835_gpio_wr(pc, FSEL_REG(pin), val); in bcm2835_pinctrl_fsel_set()
318 val &= ~(BCM2835_FSEL_MASK << FSEL_SHIFT(pin)); in bcm2835_pinctrl_fsel_set()
319 val |= fsel << FSEL_SHIFT(pin); in bcm2835_pinctrl_fsel_set()
321 dev_dbg(pc->dev, "write %08x (%u <= %s)\n", val, pin, in bcm2835_pinctrl_fsel_set()
323 bcm2835_gpio_wr(pc, FSEL_REG(pin), val); in bcm2835_pinctrl_fsel_set()
326 spin_unlock_irqrestore(&pc->fsel_lock, flags); in bcm2835_pinctrl_fsel_set()
381 struct device_node *np = dev_of_node(gc->parent); in bcm2835_add_pin_ranges_fallback()
388 gc->ngpio); in bcm2835_add_pin_ranges_fallback()
402 .base = -1,
409 .label = "pinctrl-bcm2711",
419 .base = -1,
434 events &= pc->enabled_irq_map[bank]; in bcm2835_gpio_irq_handle_bank()
437 generic_handle_domain_irq(pc->gpio_chip.irq.domain, in bcm2835_gpio_irq_handle_bank()
452 if (chip->irq.parents[i] == irq) { in bcm2835_gpio_irq_handler()
463 case 0: /* IRQ0 covers GPIOs 0-27 */ in bcm2835_gpio_irq_handler()
466 case 1: /* IRQ1 covers GPIOs 28-45 */ in bcm2835_gpio_irq_handler()
470 case 2: /* IRQ2 covers GPIOs 46-57 */ in bcm2835_gpio_irq_handler()
500 switch (pc->irq_type[offset]) { in bcm2835_gpio_irq_config()
535 raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); in bcm2835_gpio_irq_unmask()
536 set_bit(offset, &pc->enabled_irq_map[bank]); in bcm2835_gpio_irq_unmask()
538 raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); in bcm2835_gpio_irq_unmask()
550 raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); in bcm2835_gpio_irq_mask()
554 clear_bit(offset, &pc->enabled_irq_map[bank]); in bcm2835_gpio_irq_mask()
555 raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); in bcm2835_gpio_irq_mask()
570 pc->irq_type[offset] = type; in __bcm2835_gpio_irq_set_type_disabled()
574 return -EINVAL; in __bcm2835_gpio_irq_set_type_disabled()
585 if (pc->irq_type[offset] != type) { in __bcm2835_gpio_irq_set_type_enabled()
587 pc->irq_type[offset] = type; in __bcm2835_gpio_irq_set_type_enabled()
592 if (pc->irq_type[offset] == IRQ_TYPE_EDGE_BOTH) { in __bcm2835_gpio_irq_set_type_enabled()
594 pc->irq_type[offset] = IRQ_TYPE_EDGE_FALLING; in __bcm2835_gpio_irq_set_type_enabled()
596 pc->irq_type[offset] = type; in __bcm2835_gpio_irq_set_type_enabled()
597 } else if (pc->irq_type[offset] != type) { in __bcm2835_gpio_irq_set_type_enabled()
599 pc->irq_type[offset] = type; in __bcm2835_gpio_irq_set_type_enabled()
605 if (pc->irq_type[offset] == IRQ_TYPE_EDGE_BOTH) { in __bcm2835_gpio_irq_set_type_enabled()
607 pc->irq_type[offset] = IRQ_TYPE_EDGE_RISING; in __bcm2835_gpio_irq_set_type_enabled()
609 pc->irq_type[offset] = type; in __bcm2835_gpio_irq_set_type_enabled()
610 } else if (pc->irq_type[offset] != type) { in __bcm2835_gpio_irq_set_type_enabled()
612 pc->irq_type[offset] = type; in __bcm2835_gpio_irq_set_type_enabled()
618 if (pc->irq_type[offset] == IRQ_TYPE_EDGE_RISING) { in __bcm2835_gpio_irq_set_type_enabled()
620 pc->irq_type[offset] = IRQ_TYPE_EDGE_FALLING; in __bcm2835_gpio_irq_set_type_enabled()
622 pc->irq_type[offset] = type; in __bcm2835_gpio_irq_set_type_enabled()
623 } else if (pc->irq_type[offset] == IRQ_TYPE_EDGE_FALLING) { in __bcm2835_gpio_irq_set_type_enabled()
625 pc->irq_type[offset] = IRQ_TYPE_EDGE_RISING; in __bcm2835_gpio_irq_set_type_enabled()
627 pc->irq_type[offset] = type; in __bcm2835_gpio_irq_set_type_enabled()
628 } else if (pc->irq_type[offset] != type) { in __bcm2835_gpio_irq_set_type_enabled()
630 pc->irq_type[offset] = type; in __bcm2835_gpio_irq_set_type_enabled()
637 if (pc->irq_type[offset] != type) { in __bcm2835_gpio_irq_set_type_enabled()
639 pc->irq_type[offset] = type; in __bcm2835_gpio_irq_set_type_enabled()
645 return -EINVAL; in __bcm2835_gpio_irq_set_type_enabled()
660 raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); in bcm2835_gpio_irq_set_type()
662 if (test_bit(offset, &pc->enabled_irq_map[bank])) in bcm2835_gpio_irq_set_type()
672 raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); in bcm2835_gpio_irq_set_type()
692 int ret = -EINVAL; in bcm2835_gpio_irq_set_wake()
694 if (!pc->wake_irq) in bcm2835_gpio_irq_set_wake()
707 ret = enable_irq_wake(pc->wake_irq[irqgroup]); in bcm2835_gpio_irq_set_wake()
709 ret = disable_irq_wake(pc->wake_irq[irqgroup]); in bcm2835_gpio_irq_set_wake()
752 struct gpio_chip *chip = &pc->gpio_chip; in bcm2835_pctl_pin_dbg_show()
756 int irq = irq_find_mapping(chip->irq.domain, offset); in bcm2835_pctl_pin_dbg_show()
760 irq, irq_type_names[pc->irq_type[offset]]); in bcm2835_pctl_pin_dbg_show()
776 struct device_node *np, u32 pin, u32 fnum, in bcm2835_pctl_dt_node_to_map_func() argument
782 dev_err(pc->dev, "%pOF: invalid brcm,function %d\n", np, fnum); in bcm2835_pctl_dt_node_to_map_func()
783 return -EINVAL; in bcm2835_pctl_dt_node_to_map_func()
786 map->type = PIN_MAP_TYPE_MUX_GROUP; in bcm2835_pctl_dt_node_to_map_func()
787 map->data.mux.group = bcm2835_gpio_groups[pin]; in bcm2835_pctl_dt_node_to_map_func()
788 map->data.mux.function = bcm2835_functions[fnum]; in bcm2835_pctl_dt_node_to_map_func()
795 struct device_node *np, u32 pin, u32 pull, in bcm2835_pctl_dt_node_to_map_pull() argument
802 dev_err(pc->dev, "%pOF: invalid brcm,pull %d\n", np, pull); in bcm2835_pctl_dt_node_to_map_pull()
803 return -EINVAL; in bcm2835_pctl_dt_node_to_map_pull()
808 return -ENOMEM; in bcm2835_pctl_dt_node_to_map_pull()
811 map->type = PIN_MAP_TYPE_CONFIGS_PIN; in bcm2835_pctl_dt_node_to_map_pull()
812 map->data.configs.group_or_pin = bcm2835_gpio_pins[pin].name; in bcm2835_pctl_dt_node_to_map_pull()
813 map->data.configs.configs = configs; in bcm2835_pctl_dt_node_to_map_pull()
814 map->data.configs.num_configs = 1; in bcm2835_pctl_dt_node_to_map_pull()
829 u32 pin, func, pull; in bcm2835_pctl_dt_node_to_map() local
839 dev_err(pc->dev, "%pOF: missing brcm,pins property\n", np); in bcm2835_pctl_dt_node_to_map()
840 return -EINVAL; in bcm2835_pctl_dt_node_to_map()
847 dev_err(pc->dev, in bcm2835_pctl_dt_node_to_map()
850 return -EINVAL; in bcm2835_pctl_dt_node_to_map()
853 num_pins = pins->length / 4; in bcm2835_pctl_dt_node_to_map()
854 num_funcs = funcs ? (funcs->length / 4) : 0; in bcm2835_pctl_dt_node_to_map()
855 num_pulls = pulls ? (pulls->length / 4) : 0; in bcm2835_pctl_dt_node_to_map()
858 dev_err(pc->dev, in bcm2835_pctl_dt_node_to_map()
861 return -EINVAL; in bcm2835_pctl_dt_node_to_map()
865 dev_err(pc->dev, in bcm2835_pctl_dt_node_to_map()
868 return -EINVAL; in bcm2835_pctl_dt_node_to_map()
879 return -ENOMEM; in bcm2835_pctl_dt_node_to_map()
882 err = of_property_read_u32_index(np, "brcm,pins", i, &pin); in bcm2835_pctl_dt_node_to_map()
885 if (pin >= pc->pctl_desc.npins) { in bcm2835_pctl_dt_node_to_map()
886 dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n", in bcm2835_pctl_dt_node_to_map()
887 np, pin); in bcm2835_pctl_dt_node_to_map()
888 err = -EINVAL; in bcm2835_pctl_dt_node_to_map()
897 err = bcm2835_pctl_dt_node_to_map_func(pc, np, pin, in bcm2835_pctl_dt_node_to_map()
907 err = bcm2835_pctl_dt_node_to_map_pull(pc, np, pin, in bcm2835_pctl_dt_node_to_map()
966 /* every pin can do every function */ in bcm2835_pmx_get_function_groups()
1016 unsigned pin, unsigned long *config) in bcm2835_pinconf_get() argument
1020 enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, pin); in bcm2835_pinconf_get()
1021 u32 val; in bcm2835_pinconf_get() local
1028 return -EINVAL; in bcm2835_pinconf_get()
1030 val = bcm2835_gpio_get_bit(pc, GPLEV0, pin); in bcm2835_pinconf_get()
1031 *config = pinconf_to_config_packed(param, val); in bcm2835_pinconf_get()
1035 return -ENOTSUPP; in bcm2835_pinconf_get()
1042 unsigned int pin, unsigned int arg) in bcm2835_pull_config_set() argument
1046 off = GPIO_REG_OFFSET(pin); in bcm2835_pull_config_set()
1047 bit = GPIO_REG_SHIFT(pin); in bcm2835_pull_config_set()
1063 unsigned int pin, unsigned long *configs, in bcm2835_pinconf_set() argument
1077 bcm2835_pull_config_set(pc, pin, arg); in bcm2835_pinconf_set()
1082 bcm2835_pull_config_set(pc, pin, BCM2835_PUD_OFF); in bcm2835_pinconf_set()
1086 bcm2835_pull_config_set(pc, pin, BCM2835_PUD_DOWN); in bcm2835_pinconf_set()
1090 bcm2835_pull_config_set(pc, pin, BCM2835_PUD_UP); in bcm2835_pinconf_set()
1093 /* Set output-high or output-low */ in bcm2835_pinconf_set()
1095 bcm2835_gpio_set_bit(pc, arg ? GPSET0 : GPCLR0, pin); in bcm2835_pinconf_set()
1099 return -ENOTSUPP; in bcm2835_pinconf_set()
1113 static int bcm2711_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, in bcm2711_pinconf_get() argument
1118 u32 offset, shift, val; in bcm2711_pinconf_get() local
1120 offset = PUD_2711_REG_OFFSET(pin); in bcm2711_pinconf_get()
1121 shift = PUD_2711_REG_SHIFT(pin); in bcm2711_pinconf_get()
1122 val = bcm2835_gpio_rd(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (offset * 4)); in bcm2711_pinconf_get()
1126 if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_NONE) in bcm2711_pinconf_get()
1127 return -EINVAL; in bcm2711_pinconf_get()
1132 if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_UP) in bcm2711_pinconf_get()
1133 return -EINVAL; in bcm2711_pinconf_get()
1139 if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_DOWN) in bcm2711_pinconf_get()
1140 return -EINVAL; in bcm2711_pinconf_get()
1146 return bcm2835_pinconf_get(pctldev, pin, config); in bcm2711_pinconf_get()
1153 unsigned int pin, unsigned int arg) in bcm2711_pull_config_set() argument
1159 off = PUD_2711_REG_OFFSET(pin); in bcm2711_pull_config_set()
1160 shifter = PUD_2711_REG_SHIFT(pin); in bcm2711_pull_config_set()
1169 unsigned int pin, unsigned long *configs, in bcm2711_pinconf_set() argument
1190 bcm2711_pull_config_set(pc, pin, arg); in bcm2711_pinconf_set()
1195 bcm2711_pull_config_set(pc, pin, BCM2711_PULL_NONE); in bcm2711_pinconf_set()
1198 bcm2711_pull_config_set(pc, pin, BCM2711_PULL_DOWN); in bcm2711_pinconf_set()
1201 bcm2711_pull_config_set(pc, pin, BCM2711_PULL_UP); in bcm2711_pinconf_set()
1204 /* Set output-high or output-low */ in bcm2711_pinconf_set()
1206 bcm2835_gpio_set_bit(pc, arg ? GPSET0 : GPCLR0, pin); in bcm2711_pinconf_set()
1210 return -ENOTSUPP; in bcm2711_pinconf_set()
1234 .name = "pinctrl-bcm2711",
1249 .name = "pinctrl-bcm2711",
1273 .compatible = "brcm,bcm2835-gpio",
1277 .compatible = "brcm,bcm2711-gpio",
1281 .compatible = "brcm,bcm7211-gpio",
1290 struct device *dev = &pdev->dev; in bcm2835_pinctrl_probe()
1291 struct device_node *np = dev->of_node; in bcm2835_pinctrl_probe()
1305 return -ENOMEM; in bcm2835_pinctrl_probe()
1308 pc->dev = dev; in bcm2835_pinctrl_probe()
1316 pc->base = devm_ioremap_resource(dev, &iomem); in bcm2835_pinctrl_probe()
1317 if (IS_ERR(pc->base)) in bcm2835_pinctrl_probe()
1318 return PTR_ERR(pc->base); in bcm2835_pinctrl_probe()
1320 match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node); in bcm2835_pinctrl_probe()
1322 return -EINVAL; in bcm2835_pinctrl_probe()
1324 pdata = match->data; in bcm2835_pinctrl_probe()
1325 is_7211 = of_device_is_compatible(np, "brcm,bcm7211-gpio"); in bcm2835_pinctrl_probe()
1327 pc->gpio_chip = *pdata->gpio_chip; in bcm2835_pinctrl_probe()
1328 pc->gpio_chip.parent = dev; in bcm2835_pinctrl_probe()
1330 spin_lock_init(&pc->fsel_lock); in bcm2835_pinctrl_probe()
1348 raw_spin_lock_init(&pc->irq_lock[i]); in bcm2835_pinctrl_probe()
1351 pc->pctl_desc = *pdata->pctl_desc; in bcm2835_pinctrl_probe()
1352 pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc); in bcm2835_pinctrl_probe()
1353 if (IS_ERR(pc->pctl_dev)) { in bcm2835_pinctrl_probe()
1354 gpiochip_remove(&pc->gpio_chip); in bcm2835_pinctrl_probe()
1355 return PTR_ERR(pc->pctl_dev); in bcm2835_pinctrl_probe()
1358 pc->gpio_range = *pdata->gpio_range; in bcm2835_pinctrl_probe()
1359 pc->gpio_range.base = pc->gpio_chip.base; in bcm2835_pinctrl_probe()
1360 pc->gpio_range.gc = &pc->gpio_chip; in bcm2835_pinctrl_probe()
1361 pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); in bcm2835_pinctrl_probe()
1363 girq = &pc->gpio_chip.irq; in bcm2835_pinctrl_probe()
1365 girq->parent_handler = bcm2835_gpio_irq_handler; in bcm2835_pinctrl_probe()
1366 girq->num_parents = BCM2835_NUM_IRQS; in bcm2835_pinctrl_probe()
1367 girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS, in bcm2835_pinctrl_probe()
1368 sizeof(*girq->parents), in bcm2835_pinctrl_probe()
1370 if (!girq->parents) { in bcm2835_pinctrl_probe()
1371 err = -ENOMEM; in bcm2835_pinctrl_probe()
1376 pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS, in bcm2835_pinctrl_probe()
1377 sizeof(*pc->wake_irq), in bcm2835_pinctrl_probe()
1379 if (!pc->wake_irq) { in bcm2835_pinctrl_probe()
1380 err = -ENOMEM; in bcm2835_pinctrl_probe()
1387 * since we use one gpiochip to cover all lines - the in bcm2835_pinctrl_probe()
1389 * bank that was firing the IRQ and look up the per-group in bcm2835_pinctrl_probe()
1396 girq->parents[i] = irq_of_parse_and_map(np, i); in bcm2835_pinctrl_probe()
1398 if (!girq->parents[i]) { in bcm2835_pinctrl_probe()
1399 girq->num_parents = i; in bcm2835_pinctrl_probe()
1405 pc->wake_irq[i] = irq_of_parse_and_map(np, i + in bcm2835_pinctrl_probe()
1408 len = strlen(dev_name(pc->dev)) + 16; in bcm2835_pinctrl_probe()
1409 name = devm_kzalloc(pc->dev, len, GFP_KERNEL); in bcm2835_pinctrl_probe()
1411 err = -ENOMEM; in bcm2835_pinctrl_probe()
1415 snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i); in bcm2835_pinctrl_probe()
1418 err = devm_request_irq(dev, pc->wake_irq[i], in bcm2835_pinctrl_probe()
1423 pc->wake_irq[i]); in bcm2835_pinctrl_probe()
1426 girq->default_type = IRQ_TYPE_NONE; in bcm2835_pinctrl_probe()
1427 girq->handler = handle_level_irq; in bcm2835_pinctrl_probe()
1429 err = gpiochip_add_data(&pc->gpio_chip, pc); in bcm2835_pinctrl_probe()
1441 pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range); in bcm2835_pinctrl_probe()