From: Gregory Norton Subject: ispi_pci: enable support for 9-series pch To: tech@openbsd.org Date: Wed, 10 Jun 2026 20:25:15 -0400 Hi all, first patch so might be rough. I've added support for the SPI part of the intel 9-series PCH as found on the 2015 macbook8,1. When used with the aplhidev patches from Joshua Stein, it enables the keyboard and trackpad to function (albeit some quirks with backlight). The 9-series (and 8-series) chipsets didn't yet support a dedicated reset register or the ability to check the device's capabilities. Referring to the source for intel_spi in FreeBSD, looks like they do a similar skip over those checks for older models. These changes should also open the path for 8-series, braswell, and baytrail chipsets if the need arises. - Greg diff --git sys/dev/ic/ispivar.h sys/dev/ic/ispivar.h index 6131616b5..8d44bda97 100644 --- sys/dev/ic/ispivar.h +++ sys/dev/ic/ispivar.h @@ -42,6 +42,13 @@ #define DPRINTF(x) #endif +enum ispi_version { + SPI_BAYTRAIL, + SPI_BRASWELL, + SPI_LYNXPOINT, + SPI_SUNRISEPOINT +}; + struct ispi_softc { struct device sc_dev; @@ -69,6 +76,7 @@ struct ispi_softc { struct aml_node *sc_devnode; #endif u_int32_t sc_caps; + enum ispi_version sc_vers; }; void ispi_init(struct ispi_softc *sc); diff --git sys/dev/pci/ispi_pci.c sys/dev/pci/ispi_pci.c index c77e67180..a23946336 100644 --- sys/dev/pci/ispi_pci.c +++ sys/dev/pci/ispi_pci.c @@ -44,6 +44,7 @@ const struct cfattach ispi_pci_ca = { }; const struct pci_matchid ispi_pci_ids[] = { + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_9SERIES_LP_SPI }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_100SERIES_LP_SPI_3 }, }; @@ -62,26 +63,34 @@ ispi_pci_attach(struct device *parent, struct device *self, void *aux) pci_intr_handle_t ih; const char *intrstr = NULL; uint8_t type; + int mtype; 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, + mtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START); + if (pci_mapreg_map(pa, PCI_MAPREG_START, mtype, 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) >> LPSS_CAPS_TYPE_SHIFT; - if (type != LPSS_CAPS_TYPE_SPI) { - printf(": type %d not supported\n", type); - return; - } - switch (PCI_PRODUCT(pa->pa_id)) { + case PCI_PRODUCT_INTEL_9SERIES_LP_SPI: + sc->sc_vers = SPI_LYNXPOINT; + + /* SPT */ + sc->sc_lpss_reg_offset = 0x800; + sc->sc_reg_cs_ctrl = 0x18; + sc->sc_rx_threshold = 2; + sc->sc_tx_threshold = 32; + sc->sc_tx_threshold_hi = 56; + sc->sc_ssp_clk = 9600000; + break; case PCI_PRODUCT_INTEL_100SERIES_LP_SPI_3: + sc->sc_vers = SPI_SUNRISEPOINT; + /* SPT */ sc->sc_lpss_reg_offset = 0x200; sc->sc_reg_cs_ctrl = 0x24; @@ -96,9 +105,27 @@ ispi_pci_attach(struct device *parent, struct device *self, void *aux) return; } - /* un-reset - page 958 */ - bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPSS_RESETS, - (LPSS_RESETS_FUNC | LPSS_RESETS_IDMA)); + sc->sc_caps = 0; + if (sc->sc_vers == SPI_SUNRISEPOINT) { + /* + * sunrise point supports capability validation + * and includes a dedicated reset register + */ + + /* validate capabilities */ + sc->sc_caps = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LPSS_CAPS); + type = (sc->sc_caps & LPSS_CAPS_TYPE_MASK) >> LPSS_CAPS_TYPE_SHIFT; + if (type != LPSS_CAPS_TYPE_SPI) { + printf(": type %d not supported\n", type); + bus_space_unmap(sc->sc_iot, sc->sc_ioh, iosize); + return; + } + + /* un-reset - page 958 */ + if (sc->sc_vers == SPI_SUNRISEPOINT) + bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPSS_RESETS, + (LPSS_RESETS_FUNC | LPSS_RESETS_IDMA)); + } /* install interrupt handler */ if (pci_intr_map(&sc->sc_paa, &ih) == 0) {