Home | History | Annotate | Line # | Download | only in i2c
si70xx.c revision 1.10
      1 /*	$NetBSD: si70xx.c,v 1.10 2021/11/12 15:12:11 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.10 2021/11/12 15:12:11 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 		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 = 0;
    446 	if (! sc->sc_noheater) {
    447 		error2 = si70xx_update_heater(sc);
    448 	}
    449 	return error1 ? error1 : error2;
    450 }
    451 
    452 static	uint8_t
    453 si70xx_crc(uint8_t * data, size_t size)
    454 {
    455 	uint8_t crc = 0;
    456 
    457 	for (size_t i = 0; i < size; i++) {
    458 		crc ^= data[i];
    459 		for (size_t j = 8; j > 0; j--) {
    460 			if (crc & 0x80)
    461 				crc = (crc << 1) ^ 0x131;
    462 			else
    463 				crc <<= 1;
    464 		}
    465 	}
    466 	return crc;
    467 }
    468 
    469 static int
    470 si70xx_poke(i2c_tag_t tag, i2c_addr_t addr, bool matchdebug)
    471 {
    472 	uint8_t reg = SI70XX_READ_USER_REG_1;
    473 	uint8_t buf;
    474 	int error;
    475 
    476 	error = si70xx_cmd(tag, addr, &reg, 1, &buf, 1);
    477 	if (matchdebug) {
    478 		printf("poke X 1: %d\n", error);
    479 	}
    480 	return error;
    481 }
    482 
    483 static int
    484 si70xx_sysctl_init(struct si70xx_sc *sc)
    485 {
    486 	int error;
    487 	const struct sysctlnode *cnode;
    488 	int sysctlroot_num;
    489 
    490 	if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
    491 	    0, CTLTYPE_NODE, device_xname(sc->sc_dev),
    492 	    SYSCTL_DESCR("si70xx controls"), NULL, 0, NULL, 0, CTL_HW,
    493 	    CTL_CREATE, CTL_EOL)) != 0)
    494 		return error;
    495 
    496 	sysctlroot_num = cnode->sysctl_num;
    497 
    498 #ifdef SI70XX_DEBUG
    499 	if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
    500 	    CTLFLAG_READWRITE, CTLTYPE_INT, "debug",
    501 	    SYSCTL_DESCR("Debug level"), si70xx_verify_sysctl, 0,
    502 	    &sc->sc_si70xxdebug, 0, CTL_HW, sysctlroot_num, CTL_CREATE,
    503 	    CTL_EOL)) != 0)
    504 		return error;
    505 
    506 #endif
    507 
    508 #ifdef HAVE_I2C_EXECV
    509 	if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
    510 	    CTLFLAG_READWRITE, CTLTYPE_INT, "clockstretch",
    511 	    SYSCTL_DESCR("Clockstretch value"), si70xx_verify_sysctl, 0,
    512 	    &sc->sc_clockstretch, 0, CTL_HW, sysctlroot_num, CTL_CREATE,
    513 	    CTL_EOL)) != 0)
    514 		return error;
    515 #endif
    516 
    517 
    518 	if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
    519 	    CTLFLAG_READWRITE, CTLTYPE_INT, "readattempts",
    520 	    SYSCTL_DESCR("The number of times to attempt to read the values"),
    521 	    si70xx_verify_sysctl, 0, &sc->sc_readattempts, 0, CTL_HW,
    522 	    sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    523 		return error;
    524 
    525 
    526 	if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
    527 	    CTLFLAG_READONLY, CTLTYPE_STRING, "resolutions",
    528 	    SYSCTL_DESCR("Valid resolutions"), 0, 0,
    529 	    __UNCONST(si70xx_resolution_names),
    530 	    sizeof(si70xx_resolution_names) + 1,
    531 	    CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    532 		return error;
    533 
    534 	if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
    535 	    CTLFLAG_READWRITE, CTLTYPE_STRING, "resolution",
    536 	    SYSCTL_DESCR("Resolution of RH and Temp"),
    537 	    si70xx_verify_sysctl_resolution, 0, (void *) sc,
    538 	    SI70XX_RES_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    539 		return error;
    540 
    541 	if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
    542 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "ignorecrc",
    543 	    SYSCTL_DESCR("Ignore the CRC byte"), NULL, 0, &sc->sc_ignorecrc,
    544 	    0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    545 		return error;
    546 
    547 	if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
    548 	    CTLFLAG_READONLY, CTLTYPE_BOOL, "vddok",
    549 	    SYSCTL_DESCR("Vdd at least 1.9v"), NULL, 0, &sc->sc_vddok, 0,
    550 	    CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    551 		return error;
    552 
    553 	if (! sc->sc_noheater) {
    554 		if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
    555 		    CTLFLAG_READWRITE, CTLTYPE_BOOL, "heateron",
    556 		    SYSCTL_DESCR("Heater on"), si70xx_verify_sysctl_heateron, 0,
    557 		    (void *)sc, 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    558 			return error;
    559 
    560 		if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
    561 		    CTLFLAG_READWRITE, CTLTYPE_INT, "heaterstrength",
    562 		    SYSCTL_DESCR("Heater strength 1 to 6"),
    563 		    si70xx_verify_sysctl_heatervalue, 0, (void *)sc, 0, CTL_HW,
    564 		    sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    565 			return error;
    566 	}
    567 
    568 	return 0;
    569 }
    570 
    571 static int
    572 si70xx_match(device_t parent, cfdata_t match, void *aux)
    573 {
    574 	struct i2c_attach_args *ia = aux;
    575 	int error, match_result;
    576 	const bool matchdebug = false;
    577 
    578 	if (iic_use_direct_match(ia, match, NULL, &match_result))
    579 		return match_result;
    580 
    581 	/* indirect config - check for configured address */
    582 	if (ia->ia_addr != SI70XX_TYPICAL_ADDR)
    583 		return 0;
    584 
    585 	/*
    586 	 * Check to see if something is really at this i2c address. This will
    587 	 * keep phantom devices from appearing
    588 	 */
    589 	if (iic_acquire_bus(ia->ia_tag, 0) != 0) {
    590 		if (matchdebug)
    591 			printf("in match acquire bus failed\n");
    592 		return 0;
    593 	}
    594 
    595 	error = si70xx_poke(ia->ia_tag, ia->ia_addr, matchdebug);
    596 	iic_release_bus(ia->ia_tag, 0);
    597 
    598 	return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0;
    599 }
    600 
    601 static void
    602 si70xx_attach(device_t parent, device_t self, void *aux)
    603 {
    604 	struct si70xx_sc *sc;
    605 	struct i2c_attach_args *ia;
    606 	int error, i;
    607 	int ecount = 0;
    608 	uint8_t buf[8];
    609 	uint8_t testcrcpt1[4];
    610 	uint8_t testcrcpt2[4];
    611 	uint8_t crc1 = 0, crc2 = 0;
    612 	bool validcrcpt1, validcrcpt2;
    613 	uint8_t readcrc1 = 0, readcrc2 = 0;
    614 	uint8_t fwversion = 0, model, heaterregister;
    615 
    616 	ia = aux;
    617 	sc = device_private(self);
    618 
    619 	sc->sc_dev = self;
    620 	sc->sc_tag = ia->ia_tag;
    621 	sc->sc_addr = ia->ia_addr;
    622 	sc->sc_si70xxdebug = 0;
    623 #ifdef HAVE_I2C_EXECV
    624 	sc->sc_clockstretch = 2048;
    625 #endif
    626 	sc->sc_readattempts = 40;
    627 	sc->sc_ignorecrc = false;
    628 	sc->sc_sme = NULL;
    629 	sc->sc_noheater = false;
    630 	sc->sc_nofw = false;
    631 
    632 	aprint_normal("\n");
    633 
    634 	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE);
    635 	sc->sc_numsensors = __arraycount(si70xx_sensors);
    636 
    637 	if ((sc->sc_sme = sysmon_envsys_create()) == NULL) {
    638 		aprint_error_dev(self,
    639 		    "Unable to create sysmon structure\n");
    640 		sc->sc_sme = NULL;
    641 		return;
    642 	}
    643 
    644 	error = iic_acquire_bus(sc->sc_tag, 0);
    645 	if (error) {
    646 		aprint_error_dev(self, "Could not acquire iic bus: %d\n",
    647 		    error);
    648 		goto out;
    649 	}
    650 	error = si70xx_cmd1(sc, SI70XX_RESET, NULL, 0);
    651 	if (error != 0)
    652 		aprint_error_dev(self, "Reset failed: %d\n", error);
    653 
    654 	delay(15000);	/* 15 ms max */
    655 
    656 	error = si70xx_cmd2(sc, SI70XX_READ_ID_PT1A, SI70XX_READ_ID_PT1B,
    657 	    buf, 8);
    658 	if (error) {
    659 		aprint_error_dev(self, "Failed to read first part of ID: %d\n",
    660 		    error);
    661 		ecount++;
    662 	}
    663 	testcrcpt1[0] = buf[0];
    664 	testcrcpt1[1] = buf[2];
    665 	testcrcpt1[2] = buf[4];
    666 	testcrcpt1[3] = buf[6];
    667 	readcrc1 = buf[7];
    668 	crc1 = si70xx_crc(testcrcpt1, 4);
    669 	/* A "real" SI70xx has the CRC cover the entire first part of the
    670 	 * serial number.  An HTU21D has the CRC broken out into each
    671 	 * part of the serial number.
    672 	 */
    673 	validcrcpt1 = (readcrc1 == crc1);
    674 	if (! validcrcpt1) {
    675 		validcrcpt1 = (si70xx_crc(&testcrcpt1[0],1) == buf[1] &&
    676 		    si70xx_crc(&testcrcpt1[1],1) == buf[3] &&
    677 		    si70xx_crc(&testcrcpt1[2],1) == buf[5] &&
    678 		    si70xx_crc(&testcrcpt1[3],1) == buf[7]);
    679 		DPRINTF(sc, 2, ("%s: Part 1 SN CRC was not valid for real type, "
    680 		    "check clone: %d\n", device_xname(sc->sc_dev), validcrcpt1));
    681 	}
    682 
    683 	DPRINTF(sc, 2, ("%s: read 1 values: %02x%02x%02x%02x%02x%02x%02x%02x "
    684 	    "- %02x -- %d\n", device_xname(sc->sc_dev), buf[0], buf[1],
    685 	    buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
    686 	    crc1, validcrcpt1));
    687 
    688 	error = si70xx_cmd2(sc, SI70XX_READ_ID_PT2A, SI70XX_READ_ID_PT2B,
    689 	    buf, 8);
    690 	if (error != 0) {
    691 		aprint_error_dev(self, "Failed to read second part of ID: %d\n",
    692 		    error);
    693 		ecount++;
    694 	}
    695 	model = testcrcpt2[0] = buf[0];
    696 	testcrcpt2[1] = buf[1];
    697 	testcrcpt2[2] = buf[3];
    698 	testcrcpt2[3] = buf[4];
    699 	readcrc2 = buf[5];
    700 	crc2 = si70xx_crc(testcrcpt2, 4);
    701 	/* It is even stranger for this part of the serial number.  A "real"
    702 	 * SI70XX will have a single CRC for the entire second part, but
    703 	 * an HTU21D has a CRC for each word in this case.
    704 	 *
    705 	 * The datasheet actually agrees with the HTU21D case, and not the "real"
    706 	 * chip.
    707 	 */
    708 	validcrcpt2 = (readcrc2 == crc2);
    709 	if (! validcrcpt2) {
    710 		validcrcpt2 = (si70xx_crc(&testcrcpt2[0],2) == buf[2] &&
    711 		    si70xx_crc(&testcrcpt2[2],2) == buf[5]);
    712 		DPRINTF(sc, 2, ("%s: Part 2 SN CRC was not valid for real type, "
    713 		    "check clone: %d\n", device_xname(sc->sc_dev), validcrcpt2));
    714 	}
    715 
    716 	DPRINTF(sc, 2, ("%s: read 2 values: %02x%02x%02x%02x%02x%02x - %02x -- %d\n",
    717 	    device_xname(sc->sc_dev), buf[0], buf[1], buf[2],
    718 	    buf[3], buf[4], buf[5], crc2, validcrcpt2));
    719 
    720 	error = si70xx_cmd2(sc, SI70XX_READ_FW_VERA, SI70XX_READ_FW_VERB,
    721 	    buf, 8);
    722 
    723 	if (error) {
    724 		aprint_error_dev(self, "Failed to read firmware version: Error %d\n",
    725 		    error);
    726 		sc->sc_nofw = true;
    727 	}
    728 	if (! sc->sc_nofw) {
    729 		fwversion = buf[0];
    730 		DPRINTF(sc, 2, ("%s: read fw values: %#x\n", device_xname(sc->sc_dev),
    731 		    fwversion));
    732 	}
    733 
    734 	error = si70xx_cmd1(sc, SI70XX_READ_HEATER_REG, &heaterregister, 1);
    735 
    736 	if (error) {
    737 		aprint_error_dev(self, "Failed to read heater register: Error %d\n",
    738 		    error);
    739 		sc->sc_noheater = true;
    740 	}
    741 
    742 	error = si70xx_update_status(sc);
    743 
    744 	iic_release_bus(sc->sc_tag, 0);
    745 
    746 	if ((error = si70xx_sysctl_init(sc)) != 0) {
    747 		aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", error);
    748 		goto out;
    749 	}
    750 
    751 	if (error != 0) {
    752 		aprint_error_dev(self, "Failed to update status: %x\n", error);
    753 		aprint_error_dev(self, "Unable to setup device\n");
    754 		goto out;
    755 	}
    756 
    757 	for (i = 0; i < sc->sc_numsensors; i++) {
    758 		strlcpy(sc->sc_sensors[i].desc, si70xx_sensors[i].desc,
    759 		    sizeof(sc->sc_sensors[i].desc));
    760 
    761 		sc->sc_sensors[i].units = si70xx_sensors[i].type;
    762 		sc->sc_sensors[i].state = ENVSYS_SINVALID;
    763 
    764 		DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i,
    765 		    sc->sc_sensors[i].desc));
    766 
    767 		error = sysmon_envsys_sensor_attach(sc->sc_sme,
    768 		    &sc->sc_sensors[i]);
    769 		if (error) {
    770 			aprint_error_dev(self,
    771 			    "Unable to attach sensor %d: %d\n", i, error);
    772 			sc->sc_sme = NULL;
    773 			goto out;
    774 		}
    775 	}
    776 
    777 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
    778 	sc->sc_sme->sme_cookie = sc;
    779 	sc->sc_sme->sme_refresh = si70xx_refresh;
    780 
    781 	DPRINTF(sc, 2, ("si70xx_attach: registering with envsys\n"));
    782 
    783 	if (sysmon_envsys_register(sc->sc_sme)) {
    784 		aprint_error_dev(self,
    785 			"unable to register with sysmon\n");
    786 		sysmon_envsys_destroy(sc->sc_sme);
    787 		sc->sc_sme = NULL;
    788 		return;
    789 	}
    790 
    791 	char modelstr[64];
    792 	switch (model) {
    793 	case 0:
    794 	case 0xff:
    795 		snprintf(modelstr, sizeof(modelstr), "Engineering Sample");
    796 		break;
    797 	case 13:
    798 	case 20:
    799 	case 21:
    800 		snprintf(modelstr, sizeof(modelstr), "SI70%d", model);
    801 		break;
    802 	default:
    803 		snprintf(modelstr, sizeof(modelstr), "Unknown model %d (maybe an HTU21D)", model);
    804 		break;
    805 	}
    806 
    807 	const char *fwversionstr;
    808 	switch (fwversion) {
    809 	case 0xff:
    810 		fwversionstr = "1.0";
    811 		break;
    812 	case 0x20:
    813 		fwversionstr = "2.0";
    814 		break;
    815 	default:
    816 		fwversionstr = "unknown";
    817 		break;
    818 	}
    819 
    820 	aprint_normal_dev(self, "Silicon Labs Model: %s, "
    821 	    "Firmware version: %s, "
    822 	    "Serial number: %02x%02x%02x%02x%02x%02x%02x%02x%s",
    823 	    modelstr, fwversionstr, testcrcpt1[0], testcrcpt1[1],
    824 	    testcrcpt1[2], testcrcpt1[3], testcrcpt2[0], testcrcpt2[1],
    825 	    testcrcpt2[2], testcrcpt2[3],
    826 	    (validcrcpt1 && validcrcpt2) ? "\n" : " (bad crc)\n");
    827 	return;
    828 out:
    829 	sysmon_envsys_destroy(sc->sc_sme);
    830 	sc->sc_sme = NULL;
    831 }
    832 
    833 static int
    834 si70xx_exec(struct si70xx_sc *sc, uint8_t cmd, envsys_data_t *edata)
    835 {
    836 	int error;
    837 	int xdelay;
    838 	const char *name;
    839 	int64_t mul, offs;
    840 	uint8_t buf[3];
    841 
    842 	switch (cmd) {
    843 	case SI70XX_MEASURE_RH_NOHOLD:
    844 		/*
    845 		 * The published conversion for RH is: %RH =
    846 		 * ((125 * RHCODE) / 65536) - 6
    847 		 *
    848 		 * The sysmon infrastructure for RH wants %RH *
    849 		 * 10^6 The result will fit in 32 bits, but
    850 		 * the intermediate values will not.
    851 		 */
    852 		mul = 125000000;
    853 		offs = -6000000;
    854 		/*
    855 		 * Conversion times for %RH in ms
    856 		 *
    857 		 *        	Typical Max
    858 		 * 12-bit	10.0	12.0
    859 		 * 11-bit	 5.8	 7.0
    860 		 * 10-bit	 3.7	 4.5
    861 		 *  8-bit	 2.6	 3.1
    862 		 *
    863 		 * A call to read %RH will also read temperature.  The
    864 		 * conversion time will be the amount of time above
    865 		 * plus the amount of time for temperature below
    866 		 */
    867 		xdelay = 10500;
    868 		name = "RH";
    869 		break;
    870 	case SI70XX_MEASURE_TEMP_NOHOLD:
    871 		/*
    872 		 * The published conversion for temp is:
    873 		 * degree C = ((175.72 * TEMPCODE) / 65536) -
    874 		 * 46.85
    875 		 *
    876 		 * The sysmon infrastructure for temp wants
    877 		 * microkelvin.  This is simple, as degree C
    878 		 * converts directly with K with simple
    879 		 * addition. The result will fit in 32 bits,
    880 		 * but the intermediate values will not.
    881 		 */
    882 		mul = 175720000;
    883 		offs = 226300000;
    884 		/*
    885 		 * Conversion times for temperature in ms
    886 	 	 *
    887 		 *		Typical	Max
    888 		 * 14-bit	7.0	10.8
    889 		 * 13-bit	4.0	 6.2
    890 		 * 12-bit	2.4	 3.8
    891 		 * 11-bit	1.5	 2.4
    892 		 */
    893 		xdelay = 4750;
    894 		name = "TEMP";
    895 		break;
    896 	default:
    897 		return EINVAL;
    898 	}
    899 
    900 #if HAVE_I2C_EXECV
    901 	memset(buf, 0, sizeof(buf));
    902 	error = iic_execv(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
    903 	    &cmd, 1, buf, sizeof(buf), 0, I2C_ATTR_CLOCKSTRETCH,
    904 	    sc->sc_clockstretch, I2C_ATTR_EOL);
    905 #else
    906 	/*
    907 	 * The lower level driver must support the ability to
    908 	 * do a zero length read, otherwise this breaks
    909 	 */
    910 	error = si70xx_cmd1(sc, cmd, buf, 0);
    911 	if (error) {
    912 		DPRINTF(sc, 2, ("%s: Failed to read NO HOLD %s %d %d\n",
    913 		    device_xname(sc->sc_dev), name, 1, error));
    914 		return error;
    915 	}
    916 
    917 	/*
    918 	 * It will probably be at least this long... we would
    919 	 * not have to do this sort of thing if clock
    920 	 * stretching worked.  Even this is a problem for the
    921 	 * RPI without a patch to remove a [apparently] not
    922 	 * needed KASSERT()
    923 	 */
    924 	delay(xdelay);
    925 
    926 	for (int aint = 0; aint < sc->sc_readattempts; aint++) {
    927 		error = si70xx_cmd0(sc, buf, sizeof(buf));
    928 		if (error == 0)
    929 			break;
    930 		DPRINTF(sc, 2, ("%s: Failed to read NO HOLD RH"
    931 		    " %d %d\n", device_xname(sc->sc_dev), 2, error));
    932 		delay(1000);
    933 	}
    934 #endif
    935 
    936 	DPRINTF(sc, 2, ("%s: %s values: %02x%02x%02x - %02x\n",
    937 	    device_xname(sc->sc_dev), name, buf[0], buf[1], buf[2],
    938 	    si70xx_crc(buf, 2)));
    939 
    940 	uint8_t crc;
    941 	if (sc->sc_ignorecrc) {
    942 		crc = buf[2];
    943 	} else {
    944 		crc = si70xx_crc(buf, 2);
    945 	}
    946 
    947 	if (crc != buf[2]) {
    948 		DPRINTF(sc, 2, ("%s: Bad CRC for %s: %#x and %#x\n",
    949 		    device_xname(sc->sc_dev), name, crc, buf[2]));
    950 		return EINVAL;
    951 	}
    952 
    953 	uint16_t val16 = (buf[0] << 8) | buf[1];
    954 	uint64_t val64 = ((mul * val16) >> 16) + offs;
    955 	DPRINTF(sc, 2, ("%s: %s calculated values: %x %#jx\n",
    956 	    device_xname(sc->sc_dev), name, val16, (uintmax_t)val64));
    957 	edata->value_cur = (uint32_t) val64;
    958 	edata->state = ENVSYS_SVALID;
    959 	return 0;
    960 }
    961 
    962 static void
    963 si70xx_refresh(struct sysmon_envsys * sme, envsys_data_t * edata)
    964 {
    965 	struct si70xx_sc *sc;
    966 	int 		error;
    967 
    968 	sc = sme->sme_cookie;
    969 	edata->state = ENVSYS_SINVALID;
    970 
    971 	mutex_enter(&sc->sc_mutex);
    972 	error = iic_acquire_bus(sc->sc_tag, 0);
    973 	if (error) {
    974 		DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
    975 		    device_xname(sc->sc_dev), error));
    976 		goto out;
    977 	}
    978 	error = si70xx_update_status(sc);
    979 	if (error) {
    980 		DPRINTF(sc, 2, ("%s: Failed to update status in refresh %d\n",
    981 		    device_xname(sc->sc_dev), error));
    982 		goto out1;
    983 	}
    984 	switch (edata->sensor) {
    985 	case SI70XX_HUMIDITY_SENSOR:
    986 		error = si70xx_exec(sc, SI70XX_MEASURE_RH_NOHOLD, edata);
    987 		break;
    988 
    989 	case SI70XX_TEMP_SENSOR:
    990 		error = si70xx_exec(sc, SI70XX_MEASURE_TEMP_NOHOLD, edata);
    991 		break;
    992 	default:
    993 		error = EINVAL;
    994 		break;
    995 	}
    996 
    997 	if (error) {
    998 		DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d\n",
    999 		    device_xname(sc->sc_dev), error));
   1000 	}
   1001 out1:
   1002 	iic_release_bus(sc->sc_tag, 0);
   1003 out:
   1004 	mutex_exit(&sc->sc_mutex);
   1005 }
   1006 
   1007 static int
   1008 si70xx_detach(device_t self, int flags)
   1009 {
   1010 	struct si70xx_sc *sc;
   1011 
   1012 	sc = device_private(self);
   1013 
   1014 	mutex_enter(&sc->sc_mutex);
   1015 
   1016 	/* Remove the sensors */
   1017 	if (sc->sc_sme != NULL)
   1018 		sysmon_envsys_unregister(sc->sc_sme);
   1019 	mutex_exit(&sc->sc_mutex);
   1020 
   1021 	/* Remove the sysctl tree */
   1022 	sysctl_teardown(&sc->sc_si70xxlog);
   1023 
   1024 	/* Remove the mutex */
   1025 	mutex_destroy(&sc->sc_mutex);
   1026 
   1027 	return 0;
   1028 }
   1029 
   1030 MODULE(MODULE_CLASS_DRIVER, si70xxtemp, "i2cexec,sysmon_envsys");
   1031 
   1032 #ifdef _MODULE
   1033 #include "ioconf.c"
   1034 #endif
   1035 
   1036 static int
   1037 si70xxtemp_modcmd(modcmd_t cmd, void *opaque)
   1038 {
   1039 
   1040 	switch (cmd) {
   1041 	case MODULE_CMD_INIT:
   1042 #ifdef _MODULE
   1043 		return config_init_component(cfdriver_ioconf_si70xxtemp,
   1044 		    cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp);
   1045 #else
   1046 		return 0;
   1047 #endif
   1048 	case MODULE_CMD_FINI:
   1049 #ifdef _MODULE
   1050 		return config_fini_component(cfdriver_ioconf_si70xxtemp,
   1051 		      cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp);
   1052 #else
   1053 		return 0;
   1054 #endif
   1055 	default:
   1056 		return ENOTTY;
   1057 	}
   1058 }
   1059