Lines Matching +full:slave +full:- +full:dev

1 /*-
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
61 #include <dev/smbus/smbconf.h>
63 #include <dev/ichsmb/ichsmb_var.h>
64 #include <dev/ichsmb/ichsmb_reg.h>
67 * Enable debugging by defining ICHSMB_DEBUG to a non-zero value.
88 BUS-INDEPENDENT BUS METHODS
92 * Handle probe-time duties that are independent of the bus
96 ichsmb_probe(device_t dev) in ichsmb_probe() argument
102 * Handle attach-time duties that are independent of the bus
106 ichsmb_attach(device_t dev) in ichsmb_attach() argument
108 const sc_p sc = device_get_softc(dev); in ichsmb_attach()
112 mtx_init(&sc->mutex, device_get_nameunit(dev), "ichsmb", MTX_DEF); in ichsmb_attach()
115 if ((sc->smb = device_add_child(dev, DRIVER_SMBUS, -1)) == NULL) { in ichsmb_attach()
116 device_printf(dev, "no \"%s\" child found\n", DRIVER_SMBUS); in ichsmb_attach()
122 bus_write_1(sc->io_res, ICH_HST_STA, 0xff); in ichsmb_attach()
125 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, in ichsmb_attach()
126 NULL, ichsmb_device_intr, sc, &sc->irq_handle); in ichsmb_attach()
128 device_printf(dev, "can't setup irq\n"); in ichsmb_attach()
133 return (bus_delayed_attach_children(dev)); in ichsmb_attach()
135 mtx_destroy(&sc->mutex); in ichsmb_attach()
144 ichsmb_callback(device_t dev, int index, void *data) in ichsmb_callback() argument
148 DBG("index=%d how=%d\n", index, data ? *(int *)data : -1); in ichsmb_callback()
163 ichsmb_quick(device_t dev, u_char slave, int how) in ichsmb_quick() argument
165 const sc_p sc = device_get_softc(dev); in ichsmb_quick()
168 DBG("slave=0x%02x how=%d\n", slave, how); in ichsmb_quick()
169 KASSERT(sc->ich_cmd == -1, in ichsmb_quick()
170 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_quick()
174 mtx_lock(&sc->mutex); in ichsmb_quick()
175 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_QUICK; in ichsmb_quick()
176 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_quick()
177 slave | (how == SMB_QREAD ? in ichsmb_quick()
179 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_quick()
180 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_quick()
182 mtx_unlock(&sc->mutex); in ichsmb_quick()
192 ichsmb_sendb(device_t dev, u_char slave, char byte) in ichsmb_sendb() argument
194 const sc_p sc = device_get_softc(dev); in ichsmb_sendb()
197 DBG("slave=0x%02x byte=0x%02x\n", slave, (u_char)byte); in ichsmb_sendb()
198 KASSERT(sc->ich_cmd == -1, in ichsmb_sendb()
199 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_sendb()
200 mtx_lock(&sc->mutex); in ichsmb_sendb()
201 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE; in ichsmb_sendb()
202 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_sendb()
203 slave | ICH_XMIT_SLVA_WRITE); in ichsmb_sendb()
204 bus_write_1(sc->io_res, ICH_HST_CMD, byte); in ichsmb_sendb()
205 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_sendb()
206 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_sendb()
208 mtx_unlock(&sc->mutex); in ichsmb_sendb()
214 ichsmb_recvb(device_t dev, u_char slave, char *byte) in ichsmb_recvb() argument
216 const sc_p sc = device_get_softc(dev); in ichsmb_recvb()
219 DBG("slave=0x%02x\n", slave); in ichsmb_recvb()
220 KASSERT(sc->ich_cmd == -1, in ichsmb_recvb()
221 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_recvb()
222 mtx_lock(&sc->mutex); in ichsmb_recvb()
223 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE; in ichsmb_recvb()
224 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_recvb()
225 slave | ICH_XMIT_SLVA_READ); in ichsmb_recvb()
226 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_recvb()
227 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_recvb()
229 *byte = bus_read_1(sc->io_res, ICH_D0); in ichsmb_recvb()
230 mtx_unlock(&sc->mutex); in ichsmb_recvb()
236 ichsmb_writeb(device_t dev, u_char slave, char cmd, char byte) in ichsmb_writeb() argument
238 const sc_p sc = device_get_softc(dev); in ichsmb_writeb()
241 DBG("slave=0x%02x cmd=0x%02x byte=0x%02x\n", in ichsmb_writeb()
242 slave, (u_char)cmd, (u_char)byte); in ichsmb_writeb()
243 KASSERT(sc->ich_cmd == -1, in ichsmb_writeb()
244 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_writeb()
245 mtx_lock(&sc->mutex); in ichsmb_writeb()
246 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE_DATA; in ichsmb_writeb()
247 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_writeb()
248 slave | ICH_XMIT_SLVA_WRITE); in ichsmb_writeb()
249 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_writeb()
250 bus_write_1(sc->io_res, ICH_D0, byte); in ichsmb_writeb()
251 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_writeb()
252 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_writeb()
254 mtx_unlock(&sc->mutex); in ichsmb_writeb()
260 ichsmb_writew(device_t dev, u_char slave, char cmd, short word) in ichsmb_writew() argument
262 const sc_p sc = device_get_softc(dev); in ichsmb_writew()
265 DBG("slave=0x%02x cmd=0x%02x word=0x%04x\n", in ichsmb_writew()
266 slave, (u_char)cmd, (u_int16_t)word); in ichsmb_writew()
267 KASSERT(sc->ich_cmd == -1, in ichsmb_writew()
268 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_writew()
269 mtx_lock(&sc->mutex); in ichsmb_writew()
270 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_WORD_DATA; in ichsmb_writew()
271 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_writew()
272 slave | ICH_XMIT_SLVA_WRITE); in ichsmb_writew()
273 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_writew()
274 bus_write_1(sc->io_res, ICH_D0, word & 0xff); in ichsmb_writew()
275 bus_write_1(sc->io_res, ICH_D1, word >> 8); in ichsmb_writew()
276 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_writew()
277 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_writew()
279 mtx_unlock(&sc->mutex); in ichsmb_writew()
285 ichsmb_readb(device_t dev, u_char slave, char cmd, char *byte) in ichsmb_readb() argument
287 const sc_p sc = device_get_softc(dev); in ichsmb_readb()
290 DBG("slave=0x%02x cmd=0x%02x\n", slave, (u_char)cmd); in ichsmb_readb()
291 KASSERT(sc->ich_cmd == -1, in ichsmb_readb()
292 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_readb()
293 mtx_lock(&sc->mutex); in ichsmb_readb()
294 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE_DATA; in ichsmb_readb()
295 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_readb()
296 slave | ICH_XMIT_SLVA_READ); in ichsmb_readb()
297 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_readb()
298 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_readb()
299 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_readb()
301 *byte = bus_read_1(sc->io_res, ICH_D0); in ichsmb_readb()
302 mtx_unlock(&sc->mutex); in ichsmb_readb()
308 ichsmb_readw(device_t dev, u_char slave, char cmd, short *word) in ichsmb_readw() argument
310 const sc_p sc = device_get_softc(dev); in ichsmb_readw()
313 DBG("slave=0x%02x cmd=0x%02x\n", slave, (u_char)cmd); in ichsmb_readw()
314 KASSERT(sc->ich_cmd == -1, in ichsmb_readw()
315 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_readw()
316 mtx_lock(&sc->mutex); in ichsmb_readw()
317 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_WORD_DATA; in ichsmb_readw()
318 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_readw()
319 slave | ICH_XMIT_SLVA_READ); in ichsmb_readw()
320 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_readw()
321 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_readw()
322 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_readw()
324 *word = (bus_read_1(sc->io_res, in ichsmb_readw()
326 | (bus_read_1(sc->io_res, in ichsmb_readw()
329 mtx_unlock(&sc->mutex); in ichsmb_readw()
335 ichsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata) in ichsmb_pcall() argument
337 const sc_p sc = device_get_softc(dev); in ichsmb_pcall()
340 DBG("slave=0x%02x cmd=0x%02x sdata=0x%04x\n", in ichsmb_pcall()
341 slave, (u_char)cmd, (u_int16_t)sdata); in ichsmb_pcall()
342 KASSERT(sc->ich_cmd == -1, in ichsmb_pcall()
343 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_pcall()
344 mtx_lock(&sc->mutex); in ichsmb_pcall()
345 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_PROC_CALL; in ichsmb_pcall()
346 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_pcall()
347 slave | ICH_XMIT_SLVA_WRITE); in ichsmb_pcall()
348 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_pcall()
349 bus_write_1(sc->io_res, ICH_D0, sdata & 0xff); in ichsmb_pcall()
350 bus_write_1(sc->io_res, ICH_D1, sdata >> 8); in ichsmb_pcall()
351 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_pcall()
352 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_pcall()
354 *rdata = (bus_read_1(sc->io_res, in ichsmb_pcall()
356 | (bus_read_1(sc->io_res, in ichsmb_pcall()
359 mtx_unlock(&sc->mutex); in ichsmb_pcall()
365 ichsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) in ichsmb_bwrite() argument
367 const sc_p sc = device_get_softc(dev); in ichsmb_bwrite()
370 DBG("slave=0x%02x cmd=0x%02x count=%d\n", slave, (u_char)cmd, count); in ichsmb_bwrite()
376 for (p = (u_char *)buf; p - (u_char *)buf < 32; p += 8) { in ichsmb_bwrite()
378 " %c%c%c%c%c%c%c%c", (p - (u_char *)buf), in ichsmb_bwrite()
386 KASSERT(sc->ich_cmd == -1, in ichsmb_bwrite()
387 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_bwrite()
390 bcopy(buf, sc->block_data, count); in ichsmb_bwrite()
391 sc->block_count = count; in ichsmb_bwrite()
392 sc->block_index = 1; /* buf[0] is written here */ in ichsmb_bwrite()
393 sc->block_write = true; in ichsmb_bwrite()
395 mtx_lock(&sc->mutex); in ichsmb_bwrite()
396 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK; in ichsmb_bwrite()
397 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_bwrite()
398 slave | ICH_XMIT_SLVA_WRITE); in ichsmb_bwrite()
399 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_bwrite()
400 bus_write_1(sc->io_res, ICH_D0, count); in ichsmb_bwrite()
401 bus_write_1(sc->io_res, ICH_BLOCK_DB, buf[0]); in ichsmb_bwrite()
402 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_bwrite()
403 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_bwrite()
405 mtx_unlock(&sc->mutex); in ichsmb_bwrite()
411 ichsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) in ichsmb_bread() argument
413 const sc_p sc = device_get_softc(dev); in ichsmb_bread()
416 DBG("slave=0x%02x cmd=0x%02x\n", slave, (u_char)cmd); in ichsmb_bread()
417 KASSERT(sc->ich_cmd == -1, in ichsmb_bread()
418 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_bread()
419 bzero(sc->block_data, sizeof(sc->block_data)); in ichsmb_bread()
420 sc->block_count = 0; in ichsmb_bread()
421 sc->block_index = 0; in ichsmb_bread()
422 sc->block_write = false; in ichsmb_bread()
424 mtx_lock(&sc->mutex); in ichsmb_bread()
425 sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK; in ichsmb_bread()
426 bus_write_1(sc->io_res, ICH_XMIT_SLVA, in ichsmb_bread()
427 slave | ICH_XMIT_SLVA_READ); in ichsmb_bread()
428 bus_write_1(sc->io_res, ICH_HST_CMD, cmd); in ichsmb_bread()
429 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_bread()
430 ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd); in ichsmb_bread()
432 bcopy(sc->block_data, buf, sc->block_count); in ichsmb_bread()
433 *count = sc->block_count; in ichsmb_bread()
435 mtx_unlock(&sc->mutex); in ichsmb_bread()
442 for (p = (u_char *)buf; p - (u_char *)buf < 32; p += 8) { in ichsmb_bread()
444 " %c%c%c%c%c%c%c%c", (p - (u_char *)buf), in ichsmb_bread()
483 * Interrupt handler. This handler is bus-independent. Note that our
490 const device_t dev = sc->dev; in ichsmb_device_intr() local
497 mtx_lock(&sc->mutex); in ichsmb_device_intr()
501 status = bus_read_1(sc->io_res, ICH_HST_STA); in ichsmb_device_intr()
516 if (sc->killed) { in ichsmb_device_intr()
517 sc->killed = 0; in ichsmb_device_intr()
519 bus_write_1(sc->io_res, ICH_HST_CNT, in ichsmb_device_intr()
523 if (sc->ich_cmd != -1) { in ichsmb_device_intr()
524 cmd_index = sc->ich_cmd >> 2; in ichsmb_device_intr()
526 ("%s: ich_cmd=%d", device_get_nameunit(dev), in ichsmb_device_intr()
527 sc->ich_cmd)); in ichsmb_device_intr()
531 device_printf(dev, "irq 0x%02x during 0x%02x\n", status, in ichsmb_device_intr()
532 sc->ich_cmd); in ichsmb_device_intr()
533 bus_write_1(sc->io_res, in ichsmb_device_intr()
540 sc->smb_error = SMB_EABORT; in ichsmb_device_intr()
546 sc->smb_error = SMB_ECOLLI; /* XXX SMB_EBUSERR? */ in ichsmb_device_intr()
552 sc->smb_error = SMB_ENOACK; /* or SMB_ETIMEOUT? */ in ichsmb_device_intr()
558 if (sc->block_write) { in ichsmb_device_intr()
559 if (sc->block_index < sc->block_count) { in ichsmb_device_intr()
562 bus_write_1(sc->io_res, in ichsmb_device_intr()
564 sc->block_data[sc->block_index++]); in ichsmb_device_intr()
569 if (sc->block_index == 0) { in ichsmb_device_intr()
570 sc->block_count = bus_read_1( in ichsmb_device_intr()
571 sc->io_res, ICH_D0); in ichsmb_device_intr()
572 if (sc->block_count < 1 || in ichsmb_device_intr()
573 sc->block_count > 32) { in ichsmb_device_intr()
574 device_printf(dev, "block read " in ichsmb_device_intr()
576 sc->block_count); in ichsmb_device_intr()
577 bus_write_1(sc->io_res, in ichsmb_device_intr()
581 sc->block_count = 0; in ichsmb_device_intr()
582 sc->killed = true; in ichsmb_device_intr()
587 if (sc->block_index < sc->block_count) { in ichsmb_device_intr()
590 sc->block_data[sc->block_index++] = in ichsmb_device_intr()
591 bus_read_1(sc->io_res, in ichsmb_device_intr()
598 if (sc->block_index == in ichsmb_device_intr()
599 sc->block_count - 1) { in ichsmb_device_intr()
600 bus_write_1(sc->io_res, in ichsmb_device_intr()
604 sc->ich_cmd); in ichsmb_device_intr()
612 sc->smb_error = SMB_ENOERR; in ichsmb_device_intr()
614 sc->ich_cmd = -1; in ichsmb_device_intr()
615 bus_write_1(sc->io_res, in ichsmb_device_intr()
622 bus_write_1(sc->io_res, ICH_HST_STA, status); in ichsmb_device_intr()
624 mtx_unlock(&sc->mutex); in ichsmb_device_intr()
628 device_printf(dev, "interrupt loop, status=0x%02x\n", in ichsmb_device_intr()
629 bus_read_1(sc->io_res, ICH_HST_STA)); in ichsmb_device_intr()
640 const device_t dev = sc->dev; in ichsmb_wait() local
643 KASSERT(sc->ich_cmd != -1, in ichsmb_wait()
644 ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd)); in ichsmb_wait()
645 mtx_assert(&sc->mutex, MA_OWNED); in ichsmb_wait()
646 error = msleep(sc, &sc->mutex, PZERO, "ichsmb", hz / 4); in ichsmb_wait()
647 DBG("msleep -> %d\n", error); in ichsmb_wait()
650 smb_error = sc->smb_error; in ichsmb_wait()
653 device_printf(dev, "device timeout, status=0x%02x\n", in ichsmb_wait()
654 bus_read_1(sc->io_res, ICH_HST_STA)); in ichsmb_wait()
655 sc->ich_cmd = -1; in ichsmb_wait()
671 const device_t dev = sc->dev; in ichsmb_release_resources() local
673 if (sc->irq_handle != NULL) { in ichsmb_release_resources()
674 bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); in ichsmb_release_resources()
675 sc->irq_handle = NULL; in ichsmb_release_resources()
677 if (sc->irq_res != NULL) { in ichsmb_release_resources()
678 bus_release_resource(dev, in ichsmb_release_resources()
679 SYS_RES_IRQ, sc->irq_rid, sc->irq_res); in ichsmb_release_resources()
680 sc->irq_res = NULL; in ichsmb_release_resources()
682 if (sc->io_res != NULL) { in ichsmb_release_resources()
683 bus_release_resource(dev, in ichsmb_release_resources()
684 SYS_RES_IOPORT, sc->io_rid, sc->io_res); in ichsmb_release_resources()
685 sc->io_res = NULL; in ichsmb_release_resources()
690 ichsmb_detach(device_t dev) in ichsmb_detach() argument
692 const sc_p sc = device_get_softc(dev); in ichsmb_detach()
695 error = bus_generic_detach(dev); in ichsmb_detach()
698 device_delete_child(dev, sc->smb); in ichsmb_detach()
700 mtx_destroy(&sc->mutex); in ichsmb_detach()