Date: Thu, 7 Feb 2013 08:20:04 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r246454 - in head/sys/dev/sound: pcm usb Message-ID: <201302070820.r178K4P0067706@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Thu Feb 7 08:20:03 2013 New Revision: 246454 URL: http://svnweb.freebsd.org/changeset/base/246454 Log: Add support for mute buttons on USB audio devices and use the hwvol interface to adjust the mixer settings. MFC after: 1 week Modified: head/sys/dev/sound/pcm/mixer.c head/sys/dev/sound/pcm/mixer.h head/sys/dev/sound/usb/uaudio.c Modified: head/sys/dev/sound/pcm/mixer.c ============================================================================== --- head/sys/dev/sound/pcm/mixer.c Thu Feb 7 07:50:16 2013 (r246453) +++ head/sys/dev/sound/pcm/mixer.c Thu Feb 7 08:20:03 2013 (r246454) @@ -893,14 +893,8 @@ mixer_hwvol_init(device_t dev) } void -mixer_hwvol_mute(device_t dev) +mixer_hwvol_mute_locked(struct snd_mixer *m) { - struct snd_mixer *m; - struct cdev *pdev; - - pdev = mixer_get_devt(dev); - m = pdev->si_drv1; - snd_mtxlock(m->lock); if (m->hwvol_muted) { m->hwvol_muted = 0; mixer_set(m, m->hwvol_mixer, m->hwvol_mute_level); @@ -909,19 +903,26 @@ mixer_hwvol_mute(device_t dev) m->hwvol_mute_level = mixer_get(m, m->hwvol_mixer); mixer_set(m, m->hwvol_mixer, 0); } - snd_mtxunlock(m->lock); } void -mixer_hwvol_step(device_t dev, int left_step, int right_step) +mixer_hwvol_mute(device_t dev) { struct snd_mixer *m; - int level, left, right; struct cdev *pdev; pdev = mixer_get_devt(dev); m = pdev->si_drv1; snd_mtxlock(m->lock); + mixer_hwvol_mute_locked(m); + snd_mtxunlock(m->lock); +} + +void +mixer_hwvol_step_locked(struct snd_mixer *m, int left_step, int right_step) +{ + int level, left, right; + if (m->hwvol_muted) { m->hwvol_muted = 0; level = m->hwvol_mute_level; @@ -929,15 +930,31 @@ mixer_hwvol_step(device_t dev, int left_ level = mixer_get(m, m->hwvol_mixer); if (level != -1) { left = level & 0xff; - right = level >> 8; + right = (level >> 8) & 0xff; left += left_step * m->hwvol_step; if (left < 0) left = 0; + else if (left > 100) + left = 100; right += right_step * m->hwvol_step; if (right < 0) right = 0; + else if (right > 100) + right = 100; mixer_set(m, m->hwvol_mixer, left | right << 8); } +} + +void +mixer_hwvol_step(device_t dev, int left_step, int right_step) +{ + struct snd_mixer *m; + struct cdev *pdev; + + pdev = mixer_get_devt(dev); + m = pdev->si_drv1; + snd_mtxlock(m->lock); + mixer_hwvol_step_locked(m, left_step, right_step); snd_mtxunlock(m->lock); } Modified: head/sys/dev/sound/pcm/mixer.h ============================================================================== --- head/sys/dev/sound/pcm/mixer.h Thu Feb 7 07:50:16 2013 (r246453) +++ head/sys/dev/sound/pcm/mixer.h Thu Feb 7 08:20:03 2013 (r246454) @@ -40,7 +40,9 @@ int mixer_ioctl_cmd(struct cdev *i_dev, int mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi); int mixer_hwvol_init(device_t dev); +void mixer_hwvol_mute_locked(struct snd_mixer *m); void mixer_hwvol_mute(device_t dev); +void mixer_hwvol_step_locked(struct snd_mixer *m, int l_step, int r_step); void mixer_hwvol_step(device_t dev, int left_step, int right_step); int mixer_busy(struct snd_mixer *m); Modified: head/sys/dev/sound/usb/uaudio.c ============================================================================== --- head/sys/dev/sound/usb/uaudio.c Thu Feb 7 07:50:16 2013 (r246453) +++ head/sys/dev/sound/usb/uaudio.c Thu Feb 7 08:20:03 2013 (r246454) @@ -287,14 +287,17 @@ struct uaudio_hid { struct usb_xfer *xfer[UAUDIO_HID_N_TRANSFER]; struct hid_location volume_up_loc; struct hid_location volume_down_loc; + struct hid_location mute_loc; uint32_t flags; #define UAUDIO_HID_VALID 0x0001 #define UAUDIO_HID_HAS_ID 0x0002 #define UAUDIO_HID_HAS_VOLUME_UP 0x0004 #define UAUDIO_HID_HAS_VOLUME_DOWN 0x0008 +#define UAUDIO_HID_HAS_MUTE 0x0010 uint8_t iface_index; uint8_t volume_up_id; uint8_t volume_down_id; + uint8_t mute_id; }; struct uaudio_softc { @@ -1012,6 +1015,8 @@ uaudio_attach_sub(device_t dev, kobj_cla goto detach; sc->sc_mixer_init = 1; + mixer_hwvol_init(dev); + snprintf(status, sizeof(status), "at ? %s", PCM_KLDSTRING(snd_uaudio)); if (pcm_register(dev, sc, @@ -5520,9 +5525,6 @@ uaudio_hid_rx_callback(struct usb_xfer * struct uaudio_softc *sc = usbd_xfer_softc(xfer); const uint8_t *buffer = usbd_xfer_get_frame_buffer(xfer, 0); struct snd_mixer *m; - int v; - int v_l; - int v_r; uint8_t id; int actlen; @@ -5543,6 +5545,16 @@ uaudio_hid_rx_callback(struct usb_xfer * m = sc->sc_mixer_dev; + if ((sc->sc_hid.flags & UAUDIO_HID_HAS_MUTE) && + (sc->sc_hid.mute_id == id) && + hid_get_data(buffer, actlen, + &sc->sc_hid.mute_loc)) { + + DPRINTF("Mute toggle\n"); + + mixer_hwvol_mute_locked(m); + } + if ((sc->sc_hid.flags & UAUDIO_HID_HAS_VOLUME_UP) && (sc->sc_hid.volume_up_id == id) && hid_get_data(buffer, actlen, @@ -5550,13 +5562,7 @@ uaudio_hid_rx_callback(struct usb_xfer * DPRINTF("Volume Up\n"); - v = mix_get_locked(m, SOUND_MIXER_PCM, &v_l, &v_r); - if (v == 0) { - v = ((v_l + v_r) / 2) + 5; - if (v > 100) - v = 100; - mix_set_locked(m, SOUND_MIXER_PCM, v, v); - } + mixer_hwvol_step_locked(m, 1, 1); } if ((sc->sc_hid.flags & UAUDIO_HID_HAS_VOLUME_DOWN) && @@ -5566,13 +5572,7 @@ uaudio_hid_rx_callback(struct usb_xfer * DPRINTF("Volume Down\n"); - v = mix_get_locked(m, SOUND_MIXER_PCM, &v_l, &v_r); - if (v == 0) { - v = ((v_l + v_r) / 2) - 5; - if (v < 0) - v = 0; - mix_set_locked(m, SOUND_MIXER_PCM, v, v); - } + mixer_hwvol_step_locked(m, -1, -1); } case USB_ST_SETUP: @@ -5641,10 +5641,20 @@ uaudio_hid_probe(struct uaudio_softc *sc DPRINTFN(1, "Found Volume Down key\n"); } + if (hid_locate(d_ptr, d_len, + HID_USAGE2(HUP_CONSUMER, 0xE2 /* Mute */), + hid_input, 0, &sc->sc_hid.mute_loc, &flags, + &sc->sc_hid.mute_id)) { + if (flags & HIO_VARIABLE) + sc->sc_hid.flags |= UAUDIO_HID_HAS_MUTE; + DPRINTFN(1, "Found Mute key\n"); + } + free(d_ptr, M_TEMP); if (!(sc->sc_hid.flags & (UAUDIO_HID_HAS_VOLUME_UP | - UAUDIO_HID_HAS_VOLUME_DOWN))) { + UAUDIO_HID_HAS_VOLUME_DOWN | + UAUDIO_HID_HAS_MUTE))) { DPRINTFN(1, "Did not find any volume related keys\n"); return (-1); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302070820.r178K4P0067706>