summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJoshua Stein <jcs@cvs.openbsd.org>2019-03-16 02:40:44 +0000
committerJoshua Stein <jcs@cvs.openbsd.org>2019-03-16 02:40:44 +0000
commit900bce9fbf0e363afa46e0f581d1e16ea11182bf (patch)
tree3c1ca9c6f453002f473c4047ffca45b8acc4e635 /sys
parent8dbdf67c8a66140f39431162ac96988391560c96 (diff)
fetch timing parameters from ACPI like the ACPI attachment does
since those fetched from the controller may not be correct also attach on intel 300 series devices ok kettenis
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/dwiicvar.h10
-rw-r--r--sys/dev/pci/dwiic_pci.c34
2 files changed, 33 insertions, 11 deletions
diff --git a/sys/dev/ic/dwiicvar.h b/sys/dev/ic/dwiicvar.h
index 92126f66b8b..1c2e3c5faf0 100644
--- a/sys/dev/ic/dwiicvar.h
+++ b/sys/dev/ic/dwiicvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dwiicvar.h,v 1.2 2018/01/19 18:20:38 jcs Exp $ */
+/* $OpenBSD: dwiicvar.h,v 1.3 2019/03/16 02:40:43 jcs Exp $ */
/*
* Synopsys DesignWare I2C controller
*
@@ -34,6 +34,8 @@
#include <dev/ic/dwiicreg.h>
+#include "acpi.h"
+
/* #define DWIIC_DEBUG */
#ifdef DWIIC_DEBUG
@@ -99,4 +101,8 @@ 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);
-int dwiic_acpi_found_hid(struct aml_node *node, void *arg);
+#if NACPI > 0
+int dwiic_acpi_found_hid(struct aml_node *, void *);
+void dwiic_acpi_get_params(struct dwiic_softc *, char *, uint16_t *,
+ uint16_t *, uint32_t *);
+#endif
diff --git a/sys/dev/pci/dwiic_pci.c b/sys/dev/pci/dwiic_pci.c
index 19c74a82c42..5eef1e2b023 100644
--- a/sys/dev/pci/dwiic_pci.c
+++ b/sys/dev/pci/dwiic_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dwiic_pci.c,v 1.3 2018/01/12 08:11:48 mlarkin Exp $ */
+/* $OpenBSD: dwiic_pci.c,v 1.4 2019/03/16 02:40:43 jcs Exp $ */
/*
* Synopsys DesignWare I2C controller
* PCI attachment
@@ -62,6 +62,12 @@ struct cfattach dwiic_pci_ca = {
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 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_1 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_2 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_3 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_4 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_5 },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_I2C_6 },
};
int
@@ -75,6 +81,9 @@ 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;
+#if NACPI > 0
+ struct aml_node *node;
+#endif
bus_size_t iosize;
pci_intr_handle_t ih;
const char *intrstr = NULL;
@@ -109,6 +118,19 @@ dwiic_pci_attach(struct device *parent, struct device *self, void *aux)
sc->fs_lcnt = dwiic_read(sc, DW_IC_FS_SCL_LCNT);
sc->sda_hold_time = dwiic_read(sc, DW_IC_SDA_HOLD);
+#if NACPI > 0
+ /* fetch more accurate timing parameters from ACPI, if possible */
+ node = acpi_pci_match(self, &sc->sc_paa);
+ if (node != NULL) {
+ sc->sc_devnode = node;
+
+ 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);
+ }
+#endif
+
if (dwiic_init(sc)) {
printf(": failed initializing\n");
return;
@@ -184,12 +206,7 @@ dwiic_pci_bus_scan(struct device *iic, struct i2cbus_attach_args *iba,
sc->sc_iic = iic;
-#if NACPI > 0
- {
- struct aml_node *node = acpi_pci_match(aux, &sc->sc_paa);
- if (node == NULL)
- return;
-
+ if (sc->sc_devnode != NULL) {
/*
* XXX: until we can figure out why interrupts don't arrive for
* i2c slave devices on intel 100 series and newer, force
@@ -197,7 +214,6 @@ dwiic_pci_bus_scan(struct device *iic, struct i2cbus_attach_args *iba,
*/
sc->sc_poll_ihidev = 1;
- aml_find_node(node, "_HID", dwiic_acpi_found_hid, sc);
+ aml_find_node(sc->sc_devnode, "_HID", dwiic_acpi_found_hid, sc);
}
-#endif
}