From 7d7b0e490bd226ab07e62d86710dae583d063b13 Mon Sep 17 00:00:00 2001 From: anton Date: Wed, 16 Feb 2022 06:23:42 +0000 Subject: [PATCH] Currently, wskbd_set_mixervolume() only adjusts the volume of the first attached audio device, i.e. audio0. This approach does not work well while using additional audio devices equipped with physical volume keys since those would only affect the volume of audio0. Instead, correlate audio and ucc devices attached over USB in order to adjust the volume of the correct audio device. This is done by passing a cookie from the common point of attachment which is later used to correlate the audio and wskbd device. The same approach could be adopted for audio and wskbd devices attaching on a different bus. Keep in mind that it's of importance to make use of and increment the same global cookie identifier to avoid collisions. Makes the volume keys on my Logitech G435 Headset do the right thing. ok ratchov@ --- sys/dev/audio.c | 45 +++++++++++++++++++++++++++++++++------ sys/dev/usb/uaudio.c | 4 ++-- sys/dev/usb/ucc.c | 9 ++++---- sys/dev/usb/usb_subr.c | 8 ++++++- sys/dev/usb/usbdi.h | 3 ++- sys/dev/wscons/wskbd.c | 18 +++++++++++----- sys/dev/wscons/wskbdvar.h | 4 +++- 7 files changed, 71 insertions(+), 20 deletions(-) diff --git a/sys/dev/audio.c b/sys/dev/audio.c index 856a88bae98..d5bf6750d48 100644 --- a/sys/dev/audio.c +++ b/sys/dev/audio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: audio.c,v 1.195 2022/02/16 06:21:18 anton Exp $ */ +/* $OpenBSD: audio.c,v 1.196 2022/02/16 06:23:42 anton Exp $ */ /* * Copyright (c) 2015 Alexandre Ratchov * @@ -96,6 +96,8 @@ struct wskbd_vol #define WSKBD_MUTE_DISABLE 2 #define WSKBD_MUTE_ENABLE 3 }; + +int wskbd_set_mixervolume_unit(int, long, long); #endif /* @@ -2455,10 +2457,6 @@ wskbd_mixer_init(struct audio_softc *sc) }; int i; - if (sc->dev.dv_unit != 0) { - DPRINTF("%s: not configuring wskbd keys\n", DEVNAME(sc)); - return; - } for (i = 0; i < sizeof(spkr_names) / sizeof(spkr_names[0]); i++) { if (wskbd_initvol(sc, &sc->spkr, spkr_names[i].cn, spkr_names[i].dn)) @@ -2569,13 +2567,48 @@ wskbd_set_mixermute(long mute, long out) return 0; } +/* + * Adjust the volume of the audio device associated with the given cookie. + * Otherwise, fallback to audio0. + */ +int +wskbd_set_mixervolume_dev(void *cookie, long dir, long out) +{ + int unit = 0; + int i; + + for (i = 0; i < audio_cd.cd_ndevs; i++) { + struct audio_softc *sc; + + sc = (struct audio_softc *)device_lookup(&audio_cd, i); + if (sc == NULL) + continue; + if (sc->cookie != cookie) { + device_unref(&sc->dev); + continue; + } + + device_unref(&sc->dev); + unit = i; + break; + } + + return wskbd_set_mixervolume_unit(unit, dir, out); +} + int wskbd_set_mixervolume(long dir, long out) +{ + return wskbd_set_mixervolume_unit(0, dir, out); +} + +int +wskbd_set_mixervolume_unit(int unit, long dir, long out) { struct audio_softc *sc; struct wskbd_vol *vol; - sc = (struct audio_softc *)device_lookup(&audio_cd, 0); + sc = (struct audio_softc *)device_lookup(&audio_cd, unit); if (sc == NULL) return ENODEV; vol = out ? &sc->spkr : &sc->mic; diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index f7afca68c8c..c37866f061f 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uaudio.c,v 1.166 2022/02/16 06:21:19 anton Exp $ */ +/* $OpenBSD: uaudio.c,v 1.167 2022/02/16 06:23:42 anton Exp $ */ /* * Copyright (c) 2018 Alexandre Ratchov * @@ -3841,7 +3841,7 @@ uaudio_attach(struct device *parent, struct device *self, void *aux) /* print a nice uaudio attach line */ uaudio_print(sc); - audio_attach_mi(&uaudio_hw_if, sc, NULL, &sc->dev); + audio_attach_mi(&uaudio_hw_if, sc, arg->cookie, &sc->dev); } int diff --git a/sys/dev/usb/ucc.c b/sys/dev/usb/ucc.c index f23f32990bb..c37d703ff89 100644 --- a/sys/dev/usb/ucc.c +++ b/sys/dev/usb/ucc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ucc.c,v 1.29 2022/01/09 05:43:00 jsg Exp $ */ +/* $OpenBSD: ucc.c,v 1.30 2022/02/16 06:23:42 anton Exp $ */ /* * Copyright (c) 2021 Anton Lindqvist @@ -104,7 +104,7 @@ void ucc_attach(struct device *, struct device *, void *); int ucc_detach(struct device *, int); void ucc_intr(struct uhidev *, void *, u_int); -void ucc_attach_wskbd(struct ucc_softc *); +void ucc_attach_wskbd(struct ucc_softc *, void *); int ucc_enable(void *, int); void ucc_set_leds(void *, int); int ucc_ioctl(void *, u_long, caddr_t, int, struct proc *); @@ -680,7 +680,7 @@ ucc_attach(struct device *parent, struct device *self, void *aux) /* Cannot load an empty map. */ if (sc->sc_maplen > 0) - ucc_attach_wskbd(sc); + ucc_attach_wskbd(sc, uha->uaa->cookie); } int @@ -772,7 +772,7 @@ unknown: } void -ucc_attach_wskbd(struct ucc_softc *sc) +ucc_attach_wskbd(struct ucc_softc *sc, void *cookie) { static const struct wskbd_accessops accessops = { .enable = ucc_enable, @@ -784,6 +784,7 @@ ucc_attach_wskbd(struct ucc_softc *sc) .keymap = &sc->sc_keymap, .accessops = &accessops, .accesscookie = sc, + .audiocookie = cookie, }; sc->sc_keydesc[0].name = KB_US; diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 7d8480f0f01..9cbbf7f0368 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: usb_subr.c,v 1.157 2022/01/09 05:43:02 jsg Exp $ */ +/* $OpenBSD: usb_subr.c,v 1.158 2022/02/16 06:23:42 anton Exp $ */ /* $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */ @@ -839,6 +839,11 @@ usbd_status usbd_probe_and_attach(struct device *parent, struct usbd_device *dev, int port, int addr) { + /* + * Used to correlate audio and wskbd devices as this is the common point + * of attachment between the two. + */ + static char *cookie = 0; struct usb_attach_arg uaa; usb_device_descriptor_t *dd = &dev->ddesc; int i, confi, nifaces; @@ -860,6 +865,7 @@ usbd_probe_and_attach(struct device *parent, struct usbd_device *dev, int port, uaa.vendor = UGETW(dd->idVendor); uaa.product = UGETW(dd->idProduct); uaa.release = UGETW(dd->bcdDevice); + uaa.cookie = ++cookie; /* First try with device specific drivers. */ DPRINTF(("usbd_probe_and_attach trying device specific drivers\n")); diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 05209bcb809..030a6a5cdb6 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: usbdi.h,v 1.71 2021/02/01 09:21:51 mglocker Exp $ */ +/* $OpenBSD: usbdi.h,v 1.72 2022/02/16 06:23:42 anton Exp $ */ /* $NetBSD: usbdi.h,v 1.62 2002/07/11 21:14:35 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */ @@ -227,6 +227,7 @@ struct usb_attach_arg { int usegeneric; struct usbd_interface **ifaces;/* all interfaces */ int nifaces; /* number of interfaces */ + void *cookie; }; /* Match codes. */ diff --git a/sys/dev/wscons/wskbd.c b/sys/dev/wscons/wskbd.c index 5693a5b614e..0fb6ae6feac 100644 --- a/sys/dev/wscons/wskbd.c +++ b/sys/dev/wscons/wskbd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wskbd.c,v 1.110 2021/12/30 06:55:11 anton Exp $ */ +/* $OpenBSD: wskbd.c,v 1.111 2022/02/16 06:23:42 anton Exp $ */ /* $NetBSD: wskbd.c,v 1.80 2005/05/04 01:52:16 augustss Exp $ */ /* @@ -169,6 +169,10 @@ struct wskbd_softc { int sc_refcnt; u_char sc_dying; /* device is being detached */ + +#if NAUDIO > 0 + void *sc_audiocookie; +#endif }; #define MOD_SHIFT_L (1 << 0) @@ -307,7 +311,7 @@ static struct wskbd_internal wskbd_console_data; void wskbd_update_layout(struct wskbd_internal *, kbd_t); #if NAUDIO > 0 -extern int wskbd_set_mixervolume(long, long); +extern int wskbd_set_mixervolume_dev(void *, long, long); #endif void @@ -395,6 +399,10 @@ wskbd_attach(struct device *parent, struct device *self, void *aux) timeout_set(&sc->sc_repeat_ch, wskbd_repeat, sc); #endif +#if NAUDIO > 0 + sc->sc_audiocookie = ap->audiocookie; +#endif + sc->id->t_sc = sc; sc->sc_accessops = ap->accessops; @@ -1766,13 +1774,13 @@ wskbd_translate(struct wskbd_internal *id, u_int type, int value) switch (ksym) { #if NAUDIO > 0 case KS_AudioMute: - wskbd_set_mixervolume(0, 1); + wskbd_set_mixervolume_dev(sc->sc_audiocookie, 0, 1); return (0); case KS_AudioLower: - wskbd_set_mixervolume(-1, 1); + wskbd_set_mixervolume_dev(sc->sc_audiocookie, -1, 1); return (0); case KS_AudioRaise: - wskbd_set_mixervolume(1, 1); + wskbd_set_mixervolume_dev(sc->sc_audiocookie, 1, 1); return (0); #endif default: diff --git a/sys/dev/wscons/wskbdvar.h b/sys/dev/wscons/wskbdvar.h index 91bca39e30f..557a816c743 100644 --- a/sys/dev/wscons/wskbdvar.h +++ b/sys/dev/wscons/wskbdvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wskbdvar.h,v 1.3 2017/05/12 09:16:55 mpi Exp $ */ +/* $OpenBSD: wskbdvar.h,v 1.4 2022/02/16 06:23:42 anton Exp $ */ /* $NetBSD: wskbdvar.h,v 1.8 1999/12/01 23:22:59 augustss Exp $ */ /* @@ -71,6 +71,8 @@ struct wskbddev_attach_args { const struct wskbd_accessops *accessops; /* access ops */ void *accesscookie; /* access cookie */ + + void *audiocookie; }; #define WSKBDDEVCF_CONSOLE 0 -- 2.20.1