diff options
author | Jordan Hargrave <jordan@cvs.openbsd.org> | 2009-03-10 20:36:11 +0000 |
---|---|---|
committer | Jordan Hargrave <jordan@cvs.openbsd.org> | 2009-03-10 20:36:11 +0000 |
commit | e19d662685b8911900a8d769a933f7d40013f712 (patch) | |
tree | 2bbc6a25df8866cd6393bd0b66e005d450429465 /sys/dev/acpi/acpithinkpad.c | |
parent | e023a0dc8509fb134ba3371635dd853127f9c19c (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.c | 77 |
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; |