1 /* $NetBSD: si70xx.c,v 1.12 2025/01/23 19:13:19 brad Exp $ */ 2 3 /* 4 * Copyright (c) 2017 Brad Spencer <brad@anduin.eldar.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/cdefs.h> 20 __KERNEL_RCSID(0, "$NetBSD: si70xx.c,v 1.12 2025/01/23 19:13:19 brad Exp $"); 21 22 /* 23 Driver for the Silicon Labs SI7013/SI7020/SI7021, HTU21D and SHT21 24 */ 25 26 #include <sys/param.h> 27 #include <sys/systm.h> 28 #include <sys/kernel.h> 29 #include <sys/device.h> 30 #include <sys/module.h> 31 #include <sys/sysctl.h> 32 #include <sys/mutex.h> 33 34 #include <dev/sysmon/sysmonvar.h> 35 #include <dev/i2c/i2cvar.h> 36 #include <dev/i2c/si70xxreg.h> 37 #include <dev/i2c/si70xxvar.h> 38 39 40 static uint8_t si70xx_crc(uint8_t *, size_t); 41 static int si70xx_poke(i2c_tag_t, i2c_addr_t, bool); 42 static int si70xx_match(device_t, cfdata_t, void *); 43 static void si70xx_attach(device_t, device_t, void *); 44 static int si70xx_detach(device_t, int); 45 static void si70xx_refresh(struct sysmon_envsys *, envsys_data_t *); 46 static int si70xx_update_status(struct si70xx_sc *); 47 static int si70xx_set_heateron(struct si70xx_sc *); 48 static int si70xx_set_resolution(struct si70xx_sc *, size_t); 49 static int si70xx_set_heatervalue(struct si70xx_sc *, size_t); 50 static int si70xx_verify_sysctl(SYSCTLFN_ARGS); 51 static int si70xx_verify_sysctl_resolution(SYSCTLFN_ARGS); 52 static int si70xx_verify_sysctl_heateron(SYSCTLFN_ARGS); 53 static int si70xx_verify_sysctl_heatervalue(SYSCTLFN_ARGS); 54 55 #define SI70XX_DEBUG 56 #ifdef SI70XX_DEBUG 57 #define DPRINTF(s, l, x) \ 58 do { \ 59 if (l <= s->sc_si70xxdebug) \ 60 printf x; \ 61 } while (/*CONSTCOND*/0) 62 #else 63 #define DPRINTF(s, l, x) 64 #endif 65 66 CFATTACH_DECL_NEW(si70xxtemp, sizeof(struct si70xx_sc), 67 si70xx_match, si70xx_attach, si70xx_detach, NULL); 68 69 static struct si70xx_sensor si70xx_sensors[] = { 70 { 71 .desc = "humidity", 72 .type = ENVSYS_SRELHUMIDITY, 73 }, 74 { 75 .desc = "temperature", 76 .type = ENVSYS_STEMP, 77 } 78 }; 79 80 static struct si70xx_resolution si70xx_resolutions[] = { 81 { 82 .text = "12bit/14bit", 83 .num = 0x00, 84 }, 85 { 86 .text = "8bit/12bit", 87 .num = 0x01, 88 }, 89 { 90 .text = "10bit/13bit", 91 .num = 0x80, 92 }, 93 { 94 .text = "11bit/11bit", 95 .num = 0x81, 96 } 97 }; 98 99 static const char si70xx_resolution_names[] = 100 "12bit/14bit, 8bit/12bit, 10bit/13bit, 11bit/11bit"; 101 102 static const int si70xx_heatervalues[] = { 103 0xdeadbeef, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0f 104 }; 105 106 int 107 si70xx_verify_sysctl(SYSCTLFN_ARGS) 108 { 109 int error, t; 110 struct sysctlnode node; 111 112 node = *rnode; 113 t = *(int *)rnode->sysctl_data; 114 node.sysctl_data = &t; 115 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 116 if (error || newp == NULL) 117 return error; 118 119 if (t < 0) 120 return EINVAL; 121 122 *(int *)rnode->sysctl_data = t; 123 124 return 0; 125 } 126 127 int 128 si70xx_verify_sysctl_resolution(SYSCTLFN_ARGS) 129 { 130 char buf[SI70XX_RES_NAME]; 131 struct si70xx_sc *sc; 132 struct sysctlnode node; 133 int error = 0; 134 size_t i; 135 136 node = *rnode; 137 sc = node.sysctl_data; 138 (void) memcpy(buf, sc->sc_resolution, SI70XX_RES_NAME); 139 node.sysctl_data = buf; 140 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 141 if (error || newp == NULL) 142 return error; 143 144 for (i = 0; i < __arraycount(si70xx_resolutions); i++) { 145 if (memcmp(node.sysctl_data, si70xx_resolutions[i].text, 146 SI70XX_RES_NAME) == 0) 147 break; 148 } 149 150 if (i == __arraycount(si70xx_resolutions)) 151 return EINVAL; 152 (void) memcpy(sc->sc_resolution, node.sysctl_data, SI70XX_RES_NAME); 153 154 error = si70xx_set_resolution(sc, i); 155 156 return error; 157 } 158 159 int 160 si70xx_verify_sysctl_heateron(SYSCTLFN_ARGS) 161 { 162 int error; 163 bool t; 164 struct si70xx_sc *sc; 165 struct sysctlnode node; 166 167 node = *rnode; 168 sc = node.sysctl_data; 169 t = sc->sc_heateron; 170 node.sysctl_data = &t; 171 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 172 if (error || newp == NULL) 173 return error; 174 175 sc->sc_heateron = t; 176 error = si70xx_set_heateron(sc); 177 178 return error; 179 } 180 181 int 182 si70xx_verify_sysctl_heatervalue(SYSCTLFN_ARGS) 183 { 184 int error = 0, t; 185 struct si70xx_sc *sc; 186 struct sysctlnode node; 187 188 node = *rnode; 189 sc = node.sysctl_data; 190 t = sc->sc_heaterval; 191 node.sysctl_data = &t; 192 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 193 if (error || newp == NULL) 194 return (error); 195 196 if (t < 1 || t >= __arraycount(si70xx_heatervalues)) 197 return (EINVAL); 198 199 sc->sc_heaterval = t; 200 error = si70xx_set_heatervalue(sc, t); 201 202 return error; 203 } 204 205 static uint8_t 206 si70xx_dir(uint8_t cmd, size_t len) 207 { 208 switch (cmd) { 209 case SI70XX_READ_USER_REG_1: 210 case SI70XX_READ_HEATER_REG: 211 case SI70XX_READ_ID_PT1A: 212 case SI70XX_READ_ID_PT1B: 213 case SI70XX_READ_ID_PT2A: 214 case SI70XX_READ_ID_PT2B: 215 case SI70XX_READ_FW_VERA: 216 case SI70XX_READ_FW_VERB: 217 case SI70XX_MEASURE_RH_HOLD: 218 case SI70XX_MEASURE_TEMP_HOLD: 219 return I2C_OP_READ_WITH_STOP; 220 case SI70XX_WRITE_USER_REG_1: 221 case SI70XX_WRITE_HEATER_REG: 222 case SI70XX_RESET: 223 return I2C_OP_WRITE_WITH_STOP; 224 case SI70XX_MEASURE_RH_NOHOLD: 225 case SI70XX_MEASURE_TEMP_NOHOLD: 226 return len == 0 ? I2C_OP_WRITE : I2C_OP_READ_WITH_STOP; 227 default: 228 panic("%s: bad command %#x\n", __func__, cmd); 229 return 0; 230 } 231 } 232 233 static int 234 si70xx_cmd(i2c_tag_t tag, i2c_addr_t addr, uint8_t *cmd, 235 uint8_t clen, uint8_t *buf, size_t blen) 236 { 237 uint8_t dir; 238 if (clen == 0) 239 dir = blen == 0 ? I2C_OP_READ : I2C_OP_READ_WITH_STOP; 240 else 241 dir = si70xx_dir(cmd[0], blen); 242 243 if (dir == I2C_OP_READ || dir == I2C_OP_READ_WITH_STOP) 244 memset(buf, 0, blen); 245 246 return iic_exec(tag, dir, addr, cmd, clen, buf, blen, 0); 247 } 248 249 static int 250 si70xx_cmd0(struct si70xx_sc *sc, uint8_t *buf, size_t blen) 251 { 252 return si70xx_cmd(sc->sc_tag, sc->sc_addr, NULL, 0, buf, blen); 253 } 254 255 static int 256 si70xx_cmd1(struct si70xx_sc *sc, uint8_t cmd, uint8_t *buf, size_t blen) 257 { 258 return si70xx_cmd(sc->sc_tag, sc->sc_addr, &cmd, 1, buf, blen); 259 } 260 261 static int 262 si70xx_cmd2(struct si70xx_sc *sc, uint8_t cmd1, uint8_t cmd2, uint8_t *buf, 263 size_t blen) 264 { 265 uint8_t cmd[] = { cmd1, cmd2 }; 266 return si70xx_cmd(sc->sc_tag, sc->sc_addr, cmd, __arraycount(cmd), 267 buf, blen); 268 } 269 270 static int 271 si70xx_set_heateron(struct si70xx_sc * sc) 272 { 273 int error; 274 uint8_t userregister; 275 276 error = iic_acquire_bus(sc->sc_tag, 0); 277 if (error) { 278 DPRINTF(sc, 2, ("%s:%s: Failed to acquire bus: %d\n", 279 device_xname(sc->sc_dev), __func__, error)); 280 return error; 281 } 282 283 error = si70xx_cmd1(sc, SI70XX_READ_USER_REG_1, &userregister, 1); 284 if (error) { 285 DPRINTF(sc, 2, ("%s: Failed to read user register 1: %d\n", 286 device_xname(sc->sc_dev), error)); 287 goto out; 288 } 289 290 DPRINTF(sc, 2, ("%s:%s: reg 1 values before: %#x\n", 291 device_xname(sc->sc_dev), __func__, userregister)); 292 if (sc->sc_heateron) { 293 userregister |= SI70XX_HTRE_MASK; 294 } else { 295 userregister &= ~SI70XX_HTRE_MASK; 296 } 297 DPRINTF(sc, 2, ("%s:%s: user reg 1 values after: %#x\n", 298 device_xname(sc->sc_dev), __func__, userregister)); 299 300 error = si70xx_cmd1(sc, SI70XX_WRITE_USER_REG_1, &userregister, 1); 301 if (error) { 302 DPRINTF(sc, 2, ("%s: Failed to write user register 1: %d\n", 303 device_xname(sc->sc_dev), error)); 304 } 305 out: 306 iic_release_bus(sc->sc_tag, 0); 307 return error; 308 } 309 310 static int 311 si70xx_set_resolution(struct si70xx_sc * sc, size_t index) 312 { 313 int error; 314 uint8_t userregister; 315 316 error = iic_acquire_bus(sc->sc_tag, 0); 317 if (error) { 318 DPRINTF(sc, 2, ("%s: Failed to acquire bus: %d\n", 319 device_xname(sc->sc_dev), error)); 320 return error; 321 } 322 323 error = si70xx_cmd1(sc, SI70XX_READ_USER_REG_1, &userregister, 1); 324 if (error) { 325 DPRINTF(sc, 2, ("%s: Failed to read user register 1: %d\n", 326 device_xname(sc->sc_dev), error)); 327 goto out; 328 } 329 330 DPRINTF(sc, 2, ("%s:%s: reg 1 values before: %#x\n", 331 device_xname(sc->sc_dev), __func__, userregister)); 332 userregister &= (~SI70XX_RESOLUTION_MASK); 333 userregister |= si70xx_resolutions[index].num; 334 DPRINTF(sc, 2, ("%s:%s: reg 1 values after: %#x\n", 335 device_xname(sc->sc_dev), __func__, userregister)); 336 337 error = si70xx_cmd1(sc, SI70XX_WRITE_USER_REG_1, &userregister, 1); 338 if (error) { 339 DPRINTF(sc, 2, ("%s: Failed to write user register 1: %d\n", 340 device_xname(sc->sc_dev), error)); 341 } 342 out: 343 iic_release_bus(sc->sc_tag, 0); 344 return error; 345 } 346 347 static int 348 si70xx_set_heatervalue(struct si70xx_sc * sc, size_t index) 349 { 350 int error; 351 uint8_t heaterregister; 352 353 error = iic_acquire_bus(sc->sc_tag, 0); 354 if (error) { 355 DPRINTF(sc, 2, ("%s: Failed to acquire bus: %d\n", 356 device_xname(sc->sc_dev), error)); 357 return error; 358 } 359 error = si70xx_cmd1(sc, SI70XX_READ_HEATER_REG, &heaterregister, 1); 360 if (error) { 361 DPRINTF(sc, 2, ("%s: Failed to read heater register: %d\n", 362 device_xname(sc->sc_dev), error)); 363 goto out; 364 } 365 366 DPRINTF(sc, 2, ("%s:%s: heater values before: %#x\n", 367 device_xname(sc->sc_dev), __func__, heaterregister)); 368 heaterregister &= ~SI70XX_HEATER_MASK; 369 heaterregister |= si70xx_heatervalues[index]; 370 DPRINTF(sc, 2, ("%s:%s: heater values after: %#x\n", 371 device_xname(sc->sc_dev), __func__, heaterregister)); 372 373 error = si70xx_cmd1(sc, SI70XX_WRITE_HEATER_REG, &heaterregister, 1); 374 if (error) { 375 DPRINTF(sc, 2, ("%s: Failed to write heater register: %d\n", 376 device_xname(sc->sc_dev), error)); 377 } 378 out: 379 iic_release_bus(sc->sc_tag, 0); 380 return error; 381 } 382 383 static int 384 si70xx_update_heater(struct si70xx_sc *sc) 385 { 386 size_t i; 387 int error; 388 uint8_t heaterregister; 389 390 error = si70xx_cmd1(sc, SI70XX_READ_HEATER_REG, &heaterregister, 1); 391 if (error) { 392 DPRINTF(sc, 2, ("%s: Failed to read heater register: %d\n", 393 device_xname(sc->sc_dev), error)); 394 return error; 395 } 396 397 DPRINTF(sc, 2, ("%s: read heater reg values: %02x\n", 398 device_xname(sc->sc_dev), heaterregister)); 399 400 uint8_t heat = heaterregister & SI70XX_HEATER_MASK; 401 for (i = 0; i < __arraycount(si70xx_heatervalues); i++) { 402 if (si70xx_heatervalues[i] == heat) 403 break; 404 } 405 sc->sc_heaterval = i != __arraycount(si70xx_heatervalues) ? i : 0; 406 return 0; 407 } 408 409 static int 410 si70xx_update_user(struct si70xx_sc *sc) 411 { 412 size_t i; 413 int error; 414 uint8_t userregister; 415 416 error = si70xx_cmd1(sc, SI70XX_READ_USER_REG_1, &userregister, 1); 417 if (error) { 418 DPRINTF(sc, 2, ("%s: Failed to read user register 1: %d\n", 419 device_xname(sc->sc_dev), error)); 420 return error; 421 } 422 DPRINTF(sc, 2, ("%s: read user reg 1 values: %#x\n", 423 device_xname(sc->sc_dev), userregister)); 424 425 uint8_t res = userregister & SI70XX_RESOLUTION_MASK; 426 for (i = 0; i < __arraycount(si70xx_resolutions); i++) { 427 if (si70xx_resolutions[i].num == res) 428 break; 429 } 430 431 if (i != __arraycount(si70xx_resolutions)) { 432 memcpy(sc->sc_resolution, si70xx_resolutions[i].text, 433 SI70XX_RES_NAME); 434 } else { 435 snprintf(sc->sc_resolution, SI70XX_RES_NAME, "%02x", res); 436 } 437 438 sc->sc_vddok = (userregister & SI70XX_VDDS_MASK) == 0; 439 sc->sc_heaterval = userregister & SI70XX_HTRE_MASK; 440 return 0; 441 } 442 443 static int 444 si70xx_update_status(struct si70xx_sc *sc) 445 { 446 int error1 = si70xx_update_user(sc); 447 int error2 = 0; 448 if (! sc->sc_noheater) { 449 error2 = si70xx_update_heater(sc); 450 } 451 return error1 ? error1 : error2; 452 } 453 454 static uint8_t 455 si70xx_crc(uint8_t * data, size_t size) 456 { 457 uint8_t crc = 0; 458 459 for (size_t i = 0; i < size; i++) { 460 crc ^= data[i]; 461 for (size_t j = 8; j > 0; j--) { 462 if (crc & 0x80) 463 crc = (crc << 1) ^ 0x131; 464 else 465 crc <<= 1; 466 } 467 } 468 return crc; 469 } 470 471 static int 472 si70xx_poke(i2c_tag_t tag, i2c_addr_t addr, bool matchdebug) 473 { 474 uint8_t reg = SI70XX_READ_USER_REG_1; 475 uint8_t buf; 476 int error; 477 478 error = si70xx_cmd(tag, addr, ®, 1, &buf, 1); 479 if (matchdebug) { 480 printf("poke X 1: %d\n", error); 481 } 482 return error; 483 } 484 485 static int 486 si70xx_sysctl_init(struct si70xx_sc *sc) 487 { 488 int error; 489 const struct sysctlnode *cnode; 490 int sysctlroot_num; 491 492 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 493 0, CTLTYPE_NODE, device_xname(sc->sc_dev), 494 SYSCTL_DESCR("si70xx controls"), NULL, 0, NULL, 0, CTL_HW, 495 CTL_CREATE, CTL_EOL)) != 0) 496 return error; 497 498 sysctlroot_num = cnode->sysctl_num; 499 500 #ifdef SI70XX_DEBUG 501 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 502 CTLFLAG_READWRITE, CTLTYPE_INT, "debug", 503 SYSCTL_DESCR("Debug level"), si70xx_verify_sysctl, 0, 504 &sc->sc_si70xxdebug, 0, CTL_HW, sysctlroot_num, CTL_CREATE, 505 CTL_EOL)) != 0) 506 return error; 507 508 #endif 509 510 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 511 CTLFLAG_READWRITE, CTLTYPE_BOOL, "clockstretch", 512 SYSCTL_DESCR("Use clock stretch commands for measurements"), NULL, 0, 513 &sc->sc_clockstretch, 0, CTL_HW, sysctlroot_num, CTL_CREATE, 514 CTL_EOL)) != 0) 515 return error; 516 517 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 518 CTLFLAG_READWRITE, CTLTYPE_INT, "readattempts", 519 SYSCTL_DESCR("The number of times to attempt to read the values"), 520 si70xx_verify_sysctl, 0, &sc->sc_readattempts, 0, CTL_HW, 521 sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 522 return error; 523 524 525 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 526 CTLFLAG_READONLY, CTLTYPE_STRING, "resolutions", 527 SYSCTL_DESCR("Valid resolutions"), 0, 0, 528 __UNCONST(si70xx_resolution_names), 529 sizeof(si70xx_resolution_names) + 1, 530 CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 531 return error; 532 533 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 534 CTLFLAG_READWRITE, CTLTYPE_STRING, "resolution", 535 SYSCTL_DESCR("Resolution of RH and Temp"), 536 si70xx_verify_sysctl_resolution, 0, (void *) sc, 537 SI70XX_RES_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 538 return error; 539 540 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 541 CTLFLAG_READWRITE, CTLTYPE_BOOL, "ignorecrc", 542 SYSCTL_DESCR("Ignore the CRC byte"), NULL, 0, &sc->sc_ignorecrc, 543 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 544 return error; 545 546 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 547 CTLFLAG_READONLY, CTLTYPE_BOOL, "vddok", 548 SYSCTL_DESCR("Vdd at least 1.9v"), NULL, 0, &sc->sc_vddok, 0, 549 CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 550 return error; 551 552 if (! sc->sc_noheater) { 553 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 554 CTLFLAG_READWRITE, CTLTYPE_BOOL, "heateron", 555 SYSCTL_DESCR("Heater on"), si70xx_verify_sysctl_heateron, 0, 556 (void *)sc, 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 557 return error; 558 559 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 560 CTLFLAG_READWRITE, CTLTYPE_INT, "heaterstrength", 561 SYSCTL_DESCR("Heater strength 1 to 6"), 562 si70xx_verify_sysctl_heatervalue, 0, (void *)sc, 0, CTL_HW, 563 sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 564 return error; 565 } 566 567 return 0; 568 } 569 570 static int 571 si70xx_match(device_t parent, cfdata_t match, void *aux) 572 { 573 struct i2c_attach_args *ia = aux; 574 int error, match_result; 575 const bool matchdebug = false; 576 577 if (iic_use_direct_match(ia, match, NULL, &match_result)) 578 return match_result; 579 580 /* indirect config - check for configured address */ 581 if (ia->ia_addr != SI70XX_TYPICAL_ADDR) 582 return 0; 583 584 /* 585 * Check to see if something is really at this i2c address. This will 586 * keep phantom devices from appearing 587 */ 588 if (iic_acquire_bus(ia->ia_tag, 0) != 0) { 589 if (matchdebug) 590 printf("in match acquire bus failed\n"); 591 return 0; 592 } 593 594 error = si70xx_poke(ia->ia_tag, ia->ia_addr, matchdebug); 595 iic_release_bus(ia->ia_tag, 0); 596 597 return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0; 598 } 599 600 static void 601 si70xx_attach(device_t parent, device_t self, void *aux) 602 { 603 struct si70xx_sc *sc; 604 struct i2c_attach_args *ia; 605 int error, i; 606 int ecount = 0; 607 uint8_t buf[8]; 608 uint8_t testcrcpt1[4]; 609 uint8_t testcrcpt2[4]; 610 uint8_t crc1 = 0, crc2 = 0; 611 bool validcrcpt1, validcrcpt2; 612 uint8_t readcrc1 = 0, readcrc2 = 0; 613 uint8_t fwversion = 0, model, heaterregister; 614 615 ia = aux; 616 sc = device_private(self); 617 618 sc->sc_dev = self; 619 sc->sc_tag = ia->ia_tag; 620 sc->sc_addr = ia->ia_addr; 621 sc->sc_si70xxdebug = 0; 622 sc->sc_clockstretch = false; 623 sc->sc_readattempts = 40; 624 sc->sc_ignorecrc = false; 625 sc->sc_sme = NULL; 626 sc->sc_noheater = false; 627 sc->sc_nofw = false; 628 629 aprint_normal("\n"); 630 631 mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE); 632 sc->sc_numsensors = __arraycount(si70xx_sensors); 633 634 if ((sc->sc_sme = sysmon_envsys_create()) == NULL) { 635 aprint_error_dev(self, 636 "Unable to create sysmon structure\n"); 637 sc->sc_sme = NULL; 638 return; 639 } 640 641 error = iic_acquire_bus(sc->sc_tag, 0); 642 if (error) { 643 aprint_error_dev(self, "Could not acquire iic bus: %d\n", 644 error); 645 goto out; 646 } 647 error = si70xx_cmd1(sc, SI70XX_RESET, NULL, 0); 648 if (error != 0) 649 aprint_error_dev(self, "Reset failed: %d\n", error); 650 651 delay(15000); /* 15 ms max */ 652 653 error = si70xx_cmd2(sc, SI70XX_READ_ID_PT1A, SI70XX_READ_ID_PT1B, 654 buf, 8); 655 if (error) { 656 aprint_error_dev(self, "Failed to read first part of ID: %d\n", 657 error); 658 ecount++; 659 } 660 testcrcpt1[0] = buf[0]; 661 testcrcpt1[1] = buf[2]; 662 testcrcpt1[2] = buf[4]; 663 testcrcpt1[3] = buf[6]; 664 readcrc1 = buf[7]; 665 crc1 = si70xx_crc(testcrcpt1, 4); 666 /* A "real" SI70xx has the CRC cover the entire first part of the 667 * serial number. An HTU21D has the CRC broken out into each 668 * part of the serial number. 669 */ 670 validcrcpt1 = (readcrc1 == crc1); 671 if (! validcrcpt1) { 672 validcrcpt1 = (si70xx_crc(&testcrcpt1[0],1) == buf[1] && 673 si70xx_crc(&testcrcpt1[1],1) == buf[3] && 674 si70xx_crc(&testcrcpt1[2],1) == buf[5] && 675 si70xx_crc(&testcrcpt1[3],1) == buf[7]); 676 DPRINTF(sc, 2, ("%s: Part 1 SN CRC was not valid for real type, " 677 "check clone: %d\n", device_xname(sc->sc_dev), validcrcpt1)); 678 } 679 680 DPRINTF(sc, 2, ("%s: read 1 values: %02x%02x%02x%02x%02x%02x%02x%02x " 681 "- %02x -- %d\n", device_xname(sc->sc_dev), buf[0], buf[1], 682 buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], 683 crc1, validcrcpt1)); 684 685 error = si70xx_cmd2(sc, SI70XX_READ_ID_PT2A, SI70XX_READ_ID_PT2B, 686 buf, 6); 687 if (error != 0) { 688 aprint_error_dev(self, "Failed to read second part of ID: %d\n", 689 error); 690 ecount++; 691 } 692 model = testcrcpt2[0] = buf[0]; 693 testcrcpt2[1] = buf[1]; 694 testcrcpt2[2] = buf[3]; 695 testcrcpt2[3] = buf[4]; 696 readcrc2 = buf[5]; 697 crc2 = si70xx_crc(testcrcpt2, 4); 698 /* It is even stranger for this part of the serial number. A "real" 699 * SI70XX will have a single CRC for the entire second part, but 700 * an HTU21D has a CRC for each word in this case. 701 * 702 * The datasheet actually agrees with the HTU21D case, and not the "real" 703 * chip. 704 */ 705 validcrcpt2 = (readcrc2 == crc2); 706 if (! validcrcpt2) { 707 validcrcpt2 = (si70xx_crc(&testcrcpt2[0],2) == buf[2] && 708 si70xx_crc(&testcrcpt2[2],2) == buf[5]); 709 DPRINTF(sc, 2, ("%s: Part 2 SN CRC was not valid for real type, " 710 "check clone: %d\n", device_xname(sc->sc_dev), validcrcpt2)); 711 } 712 713 DPRINTF(sc, 2, ("%s: read 2 values: %02x%02x%02x%02x%02x%02x - %02x -- %d\n", 714 device_xname(sc->sc_dev), buf[0], buf[1], buf[2], 715 buf[3], buf[4], buf[5], crc2, validcrcpt2)); 716 717 error = si70xx_cmd2(sc, SI70XX_READ_FW_VERA, SI70XX_READ_FW_VERB, 718 buf, 1); 719 720 if (error) { 721 aprint_error_dev(self, "Failed to read firmware version: Error %d\n", 722 error); 723 sc->sc_nofw = true; 724 } 725 if (! sc->sc_nofw) { 726 fwversion = buf[0]; 727 DPRINTF(sc, 2, ("%s: read fw values: %#x\n", device_xname(sc->sc_dev), 728 fwversion)); 729 } 730 731 error = si70xx_cmd1(sc, SI70XX_READ_HEATER_REG, &heaterregister, 1); 732 733 if (error) { 734 aprint_error_dev(self, "Failed to read heater register: Error %d\n", 735 error); 736 sc->sc_noheater = true; 737 } 738 739 error = si70xx_update_status(sc); 740 741 iic_release_bus(sc->sc_tag, 0); 742 743 if ((error = si70xx_sysctl_init(sc)) != 0) { 744 aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", error); 745 goto out; 746 } 747 748 if (error != 0) { 749 aprint_error_dev(self, "Failed to update status: %x\n", error); 750 aprint_error_dev(self, "Unable to setup device\n"); 751 goto out; 752 } 753 754 for (i = 0; i < sc->sc_numsensors; i++) { 755 strlcpy(sc->sc_sensors[i].desc, si70xx_sensors[i].desc, 756 sizeof(sc->sc_sensors[i].desc)); 757 758 sc->sc_sensors[i].units = si70xx_sensors[i].type; 759 sc->sc_sensors[i].state = ENVSYS_SINVALID; 760 761 DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i, 762 sc->sc_sensors[i].desc)); 763 764 error = sysmon_envsys_sensor_attach(sc->sc_sme, 765 &sc->sc_sensors[i]); 766 if (error) { 767 aprint_error_dev(self, 768 "Unable to attach sensor %d: %d\n", i, error); 769 sc->sc_sme = NULL; 770 goto out; 771 } 772 } 773 774 sc->sc_sme->sme_name = device_xname(sc->sc_dev); 775 sc->sc_sme->sme_cookie = sc; 776 sc->sc_sme->sme_refresh = si70xx_refresh; 777 778 DPRINTF(sc, 2, ("si70xx_attach: registering with envsys\n")); 779 780 if (sysmon_envsys_register(sc->sc_sme)) { 781 aprint_error_dev(self, 782 "unable to register with sysmon\n"); 783 sysmon_envsys_destroy(sc->sc_sme); 784 sc->sc_sme = NULL; 785 return; 786 } 787 788 char modelstr[64]; 789 switch (model) { 790 case 0: 791 case 0xff: 792 snprintf(modelstr, sizeof(modelstr), "Engineering Sample"); 793 break; 794 case 13: 795 case 20: 796 case 21: 797 snprintf(modelstr, sizeof(modelstr), "SI70%d", model); 798 break; 799 default: 800 snprintf(modelstr, sizeof(modelstr), "Unknown model %d (maybe an HTU21D)", model); 801 break; 802 } 803 804 const char *fwversionstr; 805 switch (fwversion) { 806 case 0xff: 807 fwversionstr = "1.0"; 808 break; 809 case 0x20: 810 fwversionstr = "2.0"; 811 break; 812 default: 813 fwversionstr = "unknown"; 814 break; 815 } 816 817 aprint_normal_dev(self, "Silicon Labs Model: %s, " 818 "Firmware version: %s, " 819 "Serial number: %02x%02x%02x%02x%02x%02x%02x%02x%s", 820 modelstr, fwversionstr, testcrcpt1[0], testcrcpt1[1], 821 testcrcpt1[2], testcrcpt1[3], testcrcpt2[0], testcrcpt2[1], 822 testcrcpt2[2], testcrcpt2[3], 823 (validcrcpt1 && validcrcpt2) ? "\n" : " (bad crc)\n"); 824 return; 825 out: 826 sysmon_envsys_destroy(sc->sc_sme); 827 sc->sc_sme = NULL; 828 } 829 830 static int 831 si70xx_exec(struct si70xx_sc *sc, uint8_t cmd, envsys_data_t *edata) 832 { 833 int error; 834 int xdelay; 835 const char *name; 836 int64_t mul, offs; 837 uint8_t buf[3]; 838 839 switch (cmd) { 840 case SI70XX_MEASURE_RH_NOHOLD: 841 case SI70XX_MEASURE_RH_HOLD: 842 /* 843 * The published conversion for RH is: %RH = 844 * ((125 * RHCODE) / 65536) - 6 845 * 846 * The sysmon infrastructure for RH wants %RH * 847 * 10^6 The result will fit in 32 bits, but 848 * the intermediate values will not. 849 */ 850 mul = 125000000; 851 offs = -6000000; 852 /* 853 * Conversion times for %RH in ms 854 * 855 * Typical Max 856 * 12-bit 10.0 12.0 857 * 11-bit 5.8 7.0 858 * 10-bit 3.7 4.5 859 * 8-bit 2.6 3.1 860 * 861 * A call to read %RH will also read temperature. The 862 * conversion time will be the amount of time above 863 * plus the amount of time for temperature below 864 */ 865 xdelay = 10500; 866 name = "RH"; 867 break; 868 case SI70XX_MEASURE_TEMP_NOHOLD: 869 case SI70XX_MEASURE_TEMP_HOLD: 870 /* 871 * The published conversion for temp is: 872 * degree C = ((175.72 * TEMPCODE) / 65536) - 873 * 46.85 874 * 875 * The sysmon infrastructure for temp wants 876 * microkelvin. This is simple, as degree C 877 * converts directly with K with simple 878 * addition. The result will fit in 32 bits, 879 * but the intermediate values will not. 880 */ 881 mul = 175720000; 882 offs = 226300000; 883 /* 884 * Conversion times for temperature in ms 885 * 886 * Typical Max 887 * 14-bit 7.0 10.8 888 * 13-bit 4.0 6.2 889 * 12-bit 2.4 3.8 890 * 11-bit 1.5 2.4 891 */ 892 xdelay = 4750; 893 name = "TEMP"; 894 break; 895 default: 896 return EINVAL; 897 } 898 899 if (sc->sc_clockstretch) { 900 error = si70xx_cmd1(sc, cmd, buf, sizeof(buf)); 901 if (error) { 902 DPRINTF(sc, 2, ("%s: Failed to read HOLD %s %d %d\n", 903 device_xname(sc->sc_dev), name, 1, error)); 904 return error; 905 } 906 } else { 907 error = si70xx_cmd1(sc, cmd, NULL, 0); 908 if (error) { 909 DPRINTF(sc, 2, ("%s: Failed to read NO HOLD %s %d %d\n", 910 device_xname(sc->sc_dev), name, 1, error)); 911 return error; 912 } 913 914 /* 915 * It will probably be at least this long... we would 916 * not have to do this sort of thing if clock 917 * stretching worked. Even this is a problem for the 918 * RPI without a patch to remove a [apparently] not 919 * needed KASSERT() 920 */ 921 delay(xdelay); 922 923 for (int aint = 0; aint < sc->sc_readattempts; aint++) { 924 error = si70xx_cmd0(sc, buf, sizeof(buf)); 925 if (error == 0) 926 break; 927 DPRINTF(sc, 2, ("%s: Failed to read NO HOLD RH" 928 " %d %d\n", device_xname(sc->sc_dev), 2, error)); 929 delay(1000); 930 } 931 } 932 933 DPRINTF(sc, 2, ("%s: %s values: %02x%02x%02x - %02x\n", 934 device_xname(sc->sc_dev), name, buf[0], buf[1], buf[2], 935 si70xx_crc(buf, 2))); 936 937 uint8_t crc; 938 if (sc->sc_ignorecrc) { 939 crc = buf[2]; 940 } else { 941 crc = si70xx_crc(buf, 2); 942 } 943 944 if (crc != buf[2]) { 945 DPRINTF(sc, 2, ("%s: Bad CRC for %s: %#x and %#x\n", 946 device_xname(sc->sc_dev), name, crc, buf[2])); 947 return EINVAL; 948 } 949 950 uint16_t val16 = (buf[0] << 8) | buf[1]; 951 uint64_t val64 = ((mul * val16) >> 16) + offs; 952 DPRINTF(sc, 2, ("%s: %s calculated values: %x %#jx\n", 953 device_xname(sc->sc_dev), name, val16, (uintmax_t)val64)); 954 edata->value_cur = (uint32_t) val64; 955 edata->state = ENVSYS_SVALID; 956 return 0; 957 } 958 959 static void 960 si70xx_refresh(struct sysmon_envsys * sme, envsys_data_t * edata) 961 { 962 struct si70xx_sc *sc; 963 int error; 964 965 sc = sme->sme_cookie; 966 edata->state = ENVSYS_SINVALID; 967 968 mutex_enter(&sc->sc_mutex); 969 error = iic_acquire_bus(sc->sc_tag, 0); 970 if (error) { 971 DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n", 972 device_xname(sc->sc_dev), error)); 973 goto out; 974 } 975 error = si70xx_update_status(sc); 976 if (error) { 977 DPRINTF(sc, 2, ("%s: Failed to update status in refresh %d\n", 978 device_xname(sc->sc_dev), error)); 979 goto out1; 980 } 981 switch (edata->sensor) { 982 case SI70XX_HUMIDITY_SENSOR: 983 if (sc->sc_clockstretch) 984 error = si70xx_exec(sc, SI70XX_MEASURE_RH_HOLD, edata); 985 else 986 error = si70xx_exec(sc, SI70XX_MEASURE_RH_NOHOLD, edata); 987 break; 988 989 case SI70XX_TEMP_SENSOR: 990 if (sc->sc_clockstretch) 991 error = si70xx_exec(sc, SI70XX_MEASURE_TEMP_HOLD, edata); 992 else 993 error = si70xx_exec(sc, SI70XX_MEASURE_TEMP_NOHOLD, edata); 994 break; 995 default: 996 error = EINVAL; 997 break; 998 } 999 1000 if (error) { 1001 DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d\n", 1002 device_xname(sc->sc_dev), error)); 1003 } 1004 out1: 1005 iic_release_bus(sc->sc_tag, 0); 1006 out: 1007 mutex_exit(&sc->sc_mutex); 1008 } 1009 1010 static int 1011 si70xx_detach(device_t self, int flags) 1012 { 1013 struct si70xx_sc *sc; 1014 1015 sc = device_private(self); 1016 1017 mutex_enter(&sc->sc_mutex); 1018 1019 /* Remove the sensors */ 1020 if (sc->sc_sme != NULL) 1021 sysmon_envsys_unregister(sc->sc_sme); 1022 mutex_exit(&sc->sc_mutex); 1023 1024 /* Remove the sysctl tree */ 1025 sysctl_teardown(&sc->sc_si70xxlog); 1026 1027 /* Remove the mutex */ 1028 mutex_destroy(&sc->sc_mutex); 1029 1030 return 0; 1031 } 1032 1033 MODULE(MODULE_CLASS_DRIVER, si70xxtemp, "iic,sysmon_envsys"); 1034 1035 #ifdef _MODULE 1036 #include "ioconf.c" 1037 #endif 1038 1039 static int 1040 si70xxtemp_modcmd(modcmd_t cmd, void *opaque) 1041 { 1042 1043 switch (cmd) { 1044 case MODULE_CMD_INIT: 1045 #ifdef _MODULE 1046 return config_init_component(cfdriver_ioconf_si70xxtemp, 1047 cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp); 1048 #else 1049 return 0; 1050 #endif 1051 case MODULE_CMD_FINI: 1052 #ifdef _MODULE 1053 return config_fini_component(cfdriver_ioconf_si70xxtemp, 1054 cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp); 1055 #else 1056 return 0; 1057 #endif 1058 default: 1059 return ENOTTY; 1060 } 1061 } 1062