static int dmm32at_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { int ret; int i; dmm32at_ai_set_chanspec(dev, s, insn->chanspec, 1); /* wait for circuit to settle */ ret = comedi_timeout(dev, s, insn, dmm32at_ai_status, DMM32AT_AI_READBACK_REG); if (ret) return ret; for (i = 0; i < insn->n; i++) { outb(0xff, dev->iobase + DMM32AT_AI_START_CONV_REG); ret = comedi_timeout(dev, s, insn, dmm32at_ai_status, DMM32AT_AI_STATUS_REG); if (ret) return ret; data[i] = dmm32at_ai_get_sample(dev, s); } return insn->n; }
static int multiq3_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { int n; int chan; unsigned int hi, lo; int ret; chan = CR_CHAN(insn->chanspec); outw(MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3), dev->iobase + MULTIQ3_CONTROL); ret = comedi_timeout(dev, s, insn, multiq3_ai_status, MULTIQ3_STATUS_EOC); if (ret) return ret; for (n = 0; n < insn->n; n++) { outw(0, dev->iobase + MULTIQ3_AD_CS); ret = comedi_timeout(dev, s, insn, multiq3_ai_status, MULTIQ3_STATUS_EOC_I); if (ret) return ret; hi = inb(dev->iobase + MULTIQ3_AD_CS); lo = inb(dev->iobase + MULTIQ3_AD_CS); data[n] = (((hi << 8) | lo) + 0x1000) & 0x1fff; } return n; }
static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { struct dt2815_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); unsigned int lo, hi; int ret; for (i = 0; i < insn->n; i++) { lo = ((data[i] & 0x0f) << 4) | (chan << 1) | 0x01; hi = (data[i] & 0xff0) >> 4; ret = comedi_timeout(dev, s, insn, dt2815_ao_status, 0x00); if (ret) return ret; outb(lo, dev->iobase + DT2815_DATA); ret = comedi_timeout(dev, s, insn, dt2815_ao_status, 0x10); if (ret) return ret; devpriv->ao_readback[chan] = data[i]; } return i; }
static int dmm32at_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { unsigned int chan = CR_CHAN(insn->chanspec); int i; for (i = 0; i < insn->n; i++) { unsigned int val = data[i]; int ret; /* write LSB then MSB + chan to load DAC */ outb(val & 0xff, dev->iobase + DMM32AT_AO_LSB_REG); outb((val >> 8) | DMM32AT_AO_MSB_DACH(chan), dev->iobase + DMM32AT_AO_MSB_REG); /* wait for circuit to settle */ ret = comedi_timeout(dev, s, insn, dmm32at_ao_eoc, 0); if (ret) return ret; /* dummy read to update DAC */ inb(dev->iobase + DMM32AT_AO_MSB_REG); s->readback[chan] = val; } return insn->n; }
static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { struct comedi_cmd *cmd = &s->async->cmd; int ret; dmm32at_ai_set_chanspec(dev, s, cmd->chanlist[0], cmd->chanlist_len); /* reset the interrupt just in case */ outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG); /* * wait for circuit to settle * we don't have the 'insn' here but it's not needed */ ret = comedi_timeout(dev, s, NULL, dmm32at_ai_status, DMM32AT_AI_READBACK_REG); if (ret) return ret; if (cmd->stop_src == TRIG_NONE || cmd->stop_arg > 1) { /* start the clock and enable the interrupts */ dmm32at_setaitimer(dev, cmd->scan_begin_arg); } else { /* start the interrupts and initiate a single scan */ outb(DMM32AT_INTCLK_ADINT, dev->iobase + DMM32AT_INTCLK_REG); outb(0xff, dev->iobase + DMM32AT_AI_START_CONV_REG); } return 0; }
static int pci6208_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { unsigned int chan = CR_CHAN(insn->chanspec); unsigned int val = s->readback[chan]; int ret; int i; for (i = 0; i < insn->n; i++) { val = data[i]; /* D/A transfer rate is 2.2us */ ret = comedi_timeout(dev, s, insn, pci6208_ao_eoc, 0); if (ret) return ret; /* the hardware expects two's complement values */ outw(comedi_offset_munge(s, val), dev->iobase + PCI6208_AO_CONTROL(chan)); s->readback[chan] = val; } return insn->n; }
static int daq700_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { int n; int d; int ret; unsigned int chan = CR_CHAN(insn->chanspec); unsigned int aref = CR_AREF(insn->chanspec); unsigned int range = CR_RANGE(insn->chanspec); unsigned int r3_bits = 0; /* set channel input modes */ if (aref == AREF_DIFF) r3_bits |= CMD_R3_DIFF; /* write channel mode/range */ if (range >= 1) range++; /* convert range to hardware value */ outb(r3_bits | (range & 0x03), dev->iobase + CMD_R3); /* write channel to multiplexer */ /* set mask scan bit high to disable scanning */ outb(chan | 0x80, dev->iobase + CMD_R1); /* mux needs 2us to really settle [Fred Brooks]. */ udelay(2); /* convert n samples */ for (n = 0; n < insn->n; n++) { /* trigger conversion with out0 L to H */ outb(0x00, dev->iobase + CMD_R2); /* enable ADC conversions */ outb(0x30, dev->iobase + CMO_R); /* mode 0 out0 L, from H */ outb(0x00, dev->iobase + ADCLEAR_R); /* clear the ADC FIFO */ /* read 16bit junk from FIFO to clear */ inw(dev->iobase + ADFIFO_R); /* mode 1 out0 H, L to H, start conversion */ outb(0x32, dev->iobase + CMO_R); /* wait for conversion to end */ ret = comedi_timeout(dev, s, insn, daq700_ai_eoc, 0); if (ret) return ret; /* read data */ d = inw(dev->iobase + ADFIFO_R); /* mangle the data as necessary */ /* Bipolar Offset Binary: 0 to 4095 for -10 to +10 */ d &= 0x0fff; d ^= 0x0800; data[n] = d; } return n; }
static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { const struct das08_board_struct *thisboard = comedi_board(dev); struct das08_private_struct *devpriv = dev->private; int n; int chan; int range; int lsb, msb; int ret; chan = CR_CHAN(insn->chanspec); range = CR_RANGE(insn->chanspec); /* clear crap */ inb(dev->iobase + DAS08_LSB); inb(dev->iobase + DAS08_MSB); /* set multiplexer */ /* lock to prevent race with digital output */ spin_lock(&dev->spinlock); devpriv->do_mux_bits &= ~DAS08_MUX_MASK; devpriv->do_mux_bits |= DAS08_MUX(chan); outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL); spin_unlock(&dev->spinlock); if (s->range_table->length > 1) { /* set gain/range */ range = CR_RANGE(insn->chanspec); outb(devpriv->pg_gainlist[range], dev->iobase + DAS08AO_GAIN_CONTROL); } for (n = 0; n < insn->n; n++) { /* clear over-range bits for 16-bit boards */ if (thisboard->ai_nbits == 16) if (inb(dev->iobase + DAS08_MSB) & 0x80) dev_info(dev->class_dev, "over-range\n"); /* trigger conversion */ outb_p(0, dev->iobase + DAS08_TRIG_12BIT); ret = comedi_timeout(dev, s, insn, das08_ai_eoc, 0); if (ret) return ret; msb = inb(dev->iobase + DAS08_MSB); lsb = inb(dev->iobase + DAS08_LSB); if (thisboard->ai_encoding == das08_encode12) { data[n] = (lsb >> 4) | (msb << 4); } else if (thisboard->ai_encoding == das08_pcm_encode12) {
static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { int chan = CR_CHAN(insn->chanspec); int ret; int i; for (i = 0; i < insn->n; i++) { outb(chan, dev->iobase + DT2811_ADGCR); ret = comedi_timeout(dev, s, insn, dt2811_ai_eoc, 0); if (ret) return ret; data[i] = inb(dev->iobase + DT2811_ADDATLO); data[i] |= inb(dev->iobase + DT2811_ADDATHI) << 8; data[i] &= 0xfff; } return i; }
static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { struct dyna_pci10xx_private *devpriv = dev->private; int n; u16 d = 0; int ret = 0; unsigned int chan, range; /* get the channel number and range */ chan = CR_CHAN(insn->chanspec); range = range_codes_pci1050_ai[CR_RANGE((insn->chanspec))]; mutex_lock(&devpriv->mutex); /* convert n samples */ for (n = 0; n < insn->n; n++) { /* trigger conversion */ smp_mb(); outw_p(0x0000 + range + chan, dev->iobase + 2); udelay(10); ret = comedi_timeout(dev, s, insn, dyna_pci10xx_ai_eoc, 0); if (ret) break; /* read data */ d = inw_p(dev->iobase); /* mask the first 4 bits - EOC bits */ d &= 0x0FFF; data[n] = d; } mutex_unlock(&devpriv->mutex); /* return the number of samples read/written */ return ret ? ret : n; }
static int daq700_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { int n, chan; int d; int ret; chan = CR_CHAN(insn->chanspec); /* write channel to multiplexer */ /* set mask scan bit high to disable scanning */ outb(chan | 0x80, dev->iobase + CMD_R1); /* convert n samples */ for (n = 0; n < insn->n; n++) { /* trigger conversion with out0 L to H */ outb(0x00, dev->iobase + CMD_R2); /* enable ADC conversions */ outb(0x30, dev->iobase + CMO_R); /* mode 0 out0 L, from H */ /* mode 1 out0 H, L to H, start conversion */ outb(0x32, dev->iobase + CMO_R); /* wait for conversion to end */ ret = comedi_timeout(dev, s, insn, daq700_ai_eoc, 0); if (ret) return ret; /* read data */ d = inw(dev->iobase + ADFIFO_R); /* mangle the data as necessary */ /* Bipolar Offset Binary: 0 to 4095 for -10 to +10 */ d &= 0x0fff; d ^= 0x0800; data[n] = d; } return n; }