1 /* $NetBSD: onewire.c,v 1.16 2014/07/25 08:10:38 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.16 2014/07/25 08:10:38 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_discard = nodiscard, 94 .d_flag = D_OTHER 95 }; 96 97 extern struct cfdriver onewire_cd; 98 99 static int 100 onewire_match(device_t parent, cfdata_t cf, void *aux) 101 { 102 return 1; 103 } 104 105 static void 106 onewire_attach(device_t parent, device_t self, void *aux) 107 { 108 struct onewire_softc *sc = device_private(self); 109 struct onewirebus_attach_args *oba = aux; 110 111 sc->sc_dev = self; 112 sc->sc_bus = oba->oba_bus; 113 rw_init(&sc->sc_rwlock); 114 TAILQ_INIT(&sc->sc_devs); 115 116 aprint_normal("\n"); 117 118 if (kthread_create(PRI_NONE, 0, NULL, onewire_thread, sc, 119 &sc->sc_thread, "%s", device_xname(self)) != 0) 120 aprint_error_dev(self, "can't create kernel thread\n"); 121 } 122 123 static int 124 onewire_detach(device_t self, int flags) 125 { 126 struct onewire_softc *sc = device_private(self); 127 int rv; 128 129 sc->sc_dying = 1; 130 if (sc->sc_thread != NULL) { 131 wakeup(sc->sc_thread); 132 tsleep(&sc->sc_dying, PWAIT, "owdt", 0); 133 } 134 135 onewire_lock(sc); 136 //rv = config_detach_children(self, flags); 137 rv = 0; /* XXX riz */ 138 onewire_unlock(sc); 139 rw_destroy(&sc->sc_rwlock); 140 141 return rv; 142 } 143 144 static int 145 onewire_activate(device_t self, enum devact act) 146 { 147 struct onewire_softc *sc = device_private(self); 148 149 switch (act) { 150 case DVACT_DEACTIVATE: 151 sc->sc_dying = 1; 152 return 0; 153 default: 154 return EOPNOTSUPP; 155 } 156 } 157 158 int 159 onewire_print(void *aux, const char *pnp) 160 { 161 struct onewire_attach_args *oa = aux; 162 const char *famname; 163 164 if (pnp == NULL) 165 aprint_normal(" "); 166 167 famname = onewire_famname(ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom)); 168 if (famname == NULL) 169 aprint_normal("family 0x%02x", 170 (uint)ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom)); 171 else 172 aprint_normal("\"%s\"", famname); 173 aprint_normal(" sn %012llx", ONEWIRE_ROM_SN(oa->oa_rom)); 174 175 if (pnp != NULL) 176 aprint_normal(" at %s", pnp); 177 178 return UNCONF; 179 } 180 181 int 182 onewirebus_print(void *aux, const char *pnp) 183 { 184 if (pnp != NULL) 185 aprint_normal("onewire at %s", pnp); 186 187 return UNCONF; 188 } 189 190 void 191 onewire_lock(void *arg) 192 { 193 struct onewire_softc *sc = arg; 194 195 rw_enter(&sc->sc_rwlock, RW_WRITER); 196 } 197 198 void 199 onewire_unlock(void *arg) 200 { 201 struct onewire_softc *sc = arg; 202 203 rw_exit(&sc->sc_rwlock); 204 } 205 206 int 207 onewire_reset(void *arg) 208 { 209 struct onewire_softc *sc = arg; 210 struct onewire_bus *bus = sc->sc_bus; 211 212 return bus->bus_reset(bus->bus_cookie); 213 } 214 215 int 216 onewire_bit(void *arg, int value) 217 { 218 struct onewire_softc *sc = arg; 219 struct onewire_bus *bus = sc->sc_bus; 220 221 return bus->bus_bit(bus->bus_cookie, value); 222 } 223 224 int 225 onewire_read_byte(void *arg) 226 { 227 struct onewire_softc *sc = arg; 228 struct onewire_bus *bus = sc->sc_bus; 229 uint8_t value = 0; 230 int i; 231 232 if (bus->bus_read_byte != NULL) 233 return bus->bus_read_byte(bus->bus_cookie); 234 235 for (i = 0; i < 8; i++) 236 value |= (bus->bus_bit(bus->bus_cookie, 1) << i); 237 238 return value; 239 } 240 241 void 242 onewire_write_byte(void *arg, int value) 243 { 244 struct onewire_softc *sc = arg; 245 struct onewire_bus *bus = sc->sc_bus; 246 int i; 247 248 if (bus->bus_write_byte != NULL) 249 return bus->bus_write_byte(bus->bus_cookie, value); 250 251 for (i = 0; i < 8; i++) 252 bus->bus_bit(bus->bus_cookie, (value >> i) & 0x1); 253 } 254 255 int 256 onewire_triplet(void *arg, int dir) 257 { 258 struct onewire_softc *sc = arg; 259 struct onewire_bus *bus = sc->sc_bus; 260 int rv; 261 262 if (bus->bus_triplet != NULL) 263 return bus->bus_triplet(bus->bus_cookie, dir); 264 265 rv = bus->bus_bit(bus->bus_cookie, 1); 266 rv <<= 1; 267 rv |= bus->bus_bit(bus->bus_cookie, 1); 268 269 switch (rv) { 270 case 0x0: 271 bus->bus_bit(bus->bus_cookie, dir); 272 break; 273 case 0x1: 274 bus->bus_bit(bus->bus_cookie, 0); 275 break; 276 default: 277 bus->bus_bit(bus->bus_cookie, 1); 278 } 279 280 return rv; 281 } 282 283 void 284 onewire_read_block(void *arg, void *buf, int len) 285 { 286 uint8_t *p = buf; 287 288 while (len--) 289 *p++ = onewire_read_byte(arg); 290 } 291 292 void 293 onewire_write_block(void *arg, const void *buf, int len) 294 { 295 const uint8_t *p = buf; 296 297 while (len--) 298 onewire_write_byte(arg, *p++); 299 } 300 301 void 302 onewire_matchrom(void *arg, u_int64_t rom) 303 { 304 int i; 305 306 onewire_write_byte(arg, ONEWIRE_CMD_MATCH_ROM); 307 for (i = 0; i < 8; i++) 308 onewire_write_byte(arg, (rom >> (i * 8)) & 0xff); 309 } 310 311 static void 312 onewire_thread(void *arg) 313 { 314 struct onewire_softc *sc = arg; 315 316 while (!sc->sc_dying) { 317 onewire_scan(sc); 318 tsleep(sc->sc_thread, PWAIT, "owidle", ONEWIRE_SCANTIME * hz); 319 } 320 321 sc->sc_thread = NULL; 322 wakeup(&sc->sc_dying); 323 kthread_exit(0); 324 } 325 326 static void 327 onewire_scan(struct onewire_softc *sc) 328 { 329 struct onewire_device *d, *next, *nd; 330 struct onewire_attach_args oa; 331 device_t dev; 332 int search = 1, count = 0, present; 333 int dir, rv; 334 uint64_t mask, rom = 0, lastrom; 335 uint8_t data[8]; 336 int i, i0 = -1, lastd = -1; 337 338 TAILQ_FOREACH(d, &sc->sc_devs, d_list) 339 d->d_present = 0; 340 341 while (search && count++ < ONEWIRE_MAXDEVS) { 342 /* XXX: yield processor */ 343 tsleep(sc, PWAIT, "owscan", hz / 10); 344 345 /* 346 * Reset the bus. If there's no presence pulse 347 * don't search for any devices. 348 */ 349 onewire_lock(sc); 350 if (onewire_reset(sc) != 0) { 351 DPRINTF(("%s: scan: no presence pulse\n", 352 device_xname(sc->sc_dev))); 353 onewire_unlock(sc); 354 break; 355 } 356 357 /* 358 * Start new search. Go through the previous path to 359 * the point we made a decision last time and make an 360 * opposite decision. If we didn't make any decision 361 * stop searching. 362 */ 363 search = 0; 364 lastrom = rom; 365 rom = 0; 366 onewire_write_byte(sc, ONEWIRE_CMD_SEARCH_ROM); 367 for (i = 0,i0 = -1; i < 64; i++) { 368 dir = (lastrom >> i) & 0x1; 369 if (i == lastd) 370 dir = 1; 371 else if (i > lastd) 372 dir = 0; 373 rv = onewire_triplet(sc, dir); 374 switch (rv) { 375 case 0x0: 376 if (i != lastd) { 377 if (dir == 0) 378 i0 = i; 379 search = 1; 380 } 381 mask = dir; 382 break; 383 case 0x1: 384 mask = 0; 385 break; 386 case 0x2: 387 mask = 1; 388 break; 389 default: 390 DPRINTF(("%s: scan: triplet error 0x%x, " 391 "step %d\n", 392 device_xname(sc->sc_dev), rv, i)); 393 onewire_unlock(sc); 394 return; 395 } 396 rom |= (mask << i); 397 } 398 lastd = i0; 399 onewire_unlock(sc); 400 401 if (rom == 0) 402 continue; 403 404 /* 405 * The last byte of the ROM code contains a CRC calculated 406 * from the first 7 bytes. Re-calculate it to make sure 407 * we found a valid device. 408 */ 409 for (i = 0; i < 8; i++) 410 data[i] = (rom >> (i * 8)) & 0xff; 411 if (onewire_crc(data, 7) != data[7]) 412 continue; 413 414 /* 415 * Go through the list of attached devices to see if we 416 * found a new one. 417 */ 418 present = 0; 419 TAILQ_FOREACH(d, &sc->sc_devs, d_list) { 420 if (d->d_rom == rom) { 421 d->d_present = 1; 422 present = 1; 423 break; 424 } 425 } 426 if (!present) { 427 memset(&oa, 0, sizeof(oa)); 428 oa.oa_onewire = sc; 429 oa.oa_rom = rom; 430 if ((dev = config_found(sc->sc_dev, &oa, 431 onewire_print)) == NULL) 432 continue; 433 434 nd = malloc(sizeof(struct onewire_device), 435 M_DEVBUF, M_NOWAIT); 436 if (nd == NULL) 437 continue; 438 nd->d_dev = dev; 439 nd->d_rom = rom; 440 nd->d_present = 1; 441 TAILQ_INSERT_TAIL(&sc->sc_devs, nd, d_list); 442 } 443 } 444 445 /* Detach disappeared devices */ 446 onewire_lock(sc); 447 for (d = TAILQ_FIRST(&sc->sc_devs); 448 d != NULL; d = next) { 449 next = TAILQ_NEXT(d, d_list); 450 if (!d->d_present) { 451 config_detach(d->d_dev, DETACH_FORCE); 452 TAILQ_REMOVE(&sc->sc_devs, d, d_list); 453 free(d, M_DEVBUF); 454 } 455 } 456 onewire_unlock(sc); 457 } 458 459 MODULE(MODULE_CLASS_DRIVER, onewire, NULL); 460 461 #ifdef _MODULE 462 #include "ioconf.c" 463 #endif 464 465 static int 466 onewire_modcmd(modcmd_t cmd, void *opaque) 467 { 468 int error; 469 470 error = 0; 471 switch (cmd) { 472 case MODULE_CMD_INIT: 473 #ifdef _MODULE 474 error = config_init_component(cfdriver_ioconf_onewire, 475 cfattach_ioconf_onewire, cfdata_ioconf_onewire); 476 if (error) 477 aprint_error("%s: unable to init component\n", 478 onewire_cd.cd_name); 479 #endif 480 break; 481 case MODULE_CMD_FINI: 482 #ifdef _MODULE 483 config_fini_component(cfdriver_ioconf_onewire, 484 cfattach_ioconf_onewire, cfdata_ioconf_onewire); 485 #endif 486 break; 487 default: 488 error = ENOTTY; 489 } 490 return error; 491 } 492