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

📄 es1370.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 out;				}			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);        remove_wait_queue(&s->dma_dac2.wait, &wait);	set_current_state(TASK_RUNNING);	return ret;}/* No kernel lock - we have our own spinlock */static unsigned int es1370_poll(struct file *file, struct poll_table_struct *wait){	struct es1370_state *s = (struct es1370_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);	es1370_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 es1370_mmap(struct file *file, struct vm_area_struct *vma){	struct es1370_state *s = (struct es1370_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 es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	struct es1370_state *s = (struct es1370_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 (s->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE))				return -EINVAL;			if (val < 4000)				val = 4000;			if (val > 50000)				val = 50000;			stop_adc(s);			stop_dac2(s);			s->dma_adc.ready = s->dma_dac2.ready = 0;			spin_lock_irqsave(&s->lock, flags);			s->ctrl = (s->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(val) << CTRL_SH_PCLKDIV);			outl(s->ctrl, s->io+ES1370_REG_CONTROL);			spin_unlock_irqrestore(&s->lock, flags);		}		return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), (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)				s->sctrl |= SCTRL_R1SMB;			else				s->sctrl &= ~SCTRL_R1SMB;			outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);			spin_unlock_irqrestore(&s->lock, flags);		}		if (file->f_mode & FMODE_WRITE) {			stop_dac2(s);			s->dma_dac2.ready = 0;			spin_lock_irqsave(&s->lock, flags);			if (val)				s->sctrl |= SCTRL_P2SMB;			else				s->sctrl &= ~SCTRL_P2SMB;			outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);			spin_unlock_irqrestore(&s->lock, flags);                }		return 0;        case SNDCTL_DSP_CHANNELS:                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;				spin_lock_irqsave(&s->lock, flags);				if (val >= 2)					s->sctrl |= SCTRL_R1SMB;				else					s->sctrl &= ~SCTRL_R1SMB;				outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);				spin_unlock_irqrestore(&s->lock, flags);			}			if (file->f_mode & FMODE_WRITE) {				stop_dac2(s);				s->dma_dac2.ready = 0;				spin_lock_irqsave(&s->lock, flags);				if (val >= 2)					s->sctrl |= SCTRL_P2SMB;				else					s->sctrl &= ~SCTRL_P2SMB;				outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);				spin_unlock_irqrestore(&s->lock, flags);			}		}		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, (int *)arg);			case SNDCTL_DSP_GETFMTS: /* Returns a mask */                return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);			case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/		if (get_user(val, (int *)arg))			return -EFAULT;		if (val != AFMT_QUERY) {			if (file->f_mode & FMODE_READ) {				stop_adc(s);				s->dma_adc.ready = 0;				spin_lock_irqsave(&s->lock, flags);				if (val == AFMT_S16_LE)					s->sctrl |= SCTRL_R1SEB;				else					s->sctrl &= ~SCTRL_R1SEB;				outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);				spin_unlock_irqrestore(&s->lock, flags);			}			if (file->f_mode & FMODE_WRITE) {				stop_dac2(s);				s->dma_dac2.ready = 0;				spin_lock_irqsave(&s->lock, flags);				if (val == AFMT_S16_LE)					s->sctrl |= SCTRL_P2SEB;				else					s->sctrl &= ~SCTRL_P2SEB;				outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);				spin_unlock_irqrestore(&s->lock, flags);			}		}		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 				AFMT_S16_LE : AFMT_U8, (int *)arg);			case SNDCTL_DSP_POST:                return 0;        case SNDCTL_DSP_GETTRIGGER:		val = 0;		if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) 			val |= PCM_ENABLE_INPUT;		if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 			val |= PCM_ENABLE_OUTPUT;		return put_user(val, (int *)arg);			case SNDCTL_DSP_SETTRIGGER:		if (get_user(val, (int *)arg))			return -EFAULT;		if (file->f_mode & FMODE_READ) {			if (val & PCM_ENABLE_INPUT) {				if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))					return ret;				s->dma_adc.enabled = 1;				start_adc(s);			} else {				s->dma_adc.enabled = 0;				stop_adc(s);			}		}		if (file->f_mode & FMODE_WRITE) {			if (val & PCM_ENABLE_OUTPUT) {				if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))					return ret;				s->dma_dac2.enabled = 1;				start_dac2(s);			} else {				s->dma_dac2.enabled = 0;				stop_dac2(s);			}		}		return 0;	case SNDCTL_DSP_GETOSPACE:		if (!(file->f_mode & FMODE_WRITE))			return -EINVAL;		if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)			return val;		spin_lock_irqsave(&s->lock, flags);		es1370_update_ptr(s);		abinfo.fragsize = s->dma_dac2.fragsize;		count = s->dma_dac2.count;		if (count < 0)			count = 0;                abinfo.bytes = s->dma_dac2.dmasize - count;                abinfo.fragstotal = s->dma_dac2.numfrag;                abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;      		spin_unlock_irqrestore(&s->lock, flags);		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;	case SNDCTL_DSP_GETISPACE:		if (!(file->f_mode & FMODE_READ))			return -EINVAL;		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)			return val;		spin_lock_irqsave(&s->lock, flags);		es1370_update_ptr(s);		abinfo.fragsize = s->dma_adc.fragsize;		count = s->dma_adc.count;		if (count < 0)			count = 0;                abinfo.bytes = count;                abinfo.fragstotal = s->dma_adc.numfrag;                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      		spin_unlock_irqrestore(&s->lock, flags);		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;		        case SNDCTL_DSP_NONBLOCK:                file->f_flags |= O_NONBLOCK;                return 0;        case SNDCTL_DSP_GETODELAY:		if (!(file->f_mode & FMODE_WRITE))			return -EINVAL;		if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)			return val;		spin_lock_irqsave(&s->lock, flags);		es1370_update_ptr(s);                count = s->dma_dac2.count;		spin_unlock_irqrestore(&s->lock, flags);		if (count < 0)			count = 0;		return put_user(count, (int *)arg);        case SNDCTL_DSP_GETIPTR:		if (!(file->f_mode & FMODE_READ))			return -EINVAL;		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)			return val;		spin_lock_irqsave(&s->lock, flags);		es1370_update_ptr(s);                cinfo.bytes = s->dma_adc.total_bytes;		count = s->dma_adc.count;		if (count < 0)			count = 0;                cinfo.blocks = count >> s->dma_adc.fragshift;                cinfo.ptr = s->dma_adc.hwptr;		if (s->dma_adc.mapped)			s->dma_adc.count &= s->dma_adc.fragsize-1;		spin_unlock_irqrestore(&s->lock, flags);                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));        case SNDCTL_DSP_GETOPTR:		if (!(file->f_mode & FMODE_WRITE))			return -EINVAL;		if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)			return val;		spin_lock_irqsave(&s->lock, flags);		es1370_update_ptr(s);                cinfo.bytes = s->dma_dac2.total_bytes;		count = s->dma_dac2.count;		if (count < 0)			count = 0;                cinfo.blocks = count >> s->dma_dac2.fragshift;                cinfo.ptr = s->dma_dac2.hwptr;		if (s->dma_dac2.mapped)			s->dma_dac2.count &= s->dma_dac2.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_dac2(s)))				return val;			return put_user(s->dma_dac2.fragsize, (int *)arg);		}		if ((val = prog_dmabuf_adc(s)))			return val;

⌨️ 快捷键说明

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