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