summaryrefslogtreecommitdiff
path: root/sys/dev/i2c
diff options
context:
space:
mode:
authorhannken <hannken@NetBSD.org>2011-02-14 08:50:38 +0000
committerhannken <hannken@NetBSD.org>2011-02-14 08:50:38 +0000
commitac0fa1d012235bbcbe3e62693b30ca499b984e5d (patch)
tree43fd9c329c7dd2e1382a7cc2cfe43347fc5a7dd8 /sys/dev/i2c
parentdf23d0d3422def3f7e12788751c1ca2c950307a8 (diff)
Initial implementation of ibmhawk(4) driver for sensors behind the IBM Hawk
on-board Integrated Systems Management Processor found on some eServers. Tested on an IBM eServer x335.
Diffstat (limited to 'sys/dev/i2c')
-rw-r--r--sys/dev/i2c/files.i2c7
-rw-r--r--sys/dev/i2c/ibmhawk.c386
-rw-r--r--sys/dev/i2c/ibmhawkreg.h86
-rw-r--r--sys/dev/i2c/ibmhawkvar.h51
4 files changed, 529 insertions, 1 deletions
diff --git a/sys/dev/i2c/files.i2c b/sys/dev/i2c/files.i2c
index 1c8cb19d464..6a7e074f363 100644
--- a/sys/dev/i2c/files.i2c
+++ b/sys/dev/i2c/files.i2c
@@ -1,4 +1,4 @@
-# $NetBSD: files.i2c,v 1.32 2011/01/21 19:11:47 jakllsch Exp $
+# $NetBSD: files.i2c,v 1.33 2011/02/14 08:50:39 hannken Exp $
defflag opt_i2cbus.h I2C_SCAN
define i2cbus { }
@@ -145,3 +145,8 @@ file dev/i2c/smscmon.c smscmon
device g760a: sysmon_envsys
attach g760a at iic
file dev/i2c/g760a.c g760a
+
+# IBM Hawk Integrated Systems Management Processor
+device ibmhawk: sysmon_envsys
+attach ibmhawk at iic
+file dev/i2c/ibmhawk.c ibmhawk
diff --git a/sys/dev/i2c/ibmhawk.c b/sys/dev/i2c/ibmhawk.c
new file mode 100644
index 00000000000..409bca75260
--- /dev/null
+++ b/sys/dev/i2c/ibmhawk.c
@@ -0,0 +1,386 @@
+/* $NetBSD: ibmhawk.c,v 1.1 2011/02/14 08:50:39 hannken Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Juergen Hannken-Illjes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/systm.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/bswap.h>
+
+#include <dev/sysmon/sysmonvar.h>
+#include <dev/i2c/i2cvar.h>
+#include <dev/i2c/ibmhawkreg.h>
+#include <dev/i2c/ibmhawkvar.h>
+
+#if !defined(IBMHAWK_DEBUG) /* Set to 2 for verbose debug. */
+#if defined(DEBUG)
+#define IBMHAWK_DEBUG 1
+#else
+#define IBMHAWK_DEBUG 0
+#endif
+#endif
+
+/*
+ * Known sensors.
+ */
+static struct ibmhawk_sensordesc {
+ const char *desc;
+ uint32_t units;
+ int offset;
+} ibmhawk_sensors[] = {
+ { "Ambient temperature", ENVSYS_STEMP, IBMHAWK_T_AMBIENT },
+ { "CPU 1 temperature", ENVSYS_STEMP, IBMHAWK_T_CPU },
+ { "CPU 2 temperature", ENVSYS_STEMP, IBMHAWK_T_CPU+1 },
+ { "12 Voltage sensor", ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE },
+ { "5 Voltage sensor", ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+1 },
+ { "3.3 Voltage sensor", ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+2 },
+ { "2.5 Voltage sensor", ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+3 },
+ { "1.5 Voltage sensor", ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+4 },
+ { "1.25 Voltage sensor", ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+5 },
+ { "VRM 1", ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+6 },
+ { "Fan 1", ENVSYS_SFANRPM, IBMHAWK_F_FAN },
+ { "Fan 2", ENVSYS_SFANRPM, IBMHAWK_F_FAN+1 },
+ { "Fan 3", ENVSYS_SFANRPM, IBMHAWK_F_FAN+2 },
+ { "Fan 4", ENVSYS_SFANRPM, IBMHAWK_F_FAN+3 },
+ { "Fan 5", ENVSYS_SFANRPM, IBMHAWK_F_FAN+4 },
+ { "Fan 6", ENVSYS_SFANRPM, IBMHAWK_F_FAN+5 },
+};
+static const int ibmhawk_num_sensors =
+ (sizeof(ibmhawk_sensors)/sizeof(ibmhawk_sensors[0]));
+
+static int ibmhawk_match(device_t, cfdata_t, void *);
+static void ibmhawk_attach(device_t, device_t, void *);
+static int ibmhawk_detach(device_t, int);
+static uint8_t ibmhawk_cksum(uint8_t *);
+static int ibmhawk_request(struct ibmhawk_softc *,
+ uint8_t, ibmhawk_response_t *);
+static uint32_t ibmhawk_normalize(int, uint32_t);
+static void ibmhawk_set(struct ibmhawk_softc *, int, int, bool, bool);
+static void ibmhawk_refreshall(struct ibmhawk_softc *, bool);
+static void ibmhawk_refresh(struct sysmon_envsys *, envsys_data_t *);
+static void ibmhawk_get_limits(struct sysmon_envsys *, envsys_data_t *,
+ sysmon_envsys_lim_t *, uint32_t *);
+
+CFATTACH_DECL_NEW(ibmhawk, sizeof(struct ibmhawk_softc),
+ ibmhawk_match, ibmhawk_attach, ibmhawk_detach, NULL);
+
+static int
+ibmhawk_match(device_t parent, cfdata_t match, void *aux)
+{
+ struct i2c_attach_args *ia = aux;
+ ibmhawk_response_t resp;
+ static struct ibmhawk_softc sc;
+
+ sc.sc_tag = ia->ia_tag;
+ sc.sc_addr = ia->ia_addr;
+ if (ibmhawk_request(&sc, IHR_EQUIP, &resp))
+ return 0;
+ return 1;
+}
+
+static void
+ibmhawk_attach(device_t parent, device_t self, void *aux)
+{
+ struct ibmhawk_softc *sc = device_private(self);
+ struct i2c_attach_args *ia = aux;
+ ibmhawk_response_t resp;
+ int i;
+
+ sc->sc_dev = self;
+ sc->sc_tag = ia->ia_tag;
+ sc->sc_addr = ia->ia_addr;
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+ if (ibmhawk_request(sc, IHR_NAME, &resp)) {
+ aprint_normal(": communication failed\n");
+ return;
+ }
+ aprint_normal(": IBM Hawk \"%.16s\"\n", resp.ihr_name);
+ if (ibmhawk_request(sc, IHR_EQUIP, &resp)) {
+ aprint_error_dev(sc->sc_dev, "equip query failed\n");
+ return;
+ }
+ sc->sc_numcpus = min(resp.ihr_numcpus, IBMHAWK_MAX_CPU);
+ sc->sc_numfans = min(resp.ihr_numfans, IBMHAWK_MAX_FAN);
+#if IBMHAWK_DEBUG > 0
+ aprint_normal_dev(sc->sc_dev, "monitoring %d/%d cpu(s) %d/%d fan(s)\n",
+ sc->sc_numcpus, resp.ihr_numcpus, sc->sc_numfans, resp.ihr_numfans);
+#endif
+ /* Request and set sensor thresholds. */
+ if (ibmhawk_request(sc, IHR_TEMP_THR, &resp)) {
+ aprint_error_dev(sc->sc_dev, "temp threshold query failed\n");
+ return;
+ }
+ for (i = 0; i < sc->sc_numcpus; i++)
+ sc->sc_sensordata[IBMHAWK_T_CPU+i].ihs_warnmax =
+ resp.ihr_t_warn_thr;
+ if (ibmhawk_request(sc, IHR_VOLT_THR, &resp)) {
+ aprint_error_dev(sc->sc_dev, "volt threshold query failed\n");
+ return;
+ }
+ for (i = 0; i < IBMHAWK_MAX_VOLTAGE; i++) {
+ sc->sc_sensordata[IBMHAWK_V_VOLTAGE+i].ihs_warnmax =
+ bswap16(resp.ihr_v_voltage_thr[i*2]);
+ sc->sc_sensordata[IBMHAWK_V_VOLTAGE+i].ihs_warnmin =
+ bswap16(resp.ihr_v_voltage_thr[i*2+1]);
+ }
+ if ((sc->sc_sme = sysmon_envsys_create()) == NULL) {
+ aprint_error_dev(sc->sc_dev, "sysmon_envsys_create failed\n");
+ return;
+ }
+ ibmhawk_refreshall(sc, true);
+ sc->sc_sme->sme_name = device_xname(sc->sc_dev);
+ sc->sc_sme->sme_cookie = sc;
+ sc->sc_sme->sme_refresh = ibmhawk_refresh;
+ sc->sc_sme->sme_get_limits = ibmhawk_get_limits;
+ if (sysmon_envsys_register(sc->sc_sme)) {
+ aprint_error_dev(sc->sc_dev, "sysmon_envsys_register failed\n");
+ sysmon_envsys_destroy(sc->sc_sme);
+ sc->sc_sme = NULL;
+ return;
+ }
+}
+
+static int
+ibmhawk_detach(device_t self, int flags)
+{
+ struct ibmhawk_softc *sc = device_private(self);
+
+ if (sc->sc_sme)
+ sysmon_envsys_destroy(sc->sc_sme);
+ return 0;
+}
+
+
+/*
+ * Compute the message checksum.
+ */
+static uint8_t
+ibmhawk_cksum(uint8_t *buf)
+{
+ int len = *buf++;
+ int s = 0;
+
+ while (--len > 0)
+ s += *buf++;
+ return -s;
+}
+
+/*
+ * Request information from the management processor.
+ * The response will be zeroed on error.
+ * Request and response have the form <n> <data 0:n-2> <checksum>.
+ */
+static int
+ibmhawk_request(struct ibmhawk_softc *sc, uint8_t request,
+ ibmhawk_response_t *response)
+{
+ int i, error, retries;;
+ uint8_t buf[sizeof(ibmhawk_response_t)+3], dummy;
+
+ error = EIO; /* Fail until we have a valid response. */
+ retries = 0;
+
+ if (iic_acquire_bus(sc->sc_tag, 0))
+ return error;
+
+again:
+ memset(response, 0, sizeof(*response));
+
+ /* Build and send the request. */
+ buf[0] = 2;
+ buf[1] = request;
+ buf[2] = ibmhawk_cksum(buf);
+#if IBMHAWK_DEBUG > 1
+ printf("[");
+ for (i = 0; i < 3; i++)
+ printf(" %02x", buf[i]);
+ printf(" ]");
+#endif
+ for (i = 0; i < 3; i++)
+ if (iic_smbus_send_byte(sc->sc_tag, sc->sc_addr, buf[i], 0))
+ goto bad;
+
+ /* Receive and check the response. */
+#if IBMHAWK_DEBUG > 1
+ printf(" => [");
+#endif
+ if (iic_smbus_receive_byte(sc->sc_tag, sc->sc_addr, &buf[0], 0))
+ goto bad;
+ if (buf[0] == 0 || buf[0] == 255)
+ goto bad;
+ for (i = 1; i < buf[0]+1; i++)
+ if (iic_smbus_receive_byte(sc->sc_tag, sc->sc_addr,
+ (i < sizeof buf ? &buf[i] : &dummy), 0))
+ goto bad;
+ if (buf[0] >= sizeof(buf) || buf[1] != request ||
+ ibmhawk_cksum(buf) != buf[buf[0]])
+ goto bad;
+ if (buf[0] > 2)
+ memcpy(response, buf+2, buf[0]-2);
+ error = 0;
+
+bad:
+#if IBMHAWK_DEBUG > 1
+ for (i = 0; i < min(buf[0]+1, sizeof buf); i++)
+ printf(" %02x", buf[i]);
+ printf(" ] => %d\n", error);
+#endif
+ if (error != 0 && retries++ < 3)
+ goto again;
+
+ iic_release_bus(sc->sc_tag, 0);
+ return error;
+}
+
+static uint32_t
+ibmhawk_normalize(int value, uint32_t units)
+{
+
+ if (value == 0)
+ return 0;
+
+ switch (units) {
+ case ENVSYS_STEMP:
+ return 273150000+1000000*value;
+ case ENVSYS_SVOLTS_DC:
+ return 10000*value;
+ default:
+ return value;
+ }
+}
+
+static void
+ibmhawk_set(struct ibmhawk_softc *sc,
+ int offset, int value, bool valid, bool create)
+{
+ int i;
+ struct ibmhawk_sensordesc *sp;
+ struct ibmhawk_sensordata *sd;
+ envsys_data_t *dp;
+
+ sd = &sc->sc_sensordata[offset];
+ dp = &sd->ihs_edata;
+ sp = NULL;
+ if (create) {
+ for (i = 0; i < ibmhawk_num_sensors; i++)
+ if (ibmhawk_sensors[i].offset == offset) {
+ sp = ibmhawk_sensors+i;
+ break;
+ }
+ if (sp == NULL) {
+#if IBMHAWK_DEBUG > 0
+ aprint_error_dev(sc->sc_dev,
+ "offset %d: no sensor found\n", offset);
+#endif
+ return;
+ }
+ strlcpy(dp->desc, sp->desc, sizeof(dp->desc));
+ dp->units = sp->units;
+ if (sd->ihs_warnmin != 0 || sd->ihs_warnmax != 0) {
+ sd->ihs_warnmin =
+ ibmhawk_normalize(sd->ihs_warnmin, dp->units);
+ sd->ihs_warnmax =
+ ibmhawk_normalize(sd->ihs_warnmax, dp->units);
+ dp->flags |= ENVSYS_FMONLIMITS;
+ }
+ if (sysmon_envsys_sensor_attach(sc->sc_sme, dp))
+ aprint_error_dev(sc->sc_dev,
+ "failed to attach \"%s\"\n", dp->desc);
+ }
+
+ dp->value_cur = ibmhawk_normalize(value, dp->units);
+ if (!valid)
+ dp->state = ENVSYS_SINVALID;
+ else if (sd->ihs_warnmin != 0 && value < sd->ihs_warnmin)
+ dp->state = ENVSYS_SWARNUNDER;
+ else if (sd->ihs_warnmax != 0 && value > sd->ihs_warnmax)
+ dp->state = ENVSYS_SWARNOVER;
+ else
+ dp->state = ENVSYS_SVALID;
+}
+
+static void
+ibmhawk_refreshall(struct ibmhawk_softc *sc, bool create)
+{
+ int i;
+ bool valid;
+ ibmhawk_response_t resp;
+
+ valid = (ibmhawk_request(sc, IHR_TEMP, &resp) == 0);
+ ibmhawk_set(sc, IBMHAWK_T_AMBIENT, resp.ihr_t_ambient, valid, create);
+ for (i = 0; i < sc->sc_numcpus; i++)
+ ibmhawk_set(sc, IBMHAWK_T_CPU+i,
+ resp.ihr_t_cpu[i], valid, create);
+
+ valid = (ibmhawk_request(sc, IHR_FANRPM, &resp) == 0);
+ for (i = 0; i < sc->sc_numfans; i++)
+ ibmhawk_set(sc, IBMHAWK_F_FAN+i,
+ bswap16(resp.ihr_fanrpm[i]), valid, create);
+
+ valid = (ibmhawk_request(sc, IHR_VOLT, &resp) == 0);
+ for (i = 0; i < IBMHAWK_MAX_VOLTAGE; i++)
+ ibmhawk_set(sc, IBMHAWK_V_VOLTAGE+i,
+ bswap16(resp.ihr_v_voltage[i]), valid, create);
+}
+
+static void
+ibmhawk_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
+{
+ struct ibmhawk_softc *sc = sme->sme_cookie;
+
+ /* No more than two refreshes per second. */
+ if (hardclock_ticks-sc->sc_refresh < hz/2)
+ return;
+#if IBMHAWK_DEBUG > 1
+ aprint_normal_dev(sc->sc_dev, "refresh \"%s\" delta %d\n",
+ edata->desc, hardclock_ticks-sc->sc_refresh);
+#endif
+ sc->sc_refresh = hardclock_ticks;
+ ibmhawk_refreshall(sc, false);
+}
+
+static void
+ibmhawk_get_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
+ sysmon_envsys_lim_t *limits, uint32_t *props)
+{
+ struct ibmhawk_sensordata *sd = (struct ibmhawk_sensordata *)edata;
+
+ if (sd->ihs_warnmin != 0) {
+ limits->sel_warnmin = sd->ihs_warnmin;
+ *props |= PROP_WARNMIN;
+ }
+ if (sd->ihs_warnmax != 0) {
+ limits->sel_warnmax = sd->ihs_warnmax;
+ *props |= PROP_WARNMAX;
+ }
+}
diff --git a/sys/dev/i2c/ibmhawkreg.h b/sys/dev/i2c/ibmhawkreg.h
new file mode 100644
index 00000000000..e3cbf7960bf
--- /dev/null
+++ b/sys/dev/i2c/ibmhawkreg.h
@@ -0,0 +1,86 @@
+/* $NetBSD: ibmhawkreg.h,v 1.1 2011/02/14 08:50:39 hannken Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Juergen Hannken-Illjes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define IBMHAWK_MAX_CPU 2
+#define IBMHAWK_MAX_VOLTAGE 7
+#define IBMHAWK_MAX_FAN 6
+
+typedef union ibmhawk_response {
+ struct {
+ uint8_t unknown1;
+ uint8_t numcpus;
+ uint8_t unknown2[5];
+ uint8_t numfans;
+ } resp_equip;
+#define IHR_EQUIP 0x51
+#define ihr_numcpus resp_equip.numcpus
+#define ihr_numfans resp_equip.numfans
+ struct {
+ uint8_t unknown[4];
+ uint16_t rpm[IBMHAWK_MAX_FAN];
+ } resp_fan;
+#define IHR_FANRPM 0xa2
+#define ihr_fanrpm resp_fan.rpm
+ struct {
+ char name[16];
+ } resp_name;
+#define IHR_NAME 0x14
+#define ihr_name resp_name.name
+ struct {
+ uint8_t unknown1[4];
+ uint8_t ambient;
+ uint8_t cpu[IBMHAWK_MAX_CPU];
+ uint8_t unknown2[2];
+ } resp_temp;
+#define IHR_TEMP 0xa4
+#define ihr_t_ambient resp_temp.ambient
+#define ihr_t_cpu resp_temp.cpu
+ struct {
+ uint8_t warn_reset;
+ uint8_t warn;
+ uint8_t soft;
+ uint8_t hard;
+ } resp_temp_thresh;
+#define IHR_TEMP_THR 0xe0
+#define ihr_t_warn_thr resp_temp_thresh.warn
+#define ihr_t_soft_thr resp_temp_thresh.soft
+ struct {
+ uint8_t unknown[2];
+ uint16_t voltage[IBMHAWK_MAX_VOLTAGE];
+ } resp_volt;
+#define IHR_VOLT 0xa6
+#define ihr_v_voltage resp_volt.voltage
+ struct {
+ uint16_t voltage[IBMHAWK_MAX_VOLTAGE*2];
+ } resp_volt_thresh;
+#define IHR_VOLT_THR 0xea
+#define ihr_v_voltage_thr resp_volt_thresh.voltage
+} ibmhawk_response_t __packed;
diff --git a/sys/dev/i2c/ibmhawkvar.h b/sys/dev/i2c/ibmhawkvar.h
new file mode 100644
index 00000000000..62f923d0a47
--- /dev/null
+++ b/sys/dev/i2c/ibmhawkvar.h
@@ -0,0 +1,51 @@
+/* $NetBSD: ibmhawkvar.h,v 1.1 2011/02/14 08:50:39 hannken Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Juergen Hannken-Illjes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define IBMHAWK_T_AMBIENT 0
+#define IBMHAWK_T_CPU 1
+#define IBMHAWK_V_VOLTAGE (IBMHAWK_T_CPU+IBMHAWK_MAX_CPU)
+#define IBMHAWK_F_FAN (IBMHAWK_V_VOLTAGE+IBMHAWK_MAX_VOLTAGE)
+#define IBMHAWK_MAX_SENSOR (IBMHAWK_F_FAN+IBMHAWK_MAX_FAN)
+
+struct ibmhawk_softc {
+ device_t sc_dev;
+ i2c_tag_t sc_tag;
+ i2c_addr_t sc_addr;
+ int sc_numcpus;
+ int sc_numfans;
+ int sc_refresh;
+ struct sysmon_envsys *sc_sme;
+ struct ibmhawk_sensordata {
+ envsys_data_t ihs_edata;
+ uint32_t ihs_warnmin;
+ uint32_t ihs_warnmax;
+ } sc_sensordata[IBMHAWK_MAX_SENSOR];
+};