Lines Matching +full:irq +full:- +full:start

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
36 * The driver is implemented as an interrupt-driven state machine,
63 /* CS5536 PCI-ISA ID. */
141 int irq_rid; /* IRQ resource ID. */
142 struct resource *irq_res; /* IRQ resource. */
143 void *irq_handler; /* IRQ handler cookie. */
144 int old_irq; /* IRQ mapped by board firmware. */
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);
252 static void glxiic_smb_map_interrupt(int irq);
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()
314 int error, irq, unit; in glxiic_attach() local
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()
346 /* Read the existing IRQ map. */ in glxiic_attach()
348 sc->old_irq = GLXIIC_MAP_TO_SMB_IRQ(irq_map); in glxiic_attach()
351 if (resource_int_value("glxiic", unit, "irq", &irq) == 0) { in glxiic_attach()
352 if (irq < 1 || irq > 15) { in glxiic_attach()
353 device_printf(dev, "Bad value %d for glxiic.%d.irq\n", in glxiic_attach()
354 irq, unit); in glxiic_attach()
360 device_printf(dev, "Using irq %d set by hint\n", irq); in glxiic_attach()
361 } else if (sc->old_irq != 0) { in glxiic_attach()
363 device_printf(dev, "Using irq %d set by firmware\n", in glxiic_attach()
364 irq); in glxiic_attach()
365 irq = sc->old_irq; in glxiic_attach()
367 device_printf(dev, "No irq mapped by firmware"); in glxiic_attach()
368 printf(" and no glxiic.%d.irq hint provided\n", unit); in glxiic_attach()
373 /* Map the SMBus interrupt to the requested legacy IRQ. */ in glxiic_attach()
374 glxiic_smb_map_interrupt(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()
378 irq, irq, 1, RF_SHAREABLE | RF_ACTIVE); in glxiic_attach()
379 if (sc->irq_res == NULL) { in glxiic_attach()
380 device_printf(dev, "Could not allocate IRQ %d\n", irq); 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()
388 device_printf(dev, "Could not setup IRQ handler\n"); 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()
519 bus_read_1(sc->smb_res, GLXIIC_SMB_SDA); in glxiic_stop_locked()
521 /* Check stall after start bit and clear if needed */ 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()
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()
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()
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()
867 if (--sc->nmsgs > 0) { in glxiic_state_master_stop_callback()
868 /* Start transfer of next message. */ 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()
974 /* Set start bit and let glxiic_intr() handle the transfer. */ 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()
988 glxiic_smb_map_interrupt(int irq) in glxiic_smb_map_interrupt() argument
993 /* Protect the read-modify-write operation. */ in glxiic_smb_map_interrupt()
999 if (irq != old_irq) { in glxiic_smb_map_interrupt()
1001 irq_map |= GLXIIC_SMB_IRQ_TO_MAP(irq); 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()
1065 /* Enable stall after start and interrupt. */ 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()