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