xref: /freebsd/sys/dev/intel/spi_acpi.c (revision 1f40866feb2135a4cf764a07b1b90a8a3398ff0a)
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