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