Lines Matching +full:pins +full:- +full:bus

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
31 #include <sys/bus.h>
78 * low-level controller driver in struct gpio_pin. Currently, only pins
80 * the FDT properties. In theory, these flags are defined per-platform. In
81 * practice they are always the flags from the dt-bindings/gpio/gpio.h file.
82 * The only one of those flags we currently support is for handling active-low
83 * pins, so we just define that flag here instead of including a GPL'd header.
88 * XXX -> Move me to better place - gpio_subr.c?
104 gpio_data->gpio_pin_num = pin->pin; in gpio_alloc_intr_resource()
105 gpio_data->gpio_pin_flags = pin->flags; in gpio_alloc_intr_resource()
106 gpio_data->gpio_intr_mode = intr_mode; in gpio_alloc_intr_resource()
108 irq = intr_map_irq(pin->dev, 0, (struct intr_map_data *)gpio_data); in gpio_alloc_intr_resource()
137 /* Cannot mix pull-up/pull-down together. */ in gpio_check_flags()
144 if ((flags & GPIO_INTR_MASK) & ((flags & GPIO_INTR_MASK) - 1)) in gpio_check_flags()
165 pin->dev = device_get_parent(busdev); in gpio_pin_get_by_bus_pinnum()
166 pin->pin = pinnum; in gpio_pin_get_by_bus_pinnum()
167 pin->flags = 0; in gpio_pin_get_by_bus_pinnum()
179 if (idx >= devi->npins) in gpio_pin_get_by_child_index()
183 devi->pins[idx], ppin)); in gpio_pin_get_by_child_index()
191 KASSERT(pin->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_getcaps()
192 return (GPIO_PIN_GETCAPS(pin->dev, pin->pin, caps)); in gpio_pin_getcaps()
202 KASSERT(pin->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_is_active()
203 rv = GPIO_PIN_GET(pin->dev, pin->pin, &tmp); in gpio_pin_is_active()
208 if (pin->flags & GPIO_ACTIVE_LOW) in gpio_pin_is_active()
217 * be used in cases where a pre-existing
228 KASSERT(gpio->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_acquire()
230 busdev = GPIO_GET_BUS(gpio->dev); in gpio_pin_acquire()
234 return (gpiobus_acquire_pin(busdev, gpio->pin)); in gpio_pin_acquire()
243 KASSERT(gpio->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_release()
245 busdev = GPIO_GET_BUS(gpio->dev); in gpio_pin_release()
248 gpiobus_release_pin(busdev, gpio->pin); in gpio_pin_release()
258 if (pin->flags & GPIO_ACTIVE_LOW) in gpio_pin_set_active()
264 KASSERT(pin->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_set_active()
265 rv = GPIO_PIN_SET(pin->dev, pin->pin, tmp); in gpio_pin_set_active()
275 KASSERT(pin->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_setflags()
277 rv = GPIO_PIN_SETFLAGS(pin->dev, pin->pin, flags); in gpio_pin_setflags()
286 if (devi->npins == 0) in gpiobus_print_pins()
290 range_start = range_stop = devi->pins[0]; in gpiobus_print_pins()
291 for (i = 1; i < devi->npins; i++) { in gpiobus_print_pins()
292 if (devi->pins[i] != (range_stop + 1)) { in gpiobus_print_pins()
296 sbuf_printf(sb, "%d-%d", range_start, range_stop); in gpiobus_print_pins()
299 range_start = range_stop = devi->pins[i]; in gpiobus_print_pins()
309 sbuf_printf(sb, "%d-%d", range_start, range_stop); in gpiobus_print_pins()
343 sc->sc_busdev = dev; in gpiobus_init_softc()
344 sc->sc_dev = device_get_parent(dev); in gpiobus_init_softc()
345 sc->sc_intr_rman.rm_type = RMAN_ARRAY; in gpiobus_init_softc()
346 sc->sc_intr_rman.rm_descr = "GPIO Interrupts"; in gpiobus_init_softc()
347 if (rman_init(&sc->sc_intr_rman) != 0 || in gpiobus_init_softc()
348 rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0) in gpiobus_init_softc()
351 if (GPIO_PIN_MAX(sc->sc_dev, &sc->sc_npins) != 0) in gpiobus_init_softc()
354 KASSERT(sc->sc_npins >= 0, ("GPIO device with no pins")); in gpiobus_init_softc()
356 /* Pins = GPIO_PIN_MAX() + 1 */ in gpiobus_init_softc()
357 sc->sc_npins++; in gpiobus_init_softc()
359 sc->sc_pins = malloc(sizeof(*sc->sc_pins) * sc->sc_npins, M_DEVBUF, in gpiobus_init_softc()
361 if (sc->sc_pins == NULL) in gpiobus_init_softc()
364 /* Initialize the bus lock. */ in gpiobus_init_softc()
385 devi->npins = sc->sc_npins; in gpiobus_add_gpioc()
392 err = GPIO_GET_PIN_LIST(sc->sc_dev, devi->pins); in gpiobus_add_gpioc()
405 /* Allocate pins and flags memory. */ in gpiobus_alloc_ivars()
406 devi->pins = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF, in gpiobus_alloc_ivars()
408 if (devi->pins == NULL) in gpiobus_alloc_ivars()
417 if (devi->pins) { in gpiobus_free_ivars()
418 free(devi->pins, M_DEVBUF); in gpiobus_free_ivars()
419 devi->pins = NULL; in gpiobus_free_ivars()
421 devi->npins = 0; in gpiobus_free_ivars()
425 gpiobus_acquire_pin(device_t bus, uint32_t pin) in gpiobus_acquire_pin() argument
429 sc = device_get_softc(bus); in gpiobus_acquire_pin()
431 if (pin >= sc->sc_npins) { in gpiobus_acquire_pin()
433 device_get_nameunit(bus), pin, sc->sc_npins - 1); in gpiobus_acquire_pin()
436 if (sc->sc_pins[pin].mapped) { in gpiobus_acquire_pin()
437 device_printf(bus, "warning: pin %d is already mapped\n", pin); in gpiobus_acquire_pin()
440 sc->sc_pins[pin].mapped = 1; in gpiobus_acquire_pin()
447 gpiobus_release_pin(device_t bus, uint32_t pin) in gpiobus_release_pin() argument
451 sc = device_get_softc(bus); in gpiobus_release_pin()
453 if (pin >= sc->sc_npins) { in gpiobus_release_pin()
455 device_get_nameunit(bus), pin, sc->sc_npins - 1); in gpiobus_release_pin()
458 if (!sc->sc_pins[pin].mapped) in gpiobus_release_pin()
459 panic("%s: pin %d is not mapped", device_get_nameunit(bus), in gpiobus_release_pin()
462 sc->sc_pins[pin].mapped = 0; in gpiobus_release_pin()
471 for (i = 0; i < devi->npins; i++) { in gpiobus_acquire_child_pins()
473 if (gpiobus_acquire_pin(dev, devi->pins[i]) != 0) { in gpiobus_acquire_child_pins()
475 devi->pins[i]); in gpiobus_acquire_child_pins()
476 while (--i >= 0) { in gpiobus_acquire_child_pins()
477 gpiobus_release_pin(dev, devi->pins[i]); in gpiobus_acquire_child_pins()
483 for (i = 0; i < devi->npins; i++) { in gpiobus_acquire_child_pins()
485 GPIOBUS_PIN_SETNAME(dev, devi->pins[i], in gpiobus_acquire_child_pins()
507 devi->npins = npins; in gpiobus_parse_pins()
516 devi->pins[npins++] = i; in gpiobus_parse_pins()
524 const char *pins) in gpiobus_parse_pin_list() argument
533 p = pins; in gpiobus_parse_pin_list()
553 devi->npins = npins; in gpiobus_parse_pin_list()
560 p = pins; in gpiobus_parse_pin_list()
564 devi->pins[i] = pin; in gpiobus_parse_pin_list()
578 device_set_desc(dev, "GPIO bus"); in gpiobus_probe()
597 * Get parent's pins and mark them as unmapped in gpiobus_attach()
607 * Since this is not a self-enumerating bus, and since we always add
617 KASSERT(mtx_initialized(&sc->sc_mtx), in gpiobus_detach()
624 rman_fini(&sc->sc_intr_rman); in gpiobus_detach()
625 if (sc->sc_pins) { in gpiobus_detach()
626 for (i = 0; i < sc->sc_npins; i++) { in gpiobus_detach()
627 if (sc->sc_pins[i].name != NULL) in gpiobus_detach()
628 free(sc->sc_pins[i].name, M_DEVBUF); in gpiobus_detach()
629 sc->sc_pins[i].name = NULL; in gpiobus_detach()
631 free(sc->sc_pins, M_DEVBUF); in gpiobus_detach()
632 sc->sc_pins = NULL; in gpiobus_detach()
655 char pins[128]; in gpiobus_probe_nomatch() local
660 sbuf_new(&sb, pins, sizeof(pins), SBUF_FIXEDLEN); in gpiobus_probe_nomatch()
664 devi->npins > 1 ? "s" : "", sbuf_data(&sb)); in gpiobus_probe_nomatch()
665 resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%jd"); in gpiobus_probe_nomatch()
672 char pins[128]; in gpiobus_print_child() local
679 if (devi->npins > 0) { in gpiobus_print_child()
680 if (devi->npins > 1) in gpiobus_print_child()
681 retval += printf(" at pins "); in gpiobus_print_child()
684 sbuf_new(&sb, pins, sizeof(pins), SBUF_FIXEDLEN); in gpiobus_print_child()
689 resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%jd"); in gpiobus_print_child()
696 gpiobus_child_location(device_t bus, device_t child, struct sbuf *sb) in gpiobus_child_location() argument
701 sbuf_printf(sb, "pins="); in gpiobus_child_location()
724 resource_list_init(&devi->rl); in gpiobus_add_child_common()
746 resource_list_free(&devi->rl); in gpiobus_child_deleted()
755 * Re-scan is supposed to remove and add children, but if someone has in gpiobus_rescan()
766 gpiobus_hinted_child(device_t bus, const char *dname, int dunit) in gpiobus_hinted_child() argument
768 struct gpiobus_softc *sc = GPIOBUS_SOFTC(bus); in gpiobus_hinted_child()
770 const char *pins; in gpiobus_hinted_child() local
773 if (device_find_child(bus, dname, dunit) != NULL) { in gpiobus_hinted_child()
777 child = BUS_ADD_CHILD(bus, 0, dname, dunit); in gpiobus_hinted_child()
778 if (resource_int_value(dname, dunit, "pins", &pinmask) == 0) { in gpiobus_hinted_child()
780 device_delete_child(bus, child); in gpiobus_hinted_child()
784 else if (resource_string_value(dname, dunit, "pin_list", &pins) == 0) { in gpiobus_hinted_child()
785 if (gpiobus_parse_pin_list(sc, child, pins)) { in gpiobus_hinted_child()
786 device_delete_child(bus, child); in gpiobus_hinted_child()
792 device_printf(bus, in gpiobus_hinted_child()
805 *result = devi->npins; in gpiobus_read_ivar()
828 if (devi->npins != 0) { in gpiobus_write_ivar()
831 devi->npins = value; in gpiobus_write_ivar()
834 devi->npins = 0; in gpiobus_write_ivar()
840 for (i = 0; i < devi->npins; i++) in gpiobus_write_ivar()
841 devi->pins[i] = ptr[i]; in gpiobus_write_ivar()
853 gpiobus_get_rman(device_t bus, int type, u_int flags) in gpiobus_get_rman() argument
857 sc = device_get_softc(bus); in gpiobus_get_rman()
860 return (&sc->sc_intr_rman); in gpiobus_get_rman()
867 gpiobus_alloc_resource(device_t bus, device_t child, int type, int *rid, in gpiobus_alloc_resource() argument
876 rl = BUS_GET_RESOURCE_LIST(bus, child); in gpiobus_alloc_resource()
882 start = rle->start; in gpiobus_alloc_resource()
883 count = rle->count; in gpiobus_alloc_resource()
884 end = rle->end; in gpiobus_alloc_resource()
886 return (bus_generic_rman_alloc_resource(bus, child, type, rid, start, in gpiobus_alloc_resource()
910 gpiobus_get_resource_list(device_t bus __unused, device_t child) in gpiobus_get_resource_list()
916 return (&ivar->rl); in gpiobus_get_resource_list()
927 if (sc->sc_owner != NULL) { in gpiobus_acquire_bus()
928 if (sc->sc_owner == child) in gpiobus_acquire_bus()
929 panic("%s: %s still owns the bus.", in gpiobus_acquire_bus()
936 while (sc->sc_owner != NULL) in gpiobus_acquire_bus()
937 mtx_sleep(sc, &sc->sc_mtx, 0, "gpiobuswait", 0); in gpiobus_acquire_bus()
939 sc->sc_owner = child; in gpiobus_acquire_bus()
953 if (sc->sc_owner == NULL) in gpiobus_release_bus()
954 panic("%s: %s releasing unowned bus.", in gpiobus_release_bus()
957 if (sc->sc_owner != child) in gpiobus_release_bus()
958 panic("%s: %s trying to release bus owned by %s", in gpiobus_release_bus()
961 device_get_nameunit(sc->sc_owner)); in gpiobus_release_bus()
962 sc->sc_owner = NULL; in gpiobus_release_bus()
975 if (pin >= devi->npins) in gpiobus_pin_setflags()
977 if (GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], &caps) != 0) in gpiobus_pin_setflags()
982 return (GPIO_PIN_SETFLAGS(sc->sc_dev, devi->pins[pin], flags)); in gpiobus_pin_setflags()
992 if (pin >= devi->npins) in gpiobus_pin_getflags()
995 return (GPIO_PIN_GETFLAGS(sc->sc_dev, devi->pins[pin], flags)); in gpiobus_pin_getflags()
1005 if (pin >= devi->npins) in gpiobus_pin_getcaps()
1008 return (GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], caps)); in gpiobus_pin_getcaps()
1018 if (pin >= devi->npins) in gpiobus_pin_set()
1021 return (GPIO_PIN_SET(sc->sc_dev, devi->pins[pin], value)); in gpiobus_pin_set()
1031 if (pin >= devi->npins) in gpiobus_pin_get()
1034 return (GPIO_PIN_GET(sc->sc_dev, devi->pins[pin], value)); in gpiobus_pin_get()
1043 if (pin >= devi->npins) in gpiobus_pin_toggle()
1046 return (GPIO_PIN_TOGGLE(sc->sc_dev, devi->pins[pin])); in gpiobus_pin_toggle()
1050 * Verify that a child has all the pins they are requesting
1057 if (first_pin + num_pins > devi->npins) in gpiobus_pin_verify_32()
1060 /* Make sure the pins are consecutive. */ in gpiobus_pin_verify_32()
1061 for (uint32_t pin = first_pin; pin < first_pin + num_pins - 1; pin++) { in gpiobus_pin_verify_32()
1062 if (devi->pins[pin] + 1 != devi->pins[pin + 1]) in gpiobus_pin_verify_32()
1079 return (GPIO_PIN_ACCESS_32(sc->sc_dev, devi->pins[first_pin], in gpiobus_pin_access_32()
1095 return (GPIO_PIN_CONFIG_32(sc->sc_dev, in gpiobus_pin_config_32()
1096 devi->pins[first_pin], num_pins, pin_flags)); in gpiobus_pin_config_32()
1105 if (pin > sc->sc_npins) in gpiobus_pin_getname()
1108 if (sc->sc_pins[pin].name != NULL) { in gpiobus_pin_getname()
1109 memcpy(name, sc->sc_pins[pin].name, GPIOMAXNAME); in gpiobus_pin_getname()
1123 if (pin > sc->sc_npins) in gpiobus_pin_setname()
1128 if (sc->sc_pins[pin].name == NULL) in gpiobus_pin_setname()
1129 sc->sc_pins[pin].name = malloc(GPIOMAXNAME, M_DEVBUF, in gpiobus_pin_setname()
1131 strlcpy(sc->sc_pins[pin].name, name, GPIOMAXNAME); in gpiobus_pin_setname()
1145 /* Bus interface */