1 /* $NetBSD: onewire.c,v 1.15 2014/03/16 05:20:28 dholland Exp $ */ 2 /* $OpenBSD: onewire.c,v 1.1 2006/03/04 16:27:03 grange Exp $ */ 3 4 /* 5 * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/cdefs.h> 21 __KERNEL_RCSID(0, "$NetBSD: onewire.c,v 1.15 2014/03/16 05:20:28 dholland Exp $"); 22 23 /* 24 * 1-Wire bus driver. 25 */ 26 27 #include <sys/param.h> 28 #include <sys/systm.h> 29 #include <sys/conf.h> 30 #include <sys/device.h> 31 #include <sys/kernel.h> 32 #include <sys/kthread.h> 33 #include <sys/rwlock.h> 34 #include <sys/malloc.h> 35 #include <sys/proc.h> 36 #include <sys/queue.h> 37 #include <sys/module.h> 38 39 #include <dev/onewire/onewirereg.h> 40 #include <dev/onewire/onewirevar.h> 41 42 #ifdef ONEWIRE_DEBUG 43 #define DPRINTF(x) printf x 44 #else 45 #define DPRINTF(x) 46 #endif 47 48 //#define ONEWIRE_MAXDEVS 256 49 #define ONEWIRE_MAXDEVS 8 50 #define ONEWIRE_SCANTIME 3 51 52 struct onewire_softc { 53 device_t sc_dev; 54 55 struct onewire_bus * sc_bus; 56 krwlock_t sc_rwlock; 57 struct lwp * sc_thread; 58 TAILQ_HEAD(, onewire_device) sc_devs; 59 60 int sc_dying; 61 }; 62 63 struct onewire_device { 64 TAILQ_ENTRY(onewire_device) d_list; 65 device_t d_dev; 66 u_int64_t d_rom; 67 int d_present; 68 }; 69 70 static int onewire_match(device_t, cfdata_t, void *); 71 static void onewire_attach(device_t, device_t, void *); 72 static int onewire_detach(device_t, int); 73 static int onewire_activate(device_t, enum devact); 74 int onewire_print(void *, const char *); 75 76 static void onewire_thread(void *); 77 static void onewire_scan(struct onewire_softc *); 78 79 CFATTACH_DECL_NEW(onewire, sizeof(struct onewire_softc), 80 onewire_match, onewire_attach, onewire_detach, onewire_activate); 81 82 const struct cdevsw onewire_cdevsw = { 83 .d_open = noopen, 84 .d_close = noclose, 85 .d_read = noread, 86 .d_write = nowrite, 87 .d_ioctl = noioctl, 88 .d_stop = nostop, 89 .d_tty = notty, 90 .d_poll = nopoll, 91 .d_mmap = nommap, 92 .d_kqfilter = nokqfilter, 93 .d_flag = D_OTHER 94 }; 95 96 extern struct cfdriver onewire_cd; 97 98 static int 99 onewire_match(device_t parent, cfdata_t cf, void *aux) 100 { 101 return 1; 102 } 103 104 static void 105 onewire_attach(device_t parent, device_t self, void *aux) 106 { 107 struct onewire_softc *sc = device_private(self); 108 struct onewirebus_attach_args *oba = aux; 109 110 sc->sc_dev = self; 111 sc->sc_bus = oba->oba_bus; 112 rw_init(&sc->sc_rwlock); 113 TAILQ_INIT(&sc->sc_devs); 114 115 aprint_normal("\n"); 116 117 if (kthread_create(PRI_NONE, 0, NULL, onewire_thread, sc, 118 &sc->sc_thread, "%s", device_xname(self)) != 0) 119 aprint_error_dev(self, "can't create kernel thread\n"); 120 } 121 122 static int 123 onewire_detach(device_t self, int flags) 124 { 125 struct onewire_softc *sc = device_private(self); 126 int rv; 127 128 sc->sc_dying = 1; 129 if (sc->sc_thread != NULL) { 130 wakeup(sc->sc_thread); 131 tsleep(&sc->sc_dying, PWAIT, "owdt", 0); 132 } 133 134 onewire_lock(sc); 135 //rv = config_detach_children(self, flags); 136 rv = 0; /* XXX riz */ 137 onewire_unlock(sc); 138 rw_destroy(&sc->sc_rwlock); 139 140 return rv; 141 } 142 143 static int 144 onewire_activate(device_t self, enum devact act) 145 { 146 struct onewire_softc *sc = device_private(self); 147 148 switch (act) { 149 case DVACT_DEACTIVATE: 150 sc->sc_dying = 1; 151 return 0; 152 default: 153 return EOPNOTSUPP; 154 } 155 } 156 157 int 158 onewire_print(void *aux, const char *pnp) 159 { 160 struct onewire_attach_args *oa = aux; 161 const char *famname; 162 163 if (pnp == NULL) 164 aprint_normal(" "); 165 166 famname = onewire_famname(ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom)); 167 if (famname == NULL) 168 aprint_normal("family 0x%02x", 169 (uint)ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom)); 170 else 171 aprint_normal("\"%s\"", famname); 172 aprint_normal(" sn %012llx", ONEWIRE_ROM_SN(oa->oa_rom)); 173 174 if (pnp != NULL) 175 aprint_normal(" at %s", pnp); 176 177 return UNCONF; 178 } 179 180 int 181 onewirebus_print(void *aux, const char *pnp) 182 { 183 if (pnp != NULL) 184 aprint_normal("onewire at %s", pnp); 185 186 return UNCONF; 187 } 188 189 void 190 onewire_lock(void *arg) 191 { 192 struct onewire_softc *sc = arg; 193 194 rw_enter(&sc->sc_rwlock, RW_WRITER); 195 } 196 197 void 198 onewire_unlock(void *arg) 199 { 200 struct onewire_softc *sc = arg; 201 202 rw_exit(&sc->sc_rwlock); 203 } 204 205 int 206 onewire_reset(void *arg) 207 { 208 struct onewire_softc *sc = arg; 209 struct onewire_bus *bus = sc->sc_bus; 210 211 return bus->bus_reset(bus->bus_cookie); 212 } 213 214 int 215 onewire_bit(void *arg, int value) 216 { 217 struct onewire_softc *sc = arg; 218 struct onewire_bus *bus = sc->sc_bus; 219 220 return bus->bus_bit(bus->bus_cookie, value); 221 } 222 223 int 224 onewire_read_byte(void *arg) 225 { 226 struct onewire_softc *sc = arg; 227 struct onewire_bus *bus = sc->sc_bus; 228 uint8_t value = 0; 229 int i; 230 231 if (bus->bus_read_byte != NULL) 232 return bus->bus_read_byte(bus->bus_cookie); 233 234 for (i = 0; i < 8; i++) 235 value |= (bus->bus_bit(bus->bus_cookie, 1) << i); 236 237 return value; 238 } 239 240 void 241 onewire_write_byte(void *arg, int value) 242 { 243 struct onewire_softc *sc = arg; 244 struct onewire_bus *bus = sc->sc_bus; 245 int i; 246 247 if (bus->bus_write_byte != NULL) 248 return bus->bus_write_byte(bus->bus_cookie, value); 249 250 for (i = 0; i < 8; i++) 251 bus->bus_bit(bus->bus_cookie, (value >> i) & 0x1); 252 } 253 254 int 255 onewire_triplet(void *arg, int dir) 256 { 257 struct onewire_softc *sc = arg; 258 struct onewire_bus *bus = sc->sc_bus; 259 int rv; 260 261 if (bus->bus_triplet != NULL) 262 return bus->bus_triplet(bus->bus_cookie, dir); 263 264 rv = bus->bus_bit(bus->bus_cookie, 1); 265 rv <<= 1; 266 rv |= bus->bus_bit(bus->bus_cookie, 1); 267 268 switch (rv) { 269 case 0x0: 270 bus->bus_bit(bus->bus_cookie, dir); 271 break; 272 case 0x1: 273 bus->bus_bit(bus->bus_cookie, 0); 274 break; 275 default: 276 bus->bus_bit(bus->bus_cookie, 1); 277 } 278 279 return rv; 280 } 281 282 void 283 onewire_read_block(void *arg, void *buf, int len) 284 { 285 uint8_t *p = buf; 286 287 while (len--) 288 *p++ = onewire_read_byte(arg); 289 } 290 291 void 292 onewire_write_block(void *arg, const void *buf, int len) 293 { 294 const uint8_t *p = buf; 295 296 while (len--) 297 onewire_write_byte(arg, *p++); 298 } 299 300 void 301 onewire_matchrom(void *arg, u_int64_t rom) 302 { 303 int i; 304 305 onewire_write_byte(arg, ONEWIRE_CMD_MATCH_ROM); 306 for (i = 0; i < 8; i++) 307 onewire_write_byte(arg, (rom >> (i * 8)) & 0xff); 308 } 309 310 static void 311 onewire_thread(void *arg) 312 { 313 struct onewire_softc *sc = arg; 314 315 while (!sc->sc_dying) { 316 onewire_scan(sc); 317 tsleep(sc->sc_thread, PWAIT, "owidle", ONEWIRE_SCANTIME * hz); 318 } 319 320 sc->sc_thread = NULL; 321 wakeup(&sc->sc_dying); 322 kthread_exit(0); 323 } 324 325 static void 326 onewire_scan(struct onewire_softc *sc) 327 { 328 struct onewire_device *d, *next, *nd; 329 struct onewire_attach_args oa; 330 device_t dev; 331 int search = 1, count = 0, present; 332 int dir, rv; 333 uint64_t mask, rom = 0, lastrom; 334 uint8_t data[8]; 335 int i, i0 = -1, lastd = -1; 336 337 TAILQ_FOREACH(d, &sc->sc_devs, d_list) 338 d->d_present = 0; 339 340 while (search && count++ < ONEWIRE_MAXDEVS) { 341 /* XXX: yield processor */ 342 tsleep(sc, PWAIT, "owscan", hz / 10); 343 344 /* 345 * Reset the bus. If there's no presence pulse 346 * don't search for any devices. 347 */ 348 onewire_lock(sc); 349 if (onewire_reset(sc) != 0) { 350 DPRINTF(("%s: scan: no presence pulse\n", 351 device_xname(sc->sc_dev))); 352 onewire_unlock(sc); 353 break; 354 } 355 356 /* 357 * Start new search. Go through the previous path to 358 * the point we made a decision last time and make an 359 * opposite decision. If we didn't make any decision 360 * stop searching. 361 */ 362 search = 0; 363 lastrom = rom; 364 rom = 0; 365 onewire_write_byte(sc, ONEWIRE_CMD_SEARCH_ROM); 366 for (i = 0,i0 = -1; i < 64; i++) { 367 dir = (lastrom >> i) & 0x1; 368 if (i == lastd) 369 dir = 1; 370 else if (i > lastd) 371 dir = 0; 372 rv = onewire_triplet(sc, dir); 373 switch (rv) { 374 case 0x0: 375 if (i != lastd) { 376 if (dir == 0) 377 i0 = i; 378 search = 1; 379 } 380 mask = dir; 381 break; 382 case 0x1: 383 mask = 0; 384 break; 385 case 0x2: 386 mask = 1; 387 break; 388 default: 389 DPRINTF(("%s: scan: triplet error 0x%x, " 390 "step %d\n", 391 device_xname(sc->sc_dev), rv, i)); 392 onewire_unlock(sc); 393 return; 394 } 395 rom |= (mask << i); 396 } 397 lastd = i0; 398 onewire_unlock(sc); 399 400 if (rom == 0) 401 continue; 402 403 /* 404 * The last byte of the ROM code contains a CRC calculated 405 * from the first 7 bytes. Re-calculate it to make sure 406 * we found a valid device. 407 */ 408 for (i = 0; i < 8; i++) 409 data[i] = (rom >> (i * 8)) & 0xff; 410 if (onewire_crc(data, 7) != data[7]) 411 continue; 412 413 /* 414 * Go through the list of attached devices to see if we 415 * found a new one. 416 */ 417 present = 0; 418 TAILQ_FOREACH(d, &sc->sc_devs, d_list) { 419 if (d->d_rom == rom) { 420 d->d_present = 1; 421 present = 1; 422 break; 423 } 424 } 425 if (!present) { 426 memset(&oa, 0, sizeof(oa)); 427 oa.oa_onewire = sc; 428 oa.oa_rom = rom; 429 if ((dev = config_found(sc->sc_dev, &oa, 430 onewire_print)) == NULL) 431 continue; 432 433 nd = malloc(sizeof(struct onewire_device), 434 M_DEVBUF, M_NOWAIT); 435 if (nd == NULL) 436 continue; 437 nd->d_dev = dev; 438 nd->d_rom = rom; 439 nd->d_present = 1; 440 TAILQ_INSERT_TAIL(&sc->sc_devs, nd, d_list); 441 } 442 } 443 444 /* Detach disappeared devices */ 445 onewire_lock(sc); 446 for (d = TAILQ_FIRST(&sc->sc_devs); 447 d != NULL; d = next) { 448 next = TAILQ_NEXT(d, d_list); 449 if (!d->d_present) { 450 config_detach(d->d_dev, DETACH_FORCE); 451 TAILQ_REMOVE(&sc->sc_devs, d, d_list); 452 free(d, M_DEVBUF); 453 } 454 } 455 onewire_unlock(sc); 456 } 457 458 MODULE(MODULE_CLASS_DRIVER, onewire, NULL); 459 460 #ifdef _MODULE 461 #include "ioconf.c" 462 #endif 463 464 static int 465 onewire_modcmd(modcmd_t cmd, void *opaque) 466 { 467 int error; 468 469 error = 0; 470 switch (cmd) { 471 case MODULE_CMD_INIT: 472 #ifdef _MODULE 473 error = config_init_component(cfdriver_ioconf_onewire, 474 cfattach_ioconf_onewire, cfdata_ioconf_onewire); 475 if (error) 476 aprint_error("%s: unable to init component\n", 477 onewire_cd.cd_name); 478 #endif 479 break; 480 case MODULE_CMD_FINI: 481 #ifdef _MODULE 482 config_fini_component(cfdriver_ioconf_onewire, 483 cfattach_ioconf_onewire, cfdata_ioconf_onewire); 484 #endif 485 break; 486 default: 487 error = ENOTTY; 488 } 489 return error; 490 } 491