📄 adv_pci_dio.c
字号:
outw(0, dev->iobase+PCI1752_IDO+2); outw(0, dev->iobase+PCI1752_IDO2); outw(0, dev->iobase+PCI1752_IDO2+2); break; case TYPE_PCI1753E: outb(0x88, dev->iobase+PCI1753E_ICR0); // disable & clear interrupts outb(0x80, dev->iobase+PCI1753E_ICR1); outb(0x80, dev->iobase+PCI1753E_ICR2); outb(0x80, dev->iobase+PCI1753E_ICR3); /* NO break there! */ case TYPE_PCI1753: outb(0x88, dev->iobase+PCI1753_ICR0); // disable & clear interrupts outb(0x80, dev->iobase+PCI1753_ICR1); outb(0x80, dev->iobase+PCI1753_ICR2); outb(0x80, dev->iobase+PCI1753_ICR3); break; case TYPE_PCI1754: outw(0x08, dev->iobase+PCI1754_6_ICR0); // disable and clear interrupts outw(0x08, dev->iobase+PCI1754_6_ICR1); outw(0x08, dev->iobase+PCI1754_ICR2); outw(0x08, dev->iobase+PCI1754_ICR3); break; case TYPE_PCI1756: outw(0, dev->iobase+PCI1752_6_CFC); // disable channel freeze function outw(0x08, dev->iobase+PCI1754_6_ICR0); // disable and clear interrupts outw(0x08, dev->iobase+PCI1754_6_ICR1); outw(0, dev->iobase+PCI1756_IDO); // clear outputs outw(0, dev->iobase+PCI1756_IDO+2); break; case TYPE_PCI1760: pci1760_reset(dev); break; case TYPE_PCI1762: outw(0x0101, dev->iobase+PCI1750_ICR); // disable & clear interrupts break; } DPRINTK("adv_pci_dio EDBG: END: pci171x_reset(...)\n"); return 0;}/* ==============================================================================*/static int pci1760_attach(comedi_device *dev, comedi_devconfig *it){ comedi_subdevice *s; int subdev=0; s = dev->subdevices + subdev; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE|SDF_GROUND|SDF_COMMON; s->n_chan = 8; s->maxdata = 1; s->len_chanlist = 8; s->range_table = &range_digital; s->io_bits=0; /* all bits input */ s->insn_read=pci1760_insn_read_di; s->insn_bits=pci1760_insn_bits_di; subdev++; s = dev->subdevices + subdev; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE|SDF_GROUND|SDF_COMMON; s->n_chan = 8; s->maxdata = 1; s->len_chanlist = 8; s->range_table = &range_digital; s->io_bits=255; /* all bits output */ s->state=0; s->insn_bits=pci1760_insn_bits_do; subdev++; s = dev->subdevices + subdev; s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITABLE|SDF_LSAMPL; s->n_chan = 2; s->maxdata = 0xffffffff; s->len_chanlist = 2;// s->insn_config=pci1760_insn_pwm_cfg; subdev++; s = dev->subdevices + subdev; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE|SDF_WRITABLE; s->n_chan = 8; s->maxdata = 0xffff; s->len_chanlist = 8; s->insn_read=pci1760_insn_cnt_read; s->insn_write=pci1760_insn_cnt_write;// s->insn_config=pci1760_insn_cnt_cfg; subdev++; return 0;}/* ==============================================================================*/static int pci_dio_add_di(comedi_device *dev, comedi_subdevice *s, diosubd_data *d, int subdev){ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE|SDF_GROUND|SDF_COMMON|d->specflags; if (d->chans>16) s->subdev_flags |= SDF_LSAMPL; s->n_chan = d->chans; s->maxdata = 1; s->len_chanlist = d->chans; s->range_table = &range_digital; s->io_bits=0; /* all bits input */ switch (this_board->io_access) { case IO_8b: s->insn_bits=pci_dio_insn_bits_di_b; break; case IO_16b: s->insn_bits=pci_dio_insn_bits_di_w; break; } s->private=d; return 0;}/* ==============================================================================*/static int pci_dio_add_do(comedi_device *dev, comedi_subdevice *s, diosubd_data *d, int subdev){ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE|SDF_GROUND|SDF_COMMON; if (d->chans>16) s->subdev_flags |= SDF_LSAMPL; s->n_chan = d->chans; s->maxdata = 1; s->len_chanlist = d->chans; s->range_table = &range_digital; s->io_bits=(1 << d->chans)-1; /* all bits output */ s->state=0; switch (this_board->io_access) { case IO_8b: s->insn_bits=pci_dio_insn_bits_do_b; break; case IO_16b: s->insn_bits=pci_dio_insn_bits_do_w; break; } s->private=d; return 0;}/* ==============================================================================*/static int CheckAndAllocCard(comedi_device *dev, comedi_devconfig *it, struct pci_dev* pcidev){ pci_dio_private *pr, *prev; if (!pci_priv) { // well, first card in system pci_priv=devpriv; return 1; } for (pr=pci_priv, prev=NULL; pr!=NULL; prev=pr, pr=pr->next) if (pr->pcidev==pcidev) { if (it->options[0]||it->options[1]) { if ((pr->pcidev->bus->number==it->options[0])&& (PCI_SLOT(pr->pcidev->devfn)==it->options[1])) { rt_printk(", Error: Card on requested position is used!\n"); return 2; } } return 0; // this card is used, look for another } if (prev) { devpriv->prev=prev; } { pci_priv=devpriv; } return 1;}/* ==============================================================================*/static int pci_dio_attach(comedi_device *dev, comedi_devconfig *it){ comedi_subdevice *s; int ret, subdev, n_subdevices, i, j, iobase, found=0; struct pci_dev* pcidev; rt_printk("comedi%d: adv_pci_dio: board=%s", dev->minor, this_board->name); if ((ret=alloc_private(dev,sizeof(pci_dio_private)))<0) { rt_printk(", Error: Cann't allocate private memory!\n"); return -ENOMEM; } pci_for_each_dev(pcidev) { if ((pcidev->vendor!=this_board->vendor_id)|| (pcidev->device!=this_board->device_id)) continue; if (it->options[0]||it->options[1]) { if ((pcidev->bus->number!=it->options[0])|| (PCI_SLOT(pcidev->devfn)!=it->options[1])) { continue; } } ret=CheckAndAllocCard(dev, it, pcidev); if (ret==1) { found=1; break; } if (ret>1) { pci_dio_detach(dev); return -EIO; } } if (!found) { rt_printk(", Error: Requested type of the card was not found!\n"); pci_dio_detach(dev); return -EIO; } iobase=pci_resource_start(pcidev, this_board->main_pci_region); rt_printk(", b:s:f=%d:%d:%d, io=0x%4x", pcidev->bus->number, PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn), iobase); if (pci_request_regions(pcidev, driver_pci_dio.driver_name)) { pci_dio_detach(dev); rt_printk(", Error: Cann't allocate PCI device!\n"); return -EIO; } devpriv->pcidev=pcidev; if (pci_enable_device(pcidev)) { pci_dio_detach(dev); rt_printk(", Error: Cann't enable PCI device!\n"); return -EIO; } devpriv->enabled=1; dev->iobase=iobase; dev->board_name=this_board->name; if (this_board->cardtype==TYPE_PCI1760) { n_subdevices=4; // 8 IDI, 8 IDO, 2 PWM, 8 CNT } else { n_subdevices=0; for (i=0; i<MAX_DI_SUBDEVS; i++) if (this_board->sdi[i].chans) n_subdevices++; for (i=0; i<MAX_DO_SUBDEVS; i++) if (this_board->sdo[i].chans) n_subdevices++; for (i=0; i<MAX_DIO_SUBDEVG; i++) n_subdevices+=this_board->sdio[i].regs; if (this_board->boardid.chans) n_subdevices++; } if((ret=alloc_subdevices(dev, n_subdevices))<0) { rt_printk(", Error: Cann't allocate subdevice memory!\n"); pci_dio_detach(dev); return ret; } rt_printk(".\n"); subdev=0; for (i=0; i<MAX_DI_SUBDEVS; i++) if (this_board->sdi[i].chans) { s = dev->subdevices + subdev; pci_dio_add_di(dev, s, &this_board->sdi[i], subdev); subdev++; } for (i=0; i<MAX_DO_SUBDEVS; i++) if (this_board->sdo[i].chans) { s = dev->subdevices + subdev; pci_dio_add_do(dev, s, &this_board->sdo[i], subdev); subdev++; } for (i=0; i<MAX_DIO_SUBDEVG; i++) for (j=0; j<this_board->sdio[i].regs; j++) { s = dev->subdevices + subdev; subdev_8255_init(dev, s, NULL, dev->iobase+this_board->sdio[i].addr+SIZE_8255*j); subdev++; } if (this_board->boardid.chans) { s = dev->subdevices + subdev; s->type = COMEDI_SUBD_DI; pci_dio_add_di(dev, s, &this_board->boardid, subdev); subdev++; } if (this_board->cardtype==TYPE_PCI1760) pci1760_attach(dev, it); devpriv->valid=1; pci_dio_reset(dev); return 0;}/* ==============================================================================*/static int pci_dio_detach(comedi_device *dev){ int i; comedi_subdevice *s; if (dev->private) { if (devpriv->valid) { pci_dio_reset(dev); } for (i=0; i<dev->n_subdevices; i++) { s=dev->subdevices+i; s->private=NULL; } if (devpriv->enabled) pci_disable_device(devpriv->pcidev); if (devpriv->pcidev) pci_release_regions(devpriv->pcidev); if (devpriv->prev) { devpriv->prev->next=devpriv->next; } { pci_priv=devpriv->next; } if (devpriv->next) { devpriv->next->prev=devpriv->prev; } } return 0;}/* ==============================================================================*/COMEDI_INITCLEANUP(driver_pci_dio);/* ==============================================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -