1335b94f8SMatthew Dillon /*-
2335b94f8SMatthew Dillon * ichsmb_pci.c
3335b94f8SMatthew Dillon *
4335b94f8SMatthew Dillon * Author: Archie Cobbs <archie@freebsd.org>
5335b94f8SMatthew Dillon * Copyright (c) 2000 Whistle Communications, Inc.
6335b94f8SMatthew Dillon * All rights reserved.
7335b94f8SMatthew Dillon * Author: Archie Cobbs <archie@freebsd.org>
8335b94f8SMatthew Dillon *
9335b94f8SMatthew Dillon * Subject to the following obligations and disclaimer of warranty, use and
10335b94f8SMatthew Dillon * redistribution of this software, in source or object code forms, with or
11335b94f8SMatthew Dillon * without modifications are expressly permitted by Whistle Communications;
12335b94f8SMatthew Dillon * provided, however, that:
13335b94f8SMatthew Dillon * 1. Any and all reproductions of the source or object code must include the
14335b94f8SMatthew Dillon * copyright notice above and the following disclaimer of warranties; and
15335b94f8SMatthew Dillon * 2. No rights are granted, in any manner or form, to use Whistle
16335b94f8SMatthew Dillon * Communications, Inc. trademarks, including the mark "WHISTLE
17335b94f8SMatthew Dillon * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
18335b94f8SMatthew Dillon * such appears in the above copyright notice or in the software.
19335b94f8SMatthew Dillon *
20335b94f8SMatthew Dillon * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
21335b94f8SMatthew Dillon * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
22335b94f8SMatthew Dillon * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
23335b94f8SMatthew Dillon * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
24335b94f8SMatthew Dillon * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
25335b94f8SMatthew Dillon * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
26335b94f8SMatthew Dillon * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
27335b94f8SMatthew Dillon * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
28335b94f8SMatthew Dillon * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
29335b94f8SMatthew Dillon * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
30335b94f8SMatthew Dillon * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
31335b94f8SMatthew Dillon * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
32335b94f8SMatthew Dillon * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
33335b94f8SMatthew Dillon * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34335b94f8SMatthew Dillon * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35335b94f8SMatthew Dillon * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
36335b94f8SMatthew Dillon * OF SUCH DAMAGE.
37335b94f8SMatthew Dillon *
38335b94f8SMatthew Dillon * $FreeBSD: src/sys/dev/ichsmb/ichsmb_pci.c,v 1.25 2009/12/16 12:25:27 avg Exp $
39335b94f8SMatthew Dillon */
40335b94f8SMatthew Dillon
41335b94f8SMatthew Dillon /*
42335b94f8SMatthew Dillon * Support for the SMBus controller logical device which is part of the
43335b94f8SMatthew Dillon * Intel 81801AA/AB/BA/CA/DC/EB (ICH/ICH[02345]) I/O controller hub chips.
44335b94f8SMatthew Dillon */
45335b94f8SMatthew Dillon
46335b94f8SMatthew Dillon #include <sys/param.h>
47335b94f8SMatthew Dillon #include <sys/systm.h>
48335b94f8SMatthew Dillon #include <sys/kernel.h>
49335b94f8SMatthew Dillon #include <sys/module.h>
50335b94f8SMatthew Dillon #include <sys/errno.h>
51335b94f8SMatthew Dillon #include <sys/lock.h>
52335b94f8SMatthew Dillon #include <sys/syslog.h>
53335b94f8SMatthew Dillon #include <sys/bus.h>
54335b94f8SMatthew Dillon
55335b94f8SMatthew Dillon #include <sys/rman.h>
56335b94f8SMatthew Dillon
57335b94f8SMatthew Dillon #include <bus/pci/pcivar.h>
58335b94f8SMatthew Dillon #include <bus/pci/pcireg.h>
59335b94f8SMatthew Dillon
60335b94f8SMatthew Dillon #include <bus/smbus/smbconf.h>
61335b94f8SMatthew Dillon
62*6fbea5baSSascha Wildner #include <bus/smbus/ichsmb/ichsmb_var.h>
63*6fbea5baSSascha Wildner #include <bus/smbus/ichsmb/ichsmb_reg.h>
64335b94f8SMatthew Dillon
65335b94f8SMatthew Dillon /* PCI unique identifiers */
66f07e6439SImre Vadász #define PCI_VENDOR_INTEL 0x8086
67f07e6439SImre Vadász #define ID_82801AA 0x2413
68f07e6439SImre Vadász #define ID_82801AB 0x2423
69f07e6439SImre Vadász #define ID_82801BA 0x2443
70f07e6439SImre Vadász #define ID_82801CA 0x2483
71f07e6439SImre Vadász #define ID_82801DC 0x24C3
72f07e6439SImre Vadász #define ID_82801EB 0x24D3
73f07e6439SImre Vadász #define ID_82801FB 0x266A
74f07e6439SImre Vadász #define ID_82801GB 0x27da
75f07e6439SImre Vadász #define ID_82801H 0x283e
76f07e6439SImre Vadász #define ID_82801I 0x2930
77f07e6439SImre Vadász #define ID_EP80579 0x5032
78f07e6439SImre Vadász #define ID_82801JI 0x3a30
79f07e6439SImre Vadász #define ID_82801JD 0x3a60
80f07e6439SImre Vadász #define ID_PCH 0x3b30
81f07e6439SImre Vadász #define ID_6300ESB 0x25a4
82f07e6439SImre Vadász #define ID_631xESB 0x269b
83f07e6439SImre Vadász #define ID_DH89XXCC 0x2330
84f07e6439SImre Vadász #define ID_PATSBURG 0x1d22
85f07e6439SImre Vadász #define ID_CPT 0x1c22
86f07e6439SImre Vadász #define ID_PPT 0x1e22
87f07e6439SImre Vadász #define ID_AVOTON 0x1f3c
88f07e6439SImre Vadász #define ID_COLETOCRK 0x23B0
89f07e6439SImre Vadász #define ID_LPT 0x8c22
90f07e6439SImre Vadász #define ID_LPTLP 0x9c22
91f07e6439SImre Vadász #define ID_WCPT 0x8ca2
92f07e6439SImre Vadász #define ID_WCPTLP 0x9ca2
93f07e6439SImre Vadász #define ID_BAYTRAIL 0x0f12
94f07e6439SImre Vadász #define ID_BRASWELL 0x2292
95f07e6439SImre Vadász #define ID_WELLSBURG 0x8d22
96f07e6439SImre Vadász #define ID_SRPT 0xa123
97f07e6439SImre Vadász #define ID_SRPTLP 0x9d23
98f07e6439SImre Vadász #define ID_DENVERTON 0x19df
99f07e6439SImre Vadász #define ID_BROXTON 0x5ad4
100f07e6439SImre Vadász #define ID_LEWISBURG 0xa1a3
101f07e6439SImre Vadász #define ID_LEWISBURG2 0xa223
102f07e6439SImre Vadász #define ID_KABYLAKE 0xa2a3
103*6fbea5baSSascha Wildner #define ID_CANNONLAKE 0xa323
104*6fbea5baSSascha Wildner #define ID_COMETLAKE 0x02a3
105*6fbea5baSSascha Wildner #define ID_COMETLAKE2 0x06a3
106*6fbea5baSSascha Wildner #define ID_TIGERLAKE 0xa0a3
107*6fbea5baSSascha Wildner #define ID_TIGERLAKE2 0x43a3
108*6fbea5baSSascha Wildner #define ID_GEMINILAKE 0x31d4
109f07e6439SImre Vadász
110f07e6439SImre Vadász static const struct ichsmb_device {
111f07e6439SImre Vadász uint16_t id;
112f07e6439SImre Vadász const char *name;
113f07e6439SImre Vadász } ichsmb_devices[] = {
114f07e6439SImre Vadász { ID_82801AA, "Intel 82801AA (ICH) SMBus controller" },
115f07e6439SImre Vadász { ID_82801AB, "Intel 82801AB (ICH0) SMBus controller" },
116f07e6439SImre Vadász { ID_82801BA, "Intel 82801BA (ICH2) SMBus controller" },
117f07e6439SImre Vadász { ID_82801CA, "Intel 82801CA (ICH3) SMBus controller" },
118f07e6439SImre Vadász { ID_82801DC, "Intel 82801DC (ICH4) SMBus controller" },
119f07e6439SImre Vadász { ID_82801EB, "Intel 82801EB (ICH5) SMBus controller" },
120f07e6439SImre Vadász { ID_82801FB, "Intel 82801FB (ICH6) SMBus controller" },
121f07e6439SImre Vadász { ID_82801GB, "Intel 82801GB (ICH7) SMBus controller" },
122f07e6439SImre Vadász { ID_82801H, "Intel 82801H (ICH8) SMBus controller" },
123f07e6439SImre Vadász { ID_82801I, "Intel 82801I (ICH9) SMBus controller" },
124f07e6439SImre Vadász { ID_82801GB, "Intel 82801GB (ICH7) SMBus controller" },
125f07e6439SImre Vadász { ID_82801H, "Intel 82801H (ICH8) SMBus controller" },
126f07e6439SImre Vadász { ID_82801I, "Intel 82801I (ICH9) SMBus controller" },
127f07e6439SImre Vadász { ID_EP80579, "Intel EP80579 SMBus controller" },
128f07e6439SImre Vadász { ID_82801JI, "Intel 82801JI (ICH10) SMBus controller" },
129f07e6439SImre Vadász { ID_82801JD, "Intel 82801JD (ICH10) SMBus controller" },
130f07e6439SImre Vadász { ID_PCH, "Intel PCH SMBus controller" },
131f07e6439SImre Vadász { ID_6300ESB, "Intel 6300ESB (ICH) SMBus controller" },
132f07e6439SImre Vadász { ID_631xESB, "Intel 631xESB/6321ESB (ESB2) SMBus controller" },
133f07e6439SImre Vadász { ID_DH89XXCC, "Intel DH89xxCC SMBus controller" },
134f07e6439SImre Vadász { ID_PATSBURG, "Intel Patsburg SMBus controller" },
135f07e6439SImre Vadász { ID_CPT, "Intel Cougar Point SMBus controller" },
136f07e6439SImre Vadász { ID_PPT, "Intel Panther Point SMBus controller" },
137f07e6439SImre Vadász { ID_AVOTON, "Intel Avoton SMBus controller" },
138f07e6439SImre Vadász { ID_LPT, "Intel Lynx Point SMBus controller" },
139f07e6439SImre Vadász { ID_LPTLP, "Intel Lynx Point-LP SMBus controller" },
140f07e6439SImre Vadász { ID_WCPT, "Intel Wildcat Point SMBus controller" },
141f07e6439SImre Vadász { ID_WCPTLP, "Intel Wildcat Point-LP SMBus controller" },
142f07e6439SImre Vadász { ID_BAYTRAIL, "Intel Baytrail SMBus controller" },
143f07e6439SImre Vadász { ID_BRASWELL, "Intel Braswell SMBus controller" },
144f07e6439SImre Vadász { ID_COLETOCRK, "Intel Coleto Creek SMBus controller" },
145f07e6439SImre Vadász { ID_WELLSBURG, "Intel Wellsburg SMBus controller" },
146f07e6439SImre Vadász { ID_SRPT, "Intel Sunrise Point-H SMBus controller" },
147f07e6439SImre Vadász { ID_SRPTLP, "Intel Sunrise Point-LP SMBus controller" },
148f07e6439SImre Vadász { ID_DENVERTON, "Intel Denverton SMBus controller" },
149f07e6439SImre Vadász { ID_BROXTON, "Intel Broxton SMBus controller" },
150f07e6439SImre Vadász { ID_LEWISBURG, "Intel Lewisburg SMBus controller" },
151f07e6439SImre Vadász { ID_LEWISBURG2,"Intel Lewisburg SMBus controller" },
152f07e6439SImre Vadász { ID_KABYLAKE, "Intel Kaby Lake SMBus controller" },
153*6fbea5baSSascha Wildner { ID_CANNONLAKE,"Intel Cannon Lake SMBus controller" },
154*6fbea5baSSascha Wildner { ID_COMETLAKE, "Intel Comet Lake SMBus controller" },
155*6fbea5baSSascha Wildner { ID_COMETLAKE2,"Intel Comet Lake SMBus controller" },
156*6fbea5baSSascha Wildner { ID_TIGERLAKE, "Intel Tiger Lake SMBus controller" },
157*6fbea5baSSascha Wildner { ID_TIGERLAKE2,"Intel Tiger Lake SMBus controller" },
158*6fbea5baSSascha Wildner { ID_GEMINILAKE,"Intel Gemini Lake SMBus controller" },
159f07e6439SImre Vadász { 0, NULL },
160f07e6439SImre Vadász };
161335b94f8SMatthew Dillon
162335b94f8SMatthew Dillon /* Internal functions */
163335b94f8SMatthew Dillon static int ichsmb_pci_probe(device_t dev);
164335b94f8SMatthew Dillon static int ichsmb_pci_attach(device_t dev);
165335b94f8SMatthew Dillon /*Use generic one for now*/
166335b94f8SMatthew Dillon #if 0
167335b94f8SMatthew Dillon static int ichsmb_pci_detach(device_t dev);
168335b94f8SMatthew Dillon #endif
169335b94f8SMatthew Dillon
170335b94f8SMatthew Dillon /* Device methods */
171335b94f8SMatthew Dillon static device_method_t ichsmb_pci_methods[] = {
172335b94f8SMatthew Dillon /* Device interface */
173335b94f8SMatthew Dillon DEVMETHOD(device_probe, ichsmb_pci_probe),
174335b94f8SMatthew Dillon DEVMETHOD(device_attach, ichsmb_pci_attach),
175335b94f8SMatthew Dillon DEVMETHOD(device_detach, ichsmb_detach),
176335b94f8SMatthew Dillon
177335b94f8SMatthew Dillon /* Bus methods */
178335b94f8SMatthew Dillon DEVMETHOD(bus_print_child, bus_generic_print_child),
179335b94f8SMatthew Dillon
180335b94f8SMatthew Dillon /* SMBus methods */
181335b94f8SMatthew Dillon DEVMETHOD(smbus_callback, ichsmb_callback),
182335b94f8SMatthew Dillon DEVMETHOD(smbus_quick, ichsmb_quick),
183335b94f8SMatthew Dillon DEVMETHOD(smbus_sendb, ichsmb_sendb),
184335b94f8SMatthew Dillon DEVMETHOD(smbus_recvb, ichsmb_recvb),
185335b94f8SMatthew Dillon DEVMETHOD(smbus_writeb, ichsmb_writeb),
186335b94f8SMatthew Dillon DEVMETHOD(smbus_writew, ichsmb_writew),
187335b94f8SMatthew Dillon DEVMETHOD(smbus_readb, ichsmb_readb),
188335b94f8SMatthew Dillon DEVMETHOD(smbus_readw, ichsmb_readw),
189335b94f8SMatthew Dillon DEVMETHOD(smbus_pcall, ichsmb_pcall),
190335b94f8SMatthew Dillon DEVMETHOD(smbus_bwrite, ichsmb_bwrite),
191335b94f8SMatthew Dillon DEVMETHOD(smbus_bread, ichsmb_bread),
192335b94f8SMatthew Dillon DEVMETHOD_END
193335b94f8SMatthew Dillon };
194335b94f8SMatthew Dillon
195335b94f8SMatthew Dillon static driver_t ichsmb_pci_driver = {
196335b94f8SMatthew Dillon "ichsmb",
197335b94f8SMatthew Dillon ichsmb_pci_methods,
198335b94f8SMatthew Dillon sizeof(struct ichsmb_softc)
199335b94f8SMatthew Dillon };
200335b94f8SMatthew Dillon
201335b94f8SMatthew Dillon static devclass_t ichsmb_pci_devclass;
202335b94f8SMatthew Dillon
203335b94f8SMatthew Dillon DRIVER_MODULE(ichsmb, pci, ichsmb_pci_driver, ichsmb_pci_devclass, NULL, NULL);
204335b94f8SMatthew Dillon
205335b94f8SMatthew Dillon static int
ichsmb_pci_probe(device_t dev)206335b94f8SMatthew Dillon ichsmb_pci_probe(device_t dev)
207335b94f8SMatthew Dillon {
208f07e6439SImre Vadász const struct ichsmb_device *device;
209f07e6439SImre Vadász
210f07e6439SImre Vadász for (device = ichsmb_devices; device->name != NULL; device++) {
211f07e6439SImre Vadász if (pci_get_device(dev) == device->id) {
212f07e6439SImre Vadász device_set_desc(dev, device->name);
213f07e6439SImre Vadász return (ichsmb_probe(dev));
214f07e6439SImre Vadász }
215335b94f8SMatthew Dillon }
216335b94f8SMatthew Dillon
217f07e6439SImre Vadász return (ENXIO);
218335b94f8SMatthew Dillon }
219335b94f8SMatthew Dillon
220335b94f8SMatthew Dillon static int
ichsmb_pci_attach(device_t dev)221335b94f8SMatthew Dillon ichsmb_pci_attach(device_t dev)
222335b94f8SMatthew Dillon {
223335b94f8SMatthew Dillon const sc_p sc = device_get_softc(dev);
224335b94f8SMatthew Dillon int error;
225335b94f8SMatthew Dillon
226335b94f8SMatthew Dillon /* Initialize private state */
227335b94f8SMatthew Dillon bzero(sc, sizeof(*sc));
228335b94f8SMatthew Dillon sc->ich_cmd = -1;
229335b94f8SMatthew Dillon sc->dev = dev;
230335b94f8SMatthew Dillon
231335b94f8SMatthew Dillon /* Allocate an I/O range */
232335b94f8SMatthew Dillon sc->io_rid = ICH_SMB_BASE;
233335b94f8SMatthew Dillon sc->io_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
234335b94f8SMatthew Dillon &sc->io_rid, 0, ~0, 16, RF_ACTIVE);
235335b94f8SMatthew Dillon if (sc->io_res == NULL)
236335b94f8SMatthew Dillon sc->io_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
237335b94f8SMatthew Dillon &sc->io_rid, 0ul, ~0ul, 32, RF_ACTIVE);
238335b94f8SMatthew Dillon if (sc->io_res == NULL) {
239335b94f8SMatthew Dillon device_printf(dev, "can't map I/O\n");
240335b94f8SMatthew Dillon error = ENXIO;
241335b94f8SMatthew Dillon goto fail;
242335b94f8SMatthew Dillon }
243335b94f8SMatthew Dillon
244335b94f8SMatthew Dillon /* Allocate interrupt */
245335b94f8SMatthew Dillon sc->irq_rid = 0;
246335b94f8SMatthew Dillon sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
247335b94f8SMatthew Dillon &sc->irq_rid, RF_ACTIVE | RF_SHAREABLE);
248335b94f8SMatthew Dillon if (sc->irq_res == NULL) {
249335b94f8SMatthew Dillon device_printf(dev, "can't get IRQ\n");
250335b94f8SMatthew Dillon error = ENXIO;
251335b94f8SMatthew Dillon goto fail;
252335b94f8SMatthew Dillon }
253335b94f8SMatthew Dillon
254335b94f8SMatthew Dillon /* Enable device */
255335b94f8SMatthew Dillon pci_write_config(dev, ICH_HOSTC, ICH_HOSTC_HST_EN, 1);
256335b94f8SMatthew Dillon
257335b94f8SMatthew Dillon /* Done */
258335b94f8SMatthew Dillon error = ichsmb_attach(dev);
259335b94f8SMatthew Dillon if (error)
260335b94f8SMatthew Dillon goto fail;
261335b94f8SMatthew Dillon return (0);
262335b94f8SMatthew Dillon
263335b94f8SMatthew Dillon fail:
264335b94f8SMatthew Dillon /* Attach failed, release resources */
265335b94f8SMatthew Dillon ichsmb_release_resources(sc);
266335b94f8SMatthew Dillon return (error);
267335b94f8SMatthew Dillon }
268335b94f8SMatthew Dillon
269335b94f8SMatthew Dillon
270335b94f8SMatthew Dillon MODULE_DEPEND(ichsmb, pci, 1, 1, 1);
271335b94f8SMatthew Dillon MODULE_DEPEND(ichsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
272335b94f8SMatthew Dillon MODULE_VERSION(ichsmb, 1);
273