I like this *MUCH* better than the way acpithinkpad volume buttons currently work. these buttons should be affecting the mixer, if at all possible, instead of doing things "behind the audio system's back", which causes confusion.
On Sun, Mar 13, 2011 at 10:11:54PM +0300, Alexander Polakov wrote: > 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 -- jake...@sdf.lonestar.org SDF Public Access UNIX System - http://sdf.lonestar.org