Enscript Output

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.