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