Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/i2c Brad wants the __did_not_work code back :-)



details:   https://anonhg.NetBSD.org/src/rev/6e048b0ffc98
branches:  trunk
changeset: 1025580:6e048b0ffc98
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Nov 13 13:36:42 2021 +0000

description:
Brad wants the __did_not_work code back :-)

diffstat:

 sys/dev/i2c/sht3x.c |  469 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 466 insertions(+), 3 deletions(-)

diffs (truncated from 525 to 300 lines):

diff -r 008cc5301347 -r 6e048b0ffc98 sys/dev/i2c/sht3x.c
--- a/sys/dev/i2c/sht3x.c       Sat Nov 13 11:46:32 2021 +0000
+++ b/sys/dev/i2c/sht3x.c       Sat Nov 13 13:36:42 2021 +0000
@@ -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 <brad%anduin.eldar.org@localhost>
@@ -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 @@
 #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 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 @@
 
                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 @@
        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 @@
        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 @@
        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];



Home | Main Index | Thread Index | Old Index