Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/sound/pcm/dsp.c
Show First 20 Lines • Show All 959 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
dsp_ioctl_channel(struct cdev *dev, struct pcm_channel *volch, u_long cmd, | dsp_ioctl_channel(struct cdev *dev, struct pcm_channel *volch, u_long cmd, | ||||
caddr_t arg) | caddr_t arg) | ||||
{ | { | ||||
struct snddev_info *d; | struct snddev_info *d; | ||||
struct pcm_channel *rdch, *wrch; | struct pcm_channel *rdch, *wrch; | ||||
int j, devtype, ret; | int j, devtype, ret; | ||||
int left, right, center, mute; | |||||
d = dsp_get_info(dev); | d = dsp_get_info(dev); | ||||
if (!PCM_REGISTERED(d) || !(dsp_get_flags(dev) & SD_F_VPC)) | if (!PCM_REGISTERED(d) || !(dsp_get_flags(dev) & SD_F_VPC)) | ||||
return (-1); | return (-1); | ||||
PCM_UNLOCKASSERT(d); | PCM_UNLOCKASSERT(d); | ||||
j = cmd & 0xff; | j = cmd & 0xff; | ||||
Show All 22 Lines | if (volch == NULL && | ||||
ret = dsp_get_volume_channel(dev, &volch); | ret = dsp_get_volume_channel(dev, &volch); | ||||
if (ret != 0) | if (ret != 0) | ||||
return (ret); | return (ret); | ||||
if (volch == NULL) | if (volch == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* Final validation */ | /* Final validation */ | ||||
if (volch != NULL) { | if (volch == NULL) | ||||
return (EINVAL); | |||||
CHN_LOCK(volch); | CHN_LOCK(volch); | ||||
if (!(volch->feederflags & (1 << FEEDER_VOLUME))) { | if (!(volch->feederflags & (1 << FEEDER_VOLUME))) { | ||||
CHN_UNLOCK(volch); | CHN_UNLOCK(volch); | ||||
return (-1); | return (EINVAL); | ||||
} | } | ||||
if (volch->direction == PCMDIR_PLAY) | |||||
wrch = volch; | |||||
else | |||||
rdch = volch; | |||||
} | |||||
ret = EINVAL; | switch (cmd & ~0xff) { | ||||
case MIXER_WRITE(0): | |||||
if (volch != NULL && | switch (j) { | ||||
((j == SOUND_MIXER_PCM && volch->direction == PCMDIR_PLAY) || | case SOUND_MIXER_MUTE: | ||||
(j == SOUND_MIXER_RECLEV && volch->direction == PCMDIR_REC))) { | if (volch->direction == PCMDIR_REC) { | ||||
if ((cmd & ~0xff) == MIXER_WRITE(0)) { | chn_setmute_multi(volch, SND_VOL_C_PCM, (*(int *)arg & SOUND_MASK_RECLEV) != 0); | ||||
int left, right, center; | } else { | ||||
chn_setmute_multi(volch, SND_VOL_C_PCM, (*(int *)arg & SOUND_MASK_PCM) != 0); | |||||
} | |||||
break; | |||||
case SOUND_MIXER_PCM: | |||||
if (volch->direction != PCMDIR_PLAY) | |||||
break; | |||||
left = *(int *)arg & 0x7f; | left = *(int *)arg & 0x7f; | ||||
right = ((*(int *)arg) >> 8) & 0x7f; | right = ((*(int *)arg) >> 8) & 0x7f; | ||||
center = (left + right) >> 1; | center = (left + right) >> 1; | ||||
chn_setvolume_multi(volch, SND_VOL_C_PCM, left, right, | chn_setvolume_multi(volch, SND_VOL_C_PCM, | ||||
center); | left, right, center); | ||||
} else if ((cmd & ~0xff) == MIXER_READ(0)) { | break; | ||||
case SOUND_MIXER_RECLEV: | |||||
if (volch->direction != PCMDIR_REC) | |||||
break; | |||||
left = *(int *)arg & 0x7f; | |||||
right = ((*(int *)arg) >> 8) & 0x7f; | |||||
center = (left + right) >> 1; | |||||
chn_setvolume_multi(volch, SND_VOL_C_PCM, | |||||
left, right, center); | |||||
break; | |||||
default: | |||||
/* ignore all other mixer writes */ | |||||
break; | |||||
} | |||||
break; | |||||
case MIXER_READ(0): | |||||
switch (j) { | |||||
case SOUND_MIXER_MUTE: | |||||
mute = CHN_GETMUTE(volch, SND_VOL_C_PCM, SND_CHN_T_FL) || | |||||
CHN_GETMUTE(volch, SND_VOL_C_PCM, SND_CHN_T_FR); | |||||
if (volch->direction == PCMDIR_REC) { | |||||
*(int *)arg = mute << SOUND_MIXER_RECLEV; | |||||
} else { | |||||
*(int *)arg = mute << SOUND_MIXER_PCM; | |||||
} | |||||
break; | |||||
case SOUND_MIXER_PCM: | |||||
if (volch->direction != PCMDIR_PLAY) | |||||
break; | |||||
*(int *)arg = CHN_GETVOLUME(volch, | *(int *)arg = CHN_GETVOLUME(volch, | ||||
SND_VOL_C_PCM, SND_CHN_T_FL); | SND_VOL_C_PCM, SND_CHN_T_FL); | ||||
*(int *)arg |= CHN_GETVOLUME(volch, | *(int *)arg |= CHN_GETVOLUME(volch, | ||||
SND_VOL_C_PCM, SND_CHN_T_FR) << 8; | SND_VOL_C_PCM, SND_CHN_T_FR) << 8; | ||||
} | break; | ||||
ret = 0; | case SOUND_MIXER_RECLEV: | ||||
} else if (rdch != NULL || wrch != NULL) { | if (volch->direction != PCMDIR_REC) | ||||
switch (j) { | break; | ||||
*(int *)arg = CHN_GETVOLUME(volch, | |||||
SND_VOL_C_PCM, SND_CHN_T_FL); | |||||
*(int *)arg |= CHN_GETVOLUME(volch, | |||||
SND_VOL_C_PCM, SND_CHN_T_FR) << 8; | |||||
break; | |||||
case SOUND_MIXER_DEVMASK: | case SOUND_MIXER_DEVMASK: | ||||
case SOUND_MIXER_CAPS: | case SOUND_MIXER_CAPS: | ||||
case SOUND_MIXER_STEREODEVS: | case SOUND_MIXER_STEREODEVS: | ||||
if ((cmd & ~0xff) == MIXER_READ(0)) { | if (volch->direction == PCMDIR_REC) | ||||
*(int *)arg = 0; | *(int *)arg = SOUND_MASK_RECLEV; | ||||
if (rdch != NULL) | else | ||||
*(int *)arg |= SOUND_MASK_RECLEV; | *(int *)arg = SOUND_MASK_PCM; | ||||
if (wrch != NULL) | |||||
*(int *)arg |= SOUND_MASK_PCM; | |||||
} | |||||
ret = 0; | |||||
break; | break; | ||||
case SOUND_MIXER_RECMASK: | default: | ||||
case SOUND_MIXER_RECSRC: | |||||
if ((cmd & ~0xff) == MIXER_READ(0)) | |||||
*(int *)arg = 0; | *(int *)arg = 0; | ||||
ret = 0; | |||||
break; | break; | ||||
} | |||||
break; | |||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
} | |||||
if (volch != NULL) | |||||
CHN_UNLOCK(volch); | CHN_UNLOCK(volch); | ||||
return (0); | |||||
return (ret); | |||||
} | } | ||||
static int | static int | ||||
dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, | dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, | ||||
struct thread *td) | struct thread *td) | ||||
{ | { | ||||
struct pcm_channel *chn, *rdch, *wrch; | struct pcm_channel *chn, *rdch, *wrch; | ||||
struct snddev_info *d; | struct snddev_info *d; | ||||
▲ Show 20 Lines • Show All 1,214 Lines • ▼ Show 20 Lines | |||||
/* So much for dev_stdclone() */ | /* So much for dev_stdclone() */ | ||||
static int | static int | ||||
dsp_stdclone(char *name, char *namep, char *sep, int use_sep, int *u, int *c) | dsp_stdclone(char *name, char *namep, char *sep, int use_sep, int *u, int *c) | ||||
{ | { | ||||
size_t len; | size_t len; | ||||
len = strlen(namep); | len = strlen(namep); | ||||
if (strncmp(name, namep, len) != 0) | |||||
if (bcmp(name, namep, len) != 0) | |||||
return (ENODEV); | return (ENODEV); | ||||
name += len; | name += len; | ||||
if (isdigit(*name) == 0) | if (isdigit(*name) == 0) | ||||
return (ENODEV); | return (ENODEV); | ||||
len = strlen(sep); | len = strlen(sep); | ||||
▲ Show 20 Lines • Show All 1,073 Lines • Show Last 20 Lines |