Home | History | Annotate | Line # | Download | only in i2c
si70xx.c revision 1.4
      1 /*	$NetBSD: si70xx.c,v 1.4 2018/06/16 21:22:13 thorpej 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.4 2018/06/16 21:22:13 thorpej 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, &reg, 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 			goto out;
    722 		}
    723 	}
    724 
    725 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
    726 	sc->sc_sme->sme_cookie = sc;
    727 	sc->sc_sme->sme_refresh = si70xx_refresh;
    728 
    729 	DPRINTF(sc, 2, ("si70xx_attach: registering with envsys\n"));
    730 
    731 	if (sysmon_envsys_register(sc->sc_sme)) {
    732 		aprint_error_dev(self,
    733 			"unable to register with sysmon\n");
    734 		sysmon_envsys_destroy(sc->sc_sme);
    735 		sc->sc_sme = NULL;
    736 		return;
    737 	}
    738 	if (ecount != 0) {
    739 		aprint_normal_dev(self, "Could not read model, "
    740 		    "probably an HTU21D\n");
    741 		return;
    742 	}
    743 
    744 	char modelstr[64];
    745 	switch (model) {
    746 	case 0:
    747 	case 0xff:
    748 		snprintf(modelstr, sizeof(modelstr), "Engineering Sample");
    749 	case 13:
    750 	case 20:
    751 	case 21:
    752 		snprintf(modelstr, sizeof(modelstr), "SI70%d", model);
    753 		break;
    754 	default:
    755 		snprintf(modelstr, sizeof(modelstr), "Unknown SI70%d", model);
    756 		break;
    757 	}
    758 
    759 	const char *fwversionstr;
    760 	switch (fwversion) {
    761 	case 0xff:
    762 		fwversionstr = "1.0";
    763 		break;
    764 	case 0x20:
    765 		fwversionstr = "2.0";
    766 		break;
    767 	default:
    768 		fwversionstr = "unknown";
    769 		break;
    770 	}
    771 
    772 	aprint_normal_dev(self, "Silicon Labs Model: %s, "
    773 	    "Firmware version: %s, "
    774 	    "Serial number: %02x%02x%02x%02x%02x%02x%02x%02x%s",
    775 	    modelstr, fwversionstr, testcrcpt1[0], testcrcpt1[1],
    776 	    testcrcpt1[2], testcrcpt1[3], testcrcpt2[0], testcrcpt2[1],
    777 	    testcrcpt2[2], testcrcpt2[3],
    778 	    (crc1 == readcrc1 && crc2 == readcrc2) ? "\n" : " (bad crc)\n");
    779 	return;
    780 out:
    781 	sysmon_envsys_destroy(sc->sc_sme);
    782 	sc->sc_sme = NULL;
    783 }
    784 
    785 static int
    786 si70xx_exec(struct si70xx_sc *sc, uint8_t cmd, envsys_data_t *edata)
    787 {
    788 	int error;
    789 	int xdelay;
    790 	const char *name;
    791 	int64_t mul, offs;
    792 	uint8_t buf[3];
    793 
    794 	switch (cmd) {
    795 	case SI70XX_MEASURE_RH_NOHOLD:
    796 		/*
    797 		 * The published conversion for RH is: %RH =
    798 		 * ((125 * RHCODE) / 65536) - 6
    799 		 *
    800 		 * The sysmon infrastructure for RH wants %RH *
    801 		 * 10^6 The result will fit in 32 bits, but
    802 		 * the intermediate values will not.
    803 		 */
    804 		mul = 125000000;
    805 		offs = -6000000;
    806 		/*
    807 		 * Conversion times for %RH in ms
    808 		 *
    809 		 *        	Typical Max
    810 		 * 12-bit	10.0	12.0
    811 		 * 11-bit	 5.8	 7.0
    812 		 * 10-bit	 3.7	 4.5
    813 		 *  8-bit	 2.6	 3.1
    814 		 *
    815 		 * A call to read %RH will also read temperature.  The
    816 		 * conversion time will be the amount of time above
    817 		 * plus the amount of time for temperature below
    818 		 */
    819 		xdelay = 10500;
    820 		name = "RH";
    821 		break;
    822 	case SI70XX_MEASURE_TEMP_NOHOLD:
    823 		/*
    824 		 * The published conversion for temp is:
    825 		 * degree C = ((175.72 * TEMPCODE) / 65536) -
    826 		 * 46.85
    827 		 *
    828 		 * The sysmon infrastructure for temp wants
    829 		 * microkelvin.  This is simple, as degree C
    830 		 * converts directly with K with simple
    831 		 * addition. The result will fit in 32 bits,
    832 		 * but the intermediate values will not.
    833 		 */
    834 		mul = 175720000;
    835 		offs = 226300000;
    836 		/*
    837 		 * Conversion times for temperature in ms
    838 	 	 *
    839 		 *		Typical	Max
    840 		 * 14-bit	7.0	10.8
    841 		 * 13-bit	4.0	 6.2
    842 		 * 12-bit	2.4	 3.8
    843 		 * 11-bit	1.5	 2.4
    844 		 */
    845 		xdelay = 4750;
    846 		name = "TEMP";
    847 		break;
    848 	default:
    849 		return EINVAL;
    850 	}
    851 
    852 #if HAVE_I2C_EXECV
    853 	memset(buf, 0, sizeof(buf));
    854 	error = iic_execv(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
    855 	    &cmd, 1, buf, sizeof(buf), 0, I2C_ATTR_CLOCKSTRETCH,
    856 	    sc->sc_clockstretch, I2C_ATTR_EOL);
    857 #else
    858 	/*
    859 	 * The lower level driver must support the ability to
    860 	 * do a zero length read, otherwise this breaks
    861 	 */
    862 	error = si70xx_cmd1(sc, cmd, buf, 0);
    863 	if (error) {
    864 		DPRINTF(sc, 2, ("%s: Failed to read NO HOLD %s %d %d\n",
    865 		    device_xname(sc->sc_dev), name, 1, error));
    866 		return error;
    867 	}
    868 
    869 	/*
    870 	 * It will probably be at least this long... we would
    871 	 * not have to do this sort of thing if clock
    872 	 * stretching worked.  Even this is a problem for the
    873 	 * RPI without a patch to remove a [apparently] not
    874 	 * needed KASSERT()
    875 	 */
    876 	delay(xdelay);
    877 
    878 	for (int aint = 0; aint < sc->sc_readattempts; aint++) {
    879 		error = si70xx_cmd0(sc, buf, sizeof(buf));
    880 		if (error == 0)
    881 			break;
    882 		DPRINTF(sc, 2, ("%s: Failed to read NO HOLD RH"
    883 		    " %d %d\n", device_xname(sc->sc_dev), 2, error));
    884 		delay(1000);
    885 	}
    886 #endif
    887 
    888 	DPRINTF(sc, 2, ("%s: %s values: %02x%02x%02x - %02x\n",
    889 	    device_xname(sc->sc_dev), name, buf[0], buf[1], buf[2],
    890 	    si70xx_crc(buf, 2)));
    891 
    892 	uint8_t crc;
    893 	if (sc->sc_ignorecrc) {
    894 		crc = buf[2];
    895 	} else {
    896 		crc = si70xx_crc(buf, 2);
    897 	}
    898 
    899 	if (crc != buf[2]) {
    900 		DPRINTF(sc, 2, ("%s: Bad CRC for %s: %#x and %#x\n",
    901 		    device_xname(sc->sc_dev), name, crc, buf[2]));
    902 		return EINVAL;
    903 	}
    904 
    905 	uint16_t val16 = (buf[0] << 8) | buf[1];
    906 	uint64_t val64 = ((mul * val16) >> 16) + offs;
    907 	DPRINTF(sc, 2, ("%s: %s calculated values: %x %#jx\n",
    908 	    device_xname(sc->sc_dev), name, val16, (uintmax_t)val64));
    909 	edata->value_cur = (uint32_t) val64;
    910 	edata->state = ENVSYS_SVALID;
    911 	return 0;
    912 }
    913 
    914 static void
    915 si70xx_refresh(struct sysmon_envsys * sme, envsys_data_t * edata)
    916 {
    917 	struct si70xx_sc *sc;
    918 	int 		error;
    919 
    920 	sc = sme->sme_cookie;
    921 	edata->state = ENVSYS_SINVALID;
    922 
    923 	mutex_enter(&sc->sc_mutex);
    924 	error = iic_acquire_bus(sc->sc_tag, 0);
    925 	if (error) {
    926 		DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
    927 		    device_xname(sc->sc_dev), error));
    928 		goto out;
    929 	}
    930 	error = si70xx_update_status(sc);
    931 	if (error) {
    932 		DPRINTF(sc, 2, ("%s: Failed to update status in refresh %d\n",
    933 		    device_xname(sc->sc_dev), error));
    934 		goto out1;
    935 	}
    936 	switch (edata->sensor) {
    937 	case SI70XX_HUMIDITY_SENSOR:
    938 		error = si70xx_exec(sc, SI70XX_MEASURE_RH_NOHOLD, edata);
    939 		break;
    940 
    941 	case SI70XX_TEMP_SENSOR:
    942 		error = si70xx_exec(sc, SI70XX_MEASURE_TEMP_NOHOLD, edata);
    943 		break;
    944 	default:
    945 		error = EINVAL;
    946 		break;
    947 	}
    948 
    949 	if (error) {
    950 		DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d\n",
    951 		    device_xname(sc->sc_dev), error));
    952 	}
    953 out1:
    954 	iic_release_bus(sc->sc_tag, 0);
    955 out:
    956 	mutex_exit(&sc->sc_mutex);
    957 }
    958 
    959 static int
    960 si70xx_detach(device_t self, int flags)
    961 {
    962 	struct si70xx_sc *sc;
    963 
    964 	sc = device_private(self);
    965 
    966 	mutex_enter(&sc->sc_mutex);
    967 
    968 	/* Remove the sensors */
    969 	if (sc->sc_sme != NULL) {
    970 		sysmon_envsys_unregister(sc->sc_sme);
    971 		sc->sc_sme = NULL;
    972 	}
    973 	mutex_exit(&sc->sc_mutex);
    974 
    975 	/* Remove the sysctl tree */
    976 	sysctl_teardown(&sc->sc_si70xxlog);
    977 
    978 	/* Remove the mutex */
    979 	mutex_destroy(&sc->sc_mutex);
    980 
    981 	return 0;
    982 }
    983 
    984 MODULE(MODULE_CLASS_DRIVER, si70xxtemp, "i2cexec,sysmon_envsys");
    985 
    986 #ifdef _MODULE
    987 #include "ioconf.c"
    988 #endif
    989 
    990 static int
    991 si70xxtemp_modcmd(modcmd_t cmd, void *opaque)
    992 {
    993 
    994 	switch (cmd) {
    995 	case MODULE_CMD_INIT:
    996 #ifdef _MODULE
    997 		return config_init_component(cfdriver_ioconf_si70xxtemp,
    998 		    cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp);
    999 #else
   1000 		return 0;
   1001 #endif
   1002 	case MODULE_CMD_FINI:
   1003 #ifdef _MODULE
   1004 		return config_fini_component(cfdriver_ioconf_si70xxtemp,
   1005 		      cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp);
   1006 #else
   1007 		return 0;
   1008 #endif
   1009 	default:
   1010 		return ENOTTY;
   1011 	}
   1012 }
   1013