Here is a new version of the dwiic patch that restores the acpi_attach_deps call, confirmed working by Cesare Gargano.

Any other testers?

Index: sys/conf/files
===================================================================
RCS file: /cvs/src/sys/conf/files,v
retrieving revision 1.654
diff -u -p -u -p -r1.654 files
--- sys/conf/files      3 Nov 2017 13:01:20 -0000       1.654
+++ sys/conf/files      10 Nov 2017 15:56:34 -0000
@@ -524,6 +524,10 @@ file       dev/spdmem.c                    spdmem
device  oaic: scsi
file    dev/ic/aic6250.c                oaic

+# Synopsys DesignWare I2C controller
+device dwiic: i2cbus
+file   dev/ic/dwiic.c                  dwiic
+
# legitimate pseudo-devices
pseudo-device vnd: disk
pseudo-device rd: disk
Index: sys/dev/pci/dwiic_pci.c
===================================================================
RCS file: sys/dev/pci/dwiic_pci.c
diff -N sys/dev/pci/dwiic_pci.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/dev/pci/dwiic_pci.c     10 Nov 2017 15:56:34 -0000
@@ -0,0 +1,204 @@
+/* $OpenBSD$ */
+/*
+ * Synopsys DesignWare I2C controller
+ * PCI attachment
+ *
+ * Copyright (c) 2015-2017 joshua stein <j...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <dev/ic/dwiicvar.h>
+
+/* 13.3: I2C Additional Registers Summary */
+#define LPSS_RESETS            0x204
+#define  LPSS_RESETS_I2C       (1 << 0) | (1 << 1)
+#define  LPSS_RESETS_IDMA      (1 << 2)
+#define LPSS_ACTIVELTR         0x210
+#define LPSS_IDLELTR           0x214
+#define LPSS_CAPS              0x2fc
+#define  LPSS_CAPS_NO_IDMA     (1 << 8)
+#define  LPSS_CAPS_TYPE_SHIFT  4
+#define  LPSS_CAPS_TYPE_MASK   (0xf << LPSS_CAPS_TYPE_SHIFT)
+
+int            dwiic_pci_match(struct device *, void *, void *);
+void           dwiic_pci_attach(struct device *, struct device *, void *);
+int            dwiic_pci_activate(struct device *, int);
+void           dwiic_pci_bus_scan(struct device *,
+                   struct i2cbus_attach_args *, void *);
+
+#include "acpi.h"
+#if NACPI > 0
+struct aml_node *acpi_pci_match(struct device *dev, struct pci_attach_args 
*pa);
+#endif
+
+struct cfattach dwiic_pci_ca = {
+       sizeof(struct dwiic_softc),
+       dwiic_pci_match,
+       dwiic_pci_attach,
+       NULL,
+       dwiic_pci_activate,
+};
+
+const struct pci_matchid dwiic_pci_ids[] = {
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_100SERIES_LP_I2C_1 },
+       { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_100SERIES_LP_I2C_2 },
+};
+
+int
+dwiic_pci_match(struct device *parent, void *match, void *aux)
+{
+       return (pci_matchbyid(aux, dwiic_pci_ids, nitems(dwiic_pci_ids)));
+}
+
+void
+dwiic_pci_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct dwiic_softc *sc = (struct dwiic_softc *)self;
+       struct pci_attach_args *pa = aux;
+       bus_size_t iosize;
+       pci_intr_handle_t ih;
+       const char *intrstr = NULL;
+       uint8_t type;
+
+       memcpy(&sc->sc_paa, pa, sizeof(sc->sc_paa));
+
+       pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
+
+       if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_MEM_TYPE_64BIT, 0,
+           &sc->sc_iot, &sc->sc_ioh, NULL, &iosize, 0)) {
+               printf(": can't map mem space\n");
+               return;
+       }
+
+       sc->sc_caps = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LPSS_CAPS);
+       type = sc->sc_caps & LPSS_CAPS_TYPE_MASK;
+       type >>= LPSS_CAPS_TYPE_SHIFT;
+       if (type != 0) {
+               printf(": type %d not supported\n", type);
+               return;
+       }
+
+       /* un-reset - page 958 */
+       bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPSS_RESETS,
+           (LPSS_RESETS_I2C | LPSS_RESETS_IDMA));
+
+       /* fetch timing parameters */
+       sc->ss_hcnt = dwiic_read(sc, DW_IC_SS_SCL_HCNT);
+       sc->ss_lcnt = dwiic_read(sc, DW_IC_SS_SCL_LCNT);
+       sc->fs_hcnt = dwiic_read(sc, DW_IC_FS_SCL_HCNT);
+       sc->fs_lcnt = dwiic_read(sc, DW_IC_FS_SCL_LCNT);
+       sc->sda_hold_time = dwiic_read(sc, DW_IC_SDA_HOLD);
+
+       if (dwiic_init(sc)) {
+               printf(": failed initializing\n");
+               return;
+       }
+
+       /* leave the controller disabled */
+       dwiic_write(sc, DW_IC_INTR_MASK, 0);
+       dwiic_enable(sc, 0);
+       dwiic_read(sc, DW_IC_CLR_INTR);
+
+       /* install interrupt handler */
+       sc->sc_poll = 1;
+       if (pci_intr_map(&sc->sc_paa, &ih) == 0) {
+               intrstr = pci_intr_string(sc->sc_paa.pa_pc, ih);
+               sc->sc_ih = pci_intr_establish(sc->sc_paa.pa_pc, ih, IPL_BIO,
+                   dwiic_intr, sc, sc->sc_dev.dv_xname);
+               if (sc->sc_ih != NULL) {
+                       printf(": %s", intrstr);
+                       sc->sc_poll = 0;
+               }
+       }
+       if (sc->sc_poll)
+               printf(": polling");
+
+       printf("\n");
+
+       rw_init(&sc->sc_i2c_lock, "iiclk");
+
+       /* setup and attach iic bus */
+       sc->sc_i2c_tag.ic_cookie = sc;
+       sc->sc_i2c_tag.ic_acquire_bus = dwiic_i2c_acquire_bus;
+       sc->sc_i2c_tag.ic_release_bus = dwiic_i2c_release_bus;
+       sc->sc_i2c_tag.ic_exec = dwiic_i2c_exec;
+       sc->sc_i2c_tag.ic_intr_establish = dwiic_i2c_intr_establish;
+       sc->sc_i2c_tag.ic_intr_string = dwiic_i2c_intr_string;
+
+       bzero(&sc->sc_iba, sizeof(sc->sc_iba));
+       sc->sc_iba.iba_name = "iic";
+       sc->sc_iba.iba_tag = &sc->sc_i2c_tag;
+       sc->sc_iba.iba_bus_scan = dwiic_pci_bus_scan;
+       sc->sc_iba.iba_bus_scan_arg = sc;
+
+       config_found((struct device *)sc, &sc->sc_iba, iicbus_print);
+
+       return;
+}
+
+int
+dwiic_pci_activate(struct device *self, int act)
+{
+       struct dwiic_softc *sc = (struct dwiic_softc *)self;
+
+       switch (act) {
+       case DVACT_WAKEUP:
+               bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPSS_RESETS,
+                   (LPSS_RESETS_I2C | LPSS_RESETS_IDMA));
+
+               dwiic_init(sc);
+
+               break;
+       }
+
+       dwiic_activate(self, act);
+
+       return 0;
+}
+
+void
+dwiic_pci_bus_scan(struct device *iic, struct i2cbus_attach_args *iba,
+    void *aux)
+{
+       struct dwiic_softc *sc = (struct dwiic_softc *)aux;
+
+       sc->sc_iic = iic;
+
+#if NACPI > 0
+       {
+               struct aml_node *n = acpi_pci_match((struct device *)aux,
+                   &sc->sc_paa);
+               if (n == NULL)
+                       return;
+
+               /*
+                * XXX: until we can figure out why interrupts don't arrive for
+                * i2c slave devices on intel 100 series and newer, force
+                * polling for ihidev.
+                */
+               sc->sc_poll_ihidev = 1;
+
+               aml_find_node(n, "_HID", dwiic_acpi_found_hid, sc);
+       }
+#endif
+}
Index: sys/dev/pci/files.pci
===================================================================
RCS file: /cvs/src/sys/dev/pci/files.pci,v
retrieving revision 1.329
diff -u -p -u -p -r1.329 files.pci
--- sys/dev/pci/files.pci       21 Jan 2017 10:58:15 -0000      1.329
+++ sys/dev/pci/files.pci       10 Nov 2017 15:56:34 -0000
@@ -807,5 +807,9 @@ file        dev/pci/xspd.c                  xspd
attach  virtio at pci with virtio_pci
file    dev/pci/virtio_pci.c            virtio_pci

+# Synopsys DesignWare I2C Controller
+attach dwiic at pci with dwiic_pci
+file   dev/pci/dwiic_pci.c             dwiic_pci
+
include "dev/pci/files.agp"
include "dev/pci/drm/files.drm"
Index: share/man/man4/dwiic.4
===================================================================
RCS file: /cvs/src/share/man/man4/dwiic.4,v
retrieving revision 1.2
diff -u -p -u -p -r1.2 dwiic.4
--- share/man/man4/dwiic.4      30 Jul 2016 15:44:45 -0000      1.2
+++ share/man/man4/dwiic.4      10 Nov 2017 15:56:34 -0000
@@ -22,6 +22,7 @@
.Nd Synopsys DesignWare I2C controller
.Sh SYNOPSIS
.Cd "dwiic* at acpi?"
+.Cd "dwiic* at pci?"
.Cd "iic* at dwiic?"
.Sh DESCRIPTION
The
@@ -33,6 +34,7 @@ framework.
.Sh SEE ALSO
.Xr acpi 4 ,
.Xr iic 4
+.Xr pci 4
.Sh HISTORY
The
.Nm
Index: sys/arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.447
diff -u -p -u -p -r1.447 GENERIC
--- sys/arch/amd64/conf/GENERIC 28 Oct 2017 01:37:52 -0000      1.447
+++ sys/arch/amd64/conf/GENERIC 10 Nov 2017 15:56:35 -0000
@@ -135,6 +135,7 @@ iic*        at nviic?
amdpm*  at pci?                 # AMD-7xx/8111 and NForce SMBus controller
iic*    at amdpm?
dwiic*  at acpi?                # DesignWare Synopsys i2c controller
+dwiic* at pci?
iic*    at dwiic?

itherm* at pci?                 # Intel 3400 Thermal Sensor
Index: sys/dev/acpi/acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.332
diff -u -p -u -p -r1.332 acpi.c
--- sys/dev/acpi/acpi.c 17 Aug 2017 05:16:27 -0000      1.332
+++ sys/dev/acpi/acpi.c 10 Nov 2017 15:56:45 -0000
@@ -71,7 +71,7 @@ int   acpi_hasprocfvs;

#define ACPIEN_RETRIES 15

-void   acpi_pci_match(struct device *, struct pci_attach_args *);
+struct aml_node *acpi_pci_match(struct device *, struct pci_attach_args *);
pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
void     acpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int);
int     acpi_pci_notify(struct aml_node *, int, void *);
@@ -669,7 +669,7 @@ acpi_getpci(struct aml_node *node, void return (1);
}

-void
+struct aml_node *
acpi_pci_match(struct device *dev, struct pci_attach_args *pa)
{
        struct acpi_pci *pdev;
@@ -695,7 +695,11 @@ acpi_pci_match(struct device *dev, struc
                acpi_pci_set_powerstate(pa->pa_pc, pa->pa_tag, state, 0);

                aml_register_notify(pdev->node, NULL, acpi_pci_notify, pdev, 0);
+
+               return pdev->node;
        }
+
+       return NULL;
}

pcireg_t
Index: sys/dev/acpi/dwiic.c
===================================================================
RCS file: sys/dev/acpi/dwiic.c
diff -N sys/dev/acpi/dwiic.c
--- sys/dev/acpi/dwiic.c        17 Aug 2017 20:41:16 -0000      1.24
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,1095 +0,0 @@
-/* $OpenBSD: dwiic.c,v 1.24 2017/08/17 20:41:16 kettenis Exp $ */
-/*
- * Synopsys DesignWare I2C controller
- *
- * Copyright (c) 2015, 2016 joshua stein <j...@openbsd.org>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/kthread.h>
-
-#include <dev/acpi/acpireg.h>
-#include <dev/acpi/acpivar.h>
-#include <dev/acpi/acpidev.h>
-#include <dev/acpi/amltypes.h>
-#include <dev/acpi/dsdt.h>
-
-#include <dev/i2c/i2cvar.h>
-
-/* #define DWIIC_DEBUG */
-
-#ifdef DWIIC_DEBUG
-#define DPRINTF(x) printf x
-#else
-#define DPRINTF(x)
-#endif
-
-/* register offsets */
-#define DW_IC_CON              0x0
-#define DW_IC_TAR              0x4
-#define DW_IC_DATA_CMD         0x10
-#define DW_IC_SS_SCL_HCNT      0x14
-#define DW_IC_SS_SCL_LCNT      0x18
-#define DW_IC_FS_SCL_HCNT      0x1c
-#define DW_IC_FS_SCL_LCNT      0x20
-#define DW_IC_INTR_STAT                0x2c
-#define DW_IC_INTR_MASK                0x30
-#define DW_IC_RAW_INTR_STAT    0x34
-#define DW_IC_RX_TL            0x38
-#define DW_IC_TX_TL            0x3c
-#define DW_IC_CLR_INTR         0x40
-#define DW_IC_CLR_RX_UNDER     0x44
-#define DW_IC_CLR_RX_OVER      0x48
-#define DW_IC_CLR_TX_OVER      0x4c
-#define DW_IC_CLR_RD_REQ       0x50
-#define DW_IC_CLR_TX_ABRT      0x54
-#define DW_IC_CLR_RX_DONE      0x58
-#define DW_IC_CLR_ACTIVITY     0x5c
-#define DW_IC_CLR_STOP_DET     0x60
-#define DW_IC_CLR_START_DET    0x64
-#define DW_IC_CLR_GEN_CALL     0x68
-#define DW_IC_ENABLE           0x6c
-#define DW_IC_STATUS           0x70
-#define DW_IC_TXFLR            0x74
-#define DW_IC_RXFLR            0x78
-#define DW_IC_SDA_HOLD         0x7c
-#define DW_IC_TX_ABRT_SOURCE   0x80
-#define DW_IC_ENABLE_STATUS    0x9c
-#define DW_IC_COMP_PARAM_1     0xf4
-#define DW_IC_COMP_VERSION     0xf8
-#define DW_IC_SDA_HOLD_MIN_VERS        0x3131312A
-#define DW_IC_COMP_TYPE                0xfc
-#define DW_IC_COMP_TYPE_VALUE  0x44570140
-
-#define DW_IC_CON_MASTER       0x1
-#define DW_IC_CON_SPEED_STD    0x2
-#define DW_IC_CON_SPEED_FAST   0x4
-#define DW_IC_CON_10BITADDR_MASTER 0x10
-#define DW_IC_CON_RESTART_EN   0x20
-#define DW_IC_CON_SLAVE_DISABLE        0x40
-
-#define DW_IC_DATA_CMD_READ    0x100
-#define DW_IC_DATA_CMD_STOP    0x200
-#define DW_IC_DATA_CMD_RESTART 0x400
-
-#define DW_IC_INTR_RX_UNDER    0x001
-#define DW_IC_INTR_RX_OVER     0x002
-#define DW_IC_INTR_RX_FULL     0x004
-#define DW_IC_INTR_TX_OVER     0x008
-#define DW_IC_INTR_TX_EMPTY    0x010
-#define DW_IC_INTR_RD_REQ      0x020
-#define DW_IC_INTR_TX_ABRT     0x040
-#define DW_IC_INTR_RX_DONE     0x080
-#define DW_IC_INTR_ACTIVITY    0x100
-#define DW_IC_INTR_STOP_DET    0x200
-#define DW_IC_INTR_START_DET   0x400
-#define DW_IC_INTR_GEN_CALL    0x800
-
-#define DW_IC_STATUS_ACTIVITY  0x1
-
-/* hardware abort codes from the DW_IC_TX_ABRT_SOURCE register */
-#define ABRT_7B_ADDR_NOACK     0
-#define ABRT_10ADDR1_NOACK     1
-#define ABRT_10ADDR2_NOACK     2
-#define ABRT_TXDATA_NOACK      3
-#define ABRT_GCALL_NOACK       4
-#define ABRT_GCALL_READ                5
-#define ABRT_SBYTE_ACKDET      7
-#define ABRT_SBYTE_NORSTRT     9
-#define ABRT_10B_RD_NORSTRT    10
-#define ABRT_MASTER_DIS                11
-#define ARB_LOST               12
-
-struct dwiic_crs {
-       int irq_int;
-       uint8_t irq_flags;
-       uint32_t addr_min;
-       uint32_t addr_bas;
-       uint32_t addr_len;
-       uint16_t i2c_addr;
-       struct aml_node *devnode;
-       struct aml_node *gpio_int_node;
-       uint16_t gpio_int_pin;
-       uint16_t gpio_int_flags;
-};
-
-struct dwiic_softc {
-       struct device           sc_dev;
-
-       bus_space_tag_t         sc_iot;
-       bus_space_handle_t      sc_ioh;
-
-       struct acpi_softc       *sc_acpi;
-       struct aml_node         *sc_devnode;
-       char                    sc_hid[16];
-       void                    *sc_ih;
-
-       struct i2cbus_attach_args sc_iba;
-       struct device           *sc_iic;
-
-       int                     sc_poll;
-       int                     sc_busy;
-       int                     sc_readwait;
-       int                     sc_writewait;
-
-       uint32_t                master_cfg;
-       uint16_t                ss_hcnt, ss_lcnt, fs_hcnt, fs_lcnt;
-       uint32_t                sda_hold_time;
-       int                     tx_fifo_depth;
-       int                     rx_fifo_depth;
-
-       struct i2c_controller   sc_i2c_tag;
-       struct rwlock           sc_i2c_lock;
-       struct {
-               i2c_op_t        op;
-               void            *buf;
-               size_t          len;
-               int             flags;
-               volatile int    error;
-       } sc_i2c_xfer;
-};
-
-int            dwiic_match(struct device *, void *, void *);
-void           dwiic_attach(struct device *, struct device *, void *);
-int            dwiic_detach(struct device *, int);
-int            dwiic_activate(struct device *, int);
-
-int            dwiic_init(struct dwiic_softc *);
-void           dwiic_enable(struct dwiic_softc *, int);
-int            dwiic_intr(void *);
-
-void *         dwiic_i2c_intr_establish(void *, void *, int,
-                   int (*)(void *), void *, const char *);
-const char *   dwiic_i2c_intr_string(void *, void *);
-
-int            dwiic_acpi_parse_crs(int, union acpi_resource *, void *);
-int            dwiic_acpi_found_hid(struct aml_node *, void *);
-int            dwiic_acpi_found_ihidev(struct dwiic_softc *,
-                   struct aml_node *, char *, struct dwiic_crs);
-int            dwiic_acpi_found_iatp(struct dwiic_softc *, struct aml_node *,
-                   char *, struct dwiic_crs);
-void           dwiic_acpi_get_params(struct dwiic_softc *, char *, uint16_t *,
-                   uint16_t *, uint32_t *);
-void           dwiic_acpi_power(struct dwiic_softc *, int);
-void           dwiic_bus_scan(struct device *, struct i2cbus_attach_args *,
-                   void *);
-
-int            dwiic_i2c_acquire_bus(void *, int);
-void           dwiic_i2c_release_bus(void *, int);
-uint32_t       dwiic_read(struct dwiic_softc *, int);
-void           dwiic_write(struct dwiic_softc *, int, uint32_t);
-int            dwiic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
-                   size_t, void *, size_t, int);
-void           dwiic_xfer_msg(struct dwiic_softc *);
-
-struct cfattach dwiic_ca = {
-       sizeof(struct dwiic_softc),
-       dwiic_match,
-       dwiic_attach,
-       NULL,
-       dwiic_activate
-};
-
-struct cfdriver dwiic_cd = {
-       NULL, "dwiic", DV_DULL
-};
-
-const char *dwiic_hids[] = {
-       "INT33C2",
-       "INT33C3",
-       "INT3432",
-       "INT3433",
-       "80860F41",
-       "808622C1",
-       NULL
-};
-
-const char *ihidev_hids[] = {
-       "PNP0C50",
-       "ACPI0C50",
-       NULL
-};
-
-const char *iatp_hids[] = {
-       "ATML0000",
-       "ATML0001",
-       NULL
-};
-
-int
-dwiic_match(struct device *parent, void *match, void *aux)
-{
-       struct acpi_attach_args *aaa = aux;
-       struct cfdata *cf = match;
-
-       return acpi_matchhids(aaa, dwiic_hids, cf->cf_driver->cd_name);
-}
-
-void
-dwiic_attach(struct device *parent, struct device *self, void *aux)
-{
-       struct dwiic_softc *sc = (struct dwiic_softc *)self;
-       struct acpi_attach_args *aa = aux;
-       struct aml_value res;
-       struct dwiic_crs crs;
-
-       sc->sc_acpi = (struct acpi_softc *)parent;
-       sc->sc_devnode = aa->aaa_node;
-       memcpy(&sc->sc_hid, aa->aaa_dev, sizeof(sc->sc_hid));
-
-       printf(": %s", sc->sc_devnode->name);
-
-       if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRS", 0, NULL, &res)) {
-               printf(", no _CRS method\n");
-               return;
-       }
-       if (res.type != AML_OBJTYPE_BUFFER || res.length < 5) {
-               printf(", invalid _CRS object (type %d len %d)\n",
-                   res.type, res.length);
-               aml_freevalue(&res);
-               return;
-       }
-       memset(&crs, 0, sizeof(crs));
-       crs.devnode = sc->sc_devnode;
-       aml_parse_resource(&res, dwiic_acpi_parse_crs, &crs);
-       aml_freevalue(&res);
-
-       if (crs.addr_bas == 0) {
-               printf(", can't find address\n");
-               return;
-       }
-
-       printf(" addr 0x%x/0x%x", crs.addr_bas, crs.addr_len);
-
-       sc->sc_iot = aa->aaa_memt;
-       if (bus_space_map(sc->sc_iot, crs.addr_bas, crs.addr_len, 0,
-           &sc->sc_ioh)) {
-               printf(", failed mapping at 0x%x\n", crs.addr_bas);
-               return;
-       }
-
-       /* power up the controller */
-       dwiic_acpi_power(sc, 1);
-
-       /* fetch timing parameters */
-       sc->ss_hcnt = dwiic_read(sc, DW_IC_SS_SCL_HCNT);
-       sc->ss_lcnt = dwiic_read(sc, DW_IC_SS_SCL_LCNT);
-       sc->fs_hcnt = dwiic_read(sc, DW_IC_FS_SCL_HCNT);
-       sc->fs_lcnt = dwiic_read(sc, DW_IC_FS_SCL_LCNT);
-       sc->sda_hold_time = dwiic_read(sc, DW_IC_SDA_HOLD);
-       dwiic_acpi_get_params(sc, "SSCN", &sc->ss_hcnt, &sc->ss_lcnt, NULL);
-       dwiic_acpi_get_params(sc, "FMCN", &sc->fs_hcnt, &sc->fs_lcnt,
-           &sc->sda_hold_time);
-
-       if (dwiic_init(sc)) {
-               printf(", failed initializing\n");
-               bus_space_unmap(sc->sc_iot, sc->sc_ioh, crs.addr_len);
-               return;
-       }
-
-       /* leave the controller disabled */
-       dwiic_write(sc, DW_IC_INTR_MASK, 0);
-       dwiic_enable(sc, 0);
-       dwiic_read(sc, DW_IC_CLR_INTR);
-
-       /* try to register interrupt with apic, but not fatal without it */
-       if (crs.irq_int > 0) {
-               printf(" irq %d", crs.irq_int);
-
-               sc->sc_ih = acpi_intr_establish(crs.irq_int, crs.irq_flags,
-                   IPL_BIO, dwiic_intr, sc, sc->sc_dev.dv_xname);
-               if (sc->sc_ih == NULL)
-                       printf(", can't establish interrupt");
-       }
-
-       printf("\n");
-
-       rw_init(&sc->sc_i2c_lock, "iiclk");
-
-       /* setup and attach iic bus */
-       sc->sc_i2c_tag.ic_cookie = sc;
-       sc->sc_i2c_tag.ic_acquire_bus = dwiic_i2c_acquire_bus;
-       sc->sc_i2c_tag.ic_release_bus = dwiic_i2c_release_bus;
-       sc->sc_i2c_tag.ic_exec = dwiic_i2c_exec;
-       sc->sc_i2c_tag.ic_intr_establish = dwiic_i2c_intr_establish;
-       sc->sc_i2c_tag.ic_intr_string = dwiic_i2c_intr_string;
-
-       bzero(&sc->sc_iba, sizeof(sc->sc_iba));
-       sc->sc_iba.iba_name = "iic";
-       sc->sc_iba.iba_tag = &sc->sc_i2c_tag;
-       sc->sc_iba.iba_bus_scan = dwiic_bus_scan;
-       sc->sc_iba.iba_bus_scan_arg = sc;
-
-       config_found((struct device *)sc, &sc->sc_iba, iicbus_print);
-
-       return;
-}
-
-int
-dwiic_detach(struct device *self, int flags)
-{
-       struct dwiic_softc *sc = (struct dwiic_softc *)self;
-
-       if (sc->sc_ih != NULL) {
-               intr_disestablish(sc->sc_ih);
-               sc->sc_ih = NULL;
-       }
-
-       return 0;
-}
-
-int
-dwiic_activate(struct device *self, int act)
-{
-       struct dwiic_softc *sc = (struct dwiic_softc *)self;
-
-       switch (act) {
-       case DVACT_SUSPEND:
-               /* disable controller */
-               dwiic_enable(sc, 0);
-
-               /* disable interrupts */
-               dwiic_write(sc, DW_IC_INTR_MASK, 0);
-               dwiic_read(sc, DW_IC_CLR_INTR);
-
-               /* power down the controller */
-               dwiic_acpi_power(sc, 0);
-
-               break;
-       case DVACT_WAKEUP:
-               /* power up the controller */
-               dwiic_acpi_power(sc, 1);
-
-               dwiic_init(sc);
-
-               break;
-       }
-
-       config_activate_children(self, act);
-
-       return 0;
-}
-
-int
-dwiic_acpi_parse_crs(int crsidx, union acpi_resource *crs, void *arg)
-{
-       struct dwiic_crs *sc_crs = arg;
-       struct aml_node *node;
-       uint16_t pin;
-
-       switch (AML_CRSTYPE(crs)) {
-       case SR_IRQ:
-               sc_crs->irq_int = ffs(letoh16(crs->sr_irq.irq_mask)) - 1;
-               sc_crs->irq_flags = crs->sr_irq.irq_flags;
-               break;
-
-       case LR_EXTIRQ:
-               sc_crs->irq_int = letoh32(crs->lr_extirq.irq[0]);
-               sc_crs->irq_flags = crs->lr_extirq.flags;
-               break;
-
-       case LR_GPIO:
-               node = aml_searchname(sc_crs->devnode,
-                   (char *)&crs->pad[crs->lr_gpio.res_off]);
-               pin = *(uint16_t *)&crs->pad[crs->lr_gpio.pin_off];
-               if (crs->lr_gpio.type == LR_GPIO_INT) {
-                       sc_crs->gpio_int_node = node;
-                       sc_crs->gpio_int_pin = pin;
-                       sc_crs->gpio_int_flags = crs->lr_gpio.tflags;
-               }
-               break;
-
-       case LR_MEM32:
-               sc_crs->addr_min = letoh32(crs->lr_m32._min);
-               sc_crs->addr_len = letoh32(crs->lr_m32._len);
-               break;
-
-       case LR_MEM32FIXED:
-               sc_crs->addr_bas = letoh32(crs->lr_m32fixed._bas);
-               sc_crs->addr_len = letoh32(crs->lr_m32fixed._len);
-               break;
-
-       case LR_SERBUS:
-               if (crs->lr_serbus.type == LR_SERBUS_I2C)
-                       sc_crs->i2c_addr = letoh16(crs->lr_i2cbus._adr);
-               break;
-
-       default:
-               DPRINTF(("%s: unknown resource type %d\n", __func__,
-                   AML_CRSTYPE(crs)));
-       }
-
-       return 0;
-}
-
-void
-dwiic_acpi_get_params(struct dwiic_softc *sc, char *method, uint16_t *hcnt,
-    uint16_t *lcnt, uint32_t *sda_hold_time)
-{
-       struct aml_value res;
-
-       if (!aml_searchname(sc->sc_devnode, method))
-               return;
-
-       if (aml_evalname(sc->sc_acpi, sc->sc_devnode, method, 0, NULL, &res)) {
-               printf(": eval of %s at %s failed", method,
-                   aml_nodename(sc->sc_devnode));
-               return;
-       }
-
-       if (res.type != AML_OBJTYPE_PACKAGE) {
-               printf(": %s is not a package (%d)", method, res.type);
-               aml_freevalue(&res);
-               return;
-       }
-
-       if (res.length <= 2) {
-               printf(": %s returned package of len %d", method, res.length);
-               aml_freevalue(&res);
-               return;
-       }
-
-       *hcnt = aml_val2int(res.v_package[0]);
-       *lcnt = aml_val2int(res.v_package[1]);
-       if (sda_hold_time)
-               *sda_hold_time = aml_val2int(res.v_package[2]);
-       aml_freevalue(&res);
-}
-
-void
-dwiic_bus_scan(struct device *iic, struct i2cbus_attach_args *iba, void *aux)
-{
-       struct dwiic_softc *sc = (struct dwiic_softc *)aux;
-
-       sc->sc_iic = iic;
-       aml_find_node(sc->sc_devnode, "_HID", dwiic_acpi_found_hid, sc);
-}
-
-int
-dwiic_i2c_print(void *aux, const char *pnp)
-{
-       struct i2c_attach_args *ia = aux;
-
-       if (pnp != NULL)
-               printf("%s at %s", ia->ia_name, pnp);
-
-       printf(" addr 0x%x", ia->ia_addr);
-
-       return UNCONF;
-}
-
-void *
-dwiic_i2c_intr_establish(void *cookie, void *ih, int level,
-    int (*func)(void *), void *arg, const char *name)
-{
-       struct dwiic_crs *crs = ih;
-
-       if (crs->gpio_int_node && crs->gpio_int_node->gpio) {
-               struct acpi_gpio *gpio = crs->gpio_int_node->gpio;
-               gpio->intr_establish(gpio->cookie, crs->gpio_int_pin,
-                                    crs->gpio_int_flags, func, arg);
-               return ih;
-       }
-
-       return acpi_intr_establish(crs->irq_int, crs->irq_flags,
-           level, func, arg, name);
-}
-
-const char *
-dwiic_i2c_intr_string(void *cookie, void *ih)
-{
-       struct dwiic_crs *crs = ih;
-       static char irqstr[64];
-
-       if (crs->gpio_int_node && crs->gpio_int_node->gpio)
-               snprintf(irqstr, sizeof(irqstr), "gpio %d", crs->gpio_int_pin);
-       else
-               snprintf(irqstr, sizeof(irqstr), "irq %d", crs->irq_int);
-
-       return irqstr;
-}
-
-int
-dwiic_matchhids(const char *hid, const char *hids[])
-{
-       int i;
-
-       for (i = 0; hids[i]; i++)
-               if (!strcmp(hid, hids[i]))
-                       return (1);
-
-       return (0);
-}
-
-int
-dwiic_acpi_found_hid(struct aml_node *node, void *arg)
-{
-       struct dwiic_softc *sc = (struct dwiic_softc *)arg;
-       struct dwiic_crs crs;
-       struct aml_value res;
-       int64_t sta;
-       char cdev[16], dev[16];
-
-       if (acpi_parsehid(node, arg, cdev, dev, 16) != 0)
-               return 0;
-
-       if (aml_evalinteger(acpi_softc, node->parent, "_STA", 0, NULL, &sta))
-               sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000;
-
-       if ((sta & STA_PRESENT) == 0)
-               return 0;
-
-       DPRINTF(("%s: found HID %s at %s\n", sc->sc_dev.dv_xname, dev,
-           aml_nodename(node)));
-
-       if (aml_evalname(acpi_softc, node->parent, "_CRS", 0, NULL, &res)) {
-               printf("%s: no _CRS method at %s\n", sc->sc_dev.dv_xname,
-                   aml_nodename(node->parent));
-               return (0);
-       }
-       if (res.type != AML_OBJTYPE_BUFFER || res.length < 5) {
-               printf("%s: invalid _CRS object (type %d len %d)\n",
-                   sc->sc_dev.dv_xname, res.type, res.length);
-               aml_freevalue(&res);
-               return (0);
-       }
-       memset(&crs, 0, sizeof(crs));
-       crs.devnode = sc->sc_devnode;
-       aml_parse_resource(&res, dwiic_acpi_parse_crs, &crs);
-       aml_freevalue(&res);
-
-       acpi_attach_deps(acpi_softc, node->parent);
-
-       if (dwiic_matchhids(cdev, ihidev_hids))
-               return dwiic_acpi_found_ihidev(sc, node, dev, crs);
-       else if (dwiic_matchhids(dev, iatp_hids))
-               return dwiic_acpi_found_iatp(sc, node, dev, crs);
-
-       return 0;
-}
-
-int
-dwiic_acpi_found_ihidev(struct dwiic_softc *sc, struct aml_node *node,
-    char *dev, struct dwiic_crs crs)
-{
-       struct i2c_attach_args ia;
-       struct aml_value cmd[4], res;
-
-       /* 3cdff6f7-4267-4555-ad05-b30a3d8938de */
-       static uint8_t i2c_hid_guid[] = {
-               0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45,
-               0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE,
-       };
-
-       if (!aml_searchname(node->parent, "_DSM")) {
-               printf("%s: couldn't find _DSM at %s\n", sc->sc_dev.dv_xname,
-                   aml_nodename(node->parent));
-               return 0;
-       }
-
-       bzero(&cmd, sizeof(cmd));
-       cmd[0].type = AML_OBJTYPE_BUFFER;
-       cmd[0].v_buffer = (uint8_t *)&i2c_hid_guid;
-       cmd[0].length = sizeof(i2c_hid_guid);
-       /* rev */
-       cmd[1].type = AML_OBJTYPE_INTEGER;
-       cmd[1].v_integer = 1;
-       cmd[1].length = 1;
-       /* func */
-       cmd[2].type = AML_OBJTYPE_INTEGER;
-       cmd[2].v_integer = 1; /* HID */
-       cmd[2].length = 1;
-       /* not used */
-       cmd[3].type = AML_OBJTYPE_PACKAGE;
-       cmd[3].length = 0;
-
-       if (aml_evalname(acpi_softc, node->parent, "_DSM", 4, cmd, &res)) {
-               printf("%s: eval of _DSM at %s failed\n",
-                   sc->sc_dev.dv_xname, aml_nodename(node->parent));
-               return 0;
-       }
-
-       if (res.type != AML_OBJTYPE_INTEGER) {
-               printf("%s: bad _DSM result at %s: %d\n",
-                   sc->sc_dev.dv_xname, aml_nodename(node->parent), res.type);
-               aml_freevalue(&res);
-               return 0;
-       }
-
-       memset(&ia, 0, sizeof(ia));
-       ia.ia_tag = sc->sc_iba.iba_tag;
-       ia.ia_size = 1;
-       ia.ia_name = "ihidev";
-       ia.ia_size = aml_val2int(&res); /* hid descriptor address */
-       ia.ia_addr = crs.i2c_addr;
-       ia.ia_cookie = dev;
-
-       aml_freevalue(&res);
-
-       if (crs.irq_int <= 0 && crs.gpio_int_node == NULL) {
-               printf("%s: couldn't find irq for %s\n", sc->sc_dev.dv_xname,
-                   aml_nodename(node->parent));
-               return 0;
-       }
-       ia.ia_intr = &crs;
-
-       if (config_found(sc->sc_iic, &ia, dwiic_i2c_print)) {
-               node->parent->attached = 1;
-               return 0;
-       }
-
-       return 1;
-}
-
-int
-dwiic_acpi_found_iatp(struct dwiic_softc *sc, struct aml_node *node, char *dev,
-    struct dwiic_crs crs)
-{
-       struct i2c_attach_args ia;
-       struct aml_value res;
-
-       if (aml_evalname(acpi_softc, node->parent, "GPIO", 0, NULL, &res))
-               /* no gpio, assume this is the bootloader interface */
-               return (0);
-
-       memset(&ia, 0, sizeof(ia));
-       ia.ia_tag = sc->sc_iba.iba_tag;
-       ia.ia_size = 1;
-       ia.ia_name = "iatp";
-       ia.ia_addr = crs.i2c_addr;
-       ia.ia_cookie = dev;
-
-       if (crs.irq_int <= 0 && crs.gpio_int_node == NULL) {
-               printf("%s: couldn't find irq for %s\n", sc->sc_dev.dv_xname,
-                  aml_nodename(node->parent));
-               return 0;
-       }
-       ia.ia_intr = &crs;
-
-       if (config_found(sc->sc_iic, &ia, dwiic_i2c_print)) {
-               node->parent->attached = 1;
-               return 0;
-       }
-
-       return 1;
-}
-
-uint32_t
-dwiic_read(struct dwiic_softc *sc, int offset)
-{
-       u_int32_t b = bus_space_read_4(sc->sc_iot, sc->sc_ioh, offset);
-
-       DPRINTF(("%s: read at 0x%x = 0x%x\n", sc->sc_dev.dv_xname, offset, b));
-
-       return b;
-}
-
-void
-dwiic_write(struct dwiic_softc *sc, int offset, uint32_t val)
-{
-       bus_space_write_4(sc->sc_iot, sc->sc_ioh, offset, val);
-
-       DPRINTF(("%s: write at 0x%x: 0x%x\n", sc->sc_dev.dv_xname, offset,
-           val));
-}
-
-int
-dwiic_i2c_acquire_bus(void *cookie, int flags)
-{
-       struct dwiic_softc *sc = cookie;
-
-       if (cold || sc->sc_poll || (flags & I2C_F_POLL))
-               return (0);
-
-       return rw_enter(&sc->sc_i2c_lock, RW_WRITE | RW_INTR);
-}
-
-void
-dwiic_i2c_release_bus(void *cookie, int flags)
-{
-       struct dwiic_softc *sc = cookie;
-
-       if (cold || sc->sc_poll || (flags & I2C_F_POLL))
-               return;
-
-       rw_exit(&sc->sc_i2c_lock);
-}
-
-int
-dwiic_init(struct dwiic_softc *sc)
-{
-       uint32_t reg;
-
-       /* make sure we're talking to a device we know */
-       reg = dwiic_read(sc, DW_IC_COMP_TYPE);
-       if (reg != DW_IC_COMP_TYPE_VALUE) {
-               DPRINTF(("%s: invalid component type 0x%x\n",
-                   sc->sc_dev.dv_xname, reg));
-               return 1;
-       }
-
-       /* disable the adapter */
-       dwiic_enable(sc, 0);
-
-       /* write standard-mode SCL timing parameters */
-       dwiic_write(sc, DW_IC_SS_SCL_HCNT, sc->ss_hcnt);
-       dwiic_write(sc, DW_IC_SS_SCL_LCNT, sc->ss_lcnt);
-
-       /* and fast-mode SCL timing parameters */
-       dwiic_write(sc, DW_IC_FS_SCL_HCNT, sc->fs_hcnt);
-       dwiic_write(sc, DW_IC_FS_SCL_LCNT, sc->fs_lcnt);
-
-       /* SDA hold time */
-       reg = dwiic_read(sc, DW_IC_COMP_VERSION);
-       if (reg >= DW_IC_SDA_HOLD_MIN_VERS)
-               dwiic_write(sc, DW_IC_SDA_HOLD, sc->sda_hold_time);
-
-       /* FIFO threshold levels */
-       sc->tx_fifo_depth = 32;
-       sc->rx_fifo_depth = 32;
-       dwiic_write(sc, DW_IC_TX_TL, sc->tx_fifo_depth / 2);
-       dwiic_write(sc, DW_IC_RX_TL, 0);
-
-       /* configure as i2c master with fast speed */
-       sc->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
-           DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
-       dwiic_write(sc, DW_IC_CON, sc->master_cfg);
-
-       return 0;
-}
-
-void
-dwiic_enable(struct dwiic_softc *sc, int enable)
-{
-       int retries;
-
-       for (retries = 100; retries > 0; retries--) {
-               dwiic_write(sc, DW_IC_ENABLE, enable);
-               if ((dwiic_read(sc, DW_IC_ENABLE_STATUS) & 1) == enable)
-                       return;
-
-               DELAY(25);
-       }
-
-       printf("%s: failed to %sable\n", sc->sc_dev.dv_xname,
-           (enable ? "en" : "dis"));
-}
-
-void
-dwiic_acpi_power(struct dwiic_softc *sc, int power)
-{
-       char ps[] = "_PS0";
-
-       if (!power)
-               ps[3] = '3';
-
-       if (aml_searchname(sc->sc_devnode, ps)) {
-               if (aml_evalname(sc->sc_acpi, sc->sc_devnode, ps, 0, NULL,
-                   NULL)) {
-                       printf("%s: failed powering %s with %s\n",
-                           sc->sc_dev.dv_xname, power ? "on" : "off",
-                           ps);
-                       return;
-               }
-
-               DELAY(10000); /* 10 milliseconds */
-       } else
-               DPRINTF(("%s: no %s method\n", sc->sc_dev.dv_xname, ps));
-
-       if (strcmp(sc->sc_hid, "INT3432") == 0 ||
-           strcmp(sc->sc_hid, "INT3433") == 0) {
-               /*
-                * XXX: broadwell i2c devices may need this for initial power
-                * up and/or after s3 resume.
-                *
-                * linux does this write via LPSS -> clk_register_gate ->
-                * clk_gate_enable -> clk_gate_endisable -> clk_writel
-                */
-               dwiic_write(sc, 0x800, 1);
-       }
-}
-
-int
-dwiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmdbuf,
-    size_t cmdlen, void *buf, size_t len, int flags)
-{
-       struct dwiic_softc *sc = cookie;
-       u_int32_t ic_con, st, cmd, resp;
-       int retries, tx_limit, rx_avail, x, readpos;
-       uint8_t *b;
-
-       if (sc->sc_busy)
-               return 1;
-
-       sc->sc_busy++;
-
-       DPRINTF(("%s: %s: op %d, addr 0x%02x, cmdlen %zu, len %zu, "
-           "flags 0x%02x\n", sc->sc_dev.dv_xname, __func__, op, addr, cmdlen,
-           len, flags));
-
-       /* setup transfer */
-       sc->sc_i2c_xfer.op = op;
-       sc->sc_i2c_xfer.buf = buf;
-       sc->sc_i2c_xfer.len = len;
-       sc->sc_i2c_xfer.flags = flags;
-       sc->sc_i2c_xfer.error = 0;
-
-       /* wait for bus to be idle */
-       for (retries = 100; retries > 0; retries--) {
-               st = dwiic_read(sc, DW_IC_STATUS);
-               if (!(st & DW_IC_STATUS_ACTIVITY))
-                       break;
-               DELAY(1000);
-       }
-       DPRINTF(("%s: %s: status 0x%x\n", sc->sc_dev.dv_xname, __func__, st));
-       if (st & DW_IC_STATUS_ACTIVITY) {
-               sc->sc_busy = 0;
-               return (1);
-       }
-
-       if (cold || sc->sc_poll)
-               flags |= I2C_F_POLL;
-
-       /* disable controller */
-       dwiic_enable(sc, 0);
-
-       /* set slave address */
-       ic_con = dwiic_read(sc, DW_IC_CON);
-       ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
-       dwiic_write(sc, DW_IC_CON, ic_con);
-       dwiic_write(sc, DW_IC_TAR, addr);
-
-       /* disable interrupts */
-       dwiic_write(sc, DW_IC_INTR_MASK, 0);
-       dwiic_read(sc, DW_IC_CLR_INTR);
-
-       /* enable controller */
-       dwiic_enable(sc, 1);
-
-       /* wait until the controller is ready for commands */
-       if (flags & I2C_F_POLL)
-               DELAY(200);
-       else {
-               dwiic_read(sc, DW_IC_CLR_INTR);
-               dwiic_write(sc, DW_IC_INTR_MASK, DW_IC_INTR_TX_EMPTY);
-
-               if (tsleep(&sc->sc_writewait, PRIBIO, "dwiic", hz / 2) != 0)
-                       printf("%s: timed out waiting for tx_empty intr\n",
-                           sc->sc_dev.dv_xname);
-       }
-
-       /* send our command, one byte at a time */
-       if (cmdlen > 0) {
-               b = (void *)cmdbuf;
-
-               DPRINTF(("%s: %s: sending cmd (len %zu):", sc->sc_dev.dv_xname,
-                   __func__, cmdlen));
-               for (x = 0; x < cmdlen; x++)
-                       DPRINTF((" %02x", b[x]));
-               DPRINTF(("\n"));
-
-               tx_limit = sc->tx_fifo_depth - dwiic_read(sc, DW_IC_TXFLR);
-               if (cmdlen > tx_limit) {
-                       /* TODO */
-                       printf("%s: can't write %zu (> %d)\n",
-                           sc->sc_dev.dv_xname, cmdlen, tx_limit);
-                       sc->sc_i2c_xfer.error = 1;
-                       sc->sc_busy = 0;
-                       return (1);
-               }
-
-               for (x = 0; x < cmdlen; x++) {
-                       cmd = b[x];
-                       /*
-                        * Generate STOP condition if this is the last
-                        * byte of the transfer.
-                        */
-                       if (x == (cmdlen - 1) && len == 0 && I2C_OP_STOP_P(op))
-                               cmd |= DW_IC_DATA_CMD_STOP;
-                       dwiic_write(sc, DW_IC_DATA_CMD, cmd);
-               }
-       }
-
-       b = (void *)buf;
-       x = readpos = 0;
-       tx_limit = sc->tx_fifo_depth - dwiic_read(sc, DW_IC_TXFLR);
-
-       DPRINTF(("%s: %s: need to read %zu bytes, can send %d read reqs\n",
-               sc->sc_dev.dv_xname, __func__, len, tx_limit));
-
-       while (x < len) {
-               if (I2C_OP_WRITE_P(op))
-                       cmd = b[x];
-               else
-                       cmd = DW_IC_DATA_CMD_READ;
-
-               /*
-                * Generate RESTART condition if we're reversing
-                * direction.
-                */
-               if (x == 0 && cmdlen > 0 && I2C_OP_READ_P(op))
-                       cmd |= DW_IC_DATA_CMD_RESTART;
-               /*
-                * Generate STOP conditon on the last byte of the
-                * transfer.
-                */
-               if (x == (len - 1) && I2C_OP_STOP_P(op))
-                       cmd |= DW_IC_DATA_CMD_STOP;
-
-               dwiic_write(sc, DW_IC_DATA_CMD, cmd);
-
-               tx_limit--;
-               x++;
-
-               /*
-                * As TXFLR fills up, we need to clear it out by reading all
-                * available data.
-                */
-               while (tx_limit == 0 || x == len) {
-                       DPRINTF(("%s: %s: tx_limit %d, sent %d read reqs\n",
-                           sc->sc_dev.dv_xname, __func__, tx_limit, x));
-
-                       if (flags & I2C_F_POLL) {
-                               for (retries = 100; retries > 0; retries--) {
-                                       rx_avail = dwiic_read(sc, DW_IC_RXFLR);
-                                       if (rx_avail > 0)
-                                               break;
-                                       DELAY(50);
-                               }
-                       } else {
-                               dwiic_read(sc, DW_IC_CLR_INTR);
-                               dwiic_write(sc, DW_IC_INTR_MASK,
-                                   DW_IC_INTR_RX_FULL);
-
-                               if (tsleep(&sc->sc_readwait, PRIBIO, "dwiic",
-                                   hz / 2) != 0)
-                                       printf("%s: timed out waiting for "
-                                           "rx_full intr\n",
-                                           sc->sc_dev.dv_xname);
-
-                               rx_avail = dwiic_read(sc, DW_IC_RXFLR);
-                       }
-
-                       if (rx_avail == 0) {
-                               printf("%s: timed out reading remaining %d\n",
-                                   sc->sc_dev.dv_xname,
-                                   (int)(len - 1 - readpos));
-                               sc->sc_i2c_xfer.error = 1;
-                               sc->sc_busy = 0;
-
-                               return (1);
-                       }
-
-                       DPRINTF(("%s: %s: %d avail to read (%zu remaining)\n",
-                           sc->sc_dev.dv_xname, __func__, rx_avail,
-                           len - readpos));
-
-                       while (rx_avail > 0) {
-                               resp = dwiic_read(sc, DW_IC_DATA_CMD);
-                               if (readpos < len) {
-                                       b[readpos] = resp;
-                                       readpos++;
-                               }
-                               rx_avail--;
-                       }
-
-                       if (readpos >= len)
-                               break;
-
-                       DPRINTF(("%s: still need to read %d bytes\n",
-                           sc->sc_dev.dv_xname, (int)(len - readpos)));
-                       tx_limit = sc->tx_fifo_depth -
-                           dwiic_read(sc, DW_IC_TXFLR);
-               }
-       }
-
-       sc->sc_busy = 0;
-
-       return 0;
-}
-
-uint32_t
-dwiic_read_clear_intrbits(struct dwiic_softc *sc)
-{
-       uint32_t stat;
-
-       stat = dwiic_read(sc, DW_IC_INTR_STAT);
-
-       if (stat & DW_IC_INTR_RX_UNDER)
-              dwiic_read(sc, DW_IC_CLR_RX_UNDER);
-       if (stat & DW_IC_INTR_RX_OVER)
-              dwiic_read(sc, DW_IC_CLR_RX_OVER);
-       if (stat & DW_IC_INTR_TX_OVER)
-              dwiic_read(sc, DW_IC_CLR_TX_OVER);
-       if (stat & DW_IC_INTR_RD_REQ)
-              dwiic_read(sc, DW_IC_CLR_RD_REQ);
-       if (stat & DW_IC_INTR_TX_ABRT)
-              dwiic_read(sc, DW_IC_CLR_TX_ABRT);
-       if (stat & DW_IC_INTR_RX_DONE)
-              dwiic_read(sc, DW_IC_CLR_RX_DONE);
-       if (stat & DW_IC_INTR_ACTIVITY)
-              dwiic_read(sc, DW_IC_CLR_ACTIVITY);
-       if (stat & DW_IC_INTR_STOP_DET)
-              dwiic_read(sc, DW_IC_CLR_STOP_DET);
-       if (stat & DW_IC_INTR_START_DET)
-              dwiic_read(sc, DW_IC_CLR_START_DET);
-       if (stat & DW_IC_INTR_GEN_CALL)
-              dwiic_read(sc, DW_IC_CLR_GEN_CALL);
-
-       return stat;
-}
-
-int
-dwiic_intr(void *arg)
-{
-       struct dwiic_softc *sc = arg;
-       uint32_t en, stat;
-
-       en = dwiic_read(sc, DW_IC_ENABLE);
-       /* probably for the other controller */
-       if (!en)
-               return 0;
-
-       stat = dwiic_read_clear_intrbits(sc);
-       DPRINTF(("%s: %s: enabled=0x%x stat=0x%x\n", sc->sc_dev.dv_xname,
-           __func__, en, stat));
-       if (!(stat & ~DW_IC_INTR_ACTIVITY))
-               return 1;
-
-       if (stat & DW_IC_INTR_TX_ABRT)
-               sc->sc_i2c_xfer.error = 1;
-
-       if (sc->sc_i2c_xfer.flags & I2C_F_POLL)
-               DPRINTF(("%s: %s: intr in poll mode?\n", sc->sc_dev.dv_xname,
-                   __func__));
-       else {
-               if (stat & DW_IC_INTR_RX_FULL) {
-                       dwiic_write(sc, DW_IC_INTR_MASK, 0);
-                       DPRINTF(("%s: %s: waking up reader\n",
-                           sc->sc_dev.dv_xname, __func__));
-                       wakeup(&sc->sc_readwait);
-               }
-               if (stat & DW_IC_INTR_TX_EMPTY) {
-                       dwiic_write(sc, DW_IC_INTR_MASK, 0);
-                       DPRINTF(("%s: %s: waking up writer\n",
-                           sc->sc_dev.dv_xname, __func__));
-                       wakeup(&sc->sc_writewait);
-               }
-       }
-
-       return 1;
-}
Index: sys/dev/acpi/dwiic_acpi.c
===================================================================
RCS file: sys/dev/acpi/dwiic_acpi.c
diff -N sys/dev/acpi/dwiic_acpi.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/dev/acpi/dwiic_acpi.c   10 Nov 2017 15:56:45 -0000
@@ -0,0 +1,536 @@
+/* $OpenBSD: dwiic.c,v 1.22 2016/10/25 06:48:58 pirofti Exp $ */
+/*
+ * Synopsys DesignWare I2C controller
+ *
+ * Copyright (c) 2015, 2016 joshua stein <j...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpidev.h>
+#include <dev/acpi/amltypes.h>
+#include <dev/acpi/dsdt.h>
+
+#include <dev/ic/dwiicvar.h>
+
+struct dwiic_crs {
+       int irq_int;
+       uint8_t irq_flags;
+       uint32_t addr_min;
+       uint32_t addr_bas;
+       uint32_t addr_len;
+       uint16_t i2c_addr;
+       struct aml_node *devnode;
+       struct aml_node *gpio_int_node;
+       uint16_t gpio_int_pin;
+       uint16_t gpio_int_flags;
+};
+
+int            dwiic_acpi_match(struct device *, void *, void *);
+void           dwiic_acpi_attach(struct device *, struct device *, void *);
+
+int            dwiic_init(struct dwiic_softc *);
+void           dwiic_enable(struct dwiic_softc *, int);
+int            dwiic_intr(void *);
+
+void *         dwiic_i2c_intr_establish(void *, void *, int,
+                   int (*)(void *), void *, const char *);
+const char *   dwiic_i2c_intr_string(void *, void *);
+
+int            dwiic_acpi_parse_crs(int, union acpi_resource *, void *);
+int            dwiic_acpi_found_ihidev(struct dwiic_softc *,
+                   struct aml_node *, char *, struct dwiic_crs);
+int            dwiic_acpi_found_iatp(struct dwiic_softc *, struct aml_node *,
+                   char *, struct dwiic_crs);
+void           dwiic_acpi_get_params(struct dwiic_softc *, char *, uint16_t *,
+                   uint16_t *, uint32_t *);
+void           dwiic_acpi_power(struct dwiic_softc *, int);
+void           dwiic_acpi_bus_scan(struct device *,
+                   struct i2cbus_attach_args *, void *);
+
+int            dwiic_i2c_acquire_bus(void *, int);
+void           dwiic_i2c_release_bus(void *, int);
+uint32_t       dwiic_read(struct dwiic_softc *, int);
+void           dwiic_write(struct dwiic_softc *, int, uint32_t);
+int            dwiic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
+                   size_t, void *, size_t, int);
+void           dwiic_xfer_msg(struct dwiic_softc *);
+
+struct cfattach dwiic_acpi_ca = {
+       sizeof(struct dwiic_softc),
+       dwiic_acpi_match,
+       dwiic_acpi_attach,
+       NULL,
+       dwiic_activate
+};
+
+const char *dwiic_hids[] = {
+       "INT33C2",
+       "INT33C3",
+       "INT3432",
+       "INT3433",
+       "80860F41",
+       "808622C1",
+       NULL
+};
+
+const char *ihidev_hids[] = {
+       "PNP0C50",
+       "ACPI0C50",
+       NULL
+};
+
+const char *iatp_hids[] = {
+       "ATML0000",
+       "ATML0001",
+       NULL
+};
+
+int
+dwiic_acpi_match(struct device *parent, void *match, void *aux)
+{
+       struct acpi_attach_args *aaa = aux;
+       struct cfdata *cf = match;
+
+       return acpi_matchhids(aaa, dwiic_hids, cf->cf_driver->cd_name);
+}
+
+void
+dwiic_acpi_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct dwiic_softc *sc = (struct dwiic_softc *)self;
+       struct acpi_attach_args *aa = aux;
+       struct aml_value res;
+       struct dwiic_crs crs;
+
+       sc->sc_acpi = (struct acpi_softc *)parent;
+       sc->sc_devnode = aa->aaa_node;
+       memcpy(&sc->sc_hid, aa->aaa_dev, sizeof(sc->sc_hid));
+
+       printf(": %s", sc->sc_devnode->name);
+
+       if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRS", 0, NULL, &res)) {
+               printf(", no _CRS method\n");
+               return;
+       }
+       if (res.type != AML_OBJTYPE_BUFFER || res.length < 5) {
+               printf(", invalid _CRS object (type %d len %d)\n",
+                   res.type, res.length);
+               aml_freevalue(&res);
+               return;
+       }
+       memset(&crs, 0, sizeof(crs));
+       crs.devnode = sc->sc_devnode;
+       aml_parse_resource(&res, dwiic_acpi_parse_crs, &crs);
+       aml_freevalue(&res);
+
+       if (crs.addr_bas == 0) {
+               printf(", can't find address\n");
+               return;
+       }
+
+       printf(" addr 0x%x/0x%x", crs.addr_bas, crs.addr_len);
+
+       sc->sc_iot = aa->aaa_memt;
+       if (bus_space_map(sc->sc_iot, crs.addr_bas, crs.addr_len, 0,
+           &sc->sc_ioh)) {
+               printf(", failed mapping at 0x%x\n", crs.addr_bas);
+               return;
+       }
+
+       /* power up the controller */
+       dwiic_acpi_power(sc, 1);
+
+       /* fetch timing parameters */
+       sc->ss_hcnt = dwiic_read(sc, DW_IC_SS_SCL_HCNT);
+       sc->ss_lcnt = dwiic_read(sc, DW_IC_SS_SCL_LCNT);
+       sc->fs_hcnt = dwiic_read(sc, DW_IC_FS_SCL_HCNT);
+       sc->fs_lcnt = dwiic_read(sc, DW_IC_FS_SCL_LCNT);
+       sc->sda_hold_time = dwiic_read(sc, DW_IC_SDA_HOLD);
+       dwiic_acpi_get_params(sc, "SSCN", &sc->ss_hcnt, &sc->ss_lcnt, NULL);
+       dwiic_acpi_get_params(sc, "FMCN", &sc->fs_hcnt, &sc->fs_lcnt,
+           &sc->sda_hold_time);
+
+       if (dwiic_init(sc)) {
+               printf(", failed initializing\n");
+               bus_space_unmap(sc->sc_iot, sc->sc_ioh, crs.addr_len);
+               return;
+       }
+
+       /* leave the controller disabled */
+       dwiic_write(sc, DW_IC_INTR_MASK, 0);
+       dwiic_enable(sc, 0);
+       dwiic_read(sc, DW_IC_CLR_INTR);
+
+       /* try to register interrupt with apic, but not fatal without it */
+       if (crs.irq_int > 0) {
+               printf(" irq %d", crs.irq_int);
+
+               sc->sc_ih = acpi_intr_establish(crs.irq_int, crs.irq_flags,
+                   IPL_BIO, dwiic_intr, sc, sc->sc_dev.dv_xname);
+               if (sc->sc_ih == NULL)
+                       printf(", can't establish interrupt");
+       }
+
+       printf("\n");
+
+       rw_init(&sc->sc_i2c_lock, "iiclk");
+
+       /* setup and attach iic bus */
+       sc->sc_i2c_tag.ic_cookie = sc;
+       sc->sc_i2c_tag.ic_acquire_bus = dwiic_i2c_acquire_bus;
+       sc->sc_i2c_tag.ic_release_bus = dwiic_i2c_release_bus;
+       sc->sc_i2c_tag.ic_exec = dwiic_i2c_exec;
+       sc->sc_i2c_tag.ic_intr_establish = dwiic_i2c_intr_establish;
+       sc->sc_i2c_tag.ic_intr_string = dwiic_i2c_intr_string;
+
+       bzero(&sc->sc_iba, sizeof(sc->sc_iba));
+       sc->sc_iba.iba_name = "iic";
+       sc->sc_iba.iba_tag = &sc->sc_i2c_tag;
+       sc->sc_iba.iba_bus_scan = dwiic_acpi_bus_scan;
+       sc->sc_iba.iba_bus_scan_arg = sc;
+
+       config_found((struct device *)sc, &sc->sc_iba, iicbus_print);
+
+       return;
+}
+
+int
+dwiic_acpi_parse_crs(int crsidx, union acpi_resource *crs, void *arg)
+{
+       struct dwiic_crs *sc_crs = arg;
+       struct aml_node *node;
+       uint16_t pin;
+
+       switch (AML_CRSTYPE(crs)) {
+       case SR_IRQ:
+               sc_crs->irq_int = ffs(letoh16(crs->sr_irq.irq_mask)) - 1;
+               sc_crs->irq_flags = crs->sr_irq.irq_flags;
+               break;
+
+       case LR_EXTIRQ:
+               sc_crs->irq_int = letoh32(crs->lr_extirq.irq[0]);
+               sc_crs->irq_flags = crs->lr_extirq.flags;
+               break;
+
+       case LR_GPIO:
+               node = aml_searchname(sc_crs->devnode,
+                   (char *)&crs->pad[crs->lr_gpio.res_off]);
+               pin = *(uint16_t *)&crs->pad[crs->lr_gpio.pin_off];
+               if (crs->lr_gpio.type == LR_GPIO_INT) {
+                       sc_crs->gpio_int_node = node;
+                       sc_crs->gpio_int_pin = pin;
+                       sc_crs->gpio_int_flags = crs->lr_gpio.tflags;
+               }
+               break;
+
+       case LR_MEM32:
+               sc_crs->addr_min = letoh32(crs->lr_m32._min);
+               sc_crs->addr_len = letoh32(crs->lr_m32._len);
+               break;
+
+       case LR_MEM32FIXED:
+               sc_crs->addr_bas = letoh32(crs->lr_m32fixed._bas);
+               sc_crs->addr_len = letoh32(crs->lr_m32fixed._len);
+               break;
+
+       case LR_SERBUS:
+               if (crs->lr_serbus.type == LR_SERBUS_I2C)
+                       sc_crs->i2c_addr = letoh16(crs->lr_i2cbus._adr);
+               break;
+
+       default:
+               DPRINTF(("%s: unknown resource type %d\n", __func__,
+                   AML_CRSTYPE(crs)));
+       }
+
+       return 0;
+}
+
+void
+dwiic_acpi_get_params(struct dwiic_softc *sc, char *method, uint16_t *hcnt,
+    uint16_t *lcnt, uint32_t *sda_hold_time)
+{
+       struct aml_value res;
+
+       if (!aml_searchname(sc->sc_devnode, method))
+               return;
+
+       if (aml_evalname(sc->sc_acpi, sc->sc_devnode, method, 0, NULL, &res)) {
+               printf(": eval of %s at %s failed", method,
+                   aml_nodename(sc->sc_devnode));
+               return;
+       }
+
+       if (res.type != AML_OBJTYPE_PACKAGE) {
+               printf(": %s is not a package (%d)", method, res.type);
+               aml_freevalue(&res);
+               return;
+       }
+
+       if (res.length <= 2) {
+               printf(": %s returned package of len %d", method, res.length);
+               aml_freevalue(&res);
+               return;
+       }
+
+       *hcnt = aml_val2int(res.v_package[0]);
+       *lcnt = aml_val2int(res.v_package[1]);
+       if (sda_hold_time)
+               *sda_hold_time = aml_val2int(res.v_package[2]);
+       aml_freevalue(&res);
+}
+
+void
+dwiic_acpi_bus_scan(struct device *iic, struct i2cbus_attach_args *iba,
+    void *aux)
+{
+       struct dwiic_softc *sc = (struct dwiic_softc *)aux;
+
+       sc->sc_iic = iic;
+       aml_find_node(sc->sc_devnode, "_HID", dwiic_acpi_found_hid, sc);
+}
+
+void *
+dwiic_i2c_intr_establish(void *cookie, void *ih, int level,
+    int (*func)(void *), void *arg, const char *name)
+{
+       struct dwiic_crs *crs = ih;
+
+       if (crs->gpio_int_node && crs->gpio_int_node->gpio) {
+               struct acpi_gpio *gpio = crs->gpio_int_node->gpio;
+               gpio->intr_establish(gpio->cookie, crs->gpio_int_pin,
+                                    crs->gpio_int_flags, func, arg);
+               return ih;
+       }
+
+       return acpi_intr_establish(crs->irq_int, crs->irq_flags,
+           level, func, arg, name);
+}
+
+const char *
+dwiic_i2c_intr_string(void *cookie, void *ih)
+{
+       struct dwiic_crs *crs = ih;
+       static char irqstr[64];
+
+       if (crs->gpio_int_node && crs->gpio_int_node->gpio)
+               snprintf(irqstr, sizeof(irqstr), "gpio %d", crs->gpio_int_pin);
+       else
+               snprintf(irqstr, sizeof(irqstr), "irq %d", crs->irq_int);
+
+       return irqstr;
+}
+
+int
+dwiic_matchhids(const char *hid, const char *hids[])
+{
+       int i;
+
+       for (i = 0; hids[i]; i++)
+               if (!strcmp(hid, hids[i]))
+                       return (1);
+
+       return (0);
+}
+
+int
+dwiic_acpi_found_hid(struct aml_node *node, void *arg)
+{
+       struct dwiic_softc *sc = (struct dwiic_softc *)arg;
+       struct dwiic_crs crs;
+       struct aml_value res;
+       int64_t sta;
+       char cdev[16], dev[16];
+
+       if (acpi_parsehid(node, arg, cdev, dev, 16) != 0)
+               return 0;
+
+       if (aml_evalinteger(acpi_softc, node->parent, "_STA", 0, NULL, &sta))
+               sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000;
+
+       if ((sta & STA_PRESENT) == 0)
+               return 0;
+
+       DPRINTF(("%s: found HID %s at %s\n", sc->sc_dev.dv_xname, dev,
+           aml_nodename(node)));
+
+       if (aml_evalname(acpi_softc, node->parent, "_CRS", 0, NULL, &res)) {
+               printf("%s: no _CRS method at %s\n", sc->sc_dev.dv_xname,
+                   aml_nodename(node->parent));
+               return (0);
+       }
+       if (res.type != AML_OBJTYPE_BUFFER || res.length < 5) {
+               printf("%s: invalid _CRS object (type %d len %d)\n",
+                   sc->sc_dev.dv_xname, res.type, res.length);
+               aml_freevalue(&res);
+               return (0);
+       }
+       memset(&crs, 0, sizeof(crs));
+       crs.devnode = sc->sc_devnode;
+       aml_parse_resource(&res, dwiic_acpi_parse_crs, &crs);
+       aml_freevalue(&res);
+
+       acpi_attach_deps(acpi_softc, node->parent);
+
+       if (dwiic_matchhids(cdev, ihidev_hids))
+               return dwiic_acpi_found_ihidev(sc, node, dev, crs);
+       else if (dwiic_matchhids(dev, iatp_hids))
+               return dwiic_acpi_found_iatp(sc, node, dev, crs);
+
+       return 0;
+}
+
+int
+dwiic_acpi_found_ihidev(struct dwiic_softc *sc, struct aml_node *node,
+    char *dev, struct dwiic_crs crs)
+{
+       struct i2c_attach_args ia;
+       struct aml_value cmd[4], res;
+
+       /* 3cdff6f7-4267-4555-ad05-b30a3d8938de */
+       static uint8_t i2c_hid_guid[] = {
+               0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45,
+               0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE,
+       };
+
+       if (!aml_searchname(node->parent, "_DSM")) {
+               printf("%s: couldn't find _DSM at %s\n", sc->sc_dev.dv_xname,
+                   aml_nodename(node->parent));
+               return 0;
+       }
+
+       bzero(&cmd, sizeof(cmd));
+       cmd[0].type = AML_OBJTYPE_BUFFER;
+       cmd[0].v_buffer = (uint8_t *)&i2c_hid_guid;
+       cmd[0].length = sizeof(i2c_hid_guid);
+       /* rev */
+       cmd[1].type = AML_OBJTYPE_INTEGER;
+       cmd[1].v_integer = 1;
+       cmd[1].length = 1;
+       /* func */
+       cmd[2].type = AML_OBJTYPE_INTEGER;
+       cmd[2].v_integer = 1; /* HID */
+       cmd[2].length = 1;
+       /* not used */
+       cmd[3].type = AML_OBJTYPE_PACKAGE;
+       cmd[3].length = 0;
+
+       if (aml_evalname(acpi_softc, node->parent, "_DSM", 4, cmd, &res)) {
+               printf("%s: eval of _DSM at %s failed\n",
+                   sc->sc_dev.dv_xname, aml_nodename(node->parent));
+               return 0;
+       }
+
+       if (res.type != AML_OBJTYPE_INTEGER) {
+               printf("%s: bad _DSM result at %s: %d\n",
+                   sc->sc_dev.dv_xname, aml_nodename(node->parent), res.type);
+               aml_freevalue(&res);
+               return 0;
+       }
+
+       memset(&ia, 0, sizeof(ia));
+       ia.ia_tag = sc->sc_iba.iba_tag;
+       ia.ia_size = 1;
+       ia.ia_name = "ihidev";
+       ia.ia_size = aml_val2int(&res); /* hid descriptor address */
+       ia.ia_addr = crs.i2c_addr;
+       ia.ia_cookie = dev;
+
+       aml_freevalue(&res);
+
+       if (!sc->sc_poll_ihidev &&
+           !(crs.irq_int == 0 && crs.gpio_int_node == NULL))
+               ia.ia_intr = &crs;
+
+       if (config_found(sc->sc_iic, &ia, dwiic_i2c_print)) {
+               node->parent->attached = 1;
+               return 0;
+       }
+
+       return 1;
+}
+
+int
+dwiic_acpi_found_iatp(struct dwiic_softc *sc, struct aml_node *node, char *dev,
+    struct dwiic_crs crs)
+{
+       struct i2c_attach_args ia;
+       struct aml_value res;
+
+       if (aml_evalname(acpi_softc, node->parent, "GPIO", 0, NULL, &res))
+               /* no gpio, assume this is the bootloader interface */
+               return (0);
+
+       memset(&ia, 0, sizeof(ia));
+       ia.ia_tag = sc->sc_iba.iba_tag;
+       ia.ia_size = 1;
+       ia.ia_name = "iatp";
+       ia.ia_addr = crs.i2c_addr;
+       ia.ia_cookie = dev;
+
+       if (crs.irq_int <= 0 && crs.gpio_int_node == NULL) {
+               printf("%s: couldn't find irq for %s\n", sc->sc_dev.dv_xname,
+                  aml_nodename(node->parent));
+               return 0;
+       }
+       ia.ia_intr = &crs;
+
+       if (config_found(sc->sc_iic, &ia, dwiic_i2c_print)) {
+               node->parent->attached = 1;
+               return 0;
+       }
+
+       return 1;
+}
+
+void
+dwiic_acpi_power(struct dwiic_softc *sc, int power)
+{
+       char ps[] = "_PS0";
+
+       if (!power)
+               ps[3] = '3';
+
+       if (aml_searchname(sc->sc_devnode, ps)) {
+               if (aml_evalname(sc->sc_acpi, sc->sc_devnode, ps, 0, NULL,
+                   NULL)) {
+                       printf("%s: failed powering %s with %s\n",
+                           sc->sc_dev.dv_xname, power ? "on" : "off",
+                           ps);
+                       return;
+               }
+
+               DELAY(10000); /* 10 milliseconds */
+       } else
+               DPRINTF(("%s: no %s method\n", sc->sc_dev.dv_xname, ps));
+
+       if (strcmp(sc->sc_hid, "INT3432") == 0 ||
+           strcmp(sc->sc_hid, "INT3433") == 0) {
+               /*
+                * XXX: broadwell i2c devices may need this for initial power
+                * up and/or after s3 resume.
+                *
+                * linux does this write via LPSS -> clk_register_gate ->
+                * clk_gate_enable -> clk_gate_endisable -> clk_writel
+                */
+               dwiic_write(sc, 0x800, 1);
+       }
+}
Index: sys/dev/acpi/files.acpi
===================================================================
RCS file: /cvs/src/sys/dev/acpi/files.acpi,v
retrieving revision 1.37
diff -u -p -u -p -r1.37 files.acpi
--- sys/dev/acpi/files.acpi     22 Feb 2017 16:39:56 -0000      1.37
+++ sys/dev/acpi/files.acpi     10 Nov 2017 15:56:45 -0000
@@ -127,9 +127,8 @@ attach      sdhc at acpi with sdhc_acpi
file    dev/acpi/sdhc_acpi.c            sdhc_acpi

# Synopsys DesignWare I2C controller
-device dwiic: i2cbus
-attach dwiic at acpi
-file   dev/acpi/dwiic.c                dwiic
+attach dwiic at acpi with dwiic_acpi
+file   dev/acpi/dwiic_acpi.c           dwiic_acpi

# Chromebook keyboard backlight
device  acpicbkbd
Index: sys/dev/ic/dwiic.c
===================================================================
RCS file: sys/dev/ic/dwiic.c
diff -N sys/dev/ic/dwiic.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/dev/ic/dwiic.c  10 Nov 2017 15:56:47 -0000
@@ -0,0 +1,490 @@
+/* $OpenBSD: dwiic.c,v 1.22 2016/10/25 06:48:58 pirofti Exp $ */
+/*
+ * Synopsys DesignWare I2C controller
+ *
+ * Copyright (c) 2015-2017 joshua stein <j...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpidev.h>
+#include <dev/acpi/amltypes.h>
+#include <dev/acpi/dsdt.h>
+
+#include <dev/i2c/i2cvar.h>
+
+#include <dev/ic/dwiicvar.h>
+
+int            dwiic_match(struct device *, void *, void *);
+void           dwiic_attach(struct device *, struct device *, void *);
+int            dwiic_detach(struct device *, int);
+int            dwiic_activate(struct device *, int);
+
+int            dwiic_init(struct dwiic_softc *);
+void           dwiic_enable(struct dwiic_softc *, int);
+int            dwiic_intr(void *);
+
+void *         dwiic_i2c_intr_establish(void *, void *, int,
+                   int (*)(void *), void *, const char *);
+const char *   dwiic_i2c_intr_string(void *, void *);
+
+int            dwiic_i2c_acquire_bus(void *, int);
+void           dwiic_i2c_release_bus(void *, int);
+uint32_t       dwiic_read(struct dwiic_softc *, int);
+void           dwiic_write(struct dwiic_softc *, int, uint32_t);
+int            dwiic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
+                   size_t, void *, size_t, int);
+void           dwiic_xfer_msg(struct dwiic_softc *);
+
+struct cfdriver dwiic_cd = {
+       NULL, "dwiic", DV_DULL
+};
+
+int
+dwiic_detach(struct device *self, int flags)
+{
+       struct dwiic_softc *sc = (struct dwiic_softc *)self;
+
+       if (sc->sc_ih != NULL) {
+               intr_disestablish(sc->sc_ih);
+               sc->sc_ih = NULL;
+       }
+
+       return 0;
+}
+
+int
+dwiic_activate(struct device *self, int act)
+{
+       struct dwiic_softc *sc = (struct dwiic_softc *)self;
+
+       switch (act) {
+       case DVACT_SUSPEND:
+               /* disable controller */
+               dwiic_enable(sc, 0);
+
+               /* disable interrupts */
+               dwiic_write(sc, DW_IC_INTR_MASK, 0);
+               dwiic_read(sc, DW_IC_CLR_INTR);
+
+#if notyet
+               /* power down the controller */
+               dwiic_acpi_power(sc, 0);
+#endif
+               break;
+       case DVACT_WAKEUP:
+#if notyet
+               /* power up the controller */
+               dwiic_acpi_power(sc, 1);
+#endif
+               dwiic_init(sc);
+
+               break;
+       }
+
+       config_activate_children(self, act);
+
+       return 0;
+}
+
+int
+dwiic_i2c_print(void *aux, const char *pnp)
+{
+       struct i2c_attach_args *ia = aux;
+
+       if (pnp != NULL)
+               printf("%s at %s", ia->ia_name, pnp);
+
+       printf(" addr 0x%x", ia->ia_addr);
+
+       return UNCONF;
+}
+
+uint32_t
+dwiic_read(struct dwiic_softc *sc, int offset)
+{
+       u_int32_t b = bus_space_read_4(sc->sc_iot, sc->sc_ioh, offset);
+
+       DPRINTF(("%s: read at 0x%x = 0x%x\n", sc->sc_dev.dv_xname, offset, b));
+
+       return b;
+}
+
+void
+dwiic_write(struct dwiic_softc *sc, int offset, uint32_t val)
+{
+       DPRINTF(("%s: write at 0x%x: 0x%x\n", sc->sc_dev.dv_xname, offset,
+           val));
+
+       bus_space_write_4(sc->sc_iot, sc->sc_ioh, offset, val);
+}
+
+int
+dwiic_i2c_acquire_bus(void *cookie, int flags)
+{
+       struct dwiic_softc *sc = cookie;
+
+       if (cold || sc->sc_poll || (flags & I2C_F_POLL))
+               return (0);
+
+       return rw_enter(&sc->sc_i2c_lock, RW_WRITE | RW_INTR);
+}
+
+void
+dwiic_i2c_release_bus(void *cookie, int flags)
+{
+       struct dwiic_softc *sc = cookie;
+
+       if (cold || sc->sc_poll || (flags & I2C_F_POLL))
+               return;
+
+       rw_exit(&sc->sc_i2c_lock);
+}
+
+int
+dwiic_init(struct dwiic_softc *sc)
+{
+       uint32_t reg;
+
+       /* make sure we're talking to a device we know */
+       reg = dwiic_read(sc, DW_IC_COMP_TYPE);
+       if (reg != DW_IC_COMP_TYPE_VALUE) {
+               DPRINTF(("%s: invalid component type 0x%x\n",
+                   sc->sc_dev.dv_xname, reg));
+               return 1;
+       }
+
+       /* disable the adapter */
+       dwiic_enable(sc, 0);
+
+       /* write standard-mode SCL timing parameters */
+       dwiic_write(sc, DW_IC_SS_SCL_HCNT, sc->ss_hcnt);
+       dwiic_write(sc, DW_IC_SS_SCL_LCNT, sc->ss_lcnt);
+
+       /* and fast-mode SCL timing parameters */
+       dwiic_write(sc, DW_IC_FS_SCL_HCNT, sc->fs_hcnt);
+       dwiic_write(sc, DW_IC_FS_SCL_LCNT, sc->fs_lcnt);
+
+       /* SDA hold time */
+       reg = dwiic_read(sc, DW_IC_COMP_VERSION);
+       if (reg >= DW_IC_SDA_HOLD_MIN_VERS)
+               dwiic_write(sc, DW_IC_SDA_HOLD, sc->sda_hold_time);
+
+       /* FIFO threshold levels */
+       sc->tx_fifo_depth = 32;
+       sc->rx_fifo_depth = 32;
+       dwiic_write(sc, DW_IC_TX_TL, sc->tx_fifo_depth / 2);
+       dwiic_write(sc, DW_IC_RX_TL, 0);
+
+       /* configure as i2c master with fast speed */
+       sc->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
+           DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
+       dwiic_write(sc, DW_IC_CON, sc->master_cfg);
+
+       return 0;
+}
+
+void
+dwiic_enable(struct dwiic_softc *sc, int enable)
+{
+       int retries;
+
+       for (retries = 100; retries > 0; retries--) {
+               dwiic_write(sc, DW_IC_ENABLE, enable);
+               if ((dwiic_read(sc, DW_IC_ENABLE_STATUS) & 1) == enable)
+                       return;
+
+               DELAY(25);
+       }
+
+       printf("%s: failed to %sable\n", sc->sc_dev.dv_xname,
+           (enable ? "en" : "dis"));
+}
+
+int
+dwiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmdbuf,
+    size_t cmdlen, void *buf, size_t len, int flags)
+{
+       struct dwiic_softc *sc = cookie;
+       u_int32_t ic_con, st, cmd, resp;
+       int retries, tx_limit, rx_avail, x, readpos;
+       uint8_t *b;
+
+       if (sc->sc_busy)
+               return 1;
+
+       sc->sc_busy++;
+
+       DPRINTF(("%s: %s: op %d, addr 0x%02x, cmdlen %zu, len %zu, "
+           "flags 0x%02x\n", sc->sc_dev.dv_xname, __func__, op, addr, cmdlen,
+           len, flags));
+
+       /* setup transfer */
+       sc->sc_i2c_xfer.op = op;
+       sc->sc_i2c_xfer.buf = buf;
+       sc->sc_i2c_xfer.len = len;
+       sc->sc_i2c_xfer.flags = flags;
+       sc->sc_i2c_xfer.error = 0;
+
+       /* wait for bus to be idle */
+       for (retries = 100; retries > 0; retries--) {
+               st = dwiic_read(sc, DW_IC_STATUS);
+               if (!(st & DW_IC_STATUS_ACTIVITY))
+                       break;
+               DELAY(1000);
+       }
+       DPRINTF(("%s: %s: status 0x%x\n", sc->sc_dev.dv_xname, __func__, st));
+       if (st & DW_IC_STATUS_ACTIVITY) {
+               sc->sc_busy = 0;
+               return (1);
+       }
+
+       if (cold || sc->sc_poll)
+               flags |= I2C_F_POLL;
+
+       /* disable controller */
+       dwiic_enable(sc, 0);
+
+       /* set slave address */
+       ic_con = dwiic_read(sc, DW_IC_CON);
+       ic_con &= ~DW_IC_CON_10BITADDR_MASTER;
+       dwiic_write(sc, DW_IC_CON, ic_con);
+       dwiic_write(sc, DW_IC_TAR, addr);
+
+       /* disable interrupts */
+       dwiic_write(sc, DW_IC_INTR_MASK, 0);
+       dwiic_read(sc, DW_IC_CLR_INTR);
+
+       /* enable controller */
+       dwiic_enable(sc, 1);
+
+       /* wait until the controller is ready for commands */
+       if (flags & I2C_F_POLL)
+               DELAY(200);
+       else {
+               dwiic_read(sc, DW_IC_CLR_INTR);
+               dwiic_write(sc, DW_IC_INTR_MASK, DW_IC_INTR_TX_EMPTY);
+
+               if (tsleep(&sc->sc_writewait, PRIBIO, "dwiic", hz / 2) != 0)
+                       printf("%s: timed out waiting for tx_empty intr\n",
+                           sc->sc_dev.dv_xname);
+       }
+
+       /* send our command, one byte at a time */
+       if (cmdlen > 0) {
+               b = (void *)cmdbuf;
+
+               DPRINTF(("%s: %s: sending cmd (len %zu):", sc->sc_dev.dv_xname,
+                   __func__, cmdlen));
+               for (x = 0; x < cmdlen; x++)
+                       DPRINTF((" %02x", b[x]));
+               DPRINTF(("\n"));
+
+               tx_limit = sc->tx_fifo_depth - dwiic_read(sc, DW_IC_TXFLR);
+               if (cmdlen > tx_limit) {
+                       /* TODO */
+                       printf("%s: can't write %zu (> %d)\n",
+                           sc->sc_dev.dv_xname, cmdlen, tx_limit);
+                       sc->sc_i2c_xfer.error = 1;
+                       sc->sc_busy = 0;
+                       return (1);
+               }
+
+               for (x = 0; x < cmdlen; x++) {
+                       cmd = b[x];
+                       /*
+                        * Generate STOP condition if this is the last
+                        * byte of the transfer.
+                        */
+                       if (x == (cmdlen - 1) && len == 0 && I2C_OP_STOP_P(op))
+                               cmd |= DW_IC_DATA_CMD_STOP;
+                       dwiic_write(sc, DW_IC_DATA_CMD, cmd);
+               }
+       }
+
+       b = (void *)buf;
+       x = readpos = 0;
+       tx_limit = sc->tx_fifo_depth - dwiic_read(sc, DW_IC_TXFLR);
+
+       DPRINTF(("%s: %s: need to read %zu bytes, can send %d read reqs\n",
+               sc->sc_dev.dv_xname, __func__, len, tx_limit));
+
+       while (x < len) {
+               if (I2C_OP_WRITE_P(op))
+                       cmd = b[x];
+               else
+                       cmd = DW_IC_DATA_CMD_READ;
+
+               /*
+                * Generate RESTART condition if we're reversing
+                * direction.
+                */
+               if (x == 0 && cmdlen > 0 && I2C_OP_READ_P(op))
+                       cmd |= DW_IC_DATA_CMD_RESTART;
+               /*
+                * Generate STOP conditon on the last byte of the
+                * transfer.
+                */
+               if (x == (len - 1) && I2C_OP_STOP_P(op))
+                       cmd |= DW_IC_DATA_CMD_STOP;
+
+               dwiic_write(sc, DW_IC_DATA_CMD, cmd);
+
+               tx_limit--;
+               x++;
+
+               /*
+                * As TXFLR fills up, we need to clear it out by reading all
+                * available data.
+                */
+               while (tx_limit == 0 || x == len) {
+                       DPRINTF(("%s: %s: tx_limit %d, sent %d read reqs\n",
+                           sc->sc_dev.dv_xname, __func__, tx_limit, x));
+
+                       if (flags & I2C_F_POLL) {
+                               for (retries = 100; retries > 0; retries--) {
+                                       rx_avail = dwiic_read(sc, DW_IC_RXFLR);
+                                       if (rx_avail > 0)
+                                               break;
+                                       DELAY(50);
+                               }
+                       } else {
+                               dwiic_read(sc, DW_IC_CLR_INTR);
+                               dwiic_write(sc, DW_IC_INTR_MASK,
+                                   DW_IC_INTR_RX_FULL);
+
+                               if (tsleep(&sc->sc_readwait, PRIBIO, "dwiic",
+                                   hz / 2) != 0)
+                                       printf("%s: timed out waiting for "
+                                           "rx_full intr\n",
+                                           sc->sc_dev.dv_xname);
+
+                               rx_avail = dwiic_read(sc, DW_IC_RXFLR);
+                       }
+
+                       if (rx_avail == 0) {
+                               printf("%s: timed out reading remaining %d\n",
+                                   sc->sc_dev.dv_xname,
+                                   (int)(len - 1 - readpos));
+                               sc->sc_i2c_xfer.error = 1;
+                               sc->sc_busy = 0;
+
+                               return (1);
+                       }
+
+                       DPRINTF(("%s: %s: %d avail to read (%zu remaining)\n",
+                           sc->sc_dev.dv_xname, __func__, rx_avail,
+                           len - readpos));
+
+                       while (rx_avail > 0) {
+                               resp = dwiic_read(sc, DW_IC_DATA_CMD);
+                               if (readpos < len) {
+                                       b[readpos] = resp;
+                                       readpos++;
+                               }
+                               rx_avail--;
+                       }
+
+                       if (readpos >= len)
+                               break;
+
+                       DPRINTF(("%s: still need to read %d bytes\n",
+                           sc->sc_dev.dv_xname, (int)(len - readpos)));
+                       tx_limit = sc->tx_fifo_depth -
+                           dwiic_read(sc, DW_IC_TXFLR);
+               }
+       }
+
+       sc->sc_busy = 0;
+
+       return 0;
+}
+
+uint32_t
+dwiic_read_clear_intrbits(struct dwiic_softc *sc)
+{
+       uint32_t stat;
+
+       stat = dwiic_read(sc, DW_IC_INTR_STAT);
+
+       if (stat & DW_IC_INTR_RX_UNDER)
+              dwiic_read(sc, DW_IC_CLR_RX_UNDER);
+       if (stat & DW_IC_INTR_RX_OVER)
+              dwiic_read(sc, DW_IC_CLR_RX_OVER);
+       if (stat & DW_IC_INTR_TX_OVER)
+              dwiic_read(sc, DW_IC_CLR_TX_OVER);
+       if (stat & DW_IC_INTR_RD_REQ)
+              dwiic_read(sc, DW_IC_CLR_RD_REQ);
+       if (stat & DW_IC_INTR_TX_ABRT)
+              dwiic_read(sc, DW_IC_CLR_TX_ABRT);
+       if (stat & DW_IC_INTR_RX_DONE)
+              dwiic_read(sc, DW_IC_CLR_RX_DONE);
+       if (stat & DW_IC_INTR_ACTIVITY)
+              dwiic_read(sc, DW_IC_CLR_ACTIVITY);
+       if (stat & DW_IC_INTR_STOP_DET)
+              dwiic_read(sc, DW_IC_CLR_STOP_DET);
+       if (stat & DW_IC_INTR_START_DET)
+              dwiic_read(sc, DW_IC_CLR_START_DET);
+       if (stat & DW_IC_INTR_GEN_CALL)
+              dwiic_read(sc, DW_IC_CLR_GEN_CALL);
+
+       return stat;
+}
+
+int
+dwiic_intr(void *arg)
+{
+       struct dwiic_softc *sc = arg;
+       uint32_t en, stat;
+
+       en = dwiic_read(sc, DW_IC_ENABLE);
+       /* probably for the other controller */
+       if (!en)
+               return 0;
+
+       stat = dwiic_read_clear_intrbits(sc);
+       DPRINTF(("%s: %s: enabled=0x%x stat=0x%x\n", sc->sc_dev.dv_xname,
+           __func__, en, stat));
+       if (!(stat & ~DW_IC_INTR_ACTIVITY))
+               return 1;
+
+       if (stat & DW_IC_INTR_TX_ABRT)
+               sc->sc_i2c_xfer.error = 1;
+
+       if (sc->sc_i2c_xfer.flags & I2C_F_POLL)
+               DPRINTF(("%s: %s: intr in poll mode?\n", sc->sc_dev.dv_xname,
+                   __func__));
+       else {
+               if (stat & DW_IC_INTR_RX_FULL) {
+                       dwiic_write(sc, DW_IC_INTR_MASK, 0);
+                       DPRINTF(("%s: %s: waking up reader\n",
+                           sc->sc_dev.dv_xname, __func__));
+                       wakeup(&sc->sc_readwait);
+               }
+               if (stat & DW_IC_INTR_TX_EMPTY) {
+                       dwiic_write(sc, DW_IC_INTR_MASK, 0);
+                       DPRINTF(("%s: %s: waking up writer\n",
+                           sc->sc_dev.dv_xname, __func__));
+                       wakeup(&sc->sc_writewait);
+               }
+       }
+
+       return 1;
+}
Index: sys/dev/ic/dwiicreg.h
===================================================================
RCS file: sys/dev/ic/dwiicreg.h
diff -N sys/dev/ic/dwiicreg.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/dev/ic/dwiicreg.h       10 Nov 2017 15:56:47 -0000
@@ -0,0 +1,94 @@
+/* $OpenBSD$ */
+/*
+ * Synopsys DesignWare I2C controller
+ *
+ * Copyright (c) 2015, 2016 joshua stein <j...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* register offsets */
+#define DW_IC_CON              0x0
+#define DW_IC_TAR              0x4
+#define DW_IC_DATA_CMD         0x10
+#define DW_IC_SS_SCL_HCNT      0x14
+#define DW_IC_SS_SCL_LCNT      0x18
+#define DW_IC_FS_SCL_HCNT      0x1c
+#define DW_IC_FS_SCL_LCNT      0x20
+#define DW_IC_INTR_STAT                0x2c
+#define DW_IC_INTR_MASK                0x30
+#define DW_IC_RAW_INTR_STAT    0x34
+#define DW_IC_RX_TL            0x38
+#define DW_IC_TX_TL            0x3c
+#define DW_IC_CLR_INTR         0x40
+#define DW_IC_CLR_RX_UNDER     0x44
+#define DW_IC_CLR_RX_OVER      0x48
+#define DW_IC_CLR_TX_OVER      0x4c
+#define DW_IC_CLR_RD_REQ       0x50
+#define DW_IC_CLR_TX_ABRT      0x54
+#define DW_IC_CLR_RX_DONE      0x58
+#define DW_IC_CLR_ACTIVITY     0x5c
+#define DW_IC_CLR_STOP_DET     0x60
+#define DW_IC_CLR_START_DET    0x64
+#define DW_IC_CLR_GEN_CALL     0x68
+#define DW_IC_ENABLE           0x6c
+#define DW_IC_STATUS           0x70
+#define DW_IC_TXFLR            0x74
+#define DW_IC_RXFLR            0x78
+#define DW_IC_SDA_HOLD         0x7c
+#define DW_IC_TX_ABRT_SOURCE   0x80
+#define DW_IC_ENABLE_STATUS    0x9c
+#define DW_IC_COMP_PARAM_1     0xf4
+#define DW_IC_COMP_VERSION     0xf8
+#define DW_IC_SDA_HOLD_MIN_VERS        0x3131312A
+#define DW_IC_COMP_TYPE                0xfc
+#define DW_IC_COMP_TYPE_VALUE  0x44570140
+
+#define DW_IC_CON_MASTER       0x1
+#define DW_IC_CON_SPEED_STD    0x2
+#define DW_IC_CON_SPEED_FAST   0x4
+#define DW_IC_CON_10BITADDR_MASTER 0x10
+#define DW_IC_CON_RESTART_EN   0x20
+#define DW_IC_CON_SLAVE_DISABLE        0x40
+
+#define DW_IC_DATA_CMD_READ    0x100
+#define DW_IC_DATA_CMD_STOP    0x200
+#define DW_IC_DATA_CMD_RESTART 0x400
+
+#define DW_IC_INTR_RX_UNDER    0x001
+#define DW_IC_INTR_RX_OVER     0x002
+#define DW_IC_INTR_RX_FULL     0x004
+#define DW_IC_INTR_TX_OVER     0x008
+#define DW_IC_INTR_TX_EMPTY    0x010
+#define DW_IC_INTR_RD_REQ      0x020
+#define DW_IC_INTR_TX_ABRT     0x040
+#define DW_IC_INTR_RX_DONE     0x080
+#define DW_IC_INTR_ACTIVITY    0x100
+#define DW_IC_INTR_STOP_DET    0x200
+#define DW_IC_INTR_START_DET   0x400
+#define DW_IC_INTR_GEN_CALL    0x800
+
+#define DW_IC_STATUS_ACTIVITY  0x1
+
+/* hardware abort codes from the DW_IC_TX_ABRT_SOURCE register */
+#define ABRT_7B_ADDR_NOACK     0
+#define ABRT_10ADDR1_NOACK     1
+#define ABRT_10ADDR2_NOACK     2
+#define ABRT_TXDATA_NOACK      3
+#define ABRT_GCALL_NOACK       4
+#define ABRT_GCALL_READ                5
+#define ABRT_SBYTE_ACKDET      7
+#define ABRT_SBYTE_NORSTRT     9
+#define ABRT_10B_RD_NORSTRT    10
+#define ABRT_MASTER_DIS                11
+#define ARB_LOST               12
Index: sys/dev/ic/dwiicvar.h
===================================================================
RCS file: sys/dev/ic/dwiicvar.h
diff -N sys/dev/ic/dwiicvar.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/dev/ic/dwiicvar.h       10 Nov 2017 15:56:47 -0000
@@ -0,0 +1,103 @@
+/* $OpenBSD: dwiic.c,v 1.22 2016/10/25 06:48:58 pirofti Exp $ */
+/*
+ * Synopsys DesignWare I2C controller
+ *
+ * Copyright (c) 2015, 2016 joshua stein <j...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpidev.h>
+#include <dev/acpi/amltypes.h>
+#include <dev/acpi/dsdt.h>
+
+#include <dev/pci/pcivar.h>
+
+#include <dev/i2c/i2cvar.h>
+
+#include <dev/ic/dwiicreg.h>
+
+/* #define DWIIC_DEBUG */
+
+#ifdef DWIIC_DEBUG
+#define DPRINTF(x) printf x
+#else
+#define DPRINTF(x)
+#endif
+
+struct dwiic_softc {
+       struct device           sc_dev;
+
+       bus_space_tag_t         sc_iot;
+       bus_space_handle_t      sc_ioh;
+
+       struct acpi_softc       *sc_acpi;
+       struct aml_node         *sc_devnode;
+       char                    sc_hid[16];
+       void                    *sc_ih;
+
+       struct pci_attach_args  sc_paa;
+
+       struct i2cbus_attach_args sc_iba;
+       struct device           *sc_iic;
+
+       u_int32_t               sc_caps;
+       int                     sc_poll;
+       int                     sc_poll_ihidev;
+       int                     sc_busy;
+       int                     sc_readwait;
+       int                     sc_writewait;
+
+       uint32_t                master_cfg;
+       uint16_t                ss_hcnt, ss_lcnt, fs_hcnt, fs_lcnt;
+       uint32_t                sda_hold_time;
+       int                     tx_fifo_depth;
+       int                     rx_fifo_depth;
+
+       struct i2c_controller   sc_i2c_tag;
+       struct rwlock           sc_i2c_lock;
+       struct {
+               i2c_op_t        op;
+               void            *buf;
+               size_t          len;
+               int             flags;
+               volatile int    error;
+       } sc_i2c_xfer;
+};
+
+int            dwiic_activate(struct device *, int);
+int            dwiic_init(struct dwiic_softc *);
+void           dwiic_enable(struct dwiic_softc *, int);
+int            dwiic_intr(void *);
+
+void *         dwiic_i2c_intr_establish(void *, void *, int,
+                   int (*)(void *), void *, const char *);
+const char *   dwiic_i2c_intr_string(void *, void *);
+int            dwiic_i2c_print(void *, const char *);
+
+int            dwiic_i2c_acquire_bus(void *, int);
+void           dwiic_i2c_release_bus(void *, int);
+uint32_t       dwiic_read(struct dwiic_softc *, int);
+void           dwiic_write(struct dwiic_softc *, int, uint32_t);
+int            dwiic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
+                   size_t, void *, size_t, int);
+void           dwiic_xfer_msg(struct dwiic_softc *);
+
+int            dwiic_acpi_found_hid(struct aml_node *node, void *arg);

Reply via email to