Module Name:    src
Committed By:   jdc
Date:           Fri Jan  1 20:13:50 UTC 2016

Modified Files:
        src/sys/dev/i2c: lm75.c

Log Message:
Read the Tos limit from the chip, instead of assuming 80'C, in case
firmware has altered it.  Make the *decode functions return temperatures
in either uK or C for envsys and sysctl, respectively.


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/sys/dev/i2c/lm75.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/lm75.c
diff -u src/sys/dev/i2c/lm75.c:1.26 src/sys/dev/i2c/lm75.c:1.27
--- src/sys/dev/i2c/lm75.c:1.26	Sun Sep 27 13:02:21 2015
+++ src/sys/dev/i2c/lm75.c	Fri Jan  1 20:13:50 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: lm75.c,v 1.26 2015/09/27 13:02:21 phx Exp $	*/
+/*	$NetBSD: lm75.c,v 1.27 2016/01/01 20:13:50 jdc Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lm75.c,v 1.26 2015/09/27 13:02:21 phx Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lm75.c,v 1.27 2016/01/01 20:13:50 jdc Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -58,7 +58,7 @@ struct lmtemp_softc {
 	envsys_data_t sc_sensor;
 	int sc_tmax;
 
-	uint32_t (*sc_lmtemp_decode)(const uint8_t *);
+	uint32_t (*sc_lmtemp_decode)(const uint8_t *, int);
 };
 
 static int  lmtemp_match(device_t, cfdata_t, void *);
@@ -71,9 +71,11 @@ static void	lmtemp_refresh(struct sysmon
 
 static int	lmtemp_config_write(struct lmtemp_softc *, uint8_t);
 static int	lmtemp_temp_write(struct lmtemp_softc *, int, uint16_t);
-static uint32_t lmtemp_decode_lm75(const uint8_t *);
-static uint32_t lmtemp_decode_ds75(const uint8_t *);
-static uint32_t lmtemp_decode_lm77(const uint8_t *);
+static int	lmtemp_temp_read(struct lmtemp_softc *, uint8_t, uint32_t *,
+				int);
+static uint32_t lmtemp_decode_lm75(const uint8_t *, int);
+static uint32_t lmtemp_decode_ds75(const uint8_t *, int);
+static uint32_t lmtemp_decode_lm77(const uint8_t *, int);
 
 static void	lmtemp_setup_sysctl(struct lmtemp_softc *);
 static int	sysctl_lm75_temp(SYSCTLFN_ARGS);
@@ -97,7 +99,7 @@ static const struct {
 	const char *lmtemp_name;
 	int lmtemp_addrmask;
 	int lmtemp_addr;
-	uint32_t (*lmtemp_decode)(const uint8_t *);
+	uint32_t (*lmtemp_decode)(const uint8_t *, int);
 } lmtemptbl[] = {
 	{ lmtemp_lm75,	"LM75",
 	    LM75_ADDRMASK,	LM75_ADDR,	lmtemp_decode_lm75 },
@@ -177,16 +179,21 @@ lmtemp_attach(device_t parent, device_t 
 			lmtemptbl[i].lmtemp_name);
 	}
 
-	/*
-	 * according to the LM75 data sheet 80C is the default, so leave it
-	 * there to avoid unexpected behaviour
-	 */
-	sc->sc_tmax = 80;
+	sc->sc_lmtemp_decode = lmtemptbl[i].lmtemp_decode;
+
+	iic_acquire_bus(sc->sc_tag, I2C_F_POLL);
+
+	/* Read temperature limit and remember initial value. */
+	if (lmtemp_temp_read(sc, LM75_REG_TOS_SET_POINT, &sc->sc_tmax, 1)
+	    != 0) {
+		iic_release_bus(sc->sc_tag, I2C_F_POLL);
+		return;
+	}
+
 	if (i == lmtemp_lm75)
 		lmtemp_setup_sysctl(sc);
 
 	/* Set the configuration of the LM75 to defaults. */
-	iic_acquire_bus(sc->sc_tag, I2C_F_POLL);
 	if (lmtemp_config_write(sc, LM75_CONFIG_FAULT_QUEUE_4) != 0) {
 		aprint_error_dev(self, "unable to write config register\n");
 		iic_release_bus(sc->sc_tag, I2C_F_POLL);
@@ -206,8 +213,6 @@ lmtemp_attach(device_t parent, device_t 
 		return;
 	}
 
-	sc->sc_lmtemp_decode = lmtemptbl[i].lmtemp_decode;
-
 	/* Hook into system monitor. */
 	sc->sc_sme->sme_name = device_xname(self);
 	sc->sc_sme->sme_cookie = sc;
@@ -245,7 +250,8 @@ lmtemp_temp_write(struct lmtemp_softc *s
 }
 
 static int
-lmtemp_temp_read(struct lmtemp_softc *sc, uint8_t which, uint32_t *valp)
+lmtemp_temp_read(struct lmtemp_softc *sc, uint8_t which, uint32_t *valp,
+    int degc)
 {
 	int error;
 	uint8_t cmdbuf[1];
@@ -258,7 +264,7 @@ lmtemp_temp_read(struct lmtemp_softc *sc
 	if (error)
 		return error;
 
-	*valp = sc->sc_lmtemp_decode(buf);
+	*valp = sc->sc_lmtemp_decode(buf, degc);
 	return 0;
 }
 
@@ -268,7 +274,7 @@ lmtemp_refresh_sensor_data(struct lmtemp
 	uint32_t val;
 	int error;
 
-	error = lmtemp_temp_read(sc, LM75_REG_TEMP, &val);
+	error = lmtemp_temp_read(sc, LM75_REG_TEMP, &val, 0);
 	if (error) {
 #if 0
 		aprint_error_dev(sc->sc_dev, "unable to read temperature, error = %d\n",
@@ -293,7 +299,7 @@ lmtemp_refresh(struct sysmon_envsys *sme
 }
 
 static uint32_t
-lmtemp_decode_lm75(const uint8_t *buf)
+lmtemp_decode_lm75(const uint8_t *buf, int degc)
 {
 	int temp;
 	uint32_t val;
@@ -305,14 +311,17 @@ lmtemp_decode_lm75(const uint8_t *buf)
 	temp = (int8_t) buf[0];
 	temp = (temp << 1) + ((buf[1] >> 7) & 0x1);
 
-	/* Temp is given in 1/2 deg. C, we convert to uK. */
-	val = temp * 500000 + 273150000;
+	/* Temp is given in 1/2 deg. C, we convert to C or uK. */
+	if (degc)
+		val = temp / 2;
+	else
+		val = temp * 500000 + 273150000;
 
 	return val;
 }
 
 static uint32_t
-lmtemp_decode_ds75(const uint8_t *buf)
+lmtemp_decode_ds75(const uint8_t *buf, int degc)
 {
 	int temp;
 
@@ -324,13 +333,16 @@ lmtemp_decode_ds75(const uint8_t *buf)
 	temp = (temp << 4) | ((buf[1] >> 4) & 0xf);
 
 	/*
-	 * Conversion to uK is simple.
+	 * Conversion to C or uK is simple.
 	 */
-	return (temp * 62500 + 273150000);
+	if (degc)
+		return temp / 16;
+	else
+		return (temp * 62500 + 273150000);
 }
 
 static uint32_t
-lmtemp_decode_lm77(const uint8_t *buf)
+lmtemp_decode_lm77(const uint8_t *buf, int degc)
 {
 	int temp;
 	uint32_t val;
@@ -343,8 +355,11 @@ lmtemp_decode_lm77(const uint8_t *buf)
 	temp = (int8_t)buf[0];
 	temp = (temp << 5) | ((buf[1] >> 3) & 0x1f);
 
-	/* Temp is given in 1/2 deg. C, we convert to uK. */
-	val = temp * 500000 + 273150000;
+	/* Temp is given in 1/2 deg. C, we convert to C or uK. */
+	if (degc)
+		val = temp / 2;
+	else
+		val = temp * 500000 + 273150000;
 
 	return val;
 }
@@ -354,11 +369,6 @@ lmtemp_setup_sysctl(struct lmtemp_softc 
 {
 	const struct sysctlnode *me = NULL, *node = NULL;
 
-	iic_acquire_bus(sc->sc_tag, I2C_F_POLL);
-	lmtemp_temp_write(sc, LM75_REG_THYST_SET_POINT, (sc->sc_tmax - 5) * 2);
-	lmtemp_temp_write(sc, LM75_REG_TOS_SET_POINT, sc->sc_tmax * 2);
-	iic_release_bus(sc->sc_tag, I2C_F_POLL);
-
 	sysctl_createv(NULL, 0, NULL, &me,
 	    CTLFLAG_READWRITE,
 	    CTLTYPE_NODE, device_xname(sc->sc_dev), NULL,

Reply via email to