ichsmb_pci.c revision 119618
1126756Smlaier/*- 2244096Sdelphij * ichsmb_pci.c 3126756Smlaier * 4126756Smlaier * Author: Archie Cobbs <archie@freebsd.org> 5126756Smlaier * Copyright (c) 2000 Whistle Communications, Inc. 6126756Smlaier * All rights reserved. 7126756Smlaier * Author: Archie Cobbs <archie@freebsd.org> 8126756Smlaier * 9126756Smlaier * Subject to the following obligations and disclaimer of warranty, use and 10126756Smlaier * redistribution of this software, in source or object code forms, with or 11126756Smlaier * without modifications are expressly permitted by Whistle Communications; 12126756Smlaier * provided, however, that: 13126756Smlaier * 1. Any and all reproductions of the source or object code must include the 14126756Smlaier * copyright notice above and the following disclaimer of warranties; and 15126756Smlaier * 2. No rights are granted, in any manner or form, to use Whistle 16126756Smlaier * Communications, Inc. trademarks, including the mark "WHISTLE 17126756Smlaier * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 18126756Smlaier * such appears in the above copyright notice or in the software. 19126756Smlaier * 20126756Smlaier * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 21126756Smlaier * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 22126756Smlaier * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 23126756Smlaier * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 24126756Smlaier * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 25135183Smlaier * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 26135183Smlaier * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 27126756Smlaier * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 28126756Smlaier * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 29126756Smlaier * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 30126756Smlaier * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 31126756Smlaier * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 32126756Smlaier * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 33126756Smlaier * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34126756Smlaier * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35126756Smlaier * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 36126756Smlaier * OF SUCH DAMAGE. 37126756Smlaier */ 38126756Smlaier 39126756Smlaier#include <sys/cdefs.h> 40126756Smlaier__FBSDID("$FreeBSD: head/sys/dev/ichsmb/ichsmb_pci.c 119618 2003-08-31 19:23:00Z njl $"); 41126756Smlaier 42126756Smlaier/* 43126756Smlaier * Support for the SMBus controller logical device which is part of the 44126756Smlaier * Intel 81801AA/AB/BA/CA/DC/EB (ICH/ICH[02345]) I/O controller hub chips. 45126756Smlaier */ 46126756Smlaier 47126756Smlaier#include <sys/param.h> 48126756Smlaier#include <sys/systm.h> 49126756Smlaier#include <sys/kernel.h> 50126756Smlaier#include <sys/errno.h> 51126756Smlaier#include <sys/lock.h> 52126756Smlaier#include <sys/mutex.h> 53126756Smlaier#include <sys/syslog.h> 54126756Smlaier#include <sys/bus.h> 55126756Smlaier 56126756Smlaier#include <machine/bus.h> 57126756Smlaier#include <sys/rman.h> 58126756Smlaier#include <machine/resource.h> 59126756Smlaier 60126756Smlaier#include <dev/pci/pcivar.h> 61126756Smlaier#include <dev/pci/pcireg.h> 62126756Smlaier 63126756Smlaier#include <dev/smbus/smbconf.h> 64126756Smlaier 65126756Smlaier#include <dev/ichsmb/ichsmb_var.h> 66126756Smlaier#include <dev/ichsmb/ichsmb_reg.h> 67126756Smlaier 68126756Smlaier/* PCI unique identifiers */ 69126756Smlaier#define ID_82801AA 0x24138086 70126756Smlaier#define ID_82801AB 0x24238086 71126756Smlaier#define ID_82801BA 0x24438086 72126756Smlaier#define ID_82801CA 0x24838086 73126756Smlaier#define ID_82801DC 0x24C38086 74126756Smlaier#define ID_82801EB 0x24D38086 75126756Smlaier 76126756Smlaier#define PCIS_SERIALBUS_SMBUS_PROGIF 0x00 77126756Smlaier 78126756Smlaier/* Internal functions */ 79126756Smlaierstatic int ichsmb_pci_probe(device_t dev); 80126756Smlaierstatic int ichsmb_pci_attach(device_t dev); 81126756Smlaier 82126756Smlaier/* Device methods */ 83126756Smlaierstatic device_method_t ichsmb_pci_methods[] = { 84126756Smlaier /* Device interface */ 85126756Smlaier DEVMETHOD(device_probe, ichsmb_pci_probe), 86126756Smlaier DEVMETHOD(device_attach, ichsmb_pci_attach), 87126756Smlaier 88126756Smlaier /* Bus methods */ 89126756Smlaier DEVMETHOD(bus_print_child, bus_generic_print_child), 90126756Smlaier 91126756Smlaier /* SMBus methods */ 92126756Smlaier DEVMETHOD(smbus_callback, ichsmb_callback), 93126756Smlaier DEVMETHOD(smbus_quick, ichsmb_quick), 94126756Smlaier DEVMETHOD(smbus_sendb, ichsmb_sendb), 95126756Smlaier DEVMETHOD(smbus_recvb, ichsmb_recvb), 96126756Smlaier DEVMETHOD(smbus_writeb, ichsmb_writeb), 97126756Smlaier DEVMETHOD(smbus_writew, ichsmb_writew), 98126756Smlaier DEVMETHOD(smbus_readb, ichsmb_readb), 99126756Smlaier DEVMETHOD(smbus_readw, ichsmb_readw), 100126756Smlaier DEVMETHOD(smbus_pcall, ichsmb_pcall), 101126756Smlaier DEVMETHOD(smbus_bwrite, ichsmb_bwrite), 102126756Smlaier DEVMETHOD(smbus_bread, ichsmb_bread), 103126756Smlaier { 0, 0 } 104126756Smlaier}; 105126756Smlaier 106126756Smlaierstatic driver_t ichsmb_pci_driver = { 107126756Smlaier "ichsmb", 108126756Smlaier ichsmb_pci_methods, 109126756Smlaier sizeof(struct ichsmb_softc) 110126756Smlaier}; 111126756Smlaier 112126756Smlaierstatic devclass_t ichsmb_pci_devclass; 113126756Smlaier 114126756SmlaierDRIVER_MODULE(ichsmb, pci, ichsmb_pci_driver, ichsmb_pci_devclass, 0, 0); 115126756Smlaier 116126756Smlaierstatic int 117126756Smlaierichsmb_pci_probe(device_t dev) 118126756Smlaier{ 119126756Smlaier /* Check PCI identifier */ 120126756Smlaier switch (pci_get_devid(dev)) { 121126756Smlaier case ID_82801AA: 122126756Smlaier device_set_desc(dev, "Intel 82801AA (ICH) SMBus controller"); 123126756Smlaier break; 124126756Smlaier case ID_82801AB: 125126756Smlaier device_set_desc(dev, "Intel 82801AB (ICH0) SMBus controller"); 126126756Smlaier break; 127126756Smlaier case ID_82801BA: 128126756Smlaier device_set_desc(dev, "Intel 82801BA (ICH2) SMBus controller"); 129126756Smlaier break; 130126756Smlaier case ID_82801CA: 131126756Smlaier device_set_desc(dev, "Intel 82801CA (ICH3) SMBus controller"); 132126756Smlaier break; 133126756Smlaier case ID_82801DC: 134126756Smlaier device_set_desc(dev, "Intel 82801DC (ICH4) SMBus controller"); 135126756Smlaier break; 136126756Smlaier case ID_82801EB: 137126756Smlaier device_set_desc(dev, "Intel 82801EB (ICH5) SMBus controller"); 138126756Smlaier break; 139126756Smlaier default: 140126756Smlaier if (pci_get_class(dev) == PCIC_SERIALBUS 141126756Smlaier && pci_get_subclass(dev) == PCIS_SERIALBUS_SMBUS 142126756Smlaier && pci_get_progif(dev) == PCIS_SERIALBUS_SMBUS_PROGIF) { 143126756Smlaier device_set_desc(dev, "SMBus controller"); 144126756Smlaier return (-2); /* XXX */ 145135183Smlaier } 146135183Smlaier return (ENXIO); 147126756Smlaier } 148126756Smlaier 149126756Smlaier /* Done */ 150126756Smlaier return (ichsmb_probe(dev)); 151126756Smlaier} 152126756Smlaier 153126756Smlaierstatic int 154126756Smlaierichsmb_pci_attach(device_t dev) 155135183Smlaier{ 156135183Smlaier const sc_p sc = device_get_softc(dev); 157135183Smlaier u_int32_t cmd; 158135183Smlaier int error; 159126756Smlaier 160126756Smlaier /* Initialize private state */ 161126756Smlaier bzero(sc, sizeof(*sc)); 162126756Smlaier sc->ich_cmd = -1; 163126756Smlaier sc->dev = dev; 164126756Smlaier 165126756Smlaier /* Allocate an I/O range */ 166126756Smlaier sc->io_rid = ICH_SMB_BASE; 167126756Smlaier sc->io_res = bus_alloc_resource(dev, SYS_RES_IOPORT, 168126756Smlaier &sc->io_rid, 0, ~0, 16, RF_ACTIVE); 169126756Smlaier if (sc->io_res == NULL) { 170126756Smlaier log(LOG_ERR, "%s: can't map I/O\n", device_get_nameunit(dev)); 171126756Smlaier error = ENXIO; 172126756Smlaier goto fail; 173126756Smlaier } 174126756Smlaier sc->io_bst = rman_get_bustag(sc->io_res); 175126756Smlaier sc->io_bsh = rman_get_bushandle(sc->io_res); 176126756Smlaier 177126756Smlaier /* Allocate interrupt */ 178126756Smlaier sc->irq_rid = 0; 179126756Smlaier sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, 180126756Smlaier &sc->irq_rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 181126756Smlaier if (sc->irq_res == NULL) { 182126756Smlaier log(LOG_ERR, "%s: can't get IRQ\n", device_get_nameunit(dev)); 183126756Smlaier error = ENXIO; 184126756Smlaier goto fail; 185126756Smlaier } 186126756Smlaier 187126756Smlaier /* Set up interrupt handler */ 188126756Smlaier error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC, 189126756Smlaier ichsmb_device_intr, sc, &sc->irq_handle); 190126756Smlaier if (error != 0) { 191126756Smlaier log(LOG_ERR, "%s: can't setup irq\n", device_get_nameunit(dev)); 192126756Smlaier goto fail; 193126756Smlaier } 194126756Smlaier 195126756Smlaier /* Enable I/O mapping */ 196126756Smlaier cmd = pci_read_config(dev, PCIR_COMMAND, 4); 197126756Smlaier cmd |= PCIM_CMD_PORTEN; 198126756Smlaier pci_write_config(dev, PCIR_COMMAND, cmd, 4); 199126756Smlaier cmd = pci_read_config(dev, PCIR_COMMAND, 4); 200126756Smlaier if ((cmd & PCIM_CMD_PORTEN) == 0) { 201135183Smlaier log(LOG_ERR, "%s: can't enable memory map\n", 202126756Smlaier device_get_nameunit(dev)); 203126756Smlaier error = ENXIO; 204126756Smlaier goto fail; 205126756Smlaier } 206126756Smlaier 207126756Smlaier /* Enable device */ 208126756Smlaier pci_write_config(dev, ICH_HOSTC, ICH_HOSTC_HST_EN, 1); 209126756Smlaier 210126756Smlaier /* Done */ 211126756Smlaier return (ichsmb_attach(dev)); 212126756Smlaier 213126756Smlaierfail: 214135183Smlaier /* Attach failed, release resources */ 215126756Smlaier ichsmb_release_resources(sc); 216126756Smlaier return (error); 217126756Smlaier} 218126756Smlaier 219126756Smlaier