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

📄 au88x0_core.c

📁 鼎力推荐!本程序是基于嵌入式LUNUX系统开发的源程序代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	dma->cfg0 = 0;	dma->cfg1 = 0;	switch (count) {		/* Four or more pages */	default:	case 4:		dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1);		hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc,			snd_sgbuf_get_addr(sgbuf, psize * 3));		/* 3 pages */	case 3:		dma->cfg0 |= 0x12000000;		dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);		hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4)  + 0x8,			snd_sgbuf_get_addr(sgbuf, psize * 2));		/* 2 pages */	case 2:		dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1);		hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4,			snd_sgbuf_get_addr(sgbuf, psize));		/* 1 page */	case 1:		dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);		hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),			snd_sgbuf_get_addr(sgbuf, 0));		break;	}	hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG0 + (wtdma << 3), dma->cfg0);	hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG1 + (wtdma << 3), dma->cfg1);	vortex_wtdma_setfirstbuffer(vortex, wtdma);	vortex_wtdma_setstartbuffer(vortex, wtdma, 0);}static voidvortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d,		     /*int e, */ unsigned long offset){	stream_t *dma = &vortex->dma_wt[wtdma];	//dma->this_08 = e;	dma->dma_unknown = d;	dma->dma_ctrl = 0;	dma->dma_ctrl =	    ((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));	/* PCMOUT interrupt */	dma->dma_ctrl =	    (dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);	/* Always playback. */	dma->dma_ctrl |= (1 << DIR_SHIFT);	/* Audio Format */	dma->dma_ctrl =	    (dma->dma_ctrl & FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);	/* Write into hardware */	hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);}static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma){	stream_t *dma = &vortex->dma_wt[wtdma];	int page, p, pp, delta, i;	page =	    (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) &	     WT_SUBBUF_MASK)	    >> WT_SUBBUF_SHIFT;	if (dma->nr_periods >= 4)		delta = (page - dma->period_real) & 3;	else {		delta = (page - dma->period_real);		if (delta < 0)			delta += dma->nr_periods;	}	if (delta == 0)		return 0;	/* refresh hw page table */	if (dma->nr_periods > 4) {		for (i = 0; i < delta; i++) {			/* p: audio buffer page index */			p = dma->period_virt + i + 4;			if (p >= dma->nr_periods)				p -= dma->nr_periods;			/* pp: hardware DMA page index. */			pp = dma->period_real + i;			if (pp >= 4)				pp -= 4;			hwwrite(vortex->mmio,				VORTEX_WTDMA_BUFBASE +				(((wtdma << 2) + pp) << 2),				snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p));			/* Force write thru cache. */			hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE +			       (((wtdma << 2) + pp) << 2));		}	}	dma->period_virt += delta;	if (dma->period_virt >= dma->nr_periods)		dma->period_virt -= dma->nr_periods;	dma->period_real = page;	if (delta != 1)		printk(KERN_WARNING "vortex: wt virt = %d, delta = %d\n",		       dma->period_virt, delta);	return delta;}#if 0static voidvortex_wtdma_getposition(vortex_t * vortex, int wtdma, int *subbuf, int *pos){	int temp;	temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));	*subbuf = (temp >> WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK;	*pos = temp & POS_MASK;}static int vortex_wtdma_getcursubuffer(vortex_t * vortex, int wtdma){	return ((hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) >>		 POS_SHIFT) & POS_MASK);}#endifstatic int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma){	stream_t *dma = &vortex->dma_wt[wtdma];	int temp;	temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));	//temp = (temp & POS_MASK) + (((temp>>WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK)*(dma->cfg0&POS_MASK));	temp = (temp & POS_MASK) + ((dma->period_virt) * (dma->period_bytes));	return temp;}static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma){	stream_t *dma = &vortex->dma_wt[wtdma];	int this_8 = 0, this_4 = 0;	switch (dma->fifo_status) {	case FIFO_START:		vortex_fifo_setwtvalid(vortex, wtdma,				       dma->fifo_enabled ? 1 : 0);		break;	case FIFO_STOP:		this_8 = 1;		hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),			dma->dma_ctrl);		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,				      this_4, this_8,				      dma->fifo_enabled ? 1 : 0, 0);		break;	case FIFO_PAUSE:		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,				      this_4, this_8,				      dma->fifo_enabled ? 1 : 0, 0);		break;	}	dma->fifo_status = FIFO_START;}static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma){	stream_t *dma = &vortex->dma_wt[wtdma];	int this_8 = 0, this_4 = 0;	switch (dma->fifo_status) {	case FIFO_STOP:		hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),			dma->dma_ctrl);		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,				      this_4, this_8,				      dma->fifo_enabled ? 1 : 0, 0);		break;	case FIFO_PAUSE:		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,				      this_4, this_8,				      dma->fifo_enabled ? 1 : 0, 0);		break;	}	dma->fifo_status = FIFO_START;}static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma){	stream_t *dma = &vortex->dma_wt[wtdma];	int this_8 = 0, this_4 = 0;	switch (dma->fifo_status) {	case FIFO_START:		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,				      this_4, this_8, 0, 0);		break;	case FIFO_STOP:		hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),			dma->dma_ctrl);		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,				      this_4, this_8, 0, 0);		break;	}	dma->fifo_status = FIFO_PAUSE;}static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma){	stream_t *dma = &vortex->dma_wt[wtdma];	int this_4 = 0, this_8 = 0;	if (dma->fifo_status == FIFO_START)		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,				      this_4, this_8, 0, 0);	else if (dma->fifo_status == FIFO_STOP)		return;	dma->fifo_status = FIFO_STOP;	dma->fifo_enabled = 0;}#endif/* ADB Routes */typedef int ADBRamLink;static void vortex_adb_init(vortex_t * vortex){	int i;	/* it looks like we are writing more than we need to...	 * if we write what we are supposed to it breaks things... */	hwwrite(vortex->mmio, VORTEX_ADB_SR, 0);	for (i = 0; i < VORTEX_ADB_RTBASE_COUNT; i++)		hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (i << 2),			hwread(vortex->mmio,			       VORTEX_ADB_RTBASE + (i << 2)) | ROUTE_MASK);	for (i = 0; i < VORTEX_ADB_CHNBASE_COUNT; i++) {		hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (i << 2),			hwread(vortex->mmio,			       VORTEX_ADB_CHNBASE + (i << 2)) | ROUTE_MASK);	}}static void vortex_adb_en_sr(vortex_t * vortex, int channel){	hwwrite(vortex->mmio, VORTEX_ADB_SR,		hwread(vortex->mmio, VORTEX_ADB_SR) | (0x1 << channel));}static void vortex_adb_dis_sr(vortex_t * vortex, int channel){	hwwrite(vortex->mmio, VORTEX_ADB_SR,		hwread(vortex->mmio, VORTEX_ADB_SR) & ~(0x1 << channel));}static voidvortex_adb_addroutes(vortex_t * vortex, unsigned char channel,		     ADBRamLink * route, int rnum){	int temp, prev, lifeboat = 0;	if ((rnum <= 0) || (route == NULL))		return;	/* Write last routes. */	rnum--;	hwwrite(vortex->mmio,		VORTEX_ADB_RTBASE + ((route[rnum] & ADB_MASK) << 2),		ROUTE_MASK);	while (rnum > 0) {		hwwrite(vortex->mmio,			VORTEX_ADB_RTBASE +			((route[rnum - 1] & ADB_MASK) << 2), route[rnum]);		rnum--;	}	/* Write first route. */	temp =	    hwread(vortex->mmio,		   VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;	if (temp == ADB_MASK) {		/* First entry on this channel. */		hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),			route[0]);		vortex_adb_en_sr(vortex, channel);		return;	}	/* Not first entry on this channel. Need to link. */	do {		prev = temp;		temp =		    hwread(vortex->mmio,			   VORTEX_ADB_RTBASE + (temp << 2)) & ADB_MASK;		if ((lifeboat++) > ADB_MASK) {			printk(KERN_ERR			       "vortex_adb_addroutes: unending route! 0x%x\n",			       *route);			return;		}	}	while (temp != ADB_MASK);	hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), route[0]);}static voidvortex_adb_delroutes(vortex_t * vortex, unsigned char channel,		     ADBRamLink route0, ADBRamLink route1){	int temp, lifeboat = 0, prev;	/* Find route. */	temp =	    hwread(vortex->mmio,		   VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;	if (temp == (route0 & ADB_MASK)) {		temp =		    hwread(vortex->mmio,			   VORTEX_ADB_RTBASE + ((route1 & ADB_MASK) << 2));		if ((temp & ADB_MASK) == ADB_MASK)			vortex_adb_dis_sr(vortex, channel);		hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),			temp);		return;	}	do {		prev = temp;		temp =		    hwread(vortex->mmio,			   VORTEX_ADB_RTBASE + (prev << 2)) & ADB_MASK;		if (((lifeboat++) > ADB_MASK) || (temp == ADB_MASK)) {			printk(KERN_ERR			       "vortex_adb_delroutes: route not found! 0x%x\n",			       route0);			return;		}	}	while (temp != (route0 & ADB_MASK));	temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));	if ((temp & ADB_MASK) == route1)		temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));	/* Make bridge over deleted route. */	hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), temp);}static voidvortex_route(vortex_t * vortex, int en, unsigned char channel,	     unsigned char source, unsigned char dest){	ADBRamLink route;	route = ((source & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);	if (en) {		vortex_adb_addroutes(vortex, channel, &route, 1);		if ((source < (OFFSET_SRCOUT + NR_SRC))		    && (source >= OFFSET_SRCOUT))			vortex_src_addWTD(vortex, (source - OFFSET_SRCOUT),					  channel);		else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))			 && (source >= OFFSET_MIXOUT))			vortex_mixer_addWTD(vortex,					    (source - OFFSET_MIXOUT), channel);	} else {		vortex_adb_delroutes(vortex, channel, route, route);		if ((source < (OFFSET_SRCOUT + NR_SRC))		    && (source >= OFFSET_SRCOUT))			vortex_src_delWTD(vortex, (source - OFFSET_SRCOUT),					  channel);		else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))			 && (source >= OFFSET_MIXOUT))			vortex_mixer_delWTD(vortex,					    (source - OFFSET_MIXOUT), channel);	}}#if 0static voidvortex_routes(vortex_t * vortex, int en, unsigned char channel,	      unsigned char source, unsigned char dest0, unsigned char dest1){	ADBRamLink route[2];	route[0] = ((source & ADB_MASK) << ADB_SHIFT) | (dest0 & ADB_MASK);	route[1] = ((source & ADB_MASK) << ADB_SHIFT) | (dest1 & ADB_MASK);	if (en) {		vortex_adb_addroutes(vortex, channel, route, 2);		if ((source < (OFFSET_SRCOUT + NR_SRC))		    && (source >= (OFFSET_SRCOUT)))			vortex_src_addWTD(vortex, (source - OFFSET_SRCOUT),					  channel);		else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))			 && (source >= (OFFSET_MIXOUT)))			vortex_mixer_addWTD(vortex,					    (source - OFFSET_MIXOUT), channel);	} else {		vortex_adb_delroutes(vortex, channel, route[0], route[1]);		if ((source < (OFFSET_SRCOUT + NR_SRC))		    && (source >= (OFFSET_SRCOUT)))			vortex_src_delWTD(vortex, (source - OFFSET_SRCOUT),					  channel);		else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))			 && (source >= (OFFSET_MIXOUT)))			vortex_mixer_delWTD(vortex,					    (source - OFFSET_MIXOUT), channel);	}}#endif/* Route two sources to same target. Sources must be of same class !!! */static voidvortex_routeLRT(vortex_t * vortex, int en, unsigned char ch,		unsigned char source0, unsigned char source1,		unsigned char dest){	ADBRamLink route[2];	route[0] = ((source0 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);	route[1] = ((source1 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);	if (dest < 0x10)		route[1] = (route[1] & ~ADB_MASK) | (dest + 0x20);	/* fifo A */	if (en) {		vortex_adb_addroutes(vortex, ch, route, 2);		if ((source0 < (OFFSET_SRCOUT + NR_SRC))		    && (source0 >= OFFSET_SRCOUT)) {			vortex_src_addWTD(vortex,					  (source0 - OFFSET_SRCOUT), ch);			vortex_src_addWTD(vortex,					  (source1 - OFFSET_SRCOUT), ch);		} else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))			   && (source0 >= OFFSET_MIXOUT)) {			vortex_mixer_addWTD(vortex,					    (source0 - OFFSET_MIXOUT), ch);			vortex_mixer_addWTD(vortex,					    (source1 - OFFSET_MIXOUT), ch);		}	} else {		vortex_adb_delroutes(vortex, ch, route[0], route[1]);		if ((source0 < (OFFSET_SRCOUT + NR_SRC))		    && (source0 >= OFFSET_SRCOUT)) {			vortex_src_delWTD(vortex,					  (source0 - OFFSET_SRCOUT), ch);			vortex_src_delWTD(vortex,					  (source1 - OFFSET_SRCOUT), ch);		} else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))			   && (source0 >= OFFSET_MIXOUT)) {			vortex_mixer_delWTD(vortex,					    (source0 - OFFSET_MIXOUT), ch);			vortex_mixer_delWTD(vortex,					    (source1 - OFFSET_MIXOUT), ch);		}	}}/* Connection stuff */// Connect adbdma to src('s).static voidvortex_connection_adbdma_src(vortex_t * vortex, int en, unsigned char ch,			     unsigned char adbdma, unsigned char src){	vortex_route(vortex, en, ch, ADB_DMA(adbdma), ADB_SRCIN(src));}

⌨️ 快捷键说明

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