summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2009-09-20 19:31:58 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2009-09-20 19:31:58 +0000
commitec236804e86c8361d96d2fb87389dda5a740e52f (patch)
tree3e60bb9bfc43d419d5b878dba2f807bbbcc02e2e
parent4ebbef83089b2767bebfae16e5a1eef9122359e5 (diff)
Use name provided by the LOM device as description for the temperature
sensor.
-rw-r--r--sys/arch/sparc64/dev/lom.c118
1 files changed, 115 insertions, 3 deletions
diff --git a/sys/arch/sparc64/dev/lom.c b/sys/arch/sparc64/dev/lom.c
index 48a4c9e395e..79b980e1a1d 100644
--- a/sys/arch/sparc64/dev/lom.c
+++ b/sys/arch/sparc64/dev/lom.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: lom.c,v 1.1 2009/09/19 19:37:42 kettenis Exp $ */
+/* $OpenBSD: lom.c,v 1.2 2009/09/20 19:31:57 kettenis Exp $ */
/*
- * Copyright (c) 2008 Mark Kettenis
+ * Copyright (c) 2009 Mark Kettenis
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -36,18 +36,31 @@
#define LOM_STATUS_OBF 0x01 /* Output Buffer Full */
#define LOM_STATUS_IBF 0x02 /* Input Buffer Full */
+#define LOM_IDX_CMD 0x00
+#define LOM_IDX_CMD_GENERIC 0x00
+#define LOM_IDX_CMD_TEMP 0x04
+
#define LOM_IDX_FW_REV 0x01 /* Firmware revision */
#define LOM_IDX_TEMP1 0x18 /* Temperature */
+#define LOM_IDX_LED1 0x25
+
+#define LOM_IDX_ALARM 0x30
+
#define LOM_IDX_PROBE55 0x7e /* Always returns 0x55 */
#define LOM_IDX_PROBEAA 0x7f /* Always returns 0xaa */
+#define LOM_IDX4_TEMP_NAME_START 0x40
+#define LOM_IDX4_TEMP_NAME_END 0xff
+
struct lom_softc {
struct device sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
+ int sc_space;
+
struct ksensor sc_sensor;
struct ksensordev sc_sensordev;
};
@@ -66,6 +79,7 @@ struct cfdriver lom_cd = {
int lom_read(struct lom_softc *, uint8_t, uint8_t *);
int lom_write(struct lom_softc *, uint8_t, uint8_t);
+int lom_init_desc(struct lom_softc *sc);
void lom_refresh(void *);
int
@@ -105,6 +119,10 @@ lom_attach(struct device *parent, struct device *self, void *aux)
strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
sizeof(sc->sc_sensordev.xname));
sc->sc_sensor.type = SENSOR_TEMP;
+ if (lom_init_desc(sc)) {
+ printf(": can't read sensor names\n");
+ return;
+ }
sensor_attach(&sc->sc_sensordev, &sc->sc_sensor);
@@ -140,7 +158,7 @@ lom_read(struct lom_softc *sc, uint8_t reg, uint8_t *val)
for (i = 1000; i > 0; i--) {
str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM_STATUS);
delay(10);
- if (str & 0x01)
+ if (str & LOM_STATUS_OBF)
break;
}
if (i == 0)
@@ -150,6 +168,100 @@ lom_read(struct lom_softc *sc, uint8_t reg, uint8_t *val)
return (0);
}
+int
+lom_write(struct lom_softc *sc, uint8_t reg, uint8_t val)
+{
+ uint8_t str;
+ int i;
+
+ /* Wait for input buffer to become available. */
+ for (i = 1000; i > 0; i--) {
+ str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM_STATUS);
+ delay(10);
+ if ((str & LOM_STATUS_IBF) == 0)
+ break;
+ }
+ if (i == 0)
+ return (ETIMEDOUT);
+
+ if (sc->sc_space == LOM_IDX_CMD_GENERIC && reg != LOM_IDX_CMD)
+ reg |= 0x80;
+
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, LOM_CMD, reg);
+
+ /* Wait until the microcontroller fills output buffer. */
+ for (i = 1000; i > 0; i--) {
+ str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM_STATUS);
+ delay(10);
+ if (str & LOM_STATUS_OBF)
+ break;
+ }
+ if (i == 0)
+ return (ETIMEDOUT);
+
+ bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM_DATA);
+
+ /* Wait for input buffer to become available. */
+ for (i = 1000; i > 0; i--) {
+ str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM_STATUS);
+ delay(10);
+ if ((str & LOM_STATUS_IBF) == 0)
+ break;
+ }
+ if (i == 0)
+ return (ETIMEDOUT);
+
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, LOM_DATA, val);
+
+ /* Wait until the microcontroller fills output buffer. */
+ for (i = 1000; i > 0; i--) {
+ str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM_STATUS);
+ delay(10);
+ if (str & LOM_STATUS_OBF)
+ break;
+ }
+ if (i == 0)
+ return (ETIMEDOUT);
+
+ bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM_DATA);
+
+ /* If we switched spaces, remember the one we're in now. */
+ if (reg == LOM_IDX_CMD)
+ sc->sc_space = val;
+
+ return (0);
+}
+
+int
+lom_init_desc(struct lom_softc *sc)
+{
+ uint8_t val;
+ int i, j, error;
+
+ error = lom_write(sc, LOM_IDX_CMD, LOM_IDX_CMD_TEMP);
+ if (error)
+ return (error);
+
+ i = LOM_IDX4_TEMP_NAME_START, j = 0;
+ while (i <= LOM_IDX4_TEMP_NAME_END) {
+ error = lom_read(sc, i, &val);
+ if (error)
+ goto fail;
+
+ if (val == 0xff)
+ break;
+
+ sc->sc_sensor.desc[j++] = val;
+ if (j > sizeof (sc->sc_sensor.desc) - 1)
+ break;
+ i++;
+ }
+
+fail:
+ lom_write(sc, LOM_IDX_CMD, LOM_IDX_CMD_GENERIC);
+ return (error);
+}
+
void
lom_refresh(void *arg)
{