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