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

📄 au88x0_core.c

📁 鼎力推荐!本程序是基于嵌入式LUNUX系统开发的源程序代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			break;		}	}	while (temp & FIFO_RDONLY);	if (valid) {		if ((temp & FIFO_VALID) == 0) {			vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);	// this_4#ifdef CHIP_AU8820			temp = (this_4 & 0x1f) << 0xb;#else			temp = (this_4 & 0x3f) << 0xc;#endif			temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);			temp = (temp & 0xfffffff3) | ((priority & 3) << 2);			temp = (temp & 0xffffffef) | ((valid & 1) << 4);			temp |= FIFO_U1;			temp = (temp & 0xffffffdf) | ((empty & 1) << 5);#ifdef CHIP_AU8820			temp = (temp & 0xfffbffff) | ((f & 1) << 0x12);#endif#ifdef CHIP_AU8830			temp = (temp & 0xf7ffffff) | ((f & 1) << 0x1b);			temp = (temp & 0xefffffff) | ((f & 1) << 0x1c);#endif#ifdef CHIP_AU8810			temp = (temp & 0xfeffffff) | ((f & 1) << 0x18);			temp = (temp & 0xfdffffff) | ((f & 1) << 0x19);#endif		}	} else {		if (temp & FIFO_VALID) {#ifdef CHIP_AU8820			temp = ((f & 1) << 0x12) | (temp & 0xfffbffef);#endif#ifdef CHIP_AU8830			temp =			    ((f & 1) << 0x1b) | (temp & 0xe7ffffef) | FIFO_BITS;#endif#ifdef CHIP_AU8810			temp =			    ((f & 1) << 0x18) | (temp & 0xfcffffef) | FIFO_BITS;#endif		} else			/*if (this_8[fifo]) */			vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);	}	hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);	hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));/*	    do {		temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));		if (lifeboat++ > 0xbb8) {			printk(KERN_ERR "Vortex: vortex_fifo_setwtctrl fail (hanging)\n");			break;		}    } while ((temp & FIFO_RDONLY)&&(temp & FIFO_VALID)&&(temp != 0xFFFFFFFF));			if (valid) {		if (temp & FIFO_VALID) {			temp = 0x40000;			//temp |= 0x08000000;			//temp |= 0x10000000;			//temp |= 0x04000000;			//temp |= 0x00400000;			temp |= 0x1c400000;			temp &= 0xFFFFFFF3;			temp &= 0xFFFFFFEF;			temp |= (valid & 1) << 4;			hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);			return;		} else {			vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);			return;		}	} else {		temp &= 0xffffffef;		temp |= 0x08000000;		temp |= 0x10000000;		temp |= 0x04000000;		temp |= 0x00400000;		hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);		temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));		//((temp >> 6) & 0x3f) 				priority = 0;		if (((temp & 0x0fc0) ^ ((temp >> 6) & 0x0fc0)) & 0FFFFFFC0)			vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);		valid = 0xfb;		temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);		temp = (temp & 0xfffdffff) | ((f & 1) << 0x11);		temp = (temp & 0xfffffff3) | ((priority & 3) << 2);		temp = (temp & 0xffffffef) | ((valid & 1) << 4);		temp = (temp & 0xffffffdf) | ((empty & 1) << 5);		hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);	}		*/	/*	   temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);	   temp = (temp & 0xfffdffff) | ((f & 1) << 0x11);	   temp = (temp & 0xfffffff3) | ((priority & 3) << 2);	   temp = (temp & 0xffffffef) | ((valid & 1) << 4);	   temp = (temp & 0xffffffdf) | ((empty & 1) << 5);	   #ifdef FIFO_BITS	   temp = temp | FIFO_BITS | 40000;	   #endif	   // 0x1c440010, 0x1c400000	   hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);	 */}#endifstatic void vortex_fifo_init(vortex_t * vortex){	int x;	unsigned long addr;	/* ADB DMA channels fifos. */	addr = VORTEX_FIFO_ADBCTRL + ((NR_ADB - 1) * 4);	for (x = NR_ADB - 1; x >= 0; x--) {		hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1));		if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1))			printk(KERN_ERR "bad adb fifo reset!");		vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE);		addr -= 4;	}#ifndef CHIP_AU8810	/* WT DMA channels fifos. */	addr = VORTEX_FIFO_WTCTRL + ((NR_WT - 1) * 4);	for (x = NR_WT - 1; x >= 0; x--) {		hwwrite(vortex->mmio, addr, FIFO_U0);		if (hwread(vortex->mmio, addr) != FIFO_U0)			printk(KERN_ERR			       "bad wt fifo reset (0x%08lx, 0x%08x)!\n",			       addr, hwread(vortex->mmio, addr));		vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE);		addr -= 4;	}#endif	/* trigger... */#ifdef CHIP_AU8820	hwwrite(vortex->mmio, 0xf8c0, 0xd03);	//0x0843 0xd6b#else#ifdef CHIP_AU8830	hwwrite(vortex->mmio, 0x17000, 0x61);	/* wt a */	hwwrite(vortex->mmio, 0x17004, 0x61);	/* wt b */#endif	hwwrite(vortex->mmio, 0x17008, 0x61);	/* adb */#endif}/* ADBDMA */static void vortex_adbdma_init(vortex_t * vortex){}static void vortex_adbdma_setfirstbuffer(vortex_t * vortex, int adbdma){	stream_t *dma = &vortex->dma_adb[adbdma];	hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),		dma->dma_ctrl);}static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb){	stream_t *dma = &vortex->dma_adb[adbdma];	//hwwrite(vortex->mmio, VORTEX_ADBDMA_START + (adbdma << 2), sb << (((NR_ADB-1)-((adbdma&0xf)*2))));	hwwrite(vortex->mmio, VORTEX_ADBDMA_START + (adbdma << 2),		sb << ((0xf - (adbdma & 0xf)) * 2));	dma->period_real = dma->period_virt = sb;}static voidvortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,			 snd_pcm_sgbuf_t * sgbuf, int psize, int count){	stream_t *dma = &vortex->dma_adb[adbdma];	if (sgbuf == NULL) {		printk(KERN_INFO "vortex: FATAL: sgbuf is NULL!\n");		return;	}	//printk(KERN_INFO "vortex: page count = %d, tblcount = %d\n", count, sgbuf->tblsize);	dma->period_bytes = psize;	dma->nr_periods = count;	dma->sgbuf = sgbuf;	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_ADBDMA_BUFBASE + (adbdma << 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_ADBDMA_BUFBASE + (adbdma << 4) + 0x8,			snd_sgbuf_get_addr(sgbuf, psize * 2));		/* 2 pages */	case 2:		dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize - 1);		hwwrite(vortex->mmio,			VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x4,			snd_sgbuf_get_addr(sgbuf, psize));		/* 1 page */	case 1:		dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);		hwwrite(vortex->mmio,			VORTEX_ADBDMA_BUFBASE + (adbdma << 4),			snd_sgbuf_get_addr(sgbuf, 0));		break;	}	//printk("vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n", dma->cfg0, dma->cfg1);	hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG0 + (adbdma << 3), dma->cfg0);	hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG1 + (adbdma << 3), dma->cfg1);	vortex_adbdma_setfirstbuffer(vortex, adbdma);	vortex_adbdma_setstartbuffer(vortex, adbdma, 0);}static voidvortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir,		      int fmt, int d, unsigned long offset){	stream_t *dma = &vortex->dma_adb[adbdma];	dma->dma_unknown = d;	dma->dma_ctrl =	    ((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));	/* Enable PCMOUT interrupts. */	dma->dma_ctrl =	    (dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);	dma->dma_ctrl =	    (dma->dma_ctrl & ~DIR_MASK) | ((dir << DIR_SHIFT) & DIR_MASK);	dma->dma_ctrl =	    (dma->dma_ctrl & ~FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);	hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),		dma->dma_ctrl);	hwread(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2));}static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma){	stream_t *dma = &vortex->dma_adb[adbdma];	int page, p, pp, delta, i;	page =	    (hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2)) &	     ADB_SUBBUF_MASK) >> ADB_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_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), dma->table[p].addr);			hwwrite(vortex->mmio,				VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),				snd_sgbuf_get_addr(dma->sgbuf,				dma->period_bytes * p));			/* Force write thru cache. */			hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE +			       (((adbdma << 2) + pp) << 2));		}	}	dma->period_virt += delta;	dma->period_real = page;	if (dma->period_virt >= dma->nr_periods)		dma->period_virt -= dma->nr_periods;	if (delta != 1)		printk(KERN_INFO "vortex: %d virt=%d, real=%d, delta=%d\n",		       adbdma, dma->period_virt, dma->period_real, delta);	return delta;}static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {	stream_t *dma = &vortex->dma_adb[adbdma];	int p, pp, i;	/* refresh hw page table */	for (i=0 ; i < 4 && i < dma->nr_periods; i++) {		/* p: audio buffer page index */		p = dma->period_virt + i;		if (p >= dma->nr_periods)			p -= dma->nr_periods;		/* pp: hardware DMA page index. */		pp = dma->period_real + i;		if (dma->nr_periods < 4) {			if (pp >= dma->nr_periods)				pp -= dma->nr_periods;		}		else {			if (pp >= 4)				pp -= 4;		}		hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p));		/* Force write thru cache. */		hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));	}}static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma){	stream_t *dma = &vortex->dma_adb[adbdma];	int temp;	temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2));	temp = (dma->period_virt * dma->period_bytes) + (temp & POS_MASK);	return (temp);}static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma){	int this_8 = 0 /*empty */ , this_4 = 0 /*priority */ ;	stream_t *dma = &vortex->dma_adb[adbdma];	switch (dma->fifo_status) {	case FIFO_START:		vortex_fifo_setadbvalid(vortex, adbdma,					dma->fifo_enabled ? 1 : 0);		break;	case FIFO_STOP:		this_8 = 1;		hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),			dma->dma_ctrl);		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,				       this_4, this_8,				       dma->fifo_enabled ? 1 : 0, 0);		break;	case FIFO_PAUSE:		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,				       this_4, this_8,				       dma->fifo_enabled ? 1 : 0, 0);		break;	}	dma->fifo_status = FIFO_START;}static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma){	stream_t *dma = &vortex->dma_adb[adbdma];	int this_8 = 1, this_4 = 0;	switch (dma->fifo_status) {	case FIFO_STOP:		hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),			dma->dma_ctrl);		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,				       this_4, this_8,				       dma->fifo_enabled ? 1 : 0, 0);		break;	case FIFO_PAUSE:		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,				       this_4, this_8,				       dma->fifo_enabled ? 1 : 0, 0);		break;	}	dma->fifo_status = FIFO_START;}static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma){	stream_t *dma = &vortex->dma_adb[adbdma];	int this_8 = 0, this_4 = 0;	switch (dma->fifo_status) {	case FIFO_START:		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,				       this_4, this_8, 0, 0);		break;	case FIFO_STOP:		hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),			dma->dma_ctrl);		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,				       this_4, this_8, 0, 0);		break;	}	dma->fifo_status = FIFO_PAUSE;}#if 0				// Using pause insteadstatic void vortex_adbdma_stopfifo(vortex_t * vortex, int adbdma){	stream_t *dma = &vortex->dma_adb[adbdma];	int this_4 = 0, this_8 = 0;	if (dma->fifo_status == FIFO_START)		vortex_fifo_setadbctrl(vortex, adbdma, 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/* WTDMA */#ifndef CHIP_AU8810static void vortex_wtdma_setfirstbuffer(vortex_t * vortex, int wtdma){	//int this_7c=dma_ctrl;	stream_t *dma = &vortex->dma_wt[wtdma];	hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);}static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb){	stream_t *dma = &vortex->dma_wt[wtdma];	//hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2), sb << ((0x1f-(wtdma&0xf)*2)));	hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2),		sb << ((0xf - (wtdma & 0xf)) * 2));	dma->period_real = dma->period_virt = sb;}static voidvortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,			snd_pcm_sgbuf_t * sgbuf, int psize, int count){	stream_t *dma = &vortex->dma_wt[wtdma];	dma->period_bytes = psize;	dma->nr_periods = count;	dma->sgbuf = sgbuf;

⌨️ 快捷键说明

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