1 /* $NetBSD: i2c.c,v 1.77 2021/01/25 12:18:18 jmcneill 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.77 2021/01/25 12:18:18 jmcneill 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 uint32_t cookietype; 443 const char *name; 444 struct i2c_attach_args ia; 445 int loc[IICCF_NLOCS]; 446 447 memset(loc, 0, sizeof loc); 448 count = prop_array_count(child_devices); 449 for (i = 0; i < count; i++) { 450 dev = prop_array_get(child_devices, i); 451 if (!dev) continue; 452 if (!prop_dictionary_get_cstring_nocopy( 453 dev, "name", &name)) { 454 /* "name" property is optional. */ 455 name = NULL; 456 } 457 if (!prop_dictionary_get_uint32(dev, "addr", &addr)) 458 continue; 459 if (!prop_dictionary_get_uint64(dev, "cookie", &cookie)) 460 cookie = 0; 461 if (!prop_dictionary_get_uint32(dev, "cookietype", 462 &cookietype)) 463 cookietype = I2C_COOKIE_NONE; 464 loc[IICCF_ADDR] = addr; 465 466 memset(&ia, 0, sizeof ia); 467 ia.ia_addr = addr; 468 ia.ia_tag = ic; 469 ia.ia_name = name; 470 ia.ia_cookie = cookie; 471 ia.ia_cookietype = cookietype; 472 ia.ia_prop = dev; 473 474 buf = NULL; 475 cdata = prop_dictionary_get(dev, "compatible"); 476 if (cdata) 477 iic_fill_compat(&ia, 478 prop_data_value(cdata), 479 prop_data_size(cdata), &buf); 480 481 if (name == NULL && cdata == NULL) { 482 aprint_error_dev(self, 483 "WARNING: ignoring bad child device entry " 484 "for address 0x%02x\n", addr); 485 } else { 486 if (addr > I2C_MAX_ADDR) { 487 aprint_error_dev(self, 488 "WARNING: ignoring bad device " 489 "address @ 0x%02x\n", addr); 490 } else if (sc->sc_devices[addr] == NULL) { 491 sc->sc_devices[addr] = 492 config_found_sm_loc(self, "iic", 493 loc, &ia, iic_print_direct, 494 NULL); 495 } 496 } 497 498 if (ia.ia_compat) 499 free(ia.ia_compat, M_TEMP); 500 if (buf) 501 free(buf, M_TEMP); 502 } 503 } else if (!no_indirect_config) { 504 /* 505 * Attach all i2c devices described in the kernel 506 * configuration file. 507 */ 508 iic_rescan(self, "iic", NULL); 509 } 510 } 511 512 static int 513 iic_detach(device_t self, int flags) 514 { 515 struct iic_softc *sc = device_private(self); 516 i2c_tag_t ic = sc->sc_tag; 517 int i, error; 518 void *hdl; 519 520 for (i = 0; i <= I2C_MAX_ADDR; i++) { 521 if (sc->sc_devices[i]) { 522 error = config_detach(sc->sc_devices[i], flags); 523 if (error) 524 return error; 525 } 526 } 527 528 if (ic->ic_running) { 529 ic->ic_running = 0; 530 wakeup(ic); 531 kthread_join(ic->ic_intr_thread); 532 } 533 534 if (!LIST_EMPTY(&ic->ic_list)) { 535 device_printf(self, "WARNING: intr handler list not empty\n"); 536 while (!LIST_EMPTY(&ic->ic_list)) { 537 hdl = LIST_FIRST(&ic->ic_list); 538 iic_smbus_intr_disestablish(ic, hdl); 539 } 540 } 541 if (!LIST_EMPTY(&ic->ic_proc_list)) { 542 device_printf(self, "WARNING: proc handler list not empty\n"); 543 while (!LIST_EMPTY(&ic->ic_proc_list)) { 544 hdl = LIST_FIRST(&ic->ic_proc_list); 545 iic_smbus_intr_disestablish_proc(ic, hdl); 546 } 547 } 548 549 pmf_device_deregister(self); 550 551 return 0; 552 } 553 554 static void 555 iic_smbus_intr_thread(void *aux) 556 { 557 i2c_tag_t ic; 558 struct ic_intr_list *il; 559 560 ic = (i2c_tag_t)aux; 561 ic->ic_running = 1; 562 ic->ic_pending = 0; 563 564 while (ic->ic_running) { 565 if (ic->ic_pending == 0) 566 tsleep(ic, PZERO, "iicintr", hz); 567 if (ic->ic_pending > 0) { 568 LIST_FOREACH(il, &(ic->ic_proc_list), il_next) { 569 (*il->il_intr)(il->il_intrarg); 570 } 571 ic->ic_pending--; 572 } 573 } 574 575 kthread_exit(0); 576 } 577 578 void * 579 iic_smbus_intr_establish(i2c_tag_t ic, int (*intr)(void *), void *intrarg) 580 { 581 struct ic_intr_list *il; 582 583 il = malloc(sizeof(struct ic_intr_list), M_DEVBUF, M_WAITOK); 584 if (il == NULL) 585 return NULL; 586 587 il->il_intr = intr; 588 il->il_intrarg = intrarg; 589 590 LIST_INSERT_HEAD(&(ic->ic_list), il, il_next); 591 592 return il; 593 } 594 595 void 596 iic_smbus_intr_disestablish(i2c_tag_t ic, void *hdl) 597 { 598 struct ic_intr_list *il; 599 600 il = (struct ic_intr_list *)hdl; 601 602 LIST_REMOVE(il, il_next); 603 free(il, M_DEVBUF); 604 605 return; 606 } 607 608 void * 609 iic_smbus_intr_establish_proc(i2c_tag_t ic, int (*intr)(void *), void *intrarg) 610 { 611 struct ic_intr_list *il; 612 613 il = malloc(sizeof(struct ic_intr_list), M_DEVBUF, M_WAITOK); 614 if (il == NULL) 615 return NULL; 616 617 il->il_intr = intr; 618 il->il_intrarg = intrarg; 619 620 LIST_INSERT_HEAD(&(ic->ic_proc_list), il, il_next); 621 622 return il; 623 } 624 625 void 626 iic_smbus_intr_disestablish_proc(i2c_tag_t ic, void *hdl) 627 { 628 struct ic_intr_list *il; 629 630 il = (struct ic_intr_list *)hdl; 631 632 LIST_REMOVE(il, il_next); 633 free(il, M_DEVBUF); 634 635 return; 636 } 637 638 int 639 iic_smbus_intr(i2c_tag_t ic) 640 { 641 struct ic_intr_list *il; 642 643 LIST_FOREACH(il, &(ic->ic_list), il_next) { 644 (*il->il_intr)(il->il_intrarg); 645 } 646 647 ic->ic_pending++; 648 wakeup(ic); 649 650 return 1; 651 } 652 653 static void 654 iic_fill_compat(struct i2c_attach_args *ia, const char *compat, size_t len, 655 char **buffer) 656 { 657 int count, i; 658 const char *c, *start, **ptr; 659 660 *buffer = NULL; 661 for (i = count = 0, c = compat; i < len; i++, c++) 662 if (*c == 0) 663 count++; 664 count += 2; 665 ptr = malloc(sizeof(char*)*count, M_TEMP, M_WAITOK); 666 if (!ptr) return; 667 668 for (i = count = 0, start = c = compat; i < len; i++, c++) { 669 if (*c == 0) { 670 ptr[count++] = start; 671 start = c+1; 672 } 673 } 674 if (start < compat+len) { 675 /* last string not 0 terminated */ 676 size_t l = c-start; 677 *buffer = malloc(l+1, M_TEMP, M_WAITOK); 678 memcpy(*buffer, start, l); 679 (*buffer)[l] = 0; 680 ptr[count++] = *buffer; 681 } 682 ptr[count] = NULL; 683 684 ia->ia_compat = ptr; 685 ia->ia_ncompat = count; 686 } 687 688 /* 689 * iic_compatible_match -- 690 * Match a device's "compatible" property against the list 691 * of compatible strings provided by the driver. 692 */ 693 int 694 iic_compatible_match(const struct i2c_attach_args *ia, 695 const struct device_compatible_entry *compats) 696 { 697 int match_result; 698 699 match_result = device_compatible_match(ia->ia_compat, ia->ia_ncompat, 700 compats); 701 if (match_result) { 702 match_result = 703 MIN(I2C_MATCH_DIRECT_COMPATIBLE + match_result - 1, 704 I2C_MATCH_DIRECT_COMPATIBLE_MAX); 705 } 706 707 return match_result; 708 } 709 710 /* 711 * iic_compatible_lookup -- 712 * Look the compatible entry that matches one of the driver's 713 * "compatible" strings. The first match is returned. 714 */ 715 const struct device_compatible_entry * 716 iic_compatible_lookup(const struct i2c_attach_args *ia, 717 const struct device_compatible_entry *compats) 718 { 719 return device_compatible_lookup(ia->ia_compat, ia->ia_ncompat, 720 compats); 721 } 722 723 /* 724 * iic_use_direct_match -- 725 * Helper for direct-config of i2c. Returns true if this is 726 * a direct-config situation, along with with match result. 727 * Returns false if the driver should use indirect-config 728 * matching logic. 729 */ 730 bool 731 iic_use_direct_match(const struct i2c_attach_args *ia, const cfdata_t cf, 732 const struct device_compatible_entry *compats, 733 int *match_resultp) 734 { 735 KASSERT(match_resultp != NULL); 736 737 if (ia->ia_name != NULL && 738 strcmp(ia->ia_name, cf->cf_name) == 0) { 739 *match_resultp = I2C_MATCH_DIRECT_SPECIFIC; 740 return true; 741 } 742 743 if (ia->ia_ncompat > 0 && ia->ia_compat != NULL) { 744 *match_resultp = iic_compatible_match(ia, compats); 745 return true; 746 } 747 748 return false; 749 } 750 751 static int 752 iic_open(dev_t dev, int flag, int fmt, lwp_t *l) 753 { 754 struct iic_softc *sc = device_lookup_private(&iic_cd, minor(dev)); 755 756 mutex_enter(&iic_mtx); 757 if (sc == NULL) { 758 mutex_exit(&iic_mtx); 759 return ENXIO; 760 } 761 iic_refcnt++; 762 mutex_exit(&iic_mtx); 763 764 return 0; 765 } 766 767 static int 768 iic_close(dev_t dev, int flag, int fmt, lwp_t *l) 769 { 770 771 mutex_enter(&iic_mtx); 772 iic_refcnt--; 773 mutex_exit(&iic_mtx); 774 775 return 0; 776 } 777 778 static int 779 iic_ioctl_exec(struct iic_softc *sc, i2c_ioctl_exec_t *iie, int flag) 780 { 781 i2c_tag_t ic = sc->sc_tag; 782 uint8_t buf[I2C_EXEC_MAX_BUFLEN]; 783 void *cmd = NULL; 784 int error; 785 786 /* Validate parameters */ 787 if (iie->iie_addr > I2C_MAX_ADDR) 788 return EINVAL; 789 if (iie->iie_cmdlen > I2C_EXEC_MAX_CMDLEN || 790 iie->iie_buflen > I2C_EXEC_MAX_BUFLEN) 791 return EINVAL; 792 if (iie->iie_cmd != NULL && iie->iie_cmdlen == 0) 793 return EINVAL; 794 if (iie->iie_buf != NULL && iie->iie_buflen == 0) 795 return EINVAL; 796 if (I2C_OP_WRITE_P(iie->iie_op) && (flag & FWRITE) == 0) 797 return EBADF; 798 799 #if 0 800 /* Disallow userspace access to devices that have drivers attached. */ 801 if (sc->sc_devices[iie->iie_addr] != NULL) 802 return EBUSY; 803 #endif 804 805 if (iie->iie_cmd != NULL) { 806 cmd = kmem_alloc(iie->iie_cmdlen, KM_SLEEP); 807 error = copyin(iie->iie_cmd, cmd, iie->iie_cmdlen); 808 if (error) 809 goto out; 810 } 811 812 if (iie->iie_buf != NULL && I2C_OP_WRITE_P(iie->iie_op)) { 813 error = copyin(iie->iie_buf, buf, iie->iie_buflen); 814 if (error) 815 goto out; 816 } 817 818 iic_acquire_bus(ic, 0); 819 error = iic_exec(ic, iie->iie_op, iie->iie_addr, cmd, iie->iie_cmdlen, 820 buf, iie->iie_buflen, 0); 821 iic_release_bus(ic, 0); 822 823 /* 824 * Some drivers return error codes on failure, and others return -1. 825 */ 826 if (error < 0) 827 error = EIO; 828 829 out: 830 if (cmd) 831 kmem_free(cmd, iie->iie_cmdlen); 832 833 if (error) 834 return error; 835 836 if (iie->iie_buf != NULL && I2C_OP_READ_P(iie->iie_op)) 837 error = copyout(buf, iie->iie_buf, iie->iie_buflen); 838 839 return error; 840 } 841 842 static int 843 iic_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l) 844 { 845 struct iic_softc *sc = device_lookup_private(&iic_cd, minor(dev)); 846 847 if (sc == NULL) 848 return ENXIO; 849 850 switch (cmd) { 851 case I2C_IOCTL_EXEC: 852 return iic_ioctl_exec(sc, (i2c_ioctl_exec_t *)data, flag); 853 default: 854 return ENODEV; 855 } 856 } 857 858 859 CFATTACH_DECL3_NEW(iic, sizeof(struct iic_softc), 860 iic_match, iic_attach, iic_detach, NULL, iic_rescan, iic_child_detach, 861 DVF_DETACH_SHUTDOWN); 862 863 MODULE(MODULE_CLASS_DRIVER, iic, "i2cexec,i2c_bitbang"); 864 865 #ifdef _MODULE 866 #include "ioconf.c" 867 #endif 868 869 int 870 iic_init(void) 871 { 872 873 mutex_init(&iic_mtx, MUTEX_DEFAULT, IPL_NONE); 874 iic_refcnt = 0; 875 return 0; 876 } 877 878 static int 879 iic_modcmd(modcmd_t cmd, void *opaque) 880 { 881 #ifdef _MODULE 882 int bmajor, cmajor; 883 #endif 884 int error; 885 886 error = 0; 887 switch (cmd) { 888 case MODULE_CMD_INIT: 889 RUN_ONCE(&iic_once, iic_init); 890 891 #ifdef _MODULE 892 mutex_enter(&iic_mtx); 893 bmajor = cmajor = -1; 894 error = devsw_attach("iic", NULL, &bmajor, 895 &iic_cdevsw, &cmajor); 896 if (error != 0) { 897 mutex_exit(&iic_mtx); 898 break; 899 } 900 error = config_init_component(cfdriver_ioconf_iic, 901 cfattach_ioconf_iic, cfdata_ioconf_iic); 902 if (error) { 903 aprint_error("%s: unable to init component\n", 904 iic_cd.cd_name); 905 (void)devsw_detach(NULL, &iic_cdevsw); 906 } 907 mutex_exit(&iic_mtx); 908 #endif 909 break; 910 case MODULE_CMD_FINI: 911 mutex_enter(&iic_mtx); 912 if (iic_refcnt != 0) { 913 mutex_exit(&iic_mtx); 914 return EBUSY; 915 } 916 #ifdef _MODULE 917 error = config_fini_component(cfdriver_ioconf_iic, 918 cfattach_ioconf_iic, cfdata_ioconf_iic); 919 if (error != 0) { 920 mutex_exit(&iic_mtx); 921 break; 922 } 923 error = devsw_detach(NULL, &iic_cdevsw); 924 if (error != 0) 925 config_init_component(cfdriver_ioconf_iic, 926 cfattach_ioconf_iic, cfdata_ioconf_iic); 927 #endif 928 mutex_exit(&iic_mtx); 929 break; 930 default: 931 error = ENOTTY; 932 } 933 return error; 934 } 935