Module Name: src
Committed By: christos
Date: Sat Nov 13 13:36:43 UTC 2021
Modified Files:
src/sys/dev/i2c: sht3x.c
Log Message:
Brad wants the __did_not_work code back :-)
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 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.2 src/sys/dev/i2c/sht3x.c:1.3
--- src/sys/dev/i2c/sht3x.c:1.2 Fri Nov 12 17:16:27 2021
+++ src/sys/dev/i2c/sht3x.c Sat Nov 13 08:36:42 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: sht3x.c,v 1.2 2021/11/12 22:16:27 christos Exp $ */
+/* $NetBSD: sht3x.c,v 1.3 2021/11/13 13:36:42 christos Exp $ */
/*
* Copyright (c) 2021 Brad Spencer <[email protected]>
@@ -17,7 +17,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.2 2021/11/12 22:16:27 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.3 2021/11/13 13:36:42 christos Exp $");
/*
Driver for the Sensirion SHT30/SHT31/SHT35
@@ -41,7 +41,6 @@ __KERNEL_RCSID(0, "$NetBSD: sht3x.c,v 1.
#include <dev/i2c/sht3xreg.h>
#include <dev/i2c/sht3xvar.h>
-
static int sht3x_take_break(void *, bool);
static int sht3x_get_status_register(void *, uint16_t *, bool);
static int sht3x_clear_status_register(void *, bool);
@@ -52,6 +51,18 @@ 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 *);
+#ifdef __did_not_work
+/*
+ * 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.
+ */
+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);
@@ -1166,6 +1177,9 @@ 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));
@@ -1182,6 +1196,10 @@ 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"));
@@ -1348,6 +1366,38 @@ sht3x_parse_data(struct sht3x_sc *sc, en
return 0;
}
+#ifdef __did_not_work
+/*
+ * 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.
+ */
+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 int
sht3x_refresh_periodic(struct sysmon_envsys *sme, envsys_data_t *edata)
{
@@ -1426,6 +1476,419 @@ sht3x_refresh(struct sysmon_envsys *sme,
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));
+ mutex_exit(&sc->sc_mutex);
+ return;
+ }
+
+ 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));
+
+
+ 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;
+ }
+ 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;
+ }
+ 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 = aux;
+ int error;
+ 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));
+ return;
+ }
+ }
+
+ 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));
+ }
+
+ out:
+ if (! have_bus) {
+ iic_release_bus(sc->sc_tag, 0);
+ }
+}
+
+static void
+sht3x_set_alert_limits2(void *aux, uint16_t high, uint16_t low,
+ uint16_t highminusone, uint16_t lowplusone, bool have_bus)
+{
+ struct sht3x_sc *sc;
+ sc = aux;
+
+ int error;
+ 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));
+ return;
+ }
+ }
+
+ 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]));
+
+ 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]));
+
+ 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));
+ }
+
+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)
+{
+ struct sht3x_sc *sc = sme->sme_cookie;
+ uint16_t rawlimitshigh, rawlimitslow;
+ uint16_t rawlimitshighclear, rawlimitslowclear;
+ uint16_t rawlimitshighminusone, rawlimitslowplusone;
+ 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;
+ }
+
+ 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);
+
+
+ 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);
+
+ 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;
+ }
+
+ rawlimitshighclear = (lbuf[0] << 8) | lbuf[1];
+
+ 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;
+ }
+
+ rawlimitslowclear = (lbuf[0] << 8) | lbuf[1];
+
+ 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));
+
+ 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;
+ }
+
+ 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)
{