From 510f5d3bd0c17a6d46393b617586907c1bb94d62 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sun, 27 May 2001 23:56:55 +0000 Subject: [PATCH] Merged pcmad driver --- comedi/drivers/Makefile | 2 + comedi/drivers/pcmad.c | 180 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 comedi/drivers/pcmad.c diff --git a/comedi/drivers/Makefile b/comedi/drivers/Makefile index d8d1a53f..68f93416 100644 --- a/comedi/drivers/Makefile +++ b/comedi/drivers/Makefile @@ -60,6 +60,8 @@ obj-$(CONFIG_COMEDI_NI_PCIDIO) += ni_pcidio.o obj-$(CONFIG_COMEDI_MITE) += mite.o obj-$(CONFIG_COMEDI_NI_ATMIO16D) += ni_atmio16d.o +obj-$(CONFIG_COMEDI_PCMAD) += pcmad.o + obj-$(CONFIG_COMEDI_POC) += poc.o obj-$(CONFIG_COMEDI_PCL711) += pcl711.o diff --git a/comedi/drivers/pcmad.c b/comedi/drivers/pcmad.c new file mode 100644 index 00000000..21cd6ba5 --- /dev/null +++ b/comedi/drivers/pcmad.c @@ -0,0 +1,180 @@ +/* + module/pcmad + hardware driver for Winsystems PCM-A/D12 and PCM-A/D16 + + COMEDI - Linux Control and Measurement Device Interface + Copyright (C) 2000 David A. Schleef + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PCMAD_SIZE 4 + +#define PCMAD_STATUS 0 +#define PCMAD_LSB 1 +#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; +}; +struct pcmad_board_struct pcmad_boards[]={ + { + name: "pcmad12", + n_ai_bits: 12, + }, + { + name: "pcmad16", + n_ai_bits: 16, + }, +}; +#define this_board ((struct pcmad_board_struct *)(dev->board_ptr)) +static int n_pcmad_boards=(sizeof(pcmad_boards)/sizeof(pcmad_boards[0])); + +struct pcmad_priv_struct{ + int differential; + int twos_comp; +}; +#define devpriv ((struct pcmad_priv_struct *)dev->private) + + +#define TIMEOUT 100 + +static int pcmad_ai_mode0(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) +{ + int i,msb,lsb; + int chan; + int data; + + chan=CR_CHAN(it->chanlist[0]); + + outb(chan,dev->iobase+PCMAD_CONVERT); + + for(i=0;iiobase+PCMAD_STATUS)&0x3) == 0x3) + break; + } + lsb=inb(dev->iobase+PCMAD_LSB); + msb=inb(dev->iobase+PCMAD_MSB); + + data=(msb<<8)|(lsb); + + if(devpriv->twos_comp){ + data ^= (1<<(this_board->n_ai_bits-1)); + } + it->data[0]=data; + + return 1; +} + +static int pcmad_recognize(char *name) +{ + int i; + + for(i=0;iiobase=it->options[0]; + printk("comedi%d: pcmad: 0x%04x ",dev->minor,dev->iobase); + if(check_region(dev->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; + + dev->n_subdevices=1; + if((ret=alloc_subdevices(dev))<0) + return ret; + if((ret=alloc_private(dev,sizeof(struct pcmad_priv_struct)))<0) + return ret; + + dev->board_ptr = pcmad_boards+dev->board; + + 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->maxdata=(1<n_ai_bits)-1; + s->range_table=&range_unknown; + + return 0; +} + + +static int pcmad_detach(comedi_device *dev) +{ + printk("comedi%d: pcmad: remove\n",dev->minor); + + if(dev->irq){ + free_irq(dev->irq,dev); + } + release_region(dev->iobase,dev->iosize); + + return 0; +} + + +COMEDI_INITCLEANUP(driver_pcmad); + -- 2.26.2