static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int len = 0, dtype;
	int dev = iminor(file->f_dentry->d_inode);
	long ret = -EINVAL;
	void __user *p = (void __user *)arg;

	if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) {
		/*
		 * Have to validate the address given by the process.
		 */
		len = _SIOC_SIZE(cmd);
		if (len < 1 || len > 65536 || !p)
			return -EFAULT;
		if (_SIOC_DIR(cmd) & _SIOC_WRITE)
			if (!access_ok(VERIFY_READ, p, len))
				return -EFAULT;
		if (_SIOC_DIR(cmd) & _SIOC_READ)
			if (!access_ok(VERIFY_WRITE, p, len))
				return -EFAULT;
	}
	DEB(printk("sound_ioctl(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
	if (cmd == OSS_GETVERSION)
		return __put_user(SOUND_VERSION, (int __user *)p);
	
	lock_kernel();
	if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 &&   /* Mixer ioctl */
	    (dev & 0x0f) != SND_DEV_CTL) {              
		dtype = dev & 0x0f;
		switch (dtype) {
		case SND_DEV_DSP:
		case SND_DEV_DSP16:
		case SND_DEV_AUDIO:
			ret = sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
						 cmd, p);
			break;			
		default:
			ret = sound_mixer_ioctl(dev >> 4, cmd, p);
			break;
		}
		unlock_kernel();
		return ret;
	}
Ejemplo n.º 2
0
static int sound_ioctl(struct inode *inode, struct file *file,
		       unsigned int cmd, unsigned long arg)
{
	int err, len = 0, dtype;
	int dev = MINOR(inode->i_rdev);

	if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) {
		/*
		 * Have to validate the address given by the process.
		 */
		len = _SIOC_SIZE(cmd);
		if (len < 1 || len > 65536 || arg == 0)
			return -EFAULT;
		if (_SIOC_DIR(cmd) & _SIOC_WRITE)
			if ((err = verify_area(VERIFY_READ, (void *)arg, len)) < 0)
				return err;
		if (_SIOC_DIR(cmd) & _SIOC_READ)
			if ((err = verify_area(VERIFY_WRITE, (void *)arg, len)) < 0)
				return err;
	}
	DEB(printk("sound_ioctl(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
	if (cmd == OSS_GETVERSION)
		return __put_user(SOUND_VERSION, (int *)arg);
	
	if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 &&   /* Mixer ioctl */
	    (dev & 0x0f) != SND_DEV_CTL) {              
		dtype = dev & 0x0f;
		switch (dtype) {
#ifdef CONFIG_AUDIO
		case SND_DEV_DSP:
		case SND_DEV_DSP16:
		case SND_DEV_AUDIO:
			return sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
						 cmd, (caddr_t)arg);
#endif
			
		default:
			return sound_mixer_ioctl(dev >> 4, cmd, (caddr_t)arg);
		}
	}
static int sound_mixer_ioctl(int mixdev, unsigned int cmd, void __user *arg)
{
 	if (mixdev < 0 || mixdev >= MAX_MIXER_DEV)
 		return -ENXIO;
 	/* Try to load the mixer... */
 	if (mixer_devs[mixdev] == NULL) {
 		request_module("mixer%d", mixdev);
 	}
 	if (mixdev >= num_mixers || !mixer_devs[mixdev])
 		return -ENXIO;
	if (cmd == SOUND_MIXER_INFO)
		return get_mixer_info(mixdev, arg);
	if (cmd == SOUND_OLD_MIXER_INFO)
		return get_old_mixer_info(mixdev, arg);
	if (_SIOC_DIR(cmd) & _SIOC_WRITE)
		mixer_devs[mixdev]->modify_counter++;
	if (!mixer_devs[mixdev]->ioctl)
		return -EINVAL;
	return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg);
}
Ejemplo n.º 4
0
static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	struct video_audio va;
	int left,right,ret,val = 0;
        struct TVMIXER *mix = file->private_data;
	struct i2c_client *client = mix->dev;

	if (NULL == client)
		return -ENODEV;
	
        if (cmd == SOUND_MIXER_INFO) {
                mixer_info info;
                strncpy(info.id, "tv card", sizeof(info.id));
                strncpy(info.name, client->name, sizeof(info.name));
                info.modify_counter = 42 /* FIXME */;
                if (copy_to_user((void *)arg, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
        if (cmd == SOUND_OLD_MIXER_INFO) {
                _old_mixer_info info;
                strncpy(info.id, "tv card", sizeof(info.id));
                strncpy(info.name, client->name, sizeof(info.name));
                if (copy_to_user((void *)arg, &info, sizeof(info)))
                        return -EFAULT;
                return 0;
        }
        if (cmd == OSS_GETVERSION)
                return put_user(SOUND_VERSION, (int *)arg);

	if (_SIOC_DIR(cmd) & _SIOC_WRITE)
		if (get_user(val, (int *)arg))
			return -EFAULT;

	/* read state */
	memset(&va,0,sizeof(va));
	client->driver->command(client,VIDIOCGAUDIO,&va);

	switch (cmd) {
	case MIXER_READ(SOUND_MIXER_RECMASK):
	case MIXER_READ(SOUND_MIXER_CAPS):
	case MIXER_READ(SOUND_MIXER_RECSRC):
	case MIXER_WRITE(SOUND_MIXER_RECSRC):
		ret = 0;
		break;

	case MIXER_READ(SOUND_MIXER_STEREODEVS):
		ret = SOUND_MASK_VOLUME;
		break;
	case MIXER_READ(SOUND_MIXER_DEVMASK):
		ret = SOUND_MASK_VOLUME;
		if (va.flags & VIDEO_AUDIO_BASS)
			ret |= SOUND_MASK_BASS;
		if (va.flags & VIDEO_AUDIO_TREBLE)
			ret |= SOUND_MASK_TREBLE;
		break;

	case MIXER_WRITE(SOUND_MIXER_VOLUME):
		left  = mix_to_v4l(val);
		right = mix_to_v4l(val >> 8);
		va.volume  = MAX(left,right);
		va.balance = (32768*MIN(left,right)) / (va.volume ? va.volume : 1);
		va.balance = (left<right) ? (65535-va.balance) : va.balance;
		client->driver->command(client,VIDIOCSAUDIO,&va);
		client->driver->command(client,VIDIOCGAUDIO,&va);
		/* fall throuth */
	case MIXER_READ(SOUND_MIXER_VOLUME):
		left  = (MIN(65536 - va.balance,32768) *
			 va.volume) / 32768;
		right = (MIN(va.balance,32768) *
			 va.volume) / 32768;
		ret = v4l_to_mix2(left,right);
		break;
		
	case MIXER_WRITE(SOUND_MIXER_BASS):
		va.bass = mix_to_v4l(val);
		client->driver->command(client,VIDIOCSAUDIO,&va);
		client->driver->command(client,VIDIOCGAUDIO,&va);
		/* fall throuth  */
	case MIXER_READ(SOUND_MIXER_BASS):
		ret = v4l_to_mix(va.bass);
		break;

	case MIXER_WRITE(SOUND_MIXER_TREBLE):
		va.treble = mix_to_v4l(val);
		client->driver->command(client,VIDIOCSAUDIO,&va);
		client->driver->command(client,VIDIOCGAUDIO,&va);
		/* fall throuth */
	case MIXER_READ(SOUND_MIXER_TREBLE):
		ret = v4l_to_mix(va.treble);
		break;

	default:
		return -EINVAL;
	}
	if (put_user(ret, (int *)arg))
		return -EFAULT;
	return 0;
}
Ejemplo n.º 5
0
static int opl3sa2_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
	int cmdf = cmd & 0xff;

	opl3sa2_mixerdata* devc = (opl3sa2_mixerdata*) mixer_devs[dev]->devc;
	
	switch(cmdf)
	{
		case SOUND_MIXER_VOLUME:
		case SOUND_MIXER_MIC:
		case SOUND_MIXER_BASS:
		case SOUND_MIXER_TREBLE:
		case SOUND_MIXER_DEVMASK:
		case SOUND_MIXER_STEREODEVS: 
		case SOUND_MIXER_RECMASK:
		case SOUND_MIXER_CAPS: 
		case SOUND_MIXER_RECSRC:
			break;

		default:
			return call_ad_mixer(devc, cmd, arg);
	}
	
	if(((cmd >> 8) & 0xff) != 'M')
		return -EINVAL;
		
	if(_SIOC_DIR (cmd) & _SIOC_WRITE)
	{
		switch (cmdf)	
		{
			case SOUND_MIXER_RECSRC:
				if(devc->ad_mixer_dev != -1)
					return call_ad_mixer(devc, cmd, arg);
				else
				{
					if(*(int*)arg != 0)
						return -EINVAL;
					return 0;
				}

			case SOUND_MIXER_VOLUME:
				arg_to_volume_stereo(*(unsigned int*)arg,
						     &devc->volume_l,
						     &devc->volume_r); 
				opl3sa2_set_volume(devc, devc->volume_l,
						   devc->volume_r);
				*(int*)arg = ret_vol_stereo(devc->volume_l,
							     devc->volume_r);
				return 0;
		  
			case SOUND_MIXER_MIC:
				arg_to_volume_mono(*(unsigned int*)arg,
						   &devc->mic);
				opl3sa2_set_mic(devc, devc->mic);
				*(int*)arg = ret_vol_mono(devc->mic);
				return 0;
		  
			case SOUND_MIXER_BASS:
				if(chipset != CHIPSET_OPL3SA2)
				{
					arg_to_volume_mono(*(unsigned int*)arg,
							   &devc->bass);
					opl3sa3_set_bass(devc, devc->bass);
					*(int*)arg = ret_vol_mono(devc->bass);
					return 0;
				}
				return -EINVAL;
		  
			case SOUND_MIXER_TREBLE:
				if(chipset != CHIPSET_OPL3SA2)
				{
					arg_to_volume_mono(*(unsigned int *)arg,
							   &devc->treble);
					opl3sa3_set_treble(devc, devc->treble);
					*(int*)arg = ret_vol_mono(devc->treble);
					return 0;
				}
				return -EINVAL;
		  
			default:
				return -EINVAL;
		}
	}
	else			
	{
		/*
		 * Return parameters
		 */
		switch (cmdf)
		{
			case SOUND_MIXER_DEVMASK:
				if(call_ad_mixer(devc, cmd, arg) == -EINVAL)
					*(int*)arg = 0; /* no mixer devices */

				*(int*)arg |= (SOUND_MASK_VOLUME | SOUND_MASK_MIC);

				/* OPL3-SA2 has no bass and treble mixers */
				if(chipset != CHIPSET_OPL3SA2)
					*(int*)arg |= (SOUND_MASK_BASS |
						       SOUND_MASK_TREBLE);
				return 0;
		  
			case SOUND_MIXER_STEREODEVS:
				if(call_ad_mixer(devc, cmd, arg) == -EINVAL)
					*(int*)arg = 0; /* no stereo devices */
				*(int*)arg |= SOUND_MASK_VOLUME;
				return 0;
		  
			case SOUND_MIXER_RECMASK:
				if(devc->ad_mixer_dev != -1)
				{
					return call_ad_mixer(devc, cmd, arg);
				}
				else
				{
					/* No recording devices */
					return (*(int*)arg = 0);
				}

			case SOUND_MIXER_CAPS:
				if(devc->ad_mixer_dev != -1)
				{
					return call_ad_mixer(devc, cmd, arg);
				}
				else
				{
					*(int*)arg = SOUND_CAP_EXCL_INPUT;
					return 0;
				}

			case SOUND_MIXER_RECSRC:
				if(devc->ad_mixer_dev != -1)
				{
					return call_ad_mixer(devc, cmd, arg);
				}
				else
				{
					/* No recording source */
					return (*(int*)arg = 0);
				}

			case SOUND_MIXER_VOLUME:
				*(int*)arg = ret_vol_stereo(devc->volume_l,
							    devc->volume_r);
				return 0;
			  
			case SOUND_MIXER_MIC:
				*(int*)arg = ret_vol_mono(devc->mic);
				return 0;

			case SOUND_MIXER_BASS:
				if(chipset != CHIPSET_OPL3SA2)
				{
					*(int*)arg = ret_vol_mono(devc->bass);
					return 0;
				}
				else
				{
					return -EINVAL;
				}
			  
			case SOUND_MIXER_TREBLE:
				if(chipset != CHIPSET_OPL3SA2)
				{
					*(int*)arg = ret_vol_mono(devc->treble);
					return 0;
				}
				else
				{
					return -EINVAL;
				}
			  
			default:
				return -EINVAL;
		}
	}
}
Ejemplo n.º 6
0
static int opl3sa3_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
	int cmdf = cmd & 0xff;

	opl3sa2_mixerdata* devc = (opl3sa2_mixerdata*) mixer_devs[dev]->devc;

	switch(cmdf) {
		case SOUND_MIXER_BASS:
		case SOUND_MIXER_TREBLE:
		case SOUND_MIXER_DIGITAL1:
		case SOUND_MIXER_DEVMASK:
		case SOUND_MIXER_STEREODEVS: 
			break;

		default:
			return opl3sa2_mixer_ioctl(dev, cmd, arg);
	}

	if(((cmd >> 8) & 0xff) != 'M')
		return -EINVAL;
		
	if(_SIOC_DIR (cmd) & _SIOC_WRITE) {
		switch (cmdf) {
			case SOUND_MIXER_BASS:
				arg_to_vol_stereo(*(unsigned int*)arg,
						  &devc->bass_l, &devc->bass_r); 
				opl3sa3_set_bass(devc, devc->bass_l, devc->bass_r);
				*(int*)arg = ret_vol_stereo(devc->bass_l, devc->bass_r);
				return 0;
		  
			case SOUND_MIXER_TREBLE:
				arg_to_vol_stereo(*(unsigned int*)arg,
						  &devc->treble_l, &devc->treble_r); 
				opl3sa3_set_treble(devc, devc->treble_l, devc->treble_r);
				*(int*)arg = ret_vol_stereo(devc->treble_l, devc->treble_r);
				return 0;

			case SOUND_MIXER_DIGITAL1:
				arg_to_vol_stereo(*(unsigned int*)arg,
						  &devc->wide_l, &devc->wide_r); 
				opl3sa3_set_wide(devc, devc->wide_l, devc->wide_r);
				*(int*)arg = ret_vol_stereo(devc->wide_l, devc->wide_r);
				return 0;

			default:
				return -EINVAL;
		}
	}
	else			
	{
		/*
		 * Return parameters
		 */
		switch (cmdf) {
			case SOUND_MIXER_DEVMASK:
				*(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_MIC |
					      SOUND_MASK_BASS | SOUND_MASK_TREBLE |
					      SOUND_MASK_DIGITAL1);
				return 0;
		  
			case SOUND_MIXER_STEREODEVS:
				*(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_BASS |
					      SOUND_MASK_TREBLE | SOUND_MASK_DIGITAL1);
				return 0;
		  
			case SOUND_MIXER_BASS:
				*(int*)arg = ret_vol_stereo(devc->bass_l, devc->bass_r);
				return 0;
			  
			case SOUND_MIXER_TREBLE:
				*(int*)arg = ret_vol_stereo(devc->treble_l, devc->treble_r);
				return 0;

			case SOUND_MIXER_DIGITAL1:
				*(int*)arg = ret_vol_stereo(devc->wide_l, devc->wide_r);
				return 0;

			default:
				return -EINVAL;
		}
	}
}
Ejemplo n.º 7
0
static int opl3sa2_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
{
	int cmdf = cmd & 0xff;

	opl3sa2_mixerdata* devc = (opl3sa2_mixerdata*) mixer_devs[dev]->devc;
	
	switch(cmdf) {
		case SOUND_MIXER_VOLUME:
		case SOUND_MIXER_MIC:
		case SOUND_MIXER_DEVMASK:
		case SOUND_MIXER_STEREODEVS: 
		case SOUND_MIXER_RECMASK:
		case SOUND_MIXER_RECSRC:
		case SOUND_MIXER_CAPS: 
			break;

		default:
			return -EINVAL;
	}
	
	if(((cmd >> 8) & 0xff) != 'M')
		return -EINVAL;
		
	if(_SIOC_DIR (cmd) & _SIOC_WRITE) {
		switch (cmdf) {
			case SOUND_MIXER_VOLUME:
				arg_to_vol_stereo(*(unsigned int*)arg,
						  &devc->volume_l, &devc->volume_r); 
				opl3sa2_set_volume(devc, devc->volume_l, devc->volume_r);
				*(int*)arg = ret_vol_stereo(devc->volume_l, devc->volume_r);
				return 0;
		  
			case SOUND_MIXER_MIC:
				arg_to_vol_mono(*(unsigned int*)arg, &devc->mic);
				opl3sa2_set_mic(devc, devc->mic);
				*(int*)arg = ret_vol_mono(devc->mic);
				return 0;

			default:
				return -EINVAL;
		}
	}
	else {
		/*
		 * Return parameters
		 */
		switch (cmdf) {
			case SOUND_MIXER_DEVMASK:
				*(int*)arg = (SOUND_MASK_VOLUME | SOUND_MASK_MIC);
				return 0;
		  
			case SOUND_MIXER_STEREODEVS:
				*(int*)arg = SOUND_MASK_VOLUME;
				return 0;
		  
			case SOUND_MIXER_RECMASK:
				/* No recording devices */
				return (*(int*)arg = 0);

			case SOUND_MIXER_CAPS:
				*(int*)arg = SOUND_CAP_EXCL_INPUT;
				return 0;

			case SOUND_MIXER_RECSRC:
				/* No recording source */
				return (*(int*)arg = 0);

			case SOUND_MIXER_VOLUME:
				*(int*)arg = ret_vol_stereo(devc->volume_l, devc->volume_r);
				return 0;
			  
			case SOUND_MIXER_MIC:
				*(int*)arg = ret_vol_mono(devc->mic);
				return 0;

			default:
				return -EINVAL;
		}
	}
}