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