Module Name:    src
Committed By:   jmcneill
Date:           Mon Dec  9 22:10:25 UTC 2024

Modified Files:
        src/sys/dev/acpi: acpi_gpio.c acpi_gpio.h acpivar.h qcomgpio.c
            qcomgpioreg.h

Log Message:
acpi: gpio: Pass the full ACPI_RESOURCE_GPIO to the translate callback.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/acpi/acpi_gpio.c \
    src/sys/dev/acpi/acpi_gpio.h src/sys/dev/acpi/qcomgpio.c \
    src/sys/dev/acpi/qcomgpioreg.h
cvs rdiff -u -r1.91 -r1.92 src/sys/dev/acpi/acpivar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/acpi/acpi_gpio.c
diff -u src/sys/dev/acpi/acpi_gpio.c:1.1 src/sys/dev/acpi/acpi_gpio.c:1.2
--- src/sys/dev/acpi/acpi_gpio.c:1.1	Sun Dec  8 20:49:14 2024
+++ src/sys/dev/acpi/acpi_gpio.c	Mon Dec  9 22:10:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_gpio.c,v 1.1 2024/12/08 20:49:14 jmcneill Exp $ */
+/* $NetBSD: acpi_gpio.c,v 1.2 2024/12/09 22:10:25 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2024 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_gpio.c,v 1.1 2024/12/08 20:49:14 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_gpio.c,v 1.2 2024/12/09 22:10:25 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/gpio.h>
@@ -45,7 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_gpio.c,
 
 int
 acpi_gpio_register(struct acpi_devnode *ad, device_t dev,
-    int (*translate)(void *, ACPI_INTEGER, void **), void *priv)
+    int (*translate)(void *, ACPI_RESOURCE_GPIO *, void **), void *priv)
 {
 	if (ad->ad_gpiodev != NULL) {
 		device_printf(dev, "%s already registered\n",
@@ -95,7 +95,7 @@ acpi_gpio_translate(ACPI_RESOURCE_GPIO *
 	}
 
 	xpin = gpioad->ad_gpio_translate(gpioad->ad_gpio_priv,
-	    res->PinTable[0], gpiop);
+	    res, gpiop);
 	if (xpin == -1) {
 		/* Pin could not be translated. */
 		return AE_NOT_IMPLEMENTED;
@@ -148,15 +148,15 @@ acpi_gpio_get_int(ACPI_HANDLE hdl, u_int
 	if (ACPI_FAILURE(rv)) {
 		return rv;
 	}
+	gpio = ctx.res;
 
-	rv = acpi_gpio_translate(ctx.res, gpiop, pin);
+	rv = acpi_gpio_translate(gpio, gpiop, pin);
 	if (ACPI_FAILURE(rv)) {
 		printf("%s: translate failed: %s\n", __func__,
 		    AcpiFormatException(rv));
 		return rv;
 	}
 
-	gpio = ctx.res;
         if (gpio->Triggering == ACPI_LEVEL_SENSITIVE) {
                 *irqmode = gpio->Polarity == ACPI_ACTIVE_HIGH ? 
                     GPIO_INTR_HIGH_LEVEL : GPIO_INTR_LOW_LEVEL;
@@ -176,7 +176,7 @@ acpi_gpio_get_int(ACPI_HANDLE hdl, u_int
 }
 
 ACPI_STATUS
-acpi_gpio_get_io(ACPI_HANDLE hdl, u_int index, void **gpio, int *pin)
+acpi_gpio_get_io(ACPI_HANDLE hdl, u_int index, void **gpiop, int *pin)
 {
 	struct acpi_gpio_resource_context ctx = {
 		.index = index,
@@ -189,5 +189,5 @@ acpi_gpio_get_io(ACPI_HANDLE hdl, u_int 
 		return rv;
 	}
 
-	return acpi_gpio_translate(ctx.res, gpio, pin);
+	return acpi_gpio_translate(ctx.res, gpiop, pin);
 }
Index: src/sys/dev/acpi/acpi_gpio.h
diff -u src/sys/dev/acpi/acpi_gpio.h:1.1 src/sys/dev/acpi/acpi_gpio.h:1.2
--- src/sys/dev/acpi/acpi_gpio.h:1.1	Sun Dec  8 20:49:14 2024
+++ src/sys/dev/acpi/acpi_gpio.h	Mon Dec  9 22:10:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_gpio.h,v 1.1 2024/12/08 20:49:14 jmcneill Exp $ */
+/* $NetBSD: acpi_gpio.h,v 1.2 2024/12/09 22:10:25 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2024 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #define _DEV_ACPI_ACPI_GPIO_H
 
 int		acpi_gpio_register(struct acpi_devnode *, device_t,
-				   int (*)(void *, ACPI_INTEGER, void **), void *);
+				   int (*)(void *, ACPI_RESOURCE_GPIO *, void **), void *);
 ACPI_STATUS	acpi_gpio_get_int(ACPI_HANDLE, u_int, void **, int *, int *);
 ACPI_STATUS	acpi_gpio_get_io(ACPI_HANDLE, u_int, void **, int *);
 
Index: src/sys/dev/acpi/qcomgpio.c
diff -u src/sys/dev/acpi/qcomgpio.c:1.1 src/sys/dev/acpi/qcomgpio.c:1.2
--- src/sys/dev/acpi/qcomgpio.c:1.1	Sun Dec  8 20:49:14 2024
+++ src/sys/dev/acpi/qcomgpio.c	Mon Dec  9 22:10:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: qcomgpio.c,v 1.1 2024/12/08 20:49:14 jmcneill Exp $ */
+/* $NetBSD: qcomgpio.c,v 1.2 2024/12/09 22:10:25 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2024 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: qcomgpio.c,v 1.1 2024/12/08 20:49:14 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: qcomgpio.c,v 1.2 2024/12/09 22:10:25 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -56,13 +56,14 @@ typedef enum {
 
 struct qcomgpio_config {
 	u_int	num_pins;
-	int	(*translate)(ACPI_INTEGER);
+	int	(*translate)(ACPI_RESOURCE_GPIO *);
 };
 
 struct qcomgpio_intr_handler {
 	int	(*ih_func)(void *);
 	void	*ih_arg;
 	int	ih_pin;
+	int	ih_type;
 	LIST_ENTRY(qcomgpio_intr_handler) ih_list;
 };
 
@@ -96,7 +97,7 @@ static bool	qcomgpio_intr_str(void *, in
 static void	qcomgpio_intr_mask(void *, void *);
 static void	qcomgpio_intr_unmask(void *, void *);
 
-static int	qcomgpio_acpi_translate(void *, ACPI_INTEGER, void **);
+static int	qcomgpio_acpi_translate(void *, ACPI_RESOURCE_GPIO *, void **);
 static void	qcomgpio_register_event(void *, struct acpi_event *,
 					ACPI_RESOURCE_GPIO *);
 static int	qcomgpio_intr(void *);
@@ -104,12 +105,18 @@ static int	qcomgpio_intr(void *);
 CFATTACH_DECL_NEW(qcomgpio, sizeof(struct qcomgpio_softc),
     qcomgpio_match, qcomgpio_attach, NULL, NULL);
 
+#define X1E_NUM_PINS	239
+
 static int
-qcomgpio_x1e_translate(ACPI_INTEGER val)
+qcomgpio_x1e_translate(ACPI_RESOURCE_GPIO *gpio)
 {
-	switch (val) {
-	case 0x33:
-		return 51;
+	const ACPI_INTEGER pin = gpio->PinTable[0];
+
+	if (pin < X1E_NUM_PINS) {
+		return gpio->PinTable[0];
+	}
+
+	switch (pin) {
 	case 0x180:
 		return 67;
 	case 0x380:
@@ -120,7 +127,7 @@ qcomgpio_x1e_translate(ACPI_INTEGER val)
 }
 
 static struct qcomgpio_config qcomgpio_x1e_config = {
-	.num_pins = 239,
+	.num_pins = X1E_NUM_PINS,
 	.translate = qcomgpio_x1e_translate,
 };
 
@@ -186,12 +193,35 @@ qcomgpio_attach(device_t parent, device_
 	sc->sc_pins = kmem_zalloc(sizeof(*sc->sc_pins) *
 	    sc->sc_config->num_pins, KM_SLEEP);
 	for (pin = 0; pin < sc->sc_config->num_pins; pin++) {
+#if notyet
+		uint32_t ctl, func;
+
+		aprint_debuf_dev(self, "pin %u: ", pin);
+		ctl = RD4(sc, TLMM_GPIO_CTL(pin));
+		func = __SHIFTOUT(ctl, TLMM_GPIO_CTL_MUX);
+
+		sc->sc_pins[pin].pin_caps = 0;
+		if (func == TLMM_GPIO_CTL_MUX_GPIO) {
+			if ((ctl & TLMM_GPIO_CTL_OE) != 0) {
+				sc->sc_pins[pin].pin_caps |= GPIO_PIN_OUTPUT;
+				aprint_debug("gpio output\n");
+			} else {
+				sc->sc_pins[pin].pin_caps |= GPIO_PIN_INPUT;
+				aprint_debug("gpio input\n");
+			}
+		} else {
+			aprint_debug("func %#x\n", func);
+		}
+#else
+		sc->sc_pins[pin].pin_caps =
+		    GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
+#endif
 		sc->sc_pins[pin].pin_num = pin;
-		sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
 		sc->sc_pins[pin].pin_intrcaps =
 		    GPIO_INTR_POS_EDGE | GPIO_INTR_NEG_EDGE |
 		    GPIO_INTR_DOUBLE_EDGE | GPIO_INTR_HIGH_LEVEL |
 		    GPIO_INTR_LOW_LEVEL | GPIO_INTR_MPSAFE;
+
 		/* It's not safe to read all pins, so leave pin state unknown */
 		sc->sc_pins[pin].pin_state = 0;
 	}
@@ -238,12 +268,13 @@ done:
 }
 
 static int
-qcomgpio_acpi_translate(void *priv, ACPI_INTEGER pin, void **gpiop)
+qcomgpio_acpi_translate(void *priv, ACPI_RESOURCE_GPIO *gpio, void **gpiop)
 {
 	struct qcomgpio_softc * const sc = priv;
+	const ACPI_INTEGER pin = gpio->PinTable[0];
 	int xpin;
 
-	xpin = sc->sc_config->translate(pin);
+	xpin = sc->sc_config->translate(gpio);
 
 	aprint_debug_dev(sc->sc_dev, "translate %#lx -> %u\n", pin, xpin);
 
@@ -278,7 +309,7 @@ qcomgpio_register_event(void *priv, stru
 	int irqmode;
 	void *ih;
 
-	const int pin = qcomgpio_acpi_translate(sc, gpio->PinTable[0], NULL);
+	const int pin = qcomgpio_acpi_translate(sc, gpio, NULL);
 
 	if (pin < 0) {
 		aprint_error_dev(sc->sc_dev,
@@ -308,6 +339,10 @@ qcomgpio_register_event(void *priv, stru
 		aprint_error_dev(sc->sc_dev,
 		    "couldn't register event for pin %#x\n",
 		    gpio->PinTable[0]);
+		return;
+	}
+	if (gpio->Triggering == ACPI_LEVEL_SENSITIVE) {
+		acpi_event_set_intrcookie(ev, ih);
 	}
 }
 
@@ -320,6 +355,9 @@ qcomgpio_pin_read(void *priv, int pin)
 	if (pin < 0 || pin >= sc->sc_config->num_pins) {
 		return 0;
 	}
+	if ((sc->sc_pins[pin].pin_caps & GPIO_PIN_INPUT) == 0) {
+		return 0;
+	}
 
 	val = RD4(sc, TLMM_GPIO_IN_OUT(pin));
 	return (val & TLMM_GPIO_IN_OUT_GPIO_IN) != 0;
@@ -334,6 +372,9 @@ qcomgpio_pin_write(void *priv, int pin, 
 	if (pin < 0 || pin >= sc->sc_config->num_pins) {
 		return;
 	}
+	if ((sc->sc_pins[pin].pin_caps & GPIO_PIN_OUTPUT) == 0) {
+		return;
+	}
 
 	val = RD4(sc, TLMM_GPIO_IN_OUT(pin));
 	if (pinval) {
@@ -372,6 +413,8 @@ qcomgpio_intr_establish(void *priv, int 
 	qih->ih_func = func;
 	qih->ih_arg = arg;
 	qih->ih_pin = pin;
+	qih->ih_type = (irqmode & GPIO_INTR_LEVEL_MASK) != 0 ?
+	    IST_LEVEL : IST_EDGE;
 
 	mutex_enter(&sc->sc_lock);
 
@@ -462,6 +505,9 @@ qcomgpio_intr_mask(void *priv, void *ih)
 	uint32_t val;
 
 	val = RD4(sc, TLMM_GPIO_INTR_CFG(qih->ih_pin));
+	if (qih->ih_type == IST_LEVEL) {
+		val &= ~TLMM_GPIO_INTR_CFG_INTR_RAW_STATUS_EN;
+	}
 	val &= ~TLMM_GPIO_INTR_CFG_INTR_ENABLE;
 	WR4(sc, TLMM_GPIO_INTR_CFG(qih->ih_pin), val);
 }
@@ -474,6 +520,9 @@ qcomgpio_intr_unmask(void *priv, void *i
 	uint32_t val;
 
 	val = RD4(sc, TLMM_GPIO_INTR_CFG(qih->ih_pin));
+	if (qih->ih_type == IST_LEVEL) {
+		val |= TLMM_GPIO_INTR_CFG_INTR_RAW_STATUS_EN;
+	}
 	val |= TLMM_GPIO_INTR_CFG_INTR_ENABLE;
 	WR4(sc, TLMM_GPIO_INTR_CFG(qih->ih_pin), val);
 }
Index: src/sys/dev/acpi/qcomgpioreg.h
diff -u src/sys/dev/acpi/qcomgpioreg.h:1.1 src/sys/dev/acpi/qcomgpioreg.h:1.2
--- src/sys/dev/acpi/qcomgpioreg.h:1.1	Sun Dec  8 20:49:14 2024
+++ src/sys/dev/acpi/qcomgpioreg.h	Mon Dec  9 22:10:25 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: qcomgpioreg.h,v 1.1 2024/12/08 20:49:14 jmcneill Exp $ */
+/* $NetBSD: qcomgpioreg.h,v 1.2 2024/12/09 22:10:25 jmcneill Exp $ */
 /*
  * Copyright (c) 2022 Mark Kettenis <kette...@openbsd.org>
  *
@@ -20,6 +20,11 @@
 
 #define _TLMM_GPIO_PIN_OFFSET(pin, reg)	((pin) * 0x1000 + (reg))
 
+#define TLMM_GPIO_CTL(pin)		_TLMM_GPIO_PIN_OFFSET(pin, 0x0)
+#define  TLMM_GPIO_CTL_OE			__BIT(9)
+#define  TLMM_GPIO_CTL_MUX			__BITS(5,2)
+#define   TLMM_GPIO_CTL_MUX_GPIO			0
+
 #define TLMM_GPIO_IN_OUT(pin)		_TLMM_GPIO_PIN_OFFSET(pin, 0x4)
 #define  TLMM_GPIO_IN_OUT_GPIO_IN		__BIT(0)
 #define  TLMM_GPIO_IN_OUT_GPIO_OUT		__BIT(1)

Index: src/sys/dev/acpi/acpivar.h
diff -u src/sys/dev/acpi/acpivar.h:1.91 src/sys/dev/acpi/acpivar.h:1.92
--- src/sys/dev/acpi/acpivar.h:1.91	Sun Dec  8 20:49:14 2024
+++ src/sys/dev/acpi/acpivar.h	Mon Dec  9 22:10:25 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: acpivar.h,v 1.91 2024/12/08 20:49:14 jmcneill Exp $	*/
+/*	$NetBSD: acpivar.h,v 1.92 2024/12/09 22:10:25 jmcneill Exp $	*/
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -136,7 +136,7 @@ struct acpi_devnode {
 	bus_dma_tag_t		 ad_dmat64;	/* Bus DMA tag for device (64-bit) */
 
 	device_t		ad_gpiodev;	/* GPIO controller device */
-	int			(*ad_gpio_translate)(void *, ACPI_INTEGER, void **);
+	int			(*ad_gpio_translate)(void *, ACPI_RESOURCE_GPIO *, void **);
 	void			*ad_gpio_priv;	/* private data for translate */
 
 	SIMPLEQ_ENTRY(acpi_devnode)	ad_list;

Reply via email to