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

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

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