Home | History | Annotate | Line # | Download | only in i2c
si70xx.c revision 1.3
      1 /*	$NetBSD: si70xx.c,v 1.3 2017/12/30 03:18:26 christos 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.3 2017/12/30 03:18:26 christos Exp $");
     21 
     22 /*
     23   Driver for the Silicon Labs SI7013/SI7020/SI7021
     24 */
     25 
     26 #include <sys/param.h>
     27 #include <sys/systm.h>
     28 #include <sys/kernel.h>
     29 #include <sys/device.h>
     30 #include <sys/module.h>
     31 #include <sys/sysctl.h>
     32 #include <sys/mutex.h>
     33 
     34 #include <dev/sysmon/sysmonvar.h>
     35 #include <dev/i2c/i2cvar.h>
     36 #include <dev/i2c/si70xxreg.h>
     37 #include <dev/i2c/si70xxvar.h>
     38 
     39 
     40 static uint8_t 	si70xx_crc(uint8_t *, size_t);
     41 static int 	si70xx_poke(i2c_tag_t, i2c_addr_t, bool);
     42 static int 	si70xx_match(device_t, cfdata_t, void *);
     43 static void 	si70xx_attach(device_t, device_t, void *);
     44 static int 	si70xx_detach(device_t, int);
     45 static void 	si70xx_refresh(struct sysmon_envsys *, envsys_data_t *);
     46 static int 	si70xx_update_status(struct si70xx_sc *);
     47 static int 	si70xx_set_heateron(struct si70xx_sc *);
     48 static int 	si70xx_set_resolution(struct si70xx_sc *, size_t);
     49 static int 	si70xx_set_heatervalue(struct si70xx_sc *, size_t);
     50 static int 	si70xx_verify_sysctl(SYSCTLFN_ARGS);
     51 static int 	si70xx_verify_sysctl_resolution(SYSCTLFN_ARGS);
     52 static int 	si70xx_verify_sysctl_heateron(SYSCTLFN_ARGS);
     53 static int 	si70xx_verify_sysctl_heatervalue(SYSCTLFN_ARGS);
     54 
     55 #define SI70XX_DEBUG
     56 #ifdef SI70XX_DEBUG
     57 #define DPRINTF(s, l, x) \
     58     do { \
     59 	if (l <= s->sc_si70xxdebug) \
     60 	    printf x; \
     61     } while (/*CONSTCOND*/0)
     62 #else
     63 #define DPRINTF(s, l, x)
     64 #endif
     65 
     66 CFATTACH_DECL_NEW(si70xxtemp, sizeof(struct si70xx_sc),
     67     si70xx_match, si70xx_attach, si70xx_detach, NULL);
     68 
     69 static struct si70xx_sensor si70xx_sensors[] = {
     70 	{
     71 		.desc = "humidity",
     72 		.type = ENVSYS_SRELHUMIDITY,
     73 	},
     74 	{
     75 		.desc = "temperature",
     76 		.type = ENVSYS_STEMP,
     77 	}
     78 };
     79 
     80 static struct si70xx_resolution si70xx_resolutions[] = {
     81 	{
     82 		.text = "12bit/14bit",
     83 		.num = 0x00,
     84 	},
     85 	{
     86 		.text = "8bit/12bit",
     87 		.num = 0x01,
     88 	},
     89 	{
     90 		.text = "10bit/13bit",
     91 		.num = 0x80,
     92 	},
     93 	{
     94 		.text = "11bit/11bit",
     95 		.num = 0x81,
     96 	}
     97 };
     98 
     99 static const char si70xx_resolution_names[] =
    100     "12bit/14bit, 8bit/12bit, 10bit/13bit, 11bit/11bit";
    101 
    102 static const int si70xx_heatervalues[] = {
    103     0xdeadbeef, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0f
    104 };
    105 
    106 int
    107 si70xx_verify_sysctl(SYSCTLFN_ARGS)
    108 {
    109 	int error, t;
    110 	struct sysctlnode node;
    111 
    112 	node = *rnode;
    113 	t = *(int *)rnode->sysctl_data;
    114 	node.sysctl_data = &t;
    115 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    116 	if (error || newp == NULL)
    117 		return error;
    118 
    119 	if (t < 0)
    120 		return EINVAL;
    121 
    122 	*(int *)rnode->sysctl_data = t;
    123 
    124 	return 0;
    125 }
    126 
    127 int
    128 si70xx_verify_sysctl_resolution(SYSCTLFN_ARGS)
    129 {
    130 	char buf[SI70XX_RES_NAME];
    131 	struct si70xx_sc *sc;
    132 	struct sysctlnode node;
    133 	int error = 0;
    134 	size_t i;
    135 
    136 	node = *rnode;
    137 	sc = node.sysctl_data;
    138 	(void) memcpy(buf, sc->sc_resolution, SI70XX_RES_NAME);
    139 	node.sysctl_data = buf;
    140 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    141 	if (error || newp == NULL)
    142 		return error;
    143 
    144 	for (i = 0; i < __arraycount(si70xx_resolutions); i++) {
    145 		if (memcmp(node.sysctl_data, si70xx_resolutions[i].text,
    146 		    SI70XX_RES_NAME) == 0)
    147 			break;
    148 	}
    149 
    150 	if (i == __arraycount(si70xx_resolutions))
    151 		return EINVAL;
    152 	(void) memcpy(sc->sc_resolution, node.sysctl_data, SI70XX_RES_NAME);
    153 
    154 	error = si70xx_set_resolution(sc, i);
    155 
    156 	return error;
    157 }
    158 
    159 int
    160 si70xx_verify_sysctl_heateron(SYSCTLFN_ARGS)
    161 {
    162 	int 		error;
    163 	bool 		t;
    164 	struct si70xx_sc *sc;
    165 	struct sysctlnode node;
    166 
    167 	node = *rnode;
    168 	sc = node.sysctl_data;
    169 	t = sc->sc_heateron;
    170 	node.sysctl_data = &t;
    171 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    172 	if (error || newp == NULL)
    173 		return error;
    174 
    175 	sc->sc_heateron = t;
    176 	error = si70xx_set_heateron(sc);
    177 
    178 	return error;
    179 }
    180 
    181 int
    182 si70xx_verify_sysctl_heatervalue(SYSCTLFN_ARGS)
    183 {
    184 	int 		error = 0, t;
    185 	struct si70xx_sc *sc;
    186 	struct sysctlnode node;
    187 
    188 	node = *rnode;
    189 	sc = node.sysctl_data;
    190 	t = sc->sc_heaterval;
    191 	node.sysctl_data = &t;
    192 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    193 	if (error || newp == NULL)
    194 		return (error);
    195 
    196 	if (t < 1 || t >= __arraycount(si70xx_heatervalues))
    197 		return (EINVAL);
    198 
    199 	sc->sc_heaterval = t;
    200 	error = si70xx_set_heatervalue(sc, t);
    201 
    202 	return error;
    203 }
    204 
    205 static uint8_t
    206 si70xx_dir(uint8_t cmd, size_t len)
    207 {
    208 	switch (cmd) {
    209 	case SI70XX_READ_USER_REG_1:
    210 	case SI70XX_READ_HEATER_REG:
    211 	case SI70XX_READ_ID_PT1A:
    212 	case SI70XX_READ_ID_PT1B:
    213 	case SI70XX_READ_ID_PT2A:
    214 	case SI70XX_READ_ID_PT2B:
    215 	case SI70XX_READ_FW_VERA:
    216 	case SI70XX_READ_FW_VERB:
    217 		return I2C_OP_READ_WITH_STOP;
    218 	case SI70XX_WRITE_USER_REG_1:
    219 	case SI70XX_WRITE_HEATER_REG:
    220 	case SI70XX_RESET:
    221 		return I2C_OP_WRITE_WITH_STOP;
    222 	case SI70XX_MEASURE_RH_NOHOLD:
    223 	case SI70XX_MEASURE_TEMP_NOHOLD:
    224 		return len == 0 ? I2C_OP_READ : I2C_OP_READ_WITH_STOP;
    225 	default:
    226 		panic("%s: bad command %#x\n", __func__, cmd);
    227 		return 0;
    228 	}
    229 }
    230 
    231 static int
    232 si70xx_cmd(i2c_tag_t tag, i2c_addr_t addr, uint8_t *cmd,
    233     uint8_t clen, uint8_t *buf, size_t blen)
    234 {
    235 	uint8_t dir;
    236 	if (clen == 0)
    237 		dir = blen == 0 ? I2C_OP_READ : I2C_OP_READ_WITH_STOP;
    238 	else
    239 		dir = si70xx_dir(cmd[0], blen);
    240 
    241 	if (dir == I2C_OP_READ || dir == I2C_OP_READ_WITH_STOP)
    242 		memset(buf, 0, blen);
    243 
    244 	return iic_exec(tag, dir, addr, cmd, clen, buf, blen, 0);
    245 }
    246 
    247 static int
    248 si70xx_cmd0(struct si70xx_sc *sc, uint8_t *buf, size_t blen)
    249 {
    250 	return si70xx_cmd(sc->sc_tag, sc->sc_addr, NULL, 0, buf, blen);
    251 }
    252 
    253 static int
    254 si70xx_cmd1(struct si70xx_sc *sc, uint8_t cmd, uint8_t *buf, size_t blen)
    255 {
    256 	return si70xx_cmd(sc->sc_tag, sc->sc_addr, &cmd, 1, buf, blen);
    257 }
    258 
    259 static int
    260 si70xx_cmd2(struct si70xx_sc *sc, uint8_t cmd1, uint8_t cmd2, uint8_t *buf,
    261     size_t blen)
    262 {
    263 	uint8_t cmd[] = { cmd1, cmd2 };
    264 	return si70xx_cmd(sc->sc_tag, sc->sc_addr, cmd, __arraycount(cmd),
    265 	    buf, blen);
    266 }
    267 
    268 static int
    269 si70xx_set_heateron(struct si70xx_sc * sc)
    270 {
    271 	int error;
    272 	uint8_t userregister;
    273 
    274 	error = iic_acquire_bus(sc->sc_tag, 0);
    275 	if (error) {
    276 		DPRINTF(sc, 2, ("%s:%s: Failed to acquire bus: %d\n",
    277 		    device_xname(sc->sc_dev), __func__, error));
    278 		return error;
    279 	}
    280 
    281 	error = si70xx_cmd1(sc, SI70XX_READ_USER_REG_1, &userregister, 1);
    282 	if (error) {
    283 		DPRINTF(sc, 2, ("%s: Failed to read user register 1: %d\n",
    284 		    device_xname(sc->sc_dev), error));
    285 		goto out;
    286 	}
    287 
    288 	DPRINTF(sc, 2, ("%s:%s: reg 1 values before: %#x\n",
    289 	    device_xname(sc->sc_dev), __func__, userregister));
    290 	if (sc->sc_heateron) {
    291 		userregister |= SI70XX_HTRE_MASK;
    292 	} else {
    293 		userregister &= ~SI70XX_HTRE_MASK;
    294 	}
    295 	DPRINTF(sc, 2, ("%s:%s: user reg 1 values after: %#x\n",
    296 	    device_xname(sc->sc_dev), __func__, userregister));
    297 
    298 	error = si70xx_cmd1(sc, SI70XX_WRITE_USER_REG_1, &userregister, 1);
    299 	if (error) {
    300 		DPRINTF(sc, 2, ("%s: Failed to write user register 1: %d\n",
    301 		    device_xname(sc->sc_dev), error));
    302 	}
    303 out:
    304 	iic_release_bus(sc->sc_tag, 0);
    305 	return error;
    306 }
    307 
    308 static int
    309 si70xx_set_resolution(struct si70xx_sc * sc, size_t index)
    310 {
    311 	int error;
    312 	uint8_t userregister;
    313 
    314 	error = iic_acquire_bus(sc->sc_tag, 0);
    315 	if (error) {
    316 		DPRINTF(sc, 2, ("%s: Failed to acquire bus: %d\n",
    317 		    device_xname(sc->sc_dev), error));
    318 		return error;
    319 	}
    320 
    321 	error = si70xx_cmd1(sc, SI70XX_READ_USER_REG_1, &userregister, 1);
    322 	if (error) {
    323 		DPRINTF(sc, 2, ("%s: Failed to read user register 1: %d\n",
    324 		    device_xname(sc->sc_dev), error));
    325 		goto out;
    326 	}
    327 
    328 	DPRINTF(sc, 2, ("%s:%s: reg 1 values before: %#x\n",
    329 	    device_xname(sc->sc_dev), __func__, userregister));
    330 	userregister &= (~SI70XX_RESOLUTION_MASK);
    331 	userregister |= si70xx_resolutions[index].num;
    332 	DPRINTF(sc, 2, ("%s:%s: reg 1 values after: %#x\n",
    333 	    device_xname(sc->sc_dev), __func__, userregister));
    334 
    335 	error = si70xx_cmd1(sc, SI70XX_WRITE_USER_REG_1, &userregister, 1);
    336 	if (error) {
    337 		DPRINTF(sc, 2, ("%s: Failed to write user register 1: %d\n",
    338 		    device_xname(sc->sc_dev), error));
    339 	}
    340 out:
    341 	iic_release_bus(sc->sc_tag, 0);
    342 	return error;
    343 }
    344 
    345 static int
    346 si70xx_set_heatervalue(struct si70xx_sc * sc, size_t index)
    347 {
    348 	int error;
    349 	uint8_t heaterregister;
    350 
    351 	error = iic_acquire_bus(sc->sc_tag, 0);
    352 	if (error) {
    353 		DPRINTF(sc, 2, ("%s: Failed to acquire bus: %d\n",
    354 		    device_xname(sc->sc_dev), error));
    355 		return error;
    356 	}
    357 	error = si70xx_cmd1(sc, SI70XX_READ_HEATER_REG, &heaterregister, 1);
    358 	if (error) {
    359 		DPRINTF(sc, 2, ("%s: Failed to read heater register: %d\n",
    360 		    device_xname(sc->sc_dev), error));
    361 		goto out;
    362 	}
    363 
    364 	DPRINTF(sc, 2, ("%s:%s: heater values before: %#x\n",
    365 	    device_xname(sc->sc_dev), __func__, heaterregister));
    366 	heaterregister &= ~SI70XX_HEATER_MASK;
    367 	heaterregister |= si70xx_heatervalues[index];
    368 	DPRINTF(sc, 2, ("%s:%s: heater values after: %#x\n",
    369 	    device_xname(sc->sc_dev), __func__, heaterregister));
    370 
    371 	error = si70xx_cmd1(sc, SI70XX_WRITE_HEATER_REG, &heaterregister, 1);
    372 	if (error) {
    373 		DPRINTF(sc, 2, ("%s: Failed to write heater register: %d\n",
    374 		    device_xname(sc->sc_dev), error));
    375 	}
    376 out:
    377 	iic_release_bus(sc->sc_tag, 0);
    378 	return error;
    379 }
    380 
    381 static int
    382 si70xx_update_heater(struct si70xx_sc *sc)
    383 {
    384 	size_t i;
    385 	int error;
    386 	uint8_t heaterregister;
    387 
    388 	error = si70xx_cmd1(sc, SI70XX_READ_HEATER_REG, &heaterregister, 1);
    389 	if (error) {
    390 		DPRINTF(sc, 2, ("%s: Failed to read heater register: %d\n",
    391 		    device_xname(sc->sc_dev), error));
    392 		return error;
    393 	}
    394 
    395 	DPRINTF(sc, 2, ("%s: read heater reg values: %02x\n",
    396 	    device_xname(sc->sc_dev), heaterregister));
    397 
    398 	uint8_t heat = heaterregister & SI70XX_HEATER_MASK;
    399 	for (i = 0; i < __arraycount(si70xx_heatervalues); i++) {
    400 		if (si70xx_heatervalues[i] == heat)
    401 			break;
    402 	}
    403 	sc->sc_heaterval = i != __arraycount(si70xx_heatervalues) ? i : 0;
    404 	return 0;
    405 }
    406 
    407 static int
    408 si70xx_update_user(struct si70xx_sc *sc)
    409 {
    410 	size_t i;
    411 	int error;
    412 	uint8_t userregister;
    413 
    414 	error = si70xx_cmd1(sc, SI70XX_READ_USER_REG_1, &userregister, 1);
    415 	if (error) {
    416 		DPRINTF(sc, 2, ("%s: Failed to read user register 1: %d\n",
    417 		    device_xname(sc->sc_dev), error));
    418 		return error;
    419 	}
    420 	DPRINTF(sc, 2, ("%s: read user reg 1 values: %#x\n",
    421 	    device_xname(sc->sc_dev), userregister));
    422 
    423 	uint8_t res = userregister & SI70XX_RESOLUTION_MASK;
    424 	for (i = 0; i < __arraycount(si70xx_resolutions); i++) {
    425 		if (si70xx_resolutions[i].num == res)
    426 			break;
    427 	}
    428 
    429 	if (i != __arraycount(si70xx_resolutions)) {
    430 		memcpy(sc->sc_resolution, si70xx_resolutions[i].text,
    431 		    SI70XX_RES_NAME);
    432 	} else {
    433 		snprintf(sc->sc_resolution, SI70XX_RES_NAME, "%02x", res);
    434 	}
    435 
    436 	sc->sc_vddok = (userregister & SI70XX_VDDS_MASK) == 0;
    437 	sc->sc_heaterval = userregister & SI70XX_HTRE_MASK;
    438 	return 0;
    439 }
    440 
    441 static int
    442 si70xx_update_status(struct si70xx_sc *sc)
    443 {
    444 	int error1 = si70xx_update_user(sc);
    445 	int error2 = si70xx_update_heater(sc);
    446 	return error1 ? error1 : error2;
    447 }
    448 
    449 static	uint8_t
    450 si70xx_crc(uint8_t * data, size_t size)
    451 {
    452 	uint8_t crc = 0;
    453 
    454 	for (size_t i = 0; i < size; i++) {
    455 		crc ^= data[i];
    456 		for (size_t j = 8; j > 0; j--) {
    457 			if (crc & 0x80)
    458 				crc = (crc << 1) ^ 0x131;
    459 			else
    460 				crc <<= 1;
    461 		}
    462 	}
    463 	return crc;
    464 }
    465 
    466 static int
    467 si70xx_poke(i2c_tag_t tag, i2c_addr_t addr, bool matchdebug)
    468 {
    469 	uint8_t reg = SI70XX_READ_USER_REG_1;
    470 	uint8_t buf;
    471 	int error;
    472 
    473 	error = si70xx_cmd(tag, addr, &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;
    567 	int error;
    568 	const bool matchdebug = false;
    569 
    570 	ia = aux;
    571 
    572 	if (ia->ia_name) {
    573 		/* direct config - check name */
    574 		if (strcmp(ia->ia_name, "si70xxtemp") != 0)
    575 			return 0;
    576 	} else {
    577 		/* indirect config - check for configured address */
    578 		if (ia->ia_addr != SI70XX_TYPICAL_ADDR)
    579 			return 0;
    580 	}
    581 
    582 	/*
    583 	 * Check to see if something is really at this i2c address. This will
    584 	 * keep phantom devices from appearing
    585 	 */
    586 	if (iic_acquire_bus(ia->ia_tag, 0) != 0) {
    587 		if (matchdebug)
    588 			printf("in match acquire bus failed\n");
    589 		return 0;
    590 	}
    591 
    592 	error = si70xx_poke(ia->ia_tag, ia->ia_addr, matchdebug);
    593 	iic_release_bus(ia->ia_tag, 0);
    594 
    595 	return error == 0;
    596 }
    597 
    598 static void
    599 si70xx_attach(device_t parent, device_t self, void *aux)
    600 {
    601 	struct si70xx_sc *sc;
    602 	struct i2c_attach_args *ia;
    603 	int error, i;
    604 	int ecount = 0;
    605 	uint8_t buf[8];
    606 	uint8_t testcrcpt1[4];
    607 	uint8_t testcrcpt2[4];
    608 	uint8_t crc1 = 0, crc2 = 0;
    609 	uint8_t readcrc1 = 0, readcrc2 = 0;
    610 	uint8_t fwversion, model;
    611 
    612 	ia = aux;
    613 	sc = device_private(self);
    614 
    615 	sc->sc_dev = self;
    616 	sc->sc_tag = ia->ia_tag;
    617 	sc->sc_addr = ia->ia_addr;
    618 	sc->sc_si70xxdebug = 0;
    619 #ifdef HAVE_I2C_EXECV
    620 	sc->sc_clockstretch = 2048;
    621 #endif
    622 	sc->sc_readattempts = 25;
    623 	sc->sc_ignorecrc = false;
    624 	sc->sc_sme = NULL;
    625 
    626 	aprint_normal("\n");
    627 
    628 	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE);
    629 	sc->sc_numsensors = __arraycount(si70xx_sensors);
    630 
    631 	if ((sc->sc_sme = sysmon_envsys_create()) == NULL) {
    632 		aprint_error_dev(self,
    633 		    "Unable to create sysmon structure\n");
    634 		sc->sc_sme = NULL;
    635 		return;
    636 	}
    637 	if ((error = si70xx_sysctl_init(sc)) != 0) {
    638 		aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", error);
    639 		goto out;
    640 	}
    641 
    642 	error = iic_acquire_bus(sc->sc_tag, 0);
    643 	if (error) {
    644 		aprint_error_dev(self, "Could not acquire iic bus: %d\n",
    645 		    error);
    646 		goto out;
    647 	}
    648 	error = si70xx_cmd1(sc, SI70XX_RESET, NULL, 0);
    649 	if (error != 0)
    650 		aprint_error_dev(self, "Reset failed: %d\n", error);
    651 
    652 	delay(15000);	/* 15 ms max */
    653 
    654 	error = si70xx_cmd2(sc, SI70XX_READ_ID_PT1A, SI70XX_READ_ID_PT1B,
    655 	    buf, 8);
    656 	if (error) {
    657 		aprint_error_dev(self, "Failed to read first part of ID: %d\n",
    658 		    error);
    659 		ecount++;
    660 	}
    661 	testcrcpt1[0] = buf[0];
    662 	testcrcpt1[1] = buf[2];
    663 	testcrcpt1[2] = buf[4];
    664 	testcrcpt1[3] = buf[6];
    665 	readcrc1 = buf[7];
    666 	crc1 = si70xx_crc(testcrcpt1, 4);
    667 
    668 	DPRINTF(sc, 2, ("%s: read 1 values: %02x%02x%02x%02x%02x%02x%02x%02x "
    669 	    "- %02x\n", device_xname(sc->sc_dev), buf[0], buf[1],
    670 	    buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
    671 	    crc1));
    672 
    673 	error = si70xx_cmd2(sc, SI70XX_READ_ID_PT2A, SI70XX_READ_ID_PT2B,
    674 	    buf, 8);
    675 	if (error != 0) {
    676 		aprint_error_dev(self, "Failed to read second part of ID: %d\n",
    677 		    error);
    678 		ecount++;
    679 	}
    680 	model = testcrcpt2[0] = buf[0];
    681 	testcrcpt2[1] = buf[1];
    682 	testcrcpt2[2] = buf[3];
    683 	testcrcpt2[3] = buf[4];
    684 	readcrc2 = buf[5];
    685 	crc2 = si70xx_crc(testcrcpt2, 4);
    686 
    687 	DPRINTF(sc, 2, ("%s: read 2 values: %02x%02x%02x%02x%02x%02x - %02x\n",
    688 	    device_xname(sc->sc_dev), buf[0], buf[1], buf[2],
    689 	    buf[3], buf[4], buf[5], crc2));
    690 
    691 	error = si70xx_cmd2(sc, SI70XX_READ_FW_VERA, SI70XX_READ_FW_VERB,
    692 	    buf, 8);
    693 
    694 	if (error) {
    695 		aprint_error_dev(self, "Failed to read firware version: %d\n",
    696 		    error);
    697 		ecount++;
    698 	}
    699 	fwversion = buf[0];
    700 	DPRINTF(sc, 2, ("%s: read fw values: %#x\n", device_xname(sc->sc_dev),
    701 	    fwversion));
    702 
    703 	error = si70xx_update_status(sc);
    704 	iic_release_bus(sc->sc_tag, 0);
    705 	if (error != 0) {
    706 		aprint_error_dev(self, "Failed to update status: %x\n", error);
    707 		aprint_error_dev(self, "Unable to setup device\n");
    708 		goto out;
    709 	}
    710 
    711 	for (i = 0; i < sc->sc_numsensors; i++) {
    712 		strlcpy(sc->sc_sensors[i].desc, si70xx_sensors[i].desc,
    713 		    sizeof(sc->sc_sensors[i].desc));
    714 
    715 		sc->sc_sensors[i].units = si70xx_sensors[i].type;
    716 		sc->sc_sensors[i].state = ENVSYS_SINVALID;
    717 
    718 		DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i,
    719 		    sc->sc_sensors[i].desc));
    720 
    721 		error = sysmon_envsys_sensor_attach(sc->sc_sme,
    722 		    &sc->sc_sensors[i]);
    723 		if (error) {
    724 			aprint_error_dev(self,
    725 			    "Unable to attach sensor %d: %d\n", i, error);
    726 			goto out;
    727 		}
    728 	}
    729 
    730 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
    731 	sc->sc_sme->sme_cookie = sc;
    732 	sc->sc_sme->sme_refresh = si70xx_refresh;
    733 
    734 	DPRINTF(sc, 2, ("si70xx_attach: registering with envsys\n"));
    735 
    736 	if (sysmon_envsys_register(sc->sc_sme)) {
    737 		aprint_error_dev(self,
    738 			"unable to register with sysmon\n");
    739 		sysmon_envsys_destroy(sc->sc_sme);
    740 		sc->sc_sme = NULL;
    741 		return;
    742 	}
    743 	if (ecount != 0) {
    744 		aprint_normal_dev(self, "Could not read model, "
    745 		    "probably an HTU21D\n");
    746 		return;
    747 	}
    748 
    749 	char modelstr[64];
    750 	switch (model) {
    751 	case 0:
    752 	case 0xff:
    753 		snprintf(modelstr, sizeof(modelstr), "Engineering Sample");
    754 	case 13:
    755 	case 20:
    756 	case 21:
    757 		snprintf(modelstr, sizeof(modelstr), "SI70%d", model);
    758 		break;
    759 	default:
    760 		snprintf(modelstr, sizeof(modelstr), "Unknown SI70%d", model);
    761 		break;
    762 	}
    763 
    764 	const char *fwversionstr;
    765 	switch (fwversion) {
    766 	case 0xff:
    767 		fwversionstr = "1.0";
    768 		break;
    769 	case 0x20:
    770 		fwversionstr = "2.0";
    771 		break;
    772 	default:
    773 		fwversionstr = "unknown";
    774 		break;
    775 	}
    776 
    777 	aprint_normal_dev(self, "Silicon Labs Model: %s, "
    778 	    "Firmware version: %s, "
    779 	    "Serial number: %02x%02x%02x%02x%02x%02x%02x%02x%s",
    780 	    modelstr, fwversionstr, testcrcpt1[0], testcrcpt1[1],
    781 	    testcrcpt1[2], testcrcpt1[3], testcrcpt2[0], testcrcpt2[1],
    782 	    testcrcpt2[2], testcrcpt2[3],
    783 	    (crc1 == readcrc1 && crc2 == readcrc2) ? "\n" : " (bad crc)\n");
    784 	return;
    785 out:
    786 	sysmon_envsys_destroy(sc->sc_sme);
    787 	sc->sc_sme = NULL;
    788 }
    789 
    790 static int
    791 si70xx_exec(struct si70xx_sc *sc, uint8_t cmd, envsys_data_t *edata)
    792 {
    793 	int error;
    794 	int xdelay;
    795 	const char *name;
    796 	int64_t mul, offs;
    797 	uint8_t buf[3];
    798 
    799 	switch (cmd) {
    800 	case SI70XX_MEASURE_RH_NOHOLD:
    801 		/*
    802 		 * The published conversion for RH is: %RH =
    803 		 * ((125 * RHCODE) / 65536) - 6
    804 		 *
    805 		 * The sysmon infrastructure for RH wants %RH *
    806 		 * 10^6 The result will fit in 32 bits, but
    807 		 * the intermediate values will not.
    808 		 */
    809 		mul = 125000000;
    810 		offs = -6000000;
    811 		/*
    812 		 * Conversion times for %RH in ms
    813 		 *
    814 		 *        	Typical Max
    815 		 * 12-bit	10.0	12.0
    816 		 * 11-bit	 5.8	 7.0
    817 		 * 10-bit	 3.7	 4.5
    818 		 *  8-bit	 2.6	 3.1
    819 		 *
    820 		 * A call to read %RH will also read temperature.  The
    821 		 * conversion time will be the amount of time above
    822 		 * plus the amount of time for temperature below
    823 		 */
    824 		xdelay = 10500;
    825 		name = "RH";
    826 		break;
    827 	case SI70XX_MEASURE_TEMP_NOHOLD:
    828 		/*
    829 		 * The published conversion for temp is:
    830 		 * degree C = ((175.72 * TEMPCODE) / 65536) -
    831 		 * 46.85
    832 		 *
    833 		 * The sysmon infrastructure for temp wants
    834 		 * microkelvin.  This is simple, as degree C
    835 		 * converts directly with K with simple
    836 		 * addition. The result will fit in 32 bits,
    837 		 * but the intermediate values will not.
    838 		 */
    839 		mul = 175720000;
    840 		offs = 226300000;
    841 		/*
    842 		 * Conversion times for temperature in ms
    843 	 	 *
    844 		 *		Typical	Max
    845 		 * 14-bit	7.0	10.8
    846 		 * 13-bit	4.0	 6.2
    847 		 * 12-bit	2.4	 3.8
    848 		 * 11-bit	1.5	 2.4
    849 		 */
    850 		xdelay = 4750;
    851 		name = "TEMP";
    852 		break;
    853 	default:
    854 		return EINVAL;
    855 	}
    856 
    857 #if HAVE_I2C_EXECV
    858 	memset(buf, 0, sizeof(buf));
    859 	error = iic_execv(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
    860 	    &cmd, 1, buf, sizeof(buf), 0, I2C_ATTR_CLOCKSTRETCH,
    861 	    sc->sc_clockstretch, I2C_ATTR_EOL);
    862 #else
    863 	/*
    864 	 * The lower level driver must support the ability to
    865 	 * do a zero length read, otherwise this breaks
    866 	 */
    867 	error = si70xx_cmd1(sc, cmd, buf, 0);
    868 	if (error) {
    869 		DPRINTF(sc, 2, ("%s: Failed to read NO HOLD %s %d %d\n",
    870 		    device_xname(sc->sc_dev), name, 1, error));
    871 		return error;
    872 	}
    873 
    874 	/*
    875 	 * It will probably be at least this long... we would
    876 	 * not have to do this sort of thing if clock
    877 	 * stretching worked.  Even this is a problem for the
    878 	 * RPI without a patch to remove a [apparently] not
    879 	 * needed KASSERT()
    880 	 */
    881 	delay(xdelay);
    882 
    883 	for (int aint = 0; aint < sc->sc_readattempts; aint++) {
    884 		error = si70xx_cmd0(sc, buf, sizeof(buf));
    885 		if (error == 0)
    886 			break;
    887 		DPRINTF(sc, 2, ("%s: Failed to read NO HOLD RH"
    888 		    " %d %d\n", device_xname(sc->sc_dev), 2, error));
    889 		delay(1000);
    890 	}
    891 #endif
    892 
    893 	DPRINTF(sc, 2, ("%s: %s values: %02x%02x%02x - %02x\n",
    894 	    device_xname(sc->sc_dev), name, buf[0], buf[1], buf[2],
    895 	    si70xx_crc(buf, 2)));
    896 
    897 	uint8_t crc;
    898 	if (sc->sc_ignorecrc) {
    899 		crc = buf[2];
    900 	} else {
    901 		crc = si70xx_crc(buf, 2);
    902 	}
    903 
    904 	if (crc != buf[2]) {
    905 		DPRINTF(sc, 2, ("%s: Bad CRC for %s: %#x and %#x\n",
    906 		    device_xname(sc->sc_dev), name, crc, buf[2]));
    907 		return EINVAL;
    908 	}
    909 
    910 	uint16_t val16 = (buf[0] << 8) | buf[1];
    911 	uint64_t val64 = ((mul * val16) >> 16) + offs;
    912 	DPRINTF(sc, 2, ("%s: %s calculated values: %x %#jx\n",
    913 	    device_xname(sc->sc_dev), name, val16, (uintmax_t)val64));
    914 	edata->value_cur = (uint32_t) val64;
    915 	edata->state = ENVSYS_SVALID;
    916 	return 0;
    917 }
    918 
    919 static void
    920 si70xx_refresh(struct sysmon_envsys * sme, envsys_data_t * edata)
    921 {
    922 	struct si70xx_sc *sc;
    923 	int 		error;
    924 
    925 	sc = sme->sme_cookie;
    926 	edata->state = ENVSYS_SINVALID;
    927 
    928 	mutex_enter(&sc->sc_mutex);
    929 	error = iic_acquire_bus(sc->sc_tag, 0);
    930 	if (error) {
    931 		DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
    932 		    device_xname(sc->sc_dev), error));
    933 		goto out;
    934 	}
    935 	error = si70xx_update_status(sc);
    936 	if (error) {
    937 		DPRINTF(sc, 2, ("%s: Failed to update status in refresh %d\n",
    938 		    device_xname(sc->sc_dev), error));
    939 		goto out1;
    940 	}
    941 	switch (edata->sensor) {
    942 	case SI70XX_HUMIDITY_SENSOR:
    943 		error = si70xx_exec(sc, SI70XX_MEASURE_RH_NOHOLD, edata);
    944 		break;
    945 
    946 	case SI70XX_TEMP_SENSOR:
    947 		error = si70xx_exec(sc, SI70XX_MEASURE_TEMP_NOHOLD, edata);
    948 		break;
    949 	default:
    950 		error = EINVAL;
    951 		break;
    952 	}
    953 
    954 	if (error) {
    955 		DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d\n",
    956 		    device_xname(sc->sc_dev), error));
    957 	}
    958 out1:
    959 	iic_release_bus(sc->sc_tag, 0);
    960 out:
    961 	mutex_exit(&sc->sc_mutex);
    962 }
    963 
    964 static int
    965 si70xx_detach(device_t self, int flags)
    966 {
    967 	struct si70xx_sc *sc;
    968 
    969 	sc = device_private(self);
    970 
    971 	mutex_enter(&sc->sc_mutex);
    972 
    973 	/* Remove the sensors */
    974 	if (sc->sc_sme != NULL) {
    975 		sysmon_envsys_unregister(sc->sc_sme);
    976 		sc->sc_sme = NULL;
    977 	}
    978 	mutex_exit(&sc->sc_mutex);
    979 
    980 	/* Remove the sysctl tree */
    981 	sysctl_teardown(&sc->sc_si70xxlog);
    982 
    983 	/* Remove the mutex */
    984 	mutex_destroy(&sc->sc_mutex);
    985 
    986 	return 0;
    987 }
    988 
    989 MODULE(MODULE_CLASS_DRIVER, si70xxtemp, "i2cexec,sysmon_envsys");
    990 
    991 #ifdef _MODULE
    992 #include "ioconf.c"
    993 #endif
    994 
    995 static int
    996 si70xxtemp_modcmd(modcmd_t cmd, void *opaque)
    997 {
    998 
    999 	switch (cmd) {
   1000 	case MODULE_CMD_INIT:
   1001 #ifdef _MODULE
   1002 		return config_init_component(cfdriver_ioconf_si70xxtemp,
   1003 		    cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp);
   1004 #else
   1005 		return 0;
   1006 #endif
   1007 	case MODULE_CMD_FINI:
   1008 #ifdef _MODULE
   1009 		return config_fini_component(cfdriver_ioconf_si70xxtemp,
   1010 		      cfattach_ioconf_si70xxtemp, cfdata_ioconf_si70xxtemp);
   1011 #else
   1012 		return 0;
   1013 #endif
   1014 	default:
   1015 		return ENOTTY;
   1016 	}
   1017 }
   1018