Lines Matching +full:gpio +full:- +full:ctrl1

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
36 * The driver is implemented as an interrupt-driven state machine,
63 /* CS5536 PCI-ISA ID. */
77 /* GPIO register offsets. */
81 /* GPIO 14 (SMB_CLK) and 15 (SMB_DATA) bitmasks. */
138 int gpio_rid; /* GPIO resource ID. */
139 struct resource *gpio_res; /* GPIO resource. */
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);
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()
338 device_printf(dev, "Could not allocate GPIO I/O port\n"); 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()
503 uint8_t status, ctrl1; in glxiic_stop_locked() local
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()
511 ctrl1 | GLXIIC_SMB_CTRL1_STOP_BIT); 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()
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()
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()
706 uint8_t ctrl1; in glxiic_state_master_addr_callback() local
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()
746 ctrl1 | GLXIIC_SMB_CTRL1_ACK_BIT); in glxiic_state_master_addr_callback()
774 bus_write_1(sc->smb_res, GLXIIC_SMB_STS, 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()
795 uint8_t ctrl1; in glxiic_state_master_rx_callback() local
816 bus_write_1(sc->smb_res, GLXIIC_SMB_STS, 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()
837 ctrl1 | GLXIIC_SMB_CTRL1_ACK_BIT); in glxiic_state_master_rx_callback()
848 uint8_t ctrl1; in glxiic_state_master_stop_callback() local
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()
875 ctrl1 | GLXIIC_SMB_CTRL1_START_BIT); 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()
959 uint8_t ctrl1; in glxiic_transfer() local
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()
977 ctrl1 | GLXIIC_SMB_CTRL1_START_BIT); 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()
1031 uint8_t ctrl1; in glxiic_smb_enable() local
1033 ctrl1 = 0; in glxiic_smb_enable()
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()
1057 ctrl1 |= GLXIIC_SMB_CTRL1_NMINTE_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()
1067 ctrl1 | GLXIIC_SMB_CTRL1_STASTRE_BIT | GLXIIC_SMB_CTRL1_INTEN_BIT); 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()