extractedLnx/linux/drivers/sound/dmasound.c_mixer_ioctl.c
static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long arg)
{
int data;
if (_SIOC_DIR(cmd) & _SIOC_WRITE)
mixer.modify_counter++;
if (cmd == OSS_GETVERSION)
return IOCTL_OUT(arg, SOUND_VERSION);
switch (sound.mach.type) {
#ifdef CONFIG_ATARI
case DMASND_FALCON:
switch (cmd) {
case SOUND_MIXER_INFO: {
mixer_info info;
strncpy(info.id, "FALCON", sizeof(info.id));
strncpy(info.name, "FALCON", sizeof(info.name));
info.name[sizeof(info.name)-1] = 0;
info.modify_counter = mixer.modify_counter;
copy_to_user_ret((int *)arg, &info, sizeof(info), -EFAULT);
return 0;
}
case SOUND_MIXER_READ_DEVMASK:
return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
case SOUND_MIXER_READ_RECMASK:
return IOCTL_OUT(arg, SOUND_MASK_MIC);
case SOUND_MIXER_READ_STEREODEVS:
return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC);
case SOUND_MIXER_READ_CAPS:
return IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT);
case SOUND_MIXER_READ_VOLUME:
return IOCTL_OUT(arg,
VOLUME_ATT_TO_VOXWARE(sound.volume_left) |
VOLUME_ATT_TO_VOXWARE(sound.volume_right) << 8);
case SOUND_MIXER_WRITE_MIC:
IOCTL_IN(arg, data);
tt_dmasnd.input_gain =
RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 |
RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
/* fall thru, return set value */
case SOUND_MIXER_READ_MIC:
return IOCTL_OUT(arg,
RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8);
case SOUND_MIXER_READ_SPEAKER:
{
int porta;
cli();
sound_ym.rd_data_reg_sel = 14;
porta = sound_ym.rd_data_reg_sel;
sti();
return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
}
case SOUND_MIXER_WRITE_VOLUME:
IOCTL_IN(arg, data);
return IOCTL_OUT(arg, sound_set_volume(data));
case SOUND_MIXER_WRITE_SPEAKER:
{
int porta;
IOCTL_IN(arg, data);
cli();
sound_ym.rd_data_reg_sel = 14;
porta = (sound_ym.rd_data_reg_sel & ~0x40) |
(data < 50 ? 0x40 : 0);
sound_ym.wd_data = porta;
sti();
return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
}
}
break;
case DMASND_TT:
switch (cmd) {
case SOUND_MIXER_INFO: {
mixer_info info;
strncpy(info.id, "TT", sizeof(info.id));
strncpy(info.name, "TT", sizeof(info.name));
info.name[sizeof(info.name)-1] = 0;
info.modify_counter = mixer.modify_counter;
copy_to_user_ret((int *)arg, &info, sizeof(info), -EFAULT);
return 0;
}
case SOUND_MIXER_READ_DEVMASK:
return IOCTL_OUT(arg,
SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
(MACH_IS_TT ? SOUND_MASK_SPEAKER : 0));
case SOUND_MIXER_READ_RECMASK:
return IOCTL_OUT(arg, 0);
case SOUND_MIXER_READ_STEREODEVS:
return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
case SOUND_MIXER_READ_VOLUME:
return IOCTL_OUT(arg,
VOLUME_DB_TO_VOXWARE(sound.volume_left) |
(VOLUME_DB_TO_VOXWARE(sound.volume_right) << 8));
case SOUND_MIXER_READ_BASS:
return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.bass));
case SOUND_MIXER_READ_TREBLE:
return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(sound.treble));
case SOUND_MIXER_READ_OGAIN:
return IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(sound.gain));
case SOUND_MIXER_READ_SPEAKER:
{
int porta;
if (MACH_IS_TT) {
cli();
sound_ym.rd_data_reg_sel = 14;
porta = sound_ym.rd_data_reg_sel;
sti();
return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
}
}
break;
case SOUND_MIXER_WRITE_VOLUME:
IOCTL_IN(arg, data);
return IOCTL_OUT(arg, sound_set_volume(data));
case SOUND_MIXER_WRITE_BASS:
IOCTL_IN(arg, data);
return IOCTL_OUT(arg, sound_set_bass(data));
case SOUND_MIXER_WRITE_TREBLE:
IOCTL_IN(arg, data);
return IOCTL_OUT(arg, sound_set_treble(data));
case SOUND_MIXER_WRITE_OGAIN:
IOCTL_IN(arg, data);
return IOCTL_OUT(arg, sound_set_gain(data));
case SOUND_MIXER_WRITE_SPEAKER:
if (MACH_IS_TT) {
int porta;
IOCTL_IN(arg, data);
cli();
sound_ym.rd_data_reg_sel = 14;
porta = (sound_ym.rd_data_reg_sel & ~0x40) |
(data < 50 ? 0x40 : 0);
sound_ym.wd_data = porta;
sti();
return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
}
}
break;
#endif /* CONFIG_ATARI */
#ifdef CONFIG_AMIGA
case DMASND_AMIGA:
switch (cmd) {
case SOUND_MIXER_INFO: {
mixer_info info;
strncpy(info.id, "AMIGA", sizeof(info.id));
strncpy(info.name, "AMIGA", sizeof(info.name));
info.name[sizeof(info.name)-1] = 0;
info.modify_counter = mixer.modify_counter;
copy_to_user_ret((int *)arg, &info, sizeof(info), -EFAULT);
return 0;
}
case SOUND_MIXER_READ_DEVMASK:
return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_TREBLE);
case SOUND_MIXER_READ_RECMASK:
return IOCTL_OUT(arg, 0);
case SOUND_MIXER_READ_STEREODEVS:
return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
case SOUND_MIXER_READ_VOLUME:
return IOCTL_OUT(arg,
VOLUME_AMI_TO_VOXWARE(sound.volume_left) |
VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8);
case SOUND_MIXER_WRITE_VOLUME:
IOCTL_IN(arg, data);
return IOCTL_OUT(arg, sound_set_volume(data));
case SOUND_MIXER_READ_TREBLE:
return IOCTL_OUT(arg, sound.treble);
case SOUND_MIXER_WRITE_TREBLE:
IOCTL_IN(arg, data);
return IOCTL_OUT(arg, sound_set_treble(data));
}
break;
#endif /* CONFIG_AMIGA */
#ifdef CONFIG_PPC
case DMASND_AWACS:
/* Different IOCTLS for burgundy*/
if (awacs_revision < AWACS_BURGUNDY) {
switch (cmd) {
case SOUND_MIXER_INFO: {
mixer_info info;
strncpy(info.id, "AWACS", sizeof(info.id));
strncpy(info.name, "AWACS", sizeof(info.name));
info.name[sizeof(info.name)-1] = 0;
info.modify_counter = mixer.modify_counter;
copy_to_user_ret((int *)arg, &info,
sizeof(info), -EFAULT);
return 0;
}
case SOUND_MIXER_READ_DEVMASK:
data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
| SOUND_MASK_LINE | SOUND_MASK_MIC
| SOUND_MASK_CD | SOUND_MASK_RECLEV
| SOUND_MASK_ALTPCM
| SOUND_MASK_MONITOR;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_READ_RECMASK:
data = SOUND_MASK_LINE | SOUND_MASK_MIC
| SOUND_MASK_CD;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_READ_RECSRC:
data = 0;
if (awacs_reg[0] & MASK_MUX_AUDIN)
data |= SOUND_MASK_LINE;
if (awacs_reg[0] & MASK_MUX_MIC)
data |= SOUND_MASK_MIC;
if (awacs_reg[0] & MASK_MUX_CD)
data |= SOUND_MASK_CD;
if (awacs_reg[1] & MASK_LOOPTHRU)
data |= SOUND_MASK_MONITOR;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_WRITE_RECSRC:
IOCTL_IN(arg, data);
data &= (SOUND_MASK_LINE
| SOUND_MASK_MIC | SOUND_MASK_CD
| SOUND_MASK_MONITOR);
awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
| MASK_MUX_AUDIN);
awacs_reg[1] &= ~MASK_LOOPTHRU;
if (data & SOUND_MASK_LINE)
awacs_reg[0] |= MASK_MUX_AUDIN;
if (data & SOUND_MASK_MIC)
awacs_reg[0] |= MASK_MUX_MIC;
if (data & SOUND_MASK_CD)
awacs_reg[0] |= MASK_MUX_CD;
if (data & SOUND_MASK_MONITOR)
awacs_reg[1] |= MASK_LOOPTHRU;
awacs_write(awacs_reg[0] | MASK_ADDR0);
awacs_write(awacs_reg[1] | MASK_ADDR1);
return IOCTL_OUT(arg, data);
case SOUND_MIXER_READ_STEREODEVS:
data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
| SOUND_MASK_RECLEV;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_READ_CAPS:
return IOCTL_OUT(arg, 0);
case SOUND_MIXER_READ_VOLUME:
data = (awacs_reg[1] & MASK_AMUTE)? 0:
awacs_get_volume(awacs_reg[2], 6);
return IOCTL_OUT(arg, data);
case SOUND_MIXER_WRITE_VOLUME:
IOCTL_IN(arg, data);
return IOCTL_OUT(arg, sound_set_volume(data));
case SOUND_MIXER_READ_SPEAKER:
if (awacs_revision == 3
&& sys_ctrler == SYS_CTRLER_CUDA)
data = awacs_spkr_vol;
else
data = (awacs_reg[1] & MASK_CMUTE)? 0:
awacs_get_volume(awacs_reg[4], 6);
return IOCTL_OUT(arg, data);
case SOUND_MIXER_WRITE_SPEAKER:
IOCTL_IN(arg, data);
if (awacs_revision == 3
&& sys_ctrler == SYS_CTRLER_CUDA)
awacs_enable_amp(data);
else
data = awacs_volume_setter(data, 4, MASK_CMUTE, 6);
return IOCTL_OUT(arg, data);
case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */
IOCTL_IN(arg, data);
beep_volume = data & 0xff;
/* fall through */
case SOUND_MIXER_READ_ALTPCM:
return IOCTL_OUT(arg, beep_volume);
case SOUND_MIXER_WRITE_LINE:
IOCTL_IN(arg, data);
awacs_reg[0] &= ~MASK_MUX_AUDIN;
if ((data & 0xff) >= 50)
awacs_reg[0] |= MASK_MUX_AUDIN;
awacs_write(MASK_ADDR0 | awacs_reg[0]);
/* fall through */
case SOUND_MIXER_READ_LINE:
data = (awacs_reg[0] & MASK_MUX_AUDIN)? 100: 0;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_WRITE_MIC:
IOCTL_IN(arg, data);
data &= 0xff;
awacs_reg[0] &= ~(MASK_MUX_MIC | MASK_GAINLINE);
if (data >= 25) {
awacs_reg[0] |= MASK_MUX_MIC;
if (data >= 75)
awacs_reg[0] |= MASK_GAINLINE;
}
awacs_write(MASK_ADDR0 | awacs_reg[0]);
/* fall through */
case SOUND_MIXER_READ_MIC:
data = (awacs_reg[0] & MASK_MUX_MIC)?
(awacs_reg[0] & MASK_GAINLINE? 100: 50): 0;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_WRITE_CD:
IOCTL_IN(arg, data);
awacs_reg[0] &= ~MASK_MUX_CD;
if ((data & 0xff) >= 50)
awacs_reg[0] |= MASK_MUX_CD;
awacs_write(MASK_ADDR0 | awacs_reg[0]);
/* fall through */
case SOUND_MIXER_READ_CD:
data = (awacs_reg[0] & MASK_MUX_CD)? 100: 0;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_WRITE_RECLEV:
IOCTL_IN(arg, data);
data = awacs_volume_setter(data, 0, 0, 4);
return IOCTL_OUT(arg, data);
case SOUND_MIXER_READ_RECLEV:
data = awacs_get_volume(awacs_reg[0], 4);
return IOCTL_OUT(arg, data);
}
break;
} else {
/* We are, we are, we are... Burgundy or better */
switch(cmd) {
case SOUND_MIXER_INFO: {
mixer_info info;
strncpy(info.id, "AWACS", sizeof(info.id));
strncpy(info.name, "AWACS", sizeof(info.name));
info.name[sizeof(info.name)-1] = 0;
info.modify_counter = mixer.modify_counter;
copy_to_user_ret((int *)arg, &info,
sizeof(info), -EFAULT);
return 0;
}
case SOUND_MIXER_READ_DEVMASK:
data = SOUND_MASK_VOLUME | SOUND_MASK_CD |
SOUND_MASK_LINE | SOUND_MASK_MIC |
SOUND_MASK_SPEAKER | SOUND_MASK_ALTPCM;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_READ_RECMASK:
data = SOUND_MASK_LINE | SOUND_MASK_MIC
| SOUND_MASK_CD;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_READ_RECSRC:
data = 0;
if (awacs_reg[0] & MASK_MUX_AUDIN)
data |= SOUND_MASK_LINE;
if (awacs_reg[0] & MASK_MUX_MIC)
data |= SOUND_MASK_MIC;
if (awacs_reg[0] & MASK_MUX_CD)
data |= SOUND_MASK_CD;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_WRITE_RECSRC:
IOCTL_IN(arg, data);
data &= (SOUND_MASK_LINE
| SOUND_MASK_MIC | SOUND_MASK_CD);
awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
| MASK_MUX_AUDIN);
if (data & SOUND_MASK_LINE)
awacs_reg[0] |= MASK_MUX_AUDIN;
if (data & SOUND_MASK_MIC)
awacs_reg[0] |= MASK_MUX_MIC;
if (data & SOUND_MASK_CD)
awacs_reg[0] |= MASK_MUX_CD;
awacs_write(awacs_reg[0] | MASK_ADDR0);
return IOCTL_OUT(arg, data);
case SOUND_MIXER_READ_STEREODEVS:
data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
| SOUND_MASK_RECLEV | SOUND_MASK_CD
| SOUND_MASK_LINE;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_READ_CAPS:
return IOCTL_OUT(arg, 0);
case SOUND_MIXER_WRITE_VOLUME:
IOCTL_IN(arg, data);
awacs_burgundy_write_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME, data);
/* Fall through */
case SOUND_MIXER_READ_VOLUME:
return IOCTL_OUT(arg, awacs_burgundy_read_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME));
case SOUND_MIXER_WRITE_SPEAKER:
IOCTL_IN(arg, data);
if (!(data & 0xff)) {
/* Mute the left speaker */
awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x2);
} else {
/* Unmute the left speaker */
awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x2);
}
if (!(data & 0xff00)) {
/* Mute the right speaker */
awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x4);
} else {
/* Unmute the right speaker */
awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x4);
}
data = (((data&0xff)*16)/100 > 0xf ? 0xf :
(((data&0xff)*16)/100)) +
((((data>>8)*16)/100 > 0xf ? 0xf :
((((data>>8)*16)/100)))<<4);
awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER, ~data);
/* Fall through */
case SOUND_MIXER_READ_SPEAKER:
data = awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER);
data = (((data & 0xf)*100)/16) + ((((data>>4)*100)/16)<<8);
return IOCTL_OUT(arg, ~data);
case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */
IOCTL_IN(arg, data);
beep_volume = data & 0xff;
/* fall through */
case SOUND_MIXER_READ_ALTPCM:
return IOCTL_OUT(arg, beep_volume);
case SOUND_MIXER_WRITE_LINE:
IOCTL_IN(arg, data);
awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLLINE, data);
/* fall through */
case SOUND_MIXER_READ_LINE:
data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLLINE);
return IOCTL_OUT(arg, data);
case SOUND_MIXER_WRITE_MIC:
IOCTL_IN(arg, data);
/* Mic is mono device */
data = (data << 8) + (data << 24);
awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLMIC, data);
/* fall through */
case SOUND_MIXER_READ_MIC:
data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLMIC);
data <<= 24;
return IOCTL_OUT(arg, data);
case SOUND_MIXER_WRITE_CD:
IOCTL_IN(arg, data);
awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLCD, data);
/* fall through */
case SOUND_MIXER_READ_CD:
data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLCD);
return IOCTL_OUT(arg, data);
case SOUND_MIXER_WRITE_RECLEV:
IOCTL_IN(arg, data);
data = awacs_volume_setter(data, 0, 0, 4);
return IOCTL_OUT(arg, data);
case SOUND_MIXER_READ_RECLEV:
data = awacs_get_volume(awacs_reg[0], 4);
return IOCTL_OUT(arg, data);
case SOUND_MIXER_OUTMASK:
break;
case SOUND_MIXER_OUTSRC:
break;
}
break;
}
#endif
}
return -EINVAL;
}
Generated by GNU enscript 1.6.4.