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