Lines Matching +full:master +full:- +full:mode

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
36 * The driver is implemented as an interrupt-driven state machine,
37 * supporting both master and slave mode.
63 /* CS5536 PCI-ISA ID. */
146 struct iic_msg *msg; /* Current master mode message. */
148 uint8_t *data; /* Current master mode data byte. */
150 int error; /* Last master mode error. */
168 #define GLXIIC_LOCK(_sc) mtx_lock(&_sc->mtx)
169 #define GLXIIC_UNLOCK(_sc) mtx_unlock(&_sc->mtx)
171 mtx_init(&_sc->mtx, device_get_nameunit(_sc->dev), "glxiic", MTX_DEF)
173 mtx_sleep(_sc, &_sc->mtx, IICPRI, "glxiic", 0)
175 #define GLXIIC_LOCK_DESTROY(_sc) mtx_destroy(&_sc->mtx);
176 #define GLXIIC_ASSERT_LOCKED(_sc) mtx_assert(&_sc->mtx, MA_OWNED);
191 boolean_t master; member
198 .master = FALSE,
203 .master = FALSE,
208 .master = FALSE,
213 .master = TRUE,
218 .master = TRUE,
223 .master = TRUE,
228 .master = TRUE,
287 if (device_find_child(parent, driver->name, DEVICE_UNIT_ANY) != NULL) in glxiic_identify()
291 if (device_add_child(parent, driver->name, DEVICE_UNIT_ANY) == NULL) in glxiic_identify()
318 sc->dev = dev; in glxiic_attach()
319 sc->state = GLXIIC_STATE_IDLE; in glxiic_attach()
323 callout_init_mtx(&sc->callout, &sc->mtx, 0); in glxiic_attach()
325 sc->smb_rid = PCIR_BAR(0); in glxiic_attach()
326 sc->smb_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->smb_rid, in glxiic_attach()
328 if (sc->smb_res == NULL) { in glxiic_attach()
334 sc->gpio_rid = PCIR_BAR(1); in glxiic_attach()
335 sc->gpio_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, in glxiic_attach()
336 &sc->gpio_rid, RF_SHAREABLE | RF_ACTIVE); in glxiic_attach()
337 if (sc->gpio_res == NULL) { in glxiic_attach()
348 sc->old_irq = GLXIIC_MAP_TO_SMB_IRQ(irq_map); in glxiic_attach()
361 } else if (sc->old_irq != 0) { in glxiic_attach()
365 irq = sc->old_irq; in glxiic_attach()
376 sc->irq_rid = 0; in glxiic_attach()
377 sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, in glxiic_attach()
379 if (sc->irq_res == NULL) { in glxiic_attach()
385 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, in glxiic_attach()
386 NULL, glxiic_intr, sc, &(sc->irq_handler)); in glxiic_attach()
393 if ((sc->iicbus = device_add_child(dev, "iicbus", in glxiic_attach()
403 sc->timeout = GLXIIC_DEFAULT_TIMEOUT; in glxiic_attach()
405 "timeout", CTLFLAG_RWTUN, &sc->timeout, 0, in glxiic_attach()
416 callout_drain(&sc->callout); in glxiic_attach()
418 if (sc->iicbus != NULL) in glxiic_attach()
419 device_delete_child(dev, sc->iicbus); in glxiic_attach()
420 if (sc->smb_res != NULL) { in glxiic_attach()
422 bus_release_resource(dev, SYS_RES_IOPORT, sc->smb_rid, in glxiic_attach()
423 sc->smb_res); in glxiic_attach()
425 if (sc->gpio_res != NULL) { in glxiic_attach()
427 bus_release_resource(dev, SYS_RES_IOPORT, sc->gpio_rid, in glxiic_attach()
428 sc->gpio_res); in glxiic_attach()
430 if (sc->irq_handler != NULL) in glxiic_attach()
431 bus_teardown_intr(dev, sc->irq_res, sc->irq_handler); in glxiic_attach()
432 if (sc->irq_res != NULL) in glxiic_attach()
433 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, in glxiic_attach()
434 sc->irq_res); in glxiic_attach()
437 glxiic_smb_map_interrupt(sc->old_irq); in glxiic_attach()
457 callout_drain(&sc->callout); in glxiic_detach()
459 if (sc->smb_res != NULL) { in glxiic_detach()
461 bus_release_resource(dev, SYS_RES_IOPORT, sc->smb_rid, in glxiic_detach()
462 sc->smb_res); in glxiic_detach()
464 if (sc->gpio_res != NULL) { in glxiic_detach()
466 bus_release_resource(dev, SYS_RES_IOPORT, sc->gpio_rid, in glxiic_detach()
467 sc->gpio_res); in glxiic_detach()
469 if (sc->irq_handler != NULL) in glxiic_detach()
470 bus_teardown_intr(dev, sc->irq_res, sc->irq_handler); in glxiic_detach()
471 if (sc->irq_res != NULL) in glxiic_detach()
472 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, in glxiic_detach()
473 sc->irq_res); in glxiic_detach()
476 glxiic_smb_map_interrupt(sc->old_irq); in glxiic_detach()
490 status = bus_read_1(sc->smb_res, GLXIIC_SMB_STS); in glxiic_read_status_locked()
493 bus_write_1(sc->smb_res, GLXIIC_SMB_STS, (GLXIIC_SMB_STS_SLVSTP_BIT | in glxiic_read_status_locked()
509 ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1); in glxiic_stop_locked()
510 bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1, in glxiic_stop_locked()
514 * Perform a dummy read of SDA in master receive mode to clear in glxiic_stop_locked()
519 bus_read_1(sc->smb_res, GLXIIC_SMB_SDA); in glxiic_stop_locked()
523 bus_write_1(sc->smb_res, GLXIIC_SMB_STS, in glxiic_stop_locked()
536 GLXIIC_DEBUG_LOG("timeout in state %d", sc->state); in glxiic_timeout()
538 if (glxiic_state_table[sc->state].master) { in glxiic_timeout()
539 sc->error = IIC_ETIMEOUT; in glxiic_timeout()
543 iicbus_intr(sc->iicbus, INTR_ERROR, &error); in glxiic_timeout()
547 glxiic_smb_enable(sc, IIC_UNKNOWN, sc->addr); in glxiic_timeout()
557 callout_reset_sbt(&sc->callout, SBT_1MS * sc->timeout, 0, in glxiic_start_timeout_locked()
568 callout_stop(&sc->callout); in glxiic_set_state_locked()
569 else if (sc->timeout > 0) in glxiic_set_state_locked()
572 sc->state = state; in glxiic_set_state_locked()
582 ctrl_sts = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL_STS); in glxiic_handle_slave_match_locked()
586 addr = sc->addr | LSB; in glxiic_handle_slave_match_locked()
590 addr = sc->addr & ~LSB; in glxiic_handle_slave_match_locked()
594 iicbus_intr(sc->iicbus, INTR_START, &addr); in glxiic_handle_slave_match_locked()
598 iicbus_intr(sc->iicbus, INTR_GENERAL, &addr); in glxiic_handle_slave_match_locked()
638 iicbus_intr(sc->iicbus, INTR_STOP, NULL); in glxiic_state_slave_tx_callback()
644 iicbus_intr(sc->iicbus, INTR_NOACK, NULL); in glxiic_state_slave_tx_callback()
649 /* Handle repeated start in slave mode. */ in glxiic_state_slave_tx_callback()
658 iicbus_intr(sc->iicbus, INTR_TRANSMIT, &data); in glxiic_state_slave_tx_callback()
659 bus_write_1(sc->smb_res, GLXIIC_SMB_SDA, data); in glxiic_state_slave_tx_callback()
679 iicbus_intr(sc->iicbus, INTR_STOP, NULL); in glxiic_state_slave_rx_callback()
685 /* Handle repeated start in slave mode. */ in glxiic_state_slave_rx_callback()
694 data = bus_read_1(sc->smb_res, GLXIIC_SMB_SDA); in glxiic_state_slave_rx_callback()
695 iicbus_intr(sc->iicbus, INTR_RECEIVE, &data); in glxiic_state_slave_rx_callback()
711 GLXIIC_DEBUG_LOG("bus error after master start"); in glxiic_state_master_addr_callback()
716 GLXIIC_DEBUG_LOG("not bus master after master start"); in glxiic_state_master_addr_callback()
721 GLXIIC_DEBUG_LOG("not awaiting address in master addr"); in glxiic_state_master_addr_callback()
725 if ((sc->msg->flags & IIC_M_RD) != 0) { in glxiic_state_master_addr_callback()
726 slave = sc->msg->slave | LSB; in glxiic_state_master_addr_callback()
729 slave = sc->msg->slave & ~LSB; in glxiic_state_master_addr_callback()
733 sc->data = sc->msg->buf; in glxiic_state_master_addr_callback()
734 sc->ndata = sc->msg->len; in glxiic_state_master_addr_callback()
736 /* Handle address-only transfer. */ in glxiic_state_master_addr_callback()
737 if (sc->ndata == 0) in glxiic_state_master_addr_callback()
740 bus_write_1(sc->smb_res, GLXIIC_SMB_SDA, slave); in glxiic_state_master_addr_callback()
742 if ((sc->msg->flags & IIC_M_RD) != 0 && sc->ndata == 1) { in glxiic_state_master_addr_callback()
744 ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1); in glxiic_state_master_addr_callback()
745 bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1, in glxiic_state_master_addr_callback()
759 GLXIIC_DEBUG_LOG("bus error in master tx"); in glxiic_state_master_tx_callback()
764 GLXIIC_DEBUG_LOG("not bus master in master tx"); in glxiic_state_master_tx_callback()
769 GLXIIC_DEBUG_LOG("slave nack in master tx"); in glxiic_state_master_tx_callback()
774 bus_write_1(sc->smb_res, GLXIIC_SMB_STS, in glxiic_state_master_tx_callback()
779 GLXIIC_DEBUG_LOG("not awaiting data in master tx"); in glxiic_state_master_tx_callback()
783 bus_write_1(sc->smb_res, GLXIIC_SMB_SDA, *sc->data++); in glxiic_state_master_tx_callback()
784 if (--sc->ndata == 0) in glxiic_state_master_tx_callback()
800 GLXIIC_DEBUG_LOG("bus error in master rx"); in glxiic_state_master_rx_callback()
805 GLXIIC_DEBUG_LOG("not bus master in master rx"); in glxiic_state_master_rx_callback()
816 bus_write_1(sc->smb_res, GLXIIC_SMB_STS, in glxiic_state_master_rx_callback()
822 GLXIIC_DEBUG_LOG("no pending data in master rx"); in glxiic_state_master_rx_callback()
826 *sc->data++ = bus_read_1(sc->smb_res, GLXIIC_SMB_SDA); in glxiic_state_master_rx_callback()
827 if (--sc->ndata == 0) { in glxiic_state_master_rx_callback()
830 return (glxiic_state_table[sc->state].callback(sc, status)); in glxiic_state_master_rx_callback()
833 if (sc->ndata == 1) { in glxiic_state_master_rx_callback()
835 ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1); in glxiic_state_master_rx_callback()
836 bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1, in glxiic_state_master_rx_callback()
853 GLXIIC_DEBUG_LOG("bus error in master stop"); in glxiic_state_master_stop_callback()
858 GLXIIC_DEBUG_LOG("not bus master in master stop"); in glxiic_state_master_stop_callback()
863 GLXIIC_DEBUG_LOG("slave nack in master stop"); in glxiic_state_master_stop_callback()
867 if (--sc->nmsgs > 0) { in glxiic_state_master_stop_callback()
869 if ((sc->msg->flags & IIC_M_NOSTOP) == 0) { in glxiic_state_master_stop_callback()
873 ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1); in glxiic_state_master_stop_callback()
874 bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1, in glxiic_state_master_stop_callback()
878 sc->msg++; in glxiic_state_master_stop_callback()
883 sc->error = IIC_NOERR; in glxiic_state_master_stop_callback()
907 error = glxiic_state_table[sc->state].callback(sc, status); in glxiic_intr()
910 if (glxiic_state_table[sc->state].master) { in glxiic_intr()
913 sc->error = error; in glxiic_intr()
917 iicbus_intr(sc->iicbus, INTR_ERROR, &data); in glxiic_intr()
936 *oldaddr = sc->addr; in glxiic_reset()
937 sc->addr = addr; in glxiic_reset()
943 if (glxiic_state_table[sc->state].master) { in glxiic_reset()
944 sc->error = IIC_ESTATUS; in glxiic_reset()
965 if (sc->state != GLXIIC_STATE_IDLE) { in glxiic_transfer()
970 sc->msg = msgs; in glxiic_transfer()
971 sc->nmsgs = nmsgs; in glxiic_transfer()
975 ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1); in glxiic_transfer()
976 bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1, in glxiic_transfer()
980 error = sc->error; in glxiic_transfer()
993 /* Protect the read-modify-write operation. */ in glxiic_smb_map_interrupt()
1012 bus_write_4(sc->gpio_res, GLXIIC_GPIOL_IN_AUX1_SEL, in glxiic_gpio_enable()
1014 bus_write_4(sc->gpio_res, GLXIIC_GPIOL_OUT_AUX1_SEL, in glxiic_gpio_enable()
1022 bus_write_4(sc->gpio_res, GLXIIC_GPIOL_OUT_AUX1_SEL, in glxiic_gpio_disable()
1024 bus_write_4(sc->gpio_res, GLXIIC_GPIOL_IN_AUX1_SEL, in glxiic_gpio_disable()
1037 sc->sclfrq = GLXIIC_SLOW; in glxiic_smb_enable()
1040 sc->sclfrq = GLXIIC_FAST; in glxiic_smb_enable()
1043 sc->sclfrq = GLXIIC_FASTEST; in glxiic_smb_enable()
1052 bus_write_2(sc->smb_res, GLXIIC_SMB_CTRL2, in glxiic_smb_enable()
1053 GLXIIC_SCLFRQ(sc->sclfrq) | GLXIIC_SMB_CTRL2_EN_BIT); in glxiic_smb_enable()
1059 bus_write_1(sc->smb_res, GLXIIC_SMB_ADDR, in glxiic_smb_enable()
1062 bus_write_1(sc->smb_res, GLXIIC_SMB_ADDR, 0); in glxiic_smb_enable()
1066 bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1, in glxiic_smb_enable()
1075 sclfrq = bus_read_2(sc->smb_res, GLXIIC_SMB_CTRL2); in glxiic_smb_disable()
1076 bus_write_2(sc->smb_res, GLXIIC_SMB_CTRL2, in glxiic_smb_disable()