Hi, This is a diff to add support for "mute microphone" key, which can be found on some thinkpad models, which is currently reported as
acpithinkpad0: unknown event 0x101b A simple solution would be just add definition to acpithinkpad.c and set handled to 1, but I chose a bit harder way of adding proper support. My attempt below. Index: sys/dev/audio.c =================================================================== RCS file: /cvs/src/sys/dev/audio.c,v retrieving revision 1.111 diff -u -r1.111 audio.c --- sys/dev/audio.c 18 Nov 2010 21:15:14 -0000 1.111 +++ sys/dev/audio.c 13 Mar 2011 19:10:19 -0000 @@ -244,7 +244,7 @@ #if NWSKBD > 0 /* Mixer manipulation using keyboard */ -int wskbd_set_mixervolume(long); +int wskbd_set_mixervolume(long, int); #endif int @@ -3358,20 +3358,23 @@ #if NWSKBD > 0 int -wskbd_set_mixervolume(long dir) +wskbd_set_mixervolume(long dir, int out) { struct audio_softc *sc; mixer_devinfo_t mi; int error; u_int gain; u_char balance, mute; + struct au_mixer_ports *ports; if (audio_cd.cd_ndevs == 0 || (sc = audio_cd.cd_devs[0]) == NULL) { DPRINTF(("wskbd_set_mixervolume: audio_cd\n")); return (ENXIO); } - if (sc->sc_outports.master == -1) { + ports = out ? &sc->sc_outports : &sc->sc_inports; + + if (ports->master == -1) { DPRINTF(("wskbd_set_mixervolume: master == -1\n")); return (ENXIO); } @@ -3379,7 +3382,7 @@ if (dir == 0) { /* Mute */ - error = au_get_mute(sc, &sc->sc_outports, &mute); + error = au_get_mute(sc, ports, &mute); if (error != 0) { DPRINTF(("wskbd_set_mixervolume:" " au_get_mute: %d\n", error)); @@ -3388,7 +3391,7 @@ mute = !mute; - error = au_set_mute(sc, &sc->sc_outports, mute); + error = au_set_mute(sc, ports, mute); if (error != 0) { DPRINTF(("wskbd_set_mixervolume:" " au_set_mute: %d\n", error)); @@ -3397,7 +3400,7 @@ } else { /* Raise or lower volume */ - mi.index = sc->sc_outports.master; + mi.index = ports->master; error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi); if (error != 0) { DPRINTF(("wskbd_set_mixervolume:" @@ -3405,14 +3408,14 @@ return (error); } - au_get_gain(sc, &sc->sc_outports, &gain, &balance); + au_get_gain(sc, ports, &gain, &balance); if (dir > 0) gain += mi.un.v.delta; else gain -= mi.un.v.delta; - error = au_set_gain(sc, &sc->sc_outports, gain, balance); + error = au_set_gain(sc, ports, gain, balance); if (error != 0) { DPRINTF(("wskbd_set_mixervolume:" " au_set_gain: %d\n", error)); Index: sys/dev/acpi/acpiasus.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpiasus.c,v retrieving revision 1.11 diff -u -r1.11 acpiasus.c --- sys/dev/acpi/acpiasus.c 28 Aug 2010 17:59:17 -0000 1.11 +++ sys/dev/acpi/acpiasus.c 13 Mar 2011 19:10:19 -0000 @@ -90,7 +90,7 @@ int acpiasus_activate(struct device *, int); #if NAUDIO > 0 && NWSKBD > 0 -extern int wskbd_set_mixervolume(long dir); +extern int wskbd_set_mixervolume(long dir, int out); #endif struct cfattach acpiasus_ca = { @@ -173,15 +173,15 @@ #if NAUDIO > 0 && NWSKBD > 0 case ASUS_NOTIFY_VOLUMEMUTE: workq_add_task(NULL, 0, (workq_fn)wskbd_set_mixervolume, - (void *)(long)0, NULL); + (void *)(long)0, (void *)(int)1); break; case ASUS_NOTIFY_VOLUMEDOWN: workq_add_task(NULL, 0, (workq_fn)wskbd_set_mixervolume, - (void *)(long)-1, NULL); + (void *)(long)-1, (void *)(int)1); break; case ASUS_NOTIFY_VOLUMEUP: workq_add_task(NULL, 0, (workq_fn)wskbd_set_mixervolume, - (void *)(long)1, NULL); + (void *)(long)1, (void *)(int)1); break; #else case ASUS_NOTIFY_VOLUMEMUTE: Index: sys/dev/acpi/acpithinkpad.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/acpithinkpad.c,v retrieving revision 1.25 diff -u -r1.25 acpithinkpad.c --- sys/dev/acpi/acpithinkpad.c 2 Jan 2011 04:56:57 -0000 1.25 +++ sys/dev/acpi/acpithinkpad.c 13 Mar 2011 19:10:19 -0000 @@ -18,6 +18,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> +#include <sys/workq.h> #include <dev/acpi/acpireg.h> #include <dev/acpi/acpivar.h> @@ -27,6 +28,9 @@ #include <machine/apmvar.h> +#include "audio.h" +#include "wskbd.h" + #define THINKPAD_HKEY_VERSION 0x0100 #define THINKPAD_CMOS_VOLUME_DOWN 0x00 @@ -59,6 +63,7 @@ #define THINKPAD_BUTTON_VOLUME_DOWN 0x1016 #define THINKPAD_BUTTON_VOLUME_MUTE 0x1017 #define THINKPAD_BUTTON_THINKVANTAGE 0x1018 +#define THINKPAD_BUTTON_MICROPHONE_MUTE 0x101b #define THINKPAD_BUTTON_FN_F11 0x100b #define THINKPAD_BUTTON_HIBERNATE 0x100c #define THINKPAD_LID_OPEN 0x5001 @@ -106,6 +111,10 @@ void thinkpad_sensor_attach(struct acpithinkpad_softc *sc); void thinkpad_sensor_refresh(void *); +#if NAUDIO > 0 && NWSKBD > 0 +extern int wskbd_set_mixervolume(long dir, int out); +#endif + struct cfattach acpithinkpad_ca = { sizeof(struct acpithinkpad_softc), thinkpad_match, thinkpad_attach }; @@ -311,6 +320,13 @@ break; case THINKPAD_BUTTON_VOLUME_UP: thinkpad_volume_up(sc); + handled = 1; + break; + case THINKPAD_BUTTON_MICROPHONE_MUTE: +#if NAUDIO > 0 && NWSKBD > 0 + workq_add_task(NULL, 0, (workq_fn)wskbd_set_mixervolume, + (void *)(long)0, (void *)(int)0); +#endif handled = 1; break; case THINKPAD_BUTTON_THINKVANTAGE: Index: sys/dev/wscons/wskbd.c =================================================================== RCS file: /cvs/src/sys/dev/wscons/wskbd.c,v retrieving revision 1.64 diff -u -r1.64 wskbd.c --- sys/dev/wscons/wskbd.c 20 Nov 2010 20:52:11 -0000 1.64 +++ sys/dev/wscons/wskbd.c 13 Mar 2011 19:10:19 -0000 @@ -299,7 +299,7 @@ void wskbd_update_layout(struct wskbd_internal *, kbd_t); #if NAUDIO > 0 -extern int wskbd_set_mixervolume(long dir); +extern int wskbd_set_mixervolume(long dir, int out); #endif void @@ -1650,15 +1650,15 @@ #if NAUDIO > 0 case KS_AudioMute: workq_add_task(NULL, 0, (workq_fn)wskbd_set_mixervolume, - (void *)(long)0, NULL); + (void *)(long)0, (void *)(int)1); break; case KS_AudioLower: workq_add_task(NULL, 0, (workq_fn)wskbd_set_mixervolume, - (void *)(long)-1, NULL); + (void *)(long)-1, (void*)(int)1); break; case KS_AudioRaise: workq_add_task(NULL, 0, (workq_fn)wskbd_set_mixervolume, - (void *)(long)1, NULL); + (void *)(long)1, (void*)(int)1); return (0); #endif default: -- Alexander Polakov | plhk.ru