Version:  2.0.40 2.2.26 2.4.37 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7

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

  1 /*
  2  * quatech_daqp_cs.c
  3  * Quatech DAQP PCMCIA data capture cards COMEDI client driver
  4  * Copyright (C) 2000, 2003 Brent Baccala <baccala@freesoft.org>
  5  * The DAQP interface code in this file is released into the public domain.
  6  *
  7  * COMEDI - Linux Control and Measurement Device Interface
  8  * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
  9  * http://www.comedi.org/
 10  *
 11  * Documentation for the DAQP PCMCIA cards can be found on Quatech's site:
 12  *      ftp://ftp.quatech.com/Manuals/daqp-208.pdf
 13  *
 14  * This manual is for both the DAQP-208 and the DAQP-308.
 15  *
 16  * What works:
 17  * - A/D conversion
 18  *      - 8 channels
 19  *      - 4 gain ranges
 20  *      - ground ref or differential
 21  *      - single-shot and timed both supported
 22  * - D/A conversion, single-shot
 23  * - digital I/O
 24  *
 25  * What doesn't:
 26  * - any kind of triggering - external or D/A channel 1
 27  * - the card's optional expansion board
 28  * - the card's timer (for anything other than A/D conversion)
 29  * - D/A update modes other than immediate (i.e, timed)
 30  * - fancier timing modes
 31  * - setting card's FIFO buffer thresholds to anything but default
 32  */
 33 
 34 /*
 35  * Driver: quatech_daqp_cs
 36  * Description: Quatech DAQP PCMCIA data capture cards
 37  * Devices: [Quatech] DAQP-208 (daqp), DAQP-308
 38  * Author: Brent Baccala <baccala@freesoft.org>
 39  * Status: works
 40  */
 41 
 42 #include <linux/module.h>
 43 
 44 #include "../comedi_pcmcia.h"
 45 
 46 /*
 47  * Register I/O map
 48  *
 49  * The D/A and timer registers can be accessed with 16-bit or 8-bit I/O
 50  * instructions. All other registers can only use 8-bit instructions.
 51  *
 52  * The FIFO and scanlist registers require two 8-bit instructions to
 53  * access the 16-bit data. Data is transferred LSB then MSB.
 54  */
 55 #define DAQP_AI_FIFO_REG                0x00
 56 
 57 #define DAQP_SCANLIST_REG               0x01
 58 #define DAQP_SCANLIST_DIFFERENTIAL      BIT(14)
 59 #define DAQP_SCANLIST_GAIN(x)           (((x) & 0x3) << 12)
 60 #define DAQP_SCANLIST_CHANNEL(x)        (((x) & 0xf) << 8)
 61 #define DAQP_SCANLIST_START             BIT(7)
 62 #define DAQP_SCANLIST_EXT_GAIN(x)       (((x) & 0x3) << 4)
 63 #define DAQP_SCANLIST_EXT_CHANNEL(x)    (((x) & 0xf) << 0)
 64 
 65 #define DAQP_CTRL_REG                   0x02
 66 #define DAQP_CTRL_PACER_CLK(x)          (((x) & 0x3) << 6)
 67 #define DAQP_CTRL_PACER_CLK_EXT         DAQP_CTRL_PACER_CLK(0)
 68 #define DAQP_CTRL_PACER_CLK_5MHZ        DAQP_CTRL_PACER_CLK(1)
 69 #define DAQP_CTRL_PACER_CLK_1MHZ        DAQP_CTRL_PACER_CLK(2)
 70 #define DAQP_CTRL_PACER_CLK_100KHZ      DAQP_CTRL_PACER_CLK(3)
 71 #define DAQP_CTRL_EXPANSION             BIT(5)
 72 #define DAQP_CTRL_EOS_INT_ENA           BIT(4)
 73 #define DAQP_CTRL_FIFO_INT_ENA          BIT(3)
 74 #define DAQP_CTRL_TRIG_MODE             BIT(2)  /* 0=one-shot; 1=continuous */
 75 #define DAQP_CTRL_TRIG_SRC              BIT(1)  /* 0=internal; 1=external */
 76 #define DAQP_CTRL_TRIG_EDGE             BIT(0)  /* 0=rising; 1=falling */
 77 
 78 #define DAQP_STATUS_REG                 0x02
 79 #define DAQP_STATUS_IDLE                BIT(7)
 80 #define DAQP_STATUS_RUNNING             BIT(6)
 81 #define DAQP_STATUS_DATA_LOST           BIT(5)
 82 #define DAQP_STATUS_END_OF_SCAN         BIT(4)
 83 #define DAQP_STATUS_FIFO_THRESHOLD      BIT(3)
 84 #define DAQP_STATUS_FIFO_FULL           BIT(2)
 85 #define DAQP_STATUS_FIFO_NEARFULL       BIT(1)
 86 #define DAQP_STATUS_FIFO_EMPTY          BIT(0)
 87 /* these bits clear when the status register is read */
 88 #define DAQP_STATUS_EVENTS              (DAQP_STATUS_DATA_LOST |        \
 89                                          DAQP_STATUS_END_OF_SCAN |      \
 90                                          DAQP_STATUS_FIFO_THRESHOLD)
 91 
 92 #define DAQP_DI_REG                     0x03
 93 #define DAQP_DO_REG                     0x03
 94 
 95 #define DAQP_PACER_LOW_REG              0x04
 96 #define DAQP_PACER_MID_REG              0x05
 97 #define DAQP_PACER_HIGH_REG             0x06
 98 
 99 #define DAQP_CMD_REG                    0x07
100 /* the monostable bits are self-clearing after the function is complete */
101 #define DAQP_CMD_ARM                    BIT(7)  /* monostable */
102 #define DAQP_CMD_RSTF                   BIT(6)  /* monostable */
103 #define DAQP_CMD_RSTQ                   BIT(5)  /* monostable */
104 #define DAQP_CMD_STOP                   BIT(4)  /* monostable */
105 #define DAQP_CMD_LATCH                  BIT(3)  /* monostable */
106 #define DAQP_CMD_SCANRATE(x)            (((x) & 0x3) << 1)
107 #define DAQP_CMD_SCANRATE_100KHZ        DAQP_CMD_SCANRATE(0)
108 #define DAQP_CMD_SCANRATE_50KHZ         DAQP_CMD_SCANRATE(1)
109 #define DAQP_CMD_SCANRATE_25KHZ         DAQP_CMD_SCANRATE(2)
110 #define DAQP_CMD_FIFO_DATA              BIT(0)
111 
112 #define DAQP_AO_REG                     0x08    /* and 0x09 (16-bit) */
113 
114 #define DAQP_TIMER_REG                  0x0a    /* and 0x0b (16-bit) */
115 
116 #define DAQP_AUX_REG                    0x0f
117 /* Auxiliary Control register bits (write) */
118 #define DAQP_AUX_EXT_ANALOG_TRIG        BIT(7)
119 #define DAQP_AUX_PRETRIG                BIT(6)
120 #define DAQP_AUX_TIMER_INT_ENA          BIT(5)
121 #define DAQP_AUX_TIMER_MODE(x)          (((x) & 0x3) << 3)
122 #define DAQP_AUX_TIMER_MODE_RELOAD      DAQP_AUX_TIMER_MODE(0)
123 #define DAQP_AUX_TIMER_MODE_PAUSE       DAQP_AUX_TIMER_MODE(1)
124 #define DAQP_AUX_TIMER_MODE_GO          DAQP_AUX_TIMER_MODE(2)
125 #define DAQP_AUX_TIMER_MODE_EXT         DAQP_AUX_TIMER_MODE(3)
126 #define DAQP_AUX_TIMER_CLK_SRC_EXT      BIT(2)
127 #define DAQP_AUX_DA_UPDATE(x)           (((x) & 0x3) << 0)
128 #define DAQP_AUX_DA_UPDATE_DIRECT       DAQP_AUX_DA_UPDATE(0)
129 #define DAQP_AUX_DA_UPDATE_OVERFLOW     DAQP_AUX_DA_UPDATE(1)
130 #define DAQP_AUX_DA_UPDATE_EXTERNAL     DAQP_AUX_DA_UPDATE(2)
131 #define DAQP_AUX_DA_UPDATE_PACER        DAQP_AUX_DA_UPDATE(3)
132 /* Auxiliary Status register bits (read) */
133 #define DAQP_AUX_RUNNING                BIT(7)
134 #define DAQP_AUX_TRIGGERED              BIT(6)
135 #define DAQP_AUX_DA_BUFFER              BIT(5)
136 #define DAQP_AUX_TIMER_OVERFLOW         BIT(4)
137 #define DAQP_AUX_CONVERSION             BIT(3)
138 #define DAQP_AUX_DATA_LOST              BIT(2)
139 #define DAQP_AUX_FIFO_NEARFULL          BIT(1)
140 #define DAQP_AUX_FIFO_EMPTY             BIT(0)
141 
142 #define DAQP_FIFO_SIZE                  4096
143 
144 #define DAQP_MAX_TIMER_SPEED            10000   /* 100 kHz in nanoseconds */
145 
146 struct daqp_private {
147         unsigned int pacer_div;
148         int stop;
149 };
150 
151 static const struct comedi_lrange range_daqp_ai = {
152         4, {
153                 BIP_RANGE(10),
154                 BIP_RANGE(5),
155                 BIP_RANGE(2.5),
156                 BIP_RANGE(1.25)
157         }
158 };
159 
160 static int daqp_clear_events(struct comedi_device *dev, int loops)
161 {
162         unsigned int status;
163 
164         /*
165          * Reset any pending interrupts (my card has a tendency to require
166          * require multiple reads on the status register to achieve this).
167          */
168         while (--loops) {
169                 status = inb(dev->iobase + DAQP_STATUS_REG);
170                 if ((status & DAQP_STATUS_EVENTS) == 0)
171                         return 0;
172         }
173         dev_err(dev->class_dev, "couldn't clear events in status register\n");
174         return -EBUSY;
175 }
176 
177 static int daqp_ai_cancel(struct comedi_device *dev,
178                           struct comedi_subdevice *s)
179 {
180         struct daqp_private *devpriv = dev->private;
181 
182         if (devpriv->stop)
183                 return -EIO;
184 
185         /*
186          * Stop any conversions, disable interrupts, and clear
187          * the status event flags.
188          */
189         outb(DAQP_CMD_STOP, dev->iobase + DAQP_CMD_REG);
190         outb(0, dev->iobase + DAQP_CTRL_REG);
191         inb(dev->iobase + DAQP_STATUS_REG);
192 
193         return 0;
194 }
195 
196 static unsigned int daqp_ai_get_sample(struct comedi_device *dev,
197                                        struct comedi_subdevice *s)
198 {
199         unsigned int val;
200 
201         /*
202          * Get a two's complement sample from the FIFO and
203          * return the munged offset binary value.
204          */
205         val = inb(dev->iobase + DAQP_AI_FIFO_REG);
206         val |= inb(dev->iobase + DAQP_AI_FIFO_REG) << 8;
207         return comedi_offset_munge(s, val);
208 }
209 
210 static irqreturn_t daqp_interrupt(int irq, void *dev_id)
211 {
212         struct comedi_device *dev = dev_id;
213         struct comedi_subdevice *s = dev->read_subdev;
214         struct comedi_cmd *cmd = &s->async->cmd;
215         int loop_limit = 10000;
216         int status;
217 
218         if (!dev->attached)
219                 return IRQ_NONE;
220 
221         status = inb(dev->iobase + DAQP_STATUS_REG);
222         if (!(status & DAQP_STATUS_EVENTS))
223                 return IRQ_NONE;
224 
225         while (!(status & DAQP_STATUS_FIFO_EMPTY)) {
226                 unsigned short data;
227 
228                 if (status & DAQP_STATUS_DATA_LOST) {
229                         s->async->events |= COMEDI_CB_OVERFLOW;
230                         dev_warn(dev->class_dev, "data lost\n");
231                         break;
232                 }
233 
234                 data = daqp_ai_get_sample(dev, s);
235                 comedi_buf_write_samples(s, &data, 1);
236 
237                 if (cmd->stop_src == TRIG_COUNT &&
238                     s->async->scans_done >= cmd->stop_arg) {
239                         s->async->events |= COMEDI_CB_EOA;
240                         break;
241                 }
242 
243                 if ((loop_limit--) <= 0)
244                         break;
245 
246                 status = inb(dev->iobase + DAQP_STATUS_REG);
247         }
248 
249         if (loop_limit <= 0) {
250                 dev_warn(dev->class_dev,
251                          "loop_limit reached in daqp_interrupt()\n");
252                 s->async->events |= COMEDI_CB_ERROR;
253         }
254 
255         comedi_handle_events(dev, s);
256 
257         return IRQ_HANDLED;
258 }
259 
260 static void daqp_ai_set_one_scanlist_entry(struct comedi_device *dev,
261                                            unsigned int chanspec,
262                                            int start)
263 {
264         unsigned int chan = CR_CHAN(chanspec);
265         unsigned int range = CR_RANGE(chanspec);
266         unsigned int aref = CR_AREF(chanspec);
267         unsigned int val;
268 
269         val = DAQP_SCANLIST_CHANNEL(chan) | DAQP_SCANLIST_GAIN(range);
270 
271         if (aref == AREF_DIFF)
272                 val |= DAQP_SCANLIST_DIFFERENTIAL;
273 
274         if (start)
275                 val |= DAQP_SCANLIST_START;
276 
277         outb(val & 0xff, dev->iobase + DAQP_SCANLIST_REG);
278         outb((val >> 8) & 0xff, dev->iobase + DAQP_SCANLIST_REG);
279 }
280 
281 static int daqp_ai_eos(struct comedi_device *dev,
282                        struct comedi_subdevice *s,
283                        struct comedi_insn *insn,
284                        unsigned long context)
285 {
286         unsigned int status;
287 
288         status = inb(dev->iobase + DAQP_AUX_REG);
289         if (status & DAQP_AUX_CONVERSION)
290                 return 0;
291         return -EBUSY;
292 }
293 
294 static int daqp_ai_insn_read(struct comedi_device *dev,
295                              struct comedi_subdevice *s,
296                              struct comedi_insn *insn,
297                              unsigned int *data)
298 {
299         struct daqp_private *devpriv = dev->private;
300         int ret = 0;
301         int i;
302 
303         if (devpriv->stop)
304                 return -EIO;
305 
306         outb(0, dev->iobase + DAQP_AUX_REG);
307 
308         /* Reset scan list queue */
309         outb(DAQP_CMD_RSTQ, dev->iobase + DAQP_CMD_REG);
310 
311         /* Program one scan list entry */
312         daqp_ai_set_one_scanlist_entry(dev, insn->chanspec, 1);
313 
314         /* Reset data FIFO (see page 28 of DAQP User's Manual) */
315         outb(DAQP_CMD_RSTF, dev->iobase + DAQP_CMD_REG);
316 
317         /* Set trigger - one-shot, internal, no interrupts */
318         outb(DAQP_CTRL_PACER_CLK_100KHZ, dev->iobase + DAQP_CTRL_REG);
319 
320         ret = daqp_clear_events(dev, 10000);
321         if (ret)
322                 return ret;
323 
324         for (i = 0; i < insn->n; i++) {
325                 /* Start conversion */
326                 outb(DAQP_CMD_ARM | DAQP_CMD_FIFO_DATA,
327                      dev->iobase + DAQP_CMD_REG);
328 
329                 ret = comedi_timeout(dev, s, insn, daqp_ai_eos, 0);
330                 if (ret)
331                         break;
332 
333                 /* clear the status event flags */
334                 inb(dev->iobase + DAQP_STATUS_REG);
335 
336                 data[i] = daqp_ai_get_sample(dev, s);
337         }
338 
339         /* stop any conversions and clear the status event flags */
340         outb(DAQP_CMD_STOP, dev->iobase + DAQP_CMD_REG);
341         inb(dev->iobase + DAQP_STATUS_REG);
342 
343         return ret ? ret : insn->n;
344 }
345 
346 /* This function converts ns nanoseconds to a counter value suitable
347  * for programming the device.  We always use the DAQP's 5 MHz clock,
348  * which with its 24-bit counter, allows values up to 84 seconds.
349  * Also, the function adjusts ns so that it cooresponds to the actual
350  * time that the device will use.
351  */
352 
353 static int daqp_ns_to_timer(unsigned int *ns, unsigned int flags)
354 {
355         int timer;
356 
357         timer = *ns / 200;
358         *ns = timer * 200;
359 
360         return timer;
361 }
362 
363 static void daqp_set_pacer(struct comedi_device *dev, unsigned int val)
364 {
365         outb(val & 0xff, dev->iobase + DAQP_PACER_LOW_REG);
366         outb((val >> 8) & 0xff, dev->iobase + DAQP_PACER_MID_REG);
367         outb((val >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH_REG);
368 }
369 
370 static int daqp_ai_cmdtest(struct comedi_device *dev,
371                            struct comedi_subdevice *s,
372                            struct comedi_cmd *cmd)
373 {
374         struct daqp_private *devpriv = dev->private;
375         int err = 0;
376         unsigned int arg;
377 
378         /* Step 1 : check if triggers are trivially valid */
379 
380         err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
381         err |= comedi_check_trigger_src(&cmd->scan_begin_src,
382                                         TRIG_TIMER | TRIG_FOLLOW);
383         err |= comedi_check_trigger_src(&cmd->convert_src,
384                                         TRIG_TIMER | TRIG_NOW);
385         err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
386         err |= comedi_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 |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
394         err |= comedi_check_trigger_is_unique(cmd->convert_src);
395         err |= comedi_check_trigger_is_unique(cmd->stop_src);
396 
397         /* Step 2b : and mutually compatible */
398 
399         /* the async command requires a pacer */
400         if (cmd->scan_begin_src != TRIG_TIMER && cmd->convert_src != TRIG_TIMER)
401                 err |= -EINVAL;
402 
403         if (err)
404                 return 2;
405 
406         /* Step 3: check if arguments are trivially valid */
407 
408         err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
409 
410         err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
411         err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
412                                            cmd->chanlist_len);
413 
414         if (cmd->scan_begin_src == TRIG_TIMER)
415                 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
416                                                     DAQP_MAX_TIMER_SPEED);
417 
418         if (cmd->convert_src == TRIG_TIMER) {
419                 err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
420                                                     DAQP_MAX_TIMER_SPEED);
421 
422                 if (cmd->scan_begin_src == TRIG_TIMER) {
423                         /*
424                          * If both scan_begin and convert are both timer
425                          * values, the only way that can make sense is if
426                          * the scan time is the number of conversions times
427                          * the convert time.
428                          */
429                         arg = cmd->convert_arg * cmd->scan_end_arg;
430                         err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg,
431                                                            arg);
432                 }
433         }
434 
435         if (cmd->stop_src == TRIG_COUNT)
436                 err |= comedi_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
437         else    /* TRIG_NONE */
438                 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
439 
440         if (err)
441                 return 3;
442 
443         /* step 4: fix up any arguments */
444 
445         if (cmd->convert_src == TRIG_TIMER) {
446                 arg = cmd->convert_arg;
447                 devpriv->pacer_div = daqp_ns_to_timer(&arg, cmd->flags);
448                 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
449         } else if (cmd->scan_begin_src == TRIG_TIMER) {
450                 arg = cmd->scan_begin_arg;
451                 devpriv->pacer_div = daqp_ns_to_timer(&arg, cmd->flags);
452                 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
453         }
454 
455         if (err)
456                 return 4;
457 
458         return 0;
459 }
460 
461 static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
462 {
463         struct daqp_private *devpriv = dev->private;
464         struct comedi_cmd *cmd = &s->async->cmd;
465         int scanlist_start_on_every_entry;
466         int threshold;
467         int ret;
468         int i;
469 
470         if (devpriv->stop)
471                 return -EIO;
472 
473         outb(0, dev->iobase + DAQP_AUX_REG);
474 
475         /* Reset scan list queue */
476         outb(DAQP_CMD_RSTQ, dev->iobase + DAQP_CMD_REG);
477 
478         /* Program pacer clock
479          *
480          * There's two modes we can operate in.  If convert_src is
481          * TRIG_TIMER, then convert_arg specifies the time between
482          * each conversion, so we program the pacer clock to that
483          * frequency and set the SCANLIST_START bit on every scanlist
484          * entry.  Otherwise, convert_src is TRIG_NOW, which means
485          * we want the fastest possible conversions, scan_begin_src
486          * is TRIG_TIMER, and scan_begin_arg specifies the time between
487          * each scan, so we program the pacer clock to this frequency
488          * and only set the SCANLIST_START bit on the first entry.
489          */
490         daqp_set_pacer(dev, devpriv->pacer_div);
491 
492         if (cmd->convert_src == TRIG_TIMER)
493                 scanlist_start_on_every_entry = 1;
494         else
495                 scanlist_start_on_every_entry = 0;
496 
497         /* Program scan list */
498         for (i = 0; i < cmd->chanlist_len; i++) {
499                 int start = (i == 0 || scanlist_start_on_every_entry);
500 
501                 daqp_ai_set_one_scanlist_entry(dev, cmd->chanlist[i], start);
502         }
503 
504         /* Now it's time to program the FIFO threshold, basically the
505          * number of samples the card will buffer before it interrupts
506          * the CPU.
507          *
508          * If we don't have a stop count, then use half the size of
509          * the FIFO (the manufacturer's recommendation).  Consider
510          * that the FIFO can hold 2K samples (4K bytes).  With the
511          * threshold set at half the FIFO size, we have a margin of
512          * error of 1024 samples.  At the chip's maximum sample rate
513          * of 100,000 Hz, the CPU would have to delay interrupt
514          * service for a full 10 milliseconds in order to lose data
515          * here (as opposed to higher up in the kernel).  I've never
516          * seen it happen.  However, for slow sample rates it may
517          * buffer too much data and introduce too much delay for the
518          * user application.
519          *
520          * If we have a stop count, then things get more interesting.
521          * If the stop count is less than the FIFO size (actually
522          * three-quarters of the FIFO size - see below), we just use
523          * the stop count itself as the threshold, the card interrupts
524          * us when that many samples have been taken, and we kill the
525          * acquisition at that point and are done.  If the stop count
526          * is larger than that, then we divide it by 2 until it's less
527          * than three quarters of the FIFO size (we always leave the
528          * top quarter of the FIFO as protection against sluggish CPU
529          * interrupt response) and use that as the threshold.  So, if
530          * the stop count is 4000 samples, we divide by two twice to
531          * get 1000 samples, use that as the threshold, take four
532          * interrupts to get our 4000 samples and are done.
533          *
534          * The algorithm could be more clever.  For example, if 81000
535          * samples are requested, we could set the threshold to 1500
536          * samples and take 54 interrupts to get 81000.  But 54 isn't
537          * a power of two, so this algorithm won't find that option.
538          * Instead, it'll set the threshold at 1266 and take 64
539          * interrupts to get 81024 samples, of which the last 24 will
540          * be discarded... but we won't get the last interrupt until
541          * they've been collected.  To find the first option, the
542          * computer could look at the prime decomposition of the
543          * sample count (81000 = 3^4 * 5^3 * 2^3) and factor it into a
544          * threshold (1500 = 3 * 5^3 * 2^2) and an interrupt count (54
545          * = 3^3 * 2).  Hmmm... a one-line while loop or prime
546          * decomposition of integers... I'll leave it the way it is.
547          *
548          * I'll also note a mini-race condition before ignoring it in
549          * the code.  Let's say we're taking 4000 samples, as before.
550          * After 1000 samples, we get an interrupt.  But before that
551          * interrupt is completely serviced, another sample is taken
552          * and loaded into the FIFO.  Since the interrupt handler
553          * empties the FIFO before returning, it will read 1001 samples.
554          * If that happens four times, we'll end up taking 4004 samples,
555          * not 4000.  The interrupt handler will discard the extra four
556          * samples (by halting the acquisition with four samples still
557          * in the FIFO), but we will have to wait for them.
558          *
559          * In short, this code works pretty well, but for either of
560          * the two reasons noted, might end up waiting for a few more
561          * samples than actually requested.  Shouldn't make too much
562          * of a difference.
563          */
564 
565         /* Save away the number of conversions we should perform, and
566          * compute the FIFO threshold (in bytes, not samples - that's
567          * why we multiple devpriv->count by 2 = sizeof(sample))
568          */
569 
570         if (cmd->stop_src == TRIG_COUNT) {
571                 unsigned long long nsamples;
572                 unsigned long long nbytes;
573 
574                 nsamples = (unsigned long long)cmd->stop_arg *
575                            cmd->scan_end_arg;
576                 nbytes = nsamples * comedi_bytes_per_sample(s);
577                 while (nbytes > DAQP_FIFO_SIZE * 3 / 4)
578                         nbytes /= 2;
579                 threshold = nbytes;
580         } else {
581                 threshold = DAQP_FIFO_SIZE / 2;
582         }
583 
584         /* Reset data FIFO (see page 28 of DAQP User's Manual) */
585 
586         outb(DAQP_CMD_RSTF, dev->iobase + DAQP_CMD_REG);
587 
588         /* Set FIFO threshold.  First two bytes are near-empty
589          * threshold, which is unused; next two bytes are near-full
590          * threshold.  We computed the number of bytes we want in the
591          * FIFO when the interrupt is generated, what the card wants
592          * is actually the number of available bytes left in the FIFO
593          * when the interrupt is to happen.
594          */
595 
596         outb(0x00, dev->iobase + DAQP_AI_FIFO_REG);
597         outb(0x00, dev->iobase + DAQP_AI_FIFO_REG);
598 
599         outb((DAQP_FIFO_SIZE - threshold) & 0xff,
600              dev->iobase + DAQP_AI_FIFO_REG);
601         outb((DAQP_FIFO_SIZE - threshold) >> 8, dev->iobase + DAQP_AI_FIFO_REG);
602 
603         /* Set trigger - continuous, internal */
604         outb(DAQP_CTRL_TRIG_MODE | DAQP_CTRL_PACER_CLK_5MHZ |
605              DAQP_CTRL_FIFO_INT_ENA, dev->iobase + DAQP_CTRL_REG);
606 
607         ret = daqp_clear_events(dev, 100);
608         if (ret)
609                 return ret;
610 
611         /* Start conversion */
612         outb(DAQP_CMD_ARM | DAQP_CMD_FIFO_DATA, dev->iobase + DAQP_CMD_REG);
613 
614         return 0;
615 }
616 
617 static int daqp_ao_empty(struct comedi_device *dev,
618                          struct comedi_subdevice *s,
619                          struct comedi_insn *insn,
620                          unsigned long context)
621 {
622         unsigned int status;
623 
624         status = inb(dev->iobase + DAQP_AUX_REG);
625         if ((status & DAQP_AUX_DA_BUFFER) == 0)
626                 return 0;
627         return -EBUSY;
628 }
629 
630 static int daqp_ao_insn_write(struct comedi_device *dev,
631                               struct comedi_subdevice *s,
632                               struct comedi_insn *insn,
633                               unsigned int *data)
634 {
635         struct daqp_private *devpriv = dev->private;
636         unsigned int chan = CR_CHAN(insn->chanspec);
637         int i;
638 
639         if (devpriv->stop)
640                 return -EIO;
641 
642         /* Make sure D/A update mode is direct update */
643         outb(0, dev->iobase + DAQP_AUX_REG);
644 
645         for (i = 0; i > insn->n; i++) {
646                 unsigned val = data[i];
647                 int ret;
648 
649                 /* D/A transfer rate is about 8ms */
650                 ret = comedi_timeout(dev, s, insn, daqp_ao_empty, 0);
651                 if (ret)
652                         return ret;
653 
654                 /* write the two's complement value to the channel */
655                 outw((chan << 12) | comedi_offset_munge(s, val),
656                      dev->iobase + DAQP_AO_REG);
657 
658                 s->readback[chan] = val;
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_DI_REG);
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_DO_REG);
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 == 0)
718                 dev->irq = link->irq;
719 
720         ret = comedi_alloc_subdevices(dev, 4);
721         if (ret)
722                 return ret;
723 
724         s = &dev->subdevices[0];
725         s->type         = COMEDI_SUBD_AI;
726         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
727         s->n_chan       = 8;
728         s->maxdata      = 0xffff;
729         s->range_table  = &range_daqp_ai;
730         s->insn_read    = daqp_ai_insn_read;
731         if (dev->irq) {
732                 dev->read_subdev = s;
733                 s->subdev_flags |= SDF_CMD_READ;
734                 s->len_chanlist = 2048;
735                 s->do_cmdtest   = daqp_ai_cmdtest;
736                 s->do_cmd       = daqp_ai_cmd;
737                 s->cancel       = daqp_ai_cancel;
738         }
739 
740         s = &dev->subdevices[1];
741         s->type         = COMEDI_SUBD_AO;
742         s->subdev_flags = SDF_WRITABLE;
743         s->n_chan       = 2;
744         s->maxdata      = 0x0fff;
745         s->range_table  = &range_bipolar5;
746         s->insn_write   = daqp_ao_insn_write;
747 
748         ret = comedi_alloc_subdev_readback(s);
749         if (ret)
750                 return ret;
751 
752         /*
753          * Digital Input subdevice
754          * NOTE: The digital input lines are shared:
755          *
756          * Chan  Normal Mode        Expansion Mode
757          * ----  -----------------  ----------------------------
758          *  0    DI0, ext. trigger  Same as normal mode
759          *  1    DI1                External gain select, lo bit
760          *  2    DI2, ext. clock    Same as normal mode
761          *  3    DI3                External gain select, hi bit
762          */
763         s = &dev->subdevices[2];
764         s->type         = COMEDI_SUBD_DI;
765         s->subdev_flags = SDF_READABLE;
766         s->n_chan       = 4;
767         s->maxdata      = 1;
768         s->insn_bits    = daqp_di_insn_bits;
769 
770         /*
771          * Digital Output subdevice
772          * NOTE: The digital output lines share the same pins on the
773          * interface connector as the four external channel selection
774          * bits. If expansion mode is used the digital outputs do not
775          * work.
776          */
777         s = &dev->subdevices[3];
778         s->type         = COMEDI_SUBD_DO;
779         s->subdev_flags = SDF_WRITABLE;
780         s->n_chan       = 4;
781         s->maxdata      = 1;
782         s->insn_bits    = daqp_do_insn_bits;
783 
784         return 0;
785 }
786 
787 static struct comedi_driver driver_daqp = {
788         .driver_name    = "quatech_daqp_cs",
789         .module         = THIS_MODULE,
790         .auto_attach    = daqp_auto_attach,
791         .detach         = comedi_pcmcia_disable,
792 };
793 
794 static int daqp_cs_suspend(struct pcmcia_device *link)
795 {
796         struct comedi_device *dev = link->priv;
797         struct daqp_private *devpriv = dev ? dev->private : NULL;
798 
799         /* Mark the device as stopped, to block IO until later */
800         if (devpriv)
801                 devpriv->stop = 1;
802 
803         return 0;
804 }
805 
806 static int daqp_cs_resume(struct pcmcia_device *link)
807 {
808         struct comedi_device *dev = link->priv;
809         struct daqp_private *devpriv = dev ? dev->private : NULL;
810 
811         if (devpriv)
812                 devpriv->stop = 0;
813 
814         return 0;
815 }
816 
817 static int daqp_cs_attach(struct pcmcia_device *link)
818 {
819         return comedi_pcmcia_auto_config(link, &driver_daqp);
820 }
821 
822 static const struct pcmcia_device_id daqp_cs_id_table[] = {
823         PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0027),
824         PCMCIA_DEVICE_NULL
825 };
826 MODULE_DEVICE_TABLE(pcmcia, daqp_cs_id_table);
827 
828 static struct pcmcia_driver daqp_cs_driver = {
829         .name           = "quatech_daqp_cs",
830         .owner          = THIS_MODULE,
831         .id_table       = daqp_cs_id_table,
832         .probe          = daqp_cs_attach,
833         .remove         = comedi_pcmcia_auto_unconfig,
834         .suspend        = daqp_cs_suspend,
835         .resume         = daqp_cs_resume,
836 };
837 module_comedi_pcmcia_driver(driver_daqp, daqp_cs_driver);
838 
839 MODULE_DESCRIPTION("Comedi driver for Quatech DAQP PCMCIA data capture cards");
840 MODULE_AUTHOR("Brent Baccala <baccala@freesoft.org>");
841 MODULE_LICENSE("GPL");
842 

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