1 2 /* $NetBSD: sht3x.c,v 1.10 2025/01/23 19:14:46 brad Exp $ */ 3 4 /* 5 * Copyright (c) 2021 Brad Spencer <brad@anduin.eldar.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: sht3x.c,v 1.10 2025/01/23 19:14:46 brad Exp $"); 22 23 /* 24 Driver for the Sensirion SHT30/SHT31/SHT35 25 */ 26 27 #include <sys/param.h> 28 #include <sys/systm.h> 29 #include <sys/kernel.h> 30 #include <sys/device.h> 31 #include <sys/module.h> 32 #include <sys/conf.h> 33 #include <sys/sysctl.h> 34 #include <sys/mutex.h> 35 #include <sys/condvar.h> 36 #include <sys/kthread.h> 37 #include <sys/pool.h> 38 #include <sys/kmem.h> 39 40 #include <dev/sysmon/sysmonvar.h> 41 #include <dev/i2c/i2cvar.h> 42 #include <dev/i2c/sht3xreg.h> 43 #include <dev/i2c/sht3xvar.h> 44 45 static int sht3x_take_break(void *, bool); 46 static int sht3x_get_status_register(void *, uint16_t *, bool); 47 static int sht3x_clear_status_register(void *, bool); 48 static uint8_t sht3x_crc(uint8_t *, size_t); 49 static int sht3x_cmdr(struct sht3x_sc *, uint16_t, uint8_t *, size_t); 50 static int sht3x_poke(i2c_tag_t, i2c_addr_t, bool); 51 static int sht3x_match(device_t, cfdata_t, void *); 52 static void sht3x_attach(device_t, device_t, void *); 53 static int sht3x_detach(device_t, int); 54 static void sht3x_refresh(struct sysmon_envsys *, envsys_data_t *); 55 static int sht3x_verify_sysctl(SYSCTLFN_ARGS); 56 static int sht3x_verify_sysctl_heateron(SYSCTLFN_ARGS); 57 static int sht3x_verify_sysctl_modes(SYSCTLFN_ARGS); 58 static int sht3x_verify_sysctl_repeatability(SYSCTLFN_ARGS); 59 static int sht3x_verify_sysctl_rate(SYSCTLFN_ARGS); 60 static int sht3x_set_heater(struct sht3x_sc *); 61 static void sht3x_thread(void *); 62 static int sht3x_init_periodic_measurement(void *, int *); 63 static void sht3x_take_periodic_measurement(void *); 64 static void sht3x_start_thread(void *); 65 static void sht3x_stop_thread(void *); 66 static int sht3x_activate(device_t, enum devact); 67 68 #define SHT3X_DEBUG 69 #ifdef SHT3X_DEBUG 70 #define DPRINTF(s, l, x) \ 71 do { \ 72 if (l <= s->sc_sht3xdebug) \ 73 printf x; \ 74 } while (/*CONSTCOND*/0) 75 #else 76 #define DPRINTF(s, l, x) 77 #endif 78 79 CFATTACH_DECL_NEW(sht3xtemp, sizeof(struct sht3x_sc), 80 sht3x_match, sht3x_attach, sht3x_detach, sht3x_activate); 81 82 extern struct cfdriver sht3xtemp_cd; 83 84 static dev_type_open(sht3xopen); 85 static dev_type_read(sht3xread); 86 static dev_type_close(sht3xclose); 87 const struct cdevsw sht3x_cdevsw = { 88 .d_open = sht3xopen, 89 .d_close = sht3xclose, 90 .d_read = sht3xread, 91 .d_write = nowrite, 92 .d_ioctl = noioctl, 93 .d_stop = nostop, 94 .d_tty = notty, 95 .d_poll = nopoll, 96 .d_mmap = nommap, 97 .d_kqfilter = nokqfilter, 98 .d_discard = nodiscard, 99 .d_flag = D_OTHER 100 }; 101 102 static struct sht3x_sensor sht3x_sensors[] = { 103 { 104 .desc = "humidity", 105 .type = ENVSYS_SRELHUMIDITY, 106 }, 107 { 108 .desc = "temperature", 109 .type = ENVSYS_STEMP, 110 } 111 }; 112 113 /* The typical delays are MOSTLY documented in the datasheet for the chip. 114 There is no need to be very accurate with these, just rough estimates 115 will work fine. 116 */ 117 118 static struct sht3x_timing sht3x_timings[] = { 119 { 120 .cmd = SHT3X_SOFT_RESET, 121 .typicaldelay = 3000, 122 }, 123 { 124 .cmd = SHT3X_GET_STATUS_REGISTER, 125 .typicaldelay = 100, 126 }, 127 { 128 .cmd = SHT3X_BREAK, 129 .typicaldelay = 100, 130 }, 131 { 132 .cmd = SHT3X_CLEAR_STATUS_REGISTER, 133 .typicaldelay = 100, 134 }, 135 { 136 .cmd = SHT3X_MEASURE_REPEATABILITY_CS_HIGH, 137 .typicaldelay = 15000, 138 }, 139 { 140 .cmd = SHT3X_MEASURE_REPEATABILITY_CS_MEDIUM, 141 .typicaldelay = 6000, 142 }, 143 { 144 .cmd = SHT3X_MEASURE_REPEATABILITY_CS_LOW, 145 .typicaldelay = 4000, 146 }, 147 { 148 .cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_HIGH, 149 .typicaldelay = 15000, 150 }, 151 { 152 .cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_MEDIUM, 153 .typicaldelay = 6000, 154 }, 155 { 156 .cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_LOW, 157 .typicaldelay = 4000, 158 }, 159 { 160 .cmd = SHT3X_WRITE_HIGH_ALERT_SET, 161 .typicaldelay = 5000, 162 }, 163 { 164 .cmd = SHT3X_WRITE_HIGH_ALERT_CLEAR, 165 .typicaldelay = 5000, 166 }, 167 { 168 .cmd = SHT3X_WRITE_LOW_ALERT_SET, 169 .typicaldelay = 5000, 170 }, 171 { 172 .cmd = SHT3X_WRITE_LOW_ALERT_CLEAR, 173 .typicaldelay = 5000, 174 }, 175 { 176 .cmd = SHT3X_READ_SERIAL_NUMBER, 177 .typicaldelay = 500, 178 } 179 }; 180 181 /* In single shot mode, find the command */ 182 183 static struct sht3x_repeatability sht3x_repeatability_ss[] = { 184 { 185 .text = "high", 186 .cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_HIGH, 187 .cscmd = SHT3X_MEASURE_REPEATABILITY_CS_HIGH, 188 }, 189 { 190 .text = "medium", 191 .cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_MEDIUM, 192 .cscmd = SHT3X_MEASURE_REPEATABILITY_CS_MEDIUM, 193 }, 194 { 195 .text = "low", 196 .cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_LOW, 197 .cscmd = SHT3X_MEASURE_REPEATABILITY_CS_LOW, 198 } 199 }; 200 201 202 /* For periodic, look at the repeatability and the rate. 203 * ART is a bit fake here, as the repeatability is not really 204 * used. 205 */ 206 207 static struct sht3x_periodic sht3x_periodic_rate[] = { 208 { 209 .repeatability = "high", 210 .rate = "0.5mps", 211 .sdelay = 1000, 212 .cmd = SHT3X_HALF_MPS_HIGH, 213 }, 214 { 215 .repeatability = "medium", 216 .rate = "0.5mps", 217 .sdelay = 1000, 218 .cmd = SHT3X_HALF_MPS_MEDIUM, 219 }, 220 { 221 .repeatability = "low", 222 .rate = "0.5mps", 223 .sdelay = 1000, 224 .cmd = SHT3X_HALF_MPS_LOW, 225 }, 226 { 227 .repeatability = "high", 228 .rate = "1.0mps", 229 .sdelay = 500, 230 .cmd = SHT3X_ONE_MPS_HIGH, 231 }, 232 { 233 .repeatability = "medium", 234 .rate = "1.0mps", 235 .sdelay = 500, 236 .cmd = SHT3X_ONE_MPS_MEDIUM, 237 }, 238 { 239 .repeatability = "low", 240 .rate = "1.0mps", 241 .sdelay = 500, 242 .cmd = SHT3X_ONE_MPS_LOW, 243 }, 244 { 245 .repeatability = "high", 246 .rate = "2.0mps", 247 .sdelay = 250, 248 .cmd = SHT3X_TWO_MPS_HIGH, 249 }, 250 { 251 .repeatability = "medium", 252 .rate = "2.0mps", 253 .sdelay = 250, 254 .cmd = SHT3X_TWO_MPS_MEDIUM, 255 }, 256 { 257 .repeatability = "low", 258 .rate = "2.0mps", 259 .sdelay = 250, 260 .cmd = SHT3X_TWO_MPS_LOW, 261 }, 262 { 263 .repeatability = "high", 264 .rate = "4.0mps", 265 .sdelay = 100, 266 .cmd = SHT3X_FOUR_MPS_HIGH, 267 }, 268 { 269 .repeatability = "medium", 270 .rate = "4.0mps", 271 .sdelay = 100, 272 .cmd = SHT3X_FOUR_MPS_MEDIUM, 273 }, 274 { 275 .repeatability = "low", 276 .rate = "4.0mps", 277 .sdelay = 100, 278 .cmd = SHT3X_FOUR_MPS_LOW, 279 }, 280 { 281 .repeatability = "high", 282 .rate = "10.0mps", 283 .sdelay = 50, 284 .cmd = SHT3X_TEN_MPS_HIGH, 285 }, 286 { 287 .repeatability = "medium", 288 .rate = "10.0mps", 289 .sdelay = 50, 290 .cmd = SHT3X_FOUR_MPS_MEDIUM, 291 }, 292 { 293 .repeatability = "low", 294 .rate = "10.0mps", 295 .sdelay = 50, 296 .cmd = SHT3X_FOUR_MPS_LOW, 297 }, 298 { 299 .repeatability = "high", 300 .rate = "ART", 301 .sdelay = 100, 302 .cmd = SHT3X_ART_ENABLE, 303 }, 304 { 305 .repeatability = "medium", 306 .rate = "ART", 307 .sdelay = 100, 308 .cmd = SHT3X_ART_ENABLE, 309 }, 310 { 311 .repeatability = "low", 312 .rate = "ART", 313 .sdelay = 100, 314 .cmd = SHT3X_ART_ENABLE, 315 } 316 }; 317 318 static const char sht3x_rate_names[] = 319 "0.5mps, 1.0mps, 2.0mps, 4.0mps, 10.0mps, ART"; 320 321 static const char sht3x_mode_names[] = 322 "single-shot, periodic"; 323 324 static const char sht3x_repeatability_names[] = 325 "high, medium, low"; 326 327 static int 328 sht3x_take_break(void *aux, bool have_bus) 329 { 330 struct sht3x_sc *sc; 331 sc = aux; 332 int error = 0; 333 334 if (! have_bus) { 335 error = iic_acquire_bus(sc->sc_tag, 0); 336 if (error) { 337 DPRINTF(sc, 2, ("%s: Could not acquire iic bus for " 338 "breaking %d\n", device_xname(sc->sc_dev), error)); 339 goto out; 340 } 341 } 342 error = sht3x_cmdr(sc, SHT3X_BREAK, NULL, 0); 343 if (error) { 344 DPRINTF(sc, 2, ("%s: Error breaking: %d\n", 345 device_xname(sc->sc_dev), error)); 346 } 347 out: 348 if (! have_bus) { 349 iic_release_bus(sc->sc_tag, 0); 350 } 351 352 sc->sc_isperiodic = false; 353 strlcpy(sc->sc_mode, "single-shot", SHT3X_MODE_NAME); 354 355 return error; 356 } 357 358 static int 359 sht3x_get_status_register(void *aux, uint16_t *reg, bool have_bus) 360 { 361 struct sht3x_sc *sc = aux; 362 uint8_t buf[3]; 363 int error; 364 365 if (! have_bus) { 366 error = iic_acquire_bus(sc->sc_tag, 0); 367 if (error) { 368 DPRINTF(sc, 2, ("%s: Could not acquire iic bus for " 369 "getting status %d\n", device_xname(sc->sc_dev), 370 error)); 371 return error; 372 } 373 } 374 error = sht3x_cmdr(sc, SHT3X_GET_STATUS_REGISTER, buf, 3); 375 if (error) { 376 DPRINTF(sc, 2, ("%s: Error getting status: %d\n", 377 device_xname(sc->sc_dev), error)); 378 goto out; 379 } 380 381 uint8_t c = sht3x_crc(&buf[0], 2); 382 if (c == buf[2]) { 383 *reg = buf[0] << 8 | buf[1]; 384 } else { 385 error = EINVAL; 386 } 387 out: 388 if (! have_bus) { 389 iic_release_bus(sc->sc_tag, 0); 390 } 391 392 return error; 393 } 394 395 static int 396 sht3x_clear_status_register(void *aux, bool have_bus) 397 { 398 struct sht3x_sc *sc = aux; 399 int error; 400 401 if (! have_bus) { 402 error = iic_acquire_bus(sc->sc_tag, 0); 403 if (error) { 404 DPRINTF(sc, 2, ("%s: Could not acquire iic bus for " 405 "clearing status %d\n", device_xname(sc->sc_dev), 406 error)); 407 return error; 408 } 409 } 410 error = sht3x_cmdr(sc, SHT3X_CLEAR_STATUS_REGISTER, NULL, 0); 411 if (error) { 412 DPRINTF(sc, 2, ("%s: Error clear status register: %d\n", 413 device_xname(sc->sc_dev), error)); 414 } 415 if (! have_bus) { 416 iic_release_bus(sc->sc_tag, 0); 417 } 418 419 return error; 420 } 421 422 void 423 sht3x_thread(void *aux) 424 { 425 struct sht3x_sc *sc = aux; 426 int error, rv; 427 int sdelay = 100; 428 429 mutex_enter(&sc->sc_threadmutex); 430 431 while (!sc->sc_stopping && !sc->sc_dying) { 432 if (sc->sc_initperiodic) { 433 error = sht3x_init_periodic_measurement(sc, &sdelay); 434 if (error) { 435 DPRINTF(sc, 2, ("%s: Error initing periodic " 436 "measurement in thread: %d\n", 437 device_xname(sc->sc_dev), error)); 438 } 439 sc->sc_initperiodic = false; 440 } 441 rv = cv_timedwait(&sc->sc_condvar, &sc->sc_threadmutex, 442 mstohz(sdelay)); 443 if (rv == EWOULDBLOCK && !sc->sc_stopping && 444 !sc->sc_initperiodic && !sc->sc_dying) { 445 sht3x_take_periodic_measurement(sc); 446 } 447 } 448 mutex_exit(&sc->sc_threadmutex); 449 kthread_exit(0); 450 } 451 452 int 453 sht3x_init_periodic_measurement(void *aux, int *sdelay) 454 { 455 struct sht3x_sc *sc = aux; 456 size_t i; 457 int error; 458 uint16_t r; 459 460 for (i = 0; i < __arraycount(sht3x_periodic_rate); i++) { 461 if (strncmp(sc->sc_repeatability, 462 sht3x_periodic_rate[i].repeatability, SHT3X_REP_NAME) == 0 && 463 strncmp(sc->sc_periodic_rate, sht3x_periodic_rate[i].rate, 464 SHT3X_RATE_NAME) == 0) 465 { 466 r = sht3x_periodic_rate[i].cmd; 467 *sdelay = sht3x_periodic_rate[i].sdelay; 468 break; 469 } 470 } 471 472 if (i == __arraycount(sht3x_periodic_rate)) { 473 *sdelay = 100; 474 return ENODEV; 475 } 476 477 DPRINTF(sc, 2, ("%s: Would init with: %x\n", 478 device_xname(sc->sc_dev), r)); 479 480 mutex_enter(&sc->sc_mutex); 481 482 error = iic_acquire_bus(sc->sc_tag, 0); 483 if (error) { 484 DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: " 485 " %d\n", device_xname(sc->sc_dev), error)); 486 goto outm; 487 } 488 489 error = sht3x_take_break(sc, true); 490 if (error) { 491 DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: " 492 " %d\n", device_xname(sc->sc_dev), error)); 493 goto out; 494 } 495 496 error = sht3x_cmdr(sc, r, NULL, 0); 497 if (error) { 498 DPRINTF(sc, 2, 499 ("%s: Error sending periodic measurement command: %d\n", 500 device_xname(sc->sc_dev), error)); 501 goto out; 502 } 503 504 sc->sc_isperiodic = true; 505 strlcpy(sc->sc_mode, "periodic", SHT3X_MODE_NAME); 506 507 out: 508 iic_release_bus(sc->sc_tag, 0); 509 outm: 510 mutex_exit(&sc->sc_mutex); 511 return error; 512 } 513 514 static void 515 sht3x_take_periodic_measurement(void *aux) 516 { 517 struct sht3x_sc *sc = aux; 518 int error; 519 struct sht3x_read_q *pp; 520 uint8_t rawbuf[MAX(sizeof(sc->sc_pbuffer), sizeof(pp->measurement))]; 521 uint16_t status_reg; 522 523 mutex_enter(&sc->sc_mutex); 524 error = iic_acquire_bus(sc->sc_tag, 0); 525 if (error) { 526 DPRINTF(sc, 2, ("%s: Could not acquire iic bus for getting " 527 "periodic data: %d\n", device_xname(sc->sc_dev), error)); 528 goto out; 529 } 530 531 error = sht3x_get_status_register(sc, &status_reg, true); 532 if (error) { 533 DPRINTF(sc, 2, 534 ("%s: Error getting status register periodic: %d\n", 535 device_xname(sc->sc_dev), error)); 536 goto err; 537 } 538 539 if (status_reg & SHT3X_RESET_DETECTED) { 540 aprint_error_dev(sc->sc_dev, "Reset detected in periodic mode. " 541 "Heater may have been reset.\n"); 542 delay(3000); 543 sht3x_take_break(sc, true); 544 sht3x_clear_status_register(sc, true); 545 sc->sc_heateron = status_reg & SHT3X_HEATER_STATUS; 546 sc->sc_initperiodic = true; 547 } else { 548 int data_error = sht3x_cmdr(sc, SHT3X_PERIODIC_FETCH_DATA, 549 rawbuf, sizeof(rawbuf)); 550 /* 551 * EIO is actually expected if the poll interval is faster 552 * than the rate that the sensor is set to. Unfortunately, 553 * this will also mess with the ability to detect an actual 554 * problem with the sensor in periodic mode, so we do the best 555 * we can here. 556 */ 557 if (data_error) { 558 if (data_error != EIO) { 559 DPRINTF(sc, 2, ("%s: Error sending periodic " 560 "fetch command: %d\n", 561 device_xname(sc->sc_dev), data_error)); 562 } 563 goto err; 564 } 565 } 566 567 iic_release_bus(sc->sc_tag, 0); 568 /* 569 * If there was no errors from anything then the data should be 570 * valid. 571 */ 572 DPRINTF(sc, 2, ("%s: Raw periodic: %x%x - %x -- %x%x - %x\n", 573 device_xname(sc->sc_dev), rawbuf[0], rawbuf[1], rawbuf[2], 574 rawbuf[3], rawbuf[4], rawbuf[5])); 575 memcpy(sc->sc_pbuffer, rawbuf, sizeof(sc->sc_pbuffer)); 576 577 if (sc->sc_opened) { 578 mutex_enter(&sc->sc_read_mutex); 579 pp = pool_cache_get(sc->sc_readpool, PR_NOWAIT); 580 if (pp == NULL) { 581 aprint_error_dev(sc->sc_dev, 582 "Could not allocate memory for pool read\n"); 583 } else { 584 memcpy(pp->measurement, rawbuf, sizeof(pp->measurement)); 585 DPRINTF(sc, 4, ("%s: Queue insert\n", 586 device_xname(sc->sc_dev))); 587 SIMPLEQ_INSERT_HEAD(&sc->sc_read_queue, pp, read_q); 588 } 589 cv_signal(&sc->sc_condreadready); 590 mutex_exit(&sc->sc_read_mutex); 591 } 592 out: 593 mutex_exit(&sc->sc_mutex); 594 return; 595 err: 596 /* 597 * We are only going to worry about errors when it was not related 598 * to actually getting data. That is a likely indicator of a problem 599 * with the sensor. 600 */ 601 DPRINTF(sc, 2, ("%s: Raw periodic with error: %x%x - %x -- " 602 "%x%x - %x -- %d\n", device_xname(sc->sc_dev), rawbuf[0], rawbuf[1], 603 rawbuf[2], rawbuf[3], rawbuf[4], rawbuf[5], error)); 604 iic_release_bus(sc->sc_tag, 0); 605 if (error != 0) { 606 memcpy(sc->sc_pbuffer, "dedbef", sizeof(sc->sc_pbuffer)); 607 } 608 mutex_exit(&sc->sc_mutex); 609 } 610 611 static void 612 sht3x_stop_thread(void *aux) 613 { 614 struct sht3x_sc *sc; 615 sc = aux; 616 617 if (!sc->sc_isperiodic) { 618 return; 619 } 620 621 mutex_enter(&sc->sc_threadmutex); 622 sc->sc_stopping = true; 623 cv_signal(&sc->sc_condvar); 624 mutex_exit(&sc->sc_threadmutex); 625 626 /* wait for the thread to exit */ 627 kthread_join(sc->sc_thread); 628 629 mutex_enter(&sc->sc_mutex); 630 sht3x_take_break(sc,false); 631 mutex_exit(&sc->sc_mutex); 632 } 633 634 static void 635 sht3x_start_thread(void *aux) 636 { 637 struct sht3x_sc *sc; 638 sc = aux; 639 int error; 640 641 error = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN, NULL, 642 sht3x_thread, sc, &sc->sc_thread, "%s", device_xname(sc->sc_dev)); 643 if (error) { 644 DPRINTF(sc, 2, ("%s: Unable to create measurement thread: %d\n", 645 device_xname(sc->sc_dev), error)); 646 } 647 } 648 649 int 650 sht3x_verify_sysctl(SYSCTLFN_ARGS) 651 { 652 int error, t; 653 struct sysctlnode node; 654 655 node = *rnode; 656 t = *(int *)rnode->sysctl_data; 657 node.sysctl_data = &t; 658 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 659 if (error || newp == NULL) 660 return error; 661 662 if (t < 0) 663 return EINVAL; 664 665 *(int *)rnode->sysctl_data = t; 666 667 return 0; 668 } 669 670 int 671 sht3x_verify_sysctl_heateron(SYSCTLFN_ARGS) 672 { 673 int error; 674 bool t; 675 struct sht3x_sc *sc; 676 struct sysctlnode node; 677 678 node = *rnode; 679 sc = node.sysctl_data; 680 t = sc->sc_heateron; 681 node.sysctl_data = &t; 682 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 683 if (error || newp == NULL) 684 return error; 685 686 sc->sc_heateron = t; 687 error = sht3x_set_heater(sc); 688 689 return error; 690 } 691 692 static int 693 sht3x_set_heater(struct sht3x_sc *sc) 694 { 695 int error = 0; 696 uint16_t cmd; 697 698 mutex_enter(&sc->sc_mutex); 699 error = iic_acquire_bus(sc->sc_tag, 0); 700 if (error) { 701 DPRINTF(sc, 2, ("%s:%s: Failed to acquire bus: %d\n", 702 device_xname(sc->sc_dev), __func__, error)); 703 goto out; 704 } 705 706 if (sc->sc_heateron) { 707 cmd = SHT3X_HEATER_ENABLE; 708 } else { 709 cmd = SHT3X_HEATER_DISABLE; 710 } 711 712 error = sht3x_cmdr(sc, cmd, NULL, 0); 713 714 iic_release_bus(sc->sc_tag,0); 715 out: 716 mutex_exit(&sc->sc_mutex); 717 718 return error; 719 } 720 721 int 722 sht3x_verify_sysctl_modes(SYSCTLFN_ARGS) 723 { 724 char buf[SHT3X_MODE_NAME]; 725 struct sht3x_sc *sc; 726 struct sysctlnode node; 727 bool is_ss = false; 728 bool is_periodic = false; 729 int error; 730 731 node = *rnode; 732 sc = node.sysctl_data; 733 (void) memcpy(buf, sc->sc_mode, SHT3X_MODE_NAME); 734 node.sysctl_data = buf; 735 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 736 if (error || newp == NULL) 737 return error; 738 739 if (sc->sc_opened) { 740 return EINVAL; 741 } 742 743 is_ss = strncmp(node.sysctl_data, "single-shot", SHT3X_MODE_NAME) == 0; 744 is_periodic = strncmp(node.sysctl_data, "periodic", SHT3X_MODE_NAME) 745 == 0; 746 747 if (!is_ss && !is_periodic) { 748 return EINVAL; 749 } 750 751 (void) memcpy(sc->sc_mode, node.sysctl_data, SHT3X_MODE_NAME); 752 if (is_ss) { 753 sht3x_stop_thread(sc); 754 sc->sc_stopping = false; 755 sc->sc_initperiodic = false; 756 sc->sc_isperiodic = false; 757 } 758 759 if (is_periodic) { 760 sc->sc_stopping = false; 761 sc->sc_initperiodic = true; 762 sc->sc_isperiodic = true; 763 sht3x_start_thread(sc); 764 } 765 766 return 0; 767 } 768 769 int 770 sht3x_verify_sysctl_repeatability(SYSCTLFN_ARGS) 771 { 772 char buf[SHT3X_REP_NAME]; 773 struct sht3x_sc *sc; 774 struct sysctlnode node; 775 int error; 776 size_t i; 777 778 node = *rnode; 779 sc = node.sysctl_data; 780 (void) memcpy(buf, sc->sc_repeatability, SHT3X_REP_NAME); 781 node.sysctl_data = buf; 782 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 783 if (error || newp == NULL) 784 return error; 785 786 for (i = 0; i < __arraycount(sht3x_repeatability_ss); i++) { 787 if (strncmp(node.sysctl_data, sht3x_repeatability_ss[i].text, 788 SHT3X_REP_NAME) == 0) { 789 break; 790 } 791 } 792 793 if (i == __arraycount(sht3x_repeatability_ss)) 794 return EINVAL; 795 (void) memcpy(sc->sc_repeatability, node.sysctl_data, SHT3X_REP_NAME); 796 797 if (sc->sc_isperiodic) { 798 sc->sc_initperiodic = true; 799 } 800 801 return error; 802 } 803 804 int 805 sht3x_verify_sysctl_rate(SYSCTLFN_ARGS) 806 { 807 char buf[SHT3X_RATE_NAME]; 808 struct sht3x_sc *sc; 809 struct sysctlnode node; 810 int error; 811 size_t i; 812 813 node = *rnode; 814 sc = node.sysctl_data; 815 (void) memcpy(buf, sc->sc_periodic_rate, SHT3X_RATE_NAME); 816 node.sysctl_data = buf; 817 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 818 if (error || newp == NULL) 819 return error; 820 821 for (i = 0; i < __arraycount(sht3x_periodic_rate); i++) { 822 if (strncmp(node.sysctl_data, sht3x_periodic_rate[i].rate, 823 SHT3X_RATE_NAME) == 0) { 824 break; 825 } 826 } 827 828 if (i == __arraycount(sht3x_periodic_rate)) 829 return EINVAL; 830 831 (void) memcpy(sc->sc_periodic_rate, node.sysctl_data, SHT3X_RATE_NAME); 832 833 if (sc->sc_isperiodic) { 834 sc->sc_initperiodic = true; 835 } 836 837 return error; 838 } 839 840 static int 841 sht3x_cmddelay(uint16_t cmd) 842 { 843 size_t i; 844 845 for (i = 0; i < __arraycount(sht3x_timings); i++) { 846 if (cmd == sht3x_timings[i].cmd) { 847 break; 848 } 849 } 850 851 if (i == __arraycount(sht3x_timings)) { 852 return -1; 853 } 854 return sht3x_timings[i].typicaldelay; 855 } 856 857 static int 858 sht3x_cmd(i2c_tag_t tag, i2c_addr_t addr, uint16_t *cmd, 859 uint8_t clen, uint8_t *buf, size_t blen, int readattempts) 860 { 861 int error; 862 int cmddelay; 863 uint8_t cmd8[2]; 864 865 /* All commands are two bytes and must be in a proper order */ 866 KASSERT(clen == 2); 867 868 cmd8[0] = cmd[0] >> 8; 869 cmd8[1] = cmd[0] & 0x00ff; 870 871 if (cmd[0] == SHT3X_MEASURE_REPEATABILITY_CS_HIGH || 872 cmd[0] == SHT3X_MEASURE_REPEATABILITY_CS_MEDIUM || 873 cmd[0] == SHT3X_MEASURE_REPEATABILITY_CS_LOW) { 874 error = iic_exec(tag, I2C_OP_READ_WITH_STOP, addr, &cmd8[0], clen, 875 buf, blen, 0); 876 } else { 877 error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &cmd8[0], clen, 878 NULL, 0, 0); 879 if (error) 880 return error; 881 882 cmddelay = sht3x_cmddelay(cmd[0]); 883 if (cmddelay != -1) { 884 delay(cmddelay); 885 } 886 887 /* Not all commands return anything */ 888 if (blen == 0) { 889 return 0; 890 } 891 892 for (int aint = 0; aint < readattempts; aint++) { 893 error = iic_exec(tag, I2C_OP_READ_WITH_STOP, addr, NULL, 0, buf, 894 blen, 0); 895 if (error == 0) 896 break; 897 delay(1000); 898 } 899 } 900 901 return error; 902 } 903 904 static int 905 sht3x_cmdr(struct sht3x_sc *sc, uint16_t cmd, uint8_t *buf, size_t blen) 906 { 907 return sht3x_cmd(sc->sc_tag, sc->sc_addr, &cmd, 2, buf, blen, 908 sc->sc_readattempts); 909 } 910 911 static uint8_t 912 sht3x_crc(uint8_t *data, size_t size) 913 { 914 uint8_t crc = 0xFF; 915 916 for (size_t i = 0; i < size; i++) { 917 crc ^= data[i]; 918 for (size_t j = 8; j > 0; j--) { 919 if (crc & 0x80) 920 crc = (crc << 1) ^ 0x31; 921 else 922 crc <<= 1; 923 } 924 } 925 return crc; 926 } 927 928 static int 929 sht3x_poke(i2c_tag_t tag, i2c_addr_t addr, bool matchdebug) 930 { 931 uint16_t reg = SHT3X_GET_STATUS_REGISTER; 932 uint8_t buf[3]; 933 int error; 934 935 error = sht3x_cmd(tag, addr, ®, 2, buf, 3, 10); 936 if (matchdebug) { 937 printf("poke X 1: %d\n", error); 938 } 939 return error; 940 } 941 942 static int 943 sht3x_sysctl_init(struct sht3x_sc *sc) 944 { 945 int error; 946 const struct sysctlnode *cnode; 947 int sysctlroot_num; 948 949 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 950 0, CTLTYPE_NODE, device_xname(sc->sc_dev), 951 SYSCTL_DESCR("sht3x controls"), NULL, 0, NULL, 0, CTL_HW, 952 CTL_CREATE, CTL_EOL)) != 0) 953 return error; 954 955 sysctlroot_num = cnode->sysctl_num; 956 957 #ifdef SHT3X_DEBUG 958 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 959 CTLFLAG_READWRITE, CTLTYPE_INT, "debug", 960 SYSCTL_DESCR("Debug level"), sht3x_verify_sysctl, 0, 961 &sc->sc_sht3xdebug, 0, CTL_HW, sysctlroot_num, CTL_CREATE, 962 CTL_EOL)) != 0) 963 return error; 964 965 #endif 966 967 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 968 CTLFLAG_READWRITE, CTLTYPE_BOOL, "clockstretch", 969 SYSCTL_DESCR("Use clock stretch commands for measurements"), NULL, 0, 970 &sc->sc_clockstretch, 0, CTL_HW, sysctlroot_num, CTL_CREATE, 971 CTL_EOL)) != 0) 972 return error; 973 974 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 975 CTLFLAG_READWRITE, CTLTYPE_INT, "readattempts", 976 SYSCTL_DESCR("The number of times to attempt to read the values"), 977 sht3x_verify_sysctl, 0, &sc->sc_readattempts, 0, CTL_HW, 978 sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 979 return error; 980 981 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 982 CTLFLAG_READONLY, CTLTYPE_STRING, "modes", 983 SYSCTL_DESCR("Valid modes"), 0, 0, 984 __UNCONST(sht3x_mode_names), 985 sizeof(sht3x_mode_names) + 1, 986 CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 987 return error; 988 989 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 990 CTLFLAG_READWRITE, CTLTYPE_STRING, "mode", 991 SYSCTL_DESCR("Mode for measurement collection"), 992 sht3x_verify_sysctl_modes, 0, (void *) sc, 993 SHT3X_MODE_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 994 return error; 995 996 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 997 CTLFLAG_READONLY, CTLTYPE_STRING, "repeatabilities", 998 SYSCTL_DESCR("Valid repeatability values"), 0, 0, 999 __UNCONST(sht3x_repeatability_names), 1000 sizeof(sht3x_repeatability_names) + 1, 1001 CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 1002 return error; 1003 1004 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 1005 CTLFLAG_READWRITE, CTLTYPE_STRING, "repeatability", 1006 SYSCTL_DESCR("Repeatability of RH and Temp"), 1007 sht3x_verify_sysctl_repeatability, 0, (void *) sc, 1008 SHT3X_REP_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 1009 return error; 1010 1011 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 1012 CTLFLAG_READONLY, CTLTYPE_STRING, "rates", 1013 SYSCTL_DESCR("Valid periodic rates"), 0, 0, 1014 __UNCONST(sht3x_rate_names), 1015 sizeof(sht3x_rate_names) + 1, 1016 CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 1017 return error; 1018 1019 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 1020 CTLFLAG_READWRITE, CTLTYPE_STRING, "rate", 1021 SYSCTL_DESCR("Rate for periodic measurements"), 1022 sht3x_verify_sysctl_rate, 0, (void *) sc, 1023 SHT3X_RATE_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 1024 return error; 1025 1026 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 1027 CTLFLAG_READWRITE, CTLTYPE_BOOL, "ignorecrc", 1028 SYSCTL_DESCR("Ignore the CRC byte"), NULL, 0, &sc->sc_ignorecrc, 1029 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 1030 return error; 1031 1032 if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode, 1033 CTLFLAG_READWRITE, CTLTYPE_BOOL, "heateron", 1034 SYSCTL_DESCR("Heater on"), sht3x_verify_sysctl_heateron, 0, 1035 (void *)sc, 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 1036 return error; 1037 1038 return 0; 1039 } 1040 1041 static int 1042 sht3x_match(device_t parent, cfdata_t match, void *aux) 1043 { 1044 struct i2c_attach_args *ia = aux; 1045 int error, match_result; 1046 const bool matchdebug = false; 1047 1048 if (iic_use_direct_match(ia, match, NULL, &match_result)) 1049 return match_result; 1050 1051 if (matchdebug) { 1052 printf("Looking at ia_addr: %x\n",ia->ia_addr); 1053 } 1054 1055 /* indirect config - check for configured address */ 1056 if (ia->ia_addr != SHT3X_TYPICAL_ADDR_1 && 1057 ia->ia_addr != SHT3X_TYPICAL_ADDR_2) 1058 return 0; 1059 1060 /* 1061 * Check to see if something is really at this i2c address. 1062 * This will keep phantom devices from appearing 1063 */ 1064 if (iic_acquire_bus(ia->ia_tag, 0) != 0) { 1065 if (matchdebug) 1066 printf("in match acquire bus failed\n"); 1067 return 0; 1068 } 1069 1070 error = sht3x_poke(ia->ia_tag, ia->ia_addr, matchdebug); 1071 iic_release_bus(ia->ia_tag, 0); 1072 1073 return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0; 1074 } 1075 1076 static void 1077 sht3x_attach(device_t parent, device_t self, void *aux) 1078 { 1079 struct sht3x_sc *sc; 1080 struct i2c_attach_args *ia; 1081 int error, i; 1082 int ecount = 0; 1083 uint8_t buf[6]; 1084 uint32_t serialnumber; 1085 uint8_t sncrcpt1, sncrcpt2; 1086 1087 ia = aux; 1088 sc = device_private(self); 1089 1090 sc->sc_dev = self; 1091 sc->sc_tag = ia->ia_tag; 1092 sc->sc_addr = ia->ia_addr; 1093 sc->sc_sht3xdebug = 0; 1094 strlcpy(sc->sc_mode, "single-shot", SHT3X_MODE_NAME); 1095 sc->sc_isperiodic = false; 1096 strlcpy(sc->sc_repeatability, "high", SHT3X_REP_NAME); 1097 strlcpy(sc->sc_periodic_rate, "1.0mps", SHT3X_RATE_NAME); 1098 sc->sc_readattempts = 10; 1099 sc->sc_ignorecrc = false; 1100 sc->sc_heateron = false; 1101 sc->sc_sme = NULL; 1102 sc->sc_stopping = false; 1103 sc->sc_initperiodic = false; 1104 sc->sc_opened = false; 1105 sc->sc_clockstretch = false; 1106 sc->sc_dying = false; 1107 sc->sc_readpoolname = NULL; 1108 1109 aprint_normal("\n"); 1110 1111 mutex_init(&sc->sc_dying_mutex, MUTEX_DEFAULT, IPL_NONE); 1112 mutex_init(&sc->sc_read_mutex, MUTEX_DEFAULT, IPL_NONE); 1113 mutex_init(&sc->sc_threadmutex, MUTEX_DEFAULT, IPL_NONE); 1114 mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE); 1115 cv_init(&sc->sc_condvar, "sht3xcv"); 1116 cv_init(&sc->sc_condreadready, "sht3xread"); 1117 cv_init(&sc->sc_cond_dying, "sht3xdie"); 1118 sc->sc_numsensors = __arraycount(sht3x_sensors); 1119 1120 if ((sc->sc_sme = sysmon_envsys_create()) == NULL) { 1121 aprint_error_dev(self, 1122 "Unable to create sysmon structure\n"); 1123 sc->sc_sme = NULL; 1124 return; 1125 } 1126 if ((error = sht3x_sysctl_init(sc)) != 0) { 1127 aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", error); 1128 goto out; 1129 } 1130 1131 sc->sc_readpoolname = kmem_asprintf("sht3xrp%d",device_unit(self)); 1132 sc->sc_readpool = pool_cache_init(sizeof(struct sht3x_read_q), 0, 0, 0, 1133 sc->sc_readpoolname, NULL, IPL_VM, NULL, NULL, NULL); 1134 pool_cache_sethiwat(sc->sc_readpool,100); 1135 1136 SIMPLEQ_INIT(&sc->sc_read_queue); 1137 1138 error = iic_acquire_bus(sc->sc_tag, 0); 1139 if (error) { 1140 aprint_error_dev(self, "Could not acquire iic bus: %d\n", 1141 error); 1142 goto out; 1143 } 1144 1145 error = sht3x_cmdr(sc, SHT3X_SOFT_RESET, NULL, 0); 1146 if (error != 0) 1147 aprint_error_dev(self, "Reset failed: %d\n", error); 1148 1149 error = sht3x_clear_status_register(sc, true); 1150 if (error) { 1151 aprint_error_dev(self, "Failed to clear status register: %d\n", 1152 error); 1153 ecount++; 1154 } 1155 1156 uint16_t status_reg; 1157 error = sht3x_get_status_register(sc, &status_reg, true); 1158 if (error) { 1159 aprint_error_dev(self, "Failed to read status register: %d\n", 1160 error); 1161 ecount++; 1162 } 1163 1164 DPRINTF(sc, 2, ("%s: read status register values: %04x\n", 1165 device_xname(sc->sc_dev), status_reg)); 1166 1167 error = sht3x_cmdr(sc, SHT3X_READ_SERIAL_NUMBER, buf, 6); 1168 if (error) { 1169 aprint_error_dev(self, "Failed to read serial number: %d\n", 1170 error); 1171 ecount++; 1172 } 1173 1174 sncrcpt1 = sht3x_crc(&buf[0],2); 1175 sncrcpt2 = sht3x_crc(&buf[3],2); 1176 serialnumber = (buf[0] << 24) | (buf[1] << 16) | (buf[3] << 8) | buf[4]; 1177 1178 DPRINTF(sc, 2, ("%s: read serial number values: %02x%02x - %02x - " 1179 "%02x%02x - %02x -- %02x %02x\n", device_xname(sc->sc_dev), buf[0], 1180 buf[1], buf[2], buf[3], buf[4], buf[5], sncrcpt1, sncrcpt2)); 1181 1182 iic_release_bus(sc->sc_tag, 0); 1183 if (error != 0) { 1184 aprint_error_dev(self, "Unable to setup device\n"); 1185 goto out; 1186 } 1187 1188 for (i = 0; i < sc->sc_numsensors; i++) { 1189 strlcpy(sc->sc_sensors[i].desc, sht3x_sensors[i].desc, 1190 sizeof(sc->sc_sensors[i].desc)); 1191 1192 sc->sc_sensors[i].units = sht3x_sensors[i].type; 1193 sc->sc_sensors[i].state = ENVSYS_SINVALID; 1194 1195 DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i, 1196 sc->sc_sensors[i].desc)); 1197 1198 error = sysmon_envsys_sensor_attach(sc->sc_sme, 1199 &sc->sc_sensors[i]); 1200 if (error) { 1201 aprint_error_dev(self, 1202 "Unable to attach sensor %d: %d\n", i, error); 1203 goto out; 1204 } 1205 } 1206 1207 sc->sc_sme->sme_name = device_xname(sc->sc_dev); 1208 sc->sc_sme->sme_cookie = sc; 1209 sc->sc_sme->sme_refresh = sht3x_refresh; 1210 1211 DPRINTF(sc, 2, ("sht3x_attach: registering with envsys\n")); 1212 1213 if (sysmon_envsys_register(sc->sc_sme)) { 1214 aprint_error_dev(self, "unable to register with sysmon\n"); 1215 sysmon_envsys_destroy(sc->sc_sme); 1216 sc->sc_sme = NULL; 1217 return; 1218 } 1219 1220 /* 1221 * There is no documented way to ask the chip what version it is. This 1222 * is likely fine as the only apparent difference is in how precise the 1223 * measurements will be. The actual conversation with the chip is 1224 * identical no matter which one you are talking to. 1225 */ 1226 1227 aprint_normal_dev(self, "Sensirion SHT30/SHT31/SHT35, " 1228 "Serial number: %x%s", serialnumber, 1229 (sncrcpt1 == buf[2] && sncrcpt2 == buf[5]) ? "\n" : " (bad crc)\n"); 1230 return; 1231 out: 1232 sysmon_envsys_destroy(sc->sc_sme); 1233 sc->sc_sme = NULL; 1234 } 1235 1236 static uint16_t 1237 sht3x_compute_measure_command_ss(const char *repeatability, bool clockstretch) 1238 { 1239 int i; 1240 uint16_t r; 1241 1242 for (i = 0; i < __arraycount(sht3x_repeatability_ss); i++) { 1243 if (strncmp(repeatability, sht3x_repeatability_ss[i].text, 1244 SHT3X_REP_NAME) == 0) { 1245 if (clockstretch) 1246 r = sht3x_repeatability_ss[i].cscmd; 1247 else 1248 r = sht3x_repeatability_ss[i].cmd; 1249 break; 1250 } 1251 } 1252 1253 if (i == __arraycount(sht3x_repeatability_ss)) 1254 panic("Single-shot could not find command for " 1255 "repeatability: %s\n", repeatability); 1256 1257 return r; 1258 } 1259 1260 /* 1261 * The documented conversion calculations for the raw values are as follows: 1262 * 1263 * %RH = (-6 + 125 * rawvalue / 65535) 1264 * 1265 * T in Celsius = (-45 + 175 * rawvalue / 65535) 1266 * 1267 * It follows then: 1268 * 1269 * T in Kelvin = (228.15 + 175 * rawvalue / 65535) 1270 * 1271 * given the relationship between Celsius and Kelvin 1272 * 1273 * What follows reorders the calculation a bit and scales it up to avoid 1274 * the use of any floating point. All that would really have to happen 1275 * is a scale up to 10^6 for the sysenv framework, which wants 1276 * temperature in micro-kelvin and percent relative humidity scaled up 1277 * 10^6, but since this conversion uses 64 bits due to intermediate 1278 * values that are bigger than 32 bits the conversion first scales up to 1279 * 10^9 and the scales back down by 10^3 at the end. This preserves some 1280 * precision in the conversion that would otherwise be lost. 1281 */ 1282 1283 static uint64_t 1284 sht3x_compute_temp_from_raw(uint8_t msb, uint8_t lsb) { 1285 uint64_t svalue; 1286 int64_t v1; 1287 uint64_t v2; 1288 uint64_t d1 = 65535; 1289 uint64_t mul1; 1290 uint64_t mul2; 1291 uint64_t div1 = 10000; 1292 uint64_t q; 1293 1294 svalue = msb << 8 | lsb; 1295 1296 v1 = 22815; /* this is scaled up already from 228.15 */ 1297 v2 = 175; 1298 mul1 = 10000000000; 1299 mul2 = 100000000; 1300 1301 svalue = svalue * mul1; 1302 v1 = v1 * mul2; 1303 /* Perform the conversion */ 1304 q = ((v2 * (svalue / d1)) + v1) / div1; 1305 1306 return q; 1307 } 1308 1309 static uint64_t 1310 sht3x_compute_rh_from_raw(uint8_t msb, uint8_t lsb) { 1311 uint64_t svalue; 1312 int64_t v1; 1313 uint64_t v2; 1314 uint64_t d1 = 65535; 1315 uint64_t mul1; 1316 uint64_t mul2; 1317 uint64_t div1 = 10000; 1318 uint64_t q; 1319 1320 svalue = msb << 8 | lsb; 1321 1322 v1 = 0; 1323 v2 = 100; 1324 mul1 = 10000000000; 1325 mul2 = 10000000000; 1326 1327 svalue = svalue * mul1; 1328 v1 = v1 * mul2; 1329 /* Perform the conversion */ 1330 q = ((v2 * (svalue / d1)) + v1) / div1; 1331 1332 return q; 1333 } 1334 1335 static int 1336 sht3x_parse_data(struct sht3x_sc *sc, envsys_data_t *edata, uint8_t *rawdata) 1337 { 1338 uint64_t current_value; 1339 uint8_t *svalptr; 1340 1341 DPRINTF(sc, 2, ("%s: Raw data: %02x%02x %02x - %02x%02x %02x\n", 1342 device_xname(sc->sc_dev), rawdata[0], rawdata[1], rawdata[2], 1343 rawdata[3], rawdata[4], rawdata[5])); 1344 1345 switch (edata->sensor) { 1346 case SHT3X_TEMP_SENSOR: 1347 current_value = sht3x_compute_temp_from_raw(rawdata[0], 1348 rawdata[1]); 1349 svalptr = &rawdata[0]; 1350 break; 1351 case SHT3X_HUMIDITY_SENSOR: 1352 current_value = sht3x_compute_rh_from_raw(rawdata[3], 1353 rawdata[4]); 1354 svalptr = &rawdata[3]; 1355 break; 1356 default: 1357 DPRINTF(sc, 2, ("%s: bad sensor type %d\n", 1358 device_xname(sc->sc_dev), edata->sensor)); 1359 return EINTR; 1360 } 1361 uint8_t testcrc; 1362 /* Fake out the CRC check if being asked to ignore CRC */ 1363 if (sc->sc_ignorecrc) { 1364 testcrc = *(svalptr + 2); 1365 } else { 1366 testcrc = sht3x_crc(svalptr, 2); 1367 } 1368 1369 if (*(svalptr + 2) != testcrc) { 1370 DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d != %d\n", 1371 device_xname(sc->sc_dev), (*svalptr + 2), testcrc)); 1372 return EINVAL; 1373 } 1374 edata->value_cur = (uint32_t) current_value; 1375 edata->state = ENVSYS_SVALID; 1376 return 0; 1377 } 1378 1379 static int 1380 sht3x_refresh_periodic(struct sysmon_envsys *sme, envsys_data_t *edata) 1381 { 1382 struct sht3x_sc *sc = sme->sme_cookie; 1383 uint8_t rawdata[sizeof(sc->sc_pbuffer)]; 1384 1385 memcpy(rawdata, sc->sc_pbuffer, sizeof(rawdata)); 1386 1387 return sht3x_parse_data(sc, edata, rawdata); 1388 1389 } 1390 1391 static int 1392 sht3x_refresh_oneshot(struct sysmon_envsys *sme, envsys_data_t *edata) 1393 { 1394 struct sht3x_sc *sc = sme->sme_cookie; 1395 uint16_t measurement_command_ss; 1396 uint8_t rawdata[sizeof(sc->sc_pbuffer)]; 1397 int error; 1398 1399 error = iic_acquire_bus(sc->sc_tag, 0); 1400 if (error) { 1401 DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n", 1402 device_xname(sc->sc_dev), error)); 1403 return error; 1404 } 1405 1406 measurement_command_ss = sht3x_compute_measure_command_ss( 1407 sc->sc_repeatability, sc->sc_clockstretch); 1408 error = sht3x_cmdr(sc, measurement_command_ss, rawdata, sizeof(rawdata)); 1409 DPRINTF(sc, 2, ("%s: Status for single-shot measurement cmd %04x " 1410 "Error %d\n", device_xname(sc->sc_dev), measurement_command_ss, error)); 1411 if (error == 0) { 1412 error = sht3x_parse_data(sc, edata, rawdata); 1413 } 1414 1415 uint16_t sbuf; 1416 int status_error = sht3x_get_status_register(sc, &sbuf, true); 1417 1418 if (!status_error) { 1419 DPRINTF(sc, 2, ("%s: read status register single-shot: %04x\n", 1420 device_xname(sc->sc_dev), sbuf)); 1421 1422 if (sbuf & SHT3X_RESET_DETECTED) { 1423 aprint_error_dev(sc->sc_dev, 1424 "Reset detected in single shot mode. " 1425 "Heater may have been reset\n"); 1426 sht3x_clear_status_register(sc, true); 1427 } 1428 1429 sc->sc_heateron = sbuf & SHT3X_HEATER_STATUS; 1430 } 1431 1432 iic_release_bus(sc->sc_tag, 0); 1433 1434 return error; 1435 } 1436 1437 static void 1438 sht3x_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 1439 { 1440 struct sht3x_sc *sc = sme->sme_cookie; 1441 1442 edata->state = ENVSYS_SINVALID; 1443 1444 mutex_enter(&sc->sc_mutex); 1445 1446 if (sc->sc_isperiodic) { 1447 sht3x_refresh_periodic(sme, edata); 1448 } else { 1449 sht3x_refresh_oneshot(sme, edata); 1450 } 1451 1452 mutex_exit(&sc->sc_mutex); 1453 } 1454 1455 static int 1456 sht3xopen(dev_t dev, int flags, int fmt, struct lwp *l) 1457 { 1458 struct sht3x_sc *sc; 1459 1460 sc = device_lookup_private(&sht3xtemp_cd, minor(dev)); 1461 if (!sc) 1462 return ENXIO; 1463 1464 if (sc->sc_opened) 1465 return EBUSY; 1466 1467 mutex_enter(&sc->sc_mutex); 1468 sc->sc_opened = true; 1469 1470 sc->sc_wassingleshot = false; 1471 if (!sc->sc_isperiodic) { 1472 sc->sc_stopping = false; 1473 sc->sc_initperiodic = true; 1474 sc->sc_isperiodic = true; 1475 sc->sc_wassingleshot = true; 1476 sht3x_start_thread(sc); 1477 } 1478 mutex_exit(&sc->sc_mutex); 1479 1480 return 0; 1481 } 1482 1483 static int 1484 sht3xread(dev_t dev, struct uio *uio, int flags) 1485 { 1486 struct sht3x_sc *sc; 1487 struct sht3x_read_q *pp; 1488 int error,any; 1489 1490 sc = device_lookup_private(&sht3xtemp_cd, minor(dev)); 1491 if (!sc) 1492 return ENXIO; 1493 1494 while (uio->uio_resid) { 1495 any = 0; 1496 error = 0; 1497 mutex_enter(&sc->sc_read_mutex); 1498 1499 while (any == 0) { 1500 pp = SIMPLEQ_FIRST(&sc->sc_read_queue); 1501 if (pp != NULL) { 1502 SIMPLEQ_REMOVE_HEAD(&sc->sc_read_queue, read_q); 1503 any = 1; 1504 break; 1505 } 1506 error = cv_wait_sig(&sc->sc_condreadready, 1507 &sc->sc_read_mutex); 1508 if (sc->sc_dying) 1509 error = EIO; 1510 if (error == 0) 1511 continue; 1512 break; 1513 } 1514 1515 if (any == 1 && error == 0) { 1516 uint8_t *p = pp->measurement; 1517 mutex_exit(&sc->sc_read_mutex); 1518 pool_cache_put(sc->sc_readpool,pp); 1519 1520 DPRINTF(sc,2, ("%s: sending %02x%02x %02x -- %02x%02x " 1521 "%02x -- %x\n", device_xname(sc->sc_dev), p[0], 1522 p[1], p[2], p[3], p[4], p[5], 1523 mutex_owned(&sc->sc_read_mutex))); 1524 if ((error = uiomove(pp->measurement, 1525 sizeof(pp->measurement), uio)) != 0) { 1526 DPRINTF(sc,2, ("%s: send error %d\n", 1527 device_xname(sc->sc_dev), error)); 1528 break; 1529 } 1530 } else { 1531 mutex_exit(&sc->sc_read_mutex); 1532 if (error) { 1533 break; 1534 } 1535 } 1536 } 1537 1538 DPRINTF(sc,2, ("%s: loop done: %d\n",device_xname(sc->sc_dev),error)); 1539 if (sc->sc_dying) { 1540 DPRINTF(sc, 2, ("%s: Telling all we are almost dead\n", 1541 device_xname(sc->sc_dev))); 1542 mutex_enter(&sc->sc_dying_mutex); 1543 cv_signal(&sc->sc_cond_dying); 1544 mutex_exit(&sc->sc_dying_mutex); 1545 } 1546 return error; 1547 } 1548 1549 static int 1550 sht3xclose(dev_t dev, int flags, int fmt, struct lwp *l) 1551 { 1552 struct sht3x_sc *sc; 1553 struct sht3x_read_q *pp; 1554 1555 sc = device_lookup_private(&sht3xtemp_cd, minor(dev)); 1556 1557 if (sc->sc_wassingleshot) { 1558 sht3x_stop_thread(sc); 1559 sc->sc_stopping = false; 1560 sc->sc_initperiodic = false; 1561 sc->sc_isperiodic = false; 1562 } 1563 1564 mutex_enter(&sc->sc_mutex); 1565 /* Drain any read pools */ 1566 while ((pp = SIMPLEQ_FIRST(&sc->sc_read_queue)) != NULL) { 1567 SIMPLEQ_REMOVE_HEAD(&sc->sc_read_queue, read_q); 1568 pool_cache_put(sc->sc_readpool,pp); 1569 } 1570 1571 /* Say that the device is now free */ 1572 sc->sc_opened = false; 1573 mutex_exit(&sc->sc_mutex); 1574 1575 return(0); 1576 } 1577 1578 static int 1579 sht3x_detach(device_t self, int flags) 1580 { 1581 struct sht3x_sc *sc; 1582 struct sht3x_read_q *pp; 1583 1584 sc = device_private(self); 1585 1586 if (sc->sc_isperiodic) { 1587 sht3x_stop_thread(sc); 1588 } 1589 1590 mutex_enter(&sc->sc_mutex); 1591 1592 sc->sc_dying = true; 1593 1594 /* If this is true we are still open, destroy the condvar */ 1595 if (sc->sc_opened) { 1596 mutex_enter(&sc->sc_dying_mutex); 1597 mutex_enter(&sc->sc_read_mutex); 1598 cv_signal(&sc->sc_condreadready); 1599 mutex_exit(&sc->sc_read_mutex); 1600 DPRINTF(sc, 2, ("%s: Will wait for anything to exit\n", 1601 device_xname(sc->sc_dev))); 1602 /* In the worst case this will time out after 5 seconds. 1603 * It really should not take that long for the drain / whatever 1604 * to happen 1605 */ 1606 cv_timedwait_sig(&sc->sc_cond_dying, 1607 &sc->sc_dying_mutex, mstohz(5000)); 1608 mutex_exit(&sc->sc_dying_mutex); 1609 cv_destroy(&sc->sc_condreadready); 1610 cv_destroy(&sc->sc_cond_dying); 1611 } 1612 1613 /* Drain any read pools */ 1614 while ((pp = SIMPLEQ_FIRST(&sc->sc_read_queue)) != NULL) { 1615 SIMPLEQ_REMOVE_HEAD(&sc->sc_read_queue, read_q); 1616 pool_cache_put(sc->sc_readpool,pp); 1617 } 1618 1619 /* Destroy the pool cache now that nothing is using it */ 1620 pool_cache_destroy(sc->sc_readpool); 1621 1622 /* Remove the sensors */ 1623 if (sc->sc_sme != NULL) { 1624 sysmon_envsys_unregister(sc->sc_sme); 1625 sc->sc_sme = NULL; 1626 } 1627 mutex_exit(&sc->sc_mutex); 1628 1629 /* Remove the sysctl tree */ 1630 sysctl_teardown(&sc->sc_sht3xlog); 1631 1632 /* Remove the mutex */ 1633 mutex_destroy(&sc->sc_mutex); 1634 mutex_destroy(&sc->sc_threadmutex); 1635 mutex_destroy(&sc->sc_read_mutex); 1636 mutex_destroy(&sc->sc_dying_mutex); 1637 1638 /* Free the poolname string */ 1639 if (sc->sc_readpoolname != NULL) { 1640 kmem_free(sc->sc_readpoolname,strlen(sc->sc_readpoolname) + 1); 1641 } 1642 1643 return 0; 1644 } 1645 1646 int 1647 sht3x_activate(device_t self, enum devact act) 1648 { 1649 struct sht3x_sc *sc = device_private(self); 1650 1651 switch (act) { 1652 case DVACT_DEACTIVATE: 1653 sc->sc_dying = true; 1654 return 0; 1655 default: 1656 return EOPNOTSUPP; 1657 } 1658 } 1659 1660 MODULE(MODULE_CLASS_DRIVER, sht3xtemp, "iic,sysmon_envsys"); 1661 1662 #ifdef _MODULE 1663 #include "ioconf.c" 1664 #endif 1665 1666 static int 1667 sht3xtemp_modcmd(modcmd_t cmd, void *opaque) 1668 { 1669 int error; 1670 #ifdef _MODULE 1671 int bmaj = -1, cmaj = -1; 1672 #endif 1673 1674 switch (cmd) { 1675 case MODULE_CMD_INIT: 1676 #ifdef _MODULE 1677 error = devsw_attach("sht3xtemp", NULL, &bmaj, 1678 &sht3x_cdevsw, &cmaj); 1679 if (error) { 1680 aprint_error("%s: unable to attach devsw\n", 1681 sht3xtemp_cd.cd_name); 1682 return error; 1683 } 1684 1685 error = config_init_component(cfdriver_ioconf_sht3xtemp, 1686 cfattach_ioconf_sht3xtemp, cfdata_ioconf_sht3xtemp); 1687 if (error) { 1688 aprint_error("%s: unable to init component\n", 1689 sht3xtemp_cd.cd_name); 1690 devsw_detach(NULL, &sht3x_cdevsw); 1691 } 1692 return error; 1693 #else 1694 return 0; 1695 #endif 1696 case MODULE_CMD_FINI: 1697 #ifdef _MODULE 1698 error = config_fini_component(cfdriver_ioconf_sht3xtemp, 1699 cfattach_ioconf_sht3xtemp, cfdata_ioconf_sht3xtemp); 1700 devsw_detach(NULL, &sht3x_cdevsw); 1701 return error; 1702 #else 1703 return 0; 1704 #endif 1705 default: 1706 return ENOTTY; 1707 } 1708 } 1709