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

📄 d11_dma.c

📁 在linux环境下arm2410的 dma驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	len += sprintf(buf+len, "LCDCON2=%8x\n", LCDCON2);
	len += sprintf(buf+len, "LCDCON3=%8x\n", LCDCON3);
	len += sprintf(buf+len, "LCDCON4=%8x\n", LCDCON4);
	len += sprintf(buf+len, "LCDCON5=%8x\n", LCDCON5);
	
	len += sprintf(buf+len, "LCDADDR1=%8x\n", LCDADDR1);
	len += sprintf(buf+len, "LCDADDR2=%8x\n", LCDADDR2);
	len += sprintf(buf+len, "LCDADDR3=%8x\n", LCDADDR3);
	return len;
}

static ssize_t d11_dma_proc_write(struct file *filp, const char *buf, unsigned long len, void *data)
{	
	return 0;
}

static int d11_dma_create_proc(void)
{	
	d11_dma_proc_entry = create_proc_entry("d11_dma", 0644, NULL);
	if(d11_dma_proc_entry == NULL){
		printk("d11_dma: Couldn't create proc entry!\n");
		return -ENOMEM;
	}
	d11_dma_proc_entry->read_proc = d11_dma_proc_read;
	d11_dma_proc_entry->write_proc = d11_dma_proc_write;
	d11_dma_proc_entry->owner = THIS_MODULE;
	return 0;
}

static void d11_dma_remove_proc(void)
{
	remove_proc_entry("d11_dma", NULL);
}
/**************************************************************************/
static int d11_dma_open(struct inode * inode, struct file * filp)
{		
	if(d11_dma_ucount){			// restrict one process open this device.
		return -EBUSY;
	}
	d11_dma_ucount++;
	MOD_INC_USE_COUNT;	
	DPRINTK("open\n");
		
	return 0;
}

static int d11_dma_release(struct inode * inode, struct file * filp)
{
	d11_dma_ucount--;
	MOD_DEC_USE_COUNT;
	DPRINTK("release\n");
	return 0;
}

static int d11_dma_ioctl(struct inode * inode, struct file * filp, unsigned int command, unsigned long arg)
{
	struct image_dma_t image_dma_data;
			
	copy_from_user(&image_dma_data, (struct image_dma_t *)(arg), sizeof(image_dma_data));
		
	switch(command){
		case D11_DMA_IOCWRITE:
			if(image_review_buf.freeze && (!image_dma_data.freeze)){
				flag_unfreeze = 1;
			}
			image_review_buf.freeze = image_dma_data.freeze;
			
			/*********  请求写入的新回放区小于原回放区大小***************/
			if(image_dma_data.nr_mmblks < image_review_buf.nr_mmblks) {
				return 0;
			}
			/*******************************************************************************
				  请求写入的新回放区大于原回放区大小且
				         不超过IMG_MAX_NR 定义的最大回放区大小
			*******************************************************************************/
			else if((image_dma_data.nr_mmblks > image_review_buf.nr_mmblks) 
					&& (image_dma_data.nr_mmblks <= IMG_MAX_NR)) {
				return 0;
			}
			return 0;
			
		/*********************** 读取回放区数据***********************************/	
		case D11_DMA_IOCREAD:
			copy_to_user((struct image_dma_t *)(arg), &image_review_buf, sizeof(image_review_buf));
			return 0;			
		
		#ifdef D11_DMA_DEBUG
		case D11_DMA_IOCDBGRST:
			/* 
				in debug mode, this can remove module forcely 
			*/
			while(MOD_IN_USE)
					MOD_DEC_USE_COUNT;
			MOD_INC_USE_COUNT;
			return 0;
		#endif		/* D11_DMA_DEBUG */

		default:
			return -ENOTTY;		// Inappropriate ioctl for device.
			
	}
	return -ENOTTY;				// can't recognize the command.
}


static struct file_operations d11_dma_fops = {
	ioctl:	d11_dma_ioctl,
	poll:		d11_dma_poll,
	mmap:	d11_dma_mmap,
	read:	d11_dma_read,
	write:	d11_dma_write,
	open:	d11_dma_open,
	release:	d11_dma_release,
};

#ifdef CONFIG_DEVFS_FS
	static devfs_handle_t devfs_d11_dma_dir, devfs_d11_dma;
#endif

static int __init init_xdreq0_dma(void)
{
	int ret;
	
	set_external_irq(IRQ_EINT2, EXT_RISING_EDGE, GPIO_PULLUP_EN);	// 设置外中断2
	ret = request_irq(IRQ_EINT2, handler_isr_eint2, SA_INTERRUPT, DEVICE_NAME, NULL);
	if(ret < 0){
		printk(" unable to get EINT2 interrupts\n" );
		return -EBUSY;
	}

	ret = request_irq(IRQ_DMA0, handler_Dma0Done, SA_INTERRUPT, DEVICE_NAME, NULL);
	if(ret < 0){
		printk(" unable to get DMA0 interrupts\n" );
		return -EBUSY;
	}

	set_gpio_ctrl(GPIO_B9 | GPIO_PULLUP_EN | GPIO_MODE_nXDACK);		// GPB9=nXDACK0
	set_gpio_ctrl(GPIO_B10 | GPIO_PULLUP_EN | GPIO_MODE_nXDREQ);		// GPB10=nXDREQ0

	//(void *)fpga_dma0_reg = ioremap(FPGA_DMA0, 4);					// Can delete.

	GPHCON &= (~(0x0f << 18));
	GPHCON |=  (0x0a << 18);		//GPH9、GPH10 set as clkout.
	MISCCR=0x10410;	  			// clkout0=48M,clkout1=PCLK
	DISRC0 = FPGA_DMA0;			// Bank5 0x28000000
	DISRCC0 = (0<<1)+(1<<0);	// AHB,fixed
	DIDST0 = image_review_buf.image_dma_mmphy[0];
	DIDSTC0 = (0<<1)+(0<<0);	// AHB, inc
	DCON0 = (1<<31)+(1<<30)+(1<<29)+(1<<28)+(0<<27)+(0<<24)+(1<<23)+(1<<22)+(2<<20)+IMG_SIZE/16;
	//handshake, sync HCLK, TC int, burst tx, single service, nXDREQ0, H/W request, auto-reload off, word, 64hw
	DMTRIG0 = (0<<2)+(1<<1)+0;    //no-stop, DMA0 channel on, no-sw trigger	
	
	DPRINTK("INTMSK=0x%8x\n", INTMSK);
	DPRINTK("GPBCON=0x%8x\n", GPBCON);	
	DPRINTK("MISCCR=0x%8x\n", MISCCR);
	DPRINTK("DISRC0=0x%8x\n", DISRC0);
	DPRINTK("DISRCC0=0x%8x\n", DISRCC0);
	DPRINTK("DIDST0=0x%8x\n", DIDST0);
	DPRINTK("DIDSTC0=0x%8x\n", DIDSTC0);
	DPRINTK("DCON0=0x%8x\n", DCON0);
	DPRINTK("DMTRIG0=0x%8x\n", DMTRIG0);
	
	DPRINTK("dma init finished!\n");
	return 0;
}

static int __init image_init_dma(void)
{
	int ret;
	ret = init_xdreq0_dma();
	//s3c2410_request_dma("XDREQ0", DMA_CH0, handler_Dma0Done, NULL);
	return ret;	
}

static int __init d11_dma_init(void)
{
	int ret;
	int i;
	int d11_dma_size = 0;
	unsigned long *d11_dma_buf = (unsigned long *)0;
	dma_addr_t 	   d11_dma_phy = 0;

	SET_MODULE_OWNER(&d11_dma_fops);
	
	ret = register_chrdev(d11_dma_major, DEVICE_NAME, &d11_dma_fops);
	if(ret < 0){
		printk("d11_dma:Cant't get major number!\n");
		return ret;
	}
	if (d11_dma_major == 0) d11_dma_major = ret; /* dynamic */	

	#ifdef CONFIG_DEVFS_FS
		devfs_d11_dma_dir = devfs_mk_dir(NULL, "d11_dma", NULL);
		if (!devfs_d11_dma_dir) return -EBUSY; 		/* problem */
		devfs_d11_dma = devfs_register(devfs_d11_dma_dir, "0", 
			DEVFS_FL_DEFAULT, d11_dma_major, DMA_MINOR, 
			S_IFCHR | S_IRUSR | S_IWUSR, &d11_dma_fops, NULL);
	#endif
	
	DPRINTK("Major device no. -> %d\n",d11_dma_major);
	
	//******** alloce image review buffer *************
	image_review_buf.head_index = 0;
	image_review_buf.tail_index = 0;
	image_review_buf.nr_images = 0;
	image_review_buf.nr_mmblks = 0;
	image_review_buf.freeze = 0;
	d11_dma_size = 4*1024*128;					//PAGE_ALIGN(IMG_SIZE + PAGE_SIZE);
	image_review_buf.image_blksize = d11_dma_size;
	
	for(i=0; i<IMG_MAX_NR; i++){
		d11_dma_buf = consistent_alloc(GFP_KERNEL | GFP_DMA, d11_dma_size, &d11_dma_phy);
		if(!d11_dma_buf){
			printk("Have no enough memory for image review memory allocate!\n");
			printk("Image review memory be truncate to %d (max=%d)!\n", i, IMG_MAX_NR);			
			break;
		}
		image_review_buf.nr_mmblks++;
		image_review_buf.image_dma_mmblk[i] = d11_dma_buf;
		image_review_buf.image_dma_mmphy[i] = d11_dma_phy;
		//DPRINTK("%d:dma0 dst kerneladdr= 0x%lx\n", i, (unsigned long)d11_dma_buf);
		//DPRINTK("%d:d11_dma_phy=0x%lx\n", i, d11_dma_phy);
	}
	
	init_waitqueue_head(&d11_dma_queue);
	image_init_dma();

	//dma_tester();
	//*********  Configure BANK3 to 32bit width ********************
	//BWSCON = BWSCON & (~(0x3 << 12)) | (0x2 << 12);
	
	if(d11_dma_create_proc()){
		return -ENOMEM;
	}
	
	return 0;
}


static void __exit  d11_dma_exit(void)
{
	int i;
	int d11_dma_size = 0;
	unsigned long * d11_dma_buf = 0;
	dma_addr_t 	   d11_dma_phy = 0;

	d11_dma_remove_proc();

	//iounmap((void *)fpga_dma0_reg);
	free_irq(IRQ_EINT2, NULL);
	//s3c2410_free_dma(DMA_CH0);
	free_irq(IRQ_DMA0, NULL);
	
	//d11_dma_size = PAGE_ALIGN(IMG_SIZE + PAGE_SIZE);
	d11_dma_size = 4*1024*128;					//PAGE_ALIGN(IMG_SIZE + PAGE_SIZE);
	DPRINTK("d11_dma_size=0x%8x\n",d11_dma_size);
	for(i=0; i<image_review_buf.nr_mmblks; i++){
		d11_dma_buf = image_review_buf.image_dma_mmblk[i];
		d11_dma_phy = image_review_buf.image_dma_mmphy[i];
		if(d11_dma_buf){
			consistent_free(d11_dma_buf, d11_dma_size, d11_dma_phy);
			DPRINTK("consistent_free: addr=0x%8x\n",d11_dma_phy);
		}
	}

	DPRINTK("image review area memory released!\n");	
	
	#ifdef CONFIG_DEVFS_FS
		devfs_unregister(devfs_d11_dma);
		devfs_unregister(devfs_d11_dma_dir);
	#endif
	
	DPRINTK("release!\n");
	unregister_chrdev(d11_dma_major, DEVICE_NAME);	
		
}


module_init(d11_dma_init);
module_exit(d11_dma_exit);


MODULE_LICENSE("GPL");
MODULE_AUTHOR("LC<lcliu_chao@126.com>");
MODULE_DESCRIPTION("dma driver for emp-d11");

⌨️ 快捷键说明

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