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

📄 cmpci.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 | DSP_CAP_BIND, (int *)arg);		        case SNDCTL_DSP_RESET:		if (file->f_mode & FMODE_WRITE) {			stop_dac(s);			synchronize_irq();			s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;			if (s->status & DO_DUAL_DAC)				s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.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) {			 	spin_lock_irqsave(&s->lock, flags);				stop_adc_unlocked(s);				s->dma_adc.ready = 0;				set_adc_rate_unlocked(s, val);				spin_unlock_irqrestore(&s->lock, flags);			}			if (file->f_mode & FMODE_WRITE) {				stop_dac(s);				s->dma_dac.ready = 0;				if (s->status & DO_DUAL_DAC)					s->dma_adc.ready = 0;				set_dac_rate(s, val);			}		}		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);        case SNDCTL_DSP_STEREO:		if (get_user(val, (int *)arg))			return -EFAULT;		fmtd = 0;		fmtm = ~0;		if (file->f_mode & FMODE_READ) {			stop_adc(s);			s->dma_adc.ready = 0;			if (val)				fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;			else				fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);		}		if (file->f_mode & FMODE_WRITE) {			stop_dac(s);			s->dma_dac.ready = 0;			if (val)				fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;			else				fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);			if (s->status & DO_DUAL_DAC) {				s->dma_adc.ready = 0;				if (val)					fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;				else					fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);			}		}		set_fmt(s, fmtm, fmtd);		return 0;        case SNDCTL_DSP_CHANNELS:		if (get_user(val, (int *)arg))			return -EFAULT;		if (val != 0) {			fmtd = 0;			fmtm = ~0;			if (file->f_mode & FMODE_READ) {				stop_adc(s);				s->dma_adc.ready = 0;				if (val >= 2)					fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;				else					fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);			}			if (file->f_mode & FMODE_WRITE) {				stop_dac(s);				s->dma_dac.ready = 0;				if (val >= 2)					fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;				else					fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);				if (s->status & DO_DUAL_DAC) {					s->dma_adc.ready = 0;					if (val >= 2)						fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;					else						fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);				}			}			set_fmt(s, fmtm, fmtd);			if ((s->capability & CAN_MULTI_CH)			     && (file->f_mode & FMODE_WRITE)) {				val = set_dac_channels(s, val);				return put_user(val, (int *)arg);			}		}            		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) 					   : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, (int *)arg);			case SNDCTL_DSP_GETFMTS: /* Returns a mask */                return put_user(AFMT_S16_LE|AFMT_U8|AFMT_AC3, (int *)arg);			case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/		if (get_user(val, (int *)arg))			return -EFAULT;		if (val != AFMT_QUERY) {			fmtd = 0;			fmtm = ~0;			if (file->f_mode & FMODE_READ) {				stop_adc(s);				s->dma_adc.ready = 0;				if (val == AFMT_S16_LE)					fmtd |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;				else					fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_ADCSHIFT);			}			if (file->f_mode & FMODE_WRITE) {				stop_dac(s);				s->dma_dac.ready = 0;				if (val == AFMT_S16_LE || val == AFMT_AC3)					fmtd |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;				else					fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_DACSHIFT);				if (val == AFMT_AC3) {					fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;					set_ac3(s, s->ratedac);				} else					set_ac3(s, 0);				if (s->status & DO_DUAL_DAC) {					s->dma_adc.ready = 0;					if (val == AFMT_S16_LE)						fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;					else						fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);				}			}			set_fmt(s, fmtm, fmtd);		}		if (s->status & DO_AC3) return put_user(AFMT_AC3, (int *)arg);		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT)					   : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? AFMT_S16_LE : AFMT_U8, (int *)arg);	case SNDCTL_DSP_POST:                return 0;        case SNDCTL_DSP_GETTRIGGER:		val = 0;		if (s->status & DO_DUAL_DAC) {			if (file->f_mode & FMODE_WRITE &&			 (s->enable & CM_ENABLE_CH1) &&			 (s->enable & CM_ENABLE_CH0))				val |= PCM_ENABLE_OUTPUT;			return put_user(val, (int *)arg);		}		if (file->f_mode & FMODE_READ && s->enable & CM_ENABLE_CH0) 			val |= PCM_ENABLE_INPUT;		if (file->f_mode & FMODE_WRITE && s->enable & CM_ENABLE_CH1) 			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(s, 1)))					return ret;				start_adc(s);			} else				stop_adc(s);		}		if (file->f_mode & FMODE_WRITE) {			if (val & PCM_ENABLE_OUTPUT) {				if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))					return ret;				if (s->status & DO_DUAL_DAC) {					if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))						return ret;				}				start_dac(s);			} else				stop_dac(s);		}		return 0;	case SNDCTL_DSP_GETOSPACE:		if (!(file->f_mode & FMODE_WRITE))			return -EINVAL;		if (!(s->enable & CM_ENABLE_CH1) && (val = prog_dmabuf(s, 0)) != 0)			return val;		spin_lock_irqsave(&s->lock, flags);		cm_update_ptr(s);		abinfo.fragsize = s->dma_dac.fragsize;                abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;                abinfo.fragstotal = s->dma_dac.numfrag;                abinfo.fragments = abinfo.bytes >> s->dma_dac.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->enable & CM_ENABLE_CH0) && (val = prog_dmabuf(s, 1)) != 0)			return val;		spin_lock_irqsave(&s->lock, flags);		cm_update_ptr(s);		abinfo.fragsize = s->dma_adc.fragsize;                abinfo.bytes = s->dma_adc.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;		spin_lock_irqsave(&s->lock, flags);		cm_update_ptr(s);                val = s->dma_dac.count;		spin_unlock_irqrestore(&s->lock, flags);		return put_user(val, (int *)arg);        case SNDCTL_DSP_GETIPTR:		if (!(file->f_mode & FMODE_READ))			return -EINVAL;		spin_lock_irqsave(&s->lock, flags);		cm_update_ptr(s);                cinfo.bytes = s->dma_adc.total_bytes;                cinfo.blocks = s->dma_adc.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;		spin_lock_irqsave(&s->lock, flags);		cm_update_ptr(s);                cinfo.bytes = s->dma_dac.total_bytes;                cinfo.blocks = s->dma_dac.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;		if (s->status & DO_DUAL_DAC) {			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_GETBLKSIZE:		if (file->f_mode & FMODE_WRITE) {			if ((val = prog_dmabuf(s, 0)))				return val;			if (s->status & DO_DUAL_DAC) {				if ((val = prog_dmabuf(s, 1)))					return val;				return put_user(2 * s->dma_dac.fragsize, (int *)arg);			}			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;			if (s->status & DO_DUAL_DAC) {				s->dma_adc.ossfragshift = s->dma_dac.ossfragshift;				s->dma_adc.ossmaxfrags = s->dma_dac.ossmaxfrags;			}		}		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;			if (s->status & DO_DUAL_DAC)				s->dma_adc.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) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, (int *)arg);        case SOUND_PCM_READ_BITS:		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? 16 : 8, (int *)arg);        case SOUND_PCM_READ_FILTER:		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);	case SNDCTL_DSP_GETCHANNELMASK:		return put_user(DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE|DSP_BIND_SPDIF, (int *)arg);			case SNDCTL_DSP_BIND_CHANNEL:		if (get_user(val, (int *)arg))			return -EFAULT;		if (val == DSP_BIND_QUERY) {			val = DSP_BIND_FRONT;			if (s->status & DO_SPDIF_OUT)				val |= DSP_BIND_SPDIF;			else {				if (s->curr_channels == 4)					val |= DSP_BIND_SURR;				if (s->curr_channels > 4)					val |= DSP_BIND_CENTER_LFE;			}		} else {			if (file->f_mode & FMODE_READ) {				stop_adc(s);				s->dma_adc.ready = 0;			}			if (file->f_mode & FMODE_WRITE) {				stop_dac(s);				s->dma_dac.ready = 0;				if (val & DSP_BIND_SPDIF) {					set_spdifout(s, s->ratedac);					set_dac_channels(s, s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1);					if (!(s->status & DO_SPDIF_OUT))						val &= ~DSP_BIND_SPDIF;				} else {					int channels;					int mask;					mask = val & (DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE);					switch (mask) {					    case DSP_BIND_FRONT:						channels = 2;						break;					    case DSP_BIND_FRONT|DSP_BIND_SURR:						channels = 4;						break;					    case DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE:						channels = 6;						break;					    default:						channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1;						break;					}					set_dac_channels(s, channels);				}			}		}		return put_user(val, (int *)arg);	case SOUND_PCM_WRITE_FILTER:	case SNDCTL_DSP_MAPINBUF:	case SNDCTL_DSP_MAPOUTBUF:        case SNDCTL_DSP_SETSYNCRO:                return -EINVAL;			}	return mixer_ioctl(s, cmd, arg);}static int cm_open(struct inode *inode, struct file *file){	int minor = MINOR(inode->i_rdev);	struct cm_state *s = devs;	unsigned char fmtm = ~0, fmts = 0;	while (s && ((s->dev_audio ^ minor) & ~0xf))		s = s->next;	if (!s)		return -ENODEV;       	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;		}		up(&s->open_sem);		interruptible_sleep_on(&s->open_wait);		if (signal_pending(current))			return -ERESTARTSYS;		down(&s->open_sem);	}	if (file->f_mode & FMODE_READ) {		fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT);		if ((minor & 0xf) == SND_DEV_DSP16)			fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;		set_adc_rate(s, 8000);	}	if (file->f_mode & FMODE_WRITE) {		fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);		if ((minor & 0xf) == SND_DEV_DSP16)			fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;		set_dac_rate(s, 8000);		// clear previous multichannel, spdif, ac3 state		se

⌨️ 快捷键说明

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