Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/i2c Reviewed and OK'd by pgoyette:



details:   https://anonhg.NetBSD.org/src/rev/59a3fd5c46b5
branches:  trunk
changeset: 816804:59a3fd5c46b5
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Tue Jul 26 07:30:16 2016 +0000

description:
Reviewed and OK'd by pgoyette:
- Add support for Atmel AT30TS00, AT30TSE004, Giantec GT30TS00, GT34TS02,
  Microchip MCP9804, MCP98244, IDT TS3000GB[02], TS3001GB2, TSE2004GB2,
  and On Semiconductor CAT34TS04. Taken from OpenBSD.
- Add IDT TSE2002GB2.
- Check the temperature resolution field in the capability register instead
  of the hard coded value in the match table. With this change, some devices'
  temperature resolution would be fixed.
- The resolution register is a vendor specific register.
- All of IDT devices have the resolution register.
- The address of the resolution register of Microchip MCP98244 is different
  from other Microchip devices.
- Show accuracy, range, resolution, high voltage standoff and shutdown with
  aprint_normal().
- Show timeout with aprint_debug().

diffstat:

 sys/dev/i2c/sdtemp.c     |  214 +++++++++++++++++++++++++++++++++++-----------
 sys/dev/i2c/sdtemp_reg.h |   58 +++++++++++-
 2 files changed, 215 insertions(+), 57 deletions(-)

diffs (truncated from 423 to 300 lines):

diff -r 94868740d8af -r 59a3fd5c46b5 sys/dev/i2c/sdtemp.c
--- a/sys/dev/i2c/sdtemp.c      Tue Jul 26 07:25:51 2016 +0000
+++ b/sys/dev/i2c/sdtemp.c      Tue Jul 26 07:30:16 2016 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: sdtemp.c,v 1.27 2016/07/26 07:25:51 msaitoh Exp $        */
+/*      $NetBSD: sdtemp.c,v 1.28 2016/07/26 07:30:16 msaitoh Exp $        */
 
 /*
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdtemp.c,v 1.27 2016/07/26 07:25:51 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdtemp.c,v 1.28 2016/07/26 07:30:16 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -55,6 +55,9 @@
        sysmon_envsys_lim_t sc_deflims;
        uint32_t sc_defprops;
        int sc_resolution;
+       uint16_t sc_mfgid;
+       uint16_t sc_devid;
+       uint16_t sc_devid_masked;
        uint16_t sc_capability;
 };
 
@@ -79,12 +82,15 @@
 static uint32_t        sdtemp_decode_temp(struct sdtemp_softc *, uint16_t);
 static bool    sdtemp_pmf_suspend(device_t, const pmf_qual_t *);
 static bool    sdtemp_pmf_resume(device_t, const pmf_qual_t *);
+/* Device dependent config functions */
+static void    sdtemp_config_mcp(struct sdtemp_softc *);
+static void    sdtemp_config_idt(struct sdtemp_softc *);
 
 struct sdtemp_dev_entry {
        const uint16_t sdtemp_mfg_id;
-       const uint16_t  sdtemp_devrev;
-       const uint16_t  sdtemp_mask;
-       const uint8_t  sdtemp_resolution;
+       const uint16_t sdtemp_devrev;
+       const uint16_t sdtemp_mask;
+       void         (*sdtemp_config)(struct sdtemp_softc *);
        const char    *sdtemp_desc;
 };
 
@@ -92,47 +98,78 @@
 
 #define        __UK2C(uk) (((uk) - 273150000) / 1000000)
 
-/*
- * List of devices known to conform to JEDEC JC42.4
- *
- * NOTE: A non-negative value for resolution indicates that the sensor
- * resolution is fixed at that number of fractional bits;  a negative
- * value indicates that the sensor needs to be configured.  In either
- * case, trip-point registers are fixed at two-bit (0.25C) resolution.
- */
+/* List of devices known to conform to JEDEC JC42.4 */
+
+#define        CMCP sdtemp_config_mcp
+#define        CIDT sdtemp_config_idt
+
 static const struct sdtemp_dev_entry
 sdtemp_dev_table[] = {
-    { MAXIM_MANUFACTURER_ID, MAX_6604_DEVICE_ID,    MAX_6604_MASK,   3,
+    { AT_MANUFACTURER_ID,   AT_30TS00_DEVICE_ID,     AT_30TS00_MASK,     NULL,
+       "Atmel AT30TS00" },
+    { AT2_MANUFACTURER_ID,  AT2_30TSE004_DEVICE_ID,  AT2_30TSE004_MASK,          NULL,
+       "Atmel AT30TSE004" },
+    { GT_MANUFACTURER_ID,   GT_30TS00_DEVICE_ID,     GT_30TS00_MASK,     NULL,
+       "Giantec GT30TS00" },
+    { GT2_MANUFACTURER_ID,  GT2_34TS02_DEVICE_ID,    GT2_34TS02_MASK,    NULL,
+       "Giantec GT34TS02" },
+    { MAXIM_MANUFACTURER_ID, MAX_6604_DEVICE_ID,     MAX_6604_MASK,      NULL,
        "Maxim MAX6604" },
-    { MCP_MANUFACTURER_ID,   MCP_9805_DEVICE_ID,    MCP_9805_MASK,   2,
+    { MCP_MANUFACTURER_ID,  MCP_9804_DEVICE_ID,             MCP_9804_MASK,       CMCP,
+       "Microchip Tech MCP9804" },
+    { MCP_MANUFACTURER_ID,  MCP_9805_DEVICE_ID,             MCP_9805_MASK,       NULL,
        "Microchip Tech MCP9805/MCP9843" },
-    { MCP_MANUFACTURER_ID,   MCP_98243_DEVICE_ID,   MCP_98243_MASK, -4,
+    { MCP_MANUFACTURER_ID,  MCP_98242_DEVICE_ID,     MCP_98242_MASK,     CMCP,
+       "Microchip Tech MCP98242" },
+    { MCP_MANUFACTURER_ID,  MCP_98243_DEVICE_ID,     MCP_98243_MASK,     CMCP,
        "Microchip Tech MCP98243" },
-    { MCP_MANUFACTURER_ID,   MCP_98242_DEVICE_ID,   MCP_98242_MASK, -4,
-       "Microchip Tech MCP98242" },
-    { ADT_MANUFACTURER_ID,   ADT_7408_DEVICE_ID,    ADT_7408_MASK,   4,
+    { MCP_MANUFACTURER_ID,  MCP_98244_DEVICE_ID,     MCP_98244_MASK,     CMCP,
+       "Microchip Tech MCP98244" },
+    { ADT_MANUFACTURER_ID,  ADT_7408_DEVICE_ID,             ADT_7408_MASK,       NULL,
        "Analog Devices ADT7408" },
-    { NXP_MANUFACTURER_ID,   NXP_SE98_DEVICE_ID,    NXP_SE98_MASK,   3,
+    { NXP_MANUFACTURER_ID,  NXP_SE98_DEVICE_ID,             NXP_SE98_MASK,       NULL,
        "NXP Semiconductors SE97B/SE98" },
-    { NXP_MANUFACTURER_ID,   NXP_SE97_DEVICE_ID,    NXP_SE97_MASK,   3,
+    { NXP_MANUFACTURER_ID,  NXP_SE97_DEVICE_ID,             NXP_SE97_MASK,       NULL,
        "NXP Semiconductors SE97" },
-    { STTS_MANUFACTURER_ID,  STTS_424E_DEVICE_ID,   STTS_424E_MASK,  2,
-       "STmicroelectronics STTS424E" }, 
-    { STTS_MANUFACTURER_ID,  STTS_424_DEVICE_ID,    STTS_424_MASK,   2,
-       "STmicroelectronics STTS424" }, 
-    { STTS_MANUFACTURER_ID,  STTS_2002_DEVICE_ID,    STTS_2002_MASK,   2,
-       "STmicroelectronics STTS2002" }, 
-    { STTS_MANUFACTURER_ID,  STTS_2004_DEVICE_ID,    STTS_2004_MASK,   2,
-       "STmicroelectronics STTS2004" }, 
-    { STTS_MANUFACTURER_ID,  STTS_3000_DEVICE_ID,    STTS_3000_MASK,   2,
-       "STmicroelectronics STTS3000" }, 
-    { CAT_MANUFACTURER_ID,   CAT_34TS02_DEVICE_ID,  CAT_34TS02_MASK, 4,
+    { STTS_MANUFACTURER_ID, STTS_424E_DEVICE_ID,     STTS_424E_MASK,     NULL,
+       "STmicroelectronics STTS424E" },
+    { STTS_MANUFACTURER_ID, STTS_424_DEVICE_ID,             STTS_424_MASK,       NULL,
+       "STmicroelectronics STTS424" },
+    { STTS_MANUFACTURER_ID, STTS_2002_DEVICE_ID,     STTS_2002_MASK,     NULL,
+       "STmicroelectronics STTS2002" },
+    { STTS_MANUFACTURER_ID, STTS_2004_DEVICE_ID,     STTS_2004_MASK,     NULL,
+       "STmicroelectronics STTS2004" },
+    { STTS_MANUFACTURER_ID, STTS_3000_DEVICE_ID,     STTS_3000_MASK,     NULL,
+       "STmicroelectronics STTS3000" },
+    { CAT_MANUFACTURER_ID,  CAT_34TS02_DEVICE_ID,    CAT_34TS02_MASK,    NULL,
        "Catalyst CAT34TS02/CAT6095" },
-    { CAT_MANUFACTURER_ID,   CAT_34TS02C_DEVICE_ID,  CAT_34TS02C_MASK, 4,
+    { CAT_MANUFACTURER_ID,  CAT_34TS02C_DEVICE_ID,   CAT_34TS02C_MASK,   NULL,
        "Catalyst CAT34TS02C" },
-    { IDT_MANUFACTURER_ID,   IDT_TS3000B3_DEVICE_ID, IDT_TS3000B3_MASK, 4,
+    { CAT_MANUFACTURER_ID,  CAT_34TS04_DEVICE_ID,    CAT_34TS04_MASK,    NULL,
+       "Catalyst CAT34TS04" },
+    { IDT_MANUFACTURER_ID,  IDT_TSE2002GB2_DEVICE_ID,IDT_TSE2002GB2_MASK, CIDT,
+       "Integrated Device Technology TSE2002GB2" },
+    { IDT_MANUFACTURER_ID,  IDT_TSE2004GB2_DEVICE_ID,IDT_TSE2004GB2_MASK, NULL,
+       "Integrated Device Technology TSE2004GB2" },
+    { IDT_MANUFACTURER_ID,  IDT_TS3000B3_DEVICE_ID,  IDT_TS3000B3_MASK,          CIDT,
        "Integrated Device Technology TS3000B3/TSE2002B3" },
-    { 0, 0, 0, 2, "Unknown" }
+    { IDT_MANUFACTURER_ID,  IDT_TS3000GB0_DEVICE_ID, IDT_TS3000GB0_MASK,  CIDT,
+       "Integrated Device Technology TS3000GB0" },
+    { IDT_MANUFACTURER_ID,  IDT_TS3000GB2_DEVICE_ID, IDT_TS3000GB2_MASK,  CIDT,
+       "Integrated Device Technology TS3000GB2" },
+    { IDT_MANUFACTURER_ID,  IDT_TS3001GB2_DEVICE_ID, IDT_TS3001GB2_MASK,  CIDT,
+       "Integrated Device Technology TS3001GB2" },
+    { 0, 0, 0, NULL, "Unknown" }
+};
+
+#undef CMCP
+#undef CIDT
+
+static const char *temp_resl[] = {
+       "0.5C",
+       "0.25C",
+       "0.125C",
+       "0.0625C"
 };
 
 static int
@@ -204,9 +241,10 @@
                aprint_error(": attach error %d\n", error);
                return;
        }
+       sc->sc_mfgid = mfgid;
+       sc->sc_devid = devid;
        i = sdtemp_lookup(mfgid, devid);
-       sc->sc_resolution =
-           sdtemp_dev_table[i].sdtemp_resolution;
+       sc->sc_devid_masked = devid & sdtemp_dev_table[i].sdtemp_mask;
 
        aprint_naive(": Temp Sensor\n");
        aprint_normal(": %s Temp Sensor\n", sdtemp_dev_table[i].sdtemp_desc);
@@ -216,11 +254,38 @@
                    "mfg 0x%04x dev 0x%04x rev 0x%02x at addr 0x%02x\n",
                    mfgid, devid, devid & 0xff, ia->ia_addr);
 
+       error = sdtemp_read_16(sc, SDTEMP_REG_CAPABILITY, &sc->sc_capability);
+       aprint_debug_dev(self, "capability reg = %04x\n", sc->sc_capability);
+       sc->sc_resolution
+           = __SHIFTOUT(sc->sc_capability, SDTEMP_CAP_RESOLUTION);
+       /*
+        * Call device dependent function here. Currently, it's used for
+        * the resolution.
+        *
+        * IDT's devices and some Microchip's devices have the resolution
+        * register in the vendor specific registers area. The devices'
+        * resolution bits in the capability register are not the maximum
+        * resolution but the current vaule of the setting.
+        */
+       if (sdtemp_dev_table[i].sdtemp_config != NULL)
+               sdtemp_dev_table[i].sdtemp_config(sc);
+
+       aprint_normal_dev(self, "%s accuracy",
+           (sc->sc_capability & SDTEMP_CAP_ACCURACY_1C) ? "high" : "default");
+       if ((sc->sc_capability & SDTEMP_CAP_WIDER_RANGE) != 0)
+               aprint_normal(", wider range");
+       aprint_normal(", %s resolution", temp_resl[sc->sc_resolution]);
+       if ((sc->sc_capability & SDTEMP_CAP_VHV) != 0)
+               aprint_debug(", high voltage standoff");
+       aprint_debug(", %s timeout",
+           (sc->sc_capability & SDTEMP_CAP_TMOUT) ? "25-35ms" : "10-60ms");
+       if ((sc->sc_capability & SDTEMP_CAP_EVSD) != 0)
+               aprint_normal(", event with shutdown");
+       aprint_normal("\n");
        /*
         * Alarm capability is required;  if not present, this is likely
         * not a real sdtemp device.
         */
-       error = sdtemp_read_16(sc, SDTEMP_REG_CAPABILITY, &sc->sc_capability);
        if (error != 0 || (sc->sc_capability & SDTEMP_CAP_HAS_ALARM) == 0) {
                iic_release_bus(sc->sc_tag, 0);
                aprint_error_dev(self,
@@ -235,19 +300,6 @@
                    error);
                return;
        }
-       /* If variable resolution, set to max */
-       if (sc->sc_resolution < 0) {
-               sc->sc_resolution = ~sc->sc_resolution;
-               error = sdtemp_write_16(sc, SDTEMP_REG_RESOLUTION,
-                                       sc->sc_resolution & 0x3);
-               if (error != 0) {
-                       iic_release_bus(sc->sc_tag, 0);
-                       aprint_error_dev(self,
-                           "error %d writing resolution register\n", error);
-                       return;
-               } else
-                       sc->sc_resolution++;
-       }
        iic_release_bus(sc->sc_tag, 0);
 
        /* Hook us into the sysmon_envsys subsystem */
@@ -468,7 +520,7 @@
                temp |= SDTEMP_TEMP_SIGN_EXT;
 
        /* Mask off only bits valid within current resolution */
-       temp &= ~(0xf >> sc->sc_resolution);
+       temp &= ~(0x7 >> sc->sc_resolution);
 
        /* Treat as signed and extend to 32-bits */
        stemp = (int16_t)temp;
@@ -583,3 +635,61 @@
                return ENOTTY;
        }
 }
+
+/* Device dependent config functions */
+
+static void
+sdtemp_config_mcp(struct sdtemp_softc *sc)
+{
+       int rv;
+       uint8_t resolreg;
+
+       /* Note that MCP9805 has no resolution register */
+       switch (sc->sc_devid_masked) {
+       case MCP_9804_DEVICE_ID:
+       case MCP_98242_DEVICE_ID:
+       case MCP_98243_DEVICE_ID:
+               resolreg = SDTEMP_REG_MCP_RESOLUTION_9804;
+               break;
+       case MCP_98244_DEVICE_ID:
+               resolreg = SDTEMP_REG_MCP_RESOLUTION_98244;
+               break;
+       default:
+               aprint_error("%s: %s: unknown device ID (%04hx)\n",
+                   device_xname(sc->sc_dev), __func__, sc->sc_devid_masked);
+               return;
+       }
+
+       /*
+        * Set resolution to the max.
+        *
+        * Even if it fails, the resolution will be the default. It's not a
+        * fatal error.
+        */
+       rv = sdtemp_write_16(sc, resolreg, SDTEMP_CAP_RESOLUTION_MAX);
+       if (rv == 0)
+               sc->sc_resolution = SDTEMP_CAP_RESOLUTION_MAX;
+       else
+               aprint_error("%s: error %d writing resolution register\n",
+                   device_xname(sc->sc_dev), rv);
+}
+
+static void
+sdtemp_config_idt(struct sdtemp_softc *sc)
+{
+       int rv;
+
+       /*
+        * Set resolution to the max.
+        *
+        * Even if it fails, the resolution will be the default. It's not a
+        * fatal error.
+        */
+       rv = sdtemp_write_16(sc, SDTEMP_REG_IDT_RESOLUTION,
+           __SHIFTIN(SDTEMP_CAP_RESOLUTION_MAX, SDTEMP_CAP_RESOLUTION));
+       if (rv == 0)
+               sc->sc_resolution = SDTEMP_CAP_RESOLUTION_MAX;
+       else
+               aprint_error("%s: error %d writing resolution register\n",
+                   device_xname(sc->sc_dev), rv);
+}



Home | Main Index | Thread Index | Old Index