of the drivers were converted to insn.
s->range_table=&range_digital;
s->maxdata=1;
- /* XXX This causes a memory leak */
s->private=kmalloc(sizeof(struct subdev_8255_struct),GFP_KERNEL);
if(!s->private)return -ENOMEM;
s->state=0;
s->io_bits=0;
do_config(dev,s);
-
return 0;
}
+void subdev_8255_cleanup(comedi_device *dev,comedi_subdevice *s)
+{
+ if(s->private)
+ kfree(s->private);
+}
/*
iobase=(int)CALLBACK_ARG;
release_region(iobase,_8255_SIZE);
}
+ subdev_8255_cleanup(dev,s);
}
return 0;
#include <linux/comedidev.h>
-#ifdef CONFIG_COMEDI_8255
-
-int subdev_8255_init(comedi_device *dev,comedi_subdevice *s,int (*cb)(int,int,int,void *),void *arg);
-
-#else
-
-#ifdef CONFIG_COMEDI_8255_MODULE
+#if defined(CONFIG_COMEDI_8255) || defined(CONFIG_COMEDI_8255_MODULE)
int subdev_8255_init(comedi_device *dev,comedi_subdevice *s,int (*cb)(int,int,int,void *),void *arg);
+void subdev_8255_cleanup(comedi_device *dev,comedi_subdevice *s);
#else
return 0;
}
-#endif
+static inline void subdev_8255_cleanup(comedi_device *dev,comedi_subdevice *s){}
#endif
return -EIO;
}
- dev->iobase=iobase_9;
- request_region(dev->iobase, this_board->iorange_9118, "ADLink PCI-9118");
+ request_region(iobase_9, this_board->iorange_9118, "ADLink PCI-9118");
+ dev->iobase=iobase_9;
dev->board_name = this_board->name;
if((ret=alloc_private(dev,sizeof(pci9118_private)))<0)
devpriv->amcc=card;
devpriv->master=master;
+ request_region(iobase_a, this_board->iorange_amcc, "ADLink PCI-9118");
devpriv->iobase_a=iobase_a;
- request_region(devpriv->iobase_a, this_board->iorange_amcc, "ADLink PCI-9118");
if (irq>0) {
if (comedi_request_irq(irq, interrupt_pci9118, SA_SHIRQ, "ADLink PCI-9118", dev)) {
tmp=cmd->start_src;
cmd->start_src &= TRIG_NOW;
- if(!cmd->start_src && tmp!=cmd->start_src)err++;
+ if(!cmd->start_src || tmp!=cmd->start_src)err++;
tmp=cmd->scan_begin_src;
cmd->scan_begin_src &= TRIG_EXT;
- if(!cmd->scan_begin_src && tmp!=cmd->scan_begin_src)err++;
+ if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
tmp=cmd->convert_src;
cmd->convert_src &= TRIG_FOLLOW;
- if(!cmd->convert_src && tmp!=cmd->convert_src)err++;
+ if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
tmp=cmd->scan_end_src;
cmd->scan_end_src &= TRIG_COUNT;
- if(!cmd->scan_end_src && tmp!=cmd->scan_end_src)err++;
+ if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
tmp=cmd->stop_src;
cmd->stop_src &= TRIG_NONE;
- if(!cmd->stop_src && tmp!=cmd->stop_src)err++;
+ if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
if(err)return 1;
static int timer_attach(comedi_device *dev,comedi_devconfig *it);
static int timer_detach(comedi_device *dev);
-static comedi_driver driver_timer={
+comedi_driver driver_timer={
module: THIS_MODULE,
driver_name: "comedi_rt_timer",
attach: timer_attach,
comedi_error(dev, "failed to obtain lock");
return ret;
}
-#ifdef CONFIG_COMEDI_RTAI
- start_rt_timer(1);
-#endif
delay = nano2count(cmd->start_arg);
if(cmd->scan_begin_src == TRIG_TIMER)
period = nano2count(cmd->scan_begin_arg);
comedi_error(dev, "bug!");
return -1;
}
+#ifdef CONFIG_COMEDI_RTAI
+ start_rt_timer(period);
+#endif
if(s == dev->read_subdev)
ret = rt_task_init(&devpriv->rt_task,timer_ai_task_func,(int)dev,3000,0,0,0);
else
-static void daqboard2000_release_resources(comedi_device * dev);
static int daqboard2000_attach(comedi_device *dev,comedi_devconfig *it);
static int daqboard2000_detach(comedi_device *dev);
} card;
void *daq;
void *plx;
+ lsampl_t ao_readback[2];
} daqboard2000_private;
#define devpriv ((daqboard2000_private*)dev->private)
}
-static int daqboard2000_ai(comedi_device *dev, comedi_subdevice *s,
- comedi_trig *it)
+static int daqboard2000_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
+ comedi_insn *insn, lsampl_t *data)
{
int i;
daqboard2000_hw *fpga = devpriv->daq;
+ int gain, chan, timeout;
fpga->acqControl = DAQBOARD2000_AcqResetScanListFifo;
- fpga->acqControl = DAQBOARD2000_AcqResetResultsFifo | DAQBOARD2000_AcqResetConfigPipe;
- for(i=0 ; i < it->n_chan ; i++) {
- int gain, chan, timeout;
+ fpga->acqControl = DAQBOARD2000_AcqResetResultsFifo | DAQBOARD2000_AcqResetConfigPipe;
- gain = CR_RANGE(it->chanlist[i]);
- chan = CR_CHAN(it->chanlist[i]);
+ gain = CR_RANGE(insn->chanspec);
+ chan = CR_CHAN(insn->chanspec);
+
+ /* This doesn't look efficient. I decided to take the conservative
+ * approach when I did the insn conversion. Perhaps it would be
+ * better to have broken it completely, then someone would have been
+ * forced to fix it. --ds */
+ for(i=0;i<insn->n;i++){
setup_sampling(dev, chan, gain);
fpga->acqControl = DAQBOARD2000_SeqStartScanList;
for (timeout = 0 ; timeout < 20 ; timeout++) {
if (fpga->acqControl & DAQBOARD2000_AcqConfigPipeFull) { break; }
- udelay(2);
+ //udelay(2);
}
fpga->acqControl = DAQBOARD2000_AdcPacerEnable;
for (timeout = 0 ; timeout < 20 ; timeout++) {
if (fpga->acqControl & DAQBOARD2000_AcqLogicScanning) { break; }
- udelay(2);
+ //udelay(2);
}
for (timeout = 0 ; timeout < 20 ; timeout++) {
if (fpga->acqControl & DAQBOARD2000_AcqResultsFIFOHasValidData) { break;}
- udelay(2);
+ //udelay(2);
}
- it->data[i] = fpga->acqResultsFIFO;
+ data[i] = fpga->acqResultsFIFO;
fpga->acqControl = DAQBOARD2000_AdcPacerDisable;
fpga->acqControl = DAQBOARD2000_SeqStopScanList;
}
return i;
}
-static int daqboard2000_ao(comedi_device *dev, comedi_subdevice *s,
- comedi_trig *it)
+
+static int daqboard2000_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
+ comedi_insn *insn, lsampl_t *data)
{
int i;
- daqboard2000_hw *fpga = devpriv->daq;
+ int chan = CR_CHAN(insn->chanspec);
- for(i=0 ; i < it->n_chan ; i++) {
- int chan, data, timeout;
+ for(i=0;i<insn->n;i++){
+ data[i]=devpriv->ao_readback[chan];
+ }
- chan = CR_CHAN(it->chanlist[i]);
- data = it->data[i];
-/*
- OK, since it works OK without enabling the DAC's, let's keep
- it as simple as possible...
- fpga->dacControl = (chan + 2) * 0x0010 | 0x0001; udelay(1000);
-*/
- fpga->dacSetting[chan] = data;
+ return i;
+}
+
+static int daqboard2000_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
+ comedi_insn *insn, lsampl_t *data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ daqboard2000_hw *fpga = devpriv->daq;
+ int timeout;
+
+ for(i=0;i<insn->n;i++){
+ /*
+ * OK, since it works OK without enabling the DAC's, let's keep
+ * it as simple as possible...
+ */
+ //fpga->dacControl = (chan + 2) * 0x0010 | 0x0001; udelay(1000);
+ fpga->dacSetting[chan] = data[i];
for (timeout = 0 ; timeout < 20 ; timeout++) {
if ((fpga->dacControl & ((chan + 1) * 0x0010)) == 0) { break; }
- udelay(2);
+ //udelay(2);
}
-/*
- Since we never enabled the DAC's, we don't need to disable it...
- fpga->dacControl = (chan + 2) * 0x0010 | 0x0000; udelay(1000);
-*/
-
+ devpriv->ao_readback[chan] = data[i];
+ /*
+ * Since we never enabled the DAC's, we don't need to disable it...
+ * fpga->dacControl = (chan + 2) * 0x0010 | 0x0000; udelay(1000);
+ */
}
+
return i;
}
s->subdev_flags = SDF_READABLE|SDF_RT;
s->n_chan = 24;
s->maxdata = 0xffff;
- s->trig[0] = daqboard2000_ai;
+ s->insn_read = daqboard2000_ai_insn_read;
s->range_table = &range_daqboard2000_ai;
s = dev->subdevices + 1;
s->subdev_flags = SDF_WRITEABLE|SDF_RT;
s->n_chan = 2;
s->maxdata = 0xffff;
- s->trig[0] = daqboard2000_ao;
+ s->insn_read = daqboard2000_ao_insn_read;
+ s->insn_write = daqboard2000_ao_insn_write;
s->range_table = &range_daqboard2000_ao;
s = dev->subdevices + 2;
return result;
}
-static void daqboard2000_release_resources(comedi_device * dev)
+static int daqboard2000_detach(comedi_device * dev)
{
+ printk("comedi%d: daqboard2000: remove\n", dev->minor);
+
+ if(dev->subdevices)
+ subdev_8255_cleanup(dev,dev->subdevices+2);
+
if (devpriv && devpriv->daq) {
iounmap(devpriv->daq);
}
if (dev->irq) {
free_irq(dev->irq, dev);
}
-}
-
-static int daqboard2000_detach(comedi_device * dev)
-{
- printk("comedi%d: daqboard2000: remove\n", dev->minor);
- daqboard2000_release_resources(dev);
return 0;
}
{
comedi_subdevice *s;
int ret;
+ int iobase;
- dev->iobase=it->options[0];
- printk("comedi%d: das08: 0x%04x",dev->minor,dev->iobase);
- if(check_region(dev->iobase,DAS08_SIZE)<0){
+ iobase=it->options[0];
+ printk("comedi%d: das08: 0x%04x",dev->minor,iobase);
+ if(check_region(iobase,DAS08_SIZE)<0){
printk(" I/O port conflict\n");
return -EIO;
}
if((ret=alloc_private(dev,sizeof(struct das08_private_struct)))<0)
return ret;
- request_region(dev->iobase,DAS08_SIZE,"das08");
+ request_region(iobase,DAS08_SIZE,"das08");
+ dev->iobase = iobase;
s=dev->subdevices+0;
/* ai */
{
printk(KERN_INFO "comedi%d: das08: remove\n",dev->minor);
- release_region(dev->iobase,DAS08_SIZE);
+ if(dev->subdevices)
+ subdev_8255_cleanup(dev,dev->subdevices+4);
+
+ if(dev->iobase)
+ release_region(dev->iobase,DAS08_SIZE);
return 0;
}
/* make sure triggers are valid */
tmp=cmd->start_src;
cmd->start_src &= TRIG_NOW;
- if(!cmd->start_src && tmp!=cmd->start_src)err++;
+ if(!cmd->start_src || tmp!=cmd->start_src)err++;
tmp=cmd->scan_begin_src;
cmd->scan_begin_src &= TRIG_FOLLOW|TRIG_TIMER;
- if(!cmd->scan_begin_src && tmp!=cmd->scan_begin_src)err++;
+ if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
/* XXX This must be TRIG_FOLLOW until I figure out a way to *
* time the individual conversions. */
tmp=cmd->convert_src;
//cmd->convert_src &= TRIG_TIMER;
cmd->convert_src &= TRIG_FOLLOW;
- if(!cmd->convert_src && tmp!=cmd->convert_src)err++;
+ if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
tmp=cmd->scan_end_src;
cmd->scan_end_src &= TRIG_COUNT;
- if(!cmd->scan_end_src && tmp!=cmd->scan_end_src)err++;
+ if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
tmp=cmd->stop_src;
cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
- if(!cmd->stop_src && tmp!=cmd->stop_src)err++;
+ if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
if(err)return 1;
{
comedi_subdevice *s;
int ret, irq;
+ int iobase;
- dev->iobase = it->options[0];
+ iobase = it->options[0];
printk("comedi%d: das16:",dev->minor);
dev->board_name = thisboard->name;
if(thisboard->size<0x400){
- printk(" 0x%04x-0x%04x\n",
- dev->iobase,dev->iobase+thisboard->size);
- if(check_region(dev->iobase,thisboard->size)<0){
+ printk(" 0x%04x-0x%04x\n", iobase, iobase+thisboard->size);
+ if(check_region(iobase,thisboard->size)<0){
printk(" I/O port conflict\n");
return -EIO;
}
}else{
printk(" 0x%04x-0x%04x 0x%04x-0x%04x\n",
- dev->iobase,dev->iobase+0x0f,
- dev->iobase+0x400,dev->iobase+0x400+(thisboard->size&0x3ff));
- if(check_region(dev->iobase,0x10) < 0) {
+ iobase,iobase+0x0f,
+ iobase+0x400,iobase+0x400+(thisboard->size&0x3ff));
+ if(check_region(iobase,0x10) < 0) {
printk(" I/O port conflict: 0x%04x-0x%04x\n",
- dev->iobase,dev->iobase+0x0f);
+ iobase,iobase+0x0f);
return -EIO;
}
- if(check_region(dev->iobase+0x400,thisboard->size&0x3ff)<0){
+ if(check_region(iobase+0x400,thisboard->size&0x3ff)<0){
printk(" I/O port conflict: 0x%04x-0x%04x\n",
- dev->iobase+0x400,
- dev->iobase+0x400+(thisboard->size&0x3ff));
+ iobase+0x400,
+ iobase+0x400+(thisboard->size&0x3ff));
return -EIO;
}
}
return ret;
if(thisboard->size<0x400){
- request_region(dev->iobase,thisboard->size,"das16");
+ request_region(iobase,thisboard->size,"das16");
}else{
- request_region(dev->iobase,0x10,"das16");
- request_region(dev->iobase+0x400,thisboard->size&0x3ff,"das16");
+ request_region(iobase,0x10,"das16");
+ request_region(iobase+0x400,thisboard->size&0x3ff,"das16");
}
+ dev->iobase = iobase;
+
/* now for the irq */
irq=it->options[1];
if(irq>0){
das16_reset(dev);
+ if(dev->subdevices)
+ subdev_8255_cleanup(dev,dev->subdevices+4);
+
if(dev->irq)
free_irq(dev->irq, dev);
tmp = cmd->start_src;
cmd->start_src &= TRIG_NOW | TRIG_EXT;
- if(!cmd->start_src && tmp != cmd->start_src) err++;
+ if(!cmd->start_src || tmp != cmd->start_src) err++;
tmp = cmd->scan_begin_src;
cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
- if(!cmd->scan_begin_src && tmp != cmd->scan_begin_src) err++;
+ if(!cmd->scan_begin_src || tmp != cmd->scan_begin_src) err++;
tmp = cmd->convert_src;
cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
- if(!cmd->convert_src && tmp != cmd->convert_src) err++;
+ if(!cmd->convert_src || tmp != cmd->convert_src) err++;
tmp = cmd->scan_end_src;
cmd->scan_end_src &= TRIG_COUNT;
- if(!cmd->scan_end_src && tmp != cmd->scan_end_src) err++;
+ if(!cmd->scan_end_src || tmp != cmd->scan_end_src) err++;
tmp=cmd->stop_src;
cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
- if(!cmd->stop_src && tmp != cmd->stop_src) err++;
+ if(!cmd->stop_src || tmp != cmd->stop_src) err++;
if(err) return 1;
printk(" I/O port conflict\n");
return -EIO;
}
+ request_region(iobase,DAS6402_SIZE,"das6402");
dev->iobase=iobase;
- request_region(dev->iobase,DAS6402_SIZE,"das6402");
/* should do a probe here */
tmp = cmd->start_src;
cmd->start_src &= TRIG_NOW | TRIG_EXT;
- if(!cmd->start_src && tmp != cmd->start_src) err++;
+ if(!cmd->start_src || tmp != cmd->start_src) err++;
tmp = cmd->scan_begin_src;
cmd->scan_begin_src &= TRIG_FOLLOW;
- if(!cmd->scan_begin_src && tmp != cmd->scan_begin_src) err++;
+ if(!cmd->scan_begin_src || tmp != cmd->scan_begin_src) err++;
tmp = cmd->convert_src;
cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
- if(!cmd->convert_src && tmp != cmd->convert_src) err++;
+ if(!cmd->convert_src || tmp != cmd->convert_src) err++;
tmp = cmd->scan_end_src;
cmd->scan_end_src &= TRIG_COUNT;
- if(!cmd->scan_end_src && tmp != cmd->scan_end_src) err++;
+ if(!cmd->scan_end_src || tmp != cmd->scan_end_src) err++;
tmp=cmd->stop_src;
cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
- if(!cmd->stop_src && tmp!=cmd->stop_src) err++;
+ if(!cmd->stop_src || tmp!=cmd->stop_src) err++;
if(err) return 1;
tmp=cmd->start_src;
cmd->start_src &= TRIG_NOW;
- if(!cmd->start_src && tmp!=cmd->start_src)err++;
+ if(!cmd->start_src || tmp!=cmd->start_src)err++;
tmp=cmd->scan_begin_src;
cmd->scan_begin_src &= TRIG_TIMER;
- if(!cmd->scan_begin_src && tmp!=cmd->scan_begin_src)err++;
+ if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
tmp=cmd->convert_src;
cmd->convert_src &= TRIG_NOW;
- if(!cmd->convert_src && tmp!=cmd->convert_src)err++;
+ if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
tmp=cmd->scan_end_src;
cmd->scan_end_src &= TRIG_COUNT;
- if(!cmd->scan_end_src && tmp!=cmd->scan_end_src)err++;
+ if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
tmp=cmd->stop_src;
cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
- if(!cmd->stop_src && tmp!=cmd->stop_src)err++;
+ if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
if(err)return 1;
tmp=cmd->start_src;
cmd->start_src &= TRIG_NOW;
- if(!cmd->start_src && tmp!=cmd->start_src)err++;
+ if(!cmd->start_src || tmp!=cmd->start_src)err++;
tmp=cmd->scan_begin_src;
cmd->scan_begin_src &= TRIG_FOLLOW|TRIG_EXT;
- if(!cmd->scan_begin_src && tmp!=cmd->scan_begin_src)err++;
+ if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
tmp=cmd->convert_src;
cmd->convert_src &= TRIG_TIMER;
- if(!cmd->convert_src && tmp!=cmd->convert_src)err++;
+ if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
tmp=cmd->scan_end_src;
cmd->scan_end_src &= TRIG_COUNT;
- if(!cmd->scan_end_src && tmp!=cmd->scan_end_src)err++;
+ if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
tmp=cmd->stop_src;
cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
- if(!cmd->stop_src && tmp!=cmd->stop_src)err++;
+ if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
if(err)return 1;
tmp=cmd->start_src;
cmd->start_src &= TRIG_NOW;
- if(!cmd->start_src && tmp!=cmd->start_src)err++;
+ if(!cmd->start_src || tmp!=cmd->start_src)err++;
tmp=cmd->scan_begin_src;
cmd->scan_begin_src &= TRIG_TIMER;
- if(!cmd->scan_begin_src && tmp!=cmd->scan_begin_src)err++;
+ if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
tmp=cmd->convert_src;
cmd->convert_src &= TRIG_NOW;
- if(!cmd->convert_src && tmp!=cmd->convert_src)err++;
+ if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
tmp=cmd->scan_end_src;
cmd->scan_end_src &= TRIG_COUNT;
- if(!cmd->scan_end_src && tmp!=cmd->scan_end_src)err++;
+ if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
tmp=cmd->stop_src;
//cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
cmd->stop_src &= TRIG_COUNT; /* XXX */
- if(!cmd->stop_src && tmp!=cmd->stop_src)err++;
+ if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
if(err)return 1;
*/
static int fl512_attach(comedi_device *dev,comedi_devconfig *it)
{
+ int iobase;
comedi_subdevice *s; /* pointer to the subdevice:
Analog in, Analog out, ( not made ->and Digital IO) */
- dev->iobase = it->options[0];
- printk("comedi:%d fl512: 0x%04x",dev->minor,dev->iobase);
- if (check_region(dev->iobase, FL512_SIZE) < 0) {
+ iobase = it->options[0];
+ printk("comedi:%d fl512: 0x%04x",dev->minor,iobase);
+ if (check_region(iobase, FL512_SIZE) < 0) {
printk(" I/O port conflict\n");
return -EIO;
}
- request_region(dev->iobase, FL512_SIZE, "fl512");
+ request_region(iobase, FL512_SIZE, "fl512");
+ dev->iobase = iobase;
dev->board_name = "fl512";
dev->n_subdevices = 2; /* Analog in/out */
if(alloc_private(dev,sizeof(fl512_private)) < 0)
detach: multiq3_detach,
};
+struct multiq3_private{
+ lsampl_t ao_readback[2];
+};
+#define devpriv ((struct multiq3_private *)dev->private)
-static int multiq3_ai(comedi_device *dev, comedi_subdevice *s, comedi_trig *it)
+static int multiq3_ai_insn_read(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn, lsampl_t *data)
{
- int i, hi, lo;
- int chan;
- int data;
- int status, control;
+ int i,n;
+ int chan;
+ unsigned int hi, lo;
- chan = CR_CHAN(it->chanlist[0]);
- control = MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan<<3);
- outw(control, dev->iobase+MULTIQ3_CONTROL);
- for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
- status = inw(dev->iobase+MULTIQ3_STATUS);
- if(status & MULTIQ3_STATUS_EOC) {
- break;
- }
- udelay(10);
- }
- if(i == MULTIQ3_TIMEOUT){
- rt_printk("multiq3: timeout\n");
- return -ETIME;
- }
- outw(0, dev->iobase+MULTIQ3_AD_CS);
- for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
- status = inw(dev->iobase+MULTIQ3_STATUS);
- if(status & MULTIQ3_STATUS_EOC_I) {
- break;
- }
- udelay(10);
- }
- hi = inb(dev->iobase + MULTIQ3_AD_CS) &0xff;
- lo = inb(dev->iobase + MULTIQ3_AD_CS) &0xff;
+ chan = CR_CHAN(insn->chanspec);
+ outw(MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan<<3),
+ dev->iobase+MULTIQ3_CONTROL);
+
+ for(i = 0; i < MULTIQ3_TIMEOUT; i++) {
+ if(inw(dev->iobase+MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC)
+ break;
+ }
+ if(i==MULTIQ3_TIMEOUT)return -ETIMEDOUT;
+
+ for(n=0;n<insn->n;n++){
+ outw(0, dev->iobase+MULTIQ3_AD_CS);
+ for(i = 0; i < MULTIQ3_TIMEOUT; i++) {
+ if(inw(dev->iobase+MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC_I)
+ break;
+ }
+ if(i==MULTIQ3_TIMEOUT)return -ETIMEDOUT;
+
+ hi = inb(dev->iobase + MULTIQ3_AD_CS);
+ lo = inb(dev->iobase + MULTIQ3_AD_CS);
+ data[n] = ((hi << 8) | lo) & 0xfff;
+ }
+
+ return i;
+}
- data = (((hi << 8) | lo) + 0x1000) & 0x1fff;
- it->data[0]=data;
+static int multiq3_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
+ comedi_insn *insn, lsampl_t *data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
- return 1;
+ for(i=0;i<insn->n;i++){
+ data[i]=devpriv->ao_readback[chan];
+ }
+
+ return i;
}
-static int multiq3_ao(comedi_device *dev, comedi_subdevice *s, comedi_trig *it)
+static int multiq3_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
+ comedi_insn *insn, lsampl_t *data)
{
- int chan, control;
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
- chan=CR_CHAN(it->chanlist[0]);
- control = MULTIQ3_CONTROL_MUST | MULTIQ3_DA_LOAD | chan;
- outw(control, dev->iobase+MULTIQ3_CONTROL);
- outw(it->data[0], dev->iobase+MULTIQ3_DAC_DATA);
- control = MULTIQ3_CONTROL_MUST;
- outw(control, dev->iobase+MULTIQ3_CONTROL);
- return 1;
+ for(i=0;i<insn->n;i++){
+ outw(MULTIQ3_CONTROL_MUST | MULTIQ3_DA_LOAD | chan,
+ dev->iobase+MULTIQ3_CONTROL);
+ outw(data[i], dev->iobase+MULTIQ3_DAC_DATA);
+ outw(MULTIQ3_CONTROL_MUST, dev->iobase+MULTIQ3_CONTROL);
+
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
}
-static int multiq3_di(comedi_device *dev, comedi_subdevice *s, comedi_trig *it)
+static int multiq3_di_insn_bits(comedi_device *dev, comedi_subdevice *s,
+ comedi_insn *insn, lsampl_t *data)
{
- unsigned int bits;
+ if(insn->n!=2)return -EINVAL;
- bits = inw(dev->iobase + MULTIQ3_DIGIN_PORT);
+ data[1] = inw(dev->iobase + MULTIQ3_DIGIN_PORT);
- return di_unpack(bits,it);
+ return 2;
}
-static int multiq3_do(comedi_device *dev, comedi_subdevice *s, comedi_trig *it)
+static int multiq3_do_insn_bits(comedi_device *dev, comedi_subdevice *s,
+ comedi_insn *insn, lsampl_t *data)
{
- do_pack(&s->state,it);
+ if(insn->n!=2)return -EINVAL;
+ s->state &= ~data[0];
+ s->state |= (data[0]&data[1]);
outw(s->state, dev->iobase + MULTIQ3_DIGOUT_PORT);
- return it->n_chan;
+ return 2;
}
static int multiq3_ei(comedi_device *dev, comedi_subdevice *s, comedi_trig *it)
result = alloc_subdevices(dev);
if(result<0)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;
s->n_chan = 8;
- s->trig[0] = multiq3_ai;
+ s->insn_read = multiq3_ai_insn_read;
s->maxdata = 0x1fff;
s->range_table = &range_bipolar5;
s->type = COMEDI_SUBD_AO;
s->subdev_flags = SDF_WRITEABLE;
s->n_chan = 8;
- s->trig[0] = multiq3_ao;
+ s->insn_read = multiq3_ao_insn_read;
+ s->insn_write = multiq3_ao_insn_write;
s->maxdata = 0xfff;
s->range_table = &range_bipolar5;
s->type = COMEDI_SUBD_DI;
s->subdev_flags = SDF_READABLE;
s->n_chan = 16;
- s->trig[0] = multiq3_di;
+ s->insn_bits = multiq3_di_insn_bits;
s->maxdata = 1;
s->range_table = &range_digital;
s->type = COMEDI_SUBD_DO;
s->subdev_flags = SDF_WRITEABLE;
s->n_chan = 16;
- s->trig[0] = multiq3_do;
+ s->insn_bits = multiq3_do_insn_bits;
s->maxdata = 1;
s->range_table = &range_digital;
s->state = 0;
/* clean up allocated resources */
static int ni_atmio_detach(comedi_device *dev)
{
+ mio_common_detach(dev);
+
#ifdef HAVE_ISAPNP
if(devpriv->pcidev)
devpriv->pcidev->deactivate(devpriv->pcidev);
/* make sure triggers are valid */
tmp=cmd->start_src;
cmd->start_src &= TRIG_NOW;
- if(!cmd->start_src && tmp!=cmd->start_src)err++;
+ if(!cmd->start_src || tmp!=cmd->start_src)err++;
tmp=cmd->scan_begin_src;
cmd->scan_begin_src &= TRIG_FOLLOW|TRIG_TIMER;
- if(!cmd->scan_begin_src && tmp!=cmd->scan_begin_src)err++;
+ if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
tmp=cmd->convert_src;
cmd->convert_src &= TRIG_TIMER;
- if(!cmd->convert_src && tmp!=cmd->convert_src)err++;
+ if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
tmp=cmd->scan_end_src;
cmd->scan_end_src &= TRIG_COUNT;
- if(!cmd->scan_end_src && tmp!=cmd->scan_end_src)err++;
+ if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
tmp=cmd->stop_src;
cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
- if(!cmd->stop_src && tmp!=cmd->stop_src)err++;
+ if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
if(err)return 1;
}
-static int atmio16d_dio(comedi_device * dev, comedi_subdevice *s, comedi_trig * it)
+static int atmio16d_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
+ comedi_insn *insn, lsampl_t *data)
{
- unsigned int data,mask;
- int i;
+ if(insn->n!=2)return -EINVAL;
-#ifdef DEBUG1
- printk("atmio16d_dio\n");
-#endif
+ if(data[0]){
+ s->state &= ~data[0];
+ s->state |= (data[0]|data[1]);
+ outw(s->state, dev->iobase+MIO_16_DIG_OUT_REG );
+ }
+ data[1] = inw(dev->iobase+MIO_16_DIG_IN_REG);
- if(it->flags & TRIG_CONFIG){
- data = s->io_bits;
- for(i=0;i<it->n_chan;i++){
- mask=(CR_CHAN(it->chanlist[i])<4)?0x0f:0xf0;
- data &= ~mask;
- if(it->data[i])
- data |= mask;
- }
- s->io_bits=data;
- devpriv->com_reg_2_state &= ~(COMREG2_DOUTEN0|COMREG2_DOUTEN1);
- if(data&0x0f)
- devpriv->com_reg_2_state |= COMREG2_DOUTEN0;
- if(data&0xf0)
- devpriv->com_reg_2_state |= COMREG2_DOUTEN1;
- }else{
- if(it->flags & TRIG_WRITE){
- do_pack(&s->state,it);
- outw( s->state, dev->iobase+MIO_16_DIG_OUT_REG );
- }else{
- data = inw(dev->iobase+MIO_16_DIG_IN_REG);
- di_unpack(data,it);
- }
+ return 2;
+}
+
+static int atmio16d_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
+ comedi_insn *insn, lsampl_t *data)
+{
+ int i;
+ int mask;
+
+ for(i=0;i<insn->n;i++){
+ mask=(CR_CHAN(insn->chanspec)<4)?0x0f:0xf0;
+ s->io_bits &= ~mask;
+ if(data[i])s->io_bits |= mask;
}
+ devpriv->com_reg_2_state &= ~(COMREG2_DOUTEN0|COMREG2_DOUTEN1);
+ if(s->io_bits&0x0f)
+ devpriv->com_reg_2_state |= COMREG2_DOUTEN0;
+ if(s->io_bits&0xf0)
+ devpriv->com_reg_2_state |= COMREG2_DOUTEN1;
+ outw(devpriv->com_reg_2_state, dev->iobase+COM_REG_2);
- return it->n_chan;
+ return i;
}
s->type=COMEDI_SUBD_DIO;
s->subdev_flags=SDF_WRITEABLE|SDF_READABLE;
s->n_chan=8;
- s->trig[0]=atmio16d_dio;
+ s->insn_bits = atmio16d_dio_insn_bits;
+ s->insn_config = atmio16d_dio_insn_config;
s->maxdata=1;
s->range_table=&range_digital;
{
printk("comedi%d: atmio16d: remove\n", dev->minor);
+ if(dev->subdevices && boardtype->has_8255)
+ subdev_8255_cleanup(dev,dev->subdevices + 3);
+
if(dev->irq)
free_irq(dev->irq,dev);
return 2;
}
+static void mio_common_detach(comedi_device *dev)
+{
+ if(dev->subdevices && boardtype.has_8255)
+ subdev_8255_cleanup(dev,dev->subdevices+3);
+}
static int ni_E_init(comedi_device *dev,comedi_devconfig *it)
{
s->subdev_flags=SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON|SDF_DIFF|SDF_OTHER;
s->subdev_flags|=SDF_DITHER;
s->n_chan=boardtype.n_adchan;
- s->len_chanlist=512; /* XXX is this the same for PCI-MIO ? */
+ s->len_chanlist=512;
s->maxdata=(1<<boardtype.adbits)-1;
s->range_table=ni_range_lkup[boardtype.gainlkup];
s->insn_read=ni_ai_insn_read;
static int nidio_detach(comedi_device *dev)
{
+ int i;
+
+ if(!this_board->is_diodaq){
+ for(i=0;i<this_board->n_8255;i++){
+ subdev_8255_cleanup(dev,dev->subdevices+i);
+ }
+ }
+
if(dev->irq)
comedi_free_irq(dev->irq,dev);
/* cleans up allocated resources */
static int pcimio_detach(comedi_device *dev)
{
+ mio_common_detach(dev);
+
if(dev->private && devpriv->mite)
mite_unsetup(devpriv->mite);
printk("I/O port conflict\n");
return -EIO;
}
- request_region(dev->iobase, PCL711_SIZE, "pcl711");
+ request_region(iobase, PCL711_SIZE, "pcl711");
dev->iobase = iobase;
/* there should be a sanity check here */
static int pcl724_detach(comedi_device *dev)
{
+ int i;
+
// printk("comedi%d: pcl724: remove\n",dev->minor);
+ for(i=0;i<dev->n_subdevices;i++){
+ subdev_8255_cleanup(dev,dev->subdevices+i);
+ }
+
#ifdef PCL724_IRQ
if(dev->irq){
free_irq(dev->irq,dev);
{
comedi_subdevice *s;
int i;
+ int iobase;
- dev->iobase = it->options[0];
- printk("comedi%d: rti802: 0x%04x ", dev->minor, dev->iobase);
- if (check_region(dev->iobase, RTI802_SIZE) < 0) {
+ iobase = it->options[0];
+ printk("comedi%d: rti802: 0x%04x ", dev->minor, iobase);
+ if (check_region(iobase, RTI802_SIZE) < 0) {
printk("I/O port conflict\n");
return -EIO;
}
- request_region(dev->iobase, RTI802_SIZE, "rti802");
+ request_region(iobase, RTI802_SIZE, "rti802");
+ dev->iobase = iobase;
dev->board_name = "rti802";
*/
static int skel_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
- int n;
+ int n,i;
unsigned int d;
+ unsigned int status;
/* a typical programming sequence */
/* trigger conversion */
//outw(0,dev->iobase + SKEL_CONVERT);
+#define TIMEOUT 100
/* wait for conversion to end */
- /* return -ETIMEDOUT if there is a timeout */
+ for(i=0;i<TIMEOUT;i++){
+ status = 1;
+ //status = inb(dev->iobase + SKEL_STATUS);
+ if(status)break;
+ }
+ if(i==TIMEOUT){
+ /* rt_printk() should be used instead of printk()
+ * whenever the code can be called from real-time. */
+ rt_printk("timeout\n");
+ return -ETIMEDOUT;
+ }
/* read data */
//d = inw(dev->iobase + SKEL_AI_DATA);
tmp=cmd->start_src;
cmd->start_src &= TRIG_NOW;
- if(!cmd->start_src && tmp!=cmd->start_src)err++;
+ if(!cmd->start_src || tmp!=cmd->start_src)err++;
tmp=cmd->scan_begin_src;
cmd->scan_begin_src &= TRIG_TIMER|TRIG_EXT;
- if(!cmd->scan_begin_src && tmp!=cmd->scan_begin_src)err++;
+ if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
tmp=cmd->convert_src;
cmd->convert_src &= TRIG_TIMER|TRIG_EXT;
- if(!cmd->convert_src && tmp!=cmd->convert_src)err++;
+ if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
tmp=cmd->scan_end_src;
cmd->scan_end_src &= TRIG_COUNT;
- if(!cmd->scan_end_src && tmp!=cmd->scan_end_src)err++;
+ if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
tmp=cmd->stop_src;
cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
- if(!cmd->stop_src && tmp!=cmd->stop_src)err++;
+ if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
if(err)return 1;