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