1 /* $NetBSD: si70xx.c,v 1.6 2020/12/05 14:50:33 jdc 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.6 2020/12/05 14:50:33 jdc Exp $"); 21 22 /* 23 Driver for the Silicon Labs SI7013/SI7020/SI7021 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 return I2C_OP_READ_WITH_STOP; 218 case SI70XX_WRITE_USER_REG_1: 219 case SI70XX_WRITE_HEATER_REG: 220 case SI70XX_RESET: 221 return I2C_OP_WRITE_WITH_STOP; 222 case SI70XX_MEASURE_RH_NOHOLD: 223 case SI70XX_MEASURE_TEMP_NOHOLD: 224 return len == 0 ? I2C_OP_READ : I2C_OP_READ_WITH_STOP; 225 default: 226 panic("%s: bad command %#x\n", __func__, cmd); 227 return 0; 228 } 229 } 230 231 static int 232 si70xx_cmd(i2c_tag_t tag, i2c_addr_t addr, uint8_t *cmd, 233 uint8_t clen, uint8_t *buf, size_t blen) 234 { 235 uint8_t dir; 236 if (clen == 0) 237 dir = blen == 0 ? I2C_OP_READ : I2C_OP_READ_WITH_STOP; 238 else 239 dir = si70xx_dir(cmd[0], blen); 240 241 if (dir == I2C_OP_READ || dir == I2C_OP_READ_WITH_STOP) 242 memset(buf, 0, blen); 243 244 return iic_exec(tag, dir, addr, cmd, clen, buf, blen, 0); 245 } 246 247 static int 248 si70xx_cmd0(struct si70xx_sc *sc, uint8_t *buf, size_t blen) 249 { 250 return si70xx_cmd(sc->sc_tag, sc->sc_addr, NULL, 0, buf, blen); 251 } 252 253 static int 254 si70xx_cmd1(struct si70xx_sc *sc, uint8_t cmd, uint8_t *buf, size_t blen) 255 { 256 return si70xx_cmd(sc->sc_tag, sc->sc_addr, &cmd, 1, buf, blen); 257 } 258 259 static int 260 si70xx_cmd2(struct si70xx_sc *sc, uint8_t cmd1, uint8_t cmd2, uint8_t *buf, 261 size_t blen) 262 { 263 uint8_t cmd[] = { cmd1, cmd2 }; 264 return si70xx_cmd(sc->sc_tag, sc->sc_addr, cmd, __arraycount(cmd), 265 buf, blen); 266 } 267 268 static int 269 si70xx_set_heateron(struct si70xx_sc * sc) 270 { 271 int error; 272 uint8_t userregister; 273 274 error = iic_acquire_bus(sc->sc_tag, 0); 275 if (error) { 276 DPRINTF(sc, 2, ("%s:%s: Failed to acquire bus: %d\n", 277 device_xname(sc->sc_dev), __func__, error)); 278 return error; 279 } 280 281 error = si70xx_cmd1(sc, SI70XX_READ_USER_REG_1, &userregister, 1); 282 if (error) { 283 DPRINTF(sc, 2, ("%s: Failed to read user register 1: %d\n", 284 device_xname(sc->sc_dev), error)); 285 goto out; 286 } 287 288 DPRINTF(sc, 2, ("%s:%s: reg 1 values before: %#x\n", 289 device_xname(sc->sc_dev), __func__, userregister)); 290 if (sc->sc_heateron) { 291 userregister |= SI70XX_HTRE_MASK; 292 } else { 293 userregister &= ~SI70XX_HTRE_MASK; 294 } 295 DPRINTF(sc, 2, ("%s:%s: user reg 1 values after: %#x\n", 296 device_xname(sc->sc_dev), __func__, userregister)); 297 298 error = si70xx_cmd1(sc, SI70XX_WRITE_USER_REG_1, &userregister, 1); 299 if (error) { 300 DPRINTF(sc, 2, ("%s: Failed to write user register 1: %d\n", 301 device_xname(sc->sc_dev), error)); 302 } 303 out: 304 iic_release_bus(sc->sc_tag, 0); 305 return error; 306 } 307 308 static int 309 si70xx_set_resolution(struct si70xx_sc * sc, size_t index) 310 { 311 int error; 312 uint8_t userregister; 313 314 error = iic_acquire_bus(sc->sc_tag, 0); 315 if (error) { 316 DPRINTF(sc, 2, ("%s: Failed to acquire bus: %d\n", 317 device_xname(sc->sc_dev), error)); 318 return error; 319 } 320 321 error = si70xx_cmd1(sc, SI70XX_READ_USER_REG_1, &userregister, 1); 322 if (error) { 323 DPRINTF(sc, 2, ("%s: Failed to read user register 1: %d\n", 324 device_xname(sc->sc_dev), error)); 325 goto out; 326 } 327 328 DPRINTF(sc, 2, ("%s:%s: reg 1 values before: %#x\n", 329 device_xname(sc->sc_dev), __func__, userregister)); 330 userregister &= (~SI70XX_RESOLUTION_MASK); 331 userregister |= si70xx_resolutions[index].num; 332 DPRINTF(sc, 2, ("%s:%s: reg 1 values after: %#x\n", 333 device_xname(sc->sc_dev), __func__, userregister)); 334 335 error = si70xx_cmd1(sc, SI70XX_WRITE_USER_REG_1, &userregister, 1); 336 if (error) { 337 DPRINTF(sc, 2, ("%s: Failed to write user register 1: %d\n", 338 device_xname(sc->sc_dev), error)); 339 } 340 out: 341 iic_release_bus(sc->sc_tag, 0); 342 return error; 343 } 344 345 static int 346 si70xx_set_heatervalue(struct si70xx_sc * sc, size_t index) 347 { 348 int error; 349 uint8_t heaterregister; 350 351 error = iic_acquire_bus(sc->sc_tag, 0); 352 if (error) { 353 DPRINTF(sc, 2, ("%s: Failed to acquire bus: %d\n", 354 device_xname(sc->sc_dev), error)); 355 return error; 356 } 357 error = si70xx_cmd1(sc, SI70XX_READ_HEATER_REG, &heaterregister, 1); 358 if (error) { 359 DPRINTF(sc, 2, ("%s: Failed to read heater register: %d\n", 360 device_xname(sc->sc_dev), error)); 361 goto out; 362 } 363 364 DPRINTF(sc, 2, ("%s:%s: heater values before: %#x\n", 365 device_xname(sc->sc_dev), __func__, heaterregister)); 366 heaterregister &= ~SI70XX_HEATER_MASK; 367 heaterregister |= si70xx_heatervalues[index]; 368 DPRINTF(sc, 2, ("%s:%s: heater values after: %#x\n", 369 device_xname(sc->sc_dev), __func__, heaterregister)); 370 371 error = si70xx_cmd1(sc, SI70XX_WRITE_HEATER_REG, &heaterregister, 1); 372 if (error) { 373 DPRINTF(sc, 2, ("%s: Failed to write heater register: %d\n", 374 device_xname(sc->sc_dev), error)); 375 } 376 out: 377 iic_release_bus(sc->sc_tag, 0); 378 return error; 379 } 380 381 static int 382 si70xx_update_heater(struct si70xx_sc *sc) 383 { 384 size_t i; 385 int error; 386 uint8_t heaterregister; 387 388 error = si70xx_cmd1(sc, SI70XX_READ_HEATER_REG, &heaterregister, 1); 389 if (error) { 390 DPRINTF(sc, 2, ("%s: Failed to read heater register: %d\n", 391 device_xname(sc->sc_dev), error)); 392 return error; 393 } 394 395 DPRINTF(sc, 2, ("%s: read heater reg values: %02x\n", 396 device_xname(sc->sc_dev), heaterregister)); 397 398 uint8_t heat = heaterregister & SI70XX_HEATER_MASK; 399 for (i = 0; i < __arraycount(si70xx_heatervalues); i++) { 400 if (si70xx_heatervalues[i] == heat) 401 break; 402 } 403 sc->sc_heaterval = i != __arraycount(si70xx_heatervalues) ? i : 0; 404 return 0; 405 } 406 407 static int 408 si70xx_update_user(struct si70xx_sc *sc) 409 { 410 size_t i; 411 int error; 412 uint8_t userregister; 413 414 error = si70xx_cmd1(sc, SI70XX_READ_USER_REG_1, &userregister, 1); 415 if (error) { 416 DPRINTF(sc, 2, ("%s: Failed to read user register 1: %d\n", 417 device_xname(sc->sc_dev), error)); 418 return error; 419 } 420 DPRINTF(sc, 2, ("%s: read user reg 1 values: %#x\n", 421 device_xname(sc->sc_dev), userregister)); 422 423 uint8_t res = userregister & SI70XX_RESOLUTION_MASK; 424 for (i = 0; i < __arraycount(si70xx_resolutions); i++) { 425 if (si70xx_resolutions[i].num == res) 426 break; 427 } 428 429 if (i != __arraycount(si70xx_resolutions)) { 430 memcpy(sc->sc_resolution, si70xx_resolutions[i].text, 431 SI70XX_RES_NAME); 432 } else { 433 snprintf(sc->sc_resolution, SI70XX_RES_NAME, "%02x", res); 434 } 435 436 sc->sc_vddok = (userregister & SI70XX_VDDS_MASK) == 0; 437 sc->sc_heaterval = userregister & SI70XX_HTRE_MASK; 438 return 0; 439 } 440 441 static int 442 si70xx_update_status(struct si70xx_sc *sc) 443 { 444 int error1 = si70xx_update_user(sc); 445 int error2 = si70xx_update_heater(sc); 446 return error1 ? error1 : error2; 447 } 448 449 static uint8_t 450 si70xx_crc(uint8_t * data, size_t size) 451 { 452 uint8_t crc = 0; 453 454 for (size_t i = 0; i < size; i++) { 455 crc ^= data[i]; 456 for (size_t j = 8; j > 0; j--) { 457 if (crc & 0x80) 458 crc = (crc << 1) ^ 0x131; 459 else 460 crc <<= 1; 461 } 462 } 463 return crc; 464 } 465 466 static int 467 si70xx_poke(i2c_tag_t tag, i2c_addr_t addr, bool matchdebug) 468 { 469 uint8_t reg = SI70XX_READ_USER_REG_1; 470 uint8_t buf; 471 int error; 472 473 error = si70xx_cmd(tag, addr, ®, 1, &buf, 1); 474 if (matchdebug) { 475 printf("poke X 1: %d\n", error); 476 } 477 return error; 478 } 479 480 static int 481 si70xx_sysctl_init(struct si70xx_sc *sc) 482 { 483 int error; 484 const struct sysctlnode *cnode; 485 int sysctlroot_num; 486 487 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 488 0, CTLTYPE_NODE, device_xname(sc->sc_dev), 489 SYSCTL_DESCR("si70xx controls"), NULL, 0, NULL, 0, CTL_HW, 490 CTL_CREATE, CTL_EOL)) != 0) 491 return error; 492 493 sysctlroot_num = cnode->sysctl_num; 494 495 #ifdef SI70XX_DEBUG 496 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 497 CTLFLAG_READWRITE, CTLTYPE_INT, "debug", 498 SYSCTL_DESCR("Debug level"), si70xx_verify_sysctl, 0, 499 &sc->sc_si70xxdebug, 0, CTL_HW, sysctlroot_num, CTL_CREATE, 500 CTL_EOL)) != 0) 501 return error; 502 503 #endif 504 505 #ifdef HAVE_I2C_EXECV 506 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 507 CTLFLAG_READWRITE, CTLTYPE_INT, "clockstretch", 508 SYSCTL_DESCR("Clockstretch value"), si70xx_verify_sysctl, 0, 509 &sc->sc_clockstretch, 0, CTL_HW, sysctlroot_num, CTL_CREATE, 510 CTL_EOL)) != 0) 511 return error; 512 #endif 513 514 515 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 516 CTLFLAG_READWRITE, CTLTYPE_INT, "readattempts", 517 SYSCTL_DESCR("The number of times to attempt to read the values"), 518 si70xx_verify_sysctl, 0, &sc->sc_readattempts, 0, CTL_HW, 519 sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 520 return error; 521 522 523 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 524 CTLFLAG_READONLY, CTLTYPE_STRING, "resolutions", 525 SYSCTL_DESCR("Valid resolutions"), 0, 0, 526 __UNCONST(si70xx_resolution_names), 527 sizeof(si70xx_resolution_names) + 1, 528 CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 529 return error; 530 531 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 532 CTLFLAG_READWRITE, CTLTYPE_STRING, "resolution", 533 SYSCTL_DESCR("Resolution of RH and Temp"), 534 si70xx_verify_sysctl_resolution, 0, (void *) sc, 535 SI70XX_RES_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 536 return error; 537 538 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 539 CTLFLAG_READWRITE, CTLTYPE_BOOL, "ignorecrc", 540 SYSCTL_DESCR("Ignore the CRC byte"), NULL, 0, &sc->sc_ignorecrc, 541 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 542 return error; 543 544 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 545 CTLFLAG_READONLY, CTLTYPE_BOOL, "vddok", 546 SYSCTL_DESCR("Vdd at least 1.9v"), NULL, 0, &sc->sc_vddok, 0, 547 CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 548 return error; 549 550 if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 551 CTLFLAG_READWRITE, CTLTYPE_BOOL, "heateron", 552 SYSCTL_DESCR("Heater on"), si70xx_verify_sysctl_heateron, 0, 553 (void *)sc, 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0) 554 return error; 555 556 return sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode, 557 CTLFLAG_READWRITE, CTLTYPE_INT, "heaterstrength", 558 SYSCTL_DESCR("Heater strength 1 to 6"), 559 si70xx_verify_sysctl_heatervalue, 0, (void *)sc, 0, CTL_HW, 560 sysctlroot_num, CTL_CREATE, CTL_EOL); 561 } 562 563 static int 564 si70xx_match(device_t parent, cfdata_t match, void *aux) 565 { 566 struct i2c_attach_args *ia = aux; 567 int error, match_result; 568 const bool matchdebug = false; 569 570 if (iic_use_direct_match(ia, match, NULL, &match_result)) 571 return match_result; 572 573 /* indirect config - check for configured address */ 574 if (ia->ia_addr != SI70XX_TYPICAL_ADDR) 575 return 0; 576 577 /* 578 * Check to see if something is really at this i2c address. This will 579 * keep phantom devices from appearing 580 */ 581 if (iic_acquire_bus(ia->ia_tag, 0) != 0) { 582 if (matchdebug) 583 printf("in match acquire bus failed\n"); 584 return 0; 585 } 586 587 error = si70xx_poke(ia->ia_tag, ia->ia_addr, matchdebug); 588 iic_release_bus(ia->ia_tag, 0); 589 590 return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0; 591 } 592 593 static void 594 si70xx_attach(device_t parent, device_t self, void *aux) 595 { 596 struct si70xx_sc *sc; 597 struct i2c_attach_args *ia; 598 int error, i; 599 int ecount = 0; 600 uint8_t buf[8]; 601 uint8_t testcrcpt1[4]; 602 uint8_t testcrcpt2[4]; 603 uint8_t crc1 = 0, crc2 = 0; 604 uint8_t readcrc1 = 0, readcrc2 = 0; 605 uint8_t fwversion, model; 606 607 ia = aux; 608 sc = device_private(self); 609 610 sc->sc_dev = self; 611 sc->sc_tag = ia->ia_tag; 612 sc->sc_addr = ia->ia_addr; 613 sc->sc_si70xxdebug = 0; 614 #ifdef HAVE_I2C_EXECV 615 sc->sc_clockstretch = 2048; 616 #endif 617 sc->sc_readattempts = 25; 618 sc->sc_ignorecrc = false; 619 sc->sc_sme = NULL; 620 621 aprint_normal("\n"); 622 623 mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE); 624 sc->sc_numsensors = __arraycount(si70xx_sensors); 625 626 if ((sc->sc_sme = sysmon_envsys_create()) == NULL) { 627 aprint_error_dev(self, 628 "Unable to create sysmon structure\n"); 629 sc->sc_sme = NULL; 630 return; 631 } 632 if ((error = si70xx_sysctl_init(sc)) != 0) { 633 aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", error); 634 goto out; 635 } 636 637 error = iic_acquire_bus(sc->sc_tag, 0); 638 if (error) { 639 aprint_error_dev(self, "Could not acquire iic bus: %d\n", 640 error); 641 goto out; 642 } 643 error = si70xx_cmd1(sc, SI70XX_RESET, NULL, 0); 644 if (error != 0) 645 aprint_error_dev(self, "Reset failed: %d\n", error); 646 647 delay(15000); /* 15 ms max */ 648 649 error = si70xx_cmd2(sc, SI70XX_READ_ID_PT1A, SI70XX_READ_ID_PT1B, 650 buf, 8); 651 if (error) { 652 aprint_error_dev(self, "Failed to read first part of ID: %d\n", 653 error); 654 ecount++; 655 } 656 testcrcpt1[0] = buf[0]; 657 testcrcpt1[1] = buf[2]; 658 testcrcpt1[2] = buf[4]; 659 testcrcpt1[3] = buf[6]; 660 readcrc1 = buf[7]; 661 crc1 = si70xx_crc(testcrcpt1, 4); 662 663 DPRINTF(sc, 2, ("%s: read 1 values: %02x%02x%02x%02x%02x%02x%02x%02x " 664 "- %02x\n", device_xname(sc->sc_dev), buf[0], buf[1], 665 buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], 666 crc1)); 667 668 error = si70xx_cmd2(sc, SI70XX_READ_ID_PT2A, SI70XX_READ_ID_PT2B, 669 buf, 8); 670 if (error != 0) { 671 aprint_error_dev(self, "Failed to read second part of ID: %d\n", 672 error); 673 ecount++; 674 } 675 model = testcrcpt2[0] = buf[0]; 676 testcrcpt2[1] = buf[1]; 677 testcrcpt2[2] = buf[3]; 678 testcrcpt2[3] = buf[4]; 679 readcrc2 = buf[5]; 680 crc2 = si70xx_crc(testcrcpt2, 4); 681 682 DPRINTF(sc, 2, ("%s: read 2 values: %02x%02x%02x%02x%02x%02x - %02x\n", 683 device_xname(sc->sc_dev), buf[0], buf[1], buf[2], 684 buf[3], buf[4], buf[5], crc2)); 685 686 error = si70xx_cmd2(sc, SI70XX_READ_FW_VERA, SI70XX_READ_FW_VERB, 687 buf, 8); 688 689 if (error) { 690 aprint_error_dev(self, "Failed to read firware version: %d\n", 691 error); 692 ecount++; 693 } 694 fwversion = buf[0]; 695 DPRINTF(sc, 2, ("%s: read fw values: %#x\n", device_xname(sc->sc_dev), 696 fwversion)); 697 698 error = si70xx_update_status(sc); 699 iic_release_bus(sc->sc_tag, 0); 700 if (error != 0) { 701 aprint_error_dev(self, "Failed to update status: %x\n", error); 702 aprint_error_dev(self, "Unable to setup device\n"); 703 goto out; 704 } 705 706 for (i = 0; i < sc->sc_numsensors; i++) { 707 strlcpy(sc->sc_sensors[i].desc, si70xx_sensors[i].desc, 708 sizeof(sc->sc_sensors[i].desc)); 709 710 sc->sc_sensors[i].units = si70xx_sensors[i].type; 711 sc->sc_sensors[i].state = ENVSYS_SINVALID; 712 713 DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i, 714 sc->sc_sensors[i].desc)); 715 716 error = sysmon_envsys_sensor_attach(sc->sc_sme, 717 &sc->sc_sensors[i]); 718 if (error) { 719 aprint_error_dev(self, 720 "Unable to attach sensor %d: %d\n", i, error); 721 sc->sc_sme = NULL; 722 goto out; 723 } 724 } 725 726 sc->sc_sme->sme_name = device_xname(sc->sc_dev); 727 sc->sc_sme->sme_cookie = sc; 728 sc->sc_sme->sme_refresh = si70xx_refresh; 729 730 DPRINTF(sc, 2, ("si70xx_attach: registering with envsys\n")); 731 732 if (sysmon_envsys_register(sc->sc_sme)) { 733 aprint_error_dev(self, 734 "unable to register with sysmon\n"); 735 sysmon_envsys_destroy(sc->sc_sme); 736 sc->sc_sme = NULL; 737 return; 738 } 739 if (ecount != 0) { 740 aprint_normal_dev(self, "Could not read model, " 741 "probably an HTU21D\n"); 742 return; 743 } 744 745 char modelstr[64]; 746 switch (model) { 747 case 0: 748 case 0xff: 749 snprintf(modelstr, sizeof(modelstr), "Engineering Sample"); 750 break; 751 case 13: 752 case 20: 753 case 21: 754 snprintf(modelstr, sizeof(modelstr), "SI70%d", model); 755 break; 756 default: 757 snprintf(modelstr, sizeof(modelstr), "Unknown SI70%d", model); 758 break; 759 } 760 761 const char *fwversionstr; 762 switch (fwversion) { 763 case 0xff: 764 fwversionstr = "1.0"; 765 break; 766 case 0x20: 767 fwversionstr = "2.0"; 768 break; 769 default: 770 fwversionstr = "unknown"; 771 break; 772 } 773 774 aprint_normal_dev(self, "Silicon Labs Model: %s, " 775 "Firmware version: %s, " 776 "Serial number: %02x%02x%02x%02x%02x%02x%02x%02x%s", 777 modelstr, fwversionstr, testcrcpt1[0], testcrcpt1[1], 778 testcrcpt1[2], testcrcpt1[3], testcrcpt2[0], testcrcpt2[1], 779 testcrcpt2[2], testcrcpt2[3], 780 (crc1 == readcrc1 && crc2 == readcrc2) ? "\n" : " (bad crc)\n"); 781 return; 782 out: 783 sysmon_envsys_destroy(sc->sc_sme); 784 sc->sc_sme = NULL; 785 } 786 787 static int 788 si70xx_exec(struct si70xx_sc *sc, uint8_t cmd, envsys_data_t *edata) 789 { 790 int error; 791 int xdelay; 792 const char *name; 793 int64_t mul, offs; 794 uint8_t buf[3]; 795 796 switch (cmd) { 797 case SI70XX_MEASURE_RH_NOHOLD: 798 /* 799 * The published conversion for RH is: %RH = 800 * ((125 * RHCODE) / 65536) - 6 801 * 802 * The sysmon infrastructure for RH wants %RH * 803 * 10^6 The result will fit in 32 bits, but 804 * the intermediate values will not. 805 */ 806 mul = 125000000; 807 offs = -6000000; 808 /* 809 * Conversion times for %RH in ms 810 * 811 * Typical Max 812 * 12-bit 10.0 12.0 813 * 11-bit 5.8 7.0 814 * 10-bit 3.7 4.5 815 * 8-bit 2.6 3.1 816 * 817 * A call to read %RH will also read temperature. The 818 * conversion time will be the amount of time above 819 * plus the amount of time for temperature below 820 */ 821 xdelay = 10500; 822 name = "RH"; 823 break; 824 case SI70XX_MEASURE_TEMP_NOHOLD: 825 /* 826 * The published conversion for temp is: 827 * degree C = ((175.72 * TEMPCODE) / 65536) - 828 * 46.85 829 * 830 * The sysmon infrastructure for temp wants 831 * microkelvin. This is simple, as degree C 832 * converts directly with K with simple 833 * addition. The result will fit in 32 bits, 834 * but the intermediate values will not. 835 */ 836 mul = 175720000; 837 offs = 226300000; 838 /* 839 * Conversion times for temperature in ms 840 * 841 * Typical Max 842 * 14-bit 7.0 10.8 843 * 13-bit 4.0 6.2 844 * 12-bit 2.4 3.8 845 * 11-bit 1.5 2.4 846 */ 847 xdelay = 4750; 848 name = "TEMP"; 849 break; 850 default: 851 return EINVAL; 852 } 853 854 #if HAVE_I2C_EXECV 855 memset(buf, 0, sizeof(buf)); 856 error = iic_execv(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, 857 &cmd, 1, buf, sizeof(buf), 0, I2C_ATTR_CLOCKSTRETCH, 858 sc->sc_clockstretch, I2C_ATTR_EOL); 859 #else 860 /* 861 * The lower level driver must support the ability to 862 * do a zero length read, otherwise this breaks 863 */ 864 error = si70xx_cmd1(sc, cmd, buf, 0); 865 if (error) { 866 DPRINTF(sc, 2, ("%s: Failed to read NO HOLD %s %d %d\n", 867 device_xname(sc->sc_dev), name, 1, error)); 868 return error; 869 } 870 871 /* 872 * It will probably be at least this long... we would 873 * not have to do this sort of thing if clock 874 * stretching worked. Even this is a problem for the 875 * RPI without a patch to remove a [apparently] not 876 * needed KASSERT() 877 */ 878 delay(xdelay); 879 880 for (int aint = 0; aint < sc->sc_readattempts; aint++) { 881 error = si70xx_cmd0(sc, buf, sizeof(buf)); 882 if (error == 0) 883 break; 884 DPRINTF(sc, 2, ("%s: Failed to read NO HOLD RH" 885 " %d %d\n", device_xname(sc->sc_dev), 2, error)); 886 delay(1000); 887 } 888 #endif 889 890 DPRINTF(sc, 2, ("%s: %s values: %02x%02x%02x - %02x\n", 891 device_xname(sc->sc_dev), name, buf[0], buf[1], buf[2], 892 si70xx_crc(buf, 2))); 893 894 uint8_t crc; 895 if (sc->sc_ignorecrc) { 896 crc = buf[2]; 897 } else { 898 crc = si70xx_crc(buf, 2); 899 } 900 901 if (crc != buf[2]) { 902 DPRINTF(sc, 2, ("%s: Bad CRC for %s: %#x and %#x\n", 903 device_xname(sc->sc_dev), name, crc, buf[2])); 904 return EINVAL; 905 } 906 907 uint16_t val16 = (buf[0] << 8) | buf[1]; 908 uint64_t val64 = ((mul * val16) >> 16) + offs; 909 DPRINTF(sc, 2, ("%s: %s calculated values: %x %#jx\n", 910 device_xname(sc->sc_dev), name, val16, (uintmax_t)val64)); 911 edata->value_cur = (uint32_t) val64; 912 edata->state = ENVSYS_SVALID; 913 return 0; 914 } 915 916 static void 917 si70xx_refresh(struct sysmon_envsys * sme, envsys_data_t * edata) 918 { 919 struct si70xx_sc *sc; 920 int error; 921 922 sc = sme->sme_cookie; 923 edata->state = ENVSYS_SINVALID; 924 925 mutex_enter(&sc->sc_mutex); 926 error = iic_acquire_bus(sc->sc_tag, 0); 927 if (error) { 928 DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n", 929 device_xname(sc->sc_dev), error)); 930 goto out; 931 } 932 error = si70xx_update_status(sc); 933 if (error) { 934 DPRINTF(sc, 2, ("%s: Failed to update status in refresh %d\n", 935 device_xname(sc->sc_dev), error)); 936 goto out1; 937 } 938 switch (edata->sensor) { 939 case SI70XX_HUMIDITY_SENSOR: 940 error = si70xx_exec(sc, SI70XX_MEASURE_RH_NOHOLD, edata); 941 break; 942 943 case SI70XX_TEMP_SENSOR: 944 error = si70xx_exec(sc, SI70XX_MEASURE_TEMP_NOHOLD, edata); 945 break; 946 default: 947 error = EINVAL; 948 break; 949 } 950 951 if (error) { 952 DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d\n", 953 device_xname(sc->sc_dev), error)); 954 } 955 out1: 956 iic_release_bus(sc->sc_tag, 0); 957 out: 958 mutex_exit(&sc->sc_mutex); 959 } 960 961 static int 962 si70xx_detach(device_t self, int flags) 963 { 964 struct si70xx_sc *sc; 965 966 sc = device_private(self); 967 968 mutex_enter(&sc->sc_mutex); 969 970 /* Remove the sensors */ 971 if (sc->sc_sme != NULL) { 972 sysmon_envsys_unregister(sc->sc_sme); 973 sc->sc_sme = NULL; 974 } 975 mutex_exit(&sc->sc_mutex); 976 977 /* Remove the sysctl tree */ 978 sysctl_teardown(&sc->sc_si70xxlog); 979 980 /* Remove the mutex */ 981 mutex_destroy(&sc->sc_mutex); 982 983 return 0; 984 } 985 986 MODULE(MODULE_CLASS_DRIVER, si70xxtemp, "i2cexec,sysmon_envsys"); 987 988 #ifdef _MODULE 989 #include "ioconf.c" 990 #endif 991 992 static int 993 si70xxtemp_modcmd(modcmd_t cmd, void *opaque) 994 { 995 996 switch (cmd) { 997 case MODULE_CMD_INIT: 998 #ifdef _MODULE 999 return config_init_component(cfdriver_ioconf_si70xxtemp, 1000 cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp); 1001 #else 1002 return 0; 1003 #endif 1004 case MODULE_CMD_FINI: 1005 #ifdef _MODULE 1006 return config_fini_component(cfdriver_ioconf_si70xxtemp, 1007 cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp); 1008 #else 1009 return 0; 1010 #endif 1011 default: 1012 return ENOTTY; 1013 } 1014 } 1015