ichsmb_pci.c revision 345820
1207753Smm/*- 2207753Smm * ichsmb_pci.c 3207753Smm * 4207753Smm * Author: Archie Cobbs <archie@freebsd.org> 5207753Smm * Copyright (c) 2000 Whistle Communications, Inc. 6207753Smm * All rights reserved. 7207753Smm * Author: Archie Cobbs <archie@freebsd.org> 8207753Smm * 9207753Smm * Subject to the following obligations and disclaimer of warranty, use and 10207753Smm * redistribution of this software, in source or object code forms, with or 11207753Smm * without modifications are expressly permitted by Whistle Communications; 12207753Smm * provided, however, that: 13207753Smm * 1. Any and all reproductions of the source or object code must include the 14207753Smm * copyright notice above and the following disclaimer of warranties; and 15207753Smm * 2. No rights are granted, in any manner or form, to use Whistle 16207753Smm * Communications, Inc. trademarks, including the mark "WHISTLE 17207753Smm * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 18207753Smm * such appears in the above copyright notice or in the software. 19207753Smm * 20207753Smm * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 21207753Smm * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 22207753Smm * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 23207753Smm * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 24207753Smm * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 25207753Smm * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 26207753Smm * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 27207753Smm * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 28207753Smm * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 29207753Smm * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 30207753Smm * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 31207753Smm * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 32207753Smm * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 33207753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34207753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35207753Smm * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 36207753Smm * OF SUCH DAMAGE. 37207753Smm */ 38207753Smm 39207753Smm#include <sys/cdefs.h> 40207753Smm__FBSDID("$FreeBSD: stable/11/sys/dev/ichsmb/ichsmb_pci.c 345820 2019-04-03 01:29:54Z mav $"); 41207753Smm 42207753Smm/* 43207753Smm * Support for the SMBus controller logical device which is part of the 44207753Smm * Intel 81801AA/AB/BA/CA/DC/EB (ICH/ICH[02345]) I/O controller hub chips. 45207753Smm */ 46207753Smm 47207753Smm#include <sys/param.h> 48207753Smm#include <sys/systm.h> 49207753Smm#include <sys/kernel.h> 50207753Smm#include <sys/module.h> 51207753Smm#include <sys/errno.h> 52207753Smm#include <sys/lock.h> 53207753Smm#include <sys/mutex.h> 54207753Smm#include <sys/syslog.h> 55207753Smm#include <sys/bus.h> 56207753Smm 57207753Smm#include <machine/bus.h> 58207753Smm#include <sys/rman.h> 59207753Smm#include <machine/resource.h> 60207753Smm 61207753Smm#include <dev/pci/pcivar.h> 62207753Smm#include <dev/pci/pcireg.h> 63207753Smm 64207753Smm#include <dev/smbus/smbconf.h> 65207753Smm 66207753Smm#include <dev/ichsmb/ichsmb_var.h> 67207753Smm#include <dev/ichsmb/ichsmb_reg.h> 68207753Smm 69207753Smm/* PCI unique identifiers */ 70207753Smm#define PCI_VENDOR_INTEL 0x8086 71207753Smm#define ID_82801AA 0x2413 72207753Smm#define ID_82801AB 0x2423 73207753Smm#define ID_82801BA 0x2443 74207753Smm#define ID_82801CA 0x2483 75207753Smm#define ID_82801DC 0x24C3 76207753Smm#define ID_82801EB 0x24D3 77207753Smm#define ID_82801FB 0x266A 78207753Smm#define ID_82801GB 0x27da 79207753Smm#define ID_82801H 0x283e 80207753Smm#define ID_82801I 0x2930 81207753Smm#define ID_EP80579 0x5032 82207753Smm#define ID_82801JI 0x3a30 83207753Smm#define ID_82801JD 0x3a60 84207753Smm#define ID_PCH 0x3b30 85207753Smm#define ID_6300ESB 0x25a4 86207753Smm#define ID_631xESB 0x269b 87207753Smm#define ID_DH89XXCC 0x2330 88207753Smm#define ID_PATSBURG 0x1d22 89207753Smm#define ID_CPT 0x1c22 90207753Smm#define ID_PPT 0x1e22 91207753Smm#define ID_AVOTON 0x1f3c 92207753Smm#define ID_COLETOCRK 0x23B0 93207753Smm#define ID_LPT 0x8c22 94207753Smm#define ID_LPTLP 0x9c22 95207753Smm#define ID_WCPT 0x8ca2 96207753Smm#define ID_WCPTLP 0x9ca2 97207753Smm#define ID_BAYTRAIL 0x0f12 98207753Smm#define ID_BRASWELL 0x2292 99207753Smm#define ID_WELLSBURG 0x8d22 100207753Smm#define ID_SRPT 0xa123 101207753Smm#define ID_SRPTLP 0x9d23 102207753Smm#define ID_DENVERTON 0x19df 103207753Smm#define ID_BROXTON 0x5ad4 104207753Smm#define ID_LEWISBURG 0xa1a3 105207753Smm#define ID_LEWISBURG2 0xa223 106207753Smm#define ID_KABYLAKE 0xa2a3 107207753Smm#define ID_CANNONLAKE 0xa323 108207753Smm 109207753Smmstatic const struct ichsmb_device { 110207753Smm uint16_t id; 111207753Smm const char *name; 112207753Smm} ichsmb_devices[] = { 113207753Smm { ID_82801AA, "Intel 82801AA (ICH) SMBus controller" }, 114207753Smm { ID_82801AB, "Intel 82801AB (ICH0) SMBus controller" }, 115207753Smm { ID_82801BA, "Intel 82801BA (ICH2) SMBus controller" }, 116207753Smm { ID_82801CA, "Intel 82801CA (ICH3) SMBus controller" }, 117207753Smm { ID_82801DC, "Intel 82801DC (ICH4) SMBus controller" }, 118207753Smm { ID_82801EB, "Intel 82801EB (ICH5) SMBus controller" }, 119207753Smm { ID_82801FB, "Intel 82801FB (ICH6) SMBus controller" }, 120207753Smm { ID_82801GB, "Intel 82801GB (ICH7) SMBus controller" }, 121207753Smm { ID_82801H, "Intel 82801H (ICH8) SMBus controller" }, 122207753Smm { ID_82801I, "Intel 82801I (ICH9) SMBus controller" }, 123207753Smm { ID_82801GB, "Intel 82801GB (ICH7) SMBus controller" }, 124207753Smm { ID_82801H, "Intel 82801H (ICH8) SMBus controller" }, 125207753Smm { ID_82801I, "Intel 82801I (ICH9) SMBus controller" }, 126207753Smm { ID_EP80579, "Intel EP80579 SMBus controller" }, 127207753Smm { ID_82801JI, "Intel 82801JI (ICH10) SMBus controller" }, 128207753Smm { ID_82801JD, "Intel 82801JD (ICH10) SMBus controller" }, 129207753Smm { ID_PCH, "Intel PCH SMBus controller" }, 130207753Smm { ID_6300ESB, "Intel 6300ESB (ICH) SMBus controller" }, 131207753Smm { ID_631xESB, "Intel 631xESB/6321ESB (ESB2) SMBus controller" }, 132207753Smm { ID_DH89XXCC, "Intel DH89xxCC SMBus controller" }, 133207753Smm { ID_PATSBURG, "Intel Patsburg SMBus controller" }, 134207753Smm { ID_CPT, "Intel Cougar Point SMBus controller" }, 135207753Smm { ID_PPT, "Intel Panther Point SMBus controller" }, 136207753Smm { ID_AVOTON, "Intel Avoton SMBus controller" }, 137207753Smm { ID_LPT, "Intel Lynx Point SMBus controller" }, 138207753Smm { ID_LPTLP, "Intel Lynx Point-LP SMBus controller" }, 139215187Smm { ID_WCPT, "Intel Wildcat Point SMBus controller" }, 140215187Smm { ID_WCPTLP, "Intel Wildcat Point-LP SMBus controller" }, 141215187Smm { ID_BAYTRAIL, "Intel Baytrail SMBus controller" }, 142215187Smm { ID_BRASWELL, "Intel Braswell SMBus controller" }, 143215187Smm { ID_COLETOCRK, "Intel Coleto Creek SMBus controller" }, 144215187Smm { ID_WELLSBURG, "Intel Wellsburg SMBus controller" }, 145215187Smm { ID_SRPT, "Intel Sunrise Point-H SMBus controller" }, 146207753Smm { ID_SRPTLP, "Intel Sunrise Point-LP SMBus controller" }, 147207753Smm { ID_DENVERTON, "Intel Denverton SMBus controller" }, 148207753Smm { ID_BROXTON, "Intel Broxton SMBus controller" }, 149207753Smm { ID_LEWISBURG, "Intel Lewisburg SMBus controller" }, 150207753Smm { ID_LEWISBURG2,"Intel Lewisburg SMBus controller" }, 151207753Smm { ID_KABYLAKE, "Intel Kaby Lake SMBus controller" }, 152207753Smm { ID_CANNONLAKE,"Intel Cannon Lake SMBus controller" }, 153207753Smm { 0, NULL }, 154207753Smm}; 155207753Smm 156207753Smm/* Internal functions */ 157207753Smmstatic int ichsmb_pci_probe(device_t dev); 158207753Smmstatic int ichsmb_pci_attach(device_t dev); 159207753Smm/*Use generic one for now*/ 160207753Smm#if 0 161207753Smmstatic int ichsmb_pci_detach(device_t dev); 162207753Smm#endif 163207753Smm 164207753Smm/* Device methods */ 165207753Smmstatic device_method_t ichsmb_pci_methods[] = { 166207753Smm /* Device interface */ 167207753Smm DEVMETHOD(device_probe, ichsmb_pci_probe), 168207753Smm DEVMETHOD(device_attach, ichsmb_pci_attach), 169207753Smm DEVMETHOD(device_detach, ichsmb_detach), 170207753Smm 171207753Smm /* SMBus methods */ 172207753Smm DEVMETHOD(smbus_callback, ichsmb_callback), 173207753Smm DEVMETHOD(smbus_quick, ichsmb_quick), 174207753Smm DEVMETHOD(smbus_sendb, ichsmb_sendb), 175207753Smm DEVMETHOD(smbus_recvb, ichsmb_recvb), 176215187Smm DEVMETHOD(smbus_writeb, ichsmb_writeb), 177215187Smm DEVMETHOD(smbus_writew, ichsmb_writew), 178207753Smm DEVMETHOD(smbus_readb, ichsmb_readb), 179207753Smm DEVMETHOD(smbus_readw, ichsmb_readw), 180207753Smm DEVMETHOD(smbus_pcall, ichsmb_pcall), 181207753Smm DEVMETHOD(smbus_bwrite, ichsmb_bwrite), 182207753Smm DEVMETHOD(smbus_bread, ichsmb_bread), 183207753Smm 184207753Smm DEVMETHOD_END 185215187Smm}; 186215187Smm 187207753Smmstatic driver_t ichsmb_pci_driver = { 188207753Smm "ichsmb", 189207753Smm ichsmb_pci_methods, 190207753Smm sizeof(struct ichsmb_softc) 191207753Smm}; 192207753Smm 193207753Smmstatic devclass_t ichsmb_pci_devclass; 194207753Smm 195207753SmmDRIVER_MODULE(ichsmb, pci, ichsmb_pci_driver, ichsmb_pci_devclass, 0, 0); 196207753Smm 197207753Smmstatic int 198207753Smmichsmb_pci_probe(device_t dev) 199207753Smm{ 200207753Smm const struct ichsmb_device *device; 201207753Smm 202207753Smm if (pci_get_vendor(dev) != PCI_VENDOR_INTEL) 203207753Smm return (ENXIO); 204207753Smm 205207753Smm for (device = ichsmb_devices; device->name != NULL; device++) { 206207753Smm if (pci_get_device(dev) == device->id) { 207207753Smm device_set_desc(dev, device->name); 208207753Smm return (ichsmb_probe(dev)); 209207753Smm } 210207753Smm } 211207753Smm 212207753Smm return (ENXIO); 213207753Smm} 214207753Smm 215207753Smmstatic int 216207753Smmichsmb_pci_attach(device_t dev) 217207753Smm{ 218207753Smm const sc_p sc = device_get_softc(dev); 219207753Smm int error; 220207753Smm 221207753Smm /* Initialize private state */ 222207753Smm bzero(sc, sizeof(*sc)); 223207753Smm sc->ich_cmd = -1; 224207753Smm sc->dev = dev; 225207753Smm 226207753Smm /* Allocate an I/O range */ 227207753Smm sc->io_rid = ICH_SMB_BASE; 228207753Smm sc->io_res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, 229207753Smm &sc->io_rid, 16, RF_ACTIVE); 230207753Smm if (sc->io_res == NULL) 231207753Smm sc->io_res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, 232207753Smm &sc->io_rid, 32, RF_ACTIVE); 233207753Smm if (sc->io_res == NULL) { 234207753Smm device_printf(dev, "can't map I/O\n"); 235207753Smm error = ENXIO; 236207753Smm goto fail; 237207753Smm } 238207753Smm 239207753Smm /* Allocate interrupt */ 240207753Smm sc->irq_rid = 0; 241207753Smm sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 242207753Smm &sc->irq_rid, RF_ACTIVE | RF_SHAREABLE); 243207753Smm if (sc->irq_res == NULL) { 244207753Smm device_printf(dev, "can't get IRQ\n"); 245207753Smm error = ENXIO; 246207753Smm goto fail; 247207753Smm } 248207753Smm 249207753Smm /* Enable device */ 250207753Smm pci_write_config(dev, ICH_HOSTC, ICH_HOSTC_HST_EN, 1); 251207753Smm 252207753Smm /* Done */ 253207753Smm error = ichsmb_attach(dev); 254207753Smm if (error) 255207753Smm goto fail; 256207753Smm return (0); 257207753Smm 258207753Smmfail: 259207753Smm /* Attach failed, release resources */ 260207753Smm ichsmb_release_resources(sc); 261207753Smm return (error); 262207753Smm} 263207753Smm 264207753Smm 265207753SmmMODULE_DEPEND(ichsmb, pci, 1, 1, 1); 266207753SmmMODULE_DEPEND(ichsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); 267207753SmmMODULE_VERSION(ichsmb, 1); 268207753Smm