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

📄 au88x0_core.c

📁 鼎力推荐!本程序是基于嵌入式LUNUX系统开发的源程序代码
💻 C
📖 第 1 页 / 共 5 页
字号:
// Connect SRC to mixin.static voidvortex_connection_src_mixin(vortex_t * vortex, int en,			    unsigned char channel, unsigned char src,			    unsigned char mixin){	vortex_route(vortex, en, channel, ADB_SRCOUT(src), ADB_MIXIN(mixin));}// Connect mixin with mix output.static voidvortex_connection_mixin_mix(vortex_t * vortex, int en, unsigned char mixin,			    unsigned char mix, int a){	if (en) {		vortex_mix_enableinput(vortex, mix, mixin);		vortex_mix_setinputvolumebyte(vortex, mix, mixin, MIX_DEFIGAIN);	// added to original code.	} else		vortex_mix_disableinput(vortex, mix, mixin, a);}// Connect absolut address to mixin.static voidvortex_connection_adb_mixin(vortex_t * vortex, int en,			    unsigned char channel, unsigned char source,			    unsigned char mixin){	vortex_route(vortex, en, channel, source, ADB_MIXIN(mixin));}static voidvortex_connection_src_adbdma(vortex_t * vortex, int en, unsigned char ch,			     unsigned char src, unsigned char adbdma){	vortex_route(vortex, en, ch, ADB_SRCOUT(src), ADB_DMA(adbdma));}static voidvortex_connection_src_src_adbdma(vortex_t * vortex, int en,				 unsigned char ch, unsigned char src0,				 unsigned char src1, unsigned char adbdma){	vortex_routeLRT(vortex, en, ch, ADB_SRCOUT(src0), ADB_SRCOUT(src1),			ADB_DMA(adbdma));}// mix to absolut address.static voidvortex_connection_mix_adb(vortex_t * vortex, int en, unsigned char ch,			  unsigned char mix, unsigned char dest){	vortex_route(vortex, en, ch, ADB_MIXOUT(mix), dest);	vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN);	// added to original code.}// mixer to src.static voidvortex_connection_mix_src(vortex_t * vortex, int en, unsigned char ch,			  unsigned char mix, unsigned char src){	vortex_route(vortex, en, ch, ADB_MIXOUT(mix), ADB_SRCIN(src));	vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN);	// added to original code.}#if 0static voidvortex_connection_adbdma_src_src(vortex_t * vortex, int en,				 unsigned char channel,				 unsigned char adbdma, unsigned char src0,				 unsigned char src1){	vortex_routes(vortex, en, channel, ADB_DMA(adbdma),		      ADB_SRCIN(src0), ADB_SRCIN(src1));}// Connect two mix to AdbDma.static voidvortex_connection_mix_mix_adbdma(vortex_t * vortex, int en,				 unsigned char ch, unsigned char mix0,				 unsigned char mix1, unsigned char adbdma){	ADBRamLink routes[2];	routes[0] =	    (((mix0 +	       OFFSET_MIXOUT) & ADB_MASK) << ADB_SHIFT) | (adbdma & ADB_MASK);	routes[1] =	    (((mix1 + OFFSET_MIXOUT) & ADB_MASK) << ADB_SHIFT) | ((adbdma +								   0x20) &								  ADB_MASK);	if (en) {		vortex_adb_addroutes(vortex, ch, routes, 0x2);		vortex_mixer_addWTD(vortex, mix0, ch);		vortex_mixer_addWTD(vortex, mix1, ch);	} else {		vortex_adb_delroutes(vortex, ch, routes[0], routes[1]);		vortex_mixer_delWTD(vortex, mix0, ch);		vortex_mixer_delWTD(vortex, mix1, ch);	}}#endif/* CODEC connect. */static voidvortex_connect_codecplay(vortex_t * vortex, int en, unsigned char mixers[]){#ifdef CHIP_AU8820	vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_CODECOUT(0));	vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_CODECOUT(1));#else#if 1	// Connect front channels through EQ.	vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_EQIN(0));	vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_EQIN(1));	/* Lower volume, since EQ has some gain. */	vortex_mix_setvolumebyte(vortex, mixers[0], 0);	vortex_mix_setvolumebyte(vortex, mixers[1], 0);	vortex_route(vortex, en, 0x11, ADB_EQOUT(0), ADB_CODECOUT(0));	vortex_route(vortex, en, 0x11, ADB_EQOUT(1), ADB_CODECOUT(1));	/* Check if reg 0x28 has SDAC bit set. */	if (VORTEX_IS_QUAD(vortex)) {		/* Rear channel. Note: ADB_CODECOUT(0+2) and (1+2) is for AC97 modem */		vortex_connection_mix_adb(vortex, en, 0x11, mixers[2],					  ADB_CODECOUT(0 + 4));		vortex_connection_mix_adb(vortex, en, 0x11, mixers[3],					  ADB_CODECOUT(1 + 4));		//printk("SDAC detected ");	}#else	// Use plain direct output to codec.	vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_CODECOUT(0));	vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_CODECOUT(1));#endif#endif}static voidvortex_connect_codecrec(vortex_t * vortex, int en, unsigned char mixin0,			unsigned char mixin1){	/*	   Enable: 0x1, 0x1	   Channel: 0x11, 0x11	   ADB Source address: 0x48, 0x49	   Destination Asp4Topology_0x9c,0x98	 */	vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(0), mixin0);	vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(1), mixin1);}// Higher level ADB audio path (de)allocator./* Resource manager */static int resnum[VORTEX_RESOURCE_LAST] =    { NR_ADB, NR_SRC, NR_MIXIN, NR_MIXOUT, NR_A3D };/* Checkout/Checkin resource of given type.  resmap: resource map to be used. If NULL means that we want to allocate a DMA resource (root of all other resources of a dma channel). out: Mean checkout if != 0. Else mean Checkin resource. restype: Indicates type of resource to be checked in or out.*/static charvortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype){	int i, qty = resnum[restype], resinuse = 0;	if (out) {		/* Gather used resources by all streams. */		for (i = 0; i < NR_ADB; i++) {			resinuse |= vortex->dma_adb[i].resources[restype];		}		resinuse |= vortex->fixed_res[restype];		/* Find and take free resource. */		for (i = 0; i < qty; i++) {			if ((resinuse & (1 << i)) == 0) {				if (resmap != NULL)					resmap[restype] |= (1 << i);				else					vortex->dma_adb[i].resources[restype] |= (1 << i);				//printk("vortex: ResManager: type %d out %d\n", restype, i);				return i;			}		}	} else {		if (resmap == NULL)			return -EINVAL;		/* Checkin first resource of type restype. */		for (i = 0; i < qty; i++) {			if (resmap[restype] & (1 << i)) {				resmap[restype] &= ~(1 << i);				//printk("vortex: ResManager: type %d in %d\n",restype, i);				return i;			}		}	}	printk("vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);	return -ENOMEM;}/* Default Connections  */static intvortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type);static void vortex_connect_default(vortex_t * vortex, int en){	// Connect AC97 codec.	vortex->mixplayb[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,				  VORTEX_RESOURCE_MIXOUT);	vortex->mixplayb[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,				  VORTEX_RESOURCE_MIXOUT);	if (VORTEX_IS_QUAD(vortex)) {		vortex->mixplayb[2] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,					  VORTEX_RESOURCE_MIXOUT);		vortex->mixplayb[3] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,					  VORTEX_RESOURCE_MIXOUT);	}	vortex_connect_codecplay(vortex, en, vortex->mixplayb);	vortex->mixcapt[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,				  VORTEX_RESOURCE_MIXIN);	vortex->mixcapt[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,				  VORTEX_RESOURCE_MIXIN);	vortex_connect_codecrec(vortex, en, MIX_CAPT(0), MIX_CAPT(1));	// Connect SPDIF#ifndef CHIP_AU8820	vortex->mixspdif[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,				  VORTEX_RESOURCE_MIXOUT);	vortex->mixspdif[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,				  VORTEX_RESOURCE_MIXOUT);	vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[0],				  ADB_SPDIFOUT(0));	vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[1],				  ADB_SPDIFOUT(1));#endif	// Connect WT#ifndef CHIP_AU8810	vortex_wt_connect(vortex, en);#endif	// A3D (crosstalk canceler and A3D slices). AU8810 disabled for now.#ifndef CHIP_AU8820	vortex_Vort3D_connect(vortex, en);#endif	// Connect I2S	// Connect DSP interface for SQ3500 turbo (not here i think...)	// Connect AC98 modem codec	}/*  Allocate nr_ch pcm audio routes if dma < 0. If dma >= 0, existing routes  are deallocated.  dma: DMA engine routes to be deallocated when dma >= 0.  nr_ch: Number of channels to be de/allocated.  dir: direction of stream. Uses same values as substream->stream.  type: Type of audio output/source (codec, spdif, i2s, dsp, etc)  Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.*/static intvortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type){	stream_t *stream;	int i, en;		if ((nr_ch == 3)	    || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))		return -EBUSY;	if (dma >= 0) {		en = 0;		vortex_adb_checkinout(vortex,				      vortex->dma_adb[dma].resources, en,				      VORTEX_RESOURCE_DMA);	} else {		en = 1;		if ((dma =		     vortex_adb_checkinout(vortex, NULL, en,					   VORTEX_RESOURCE_DMA)) < 0)			return -EBUSY;	}	stream = &vortex->dma_adb[dma];	stream->dma = dma;	stream->dir = dir;	stream->type = type;	/* PLAYBACK ROUTES. */	if (dir == SNDRV_PCM_STREAM_PLAYBACK) {		int src[4], mix[4], ch_top;#ifndef CHIP_AU8820		int a3d = 0;#endif		/* Get SRC and MIXER hardware resources. */		if (stream->type != VORTEX_PCM_SPDIF) {			for (i = 0; i < nr_ch; i++) {				if ((src[i] = vortex_adb_checkinout(vortex,							   stream->resources, en,							   VORTEX_RESOURCE_SRC)) < 0) {					memset(stream->resources, 0,					       sizeof(unsigned char) *					       VORTEX_RESOURCE_LAST);					return -EBUSY;				}				if (stream->type != VORTEX_PCM_A3D) {					if ((mix[i] = vortex_adb_checkinout(vortex,								   stream->resources,								   en,								   VORTEX_RESOURCE_MIXIN)) < 0) {						memset(stream->resources,						       0,						       sizeof(unsigned char) * VORTEX_RESOURCE_LAST);						return -EBUSY;					}				}			}		}#ifndef CHIP_AU8820		if (stream->type == VORTEX_PCM_A3D) {			if ((a3d =			     vortex_adb_checkinout(vortex,						   stream->resources, en,						   VORTEX_RESOURCE_A3D)) < 0) {				memset(stream->resources, 0,				       sizeof(unsigned char) *				       VORTEX_RESOURCE_LAST);				printk("vortex: out of A3D sources. Sorry\n");				return -EBUSY;			}			/* (De)Initialize A3D hardware source. */			vortex_Vort3D_InitializeSource(&(vortex->a3d[a3d]), en);		}		/* Make SPDIF out exclusive to "spdif" device when in use. */		if ((stream->type == VORTEX_PCM_SPDIF) && (en)) {			vortex_route(vortex, 0, 0x14,				     ADB_MIXOUT(vortex->mixspdif[0]),				     ADB_SPDIFOUT(0));			vortex_route(vortex, 0, 0x14,				     ADB_MIXOUT(vortex->mixspdif[1]),				     ADB_SPDIFOUT(1));		}#endif		/* Make playback routes. */		for (i = 0; i < nr_ch; i++) {			if (stream->type == VORTEX_PCM_ADB) {				vortex_connection_adbdma_src(vortex, en,							     src[nr_ch - 1],							     dma,							     src[i]);				vortex_connection_src_mixin(vortex, en,							    0x11, src[i],							    mix[i]);				vortex_connection_mixin_mix(vortex, en,							    mix[i],							    MIX_PLAYB(i), 0);#ifndef CHIP_AU8820				vortex_connection_mixin_mix(vortex, en,							    mix[i],							    MIX_SPDIF(i % 2), 0);				vortex_mix_setinputvolumebyte(vortex,							      MIX_SPDIF(i % 2),							      mix[i],							      MIX_DEFIGAIN);#endif			}#ifndef CHIP_AU8820			if (stream->type == VORTEX_PCM_A3D) {				vortex_connection_adbdma_src(vortex, en,							     src[nr_ch - 1], 								 dma,							     src[i]);				vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_A3DIN(a3d));				/* XTalk test. */				//vortex_route(vortex, en, 0x11, dma, ADB_XTALKIN(i?9:4));				//vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_XTALKIN(i?4:9));			}			if (stream->type == VORTEX_PCM_SPDIF)				vortex_route(vortex, en, 0x14,					     ADB_DMA(stream->dma),					     ADB_SPDIFOUT(i));#endif		}		if (stream->type != VORTEX_PCM_SPDIF && stream->type != VORTEX_PCM_A3D) {			ch_top = (VORTEX_IS_QUAD(vortex) ? 4 : 2);			for (i = nr_ch; i < ch_top; i++) {				vortex_connection_mixin_mix(vortex, en,							    mix[i % nr_ch],							    MIX_PLAYB(i), 0);#ifndef CHIP_AU8820				vortex_connection_mixin_mix(vortex, en,							    mix[i % nr_ch],							    MIX_SPDIF(i % 2),								0);				vortex_mix_setinputvolumebyte(vortex,							      MIX_SPDIF(i % 2),							      mix[i % nr_ch],							      MIX_DEFIGAIN);#endif			}		}#ifndef CHIP_AU8820		else {			if (nr_ch == 1 && stream->type == VORTEX_PCM_SPDIF)				vortex_route(vortex, en, 0x14,					     ADB_DMA(stream->dma),					     ADB_SPDIFOUT(1));		}		/* Reconnect SPDIF out when "spdif" device is down. */		if ((stream->type == VORTEX_PCM_SPDIF) && (!en)) {			vortex_route(vortex, 1, 0x14,				     ADB_MIXOUT(vortex->mixspdif[0]),				     ADB_SPDIFOUT(0));			vortex_route(vortex, 1, 0x14,				     ADB_MIXOUT(vortex->mixspdif[1]),				     ADB_SPDIFOUT(1));		}#endif	/* CAPTURE ROUTES. */	} else {		int src[2], mix[2];		/* Get SRC and MIXER hardware resources. */		for (i = 0; i < nr_ch; i++) {			if ((mix[i] =			     vortex_adb_checkinout(vortex,						   stream->resources, en,						   VORTEX_RESOURCE_MIXOUT))			    < 0) {				memset(stream->resources, 0,				       sizeof(unsigned char) *				       VORTEX_RESOURCE_LAST);				return -EBUSY;			}			if ((src[i] =			     vortex_adb_checkinout(vortex,						   stream->resources, en,						   VORTEX_RESOURCE_SRC)) < 0) {				memset(stream->resources, 0,				       sizeof(unsigned char) *				       VORTEX_RESOURCE_LAST);				return -EBUSY;			}		}		/* Make capture routes. */		vortex_connection_mixin_mix(vortex, en, MIX_CAPT(0), mix[0], 0);		vortex_connection_mix_src(vortex, en, 0x11, mix[0], src[0]);		if (nr_ch == 1) {			vortex_connection_mixin_mix(vortex, en,						    MIX_CAPT(1), mix[0], 0);			vortex_connection_src_adbdma(vorte

⌨️ 快捷键说明

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