Module Name: src
Committed By: msaitoh
Date: Tue Jul 26 07:30:16 UTC 2016
Modified Files:
src/sys/dev/i2c: sdtemp.c sdtemp_reg.h
Log Message:
Reviewed and OK'd by pgoyette:
- Add supoprt 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 and timeout with aprint_normal().
- Show timeout with aprint_debug().
To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/i2c/sdtemp.c
cvs rdiff -u -r1.8 -r1.9 src/sys/dev/i2c/sdtemp_reg.h
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/sdtemp.c
diff -u src/sys/dev/i2c/sdtemp.c:1.27 src/sys/dev/i2c/sdtemp.c:1.28
--- src/sys/dev/i2c/sdtemp.c:1.27 Tue Jul 26 07:25:51 2016
+++ src/sys/dev/i2c/sdtemp.c Tue Jul 26 07:30:16 2016
@@ -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 @@ struct sdtemp_softc {
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 int sdtemp_write_16(struct sdtemp
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 @@ struct sdtemp_dev_entry {
#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,
- "Microchip Tech MCP98243" },
- { MCP_MANUFACTURER_ID, MCP_98242_DEVICE_ID, MCP_98242_MASK, -4,
+ { MCP_MANUFACTURER_ID, MCP_98242_DEVICE_ID, MCP_98242_MASK, CMCP,
"Microchip Tech MCP98242" },
- { ADT_MANUFACTURER_ID, ADT_7408_DEVICE_ID, ADT_7408_MASK, 4,
+ { MCP_MANUFACTURER_ID, MCP_98243_DEVICE_ID, MCP_98243_MASK, CMCP,
+ "Microchip Tech MCP98243" },
+ { 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 @@ sdtemp_attach(device_t parent, device_t
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 @@ sdtemp_attach(device_t parent, device_t
"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 @@ sdtemp_attach(device_t parent, device_t
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 @@ sdtemp_decode_temp(struct sdtemp_softc *
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 @@ sdtemp_modcmd(modcmd_t cmd, void *opaque
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);
+}
Index: src/sys/dev/i2c/sdtemp_reg.h
diff -u src/sys/dev/i2c/sdtemp_reg.h:1.8 src/sys/dev/i2c/sdtemp_reg.h:1.9
--- src/sys/dev/i2c/sdtemp_reg.h:1.8 Wed May 20 00:43:28 2015
+++ src/sys/dev/i2c/sdtemp_reg.h Tue Jul 26 07:30:16 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: sdtemp_reg.h,v 1.8 2015/05/20 00:43:28 msaitoh Exp $ */
+/* $NetBSD: sdtemp_reg.h,v 1.9 2016/07/26 07:30:16 msaitoh Exp $ */
/*
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -47,13 +47,16 @@
#define SDTEMP_REG_AMBIENT_TEMP 0x05
#define SDTEMP_REG_MFG_ID 0x06
#define SDTEMP_REG_DEV_REV 0x07
-#define SDTEMP_REG_RESOLUTION 0x08
#define SDTEMP_CAP_HAS_ALARM 0x0001
#define SDTEMP_CAP_ACCURACY_1C 0x0002
#define SDTEMP_CAP_WIDER_RANGE 0x0004
#define SDTEMP_CAP_RESOLUTION 0x0018
-#define SDTEMP_CAP_RES_SHIFT 3
+#define SDTEMP_CAP_RESOLUTION_MAX 0x0003 /* 0.0625C */
+#define SDTEMP_CAP_VHV 0x0020
+#define SDTEMP_CAP_TMOUT 0x0040
+#define SDTEMP_CAP_EVSD 0x0080
+
#define SDTEMP_CONFIG_EVENT_MODE 0x0001
#define SDTEMP_CONFIG_EVENT_POL_AH 0x0002
@@ -91,34 +94,77 @@
/*
* Devices known to conform to JEDEC JC42.4
*/
+
+/* Atmel */
+#define AT_MANUFACTURER_ID 0x001f
+#define AT_30TS00_DEVICE_ID 0x8201 /* Also matches 002A and 002B */
+#define AT_30TS00_MASK 0xFFFF
+
+#define AT2_MANUFACTURER_ID 0x1114
+#define AT2_30TSE004_DEVICE_ID 0x2200
+#define AT2_30TSE004_MASK 0xFFFF
+
+/* Giantec Semiconductor */
+#define GT_MANUFACTURER_ID 0x1C68
+#define GT_30TS00_DEVICE_ID 0x2201
+#define GT_30TS00_MASK 0xFFFF
+
+#define GT2_MANUFACTURER_ID 0x132D
+#define GT2_34TS02_DEVICE_ID 0x3300
+#define GT2_34TS02_MASK 0xFFFF
+
+/* Maxim */
#define MAXIM_MANUFACTURER_ID 0x004D
#define MAX_6604_DEVICE_ID 0x3E00
#define MAX_6604_MASK 0xFFFF
+/* Microchip */
#define MCP_MANUFACTURER_ID 0x0054
+#define MCP_9804_DEVICE_ID 0x0200
+#define MCP_9804_MASK 0xFFFC
#define MCP_9805_DEVICE_ID 0x0000 /* Also matches MCP9843 */
#define MCP_9805_MASK 0xFFFE
#define MCP_98242_DEVICE_ID 0x2000
#define MCP_98242_MASK 0xFFFC
#define MCP_98243_DEVICE_ID 0x2100
#define MCP_98243_MASK 0xFFFC
+#define MCP_98244_DEVICE_ID 0x2200
+#define MCP_98244_MASK 0xFFFC
-/* According to datasheets, SE97 and SE98 have same ID */
+#define SDTEMP_REG_MCP_RESOLUTION_9804 0x08 /* 9804, 9824[23] */
+#define SDTEMP_REG_MCP_RESOLUTION_98244 0x09 /* 98244 */
+/* NXP Semiconductors */
+/* According to datasheets, SE97 and SE98 have same ID */
#define NXP_MANUFACTURER_ID 0x1131
#define NXP_SE98_DEVICE_ID 0xA100
#define NXP_SE98_MASK 0xFFFC
#define NXP_SE97_DEVICE_ID 0xA200
#define NXP_SE97_MASK 0xFFFC
+/* Analog Devices */
#define ADT_MANUFACTURER_ID 0x11D4
#define ADT_7408_DEVICE_ID 0x8001
#define ADT_7408_MASK 0xFFFF
+/* IDT */
#define IDT_MANUFACTURER_ID 0x00B3
#define IDT_TS3000B3_DEVICE_ID 0x2903 /* Also matches TSE2002B3 */
#define IDT_TS3000B3_MASK 0xFFFF
+#define IDT_TS3000GB0_DEVICE_ID 0x2913
+#define IDT_TS3000GB0_MASK 0xFFFF
+#define IDT_TS3000GB2_DEVICE_ID 0x2912
+#define IDT_TS3000GB2_MASK 0xFFFF
+#define IDT_TS3001GB2_DEVICE_ID 0x3001
+#define IDT_TS3001GB2_MASK 0xFFFF
+#define IDT_TSE2002GB2_DEVICE_ID 0x2912
+#define IDT_TSE2002GB2_MASK 0xFFFF
+#define IDT_TSE2004GB2_DEVICE_ID 0x2214
+#define IDT_TSE2004GB2_MASK 0xFFFF
+
+#define SDTEMP_REG_IDT_RESOLUTION 0x08 /* 2002 */
+/* STmicroelectronics */
#define STTS_MANUFACTURER_ID 0x104A
#define STTS_424_DEVICE_ID 0x0101
#define STTS_424_MASK 0xFFFF
@@ -131,12 +177,14 @@
#define STTS_2004_DEVICE_ID 0x2201
#define STTS_2004_MASK 0xFFFF
+/* On Semiconductor (Catalyst) */
/* According to datasheets, both the CAT6095 and CAT34TS02 have the same ID */
-
#define CAT_MANUFACTURER_ID 0x1B09
#define CAT_34TS02_DEVICE_ID 0x0800
#define CAT_34TS02_MASK 0xFFE0
#define CAT_34TS02C_DEVICE_ID 0x0a00
#define CAT_34TS02C_MASK 0xFFFF
+#define CAT_34TS04_DEVICE_ID 0x2200
+#define CAT_34TS04_MASK 0xFFFF
#endif /* _DEV_I2C_SDTEMPREG_H */