Subject: LM77 temperature
To: None <tech-kern@netbsd.org>
From: KIYOHARA Takashi <kiyohara@kk.iij4u.or.jp>
List: tech-kern
Date: 04/30/2006 02:01:43
----Next_Part(Sun_Apr_30_02:01:44_2006_187)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Hi! all,
LM77 can be supported with this patch. ;-)
The address is the same though LM77 uses a mask different from LM75.
Some registers are added.
Besides, is there an idea?
Thanks,
--
kiyohara
----Next_Part(Sun_Apr_30_02:01:44_2006_187)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="lmtemp.diff"
Index: lm75.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/lm75.c,v
retrieving revision 1.7
diff -u -r1.7 lm75.c
--- lm75.c 4 Apr 2006 19:38:38 -0000 1.7
+++ lm75.c 29 Apr 2006 16:56:42 -0000
@@ -49,12 +49,13 @@
struct device sc_dev;
i2c_tag_t sc_tag;
int sc_address;
- int sc_is_ds75;
struct envsys_tre_data sc_sensor[1];
struct envsys_basic_info sc_info[1];
struct sysmon_envsys sc_sysmon;
+
+ uint32_t (*sc_lmtemp_decode)(const uint8_t *);
};
static int lmtemp_match(struct device *, struct cfdata *, void *);
@@ -76,13 +77,45 @@
static int lmtemp_config_write(struct lmtemp_softc *, uint8_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 *);
+
+enum {
+ lmtemp_lm75 = 0,
+ lmtemp_ds75,
+ lmtemp_lm77,
+};
+static const struct {
+ int lmtemp_type;
+ const char *lmtemp_name;
+ int lmtemp_addrmask;
+ int lmtemp_addr;
+ uint32_t (*lmtemp_decode)(const uint8_t *);
+} lmtemptbl[] = {
+ { lmtemp_lm75, "LM75",
+ LM75_ADDRMASK, LM75_ADDR, lmtemp_decode_lm75 },
+ { lmtemp_ds75, "DS75",
+ LM75_ADDRMASK, LM75_ADDR, lmtemp_decode_ds75 },
+ { lmtemp_lm77, "LM77",
+ LM77_ADDRMASK, LM77_ADDR, lmtemp_decode_lm77 },
+
+ { -1, NULL,
+ 0, 0, NULL }
+};
static int
lmtemp_match(struct device *parent, struct cfdata *cf, void *aux)
{
struct i2c_attach_args *ia = aux;
+ int i;
+
+ for (i = 0; lmtemptbl[i].lmtemp_type != -1 ; i++)
+ if (lmtemptbl[i].lmtemp_type == cf->cf_flags)
+ break;
+ if (lmtemptbl[i].lmtemp_type == -1)
+ return (0);
- if ((ia->ia_addr & LM75_ADDRMASK) == LM75_ADDR)
+ if ((ia->ia_addr & lmtemptbl[i].lmtemp_addrmask) ==
+ lmtemptbl[i].lmtemp_addr)
return (1);
return (0);
@@ -93,15 +126,18 @@
{
struct lmtemp_softc *sc = device_private(self);
struct i2c_attach_args *ia = aux;
- int ptype;
+ int ptype, i;
+
+ for (i = 0; lmtemptbl[i].lmtemp_type != -1 ; i++)
+ if (lmtemptbl[i].lmtemp_type ==
+ device_cfdata(&sc->sc_dev)->cf_flags)
+ break;
sc->sc_tag = ia->ia_tag;
sc->sc_address = ia->ia_addr;
- sc->sc_is_ds75 = device_cfdata(&sc->sc_dev)->cf_flags & 1;
aprint_naive(": Temperature Sensor\n");
- aprint_normal(": %s Temperature Sensor\n",
- (sc->sc_is_ds75) ? "DS75" : "LM75");
+ aprint_normal(": %s Temperature Sensor\n", lmtemptbl[i].lmtemp_name);
/* Set the configuration of the LM75 to defaults. */
iic_acquire_bus(sc->sc_tag, I2C_F_POLL);
@@ -126,6 +162,8 @@
ptype != PROP_STRING)
strcpy(sc->sc_info[0].desc, sc->sc_dev.dv_xname);
+ sc->sc_lmtemp_decode = lmtemptbl[i].lmtemp_decode;
+
/* Hook into system monitor. */
sc->sc_sysmon.sme_ranges = lmtemp_ranges;
sc->sc_sysmon.sme_sensor_info = sc->sc_info;
@@ -169,11 +207,7 @@
if (error)
return (error);
- if (sc->sc_is_ds75)
- *valp = lmtemp_decode_ds75(buf);
- else
- *valp = lmtemp_decode_lm75(buf);
-
+ *valp = sc->sc_lmtemp_decode(buf);
return (0);
}
@@ -276,3 +310,23 @@
return (temp * 62500 + 273150000);
}
+static uint32_t
+lmtemp_decode_lm77(const uint8_t *buf)
+{
+ int temp;
+ uint32_t val;
+
+ /*
+ * Describe each bits of temperature registers on LM77.
+ * D15 - D12: Sign
+ * D11 - D3 : Bit8(MSB) - Bit0
+ */
+ temp = (int8_t)buf[0];
+ temp = (temp << 5) | (buf[1] >> 3);
+
+ /* Temp is given in 1/2 deg. C, we convert to uK. */
+ val = temp * 500000 + 273150000;
+
+ return (val);
+}
+
Index: lm75reg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/lm75reg.h,v
retrieving revision 1.2
diff -u -r1.2 lm75reg.h
--- lm75reg.h 11 Dec 2005 12:21:22 -0000 1.2
+++ lm75reg.h 29 Apr 2006 16:56:42 -0000
@@ -45,6 +45,8 @@
*/
#define LM75_ADDRMASK 0x78
#define LM75_ADDR 0x48
+#define LM77_ADDRMASK 0x7c
+#define LM77_ADDR 0x48
/*
* Temperature on the LM75 is represented by a 9-bit two's complement
@@ -65,6 +67,11 @@
#define LM75_REG_THYST_SET_POINT 0x02
#define LM75_REG_TOS_SET_POINT 0x03
+#define LM77_REG_TCRIT_SET_POINT 0x03
+#define LM77_REG_TLOW_SET_POINT 0x04
+#define LM77_REG_THIGH_SET_POINT 0x05
+
+
#define LM75_TEMP_LEN 2 /* 2 data bytes */
#define LM75_CONFIG_SHUTDOWN 0x01
@@ -75,4 +82,8 @@
#define LM75_CONFIG_FAULT_QUEUE_4 (2 << 3)
#define LM75_CONFIG_FAULT_QUEUE_6 (3 << 3)
+#define LM77_CONFIG_TCRITAPOLARITY 0x04
+#define LM77_CONFIG_INTPOLARITY 0x08
+#define LM77_CONFIG_FAULT_QUEUE LM75_CONFIG_FAULT_QUEUE_4
+
#endif /* _DEV_I2C_LM75REG_H_ */
----Next_Part(Sun_Apr_30_02:01:44_2006_187)----