Module Name:    src
Committed By:   manu
Date:           Thu Mar 24 02:24:25 UTC 2022

Modified Files:
        src/sys/arch/amd64/conf: GENERIC
        src/sys/conf: files
        src/sys/dev/acpi: files.acpi
Added Files:
        src/sys/dev/acpi: igpio_acpi.c
        src/sys/dev/ic: igpio.c igpioreg.h igpiovar.h

Log Message:
Add initial support for Intel GPIO chips


To generate a diff of this commit:
cvs rdiff -u -r1.593 -r1.594 src/sys/arch/amd64/conf/GENERIC
cvs rdiff -u -r1.1295 -r1.1296 src/sys/conf/files
cvs rdiff -u -r1.124 -r1.125 src/sys/dev/acpi/files.acpi
cvs rdiff -u -r0 -r1.1 src/sys/dev/acpi/igpio_acpi.c
cvs rdiff -u -r0 -r1.1 src/sys/dev/ic/igpio.c src/sys/dev/ic/igpioreg.h \
    src/sys/dev/ic/igpiovar.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/arch/amd64/conf/GENERIC
diff -u src/sys/arch/amd64/conf/GENERIC:1.593 src/sys/arch/amd64/conf/GENERIC:1.594
--- src/sys/arch/amd64/conf/GENERIC:1.593	Sun Oct 31 00:31:48 2021
+++ src/sys/arch/amd64/conf/GENERIC	Thu Mar 24 02:24:24 2022
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.593 2021/10/31 00:31:48 simonb Exp $
+# $NetBSD: GENERIC,v 1.594 2022/03/24 02:24:24 manu Exp $
 #
 # GENERIC machine description file
 #
@@ -22,7 +22,7 @@ include 	"arch/amd64/conf/std.amd64"
 
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident		"GENERIC-$Revision: 1.593 $"
+#ident		"GENERIC-$Revision: 1.594 $"
 
 maxusers	64		# estimated number of users
 
@@ -596,6 +596,9 @@ iic*		at dwiic?
 #sdtemp* at iic? addr 0x1e
 #sdtemp* at iic? addr 0x1f
 
+# Intel GPIO
+igpio*         at acpi? 
+
 # I2C HID devices
 ihidev* at iic?
 

Index: src/sys/conf/files
diff -u src/sys/conf/files:1.1295 src/sys/conf/files:1.1296
--- src/sys/conf/files:1.1295	Wed Feb 16 20:14:30 2022
+++ src/sys/conf/files	Thu Mar 24 02:24:24 2022
@@ -1,4 +1,4 @@
-#	$NetBSD: files,v 1.1295 2022/02/16 20:14:30 riastradh Exp $
+#	$NetBSD: files,v 1.1296 2022/03/24 02:24:24 manu Exp $
 #	@(#)files.newconf	7.5 (Berkeley) 5/10/93
 
 version 	20171118
@@ -1357,6 +1357,10 @@ file	dev/ic/pl061.c			plgpio
 device	plmmc: sdmmcbus
 file	dev/ic/pl181.c			plmmc
 
+# Intel GPIO
+device	igpio: gpiobus
+file	dev/ic/igpio.c			igpio
+
 # Myson MTD803 3-in-1 Fast Ethernet Controller
 device	mtd: arp, ether, ifnet, mii
 file	dev/ic/mtd803.c			mtd

Index: src/sys/dev/acpi/files.acpi
diff -u src/sys/dev/acpi/files.acpi:1.124 src/sys/dev/acpi/files.acpi:1.125
--- src/sys/dev/acpi/files.acpi:1.124	Wed Feb 16 20:14:30 2022
+++ src/sys/dev/acpi/files.acpi	Thu Mar 24 02:24:25 2022
@@ -1,4 +1,4 @@
-#	$NetBSD: files.acpi,v 1.124 2022/02/16 20:14:30 riastradh Exp $
+#	$NetBSD: files.acpi,v 1.125 2022/03/24 02:24:25 manu Exp $
 
 defflag	opt_acpi.h	ACPIVERBOSE ACPI_DEBUG ACPI_ACTIVATE_DEV
 			ACPI_DSDT_OVERRIDE ACPI_SCANPCI ACPI_BREAKPOINT
@@ -300,6 +300,10 @@ file	dev/acpi/genet_acpi.c		genet_acpi
 attach	eqos at acpinodebus with eqos_acpi
 file	dev/acpi/eqos_acpi.c		eqos_acpi
 
+# Intel GPIO
+attach	igpio at acpinodebus with igpio_acpi
+file	dev/acpi/igpio_acpi.c		igpio_acpi
+
 # DesignWare Mobile Storage Host Controller
 attach	dwcmmc at acpinodebus with dwcmmc_acpi
 file	dev/acpi/dwcmmc_acpi.c		dwcmmc_acpi

Added files:

Index: src/sys/dev/acpi/igpio_acpi.c
diff -u /dev/null src/sys/dev/acpi/igpio_acpi.c:1.1
--- /dev/null	Thu Mar 24 02:24:25 2022
+++ src/sys/dev/acpi/igpio_acpi.c	Thu Mar 24 02:24:25 2022
@@ -0,0 +1,237 @@
+/* $NetBSD: igpio_acpi.c,v 1.1 2022/03/24 02:24:25 manu Exp $ */
+
+/*-
+ * Copyright (c) 2021,2022 Emmanuel Dreyfus
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: igpio_acpi.c,v 1.1 2022/03/24 02:24:25 manu Exp $");
+
+#include <sys/param.h>
+#include <sys/kmem.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/device.h>
+#include <sys/gpio.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpi_intr.h>
+#include <dev/acpi/acpi_event.h>
+
+#include <dev/gpio/gpiovar.h>
+#include <dev/ic/igpiovar.h>
+
+struct igpio_acpi_softc {
+	ACPI_HANDLE		sc_handle;
+	struct igpio_softc	sc_isc;
+	struct acpi_event *	sc_event[8];
+	int			sc_pmf;
+	void			*sc_intr;
+};
+
+static int	igpio_acpi_match(device_t, cfdata_t, void *);
+static void	igpio_acpi_attach(device_t, device_t, void *);
+static int	igpio_acpi_detach(device_t, int);
+
+static void	igpio_acpi_register_event(void *, struct acpi_event *, ACPI_RESOURCE_GPIO *);
+static int	igpio_acpi_intr(void *);
+
+CFATTACH_DECL_NEW(igpio_acpi, sizeof(struct igpio_acpi_softc), igpio_acpi_match, igpio_acpi_attach, igpio_acpi_detach, NULL);
+
+static const struct device_compatible_entry compat_data[] = {
+	{ .compat = "INT33B2" },	/* baytrail */
+	{ .compat = "INT33C7" },	/* lynxpoint */
+	{ .compat = "INT33FC" },	/* baytrail */
+	{ .compat = "INT3437" },	/* lynxpoint */
+	{ .compat = "INT344B" },	/* sunrisepoint */
+	{ .compat = "INT3450" },	/* cannonlake */
+	{ .compat = "INT3451" },	/* sunrisepoint */
+	{ .compat = "INT3453" },	/* geminilake */
+	{ .compat = "INT3455" },	/* icelake */
+	{ .compat = "INT345D" },	/* sunrisepoint */
+	{ .compat = "INT34BB" },	/* cannonlake */
+	{ .compat = "INT34C4" },	/* lakefield */
+	{ .compat = "INT34C5" },	/* tigerlake */
+	{ .compat = "INT34C6" },	/* tigerlake */
+	{ .compat = "INT34C8" },	/* jasperlake */
+	{ .compat = "INT3536" },	/* lewisburg */
+	{ .compat = "INTC1055" },	/* tigerlake */
+	{ .compat = "INTC1056" },	/* alderlake */
+	{ .compat = "INTC1057" },	/* tigerlake */
+	{ .compat = "INTC1071" },	/* emmitsburg */
+	{ .compat = "INTC3000" },	/* denverton */
+	{ .compat = "INTC3001" },	/* cedarfork */
+#ifdef notyet
+	/*
+	 * Complete bank setup in src/sys/dev/ic/igpioreg.h
+	 * before enabling
+	 */
+	{ .compat = "INT3452" },	/* broxton */
+	{ .compat = "INT34D1" },	/* broxton */
+	{ .compat = "apollolake-pinctrl" },	/* broxton */
+	{ .compat = "broxton-pinctrl" },	/* broxton */
+	{ .compat = "INT33FF" },	/* cherryview */
+#endif
+	DEVICE_COMPAT_EOL
+};
+
+static int
+igpio_acpi_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct acpi_attach_args *aa = aux;
+
+	return acpi_compatible_match(aa, compat_data);
+}
+
+static void
+igpio_acpi_attach(device_t parent, device_t self, void *aux)
+{
+	struct igpio_acpi_softc * const asc = device_private(self);
+	struct acpi_attach_args *aa = aux;
+	ACPI_DEVICE_INFO *ad = aa->aa_node->ad_devinfo;
+	struct acpi_resources res;
+	struct acpi_mem *mem;
+	struct acpi_irq *irq;
+	int nbar;
+	ACPI_STATUS rv;
+	int i;
+
+	asc->sc_handle = aa->aa_node->ad_handle;
+
+	rv = acpi_resource_parse(self, aa->aa_node->ad_handle, "_CRS",
+	    &res, &acpi_resource_parse_ops_default);
+	if (ACPI_FAILURE(rv))
+		return;
+
+	irq = acpi_res_irq(&res, 0);
+	if (irq == NULL) {
+		aprint_error_dev(self, "couldn't find irq resource\n");
+		goto done;
+	}
+
+	asc->sc_isc.sc_dev = self;
+
+	asc->sc_isc.sc_bst = aa->aa_memt;
+	for (nbar = 0; acpi_res_mem(&res, nbar); nbar++);
+	asc->sc_isc.sc_nbar = nbar;
+	asc->sc_isc.sc_base = 
+	    kmem_zalloc(sizeof(*asc->sc_isc.sc_base) * nbar, KM_SLEEP);
+	asc->sc_isc.sc_length = 
+	    kmem_zalloc(sizeof(*asc->sc_isc.sc_length) * nbar, KM_SLEEP);
+	asc->sc_isc.sc_bsh = 
+	    kmem_zalloc(sizeof(*asc->sc_isc.sc_bsh) * nbar, KM_SLEEP);
+
+	asc->sc_isc.sc_acpi_hid = ad->HardwareId.String;
+
+	for (i = 0; i < nbar; i++) {
+		mem = acpi_res_mem(&res, i);
+		if (mem == NULL) {
+			aprint_error_dev(self, "couldn't find mem resource\n");
+			goto done;
+		}
+
+		asc->sc_isc.sc_base[i] = mem->ar_base;
+		asc->sc_isc.sc_length[i] = mem->ar_length;
+	}
+
+	igpio_attach(&asc->sc_isc);
+	
+	/* If attachement failed */
+	if (asc->sc_isc.sc_banks == NULL) {
+		igpio_acpi_detach(self, 0);
+		goto done;
+	}
+
+	rv = acpi_event_create_gpio(self, asc->sc_handle, igpio_acpi_register_event, asc);
+	if (ACPI_FAILURE(rv)) {
+		if (rv != AE_NOT_FOUND)
+			aprint_error_dev(self, "failed to create events: %s\n", AcpiFormatException(rv));
+		goto done;
+	}
+
+	asc->sc_intr = acpi_intr_establish(self,
+	    (uint64_t)(uintptr_t)asc->sc_handle,
+	    IPL_VM, false, igpio_acpi_intr, asc, device_xname(self));
+	if (asc->sc_intr == NULL)
+		aprint_error_dev(self, "couldn't establish interrupt\n");
+
+done:
+	acpi_resource_cleanup(&res);
+	(void)pmf_device_register(self, NULL, NULL);
+	asc->sc_pmf = 1;
+}
+
+static int
+igpio_acpi_detach(device_t self, int flags)
+{
+	struct igpio_acpi_softc * const asc = device_private(self);
+	struct igpio_softc * const isc = &asc->sc_isc;
+	int nbar = isc->sc_nbar;
+
+	acpi_intr_disestablish(asc->sc_intr);
+
+	igpio_detach(&asc->sc_isc);
+
+	if (isc->sc_base != NULL) {	
+		kmem_free(isc->sc_base, sizeof(*isc->sc_base) * nbar);
+		isc->sc_base = NULL;
+	}
+	
+	if (isc->sc_length != NULL) {
+		kmem_free(isc->sc_length, sizeof(*isc->sc_length) * nbar);
+		isc->sc_length = NULL;
+	}
+
+	if (isc->sc_bsh != NULL) {
+		kmem_free(isc->sc_bsh, sizeof(*isc->sc_bsh) * nbar);
+		isc->sc_length = NULL;
+	}
+
+	if (asc->sc_pmf) {
+		pmf_device_deregister(self);
+		asc->sc_pmf = 0;
+	}
+
+	return 0;
+}
+
+static void
+igpio_acpi_register_event(void *priv, struct acpi_event *ev, ACPI_RESOURCE_GPIO *gpio)
+{
+	return;
+}
+
+static int
+igpio_acpi_intr(void *priv)
+{
+	struct igpio_acpi_softc *asc = priv;
+	struct igpio_softc * const isc = &asc->sc_isc;
+	int ret;	
+
+	ret = igpio_intr(isc);
+	
+	return ret;
+}

Index: src/sys/dev/ic/igpio.c
diff -u /dev/null src/sys/dev/ic/igpio.c:1.1
--- /dev/null	Thu Mar 24 02:24:25 2022
+++ src/sys/dev/ic/igpio.c	Thu Mar 24 02:24:25 2022
@@ -0,0 +1,806 @@
+/* $NetBSD: igpio.c,v 1.1 2022/03/24 02:24:25 manu Exp $ */
+
+/*
+ * Copyright (c) 2021,2022 Emmanuel Dreyfus
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/kmem.h>
+#include <sys/endian.h>
+#include <sys/gpio.h>
+
+#include <dev/gpio/gpiovar.h>
+#include "gpio.h"
+
+#include <dev/ic/igpiovar.h>
+#include <dev/ic/igpioreg.h>
+
+struct igpio_intr {
+	int (*ii_func)(void *);
+	void *ii_arg;
+	struct igpio_bank *ii_bank;
+	int ii_pin;
+};
+
+struct igpio_bank {
+	int ib_barno;
+	int ib_revid;
+	int ib_cap;
+	int ib_padbar;
+	struct igpio_bank_setup *ib_setup;
+	struct igpio_softc *ib_sc;
+	struct igpio_intr *ib_intr;
+	kmutex_t ib_mtx;
+};
+
+
+static int igpio_debug = 0;
+#define DPRINTF(x) if (igpio_debug) printf x;
+
+static char *
+igpio_padcfg0_print(uint32_t val, int idx)
+{
+	uint32_t rxev, pmode;
+	static char buf0[256];
+	static char buf1[256];
+	char *buf = (idx % 2) ? &buf0[0] : &buf1[0];
+	size_t len = sizeof(buf0) - 1;
+	size_t wr = 0;
+	uint32_t unknown_bits = 
+	    __BITS(3,7)|__BITS(14,16)|__BITS(21,22)|__BITS(27,31);
+	int b;
+
+	rxev = 
+	    (val & IGPIO_PADCFG0_RXEVCFG_MASK) >> IGPIO_PADCFG0_RXEVCFG_SHIFT;
+	wr += snprintf(buf + wr, len - wr, "rxev ");
+	switch (rxev) {
+	case IGPIO_PADCFG0_RXEVCFG_LEVEL:
+		wr += snprintf(buf + wr, len - wr, "level");
+		break;
+	case IGPIO_PADCFG0_RXEVCFG_EDGE:
+		wr += snprintf(buf + wr, len - wr, "edge");
+		break;
+	case IGPIO_PADCFG0_RXEVCFG_DISABLED:
+		wr += snprintf(buf + wr, len - wr, "disabled");
+		break;
+	case IGPIO_PADCFG0_RXEVCFG_EDGE_BOTH:
+		wr += snprintf(buf + wr, len - wr, "edge both");
+		break;
+	default:
+		break;
+	}
+
+	if (val & IGPIO_PADCFG0_PREGFRXSEL)
+		wr += snprintf(buf + wr, len - wr, ", pregfrxsel");
+
+	if (val & IGPIO_PADCFG0_RXINV)
+		wr += snprintf(buf + wr, len - wr, ", rxinv");
+
+	if (val & (IGPIO_PADCFG0_GPIROUTIOXAPIC|IGPIO_PADCFG0_GPIROUTSCI|
+		   IGPIO_PADCFG0_GPIROUTSMI|IGPIO_PADCFG0_GPIROUTNMI)) {
+		wr += snprintf(buf + wr, len - wr, ", gpirout");
+
+		if (val & IGPIO_PADCFG0_GPIROUTIOXAPIC)
+			wr += snprintf(buf + wr, len - wr, " ioxapic");
+
+		if (val & IGPIO_PADCFG0_GPIROUTSCI)
+			wr += snprintf(buf + wr, len - wr, " sci");
+
+		if (val & IGPIO_PADCFG0_GPIROUTSMI)
+			wr += snprintf(buf + wr, len - wr, " smi");
+
+		if (val & IGPIO_PADCFG0_GPIROUTNMI)
+			wr += snprintf(buf + wr, len - wr, " nmi");
+	}
+
+	pmode = 
+	    (val & IGPIO_PADCFG0_PMODE_MASK) >> IGPIO_PADCFG0_PMODE_SHIFT;
+	switch (pmode) {
+	case IGPIO_PADCFG0_PMODE_GPIO:
+		wr += snprintf(buf + wr, len - wr, ", pmode gpio");
+		break;
+	default:
+		wr += snprintf(buf + wr, len - wr, ", pmode %d", pmode);
+		break;
+	}
+
+	if (val & IGPIO_PADCFG0_GPIORXDIS)
+		wr += snprintf(buf + wr, len - wr, ", rx disabled");
+	else
+		wr += snprintf(buf + wr, len - wr, ", rx %d",
+		    !!(val & IGPIO_PADCFG0_GPIORXSTATE));
+
+	if (val & IGPIO_PADCFG0_GPIOTXDIS)
+		wr += snprintf(buf + wr, len - wr, ", tx disabled");
+	else
+		wr += snprintf(buf + wr, len - wr, ", tx %d",
+		    !!(val & IGPIO_PADCFG0_GPIOTXSTATE));
+
+	if (val & unknown_bits) {
+		wr += snprintf(buf + wr, len - wr, ", unknown bits");
+		for (b = 0; b < 32; b++) {
+			if (!(__BIT(b) & unknown_bits & val))
+				continue;
+			wr += snprintf(buf + wr, len - wr, " %d", b);
+		}
+	}
+
+	return buf;
+}
+
+
+static struct igpio_bank_setup *
+igpio_find_bank_setup(struct igpio_bank *ib, int barno)
+{
+	struct igpio_bank_setup *ibs;
+
+	for (ibs = igpio_bank_setup; ibs->ibs_acpi_hid; ibs++) {
+		if (strcmp(ib->ib_sc->sc_acpi_hid, ibs->ibs_acpi_hid) != 0)
+			continue;
+		if (ibs->ibs_barno != barno)
+			continue;
+
+		return ibs;
+	}
+
+	return NULL;
+}
+
+static struct igpio_bank *
+igpio_find_bank(struct igpio_softc *sc, int pin)
+{
+	int i;
+	struct igpio_bank *ib;
+
+	for (i = 0; i < sc->sc_nbar; i++) {
+		ib = &sc->sc_banks[i];
+		if (pin >= ib->ib_setup->ibs_first_pin &&
+		    pin <= ib->ib_setup->ibs_last_pin)
+			goto out;
+	}
+
+	ib = NULL;
+out:
+	return ib;
+}
+
+static int
+igpio_bank_pin(struct igpio_bank *ib, int pin)
+{
+	return pin - ib->ib_setup->ibs_first_pin;
+}
+
+#if 0
+static void
+igpio_hexdump(struct igpio_softc *sc, int n)
+{
+	int i, j;
+	uint8_t v;
+	size_t len = MIN(sc->sc_length[n], 2048);
+
+	printf("bar %d\n", n);
+	for (j = 0; j < len; j += 16) {	
+		printf("%04x ", j);
+		for (i = 0; i < 16 && i + j < len; i++) {
+			v = bus_space_read_1(sc->sc_bst, sc->sc_bsh[n], i + j);
+			printf("%02x ", v);
+		}
+		printf("\n");
+	}
+}
+#endif
+
+void
+igpio_attach(struct igpio_softc *sc)
+{
+	device_t self = sc->sc_dev;
+	int i,j;
+	struct gpiobus_attach_args gba;
+	int success = 0;
+
+	sc->sc_banks = 
+	    kmem_zalloc(sizeof(*sc->sc_banks) * sc->sc_nbar, KM_SLEEP);
+
+	sc->sc_npins = 0;
+
+	for (i = 0; i < sc->sc_nbar; i++) {
+		struct igpio_bank *ib = &sc->sc_banks[i];
+		struct igpio_bank_setup *ibs;
+		bus_size_t reg;
+		uint32_t val;
+		int error;
+		int npins;
+
+		ib->ib_barno = i;
+		ib->ib_sc = sc;
+
+		mutex_init(&ib->ib_mtx, MUTEX_DEFAULT, IPL_VM);
+
+		error = bus_space_map(sc->sc_bst, sc->sc_base[i],
+		    sc->sc_length[i], 0, &sc->sc_bsh[i]);
+		if (error) {
+			aprint_error_dev(self, "couldn't map registers\n");
+			goto out;
+		}
+
+		reg = IGPIO_REVID;
+		val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[i], reg);
+		if (val == 0) {
+			aprint_error_dev(self, "couldn't find revid\n");
+			goto out;
+		}
+		ib->ib_revid = val >> 16;
+
+		DPRINTF(("revid[%d] = #%x\n", i, ib->ib_revid));
+
+		if (ib->ib_revid > 0x94) {
+			ib->ib_cap |= IGPIO_PINCTRL_FEATURE_DEBOUNCE;
+			ib->ib_cap |= IGPIO_PINCTRL_FEATURE_1K_PD;
+		}
+
+		reg = IGPIO_CAPLIST;
+		do {
+			/* higher 16 bits: value, lower 16 bits, next reg */
+			val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[i], reg);
+
+			reg = val & 0xffff;
+			val = val >> 16;
+
+			switch (val) {
+			case IGPIO_CAPLIST_ID_GPIO_HW_INFO:
+				ib->ib_cap |=
+				    IGPIO_PINCTRL_FEATURE_GPIO_HW_INFO;
+				break;
+			case IGPIO_CAPLIST_ID_PWM:
+				ib->ib_cap |= IGPIO_PINCTRL_FEATURE_PWM;
+				break;
+			case IGPIO_CAPLIST_ID_BLINK:
+				ib->ib_cap |= IGPIO_PINCTRL_FEATURE_BLINK;
+				break;
+			case IGPIO_CAPLIST_ID_EXP:
+				ib->ib_cap |= IGPIO_PINCTRL_FEATURE_EXP;
+				break;
+			default:
+				break;
+			}
+		} while (reg);
+		DPRINTF(("cap[%d] = #%x\n", i, ib->ib_cap));
+
+		reg = IGPIO_PADBAR;
+		val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[i], reg);
+		ib->ib_padbar = val;
+		DPRINTF(("padbar[%d] = #%x\n", i, ib->ib_padbar));
+		if (ib->ib_padbar > sc->sc_length[i]) {
+			printf("PADBAR = #%x higher than max #%lx\n",
+			     ib->ib_padbar, sc->sc_length[i]);
+			goto out;
+		}
+
+		ib->ib_setup = igpio_find_bank_setup(ib, i);
+		if (ib->ib_setup == NULL) {
+			printf("Missing BAR %d\n", i);
+			goto out;
+		}
+	
+		ibs = ib->ib_setup;
+
+		DPRINTF(("setup[%d] = "
+		    "{ barno = %d, first_pin = %d, last_pin = %d }\n",
+		    i, ibs->ibs_barno, ibs->ibs_first_pin, ibs->ibs_last_pin));
+
+		npins = 1 + ibs->ibs_last_pin - ibs->ibs_first_pin;
+
+		ib->ib_intr = 
+	    	    kmem_zalloc(sizeof(*ib->ib_intr) * npins, KM_SLEEP);
+
+		sc->sc_npins += npins;
+	}
+
+	if (sc->sc_npins < 1 || sc->sc_npins > 4096) {
+		printf("Unexpected pin count %d\n", sc->sc_npins);
+		goto out;
+	}
+
+	sc->sc_pins = 
+	    kmem_zalloc(sizeof(*sc->sc_pins) * sc->sc_npins, KM_SLEEP);
+
+	for (j = 0; j < sc->sc_npins; j++) {
+		sc->sc_pins[j].pin_num = j;
+		sc->sc_pins[j].pin_caps =
+		    GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_INOUT |
+		    GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN | GPIO_PIN_INVIN; 
+		sc->sc_pins[j].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;
+		sc->sc_pins[j].pin_state = igpio_pin_read(sc, j);
+	}
+
+	sc->sc_gc.gp_cookie = sc;
+	sc->sc_gc.gp_pin_read = igpio_pin_read;
+	sc->sc_gc.gp_pin_write = igpio_pin_write;
+	sc->sc_gc.gp_pin_ctl = igpio_pin_ctl;
+	sc->sc_gc.gp_intr_establish = igpio_intr_establish;
+	sc->sc_gc.gp_intr_disestablish = igpio_intr_disestablish;
+	sc->sc_gc.gp_intr_str = igpio_intr_str;
+
+	memset(&gba, 0, sizeof(gba));
+	gba.gba_gc = &sc->sc_gc;
+	gba.gba_pins = sc->sc_pins;
+	gba.gba_npins = sc->sc_npins;
+
+#if NGPIO > 0
+	config_found(sc->sc_dev, &gba, gpiobus_print, CFARGS_NONE);
+#endif
+
+	success = 1;
+out:
+	if (!success)
+		igpio_detach(sc);
+	
+	return;
+}
+
+void
+igpio_detach(struct igpio_softc *sc)
+{
+	int i;
+
+	for (i = 0; i < sc->sc_nbar; i++) {
+		struct igpio_bank *ib = &sc->sc_banks[i];
+		struct igpio_bank_setup *ibs = ib->ib_setup;
+		int npins = 1 + ibs->ibs_last_pin - ibs->ibs_first_pin;
+
+		if (ib->ib_intr != NULL) {
+			kmem_free(ib->ib_intr, sizeof(*ib->ib_intr) * npins);
+			ib->ib_intr = NULL;
+		}
+	}
+		
+	if (sc->sc_pins != NULL) {
+		kmem_free(sc->sc_pins, sizeof(*sc->sc_pins) * sc->sc_npins);
+		sc->sc_pins = NULL;
+	}
+
+	if (sc->sc_banks != NULL) {
+		kmem_free(sc->sc_banks, sizeof(*sc->sc_banks) * sc->sc_nbar);
+		sc->sc_banks = NULL;
+	}
+
+	return;
+}
+
+static bus_addr_t
+igpio_pincfg(struct igpio_bank *ib, int pin, int reg)
+{
+	int nregs = (ib->ib_cap & IGPIO_PINCTRL_FEATURE_DEBOUNCE) ? 4 : 2;
+	bus_addr_t pincfg; 
+
+	pincfg = ib->ib_padbar + reg + (pin * nregs * 4);
+#if 0
+	DPRINTF(("%s bar %d pin %d reg #%x pincfg = %p\n",
+	    __func__, ib->ib_barno, pin, reg, (void *)pincfg));
+#endif
+	return pincfg;
+}
+
+#if notyet
+static struct igpio_pin_group *
+igpio_find_group(struct igpio_bank *ib, int pin)
+{
+	struct igpio_bank_setup *ibs = ib->ib_setup;
+	struct igpio_pin_group *found_ipg = NULL;
+	struct igpio_pin_group *ipg;
+
+	if (pin > ibs->ibs_last_pin) {
+		DPRINTF(("%s: barno %d, pin = %d > past pin = %d\n", __func__,
+		    ibs->ibs_barno, pin, ibs->ibs_last_pin));
+		return NULL;
+	}
+
+	for (ipg = igpio_pin_group; ipg->ipg_acpi_hid; ipg++) {
+		if (strcmp(ipg->ipg_acpi_hid, ibs->ibs_acpi_hid) != 0)
+			continue;
+
+		if (pin > ipg->ipg_first_pin) {
+			found_ipg = ipg;
+			continue;
+		}
+	}
+
+	return found_ipg;
+}
+
+static bus_addr_t
+igpio_groupcfg(struct igpio_bank *ib, int pin)
+{
+	struct igpio_bank_setup *ibs = ib->ib_setup;
+	struct igpio_pin_group *ipg;
+	bus_addr_t groupcfg;
+
+	if ((ipg = igpio_find_group(ib, pin)) == NULL)
+		return (bus_addr_t)NULL;
+
+	groupcfg = ib->ib_padbar 
+		 + (ipg->ipg_groupno * 4) 
+		 + (pin - ipg->ipg_first_pin) / 2;
+	
+	DPRINTF(("%s: barno %d, pin = %d, found group %d \"%s\", cfg %p\n", \
+	    __func__, ibs->ibs_barno, pin, ipg->ipg_groupno,		    \
+	    ipg->ipg_name, (void *)groupcfg));
+
+	return groupcfg;
+}
+#endif
+
+
+int
+igpio_pin_read(void *priv, int pin)
+{
+	struct igpio_softc *sc = priv;
+	struct igpio_bank *ib = igpio_find_bank(sc, pin);
+	bus_addr_t cfg0;
+	uint32_t val;
+
+	pin = igpio_bank_pin(ib, pin);
+	cfg0  = igpio_pincfg(ib, pin, IGPIO_PADCFG0);
+
+	mutex_enter(&ib->ib_mtx);
+
+	val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0);
+	DPRINTF(("%s: bar %d pin %d val #%x (%s)\n", __func__, 
+	    ib->ib_barno, pin, val, igpio_padcfg0_print(val, 0)));
+
+	if (val & IGPIO_PADCFG0_GPIOTXDIS) 
+		val = (val & IGPIO_PADCFG0_GPIORXSTATE) ? 1 : 0;
+	else
+		val = (val & IGPIO_PADCFG0_GPIOTXSTATE) ? 1 : 0;
+
+	mutex_exit(&ib->ib_mtx);
+
+	return val;
+}
+
+void
+igpio_pin_write(void *priv, int pin, int value)
+{
+	struct igpio_softc *sc = priv;
+	struct igpio_bank *ib = igpio_find_bank(sc, pin);
+	bus_addr_t cfg0;
+	uint32_t val, newval;
+
+	pin = igpio_bank_pin(ib, pin);
+	cfg0 = igpio_pincfg(ib, pin, IGPIO_PADCFG0);
+
+	mutex_enter(&ib->ib_mtx);
+
+	val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0);
+
+	if (value)
+		newval = val |  IGPIO_PADCFG0_GPIOTXSTATE;
+	else
+		newval = val & ~IGPIO_PADCFG0_GPIOTXSTATE;
+
+	DPRINTF(("%s: bar %d pin %d value %d val #%x (%s) -> #%x (%s)\n",
+	    __func__, ib->ib_barno, pin, value,
+	    val, igpio_padcfg0_print(val, 0),
+	    newval, igpio_padcfg0_print(newval, 1)));
+
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0, newval);
+
+	mutex_exit(&ib->ib_mtx);
+
+	return;
+}
+
+void
+igpio_pin_ctl(void *priv, int pin, int flags)
+{
+	struct igpio_softc *sc = priv;
+	struct igpio_bank *ib = igpio_find_bank(sc, pin);
+	bus_addr_t cfg0, cfg1;
+	uint32_t val0, newval0;
+	uint32_t val1, newval1;
+
+	pin = igpio_bank_pin(ib, pin);
+	cfg0  = igpio_pincfg(ib, pin, IGPIO_PADCFG0);
+	cfg1  = igpio_pincfg(ib, pin, IGPIO_PADCFG1);
+
+	mutex_enter(&ib->ib_mtx);
+
+	val0 = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0);
+	val1 = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg1);
+
+	newval0 = val0;
+	newval1 = val1;
+
+	newval0 &= ~IGPIO_PADCFG0_PMODE_MASK;
+	newval0 |=  IGPIO_PADCFG0_PMODE_GPIO;
+
+	newval0 |= IGPIO_PADCFG0_GPIORXDIS;
+	newval0 |= IGPIO_PADCFG0_GPIOTXDIS;
+
+	newval0 &= ~(IGPIO_PADCFG0_GPIROUTIOXAPIC | IGPIO_PADCFG0_GPIROUTSCI);
+	newval0 &= ~(IGPIO_PADCFG0_GPIROUTSMI | IGPIO_PADCFG0_GPIROUTNMI);
+
+	if (flags & GPIO_PIN_INPUT) {
+		newval0 &= ~IGPIO_PADCFG0_GPIORXDIS;
+		newval0 |=  IGPIO_PADCFG0_GPIOTXDIS;
+	}
+
+	if (flags & GPIO_PIN_OUTPUT) {
+		newval0 &= ~IGPIO_PADCFG0_GPIOTXDIS;
+		newval0 |=  IGPIO_PADCFG0_GPIORXDIS;
+	}
+
+	if (flags & GPIO_PIN_INOUT) {
+		newval0 &= ~IGPIO_PADCFG0_GPIOTXDIS;
+		newval0 &= ~IGPIO_PADCFG0_GPIORXDIS;
+	}
+
+	if (flags & GPIO_PIN_INVIN)
+		newval0 |=  IGPIO_PADCFG0_RXINV;
+	else
+		newval0 &= ~IGPIO_PADCFG0_RXINV;
+
+	newval1 &= ~IGPIO_PADCFG1_TERM_MASK;
+	if (flags & GPIO_PIN_PULLUP) {
+		newval1 |=  IGPIO_PADCFG1_TERM_UP;
+		newval1 |=  IGPIO_PADCFG1_TERM_5K;
+	}
+
+	if (flags & GPIO_PIN_PULLDOWN) {
+		newval1 &= ~IGPIO_PADCFG1_TERM_UP;
+		newval1 |=  IGPIO_PADCFG1_TERM_5K;
+	}
+
+	DPRINTF(("%s: bar %d pin %d flags #%x val0 #%x (%s) -> #%x (%s), "
+	    "val1 #%x -> #%x\n", __func__, ib->ib_barno, pin, flags, 
+	    val0, igpio_padcfg0_print(val0, 0),
+	    newval0, igpio_padcfg0_print(newval0, 1),
+	    val1, newval1));
+
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0, newval0);
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg1, newval1);
+
+	mutex_exit(&ib->ib_mtx);
+
+	return;
+}
+
+void *
+igpio_intr_establish(void *priv, int pin, int ipl, int irqmode,
+    int (*func)(void *), void *arg)
+{
+	struct igpio_softc *sc = priv;
+	struct igpio_bank *ib = igpio_find_bank(sc, pin);
+	bus_addr_t cfg0;
+	uint32_t val, newval;
+	struct igpio_intr *ii;
+
+	pin = igpio_bank_pin(ib, pin);
+	cfg0 = igpio_pincfg(ib, pin, IGPIO_PADCFG0);
+
+	ii = &ib->ib_intr[pin];
+	ii->ii_func = func;
+	ii->ii_arg = arg;
+	ii->ii_pin = pin;
+	ii->ii_bank = ib;
+
+	mutex_enter(&ib->ib_mtx);
+
+	val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0);
+	newval = val;
+
+	newval &= ~IGPIO_PADCFG0_PMODE_MASK;
+	newval |=  IGPIO_PADCFG0_PMODE_GPIO;
+
+	newval &= ~IGPIO_PADCFG0_GPIORXDIS;
+	newval |=  IGPIO_PADCFG0_GPIOTXDIS;
+
+	newval |= (IGPIO_PADCFG0_GPIROUTIOXAPIC | IGPIO_PADCFG0_GPIROUTSCI);
+	newval |= (IGPIO_PADCFG0_GPIROUTSMI | IGPIO_PADCFG0_GPIROUTNMI);
+
+	newval &= ~IGPIO_PADCFG0_RXINV;
+	newval &= ~IGPIO_PADCFG0_RXEVCFG_EDGE;
+	newval &= ~IGPIO_PADCFG0_RXEVCFG_LEVEL;
+	newval &= ~IGPIO_PADCFG0_RXEVCFG_DISABLED;
+
+	switch (irqmode & GPIO_INTR_EDGE_MASK) { 
+	case GPIO_INTR_DOUBLE_EDGE:
+		newval |= IGPIO_PADCFG0_RXEVCFG_EDGE_BOTH;
+		break;
+	case GPIO_INTR_NEG_EDGE:
+                newval |= IGPIO_PADCFG0_RXEVCFG_EDGE;
+                newval |= IGPIO_PADCFG0_RXINV; 
+		break;
+	case GPIO_INTR_POS_EDGE:
+		newval |= IGPIO_PADCFG0_RXEVCFG_EDGE;
+		break;
+	default:
+		switch (irqmode & GPIO_INTR_LEVEL_MASK) { 
+		case GPIO_INTR_HIGH_LEVEL:
+			newval |= IGPIO_PADCFG0_RXEVCFG_LEVEL;
+			break;
+		case GPIO_INTR_LOW_LEVEL:
+			newval |= IGPIO_PADCFG0_RXEVCFG_LEVEL;
+			newval |= IGPIO_PADCFG0_RXINV;
+			break;
+		default:
+			newval |= IGPIO_PADCFG0_RXEVCFG_DISABLED;
+			break;
+		}
+		break;
+	}
+
+
+	DPRINTF(("%s: bar %d pin %d val #%x (%s) -> #%x (%s)\n",
+	    __func__, ib->ib_barno, pin,
+	    val, igpio_padcfg0_print(val, 0), 
+	    newval, igpio_padcfg0_print(newval, 1)));
+
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0, newval);
+
+	mutex_exit(&ib->ib_mtx);
+
+	return ii;
+}
+
+void
+igpio_intr_disestablish(void *priv, void *ih)
+{
+	struct igpio_softc *sc = priv;
+	struct igpio_bank *ib;
+	struct igpio_intr *ii = ih;
+	int pin;
+	bus_addr_t cfg0;
+	uint32_t val, newval;
+
+	if (ih == NULL)
+		return;
+
+	pin = ii->ii_pin;
+	ib = igpio_find_bank(sc, pin);
+	pin = igpio_bank_pin(ib, pin);
+	cfg0  = igpio_pincfg(ib, pin, IGPIO_PADCFG0);
+
+	mutex_enter(&ib->ib_mtx);
+
+	val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0);
+	newval = val;
+
+	newval &= ~IGPIO_PADCFG0_PMODE_MASK;
+	newval |=  IGPIO_PADCFG0_PMODE_GPIO;
+
+	newval &= ~(IGPIO_PADCFG0_GPIROUTIOXAPIC | IGPIO_PADCFG0_GPIROUTSCI);
+	newval &= ~(IGPIO_PADCFG0_GPIROUTSMI | IGPIO_PADCFG0_GPIROUTNMI);
+
+	DPRINTF(("%s: bar %d pin %d val #%x (%s) -> #%x (%s)\n", \
+	    __func__, ib->ib_barno, pin,
+	    val, igpio_padcfg0_print(val, 0), 
+	    newval, igpio_padcfg0_print(newval, 1)));
+
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0, newval);
+
+	mutex_exit(&ib->ib_mtx);
+
+	ii->ii_func = NULL;
+	ii->ii_arg = NULL;
+
+	return;
+}
+
+bool
+igpio_intr_str(void *priv, int pin, int irqmode,
+    char *buf, size_t buflen)
+{
+	struct igpio_softc *sc = priv;
+	const char *name = sc->sc_dev->dv_xname;
+	int rv;
+
+	rv = snprintf(buf, buflen, "%s pin %d", name, pin);
+
+	return (rv < buflen);
+}
+
+int
+igpio_intr(void *priv)
+{
+	struct igpio_softc *sc = priv;
+	int i;
+	int ret = 0;
+
+	for (i = 0; i < sc->sc_nbar; i++) {
+		struct igpio_bank *ib = &sc->sc_banks[i];
+		struct igpio_bank_setup *ibs = ib->ib_setup;
+		bus_space_handle_t bsh = sc->sc_bsh[i];
+		struct igpio_pin_group *ipg;
+
+		mutex_enter(&ib->ib_mtx);
+
+		for (ipg = igpio_pin_group; ipg->ipg_acpi_hid; ipg++) {
+			int offset;
+			bus_addr_t is_reg;
+			bus_addr_t ie_reg;
+			uint32_t raised;
+			uint32_t pending;
+			uint32_t enabled;
+			int b;
+
+			if (strcmp(ipg->ipg_acpi_hid,
+			    ibs->ibs_acpi_hid) != 0)
+				continue;
+
+			offset = ib->ib_padbar + ipg->ipg_groupno * 4;
+			is_reg = offset + ibs->ibs_gpi_is;
+			ie_reg = offset + ibs->ibs_gpi_ie;
+
+			raised = bus_space_read_4(sc->sc_bst, bsh, is_reg);
+			enabled = bus_space_read_4(sc->sc_bst, bsh, ie_reg);
+
+			/*
+			 * find pins for which interupt is pending
+			 * and enabled
+			 */
+			pending = raised & enabled;
+			
+			for (b = 0; b < 32; b++) {
+				int pin;
+				int (*func)(void *);
+				void *arg;
+
+				if ((pending & (1 << b)) == 0)
+					continue;
+
+				pin = ipg->ipg_first_pin + b;
+				func = ib->ib_intr[pin].ii_func;
+				arg = ib->ib_intr[pin].ii_arg;
+
+				/* XXX ack intr, handled or not? */
+				raised &= ~(1 << b);
+
+				if (func == NULL)
+					continue;
+
+				ret |= func(arg);
+			}
+
+			bus_space_write_4(sc->sc_bst, bsh, is_reg, raised);
+
+		}
+
+		mutex_exit(&ib->ib_mtx);
+
+	}
+
+	return ret;
+}
Index: src/sys/dev/ic/igpioreg.h
diff -u /dev/null src/sys/dev/ic/igpioreg.h:1.1
--- /dev/null	Thu Mar 24 02:24:25 2022
+++ src/sys/dev/ic/igpioreg.h	Thu Mar 24 02:24:25 2022
@@ -0,0 +1,493 @@
+/* $NetBSD: igpioreg.h,v 1.1 2022/03/24 02:24:25 manu Exp $ */
+
+/*
+ * Copyright (c) 2021 Emmanuel Dreyfus
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _IGPIOREG_H
+#define _IGPIOREG_H
+
+#define IGPIO_REVID	0x0000
+#define IGPIO_CAPLIST	0x0004
+#define IGPIO_PADBAR	0x000c
+
+#define IGPIO_PADCFG0	0x0000
+
+#define IGPIO_PADCFG0_RXEVCFG_SHIFT           25
+#define IGPIO_PADCFG0_RXEVCFG_MASK            __BITS(26, 25)
+#define IGPIO_PADCFG0_RXEVCFG_LEVEL           0
+#define IGPIO_PADCFG0_RXEVCFG_EDGE            1
+#define IGPIO_PADCFG0_RXEVCFG_DISABLED        2
+#define IGPIO_PADCFG0_RXEVCFG_EDGE_BOTH       3
+#define IGPIO_PADCFG0_PREGFRXSEL              __BIT(24)
+#define IGPIO_PADCFG0_RXINV                   __BIT(23)
+#define IGPIO_PADCFG0_GPIROUTIOXAPIC          __BIT(20)
+#define IGPIO_PADCFG0_GPIROUTSCI              __BIT(19)
+#define IGPIO_PADCFG0_GPIROUTSMI              __BIT(18)
+#define IGPIO_PADCFG0_GPIROUTNMI              __BIT(17)
+#define IGPIO_PADCFG0_PMODE_SHIFT             10
+#define IGPIO_PADCFG0_PMODE_MASK              __BITS(13, 10)
+#define IGPIO_PADCFG0_PMODE_GPIO              0
+#define IGPIO_PADCFG0_GPIORXDIS               __BIT(9)
+#define IGPIO_PADCFG0_GPIOTXDIS               __BIT(8)
+#define IGPIO_PADCFG0_GPIORXSTATE             __BIT(1)
+#define IGPIO_PADCFG0_GPIOTXSTATE             __BIT(0)
+
+#define IGPIO_PADCFG1	0x0004
+#define IGPIO_PADCFG1_TERM_UP                 __BIT(13)
+#define IGPIO_PADCFG1_TERM_SHIFT              10
+#define IGPIO_PADCFG1_TERM_MASK               __BITS(12, 10)
+#define IGPIO_PADCFG1_TERM_20K                __BIT(2)
+#define IGPIO_PADCFG1_TERM_5K                 __BIT(1)
+#define IGPIO_PADCFG1_TERM_1K                 __BIT(0)
+#define IGPIO_PADCFG1_TERM_833                (__BIT(1) | BIT(0))
+
+#define IGPIO_CAPLIST_ID_GPIO_HW_INFO	1
+#define IGPIO_CAPLIST_ID_PWM		2
+#define IGPIO_CAPLIST_ID_BLINK		3
+#define IGPIO_CAPLIST_ID_EXP		4
+
+
+#define IGPIO_PINCTRL_FEATURE_DEBOUNCE		0x001
+#define IGPIO_PINCTRL_FEATURE_1K_PD		0x002
+#define IGPIO_PINCTRL_FEATURE_GPIO_HW_INFO	0x004
+#define IGPIO_PINCTRL_FEATURE_PWM		0x010
+#define IGPIO_PINCTRL_FEATURE_BLINK		0x020
+#define IGPIO_PINCTRL_FEATURE_EXP		0x040
+
+struct igpio_bank_setup {
+	const char *ibs_acpi_hid;
+	int ibs_barno;
+	int ibs_first_pin;
+	int ibs_last_pin;
+	int ibs_gpi_is;
+	int ibs_gpi_ie;
+};
+
+struct igpio_pin_group {
+	const char *ipg_acpi_hid;
+	int ipg_groupno;
+	int ipg_first_pin;
+	const char *ipg_name;
+};
+
+struct igpio_bank_setup igpio_bank_setup[] = {
+	/* Sunrisepoint-LP */
+	{ "INT344B",    0,   0,  47, 0x100, 0x120 },
+	{ "INT344B",    1,  48, 119, 0x100, 0x120 },
+	{ "INT344B",    2, 120, 151, 0x100, 0x120 },
+
+	/* Sunrisepoint-H */
+	{ "INT3451",    0,   0,  47, 0x100, 0x120 },
+	{ "INT3451",    1,  48, 180, 0x100, 0x120 },
+	{ "INT3451",    2, 181, 191, 0x100, 0x120 },
+
+	/* Sunrisepoint-H */
+	{ "INT345D",    0,   0,  47, 0x100, 0x120 },
+	{ "INT345D",    1,  48, 180, 0x100, 0x120 },
+	{ "INT345D",    2, 181, 191, 0x100, 0x120 },
+
+	/* Baytrail XXX GPI_IS and GPI_IE */
+	{ "INT33B2",    0,   0, 101, 0x000, 0x000 },
+	{ "INT33FC",    0,   0, 101, 0x000, 0x000 },
+
+	/* Lynxpoint XXX GPI_IS and GPI_IE */
+	{ "INT33C7",    0,   0,  94, 0x000, 0x000 },
+	{ "INT3437",    0,   0,  94, 0x000, 0x000 },
+
+	/* Cannonlake-H */
+	{ "INT3450",    0,   0,  50, 0x100, 0x120 },
+	{ "INT3450",    1,  51, 154, 0x100, 0x120 },
+	{ "INT3450",    2, 155, 248, 0x100, 0x120 },
+	{ "INT3450",    3, 249, 298, 0x100, 0x120 },
+
+	/* Cannonlake-LP */
+	{ "INT34BB",    0,   0,  67, 0x100, 0x120 },
+	{ "INT34BB",    1,  68, 180, 0x100, 0x120 },
+	{ "INT34BB",    2, 181, 243, 0x100, 0x120 },
+
+	/* Alderlake */
+	{ "INTC1056",   0,   0,  94, 0x200, 0x220 },
+	{ "INTC1056",   1,  95, 150, 0x200, 0x220 },
+	{ "INTC1056",   2, 151, 199, 0x200, 0x220 },
+	{ "INTC1056",   3, 200, 269, 0x200, 0x220 },
+	{ "INTC1056",   4, 270, 303, 0x200, 0x220 },
+
+	/* Icelake */
+	{ "INT3455",    0,   0,  58, 0x100, 0x110 },
+	{ "INT3455",    1,  59, 152, 0x100, 0x110 },
+	{ "INT3455",    2, 153, 215, 0x100, 0x110 },
+	{ "INT3455",    3, 216, 240, 0x100, 0x110 },
+
+	/* Lakefield */
+	{ "INT34C4",    0,   0,  59, 0x100, 0x110 },
+	{ "INT34C4",    1,  60, 148, 0x100, 0x110 },
+	{ "INT34C4",    2, 149, 237, 0x100, 0x110 },
+	{ "INT34C4",    3, 238, 266, 0x100, 0x110 },
+
+	/* Tigerlake-LP */
+	{ "INT34C5",    0,   0,  66, 0x100, 0x120 },
+	{ "INT34C5",    1,  67, 170, 0x100, 0x120 },
+	{ "INT34C5",    2, 171, 259, 0x100, 0x120 },
+	{ "INT34C5",    3, 260, 276, 0x100, 0x120 },
+
+	/* Tigerlake-LP */
+	{ "INTC1055",    0,   0,  66, 0x100, 0x120 },
+	{ "INTC1055",    1,  67, 170, 0x100, 0x120 },
+	{ "INTC1055",    2, 171, 259, 0x100, 0x120 },
+	{ "INTC1055",    3, 260, 276, 0x100, 0x120 },
+
+	/* Tigerlake-LP */
+	{ "INTC1057",    0,   0,  66, 0x100, 0x120 },
+	{ "INTC1057",    1,  67, 170, 0x100, 0x120 },
+	{ "INTC1057",    2, 171, 259, 0x100, 0x120 },
+	{ "INTC1057",    3, 260, 276, 0x100, 0x120 },
+
+	/* Tigerlake-H */
+	{ "INT34C6",    0,   0,  78, 0x100, 0x120 },
+	{ "INT34C6",    1,  79, 180, 0x100, 0x120 },
+	{ "INT34C6",    2, 181, 217, 0x100, 0x120 },
+	{ "INT34C6",    3, 218, 266, 0x100, 0x120 },
+	{ "INT34C6",    4, 267, 290, 0x100, 0x120 },
+
+	/* Jasperlake */
+	{ "INT34C8",    0,   0,  91, 0x100, 0x120 },
+	{ "INT34C8",    1,  92, 194, 0x100, 0x120 },
+	{ "INT34C8",    2, 195, 224, 0x100, 0x120 },
+	{ "INT34C8",    3, 225, 232, 0x100, 0x120 },
+
+	/* Lewisburg */
+	{ "INT3536",    0,   0,   7, 0x100, 0x110 },
+	{ "INT3536",    1,  72,  13, 0x100, 0x110 },
+	{ "INT3536",    3, 133,  14, 0x100, 0x110 },
+	{ "INT3536",    4, 144,  17, 0x100, 0x110 },
+	{ "INT3536",    5, 179, 246, 0x100, 0x110 },
+
+	/* Emmitsburg */
+	{ "INTC1071",    0,   0,  65, 0x200, 0x210 },
+	{ "INTC1071",    1,  66, 111, 0x200, 0x210 },
+	{ "INTC1071",    2, 112, 145, 0x200, 0x210 },
+	{ "INTC1071",    3, 146, 183, 0x200, 0x210 },
+	{ "INTC1071",    4, 184, 261, 0x200, 0x210 },
+
+	/* Denverton */
+        { "INTC3000",    0,   0,  40, 0x100, 0x120 },
+        { "INTC3000",    1,  41, 153, 0x100, 0x120 },
+
+	/* Cedarfork */
+        { "INTC3001",    0,   0, 167, 0x200, 0x230 },
+        { "INTC3001",    1, 168, 236, 0x200, 0x230 },
+
+	/* Geminilake */
+	{ "INT3453",     0,   0,  34, 0x100, 0x110 }, 
+
+#ifdef notyet
+	/*
+	 * BAR mappings not obvious, further studying required
+	 */
+	/* Broxton */
+	{ "apollolake-pinctrl", 0,   0,   0, 0x100, 0x110 },
+	{ "broxton-pinctrl",    0,   0,   0, 0x100, 0x110 },
+	{ "INT34D1",     0,   0,    0, 0x100, 0x110 },
+	{ "INT3452",     0,   0,    0, 0x100, 0x110 }, 
+
+	/* Cherryview */
+	{ "INT33FF",     0,   0,    0, 0x000, 0x000 },
+#endif
+
+	{      NULL,     0,   0,   0,  0x000, 0x000 },
+};
+
+struct igpio_pin_group igpio_pin_group[] = {
+	/* Sunrisepoint-LP */
+	{ "INT344B",    0, 151,  "A" },
+
+	/* Sunrisepoint-H */
+	{ "INT3451",    0,   0,  "A" },
+	{ "INT3451",    1,  24,  "B" },
+	{ "INT3451",    0,  48,  "C" },
+	{ "INT3451",    1,  72,  "D" },
+	{ "INT3451",    2,  96,  "E" },      
+	{ "INT3451",    3, 109,  "F" },
+	{ "INT3451",    4, 133,  "G" },
+	{ "INT3451",    5, 157,  "H" },      
+	{ "INT3451",    0, 181,  "I" },      
+                
+	/* Sunrisepoint-H */
+	{ "INT345D",    0,   0,  "A" },
+	{ "INT345D",    1,  24,  "B" },
+	{ "INT345D",    0,  48,  "C" },
+	{ "INT345D",    1,  72,  "D" },
+	{ "INT345D",    2,  96,  "E" },      
+	{ "INT345D",    3, 109,  "F" },
+	{ "INT345D",    4, 133,  "G" },
+	{ "INT345D",    5, 157,  "H" },      
+	{ "INT345D",    0, 181,  "I" },      
+                
+
+	/* Baytrail */
+	{ "INT33B2",    0, 101,  "A" },
+
+	/* Lynxpoint */
+	{ "INT33C7",    0,  94,  "A" },
+	{ "INT3437",    0,  94,  "A" },
+
+	/* Cannonlake-H */
+	{ "INT3450",  0,  0,  "GPP_A" },
+	{ "INT3450",  1,  25,  "GPP_B" },
+	{ "INT3450",  0,  51,  "GPP_C" },
+	{ "INT3450",  1,  75,  "GPP_D" },
+	{ "INT3450",  2,  99,  "GPP_G" },
+	{ "INT3450",  3,  107,  "AZA" },
+	{ "INT3450",  4,  115,  "vGPIO_0" },
+	{ "INT3450",  5,  147,  "vGPIO_1" },
+	{ "INT3450",  0,  155,  "GPP_K" },
+	{ "INT3450",  1,  179,  "GPP_H" },
+	{ "INT3450",  2,  203,  "GPP_E" },
+	{ "INT3450",  3,  216,  "GPP_F" },
+	{ "INT3450",  4,  240,  "SPI" },
+	{ "INT3450",  0,  249,  "CPU" },
+	{ "INT3450",  1,  260,  "JTAG" },
+	{ "INT3450",  2,  269,  "GPP_I" },
+	{ "INT3450",  3,  287,  "GPP_J" },
+
+	/* Cannonlake-LP */
+	{ "INT34BB",  0,  0,  "GPP_A" },
+	{ "INT34BB",  1,  25,  "GPP_B" },
+	{ "INT34BB",  2,  51,  "GPP_G" },
+	{ "INT34BB",  3,  59,  "SPI" },
+	{ "INT34BB",  0,  68,  "GPP_D" },
+	{ "INT34BB",  1,  93,  "GPP_F" },
+	{ "INT34BB",  2,  117,  "GPP_H" },
+	{ "INT34BB",  3,  141,  "vGPIO" },
+	{ "INT34BB",  4,  173,  "vGPIO" },
+	{ "INT34BB",  0,  181,  "GPP_C" },
+	{ "INT34BB",  1,  205,  "GPP_E" },
+	{ "INT34BB",  2,  229,  "JTAG" },
+	{ "INT34BB",  3,  238,  "HVCMOS" },
+
+	/* Alderlake */
+	{ "INTC1056",  0,  0,  "GPP_I" },
+	{ "INTC1056",  1,  25,  "GPP_R" },
+	{ "INTC1056",  2,  48,  "GPP_J" },
+	{ "INTC1056",  3,  60,  "vGPIO" },
+	{ "INTC1056",  4,  87,  "vGPIO_0" },
+	{ "INTC1056",  0,  95,  "GPP_B" },
+	{ "INTC1056",  1,  119,  "GPP_G" },
+	{ "INTC1056",  2,  127,  "GPP_H" },
+	{ "INTC1056",  0,  151,  "SPI0" },
+	{ "INTC1056",  1,  160,  "GPP_A" },
+	{ "INTC1056",  2,  176,  "GPP_C" },
+	{ "INTC1056",  0,  200,  "GPP_S" },
+	{ "INTC1056",  1,  208,  "GPP_E" },
+	{ "INTC1056",  2,  231,  "GPP_K" },
+	{ "INTC1056",  3,  246,  "GPP_F" },
+	{ "INTC1056",  0,  270,  "GPP_D" },
+	{ "INTC1056",  1,  295,  "JTAG" },
+
+
+	/* Icelake */
+	{ "INT3455",  0,  0,  "GPP_G" },
+	{ "INT3455",  1,  8,  "GPP_B" },
+	{ "INT3455",  2,  34,  "GPP_A" },
+	{ "INT3455",  0,  59,  "GPP_H" },
+	{ "INT3455",  1,  83,  "GPP_D" },
+	{ "INT3455",  2,  104,  "GPP_F" },
+	{ "INT3455",  3,  124,  "vGPIO" },
+	{ "INT3455",  0,  153,  "GPP_C" },
+	{ "INT3455",  1,  177,  "HVCMOS" },
+	{ "INT3455",  2,  183,  "GPP_E" },
+	{ "INT3455",  3,  207,  "JTAG" },
+	{ "INT3455",  2,  232,  "SPI" },
+
+
+	/* Lakefield */
+	{ "INT34C4",  0,  0,  "EAST_0" },
+	{ "INT34C4",  1,  32,  "EAST_1" },
+	{ "INT34C4",  0,  60,  "NORTHWEST_0" },
+	{ "INT34C4",  1,  92,  "NORTHWEST_1" },
+	{ "INT34C4",  2,  124,  "NORTHWEST_2" },
+	{ "INT34C4",  0,  149,  "WEST_0" },
+	{ "INT34C4",  1,  181,  "WEST_1" },
+	{ "INT34C4",  2,  213,  "WEST_2" },
+	{ "INT34C4",  0,  238,  "SOUTHEAST" },
+
+
+	/* Tigerlake-LP */
+	{ "INT34C5",  0,  0,  "GPP_A" },
+	{ "INT34C5",  1,  25,  "GPP_R" },
+	{ "INT34C5",  2,  45,  "GPP_B" },
+	{ "INT34C5",  3,  71,  "vGPIO_0" },
+	{ "INT34C5",  0,  79,  "GPP_D" },
+	{ "INT34C5",  1,  105,  "GPP_C" },
+	{ "INT34C5",  2,  129,  "GPP_S" },
+	{ "INT34C5",  3,  137,  "GPP_G" },
+	{ "INT34C5",  4,  154,  "vGPIO" },
+	{ "INT34C5",  0,  181,  "GPP_E" },
+	{ "INT34C5",  1,  194,  "GPP_F" },
+	{ "INT34C5",  0,  218,  "GPP_H" },
+	{ "INT34C5",  1,  242,  "GPP_J" },
+	{ "INT34C5",  2,  252,  "GPP_K" },
+	{ "INT34C5",  0,  267,  "GPP_I" },
+	{ "INT34C5",  1,  282,  "JTAG" },
+
+
+	/* Tigerlake-LP */
+	{ "INTC1055",  0,  0,  "GPP_A" },
+	{ "INTC1055",  1,  25,  "GPP_R" },
+	{ "INTC1055",  2,  45,  "GPP_B" },
+	{ "INTC1055",  3,  71,  "vGPIO_0" },
+	{ "INTC1055",  0,  79,  "GPP_D" },
+	{ "INTC1055",  1,  105,  "GPP_C" },
+	{ "INTC1055",  2,  129,  "GPP_S" },
+	{ "INTC1055",  3,  137,  "GPP_G" },
+	{ "INTC1055",  4,  154,  "vGPIO" },
+	{ "INTC1055",  0,  181,  "GPP_E" },
+	{ "INTC1055",  1,  194,  "GPP_F" },
+	{ "INTC1055",  0,  218,  "GPP_H" },
+	{ "INTC1055",  1,  242,  "GPP_J" },
+	{ "INTC1055",  2,  252,  "GPP_K" },
+	{ "INTC1055",  0,  267,  "GPP_I" },
+	{ "INTC1055",  1,  282,  "JTAG" },
+
+
+	/* Tigerlake-LP */
+	{ "INTC1057",  0,  0,  "GPP_A" },
+	{ "INTC1057",  1,  25,  "GPP_R" },
+	{ "INTC1057",  2,  45,  "GPP_B" },
+	{ "INTC1057",  3,  71,  "vGPIO_0" },
+	{ "INTC1057",  0,  79,  "GPP_D" },
+	{ "INTC1057",  1,  105,  "GPP_C" },
+	{ "INTC1057",  2,  129,  "GPP_S" },
+	{ "INTC1057",  3,  137,  "GPP_G" },
+	{ "INTC1057",  4,  154,  "vGPIO" },
+	{ "INTC1057",  0,  181,  "GPP_E" },
+	{ "INTC1057",  1,  194,  "GPP_F" },
+	{ "INTC1057",  0,  218,  "GPP_H" },
+	{ "INTC1057",  1,  242,  "GPP_J" },
+	{ "INTC1057",  2,  252,  "GPP_K" },
+	{ "INTC1057",  0,  267,  "GPP_I" },
+	{ "INTC1057",  1,  282,  "JTAG" },
+
+	/* Tigerlake-H */
+	{ "INT34C6",  0,  0,  "GPP_B" },
+	{ "INT34C6",  1,  26,  "GPP_T" },
+	{ "INT34C6",  2,  42,  "GPP_A" },
+	{ "INT34C6",  0,  67,  "GPP_S" },
+	{ "INT34C6",  1,  75,  "GPP_H" },
+	{ "INT34C6",  2,  99,  "GPP_D" },
+	{ "INT34C6",  3,  120,  "GPP_U" },
+	{ "INT34C6",  4,  144,  "vGPIO" },
+	{ "INT34C6",  0,  171,  "GPP_C" },
+	{ "INT34C6",  1,  195,  "GPP_F" },
+	{ "INT34C6",  2,  220,  "HVCMOS" },
+	{ "INT34C6",  3,  226,  "GPP_E" },
+	{ "INT34C6",  4,  251,  "JTAG" },
+	{ "INT34C6",  0,  260,  "GPP_R" },
+	{ "INT34C6",  1,  268,  "SPI" },
+
+	/* Jasperlake */
+	{ "INT34C8",  0,  0,  "GPP_F" },
+	{ "INT34C8",  1,  20,  "SPI" },
+	{ "INT34C8",  2,  29,  "GPP_B" },
+	{ "INT34C8",  3,  55,  "GPP_A" },
+	{ "INT34C8",  4,  76,  "GPP_S" },
+	{ "INT34C8",  5,  84,  "GPP_R" },
+	{ "INT34C8",  0,  92,  "GPP_H" },
+	{ "INT34C8",  1,  116,  "GPP_D" },
+	{ "INT34C8",  2,  142,  "vGPIO" },
+	{ "INT34C8",  3,  171,  "GPP_C" },
+	{ "INT34C8",  0,  195,  "HVCMOS" },
+	{ "INT34C8",  1,  201,  "GPP_E" },
+	{ "INT34C8",  0,  225,  "GPP_G" },
+
+
+	/* Lewisburg */
+	{ "INT3536",   0,   7,  "" },
+
+	/* Emmitsburg */
+	{ "INTC1071",  0,  0,  "GPP_A" },
+	{ "INTC1071",  1,  21,  "GPP_B" },
+	{ "INTC1071",  2,  45,  "SPI" },
+	{ "INTC1071",  0,  66,  "GPP_C" },
+	{ "INTC1071",  1,  88,  "GPP_D" },
+	{ "INTC1071",  0,  112,  "GPP_E" },
+	{ "INTC1071",  1,  136,  "JTAG" },
+	{ "INTC1071",  0,  146,  "GPP_H" },
+	{ "INTC1071",  1,  166,  "GPP_J" },
+	{ "INTC1071",  0,  184,  "GPP_I" },
+	{ "INTC1071",  1,  208,  "GPP_L" },
+	{ "INTC1071",  2,  226,  "GPP_M" },
+	{ "INTC1071",  3,  244,  "GPP_N" },
+
+	/* Denverton */
+	{ "INTC3000",  0,  0,  "North" },
+	{ "INTC3000",  1,  32,  "North" },
+	{ "INTC3000",  0,  41,  "South" },
+	{ "INTC3000",  1,  59,  "South" },
+	{ "INTC3000",  2,  91,  "South" },
+	{ "INTC3000",  3,  112,  "South" },
+	{ "INTC3000",  4,  144,  "South" },
+
+
+	/* Cedarfork */
+	{ "INTC3001",  0,  0,  "WEST2" },
+	{ "INTC3001",  1,  24,  "WEST3" },
+	{ "INTC3001",  2,  48,  "WEST01" },
+	{ "INTC3001",  3,  71,  "WEST5" },
+	{ "INTC3001",  4,  91,  "WESTC" },
+	{ "INTC3001",  5,  97,  "WESTC_DFX" },
+	{ "INTC3001",  6,  102,  "WESTA" },
+	{ "INTC3001",  7,  112,  "WESTB" },
+	{ "INTC3001",  8,  124,  "WESTD" },
+	{ "INTC3001",  9,  144,  "WESTD_PECI" },
+	{ "INTC3001",  10,  145,  "WESTF" },
+	{ "INTC3001",  0,  168,  "EAST2" },
+	{ "INTC3001",  1,  192,  "EAST3" },
+	{ "INTC3001",  2,  203,  "EAST0" },
+	{ "INTC3001",  3,  226,  "EMMC" },
+
+	/* Geminilake */
+	{ "INT3453",     0,   34,  "" }, 
+
+#ifdef notyet
+	/*
+	 * BAR mappings not obvious, further studying required
+	 */
+	/* Broxton */
+	{ "apollolake-pinctrl", 0,   0,   "" },
+	{ "broxton-pinctrl",    0,   0,   "" },
+	{ "INT34D1",     0,   0,   "" },
+	{ "INT3452",     0,   0,   "" }, 
+
+	/* Cherryview */
+	{ "INT33FF",     0,   0,   "" },
+#endif
+
+	{      NULL,    0,   0,   0 },
+};
+
+#endif /* _IGPIOREG_H */
+
Index: src/sys/dev/ic/igpiovar.h
diff -u /dev/null src/sys/dev/ic/igpiovar.h:1.1
--- /dev/null	Thu Mar 24 02:24:25 2022
+++ src/sys/dev/ic/igpiovar.h	Thu Mar 24 02:24:25 2022
@@ -0,0 +1,63 @@
+/* $NetBSD: igpiovar.h,v 1.1 2022/03/24 02:24:25 manu Exp $ */
+
+/*
+ * Copyright (c) 2021 Emmanuel Dreyfus
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _IGPIOVAR_H
+#define _IGPIOVAR_H
+
+struct igpio_softc {
+	device_t		sc_dev;
+	const char 		*sc_acpi_hid;
+	bus_space_tag_t		sc_bst;
+	int			sc_nbar;
+	bus_addr_t		*sc_base;
+	bus_size_t		*sc_length;
+	bus_space_handle_t	*sc_bsh;
+
+	gpio_pin_t		*sc_pins;
+	int			sc_npins;
+	struct gpio_chipset_tag	sc_gc;
+
+	uint32_t		sc_reserved_mask;
+
+	struct igpio_bank	*sc_banks;
+};
+
+void igpio_attach(struct igpio_softc *);
+void igpio_detach(struct igpio_softc *);
+
+int	igpio_pin_read(void *, int);
+void	igpio_pin_write(void *, int, int);
+void	igpio_pin_ctl(void *, int, int);
+void	*igpio_intr_establish(void *, int, int, int, int (*)(void *), void *);
+void	igpio_intr_disestablish(void *, void *);
+bool	igpio_intr_str(void *, int, int, char *, size_t);
+int	igpio_intr(void *);
+
+
+
+#endif /* !_IGPIOVAR_H */

Reply via email to