xref: /freebsd/sys/dev/intel/spi_acpi.c (revision fdafd315ad0d0f28a11b9fb4476a9ab059c62b92)
11f40866fSVal Packett /*-
21f40866fSVal Packett  * SPDX-License-Identifier: BSD-2-Clause
31f40866fSVal Packett  *
41f40866fSVal Packett  * Copyright (c) 2021 Val Packett <val@packett.cool>
51f40866fSVal Packett  *
61f40866fSVal Packett  * Redistribution and use in source and binary forms, with or without
71f40866fSVal Packett  * modification, are permitted provided that the following conditions
81f40866fSVal Packett  * are met:
91f40866fSVal Packett  * 1. Redistributions of source code must retain the above copyright
101f40866fSVal Packett  *    notice, this list of conditions and the following disclaimer.
111f40866fSVal Packett  * 2. Redistributions in binary form must reproduce the above copyright
121f40866fSVal Packett  *    notice, this list of conditions and the following disclaimer in the
131f40866fSVal Packett  *    documentation and/or other materials provided with the distribution.
141f40866fSVal Packett  *
151f40866fSVal Packett  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
161f40866fSVal Packett  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
171f40866fSVal Packett  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
181f40866fSVal Packett  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
191f40866fSVal Packett  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
201f40866fSVal Packett  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
211f40866fSVal Packett  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
221f40866fSVal Packett  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
231f40866fSVal Packett  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
241f40866fSVal Packett  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
251f40866fSVal Packett  * SUCH DAMAGE.
261f40866fSVal Packett  */
271f40866fSVal Packett 
281f40866fSVal Packett #include "opt_acpi.h"
291f40866fSVal Packett 
301f40866fSVal Packett #include <sys/param.h>
311f40866fSVal Packett #include <sys/bus.h>
321f40866fSVal Packett #include <sys/kernel.h>
331f40866fSVal Packett #include <sys/module.h>
341f40866fSVal Packett #include <sys/proc.h>
351f40866fSVal Packett #include <sys/rman.h>
361f40866fSVal Packett 
371f40866fSVal Packett #include <dev/intel/spi.h>
381f40866fSVal Packett 
391f40866fSVal Packett #include "spibus_if.h"
401f40866fSVal Packett 
411f40866fSVal Packett static const struct intelspi_acpi_device {
421f40866fSVal Packett 	const char *hid;
431f40866fSVal Packett 	enum intelspi_vers vers;
44*f56dbe7aSVladimir Kondratyev 	const char *desc;
451f40866fSVal Packett } intelspi_acpi_devices[] = {
46*f56dbe7aSVladimir Kondratyev 	{ "80860F0E", SPI_BAYTRAIL, "Intel Bay Trail SPI Controller" },
47*f56dbe7aSVladimir Kondratyev 	{ "8086228E", SPI_BRASWELL, "Intel Braswell SPI Controller" },
481f40866fSVal Packett };
491f40866fSVal Packett 
501f40866fSVal Packett static char *intelspi_ids[] = { "80860F0E", "8086228E", NULL };
511f40866fSVal Packett 
521f40866fSVal Packett static int
intelspi_acpi_probe(device_t dev)531f40866fSVal Packett intelspi_acpi_probe(device_t dev)
541f40866fSVal Packett {
551f40866fSVal Packett 	struct intelspi_softc *sc = device_get_softc(dev);
561f40866fSVal Packett 	char *hid;
571f40866fSVal Packett 	int i;
581f40866fSVal Packett 
591f40866fSVal Packett 	if (acpi_disabled("spi"))
601f40866fSVal Packett 		return (ENXIO);
611f40866fSVal Packett 
621f40866fSVal Packett 	if (ACPI_ID_PROBE(device_get_parent(dev), dev, intelspi_ids, &hid) > 0)
631f40866fSVal Packett 		return (ENXIO);
641f40866fSVal Packett 
651f40866fSVal Packett 	for (i = 0; i < nitems(intelspi_acpi_devices); i++) {
661f40866fSVal Packett 		if (strcmp(intelspi_acpi_devices[i].hid, hid) == 0) {
671f40866fSVal Packett 			sc->sc_vers = intelspi_acpi_devices[i].vers;
681f40866fSVal Packett 			sc->sc_handle = acpi_get_handle(dev);
69*f56dbe7aSVladimir Kondratyev 			device_set_desc(dev, intelspi_acpi_devices[i].desc);
701f40866fSVal Packett 			return (BUS_PROBE_DEFAULT);
711f40866fSVal Packett 		}
721f40866fSVal Packett 	}
731f40866fSVal Packett 
741f40866fSVal Packett 	return (ENXIO);
751f40866fSVal Packett }
761f40866fSVal Packett 
771f40866fSVal Packett static int
intelspi_acpi_attach(device_t dev)781f40866fSVal Packett intelspi_acpi_attach(device_t dev)
791f40866fSVal Packett {
801f40866fSVal Packett 	struct intelspi_softc *sc = device_get_softc(dev);
811f40866fSVal Packett 
821f40866fSVal Packett 	sc->sc_mem_rid = 0;
831f40866fSVal Packett 	sc->sc_irq_rid = 0;
841f40866fSVal Packett 
851f40866fSVal Packett 	return (intelspi_attach(dev));
861f40866fSVal Packett }
871f40866fSVal Packett 
881f40866fSVal Packett static device_method_t intelspi_acpi_methods[] = {
891f40866fSVal Packett 	/* Device interface */
901f40866fSVal Packett 	DEVMETHOD(device_probe, intelspi_acpi_probe),
911f40866fSVal Packett 	DEVMETHOD(device_attach, intelspi_acpi_attach),
921f40866fSVal Packett 	DEVMETHOD(device_detach, intelspi_detach),
931f40866fSVal Packett 	DEVMETHOD(device_suspend, intelspi_suspend),
941f40866fSVal Packett 	DEVMETHOD(device_resume, intelspi_resume),
951f40866fSVal Packett 
962a04c3a4SVladimir Kondratyev 	/* Bus interface */
972a04c3a4SVladimir Kondratyev 	DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
982a04c3a4SVladimir Kondratyev 	DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
992a04c3a4SVladimir Kondratyev 	DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
1002a04c3a4SVladimir Kondratyev 	DEVMETHOD(bus_release_resource, bus_generic_release_resource),
1012a04c3a4SVladimir Kondratyev 	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
1022a04c3a4SVladimir Kondratyev 	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
1032a04c3a4SVladimir Kondratyev 	DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
1042a04c3a4SVladimir Kondratyev 
1051f40866fSVal Packett 	/* SPI interface */
1061f40866fSVal Packett 	DEVMETHOD(spibus_transfer, intelspi_transfer),
1071f40866fSVal Packett 
1081f40866fSVal Packett 	DEVMETHOD_END
1091f40866fSVal Packett };
1101f40866fSVal Packett 
1111f40866fSVal Packett static driver_t intelspi_acpi_driver = {
1121f40866fSVal Packett 	"spi",
1131f40866fSVal Packett 	intelspi_acpi_methods,
1141f40866fSVal Packett 	sizeof(struct intelspi_softc),
1151f40866fSVal Packett };
1161f40866fSVal Packett 
1171f40866fSVal Packett DRIVER_MODULE(intelspi, acpi, intelspi_acpi_driver, 0, 0);
1181f40866fSVal Packett MODULE_DEPEND(intelspi, acpi, 1, 1, 1);
1191f40866fSVal Packett MODULE_DEPEND(intelspi, spibus, 1, 1, 1);
1201f40866fSVal Packett ACPI_PNP_INFO(intelspi_ids);
121