diff options
author | joshua stein <jcs@cvs.openbsd.org> | 2008-05-14 02:02:06 +0000 |
---|---|---|
committer | joshua stein <jcs@cvs.openbsd.org> | 2008-05-14 02:02:06 +0000 |
commit | 0677585573a0200ea4a3039561de3b057dd2d526 (patch) | |
tree | 6590a40c69c877589f00dc9c137f633be6b50be0 /sys/dev/acpi/acpithinkpad.c | |
parent | 6e1e877d6f62924be199fa22500c3638e84b5ada (diff) |
recognize some more events
hook up the volume keys to actually do stuff; from Stefan Kempf
use aml_freevalue to properly free memory in all cases; prodded by
deanna
Diffstat (limited to 'sys/dev/acpi/acpithinkpad.c')
-rw-r--r-- | sys/dev/acpi/acpithinkpad.c | 90 |
1 files changed, 82 insertions, 8 deletions
diff --git a/sys/dev/acpi/acpithinkpad.c b/sys/dev/acpi/acpithinkpad.c index 47066f53579..a434bcff06b 100644 --- a/sys/dev/acpi/acpithinkpad.c +++ b/sys/dev/acpi/acpithinkpad.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpithinkpad.c,v 1.1 2008/04/27 16:23:16 jcs Exp $ */ +/* $OpenBSD: acpithinkpad.c,v 1.2 2008/05/14 02:02:05 jcs Exp $ */ /* * Copyright (c) 2008 joshua stein <jcs@openbsd.org> @@ -27,6 +27,9 @@ #define THINKPAD_HKEY_VERSION 0x0100 +#define THINKPAD_CMOS_VOLUME_DOWN 0x00 +#define THINKPAD_CMOS_VOLUME_UP 0x01 +#define THINKPAD_CMOS_VOLUME_MUTE 0x02 #define THINKPAD_CMOS_BRIGHTNESS_UP 0x04 #define THINKPAD_CMOS_BRIGHTNESS_DOWN 0x05 @@ -51,6 +54,9 @@ #define THINKPAD_BUTTON_BRIGHTNESS_DOWN 0x011 #define THINKPAD_BUTTON_THINKLIGHT 0x012 #define THINKPAD_BUTTON_FN_SPACE 0x014 +#define THINKPAD_BUTTON_VOLUME_UP 0x015 +#define THINKPAD_BUTTON_VOLUME_DOWN 0x016 +#define THINKPAD_BUTTON_VOLUME_MUTE 0x017 #define THINKPAD_BUTTON_THINKVANTAGE 0x018 #define THINKPAD_BUTTON_FN_F11 0x00b #define THINKPAD_BUTTON_HIBERNATE 0x00c @@ -63,6 +69,9 @@ #define THINKPAD_TABLET_PEN_INSERTED 0x00b #define THINKPAD_TABLET_PEN_REMOVED 0x00c +/* type 7 events */ +#define THINKPAD_SWITCH_WIRELESS 0x000 + struct acpithinkpad_softc { struct device sc_dev; @@ -77,6 +86,9 @@ int thinkpad_enable_events(struct acpithinkpad_softc *); int thinkpad_toggle_bluetooth(struct acpithinkpad_softc *); int thinkpad_toggle_wan(struct acpithinkpad_softc *); int thinkpad_cmos(struct acpithinkpad_softc *sc, uint8_t); +int thinkpad_volume_down(struct acpithinkpad_softc *); +int thinkpad_volume_up(struct acpithinkpad_softc *); +int thinkpad_volume_mute(struct acpithinkpad_softc *); int thinkpad_brightness_up(struct acpithinkpad_softc *); int thinkpad_brightness_down(struct acpithinkpad_softc *); @@ -107,6 +119,7 @@ thinkpad_match(struct device *parent, void *match, void *aux) if (aml_val2int(&res) != THINKPAD_HKEY_VERSION) goto fail; + aml_freevalue(&res); return (1); fail: @@ -118,7 +131,7 @@ void thinkpad_attach(struct device *parent, struct device *self, void *aux) { struct acpithinkpad_softc *sc = (struct acpithinkpad_softc *)self; - struct acpi_attach_args *aa = aux; + struct acpi_attach_args *aa = aux; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_devnode = aa->aaa_node->child; @@ -145,8 +158,7 @@ thinkpad_enable_events(struct acpithinkpad_softc *sc) /* get the supported event mask */ if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "MHKA", 0, NULL, &res)) { printf("%s: no MHKA\n", DEVNAME(sc)); - aml_freevalue(&res); - return (1); + goto fail; } mask = aml_val2int(&res); @@ -160,7 +172,7 @@ thinkpad_enable_events(struct acpithinkpad_softc *sc) if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "MHKM", 2, args, NULL)) { printf("%s: couldn't toggle MHKM\n", DEVNAME(sc)); - return (1); + goto fail; } } @@ -170,10 +182,24 @@ thinkpad_enable_events(struct acpithinkpad_softc *sc) arg.v_integer = 1; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "MHKC", 1, &arg, NULL)) { printf("%s: couldn't enable hotkeys\n", DEVNAME(sc)); - return (1); + goto fail; } + aml_freevalue(&res); + aml_freevalue(&args[0]); + aml_freevalue(&args[1]); + aml_freevalue(&args[2]); + aml_freevalue(&arg); + return (0); + +fail: + aml_freevalue(&res); + aml_freevalue(&args[0]); + aml_freevalue(&args[1]); + aml_freevalue(&args[2]); + aml_freevalue(&arg); + return (1); } int @@ -191,6 +217,7 @@ thinkpad_hotkey(struct aml_node *node, int notify_type, void *arg) } val = aml_val2int(&res); + aml_freevalue(&res); if (val == 0) return (1); @@ -230,9 +257,22 @@ thinkpad_hotkey(struct aml_node *node, int notify_type, void *arg) case THINKPAD_BUTTON_EJECT: case THINKPAD_BUTTON_THINKLIGHT: case THINKPAD_BUTTON_FN_SPACE: + handled = 1; + break; + case THINKPAD_BUTTON_VOLUME_DOWN: + thinkpad_volume_down(sc); + handled = 1; + break; + case THINKPAD_BUTTON_VOLUME_UP: + thinkpad_volume_up(sc); + handled = 1; + break; + case THINKPAD_BUTTON_VOLUME_MUTE: + thinkpad_volume_mute(sc); + handled = 1; + break; case THINKPAD_BUTTON_THINKVANTAGE: case THINKPAD_BUTTON_FN_F11: - /* TODO: notify userland */ handled = 1; break; } @@ -246,12 +286,19 @@ thinkpad_hotkey(struct aml_node *node, int notify_type, void *arg) case THINKPAD_LID_CLOSED: case THINKPAD_TABLET_PEN_INSERTED: case THINKPAD_TABLET_PEN_REMOVED: - /* TODO: notify userland */ handled = 1; break; } break; + case 7: + switch (event) { + case THINKPAD_SWITCH_WIRELESS: + handled = 1; + + break; + } + break; } if (!handled) @@ -282,9 +329,12 @@ thinkpad_toggle_bluetooth(struct acpithinkpad_softc *sc) arg.v_integer = bluetooth ^= THINKPAD_BLUETOOTH_ENABLED; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "SBDC", 1, &arg, NULL)) { printf("%s: couldn't toggle bluetooth\n", DEVNAME(sc)); + aml_freevalue(&arg); return (1); } + aml_freevalue(&arg); + return (0); } @@ -309,9 +359,12 @@ thinkpad_toggle_wan(struct acpithinkpad_softc *sc) arg.v_integer = wan ^= THINKPAD_WAN_ENABLED; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "SWAN", 1, &arg, NULL)) { printf("%s: couldn't toggle wan\n", DEVNAME(sc)); + aml_freevalue(&arg); return (1); } + aml_freevalue(&arg); + return (0); } @@ -327,13 +380,34 @@ thinkpad_cmos(struct acpithinkpad_softc *sc, uint8_t cmd) if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "\\UCMS", 1, &arg, NULL)) { printf("%s: cmos command 0x%x failed\n", DEVNAME(sc), cmd); + aml_freevalue(&arg); return (1); } + aml_freevalue(&arg); + return (0); } int +thinkpad_volume_down(struct acpithinkpad_softc *sc) +{ + return thinkpad_cmos(sc, THINKPAD_CMOS_VOLUME_DOWN); +} + +int +thinkpad_volume_up(struct acpithinkpad_softc *sc) +{ + return thinkpad_cmos(sc, THINKPAD_CMOS_VOLUME_UP); +} + +int +thinkpad_volume_mute(struct acpithinkpad_softc *sc) +{ + return thinkpad_cmos(sc, THINKPAD_CMOS_VOLUME_MUTE); +} + +int thinkpad_brightness_up(struct acpithinkpad_softc *sc) { return thinkpad_cmos(sc, THINKPAD_CMOS_BRIGHTNESS_UP); |