static int pci263_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pci_dev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret; ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pci_dev, 2); ret = comedi_alloc_subdevices(dev, 1); if (ret) return ret; s = &dev->subdevices[0]; /* digital output subdevice */ 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_bits = pci263_do_insn_bits; /* read initial relay state */ s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8); return 0; }
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 aio_iiro_16_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; int ret; ret = comedi_request_region(dev, it->options[0], AIO_IIRO_16_SIZE); if (ret) return ret; ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = aio_iiro_16_dio_insn_bits_write; s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = aio_iiro_16_dio_insn_bits_read; return 1; }
static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; int ret; ret = comedi_alloc_subdevices(dev, 1); if (ret) return ret; s = &dev->subdevices[0]; /* digital i/o subdevice */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 20; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = dnp_dio_insn_bits; s->insn_config = dnp_dio_insn_config; /* We use the I/O ports 0x22,0x23 and 0xa3-0xa9, which are always * allocated for the primary 8259, so we don't need to allocate them * ourselves. */ /* configure all ports as input (default) */ outb(PAMR, CSCIR); outb(0x00, CSCDR); outb(PBMR, CSCIR); outb(0x00, CSCDR); outb(PCMR, CSCIR); outb((inb(CSCDR) & 0xAA), CSCDR); dev_info(dev->class_dev, "%s: attached\n", dev->board_name); return 1; }
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 pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; int ret; ret = comedi_request_region(dev, it->options[0], PCL725_SIZE); if (ret) return ret; ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; s = &dev->subdevices[0]; /* do */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->maxdata = 1; s->n_chan = 8; s->insn_bits = pcl725_do_insn; s->range_table = &range_digital; s = &dev->subdevices[1]; /* di */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->maxdata = 1; s->n_chan = 8; s->insn_bits = pcl725_di_insn; s->range_table = &range_digital; printk(KERN_INFO "\n"); return 0; }
static int pci6208_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; unsigned int val; int ret; ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 2); ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; s = &dev->subdevices[0]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; /* Only 8 usable on PCI-6208 */ s->maxdata = 0xffff; s->range_table = &range_bipolar10; s->insn_write = pci6208_ao_insn_write; ret = comedi_alloc_subdev_readback(s); if (ret) return ret; s = &dev->subdevices[1]; /* digital input subdevice */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = pci6208_di_insn_bits; s = &dev->subdevices[2]; /* digital output subdevice */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = pci6208_do_insn_bits; /* * Get the read back signals from the digital outputs * and save it as the initial state for the subdevice. */ val = inw(dev->iobase + PCI6208_DIO); val = (val & PCI6208_DIO_DO_MASK) >> PCI6208_DIO_DO_SHIFT; s->state = val; return 0; }
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 c6xdigio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; int ret; ret = comedi_request_region(dev, it->options[0], C6XDIGIO_SIZE); if (ret) return ret; ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; /* Make sure that PnP ports get activated */ pnp_register_driver(&c6xdigio_pnp_driver); s = &dev->subdevices[0]; /* pwm output subdevice */ s->type = COMEDI_SUBD_AO; /* Not sure what to put here */ s->subdev_flags = SDF_WRITEABLE; s->n_chan = 2; /* s->trig[0] = c6xdigio_pwmo; */ s->insn_read = c6xdigio_pwmo_insn_read; s->insn_write = c6xdigio_pwmo_insn_write; s->maxdata = 500; s->range_table = &range_bipolar10; /* A suitable lie */ s = &dev->subdevices[1]; /* encoder (counter) subdevice */ s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE | SDF_LSAMPL; s->n_chan = 2; /* s->trig[0] = c6xdigio_ei; */ s->insn_read = c6xdigio_ei_insn_read; s->maxdata = 0xffffff; s->range_table = &range_unknown; /* s = &dev->subdevices[2]; */ /* pwm output subdevice */ /* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */ /* s->subdev_flags = SDF_WRITEABLE; */ /* s->n_chan = 1; */ /* s->trig[0] = c6xdigio_ei_init; */ /* s->insn_read = c6xdigio_ei_init_insn_read; */ /* s->insn_write = c6xdigio_ei_init_insn_write; */ /* s->maxdata = 0xFFFF; // Really just a don't care */ /* s->range_table = &range_unknown; // Not sure what to put here */ /* I will call this init anyway but more than likely the DSP board */ /* will not be connected when device driver is loaded. */ board_init(dev); return 0; }
static int daq700_auto_attach(struct comedi_device *dev, unsigned long context) { struct pcmcia_device *link = comedi_to_pcmcia_dev(dev); struct comedi_subdevice *s; int ret; dev->board_name = dev->driver->driver_name; link->config_flags |= CONF_AUTO_SET_IO; ret = comedi_pcmcia_enable(dev, NULL); if (ret) return ret; dev->iobase = link->resource[0]->start; ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; /* DAQCard-700 dio */ s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 16; s->range_table = &range_digital; s->maxdata = 1; s->insn_bits = daq700_dio_insn_bits; s->insn_config = daq700_dio_insn_config; s->state = 0; s->io_bits = 0x00ff; /* DAQCard-700 ai */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AI; /* we support single-ended (ground) */ s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = 16; s->maxdata = (1 << 12) - 1; s->range_table = &range_bipolar10; s->insn_read = daq700_ai_rinsn; daq700_ai_config(dev, s); dev_info(dev->class_dev, "%s: %s, io 0x%lx\n", dev->driver->driver_name, dev->board_name, dev->iobase); return 0; }
static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; printk("comedi%d: contec: ", dev->minor); dev->board_name = thisboard->name; ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; pcidev = contec_find_pci_dev(dev, it); if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); if (comedi_pci_enable(pcidev, "contec_pci_dio")) { printk("error enabling PCI device and request regions!\n"); return -EIO; } dev->iobase = pci_resource_start(pcidev, 0); printk(" base addr %lx ", dev->iobase); 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_bits = contec_di_insn_bits; s = dev->subdevices + 1; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = contec_do_insn_bits; printk("attached\n"); return 1; }
static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl724_board *board = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase; unsigned int iorange; int n_subdevices; int ret; int i; iorange = board->io_range; n_subdevices = board->numofports; /* Handle PCL-724 in 96 DIO configuration */ if (board->can_have96 && (it->options[2] == 1 || it->options[2] == 96)) { iorange = 0x10; n_subdevices = 4; } ret = comedi_request_region(dev, it->options[0], iorange); if (ret) return ret; ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret) return ret; for (i = 0; i < dev->n_subdevices; i++) { s = &dev->subdevices[i]; if (board->is_pet48) { iobase = dev->iobase + (i * 0x1000); ret = subdev_8255_init(dev, s, pcl724_8255mapped_io, iobase); } else { iobase = dev->iobase + (i * SIZE_8255); ret = subdev_8255_init(dev, s, NULL, iobase); } if (ret) return ret; } return 0; }
static int pci1720_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret; ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 2); ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; /* Analog Output subdevice */ s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 0x0fff; s->range_table = &pci1720_ao_range; s->insn_write = pci1720_ao_insn_write; ret = comedi_alloc_subdev_readback(s); if (ret) return ret; /* Digital Input subdevice (BoardID SW1) */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 4; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = pci1720_di_insn_bits; /* disable synchronized output, channels update when written */ outb(0, dev->iobase + PCI1720_SYNC_CTRL_REG); return 0; }
static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; unsigned long iobase; int ret; iobase = it->options[0]; printk(KERN_INFO "comedi%d: pcl725: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, PCL725_SIZE, "pcl725")) { printk("I/O port conflict\n"); return -EIO; } dev->board_name = "pcl725"; dev->iobase = iobase; dev->irq = 0; ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; s = dev->subdevices + 0; /* do */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->maxdata = 1; s->n_chan = 8; s->insn_bits = pcl725_do_insn; s->range_table = &range_digital; s = dev->subdevices + 1; /* di */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->maxdata = 1; s->n_chan = 8; s->insn_bits = pcl725_di_insn; s->range_table = &range_digital; printk(KERN_INFO "\n"); return 0; }
int amplc_pc236_common_attach(struct comedi_device *dev, unsigned long iobase, unsigned int irq, unsigned long req_irq_flags) { struct comedi_subdevice *s; int ret; dev->iobase = iobase; ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; s = &dev->subdevices[0]; /* digital i/o subdevice (8255) */ ret = subdev_8255_init(dev, s, NULL, 0x00); if (ret) return ret; s = &dev->subdevices[1]; dev->read_subdev = s; s->type = COMEDI_SUBD_UNUSED; pc236_intr_update(dev, false); if (irq) { if (request_irq(irq, pc236_interrupt, req_irq_flags, dev->board_name, dev) >= 0) { dev->irq = irq; 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_bits = pc236_intr_insn; s->len_chanlist = 1; s->do_cmdtest = pc236_intr_cmdtest; s->do_cmd = pc236_intr_cmd; s->cancel = pc236_intr_cancel; } } return 0; }
static int dio24_auto_attach(struct comedi_device *dev, unsigned long context) { struct pcmcia_device *link = comedi_to_pcmcia_dev(dev); struct comedi_subdevice *s; int ret; link->config_flags |= CONF_AUTO_SET_IO; ret = comedi_pcmcia_enable(dev, NULL); if (ret) return ret; dev->iobase = link->resource[0]->start; ret = comedi_alloc_subdevices(dev, 1); if (ret) return ret; /* 8255 dio */ s = &dev->subdevices[0]; return subdev_8255_init(dev, s, NULL, 0x00); }
static int ke_counter_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret; ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 0); ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; s = &dev->subdevices[0]; s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE; s->n_chan = 3; s->maxdata = 0x01ffffff; s->range_table = &range_unknown; s->insn_read = ke_counter_insn_read; s->insn_write = ke_counter_insn_write; s->insn_config = ke_counter_insn_config; s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 3; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = ke_counter_do_insn_bits; outb(KE_OSC_SEL_20MHZ, dev->iobase + KE_OSC_SEL_REG); ke_counter_reset(dev); return 0; }
static int daq700_auto_attach(struct comedi_device *dev, unsigned long context) { struct pcmcia_device *link = comedi_to_pcmcia_dev(dev); struct comedi_subdevice *s; int ret; link->config_flags |= CONF_AUTO_SET_IO; ret = comedi_pcmcia_enable(dev, NULL); if (ret) return ret; dev->iobase = link->resource[0]->start; ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; /* DAQCard-700 dio */ s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 16; s->range_table = &range_digital; s->maxdata = 1; s->insn_bits = daq700_dio_insn_bits; s->insn_config = daq700_dio_insn_config; s->io_bits = 0x00ff; /* DAQCard-700 ai */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; s->n_chan = 16; s->maxdata = (1 << 12) - 1; s->range_table = &range_daq700_ai; s->insn_read = daq700_ai_rinsn; daq700_ai_config(dev, s); return 0; }
static int cb_pcimdda_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret; ret = comedi_pci_enable(dev); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 3); ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; s = &dev->subdevices[0]; /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = 6; s->maxdata = 0xffff; s->range_table = &range_bipolar5; s->insn_write = cb_pcimdda_ao_insn_write; s->insn_read = cb_pcimdda_ao_insn_read; ret = comedi_alloc_subdev_readback(s); if (ret) return ret; s = &dev->subdevices[1]; /* digital i/o subdevice */ ret = subdev_8255_init(dev, s, NULL, PCIMDDA_8255_BASE_REG); if (ret) return ret; return 0; }
static int contec_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret; dev->board_name = dev->driver->driver_name; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 0); ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; 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_bits = contec_di_insn_bits; s = &dev->subdevices[1]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = contec_do_insn_bits; dev_info(dev->class_dev, "%s attached\n", dev->board_name); return 0; }
static int dac02_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; int ret; ret = comedi_request_region(dev, it->options[0], 0x08); if (ret) return ret; ret = comedi_alloc_subdevices(dev, 1); if (ret) return ret; /* Analog Output subdevice */ s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = 0x0fff; s->range_table = &das02_ao_ranges; s->insn_write = dac02_ao_insn_write; return comedi_alloc_subdev_readback(s); }
static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; int ret; ret = comedi_request_region(dev, it->options[0], 0x10); if (ret) return ret; ret = dmm32at_reset(dev); if (ret) { dev_err(dev->class_dev, "board detection failed\n"); return ret; } if (it->options[1]) { ret = request_irq(it->options[1], dmm32at_isr, 0, dev->board_name, dev); if (ret == 0) dev->irq = it->options[1]; } ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; /* Analog Input subdevice */ s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; s->n_chan = 32; s->maxdata = 0xffff; s->range_table = &dmm32at_airanges; s->insn_read = dmm32at_ai_insn_read; if (dev->irq) { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; s->len_chanlist = s->n_chan; s->do_cmd = dmm32at_ai_cmd; s->do_cmdtest = dmm32at_ai_cmdtest; s->cancel = dmm32at_ai_cancel; } /* Analog Output subdevice */ s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 4; s->maxdata = 0x0fff; s->range_table = &dmm32at_aoranges; s->insn_write = dmm32at_ao_insn_write; ret = comedi_alloc_subdev_readback(s); if (ret) return ret; /* Digital I/O subdevice */ s = &dev->subdevices[2]; return subdev_8255_init(dev, s, dmm32at_8255_io, DMM32AT_8255_IOBASE); }
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 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; }
/* 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, irq; */ /* unsigned long irqs; */ /* long flags; */ const struct dt2811_board *board = comedi_board(dev); int ret; struct comedi_subdevice *s; unsigned long iobase; iobase = it->options[0]; printk(KERN_INFO "comedi%d: dt2811:base=0x%04lx\n", dev->minor, iobase); if (!request_region(iobase, DT2811_SIZE, driver_name)) { printk(KERN_ERR "I/O port conflict\n"); return -EIO; } dev->iobase = iobase; dev->board_name = board->name; #if 0 outb(0, dev->iobase + DT2811_ADCSR); udelay(100); i = inb(dev->iobase + DT2811_ADDATLO); i = inb(dev->iobase + DT2811_ADDATHI); #endif #if 0 irq = it->options[1]; if (irq < 0) { save_flags(flags); sti(); irqs = probe_irq_on(); outb(DT2811_CLRERROR | DT2811_INTENB, dev->iobase + DT2811_ADCSR); outb(0, dev->iobase + DT2811_ADGCR); udelay(100); irq = probe_irq_off(irqs); restore_flags(flags); /*outb(DT2811_CLRERROR|DT2811_INTENB, dev->iobase+DT2811_ADCSR);*/ if (inb(dev->iobase + DT2811_ADCSR) & DT2811_ADERROR) printk(KERN_ERR "error probing irq (bad)\n"); dev->irq = 0; if (irq > 0) { i = inb(dev->iobase + DT2811_ADDATLO); i = inb(dev->iobase + DT2811_ADDATHI); printk(KERN_INFO "(irq = %d)\n", irq); ret = request_irq(irq, dt2811_interrupt, 0, driver_name, dev); if (ret < 0) return -EIO; dev->irq = irq; } else if (irq == 0) { printk(KERN_INFO "(no irq)\n"); } else { printk(KERN_ERR "( multiple irq's -- this is bad! )\n"); } } #endif ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; ret = alloc_private(dev, sizeof(struct dt2811_private)); if (ret < 0) return ret; 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->insn_write = dt2811_ao_insn; s->insn_read = dt2811_ao_insn_read; 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 = &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; }
static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) { unsigned long iobase; int ret; /* pointer to the subdevice: Analog in, Analog out, (not made ->and Digital IO) */ struct comedi_subdevice *s; iobase = it->options[0]; printk(KERN_INFO "comedi:%d fl512: 0x%04lx", dev->minor, iobase); if (!request_region(iobase, FL512_SIZE, "fl512")) { printk(KERN_WARNING " I/O port conflict\n"); return -EIO; } dev->iobase = iobase; dev->board_name = "fl512"; if (alloc_private(dev, sizeof(struct fl512_private)) < 0) return -ENOMEM; #if DEBUG printk(KERN_DEBUG "malloc ok\n"); #endif 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; printk(KERN_INFO "comedi: fl512: subdevice 0 initialized\n"); /* 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; printk(KERN_INFO "comedi: fl512: subdevice 1 initialized\n"); return 1; }
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 multiq3_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int result = 0; unsigned long iobase; unsigned int irq; struct comedi_subdevice *s; iobase = it->options[0]; printk(KERN_INFO "comedi%d: multiq3: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, MULTIQ3_SIZE, "multiq3")) { printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor); return -EIO; } dev->iobase = iobase; irq = it->options[1]; if (irq) printk(KERN_WARNING "comedi%d: irq = %u ignored\n", dev->minor, irq); else printk(KERN_WARNING "comedi%d: no irq\n", dev->minor); dev->board_name = "multiq3"; result = comedi_alloc_subdevices(dev, 5); if (result) return result; result = alloc_private(dev, sizeof(struct multiq3_private)); if (result < 0) return result; 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 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 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; }