summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2006-01-13 21:41:40 +0000
committerderaadt <deraadt@openbsd.org>2006-01-13 21:41:40 +0000
commita938f6f934b5be6bc6c39099d09622933f5c91af (patch)
tree3a37efddec0014bf3c72b8b7ecfd0100fb887fea
parentPull in inttypes.h, not stdint.h so we get the prototypes for (diff)
downloadwireguard-openbsd-a938f6f934b5be6bc6c39099d09622933f5c91af.tar.xz
wireguard-openbsd-a938f6f934b5be6bc6c39099d09622933f5c91af.zip
handle all 3 types of chips correctly. go into continuous mode, and
start the chips right (two kinds of start sequences). then get the temperature readings correctly, including negative temperatures. done with grange. pity the poor russian with only the lowest of the low end i2c chips
-rw-r--r--sys/dev/i2c/ds1631.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/sys/dev/i2c/ds1631.c b/sys/dev/i2c/ds1631.c
index 703e063a8c7..13bcc30d9e8 100644
--- a/sys/dev/i2c/ds1631.c
+++ b/sys/dev/i2c/ds1631.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ds1631.c,v 1.3 2006/01/13 00:13:01 deraadt Exp $ */
+/* $OpenBSD: ds1631.c,v 1.4 2006/01/13 21:41:40 deraadt Exp $ */
/*
* Copyright (c) 2005 Theo de Raadt
@@ -24,7 +24,12 @@
#include <dev/i2c/i2cvar.h>
/* Maxim ds 1631 registers */
+#define DS1631_START 0x51
+#define DS1624_START 0xee
#define DS1631_TEMP 0xaa
+#define DS1631_CONTROL 0xac
+#define DS1631_CONTROL_DONE 0x80
+#define DS1631_CONTROL_1SHOT 0x01
/* Sensors */
#define MAXDS_TEMP 0
@@ -67,11 +72,45 @@ maxds_attach(struct device *parent, struct device *self, void *aux)
{
struct maxds_softc *sc = (struct maxds_softc *)self;
struct i2c_attach_args *ia = aux;
+ u_int8_t cmd, data;
int i;
+ printf(": %s", ia->ia_name);
+
sc->sc_tag = ia->ia_tag;
sc->sc_addr = ia->ia_addr;
+ iic_acquire_bus(sc->sc_tag, 0);
+
+ cmd = DS1631_CONTROL;
+ if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
+ sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
+ if (data & DS1631_CONTROL_1SHOT) {
+ /*
+ * 1-Shot mode would require us to write every refresh
+ * which is stupid. Put us into continuous mode.
+ */
+ data &= ~DS1631_CONTROL_1SHOT;
+
+ (void) iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
+ sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0);
+ //delay(10 * 1000);
+ printf(", continuous");
+ goto dostart;
+ }
+ if (data & DS1631_CONTROL_DONE) {
+dostart:
+ cmd = DS1631_START;
+ if (strcmp(ia->ia_name, "ds1624") == 0)
+ cmd = DS1624_START;
+ (void) iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
+ sc->sc_addr, &cmd, sizeof cmd, NULL, 0, 0);
+ printf(", starting");
+ }
+ }
+
+ iic_release_bus(sc->sc_tag, 0);
+
/* Initialize sensor data. */
for (i = 0; i < MAXDS_NUM_SENSORS; i++)
strlcpy(sc->sc_sensor[i].device, sc->sc_dev.dv_xname,
@@ -104,7 +143,7 @@ maxds_refresh(void *arg)
if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
sc->sc_sensor[MAXDS_TEMP].value = 273150000 +
- 1000000 * data[1] + 1000000 * data[0] / 256;
+ ((int)((u_int16_t)data[0] << 8 | data[1])) / 8 * 31250;
iic_release_bus(sc->sc_tag, 0);
}