Version:  2.0.40 2.2.26 2.4.37 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 3.17 3.18 3.19 4.0

Linux/drivers/staging/comedi/drivers/quatech_daqp_cs.c

  1 /*======================================================================
  2 
  3     comedi/drivers/quatech_daqp_cs.c
  4 
  5     Quatech DAQP PCMCIA data capture cards COMEDI client driver
  6     Copyright (C) 2000, 2003 Brent Baccala <baccala@freesoft.org>
  7     The DAQP interface code in this file is released into the public domain.
  8 
  9     COMEDI - Linux Control and Measurement Device Interface
 10     Copyright (C) 1998 David A. Schleef <ds@schleef.org>
 11     http://www.comedi.org/
 12 
 13     quatech_daqp_cs.c 1.10
 14 
 15     Documentation for the DAQP PCMCIA cards can be found on Quatech's site:
 16 
 17                 ftp://ftp.quatech.com/Manuals/daqp-208.pdf
 18 
 19     This manual is for both the DAQP-208 and the DAQP-308.
 20 
 21     What works:
 22 
 23         - A/D conversion
 24             - 8 channels
 25             - 4 gain ranges
 26             - ground ref or differential
 27             - single-shot and timed both supported
 28         - D/A conversion, single-shot
 29         - digital I/O
 30 
 31     What doesn't:
 32 
 33         - any kind of triggering - external or D/A channel 1
 34         - the card's optional expansion board
 35         - the card's timer (for anything other than A/D conversion)
 36         - D/A update modes other than immediate (i.e, timed)
 37         - fancier timing modes
 38         - setting card's FIFO buffer thresholds to anything but default
 39 
 40 ======================================================================*/
 41 
 42 /*
 43 Driver: quatech_daqp_cs
 44 Description: Quatech DAQP PCMCIA data capture cards
 45 Author: Brent Baccala <baccala@freesoft.org>
 46 Status: works
 47 Devices: [Quatech] DAQP-208 (daqp), DAQP-308
 48 */
 49 
 50 #include <linux/module.h>
 51 #include <linux/semaphore.h>
 52 #include <linux/completion.h>
 53 
 54 #include "../comedi_pcmcia.h"
 55 #include "comedi_fc.h"
 56 
 57 struct daqp_private {
 58         int stop;
 59 
 60         enum { semaphore, buffer } interrupt_mode;
 61 
 62         struct completion eos;
 63 };
 64 
 65 /* The DAQP communicates with the system through a 16 byte I/O window. */
 66 
 67 #define DAQP_FIFO_SIZE          4096
 68 
 69 #define DAQP_FIFO               0
 70 #define DAQP_SCANLIST           1
 71 #define DAQP_CONTROL            2
 72 #define DAQP_STATUS             2
 73 #define DAQP_DIGITAL_IO         3
 74 #define DAQP_PACER_LOW          4
 75 #define DAQP_PACER_MID          5
 76 #define DAQP_PACER_HIGH         6
 77 #define DAQP_COMMAND            7
 78 #define DAQP_DA                 8
 79 #define DAQP_TIMER              10
 80 #define DAQP_AUX                15
 81 
 82 #define DAQP_SCANLIST_DIFFERENTIAL      0x4000
 83 #define DAQP_SCANLIST_GAIN(x)           ((x)<<12)
 84 #define DAQP_SCANLIST_CHANNEL(x)        ((x)<<8)
 85 #define DAQP_SCANLIST_START             0x0080
 86 #define DAQP_SCANLIST_EXT_GAIN(x)       ((x)<<4)
 87 #define DAQP_SCANLIST_EXT_CHANNEL(x)    (x)
 88 
 89 #define DAQP_CONTROL_PACER_100kHz       0xc0
 90 #define DAQP_CONTROL_PACER_1MHz         0x80
 91 #define DAQP_CONTROL_PACER_5MHz         0x40
 92 #define DAQP_CONTROL_PACER_EXTERNAL     0x00
 93 #define DAQP_CONTORL_EXPANSION          0x20
 94 #define DAQP_CONTROL_EOS_INT_ENABLE     0x10
 95 #define DAQP_CONTROL_FIFO_INT_ENABLE    0x08
 96 #define DAQP_CONTROL_TRIGGER_ONESHOT    0x00
 97 #define DAQP_CONTROL_TRIGGER_CONTINUOUS 0x04
 98 #define DAQP_CONTROL_TRIGGER_INTERNAL   0x00
 99 #define DAQP_CONTROL_TRIGGER_EXTERNAL   0x02
100 #define DAQP_CONTROL_TRIGGER_RISING     0x00
101 #define DAQP_CONTROL_TRIGGER_FALLING    0x01
102 
103 #define DAQP_STATUS_IDLE                0x80
104 #define DAQP_STATUS_RUNNING             0x40
105 #define DAQP_STATUS_EVENTS              0x38
106 #define DAQP_STATUS_DATA_LOST           0x20
107 #define DAQP_STATUS_END_OF_SCAN         0x10
108 #define DAQP_STATUS_FIFO_THRESHOLD      0x08
109 #define DAQP_STATUS_FIFO_FULL           0x04
110 #define DAQP_STATUS_FIFO_NEARFULL       0x02
111 #define DAQP_STATUS_FIFO_EMPTY          0x01
112 
113 #define DAQP_COMMAND_ARM                0x80
114 #define DAQP_COMMAND_RSTF               0x40
115 #define DAQP_COMMAND_RSTQ               0x20
116 #define DAQP_COMMAND_STOP               0x10
117 #define DAQP_COMMAND_LATCH              0x08
118 #define DAQP_COMMAND_100kHz             0x00
119 #define DAQP_COMMAND_50kHz              0x02
120 #define DAQP_COMMAND_25kHz              0x04
121 #define DAQP_COMMAND_FIFO_DATA          0x01
122 #define DAQP_COMMAND_FIFO_PROGRAM       0x00
123 
124 #define DAQP_AUX_TRIGGER_TTL            0x00
125 #define DAQP_AUX_TRIGGER_ANALOG         0x80
126 #define DAQP_AUX_TRIGGER_PRETRIGGER     0x40
127 #define DAQP_AUX_TIMER_INT_ENABLE       0x20
128 #define DAQP_AUX_TIMER_RELOAD           0x00
129 #define DAQP_AUX_TIMER_PAUSE            0x08
130 #define DAQP_AUX_TIMER_GO               0x10
131 #define DAQP_AUX_TIMER_GO_EXTERNAL      0x18
132 #define DAQP_AUX_TIMER_EXTERNAL_SRC     0x04
133 #define DAQP_AUX_TIMER_INTERNAL_SRC     0x00
134 #define DAQP_AUX_DA_DIRECT              0x00
135 #define DAQP_AUX_DA_OVERFLOW            0x01
136 #define DAQP_AUX_DA_EXTERNAL            0x02
137 #define DAQP_AUX_DA_PACER               0x03
138 
139 #define DAQP_AUX_RUNNING                0x80
140 #define DAQP_AUX_TRIGGERED              0x40
141 #define DAQP_AUX_DA_BUFFER              0x20
142 #define DAQP_AUX_TIMER_OVERFLOW         0x10
143 #define DAQP_AUX_CONVERSION             0x08
144 #define DAQP_AUX_DATA_LOST              0x04
145 #define DAQP_AUX_FIFO_NEARFULL          0x02
146 #define DAQP_AUX_FIFO_EMPTY             0x01
147 
148 static const struct comedi_lrange range_daqp_ai = {
149         4, {
150                 BIP_RANGE(10),
151                 BIP_RANGE(5),
152                 BIP_RANGE(2.5),
153                 BIP_RANGE(1.25)
154         }
155 };
156 
157 /* Cancel a running acquisition */
158 
159 static int daqp_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
160 {
161         struct daqp_private *devpriv = dev->private;
162 
163         if (devpriv->stop)
164                 return -EIO;
165 
166         outb(DAQP_COMMAND_STOP, dev->iobase + DAQP_COMMAND);
167 
168         /* flush any linguring data in FIFO - superfluous here */
169         /* outb(DAQP_COMMAND_RSTF, dev->iobase+DAQP_COMMAND); */
170 
171         devpriv->interrupt_mode = semaphore;
172 
173         return 0;
174 }
175 
176 /* Interrupt handler
177  *
178  * Operates in one of two modes.  If devpriv->interrupt_mode is
179  * 'semaphore', just signal the devpriv->eos completion and return
180  * (one-shot mode).  Otherwise (continuous mode), read data in from
181  * the card, transfer it to the buffer provided by the higher-level
182  * comedi kernel module, and signal various comedi callback routines,
183  * which run pretty quick.
184  */
185 static enum irqreturn daqp_interrupt(int irq, void *dev_id)
186 {
187         struct comedi_device *dev = dev_id;
188         struct daqp_private *devpriv = dev->private;
189         struct comedi_subdevice *s = dev->read_subdev;
190         struct comedi_cmd *cmd = &s->async->cmd;
191         int loop_limit = 10000;
192         int status;
193 
194         if (!dev->attached)
195                 return IRQ_NONE;
196 
197         switch (devpriv->interrupt_mode) {
198         case semaphore:
199                 complete(&devpriv->eos);
200                 break;
201 
202         case buffer:
203                 while (!((status = inb(dev->iobase + DAQP_STATUS))
204                          & DAQP_STATUS_FIFO_EMPTY)) {
205                         unsigned short data;
206 
207                         if (status & DAQP_STATUS_DATA_LOST) {
208                                 s->async->events |= COMEDI_CB_OVERFLOW;
209                                 dev_warn(dev->class_dev, "data lost\n");
210                                 break;
211                         }
212 
213                         data = inb(dev->iobase + DAQP_FIFO);
214                         data |= inb(dev->iobase + DAQP_FIFO) << 8;
215                         data ^= 0x8000;
216 
217                         comedi_buf_write_samples(s, &data, 1);
218 
219                         /* If there's a limit, decrement it
220                          * and stop conversion if zero
221                          */
222 
223                         if (cmd->stop_src == TRIG_COUNT &&
224                             s->async->scans_done >= cmd->stop_arg) {
225                                 s->async->events |= COMEDI_CB_EOA;
226                                 break;
227                         }
228 
229                         if ((loop_limit--) <= 0)
230                                 break;
231                 }
232 
233                 if (loop_limit <= 0) {
234                         dev_warn(dev->class_dev,
235                                  "loop_limit reached in daqp_interrupt()\n");
236                         s->async->events |= COMEDI_CB_ERROR;
237                 }
238 
239                 comedi_handle_events(dev, s);
240         }
241         return IRQ_HANDLED;
242 }
243 
244 static void daqp_ai_set_one_scanlist_entry(struct comedi_device *dev,
245                                            unsigned int chanspec,
246                                            int start)
247 {
248         unsigned int chan = CR_CHAN(chanspec);
249         unsigned int range = CR_RANGE(chanspec);
250         unsigned int aref = CR_AREF(chanspec);
251         unsigned int val;
252 
253         val = DAQP_SCANLIST_CHANNEL(chan) | DAQP_SCANLIST_GAIN(range);
254 
255         if (aref == AREF_DIFF)
256                 val |= DAQP_SCANLIST_DIFFERENTIAL;
257 
258         if (start)
259                 val |= DAQP_SCANLIST_START;
260 
261         outb(val & 0xff, dev->iobase + DAQP_SCANLIST);
262         outb((val >> 8) & 0xff, dev->iobase + DAQP_SCANLIST);
263 }
264 
265 /* One-shot analog data acquisition routine */
266 
267 static int daqp_ai_insn_read(struct comedi_device *dev,
268                              struct comedi_subdevice *s,
269                              struct comedi_insn *insn, unsigned int *data)
270 {
271         struct daqp_private *devpriv = dev->private;
272         int i;
273         int v;
274         int counter = 10000;
275 
276         if (devpriv->stop)
277                 return -EIO;
278 
279         /* Stop any running conversion */
280         daqp_ai_cancel(dev, s);
281 
282         outb(0, dev->iobase + DAQP_AUX);
283 
284         /* Reset scan list queue */
285         outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
286 
287         /* Program one scan list entry */
288         daqp_ai_set_one_scanlist_entry(dev, insn->chanspec, 1);
289 
290         /* Reset data FIFO (see page 28 of DAQP User's Manual) */
291 
292         outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
293 
294         /* Set trigger */
295 
296         v = DAQP_CONTROL_TRIGGER_ONESHOT | DAQP_CONTROL_TRIGGER_INTERNAL
297             | DAQP_CONTROL_PACER_100kHz | DAQP_CONTROL_EOS_INT_ENABLE;
298 
299         outb(v, dev->iobase + DAQP_CONTROL);
300 
301         /* Reset any pending interrupts (my card has a tendency to require
302          * require multiple reads on the status register to achieve this)
303          */
304 
305         while (--counter
306                && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS))
307                 ;
308         if (!counter) {
309                 dev_err(dev->class_dev,
310                         "couldn't clear interrupts in status register\n");
311                 return -1;
312         }
313 
314         init_completion(&devpriv->eos);
315         devpriv->interrupt_mode = semaphore;
316 
317         for (i = 0; i < insn->n; i++) {
318 
319                 /* Start conversion */
320                 outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
321                      dev->iobase + DAQP_COMMAND);
322 
323                 /* Wait for interrupt service routine to unblock completion */
324                 /* Maybe could use a timeout here, but it's interruptible */
325                 if (wait_for_completion_interruptible(&devpriv->eos))
326                         return -EINTR;
327 
328                 data[i] = inb(dev->iobase + DAQP_FIFO);
329                 data[i] |= inb(dev->iobase + DAQP_FIFO) << 8;
330                 data[i] ^= 0x8000;
331         }
332 
333         return insn->n;
334 }
335 
336 /* This function converts ns nanoseconds to a counter value suitable
337  * for programming the device.  We always use the DAQP's 5 MHz clock,
338  * which with its 24-bit counter, allows values up to 84 seconds.
339  * Also, the function adjusts ns so that it cooresponds to the actual
340  * time that the device will use.
341  */
342 
343 static int daqp_ns_to_timer(unsigned int *ns, unsigned int flags)
344 {
345         int timer;
346 
347         timer = *ns / 200;
348         *ns = timer * 200;
349 
350         return timer;
351 }
352 
353 /* cmdtest tests a particular command to see if it is valid.
354  * Using the cmdtest ioctl, a user can create a valid cmd
355  * and then have it executed by the cmd ioctl.
356  *
357  * cmdtest returns 1,2,3,4 or 0, depending on which tests
358  * the command passes.
359  */
360 
361 static int daqp_ai_cmdtest(struct comedi_device *dev,
362                            struct comedi_subdevice *s, struct comedi_cmd *cmd)
363 {
364         int err = 0;
365         unsigned int arg;
366 
367         /* Step 1 : check if triggers are trivially valid */
368 
369         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
370         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
371                                         TRIG_TIMER | TRIG_FOLLOW);
372         err |= cfc_check_trigger_src(&cmd->convert_src,
373                                         TRIG_TIMER | TRIG_NOW);
374         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
375         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
376 
377         if (err)
378                 return 1;
379 
380         /* Step 2a : make sure trigger sources are unique */
381 
382         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
383         err |= cfc_check_trigger_is_unique(cmd->convert_src);
384         err |= cfc_check_trigger_is_unique(cmd->stop_src);
385 
386         /* Step 2b : and mutually compatible */
387 
388         if (err)
389                 return 2;
390 
391         /* Step 3: check if arguments are trivially valid */
392 
393         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
394 
395 #define MAX_SPEED       10000   /* 100 kHz - in nanoseconds */
396 
397         if (cmd->scan_begin_src == TRIG_TIMER)
398                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
399                                                  MAX_SPEED);
400 
401         /* If both scan_begin and convert are both timer values, the only
402          * way that can make sense is if the scan time is the number of
403          * conversions times the convert time
404          */
405 
406         if (cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER
407             && cmd->scan_begin_arg != cmd->convert_arg * cmd->scan_end_arg) {
408                 err |= -EINVAL;
409         }
410 
411         if (cmd->convert_src == TRIG_TIMER)
412                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED);
413 
414         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
415 
416         if (cmd->stop_src == TRIG_COUNT)
417                 err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
418         else    /* TRIG_NONE */
419                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
420 
421         if (err)
422                 return 3;
423 
424         /* step 4: fix up any arguments */
425 
426         if (cmd->scan_begin_src == TRIG_TIMER) {
427                 arg = cmd->scan_begin_arg;
428                 daqp_ns_to_timer(&arg, cmd->flags);
429                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
430         }
431 
432         if (cmd->convert_src == TRIG_TIMER) {
433                 arg = cmd->convert_arg;
434                 daqp_ns_to_timer(&arg, cmd->flags);
435                 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
436         }
437 
438         if (err)
439                 return 4;
440 
441         return 0;
442 }
443 
444 static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
445 {
446         struct daqp_private *devpriv = dev->private;
447         struct comedi_cmd *cmd = &s->async->cmd;
448         int counter;
449         int scanlist_start_on_every_entry;
450         int threshold;
451 
452         int i;
453         int v;
454 
455         if (devpriv->stop)
456                 return -EIO;
457 
458         /* Stop any running conversion */
459         daqp_ai_cancel(dev, s);
460 
461         outb(0, dev->iobase + DAQP_AUX);
462 
463         /* Reset scan list queue */
464         outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
465 
466         /* Program pacer clock
467          *
468          * There's two modes we can operate in.  If convert_src is
469          * TRIG_TIMER, then convert_arg specifies the time between
470          * each conversion, so we program the pacer clock to that
471          * frequency and set the SCANLIST_START bit on every scanlist
472          * entry.  Otherwise, convert_src is TRIG_NOW, which means
473          * we want the fastest possible conversions, scan_begin_src
474          * is TRIG_TIMER, and scan_begin_arg specifies the time between
475          * each scan, so we program the pacer clock to this frequency
476          * and only set the SCANLIST_START bit on the first entry.
477          */
478 
479         if (cmd->convert_src == TRIG_TIMER) {
480                 counter = daqp_ns_to_timer(&cmd->convert_arg, cmd->flags);
481                 outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
482                 outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
483                 outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
484                 scanlist_start_on_every_entry = 1;
485         } else {
486                 counter = daqp_ns_to_timer(&cmd->scan_begin_arg, cmd->flags);
487                 outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
488                 outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
489                 outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
490                 scanlist_start_on_every_entry = 0;
491         }
492 
493         /* Program scan list */
494         for (i = 0; i < cmd->chanlist_len; i++) {
495                 int start = (i == 0 || scanlist_start_on_every_entry);
496 
497                 daqp_ai_set_one_scanlist_entry(dev, cmd->chanlist[i], start);
498         }
499 
500         /* Now it's time to program the FIFO threshold, basically the
501          * number of samples the card will buffer before it interrupts
502          * the CPU.
503          *
504          * If we don't have a stop count, then use half the size of
505          * the FIFO (the manufacturer's recommendation).  Consider
506          * that the FIFO can hold 2K samples (4K bytes).  With the
507          * threshold set at half the FIFO size, we have a margin of
508          * error of 1024 samples.  At the chip's maximum sample rate
509          * of 100,000 Hz, the CPU would have to delay interrupt
510          * service for a full 10 milliseconds in order to lose data
511          * here (as opposed to higher up in the kernel).  I've never
512          * seen it happen.  However, for slow sample rates it may
513          * buffer too much data and introduce too much delay for the
514          * user application.
515          *
516          * If we have a stop count, then things get more interesting.
517          * If the stop count is less than the FIFO size (actually
518          * three-quarters of the FIFO size - see below), we just use
519          * the stop count itself as the threshold, the card interrupts
520          * us when that many samples have been taken, and we kill the
521          * acquisition at that point and are done.  If the stop count
522          * is larger than that, then we divide it by 2 until it's less
523          * than three quarters of the FIFO size (we always leave the
524          * top quarter of the FIFO as protection against sluggish CPU
525          * interrupt response) and use that as the threshold.  So, if
526          * the stop count is 4000 samples, we divide by two twice to
527          * get 1000 samples, use that as the threshold, take four
528          * interrupts to get our 4000 samples and are done.
529          *
530          * The algorithm could be more clever.  For example, if 81000
531          * samples are requested, we could set the threshold to 1500
532          * samples and take 54 interrupts to get 81000.  But 54 isn't
533          * a power of two, so this algorithm won't find that option.
534          * Instead, it'll set the threshold at 1266 and take 64
535          * interrupts to get 81024 samples, of which the last 24 will
536          * be discarded... but we won't get the last interrupt until
537          * they've been collected.  To find the first option, the
538          * computer could look at the prime decomposition of the
539          * sample count (81000 = 3^4 * 5^3 * 2^3) and factor it into a
540          * threshold (1500 = 3 * 5^3 * 2^2) and an interrupt count (54
541          * = 3^3 * 2).  Hmmm... a one-line while loop or prime
542          * decomposition of integers... I'll leave it the way it is.
543          *
544          * I'll also note a mini-race condition before ignoring it in
545          * the code.  Let's say we're taking 4000 samples, as before.
546          * After 1000 samples, we get an interrupt.  But before that
547          * interrupt is completely serviced, another sample is taken
548          * and loaded into the FIFO.  Since the interrupt handler
549          * empties the FIFO before returning, it will read 1001 samples.
550          * If that happens four times, we'll end up taking 4004 samples,
551          * not 4000.  The interrupt handler will discard the extra four
552          * samples (by halting the acquisition with four samples still
553          * in the FIFO), but we will have to wait for them.
554          *
555          * In short, this code works pretty well, but for either of
556          * the two reasons noted, might end up waiting for a few more
557          * samples than actually requested.  Shouldn't make too much
558          * of a difference.
559          */
560 
561         /* Save away the number of conversions we should perform, and
562          * compute the FIFO threshold (in bytes, not samples - that's
563          * why we multiple devpriv->count by 2 = sizeof(sample))
564          */
565 
566         if (cmd->stop_src == TRIG_COUNT) {
567                 unsigned long long nsamples;
568                 unsigned long long nbytes;
569 
570                 nsamples = (unsigned long long)cmd->stop_arg *
571                            cmd->scan_end_arg;
572                 nbytes = nsamples * comedi_bytes_per_sample(s);
573                 while (nbytes > DAQP_FIFO_SIZE * 3 / 4)
574                         nbytes /= 2;
575                 threshold = nbytes;
576         } else {
577                 threshold = DAQP_FIFO_SIZE / 2;
578         }
579 
580         /* Reset data FIFO (see page 28 of DAQP User's Manual) */
581 
582         outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
583 
584         /* Set FIFO threshold.  First two bytes are near-empty
585          * threshold, which is unused; next two bytes are near-full
586          * threshold.  We computed the number of bytes we want in the
587          * FIFO when the interrupt is generated, what the card wants
588          * is actually the number of available bytes left in the FIFO
589          * when the interrupt is to happen.
590          */
591 
592         outb(0x00, dev->iobase + DAQP_FIFO);
593         outb(0x00, dev->iobase + DAQP_FIFO);
594 
595         outb((DAQP_FIFO_SIZE - threshold) & 0xff, dev->iobase + DAQP_FIFO);
596         outb((DAQP_FIFO_SIZE - threshold) >> 8, dev->iobase + DAQP_FIFO);
597 
598         /* Set trigger */
599 
600         v = DAQP_CONTROL_TRIGGER_CONTINUOUS | DAQP_CONTROL_TRIGGER_INTERNAL
601             | DAQP_CONTROL_PACER_5MHz | DAQP_CONTROL_FIFO_INT_ENABLE;
602 
603         outb(v, dev->iobase + DAQP_CONTROL);
604 
605         /* Reset any pending interrupts (my card has a tendency to require
606          * require multiple reads on the status register to achieve this)
607          */
608         counter = 100;
609         while (--counter
610                && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS))
611                 ;
612         if (!counter) {
613                 dev_err(dev->class_dev,
614                         "couldn't clear interrupts in status register\n");
615                 return -1;
616         }
617 
618         devpriv->interrupt_mode = buffer;
619 
620         /* Start conversion */
621         outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
622              dev->iobase + DAQP_COMMAND);
623 
624         return 0;
625 }
626 
627 static int daqp_ao_insn_write(struct comedi_device *dev,
628                               struct comedi_subdevice *s,
629                               struct comedi_insn *insn,
630                               unsigned int *data)
631 {
632         struct daqp_private *devpriv = dev->private;
633         unsigned int chan = CR_CHAN(insn->chanspec);
634         int i;
635 
636         if (devpriv->stop)
637                 return -EIO;
638 
639         /* Make sure D/A update mode is direct update */
640         outb(0, dev->iobase + DAQP_AUX);
641 
642         for (i = 0; i > insn->n; i++) {
643                 unsigned val = data[i];
644 
645                 s->readback[chan] = val;
646 
647                 val &= 0x0fff;
648                 val ^= 0x0800;          /* Flip the sign */
649                 val |= (chan << 12);
650 
651                 outw(val, dev->iobase + DAQP_DA);
652         }
653 
654         return insn->n;
655 }
656 
657 static int daqp_di_insn_bits(struct comedi_device *dev,
658                              struct comedi_subdevice *s,
659                              struct comedi_insn *insn,
660                              unsigned int *data)
661 {
662         struct daqp_private *devpriv = dev->private;
663 
664         if (devpriv->stop)
665                 return -EIO;
666 
667         data[0] = inb(dev->iobase + DAQP_DIGITAL_IO);
668 
669         return insn->n;
670 }
671 
672 static int daqp_do_insn_bits(struct comedi_device *dev,
673                              struct comedi_subdevice *s,
674                              struct comedi_insn *insn,
675                              unsigned int *data)
676 {
677         struct daqp_private *devpriv = dev->private;
678 
679         if (devpriv->stop)
680                 return -EIO;
681 
682         if (comedi_dio_update_state(s, data))
683                 outb(s->state, dev->iobase + DAQP_DIGITAL_IO);
684 
685         data[1] = s->state;
686 
687         return insn->n;
688 }
689 
690 static int daqp_auto_attach(struct comedi_device *dev,
691                             unsigned long context)
692 {
693         struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
694         struct daqp_private *devpriv;
695         struct comedi_subdevice *s;
696         int ret;
697 
698         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
699         if (!devpriv)
700                 return -ENOMEM;
701 
702         link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
703         ret = comedi_pcmcia_enable(dev, NULL);
704         if (ret)
705                 return ret;
706         dev->iobase = link->resource[0]->start;
707 
708         link->priv = dev;
709         ret = pcmcia_request_irq(link, daqp_interrupt);
710         if (ret)
711                 return ret;
712 
713         ret = comedi_alloc_subdevices(dev, 4);
714         if (ret)
715                 return ret;
716 
717         s = &dev->subdevices[0];
718         dev->read_subdev = s;
719         s->type         = COMEDI_SUBD_AI;
720         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
721         s->n_chan       = 8;
722         s->len_chanlist = 2048;
723         s->maxdata      = 0xffff;
724         s->range_table  = &range_daqp_ai;
725         s->insn_read    = daqp_ai_insn_read;
726         s->do_cmdtest   = daqp_ai_cmdtest;
727         s->do_cmd       = daqp_ai_cmd;
728         s->cancel       = daqp_ai_cancel;
729 
730         s = &dev->subdevices[1];
731         s->type         = COMEDI_SUBD_AO;
732         s->subdev_flags = SDF_WRITABLE;
733         s->n_chan       = 2;
734         s->maxdata      = 0x0fff;
735         s->range_table  = &range_bipolar5;
736         s->insn_write   = daqp_ao_insn_write;
737 
738         ret = comedi_alloc_subdev_readback(s);
739         if (ret)
740                 return ret;
741 
742         s = &dev->subdevices[2];
743         s->type         = COMEDI_SUBD_DI;
744         s->subdev_flags = SDF_READABLE;
745         s->n_chan       = 1;
746         s->maxdata      = 1;
747         s->insn_bits    = daqp_di_insn_bits;
748 
749         s = &dev->subdevices[3];
750         s->type         = COMEDI_SUBD_DO;
751         s->subdev_flags = SDF_WRITABLE;
752         s->n_chan       = 1;
753         s->maxdata      = 1;
754         s->insn_bits    = daqp_do_insn_bits;
755 
756         return 0;
757 }
758 
759 static struct comedi_driver driver_daqp = {
760         .driver_name    = "quatech_daqp_cs",
761         .module         = THIS_MODULE,
762         .auto_attach    = daqp_auto_attach,
763         .detach         = comedi_pcmcia_disable,
764 };
765 
766 static int daqp_cs_suspend(struct pcmcia_device *link)
767 {
768         struct comedi_device *dev = link->priv;
769         struct daqp_private *devpriv = dev ? dev->private : NULL;
770 
771         /* Mark the device as stopped, to block IO until later */
772         if (devpriv)
773                 devpriv->stop = 1;
774 
775         return 0;
776 }
777 
778 static int daqp_cs_resume(struct pcmcia_device *link)
779 {
780         struct comedi_device *dev = link->priv;
781         struct daqp_private *devpriv = dev ? dev->private : NULL;
782 
783         if (devpriv)
784                 devpriv->stop = 0;
785 
786         return 0;
787 }
788 
789 static int daqp_cs_attach(struct pcmcia_device *link)
790 {
791         return comedi_pcmcia_auto_config(link, &driver_daqp);
792 }
793 
794 static const struct pcmcia_device_id daqp_cs_id_table[] = {
795         PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0027),
796         PCMCIA_DEVICE_NULL
797 };
798 MODULE_DEVICE_TABLE(pcmcia, daqp_cs_id_table);
799 
800 static struct pcmcia_driver daqp_cs_driver = {
801         .name           = "quatech_daqp_cs",
802         .owner          = THIS_MODULE,
803         .id_table       = daqp_cs_id_table,
804         .probe          = daqp_cs_attach,
805         .remove         = comedi_pcmcia_auto_unconfig,
806         .suspend        = daqp_cs_suspend,
807         .resume         = daqp_cs_resume,
808 };
809 module_comedi_pcmcia_driver(driver_daqp, daqp_cs_driver);
810 
811 MODULE_DESCRIPTION("Comedi driver for Quatech DAQP PCMCIA data capture cards");
812 MODULE_AUTHOR("Brent Baccala <baccala@freesoft.org>");
813 MODULE_LICENSE("GPL");
814 

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