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

📄 sonicvibes.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 5 页
字号:
			count = 0;                cinfo.blocks = count >> s->dma_dac.fragshift;                cinfo.ptr = s->dma_dac.hwptr;		if (s->dma_dac.mapped)			s->dma_dac.count &= s->dma_dac.fragsize-1;		spin_unlock_irqrestore(&s->lock, flags);                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));        case SNDCTL_DSP_GETBLKSIZE:		if (file->f_mode & FMODE_WRITE) {			if ((val = prog_dmabuf(s, 0)))				return val;			return put_user(s->dma_dac.fragsize, (int *)arg);		}		if ((val = prog_dmabuf(s, 1)))			return val;		return put_user(s->dma_adc.fragsize, (int *)arg);        case SNDCTL_DSP_SETFRAGMENT:                if (get_user(val, (int *)arg))			return -EFAULT;		if (file->f_mode & FMODE_READ) {			s->dma_adc.ossfragshift = val & 0xffff;			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;			if (s->dma_adc.ossfragshift < 4)				s->dma_adc.ossfragshift = 4;			if (s->dma_adc.ossfragshift > 15)				s->dma_adc.ossfragshift = 15;			if (s->dma_adc.ossmaxfrags < 4)				s->dma_adc.ossmaxfrags = 4;		}		if (file->f_mode & FMODE_WRITE) {			s->dma_dac.ossfragshift = val & 0xffff;			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;			if (s->dma_dac.ossfragshift < 4)				s->dma_dac.ossfragshift = 4;			if (s->dma_dac.ossfragshift > 15)				s->dma_dac.ossfragshift = 15;			if (s->dma_dac.ossmaxfrags < 4)				s->dma_dac.ossmaxfrags = 4;		}		return 0;        case SNDCTL_DSP_SUBDIVIDE:		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))			return -EINVAL;                if (get_user(val, (int *)arg))			return -EFAULT;		if (val != 1 && val != 2 && val != 4)			return -EINVAL;		if (file->f_mode & FMODE_READ)			s->dma_adc.subdivision = val;		if (file->f_mode & FMODE_WRITE)			s->dma_dac.subdivision = val;		return 0;        case SOUND_PCM_READ_RATE:		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);        case SOUND_PCM_READ_CHANNELS:		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT) 					   : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, (int *)arg);        case SOUND_PCM_READ_BITS:		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT) 					   : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? 16 : 8, (int *)arg);        case SOUND_PCM_WRITE_FILTER:        case SNDCTL_DSP_SETSYNCRO:        case SOUND_PCM_READ_FILTER:                return -EINVAL;			}	return mixer_ioctl(s, cmd, arg);}static int sv_open(struct inode *inode, struct file *file){	int minor = MINOR(inode->i_rdev);	DECLARE_WAITQUEUE(wait, current);	unsigned char fmtm = ~0, fmts = 0;	struct list_head *list;	struct sv_state *s;	for (list = devs.next; ; list = list->next) {		if (list == &devs)			return -ENODEV;		s = list_entry(list, struct sv_state, devs);		if (!((s->dev_audio ^ minor) & ~0xf))			break;	}       	VALIDATE_STATE(s);	file->private_data = s;	/* wait for device to become free */	down(&s->open_sem);	while (s->open_mode & file->f_mode) {		if (file->f_flags & O_NONBLOCK) {			up(&s->open_sem);			return -EBUSY;		}		add_wait_queue(&s->open_wait, &wait);		__set_current_state(TASK_INTERRUPTIBLE);		up(&s->open_sem);		schedule();		remove_wait_queue(&s->open_wait, &wait);		set_current_state(TASK_RUNNING);		if (signal_pending(current))			return -ERESTARTSYS;		down(&s->open_sem);	}	if (file->f_mode & FMODE_READ) {		fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT);		if ((minor & 0xf) == SND_DEV_DSP16)			fmts |= SV_CFMT_16BIT << SV_CFMT_CSHIFT;		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;		s->dma_adc.enabled = 1;		set_adc_rate(s, 8000);	}	if (file->f_mode & FMODE_WRITE) {		fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_ASHIFT);		if ((minor & 0xf) == SND_DEV_DSP16)			fmts |= SV_CFMT_16BIT << SV_CFMT_ASHIFT;		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;		s->dma_dac.enabled = 1;		set_dac_rate(s, 8000);	}	set_fmt(s, fmtm, fmts);	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);	up(&s->open_sem);	return 0;}static int sv_release(struct inode *inode, struct file *file){	struct sv_state *s = (struct sv_state *)file->private_data;	VALIDATE_STATE(s);	lock_kernel();	if (file->f_mode & FMODE_WRITE)		drain_dac(s, file->f_flags & O_NONBLOCK);	down(&s->open_sem);	if (file->f_mode & FMODE_WRITE) {		stop_dac(s);		dealloc_dmabuf(s, &s->dma_dac);	}	if (file->f_mode & FMODE_READ) {		stop_adc(s);		dealloc_dmabuf(s, &s->dma_adc);	}	s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);	wake_up(&s->open_wait);	up(&s->open_sem);	unlock_kernel();	return 0;}static /*const*/ struct file_operations sv_audio_fops = {	owner:		THIS_MODULE,	llseek:		no_llseek,	read:		sv_read,	write:		sv_write,	poll:		sv_poll,	ioctl:		sv_ioctl,	mmap:		sv_mmap,	open:		sv_open,	release:	sv_release,};/* --------------------------------------------------------------------- */static ssize_t sv_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos){	struct sv_state *s = (struct sv_state *)file->private_data;	DECLARE_WAITQUEUE(wait, current);	ssize_t ret;	unsigned long flags;	unsigned ptr;	int cnt;	VALIDATE_STATE(s);	if (ppos != &file->f_pos)		return -ESPIPE;	if (!access_ok(VERIFY_WRITE, buffer, count))		return -EFAULT;	if (count == 0)		return 0;	ret = 0;	add_wait_queue(&s->midi.iwait, &wait);	while (count > 0) {		spin_lock_irqsave(&s->lock, flags);		ptr = s->midi.ird;		cnt = MIDIINBUF - ptr;		if (s->midi.icnt < cnt)			cnt = s->midi.icnt;		if (cnt <= 0)                      __set_current_state(TASK_INTERRUPTIBLE);		spin_unlock_irqrestore(&s->lock, flags);		if (cnt > count)			cnt = count;		if (cnt <= 0) {                      if (file->f_flags & O_NONBLOCK) {                              if (!ret)                                      ret = -EAGAIN;                              break;                      }                      schedule();                      if (signal_pending(current)) {                              if (!ret)                                      ret = -ERESTARTSYS;                              break;                      }			continue;		}		if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {			if (!ret)				ret = -EFAULT;			break;		}		ptr = (ptr + cnt) % MIDIINBUF;		spin_lock_irqsave(&s->lock, flags);		s->midi.ird = ptr;		s->midi.icnt -= cnt;		spin_unlock_irqrestore(&s->lock, flags);		count -= cnt;		buffer += cnt;		ret += cnt;		break;	}	__set_current_state(TASK_RUNNING);	remove_wait_queue(&s->midi.iwait, &wait);	return ret;}static ssize_t sv_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos){	struct sv_state *s = (struct sv_state *)file->private_data;	DECLARE_WAITQUEUE(wait, current);	ssize_t ret;	unsigned long flags;	unsigned ptr;	int cnt;	VALIDATE_STATE(s);	if (ppos != &file->f_pos)		return -ESPIPE;	if (!access_ok(VERIFY_READ, buffer, count))		return -EFAULT;	if (count == 0)		return 0;	ret = 0;        add_wait_queue(&s->midi.owait, &wait);	while (count > 0) {		spin_lock_irqsave(&s->lock, flags);		ptr = s->midi.owr;		cnt = MIDIOUTBUF - ptr;		if (s->midi.ocnt + cnt > MIDIOUTBUF)			cnt = MIDIOUTBUF - s->midi.ocnt;		if (cnt <= 0) {			__set_current_state(TASK_INTERRUPTIBLE);			sv_handle_midi(s);		}		spin_unlock_irqrestore(&s->lock, flags);		if (cnt > count)			cnt = count;		if (cnt <= 0) {			if (file->f_flags & O_NONBLOCK) {				if (!ret)					ret = -EAGAIN;				break;			}			schedule();			if (signal_pending(current)) {				if (!ret)					ret = -ERESTARTSYS;				break;			}			continue;		}		if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {			if (!ret)				ret = -EFAULT;			break;		}		ptr = (ptr + cnt) % MIDIOUTBUF;		spin_lock_irqsave(&s->lock, flags);		s->midi.owr = ptr;		s->midi.ocnt += cnt;		spin_unlock_irqrestore(&s->lock, flags);		count -= cnt;		buffer += cnt;		ret += cnt;		spin_lock_irqsave(&s->lock, flags);		sv_handle_midi(s);		spin_unlock_irqrestore(&s->lock, flags);	}	__set_current_state(TASK_RUNNING);	remove_wait_queue(&s->midi.owait, &wait);	return ret;}/* No kernel lock - we have our own spinlock */static unsigned int sv_midi_poll(struct file *file, struct poll_table_struct *wait){	struct sv_state *s = (struct sv_state *)file->private_data;	unsigned long flags;	unsigned int mask = 0;	VALIDATE_STATE(s);	if (file->f_mode & FMODE_WRITE)		poll_wait(file, &s->midi.owait, wait);	if (file->f_mode & FMODE_READ)		poll_wait(file, &s->midi.iwait, wait);	spin_lock_irqsave(&s->lock, flags);	if (file->f_mode & FMODE_READ) {		if (s->midi.icnt > 0)			mask |= POLLIN | POLLRDNORM;	}	if (file->f_mode & FMODE_WRITE) {		if (s->midi.ocnt < MIDIOUTBUF)			mask |= POLLOUT | POLLWRNORM;	}	spin_unlock_irqrestore(&s->lock, flags);	return mask;}static int sv_midi_open(struct inode *inode, struct file *file){	int minor = MINOR(inode->i_rdev);	DECLARE_WAITQUEUE(wait, current);	unsigned long flags;	struct list_head *list;	struct sv_state *s;	for (list = devs.next; ; list = list->next) {		if (list == &devs)			return -ENODEV;		s = list_entry(list, struct sv_state, devs);		if (s->dev_midi == minor)			break;	}       	VALIDATE_STATE(s);	file->private_data = s;	/* wait for device to become free */	down(&s->open_sem);	while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {		if (file->f_flags & O_NONBLOCK) {			up(&s->open_sem);			return -EBUSY;		}		add_wait_queue(&s->open_wait, &wait);		__set_current_state(TASK_INTERRUPTIBLE);		up(&s->open_sem);		schedule();		remove_wait_queue(&s->open_wait, &wait);		set_current_state(TASK_RUNNING);		if (signal_pending(current))			return -ERESTARTSYS;		down(&s->open_sem);	}	spin_lock_irqsave(&s->lock, flags);	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;		//outb(inb(s->ioenh + SV_CODEC_CONTROL) | SV_CCTRL_WAVETABLE, s->ioenh + SV_CODEC_CONTROL);		outb(inb(s->ioenh + SV_CODEC_INTMASK) | SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK);		wrindir(s, SV_CIUARTCONTROL, 5); /* output MIDI data to external and internal synth */		wrindir(s, SV_CIWAVETABLESRC, 1); /* Wavetable in PC RAM */		outb(0xff, s->iomidi+1); /* reset command */		outb(0x3f, s->iomidi+1); /* uart command */		if (!(inb(s->iomidi+1) & 0x80))			inb(s->iomidi);		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;		init_timer(&s->midi.timer);		s->midi.timer.expires = jiffies+1;		s->midi.timer.data = (unsigned long)s;		s->midi.timer.function = sv_midi_timer;		add_timer(&s->midi.timer);	}	if (file->f_mode & FMODE_READ) {		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;	}	if (file->f_mode & FMODE_WRITE) {		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;	}	spin_unlock_irqrestore(&s->lock, flags);	s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);	up(&s->open_sem);	return 0;}static int sv_midi_release(struct inode *inode, struct file *file){	struct sv_state *s = (struct sv_state *)file->private_data;	DECLARE_WAITQUEUE(wait, current);	unsigned long flags;	unsigned count, tmo;	VALIDATE_STATE(s);	lock_kernel();	if (file->f_mode & FMODE_WRITE) {		add_wait_queue(&s->midi.owait, &wait);		for (;;) {			__set_current_state(TASK_INTERRUPTIBLE);			spin_lock_irqsave(&s->lock, flags);			count = s->midi.ocnt;			spin_unlock_irqrestore(&s->lock, flags);			if (count <= 0)				break;			if (signal_pending(current))				break;			if (file->f_flags & O_NONBLOCK)				break;			tmo = (count * HZ) / 3100;			if (!schedule_timeout(tmo ? : 1) && tmo)				printk(KERN_DEBUG "sv: midi timed out??\n");		}		remove_wait_queue(&s->midi.owait, &wait);		set_current_state(TASK_RUNNING);	}	down(&s->open_sem);	s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE);	spin_lock_irqsave(&s->lock, flags);	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {		outb(inb(s->ioenh + SV_CODEC_INTMASK) & ~SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK);		del_timer(&s->midi.timer);			}	spin_unlock_irqrestore(&s->lock, flags);	wake_up(&s->open_wait);	up(&s->open_sem);	unlock_kernel();	return 0;}static /*const*/ struct file_operations sv_midi_fops = {	owner:		THIS_MODULE,	llseek:		no_llseek,	read:		sv_midi_read,	write:		sv_midi_write,	poll:		sv_midi_poll,	open:		sv_midi_open,	release:	sv_midi_release,};/* --------------------------------------------------------------------- */static int sv_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	static const unsigned char op_offset[18] = {		0x00, 0x01, 0x02, 0x03, 0x04, 0x05,		0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,		0x10, 0x11, 0x1

⌨️ 快捷键说明

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