Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/drivers/staging/comedi/drivers/ni_daq_700.c

  1 /*
  2  *     comedi/drivers/ni_daq_700.c
  3  *     Driver for DAQCard-700 DIO/AI
  4  *     copied from 8255
  5  *
  6  *     COMEDI - Linux Control and Measurement Device Interface
  7  *     Copyright (C) 1998 David A. Schleef <ds@schleef.org>
  8  *
  9  *     This program is free software; you can redistribute it and/or modify
 10  *     it under the terms of the GNU General Public License as published by
 11  *     the Free Software Foundation; either version 2 of the License, or
 12  *     (at your option) any later version.
 13  *
 14  *     This program is distributed in the hope that it will be useful,
 15  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 16  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17  *     GNU General Public License for more details.
 18  */
 19 
 20 /*
 21 Driver: ni_daq_700
 22 Description: National Instruments PCMCIA DAQCard-700 DIO only
 23 Author: Fred Brooks <nsaspook@nsaspook.com>,
 24   based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es>
 25 Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700)
 26 Status: works
 27 Updated: Wed, 19 Sep 2012 12:07:20 +0000
 28 
 29 The daqcard-700 appears in Comedi as a  digital I/O subdevice (0) with
 30 16 channels and a analog input subdevice (1) with 16 single-ended channels.
 31 
 32 Digital:  The channel 0 corresponds to the daqcard-700's output
 33 port, bit 0; channel 8 corresponds to the input port, bit 0.
 34 
 35 Digital direction configuration: channels 0-7 output, 8-15 input (8225 device
 36 emu as port A output, port B input, port C N/A).
 37 
 38 Analog: The input  range is 0 to 4095 for -10 to +10 volts
 39 IRQ is assigned but not used.
 40 
 41 Version 0.1     Original DIO only driver
 42 Version 0.2     DIO and basic AI analog input support on 16 se channels
 43 
 44 Manuals:        Register level: http://www.ni.com/pdf/manuals/340698.pdf
 45                 User Manual:    http://www.ni.com/pdf/manuals/320676d.pdf
 46 */
 47 
 48 #include <linux/module.h>
 49 #include <linux/delay.h>
 50 #include <linux/interrupt.h>
 51 
 52 #include "../comedidev.h"
 53 
 54 #include <pcmcia/cistpl.h>
 55 #include <pcmcia/ds.h>
 56 
 57 /* daqcard700 registers */
 58 #define DIO_W           0x04    /* WO 8bit */
 59 #define DIO_R           0x05    /* RO 8bit */
 60 #define CMD_R1          0x00    /* WO 8bit */
 61 #define CMD_R2          0x07    /* RW 8bit */
 62 #define CMD_R3          0x05    /* W0 8bit */
 63 #define STA_R1          0x00    /* RO 8bit */
 64 #define STA_R2          0x01    /* RO 8bit */
 65 #define ADFIFO_R        0x02    /* RO 16bit */
 66 #define ADCLEAR_R       0x01    /* WO 8bit */
 67 #define CDA_R0          0x08    /* RW 8bit */
 68 #define CDA_R1          0x09    /* RW 8bit */
 69 #define CDA_R2          0x0A    /* RW 8bit */
 70 #define CMO_R           0x0B    /* RO 8bit */
 71 #define TIC_R           0x06    /* WO 8bit */
 72 
 73 static int daq700_dio_insn_bits(struct comedi_device *dev,
 74                                 struct comedi_subdevice *s,
 75                                 struct comedi_insn *insn,
 76                                 unsigned int *data)
 77 {
 78         unsigned int mask;
 79         unsigned int val;
 80 
 81         mask = comedi_dio_update_state(s, data);
 82         if (mask) {
 83                 if (mask & 0xff)
 84                         outb(s->state & 0xff, dev->iobase + DIO_W);
 85         }
 86 
 87         val = s->state & 0xff;
 88         val |= inb(dev->iobase + DIO_R) << 8;
 89 
 90         data[1] = val;
 91 
 92         return insn->n;
 93 }
 94 
 95 static int daq700_dio_insn_config(struct comedi_device *dev,
 96                                   struct comedi_subdevice *s,
 97                                   struct comedi_insn *insn,
 98                                   unsigned int *data)
 99 {
100         int ret;
101 
102         ret = comedi_dio_insn_config(dev, s, insn, data, 0);
103         if (ret)
104                 return ret;
105 
106         /* The DIO channels are not configurable, fix the io_bits */
107         s->io_bits = 0x00ff;
108 
109         return insn->n;
110 }
111 
112 static int daq700_ai_eoc(struct comedi_device *dev,
113                          struct comedi_subdevice *s,
114                          struct comedi_insn *insn,
115                          unsigned long context)
116 {
117         unsigned int status;
118 
119         status = inb(dev->iobase + STA_R2);
120         if ((status & 0x03))
121                 return -EOVERFLOW;
122         status = inb(dev->iobase + STA_R1);
123         if ((status & 0x02))
124                 return -ENODATA;
125         if ((status & 0x11) == 0x01)
126                 return 0;
127         return -EBUSY;
128 }
129 
130 static int daq700_ai_rinsn(struct comedi_device *dev,
131                            struct comedi_subdevice *s,
132                            struct comedi_insn *insn, unsigned int *data)
133 {
134         int n, chan;
135         int d;
136         int ret;
137 
138         chan = CR_CHAN(insn->chanspec);
139         /* write channel to multiplexer */
140         /* set mask scan bit high to disable scanning */
141         outb(chan | 0x80, dev->iobase + CMD_R1);
142         /* mux needs 2us to really settle [Fred Brooks]. */
143         udelay(2);
144 
145         /* convert n samples */
146         for (n = 0; n < insn->n; n++) {
147                 /* trigger conversion with out0 L to H */
148                 outb(0x00, dev->iobase + CMD_R2); /* enable ADC conversions */
149                 outb(0x30, dev->iobase + CMO_R); /* mode 0 out0 L, from H */
150                 /* mode 1 out0 H, L to H, start conversion */
151                 outb(0x32, dev->iobase + CMO_R);
152 
153                 /* wait for conversion to end */
154                 ret = comedi_timeout(dev, s, insn, daq700_ai_eoc, 0);
155                 if (ret)
156                         return ret;
157 
158                 /* read data */
159                 d = inw(dev->iobase + ADFIFO_R);
160                 /* mangle the data as necessary */
161                 /* Bipolar Offset Binary: 0 to 4095 for -10 to +10 */
162                 d &= 0x0fff;
163                 d ^= 0x0800;
164                 data[n] = d;
165         }
166         return n;
167 }
168 
169 /*
170  * Data acquisition is enabled.
171  * The counter 0 output is high.
172  * The I/O connector pin CLK1 drives counter 1 source.
173  * Multiple-channel scanning is disabled.
174  * All interrupts are disabled.
175  * The analog input range is set to +-10 V
176  * The analog input mode is single-ended.
177  * The analog input circuitry is initialized to channel 0.
178  * The A/D FIFO is cleared.
179  */
180 static void daq700_ai_config(struct comedi_device *dev,
181                              struct comedi_subdevice *s)
182 {
183         unsigned long iobase = dev->iobase;
184 
185         outb(0x80, iobase + CMD_R1);    /* disable scanning, ADC to chan 0 */
186         outb(0x00, iobase + CMD_R2);    /* clear all bits */
187         outb(0x00, iobase + CMD_R3);    /* set +-10 range */
188         outb(0x32, iobase + CMO_R);     /* config counter mode1, out0 to H */
189         outb(0x00, iobase + TIC_R);     /* clear counter interrupt */
190         outb(0x00, iobase + ADCLEAR_R); /* clear the ADC FIFO */
191         inw(iobase + ADFIFO_R);         /* read 16bit junk from FIFO to clear */
192 }
193 
194 static int daq700_auto_attach(struct comedi_device *dev,
195                               unsigned long context)
196 {
197         struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
198         struct comedi_subdevice *s;
199         int ret;
200 
201         link->config_flags |= CONF_AUTO_SET_IO;
202         ret = comedi_pcmcia_enable(dev, NULL);
203         if (ret)
204                 return ret;
205         dev->iobase = link->resource[0]->start;
206 
207         ret = comedi_alloc_subdevices(dev, 2);
208         if (ret)
209                 return ret;
210 
211         /* DAQCard-700 dio */
212         s = &dev->subdevices[0];
213         s->type         = COMEDI_SUBD_DIO;
214         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
215         s->n_chan       = 16;
216         s->range_table  = &range_digital;
217         s->maxdata      = 1;
218         s->insn_bits    = daq700_dio_insn_bits;
219         s->insn_config  = daq700_dio_insn_config;
220         s->io_bits      = 0x00ff;
221 
222         /* DAQCard-700 ai */
223         s = &dev->subdevices[1];
224         s->type = COMEDI_SUBD_AI;
225         /* we support single-ended (ground)  */
226         s->subdev_flags = SDF_READABLE | SDF_GROUND;
227         s->n_chan = 16;
228         s->maxdata = (1 << 12) - 1;
229         s->range_table = &range_bipolar10;
230         s->insn_read = daq700_ai_rinsn;
231         daq700_ai_config(dev, s);
232 
233         return 0;
234 }
235 
236 static struct comedi_driver daq700_driver = {
237         .driver_name    = "ni_daq_700",
238         .module         = THIS_MODULE,
239         .auto_attach    = daq700_auto_attach,
240         .detach         = comedi_pcmcia_disable,
241 };
242 
243 static int daq700_cs_attach(struct pcmcia_device *link)
244 {
245         return comedi_pcmcia_auto_config(link, &daq700_driver);
246 }
247 
248 static const struct pcmcia_device_id daq700_cs_ids[] = {
249         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743),
250         PCMCIA_DEVICE_NULL
251 };
252 MODULE_DEVICE_TABLE(pcmcia, daq700_cs_ids);
253 
254 static struct pcmcia_driver daq700_cs_driver = {
255         .name           = "ni_daq_700",
256         .owner          = THIS_MODULE,
257         .id_table       = daq700_cs_ids,
258         .probe          = daq700_cs_attach,
259         .remove         = comedi_pcmcia_auto_unconfig,
260 };
261 module_comedi_pcmcia_driver(daq700_driver, daq700_cs_driver);
262 
263 MODULE_AUTHOR("Fred Brooks <nsaspook@nsaspook.com>");
264 MODULE_DESCRIPTION(
265         "Comedi driver for National Instruments PCMCIA DAQCard-700 DIO/AI");
266 MODULE_VERSION("0.2.00");
267 MODULE_LICENSE("GPL");
268 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us