1*1f40866fSVal Packett /*- 2*1f40866fSVal Packett * SPDX-License-Identifier: BSD-2-Clause 3*1f40866fSVal Packett * 4*1f40866fSVal Packett * Copyright (c) 2021 Val Packett <val@packett.cool> 5*1f40866fSVal Packett * 6*1f40866fSVal Packett * Redistribution and use in source and binary forms, with or without 7*1f40866fSVal Packett * modification, are permitted provided that the following conditions 8*1f40866fSVal Packett * are met: 9*1f40866fSVal Packett * 1. Redistributions of source code must retain the above copyright 10*1f40866fSVal Packett * notice, this list of conditions and the following disclaimer. 11*1f40866fSVal Packett * 2. Redistributions in binary form must reproduce the above copyright 12*1f40866fSVal Packett * notice, this list of conditions and the following disclaimer in the 13*1f40866fSVal Packett * documentation and/or other materials provided with the distribution. 14*1f40866fSVal Packett * 15*1f40866fSVal Packett * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*1f40866fSVal Packett * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*1f40866fSVal Packett * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*1f40866fSVal Packett * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*1f40866fSVal Packett * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*1f40866fSVal Packett * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*1f40866fSVal Packett * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*1f40866fSVal Packett * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*1f40866fSVal Packett * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*1f40866fSVal Packett * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*1f40866fSVal Packett * SUCH DAMAGE. 26*1f40866fSVal Packett */ 27*1f40866fSVal Packett 28*1f40866fSVal Packett #include "opt_acpi.h" 29*1f40866fSVal Packett 30*1f40866fSVal Packett #include <sys/cdefs.h> 31*1f40866fSVal Packett #include <sys/param.h> 32*1f40866fSVal Packett #include <sys/bus.h> 33*1f40866fSVal Packett #include <sys/kernel.h> 34*1f40866fSVal Packett #include <sys/module.h> 35*1f40866fSVal Packett #include <sys/proc.h> 36*1f40866fSVal Packett #include <sys/rman.h> 37*1f40866fSVal Packett 38*1f40866fSVal Packett #include <dev/intel/spi.h> 39*1f40866fSVal Packett 40*1f40866fSVal Packett #include "spibus_if.h" 41*1f40866fSVal Packett 42*1f40866fSVal Packett static const struct intelspi_acpi_device { 43*1f40866fSVal Packett const char *hid; 44*1f40866fSVal Packett enum intelspi_vers vers; 45*1f40866fSVal Packett } intelspi_acpi_devices[] = { 46*1f40866fSVal Packett { "80860F0E", SPI_BAYTRAIL }, 47*1f40866fSVal Packett { "8086228E", SPI_BRASWELL }, 48*1f40866fSVal Packett }; 49*1f40866fSVal Packett 50*1f40866fSVal Packett static char *intelspi_ids[] = { "80860F0E", "8086228E", NULL }; 51*1f40866fSVal Packett 52*1f40866fSVal Packett static int 53*1f40866fSVal Packett intelspi_acpi_probe(device_t dev) 54*1f40866fSVal Packett { 55*1f40866fSVal Packett struct intelspi_softc *sc = device_get_softc(dev); 56*1f40866fSVal Packett char *hid; 57*1f40866fSVal Packett int i; 58*1f40866fSVal Packett 59*1f40866fSVal Packett if (acpi_disabled("spi")) 60*1f40866fSVal Packett return (ENXIO); 61*1f40866fSVal Packett 62*1f40866fSVal Packett if (ACPI_ID_PROBE(device_get_parent(dev), dev, intelspi_ids, &hid) > 0) 63*1f40866fSVal Packett return (ENXIO); 64*1f40866fSVal Packett 65*1f40866fSVal Packett for (i = 0; i < nitems(intelspi_acpi_devices); i++) { 66*1f40866fSVal Packett if (strcmp(intelspi_acpi_devices[i].hid, hid) == 0) { 67*1f40866fSVal Packett sc->sc_vers = intelspi_acpi_devices[i].vers; 68*1f40866fSVal Packett sc->sc_handle = acpi_get_handle(dev); 69*1f40866fSVal Packett device_set_desc(dev, intelspi_infos[sc->sc_vers].desc); 70*1f40866fSVal Packett return (BUS_PROBE_DEFAULT); 71*1f40866fSVal Packett } 72*1f40866fSVal Packett } 73*1f40866fSVal Packett 74*1f40866fSVal Packett return (ENXIO); 75*1f40866fSVal Packett } 76*1f40866fSVal Packett 77*1f40866fSVal Packett static int 78*1f40866fSVal Packett intelspi_acpi_attach(device_t dev) 79*1f40866fSVal Packett { 80*1f40866fSVal Packett struct intelspi_softc *sc = device_get_softc(dev); 81*1f40866fSVal Packett 82*1f40866fSVal Packett sc->sc_mem_rid = 0; 83*1f40866fSVal Packett sc->sc_irq_rid = 0; 84*1f40866fSVal Packett 85*1f40866fSVal Packett return (intelspi_attach(dev)); 86*1f40866fSVal Packett } 87*1f40866fSVal Packett 88*1f40866fSVal Packett static device_method_t intelspi_acpi_methods[] = { 89*1f40866fSVal Packett /* Device interface */ 90*1f40866fSVal Packett DEVMETHOD(device_probe, intelspi_acpi_probe), 91*1f40866fSVal Packett DEVMETHOD(device_attach, intelspi_acpi_attach), 92*1f40866fSVal Packett DEVMETHOD(device_detach, intelspi_detach), 93*1f40866fSVal Packett DEVMETHOD(device_suspend, intelspi_suspend), 94*1f40866fSVal Packett DEVMETHOD(device_resume, intelspi_resume), 95*1f40866fSVal Packett 96*1f40866fSVal Packett /* SPI interface */ 97*1f40866fSVal Packett DEVMETHOD(spibus_transfer, intelspi_transfer), 98*1f40866fSVal Packett 99*1f40866fSVal Packett DEVMETHOD_END 100*1f40866fSVal Packett }; 101*1f40866fSVal Packett 102*1f40866fSVal Packett static driver_t intelspi_acpi_driver = { 103*1f40866fSVal Packett "spi", 104*1f40866fSVal Packett intelspi_acpi_methods, 105*1f40866fSVal Packett sizeof(struct intelspi_softc), 106*1f40866fSVal Packett }; 107*1f40866fSVal Packett 108*1f40866fSVal Packett DRIVER_MODULE(intelspi, acpi, intelspi_acpi_driver, 0, 0); 109*1f40866fSVal Packett MODULE_DEPEND(intelspi, acpi, 1, 1, 1); 110*1f40866fSVal Packett MODULE_DEPEND(intelspi, spibus, 1, 1, 1); 111*1f40866fSVal Packett ACPI_PNP_INFO(intelspi_ids); 112