diff options
author | jhb <jhb@FreeBSD.org> | 2001-01-05 07:07:03 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-01-05 07:07:03 +0000 |
commit | a7d7562a9162219c57926fa90b34aad990222b7b (patch) | |
tree | a781c6152b088c4b5e148f084177a1b37ba8aa70 /sys/dev/sound/pcm/mixer.c | |
parent | c89c5ac184c8121ba8c76a673fa9099c1540dcdf (diff) | |
download | FreeBSD-src-a7d7562a9162219c57926fa90b34aad990222b7b.zip FreeBSD-src-a7d7562a9162219c57926fa90b34aad990222b7b.tar.gz |
- Make the 'hwvol_mixer' and 'hwvol_step' variables be specific to a
specific snd_mixer device rather than global across all mixers.
- Add per-mixer mute status and saved mute_level so that the mixer_hwmute()
function can now toggle the mute state when the mute button is pressed.
- Create a dynamic sysctl tree hw.snd.pcmX when a pcm device is registered.
- Move the hw.snd.hwvol_* sysctl's to hw.snd.pcmX.hwvol_* so that they
are now properly device-specific. Eventually when the mixers become
their own devices these sysctl's will move to live under a mixerX tree.
- Change the interface of the hwvol_mixer sysctl so that it reports the
name of the current mixer device instead of the number and is settable
with the name instead of the number.
- Add a new function mixer_hwinit() used to setup the dynamic sysctl's
needed for the hwvol support that can be called by drivers that support
hwvol.
Reviewed by: cg
Diffstat (limited to 'sys/dev/sound/pcm/mixer.c')
-rw-r--r-- | sys/dev/sound/pcm/mixer.c | 75 |
1 files changed, 66 insertions, 9 deletions
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c index b8bbef7..c9d4ae8 100644 --- a/sys/dev/sound/pcm/mixer.c +++ b/sys/dev/sound/pcm/mixer.c @@ -48,6 +48,20 @@ static u_int16_t snd_mixerdefaults[SOUND_MIXER_NRDEVICES] = { [SOUND_MIXER_OGAIN] = 50, }; +static char* snd_mixernames[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; + +static int +mixer_lookup(char *devname) +{ + int i; + + for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) + if (strncmp(devname, snd_mixernames[i], + strlen(snd_mixernames[i])) == 0) + return i; + return -1; +} + static int mixer_set(snd_mixer *mixer, unsigned dev, unsigned lev) { @@ -254,39 +268,82 @@ mixer_ioctl(snddev_info *d, u_long cmd, caddr_t arg) return ENXIO; } -static int hwvol_step = 5; -SYSCTL_INT(_hw_snd, OID_AUTO, hwvol_step, CTLFLAG_RW, &hwvol_step, 0, ""); +static int +sysctl_hw_snd_hwvol_mixer(SYSCTL_HANDLER_ARGS) +{ + char devname[32]; + int error, dev; + snd_mixer *m; + + m = oidp->oid_arg1; + strncpy(devname, snd_mixernames[m->hwvol_mixer], sizeof(devname)); + error = sysctl_handle_string(oidp, &devname[0], sizeof(devname), req); + if (error == 0 && req->newptr != NULL) { + dev = mixer_lookup(devname); + if (dev == -1) + return EINVAL; + else + m->hwvol_mixer = dev; + } + return error; +} + +int +mixer_hwinit(device_t dev) +{ + snddev_info *d; + snd_mixer *m; -static int hwvol_mixer = SOUND_MIXER_VOLUME; -SYSCTL_INT(_hw_snd, OID_AUTO, hwvol_mixer, CTLFLAG_RW, &hwvol_mixer, 0, ""); + d = device_get_softc(dev); + m = d->mixer; + m->hwvol_mixer = SOUND_MIXER_VOLUME; + m->hwvol_step = 5; + SYSCTL_ADD_INT(&d->sysctl_tree, SYSCTL_CHILDREN(d->sysctl_tree_top), + OID_AUTO, "hwvol_step", CTLFLAG_RW, &m->hwvol_step, 0, ""); + SYSCTL_ADD_PROC(&d->sysctl_tree, SYSCTL_CHILDREN(d->sysctl_tree_top), + OID_AUTO, "hwvol_mixer", CTLTYPE_STRING | CTLFLAG_RW, m, 0, + sysctl_hw_snd_hwvol_mixer, "A", "") + return 0; +} void mixer_hwmute(device_t dev) { snddev_info *d; + snd_mixer *m; d = device_get_softc(dev); - mixer_set(d->mixer, hwvol_mixer, 0); + m = d->mixer; + if (m->muted) { + m->muted = 0; + mixer_set(m, m->hwvol_mixer, m->mute_level); + } else { + m->muted++; + m->mute_level = mixer_get(m, m->hwvol_mixer); + mixer_set(m, m->hwvol_mixer, 0); + } } void mixer_hwstep(device_t dev, int left_step, int right_step) { snddev_info *d; + snd_mixer *m; int level, left, right; d = device_get_softc(dev); - level = mixer_get(d->mixer, hwvol_mixer); + m = d->mixer; + level = mixer_get(m, m->hwvol_mixer); if (level != -1) { left = level & 0xff; right = level >> 8; - left += left_step * hwvol_step; + left += left_step * m->hwvol_step; if (left < 0) left = 0; - right += right_step * hwvol_step; + right += right_step * m->hwvol_step; if (right < 0) right = 0; - mixer_set(d->mixer, hwvol_mixer, left | right << 8); + mixer_set(m, m->hwvol_mixer, left | right << 8); } } |