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

📄 es1371.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
static int es1371_release_mixdev(struct inode *inode, struct file *file){	struct es1371_state *s = (struct es1371_state *)file->private_data;		VALIDATE_STATE(s);	return 0;}static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	struct es1371_state *s = (struct es1371_state *)file->private_data;	struct ac97_codec *codec = &s->codec;	return mixdev_ioctl(codec, cmd, arg);}static /*const*/ struct file_operations es1371_mixer_fops = {	owner:		THIS_MODULE,	llseek:		no_llseek,	ioctl:		es1371_ioctl_mixdev,	open:		es1371_open_mixdev,	release:	es1371_release_mixdev,};/* --------------------------------------------------------------------- */static int drain_dac1(struct es1371_state *s, int nonblock){	DECLARE_WAITQUEUE(wait, current);	unsigned long flags;	int count, tmo;		if (s->dma_dac1.mapped || !s->dma_dac1.ready)		return 0;        add_wait_queue(&s->dma_dac1.wait, &wait);        for (;;) {		__set_current_state(TASK_INTERRUPTIBLE);                spin_lock_irqsave(&s->lock, flags);		count = s->dma_dac1.count;                spin_unlock_irqrestore(&s->lock, flags);		if (count <= 0)			break;		if (signal_pending(current))                        break;                if (nonblock) {                        remove_wait_queue(&s->dma_dac1.wait, &wait);                        set_current_state(TASK_RUNNING);                        return -EBUSY;                }		tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 / s->dac1rate;		tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];		if (!schedule_timeout(tmo + 1))			DBG(printk(KERN_DEBUG PFX "dac1 dma timed out??\n");)        }        remove_wait_queue(&s->dma_dac1.wait, &wait);        set_current_state(TASK_RUNNING);        if (signal_pending(current))                return -ERESTARTSYS;        return 0;}static int drain_dac2(struct es1371_state *s, int nonblock){	DECLARE_WAITQUEUE(wait, current);	unsigned long flags;	int count, tmo;	if (s->dma_dac2.mapped || !s->dma_dac2.ready)		return 0;        add_wait_queue(&s->dma_dac2.wait, &wait);        for (;;) {		__set_current_state(TASK_UNINTERRUPTIBLE);                spin_lock_irqsave(&s->lock, flags);		count = s->dma_dac2.count;                spin_unlock_irqrestore(&s->lock, flags);		if (count <= 0)			break;		if (signal_pending(current))                        break;                if (nonblock) {                        remove_wait_queue(&s->dma_dac2.wait, &wait);                        set_current_state(TASK_RUNNING);                        return -EBUSY;                }		tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 / s->dac2rate;		tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];		if (!schedule_timeout(tmo + 1))			DBG(printk(KERN_DEBUG PFX "dac2 dma timed out??\n");)        }        remove_wait_queue(&s->dma_dac2.wait, &wait);        set_current_state(TASK_RUNNING);        if (signal_pending(current))                return -ERESTARTSYS;        return 0;}/* --------------------------------------------------------------------- */static ssize_t es1371_read(struct file *file, char *buffer, size_t count, loff_t *ppos){	struct es1371_state *s = (struct es1371_state *)file->private_data;	DECLARE_WAITQUEUE(wait, current);	ssize_t ret = 0;	unsigned long flags;	unsigned swptr;	int cnt;	VALIDATE_STATE(s);	if (ppos != &file->f_pos)		return -ESPIPE;	if (s->dma_adc.mapped)		return -ENXIO;	if (!access_ok(VERIFY_WRITE, buffer, count))		return -EFAULT;	down(&s->sem);	if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))		goto out2;		add_wait_queue(&s->dma_adc.wait, &wait);	while (count > 0) {		spin_lock_irqsave(&s->lock, flags);		swptr = s->dma_adc.swptr;		cnt = s->dma_adc.dmasize-swptr;		if (s->dma_adc.count < cnt)			cnt = s->dma_adc.count;		if (cnt <= 0)			__set_current_state(TASK_INTERRUPTIBLE);		spin_unlock_irqrestore(&s->lock, flags);		if (cnt > count)			cnt = count;		if (cnt <= 0) {			if (s->dma_adc.enabled)				start_adc(s);			if (file->f_flags & O_NONBLOCK) {				if (!ret)					ret = -EAGAIN;				goto out;			}			up(&s->sem);			schedule();			if (signal_pending(current)) {				if (!ret)					ret = -ERESTARTSYS;				goto out2;			}			down(&s->sem);			if (s->dma_adc.mapped)			{				ret = -ENXIO;				goto out;			}			continue;		}		if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {			if (!ret)				ret = -EFAULT;			goto out;		}		swptr = (swptr + cnt) % s->dma_adc.dmasize;		spin_lock_irqsave(&s->lock, flags);		s->dma_adc.swptr = swptr;		s->dma_adc.count -= cnt;		spin_unlock_irqrestore(&s->lock, flags);		count -= cnt;		buffer += cnt;		ret += cnt;		if (s->dma_adc.enabled)			start_adc(s);	}out:	up(&s->sem);out2:	remove_wait_queue(&s->dma_adc.wait, &wait);	set_current_state(TASK_RUNNING);	return ret;}static ssize_t es1371_write(struct file *file, const char *buffer, size_t count, loff_t *ppos){	struct es1371_state *s = (struct es1371_state *)file->private_data;	DECLARE_WAITQUEUE(wait, current);	ssize_t ret;	unsigned long flags;	unsigned swptr;	int cnt;	VALIDATE_STATE(s);	if (ppos != &file->f_pos)		return -ESPIPE;	if (s->dma_dac2.mapped)		return -ENXIO;	if (!access_ok(VERIFY_READ, buffer, count))		return -EFAULT;	down(&s->sem);		if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))		goto out3;	ret = 0;	add_wait_queue(&s->dma_dac2.wait, &wait);	while (count > 0) {		spin_lock_irqsave(&s->lock, flags);		if (s->dma_dac2.count < 0) {			s->dma_dac2.count = 0;			s->dma_dac2.swptr = s->dma_dac2.hwptr;		}		swptr = s->dma_dac2.swptr;		cnt = s->dma_dac2.dmasize-swptr;		if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize)			cnt = s->dma_dac2.dmasize - s->dma_dac2.count;		if (cnt <= 0)			__set_current_state(TASK_INTERRUPTIBLE);		spin_unlock_irqrestore(&s->lock, flags);		if (cnt > count)			cnt = count;		if (cnt <= 0) {			if (s->dma_dac2.enabled)				start_dac2(s);			if (file->f_flags & O_NONBLOCK) {				if (!ret)					ret = -EAGAIN;				goto out;			}				up(&s->sem);			schedule();			if (signal_pending(current)) {				if (!ret)					ret = -ERESTARTSYS;				goto out2;			}			down(&s->sem);			if (s->dma_dac2.mapped)			{				ret = -ENXIO;				goto out;			}			continue;		}		if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) {			if (!ret)				ret = -EFAULT;			goto out;		}		swptr = (swptr + cnt) % s->dma_dac2.dmasize;		spin_lock_irqsave(&s->lock, flags);		s->dma_dac2.swptr = swptr;		s->dma_dac2.count += cnt;		s->dma_dac2.endcleared = 0;		spin_unlock_irqrestore(&s->lock, flags);		count -= cnt;		buffer += cnt;		ret += cnt;		if (s->dma_dac2.enabled)			start_dac2(s);	}out:	up(&s->sem);out2:	remove_wait_queue(&s->dma_dac2.wait, &wait);out3:		set_current_state(TASK_RUNNING);	return ret;}/* No kernel lock - we have our own spinlock */static unsigned int es1371_poll(struct file *file, struct poll_table_struct *wait){	struct es1371_state *s = (struct es1371_state *)file->private_data;	unsigned long flags;	unsigned int mask = 0;	VALIDATE_STATE(s);	if (file->f_mode & FMODE_WRITE) {		if (!s->dma_dac2.ready && prog_dmabuf_dac2(s))			return 0;		poll_wait(file, &s->dma_dac2.wait, wait);	}	if (file->f_mode & FMODE_READ) {		if (!s->dma_adc.ready && prog_dmabuf_adc(s))			return 0;		poll_wait(file, &s->dma_adc.wait, wait);	}	spin_lock_irqsave(&s->lock, flags);	es1371_update_ptr(s);	if (file->f_mode & FMODE_READ) {			if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)				mask |= POLLIN | POLLRDNORM;	}	if (file->f_mode & FMODE_WRITE) {		if (s->dma_dac2.mapped) {			if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) 				mask |= POLLOUT | POLLWRNORM;		} else {			if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize)				mask |= POLLOUT | POLLWRNORM;		}	}	spin_unlock_irqrestore(&s->lock, flags);	return mask;}static int es1371_mmap(struct file *file, struct vm_area_struct *vma){	struct es1371_state *s = (struct es1371_state *)file->private_data;	struct dmabuf *db;	int ret = 0;	unsigned long size;	VALIDATE_STATE(s);	lock_kernel();	down(&s->sem);		if (vma->vm_flags & VM_WRITE) {		if ((ret = prog_dmabuf_dac2(s)) != 0) {			goto out;		}		db = &s->dma_dac2;	} else if (vma->vm_flags & VM_READ) {		if ((ret = prog_dmabuf_adc(s)) != 0) {			goto out;		}		db = &s->dma_adc;	} else {		ret = -EINVAL;		goto out;	}	if (vma->vm_pgoff != 0) {		ret = -EINVAL;		goto out;	}	size = vma->vm_end - vma->vm_start;	if (size > (PAGE_SIZE << db->buforder)) {		ret = -EINVAL;		goto out;	}	if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) {		ret = -EAGAIN;		goto out;	}	db->mapped = 1;out:	up(&s->sem);	unlock_kernel();	return ret;}static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	struct es1371_state *s = (struct es1371_state *)file->private_data;	unsigned long flags;        audio_buf_info abinfo;        count_info cinfo;	int count;	int val, mapped, ret;	VALIDATE_STATE(s);        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) ||		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);	switch (cmd) {	case OSS_GETVERSION:		return put_user(SOUND_VERSION, (int *)arg);	case SNDCTL_DSP_SYNC:		if (file->f_mode & FMODE_WRITE)			return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/);		return 0;			case SNDCTL_DSP_SETDUPLEX:		return 0;	case SNDCTL_DSP_GETCAPS:		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);		        case SNDCTL_DSP_RESET:		if (file->f_mode & FMODE_WRITE) {			stop_dac2(s);			synchronize_irq();			s->dma_dac2.swptr = s->dma_dac2.hwptr = s->dma_dac2.count = s->dma_dac2.total_bytes = 0;		}		if (file->f_mode & FMODE_READ) {			stop_adc(s);			synchronize_irq();			s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;		}		return 0;        case SNDCTL_DSP_SPEED:                if (get_user(val, (int *)arg))			return -EFAULT;		if (val >= 0) {			if (file->f_mode & FMODE_READ) {				stop_adc(s);				s->dma_adc.ready = 0;				set_adc_rate(s, val);			}			if (file->f_mode & FMODE_WRITE) {				stop_dac2(s);				s->dma_dac2.ready = 0;				set_dac2_rate(s, val);			}		}		return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, (int *)arg);        case SNDCTL_DSP_STEREO:		if (get_user(val, (int *)arg))			return -EFAULT;		if (file->f_mode & FMODE_READ) {			stop_adc(s);			s->dma_adc.ready = 0;			spin_lock_irqsave(&s->lock, flags);			if (val)

⌨️ 快捷键说明

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