Lines Matching +full:smbus +full:- +full:timeout +full:- +full:disable
1 /*-
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
40 * Support for the SMBus controller logical device which is part of the
43 * This driver assumes that the generic SMBus code will ensure that
44 * at most one process at a time calls into the SMBus methods below.
61 #include <dev/smbus/smbconf.h>
67 * Enable debugging by defining ICHSMB_DEBUG to a non-zero value.
80 #define DRIVER_SMBUS "smbus"
88 BUS-INDEPENDENT BUS METHODS
92 * Handle probe-time duties that are independent of the bus
102 * Handle attach-time duties that are independent of the bus
112 mtx_init(&sc->mutex, device_get_nameunit(dev), "ichsmb", MTX_DEF); in ichsmb_attach()
114 /* Add child: an instance of the "smbus" device */ in ichsmb_attach()
115 if ((sc->smb = device_add_child(dev, DRIVER_SMBUS, in ichsmb_attach()
123 bus_write_1(sc->io_res, ICH_HST_STA, 0xff); in ichsmb_attach()
126 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, in ichsmb_attach()
127 NULL, ichsmb_device_intr, sc, &sc->irq_handle); in ichsmb_attach()
137 mtx_destroy(&sc->mutex); in ichsmb_attach()
142 SMBUS METHODS
150 DBG("index=%d how=%d\n", index, data ? *(int *)data : -1); in ichsmb_callback()
171 KASSERT(sc->ich_cmd == -1, in ichsmb_quick()
172 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_quick()
176 mtx_lock(&sc->mutex); in ichsmb_quick()
177 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_QUICK; in ichsmb_quick()
178 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_quick()
181 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_quick()
182 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_quick()
184 mtx_unlock(&sc->mutex); in ichsmb_quick()
200 KASSERT(sc->ich_cmd == -1, in ichsmb_sendb()
201 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_sendb()
202 mtx_lock(&sc->mutex); in ichsmb_sendb()
203 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE; in ichsmb_sendb()
204 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_sendb()
206 bus_write_1(sc->io_res, ICH_HST_CMD, byte); in ichsmb_sendb()
207 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_sendb()
208 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_sendb()
210 mtx_unlock(&sc->mutex); in ichsmb_sendb()
222 KASSERT(sc->ich_cmd == -1, in ichsmb_recvb()
223 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_recvb()
224 mtx_lock(&sc->mutex); in ichsmb_recvb()
225 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE; in ichsmb_recvb()
226 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_recvb()
228 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_recvb()
229 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_recvb()
231 *byte = bus_read_1(sc->io_res, ICH_D0); in ichsmb_recvb()
232 mtx_unlock(&sc->mutex); in ichsmb_recvb()
245 KASSERT(sc->ich_cmd == -1, in ichsmb_writeb()
246 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_writeb()
247 mtx_lock(&sc->mutex); in ichsmb_writeb()
248 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE_DATA; in ichsmb_writeb()
249 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_writeb()
251 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_writeb()
252 bus_write_1(sc->io_res, ICH_D0, byte); in ichsmb_writeb()
253 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_writeb()
254 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_writeb()
256 mtx_unlock(&sc->mutex); in ichsmb_writeb()
269 KASSERT(sc->ich_cmd == -1, in ichsmb_writew()
270 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_writew()
271 mtx_lock(&sc->mutex); in ichsmb_writew()
272 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_WORD_DATA; in ichsmb_writew()
273 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_writew()
275 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_writew()
276 bus_write_1(sc->io_res, ICH_D0, word & 0xff); in ichsmb_writew()
277 bus_write_1(sc->io_res, ICH_D1, word >> 8); in ichsmb_writew()
278 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_writew()
279 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_writew()
281 mtx_unlock(&sc->mutex); in ichsmb_writew()
293 KASSERT(sc->ich_cmd == -1, in ichsmb_readb()
294 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_readb()
295 mtx_lock(&sc->mutex); in ichsmb_readb()
296 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE_DATA; in ichsmb_readb()
297 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_readb()
299 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_readb()
300 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_readb()
301 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_readb()
303 *byte = bus_read_1(sc->io_res, ICH_D0); in ichsmb_readb()
304 mtx_unlock(&sc->mutex); in ichsmb_readb()
316 KASSERT(sc->ich_cmd == -1, in ichsmb_readw()
317 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_readw()
318 mtx_lock(&sc->mutex); in ichsmb_readw()
319 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_WORD_DATA; in ichsmb_readw()
320 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_readw()
322 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_readw()
323 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_readw()
324 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_readw()
326 *word = (bus_read_1(sc->io_res, in ichsmb_readw()
328 | (bus_read_1(sc->io_res, in ichsmb_readw()
331 mtx_unlock(&sc->mutex); in ichsmb_readw()
344 KASSERT(sc->ich_cmd == -1, in ichsmb_pcall()
345 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_pcall()
346 mtx_lock(&sc->mutex); in ichsmb_pcall()
347 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_PROC_CALL; in ichsmb_pcall()
348 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_pcall()
350 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_pcall()
351 bus_write_1(sc->io_res, ICH_D0, sdata & 0xff); in ichsmb_pcall()
352 bus_write_1(sc->io_res, ICH_D1, sdata >> 8); in ichsmb_pcall()
353 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_pcall()
354 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_pcall()
356 *rdata = (bus_read_1(sc->io_res, in ichsmb_pcall()
358 | (bus_read_1(sc->io_res, in ichsmb_pcall()
361 mtx_unlock(&sc->mutex); in ichsmb_pcall()
378 for (p = (u_char *)buf; p - (u_char *)buf < 32; p += 8) { in ichsmb_bwrite()
380 " %c%c%c%c%c%c%c%c", (p - (u_char *)buf), in ichsmb_bwrite()
388 KASSERT(sc->ich_cmd == -1, in ichsmb_bwrite()
389 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_bwrite()
392 bcopy(buf, sc->block_data, count); in ichsmb_bwrite()
393 sc->block_count = count; in ichsmb_bwrite()
394 sc->block_index = 1; /* buf[0] is written here */ in ichsmb_bwrite()
395 sc->block_write = true; in ichsmb_bwrite()
397 mtx_lock(&sc->mutex); in ichsmb_bwrite()
398 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK; in ichsmb_bwrite()
399 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_bwrite()
401 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_bwrite()
402 bus_write_1(sc->io_res, ICH_D0, count); in ichsmb_bwrite()
403 bus_write_1(sc->io_res, ICH_BLOCK_DB, buf[0]); in ichsmb_bwrite()
404 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_bwrite()
405 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_bwrite()
407 mtx_unlock(&sc->mutex); in ichsmb_bwrite()
419 KASSERT(sc->ich_cmd == -1, in ichsmb_bread()
420 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_bread()
421 bzero(sc->block_data, sizeof(sc->block_data)); in ichsmb_bread()
422 sc->block_count = 0; in ichsmb_bread()
423 sc->block_index = 0; in ichsmb_bread()
424 sc->block_write = false; in ichsmb_bread()
426 mtx_lock(&sc->mutex); in ichsmb_bread()
427 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK; in ichsmb_bread()
428 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_bread()
430 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_bread()
431 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_bread()
432 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_bread()
434 bcopy(sc->block_data, buf, sc->block_count); in ichsmb_bread()
435 *count = sc->block_count; in ichsmb_bread()
437 mtx_unlock(&sc->mutex); in ichsmb_bread()
444 for (p = (u_char *)buf; p - (u_char *)buf < 32; p += 8) { in ichsmb_bread()
446 " %c%c%c%c%c%c%c%c", (p - (u_char *)buf), in ichsmb_bread()
485 * Interrupt handler. This handler is bus-independent. Note that our
492 const device_t dev = sc->dev; in ichsmb_device_intr()
499 mtx_lock(&sc->mutex); in ichsmb_device_intr()
503 status = bus_read_1(sc->io_res, ICH_HST_STA); in ichsmb_device_intr()
518 if (sc->killed) { in ichsmb_device_intr()
519 sc->killed = 0; in ichsmb_device_intr()
521 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_device_intr()
525 if (sc->ich_cmd != -1) { in ichsmb_device_intr()
526 cmd_index = sc->ich_cmd >> 2; in ichsmb_device_intr()
529 sc->ich_cmd)); in ichsmb_device_intr()
534 sc->ich_cmd); in ichsmb_device_intr()
535 bus_write_1(sc->io_res, in ichsmb_device_intr()
542 sc->smb_error = SMB_EABORT; in ichsmb_device_intr()
548 sc->smb_error = SMB_ECOLLI; /* XXX SMB_EBUSERR? */ in ichsmb_device_intr()
554 sc->smb_error = SMB_ENOACK; /* or SMB_ETIMEOUT? */ in ichsmb_device_intr()
560 if (sc->block_write) { in ichsmb_device_intr()
561 if (sc->block_index < sc->block_count) { in ichsmb_device_intr()
564 bus_write_1(sc->io_res, in ichsmb_device_intr()
566 sc->block_data[sc->block_index++]); in ichsmb_device_intr()
571 if (sc->block_index == 0) { in ichsmb_device_intr()
572 sc->block_count = bus_read_1( in ichsmb_device_intr()
573 sc->io_res, ICH_D0); in ichsmb_device_intr()
574 if (sc->block_count < 1 || in ichsmb_device_intr()
575 sc->block_count > 32) { in ichsmb_device_intr()
578 sc->block_count); in ichsmb_device_intr()
579 bus_write_1(sc->io_res, in ichsmb_device_intr()
583 sc->block_count = 0; in ichsmb_device_intr()
584 sc->killed = true; in ichsmb_device_intr()
589 if (sc->block_index < sc->block_count) { in ichsmb_device_intr()
592 sc->block_data[sc->block_index++] = in ichsmb_device_intr()
593 bus_read_1(sc->io_res, in ichsmb_device_intr()
600 if (sc->block_index == in ichsmb_device_intr()
601 sc->block_count - 1) { in ichsmb_device_intr()
602 bus_write_1(sc->io_res, in ichsmb_device_intr()
606 sc->ich_cmd); in ichsmb_device_intr()
614 sc->smb_error = SMB_ENOERR; in ichsmb_device_intr()
616 sc->ich_cmd = -1; in ichsmb_device_intr()
617 bus_write_1(sc->io_res, in ichsmb_device_intr()
624 bus_write_1(sc->io_res, ICH_HST_STA, status); in ichsmb_device_intr()
626 mtx_unlock(&sc->mutex); in ichsmb_device_intr()
631 bus_read_1(sc->io_res, ICH_HST_STA)); in ichsmb_device_intr()
642 const device_t dev = sc->dev; in ichsmb_wait()
645 KASSERT(sc->ich_cmd != -1, in ichsmb_wait()
646 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_wait()
647 mtx_assert(&sc->mutex, MA_OWNED); in ichsmb_wait()
648 error = msleep(sc, &sc->mutex, PZERO, "ichsmb", hz / 4); in ichsmb_wait()
649 DBG("msleep -> %d\n", error); in ichsmb_wait()
652 smb_error = sc->smb_error; in ichsmb_wait()
655 device_printf(dev, "device timeout, status=0x%02x\n", in ichsmb_wait()
656 bus_read_1(sc->io_res, ICH_HST_STA)); in ichsmb_wait()
657 sc->ich_cmd = -1; in ichsmb_wait()
673 const device_t dev = sc->dev; in ichsmb_release_resources()
675 if (sc->irq_handle != NULL) { in ichsmb_release_resources()
676 bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); in ichsmb_release_resources()
677 sc->irq_handle = NULL; in ichsmb_release_resources()
679 if (sc->irq_res != NULL) { in ichsmb_release_resources()
681 SYS_RES_IRQ, sc->irq_rid, sc->irq_res); in ichsmb_release_resources()
682 sc->irq_res = NULL; in ichsmb_release_resources()
684 if (sc->io_res != NULL) { in ichsmb_release_resources()
686 SYS_RES_IOPORT, sc->io_rid, sc->io_res); in ichsmb_release_resources()
687 sc->io_res = NULL; in ichsmb_release_resources()
701 mtx_destroy(&sc->mutex); in ichsmb_detach()
711 /* Disable interrupts */ in ichsmb_shutdown()
712 bus_write_1(sc->io_res, ICH_HST_CNT, 0); in ichsmb_shutdown()
717 DRIVER_MODULE(smbus, ichsmb, smbus_driver, 0, 0);