11961a14aSEmmanuel Vadot /*-
21961a14aSEmmanuel Vadot * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
31961a14aSEmmanuel Vadot *
41961a14aSEmmanuel Vadot * Redistribution and use in source and binary forms, with or without
51961a14aSEmmanuel Vadot * modification, are permitted provided that the following conditions
61961a14aSEmmanuel Vadot * are met:
71961a14aSEmmanuel Vadot * 1. Redistributions of source code must retain the above copyright
81961a14aSEmmanuel Vadot * notice, this list of conditions and the following disclaimer.
91961a14aSEmmanuel Vadot * 2. Redistributions in binary form must reproduce the above copyright
101961a14aSEmmanuel Vadot * notice, this list of conditions and the following disclaimer in the
111961a14aSEmmanuel Vadot * documentation and/or other materials provided with the distribution.
121961a14aSEmmanuel Vadot *
131961a14aSEmmanuel Vadot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
141961a14aSEmmanuel Vadot * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
151961a14aSEmmanuel Vadot * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
161961a14aSEmmanuel Vadot * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
171961a14aSEmmanuel Vadot * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
181961a14aSEmmanuel Vadot * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
191961a14aSEmmanuel Vadot * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
201961a14aSEmmanuel Vadot * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
211961a14aSEmmanuel Vadot * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
221961a14aSEmmanuel Vadot * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
231961a14aSEmmanuel Vadot * SUCH DAMAGE.
241961a14aSEmmanuel Vadot *
251961a14aSEmmanuel Vadot */
261961a14aSEmmanuel Vadot
271961a14aSEmmanuel Vadot #include <sys/param.h>
281961a14aSEmmanuel Vadot #include <sys/systm.h>
291961a14aSEmmanuel Vadot #include <sys/bus.h>
301961a14aSEmmanuel Vadot #include <sys/malloc.h>
311961a14aSEmmanuel Vadot
321961a14aSEmmanuel Vadot #include <dev/iicbus/iicbus.h>
331961a14aSEmmanuel Vadot #include <dev/iicbus/iiconf.h>
341961a14aSEmmanuel Vadot
351961a14aSEmmanuel Vadot #include <linux/device.h>
361961a14aSEmmanuel Vadot #include <linux/i2c.h>
371961a14aSEmmanuel Vadot #include <linux/i2c-algo-bit.h>
381961a14aSEmmanuel Vadot #include <linux/list.h>
391961a14aSEmmanuel Vadot #include <linux/pci.h>
401961a14aSEmmanuel Vadot
4163641805SEmmanuel Vadot #include "iicbus_if.h"
421961a14aSEmmanuel Vadot #include "iicbb_if.h"
431961a14aSEmmanuel Vadot #include "lkpi_iic_if.h"
441961a14aSEmmanuel Vadot
451961a14aSEmmanuel Vadot static void lkpi_iicbb_setsda(device_t dev, int val);
461961a14aSEmmanuel Vadot static void lkpi_iicbb_setscl(device_t dev, int val);
471961a14aSEmmanuel Vadot static int lkpi_iicbb_getscl(device_t dev);
481961a14aSEmmanuel Vadot static int lkpi_iicbb_getsda(device_t dev);
491961a14aSEmmanuel Vadot static int lkpi_iicbb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr);
5063641805SEmmanuel Vadot static int lkpi_iicbb_pre_xfer(device_t dev);
5163641805SEmmanuel Vadot static void lkpi_iicbb_post_xfer(device_t dev);
521961a14aSEmmanuel Vadot
531961a14aSEmmanuel Vadot struct lkpi_iicbb_softc {
541961a14aSEmmanuel Vadot device_t iicbb;
551961a14aSEmmanuel Vadot struct i2c_adapter *adapter;
561961a14aSEmmanuel Vadot };
571961a14aSEmmanuel Vadot
5863641805SEmmanuel Vadot static struct sx lkpi_sx_i2cbb;
5963641805SEmmanuel Vadot
6063641805SEmmanuel Vadot static void
lkpi_sysinit_i2cbb(void * arg __unused)6163641805SEmmanuel Vadot lkpi_sysinit_i2cbb(void *arg __unused)
6263641805SEmmanuel Vadot {
6363641805SEmmanuel Vadot
6463641805SEmmanuel Vadot sx_init(&lkpi_sx_i2cbb, "lkpi-i2cbb");
6563641805SEmmanuel Vadot }
6663641805SEmmanuel Vadot
6763641805SEmmanuel Vadot static void
lkpi_sysuninit_i2cbb(void * arg __unused)6863641805SEmmanuel Vadot lkpi_sysuninit_i2cbb(void *arg __unused)
6963641805SEmmanuel Vadot {
7063641805SEmmanuel Vadot
7163641805SEmmanuel Vadot sx_destroy(&lkpi_sx_i2cbb);
7263641805SEmmanuel Vadot }
7363641805SEmmanuel Vadot
7463641805SEmmanuel Vadot SYSINIT(lkpi_i2cbb, SI_SUB_DRIVERS, SI_ORDER_ANY,
7563641805SEmmanuel Vadot lkpi_sysinit_i2cbb, NULL);
7663641805SEmmanuel Vadot SYSUNINIT(lkpi_i2cbb, SI_SUB_DRIVERS, SI_ORDER_ANY,
7763641805SEmmanuel Vadot lkpi_sysuninit_i2cbb, NULL);
7863641805SEmmanuel Vadot
791961a14aSEmmanuel Vadot static int
lkpi_iicbb_probe(device_t dev)801961a14aSEmmanuel Vadot lkpi_iicbb_probe(device_t dev)
811961a14aSEmmanuel Vadot {
821961a14aSEmmanuel Vadot
831961a14aSEmmanuel Vadot device_set_desc(dev, "LinuxKPI I2CBB");
841961a14aSEmmanuel Vadot return (BUS_PROBE_NOWILDCARD);
851961a14aSEmmanuel Vadot }
861961a14aSEmmanuel Vadot
871961a14aSEmmanuel Vadot static int
lkpi_iicbb_attach(device_t dev)881961a14aSEmmanuel Vadot lkpi_iicbb_attach(device_t dev)
891961a14aSEmmanuel Vadot {
901961a14aSEmmanuel Vadot struct lkpi_iicbb_softc *sc;
911961a14aSEmmanuel Vadot
921961a14aSEmmanuel Vadot sc = device_get_softc(dev);
931961a14aSEmmanuel Vadot sc->iicbb = device_add_child(dev, "iicbb", -1);
941961a14aSEmmanuel Vadot if (sc->iicbb == NULL) {
951961a14aSEmmanuel Vadot device_printf(dev, "Couldn't add iicbb child, aborting\n");
961961a14aSEmmanuel Vadot return (ENXIO);
971961a14aSEmmanuel Vadot }
981961a14aSEmmanuel Vadot bus_generic_attach(dev);
991961a14aSEmmanuel Vadot return (0);
1001961a14aSEmmanuel Vadot }
1011961a14aSEmmanuel Vadot
1021961a14aSEmmanuel Vadot static int
lkpi_iicbb_detach(device_t dev)1031961a14aSEmmanuel Vadot lkpi_iicbb_detach(device_t dev)
1041961a14aSEmmanuel Vadot {
1051961a14aSEmmanuel Vadot struct lkpi_iicbb_softc *sc;
1061961a14aSEmmanuel Vadot
1071961a14aSEmmanuel Vadot sc = device_get_softc(dev);
1081961a14aSEmmanuel Vadot if (sc->iicbb)
1091961a14aSEmmanuel Vadot device_delete_child(dev, sc->iicbb);
1101961a14aSEmmanuel Vadot return (0);
1111961a14aSEmmanuel Vadot }
1121961a14aSEmmanuel Vadot
1131961a14aSEmmanuel Vadot static int
lkpi_iicbb_add_adapter(device_t dev,struct i2c_adapter * adapter)1141961a14aSEmmanuel Vadot lkpi_iicbb_add_adapter(device_t dev, struct i2c_adapter *adapter)
1151961a14aSEmmanuel Vadot {
1161961a14aSEmmanuel Vadot struct lkpi_iicbb_softc *sc;
11763641805SEmmanuel Vadot struct i2c_algo_bit_data *algo_data;
1181961a14aSEmmanuel Vadot
1191961a14aSEmmanuel Vadot sc = device_get_softc(dev);
1201961a14aSEmmanuel Vadot sc->adapter = adapter;
1211961a14aSEmmanuel Vadot
12263641805SEmmanuel Vadot /*
12363641805SEmmanuel Vadot * Set iicbb timing parameters deriving speed from the protocol delay.
12463641805SEmmanuel Vadot */
12563641805SEmmanuel Vadot algo_data = adapter->algo_data;
12663641805SEmmanuel Vadot if (algo_data->udelay != 0)
12763641805SEmmanuel Vadot IICBUS_RESET(sc->iicbb, 1000000 / algo_data->udelay, 0, NULL);
1281961a14aSEmmanuel Vadot return (0);
1291961a14aSEmmanuel Vadot }
1301961a14aSEmmanuel Vadot
13125d21a84SEmmanuel Vadot static struct i2c_adapter *
lkpi_iicbb_get_adapter(device_t dev)13225d21a84SEmmanuel Vadot lkpi_iicbb_get_adapter(device_t dev)
13325d21a84SEmmanuel Vadot {
13425d21a84SEmmanuel Vadot struct lkpi_iicbb_softc *sc;
13525d21a84SEmmanuel Vadot
13625d21a84SEmmanuel Vadot sc = device_get_softc(dev);
13725d21a84SEmmanuel Vadot return (sc->adapter);
13825d21a84SEmmanuel Vadot }
13925d21a84SEmmanuel Vadot
1401961a14aSEmmanuel Vadot static device_method_t lkpi_iicbb_methods[] = {
1411961a14aSEmmanuel Vadot /* device interface */
1421961a14aSEmmanuel Vadot DEVMETHOD(device_probe, lkpi_iicbb_probe),
1431961a14aSEmmanuel Vadot DEVMETHOD(device_attach, lkpi_iicbb_attach),
1441961a14aSEmmanuel Vadot DEVMETHOD(device_detach, lkpi_iicbb_detach),
1451961a14aSEmmanuel Vadot DEVMETHOD(device_suspend, bus_generic_suspend),
1461961a14aSEmmanuel Vadot DEVMETHOD(device_resume, bus_generic_resume),
1471961a14aSEmmanuel Vadot
1481961a14aSEmmanuel Vadot /* iicbb interface */
1491961a14aSEmmanuel Vadot DEVMETHOD(iicbb_setsda, lkpi_iicbb_setsda),
1501961a14aSEmmanuel Vadot DEVMETHOD(iicbb_setscl, lkpi_iicbb_setscl),
1511961a14aSEmmanuel Vadot DEVMETHOD(iicbb_getsda, lkpi_iicbb_getsda),
1521961a14aSEmmanuel Vadot DEVMETHOD(iicbb_getscl, lkpi_iicbb_getscl),
1531961a14aSEmmanuel Vadot DEVMETHOD(iicbb_reset, lkpi_iicbb_reset),
15463641805SEmmanuel Vadot DEVMETHOD(iicbb_pre_xfer, lkpi_iicbb_pre_xfer),
15563641805SEmmanuel Vadot DEVMETHOD(iicbb_post_xfer, lkpi_iicbb_post_xfer),
1561961a14aSEmmanuel Vadot
1571961a14aSEmmanuel Vadot /* lkpi_iicbb interface */
1581961a14aSEmmanuel Vadot DEVMETHOD(lkpi_iic_add_adapter, lkpi_iicbb_add_adapter),
15925d21a84SEmmanuel Vadot DEVMETHOD(lkpi_iic_get_adapter, lkpi_iicbb_get_adapter),
1601961a14aSEmmanuel Vadot
1611961a14aSEmmanuel Vadot DEVMETHOD_END
1621961a14aSEmmanuel Vadot };
1631961a14aSEmmanuel Vadot
1641961a14aSEmmanuel Vadot driver_t lkpi_iicbb_driver = {
1651961a14aSEmmanuel Vadot "lkpi_iicbb",
1661961a14aSEmmanuel Vadot lkpi_iicbb_methods,
1671961a14aSEmmanuel Vadot sizeof(struct lkpi_iicbb_softc),
1681961a14aSEmmanuel Vadot };
1691961a14aSEmmanuel Vadot
17063641805SEmmanuel Vadot DRIVER_MODULE(lkpi_iicbb, drmn, lkpi_iicbb_driver, 0, 0);
17163641805SEmmanuel Vadot DRIVER_MODULE(lkpi_iicbb, drm, lkpi_iicbb_driver, 0, 0);
1728c13dd83SJohn Baldwin DRIVER_MODULE(iicbb, lkpi_iicbb, iicbb_driver, 0, 0);
17363641805SEmmanuel Vadot MODULE_DEPEND(linuxkpi, iicbb, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
1741961a14aSEmmanuel Vadot
1751961a14aSEmmanuel Vadot static void
lkpi_iicbb_setsda(device_t dev,int val)1761961a14aSEmmanuel Vadot lkpi_iicbb_setsda(device_t dev, int val)
1771961a14aSEmmanuel Vadot {
1781961a14aSEmmanuel Vadot struct lkpi_iicbb_softc *sc;
1791961a14aSEmmanuel Vadot struct i2c_algo_bit_data *algo_data;
1801961a14aSEmmanuel Vadot
1811961a14aSEmmanuel Vadot sc = device_get_softc(dev);
18263641805SEmmanuel Vadot algo_data = sc->adapter->algo_data;
1831961a14aSEmmanuel Vadot algo_data->setsda(algo_data->data, val);
1841961a14aSEmmanuel Vadot }
1851961a14aSEmmanuel Vadot
1861961a14aSEmmanuel Vadot static void
lkpi_iicbb_setscl(device_t dev,int val)1871961a14aSEmmanuel Vadot lkpi_iicbb_setscl(device_t dev, int val)
1881961a14aSEmmanuel Vadot {
1891961a14aSEmmanuel Vadot struct lkpi_iicbb_softc *sc;
1901961a14aSEmmanuel Vadot struct i2c_algo_bit_data *algo_data;
1911961a14aSEmmanuel Vadot
1921961a14aSEmmanuel Vadot sc = device_get_softc(dev);
19363641805SEmmanuel Vadot algo_data = sc->adapter->algo_data;
1941961a14aSEmmanuel Vadot algo_data->setscl(algo_data->data, val);
1951961a14aSEmmanuel Vadot }
1961961a14aSEmmanuel Vadot
1971961a14aSEmmanuel Vadot static int
lkpi_iicbb_getscl(device_t dev)1981961a14aSEmmanuel Vadot lkpi_iicbb_getscl(device_t dev)
1991961a14aSEmmanuel Vadot {
2001961a14aSEmmanuel Vadot struct lkpi_iicbb_softc *sc;
2011961a14aSEmmanuel Vadot struct i2c_algo_bit_data *algo_data;
20263641805SEmmanuel Vadot int ret;
2031961a14aSEmmanuel Vadot
2041961a14aSEmmanuel Vadot sc = device_get_softc(dev);
20563641805SEmmanuel Vadot algo_data = sc->adapter->algo_data;
2061961a14aSEmmanuel Vadot ret = algo_data->getscl(algo_data->data);
2071961a14aSEmmanuel Vadot return (ret);
2081961a14aSEmmanuel Vadot }
2091961a14aSEmmanuel Vadot
2101961a14aSEmmanuel Vadot static int
lkpi_iicbb_getsda(device_t dev)2111961a14aSEmmanuel Vadot lkpi_iicbb_getsda(device_t dev)
2121961a14aSEmmanuel Vadot {
2131961a14aSEmmanuel Vadot struct lkpi_iicbb_softc *sc;
2141961a14aSEmmanuel Vadot struct i2c_algo_bit_data *algo_data;
21563641805SEmmanuel Vadot int ret;
2161961a14aSEmmanuel Vadot
2171961a14aSEmmanuel Vadot sc = device_get_softc(dev);
21863641805SEmmanuel Vadot algo_data = sc->adapter->algo_data;
2191961a14aSEmmanuel Vadot ret = algo_data->getsda(algo_data->data);
2201961a14aSEmmanuel Vadot return (ret);
2211961a14aSEmmanuel Vadot }
2221961a14aSEmmanuel Vadot
2231961a14aSEmmanuel Vadot static int
lkpi_iicbb_reset(device_t dev,u_char speed,u_char addr,u_char * oldaddr)2241961a14aSEmmanuel Vadot lkpi_iicbb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
2251961a14aSEmmanuel Vadot {
2261961a14aSEmmanuel Vadot
22763641805SEmmanuel Vadot /* That doesn't seems to be supported in linux */
2281961a14aSEmmanuel Vadot return (0);
2291961a14aSEmmanuel Vadot }
2301961a14aSEmmanuel Vadot
23163641805SEmmanuel Vadot static int
lkpi_iicbb_pre_xfer(device_t dev)23263641805SEmmanuel Vadot lkpi_iicbb_pre_xfer(device_t dev)
2331961a14aSEmmanuel Vadot {
23463641805SEmmanuel Vadot struct lkpi_iicbb_softc *sc;
23563641805SEmmanuel Vadot struct i2c_algo_bit_data *algo_data;
23663641805SEmmanuel Vadot int rc = 0;
2371961a14aSEmmanuel Vadot
23863641805SEmmanuel Vadot sc = device_get_softc(dev);
23963641805SEmmanuel Vadot algo_data = sc->adapter->algo_data;
24063641805SEmmanuel Vadot if (algo_data->pre_xfer != 0)
24163641805SEmmanuel Vadot rc = algo_data->pre_xfer(sc->adapter);
24263641805SEmmanuel Vadot return (rc);
24363641805SEmmanuel Vadot }
24463641805SEmmanuel Vadot
24563641805SEmmanuel Vadot static void
lkpi_iicbb_post_xfer(device_t dev)24663641805SEmmanuel Vadot lkpi_iicbb_post_xfer(device_t dev)
24763641805SEmmanuel Vadot {
24863641805SEmmanuel Vadot struct lkpi_iicbb_softc *sc;
24963641805SEmmanuel Vadot struct i2c_algo_bit_data *algo_data;
25063641805SEmmanuel Vadot
25163641805SEmmanuel Vadot sc = device_get_softc(dev);
25263641805SEmmanuel Vadot algo_data = sc->adapter->algo_data;
25363641805SEmmanuel Vadot if (algo_data->post_xfer != NULL)
25463641805SEmmanuel Vadot algo_data->post_xfer(sc->adapter);
25563641805SEmmanuel Vadot }
25663641805SEmmanuel Vadot
25763641805SEmmanuel Vadot int
lkpi_i2cbb_transfer(struct i2c_adapter * adapter,struct i2c_msg * msgs,int nmsgs)25863641805SEmmanuel Vadot lkpi_i2cbb_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
25963641805SEmmanuel Vadot int nmsgs)
26063641805SEmmanuel Vadot {
26163641805SEmmanuel Vadot struct iic_msg *bsd_msgs;
26263641805SEmmanuel Vadot int ret = ENXIO;
26363641805SEmmanuel Vadot
26463641805SEmmanuel Vadot linux_set_current(curthread);
26563641805SEmmanuel Vadot
26663641805SEmmanuel Vadot bsd_msgs = malloc(sizeof(struct iic_msg) * nmsgs,
26763641805SEmmanuel Vadot M_DEVBUF, M_WAITOK | M_ZERO);
26863641805SEmmanuel Vadot
26963641805SEmmanuel Vadot for (int i = 0; i < nmsgs; i++) {
27063641805SEmmanuel Vadot bsd_msgs[i].slave = msgs[i].addr << 1;
27163641805SEmmanuel Vadot bsd_msgs[i].len = msgs[i].len;
27263641805SEmmanuel Vadot bsd_msgs[i].buf = msgs[i].buf;
27363641805SEmmanuel Vadot if (msgs[i].flags & I2C_M_RD)
27463641805SEmmanuel Vadot bsd_msgs[i].flags |= IIC_M_RD;
27563641805SEmmanuel Vadot if (msgs[i].flags & I2C_M_NOSTART)
27663641805SEmmanuel Vadot bsd_msgs[i].flags |= IIC_M_NOSTART;
27763641805SEmmanuel Vadot }
27863641805SEmmanuel Vadot
27963641805SEmmanuel Vadot for (int unit = 0; ; unit++) {
28063641805SEmmanuel Vadot device_t child;
28163641805SEmmanuel Vadot struct lkpi_iicbb_softc *sc;
28263641805SEmmanuel Vadot
28363641805SEmmanuel Vadot child = device_find_child(adapter->dev.parent->bsddev,
28463641805SEmmanuel Vadot "lkpi_iicbb", unit);
28563641805SEmmanuel Vadot if (child == NULL)
28663641805SEmmanuel Vadot break;
28763641805SEmmanuel Vadot if (adapter == LKPI_IIC_GET_ADAPTER(child)) {
28863641805SEmmanuel Vadot sc = device_get_softc(child);
28963641805SEmmanuel Vadot ret = IICBUS_TRANSFER(sc->iicbb, bsd_msgs, nmsgs);
29063641805SEmmanuel Vadot ret = iic2errno(ret);
29163641805SEmmanuel Vadot break;
29263641805SEmmanuel Vadot }
29363641805SEmmanuel Vadot }
29463641805SEmmanuel Vadot
29563641805SEmmanuel Vadot free(bsd_msgs, M_DEVBUF);
29663641805SEmmanuel Vadot
29763641805SEmmanuel Vadot if (ret != 0)
29863641805SEmmanuel Vadot return (-ret);
29963641805SEmmanuel Vadot return (nmsgs);
3001961a14aSEmmanuel Vadot }
3011961a14aSEmmanuel Vadot
3021961a14aSEmmanuel Vadot int
lkpi_i2c_bit_add_bus(struct i2c_adapter * adapter)3031961a14aSEmmanuel Vadot lkpi_i2c_bit_add_bus(struct i2c_adapter *adapter)
3041961a14aSEmmanuel Vadot {
3051961a14aSEmmanuel Vadot device_t lkpi_iicbb;
3061961a14aSEmmanuel Vadot int error;
3071961a14aSEmmanuel Vadot
3081961a14aSEmmanuel Vadot if (bootverbose)
3091961a14aSEmmanuel Vadot device_printf(adapter->dev.parent->bsddev,
3101961a14aSEmmanuel Vadot "Adding i2c adapter %s\n", adapter->name);
31163641805SEmmanuel Vadot sx_xlock(&lkpi_sx_i2cbb);
3121961a14aSEmmanuel Vadot lkpi_iicbb = device_add_child(adapter->dev.parent->bsddev, "lkpi_iicbb", -1);
3131961a14aSEmmanuel Vadot if (lkpi_iicbb == NULL) {
3141961a14aSEmmanuel Vadot device_printf(adapter->dev.parent->bsddev, "Couldn't add lkpi_iicbb\n");
31563641805SEmmanuel Vadot sx_xunlock(&lkpi_sx_i2cbb);
3161961a14aSEmmanuel Vadot return (ENXIO);
3171961a14aSEmmanuel Vadot }
3181961a14aSEmmanuel Vadot
31963641805SEmmanuel Vadot bus_topo_lock();
3201961a14aSEmmanuel Vadot error = bus_generic_attach(adapter->dev.parent->bsddev);
32163641805SEmmanuel Vadot bus_topo_unlock();
3221961a14aSEmmanuel Vadot if (error) {
3231961a14aSEmmanuel Vadot device_printf(adapter->dev.parent->bsddev,
3241961a14aSEmmanuel Vadot "failed to attach child: error %d\n", error);
32563641805SEmmanuel Vadot sx_xunlock(&lkpi_sx_i2cbb);
3261961a14aSEmmanuel Vadot return (ENXIO);
3271961a14aSEmmanuel Vadot }
3281961a14aSEmmanuel Vadot LKPI_IIC_ADD_ADAPTER(lkpi_iicbb, adapter);
32963641805SEmmanuel Vadot sx_xunlock(&lkpi_sx_i2cbb);
3301961a14aSEmmanuel Vadot return (0);
3311961a14aSEmmanuel Vadot }
332