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

Reply via email to