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

📄 s3c2410_dma_3.c

📁 自己写的支持S3C2410下的实时DMA操作的linux平台驱动程序 功能完善
💻 C
📖 第 1 页 / 共 2 页
字号:
	int num_start= num_be?(S3C2410_DMA_NUMSBUF/2):0;	int i ;	for (i = num_start;i < num_end;i ++)		s3c2410_dmabuffer_array_rd[i].dirty = 0;	printk("zero_dmabuffarray--%d--",num_be);}static int DMA0_STOP(void){		while (!(dma_types[DMA_CH0]->DMASKTRIG & CHANNEL_ON))	{dma_types[DMA_CH0]->DCON |= CLR_ATRELOAD;	dma_types[DMA_CH0]->DMASKTRIG = DMA_STOP;	}//dma_types[DMA_CH0]->DMASKTRIG = DMA_STOP;	printk("Channel is turnning down\n");	spin_unlock_wait(&protect_dma_lock);	printk("protect_dma_lock is locked");	return 0;}	static  int exter_DMA0_read(struct file *file, char *buf, size_t cnt, loff_t * ppos){		int err = 0,dirty[2] = {1,1},k;	for (k = 0; k< S3C2410_DMA_NUMSBUF;k++)		dirty[k > (S3C2410_DMA_NUMSBUF/2 -1)] *= s3c2410_dmabuffer_array_rd[k].dirty;	if (!(dirty[0]|dirty[1]))		return 0;	else 		{if (dirty[0])	{		err = copy_to_user(buf, s3c2410_dmabuffer_array_rd[0].start, PAGESIZE);		if (err< 0)			printk(KERN_ERR "unable to -----copy_to_user failure----\n");		zero_dmabuffarray(0);	}	else	{		err = copy_to_user(buf, s3c2410_dmabuffer_array_rd[4].start, PAGESIZE);		if (err< 0)			printk(KERN_ERR "unable to -----copy_to_user failure----\n");		zero_dmabuffarray(1);	}		}	return (PAGESIZE - err);			}//返回读出字节数小于static  int exter_DMA1_write(struct file *file, const char *buf,  size_t cnt, loff_t * ppos){	int err = 0;	if (usr_buff_write.active[0]||usr_buff_write.active[1])		return -1;	if (copy_from_user(&usr_buff_write,buf,sizeof(user_buf_t)))		{			printk( KERN_ERR "unable to -----copy_from_user failure----\n");			return -1;		}	printk("---pp---\n");	usr_buff_write.active[usr_buff_write.num] = 1;	usr_buff_write.curr_pos= usr_buff_write.start;	usr_buff_write.valid_size = cnt;	s3c2410_dmabuffer_array_wr.size_valid =((usr_buff_write.valid_size >( s3c2410_dmabuffer_array_wr.size)) ?(s3c2410_dmabuffer_array_wr.size):(usr_buff_write.valid_size));	err = copy_from_user( s3c2410_dmabuffer_array_wr.start, usr_buff_write.curr_pos,s3c2410_dmabuffer_array_wr.size_valid);		if (err < 0)		{			printk( KERN_ERR "unable to -----copy_from_user failure----\n");			return -1;		}		s3c2410_dmabuffer_array_wr.size_valid -= err;		usr_buff_write.curr_pos +=  s3c2410_dmabuffer_array_wr.size_valid;		printk("user_num +%d,size_valid %d\n",usr_buff_write.num,s3c2410_dmabuffer_array_wr.size_valid);	DMA1_write();	//wait_event_interruptible(wq, (usr_buff_write[user_num].write_success == cnt));	return ( usr_buff_write.curr_pos- usr_buff_write.start);}//成功返回字节数static int DMA0_check_fifo(){ 	unsigned int ret_tmp =	(*(volatile unsigned int*)( Mod612Addr ));     RunMode = ret_tmp & 0x1;	switch( RunMode )	{		case ENCODE:			DMA0_read();			break;		//case DECODE:		//	DMA1_write();		//	break;	}	return RunMode;}/******************************************///读时自动装载;//写时自动装载;/******************************************/static void clear_usr_buff(user_buf_t * p){	printk("Clear usr buff\n");	p ->active[p->num] =0;	p->curr_pos = p->start;	//wake_up_interruptible(&wq);}static void s3c2410_dma_done_callback(int irq, void *dev_id, struct pt_regs *regs){	int left,err;//time_t  timecul = xtime.tv_sec; 	dma_buf_t *dma_buff_curr = (dma_buf_t *)dev_id;	SRCPND = INT_DMA0;	INTPND = INT_DMA0;	if (dma_buff_curr->write_or_rd == DMA_BUF_WR)	{			printk(KERN_INFO DEVICE_NAME "----DMA0 Write interrupt handle--.\n");//s3c2410_dma_buff_rd.start);		if (!usr_buff_write.active[usr_buff_write.num])				goto end;		else if(! (left = (usr_buff_write.valid_size +usr_buff_write.start- usr_buff_write.curr_pos)))		{	//end				clear_usr_buff(&usr_buff_write);				goto end;		}		else			s3c2410_dmabuffer_array_wr.size_valid =((left >( s3c2410_dmabuffer_array_wr.size)) ?(s3c2410_dmabuffer_array_wr.size):left);		err = copy_from_user( s3c2410_dmabuffer_array_wr.start, usr_buff_write.curr_pos,s3c2410_dmabuffer_array_wr.size_valid);		if (err < 0)		{			printk( KERN_ERR "unable to -----copy_from_user failure----\n");			return ;		}		s3c2410_dmabuffer_array_wr.size_valid -= err;		usr_buff_write .curr_pos +=  s3c2410_dmabuffer_array_wr.size_valid;		printk("buff.%d,left +%d,curr_pos+%x,curr.size_valid +%d\n",usr_buff_write.num,left,usr_buff_write.curr_pos,s3c2410_dmabuffer_array_wr.size_valid);		dma_types[DMA_CH0]->DCON = rXDREQ0_WR_CTL|TX_CNT(dma_buff_cur_int.size_valid/16); 	}//up(&(dma0_sem));	else	{		//dma_types[DMA_CH0]->DIDST = DMA_BASE_ADDR(s3c2410_dmabuffer_array_rd[(ch0_buff_rd++)%S3C2410_DMA_NUMSBUF].dma_addr);		memcpy(s3c2410_dmabuffer_array_rd[ch0_buff_rd%S3C2410_DMA_NUMSBUF].start,s3c2410_dma_buff_rd.start,s3c2410_dma_buff_rd.size);		printk(KERN_INFO DEVICE_NAME "--DMA0 read interrupt ---read %d Bytes num--%d--\n",s3c2410_dma_buff_rd.size,(ch0_buff_rd%S3C2410_DMA_NUMSBUF));		s3c2410_dmabuffer_array_rd[ch0_buff_rd++%S3C2410_DMA_NUMSBUF].dirty = 1;		//dma_types[DMA_CH0]->DCON |= TX_CNT(DMA_TRANS_NUM);	}end:	up(&dma0_sem);	init_MUTEX(&dma0_sem);	//spin_unlock(&protect_dma_lock);	printk("protect_dma_lock is unlocked\n");	//	printk("time 4 +%d\n",(int)(timecul =(xtime.tv_sec - timecul)));///////////////	return ;}static int DMA_transfer_init(void){	int err;	err = request_irq(IRQ_DMA0, s3c2410_dma_done_callback, 0,					  "nDMA0", (void *)&dma_buff_cur_int);	if (err) 	{		printk( KERN_ERR			"%s: unable to request read IRQ %d for DMA channel\n",			"DMA0", IRQ_DMA0);		return err;	}	PRIORITY |= 0x00000000;	INTMOD |= 0x00000000;	INTMSK &= ~INT_DMA0;	return 0;}/**********************************************************************************************************											 File Operations function**open,release********************************************************************************************************/static int s3c2410_dma_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){	int ret = 0;	if (arg > 4) return -EINVAL;	switch(cmd) 	{		case DMA_BUF_WR0:			ret = usr_buff_write.active[0];			break;		case DMA_BUF_WR1:			ret = usr_buff_write.active[1];			break;		case DMA_CHECK:			ret = DMA0_check_fifo();			break;		case DMA_DSTAT0:			ret = DSTAT0;			break;		case DMA_SET_STOP:			DMA0_STOP();			break;		case DMA_SET_READ:			DMA0_read();		default:			return -EINVAL;	}	return ret;}static int s3c2410_dma_open(struct inode *inode, struct file *filp){	//************Only to Test*******//	unsigned int	ret_tmp;	char  *MapAddr = NULL;	dma_buff_initizlize();	DMA_transfer_init();	//init_waitqueue_head(&wq);	init_MUTEX(&dma0_sem);	//spin_lock_init(&protect_write_lock);	/*****************REQ0 Input**************/	GPBCON|= (2<<20)|(2<<18);	/***************************************/	//0x28000000--0x28000408		MapAddr = ioremap(HARDWARE_FIFO_ADDR,0x100);     Cmd612Addr  = MapAddr; 	Dat612Addr  = MapAddr+0x04; //base+0x04	//Fifo612Addr = MapAddr+0x08; //base+0x08	Int612Addr  = MapAddr+0x18; //base+0x10	Cfg612Addr  = MapAddr+0x1c; //base+0x10	Mod612Addr  = MapAddr+0x24; //base+0x1c	/*******************************/ 	ret_tmp =	(*(volatile unsigned int*)( Cfg612Addr ));    	boardtype = (unsigned short)ret_tmp&0xff;  	boardversion = ((ret_tmp&0xf0000000)>>28)*100+((ret_tmp&0x0f000000)>>24); 	ret_tmp =	(*(volatile unsigned int*)( Mod612Addr ));     RunMode = ret_tmp & 0x1;   	printk ("MPSIO nGCS5 Driver Ver2.0.071022 build022 Loaded \n");  	printk ("(c)Copyright  1992~2007 \n");  	printk ("StartAddr:0x%x Range:0~%d\n", HARDWARE_FIFO_ADDR, 0x100);  	printk ("Boardtype=0x%x   HWVersion=%d\n", boardtype, boardversion);  	printk ("BANK5=0x%x->\n", BANKCON5);  		//	fifo_check_rd = MapAddr + 0x08;	fifo_check_wr = MapAddr + 0x08;		///////////////////////////////////////////////////	//BANKCON5 = 0x2a70;  	printk ("BANK5=0x%x\n", BANKCON5);		DMA0_check_fifo();  	if( RunMode==ENCODE )  	{  		LVT612_EN_Init();  		printk ("Mode%d: ENCODE\n", RunMode);  	}  	else  	{  		LVT612_DE_Init();  		printk ("Mode%d: DECODE\n", RunMode);	}		///////////////////////////////////////////////////		MOD_INC_USE_COUNT;	printk(KERN_INFO DEVICE_NAME ": opened.\n");	return 0;}static int s3c2410_dma_release(struct inode *inode, struct file *filp){	dma_clear_buf(&dma_buff_temp_2page,1);//dma mem free	dma_clear_buf(&s3c2410_dmabuffer_array_wr,1);//dma mem free	dma_clear_buf(&s3c2410_dma_buff_rd,1);//dma mem free	free_irq(IRQ_DMA0,(void *)&dma_buff_cur_int);	MOD_DEC_USE_COUNT;	printk(KERN_INFO DEVICE_NAME ": released.\n");	return 0;}static struct file_operations s3c2410_dma_fops = {	owner:	THIS_MODULE,	read:	exter_DMA0_read,	write:	exter_DMA1_write,	ioctl:	s3c2410_dma_ioctl,	open:	s3c2410_dma_open,	mmap:	s3c2410_dma_mmap,	release:	s3c2410_dma_release,};static int __init s3c2410_dma_init(void){	dma_types[0] = (dma_regs_t *)io_p2v(0x4b000000);	//Register Char Driver	devfs_handle = devfs_register(NULL, DEVICE_NAME, DEVFS_FL_AUTO_DEVNUM,		0, 0, S_IFCHR | S_IRUSR | S_IWUSR, &s3c2410_dma_fops, NULL);	printk(KERN_INFO DEVICE_NAME ": Initialize s3c2410_DMA_char OK.\n");	return 0;}static void __exit s3c2410_dma_exit(void){	devfs_unregister(devfs_handle);}module_init(s3c2410_dma_init);module_exit(s3c2410_dma_exit);/***********************************************************************************************************                                     End of File*********************************************************************************************************/

⌨️ 快捷键说明

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