2 * Copyright (c) 2014 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * Intel 4th generation mobile cpus integrated I2C device, smbus driver.
37 * See ig4_reg.h for datasheet reference and notes.
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/module.h>
44 #include <sys/errno.h>
46 #include <sys/mutex.h>
47 #include <sys/syslog.h>
49 #include <sys/sysctl.h>
53 #include <bus/pci/pcivar.h>
54 #include <bus/pci/pcireg.h>
55 #include <bus/smbus/smbconf.h>
62 #define TRANS_NORMAL 1
66 static void ig4iic_intr(void *cookie);
67 static void ig4iic_dump(ig4iic_softc_t *sc);
70 SYSCTL_INT(_debug, OID_AUTO, ig4_dump, CTLTYPE_INT | CTLFLAG_RW,
74 * Low-level inline support functions
78 reg_write(ig4iic_softc_t *sc, uint32_t reg, uint32_t value)
80 bus_space_write_4(sc->regs_t, sc->regs_h, reg, value);
81 bus_space_barrier(sc->regs_t, sc->regs_h, reg, 4,
82 BUS_SPACE_BARRIER_WRITE);
87 reg_read(ig4iic_softc_t *sc, uint32_t reg)
91 bus_space_barrier(sc->regs_t, sc->regs_h, reg, 4,
92 BUS_SPACE_BARRIER_READ);
93 value = bus_space_read_4(sc->regs_t, sc->regs_h, reg);
98 * Enable or disable the controller and wait for the controller to acknowledge
103 set_controller(ig4iic_softc_t *sc, uint32_t ctl)
109 reg_write(sc, IG4_REG_I2C_EN, ctl);
110 error = SMB_ETIMEOUT;
112 for (retry = 100; retry > 0; --retry) {
113 v = reg_read(sc, IG4_REG_ENABLE_STATUS);
114 if (((v ^ ctl) & IG4_I2C_ENABLE) == 0) {
118 tsleep(sc, 0, "i2cslv", 1);
124 * Wait up to 25ms for the requested status using a 25uS polling loop.
128 wait_status(ig4iic_softc_t *sc, uint32_t status)
136 error = SMB_ETIMEOUT;
137 count = sys_cputimer->count();
138 limit = sys_cputimer->freq / 40;
142 * Check requested status
144 v = reg_read(sc, IG4_REG_I2C_STA);
151 * When waiting for receive data break-out if the interrupt
152 * loaded data into the FIFO.
154 if (status & IG4_STATUS_RX_NOTEMPTY) {
155 if (sc->rpos != sc->rnext) {
162 * When waiting for the transmit FIFO to become empty,
163 * reset the timeout if we see a change in the transmit
164 * FIFO level as progress is being made.
166 if (status & IG4_STATUS_TX_EMPTY) {
167 v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK;
170 count = sys_cputimer->count();
175 * Stop if we've run out of time.
177 if (sys_cputimer->count() - count > limit)
181 * When waiting for receive data let the interrupt do its
182 * work, otherwise poll with the lock held.
184 if (status & IG4_STATUS_RX_NOTEMPTY) {
185 lksleep(sc, &sc->lk, 0, "i2cwait", (hz + 99) / 100);
195 * Read I2C data. The data might have already been read by
196 * the interrupt code, otherwise it is sitting in the data
201 data_read(ig4iic_softc_t *sc)
205 if (sc->rpos == sc->rnext) {
206 c = (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
208 c = sc->rbuf[sc->rpos & IG4_RBUFMASK];
215 * Set the slave address. The controller must be disabled when
216 * changing the address.
218 * This operation does not issue anything to the I2C bus but sets
219 * the target address for when the controller later issues a START.
223 set_slave_addr(ig4iic_softc_t *sc, uint8_t slave, int trans_op)
229 use_10bit = sc->use_10bit;
230 if (trans_op & SMB_TRANS_7BIT)
232 if (trans_op & SMB_TRANS_10BIT)
235 if (sc->slave_valid && sc->last_slave == slave &&
236 sc->use_10bit == use_10bit) {
239 sc->use_10bit = use_10bit;
242 * Wait for TXFIFO to drain before disabling the controller.
244 * If a write message has not been completed it's really a
245 * programming error, but for now in that case issue an extra
248 * If a read message has not been completed it's also a programming
249 * error, for now just ignore it.
251 wait_status(sc, IG4_STATUS_TX_NOTFULL);
252 if (sc->write_started) {
253 reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_STOP);
254 sc->write_started = 0;
256 if (sc->read_started)
257 sc->read_started = 0;
258 wait_status(sc, IG4_STATUS_TX_EMPTY);
260 set_controller(sc, 0);
261 ctl = reg_read(sc, IG4_REG_CTL);
262 ctl &= ~IG4_CTL_10BIT;
263 ctl |= IG4_CTL_RESTARTEN;
267 tar |= IG4_TAR_10BIT;
268 ctl |= IG4_CTL_10BIT;
270 reg_write(sc, IG4_REG_CTL, ctl);
271 reg_write(sc, IG4_REG_TAR_ADD, tar);
272 set_controller(sc, IG4_I2C_ENABLE);
274 sc->last_slave = slave;
278 * Issue START with byte command, possible count, and a variable length
279 * read or write buffer, then possible turn-around read. The read also
280 * has a possible count received.
284 * Quick: START+ADDR+RD/WR STOP
286 * Normal: START+ADDR+WR CMD DATA..DATA STOP
289 * RESTART+ADDR RDATA..RDATA STOP
290 * (can also be used for I2C transactions)
292 * Process Call: START+ADDR+WR CMD DATAL DATAH
293 * RESTART+ADDR+RD RDATAL RDATAH STOP
295 * Block: START+ADDR+RD CMD
296 * RESTART+ADDR+RD RCOUNT DATA... STOP
299 * RESTART+ADDR+WR WCOUNT DATA... STOP
301 * For I2C - basically, no *COUNT fields, possibly no *CMD field. If the
302 * sender needs to issue a 2-byte command it will incorporate it
303 * into the write buffer and also set NOCMD.
305 * Generally speaking, the START+ADDR / RESTART+ADDR is handled automatically
306 * by the controller at the beginning of a command sequence or on a data
307 * direction turn-around, and we only need to tell it when to issue the STOP.
310 smb_transaction(ig4iic_softc_t *sc, char cmd, int op,
311 char *wbuf, int wcount, char *rbuf, int rcount, int *actualp)
318 * Debugging - dump registers
321 unit = device_get_unit(sc->dev);
322 if (ig4_dump & (1 << unit)) {
323 ig4_dump &= ~(1 << unit);
329 * Issue START or RESTART with next data byte, clear any previous
330 * abort condition that may have been holding the txfifo in reset.
332 last = IG4_DATA_RESTART;
333 reg_read(sc, IG4_REG_CLR_TX_ABORT);
338 * Issue command if not told otherwise (smbus).
340 if ((op & SMB_TRANS_NOCMD) == 0) {
341 error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
345 if (wcount == 0 && rcount == 0 && (op & SMB_TRANS_NOSTOP) == 0)
346 last |= IG4_DATA_STOP;
347 reg_write(sc, IG4_REG_DATA_CMD, last);
352 * Clean out any previously received data.
354 if (sc->rpos != sc->rnext &&
355 (op & SMB_TRANS_NOREPORT) == 0) {
356 device_printf(sc->dev,
357 "discarding %d bytes of spurious data\n",
358 sc->rnext - sc->rpos);
364 * If writing and not told otherwise, issue the write count (smbus).
366 if (wcount && (op & SMB_TRANS_NOCNT) == 0) {
367 error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
371 reg_write(sc, IG4_REG_DATA_CMD, last);
379 error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
382 last |= (u_char)*wbuf;
383 if (wcount == 1 && rcount == 0 && (op & SMB_TRANS_NOSTOP) == 0)
384 last |= IG4_DATA_STOP;
385 reg_write(sc, IG4_REG_DATA_CMD, last);
392 * Issue reads to xmit FIFO (strange, I know) to tell the controller
393 * to clock in data. At the moment just issue one read ahead to
394 * pipeline the incoming data.
396 * NOTE: In the case of NOCMD and wcount == 0 we still issue a
397 * RESTART here, even if the data direction has not changed
398 * from the previous CHAINing call. This we force the RESTART.
399 * (A new START is issued automatically by the controller in
400 * the other nominal cases such as a data direction change or
401 * a previous STOP was issued).
403 * If this will be the last byte read we must also issue the STOP
404 * at the end of the read.
407 last = IG4_DATA_RESTART | IG4_DATA_COMMAND_RD;
409 (op & (SMB_TRANS_NOSTOP | SMB_TRANS_NOCNT)) ==
411 last |= IG4_DATA_STOP;
413 reg_write(sc, IG4_REG_DATA_CMD, last);
414 last = IG4_DATA_COMMAND_RD;
418 * Bulk read (i2c) and count field handling (smbus)
422 * Maintain a pipeline by queueing the allowance for the next
423 * read before waiting for the current read.
426 if (op & SMB_TRANS_NOCNT)
427 last = (rcount == 2) ? IG4_DATA_STOP : 0;
430 reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD |
433 error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY);
435 if ((op & SMB_TRANS_NOREPORT) == 0) {
436 device_printf(sc->dev,
437 "rx timeout addr 0x%02x\n",
442 last = data_read(sc);
444 if (op & SMB_TRANS_NOCNT) {
445 *rbuf = (u_char)last;
452 * Handle count field (smbus), which is not part of
453 * the rcount'ed buffer. The first read data in a
454 * bulk transfer is the count.
456 * XXX if rcount is loaded as 0 how do I generate a
457 * STOP now without issuing another RD or WR?
459 if (rcount > (u_char)last)
460 rcount = (u_char)last;
461 op |= SMB_TRANS_NOCNT;
466 /* XXX wait for xmit buffer to become empty */
467 last = reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
473 * SMBUS API FUNCTIONS
475 * Called from ig4iic_pci_attach/detach()
478 ig4iic_attach(ig4iic_softc_t *sc)
483 lockmgr(&sc->lk, LK_EXCLUSIVE);
485 v = reg_read(sc, IG4_REG_COMP_TYPE);
486 kprintf("type %08x", v);
487 v = reg_read(sc, IG4_REG_COMP_PARAM1);
488 kprintf(" params %08x", v);
489 v = reg_read(sc, IG4_REG_GENERAL);
490 kprintf(" general %08x", v);
491 if ((v & IG4_GENERAL_SWMODE) == 0) {
492 v |= IG4_GENERAL_SWMODE;
493 reg_write(sc, IG4_REG_GENERAL, v);
494 v = reg_read(sc, IG4_REG_GENERAL);
495 kprintf(" (updated %08x)", v);
498 v = reg_read(sc, IG4_REG_SW_LTR_VALUE);
499 kprintf(" swltr %08x", v);
500 v = reg_read(sc, IG4_REG_AUTO_LTR_VALUE);
501 kprintf(" autoltr %08x", v);
503 v = reg_read(sc, IG4_REG_COMP_VER);
504 kprintf(" version %08x\n", v);
505 if (v != IG4_COMP_VER) {
510 v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
511 kprintf("SS_SCL_HCNT=%08x", v);
512 v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
513 kprintf(" LCNT=%08x", v);
514 v = reg_read(sc, IG4_REG_FS_SCL_HCNT);
515 kprintf(" FS_SCL_HCNT=%08x", v);
516 v = reg_read(sc, IG4_REG_FS_SCL_LCNT);
517 kprintf(" LCNT=%08x\n", v);
518 v = reg_read(sc, IG4_REG_SDA_HOLD);
519 kprintf("HOLD %08x\n", v);
521 v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
522 reg_write(sc, IG4_REG_FS_SCL_HCNT, v);
523 v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
524 reg_write(sc, IG4_REG_FS_SCL_LCNT, v);
527 * Program based on a 25000 Hz clock. This is a bit of a
528 * hack (obviously). The defaults are 400 and 470 for standard
529 * and 60 and 130 for fast. The defaults for standard fail
530 * utterly (presumably cause an abort) because the clock time
531 * is ~18.8ms by default. This brings it down to ~4ms (for now).
533 reg_write(sc, IG4_REG_SS_SCL_HCNT, 100);
534 reg_write(sc, IG4_REG_SS_SCL_LCNT, 125);
535 reg_write(sc, IG4_REG_FS_SCL_HCNT, 100);
536 reg_write(sc, IG4_REG_FS_SCL_LCNT, 125);
539 * Use a threshold of 1 so we get interrupted on each character,
540 * allowing us to use lksleep() in our poll code. Not perfect
541 * but this is better than using DELAY() for receiving data.
543 reg_write(sc, IG4_REG_RX_TL, 1);
545 reg_write(sc, IG4_REG_CTL,
547 IG4_CTL_SLAVE_DISABLE |
551 sc->smb = device_add_child(sc->dev, "smbus", -1);
552 if (sc->smb == NULL) {
553 device_printf(sc->dev, "smbus driver not found\n");
560 * Don't do this, it blows up the PCI config
562 reg_write(sc, IG4_REG_RESETS, IG4_RESETS_ASSERT);
563 reg_write(sc, IG4_REG_RESETS, IG4_RESETS_DEASSERT);
567 * Interrupt on STOP detect or receive character ready
569 reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET |
571 if (set_controller(sc, 0))
572 device_printf(sc->dev, "controller error during attach-1\n");
573 if (set_controller(sc, IG4_I2C_ENABLE))
574 device_printf(sc->dev, "controller error during attach-2\n");
575 error = bus_setup_intr(sc->dev, sc->intr_res, 0,
576 ig4iic_intr, sc, &sc->intr_handle, NULL);
578 device_printf(sc->dev,
579 "Unable to setup irq: error %d\n", error);
583 /* Attach us to the smbus */
584 lockmgr(&sc->lk, LK_RELEASE);
585 error = bus_generic_attach(sc->dev);
586 lockmgr(&sc->lk, LK_EXCLUSIVE);
588 device_printf(sc->dev,
589 "failed to attach child: error %d\n", error);
592 sc->generic_attached = 1;
595 lockmgr(&sc->lk, LK_RELEASE);
600 ig4iic_detach(ig4iic_softc_t *sc)
604 lockmgr(&sc->lk, LK_EXCLUSIVE);
606 reg_write(sc, IG4_REG_INTR_MASK, 0);
607 reg_read(sc, IG4_REG_CLR_INTR);
608 set_controller(sc, 0);
610 if (sc->generic_attached) {
611 error = bus_generic_detach(sc->dev);
614 sc->generic_attached = 0;
617 device_delete_child(sc->dev, sc->smb);
620 if (sc->intr_handle) {
621 bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle);
622 sc->intr_handle = NULL;
627 lockmgr(&sc->lk, LK_RELEASE);
632 ig4iic_smb_callback(device_t dev, int index, void *data)
634 ig4iic_softc_t *sc = device_get_softc(dev);
637 lockmgr(&sc->lk, LK_EXCLUSIVE);
640 case SMB_REQUEST_BUS:
643 case SMB_RELEASE_BUS:
651 lockmgr(&sc->lk, LK_RELEASE);
657 * Quick command. i.e. START + cmd + R/W + STOP and no data. It is
658 * unclear to me how I could implement this with the intel i2c controller
659 * because the controler sends STARTs and STOPs automatically with data.
662 ig4iic_smb_quick(device_t dev, u_char slave, int how)
664 ig4iic_softc_t *sc = device_get_softc(dev);
667 lockmgr(&sc->lk, LK_EXCLUSIVE);
671 error = SMB_ENOTSUPP;
674 error = SMB_ENOTSUPP;
677 error = SMB_ENOTSUPP;
680 lockmgr(&sc->lk, LK_RELEASE);
686 * Incremental send byte without stop (?). It is unclear why the slave
687 * address is specified if this presumably is used in combination with
688 * ig4iic_smb_quick().
690 * (Also, how would this work anyway? Issue the last byte with writeb()?)
693 ig4iic_smb_sendb(device_t dev, u_char slave, char byte)
695 ig4iic_softc_t *sc = device_get_softc(dev);
699 lockmgr(&sc->lk, LK_EXCLUSIVE);
701 set_slave_addr(sc, slave, 0);
703 if (wait_status(sc, IG4_STATUS_TX_NOTFULL) == 0) {
704 reg_write(sc, IG4_REG_DATA_CMD, cmd);
707 error = SMB_ETIMEOUT;
710 lockmgr(&sc->lk, LK_RELEASE);
715 * Incremental receive byte without stop (?). It is unclear why the slave
716 * address is specified if this presumably is used in combination with
717 * ig4iic_smb_quick().
720 ig4iic_smb_recvb(device_t dev, u_char slave, char *byte)
722 ig4iic_softc_t *sc = device_get_softc(dev);
725 lockmgr(&sc->lk, LK_EXCLUSIVE);
727 set_slave_addr(sc, slave, 0);
728 reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD);
729 if (wait_status(sc, IG4_STATUS_RX_NOTEMPTY) == 0) {
730 *byte = data_read(sc);
734 error = SMB_ETIMEOUT;
737 lockmgr(&sc->lk, LK_RELEASE);
742 * Write command and single byte in transaction.
745 ig4iic_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
747 ig4iic_softc_t *sc = device_get_softc(dev);
750 lockmgr(&sc->lk, LK_EXCLUSIVE);
752 set_slave_addr(sc, slave, 0);
753 error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
754 &byte, 1, NULL, 0, NULL);
756 lockmgr(&sc->lk, LK_RELEASE);
761 * Write command and single word in transaction.
764 ig4iic_smb_writew(device_t dev, u_char slave, char cmd, short word)
766 ig4iic_softc_t *sc = device_get_softc(dev);
770 lockmgr(&sc->lk, LK_EXCLUSIVE);
772 set_slave_addr(sc, slave, 0);
773 buf[0] = word & 0xFF;
775 error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
776 buf, 2, NULL, 0, NULL);
778 lockmgr(&sc->lk, LK_RELEASE);
783 * write command and read single byte in transaction.
786 ig4iic_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
788 ig4iic_softc_t *sc = device_get_softc(dev);
791 lockmgr(&sc->lk, LK_EXCLUSIVE);
793 set_slave_addr(sc, slave, 0);
794 error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
795 NULL, 0, byte, 1, NULL);
797 lockmgr(&sc->lk, LK_RELEASE);
802 * write command and read word in transaction.
805 ig4iic_smb_readw(device_t dev, u_char slave, char cmd, short *word)
807 ig4iic_softc_t *sc = device_get_softc(dev);
811 lockmgr(&sc->lk, LK_EXCLUSIVE);
813 set_slave_addr(sc, slave, 0);
814 if ((error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
815 NULL, 0, buf, 2, NULL)) == 0) {
816 *word = (u_char)buf[0] | ((u_char)buf[1] << 8);
819 lockmgr(&sc->lk, LK_RELEASE);
824 * write command and word and read word in transaction
827 ig4iic_smb_pcall(device_t dev, u_char slave, char cmd,
828 short sdata, short *rdata)
830 ig4iic_softc_t *sc = device_get_softc(dev);
835 lockmgr(&sc->lk, LK_EXCLUSIVE);
837 set_slave_addr(sc, slave, 0);
838 wbuf[0] = sdata & 0xFF;
839 wbuf[1] = sdata >> 8;
840 if ((error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
841 wbuf, 2, rbuf, 2, NULL)) == 0) {
842 *rdata = (u_char)rbuf[0] | ((u_char)rbuf[1] << 8);
845 lockmgr(&sc->lk, LK_RELEASE);
850 ig4iic_smb_bwrite(device_t dev, u_char slave, char cmd,
851 u_char wcount, char *buf)
853 ig4iic_softc_t *sc = device_get_softc(dev);
856 lockmgr(&sc->lk, LK_EXCLUSIVE);
858 set_slave_addr(sc, slave, 0);
859 error = smb_transaction(sc, cmd, 0,
860 buf, wcount, NULL, 0, NULL);
862 lockmgr(&sc->lk, LK_RELEASE);
867 ig4iic_smb_bread(device_t dev, u_char slave, char cmd,
868 u_char *countp_char, char *buf)
870 ig4iic_softc_t *sc = device_get_softc(dev);
871 int rcount = *countp_char;
874 lockmgr(&sc->lk, LK_EXCLUSIVE);
876 set_slave_addr(sc, slave, 0);
877 error = smb_transaction(sc, cmd, 0,
878 NULL, 0, buf, rcount, &rcount);
879 *countp_char = rcount;
881 lockmgr(&sc->lk, LK_RELEASE);
886 ig4iic_smb_trans(device_t dev, int slave, char cmd, int op,
887 char *wbuf, int wcount, char *rbuf, int rcount,
890 ig4iic_softc_t *sc = device_get_softc(dev);
893 lockmgr(&sc->lk, LK_EXCLUSIVE);
895 set_slave_addr(sc, slave, op);
896 error = smb_transaction(sc, cmd, op,
897 wbuf, wcount, rbuf, rcount, actualp);
899 lockmgr(&sc->lk, LK_RELEASE);
904 * Interrupt Operation
908 ig4iic_intr(void *cookie)
910 ig4iic_softc_t *sc = cookie;
913 lockmgr(&sc->lk, LK_EXCLUSIVE);
914 /* reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/
915 status = reg_read(sc, IG4_REG_I2C_STA);
916 while (status & IG4_STATUS_RX_NOTEMPTY) {
917 sc->rbuf[sc->rnext & IG4_RBUFMASK] =
918 (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
920 status = reg_read(sc, IG4_REG_I2C_STA);
922 reg_read(sc, IG4_REG_CLR_INTR);
924 lockmgr(&sc->lk, LK_RELEASE);
927 #define REGDUMP(sc, reg) \
928 device_printf(sc->dev, " %-23s %08x\n", #reg, reg_read(sc, reg))
932 ig4iic_dump(ig4iic_softc_t *sc)
934 device_printf(sc->dev, "ig4iic register dump:\n");
935 REGDUMP(sc, IG4_REG_CTL);
936 REGDUMP(sc, IG4_REG_TAR_ADD);
937 REGDUMP(sc, IG4_REG_SS_SCL_HCNT);
938 REGDUMP(sc, IG4_REG_SS_SCL_LCNT);
939 REGDUMP(sc, IG4_REG_FS_SCL_HCNT);
940 REGDUMP(sc, IG4_REG_FS_SCL_LCNT);
941 REGDUMP(sc, IG4_REG_INTR_STAT);
942 REGDUMP(sc, IG4_REG_INTR_MASK);
943 REGDUMP(sc, IG4_REG_RAW_INTR_STAT);
944 REGDUMP(sc, IG4_REG_RX_TL);
945 REGDUMP(sc, IG4_REG_TX_TL);
946 REGDUMP(sc, IG4_REG_I2C_EN);
947 REGDUMP(sc, IG4_REG_I2C_STA);
948 REGDUMP(sc, IG4_REG_TXFLR);
949 REGDUMP(sc, IG4_REG_RXFLR);
950 REGDUMP(sc, IG4_REG_SDA_HOLD);
951 REGDUMP(sc, IG4_REG_TX_ABRT_SOURCE);
952 REGDUMP(sc, IG4_REG_SLV_DATA_NACK);
953 REGDUMP(sc, IG4_REG_DMA_CTRL);
954 REGDUMP(sc, IG4_REG_DMA_TDLR);
955 REGDUMP(sc, IG4_REG_DMA_RDLR);
956 REGDUMP(sc, IG4_REG_SDA_SETUP);
957 REGDUMP(sc, IG4_REG_ENABLE_STATUS);
958 REGDUMP(sc, IG4_REG_COMP_PARAM1);
959 REGDUMP(sc, IG4_REG_COMP_VER);
960 REGDUMP(sc, IG4_REG_COMP_TYPE);
961 REGDUMP(sc, IG4_REG_CLK_PARMS);
962 REGDUMP(sc, IG4_REG_RESETS);
963 REGDUMP(sc, IG4_REG_GENERAL);
964 REGDUMP(sc, IG4_REG_SW_LTR_VALUE);
965 REGDUMP(sc, IG4_REG_AUTO_LTR_VALUE);
969 DRIVER_MODULE(smbus, ig4iic, smbus_driver, smbus_devclass, NULL, NULL);