linux/drivers/staging/comedi/drivers/amplc_pci224.c
<<
>>
Prefs
   1/*
   2    comedi/drivers/amplc_pci224.c
   3    Driver for Amplicon PCI224 and PCI234 AO boards.
   4
   5    Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
   6
   7    COMEDI - Linux Control and Measurement Device Interface
   8    Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
   9
  10    This program is free software; you can redistribute it and/or modify
  11    it under the terms of the GNU General Public License as published by
  12    the Free Software Foundation; either version 2 of the License, or
  13    (at your option) any later version.
  14
  15    This program is distributed in the hope that it will be useful,
  16    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18    GNU General Public License for more details.
  19
  20    You should have received a copy of the GNU General Public License
  21    along with this program; if not, write to the Free Software
  22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23
  24*/
  25/*
  26Driver: amplc_pci224
  27Description: Amplicon PCI224, PCI234
  28Author: Ian Abbott <abbotti@mev.co.uk>
  29Devices: [Amplicon] PCI224 (amplc_pci224 or pci224),
  30  PCI234 (amplc_pci224 or pci234)
  31Updated: Wed, 22 Oct 2008 12:25:08 +0100
  32Status: works, but see caveats
  33
  34Supports:
  35
  36  - ao_insn read/write
  37  - ao_do_cmd mode with the following sources:
  38
  39    - start_src         TRIG_INT        TRIG_EXT
  40    - scan_begin_src    TRIG_TIMER      TRIG_EXT
  41    - convert_src       TRIG_NOW
  42    - scan_end_src      TRIG_COUNT
  43    - stop_src          TRIG_COUNT      TRIG_EXT        TRIG_NONE
  44
  45    The channel list must contain at least one channel with no repeated
  46    channels.  The scan end count must equal the number of channels in
  47    the channel list.
  48
  49    There is only one external trigger source so only one of start_src,
  50    scan_begin_src or stop_src may use TRIG_EXT.
  51
  52Configuration options - PCI224:
  53  [0] - PCI bus of device (optional).
  54  [1] - PCI slot of device (optional).
  55          If bus/slot is not specified, the first available PCI device
  56          will be used.
  57  [2] - Select available ranges according to jumper LK1.  All channels
  58        are set to the same range:
  59        0=Jumper position 1-2 (factory default), 4 software-selectable
  60          internal voltage references, giving 4 bipolar and 4 unipolar
  61          ranges:
  62            [-10V,+10V], [-5V,+5V], [-2.5V,+2.5V], [-1.25V,+1.25V],
  63            [0,+10V], [0,+5V], [0,+2.5V], [0,1.25V].
  64        1=Jumper position 2-3, 1 external voltage reference, giving
  65          1 bipolar and 1 unipolar range:
  66            [-Vext,+Vext], [0,+Vext].
  67
  68Configuration options - PCI234:
  69  [0] - PCI bus of device (optional).
  70  [1] - PCI slot of device (optional).
  71          If bus/slot is not specified, the first available PCI device
  72          will be used.
  73  [2] - Select internal or external voltage reference according to
  74        jumper LK1.  This affects all channels:
  75        0=Jumper position 1-2 (factory default), Vref=5V internal.
  76        1=Jumper position 2-3, Vref=Vext external.
  77  [3] - Select channel 0 range according to jumper LK2:
  78        0=Jumper position 2-3 (factory default), range [-2*Vref,+2*Vref]
  79          (10V bipolar when options[2]=0).
  80        1=Jumper position 1-2, range [-Vref,+Vref]
  81          (5V bipolar when options[2]=0).
  82  [4] - Select channel 1 range according to jumper LK3: cf. options[3].
  83  [5] - Select channel 2 range according to jumper LK4: cf. options[3].
  84  [6] - Select channel 3 range according to jumper LK5: cf. options[3].
  85
  86Passing a zero for an option is the same as leaving it unspecified.
  87
  88Caveats:
  89
  90  1) All channels on the PCI224 share the same range.  Any change to the
  91     range as a result of insn_write or a streaming command will affect
  92     the output voltages of all channels, including those not specified
  93     by the instruction or command.
  94
  95  2) For the analog output command,  the first scan may be triggered
  96     falsely at the start of acquisition.  This occurs when the DAC scan
  97     trigger source is switched from 'none' to 'timer' (scan_begin_src =
  98     TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
  99     of acquisition and the trigger source is at logic level 1 at the
 100     time of the switch.  This is very likely for TRIG_TIMER.  For
 101     TRIG_EXT, it depends on the state of the external line and whether
 102     the CR_INVERT flag has been set.  The remaining scans are triggered
 103     correctly.
 104*/
 105
 106#include <linux/interrupt.h>
 107#include <linux/slab.h>
 108
 109#include "../comedidev.h"
 110
 111#include "comedi_pci.h"
 112
 113#include "comedi_fc.h"
 114#include "8253.h"
 115
 116#define DRIVER_NAME     "amplc_pci224"
 117
 118/*
 119 * PCI IDs.
 120 */
 121#define PCI_VENDOR_ID_AMPLICON 0x14dc
 122#define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
 123#define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
 124#define PCI_DEVICE_ID_INVALID 0xffff
 125
 126/*
 127 * PCI224/234 i/o space 1 (PCIBAR2) registers.
 128 */
 129#define PCI224_IO1_SIZE 0x20    /* Size of i/o space 1 (8-bit registers) */
 130#define PCI224_Z2_CT0   0x14    /* 82C54 counter/timer 0 */
 131#define PCI224_Z2_CT1   0x15    /* 82C54 counter/timer 1 */
 132#define PCI224_Z2_CT2   0x16    /* 82C54 counter/timer 2 */
 133#define PCI224_Z2_CTC   0x17    /* 82C54 counter/timer control word */
 134#define PCI224_ZCLK_SCE 0x1A    /* Group Z Clock Configuration Register */
 135#define PCI224_ZGAT_SCE 0x1D    /* Group Z Gate Configuration Register */
 136#define PCI224_INT_SCE  0x1E    /* ISR Interrupt source mask register */
 137                                /* /Interrupt status */
 138
 139/*
 140 * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
 141 */
 142#define PCI224_IO2_SIZE 0x10    /* Size of i/o space 2 (16-bit registers). */
 143#define PCI224_DACDATA  0x00    /* (w-o) DAC FIFO data. */
 144#define PCI224_SOFTTRIG 0x00    /* (r-o) DAC software scan trigger. */
 145#define PCI224_DACCON   0x02    /* (r/w) DAC status/configuration. */
 146#define PCI224_FIFOSIZ  0x04    /* (w-o) FIFO size for wraparound mode. */
 147#define PCI224_DACCEN   0x06    /* (w-o) DAC channel enable register. */
 148
 149/*
 150 * DACCON values.
 151 */
 152/* (r/w) Scan trigger. */
 153#define PCI224_DACCON_TRIG_MASK         (7 << 0)
 154#define PCI224_DACCON_TRIG_NONE         (0 << 0)        /* none */
 155#define PCI224_DACCON_TRIG_SW           (1 << 0)        /* software trig */
 156#define PCI224_DACCON_TRIG_EXTP         (2 << 0)        /* ext +ve edge */
 157#define PCI224_DACCON_TRIG_EXTN         (3 << 0)        /* ext -ve edge */
 158#define PCI224_DACCON_TRIG_Z2CT0        (4 << 0)        /* Z2 CT0 out */
 159#define PCI224_DACCON_TRIG_Z2CT1        (5 << 0)        /* Z2 CT1 out */
 160#define PCI224_DACCON_TRIG_Z2CT2        (6 << 0)        /* Z2 CT2 out */
 161/* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
 162#define PCI224_DACCON_POLAR_MASK        (1 << 3)
 163#define PCI224_DACCON_POLAR_UNI         (0 << 3)        /* range [0,Vref] */
 164#define PCI224_DACCON_POLAR_BI          (1 << 3)        /* range [-Vref,Vref] */
 165/* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
 166#define PCI224_DACCON_VREF_MASK         (3 << 4)
 167#define PCI224_DACCON_VREF_1_25         (0 << 4)        /* Vref = 1.25V */
 168#define PCI224_DACCON_VREF_2_5          (1 << 4)        /* Vref = 2.5V */
 169#define PCI224_DACCON_VREF_5            (2 << 4)        /* Vref = 5V */
 170#define PCI224_DACCON_VREF_10           (3 << 4)        /* Vref = 10V */
 171/* (r/w) Wraparound mode enable (to play back stored waveform). */
 172#define PCI224_DACCON_FIFOWRAP          (1 << 7)
 173/* (r/w) FIFO enable.  It MUST be set! */
 174#define PCI224_DACCON_FIFOENAB          (1 << 8)
 175/* (r/w) FIFO interrupt trigger level (most values are not very useful). */
 176#define PCI224_DACCON_FIFOINTR_MASK     (7 << 9)
 177#define PCI224_DACCON_FIFOINTR_EMPTY    (0 << 9)        /* when empty */
 178#define PCI224_DACCON_FIFOINTR_NEMPTY   (1 << 9)        /* when not empty */
 179#define PCI224_DACCON_FIFOINTR_NHALF    (2 << 9)        /* when not half full */
 180#define PCI224_DACCON_FIFOINTR_HALF     (3 << 9)        /* when half full */
 181#define PCI224_DACCON_FIFOINTR_NFULL    (4 << 9)        /* when not full */
 182#define PCI224_DACCON_FIFOINTR_FULL     (5 << 9)        /* when full */
 183/* (r-o) FIFO fill level. */
 184#define PCI224_DACCON_FIFOFL_MASK       (7 << 12)
 185#define PCI224_DACCON_FIFOFL_EMPTY      (1 << 12)       /* 0 */
 186#define PCI224_DACCON_FIFOFL_ONETOHALF  (0 << 12)       /* [1,2048] */
 187#define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12)       /* [2049,4095] */
 188#define PCI224_DACCON_FIFOFL_FULL       (6 << 12)       /* 4096 */
 189/* (r-o) DAC busy flag. */
 190#define PCI224_DACCON_BUSY              (1 << 15)
 191/* (w-o) FIFO reset. */
 192#define PCI224_DACCON_FIFORESET         (1 << 12)
 193/* (w-o) Global reset (not sure what it does). */
 194#define PCI224_DACCON_GLOBALRESET       (1 << 13)
 195
 196/*
 197 * DAC FIFO size.
 198 */
 199#define PCI224_FIFO_SIZE        4096
 200
 201/*
 202 * DAC FIFO guaranteed minimum room available, depending on reported fill level.
 203 * The maximum room available depends on the reported fill level and how much
 204 * has been written!
 205 */
 206#define PCI224_FIFO_ROOM_EMPTY          PCI224_FIFO_SIZE
 207#define PCI224_FIFO_ROOM_ONETOHALF      (PCI224_FIFO_SIZE / 2)
 208#define PCI224_FIFO_ROOM_HALFTOFULL     1
 209#define PCI224_FIFO_ROOM_FULL           0
 210
 211/*
 212 * Counter/timer clock input configuration sources.
 213 */
 214#define CLK_CLK         0       /* reserved (channel-specific clock) */
 215#define CLK_10MHZ       1       /* internal 10 MHz clock */
 216#define CLK_1MHZ        2       /* internal 1 MHz clock */
 217#define CLK_100KHZ      3       /* internal 100 kHz clock */
 218#define CLK_10KHZ       4       /* internal 10 kHz clock */
 219#define CLK_1KHZ        5       /* internal 1 kHz clock */
 220#define CLK_OUTNM1      6       /* output of channel-1 modulo total */
 221#define CLK_EXT         7       /* external clock */
 222/* Macro to construct clock input configuration register value. */
 223#define CLK_CONFIG(chan, src)   ((((chan) & 3) << 3) | ((src) & 7))
 224/* Timebases in ns. */
 225#define TIMEBASE_10MHZ          100
 226#define TIMEBASE_1MHZ           1000
 227#define TIMEBASE_100KHZ         10000
 228#define TIMEBASE_10KHZ          100000
 229#define TIMEBASE_1KHZ           1000000
 230
 231/*
 232 * Counter/timer gate input configuration sources.
 233 */
 234#define GAT_VCC         0       /* VCC (i.e. enabled) */
 235#define GAT_GND         1       /* GND (i.e. disabled) */
 236#define GAT_EXT         2       /* reserved (external gate input) */
 237#define GAT_NOUTNM2     3       /* inverted output of channel-2 modulo total */
 238/* Macro to construct gate input configuration register value. */
 239#define GAT_CONFIG(chan, src)   ((((chan) & 3) << 3) | ((src) & 7))
 240
 241/*
 242 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
 243 *
 244 *              Channel's       Channel's
 245 *              clock input     gate input
 246 * Channel      CLK_OUTNM1      GAT_NOUTNM2
 247 * -------      ----------      -----------
 248 * Z2-CT0       Z2-CT2-OUT      /Z2-CT1-OUT
 249 * Z2-CT1       Z2-CT0-OUT      /Z2-CT2-OUT
 250 * Z2-CT2       Z2-CT1-OUT      /Z2-CT0-OUT
 251 */
 252
 253/*
 254 * Interrupt enable/status bits
 255 */
 256#define PCI224_INTR_EXT         0x01    /* rising edge on external input */
 257#define PCI224_INTR_DAC         0x04    /* DAC (FIFO) interrupt */
 258#define PCI224_INTR_Z2CT1       0x20    /* rising edge on Z2-CT1 output */
 259
 260#define PCI224_INTR_EDGE_BITS   (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
 261#define PCI224_INTR_LEVEL_BITS  PCI224_INTR_DACFIFO
 262
 263/*
 264 * Handy macros.
 265 */
 266
 267/* Combine old and new bits. */
 268#define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
 269
 270/* A generic null function pointer value.  */
 271#define NULLFUNC        0
 272
 273/* Current CPU.  XXX should this be hard_smp_processor_id()? */
 274#define THISCPU         smp_processor_id()
 275
 276/* State bits for use with atomic bit operations. */
 277#define AO_CMD_STARTED  0
 278
 279/*
 280 * Range tables.
 281 */
 282
 283/* The software selectable internal ranges for PCI224 (option[2] == 0). */
 284static const struct comedi_lrange range_pci224_internal = {
 285        8,
 286        {
 287         BIP_RANGE(10),
 288         BIP_RANGE(5),
 289         BIP_RANGE(2.5),
 290         BIP_RANGE(1.25),
 291         UNI_RANGE(10),
 292         UNI_RANGE(5),
 293         UNI_RANGE(2.5),
 294         UNI_RANGE(1.25),
 295         }
 296};
 297
 298static const unsigned short hwrange_pci224_internal[8] = {
 299        PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
 300        PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
 301        PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
 302        PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
 303        PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
 304        PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
 305        PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
 306        PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
 307};
 308
 309/* The software selectable external ranges for PCI224 (option[2] == 1). */
 310static const struct comedi_lrange range_pci224_external = {
 311        2,
 312        {
 313         RANGE_ext(-1, 1),      /* bipolar [-Vref,+Vref] */
 314         RANGE_ext(0, 1),       /* unipolar [0,+Vref] */
 315         }
 316};
 317
 318static const unsigned short hwrange_pci224_external[2] = {
 319        PCI224_DACCON_POLAR_BI,
 320        PCI224_DACCON_POLAR_UNI,
 321};
 322
 323/* The hardware selectable Vref*2 external range for PCI234
 324 * (option[2] == 1, option[3+n] == 0). */
 325static const struct comedi_lrange range_pci234_ext2 = {
 326        1,
 327        {
 328         RANGE_ext(-2, 2),
 329         }
 330};
 331
 332/* The hardware selectable Vref external range for PCI234
 333 * (option[2] == 1, option[3+n] == 1). */
 334static const struct comedi_lrange range_pci234_ext = {
 335        1,
 336        {
 337         RANGE_ext(-1, 1),
 338         }
 339};
 340
 341/* This serves for all the PCI234 ranges. */
 342static const unsigned short hwrange_pci234[1] = {
 343        PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
 344};
 345
 346/*
 347 * Board descriptions.
 348 */
 349
 350enum pci224_model { any_model, pci224_model, pci234_model };
 351
 352struct pci224_board {
 353        const char *name;
 354        unsigned short devid;
 355        enum pci224_model model;
 356        unsigned int ao_chans;
 357        unsigned int ao_bits;
 358};
 359
 360static const struct pci224_board pci224_boards[] = {
 361        {
 362         .name = "pci224",
 363         .devid = PCI_DEVICE_ID_AMPLICON_PCI224,
 364         .model = pci224_model,
 365         .ao_chans = 16,
 366         .ao_bits = 12,
 367         },
 368        {
 369         .name = "pci234",
 370         .devid = PCI_DEVICE_ID_AMPLICON_PCI234,
 371         .model = pci234_model,
 372         .ao_chans = 4,
 373         .ao_bits = 16,
 374         },
 375        {
 376         .name = DRIVER_NAME,
 377         .devid = PCI_DEVICE_ID_INVALID,
 378         .model = any_model,    /* wildcard */
 379         },
 380};
 381
 382/*
 383 * Useful for shorthand access to the particular board structure
 384 */
 385#define thisboard ((struct pci224_board *)dev->board_ptr)
 386
 387/* this structure is for data unique to this hardware driver.  If
 388   several hardware drivers keep similar information in this structure,
 389   feel free to suggest moving the variable to the struct comedi_device struct.  */
 390struct pci224_private {
 391        struct pci_dev *pci_dev;        /* PCI device */
 392        const unsigned short *hwrange;
 393        unsigned long iobase1;
 394        unsigned long state;
 395        spinlock_t ao_spinlock;
 396        unsigned int *ao_readback;
 397        short *ao_scan_vals;
 398        unsigned char *ao_scan_order;
 399        int intr_cpuid;
 400        short intr_running;
 401        unsigned short daccon;
 402        unsigned int cached_div1;
 403        unsigned int cached_div2;
 404        unsigned int ao_stop_count;
 405        short ao_stop_continuous;
 406        unsigned short ao_enab; /* max 16 channels so 'short' will do */
 407        unsigned char intsce;
 408};
 409
 410#define devpriv ((struct pci224_private *)dev->private)
 411
 412/*
 413 * Called from the 'insn_write' function to perform a single write.
 414 */
 415static void
 416pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
 417                   unsigned int data)
 418{
 419        unsigned short mangled;
 420
 421        /* Store unmangled data for readback. */
 422        devpriv->ao_readback[chan] = data;
 423        /* Enable the channel. */
 424        outw(1 << chan, dev->iobase + PCI224_DACCEN);
 425        /* Set range and reset FIFO. */
 426        devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
 427                                  (PCI224_DACCON_POLAR_MASK |
 428                                   PCI224_DACCON_VREF_MASK));
 429        outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
 430             dev->iobase + PCI224_DACCON);
 431        /*
 432         * Mangle the data.  The hardware expects:
 433         * - bipolar: 16-bit 2's complement
 434         * - unipolar: 16-bit unsigned
 435         */
 436        mangled = (unsigned short)data << (16 - thisboard->ao_bits);
 437        if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
 438            PCI224_DACCON_POLAR_BI) {
 439                mangled ^= 0x8000;
 440        }
 441        /* Write mangled data to the FIFO. */
 442        outw(mangled, dev->iobase + PCI224_DACDATA);
 443        /* Trigger the conversion. */
 444        inw(dev->iobase + PCI224_SOFTTRIG);
 445}
 446
 447/*
 448 * 'insn_write' function for AO subdevice.
 449 */
 450static int
 451pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
 452                     struct comedi_insn *insn, unsigned int *data)
 453{
 454        int i;
 455        int chan, range;
 456
 457        /* Unpack channel and range. */
 458        chan = CR_CHAN(insn->chanspec);
 459        range = CR_RANGE(insn->chanspec);
 460
 461        /* Writing a list of values to an AO channel is probably not
 462         * very useful, but that's how the interface is defined. */
 463        for (i = 0; i < insn->n; i++)
 464                pci224_ao_set_data(dev, chan, range, data[i]);
 465
 466        return i;
 467}
 468
 469/*
 470 * 'insn_read' function for AO subdevice.
 471 *
 472 * N.B. The value read will not be valid if the DAC channel has
 473 * never been written successfully since the device was attached
 474 * or since the channel has been used by an AO streaming write
 475 * command.
 476 */
 477static int
 478pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
 479                    struct comedi_insn *insn, unsigned int *data)
 480{
 481        int i;
 482        int chan;
 483
 484        chan = CR_CHAN(insn->chanspec);
 485
 486        for (i = 0; i < insn->n; i++)
 487                data[i] = devpriv->ao_readback[chan];
 488
 489
 490        return i;
 491}
 492
 493/*
 494 * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
 495 */
 496static void
 497pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
 498                           unsigned int *nanosec, int round_mode)
 499{
 500        i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
 501}
 502
 503/*
 504 * Kills a command running on the AO subdevice.
 505 */
 506static void pci224_ao_stop(struct comedi_device *dev,
 507                           struct comedi_subdevice *s)
 508{
 509        unsigned long flags;
 510
 511        if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
 512                return;
 513
 514
 515        spin_lock_irqsave(&devpriv->ao_spinlock, flags);
 516        /* Kill the interrupts. */
 517        devpriv->intsce = 0;
 518        outb(0, devpriv->iobase1 + PCI224_INT_SCE);
 519        /*
 520         * Interrupt routine may or may not be running.  We may or may not
 521         * have been called from the interrupt routine (directly or
 522         * indirectly via a comedi_events() callback routine).  It's highly
 523         * unlikely that we've been called from some other interrupt routine
 524         * but who knows what strange things coders get up to!
 525         *
 526         * If the interrupt routine is currently running, wait for it to
 527         * finish, unless we appear to have been called via the interrupt
 528         * routine.
 529         */
 530        while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
 531                spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
 532                spin_lock_irqsave(&devpriv->ao_spinlock, flags);
 533        }
 534        spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
 535        /* Reconfigure DAC for insn_write usage. */
 536        outw(0, dev->iobase + PCI224_DACCEN);   /* Disable channels. */
 537        devpriv->daccon = COMBINE(devpriv->daccon,
 538                                  PCI224_DACCON_TRIG_SW |
 539                                  PCI224_DACCON_FIFOINTR_EMPTY,
 540                                  PCI224_DACCON_TRIG_MASK |
 541                                  PCI224_DACCON_FIFOINTR_MASK);
 542        outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
 543             dev->iobase + PCI224_DACCON);
 544}
 545
 546/*
 547 * Handles start of acquisition for the AO subdevice.
 548 */
 549static void pci224_ao_start(struct comedi_device *dev,
 550                            struct comedi_subdevice *s)
 551{
 552        struct comedi_cmd *cmd = &s->async->cmd;
 553        unsigned long flags;
 554
 555        set_bit(AO_CMD_STARTED, &devpriv->state);
 556        if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
 557                /* An empty acquisition! */
 558                pci224_ao_stop(dev, s);
 559                s->async->events |= COMEDI_CB_EOA;
 560                comedi_event(dev, s);
 561        } else {
 562                /* Enable interrupts. */
 563                spin_lock_irqsave(&devpriv->ao_spinlock, flags);
 564                if (cmd->stop_src == TRIG_EXT)
 565                        devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
 566                else
 567                        devpriv->intsce = PCI224_INTR_DAC;
 568
 569                outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
 570                spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
 571        }
 572}
 573
 574/*
 575 * Handles interrupts from the DAC FIFO.
 576 */
 577static void pci224_ao_handle_fifo(struct comedi_device *dev,
 578                                  struct comedi_subdevice *s)
 579{
 580        struct comedi_cmd *cmd = &s->async->cmd;
 581        unsigned int num_scans;
 582        unsigned int room;
 583        unsigned short dacstat;
 584        unsigned int i, n;
 585        unsigned int bytes_per_scan;
 586
 587        if (cmd->chanlist_len) {
 588                bytes_per_scan = cmd->chanlist_len * sizeof(short);
 589        } else {
 590                /* Shouldn't get here! */
 591                bytes_per_scan = sizeof(short);
 592        }
 593        /* Determine number of scans available in buffer. */
 594        num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
 595        if (!devpriv->ao_stop_continuous) {
 596                /* Fixed number of scans. */
 597                if (num_scans > devpriv->ao_stop_count)
 598                        num_scans = devpriv->ao_stop_count;
 599
 600        }
 601
 602        /* Determine how much room is in the FIFO (in samples). */
 603        dacstat = inw(dev->iobase + PCI224_DACCON);
 604        switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
 605        case PCI224_DACCON_FIFOFL_EMPTY:
 606                room = PCI224_FIFO_ROOM_EMPTY;
 607                if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
 608                        /* FIFO empty at end of counted acquisition. */
 609                        pci224_ao_stop(dev, s);
 610                        s->async->events |= COMEDI_CB_EOA;
 611                        comedi_event(dev, s);
 612                        return;
 613                }
 614                break;
 615        case PCI224_DACCON_FIFOFL_ONETOHALF:
 616                room = PCI224_FIFO_ROOM_ONETOHALF;
 617                break;
 618        case PCI224_DACCON_FIFOFL_HALFTOFULL:
 619                room = PCI224_FIFO_ROOM_HALFTOFULL;
 620                break;
 621        default:
 622                room = PCI224_FIFO_ROOM_FULL;
 623                break;
 624        }
 625        if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
 626                /* FIFO is less than half-full. */
 627                if (num_scans == 0) {
 628                        /* Nothing left to put in the FIFO. */
 629                        pci224_ao_stop(dev, s);
 630                        s->async->events |= COMEDI_CB_OVERFLOW;
 631                        printk(KERN_ERR "comedi%d: "
 632                               "AO buffer underrun\n", dev->minor);
 633                }
 634        }
 635        /* Determine how many new scans can be put in the FIFO. */
 636        if (cmd->chanlist_len)
 637                room /= cmd->chanlist_len;
 638
 639        /* Determine how many scans to process. */
 640        if (num_scans > room)
 641                num_scans = room;
 642
 643        /* Process scans. */
 644        for (n = 0; n < num_scans; n++) {
 645                cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
 646                                           bytes_per_scan);
 647                for (i = 0; i < cmd->chanlist_len; i++) {
 648                        outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
 649                             dev->iobase + PCI224_DACDATA);
 650                }
 651        }
 652        if (!devpriv->ao_stop_continuous) {
 653                devpriv->ao_stop_count -= num_scans;
 654                if (devpriv->ao_stop_count == 0) {
 655                        /*
 656                         * Change FIFO interrupt trigger level to wait
 657                         * until FIFO is empty.
 658                         */
 659                        devpriv->daccon = COMBINE(devpriv->daccon,
 660                                                  PCI224_DACCON_FIFOINTR_EMPTY,
 661                                                  PCI224_DACCON_FIFOINTR_MASK);
 662                        outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
 663                }
 664        }
 665        if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
 666            PCI224_DACCON_TRIG_NONE) {
 667                unsigned short trig;
 668
 669                /*
 670                 * This is the initial DAC FIFO interrupt at the
 671                 * start of the acquisition.  The DAC's scan trigger
 672                 * has been set to 'none' up until now.
 673                 *
 674                 * Now that data has been written to the FIFO, the
 675                 * DAC's scan trigger source can be set to the
 676                 * correct value.
 677                 *
 678                 * BUG: The first scan will be triggered immediately
 679                 * if the scan trigger source is at logic level 1.
 680                 */
 681                if (cmd->scan_begin_src == TRIG_TIMER) {
 682                        trig = PCI224_DACCON_TRIG_Z2CT0;
 683                } else {
 684                        /* cmd->scan_begin_src == TRIG_EXT */
 685                        if (cmd->scan_begin_arg & CR_INVERT)
 686                                trig = PCI224_DACCON_TRIG_EXTN;
 687                        else
 688                                trig = PCI224_DACCON_TRIG_EXTP;
 689
 690                }
 691                devpriv->daccon = COMBINE(devpriv->daccon, trig,
 692                                          PCI224_DACCON_TRIG_MASK);
 693                outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
 694        }
 695        if (s->async->events)
 696                comedi_event(dev, s);
 697
 698}
 699
 700/*
 701 * Internal trigger function to start acquisition on AO subdevice.
 702 */
 703static int
 704pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
 705                        unsigned int trignum)
 706{
 707        if (trignum != 0)
 708                return -EINVAL;
 709
 710        s->async->inttrig = NULLFUNC;
 711        pci224_ao_start(dev, s);
 712
 713        return 1;
 714}
 715
 716#define MAX_SCAN_PERIOD         0xFFFFFFFFU
 717#define MIN_SCAN_PERIOD         2500
 718#define CONVERT_PERIOD          625
 719
 720/*
 721 * 'do_cmdtest' function for AO subdevice.
 722 */
 723static int
 724pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 725                  struct comedi_cmd *cmd)
 726{
 727        int err = 0;
 728        unsigned int tmp;
 729
 730        /* Step 1: make sure trigger sources are trivially valid. */
 731
 732        tmp = cmd->start_src;
 733        cmd->start_src &= TRIG_INT | TRIG_EXT;
 734        if (!cmd->start_src || tmp != cmd->start_src)
 735                err++;
 736
 737        tmp = cmd->scan_begin_src;
 738        cmd->scan_begin_src &= TRIG_EXT | TRIG_TIMER;
 739        if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
 740                err++;
 741
 742        tmp = cmd->convert_src;
 743        cmd->convert_src &= TRIG_NOW;
 744        if (!cmd->convert_src || tmp != cmd->convert_src)
 745                err++;
 746
 747        tmp = cmd->scan_end_src;
 748        cmd->scan_end_src &= TRIG_COUNT;
 749        if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
 750                err++;
 751
 752        tmp = cmd->stop_src;
 753        cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
 754        if (!cmd->stop_src || tmp != cmd->stop_src)
 755                err++;
 756
 757        if (err)
 758                return 1;
 759
 760        /* Step 2: make sure trigger sources are unique and mutually
 761         * compatible. */
 762
 763        /* these tests are true if more than one _src bit is set */
 764        if ((cmd->start_src & (cmd->start_src - 1)) != 0)
 765                err++;
 766        if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
 767                err++;
 768        if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
 769                err++;
 770        if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
 771                err++;
 772        if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
 773                err++;
 774
 775        /* There's only one external trigger signal (which makes these
 776         * tests easier).  Only one thing can use it. */
 777        tmp = 0;
 778        if (cmd->start_src & TRIG_EXT)
 779                tmp++;
 780        if (cmd->scan_begin_src & TRIG_EXT)
 781                tmp++;
 782        if (cmd->stop_src & TRIG_EXT)
 783                tmp++;
 784        if (tmp > 1)
 785                err++;
 786
 787        if (err)
 788                return 2;
 789
 790        /* Step 3: make sure arguments are trivially compatible. */
 791
 792        switch (cmd->start_src) {
 793        case TRIG_INT:
 794                if (cmd->start_arg != 0) {
 795                        cmd->start_arg = 0;
 796                        err++;
 797                }
 798                break;
 799        case TRIG_EXT:
 800                /* Force to external trigger 0. */
 801                if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
 802                        cmd->start_arg = COMBINE(cmd->start_arg, 0,
 803                                                 ~CR_FLAGS_MASK);
 804                        err++;
 805                }
 806                /* The only flag allowed is CR_EDGE, which is ignored. */
 807                if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
 808                        cmd->start_arg = COMBINE(cmd->start_arg, 0,
 809                                                 CR_FLAGS_MASK & ~CR_EDGE);
 810                        err++;
 811                }
 812                break;
 813        }
 814
 815        switch (cmd->scan_begin_src) {
 816        case TRIG_TIMER:
 817                if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
 818                        cmd->scan_begin_arg = MAX_SCAN_PERIOD;
 819                        err++;
 820                }
 821                tmp = cmd->chanlist_len * CONVERT_PERIOD;
 822                if (tmp < MIN_SCAN_PERIOD)
 823                        tmp = MIN_SCAN_PERIOD;
 824
 825                if (cmd->scan_begin_arg < tmp) {
 826                        cmd->scan_begin_arg = tmp;
 827                        err++;
 828                }
 829                break;
 830        case TRIG_EXT:
 831                /* Force to external trigger 0. */
 832                if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
 833                        cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
 834                                                      ~CR_FLAGS_MASK);
 835                        err++;
 836                }
 837                /* Only allow flags CR_EDGE and CR_INVERT.  Ignore CR_EDGE. */
 838                if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
 839                     ~(CR_EDGE | CR_INVERT)) != 0) {
 840                        cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
 841                                                      CR_FLAGS_MASK & ~(CR_EDGE
 842                                                                        |
 843                                                                        CR_INVERT));
 844                        err++;
 845                }
 846                break;
 847        }
 848
 849        /* cmd->convert_src == TRIG_NOW */
 850        if (cmd->convert_arg != 0) {
 851                cmd->convert_arg = 0;
 852                err++;
 853        }
 854
 855        /* cmd->scan_end_arg == TRIG_COUNT */
 856        if (cmd->scan_end_arg != cmd->chanlist_len) {
 857                cmd->scan_end_arg = cmd->chanlist_len;
 858                err++;
 859        }
 860
 861        switch (cmd->stop_src) {
 862        case TRIG_COUNT:
 863                /* Any count allowed. */
 864                break;
 865        case TRIG_EXT:
 866                /* Force to external trigger 0. */
 867                if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
 868                        cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
 869                                                ~CR_FLAGS_MASK);
 870                        err++;
 871                }
 872                /* The only flag allowed is CR_EDGE, which is ignored. */
 873                if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
 874                        cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
 875                                                CR_FLAGS_MASK & ~CR_EDGE);
 876                }
 877                break;
 878        case TRIG_NONE:
 879                if (cmd->stop_arg != 0) {
 880                        cmd->stop_arg = 0;
 881                        err++;
 882                }
 883                break;
 884        }
 885
 886        if (err)
 887                return 3;
 888
 889        /* Step 4: fix up any arguments. */
 890
 891        if (cmd->scan_begin_src == TRIG_TIMER) {
 892                unsigned int div1, div2, round;
 893                int round_mode = cmd->flags & TRIG_ROUND_MASK;
 894
 895                tmp = cmd->scan_begin_arg;
 896                /* Check whether to use a single timer. */
 897                switch (round_mode) {
 898                case TRIG_ROUND_NEAREST:
 899                default:
 900                        round = TIMEBASE_10MHZ / 2;
 901                        break;
 902                case TRIG_ROUND_DOWN:
 903                        round = 0;
 904                        break;
 905                case TRIG_ROUND_UP:
 906                        round = TIMEBASE_10MHZ - 1;
 907                        break;
 908                }
 909                /* Be careful to avoid overflow! */
 910                div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
 911                div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
 912                    TIMEBASE_10MHZ;
 913                if (div2 <= 0x10000) {
 914                        /* A single timer will suffice. */
 915                        if (div2 < 2)
 916                                div2 = 2;
 917                        cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
 918                        if (cmd->scan_begin_arg < div2 ||
 919                            cmd->scan_begin_arg < TIMEBASE_10MHZ) {
 920                                /* Overflow! */
 921                                cmd->scan_begin_arg = MAX_SCAN_PERIOD;
 922                        }
 923                } else {
 924                        /* Use two timers. */
 925                        div1 = devpriv->cached_div1;
 926                        div2 = devpriv->cached_div2;
 927                        pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
 928                                                   &cmd->scan_begin_arg,
 929                                                   round_mode);
 930                        devpriv->cached_div1 = div1;
 931                        devpriv->cached_div2 = div2;
 932                }
 933                if (tmp != cmd->scan_begin_arg)
 934                        err++;
 935
 936        }
 937
 938        if (err)
 939                return 4;
 940
 941        /* Step 5: check channel list. */
 942
 943        if (cmd->chanlist && (cmd->chanlist_len > 0)) {
 944                unsigned int range;
 945                enum { range_err = 1, dupchan_err = 2, };
 946                unsigned errors;
 947                unsigned int n;
 948                unsigned int ch;
 949
 950                /*
 951                 * Check all channels have the same range index.  Don't care
 952                 * about analogue reference, as we can't configure it.
 953                 *
 954                 * Check the list has no duplicate channels.
 955                 */
 956                range = CR_RANGE(cmd->chanlist[0]);
 957                errors = 0;
 958                tmp = 0;
 959                for (n = 0; n < cmd->chanlist_len; n++) {
 960                        ch = CR_CHAN(cmd->chanlist[n]);
 961                        if (tmp & (1U << ch))
 962                                errors |= dupchan_err;
 963
 964                        tmp |= (1U << ch);
 965                        if (CR_RANGE(cmd->chanlist[n]) != range)
 966                                errors |= range_err;
 967
 968                }
 969                if (errors) {
 970                        if (errors & dupchan_err) {
 971                                DPRINTK("comedi%d: " DRIVER_NAME
 972                                        ": ao_cmdtest: "
 973                                        "entries in chanlist must contain no "
 974                                        "duplicate channels\n", dev->minor);
 975                        }
 976                        if (errors & range_err) {
 977                                DPRINTK("comedi%d: " DRIVER_NAME
 978                                        ": ao_cmdtest: "
 979                                        "entries in chanlist must all have "
 980                                        "the same range index\n", dev->minor);
 981                        }
 982                        err++;
 983                }
 984        }
 985
 986        if (err)
 987                return 5;
 988
 989        return 0;
 990}
 991
 992/*
 993 * 'do_cmd' function for AO subdevice.
 994 */
 995static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 996{
 997        struct comedi_cmd *cmd = &s->async->cmd;
 998        int range;
 999        unsigned int i, j;
1000        unsigned int ch;
1001        unsigned int rank;
1002        unsigned long flags;
1003
1004        /* Cannot handle null/empty chanlist. */
1005        if (cmd->chanlist == NULL || cmd->chanlist_len == 0)
1006                return -EINVAL;
1007
1008
1009        /* Determine which channels are enabled and their load order.  */
1010        devpriv->ao_enab = 0;
1011
1012        for (i = 0; i < cmd->chanlist_len; i++) {
1013                ch = CR_CHAN(cmd->chanlist[i]);
1014                devpriv->ao_enab |= 1U << ch;
1015                rank = 0;
1016                for (j = 0; j < cmd->chanlist_len; j++) {
1017                        if (CR_CHAN(cmd->chanlist[j]) < ch)
1018                                rank++;
1019
1020                }
1021                devpriv->ao_scan_order[rank] = i;
1022        }
1023
1024        /* Set enabled channels. */
1025        outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
1026
1027        /* Determine range and polarity.  All channels the same.  */
1028        range = CR_RANGE(cmd->chanlist[0]);
1029
1030        /*
1031         * Set DAC range and polarity.
1032         * Set DAC scan trigger source to 'none'.
1033         * Set DAC FIFO interrupt trigger level to 'not half full'.
1034         * Reset DAC FIFO.
1035         *
1036         * N.B. DAC FIFO interrupts are currently disabled.
1037         */
1038        devpriv->daccon = COMBINE(devpriv->daccon,
1039                                  (devpriv->
1040                                   hwrange[range] | PCI224_DACCON_TRIG_NONE |
1041                                   PCI224_DACCON_FIFOINTR_NHALF),
1042                                  (PCI224_DACCON_POLAR_MASK |
1043                                   PCI224_DACCON_VREF_MASK |
1044                                   PCI224_DACCON_TRIG_MASK |
1045                                   PCI224_DACCON_FIFOINTR_MASK));
1046        outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1047             dev->iobase + PCI224_DACCON);
1048
1049        if (cmd->scan_begin_src == TRIG_TIMER) {
1050                unsigned int div1, div2, round;
1051                unsigned int ns = cmd->scan_begin_arg;
1052                int round_mode = cmd->flags & TRIG_ROUND_MASK;
1053
1054                /* Check whether to use a single timer. */
1055                switch (round_mode) {
1056                case TRIG_ROUND_NEAREST:
1057                default:
1058                        round = TIMEBASE_10MHZ / 2;
1059                        break;
1060                case TRIG_ROUND_DOWN:
1061                        round = 0;
1062                        break;
1063                case TRIG_ROUND_UP:
1064                        round = TIMEBASE_10MHZ - 1;
1065                        break;
1066                }
1067                /* Be careful to avoid overflow! */
1068                div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
1069                div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
1070                    TIMEBASE_10MHZ;
1071                if (div2 <= 0x10000) {
1072                        /* A single timer will suffice. */
1073                        if (div2 < 2)
1074                                div2 = 2;
1075                        div2 &= 0xffff;
1076                        div1 = 1;       /* Flag that single timer to be used. */
1077                } else {
1078                        /* Use two timers. */
1079                        div1 = devpriv->cached_div1;
1080                        div2 = devpriv->cached_div2;
1081                        pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
1082                                                   &ns, round_mode);
1083                }
1084
1085                /*
1086                 * The output of timer Z2-0 will be used as the scan trigger
1087                 * source.
1088                 */
1089                /* Make sure Z2-0 is gated on.  */
1090                outb(GAT_CONFIG(0, GAT_VCC),
1091                     devpriv->iobase1 + PCI224_ZGAT_SCE);
1092                if (div1 == 1) {
1093                        /* Not cascading.  Z2-0 needs 10 MHz clock. */
1094                        outb(CLK_CONFIG(0, CLK_10MHZ),
1095                             devpriv->iobase1 + PCI224_ZCLK_SCE);
1096                } else {
1097                        /* Cascading with Z2-2. */
1098                        /* Make sure Z2-2 is gated on.  */
1099                        outb(GAT_CONFIG(2, GAT_VCC),
1100                             devpriv->iobase1 + PCI224_ZGAT_SCE);
1101                        /* Z2-2 needs 10 MHz clock. */
1102                        outb(CLK_CONFIG(2, CLK_10MHZ),
1103                             devpriv->iobase1 + PCI224_ZCLK_SCE);
1104                        /* Load Z2-2 mode (2) and counter (div1). */
1105                        i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
1106                                   2, div1, 2);
1107                        /* Z2-0 is clocked from Z2-2's output. */
1108                        outb(CLK_CONFIG(0, CLK_OUTNM1),
1109                             devpriv->iobase1 + PCI224_ZCLK_SCE);
1110                }
1111                /* Load Z2-0 mode (2) and counter (div2). */
1112                i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
1113        }
1114
1115        /*
1116         * Sort out end of acquisition.
1117         */
1118        switch (cmd->stop_src) {
1119        case TRIG_COUNT:
1120                /* Fixed number of scans.  */
1121                devpriv->ao_stop_continuous = 0;
1122                devpriv->ao_stop_count = cmd->stop_arg;
1123                break;
1124        default:
1125                /* Continuous scans. */
1126                devpriv->ao_stop_continuous = 1;
1127                devpriv->ao_stop_count = 0;
1128                break;
1129        }
1130
1131        /*
1132         * Sort out start of acquisition.
1133         */
1134        switch (cmd->start_src) {
1135        case TRIG_INT:
1136                spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1137                s->async->inttrig = &pci224_ao_inttrig_start;
1138                spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1139                break;
1140        case TRIG_EXT:
1141                /* Enable external interrupt trigger to start acquisition. */
1142                spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1143                devpriv->intsce |= PCI224_INTR_EXT;
1144                outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
1145                spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1146                break;
1147        }
1148
1149        return 0;
1150}
1151
1152/*
1153 * 'cancel' function for AO subdevice.
1154 */
1155static int pci224_ao_cancel(struct comedi_device *dev,
1156                            struct comedi_subdevice *s)
1157{
1158        pci224_ao_stop(dev, s);
1159        return 0;
1160}
1161
1162/*
1163 * 'munge' data for AO command.
1164 */
1165static void
1166pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
1167                void *data, unsigned int num_bytes, unsigned int chan_index)
1168{
1169        struct comedi_async *async = s->async;
1170        short *array = data;
1171        unsigned int length = num_bytes / sizeof(*array);
1172        unsigned int offset;
1173        unsigned int shift;
1174        unsigned int i;
1175
1176        /* The hardware expects 16-bit numbers. */
1177        shift = 16 - thisboard->ao_bits;
1178        /* Channels will be all bipolar or all unipolar. */
1179        if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
1180             PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
1181                /* Unipolar */
1182                offset = 0;
1183        } else {
1184                /* Bipolar */
1185                offset = 32768;
1186        }
1187        /* Munge the data. */
1188        for (i = 0; i < length; i++)
1189                array[i] = (array[i] << shift) - offset;
1190
1191}
1192
1193/*
1194 * Interrupt handler.
1195 */
1196static irqreturn_t pci224_interrupt(int irq, void *d)
1197{
1198        struct comedi_device *dev = d;
1199        struct comedi_subdevice *s = &dev->subdevices[0];
1200        struct comedi_cmd *cmd;
1201        unsigned char intstat, valid_intstat;
1202        unsigned char curenab;
1203        int retval = 0;
1204        unsigned long flags;
1205
1206        intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
1207        if (intstat) {
1208                retval = 1;
1209                spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1210                valid_intstat = devpriv->intsce & intstat;
1211                /* Temporarily disable interrupt sources. */
1212                curenab = devpriv->intsce & ~intstat;
1213                outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
1214                devpriv->intr_running = 1;
1215                devpriv->intr_cpuid = THISCPU;
1216                spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1217                if (valid_intstat != 0) {
1218                        cmd = &s->async->cmd;
1219                        if (valid_intstat & PCI224_INTR_EXT) {
1220                                devpriv->intsce &= ~PCI224_INTR_EXT;
1221                                if (cmd->start_src == TRIG_EXT)
1222                                        pci224_ao_start(dev, s);
1223                                else if (cmd->stop_src == TRIG_EXT)
1224                                        pci224_ao_stop(dev, s);
1225
1226                        }
1227                        if (valid_intstat & PCI224_INTR_DAC)
1228                                pci224_ao_handle_fifo(dev, s);
1229
1230                }
1231                /* Reenable interrupt sources. */
1232                spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1233                if (curenab != devpriv->intsce) {
1234                        outb(devpriv->intsce,
1235                             devpriv->iobase1 + PCI224_INT_SCE);
1236                }
1237                devpriv->intr_running = 0;
1238                spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1239        }
1240        return IRQ_RETVAL(retval);
1241}
1242
1243/*
1244 * This function looks for a board matching the supplied PCI device.
1245 */
1246static const struct pci224_board
1247*pci224_find_pci_board(struct pci_dev *pci_dev)
1248{
1249        int i;
1250
1251        for (i = 0; i < ARRAY_SIZE(pci224_boards); i++)
1252                if (pci_dev->device == pci224_boards[i].devid)
1253                        return &pci224_boards[i];
1254        return NULL;
1255}
1256
1257/*
1258 * This function looks for a PCI device matching the requested board name,
1259 * bus and slot.
1260 */
1261static int
1262pci224_find_pci(struct comedi_device *dev, int bus, int slot,
1263                struct pci_dev **pci_dev_p)
1264{
1265        struct pci_dev *pci_dev = NULL;
1266
1267        *pci_dev_p = NULL;
1268
1269        /* Look for matching PCI device. */
1270        for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
1271             pci_dev != NULL;
1272             pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
1273                                      pci_dev)) {
1274                /* If bus/slot specified, check them. */
1275                if (bus || slot) {
1276                        if (bus != pci_dev->bus->number
1277                            || slot != PCI_SLOT(pci_dev->devfn))
1278                                continue;
1279                }
1280                if (thisboard->model == any_model) {
1281                        /* Match any supported model. */
1282                        const struct pci224_board *board_ptr;
1283                        board_ptr = pci224_find_pci_board(pci_dev);
1284                        if (board_ptr == NULL)
1285                                continue;
1286                        /* Change board_ptr to matched board. */
1287                        dev->board_ptr = board_ptr;
1288                } else {
1289                        /* Match specific model name. */
1290                        if (thisboard->devid != pci_dev->device)
1291                                continue;
1292                }
1293
1294                /* Found a match. */
1295                *pci_dev_p = pci_dev;
1296                return 0;
1297        }
1298        /* No match found. */
1299        if (bus || slot) {
1300                printk(KERN_ERR "comedi%d: error! "
1301                       "no %s found at pci %02x:%02x!\n",
1302                       dev->minor, thisboard->name, bus, slot);
1303        } else {
1304                printk(KERN_ERR "comedi%d: error! no %s found!\n",
1305                       dev->minor, thisboard->name);
1306        }
1307        return -EIO;
1308}
1309
1310/*
1311 * Common part of attach and attach_pci.
1312 */
1313static int pci224_attach_common(struct comedi_device *dev,
1314                                struct pci_dev *pci_dev, int *options)
1315{
1316        struct comedi_subdevice *s;
1317        unsigned int irq;
1318        unsigned n;
1319        int ret;
1320
1321        devpriv->pci_dev = pci_dev;
1322        ret = comedi_pci_enable(pci_dev, DRIVER_NAME);
1323        if (ret < 0) {
1324                printk(KERN_ERR
1325                       "comedi%d: error! cannot enable PCI device "
1326                       "and request regions!\n", dev->minor);
1327                return ret;
1328        }
1329        spin_lock_init(&devpriv->ao_spinlock);
1330
1331        devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1332        dev->iobase = pci_resource_start(pci_dev, 3);
1333        irq = pci_dev->irq;
1334
1335        /* Allocate readback buffer for AO channels. */
1336        devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
1337                                       thisboard->ao_chans, GFP_KERNEL);
1338        if (!devpriv->ao_readback)
1339                return -ENOMEM;
1340
1341
1342        /* Allocate buffer to hold values for AO channel scan. */
1343        devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
1344                                        thisboard->ao_chans, GFP_KERNEL);
1345        if (!devpriv->ao_scan_vals)
1346                return -ENOMEM;
1347
1348
1349        /* Allocate buffer to hold AO channel scan order. */
1350        devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
1351                                         thisboard->ao_chans, GFP_KERNEL);
1352        if (!devpriv->ao_scan_order)
1353                return -ENOMEM;
1354
1355
1356        /* Disable interrupt sources. */
1357        devpriv->intsce = 0;
1358        outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1359
1360        /* Initialize the DAC hardware. */
1361        outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1362        outw(0, dev->iobase + PCI224_DACCEN);
1363        outw(0, dev->iobase + PCI224_FIFOSIZ);
1364        devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1365                           PCI224_DACCON_FIFOENAB |
1366                           PCI224_DACCON_FIFOINTR_EMPTY);
1367        outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1368             dev->iobase + PCI224_DACCON);
1369
1370        /* Allocate subdevices.  There is only one!  */
1371        ret = alloc_subdevices(dev, 1);
1372        if (ret < 0) {
1373                printk(KERN_ERR "comedi%d: error! out of memory!\n",
1374                       dev->minor);
1375                return ret;
1376        }
1377
1378        s = dev->subdevices + 0;
1379        /* Analog output subdevice. */
1380        s->type = COMEDI_SUBD_AO;
1381        s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1382        s->n_chan = thisboard->ao_chans;
1383        s->maxdata = (1 << thisboard->ao_bits) - 1;
1384        s->insn_write = &pci224_ao_insn_write;
1385        s->insn_read = &pci224_ao_insn_read;
1386        s->len_chanlist = s->n_chan;
1387
1388        dev->write_subdev = s;
1389        s->do_cmd = &pci224_ao_cmd;
1390        s->do_cmdtest = &pci224_ao_cmdtest;
1391        s->cancel = &pci224_ao_cancel;
1392        s->munge = &pci224_ao_munge;
1393
1394        /* Sort out channel range options. */
1395        if (thisboard->model == pci234_model) {
1396                /* PCI234 range options. */
1397                const struct comedi_lrange **range_table_list;
1398
1399                s->range_table_list = range_table_list =
1400                    kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
1401                            GFP_KERNEL);
1402                if (!s->range_table_list)
1403                        return -ENOMEM;
1404
1405                if (options) {
1406                        for (n = 2; n < 3 + s->n_chan; n++) {
1407                                if (options[n] < 0 || options[n] > 1) {
1408                                        printk(KERN_WARNING
1409                                               "comedi%d: %s: warning! bad options[%u]=%d\n",
1410                                               dev->minor, DRIVER_NAME, n,
1411                                               options[n]);
1412                                }
1413                        }
1414                }
1415                for (n = 0; n < s->n_chan; n++) {
1416                        if (n < COMEDI_NDEVCONFOPTS - 3 && options &&
1417                            options[3 + n] == 1) {
1418                                if (options[2] == 1)
1419                                        range_table_list[n] = &range_pci234_ext;
1420                                else
1421                                        range_table_list[n] = &range_bipolar5;
1422
1423                        } else {
1424                                if (options && options[2] == 1) {
1425                                        range_table_list[n] =
1426                                            &range_pci234_ext2;
1427                                } else {
1428                                        range_table_list[n] = &range_bipolar10;
1429                                }
1430                        }
1431                }
1432                devpriv->hwrange = hwrange_pci234;
1433        } else {
1434                /* PCI224 range options. */
1435                if (options && options[2] == 1) {
1436                        s->range_table = &range_pci224_external;
1437                        devpriv->hwrange = hwrange_pci224_external;
1438                } else {
1439                        if (options && options[2] != 0) {
1440                                printk(KERN_WARNING "comedi%d: %s: warning! "
1441                                       "bad options[2]=%d\n",
1442                                       dev->minor, DRIVER_NAME, options[2]);
1443                        }
1444                        s->range_table = &range_pci224_internal;
1445                        devpriv->hwrange = hwrange_pci224_internal;
1446                }
1447        }
1448
1449        dev->board_name = thisboard->name;
1450
1451        if (irq) {
1452                ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1453                                  DRIVER_NAME, dev);
1454                if (ret < 0) {
1455                        printk(KERN_ERR "comedi%d: error! "
1456                               "unable to allocate irq %u\n", dev->minor, irq);
1457                        return ret;
1458                } else {
1459                        dev->irq = irq;
1460                }
1461        }
1462
1463        printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1464        printk("(pci %s) ", pci_name(pci_dev));
1465        if (irq)
1466                printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1467        else
1468                printk("(no irq) ");
1469
1470
1471        printk("attached\n");
1472
1473        return 1;
1474}
1475
1476static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1477{
1478        struct pci_dev *pci_dev;
1479        int bus, slot;
1480        int ret;
1481
1482        printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME);
1483
1484        bus = it->options[0];
1485        slot = it->options[1];
1486        ret = alloc_private(dev, sizeof(struct pci224_private));
1487        if (ret < 0) {
1488                printk(KERN_ERR "comedi%d: error! out of memory!\n",
1489                       dev->minor);
1490                return ret;
1491        }
1492
1493        ret = pci224_find_pci(dev, bus, slot, &pci_dev);
1494        if (ret < 0)
1495                return ret;
1496
1497        return pci224_attach_common(dev, pci_dev, it->options);
1498}
1499
1500static int
1501pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev)
1502{
1503        int ret;
1504
1505        printk(KERN_DEBUG "comedi%d: %s: attach_pci %s\n", dev->minor,
1506               DRIVER_NAME, pci_name(pci_dev));
1507
1508        ret = alloc_private(dev, sizeof(struct pci224_private));
1509        if (ret < 0) {
1510                printk(KERN_ERR "comedi%d: error! out of memory!\n",
1511                       dev->minor);
1512                return ret;
1513        }
1514
1515        dev->board_ptr = pci224_find_pci_board(pci_dev);
1516        if (dev->board_ptr == NULL) {
1517                printk(KERN_ERR
1518                       "comedi%d: %s: BUG! cannot determine board type!\n",
1519                       dev->minor, DRIVER_NAME);
1520                return -EINVAL;
1521        }
1522        return pci224_attach_common(dev, pci_dev, NULL);
1523}
1524
1525static void pci224_detach(struct comedi_device *dev)
1526{
1527        if (dev->irq)
1528                free_irq(dev->irq, dev);
1529        if (dev->subdevices) {
1530                struct comedi_subdevice *s;
1531
1532                s = dev->subdevices + 0;
1533                /* AO subdevice */
1534                kfree(s->range_table_list);
1535        }
1536        if (devpriv) {
1537                kfree(devpriv->ao_readback);
1538                kfree(devpriv->ao_scan_vals);
1539                kfree(devpriv->ao_scan_order);
1540                if (devpriv->pci_dev) {
1541                        if (dev->iobase)
1542                                comedi_pci_disable(devpriv->pci_dev);
1543                        pci_dev_put(devpriv->pci_dev);
1544                }
1545        }
1546}
1547
1548static struct comedi_driver amplc_pci224_driver = {
1549        .driver_name    = "amplc_pci224",
1550        .module         = THIS_MODULE,
1551        .attach         = pci224_attach,
1552        .detach         = pci224_detach,
1553        .attach_pci     = pci224_attach_pci,
1554        .board_name     = &pci224_boards[0].name,
1555        .offset         = sizeof(struct pci224_board),
1556        .num_names      = ARRAY_SIZE(pci224_boards),
1557};
1558
1559static int __devinit amplc_pci224_pci_probe(struct pci_dev *dev,
1560                                                   const struct pci_device_id
1561                                                   *ent)
1562{
1563        return comedi_pci_auto_config(dev, &amplc_pci224_driver);
1564}
1565
1566static void __devexit amplc_pci224_pci_remove(struct pci_dev *dev)
1567{
1568        comedi_pci_auto_unconfig(dev);
1569}
1570
1571static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = {
1572        { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) },
1573        { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) },
1574        { 0 }
1575};
1576MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);
1577
1578static struct pci_driver amplc_pci224_pci_driver = {
1579        .name           = "amplc_pci224",
1580        .id_table       = amplc_pci224_pci_table,
1581        .probe          = amplc_pci224_pci_probe,
1582        .remove         = __devexit_p(amplc_pci224_pci_remove),
1583};
1584module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
1585
1586MODULE_AUTHOR("Comedi http://www.comedi.org");
1587MODULE_DESCRIPTION("Comedi low-level driver");
1588MODULE_LICENSE("GPL");
1589