Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/sound/pcm/mixer.c
Show First 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | SYSCTL_INT(_hw_snd, OID_AUTO, vpc_mixer_bypass, CTLFLAG_RWTUN, | ||||
&mixer_bypass, 0, | &mixer_bypass, 0, | ||||
"control channel pcm/rec volume, bypassing real mixer device"); | "control channel pcm/rec volume, bypassing real mixer device"); | ||||
#define MIXER_NAMELEN 16 | #define MIXER_NAMELEN 16 | ||||
struct snd_mixer { | struct snd_mixer { | ||||
KOBJ_FIELDS; | KOBJ_FIELDS; | ||||
void *devinfo; | void *devinfo; | ||||
int busy; | int busy; | ||||
int hwvol_muted; | |||||
int hwvol_mixer; | int hwvol_mixer; | ||||
int hwvol_step; | int hwvol_step; | ||||
int type; | int type; | ||||
device_t dev; | device_t dev; | ||||
u_int32_t hwvol_mute_level; | |||||
u_int32_t devs; | u_int32_t devs; | ||||
u_int32_t mutedevs; | |||||
u_int32_t recdevs; | u_int32_t recdevs; | ||||
u_int32_t recsrc; | u_int32_t recsrc; | ||||
u_int16_t level[32]; | u_int16_t level[32]; | ||||
u_int16_t level_muted[32]; | |||||
u_int8_t parent[32]; | u_int8_t parent[32]; | ||||
u_int32_t child[32]; | u_int32_t child[32]; | ||||
u_int8_t realdev[32]; | u_int8_t realdev[32]; | ||||
char name[MIXER_NAMELEN]; | char name[MIXER_NAMELEN]; | ||||
struct mtx *lock; | struct mtx *lock; | ||||
oss_mixer_enuminfo enuminfo; | oss_mixer_enuminfo enuminfo; | ||||
/** | /** | ||||
* Counter is incremented when applications change any of this | * Counter is incremented when applications change any of this | ||||
▲ Show 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | mixer_set_eq(struct snd_mixer *m, struct snddev_info *d, | ||||
MIXER_SET_UNLOCK(d, acquiremtx); | MIXER_SET_UNLOCK(d, acquiremtx); | ||||
MIXER_SET_LOCK(m, dropmtx); | MIXER_SET_LOCK(m, dropmtx); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
mixer_set(struct snd_mixer *m, u_int dev, u_int lev) | mixer_set(struct snd_mixer *m, u_int dev, u_int32_t muted, u_int lev) | ||||
{ | { | ||||
struct snddev_info *d; | struct snddev_info *d; | ||||
u_int l, r, tl, tr; | u_int l, r, tl, tr; | ||||
u_int32_t parent = SOUND_MIXER_NONE, child = 0; | u_int32_t parent = SOUND_MIXER_NONE, child = 0; | ||||
u_int32_t realdev; | u_int32_t realdev; | ||||
int i, dropmtx; | int i, dropmtx; | ||||
if (m == NULL || dev >= SOUND_MIXER_NRDEVICES || | if (m == NULL || dev >= SOUND_MIXER_NRDEVICES || | ||||
(0 == (m->devs & (1 << dev)))) | (0 == (m->devs & (1 << dev)))) | ||||
return -1; | return (-1); | ||||
l = min((lev & 0x00ff), 100); | l = min((lev & 0x00ff), 100); | ||||
r = min(((lev & 0xff00) >> 8), 100); | r = min(((lev & 0xff00) >> 8), 100); | ||||
realdev = m->realdev[dev]; | realdev = m->realdev[dev]; | ||||
d = device_get_softc(m->dev); | d = device_get_softc(m->dev); | ||||
if (d == NULL) | if (d == NULL) | ||||
return -1; | return (-1); | ||||
/* It is safe to drop this mutex due to Giant. */ | /* It is safe to drop this mutex due to Giant. */ | ||||
if (!(d->flags & SD_F_MPSAFE) && mtx_owned(m->lock) != 0) | if (!(d->flags & SD_F_MPSAFE) && mtx_owned(m->lock) != 0) | ||||
dropmtx = 1; | dropmtx = 1; | ||||
else | else | ||||
dropmtx = 0; | dropmtx = 0; | ||||
/* Allow the volume to be "changed" while muted. */ | |||||
if (muted & (1 << dev)) { | |||||
m->level_muted[dev] = l | (r << 8); | |||||
return (0); | |||||
} | |||||
MIXER_SET_UNLOCK(m, dropmtx); | MIXER_SET_UNLOCK(m, dropmtx); | ||||
/* TODO: recursive handling */ | /* TODO: recursive handling */ | ||||
parent = m->parent[dev]; | parent = m->parent[dev]; | ||||
if (parent >= SOUND_MIXER_NRDEVICES) | if (parent >= SOUND_MIXER_NRDEVICES) | ||||
parent = SOUND_MIXER_NONE; | parent = SOUND_MIXER_NONE; | ||||
if (parent == SOUND_MIXER_NONE) | if (parent == SOUND_MIXER_NONE) | ||||
child = m->child[dev]; | child = m->child[dev]; | ||||
if (parent != SOUND_MIXER_NONE) { | if (parent != SOUND_MIXER_NONE) { | ||||
tl = (l * (m->level[parent] & 0x00ff)) / 100; | tl = (l * (m->level[parent] & 0x00ff)) / 100; | ||||
tr = (r * ((m->level[parent] & 0xff00) >> 8)) / 100; | tr = (r * ((m->level[parent] & 0xff00) >> 8)) / 100; | ||||
if (dev == SOUND_MIXER_PCM && (d->flags & SD_F_SOFTPCMVOL)) | if (dev == SOUND_MIXER_PCM && (d->flags & SD_F_SOFTPCMVOL)) | ||||
(void)mixer_set_softpcmvol(m, d, tl, tr); | (void)mixer_set_softpcmvol(m, d, tl, tr); | ||||
else if (realdev != SOUND_MIXER_NONE && | else if (realdev != SOUND_MIXER_NONE && | ||||
MIXER_SET(m, realdev, tl, tr) < 0) { | MIXER_SET(m, realdev, tl, tr) < 0) { | ||||
MIXER_SET_LOCK(m, dropmtx); | MIXER_SET_LOCK(m, dropmtx); | ||||
return -1; | return (-1); | ||||
} | } | ||||
} else if (child != 0) { | } else if (child != 0) { | ||||
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | ||||
if (!(child & (1 << i)) || m->parent[i] != dev) | if (!(child & (1 << i)) || m->parent[i] != dev) | ||||
continue; | continue; | ||||
realdev = m->realdev[i]; | realdev = m->realdev[i]; | ||||
tl = (l * (m->level[i] & 0x00ff)) / 100; | tl = (l * (m->level[i] & 0x00ff)) / 100; | ||||
tr = (r * ((m->level[i] & 0xff00) >> 8)) / 100; | tr = (r * ((m->level[i] & 0xff00) >> 8)) / 100; | ||||
if (i == SOUND_MIXER_PCM && | if (i == SOUND_MIXER_PCM && | ||||
(d->flags & SD_F_SOFTPCMVOL)) | (d->flags & SD_F_SOFTPCMVOL)) | ||||
(void)mixer_set_softpcmvol(m, d, tl, tr); | (void)mixer_set_softpcmvol(m, d, tl, tr); | ||||
else if (realdev != SOUND_MIXER_NONE) | else if (realdev != SOUND_MIXER_NONE) | ||||
MIXER_SET(m, realdev, tl, tr); | MIXER_SET(m, realdev, tl, tr); | ||||
} | } | ||||
realdev = m->realdev[dev]; | realdev = m->realdev[dev]; | ||||
if (realdev != SOUND_MIXER_NONE && | if (realdev != SOUND_MIXER_NONE && | ||||
MIXER_SET(m, realdev, l, r) < 0) { | MIXER_SET(m, realdev, l, r) < 0) { | ||||
MIXER_SET_LOCK(m, dropmtx); | MIXER_SET_LOCK(m, dropmtx); | ||||
return -1; | return (-1); | ||||
} | } | ||||
} else { | } else { | ||||
if (dev == SOUND_MIXER_PCM && (d->flags & SD_F_SOFTPCMVOL)) | if (dev == SOUND_MIXER_PCM && (d->flags & SD_F_SOFTPCMVOL)) | ||||
(void)mixer_set_softpcmvol(m, d, l, r); | (void)mixer_set_softpcmvol(m, d, l, r); | ||||
else if ((dev == SOUND_MIXER_TREBLE || | else if ((dev == SOUND_MIXER_TREBLE || | ||||
dev == SOUND_MIXER_BASS) && (d->flags & SD_F_EQ)) | dev == SOUND_MIXER_BASS) && (d->flags & SD_F_EQ)) | ||||
(void)mixer_set_eq(m, d, dev, (l + r) >> 1); | (void)mixer_set_eq(m, d, dev, (l + r) >> 1); | ||||
else if (realdev != SOUND_MIXER_NONE && | else if (realdev != SOUND_MIXER_NONE && | ||||
MIXER_SET(m, realdev, l, r) < 0) { | MIXER_SET(m, realdev, l, r) < 0) { | ||||
MIXER_SET_LOCK(m, dropmtx); | MIXER_SET_LOCK(m, dropmtx); | ||||
return -1; | return (-1); | ||||
} | } | ||||
} | } | ||||
MIXER_SET_LOCK(m, dropmtx); | MIXER_SET_LOCK(m, dropmtx); | ||||
m->level[dev] = l | (r << 8); | m->level[dev] = l | (r << 8); | ||||
m->modify_counter++; | m->modify_counter++; | ||||
return 0; | return (0); | ||||
} | } | ||||
static int | static int | ||||
mixer_get(struct snd_mixer *mixer, int dev) | mixer_get(struct snd_mixer *mixer, int dev) | ||||
{ | { | ||||
if ((dev < SOUND_MIXER_NRDEVICES) && (mixer->devs & (1 << dev))) | if ((dev < SOUND_MIXER_NRDEVICES) && (mixer->devs & (1 << dev))) { | ||||
return mixer->level[dev]; | if (mixer->mutedevs & (1 << dev)) | ||||
return (mixer->level_muted[dev]); | |||||
else | else | ||||
return -1; | return (mixer->level[dev]); | ||||
} else { | |||||
return (-1); | |||||
} | } | ||||
} | |||||
void | |||||
mix_setmutedevs(struct snd_mixer *mixer, u_int32_t mutedevs) | |||||
{ | |||||
u_int32_t delta; | |||||
/* Filter out invalid values. */ | |||||
mutedevs &= mixer->devs; | |||||
delta = (mixer->mutedevs ^ mutedevs) & mixer->devs; | |||||
mixer->mutedevs = mutedevs; | |||||
for (int i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | |||||
if (!(delta & (1 << i))) | |||||
continue; | |||||
if (mutedevs & (1 << i)) { | |||||
mixer->level_muted[i] = mixer->level[i]; | |||||
mixer_set(mixer, i, 0, 0); | |||||
} else { | |||||
mixer_set(mixer, i, 0, mixer->level_muted[i]); | |||||
} | |||||
} | |||||
} | |||||
static int | static int | ||||
mixer_setrecsrc(struct snd_mixer *mixer, u_int32_t src) | mixer_setrecsrc(struct snd_mixer *mixer, u_int32_t src) | ||||
{ | { | ||||
struct snddev_info *d; | struct snddev_info *d; | ||||
u_int32_t recsrc; | u_int32_t recsrc; | ||||
int dropmtx; | int dropmtx; | ||||
d = device_get_softc(mixer->dev); | d = device_get_softc(mixer->dev); | ||||
▲ Show 20 Lines • Show All 245 Lines • ▼ Show 20 Lines | |||||
u_int32_t | u_int32_t | ||||
mix_getdevs(struct snd_mixer *m) | mix_getdevs(struct snd_mixer *m) | ||||
{ | { | ||||
return m->devs; | return m->devs; | ||||
} | } | ||||
u_int32_t | u_int32_t | ||||
mix_getmutedevs(struct snd_mixer *m) | |||||
{ | |||||
return m->mutedevs; | |||||
} | |||||
u_int32_t | |||||
mix_getrecdevs(struct snd_mixer *m) | mix_getrecdevs(struct snd_mixer *m) | ||||
{ | { | ||||
return m->recdevs; | return m->recdevs; | ||||
} | } | ||||
void * | void * | ||||
mix_getdevinfo(struct snd_mixer *m) | mix_getdevinfo(struct snd_mixer *m) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | ||||
if (resource_int_value(device_get_name(dev), | if (resource_int_value(device_get_name(dev), | ||||
device_get_unit(dev), snd_mixernames[i], &val) == 0) { | device_get_unit(dev), snd_mixernames[i], &val) == 0) { | ||||
if (val >= 0 && val <= 100) { | if (val >= 0 && val <= 100) { | ||||
v = (u_int16_t) val; | v = (u_int16_t) val; | ||||
} | } | ||||
} | } | ||||
mixer_set(m, i, v | (v << 8)); | mixer_set(m, i, 0, v | (v << 8)); | ||||
} | } | ||||
mixer_setrecsrc(m, 0); /* Set default input. */ | mixer_setrecsrc(m, 0); /* Set default input. */ | ||||
unit = device_get_unit(dev); | unit = device_get_unit(dev); | ||||
devunit = snd_mkunit(unit, SND_DEV_CTL, 0); | devunit = snd_mkunit(unit, SND_DEV_CTL, 0); | ||||
pdev = make_dev(&mixer_cdevsw, PCMMINOR(devunit), | pdev = make_dev(&mixer_cdevsw, PCMMINOR(devunit), | ||||
UID_ROOT, GID_WHEEL, 0666, "mixer%d", unit); | UID_ROOT, GID_WHEEL, 0666, "mixer%d", unit); | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | mixer_uninit(device_t dev) | ||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
pdev->si_drv1 = NULL; | pdev->si_drv1 = NULL; | ||||
destroy_dev(pdev); | destroy_dev(pdev); | ||||
snd_mtxlock(m->lock); | snd_mtxlock(m->lock); | ||||
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) | for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||||
mixer_set(m, i, 0); | mixer_set(m, i, 0, 0); | ||||
mixer_setrecsrc(m, SOUND_MASK_MIC); | mixer_setrecsrc(m, SOUND_MASK_MIC); | ||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
/* mixer uninit can sleep --hps */ | /* mixer uninit can sleep --hps */ | ||||
MIXER_UNINIT(m); | MIXER_UNINIT(m); | ||||
Show All 20 Lines | mixer_reinit(device_t dev) | ||||
snd_mtxlock(m->lock); | snd_mtxlock(m->lock); | ||||
i = MIXER_REINIT(m); | i = MIXER_REINIT(m); | ||||
if (i) { | if (i) { | ||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
return i; | return i; | ||||
} | } | ||||
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) | for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | ||||
mixer_set(m, i, m->level[i]); | if (m->mutedevs & (1 << i)) | ||||
mixer_set(m, i, 0, 0); | |||||
else | |||||
mixer_set(m, i, 0, m->level[i]); | |||||
} | |||||
mixer_setrecsrc(m, m->recsrc); | mixer_setrecsrc(m, m->recsrc); | ||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
return 0; | return 0; | ||||
} | } | ||||
static int | static int | ||||
Show All 9 Lines | sysctl_hw_snd_hwvol_mixer(SYSCTL_HANDLER_ARGS) | ||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
error = sysctl_handle_string(oidp, &devname[0], sizeof(devname), req); | error = sysctl_handle_string(oidp, &devname[0], sizeof(devname), req); | ||||
snd_mtxlock(m->lock); | snd_mtxlock(m->lock); | ||||
if (error == 0 && req->newptr != NULL) { | if (error == 0 && req->newptr != NULL) { | ||||
dev = mixer_lookup(devname); | dev = mixer_lookup(devname); | ||||
if (dev == -1) { | if (dev == -1) { | ||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
return EINVAL; | return EINVAL; | ||||
} | } else { | ||||
else if (dev != m->hwvol_mixer) { | |||||
m->hwvol_mixer = dev; | m->hwvol_mixer = dev; | ||||
m->hwvol_muted = 0; | |||||
} | } | ||||
} | } | ||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
return error; | return error; | ||||
} | } | ||||
int | int | ||||
mixer_hwvol_init(device_t dev) | mixer_hwvol_init(device_t dev) | ||||
Show All 14 Lines | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), | ||||
"hwvol_mixer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, | "hwvol_mixer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, | ||||
m, 0, sysctl_hw_snd_hwvol_mixer, "A", ""); | m, 0, sysctl_hw_snd_hwvol_mixer, "A", ""); | ||||
return 0; | return 0; | ||||
} | } | ||||
void | void | ||||
mixer_hwvol_mute_locked(struct snd_mixer *m) | mixer_hwvol_mute_locked(struct snd_mixer *m) | ||||
{ | { | ||||
if (m->hwvol_muted) { | mix_setmutedevs(m, m->mutedevs ^ (1 << m->hwvol_mixer)); | ||||
m->hwvol_muted = 0; | |||||
mixer_set(m, m->hwvol_mixer, m->hwvol_mute_level); | |||||
} else { | |||||
m->hwvol_muted++; | |||||
m->hwvol_mute_level = mixer_get(m, m->hwvol_mixer); | |||||
mixer_set(m, m->hwvol_mixer, 0); | |||||
} | } | ||||
} | |||||
void | void | ||||
mixer_hwvol_mute(device_t dev) | mixer_hwvol_mute(device_t dev) | ||||
{ | { | ||||
struct snd_mixer *m; | struct snd_mixer *m; | ||||
struct cdev *pdev; | struct cdev *pdev; | ||||
pdev = mixer_get_devt(dev); | pdev = mixer_get_devt(dev); | ||||
m = pdev->si_drv1; | m = pdev->si_drv1; | ||||
snd_mtxlock(m->lock); | snd_mtxlock(m->lock); | ||||
mixer_hwvol_mute_locked(m); | mixer_hwvol_mute_locked(m); | ||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
} | } | ||||
void | void | ||||
mixer_hwvol_step_locked(struct snd_mixer *m, int left_step, int right_step) | mixer_hwvol_step_locked(struct snd_mixer *m, int left_step, int right_step) | ||||
{ | { | ||||
int level, left, right; | int level, left, right; | ||||
if (m->hwvol_muted) { | |||||
m->hwvol_muted = 0; | |||||
level = m->hwvol_mute_level; | |||||
} else | |||||
level = mixer_get(m, m->hwvol_mixer); | level = mixer_get(m, m->hwvol_mixer); | ||||
if (level != -1) { | if (level != -1) { | ||||
left = level & 0xff; | left = level & 0xff; | ||||
right = (level >> 8) & 0xff; | right = (level >> 8) & 0xff; | ||||
left += left_step * m->hwvol_step; | left += left_step * m->hwvol_step; | ||||
if (left < 0) | if (left < 0) | ||||
left = 0; | left = 0; | ||||
else if (left > 100) | else if (left > 100) | ||||
left = 100; | left = 100; | ||||
right += right_step * m->hwvol_step; | right += right_step * m->hwvol_step; | ||||
if (right < 0) | if (right < 0) | ||||
right = 0; | right = 0; | ||||
else if (right > 100) | else if (right > 100) | ||||
right = 100; | right = 100; | ||||
mixer_set(m, m->hwvol_mixer, left | right << 8); | |||||
mixer_set(m, m->hwvol_mixer, m->mutedevs, left | right << 8); | |||||
} | } | ||||
} | } | ||||
void | void | ||||
mixer_hwvol_step(device_t dev, int left_step, int right_step) | mixer_hwvol_step(device_t dev, int left_step, int right_step) | ||||
{ | { | ||||
struct snd_mixer *m; | struct snd_mixer *m; | ||||
struct cdev *pdev; | struct cdev *pdev; | ||||
Show All 16 Lines | |||||
int | int | ||||
mix_set(struct snd_mixer *m, u_int dev, u_int left, u_int right) | mix_set(struct snd_mixer *m, u_int dev, u_int left, u_int right) | ||||
{ | { | ||||
int ret; | int ret; | ||||
KASSERT(m != NULL, ("NULL snd_mixer")); | KASSERT(m != NULL, ("NULL snd_mixer")); | ||||
snd_mtxlock(m->lock); | snd_mtxlock(m->lock); | ||||
ret = mixer_set(m, dev, left | (right << 8)); | ret = mixer_set(m, dev, m->mutedevs, left | (right << 8)); | ||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
return ((ret != 0) ? ENXIO : 0); | return ((ret != 0) ? ENXIO : 0); | ||||
} | } | ||||
int | int | ||||
mix_get(struct snd_mixer *m, u_int dev) | mix_get(struct snd_mixer *m, u_int dev) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 311 Lines • ▼ Show 20 Lines | case OSS_GETVERSION: | ||||
ret = 0; | ret = 0; | ||||
goto done; | goto done; | ||||
case SOUND_MIXER_INFO: | case SOUND_MIXER_INFO: | ||||
mixer_mixerinfo(m, (mixer_info *)arg); | mixer_mixerinfo(m, (mixer_info *)arg); | ||||
ret = 0; | ret = 0; | ||||
goto done; | goto done; | ||||
} | } | ||||
if ((cmd & ~0xff) == MIXER_WRITE(0)) { | if ((cmd & ~0xff) == MIXER_WRITE(0)) { | ||||
if (j == SOUND_MIXER_RECSRC) | switch (j) { | ||||
case SOUND_MIXER_RECSRC: | |||||
ret = mixer_setrecsrc(m, *arg_i); | ret = mixer_setrecsrc(m, *arg_i); | ||||
else | break; | ||||
ret = mixer_set(m, j, *arg_i); | case SOUND_MIXER_MUTE: | ||||
mix_setmutedevs(m, *arg_i); | |||||
ret = 0; | |||||
break; | |||||
default: | |||||
ret = mixer_set(m, j, m->mutedevs, *arg_i); | |||||
break; | |||||
} | |||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
return ((ret == 0) ? 0 : ENXIO); | return ((ret == 0) ? 0 : ENXIO); | ||||
} | } | ||||
if ((cmd & ~0xff) == MIXER_READ(0)) { | if ((cmd & ~0xff) == MIXER_READ(0)) { | ||||
switch (j) { | switch (j) { | ||||
case SOUND_MIXER_DEVMASK: | case SOUND_MIXER_DEVMASK: | ||||
case SOUND_MIXER_CAPS: | case SOUND_MIXER_CAPS: | ||||
case SOUND_MIXER_STEREODEVS: | case SOUND_MIXER_STEREODEVS: | ||||
v = mix_getdevs(m); | v = mix_getdevs(m); | ||||
break; | break; | ||||
case SOUND_MIXER_MUTE: | |||||
v = mix_getmutedevs(m); | |||||
break; | |||||
case SOUND_MIXER_RECMASK: | case SOUND_MIXER_RECMASK: | ||||
v = mix_getrecdevs(m); | v = mix_getrecdevs(m); | ||||
break; | break; | ||||
case SOUND_MIXER_RECSRC: | case SOUND_MIXER_RECSRC: | ||||
v = mixer_getrecsrc(m); | v = mixer_getrecsrc(m); | ||||
break; | break; | ||||
default: | default: | ||||
v = mixer_get(m, j); | v = mixer_get(m, j); | ||||
break; | |||||
} | } | ||||
*arg_i = v; | *arg_i = v; | ||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
return ((v != -1) ? 0 : ENXIO); | return ((v != -1) ? 0 : ENXIO); | ||||
} | } | ||||
done: | done: | ||||
snd_mtxunlock(m->lock); | snd_mtxunlock(m->lock); | ||||
return (ret); | return (ret); | ||||
▲ Show 20 Lines • Show All 212 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
mix_set_locked(struct snd_mixer *m, u_int dev, int left, int right) | mix_set_locked(struct snd_mixer *m, u_int dev, int left, int right) | ||||
{ | { | ||||
int level; | int level; | ||||
level = (left & 0xFF) | ((right & 0xFF) << 8); | level = (left & 0xFF) | ((right & 0xFF) << 8); | ||||
return (mixer_set(m, dev, level)); | return (mixer_set(m, dev, m->mutedevs, level)); | ||||
} | } |