Download raw body.
qcgpio(4) X1E support based on ACPI tables
> Date: Sun, 22 Dec 2024 10:51:35 +0100
> From: Marcus Glocker <marcus@nazgul.ch>
>
> patrick@ found a NetBSD commit which figured out how to map the GPIO
> pins based on the ACPI tables for X1E devices:
>
> https://github.com/NetBSD/src/commit/575554bd388d93cfff9174abadf2aab93fbfdf8e
>
> Currently we're only using hard coded mapping in qcgpio(4), which
> might not do the correct mapping, or miss some mappings.
>
> Following a diff which tries to adapt the NetBSD implementation in
> qcpgio(4) for X1E devices.
>
> Before I throw this diff in my attic, maybe some X1E users want to
> regression test it, or see if it even fixes some GPIO mappings.
>
> On my Samsung Galaxy Book4 Edge it causes no regression (keyboard and
> touch-pad still work). Unfortunately the touch-screen still doesn't
> work. I guess there is another issue with that.
I think this is useful to have. Tested this on my x13s (no change)
and my vivobook (no change apart from debug output).
ok kettenis@
--- dmesg.acpi.before Sun Dec 22 17:58:49 2024
+++ dmesg.acpi.after Sun Dec 22 18:16:37 2024
@@ -1,5 +1,5 @@
-OpenBSD 7.6-current (GENERIC.MP) #266: Fri Dec 20 22:58:05 MST 2024
- deraadt@arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP
+OpenBSD 7.6-current (GENERIC.MP) #1: Sun Dec 22 18:14:20 CET 2024
+ kettenis@massenet.sibelius.xs4all.nl:/home/kettenis/src/acpi/sys/arch/arm64/compile/GENERIC.MP
real mem = 16449925120 (15687MB)
avail mem = 15806259200 (15074MB)
random: good seed from bootblocks
@@ -100,7 +100,131 @@ qciic0 at acpi0 I2C6 addr 0xb94000/0x4000
iic0 at qciic0
### AML PARSE ERROR (0x3077d): Undefined name: OSYS
error evaluating: \\_SB_.WMIT._STA
-qcgpio0 at acpi0 GIO0 addr 0xf100000/0xf00000 irq 240
+qcgpio0 at acpi0 GIO0 addr 0xf100000/0xf00000
+qcgpio_acpi_attach: npdcmap=14
+qcgpio_get_irqs: irq index 0: irq 240
+qcgpio_get_irqs: irq index 1: irq 240
+qcgpio_get_irqs: irq index 2: irq 240
+qcgpio_get_irqs: irq index 3: irq 240
+qcgpio_get_irqs: irq index 4: irq 598
+qcgpio_get_irqs: irq index 5: irq 760
+qcgpio_get_irqs: irq index 6: irq 595
+qcgpio_get_irqs: irq index 7: irq 659
+qcgpio_get_irqs: irq index 8: irq 602
+qcgpio_get_irqs: irq index 9: irq 604
+qcgpio_get_irqs: irq index 10: irq 645
+qcgpio_get_irqs: irq index 11: irq 642
+qcgpio_get_irqs: irq index 12: irq 649
+qcgpio_get_irqs: irq index 13: irq 756
+qcgpio_fill_pdcmap: pdc index 0: probing irq 655, pin 38
+qcgpio_fill_pdcmap: pdc index 1: probing irq 654, pin 166
+qcgpio_fill_pdcmap: pdc index 2: probing irq 653, pin 221
+qcgpio_fill_pdcmap: pdc index 3: probing irq 652, pin 220
+qcgpio_fill_pdcmap: pdc index 4: probing irq 651, pin 217
+qcgpio_fill_pdcmap: pdc index 5: probing irq 650, pin 196
+qcgpio_fill_pdcmap: pdc index 6: probing irq 649, pin 157
+qcgpio_fill_pdcmap: pdc index 7: probing irq 648, pin 65
+qcgpio_fill_pdcmap: pdc index 8: probing irq 647, pin 156
+qcgpio_fill_pdcmap: pdc index 9: probing irq 646, pin 153
+qcgpio_fill_pdcmap: pdc index 10: probing irq 645, pin 151
+qcgpio_fill_pdcmap: pdc index 11: probing irq 644, pin 150
+qcgpio_fill_pdcmap: pdc index 12: probing irq 643, pin 181
+qcgpio_fill_pdcmap: pdc index 13: probing irq 642, pin 154
+qcgpio_fill_pdcmap: pdc index 14: probing irq 641, pin 172
+qcgpio_fill_pdcmap: pdc index 15: probing irq 605, pin 163
+qcgpio_fill_pdcmap: pdc index 16: probing irq 604, pin 148
+qcgpio_fill_pdcmap: pdc index 17: probing irq 603, pin 147
+qcgpio_fill_pdcmap: pdc index 18: probing irq 602, pin 145
+qcgpio_fill_pdcmap: pdc index 19: probing irq 601, pin 144
+qcgpio_fill_pdcmap: pdc index 20: probing irq 600, pin 141
+qcgpio_fill_pdcmap: pdc index 21: probing irq 599, pin 30
+qcgpio_fill_pdcmap: pdc index 22: probing irq 598, pin 71
+qcgpio_fill_pdcmap: pdc index 23: probing irq 597, pin 64
+qcgpio_fill_pdcmap: pdc index 24: probing irq 596, pin 53
+qcgpio_fill_pdcmap: pdc index 25: probing irq 595, pin 67
+qcgpio_fill_pdcmap: pdc index 26: probing irq 594, pin 59
+qcgpio_fill_pdcmap: pdc index 27: probing irq 593, pin 13
+qcgpio_fill_pdcmap: pdc index 28: probing irq 592, pin 11
+qcgpio_fill_pdcmap: pdc index 29: probing irq 591, pin 113
+qcgpio_fill_pdcmap: pdc index 30: probing irq 590, pin 134
+qcgpio_fill_pdcmap: pdc index 31: probing irq 589, pin 131
+qcgpio_fill_pdcmap: pdc index 32: probing irq 588, pin 55
+qcgpio_fill_pdcmap: pdc index 33: probing irq 587, pin 39
+qcgpio_fill_pdcmap: pdc index 34: probing irq 586, pin 51
+qcgpio_fill_pdcmap: pdc index 35: probing irq 585, pin 29
+qcgpio_fill_pdcmap: pdc index 36: probing irq 584, pin 28
+qcgpio_fill_pdcmap: pdc index 37: probing irq 583, pin 129
+qcgpio_fill_pdcmap: pdc index 38: probing irq 582, pin 125
+qcgpio_fill_pdcmap: pdc index 39: probing irq 581, pin 123
+qcgpio_fill_pdcmap: pdc index 40: probing irq 580, pin 121
+qcgpio_fill_pdcmap: pdc index 41: probing irq 579, pin 0
+qcgpio_fill_pdcmap: pdc index 42: probing irq 578, pin 3
+qcgpio_fill_pdcmap: pdc index 43: probing irq 577, pin 2
+qcgpio_fill_pdcmap: pdc index 44: probing irq 576, pin 19
+qcgpio_fill_pdcmap: pdc index 45: probing irq 575, pin 15
+qcgpio_fill_pdcmap: pdc index 46: probing irq 574, pin 7
+qcgpio_fill_pdcmap: pdc index 47: probing irq 850, pin 32
+qcgpio_fill_pdcmap: pdc index 48: probing irq 849, pin 27
+qcgpio_fill_pdcmap: pdc index 49: probing irq 848, pin 23
+qcgpio_fill_pdcmap: pdc index 50: probing irq 760, pin 66
+qcgpio_fill_pdcmap: pdc index 51: probing irq 759, pin 95
+qcgpio_fill_pdcmap: pdc index 52: probing irq 758, pin 94
+qcgpio_fill_pdcmap: pdc index 53: probing irq 757, pin 93
+qcgpio_fill_pdcmap: pdc index 54: probing irq 756, pin 92
+qcgpio_fill_pdcmap: pdc index 55: probing irq 755, pin 84
+qcgpio_fill_pdcmap: pdc index 56: probing irq 754, pin 230
+qcgpio_fill_pdcmap: pdc index 57: probing irq 753, pin 228
+qcgpio_fill_pdcmap: pdc index 58: probing irq 752, pin 208
+qcgpio_fill_pdcmap: pdc index 59: probing irq 751, pin 203
+qcgpio_fill_pdcmap: pdc index 60: probing irq 750, pin 225
+qcgpio_fill_pdcmap: pdc index 61: probing irq 749, pin 224
+qcgpio_fill_pdcmap: pdc index 62: probing irq 672, pin 34
+qcgpio_fill_pdcmap: pdc index 63: probing irq 671, pin 26
+qcgpio_fill_pdcmap: pdc index 64: probing irq 670, pin 81
+qcgpio_fill_pdcmap: pdc index 65: probing irq 668, pin 24
+qcgpio_fill_pdcmap: pdc index 66: probing irq 667, pin 80
+qcgpio_fill_pdcmap: pdc index 67: probing irq 666, pin 222
+qcgpio_fill_pdcmap: pdc index 68: probing irq 665, pin 6
+qcgpio_fill_pdcmap: pdc index 69: probing irq 664, pin 18
+qcgpio_fill_pdcmap: pdc index 70: probing irq 663, pin 214
+qcgpio_fill_pdcmap: pdc index 71: probing irq 662, pin 212
+qcgpio_fill_pdcmap: pdc index 72: probing irq 661, pin 219
+qcgpio_fill_pdcmap: pdc index 73: probing irq 660, pin 215
+qcgpio_fill_pdcmap: pdc index 74: probing irq 659, pin 193
+qcgpio_fill_pdcmap: pdc index 75: probing irq 658, pin 184
+qcgpio_fill_pdcmap: pdc index 76: probing irq 657, pin 33
+qcgpio_fill_pdcmap: pdc index 77: probing irq 656, pin 175
+qcgpio_fill_pdcmap: pdc index 78: probing irq 862, pin 91
+qcgpio_fill_pdcmap: pdc index 79: probing irq 861, pin 87
+qcgpio_fill_pdcmap: pdc index 80: probing irq 860, pin 85
+qcgpio_fill_pdcmap: pdc index 81: probing irq 859, pin 83
+qcgpio_fill_pdcmap: pdc index 82: probing irq 858, pin 79
+qcgpio_fill_pdcmap: pdc index 83: probing irq 857, pin 75
+qcgpio_fill_pdcmap: pdc index 84: probing irq 856, pin 68
+qcgpio_fill_pdcmap: pdc index 85: probing irq 855, pin 213
+qcgpio_fill_pdcmap: pdc index 86: probing irq 854, pin 47
+qcgpio_fill_pdcmap: pdc index 87: probing irq 853, pin 43
+qcgpio_fill_pdcmap: pdc index 88: probing irq 852, pin 36
+qcgpio_fill_pdcmap: pdc index 89: probing irq 851, pin 35
+qcgpio_fill_pdcmap: pdc index 90: probing irq 867, pin 232
+qcgpio_fill_pdcmap: pdc index 91: probing irq 864, pin 31
+qcgpio_fill_pdcmap: pdc index 92: probing irq 863, pin 21
+qcgpio_fill_pdcmap: irq index 0: irq=240, pin=-1
+qcgpio_fill_pdcmap: irq index 1: irq=240, pin=-1
+qcgpio_fill_pdcmap: irq index 2: irq=240, pin=-1
+qcgpio_fill_pdcmap: irq index 3: irq=240, pin=-1
+qcgpio_fill_pdcmap: irq index 4: irq=598, pin=71
+qcgpio_fill_pdcmap: irq index 5: irq=760, pin=66
+qcgpio_fill_pdcmap: irq index 6: irq=595, pin=67
+qcgpio_fill_pdcmap: irq index 7: irq=659, pin=193
+qcgpio_fill_pdcmap: irq index 8: irq=602, pin=145
+qcgpio_fill_pdcmap: irq index 9: irq=604, pin=148
+qcgpio_fill_pdcmap: irq index 10: irq=645, pin=151
+qcgpio_fill_pdcmap: irq index 11: irq=642, pin=154
+qcgpio_fill_pdcmap: irq index 12: irq=649, pin=157
+qcgpio_fill_pdcmap: irq index 13: irq=756, pin=92
+qcgpio_acpi_attach: npins=238
+ irq 240
ihidev0 at iic0 addr 0x3a gpio 384, vendor 0xb05 product 0x4543, QTEC0001
ihidev0: 90 report ids
hid at ihidev0 reportid 6 not configured
>
>
> Index: sys/dev/acpi/qcgpio.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/qcgpio.c,v
> diff -u -p -u -p -r1.11 qcgpio.c
> --- sys/dev/acpi/qcgpio.c 15 Jul 2024 15:33:54 -0000 1.11
> +++ sys/dev/acpi/qcgpio.c 15 Dec 2024 19:03:25 -0000
> @@ -25,6 +25,14 @@
> #include <dev/acpi/amltypes.h>
> #include <dev/acpi/dsdt.h>
>
> +#define QCGPIO_DEBUG
> +#ifdef QCGPIO_DEBUG
> +int qcgpio_debug = 1;
> +#define DPRINTF(l, x...) do { if ((l) <= qcgpio_debug) printf(x); } while (0)
> +#else
> +#define DPRINTF(l, x...)
> +#endif
> +
> /* Registers. */
> #define TLMM_GPIO_IN_OUT(pin) (0x0004 + 0x1000 * (pin))
> #define TLMM_GPIO_IN_OUT_GPIO_IN (1 << 0)
> @@ -62,6 +70,11 @@ struct qcgpio_intrhand {
> void *ih_arg;
> };
>
> +struct qcgpio_pdcmap {
> + int pm_pin;
> + uint32_t pm_irq;
> +};
> +
> struct qcgpio_softc {
> struct device sc_dev;
> struct acpi_softc *sc_acpi;
> @@ -73,10 +86,15 @@ struct qcgpio_softc {
> void *sc_ih;
>
> uint32_t sc_npins;
> - int (*sc_pin_map)(int, bus_size_t *);
> + int (*sc_pin_map)(struct qcgpio_softc *, int,
> + bus_size_t *);
> struct qcgpio_intrhand *sc_pin_ih;
>
> struct acpi_gpio sc_gpio;
> +
> + struct qcgpio_pdcmap *sc_pdcmap;
> + uint32_t sc_npdcmap;
> + uint32_t sc_ipdcmap;
> };
>
> int qcgpio_acpi_match(struct device *, void *, void *);
> @@ -97,9 +115,29 @@ const char *qcgpio_hids[] = {
> NULL
> };
>
> -int qcgpio_sc7180_pin_map(int, bus_size_t *);
> -int qcgpio_sc8280xp_pin_map(int, bus_size_t *);
> -int qcgpio_x1e80100_pin_map(int, bus_size_t *);
> +/* 98b9b2a4-1663-4a5f-82f2-c6c99a394726 */
> +static uint8_t qcgpio_gpio_dsm_uuid[] = {
> + 0xa4, 0xb2, 0xb9, 0x98, 0x63, 0x16, 0x5f, 0x4a,
> + 0x82, 0xf2, 0xc6, 0xc9, 0x9a, 0x39, 0x47, 0x26
> +};
> +#define QCGPIO_GPIO_DSM_REV 0
> +#define QCGPIO_GPIO_DSM_FUNC_NUM_PINS 2
> +
> +/* 921b0fd4-567c-43a0-bb14-2648f7b2a18c */
> +static uint8_t qcgpio_pdc_dsm_uuid[] = {
> + 0xd4, 0x0f, 0x1b, 0x92, 0x7c, 0x56, 0xa0, 0x43,
> + 0xbb, 0x14, 0x26, 0x48, 0xf7, 0xb2, 0xa1, 0x8c
> +};
> +#define QCGPIO_PDC_DSM_REV 0
> +#define QCGPIO_PDC_DSM_FUNC_CIPR 2
> +
> +int qcgpio_get_nirq(int, union acpi_resource *, void *);
> +int qcgpio_get_irqs(int, union acpi_resource *, void *);
> +void qcgpio_fill_pdcmap(struct qcgpio_softc *);
> +int qcgpio_get_pin_count(struct acpi_softc *, struct aml_node *);
> +int qcgpio_sc7180_pin_map(struct qcgpio_softc *, int, bus_size_t *);
> +int qcgpio_sc8280xp_pin_map(struct qcgpio_softc *, int, bus_size_t *);
> +int qcgpio_x1e80100_pin_map(struct qcgpio_softc *, int, bus_size_t *);
>
> int qcgpio_read_pin(void *, int);
> void qcgpio_write_pin(void *, int, int);
> @@ -109,6 +147,137 @@ void qcgpio_intr_disable(void *, int);
> int qcgpio_intr(void *);
>
> int
> +qcgpio_get_nirq(int crsidx, union acpi_resource *crs, void *arg)
> +{
> + struct qcgpio_softc *sc = arg;
> + int typ;
> +
> + typ = AML_CRSTYPE(crs);
> +
> + switch (typ) {
> + case LR_EXTIRQ:
> + sc->sc_npdcmap++;
> + break;
> + }
> +
> + return 0;
> +}
> +
> +int
> +qcgpio_get_irqs(int crsidx, union acpi_resource *crs, void *arg)
> +{
> + struct qcgpio_softc *sc = arg;
> + int typ;
> +
> + typ = AML_CRSTYPE(crs);
> +
> + switch (typ) {
> + case LR_EXTIRQ:
> + sc->sc_pdcmap[sc->sc_ipdcmap].pm_irq = crs->lr_extirq.irq[0];
> + sc->sc_pdcmap[sc->sc_ipdcmap].pm_pin = -1;
> + DPRINTF(1, "%s: irq index %d: irq %d\n",
> + __func__, sc->sc_ipdcmap,
> + sc->sc_pdcmap[sc->sc_ipdcmap].pm_irq);
> + sc->sc_ipdcmap++;
> + break;
> + }
> +
> + return 0;
> +}
> +
> +void
> +qcgpio_fill_pdcmap(struct qcgpio_softc *sc)
> +{
> + struct aml_value cmd[4], res, *ref;
> + int i, j, pin;
> + uint32_t irq;
> +
> + bzero(&cmd, sizeof(cmd));
> + cmd[0].type = AML_OBJTYPE_BUFFER;
> + cmd[0].v_buffer = (uint8_t *)&qcgpio_pdc_dsm_uuid;
> + cmd[0].length = sizeof(qcgpio_pdc_dsm_uuid);
> + /* rev */
> + cmd[1].type = AML_OBJTYPE_INTEGER;
> + cmd[1].v_integer = QCGPIO_PDC_DSM_REV;
> + cmd[1].length = 1;
> + /* func */
> + cmd[2].type = AML_OBJTYPE_INTEGER;
> + cmd[2].v_integer = QCGPIO_PDC_DSM_FUNC_CIPR;
> + cmd[2].length = 1;
> + /* not used */
> + cmd[3].type = AML_OBJTYPE_PACKAGE;
> + cmd[3].v_integer = 0;
> + cmd[3].length = 0;
> +
> + if (aml_evalname(sc->sc_acpi, sc->sc_node, "_DSM", 4, cmd, &res)) {
> + printf("%s: PDC _DSM failed\n", __func__);
> + return;
> + }
> +
> + for (i = 0; i < res.length; i++) {
> + ref = res.v_package[i];
> +
> + if (ref->type != AML_OBJTYPE_PACKAGE ||
> + ref->length < 3 ||
> + ref->v_package[0]->type != AML_OBJTYPE_INTEGER ||
> + ref->v_package[1]->type != AML_OBJTYPE_INTEGER ||
> + ref->v_package[2]->type != AML_OBJTYPE_INTEGER) {
> + continue;
> + }
> +
> + irq = ref->v_package[2]->v_integer;
> + pin = ref->v_package[1]->v_integer;
> + DPRINTF(1, "%s: pdc index %d: probing irq %d, pin %d\n",
> + __func__, i, irq, pin);
> +
> + for (j = 0; j < sc->sc_npdcmap; j++) {
> + if (sc->sc_pdcmap[j].pm_irq == irq) {
> + sc->sc_pdcmap[j].pm_pin = pin;
> + break;
> + }
> + }
> + }
> +#ifdef QCGPIO_DEBUG
> + for (i = 0; i < sc->sc_npdcmap; i++) {
> + printf("%s: irq index %d: irq=%d, pin=%d\n",
> + __func__, i, sc->sc_pdcmap[i].pm_irq,
> + sc->sc_pdcmap[i].pm_pin);
> + }
> +#endif
> +}
> +
> +int
> +qcgpio_get_pin_count(struct acpi_softc *sc, struct aml_node *node)
> +{
> + struct aml_value cmd[4];
> + int64_t npins;
> +
> + bzero(&cmd, sizeof(cmd));
> + cmd[0].type = AML_OBJTYPE_BUFFER;
> + cmd[0].v_buffer = (uint8_t *)&qcgpio_gpio_dsm_uuid;
> + cmd[0].length = sizeof(qcgpio_gpio_dsm_uuid);
> + /* rev */
> + cmd[1].type = AML_OBJTYPE_INTEGER;
> + cmd[1].v_integer = QCGPIO_GPIO_DSM_REV;
> + cmd[1].length = 1;
> + /* func */
> + cmd[2].type = AML_OBJTYPE_INTEGER;
> + cmd[2].v_integer = QCGPIO_GPIO_DSM_FUNC_NUM_PINS;
> + cmd[2].length = 1;
> + /* not used */
> + cmd[3].type = AML_OBJTYPE_PACKAGE;
> + cmd[3].v_integer = 0;
> + cmd[3].length = 0;
> +
> + if (aml_evalinteger(sc, node, "_DSM", 4, cmd, &npins)) {
> + printf("%s: GPIO _DSM failed\n", __func__);
> + return 0;
> + }
> +
> + return (uint32_t)npins;
> +}
> +
> +int
> qcgpio_acpi_match(struct device *parent, void *match, void *aux)
> {
> struct acpi_attach_args *aaa = aux;
> @@ -124,6 +293,7 @@ qcgpio_acpi_attach(struct device *parent
> {
> struct acpi_attach_args *aaa = aux;
> struct qcgpio_softc *sc = (struct qcgpio_softc *)self;
> + struct aml_value res;
>
> sc->sc_acpi = (struct acpi_softc *)parent;
> sc->sc_node = aaa->aaa_node;
> @@ -145,7 +315,25 @@ qcgpio_acpi_attach(struct device *parent
> sc->sc_npins = 228;
> sc->sc_pin_map = qcgpio_sc8280xp_pin_map;
> } else if (strcmp(aaa->aaa_dev, "QCOM0C0C") == 0) {
> - sc->sc_npins = 239;
> + if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL,
> + &res)) {
> + printf("no _CRS method\n");
> + return;
> + }
> + if (res.type != AML_OBJTYPE_BUFFER || res.length < 5) {
> + printf("invalid _CRS object\n");
> + aml_freevalue(&res);
> + return;
> + }
> + aml_parse_resource(&res, qcgpio_get_nirq, sc);
> + DPRINTF(1, "\n%s: npdcmap=%d\n", __func__, sc->sc_npdcmap);
> + sc->sc_pdcmap = mallocarray(sc->sc_npdcmap,
> + sizeof(*sc->sc_pdcmap), M_DEVBUF, M_WAITOK | M_ZERO);
> + aml_parse_resource(&res, qcgpio_get_irqs, sc);
> + aml_freevalue(&res);
> + qcgpio_fill_pdcmap(sc);
> + sc->sc_npins = qcgpio_get_pin_count(sc->sc_acpi, sc->sc_node);
> + DPRINTF(1, "%s: npins=%d\n", __func__, sc->sc_npins);
> sc->sc_pin_map = qcgpio_x1e80100_pin_map;
> }
> KASSERT(sc->sc_npins != 0);
> @@ -180,11 +368,12 @@ unmap:
> if (sc->sc_ih)
> acpi_intr_disestablish(sc->sc_ih);
> free(sc->sc_pin_ih, M_DEVBUF, sc->sc_npins * sizeof(*sc->sc_pin_ih));
> + free(sc->sc_pdcmap, M_DEVBUF, sc->sc_npdcmap * sizeof(*sc->sc_pdcmap));
> bus_space_unmap(sc->sc_iot, sc->sc_ioh, aaa->aaa_size[0]);
> }
>
> int
> -qcgpio_sc7180_pin_map(int pin, bus_size_t *off)
> +qcgpio_sc7180_pin_map(struct qcgpio_softc *sc, int pin, bus_size_t *off)
> {
> switch (pin) {
> case 30:
> @@ -211,7 +400,7 @@ qcgpio_sc7180_pin_map(int pin, bus_size_
> }
>
> int
> -qcgpio_sc8280xp_pin_map(int pin, bus_size_t *off)
> +qcgpio_sc8280xp_pin_map(struct qcgpio_softc *sc, int pin, bus_size_t *off)
> {
> switch (pin) {
> case 107:
> @@ -229,21 +418,19 @@ qcgpio_sc8280xp_pin_map(int pin, bus_siz
> }
>
> int
> -qcgpio_x1e80100_pin_map(int pin, bus_size_t *off)
> +qcgpio_x1e80100_pin_map(struct qcgpio_softc *sc, int pin, bus_size_t *off)
> {
> - switch (pin) {
> - case 3:
> - case 51:
> - return pin;
> - case 0x180:
> - return 67;
> - case 0x380:
> - return 33;
> - case 0x3c0:
> - return 3;
> - default:
> - return -1;
> + int real_pin = -1;
> +
> + if (pin < sc->sc_npins) {
> + real_pin = pin;
> + } else if (pin / 64 < sc->sc_npdcmap) {
> + real_pin = sc->sc_pdcmap[pin / 64].pm_pin;
> }
> +
> + DPRINTF(2, "%s: map pin %d to real_pin %d\n", __func__, pin, real_pin);
> +
> + return real_pin;
> }
>
> int
> @@ -253,7 +440,7 @@ qcgpio_read_pin(void *cookie, int pin)
> bus_size_t off = 0;
> uint32_t reg;
>
> - pin = sc->sc_pin_map(pin, &off);
> + pin = sc->sc_pin_map(sc, pin, &off);
> if (pin < 0 || pin >= sc->sc_npins)
> return 0;
>
> @@ -267,7 +454,7 @@ qcgpio_write_pin(void *cookie, int pin,
> struct qcgpio_softc *sc = cookie;
> bus_size_t off = 0;
>
> - pin = sc->sc_pin_map(pin, &off);
> + pin = sc->sc_pin_map(sc, pin, &off);
> if (pin < 0 || pin >= sc->sc_npins)
> return;
>
> @@ -288,7 +475,7 @@ qcgpio_intr_establish(void *cookie, int
> bus_size_t off = 0;
> uint32_t reg;
>
> - pin = sc->sc_pin_map(pin, &off);
> + pin = sc->sc_pin_map(sc, pin, &off);
> if (pin < 0 || pin >= sc->sc_npins)
> return;
>
> @@ -335,7 +522,7 @@ qcgpio_intr_enable(void *cookie, int pin
> struct qcgpio_softc *sc = cookie;
> bus_size_t off = 0;
>
> - pin = sc->sc_pin_map(pin, &off);
> + pin = sc->sc_pin_map(sc, pin, &off);
> if (pin < 0 || pin >= sc->sc_npins)
> return;
>
> @@ -349,7 +536,7 @@ qcgpio_intr_disable(void *cookie, int pi
> struct qcgpio_softc *sc = cookie;
> bus_size_t off = 0;
>
> - pin = sc->sc_pin_map(pin, &off);
> + pin = sc->sc_pin_map(sc, pin, &off);
> if (pin < 0 || pin >= sc->sc_npins)
> return;
>
> @@ -369,7 +556,7 @@ qcgpio_intr(void *arg)
> if (sc->sc_pin_ih[pin].ih_func == NULL)
> continue;
>
> - sc->sc_pin_map(pin, &off);
> + sc->sc_pin_map(sc, pin, &off);
>
> stat = HREAD4(sc, off + TLMM_GPIO_INTR_STATUS(pin));
> if (stat & TLMM_GPIO_INTR_STATUS_INTR_STATUS) {
>
>
qcgpio(4) X1E support based on ACPI tables