From: David Schleef Date: Wed, 11 Apr 2001 05:08:12 +0000 (+0000) Subject: Migrating drivers from trig to insn X-Git-Tag: r0_7_59~122 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=2009ee124a3c9702bceb344835f22e9b59451f72;p=comedi.git Migrating drivers from trig to insn --- diff --git a/comedi/drivers/Makefile b/comedi/drivers/Makefile index de97c7b2..05392fd9 100644 --- a/comedi/drivers/Makefile +++ b/comedi/drivers/Makefile @@ -51,6 +51,8 @@ obj-$(CONFIG_COMEDI_II_PCI20KC) += ii_pci20kc.o obj-$(CONFIG_COMEDI_MULTIQ3) += multiq3.o +obj-$(CONFIG_COMEDI_MPC8260CPM) += mpc8260cpm.o + obj-$(CONFIG_COMEDI_NI_ATMIO) += ni_atmio.o obj-$(CONFIG_COMEDI_NI_MIO_CS) += ni_mio_cs.o obj-$(CONFIG_COMEDI_NI_PCIMIO) += ni_pcimio.o diff --git a/comedi/drivers/comedi_rt_timer.c b/comedi/drivers/comedi_rt_timer.c index 2a09d791..5c9793bd 100644 --- a/comedi/drivers/comedi_rt_timer.c +++ b/comedi/drivers/comedi_rt_timer.c @@ -100,7 +100,6 @@ static void timer_ai_task_func(int d) comedi_device *dev=(comedi_device *)d; comedi_subdevice *s=dev->subdevices+0; comedi_trig *it=&devpriv->trig; - comedi_trig *my_trig=&s->cur_trig; int i,n,ret; int n_chan; diff --git a/comedi/drivers/dt2811.c b/comedi/drivers/dt2811.c index 5138405b..c73274e8 100644 --- a/comedi/drivers/dt2811.c +++ b/comedi/drivers/dt2811.c @@ -256,7 +256,6 @@ static void dt2811_interrupt(int irq, void *d, struct pt_regs *regs) data = lo + (hi << 8); if (!(--devpriv->ntrig)) { - /* XXX */ /* how to turn off acquisition */ comedi_done(dev, dev->subdevices + 0); } @@ -290,17 +289,19 @@ static int dt2811_attach(comedi_device * dev, comedi_devconfig * it) //long flags; int ret; comedi_subdevice *s; + int iobase; - dev->iobase = it->options[0]; + iobase = it->options[0]; - printk("comedi%d: dt2811: base=0x%04x\n", dev->minor, dev->iobase); + printk("comedi%d: dt2811: base=0x%04x\n", dev->minor, iobase); - if (check_region(dev->iobase, DT2811_SIZE) < 0) { + if (check_region(iobase, DT2811_SIZE) < 0) { printk("I/O port conflict\n"); return -EIO; } - request_region(dev->iobase, DT2811_SIZE, driver_name); + request_region(iobase, DT2811_SIZE, driver_name); + dev->iobase = iobase; dev->board_name = this_board->name; #if 0 diff --git a/comedi/drivers/dt2814.c b/comedi/drivers/dt2814.c index 98ca568e..21a560c4 100644 --- a/comedi/drivers/dt2814.c +++ b/comedi/drivers/dt2814.c @@ -73,7 +73,7 @@ typedef struct{ #define DT2814_TIMEOUT 10 -#define DT2814_MAX_SPEED 100000 /* XXX 10 khz */ +#define DT2814_MAX_SPEED 100000 /* Arbitrary 10 khz limit */ static int dt2814_ai_insn_read(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn, lsampl_t *data) @@ -230,15 +230,16 @@ static int dt2814_attach(comedi_device *dev,comedi_devconfig *it) int i,irq; int ret; comedi_subdevice *s; + int iobase; - dev->iobase=it->options[0]; + iobase=it->options[0]; printk("comedi%d: dt2814: 0x%04x ",dev->minor,dev->iobase); - if(check_region(dev->iobase,DT2814_SIZE)<0){ + if(check_region(iobase,DT2814_SIZE)<0){ printk("I/O port conflict\n"); return -EIO; } - request_region(dev->iobase,DT2814_SIZE,"dt2814"); - dev->iobase=dev->iobase; + request_region(iobase,DT2814_SIZE,"dt2814"); + dev->iobase=iobase; dev->board_name = "dt2814"; outb(0,dev->iobase+DT2814_CSR); diff --git a/comedi/drivers/dt2815.c b/comedi/drivers/dt2815.c index c9ebe9b1..82e5e7ab 100644 --- a/comedi/drivers/dt2815.c +++ b/comedi/drivers/dt2815.c @@ -37,10 +37,10 @@ static comedi_lrange range_dt2815_ao_32_current = { 1, { - RANGE( 0, 32 ) /* XXX mA */ + RANGE_mA( 0, 32 ) }}; static comedi_lrange range_dt2815_ao_20_current = { 1, { - RANGE( 4, 20 ) + RANGE_mA( 4, 20 ) }}; #define DT2815_SIZE 2 @@ -62,51 +62,63 @@ static void dt2815_free_resources(comedi_device * dev); typedef struct { comedi_lrange * range_type_list[8]; + lsampl_t ao_readback[8]; } dt2815_private; #define devpriv ((dt2815_private *)dev->private) -static int dt2815_ao(comedi_device * dev, comedi_subdevice *s, comedi_trig * it) +static int dt2815_wait_for_status(comedi_device *dev,int status) +{ + int i; + + for(i=0;i<100;i++){ + if(inb(dev->iobase + DT2815_STATUS)==status) + break; + } + return status; +} + +static int dt2815_ao_insn_read(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) +{ + int i; + int chan = CR_CHAN(insn->chanspec); + + for(i=0;in;i++){ + data[i]=devpriv->ao_readback[chan]; + } + + return i; +} + +static int dt2815_ao_insn(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) { int i; - int t; - int chan; - int data; + int chan = CR_CHAN(insn->chanspec); unsigned int status; unsigned int lo, hi; - for(i=0 ; i < it->n_chan ; i++) { - chan = CR_CHAN(it->chanlist[i]); - data = it->data[i]; + for(i=0;in;i++){ + lo = ((data[i] & 0x0f) << 4) | (chan << 1) | 0x01; + hi = (data[i] & 0xff0) >> 4; - lo = ((data & 0x0f) << 4) | (chan << 1) | 0x01; - hi = (data & 0xff0) >> 4; - status = inb(dev->iobase + DT2815_STATUS); - for (t = 0 ; t < 30 ; t++) { - if (status == 0x00) break; - udelay(10); - status = inb(dev->iobase + DT2815_STATUS); - } - if (status == 0x00) { - outb(lo, dev->iobase + DT2815_DATA); - } else { - rt_printk("dt2815: failed to write low byte on %d reason %x, %d\n", - chan, status, t); + status = dt2815_wait_for_status(dev,0x00); + if(status!=0){ + rt_printk("dt2815: failed to write low byte on %d reason %x\n", + chan, status); return -EBUSY; } - status = inb(dev->iobase + DT2815_STATUS); - for (t = 0 ; t < 30 ; t++) { - if (status == 0x10) break; - udelay(10); - status = inb(dev->iobase + DT2815_STATUS); - } - if (status == 0x10) { - outb(hi, dev->iobase + DT2815_DATA); - } else { - rt_printk("dt2815: failed to write high byte on %d reason %x, %d\n", - chan, status, t); + + outb(lo, dev->iobase + DT2815_DATA); + + status = dt2815_wait_for_status(dev,0x10); + if(status!=0x10){ + rt_printk("dt2815: failed to write high byte on %d reason %x\n", + chan, status); return -EBUSY; } + devpriv->ao_readback[chan] = data[i]; } return i; } @@ -140,15 +152,17 @@ static int dt2815_attach(comedi_device * dev, comedi_devconfig * it) comedi_subdevice *s; int i; comedi_lrange *current_range_type, *voltage_range_type; + int iobase; - dev->iobase = it->options[0]; - printk("comedi%d: dt2815: 0x%04x ", dev->minor, dev->iobase); - if (check_region(dev->iobase, DT2815_SIZE) < 0) { + iobase = it->options[0]; + printk("comedi%d: dt2815: 0x%04x ", dev->minor, iobase); + if (check_region(iobase, DT2815_SIZE) < 0) { printk("I/O port conflict\n"); return -EIO; } - request_region(dev->iobase, DT2815_SIZE, "dt2815"); + request_region(iobase, DT2815_SIZE, "dt2815"); + dev->iobase = iobase; dev->board_name = "dt2815"; dev->n_subdevices = 1; @@ -163,7 +177,8 @@ static int dt2815_attach(comedi_device * dev, comedi_devconfig * it) s->subdev_flags=SDF_WRITEABLE; s->maxdata=0xfff; s->n_chan=8; - s->trig[0] = dt2815_ao; + 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]) diff --git a/comedi/drivers/dt2817.c b/comedi/drivers/dt2817.c index a7b7d7c2..3addca31 100644 --- a/comedi/drivers/dt2817.c +++ b/comedi/drivers/dt2817.c @@ -120,14 +120,16 @@ static int dt2817_attach(comedi_device *dev,comedi_devconfig *it) { int ret; comedi_subdevice *s; + int iobase; - dev->iobase=it->options[0]; - printk("comedi%d: dt2817: 0x%04x ",dev->minor,dev->iobase); - if(check_region(dev->iobase,DT2817_SIZE)<0){ + iobase=it->options[0]; + printk("comedi%d: dt2817: 0x%04x ",dev->minor,iobase); + if(check_region(iobase,DT2817_SIZE)<0){ printk("I/O port conflict\n"); return -EIO; } - request_region(dev->iobase,DT2817_SIZE,"dt2817"); + request_region(iobase,DT2817_SIZE,"dt2817"); + dev->iobase = iobase; dev->board_name="dt2817"; dev->n_subdevices=1; diff --git a/comedi/drivers/dt282x.c b/comedi/drivers/dt282x.c index a84ed163..579bdcd5 100644 --- a/comedi/drivers/dt282x.c +++ b/comedi/drivers/dt282x.c @@ -1081,7 +1081,7 @@ static int dt282x_dio_insn_config(comedi_device *dev,comedi_subdevice *s, outw(devpriv->dacsr, dev->iobase + DT2821_DACSR); - return 0; + return 1; } @@ -1142,20 +1142,20 @@ static int dt282x_attach(comedi_device * dev, comedi_devconfig * it) long flags; int ret; comedi_subdevice *s; + int iobase; dev->board_name = this_board->name; - if (it->options[opt_iobase]) - dev->iobase = it->options[opt_iobase]; - else - dev->iobase = 0x240; + iobase = it->options[opt_iobase]; + if(!iobase)iobase = 0x240; - printk("comedi%d: dt282x: 0x%04x", dev->minor, dev->iobase); - if (check_region(dev->iobase, DT2821_SIZE) < 0) { + printk("comedi%d: dt282x: 0x%04x", dev->minor, iobase); + if (check_region(iobase, DT2821_SIZE) < 0) { printk(" I/O port conflict\n"); return -EBUSY; } - request_region(dev->iobase, DT2821_SIZE, "dt282x"); + request_region(iobase, DT2821_SIZE, "dt282x"); + dev->iobase = iobase; outw(DT2821_BDINIT, dev->iobase + DT2821_SUPCSR); i = inw(dev->iobase + DT2821_ADCSR); diff --git a/comedi/drivers/dt3000.c b/comedi/drivers/dt3000.c index 433a2a5d..6bf9eb55 100644 --- a/comedi/drivers/dt3000.c +++ b/comedi/drivers/dt3000.c @@ -219,6 +219,7 @@ typedef struct{ unsigned long phys_addr; void *io_addr; unsigned int lock; + lsampl_t ao_readback[2]; }dt3k_private; #define devpriv ((dt3k_private *)dev->private) @@ -230,6 +231,7 @@ comedi_driver driver_dt3000={ attach: dt3000_attach, detach: dt3000_detach, }; +COMEDI_INITCLEANUP(driver_dt3000); #define TIMEOUT 100 @@ -316,31 +318,51 @@ static int dt3k_ai_config(comedi_device *dev,comedi_subdevice *s,comedi_trig *it } #endif - -static int dt3k_ai_mode0(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) +static int dt3k_ai_insn(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) { + int i; unsigned int chan,gain,aref; - chan=CR_CHAN(it->chanlist[0]); - gain=CR_RANGE(it->chanlist[0]); - /* docs don't explain how to select aref */ - aref=CR_AREF(it->chanlist[0]); + chan=CR_CHAN(insn->chanspec); + gain=CR_RANGE(insn->chanspec); + /* XXX docs don't explain how to select aref */ + aref=CR_AREF(insn->chanspec); - it->data[0]=dt3k_readsingle(dev,SUBS_AI,chan,gain); - - return 1; + for(i=0;in;i++){ + data[i]=dt3k_readsingle(dev,SUBS_AI,chan,gain); + } + + return i; } -static int dt3k_ao_mode0(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) +static int dt3k_ao_insn(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) { - unsigned int chan,data; + int i; + unsigned int chan; + + chan=CR_CHAN(insn->chanspec); + for(i=0;in;i++){ + dt3k_writesingle(dev,SUBS_AO,chan,data[i]); + devpriv->ao_readback[chan]=data[i]; + } - chan=CR_CHAN(it->chanlist[0]); - data=it->data[0]; + return i; +} - dt3k_writesingle(dev,SUBS_AO,chan,data); +static int dt3k_ao_insn_read(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) +{ + int i; + unsigned int chan; - return 1; + chan=CR_CHAN(insn->chanspec); + for(i=0;in;i++){ + data[i]=devpriv->ao_readback[chan]; + } + + return i; } static void dt3k_dio_config(comedi_device *dev,int bits) @@ -358,49 +380,55 @@ static void dt3k_dio_config(comedi_device *dev,int bits) dt3k_send_cmd(dev,CMD_CONFIG); } -static int dt3k_dio(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) +static int dt3k_dio_insn_config(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) { - if(it->flags&TRIG_CONFIG){ - int mask,i; + int mask; - for(i=0;in_chan;i++){ - mask=(CR_CHAN(it->chanlist[i])<4)?0x0f:0xf0; - if(it->data[i])s->io_bits|=mask; - else s->io_bits&=~mask; - } + if(insn->n!=1)return -EINVAL; - mask=(s->io_bits&0x01)|((s->io_bits&0x10)>>3); - dt3k_dio_config(dev,mask); - }else{ - unsigned int data; - - if(it->flags&TRIG_WRITE){ - do_pack(&s->state,it); - dt3k_writesingle(dev,SUBS_DOUT,0,s->state); - }else{ - data=dt3k_readsingle(dev,SUBS_DIN,0,0); - di_unpack(data,it); - } + mask=(CR_CHAN(insn->chanspec)<4)?0x0f:0xf0; + if(data[0]==COMEDI_OUTPUT)s->io_bits|=mask; + else s->io_bits&=~mask; + + mask=(s->io_bits&0x01)|((s->io_bits&0x10)>>3); + dt3k_dio_config(dev,mask); + + return 1; +} + +static int dt3k_dio_insn_bits(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) +{ + if(insn->n!=2)return -EINVAL; + + if(data[0]){ + s->state &= ~data[0]; + s->state |= data[1]&data[0]; + dt3k_writesingle(dev,SUBS_DOUT,0,s->state); } + data[1]=dt3k_readsingle(dev,SUBS_DIN,0,0); - return it->n_chan; + return 2; } -static int dt3k_readmem(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) +static int dt3k_mem_insn_read(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) { - unsigned int addr; - - addr=CR_CHAN(it->chanlist[0]); - - writew(SUBS_MEM,dev->iobase+DPR_SubSys); - writew(addr,dev->iobase+DPR_Params(0)); - writew(1,dev->iobase+DPR_Params(1)); + unsigned int addr=CR_CHAN(insn->chanspec); + int i; + + for(i=0;in;i++){ + writew(SUBS_MEM,dev->iobase+DPR_SubSys); + writew(addr,dev->iobase+DPR_Params(0)); + writew(1,dev->iobase+DPR_Params(1)); - dt3k_send_cmd(dev,CMD_READCODE); + dt3k_send_cmd(dev,CMD_READCODE); - it->data[0]=readw(dev->iobase+DPR_Params(2)); + data[i]=readw(dev->iobase+DPR_Params(2)); + } - return 1; + return i; } static int dt_pci_probe(comedi_device *dev); @@ -442,7 +470,7 @@ static int dt3000_attach(comedi_device *dev,comedi_devconfig *it) s->type=COMEDI_SUBD_AI; s->subdev_flags=SDF_READABLE; s->n_chan=this_board->adchan; - s->trig[0]=dt3k_ai_mode0; + s->insn_read=dt3k_ai_insn; s->maxdata=(1<adbits)-1; s->len_chanlist=512; s->range_table=&range_dt3000_ai; /* XXX */ @@ -452,7 +480,8 @@ static int dt3000_attach(comedi_device *dev,comedi_devconfig *it) s->type=COMEDI_SUBD_AO; s->subdev_flags=SDF_WRITEABLE; s->n_chan=2; - s->trig[0]=dt3k_ao_mode0; + s->insn_read=dt3k_ao_insn_read; + s->insn_write=dt3k_ao_insn; s->maxdata=(1<dabits)-1; s->len_chanlist=1; s->range_table=&range_bipolar10; @@ -462,7 +491,8 @@ static int dt3000_attach(comedi_device *dev,comedi_devconfig *it) s->type=COMEDI_SUBD_DIO; s->subdev_flags=SDF_READABLE|SDF_WRITEABLE; s->n_chan=8; - s->trig[0]=dt3k_dio; + s->insn_config=dt3k_dio_insn_config; + s->insn_bits=dt3k_dio_insn_bits; s->maxdata=1; s->len_chanlist=8; s->range_table=&range_digital; @@ -472,7 +502,7 @@ static int dt3000_attach(comedi_device *dev,comedi_devconfig *it) s->type=COMEDI_SUBD_MEMORY; s->subdev_flags=SDF_READABLE; s->n_chan=0x1000; - s->trig[0]=dt3k_readmem; + s->insn_read=dt3k_mem_insn_read; s->maxdata=0xff; s->len_chanlist=1; s->range_table=&range_unknown; @@ -655,16 +685,3 @@ static struct pci_dev *dt_pci_find_device(struct pci_dev *from,int *board) #endif #endif /* PCI_SUPPORT_VER1 */ -#ifdef MODULE -int init_module(void) -{ - comedi_driver_register(&driver_dt3000); - - return 0; -} - -void cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt3000); -} -#endif diff --git a/comedi/drivers/ni_pcidio.c b/comedi/drivers/ni_pcidio.c index 3ab3feaa..1faccf4b 100644 --- a/comedi/drivers/ni_pcidio.c +++ b/comedi/drivers/ni_pcidio.c @@ -297,28 +297,6 @@ static int ni_pcidio_insn_bits(comedi_device *dev,comedi_subdevice *s, return 2; } -#if 0 -static int nidio_dio(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) -{ - if(it->flags & TRIG_CONFIG){ - do_pack(&s->io_bits,it); - writel(s->io_bits,dev->iobase+Port_Pin_Directions(0)); - }else{ - if(it->flags&TRIG_WRITE){ - do_pack(&s->state,it); - writel(s->state,dev->iobase+Port_IO(0)); - }else{ - unsigned int data; - - data=readl(dev->iobase+Port_IO(0)); - di_unpack(data,it); - } - } - - return it->n_chan; -} -#endif - static int nidio_dio_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) { int i; @@ -442,7 +420,6 @@ static int nidio_attach(comedi_device *dev,comedi_devconfig *it) s->n_chan=32; s->range_table=&range_digital; s->maxdata=1; - //s->trig[0]=nidio_dio; s->trig[2]=nidio_dio_mode2; s->insn_config = ni_pcidio_insn_config; s->insn_bits = ni_pcidio_insn_bits; diff --git a/comedi/drivers/pcl711.c b/comedi/drivers/pcl711.c index 718cf307..e64096e2 100644 --- a/comedi/drivers/pcl711.c +++ b/comedi/drivers/pcl711.c @@ -162,6 +162,7 @@ comedi_driver driver_pcl711={ num_names: n_boardtypes, offset: sizeof(boardtype), }; +COMEDI_INITCLEANUP(driver_pcl711); typedef struct { int board; @@ -169,6 +170,7 @@ typedef struct { int ntrig; int aip[8]; int mode; + lsampl_t ao_readback[2]; } pcl711_private; #define devpriv ((pcl711_private *)dev->private) @@ -225,49 +227,46 @@ static void pcl711_set_changain(comedi_device * dev, int chan) } } -static int pcl711_ai_mode0(comedi_device * dev, comedi_subdevice * s, comedi_trig * it) +static int pcl711_ai_insn(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) { - int hi, lo, i; - int nmax=40; /* 1000 us / 25 us */ - int n; + int i,n; + int hi,lo; - if(it->n<=nmax)nmax=it->n; + pcl711_set_changain(dev,insn->chanspec); - pcl711_set_changain(dev,it->chanlist[0]); - /* a sensible precaution to wait for the mux to settle here. is 10us enough? */ udelay(10); -for(n=0;niobase + PCL711_MODE); + for(n=0;nn;n++){ + /* + * Write the correct mode (software polling) and start polling by writing + * to the trigger register + */ + outb(1, dev->iobase + PCL711_MODE); - if (this_board->is_8112) { - }else{ - outb(0, dev->iobase + PCL711_SOFTTRIG); - } + if (this_board->is_8112) { + }else{ + outb(0, dev->iobase + PCL711_SOFTTRIG); + } - i=PCL711_TIMEOUT; - while(--i){ - hi = inb(dev->iobase + PCL711_AD_HI); - if (!(hi & PCL711_DRDY)) - goto ok; - udelay(5); - } - rt_printk("comedi%d: pcl711: A/D timeout\n", dev->minor); - return -ETIME; + i=PCL711_TIMEOUT; + while(--i){ + hi = inb(dev->iobase + PCL711_AD_HI); + if (!(hi & PCL711_DRDY)) + goto ok; + } + rt_printk("comedi%d: pcl711: A/D timeout\n", dev->minor); + return -ETIME; ok: - lo = inb(dev->iobase + PCL711_AD_LO); + lo = inb(dev->iobase + PCL711_AD_LO); - it->data[n] = ((hi & 0xf) << 8) | lo; -} + data[n] = ((hi & 0xf) << 8) | lo; + } return n; } @@ -330,60 +329,73 @@ static int pcl711_ai_mode1(comedi_device * dev, comedi_subdevice * s, comedi_tri /* analog output */ -static int pcl711_ao(comedi_device * dev, comedi_subdevice * s, comedi_trig * it) +static int pcl711_ao_insn(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) { - int chan = CR_CHAN(it->chanlist[0]); - sampl_t data = it->data[0]; + int n; + int chan = CR_CHAN(insn->chanspec); - outb((data & 0xff), dev->iobase + (chan ? PCL711_DA1_LO : PCL711_DA0_LO)); - outb((data >> 8), dev->iobase + (chan ? PCL711_DA1_HI : PCL711_DA0_HI)); + for(n=0;nn;n++){ + outb((data[n] & 0xff), dev->iobase + (chan ? PCL711_DA1_LO : PCL711_DA0_LO)); + outb((data[n] >> 8), dev->iobase + (chan ? PCL711_DA1_HI : PCL711_DA0_HI)); + + devpriv->ao_readback[chan] = data[n]; + } + + return n; +} + +static int pcl711_ao_insn_read(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) +{ + int n; + int chan = CR_CHAN(insn->chanspec); + + for(n=0;nn;n++){ + data[n] = devpriv->ao_readback[chan]; + } + + return n; - return 0; } /* Digital port read - Untested on 8112 */ -static int pcl711_di(comedi_device * dev, comedi_subdevice * s, comedi_trig * it) +static int pcl711_di_insn_bits(comedi_device * dev, comedi_subdevice * s, + comedi_insn *insn,lsampl_t *data) { - int data; - int chan; - int i; + if(insn->n!=2)return -EINVAL; - data = inb(dev->iobase + PCL711_DI_LO) | + data[1] = inb(dev->iobase + PCL711_DI_LO) | (inb(dev->iobase + PCL711_DI_HI) << 8); - for(i=0;in_chan;i++){ - chan=CR_CHAN(it->chanlist[i]); - it->data[i]=(data>>chan)&1; - } - - return it->n_chan; + return 2; } /* Digital port write - Untested on 8112 */ -static int pcl711_do(comedi_device * dev, comedi_subdevice * s, comedi_trig * it) +static int pcl711_do_insn_bits(comedi_device * dev, comedi_subdevice * s, + comedi_insn *insn,lsampl_t *data) { - int mask, data; - int chan; - int i; - - data=s->state; - for(i=0;in_chan;i++){ - chan=CR_CHAN(it->chanlist[i]); - mask=(1<data[i]) - data |= mask; + if(insn->n!=2)return -EINVAL; + + if(data[0]){ + s->state &= ~data[0]; + s->state |= data[0]&data[1]; } - outb(data & 0xff, dev->iobase + PCL711_DO_LO); - outb((data >> 8), dev->iobase + PCL711_DO_HI); - s->state = data; + if(data[0]&0x00ff) + outb(s->state & 0xff, dev->iobase + PCL711_DO_LO); + if(data[0]&0xff00) + outb((s->state >> 8), dev->iobase + PCL711_DO_HI); - return it->n_chan; + data[1]=s->state; + + return 2; } /* Free any resources that we have claimed */ -static void free_resources(comedi_device * dev) +static int pcl711_detach(comedi_device * dev) { + printk("comedi%d: pcl711: remove\n", dev->minor); + if (dev->irq) free_irq(dev->irq, dev); @@ -447,7 +459,7 @@ static int pcl711_attach(comedi_device * dev, comedi_devconfig * it) s->maxdata = 0xfff; s->len_chanlist = 1; s->range_table = this_board->ai_range_type; - s->trig[0] = pcl711_ai_mode0; + s->insn_read = pcl711_ai_insn; s->trig[1] = pcl711_ai_mode1; s->trig[4] = pcl711_ai_mode4; @@ -459,7 +471,8 @@ static int pcl711_attach(comedi_device * dev, comedi_devconfig * it) s->maxdata = 0xfff; s->len_chanlist = 1; s->range_table = &range_bipolar5; - s->trig[0] = pcl711_ao; + s->insn_write = pcl711_ao_insn; + s->insn_read = pcl711_ao_insn_read; s++; /* 16-bit digital input */ @@ -469,7 +482,7 @@ static int pcl711_attach(comedi_device * dev, comedi_devconfig * it) s->maxdata = 1; s->len_chanlist = 16; s->range_table = &range_digital; - s->trig[0] = pcl711_di; + s->insn_bits = pcl711_di_insn_bits; s++; /* 16-bit digital out */ @@ -480,7 +493,7 @@ static int pcl711_attach(comedi_device * dev, comedi_devconfig * it) s->len_chanlist = 16; s->range_table = &range_digital; s->state=0; - s->trig[0] = pcl711_do; + s->insn_bits = pcl711_do_insn_bits; /* this is the "base value" for the mode register, which is @@ -501,19 +514,3 @@ static int pcl711_attach(comedi_device * dev, comedi_devconfig * it) return 0; } - -/* - * Removes device - */ - -static int pcl711_detach(comedi_device * dev) -{ - printk("comedi%d: pcl711: remove\n", dev->minor); - - free_resources(dev); - - return 0; -} - -COMEDI_INITCLEANUP(driver_pcl711); - diff --git a/comedi/drivers/pcl725.c b/comedi/drivers/pcl725.c index 96599b43..b0e18f5b 100644 --- a/comedi/drivers/pcl725.c +++ b/comedi/drivers/pcl725.c @@ -34,40 +34,46 @@ comedi_driver driver_pcl725={ }; COMEDI_INITCLEANUP(driver_pcl725); -static int pcl725_do(comedi_device *dev,comedi_subdevice *s,comedi_trig *it); -static int pcl725_di(comedi_device *dev,comedi_subdevice *s,comedi_trig *it); - -static int pcl725_do(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) +static int pcl725_do_insn(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) { - do_pack(&s->state,it); + if(insn->n!=2)return -EINVAL; + + if(data[0]){ + s->state &= ~data[0]; + s->state |= (data[0]&data[1]); + outb(s->state,dev->iobase+PCL725_DO); + } - outb(s->state,dev->iobase+PCL725_DO); + data[1]=s->state; - return it->n_chan; + return 2; } -static int pcl725_di(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) +static int pcl725_di_insn(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) { - unsigned int bits; - - bits=inb(dev->iobase+PCL725_DI); - - return di_unpack(bits,it); + if(insn->n!=2)return -EINVAL; + + data[1]=inb(dev->iobase+PCL725_DI); + + return 2; } static int pcl725_attach(comedi_device *dev,comedi_devconfig *it) { comedi_subdevice *s; + int iobase; - dev->iobase=it->options[0]; - printk("comedi%d: pcl725: 0x%04x ",dev->minor,dev->iobase); - if(check_region(dev->iobase,PCL725_SIZE)<0){ + iobase=it->options[0]; + printk("comedi%d: pcl725: 0x%04x ",dev->minor,iobase); + if(check_region(iobase,PCL725_SIZE)<0){ printk("I/O port conflict\n"); return -EIO; } - request_region(dev->iobase,PCL725_SIZE,"pcl725"); + request_region(iobase,PCL725_SIZE,"pcl725"); dev->board_name="pcl725"; - dev->iobase=dev->iobase; + dev->iobase=iobase; dev->irq=0; dev->n_subdevices=2; @@ -81,16 +87,16 @@ static int pcl725_attach(comedi_device *dev,comedi_devconfig *it) s->subdev_flags=SDF_WRITEABLE; s->maxdata=1; s->n_chan=8; - s->trig[0]=pcl725_do; + s->insn_bits = pcl725_do_insn; s->range_table=&range_digital; s=dev->subdevices+1; - /* do */ + /* di */ s->type=COMEDI_SUBD_DI; s->subdev_flags=SDF_READABLE; s->maxdata=1; s->n_chan=8; - s->trig[0]=pcl725_di; + s->insn_bits = pcl725_di_insn; s->range_table=&range_digital; printk("\n"); diff --git a/comedi/drivers/pcl726.c b/comedi/drivers/pcl726.c index e2ff37c3..3643ac98 100644 --- a/comedi/drivers/pcl726.c +++ b/comedi/drivers/pcl726.c @@ -170,46 +170,73 @@ COMEDI_INITCLEANUP(driver_pcl726); typedef struct{ int bipolar[12]; comedi_lrange *rangelist[12]; + lsampl_t ao_readback[12]; }pcl726_private; #define devpriv ((pcl726_private *)dev->private) -static int pcl726_ao(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) +static int pcl726_ao_insn(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) { int hi,lo; - int chan=CR_CHAN(it->chanlist[0]); - - lo=it->data[0]&0xff; - hi=(it->data[0]>>8)&0xf; - if(devpriv->bipolar[chan])hi^=0x8; -/* - the programming info did not say which order to write bytes. - switch the order of the next two lines if you get glitches. -*/ - outb(hi,dev->iobase+PCL726_DAC0_HI + 2*chan); - outb(lo,dev->iobase+PCL726_DAC0_LO + 2*chan); + int n; + int chan=CR_CHAN(insn->chanspec); + + for(n=0;nn;n++){ + lo=data[n]&0xff; + hi=(data[n]>>8)&0xf; + if(devpriv->bipolar[chan])hi^=0x8; + /* + * the programming info did not say which order + * to write bytes. switch the order of the next + * two lines if you get glitches. + */ + outb(hi,dev->iobase+PCL726_DAC0_HI + 2*chan); + outb(lo,dev->iobase+PCL726_DAC0_LO + 2*chan); + devpriv->ao_readback[chan]=data[n]; + } - return 1; + return n; +} + +static int pcl726_ao_insn_read(comedi_device *dev,comedi_subdevice *s, + comedi_insn *insn,lsampl_t *data) +{ + int chan=CR_CHAN(insn->chanspec); + int n; + + for(n=0;nn;n++){ + data[n]=devpriv->ao_readback[chan]; + } + return n; } -static int pcl726_di(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) +static int pcl726_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=inb(dev->iobase+this_board->di_lo)| + data[1]=inb(dev->iobase+this_board->di_lo)| (inb(dev->iobase+this_board->di_hi)<<8); - return di_unpack(bits,it); + return 2; } -static int pcl726_do(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) +static int pcl726_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; - outb(s->state&0xff,dev->iobase+this_board->do_lo); - outb((s->state>>8),dev->iobase+this_board->do_hi); + if(data[0]){ + s->state &= ~data[0]; + s->state |= data[0]&data[1]; + } + if(data[1]&0x00ff) + outb(s->state&0xff,dev->iobase+this_board->do_lo); + if(data[1]&0xff00) + outb((s->state>>8),dev->iobase+this_board->do_hi); - return it->n_chan; + return 2; } static int pcl726_attach(comedi_device *dev,comedi_devconfig *it) @@ -276,8 +303,8 @@ static int pcl726_attach(comedi_device *dev,comedi_devconfig *it) s->n_chan=this_board->n_aochan; s->maxdata=0xfff; s->len_chanlist=1; - s->trig[0]=pcl726_ao; - /*s->range_table=&range_unknown;*/ /* XXX */ + s->insn_write=pcl726_ao_insn; + s->insn_read=pcl726_ao_insn_read; s->range_table_list = devpriv->rangelist; for (i=0; in_aochan; i++) { int j; @@ -293,8 +320,6 @@ static int pcl726_attach(comedi_device *dev,comedi_devconfig *it) devpriv->bipolar[i]=1; /* bipolar range */ } - - s=dev->subdevices+1; /* di */ if (!this_board->have_dio){ @@ -305,7 +330,7 @@ static int pcl726_attach(comedi_device *dev,comedi_devconfig *it) s->n_chan=16; s->maxdata=1; s->len_chanlist=1; - s->trig[0]=pcl726_di; + s->insn_bits=pcl726_di_insn_bits; s->range_table=&range_digital; } @@ -319,7 +344,7 @@ static int pcl726_attach(comedi_device *dev,comedi_devconfig *it) s->n_chan=16; s->maxdata=1; s->len_chanlist=1; - s->trig[0]=pcl726_do; + s->insn_bits=pcl726_do_insn_bits; s->range_table=&range_digital; } @@ -337,7 +362,8 @@ static int pcl726_detach(comedi_device *dev) } #endif - release_region(dev->iobase,this_board->io_range); + if(dev->iobase) + release_region(dev->iobase,this_board->io_range); return 0; }