Lines Matching +full:slave +full:- +full:dev
1 /*-
36 #include <dev/smbus/smbconf.h>
40 #include <dev/pci/pcireg.h>
41 #include <dev/pci/pcivar.h>
42 #include <dev/intpm/intpmreg.h>
43 #include <dev/amdsbwd/amd_chipset.h>
48 device_t dev; member
62 #define INTSMB_LOCK(sc) mtx_lock(&(sc)->lock)
63 #define INTSMB_UNLOCK(sc) mtx_unlock(&(sc)->lock)
64 #define INTSMB_LOCK_ASSERT(sc) mtx_assert(&(sc)->lock, MA_OWNED)
72 static int intsmb_callback(device_t dev, int index, void *data);
73 static int intsmb_quick(device_t dev, u_char slave, int how);
74 static int intsmb_sendb(device_t dev, u_char slave, char byte);
75 static int intsmb_recvb(device_t dev, u_char slave, char *byte);
76 static int intsmb_writeb(device_t dev, u_char slave, char cmd, char byte);
77 static int intsmb_writew(device_t dev, u_char slave, char cmd, short word);
78 static int intsmb_readb(device_t dev, u_char slave, char cmd, char *byte);
79 static int intsmb_readw(device_t dev, u_char slave, char cmd, short *word);
80 static int intsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata);
81 static int intsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf);
82 static int intsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf);
107 intsmb_probe(device_t dev) in intsmb_probe() argument
113 devid = pci_get_devid(dev); in intsmb_probe()
116 if (isd->devid == devid) { in intsmb_probe()
117 device_set_desc(dev, isd->description); in intsmb_probe()
132 sb8xx_attach(device_t dev) in sb8xx_attach() argument
144 sc = device_get_softc(dev); in sb8xx_attach()
145 devid = pci_get_devid(dev); in sb8xx_attach()
146 revid = pci_get_revid(dev); in sb8xx_attach()
149 * Comment from Linux i2c-piix4.c: in sb8xx_attach()
156 sc->type = SYS_RES_MEMORY; in sb8xx_attach()
159 sc->type = SYS_RES_IOPORT; in sb8xx_attach()
164 rc = bus_set_resource(dev, sc->type, rid, addr, in sb8xx_attach()
167 device_printf(dev, "bus_set_resource for PM IO failed\n"); in sb8xx_attach()
170 res = bus_alloc_resource_any(dev, sc->type, &rid, in sb8xx_attach()
173 device_printf(dev, "bus_alloc_resource for PM IO failed\n"); in sb8xx_attach()
196 bus_release_resource(dev, sc->type, rid, res); in sb8xx_attach()
197 bus_delete_resource(dev, sc->type, rid); in sb8xx_attach()
200 device_printf(dev, "SB8xx/SB9xx/FCH SMBus not enabled\n"); in sb8xx_attach()
204 sc->io_rid = 0; in sb8xx_attach()
205 rc = bus_set_resource(dev, sc->type, sc->io_rid, addr, in sb8xx_attach()
208 device_printf(dev, "bus_set_resource for SMBus IO failed\n"); in sb8xx_attach()
211 sc->io_res = bus_alloc_resource_any(dev, sc->type, &sc->io_rid, in sb8xx_attach()
213 if (sc->io_res == NULL) { in sb8xx_attach()
214 device_printf(dev, "Could not allocate I/O space\n"); in sb8xx_attach()
217 sc->poll = 1; in sb8xx_attach()
222 intsmb_release_resources(device_t dev) in intsmb_release_resources() argument
224 struct intsmb_softc *sc = device_get_softc(dev); in intsmb_release_resources()
226 device_delete_children(dev); in intsmb_release_resources()
227 if (sc->irq_hand) in intsmb_release_resources()
228 bus_teardown_intr(dev, sc->irq_res, sc->irq_hand); in intsmb_release_resources()
229 if (sc->irq_res) in intsmb_release_resources()
230 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); in intsmb_release_resources()
231 if (sc->io_res) in intsmb_release_resources()
232 bus_release_resource(dev, sc->type, sc->io_rid, in intsmb_release_resources()
233 sc->io_res); in intsmb_release_resources()
234 mtx_destroy(&sc->lock); in intsmb_release_resources()
238 intsmb_attach(device_t dev) in intsmb_attach() argument
240 struct intsmb_softc *sc = device_get_softc(dev); in intsmb_attach()
245 sc->dev = dev; in intsmb_attach()
247 mtx_init(&sc->lock, device_get_nameunit(dev), "intsmb", MTX_DEF); in intsmb_attach()
249 sc->cfg_irq9 = 0; in intsmb_attach()
250 sc->type = SYS_RES_IOPORT; in intsmb_attach()
251 switch (pci_get_devid(dev)) { in intsmb_attach()
256 sc->cfg_irq9 = 1; in intsmb_attach()
260 if (pci_get_revid(dev) >= AMDSB8_SMBUS_REVID) in intsmb_attach()
261 sc->sb8xx = 1; in intsmb_attach()
266 sc->sb8xx = 1; in intsmb_attach()
270 if (sc->sb8xx) { in intsmb_attach()
271 error = sb8xx_attach(dev); in intsmb_attach()
278 sc->io_rid = PCI_BASE_ADDR_SMB; in intsmb_attach()
279 sc->io_res = bus_alloc_resource_any(dev, sc->type, &sc->io_rid, in intsmb_attach()
281 if (sc->io_res == NULL) { in intsmb_attach()
282 device_printf(dev, "Could not allocate I/O space\n"); in intsmb_attach()
287 if (sc->cfg_irq9) { in intsmb_attach()
288 pci_write_config(dev, PCIR_INTLINE, 0x9, 1); in intsmb_attach()
289 pci_write_config(dev, PCI_HST_CFG_SMB, in intsmb_attach()
292 value = pci_read_config(dev, PCI_HST_CFG_SMB, 1); in intsmb_attach()
293 sc->poll = (value & PCI_INTR_SMB_ENABLE) == 0; in intsmb_attach()
309 device_printf(dev, "intr %s %s ", str, in intsmb_attach()
310 sc->poll == 0 ? "enabled" : "disabled"); in intsmb_attach()
311 printf("revision %d\n", pci_read_config(dev, PCI_REVID_SMB, 1)); in intsmb_attach()
313 if (!sc->poll && intr == PCI_INTR_SMB_SMI) { in intsmb_attach()
314 device_printf(dev, in intsmb_attach()
316 sc->poll = 1; in intsmb_attach()
319 if (sc->poll) in intsmb_attach()
323 device_printf(dev, "Unsupported interrupt mode\n"); in intsmb_attach()
330 if (sc->cfg_irq9) in intsmb_attach()
331 bus_set_resource(dev, SYS_RES_IRQ, rid, 9, 1); in intsmb_attach()
333 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in intsmb_attach()
335 if (sc->irq_res == NULL) { in intsmb_attach()
336 device_printf(dev, "Could not allocate irq\n"); in intsmb_attach()
341 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, in intsmb_attach()
342 NULL, intsmb_rawintr, sc, &sc->irq_hand); in intsmb_attach()
344 device_printf(dev, "Failed to map intr\n"); in intsmb_attach()
349 sc->isbusy = 0; in intsmb_attach()
350 sc->smbus = device_add_child(dev, "smbus", DEVICE_UNIT_ANY); in intsmb_attach()
351 if (sc->smbus == NULL) { in intsmb_attach()
352 device_printf(dev, "failed to add smbus child\n"); in intsmb_attach()
356 error = device_probe_and_attach(sc->smbus); in intsmb_attach()
358 device_printf(dev, "failed to probe+attach smbus child\n"); in intsmb_attach()
364 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN); in intsmb_attach()
369 intsmb_release_resources(dev); in intsmb_attach()
374 intsmb_detach(device_t dev) in intsmb_detach() argument
378 error = bus_generic_detach(dev); in intsmb_detach()
380 device_printf(dev, "bus detach failed\n"); in intsmb_detach()
384 intsmb_release_resources(dev); in intsmb_detach()
400 intsmb_callback(device_t dev, int index, void *data) in intsmb_callback() argument
422 if ((bus_read_1(sc->io_res, PIIX4_SMBHSTSTS) & PIIX4_SMBHSTSTAT_BUSY) || in intsmb_free()
424 (bus_read_1(sc->io_res, PIIX4_SMBSLVSTS) & PIIX4_SMBSLVSTS_BUSY) || in intsmb_free()
426 sc->isbusy) in intsmb_free()
429 sc->isbusy = 1; in intsmb_free()
430 /* Disable Interrupt in slave part. */ in intsmb_free()
432 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 0); in intsmb_free()
435 bus_write_1(sc->io_res, PIIX4_SMBHSTSTS, in intsmb_free()
446 status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS); in intsmb_intr()
453 tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); in intsmb_intr()
454 bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, in intsmb_intr()
456 if (sc->isbusy) { in intsmb_intr()
457 sc->isbusy = 0; in intsmb_intr()
470 status = bus_read_1(sc->io_res, PIIX4_SMBSLVSTS); in intsmb_slvintr()
480 bus_write_1(sc->io_res, PIIX4_SMBSLVSTS, in intsmb_slvintr()
496 slvcnt = bus_read_1(sc->io_res, PIIX4_SMBSLVCNT); in intsmb_alrintr()
498 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, in intsmb_alrintr()
509 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, SMBALTRESP | LSB); in intsmb_alrintr()
513 device_printf(sc->dev, "ALART: ERROR\n"); in intsmb_alrintr()
515 addr = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); in intsmb_alrintr()
516 device_printf(sc->dev, "ALART_RESPONSE: 0x%x\n", addr); in intsmb_alrintr()
519 /* Re-enable INTR from ALART. */ in intsmb_alrintr()
520 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, in intsmb_alrintr()
532 tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); in intsmb_start()
538 if (!sc->poll && !cold && !nointr) in intsmb_start()
540 bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp); in intsmb_start()
544 intsmb_error(device_t dev, int status) in intsmb_error() argument
550 * - SMB_ENOACK ("Unclaimed cycle"), in intsmb_error()
551 * - SMB_ETIMEOUT ("Host device time-out"), in intsmb_error()
552 * - SMB_EINVAL ("Illegal command field"). in intsmb_error()
563 device_printf(dev, "error = %d, status = %#x\n", error, status); in intsmb_error()
585 if (bus_read_1(sc->io_res, PIIX4_SMBHSTSTS) & in intsmb_stop_poll()
591 status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS); in intsmb_stop_poll()
593 sc->isbusy = 0; in intsmb_stop_poll()
594 error = intsmb_error(sc->dev, status); in intsmb_stop_poll()
600 sc->isbusy = 0; in intsmb_stop_poll()
601 tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); in intsmb_stop_poll()
602 bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp & ~PIIX4_SMBHSTCNT_INTREN); in intsmb_stop_poll()
616 if (sc->poll || cold) in intsmb_stop()
620 error = msleep(sc, &sc->lock, PWAIT | PCATCH, "SMBWAI", hz / 8); in intsmb_stop()
622 status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS); in intsmb_stop()
624 error = intsmb_error(sc->dev, status); in intsmb_stop()
626 device_printf(sc->dev, "unknown cause why?\n"); in intsmb_stop()
628 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, in intsmb_stop()
636 sc->isbusy = 0; in intsmb_stop()
638 /* Re-enable suppressed interrupt from slave part. */ in intsmb_stop()
639 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN); in intsmb_stop()
647 intsmb_quick(device_t dev, u_char slave, int how) in intsmb_quick() argument
649 struct intsmb_softc *sc = device_get_softc(dev); in intsmb_quick()
653 data = slave; in intsmb_quick()
673 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, data); in intsmb_quick()
681 intsmb_sendb(device_t dev, u_char slave, char byte) in intsmb_sendb() argument
683 struct intsmb_softc *sc = device_get_softc(dev); in intsmb_sendb()
692 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); in intsmb_sendb()
693 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, byte); in intsmb_sendb()
701 intsmb_recvb(device_t dev, u_char slave, char *byte) in intsmb_recvb() argument
703 struct intsmb_softc *sc = device_get_softc(dev); in intsmb_recvb()
712 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); in intsmb_recvb()
721 *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTCMD); in intsmb_recvb()
723 *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); in intsmb_recvb()
731 intsmb_writeb(device_t dev, u_char slave, char cmd, char byte) in intsmb_writeb() argument
733 struct intsmb_softc *sc = device_get_softc(dev); in intsmb_writeb()
742 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); in intsmb_writeb()
743 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); in intsmb_writeb()
744 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, byte); in intsmb_writeb()
752 intsmb_writew(device_t dev, u_char slave, char cmd, short word) in intsmb_writew() argument
754 struct intsmb_softc *sc = device_get_softc(dev); in intsmb_writew()
763 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); in intsmb_writew()
764 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); in intsmb_writew()
765 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, word & 0xff); in intsmb_writew()
766 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT1, (word >> 8) & 0xff); in intsmb_writew()
774 intsmb_readb(device_t dev, u_char slave, char cmd, char *byte) in intsmb_readb() argument
776 struct intsmb_softc *sc = device_get_softc(dev); in intsmb_readb()
785 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); in intsmb_readb()
786 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); in intsmb_readb()
790 *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); in intsmb_readb()
796 intsmb_readw(device_t dev, u_char slave, char cmd, short *word) in intsmb_readw() argument
798 struct intsmb_softc *sc = device_get_softc(dev); in intsmb_readw()
807 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); in intsmb_readw()
808 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); in intsmb_readw()
812 *word = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); in intsmb_readw()
813 *word |= bus_read_1(sc->io_res, PIIX4_SMBHSTDAT1) << 8; in intsmb_readw()
820 intsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata) in intsmb_pcall() argument
827 intsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) in intsmb_bwrite() argument
829 struct intsmb_softc *sc = device_get_softc(dev); in intsmb_bwrite()
843 bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); in intsmb_bwrite()
845 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); in intsmb_bwrite()
846 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); in intsmb_bwrite()
848 bus_write_1(sc->io_res, PIIX4_SMBBLKDAT, buf[i]); in intsmb_bwrite()
849 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, count); in intsmb_bwrite()
857 intsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) in intsmb_bread() argument
859 struct intsmb_softc *sc = device_get_softc(dev); in intsmb_bread()
871 bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); in intsmb_bread()
873 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); in intsmb_bread()
874 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); in intsmb_bread()
878 nread = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); in intsmb_bread()
882 bus_read_1(sc->io_res, PIIX4_SMBBLKDAT); in intsmb_bread()