static int apci1032_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct apci1032_private *devpriv; struct comedi_subdevice *s; int ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; ret = comedi_pci_enable(dev); if (ret) return ret; devpriv->amcc_iobase = pci_resource_start(pcidev, 0); dev->iobase = pci_resource_start(pcidev, 1); apci1032_reset(dev); if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, apci1032_interrupt, IRQF_SHARED, dev->board_name, dev); if (ret == 0) dev->irq = pcidev->irq; } ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 32; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = apci1032_di_insn_bits; /* Change-Of-State (COS) interrupt subdevice */ s = &dev->subdevices[1]; if (dev->irq) { dev->read_subdev = s; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_CMD_READ; s->n_chan = 1; s->maxdata = 1; s->range_table = &range_digital; s->insn_config = apci1032_cos_insn_config; s->insn_bits = apci1032_cos_insn_bits; s->len_chanlist = 1; s->do_cmdtest = apci1032_cos_cmdtest; s->do_cmd = apci1032_cos_cmd; s->cancel = apci1032_cos_cancel; } else { s->type = COMEDI_SUBD_UNUSED; } return 0; }
static int labpc_pci_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct labpc_boardinfo *board = NULL; struct labpc_private *devpriv; int ret; if (context < ARRAY_SIZE(labpc_pci_boards)) board = &labpc_pci_boards[context]; if (!board) return -ENODEV; dev->board_ptr = board; dev->board_name = board->name; ret = comedi_pci_enable(dev); if (ret) return ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) return -ENOMEM; ret = mite_setup(devpriv->mite); if (ret < 0) return ret; dev->iobase = (unsigned long)devpriv->mite->daq_io_addr; return labpc_common_attach(dev, mite_irq(devpriv->mite), IRQF_SHARED); }
static int pci236_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pci_dev = comedi_to_pci_dev(dev); struct pc236_private *devpriv; unsigned long iobase; int ret; dev_info(dev->class_dev, "amplc_pci236: attach pci %s\n", pci_name(pci_dev)); devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; dev->board_ptr = &pc236_pci_board; dev->board_name = pc236_pci_board.name; ret = comedi_pci_enable(dev); if (ret) return ret; devpriv->lcr_iobase = pci_resource_start(pci_dev, 1); iobase = pci_resource_start(pci_dev, 2); return amplc_pc236_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED); }
static int labpc_pci_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct labpc_boardinfo *board = NULL; struct labpc_private *devpriv; int ret; if (context < ARRAY_SIZE(labpc_pci_boards)) board = &labpc_pci_boards[context]; if (!board) return -ENODEV; dev->board_ptr = board; dev->board_name = board->name; ret = comedi_pci_enable(dev); if (ret) return ret; ret = labpc_pci_mite_init(pcidev); if (ret) return ret; dev->mmio = pci_ioremap_bar(pcidev, 1); if (!dev->mmio) return -ENOMEM; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; return labpc_common_attach(dev, pcidev->irq, IRQF_SHARED); }
static int pcm3724_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct priv_pcm3724 *priv; struct comedi_subdevice *s; int ret, i; priv = comedi_alloc_devpriv(dev, sizeof(*priv)); if (!priv) return -ENOMEM; ret = comedi_request_region(dev, it->options[0], PCM3724_SIZE); if (ret) return ret; ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; for (i = 0; i < dev->n_subdevices; i++) { s = &dev->subdevices[i]; subdev_8255_init(dev, s, subdev_8255_cb, (unsigned long)(dev->iobase + SIZE_8255 * i)); s->insn_config = subdev_3724_insn_config; } return 0; }
static int dio200_pci_auto_attach(struct comedi_device *dev, unsigned long context_model) { struct pci_dev *pci_dev = comedi_to_pci_dev(dev); const struct dio200_board *thisboard = NULL; struct dio200_private *devpriv; unsigned int bar; int ret; if (context_model < ARRAY_SIZE(dio200_pci_boards)) thisboard = &dio200_pci_boards[context_model]; if (!thisboard) return -EINVAL; dev->board_ptr = thisboard; dev->board_name = thisboard->name; dev_info(dev->class_dev, "%s: attach pci %s (%s)\n", dev->driver->driver_name, pci_name(pci_dev), dev->board_name); devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; ret = comedi_pci_enable(dev); if (ret) return ret; bar = thisboard->mainbar; if (pci_resource_len(pci_dev, bar) < thisboard->mainsize) { dev_err(dev->class_dev, "error! PCI region size too small!\n"); return -EINVAL; } if (pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) { devpriv->io.u.membase = pci_ioremap_bar(pci_dev, bar); if (!devpriv->io.u.membase) { dev_err(dev->class_dev, "error! cannot remap registers\n"); return -ENOMEM; } devpriv->io.regtype = mmio_regtype; } else { devpriv->io.u.iobase = pci_resource_start(pci_dev, bar); devpriv->io.regtype = io_regtype; } switch (context_model) { case pcie215_model: case pcie236_model: case pcie296_model: ret = dio200_pcie_board_setup(dev); if (ret < 0) return ret; break; default: break; } return amplc_dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED); }
static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct fl512_private *devpriv; struct comedi_subdevice *s; int ret; ret = comedi_request_region(dev, it->options[0], FL512_SIZE); if (ret) return ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; /* * this if the definitions of the supdevices, 2 have been defined */ /* Analog indput */ s = &dev->subdevices[0]; /* define subdevice as Analog In */ s->type = COMEDI_SUBD_AI; /* you can read it from userspace */ s->subdev_flags = SDF_READABLE | SDF_GROUND; /* Number of Analog input channels */ s->n_chan = 16; /* accept only 12 bits of data */ s->maxdata = 0x0fff; /* device use one of the ranges */ s->range_table = &range_fl512; /* function to call when read AD */ s->insn_read = fl512_ai_insn; /* Analog output */ s = &dev->subdevices[1]; /* define subdevice as Analog OUT */ s->type = COMEDI_SUBD_AO; /* you can write it from userspace */ s->subdev_flags = SDF_WRITABLE; /* Number of Analog output channels */ s->n_chan = 2; /* accept only 12 bits of data */ s->maxdata = 0x0fff; /* device use one of the ranges */ s->range_table = &range_fl512; /* function to call when write DA */ s->insn_write = fl512_ao_insn; /* function to call when reading DA */ s->insn_read = fl512_ao_insn_readback; return 1; }
static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pc236_private *devpriv; int ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; ret = comedi_request_region(dev, it->options[0], 0x4); if (ret) return ret; return amplc_pc236_common_attach(dev, dev->iobase, it->options[1], 0); }
static int das08_isa_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das08_board_struct *thisboard = dev->board_ptr; struct das08_private_struct *devpriv; int ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; ret = comedi_request_region(dev, it->options[0], thisboard->iosize); if (ret) return ret; return das08_common_attach(dev, dev->iobase); }
static int das08_pci_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pdev = comedi_to_pci_dev(dev); struct das08_private_struct *devpriv; int ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; /* The das08 driver needs the board_ptr */ dev->board_ptr = &das08_pci_boards[0]; ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pdev, 2); return das08_common_attach(dev, dev->iobase); }
static int multiq3_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct multiq3_private *devpriv; struct comedi_subdevice *s; int ret; ret = comedi_request_region(dev, it->options[0], 0x10); if (ret) return ret; ret = comedi_alloc_subdevices(dev, 5); if (ret) return ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; s = &dev->subdevices[0]; /* ai subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = 8; s->insn_read = multiq3_ai_insn_read; s->maxdata = 0x1fff; s->range_table = &range_bipolar5; s = &dev->subdevices[1]; /* ao subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->insn_read = multiq3_ao_insn_read; s->insn_write = multiq3_ao_insn_write; s->maxdata = 0xfff; s->range_table = &range_bipolar5; s = &dev->subdevices[2]; /* di subdevice */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 16; s->insn_bits = multiq3_di_insn_bits; s->maxdata = 1; s->range_table = &range_digital; s = &dev->subdevices[3]; /* do subdevice */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->insn_bits = multiq3_do_insn_bits; s->maxdata = 1; s->range_table = &range_digital; s->state = 0; s = &dev->subdevices[4]; /* encoder (counter) subdevice */ s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_LSAMPL; s->n_chan = it->options[2] * 2; s->insn_read = multiq3_encoder_insn_read; s->maxdata = 0xffffff; s->range_table = &range_unknown; encoder_reset(dev); return 0; }
static int apci1500_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct apci1500_private *devpriv; struct comedi_subdevice *s; int ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 1); devpriv->iobase = dev->iobase; devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, apci1500_interrupt, IRQF_SHARED, dev->board_name, dev); if (ret == 0) dev->irq = pcidev->irq; } ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->insn_config = apci1500_di_config; s->insn_read = apci1500_di_read; s->insn_write = apci1500_di_write; s->insn_bits = apci1500_di_insn_bits; /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->insn_config = apci1500_do_config; s->insn_write = apci1500_do_write; s->insn_bits = apci1500_do_bits; /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[2]; s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITABLE; s->n_chan = 1; s->maxdata = 0; s->len_chanlist = 1; s->range_table = &range_digital; s->insn_write = apci1500_timer_write; s->insn_read = apci1500_timer_read; s->insn_config = apci1500_timer_config; s->insn_bits = apci1500_timer_bits; apci1500_reset(dev); return 0; }
static int pci_8255_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct pci_8255_boardinfo *board = NULL; struct pci_8255_private *devpriv; struct comedi_subdevice *s; bool is_mmio; int ret; int i; if (context < ARRAY_SIZE(pci_8255_boards)) board = &pci_8255_boards[context]; if (!board) return -ENODEV; dev->board_ptr = board; dev->board_name = board->name; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; ret = comedi_pci_enable(dev); if (ret) return ret; if (board->has_mite) { ret = pci_8255_mite_init(pcidev); if (ret) return ret; } is_mmio = (pci_resource_flags(pcidev, board->dio_badr) & IORESOURCE_MEM) != 0; if (is_mmio) { devpriv->mmio_base = pci_ioremap_bar(pcidev, board->dio_badr); if (!devpriv->mmio_base) return -ENOMEM; } else { dev->iobase = pci_resource_start(pcidev, board->dio_badr); } /* * One, two, or four subdevices are setup by this driver depending * on the number of channels provided by the board. Each subdevice * has 24 channels supported by the 8255 module. */ ret = comedi_alloc_subdevices(dev, board->n_8255); if (ret) return ret; for (i = 0; i < board->n_8255; i++) { unsigned long iobase; s = &dev->subdevices[i]; if (is_mmio) { iobase = (unsigned long)(devpriv->mmio_base + (i * 4)); ret = subdev_8255_init(dev, s, pci_8255_mmio, iobase); } else { iobase = dev->iobase + (i * 4); ret = subdev_8255_init(dev, s, NULL, iobase); } if (ret) return ret; } return 0; }
static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct dt2815_private *devpriv; struct comedi_subdevice *s; int i; const struct comedi_lrange *current_range_type, *voltage_range_type; int ret; ret = comedi_request_region(dev, it->options[0], 0x2); if (ret) return ret; ret = comedi_alloc_subdevices(dev, 1); if (ret) return ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; s = &dev->subdevices[0]; /* ao subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->maxdata = 0xfff; s->n_chan = 8; s->insn_write = dt2815_ao_insn; s->insn_read = dt2815_ao_insn_read; s->range_table_list = devpriv->range_type_list; current_range_type = (it->options[3]) ? &range_4_20mA : &range_0_32mA; voltage_range_type = (it->options[2]) ? &range_bipolar5 : &range_unipolar5; for (i = 0; i < 8; i++) { devpriv->range_type_list[i] = (it->options[5 + i]) ? current_range_type : voltage_range_type; } /* Init the 2815 */ outb(0x00, dev->iobase + DT2815_STATUS); for (i = 0; i < 100; i++) { /* This is incredibly slow (approx 20 ms) */ unsigned int status; usleep_range(1000, 3000); status = inb(dev->iobase + DT2815_STATUS); if (status == 4) { unsigned int program; program = (it->options[4] & 0x3) << 3 | 0x7; outb(program, dev->iobase + DT2815_DATA); dev_dbg(dev->class_dev, "program: 0x%x (@t=%d)\n", program, i); break; } else if (status != 0x00) { dev_dbg(dev->class_dev, "unexpected status 0x%x (@t=%d)\n", status, i); if (status & 0x60) outb(0x00, dev->iobase + DT2815_STATUS); } } return 0; }
static int dyna_pci10xx_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct dyna_pci10xx_private *devpriv; struct comedi_subdevice *s; int ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 2); devpriv->BADR3 = pci_resource_start(pcidev, 3); mutex_init(&devpriv->mutex); ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; /* analog input */ s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; s->n_chan = 16; s->maxdata = 0x0FFF; s->range_table = &range_pci1050_ai; s->len_chanlist = 16; s->insn_read = dyna_pci10xx_insn_read_ai; /* analog output */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 0x0FFF; s->range_table = &range_unipolar10; s->len_chanlist = 16; s->insn_write = dyna_pci10xx_insn_write_ao; /* digital input */ s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->len_chanlist = 16; s->insn_bits = dyna_pci10xx_di_insn_bits; /* digital output */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->len_chanlist = 16; s->state = 0; s->insn_bits = dyna_pci10xx_do_insn_bits; return 0; }
static int usbduxsigma_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct usb_interface *intf = comedi_to_usb_interface(dev); struct usb_device *usb = comedi_to_usb_dev(dev); struct usbduxsigma_private *devpriv; struct comedi_subdevice *s; int offset; int ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; sema_init(&devpriv->sem, 1); usb_set_intfdata(intf, devpriv); devpriv->high_speed = (usb->speed == USB_SPEED_HIGH); if (devpriv->high_speed) { devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH; devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH; devpriv->pwm_buf_sz = 512; } else { devpriv->n_ai_urbs = NUMOFINBUFFERSFULL; devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL; } ret = usbduxsigma_alloc_usb_buffers(dev); if (ret) return ret; /* setting to alternate setting 3: enabling iso ep and bulk ep. */ ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber, 3); if (ret < 0) { dev_err(dev->class_dev, "could not set alternate setting 3 in high speed\n"); return ret; } ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE, usbduxsigma_firmware_upload, 0); if (ret) return ret; ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 4 : 3); if (ret) return ret; /* Analog Input subdevice */ s = &dev->subdevices[0]; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ | SDF_LSAMPL; s->n_chan = NUMCHANNELS; s->len_chanlist = NUMCHANNELS; s->maxdata = 0x00ffffff; s->range_table = &usbduxsigma_ai_range; s->insn_read = usbduxsigma_ai_insn_read; s->do_cmdtest = usbduxsigma_ai_cmdtest; s->do_cmd = usbduxsigma_ai_cmd; s->cancel = usbduxsigma_ai_cancel; /* Analog Output subdevice */ s = &dev->subdevices[1]; dev->write_subdev = s; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; s->n_chan = 4; s->len_chanlist = s->n_chan; s->maxdata = 0x00ff; s->range_table = &range_unipolar2_5; s->insn_write = usbduxsigma_ao_insn_write; s->insn_read = usbduxsigma_ao_insn_read; s->do_cmdtest = usbduxsigma_ao_cmdtest; s->do_cmd = usbduxsigma_ao_cmd; s->cancel = usbduxsigma_ao_cancel; ret = comedi_alloc_subdev_readback(s); if (ret) return ret; /* Digital I/O subdevice */ s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 24; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = usbduxsigma_dio_insn_bits; s->insn_config = usbduxsigma_dio_insn_config; if (devpriv->high_speed) { /* Timer / pwm subdevice */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_PWM; s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; s->n_chan = 8; s->maxdata = devpriv->pwm_buf_sz; s->insn_write = usbduxsigma_pwm_write; s->insn_config = usbduxsigma_pwm_config; usbduxsigma_pwm_period(dev, s, PWM_DEFAULT_PERIOD); } offset = usbduxsigma_getstatusinfo(dev, 0); if (offset < 0) { dev_err(dev->class_dev, "Communication to USBDUXSIGMA failed! Check firmware and cabling.\n"); return offset; } dev_info(dev->class_dev, "ADC_zero = %x\n", offset); return 0; }
static int addi_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct addi_board *this_board = dev->board_ptr; struct addi_private *devpriv; struct comedi_subdevice *s; int ret, n_subdevices; unsigned int dw_Dummy; dev->board_name = this_board->pc_DriverName; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; ret = comedi_pci_enable(dev); if (ret) return ret; if (this_board->i_IorangeBase1) dev->iobase = pci_resource_start(pcidev, 1); else dev->iobase = pci_resource_start(pcidev, 0); devpriv->iobase = dev->iobase; devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); /* Initialize parameters that can be overridden in EEPROM */ devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; devpriv->s_EeParameters.i_Timer = this_board->i_Timer; devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = this_board->ui_MinAcquisitiontimeNs; devpriv->s_EeParameters.ui_MinDelaytimeNs = this_board->ui_MinDelaytimeNs; /* ## */ if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, dev->board_name, dev); if (ret == 0) dev->irq = pcidev->irq; } /* Read eepeom and fill addi_board Structure */ if (this_board->i_PCIEeprom) { if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { /* Set 3 wait stait */ if (!(strcmp(dev->board_name, "apci035"))) outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); else outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); /* Enable the interrupt for the controller */ dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); } addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); } n_subdevices = 7; ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret) return ret; /* Allocate and Initialise AI Subdevice Structures */ s = &dev->subdevices[0]; if ((devpriv->s_EeParameters.i_NbrAiChannel) || (this_board->i_NbrAiChannelDiff)) { dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; if (devpriv->s_EeParameters.i_NbrAiChannel) s->n_chan = devpriv->s_EeParameters.i_NbrAiChannel; else s->n_chan = this_board->i_NbrAiChannelDiff; s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; s->len_chanlist = this_board->i_AiChannelList; s->range_table = this_board->pr_AiRangelist; s->insn_config = this_board->ai_config; s->insn_read = this_board->ai_read; s->insn_write = this_board->ai_write; s->insn_bits = this_board->ai_bits; s->do_cmdtest = this_board->ai_cmdtest; s->do_cmd = this_board->ai_cmd; s->cancel = this_board->ai_cancel; } else { s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise AO Subdevice Structures */ s = &dev->subdevices[1]; if (devpriv->s_EeParameters.i_NbrAoChannel) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; s->len_chanlist = devpriv->s_EeParameters.i_NbrAoChannel; s->insn_write = this_board->ao_write; } else { s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[2]; if (devpriv->s_EeParameters.i_NbrDiChannel) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; s->maxdata = 1; s->len_chanlist = devpriv->s_EeParameters.i_NbrDiChannel; s->range_table = &range_digital; s->insn_config = this_board->di_config; s->insn_read = this_board->di_read; s->insn_write = this_board->di_write; s->insn_bits = this_board->di_bits; } else { s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; if (devpriv->s_EeParameters.i_NbrDoChannel) { s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; s->len_chanlist = devpriv->s_EeParameters.i_NbrDoChannel; s->range_table = &range_digital; /* insn_config - for digital output memory */ s->insn_config = this_board->do_config; s->insn_write = this_board->do_write; s->insn_bits = this_board->do_bits; s->insn_read = this_board->do_read; } else { s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[4]; if (devpriv->s_EeParameters.i_Timer) { s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE | 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->timer_write; s->insn_read = this_board->timer_read; s->insn_config = this_board->timer_config; s->insn_bits = this_board->timer_bits; } else { s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise TTL */ s = &dev->subdevices[5]; 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; } i_ADDI_Reset(dev); return 0; }
/* options[0] Board base address options[1] IRQ options[2] Input configuration 0 == single-ended 1 == differential 2 == pseudo-differential options[3] Analog input range configuration 0 == bipolar 5 (-5V -- +5V) 1 == bipolar 2.5V (-2.5V -- +2.5V) 2 == unipolar 5V (0V -- +5V) options[4] Analog output 0 range configuration 0 == bipolar 5 (-5V -- +5V) 1 == bipolar 2.5V (-2.5V -- +2.5V) 2 == unipolar 5V (0V -- +5V) options[5] Analog output 1 range configuration 0 == bipolar 5 (-5V -- +5V) 1 == bipolar 2.5V (-2.5V -- +2.5V) 2 == unipolar 5V (0V -- +5V) */ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) { /* int i; */ const struct dt2811_board *board = dev->board_ptr; struct dt2811_private *devpriv; int ret; struct comedi_subdevice *s; ret = comedi_request_region(dev, it->options[0], 0x8); if (ret) return ret; #if 0 outb(0, dev->iobase + DT2811_ADCSR); udelay(100); i = inb(dev->iobase + DT2811_ADDATLO); i = inb(dev->iobase + DT2811_ADDATHI); #endif ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; switch (it->options[2]) { case 0: devpriv->adc_mux = adc_singleended; break; case 1: devpriv->adc_mux = adc_diff; break; case 2: devpriv->adc_mux = adc_pseudo_diff; break; default: devpriv->adc_mux = adc_singleended; break; } switch (it->options[4]) { case 0: devpriv->dac_range[0] = dac_bipolar_5; break; case 1: devpriv->dac_range[0] = dac_bipolar_2_5; break; case 2: devpriv->dac_range[0] = dac_unipolar_5; break; default: devpriv->dac_range[0] = dac_bipolar_5; break; } switch (it->options[5]) { case 0: devpriv->dac_range[1] = dac_bipolar_5; break; case 1: devpriv->dac_range[1] = dac_bipolar_2_5; break; case 2: devpriv->dac_range[1] = dac_unipolar_5; break; default: devpriv->dac_range[1] = dac_bipolar_5; break; } s = &dev->subdevices[0]; /* initialize the ADC subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = devpriv->adc_mux == adc_diff ? 8 : 16; s->insn_read = dt2811_ai_insn; s->maxdata = 0xfff; switch (it->options[3]) { case 0: default: s->range_table = board->bip_5; break; case 1: s->range_table = board->bip_2_5; break; case 2: s->range_table = board->unip_5; break; } s = &dev->subdevices[1]; /* ao subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = 0xfff; s->range_table_list = devpriv->range_type_list; devpriv->range_type_list[0] = dac_range_types[devpriv->dac_range[0]]; devpriv->range_type_list[1] = dac_range_types[devpriv->dac_range[1]]; s->insn_write = dt2811_ao_insn_write; ret = comedi_alloc_subdev_readback(s); if (ret) return ret; s = &dev->subdevices[2]; /* di subdevice */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 8; s->insn_bits = dt2811_di_insn_bits; s->maxdata = 1; s->range_table = &range_digital; s = &dev->subdevices[3]; /* do subdevice */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 8; s->insn_bits = dt2811_do_insn_bits; s->maxdata = 1; s->state = 0; s->range_table = &range_digital; return 0; }