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

📄 es1370.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
		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_dac2.ossfragshift = val & 0xffff;			s->dma_dac2.ossmaxfrags = (val >> 16) & 0xffff;			if (s->dma_dac2.ossfragshift < 4)				s->dma_dac2.ossfragshift = 4;			if (s->dma_dac2.ossfragshift > 15)				s->dma_dac2.ossfragshift = 15;			if (s->dma_dac2.ossmaxfrags < 4)				s->dma_dac2.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_dac2.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_dac2.subdivision = val;		return 0;        case SOUND_PCM_READ_RATE:		return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), (int *)arg);        case SOUND_PCM_READ_CHANNELS:		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ?				2 : 1, (int *)arg);        case SOUND_PCM_READ_BITS:		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 				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 es1370_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 es1370_state *s;	for (list = devs.next; ; list = list->next) {		if (list == &devs)			return -ENODEV;		s = list_entry(list, struct es1370_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);	}	spin_lock_irqsave(&s->lock, flags);	if (!(s->open_mode & (FMODE_READ|FMODE_WRITE)))		s->ctrl = (s->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV);	if (file->f_mode & FMODE_READ) {		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;		s->dma_adc.enabled = 1;		s->sctrl &= ~SCTRL_R1FMT;		if ((minor & 0xf) == SND_DEV_DSP16)			s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_R1FMT;		else			s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_R1FMT;	}	if (file->f_mode & FMODE_WRITE) {		s->dma_dac2.ossfragshift = s->dma_dac2.ossmaxfrags = s->dma_dac2.subdivision = 0;		s->dma_dac2.enabled = 1;		s->sctrl &= ~SCTRL_P2FMT;		if ((minor & 0xf) == SND_DEV_DSP16)			s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_P2FMT;		else			s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_P2FMT;	}	outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);	outl(s->ctrl, s->io+ES1370_REG_CONTROL);	spin_unlock_irqrestore(&s->lock, flags);	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);	up(&s->open_sem);	init_MUTEX(&s->sem);	return 0;}static int es1370_release(struct inode *inode, struct file *file){	struct es1370_state *s = (struct es1370_state *)file->private_data;	VALIDATE_STATE(s);	lock_kernel();	if (file->f_mode & FMODE_WRITE)		drain_dac2(s, file->f_flags & O_NONBLOCK);	down(&s->open_sem);	if (file->f_mode & FMODE_WRITE) {		stop_dac2(s);		synchronize_irq();		dealloc_dmabuf(s, &s->dma_dac2);	}	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 es1370_audio_fops = {	owner:		THIS_MODULE,	llseek:		no_llseek,	read:		es1370_read,	write:		es1370_write,	poll:		es1370_poll,	ioctl:		es1370_ioctl,	mmap:		es1370_mmap,	open:		es1370_open,	release:	es1370_release,};/* --------------------------------------------------------------------- */static ssize_t es1370_write_dac(struct file *file, const char *buffer, size_t count, loff_t *ppos){	struct es1370_state *s = (struct es1370_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_dac1.mapped)		return -ENXIO;	if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))		return ret;	if (!access_ok(VERIFY_READ, buffer, count))		return -EFAULT;        add_wait_queue(&s->dma_dac1.wait, &wait);	while (count > 0) {		spin_lock_irqsave(&s->lock, flags);		if (s->dma_dac1.count < 0) {			s->dma_dac1.count = 0;			s->dma_dac1.swptr = s->dma_dac1.hwptr;		}		swptr = s->dma_dac1.swptr;		cnt = s->dma_dac1.dmasize-swptr;		if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize)			cnt = s->dma_dac1.dmasize - s->dma_dac1.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_dac1.enabled)				start_dac1(s);			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->dma_dac1.rawbuf + swptr, buffer, cnt)) {			if (!ret)				ret = -EFAULT;			break;		}		swptr = (swptr + cnt) % s->dma_dac1.dmasize;		spin_lock_irqsave(&s->lock, flags);		s->dma_dac1.swptr = swptr;		s->dma_dac1.count += cnt;		s->dma_dac1.endcleared = 0;		spin_unlock_irqrestore(&s->lock, flags);		count -= cnt;		buffer += cnt;		ret += cnt;		if (s->dma_dac1.enabled)			start_dac1(s);	}        remove_wait_queue(&s->dma_dac1.wait, &wait);	set_current_state(TASK_RUNNING);	return ret;}/* No kernel lock - we have our own spinlock */static unsigned int es1370_poll_dac(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 (!s->dma_dac1.ready && prog_dmabuf_dac1(s))		return 0;	poll_wait(file, &s->dma_dac1.wait, wait);	spin_lock_irqsave(&s->lock, flags);	es1370_update_ptr(s);	if (s->dma_dac1.mapped) {		if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)			mask |= POLLOUT | POLLWRNORM;	} else {		if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize)			mask |= POLLOUT | POLLWRNORM;	}	spin_unlock_irqrestore(&s->lock, flags);	return mask;}static int es1370_mmap_dac(struct file *file, struct vm_area_struct *vma){	struct es1370_state *s = (struct es1370_state *)file->private_data;	int ret;	unsigned long size;	VALIDATE_STATE(s);	if (!(vma->vm_flags & VM_WRITE))		return -EINVAL;	lock_kernel();	if ((ret = prog_dmabuf_dac1(s)) != 0)		goto out;	ret = -EINVAL;	if (vma->vm_pgoff != 0)		goto out;	size = vma->vm_end - vma->vm_start;	if (size > (PAGE_SIZE << s->dma_dac1.buforder))		goto out;	ret = -EAGAIN;	if (remap_page_range(vma->vm_start, virt_to_phys(s->dma_dac1.rawbuf), size, vma->vm_page_prot))		goto out;	s->dma_dac1.mapped = 1;	ret = 0;out:	unlock_kernel();	return ret;}static int es1370_ioctl_dac(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;	unsigned ctrl;	int val, ret;	VALIDATE_STATE(s);	switch (cmd) {	case OSS_GETVERSION:		return put_user(SOUND_VERSION, (int *)arg);	case SNDCTL_DSP_SYNC:		return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/);			case SNDCTL_DSP_SETDUPLEX:		return -EINVAL;	case SNDCTL_DSP_GETCAPS:		return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);		        case SNDCTL_DSP_RESET:		stop_dac1(s);		synchronize_irq();		s->dma_dac1.swptr = s->dma_dac1.hwptr = s->dma_dac1.count = s->dma_dac1.total_bytes = 0;		return 0;        case SNDCTL_DSP_SPEED:                if (get_user(val, (int *)arg))			return -EFAULT;		if (val >= 0) {			stop_dac1(s);			s->dma_dac1.ready = 0;			for (ctrl = 0; ctrl <= 2; ctrl++)				if (val < (dac1_samplerate[ctrl] + dac1_samplerate[ctrl+1]) / 2)					break;			spin_lock_irqsave(&s->lock, flags);			s->ctrl = (s->ctrl & ~CTRL_WTSRSEL) | (ctrl << CTRL_SH_WTSRSEL);			outl(s->ctrl, s->io+ES1370_REG_CONTROL);			spin_unlock_irqrestore(&s->lock, flags);		}		return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], (int *)arg);		        case SNDCTL_DSP_STEREO:                if (get_user(val, (int *)arg))			return -EFAULT;		stop_dac1(s);		s->dma_dac1.ready = 0;		spin_lock_irqsave(&s->lock, flags);		if (val)			s->sctrl |= SCTRL_P1SMB;		else			s->sctrl &= ~SCTRL_P1SMB;		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 (s->dma_dac1.mapped)				return -EINVAL;			stop_dac1(s);			s->dma_dac1.ready = 0;			spin_lock_irqsave(&s->lock, flags);			if (val >= 2)				s->sctrl |= SCTRL_P1SMB;			else				s->sctrl &= ~SCTRL_P1SMB;			outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);			spin_unlock_irqrestore(&s->lock, flags);		}		return put_user((s->sctrl & SCTRL_P1SMB) ? 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) {			stop_dac1(s);			s->dma_dac1.ready = 0;			spin_lock_irqsave(&s->lock, flags);			if (val == AFMT_S16_LE)				s->sctrl |= SCTRL_P1SEB;			else				s->sctrl &= ~SCTRL_P1SEB;			outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);			spin_unlock_irqrestore(&s->lock, flags);		}		return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, (int *)arg);        case SNDCTL_DSP_POST:                return 0;        case SNDCTL_DSP_GETTRIGGER:		return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, (int *)arg);							case SNDCTL_DSP_SETTRIGGER:		if (get_user(val, (int *)arg))			return -EFAULT;		if (val & PCM_ENABLE_OUTPUT) {			if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))				return ret;			s->dma_dac1.enabled = 1;			start_dac1(s);		} else {			s->dma_dac1.enabled = 0;			stop_dac1(s);		}		return 0;	case SNDCTL_DSP_GETOSPACE:		if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)			return val;		spin_lock_irqsave(&s->lock, flags);		es1370_update_ptr(s);		abinfo.fragsize = s->dma_dac1.fragsize;		count = s->dma_dac1.count;		if (count < 0)			count = 0;                abinfo.bytes = s->dma_dac1.dmasize - count;                abinfo.fragstotal

⌨️ 快捷键说明

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