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

📄 dmasound_core.c

📁 鼎力推荐!本程序是基于嵌入式LUNUX系统开发的源程序代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * will be set so long as the shared resources have no owner.	 */	if (shared_resource_owner == 0) {		dmasound.soft = dmasound.mach.default_soft ;		dmasound.hard = dmasound.mach.default_hard ;		dmasound.dsp = dmasound.mach.default_soft ;		shared_resources_initialised = 0 ;	}	return 0 ;}    /*     *  /dev/sndstat     *//* we allow more space for record-enabled because there are extra output lines.   the number here must include the amount we are prepared to give to the low-level   driver.*/#ifdef HAS_RECORD#define STAT_BUFF_LEN 1024#else#define STAT_BUFF_LEN 768#endif/* this is how much space we will allow the low-level driver to use   in the stat buffer.  Currently, 2 * (80 character line + <NL>).   We do not police this (it is up to the ll driver to be honest).*/#define LOW_LEVEL_STAT_ALLOC 162static struct {    int busy;    char buf[STAT_BUFF_LEN];	/* state.buf should not overflow! */    int len, ptr;} state;/* publish this function for use by low-level code, if required */char *get_afmt_string(int afmt){        switch(afmt) {            case AFMT_MU_LAW:                return "mu-law";                break;            case AFMT_A_LAW:                return "A-law";                break;            case AFMT_U8:                return "unsigned 8 bit";                break;            case AFMT_S8:                return "signed 8 bit";                break;            case AFMT_S16_BE:                return "signed 16 bit BE";                break;            case AFMT_U16_BE:                return "unsigned 16 bit BE";                break;            case AFMT_S16_LE:                return "signed 16 bit LE";                break;            case AFMT_U16_LE:                return "unsigned 16 bit LE";                break;	    case 0:		return "format not set" ;		break ;            default:                break ;        }        return "ERROR: Unsupported AFMT_XXXX code" ;}static int state_open(struct inode *inode, struct file *file){	char *buffer = state.buf;	int len = 0;	if (state.busy)		return -EBUSY;	if (!try_module_get(dmasound.mach.owner))		return -ENODEV;	state.ptr = 0;	state.busy = 1;	len += sprintf(buffer+len, "%sDMA sound driver rev %03d :\n",		dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) +		((dmasound.mach.version>>8) & 0x0f));	len += sprintf(buffer+len,		"Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",		DMASOUND_CORE_REVISION, DMASOUND_CORE_EDITION, dmasound.mach.name2,		(dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;	/* call the low-level module to fill in any stat info. that it has	   if present.  Maximum buffer usage is specified.	*/	if (dmasound.mach.state_info)		len += dmasound.mach.state_info(buffer+len,			(size_t) LOW_LEVEL_STAT_ALLOC) ;	/* make usage of the state buffer as deterministic as poss.	   exceptional conditions could cause overrun - and this is flagged as	   a kernel error.	*/	/* formats and settings */	len += sprintf(buffer+len,"\t\t === Formats & settings ===\n") ;	len += sprintf(buffer+len,"Parameter %20s%20s\n","soft","hard") ;	len += sprintf(buffer+len,"Format   :%20s%20s\n",		get_afmt_string(dmasound.soft.format),		get_afmt_string(dmasound.hard.format));	len += sprintf(buffer+len,"Samp Rate:%14d s/sec%14d s/sec\n",		       dmasound.soft.speed, dmasound.hard.speed);	len += sprintf(buffer+len,"Channels :%20s%20s\n",		       dmasound.soft.stereo ? "stereo" : "mono",		       dmasound.hard.stereo ? "stereo" : "mono" );	/* sound queue status */	len += sprintf(buffer+len,"\t\t === Sound Queue status ===\n");	len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ;	len += sprintf(buffer+len,"%9s:%8d%6d\n",		"write", write_sq.numBufs, write_sq.bufSize) ;#ifdef HAS_RECORD	if (dmasound.mach.record)		len += sprintf(buffer+len,"%9s:%8d%6d\n",			"read", read_sq.numBufs, read_sq.bufSize) ;#endif	len += sprintf(buffer+len,		"Current  : MaxFrg FragSiz MaxAct Frnt Rear "		"Cnt RrSize A B S L  xruns\n") ;	len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",		"write", write_sq.max_count, write_sq.block_size,		write_sq.max_active, write_sq.front, write_sq.rear,		write_sq.count, write_sq.rear_size, write_sq.active,		write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ;#ifdef HAS_RECORD	if (dmasound.mach.record)		len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",			"read", read_sq.max_count, read_sq.block_size,			read_sq.max_active, read_sq.front, read_sq.rear,			read_sq.count, read_sq.rear_size, read_sq.active,			read_sq.busy, read_sq.syncing, read_sq.locked, read_sq.xruns) ;#endif#ifdef DEBUG_DMASOUNDprintk("dmasound: stat buffer used %d bytes\n", len) ;#endif	if (len >= STAT_BUFF_LEN)		printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n");	state.len = len;	return 0;}static int state_release(struct inode *inode, struct file *file){	lock_kernel();	state.busy = 0;	module_put(dmasound.mach.owner);	unlock_kernel();	return 0;}static ssize_t state_read(struct file *file, char __user *buf, size_t count,			  loff_t *ppos){	int n = state.len - state.ptr;	if (n > count)		n = count;	if (n <= 0)		return 0;	if (copy_to_user(buf, &state.buf[state.ptr], n))		return -EFAULT;	state.ptr += n;	return n;}static struct file_operations state_fops = {	.owner		= THIS_MODULE,	.llseek		= no_llseek,	.read		= state_read,	.open		= state_open,	.release	= state_release,};static int state_init(void){#ifndef MODULE	int state_unit;#endif	state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);	if (state_unit < 0)		return state_unit ;	state.busy = 0;	return 0 ;}    /*     *  Config & Setup     *     *  This function is called by _one_ chipset-specific driver     */int dmasound_init(void){	int res ;#ifdef MODULE	if (irq_installed)		return -EBUSY;#endif	/* Set up sound queue, /dev/audio and /dev/dsp. */	/* Set default settings. */	if ((res = sq_init()) < 0)		return res ;	/* Set up /dev/sndstat. */	if ((res = state_init()) < 0)		return res ;	/* Set up /dev/mixer. */	mixer_init();	if (!dmasound.mach.irqinit()) {		printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");		return -ENODEV;	}#ifdef MODULE	irq_installed = 1;#endif	printk(KERN_INFO "%s DMA sound driver rev %03d installed\n",		dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) +		((dmasound.mach.version>>8) & 0x0f));	printk(KERN_INFO		"Core driver edition %02d.%02d : %s driver edition %02d.%02d\n",		DMASOUND_CORE_REVISION, DMASOUND_CORE_EDITION, dmasound.mach.name2,		(dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;	printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n",		numWriteBufs, writeBufSize) ;#ifdef HAS_RECORD	if (dmasound.mach.record)		printk(KERN_INFO			"Read  will use %4d fragments of %7d bytes as default\n",			numReadBufs, readBufSize) ;#endif	return 0;}#ifdef MODULEvoid dmasound_deinit(void){	if (irq_installed) {		sound_silence();		dmasound.mach.irqcleanup();		irq_installed = 0;	}	write_sq_release_buffers();	read_sq_release_buffers();	if (mixer_unit >= 0)		unregister_sound_mixer(mixer_unit);	if (state_unit >= 0)		unregister_sound_special(state_unit);	if (sq_unit >= 0)		unregister_sound_dsp(sq_unit);}#else /* !MODULE */static int dmasound_setup(char *str){	int ints[6], size;	str = get_options(str, ARRAY_SIZE(ints), ints);	/* check the bootstrap parameter for "dmasound=" */	/* FIXME: other than in the most naive of cases there is no sense in these	 *	  buffers being other than powers of two.  This is not checked yet.	 */	switch (ints[0]) {#ifdef HAS_RECORD        case 5:                if ((ints[5] < 0) || (ints[5] > MAX_CATCH_RADIUS))                        printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);                else                        catchRadius = ints[5];                /* fall through */        case 4:                if (ints[4] < MIN_BUFFERS)                        printk("dmasound_setup: invalid number of read buffers, using default = %d\n",                                 numReadBufs);                else                        numReadBufs = ints[4];                /* fall through */        case 3:		if ((size = ints[3]) < 256)  /* check for small buffer specs */			size <<= 10 ;                if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)                        printk("dmasound_setup: invalid read buffer size, using default = %d\n", readBufSize);                else                        readBufSize = size;                /* fall through */#else	case 3:		if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))			printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);		else			catchRadius = ints[3];		/* fall through */#endif	case 2:		if (ints[1] < MIN_BUFFERS)			printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);		else			numWriteBufs = ints[1];		/* fall through */	case 1:		if ((size = ints[2]) < 256) /* check for small buffer specs */			size <<= 10 ;                if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)                        printk("dmasound_setup: invalid write buffer size, using default = %d\n", writeBufSize);                else                        writeBufSize = size;	case 0:		break;	default:		printk("dmasound_setup: invalid number of arguments\n");		return 0;	}	return 1;}__setup("dmasound=", dmasound_setup);#endif /* !MODULE */    /*     *  Conversion tables     */#ifdef HAS_8BIT_TABLES/* 8 bit mu-law */char dmasound_ulaw2dma8[] = {	-126,	-122,	-118,	-114,	-110,	-106,	-102,	-98,	-94,	-90,	-86,	-82,	-78,	-74,	-70,	-66,	-63,	-61,	-59,	-57,	-55,	-53,	-51,	-49,	-47,	-45,	-43,	-41,	-39,	-37,	-35,	-33,	-31,	-30,	-29,	-28,	-27,	-26,	-25,	-24,	-23,	-22,	-21,	-20,	-19,	-18,	-17,	-16,	-16,	-15,	-15,	-14,	-14,	-13,	-13,	-12,	-12,	-11,	-11,	-10,	-10,	-9,	-9,	-8,	-8,	-8,	-7,	-7,	-7,	-7,	-6,	-6,	-6,	-6,	-5,	-5,	-5,	-5,	-4,	-4,	-4,	-4,	-4,	-4,	-3,	-3,	-3,	-3,	-3,	-3,	-3,	-3,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	125,	121,	117,	113,	109,	105,	101,	97,	93,	89,	85,	81,	77,	73,	69,	65,	62,	60,	58,	56,	54,	52,	50,	48,	46,	44,	42,	40,	38,	36,	34,	32,	30,	29,	28,	27,	26,	25,	24,	23,	22,	21,	20,	19,	18,	17,	16,	15,	15,	14,	14,	13,	13,	12,	12,	11,	11,	10,	10,	9,	9,	8,	8,	7,	7,	7,	6,	6,	6,	6,	5,	5,	5,	5,	4,	4,	4,	4,	3,	3,	3,	3,	3,	3,	2,	2,	2,	2,	2,	2,	2,	2,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0};/* 8 bit A-law */char dmasound_alaw2dma8[] = {	-22,	-21,	-24,	-23,	-18,	-17,	-20,	-19,	-30,	-29,	-32,	-31,	-26,	-25,	-28,	-27,	-11,	-11,	-12,	-12,	-9,	-9,	-10,	-10,	-15,	-15,	-16,	-16,	-13,	-13,	-14,	-14,	-86,	-82,	-94,	-90,	-70,	-66,	-78,	-74,	-118,	-114,	-126,	-122,	-102,	-98,	-110,	-106,	-43,	-41,	-47,	-45,	-35,	-33,	-39,	-37,	-59,	-57,	-63,	-61,	-51,	-49,	-55,	-53,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-6,	-6,	-6,	-6,	-5,	-5,	-5,	-5,	-8,	-8,	-8,	-8,	-7,	-7,	-7,	-7,	-3,	-3,	-3,	-3,	-3,	-3,	-3,	-3,	-4,	-4,	-4,	-4,	-4,	-4,	-4,	-4,	21,	20,	23,	22,	17,	16,	19,	18,	29,	28,	31,	30,	25,	24,	27,	26,	10,	10,	11,	11,	8,	8,	9,	9,	14,	14,	15,	15,	12,	12,	13,	13,	86,	82,	94,	90,	70,	66,	78,	74,	118,	114,	126,	122,	102,	98,	110,	106,	43,	41,	47,	45,	35,	33,	39,	37,	59,	57,	63,	61,	51,	49,	55,	53,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	5,	5,	5,	5,	4,	4,	4,	4,	7,	7,	7,	7,	6,	6,	6,	6,	2,	2,	2,	2,	2,	2,	2,	2,	3,	3,	3,	3,	3,	3,	3,	3};#endif /* HAS_8BIT_TABLES */    /*     *  Visible symbols for modules     */EXPORT_SYMBOL(dmasound);EXPORT_SYMBOL(dmasound_init);#ifdef MODULEEXPORT_SYMBOL(dmasound_deinit);#endifEXPORT_SYMBOL(dmasound_write_sq);#ifdef HAS_RECORDEXPORT_SYMBOL(dmasound_read_sq);#endifEXPORT_SYMBOL(dmasound_catchRadius);#ifdef HAS_8BIT_TABLESEXPORT_SYMBOL(dmasound_ulaw2dma8);EXPORT_SYMBOL(dmasound_alaw2dma8);#endifEXPORT_SYMBOL(get_afmt_string) ;

⌨️ 快捷键说明

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