Lines Matching +full:wr +full:- +full:setup

2  * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2025 Poul-Henning Kamp <phk@FreeBSD.org>
29 * The GENI is actually a multi-protocol serial controller, so a lot of
125 #define RD(sc, reg) bus_read_4((sc)->regs_res, reg)
126 #define WR(sc, reg, val) bus_write_4((sc)->regs_res, reg, val) macro
131 device_printf(sc->dev, "Register Dump\n"); in geni_dump_regs()
133 device_printf(sc->dev, \ in geni_dump_regs()
156 mtx_lock_spin(&sc->intr_lock); in geniiic_intr()
160 if (sc->rx_buf != NULL && rx_fifo_status & 0x3f) { in geniiic_intr()
163 unsigned gotlen = (((rx_fifo_status & 0x3f) << 2)-1) * 4; in geniiic_intr()
173 for (u = 0; u < 4 && sc->rx_len && gotlen; u++) { in geniiic_intr()
174 *sc->rx_buf++ = data & 0xff; in geniiic_intr()
176 sc->rx_len--; in geniiic_intr()
177 gotlen--; in geniiic_intr()
182 WR(sc, GENI_M_IRQ_CLEAR, (1<<26)); in geniiic_intr()
187 sc->rx_complete = true; in geniiic_intr()
188 WR(sc, GENI_M_IRQ_EN_CLEAR, (1<<0)); in geniiic_intr()
189 WR(sc, GENI_M_IRQ_EN_CLEAR, (1<<26)); in geniiic_intr()
190 WR(sc, GENI_M_IRQ_CLEAR, (1<<0)); in geniiic_intr()
194 sc->cmd_status = m_status; in geniiic_intr()
196 if (sc->rx_buf == NULL) { in geniiic_intr()
197 device_printf(sc->dev, in geniiic_intr()
200 WR(sc, GENI_M_IRQ_EN, 0); in geniiic_intr()
201 WR(sc, GENI_M_IRQ_CLEAR, m_status); in geniiic_intr()
202 device_printf(sc->dev, in geniiic_intr()
205 device_printf(sc->dev, in geniiic_intr()
208 device_printf(sc->dev, in geniiic_intr()
211 device_printf(sc->dev, in geniiic_intr()
214 WR(sc, GENI_DMA_TX_IRQ_EN_CLR, RD(sc, GENI_DMA_TX_IRQ_STAT)); in geniiic_intr()
215 WR(sc, GENI_DMA_TX_IRQ_CLR, RD(sc, GENI_DMA_TX_IRQ_STAT)); in geniiic_intr()
216 WR(sc, GENI_DMA_RX_IRQ_EN_CLR, RD(sc, GENI_DMA_RX_IRQ_STAT)); in geniiic_intr()
217 WR(sc, GENI_DMA_RX_IRQ_CLR, RD(sc, GENI_DMA_RX_IRQ_STAT)); in geniiic_intr()
219 mtx_unlock_spin(&sc->intr_lock); in geniiic_intr()
246 WR(sc, GENI_M_IRQ_CLEAR, istatus); in geniiic_read()
248 sc->rx_complete = false; in geniiic_read()
249 sc->rx_fifo = false; in geniiic_read()
250 sc->rx_buf = buf; in geniiic_read()
251 sc->rx_len = len; in geniiic_read()
252 WR(sc, GENI_I2C_RX_TRANS_LEN, len); in geniiic_read()
264 WR(sc, GENI_RX_WATERMARK_REG, sc->rx_fifo_size - 4); in geniiic_read()
267 WR(sc, GENI_M_IRQ_EN, (1<<0) | (1<<26)); in geniiic_read()
270 WR(sc, GENI_IRQ_EN, (1<<2)); in geniiic_read()
272 WR(sc, GENI_M_CMD0, cmd); in geniiic_read()
274 mtx_lock_spin(&sc->intr_lock); in geniiic_read()
275 sc->rx_fifo = false; in geniiic_read()
278 msleep_spin_sbt(sc, &sc->intr_lock, in geniiic_read()
280 if (sc->rx_complete) in geniiic_read()
283 if (msec > sc->worst) { in geniiic_read()
284 device_printf(sc->dev, in geniiic_read()
285 "Tworst from %u to %u\n", sc->worst, msec); in geniiic_read()
287 sc->worst = msec; in geniiic_read()
290 if (!sc->rx_complete) { in geniiic_read()
292 WR(sc, GENI_M_CMD_CTRL_REG, (1<<2)); in geniiic_read()
294 WR(sc, GENI_IRQ_EN, 0); in geniiic_read()
295 device_printf(sc->dev, in geniiic_read()
296 "Incomplete read (residual %x)\n", sc->rx_len); in geniiic_read()
299 sc->rx_buf = NULL; in geniiic_read()
300 len = sc->rx_len; in geniiic_read()
301 sc->rx_len = 0; in geniiic_read()
303 mtx_unlock_spin(&sc->intr_lock); in geniiic_read()
306 device_printf(sc->dev, \ in geniiic_read()
308 slave, len, cmd, sc->cmd_status \ in geniiic_read()
312 unsigned unit = device_get_unit(sc->dev); in geniiic_read()
321 if (sc->cmd_status & (1<<10)) { in geniiic_read()
342 WR(sc, GENI_M_IRQ_CLEAR, status); in geniiic_write()
344 WR(sc, GENI_I2C_TX_TRANS_LEN, len); in geniiic_write()
356 WR(sc, GENI_M_CMD0, cmd); in geniiic_write()
361 if (len) { data |= *buf << 0; buf++; len--; } in geniiic_write()
362 if (len) { data |= *buf << 8; buf++; len--; } in geniiic_write()
363 if (len) { data |= *buf << 16; buf++; len--; } in geniiic_write()
364 if (len) { data |= *buf << 24; buf++; len--; } in geniiic_write()
365 WR(sc, GENI_TX_FIFOn, data); in geniiic_write()
376 device_printf(sc->dev, in geniiic_write()
402 if (sc->nfail > 4) { in geniiic_transfer()
407 sx_xlock(&sc->real_bus_lock); in geniiic_transfer()
419 (u < nmsgs - 1) && (msgs[u].flags & IIC_M_NOSTOP); in geniiic_transfer()
437 sc->nfail++; in geniiic_transfer()
439 sc->nfail = 0; in geniiic_transfer()
440 sx_xunlock(&sc->real_bus_lock); in geniiic_transfer()
451 WR(sc, GENI_M_IRQ_EN, 0); in geniiic_reset()
452 WR(sc, GENI_M_IRQ_CLEAR, ~0); in geniiic_reset()
453 WR(sc, GENI_DMA_TX_IRQ_EN_CLR, ~0); in geniiic_reset()
454 WR(sc, GENI_DMA_TX_IRQ_CLR, ~0); in geniiic_reset()
455 WR(sc, GENI_DMA_RX_IRQ_EN_CLR, ~0); in geniiic_reset()
456 WR(sc, GENI_DMA_RX_IRQ_CLR, ~0); in geniiic_reset()
459 WR(sc, GENI_M_CMD_CTRL_REG, (1<<1)); in geniiic_reset()
461 WR(sc, GENI_DMA_RX_FSM_RST, 1); in geniiic_reset()
469 WR(sc, GENI_DMA_TX_FSM_RST, 1); in geniiic_reset()
489 if (sx_try_xlock(&sc->bus_lock) == 0) in geniiic_callback()
492 sc->bus_locked = true; in geniiic_callback()
496 if (!sc->bus_locked) { in geniiic_callback()
499 sc->bus_locked = false; in geniiic_callback()
500 sx_xunlock(&sc->bus_lock); in geniiic_callback()
518 mtx_init(&sc->intr_lock, "geniiic intr lock", NULL, MTX_SPIN); in geniiic_attach()
519 sx_init(&sc->real_bus_lock, "geniiic real bus lock"); in geniiic_attach()
520 sx_init(&sc->bus_lock, "geniiic bus lock"); in geniiic_attach()
522 sc->rx_fifo_size = (RD(sc, GENI_HW_PARAM_1) >> 16) & 0x3f; in geniiic_attach()
523 device_printf(sc->dev, " RX fifo size= 0x%x\n", sc->rx_fifo_size); in geniiic_attach()
532 sc->iicbus = device_add_child(sc->dev, "iicbus", DEVICE_UNIT_ANY); in geniiic_attach()
533 if (sc->iicbus == NULL) { in geniiic_attach()
534 device_printf(sc->dev, "iicbus driver not found\n"); in geniiic_attach()
538 error = bus_setup_intr(sc->dev, in geniiic_attach()
539 sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE, in geniiic_attach()
540 geniiic_intr, NULL, sc, &sc->intr_handle); in geniiic_attach()
542 device_printf(sc->dev, in geniiic_attach()
543 "Unable to setup irq: error %d\n", error); in geniiic_attach()
546 bus_attach_children(sc->dev); in geniiic_attach()
555 error = bus_generic_detach(sc->dev); in geniiic_detach()
559 WR(sc, GENI_M_IRQ_EN, 0); in geniiic_detach()
561 if (sc->intr_handle) { in geniiic_detach()
562 bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); in geniiic_detach()
565 sx_xlock(&sc->bus_lock); in geniiic_detach()
566 sx_xlock(&sc->real_bus_lock); in geniiic_detach()
568 geniiic_reset(sc->dev, 0, 0, NULL); in geniiic_detach()
569 sc->iicbus = NULL; in geniiic_detach()
570 sc->intr_handle = NULL; in geniiic_detach()
572 sx_xunlock(&sc->real_bus_lock); in geniiic_detach()
573 sx_xunlock(&sc->bus_lock); in geniiic_detach()
575 sx_destroy(&sc->real_bus_lock); in geniiic_detach()
576 sx_destroy(&sc->bus_lock); in geniiic_detach()
578 mtx_destroy(&sc->intr_lock); in geniiic_detach()
587 device_printf(sc->dev, "suspend method is NO-OP (good luck!)\n"); in geniiic_suspend()
589 error = bus_generic_suspend(sc->dev); in geniiic_suspend()
598 device_printf(sc->dev, "resume method is NO-OP (good luck!)\n"); in geniiic_resume()
600 error = bus_generic_resume(sc->dev); in geniiic_resume()