summaryrefslogtreecommitdiff
path: root/sys/dev/i2c
diff options
context:
space:
mode:
authorkiyohara <kiyohara@NetBSD.org>2006-05-17 00:10:54 +0000
committerkiyohara <kiyohara@NetBSD.org>2006-05-17 00:10:54 +0000
commit43911ef4e28c4a5fb2a94cf0bebf20359ad2787f (patch)
treeffa76d19673784cd697357bdfc98cce11ddb336b /sys/dev/i2c
parentdbbc553deb1472bb58173541a7af3db61c0f0035 (diff)
Support LM77 Temperature.
Diffstat (limited to 'sys/dev/i2c')
-rw-r--r--sys/dev/i2c/lm75.c77
-rw-r--r--sys/dev/i2c/lm75reg.h13
2 files changed, 78 insertions, 12 deletions
diff --git a/sys/dev/i2c/lm75.c b/sys/dev/i2c/lm75.c
index d4a2706204e..c5ec22c4ff6 100644
--- a/sys/dev/i2c/lm75.c
+++ b/sys/dev/i2c/lm75.c
@@ -1,4 +1,4 @@
-/* $NetBSD: lm75.c,v 1.8 2006/05/05 18:04:42 thorpej Exp $ */
+/* $NetBSD: lm75.c,v 1.9 2006/05/17 00:10:54 kiyohara Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@@ -49,12 +49,13 @@ struct lmtemp_softc {
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 const struct envsys_range lmtemp_ranges[] = {
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);
@@ -94,14 +127,18 @@ lmtemp_attach(struct device *parent, struct device *self, void *aux)
struct lmtemp_softc *sc = device_private(self);
struct i2c_attach_args *ia = aux;
prop_string_t desc;
+ int 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);
@@ -129,6 +166,8 @@ lmtemp_attach(struct device *parent, struct device *self, void *aux)
else
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;
@@ -172,11 +211,7 @@ lmtemp_temp_read(struct lmtemp_softc *sc, uint8_t which, uint32_t *valp)
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);
}
@@ -279,3 +314,23 @@ lmtemp_decode_ds75(const uint8_t *buf)
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);
+}
+
diff --git a/sys/dev/i2c/lm75reg.h b/sys/dev/i2c/lm75reg.h
index 75de5fdc110..dad8b64fe88 100644
--- a/sys/dev/i2c/lm75reg.h
+++ b/sys/dev/i2c/lm75reg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: lm75reg.h,v 1.2 2005/12/11 12:21:22 christos Exp $ */
+/* $NetBSD: lm75reg.h,v 1.3 2006/05/17 00:10:54 kiyohara Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@@ -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_ */