1 /* $NetBSD: i2c.c,v 1.38 2012/03/14 02:57:10 pgoyette 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 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.38 2012/03/14 02:57:10 pgoyette Exp $"); 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/device.h> 44 #include <sys/event.h> 45 #include <sys/conf.h> 46 #include <sys/malloc.h> 47 #include <sys/kmem.h> 48 #include <sys/kthread.h> 49 #include <sys/proc.h> 50 #include <sys/kernel.h> 51 #include <sys/fcntl.h> 52 #include <sys/module.h> 53 54 #include <dev/i2c/i2cvar.h> 55 56 #include "locators.h" 57 58 #define I2C_MAX_ADDR 0x3ff /* 10-bit address, max */ 59 60 struct iic_softc { 61 i2c_tag_t sc_tag; 62 int sc_type; 63 device_t sc_devices[I2C_MAX_ADDR + 1]; 64 }; 65 66 static dev_type_open(iic_open); 67 static dev_type_close(iic_close); 68 static dev_type_ioctl(iic_ioctl); 69 70 const struct cdevsw iic_cdevsw = { 71 iic_open, iic_close, noread, nowrite, iic_ioctl, 72 nostop, notty, nopoll, nommap, nokqfilter, D_OTHER 73 }; 74 75 extern struct cfdriver iic_cd; 76 77 static void iic_smbus_intr_thread(void *); 78 static void iic_fill_compat(struct i2c_attach_args*, const char*, 79 size_t, char **); 80 81 static int 82 iic_print_direct(void *aux, const char *pnp) 83 { 84 struct i2c_attach_args *ia = aux; 85 86 if (pnp != NULL) 87 aprint_normal("%s at %s addr 0x%02x", ia->ia_name, pnp, 88 ia->ia_addr); 89 else 90 aprint_normal(" addr 0x%02x", ia->ia_addr); 91 92 return UNCONF; 93 } 94 95 static int 96 iic_print(void *aux, const char *pnp) 97 { 98 struct i2c_attach_args *ia = aux; 99 100 if (ia->ia_addr != (i2c_addr_t)-1) 101 aprint_normal(" addr 0x%x", ia->ia_addr); 102 103 return UNCONF; 104 } 105 106 static int 107 iic_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 108 { 109 struct iic_softc *sc = device_private(parent); 110 struct i2c_attach_args ia; 111 112 ia.ia_tag = sc->sc_tag; 113 ia.ia_addr = cf->cf_loc[IICCF_ADDR]; 114 ia.ia_size = cf->cf_loc[IICCF_SIZE]; 115 ia.ia_type = sc->sc_type; 116 117 ia.ia_name = NULL; 118 ia.ia_ncompat = 0; 119 ia.ia_compat = NULL; 120 121 if (ia.ia_addr != (i2c_addr_t)-1 && 122 ia.ia_addr <= I2C_MAX_ADDR && 123 !sc->sc_devices[ia.ia_addr]) 124 if (config_match(parent, cf, &ia) > 0) { 125 sc->sc_devices[ia.ia_addr] = 126 config_attach(parent, cf, &ia, iic_print); 127 } 128 return 0; 129 } 130 131 static void 132 iic_child_detach(device_t parent, device_t child) 133 { 134 struct iic_softc *sc = device_private(parent); 135 int i; 136 137 for (i = 0; i <= I2C_MAX_ADDR; i++) 138 if (sc->sc_devices[i] == child) { 139 sc->sc_devices[i] = NULL; 140 break; 141 } 142 } 143 144 static int 145 iic_rescan(device_t self, const char *ifattr, const int *locators) 146 { 147 config_search_ia(iic_search, self, ifattr, NULL); 148 return 0; 149 } 150 151 static int 152 iic_match(device_t parent, cfdata_t cf, void *aux) 153 { 154 155 return 1; 156 } 157 158 static void 159 iic_attach(device_t parent, device_t self, void *aux) 160 { 161 struct iic_softc *sc = device_private(self); 162 struct i2cbus_attach_args *iba = aux; 163 prop_array_t child_devices; 164 char *buf; 165 i2c_tag_t ic; 166 int rv; 167 168 aprint_naive("\n"); 169 aprint_normal(": I2C bus\n"); 170 171 sc->sc_tag = iba->iba_tag; 172 sc->sc_type = iba->iba_type; 173 ic = sc->sc_tag; 174 ic->ic_devname = device_xname(self); 175 176 LIST_INIT(&(sc->sc_tag->ic_list)); 177 LIST_INIT(&(sc->sc_tag->ic_proc_list)); 178 179 rv = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN, NULL, 180 iic_smbus_intr_thread, ic, &ic->ic_intr_thread, 181 "%s", ic->ic_devname); 182 if (rv) 183 aprint_error_dev(self, "unable to create intr thread\n"); 184 185 if (!pmf_device_register(self, NULL, NULL)) 186 aprint_error_dev(self, "couldn't establish power handler\n"); 187 188 child_devices = prop_dictionary_get(device_properties(parent), 189 "i2c-child-devices"); 190 if (child_devices) { 191 unsigned int i, count; 192 prop_dictionary_t dev; 193 prop_data_t cdata; 194 uint32_t addr, size; 195 uint64_t cookie; 196 const char *name; 197 struct i2c_attach_args ia; 198 int loc[2]; 199 200 memset(loc, 0, sizeof loc); 201 count = prop_array_count(child_devices); 202 for (i = 0; i < count; i++) { 203 dev = prop_array_get(child_devices, i); 204 if (!dev) continue; 205 if (!prop_dictionary_get_cstring_nocopy( 206 dev, "name", &name)) 207 continue; 208 if (!prop_dictionary_get_uint32(dev, "addr", &addr)) 209 continue; 210 if (!prop_dictionary_get_uint64(dev, "cookie", &cookie)) 211 cookie = 0; 212 loc[0] = addr; 213 if (prop_dictionary_get_uint32(dev, "size", &size)) 214 loc[1] = size; 215 else 216 loc[1] = -1; 217 218 memset(&ia, 0, sizeof ia); 219 ia.ia_addr = addr; 220 ia.ia_type = sc->sc_type; 221 ia.ia_tag = ic; 222 ia.ia_name = name; 223 ia.ia_cookie = cookie; 224 225 buf = NULL; 226 cdata = prop_dictionary_get(dev, "compatible"); 227 if (cdata) 228 iic_fill_compat(&ia, 229 prop_data_data_nocopy(cdata), 230 prop_data_size(cdata), &buf); 231 232 if (addr > I2C_MAX_ADDR) { 233 aprint_error_dev(self, 234 "WARNING: ignoring bad device address " 235 "@ 0x%02x\n", addr); 236 } else if (sc->sc_devices[addr] == NULL) { 237 sc->sc_devices[addr] = 238 config_found_sm_loc(self, "iic", loc, &ia, 239 iic_print_direct, NULL); 240 } 241 242 if (ia.ia_compat) 243 free(ia.ia_compat, M_TEMP); 244 if (buf) 245 free(buf, M_TEMP); 246 } 247 } else { 248 /* 249 * Attach all i2c devices described in the kernel 250 * configuration file. 251 */ 252 iic_rescan(self, "iic", NULL); 253 } 254 } 255 256 static int 257 iic_detach(device_t self, int flags) 258 { 259 struct iic_softc *sc = device_private(self); 260 i2c_tag_t ic = sc->sc_tag; 261 int i, error; 262 void *hdl; 263 264 for (i = 0; i <= I2C_MAX_ADDR; i++) { 265 if (sc->sc_devices[i]) { 266 error = config_detach(sc->sc_devices[i], flags); 267 if (error) 268 return error; 269 } 270 } 271 272 if (ic->ic_running) { 273 ic->ic_running = 0; 274 wakeup(ic); 275 kthread_join(ic->ic_intr_thread); 276 } 277 278 if (!LIST_EMPTY(&ic->ic_list)) { 279 device_printf(self, "WARNING: intr handler list not empty\n"); 280 while (!LIST_EMPTY(&ic->ic_list)) { 281 hdl = LIST_FIRST(&ic->ic_list); 282 iic_smbus_intr_disestablish(ic, hdl); 283 } 284 } 285 if (!LIST_EMPTY(&ic->ic_proc_list)) { 286 device_printf(self, "WARNING: proc handler list not empty\n"); 287 while (!LIST_EMPTY(&ic->ic_proc_list)) { 288 hdl = LIST_FIRST(&ic->ic_proc_list); 289 iic_smbus_intr_disestablish_proc(ic, hdl); 290 } 291 } 292 293 pmf_device_deregister(self); 294 295 return 0; 296 } 297 298 static void 299 iic_smbus_intr_thread(void *aux) 300 { 301 i2c_tag_t ic; 302 struct ic_intr_list *il; 303 int rv; 304 305 ic = (i2c_tag_t)aux; 306 ic->ic_running = 1; 307 ic->ic_pending = 0; 308 309 while (ic->ic_running) { 310 if (ic->ic_pending == 0) 311 rv = tsleep(ic, PZERO, "iicintr", hz); 312 if (ic->ic_pending > 0) { 313 LIST_FOREACH(il, &(ic->ic_proc_list), il_next) { 314 (*il->il_intr)(il->il_intrarg); 315 } 316 ic->ic_pending--; 317 } 318 } 319 320 kthread_exit(0); 321 } 322 323 void * 324 iic_smbus_intr_establish(i2c_tag_t ic, int (*intr)(void *), void *intrarg) 325 { 326 struct ic_intr_list *il; 327 328 il = malloc(sizeof(struct ic_intr_list), M_DEVBUF, M_WAITOK); 329 if (il == NULL) 330 return NULL; 331 332 il->il_intr = intr; 333 il->il_intrarg = intrarg; 334 335 LIST_INSERT_HEAD(&(ic->ic_list), il, il_next); 336 337 return il; 338 } 339 340 void 341 iic_smbus_intr_disestablish(i2c_tag_t ic, void *hdl) 342 { 343 struct ic_intr_list *il; 344 345 il = (struct ic_intr_list *)hdl; 346 347 LIST_REMOVE(il, il_next); 348 free(il, M_DEVBUF); 349 350 return; 351 } 352 353 void * 354 iic_smbus_intr_establish_proc(i2c_tag_t ic, int (*intr)(void *), void *intrarg) 355 { 356 struct ic_intr_list *il; 357 358 il = malloc(sizeof(struct ic_intr_list), M_DEVBUF, M_WAITOK); 359 if (il == NULL) 360 return NULL; 361 362 il->il_intr = intr; 363 il->il_intrarg = intrarg; 364 365 LIST_INSERT_HEAD(&(ic->ic_proc_list), il, il_next); 366 367 return il; 368 } 369 370 void 371 iic_smbus_intr_disestablish_proc(i2c_tag_t ic, void *hdl) 372 { 373 struct ic_intr_list *il; 374 375 il = (struct ic_intr_list *)hdl; 376 377 LIST_REMOVE(il, il_next); 378 free(il, M_DEVBUF); 379 380 return; 381 } 382 383 int 384 iic_smbus_intr(i2c_tag_t ic) 385 { 386 struct ic_intr_list *il; 387 388 LIST_FOREACH(il, &(ic->ic_list), il_next) { 389 (*il->il_intr)(il->il_intrarg); 390 } 391 392 ic->ic_pending++; 393 wakeup(ic); 394 395 return 1; 396 } 397 398 static void 399 iic_fill_compat(struct i2c_attach_args *ia, const char *compat, size_t len, 400 char **buffer) 401 { 402 int count, i; 403 const char *c, *start, **ptr; 404 405 *buffer = NULL; 406 for (i = count = 0, c = compat; i < len; i++, c++) 407 if (*c == 0) 408 count++; 409 count += 2; 410 ptr = malloc(sizeof(char*)*count, M_TEMP, M_WAITOK); 411 if (!ptr) return; 412 413 for (i = count = 0, start = c = compat; i < len; i++, c++) { 414 if (*c == 0) { 415 ptr[count++] = start; 416 start = c+1; 417 } 418 } 419 if (start < compat+len) { 420 /* last string not 0 terminated */ 421 size_t l = c-start; 422 *buffer = malloc(l+1, M_TEMP, M_WAITOK); 423 memcpy(*buffer, start, l); 424 (*buffer)[l] = 0; 425 ptr[count++] = *buffer; 426 } 427 ptr[count] = NULL; 428 429 ia->ia_compat = ptr; 430 ia->ia_ncompat = count; 431 } 432 433 int 434 iic_compat_match(struct i2c_attach_args *ia, const char ** compats) 435 { 436 int i; 437 438 for (; compats && *compats; compats++) { 439 for (i = 0; i < ia->ia_ncompat; i++) { 440 if (strcmp(*compats, ia->ia_compat[i]) == 0) 441 return 1; 442 } 443 } 444 return 0; 445 } 446 447 static int 448 iic_open(dev_t dev, int flag, int fmt, lwp_t *l) 449 { 450 struct iic_softc *sc = device_lookup_private(&iic_cd, minor(dev)); 451 452 if (sc == NULL) 453 return ENXIO; 454 455 return 0; 456 } 457 458 static int 459 iic_close(dev_t dev, int flag, int fmt, lwp_t *l) 460 { 461 return 0; 462 } 463 464 static int 465 iic_ioctl_exec(struct iic_softc *sc, i2c_ioctl_exec_t *iie, int flag) 466 { 467 i2c_tag_t ic = sc->sc_tag; 468 uint8_t buf[I2C_EXEC_MAX_BUFLEN]; 469 void *cmd = NULL; 470 int error; 471 472 /* Validate parameters */ 473 if (iie->iie_addr > I2C_MAX_ADDR) 474 return EINVAL; 475 if (iie->iie_cmdlen > I2C_EXEC_MAX_CMDLEN || 476 iie->iie_buflen > I2C_EXEC_MAX_BUFLEN) 477 return EINVAL; 478 if (iie->iie_cmd != NULL && iie->iie_cmdlen == 0) 479 return EINVAL; 480 if (iie->iie_buf != NULL && iie->iie_buflen == 0) 481 return EINVAL; 482 if (I2C_OP_WRITE_P(iie->iie_op) && (flag & FWRITE) == 0) 483 return EBADF; 484 485 #if 0 486 /* Disallow userspace access to devices that have drivers attached. */ 487 if (sc->sc_devices[iie->iie_addr] != NULL) 488 return EBUSY; 489 #endif 490 491 if (iie->iie_cmd != NULL) { 492 cmd = kmem_alloc(iie->iie_cmdlen, KM_SLEEP); 493 if (cmd == NULL) 494 return ENOMEM; 495 error = copyin(iie->iie_cmd, cmd, iie->iie_cmdlen); 496 if (error) { 497 kmem_free(cmd, iie->iie_cmdlen); 498 return error; 499 } 500 } 501 502 iic_acquire_bus(ic, 0); 503 error = iic_exec(ic, iie->iie_op, iie->iie_addr, cmd, iie->iie_cmdlen, 504 buf, iie->iie_buflen, 0); 505 iic_release_bus(ic, 0); 506 507 /* 508 * Some drivers return error codes on failure, and others return -1. 509 */ 510 if (error < 0) 511 error = EIO; 512 513 if (cmd) 514 kmem_free(cmd, iie->iie_cmdlen); 515 516 if (error) 517 return error; 518 519 if (iie->iie_buf) 520 error = copyout(buf, iie->iie_buf, iie->iie_buflen); 521 522 return error; 523 } 524 525 static int 526 iic_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l) 527 { 528 struct iic_softc *sc = device_lookup_private(&iic_cd, minor(dev)); 529 530 if (sc == NULL) 531 return ENXIO; 532 533 switch (cmd) { 534 case I2C_IOCTL_EXEC: 535 return iic_ioctl_exec(sc, (i2c_ioctl_exec_t *)data, flag); 536 default: 537 return ENODEV; 538 } 539 } 540 541 542 CFATTACH_DECL2_NEW(iic, sizeof(struct iic_softc), 543 iic_match, iic_attach, iic_detach, NULL, iic_rescan, iic_child_detach); 544 545 MODULE(MODULE_CLASS_DRIVER, iic, NULL); 546 547 #ifdef _MODULE 548 #include "ioconf.c" 549 #endif 550 551 static int 552 iic_modcmd(modcmd_t cmd, void *opaque) 553 { 554 int error; 555 556 error = 0; 557 switch (cmd) { 558 case MODULE_CMD_INIT: 559 #ifdef _MODULE 560 error = config_init_component(cfdriver_ioconf_iic, 561 cfattach_ioconf_iic, cfdata_ioconf_iic); 562 if (error) 563 aprint_error("%s: unable to init component\n", 564 iic_cd.cd_name); 565 #endif 566 break; 567 case MODULE_CMD_FINI: 568 #ifdef _MODULE 569 config_fini_component(cfdriver_ioconf_iic, 570 cfattach_ioconf_iic, cfdata_ioconf_iic); 571 #endif 572 break; 573 default: 574 error = ENOTTY; 575 } 576 return error; 577 } 578