Home | History | Annotate | Line # | Download | only in i2c
      1 /*	$NetBSD: si70xx.c,v 1.12 2025/01/23 19:13:19 brad Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2017 Brad Spencer <brad (at) 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, &reg, 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