xref: /netbsd-src/sys/dev/i2c/sht3x.c (revision ccd9df534e375a4366c5b55f23782053c7a98d82)
1 
2 /*	$NetBSD: sht3x.c,v 1.7 2022/04/27 23:11:25 brad Exp $	*/
3 
4 /*
5  * Copyright (c) 2021 Brad Spencer <brad@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.7 2022/04/27 23:11:25 brad 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 static int 	sht3x_verify_sysctl(SYSCTLFN_ARGS);
56 static int 	sht3x_verify_sysctl_heateron(SYSCTLFN_ARGS);
57 static int 	sht3x_verify_sysctl_modes(SYSCTLFN_ARGS);
58 static int 	sht3x_verify_sysctl_repeatability(SYSCTLFN_ARGS);
59 static int 	sht3x_verify_sysctl_rate(SYSCTLFN_ARGS);
60 static int	sht3x_set_heater(struct sht3x_sc *);
61 static void     sht3x_thread(void *);
62 static int	sht3x_init_periodic_measurement(void *, int *);
63 static void     sht3x_take_periodic_measurement(void *);
64 static void     sht3x_start_thread(void *);
65 static void     sht3x_stop_thread(void *);
66 static int	sht3x_activate(device_t, enum devact);
67 
68 #define SHT3X_DEBUG
69 #ifdef SHT3X_DEBUG
70 #define DPRINTF(s, l, x) \
71     do { \
72 	if (l <= s->sc_sht3xdebug) \
73 	    printf x; \
74     } while (/*CONSTCOND*/0)
75 #else
76 #define DPRINTF(s, l, x)
77 #endif
78 
79 CFATTACH_DECL_NEW(sht3xtemp, sizeof(struct sht3x_sc),
80     sht3x_match, sht3x_attach, sht3x_detach, sht3x_activate);
81 
82 extern struct cfdriver sht3xtemp_cd;
83 
84 static dev_type_open(sht3xopen);
85 static dev_type_read(sht3xread);
86 static dev_type_close(sht3xclose);
87 const struct cdevsw sht3x_cdevsw = {
88 	.d_open = sht3xopen,
89 	.d_close = sht3xclose,
90 	.d_read = sht3xread,
91 	.d_write = nowrite,
92 	.d_ioctl = noioctl,
93 	.d_stop = nostop,
94 	.d_tty = notty,
95 	.d_poll = nopoll,
96 	.d_mmap = nommap,
97 	.d_kqfilter = nokqfilter,
98 	.d_discard = nodiscard,
99 	.d_flag = D_OTHER
100 };
101 
102 static struct sht3x_sensor sht3x_sensors[] = {
103 	{
104 		.desc = "humidity",
105 		.type = ENVSYS_SRELHUMIDITY,
106 	},
107 	{
108 		.desc = "temperature",
109 		.type = ENVSYS_STEMP,
110 	}
111 };
112 
113 /* The typical delays are MOSTLY documented in the datasheet for the chip.
114    There is no need to be very accurate with these, just rough estimates
115    will work fine.
116 */
117 
118 static struct sht3x_timing sht3x_timings[] = {
119 	{
120 		.cmd = SHT3X_SOFT_RESET,
121 		.typicaldelay = 3000,
122 	},
123 	{
124 		.cmd = SHT3X_GET_STATUS_REGISTER,
125 		.typicaldelay = 100,
126 	},
127 	{
128 		.cmd = SHT3X_BREAK,
129 		.typicaldelay = 100,
130 	},
131 	{
132 		.cmd = SHT3X_CLEAR_STATUS_REGISTER,
133 		.typicaldelay = 100,
134 	},
135 	{
136 		.cmd = SHT3X_MEASURE_REPEATABILITY_CS_HIGH,
137 		.typicaldelay = 15000,
138 	},
139 	{
140 		.cmd = SHT3X_MEASURE_REPEATABILITY_CS_MEDIUM,
141 		.typicaldelay = 6000,
142 	},
143 	{
144 		.cmd = SHT3X_MEASURE_REPEATABILITY_CS_LOW,
145 		.typicaldelay = 4000,
146 	},
147 	{
148 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_HIGH,
149 		.typicaldelay = 15000,
150 	},
151 	{
152 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_MEDIUM,
153 		.typicaldelay = 6000,
154 	},
155 	{
156 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_LOW,
157 		.typicaldelay = 4000,
158 	},
159 	{
160 		.cmd = SHT3X_WRITE_HIGH_ALERT_SET,
161 		.typicaldelay = 5000,
162 	},
163 	{
164 		.cmd = SHT3X_WRITE_HIGH_ALERT_CLEAR,
165 		.typicaldelay = 5000,
166 	},
167 	{
168 		.cmd = SHT3X_WRITE_LOW_ALERT_SET,
169 		.typicaldelay = 5000,
170 	},
171 	{
172 		.cmd = SHT3X_WRITE_LOW_ALERT_CLEAR,
173 		.typicaldelay = 5000,
174 	}
175 };
176 
177 /* In single shot mode, find the command */
178 
179 static struct sht3x_repeatability sht3x_repeatability_ss[] = {
180 	{
181 		.text = "high",
182 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_HIGH,
183 	},
184 	{
185 		.text = "medium",
186 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_MEDIUM,
187 	},
188 	{
189 		.text = "low",
190 		.cmd = SHT3X_MEASURE_REPEATABILITY_NOCS_LOW,
191 	}
192 };
193 
194 
195 /* For periodic, look at the repeatability and the rate.
196  * ART is a bit fake here, as the repeatability is not really
197  * used.
198  */
199 
200 static struct sht3x_periodic sht3x_periodic_rate[] = {
201 	{
202 		.repeatability = "high",
203 		.rate = "0.5mps",
204 		.sdelay = 1000,
205 		.cmd = SHT3X_HALF_MPS_HIGH,
206 	},
207 	{
208 		.repeatability = "medium",
209 		.rate = "0.5mps",
210 		.sdelay = 1000,
211 		.cmd = SHT3X_HALF_MPS_MEDIUM,
212 	},
213 	{
214 		.repeatability = "low",
215 		.rate = "0.5mps",
216 		.sdelay = 1000,
217 		.cmd = SHT3X_HALF_MPS_LOW,
218 	},
219 	{
220 		.repeatability = "high",
221 		.rate = "1.0mps",
222 		.sdelay = 500,
223 		.cmd = SHT3X_ONE_MPS_HIGH,
224 	},
225 	{
226 		.repeatability = "medium",
227 		.rate = "1.0mps",
228 		.sdelay = 500,
229 		.cmd = SHT3X_ONE_MPS_MEDIUM,
230 	},
231 	{
232 		.repeatability = "low",
233 		.rate = "1.0mps",
234 		.sdelay = 500,
235 		.cmd = SHT3X_ONE_MPS_LOW,
236 	},
237 	{
238 		.repeatability = "high",
239 		.rate = "2.0mps",
240 		.sdelay = 250,
241 		.cmd = SHT3X_TWO_MPS_HIGH,
242 	},
243 	{
244 		.repeatability = "medium",
245 		.rate = "2.0mps",
246 		.sdelay = 250,
247 		.cmd = SHT3X_TWO_MPS_MEDIUM,
248 	},
249 	{
250 		.repeatability = "low",
251 		.rate = "2.0mps",
252 		.sdelay = 250,
253 		.cmd = SHT3X_TWO_MPS_LOW,
254 	},
255 	{
256 		.repeatability = "high",
257 		.rate = "4.0mps",
258 		.sdelay = 100,
259 		.cmd = SHT3X_FOUR_MPS_HIGH,
260 	},
261 	{
262 		.repeatability = "medium",
263 		.rate = "4.0mps",
264 		.sdelay = 100,
265 		.cmd = SHT3X_FOUR_MPS_MEDIUM,
266 	},
267 	{
268 		.repeatability = "low",
269 		.rate = "4.0mps",
270 		.sdelay = 100,
271 		.cmd = SHT3X_FOUR_MPS_LOW,
272 	},
273 	{
274 		.repeatability = "high",
275 		.rate = "10.0mps",
276 		.sdelay = 50,
277 		.cmd = SHT3X_TEN_MPS_HIGH,
278 	},
279 	{
280 		.repeatability = "medium",
281 		.rate = "10.0mps",
282 		.sdelay = 50,
283 		.cmd = SHT3X_FOUR_MPS_MEDIUM,
284 	},
285 	{
286 		.repeatability = "low",
287 		.rate = "10.0mps",
288 		.sdelay = 50,
289 		.cmd = SHT3X_FOUR_MPS_LOW,
290 	},
291 	{
292 		.repeatability = "high",
293 		.rate = "ART",
294 		.sdelay = 100,
295 		.cmd = SHT3X_ART_ENABLE,
296 	},
297 	{
298 		.repeatability = "medium",
299 		.rate = "ART",
300 		.sdelay = 100,
301 		.cmd = SHT3X_ART_ENABLE,
302 	},
303 	{
304 		.repeatability = "low",
305 		.rate = "ART",
306 		.sdelay = 100,
307 		.cmd = SHT3X_ART_ENABLE,
308 	}
309 };
310 
311 static const char sht3x_rate_names[] =
312     "0.5mps, 1.0mps, 2.0mps, 4.0mps, 10.0mps, ART";
313 
314 static const char sht3x_mode_names[] =
315     "single-shot, periodic";
316 
317 static const char sht3x_repeatability_names[] =
318     "high, medium, low";
319 
320 static int
321 sht3x_take_break(void *aux, bool have_bus)
322 {
323 	struct sht3x_sc *sc;
324 	sc = aux;
325 	int error = 0;
326 
327 	if (! have_bus) {
328 		error = iic_acquire_bus(sc->sc_tag, 0);
329 		if (error) {
330 			DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
331 			    "breaking %d\n", device_xname(sc->sc_dev), error));
332 			goto out;
333 		}
334 	}
335 	error = sht3x_cmdr(sc, SHT3X_BREAK, NULL, 0);
336 	if (error) {
337 		DPRINTF(sc, 2, ("%s: Error breaking: %d\n",
338 		    device_xname(sc->sc_dev), error));
339 	}
340 out:
341 	if (! have_bus) {
342 		iic_release_bus(sc->sc_tag, 0);
343 	}
344 
345 	sc->sc_isperiodic = false;
346 	strlcpy(sc->sc_mode, "single-shot", SHT3X_MODE_NAME);
347 
348 	return error;
349 }
350 
351 static int
352 sht3x_get_status_register(void *aux, uint16_t *reg, bool have_bus)
353 {
354 	struct sht3x_sc *sc = aux;
355 	uint8_t buf[3];
356 	int error;
357 
358 	if (! have_bus) {
359 		error = iic_acquire_bus(sc->sc_tag, 0);
360 		if (error) {
361 			DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
362 			    "getting status %d\n", device_xname(sc->sc_dev),
363 			    error));
364 			return error;
365 		}
366 	}
367 	error = sht3x_cmdr(sc, SHT3X_GET_STATUS_REGISTER, buf, 3);
368 	if (error) {
369 		DPRINTF(sc, 2, ("%s: Error getting status: %d\n",
370 		    device_xname(sc->sc_dev), error));
371 		goto out;
372 	}
373 
374 	uint8_t c = sht3x_crc(&buf[0], 2);
375 	if (c == buf[2]) {
376 		*reg = buf[0] << 8 | buf[1];
377 	} else {
378 		error = EINVAL;
379 	}
380 out:
381 	if (! have_bus) {
382 		iic_release_bus(sc->sc_tag, 0);
383 	}
384 
385 	return error;
386 }
387 
388 static int
389 sht3x_clear_status_register(void *aux, bool have_bus)
390 {
391 	struct sht3x_sc *sc = aux;
392 	int error;
393 
394 	if (! have_bus) {
395 		error = iic_acquire_bus(sc->sc_tag, 0);
396 		if (error) {
397 			DPRINTF(sc, 2, ("%s: Could not acquire iic bus for "
398 			    "clearing status %d\n", device_xname(sc->sc_dev),
399 			    error));
400 			return error;
401 		}
402 	}
403 	error = sht3x_cmdr(sc, SHT3X_CLEAR_STATUS_REGISTER, NULL, 0);
404 	if (error) {
405 		DPRINTF(sc, 2, ("%s: Error clear status register: %d\n",
406 		    device_xname(sc->sc_dev), error));
407 	}
408 	if (! have_bus) {
409 		iic_release_bus(sc->sc_tag, 0);
410 	}
411 
412 	return error;
413 }
414 
415 void
416 sht3x_thread(void *aux)
417 {
418 	struct sht3x_sc *sc = aux;
419 	int error, rv;
420 	int sdelay = 100;
421 
422 	mutex_enter(&sc->sc_threadmutex);
423 
424 	while (!sc->sc_stopping && !sc->sc_dying) {
425 		if (sc->sc_initperiodic) {
426 			error = sht3x_init_periodic_measurement(sc, &sdelay);
427 			if (error) {
428 				DPRINTF(sc, 2, ("%s: Error initing periodic "
429 				    "measurement in thread: %d\n",
430 				    device_xname(sc->sc_dev), error));
431 			}
432 			sc->sc_initperiodic = false;
433 		}
434 		rv = cv_timedwait(&sc->sc_condvar, &sc->sc_threadmutex,
435 		    mstohz(sdelay));
436 		if (rv == EWOULDBLOCK && !sc->sc_stopping &&
437 		    !sc->sc_initperiodic && !sc->sc_dying) {
438 			sht3x_take_periodic_measurement(sc);
439 		}
440 	}
441 	mutex_exit(&sc->sc_threadmutex);
442 	kthread_exit(0);
443 }
444 
445 int
446 sht3x_init_periodic_measurement(void *aux, int *sdelay)
447 {
448 	struct sht3x_sc *sc = aux;
449 	size_t i;
450 	int error;
451 	uint16_t r;
452 
453 	for (i = 0; i < __arraycount(sht3x_periodic_rate); i++) {
454 		if (strncmp(sc->sc_repeatability,
455 		    sht3x_periodic_rate[i].repeatability, SHT3X_REP_NAME) == 0 &&
456 		    strncmp(sc->sc_periodic_rate, sht3x_periodic_rate[i].rate,
457 		    SHT3X_RATE_NAME) == 0)
458 		{
459 			r = sht3x_periodic_rate[i].cmd;
460 			*sdelay = sht3x_periodic_rate[i].sdelay;
461 			break;
462 		}
463 	}
464 
465 	if (i == __arraycount(sht3x_periodic_rate)) {
466 		*sdelay = 100;
467 		return ENODEV;
468 	}
469 
470 	DPRINTF(sc, 2, ("%s: Would init with: %x\n",
471 	    device_xname(sc->sc_dev), r));
472 
473 	mutex_enter(&sc->sc_mutex);
474 
475 	error = iic_acquire_bus(sc->sc_tag, 0);
476 	if (error) {
477 		DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: "
478 		    " %d\n", device_xname(sc->sc_dev), error));
479 		goto outm;
480 	}
481 
482 	error = sht3x_take_break(sc, true);
483 	if (error) {
484 	    DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: "
485 		" %d\n", device_xname(sc->sc_dev), error));
486 	    goto out;
487 	}
488 
489 	error = sht3x_cmdr(sc, r, NULL, 0);
490 	if (error) {
491 		DPRINTF(sc, 2,
492 		    ("%s: Error sending periodic measurement command: %d\n",
493 		    device_xname(sc->sc_dev), error));
494 		goto out;
495 	}
496 
497 	sc->sc_isperiodic = true;
498 	strlcpy(sc->sc_mode, "periodic", SHT3X_MODE_NAME);
499 
500 out:
501 	iic_release_bus(sc->sc_tag, 0);
502 outm:
503 	mutex_exit(&sc->sc_mutex);
504 	return error;
505 }
506 
507 static void
508 sht3x_take_periodic_measurement(void *aux)
509 {
510 	struct sht3x_sc *sc = aux;
511 	int error;
512 	struct sht3x_read_q *pp;
513 	uint8_t rawbuf[MAX(sizeof(sc->sc_pbuffer), sizeof(pp->measurement))];
514 	uint16_t status_reg;
515 
516 	mutex_enter(&sc->sc_mutex);
517 	error = iic_acquire_bus(sc->sc_tag, 0);
518 	if (error) {
519 		DPRINTF(sc, 2, ("%s: Could not acquire iic bus for getting "
520 		    "periodic data: %d\n", device_xname(sc->sc_dev), error));
521 		goto out;
522 	}
523 
524 	error = sht3x_get_status_register(sc, &status_reg, true);
525 	if (error) {
526 		DPRINTF(sc, 2,
527 		    ("%s: Error getting status register periodic: %d\n",
528 		    device_xname(sc->sc_dev), error));
529 		goto err;
530 	}
531 
532 	if (status_reg & SHT3X_RESET_DETECTED) {
533 		aprint_error_dev(sc->sc_dev, "Reset detected in periodic mode. "
534 		    "Heater may have been reset.\n");
535 		delay(3000);
536 		sht3x_take_break(sc, true);
537 		sht3x_clear_status_register(sc, true);
538 		sc->sc_heateron = status_reg & SHT3X_HEATER_STATUS;
539 		sc->sc_initperiodic = true;
540 	} else {
541 		int data_error = sht3x_cmdr(sc, SHT3X_PERIODIC_FETCH_DATA,
542 		    rawbuf, sizeof(rawbuf));
543 		/*
544 		 * EIO is actually expected if the poll interval is faster
545 		 * than the rate that the sensor is set to.  Unfortunally,
546 		 * this will also mess with the ability to detect an actual
547 		 * problem with the sensor in periodic mode, so we do the best
548 		 * we can here.
549 		 */
550 		if (data_error) {
551 			if (data_error != EIO) {
552 				DPRINTF(sc, 2, ("%s: Error sending periodic "
553 				    "fetch command: %d\n",
554 				    device_xname(sc->sc_dev), data_error));
555 			}
556 			goto err;
557 		}
558 	}
559 
560 	iic_release_bus(sc->sc_tag, 0);
561 	/*
562 	 * If there was no errors from anything then the data should be
563 	 * valid.
564 	 */
565 	DPRINTF(sc, 2, ("%s: Raw periodic: %x%x - %x -- %x%x - %x\n",
566 	    device_xname(sc->sc_dev), rawbuf[0], rawbuf[1], rawbuf[2],
567 	    rawbuf[3], rawbuf[4], rawbuf[5]));
568 	memcpy(sc->sc_pbuffer, rawbuf, sizeof(sc->sc_pbuffer));
569 
570 	if (sc->sc_opened) {
571 		mutex_enter(&sc->sc_read_mutex);
572 		pp = pool_cache_get(sc->sc_readpool, PR_NOWAIT);
573 		if (pp == NULL) {
574 			aprint_error_dev(sc->sc_dev,
575 			    "Could not allocate memory for pool read\n");
576 		} else {
577 			memcpy(pp->measurement, rawbuf, sizeof(pp->measurement));
578 			DPRINTF(sc, 4, ("%s: Queue insert\n",
579 			    device_xname(sc->sc_dev)));
580 			SIMPLEQ_INSERT_HEAD(&sc->sc_read_queue, pp, read_q);
581 		}
582 		cv_signal(&sc->sc_condreadready);
583 		mutex_exit(&sc->sc_read_mutex);
584 	}
585 out:
586 	mutex_exit(&sc->sc_mutex);
587 	return;
588 err:
589 	/*
590 	 * We are only going to worry about errors when it was not related
591 	 * to actually getting data.  That is a likely indicator of a problem
592 	 * with the sensor.
593 	 */
594 	DPRINTF(sc, 2, ("%s: Raw periodic with error: %x%x - %x -- "
595 	    "%x%x - %x -- %d\n", device_xname(sc->sc_dev), rawbuf[0], rawbuf[1],
596 	    rawbuf[2], rawbuf[3], rawbuf[4], rawbuf[5], error));
597 	iic_release_bus(sc->sc_tag, 0);
598 	if (error != 0) {
599 		memcpy(sc->sc_pbuffer, "dedbef", sizeof(sc->sc_pbuffer));
600 	}
601 	mutex_exit(&sc->sc_mutex);
602 }
603 
604 static void
605 sht3x_stop_thread(void *aux)
606 {
607 	struct sht3x_sc *sc;
608 	sc = aux;
609 
610 	if (!sc->sc_isperiodic) {
611 		return;
612 	}
613 
614 	mutex_enter(&sc->sc_threadmutex);
615 	sc->sc_stopping = true;
616 	cv_signal(&sc->sc_condvar);
617 	mutex_exit(&sc->sc_threadmutex);
618 
619 	/* wait for the thread to exit */
620 	kthread_join(sc->sc_thread);
621 
622 	mutex_enter(&sc->sc_mutex);
623 	sht3x_take_break(sc,false);
624 	mutex_exit(&sc->sc_mutex);
625 }
626 
627 static void
628 sht3x_start_thread(void *aux)
629 {
630 	struct sht3x_sc *sc;
631 	sc = aux;
632 	int error;
633 
634 	error = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN, NULL,
635 	    sht3x_thread, sc, &sc->sc_thread, "%s", device_xname(sc->sc_dev));
636 	if (error) {
637 		DPRINTF(sc, 2, ("%s: Unable to create measurement thread: %d\n",
638 		    device_xname(sc->sc_dev), error));
639 	}
640 }
641 
642 int
643 sht3x_verify_sysctl(SYSCTLFN_ARGS)
644 {
645 	int error, t;
646 	struct sysctlnode node;
647 
648 	node = *rnode;
649 	t = *(int *)rnode->sysctl_data;
650 	node.sysctl_data = &t;
651 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
652 	if (error || newp == NULL)
653 		return error;
654 
655 	if (t < 0)
656 		return EINVAL;
657 
658 	*(int *)rnode->sysctl_data = t;
659 
660 	return 0;
661 }
662 
663 int
664 sht3x_verify_sysctl_heateron(SYSCTLFN_ARGS)
665 {
666 	int 		error;
667 	bool 		t;
668 	struct sht3x_sc *sc;
669 	struct sysctlnode node;
670 
671 	node = *rnode;
672 	sc = node.sysctl_data;
673 	t = sc->sc_heateron;
674 	node.sysctl_data = &t;
675 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
676 	if (error || newp == NULL)
677 		return error;
678 
679 	sc->sc_heateron = t;
680 	error = sht3x_set_heater(sc);
681 
682 	return error;
683 }
684 
685 static int
686 sht3x_set_heater(struct sht3x_sc *sc)
687 {
688 	int error = 0;
689 	uint16_t cmd;
690 
691 	mutex_enter(&sc->sc_mutex);
692 	error = iic_acquire_bus(sc->sc_tag, 0);
693 	if (error) {
694 		DPRINTF(sc, 2, ("%s:%s: Failed to acquire bus: %d\n",
695 		    device_xname(sc->sc_dev), __func__, error));
696 		goto out;
697 	}
698 
699 	if (sc->sc_heateron) {
700 		cmd = SHT3X_HEATER_ENABLE;
701 	} else {
702 		cmd = SHT3X_HEATER_DISABLE;
703 	}
704 
705 	error = sht3x_cmdr(sc, cmd, NULL, 0);
706 
707 	iic_release_bus(sc->sc_tag,0);
708 out:
709 	mutex_exit(&sc->sc_mutex);
710 
711 	return error;
712 }
713 
714 int
715 sht3x_verify_sysctl_modes(SYSCTLFN_ARGS)
716 {
717 	char buf[SHT3X_MODE_NAME];
718 	struct sht3x_sc *sc;
719 	struct sysctlnode node;
720 	bool is_ss = false;
721 	bool is_periodic = false;
722 	int error;
723 
724 	node = *rnode;
725 	sc = node.sysctl_data;
726 	(void) memcpy(buf, sc->sc_mode, SHT3X_MODE_NAME);
727 	node.sysctl_data = buf;
728 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
729 	if (error || newp == NULL)
730 		return error;
731 
732 	if (sc->sc_opened) {
733 		return EINVAL;
734 	}
735 
736 	is_ss = strncmp(node.sysctl_data, "single-shot", SHT3X_MODE_NAME) == 0;
737 	is_periodic = strncmp(node.sysctl_data, "periodic", SHT3X_MODE_NAME)
738 	    == 0;
739 
740 	if (!is_ss && !is_periodic) {
741 		return EINVAL;
742 	}
743 
744 	(void) memcpy(sc->sc_mode, node.sysctl_data, SHT3X_MODE_NAME);
745 	if (is_ss) {
746 		sht3x_stop_thread(sc);
747 		sc->sc_stopping = false;
748 		sc->sc_initperiodic = false;
749 		sc->sc_isperiodic = false;
750 	}
751 
752 	if (is_periodic) {
753 		sc->sc_stopping = false;
754 		sc->sc_initperiodic = true;
755 		sc->sc_isperiodic = true;
756 		sht3x_start_thread(sc);
757 	}
758 
759 	return 0;
760 }
761 
762 int
763 sht3x_verify_sysctl_repeatability(SYSCTLFN_ARGS)
764 {
765 	char buf[SHT3X_REP_NAME];
766 	struct sht3x_sc *sc;
767 	struct sysctlnode node;
768 	int error;
769 	size_t i;
770 
771 	node = *rnode;
772 	sc = node.sysctl_data;
773 	(void) memcpy(buf, sc->sc_repeatability, SHT3X_REP_NAME);
774 	node.sysctl_data = buf;
775 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
776 	if (error || newp == NULL)
777 		return error;
778 
779 	for (i = 0; i < __arraycount(sht3x_repeatability_ss); i++) {
780 		if (strncmp(node.sysctl_data, sht3x_repeatability_ss[i].text,
781 		    SHT3X_REP_NAME) == 0) {
782 			break;
783 		}
784 	}
785 
786 	if (i == __arraycount(sht3x_repeatability_ss))
787 		return EINVAL;
788 	(void) memcpy(sc->sc_repeatability, node.sysctl_data, SHT3X_REP_NAME);
789 
790 	if (sc->sc_isperiodic) {
791 		sc->sc_initperiodic = true;
792 	}
793 
794 	return error;
795 }
796 
797 int
798 sht3x_verify_sysctl_rate(SYSCTLFN_ARGS)
799 {
800 	char buf[SHT3X_RATE_NAME];
801 	struct sht3x_sc *sc;
802 	struct sysctlnode node;
803 	int error;
804 	size_t i;
805 
806 	node = *rnode;
807 	sc = node.sysctl_data;
808 	(void) memcpy(buf, sc->sc_periodic_rate, SHT3X_RATE_NAME);
809 	node.sysctl_data = buf;
810 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
811 	if (error || newp == NULL)
812 		return error;
813 
814 	for (i = 0; i < __arraycount(sht3x_periodic_rate); i++) {
815 		if (strncmp(node.sysctl_data, sht3x_periodic_rate[i].rate,
816 		    SHT3X_RATE_NAME) == 0) {
817 			break;
818 		}
819 	}
820 
821 	if (i == __arraycount(sht3x_periodic_rate))
822 		return EINVAL;
823 
824 	(void) memcpy(sc->sc_periodic_rate, node.sysctl_data, SHT3X_RATE_NAME);
825 
826 	if (sc->sc_isperiodic) {
827 		sc->sc_initperiodic = true;
828 	}
829 
830 	return error;
831 }
832 
833 static int
834 sht3x_cmddelay(uint16_t cmd)
835 {
836 	size_t i;
837 
838 	for (i = 0; i < __arraycount(sht3x_timings); i++) {
839 		if (cmd == sht3x_timings[i].cmd) {
840 			break;
841 		}
842 	}
843 
844 	if (i == __arraycount(sht3x_timings)) {
845 		return -1;
846 	}
847 	return sht3x_timings[i].typicaldelay;
848 }
849 
850 static int
851 sht3x_cmd(i2c_tag_t tag, i2c_addr_t addr, uint16_t *cmd,
852     uint8_t clen, uint8_t *buf, size_t blen, int readattempts)
853 {
854 	int error;
855 	int cmddelay;
856 	uint8_t cmd8[2];
857 
858 	/* All commands are two bytes and must be in a proper order */
859 	KASSERT(clen == 2);
860 
861 	cmd8[0] = cmd[0] >> 8;
862 	cmd8[1] = cmd[0] & 0x00ff;
863 
864 	error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &cmd8[0], clen,
865 	    NULL, 0, 0);
866 	if (error)
867 		return error;
868 
869 	cmddelay = sht3x_cmddelay(cmd[0]);
870 	if (cmddelay != -1) {
871 		delay(cmddelay);
872 	}
873 
874 	/* Not all commands return anything  */
875 	if (blen == 0) {
876 		return 0;
877 	}
878 
879 	for (int aint = 0; aint < readattempts; aint++) {
880 		error = iic_exec(tag, I2C_OP_READ_WITH_STOP, addr, NULL, 0, buf,
881 		    blen, 0);
882 		if (error == 0)
883 			break;
884 		delay(1000);
885 	}
886 
887 	return error;
888 }
889 
890 static int
891 sht3x_cmdr(struct sht3x_sc *sc, uint16_t cmd, uint8_t *buf, size_t blen)
892 {
893 	return sht3x_cmd(sc->sc_tag, sc->sc_addr, &cmd, 2, buf, blen,
894 	    sc->sc_readattempts);
895 }
896 
897 static	uint8_t
898 sht3x_crc(uint8_t *data, size_t size)
899 {
900 	uint8_t crc = 0xFF;
901 
902 	for (size_t i = 0; i < size; i++) {
903 		crc ^= data[i];
904 		for (size_t j = 8; j > 0; j--) {
905 			if (crc & 0x80)
906 				crc = (crc << 1) ^ 0x31;
907 			else
908 				crc <<= 1;
909 		}
910 	}
911 	return crc;
912 }
913 
914 static int
915 sht3x_poke(i2c_tag_t tag, i2c_addr_t addr, bool matchdebug)
916 {
917 	uint16_t reg = SHT3X_GET_STATUS_REGISTER;
918 	uint8_t buf[3];
919 	int error;
920 
921 	error = sht3x_cmd(tag, addr, &reg, 2, buf, 3, 10);
922 	if (matchdebug) {
923 		printf("poke X 1: %d\n", error);
924 	}
925 	return error;
926 }
927 
928 static int
929 sht3x_sysctl_init(struct sht3x_sc *sc)
930 {
931 	int error;
932 	const struct sysctlnode *cnode;
933 	int sysctlroot_num;
934 
935 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
936 	    0, CTLTYPE_NODE, device_xname(sc->sc_dev),
937 	    SYSCTL_DESCR("sht3x controls"), NULL, 0, NULL, 0, CTL_HW,
938 	    CTL_CREATE, CTL_EOL)) != 0)
939 		return error;
940 
941 	sysctlroot_num = cnode->sysctl_num;
942 
943 #ifdef SHT3X_DEBUG
944 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
945 	    CTLFLAG_READWRITE, CTLTYPE_INT, "debug",
946 	    SYSCTL_DESCR("Debug level"), sht3x_verify_sysctl, 0,
947 	    &sc->sc_sht3xdebug, 0, CTL_HW, sysctlroot_num, CTL_CREATE,
948 	    CTL_EOL)) != 0)
949 		return error;
950 
951 #endif
952 
953 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
954 	    CTLFLAG_READWRITE, CTLTYPE_INT, "readattempts",
955 	    SYSCTL_DESCR("The number of times to attempt to read the values"),
956 	    sht3x_verify_sysctl, 0, &sc->sc_readattempts, 0, CTL_HW,
957 	    sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
958 		return error;
959 
960 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
961 	    CTLFLAG_READONLY, CTLTYPE_STRING, "modes",
962 	    SYSCTL_DESCR("Valid modes"), 0, 0,
963 	    __UNCONST(sht3x_mode_names),
964 	    sizeof(sht3x_mode_names) + 1,
965 	    CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
966 		return error;
967 
968 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
969 	    CTLFLAG_READWRITE, CTLTYPE_STRING, "mode",
970 	    SYSCTL_DESCR("Mode for measurement collection"),
971 	    sht3x_verify_sysctl_modes, 0, (void *) sc,
972 	    SHT3X_MODE_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
973 		return error;
974 
975 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
976 	    CTLFLAG_READONLY, CTLTYPE_STRING, "repeatabilities",
977 	    SYSCTL_DESCR("Valid repeatability values"), 0, 0,
978 	    __UNCONST(sht3x_repeatability_names),
979 	    sizeof(sht3x_repeatability_names) + 1,
980 	    CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
981 		return error;
982 
983 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
984 	    CTLFLAG_READWRITE, CTLTYPE_STRING, "repeatability",
985 	    SYSCTL_DESCR("Repeatability of RH and Temp"),
986 	    sht3x_verify_sysctl_repeatability, 0, (void *) sc,
987 	    SHT3X_REP_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
988 		return error;
989 
990 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
991 	    CTLFLAG_READONLY, CTLTYPE_STRING, "rates",
992 	    SYSCTL_DESCR("Valid peridoic rates"), 0, 0,
993 	    __UNCONST(sht3x_rate_names),
994 	    sizeof(sht3x_rate_names) + 1,
995 	    CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
996 		return error;
997 
998 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
999 	    CTLFLAG_READWRITE, CTLTYPE_STRING, "rate",
1000 	    SYSCTL_DESCR("Rate for periodic measurements"),
1001 	    sht3x_verify_sysctl_rate, 0, (void *) sc,
1002 	    SHT3X_RATE_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
1003 		return error;
1004 
1005 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
1006 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "ignorecrc",
1007 	    SYSCTL_DESCR("Ignore the CRC byte"), NULL, 0, &sc->sc_ignorecrc,
1008 	    0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
1009 		return error;
1010 
1011 	if ((error = sysctl_createv(&sc->sc_sht3xlog, 0, NULL, &cnode,
1012 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "heateron",
1013 	    SYSCTL_DESCR("Heater on"), sht3x_verify_sysctl_heateron, 0,
1014 	    (void *)sc, 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
1015 		return error;
1016 
1017 	return 0;
1018 }
1019 
1020 static int
1021 sht3x_match(device_t parent, cfdata_t match, void *aux)
1022 {
1023 	struct i2c_attach_args *ia = aux;
1024 	int error, match_result;
1025 	const bool matchdebug = false;
1026 
1027 	if (iic_use_direct_match(ia, match, NULL, &match_result))
1028 		return match_result;
1029 
1030 	if (matchdebug) {
1031 		printf("Looking at ia_addr: %x\n",ia->ia_addr);
1032 	}
1033 
1034 	/* indirect config - check for configured address */
1035 	if (ia->ia_addr != SHT3X_TYPICAL_ADDR_1 &&
1036 	    ia->ia_addr != SHT3X_TYPICAL_ADDR_2)
1037 		return 0;
1038 
1039 	/*
1040 	 * Check to see if something is really at this i2c address.
1041 	 * This will keep phantom devices from appearing
1042 	 */
1043 	if (iic_acquire_bus(ia->ia_tag, 0) != 0) {
1044 		if (matchdebug)
1045 			printf("in match acquire bus failed\n");
1046 		return 0;
1047 	}
1048 
1049 	error = sht3x_poke(ia->ia_tag, ia->ia_addr, matchdebug);
1050 	iic_release_bus(ia->ia_tag, 0);
1051 
1052 	return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0;
1053 }
1054 
1055 static void
1056 sht3x_attach(device_t parent, device_t self, void *aux)
1057 {
1058 	struct sht3x_sc *sc;
1059 	struct i2c_attach_args *ia;
1060 	int error, i;
1061 	int ecount = 0;
1062 	uint8_t buf[6];
1063 	uint32_t serialnumber;
1064 	uint8_t sncrcpt1, sncrcpt2;
1065 
1066 	ia = aux;
1067 	sc = device_private(self);
1068 
1069 	sc->sc_dev = self;
1070 	sc->sc_tag = ia->ia_tag;
1071 	sc->sc_addr = ia->ia_addr;
1072 	sc->sc_sht3xdebug = 0;
1073 	strlcpy(sc->sc_mode, "single-shot", SHT3X_MODE_NAME);
1074 	sc->sc_isperiodic = false;
1075 	strlcpy(sc->sc_repeatability, "high", SHT3X_REP_NAME);
1076 	strlcpy(sc->sc_periodic_rate, "1.0mps", SHT3X_RATE_NAME);
1077 	sc->sc_readattempts = 10;
1078 	sc->sc_ignorecrc = false;
1079 	sc->sc_heateron = false;
1080 	sc->sc_sme = NULL;
1081 	sc->sc_stopping = false;
1082 	sc->sc_initperiodic = false;
1083 	sc->sc_opened = false;
1084 	sc->sc_dying = false;
1085 	sc->sc_readpoolname = NULL;
1086 
1087 	aprint_normal("\n");
1088 
1089 	mutex_init(&sc->sc_dying_mutex, MUTEX_DEFAULT, IPL_NONE);
1090 	mutex_init(&sc->sc_read_mutex, MUTEX_DEFAULT, IPL_NONE);
1091 	mutex_init(&sc->sc_threadmutex, MUTEX_DEFAULT, IPL_NONE);
1092 	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE);
1093 	cv_init(&sc->sc_condvar, "sht3xcv");
1094 	cv_init(&sc->sc_condreadready, "sht3xread");
1095 	cv_init(&sc->sc_cond_dying, "sht3xdie");
1096 	sc->sc_numsensors = __arraycount(sht3x_sensors);
1097 
1098 	if ((sc->sc_sme = sysmon_envsys_create()) == NULL) {
1099 		aprint_error_dev(self,
1100 		    "Unable to create sysmon structure\n");
1101 		sc->sc_sme = NULL;
1102 		return;
1103 	}
1104 	if ((error = sht3x_sysctl_init(sc)) != 0) {
1105 		aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", error);
1106 		goto out;
1107 	}
1108 
1109 	sc->sc_readpoolname = kmem_asprintf("sht3xrp%d",device_unit(self));
1110 	sc->sc_readpool = pool_cache_init(sizeof(struct sht3x_read_q), 0, 0, 0,
1111 	    sc->sc_readpoolname, NULL, IPL_VM, NULL, NULL, NULL);
1112 	pool_cache_sethiwat(sc->sc_readpool,100);
1113 
1114 	SIMPLEQ_INIT(&sc->sc_read_queue);
1115 
1116 	error = iic_acquire_bus(sc->sc_tag, 0);
1117 	if (error) {
1118 		aprint_error_dev(self, "Could not acquire iic bus: %d\n",
1119 		    error);
1120 		goto out;
1121 	}
1122 
1123 	error = sht3x_cmdr(sc, SHT3X_SOFT_RESET, NULL, 0);
1124 	if (error != 0)
1125 		aprint_error_dev(self, "Reset failed: %d\n", error);
1126 
1127 	error = sht3x_clear_status_register(sc, true);
1128 	if (error) {
1129 		aprint_error_dev(self, "Failed to clear status register: %d\n",
1130 		    error);
1131 		ecount++;
1132 	}
1133 
1134 	uint16_t status_reg;
1135 	error = sht3x_get_status_register(sc, &status_reg, true);
1136 	if (error) {
1137 		aprint_error_dev(self, "Failed to read status register: %d\n",
1138 		    error);
1139 		ecount++;
1140 	}
1141 
1142 	DPRINTF(sc, 2, ("%s: read status register values: %04x\n",
1143 	    device_xname(sc->sc_dev), status_reg));
1144 
1145 	error = sht3x_cmdr(sc, SHT3X_READ_SERIAL_NUMBER, buf, 6);
1146 	if (error) {
1147 		aprint_error_dev(self, "Failed to read serial number: %d\n",
1148 		    error);
1149 		ecount++;
1150 	}
1151 
1152 	sncrcpt1 = sht3x_crc(&buf[0],2);
1153 	sncrcpt2 = sht3x_crc(&buf[3],2);
1154 	serialnumber = (buf[0] << 24) | (buf[1] << 16) | (buf[3] << 8) | buf[4];
1155 
1156 	DPRINTF(sc, 2, ("%s: read serial number values: %02x%02x - %02x - "
1157 	    "%02x%02x - %02x -- %02x %02x\n", device_xname(sc->sc_dev), buf[0],
1158 	    buf[1], buf[2], buf[3], buf[4], buf[5], sncrcpt1, sncrcpt2));
1159 
1160 	iic_release_bus(sc->sc_tag, 0);
1161 	if (error != 0) {
1162 		aprint_error_dev(self, "Unable to setup device\n");
1163 		goto out;
1164 	}
1165 
1166 	for (i = 0; i < sc->sc_numsensors; i++) {
1167 		strlcpy(sc->sc_sensors[i].desc, sht3x_sensors[i].desc,
1168 		    sizeof(sc->sc_sensors[i].desc));
1169 
1170 		sc->sc_sensors[i].units = sht3x_sensors[i].type;
1171 		sc->sc_sensors[i].state = ENVSYS_SINVALID;
1172 
1173 		DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i,
1174 		    sc->sc_sensors[i].desc));
1175 
1176 		error = sysmon_envsys_sensor_attach(sc->sc_sme,
1177 		    &sc->sc_sensors[i]);
1178 		if (error) {
1179 			aprint_error_dev(self,
1180 			    "Unable to attach sensor %d: %d\n", i, error);
1181 			goto out;
1182 		}
1183 	}
1184 
1185 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
1186 	sc->sc_sme->sme_cookie = sc;
1187 	sc->sc_sme->sme_refresh = sht3x_refresh;
1188 
1189 	DPRINTF(sc, 2, ("sht3x_attach: registering with envsys\n"));
1190 
1191 	if (sysmon_envsys_register(sc->sc_sme)) {
1192 		aprint_error_dev(self, "unable to register with sysmon\n");
1193 		sysmon_envsys_destroy(sc->sc_sme);
1194 		sc->sc_sme = NULL;
1195 		return;
1196 	}
1197 
1198 	/*
1199 	 * There is no documented way to ask the chip what version it is. This
1200 	 * is likely fine as the only apparent difference is in how precise the
1201 	 * measurements will be. The actual conversation with the chip is
1202 	 * identical no matter which one you are talking to.
1203 	 */
1204 
1205 	aprint_normal_dev(self, "Sensirion SHT30/SHT31/SHT35, "
1206 	    "Serial number: %x%s", serialnumber,
1207 	    (sncrcpt1 == buf[2] && sncrcpt2 == buf[5]) ? "\n" : " (bad crc)\n");
1208 	return;
1209 out:
1210 	sysmon_envsys_destroy(sc->sc_sme);
1211 	sc->sc_sme = NULL;
1212 }
1213 
1214 static uint16_t
1215 sht3x_compute_measure_command_ss(const char *repeatability)
1216 {
1217 	int i;
1218 	uint16_t r;
1219 
1220 	for (i = 0; i < __arraycount(sht3x_repeatability_ss); i++) {
1221 		if (strncmp(repeatability, sht3x_repeatability_ss[i].text,
1222 		    SHT3X_REP_NAME) == 0) {
1223 			r = sht3x_repeatability_ss[i].cmd;
1224 			break;
1225 		}
1226 	}
1227 
1228 	if (i == __arraycount(sht3x_repeatability_ss))
1229 		panic("Single-shot could not find command for "
1230 		    "repeatability: %s\n", repeatability);
1231 
1232 	return r;
1233 }
1234 
1235 /*
1236  * The documented conversion calculations for the raw values are as follows:
1237  *
1238  * %RH = (-6 + 125 * rawvalue / 65535)
1239  *
1240  * T in Celsius = (-45 + 175 * rawvalue / 65535)
1241  *
1242  * It follows then:
1243  *
1244  * T in Kelvin = (228.15 + 175 * rawvalue / 65535)
1245  *
1246  * given the relationship between Celsius and Kelvin
1247  *
1248  * What follows reorders the calculation a bit and scales it up to avoid
1249  * the use of any floating point.  All that would really have to happen
1250  * is a scale up to 10^6 for the sysenv framework, which wants
1251  * temperature in micro-kelvin and percent relative humidity scaled up
1252  * 10^6, but since this conversion uses 64 bits due to intermediate
1253  * values that are bigger than 32 bits the conversion first scales up to
1254  * 10^9 and the scales back down by 10^3 at the end.  This preserves some
1255  * precision in the conversion that would otherwise be lost.
1256  */
1257 
1258 static uint64_t
1259 sht3x_compute_temp_from_raw(uint8_t msb, uint8_t lsb) {
1260 	uint64_t svalue;
1261 	int64_t v1;
1262 	uint64_t v2;
1263 	uint64_t d1 = 65535;
1264 	uint64_t mul1;
1265 	uint64_t mul2;
1266 	uint64_t div1 = 10000;
1267 	uint64_t q;
1268 
1269 	svalue = msb << 8 | lsb;
1270 
1271 	v1 = 22815; /* this is scaled up already from 228.15 */
1272 	v2 = 175;
1273 	mul1 = 10000000000;
1274 	mul2 = 100000000;
1275 
1276 	svalue = svalue * mul1;
1277 	v1 = v1 * mul2;
1278 	/* Perform the conversion */
1279 	q = ((v2 * (svalue / d1)) + v1) / div1;
1280 
1281 	return q;
1282 }
1283 
1284 static uint64_t
1285 sht3x_compute_rh_from_raw(uint8_t msb, uint8_t lsb) {
1286 	uint64_t svalue;
1287 	int64_t v1;
1288 	uint64_t v2;
1289 	uint64_t d1 = 65535;
1290 	uint64_t mul1;
1291 	uint64_t mul2;
1292 	uint64_t div1 = 10000;
1293 	uint64_t q;
1294 
1295 	svalue = msb << 8 | lsb;
1296 
1297 	v1 = 0;
1298 	v2 = 100;
1299 	mul1 = 10000000000;
1300 	mul2 = 10000000000;
1301 
1302 	svalue = svalue * mul1;
1303 	v1 = v1 * mul2;
1304 	/* Perform the conversion */
1305 	q = ((v2 * (svalue / d1)) + v1) / div1;
1306 
1307 	return q;
1308 }
1309 
1310 static int
1311 sht3x_parse_data(struct sht3x_sc *sc, envsys_data_t *edata, uint8_t *rawdata)
1312 {
1313 	uint64_t current_value;
1314 	uint8_t *svalptr;
1315 
1316 	DPRINTF(sc, 2, ("%s: Raw data: %02x%02x %02x - %02x%02x %02x\n",
1317 	    device_xname(sc->sc_dev), rawdata[0], rawdata[1], rawdata[2],
1318 	    rawdata[3], rawdata[4], rawdata[5]));
1319 
1320 	switch (edata->sensor) {
1321 	case SHT3X_TEMP_SENSOR:
1322 		current_value = sht3x_compute_temp_from_raw(rawdata[0],
1323 		    rawdata[1]);
1324 		svalptr = &rawdata[0];
1325 		break;
1326 	case SHT3X_HUMIDITY_SENSOR:
1327 		current_value = sht3x_compute_rh_from_raw(rawdata[3],
1328 		    rawdata[4]);
1329 		svalptr = &rawdata[3];
1330 		break;
1331 	default:
1332 		DPRINTF(sc, 2, ("%s: bad sensor type %d\n",
1333 		    device_xname(sc->sc_dev), edata->sensor));
1334 		return EINTR;
1335 	}
1336 	uint8_t testcrc;
1337 	/* Fake out the CRC check if being asked to ignore CRC */
1338 	if (sc->sc_ignorecrc) {
1339 		testcrc = *(svalptr + 2);
1340 	} else {
1341 		testcrc = sht3x_crc(svalptr, 2);
1342 	}
1343 
1344 	if (*(svalptr + 2) != testcrc) {
1345 	    DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d != %d\n",
1346 	    device_xname(sc->sc_dev), (*svalptr + 2), testcrc));
1347 	    return EINVAL;
1348 	}
1349 	edata->value_cur = (uint32_t) current_value;
1350 	edata->state = ENVSYS_SVALID;
1351 	return 0;
1352 }
1353 
1354 static int
1355 sht3x_refresh_periodic(struct sysmon_envsys *sme, envsys_data_t *edata)
1356 {
1357 	struct sht3x_sc *sc = sme->sme_cookie;
1358 	uint8_t rawdata[sizeof(sc->sc_pbuffer)];
1359 
1360 	memcpy(rawdata, sc->sc_pbuffer, sizeof(rawdata));
1361 
1362 	return sht3x_parse_data(sc, edata, rawdata);
1363 
1364 }
1365 
1366 static int
1367 sht3x_refresh_oneshot(struct sysmon_envsys *sme, envsys_data_t *edata)
1368 {
1369 	struct sht3x_sc *sc = sme->sme_cookie;
1370 	uint16_t measurement_command_ss;
1371 	uint8_t rawdata[sizeof(sc->sc_pbuffer)];
1372 	int error;
1373 
1374 	error = iic_acquire_bus(sc->sc_tag, 0);
1375 	if (error) {
1376 		DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
1377 		    device_xname(sc->sc_dev), error));
1378 		return error;
1379 	}
1380 
1381 	measurement_command_ss = sht3x_compute_measure_command_ss(
1382 	    sc->sc_repeatability);
1383 	error = sht3x_cmdr(sc, measurement_command_ss, rawdata, sizeof(rawdata));
1384 	DPRINTF(sc, 2, ("%s: Status for single-shot measurement cmd %04x "
1385 	    "Error %d\n", device_xname(sc->sc_dev), measurement_command_ss, error));
1386 	if (error == 0) {
1387 		error = sht3x_parse_data(sc, edata, rawdata);
1388 	}
1389 
1390 	uint16_t sbuf;
1391 	int status_error = sht3x_get_status_register(sc, &sbuf, true);
1392 
1393 	if (!status_error) {
1394 		DPRINTF(sc, 2, ("%s: read status register single-shot: %04x\n",
1395 		    device_xname(sc->sc_dev), sbuf));
1396 
1397 		if (sbuf & SHT3X_RESET_DETECTED) {
1398 			aprint_error_dev(sc->sc_dev,
1399 			    "Reset detected in single shot mode. "
1400 			    "Heater may have been reset\n");
1401 			sht3x_clear_status_register(sc, true);
1402 		}
1403 
1404 		sc->sc_heateron = sbuf & SHT3X_HEATER_STATUS;
1405 	}
1406 
1407 	iic_release_bus(sc->sc_tag, 0);
1408 
1409 	return error;
1410 }
1411 
1412 static void
1413 sht3x_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
1414 {
1415 	struct sht3x_sc *sc = sme->sme_cookie;
1416 
1417 	edata->state = ENVSYS_SINVALID;
1418 
1419 	mutex_enter(&sc->sc_mutex);
1420 
1421 	if (sc->sc_isperiodic) {
1422 		sht3x_refresh_periodic(sme, edata);
1423 	} else {
1424 		sht3x_refresh_oneshot(sme, edata);
1425 	}
1426 
1427 	mutex_exit(&sc->sc_mutex);
1428 }
1429 
1430 static int
1431 sht3xopen(dev_t dev, int flags, int fmt, struct lwp *l)
1432 {
1433 	struct sht3x_sc *sc;
1434 
1435 	sc = device_lookup_private(&sht3xtemp_cd, minor(dev));
1436 	if (!sc)
1437 		return ENXIO;
1438 
1439 	if (sc->sc_opened)
1440 		return EBUSY;
1441 
1442 	mutex_enter(&sc->sc_mutex);
1443 	sc->sc_opened = true;
1444 
1445 	sc->sc_wassingleshot = false;
1446 	if (!sc->sc_isperiodic) {
1447 		sc->sc_stopping = false;
1448 		sc->sc_initperiodic = true;
1449 		sc->sc_isperiodic = true;
1450 		sc->sc_wassingleshot = true;
1451 		sht3x_start_thread(sc);
1452 	}
1453 	mutex_exit(&sc->sc_mutex);
1454 
1455 	return 0;
1456 }
1457 
1458 static int
1459 sht3xread(dev_t dev, struct uio *uio, int flags)
1460 {
1461 	struct sht3x_sc *sc;
1462 	struct sht3x_read_q *pp;
1463 	int error,any;
1464 
1465 	sc = device_lookup_private(&sht3xtemp_cd, minor(dev));
1466 	if (!sc)
1467 		return ENXIO;
1468 
1469 	while (uio->uio_resid) {
1470 		any = 0;
1471 		error = 0;
1472 		mutex_enter(&sc->sc_read_mutex);
1473 
1474 		while (any == 0) {
1475 			pp = SIMPLEQ_FIRST(&sc->sc_read_queue);
1476 			if (pp != NULL) {
1477 				SIMPLEQ_REMOVE_HEAD(&sc->sc_read_queue, read_q);
1478 				any = 1;
1479 				break;
1480 			}
1481 			error = cv_wait_sig(&sc->sc_condreadready,
1482 			    &sc->sc_read_mutex);
1483 			if (sc->sc_dying)
1484 				error = EIO;
1485 			if (error == 0)
1486 				continue;
1487 			break;
1488 		}
1489 
1490 		if (any == 1 && error == 0) {
1491 			uint8_t *p = pp->measurement;
1492 			mutex_exit(&sc->sc_read_mutex);
1493 			pool_cache_put(sc->sc_readpool,pp);
1494 
1495 			DPRINTF(sc,2, ("%s: sending %02x%02x %02x -- %02x%02x "
1496 			    "%02x -- %x\n", device_xname(sc->sc_dev), p[0],
1497 			    p[1], p[2], p[3], p[4], p[5],
1498 			    mutex_owned(&sc->sc_read_mutex)));
1499 			if ((error = uiomove(pp->measurement,
1500 			    sizeof(pp->measurement), uio)) != 0) {
1501 				DPRINTF(sc,2, ("%s: send error %d\n",
1502 				    device_xname(sc->sc_dev), error));
1503 				break;
1504 			}
1505 		} else {
1506 			mutex_exit(&sc->sc_read_mutex);
1507 			if (error) {
1508 				break;
1509 			}
1510 		}
1511 	}
1512 
1513 	DPRINTF(sc,2, ("%s: loop done: %d\n",device_xname(sc->sc_dev),error));
1514 	if (sc->sc_dying) {
1515 		DPRINTF(sc, 2, ("%s: Telling all we are almost dead\n",
1516 		    device_xname(sc->sc_dev)));
1517 		mutex_enter(&sc->sc_dying_mutex);
1518 		cv_signal(&sc->sc_cond_dying);
1519 		mutex_exit(&sc->sc_dying_mutex);
1520 	}
1521 	return error;
1522 }
1523 
1524 static int
1525 sht3xclose(dev_t dev, int flags, int fmt, struct lwp *l)
1526 {
1527 	struct sht3x_sc *sc;
1528 	struct sht3x_read_q *pp;
1529 
1530 	sc = device_lookup_private(&sht3xtemp_cd, minor(dev));
1531 
1532 	if (sc->sc_wassingleshot) {
1533 		sht3x_stop_thread(sc);
1534 		sc->sc_stopping = false;
1535 		sc->sc_initperiodic = false;
1536 		sc->sc_isperiodic = false;
1537 	}
1538 
1539 	mutex_enter(&sc->sc_mutex);
1540 	/* Drain any read pools */
1541 	while ((pp = SIMPLEQ_FIRST(&sc->sc_read_queue)) != NULL) {
1542 		SIMPLEQ_REMOVE_HEAD(&sc->sc_read_queue, read_q);
1543 		pool_cache_put(sc->sc_readpool,pp);
1544 	}
1545 
1546 	/* Say that the device is now free */
1547 	sc->sc_opened = false;
1548 	mutex_exit(&sc->sc_mutex);
1549 
1550 	return(0);
1551 }
1552 
1553 static int
1554 sht3x_detach(device_t self, int flags)
1555 {
1556 	struct sht3x_sc *sc;
1557 	struct sht3x_read_q *pp;
1558 
1559 	sc = device_private(self);
1560 
1561 	if (sc->sc_isperiodic) {
1562 		sht3x_stop_thread(sc);
1563 	}
1564 
1565 	mutex_enter(&sc->sc_mutex);
1566 
1567 	sc->sc_dying = true;
1568 
1569 	/* If this is true we are still open, destroy the condvar */
1570 	if (sc->sc_opened) {
1571 		mutex_enter(&sc->sc_dying_mutex);
1572 		mutex_enter(&sc->sc_read_mutex);
1573 		cv_signal(&sc->sc_condreadready);
1574 		mutex_exit(&sc->sc_read_mutex);
1575 		DPRINTF(sc, 2, ("%s: Will wait for anything to exit\n",
1576 		    device_xname(sc->sc_dev)));
1577 		/* In the worst case this will time out after 5 seconds.
1578 		 * It really should not take that long for the drain / whatever
1579 		 * to happen
1580 		 */
1581 		cv_timedwait_sig(&sc->sc_cond_dying,
1582 		    &sc->sc_dying_mutex, mstohz(5000));
1583 		mutex_exit(&sc->sc_dying_mutex);
1584 		cv_destroy(&sc->sc_condreadready);
1585 		cv_destroy(&sc->sc_cond_dying);
1586 	}
1587 
1588 	/* Drain any read pools */
1589 	while ((pp = SIMPLEQ_FIRST(&sc->sc_read_queue)) != NULL) {
1590 		SIMPLEQ_REMOVE_HEAD(&sc->sc_read_queue, read_q);
1591 		pool_cache_put(sc->sc_readpool,pp);
1592 	}
1593 
1594 	/* Destroy the pool cache now that nothing is using it */
1595 	pool_cache_destroy(sc->sc_readpool);
1596 
1597 	/* Remove the sensors */
1598 	if (sc->sc_sme != NULL) {
1599 		sysmon_envsys_unregister(sc->sc_sme);
1600 		sc->sc_sme = NULL;
1601 	}
1602 	mutex_exit(&sc->sc_mutex);
1603 
1604 	/* Remove the sysctl tree */
1605 	sysctl_teardown(&sc->sc_sht3xlog);
1606 
1607 	/* Remove the mutex */
1608 	mutex_destroy(&sc->sc_mutex);
1609 	mutex_destroy(&sc->sc_threadmutex);
1610 	mutex_destroy(&sc->sc_read_mutex);
1611 	mutex_destroy(&sc->sc_dying_mutex);
1612 
1613 	/* Free the poolname string */
1614         if (sc->sc_readpoolname != NULL) {
1615                 kmem_free(sc->sc_readpoolname,strlen(sc->sc_readpoolname) + 1);
1616         }
1617 
1618 	return 0;
1619 }
1620 
1621 int
1622 sht3x_activate(device_t self, enum devact act)
1623 {
1624 	struct sht3x_sc *sc = device_private(self);
1625 
1626 	switch (act) {
1627 	case DVACT_DEACTIVATE:
1628 		sc->sc_dying = true;
1629 		return 0;
1630 	default:
1631 		return EOPNOTSUPP;
1632 	}
1633 }
1634 
1635 MODULE(MODULE_CLASS_DRIVER, sht3xtemp, "iic,sysmon_envsys");
1636 
1637 #ifdef _MODULE
1638 #include "ioconf.c"
1639 #endif
1640 
1641 static int
1642 sht3xtemp_modcmd(modcmd_t cmd, void *opaque)
1643 {
1644 	int error;
1645 #ifdef _MODULE
1646 	int bmaj = -1, cmaj = -1;
1647 #endif
1648 
1649 	switch (cmd) {
1650 	case MODULE_CMD_INIT:
1651 #ifdef _MODULE
1652 		error = devsw_attach("sht3xtemp", NULL, &bmaj,
1653 		    &sht3x_cdevsw, &cmaj);
1654 		if (error) {
1655 			aprint_error("%s: unable to attach devsw\n",
1656 			    sht3xtemp_cd.cd_name);
1657 			return error;
1658 		}
1659 
1660 		error = config_init_component(cfdriver_ioconf_sht3xtemp,
1661 		    cfattach_ioconf_sht3xtemp, cfdata_ioconf_sht3xtemp);
1662 		if (error) {
1663 			aprint_error("%s: unable to init component\n",
1664 			    sht3xtemp_cd.cd_name);
1665 			devsw_detach(NULL, &sht3x_cdevsw);
1666 		}
1667 		return error;
1668 #else
1669 		return 0;
1670 #endif
1671 	case MODULE_CMD_FINI:
1672 #ifdef _MODULE
1673 		error = config_fini_component(cfdriver_ioconf_sht3xtemp,
1674 		      cfattach_ioconf_sht3xtemp, cfdata_ioconf_sht3xtemp);
1675 		devsw_detach(NULL, &sht3x_cdevsw);
1676 		return error;
1677 #else
1678 		return 0;
1679 #endif
1680 	default:
1681 		return ENOTTY;
1682 	}
1683 }
1684