⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mixer.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 3 页
字号:
			case CMD_READPTR:				if(ctl.val[1] >= 0x40)					return -EINVAL;				if((ctl.val[0] & 0x7ff) > 0xff)					return -EINVAL;				if((ctl.val[0] & 0x7ff) > 0x3f)					ctl.val[1] = 0x00;				ctl.val[2] = sblive_readptr(card, ctl.val[0], ctl.val[1]);				if (copy_to_user((void *) arg, &ctl, sizeof(struct mixer_private_ioctl)))					return -EFAULT;				return 0;				break;			case CMD_SETRECSRC:				switch(ctl.val[0]){				case WAVERECORD_AC97:					if(card->isaps)						return -EINVAL;					card->wavein.recsrc = WAVERECORD_AC97;					break;				case WAVERECORD_MIC:						card->wavein.recsrc = WAVERECORD_MIC;					break;				case WAVERECORD_FX:					card->wavein.recsrc = WAVERECORD_FX;					card->wavein.fxwc = ctl.val[1] & 0xffff;					if(!card->wavein.fxwc)						return -EINVAL;					break;				default:					return -EINVAL;				}				return 0;				break;			case CMD_GETRECSRC:				ctl.val[0] = card->wavein.recsrc;				ctl.val[1] = card->wavein.fxwc;				if (copy_to_user((void *) arg, &ctl, sizeof(struct mixer_private_ioctl)))					return -EFAULT;				return 0;				break;			case CMD_GETVOICEPARAM:				ctl.val[0] = card->waveout.send_routing[0];				ctl.val[1] = card->waveout.send_a[0] | card->waveout.send_b[0] << 8 |				             card->waveout.send_c[0] << 16 | card->waveout.send_d[0] << 24;				ctl.val[2] = card->waveout.send_routing[1]; 				ctl.val[3] = card->waveout.send_a[1] | card->waveout.send_b[1] << 8 |					     card->waveout.send_c[1] << 16 | card->waveout.send_d[1] << 24;				ctl.val[4] = card->waveout.send_routing[2]; 				ctl.val[5] = card->waveout.send_a[2] | card->waveout.send_b[2] << 8 |					     card->waveout.send_c[2] << 16 | card->waveout.send_d[2] << 24;				if (copy_to_user((void *) arg, &ctl, sizeof(struct mixer_private_ioctl)))					return -EFAULT;				return 0;				break;			case CMD_SETVOICEPARAM:				card->waveout.send_routing[0] = ctl.val[0] & 0xffff;				card->waveout.send_a[0] = ctl.val[1] & 0xff;				card->waveout.send_b[0] = (ctl.val[1] >> 8) & 0xff;				card->waveout.send_c[0] = (ctl.val[1] >> 16) & 0xff;				card->waveout.send_d[0] = (ctl.val[1] >> 24) & 0xff;				card->waveout.send_routing[1] = ctl.val[2] & 0xffff;				card->waveout.send_a[1] = ctl.val[3] & 0xff;				card->waveout.send_b[1] = (ctl.val[3] >> 8) & 0xff;				card->waveout.send_c[1] = (ctl.val[3] >> 16) & 0xff;				card->waveout.send_d[1] = (ctl.val[3] >> 24) & 0xff;				card->waveout.send_routing[2] = ctl.val[4] & 0xffff;				card->waveout.send_a[2] = ctl.val[5] & 0xff;				card->waveout.send_b[2] = (ctl.val[5] >> 8) & 0xff;				card->waveout.send_c[2] = (ctl.val[5] >> 16) & 0xff;				card->waveout.send_d[2] = (ctl.val[5] >> 24) & 0xff;				return 0;				break;			default:				return -EINVAL;				break;			}		}		break;	case SOUND_MIXER_PRIVATE4:{			u32 size;			int size_reg = 0;			if (copy_from_user(&size, (void *) arg, sizeof(size)))				return -EFAULT;			DPD(2,"External tram size 0x%x\n", size);			if(size > 0x1fffff)				return -EINVAL;			if (size != 0) {					size = (size - 1) >> 14;        	                while (size) {                	                size >>= 1;                        	        size_reg++;                        	}                        	size = 0x4000 << size_reg;			}			DPD(2,"External tram size 0x%x 0x%x\n", size, size_reg);			if (size != card->tankmem.size) {				if (card->tankmem.size > 0) {					emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 1);					sblive_writeptr_tag(card, 0, TCB, 0,							    TCBS, 0,							    TAGLIST_END);					pci_free_consistent(card->pci_dev, card->tankmem.size,							    card->tankmem.addr, card->tankmem.dma_handle);					card->tankmem.size = 0;				}				if (size != 0) {					if ((card->tankmem.addr = pci_alloc_consistent(card->pci_dev, size,					     &card->tankmem.dma_handle)) == NULL)						return -ENOMEM;					card->tankmem.size = size;					sblive_writeptr_tag(card, 0, TCB, card->tankmem.dma_handle,                        	                            TCBS, size_reg,                                	                    TAGLIST_END);					emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 0);				}			}			return 0;		}		break;	default:		break;	}	if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))		return -EINVAL;	if (_IOC_DIR(cmd) == _IOC_READ) {		switch (_IOC_NR(cmd)) {			case SOUND_MIXER_DEVMASK:       /* Arg contains a bit for each supported device */                        DPF(4, "SOUND_MIXER_READ_DEVMASK\n");			if (card->isaps)#ifdef TONE_CONTROL				return put_user(SOUND_MASK_PCM | SOUND_MASK_VOLUME |						SOUND_MASK_BASS | SOUND_MASK_TREBLE,						(int *) arg); #else				return put_user(SOUND_MASK_PCM | SOUND_MASK_VOLUME,						(int *) arg); #endif		#ifdef TONE_CONTROL			return put_user(SOUND_MASK_LINE | SOUND_MASK_CD |                                        SOUND_MASK_OGAIN | SOUND_MASK_LINE1 |                                        SOUND_MASK_PCM | SOUND_MASK_VOLUME |                                        SOUND_MASK_PHONEIN | SOUND_MASK_MIC |                                        SOUND_MASK_BASS | SOUND_MASK_TREBLE |                                        SOUND_MASK_RECLEV | SOUND_MASK_SPEAKER |                                        SOUND_MASK_LINE3 | SOUND_MASK_DIGITAL1 |                                         SOUND_MASK_DIGITAL2 | SOUND_MASK_LINE2, (int *) arg);#else			return put_user(SOUND_MASK_LINE | SOUND_MASK_CD |                                        SOUND_MASK_OGAIN | SOUND_MASK_LINE1 |                                        SOUND_MASK_PCM | SOUND_MASK_VOLUME |                                        SOUND_MASK_PHONEIN | SOUND_MASK_MIC |                                        SOUND_MASK_RECLEV | SOUND_MASK_SPEAKER |                                        SOUND_MASK_LINE3 | SOUND_MASK_DIGITAL1 |                                         SOUND_MASK_DIGITAL2 | SOUND_MASK_LINE2, (int *) arg);#endif			case SOUND_MIXER_RECMASK:       /* Arg contains a bit for each supported recording source */				DPF(2, "SOUND_MIXER_READ_RECMASK\n");				if (card->isaps)					return put_user(0, (int *) arg);				return put_user(SOUND_MASK_MIC | SOUND_MASK_CD |					SOUND_MASK_LINE1 | SOUND_MASK_LINE |					SOUND_MASK_VOLUME | SOUND_MASK_OGAIN |					SOUND_MASK_PHONEIN, (int *) arg);			case SOUND_MIXER_STEREODEVS:    /* Mixer channels supporting stereo */				DPF(2, "SOUND_MIXER_READ_STEREODEVS\n");				if (card->isaps)#ifdef TONE_CONTROL					return put_user(SOUND_MASK_PCM | SOUND_MASK_VOLUME |                                        		SOUND_MASK_BASS | SOUND_MASK_TREBLE,                                        		(int *) arg);#else					return put_user(SOUND_MASK_PCM | SOUND_MASK_VOLUME,                                         		(int *) arg);#endif#ifdef TONE_CONTROL				return put_user(SOUND_MASK_LINE | SOUND_MASK_CD |					SOUND_MASK_OGAIN | SOUND_MASK_LINE1 |					SOUND_MASK_PCM | SOUND_MASK_VOLUME |					SOUND_MASK_BASS | SOUND_MASK_TREBLE |					SOUND_MASK_RECLEV | SOUND_MASK_LINE3 |					SOUND_MASK_DIGITAL1 | SOUND_MASK_DIGITAL2 |					SOUND_MASK_LINE2, (int *) arg);#else				return put_user(SOUND_MASK_LINE | SOUND_MASK_CD |					SOUND_MASK_OGAIN | SOUND_MASK_LINE1 |					SOUND_MASK_PCM | SOUND_MASK_VOLUME |					SOUND_MASK_RECLEV | SOUND_MASK_LINE3 |					SOUND_MASK_DIGITAL1 | SOUND_MASK_DIGITAL2 |					SOUND_MASK_LINE2, (int *) arg);#endif			case SOUND_MIXER_CAPS:				DPF(2, "SOUND_MIXER_READ_CAPS\n");				return put_user(SOUND_CAP_EXCL_INPUT, (int *) arg);#ifdef PRIVATE_PCM_VOLUME                case SOUND_MIXER_PCM:                        /* needs to be before default: !!*/                        {                                int i;                                for (i = 0; i < MAX_PCM_CHANNELS; i++) {                                        if (sblive_pcm_volume[i].files == current->files) {                                                return put_user((int) sblive_pcm_volume[i].mixer, (int *) arg);                                        }                                }                        }#endif		default:			break;		}		switch (_IOC_NR(cmd)) {		case SOUND_MIXER_RECSRC:	/* Arg contains a bit for each recording source */			DPF(2, "SOUND_MIXER_READ_RECSRC\n");			if (card->isaps)				return put_user(0, (int *) arg);			sblive_readac97(card, AC97_RECORDSELECT, &reg);			return put_user(recsrc[reg & 7], (int *) arg);		default:			i = _IOC_NR(cmd);			DPD(4, "SOUND_MIXER_READ(%d)\n", i);			if (i >= SOUND_MIXER_NRDEVICES)				return -EINVAL;#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS			return mixer_rdch(card, i, (int *) arg);#else				/* OSS_DOCUMENTED_MIXER_SEMANTICS */			if (!volidx[i])				return -EINVAL;			return put_user(card->arrwVol[volidx[i]], (int *) arg);#endif				/* OSS_DOCUMENTED_MIXER_SEMANTICS */		}	}	/* End of _IOC_READ */	if (_IOC_DIR(cmd) != (_IOC_READ | _IOC_WRITE))		return -EINVAL;	/* _IOC_WRITE */	card->modcnt++;	switch (_IOC_NR(cmd)) {	case SOUND_MIXER_RECSRC:	/* Arg contains a bit for each recording source */		DPF(2, "SOUND_MIXER_WRITE_RECSRC\n");		if (card->isaps)			return -EINVAL;		if (get_user(val, (int *) arg))			return -EFAULT;		i = hweight32(val);		if (i == 0)			return 0;	/* val = mixer_recmask(s); */		else if (i > 1) {			sblive_readac97(card, AC97_RECORDSELECT, &reg);			val &= ~recsrc[reg & 7];		}		for (i = 0; i < 8; i++) {			if (val & recsrc[i]) {				DPD(2, "Selecting record source to be 0x%04x\n", 0x0101 * i);				sblive_writeac97(card, AC97_RECORDSELECT, 0x0101 * i);				return 0;			}		}		return 0;	default:		i = _IOC_NR(cmd);		DPD(4, "SOUND_MIXER_WRITE(%d)\n", i);		if (i >= SOUND_MIXER_NRDEVICES)			return -EINVAL;		if (get_user(val, (int *) arg))			return -EFAULT;		if (emu10k1_mixer_wrch(card, i, val))			return -EINVAL;#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS		return mixer_rdch(card, i, (int *) arg);#else				/* OSS_DOCUMENTED_MIXER_SEMANTICS */		return put_user(card->arrwVol[volidx[i]], (int *) arg);#endif				/* OSS_DOCUMENTED_MIXER_SEMANTICS */	}}static int emu10k1_mixer_open(struct inode *inode, struct file *file){	int minor = MINOR(inode->i_rdev);	struct emu10k1_card *card;	struct list_head *entry;	DPF(4, "emu10k1_mixer_open()\n");	list_for_each(entry, &emu10k1_devs) {		card = list_entry(entry, struct emu10k1_card, list);		if (card->mixer_num == minor)			break;	}	if (entry == &emu10k1_devs)		return -ENODEV;	file->private_data = card;	return 0;}static int emu10k1_mixer_release(struct inode *inode, struct file *file){	DPF(4, "emu10k1_mixer_release()\n");	return 0;}struct file_operations emu10k1_mixer_fops = {        owner:		THIS_MODULE,	llseek:		emu10k1_mixer_llseek,	ioctl:		emu10k1_mixer_ioctl,	open:		emu10k1_mixer_open,	release:	emu10k1_mixer_release,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -