svn commit: r246454 - in head/sys/dev/sound: pcm usb
Hans Petter Selasky
hselasky at FreeBSD.org
Thu Feb 7 08:20:04 UTC 2013
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);
}
More information about the svn-src-head
mailing list