From: Gregory Norton Subject: Re: ispi_pci: enable support for 9-series pch To: tech@openbsd.org Date: Thu, 11 Jun 2026 10:13:33 -0400 I knew I would miss something obvious. Added the version type to the ispi_acpi variant as well in case we ever need to use it again from the ic/ispi code. Also removed the redundant check for the version in attach. - Greg diff --git sys/dev/acpi/ispi_acpi.c sys/dev/acpi/ispi_acpi.c index 2a648b2d4..cf1f38d3c 100644 --- sys/dev/acpi/ispi_acpi.c +++ sys/dev/acpi/ispi_acpi.c @@ -75,6 +75,7 @@ ispi_acpi_attach(struct device *parent, struct device *self, void *aux) sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_devnode = aa->aaa_node; + sc->sc_vers = SPI_SUNRISEPOINT; rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname); printf(": %s", sc->sc_devnode->name); 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..852f2c9b7 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,26 @@ 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 */ + 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) { On 2026-06-10 20:25, Gregory Norton wrote: > 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) { >