-/* $OpenBSD: acpi.c,v 1.416 2022/09/10 13:18:31 kettenis Exp $ */
+/* $OpenBSD: acpi.c,v 1.417 2022/09/12 17:42:31 kettenis Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
struct acpi_gpio_event {
struct aml_node *node;
+ uint16_t tflags;
uint16_t pin;
};
void
acpi_gpio_event_task(void *arg0, int arg1)
{
- struct aml_node *node = arg0;
+ struct acpi_softc *sc = acpi_softc;
+ struct acpi_gpio_event *ev = arg0;
+ struct acpi_gpio *gpio = ev->node->gpio;
struct aml_value evt;
uint16_t pin = arg1;
char name[5];
if (pin < 256) {
- snprintf(name, sizeof(name), "_E%.2X", pin);
- if (aml_evalname(acpi_softc, node, name, 0, NULL, NULL) == 0)
- return;
+ if ((ev->tflags & LR_GPIO_MODE) == LR_GPIO_LEVEL) {
+ snprintf(name, sizeof(name), "_L%.2X", pin);
+ if (aml_evalname(sc, ev->node, name, 0, NULL, NULL)) {
+ if (gpio->intr_enable)
+ gpio->intr_enable(gpio->cookie, pin);
+ return;
+ }
+ } else {
+ snprintf(name, sizeof(name), "_E%.2X", pin);
+ if (aml_evalname(sc, ev->node, name, 0, NULL, NULL)) {
+ if (gpio->intr_enable)
+ gpio->intr_enable(gpio->cookie, pin);
+ return;
+ }
+ }
}
memset(&evt, 0, sizeof(evt));
evt.v_integer = pin;
evt.type = AML_OBJTYPE_INTEGER;
- aml_evalname(acpi_softc, node, "_EVT", 1, &evt, NULL);
+ aml_evalname(sc, ev->node, "_EVT", 1, &evt, NULL);
+ if ((ev->tflags & LR_GPIO_MODE) == LR_GPIO_LEVEL) {
+ if (gpio->intr_enable)
+ gpio->intr_enable(gpio->cookie, pin);
+ }
}
int
acpi_gpio_event(void *arg)
{
struct acpi_gpio_event *ev = arg;
+ struct acpi_gpio *gpio = ev->node->gpio;
- acpi_addtask(acpi_softc, acpi_gpio_event_task, ev->node, ev->pin);
+ if ((ev->tflags & LR_GPIO_MODE) == LR_GPIO_LEVEL) {
+ if(gpio->intr_disable)
+ gpio->intr_disable(gpio->cookie, ev->pin);
+ }
+ acpi_addtask(acpi_softc, acpi_gpio_event_task, ev, ev->pin);
acpi_wakeup(acpi_softc);
return 1;
}
ev = malloc(sizeof(*ev), M_DEVBUF, M_WAITOK);
ev->node = devnode;
+ ev->tflags = crs->lr_gpio.tflags;
ev->pin = pin;
gpio->intr_establish(gpio->cookie, pin,
crs->lr_gpio.tflags, acpi_gpio_event, ev);
-/* $OpenBSD: amltypes.h,v 1.48 2019/01/10 18:50:32 kettenis Exp $ */
+/* $OpenBSD: amltypes.h,v 1.49 2022/09/12 17:42:31 kettenis Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
*
int (*read_pin)(void *, int);
void (*write_pin)(void *, int, int);
void (*intr_establish)(void *, int, int, int (*)(void *), void *);
+ void (*intr_enable)(void *, int);
+ void (*intr_disable)(void *, int);
};
struct i2c_controller;
-/* $OpenBSD: qcgpio.c,v 1.4 2022/09/10 14:32:53 kettenis Exp $ */
+/* $OpenBSD: qcgpio.c,v 1.5 2022/09/12 17:42:31 kettenis Exp $ */
/*
* Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org>
*
int qcgpio_read_pin(void *, int);
void qcgpio_write_pin(void *, int, int);
void qcgpio_intr_establish(void *, int, int, int (*)(void *), void *);
+void qcgpio_intr_enable(void *, int);
+void qcgpio_intr_disable(void *, int);
int qcgpio_pin_intr(struct qcgpio_softc *, int);
int qcgpio_intr(void *);
sc->sc_gpio.read_pin = qcgpio_read_pin;
sc->sc_gpio.write_pin = qcgpio_write_pin;
sc->sc_gpio.intr_establish = qcgpio_intr_establish;
+ sc->sc_gpio.intr_enable = qcgpio_intr_enable;
+ sc->sc_gpio.intr_disable = qcgpio_intr_disable;
sc->sc_node->gpio = &sc->sc_gpio;
printf("\n");
qcgpio_sc7180_pin_map(int pin, bus_size_t *off)
{
switch (pin) {
+ case 30:
+ *off = QCGPIO_SC7180_SOUTH;
+ return 30;
case 33:
case 0x180:
*off = QCGPIO_SC7180_NORTH;
HWRITE4(sc, off + TLMM_GPIO_INTR_CFG(pin), reg);
}
+void
+qcgpio_intr_enable(void *cookie, int pin)
+{
+ struct qcgpio_softc *sc = cookie;
+ bus_size_t off = 0;
+
+ pin = sc->sc_pin_map(pin, &off);
+ if (pin < 0 || pin >= sc->sc_npins)
+ return;
+
+ HSET4(sc, off + TLMM_GPIO_INTR_CFG(pin),
+ TLMM_GPIO_INTR_CFG_INTR_ENABLE);
+}
+
+void
+qcgpio_intr_disable(void *cookie, int pin)
+{
+ struct qcgpio_softc *sc = cookie;
+ bus_size_t off = 0;
+
+ pin = sc->sc_pin_map(pin, &off);
+ if (pin < 0 || pin >= sc->sc_npins)
+ return;
+
+ HCLR4(sc, off + TLMM_GPIO_INTR_CFG(pin),
+ TLMM_GPIO_INTR_CFG_INTR_ENABLE);
+}
+
int
qcgpio_intr(void *arg)
{