Update pcmad driver for Comedi changes in the last year.
authorDavid Schleef <ds@schleef.org>
Mon, 28 May 2001 00:08:41 +0000 (00:08 +0000)
committerDavid Schleef <ds@schleef.org>
Mon, 28 May 2001 00:08:41 +0000 (00:08 +0000)
comedi/drivers/pcmad.c

index 21cd6ba512025b5b91820c0e68ddd3065dd8bc9a..0e9dfd5afb053761561359ff9d305412b8b4253e 100644 (file)
@@ -3,7 +3,7 @@
     hardware driver for Winsystems PCM-A/D12 and PCM-A/D16
 
     COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2000 David A. Schleef <ds@stm.lbl.gov>
+    Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/comedidev.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/malloc.h>
@@ -34,7 +35,6 @@
 #include <linux/timex.h>
 #include <linux/timer.h>
 #include <asm/io.h>
-#include <comedi_module.h>
 
 
 #define PCMAD_SIZE             4
 #define PCMAD_MSB              2
 #define PCMAD_CONVERT          1
 
-static int pcmad_attach(comedi_device *dev,comedi_devconfig *it);
-static int pcmad_detach(comedi_device *dev);
-static int pcmad_recognize(char *name);
-comedi_driver driver_pcmad={
-       driver_name:    "pcmad",
-       module:         THIS_MODULE,
-       attach:         pcmad_attach,
-       detach:         pcmad_detach,
-       recognize:      pcmad_recognize,
-};
-
 struct pcmad_board_struct{
        char *name;
        int n_ai_bits;
@@ -70,7 +59,7 @@ struct pcmad_board_struct pcmad_boards[]={
        },
 };
 #define this_board ((struct pcmad_board_struct *)(dev->board_ptr))
-static int n_pcmad_boards=(sizeof(pcmad_boards)/sizeof(pcmad_boards[0]));
+#define n_pcmad_boards (sizeof(pcmad_boards)/sizeof(pcmad_boards[0]))
 
 struct pcmad_priv_struct{
        int differential;
@@ -78,46 +67,47 @@ struct pcmad_priv_struct{
 };
 #define devpriv ((struct pcmad_priv_struct *)dev->private)
 
+static int pcmad_attach(comedi_device *dev,comedi_devconfig *it);
+static int pcmad_detach(comedi_device *dev);
+comedi_driver driver_pcmad={
+       driver_name:    "pcmad",
+       module:         THIS_MODULE,
+       attach:         pcmad_attach,
+       detach:         pcmad_detach,
+       board_name:     pcmad_boards,
+       num_names:      n_pcmad_boards,
+       offset:         sizeof(pcmad_boards[0]),
+};
+COMEDI_INITCLEANUP(driver_pcmad);
+
 
 #define TIMEOUT        100
 
-static int pcmad_ai_mode0(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
+static int pcmad_ai_insn_read(comedi_device *dev,comedi_subdevice *s,
+       comedi_insn *insn, lsampl_t *data)
 {
-       int i,msb,lsb;
+       int i;
        int chan;
-       int data;
+       int n;
 
-       chan=CR_CHAN(it->chanlist[0]);
+       chan=CR_CHAN(insn->chanspec);
 
-       outb(chan,dev->iobase+PCMAD_CONVERT);
+       for(n=0;n<insn->n;n++){
+               outb(chan,dev->iobase+PCMAD_CONVERT);
 
-       for(i=0;i<TIMEOUT;i++){
-               if((inb(dev->iobase+PCMAD_STATUS)&0x3) == 0x3)
-                       break;
-       }
-       lsb=inb(dev->iobase+PCMAD_LSB);
-       msb=inb(dev->iobase+PCMAD_MSB);
-
-       data=(msb<<8)|(lsb);
+               for(i=0;i<TIMEOUT;i++){
+                       if((inb(dev->iobase+PCMAD_STATUS)&0x3) == 0x3)
+                               break;
+               }
+               data[n]=inb(dev->iobase+PCMAD_LSB);
+               data[n]|=(inb(dev->iobase+PCMAD_MSB)<<8);
 
-       if(devpriv->twos_comp){
-               data ^= (1<<(this_board->n_ai_bits-1));
+               if(devpriv->twos_comp){
+                       data[n] ^= (1<<(this_board->n_ai_bits-1));
+               }
        }
-       it->data[0]=data;
        
-       return 1;
-}
-
-static int pcmad_recognize(char *name)
-{
-       int i;
-
-       for(i=0;i<n_pcmad_boards;i++){
-               if(!strcmp(pcmad_boards[i].name,name))
-                       return i;
-       }
-
-       return -1;
+       return n;
 }
 
 /*
@@ -131,16 +121,16 @@ static int pcmad_attach(comedi_device *dev,comedi_devconfig *it)
 {
        int ret;
        comedi_subdevice *s;
+       int iobase;
 
-       dev->iobase=it->options[0];
-       printk("comedi%d: pcmad: 0x%04x ",dev->minor,dev->iobase);
-       if(check_region(dev->iobase,PCMAD_SIZE)<0){
+       iobase=it->options[0];
+       printk("comedi%d: pcmad: 0x%04x ",dev->minor,iobase);
+       if(check_region(iobase,PCMAD_SIZE)<0){
                printk("I/O port conflict\n");
                return -EIO;
        }
-       request_region(dev->iobase,PCMAD_SIZE,"pcmad");
-       dev->iobase=dev->iobase;
-       dev->iosize=PCMAD_SIZE;
+       request_region(iobase,PCMAD_SIZE,"pcmad");
+       dev->iobase=iobase;
 
        dev->n_subdevices=1;
        if((ret=alloc_subdevices(dev))<0)
@@ -148,14 +138,14 @@ static int pcmad_attach(comedi_device *dev,comedi_devconfig *it)
        if((ret=alloc_private(dev,sizeof(struct pcmad_priv_struct)))<0)
                return ret;
 
-       dev->board_ptr = pcmad_boards+dev->board;
+       dev->board_name = this_board->name;
 
        s=dev->subdevices+0;
        s->type=COMEDI_SUBD_AI;
        s->subdev_flags=SDF_READABLE;
        s->n_chan=16;                   /* XXX */
        s->len_chanlist=1;
-       s->trig[0]=pcmad_ai_mode0;
+       s->insn_read=pcmad_ai_insn_read;
        s->maxdata=(1<<this_board->n_ai_bits)-1;
        s->range_table=&range_unknown;
 
@@ -170,11 +160,9 @@ static int pcmad_detach(comedi_device *dev)
        if(dev->irq){
                free_irq(dev->irq,dev);
        }
-       release_region(dev->iobase,dev->iosize);
+       if(dev->iobase)
+               release_region(dev->iobase,PCMAD_SIZE);
 
        return 0;
 }
 
-
-COMEDI_INITCLEANUP(driver_pcmad);
-