summaryrefslogtreecommitdiff
path: root/sys/dev/acpi/acpithinkpad.c
diff options
context:
space:
mode:
authorJordan Hargrave <jordan@cvs.openbsd.org>2009-03-10 20:36:11 +0000
committerJordan Hargrave <jordan@cvs.openbsd.org>2009-03-10 20:36:11 +0000
commite19d662685b8911900a8d769a933f7d40013f712 (patch)
tree2bbc6a25df8866cd6393bd0b66e005d450429465 /sys/dev/acpi/acpithinkpad.c
parente023a0dc8509fb134ba3371635dd853127f9c19c (diff)
Added sensor devices for Thinkpad (temp+fan)
Exported aml_evalinteger method ok marco@
Diffstat (limited to 'sys/dev/acpi/acpithinkpad.c')
-rw-r--r--sys/dev/acpi/acpithinkpad.c77
1 files changed, 75 insertions, 2 deletions
diff --git a/sys/dev/acpi/acpithinkpad.c b/sys/dev/acpi/acpithinkpad.c
index fc48e0d4b9c..a70755073f7 100644
--- a/sys/dev/acpi/acpithinkpad.c
+++ b/sys/dev/acpi/acpithinkpad.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpithinkpad.c,v 1.15 2008/12/26 06:35:34 jsg Exp $ */
+/* $OpenBSD: acpithinkpad.c,v 1.16 2009/03/10 20:36:10 jordan Exp $ */
/*
* Copyright (c) 2008 joshua stein <jcs@openbsd.org>
*
@@ -75,13 +75,25 @@
/* type 7 events */
#define THINKPAD_SWITCH_WIRELESS 0x000
+#define THINKPAD_NSENSORS 9
+#define THINKPAD_NTEMPSENSORS 8
+
+#define THINKPAD_ECOFFSET_FANLO 0x84
+#define THINKPAD_ECOFFSET_FANHI 0x85
+
struct acpithinkpad_softc {
struct device sc_dev;
+ struct acpiec_softc *sc_ec;
struct acpi_softc *sc_acpi;
struct aml_node *sc_devnode;
+
+ struct ksensor sc_sens[THINKPAD_NSENSORS];
+ struct ksensordev sc_sensdev;
};
+extern void acpiec_read(struct acpiec_softc *, u_int8_t, int, u_int8_t *);
+
int thinkpad_match(struct device *, void *, void *);
void thinkpad_attach(struct device *, struct device *, void *);
int thinkpad_hotkey(struct aml_node *, int, void *);
@@ -95,6 +107,9 @@ int thinkpad_volume_mute(struct acpithinkpad_softc *);
int thinkpad_brightness_up(struct acpithinkpad_softc *);
int thinkpad_brightness_down(struct acpithinkpad_softc *);
+void thinkpad_sensor_attach(struct acpithinkpad_softc *sc);
+void thinkpad_sensor_refresh(void *);
+
struct cfattach acpithinkpad_ca = {
sizeof(struct acpithinkpad_softc), thinkpad_match, thinkpad_attach
};
@@ -128,6 +143,58 @@ thinkpad_match(struct device *parent, void *match, void *aux)
}
void
+thinkpad_sensor_attach(struct acpithinkpad_softc *sc)
+{
+ int i;
+
+ if (sc->sc_acpi->sc_ec == NULL)
+ return;
+ sc->sc_ec = sc->sc_acpi->sc_ec;
+
+ /* Add temperature probes */
+ strlcpy(sc->sc_sensdev.xname, DEVNAME(sc),
+ sizeof(sc->sc_sensdev.xname));
+ for (i=0; i<THINKPAD_NTEMPSENSORS; i++) {
+ snprintf(sc->sc_sens[i].desc, sizeof(sc->sc_sens[i].desc),
+ "TMP%d", i);
+ sc->sc_sens[i].type = SENSOR_TEMP;
+ sc->sc_sens[i].value = 0;
+ sensor_attach(&sc->sc_sensdev, &sc->sc_sens[i]);
+ }
+
+ /* Add fan probe */
+ strlcpy(sc->sc_sens[i].desc, "fan",
+ sizeof(sc->sc_sens[i].desc));
+ sc->sc_sens[i].type = SENSOR_FANRPM;
+ sc->sc_sens[i].value = 0;
+ sensor_attach(&sc->sc_sensdev, &sc->sc_sens[i]);
+
+ sensordev_install(&sc->sc_sensdev);
+}
+
+void
+thinkpad_sensor_refresh(void *arg)
+{
+ struct acpithinkpad_softc *sc = arg;
+ u_int8_t lo, hi, i;
+ int64_t tmp;
+
+ /* Refresh sensor readings */
+ for (i=0; i<THINKPAD_NTEMPSENSORS; i++) {
+ aml_evalinteger(sc->sc_acpi, sc->sc_ec->sc_devnode,
+ sc->sc_sens[i].desc, 0, 0, &tmp);
+ sc->sc_sens[i].value = (tmp * 1000000) + 273150000;
+ if (tmp > 127 || tmp < -127)
+ sc->sc_sens[i].flags = SENSOR_FINVALID;
+ }
+
+ /* Read fan RPM */
+ acpiec_read(sc->sc_ec, THINKPAD_ECOFFSET_FANLO, 1, &lo);
+ acpiec_read(sc->sc_ec, THINKPAD_ECOFFSET_FANHI, 1, &hi);
+ sc->sc_sens[i].value = ((hi << 8L) + lo);
+}
+
+void
thinkpad_attach(struct device *parent, struct device *self, void *aux)
{
struct acpithinkpad_softc *sc = (struct acpithinkpad_softc *)self;
@@ -140,10 +207,11 @@ thinkpad_attach(struct device *parent, struct device *self, void *aux)
/* set event mask to receive everything */
thinkpad_enable_events(sc);
+ thinkpad_sensor_attach(sc);
/* run thinkpad_hotkey on button presses */
aml_register_notify(sc->sc_devnode, aa->aaa_dev,
- thinkpad_hotkey, sc, ACPIDEV_NOPOLL);
+ thinkpad_hotkey, sc, ACPIDEV_POLL);
}
int
@@ -196,6 +264,11 @@ thinkpad_hotkey(struct aml_node *node, int notify_type, void *arg)
struct aml_value res;
int val, type, event, handled, rv = 1, tot = 0;
+ if (notify_type == 0x00) {
+ /* poll sensors */
+ thinkpad_sensor_refresh(sc);
+ return 0;
+ }
if (notify_type != 0x80)
goto fail;