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
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;
data = lo + (hi << 8);
if (!(--devpriv->ntrig)) {
- /* XXX */
/* how to turn off acquisition */
comedi_done(dev, dev->subdevices + 0);
}
//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
#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)
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);
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
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;i<insn->n;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;i<insn->n;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;
}
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;
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])
{
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;
outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
- return 0;
+ return 1;
}
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);
unsigned long phys_addr;
void *io_addr;
unsigned int lock;
+ lsampl_t ao_readback[2];
}dt3k_private;
#define devpriv ((dt3k_private *)dev->private)
attach: dt3000_attach,
detach: dt3000_detach,
};
+COMEDI_INITCLEANUP(driver_dt3000);
#define TIMEOUT 100
}
#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;i<insn->n;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;i<insn->n;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;i<insn->n;i++){
+ data[i]=devpriv->ao_readback[chan];
+ }
+
+ return i;
}
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;i<it->n_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;i<insn->n;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);
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<<this_board->adbits)-1;
s->len_chanlist=512;
s->range_table=&range_dt3000_ai; /* XXX */
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<<this_board->dabits)-1;
s->len_chanlist=1;
s->range_table=&range_bipolar10;
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;
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;
#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
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;
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;
num_names: n_boardtypes,
offset: sizeof(boardtype),
};
+COMEDI_INITCLEANUP(driver_pcl711);
typedef struct {
int board;
int ntrig;
int aip[8];
int mode;
+ lsampl_t ao_readback[2];
} pcl711_private;
#define devpriv ((pcl711_private *)dev->private)
}
}
-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;n<nmax;n++){
- /*
- * Write the correct mode (software polling) and start polling by writing
- * to the trigger register
- */
- outb(1, dev->iobase + PCL711_MODE);
+ for(n=0;n<insn->n;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;
}
/*
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;n<insn->n;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;n<insn->n;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;i<it->n_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;i<it->n_chan;i++){
- chan=CR_CHAN(it->chanlist[i]);
- mask=(1<<chan);
- data &= ~mask;
- if(it->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);
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;
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 */
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 */
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
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);
-
};
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;
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");
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;n<insn->n;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;n<insn->n;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)
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; i<this_board->n_aochan; i++) {
int j;
devpriv->bipolar[i]=1; /* bipolar range */
}
-
-
s=dev->subdevices+1;
/* di */
if (!this_board->have_dio){
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;
}
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;
}
}
#endif
- release_region(dev->iobase,this_board->io_range);
+ if(dev->iobase)
+ release_region(dev->iobase,this_board->io_range);
return 0;
}