Lines Matching +full:dev +full:- +full:a +full:- +full:active +full:- +full:pins
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 #include <dev/gpio/gpiobusvar.h>
42 #include <dev/gpio/gpiobus_internal.h>
79 * low-level controller driver in struct gpio_pin. Currently, only pins
81 * the FDT properties. In theory, these flags are defined per-platform. In
82 * practice they are always the flags from the dt-bindings/gpio/gpio.h file.
83 * The only one of those flags we currently support is for handling active-low
84 * pins, so we just define that flag here instead of including a GPL'd header.
89 * XXX -> Move me to better place - gpio_subr.c?
105 gpio_data->gpio_pin_num = pin->pin; in gpio_alloc_intr_resource()
106 gpio_data->gpio_pin_flags = pin->flags; in gpio_alloc_intr_resource()
107 gpio_data->gpio_intr_mode = intr_mode; in gpio_alloc_intr_resource()
109 irq = intr_map_irq(pin->dev, 0, (struct intr_map_data *)gpio_data); in gpio_alloc_intr_resource()
138 /* Cannot mix pull-up/pull-down together. */ in gpio_check_flags()
145 if ((flags & GPIO_INTR_MASK) & ((flags & GPIO_INTR_MASK) - 1)) in gpio_check_flags()
166 pin->dev = device_get_parent(busdev); in gpio_pin_get_by_bus_pinnum()
167 pin->pin = pinnum; in gpio_pin_get_by_bus_pinnum()
168 pin->flags = 0; in gpio_pin_get_by_bus_pinnum()
180 if (idx >= devi->npins) in gpio_pin_get_by_child_index()
184 devi->pins[idx], ppin)); in gpio_pin_get_by_child_index()
192 KASSERT(pin->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_getcaps()
193 return (GPIO_PIN_GETCAPS(pin->dev, pin->pin, caps)); in gpio_pin_getcaps()
197 gpio_pin_is_active(gpio_pin_t pin, bool *active) in gpio_pin_is_active() argument
203 KASSERT(pin->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_is_active()
204 rv = GPIO_PIN_GET(pin->dev, pin->pin, &tmp); in gpio_pin_is_active()
209 if (pin->flags & GPIO_ACTIVE_LOW) in gpio_pin_is_active()
210 *active = tmp == 0; in gpio_pin_is_active()
212 *active = tmp != 0; in gpio_pin_is_active()
218 * be used in cases where a pre-existing
229 KASSERT(gpio->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_acquire()
231 busdev = GPIO_GET_BUS(gpio->dev); in gpio_pin_acquire()
235 return (gpiobus_acquire_pin(busdev, gpio->pin)); in gpio_pin_acquire()
244 KASSERT(gpio->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_release()
246 busdev = GPIO_GET_BUS(gpio->dev); in gpio_pin_release()
247 KASSERT(busdev != NULL, ("gpiobus dev is NULL.")); in gpio_pin_release()
249 gpiobus_release_pin(busdev, gpio->pin); in gpio_pin_release()
254 gpio_pin_set_active(gpio_pin_t pin, bool active) in gpio_pin_set_active() argument
259 if (pin->flags & GPIO_ACTIVE_LOW) in gpio_pin_set_active()
260 tmp = active ? 0 : 1; in gpio_pin_set_active()
262 tmp = active ? 1 : 0; in gpio_pin_set_active()
265 KASSERT(pin->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_set_active()
266 rv = GPIO_PIN_SET(pin->dev, pin->pin, tmp); in gpio_pin_set_active()
276 KASSERT(pin->dev != NULL, ("GPIO pin device is NULL.")); in gpio_pin_setflags()
278 rv = GPIO_PIN_SETFLAGS(pin->dev, pin->pin, flags); in gpio_pin_setflags()
287 if (devi->npins == 0) in gpiobus_print_pins()
291 range_start = range_stop = devi->pins[0]; in gpiobus_print_pins()
292 for (i = 1; i < devi->npins; i++) { in gpiobus_print_pins()
293 if (devi->pins[i] != (range_stop + 1)) { in gpiobus_print_pins()
297 sbuf_printf(sb, "%d-%d", range_start, range_stop); in gpiobus_print_pins()
300 range_start = range_stop = devi->pins[i]; in gpiobus_print_pins()
310 sbuf_printf(sb, "%d-%d", range_start, range_stop); in gpiobus_print_pins()
316 gpiobus_add_bus(device_t dev) in gpiobus_add_bus() argument
320 busdev = device_add_child(dev, "gpiobus", DEVICE_UNIT_ANY); in gpiobus_add_bus()
323 if (device_add_child(dev, "gpioc", DEVICE_UNIT_ANY) == NULL) { in gpiobus_add_bus()
324 device_delete_child(dev, busdev); in gpiobus_add_bus()
328 ofw_gpiobus_register_provider(dev); in gpiobus_add_bus()
334 * Attach a gpiobus child.
339 gpiobus_attach_bus(device_t dev) in gpiobus_attach_bus() argument
343 busdev = gpiobus_add_bus(dev); in gpiobus_attach_bus()
347 bus_attach_children(dev); in gpiobus_attach_bus()
352 gpiobus_detach_bus(device_t dev) in gpiobus_detach_bus() argument
355 ofw_gpiobus_unregister_provider(dev); in gpiobus_detach_bus()
357 return (bus_generic_detach(dev)); in gpiobus_detach_bus()
361 gpiobus_init_softc(device_t dev) in gpiobus_init_softc() argument
365 sc = GPIOBUS_SOFTC(dev); in gpiobus_init_softc()
366 sc->sc_busdev = dev; in gpiobus_init_softc()
367 sc->sc_dev = device_get_parent(dev); in gpiobus_init_softc()
368 sc->sc_intr_rman.rm_type = RMAN_ARRAY; in gpiobus_init_softc()
369 sc->sc_intr_rman.rm_descr = "GPIO Interrupts"; in gpiobus_init_softc()
370 if (rman_init(&sc->sc_intr_rman) != 0 || in gpiobus_init_softc()
371 rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0) in gpiobus_init_softc()
374 if (GPIO_PIN_MAX(sc->sc_dev, &sc->sc_npins) != 0) in gpiobus_init_softc()
377 KASSERT(sc->sc_npins >= 0, ("GPIO device with no pins")); in gpiobus_init_softc()
379 /* Pins = GPIO_PIN_MAX() + 1 */ in gpiobus_init_softc()
380 sc->sc_npins++; in gpiobus_init_softc()
382 sc->sc_pins = malloc(sizeof(*sc->sc_pins) * sc->sc_npins, M_DEVBUF, in gpiobus_init_softc()
384 if (sc->sc_pins == NULL) in gpiobus_init_softc()
397 /* Allocate pins and flags memory. */ in gpiobus_alloc_ivars()
398 devi->pins = malloc(sizeof(uint32_t) * devi->npins, M_DEVBUF, in gpiobus_alloc_ivars()
400 if (devi->pins == NULL) in gpiobus_alloc_ivars()
409 if (devi->pins) { in gpiobus_free_ivars()
410 free(devi->pins, M_DEVBUF); in gpiobus_free_ivars()
411 devi->pins = NULL; in gpiobus_free_ivars()
413 devi->npins = 0; in gpiobus_free_ivars()
423 if (pin >= sc->sc_npins) { in gpiobus_acquire_pin()
425 device_get_nameunit(bus), pin, sc->sc_npins - 1); in gpiobus_acquire_pin()
428 if (sc->sc_pins[pin].mapped) { in gpiobus_acquire_pin()
432 sc->sc_pins[pin].mapped = 1; in gpiobus_acquire_pin()
445 if (pin >= sc->sc_npins) { in gpiobus_release_pin()
447 device_get_nameunit(bus), pin, sc->sc_npins - 1); in gpiobus_release_pin()
450 if (!sc->sc_pins[pin].mapped) in gpiobus_release_pin()
454 sc->sc_pins[pin].mapped = 0; in gpiobus_release_pin()
458 gpiobus_acquire_child_pins(device_t dev, device_t child) in gpiobus_acquire_child_pins() argument
463 for (i = 0; i < devi->npins; i++) { in gpiobus_acquire_child_pins()
465 if (gpiobus_acquire_pin(dev, devi->pins[i]) != 0) { in gpiobus_acquire_child_pins()
467 devi->pins[i]); in gpiobus_acquire_child_pins()
468 while (--i >= 0) { in gpiobus_acquire_child_pins()
469 gpiobus_release_pin(dev, devi->pins[i]); in gpiobus_acquire_child_pins()
475 for (i = 0; i < devi->npins; i++) { in gpiobus_acquire_child_pins()
477 GPIOBUS_PIN_SETNAME(dev, devi->pins[i], in gpiobus_acquire_child_pins()
499 devi->npins = npins; in gpiobus_parse_pins()
508 devi->pins[npins++] = i; in gpiobus_parse_pins()
516 const char *pins) in gpiobus_parse_pin_list() argument
525 p = pins; in gpiobus_parse_pin_list()
545 devi->npins = npins; in gpiobus_parse_pin_list()
552 p = pins; in gpiobus_parse_pin_list()
556 devi->pins[i] = pin; in gpiobus_parse_pin_list()
568 gpiobus_probe(device_t dev) in gpiobus_probe() argument
570 device_set_desc(dev, "GPIO bus"); in gpiobus_probe()
576 gpiobus_attach(device_t dev) in gpiobus_attach() argument
580 err = gpiobus_init_softc(dev); in gpiobus_attach()
585 * Get parent's pins and mark them as unmapped in gpiobus_attach()
587 bus_identify_children(dev); in gpiobus_attach()
588 bus_enumerate_hinted_children(dev); in gpiobus_attach()
590 bus_attach_children(dev); in gpiobus_attach()
595 * Since this is not a self-enumerating bus, and since we always add
599 gpiobus_detach(device_t dev) in gpiobus_detach() argument
604 sc = GPIOBUS_SOFTC(dev); in gpiobus_detach()
605 KASSERT(mtx_initialized(&sc->sc_mtx), in gpiobus_detach()
609 if ((err = bus_detach_children(dev)) != 0) in gpiobus_detach()
612 rman_fini(&sc->sc_intr_rman); in gpiobus_detach()
613 if (sc->sc_pins) { in gpiobus_detach()
614 for (i = 0; i < sc->sc_npins; i++) { in gpiobus_detach()
615 if (sc->sc_pins[i].name != NULL) in gpiobus_detach()
616 free(sc->sc_pins[i].name, M_DEVBUF); in gpiobus_detach()
617 sc->sc_pins[i].name = NULL; in gpiobus_detach()
619 free(sc->sc_pins, M_DEVBUF); in gpiobus_detach()
620 sc->sc_pins = NULL; in gpiobus_detach()
627 gpiobus_suspend(device_t dev) in gpiobus_suspend() argument
630 return (bus_generic_suspend(dev)); in gpiobus_suspend()
634 gpiobus_resume(device_t dev) in gpiobus_resume() argument
637 return (bus_generic_resume(dev)); in gpiobus_resume()
641 gpiobus_probe_nomatch(device_t dev, device_t child) in gpiobus_probe_nomatch() argument
643 char pins[128]; in gpiobus_probe_nomatch() local
648 sbuf_new(&sb, pins, sizeof(pins), SBUF_FIXEDLEN); in gpiobus_probe_nomatch()
651 device_printf(dev, "<unknown device> at pin%s %s", in gpiobus_probe_nomatch()
652 devi->npins > 1 ? "s" : "", sbuf_data(&sb)); in gpiobus_probe_nomatch()
653 resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%jd"); in gpiobus_probe_nomatch()
658 gpiobus_print_child(device_t dev, device_t child) in gpiobus_print_child() argument
660 char pins[128]; in gpiobus_print_child() local
666 retval += bus_print_child_header(dev, child); in gpiobus_print_child()
667 if (devi->npins > 0) { in gpiobus_print_child()
668 if (devi->npins > 1) in gpiobus_print_child()
669 retval += printf(" at pins "); in gpiobus_print_child()
672 sbuf_new(&sb, pins, sizeof(pins), SBUF_FIXEDLEN); in gpiobus_print_child()
677 resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%jd"); in gpiobus_print_child()
678 retval += bus_print_child_footer(dev, child); in gpiobus_print_child()
689 sbuf_printf(sb, "pins="); in gpiobus_child_location()
696 gpiobus_add_child(device_t dev, u_int order, const char *name, int unit) in gpiobus_add_child() argument
701 child = device_add_child_ordered(dev, order, name, unit); in gpiobus_add_child()
706 device_delete_child(dev, child); in gpiobus_add_child()
709 resource_list_init(&devi->rl); in gpiobus_add_child()
716 gpiobus_child_deleted(device_t dev, device_t child) in gpiobus_child_deleted() argument
724 resource_list_free(&devi->rl); in gpiobus_child_deleted()
729 gpiobus_rescan(device_t dev) in gpiobus_rescan() argument
733 * Re-scan is supposed to remove and add children, but if someone has in gpiobus_rescan()
734 * deleted the hints for a child we attached earlier, we have no easy in gpiobus_rescan()
738 bus_enumerate_hinted_children(dev); in gpiobus_rescan()
739 bus_attach_children(dev); in gpiobus_rescan()
748 const char *pins; in gpiobus_hinted_child() local
756 if (resource_int_value(dname, dunit, "pins", &pinmask) == 0) { in gpiobus_hinted_child()
762 else if (resource_string_value(dname, dunit, "pin_list", &pins) == 0) { in gpiobus_hinted_child()
763 if (gpiobus_parse_pin_list(sc, child, pins)) { in gpiobus_hinted_child()
776 gpiobus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) in gpiobus_read_ivar() argument
783 *result = devi->npins; in gpiobus_read_ivar()
796 gpiobus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) in gpiobus_write_ivar() argument
806 if (devi->npins != 0) { in gpiobus_write_ivar()
809 devi->npins = value; in gpiobus_write_ivar()
812 devi->npins = 0; in gpiobus_write_ivar()
818 for (i = 0; i < devi->npins; i++) in gpiobus_write_ivar()
819 devi->pins[i] = ptr[i]; in gpiobus_write_ivar()
820 if (gpiobus_acquire_child_pins(dev, child) != 0) in gpiobus_write_ivar()
838 return (&sc->sc_intr_rman); in gpiobus_get_rman()
860 start = rle->start; in gpiobus_alloc_resource()
861 count = rle->count; in gpiobus_alloc_resource()
862 end = rle->end; in gpiobus_alloc_resource()
869 gpiobus_release_resource(device_t dev, device_t child, struct resource *r) in gpiobus_release_resource() argument
878 err = bus_generic_rman_release_resource(dev, child, r); in gpiobus_release_resource()
894 return (&ivar->rl); in gpiobus_get_resource_list()
905 if (sc->sc_owner != NULL) { in gpiobus_acquire_bus()
906 if (sc->sc_owner == child) in gpiobus_acquire_bus()
914 while (sc->sc_owner != NULL) in gpiobus_acquire_bus()
915 mtx_sleep(sc, &sc->sc_mtx, 0, "gpiobuswait", 0); in gpiobus_acquire_bus()
917 sc->sc_owner = child; in gpiobus_acquire_bus()
931 if (sc->sc_owner == NULL) in gpiobus_release_bus()
935 if (sc->sc_owner != child) in gpiobus_release_bus()
939 device_get_nameunit(sc->sc_owner)); in gpiobus_release_bus()
940 sc->sc_owner = NULL; in gpiobus_release_bus()
946 gpiobus_pin_setflags(device_t dev, device_t child, uint32_t pin, in gpiobus_pin_setflags() argument
949 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); in gpiobus_pin_setflags()
953 if (pin >= devi->npins) in gpiobus_pin_setflags()
955 if (GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], &caps) != 0) in gpiobus_pin_setflags()
960 return (GPIO_PIN_SETFLAGS(sc->sc_dev, devi->pins[pin], flags)); in gpiobus_pin_setflags()
964 gpiobus_pin_getflags(device_t dev, device_t child, uint32_t pin, in gpiobus_pin_getflags() argument
967 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); in gpiobus_pin_getflags()
970 if (pin >= devi->npins) in gpiobus_pin_getflags()
973 return GPIO_PIN_GETFLAGS(sc->sc_dev, devi->pins[pin], flags); in gpiobus_pin_getflags()
977 gpiobus_pin_getcaps(device_t dev, device_t child, uint32_t pin, in gpiobus_pin_getcaps() argument
980 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); in gpiobus_pin_getcaps()
983 if (pin >= devi->npins) in gpiobus_pin_getcaps()
986 return GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], caps); in gpiobus_pin_getcaps()
990 gpiobus_pin_set(device_t dev, device_t child, uint32_t pin, in gpiobus_pin_set() argument
993 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); in gpiobus_pin_set()
996 if (pin >= devi->npins) in gpiobus_pin_set()
999 return GPIO_PIN_SET(sc->sc_dev, devi->pins[pin], value); in gpiobus_pin_set()
1003 gpiobus_pin_get(device_t dev, device_t child, uint32_t pin, in gpiobus_pin_get() argument
1006 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); in gpiobus_pin_get()
1009 if (pin >= devi->npins) in gpiobus_pin_get()
1012 return GPIO_PIN_GET(sc->sc_dev, devi->pins[pin], value); in gpiobus_pin_get()
1016 gpiobus_pin_toggle(device_t dev, device_t child, uint32_t pin) in gpiobus_pin_toggle() argument
1018 struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); in gpiobus_pin_toggle()
1021 if (pin >= devi->npins) in gpiobus_pin_toggle()
1024 return GPIO_PIN_TOGGLE(sc->sc_dev, devi->pins[pin]); in gpiobus_pin_toggle()
1028 gpiobus_pin_getname(device_t dev, uint32_t pin, char *name) in gpiobus_pin_getname() argument
1032 sc = GPIOBUS_SOFTC(dev); in gpiobus_pin_getname()
1033 if (pin > sc->sc_npins) in gpiobus_pin_getname()
1035 /* Did we have a name for this pin ? */ in gpiobus_pin_getname()
1036 if (sc->sc_pins[pin].name != NULL) { in gpiobus_pin_getname()
1037 memcpy(name, sc->sc_pins[pin].name, GPIOMAXNAME); in gpiobus_pin_getname()
1042 return (GPIO_PIN_GETNAME(device_get_parent(dev), pin, name)); in gpiobus_pin_getname()
1046 gpiobus_pin_setname(device_t dev, uint32_t pin, const char *name) in gpiobus_pin_setname() argument
1050 sc = GPIOBUS_SOFTC(dev); in gpiobus_pin_setname()
1051 if (pin > sc->sc_npins) in gpiobus_pin_setname()
1056 if (sc->sc_pins[pin].name == NULL) in gpiobus_pin_setname()
1057 sc->sc_pins[pin].name = malloc(GPIOMAXNAME, M_DEVBUF, in gpiobus_pin_setname()
1059 strlcpy(sc->sc_pins[pin].name, name, GPIOMAXNAME); in gpiobus_pin_setname()