xref: /openbsd-src/sys/arch/sparc64/dev/mgiic.c (revision eb7eaf8de3ff431d305450f61b441e5460c82246)
1*eb7eaf8dSmpi /*	$OpenBSD: mgiic.c,v 1.4 2021/10/24 17:05:03 mpi Exp $	*/
24438e468Sderaadt /*
3539dbbeaSderaadt  * Copyright (c) 2008 Theo de Raadt <deraadt@openbsd.org>
44438e468Sderaadt  *
54438e468Sderaadt  * Permission to use, copy, modify, and distribute this software for any
64438e468Sderaadt  * purpose with or without fee is hereby granted, provided that the above
74438e468Sderaadt  * copyright notice and this permission notice appear in all copies.
84438e468Sderaadt  *
94438e468Sderaadt  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
104438e468Sderaadt  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
114438e468Sderaadt  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
124438e468Sderaadt  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
134438e468Sderaadt  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
144438e468Sderaadt  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
154438e468Sderaadt  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
164438e468Sderaadt  */
174438e468Sderaadt 
184438e468Sderaadt #include <sys/param.h>
194438e468Sderaadt #include <sys/device.h>
204438e468Sderaadt #include <sys/errno.h>
214438e468Sderaadt #include <sys/malloc.h>
224438e468Sderaadt #include <sys/systm.h>
234438e468Sderaadt #include <sys/rwlock.h>
244438e468Sderaadt 
254438e468Sderaadt #include <uvm/uvm_extern.h>
264438e468Sderaadt 
274438e468Sderaadt #include <machine/bus.h>
284438e468Sderaadt #include <machine/autoconf.h>
294438e468Sderaadt #include <machine/openfirm.h>
304438e468Sderaadt 
314438e468Sderaadt #include <dev/i2c/i2cvar.h>
324438e468Sderaadt #include <sparc64/dev/ofwi2cvar.h>
334438e468Sderaadt 
34539dbbeaSderaadt #define MGSLAVEADDR		0x00
35539dbbeaSderaadt #define MGSLAVEXADDR		0x08
36539dbbeaSderaadt #define MGDATA			0x10
37539dbbeaSderaadt #define MGCONTROL			0x18
38539dbbeaSderaadt #define  MGCONTROL_IEN			0x80
39539dbbeaSderaadt #define  MGCONTROL_ENAB			0x40
40539dbbeaSderaadt #define  MGCONTROL_STA			0x20
41539dbbeaSderaadt #define  MGCONTROL_STP			0x10
42539dbbeaSderaadt #define  MGCONTROL_IFLG			0x08
43539dbbeaSderaadt #define  MGCONTROL_AAK			0x04
44539dbbeaSderaadt #define MGSTATUS		0x20
45539dbbeaSderaadt #define  MGSTATUS_BUSERR		0x00
46539dbbeaSderaadt #define  MGSTATUS_STARTSENT		0x08
47539dbbeaSderaadt #define	 MGSTATUS_REPEATSTART		0x10
48539dbbeaSderaadt #define  MGSTATUS_ADDR_W_ACKR		0x18
49539dbbeaSderaadt #define  MGSTATUS_ADDR_W_NOACKR		0x20
50539dbbeaSderaadt #define  MGSTATUS_MDATA_ACKR		0x28
51539dbbeaSderaadt #define  MGSTATUS_MDATA_NOACKR		0x30
52539dbbeaSderaadt #define  MGSTATUS_ARBLOST		0x38
53539dbbeaSderaadt #define  MGSTATUS_ADDR_R_ACKR		0x40
54539dbbeaSderaadt #define  MGSTATUS_ADDR_R_NOACKR		0x48
55539dbbeaSderaadt #define  MGSTATUS_MDATA_ACKT		0x50
56539dbbeaSderaadt #define  MGSTATUS_MDATA_NOACKT		0x58
57539dbbeaSderaadt #define  MGSTATUS_SADDR_W_ACKT		0x60
58539dbbeaSderaadt #define  MGSTATUS_ARBLOST_SLW_ACKT	0x68
59539dbbeaSderaadt #define  MGSTATUS_GC_TACK		0x70
60539dbbeaSderaadt #define  MGSTATUS_ARBLOST_GC_ACKT	0x78
61539dbbeaSderaadt #define  MGSTATUS_IDLE			0xf8
62539dbbeaSderaadt #define MGCLOCKCONTROL		0x28
63539dbbeaSderaadt #define MGSOFTRESET		0x30
644438e468Sderaadt 
654438e468Sderaadt struct mgiic_softc {
664438e468Sderaadt 	struct device sc_dev;
674438e468Sderaadt 
684438e468Sderaadt 	bus_space_tag_t		sc_bt;
694438e468Sderaadt 	bus_space_handle_t	sc_regh;
704438e468Sderaadt 
714438e468Sderaadt 
724438e468Sderaadt 	int			sc_poll;
734438e468Sderaadt 
744438e468Sderaadt 	struct i2c_controller	sc_i2c;
754438e468Sderaadt 	struct rwlock		sc_lock;
764438e468Sderaadt };
774438e468Sderaadt 
784438e468Sderaadt int			mgiic_match(struct device *, void *, void *);
794438e468Sderaadt void			mgiic_attach(struct device *, struct device *, void *);
804438e468Sderaadt 
814438e468Sderaadt struct cfdriver mgiic_cd = {
824438e468Sderaadt         NULL, "mgiic", DV_DULL
834438e468Sderaadt };
844438e468Sderaadt 
85*eb7eaf8dSmpi const struct cfattach mgiic_ca = {
864438e468Sderaadt         sizeof(struct mgiic_softc), mgiic_match, mgiic_attach
874438e468Sderaadt };
884438e468Sderaadt 
894438e468Sderaadt int			mgiic_i2c_acquire_bus(void *, int);
904438e468Sderaadt void			mgiic_i2c_release_bus(void *, int);
914438e468Sderaadt int			mgiic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
924438e468Sderaadt 			    size_t, void *, size_t, int);
934438e468Sderaadt 
94539dbbeaSderaadt int			mgiic_xmit(struct mgiic_softc *, u_int8_t, const u_int8_t *,
95539dbbeaSderaadt 			    size_t);
964438e468Sderaadt int			mgiic_recv(struct mgiic_softc *, u_int8_t, u_int8_t *, size_t);
974438e468Sderaadt volatile u_int8_t	mgiic_read(struct mgiic_softc *, bus_size_t);
984438e468Sderaadt volatile void		mgiic_write(struct mgiic_softc *, bus_size_t, u_int8_t);
994438e468Sderaadt volatile void		mgiic_control(struct mgiic_softc *, u_int8_t, u_int8_t);
1004438e468Sderaadt int			mgiic_poll(struct mgiic_softc *);
1014438e468Sderaadt 
1024438e468Sderaadt int
mgiic_match(struct device * parent,void * match,void * aux)1034438e468Sderaadt mgiic_match(struct device *parent, void *match, void *aux)
1044438e468Sderaadt {
1054438e468Sderaadt 	struct mainbus_attach_args *ma = aux;
1064438e468Sderaadt 	char compat[32];
1074438e468Sderaadt 
1084438e468Sderaadt 	if (strcmp(ma->ma_name, "i2c") != 0)
1094438e468Sderaadt 		return (0);
1104438e468Sderaadt 	if (OF_getprop(ma->ma_node, "compatible", compat, sizeof(compat)) == -1)
1114438e468Sderaadt 		return (0);
1124438e468Sderaadt 	if (strcmp(compat, "fire-i2c") == 0)
1134438e468Sderaadt 		return (1);
1144438e468Sderaadt 	return (0);
1154438e468Sderaadt }
1164438e468Sderaadt 
1174438e468Sderaadt void
mgiic_attach(struct device * parent,struct device * self,void * aux)1184438e468Sderaadt mgiic_attach(struct device *parent, struct device *self, void *aux)
1194438e468Sderaadt {
1204438e468Sderaadt 	struct mgiic_softc *sc = (struct mgiic_softc *)self;
1214438e468Sderaadt 	struct mainbus_attach_args *ma = aux;
1224438e468Sderaadt 	struct i2cbus_attach_args iba;
1234438e468Sderaadt 
1244438e468Sderaadt 	sc->sc_bt = ma->ma_bustag;
1254438e468Sderaadt 
1264438e468Sderaadt 	if (bus_space_map(sc->sc_bt, ma->ma_reg[0].ur_paddr,
1274438e468Sderaadt 	    ma->ma_reg[0].ur_len, 0, &sc->sc_regh)) {
1284438e468Sderaadt 		printf(": failed to map preg\n");
1294438e468Sderaadt 		return;
1304438e468Sderaadt 	}
1314438e468Sderaadt 
1324438e468Sderaadt 	rw_init(&sc->sc_lock, "iiclk");
1334438e468Sderaadt 	sc->sc_i2c.ic_cookie = sc;
1344438e468Sderaadt 	sc->sc_i2c.ic_acquire_bus = mgiic_i2c_acquire_bus;
1354438e468Sderaadt 	sc->sc_i2c.ic_release_bus = mgiic_i2c_release_bus;
1364438e468Sderaadt 	sc->sc_i2c.ic_exec = mgiic_i2c_exec;
1374438e468Sderaadt 
138539dbbeaSderaadt 	printf("\n");
139539dbbeaSderaadt 
1404438e468Sderaadt 	bzero(&iba, sizeof(iba));
1414438e468Sderaadt 	iba.iba_name = "iic";
1424438e468Sderaadt 	iba.iba_tag = &sc->sc_i2c;
1434438e468Sderaadt 	iba.iba_bus_scan = ofwiic_scan;
1444438e468Sderaadt 	iba.iba_bus_scan_arg = &ma->ma_node;
1454438e468Sderaadt 	config_found(&sc->sc_dev, &iba, iicbus_print);
1464438e468Sderaadt }
1474438e468Sderaadt 
1484438e468Sderaadt int
mgiic_i2c_acquire_bus(void * arg,int flags)1494438e468Sderaadt mgiic_i2c_acquire_bus(void *arg, int flags)
1504438e468Sderaadt {
1514438e468Sderaadt 	struct mgiic_softc     *sc = arg;
1524438e468Sderaadt 
1534438e468Sderaadt 	if (cold || sc->sc_poll || (flags & I2C_F_POLL))
1544438e468Sderaadt 		return (0);
1554438e468Sderaadt 
1564438e468Sderaadt 	return (rw_enter(&sc->sc_lock, RW_WRITE | RW_INTR));
1574438e468Sderaadt }
1584438e468Sderaadt 
1594438e468Sderaadt void
mgiic_i2c_release_bus(void * arg,int flags)1604438e468Sderaadt mgiic_i2c_release_bus(void *arg, int flags)
1614438e468Sderaadt {
1624438e468Sderaadt 	struct mgiic_softc     *sc = arg;
1634438e468Sderaadt 
1644438e468Sderaadt 	if (cold || sc->sc_poll || (flags & I2C_F_POLL))
1654438e468Sderaadt 		return;
1664438e468Sderaadt 
1674438e468Sderaadt 	rw_exit(&sc->sc_lock);
1684438e468Sderaadt }
1694438e468Sderaadt 
1704438e468Sderaadt int
mgiic_i2c_exec(void * arg,i2c_op_t op,i2c_addr_t addr,const void * cmdbuf,size_t cmdlen,void * buf,size_t len,int flags)1714438e468Sderaadt mgiic_i2c_exec(void *arg, i2c_op_t op, i2c_addr_t addr,
1724438e468Sderaadt     const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
1734438e468Sderaadt {
1744438e468Sderaadt 	struct mgiic_softc	*sc = arg;
175539dbbeaSderaadt 	int			ret = 0;
1764438e468Sderaadt 
1774438e468Sderaadt 	if (addr & ~0x7f)
1784438e468Sderaadt 		return (1);
1794438e468Sderaadt 
1804438e468Sderaadt 	if (cold || sc->sc_poll)
1814438e468Sderaadt 		flags |= I2C_F_POLL;
1824438e468Sderaadt 
183022afbd7Sjsg 	if (cmdlen > 0) {
184539dbbeaSderaadt 		ret = mgiic_xmit(sc, addr & 0x7f, cmdbuf, cmdlen);
185539dbbeaSderaadt 		if (ret != 0)
186539dbbeaSderaadt 			goto done;
187022afbd7Sjsg 	}
1884438e468Sderaadt 
1894438e468Sderaadt 	if (len > 0) {
1904438e468Sderaadt 		if (I2C_OP_WRITE_P(op))
1914438e468Sderaadt 			ret = mgiic_xmit(sc, addr & 0x7f, buf, len);
1924438e468Sderaadt 		else
1934438e468Sderaadt 			ret = mgiic_recv(sc, addr & 0x7f, buf, len);
1944438e468Sderaadt 	}
195539dbbeaSderaadt done:
1964438e468Sderaadt 	printf("e%d\n", ret);
1974438e468Sderaadt 	return (ret);
1984438e468Sderaadt }
1994438e468Sderaadt 
2004438e468Sderaadt int
mgiic_xmit(struct mgiic_softc * sc,u_int8_t addr,const u_int8_t * buf,size_t len)2014438e468Sderaadt mgiic_xmit(struct mgiic_softc *sc, u_int8_t addr, const u_int8_t *buf,
2024438e468Sderaadt     size_t len)
2034438e468Sderaadt {
204539dbbeaSderaadt 	int err = 1, i = 0;
2054438e468Sderaadt 
206539dbbeaSderaadt top:
207539dbbeaSderaadt 	printf("xmit s%02x STA ", mgiic_read(sc, MGSTATUS));
208539dbbeaSderaadt 	mgiic_control(sc, MGCONTROL_STA, MGCONTROL_IFLG);
2094438e468Sderaadt 
2104438e468Sderaadt 	if (mgiic_poll(sc))
2114438e468Sderaadt 		goto bail;
212539dbbeaSderaadt 	printf("s%02x ", mgiic_read(sc, MGSTATUS));
213539dbbeaSderaadt 	if (mgiic_read(sc, MGSTATUS) != MGSTATUS_STARTSENT)
2144438e468Sderaadt 		goto bail;
2154438e468Sderaadt 
216539dbbeaSderaadt 	mgiic_write(sc, MGDATA, addr << 1);
217539dbbeaSderaadt 	printf("a%02x ", addr << 1);
218539dbbeaSderaadt 	mgiic_control(sc, 0, MGCONTROL_IFLG);
2194438e468Sderaadt 
220539dbbeaSderaadt 	while (i < len) {
2214438e468Sderaadt 		if (mgiic_poll(sc))
2224438e468Sderaadt 			 goto bail;
223539dbbeaSderaadt 		printf("s%02x ", mgiic_read(sc, MGSTATUS));
224539dbbeaSderaadt 		switch (mgiic_read(sc, MGSTATUS)) {
225539dbbeaSderaadt 		case MGSTATUS_ADDR_W_ACKR:
226539dbbeaSderaadt 		case MGSTATUS_MDATA_ACKR:
227539dbbeaSderaadt 			mgiic_write(sc, MGDATA, buf[i]);
2284438e468Sderaadt 			printf("w%02x ", buf[i]);
229539dbbeaSderaadt 			i++;
230539dbbeaSderaadt 			mgiic_control(sc, 0, MGCONTROL_IFLG);
2314438e468Sderaadt 			break;
232539dbbeaSderaadt 		case MGSTATUS_ADDR_W_NOACKR:
233539dbbeaSderaadt 		case MGSTATUS_MDATA_NOACKR:
234539dbbeaSderaadt 			mgiic_write(sc, MGDATA, buf[i]);
235539dbbeaSderaadt 			printf("w%02x ", buf[i]);
236539dbbeaSderaadt 			mgiic_control(sc, 0, MGCONTROL_IFLG);
237539dbbeaSderaadt 			break;
238539dbbeaSderaadt 		case MGSTATUS_BUSERR:
239539dbbeaSderaadt 			mgiic_control(sc, MGCONTROL_STP, MGCONTROL_IFLG);
240539dbbeaSderaadt 			i = 0;
241539dbbeaSderaadt 			if (mgiic_poll(sc))
242539dbbeaSderaadt 				goto bail;
243539dbbeaSderaadt 			goto top;
244539dbbeaSderaadt 		case MGSTATUS_IDLE:
2454438e468Sderaadt 		default:
246539dbbeaSderaadt 			err = 1;
2474438e468Sderaadt 			goto bail;
2484438e468Sderaadt 		}
2494438e468Sderaadt 	}
250539dbbeaSderaadt 	printf("OK ");
2514438e468Sderaadt 	err = 0;
2524438e468Sderaadt bail:
253539dbbeaSderaadt 	if (err)
254539dbbeaSderaadt 		printf("BAIL STP s%02x\n", mgiic_read(sc, MGSTATUS));
255539dbbeaSderaadt 	mgiic_control(sc, MGCONTROL_STP, MGCONTROL_IFLG);
256539dbbeaSderaadt 	while (mgiic_read(sc, MGSTATUS) != MGSTATUS_IDLE)
2574438e468Sderaadt 		;
258539dbbeaSderaadt 	printf("s%02x\n", mgiic_read(sc, MGSTATUS));
2594438e468Sderaadt 	return (err);
2604438e468Sderaadt }
2614438e468Sderaadt 
2624438e468Sderaadt int
mgiic_recv(struct mgiic_softc * sc,u_int8_t addr,u_int8_t * buf,size_t len)2634438e468Sderaadt mgiic_recv(struct mgiic_softc *sc, u_int8_t addr, u_int8_t *buf, size_t len)
2644438e468Sderaadt {
265539dbbeaSderaadt 	int err = 1, i = 0;
2664438e468Sderaadt 
267539dbbeaSderaadt 	printf("recv s%02x ", mgiic_read(sc, MGSTATUS));
268539dbbeaSderaadt 	mgiic_control(sc, MGCONTROL_STA, MGCONTROL_IFLG);
2694438e468Sderaadt 	if (mgiic_poll(sc))
2704438e468Sderaadt 		goto bail;
271539dbbeaSderaadt 
272539dbbeaSderaadt 	printf("s%02x ", mgiic_read(sc, MGSTATUS));
273539dbbeaSderaadt 	if (mgiic_read(sc, MGSTATUS) != MGSTATUS_STARTSENT)
2744438e468Sderaadt 		goto bail;
2754438e468Sderaadt 
276539dbbeaSderaadt re_address:
277539dbbeaSderaadt 	mgiic_write(sc, MGDATA, (addr << 1) | 0x01);
278539dbbeaSderaadt 	printf("a%02x ", (addr << 1) | 0x01);
279539dbbeaSderaadt 	mgiic_control(sc, 0, MGCONTROL_IFLG);
2804438e468Sderaadt 
281539dbbeaSderaadt 	while (i < len) {
2824438e468Sderaadt 		if (mgiic_poll(sc))
2834438e468Sderaadt 			goto bail;
284539dbbeaSderaadt 		printf("s%02x ", mgiic_read(sc, MGSTATUS));
285539dbbeaSderaadt 		switch (mgiic_read(sc, MGSTATUS)) {
286539dbbeaSderaadt 		case MGSTATUS_ADDR_R_ACKR:
287539dbbeaSderaadt 			if (len - i > 1)
288539dbbeaSderaadt 				mgiic_control(sc, MGCONTROL_AAK, MGCONTROL_IFLG);
289539dbbeaSderaadt 			else
290539dbbeaSderaadt 				mgiic_control(sc, 0, MGCONTROL_IFLG);
2914438e468Sderaadt 			break;
292539dbbeaSderaadt 		case MGSTATUS_ADDR_R_NOACKR:
293539dbbeaSderaadt 			mgiic_control(sc, MGCONTROL_STA, MGCONTROL_IFLG);
2944438e468Sderaadt 			break;
295539dbbeaSderaadt 		case MGSTATUS_REPEATSTART:
296539dbbeaSderaadt 			goto re_address;
297539dbbeaSderaadt 		case MGSTATUS_MDATA_ACKT:
298539dbbeaSderaadt 			buf[i] = mgiic_read(sc, MGDATA);
2994438e468Sderaadt 			printf("r%02x ", buf[i]);
3004438e468Sderaadt 			i++;
301539dbbeaSderaadt 			if (len - i > 1)
302539dbbeaSderaadt 				mgiic_control(sc, MGCONTROL_AAK, MGCONTROL_IFLG);
303539dbbeaSderaadt 			else
304539dbbeaSderaadt 				mgiic_control(sc, 0, MGCONTROL_IFLG|MGCONTROL_AAK);
305539dbbeaSderaadt 			break;
306539dbbeaSderaadt 		case MGSTATUS_MDATA_NOACKT:
307539dbbeaSderaadt 			buf[i] = mgiic_read(sc, MGDATA);
308539dbbeaSderaadt 			printf("r%02x ", buf[i]);
309539dbbeaSderaadt 			i++;
310539dbbeaSderaadt 			if (len == i) {
311539dbbeaSderaadt 				printf("DONE ");
312539dbbeaSderaadt 				err = 0;
313539dbbeaSderaadt 				goto bail;
314539dbbeaSderaadt 			}
315539dbbeaSderaadt 			printf("SHORT ");
316539dbbeaSderaadt 			goto bail;
3174438e468Sderaadt 			break;
3184438e468Sderaadt 		default:
319539dbbeaSderaadt 			printf("BAD");
3204438e468Sderaadt 			goto bail;
3214438e468Sderaadt 		}
3224438e468Sderaadt 	}
323539dbbeaSderaadt 	printf("OK ");
3244438e468Sderaadt 	err = 0;
3254438e468Sderaadt bail:
326539dbbeaSderaadt 	if (err)
327539dbbeaSderaadt 		printf("BAIL STP s%02x\n", mgiic_read(sc, MGSTATUS));
328539dbbeaSderaadt 	mgiic_control(sc, MGCONTROL_STP, MGCONTROL_IFLG | MGCONTROL_AAK);
329539dbbeaSderaadt 	while (mgiic_read(sc, MGSTATUS) != MGSTATUS_IDLE)
3304438e468Sderaadt 		;
331539dbbeaSderaadt 	printf("s%02x\n", mgiic_read(sc, MGSTATUS));
3324438e468Sderaadt 	return (err);
3334438e468Sderaadt }
3344438e468Sderaadt 
3354438e468Sderaadt volatile u_int8_t
mgiic_read(struct mgiic_softc * sc,bus_size_t r)3364438e468Sderaadt mgiic_read(struct mgiic_softc *sc, bus_size_t r)
3374438e468Sderaadt {
3384438e468Sderaadt 	bus_space_barrier(sc->sc_bt, sc->sc_regh, r, 8,
3394438e468Sderaadt 	    BUS_SPACE_BARRIER_READ);
3404438e468Sderaadt 	return (bus_space_read_8(sc->sc_bt, sc->sc_regh, r)) & 0xff;
3414438e468Sderaadt }
3424438e468Sderaadt 
3434438e468Sderaadt volatile void
mgiic_write(struct mgiic_softc * sc,bus_size_t r,u_int8_t v)3444438e468Sderaadt mgiic_write(struct mgiic_softc *sc, bus_size_t r, u_int8_t v)
3454438e468Sderaadt {
3464438e468Sderaadt 	u_int64_t val = v;
3474438e468Sderaadt 
3484438e468Sderaadt 	bus_space_write_8(sc->sc_bt, sc->sc_regh, r, val);
3494438e468Sderaadt 	bus_space_barrier(sc->sc_bt, sc->sc_regh, r, 8,
3504438e468Sderaadt 	    BUS_SPACE_BARRIER_WRITE);
3514438e468Sderaadt }
3524438e468Sderaadt 
3534438e468Sderaadt volatile void
mgiic_control(struct mgiic_softc * sc,u_int8_t on,u_int8_t off)3544438e468Sderaadt mgiic_control(struct mgiic_softc *sc, u_int8_t on, u_int8_t off)
3554438e468Sderaadt {
3564438e468Sderaadt 	u_int8_t val;
3574438e468Sderaadt 
358539dbbeaSderaadt 	val = (mgiic_read(sc, MGCONTROL) | on) & ~off;
359539dbbeaSderaadt 	mgiic_write(sc, MGCONTROL, val);
3604438e468Sderaadt }
3614438e468Sderaadt 
3624438e468Sderaadt int
mgiic_poll(struct mgiic_softc * sc)3634438e468Sderaadt mgiic_poll(struct mgiic_softc *sc)
3644438e468Sderaadt {
3654438e468Sderaadt 	int		i;
3664438e468Sderaadt 
3674438e468Sderaadt 	for (i = 0; i < 1000; i++) {
368539dbbeaSderaadt 		if (mgiic_read(sc, MGCONTROL) & MGCONTROL_IFLG)
3694438e468Sderaadt 			return (0);
3704438e468Sderaadt 		delay(100);
3714438e468Sderaadt 	}
3724438e468Sderaadt 	return (1);
3734438e468Sderaadt }
374