1 /* $NetBSD: si70xx.c,v 1.3 2017/12/30 03:18:26 christos 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.3 2017/12/30 03:18:26 christos 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; 567 int error; 568 const bool matchdebug = false; 569 570 ia = aux; 571 572 if (ia->ia_name) { 573 /* direct config - check name */ 574 if (strcmp(ia->ia_name, "si70xxtemp") != 0) 575 return 0; 576 } else { 577 /* indirect config - check for configured address */ 578 if (ia->ia_addr != SI70XX_TYPICAL_ADDR) 579 return 0; 580 } 581 582 /* 583 * Check to see if something is really at this i2c address. This will 584 * keep phantom devices from appearing 585 */ 586 if (iic_acquire_bus(ia->ia_tag, 0) != 0) { 587 if (matchdebug) 588 printf("in match acquire bus failed\n"); 589 return 0; 590 } 591 592 error = si70xx_poke(ia->ia_tag, ia->ia_addr, matchdebug); 593 iic_release_bus(ia->ia_tag, 0); 594 595 return error == 0; 596 } 597 598 static void 599 si70xx_attach(device_t parent, device_t self, void *aux) 600 { 601 struct si70xx_sc *sc; 602 struct i2c_attach_args *ia; 603 int error, i; 604 int ecount = 0; 605 uint8_t buf[8]; 606 uint8_t testcrcpt1[4]; 607 uint8_t testcrcpt2[4]; 608 uint8_t crc1 = 0, crc2 = 0; 609 uint8_t readcrc1 = 0, readcrc2 = 0; 610 uint8_t fwversion, model; 611 612 ia = aux; 613 sc = device_private(self); 614 615 sc->sc_dev = self; 616 sc->sc_tag = ia->ia_tag; 617 sc->sc_addr = ia->ia_addr; 618 sc->sc_si70xxdebug = 0; 619 #ifdef HAVE_I2C_EXECV 620 sc->sc_clockstretch = 2048; 621 #endif 622 sc->sc_readattempts = 25; 623 sc->sc_ignorecrc = false; 624 sc->sc_sme = NULL; 625 626 aprint_normal("\n"); 627 628 mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE); 629 sc->sc_numsensors = __arraycount(si70xx_sensors); 630 631 if ((sc->sc_sme = sysmon_envsys_create()) == NULL) { 632 aprint_error_dev(self, 633 "Unable to create sysmon structure\n"); 634 sc->sc_sme = NULL; 635 return; 636 } 637 if ((error = si70xx_sysctl_init(sc)) != 0) { 638 aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", error); 639 goto out; 640 } 641 642 error = iic_acquire_bus(sc->sc_tag, 0); 643 if (error) { 644 aprint_error_dev(self, "Could not acquire iic bus: %d\n", 645 error); 646 goto out; 647 } 648 error = si70xx_cmd1(sc, SI70XX_RESET, NULL, 0); 649 if (error != 0) 650 aprint_error_dev(self, "Reset failed: %d\n", error); 651 652 delay(15000); /* 15 ms max */ 653 654 error = si70xx_cmd2(sc, SI70XX_READ_ID_PT1A, SI70XX_READ_ID_PT1B, 655 buf, 8); 656 if (error) { 657 aprint_error_dev(self, "Failed to read first part of ID: %d\n", 658 error); 659 ecount++; 660 } 661 testcrcpt1[0] = buf[0]; 662 testcrcpt1[1] = buf[2]; 663 testcrcpt1[2] = buf[4]; 664 testcrcpt1[3] = buf[6]; 665 readcrc1 = buf[7]; 666 crc1 = si70xx_crc(testcrcpt1, 4); 667 668 DPRINTF(sc, 2, ("%s: read 1 values: %02x%02x%02x%02x%02x%02x%02x%02x " 669 "- %02x\n", device_xname(sc->sc_dev), buf[0], buf[1], 670 buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], 671 crc1)); 672 673 error = si70xx_cmd2(sc, SI70XX_READ_ID_PT2A, SI70XX_READ_ID_PT2B, 674 buf, 8); 675 if (error != 0) { 676 aprint_error_dev(self, "Failed to read second part of ID: %d\n", 677 error); 678 ecount++; 679 } 680 model = testcrcpt2[0] = buf[0]; 681 testcrcpt2[1] = buf[1]; 682 testcrcpt2[2] = buf[3]; 683 testcrcpt2[3] = buf[4]; 684 readcrc2 = buf[5]; 685 crc2 = si70xx_crc(testcrcpt2, 4); 686 687 DPRINTF(sc, 2, ("%s: read 2 values: %02x%02x%02x%02x%02x%02x - %02x\n", 688 device_xname(sc->sc_dev), buf[0], buf[1], buf[2], 689 buf[3], buf[4], buf[5], crc2)); 690 691 error = si70xx_cmd2(sc, SI70XX_READ_FW_VERA, SI70XX_READ_FW_VERB, 692 buf, 8); 693 694 if (error) { 695 aprint_error_dev(self, "Failed to read firware version: %d\n", 696 error); 697 ecount++; 698 } 699 fwversion = buf[0]; 700 DPRINTF(sc, 2, ("%s: read fw values: %#x\n", device_xname(sc->sc_dev), 701 fwversion)); 702 703 error = si70xx_update_status(sc); 704 iic_release_bus(sc->sc_tag, 0); 705 if (error != 0) { 706 aprint_error_dev(self, "Failed to update status: %x\n", error); 707 aprint_error_dev(self, "Unable to setup device\n"); 708 goto out; 709 } 710 711 for (i = 0; i < sc->sc_numsensors; i++) { 712 strlcpy(sc->sc_sensors[i].desc, si70xx_sensors[i].desc, 713 sizeof(sc->sc_sensors[i].desc)); 714 715 sc->sc_sensors[i].units = si70xx_sensors[i].type; 716 sc->sc_sensors[i].state = ENVSYS_SINVALID; 717 718 DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i, 719 sc->sc_sensors[i].desc)); 720 721 error = sysmon_envsys_sensor_attach(sc->sc_sme, 722 &sc->sc_sensors[i]); 723 if (error) { 724 aprint_error_dev(self, 725 "Unable to attach sensor %d: %d\n", i, error); 726 goto out; 727 } 728 } 729 730 sc->sc_sme->sme_name = device_xname(sc->sc_dev); 731 sc->sc_sme->sme_cookie = sc; 732 sc->sc_sme->sme_refresh = si70xx_refresh; 733 734 DPRINTF(sc, 2, ("si70xx_attach: registering with envsys\n")); 735 736 if (sysmon_envsys_register(sc->sc_sme)) { 737 aprint_error_dev(self, 738 "unable to register with sysmon\n"); 739 sysmon_envsys_destroy(sc->sc_sme); 740 sc->sc_sme = NULL; 741 return; 742 } 743 if (ecount != 0) { 744 aprint_normal_dev(self, "Could not read model, " 745 "probably an HTU21D\n"); 746 return; 747 } 748 749 char modelstr[64]; 750 switch (model) { 751 case 0: 752 case 0xff: 753 snprintf(modelstr, sizeof(modelstr), "Engineering Sample"); 754 case 13: 755 case 20: 756 case 21: 757 snprintf(modelstr, sizeof(modelstr), "SI70%d", model); 758 break; 759 default: 760 snprintf(modelstr, sizeof(modelstr), "Unknown SI70%d", model); 761 break; 762 } 763 764 const char *fwversionstr; 765 switch (fwversion) { 766 case 0xff: 767 fwversionstr = "1.0"; 768 break; 769 case 0x20: 770 fwversionstr = "2.0"; 771 break; 772 default: 773 fwversionstr = "unknown"; 774 break; 775 } 776 777 aprint_normal_dev(self, "Silicon Labs Model: %s, " 778 "Firmware version: %s, " 779 "Serial number: %02x%02x%02x%02x%02x%02x%02x%02x%s", 780 modelstr, fwversionstr, testcrcpt1[0], testcrcpt1[1], 781 testcrcpt1[2], testcrcpt1[3], testcrcpt2[0], testcrcpt2[1], 782 testcrcpt2[2], testcrcpt2[3], 783 (crc1 == readcrc1 && crc2 == readcrc2) ? "\n" : " (bad crc)\n"); 784 return; 785 out: 786 sysmon_envsys_destroy(sc->sc_sme); 787 sc->sc_sme = NULL; 788 } 789 790 static int 791 si70xx_exec(struct si70xx_sc *sc, uint8_t cmd, envsys_data_t *edata) 792 { 793 int error; 794 int xdelay; 795 const char *name; 796 int64_t mul, offs; 797 uint8_t buf[3]; 798 799 switch (cmd) { 800 case SI70XX_MEASURE_RH_NOHOLD: 801 /* 802 * The published conversion for RH is: %RH = 803 * ((125 * RHCODE) / 65536) - 6 804 * 805 * The sysmon infrastructure for RH wants %RH * 806 * 10^6 The result will fit in 32 bits, but 807 * the intermediate values will not. 808 */ 809 mul = 125000000; 810 offs = -6000000; 811 /* 812 * Conversion times for %RH in ms 813 * 814 * Typical Max 815 * 12-bit 10.0 12.0 816 * 11-bit 5.8 7.0 817 * 10-bit 3.7 4.5 818 * 8-bit 2.6 3.1 819 * 820 * A call to read %RH will also read temperature. The 821 * conversion time will be the amount of time above 822 * plus the amount of time for temperature below 823 */ 824 xdelay = 10500; 825 name = "RH"; 826 break; 827 case SI70XX_MEASURE_TEMP_NOHOLD: 828 /* 829 * The published conversion for temp is: 830 * degree C = ((175.72 * TEMPCODE) / 65536) - 831 * 46.85 832 * 833 * The sysmon infrastructure for temp wants 834 * microkelvin. This is simple, as degree C 835 * converts directly with K with simple 836 * addition. The result will fit in 32 bits, 837 * but the intermediate values will not. 838 */ 839 mul = 175720000; 840 offs = 226300000; 841 /* 842 * Conversion times for temperature in ms 843 * 844 * Typical Max 845 * 14-bit 7.0 10.8 846 * 13-bit 4.0 6.2 847 * 12-bit 2.4 3.8 848 * 11-bit 1.5 2.4 849 */ 850 xdelay = 4750; 851 name = "TEMP"; 852 break; 853 default: 854 return EINVAL; 855 } 856 857 #if HAVE_I2C_EXECV 858 memset(buf, 0, sizeof(buf)); 859 error = iic_execv(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, 860 &cmd, 1, buf, sizeof(buf), 0, I2C_ATTR_CLOCKSTRETCH, 861 sc->sc_clockstretch, I2C_ATTR_EOL); 862 #else 863 /* 864 * The lower level driver must support the ability to 865 * do a zero length read, otherwise this breaks 866 */ 867 error = si70xx_cmd1(sc, cmd, buf, 0); 868 if (error) { 869 DPRINTF(sc, 2, ("%s: Failed to read NO HOLD %s %d %d\n", 870 device_xname(sc->sc_dev), name, 1, error)); 871 return error; 872 } 873 874 /* 875 * It will probably be at least this long... we would 876 * not have to do this sort of thing if clock 877 * stretching worked. Even this is a problem for the 878 * RPI without a patch to remove a [apparently] not 879 * needed KASSERT() 880 */ 881 delay(xdelay); 882 883 for (int aint = 0; aint < sc->sc_readattempts; aint++) { 884 error = si70xx_cmd0(sc, buf, sizeof(buf)); 885 if (error == 0) 886 break; 887 DPRINTF(sc, 2, ("%s: Failed to read NO HOLD RH" 888 " %d %d\n", device_xname(sc->sc_dev), 2, error)); 889 delay(1000); 890 } 891 #endif 892 893 DPRINTF(sc, 2, ("%s: %s values: %02x%02x%02x - %02x\n", 894 device_xname(sc->sc_dev), name, buf[0], buf[1], buf[2], 895 si70xx_crc(buf, 2))); 896 897 uint8_t crc; 898 if (sc->sc_ignorecrc) { 899 crc = buf[2]; 900 } else { 901 crc = si70xx_crc(buf, 2); 902 } 903 904 if (crc != buf[2]) { 905 DPRINTF(sc, 2, ("%s: Bad CRC for %s: %#x and %#x\n", 906 device_xname(sc->sc_dev), name, crc, buf[2])); 907 return EINVAL; 908 } 909 910 uint16_t val16 = (buf[0] << 8) | buf[1]; 911 uint64_t val64 = ((mul * val16) >> 16) + offs; 912 DPRINTF(sc, 2, ("%s: %s calculated values: %x %#jx\n", 913 device_xname(sc->sc_dev), name, val16, (uintmax_t)val64)); 914 edata->value_cur = (uint32_t) val64; 915 edata->state = ENVSYS_SVALID; 916 return 0; 917 } 918 919 static void 920 si70xx_refresh(struct sysmon_envsys * sme, envsys_data_t * edata) 921 { 922 struct si70xx_sc *sc; 923 int error; 924 925 sc = sme->sme_cookie; 926 edata->state = ENVSYS_SINVALID; 927 928 mutex_enter(&sc->sc_mutex); 929 error = iic_acquire_bus(sc->sc_tag, 0); 930 if (error) { 931 DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n", 932 device_xname(sc->sc_dev), error)); 933 goto out; 934 } 935 error = si70xx_update_status(sc); 936 if (error) { 937 DPRINTF(sc, 2, ("%s: Failed to update status in refresh %d\n", 938 device_xname(sc->sc_dev), error)); 939 goto out1; 940 } 941 switch (edata->sensor) { 942 case SI70XX_HUMIDITY_SENSOR: 943 error = si70xx_exec(sc, SI70XX_MEASURE_RH_NOHOLD, edata); 944 break; 945 946 case SI70XX_TEMP_SENSOR: 947 error = si70xx_exec(sc, SI70XX_MEASURE_TEMP_NOHOLD, edata); 948 break; 949 default: 950 error = EINVAL; 951 break; 952 } 953 954 if (error) { 955 DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d\n", 956 device_xname(sc->sc_dev), error)); 957 } 958 out1: 959 iic_release_bus(sc->sc_tag, 0); 960 out: 961 mutex_exit(&sc->sc_mutex); 962 } 963 964 static int 965 si70xx_detach(device_t self, int flags) 966 { 967 struct si70xx_sc *sc; 968 969 sc = device_private(self); 970 971 mutex_enter(&sc->sc_mutex); 972 973 /* Remove the sensors */ 974 if (sc->sc_sme != NULL) { 975 sysmon_envsys_unregister(sc->sc_sme); 976 sc->sc_sme = NULL; 977 } 978 mutex_exit(&sc->sc_mutex); 979 980 /* Remove the sysctl tree */ 981 sysctl_teardown(&sc->sc_si70xxlog); 982 983 /* Remove the mutex */ 984 mutex_destroy(&sc->sc_mutex); 985 986 return 0; 987 } 988 989 MODULE(MODULE_CLASS_DRIVER, si70xxtemp, "i2cexec,sysmon_envsys"); 990 991 #ifdef _MODULE 992 #include "ioconf.c" 993 #endif 994 995 static int 996 si70xxtemp_modcmd(modcmd_t cmd, void *opaque) 997 { 998 999 switch (cmd) { 1000 case MODULE_CMD_INIT: 1001 #ifdef _MODULE 1002 return config_init_component(cfdriver_ioconf_si70xxtemp, 1003 cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp); 1004 #else 1005 return 0; 1006 #endif 1007 case MODULE_CMD_FINI: 1008 #ifdef _MODULE 1009 return config_fini_component(cfdriver_ioconf_si70xxtemp, 1010 cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp); 1011 #else 1012 return 0; 1013 #endif 1014 default: 1015 return ENOTTY; 1016 } 1017 } 1018