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

📄 pmc9054.c

📁 linux plx9054芯片驱动程序 设备为一块只写PMC板
💻 C
📖 第 1 页 / 共 2 页
字号:
#define DRV_NAME	"pmc9054"#define DRV_VERSION	"0.2"#define VUINT   volatile unsigned int#ifndef __KERNEL__#define __KERNEL__#endif //#ifndef CONFIG_PROC_FS//#define CONFIG_PROC_FS//#endif#define RELOAD 29#define  U32  unsigned  int#define  U16  unsigned  short#define  S32  int#define  S16  short  int#define  U8   unsigned  char#define  S8   char#define DMAENABLE (1<<31)#define APDCEN    (1<<0)#include <linux/pci.h>#include <linux/module.h>//#include <asm/uaccess.h>#include <linux/interrupt.h>#include <linux/config.h>#include <linux/ioctl.h>#include <linux/poll.h>#include <asm/dma.h>#include <asm/io.h>#include <linux/slab.h>#include "myvalues.h"#include<asm/delay.h>#include <linux/mm.h>#include <asm/page.h>// GLOBAL DEFINITIONSstruct pci_dev *pdev = NULL;char arm[]="Xscale";int irqdma0=9;int irqdma1=10;unsigned long ulPciRegister   = 0;unsigned long ulPciRegLen     = 0;unsigned long ulFpgaRegister  = 0;unsigned long ulFpgaRegLen    = 0;unsigned long ulIOMem         = 0;unsigned long ulIOMemLen		= 0;void  *fpgaMem = NULL;void  *pciMem =  NULL;//extern unsigned long base;unsigned char bufFlag = 0;		// 0 for send, 1 for receiveunsigned char sendHappened = 0;		// to represent that send interrupt has occuredunsigned char recvHappened = 0;		// to represent that receive interrupt has occuredunsigned long ulRecvSize   = 0x4000;//16kstatic DECLARE_WAIT_QUEUE_HEAD(pci9054_wqs);static DECLARE_WAIT_QUEUE_HEAD(pci9054_wqr);void *kernBuffer = NULL;unsigned int order = 0;dma_addr_t dmaSendAddr = 0;//unsigned long SendSize = 0x4000;	// 16kunsigned long RecvSize = 0x4000;// 16kstatic const struct pci_device_id pci9054_ids[] = { {VENDORID, DEVICEID},{ 0, },};//for debugint *a;short *b;int tt;MODULE_DEVICE_TABLE(pci, pci9054_ids);/****************************************\|*     Driver "pci9054.o"`s entries      *|\****************************************/voidXscale_do_tasklet(unsigned long unused){     	   /*  if (bufFlag == 0)	{		sendHappened = 1;		wake_up_interruptible(&pci9054_wqs);		PDEBUG( "Send Over!\n");	}	else		if (bufFlag == 1)		{			recvHappened = 1;			wake_up_interruptible(&pci9054_wqr);			PDEBUG( "Receive Over!\n");		}		else			PDEBUG( "error!\n");*/           return;}DECLARE_TASKLET(Xscale_tasklet, Xscale_do_tasklet, 0);void Xscale_Isr(int irqn, void *dev_id, struct pt_regs *regs){			   printk(KERN_ALERT "ENTERING  DMA CH0 Interrupt\n");	   	   if(PCI_DMACTRL&(1<<3))	   	   printk(KERN_ALERT "ATPDMA CH0 COMPLETE Interrupt\n");	   if(PCI_DMACTRL&(1<<4))	   	   printk(KERN_ALERT "ATPDMA CH0 ERROR Interrupt\n");	   if(PCI_DMACTRL&(1<<5))	   	   printk(KERN_ALERT "ATPDMA CH1 COMPLETE Interrupt\n");	   if(PCI_DMACTRL&(1<<6))	   	   printk(KERN_ALERT "ATPDMA CH1 ERROR Interrupt\n");	   if(PCI_ISR&(1<<3))	   	 pci_unmap_single(pdev, a, 1024*4, PCI_DMA_TODEVICE);	   if(PCI_DMACTRL&(1<<11))	   	   printk(KERN_ALERT "PTADMA CH0 COMPLETE Interrupt\n");	   if(PCI_DMACTRL&(1<<12))	   	   printk(KERN_ALERT "PTADMA CH0 ERROR Interrupt\n");	   if(PCI_DMACTRL&(1<<13))	   	   printk(KERN_ALERT "PTADMA CH1 COMPLETE Interrupt\n");	   if(PCI_DMACTRL&(1<<14))	   	   printk(KERN_ALERT "PTADMA CH1 ERROR Interrupt\n");	   if(PCI_ISR&(1<<3))	   	 pci_unmap_single(pdev, a, 1024*4, PCI_DMA_FROMDEVICE);	   			   /*    u32 intcsr=0;   u32 dmactrl=0;   u32 pcinten=0;    pcinten|=(1<<3);	*PCI_INTEN|=pcinten;	intcsr = readl((unsigned long)pciMem + 0x0068);	if (! intcsr & (1 << 21) )	printk(KERN_ALERT "DMA CH0 Interrupt\n");		if (*PCI_DMACTRL && (1<<5))	{		printk(KERN_ALERT "DMA CH1   COMPLETE  Interrupt\n");	}	else		if (*PCI_DMACTRL && (1<<6))		{		    printk(KERN_ALERT "DMA CH1  ERROR  Interrupt\n");		}			// request dpc...that's tasklet under linux	*/	tasklet_schedule(&Xscale_tasklet);		}int pci9054_probe(struct pci_dev *dev, const struct pci_device_id *id){	int status = -1;	status = pci_enable_device(dev);	//pci_set_master(dev);	pdev = dev;	// save it for later use  	return status;}voidpci9054_remove(struct pci_dev *dev){	pci_disable_device(dev);	return;}/* device module information */static struct pci_driver pci9054_driver = {	.name = DRV_NAME,	.id_table = pci9054_ids,	.probe = pci9054_probe, 	.remove = pci9054_remove,};int pci9054_open(struct inode *inode, struct file *filp){	// setup the irq interrupt handler  //	request_irq(pdev->irq, pci9054_Isr, SA_SHIRQ, "da9054", (void *)pci9054_ids);    request_irq(irqdma1,  Xscale_Isr, SA_SHIRQ, "Xscale", (void *)arm);	return 0;}int pci9054_release(struct inode *inode, struct file *filp){	 //     free_irq(pdev->irq, (void *)pci9054_ids);           free_irq(irqdma1, (void *)arm);       	iounmap((unsigned long *)ulPciRegister);	 iounmap((unsigned long *)ulFpgaRegister);        	return 0;}       int pci9054_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){	struct FpgaRegister *preg = (struct FpgaRegister *)arg;	struct iomem *p1reg =(struct iomem *)arg;	//u32 lregvalue;	u32 bregvalue;	u32 dmactl=0;   unsigned long i;    	switch (cmd)    	{            case RD_IOMEM:             PDEBUG("READ");        //  memcpy_fromio(p1reg->value,fpgaMem,p1reg->len);             for(i=0;i<p1reg->len;i++)         *(long *)((int)(p1reg->value)+i)= readl((unsigned long)fpgaMem+p1reg->offset+i);          break;      case WR_IOMEM:      //    PDEBUG("WRITE");     //      memcpy_toio(fpgaMem,p1reg->value,p1reg->len);              for(i=0;i<p1reg->len;i++)          writel(*(long *)((int)p1reg->value+i),(unsigned long)fpgaMem+p1reg->offset+i);           break;      case RD_REG:         preg->value=readl((unsigned long)pciMem+preg->offset);          break;      case WR_EEPROM:			 EepromWrite(preg->value, preg->offset);		    	break;      case RD_EEPROM:		    preg->value = EepromRead(preg->offset);		    	break;		case WR_FPGA_REGISTER:			writel(preg->value, (unsigned long)ulFpgaRegister+preg->offset);		    	break;	   case RD_FPGA_REGISTER:		    	preg->value = readl((unsigned long)ulFpgaRegister + preg->offset);		    	break;  case DMA_CH0_RECV_CTRL:         printk(KERN_ALERT "6.1 DMA start!1 \n");			// map the kernBuffer into dma address						//bufFlag = 1;//		 for (page = virt_to_page(kernBuffer); page < virt_to_page(kernBuffer + BUF_SIZE); page++)//		                      SetPageReserved(page);                 a=kmalloc(1024,__GFP_DMA);                           for(tt=0;tt<20;tt++)               {                 *(a+tt)=tt;                   printk(KERN_ALERT "before dma a=0x%x \n",*(a+tt));                }                  printk(KERN_ALERT "phy  addr  a  =0x%x \n",a);                  printk(KERN_ALERT "pci register addr=0x%x \n",pciMem);                   printk(KERN_ALERT "fpga mem=0x%x \n",fpgaMem);             		       dmaSendAddr = pci_map_single(pdev, a,1024, PCI_DMA_FROMDEVICE); 	        //	   dmactl|=APDCEN;	       //	  writel(dmactl,PCI_DMACTRL)//dmactl channel 1 enable                            //     printk(KERN_ALERT "before dma a=0x%x \n",*a);		         printk(KERN_ALERT "dmasendaddr =0x%x \n", dmaSendAddr);                            printk(KERN_ALERT "a before dma addr  =0x%x \n", a);			 for(tt=0;tt<20;tt++)                                               printk(KERN_ALERT "pci register before dma=0x%x \n",dmactl=readl(ulPciRegister+4*tt));                          *PCI_PTADMA0_PCIADDR=(unsigned long )ulPciRegister;                        * PCI_PTADMA0_AHBADDR=dmaSendAddr;                                           printk(KERN_ALERT " *PCI_PTADMA0_AHBADDR=0x%x \n", *PCI_PTADMA0_AHBADDR);  			//Set pointer to the right array address before the first transfer			//writel((unsigned long)ulFpgaRegister,(unsigned long)PCI_ATPDMA0_AHBADDR);   // CH1  PCI address			// CH0 local address offset			//*PCI_PTADMA0_PCIADDR=(unsigned  long)ulPciRegister;                                          printk(KERN_ALERT "PCI_PTADMA0_PCIADDR=0x%x \n",*PCI_PTADMA0_PCIADDR);                        //   *PCI_PTADMA0_PCIADDR=(unsigned  long)ulFpgaRegister;			// Enable CH0			*PCI_PTADMA0_LENADDR=5;                            printk(KERN_ALERT "ATPDMA0LEN value after size =0x%x \n", *PCI_PTADMA0_LENADDR);                        // bregvalue |= 1 << 27;			//writel(bregvalue,(unsigned long)PCI_ATPDMA0_LENADDR); //data swap                        //*PCI_ATPDMA0_LENADDR|=bregvalue;		                                                  printk(KERN_ALERT "*PCI_PTADMA0_LENADDR before dma =0x%x \n",*PCI_PTADMA0_LENADDR);			*PCI_PTADMA0_LENADDR|= (1<<31);// Start DMA CH1 								udelay(100);                 printk(KERN_ALERT "DMA END \n *PCI_PTADMA0_LENADDR =0x%x \n",*PCI_PTADMA0_LENADDR);			pci_unmap_single(pdev, a,1024 , PCI_DMA_FROMDEVICE);

⌨️ 快捷键说明

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