Module Name: src Committed By: christos Date: Fri Nov 12 22:16:28 UTC 2021
Modified Files: src/sys/dev/i2c: sht3x.c Log Message: simplify the code and remove unused (it is in CVS anyway). Try to merge duplicate code. Follow KNF. Brad, please test! To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/dev/i2c/sht3x.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/i2c/sht3x.c diff -u src/sys/dev/i2c/sht3x.c:1.1 src/sys/dev/i2c/sht3x.c:1.2 --- src/sys/dev/i2c/sht3x.c:1.1 Sat Nov 6 09:34:40 2021 +++ src/sys/dev/i2c/sht3x.c Fri Nov 12 17:16:27 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: sht3x.c,v 1.1 2021/11/06 13:34:40 brad Exp $ */ +/* $NetBSD: sht3x.c,v 1.2 2021/11/12 22:16:27 christos Exp $ */ /* * Copyright (c) 2021 Brad Spencer <b...@anduin.eldar.org> @@ -17,7 +17,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.1 2021/11/06 13:34:40 brad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.2 2021/11/12 22:16:27 christos Exp $"); /* Driver for the Sensirion SHT30/SHT31/SHT35 @@ -52,17 +52,6 @@ static int sht3x_match(device_t, cfdata static void sht3x_attach(device_t, device_t, void *); static int sht3x_detach(device_t, int); static void sht3x_refresh(struct sysmon_envsys *, envsys_data_t *); -/* The chip that I had would not allow the limits to actually be set - * for reasons which are not obvious. The chip took the command just - * fine, but a read back of the limit registers showed that no change - * was made, so disable limits for now. - */ -#ifdef __did_not_work -static void sht3x_get_limits(struct sysmon_envsys *, envsys_data_t *, - sysmon_envsys_lim_t *, uint32_t *); -static void sht3x_set_limits(struct sysmon_envsys *, envsys_data_t *, - sysmon_envsys_lim_t *, uint32_t *); -#endif static int sht3x_verify_sysctl(SYSCTLFN_ARGS); static int sht3x_verify_sysctl_heateron(SYSCTLFN_ARGS); static int sht3x_verify_sysctl_modes(SYSCTLFN_ARGS); @@ -338,8 +327,8 @@ sht3x_take_break(void *aux, bool have_bu if (! have_bus) { error = iic_acquire_bus(sc->sc_tag, 0); if (error) { - DPRINTF(sc, 2, ("%s: Could not acquire iic bus for breaking %d\n", - device_xname(sc->sc_dev), error)); + DPRINTF(sc, 2, ("%s: Could not acquire iic bus for " + "breaking %d\n", device_xname(sc->sc_dev), error)); goto out; } } @@ -348,13 +337,13 @@ sht3x_take_break(void *aux, bool have_bu DPRINTF(sc, 2, ("%s: Error breaking: %d\n", device_xname(sc->sc_dev), error)); } - out: +out: if (! have_bus) { iic_release_bus(sc->sc_tag, 0); } sc->sc_isperiodic = false; - strlcpy(sc->sc_mode,"single-shot",SHT3X_MODE_NAME); + strlcpy(sc->sc_mode, "single-shot", SHT3X_MODE_NAME); return error; } @@ -362,56 +351,53 @@ sht3x_take_break(void *aux, bool have_bu static int sht3x_get_status_register(void *aux, uint16_t *reg, bool have_bus) { - struct sht3x_sc *sc; - sc = aux; + struct sht3x_sc *sc = aux; uint8_t buf[3]; - int error = 0; + int error; if (! have_bus) { error = iic_acquire_bus(sc->sc_tag, 0); if (error) { - DPRINTF(sc, 2, ("%s: Could not acquire iic bus for getting status %d\n", - device_xname(sc->sc_dev), error)); - goto out; + DPRINTF(sc, 2, ("%s: Could not acquire iic bus for " + "getting status %d\n", device_xname(sc->sc_dev), + error)); + return error; } } error = sht3x_cmdr(sc, SHT3X_GET_STATUS_REGISTER, buf, 3); if (error) { DPRINTF(sc, 2, ("%s: Error getting status: %d\n", device_xname(sc->sc_dev), error)); + goto out; } - out: + + uint8_t c = sht3x_crc(&buf[0], 2); + if (c == buf[2]) { + *reg = buf[0] << 8 | buf[1]; + } else { + error = EINVAL; + } +out: if (! have_bus) { iic_release_bus(sc->sc_tag, 0); } - if (!error) { - uint8_t c; - - c = sht3x_crc(&buf[0],2); - if (c == buf[2]) { - *reg = buf[0] << 8 | buf[1]; - } else { - error = EINVAL; - } - } - return error; } static int sht3x_clear_status_register(void *aux, bool have_bus) { - struct sht3x_sc *sc; - sc = aux; - int error = 0; + struct sht3x_sc *sc = aux; + int error; if (! have_bus) { error = iic_acquire_bus(sc->sc_tag, 0); if (error) { - DPRINTF(sc, 2, ("%s: Could not acquire iic bus for clearing status %d\n", - device_xname(sc->sc_dev), error)); - goto out; + DPRINTF(sc, 2, ("%s: Could not acquire iic bus for " + "clearing status %d\n", device_xname(sc->sc_dev), + error)); + return error; } } error = sht3x_cmdr(sc, SHT3X_CLEAR_STATUS_REGISTER, NULL, 0); @@ -419,7 +405,6 @@ sht3x_clear_status_register(void *aux, b DPRINTF(sc, 2, ("%s: Error clear status register: %d\n", device_xname(sc->sc_dev), error)); } - out: if (! have_bus) { iic_release_bus(sc->sc_tag, 0); } @@ -438,16 +423,18 @@ sht3x_thread(void *aux) while (!sc->sc_stopping && !sc->sc_dying) { if (sc->sc_initperiodic) { - error = sht3x_init_periodic_measurement(sc,&sdelay); + error = sht3x_init_periodic_measurement(sc, &sdelay); if (error) { - DPRINTF(sc, 2, ("%s: Error initing periodic measurement " - "in thread: %d\n", device_xname(sc->sc_dev), error)); + DPRINTF(sc, 2, ("%s: Error initing periodic " + "measurement in thread: %d\n", + device_xname(sc->sc_dev), error)); } sc->sc_initperiodic = false; } rv = cv_timedwait(&sc->sc_condvar, &sc->sc_threadmutex, mstohz(sdelay)); - if (rv == EWOULDBLOCK && !sc->sc_stopping && !sc->sc_initperiodic && !sc->sc_dying) { + if (rv == EWOULDBLOCK && !sc->sc_stopping && + !sc->sc_initperiodic && !sc->sc_dying) { sht3x_take_periodic_measurement(sc); } } @@ -458,14 +445,17 @@ sht3x_thread(void *aux) int sht3x_init_periodic_measurement(void *aux, int *sdelay) { - struct sht3x_sc *sc; - sc = aux; - int i,error = 0; - uint16_t r = 0; + struct sht3x_sc *sc = aux; + size_t i; + int error; + uint16_t r; for (i = 0; i < __arraycount(sht3x_periodic_rate); i++) { - if (strncmp(sc->sc_repeatability,sht3x_periodic_rate[i].repeatability,SHT3X_REP_NAME) == 0 && - strncmp(sc->sc_periodic_rate, sht3x_periodic_rate[i].rate,SHT3X_RATE_NAME) == 0) { + if (strncmp(sc->sc_repeatability, + sht3x_periodic_rate[i].repeatability, SHT3X_REP_NAME) == 0 && + strncmp(sc->sc_periodic_rate, sht3x_periodic_rate[i].rate, + SHT3X_RATE_NAME) == 0) + { r = sht3x_periodic_rate[i].cmd; *sdelay = sht3x_periodic_rate[i].sdelay; break; @@ -473,123 +463,138 @@ sht3x_init_periodic_measurement(void *au } if (i == __arraycount(sht3x_periodic_rate)) { - error = 1; *sdelay = 100; + return ENODEV; } DPRINTF(sc, 2, ("%s: Would init with: %x\n", device_xname(sc->sc_dev), r)); - if (error == 0) { - mutex_enter(&sc->sc_mutex); + mutex_enter(&sc->sc_mutex); - error = iic_acquire_bus(sc->sc_tag, 0); - if (error) { - DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: " - " %d\n", device_xname(sc->sc_dev), error)); - } else { - error = sht3x_take_break(sc,true); - if (error) { - DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: " - " %d\n", device_xname(sc->sc_dev), error)); - } + error = iic_acquire_bus(sc->sc_tag, 0); + if (error) { + DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: " + " %d\n", device_xname(sc->sc_dev), error)); + goto out; + } - error = sht3x_cmdr(sc, r, NULL, 0); - if (error) { - DPRINTF(sc, 2, ("%s: Error sending periodic measurement command: %d\n", - device_xname(sc->sc_dev), error)); - } - iic_release_bus(sc->sc_tag, 0); - sc->sc_isperiodic = true; - strlcpy(sc->sc_mode,"periodic",SHT3X_MODE_NAME); - } - mutex_exit(&sc->sc_mutex); + error = sht3x_take_break(sc, true); + if (error) { + DPRINTF(sc, 2, ("%s: Could not acquire iic bus for initing: " + " %d\n", device_xname(sc->sc_dev), error)); + goto out; + } + + error = sht3x_cmdr(sc, r, NULL, 0); + if (error) { + DPRINTF(sc, 2, + ("%s: Error sending periodic measurement command: %d\n", + device_xname(sc->sc_dev), error)); + goto out; } + sc->sc_isperiodic = true; + strlcpy(sc->sc_mode, "periodic", SHT3X_MODE_NAME); + +out: + iic_release_bus(sc->sc_tag, 0); + mutex_exit(&sc->sc_mutex); return error; } static void sht3x_take_periodic_measurement(void *aux) { - struct sht3x_sc *sc; - sc = aux; - int error = 0, data_error = 0; - uint8_t rawbuf[6]; + struct sht3x_sc *sc = aux; + int error; struct sht3x_read_q *pp; + uint8_t rawbuf[MAX(sizeof(sc->sc_pbuffer), sizeof(pp->measurement))]; + uint16_t status_reg; mutex_enter(&sc->sc_mutex); error = iic_acquire_bus(sc->sc_tag, 0); if (error) { DPRINTF(sc, 2, ("%s: Could not acquire iic bus for getting " "periodic data: %d\n", device_xname(sc->sc_dev), error)); - } else { - uint16_t status_reg; + goto out; + } - error = sht3x_get_status_register(sc, &status_reg, true); - if (error) { - DPRINTF(sc, 2, ("%s: Error getting status register periodic: %d\n", - device_xname(sc->sc_dev), error)); - } else { - if (status_reg & SHT3X_RESET_DETECTED) { - aprint_error_dev(sc->sc_dev, "Reset detected in periodic mode. Heater may have been reset.\n"); - delay(3000); - sht3x_take_break(sc,true); - sht3x_clear_status_register(sc, true); - sc->sc_heateron = status_reg & SHT3X_HEATER_STATUS; - sc->sc_initperiodic = true; - } else { - data_error = sht3x_cmdr(sc, SHT3X_PERIODIC_FETCH_DATA, rawbuf, 6); - /* EIO is actually expected if the poll interval is faster - * than the rate that the sensor is set to. Unfortunally, - * this will also mess with the ability to detect an actual problem - * with the sensor in periodic mode, so we do the best we can here. - */ - if (data_error && data_error != EIO) { - DPRINTF(sc, 2, ("%s: Error sending periodic fetch command: %d\n", - device_xname(sc->sc_dev), data_error)); - } - } - } - iic_release_bus(sc->sc_tag, 0); - /* If there was no errors from anything then the data should be - * valid. + error = sht3x_get_status_register(sc, &status_reg, true); + if (error) { + DPRINTF(sc, 2, + ("%s: Error getting status register periodic: %d\n", + device_xname(sc->sc_dev), error)); + goto err; + } + + if (status_reg & SHT3X_RESET_DETECTED) { + aprint_error_dev(sc->sc_dev, "Reset detected in periodic mode. " + "Heater may have been reset.\n"); + delay(3000); + sht3x_take_break(sc, true); + sht3x_clear_status_register(sc, true); + sc->sc_heateron = status_reg & SHT3X_HEATER_STATUS; + sc->sc_initperiodic = true; + } else { + int data_error = sht3x_cmdr(sc, SHT3X_PERIODIC_FETCH_DATA, + rawbuf, sizeof(rawbuf)); + /* + * EIO is actually expected if the poll interval is faster + * than the rate that the sensor is set to. Unfortunally, + * this will also mess with the ability to detect an actual + * problem with the sensor in periodic mode, so we do the best + * we can here. */ - if (!data_error && !error) { - DPRINTF(sc, 2, ("%s: Raw periodic: %x%x - %x -- %x%x - %x\n", - device_xname(sc->sc_dev), rawbuf[0], rawbuf[1], rawbuf[2], - rawbuf[3], rawbuf[4], rawbuf[5])); - memcpy(sc->sc_pbuffer,rawbuf,6); - - if (sc->sc_opened) { - mutex_enter(&sc->sc_read_mutex); - pp = pool_cache_get(sc->sc_readpool,PR_NOWAIT); - if (pp != NULL) { - memcpy(pp->measurement,rawbuf,6); - DPRINTF(sc, 4, ("%s: Queue insert\n",device_xname(sc->sc_dev))); - SIMPLEQ_INSERT_HEAD(&sc->sc_read_queue,pp,read_q); - } else { - aprint_error("Could not allocate memory for pool read\n"); - } - cv_signal(&sc->sc_condreadready); - mutex_exit(&sc->sc_read_mutex); + if (data_error) { + if (data_error != EIO) { + DPRINTF(sc, 2, ("%s: Error sending periodic " + "fetch command: %d\n", + device_xname(sc->sc_dev), data_error)); } + goto err; + } + } + iic_release_bus(sc->sc_tag, 0); + /* + * If there was no errors from anything then the data should be + * valid. + */ + DPRINTF(sc, 2, ("%s: Raw periodic: %x%x - %x -- %x%x - %x\n", + device_xname(sc->sc_dev), rawbuf[0], rawbuf[1], rawbuf[2], + rawbuf[3], rawbuf[4], rawbuf[5])); + memcpy(sc->sc_pbuffer, rawbuf, sizeof(sc->sc_pbuffer)); + + if (sc->sc_opened) { + mutex_enter(&sc->sc_read_mutex); + pp = pool_cache_get(sc->sc_readpool, PR_NOWAIT); + if (pp == NULL) { + aprint_error_dev(sc->sc_dev, + "Could not allocate memory for pool read\n"); } else { - /* We are only going to worry about errors when it was not related - * to actually getting data. That is a likely indicator of a problem - * with the sensor. - */ - if (error) { - DPRINTF(sc, 2, ("%s: Raw periodic with error: %x%x - %x -- %x%x - %x -- %d\n", - device_xname(sc->sc_dev), rawbuf[0], rawbuf[1], rawbuf[2], - rawbuf[3], rawbuf[4], rawbuf[5], error)); - uint8_t bad[6] = "dedbef"; - memcpy(sc->sc_pbuffer, bad, 6); - } + memcpy(pp->measurement, rawbuf, sizeof(pp->measurement)); + DPRINTF(sc, 4, ("%s: Queue insert\n", + device_xname(sc->sc_dev))); + SIMPLEQ_INSERT_HEAD(&sc->sc_read_queue, pp, read_q); } - + cv_signal(&sc->sc_condreadready); + mutex_exit(&sc->sc_read_mutex); } +out: + mutex_exit(&sc->sc_mutex); + return; +err: + /* + * We are only going to worry about errors when it was not related + * to actually getting data. That is a likely indicator of a problem + * with the sensor. + */ + DPRINTF(sc, 2, ("%s: Raw periodic with error: %x%x - %x -- " + "%x%x - %x -- %d\n", device_xname(sc->sc_dev), rawbuf[0], rawbuf[1], + rawbuf[2], rawbuf[3], rawbuf[4], rawbuf[5], error)); + iic_release_bus(sc->sc_tag, 0); + memcpy(sc->sc_pbuffer, "dedbef", sizeof(sc->sc_pbuffer)); mutex_exit(&sc->sc_mutex); } @@ -685,7 +690,7 @@ sht3x_set_heater(struct sht3x_sc *sc) if (error) { DPRINTF(sc, 2, ("%s:%s: Failed to acquire bus: %d\n", device_xname(sc->sc_dev), __func__, error)); - return error; + goto out; } if (sc->sc_heateron) { @@ -697,6 +702,7 @@ sht3x_set_heater(struct sht3x_sc *sc) error = sht3x_cmdr(sc, cmd, NULL, 0); iic_release_bus(sc->sc_tag,0); +out: mutex_exit(&sc->sc_mutex); return error; @@ -708,9 +714,9 @@ sht3x_verify_sysctl_modes(SYSCTLFN_ARGS) char buf[SHT3X_MODE_NAME]; struct sht3x_sc *sc; struct sysctlnode node; - int error = 0; bool is_ss = false; bool is_periodic = false; + int error; node = *rnode; sc = node.sysctl_data; @@ -724,31 +730,30 @@ sht3x_verify_sysctl_modes(SYSCTLFN_ARGS) return EINVAL; } - is_ss = (strncmp(node.sysctl_data, "single-shot", SHT3X_MODE_NAME) == 0); - is_periodic = (strncmp(node.sysctl_data, "periodic", SHT3X_MODE_NAME) == 0); + is_ss = strncmp(node.sysctl_data, "single-shot", SHT3X_MODE_NAME) == 0; + is_periodic = strncmp(node.sysctl_data, "periodic", SHT3X_MODE_NAME) + == 0; - if (is_ss || is_periodic) { - (void) memcpy(sc->sc_mode, node.sysctl_data, SHT3X_MODE_NAME); - } else { - error = EINVAL; + if (!is_ss && !is_periodic) { + return EINVAL; } - if (error == 0) { - if (is_ss) { - sht3x_stop_thread(sc); - sc->sc_stopping = false; - sc->sc_initperiodic = false; - sc->sc_isperiodic = false; - } - if (is_periodic) { - sc->sc_stopping = false; - sc->sc_initperiodic = true; - sc->sc_isperiodic = true; - sht3x_start_thread(sc); - } + (void) memcpy(sc->sc_mode, node.sysctl_data, SHT3X_MODE_NAME); + if (is_ss) { + sht3x_stop_thread(sc); + sc->sc_stopping = false; + sc->sc_initperiodic = false; + sc->sc_isperiodic = false; } - return error; + if (is_periodic) { + sc->sc_stopping = false; + sc->sc_initperiodic = true; + sc->sc_isperiodic = true; + sht3x_start_thread(sc); + } + + return 0; } int @@ -757,7 +762,7 @@ sht3x_verify_sysctl_repeatability(SYSCTL char buf[SHT3X_REP_NAME]; struct sht3x_sc *sc; struct sysctlnode node; - int error = 0; + int error; size_t i; node = *rnode; @@ -792,7 +797,7 @@ sht3x_verify_sysctl_rate(SYSCTLFN_ARGS) char buf[SHT3X_RATE_NAME]; struct sht3x_sc *sc; struct sysctlnode node; - int error = 0; + int error; size_t i; node = *rnode; @@ -812,6 +817,7 @@ sht3x_verify_sysctl_rate(SYSCTLFN_ARGS) if (i == __arraycount(sht3x_periodic_rate)) return EINVAL; + (void) memcpy(sc->sc_periodic_rate, node.sysctl_data, SHT3X_RATE_NAME); if (sc->sc_isperiodic) { @@ -824,20 +830,18 @@ sht3x_verify_sysctl_rate(SYSCTLFN_ARGS) static int sht3x_cmddelay(uint16_t cmd) { - int r = -2; + size_t i; - for(int i = 0;i < __arraycount(sht3x_timings);i++) { + for (i = 0; i < __arraycount(sht3x_timings); i++) { if (cmd == sht3x_timings[i].cmd) { - r = sht3x_timings[i].typicaldelay; break; } } - if (r == -2) { - r = -1; + if (i == __arraycount(sht3x_timings)) { + return -1; } - - return r; + return sht3x_timings[i].typicaldelay; } static int @@ -854,23 +858,27 @@ sht3x_cmd(i2c_tag_t tag, i2c_addr_t addr cmd8[0] = cmd[0] >> 8; cmd8[1] = cmd[0] & 0x00ff; - error = iic_exec(tag,I2C_OP_WRITE_WITH_STOP,addr,&cmd8[0],clen,NULL,0,0); + error = iic_exec(tag, I2C_OP_WRITE_WITH_STOP, addr, &cmd8[0], clen, + NULL, 0, 0); + if (error) + return error; - if (error == 0) { - cmddelay = sht3x_cmddelay(cmd[0]); - if (cmddelay != -1) { - delay(cmddelay); - } + cmddelay = sht3x_cmddelay(cmd[0]); + if (cmddelay != -1) { + delay(cmddelay); + } - /* Not all commands return anything */ - if (blen > 0) { - for (int aint = 0; aint < readattempts; aint++) { - error = iic_exec(tag,I2C_OP_READ_WITH_STOP,addr,NULL,0,buf,blen,0); - if (error == 0) - break; - delay(1000); - } - } + /* Not all commands return anything */ + if (blen == 0) { + return 0; + } + + for (int aint = 0; aint < readattempts; aint++) { + error = iic_exec(tag, I2C_OP_READ_WITH_STOP, addr, NULL, 0, buf, + blen, 0); + if (error == 0) + break; + delay(1000); } return error; @@ -879,11 +887,12 @@ sht3x_cmd(i2c_tag_t tag, i2c_addr_t addr static int sht3x_cmdr(struct sht3x_sc *sc, uint16_t cmd, uint8_t *buf, size_t blen) { - return sht3x_cmd(sc->sc_tag, sc->sc_addr, &cmd, 2, buf, blen, sc->sc_readattempts); + return sht3x_cmd(sc->sc_tag, sc->sc_addr, &cmd, 2, buf, blen, + sc->sc_readattempts); } static uint8_t -sht3x_crc(uint8_t * data, size_t size) +sht3x_crc(uint8_t *data, size_t size) { uint8_t crc = 0xFF; @@ -1020,25 +1029,24 @@ sht3x_match(device_t parent, cfdata_t ma } /* indirect config - check for configured address */ - if (ia->ia_addr == SHT3X_TYPICAL_ADDR_1 || - ia->ia_addr == SHT3X_TYPICAL_ADDR_2) { - /* - * Check to see if something is really at this i2c address. This will - * keep phantom devices from appearing - */ - if (iic_acquire_bus(ia->ia_tag, 0) != 0) { - if (matchdebug) - printf("in match acquire bus failed\n"); - return 0; - } - - error = sht3x_poke(ia->ia_tag, ia->ia_addr, matchdebug); - iic_release_bus(ia->ia_tag, 0); + if (ia->ia_addr != SHT3X_TYPICAL_ADDR_1 && + ia->ia_addr != SHT3X_TYPICAL_ADDR_2) + return 0; - return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0; - } else { + /* + * Check to see if something is really at this i2c address. + * This will keep phantom devices from appearing + */ + if (iic_acquire_bus(ia->ia_tag, 0) != 0) { + if (matchdebug) + printf("in match acquire bus failed\n"); return 0; } + + error = sht3x_poke(ia->ia_tag, ia->ia_addr, matchdebug); + iic_release_bus(ia->ia_tag, 0); + + return error == 0 ? I2C_MATCH_ADDRESS_AND_PROBE : 0; } static void @@ -1059,10 +1067,10 @@ sht3x_attach(device_t parent, device_t s sc->sc_tag = ia->ia_tag; sc->sc_addr = ia->ia_addr; sc->sc_sht3xdebug = 0; - strlcpy(sc->sc_mode,"single-shot",SHT3X_MODE_NAME); + strlcpy(sc->sc_mode, "single-shot", SHT3X_MODE_NAME); sc->sc_isperiodic = false; - strlcpy(sc->sc_repeatability,"high",SHT3X_REP_NAME); - strlcpy(sc->sc_periodic_rate,"1.0mps",SHT3X_RATE_NAME); + strlcpy(sc->sc_repeatability, "high", SHT3X_REP_NAME); + strlcpy(sc->sc_periodic_rate, "1.0mps", SHT3X_RATE_NAME); sc->sc_readattempts = 10; sc->sc_ignorecrc = false; sc->sc_heateron = false; @@ -1096,7 +1104,8 @@ sht3x_attach(device_t parent, device_t s } sc->sc_readpoolname = kmem_asprintf("sht3xrp%d",device_unit(self)); - sc->sc_readpool = pool_cache_init(sizeof(struct sht3x_read_q),0,0,0,sc->sc_readpoolname,NULL,IPL_VM,NULL,NULL,NULL); + sc->sc_readpool = pool_cache_init(sizeof(struct sht3x_read_q), 0, 0, 0, + sc->sc_readpoolname, NULL, IPL_VM, NULL, NULL, NULL); pool_cache_sethiwat(sc->sc_readpool,100); SIMPLEQ_INIT(&sc->sc_read_queue); @@ -1141,8 +1150,9 @@ sht3x_attach(device_t parent, device_t s sncrcpt2 = sht3x_crc(&buf[3],2); serialnumber = (buf[0] << 24) | (buf[1] << 16) | (buf[3] << 8) | buf[4]; - DPRINTF(sc, 2, ("%s: read serial number values: %02x%02x - %02x - %02x%02x - %02x -- %02x %02x\n", - device_xname(sc->sc_dev), buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], sncrcpt1, sncrcpt2)); + DPRINTF(sc, 2, ("%s: read serial number values: %02x%02x - %02x - " + "%02x%02x - %02x -- %02x %02x\n", device_xname(sc->sc_dev), buf[0], + buf[1], buf[2], buf[3], buf[4], buf[5], sncrcpt1, sncrcpt2)); iic_release_bus(sc->sc_tag, 0); if (error != 0) { @@ -1156,9 +1166,6 @@ sht3x_attach(device_t parent, device_t s sc->sc_sensors[i].units = sht3x_sensors[i].type; sc->sc_sensors[i].state = ENVSYS_SINVALID; -#ifdef __did_not_work - sc->sc_sensors[i].flags |= ENVSYS_FMONLIMITS; -#endif DPRINTF(sc, 2, ("%s: registering sensor %d (%s)\n", __func__, i, sc->sc_sensors[i].desc)); @@ -1175,30 +1182,25 @@ sht3x_attach(device_t parent, device_t s sc->sc_sme->sme_name = device_xname(sc->sc_dev); sc->sc_sme->sme_cookie = sc; sc->sc_sme->sme_refresh = sht3x_refresh; -#ifdef __did_not_work - sc->sc_sme->sme_get_limits = sht3x_get_limits; - sc->sc_sme->sme_set_limits = sht3x_set_limits; -#endif DPRINTF(sc, 2, ("sht3x_attach: registering with envsys\n")); if (sysmon_envsys_register(sc->sc_sme)) { - aprint_error_dev(self, - "unable to register with sysmon\n"); + aprint_error_dev(self, "unable to register with sysmon\n"); sysmon_envsys_destroy(sc->sc_sme); sc->sc_sme = NULL; return; } - /* There is no documented way to ask the chip what version it is. This - is likely fine as the only apparent difference is in how precise the - measurements will be. The actual conversation with the chip is - identical no matter which one you are talking to. - */ + /* + * There is no documented way to ask the chip what version it is. This + * is likely fine as the only apparent difference is in how precise the + * measurements will be. The actual conversation with the chip is + * identical no matter which one you are talking to. + */ aprint_normal_dev(self, "Sensirion SHT30/SHT31/SHT35, " - "Serial number: %x%s", - serialnumber, + "Serial number: %x%s", serialnumber, (sncrcpt1 == buf[2] && sncrcpt2 == buf[5]) ? "\n" : " (bad crc)\n"); return; out: @@ -1207,7 +1209,7 @@ out: } static uint16_t -sht3x_compute_measure_command_ss(char *repeatability) +sht3x_compute_measure_command_ss(const char *repeatability) { int i; uint16_t r; @@ -1221,33 +1223,34 @@ sht3x_compute_measure_command_ss(char *r } if (i == __arraycount(sht3x_repeatability_ss)) - panic("Single-shot could not find command for repeatability: %s\n", repeatability); + panic("Single-shot could not find command for " + "repeatability: %s\n", repeatability); return r; } /* - The documented conversion calculations for the raw values are as follows: - - %RH = (-6 + 125 * rawvalue / 65535) - - T in Celsius = (-45 + 175 * rawvalue / 65535) - - It follows then: - - T in Kelvin = (228.15 + 175 * rawvalue / 65535) - - given the relationship between Celsius and Kelvin - - What follows reorders the calculation a bit and scales it up to avoid - the use of any floating point. All that would really have to happen - is a scale up to 10^6 for the sysenv framework, which wants - temperature in micro-kelvin and percent relative humidity scaled up - 10^6, but since this conversion uses 64 bits due to intermediate - values that are bigger than 32 bits the conversion first scales up to - 10^9 and the scales back down by 10^3 at the end. This preserves some - precision in the conversion that would otherwise be lost. -*/ + * The documented conversion calculations for the raw values are as follows: + * + * %RH = (-6 + 125 * rawvalue / 65535) + * + * T in Celsius = (-45 + 175 * rawvalue / 65535) + * + * It follows then: + * + * T in Kelvin = (228.15 + 175 * rawvalue / 65535) + * + * given the relationship between Celsius and Kelvin + * + * What follows reorders the calculation a bit and scales it up to avoid + * the use of any floating point. All that would really have to happen + * is a scale up to 10^6 for the sysenv framework, which wants + * temperature in micro-kelvin and percent relative humidity scaled up + * 10^6, but since this conversion uses 64 bits due to intermediate + * values that are bigger than 32 bits the conversion first scales up to + * 10^9 and the scales back down by 10^3 at the end. This preserves some + * precision in the conversion that would otherwise be lost. + */ static uint64_t sht3x_compute_temp_from_raw(uint8_t msb, uint8_t lsb) { @@ -1301,572 +1304,127 @@ sht3x_compute_rh_from_raw(uint8_t msb, u return q; } -/* These are the the same as above except solved for the raw tick rather than - * temperature or humidity. These are needed for setting the alert limits, but - * since that did not work, disable these too for now. - */ -#ifdef __did_not_work -static uint16_t -sht3x_compute_raw_from_temp(uint32_t temp) -{ - uint64_t i1; - uint32_t tempc; - - tempc = temp - 272150000; - tempc = tempc / 1000000; - - i1 = (13107 * tempc) + 589815; - return (uint16_t)(i1 / 35); -} - -static uint16_t -sht3x_compute_raw_from_rh(uint32_t mrh) -{ - uint64_t i1; - uint32_t rh; - - rh = mrh / 1000000; - - i1 = 13107 * rh; - return (uint16_t)(i1 / 20); -} -#endif - -static void -sht3x_refresh(struct sysmon_envsys * sme, envsys_data_t * edata) +static int +sht3x_parse_data(struct sht3x_sc *sc, envsys_data_t *edata, uint8_t *rawdata) { - struct sht3x_sc *sc; - sc = sme->sme_cookie; - int error; - uint8_t rawdata[6]; - uint16_t measurement_command_ss; uint64_t current_value; uint8_t *svalptr; - edata->state = ENVSYS_SINVALID; - - mutex_enter(&sc->sc_mutex); - - if (!sc->sc_isperiodic) { - error = iic_acquire_bus(sc->sc_tag, 0); - if (error) { - DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n", - device_xname(sc->sc_dev), error)); - goto out; - } - - measurement_command_ss = sht3x_compute_measure_command_ss(sc->sc_repeatability); - DPRINTF(sc, 2, ("%s: Measurement command: %04x\n", - device_xname(sc->sc_dev), measurement_command_ss)); - error = sht3x_cmdr(sc,measurement_command_ss,rawdata,6); - if (error == 0) { - DPRINTF(sc, 2, ("%s: Raw data ss: %02x%02x %02x - %02x%02x %02x\n", - device_xname(sc->sc_dev), rawdata[0], rawdata[1], rawdata[2], - rawdata[3], rawdata[4], rawdata[5])); - switch (edata->sensor) { - case SHT3X_TEMP_SENSOR: - svalptr = &rawdata[0]; - current_value = sht3x_compute_temp_from_raw(rawdata[0],rawdata[1]); - break; - case SHT3X_HUMIDITY_SENSOR: - svalptr = &rawdata[3]; - current_value = sht3x_compute_rh_from_raw(rawdata[3],rawdata[4]); - break; - default: - error = EINTR; - break; - } - - if (error == 0) { - uint8_t testcrc; - - /* Fake out the CRC check if being asked to ignore CRC */ - if (sc->sc_ignorecrc) { - testcrc = *(svalptr + 2); - } else { - testcrc = sht3x_crc(svalptr,2); - } - - if (*(svalptr + 2) == testcrc) { - edata->value_cur = (uint32_t) current_value; - edata->state = ENVSYS_SVALID; - } else { - error = EINVAL; - } - } - } - - if (error) { - DPRINTF(sc, 2, ("%s: Failed to get new status in refresh for single-shot %d\n", - device_xname(sc->sc_dev), error)); - } - - uint16_t sbuf; - int status_error; - - status_error = sht3x_get_status_register(sc, &sbuf, true); - - if (!status_error) { - DPRINTF(sc, 2, ("%s: read status register single-shot: %04x\n", - device_xname(sc->sc_dev), sbuf)); - - if (sbuf & SHT3X_RESET_DETECTED) { - aprint_error_dev(sc->sc_dev, "Reset detected in single shot mode. Heater may have been reset\n"); - sht3x_clear_status_register(sc, true); - } - - sc->sc_heateron = sbuf & SHT3X_HEATER_STATUS; - } - - iic_release_bus(sc->sc_tag, 0); - } else { - error = 0; - memcpy(rawdata,sc->sc_pbuffer,6); - - DPRINTF(sc, 2, ("%s: Raw data periodic: %02x%02x %02x - %02x%02x %02x\n", - device_xname(sc->sc_dev), rawdata[0], rawdata[1], rawdata[2], - rawdata[3], rawdata[4], rawdata[5])); - - switch (edata->sensor) { - case SHT3X_TEMP_SENSOR: - svalptr = &rawdata[0]; - current_value = sht3x_compute_temp_from_raw(rawdata[0],rawdata[1]); - break; - case SHT3X_HUMIDITY_SENSOR: - svalptr = &rawdata[3]; - current_value = sht3x_compute_rh_from_raw(rawdata[3],rawdata[4]); - break; - default: - error = EINTR; - break; - } - - if (error == 0) { - uint8_t testcrc; - - /* Fake out the CRC check if being asked to ignore CRC */ - if (sc->sc_ignorecrc) { - testcrc = *(svalptr + 2); - } else { - testcrc = sht3x_crc(svalptr,2); - } - - if (*(svalptr + 2) == testcrc) { - edata->value_cur = (uint32_t) current_value; - edata->state = ENVSYS_SVALID; - } else { - error = EINVAL; - } - } - - if (error) { - DPRINTF(sc, 2, ("%s: Failed to get new status in refresh for periodic %d\n", - device_xname(sc->sc_dev), error)); - } - } -out: - mutex_exit(&sc->sc_mutex); -} - -#ifdef __did_not_work -static void -sht3x_get_limits(struct sysmon_envsys *sme, envsys_data_t *edata, - sysmon_envsys_lim_t *limits, uint32_t *props) -{ - struct sht3x_sc *sc = sme->sme_cookie; - uint16_t rawlimitshigh, rawlimitslow; - uint16_t templimithigh, rhlimithigh, - templimitlow, rhlimitlow; - uint8_t templimithighmsb, templimithighlsb, - templimitlowmsb, templimitlowlsb; - uint8_t rhlimithighmsb, rhlimithighlsb, - rhlimitlowmsb, rhlimitlowlsb; - int error; - uint8_t lbuf[3]; - uint8_t limitscrchigh, limitskcrchigh, - limitscrclow, limitskcrclow; - - *props = 0; - - mutex_enter(&sc->sc_mutex); - error = iic_acquire_bus(sc->sc_tag, 0); - if (error) { - DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n", - device_xname(sc->sc_dev), error)); - goto out; - } - - error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, lbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n", - device_xname(sc->sc_dev), error)); - goto out; - } - - rawlimitshigh = (lbuf[0] << 8) | lbuf[1]; - limitskcrchigh = lbuf[2]; - limitscrchigh = sht3x_crc(&lbuf[0],2); - - templimithigh = ((rawlimitshigh & 0x1FF) << 7); - templimithighmsb = (uint8_t)(templimithigh >> 8); - templimithighlsb = (uint8_t)(templimithigh & 0x00FF); - DPRINTF(sc, 2, ("%s: Limits high intermediate temp: %04x %04x %02x %02x\n", - device_xname(sc->sc_dev), rawlimitshigh, templimithigh, templimithighmsb, - templimithighlsb)); - - rhlimithigh = (rawlimitshigh & 0xFE00); - rhlimithighmsb = (uint8_t)(rhlimithigh >> 8); - rhlimithighlsb = (uint8_t)(rhlimithigh & 0x00FF); - DPRINTF(sc, 2, ("%s: Limits high intermediate rh: %04x %04x %02x %02x\n", - device_xname(sc->sc_dev), rawlimitshigh, rhlimithigh, rhlimithighmsb, - rhlimithighlsb)); - - DPRINTF(sc, 2, ("%s: Limit high raw: %02x%02x %02x %02x %02x\n", - device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2], - limitscrchigh, limitskcrchigh)); - - error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_SET, lbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n", - device_xname(sc->sc_dev), error)); - goto out; - } - - rawlimitslow = (lbuf[0] << 8) | lbuf[1]; - limitskcrclow = lbuf[2]; - limitscrclow = sht3x_crc(&lbuf[0],2); - - templimitlow = ((rawlimitslow & 0x1FF) << 7); - templimitlowmsb = (uint8_t)(templimitlow >> 8); - templimitlowlsb = (uint8_t)(templimitlow & 0x00FF); - DPRINTF(sc, 2, ("%s: Limits low intermediate temp: %04x %04x %02x %02x\n", - device_xname(sc->sc_dev), rawlimitslow, templimitlow, templimitlowmsb, - templimitlowlsb)); - - rhlimitlow = (rawlimitslow & 0xFE00); - rhlimitlowmsb = (uint8_t)(rhlimitlow >> 8); - rhlimitlowlsb = (uint8_t)(rhlimitlow & 0x00FF); - DPRINTF(sc, 2, ("%s: Limits low intermediate rh: %04x %04x %02x %02x\n", - device_xname(sc->sc_dev), rawlimitslow, rhlimitlow, rhlimitlowmsb, - rhlimitlowlsb)); - - DPRINTF(sc, 2, ("%s: Limit low raw: %02x%02x %02x %02x %02x\n", - device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2], - limitscrclow, limitskcrclow)); - + DPRINTF(sc, 2, ("%s: Raw data: %02x%02x %02x - %02x%02x %02x\n", + device_xname(sc->sc_dev), rawdata[0], rawdata[1], rawdata[2], + rawdata[3], rawdata[4], rawdata[5])); switch (edata->sensor) { case SHT3X_TEMP_SENSOR: - if (limitscrchigh == limitskcrchigh) { - limits->sel_critmax = sht3x_compute_temp_from_raw(templimithighmsb, templimithighlsb); - *props |= PROP_CRITMAX; - } - if (limitscrclow == limitskcrclow) { - limits->sel_critmin = sht3x_compute_temp_from_raw(templimitlowmsb, templimitlowlsb); - *props |= PROP_CRITMIN; - } + current_value = sht3x_compute_temp_from_raw(rawdata[0], + rawdata[1]); + svalptr = &rawdata[0]; break; case SHT3X_HUMIDITY_SENSOR: - if (limitscrchigh == limitskcrchigh) { - limits->sel_critmax = sht3x_compute_rh_from_raw(rhlimithighmsb, rhlimithighlsb); - *props |= PROP_CRITMAX; - } - if (limitscrclow == limitskcrclow) { - limits->sel_critmin = sht3x_compute_rh_from_raw(rhlimitlowmsb, rhlimitlowlsb); - *props |= PROP_CRITMIN; - } + current_value = sht3x_compute_rh_from_raw(rawdata[3], + rawdata[4]); + svalptr = &rawdata[3]; break; default: - break; - } - - if (*props != 0) - *props |= PROP_DRIVER_LIMITS; - - iic_release_bus(sc->sc_tag, 0); - out: - mutex_exit(&sc->sc_mutex); -} - -static void -sht3x_set_alert_limits(void *aux, uint16_t high, uint16_t low, bool have_bus) -{ - struct sht3x_sc *sc; - sc = aux; - - int error = 0; - uint8_t hbuf[3]; - uint8_t lbuf[3]; - - if (! have_bus) { - error = iic_acquire_bus(sc->sc_tag, 0); - if (error) { - DPRINTF(sc, 2, ("%s: Could not acquire iic bus for setting alerts %d\n", - device_xname(sc->sc_dev), error)); - goto out; - } - } - - hbuf[0] = high >> 8; - hbuf[1] = high & 0x00FF; - hbuf[2] = sht3x_crc(&hbuf[0],2); - - lbuf[0] = low >> 8; - lbuf[1] = low & 0x00FF; - lbuf[2] = sht3x_crc(&lbuf[0],2); - - error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_SET, hbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not set high alert for SET %d\n", - device_xname(sc->sc_dev), error)); - goto out; - } - error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_CLEAR, hbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n", - device_xname(sc->sc_dev), error)); - goto out; - } - error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_SET, lbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not set low alert for SET %d\n", - device_xname(sc->sc_dev), error)); - goto out; - } - error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_CLEAR, lbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n", - device_xname(sc->sc_dev), error)); + DPRINTF(sc, 2, ("%s: bad sensor type %d\n", + device_xname(sc->sc_dev), edata->sensor)); + return EINTR; + } + uint8_t testcrc; + /* Fake out the CRC check if being asked to ignore CRC */ + if (sc->sc_ignorecrc) { + testcrc = *(svalptr + 2); + } else { + testcrc = sht3x_crc(svalptr, 2); } - out: - if (! have_bus) { - iic_release_bus(sc->sc_tag, 0); + if (*(svalptr + 2) != testcrc) { + DPRINTF(sc, 2, ("%s: Failed to get new status in refresh %d != %d\n", + device_xname(sc->sc_dev), (*svalptr + 2), testcrc)); + return EINVAL; } + edata->value_cur = (uint32_t) current_value; + edata->state = ENVSYS_SVALID; + return 0; } -static void -sht3x_set_alert_limits2(void *aux, uint16_t high, uint16_t low, - uint16_t highminusone, uint16_t lowplusone, bool have_bus) +static int +sht3x_refresh_periodic(struct sysmon_envsys *sme, envsys_data_t *edata) { - struct sht3x_sc *sc; - sc = aux; - - int error = 0; - uint8_t hbuf[3]; - uint8_t lbuf[3]; - uint8_t hbufminusone[3]; - uint8_t lbufplusone[3]; - - if (! have_bus) { - error = iic_acquire_bus(sc->sc_tag, 0); - if (error) { - DPRINTF(sc, 2, ("%s: Could not acquire iic bus for setting alerts %d\n", - device_xname(sc->sc_dev), error)); - goto out; - } - } - - hbuf[0] = high >> 8; - hbuf[1] = high & 0x00FF; - hbuf[2] = sht3x_crc(&hbuf[0],2); - - lbuf[0] = low >> 8; - lbuf[1] = low & 0x00FF; - lbuf[2] = sht3x_crc(&lbuf[0],2); - - hbufminusone[0] = highminusone >> 8; - hbufminusone[1] = highminusone & 0x00FF; - hbufminusone[2] = sht3x_crc(&hbufminusone[0],2); - - lbufplusone[0] = lowplusone >> 8; - lbufplusone[1] = lowplusone & 0x00FF; - lbufplusone[2] = sht3x_crc(&lbufplusone[0],2); - - DPRINTF(sc, 2, ("%s: Physical SET HIGH %02x %02x %02x\n", - device_xname(sc->sc_dev), hbuf[0], hbuf[1], hbuf[2])); - error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_SET, hbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not set high alert for SET %d\n", - device_xname(sc->sc_dev), error)); - goto out; - } - - uint16_t sbuf; - int status_error; - status_error = sht3x_get_status_register(sc, &sbuf, true); - DPRINTF(sc, 2, ("%s: In SETTING, status register %04x -- %d\n", - device_xname(sc->sc_dev), sbuf, status_error)); - - hbuf[0] = 0; - hbuf[1] = 0; - hbuf[2] = 0; - error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, hbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not read high alert for SET %d\n", - device_xname(sc->sc_dev), error)); - goto out; - } - DPRINTF(sc, 2, ("%s: Physical READBACK SET HIGH %02x %02x %02x\n", - device_xname(sc->sc_dev), hbuf[0], hbuf[1], hbuf[2])); + struct sht3x_sc *sc = sme->sme_cookie; + uint8_t rawdata[sizeof(sc->sc_pbuffer)]; - DPRINTF(sc, 2, ("%s: Physical CLEAR HIGH %02x %02x %02x\n", - device_xname(sc->sc_dev), hbufminusone[0], hbufminusone[1], hbufminusone[2])); - error = sht3x_cmdr(sc, SHT3X_WRITE_HIGH_ALERT_CLEAR, hbufminusone, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n", - device_xname(sc->sc_dev), error)); - goto out; - } - hbufminusone[0] = 0; - hbufminusone[1] = 0; - hbufminusone[2] = 0; - error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_CLEAR, hbufminusone, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not read high alert for CLEAR %d\n", - device_xname(sc->sc_dev), error)); - goto out; - } - DPRINTF(sc, 2, ("%s: Physical READBACK CLEAR HIGH %02x %02x %02x\n", - device_xname(sc->sc_dev), hbufminusone[0], hbufminusone[1], hbufminusone[2])); + memcpy(rawdata, sc->sc_pbuffer, sizeof(rawdata)); - DPRINTF(sc, 2, ("%s: Physical SET LOW %02x %02x %02x\n", - device_xname(sc->sc_dev), lbuf[0], lbuf[1], lbuf[2])); - error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_SET, lbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not set low alert for SET %d\n", - device_xname(sc->sc_dev), error)); - goto out; - } - DPRINTF(sc, 2, ("%s: Physical CLEAR LOW %02x %02x %02x\n", - device_xname(sc->sc_dev), lbufplusone[0], lbufplusone[1], lbufplusone[2])); - error = sht3x_cmdr(sc, SHT3X_WRITE_LOW_ALERT_CLEAR, lbufplusone, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not set high alert for CLEAR %d\n", - device_xname(sc->sc_dev), error)); - } + return sht3x_parse_data(sc, edata, rawdata); - out: - if (! have_bus) { - iic_release_bus(sc->sc_tag, 0); - } } -static void -sht3x_set_limits(struct sysmon_envsys *sme, envsys_data_t *edata, - sysmon_envsys_lim_t *limits, uint32_t *props) +static int +sht3x_refresh_oneshot(struct sysmon_envsys *sme, envsys_data_t *edata) { struct sht3x_sc *sc = sme->sme_cookie; - uint16_t rawlimitshigh, rawlimitslow; - uint16_t rawlimitshighclear, rawlimitslowclear; - uint16_t rawlimitshighminusone, rawlimitslowplusone; + uint16_t measurement_command_ss; + uint8_t rawdata[sizeof(sc->sc_pbuffer)]; int error; - uint8_t lbuf[3]; - uint8_t limitscrchigh, limitskcrchigh, - limitscrclow, limitskcrclow; - uint16_t limithigh, limitlow; - uint16_t limithighminusone, limitlowplusone; - if (limits == NULL) { - printf("XXX - Need to set back to default... limits is NULL\n"); - return; - } - - DPRINTF(sc, 2, ("%s: In set_limits - %d -- %d %d\n", - device_xname(sc->sc_dev), edata->sensor, - limits->sel_critmin, limits->sel_critmax)); - - mutex_enter(&sc->sc_mutex); error = iic_acquire_bus(sc->sc_tag, 0); if (error) { DPRINTF(sc, 2, ("%s: Could not acquire i2c bus: %x\n", device_xname(sc->sc_dev), error)); - goto out; + return error; } - error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_SET, lbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n", - device_xname(sc->sc_dev), error)); - goto out; + measurement_command_ss = sht3x_compute_measure_command_ss( + sc->sc_repeatability); + DPRINTF(sc, 2, ("%s: Measurement command: %04x\n", + device_xname(sc->sc_dev), measurement_command_ss)); + error = sht3x_cmdr(sc, measurement_command_ss, rawdata, sizeof(rawdata)); + if (error == 0) { + DPRINTF(sc, 2, ("%s: Failed to get new status in refresh for " + "single-shot %d\n", device_xname(sc->sc_dev), error)); + if ((error = sht3x_parse_data(sc, edata, rawdata)) == 0) + return 0; } - rawlimitshigh = (lbuf[0] << 8) | lbuf[1]; - limitskcrchigh = lbuf[2]; - limitscrchigh = sht3x_crc(&lbuf[0],2); - + uint16_t sbuf; + int status_error = sht3x_get_status_register(sc, &sbuf, true); - error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_SET, lbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not get high alert: %x\n", - device_xname(sc->sc_dev), error)); - goto out; - } + if (!status_error) { + DPRINTF(sc, 2, ("%s: read status register single-shot: %04x\n", + device_xname(sc->sc_dev), sbuf)); - rawlimitslow = (lbuf[0] << 8) | lbuf[1]; - limitskcrclow = lbuf[2]; - limitscrclow = sht3x_crc(&lbuf[0],2); + if (sbuf & SHT3X_RESET_DETECTED) { + aprint_error_dev(sc->sc_dev, + "Reset detected in single shot mode. " + "Heater may have been reset\n"); + sht3x_clear_status_register(sc, true); + } - error = sht3x_cmdr(sc, SHT3X_READ_HIGH_ALERT_CLEAR, lbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not get high alert clear: %x\n", - device_xname(sc->sc_dev), error)); - goto out; + sc->sc_heateron = sbuf & SHT3X_HEATER_STATUS; } - rawlimitshighclear = (lbuf[0] << 8) | lbuf[1]; + iic_release_bus(sc->sc_tag, 0); + return 0; +} - error = sht3x_cmdr(sc, SHT3X_READ_LOW_ALERT_CLEAR, lbuf, 3); - if (error) { - DPRINTF(sc, 2, ("%s: Could not get high alert clear: %x\n", - device_xname(sc->sc_dev), error)); - goto out; - } +static void +sht3x_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) +{ + struct sht3x_sc *sc = sme->sme_cookie; - rawlimitslowclear = (lbuf[0] << 8) | lbuf[1]; + edata->state = ENVSYS_SINVALID; - DPRINTF(sc, 2, ("%s: Set limits current raw limits %04x - %02x %02x ; %04x - %02x %02x ;; %04x %04x\n", - device_xname(sc->sc_dev), rawlimitshigh, limitskcrchigh, limitscrchigh, - rawlimitslow, limitskcrclow, limitscrclow, rawlimitshighclear, rawlimitslowclear)); + mutex_enter(&sc->sc_mutex); - switch (edata->sensor) { - case SHT3X_TEMP_SENSOR: - limithigh = sht3x_compute_raw_from_temp(limits->sel_critmax); - limitlow = sht3x_compute_raw_from_temp(limits->sel_critmin); - limithigh = limithigh >> 7; - limithighminusone = limithigh - 1; - limitlow = limitlow >> 7; - limitlowplusone = limitlow + 1; - rawlimitshigh = (rawlimitshigh & 0xFE00) | limithigh; - rawlimitshighminusone = (rawlimitshigh & 0xFE00) | limithighminusone; - rawlimitslow = (rawlimitslow & 0xFE00) | limitlow; - rawlimitslowplusone = (rawlimitslow & 0xFE00) | limitlowplusone; - DPRINTF(sc, 2, ("%s: Temp new raw limits high/low %04x %04x %04x %04x\n", - device_xname(sc->sc_dev), rawlimitshigh, rawlimitslow, - rawlimitshighminusone, rawlimitslowplusone)); - sht3x_set_alert_limits2(sc, rawlimitshigh, rawlimitslow, - rawlimitshighminusone, rawlimitslowplusone, true); - break; - case SHT3X_HUMIDITY_SENSOR: - limithigh = sht3x_compute_raw_from_rh(limits->sel_critmax); - limitlow = sht3x_compute_raw_from_rh(limits->sel_critmin); - limithigh = limithigh & 0xFE00; - limitlow = limitlow & 0xFE00; - rawlimitshigh = (rawlimitshigh & 0x1FF) | limithigh; - rawlimitslow = (rawlimitslow & 0x1FF) | limitlow; - DPRINTF(sc, 2, ("%s: RH new raw limits high/low %04x %04x from %x %x\n", - device_xname(sc->sc_dev), rawlimitshigh, rawlimitslow, limithigh, limitlow)); - sht3x_set_alert_limits(sc, rawlimitshigh, rawlimitslow, true); - break; - default: - break; + if (sc->sc_isperiodic) { + sht3x_refresh_periodic(sme, edata); + } else { + sht3x_refresh_oneshot(sme, edata); } - iic_release_bus(sc->sc_tag, 0); - out: mutex_exit(&sc->sc_mutex); } -#endif static int sht3xopen(dev_t dev, int flags, int fmt, struct lwp *l) @@ -1875,10 +1433,10 @@ sht3xopen(dev_t dev, int flags, int fmt, sc = device_lookup_private(&sht3xtemp_cd, minor(dev)); if (!sc) - return (ENXIO); + return ENXIO; if (sc->sc_opened) - return (EBUSY); + return EBUSY; mutex_enter(&sc->sc_mutex); sc->sc_opened = true; @@ -1893,7 +1451,7 @@ sht3xopen(dev_t dev, int flags, int fmt, } mutex_exit(&sc->sc_mutex); - return (0); + return 0; } static int @@ -1905,7 +1463,7 @@ sht3xread(dev_t dev, struct uio *uio, in sc = device_lookup_private(&sht3xtemp_cd, minor(dev)); if (!sc) - return (ENXIO); + return ENXIO; while (uio->uio_resid) { any = 0; @@ -1918,23 +1476,29 @@ sht3xread(dev_t dev, struct uio *uio, in SIMPLEQ_REMOVE_HEAD(&sc->sc_read_queue, read_q); any = 1; break; - } else { - error = cv_wait_sig(&sc->sc_condreadready,&sc->sc_read_mutex); - if (sc->sc_dying) - error = EIO; - if (error == 0) - continue; - break; } + error = cv_wait_sig(&sc->sc_condreadready, + &sc->sc_read_mutex); + if (sc->sc_dying) + error = EIO; + if (error == 0) + continue; + break; } if (any == 1 && error == 0) { + uint8_t *p = pp->measurement; mutex_exit(&sc->sc_read_mutex); pool_cache_put(sc->sc_readpool,pp); - DPRINTF(sc,2, ("%s: sending %02x%02x %02x -- %02x%02x %02x -- %x\n",device_xname(sc->sc_dev),pp->measurement[0],pp->measurement[1],pp->measurement[2],pp->measurement[3],pp->measurement[4],pp->measurement[5],mutex_owned(&sc->sc_read_mutex))); - if ((error = uiomove(&pp->measurement[0], 6, uio)) != 0) { - DPRINTF(sc,2, ("%s: send error %d\n",device_xname(sc->sc_dev),error)); + DPRINTF(sc,2, ("%s: sending %02x%02x %02x -- %02x%02x " + "%02x -- %x\n", device_xname(sc->sc_dev), p[0], + p[1], p[2], p[3], p[4], p[5], + mutex_owned(&sc->sc_read_mutex))); + if ((error = uiomove(pp->measurement, + sizeof(pp->measurement), uio)) != 0) { + DPRINTF(sc,2, ("%s: send error %d\n", + device_xname(sc->sc_dev), error)); break; } } else { @@ -2009,7 +1573,8 @@ sht3x_detach(device_t self, int flags) mutex_exit(&sc->sc_read_mutex); DPRINTF(sc, 2, ("%s: Will wait for anything to exit\n", device_xname(sc->sc_dev))); - cv_timedwait_sig(&sc->sc_cond_dying,&sc->sc_dying_mutex,mstohz(5000)); + cv_timedwait_sig(&sc->sc_cond_dying, + &sc->sc_dying_mutex, mstohz(5000)); mutex_exit(&sc->sc_dying_mutex); cv_destroy(&sc->sc_condreadready); cv_destroy(&sc->sc_cond_dying);