1187262Snwhitehorn/*-
2187262Snwhitehorn * Copyright (c) 2001 Tsubai Masanari.  All rights reserved.
3187262Snwhitehorn *
4187262Snwhitehorn * Redistribution and use in source and binary forms, with or without
5187262Snwhitehorn * modification, are permitted provided that the following conditions
6187262Snwhitehorn * are met:
7187262Snwhitehorn * 1. Redistributions of source code must retain the above copyright
8187262Snwhitehorn *    notice, this list of conditions and the following disclaimer.
9187262Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright
10187262Snwhitehorn *    notice, this list of conditions and the following disclaimer in the
11187262Snwhitehorn *    documentation and/or other materials provided with the distribution.
12187262Snwhitehorn * 3. The name of the author may not be used to endorse or promote products
13187262Snwhitehorn *    derived from this software without specific prior written permission.
14187262Snwhitehorn *
15187262Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16187262Snwhitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17187262Snwhitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18187262Snwhitehorn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19187262Snwhitehorn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20187262Snwhitehorn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21187262Snwhitehorn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22187262Snwhitehorn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23187262Snwhitehorn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24187262Snwhitehorn * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25187262Snwhitehorn *
26187262Snwhitehorn * $FreeBSD$
27187262Snwhitehorn *	NetBSD: ki2c.c,v 1.11 2007/12/06 17:00:33 ad Exp
28187262Snwhitehorn *	Id: ki2c.c,v 1.7 2002/10/05 09:56:05 tsubai Exp
29187262Snwhitehorn */
30187262Snwhitehorn
31187262Snwhitehorn/*
32187262Snwhitehorn * 	Support routines for the Keywest I2C controller.
33187262Snwhitehorn */
34187262Snwhitehorn
35187262Snwhitehorn#include <sys/param.h>
36187262Snwhitehorn#include <sys/systm.h>
37187262Snwhitehorn#include <sys/kernel.h>
38187262Snwhitehorn#include <sys/module.h>
39187262Snwhitehorn#include <sys/bus.h>
40187262Snwhitehorn#include <sys/lock.h>
41187262Snwhitehorn#include <sys/mutex.h>
42187262Snwhitehorn#include <machine/resource.h>
43187262Snwhitehorn#include <machine/bus.h>
44187262Snwhitehorn#include <sys/rman.h>
45187262Snwhitehorn
46187262Snwhitehorn#include <dev/iicbus/iicbus.h>
47187262Snwhitehorn#include <dev/iicbus/iiconf.h>
48187262Snwhitehorn#include <dev/ofw/ofw_bus.h>
49187262Snwhitehorn#include "iicbus_if.h"
50187262Snwhitehorn
51187262Snwhitehorn/* Keywest I2C Register offsets */
52187262Snwhitehorn#define MODE	0
53187262Snwhitehorn#define CONTROL	1
54187262Snwhitehorn#define STATUS	2
55187262Snwhitehorn#define ISR	3
56187262Snwhitehorn#define IER	4
57187262Snwhitehorn#define ADDR	5
58187262Snwhitehorn#define SUBADDR	6
59187262Snwhitehorn#define DATA	7
60209302Snwhitehorn#define REV	8
61187262Snwhitehorn
62187262Snwhitehorn/* MODE */
63187262Snwhitehorn#define I2C_SPEED	0x03	/* Speed mask */
64187262Snwhitehorn#define  I2C_100kHz	0x00
65187262Snwhitehorn#define  I2C_50kHz	0x01
66187262Snwhitehorn#define  I2C_25kHz	0x02
67187262Snwhitehorn#define I2C_MODE	0x0c	/* Mode mask */
68187262Snwhitehorn#define  I2C_DUMBMODE	0x00	/*  Dumb mode */
69187262Snwhitehorn#define  I2C_STDMODE	0x04	/*  Standard mode */
70187262Snwhitehorn#define  I2C_STDSUBMODE	0x08	/*  Standard mode + sub address */
71187262Snwhitehorn#define  I2C_COMBMODE	0x0c	/*  Combined mode */
72187262Snwhitehorn#define I2C_PORT	0xf0	/* Port mask */
73187262Snwhitehorn
74187262Snwhitehorn/* CONTROL */
75187262Snwhitehorn#define I2C_CT_AAK	0x01	/* Send AAK */
76187262Snwhitehorn#define I2C_CT_ADDR	0x02	/* Send address(es) */
77187262Snwhitehorn#define I2C_CT_STOP	0x04	/* Send STOP */
78187262Snwhitehorn#define I2C_CT_START	0x08	/* Send START */
79187262Snwhitehorn
80187262Snwhitehorn/* STATUS */
81187262Snwhitehorn#define I2C_ST_BUSY	0x01	/* Busy */
82187262Snwhitehorn#define I2C_ST_LASTAAK	0x02	/* Last AAK */
83187262Snwhitehorn#define I2C_ST_LASTRW	0x04	/* Last R/W */
84187262Snwhitehorn#define I2C_ST_SDA	0x08	/* SDA */
85187262Snwhitehorn#define I2C_ST_SCL	0x10	/* SCL */
86187262Snwhitehorn
87187262Snwhitehorn/* ISR/IER */
88187262Snwhitehorn#define I2C_INT_DATA	0x01	/* Data byte sent/received */
89187262Snwhitehorn#define I2C_INT_ADDR	0x02	/* Address sent */
90187262Snwhitehorn#define I2C_INT_STOP	0x04	/* STOP condition sent */
91187262Snwhitehorn#define I2C_INT_START	0x08	/* START condition sent */
92187262Snwhitehorn
93187262Snwhitehorn/* I2C flags */
94187262Snwhitehorn#define I2C_BUSY	0x01
95187262Snwhitehorn#define I2C_READING	0x02
96187262Snwhitehorn#define I2C_ERROR	0x04
97187262Snwhitehorn#define I2C_SELECTED	0x08
98187262Snwhitehorn
99187262Snwhitehornstruct kiic_softc {
100187262Snwhitehorn	device_t 		 sc_dev;
101187262Snwhitehorn	phandle_t		 sc_node;
102187262Snwhitehorn	struct mtx 		 sc_mutex;
103187262Snwhitehorn	struct resource		*sc_reg;
104187262Snwhitehorn	int			 sc_irqrid;
105187262Snwhitehorn	struct resource		*sc_irq;
106187262Snwhitehorn	void			*sc_ih;
107187262Snwhitehorn	u_int 			 sc_regstep;
108187262Snwhitehorn	u_int 			 sc_flags;
109187262Snwhitehorn	u_char			*sc_data;
110187262Snwhitehorn	int 			 sc_resid;
111208840Snwhitehorn	uint16_t		 sc_i2c_base;
112187262Snwhitehorn	device_t 		 sc_iicbus;
113187262Snwhitehorn};
114187262Snwhitehorn
115187262Snwhitehornstatic int 	kiic_probe(device_t dev);
116187262Snwhitehornstatic int 	kiic_attach(device_t dev);
117187262Snwhitehornstatic void 	kiic_writereg(struct kiic_softc *sc, u_int, u_int);
118187262Snwhitehornstatic u_int 	kiic_readreg(struct kiic_softc *, u_int);
119208840Snwhitehornstatic void 	kiic_setport(struct kiic_softc *, u_int);
120187262Snwhitehornstatic void 	kiic_setmode(struct kiic_softc *, u_int);
121187262Snwhitehornstatic void 	kiic_setspeed(struct kiic_softc *, u_int);
122187262Snwhitehornstatic void 	kiic_intr(void *xsc);
123187262Snwhitehornstatic int	kiic_transfer(device_t dev, struct iic_msg *msgs,
124187262Snwhitehorn		    uint32_t nmsgs);
125187262Snwhitehornstatic phandle_t kiic_get_node(device_t bus, device_t dev);
126187262Snwhitehorn
127187262Snwhitehornstatic device_method_t kiic_methods[] = {
128187262Snwhitehorn	/* device interface */
129187262Snwhitehorn	DEVMETHOD(device_probe, 	kiic_probe),
130187262Snwhitehorn	DEVMETHOD(device_attach, 	kiic_attach),
131187262Snwhitehorn
132187262Snwhitehorn	/* iicbus interface */
133187262Snwhitehorn	DEVMETHOD(iicbus_callback,	iicbus_null_callback),
134187262Snwhitehorn	DEVMETHOD(iicbus_transfer,	kiic_transfer),
135187262Snwhitehorn
136187262Snwhitehorn	/* ofw_bus interface */
137187262Snwhitehorn	DEVMETHOD(ofw_bus_get_node,	kiic_get_node),
138187262Snwhitehorn
139187262Snwhitehorn	{ 0, 0 }
140187262Snwhitehorn};
141187262Snwhitehorn
142187262Snwhitehornstatic driver_t kiic_driver = {
143187262Snwhitehorn	"iichb",
144187262Snwhitehorn	kiic_methods,
145187262Snwhitehorn	sizeof(struct kiic_softc)
146187262Snwhitehorn};
147187262Snwhitehornstatic devclass_t kiic_devclass;
148187262Snwhitehorn
149187262SnwhitehornDRIVER_MODULE(kiic, macio, kiic_driver, kiic_devclass, 0, 0);
150209302SnwhitehornDRIVER_MODULE(kiic, unin, kiic_driver, kiic_devclass, 0, 0);
151187262Snwhitehorn
152187262Snwhitehornstatic int
153187262Snwhitehornkiic_probe(device_t self)
154187262Snwhitehorn{
155187262Snwhitehorn	const char *name;
156187262Snwhitehorn
157187262Snwhitehorn	name = ofw_bus_get_name(self);
158187262Snwhitehorn	if (name && strcmp(name, "i2c") == 0) {
159187262Snwhitehorn		device_set_desc(self, "Keywest I2C controller");
160187262Snwhitehorn		return (0);
161187262Snwhitehorn	}
162187262Snwhitehorn
163187262Snwhitehorn	return (ENXIO);
164187262Snwhitehorn}
165187262Snwhitehorn
166187262Snwhitehornstatic int
167187262Snwhitehornkiic_attach(device_t self)
168187262Snwhitehorn{
169187262Snwhitehorn	struct kiic_softc *sc = device_get_softc(self);
170187262Snwhitehorn	int rid, rate;
171187262Snwhitehorn	phandle_t node;
172187262Snwhitehorn	char name[64];
173187262Snwhitehorn
174187262Snwhitehorn	bzero(sc, sizeof(*sc));
175187262Snwhitehorn	sc->sc_dev = self;
176187262Snwhitehorn
177187262Snwhitehorn	node = ofw_bus_get_node(self);
178187262Snwhitehorn	if (node == 0 || node == -1) {
179187262Snwhitehorn		return (EINVAL);
180187262Snwhitehorn	}
181187262Snwhitehorn
182187262Snwhitehorn	rid = 0;
183187262Snwhitehorn	sc->sc_reg = bus_alloc_resource_any(self, SYS_RES_MEMORY,
184187262Snwhitehorn			&rid, RF_ACTIVE);
185187262Snwhitehorn	if (sc->sc_reg == NULL) {
186187262Snwhitehorn		return (ENOMEM);
187187262Snwhitehorn	}
188187262Snwhitehorn
189187262Snwhitehorn	if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) {
190187262Snwhitehorn		device_printf(self, "cannot get i2c-rate\n");
191187262Snwhitehorn		return (ENXIO);
192187262Snwhitehorn	}
193187262Snwhitehorn	if (OF_getprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) {
194187262Snwhitehorn		device_printf(self, "unable to find i2c address step\n");
195187262Snwhitehorn		return (ENXIO);
196187262Snwhitehorn	}
197187262Snwhitehorn
198187262Snwhitehorn	/*
199187262Snwhitehorn	 * Some Keywest I2C devices have their children attached directly
200187262Snwhitehorn	 * underneath them.  Some have a single 'iicbus' child with the
201187262Snwhitehorn	 * devices underneath that.  Sort this out, and make sure that the
202187262Snwhitehorn	 * OFW I2C layer has the correct node.
203208840Snwhitehorn	 *
204208840Snwhitehorn	 * Note: the I2C children of the Uninorth bridges have two ports.
205208840Snwhitehorn	 *  In general, the port is designated in the 9th bit of the I2C
206208840Snwhitehorn	 *  address. However, for kiic devices with children attached below
207208840Snwhitehorn	 *  an i2c-bus node, the port is indicated in the 'reg' property
208208840Snwhitehorn	 *  of the i2c-bus node.
209187262Snwhitehorn	 */
210187262Snwhitehorn
211208840Snwhitehorn	sc->sc_node = node;
212208840Snwhitehorn
213208840Snwhitehorn	node = OF_child(node);
214208840Snwhitehorn	if (OF_getprop(node, "name", name, sizeof(name)) > 0) {
215208840Snwhitehorn		if (strcmp(name,"i2c-bus") == 0) {
216208840Snwhitehorn			phandle_t reg;
217208840Snwhitehorn			if (OF_getprop(node, "reg", &reg, sizeof(reg)) > 0)
218208840Snwhitehorn				sc->sc_i2c_base = reg << 8;
219208840Snwhitehorn
220187262Snwhitehorn			sc->sc_node = node;
221208840Snwhitehorn		}
222187262Snwhitehorn	}
223187262Snwhitehorn
224187262Snwhitehorn	mtx_init(&sc->sc_mutex, "kiic", NULL, MTX_DEF);
225187262Snwhitehorn
226187262Snwhitehorn	sc->sc_irq = bus_alloc_resource_any(self, SYS_RES_IRQ, &sc->sc_irqrid,
227187262Snwhitehorn	    RF_ACTIVE);
228187262Snwhitehorn	bus_setup_intr(self, sc->sc_irq, INTR_TYPE_MISC | INTR_MPSAFE, NULL,
229187262Snwhitehorn	    kiic_intr, sc, &sc->sc_ih);
230187262Snwhitehorn
231208840Snwhitehorn	kiic_writereg(sc, ISR, kiic_readreg(sc, ISR));
232187262Snwhitehorn	kiic_writereg(sc, STATUS, 0);
233187262Snwhitehorn	kiic_writereg(sc, IER, 0);
234187262Snwhitehorn
235187262Snwhitehorn	kiic_setmode(sc, I2C_STDMODE);
236187262Snwhitehorn	kiic_setspeed(sc, I2C_100kHz);		/* XXX rate */
237187262Snwhitehorn
238187262Snwhitehorn	kiic_writereg(sc, IER, I2C_INT_DATA | I2C_INT_ADDR | I2C_INT_STOP);
239187262Snwhitehorn
240209302Snwhitehorn	if (bootverbose)
241209302Snwhitehorn		device_printf(self, "Revision: %02X\n", kiic_readreg(sc, REV));
242209302Snwhitehorn
243187262Snwhitehorn	/* Add the IIC bus layer */
244187262Snwhitehorn	sc->sc_iicbus = device_add_child(self, "iicbus", -1);
245187262Snwhitehorn
246187262Snwhitehorn	return (bus_generic_attach(self));
247187262Snwhitehorn}
248187262Snwhitehorn
249187262Snwhitehornstatic void
250187262Snwhitehornkiic_writereg(struct kiic_softc *sc, u_int reg, u_int val)
251187262Snwhitehorn{
252209302Snwhitehorn	bus_write_4(sc->sc_reg, sc->sc_regstep * reg, val);
253212687Sandreast	DELAY(100); /* register access delay */
254187262Snwhitehorn}
255187262Snwhitehorn
256187262Snwhitehornstatic u_int
257187262Snwhitehornkiic_readreg(struct kiic_softc *sc, u_int reg)
258187262Snwhitehorn{
259209302Snwhitehorn	return bus_read_4(sc->sc_reg, sc->sc_regstep * reg) & 0xff;
260187262Snwhitehorn}
261187262Snwhitehorn
262187262Snwhitehornstatic void
263187262Snwhitehornkiic_setmode(struct kiic_softc *sc, u_int mode)
264187262Snwhitehorn{
265187262Snwhitehorn	u_int x;
266187262Snwhitehorn
267187262Snwhitehorn	KASSERT((mode & ~I2C_MODE) == 0, ("bad mode"));
268187262Snwhitehorn	x = kiic_readreg(sc, MODE);
269187262Snwhitehorn	x &= ~I2C_MODE;
270187262Snwhitehorn	x |= mode;
271187262Snwhitehorn	kiic_writereg(sc, MODE, x);
272187262Snwhitehorn}
273187262Snwhitehorn
274187262Snwhitehornstatic void
275208840Snwhitehornkiic_setport(struct kiic_softc *sc, u_int port)
276208840Snwhitehorn{
277208840Snwhitehorn	u_int x;
278208840Snwhitehorn
279208840Snwhitehorn	KASSERT(port == 1 || port == 0, ("bad port"));
280208840Snwhitehorn	x = kiic_readreg(sc, MODE);
281208840Snwhitehorn	x &= ~I2C_PORT;
282208840Snwhitehorn	x |= (port << 4);
283208840Snwhitehorn	kiic_writereg(sc, MODE, x);
284208840Snwhitehorn}
285208840Snwhitehorn
286208840Snwhitehornstatic void
287187262Snwhitehornkiic_setspeed(struct kiic_softc *sc, u_int speed)
288187262Snwhitehorn{
289187262Snwhitehorn	u_int x;
290187262Snwhitehorn
291187262Snwhitehorn	KASSERT((speed & ~I2C_SPEED) == 0, ("bad speed"));
292187262Snwhitehorn	x = kiic_readreg(sc, MODE);
293187262Snwhitehorn	x &= ~I2C_SPEED;
294187262Snwhitehorn	x |= speed;
295187262Snwhitehorn	kiic_writereg(sc, MODE, x);
296187262Snwhitehorn}
297187262Snwhitehorn
298187262Snwhitehornstatic void
299187262Snwhitehornkiic_intr(void *xsc)
300187262Snwhitehorn{
301187262Snwhitehorn	struct kiic_softc *sc = xsc;
302187262Snwhitehorn	u_int isr;
303187262Snwhitehorn	uint32_t x;
304187262Snwhitehorn
305187262Snwhitehorn	mtx_lock(&sc->sc_mutex);
306187262Snwhitehorn	isr = kiic_readreg(sc, ISR);
307187262Snwhitehorn
308187262Snwhitehorn	if (isr & I2C_INT_ADDR) {
309187262Snwhitehorn		sc->sc_flags |= I2C_SELECTED;
310187262Snwhitehorn
311187262Snwhitehorn		if (sc->sc_flags & I2C_READING) {
312187262Snwhitehorn			if (sc->sc_resid > 1) {
313187262Snwhitehorn				x = kiic_readreg(sc, CONTROL);
314187262Snwhitehorn				x |= I2C_CT_AAK;
315187262Snwhitehorn				kiic_writereg(sc, CONTROL, x);
316187262Snwhitehorn			}
317187262Snwhitehorn		} else {
318187262Snwhitehorn			kiic_writereg(sc, DATA, *sc->sc_data++);
319187262Snwhitehorn			sc->sc_resid--;
320187262Snwhitehorn		}
321187262Snwhitehorn	}
322187262Snwhitehorn
323187262Snwhitehorn	if (isr & I2C_INT_DATA) {
324187473Snwhitehorn		if (sc->sc_flags & I2C_READING) {
325187473Snwhitehorn			if (sc->sc_resid > 0) {
326187262Snwhitehorn				*sc->sc_data++ = kiic_readreg(sc, DATA);
327187262Snwhitehorn				sc->sc_resid--;
328187473Snwhitehorn			}
329208840Snwhitehorn			if (sc->sc_resid == 0)  /* done */
330208840Snwhitehorn				kiic_writereg(sc, CONTROL, 0);
331187473Snwhitehorn		} else {
332187473Snwhitehorn			if (sc->sc_resid == 0) {
333187473Snwhitehorn				x = kiic_readreg(sc, CONTROL);
334187473Snwhitehorn				x |= I2C_CT_STOP;
335187473Snwhitehorn				kiic_writereg(sc, CONTROL, x);
336187262Snwhitehorn			} else {
337187262Snwhitehorn				kiic_writereg(sc, DATA, *sc->sc_data++);
338187262Snwhitehorn				sc->sc_resid--;
339187262Snwhitehorn			}
340187262Snwhitehorn		}
341187262Snwhitehorn	}
342187262Snwhitehorn
343187262Snwhitehorn	if (isr & I2C_INT_STOP) {
344187262Snwhitehorn		kiic_writereg(sc, CONTROL, 0);
345187262Snwhitehorn		sc->sc_flags &= ~I2C_SELECTED;
346187262Snwhitehorn		wakeup(sc->sc_dev);
347187262Snwhitehorn	}
348187262Snwhitehorn
349187262Snwhitehorn	kiic_writereg(sc, ISR, isr);
350187262Snwhitehorn	mtx_unlock(&sc->sc_mutex);
351187262Snwhitehorn}
352187262Snwhitehorn
353187262Snwhitehornstatic int
354187262Snwhitehornkiic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
355187262Snwhitehorn{
356187262Snwhitehorn	struct kiic_softc *sc;
357187473Snwhitehorn	int i, x, timo, err;
358208840Snwhitehorn	uint16_t addr;
359208840Snwhitehorn	uint8_t subaddr;
360187262Snwhitehorn
361187262Snwhitehorn	sc = device_get_softc(dev);
362187262Snwhitehorn	timo = 100;
363208840Snwhitehorn	subaddr = 0;
364187262Snwhitehorn
365187262Snwhitehorn	mtx_lock(&sc->sc_mutex);
366187262Snwhitehorn
367187262Snwhitehorn	if (sc->sc_flags & I2C_BUSY)
368187262Snwhitehorn		mtx_sleep(dev, &sc->sc_mutex, 0, "kiic", timo);
369187262Snwhitehorn
370187262Snwhitehorn	if (sc->sc_flags & I2C_BUSY) {
371187262Snwhitehorn		mtx_unlock(&sc->sc_mutex);
372187262Snwhitehorn		return (ETIMEDOUT);
373187262Snwhitehorn	}
374187262Snwhitehorn
375187262Snwhitehorn	sc->sc_flags = I2C_BUSY;
376187262Snwhitehorn
377208840Snwhitehorn	/* Clear pending interrupts, and reset controller */
378208840Snwhitehorn	kiic_writereg(sc, ISR, kiic_readreg(sc, ISR));
379208840Snwhitehorn	kiic_writereg(sc, STATUS, 0);
380208840Snwhitehorn
381187262Snwhitehorn	for (i = 0; i < nmsgs; i++) {
382208840Snwhitehorn		if (msgs[i].flags & IIC_M_NOSTOP) {
383208840Snwhitehorn			if (msgs[i+1].flags & IIC_M_RD)
384208840Snwhitehorn				kiic_setmode(sc, I2C_COMBMODE);
385208840Snwhitehorn			else
386208840Snwhitehorn				kiic_setmode(sc, I2C_STDSUBMODE);
387208840Snwhitehorn			KASSERT(msgs[i].len == 1, ("oversize I2C message"));
388208840Snwhitehorn			subaddr = msgs[i].buf[0];
389208840Snwhitehorn			i++;
390208840Snwhitehorn		} else {
391208840Snwhitehorn			kiic_setmode(sc, I2C_STDMODE);
392208840Snwhitehorn		}
393208840Snwhitehorn
394187262Snwhitehorn		sc->sc_data = msgs[i].buf;
395187262Snwhitehorn		sc->sc_resid = msgs[i].len;
396187262Snwhitehorn		sc->sc_flags = I2C_BUSY;
397187262Snwhitehorn		addr = msgs[i].slave;
398187262Snwhitehorn		timo = 1000 + sc->sc_resid * 200;
399187473Snwhitehorn		timo += 100000;
400187262Snwhitehorn
401187262Snwhitehorn		if (msgs[i].flags & IIC_M_RD) {
402187262Snwhitehorn			sc->sc_flags |= I2C_READING;
403187262Snwhitehorn			addr |= 1;
404187262Snwhitehorn		}
405187262Snwhitehorn
406208840Snwhitehorn		addr |= sc->sc_i2c_base;
407187262Snwhitehorn
408208840Snwhitehorn		kiic_setport(sc, (addr & 0x100) >> 8);
409208840Snwhitehorn		kiic_writereg(sc, ADDR, addr & 0xff);
410208840Snwhitehorn		kiic_writereg(sc, SUBADDR, subaddr);
411208840Snwhitehorn
412187262Snwhitehorn		x = kiic_readreg(sc, CONTROL) | I2C_CT_ADDR;
413187262Snwhitehorn		kiic_writereg(sc, CONTROL, x);
414187262Snwhitehorn
415187473Snwhitehorn		err = mtx_sleep(dev, &sc->sc_mutex, 0, "kiic", timo);
416187473Snwhitehorn
417187262Snwhitehorn		msgs[i].len -= sc->sc_resid;
418187262Snwhitehorn
419187473Snwhitehorn		if ((sc->sc_flags & I2C_ERROR) || err == EWOULDBLOCK) {
420187473Snwhitehorn			device_printf(sc->sc_dev, "I2C error\n");
421187473Snwhitehorn			sc->sc_flags = 0;
422187262Snwhitehorn			mtx_unlock(&sc->sc_mutex);
423254737Sandreast			return (EIO);
424187262Snwhitehorn		}
425187262Snwhitehorn	}
426187262Snwhitehorn
427187262Snwhitehorn	sc->sc_flags = 0;
428187262Snwhitehorn
429187262Snwhitehorn	mtx_unlock(&sc->sc_mutex);
430187262Snwhitehorn
431187262Snwhitehorn	return (0);
432187262Snwhitehorn}
433187262Snwhitehorn
434187262Snwhitehornstatic phandle_t
435187262Snwhitehornkiic_get_node(device_t bus, device_t dev)
436187262Snwhitehorn{
437187262Snwhitehorn	struct kiic_softc *sc;
438187262Snwhitehorn
439187262Snwhitehorn	sc = device_get_softc(bus);
440187262Snwhitehorn	/* We only have one child, the I2C bus, which needs our own node. */
441187262Snwhitehorn
442187262Snwhitehorn	return sc->sc_node;
443187262Snwhitehorn}
444187262Snwhitehorn
445