Home | History | Annotate | Line # | Download | only in i2c
sht3x.c revision 1.3
      1 /*	$NetBSD: sht3x.c,v 1.3 2021/11/13 13:36:42 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2021 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: sht3x.c,v 1.3 2021/11/13 13:36:42 christos Exp $");
     21 
     22 /*
     23   Driver for the Sensirion SHT30/SHT31/SHT35
     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/conf.h>
     32 #include <sys/sysctl.h>
     33 #include <sys/mutex.h>
     34 #include <sys/condvar.h>
     35 #include <sys/kthread.h>
     36 #include <sys/pool.h>
     37 #include <sys/kmem.h>
     38 
     39 #include <dev/sysmon/sysmonvar.h>
     40 #include <dev/i2c/i2cvar.h>
     41 #include <dev/i2c/sht3xreg.h>
     42 #include <dev/i2c/sht3xvar.h>
     43 
     44 static int	sht3x_take_break(void *, bool);
     45 static int	sht3x_get_status_register(void *, uint16_t *, bool);
     46 static int	sht3x_clear_status_register(void *, bool);
     47 static uint8_t 	sht3x_crc(uint8_t *, size_t);
     48 static int	sht3x_cmdr(struct sht3x_sc *, uint16_t, uint8_t *, size_t);
     49 static int 	sht3x_poke(i2c_tag_t, i2c_addr_t, bool);
     50 static int 	sht3x_match(device_t, cfdata_t, void *);
     51 static void 	sht3x_attach(device_t, device_t, void *);
     52 static int 	sht3x_detach(device_t, int);
     53 static void 	sht3x_refresh(struct sysmon_envsys *, envsys_data_t *);
     54 #ifdef __did_not_work
     55 /*
     56  * The chip that I had would not allow the limits to actually be set
     57  * for reasons which are not obvious.  The chip took the command just
     58  * fine, but a read back of the limit registers showed that no change
     59  * was made, so disable limits for now.
     60  */
     61 static void	sht3x_get_limits(struct sysmon_envsys *, envsys_data_t *,
     62     sysmon_envsys_lim_t *, uint32_t *);
     63 static void	sht3x_set_limits(struct sysmon_envsys *, envsys_data_t *,
     64     sysmon_envsys_lim_t *, uint32_t *);
     65 #endif
     66 static int 	sht3x_verify_sysctl(SYSCTLFN_ARGS);
     67 static int 	sht3x_verify_sysctl_heateron(SYSCTLFN_ARGS);
     68 static int 	sht3x_verify_sysctl_modes(SYSCTLFN_ARGS);
     69 static int 	sht3x_verify_sysctl_repeatability(SYSCTLFN_ARGS);
     70 static int 	sht3x_verify_sysctl_rate(SYSCTLFN_ARGS);
     71 static int	sht3x_set_heater(struct sht3x_sc *);
     72 static void     sht3x_thread(void *);
     73 static int	sht3x_init_periodic_measurement(void *, int *);
     74 static void     sht3x_take_periodic_measurement(void *);
     75 static void     sht3x_start_thread(void *);
     76 static void     sht3x_stop_thread(void *);
     77 static int	sht3x_activate(device_t, enum devact);
     78 
     79 #define SHT3X_DEBUG
     80 #ifdef SHT3X_DEBUG
     81 #define DPRINTF(s, l, x) \
     82     do { \
     83 	if (l <= s->sc_sht3xdebug) \
     84 	    printf x; \
     85     } while (/*CONSTCOND*/0)
     86 #else
     87 #define DPRINTF(s, l, x)
     88 #endif
     89 
     90 CFATTACH_DECL_NEW(sht3xtemp, sizeof(struct sht3x_sc),
     91     sht3x_match, sht3x_attach, sht3x_detach, sht3x_activate);
     92 
     93 extern struct cfdriver sht3xtemp_cd;
     94 
     95 static dev_type_open(sht3xopen);
     96 static dev_type_read(sht3xread);
     97 static dev_type_close(sht3xclose);
     98 const struct cdevsw sht3x_cdevsw = {
     99 	.d_open = sht3xopen,
    100 	.d_close = sht3xclose,
    101 	.d_read = sht3xread,
    102 	.d_write = nowrite,
    103 	.d_ioctl = noioctl,
    104 	.d_stop = nostop,
    105 	.d_tty = notty,
    106 	.d_poll = nopoll,
    107 	.d_mmap = nommap,
    108 	.d_kqfilter = nokqfilter,
    109 	.d_discard = nodiscard,
    110 	.d_flag = D_OTHER
    111 };
    112 
    113 static struct sht3x_sensor sht3x_sensors[] = {
    114 	{
    115 		.desc = "humidity",
    116 		.type = ENVSYS_SRELHUMIDITY,
    117 	},
    118 	{
    119 		.desc = "temperature",
    120 		.type = ENVSYS_STEMP,
    121 	}
    122 };
    123 
    124 /* The typical delays are MOSTLY documented in the datasheet for the chip.
    125    There is no need to be very accurate with these, just rough estimates
    126    will work fine.
    127 */
    128 
    129 static struct sht3x_timing sht3x_timings[] = {
    130 	{
    131 		.cmd = SHT3X_SOFT_RESET,
    132 		.typicaldelay = 3000,
    133 	},
    134 	{
    135 		.cmd = SHT3X_GET_STATUS_REGISTER,
    136 		.typicaldelay = 100,
    137 	},
    138 	{
    139 		.cmd = SHT3X_BREAK,
    140 		.typicaldelay = 100,
    141 	},
    142 	{
    143 		.cmd = SHT3X_CLEAR_STATUS_REGISTER,
    144 		.typicaldelay = 100,
    145 	},
    146 	{
    147 		.cmd = SHT3X_MEASURE_REPEATABILITY_CS_HIGH,
    148 		.typicaldelay = 15000,
    149 	},
    150 	{
    151 		.cmd = SHT3X_MEASURE_REPEATABILITY_CS_MEDIUM,
    152 		.typicaldelay = 6000,
    153 	},
    154 	{
    155 		.cmd = SHT3X_MEASURE_REPEATABILITY_CS_LOW,
    156 		.typicaldelay = 4000,
    157 	},
    158 	{
    159 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_HIGH,
    160 		.typicaldelay = 15000,
    161 	},
    162 	{
    163 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_MEDIUM,
    164 		.typicaldelay = 6000,
    165 	},
    166 	{
    167 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_LOW,
    168 		.typicaldelay = 4000,
    169 	},
    170 	{
    171 		.cmd = SHT3X_WRITE_HIGH_ALERT_SET,
    172 		.typicaldelay = 5000,
    173 	},
    174 	{
    175 		.cmd = SHT3X_WRITE_HIGH_ALERT_CLEAR,
    176 		.typicaldelay = 5000,
    177 	},
    178 	{
    179 		.cmd = SHT3X_WRITE_LOW_ALERT_SET,
    180 		.typicaldelay = 5000,
    181 	},
    182 	{
    183 		.cmd = SHT3X_WRITE_LOW_ALERT_CLEAR,
    184 		.typicaldelay = 5000,
    185 	}
    186 };
    187 
    188 /* In single shot mode, find the command */
    189 
    190 static struct sht3x_repeatability sht3x_repeatability_ss[] = {
    191 	{
    192 		.text = "high",
    193 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_HIGH,
    194 	},
    195 	{
    196 		.text = "medium",
    197 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_MEDIUM,
    198 	},
    199 	{
    200 		.text = "low",
    201 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_LOW,
    202 	}
    203 };
    204 
    205 
    206 /* For periodic, look at the repeatability and the rate.
    207  * ART is a bit fake here, as the repeatability is not really
    208  * used.
    209  */
    210 
    211 static struct sht3x_periodic sht3x_periodic_rate[] = {
    212 	{
    213 		.repeatability = "high",
    214 		.rate = "0.5mps",
    215 		.sdelay = 1000,
    216 		.cmd = SHT3X_HALF_MPS_HIGH,
    217 	},
    218 	{
    219 		.repeatability = "medium",
    220 		.rate = "0.5mps",
    221 		.sdelay = 1000,
    222 		.cmd = SHT3X_HALF_MPS_MEDIUM,
    223 	},
    224 	{
    225 		.repeatability = "low",
    226 		.rate = "0.5mps",
    227 		.sdelay = 1000,
    228 		.cmd = SHT3X_HALF_MPS_LOW,
    229 	},
    230 	{
    231 		.repeatability = "high",
    232 		.rate = "1.0mps",
    233 		.sdelay = 500,
    234 		.cmd = SHT3X_ONE_MPS_HIGH,
    235 	},
    236 	{
    237 		.repeatability = "medium",
    238 		.rate = "1.0mps",
    239 		.sdelay = 500,
    240 		.cmd = SHT3X_ONE_MPS_MEDIUM,
    241 	},
    242 	{
    243 		.repeatability = "low",
    244 		.rate = "1.0mps",
    245 		.sdelay = 500,
    246 		.cmd = SHT3X_ONE_MPS_LOW,
    247 	},
    248 	{
    249 		.repeatability = "high",
    250 		.rate = "2.0mps",
    251 		.sdelay = 250,
    252 		.cmd = SHT3X_TWO_MPS_HIGH,
    253 	},
    254 	{
    255 		.repeatability = "medium",
    256 		.rate = "2.0mps",
    257 		.sdelay = 250,
    258 		.cmd = SHT3X_TWO_MPS_MEDIUM,
    259 	},
    260 	{
    261 		.repeatability = "low",
    262 		.rate = "2.0mps",
    263 		.sdelay = 250,
    264 		.cmd = SHT3X_TWO_MPS_LOW,
    265 	},
    266 	{
    267 		.repeatability = "high",
    268 		.rate = "4.0mps",
    269 		.sdelay = 100,
    270 		.cmd = SHT3X_FOUR_MPS_HIGH,
    271 	},
    272 	{
    273 		.repeatability = "medium",
    274 		.rate = "4.0mps",
    275 		.sdelay = 100,
    276 		.cmd = SHT3X_FOUR_MPS_MEDIUM,
    277 	},
    278 	{
    279 		.repeatability = "low",
    280 		.rate = "4.0mps",
    281 		.sdelay = 100,
    282 		.cmd = SHT3X_FOUR_MPS_LOW,
    283 	},
    284 	{
    285 		.repeatability = "high",
    286 		.rate = "10.0mps",
    287 		.sdelay = 50,
    288 		.cmd = SHT3X_TEN_MPS_HIGH,
    289 	},
    290 	{
    291 		.repeatability = "medium",
    292 		.rate = "10.0mps",
    293 		.sdelay = 50,
    294 		.cmd = SHT3X_FOUR_MPS_MEDIUM,
    295 	},
    296 	{
    297 		.repeatability = "low",
    298 		.rate = "10.0mps",
    299 		.sdelay = 50,
    300 		.cmd = SHT3X_FOUR_MPS_LOW,
    301 	},
    302 	{
    303 		.repeatability = "high",
    304 		.rate = "ART",
    305 		.sdelay = 100,
    306 		.cmd = SHT3X_ART_ENABLE,
    307 	},
    308 	{
    309 		.repeatability = "medium",
    310 		.rate = "ART",
    311 		.sdelay = 100,
    312 		.cmd = SHT3X_ART_ENABLE,
    313 	},
    314 	{
    315 		.repeatability = "low",
    316 		.rate = "ART",
    317 		.sdelay = 100,
    318 		.cmd = SHT3X_ART_ENABLE,
    319 	}
    320 };
    321 
    322 static const char sht3x_rate_names[] =
    323     "0.5mps, 1.0mps, 2.0mps, 4.0mps, 10.0mps, ART";
    324 
    325 static const char sht3x_mode_names[] =
    326     "single-shot, periodic";
    327 
    328 static const char sht3x_repeatability_names[] =
    329     "high, medium, low";
    330 
    331 static int
    332 sht3x_take_break(void *aux, bool have_bus)
    333 {
    334 	struct sht3x_sc *sc;
    335 	sc = aux;
    336 	int error = 0;
    337 
    338 	if (! have_bus) {
    339 		error = iic_acquire_bus(sc->sc_tag, 0);
    340 		if (error) {
    341 			DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
    342 			    "breaking %d\n", device_xname(sc->sc_dev), error));
    343 			goto out;
    344 		}
    345 	}
    346 	error = sht3x_cmdr(sc, SHT3X_BREAK, NULL, 0);
    347 	if (error) {
    348 		DPRINTF(sc, 2, ("%s: Error breaking: %d\n",
    349 		    device_xname(sc->sc_dev), error));
    350 	}
    351 out:
    352 	if (! have_bus) {
    353 		iic_release_bus(sc->sc_tag, 0);
    354 	}
    355 
    356 	sc->sc_isperiodic = false;
    357 	strlcpy(sc->sc_mode, "single-shot", SHT3X_MODE_NAME);
    358 
    359 	return error;
    360 }
    361 
    362 static int
    363 sht3x_get_status_register(void *aux, uint16_t *reg, bool have_bus)
    364 {
    365 	struct sht3x_sc *sc = aux;
    366 	uint8_t buf[3];
    367 	int error;
    368 
    369 	if (! have_bus) {
    370 		error = iic_acquire_bus(sc->sc_tag, 0);
    371 		if (error) {
    372 			DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
    373 			    "getting status %d\n", device_xname(sc->sc_dev),
    374 			    error));
    375 			return error;
    376 		}
    377 	}
    378 	error = sht3x_cmdr(sc, SHT3X_GET_STATUS_REGISTER, buf, 3);
    379 	if (error) {
    380 		DPRINTF(sc, 2, ("%s: Error getting status: %d\n",
    381 		    device_xname(sc->sc_dev), error));
    382 		goto out;
    383 	}
    384 
    385 	uint8_t c = sht3x_crc(&buf[0], 2);
    386 	if (c == buf[2]) {
    387 		*reg = buf[0] << 8 | buf[1];
    388 	} else {
    389 		error = EINVAL;
    390 	}
    391 out:
    392 	if (! have_bus) {
    393 		iic_release_bus(sc->sc_tag, 0);
    394 	}
    395 
    396 	return error;
    397 }
    398 
    399 static int
    400 sht3x_clear_status_register(void *aux, bool have_bus)
    401 {
    402 	struct sht3x_sc *sc = aux;
    403 	int error;
    404 
    405 	if (! have_bus) {
    406 		error = iic_acquire_bus(sc->sc_tag, 0);
    407 		if (error) {
    408 			DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
    409 			    "clearing status %d\n", device_xname(sc->sc_dev),
    410 			    error));
    411 			return error;
    412 		}
    413 	}
    414 	error = sht3x_cmdr(sc, SHT3X_CLEAR_STATUS_REGISTER, NULL, 0);
    415 	if (error) {
    416 		DPRINTF(sc, 2, ("%s: Error clear status register: %d\n",
    417 		    device_xname(sc->sc_dev), error));
    418 	}
    419 	if (! have_bus) {
    420 		iic_release_bus(sc->sc_tag, 0);
    421 	}
    422 
    423 	return error;
    424 }
    425 
    426 void
    427 sht3x_thread(void *aux)
    428 {
    429 	struct sht3x_sc *sc = aux;
    430 	int error, rv;
    431 	int sdelay = 100;
    432 
    433 	mutex_enter(&sc->sc_threadmutex);
    434 
    435 	while (!sc->sc_stopping && !sc->sc_dying) {
    436 		if (sc->sc_initperiodic) {
    437 			error = sht3x_init_periodic_measurement(sc, &sdelay);
    438 			if (error) {
    439 				DPRINTF(sc, 2, ("%s: Error initing periodic "
    440 				    "measurement in thread: %d\n",
    441 				    device_xname(sc->sc_dev), error));
    442 			}
    443 			sc->sc_initperiodic = false;
    444 		}
    445 		rv = cv_timedwait(&sc->sc_condvar, &sc->sc_threadmutex,
    446 		    mstohz(sdelay));
    447 		if (rv == EWOULDBLOCK && !sc->sc_stopping &&
    448 		    !sc->sc_initperiodic && !sc->sc_dying) {
    449 			sht3x_take_periodic_measurement(sc);
    450 		}
    451 	}
    452 	mutex_exit(&sc->sc_threadmutex);
    453 	kthread_exit(0);
    454 }
    455 
    456 int
    457 sht3x_init_periodic_measurement(void *aux, int *sdelay)
    458 {
    459 	struct sht3x_sc *sc = aux;
    460 	size_t i;
    461 	int error;
    462 	uint16_t r;
    463 
    464 	for (i = 0; i < __arraycount(sht3x_periodic_rate); i++) {
    465 		if (strncmp(sc->sc_repeatability,
    466 		    sht3x_periodic_rate[i].repeatability, SHT3X_REP_NAME) == 0 &&
    467 		    strncmp(sc->sc_periodic_rate, sht3x_periodic_rate[i].rate,
    468 		    SHT3X_RATE_NAME) == 0)
    469 		{
    470 			r = sht3x_periodic_rate[i].cmd;
    471 			*sdelay = sht3x_periodic_rate[i].sdelay;
    472 			break;
    473 		}
    474 	}
    475 
    476 	if (i == __arraycount(sht3x_periodic_rate)) {
    477 		*sdelay = 100;
    478 		return ENODEV;
    479 	}
    480 
    481 	DPRINTF(sc, 2, ("%s: Would init with: %x\n",
    482 	    device_xname(sc->sc_dev), r));
    483 
    484 	mutex_enter(&sc->sc_mutex);
    485 
    486 	error = iic_acquire_bus(sc->sc_tag, 0);
    487 	if (error) {
    488 		DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: "
    489 		    " %d\n", device_xname(sc->sc_dev), error));
    490 		goto out;
    491 	}
    492 
    493 	error = sht3x_take_break(sc, true);
    494 	if (error) {
    495 	    DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: "
    496 		" %d\n", device_xname(sc->sc_dev), error));
    497 	    goto out;
    498 	}
    499 
    500 	error = sht3x_cmdr(sc, r, NULL, 0);
    501 	if (error) {
    502 		DPRINTF(sc, 2,
    503 		    ("%s: Error sending periodic measurement command: %d\n",
    504 		    device_xname(sc->sc_dev), error));
    505 		goto out;
    506 	}
    507 
    508 	sc->sc_isperiodic = true;
    509 	strlcpy(sc->sc_mode, "periodic", SHT3X_MODE_NAME);
    510 
    511 out:
    512 	iic_release_bus(sc->sc_tag, 0);
    513 	mutex_exit(&sc->sc_mutex);
    514 	return error;
    515 }
    516 
    517 static void
    518 sht3x_take_periodic_measurement(void *aux)
    519 {
    520 	struct sht3x_sc *sc = aux;
    521 	int error;
    522 	struct sht3x_read_q *pp;
    523 	uint8_t rawbuf[MAX(sizeof(sc->sc_pbuffer), sizeof(pp->measurement))];
    524 	uint16_t status_reg;
    525 
    526 	mutex_enter(&sc->sc_mutex);
    527 	error = iic_acquire_bus(sc->sc_tag, 0);
    528 	if (error) {
    529 		DPRINTF(sc, 2, ("%s: Could not acquire iic bus for getting "
    530 		    "periodic data: %d\n", device_xname(sc->sc_dev), error));
    531 		goto out;
    532 	}
    533 
    534 	error = sht3x_get_status_register(sc, &status_reg, true);
    535 	if (error) {
    536 		DPRINTF(sc, 2,
    537 		    ("%s: Error getting status register periodic: %d\n",
    538 		    device_xname(sc->sc_dev), error));
    539 		goto err;
    540 	}
    541 
    542 	if (status_reg & SHT3X_RESET_DETECTED) {
    543 		aprint_error_dev(sc->sc_dev, "Reset detected in periodic mode. "
    544 		    "Heater may have been reset.\n");
    545 		delay(3000);
    546 		sht3x_take_break(sc, true);
    547 		sht3x_clear_status_register(sc, true);
    548 		sc->sc_heateron = status_reg & SHT3X_HEATER_STATUS;
    549 		sc->sc_initperiodic = true;
    550 	} else {
    551 		int data_error = sht3x_cmdr(sc, SHT3X_PERIODIC_FETCH_DATA,
    552 		    rawbuf, sizeof(rawbuf));
    553 		/*
    554 		 * EIO is actually expected if the poll interval is faster
    555 		 * than the rate that the sensor is set to.  Unfortunally,
    556 		 * this will also mess with the ability to detect an actual
    557 		 * problem with the sensor in periodic mode, so we do the best
    558 		 * we can here.
    559 		 */
    560 		if (data_error) {
    561 			if (data_error != EIO) {
    562 				DPRINTF(sc, 2, ("%s: Error sending periodic "
    563 				    "fetch command: %d\n",
    564 				    device_xname(sc->sc_dev), data_error));
    565 			}
    566 			goto err;
    567 		}
    568 	}
    569 
    570 	iic_release_bus(sc->sc_tag, 0);
    571 	/*
    572 	 * If there was no errors from anything then the data should be
    573 	 * valid.
    574 	 */
    575 	DPRINTF(sc, 2, ("%s: Raw periodic: %x%x - %x -- %x%x - %x\n",
    576 	    device_xname(sc->sc_dev), rawbuf[0], rawbuf[1], rawbuf[2],
    577 	    rawbuf[3], rawbuf[4], rawbuf[5]));
    578 	memcpy(sc->sc_pbuffer, rawbuf, sizeof(sc->sc_pbuffer));
    579 
    580 	if (sc->sc_opened) {
    581 		mutex_enter(&sc->sc_read_mutex);
    582 		pp = pool_cache_get(sc->sc_readpool, PR_NOWAIT);
    583 		if (pp == NULL) {
    584 			aprint_error_dev(sc->sc_dev,
    585 			    "Could not allocate memory for pool read\n");
    586 		} else {
    587 			memcpy(pp->measurement, rawbuf, sizeof(pp->measurement));
    588 			DPRINTF(sc, 4, ("%s: Queue insert\n",
    589 			    device_xname(sc->sc_dev)));
    590 			SIMPLEQ_INSERT_HEAD(&sc->sc_read_queue, pp, read_q);
    591 		}
    592 		cv_signal(&sc->sc_condreadready);
    593 		mutex_exit(&sc->sc_read_mutex);
    594 	}
    595 out:
    596 	mutex_exit(&sc->sc_mutex);
    597 	return;
    598 err:
    599 	/*
    600 	 * We are only going to worry about errors when it was not related
    601 	 * to actually getting data.  That is a likely indicator of a problem
    602 	 * with the sensor.
    603 	 */
    604 	DPRINTF(sc, 2, ("%s: Raw periodic with error: %x%x - %x -- "
    605 	    "%x%x - %x -- %d\n", device_xname(sc->sc_dev), rawbuf[0], rawbuf[1],
    606 	    rawbuf[2], rawbuf[3], rawbuf[4], rawbuf[5], error));
    607 	iic_release_bus(sc->sc_tag, 0);
    608 	memcpy(sc->sc_pbuffer, "dedbef", sizeof(sc->sc_pbuffer));
    609 	mutex_exit(&sc->sc_mutex);
    610 }
    611 
    612 static void
    613 sht3x_stop_thread(void *aux)
    614 {
    615 	struct sht3x_sc *sc;
    616 	sc = aux;
    617 
    618 	if (!sc->sc_isperiodic) {
    619 		return;
    620 	}
    621 
    622 	mutex_enter(&sc->sc_threadmutex);
    623 	sc->sc_stopping = true;
    624 	cv_signal(&sc->sc_condvar);
    625 	mutex_exit(&sc->sc_threadmutex);
    626 
    627 	/* wait for the thread to exit */
    628 	kthread_join(sc->sc_thread);
    629 
    630 	mutex_enter(&sc->sc_mutex);
    631 	sht3x_take_break(sc,false);
    632 	mutex_exit(&sc->sc_mutex);
    633 }
    634 
    635 static void
    636 sht3x_start_thread(void *aux)
    637 {
    638 	struct sht3x_sc *sc;
    639 	sc = aux;
    640 	int error;
    641 
    642 	error = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN, NULL,
    643 	    sht3x_thread, sc, &sc->sc_thread, "%s", device_xname(sc->sc_dev));
    644 	if (error) {
    645 		DPRINTF(sc, 2, ("%s: Unable to create measurement thread: %d\n",
    646 		    device_xname(sc->sc_dev), error));
    647 	}
    648 }
    649 
    650 int
    651 sht3x_verify_sysctl(SYSCTLFN_ARGS)
    652 {
    653 	int error, t;
    654 	struct sysctlnode node;
    655 
    656 	node = *rnode;
    657 	t = *(int *)rnode->sysctl_data;
    658 	node.sysctl_data = &t;
    659 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    660 	if (error || newp == NULL)
    661 		return error;
    662 
    663 	if (t < 0)
    664 		return EINVAL;
    665 
    666 	*(int *)rnode->sysctl_data = t;
    667 
    668 	return 0;
    669 }
    670 
    671 int
    672 sht3x_verify_sysctl_heateron(SYSCTLFN_ARGS)
    673 {
    674 	int 		error;
    675 	bool 		t;
    676 	struct sht3x_sc *sc;
    677 	struct sysctlnode node;
    678 
    679 	node = *rnode;
    680 	sc = node.sysctl_data;
    681 	t = sc->sc_heateron;
    682 	node.sysctl_data = &t;
    683 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    684 	if (error || newp == NULL)
    685 		return error;
    686 
    687 	sc->sc_heateron = t;
    688 	error = sht3x_set_heater(sc);
    689 
    690 	return error;
    691 }
    692 
    693 static int
    694 sht3x_set_heater(struct sht3x_sc *sc)
    695 {
    696 	int error = 0;
    697 	uint16_t cmd;
    698 
    699 	mutex_enter(&sc->sc_mutex);
    700 	error = iic_acquire_bus(sc->sc_tag, 0);
    701 	if (error) {
    702 		DPRINTF(sc, 2, ("%s:%s: Failed to acquire bus: %d\n",
    703 		    device_xname(sc->sc_dev), __func__, error));
    704 		goto out;
    705 	}
    706 
    707 	if (sc->sc_heateron) {
    708 		cmd = SHT3X_HEATER_ENABLE;
    709 	} else {
    710 		cmd = SHT3X_HEATER_DISABLE;
    711 	}
    712 
    713 	error = sht3x_cmdr(sc, cmd, NULL, 0);
    714 
    715 	iic_release_bus(sc->sc_tag,0);
    716 out:
    717 	mutex_exit(&sc->sc_mutex);
    718 
    719 	return error;
    720 }
    721 
    722 int
    723 sht3x_verify_sysctl_modes(SYSCTLFN_ARGS)
    724 {
    725 	char buf[SHT3X_MODE_NAME];
    726 	struct sht3x_sc *sc;
    727 	struct sysctlnode node;
    728 	bool is_ss = false;
    729 	bool is_periodic = false;
    730 	int error;
    731 
    732 	node = *rnode;
    733 	sc = node.sysctl_data;
    734 	(void) memcpy(buf, sc->sc_mode, SHT3X_MODE_NAME);
    735 	node.sysctl_data = buf;
    736 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    737 	if (error || newp == NULL)
    738 		return error;
    739 
    740 	if (sc->sc_opened) {
    741 		return EINVAL;
    742 	}
    743 
    744 	is_ss = strncmp(node.sysctl_data, "single-shot", SHT3X_MODE_NAME) == 0;
    745 	is_periodic = strncmp(node.sysctl_data, "periodic", SHT3X_MODE_NAME)
    746 	    == 0;
    747 
    748 	if (!is_ss && !is_periodic) {
    749 		return EINVAL;
    750 	}
    751 
    752 	(void) memcpy(sc->sc_mode, node.sysctl_data, SHT3X_MODE_NAME);
    753 	if (is_ss) {
    754 		sht3x_stop_thread(sc);
    755 		sc->sc_stopping = false;
    756 		sc->sc_initperiodic = false;
    757 		sc->sc_isperiodic = false;
    758 	}
    759 
    760 	if (is_periodic) {
    761 		sc->sc_stopping = false;
    762 		sc->sc_initperiodic = true;
    763 		sc->sc_isperiodic = true;
    764 		sht3x_start_thread(sc);
    765 	}
    766 
    767 	return 0;
    768 }
    769 
    770 int
    771 sht3x_verify_sysctl_repeatability(SYSCTLFN_ARGS)
    772 {
    773 	char buf[SHT3X_REP_NAME];
    774 	struct sht3x_sc *sc;
    775 	struct sysctlnode node;
    776 	int error;
    777 	size_t i;
    778 
    779 	node = *rnode;
    780 	sc = node.sysctl_data;
    781 	(void) memcpy(buf, sc->sc_repeatability, SHT3X_REP_NAME);
    782 	node.sysctl_data = buf;
    783 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    784 	if (error || newp == NULL)
    785 		return error;
    786 
    787 	for (i = 0; i < __arraycount(sht3x_repeatability_ss); i++) {
    788 		if (strncmp(node.sysctl_data, sht3x_repeatability_ss[i].text,
    789 		    SHT3X_REP_NAME) == 0) {
    790 			break;
    791 		}
    792 	}
    793 
    794 	if (i == __arraycount(sht3x_repeatability_ss))
    795 		return EINVAL;
    796 	(void) memcpy(sc->sc_repeatability, node.sysctl_data, SHT3X_REP_NAME);
    797 
    798 	if (sc->sc_isperiodic) {
    799 		sc->sc_initperiodic = true;
    800 	}
    801 
    802 	return error;
    803 }
    804 
    805 int
    806 sht3x_verify_sysctl_rate(SYSCTLFN_ARGS)
    807 {
    808 	char buf[SHT3X_RATE_NAME];
    809 	struct sht3x_sc *sc;
    810 	struct sysctlnode node;
    811 	int error;
    812 	size_t i;
    813 
    814 	node = *rnode;
    815 	sc = node.sysctl_data;
    816 	(void) memcpy(buf, sc->sc_periodic_rate, SHT3X_RATE_NAME);
    817 	node.sysctl_data = buf;
    818 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    819 	if (error || newp == NULL)
    820 		return error;
    821 
    822 	for (i = 0; i < __arraycount(sht3x_periodic_rate); i++) {
    823 		if (strncmp(node.sysctl_data, sht3x_periodic_rate[i].rate,
    824 		    SHT3X_RATE_NAME) == 0) {
    825 			break;
    826 		}
    827 	}
    828 
    829 	if (i == __arraycount(sht3x_periodic_rate))
    830 		return EINVAL;
    831 
    832 	(void) memcpy(sc->sc_periodic_rate, node.sysctl_data, SHT3X_RATE_NAME);
    833 
    834 	if (sc->sc_isperiodic) {
    835 		sc->sc_initperiodic = true;
    836 	}
    837 
    838 	return error;
    839 }
    840 
    841 static int
    842 sht3x_cmddelay(uint16_t cmd)
    843 {
    844 	size_t i;
    845 
    846 	for (i = 0; i < __arraycount(sht3x_timings); i++) {
    847 		if (cmd == sht3x_timings[i].cmd) {
    848 			break;
    849 		}
    850 	}
    851 
    852 	if (i == __arraycount(sht3x_timings)) {
    853 		return -1;
    854 	}
    855 	return sht3x_timings[i].typicaldelay;
    856 }
    857 
    858 static int
    859 sht3x_cmd(i2c_tag_t tag, i2c_addr_t addr, uint16_t *cmd,
    860     uint8_t clen, uint8_t *buf, size_t blen, int readattempts)
    861 {
    862 	int error;
    863 	int cmddelay;
    864 	uint8_t cmd8[2];
    865 
    866 	/* All commands are two bytes and must be in a proper order */
    867 	KASSERT(clen == 2);
    868 
    869 	cmd8[0] = cmd[0] >> 8;
    870 	cmd8[1] = cmd[0] & 0x00ff;
    871 
    872 	error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &cmd8[0], clen,
    873 	    NULL, 0, 0);
    874 	if (error)
    875 		return error;
    876 
    877 	cmddelay = sht3x_cmddelay(cmd[0]);
    878 	if (cmddelay != -1) {
    879 		delay(cmddelay);
    880 	}
    881 
    882 	/* Not all commands return anything  */
    883 	if (blen == 0) {
    884 		return 0;
    885 	}
    886 
    887 	for (int aint = 0; aint < readattempts; aint++) {
    888 		error = iic_exec(tag, I2C_OP_READ_WITH_STOP, addr, NULL, 0, buf,
    889 		    blen, 0);
    890 		if (error == 0)
    891 			break;
    892 		delay(1000);
    893 	}
    894 
    895 	return error;
    896 }
    897 
    898 static int
    899 sht3x_cmdr(struct sht3x_sc *sc, uint16_t cmd, uint8_t *buf, size_t blen)
    900 {
    901 	return sht3x_cmd(sc->sc_tag, sc->sc_addr, &cmd, 2, buf, blen,
    902 	    sc->sc_readattempts);
    903 }
    904 
    905 static	uint8_t
    906 sht3x_crc(uint8_t *data, size_t size)
    907 {
    908 	uint8_t crc = 0xFF;
    909 
    910 	for (size_t i = 0; i < size; i++) {
    911 		crc ^= data[i];
    912 		for (size_t j = 8; j > 0; j--) {
    913 			if (crc & 0x80)
    914 				crc = (crc << 1) ^ 0x31;
    915 			else
    916 				crc <<= 1;
    917 		}
    918 	}
    919 	return crc;
    920 }
    921 
    922 static int
    923 sht3x_poke(i2c_tag_t tag, i2c_addr_t addr, bool matchdebug)
    924 {
    925 	uint16_t reg = SHT3X_GET_STATUS_REGISTER;
    926 	uint8_t buf[3];
    927 	int error;
    928 
    929 	error = sht3x_cmd(tag, addr, &reg, 2, buf, 3, 10);
    930 	if (matchdebug) {
    931 		printf("poke X 1: %d\n", error);
    932 	}
    933 	return error;
    934 }
    935 
    936 static int
    937 sht3x_sysctl_init(struct sht3x_sc *sc)
    938 {
    939 	int error;
    940 	const struct sysctlnode *cnode;
    941 	int sysctlroot_num;
    942 
    943 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
    944 	    0, CTLTYPE_NODE, device_xname(sc->sc_dev),
    945 	    SYSCTL_DESCR("sht3x controls"), NULL, 0, NULL, 0, CTL_HW,
    946 	    CTL_CREATE, CTL_EOL)) != 0)
    947 		return error;
    948 
    949 	sysctlroot_num = cnode->sysctl_num;
    950 
    951 #ifdef SHT3X_DEBUG
    952 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
    953 	    CTLFLAG_READWRITE, CTLTYPE_INT, "debug",
    954 	    SYSCTL_DESCR("Debug level"), sht3x_verify_sysctl, 0,
    955 	    &sc->sc_sht3xdebug, 0, CTL_HW, sysctlroot_num, CTL_CREATE,
    956 	    CTL_EOL)) != 0)
    957 		return error;
    958 
    959 #endif
    960 
    961 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
    962 	    CTLFLAG_READWRITE, CTLTYPE_INT, "readattempts",
    963 	    SYSCTL_DESCR("The number of times to attempt to read the values"),
    964 	    sht3x_verify_sysctl, 0, &sc->sc_readattempts, 0, CTL_HW,
    965 	    sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    966 		return error;
    967 
    968 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
    969 	    CTLFLAG_READONLY, CTLTYPE_STRING, "modes",
    970 	    SYSCTL_DESCR("Valid modes"), 0, 0,
    971 	    __UNCONST(sht3x_mode_names),
    972 	    sizeof(sht3x_mode_names) + 1,
    973 	    CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    974 		return error;
    975 
    976 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
    977 	    CTLFLAG_READWRITE, CTLTYPE_STRING, "mode",
    978 	    SYSCTL_DESCR("Mode for measurement collection"),
    979 	    sht3x_verify_sysctl_modes, 0, (void *) sc,
    980 	    SHT3X_MODE_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    981 		return error;
    982 
    983 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
    984 	    CTLFLAG_READONLY, CTLTYPE_STRING, "repeatabilities",
    985 	    SYSCTL_DESCR("Valid repeatability values"), 0, 0,
    986 	    __UNCONST(sht3x_repeatability_names),
    987 	    sizeof(sht3x_repeatability_names) + 1,
    988 	    CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    989 		return error;
    990 
    991 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
    992 	    CTLFLAG_READWRITE, CTLTYPE_STRING, "repeatability",
    993 	    SYSCTL_DESCR("Repeatability of RH and Temp"),
    994 	    sht3x_verify_sysctl_repeatability, 0, (void *) sc,
    995 	    SHT3X_REP_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    996 		return error;
    997 
    998 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
    999 	    CTLFLAG_READONLY, CTLTYPE_STRING, "rates",
   1000 	    SYSCTL_DESCR("Valid peridoic rates"), 0, 0,
   1001 	    __UNCONST(sht3x_rate_names),
   1002 	    sizeof(sht3x_rate_names) + 1,
   1003 	    CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
   1004 		return error;
   1005 
   1006 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
   1007 	    CTLFLAG_READWRITE, CTLTYPE_STRING, "rate",
   1008 	    SYSCTL_DESCR("Rate for periodic measurements"),
   1009 	    sht3x_verify_sysctl_rate, 0, (void *) sc,
   1010 	    SHT3X_RATE_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
   1011 		return error;
   1012 
   1013 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
   1014 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "ignorecrc",
   1015 	    SYSCTL_DESCR("Ignore the CRC byte"), NULL, 0, &sc->sc_ignorecrc,
   1016 	    0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
   1017 		return error;
   1018 
   1019 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
   1020 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "heateron",
   1021 	    SYSCTL_DESCR("Heater on"), sht3x_verify_sysctl_heateron, 0,
   1022 	    (void *)sc, 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
   1023 		return error;
   1024 
   1025 	return 0;
   1026 }
   1027 
   1028 static int
   1029 sht3x_match(device_t parent, cfdata_t match, void *aux)
   1030 {
   1031 	struct i2c_attach_args *ia = aux;
   1032 	int error, match_result;
   1033 	const bool matchdebug = false;
   1034 
   1035 	if (iic_use_direct_match(ia, match, NULL, &match_result))
   1036 		return match_result;
   1037 
   1038 	if (matchdebug) {
   1039 		printf("Looking at ia_addr: %x\n",ia->ia_addr);
   1040 	}
   1041 
   1042 	/* indirect config - check for configured address */
   1043 	if (ia->ia_addr != SHT3X_TYPICAL_ADDR_1 &&
   1044 	    ia->ia_addr != SHT3X_TYPICAL_ADDR_2)
   1045 		return 0;
   1046 
   1047 	/*
   1048 	 * Check to see if something is really at this i2c address.
   1049 	 * This will keep phantom devices from appearing
   1050 	 */
   1051 	if (iic_acquire_bus(ia->ia_tag, 0) != 0) {
   1052 		if (matchdebug)
   1053 			printf("in match acquire bus failed\n");
   1054 		return 0;
   1055 	}
   1056 
   1057 	error = sht3x_poke(ia->ia_tag, ia->ia_addr, matchdebug);
   1058 	iic_release_bus(ia->ia_tag, 0);
   1059 
   1060 	return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0;
   1061 }
   1062 
   1063 static void
   1064 sht3x_attach(device_t parent, device_t self, void *aux)
   1065 {
   1066 	struct sht3x_sc *sc;
   1067 	struct i2c_attach_args *ia;
   1068 	int error, i;
   1069 	int ecount = 0;
   1070 	uint8_t buf[6];
   1071 	uint32_t serialnumber;
   1072 	uint8_t sncrcpt1, sncrcpt2;
   1073 
   1074 	ia = aux;
   1075 	sc = device_private(self);
   1076 
   1077 	sc->sc_dev = self;
   1078 	sc->sc_tag = ia->ia_tag;
   1079 	sc->sc_addr = ia->ia_addr;
   1080 	sc->sc_sht3xdebug = 0;
   1081 	strlcpy(sc->sc_mode, "single-shot", SHT3X_MODE_NAME);
   1082 	sc->sc_isperiodic = false;
   1083 	strlcpy(sc->sc_repeatability, "high", SHT3X_REP_NAME);
   1084 	strlcpy(sc->sc_periodic_rate, "1.0mps", SHT3X_RATE_NAME);
   1085 	sc->sc_readattempts = 10;
   1086 	sc->sc_ignorecrc = false;
   1087 	sc->sc_heateron = false;
   1088 	sc->sc_sme = NULL;
   1089 	sc->sc_stopping = false;
   1090 	sc->sc_initperiodic = false;
   1091 	sc->sc_opened = false;
   1092 	sc->sc_dying = false;
   1093 	sc->sc_readpoolname = NULL;
   1094 
   1095 	aprint_normal("\n");
   1096 
   1097 	mutex_init(&sc->sc_dying_mutex, MUTEX_DEFAULT, IPL_NONE);
   1098 	mutex_init(&sc->sc_read_mutex, MUTEX_DEFAULT, IPL_NONE);
   1099 	mutex_init(&sc->sc_threadmutex, MUTEX_DEFAULT, IPL_NONE);
   1100 	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE);
   1101 	cv_init(&sc->sc_condvar, "sht3xcv");
   1102 	cv_init(&sc->sc_condreadready, "sht3xread");
   1103 	cv_init(&sc->sc_cond_dying, "sht3xdie");
   1104 	sc->sc_numsensors = __arraycount(sht3x_sensors);
   1105 
   1106 	if ((sc->sc_sme = sysmon_envsys_create()) == NULL) {
   1107 		aprint_error_dev(self,
   1108 		    "Unable to create sysmon structure\n");
   1109 		sc->sc_sme = NULL;
   1110 		return;
   1111 	}
   1112 	if ((error = sht3x_sysctl_init(sc)) != 0) {
   1113 		aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", error);
   1114 		goto out;
   1115 	}
   1116 
   1117 	sc->sc_readpoolname = kmem_asprintf("sht3xrp%d",device_unit(self));
   1118 	sc->sc_readpool = pool_cache_init(sizeof(struct sht3x_read_q), 0, 0, 0,
   1119 	    sc->sc_readpoolname, NULL, IPL_VM, NULL, NULL, NULL);
   1120 	pool_cache_sethiwat(sc->sc_readpool,100);
   1121 
   1122 	SIMPLEQ_INIT(&sc->sc_read_queue);
   1123 
   1124 	error = iic_acquire_bus(sc->sc_tag, 0);
   1125 	if (error) {
   1126 		aprint_error_dev(self, "Could not acquire iic bus: %d\n",
   1127 		    error);
   1128 		goto out;
   1129 	}
   1130 
   1131 	error = sht3x_cmdr(sc, SHT3X_SOFT_RESET, NULL, 0);
   1132 	if (error != 0)
   1133 		aprint_error_dev(self, "Reset failed: %d\n", error);
   1134 
   1135 	error = sht3x_clear_status_register(sc, true);
   1136 	if (error) {
   1137 		aprint_error_dev(self, "Failed to clear status register: %d\n",
   1138 		    error);
   1139 		ecount++;
   1140 	}
   1141 
   1142 	uint16_t status_reg;
   1143 	error = sht3x_get_status_register(sc, &status_reg, true);
   1144 	if (error) {
   1145 		aprint_error_dev(self, "Failed to read status register: %d\n",
   1146 		    error);
   1147 		ecount++;
   1148 	}
   1149 
   1150 	DPRINTF(sc, 2, ("%s: read status register values: %04x\n",
   1151 	    device_xname(sc->sc_dev), status_reg));
   1152 
   1153 	error = sht3x_cmdr(sc, SHT3X_READ_SERIAL_NUMBER, buf, 6);
   1154 	if (error) {
   1155 		aprint_error_dev(self, "Failed to read serial number: %d\n",
   1156 		    error);
   1157 		ecount++;
   1158 	}
   1159 
   1160 	sncrcpt1 = sht3x_crc(&buf[0],2);
   1161 	sncrcpt2 = sht3x_crc(&buf[3],2);
   1162 	serialnumber = (buf[0] << 24) | (buf[1] << 16) | (buf[3] << 8) | buf[4];
   1163 
   1164 	DPRINTF(sc, 2, ("%s: read serial number values: %02x%02x - %02x - "
   1165 	    "%02x%02x - %02x -- %02x %02x\n", device_xname(sc->sc_dev), buf[0],
   1166 	    buf[1], buf[2], buf[3], buf[4], buf[5], sncrcpt1, sncrcpt2));
   1167 
   1168 	iic_release_bus(sc->sc_tag, 0);
   1169 	if (error != 0) {
   1170 		aprint_error_dev(self, "Unable to setup device\n");
   1171 		goto out;
   1172 	}
   1173 
   1174 	for (i = 0; i < sc->sc_numsensors; i++) {
   1175 		strlcpy(sc->sc_sensors[i].desc, sht3x_sensors[i].desc,
   1176 		    sizeof(sc->sc_sensors[i].desc));
   1177 
   1178 		sc->sc_sensors[i].units = sht3x_sensors[i].type;
   1179 		sc->sc_sensors[i].state = ENVSYS_SINVALID;
   1180 #ifdef __did_not_work
   1181 		sc->sc_sensors[i].flags |= ENVSYS_FMONLIMITS;
   1182 #endif
   1183 
   1184 		DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i,
   1185 		    sc->sc_sensors[i].desc));
   1186 
   1187 		error = sysmon_envsys_sensor_attach(sc->sc_sme,
   1188 		    &sc->sc_sensors[i]);
   1189 		if (error) {
   1190 			aprint_error_dev(self,
   1191 			    "Unable to attach sensor %d: %d\n", i, error);
   1192 			goto out;
   1193 		}
   1194 	}
   1195 
   1196 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
   1197 	sc->sc_sme->sme_cookie = sc;
   1198 	sc->sc_sme->sme_refresh = sht3x_refresh;
   1199 #ifdef __did_not_work
   1200 	sc->sc_sme->sme_get_limits = sht3x_get_limits;
   1201 	sc->sc_sme->sme_set_limits = sht3x_set_limits;
   1202 #endif
   1203 
   1204 	DPRINTF(sc, 2, ("sht3x_attach: registering with envsys\n"));
   1205 
   1206 	if (sysmon_envsys_register(sc->sc_sme)) {
   1207 		aprint_error_dev(self, "unable to register with sysmon\n");
   1208 		sysmon_envsys_destroy(sc->sc_sme);
   1209 		sc->sc_sme = NULL;
   1210 		return;
   1211 	}
   1212 
   1213 	/*
   1214 	 * There is no documented way to ask the chip what version it is. This
   1215 	 * is likely fine as the only apparent difference is in how precise the
   1216 	 * measurements will be. The actual conversation with the chip is
   1217 	 * identical no matter which one you are talking to.
   1218 	 */
   1219 
   1220 	aprint_normal_dev(self, "Sensirion SHT30/SHT31/SHT35, "
   1221 	    "Serial number: %x%s", serialnumber,
   1222 	    (sncrcpt1 == buf[2] && sncrcpt2 == buf[5]) ? "\n" : " (bad crc)\n");
   1223 	return;
   1224 out:
   1225 	sysmon_envsys_destroy(sc->sc_sme);
   1226 	sc->sc_sme = NULL;
   1227 }
   1228 
   1229 static uint16_t
   1230 sht3x_compute_measure_command_ss(const char *repeatability)
   1231 {
   1232 	int i;
   1233 	uint16_t r;
   1234 
   1235 	for (i = 0; i < __arraycount(sht3x_repeatability_ss); i++) {
   1236 		if (strncmp(repeatability, sht3x_repeatability_ss[i].text,
   1237 		    SHT3X_REP_NAME) == 0) {
   1238 			r = sht3x_repeatability_ss[i].cmd;
   1239 			break;
   1240 		}
   1241 	}
   1242 
   1243 	if (i == __arraycount(sht3x_repeatability_ss))
   1244 		panic("Single-shot could not find command for "
   1245 		    "repeatability: %s\n", repeatability);
   1246 
   1247 	return r;
   1248 }
   1249 
   1250 /*
   1251  * The documented conversion calculations for the raw values are as follows:
   1252  *
   1253  * %RH = (-6 + 125 * rawvalue / 65535)
   1254  *
   1255  * T in Celsius = (-45 + 175 * rawvalue / 65535)
   1256  *
   1257  * It follows then:
   1258  *
   1259  * T in Kelvin = (228.15 + 175 * rawvalue / 65535)
   1260  *
   1261  * given the relationship between Celsius and Kelvin
   1262  *
   1263  * What follows reorders the calculation a bit and scales it up to avoid
   1264  * the use of any floating point.  All that would really have to happen
   1265  * is a scale up to 10^6 for the sysenv framework, which wants
   1266  * temperature in micro-kelvin and percent relative humidity scaled up
   1267  * 10^6, but since this conversion uses 64 bits due to intermediate
   1268  * values that are bigger than 32 bits the conversion first scales up to
   1269  * 10^9 and the scales back down by 10^3 at the end.  This preserves some
   1270  * precision in the conversion that would otherwise be lost.
   1271  */
   1272 
   1273 static uint64_t
   1274 sht3x_compute_temp_from_raw(uint8_t msb, uint8_t lsb) {
   1275 	uint64_t svalue;
   1276 	int64_t v1;
   1277 	uint64_t v2;
   1278 	uint64_t d1 = 65535;
   1279 	uint64_t mul1;
   1280 	uint64_t mul2;
   1281 	uint64_t div1 = 10000;
   1282 	uint64_t q;
   1283 
   1284 	svalue = msb << 8 | lsb;
   1285 
   1286 	v1 = 22815; /* this is scaled up already from 228.15 */
   1287 	v2 = 175;
   1288 	mul1 = 10000000000;
   1289 	mul2 = 100000000;
   1290 
   1291 	svalue = svalue * mul1;
   1292 	v1 = v1 * mul2;
   1293 	/* Perform the conversion */
   1294 	q = ((v2 * (svalue / d1)) + v1) / div1;
   1295 
   1296 	return q;
   1297 }
   1298 
   1299 static uint64_t
   1300 sht3x_compute_rh_from_raw(uint8_t msb, uint8_t lsb) {
   1301 	uint64_t svalue;
   1302 	int64_t v1;
   1303 	uint64_t v2;
   1304 	uint64_t d1 = 65535;
   1305 	uint64_t mul1;
   1306 	uint64_t mul2;
   1307 	uint64_t div1 = 10000;
   1308 	uint64_t q;
   1309 
   1310 	svalue = msb << 8 | lsb;
   1311 
   1312 	v1 = 0;
   1313 	v2 = 100;
   1314 	mul1 = 10000000000;
   1315 	mul2 = 10000000000;
   1316 
   1317 	svalue = svalue * mul1;
   1318 	v1 = v1 * mul2;
   1319 	/* Perform the conversion */
   1320 	q = ((v2 * (svalue / d1)) + v1) / div1;
   1321 
   1322 	return q;
   1323 }
   1324 
   1325 static int
   1326 sht3x_parse_data(struct sht3x_sc *sc, envsys_data_t *edata, uint8_t *rawdata)
   1327 {
   1328 	uint64_t current_value;
   1329 	uint8_t *svalptr;
   1330 
   1331 	DPRINTF(sc, 2, ("%s: Raw data: %02x%02x %02x - %02x%02x %02x\n",
   1332 	    device_xname(sc->sc_dev), rawdata[0], rawdata[1], rawdata[2],
   1333 	    rawdata[3], rawdata[4], rawdata[5]));
   1334 
   1335 	switch (edata->sensor) {
   1336 	case SHT3X_TEMP_SENSOR:
   1337 		current_value = sht3x_compute_temp_from_raw(rawdata[0],
   1338 		    rawdata[1]);
   1339 		svalptr = &rawdata[0];
   1340 		break;
   1341 	case SHT3X_HUMIDITY_SENSOR:
   1342 		current_value = sht3x_compute_rh_from_raw(rawdata[3],
   1343 		    rawdata[4]);
   1344 		svalptr = &rawdata[3];
   1345 		break;
   1346 	default:
   1347 		DPRINTF(sc, 2, ("%s: bad sensor type %d\n",
   1348 		    device_xname(sc->sc_dev), edata->sensor));
   1349 		return EINTR;
   1350 	}
   1351 	uint8_t testcrc;
   1352 	/* Fake out the CRC check if being asked to ignore CRC */
   1353 	if (sc->sc_ignorecrc) {
   1354 		testcrc = *(svalptr + 2);
   1355 	} else {
   1356 		testcrc = sht3x_crc(svalptr, 2);
   1357 	}
   1358 
   1359 	if (*(svalptr + 2) != testcrc) {
   1360 	    DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d != %d\n",
   1361 	    device_xname(sc->sc_dev), (*svalptr + 2), testcrc));
   1362 	    return EINVAL;
   1363 	}
   1364 	edata->value_cur = (uint32_t) current_value;
   1365 	edata->state = ENVSYS_SVALID;
   1366 	return 0;
   1367 }
   1368 
   1369 #ifdef __did_not_work
   1370 /*
   1371  * These are the the same as above except solved for the raw tick rather than
   1372  * temperature or humidity.  These are needed for setting the alert limits, but
   1373  * since that did not work, disable these too for now.
   1374  */
   1375 static uint16_t
   1376 sht3x_compute_raw_from_temp(uint32_t temp)
   1377 {
   1378 	uint64_t i1;
   1379 	uint32_t tempc;
   1380 
   1381 	tempc = temp - 272150000;
   1382 	tempc = tempc / 1000000;
   1383 
   1384 	i1 = (13107 * tempc) + 589815;
   1385 	return (uint16_t)(i1 / 35);
   1386 }
   1387 
   1388 static uint16_t
   1389 sht3x_compute_raw_from_rh(uint32_t mrh)
   1390 {
   1391 	uint64_t i1;
   1392 	uint32_t rh;
   1393 
   1394 	rh = mrh / 1000000;
   1395 
   1396 	i1 = 13107 * rh;
   1397 	return (uint16_t)(i1 / 20);
   1398 }
   1399 #endif
   1400 
   1401 static int
   1402 sht3x_refresh_periodic(struct sysmon_envsys *sme, envsys_data_t *edata)
   1403 {
   1404 	struct sht3x_sc *sc = sme->sme_cookie;
   1405 	uint8_t rawdata[sizeof(sc->sc_pbuffer)];
   1406 
   1407 	memcpy(rawdata, sc->sc_pbuffer, sizeof(rawdata));
   1408 
   1409 	return sht3x_parse_data(sc, edata, rawdata);
   1410 
   1411 }
   1412 
   1413 static int
   1414 sht3x_refresh_oneshot(struct sysmon_envsys *sme, envsys_data_t *edata)
   1415 {
   1416 	struct sht3x_sc *sc = sme->sme_cookie;
   1417 	uint16_t measurement_command_ss;
   1418 	uint8_t rawdata[sizeof(sc->sc_pbuffer)];
   1419 	int error;
   1420 
   1421 	error = iic_acquire_bus(sc->sc_tag, 0);
   1422 	if (error) {
   1423 		DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
   1424 		    device_xname(sc->sc_dev), error));
   1425 		return error;
   1426 	}
   1427 
   1428 	measurement_command_ss = sht3x_compute_measure_command_ss(
   1429 	    sc->sc_repeatability);
   1430 	DPRINTF(sc, 2, ("%s: Measurement command: %04x\n",
   1431 	    device_xname(sc->sc_dev), measurement_command_ss));
   1432 	error = sht3x_cmdr(sc, measurement_command_ss, rawdata, sizeof(rawdata));
   1433 	if (error == 0) {
   1434 		DPRINTF(sc, 2, ("%s: Failed to get new status in refresh for "
   1435 		    "single-shot %d\n", device_xname(sc->sc_dev), error));
   1436 		if ((error = sht3x_parse_data(sc, edata, rawdata)) == 0)
   1437 			return 0;
   1438 	}
   1439 
   1440 	uint16_t sbuf;
   1441 	int status_error = sht3x_get_status_register(sc, &sbuf, true);
   1442 
   1443 	if (!status_error) {
   1444 		DPRINTF(sc, 2, ("%s: read status register single-shot: %04x\n",
   1445 		    device_xname(sc->sc_dev), sbuf));
   1446 
   1447 		if (sbuf & SHT3X_RESET_DETECTED) {
   1448 			aprint_error_dev(sc->sc_dev,
   1449 			    "Reset detected in single shot mode. "
   1450 			    "Heater may have been reset\n");
   1451 			sht3x_clear_status_register(sc, true);
   1452 		}
   1453 
   1454 		sc->sc_heateron = sbuf & SHT3X_HEATER_STATUS;
   1455 	}
   1456 
   1457 	iic_release_bus(sc->sc_tag, 0);
   1458 	return 0;
   1459 }
   1460 
   1461 static void
   1462 sht3x_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
   1463 {
   1464 	struct sht3x_sc *sc = sme->sme_cookie;
   1465 
   1466 	edata->state = ENVSYS_SINVALID;
   1467 
   1468 	mutex_enter(&sc->sc_mutex);
   1469 
   1470 	if (sc->sc_isperiodic) {
   1471 		sht3x_refresh_periodic(sme, edata);
   1472 	} else {
   1473 		sht3x_refresh_oneshot(sme, edata);
   1474 	}
   1475 
   1476 	mutex_exit(&sc->sc_mutex);
   1477 }
   1478 
   1479 #ifdef __did_not_work
   1480 static void
   1481 sht3x_get_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
   1482     sysmon_envsys_lim_t *limits, uint32_t *props)
   1483 {
   1484 	struct sht3x_sc *sc = sme->sme_cookie;
   1485 	uint16_t rawlimitshigh, rawlimitslow;
   1486 	uint16_t templimithigh, rhlimithigh,
   1487 	    templimitlow, rhlimitlow;
   1488 	uint8_t templimithighmsb, templimithighlsb,
   1489 	    templimitlowmsb, templimitlowlsb;
   1490 	uint8_t rhlimithighmsb, rhlimithighlsb,
   1491 	    rhlimitlowmsb, rhlimitlowlsb;
   1492 	int error;
   1493 	uint8_t lbuf[3];
   1494 	uint8_t limitscrchigh, limitskcrchigh,
   1495 	    limitscrclow, limitskcrclow;
   1496 
   1497 	*props = 0;
   1498 
   1499 	mutex_enter(&sc->sc_mutex);
   1500 	error = iic_acquire_bus(sc->sc_tag, 0);
   1501 	if (error) {
   1502 		DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
   1503 		    device_xname(sc->sc_dev), error));
   1504 		mutex_exit(&sc->sc_mutex);
   1505 		return;
   1506 	}
   1507 
   1508 	error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, lbuf, 3);
   1509 	if (error) {
   1510 		DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
   1511 		    device_xname(sc->sc_dev), error));
   1512 		goto out;
   1513 	}
   1514 
   1515 	rawlimitshigh = (lbuf[0] << 8) | lbuf[1];
   1516 	limitskcrchigh = lbuf[2];
   1517 	limitscrchigh = sht3x_crc(&lbuf[0],2);
   1518 
   1519 	templimithigh = ((rawlimitshigh & 0x1FF) << 7);
   1520 	templimithighmsb = (uint8_t)(templimithigh >> 8);
   1521 	templimithighlsb = (uint8_t)(templimithigh & 0x00FF);
   1522 	DPRINTF(sc, 2, ("%s: Limits high intermediate temp: "
   1523 	    "%04x %04x %02x %02x\n", device_xname(sc->sc_dev), rawlimitshigh,
   1524 	    templimithigh, templimithighmsb, templimithighlsb));
   1525 
   1526 	rhlimithigh = (rawlimitshigh & 0xFE00);
   1527 	rhlimithighmsb = (uint8_t)(rhlimithigh >> 8);
   1528 	rhlimithighlsb = (uint8_t)(rhlimithigh & 0x00FF);
   1529 	DPRINTF(sc, 2, ("%s: Limits high intermediate rh: "
   1530 	    "%04x %04x %02x %02x\n", device_xname(sc->sc_dev), rawlimitshigh,
   1531 	    rhlimithigh, rhlimithighmsb, rhlimithighlsb));
   1532 
   1533 	DPRINTF(sc, 2, ("%s: Limit high raw: %02x%02x %02x %02x %02x\n",
   1534 	    device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2],
   1535 	    limitscrchigh, limitskcrchigh));
   1536 
   1537 	error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_SET, lbuf, 3);
   1538 	if (error) {
   1539 		DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
   1540 		    device_xname(sc->sc_dev), error));
   1541 		goto out;
   1542 	}
   1543 
   1544 	rawlimitslow = (lbuf[0] << 8) | lbuf[1];
   1545 	limitskcrclow = lbuf[2];
   1546 	limitscrclow = sht3x_crc(&lbuf[0],2);
   1547 
   1548 	templimitlow = ((rawlimitslow & 0x1FF) << 7);
   1549 	templimitlowmsb = (uint8_t)(templimitlow >> 8);
   1550 	templimitlowlsb = (uint8_t)(templimitlow & 0x00FF);
   1551 	DPRINTF(sc, 2, ("%s: Limits low intermediate temp: "
   1552 	    "%04x %04x %02x %02x\n", device_xname(sc->sc_dev), rawlimitslow,
   1553 	    templimitlow, templimitlowmsb, templimitlowlsb));
   1554 
   1555 	rhlimitlow = (rawlimitslow & 0xFE00);
   1556 	rhlimitlowmsb = (uint8_t)(rhlimitlow >> 8);
   1557 	rhlimitlowlsb = (uint8_t)(rhlimitlow & 0x00FF);
   1558 	DPRINTF(sc, 2, ("%s: Limits low intermediate rh: %04x %04x %02x %02x\n",
   1559 	    device_xname(sc->sc_dev), rawlimitslow, rhlimitlow, rhlimitlowmsb,
   1560 	    rhlimitlowlsb));
   1561 
   1562 	DPRINTF(sc, 2, ("%s: Limit low raw: %02x%02x %02x %02x %02x\n",
   1563 	    device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2],
   1564 	    limitscrclow, limitskcrclow));
   1565 
   1566 
   1567 	switch (edata->sensor) {
   1568 	case SHT3X_TEMP_SENSOR:
   1569 		if (limitscrchigh == limitskcrchigh) {
   1570 			limits->sel_critmax = sht3x_compute_temp_from_raw(
   1571 			    templimithighmsb, templimithighlsb);
   1572 			*props |= PROP_CRITMAX;
   1573 		}
   1574 		if (limitscrclow == limitskcrclow) {
   1575 			limits->sel_critmin = sht3x_compute_temp_from_raw(
   1576 			    templimitlowmsb, templimitlowlsb);
   1577 			*props |= PROP_CRITMIN;
   1578 		}
   1579 		break;
   1580 	case SHT3X_HUMIDITY_SENSOR:
   1581 		if (limitscrchigh == limitskcrchigh) {
   1582 			limits->sel_critmax = sht3x_compute_rh_from_raw(
   1583 			    rhlimithighmsb, rhlimithighlsb);
   1584 			*props |= PROP_CRITMAX;
   1585 		}
   1586 		if (limitscrclow == limitskcrclow) {
   1587 			limits->sel_critmin = sht3x_compute_rh_from_raw(
   1588 			    rhlimitlowmsb, rhlimitlowlsb);
   1589 			*props |= PROP_CRITMIN;
   1590 		}
   1591 		break;
   1592 	default:
   1593 		break;
   1594 	}
   1595 
   1596 	if (*props != 0)
   1597 		*props |= PROP_DRIVER_LIMITS;
   1598 
   1599 	iic_release_bus(sc->sc_tag, 0);
   1600 out:
   1601 	mutex_exit(&sc->sc_mutex);
   1602 }
   1603 
   1604 static void
   1605 sht3x_set_alert_limits(void *aux, uint16_t high, uint16_t low, bool have_bus)
   1606 {
   1607 	struct sht3x_sc *sc = aux;
   1608 	int error;
   1609 	uint8_t hbuf[3];
   1610 	uint8_t lbuf[3];
   1611 
   1612 	if (! have_bus) {
   1613 		error = iic_acquire_bus(sc->sc_tag, 0);
   1614 		if (error) {
   1615 			DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
   1616 			    "setting alerts %d\n", device_xname(sc->sc_dev),
   1617 			    error));
   1618 			return;
   1619 		}
   1620 	}
   1621 
   1622 	hbuf[0] = high >> 8;
   1623 	hbuf[1] = high & 0x00FF;
   1624 	hbuf[2] = sht3x_crc(&hbuf[0],2);
   1625 
   1626 	lbuf[0] = low >> 8;
   1627 	lbuf[1] = low & 0x00FF;
   1628 	lbuf[2] = sht3x_crc(&lbuf[0],2);
   1629 
   1630 	error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_SET, hbuf, 3);
   1631 	if (error) {
   1632 		DPRINTF(sc, 2, ("%s: Could not set high alert for SET %d\n",
   1633 		    device_xname(sc->sc_dev), error));
   1634 		goto out;
   1635 	}
   1636 	error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_CLEAR, hbuf, 3);
   1637 	if (error) {
   1638 		DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
   1639 		    device_xname(sc->sc_dev), error));
   1640 		goto out;
   1641 	}
   1642 	error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_SET, lbuf, 3);
   1643 	if (error) {
   1644 		DPRINTF(sc, 2, ("%s: Could not set low alert for SET %d\n",
   1645 		    device_xname(sc->sc_dev), error));
   1646 		goto out;
   1647 	}
   1648 	error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_CLEAR, lbuf, 3);
   1649 	if (error) {
   1650 		DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
   1651 		    device_xname(sc->sc_dev), error));
   1652 	}
   1653 
   1654  out:
   1655 	if (! have_bus) {
   1656 		iic_release_bus(sc->sc_tag, 0);
   1657 	}
   1658 }
   1659 
   1660 static void
   1661 sht3x_set_alert_limits2(void *aux, uint16_t high, uint16_t low,
   1662     uint16_t highminusone, uint16_t lowplusone, bool have_bus)
   1663 {
   1664 	struct sht3x_sc *sc;
   1665 	sc = aux;
   1666 
   1667 	int error;
   1668 	uint8_t hbuf[3];
   1669 	uint8_t lbuf[3];
   1670 	uint8_t hbufminusone[3];
   1671 	uint8_t lbufplusone[3];
   1672 
   1673 	if (! have_bus) {
   1674 		error = iic_acquire_bus(sc->sc_tag, 0);
   1675 		if (error) {
   1676 			DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
   1677 			    "setting alerts %d\n", device_xname(sc->sc_dev),
   1678 			    error));
   1679 			return;
   1680 		}
   1681 	}
   1682 
   1683 	hbuf[0] = high >> 8;
   1684 	hbuf[1] = high & 0x00FF;
   1685 	hbuf[2] = sht3x_crc(&hbuf[0],2);
   1686 
   1687 	lbuf[0] = low >> 8;
   1688 	lbuf[1] = low & 0x00FF;
   1689 	lbuf[2] = sht3x_crc(&lbuf[0],2);
   1690 
   1691 	hbufminusone[0] = highminusone >> 8;
   1692 	hbufminusone[1] = highminusone & 0x00FF;
   1693 	hbufminusone[2] = sht3x_crc(&hbufminusone[0],2);
   1694 
   1695 	lbufplusone[0] = lowplusone >> 8;
   1696 	lbufplusone[1] = lowplusone & 0x00FF;
   1697 	lbufplusone[2] = sht3x_crc(&lbufplusone[0],2);
   1698 
   1699 	DPRINTF(sc, 2, ("%s: Physical SET HIGH %02x %02x %02x\n",
   1700 	    device_xname(sc->sc_dev), hbuf[0], hbuf[1], hbuf[2]));
   1701 	error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_SET, hbuf, 3);
   1702 	if (error) {
   1703 		DPRINTF(sc, 2, ("%s: Could not set high alert for SET %d\n",
   1704 		    device_xname(sc->sc_dev), error));
   1705 		goto out;
   1706 	}
   1707 
   1708 	uint16_t sbuf;
   1709 	int status_error;
   1710 	status_error = sht3x_get_status_register(sc, &sbuf, true);
   1711 	DPRINTF(sc, 2, ("%s: In SETTING, status register %04x -- %d\n",
   1712 	    device_xname(sc->sc_dev), sbuf, status_error));
   1713 
   1714 	hbuf[0] = 0;
   1715 	hbuf[1] = 0;
   1716 	hbuf[2] = 0;
   1717 	error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, hbuf, 3);
   1718 	if (error) {
   1719 		DPRINTF(sc, 2, ("%s: Could not read high alert for SET %d\n",
   1720 		    device_xname(sc->sc_dev), error));
   1721 		goto out;
   1722 	}
   1723 	DPRINTF(sc, 2, ("%s: Physical READBACK SET HIGH %02x %02x %02x\n",
   1724 	    device_xname(sc->sc_dev), hbuf[0], hbuf[1], hbuf[2]));
   1725 
   1726 	DPRINTF(sc, 2, ("%s: Physical CLEAR HIGH %02x %02x %02x\n",
   1727 	    device_xname(sc->sc_dev), hbufminusone[0], hbufminusone[1],
   1728 	    hbufminusone[2]));
   1729 	error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_CLEAR, hbufminusone, 3);
   1730 	if (error) {
   1731 		DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
   1732 		    device_xname(sc->sc_dev), error));
   1733 		goto out;
   1734 	}
   1735 	hbufminusone[0] = 0;
   1736 	hbufminusone[1] = 0;
   1737 	hbufminusone[2] = 0;
   1738 	error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_CLEAR, hbufminusone, 3);
   1739 	if (error) {
   1740 		DPRINTF(sc, 2, ("%s: Could not read high alert for CLEAR %d\n",
   1741 		    device_xname(sc->sc_dev), error));
   1742 		goto out;
   1743 	}
   1744 	DPRINTF(sc, 2, ("%s: Physical READBACK CLEAR HIGH %02x %02x %02x\n",
   1745 	    device_xname(sc->sc_dev), hbufminusone[0], hbufminusone[1],
   1746 	    hbufminusone[2]));
   1747 
   1748 	DPRINTF(sc, 2, ("%s: Physical SET LOW %02x %02x %02x\n",
   1749 	    device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2]));
   1750 	error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_SET, lbuf, 3);
   1751 	if (error) {
   1752 		DPRINTF(sc, 2, ("%s: Could not set low alert for SET %d\n",
   1753 		    device_xname(sc->sc_dev), error));
   1754 		goto out;
   1755 	}
   1756 	DPRINTF(sc, 2, ("%s: Physical CLEAR LOW %02x %02x %02x\n",
   1757 	    device_xname(sc->sc_dev), lbufplusone[0], lbufplusone[1],
   1758 	    lbufplusone[2]));
   1759 	error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_CLEAR, lbufplusone, 3);
   1760 	if (error) {
   1761 		DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n",
   1762 		    device_xname(sc->sc_dev), error));
   1763 	}
   1764 
   1765 out:
   1766 	if (! have_bus) {
   1767 		iic_release_bus(sc->sc_tag, 0);
   1768 	}
   1769 }
   1770 
   1771 static void
   1772 sht3x_set_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
   1773     sysmon_envsys_lim_t *limits, uint32_t *props)
   1774 {
   1775 	struct sht3x_sc *sc = sme->sme_cookie;
   1776 	uint16_t rawlimitshigh, rawlimitslow;
   1777 	uint16_t rawlimitshighclear, rawlimitslowclear;
   1778 	uint16_t rawlimitshighminusone, rawlimitslowplusone;
   1779 	int error;
   1780 	uint8_t lbuf[3];
   1781 	uint8_t limitscrchigh, limitskcrchigh, limitscrclow, limitskcrclow;
   1782 	uint16_t limithigh, limitlow;
   1783 	uint16_t limithighminusone, limitlowplusone;
   1784 
   1785 	if (limits == NULL) {
   1786 		printf("XXX - Need to set back to default... limits is NULL\n");
   1787 		return;
   1788 	}
   1789 
   1790 	DPRINTF(sc, 2, ("%s: In set_limits - %d -- %d %d\n",
   1791 	    device_xname(sc->sc_dev), edata->sensor,
   1792 	    limits->sel_critmin, limits->sel_critmax));
   1793 
   1794 	mutex_enter(&sc->sc_mutex);
   1795 	error = iic_acquire_bus(sc->sc_tag, 0);
   1796 	if (error) {
   1797 		DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
   1798 		    device_xname(sc->sc_dev), error));
   1799 		goto out;
   1800 	}
   1801 
   1802 	error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, lbuf, 3);
   1803 	if (error) {
   1804 		DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
   1805 		    device_xname(sc->sc_dev), error));
   1806 		goto out;
   1807 	}
   1808 
   1809 	rawlimitshigh = (lbuf[0] << 8) | lbuf[1];
   1810 	limitskcrchigh = lbuf[2];
   1811 	limitscrchigh = sht3x_crc(&lbuf[0],2);
   1812 
   1813 
   1814 	error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_SET, lbuf, 3);
   1815 	if (error) {
   1816 		DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n",
   1817 		    device_xname(sc->sc_dev), error));
   1818 		goto out;
   1819 	}
   1820 
   1821 	rawlimitslow = (lbuf[0] << 8) | lbuf[1];
   1822 	limitskcrclow = lbuf[2];
   1823 	limitscrclow = sht3x_crc(&lbuf[0],2);
   1824 
   1825 	error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_CLEAR, lbuf, 3);
   1826 	if (error) {
   1827 		DPRINTF(sc, 2, ("%s: Could not get high alert clear: %x\n",
   1828 		    device_xname(sc->sc_dev), error));
   1829 		goto out;
   1830 	}
   1831 
   1832 	rawlimitshighclear = (lbuf[0] << 8) | lbuf[1];
   1833 
   1834 	error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_CLEAR, lbuf, 3);
   1835 	if (error) {
   1836 		DPRINTF(sc, 2, ("%s: Could not get high alert clear: %x\n",
   1837 		    device_xname(sc->sc_dev), error));
   1838 		goto out;
   1839 	}
   1840 
   1841 	rawlimitslowclear = (lbuf[0] << 8) | lbuf[1];
   1842 
   1843 	DPRINTF(sc, 2, ("%s: Set limits current raw limits %04x - %02x %02x ; "
   1844 	    "%04x - %02x %02x ;; %04x %04x\n",
   1845 	    device_xname(sc->sc_dev), rawlimitshigh, limitskcrchigh,
   1846 	    limitscrchigh, rawlimitslow, limitskcrclow, limitscrclow,
   1847 	    rawlimitshighclear, rawlimitslowclear));
   1848 
   1849 	switch (edata->sensor) {
   1850 	case SHT3X_TEMP_SENSOR:
   1851 		limithigh = sht3x_compute_raw_from_temp(limits->sel_critmax);
   1852 		limitlow = sht3x_compute_raw_from_temp(limits->sel_critmin);
   1853 		limithigh = limithigh >> 7;
   1854 		limithighminusone = limithigh - 1;
   1855 		limitlow = limitlow >> 7;
   1856 		limitlowplusone = limitlow + 1;
   1857 		rawlimitshigh = (rawlimitshigh & 0xFE00) | limithigh;
   1858 		rawlimitshighminusone = (rawlimitshigh & 0xFE00) |
   1859 		    limithighminusone;
   1860 		rawlimitslow = (rawlimitslow & 0xFE00) | limitlow;
   1861 		rawlimitslowplusone = (rawlimitslow & 0xFE00) | limitlowplusone;
   1862 		DPRINTF(sc, 2, ("%s: Temp new raw limits high/low "
   1863 		    "%04x %04x %04x %04x\n",
   1864 		    device_xname(sc->sc_dev), rawlimitshigh, rawlimitslow,
   1865 		    rawlimitshighminusone, rawlimitslowplusone));
   1866 		sht3x_set_alert_limits2(sc, rawlimitshigh, rawlimitslow,
   1867 		    rawlimitshighminusone, rawlimitslowplusone, true);
   1868 		break;
   1869 	case SHT3X_HUMIDITY_SENSOR:
   1870 		limithigh = sht3x_compute_raw_from_rh(limits->sel_critmax);
   1871 		limitlow = sht3x_compute_raw_from_rh(limits->sel_critmin);
   1872 		limithigh = limithigh & 0xFE00;
   1873 		limitlow = limitlow & 0xFE00;
   1874 		rawlimitshigh = (rawlimitshigh & 0x1FF) | limithigh;
   1875 		rawlimitslow = (rawlimitslow & 0x1FF) | limitlow;
   1876 		DPRINTF(sc, 2, ("%s: RH new raw limits high/low "
   1877 		    "%04x %04x from %x %x\n",
   1878 		    device_xname(sc->sc_dev), rawlimitshigh, rawlimitslow,
   1879 		    limithigh, limitlow));
   1880 		sht3x_set_alert_limits(sc, rawlimitshigh, rawlimitslow, true);
   1881 		break;
   1882 	default:
   1883 		break;
   1884 	}
   1885 
   1886 	iic_release_bus(sc->sc_tag, 0);
   1887  out:
   1888 	mutex_exit(&sc->sc_mutex);
   1889 }
   1890 #endif
   1891 
   1892 static int
   1893 sht3xopen(dev_t dev, int flags, int fmt, struct lwp *l)
   1894 {
   1895 	struct sht3x_sc *sc;
   1896 
   1897 	sc = device_lookup_private(&sht3xtemp_cd, minor(dev));
   1898 	if (!sc)
   1899 		return ENXIO;
   1900 
   1901 	if (sc->sc_opened)
   1902 		return EBUSY;
   1903 
   1904 	mutex_enter(&sc->sc_mutex);
   1905 	sc->sc_opened = true;
   1906 
   1907 	sc->sc_wassingleshot = false;
   1908 	if (!sc->sc_isperiodic) {
   1909 		sc->sc_stopping = false;
   1910 		sc->sc_initperiodic = true;
   1911 		sc->sc_isperiodic = true;
   1912 		sc->sc_wassingleshot = true;
   1913 		sht3x_start_thread(sc);
   1914 	}
   1915 	mutex_exit(&sc->sc_mutex);
   1916 
   1917 	return 0;
   1918 }
   1919 
   1920 static int
   1921 sht3xread(dev_t dev, struct uio *uio, int flags)
   1922 {
   1923 	struct sht3x_sc *sc;
   1924 	struct sht3x_read_q *pp;
   1925 	int error,any;
   1926 
   1927 	sc = device_lookup_private(&sht3xtemp_cd, minor(dev));
   1928 	if (!sc)
   1929 		return ENXIO;
   1930 
   1931 	while (uio->uio_resid) {
   1932 		any = 0;
   1933 		error = 0;
   1934 		mutex_enter(&sc->sc_read_mutex);
   1935 
   1936 		while (any == 0) {
   1937 			pp = SIMPLEQ_FIRST(&sc->sc_read_queue);
   1938 			if (pp != NULL) {
   1939 				SIMPLEQ_REMOVE_HEAD(&sc->sc_read_queue, read_q);
   1940 				any = 1;
   1941 				break;
   1942 			}
   1943 			error = cv_wait_sig(&sc->sc_condreadready,
   1944 			    &sc->sc_read_mutex);
   1945 			if (sc->sc_dying)
   1946 				error = EIO;
   1947 			if (error == 0)
   1948 				continue;
   1949 			break;
   1950 		}
   1951 
   1952 		if (any == 1 && error == 0) {
   1953 			uint8_t *p = pp->measurement;
   1954 			mutex_exit(&sc->sc_read_mutex);
   1955 			pool_cache_put(sc->sc_readpool,pp);
   1956 
   1957 			DPRINTF(sc,2, ("%s: sending %02x%02x %02x -- %02x%02x "
   1958 			    "%02x -- %x\n", device_xname(sc->sc_dev), p[0],
   1959 			    p[1], p[2], p[3], p[4], p[5],
   1960 			    mutex_owned(&sc->sc_read_mutex)));
   1961 			if ((error = uiomove(pp->measurement,
   1962 			    sizeof(pp->measurement), uio)) != 0) {
   1963 				DPRINTF(sc,2, ("%s: send error %d\n",
   1964 				    device_xname(sc->sc_dev), error));
   1965 				break;
   1966 			}
   1967 		} else {
   1968 			mutex_exit(&sc->sc_read_mutex);
   1969 			if (error) {
   1970 				break;
   1971 			}
   1972 		}
   1973 	}
   1974 
   1975 	DPRINTF(sc,2, ("%s: loop done: %d\n",device_xname(sc->sc_dev),error));
   1976 	if (sc->sc_dying) {
   1977 		DPRINTF(sc, 2, ("%s: Telling all we are almost dead\n",
   1978 		    device_xname(sc->sc_dev)));
   1979 		mutex_enter(&sc->sc_dying_mutex);
   1980 		cv_signal(&sc->sc_cond_dying);
   1981 		mutex_exit(&sc->sc_dying_mutex);
   1982 	}
   1983 	return error;
   1984 }
   1985 
   1986 static int
   1987 sht3xclose(dev_t dev, int flags, int fmt, struct lwp *l)
   1988 {
   1989 	struct sht3x_sc *sc;
   1990 	struct sht3x_read_q *pp;
   1991 
   1992 	sc = device_lookup_private(&sht3xtemp_cd, minor(dev));
   1993 
   1994 	if (sc->sc_wassingleshot) {
   1995 		sht3x_stop_thread(sc);
   1996 		sc->sc_stopping = false;
   1997 		sc->sc_initperiodic = false;
   1998 		sc->sc_isperiodic = false;
   1999 	}
   2000 
   2001 	mutex_enter(&sc->sc_mutex);
   2002 	/* Drain any read pools */
   2003 	while ((pp = SIMPLEQ_FIRST(&sc->sc_read_queue)) != NULL) {
   2004 		SIMPLEQ_REMOVE_HEAD(&sc->sc_read_queue, read_q);
   2005 		pool_cache_put(sc->sc_readpool,pp);
   2006 	}
   2007 
   2008 	/* Say that the device is now free */
   2009 	sc->sc_opened = false;
   2010 	mutex_exit(&sc->sc_mutex);
   2011 
   2012 	return(0);
   2013 }
   2014 
   2015 static int
   2016 sht3x_detach(device_t self, int flags)
   2017 {
   2018 	struct sht3x_sc *sc;
   2019 	struct sht3x_read_q *pp;
   2020 
   2021 	sc = device_private(self);
   2022 
   2023 	if (sc->sc_isperiodic) {
   2024 		sht3x_stop_thread(sc);
   2025 	}
   2026 
   2027 	mutex_enter(&sc->sc_mutex);
   2028 
   2029 	sc->sc_dying = true;
   2030 
   2031 	/* If this is true we are still open, destroy the condvar */
   2032 	if (sc->sc_opened) {
   2033 		mutex_enter(&sc->sc_dying_mutex);
   2034 		mutex_enter(&sc->sc_read_mutex);
   2035 		cv_signal(&sc->sc_condreadready);
   2036 		mutex_exit(&sc->sc_read_mutex);
   2037 		DPRINTF(sc, 2, ("%s: Will wait for anything to exit\n",
   2038 		    device_xname(sc->sc_dev)));
   2039 		cv_timedwait_sig(&sc->sc_cond_dying,
   2040 		    &sc->sc_dying_mutex, mstohz(5000));
   2041 		mutex_exit(&sc->sc_dying_mutex);
   2042 		cv_destroy(&sc->sc_condreadready);
   2043 		cv_destroy(&sc->sc_cond_dying);
   2044 	}
   2045 
   2046 	/* Drain any read pools */
   2047 	while ((pp = SIMPLEQ_FIRST(&sc->sc_read_queue)) != NULL) {
   2048 		SIMPLEQ_REMOVE_HEAD(&sc->sc_read_queue, read_q);
   2049 		pool_cache_put(sc->sc_readpool,pp);
   2050 	}
   2051 
   2052 	/* Destroy the pool cache now that nothing is using it */
   2053 	pool_cache_destroy(sc->sc_readpool);
   2054 
   2055 	/* Remove the sensors */
   2056 	if (sc->sc_sme != NULL) {
   2057 		sysmon_envsys_unregister(sc->sc_sme);
   2058 		sc->sc_sme = NULL;
   2059 	}
   2060 	mutex_exit(&sc->sc_mutex);
   2061 
   2062 	/* Remove the sysctl tree */
   2063 	sysctl_teardown(&sc->sc_sht3xlog);
   2064 
   2065 	/* Remove the mutex */
   2066 	mutex_destroy(&sc->sc_mutex);
   2067 	mutex_destroy(&sc->sc_threadmutex);
   2068 	mutex_destroy(&sc->sc_read_mutex);
   2069 	mutex_destroy(&sc->sc_dying_mutex);
   2070 
   2071 	/* Free the poolname string */
   2072         if (sc->sc_readpoolname != NULL) {
   2073                 kmem_free(sc->sc_readpoolname,strlen(sc->sc_readpoolname) + 1);
   2074         }
   2075 
   2076 	return 0;
   2077 }
   2078 
   2079 int
   2080 sht3x_activate(device_t self, enum devact act)
   2081 {
   2082 	struct sht3x_sc *sc = device_private(self);
   2083 
   2084 	switch (act) {
   2085 	case DVACT_DEACTIVATE:
   2086 		sc->sc_dying = true;
   2087 		return 0;
   2088 	default:
   2089 		return EOPNOTSUPP;
   2090 	}
   2091 }
   2092 
   2093 MODULE(MODULE_CLASS_DRIVER, sht3xtemp, "i2cexec,sysmon_envsys");
   2094 
   2095 #ifdef _MODULE
   2096 #include "ioconf.c"
   2097 #endif
   2098 
   2099 static int
   2100 sht3xtemp_modcmd(modcmd_t cmd, void *opaque)
   2101 {
   2102 	int error;
   2103 #ifdef _MODULE
   2104 	int bmaj = -1, cmaj = -1;
   2105 #endif
   2106 
   2107 	switch (cmd) {
   2108 	case MODULE_CMD_INIT:
   2109 #ifdef _MODULE
   2110 		error = config_init_component(cfdriver_ioconf_sht3xtemp,
   2111 		    cfattach_ioconf_sht3xtemp, cfdata_ioconf_sht3xtemp);
   2112 		if (error)
   2113 			aprint_error("%s: unable to init component\n",
   2114 			    sht3xtemp_cd.cd_name);
   2115 
   2116 		error = devsw_attach("sht3xtemp", NULL, &bmaj,
   2117 		    &sht3x_cdevsw, &cmaj);
   2118 		if (error) {
   2119 			aprint_error("%s: unable to attach devsw\n",
   2120 			    sht3xtemp_cd.cd_name);
   2121 			config_fini_component(cfdriver_ioconf_sht3xtemp,
   2122 			    cfattach_ioconf_sht3xtemp, cfdata_ioconf_sht3xtemp);
   2123 		}
   2124 		return error;
   2125 #else
   2126 		return 0;
   2127 #endif
   2128 	case MODULE_CMD_FINI:
   2129 #ifdef _MODULE
   2130 		devsw_detach(NULL, &sht3x_cdevsw);
   2131 		return config_fini_component(cfdriver_ioconf_sht3xtemp,
   2132 		      cfattach_ioconf_sht3xtemp, cfdata_ioconf_sht3xtemp);
   2133 #else
   2134 		return 0;
   2135 #endif
   2136 	default:
   2137 		return ENOTTY;
   2138 	}
   2139 }
   2140