Lines Matching refs:sc

86 #define	debugf(sc, fmt, args...)	if ((sc)->debug)	\  argument
87 device_printf((sc)->dev, "%s: " fmt, __func__, ##args)
96 TWSI_READ(struct twsi_softc *sc, bus_size_t off) in TWSI_READ() argument
100 val = bus_read_4(sc->res[0], off); in TWSI_READ()
101 if (sc->debug > 1) in TWSI_READ()
102 debugf(sc, "read %x from %lx\n", val, off); in TWSI_READ()
107 TWSI_WRITE(struct twsi_softc *sc, bus_size_t off, uint32_t val) in TWSI_WRITE() argument
110 if (sc->debug > 1) in TWSI_WRITE()
111 debugf(sc, "Writing %x to %lx\n", val, off); in TWSI_WRITE()
112 bus_write_4(sc->res[0], off, val); in TWSI_WRITE()
116 twsi_control_clear(struct twsi_softc *sc, uint32_t mask) in twsi_control_clear() argument
120 val = TWSI_READ(sc, sc->reg_control); in twsi_control_clear()
121 debugf(sc, "read val=%x\n", val); in twsi_control_clear()
124 debugf(sc, "write val=%x\n", val); in twsi_control_clear()
125 TWSI_WRITE(sc, sc->reg_control, val); in twsi_control_clear()
129 twsi_control_set(struct twsi_softc *sc, uint32_t mask) in twsi_control_set() argument
133 val = TWSI_READ(sc, sc->reg_control); in twsi_control_set()
134 debugf(sc, "read val=%x\n", val); in twsi_control_set()
137 debugf(sc, "write val=%x\n", val); in twsi_control_set()
138 TWSI_WRITE(sc, sc->reg_control, val); in twsi_control_set()
142 twsi_clear_iflg(struct twsi_softc *sc) in twsi_clear_iflg() argument
147 if (sc->iflag_w1c) in twsi_clear_iflg()
148 twsi_control_set(sc, TWSI_CONTROL_IFLG); in twsi_clear_iflg()
150 twsi_control_clear(sc, TWSI_CONTROL_IFLG); in twsi_clear_iflg()
162 twsi_poll_ctrl(struct twsi_softc *sc, int timeout, uint32_t mask) in twsi_poll_ctrl() argument
166 debugf(sc, "Waiting for ctrl reg to match mask %x\n", mask); in twsi_poll_ctrl()
167 while (!(TWSI_READ(sc, sc->reg_control) & mask)) { in twsi_poll_ctrl()
172 debugf(sc, "done\n"); in twsi_poll_ctrl()
184 twsi_locked_start(device_t dev, struct twsi_softc *sc, int32_t mask, in twsi_locked_start() argument
190 mtx_assert(&sc->mutex, MA_OWNED); in twsi_locked_start()
194 iflg_set = TWSI_READ(sc, sc->reg_control) & TWSI_CONTROL_IFLG; in twsi_locked_start()
196 debugf(sc, "send start\n"); in twsi_locked_start()
197 twsi_control_set(sc, TWSI_CONTROL_START); in twsi_locked_start()
200 debugf(sc, "IFLG set, clearing (mask=%x)\n", mask); in twsi_locked_start()
201 twsi_clear_iflg(sc); in twsi_locked_start()
210 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { in twsi_locked_start()
211 debugf(sc, "timeout sending %sSTART condition\n", in twsi_locked_start()
216 status = TWSI_READ(sc, sc->reg_status); in twsi_locked_start()
217 debugf(sc, "status=%x\n", status); in twsi_locked_start()
220 debugf(sc, "wrong status (%02x) after sending %sSTART condition\n", in twsi_locked_start()
225 TWSI_WRITE(sc, sc->reg_data, slave); in twsi_locked_start()
226 twsi_clear_iflg(sc); in twsi_locked_start()
229 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { in twsi_locked_start()
230 debugf(sc, "timeout sending slave address (timeout=%d)\n", timeout); in twsi_locked_start()
235 status = TWSI_READ(sc, sc->reg_status); in twsi_locked_start()
238 debugf(sc, "no ACK (status: %02x) after sending slave address\n", in twsi_locked_start()
250 twsi_calc_baud_rate(struct twsi_softc *sc, const u_int target, in twsi_calc_baud_rate() argument
260 if (clk_get_freq(sc->clk_core, &clk) < 0) in twsi_calc_baud_rate()
263 debugf(sc, "Bus clock is at %ju\n", clk); in twsi_calc_baud_rate()
287 struct twsi_softc *sc; in twsi_reset() local
291 sc = device_get_softc(dev); in twsi_reset()
293 busfreq = IICBUS_GET_FREQUENCY(sc->iicbus, speed); in twsi_reset()
295 if (twsi_calc_baud_rate(sc, busfreq, &param) == -1) { in twsi_reset()
299 param = sc->baud_rate[speed].param; in twsi_reset()
300 debugf(sc, "Using IIC_FAST mode with speed param=%x\n", param); in twsi_reset()
305 param = sc->baud_rate[IIC_FAST].param; in twsi_reset()
306 debugf(sc, "Using IIC_FASTEST/UNKNOWN mode with speed param=%x\n", param); in twsi_reset()
311 debugf(sc, "Using clock param=%x\n", param); in twsi_reset()
313 mtx_lock(&sc->mutex); in twsi_reset()
314 TWSI_WRITE(sc, sc->reg_soft_reset, 0x1); in twsi_reset()
315 TWSI_WRITE(sc, sc->reg_baud_rate, param); in twsi_reset()
316 TWSI_WRITE(sc, sc->reg_control, TWSI_CONTROL_TWSIEN); in twsi_reset()
318 mtx_unlock(&sc->mutex); in twsi_reset()
326 struct twsi_softc *sc; in twsi_stop() local
328 sc = device_get_softc(dev); in twsi_stop()
330 debugf(sc, "%s\n", __func__); in twsi_stop()
331 mtx_lock(&sc->mutex); in twsi_stop()
332 twsi_control_clear(sc, TWSI_CONTROL_ACK); in twsi_stop()
333 twsi_control_set(sc, TWSI_CONTROL_STOP); in twsi_stop()
334 twsi_clear_iflg(sc); in twsi_stop()
336 mtx_unlock(&sc->mutex); in twsi_stop()
347 struct twsi_softc *sc; in twsi_repeated_start() local
350 sc = device_get_softc(dev); in twsi_repeated_start()
352 debugf(sc, "%s: slave=%x\n", __func__, slave); in twsi_repeated_start()
353 mtx_lock(&sc->mutex); in twsi_repeated_start()
354 rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave, in twsi_repeated_start()
356 mtx_unlock(&sc->mutex); in twsi_repeated_start()
371 struct twsi_softc *sc; in twsi_start() local
374 sc = device_get_softc(dev); in twsi_start()
376 debugf(sc, "%s: slave=%x\n", __func__, slave); in twsi_start()
377 mtx_lock(&sc->mutex); in twsi_start()
378 rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout); in twsi_start()
379 mtx_unlock(&sc->mutex); in twsi_start()
391 struct twsi_softc *sc; in twsi_read() local
395 sc = device_get_softc(dev); in twsi_read()
397 mtx_lock(&sc->mutex); in twsi_read()
406 twsi_control_clear(sc, TWSI_CONTROL_ACK); in twsi_read()
408 twsi_control_set(sc, TWSI_CONTROL_ACK); in twsi_read()
410 twsi_clear_iflg(sc); in twsi_read()
413 if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) { in twsi_read()
414 debugf(sc, "timeout reading data (delay=%d)\n", delay); in twsi_read()
419 status = TWSI_READ(sc, sc->reg_status); in twsi_read()
422 debugf(sc, "wrong status (%02x) while reading\n", status); in twsi_read()
427 *buf++ = TWSI_READ(sc, sc->reg_data); in twsi_read()
432 mtx_unlock(&sc->mutex); in twsi_read()
439 struct twsi_softc *sc; in twsi_write() local
443 sc = device_get_softc(dev); in twsi_write()
445 mtx_lock(&sc->mutex); in twsi_write()
448 TWSI_WRITE(sc, sc->reg_data, *buf++); in twsi_write()
450 twsi_clear_iflg(sc); in twsi_write()
452 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { in twsi_write()
453 debugf(sc, "timeout writing data (timeout=%d)\n", timeout); in twsi_write()
458 status = TWSI_READ(sc, sc->reg_status); in twsi_write()
460 debugf(sc, "wrong status (%02x) while writing\n", status); in twsi_write()
468 mtx_unlock(&sc->mutex); in twsi_write()
473 twsi_error(struct twsi_softc *sc, int err) in twsi_error() argument
478 debugf(sc, "Sending STOP condition for error %d\n", err); in twsi_error()
479 sc->transfer = 0; in twsi_error()
480 sc->error = err; in twsi_error()
481 sc->control_val = 0; in twsi_error()
482 TWSI_WRITE(sc, sc->reg_control, sc->control_val | TWSI_CONTROL_STOP); in twsi_error()
488 struct twsi_softc *sc; in twsi_transfer() local
492 sc = device_get_softc(dev); in twsi_transfer()
494 if (!sc->have_intr) in twsi_transfer()
497 mtx_lock(&sc->mutex); in twsi_transfer()
498 KASSERT(sc->transfer == 0, in twsi_transfer()
501 debugf(sc, "transmitting %d messages\n", nmsgs); in twsi_transfer()
502 status = TWSI_READ(sc, sc->reg_status); in twsi_transfer()
503 debugf(sc, "status=0x%x\n", status); in twsi_transfer()
505 debugf(sc, "Bad status at start of transfer\n"); in twsi_transfer()
506 twsi_error(sc, IIC_ESTATUS); in twsi_transfer()
510 sc->nmsgs = nmsgs; in twsi_transfer()
511 sc->msgs = msgs; in twsi_transfer()
512 sc->msg_idx = 0; in twsi_transfer()
513 sc->transfer = 1; in twsi_transfer()
514 sc->error = 0; in twsi_transfer()
518 debugf(sc, "msg %d is %d bytes long\n", i, msgs[i].len); in twsi_transfer()
522 sc->control_val = TWSI_CONTROL_TWSIEN | TWSI_CONTROL_INTEN; in twsi_transfer()
523 TWSI_WRITE(sc, sc->reg_control, sc->control_val | TWSI_CONTROL_START); in twsi_transfer()
524 msleep_sbt(sc, &sc->mutex, 0, "twsi", 3000 * SBT_1MS, SBT_1MS, 0); in twsi_transfer()
525 debugf(sc, "pause finish\n"); in twsi_transfer()
526 if (sc->error == 0 && sc->transfer != 0) { in twsi_transfer()
527 device_printf(sc->dev, "transfer timeout\n"); in twsi_transfer()
528 sc->error = IIC_ETIMEOUT; in twsi_transfer()
529 sc->transfer = 0; in twsi_transfer()
532 if (sc->error != 0) in twsi_transfer()
533 debugf(sc, "Error: %d\n", sc->error); in twsi_transfer()
537 debugf(sc, "status=0x%x\n", TWSI_READ(sc, sc->reg_status)); in twsi_transfer()
538 TWSI_WRITE(sc, sc->reg_control, 0); in twsi_transfer()
539 debugf(sc, "status=0x%x\n", TWSI_READ(sc, sc->reg_status)); in twsi_transfer()
540 error = sc->error; in twsi_transfer()
541 mtx_unlock(&sc->mutex); in twsi_transfer()
549 struct twsi_softc *sc; in twsi_intr() local
554 sc = arg; in twsi_intr()
557 mtx_lock(&sc->mutex); in twsi_intr()
558 debugf(sc, "Got interrupt, current msg=%u\n", sc->msg_idx); in twsi_intr()
560 status = TWSI_READ(sc, sc->reg_status); in twsi_intr()
561 debugf(sc, "reg control = 0x%x, status = 0x%x\n", in twsi_intr()
562 TWSI_READ(sc, sc->reg_control), status); in twsi_intr()
564 if (sc->transfer == 0) { in twsi_intr()
565 device_printf(sc->dev, "interrupt without active transfer, " in twsi_intr()
567 TWSI_WRITE(sc, sc->reg_control, sc->control_val | in twsi_intr()
579 debugf(sc, "Send address 0x%x\n", in twsi_intr()
580 sc->msgs[sc->msg_idx].slave); in twsi_intr()
582 if (sc->msgs[sc->msg_idx].flags & IIC_M_RD) in twsi_intr()
583 TWSI_WRITE(sc, sc->reg_data, in twsi_intr()
584 sc->msgs[sc->msg_idx].slave | LSB); in twsi_intr()
586 TWSI_WRITE(sc, sc->reg_data, in twsi_intr()
587 sc->msgs[sc->msg_idx].slave & ~LSB); in twsi_intr()
591 debugf(sc, "Address ACK-ed (write)\n"); in twsi_intr()
593 if (sc->msgs[sc->msg_idx].len > 0) { in twsi_intr()
595 sc->sent_bytes = 1; in twsi_intr()
596 debugf(sc, "Sending byte 0 (of %d) = %x\n", in twsi_intr()
597 sc->msgs[sc->msg_idx].len, in twsi_intr()
598 sc->msgs[sc->msg_idx].buf[0]); in twsi_intr()
599 TWSI_WRITE(sc, sc->reg_data, in twsi_intr()
600 sc->msgs[sc->msg_idx].buf[0]); in twsi_intr()
602 debugf(sc, "Zero-length write, sending STOP\n"); in twsi_intr()
603 TWSI_WRITE(sc, sc->reg_control, in twsi_intr()
604 sc->control_val | TWSI_CONTROL_STOP); in twsi_intr()
609 debugf(sc, "Address ACK-ed (read)\n"); in twsi_intr()
610 sc->recv_bytes = 0; in twsi_intr()
612 if (sc->msgs[sc->msg_idx].len == 0) { in twsi_intr()
613 debugf(sc, "Zero-length read, sending STOP\n"); in twsi_intr()
614 TWSI_WRITE(sc, sc->reg_control, in twsi_intr()
615 sc->control_val | TWSI_CONTROL_STOP); in twsi_intr()
616 } else if (sc->msgs[sc->msg_idx].len == 1) { in twsi_intr()
617 sc->control_val &= ~TWSI_CONTROL_ACK; in twsi_intr()
619 sc->control_val |= TWSI_CONTROL_ACK; in twsi_intr()
625 debugf(sc, "Address NACK-ed\n"); in twsi_intr()
626 twsi_error(sc, IIC_ENOACK); in twsi_intr()
629 debugf(sc, "Data byte NACK-ed\n"); in twsi_intr()
630 twsi_error(sc, IIC_ENOACK); in twsi_intr()
633 KASSERT(sc->sent_bytes <= sc->msgs[sc->msg_idx].len, in twsi_intr()
635 debugf(sc, "ACK received after transmitting data\n"); in twsi_intr()
636 if (sc->sent_bytes == sc->msgs[sc->msg_idx].len) { in twsi_intr()
637 debugf(sc, "Done TX data\n"); in twsi_intr()
640 if (!(sc->msgs[sc->msg_idx].flags & IIC_M_NOSTOP)) { in twsi_intr()
641 TWSI_WRITE(sc, sc->reg_control, in twsi_intr()
642 sc->control_val | TWSI_CONTROL_STOP); in twsi_intr()
644 debugf(sc, "NOSTOP flag\n"); in twsi_intr()
650 debugf(sc, "Sending byte %d (of %d) = 0x%x\n", in twsi_intr()
651 sc->sent_bytes, in twsi_intr()
652 sc->msgs[sc->msg_idx].len, in twsi_intr()
653 sc->msgs[sc->msg_idx].buf[sc->sent_bytes]); in twsi_intr()
654 TWSI_WRITE(sc, sc->reg_data, in twsi_intr()
655 sc->msgs[sc->msg_idx].buf[sc->sent_bytes]); in twsi_intr()
656 sc->sent_bytes++; in twsi_intr()
660 debugf(sc, "Received and ACK-ed data\n"); in twsi_intr()
661 KASSERT(sc->recv_bytes < sc->msgs[sc->msg_idx].len, in twsi_intr()
664 sc->msgs[sc->msg_idx].buf[sc->recv_bytes] = in twsi_intr()
665 TWSI_READ(sc, sc->reg_data); in twsi_intr()
666 debugf(sc, "Received byte %d (of %d) = 0x%x\n", in twsi_intr()
667 sc->recv_bytes, in twsi_intr()
668 sc->msgs[sc->msg_idx].len, in twsi_intr()
669 sc->msgs[sc->msg_idx].buf[sc->recv_bytes]); in twsi_intr()
670 sc->recv_bytes++; in twsi_intr()
673 if (sc->msgs[sc->msg_idx].len - sc->recv_bytes == 1) { in twsi_intr()
674 sc->control_val &= ~TWSI_CONTROL_ACK; in twsi_intr()
675 } else if (sc->msgs[sc->msg_idx].len == sc->recv_bytes) { in twsi_intr()
680 debugf(sc, "RX all but asked for more?\n"); in twsi_intr()
681 twsi_error(sc, IIC_ESTATUS); in twsi_intr()
686 debugf(sc, "Received and NACK-ed data\n"); in twsi_intr()
687 KASSERT(sc->recv_bytes == sc->msgs[sc->msg_idx].len - 1, in twsi_intr()
689 sc->msgs[sc->msg_idx].buf[sc->recv_bytes] = in twsi_intr()
690 TWSI_READ(sc, sc->reg_data); in twsi_intr()
691 debugf(sc, "Received byte %d (of %d) = 0x%x\n", in twsi_intr()
692 sc->recv_bytes, in twsi_intr()
693 sc->msgs[sc->msg_idx].len, in twsi_intr()
694 sc->msgs[sc->msg_idx].buf[sc->recv_bytes]); in twsi_intr()
695 sc->recv_bytes++; in twsi_intr()
697 if (sc->msgs[sc->msg_idx].len == sc->recv_bytes) { in twsi_intr()
698 debugf(sc, "Done RX data\n"); in twsi_intr()
699 if (!(sc->msgs[sc->msg_idx].flags & IIC_M_NOSTOP)) { in twsi_intr()
700 debugf(sc, "Send STOP\n"); in twsi_intr()
701 TWSI_WRITE(sc, sc->reg_control, in twsi_intr()
702 sc->control_val | TWSI_CONTROL_STOP); in twsi_intr()
710 debugf(sc, "NACK-ed before receving all bytes?\n"); in twsi_intr()
711 twsi_error(sc, IIC_ESTATUS); in twsi_intr()
716 debugf(sc, "Bus error\n"); in twsi_intr()
717 twsi_error(sc, IIC_EBUSERR); in twsi_intr()
720 debugf(sc, "Arbitration lost\n"); in twsi_intr()
721 twsi_error(sc, IIC_EBUSBSY); in twsi_intr()
724 debugf(sc, "unexpected status 0x%x\n", status); in twsi_intr()
725 twsi_error(sc, IIC_ESTATUS); in twsi_intr()
730 sc->msg_idx++; in twsi_intr()
731 if (sc->msg_idx == sc->nmsgs) { in twsi_intr()
732 debugf(sc, "All messages transmitted\n"); in twsi_intr()
733 sc->transfer = 0; in twsi_intr()
734 sc->error = 0; in twsi_intr()
735 } else if ((sc->msgs[sc->msg_idx].flags & IIC_M_NOSTART) == 0) { in twsi_intr()
736 debugf(sc, "Send (repeated) start\n"); in twsi_intr()
740 KASSERT((sc->msgs[sc->msg_idx - 1].flags & IIC_M_NOSTOP) != 0, in twsi_intr()
742 KASSERT((sc->msgs[sc->msg_idx].flags & IIC_M_RD) == in twsi_intr()
743 (sc->msgs[sc->msg_idx - 1].flags & IIC_M_RD), in twsi_intr()
745 debugf(sc, "NOSTART message after NOSTOP\n"); in twsi_intr()
746 sc->sent_bytes = 0; in twsi_intr()
747 sc->recv_bytes = 0; in twsi_intr()
748 if ((sc->msgs[sc->msg_idx].flags & IIC_M_RD) == 0) { in twsi_intr()
752 debugf(sc, "Read+NOSTART unsupported\n"); in twsi_intr()
753 twsi_error(sc, IIC_ESTATUS); in twsi_intr()
761 debugf(sc, "Refresh reg_control\n"); in twsi_intr()
762 TWSI_WRITE(sc, sc->reg_control, sc->control_val | in twsi_intr()
763 (sc->iflag_w1c ? TWSI_CONTROL_IFLG : 0) | in twsi_intr()
766 debugf(sc, "Done with interrupt, transfer = %d\n", sc->transfer); in twsi_intr()
767 if (sc->transfer == 0) in twsi_intr()
768 wakeup(sc); in twsi_intr()
769 mtx_unlock(&sc->mutex); in twsi_intr()
775 struct twsi_softc *sc; in twsi_intr_start() local
777 sc = device_get_softc(pdev); in twsi_intr_start()
779 if ((bus_setup_intr(pdev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, in twsi_intr_start()
780 NULL, twsi_intr, sc, &sc->intrhand))) in twsi_intr_start()
783 sc->have_intr = true; in twsi_intr_start()
789 struct twsi_softc *sc; in twsi_attach() local
794 sc = device_get_softc(dev); in twsi_attach()
795 sc->dev = dev; in twsi_attach()
797 mtx_init(&sc->mutex, device_get_nameunit(dev), "twsi", MTX_DEF); in twsi_attach()
799 if (bus_alloc_resources(dev, res_spec, sc->res)) { in twsi_attach()
806 sc->debug = 1; in twsi_attach()
812 &sc->debug, 0, "Set debug level (zero to disable)"); in twsi_attach()
815 if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) { in twsi_attach()
830 struct twsi_softc *sc; in twsi_detach() local
833 sc = device_get_softc(dev); in twsi_detach()
838 if (sc->iicbus != NULL) in twsi_detach()
839 if ((rv = device_delete_child(dev, sc->iicbus)) != 0) in twsi_detach()
842 if (sc->intrhand != NULL) in twsi_detach()
843 bus_teardown_intr(sc->dev, sc->res[1], sc->intrhand); in twsi_detach()
845 bus_release_resources(dev, res_spec, sc->res); in twsi_detach()
847 mtx_destroy(&sc->mutex); in twsi_detach()