Home | History | Annotate | Line # | Download | only in usb
      1 /*	$NetBSD: umcpmio_iic.c,v 1.2 2025/12/12 17:49:35 andvar Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2024, 2025 Brad Spencer <brad (at) anduin.eldar.org>
      5  *
      6  * Permission to use, copy, modify, and distribute this software for any
      7  * purpose with or without fee is hereby granted, provided that the above
      8  * copyright notice and this permission notice appear in all copies.
      9  *
     10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17  */
     18 
     19 #include <sys/cdefs.h>
     20 __KERNEL_RCSID(0, "$NetBSD: umcpmio_iic.c,v 1.2 2025/12/12 17:49:35 andvar Exp $");
     21 
     22 #ifdef _KERNEL_OPT
     23 #include "opt_usb.h"
     24 #endif
     25 
     26 #include <sys/param.h>
     27 #include <sys/types.h>
     28 
     29 #include <dev/i2c/i2cvar.h>
     30 
     31 #include <dev/usb/umcpmio.h>
     32 #include <dev/usb/umcpmio_hid_reports.h>
     33 #include <dev/usb/umcpmio_transport.h>
     34 #include <dev/usb/umcpmio_iic.h>
     35 #include <dev/usb/umcpmio_subr.h>
     36 
     37 #define UMCPMIO_DEBUG 1
     38 #ifdef UMCPMIO_DEBUG
     39 #define DPRINTF(x)	do { if (umcpmiodebug) printf x; } while (0)
     40 #define DPRINTFN(n, x)	do { if (umcpmiodebug > (n)) printf x; } while (0)
     41 extern int umcpmiodebug;
     42 #else
     43 #define DPRINTF(x)	__nothing
     44 #define DPRINTFN(n, x)	__nothing
     45 #endif
     46 
     47 /* Stuff required for the I2C part of the MCP2221 / MCP2221A */
     48 
     49 /* Clear status of the I2C engine */
     50 
     51 static void
     52 mcp2221_set_i2c_speed(struct mcp2221_status_req *req, int flags)
     53 {
     54 	int i2cbaud = MCP2221_DEFAULT_I2C_SPEED;
     55 
     56 	if (flags & I2C_F_SPEED)
     57 		i2cbaud = 400000;
     58 
     59 	req->set_i2c_speed = MCP2221_I2C_SET_SPEED;
     60 	if (i2cbaud <= 0)
     61 		i2cbaud = MCP2221_DEFAULT_I2C_SPEED;
     62 
     63 	/* Everyone and their brother seems to store the I2C divider like this,
     64 	 * so do likewise */
     65 	req->i2c_clock_divider = (MCP2221_INTERNAL_CLOCK / i2cbaud) - 3;
     66 }
     67 
     68 static int
     69 mcp2221_set_i2c_speed_one(struct umcpmio_softc *sc, int flags)
     70 {
     71 	int err = 0;
     72 	struct mcp2221_status_req req;
     73 	struct mcp2221_status_res res;
     74 
     75 	KASSERT(mutex_owned(&sc->sc_action_mutex));
     76 
     77 	memset(&req, 0, MCP2221_REQ_BUFFER_SIZE);
     78 	mcp2221_set_i2c_speed(&req, flags);
     79 	err = mcp2221_put_status(sc, &req, &res);
     80 	if (err)
     81 		goto out;
     82 	if (res.set_i2c_speed == MCP2221_I2C_SPEED_BUSY)
     83 		err = EBUSY;
     84 out:
     85 	return err;
     86 }
     87 
     88 static int
     89 mcp2221_i2c_clear(struct umcpmio_softc *sc)
     90 {
     91 	int err = 0;
     92 	struct mcp2221_status_req status_req;
     93 	struct mcp2221_status_res status_res;
     94 
     95 	KASSERT(mutex_owned(&sc->sc_action_mutex));
     96 
     97 	memset(&status_req, 0, MCP2221_REQ_BUFFER_SIZE);
     98 	status_req.cmd = MCP2221_CMD_STATUS;
     99 	status_req.cancel_transfer = MCP2221_I2C_DO_CANCEL;
    100 
    101 	err = umcpmio_send_report(sc,
    102 	    (uint8_t *) & status_req, MCP2221_REQ_BUFFER_SIZE,
    103 	    (uint8_t *) & status_res, sc->sc_cv_wait);
    104 
    105 	if (err) {
    106 		err = EIO;
    107 		goto out;
    108 	}
    109 	umcpmio_dump_buffer(sc->sc_dumpbuffer,
    110 	    (uint8_t *) & status_res, MCP2221_RES_BUFFER_SIZE,
    111 	    "mcp2221_i2c_clear buffer copy");
    112 
    113 	if (status_res.cmd != MCP2221_CMD_STATUS &&
    114 	    status_res.completion != MCP2221_CMD_COMPLETE_OK) {
    115 		err = EIO;
    116 		goto out;
    117 	}
    118 	umcpmio_dump_buffer(true,
    119 	    (uint8_t *) & status_res, MCP2221_RES_BUFFER_SIZE,
    120 	    "mcp2221_i2c_clear res buffer");
    121 
    122 out:
    123 	return err;
    124 }
    125 
    126 /*
    127  * There isn't much required to acquire or release the I2C bus, but the man
    128  * pages says these are needed
    129  */
    130 
    131 static int
    132 mcp2221_acquire_bus(void *v, int flags)
    133 {
    134 	return 0;
    135 }
    136 
    137 static void
    138 mcp2221_release_bus(void *v, int flags)
    139 {
    140 	return;
    141 }
    142 
    143 /*
    144  * The I2C write and I2C read functions mostly use an algorithm that Adafruit
    145  * came up with in their Python based driver.  A lot of other people have used
    146  * this same algorithm to good effect.  If changes are made to the I2C read and
    147  * write functions, it is HIGHLY advisable that a MCP2221 or MCP2221A be on
    148  * hand to test them.
    149  */
    150 
    151 /* This is what is considered a fatal return from the engine. */
    152 
    153 static bool
    154 mcp2221_i2c_fatal(uint8_t state)
    155 {
    156 	int r = false;
    157 
    158 	if (state == MCP2221_ENGINE_ADDRNACK ||
    159 	    state == MCP2221_ENGINE_STARTTIMEOUT ||
    160 	    state == MCP2221_ENGINE_REPSTARTTIMEOUT ||
    161 	    state == MCP2221_ENGINE_STOPTIMEOUT ||
    162 	    state == MCP2221_ENGINE_READTIMEOUT ||
    163 	    state == MCP2221_ENGINE_WRITETIMEOUT ||
    164 	    state == MCP2221_ENGINE_ADDRTIMEOUT)
    165 		r = true;
    166 	return r;
    167 }
    168 
    169 static int
    170 mcp2221_i2c_write(struct umcpmio_softc *sc, i2c_op_t op, i2c_addr_t addr,
    171     const void *cmdbuf, size_t cmdlen, void *databuf, size_t datalen,
    172     int flags)
    173 {
    174 	struct mcp2221_i2c_req i2c_req;
    175 	struct mcp2221_i2c_res i2c_res;
    176 	struct mcp2221_status_res status_res;
    177 	int remaining;
    178 	int err = 0;
    179 	uint8_t cmd;
    180 	size_t totallen = 0;
    181 	int wretry = sc->sc_retry_busy_write;
    182 	int wsretry = sc->sc_retry_busy_write;
    183 
    184 	mutex_enter(&sc->sc_action_mutex);
    185 	err = mcp2221_get_status(sc, &status_res);
    186 	mutex_exit(&sc->sc_action_mutex);
    187 	if (err)
    188 		goto out;
    189 	if (status_res.internal_i2c_state != 0) {
    190 		DPRINTF(("mcp2221_i2c_write: internal state not zero,"
    191 		    " clearing. internal_i2c_state=%02x\n",
    192 		    status_res.internal_i2c_state));
    193 		mutex_enter(&sc->sc_action_mutex);
    194 		err = mcp2221_i2c_clear(sc);
    195 		mutex_exit(&sc->sc_action_mutex);
    196 	}
    197 	if (err)
    198 		goto out;
    199 
    200 	if (cmdbuf != NULL)
    201 		totallen += cmdlen;
    202 	if (databuf != NULL)
    203 		totallen += datalen;
    204 
    205 again:
    206 	memset(&i2c_req, 0, MCP2221_REQ_BUFFER_SIZE);
    207 	cmd = MCP2221_I2C_WRITE_DATA_NS;
    208 	if (I2C_OP_STOP_P(op))
    209 		cmd = MCP2221_I2C_WRITE_DATA;
    210 	i2c_req.cmd = cmd;
    211 	i2c_req.lsblen = totallen;
    212 	i2c_req.msblen = 0;
    213 	i2c_req.slaveaddr = addr << 1;
    214 
    215 	remaining = 0;
    216 	if (cmdbuf != NULL) {
    217 		memcpy(&i2c_req.data[0], cmdbuf, cmdlen);
    218 		remaining = cmdlen;
    219 	}
    220 	if (databuf != NULL)
    221 		memcpy(&i2c_req.data[remaining], databuf, datalen);
    222 
    223 	DPRINTF(("mcp2221_i2c_write: I2C WRITE: cmd: %02x\n", cmd));
    224 	umcpmio_dump_buffer(sc->sc_dumpbuffer,
    225 	    (uint8_t *) & i2c_req, MCP2221_REQ_BUFFER_SIZE,
    226 	    "mcp2221_i2c_write: write req buffer copy");
    227 
    228 	mutex_enter(&sc->sc_action_mutex);
    229 	err = umcpmio_send_report(sc,
    230 	    (uint8_t *) & i2c_req, MCP2221_REQ_BUFFER_SIZE,
    231 	    (uint8_t *) & i2c_res, sc->sc_cv_wait);
    232 	mutex_exit(&sc->sc_action_mutex);
    233 	if (err) {
    234 		err = EIO;
    235 		goto out;
    236 	}
    237 	umcpmio_dump_buffer(sc->sc_dumpbuffer,
    238 	    (uint8_t *) & i2c_res, MCP2221_RES_BUFFER_SIZE,
    239 	    "mcp2221_i2c_write: write res buffer copy");
    240 	if (i2c_res.cmd == cmd &&
    241 	    i2c_res.completion == MCP2221_CMD_COMPLETE_OK) {
    242 		/* Adafruit does a read back of the status at this point.  We
    243 		 * choose not to do that.  That is done later anyway, and it
    244 		 * seemed to be redundant. */
    245 	} else if (i2c_res.cmd == cmd &&
    246 	    i2c_res.completion == MCP2221_I2C_ENGINE_BUSY) {
    247 		DPRINTF(("mcp2221_i2c_write:"
    248 		    " I2C engine busy\n"));
    249 
    250 		if (mcp2221_i2c_fatal(i2c_res.internal_i2c_state)) {
    251 			err = EIO;
    252 			goto out;
    253 		}
    254 		wretry--;
    255 		if (wretry > 0) {
    256 			WAITMS(sc->sc_busy_delay);
    257 			goto again;
    258 		} else {
    259 			err = EBUSY;
    260 			goto out;
    261 		}
    262 	} else {
    263 		err = EIO;
    264 		goto out;
    265 	}
    266 
    267 	while (wsretry > 0) {
    268 		wsretry--;
    269 
    270 		DPRINTF(("mcp2221_i2c_write: checking status loop:"
    271 		    " wcretry=%d\n", wsretry));
    272 
    273 		mutex_enter(&sc->sc_action_mutex);
    274 		err = mcp2221_get_status(sc, &status_res);
    275 		mutex_exit(&sc->sc_action_mutex);
    276 		if (err) {
    277 			err = EIO;
    278 			break;
    279 		}
    280 		umcpmio_dump_buffer(sc->sc_dumpbuffer,
    281 		    (uint8_t *) & status_res,
    282 		    MCP2221_RES_BUFFER_SIZE,
    283 		    "mcp2221_i2c_write post check status");
    284 		/* Since there isn't any documentation on what some of the
    285 		 * internal state means, it isn't clear that this is any
    286 		 * different than than MCP2221_ENGINE_ADDRNACK in the other
    287 		 * state register. */
    288 
    289 		if (status_res.internal_i2c_state20 &
    290 		    MCP2221_ENGINE_T1_MASK_NACK) {
    291 			DPRINTF(("mcp2221_i2c_write post check:"
    292 			    " engine internal state T1 says NACK\n"));
    293 			err = EIO;
    294 			break;
    295 		}
    296 		if (status_res.internal_i2c_state == 0) {
    297 			DPRINTF(("mcp2221_i2c_write post check:"
    298 			    " engine internal state is ZERO\n"));
    299 			err = 0;
    300 			break;
    301 		}
    302 		if (status_res.internal_i2c_state ==
    303 		    MCP2221_ENGINE_WRITINGNOSTOP &&
    304 		    cmd == MCP2221_I2C_WRITE_DATA_NS) {
    305 			DPRINTF(("mcp2221_i2c_write post check:"
    306 			    " engine internal state is WRITINGNOSTOP\n"));
    307 			err = 0;
    308 			break;
    309 		}
    310 		if (mcp2221_i2c_fatal(status_res.internal_i2c_state)) {
    311 			DPRINTF(("mcp2221_i2c_write post check:"
    312 			    " engine internal state is fatal: %02x\n",
    313 			    status_res.internal_i2c_state));
    314 			err = EIO;
    315 			break;
    316 		}
    317 		WAITMS(sc->sc_busy_delay);
    318 	}
    319 
    320 out:
    321 	return err;
    322 }
    323 
    324 /*
    325  * This one deviates a bit from Adafruit in that is supports a straight
    326  * read and a write + read.  That is, write a register to read from and
    327  * then do the read.
    328  */
    329 
    330 static int
    331 mcp2221_i2c_read(struct umcpmio_softc *sc, i2c_op_t op, i2c_addr_t addr,
    332     const void *cmdbuf, size_t cmdlen, void *databuf, size_t datalen, int
    333     flags)
    334 {
    335 	struct mcp2221_i2c_req i2c_req;
    336 	struct mcp2221_i2c_res i2c_res;
    337 	struct mcp2221_i2c_fetch_req i2c_fetch_req;
    338 	struct mcp2221_i2c_fetch_res i2c_fetch_res;
    339 	struct mcp2221_status_res status_res;
    340 	int err = 0;
    341 	uint8_t cmd;
    342 	int rretry = sc->sc_retry_busy_read;
    343 
    344 	if (cmdbuf != NULL) {
    345 		DPRINTF(("mcp2221_i2c_read: has a cmdbuf, doing write first:"
    346 		    " addr=%02x\n", addr));
    347 		err = mcp2221_i2c_write(sc, I2C_OP_WRITE, addr, cmdbuf, cmdlen,
    348 		    NULL, 0, flags);
    349 	}
    350 	if (err)
    351 		goto out;
    352 
    353 	mutex_enter(&sc->sc_action_mutex);
    354 	err = mcp2221_get_status(sc, &status_res);
    355 	mutex_exit(&sc->sc_action_mutex);
    356 	if (err)
    357 		goto out;
    358 
    359 	if (status_res.internal_i2c_state != 0 &&
    360 	    status_res.internal_i2c_state != MCP2221_ENGINE_WRITINGNOSTOP) {
    361 		DPRINTF(("mcp2221_i2c_read:"
    362 		    " internal state not zero and not WRITINGNOSTOP,"
    363 		    " clearing. internal_i2c_state=%02x\n",
    364 		    status_res.internal_i2c_state));
    365 		mutex_enter(&sc->sc_action_mutex);
    366 		err = mcp2221_i2c_clear(sc);
    367 		mutex_exit(&sc->sc_action_mutex);
    368 	}
    369 	if (err)
    370 		goto out;
    371 
    372 	memset(&i2c_req, 0, MCP2221_REQ_BUFFER_SIZE);
    373 	if (cmdbuf == NULL &&
    374 	    status_res.internal_i2c_state != MCP2221_ENGINE_WRITINGNOSTOP) {
    375 		cmd = MCP2221_I2C_READ_DATA;
    376 	} else {
    377 		cmd = MCP2221_I2C_READ_DATA_RS;
    378 	}
    379 
    380 	/* The chip apparently can't do a READ without a STOP operation. Report
    381 	 * that, and try treating it like a READ with a STOP.  This won't work
    382 	 * for a lot of devices. */
    383 
    384 	if (!I2C_OP_STOP_P(op) && sc->sc_reportreadnostop) {
    385 		device_printf(sc->sc_dev,
    386 		    "mcp2221_i2c_read: ************ called with READ"
    387 		    " without STOP ***************\n");
    388 	}
    389 	i2c_req.cmd = cmd;
    390 	i2c_req.lsblen = datalen;
    391 	i2c_req.msblen = 0;
    392 	i2c_req.slaveaddr = (addr << 1) | 0x01;
    393 
    394 	DPRINTF(("mcp2221_i2c_read: I2C READ normal read:"
    395 	    " cmd=%02x, addr=%02x\n", cmd, addr));
    396 
    397 	umcpmio_dump_buffer(sc->sc_dumpbuffer,
    398 	    (uint8_t *) & i2c_req, MCP2221_RES_BUFFER_SIZE,
    399 	    "mcp2221_i2c_read normal read req buffer copy");
    400 
    401 	mutex_enter(&sc->sc_action_mutex);
    402 	err = umcpmio_send_report(sc,
    403 	    (uint8_t *) & i2c_req, MCP2221_REQ_BUFFER_SIZE,
    404 	    (uint8_t *) & i2c_res, sc->sc_cv_wait);
    405 	mutex_exit(&sc->sc_action_mutex);
    406 
    407 	if (err) {
    408 		err = EIO;
    409 		goto out;
    410 	}
    411 	umcpmio_dump_buffer(sc->sc_dumpbuffer,
    412 	    (uint8_t *) & i2c_res, MCP2221_RES_BUFFER_SIZE,
    413 	    "mcp2221_i2c_read read-request response buffer copy");
    414 
    415 	while (rretry > 0) {
    416 		rretry--;
    417 		DPRINTF(("mcp2221_i2c_read: fetch loop: rretry=%d\n", rretry));
    418 		err = 0;
    419 		memset(&i2c_fetch_req, 0, MCP2221_REQ_BUFFER_SIZE);
    420 		i2c_fetch_req.cmd = MCP2221_CMD_I2C_FETCH_READ_DATA;
    421 		mutex_enter(&sc->sc_action_mutex);
    422 		err = umcpmio_send_report(sc,
    423 		    (uint8_t *) & i2c_fetch_req, MCP2221_REQ_BUFFER_SIZE,
    424 		    (uint8_t *) & i2c_fetch_res, sc->sc_cv_wait);
    425 		mutex_exit(&sc->sc_action_mutex);
    426 		umcpmio_dump_buffer(sc->sc_dumpbuffer,
    427 		    (uint8_t *) & i2c_fetch_req, MCP2221_RES_BUFFER_SIZE,
    428 		    "mcp2221_i2c_read fetch res buffer copy");
    429 
    430 		if (i2c_fetch_res.cmd != MCP2221_CMD_I2C_FETCH_READ_DATA) {
    431 			err = EIO;
    432 			break;
    433 		}
    434 		if (i2c_fetch_res.completion ==
    435 		    MCP2221_FETCH_READ_PARTIALDATA ||
    436 		    i2c_fetch_res.fetchlen == MCP2221_FETCH_READERROR) {
    437 			DPRINTF(("mcp2221_i2c_read: fetch loop:"
    438 			    " partial data or read error:"
    439 			    " completion=%02x, fetchlen=%02x\n",
    440 			    i2c_fetch_res.completion,
    441 			    i2c_fetch_res.fetchlen));
    442 			WAITMS(sc->sc_busy_delay);
    443 			err = EAGAIN;
    444 			continue;
    445 		}
    446 		if (i2c_fetch_res.internal_i2c_state ==
    447 		    MCP2221_ENGINE_ADDRNACK) {
    448 			DPRINTF(("mcp2221_i2c_read:"
    449 			    " fetch loop: engine NACK\n"));
    450 			err = EIO;
    451 			break;
    452 		}
    453 		if (i2c_fetch_res.internal_i2c_state == 0 &&
    454 		    i2c_fetch_res.fetchlen == 0) {
    455 			DPRINTF(("mcp2221_i2c_read: fetch loop:"
    456 			    " internal state and fetch len are ZERO\n"));
    457 			err = 0;
    458 			break;
    459 		}
    460 		if (i2c_fetch_res.internal_i2c_state ==
    461 		    MCP2221_ENGINE_READPARTIAL ||
    462 		    i2c_fetch_res.internal_i2c_state ==
    463 		    MCP2221_ENGINE_READCOMPLETE) {
    464 			DPRINTF(("mcp2221_i2c_read:"
    465 			    " fetch loop: read partial or"
    466 			    " read complete: internal_i2c_state=%02x\n",
    467 			    i2c_fetch_res.internal_i2c_state));
    468 			err = 0;
    469 			break;
    470 		}
    471 	}
    472 	if (err == EAGAIN)
    473 		err = ETIMEDOUT;
    474 	if (err)
    475 		goto out;
    476 
    477 	if (databuf == NULL ||
    478 	    i2c_fetch_res.fetchlen == MCP2221_FETCH_READERROR) {
    479 		DPRINTF(("mcp2221_i2c_read: copy data:"
    480 		    " databuf is NULL\n"));
    481 		goto out;
    482 	}
    483 	const int size = uimin(i2c_fetch_res.fetchlen, datalen);
    484 	DPRINTF(("mcp2221_i2c_read: copy data: size=%d, fetchlen=%d\n",
    485 	    size, i2c_fetch_res.fetchlen));
    486 	if (size > 0) {
    487 		memcpy(databuf, &i2c_fetch_res.data[0], size);
    488 	}
    489 out:
    490 	return err;
    491 }
    492 
    493 static int
    494 mcp2221_i2c_exec(void *v, i2c_op_t op, i2c_addr_t addr, const void *cmdbuf,
    495     size_t cmdlen, void *databuf, size_t datalen, int flags)
    496 {
    497 	struct umcpmio_softc *sc = v;
    498 	size_t totallen = 0;
    499 	int err = 0;
    500 
    501 	if (sc->sc_dying)
    502 		return EIO;
    503 
    504 	if (addr > 0x7f)
    505 		return ENOTSUP;
    506 
    507 	if (cmdbuf != NULL)
    508 		totallen += cmdlen;
    509 	if (databuf != NULL)
    510 		totallen += datalen;
    511 
    512 	/* There is a way to do a transfer that is larger than 60 bytes, but it
    513 	 * requires that your break the transfer up into pieces and send them
    514 	 * in 60 byte chunks.  We just won't support that right now. It would
    515 	 * be somewhat unusual for there to be a transfer that big, unless you
    516 	 * are trying to do block transfers and that isn't natively supported
    517 	 * by the chip anyway...  so those have to be broken up and sent as
    518 	 * bytes. */
    519 
    520 	if (totallen > 60)
    521 		return ENOTSUP;
    522 
    523 	if (I2C_OP_WRITE_P(op)) {
    524 		err = mcp2221_i2c_write(sc, op, addr, cmdbuf, cmdlen,
    525 		    databuf, datalen, flags);
    526 
    527 		DPRINTF(("umcpmio_exec: I2C WRITE: err=%d\n", err));
    528 	} else {
    529 		err = mcp2221_i2c_read(sc, op, addr, cmdbuf, cmdlen,
    530 		    databuf, datalen, flags);
    531 
    532 		DPRINTF(("umcpmio_exec: I2C READ: err=%d\n", err));
    533 	}
    534 
    535 	return err;
    536 }
    537 
    538 int
    539 umcpmio_i2c_attach(struct umcpmio_softc *sc)
    540 {
    541 	sc->sc_reportreadnostop = true;
    542 	sc->sc_busy_delay = 1;
    543 	sc->sc_retry_busy_read = 50;
    544 	sc->sc_retry_busy_write = 50;
    545 
    546 	int err = 0;
    547 
    548 	/* The datasheet suggests that it is possible for this to fail if the
    549 	 * I2C port is currently being used. However...  since you just plugged
    550 	 * in the chip, the I2C port should not really be in use at that
    551 	 * moment. In any case, try hard to set this and don't make it fatal if
    552 	 * it did not get set. */
    553 	int i2cspeed;
    554 	for (i2cspeed = 0; i2cspeed < 3; i2cspeed++) {
    555 		mutex_enter(&sc->sc_action_mutex);
    556 		err = mcp2221_set_i2c_speed_one(sc, I2C_SPEED_SM);
    557 		mutex_exit(&sc->sc_action_mutex);
    558 		if (err) {
    559 			aprint_error_dev(sc->sc_dev, "umcpmio_i2c_attach:"
    560 			    " set I2C speed: err=%d\n",
    561 			    err);
    562 			delay(300);
    563 		}
    564 		break;
    565 	}
    566 
    567 	iic_tag_init(&sc->sc_i2c_tag);
    568 	sc->sc_i2c_tag.ic_cookie = sc;
    569 	sc->sc_i2c_tag.ic_acquire_bus = mcp2221_acquire_bus;
    570 	sc->sc_i2c_tag.ic_release_bus = mcp2221_release_bus;
    571 	sc->sc_i2c_tag.ic_exec = mcp2221_i2c_exec;
    572 
    573 	sc->sc_i2c_dev = iicbus_attach(sc->sc_dev, &sc->sc_i2c_tag);
    574 
    575 	return err;
    576 }
    577