Merge branch 'vendor/LIBARCHIVE'
[dragonfly.git] / sys / bus / smbus / ichiic / ig4_iic.c
1 /*
2  * Copyright (c) 2014 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
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
16  *    distribution.
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.
20  *
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
32  * SUCH DAMAGE.
33  */
34 /*
35  * Intel 4th generation mobile cpus integrated I2C device, smbus driver.
36  *
37  * See ig4_reg.h for datasheet reference and notes.
38  */
39
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>
45 #include <sys/lock.h>
46 #include <sys/mutex.h>
47 #include <sys/syslog.h>
48 #include <sys/bus.h>
49 #include <sys/sysctl.h>
50
51 #include <sys/rman.h>
52
53 #include <bus/pci/pcivar.h>
54 #include <bus/pci/pcireg.h>
55 #include <bus/smbus/smbconf.h>
56
57 #include "smbus_if.h"
58
59 #include "ig4_reg.h"
60 #include "ig4_var.h"
61
62 #define TRANS_NORMAL    1
63 #define TRANS_PCALL     2
64 #define TRANS_BLOCK     3
65
66 static void ig4iic_intr(void *cookie);
67 static void ig4iic_dump(ig4iic_softc_t *sc);
68
69 static int ig4_dump;
70 SYSCTL_INT(_debug, OID_AUTO, ig4_dump, CTLTYPE_INT | CTLFLAG_RW,
71            &ig4_dump, 0, "");
72
73 /*
74  * Low-level inline support functions
75  */
76 static __inline
77 void
78 reg_write(ig4iic_softc_t *sc, uint32_t reg, uint32_t value)
79 {
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);
83 }
84
85 static __inline
86 uint32_t
87 reg_read(ig4iic_softc_t *sc, uint32_t reg)
88 {
89         uint32_t value;
90
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);
94         return value;
95 }
96
97 /*
98  * Enable or disable the controller and wait for the controller to acknowledge
99  * the state change.
100  */
101 static
102 int
103 set_controller(ig4iic_softc_t *sc, uint32_t ctl)
104 {
105         int retry;
106         int error;
107         uint32_t v;
108
109         if (ctl & IG4_I2C_ENABLE) {
110                 reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET |
111                                                  IG4_INTR_RX_FULL);
112                 reg_read(sc, IG4_REG_CLR_INTR);
113         } else {
114                 reg_write(sc, IG4_REG_INTR_MASK, 0);
115         }
116         reg_write(sc, IG4_REG_I2C_EN, ctl);
117         error = SMB_ETIMEOUT;
118
119         for (retry = 100; retry > 0; --retry) {
120                 v = reg_read(sc, IG4_REG_ENABLE_STATUS);
121                 if (((v ^ ctl) & IG4_I2C_ENABLE) == 0) {
122                         error = 0;
123                         break;
124                 }
125                 tsleep(sc, 0, "i2cslv", 1);
126         }
127         return error;
128 }
129
130 /*
131  * Wait up to 25ms for the requested status using a 25uS polling loop.
132  */
133 static
134 int
135 wait_status(ig4iic_softc_t *sc, uint32_t status)
136 {
137         uint32_t v;
138         int error;
139         int txlvl = -1;
140         sysclock_t count;
141         sysclock_t limit;
142
143         error = SMB_ETIMEOUT;
144         count = sys_cputimer->count();
145         limit = sys_cputimer->freq / 40;
146
147         for (;;) {
148                 /*
149                  * Check requested status
150                  */
151                 v = reg_read(sc, IG4_REG_I2C_STA);
152                 if (v & status) {
153                         error = 0;
154                         break;
155                 }
156
157                 /*
158                  * When waiting for receive data break-out if the interrupt
159                  * loaded data into the FIFO.
160                  */
161                 if (status & IG4_STATUS_RX_NOTEMPTY) {
162                         if (sc->rpos != sc->rnext) {
163                                 error = 0;
164                                 break;
165                         }
166                 }
167
168                 /*
169                  * When waiting for the transmit FIFO to become empty,
170                  * reset the timeout if we see a change in the transmit
171                  * FIFO level as progress is being made.
172                  */
173                 if (status & IG4_STATUS_TX_EMPTY) {
174                         v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK;
175                         if (txlvl != v) {
176                                 txlvl = v;
177                                 count = sys_cputimer->count();
178                         }
179                 }
180
181                 /*
182                  * Stop if we've run out of time.
183                  */
184                 if (sys_cputimer->count() - count > limit)
185                         break;
186
187                 /*
188                  * When waiting for receive data let the interrupt do its
189                  * work, otherwise poll with the lock held.
190                  */
191                 if (status & IG4_STATUS_RX_NOTEMPTY) {
192                         lksleep(sc, &sc->lk, 0, "i2cwait", (hz + 99) / 100);
193                 } else {
194                         DELAY(25);
195                 }
196         }
197
198         return error;
199 }
200
201 /*
202  * Read I2C data.  The data might have already been read by
203  * the interrupt code, otherwise it is sitting in the data
204  * register.
205  */
206 static
207 uint8_t
208 data_read(ig4iic_softc_t *sc)
209 {
210         uint8_t c;
211
212         if (sc->rpos == sc->rnext) {
213                 c = (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
214         } else {
215                 c = sc->rbuf[sc->rpos & IG4_RBUFMASK];
216                 ++sc->rpos;
217         }
218         return c;
219 }
220
221 /*
222  * Set the slave address.  The controller must be disabled when
223  * changing the address.
224  *
225  * This operation does not issue anything to the I2C bus but sets
226  * the target address for when the controller later issues a START.
227  */
228 static
229 void
230 set_slave_addr(ig4iic_softc_t *sc, uint8_t slave, int trans_op)
231 {
232         uint32_t tar;
233         uint32_t ctl;
234         int use_10bit;
235
236         use_10bit = sc->use_10bit;
237         if (trans_op & SMB_TRANS_7BIT)
238                 use_10bit = 0;
239         if (trans_op & SMB_TRANS_10BIT)
240                 use_10bit = 1;
241
242         if (sc->slave_valid && sc->last_slave == slave &&
243             sc->use_10bit == use_10bit) {
244                 return;
245         }
246         sc->use_10bit = use_10bit;
247
248         /*
249          * Wait for TXFIFO to drain before disabling the controller.
250          *
251          * If a write message has not been completed it's really a
252          * programming error, but for now in that case issue an extra
253          * byte + STOP.
254          *
255          * If a read message has not been completed it's also a programming
256          * error, for now just ignore it.
257          */
258         wait_status(sc, IG4_STATUS_TX_NOTFULL);
259         if (sc->write_started) {
260                 reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_STOP);
261                 sc->write_started = 0;
262         }
263         if (sc->read_started)
264                 sc->read_started = 0;
265         wait_status(sc, IG4_STATUS_TX_EMPTY);
266
267         set_controller(sc, 0);
268         ctl = reg_read(sc, IG4_REG_CTL);
269         ctl &= ~IG4_CTL_10BIT;
270         ctl |= IG4_CTL_RESTARTEN;
271
272         tar = slave;
273         if (sc->use_10bit) {
274                 tar |= IG4_TAR_10BIT;
275                 ctl |= IG4_CTL_10BIT;
276         }
277         reg_write(sc, IG4_REG_CTL, ctl);
278         reg_write(sc, IG4_REG_TAR_ADD, tar);
279         set_controller(sc, IG4_I2C_ENABLE);
280         sc->slave_valid = 1;
281         sc->last_slave = slave;
282 }
283
284 /*
285  * Issue START with byte command, possible count, and a variable length
286  * read or write buffer, then possible turn-around read.  The read also
287  * has a possible count received.
288  *
289  * For SMBUS -
290  *
291  * Quick:               START+ADDR+RD/WR STOP
292  *
293  * Normal:              START+ADDR+WR CMD DATA..DATA STOP
294  *
295  *                      START+ADDR+RD CMD
296  *                      RESTART+ADDR RDATA..RDATA STOP
297  *                      (can also be used for I2C transactions)
298  *
299  * Process Call:        START+ADDR+WR CMD DATAL DATAH
300  *                      RESTART+ADDR+RD RDATAL RDATAH STOP
301  *
302  * Block:               START+ADDR+RD CMD
303  *                      RESTART+ADDR+RD RCOUNT DATA... STOP
304  *
305  *                      START+ADDR+WR CMD
306  *                      RESTART+ADDR+WR WCOUNT DATA... STOP
307  *
308  * For I2C - basically, no *COUNT fields, possibly no *CMD field.  If the
309  *           sender needs to issue a 2-byte command it will incorporate it
310  *           into the write buffer and also set NOCMD.
311  *
312  * Generally speaking, the START+ADDR / RESTART+ADDR is handled automatically
313  * by the controller at the beginning of a command sequence or on a data
314  * direction turn-around, and we only need to tell it when to issue the STOP.
315  */
316 static int
317 smb_transaction(ig4iic_softc_t *sc, char cmd, int op,
318                 char *wbuf, int wcount, char *rbuf, int rcount, int *actualp)
319 {
320         int error;
321         int unit;
322         uint32_t last;
323
324         /*
325          * Debugging - dump registers
326          */
327         if (ig4_dump) {
328                 unit = device_get_unit(sc->dev);
329                 if (ig4_dump & (1 << unit)) {
330                         ig4_dump &= ~(1 << unit);
331                         ig4iic_dump(sc);
332                 }
333         }
334
335         /*
336          * Issue START or RESTART with next data byte, clear any previous
337          * abort condition that may have been holding the txfifo in reset.
338          */
339         last = IG4_DATA_RESTART;
340         reg_read(sc, IG4_REG_CLR_TX_ABORT);
341         if (actualp)
342                 *actualp = 0;
343
344         /*
345          * Issue command if not told otherwise (smbus).
346          */
347         if ((op & SMB_TRANS_NOCMD) == 0) {
348                 error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
349                 if (error)
350                         goto done;
351                 last |= (u_char)cmd;
352                 if (wcount == 0 && rcount == 0 && (op & SMB_TRANS_NOSTOP) == 0)
353                         last |= IG4_DATA_STOP;
354                 reg_write(sc, IG4_REG_DATA_CMD, last);
355                 last = 0;
356         }
357
358         /*
359          * Clean out any previously received data.
360          */
361         if (sc->rpos != sc->rnext &&
362             (op & SMB_TRANS_NOREPORT) == 0) {
363                 device_printf(sc->dev,
364                               "discarding %d bytes of spurious data\n",
365                               sc->rnext - sc->rpos);
366         }
367         sc->rpos = 0;
368         sc->rnext = 0;
369
370         /*
371          * If writing and not told otherwise, issue the write count (smbus).
372          */
373         if (wcount && (op & SMB_TRANS_NOCNT) == 0) {
374                 error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
375                 if (error)
376                         goto done;
377                 last |= (u_char)cmd;
378                 reg_write(sc, IG4_REG_DATA_CMD, last);
379                 last = 0;
380         }
381
382         /*
383          * Bulk write (i2c)
384          */
385         while (wcount) {
386                 error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
387                 if (error)
388                         goto done;
389                 last |= (u_char)*wbuf;
390                 if (wcount == 1 && rcount == 0 && (op & SMB_TRANS_NOSTOP) == 0)
391                         last |= IG4_DATA_STOP;
392                 reg_write(sc, IG4_REG_DATA_CMD, last);
393                 --wcount;
394                 ++wbuf;
395                 last = 0;
396         }
397
398         /*
399          * Issue reads to xmit FIFO (strange, I know) to tell the controller
400          * to clock in data.  At the moment just issue one read ahead to
401          * pipeline the incoming data.
402          *
403          * NOTE: In the case of NOCMD and wcount == 0 we still issue a
404          *       RESTART here, even if the data direction has not changed
405          *       from the previous CHAINing call.  This we force the RESTART.
406          *       (A new START is issued automatically by the controller in
407          *       the other nominal cases such as a data direction change or
408          *       a previous STOP was issued).
409          *
410          * If this will be the last byte read we must also issue the STOP
411          * at the end of the read.
412          */
413         if (rcount) {
414                 last = IG4_DATA_RESTART | IG4_DATA_COMMAND_RD;
415                 if (rcount == 1 &&
416                     (op & (SMB_TRANS_NOSTOP | SMB_TRANS_NOCNT)) ==
417                     SMB_TRANS_NOCNT) {
418                         last |= IG4_DATA_STOP;
419                 }
420                 reg_write(sc, IG4_REG_DATA_CMD, last);
421                 last = IG4_DATA_COMMAND_RD;
422         }
423
424         /*
425          * Bulk read (i2c) and count field handling (smbus)
426          */
427         while (rcount) {
428                 /*
429                  * Maintain a pipeline by queueing the allowance for the next
430                  * read before waiting for the current read.
431                  */
432                 if (rcount > 1) {
433                         if (op & SMB_TRANS_NOCNT)
434                                 last = (rcount == 2) ? IG4_DATA_STOP : 0;
435                         else
436                                 last = 0;
437                         reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD |
438                                                         last);
439                 }
440                 error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY);
441                 if (error) {
442                         if ((op & SMB_TRANS_NOREPORT) == 0) {
443                                 device_printf(sc->dev,
444                                               "rx timeout addr 0x%02x\n",
445                                               sc->last_slave);
446                         }
447                         goto done;
448                 }
449                 last = data_read(sc);
450
451                 if (op & SMB_TRANS_NOCNT) {
452                         *rbuf = (u_char)last;
453                         ++rbuf;
454                         --rcount;
455                         if (actualp)
456                                 ++*actualp;
457                 } else {
458                         /*
459                          * Handle count field (smbus), which is not part of
460                          * the rcount'ed buffer.  The first read data in a
461                          * bulk transfer is the count.
462                          *
463                          * XXX if rcount is loaded as 0 how do I generate a
464                          *     STOP now without issuing another RD or WR?
465                          */
466                         if (rcount > (u_char)last)
467                                 rcount = (u_char)last;
468                         op |= SMB_TRANS_NOCNT;
469                 }
470         }
471         error = 0;
472 done:
473         /* XXX wait for xmit buffer to become empty */
474         last = reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
475
476         return error;
477 }
478
479 /*
480  *                              SMBUS API FUNCTIONS
481  *
482  * Called from ig4iic_pci_attach/detach()
483  */
484 int
485 ig4iic_attach(ig4iic_softc_t *sc)
486 {
487         int error;
488         uint32_t v;
489
490         lockmgr(&sc->lk, LK_EXCLUSIVE);
491
492         v = reg_read(sc, IG4_REG_COMP_TYPE);
493         kprintf("type %08x", v);
494         v = reg_read(sc, IG4_REG_COMP_PARAM1);
495         kprintf(" params %08x", v);
496         v = reg_read(sc, IG4_REG_GENERAL);
497         kprintf(" general %08x", v);
498         if ((v & IG4_GENERAL_SWMODE) == 0) {
499                 v |= IG4_GENERAL_SWMODE;
500                 reg_write(sc, IG4_REG_GENERAL, v);
501                 v = reg_read(sc, IG4_REG_GENERAL);
502                 kprintf(" (updated %08x)", v);
503         }
504
505         v = reg_read(sc, IG4_REG_SW_LTR_VALUE);
506         kprintf(" swltr %08x", v);
507         v = reg_read(sc, IG4_REG_AUTO_LTR_VALUE);
508         kprintf(" autoltr %08x", v);
509
510         v = reg_read(sc, IG4_REG_COMP_VER);
511         kprintf(" version %08x\n", v);
512         if (v != IG4_COMP_VER) {
513                 error = ENXIO;
514                 goto done;
515         }
516 #if 1
517         v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
518         kprintf("SS_SCL_HCNT=%08x", v);
519         v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
520         kprintf(" LCNT=%08x", v);
521         v = reg_read(sc, IG4_REG_FS_SCL_HCNT);
522         kprintf(" FS_SCL_HCNT=%08x", v);
523         v = reg_read(sc, IG4_REG_FS_SCL_LCNT);
524         kprintf(" LCNT=%08x\n", v);
525         v = reg_read(sc, IG4_REG_SDA_HOLD);
526         kprintf("HOLD        %08x\n", v);
527
528         v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
529         reg_write(sc, IG4_REG_FS_SCL_HCNT, v);
530         v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
531         reg_write(sc, IG4_REG_FS_SCL_LCNT, v);
532 #endif
533         /*
534          * Program based on a 25000 Hz clock.  This is a bit of a
535          * hack (obviously).  The defaults are 400 and 470 for standard
536          * and 60 and 130 for fast.  The defaults for standard fail
537          * utterly (presumably cause an abort) because the clock time
538          * is ~18.8ms by default.  This brings it down to ~4ms (for now).
539          */
540         reg_write(sc, IG4_REG_SS_SCL_HCNT, 100);
541         reg_write(sc, IG4_REG_SS_SCL_LCNT, 125);
542         reg_write(sc, IG4_REG_FS_SCL_HCNT, 100);
543         reg_write(sc, IG4_REG_FS_SCL_LCNT, 125);
544
545         /*
546          * Use a threshold of 1 so we get interrupted on each character,
547          * allowing us to use lksleep() in our poll code.  Not perfect
548          * but this is better than using DELAY() for receiving data.
549          */
550         reg_write(sc, IG4_REG_RX_TL, 1);
551
552         reg_write(sc, IG4_REG_CTL,
553                   IG4_CTL_MASTER |
554                   IG4_CTL_SLAVE_DISABLE |
555                   IG4_CTL_RESTARTEN |
556                   IG4_CTL_SPEED_STD);
557
558         sc->smb = device_add_child(sc->dev, "smbus", -1);
559         if (sc->smb == NULL) {
560                 device_printf(sc->dev, "smbus driver not found\n");
561                 error = ENXIO;
562                 goto done;
563         }
564
565 #if 0
566         /*
567          * Don't do this, it blows up the PCI config
568          */
569         reg_write(sc, IG4_REG_RESETS, IG4_RESETS_ASSERT);
570         reg_write(sc, IG4_REG_RESETS, IG4_RESETS_DEASSERT);
571 #endif
572
573         /*
574          * Interrupt on STOP detect or receive character ready
575          */
576         if (set_controller(sc, 0))
577                 device_printf(sc->dev, "controller error during attach-1\n");
578         if (set_controller(sc, IG4_I2C_ENABLE))
579                 device_printf(sc->dev, "controller error during attach-2\n");
580         error = bus_setup_intr(sc->dev, sc->intr_res, 0,
581                                ig4iic_intr, sc, &sc->intr_handle, NULL);
582         if (error) {
583                 device_printf(sc->dev,
584                               "Unable to setup irq: error %d\n", error);
585                 goto done;
586         }
587
588         /* Attach us to the smbus */
589         lockmgr(&sc->lk, LK_RELEASE);
590         error = bus_generic_attach(sc->dev);
591         lockmgr(&sc->lk, LK_EXCLUSIVE);
592         if (error) {
593                 device_printf(sc->dev,
594                               "failed to attach child: error %d\n", error);
595                 goto done;
596         }
597         sc->generic_attached = 1;
598
599 done:
600         lockmgr(&sc->lk, LK_RELEASE);
601         return error;
602 }
603
604 int
605 ig4iic_detach(ig4iic_softc_t *sc)
606 {
607         int error;
608
609         lockmgr(&sc->lk, LK_EXCLUSIVE);
610
611         reg_write(sc, IG4_REG_INTR_MASK, 0);
612         set_controller(sc, 0);
613
614         if (sc->generic_attached) {
615                 error = bus_generic_detach(sc->dev);
616                 if (error)
617                         goto done;
618                 sc->generic_attached = 0;
619         }
620         if (sc->smb) {
621                 device_delete_child(sc->dev, sc->smb);
622                 sc->smb = NULL;
623         }
624         if (sc->intr_handle) {
625                 bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle);
626                 sc->intr_handle = NULL;
627         }
628
629         error = 0;
630 done:
631         lockmgr(&sc->lk, LK_RELEASE);
632         return error;
633 }
634
635 int
636 ig4iic_smb_callback(device_t dev, int index, void *data)
637 {
638         ig4iic_softc_t *sc = device_get_softc(dev);
639         int error;
640
641         lockmgr(&sc->lk, LK_EXCLUSIVE);
642
643         switch (index) {
644         case SMB_REQUEST_BUS:
645                 error = 0;
646                 break;
647         case SMB_RELEASE_BUS:
648                 error = 0;
649                 break;
650         default:
651                 error = SMB_EABORT;
652                 break;
653         }
654
655         lockmgr(&sc->lk, LK_RELEASE);
656
657         return error;
658 }
659
660 /*
661  * Quick command.  i.e. START + cmd + R/W + STOP and no data.  It is
662  * unclear to me how I could implement this with the intel i2c controller
663  * because the controler sends STARTs and STOPs automatically with data.
664  */
665 int
666 ig4iic_smb_quick(device_t dev, u_char slave, int how)
667 {
668         ig4iic_softc_t *sc = device_get_softc(dev);
669         int error;
670
671         lockmgr(&sc->lk, LK_EXCLUSIVE);
672
673         switch (how) {
674         case SMB_QREAD:
675                 error = SMB_ENOTSUPP;
676                 break;
677         case SMB_QWRITE:
678                 error = SMB_ENOTSUPP;
679                 break;
680         default:
681                 error = SMB_ENOTSUPP;
682                 break;
683         }
684         lockmgr(&sc->lk, LK_RELEASE);
685
686         return error;
687 }
688
689 /*
690  * Incremental send byte without stop (?).  It is unclear why the slave
691  * address is specified if this presumably is used in combination with
692  * ig4iic_smb_quick().
693  *
694  * (Also, how would this work anyway?  Issue the last byte with writeb()?)
695  */
696 int
697 ig4iic_smb_sendb(device_t dev, u_char slave, char byte)
698 {
699         ig4iic_softc_t *sc = device_get_softc(dev);
700         uint32_t cmd;
701         int error;
702
703         lockmgr(&sc->lk, LK_EXCLUSIVE);
704
705         set_slave_addr(sc, slave, 0);
706         cmd = byte;
707         if (wait_status(sc, IG4_STATUS_TX_NOTFULL) == 0) {
708                 reg_write(sc, IG4_REG_DATA_CMD, cmd);
709                 error = 0;
710         } else {
711                 error = SMB_ETIMEOUT;
712         }
713
714         lockmgr(&sc->lk, LK_RELEASE);
715         return error;
716 }
717
718 /*
719  * Incremental receive byte without stop (?).  It is unclear why the slave
720  * address is specified if this presumably is used in combination with
721  * ig4iic_smb_quick().
722  */
723 int
724 ig4iic_smb_recvb(device_t dev, u_char slave, char *byte)
725 {
726         ig4iic_softc_t *sc = device_get_softc(dev);
727         int error;
728
729         lockmgr(&sc->lk, LK_EXCLUSIVE);
730
731         set_slave_addr(sc, slave, 0);
732         reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD);
733         if (wait_status(sc, IG4_STATUS_RX_NOTEMPTY) == 0) {
734                 *byte = data_read(sc);
735                 error = 0;
736         } else {
737                 *byte = 0;
738                 error = SMB_ETIMEOUT;
739         }
740
741         lockmgr(&sc->lk, LK_RELEASE);
742         return error;
743 }
744
745 /*
746  * Write command and single byte in transaction.
747  */
748 int
749 ig4iic_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
750 {
751         ig4iic_softc_t *sc = device_get_softc(dev);
752         int error;
753
754         lockmgr(&sc->lk, LK_EXCLUSIVE);
755
756         set_slave_addr(sc, slave, 0);
757         error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
758                                 &byte, 1, NULL, 0, NULL);
759
760         lockmgr(&sc->lk, LK_RELEASE);
761         return error;
762 }
763
764 /*
765  * Write command and single word in transaction.
766  */
767 int
768 ig4iic_smb_writew(device_t dev, u_char slave, char cmd, short word)
769 {
770         ig4iic_softc_t *sc = device_get_softc(dev);
771         char buf[2];
772         int error;
773
774         lockmgr(&sc->lk, LK_EXCLUSIVE);
775
776         set_slave_addr(sc, slave, 0);
777         buf[0] = word & 0xFF;
778         buf[1] = word >> 8;
779         error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
780                                 buf, 2, NULL, 0, NULL);
781
782         lockmgr(&sc->lk, LK_RELEASE);
783         return error;
784 }
785
786 /*
787  * write command and read single byte in transaction.
788  */
789 int
790 ig4iic_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
791 {
792         ig4iic_softc_t *sc = device_get_softc(dev);
793         int error;
794
795         lockmgr(&sc->lk, LK_EXCLUSIVE);
796
797         set_slave_addr(sc, slave, 0);
798         error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
799                                 NULL, 0, byte, 1, NULL);
800
801         lockmgr(&sc->lk, LK_RELEASE);
802         return error;
803 }
804
805 /*
806  * write command and read word in transaction.
807  */
808 int
809 ig4iic_smb_readw(device_t dev, u_char slave, char cmd, short *word)
810 {
811         ig4iic_softc_t *sc = device_get_softc(dev);
812         char buf[2];
813         int error;
814
815         lockmgr(&sc->lk, LK_EXCLUSIVE);
816
817         set_slave_addr(sc, slave, 0);
818         if ((error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
819                                      NULL, 0, buf, 2, NULL)) == 0) {
820                 *word = (u_char)buf[0] | ((u_char)buf[1] << 8);
821         }
822
823         lockmgr(&sc->lk, LK_RELEASE);
824         return error;
825 }
826
827 /*
828  * write command and word and read word in transaction
829  */
830 int
831 ig4iic_smb_pcall(device_t dev, u_char slave, char cmd,
832                  short sdata, short *rdata)
833 {
834         ig4iic_softc_t *sc = device_get_softc(dev);
835         char rbuf[2];
836         char wbuf[2];
837         int error;
838
839         lockmgr(&sc->lk, LK_EXCLUSIVE);
840
841         set_slave_addr(sc, slave, 0);
842         wbuf[0] = sdata & 0xFF;
843         wbuf[1] = sdata >> 8;
844         if ((error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
845                                      wbuf, 2, rbuf, 2, NULL)) == 0) {
846                 *rdata = (u_char)rbuf[0] | ((u_char)rbuf[1] << 8);
847         }
848
849         lockmgr(&sc->lk, LK_RELEASE);
850         return error;
851 }
852
853 int
854 ig4iic_smb_bwrite(device_t dev, u_char slave, char cmd,
855                   u_char wcount, char *buf)
856 {
857         ig4iic_softc_t *sc = device_get_softc(dev);
858         int error;
859
860         lockmgr(&sc->lk, LK_EXCLUSIVE);
861
862         set_slave_addr(sc, slave, 0);
863         error = smb_transaction(sc, cmd, 0,
864                                 buf, wcount, NULL, 0, NULL);
865
866         lockmgr(&sc->lk, LK_RELEASE);
867         return error;
868 }
869
870 int
871 ig4iic_smb_bread(device_t dev, u_char slave, char cmd,
872                  u_char *countp_char, char *buf)
873 {
874         ig4iic_softc_t *sc = device_get_softc(dev);
875         int rcount = *countp_char;
876         int error;
877
878         lockmgr(&sc->lk, LK_EXCLUSIVE);
879
880         set_slave_addr(sc, slave, 0);
881         error = smb_transaction(sc, cmd, 0,
882                                 NULL, 0, buf, rcount, &rcount);
883         *countp_char = rcount;
884
885         lockmgr(&sc->lk, LK_RELEASE);
886         return error;
887 }
888
889 int
890 ig4iic_smb_trans(device_t dev, int slave, char cmd, int op,
891                  char *wbuf, int wcount, char *rbuf, int rcount,
892                  int *actualp)
893 {
894         ig4iic_softc_t *sc = device_get_softc(dev);
895         int error;
896
897         lockmgr(&sc->lk, LK_EXCLUSIVE);
898
899         set_slave_addr(sc, slave, op);
900         error = smb_transaction(sc, cmd, op,
901                                 wbuf, wcount, rbuf, rcount, actualp);
902
903         lockmgr(&sc->lk, LK_RELEASE);
904         return error;
905 }
906
907 /*
908  * Interrupt Operation
909  */
910 static
911 void
912 ig4iic_intr(void *cookie)
913 {
914         ig4iic_softc_t *sc = cookie;
915         uint32_t status;
916
917         lockmgr(&sc->lk, LK_EXCLUSIVE);
918 /*      reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/
919         reg_read(sc, IG4_REG_CLR_INTR);
920         status = reg_read(sc, IG4_REG_I2C_STA);
921         while (status & IG4_STATUS_RX_NOTEMPTY) {
922                 sc->rbuf[sc->rnext & IG4_RBUFMASK] =
923                     (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
924                 ++sc->rnext;
925                 status = reg_read(sc, IG4_REG_I2C_STA);
926         }
927         wakeup(sc);
928         lockmgr(&sc->lk, LK_RELEASE);
929 }
930
931 #define REGDUMP(sc, reg)        \
932         device_printf(sc->dev, "  %-23s %08x\n", #reg, reg_read(sc, reg))
933
934 static
935 void
936 ig4iic_dump(ig4iic_softc_t *sc)
937 {
938         device_printf(sc->dev, "ig4iic register dump:\n");
939         REGDUMP(sc, IG4_REG_CTL);
940         REGDUMP(sc, IG4_REG_TAR_ADD);
941         REGDUMP(sc, IG4_REG_SS_SCL_HCNT);
942         REGDUMP(sc, IG4_REG_SS_SCL_LCNT);
943         REGDUMP(sc, IG4_REG_FS_SCL_HCNT);
944         REGDUMP(sc, IG4_REG_FS_SCL_LCNT);
945         REGDUMP(sc, IG4_REG_INTR_STAT);
946         REGDUMP(sc, IG4_REG_INTR_MASK);
947         REGDUMP(sc, IG4_REG_RAW_INTR_STAT);
948         REGDUMP(sc, IG4_REG_RX_TL);
949         REGDUMP(sc, IG4_REG_TX_TL);
950         REGDUMP(sc, IG4_REG_I2C_EN);
951         REGDUMP(sc, IG4_REG_I2C_STA);
952         REGDUMP(sc, IG4_REG_TXFLR);
953         REGDUMP(sc, IG4_REG_RXFLR);
954         REGDUMP(sc, IG4_REG_SDA_HOLD);
955         REGDUMP(sc, IG4_REG_TX_ABRT_SOURCE);
956         REGDUMP(sc, IG4_REG_SLV_DATA_NACK);
957         REGDUMP(sc, IG4_REG_DMA_CTRL);
958         REGDUMP(sc, IG4_REG_DMA_TDLR);
959         REGDUMP(sc, IG4_REG_DMA_RDLR);
960         REGDUMP(sc, IG4_REG_SDA_SETUP);
961         REGDUMP(sc, IG4_REG_ENABLE_STATUS);
962         REGDUMP(sc, IG4_REG_COMP_PARAM1);
963         REGDUMP(sc, IG4_REG_COMP_VER);
964         REGDUMP(sc, IG4_REG_COMP_TYPE);
965         REGDUMP(sc, IG4_REG_CLK_PARMS);
966         REGDUMP(sc, IG4_REG_RESETS);
967         REGDUMP(sc, IG4_REG_GENERAL);
968         REGDUMP(sc, IG4_REG_SW_LTR_VALUE);
969         REGDUMP(sc, IG4_REG_AUTO_LTR_VALUE);
970 }
971 #undef REGDUMP
972
973 DRIVER_MODULE(smbus, ig4iic, smbus_driver, smbus_devclass, NULL, NULL);