Lines Matching +full:dev +full:- +full:a +full:- +full:active +full:- +full:pins
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 #include <dev/gpio/gpiobusvar.h>
56 #include <dev/ofw/openfirm.h>
57 #include <dev/ofw/ofw_bus.h>
58 #include <dev/ofw/ofw_bus_subr.h>
73 #define TI_GPIO_IRQSTATUS_0 0x002C /* writing a 0 has no effect */
74 #define TI_GPIO_IRQSTATUS_1 0x0030 /* writing a 0 has no effect */
75 #define TI_GPIO_IRQSTATUS_SET_0 0x0034 /* writing a 0 has no effect */
76 #define TI_GPIO_IRQSTATUS_SET_1 0x0038 /* writing a 0 has no effect */
77 #define TI_GPIO_IRQSTATUS_CLR_0 0x003C /* writing a 0 has no effect */
78 #define TI_GPIO_IRQSTATUS_CLR_1 0x0040 /* writing a 0 has no effect */
135 #define TI_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
136 #define TI_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
138 mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
140 #define TI_GPIO_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
141 #define TI_GPIO_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
142 #define TI_GPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED)
145 * ti_gpio_read_4 - reads a 32-bit value from one of the GPIO registers
148 * @off: The offset of a register from the GPIO register address range
152 * 32-bit value read from the register.
157 return (bus_read_4(sc->sc_mem_res, off)); in ti_gpio_read_4()
161 * ti_gpio_write_4 - writes a 32-bit value to one of the GPIO registers
164 * @off: The offset of a register from the GPIO register address range
174 bus_write_4(sc->sc_mem_res, off, val); in ti_gpio_write_4()
222 ti_gpio_get_bus(device_t dev) in ti_gpio_get_bus() argument
226 sc = device_get_softc(dev); in ti_gpio_get_bus()
228 return (sc->sc_busdev); in ti_gpio_get_bus()
232 * ti_gpio_pin_max - Returns the maximum number of GPIO pins
233 * @dev: gpio device handle
234 * @maxpin: pointer to a value that upon return will contain the maximum number
235 * of pins in the device.
245 ti_gpio_pin_max(device_t dev, int *maxpin) in ti_gpio_pin_max() argument
248 *maxpin = PINS_PER_BANK - 1; in ti_gpio_pin_max()
257 if (pin >= sc->sc_maxpin || sc->sc_mem_res == NULL) in ti_gpio_valid_pin()
264 * ti_gpio_pin_getcaps - Gets the capabilities of a given pin
265 * @dev: gpio device handle
267 * @caps: pointer to a value that upon return will contain the capabilities
269 * Currently all pins have the same capability, notably:
270 * - GPIO_PIN_INPUT
271 * - GPIO_PIN_OUTPUT
272 * - GPIO_PIN_PULLUP
273 * - GPIO_PIN_PULLDOWN
274 * - GPIO_INTR_LEVEL_LOW
275 * - GPIO_INTR_LEVEL_HIGH
276 * - GPIO_INTR_EDGE_RISING
277 * - GPIO_INTR_EDGE_FALLING
278 * - GPIO_INTR_EDGE_BOTH
287 ti_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) in ti_gpio_pin_getcaps() argument
291 sc = device_get_softc(dev); in ti_gpio_pin_getcaps()
304 * ti_gpio_pin_getflags - Gets the current flags of a given pin
305 * @dev: gpio device handle
309 * Reads the current flags of a given pin, here we actually read the H/W
320 ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) in ti_gpio_pin_getflags() argument
324 sc = device_get_softc(dev); in ti_gpio_pin_getflags()
330 TI_GPIO_GET_FLAGS(dev, pin, flags); in ti_gpio_pin_getflags()
337 * ti_gpio_pin_getname - Gets the name of a given pin
338 * @dev: gpio device handle
342 * The driver simply calls the pins gpio_n, where 'n' is obviously the number
352 ti_gpio_pin_getname(device_t dev, uint32_t pin, char *name) in ti_gpio_pin_getname() argument
356 sc = device_get_softc(dev); in ti_gpio_pin_getname()
360 /* Set a very simple name */ in ti_gpio_pin_getname()
362 name[GPIOMAXNAME - 1] = '\0'; in ti_gpio_pin_getname()
368 * ti_gpio_pin_setflags - Sets the flags for a given pin
369 * @dev: gpio device handle
373 * The flags of the pin correspond to things like input/output mode, pull-ups,
374 * pull-downs, etc. This driver doesn't support all flags, only the following:
375 * - GPIO_PIN_INPUT
376 * - GPIO_PIN_OUTPUT
377 * - GPIO_PIN_PULLUP
378 * - GPIO_PIN_PULLDOWN
387 ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) in ti_gpio_pin_setflags() argument
392 sc = device_get_softc(dev); in ti_gpio_pin_setflags()
398 if (TI_GPIO_SET_FLAGS(dev, pin, flags) != 0) { in ti_gpio_pin_setflags()
416 * ti_gpio_pin_set - Sets the current level on a GPIO pin
417 * @dev: gpio device handle
419 * @value: non-zero value will drive the pin high, otherwise the pin is
427 * Returns 0 on success otherwise a error code
430 ti_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) in ti_gpio_pin_set() argument
435 sc = device_get_softc(dev); in ti_gpio_pin_set()
451 * ti_gpio_pin_get - Gets the current level on a GPIO pin
452 * @dev: gpio device handle
454 * @value: pointer to a value that upond return will contain the pin value
463 * Returns 0 on success otherwise a error code
466 ti_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value) in ti_gpio_pin_get() argument
471 sc = device_get_softc(dev); in ti_gpio_pin_get()
493 * ti_gpio_pin_toggle - Toggles a given GPIO pin
494 * @dev: gpio device handle
502 * Returns 0 on success otherwise a error code
505 ti_gpio_pin_toggle(device_t dev, uint32_t pin) in ti_gpio_pin_toggle() argument
510 sc = device_get_softc(dev); in ti_gpio_pin_toggle()
528 ti_gpio_bank_init(device_t dev) in ti_gpio_bank_init() argument
535 sc = device_get_softc(dev); in ti_gpio_bank_init()
538 rev_address = ti_sysc_get_rev_address(device_get_parent(dev)); in ti_gpio_bank_init()
540 * sc->sc_bank used in am335x/am335x_gpio.c and omap4/omap4_gpio.c */ in ti_gpio_bank_init()
546 sc->sc_bank = 0; in ti_gpio_bank_init()
549 sc->sc_bank = 1; in ti_gpio_bank_init()
552 sc->sc_bank = 2; in ti_gpio_bank_init()
555 sc->sc_bank = 3; in ti_gpio_bank_init()
560 err = ti_sysc_clock_enable(device_get_parent(dev)); in ti_gpio_bank_init()
562 device_printf(dev, "Failed to enable clock\n"); in ti_gpio_bank_init()
572 ti_sysc_get_rev_address_offset_host(device_get_parent(dev))); in ti_gpio_bank_init()
576 device_printf(dev, "Warning: could not determine the revision " in ti_gpio_bank_init()
581 /* Disable interrupts for all pins. */ in ti_gpio_bank_init()
588 TI_GPIO_GET_FLAGS(dev, pin, &flags); in ti_gpio_bank_init()
603 * ti_gpio_attach - attach function for the driver
604 * @dev: gpio device handle
616 ti_gpio_attach(device_t dev) in ti_gpio_attach() argument
621 sc = device_get_softc(dev); in ti_gpio_attach()
622 sc->sc_dev = dev; in ti_gpio_attach()
624 ti_gpio_pin_max(dev, &sc->sc_maxpin); in ti_gpio_attach()
625 sc->sc_maxpin++; in ti_gpio_attach()
627 sc->sc_mem_rid = 0; in ti_gpio_attach()
628 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, in ti_gpio_attach()
629 &sc->sc_mem_rid, RF_ACTIVE); in ti_gpio_attach()
630 if (!sc->sc_mem_res) { in ti_gpio_attach()
631 device_printf(dev, "Error: could not allocate mem resources\n"); in ti_gpio_attach()
632 ti_gpio_detach(dev); in ti_gpio_attach()
636 sc->sc_irq_rid = 0; in ti_gpio_attach()
637 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, in ti_gpio_attach()
638 &sc->sc_irq_rid, RF_ACTIVE); in ti_gpio_attach()
639 if (!sc->sc_irq_res) { in ti_gpio_attach()
640 device_printf(dev, "Error: could not allocate irq resources\n"); in ti_gpio_attach()
641 ti_gpio_detach(dev); in ti_gpio_attach()
648 if (bus_setup_intr(dev, sc->sc_irq_res, in ti_gpio_attach()
650 &sc->sc_irq_hdl) != 0) { in ti_gpio_attach()
651 device_printf(dev, in ti_gpio_attach()
653 ti_gpio_detach(dev); in ti_gpio_attach()
658 device_printf(dev, "WARNING: unable to attach PIC\n"); in ti_gpio_attach()
659 ti_gpio_detach(dev); in ti_gpio_attach()
665 * pins are configured which would result in less power used if the GPIO in ti_gpio_attach()
666 * pins weren't used ... in ti_gpio_attach()
668 if (sc->sc_mem_res != NULL) { in ti_gpio_attach()
670 err = ti_gpio_bank_init(dev); in ti_gpio_attach()
672 ti_gpio_detach(dev); in ti_gpio_attach()
677 sc->sc_busdev = gpiobus_attach_bus(dev); in ti_gpio_attach()
678 if (sc->sc_busdev == NULL) { in ti_gpio_attach()
679 ti_gpio_detach(dev); in ti_gpio_attach()
687 * ti_gpio_detach - detach function for the driver
688 * @dev: scm device handle
690 * Allocates and sets up the driver context, this simply entails creating a
700 ti_gpio_detach(device_t dev) in ti_gpio_detach() argument
702 struct ti_gpio_softc *sc = device_get_softc(dev); in ti_gpio_detach()
704 KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized")); in ti_gpio_detach()
707 if (sc->sc_mem_res != NULL) in ti_gpio_detach()
709 if (sc->sc_busdev != NULL) in ti_gpio_detach()
710 gpiobus_detach_bus(dev); in ti_gpio_detach()
711 if (sc->sc_isrcs != NULL) in ti_gpio_detach()
714 if (sc->sc_irq_hdl) { in ti_gpio_detach()
715 bus_teardown_intr(dev, sc->sc_irq_res, in ti_gpio_detach()
716 sc->sc_irq_hdl); in ti_gpio_detach()
718 if (sc->sc_irq_res) in ti_gpio_detach()
719 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irq_rid, in ti_gpio_detach()
720 sc->sc_irq_res); in ti_gpio_detach()
721 if (sc->sc_mem_res) in ti_gpio_detach()
722 bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid, in ti_gpio_detach()
723 sc->sc_mem_res); in ti_gpio_detach()
743 /* Writing a 0 has no effect. */ in ti_gpio_isrc_mask()
744 ti_gpio_intr_clr(sc, tgi->tgi_mask); in ti_gpio_isrc_mask()
751 /* Writing a 0 has no effect. */ in ti_gpio_isrc_unmask()
752 ti_gpio_intr_set(sc, tgi->tgi_mask); in ti_gpio_isrc_unmask()
759 /* Writing a 0 has no effect. */ in ti_gpio_isrc_eoi()
760 ti_gpio_intr_ack(sc, tgi->tgi_mask); in ti_gpio_isrc_eoi()
767 return (tgi->tgi_mode == GPIO_INTR_LEVEL_LOW || in ti_gpio_isrc_is_level()
768 tgi->tgi_mode == GPIO_INTR_LEVEL_HIGH); in ti_gpio_isrc_is_level()
781 tf = curthread->td_intr_frame; in ti_gpio_intr()
784 for (irq = 0; irq < sc->sc_maxpin; irq++) { in ti_gpio_intr()
785 tgi = &sc->sc_isrcs[irq]; in ti_gpio_intr()
786 if ((reg & tgi->tgi_mask) == 0) in ti_gpio_intr()
790 if (intr_isrc_dispatch(&tgi->tgi_isrc, tf) != 0) { in ti_gpio_intr()
794 device_printf(sc->sc_dev, "Stray irq %u disabled\n", in ti_gpio_intr()
808 sc->sc_isrcs = malloc(sizeof(*sc->sc_isrcs) * sc->sc_maxpin, M_DEVBUF, in ti_gpio_pic_attach()
811 name = device_get_nameunit(sc->sc_dev); in ti_gpio_pic_attach()
812 for (irq = 0; irq < sc->sc_maxpin; irq++) { in ti_gpio_pic_attach()
813 sc->sc_isrcs[irq].tgi_irq = irq; in ti_gpio_pic_attach()
814 sc->sc_isrcs[irq].tgi_mask = TI_GPIO_MASK(irq); in ti_gpio_pic_attach()
815 sc->sc_isrcs[irq].tgi_mode = GPIO_INTR_CONFORM; in ti_gpio_pic_attach()
817 error = intr_isrc_register(&sc->sc_isrcs[irq].tgi_isrc, in ti_gpio_pic_attach()
818 sc->sc_dev, 0, "%s,%u", name, irq); in ti_gpio_pic_attach()
822 if (intr_pic_register(sc->sc_dev, in ti_gpio_pic_attach()
823 OF_xref_from_node(ofw_bus_get_node(sc->sc_dev))) == NULL) in ti_gpio_pic_attach()
837 device_printf(sc->sc_dev, "%s: not implemented yet\n", __func__); in ti_gpio_pic_detach()
847 ti_gpio_rwreg_modify(sc, TI_GPIO_RISINGDETECT, tgi->tgi_mask, in ti_gpio_pic_config_intr()
849 ti_gpio_rwreg_modify(sc, TI_GPIO_FALLINGDETECT, tgi->tgi_mask, in ti_gpio_pic_config_intr()
851 ti_gpio_rwreg_modify(sc, TI_GPIO_LEVELDETECT1, tgi->tgi_mask, in ti_gpio_pic_config_intr()
853 ti_gpio_rwreg_modify(sc, TI_GPIO_LEVELDETECT0, tgi->tgi_mask, in ti_gpio_pic_config_intr()
855 tgi->tgi_mode = mode; in ti_gpio_pic_config_intr()
860 ti_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc) in ti_gpio_pic_disable_intr() argument
862 struct ti_gpio_softc *sc = device_get_softc(dev); in ti_gpio_pic_disable_intr()
869 ti_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc) in ti_gpio_pic_enable_intr() argument
871 struct ti_gpio_softc *sc = device_get_softc(dev); in ti_gpio_pic_enable_intr()
874 arm_irq_memory_barrier(tgi->tgi_irq); in ti_gpio_pic_enable_intr()
888 * 1 = low-to-high edge triggered. in ti_gpio_pic_map_fdt()
889 * 2 = high-to-low edge triggered. in ti_gpio_pic_map_fdt()
890 * 4 = active high level-sensitive. in ti_gpio_pic_map_fdt()
891 * 8 = active low level-sensitive. in ti_gpio_pic_map_fdt()
893 if (daf->ncells != 2 || daf->cells[0] >= sc->sc_maxpin) in ti_gpio_pic_map_fdt()
897 if (daf->cells[1] == 1) in ti_gpio_pic_map_fdt()
899 else if (daf->cells[1] == 2) in ti_gpio_pic_map_fdt()
901 else if (daf->cells[1] == 3) in ti_gpio_pic_map_fdt()
903 else if (daf->cells[1] == 4) in ti_gpio_pic_map_fdt()
905 else if (daf->cells[1] == 8) in ti_gpio_pic_map_fdt()
910 *irqp = daf->cells[0]; in ti_gpio_pic_map_fdt()
922 if (dag->gpio_pin_num >= sc->sc_maxpin) in ti_gpio_pic_map_gpio()
925 mode = dag->gpio_intr_mode; in ti_gpio_pic_map_gpio()
931 *irqp = dag->gpio_pin_num; in ti_gpio_pic_map_gpio()
942 switch (data->type) { in ti_gpio_pic_map()
955 ti_gpio_pic_map_intr(device_t dev, struct intr_map_data *data, in ti_gpio_pic_map_intr() argument
960 struct ti_gpio_softc *sc = device_get_softc(dev); in ti_gpio_pic_map_intr()
964 *isrcp = &sc->sc_isrcs[irq].tgi_isrc; in ti_gpio_pic_map_intr()
969 ti_gpio_pic_post_filter(device_t dev, struct intr_irqsrc *isrc) in ti_gpio_pic_post_filter() argument
971 struct ti_gpio_softc *sc = device_get_softc(dev); in ti_gpio_pic_post_filter()
979 ti_gpio_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc) in ti_gpio_pic_post_ithread() argument
982 ti_gpio_pic_enable_intr(dev, isrc); in ti_gpio_pic_post_ithread()
986 ti_gpio_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc) in ti_gpio_pic_pre_ithread() argument
988 struct ti_gpio_softc *sc = device_get_softc(dev); in ti_gpio_pic_pre_ithread()
997 ti_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc, in ti_gpio_pic_setup_intr() argument
1008 sc = device_get_softc(dev); in ti_gpio_pic_setup_intr()
1012 if (ti_gpio_pic_map(sc, data, &irq, &mode) != 0 || tgi->tgi_irq != irq) in ti_gpio_pic_setup_intr()
1016 * If this is a setup for another handler, in ti_gpio_pic_setup_intr()
1019 if (isrc->isrc_handlers != 0) in ti_gpio_pic_setup_intr()
1020 return (tgi->tgi_mode == mode ? 0 : EINVAL); in ti_gpio_pic_setup_intr()
1027 ti_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, in ti_gpio_pic_teardown_intr() argument
1030 struct ti_gpio_softc *sc = device_get_softc(dev); in ti_gpio_pic_teardown_intr()
1033 if (isrc->isrc_handlers == 0) in ti_gpio_pic_teardown_intr()
1039 ti_gpio_get_node(device_t bus, device_t dev) in ti_gpio_get_node() argument