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

📄 addi_common.c

📁 最新版comedi的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	void cleanup_module(void){comedi_driver_unregister(&(x));}*/COMEDI_INITCLEANUP(driver_addi);/*+----------------------------------------------------------------------------+| Function name     :static int i_ADDI_Attach(comedi_device *dev,            ||										comedi_devconfig *it)        ||                                        									 |+----------------------------------------------------------------------------+| Task              :Detects the card.                                       ||  			 Configure the driver for a particular board.            ||  			 This function does all the initializations and memory   | |			 allocation of data structures for the driver.	         |+----------------------------------------------------------------------------+| Input Parameters  :comedi_device *dev										 ||                    comedi_devconfig *it									 ||                                                 					         |+----------------------------------------------------------------------------+| Return Value      :  0            					                     ||                    													     |+----------------------------------------------------------------------------+*/static int i_ADDI_Attach(comedi_device *dev,comedi_devconfig *it){	comedi_subdevice *s;	int ret,pages,i,n_subdevices;        DWORD dw_Dummy; 	unsigned long io_addr[5];	unsigned short master,irq;//v_58        unsigned long iobase_a,iobase_main,iobase_addon,iobase_reserved;	struct pcilst_struct *card=NULL;	unsigned char pci_bus,pci_slot,pci_func;	int i_Dma = 0;	static char c_Identifier [150];		sprintf (c_Identifier, "Addi-Data GmbH Comedi %s", this_board->pc_DriverName); 	if (!pci_list_builded) 	    {	    v_pci_card_list_init(this_board->i_VendorId,1); //1 for displaying the list..	    pci_list_builded=1;	    }	     	//rt_printk("comedi%d: addi_common: board=%s",dev->minor,this_board->pc_DriverName);		if ((this_board->i_Dma) && (it->options[2] == 0))	   {	   i_Dma = 1;	   }		if ((card=ptr_select_and_alloc_pci_card(this_board->i_VendorId, 	                                        this_board->i_DeviceId,	                                        it->options[0],	                                        it->options[1],	                                        i_Dma))==NULL) 	   {	   return -EIO;	   }	   	if ((i_pci_card_data(card,&pci_bus,&pci_slot,&pci_func,&io_addr[0],&irq,&master))<0) 	   {	   i_pci_card_free(card);	   printk(" - Can't get AMCC data!\n");	   return -EIO;	   }	   	iobase_a=io_addr[0];	iobase_main=io_addr[1];	iobase_addon=io_addr[2];        iobase_reserved=io_addr[3];	printk("\nBus %d: Slot %d: Funct%d\nBase0: 0x%8lx\nBase1: 0x%8lx\nBase2: 0x%8lx\nBase3: 0x%8lx\n",	        pci_bus,pci_slot,pci_func,io_addr[0],io_addr[1],io_addr[2],io_addr[3]);		if ((this_board->pc_EepromChip == NULL) || (strcmp (this_board->pc_EepromChip, ADDIDATA_9054) != 0))	   {	   /************************************/	   /* Test if more that 1 address used */	   /************************************/		   if (this_board->i_IorangeBase1 != 0)	      {	      dev->iobase=iobase_main;// DAQ base address...	      printk("\nrequest_region i_IorangeBase1 - 1\n");	      request_region(dev->iobase,  this_board->i_IorangeBase1, c_Identifier);	      printk("\nrequest_region i_IorangeBase1 - 1 OK\n");	      }	   else	      {	      dev->iobase=iobase_a;// DAQ base address...	      printk("\nrequest_region i_IorangeBase0 - 2");	      request_region(dev->iobase,  this_board->i_IorangeBase0, c_Identifier);	      printk("\nrequest_region i_IorangeBase0 - 2 %lX OK", dev->iobase);	      }	   dev->board_name =this_board->pc_DriverName;	   if((ret=alloc_private(dev,sizeof(addi_private)))<0)	      {	      return -ENOMEM;	      }	   devpriv->amcc=card;	   devpriv->master=master; //testing            devpriv->iobase=dev->iobase;	   devpriv->i_IobaseAmcc=iobase_a;//AMCC base address...	   devpriv->i_IobaseAddon=iobase_addon;//ADD ON base address....           devpriv->i_IobaseReserved=iobase_reserved; 	   devpriv->ps_BoardInfo = this_board;           //if(this_board->i_Dma)	   if((iobase_a) && (iobase_a != dev->iobase))	      {	      request_region(devpriv->i_IobaseAmcc,this_board->i_IorangeBase0, c_Identifier);	      printk("\nrequest_region i_IorangeBase0 - 3 OK\n");	      }                   //##	   if(io_addr[2])	      {	      printk("request_region i_IorangeBase2\n");	      request_region(io_addr[2],this_board->i_IorangeBase2, c_Identifier);	      printk("request_region i_IorangeBase2 OK\n");	      }	   }	else	   {	   if((ret=alloc_private(dev,sizeof(addi_private)))<0)	      {	      return -ENOMEM;	      }	   	   if (pci_request_regions (card->pcidev, c_Identifier))	      {	      printk("\nRequest regions error\n");	      return -EIO;	      }	      	   dev->board_name =this_board->pc_DriverName;	   dev->iobase=io_addr[2];	   devpriv->amcc=card;           devpriv->iobase=io_addr[2];	   devpriv->ps_BoardInfo = this_board;	   devpriv->i_IobaseReserved=io_addr[3];	   printk ("\nioremap begin");	   devpriv->dw_AiBase=(UINT) ioremap(io_addr[3],this_board->i_IorangeBase3);	   printk ("\nioremap end");	   }        //##	if (irq>0)  	   {	   if (comedi_request_irq(irq, v_ADDI_Interrupt, SA_SHIRQ, c_Identifier, dev) < 0) 	      {	      printk(", unable to allocate IRQ %d, DISABLING IT", irq);	      irq=0; /* Can't use IRQ */	      } 	   else 	      {	      rt_printk("\nirq=%d", irq);	      enable_irq (irq);	      }    	   } 	else 	   {	   rt_printk(", IRQ disabled");	   }	   	printk("\nOption %d %d %d\n",it->options[0],it->options[1],it->options[2]); 	dev->irq = irq;        	// Read eepeom and fill boardtype Structure        	if(this_board->i_PCIEeprom)	   { 	   printk("\nPCI Eeprom used"); 	   if (!(strcmp(this_board->pc_EepromChip, "S5920")))	      {	      // Set 3 wait stait 	      if(!(strcmp(this_board->pc_DriverName,"apci035")))	         {	         outl(0x80808082,devpriv->i_IobaseAmcc+0x60); 	         }	      else	         { 	         outl(0x83838383,devpriv->i_IobaseAmcc+0x60);	         }	      // Enable the interrupt for the controler 	      dw_Dummy =  inl(devpriv->i_IobaseAmcc+ 0x38);	      outl(dw_Dummy | 0x2000,devpriv->i_IobaseAmcc+0x38);	      printk ("\nEnable the interrupt for the controler");	      }	   printk("\nRead Eeprom"); 	   i_EepromReadMainHeader(io_addr[0],this_board->pc_EepromChip,dev);	   } 	else	   {	   printk("\nPCI Eeprom unused"); 	   }		if (it->options[2]>0)		  {	  devpriv->us_UseDma=ADDI_DISABLE;	  }	else	  {	  devpriv->us_UseDma=ADDI_ENABLE;	  }		if(this_board->i_Dma)	   { 	   printk("\nDMA used"); 	   if (devpriv->us_UseDma==ADDI_ENABLE) 	      {	      // alloc DMA buffers	      devpriv->b_DmaDoubleBuffer=0;	      for (i=0; i<2; i++) 	         {	         for (pages=4; pages>=0; pages--)	            {	            if((devpriv->ul_DmaBufferVirtual[i]=(void *)__get_free_pages(GFP_KERNEL,pages)))	               {	               break;	               }	            }	         if (devpriv->ul_DmaBufferVirtual[i]) 	            {	            devpriv->ui_DmaBufferPages[i]=pages;	            devpriv->ui_DmaBufferSize[i]=PAGE_SIZE*pages;	            devpriv->ui_DmaBufferSamples[i]=devpriv->ui_DmaBufferSize[i]>>1;	            devpriv->ul_DmaBufferHw[i]=virt_to_bus((void*)devpriv->ul_DmaBufferVirtual[i]);	            }	         }	      if (!devpriv->ul_DmaBufferVirtual[0]) 	         {	         rt_printk(", Can't allocate DMA buffer, DMA disabled!");	         master=0;	         devpriv->us_UseDma=ADDI_DISABLE;	         }	      if (devpriv->ul_DmaBufferVirtual[1])	         {	         devpriv->b_DmaDoubleBuffer=1;	         }	      }       	   if ((devpriv->us_UseDma==ADDI_ENABLE)) 	      {	      rt_printk("\nDMA ENABLED\n");	      } 	   else 	      {	      printk("\nDMA DISABLED\n");	      }	   }	if (!strcmp(this_board->pc_DriverName,"apci1710"))	   {	   i_ADDI_AttachPCI1710 (dev);    	   // save base address	   devpriv->s_BoardInfos.ui_Address=io_addr[2];	   }       	else	{	//Update-0.7.57->0.7.68dev->n_subdevices = 7;	n_subdevices = 7;	if((ret=alloc_subdevices(dev,n_subdevices))<0)    	return ret;     // Allocate and Initialise AI Subdevice Structures	s = dev->subdevices + 0;        if((this_board->i_NbrAiChannel) || (this_board->i_NbrAiChannelDiff))        {	dev->read_subdev = s;	s->type = COMEDI_SUBD_AI;	s->subdev_flags = SDF_READABLE|SDF_RT|SDF_COMMON|SDF_GROUND|SDF_DIFF;	if (this_board->i_NbrAiChannel)	   s->n_chan = this_board->i_NbrAiChannel;	else	   s->n_chan = this_board->i_NbrAiChannelDiff;	s->maxdata = this_board->i_AiMaxdata;	s->len_chanlist = this_board->i_AiChannelList;	s->range_table = this_board->pr_AiRangelist;                               s->insn_config=this_board->i_hwdrv_InsnConfigAnalogInput;	s->insn_read=this_board->i_hwdrv_InsnReadAnalogInput;        s->insn_write=this_board->i_hwdrv_InsnWriteAnalogInput;          s->insn_bits=this_board->i_hwdrv_InsnBitsAnalogInput;  	s->do_cmdtest=this_board->i_hwdrv_CommandTestAnalogInput;	s->do_cmd=this_board->i_hwdrv_CommandAnalogInput;        s->cancel=this_board->i_hwdrv_CancelAnalogInput;         }        else	{		s->type=COMEDI_SUBD_UNUSED;	}    // Allocate and Initialise AO Subdevice Structures	s = dev->subdevices + 1;        if(this_board->i_NbrAoChannel)	{	s->type = COMEDI_SUBD_AO;	s->subdev_flags = SDF_WRITEABLE|SDF_GROUND|SDF_COMMON|SDF_RT;	s->n_chan = this_board->i_NbrAoChannel;	s->maxdata = this_board->i_AoMaxdata;	s->len_chanlist = this_board->i_NbrAoChannel;	s->range_table = this_board->pr_AoRangelist;        s->insn_config=this_board->i_hwdrv_InsnConfigAnalogOutput;	s->insn_write=this_board->i_hwdrv_InsnWriteAnalogOutput;	}        else        {		s->type=COMEDI_SUBD_UNUSED;	}    // Allocate and Initialise DI Subdevice Structures		s = dev->subdevices + 2;        if(this_board->i_NbrDiChannel)	{	s->type = COMEDI_SUBD_DI;	s->subdev_flags = SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON;	s->n_chan = this_board->i_NbrDiChannel;	s->maxdata = 1;	s->len_chanlist = this_board->i_NbrDiChannel;    	s->range_table = &range_digital;	s->io_bits=0;		/* all bits input */        s->insn_config=this_board->i_hwdrv_InsnConfigDigitalInput;        s->insn_read=this_board->i_hwdrv_InsnReadDigitalInput;        s->insn_write=this_board->i_hwdrv_InsnWriteDigitalInput;	s->insn_bits=this_board->i_hwdrv_InsnBitsDigitalInput;	}	else	{		s->type=COMEDI_SUBD_UNUSED;	}    // Allocate and Initialise DO Subdevice Structures		s = dev->subdevices + 3;        if(this_board->i_NbrDoChannel)	{	s->type = COMEDI_SUBD_DO;	s->subdev_flags = SDF_READABLE|SDF_WRITEABLE|SDF_RT|SDF_GROUND|SDF_COMMON;	s->n_chan= this_board->i_NbrDoChannel; 	s->maxdata = this_board->i_DoMaxdata;	s->len_chanlist =this_board->i_NbrDoChannel ;	s->range_table = &range_digital;	s->io_bits=0xf;		/* all bits output */                s->insn_config=this_board->i_hwdrv_InsnConfigDigitalOutput;//for digital output memory..         s->insn_write=this_board->i_hwdrv_InsnWriteDigitalOutput;	s->insn_bits=this_board->i_hwdrv_InsnBitsDigitalOutput;        s->insn_read=this_board->i_hwdrv_InsnReadDigitalOutput;  	}        else	{		s->type=COMEDI_SUBD_UNUSED;	}      // Allocate and Initialise Timer Subdevice Structures		    	s = dev->subdevices + 4;	if(this_board->i_Timer)	{	s->type = COMEDI_SUBD_TIMER;	s->subdev_flags = SDF_WRITEABLE|SDF_RT|SDF_GROUND|SDF_COMMON; 	s->n_chan = 1; 	s->maxdata = 0; 	s->len_chanlist = 1;	s->range_table = &range_digital;                s->insn_write=this_board->i_hwdrv_InsnWriteTimer;	s->insn_read=this_board->i_hwdrv_InsnReadTimer;	s->insn_config=this_board->i_hwdrv_InsnConfigTimer;        s->insn_bits=this_board->i_hwdrv_InsnBitsTimer;        }        else	{		s->type=COMEDI_SUBD_UNUSED;	}    // Allocate and Initialise TTL        s = dev->subdevices + 5;	if(this_board->i_NbrTTLChannel)	{	s->type         = COMEDI_SUBD_TTLIO;	s->subdev_flags = SDF_WRITEABLE|SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON;	s->n_chan       = this_board->i_NbrTTLChannel;	s->maxdata      = 0;	s->io_bits=0;		/* all bits input */	s->len_chanlist = this_board->i_NbrTTLChannel;    	s->range_table  = this_board->pr_TTLRangelist; // to pass arguments in range	        s->insn_config  = this_board->i_hwdr_ConfigInitTTLIO;	s->insn_bits    = this_board->i_hwdr_ReadTTLIOBits;        s->insn_read    = this_board->i_hwdr_ReadTTLIOAllPortValue; 	s->insn_write   = this_board->i_hwdr_WriteTTLIOChlOnOff;        }        else	{		s->type=COMEDI_SUBD_UNUSED;	}	        /* EEPROM */	s=dev->subdevices+6;        if(this_board->i_PCIEeprom)	{	s->type=COMEDI_SUBD_MEMORY;	s->subdev_flags=SDF_READABLE|SDF_INTERNAL;	s->n_chan=256;	s->maxdata=0xffff;	s->insn_read=i_ADDIDATA_InsnReadEeprom;	}        else	{		s->type=COMEDI_SUBD_UNUSED;	}     }		printk("\ni_ADDI_Attach end\n"); 	i_ADDI_Reset(dev);	devpriv->b_ValidDriver=1;	return 0;}/*+----------------------------------------------------------------------------+| Function name     : static int i_ADDI_Detach(comedi_device *dev)           ||                                        									 ||                                            						         |+----------------------------------------------------------------------------+| Task              : Deallocates resources of the addi_common driver        ||			  Free the DMA buffers, unregister irq.				     ||                     										                 |+----------------------------------------------------------------------------+| Input Parameters  : comedi_device *dev									 ||                     														 ||                                                 					         |+----------------------------------------------------------------------------+| Return Value      : 0             					                     ||                    													     |+----------------------------------------------------------------------------+*/static int i_ADDI_Detach(comedi_device *dev)	{   	if (dev->private) 	   {	   if (devpriv->b_ValidDriver) 	      {	      i_ADDI_Reset(dev);	      }	   	   if ((devpriv->ps_BoardInfo->pc_EepromChip == NULL) || (strcmp (devpriv->ps_BoardInfo->pc_EepromChip, ADDIDATA_9054) != 0))	      {	      if(devpriv->i_IobaseAmcc)	         {	         printk("\nrelease_region base address 0");	         release_region(devpriv->i_IobaseAmcc,this_board->i_IorangeBase0);	         printk("\nrelease_region base address 0 OK");	         }	         	      if(this_board->i_IorangeBase1) 	         {	         printk("\nrelease_region base address 1");	         release_region(dev->iobase,this_board->i_IorangeBase1);	         printk("\nrelease_region base address 1 OK");	         }	      if(this_board->i_IorangeBase2) 	         {	         printk("\nrelease_region base address 2");	         release_region(devpriv->i_IobaseAddon,this_board->i_IorangeBase2); 	         printk("\nrelease_region base address 2 OK");	         }	         	      if (devpriv->allocated)	         {          	         i_pci_card_free(devpriv->amcc);	         }	   	      if (devpriv->ul_DmaBufferVirtual[0]) 	         {          	         free_pages((unsigned long)devpriv->ul_DmaBufferVirtual[0],devpriv->ui_DmaBufferPages[0]);	         }	   	      if (devpriv->ul_DmaBufferVirtual[1]) 	         {          	         free_pages((unsigned long)devpriv->ul_DmaBufferVirtual[1],devpriv->ui_DmaBufferPages[1]);	         }	      }	   else	      {	      iounmap ((void *) devpriv->dw_AiBase);	      	      pci_release_regions(devpriv->amcc->pcidev);	      if (devpriv->allocated)	         {          	         i_pci_card_free(devpriv->amcc);	         }	      }           	   if(dev->irq)	      {	      free_irq(dev->irq,dev);	      }       	   if (pci_list_builded) 	      {	      //v_pci_card_list_cleanup(PCI_VENDOR_ID_AMCC);	      v_pci_card_list_cleanup(this_board->i_VendorId);	      pci_list_builded=0;	      }	   }	      	return 0;	}/*+----------------------------------------------------------------------------+| Function name     : static int i_ADDI_Reset(comedi_device *dev)			 ||                                        									 |+----------------------------------------------------------------------------+| Task              : Disables all interrupts, Resets digital output to low, ||				Set all analog output to low						 ||                     										                 |+----------------------------------------------------------------------------+| Input Parameters  : comedi_device *dev									 ||                     														 ||                                                 					         |+----------------------------------------------------------------------------+| Return Value      : 0           					                         ||                    													     |+----------------------------------------------------------------------------+*/static int i_ADDI_Reset(comedi_device *dev){	        this_board->i_hwdrv_Reset(dev);	return 0;}// Interrupt function/*+----------------------------------------------------------------------------+| Function name     :                                                        ||static void v_ADDI_Interrupt(int irq, void *d, struct pt_regs *regs)        ||                                        									 |+----------------------------------------------------------------------------+| Task              : Registerd interrupt routine						     ||                     										                 |+----------------------------------------------------------------------------+| Input Parameters  : 	int irq												 ||                     														 ||                                                 					         |+----------------------------------------------------------------------------+| Return Value      :              					                         ||                    													     |+----------------------------------------------------------------------------+*/static irqreturn_t v_ADDI_Interrupt(int irq, void *d, struct pt_regs *regs){comedi_device *dev = d;this_board->v_hwdrv_Interrupt(irq,d,regs);return IRQ_RETVAL(1);}// EEPROM Read Function/*+----------------------------------------------------------------------------+| Function name     :                                                        ||INT i_ADDIDATA_InsnReadEeprom(comedi_device *dev,comedi_subdevice *s,							comedi_insn *insn,lsampl_t *data)|                                        									 |+----------------------------------------------------------------------------+| Task              : Read 256 words from EEPROM          				     ||                     										                 |+----------------------------------------------------------------------------+| Input Parameters  :(comedi_device *dev,comedi_subdevice *s,			comedi_insn *insn,lsampl_t *data) 						 ||                     														 ||                                                 					         |+----------------------------------------------------------------------------+| Return Value      :              					                         ||                    													     |+----------------------------------------------------------------------------+*/static int i_ADDIDATA_InsnReadEeprom(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){    WORD w_Data;   WORD w_Address;   w_Address = CR_CHAN(insn->chanspec);// address to be read as 0,1,2,3...255      w_Data=w_EepromReadWord(devpriv->i_IobaseAmcc,this_board->pc_EepromChip,0x100+(2*w_Address));   data[0]=w_Data;   //multiplied by 2 bcozinput will be like 0,1,2...255   return insn->n;}

⌨️ 快捷键说明

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