Home | History | Annotate | Line # | Download | only in i2c
      1 /*	$NetBSD: i2c.c,v 1.99 2025/09/18 02:51:04 thorpej Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2003 Wasabi Systems, Inc.
      5  * All rights reserved.
      6  *
      7  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *      This product includes software developed for the NetBSD Project by
     20  *      Wasabi Systems, Inc.
     21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     22  *    or promote products derived from this software without specific prior
     23  *    written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 
     38 #ifdef _KERNEL_OPT
     39 #include "opt_i2c.h"
     40 
     41 #include "opt_fdt.h"
     42 #ifdef FDT
     43 #define	I2C_USE_FDT
     44 #endif /* FDT */
     45 
     46 #if defined(__aarch64__) || defined(__amd64__)
     47 #include "acpica.h"
     48 #if NACPICA > 0
     49 #define	I2C_USE_ACPI
     50 #endif /* NACPICA > 0 */
     51 #endif /* __aarch64__ || __amd64__ */
     52 
     53 #endif /* _KERNEL_OPT */
     54 
     55 #include <sys/cdefs.h>
     56 __KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.99 2025/09/18 02:51:04 thorpej Exp $");
     57 
     58 #include <sys/param.h>
     59 #include <sys/systm.h>
     60 #include <sys/device.h>
     61 #include <sys/event.h>
     62 #include <sys/conf.h>
     63 #include <sys/malloc.h>
     64 #include <sys/kmem.h>
     65 #include <sys/kthread.h>
     66 #include <sys/proc.h>
     67 #include <sys/kernel.h>
     68 #include <sys/fcntl.h>
     69 #include <sys/module.h>
     70 #include <sys/once.h>
     71 #include <sys/mutex.h>
     72 
     73 #ifdef I2C_USE_ACPI
     74 #include <dev/acpi/acpivar.h>
     75 #include <dev/acpi/acpi_i2c.h>
     76 #endif /* I2C_USE_ACPI */
     77 
     78 #ifdef I2C_USE_FDT
     79 #include <dev/fdt/fdtvar.h>
     80 #include <dev/fdt/fdt_i2c.h>
     81 #endif /* I2C_USE_FDT */
     82 
     83 #include <dev/i2c/i2cvar.h>
     84 
     85 #include "ioconf.h"
     86 #include "locators.h"
     87 
     88 #ifndef I2C_MAX_ADDR
     89 #define I2C_MAX_ADDR	0x3ff	/* 10-bit address, max */
     90 #endif
     91 
     92 struct iic_softc {
     93 	device_t sc_dev;
     94 	i2c_tag_t sc_tag;
     95 	device_t sc_devices[I2C_MAX_ADDR + 1];
     96 };
     97 
     98 static dev_type_open(iic_open);
     99 static dev_type_close(iic_close);
    100 static dev_type_ioctl(iic_ioctl);
    101 
    102 int iic_init(void);
    103 
    104 kmutex_t iic_mtx;
    105 int iic_refcnt;
    106 
    107 ONCE_DECL(iic_once);
    108 
    109 const struct cdevsw iic_cdevsw = {
    110 	.d_open = iic_open,
    111 	.d_close = iic_close,
    112 	.d_read = noread,
    113 	.d_write = nowrite,
    114 	.d_ioctl = iic_ioctl,
    115 	.d_stop = nostop,
    116 	.d_tty = notty,
    117 	.d_poll = nopoll,
    118 	.d_mmap = nommap,
    119 	.d_kqfilter = nokqfilter,
    120 	.d_discard = nodiscard,
    121 	.d_flag = D_OTHER
    122 };
    123 
    124 static void	iic_fill_compat(struct i2c_attach_args*, const char*,
    125 			size_t, char **);
    126 
    127 static int
    128 iic_print_direct(void *aux, const char *pnp)
    129 {
    130 	struct i2c_attach_args *ia = aux;
    131 
    132 	if (pnp != NULL)
    133 		aprint_normal("%s%s%s%s at %s addr 0x%02x",
    134 			      ia->ia_name ? ia->ia_name : "(unknown)",
    135 			      ia->ia_ncompat ? " (" : "",
    136 			      ia->ia_ncompat ? ia->ia_compat[0] : "",
    137 			      ia->ia_ncompat ? ")" : "",
    138 			      pnp, ia->ia_addr);
    139 	else
    140 		aprint_normal(" addr 0x%02x", ia->ia_addr);
    141 
    142 	return UNCONF;
    143 }
    144 
    145 static int
    146 iic_print(void *aux, const char *pnp)
    147 {
    148 	struct i2c_attach_args *ia = aux;
    149 
    150 	if (ia->ia_addr != (i2c_addr_t)IICCF_ADDR_DEFAULT)
    151 		aprint_normal(" addr 0x%x", ia->ia_addr);
    152 
    153 	return UNCONF;
    154 }
    155 
    156 static bool
    157 iic_is_special_address(i2c_addr_t addr)
    158 {
    159 
    160 	/*
    161 	 * See: https://www.i2c-bus.org/addressing/
    162 	 */
    163 
    164 	/* General Call (read) / Start Byte (write) */
    165 	if (addr == 0x00)
    166 		return (true);
    167 
    168 	/* CBUS Addresses */
    169 	if (addr == 0x01)
    170 		return (true);
    171 
    172 	/* Reserved for Different Bus Formats */
    173 	if (addr == 0x02)
    174 		return (true);
    175 
    176 	/* Reserved for future purposes */
    177 	if (addr == 0x03)
    178 		return (true);
    179 
    180 	/* High Speed Master Code */
    181 	if ((addr & 0x7c) == 0x04)
    182 		return (true);
    183 
    184 	/* 10-bit Slave Addressing prefix */
    185 	if ((addr & 0x7c) == 0x78)
    186 		return (true);
    187 
    188 	/* Reserved for future purposes */
    189 	if ((addr & 0x7c) == 0x7c)
    190 		return (true);
    191 
    192 	return (false);
    193 }
    194 
    195 static int
    196 iic_probe_none(struct iic_softc *sc,
    197 	       const struct i2c_attach_args *ia, int flags)
    198 {
    199 
    200 	return (0);
    201 }
    202 
    203 static int
    204 iic_probe_smbus_quick_write(struct iic_softc *sc,
    205 			    const struct i2c_attach_args *ia, int flags)
    206 {
    207 	int error;
    208 
    209 	if ((error = iic_acquire_bus(ia->ia_tag, flags)) == 0) {
    210 		error = iic_smbus_quick_write(ia->ia_tag, ia->ia_addr, flags);
    211 	}
    212 	(void) iic_release_bus(ia->ia_tag, flags);
    213 
    214 	return (error);
    215 }
    216 
    217 static int
    218 iic_probe_smbus_receive_byte(struct iic_softc *sc,
    219 			     const struct i2c_attach_args *ia, int flags)
    220 {
    221 	int error;
    222 
    223 	if ((error = iic_acquire_bus(ia->ia_tag, flags)) == 0) {
    224 		uint8_t dummy;
    225 
    226 		error = iic_smbus_receive_byte(ia->ia_tag, ia->ia_addr,
    227 					       &dummy, flags);
    228 	}
    229 	(void) iic_release_bus(ia->ia_tag, flags);
    230 
    231 	return (error);
    232 }
    233 
    234 static bool
    235 iic_indirect_driver_is_permitted(struct iic_softc *sc, cfdata_t cf)
    236 {
    237 	prop_object_iterator_t iter;
    238 	prop_array_t permitlist;
    239 	prop_string_t pstr;
    240 	prop_type_t ptype;
    241 	bool rv = false;
    242 
    243 	permitlist = prop_dictionary_get(device_properties(sc->sc_dev),
    244 					 I2C_PROP_INDIRECT_DEVICE_PERMITLIST);
    245 	if (permitlist == NULL) {
    246 		/* No permitlist -> everything allowed */
    247 		return (true);
    248 	}
    249 
    250 	if ((ptype = prop_object_type(permitlist)) != PROP_TYPE_ARRAY) {
    251 		aprint_error_dev(sc->sc_dev,
    252 		    "invalid property type (%d) for '%s'; must be array (%d)\n",
    253 		    ptype, I2C_PROP_INDIRECT_DEVICE_PERMITLIST,
    254 		    PROP_TYPE_ARRAY);
    255 		return (false);
    256 	}
    257 
    258 	iter = prop_array_iterator(permitlist);
    259 	while ((pstr = prop_object_iterator_next(iter)) != NULL) {
    260 		if (prop_string_equals_string(pstr, cf->cf_name)) {
    261 			rv = true;
    262 			break;
    263 		}
    264 	}
    265 	prop_object_iterator_release(iter);
    266 
    267 	return (rv);
    268 }
    269 
    270 static int
    271 iic_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
    272 {
    273 	struct iic_softc *sc = device_private(parent);
    274 	struct i2c_attach_args ia;
    275 	int (*probe_func)(struct iic_softc *,
    276 			  const struct i2c_attach_args *, int);
    277 	prop_string_t pstr;
    278 	i2c_addr_t first_addr, last_addr;
    279 
    280 	/*
    281 	 * Before we do any more work, consult the allowed-driver
    282 	 * permit-list for this bus (if any).
    283 	 */
    284 	if (iic_indirect_driver_is_permitted(sc, cf) == false)
    285 		return (0);
    286 
    287 	/* default to "quick write". */
    288 	probe_func = iic_probe_smbus_quick_write;
    289 
    290 	pstr = prop_dictionary_get(device_properties(sc->sc_dev),
    291 				   I2C_PROP_INDIRECT_PROBE_STRATEGY);
    292 	if (pstr == NULL) {
    293 		/* Use the default. */
    294 	} else if (prop_string_equals_string(pstr,
    295 					I2C_PROBE_STRATEGY_QUICK_WRITE)) {
    296 		probe_func = iic_probe_smbus_quick_write;
    297 	} else if (prop_string_equals_string(pstr,
    298 					I2C_PROBE_STRATEGY_RECEIVE_BYTE)) {
    299 		probe_func = iic_probe_smbus_receive_byte;
    300 	} else if (prop_string_equals_string(pstr,
    301 					I2C_PROBE_STRATEGY_NONE)) {
    302 		probe_func = iic_probe_none;
    303 	} else {
    304 		aprint_error_dev(sc->sc_dev,
    305 			"unknown probe strategy '%s'; defaulting to '%s'\n",
    306 			prop_string_value(pstr),
    307 			I2C_PROBE_STRATEGY_QUICK_WRITE);
    308 
    309 		/* Use the default. */
    310 	}
    311 
    312 	ia.ia_tag = sc->sc_tag;
    313 
    314 	ia.ia_name = NULL;
    315 	ia.ia_ncompat = 0;
    316 	ia.ia_compat = NULL;
    317 	ia.ia_prop = NULL;
    318 
    319 	if (cf->cf_loc[IICCF_ADDR] == IICCF_ADDR_DEFAULT) {
    320 		/*
    321 		 * This particular config directive has
    322 		 * wildcarded the address, so we will
    323 		 * scan the entire bus for it.
    324 		 */
    325 		first_addr = 0;
    326 		last_addr = I2C_MAX_ADDR;
    327 	} else {
    328 		/*
    329 		 * This config directive hard-wires the i2c
    330 		 * bus address for the device, so there is
    331 		 * no need to go poking around at any other
    332 		 * addresses.
    333 		 */
    334 		if (cf->cf_loc[IICCF_ADDR] < 0 ||
    335 		    cf->cf_loc[IICCF_ADDR] > I2C_MAX_ADDR) {
    336 			/* Invalid config directive! */
    337 			return (0);
    338 		}
    339 		first_addr = last_addr = cf->cf_loc[IICCF_ADDR];
    340 	}
    341 
    342 	for (ia.ia_addr = first_addr; ia.ia_addr <= last_addr; ia.ia_addr++) {
    343 		int error, match_result;
    344 
    345 		/*
    346 		 * Skip I2C addresses that are reserved for
    347 		 * special purposes.
    348 		 */
    349 		if (iic_is_special_address(ia.ia_addr))
    350 			continue;
    351 
    352 		/*
    353 		 * Skip addresses where a device is already attached.
    354 		 */
    355 		if (sc->sc_devices[ia.ia_addr] != NULL)
    356 			continue;
    357 
    358 		/*
    359 		 * Call the "match" routine for the device.  If that
    360 		 * returns success, then call the probe strategy
    361 		 * function.
    362 		 *
    363 		 * We do it in this order because i2c devices tend
    364 		 * to be found at a small number of possible addresses
    365 		 * (e.g. read-time clocks that are only ever found at
    366 		 * 0x68).  This gives the driver a chance to skip any
    367 		 * address that are not valid for the device, saving
    368 		 * us from having to poke at the bus to see if anything
    369 		 * is there.
    370 		 */
    371 		match_result = config_probe(parent, cf, &ia);/*XXX*/
    372 		if (match_result <= 0)
    373 			continue;
    374 
    375 		/*
    376 		 * If the quality of the match by the driver was low
    377 		 * (i.e. matched on being a valid address only, didn't
    378 		 * perform any hardware probe), invoke our probe routine
    379 		 * to see if it looks like something is really there.
    380 		 */
    381 		if (match_result == I2C_MATCH_ADDRESS_ONLY &&
    382 		    (error = (*probe_func)(sc, &ia, 0)) != 0)
    383 			continue;
    384 
    385 		sc->sc_devices[ia.ia_addr] =
    386 		    config_attach(parent, cf, &ia, iic_print, CFARGS_NONE);
    387 	}
    388 
    389 	return 0;
    390 }
    391 
    392 static void
    393 iic_child_detach(device_t parent, device_t child)
    394 {
    395 	struct iic_softc *sc = device_private(parent);
    396 	int i;
    397 
    398 	for (i = 0; i <= I2C_MAX_ADDR; i++)
    399 		if (sc->sc_devices[i] == child) {
    400 			sc->sc_devices[i] = NULL;
    401 			break;
    402 		}
    403 }
    404 
    405 static int
    406 iic_rescan(device_t self, const char *ifattr, const int *locators)
    407 {
    408 	config_search(self, NULL,
    409 	    CFARGS(.search = iic_search,
    410 		   .locators = locators));
    411 	return 0;
    412 }
    413 
    414 static int
    415 iic_match(device_t parent, cfdata_t cf, void *aux)
    416 {
    417 
    418 	return 1;
    419 }
    420 
    421 static bool
    422 iic_attach_children_direct(struct iic_softc *sc)
    423 {
    424 	device_t parent = device_parent(sc->sc_dev);
    425 	devhandle_t devhandle = device_handle(sc->sc_dev);
    426 	prop_array_t child_devices;
    427 	i2c_tag_t ic = sc->sc_tag;
    428 	bool no_indirect_config;
    429 
    430 	child_devices = prop_dictionary_get(device_properties(parent),
    431 					    "i2c-child-devices");
    432 	if (!prop_dictionary_get_bool(device_properties(parent),
    433 				      "i2c-no-indirect-config",
    434 				      &no_indirect_config)) {
    435 		no_indirect_config = false;
    436 	}
    437 
    438 	if (child_devices == NULL) {
    439 		switch (devhandle_type(devhandle)) {
    440 #ifdef I2C_USE_ACPI
    441 		case DEVHANDLE_TYPE_ACPI:
    442 			child_devices = acpi_copy_i2c_devs(sc->sc_dev);
    443 			no_indirect_config = true;
    444 			break;
    445 #endif
    446 #ifdef I2C_USE_FDT
    447 		case DEVHANDLE_TYPE_OF:
    448 			child_devices = fdtbus_copy_i2c_devs(sc->sc_dev);
    449 			no_indirect_config = true;
    450 			break;
    451 #endif
    452 		default:
    453 			break;
    454 		}
    455 	} else {
    456 		prop_object_retain(child_devices);
    457 	}
    458 
    459 	if (child_devices) {
    460 		unsigned int i, count;
    461 		prop_dictionary_t dev;
    462 		prop_data_t cdata;
    463 		uint32_t addr;
    464 		const char *name;
    465 		char *buf;
    466 		struct i2c_attach_args ia;
    467 		devhandle_t child_devhandle;
    468 		int loc[IICCF_NLOCS];
    469 		const void *vptr;
    470 		size_t vsize;
    471 
    472 		memset(loc, 0, sizeof loc);
    473 		count = prop_array_count(child_devices);
    474 		for (i = 0; i < count; i++) {
    475 			dev = prop_array_get(child_devices, i);
    476 			if (!dev) continue;
    477  			if (!prop_dictionary_get_string(
    478 			    dev, "name", &name)) {
    479 				/* "name" property is optional. */
    480 				name = NULL;
    481 			}
    482 			if (!prop_dictionary_get_uint32(dev, "addr", &addr))
    483 				continue;
    484 			vptr = NULL;
    485 			if (prop_dictionary_get_data(dev, "devhandle",
    486 						     &vptr, &vsize)) {
    487 				if (vsize != sizeof(child_devhandle)) {
    488 					vptr = NULL;
    489 				}
    490 			}
    491 			if (vptr != NULL) {
    492 				memcpy(&child_devhandle, vptr,
    493 				    sizeof(child_devhandle));
    494 			} else {
    495 				child_devhandle = devhandle_invalid();
    496 			}
    497 			loc[IICCF_ADDR] = addr;
    498 
    499 			memset(&ia, 0, sizeof ia);
    500 			ia.ia_addr = addr;
    501 			ia.ia_tag = ic;
    502 			ia.ia_name = name;
    503 
    504 			/* XXX Gross, but good enough until these are gone. */
    505 			ia.__xxx_ia_cookie =
    506 			    (uint64_t)child_devhandle.uintptr;
    507 			switch (devhandle_type(child_devhandle)) {
    508 			case DEVHANDLE_TYPE_ACPI:
    509 				ia.__xxx_ia_cookietype = I2C_COOKIE_ACPI;
    510 				break;
    511 			case DEVHANDLE_TYPE_OF:
    512 				ia.__xxx_ia_cookietype = I2C_COOKIE_OF;
    513 				break;
    514 			default:
    515 				ia.__xxx_ia_cookietype = I2C_COOKIE_NONE;
    516 				break;
    517 			}
    518 			ia.ia_prop = dev;
    519 
    520 			buf = NULL;
    521 			cdata = prop_dictionary_get(dev, "compatible");
    522 			if (cdata)
    523 				iic_fill_compat(&ia,
    524 				    prop_data_value(cdata),
    525 				    prop_data_size(cdata), &buf);
    526 
    527 			if (name == NULL && cdata == NULL) {
    528 				aprint_error_dev(sc->sc_dev,
    529 				    "WARNING: ignoring bad child device entry "
    530 				    "for address 0x%02x\n", addr);
    531 			} else {
    532 				if (addr > I2C_MAX_ADDR) {
    533 					aprint_error_dev(sc->sc_dev,
    534 					    "WARNING: ignoring bad device "
    535 					    "address @ 0x%02x\n", addr);
    536 				} else if (sc->sc_devices[addr] == NULL) {
    537 					sc->sc_devices[addr] =
    538 					    config_found(sc->sc_dev, &ia,
    539 					    iic_print_direct,
    540 					    CFARGS(.locators = loc,
    541 						   .devhandle = child_devhandle));
    542 				}
    543 			}
    544 
    545 			if (ia.ia_compat)
    546 				free(ia.ia_compat, M_TEMP);
    547 			if (buf)
    548 				free(buf, M_TEMP);
    549 		}
    550 		prop_object_release(child_devices);
    551 		child_devices = NULL;
    552 	}
    553 
    554 	/*
    555 	 * We return "true" if we want to let indirect configuration
    556 	 * proceed.
    557 	 */
    558 	return !no_indirect_config;
    559 }
    560 
    561 static void
    562 iic_attach(device_t parent, device_t self, void *aux)
    563 {
    564 	struct iic_softc *sc = device_private(self);
    565 	devhandle_t devhandle = device_handle(self);
    566 	struct i2cbus_attach_args *iba = aux;
    567 
    568 	aprint_naive("\n");
    569 	aprint_normal(": I2C bus\n");
    570 
    571 	sc->sc_dev = self;
    572 	sc->sc_tag = iba->iba_tag;
    573 
    574 	if (!pmf_device_register(self, NULL, NULL))
    575 		aprint_error_dev(self, "couldn't establish power handler\n");
    576 
    577 	/* XXX There ought to be a generic way to do this. */
    578 	switch (devhandle_type(devhandle)) {
    579 #ifdef I2C_USE_ACPI
    580 	case DEVHANDLE_TYPE_ACPI:
    581 		acpi_i2c_register(self, sc->sc_tag);
    582 		break;
    583 #endif
    584 #ifdef I2C_USE_FDT
    585 	case DEVHANDLE_TYPE_OF:
    586 		fdtbus_register_i2c_controller(self, sc->sc_tag);
    587 		break;
    588 #endif
    589 	default:
    590 		break;
    591 	}
    592 
    593 	if (iic_attach_children_direct(sc)) {
    594 		/*
    595 		 * Attach all i2c devices described in the kernel
    596 		 * configuration file.
    597 		 */
    598 		iic_rescan(self, "iic", NULL);
    599 	}
    600 }
    601 
    602 static int
    603 iic_detach(device_t self, int flags)
    604 {
    605 	int error;
    606 
    607 	error = config_detach_children(self, flags);
    608 	if (error)
    609 		return error;
    610 
    611 	pmf_device_deregister(self);
    612 
    613 	return 0;
    614 }
    615 
    616 static void
    617 iic_fill_compat(struct i2c_attach_args *ia, const char *compat, size_t len,
    618 	char **buffer)
    619 {
    620 	int count, i;
    621 	const char *c, *start, **ptr;
    622 
    623 	*buffer = NULL;
    624 	for (i = count = 0, c = compat; i < len; i++, c++)
    625 		if (*c == 0)
    626 			count++;
    627 	count += 2;
    628 	ptr = malloc(sizeof(char*)*count, M_TEMP, M_WAITOK);
    629 	if (!ptr) return;
    630 
    631 	for (i = count = 0, start = c = compat; i < len; i++, c++) {
    632 		if (*c == 0) {
    633 			ptr[count++] = start;
    634 			start = c+1;
    635 		}
    636 	}
    637 	if (start < compat+len) {
    638 		/* last string not 0 terminated */
    639 		size_t l = c-start;
    640 		*buffer = malloc(l+1, M_TEMP, M_WAITOK);
    641 		memcpy(*buffer, start, l);
    642 		(*buffer)[l] = 0;
    643 		ptr[count++] = *buffer;
    644 	}
    645 	ptr[count] = NULL;
    646 
    647 	ia->ia_compat = ptr;
    648 	ia->ia_ncompat = count;
    649 }
    650 
    651 /*
    652  * iic_compatible_match --
    653  *	Match a device's "compatible" property against the list
    654  *	of compatible strings provided by the driver.
    655  */
    656 int
    657 iic_compatible_match(const struct i2c_attach_args *ia,
    658 		     const struct device_compatible_entry *compats)
    659 {
    660 	int match_result;
    661 
    662 	match_result = device_compatible_match(ia->ia_compat, ia->ia_ncompat,
    663 					       compats);
    664 	if (match_result) {
    665 		match_result =
    666 		    MIN(I2C_MATCH_DIRECT_COMPATIBLE + match_result - 1,
    667 			I2C_MATCH_DIRECT_COMPATIBLE_MAX);
    668 	}
    669 
    670 	return match_result;
    671 }
    672 
    673 /*
    674  * iic_compatible_lookup --
    675  *	Look the compatible entry that matches one of the driver's
    676  *	"compatible" strings.  The first match is returned.
    677  */
    678 const struct device_compatible_entry *
    679 iic_compatible_lookup(const struct i2c_attach_args *ia,
    680 		      const struct device_compatible_entry *compats)
    681 {
    682 	return device_compatible_lookup(ia->ia_compat, ia->ia_ncompat,
    683 					compats);
    684 }
    685 
    686 /*
    687  * iic_use_direct_match --
    688  *	Helper for direct-config of i2c.  Returns true if this is
    689  *	a direct-config situation, along with match result.
    690  *	Returns false if the driver should use indirect-config
    691  *	matching logic.
    692  */
    693 bool
    694 iic_use_direct_match(const struct i2c_attach_args *ia, const cfdata_t cf,
    695 		     const struct device_compatible_entry *compats,
    696 		     int *match_resultp)
    697 {
    698 	KASSERT(match_resultp != NULL);
    699 
    700 	if (ia->ia_name != NULL &&
    701 	    strcmp(ia->ia_name, cf->cf_name) == 0) {
    702 		*match_resultp = I2C_MATCH_DIRECT_SPECIFIC;
    703 		return true;
    704 	}
    705 
    706 	if (ia->ia_ncompat > 0 && ia->ia_compat != NULL) {
    707 		*match_resultp = iic_compatible_match(ia, compats);
    708 		return true;
    709 	}
    710 
    711 	return false;
    712 }
    713 
    714 static int
    715 iic_open(dev_t dev, int flag, int fmt, lwp_t *l)
    716 {
    717 	struct iic_softc *sc = device_lookup_private(&iic_cd, minor(dev));
    718 
    719 	mutex_enter(&iic_mtx);
    720 	if (sc == NULL) {
    721 		mutex_exit(&iic_mtx);
    722 		return ENXIO;
    723 	}
    724 	iic_refcnt++;
    725 	mutex_exit(&iic_mtx);
    726 
    727 	return 0;
    728 }
    729 
    730 static int
    731 iic_close(dev_t dev, int flag, int fmt, lwp_t *l)
    732 {
    733 
    734 	mutex_enter(&iic_mtx);
    735 	iic_refcnt--;
    736 	mutex_exit(&iic_mtx);
    737 
    738 	return 0;
    739 }
    740 
    741 static int
    742 iic_ioctl_exec(struct iic_softc *sc, i2c_ioctl_exec_t *iie, int flag)
    743 {
    744 	i2c_tag_t ic = sc->sc_tag;
    745 	uint8_t *buf = NULL;
    746 	void *cmd = NULL;
    747 	int error = 0;
    748 
    749 	/* Validate parameters */
    750 	if (iie->iie_addr > I2C_MAX_ADDR)
    751 		return EINVAL;
    752 	if (iie->iie_cmdlen > I2C_EXEC_MAX_CMDLEN ||
    753 	    iie->iie_buflen > I2C_EXEC_MAX_BUFLEN)
    754 		return EINVAL;
    755 	if (iie->iie_cmd != NULL && iie->iie_cmdlen == 0)
    756 		return EINVAL;
    757 	if (iie->iie_buf != NULL && iie->iie_buflen == 0)
    758 		return EINVAL;
    759 	if (I2C_OP_WRITE_P(iie->iie_op) && (flag & FWRITE) == 0)
    760 		return EBADF;
    761 
    762 #if 0
    763 	/* Disallow userspace access to devices that have drivers attached. */
    764 	if (sc->sc_devices[iie->iie_addr] != NULL)
    765 		return EBUSY;
    766 #endif
    767 
    768 	if (iie->iie_cmd != NULL) {
    769 		cmd = kmem_alloc(iie->iie_cmdlen, KM_SLEEP);
    770 		error = copyin(iie->iie_cmd, cmd, iie->iie_cmdlen);
    771 		if (error)
    772 			goto out;
    773 	}
    774 
    775 	if (iie->iie_buf != NULL) {
    776 		buf = kmem_alloc(iie->iie_buflen, KM_SLEEP);
    777 		if (I2C_OP_WRITE_P(iie->iie_op)) {
    778 			error = copyin(iie->iie_buf, buf, iie->iie_buflen);
    779 			if (error)
    780 				goto out;
    781 		}
    782 	}
    783 
    784 	iic_acquire_bus(ic, 0);
    785 	error = iic_exec(ic, iie->iie_op, iie->iie_addr, cmd, iie->iie_cmdlen,
    786 	    buf, iie->iie_buflen, 0);
    787 	iic_release_bus(ic, 0);
    788 
    789 	/*
    790 	 * Some drivers return error codes on failure, and others return -1.
    791 	 */
    792 	if (error < 0)
    793 		error = EIO;
    794 
    795 out:
    796 	if (!error && iie->iie_buf != NULL && I2C_OP_READ_P(iie->iie_op))
    797 		error = copyout(buf, iie->iie_buf, iie->iie_buflen);
    798 
    799 	if (buf)
    800 		kmem_free(buf, iie->iie_buflen);
    801 
    802 	if (cmd)
    803 		kmem_free(cmd, iie->iie_cmdlen);
    804 
    805 	return error;
    806 }
    807 
    808 static int
    809 iic_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
    810 {
    811 	struct iic_softc *sc = device_lookup_private(&iic_cd, minor(dev));
    812 
    813 	if (sc == NULL)
    814 		return ENXIO;
    815 
    816 	switch (cmd) {
    817 	case I2C_IOCTL_EXEC:
    818 		return iic_ioctl_exec(sc, (i2c_ioctl_exec_t *)data, flag);
    819 	default:
    820 		return ENODEV;
    821 	}
    822 }
    823 
    824 
    825 CFATTACH_DECL3_NEW(iic, sizeof(struct iic_softc),
    826     iic_match, iic_attach, iic_detach, NULL, iic_rescan, iic_child_detach,
    827     DVF_DETACH_SHUTDOWN);
    828 
    829 MODULE(MODULE_CLASS_DRIVER, iic, "i2cexec,i2c_bitbang,i2c_subr");
    830 
    831 #ifdef _MODULE
    832 #include "ioconf.c"
    833 #endif
    834 
    835 int
    836 iic_init(void)
    837 {
    838 
    839 	mutex_init(&iic_mtx, MUTEX_DEFAULT, IPL_NONE);
    840 	iic_refcnt = 0;
    841 	return 0;
    842 }
    843 
    844 static int
    845 iic_modcmd(modcmd_t cmd, void *opaque)
    846 {
    847 #ifdef _MODULE
    848 	int bmajor, cmajor;
    849 #endif
    850 	int error;
    851 
    852 	error = 0;
    853 	switch (cmd) {
    854 	case MODULE_CMD_INIT:
    855 		RUN_ONCE(&iic_once, iic_init);
    856 
    857 #ifdef _MODULE
    858 		mutex_enter(&iic_mtx);
    859 		bmajor = cmajor = -1;
    860 		error = devsw_attach("iic", NULL, &bmajor,
    861 		    &iic_cdevsw, &cmajor);
    862 		if (error != 0) {
    863 			mutex_exit(&iic_mtx);
    864 			break;
    865 		}
    866 		error = config_init_component(cfdriver_ioconf_iic,
    867 		    cfattach_ioconf_iic, cfdata_ioconf_iic);
    868 		if (error) {
    869 			aprint_error("%s: unable to init component\n",
    870 			    iic_cd.cd_name);
    871 			devsw_detach(NULL, &iic_cdevsw);
    872 		}
    873 		mutex_exit(&iic_mtx);
    874 #endif
    875 		break;
    876 	case MODULE_CMD_FINI:
    877 		mutex_enter(&iic_mtx);
    878 		if (iic_refcnt != 0) {
    879 			mutex_exit(&iic_mtx);
    880 			return EBUSY;
    881 		}
    882 #ifdef _MODULE
    883 		error = config_fini_component(cfdriver_ioconf_iic,
    884 		    cfattach_ioconf_iic, cfdata_ioconf_iic);
    885 		if (error != 0) {
    886 			mutex_exit(&iic_mtx);
    887 			break;
    888 		}
    889 		devsw_detach(NULL, &iic_cdevsw);
    890 #endif
    891 		mutex_exit(&iic_mtx);
    892 		break;
    893 	default:
    894 		error = ENOTTY;
    895 	}
    896 	return error;
    897 }
    898