📄 addi_common.c
字号:
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 + -