Home | History | Annotate | Line # | Download | only in i2c
      1 /*	$NetBSD: sht4x.c,v 1.3 2022/03/30 00:06:50 pgoyette Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2021 Brad Spencer <brad (at) anduin.eldar.org>
      5  *
      6  * Permission to use, copy, modify, and distribute this software for any
      7  * purpose with or without fee is hereby granted, provided that the above
      8  * copyright notice and this permission notice appear in all copies.
      9  *
     10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17  */
     18 
     19 #include <sys/cdefs.h>
     20 __KERNEL_RCSID(0, "$NetBSD: sht4x.c,v 1.3 2022/03/30 00:06:50 pgoyette Exp $");
     21 
     22 /*
     23   Driver for the Sensirion SHT40/SHT41/SHT45
     24 */
     25 
     26 #include <sys/param.h>
     27 #include <sys/systm.h>
     28 #include <sys/kernel.h>
     29 #include <sys/device.h>
     30 #include <sys/module.h>
     31 #include <sys/sysctl.h>
     32 #include <sys/mutex.h>
     33 
     34 #include <dev/sysmon/sysmonvar.h>
     35 #include <dev/i2c/i2cvar.h>
     36 #include <dev/i2c/sht4xreg.h>
     37 #include <dev/i2c/sht4xvar.h>
     38 
     39 
     40 static uint8_t 	sht4x_crc(uint8_t *, size_t);
     41 static int 	sht4x_poke(i2c_tag_t, i2c_addr_t, bool);
     42 static int 	sht4x_match(device_t, cfdata_t, void *);
     43 static void 	sht4x_attach(device_t, device_t, void *);
     44 static int 	sht4x_detach(device_t, int);
     45 static void 	sht4x_refresh(struct sysmon_envsys *, envsys_data_t *);
     46 static int 	sht4x_verify_sysctl(SYSCTLFN_ARGS);
     47 static int 	sht4x_verify_sysctl_resolution(SYSCTLFN_ARGS);
     48 static int 	sht4x_verify_sysctl_heateron(SYSCTLFN_ARGS);
     49 static int 	sht4x_verify_sysctl_heatervalue(SYSCTLFN_ARGS);
     50 static int 	sht4x_verify_sysctl_heaterpulse(SYSCTLFN_ARGS);
     51 
     52 #define SHT4X_DEBUG
     53 #ifdef SHT4X_DEBUG
     54 #define DPRINTF(s, l, x) \
     55     do { \
     56 	if (l <= s->sc_sht4xdebug) \
     57 	    printf x; \
     58     } while (/*CONSTCOND*/0)
     59 #else
     60 #define DPRINTF(s, l, x)
     61 #endif
     62 
     63 CFATTACH_DECL_NEW(sht4xtemp, sizeof(struct sht4x_sc),
     64     sht4x_match, sht4x_attach, sht4x_detach, NULL);
     65 
     66 static struct sht4x_sensor sht4x_sensors[] = {
     67 	{
     68 		.desc = "humidity",
     69 		.type = ENVSYS_SRELHUMIDITY,
     70 	},
     71 	{
     72 		.desc = "temperature",
     73 		.type = ENVSYS_STEMP,
     74 	}
     75 };
     76 
     77 /* The typical delays are documented in the datasheet for the chip.
     78    There is no need to be very accurate with these, just rough estimates
     79    will work fine.
     80 */
     81 
     82 static struct sht4x_timing sht4x_timings[] = {
     83 	{
     84 		.cmd = SHT4X_READ_SERIAL,
     85 		.typicaldelay = 5000,
     86 	},
     87 	{
     88 		.cmd = SHT4X_SOFT_RESET,
     89 		.typicaldelay = 1000,
     90 	},
     91 	{
     92 		.cmd = SHT4X_MEASURE_HIGH_PRECISION,
     93 		.typicaldelay = 8000,
     94 	},
     95 	{
     96 		.cmd = SHT4X_MEASURE_MEDIUM_PRECISION,
     97 		.typicaldelay = 4000,
     98 	},
     99 	{
    100 		.cmd = SHT4X_MEASURE_LOW_PRECISION,
    101 		.typicaldelay = 2000,
    102 	},
    103 	{
    104 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_HIGH_HEAT_1_S,
    105 		.typicaldelay = 1000000,
    106 	},
    107 	{
    108 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_MEDIUM_HEAT_1_S,
    109 		.typicaldelay = 1000000,
    110 	},
    111 	{
    112 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_LOW_HEAT_1_S,
    113 		.typicaldelay = 1000000,
    114 	},
    115 	{
    116 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_HIGH_HEAT_TENTH_S,
    117 		.typicaldelay = 100000,
    118 	},
    119 	{
    120 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_MEDIUM_HEAT_TENTH_S,
    121 		.typicaldelay = 100000,
    122 	},
    123 	{
    124 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_LOW_HEAT_TENTH_S,
    125 		.typicaldelay = 100000,
    126 	}
    127 };
    128 
    129 /* Used when the heater is not on to find the command to use for the
    130  * measurement.
    131  */
    132 
    133 static struct sht4x_resolution sht4x_resolutions[] = {
    134 	{
    135 		.text = "high",
    136 		.cmd = SHT4X_MEASURE_HIGH_PRECISION,
    137 	},
    138 	{
    139 		.text = "medium",
    140 		.cmd = SHT4X_MEASURE_MEDIUM_PRECISION,
    141 	},
    142 	{
    143 		.text = "low",
    144 		.cmd = SHT4X_MEASURE_LOW_PRECISION,
    145 	}
    146 };
    147 
    148 static const char sht4x_resolution_names[] =
    149     "high, medium, low";
    150 
    151 static struct sht4x_heaterpulse sht4x_heaterpulses[] = {
    152 	{
    153 		.length = "short",
    154 	},
    155 	{
    156 		.length = "long",
    157 	}
    158 };
    159 
    160 /* This is consulted when the heater is on for which command is to be
    161    used for the measurement.
    162 */
    163 
    164 static struct sht4x_heateron_command sht4x_heateron_commands[] = {
    165 	{
    166 		.heatervalue = 1,
    167 		.pulselength = "short",
    168 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_LOW_HEAT_TENTH_S,
    169 	},
    170 	{
    171 		.heatervalue = 2,
    172 		.pulselength = "short",
    173 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_MEDIUM_HEAT_TENTH_S,
    174 	},
    175 	{
    176 		.heatervalue = 3,
    177 		.pulselength = "short",
    178 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_HIGH_HEAT_TENTH_S,
    179 	},
    180 	{
    181 		.heatervalue = 1,
    182 		.pulselength = "long",
    183 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_LOW_HEAT_1_S,
    184 	},
    185 	{
    186 		.heatervalue = 2,
    187 		.pulselength = "long",
    188 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_MEDIUM_HEAT_1_S,
    189 	},
    190 	{
    191 		.heatervalue = 3,
    192 		.pulselength = "long",
    193 		.cmd = SHT4X_MEASURE_HIGH_PRECISION_HIGH_HEAT_1_S,
    194 	}
    195 };
    196 
    197 static const char sht4x_heaterpulse_names[] =
    198     "short, long";
    199 
    200 int
    201 sht4x_verify_sysctl(SYSCTLFN_ARGS)
    202 {
    203 	int error, t;
    204 	struct sysctlnode node;
    205 
    206 	node = *rnode;
    207 	t = *(int *)rnode->sysctl_data;
    208 	node.sysctl_data = &t;
    209 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    210 	if (error || newp == NULL)
    211 		return error;
    212 
    213 	if (t < 0)
    214 		return EINVAL;
    215 
    216 	*(int *)rnode->sysctl_data = t;
    217 
    218 	return 0;
    219 }
    220 
    221 /* None of the heater and resolutions sysctls change anything on the chip in
    222    real time.  The values set are used to send different commands depending on
    223    how they are set up.
    224 
    225    What this implies is that the chip could be reset and the driver would not care.
    226 
    227 */
    228 
    229 int
    230 sht4x_verify_sysctl_resolution(SYSCTLFN_ARGS)
    231 {
    232 	char buf[SHT4X_RES_NAME];
    233 	struct sht4x_sc *sc;
    234 	struct sysctlnode node;
    235 	int error = 0;
    236 	size_t i;
    237 
    238 	node = *rnode;
    239 	sc = node.sysctl_data;
    240 	(void) memcpy(buf, sc->sc_resolution, SHT4X_RES_NAME);
    241 	node.sysctl_data = buf;
    242 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    243 	if (error || newp == NULL)
    244 		return error;
    245 
    246 	for (i = 0; i < __arraycount(sht4x_resolutions); i++) {
    247 		if (strncmp(node.sysctl_data, sht4x_resolutions[i].text,
    248 		    SHT4X_RES_NAME) == 0) {
    249 			break;
    250 		}
    251 	}
    252 
    253 	if (i == __arraycount(sht4x_resolutions))
    254 		return EINVAL;
    255 	(void) memcpy(sc->sc_resolution, node.sysctl_data, SHT4X_RES_NAME);
    256 
    257 	return error;
    258 }
    259 
    260 int
    261 sht4x_verify_sysctl_heateron(SYSCTLFN_ARGS)
    262 {
    263 	int 		error;
    264 	bool 		t;
    265 	struct sht4x_sc *sc;
    266 	struct sysctlnode node;
    267 
    268 	node = *rnode;
    269 	sc = node.sysctl_data;
    270 	t = sc->sc_heateron;
    271 	node.sysctl_data = &t;
    272 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    273 	if (error || newp == NULL)
    274 		return error;
    275 
    276 	sc->sc_heateron = t;
    277 
    278 	return error;
    279 }
    280 
    281 int
    282 sht4x_verify_sysctl_heatervalue(SYSCTLFN_ARGS)
    283 {
    284 	int 		error = 0, t;
    285 	struct sht4x_sc *sc;
    286 	struct sysctlnode node;
    287 
    288 	node = *rnode;
    289 	sc = node.sysctl_data;
    290 	t = sc->sc_heaterval;
    291 	node.sysctl_data = &t;
    292 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    293 	if (error || newp == NULL)
    294 		return (error);
    295 
    296 	if (t < 1 || t > 3)
    297 		return (EINVAL);
    298 
    299 	sc->sc_heaterval = t;
    300 
    301 	return error;
    302 }
    303 
    304 int
    305 sht4x_verify_sysctl_heaterpulse(SYSCTLFN_ARGS)
    306 {
    307 	char buf[SHT4X_PULSE_NAME];
    308 	struct sht4x_sc *sc;
    309 	struct sysctlnode node;
    310 	int error = 0;
    311 	size_t i;
    312 
    313 	node = *rnode;
    314 	sc = node.sysctl_data;
    315 	(void) memcpy(buf, sc->sc_heaterpulse, SHT4X_PULSE_NAME);
    316 	node.sysctl_data = buf;
    317 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    318 	if (error || newp == NULL)
    319 		return error;
    320 
    321 	for (i = 0; i < __arraycount(sht4x_heaterpulses); i++) {
    322 		if (strncmp(node.sysctl_data, sht4x_heaterpulses[i].length,
    323 		    SHT4X_RES_NAME) == 0) {
    324 			break;
    325 		}
    326 	}
    327 
    328 	if (i == __arraycount(sht4x_heaterpulses))
    329 		return EINVAL;
    330 	(void) memcpy(sc->sc_heaterpulse, node.sysctl_data, SHT4X_PULSE_NAME);
    331 
    332 	return error;
    333 }
    334 
    335 static int
    336 sht4x_cmddelay(uint8_t cmd)
    337 {
    338 	int r = -1;
    339 
    340 	for(int i = 0;i < __arraycount(sht4x_timings);i++) {
    341 		if (cmd == sht4x_timings[i].cmd) {
    342 			r = sht4x_timings[i].typicaldelay;
    343 			break;
    344 		}
    345 	}
    346 
    347 	if (r == -1) {
    348 		panic("Bad command look up in cmd delay: cmd: %d\n",cmd);
    349 	}
    350 
    351 	return r;
    352 }
    353 
    354 static int
    355 sht4x_cmd(i2c_tag_t tag, i2c_addr_t addr, uint8_t *cmd,
    356     uint8_t clen, uint8_t *buf, size_t blen, int readattempts)
    357 {
    358 	int error;
    359 	int cmddelay;
    360 
    361 	error = iic_exec(tag,I2C_OP_WRITE_WITH_STOP,addr,cmd,clen,NULL,0,0);
    362 
    363 	/* Every command returns something except for the soft reset
    364 	   which returns nothing.  This chip is also nice in that pretty
    365 	   much every command that returns something does it in the same way.
    366 	*/
    367 	if (error == 0 && cmd[0] != SHT4X_SOFT_RESET) {
    368 		cmddelay = sht4x_cmddelay(cmd[0]);
    369 		delay(cmddelay);
    370 
    371 		for (int aint = 0; aint < readattempts; aint++) {
    372 			error = iic_exec(tag,I2C_OP_READ_WITH_STOP,addr,NULL,0,buf,blen,0);
    373 			if (error == 0)
    374 				break;
    375 			delay(1000);
    376 		}
    377 	}
    378 
    379 	return error;
    380 }
    381 
    382 static int
    383 sht4x_cmdr(struct sht4x_sc *sc, uint8_t cmd, uint8_t *buf, size_t blen)
    384 {
    385 	return sht4x_cmd(sc->sc_tag, sc->sc_addr, &cmd, 1, buf, blen, sc->sc_readattempts);
    386 }
    387 
    388 static	uint8_t
    389 sht4x_crc(uint8_t * data, size_t size)
    390 {
    391 	uint8_t crc = 0xFF;
    392 
    393 	for (size_t i = 0; i < size; i++) {
    394 		crc ^= data[i];
    395 		for (size_t j = 8; j > 0; j--) {
    396 			if (crc & 0x80)
    397 				crc = (crc << 1) ^ 0x131;
    398 			else
    399 				crc <<= 1;
    400 		}
    401 	}
    402 	return crc;
    403 }
    404 
    405 static int
    406 sht4x_poke(i2c_tag_t tag, i2c_addr_t addr, bool matchdebug)
    407 {
    408 	uint8_t reg = SHT4X_READ_SERIAL;
    409 	uint8_t buf[6];
    410 	int error;
    411 
    412 	error = sht4x_cmd(tag, addr, &reg, 1, buf, 6, 10);
    413 	if (matchdebug) {
    414 		printf("poke X 1: %d\n", error);
    415 	}
    416 	return error;
    417 }
    418 
    419 static int
    420 sht4x_sysctl_init(struct sht4x_sc *sc)
    421 {
    422 	int error;
    423 	const struct sysctlnode *cnode;
    424 	int sysctlroot_num;
    425 
    426 	if ((error = sysctl_createv(&sc->sc_sht4xlog, 0, NULL, &cnode,
    427 	    0, CTLTYPE_NODE, device_xname(sc->sc_dev),
    428 	    SYSCTL_DESCR("sht4x controls"), NULL, 0, NULL, 0, CTL_HW,
    429 	    CTL_CREATE, CTL_EOL)) != 0)
    430 		return error;
    431 
    432 	sysctlroot_num = cnode->sysctl_num;
    433 
    434 #ifdef SHT4X_DEBUG
    435 	if ((error = sysctl_createv(&sc->sc_sht4xlog, 0, NULL, &cnode,
    436 	    CTLFLAG_READWRITE, CTLTYPE_INT, "debug",
    437 	    SYSCTL_DESCR("Debug level"), sht4x_verify_sysctl, 0,
    438 	    &sc->sc_sht4xdebug, 0, CTL_HW, sysctlroot_num, CTL_CREATE,
    439 	    CTL_EOL)) != 0)
    440 		return error;
    441 
    442 #endif
    443 
    444 	if ((error = sysctl_createv(&sc->sc_sht4xlog, 0, NULL, &cnode,
    445 	    CTLFLAG_READWRITE, CTLTYPE_INT, "readattempts",
    446 	    SYSCTL_DESCR("The number of times to attempt to read the values"),
    447 	    sht4x_verify_sysctl, 0, &sc->sc_readattempts, 0, CTL_HW,
    448 	    sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    449 		return error;
    450 
    451 	if ((error = sysctl_createv(&sc->sc_sht4xlog, 0, NULL, &cnode,
    452 	    CTLFLAG_READONLY, CTLTYPE_STRING, "resolutions",
    453 	    SYSCTL_DESCR("Valid resolutions"), 0, 0,
    454 	    __UNCONST(sht4x_resolution_names),
    455 	    sizeof(sht4x_resolution_names) + 1,
    456 	    CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    457 		return error;
    458 
    459 	if ((error = sysctl_createv(&sc->sc_sht4xlog, 0, NULL, &cnode,
    460 	    CTLFLAG_READWRITE, CTLTYPE_STRING, "resolution",
    461 	    SYSCTL_DESCR("Resolution of RH and Temp"),
    462 	    sht4x_verify_sysctl_resolution, 0, (void *) sc,
    463 	    SHT4X_RES_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    464 		return error;
    465 
    466 	if ((error = sysctl_createv(&sc->sc_sht4xlog, 0, NULL, &cnode,
    467 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "ignorecrc",
    468 	    SYSCTL_DESCR("Ignore the CRC byte"), NULL, 0, &sc->sc_ignorecrc,
    469 	    0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    470 		return error;
    471 
    472 	if ((error = sysctl_createv(&sc->sc_sht4xlog, 0, NULL, &cnode,
    473 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "heateron",
    474 	    SYSCTL_DESCR("Heater on"), sht4x_verify_sysctl_heateron, 0,
    475 	    (void *)sc, 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    476 		return error;
    477 
    478 	if ((error = sysctl_createv(&sc->sc_sht4xlog, 0, NULL, &cnode,
    479 	    CTLFLAG_READWRITE, CTLTYPE_INT, "heaterstrength",
    480 	    SYSCTL_DESCR("Heater strength 1 to 3"),
    481 	    sht4x_verify_sysctl_heatervalue, 0, (void *)sc, 0, CTL_HW,
    482 	    sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    483 		return error;
    484 
    485 	if ((error = sysctl_createv(&sc->sc_sht4xlog, 0, NULL, &cnode,
    486 	    CTLFLAG_READONLY, CTLTYPE_STRING, "heaterpulses",
    487 	    SYSCTL_DESCR("Valid heater pulse lengths"), 0, 0,
    488 	    __UNCONST(sht4x_heaterpulse_names),
    489 	    sizeof(sht4x_heaterpulse_names) + 1,
    490 	    CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    491 		return error;
    492 
    493 	if ((error = sysctl_createv(&sc->sc_sht4xlog, 0, NULL, &cnode,
    494 	    CTLFLAG_READWRITE, CTLTYPE_STRING, "heaterpulse",
    495 	    SYSCTL_DESCR("Heater pulse length"),
    496 	    sht4x_verify_sysctl_heaterpulse, 0, (void *) sc,
    497 	    SHT4X_RES_NAME, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
    498 		return error;
    499 	return 0;
    500 }
    501 
    502 static int
    503 sht4x_match(device_t parent, cfdata_t match, void *aux)
    504 {
    505 	struct i2c_attach_args *ia = aux;
    506 	int error, match_result;
    507 	const bool matchdebug = false;
    508 
    509 	if (iic_use_direct_match(ia, match, NULL, &match_result))
    510 		return match_result;
    511 
    512 	/* indirect config - check for configured address */
    513 	if (ia->ia_addr != SHT4X_TYPICAL_ADDR)
    514 		return 0;
    515 
    516 	/*
    517 	 * Check to see if something is really at this i2c address. This will
    518 	 * keep phantom devices from appearing
    519 	 */
    520 	if (iic_acquire_bus(ia->ia_tag, 0) != 0) {
    521 		if (matchdebug)
    522 			printf("in match acquire bus failed\n");
    523 		return 0;
    524 	}
    525 
    526 	error = sht4x_poke(ia->ia_tag, ia->ia_addr, matchdebug);
    527 	iic_release_bus(ia->ia_tag, 0);
    528 
    529 	return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0;
    530 }
    531 
    532 static void
    533 sht4x_attach(device_t parent, device_t self, void *aux)
    534 {
    535 	struct sht4x_sc *sc;
    536 	struct i2c_attach_args *ia;
    537 	int error, i;
    538 	int ecount = 0;
    539 	uint8_t buf[6];
    540 	uint8_t sncrcpt1, sncrcpt2;
    541 
    542 	ia = aux;
    543 	sc = device_private(self);
    544 
    545 	sc->sc_dev = self;
    546 	sc->sc_tag = ia->ia_tag;
    547 	sc->sc_addr = ia->ia_addr;
    548 	sc->sc_sht4xdebug = 0;
    549 	strlcpy(sc->sc_resolution,"high",SHT4X_RES_NAME);
    550 	sc->sc_readattempts = 10;
    551 	sc->sc_ignorecrc = false;
    552 	sc->sc_heateron = false;
    553 	sc->sc_heaterval = 1;
    554 	strlcpy(sc->sc_heaterpulse,"short",SHT4X_PULSE_NAME);
    555 	sc->sc_sme = NULL;
    556 
    557 	aprint_normal("\n");
    558 
    559 	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE);
    560 	sc->sc_numsensors = __arraycount(sht4x_sensors);
    561 
    562 	if ((sc->sc_sme = sysmon_envsys_create()) == NULL) {
    563 		aprint_error_dev(self,
    564 		    "Unable to create sysmon structure\n");
    565 		sc->sc_sme = NULL;
    566 		return;
    567 	}
    568 	if ((error = sht4x_sysctl_init(sc)) != 0) {
    569 		aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", error);
    570 		goto out;
    571 	}
    572 
    573 	error = iic_acquire_bus(sc->sc_tag, 0);
    574 	if (error) {
    575 		aprint_error_dev(self, "Could not acquire iic bus: %d\n",
    576 		    error);
    577 		goto out;
    578 	}
    579 
    580 	error = sht4x_cmdr(sc, SHT4X_SOFT_RESET, NULL, 0);
    581 	if (error != 0)
    582 		aprint_error_dev(self, "Reset failed: %d\n", error);
    583 
    584 	delay(1000); /* 1 ms max */
    585 
    586 	error = sht4x_cmdr(sc, SHT4X_READ_SERIAL, buf, 6);
    587 	if (error) {
    588 		aprint_error_dev(self, "Failed to read serial number: %d\n",
    589 		    error);
    590 		ecount++;
    591 	}
    592 
    593 	sncrcpt1 = sht4x_crc(&buf[0],2);
    594 	sncrcpt2 = sht4x_crc(&buf[3],2);
    595 
    596 	DPRINTF(sc, 2, ("%s: read serial number values: %02x%02x - %02x, %02x%02x - %02x ; %02x %02x\n",
    597 	    device_xname(sc->sc_dev), buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], sncrcpt1, sncrcpt2));
    598 
    599 	iic_release_bus(sc->sc_tag, 0);
    600 	if (error != 0) {
    601 		aprint_error_dev(self, "Unable to setup device\n");
    602 		goto out;
    603 	}
    604 
    605 	for (i = 0; i < sc->sc_numsensors; i++) {
    606 		strlcpy(sc->sc_sensors[i].desc, sht4x_sensors[i].desc,
    607 		    sizeof(sc->sc_sensors[i].desc));
    608 
    609 		sc->sc_sensors[i].units = sht4x_sensors[i].type;
    610 		sc->sc_sensors[i].state = ENVSYS_SINVALID;
    611 
    612 		DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i,
    613 		    sc->sc_sensors[i].desc));
    614 
    615 		error = sysmon_envsys_sensor_attach(sc->sc_sme,
    616 		    &sc->sc_sensors[i]);
    617 		if (error) {
    618 			aprint_error_dev(self,
    619 			    "Unable to attach sensor %d: %d\n", i, error);
    620 			goto out;
    621 		}
    622 	}
    623 
    624 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
    625 	sc->sc_sme->sme_cookie = sc;
    626 	sc->sc_sme->sme_refresh = sht4x_refresh;
    627 
    628 	DPRINTF(sc, 2, ("sht4x_attach: registering with envsys\n"));
    629 
    630 	if (sysmon_envsys_register(sc->sc_sme)) {
    631 		aprint_error_dev(self,
    632 			"unable to register with sysmon\n");
    633 		sysmon_envsys_destroy(sc->sc_sme);
    634 		sc->sc_sme = NULL;
    635 		return;
    636 	}
    637 
    638 	/* There is no documented way to ask the chip what version it is.  This
    639 	   is likely fine as the only apparent difference is in how precise the
    640 	   measurements will be.  The actual conversation with the chip is
    641 	   identical no matter which one you are talking to.
    642 	*/
    643 
    644 	aprint_normal_dev(self, "Sensirion SHT40/SHT41/SHT45, "
    645 	    "Serial number: %02x%02x%02x%02x%s",
    646 	    buf[0], buf[1], buf[3], buf[4],
    647 	    (sncrcpt1 == buf[2] && sncrcpt2 == buf[5]) ? "\n" : " (bad crc)\n");
    648 	return;
    649 out:
    650 	sysmon_envsys_destroy(sc->sc_sme);
    651 	sc->sc_sme = NULL;
    652 }
    653 
    654 /* If you use the heater on this chip, there is no documented choice but to use
    655    the highest precision.  If the heater is not in use one may select different
    656    precisions or repeatability for the measurement.
    657 
    658    Further, if the heater is used, it will only be active during the measurement.
    659    The use of the heater will add delay to the measurement as chip will not
    660    return anything until the heater pulse time is over.
    661 */
    662 
    663 static uint8_t
    664 sht4x_compute_measure_command(char *resolution, bool heateron,
    665     int heatervalue, char *heaterpulse)
    666 {
    667 	int i;
    668 	uint8_t r;
    669 
    670 	if (heateron == false) {
    671 		for (i = 0; i < __arraycount(sht4x_resolutions); i++) {
    672 			if (strncmp(resolution, sht4x_resolutions[i].text,
    673 			    SHT4X_RES_NAME) == 0) {
    674 				r = sht4x_resolutions[i].cmd;
    675 				break;
    676 			}
    677 		}
    678 
    679 		if (i == __arraycount(sht4x_resolutions))
    680 			panic("Heater off could not find command for resolution: %s\n",resolution);
    681 	} else {
    682 		for (i = 0; i < __arraycount(sht4x_heateron_commands); i++) {
    683 			if (heatervalue == sht4x_heateron_commands[i].heatervalue &&
    684 			    strncmp(heaterpulse, sht4x_heateron_commands[i].pulselength,
    685 			    SHT4X_PULSE_NAME) == 0) {
    686 				r = sht4x_heateron_commands[i].cmd;
    687 				break;
    688 			}
    689 		}
    690 
    691 		if (i == __arraycount(sht4x_heateron_commands))
    692 			panic("Heater on could not find command for heatervalue, heaterpulse: %d %s\n",
    693 			    heatervalue,heaterpulse);
    694 	}
    695 
    696 	return r;
    697 }
    698 
    699 static void
    700 sht4x_refresh(struct sysmon_envsys * sme, envsys_data_t * edata)
    701 {
    702 	struct sht4x_sc *sc;
    703 	sc = sme->sme_cookie;
    704 	int error;
    705 	uint8_t rawdata[6];
    706 	uint8_t measurement_command;
    707 	edata->state = ENVSYS_SINVALID;
    708 
    709 	mutex_enter(&sc->sc_mutex);
    710 	error = iic_acquire_bus(sc->sc_tag, 0);
    711 	if (error) {
    712 		DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n",
    713 		    device_xname(sc->sc_dev), error));
    714 		goto out;
    715 	}
    716 
    717 	/*
    718 	  The documented conversion calculations for the raw values are as follows:
    719 
    720 	  %RH = (-6 + 125 * rawvalue / 65535)
    721 
    722 	  T in Celsius = (-45 + 175 * rawvalue / 65535)
    723 
    724 	  It follows then:
    725 
    726 	  T in Kelvin = (228.15 + 175 * rawvalue / 65535)
    727 
    728 	  given the relationship between Celsius and Kelvin.
    729 
    730 	  What follows reorders the calculation a bit and scales it up to avoid
    731 	  the use of any floating point.  All that would really have to happen
    732 	  is a scale up to 10^6 for the sysenv framework, which wants
    733 	  temperature in micro-kelvin and percent relative humidity scaled up
    734 	  10^6, but since this conversion uses 64 bits due to intermediate
    735 	  values that are bigger than 32 bits the conversion first scales up to
    736 	  10^9 and the scales back down by 10^3 at the end.  This preserves some
    737 	  precision in the conversion that would otherwise be lost.
    738 	 */
    739 
    740 	measurement_command = sht4x_compute_measure_command(sc->sc_resolution,
    741 	    sc->sc_heateron, sc->sc_heaterval, sc->sc_heaterpulse);
    742 	DPRINTF(sc, 2, ("%s: Measurement command: %02x\n",
    743 	    device_xname(sc->sc_dev), measurement_command));
    744 
    745 	/* This chip is pretty nice in that all commands are the same length and
    746 	   return the same result.  What is not so nice is that you can not ask
    747 	   for temperature and humidity independently.
    748 
    749 	   The result will be 16 bits of raw temperature and a CRC byte followed
    750 	   by 16 bits of humidity followed by a CRC byte.
    751 	*/
    752 
    753 	error = sht4x_cmdr(sc,measurement_command,rawdata,6);
    754 
    755 	if (error == 0) {
    756 		DPRINTF(sc, 2, ("%s: Raw data: %02x%02x %02x - %02x%02x %02x\n",
    757 		    device_xname(sc->sc_dev), rawdata[0], rawdata[1], rawdata[2],
    758 		    rawdata[3], rawdata[4], rawdata[5]));
    759 
    760 
    761 		uint8_t *svalptr;
    762 		uint64_t svalue;
    763 		int64_t v1;
    764 		uint64_t v2;
    765 		uint64_t d1 = 65535;
    766 		uint64_t mul1;
    767 		uint64_t mul2;
    768 		uint64_t div1 = 10000;
    769 		uint64_t q;
    770 
    771 		switch (edata->sensor) {
    772 		case SHT4X_TEMP_SENSOR:
    773 			svalptr = &rawdata[0];
    774 			v1 = 22815; /* this is scaled up already from 228.15 */
    775 			v2 = 175;
    776 			mul1 = 10000000000;
    777 			mul2 = 100000000;
    778 			break;
    779 		case SHT4X_HUMIDITY_SENSOR:
    780 			svalptr = &rawdata[3];
    781 			v1 = -6;
    782 			v2 = 125;
    783 			mul1 = 10000000000;
    784 			mul2 = 10000000000;
    785 			break;
    786 		default:
    787 			error = EINVAL;
    788 			break;
    789 		}
    790 
    791 		if (error == 0) {
    792 			uint8_t testcrc;
    793 
    794 			/* Fake out the CRC check if being asked to ignore CRC */
    795 			if (sc->sc_ignorecrc) {
    796 				testcrc = *(svalptr + 2);
    797 			} else {
    798 				testcrc = sht4x_crc(svalptr,2);
    799 			}
    800 
    801 			if (*(svalptr + 2) == testcrc) {
    802 				svalue = *svalptr << 8 | *(svalptr + 1);
    803 				DPRINTF(sc, 2, ("%s: Raw sensor 16 bit: %#jx\n",
    804 				    device_xname(sc->sc_dev), (uintmax_t)svalue));
    805 
    806 				/* Scale up */
    807 				svalue = svalue * mul1;
    808 				v1 = v1 * mul2;
    809 				/* Perform the conversion */
    810 				q = ((v2 * (svalue / d1)) + v1) / div1;
    811 
    812 				DPRINTF(sc, 2, ("%s: Computed sensor: %#jx\n",
    813 				    device_xname(sc->sc_dev), (uintmax_t)q));
    814 				/* The results will fit in 32 bits, so nothing will be lost */
    815 				edata->value_cur = (uint32_t) q;
    816 				edata->state = ENVSYS_SVALID;
    817 			} else {
    818 				error = EINVAL;
    819 			}
    820 		}
    821 	}
    822 
    823 	if (error) {
    824 		DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d\n",
    825 		    device_xname(sc->sc_dev), error));
    826 	}
    827 
    828 	iic_release_bus(sc->sc_tag, 0);
    829 out:
    830 	mutex_exit(&sc->sc_mutex);
    831 }
    832 
    833 static int
    834 sht4x_detach(device_t self, int flags)
    835 {
    836 	struct sht4x_sc *sc;
    837 
    838 	sc = device_private(self);
    839 
    840 	mutex_enter(&sc->sc_mutex);
    841 
    842 	/* Remove the sensors */
    843 	if (sc->sc_sme != NULL) {
    844 		sysmon_envsys_unregister(sc->sc_sme);
    845 		sc->sc_sme = NULL;
    846 	}
    847 	mutex_exit(&sc->sc_mutex);
    848 
    849 	/* Remove the sysctl tree */
    850 	sysctl_teardown(&sc->sc_sht4xlog);
    851 
    852 	/* Remove the mutex */
    853 	mutex_destroy(&sc->sc_mutex);
    854 
    855 	return 0;
    856 }
    857 
    858 MODULE(MODULE_CLASS_DRIVER, sht4xtemp, "iic,sysmon_envsys");
    859 
    860 #ifdef _MODULE
    861 #include "ioconf.c"
    862 #endif
    863 
    864 static int
    865 sht4xtemp_modcmd(modcmd_t cmd, void *opaque)
    866 {
    867 
    868 	switch (cmd) {
    869 	case MODULE_CMD_INIT:
    870 #ifdef _MODULE
    871 		return config_init_component(cfdriver_ioconf_sht4xtemp,
    872 		    cfattach_ioconf_sht4xtemp, cfdata_ioconf_sht4xtemp);
    873 #else
    874 		return 0;
    875 #endif
    876 	case MODULE_CMD_FINI:
    877 #ifdef _MODULE
    878 		return config_fini_component(cfdriver_ioconf_sht4xtemp,
    879 		      cfattach_ioconf_sht4xtemp, cfdata_ioconf_sht4xtemp);
    880 #else
    881 		return 0;
    882 #endif
    883 	default:
    884 		return ENOTTY;
    885 	}
    886 }
    887