xref: /dragonfly/sys/bus/smbus/ichiic/ig4_iic.c (revision 279dd846)
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 	reg_write(sc, IG4_REG_I2C_EN, ctl);
110 	error = SMB_ETIMEOUT;
111 
112 	for (retry = 100; retry > 0; --retry) {
113 		v = reg_read(sc, IG4_REG_ENABLE_STATUS);
114 		if (((v ^ ctl) & IG4_I2C_ENABLE) == 0) {
115 			error = 0;
116 			break;
117 		}
118 		tsleep(sc, 0, "i2cslv", 1);
119 	}
120 	return error;
121 }
122 
123 /*
124  * Wait up to 25ms for the requested status using a 25uS polling loop.
125  */
126 static
127 int
128 wait_status(ig4iic_softc_t *sc, uint32_t status)
129 {
130 	uint32_t v;
131 	int error;
132 	int txlvl = -1;
133 	sysclock_t count;
134 	sysclock_t limit;
135 
136 	error = SMB_ETIMEOUT;
137 	count = sys_cputimer->count();
138 	limit = sys_cputimer->freq / 40;
139 
140 	for (;;) {
141 		/*
142 		 * Check requested status
143 		 */
144 		v = reg_read(sc, IG4_REG_I2C_STA);
145 		if (v & status) {
146 			error = 0;
147 			break;
148 		}
149 
150 		/*
151 		 * When waiting for receive data break-out if the interrupt
152 		 * loaded data into the FIFO.
153 		 */
154 		if (status & IG4_STATUS_RX_NOTEMPTY) {
155 			if (sc->rpos != sc->rnext) {
156 				error = 0;
157 				break;
158 			}
159 		}
160 
161 		/*
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.
165 		 */
166 		if (status & IG4_STATUS_TX_EMPTY) {
167 			v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK;
168 			if (txlvl != v) {
169 				txlvl = v;
170 				count = sys_cputimer->count();
171 			}
172 		}
173 
174 		/*
175 		 * Stop if we've run out of time.
176 		 */
177 		if (sys_cputimer->count() - count > limit)
178 			break;
179 
180 		/*
181 		 * When waiting for receive data let the interrupt do its
182 		 * work, otherwise poll with the lock held.
183 		 */
184 		if (status & IG4_STATUS_RX_NOTEMPTY) {
185 			lksleep(sc, &sc->lk, 0, "i2cwait", (hz + 99) / 100);
186 		} else {
187 			DELAY(25);
188 		}
189 	}
190 
191 	return error;
192 }
193 
194 /*
195  * Read I2C data.  The data might have already been read by
196  * the interrupt code, otherwise it is sitting in the data
197  * register.
198  */
199 static
200 uint8_t
201 data_read(ig4iic_softc_t *sc)
202 {
203 	uint8_t c;
204 
205 	if (sc->rpos == sc->rnext) {
206 		c = (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
207 	} else {
208 		c = sc->rbuf[sc->rpos & IG4_RBUFMASK];
209 		++sc->rpos;
210 	}
211 	return c;
212 }
213 
214 /*
215  * Set the slave address.  The controller must be disabled when
216  * changing the address.
217  *
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.
220  */
221 static
222 void
223 set_slave_addr(ig4iic_softc_t *sc, uint8_t slave, int trans_op)
224 {
225 	uint32_t tar;
226 	uint32_t ctl;
227 	int use_10bit;
228 
229 	use_10bit = sc->use_10bit;
230 	if (trans_op & SMB_TRANS_7BIT)
231 		use_10bit = 0;
232 	if (trans_op & SMB_TRANS_10BIT)
233 		use_10bit = 1;
234 
235 	if (sc->slave_valid && sc->last_slave == slave &&
236 	    sc->use_10bit == use_10bit) {
237 		return;
238 	}
239 	sc->use_10bit = use_10bit;
240 
241 	/*
242 	 * Wait for TXFIFO to drain before disabling the controller.
243 	 *
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
246 	 * byte + STOP.
247 	 *
248 	 * If a read message has not been completed it's also a programming
249 	 * error, for now just ignore it.
250 	 */
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;
255 	}
256 	if (sc->read_started)
257 		sc->read_started = 0;
258 	wait_status(sc, IG4_STATUS_TX_EMPTY);
259 
260 	set_controller(sc, 0);
261 	ctl = reg_read(sc, IG4_REG_CTL);
262 	ctl &= ~IG4_CTL_10BIT;
263 	ctl |= IG4_CTL_RESTARTEN;
264 
265 	tar = slave;
266 	if (sc->use_10bit) {
267 		tar |= IG4_TAR_10BIT;
268 		ctl |= IG4_CTL_10BIT;
269 	}
270 	reg_write(sc, IG4_REG_CTL, ctl);
271 	reg_write(sc, IG4_REG_TAR_ADD, tar);
272 	set_controller(sc, IG4_I2C_ENABLE);
273 	sc->slave_valid = 1;
274 	sc->last_slave = slave;
275 }
276 
277 /*
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.
281  *
282  * For SMBUS -
283  *
284  * Quick:		START+ADDR+RD/WR STOP
285  *
286  * Normal:		START+ADDR+WR CMD DATA..DATA STOP
287  *
288  *			START+ADDR+RD CMD
289  *			RESTART+ADDR RDATA..RDATA STOP
290  *			(can also be used for I2C transactions)
291  *
292  * Process Call:	START+ADDR+WR CMD DATAL DATAH
293  *			RESTART+ADDR+RD RDATAL RDATAH STOP
294  *
295  * Block:		START+ADDR+RD CMD
296  *			RESTART+ADDR+RD RCOUNT DATA... STOP
297  *
298  * 			START+ADDR+WR CMD
299  *			RESTART+ADDR+WR WCOUNT DATA... STOP
300  *
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.
304  *
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.
308  */
309 static int
310 smb_transaction(ig4iic_softc_t *sc, char cmd, int op,
311 		char *wbuf, int wcount, char *rbuf, int rcount, int *actualp)
312 {
313 	int error;
314 	int unit;
315 	uint32_t last;
316 
317 	/*
318 	 * Debugging - dump registers
319 	 */
320 	if (ig4_dump) {
321 		unit = device_get_unit(sc->dev);
322 		if (ig4_dump & (1 << unit)) {
323 			ig4_dump &= ~(1 << unit);
324 			ig4iic_dump(sc);
325 		}
326 	}
327 
328 	/*
329 	 * Issue START or RESTART with next data byte, clear any previous
330 	 * abort condition that may have been holding the txfifo in reset.
331 	 */
332 	last = IG4_DATA_RESTART;
333 	reg_read(sc, IG4_REG_CLR_TX_ABORT);
334 	if (actualp)
335 		*actualp = 0;
336 
337 	/*
338 	 * Issue command if not told otherwise (smbus).
339 	 */
340 	if ((op & SMB_TRANS_NOCMD) == 0) {
341 		error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
342 		if (error)
343 			goto done;
344 		last |= (u_char)cmd;
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);
348 		last = 0;
349 	}
350 
351 	/*
352 	 * Clean out any previously received data.
353 	 */
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);
359 	}
360 	sc->rpos = 0;
361 	sc->rnext = 0;
362 
363 	/*
364 	 * If writing and not told otherwise, issue the write count (smbus).
365 	 */
366 	if (wcount && (op & SMB_TRANS_NOCNT) == 0) {
367 		error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
368 		if (error)
369 			goto done;
370 		last |= (u_char)cmd;
371 		reg_write(sc, IG4_REG_DATA_CMD, last);
372 		last = 0;
373 	}
374 
375 	/*
376 	 * Bulk write (i2c)
377 	 */
378 	while (wcount) {
379 		error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
380 		if (error)
381 			goto done;
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);
386 		--wcount;
387 		++wbuf;
388 		last = 0;
389 	}
390 
391 	/*
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.
395 	 *
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).
402 	 *
403 	 * If this will be the last byte read we must also issue the STOP
404 	 * at the end of the read.
405 	 */
406 	if (rcount) {
407 		last = IG4_DATA_RESTART | IG4_DATA_COMMAND_RD;
408 		if (rcount == 1 &&
409 		    (op & (SMB_TRANS_NOSTOP | SMB_TRANS_NOCNT)) ==
410 		    SMB_TRANS_NOCNT) {
411 			last |= IG4_DATA_STOP;
412 		}
413 		reg_write(sc, IG4_REG_DATA_CMD, last);
414 		last = IG4_DATA_COMMAND_RD;
415 	}
416 
417 	/*
418 	 * Bulk read (i2c) and count field handling (smbus)
419 	 */
420 	while (rcount) {
421 		/*
422 		 * Maintain a pipeline by queueing the allowance for the next
423 		 * read before waiting for the current read.
424 		 */
425 		if (rcount > 1) {
426 			if (op & SMB_TRANS_NOCNT)
427 				last = (rcount == 2) ? IG4_DATA_STOP : 0;
428 			else
429 				last = 0;
430 			reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD |
431 							last);
432 		}
433 		error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY);
434 		if (error) {
435 			if ((op & SMB_TRANS_NOREPORT) == 0) {
436 				device_printf(sc->dev,
437 					      "rx timeout addr 0x%02x\n",
438 					      sc->last_slave);
439 			}
440 			goto done;
441 		}
442 		last = data_read(sc);
443 
444 		if (op & SMB_TRANS_NOCNT) {
445 			*rbuf = (u_char)last;
446 			++rbuf;
447 			--rcount;
448 			if (actualp)
449 				++*actualp;
450 		} else {
451 			/*
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.
455 			 *
456 			 * XXX if rcount is loaded as 0 how do I generate a
457 			 *     STOP now without issuing another RD or WR?
458 			 */
459 			if (rcount > (u_char)last)
460 				rcount = (u_char)last;
461 			op |= SMB_TRANS_NOCNT;
462 		}
463 	}
464 	error = 0;
465 done:
466 	/* XXX wait for xmit buffer to become empty */
467 	last = reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
468 
469 	return error;
470 }
471 
472 /*
473  *				SMBUS API FUNCTIONS
474  *
475  * Called from ig4iic_pci_attach/detach()
476  */
477 int
478 ig4iic_attach(ig4iic_softc_t *sc)
479 {
480 	int error;
481 	uint32_t v;
482 
483 	lockmgr(&sc->lk, LK_EXCLUSIVE);
484 
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);
496 	}
497 
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);
502 
503 	v = reg_read(sc, IG4_REG_COMP_VER);
504 	kprintf(" version %08x\n", v);
505 	if (v != IG4_COMP_VER) {
506 		error = ENXIO;
507 		goto done;
508 	}
509 #if 1
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);
520 
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);
525 #endif
526 	/*
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).
532 	 */
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);
537 
538 	/*
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.
542 	 */
543 	reg_write(sc, IG4_REG_RX_TL, 1);
544 
545 	reg_write(sc, IG4_REG_CTL,
546 		  IG4_CTL_MASTER |
547 		  IG4_CTL_SLAVE_DISABLE |
548 		  IG4_CTL_RESTARTEN |
549 		  IG4_CTL_SPEED_STD);
550 
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");
554 		error = ENXIO;
555 		goto done;
556 	}
557 
558 #if 0
559 	/*
560 	 * Don't do this, it blows up the PCI config
561 	 */
562 	reg_write(sc, IG4_REG_RESETS, IG4_RESETS_ASSERT);
563 	reg_write(sc, IG4_REG_RESETS, IG4_RESETS_DEASSERT);
564 #endif
565 
566 	/*
567 	 * Interrupt on STOP detect or receive character ready
568 	 */
569 	reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET |
570 					 IG4_INTR_RX_FULL);
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);
577 	if (error) {
578 		device_printf(sc->dev,
579 			      "Unable to setup irq: error %d\n", error);
580 		goto done;
581 	}
582 
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);
587 	if (error) {
588 		device_printf(sc->dev,
589 			      "failed to attach child: error %d\n", error);
590 		goto done;
591 	}
592 	sc->generic_attached = 1;
593 
594 done:
595 	lockmgr(&sc->lk, LK_RELEASE);
596 	return error;
597 }
598 
599 int
600 ig4iic_detach(ig4iic_softc_t *sc)
601 {
602 	int error;
603 
604 	lockmgr(&sc->lk, LK_EXCLUSIVE);
605 
606 	reg_write(sc, IG4_REG_INTR_MASK, 0);
607 	reg_read(sc, IG4_REG_CLR_INTR);
608 	set_controller(sc, 0);
609 
610 	if (sc->generic_attached) {
611 		error = bus_generic_detach(sc->dev);
612 		if (error)
613 			goto done;
614 		sc->generic_attached = 0;
615 	}
616 	if (sc->smb) {
617 		device_delete_child(sc->dev, sc->smb);
618 		sc->smb = NULL;
619 	}
620 	if (sc->intr_handle) {
621 		bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle);
622 		sc->intr_handle = NULL;
623 	}
624 
625 	error = 0;
626 done:
627 	lockmgr(&sc->lk, LK_RELEASE);
628 	return error;
629 }
630 
631 int
632 ig4iic_smb_callback(device_t dev, int index, void *data)
633 {
634 	ig4iic_softc_t *sc = device_get_softc(dev);
635 	int error;
636 
637 	lockmgr(&sc->lk, LK_EXCLUSIVE);
638 
639 	switch (index) {
640 	case SMB_REQUEST_BUS:
641 		error = 0;
642 		break;
643 	case SMB_RELEASE_BUS:
644 		error = 0;
645 		break;
646 	default:
647 		error = SMB_EABORT;
648 		break;
649 	}
650 
651 	lockmgr(&sc->lk, LK_RELEASE);
652 
653 	return error;
654 }
655 
656 /*
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.
660  */
661 int
662 ig4iic_smb_quick(device_t dev, u_char slave, int how)
663 {
664 	ig4iic_softc_t *sc = device_get_softc(dev);
665 	int error;
666 
667 	lockmgr(&sc->lk, LK_EXCLUSIVE);
668 
669 	switch (how) {
670 	case SMB_QREAD:
671 		error = SMB_ENOTSUPP;
672 		break;
673 	case SMB_QWRITE:
674 		error = SMB_ENOTSUPP;
675 		break;
676 	default:
677 		error = SMB_ENOTSUPP;
678 		break;
679 	}
680 	lockmgr(&sc->lk, LK_RELEASE);
681 
682 	return error;
683 }
684 
685 /*
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().
689  *
690  * (Also, how would this work anyway?  Issue the last byte with writeb()?)
691  */
692 int
693 ig4iic_smb_sendb(device_t dev, u_char slave, char byte)
694 {
695 	ig4iic_softc_t *sc = device_get_softc(dev);
696 	uint32_t cmd;
697 	int error;
698 
699 	lockmgr(&sc->lk, LK_EXCLUSIVE);
700 
701 	set_slave_addr(sc, slave, 0);
702 	cmd = byte;
703 	if (wait_status(sc, IG4_STATUS_TX_NOTFULL) == 0) {
704 		reg_write(sc, IG4_REG_DATA_CMD, cmd);
705 		error = 0;
706 	} else {
707 		error = SMB_ETIMEOUT;
708 	}
709 
710 	lockmgr(&sc->lk, LK_RELEASE);
711 	return error;
712 }
713 
714 /*
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().
718  */
719 int
720 ig4iic_smb_recvb(device_t dev, u_char slave, char *byte)
721 {
722 	ig4iic_softc_t *sc = device_get_softc(dev);
723 	int error;
724 
725 	lockmgr(&sc->lk, LK_EXCLUSIVE);
726 
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);
731 		error = 0;
732 	} else {
733 		*byte = 0;
734 		error = SMB_ETIMEOUT;
735 	}
736 
737 	lockmgr(&sc->lk, LK_RELEASE);
738 	return error;
739 }
740 
741 /*
742  * Write command and single byte in transaction.
743  */
744 int
745 ig4iic_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
746 {
747 	ig4iic_softc_t *sc = device_get_softc(dev);
748 	int error;
749 
750 	lockmgr(&sc->lk, LK_EXCLUSIVE);
751 
752 	set_slave_addr(sc, slave, 0);
753 	error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
754 				&byte, 1, NULL, 0, NULL);
755 
756 	lockmgr(&sc->lk, LK_RELEASE);
757 	return error;
758 }
759 
760 /*
761  * Write command and single word in transaction.
762  */
763 int
764 ig4iic_smb_writew(device_t dev, u_char slave, char cmd, short word)
765 {
766 	ig4iic_softc_t *sc = device_get_softc(dev);
767 	char buf[2];
768 	int error;
769 
770 	lockmgr(&sc->lk, LK_EXCLUSIVE);
771 
772 	set_slave_addr(sc, slave, 0);
773 	buf[0] = word & 0xFF;
774 	buf[1] = word >> 8;
775 	error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
776 				buf, 2, NULL, 0, NULL);
777 
778 	lockmgr(&sc->lk, LK_RELEASE);
779 	return error;
780 }
781 
782 /*
783  * write command and read single byte in transaction.
784  */
785 int
786 ig4iic_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
787 {
788 	ig4iic_softc_t *sc = device_get_softc(dev);
789 	int error;
790 
791 	lockmgr(&sc->lk, LK_EXCLUSIVE);
792 
793 	set_slave_addr(sc, slave, 0);
794 	error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
795 				NULL, 0, byte, 1, NULL);
796 
797 	lockmgr(&sc->lk, LK_RELEASE);
798 	return error;
799 }
800 
801 /*
802  * write command and read word in transaction.
803  */
804 int
805 ig4iic_smb_readw(device_t dev, u_char slave, char cmd, short *word)
806 {
807 	ig4iic_softc_t *sc = device_get_softc(dev);
808 	char buf[2];
809 	int error;
810 
811 	lockmgr(&sc->lk, LK_EXCLUSIVE);
812 
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);
817 	}
818 
819 	lockmgr(&sc->lk, LK_RELEASE);
820 	return error;
821 }
822 
823 /*
824  * write command and word and read word in transaction
825  */
826 int
827 ig4iic_smb_pcall(device_t dev, u_char slave, char cmd,
828 		 short sdata, short *rdata)
829 {
830 	ig4iic_softc_t *sc = device_get_softc(dev);
831 	char rbuf[2];
832 	char wbuf[2];
833 	int error;
834 
835 	lockmgr(&sc->lk, LK_EXCLUSIVE);
836 
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);
843 	}
844 
845 	lockmgr(&sc->lk, LK_RELEASE);
846 	return error;
847 }
848 
849 int
850 ig4iic_smb_bwrite(device_t dev, u_char slave, char cmd,
851 		  u_char wcount, char *buf)
852 {
853 	ig4iic_softc_t *sc = device_get_softc(dev);
854 	int error;
855 
856 	lockmgr(&sc->lk, LK_EXCLUSIVE);
857 
858 	set_slave_addr(sc, slave, 0);
859 	error = smb_transaction(sc, cmd, 0,
860 				buf, wcount, NULL, 0, NULL);
861 
862 	lockmgr(&sc->lk, LK_RELEASE);
863 	return error;
864 }
865 
866 int
867 ig4iic_smb_bread(device_t dev, u_char slave, char cmd,
868 		 u_char *countp_char, char *buf)
869 {
870 	ig4iic_softc_t *sc = device_get_softc(dev);
871 	int rcount = *countp_char;
872 	int error;
873 
874 	lockmgr(&sc->lk, LK_EXCLUSIVE);
875 
876 	set_slave_addr(sc, slave, 0);
877 	error = smb_transaction(sc, cmd, 0,
878 				NULL, 0, buf, rcount, &rcount);
879 	*countp_char = rcount;
880 
881 	lockmgr(&sc->lk, LK_RELEASE);
882 	return error;
883 }
884 
885 int
886 ig4iic_smb_trans(device_t dev, int slave, char cmd, int op,
887 		 char *wbuf, int wcount, char *rbuf, int rcount,
888 		 int *actualp)
889 {
890 	ig4iic_softc_t *sc = device_get_softc(dev);
891 	int error;
892 
893 	lockmgr(&sc->lk, LK_EXCLUSIVE);
894 
895 	set_slave_addr(sc, slave, op);
896 	error = smb_transaction(sc, cmd, op,
897 				wbuf, wcount, rbuf, rcount, actualp);
898 
899 	lockmgr(&sc->lk, LK_RELEASE);
900 	return error;
901 }
902 
903 /*
904  * Interrupt Operation
905  */
906 static
907 void
908 ig4iic_intr(void *cookie)
909 {
910 	ig4iic_softc_t *sc = cookie;
911 	uint32_t status;
912 
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);
919 		++sc->rnext;
920 		status = reg_read(sc, IG4_REG_I2C_STA);
921 	}
922 	reg_read(sc, IG4_REG_CLR_INTR);
923 	wakeup(sc);
924 	lockmgr(&sc->lk, LK_RELEASE);
925 }
926 
927 #define REGDUMP(sc, reg)	\
928 	device_printf(sc->dev, "  %-23s %08x\n", #reg, reg_read(sc, reg))
929 
930 static
931 void
932 ig4iic_dump(ig4iic_softc_t *sc)
933 {
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);
966 }
967 #undef REGDUMP
968 
969 DRIVER_MODULE(smbus, ig4iic, smbus_driver, smbus_devclass, NULL, NULL);
970