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

📄 adl_pci9111.c

📁 最新rtlinux内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    }     if (pci9111_is_fifo_half_full())    {#ifdef INTERRUPT_DEBUG      printk (PCI9111_DRIVER_NAME ": fifo is half full\n");#endif      async->events |= COMEDI_CB_BLOCK;            for (i=0;i<PCI9111_FIFO_HALF_SIZE;i++)      {	// FIXME: The resolution test should be done outside of the read loop		if (resolution == PCI9111_HR_AI_RESOLUTION) {	  data = pci9111_hr_ai_get_data ();	}	else	{	  data = pci9111_ai_get_data ();	}		if (((dev_private->stop_counter > 0) || (dev_private->stop_is_none)) &&	    (dev_private->scan_begin_counter < async->cmd.chanlist_len))	{	  comedi_buf_put (async, data);	  dev_private->stop_counter--;	}		dev_private->scan_begin_counter++;	if (dev_private->scan_begin_counter >= dev_private->scan_begin_counter_limit)	{	  dev_private->scan_begin_counter=0;	}      }    }  }  if ((dev_private->stop_counter==0) && (!dev_private->stop_is_none))  {    async->events |= COMEDI_CB_EOA;    pci9111_ai_cancel (dev, subdevice);  }    // Very important, otherwise another interrupt request will be inserted  // and will cause driver hangs on processing interrupt event (and cause a  // computer crash, and corrupt the source file of the driver you are   // working on, since you forgot to do a sync before test, and you cry,   // and ...)    pci9111_interrupt_clear();  comedi_spin_unlock_irqrestore (&dev->spinlock, irq_flags);  comedi_event (dev, subdevice, async->events);}			       // ------------------------------------------------------------------// // INSTANT ANALOG INPUT OUTPUT SECTION// // ------------------------------------------------------------------//// analog instant input//#undef AI_INSN_DEBUGstatic int pci9111_ai_insn_read ( comedi_device *dev,				  comedi_subdevice *subdevice, 				  comedi_insn *insn,				  lsampl_t *data ){  int resolution = ((pci9111_board_struct *) dev->board_ptr)->ai_resolution;  int timeout,i;#ifdef AI_INSN_DEBUG  printk (PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n",  	  CR_CHAN((&insn->chanspec)[0]),	  CR_RANGE((&insn->chanspec)[0]),	  insn->n);#endif  pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0]));  if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0]))  {    pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0]));  }  pci9111_fifo_reset();  for (i=0;i<insn->n;i++)  {    pci9111_software_trigger();        timeout=PCI9111_AI_INSTANT_READ_TIMEOUT;        while (timeout--) {      if (!pci9111_is_fifo_empty()) goto conversion_done;    }    comedi_error(dev,"A/D read timeout");    data[i]=0;    pci9111_fifo_reset();    return -ETIME;conversion_done:     if (resolution==PCI9111_HR_AI_RESOLUTION)    {      data[i] = pci9111_hr_ai_get_data();    }     else    {      data[i] = pci9111_ai_get_data();    }  }  #ifdef AI_INSN_DEBUG  printk (PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n",  	  pci9111_ai_channel_get(),	  pci9111_ai_range_get(),	  pci9111_trigger_and_autoscan_get());#endif  return i;}//// Analog instant output//static int pci9111_ao_insn_write ( comedi_device *dev,				   comedi_subdevice *s, 				   comedi_insn *insn,				   lsampl_t *data ){  int i;  for (i=0; i<insn->n; i++) {    pci9111_ao_set_data(data[i]);    dev_private->ao_readback=data[i];  }  return i;}// // Analog output readback//static int pci9111_ao_insn_read ( comedi_device * dev, 				  comedi_subdevice * s, 				  comedi_insn *insn, 				  lsampl_t *data) {  int i;  for (i=0; i<insn->n; i++) {     data[i]=dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK;  }  return i;}// ------------------------------------------------------------------// // DIGITAL INPUT OUTPUT SECTION// // ------------------------------------------------------------------//// Digital inputs//static int pci9111_di_insn_bits ( comedi_device *dev, 				  comedi_subdevice *subdevice,				  comedi_insn *insn,				  lsampl_t *data){  lsampl_t bits;  bits = pci9111_di_get_bits();  data[1] = bits;    return 2;}//// Digital outputs//static int pci9111_do_insn_bits ( comedi_device *dev, 				  comedi_subdevice *subdevice,				  comedi_insn *insn,				  lsampl_t *data){  lsampl_t bits;  // Only set bits that have been masked  // data[0] = mask  // data[1] = bit state    data[0] &= PCI9111_DO_MASK;    bits = subdevice->state;  bits &= ~data[0];  bits |= data[0] & data[1];  subdevice->state = bits;    pci9111_do_set_bits(bits);  data[1] = bits;    return 2;}// ------------------------------------------------------------------// // INITIALISATION SECTION// // ------------------------------------------------------------------//// Reset device// static int pci9111_reset (comedi_device *dev){   // Set trigger source to software    plx9050_interrupt_control (dev_private->lcr_io_base, true, true, true, true, false);  pci9111_trigger_source_set (dev, software);  pci9111_pretrigger_set (dev, false);  pci9111_autoscan_set (dev,false);  // Reset 8254 chip    dev_private->timer_divisor_1=0;  dev_private->timer_divisor_2=0;    pci9111_timer_set (dev);  return 0;}//// Attach // 	// 	- Register PCI device// 	- Declare device driver capability//	static int pci9111_attach(comedi_device *dev,comedi_devconfig *it){  comedi_subdevice *subdevice;  int io_base, io_range, lcr_io_base, lcr_io_range;  struct pci_dev* pci_device;  int error,i;  pci9111_board_struct* board;//// Probe the device to determine what device in the series it is.//    printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n",dev->minor);  pci_for_each_dev(pci_device)  {    if (pci_device->vendor == PCI_VENDOR_ID_ADLINK)    {      for (i= 0; i< pci9111_board_nbr; i++)      {	if(pci9111_boards[i].device_id == pci_device->device)	{	  // was a particular bus/slot requested?	  if((it->options[0] != 0) || (it->options[1] != 0))	  {	    // are we on the wrong bus/slot?	    if(pci_device->bus->number != it->options[0] ||	       PCI_SLOT(pci_device->devfn) != it->options[1])	    {	      continue;	    }	  }	  	  dev->board_ptr = pci9111_boards + i;	  board = (pci9111_board_struct *) dev->board_ptr;	  goto found;	}      }    }  }    printk ("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",	  dev->minor,it->options[0], it->options[1]);  return -EIO;found:  printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n", 	 dev->minor,	 pci9111_boards[i].name,	 pci_device->bus->number,	 PCI_SLOT(pci_device->devfn),	 PCI_FUNC(pci_device->devfn),	 pci_device->irq);  // TODO: Warn about non-tested boards.  switch(board->device_id)  {  };  // Read local configuration register base address [PCI_BASE_ADDRESS #1].    lcr_io_base = pci_resource_start (pci_device, 1);  lcr_io_range = pci_resource_end (pci_device, 1) - lcr_io_base +1;    printk ("comedi%d: local configuration registers at address 0x%4x [0x%4x]\n",	  dev->minor,	  lcr_io_base,	  lcr_io_range);    if (check_region (lcr_io_base, lcr_io_range) < 0)   {    printk("comedi%d: I/O port conflict\n",dev->minor);    return -EIO;  }    // Read PCI6308 register base address [PCI_BASE_ADDRESS #2].    io_base = pci_resource_start (pci_device, 2);  io_range = pci_resource_end (pci_device, 2) - io_base +1;    printk ("comedi%d: 6503 registers at address 0x%4x [0x%4x]\n",	  dev->minor,	  io_base,	  io_range);    if (check_region (io_base, io_range) < 0)   {    printk("comedi%d: I/O port conflict\n",dev->minor);    return -EIO;  }    // Allocate IO ressources    pci_request_regions(pci_device, PCI9111_DRIVER_NAME);    dev->iobase=io_base;  dev->board_name = board->name;    if(alloc_private(dev,sizeof(pci9111_private_data_struct))<0)    return -ENOMEM;    dev_private->pci_device = pci_device;  dev_private->io_range = io_range;  dev_private->is_valid=0;  dev_private->lcr_io_base=lcr_io_base;  dev_private->lcr_io_range=lcr_io_range;    pci9111_reset(dev);  // Irq setup    dev->irq=0;  if (pci_device->irq>0)   {    if (comedi_request_irq (pci_device->irq,			    pci9111_interrupt, 			    SA_SHIRQ, 			    PCI9111_DRIVER_NAME, 			    dev)!=0)    {      printk ("comedi%d: unable to allocate irq  %d\n", dev->minor, pci_device->irq);      return -EINVAL;    }  }  dev->irq = pci_device->irq;  //// TODO: Add external multiplexer setup (according to option[2]).//  if((error=alloc_subdevices(dev, 4))<0)    return  error;    subdevice 			= dev->subdevices + 0;  dev->read_subdev = subdevice;  subdevice->type 		= COMEDI_SUBD_AI;  subdevice->subdev_flags 	= SDF_READABLE|SDF_COMMON;//// TODO: Add external multiplexer data// //    if (devpriv->usemux) { subdevice->n_chan = devpriv->usemux; }//    else { subdevice->n_chan = this_board->n_aichan; }//    subdevice->n_chan 		= board->ai_channel_nbr;  subdevice->maxdata 		= board->ai_resolution_mask;  subdevice->len_chanlist 	= board->ai_channel_nbr;  subdevice->range_table 	= board->ai_range_list;  subdevice->cancel		= pci9111_ai_cancel;  subdevice->insn_read		= pci9111_ai_insn_read;  subdevice->do_cmdtest		= pci9111_ai_do_cmd_test;  subdevice->do_cmd		= pci9111_ai_do_cmd;  subdevice 			= dev->subdevices + 1;  subdevice->type 		= COMEDI_SUBD_AO;  subdevice->subdev_flags	= SDF_WRITABLE|SDF_COMMON;   subdevice->n_chan		= board->ao_channel_nbr;  subdevice->maxdata		= board->ao_resolution_mask;  subdevice->len_chanlist	= board->ao_channel_nbr;  subdevice->range_table	= board->ao_range_list;  subdevice->insn_write		= pci9111_ao_insn_write;  subdevice->insn_read		= pci9111_ao_insn_read;      subdevice 			= dev->subdevices + 2;  subdevice->type 		= COMEDI_SUBD_DI;  subdevice->subdev_flags 	= SDF_READABLE;  subdevice->n_chan 		= PCI9111_DI_CHANNEL_NBR;  subdevice->maxdata 		= 1;  subdevice->range_table 	= &range_digital;  subdevice->insn_bits		= pci9111_di_insn_bits;	  subdevice 			= dev->subdevices + 3;  subdevice->type 		= COMEDI_SUBD_DO;  subdevice->subdev_flags 	= SDF_READABLE|SDF_WRITABLE;  subdevice->n_chan 		= PCI9111_DO_CHANNEL_NBR;  subdevice->maxdata 		= 1;  subdevice->range_table 	= &range_digital;  subdevice->insn_bits		= pci9111_do_insn_bits;    dev_private->is_valid			= 1;    return 0;}//// Detach //static int pci9111_detach(comedi_device *dev){  // Reset device    if (dev->private!=0)   {    if (dev_private->is_valid) pci9111_reset(dev);  }  // Release previously allocated irq    if (dev->irq!=0)  {    comedi_free_irq(dev->irq,dev);  }  pci_release_regions(dev_private->pci_device);  return 0;}

⌨️ 快捷键说明

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