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

📄 msnd_pinnacle.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
		/* digital controls */	case SOUND_MIXER_SYNTH:			/* synth vol (dsp mix) */	case SOUND_MIXER_PCM:			/* pcm vol (dsp mix) */	case SOUND_MIXER_IMIX:			/* input monitor (dsp mix) */		/* scaled by master volume */		updatemaster = 1;		break;	default:		return 0;	}	if (updatemaster) {		/* update master volume scaled controls */		update_volm(SOUND_MIXER_PCM, wCurrPlayVol);		update_volm(SOUND_MIXER_IMIX, wCurrInVol);#ifndef MSND_CLASSIC		update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol);#endif		update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS);	}	return mixer_get(d);}static void mixer_setup(void){	update_pot(SOUND_MIXER_LINE, bInPotPos, HDEXAR_IN_SET_POTS);	update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS);	update_volm(SOUND_MIXER_PCM, wCurrPlayVol);	update_volm(SOUND_MIXER_IMIX, wCurrInVol);#ifndef MSND_CLASSIC	update_pot(SOUND_MIXER_MIC, bMicPotPos, HDEXAR_MIC_SET_POTS);	update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol);#endif}static unsigned long set_recsrc(unsigned long recsrc){	if (dev.recsrc == recsrc)		return dev.recsrc;#ifdef HAVE_NORECSRC	else if (recsrc == 0)		dev.recsrc = 0;#endif	else		dev.recsrc ^= recsrc;#ifndef MSND_CLASSIC	if (dev.recsrc & SOUND_MASK_IMIX) {		if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0)			chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);	}	else if (dev.recsrc & SOUND_MASK_SYNTH) {		if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_SYNTH_IN) == 0)			chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);	}	else if ((dev.recsrc & SOUND_MASK_DIGITAL1) && test_bit(F_HAVEDIGITAL, &dev.flags)) {		if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_DAT_IN) == 0)      			chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);	}	else {#ifdef HAVE_NORECSRC		/* Select no input (?) */		dev.recsrc = 0;#else		dev.recsrc = SOUND_MASK_IMIX;		if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0)			chk_send_dsp_cmd(&dev, HDEX_AUX_REQ);#endif	}#endif /* MSND_CLASSIC */	return dev.recsrc;}static unsigned long force_recsrc(unsigned long recsrc){	dev.recsrc = 0;	return set_recsrc(recsrc);}#define set_mixer_info()							\		strncpy(info.id, "MSNDMIXER", sizeof(info.id));			\		strncpy(info.name, "MultiSound Mixer", sizeof(info.name));static int mixer_ioctl(unsigned int cmd, unsigned long arg){	if (cmd == SOUND_MIXER_INFO) {		mixer_info info;		set_mixer_info();		info.modify_counter = dev.mixer_mod_count;		return copy_to_user((void *)arg, &info, sizeof(info));	} else if (cmd == SOUND_OLD_MIXER_INFO) {		_old_mixer_info info;		set_mixer_info();		return copy_to_user((void *)arg, &info, sizeof(info));	} else if (cmd == SOUND_MIXER_PRIVATE1) {		dev.nresets = 0;		dsp_full_reset();		return 0;	} else if (((cmd >> 8) & 0xff) == 'M') {		int val = 0;		if (_SIOC_DIR(cmd) & _SIOC_WRITE) {			switch (cmd & 0xff) {			case SOUND_MIXER_RECSRC:				if (get_user(val, (int *)arg))					return -EFAULT;				val = set_recsrc(val);				break;			default:				if (get_user(val, (int *)arg))					return -EFAULT;				val = mixer_set(cmd & 0xff, val);				break;			}			++dev.mixer_mod_count;			return put_user(val, (int *)arg);		} else {			switch (cmd & 0xff) {			case SOUND_MIXER_RECSRC:				val = dev.recsrc;				break;			case SOUND_MIXER_DEVMASK:			case SOUND_MIXER_STEREODEVS:				val =   SOUND_MASK_PCM |					SOUND_MASK_LINE |					SOUND_MASK_IMIX |					SOUND_MASK_LINE1 |#ifndef MSND_CLASSIC					SOUND_MASK_MIC |					SOUND_MASK_SYNTH |#endif					SOUND_MASK_VOLUME;				break;				  			case SOUND_MIXER_RECMASK:#ifdef MSND_CLASSIC				val =   0;#else				val =   SOUND_MASK_IMIX |					SOUND_MASK_SYNTH;				if (test_bit(F_HAVEDIGITAL, &dev.flags))					val |= SOUND_MASK_DIGITAL1;#endif				break;				  			case SOUND_MIXER_CAPS:				val =   SOUND_CAP_EXCL_INPUT;				break;			default:				if ((val = mixer_get(cmd & 0xff)) < 0)					return -EINVAL;				break;			}		}		return put_user(val, (int *)arg); 	}	return -EINVAL;}static int dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	int minor = MINOR(inode->i_rdev);	if (cmd == OSS_GETVERSION) {		int sound_version = SOUND_VERSION;		return put_user(sound_version, (int *)arg);	}	if (minor == dev.dsp_minor)		return dsp_ioctl(file, cmd, arg);	else if (minor == dev.mixer_minor)		return mixer_ioctl(cmd, arg);	return -EINVAL;}static void dsp_write_flush(void){	if (!(dev.mode & FMODE_WRITE) || !test_bit(F_WRITING, &dev.flags))		return;	set_bit(F_WRITEFLUSH, &dev.flags);	interruptible_sleep_on_timeout(		&dev.writeflush,		get_play_delay_jiffies(dev.DAPF.len));	clear_bit(F_WRITEFLUSH, &dev.flags);	if (!signal_pending(current)) {		current->state = TASK_INTERRUPTIBLE;		schedule_timeout(get_play_delay_jiffies(DAP_BUFF_SIZE));	}	clear_bit(F_WRITING, &dev.flags);}static void dsp_halt(struct file *file){	if ((file ? file->f_mode : dev.mode) & FMODE_READ) {		clear_bit(F_READING, &dev.flags);		chk_send_dsp_cmd(&dev, HDEX_RECORD_STOP);		msnd_disable_irq(&dev);		if (file) {			printk(KERN_DEBUG LOGNAME ": Stopping read for %p\n", file);			dev.mode &= ~FMODE_READ;		}		clear_bit(F_AUDIO_READ_INUSE, &dev.flags);	}	if ((file ? file->f_mode : dev.mode) & FMODE_WRITE) {		if (test_bit(F_WRITING, &dev.flags)) {			dsp_write_flush();			chk_send_dsp_cmd(&dev, HDEX_PLAY_STOP);		}		msnd_disable_irq(&dev);		if (file) {			printk(KERN_DEBUG LOGNAME ": Stopping write for %p\n", file);			dev.mode &= ~FMODE_WRITE;		}		clear_bit(F_AUDIO_WRITE_INUSE, &dev.flags);	}}static int dsp_release(struct file *file){	dsp_halt(file);	return 0;}static int dsp_open(struct file *file){	if ((file ? file->f_mode : dev.mode) & FMODE_WRITE) {		set_bit(F_AUDIO_WRITE_INUSE, &dev.flags);		clear_bit(F_WRITING, &dev.flags);		msnd_fifo_make_empty(&dev.DAPF);		reset_play_queue();		if (file) {			printk(KERN_DEBUG LOGNAME ": Starting write for %p\n", file);			dev.mode |= FMODE_WRITE;		}		msnd_enable_irq(&dev);	}	if ((file ? file->f_mode : dev.mode) & FMODE_READ) {		set_bit(F_AUDIO_READ_INUSE, &dev.flags);		clear_bit(F_READING, &dev.flags);		msnd_fifo_make_empty(&dev.DARF);		reset_record_queue();		if (file) {			printk(KERN_DEBUG LOGNAME ": Starting read for %p\n", file);			dev.mode |= FMODE_READ;		}		msnd_enable_irq(&dev);	}	return 0;}static void set_default_play_audio_parameters(void){	dev.play_sample_size = DEFSAMPLESIZE;	dev.play_sample_rate = DEFSAMPLERATE;	dev.play_channels = DEFCHANNELS;}static void set_default_rec_audio_parameters(void){	dev.rec_sample_size = DEFSAMPLESIZE;	dev.rec_sample_rate = DEFSAMPLERATE;	dev.rec_channels = DEFCHANNELS;}static void set_default_audio_parameters(void){	set_default_play_audio_parameters();	set_default_rec_audio_parameters();}static int dev_open(struct inode *inode, struct file *file){	int minor = MINOR(inode->i_rdev);	int err = 0;	if (minor == dev.dsp_minor) {		if ((file->f_mode & FMODE_WRITE &&		     test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) ||		    (file->f_mode & FMODE_READ &&		     test_bit(F_AUDIO_READ_INUSE, &dev.flags)))			return -EBUSY;		if ((err = dsp_open(file)) >= 0) {			dev.nresets = 0;			if (file->f_mode & FMODE_WRITE) {				set_default_play_audio_parameters();				if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags))					dev.play_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0;				else					dev.play_ndelay = 0;			}			if (file->f_mode & FMODE_READ) {				set_default_rec_audio_parameters();				dev.rec_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0;			}		}	}	else if (minor == dev.mixer_minor) {		/* nothing */	} else		err = -EINVAL;	return err;}static int dev_release(struct inode *inode, struct file *file){	int minor = MINOR(inode->i_rdev);	int err = 0;	lock_kernel();	if (minor == dev.dsp_minor)		err = dsp_release(file);	else if (minor == dev.mixer_minor) {		/* nothing */	} else		err = -EINVAL;	unlock_kernel();	return err;}static __inline__ int pack_DARQ_to_DARF(register int bank){	register int size, n, timeout = 3;	register WORD wTmp;	LPDAQD DAQD;	/* Increment the tail and check for queue wrap */	wTmp = isa_readw(dev.DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size);	if (wTmp > isa_readw(dev.DARQ + JQS_wSize))		wTmp = 0;	while (wTmp == isa_readw(dev.DARQ + JQS_wHead) && timeout--)		udelay(1);	isa_writew(wTmp, dev.DARQ + JQS_wTail);	/* Get our digital audio queue struct */	DAQD = bank * DAQDS__size + dev.base + DARQ_DATA_BUFF;	/* Get length of data */	size = isa_readw(DAQD + DAQDS_wSize);	/* Read data from the head (unprotected bank 1 access okay           since this is only called inside an interrupt) */	outb(HPBLKSEL_1, dev.io + HP_BLKS);	if ((n = msnd_fifo_write(		&dev.DARF,		(char *)(dev.base + bank * DAR_BUFF_SIZE),		size, 0)) <= 0) {		outb(HPBLKSEL_0, dev.io + HP_BLKS);		return n;	}	outb(HPBLKSEL_0, dev.io + HP_BLKS);	return 1;}static __inline__ int pack_DAPF_to_DAPQ(register int start){	register WORD DAPQ_tail;	register int protect = start, nbanks = 0;	LPDAQD DAQD;	DAPQ_tail = isa_readw(dev.DAPQ + JQS_wTail);	while (DAPQ_tail != isa_readw(dev.DAPQ + JQS_wHead) || start) {		register int bank_num = DAPQ_tail / PCTODSP_OFFSET(DAQDS__size);		register int n;		unsigned long flags;		/* Write the data to the new tail */		if (protect) {			/* Critical section: protect fifo in non-interrupt */			spin_lock_irqsave(&dev.lock, flags);			if ((n = msnd_fifo_read(				&dev.DAPF,				(char *)(dev.base + bank_num * DAP_BUFF_SIZE),				DAP_BUFF_SIZE, 0)) < 0) {				spin_unlock_irqrestore(&dev.lock, flags);				return n;			}			spin_unlock_irqrestore(&dev.lock, flags);		} else {			if ((n = msnd_fifo_read(				&dev.DAPF,				(char *)(dev.base + bank_num * DAP_BUFF_SIZE),				DAP_BUFF_SIZE, 0)) < 0) {				return n;			}		}		if (!n)			break;		if (start)			start = 0;		/* Get our digital audio queue struct */		DAQD = bank_num * DAQDS__size + dev.base + DAPQ_DATA_BUFF;		/* Write size of this bank */		isa_writew(n, DAQD + DAQDS_wSize);		++nbanks;		/* Then advance the tail */		DAPQ_tail = (++bank_num % 3) * PCTODSP_OFFSET(DAQDS__size);		isa_writew(DAPQ_tail, dev.DAPQ + JQS_wTail);		/* Tell the DSP to play the bank */		msnd_send_dsp_cmd(&dev, HDEX_PLAY_START);	}	return nbanks;}static int dsp_read(char *buf, size_t len){	int count = len;	while (count > 0) {		int n;		unsigned long flags;		/* Critical section: protect fifo in non-interrupt */		spin_lock_irqsave(&dev.lock, flags);		if ((n = msnd_fifo_read(&dev.DARF, buf, count, 1)) < 0) {			printk(KERN_WARNING LOGNAME ": FIFO read error\n");			spin_unlock_irqrestore(&dev.lock, flags);			return n;		}		spin_unlock_irqrestore(&dev.lock, flags);		buf += n;		count -= n;		if (!test_bit(F_READING, &dev.flags) && dev.mode & FMODE_READ) {			dev.last_recbank = -1;			if (chk_send_dsp_cmd(&dev, HDEX_RECORD_START) == 0)				set_bit(F_READING, &dev.flags);		}		if (dev.rec_ndelay)			return count == len ? -EAGAIN : len - count;		if (count > 0) {			set_bit(F_READBLOCK, &dev.flags);			if (!interruptible_sleep_on_timeout(				&dev.readblock,				get_rec_delay_jiffies(DAR_BUFF_SIZE)))				clear_bit(F_READING, &dev.flags);			clear_bit(F_READBLOCK, &dev.flags);			if (signal_pending(current))				return -EINTR;		}	}	return len - count;}static int dsp_write(const char *buf, size_t len){	int count = len;	while (count > 0) {		int n;		unsigned long flags;		/* Critical section: protect fifo in non-interrupt */		spin_lock_irqsave(&dev.lock, flags);		if ((n = msnd_fifo_write(&dev.DAPF, buf, count, 1)) < 0) {			printk(KERN_WARNING LOGNAME ": FIFO write error\n");

⌨️ 快捷键说明

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