linux/drivers/staging/comedi/drivers/amplc_pci230.c
<<
>>
Prefs
   1/*
   2 * comedi/drivers/amplc_pci230.c
   3 * Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards.
   4 *
   5 * Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au>
   6 *
   7 * COMEDI - Linux Control and Measurement Device Interface
   8 * Copyright (C) 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
  21/*
  22 * Driver: amplc_pci230
  23 * Description: Amplicon PCI230, PCI260 Multifunction I/O boards
  24 * Author: Allan Willcox <allanwillcox@ozemail.com.au>,
  25 *   Steve D Sharples <steve.sharples@nottingham.ac.uk>,
  26 *   Ian Abbott <abbotti@mev.co.uk>
  27 * Updated: Mon, 01 Sep 2014 10:09:16 +0000
  28 * Devices: [Amplicon] PCI230 (amplc_pci230), PCI230+, PCI260, PCI260+
  29 * Status: works
  30 *
  31 * Configuration options:
  32 *   none
  33 *
  34 * Manual configuration of PCI cards is not supported; they are configured
  35 * automatically.
  36 *
  37 * The PCI230+ and PCI260+ have the same PCI device IDs as the PCI230 and
  38 * PCI260, but can be distinguished by the size of the PCI regions.  A
  39 * card will be configured as a "+" model if detected as such.
  40 *
  41 * Subdevices:
  42 *
  43 *                 PCI230(+)    PCI260(+)
  44 *                 ---------    ---------
  45 *   Subdevices       3            1
  46 *         0          AI           AI
  47 *         1          AO
  48 *         2          DIO
  49 *
  50 * AI Subdevice:
  51 *
  52 *   The AI subdevice has 16 single-ended channels or 8 differential
  53 *   channels.
  54 *
  55 *   The PCI230 and PCI260 cards have 12-bit resolution.  The PCI230+ and
  56 *   PCI260+ cards have 16-bit resolution.
  57 *
  58 *   For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use
  59 *   inputs 14 and 15 for channel 7).  If the card is physically a PCI230
  60 *   or PCI260 then it actually uses a "pseudo-differential" mode where the
  61 *   inputs are sampled a few microseconds apart.  The PCI230+ and PCI260+
  62 *   use true differential sampling.  Another difference is that if the
  63 *   card is physically a PCI230 or PCI260, the inverting input is 2N,
  64 *   whereas for a PCI230+ or PCI260+ the inverting input is 2N+1.  So if a
  65 *   PCI230 is physically replaced by a PCI230+ (or a PCI260 with a
  66 *   PCI260+) and differential mode is used, the differential inputs need
  67 *   to be physically swapped on the connector.
  68 *
  69 *   The following input ranges are supported:
  70 *
  71 *     0 => [-10, +10] V
  72 *     1 => [-5, +5] V
  73 *     2 => [-2.5, +2.5] V
  74 *     3 => [-1.25, +1.25] V
  75 *     4 => [0, 10] V
  76 *     5 => [0, 5] V
  77 *     6 => [0, 2.5] V
  78 *
  79 * AI Commands:
  80 *
  81 *   +=========+==============+===========+============+==========+
  82 *   |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
  83 *   +=========+==============+===========+============+==========+
  84 *   |TRIG_NOW | TRIG_FOLLOW  |TRIG_TIMER | TRIG_COUNT |TRIG_NONE |
  85 *   |TRIG_INT |              |TRIG_EXT(3)|            |TRIG_COUNT|
  86 *   |         |              |TRIG_INT   |            |          |
  87 *   |         |--------------|-----------|            |          |
  88 *   |         | TRIG_TIMER(1)|TRIG_TIMER |            |          |
  89 *   |         | TRIG_EXT(2)  |           |            |          |
  90 *   |         | TRIG_INT     |           |            |          |
  91 *   +---------+--------------+-----------+------------+----------+
  92 *
  93 *   Note 1: If AI command and AO command are used simultaneously, only
  94 *           one may have scan_begin_src == TRIG_TIMER.
  95 *
  96 *   Note 2: For PCI230 and PCI230+, scan_begin_src == TRIG_EXT uses
  97 *           DIO channel 16 (pin 49) which will need to be configured as
  98 *           a digital input.  For PCI260+, the EXTTRIG/EXTCONVCLK input
  99 *           (pin 17) is used instead.  For PCI230, scan_begin_src ==
 100 *           TRIG_EXT is not supported.  The trigger is a rising edge
 101 *           on the input.
 102 *
 103 *   Note 3: For convert_src == TRIG_EXT, the EXTTRIG/EXTCONVCLK input
 104 *           (pin 25 on PCI230(+), pin 17 on PCI260(+)) is used.  The
 105 *           convert_arg value is interpreted as follows:
 106 *
 107 *             convert_arg == (CR_EDGE | 0) => rising edge
 108 *             convert_arg == (CR_EDGE | CR_INVERT | 0) => falling edge
 109 *             convert_arg == 0 => falling edge (backwards compatibility)
 110 *             convert_arg == 1 => rising edge (backwards compatibility)
 111 *
 112 *   All entries in the channel list must use the same analogue reference.
 113 *   If the analogue reference is not AREF_DIFF (not differential) each
 114 *   pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same
 115 *   input range.  The input ranges used in the sequence must be all
 116 *   bipolar (ranges 0 to 3) or all unipolar (ranges 4 to 6).  The channel
 117 *   sequence must consist of 1 or more identical subsequences.  Within the
 118 *   subsequence, channels must be in ascending order with no repeated
 119 *   channels.  For example, the following sequences are valid: 0 1 2 3
 120 *   (single valid subsequence), 0 2 3 5 0 2 3 5 (repeated valid
 121 *   subsequence), 1 1 1 1 (repeated valid subsequence).  The following
 122 *   sequences are invalid: 0 3 2 1 (invalid subsequence), 0 2 3 5 0 2 3
 123 *   (incompletely repeated subsequence).  Some versions of the PCI230+ and
 124 *   PCI260+ have a bug that requires a subsequence longer than one entry
 125 *   long to include channel 0.
 126 *
 127 * AO Subdevice:
 128 *
 129 *   The AO subdevice has 2 channels with 12-bit resolution.
 130 *   The following output ranges are supported:
 131 *     0 => [0, 10] V
 132 *     1 => [-10, +10] V
 133 *
 134 * AO Commands:
 135 *
 136 *   +=========+==============+===========+============+==========+
 137 *   |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
 138 *   +=========+==============+===========+============+==========+
 139 *   |TRIG_INT | TRIG_TIMER(1)| TRIG_NOW  | TRIG_COUNT |TRIG_NONE |
 140 *   |         | TRIG_EXT(2)  |           |            |TRIG_COUNT|
 141 *   |         | TRIG_INT     |           |            |          |
 142 *   +---------+--------------+-----------+------------+----------+
 143 *
 144 *   Note 1: If AI command and AO command are used simultaneously, only
 145 *           one may have scan_begin_src == TRIG_TIMER.
 146 *
 147 *   Note 2: scan_begin_src == TRIG_EXT is only supported if the card is
 148 *           configured as a PCI230+ and is only supported on later
 149 *           versions of the card.  As a card configured as a PCI230+ is
 150 *           not guaranteed to support external triggering, please consider
 151 *           this support to be a bonus.  It uses the EXTTRIG/ EXTCONVCLK
 152 *           input (PCI230+ pin 25).  Triggering will be on the rising edge
 153 *           unless the CR_INVERT flag is set in scan_begin_arg.
 154 *
 155 *   The channels in the channel sequence must be in ascending order with
 156 *   no repeats.  All entries in the channel sequence must use the same
 157 *   output range.
 158 *
 159 * DIO Subdevice:
 160 *
 161 *   The DIO subdevice is a 8255 chip providing 24 DIO channels.  The DIO
 162 *   channels are configurable as inputs or outputs in four groups:
 163 *
 164 *     Port A  - channels  0 to  7
 165 *     Port B  - channels  8 to 15
 166 *     Port CL - channels 16 to 19
 167 *     Port CH - channels 20 to 23
 168 *
 169 *   Only mode 0 of the 8255 chip is supported.
 170 *
 171 *   Bit 0 of port C (DIO channel 16) is also used as an external scan
 172 *   trigger input for AI commands on PCI230 and PCI230+, so would need to
 173 *   be configured as an input to use it for that purpose.
 174 */
 175
 176/*
 177 * Extra triggered scan functionality, interrupt bug-fix added by Steve
 178 * Sharples.  Support for PCI230+/260+, more triggered scan functionality,
 179 * and workarounds for (or detection of) various hardware problems added
 180 * by Ian Abbott.
 181 */
 182
 183#include <linux/module.h>
 184#include <linux/delay.h>
 185#include <linux/interrupt.h>
 186
 187#include "../comedi_pci.h"
 188
 189#include "comedi_8254.h"
 190#include "8255.h"
 191
 192/*
 193 * PCI230 PCI configuration register information
 194 */
 195#define PCI_DEVICE_ID_PCI230 0x0000
 196#define PCI_DEVICE_ID_PCI260 0x0006
 197
 198/*
 199 * PCI230 i/o space 1 registers.
 200 */
 201#define PCI230_PPI_X_BASE       0x00    /* User PPI (82C55) base */
 202#define PCI230_PPI_X_A          0x00    /* User PPI (82C55) port A */
 203#define PCI230_PPI_X_B          0x01    /* User PPI (82C55) port B */
 204#define PCI230_PPI_X_C          0x02    /* User PPI (82C55) port C */
 205#define PCI230_PPI_X_CMD        0x03    /* User PPI (82C55) control word */
 206#define PCI230_Z2_CT_BASE       0x14    /* 82C54 counter/timer base */
 207#define PCI230_ZCLK_SCE         0x1A    /* Group Z Clock Configuration */
 208#define PCI230_ZGAT_SCE         0x1D    /* Group Z Gate Configuration */
 209#define PCI230_INT_SCE          0x1E    /* Interrupt source mask (w) */
 210#define PCI230_INT_STAT         0x1E    /* Interrupt status (r) */
 211
 212/*
 213 * PCI230 i/o space 2 registers.
 214 */
 215#define PCI230_DACCON           0x00    /* DAC control */
 216#define PCI230_DACOUT1          0x02    /* DAC channel 0 (w) */
 217#define PCI230_DACOUT2          0x04    /* DAC channel 1 (w) (not FIFO mode) */
 218#define PCI230_ADCDATA          0x08    /* ADC data (r) */
 219#define PCI230_ADCSWTRIG        0x08    /* ADC software trigger (w) */
 220#define PCI230_ADCCON           0x0A    /* ADC control */
 221#define PCI230_ADCEN            0x0C    /* ADC channel enable bits */
 222#define PCI230_ADCG             0x0E    /* ADC gain control bits */
 223/* PCI230+ i/o space 2 additional registers. */
 224#define PCI230P_ADCTRIG         0x10    /* ADC start acquisition trigger */
 225#define PCI230P_ADCTH           0x12    /* ADC analog trigger threshold */
 226#define PCI230P_ADCFFTH         0x14    /* ADC FIFO interrupt threshold */
 227#define PCI230P_ADCFFLEV        0x16    /* ADC FIFO level (r) */
 228#define PCI230P_ADCPTSC         0x18    /* ADC pre-trigger sample count (r) */
 229#define PCI230P_ADCHYST         0x1A    /* ADC analog trigger hysteresys */
 230#define PCI230P_EXTFUNC         0x1C    /* Extended functions */
 231#define PCI230P_HWVER           0x1E    /* Hardware version (r) */
 232/* PCI230+ hardware version 2 onwards. */
 233#define PCI230P2_DACDATA        0x02    /* DAC data (FIFO mode) (w) */
 234#define PCI230P2_DACSWTRIG      0x02    /* DAC soft trigger (FIFO mode) (r) */
 235#define PCI230P2_DACEN          0x06    /* DAC channel enable (FIFO mode) */
 236
 237/*
 238 * DACCON read-write values.
 239 */
 240#define PCI230_DAC_OR(x)                (((x) & 0x1) << 0)
 241#define PCI230_DAC_OR_UNI               PCI230_DAC_OR(0) /* Output unipolar */
 242#define PCI230_DAC_OR_BIP               PCI230_DAC_OR(1) /* Output bipolar */
 243#define PCI230_DAC_OR_MASK              PCI230_DAC_OR(1)
 244/*
 245 * The following applies only if DAC FIFO support is enabled in the EXTFUNC
 246 * register (and only for PCI230+ hardware version 2 onwards).
 247 */
 248#define PCI230P2_DAC_FIFO_EN            BIT(8) /* FIFO enable */
 249/*
 250 * The following apply only if the DAC FIFO is enabled (and only for PCI230+
 251 * hardware version 2 onwards).
 252 */
 253#define PCI230P2_DAC_TRIG(x)            (((x) & 0x7) << 2)
 254#define PCI230P2_DAC_TRIG_NONE          PCI230P2_DAC_TRIG(0) /* none */
 255#define PCI230P2_DAC_TRIG_SW            PCI230P2_DAC_TRIG(1) /* soft trig */
 256#define PCI230P2_DAC_TRIG_EXTP          PCI230P2_DAC_TRIG(2) /* ext + edge */
 257#define PCI230P2_DAC_TRIG_EXTN          PCI230P2_DAC_TRIG(3) /* ext - edge */
 258#define PCI230P2_DAC_TRIG_Z2CT0         PCI230P2_DAC_TRIG(4) /* Z2 CT0 out */
 259#define PCI230P2_DAC_TRIG_Z2CT1         PCI230P2_DAC_TRIG(5) /* Z2 CT1 out */
 260#define PCI230P2_DAC_TRIG_Z2CT2         PCI230P2_DAC_TRIG(6) /* Z2 CT2 out */
 261#define PCI230P2_DAC_TRIG_MASK          PCI230P2_DAC_TRIG(7)
 262#define PCI230P2_DAC_FIFO_WRAP          BIT(7) /* FIFO wraparound mode */
 263#define PCI230P2_DAC_INT_FIFO(x)        (((x) & 7) << 9)
 264#define PCI230P2_DAC_INT_FIFO_EMPTY     PCI230P2_DAC_INT_FIFO(0) /* empty */
 265#define PCI230P2_DAC_INT_FIFO_NEMPTY    PCI230P2_DAC_INT_FIFO(1) /* !empty */
 266#define PCI230P2_DAC_INT_FIFO_NHALF     PCI230P2_DAC_INT_FIFO(2) /* !half */
 267#define PCI230P2_DAC_INT_FIFO_HALF      PCI230P2_DAC_INT_FIFO(3) /* half */
 268#define PCI230P2_DAC_INT_FIFO_NFULL     PCI230P2_DAC_INT_FIFO(4) /* !full */
 269#define PCI230P2_DAC_INT_FIFO_FULL      PCI230P2_DAC_INT_FIFO(5) /* full */
 270#define PCI230P2_DAC_INT_FIFO_MASK      PCI230P2_DAC_INT_FIFO(7)
 271
 272/*
 273 * DACCON read-only values.
 274 */
 275#define PCI230_DAC_BUSY                 BIT(1) /* DAC busy. */
 276/*
 277 * The following apply only if the DAC FIFO is enabled (and only for PCI230+
 278 * hardware version 2 onwards).
 279 */
 280#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED      BIT(5) /* Underrun error */
 281#define PCI230P2_DAC_FIFO_EMPTY         BIT(13) /* FIFO empty */
 282#define PCI230P2_DAC_FIFO_FULL          BIT(14) /* FIFO full */
 283#define PCI230P2_DAC_FIFO_HALF          BIT(15) /* FIFO half full */
 284
 285/*
 286 * DACCON write-only, transient values.
 287 */
 288/*
 289 * The following apply only if the DAC FIFO is enabled (and only for PCI230+
 290 * hardware version 2 onwards).
 291 */
 292#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR        BIT(5) /* Clear underrun */
 293#define PCI230P2_DAC_FIFO_RESET         BIT(12) /* FIFO reset */
 294
 295/*
 296 * PCI230+ hardware version 2 DAC FIFO levels.
 297 */
 298#define PCI230P2_DAC_FIFOLEVEL_HALF     512
 299#define PCI230P2_DAC_FIFOLEVEL_FULL     1024
 300/* Free space in DAC FIFO. */
 301#define PCI230P2_DAC_FIFOROOM_EMPTY             PCI230P2_DAC_FIFOLEVEL_FULL
 302#define PCI230P2_DAC_FIFOROOM_ONETOHALF         \
 303        (PCI230P2_DAC_FIFOLEVEL_FULL - PCI230P2_DAC_FIFOLEVEL_HALF)
 304#define PCI230P2_DAC_FIFOROOM_HALFTOFULL        1
 305#define PCI230P2_DAC_FIFOROOM_FULL              0
 306
 307/*
 308 * ADCCON read/write values.
 309 */
 310#define PCI230_ADC_TRIG(x)              (((x) & 0x7) << 0)
 311#define PCI230_ADC_TRIG_NONE            PCI230_ADC_TRIG(0) /* none */
 312#define PCI230_ADC_TRIG_SW              PCI230_ADC_TRIG(1) /* soft trig */
 313#define PCI230_ADC_TRIG_EXTP            PCI230_ADC_TRIG(2) /* ext + edge */
 314#define PCI230_ADC_TRIG_EXTN            PCI230_ADC_TRIG(3) /* ext - edge */
 315#define PCI230_ADC_TRIG_Z2CT0           PCI230_ADC_TRIG(4) /* Z2 CT0 out*/
 316#define PCI230_ADC_TRIG_Z2CT1           PCI230_ADC_TRIG(5) /* Z2 CT1 out */
 317#define PCI230_ADC_TRIG_Z2CT2           PCI230_ADC_TRIG(6) /* Z2 CT2 out */
 318#define PCI230_ADC_TRIG_MASK            PCI230_ADC_TRIG(7)
 319#define PCI230_ADC_IR(x)                (((x) & 0x1) << 3)
 320#define PCI230_ADC_IR_UNI               PCI230_ADC_IR(0) /* Input unipolar */
 321#define PCI230_ADC_IR_BIP               PCI230_ADC_IR(1) /* Input bipolar */
 322#define PCI230_ADC_IR_MASK              PCI230_ADC_IR(1)
 323#define PCI230_ADC_IM(x)                (((x) & 0x1) << 4)
 324#define PCI230_ADC_IM_SE                PCI230_ADC_IM(0) /* single ended */
 325#define PCI230_ADC_IM_DIF               PCI230_ADC_IM(1) /* differential */
 326#define PCI230_ADC_IM_MASK              PCI230_ADC_IM(1)
 327#define PCI230_ADC_FIFO_EN              BIT(8) /* FIFO enable */
 328#define PCI230_ADC_INT_FIFO(x)          (((x) & 0x7) << 9)
 329#define PCI230_ADC_INT_FIFO_EMPTY       PCI230_ADC_INT_FIFO(0) /* empty */
 330#define PCI230_ADC_INT_FIFO_NEMPTY      PCI230_ADC_INT_FIFO(1) /* !empty */
 331#define PCI230_ADC_INT_FIFO_NHALF       PCI230_ADC_INT_FIFO(2) /* !half */
 332#define PCI230_ADC_INT_FIFO_HALF        PCI230_ADC_INT_FIFO(3) /* half */
 333#define PCI230_ADC_INT_FIFO_NFULL       PCI230_ADC_INT_FIFO(4) /* !full */
 334#define PCI230_ADC_INT_FIFO_FULL        PCI230_ADC_INT_FIFO(5) /* full */
 335#define PCI230P_ADC_INT_FIFO_THRESH     PCI230_ADC_INT_FIFO(7) /* threshold */
 336#define PCI230_ADC_INT_FIFO_MASK        PCI230_ADC_INT_FIFO(7)
 337
 338/*
 339 * ADCCON write-only, transient values.
 340 */
 341#define PCI230_ADC_FIFO_RESET           BIT(12) /* FIFO reset */
 342#define PCI230_ADC_GLOB_RESET           BIT(13) /* Global reset */
 343
 344/*
 345 * ADCCON read-only values.
 346 */
 347#define PCI230_ADC_BUSY                 BIT(15) /* ADC busy */
 348#define PCI230_ADC_FIFO_EMPTY           BIT(12) /* FIFO empty */
 349#define PCI230_ADC_FIFO_FULL            BIT(13) /* FIFO full */
 350#define PCI230_ADC_FIFO_HALF            BIT(14) /* FIFO half full */
 351#define PCI230_ADC_FIFO_FULL_LATCHED    BIT(5)  /* FIFO overrun occurred */
 352
 353/*
 354 * PCI230 ADC FIFO levels.
 355 */
 356#define PCI230_ADC_FIFOLEVEL_HALFFULL   2049    /* Value for FIFO half full */
 357#define PCI230_ADC_FIFOLEVEL_FULL       4096    /* FIFO size */
 358
 359/*
 360 * PCI230+ EXTFUNC values.
 361 */
 362/* Route EXTTRIG pin to external gate inputs. */
 363#define PCI230P_EXTFUNC_GAT_EXTTRIG     BIT(0)
 364/* PCI230+ hardware version 2 values. */
 365/* Allow DAC FIFO to be enabled. */
 366#define PCI230P2_EXTFUNC_DACFIFO        BIT(1)
 367
 368/*
 369 * Counter/timer clock input configuration sources.
 370 */
 371#define CLK_CLK         0       /* reserved (channel-specific clock) */
 372#define CLK_10MHZ       1       /* internal 10 MHz clock */
 373#define CLK_1MHZ        2       /* internal 1 MHz clock */
 374#define CLK_100KHZ      3       /* internal 100 kHz clock */
 375#define CLK_10KHZ       4       /* internal 10 kHz clock */
 376#define CLK_1KHZ        5       /* internal 1 kHz clock */
 377#define CLK_OUTNM1      6       /* output of channel-1 modulo total */
 378#define CLK_EXT         7       /* external clock */
 379
 380static unsigned int pci230_clk_config(unsigned int chan, unsigned int src)
 381{
 382        return ((chan & 3) << 3) | (src & 7);
 383}
 384
 385/*
 386 * Counter/timer gate input configuration sources.
 387 */
 388#define GAT_VCC         0       /* VCC (i.e. enabled) */
 389#define GAT_GND         1       /* GND (i.e. disabled) */
 390#define GAT_EXT         2       /* external gate input (PPCn on PCI230) */
 391#define GAT_NOUTNM2     3       /* inverted output of channel-2 modulo total */
 392
 393static unsigned int pci230_gat_config(unsigned int chan, unsigned int src)
 394{
 395        return ((chan & 3) << 3) | (src & 7);
 396}
 397
 398/*
 399 * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI230 and PCI260:
 400 *
 401 *              Channel's       Channel's
 402 *              clock input     gate input
 403 * Channel      CLK_OUTNM1      GAT_NOUTNM2
 404 * -------      ----------      -----------
 405 * Z2-CT0       Z2-CT2-OUT      /Z2-CT1-OUT
 406 * Z2-CT1       Z2-CT0-OUT      /Z2-CT2-OUT
 407 * Z2-CT2       Z2-CT1-OUT      /Z2-CT0-OUT
 408 */
 409
 410/*
 411 * Interrupt enables/status register values.
 412 */
 413#define PCI230_INT_DISABLE              0
 414#define PCI230_INT_PPI_C0               BIT(0)
 415#define PCI230_INT_PPI_C3               BIT(1)
 416#define PCI230_INT_ADC                  BIT(2)
 417#define PCI230_INT_ZCLK_CT1             BIT(5)
 418/* For PCI230+ hardware version 2 when DAC FIFO enabled. */
 419#define PCI230P2_INT_DAC                BIT(4)
 420
 421/*
 422 * (Potentially) shared resources and their owners
 423 */
 424enum {
 425        RES_Z2CT0 = BIT(0),     /* Z2-CT0 */
 426        RES_Z2CT1 = BIT(1),     /* Z2-CT1 */
 427        RES_Z2CT2 = BIT(2)      /* Z2-CT2 */
 428};
 429
 430enum {
 431        OWNER_AICMD,            /* Owned by AI command */
 432        OWNER_AOCMD,            /* Owned by AO command */
 433        NUM_OWNERS              /* Number of owners */
 434};
 435
 436/*
 437 * Handy macros.
 438 */
 439
 440/* Combine old and new bits. */
 441#define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
 442
 443/* Current CPU.  XXX should this be hard_smp_processor_id()? */
 444#define THISCPU         smp_processor_id()
 445
 446/*
 447 * Board descriptions for the two boards supported.
 448 */
 449
 450struct pci230_board {
 451        const char *name;
 452        unsigned short id;
 453        unsigned char ai_bits;
 454        unsigned char ao_bits;
 455        unsigned char min_hwver; /* Minimum hardware version supported. */
 456        bool have_dio:1;
 457};
 458
 459static const struct pci230_board pci230_boards[] = {
 460        {
 461                .name           = "pci230+",
 462                .id             = PCI_DEVICE_ID_PCI230,
 463                .ai_bits        = 16,
 464                .ao_bits        = 12,
 465                .have_dio       = true,
 466                .min_hwver      = 1,
 467        },
 468        {
 469                .name           = "pci260+",
 470                .id             = PCI_DEVICE_ID_PCI260,
 471                .ai_bits        = 16,
 472                .min_hwver      = 1,
 473        },
 474        {
 475                .name           = "pci230",
 476                .id             = PCI_DEVICE_ID_PCI230,
 477                .ai_bits        = 12,
 478                .ao_bits        = 12,
 479                .have_dio       = true,
 480        },
 481        {
 482                .name           = "pci260",
 483                .id             = PCI_DEVICE_ID_PCI260,
 484                .ai_bits        = 12,
 485        },
 486};
 487
 488struct pci230_private {
 489        spinlock_t isr_spinlock;        /* Interrupt spin lock */
 490        spinlock_t res_spinlock;        /* Shared resources spin lock */
 491        spinlock_t ai_stop_spinlock;    /* Spin lock for stopping AI command */
 492        spinlock_t ao_stop_spinlock;    /* Spin lock for stopping AO command */
 493        unsigned long daqio;            /* PCI230's DAQ I/O space */
 494        int intr_cpuid;                 /* ID of CPU running ISR */
 495        unsigned short hwver;           /* Hardware version (for '+' models) */
 496        unsigned short adccon;          /* ADCCON register value */
 497        unsigned short daccon;          /* DACCON register value */
 498        unsigned short adcfifothresh;   /* ADC FIFO threshold (PCI230+/260+) */
 499        unsigned short adcg;            /* ADCG register value */
 500        unsigned char ier;              /* Interrupt enable bits */
 501        unsigned char res_owned[NUM_OWNERS]; /* Owned resources */
 502        bool intr_running:1;            /* Flag set in interrupt routine */
 503        bool ai_bipolar:1;              /* Flag AI range is bipolar */
 504        bool ao_bipolar:1;              /* Flag AO range is bipolar */
 505        bool ai_cmd_started:1;          /* Flag AI command started */
 506        bool ao_cmd_started:1;          /* Flag AO command started */
 507};
 508
 509/* PCI230 clock source periods in ns */
 510static const unsigned int pci230_timebase[8] = {
 511        [CLK_10MHZ]     = I8254_OSC_BASE_10MHZ,
 512        [CLK_1MHZ]      = I8254_OSC_BASE_1MHZ,
 513        [CLK_100KHZ]    = I8254_OSC_BASE_100KHZ,
 514        [CLK_10KHZ]     = I8254_OSC_BASE_10KHZ,
 515        [CLK_1KHZ]      = I8254_OSC_BASE_1KHZ,
 516};
 517
 518/* PCI230 analogue input range table */
 519static const struct comedi_lrange pci230_ai_range = {
 520        7, {
 521                BIP_RANGE(10),
 522                BIP_RANGE(5),
 523                BIP_RANGE(2.5),
 524                BIP_RANGE(1.25),
 525                UNI_RANGE(10),
 526                UNI_RANGE(5),
 527                UNI_RANGE(2.5)
 528        }
 529};
 530
 531/* PCI230 analogue gain bits for each input range. */
 532static const unsigned char pci230_ai_gain[7] = { 0, 1, 2, 3, 1, 2, 3 };
 533
 534/* PCI230 analogue output range table */
 535static const struct comedi_lrange pci230_ao_range = {
 536        2, {
 537                UNI_RANGE(10),
 538                BIP_RANGE(10)
 539        }
 540};
 541
 542static unsigned short pci230_ai_read(struct comedi_device *dev)
 543{
 544        const struct pci230_board *board = dev->board_ptr;
 545        struct pci230_private *devpriv = dev->private;
 546        unsigned short data;
 547
 548        /* Read sample. */
 549        data = inw(devpriv->daqio + PCI230_ADCDATA);
 550        /*
 551         * PCI230 is 12 bit - stored in upper bits of 16 bit register
 552         * (lower four bits reserved for expansion).  PCI230+ is 16 bit AI.
 553         *
 554         * If a bipolar range was specified, mangle it
 555         * (twos complement->straight binary).
 556         */
 557        if (devpriv->ai_bipolar)
 558                data ^= 0x8000;
 559        data >>= (16 - board->ai_bits);
 560        return data;
 561}
 562
 563static unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
 564                                             unsigned short datum)
 565{
 566        const struct pci230_board *board = dev->board_ptr;
 567        struct pci230_private *devpriv = dev->private;
 568
 569        /*
 570         * PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
 571         * four bits reserved for expansion).  PCI230+ is also 12 bit AO.
 572         */
 573        datum <<= (16 - board->ao_bits);
 574        /*
 575         * If a bipolar range was specified, mangle it
 576         * (straight binary->twos complement).
 577         */
 578        if (devpriv->ao_bipolar)
 579                datum ^= 0x8000;
 580        return datum;
 581}
 582
 583static void pci230_ao_write_nofifo(struct comedi_device *dev,
 584                                   unsigned short datum, unsigned int chan)
 585{
 586        struct pci230_private *devpriv = dev->private;
 587
 588        /* Write mangled datum to appropriate DACOUT register. */
 589        outw(pci230_ao_mangle_datum(dev, datum),
 590             devpriv->daqio + ((chan == 0) ? PCI230_DACOUT1 : PCI230_DACOUT2));
 591}
 592
 593static void pci230_ao_write_fifo(struct comedi_device *dev,
 594                                 unsigned short datum, unsigned int chan)
 595{
 596        struct pci230_private *devpriv = dev->private;
 597
 598        /* Write mangled datum to appropriate DACDATA register. */
 599        outw(pci230_ao_mangle_datum(dev, datum),
 600             devpriv->daqio + PCI230P2_DACDATA);
 601}
 602
 603static bool pci230_claim_shared(struct comedi_device *dev,
 604                                unsigned char res_mask, unsigned int owner)
 605{
 606        struct pci230_private *devpriv = dev->private;
 607        unsigned int o;
 608        unsigned long irqflags;
 609
 610        spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
 611        for (o = 0; o < NUM_OWNERS; o++) {
 612                if (o == owner)
 613                        continue;
 614                if (devpriv->res_owned[o] & res_mask) {
 615                        spin_unlock_irqrestore(&devpriv->res_spinlock,
 616                                               irqflags);
 617                        return false;
 618                }
 619        }
 620        devpriv->res_owned[owner] |= res_mask;
 621        spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
 622        return true;
 623}
 624
 625static void pci230_release_shared(struct comedi_device *dev,
 626                                  unsigned char res_mask, unsigned int owner)
 627{
 628        struct pci230_private *devpriv = dev->private;
 629        unsigned long irqflags;
 630
 631        spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
 632        devpriv->res_owned[owner] &= ~res_mask;
 633        spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
 634}
 635
 636static void pci230_release_all_resources(struct comedi_device *dev,
 637                                         unsigned int owner)
 638{
 639        pci230_release_shared(dev, (unsigned char)~0, owner);
 640}
 641
 642static unsigned int pci230_divide_ns(u64 ns, unsigned int timebase,
 643                                     unsigned int flags)
 644{
 645        u64 div;
 646        unsigned int rem;
 647
 648        div = ns;
 649        rem = do_div(div, timebase);
 650        switch (flags & CMDF_ROUND_MASK) {
 651        default:
 652        case CMDF_ROUND_NEAREST:
 653                div += DIV_ROUND_CLOSEST(rem, timebase);
 654                break;
 655        case CMDF_ROUND_DOWN:
 656                break;
 657        case CMDF_ROUND_UP:
 658                div += DIV_ROUND_UP(rem, timebase);
 659                break;
 660        }
 661        return div > UINT_MAX ? UINT_MAX : (unsigned int)div;
 662}
 663
 664/*
 665 * Given desired period in ns, returns the required internal clock source
 666 * and gets the initial count.
 667 */
 668static unsigned int pci230_choose_clk_count(u64 ns, unsigned int *count,
 669                                            unsigned int flags)
 670{
 671        unsigned int clk_src, cnt;
 672
 673        for (clk_src = CLK_10MHZ;; clk_src++) {
 674                cnt = pci230_divide_ns(ns, pci230_timebase[clk_src], flags);
 675                if (cnt <= 65536 || clk_src == CLK_1KHZ)
 676                        break;
 677        }
 678        *count = cnt;
 679        return clk_src;
 680}
 681
 682static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int flags)
 683{
 684        unsigned int count;
 685        unsigned int clk_src;
 686
 687        clk_src = pci230_choose_clk_count(*ns, &count, flags);
 688        *ns = count * pci230_timebase[clk_src];
 689}
 690
 691static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct,
 692                                    unsigned int mode, u64 ns,
 693                                    unsigned int flags)
 694{
 695        unsigned int clk_src;
 696        unsigned int count;
 697
 698        /* Set mode. */
 699        comedi_8254_set_mode(dev->pacer, ct, mode);
 700        /* Determine clock source and count. */
 701        clk_src = pci230_choose_clk_count(ns, &count, flags);
 702        /* Program clock source. */
 703        outb(pci230_clk_config(ct, clk_src), dev->iobase + PCI230_ZCLK_SCE);
 704        /* Set initial count. */
 705        if (count >= 65536)
 706                count = 0;
 707
 708        comedi_8254_write(dev->pacer, ct, count);
 709}
 710
 711static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct)
 712{
 713        /* Counter ct, 8254 mode 1, initial count not written. */
 714        comedi_8254_set_mode(dev->pacer, ct, I8254_MODE1);
 715}
 716
 717static int pci230_ai_eoc(struct comedi_device *dev,
 718                         struct comedi_subdevice *s,
 719                         struct comedi_insn *insn,
 720                         unsigned long context)
 721{
 722        struct pci230_private *devpriv = dev->private;
 723        unsigned int status;
 724
 725        status = inw(devpriv->daqio + PCI230_ADCCON);
 726        if ((status & PCI230_ADC_FIFO_EMPTY) == 0)
 727                return 0;
 728        return -EBUSY;
 729}
 730
 731static int pci230_ai_insn_read(struct comedi_device *dev,
 732                               struct comedi_subdevice *s,
 733                               struct comedi_insn *insn, unsigned int *data)
 734{
 735        struct pci230_private *devpriv = dev->private;
 736        unsigned int n;
 737        unsigned int chan, range, aref;
 738        unsigned int gainshift;
 739        unsigned short adccon, adcen;
 740        int ret;
 741
 742        /* Unpack channel and range. */
 743        chan = CR_CHAN(insn->chanspec);
 744        range = CR_RANGE(insn->chanspec);
 745        aref = CR_AREF(insn->chanspec);
 746        if (aref == AREF_DIFF) {
 747                /* Differential. */
 748                if (chan >= s->n_chan / 2) {
 749                        dev_dbg(dev->class_dev,
 750                                "%s: differential channel number out of range 0 to %u\n",
 751                                __func__, (s->n_chan / 2) - 1);
 752                        return -EINVAL;
 753                }
 754        }
 755
 756        /*
 757         * Use Z2-CT2 as a conversion trigger instead of the built-in
 758         * software trigger, as otherwise triggering of differential channels
 759         * doesn't work properly for some versions of PCI230/260.  Also set
 760         * FIFO mode because the ADC busy bit only works for software triggers.
 761         */
 762        adccon = PCI230_ADC_TRIG_Z2CT2 | PCI230_ADC_FIFO_EN;
 763        /* Set Z2-CT2 output low to avoid any false triggers. */
 764        comedi_8254_set_mode(dev->pacer, 2, I8254_MODE0);
 765        devpriv->ai_bipolar = comedi_range_is_bipolar(s, range);
 766        if (aref == AREF_DIFF) {
 767                /* Differential. */
 768                gainshift = chan * 2;
 769                if (devpriv->hwver == 0) {
 770                        /*
 771                         * Original PCI230/260 expects both inputs of the
 772                         * differential channel to be enabled.
 773                         */
 774                        adcen = 3 << gainshift;
 775                } else {
 776                        /*
 777                         * PCI230+/260+ expects only one input of the
 778                         * differential channel to be enabled.
 779                         */
 780                        adcen = 1 << gainshift;
 781                }
 782                adccon |= PCI230_ADC_IM_DIF;
 783        } else {
 784                /* Single ended. */
 785                adcen = 1 << chan;
 786                gainshift = chan & ~1;
 787                adccon |= PCI230_ADC_IM_SE;
 788        }
 789        devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) |
 790                        (pci230_ai_gain[range] << gainshift);
 791        if (devpriv->ai_bipolar)
 792                adccon |= PCI230_ADC_IR_BIP;
 793        else
 794                adccon |= PCI230_ADC_IR_UNI;
 795
 796        /*
 797         * Enable only this channel in the scan list - otherwise by default
 798         * we'll get one sample from each channel.
 799         */
 800        outw(adcen, devpriv->daqio + PCI230_ADCEN);
 801
 802        /* Set gain for channel. */
 803        outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG);
 804
 805        /* Specify uni/bip, se/diff, conversion source, and reset FIFO. */
 806        devpriv->adccon = adccon;
 807        outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON);
 808
 809        /* Convert n samples */
 810        for (n = 0; n < insn->n; n++) {
 811                /*
 812                 * Trigger conversion by toggling Z2-CT2 output
 813                 * (finish with output high).
 814                 */
 815                comedi_8254_set_mode(dev->pacer, 2, I8254_MODE0);
 816                comedi_8254_set_mode(dev->pacer, 2, I8254_MODE1);
 817
 818                /* wait for conversion to end */
 819                ret = comedi_timeout(dev, s, insn, pci230_ai_eoc, 0);
 820                if (ret)
 821                        return ret;
 822
 823                /* read data */
 824                data[n] = pci230_ai_read(dev);
 825        }
 826
 827        /* return the number of samples read/written */
 828        return n;
 829}
 830
 831static int pci230_ao_insn_write(struct comedi_device *dev,
 832                                struct comedi_subdevice *s,
 833                                struct comedi_insn *insn,
 834                                unsigned int *data)
 835{
 836        struct pci230_private *devpriv = dev->private;
 837        unsigned int chan = CR_CHAN(insn->chanspec);
 838        unsigned int range = CR_RANGE(insn->chanspec);
 839        unsigned int val = s->readback[chan];
 840        int i;
 841
 842        /*
 843         * Set range - see analogue output range table; 0 => unipolar 10V,
 844         * 1 => bipolar +/-10V range scale
 845         */
 846        devpriv->ao_bipolar = comedi_range_is_bipolar(s, range);
 847        outw(range, devpriv->daqio + PCI230_DACCON);
 848
 849        for (i = 0; i < insn->n; i++) {
 850                val = data[i];
 851                pci230_ao_write_nofifo(dev, val, chan);
 852        }
 853        s->readback[chan] = val;
 854
 855        return insn->n;
 856}
 857
 858static int pci230_ao_check_chanlist(struct comedi_device *dev,
 859                                    struct comedi_subdevice *s,
 860                                    struct comedi_cmd *cmd)
 861{
 862        unsigned int prev_chan = CR_CHAN(cmd->chanlist[0]);
 863        unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
 864        int i;
 865
 866        for (i = 1; i < cmd->chanlist_len; i++) {
 867                unsigned int chan = CR_CHAN(cmd->chanlist[i]);
 868                unsigned int range = CR_RANGE(cmd->chanlist[i]);
 869
 870                if (chan < prev_chan) {
 871                        dev_dbg(dev->class_dev,
 872                                "%s: channel numbers must increase\n",
 873                                __func__);
 874                        return -EINVAL;
 875                }
 876
 877                if (range != range0) {
 878                        dev_dbg(dev->class_dev,
 879                                "%s: channels must have the same range\n",
 880                                __func__);
 881                        return -EINVAL;
 882                }
 883
 884                prev_chan = chan;
 885        }
 886
 887        return 0;
 888}
 889
 890static int pci230_ao_cmdtest(struct comedi_device *dev,
 891                             struct comedi_subdevice *s, struct comedi_cmd *cmd)
 892{
 893        const struct pci230_board *board = dev->board_ptr;
 894        struct pci230_private *devpriv = dev->private;
 895        int err = 0;
 896        unsigned int tmp;
 897
 898        /* Step 1 : check if triggers are trivially valid */
 899
 900        err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
 901
 902        tmp = TRIG_TIMER | TRIG_INT;
 903        if (board->min_hwver > 0 && devpriv->hwver >= 2) {
 904                /*
 905                 * For PCI230+ hardware version 2 onwards, allow external
 906                 * trigger from EXTTRIG/EXTCONVCLK input (PCI230+ pin 25).
 907                 *
 908                 * FIXME: The permitted scan_begin_src values shouldn't depend
 909                 * on devpriv->hwver (the detected card's actual hardware
 910                 * version).  They should only depend on board->min_hwver
 911                 * (the static capabilities of the configured card).  To fix
 912                 * it, a new card model, e.g. "pci230+2" would have to be
 913                 * defined with min_hwver set to 2.  It doesn't seem worth it
 914                 * for this alone.  At the moment, please consider
 915                 * scan_begin_src==TRIG_EXT support to be a bonus rather than a
 916                 * guarantee!
 917                 */
 918                tmp |= TRIG_EXT;
 919        }
 920        err |= comedi_check_trigger_src(&cmd->scan_begin_src, tmp);
 921
 922        err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
 923        err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 924        err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 925
 926        if (err)
 927                return 1;
 928
 929        /* Step 2a : make sure trigger sources are unique */
 930
 931        err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
 932        err |= comedi_check_trigger_is_unique(cmd->stop_src);
 933
 934        /* Step 2b : and mutually compatible */
 935
 936        if (err)
 937                return 2;
 938
 939        /* Step 3: check if arguments are trivially valid */
 940
 941        err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
 942
 943#define MAX_SPEED_AO    8000    /* 8000 ns => 125 kHz */
 944/*
 945 * Comedi limit due to unsigned int cmd.  Driver limit =
 946 * 2^16 (16bit * counter) * 1000000ns (1kHz onboard clock) = 65.536s
 947 */
 948#define MIN_SPEED_AO    4294967295u     /* 4294967295ns = 4.29s */
 949
 950        switch (cmd->scan_begin_src) {
 951        case TRIG_TIMER:
 952                err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
 953                                                    MAX_SPEED_AO);
 954                err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
 955                                                    MIN_SPEED_AO);
 956                break;
 957        case TRIG_EXT:
 958                /*
 959                 * External trigger - for PCI230+ hardware version 2 onwards.
 960                 */
 961                /* Trigger number must be 0. */
 962                if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) {
 963                        cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
 964                                                      ~CR_FLAGS_MASK);
 965                        err |= -EINVAL;
 966                }
 967                /*
 968                 * The only flags allowed are CR_EDGE and CR_INVERT.
 969                 * The CR_EDGE flag is ignored.
 970                 */
 971                if (cmd->scan_begin_arg & CR_FLAGS_MASK &
 972                    ~(CR_EDGE | CR_INVERT)) {
 973                        cmd->scan_begin_arg =
 974                            COMBINE(cmd->scan_begin_arg, 0,
 975                                    CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
 976                        err |= -EINVAL;
 977                }
 978                break;
 979        default:
 980                err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
 981                break;
 982        }
 983
 984        err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
 985                                           cmd->chanlist_len);
 986
 987        if (cmd->stop_src == TRIG_COUNT)
 988                err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
 989        else    /* TRIG_NONE */
 990                err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
 991
 992        if (err)
 993                return 3;
 994
 995        /* Step 4: fix up any arguments */
 996
 997        if (cmd->scan_begin_src == TRIG_TIMER) {
 998                tmp = cmd->scan_begin_arg;
 999                pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags);
1000                if (tmp != cmd->scan_begin_arg)
1001                        err++;
1002        }
1003
1004        if (err)
1005                return 4;
1006
1007        /* Step 5: check channel list if it exists */
1008        if (cmd->chanlist && cmd->chanlist_len > 0)
1009                err |= pci230_ao_check_chanlist(dev, s, cmd);
1010
1011        if (err)
1012                return 5;
1013
1014        return 0;
1015}
1016
1017static void pci230_ao_stop(struct comedi_device *dev,
1018                           struct comedi_subdevice *s)
1019{
1020        struct pci230_private *devpriv = dev->private;
1021        unsigned long irqflags;
1022        unsigned char intsrc;
1023        bool started;
1024        struct comedi_cmd *cmd;
1025
1026        spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
1027        started = devpriv->ao_cmd_started;
1028        devpriv->ao_cmd_started = false;
1029        spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
1030        if (!started)
1031                return;
1032        cmd = &s->async->cmd;
1033        if (cmd->scan_begin_src == TRIG_TIMER) {
1034                /* Stop scan rate generator. */
1035                pci230_cancel_ct(dev, 1);
1036        }
1037        /* Determine interrupt source. */
1038        if (devpriv->hwver < 2) {
1039                /* Not using DAC FIFO.  Using CT1 interrupt. */
1040                intsrc = PCI230_INT_ZCLK_CT1;
1041        } else {
1042                /* Using DAC FIFO interrupt. */
1043                intsrc = PCI230P2_INT_DAC;
1044        }
1045        /*
1046         * Disable interrupt and wait for interrupt routine to finish running
1047         * unless we are called from the interrupt routine.
1048         */
1049        spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1050        devpriv->ier &= ~intsrc;
1051        while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
1052                spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
1053                spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1054        }
1055        outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
1056        spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
1057        if (devpriv->hwver >= 2) {
1058                /*
1059                 * Using DAC FIFO.  Reset FIFO, clear underrun error,
1060                 * disable FIFO.
1061                 */
1062                devpriv->daccon &= PCI230_DAC_OR_MASK;
1063                outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET |
1064                     PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
1065                     devpriv->daqio + PCI230_DACCON);
1066        }
1067        /* Release resources. */
1068        pci230_release_all_resources(dev, OWNER_AOCMD);
1069}
1070
1071static void pci230_handle_ao_nofifo(struct comedi_device *dev,
1072                                    struct comedi_subdevice *s)
1073{
1074        struct comedi_async *async = s->async;
1075        struct comedi_cmd *cmd = &async->cmd;
1076        unsigned short data;
1077        int i;
1078
1079        if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
1080                return;
1081
1082        for (i = 0; i < cmd->chanlist_len; i++) {
1083                unsigned int chan = CR_CHAN(cmd->chanlist[i]);
1084
1085                if (!comedi_buf_read_samples(s, &data, 1)) {
1086                        async->events |= COMEDI_CB_OVERFLOW;
1087                        return;
1088                }
1089                pci230_ao_write_nofifo(dev, data, chan);
1090                s->readback[chan] = data;
1091        }
1092
1093        if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
1094                async->events |= COMEDI_CB_EOA;
1095}
1096
1097/*
1098 * Loads DAC FIFO (if using it) from buffer.
1099 * Returns false if AO finished due to completion or error, true if still going.
1100 */
1101static bool pci230_handle_ao_fifo(struct comedi_device *dev,
1102                                  struct comedi_subdevice *s)
1103{
1104        struct pci230_private *devpriv = dev->private;
1105        struct comedi_async *async = s->async;
1106        struct comedi_cmd *cmd = &async->cmd;
1107        unsigned int num_scans = comedi_nscans_left(s, 0);
1108        unsigned int room;
1109        unsigned short dacstat;
1110        unsigned int i, n;
1111        unsigned int events = 0;
1112
1113        /* Get DAC FIFO status. */
1114        dacstat = inw(devpriv->daqio + PCI230_DACCON);
1115
1116        if (cmd->stop_src == TRIG_COUNT && num_scans == 0)
1117                events |= COMEDI_CB_EOA;
1118
1119        if (events == 0) {
1120                /* Check for FIFO underrun. */
1121                if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) {
1122                        dev_err(dev->class_dev, "AO FIFO underrun\n");
1123                        events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
1124                }
1125                /*
1126                 * Check for buffer underrun if FIFO less than half full
1127                 * (otherwise there will be loads of "DAC FIFO not half full"
1128                 * interrupts).
1129                 */
1130                if (num_scans == 0 &&
1131                    (dacstat & PCI230P2_DAC_FIFO_HALF) == 0) {
1132                        dev_err(dev->class_dev, "AO buffer underrun\n");
1133                        events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
1134                }
1135        }
1136        if (events == 0) {
1137                /* Determine how much room is in the FIFO (in samples). */
1138                if (dacstat & PCI230P2_DAC_FIFO_FULL)
1139                        room = PCI230P2_DAC_FIFOROOM_FULL;
1140                else if (dacstat & PCI230P2_DAC_FIFO_HALF)
1141                        room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
1142                else if (dacstat & PCI230P2_DAC_FIFO_EMPTY)
1143                        room = PCI230P2_DAC_FIFOROOM_EMPTY;
1144                else
1145                        room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
1146                /* Convert room to number of scans that can be added. */
1147                room /= cmd->chanlist_len;
1148                /* Determine number of scans to process. */
1149                if (num_scans > room)
1150                        num_scans = room;
1151                /* Process scans. */
1152                for (n = 0; n < num_scans; n++) {
1153                        for (i = 0; i < cmd->chanlist_len; i++) {
1154                                unsigned int chan = CR_CHAN(cmd->chanlist[i]);
1155                                unsigned short datum;
1156
1157                                comedi_buf_read_samples(s, &datum, 1);
1158                                pci230_ao_write_fifo(dev, datum, chan);
1159                                s->readback[chan] = datum;
1160                        }
1161                }
1162
1163                if (cmd->stop_src == TRIG_COUNT &&
1164                    async->scans_done >= cmd->stop_arg) {
1165                        /*
1166                         * All data for the command has been written
1167                         * to FIFO.  Set FIFO interrupt trigger level
1168                         * to 'empty'.
1169                         */
1170                        devpriv->daccon &= ~PCI230P2_DAC_INT_FIFO_MASK;
1171                        devpriv->daccon |= PCI230P2_DAC_INT_FIFO_EMPTY;
1172                        outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON);
1173                }
1174                /* Check if FIFO underrun occurred while writing to FIFO. */
1175                dacstat = inw(devpriv->daqio + PCI230_DACCON);
1176                if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) {
1177                        dev_err(dev->class_dev, "AO FIFO underrun\n");
1178                        events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
1179                }
1180        }
1181        async->events |= events;
1182        return !(async->events & COMEDI_CB_CANCEL_MASK);
1183}
1184
1185static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev,
1186                                        struct comedi_subdevice *s,
1187                                        unsigned int trig_num)
1188{
1189        struct pci230_private *devpriv = dev->private;
1190        unsigned long irqflags;
1191
1192        if (trig_num)
1193                return -EINVAL;
1194
1195        spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
1196        if (!devpriv->ao_cmd_started) {
1197                spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
1198                return 1;
1199        }
1200        /* Perform scan. */
1201        if (devpriv->hwver < 2) {
1202                /* Not using DAC FIFO. */
1203                spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
1204                pci230_handle_ao_nofifo(dev, s);
1205                comedi_handle_events(dev, s);
1206        } else {
1207                /* Using DAC FIFO. */
1208                /* Read DACSWTRIG register to trigger conversion. */
1209                inw(devpriv->daqio + PCI230P2_DACSWTRIG);
1210                spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
1211        }
1212        /* Delay.  Should driver be responsible for this? */
1213        /* XXX TODO: See if DAC busy bit can be used. */
1214        udelay(8);
1215        return 1;
1216}
1217
1218static void pci230_ao_start(struct comedi_device *dev,
1219                            struct comedi_subdevice *s)
1220{
1221        struct pci230_private *devpriv = dev->private;
1222        struct comedi_async *async = s->async;
1223        struct comedi_cmd *cmd = &async->cmd;
1224        unsigned long irqflags;
1225
1226        devpriv->ao_cmd_started = true;
1227
1228        if (devpriv->hwver >= 2) {
1229                /* Using DAC FIFO. */
1230                unsigned short scantrig;
1231                bool run;
1232
1233                /* Preload FIFO data. */
1234                run = pci230_handle_ao_fifo(dev, s);
1235                comedi_handle_events(dev, s);
1236                if (!run) {
1237                        /* Stopped. */
1238                        return;
1239                }
1240                /* Set scan trigger source. */
1241                switch (cmd->scan_begin_src) {
1242                case TRIG_TIMER:
1243                        scantrig = PCI230P2_DAC_TRIG_Z2CT1;
1244                        break;
1245                case TRIG_EXT:
1246                        /* Trigger on EXTTRIG/EXTCONVCLK pin. */
1247                        if ((cmd->scan_begin_arg & CR_INVERT) == 0) {
1248                                /* +ve edge */
1249                                scantrig = PCI230P2_DAC_TRIG_EXTP;
1250                        } else {
1251                                /* -ve edge */
1252                                scantrig = PCI230P2_DAC_TRIG_EXTN;
1253                        }
1254                        break;
1255                case TRIG_INT:
1256                        scantrig = PCI230P2_DAC_TRIG_SW;
1257                        break;
1258                default:
1259                        /* Shouldn't get here. */
1260                        scantrig = PCI230P2_DAC_TRIG_NONE;
1261                        break;
1262                }
1263                devpriv->daccon =
1264                    (devpriv->daccon & ~PCI230P2_DAC_TRIG_MASK) | scantrig;
1265                outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON);
1266        }
1267        switch (cmd->scan_begin_src) {
1268        case TRIG_TIMER:
1269                if (devpriv->hwver < 2) {
1270                        /* Not using DAC FIFO. */
1271                        /* Enable CT1 timer interrupt. */
1272                        spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1273                        devpriv->ier |= PCI230_INT_ZCLK_CT1;
1274                        outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
1275                        spin_unlock_irqrestore(&devpriv->isr_spinlock,
1276                                               irqflags);
1277                }
1278                /* Set CT1 gate high to start counting. */
1279                outb(pci230_gat_config(1, GAT_VCC),
1280                     dev->iobase + PCI230_ZGAT_SCE);
1281                break;
1282        case TRIG_INT:
1283                async->inttrig = pci230_ao_inttrig_scan_begin;
1284                break;
1285        }
1286        if (devpriv->hwver >= 2) {
1287                /* Using DAC FIFO.  Enable DAC FIFO interrupt. */
1288                spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1289                devpriv->ier |= PCI230P2_INT_DAC;
1290                outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
1291                spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
1292        }
1293}
1294
1295static int pci230_ao_inttrig_start(struct comedi_device *dev,
1296                                   struct comedi_subdevice *s,
1297                                   unsigned int trig_num)
1298{
1299        struct comedi_cmd *cmd = &s->async->cmd;
1300
1301        if (trig_num != cmd->start_src)
1302                return -EINVAL;
1303
1304        s->async->inttrig = NULL;
1305        pci230_ao_start(dev, s);
1306
1307        return 1;
1308}
1309
1310static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1311{
1312        struct pci230_private *devpriv = dev->private;
1313        unsigned short daccon;
1314        unsigned int range;
1315
1316        /* Get the command. */
1317        struct comedi_cmd *cmd = &s->async->cmd;
1318
1319        if (cmd->scan_begin_src == TRIG_TIMER) {
1320                /* Claim Z2-CT1. */
1321                if (!pci230_claim_shared(dev, RES_Z2CT1, OWNER_AOCMD))
1322                        return -EBUSY;
1323        }
1324
1325        /*
1326         * Set range - see analogue output range table; 0 => unipolar 10V,
1327         * 1 => bipolar +/-10V range scale
1328         */
1329        range = CR_RANGE(cmd->chanlist[0]);
1330        devpriv->ao_bipolar = comedi_range_is_bipolar(s, range);
1331        daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
1332        /* Use DAC FIFO for hardware version 2 onwards. */
1333        if (devpriv->hwver >= 2) {
1334                unsigned short dacen;
1335                unsigned int i;
1336
1337                dacen = 0;
1338                for (i = 0; i < cmd->chanlist_len; i++)
1339                        dacen |= 1 << CR_CHAN(cmd->chanlist[i]);
1340
1341                /* Set channel scan list. */
1342                outw(dacen, devpriv->daqio + PCI230P2_DACEN);
1343                /*
1344                 * Enable DAC FIFO.
1345                 * Set DAC scan source to 'none'.
1346                 * Set DAC FIFO interrupt trigger level to 'not half full'.
1347                 * Reset DAC FIFO and clear underrun.
1348                 *
1349                 * N.B. DAC FIFO interrupts are currently disabled.
1350                 */
1351                daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET |
1352                          PCI230P2_DAC_FIFO_UNDERRUN_CLEAR |
1353                          PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
1354        }
1355
1356        /* Set DACCON. */
1357        outw(daccon, devpriv->daqio + PCI230_DACCON);
1358        /* Preserve most of DACCON apart from write-only, transient bits. */
1359        devpriv->daccon = daccon & ~(PCI230P2_DAC_FIFO_RESET |
1360                                     PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
1361
1362        if (cmd->scan_begin_src == TRIG_TIMER) {
1363                /*
1364                 * Set the counter timer 1 to the specified scan frequency.
1365                 * cmd->scan_begin_arg is sampling period in ns.
1366                 * Gate it off for now.
1367                 */
1368                outb(pci230_gat_config(1, GAT_GND),
1369                     dev->iobase + PCI230_ZGAT_SCE);
1370                pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
1371                                        cmd->scan_begin_arg,
1372                                        cmd->flags);
1373        }
1374
1375        /* N.B. cmd->start_src == TRIG_INT */
1376        s->async->inttrig = pci230_ao_inttrig_start;
1377
1378        return 0;
1379}
1380
1381static int pci230_ao_cancel(struct comedi_device *dev,
1382                            struct comedi_subdevice *s)
1383{
1384        pci230_ao_stop(dev, s);
1385        return 0;
1386}
1387
1388static int pci230_ai_check_scan_period(struct comedi_cmd *cmd)
1389{
1390        unsigned int min_scan_period, chanlist_len;
1391        int err = 0;
1392
1393        chanlist_len = cmd->chanlist_len;
1394        if (cmd->chanlist_len == 0)
1395                chanlist_len = 1;
1396
1397        min_scan_period = chanlist_len * cmd->convert_arg;
1398        if (min_scan_period < chanlist_len ||
1399            min_scan_period < cmd->convert_arg) {
1400                /* Arithmetic overflow. */
1401                min_scan_period = UINT_MAX;
1402                err++;
1403        }
1404        if (cmd->scan_begin_arg < min_scan_period) {
1405                cmd->scan_begin_arg = min_scan_period;
1406                err++;
1407        }
1408
1409        return !err;
1410}
1411
1412static int pci230_ai_check_chanlist(struct comedi_device *dev,
1413                                    struct comedi_subdevice *s,
1414                                    struct comedi_cmd *cmd)
1415{
1416        struct pci230_private *devpriv = dev->private;
1417        unsigned int max_diff_chan = (s->n_chan / 2) - 1;
1418        unsigned int prev_chan = 0;
1419        unsigned int prev_range = 0;
1420        unsigned int prev_aref = 0;
1421        bool prev_bipolar = false;
1422        unsigned int subseq_len = 0;
1423        int i;
1424
1425        for (i = 0; i < cmd->chanlist_len; i++) {
1426                unsigned int chanspec = cmd->chanlist[i];
1427                unsigned int chan = CR_CHAN(chanspec);
1428                unsigned int range = CR_RANGE(chanspec);
1429                unsigned int aref = CR_AREF(chanspec);
1430                bool bipolar = comedi_range_is_bipolar(s, range);
1431
1432                if (aref == AREF_DIFF && chan >= max_diff_chan) {
1433                        dev_dbg(dev->class_dev,
1434                                "%s: differential channel number out of range 0 to %u\n",
1435                                __func__, max_diff_chan);
1436                        return -EINVAL;
1437                }
1438
1439                if (i > 0) {
1440                        /*
1441                         * Channel numbers must strictly increase or
1442                         * subsequence must repeat exactly.
1443                         */
1444                        if (chan <= prev_chan && subseq_len == 0)
1445                                subseq_len = i;
1446
1447                        if (subseq_len > 0 &&
1448                            cmd->chanlist[i % subseq_len] != chanspec) {
1449                                dev_dbg(dev->class_dev,
1450                                        "%s: channel numbers must increase or sequence must repeat exactly\n",
1451                                        __func__);
1452                                return -EINVAL;
1453                        }
1454
1455                        if (aref != prev_aref) {
1456                                dev_dbg(dev->class_dev,
1457                                        "%s: channel sequence analogue references must be all the same (single-ended or differential)\n",
1458                                        __func__);
1459                                return -EINVAL;
1460                        }
1461
1462                        if (bipolar != prev_bipolar) {
1463                                dev_dbg(dev->class_dev,
1464                                        "%s: channel sequence ranges must be all bipolar or all unipolar\n",
1465                                        __func__);
1466                                return -EINVAL;
1467                        }
1468
1469                        if (aref != AREF_DIFF && range != prev_range &&
1470                            ((chan ^ prev_chan) & ~1) == 0) {
1471                                dev_dbg(dev->class_dev,
1472                                        "%s: single-ended channel pairs must have the same range\n",
1473                                        __func__);
1474                                return -EINVAL;
1475                        }
1476                }
1477                prev_chan = chan;
1478                prev_range = range;
1479                prev_aref = aref;
1480                prev_bipolar = bipolar;
1481        }
1482
1483        if (subseq_len == 0)
1484                subseq_len = cmd->chanlist_len;
1485
1486        if (cmd->chanlist_len % subseq_len) {
1487                dev_dbg(dev->class_dev,
1488                        "%s: sequence must repeat exactly\n", __func__);
1489                return -EINVAL;
1490        }
1491
1492        /*
1493         * Buggy PCI230+ or PCI260+ requires channel 0 to be (first) in the
1494         * sequence if the sequence contains more than one channel. Hardware
1495         * versions 1 and 2 have the bug. There is no hardware version 3.
1496         *
1497         * Actually, there are two firmwares that report themselves as
1498         * hardware version 1 (the boards have different ADC chips with
1499         * slightly different timing requirements, which was supposed to
1500         * be invisible to software). The first one doesn't seem to have
1501         * the bug, but the second one does, and we can't tell them apart!
1502         */
1503        if (devpriv->hwver > 0 && devpriv->hwver < 4) {
1504                if (subseq_len > 1 && CR_CHAN(cmd->chanlist[0])) {
1505                        dev_info(dev->class_dev,
1506                                 "amplc_pci230: ai_cmdtest: Buggy PCI230+/260+ h/w version %u requires first channel of multi-channel sequence to be 0 (corrected in h/w version 4)\n",
1507                                 devpriv->hwver);
1508                        return -EINVAL;
1509                }
1510        }
1511
1512        return 0;
1513}
1514
1515static int pci230_ai_cmdtest(struct comedi_device *dev,
1516                             struct comedi_subdevice *s, struct comedi_cmd *cmd)
1517{
1518        const struct pci230_board *board = dev->board_ptr;
1519        struct pci230_private *devpriv = dev->private;
1520        int err = 0;
1521        unsigned int tmp;
1522
1523        /* Step 1 : check if triggers are trivially valid */
1524
1525        err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
1526
1527        tmp = TRIG_FOLLOW | TRIG_TIMER | TRIG_INT;
1528        if (board->have_dio || board->min_hwver > 0) {
1529                /*
1530                 * Unfortunately, we cannot trigger a scan off an external
1531                 * source on the PCI260 board, since it uses the PPIC0 (DIO)
1532                 * input, which isn't present on the PCI260.  For PCI260+
1533                 * we can use the EXTTRIG/EXTCONVCLK input on pin 17 instead.
1534                 */
1535                tmp |= TRIG_EXT;
1536        }
1537        err |= comedi_check_trigger_src(&cmd->scan_begin_src, tmp);
1538        err |= comedi_check_trigger_src(&cmd->convert_src,
1539                                        TRIG_TIMER | TRIG_INT | TRIG_EXT);
1540        err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1541        err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1542
1543        if (err)
1544                return 1;
1545
1546        /* Step 2a : make sure trigger sources are unique */
1547
1548        err |= comedi_check_trigger_is_unique(cmd->start_src);
1549        err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
1550        err |= comedi_check_trigger_is_unique(cmd->convert_src);
1551        err |= comedi_check_trigger_is_unique(cmd->stop_src);
1552
1553        /* Step 2b : and mutually compatible */
1554
1555        /*
1556         * If scan_begin_src is not TRIG_FOLLOW, then a monostable will be
1557         * set up to generate a fixed number of timed conversion pulses.
1558         */
1559        if (cmd->scan_begin_src != TRIG_FOLLOW &&
1560            cmd->convert_src != TRIG_TIMER)
1561                err |= -EINVAL;
1562
1563        if (err)
1564                return 2;
1565
1566        /* Step 3: check if arguments are trivially valid */
1567
1568        err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
1569
1570#define MAX_SPEED_AI_SE         3200    /* PCI230 SE:   3200 ns => 312.5 kHz */
1571#define MAX_SPEED_AI_DIFF       8000    /* PCI230 DIFF: 8000 ns => 125 kHz */
1572#define MAX_SPEED_AI_PLUS       4000    /* PCI230+:     4000 ns => 250 kHz */
1573/*
1574 * Comedi limit due to unsigned int cmd.  Driver limit =
1575 * 2^16 (16bit * counter) * 1000000ns (1kHz onboard clock) = 65.536s
1576 */
1577#define MIN_SPEED_AI    4294967295u     /* 4294967295ns = 4.29s */
1578
1579        if (cmd->convert_src == TRIG_TIMER) {
1580                unsigned int max_speed_ai;
1581
1582                if (devpriv->hwver == 0) {
1583                        /*
1584                         * PCI230 or PCI260.  Max speed depends whether
1585                         * single-ended or pseudo-differential.
1586                         */
1587                        if (cmd->chanlist && cmd->chanlist_len > 0) {
1588                                /* Peek analogue reference of first channel. */
1589                                if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF)
1590                                        max_speed_ai = MAX_SPEED_AI_DIFF;
1591                                else
1592                                        max_speed_ai = MAX_SPEED_AI_SE;
1593
1594                        } else {
1595                                /* No channel list.  Assume single-ended. */
1596                                max_speed_ai = MAX_SPEED_AI_SE;
1597                        }
1598                } else {
1599                        /* PCI230+ or PCI260+. */
1600                        max_speed_ai = MAX_SPEED_AI_PLUS;
1601                }
1602
1603                err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
1604                                                    max_speed_ai);
1605                err |= comedi_check_trigger_arg_max(&cmd->convert_arg,
1606                                                    MIN_SPEED_AI);
1607        } else if (cmd->convert_src == TRIG_EXT) {
1608                /*
1609                 * external trigger
1610                 *
1611                 * convert_arg == (CR_EDGE | 0)
1612                 *                => trigger on +ve edge.
1613                 * convert_arg == (CR_EDGE | CR_INVERT | 0)
1614                 *                => trigger on -ve edge.
1615                 */
1616                if (cmd->convert_arg & CR_FLAGS_MASK) {
1617                        /* Trigger number must be 0. */
1618                        if (cmd->convert_arg & ~CR_FLAGS_MASK) {
1619                                cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
1620                                                           ~CR_FLAGS_MASK);
1621                                err |= -EINVAL;
1622                        }
1623                        /*
1624                         * The only flags allowed are CR_INVERT and CR_EDGE.
1625                         * CR_EDGE is required.
1626                         */
1627                        if ((cmd->convert_arg & CR_FLAGS_MASK & ~CR_INVERT) !=
1628                            CR_EDGE) {
1629                                /* Set CR_EDGE, preserve CR_INVERT. */
1630                                cmd->convert_arg =
1631                                    COMBINE(cmd->start_arg, CR_EDGE | 0,
1632                                            CR_FLAGS_MASK & ~CR_INVERT);
1633                                err |= -EINVAL;
1634                        }
1635                } else {
1636                        /*
1637                         * Backwards compatibility with previous versions:
1638                         * convert_arg == 0 => trigger on -ve edge.
1639                         * convert_arg == 1 => trigger on +ve edge.
1640                         */
1641                        err |= comedi_check_trigger_arg_max(&cmd->convert_arg,
1642                                                            1);
1643                }
1644        } else {
1645                err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
1646        }
1647
1648        err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
1649                                           cmd->chanlist_len);
1650
1651        if (cmd->stop_src == TRIG_COUNT)
1652                err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
1653        else    /* TRIG_NONE */
1654                err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
1655
1656        if (cmd->scan_begin_src == TRIG_EXT) {
1657                /*
1658                 * external "trigger" to begin each scan:
1659                 * scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate
1660                 * of CT2 (sample convert trigger is CT2)
1661                 */
1662                if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) {
1663                        cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1664                                                      ~CR_FLAGS_MASK);
1665                        err |= -EINVAL;
1666                }
1667                /* The only flag allowed is CR_EDGE, which is ignored. */
1668                if (cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) {
1669                        cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
1670                                                      CR_FLAGS_MASK & ~CR_EDGE);
1671                        err |= -EINVAL;
1672                }
1673        } else if (cmd->scan_begin_src == TRIG_TIMER) {
1674                /* N.B. cmd->convert_arg is also TRIG_TIMER */
1675                if (!pci230_ai_check_scan_period(cmd))
1676                        err |= -EINVAL;
1677
1678        } else {
1679                err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1680        }
1681
1682        if (err)
1683                return 3;
1684
1685        /* Step 4: fix up any arguments */
1686
1687        if (cmd->convert_src == TRIG_TIMER) {
1688                tmp = cmd->convert_arg;
1689                pci230_ns_to_single_timer(&cmd->convert_arg, cmd->flags);
1690                if (tmp != cmd->convert_arg)
1691                        err++;
1692        }
1693
1694        if (cmd->scan_begin_src == TRIG_TIMER) {
1695                /* N.B. cmd->convert_arg is also TRIG_TIMER */
1696                tmp = cmd->scan_begin_arg;
1697                pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags);
1698                if (!pci230_ai_check_scan_period(cmd)) {
1699                        /* Was below minimum required.  Round up. */
1700                        pci230_ns_to_single_timer(&cmd->scan_begin_arg,
1701                                                  CMDF_ROUND_UP);
1702                        pci230_ai_check_scan_period(cmd);
1703                }
1704                if (tmp != cmd->scan_begin_arg)
1705                        err++;
1706        }
1707
1708        if (err)
1709                return 4;
1710
1711        /* Step 5: check channel list if it exists */
1712        if (cmd->chanlist && cmd->chanlist_len > 0)
1713                err |= pci230_ai_check_chanlist(dev, s, cmd);
1714
1715        if (err)
1716                return 5;
1717
1718        return 0;
1719}
1720
1721static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
1722                                                struct comedi_subdevice *s)
1723{
1724        struct pci230_private *devpriv = dev->private;
1725        struct comedi_cmd *cmd = &s->async->cmd;
1726        unsigned int wake;
1727        unsigned short triglev;
1728        unsigned short adccon;
1729
1730        if (cmd->flags & CMDF_WAKE_EOS)
1731                wake = cmd->scan_end_arg - s->async->cur_chan;
1732        else
1733                wake = comedi_nsamples_left(s, PCI230_ADC_FIFOLEVEL_HALFFULL);
1734
1735        if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
1736                triglev = PCI230_ADC_INT_FIFO_HALF;
1737        } else if (wake > 1 && devpriv->hwver > 0) {
1738                /* PCI230+/260+ programmable FIFO interrupt level. */
1739                if (devpriv->adcfifothresh != wake) {
1740                        devpriv->adcfifothresh = wake;
1741                        outw(wake, devpriv->daqio + PCI230P_ADCFFTH);
1742                }
1743                triglev = PCI230P_ADC_INT_FIFO_THRESH;
1744        } else {
1745                triglev = PCI230_ADC_INT_FIFO_NEMPTY;
1746        }
1747        adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev;
1748        if (adccon != devpriv->adccon) {
1749                devpriv->adccon = adccon;
1750                outw(adccon, devpriv->daqio + PCI230_ADCCON);
1751        }
1752}
1753
1754static int pci230_ai_inttrig_convert(struct comedi_device *dev,
1755                                     struct comedi_subdevice *s,
1756                                     unsigned int trig_num)
1757{
1758        struct pci230_private *devpriv = dev->private;
1759        unsigned long irqflags;
1760        unsigned int delayus;
1761
1762        if (trig_num)
1763                return -EINVAL;
1764
1765        spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
1766        if (!devpriv->ai_cmd_started) {
1767                spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
1768                return 1;
1769        }
1770        /*
1771         * Trigger conversion by toggling Z2-CT2 output.
1772         * Finish with output high.
1773         */
1774        comedi_8254_set_mode(dev->pacer, 2, I8254_MODE0);
1775        comedi_8254_set_mode(dev->pacer, 2, I8254_MODE1);
1776        /*
1777         * Delay.  Should driver be responsible for this?  An
1778         * alternative would be to wait until conversion is complete,
1779         * but we can't tell when it's complete because the ADC busy
1780         * bit has a different meaning when FIFO enabled (and when
1781         * FIFO not enabled, it only works for software triggers).
1782         */
1783        if ((devpriv->adccon & PCI230_ADC_IM_MASK) == PCI230_ADC_IM_DIF &&
1784            devpriv->hwver == 0) {
1785                /* PCI230/260 in differential mode */
1786                delayus = 8;
1787        } else {
1788                /* single-ended or PCI230+/260+ */
1789                delayus = 4;
1790        }
1791        spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
1792        udelay(delayus);
1793        return 1;
1794}
1795
1796static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev,
1797                                        struct comedi_subdevice *s,
1798                                        unsigned int trig_num)
1799{
1800        struct pci230_private *devpriv = dev->private;
1801        unsigned long irqflags;
1802        unsigned char zgat;
1803
1804        if (trig_num)
1805                return -EINVAL;
1806
1807        spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
1808        if (devpriv->ai_cmd_started) {
1809                /* Trigger scan by waggling CT0 gate source. */
1810                zgat = pci230_gat_config(0, GAT_GND);
1811                outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
1812                zgat = pci230_gat_config(0, GAT_VCC);
1813                outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
1814        }
1815        spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
1816
1817        return 1;
1818}
1819
1820static void pci230_ai_stop(struct comedi_device *dev,
1821                           struct comedi_subdevice *s)
1822{
1823        struct pci230_private *devpriv = dev->private;
1824        unsigned long irqflags;
1825        struct comedi_cmd *cmd;
1826        bool started;
1827
1828        spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
1829        started = devpriv->ai_cmd_started;
1830        devpriv->ai_cmd_started = false;
1831        spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
1832        if (!started)
1833                return;
1834        cmd = &s->async->cmd;
1835        if (cmd->convert_src == TRIG_TIMER) {
1836                /* Stop conversion rate generator. */
1837                pci230_cancel_ct(dev, 2);
1838        }
1839        if (cmd->scan_begin_src != TRIG_FOLLOW) {
1840                /* Stop scan period monostable. */
1841                pci230_cancel_ct(dev, 0);
1842        }
1843        spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1844        /*
1845         * Disable ADC interrupt and wait for interrupt routine to finish
1846         * running unless we are called from the interrupt routine.
1847         */
1848        devpriv->ier &= ~PCI230_INT_ADC;
1849        while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
1850                spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
1851                spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1852        }
1853        outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
1854        spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
1855        /*
1856         * Reset FIFO, disable FIFO and set start conversion source to none.
1857         * Keep se/diff and bip/uni settings.
1858         */
1859        devpriv->adccon =
1860            (devpriv->adccon & (PCI230_ADC_IR_MASK | PCI230_ADC_IM_MASK)) |
1861            PCI230_ADC_TRIG_NONE;
1862        outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
1863             devpriv->daqio + PCI230_ADCCON);
1864        /* Release resources. */
1865        pci230_release_all_resources(dev, OWNER_AICMD);
1866}
1867
1868static void pci230_ai_start(struct comedi_device *dev,
1869                            struct comedi_subdevice *s)
1870{
1871        struct pci230_private *devpriv = dev->private;
1872        unsigned long irqflags;
1873        unsigned short conv;
1874        struct comedi_async *async = s->async;
1875        struct comedi_cmd *cmd = &async->cmd;
1876
1877        devpriv->ai_cmd_started = true;
1878
1879        /* Enable ADC FIFO trigger level interrupt. */
1880        spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
1881        devpriv->ier |= PCI230_INT_ADC;
1882        outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
1883        spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
1884
1885        /*
1886         * Update conversion trigger source which is currently set
1887         * to CT2 output, which is currently stuck high.
1888         */
1889        switch (cmd->convert_src) {
1890        default:
1891                conv = PCI230_ADC_TRIG_NONE;
1892                break;
1893        case TRIG_TIMER:
1894                /* Using CT2 output. */
1895                conv = PCI230_ADC_TRIG_Z2CT2;
1896                break;
1897        case TRIG_EXT:
1898                if (cmd->convert_arg & CR_EDGE) {
1899                        if ((cmd->convert_arg & CR_INVERT) == 0) {
1900                                /* Trigger on +ve edge. */
1901                                conv = PCI230_ADC_TRIG_EXTP;
1902                        } else {
1903                                /* Trigger on -ve edge. */
1904                                conv = PCI230_ADC_TRIG_EXTN;
1905                        }
1906                } else {
1907                        /* Backwards compatibility. */
1908                        if (cmd->convert_arg) {
1909                                /* Trigger on +ve edge. */
1910                                conv = PCI230_ADC_TRIG_EXTP;
1911                        } else {
1912                                /* Trigger on -ve edge. */
1913                                conv = PCI230_ADC_TRIG_EXTN;
1914                        }
1915                }
1916                break;
1917        case TRIG_INT:
1918                /*
1919                 * Use CT2 output for software trigger due to problems
1920                 * in differential mode on PCI230/260.
1921                 */
1922                conv = PCI230_ADC_TRIG_Z2CT2;
1923                break;
1924        }
1925        devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK) | conv;
1926        outw(devpriv->adccon, devpriv->daqio + PCI230_ADCCON);
1927        if (cmd->convert_src == TRIG_INT)
1928                async->inttrig = pci230_ai_inttrig_convert;
1929
1930        /*
1931         * Update FIFO interrupt trigger level, which is currently
1932         * set to "full".
1933         */
1934        pci230_ai_update_fifo_trigger_level(dev, s);
1935        if (cmd->convert_src == TRIG_TIMER) {
1936                /* Update timer gates. */
1937                unsigned char zgat;
1938
1939                if (cmd->scan_begin_src != TRIG_FOLLOW) {
1940                        /*
1941                         * Conversion timer CT2 needs to be gated by
1942                         * inverted output of monostable CT2.
1943                         */
1944                        zgat = pci230_gat_config(2, GAT_NOUTNM2);
1945                } else {
1946                        /*
1947                         * Conversion timer CT2 needs to be gated on
1948                         * continuously.
1949                         */
1950                        zgat = pci230_gat_config(2, GAT_VCC);
1951                }
1952                outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
1953                if (cmd->scan_begin_src != TRIG_FOLLOW) {
1954                        /* Set monostable CT0 trigger source. */
1955                        switch (cmd->scan_begin_src) {
1956                        default:
1957                                zgat = pci230_gat_config(0, GAT_VCC);
1958                                break;
1959                        case TRIG_EXT:
1960                                /*
1961                                 * For CT0 on PCI230, the external trigger
1962                                 * (gate) signal comes from PPC0, which is
1963                                 * channel 16 of the DIO subdevice.  The
1964                                 * application needs to configure this as an
1965                                 * input in order to use it as an external scan
1966                                 * trigger.
1967                                 */
1968                                zgat = pci230_gat_config(0, GAT_EXT);
1969                                break;
1970                        case TRIG_TIMER:
1971                                /*
1972                                 * Monostable CT0 triggered by rising edge on
1973                                 * inverted output of CT1 (falling edge on CT1).
1974                                 */
1975                                zgat = pci230_gat_config(0, GAT_NOUTNM2);
1976                                break;
1977                        case TRIG_INT:
1978                                /*
1979                                 * Monostable CT0 is triggered by inttrig
1980                                 * function waggling the CT0 gate source.
1981                                 */
1982                                zgat = pci230_gat_config(0, GAT_VCC);
1983                                break;
1984                        }
1985                        outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
1986                        switch (cmd->scan_begin_src) {
1987                        case TRIG_TIMER:
1988                                /*
1989                                 * Scan period timer CT1 needs to be
1990                                 * gated on to start counting.
1991                                 */
1992                                zgat = pci230_gat_config(1, GAT_VCC);
1993                                outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
1994                                break;
1995                        case TRIG_INT:
1996                                async->inttrig = pci230_ai_inttrig_scan_begin;
1997                                break;
1998                        }
1999                }
2000        } else if (cmd->convert_src != TRIG_INT) {
2001                /* No longer need Z2-CT2. */
2002                pci230_release_shared(dev, RES_Z2CT2, OWNER_AICMD);
2003        }
2004}
2005
2006static int pci230_ai_inttrig_start(struct comedi_device *dev,
2007                                   struct comedi_subdevice *s,
2008                                   unsigned int trig_num)
2009{
2010        struct comedi_cmd *cmd = &s->async->cmd;
2011
2012        if (trig_num != cmd->start_arg)
2013                return -EINVAL;
2014
2015        s->async->inttrig = NULL;
2016        pci230_ai_start(dev, s);
2017
2018        return 1;
2019}
2020
2021static void pci230_handle_ai(struct comedi_device *dev,
2022                             struct comedi_subdevice *s)
2023{
2024        struct pci230_private *devpriv = dev->private;
2025        struct comedi_async *async = s->async;
2026        struct comedi_cmd *cmd = &async->cmd;
2027        unsigned int status_fifo;
2028        unsigned int i;
2029        unsigned int nsamples;
2030        unsigned int fifoamount;
2031        unsigned short val;
2032
2033        /* Determine number of samples to read. */
2034        nsamples = comedi_nsamples_left(s, PCI230_ADC_FIFOLEVEL_HALFFULL);
2035        if (nsamples == 0)
2036                return;
2037
2038        fifoamount = 0;
2039        for (i = 0; i < nsamples; i++) {
2040                if (fifoamount == 0) {
2041                        /* Read FIFO state. */
2042                        status_fifo = inw(devpriv->daqio + PCI230_ADCCON);
2043                        if (status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) {
2044                                /*
2045                                 * Report error otherwise FIFO overruns will go
2046                                 * unnoticed by the caller.
2047                                 */
2048                                dev_err(dev->class_dev, "AI FIFO overrun\n");
2049                                async->events |= COMEDI_CB_ERROR;
2050                                break;
2051                        } else if (status_fifo & PCI230_ADC_FIFO_EMPTY) {
2052                                /* FIFO empty. */
2053                                break;
2054                        } else if (status_fifo & PCI230_ADC_FIFO_HALF) {
2055                                /* FIFO half full. */
2056                                fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL;
2057                        } else if (devpriv->hwver > 0) {
2058                                /* Read PCI230+/260+ ADC FIFO level. */
2059                                fifoamount = inw(devpriv->daqio +
2060                                                 PCI230P_ADCFFLEV);
2061                                if (fifoamount == 0)
2062                                        break;  /* Shouldn't happen. */
2063                        } else {
2064                                /* FIFO not empty. */
2065                                fifoamount = 1;
2066                        }
2067                }
2068
2069                val = pci230_ai_read(dev);
2070                if (!comedi_buf_write_samples(s, &val, 1))
2071                        break;
2072
2073                fifoamount--;
2074
2075                if (cmd->stop_src == TRIG_COUNT &&
2076                    async->scans_done >= cmd->stop_arg) {
2077                        async->events |= COMEDI_CB_EOA;
2078                        break;
2079                }
2080        }
2081
2082        /* update FIFO interrupt trigger level if still running */
2083        if (!(async->events & COMEDI_CB_CANCEL_MASK))
2084                pci230_ai_update_fifo_trigger_level(dev, s);
2085}
2086
2087static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
2088{
2089        struct pci230_private *devpriv = dev->private;
2090        unsigned int i, chan, range, diff;
2091        unsigned int res_mask;
2092        unsigned short adccon, adcen;
2093        unsigned char zgat;
2094
2095        /* Get the command. */
2096        struct comedi_async *async = s->async;
2097        struct comedi_cmd *cmd = &async->cmd;
2098
2099        /*
2100         * Determine which shared resources are needed.
2101         */
2102        res_mask = 0;
2103        /*
2104         * Need Z2-CT2 to supply a conversion trigger source at a high
2105         * logic level, even if not doing timed conversions.
2106         */
2107        res_mask |= RES_Z2CT2;
2108        if (cmd->scan_begin_src != TRIG_FOLLOW) {
2109                /* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */
2110                res_mask |= RES_Z2CT0;
2111                if (cmd->scan_begin_src == TRIG_TIMER) {
2112                        /* Using Z2-CT1 for scan frequency */
2113                        res_mask |= RES_Z2CT1;
2114                }
2115        }
2116        /* Claim resources. */
2117        if (!pci230_claim_shared(dev, res_mask, OWNER_AICMD))
2118                return -EBUSY;
2119
2120        /*
2121         * Steps:
2122         * - Set channel scan list.
2123         * - Set channel gains.
2124         * - Enable and reset FIFO, specify uni/bip, se/diff, and set
2125         *   start conversion source to point to something at a high logic
2126         *   level (we use the output of counter/timer 2 for this purpose.
2127         * - PAUSE to allow things to settle down.
2128         * - Reset the FIFO again because it needs resetting twice and there
2129         *   may have been a false conversion trigger on some versions of
2130         *   PCI230/260 due to the start conversion source being set to a
2131         *   high logic level.
2132         * - Enable ADC FIFO level interrupt.
2133         * - Set actual conversion trigger source and FIFO interrupt trigger
2134         *   level.
2135         * - If convert_src is TRIG_TIMER, set up the timers.
2136         */
2137
2138        adccon = PCI230_ADC_FIFO_EN;
2139        adcen = 0;
2140
2141        if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
2142                /* Differential - all channels must be differential. */
2143                diff = 1;
2144                adccon |= PCI230_ADC_IM_DIF;
2145        } else {
2146                /* Single ended - all channels must be single-ended. */
2147                diff = 0;
2148                adccon |= PCI230_ADC_IM_SE;
2149        }
2150
2151        range = CR_RANGE(cmd->chanlist[0]);
2152        devpriv->ai_bipolar = comedi_range_is_bipolar(s, range);
2153        if (devpriv->ai_bipolar)
2154                adccon |= PCI230_ADC_IR_BIP;
2155        else
2156                adccon |= PCI230_ADC_IR_UNI;
2157
2158        for (i = 0; i < cmd->chanlist_len; i++) {
2159                unsigned int gainshift;
2160
2161                chan = CR_CHAN(cmd->chanlist[i]);
2162                range = CR_RANGE(cmd->chanlist[i]);
2163                if (diff) {
2164                        gainshift = 2 * chan;
2165                        if (devpriv->hwver == 0) {
2166                                /*
2167                                 * Original PCI230/260 expects both inputs of
2168                                 * the differential channel to be enabled.
2169                                 */
2170                                adcen |= 3 << gainshift;
2171                        } else {
2172                                /*
2173                                 * PCI230+/260+ expects only one input of the
2174                                 * differential channel to be enabled.
2175                                 */
2176                                adcen |= 1 << gainshift;
2177                        }
2178                } else {
2179                        gainshift = chan & ~1;
2180                        adcen |= 1 << chan;
2181                }
2182                devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) |
2183                                (pci230_ai_gain[range] << gainshift);
2184        }
2185
2186        /* Set channel scan list. */
2187        outw(adcen, devpriv->daqio + PCI230_ADCEN);
2188
2189        /* Set channel gains. */
2190        outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG);
2191
2192        /*
2193         * Set counter/timer 2 output high for use as the initial start
2194         * conversion source.
2195         */
2196        comedi_8254_set_mode(dev->pacer, 2, I8254_MODE1);
2197
2198        /*
2199         * Temporarily use CT2 output as conversion trigger source and
2200         * temporarily set FIFO interrupt trigger level to 'full'.
2201         */
2202        adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
2203
2204        /*
2205         * Enable and reset FIFO, specify FIFO trigger level full, specify
2206         * uni/bip, se/diff, and temporarily set the start conversion source
2207         * to CT2 output.  Note that CT2 output is currently high, and this
2208         * will produce a false conversion trigger on some versions of the
2209         * PCI230/260, but that will be dealt with later.
2210         */
2211        devpriv->adccon = adccon;
2212        outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON);
2213
2214        /*
2215         * Delay -
2216         * Failure to include this will result in the first few channels'-worth
2217         * of data being corrupt, normally manifesting itself by large negative
2218         * voltages. It seems the board needs time to settle between the first
2219         * FIFO reset (above) and the second FIFO reset (below). Setting the
2220         * channel gains and scan list _before_ the first FIFO reset also
2221         * helps, though only slightly.
2222         */
2223        usleep_range(25, 100);
2224
2225        /* Reset FIFO again. */
2226        outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON);
2227
2228        if (cmd->convert_src == TRIG_TIMER) {
2229                /*
2230                 * Set up CT2 as conversion timer, but gate it off for now.
2231                 * Note, counter/timer output 2 can be monitored on the
2232                 * connector: PCI230 pin 21, PCI260 pin 18.
2233                 */
2234                zgat = pci230_gat_config(2, GAT_GND);
2235                outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
2236                /* Set counter/timer 2 to the specified conversion period. */
2237                pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg,
2238                                        cmd->flags);
2239                if (cmd->scan_begin_src != TRIG_FOLLOW) {
2240                        /*
2241                         * Set up monostable on CT0 output for scan timing.  A
2242                         * rising edge on the trigger (gate) input of CT0 will
2243                         * trigger the monostable, causing its output to go low
2244                         * for the configured period.  The period depends on
2245                         * the conversion period and the number of conversions
2246                         * in the scan.
2247                         *
2248                         * Set the trigger high before setting up the
2249                         * monostable to stop it triggering.  The trigger
2250                         * source will be changed later.
2251                         */
2252                        zgat = pci230_gat_config(0, GAT_VCC);
2253                        outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
2254                        pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1,
2255                                                ((u64)cmd->convert_arg *
2256                                                 cmd->scan_end_arg),
2257                                                CMDF_ROUND_UP);
2258                        if (cmd->scan_begin_src == TRIG_TIMER) {
2259                                /*
2260                                 * Monostable on CT0 will be triggered by
2261                                 * output of CT1 at configured scan frequency.
2262                                 *
2263                                 * Set up CT1 but gate it off for now.
2264                                 */
2265                                zgat = pci230_gat_config(1, GAT_GND);
2266                                outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
2267                                pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
2268                                                        cmd->scan_begin_arg,
2269                                                        cmd->flags);
2270                        }
2271                }
2272        }
2273
2274        if (cmd->start_src == TRIG_INT)
2275                s->async->inttrig = pci230_ai_inttrig_start;
2276        else    /* TRIG_NOW */
2277                pci230_ai_start(dev, s);
2278
2279        return 0;
2280}
2281
2282static int pci230_ai_cancel(struct comedi_device *dev,
2283                            struct comedi_subdevice *s)
2284{
2285        pci230_ai_stop(dev, s);
2286        return 0;
2287}
2288
2289/* Interrupt handler */
2290static irqreturn_t pci230_interrupt(int irq, void *d)
2291{
2292        unsigned char status_int, valid_status_int, temp_ier;
2293        struct comedi_device *dev = d;
2294        struct pci230_private *devpriv = dev->private;
2295        struct comedi_subdevice *s_ao = dev->write_subdev;
2296        struct comedi_subdevice *s_ai = dev->read_subdev;
2297        unsigned long irqflags;
2298
2299        /* Read interrupt status/enable register. */
2300        status_int = inb(dev->iobase + PCI230_INT_STAT);
2301
2302        if (status_int == PCI230_INT_DISABLE)
2303                return IRQ_NONE;
2304
2305        spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2306        valid_status_int = devpriv->ier & status_int;
2307        /*
2308         * Disable triggered interrupts.
2309         * (Only those interrupts that need re-enabling, are, later in the
2310         * handler).
2311         */
2312        temp_ier = devpriv->ier & ~status_int;
2313        outb(temp_ier, dev->iobase + PCI230_INT_SCE);
2314        devpriv->intr_running = true;
2315        devpriv->intr_cpuid = THISCPU;
2316        spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2317
2318        /*
2319         * Check the source of interrupt and handle it.
2320         * The PCI230 can cope with concurrent ADC, DAC, PPI C0 and C3
2321         * interrupts.  However, at present (Comedi-0.7.60) does not allow
2322         * concurrent execution of commands, instructions or a mixture of the
2323         * two.
2324         */
2325
2326        if (valid_status_int & PCI230_INT_ZCLK_CT1)
2327                pci230_handle_ao_nofifo(dev, s_ao);
2328
2329        if (valid_status_int & PCI230P2_INT_DAC)
2330                pci230_handle_ao_fifo(dev, s_ao);
2331
2332        if (valid_status_int & PCI230_INT_ADC)
2333                pci230_handle_ai(dev, s_ai);
2334
2335        /* Reenable interrupts. */
2336        spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
2337        if (devpriv->ier != temp_ier)
2338                outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
2339        devpriv->intr_running = false;
2340        spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
2341
2342        comedi_handle_events(dev, s_ao);
2343        comedi_handle_events(dev, s_ai);
2344
2345        return IRQ_HANDLED;
2346}
2347
2348/* Check if PCI device matches a specific board. */
2349static bool pci230_match_pci_board(const struct pci230_board *board,
2350                                   struct pci_dev *pci_dev)
2351{
2352        /* assume pci_dev->device != PCI_DEVICE_ID_INVALID */
2353        if (board->id != pci_dev->device)
2354                return false;
2355        if (board->min_hwver == 0)
2356                return true;
2357        /* Looking for a '+' model.  First check length of registers. */
2358        if (pci_resource_len(pci_dev, 3) < 32)
2359                return false;   /* Not a '+' model. */
2360        /*
2361         * TODO: temporarily enable PCI device and read the hardware version
2362         * register.  For now, assume it's okay.
2363         */
2364        return true;
2365}
2366
2367/* Look for board matching PCI device. */
2368static const struct pci230_board *pci230_find_pci_board(struct pci_dev *pci_dev)
2369{
2370        unsigned int i;
2371
2372        for (i = 0; i < ARRAY_SIZE(pci230_boards); i++)
2373                if (pci230_match_pci_board(&pci230_boards[i], pci_dev))
2374                        return &pci230_boards[i];
2375        return NULL;
2376}
2377
2378static int pci230_auto_attach(struct comedi_device *dev,
2379                              unsigned long context_unused)
2380{
2381        struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
2382        const struct pci230_board *board;
2383        struct pci230_private *devpriv;
2384        struct comedi_subdevice *s;
2385        int rc;
2386
2387        dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n",
2388                 pci_name(pci_dev));
2389
2390        devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
2391        if (!devpriv)
2392                return -ENOMEM;
2393
2394        spin_lock_init(&devpriv->isr_spinlock);
2395        spin_lock_init(&devpriv->res_spinlock);
2396        spin_lock_init(&devpriv->ai_stop_spinlock);
2397        spin_lock_init(&devpriv->ao_stop_spinlock);
2398
2399        board = pci230_find_pci_board(pci_dev);
2400        if (!board) {
2401                dev_err(dev->class_dev,
2402                        "amplc_pci230: BUG! cannot determine board type!\n");
2403                return -EINVAL;
2404        }
2405        dev->board_ptr = board;
2406        dev->board_name = board->name;
2407
2408        rc = comedi_pci_enable(dev);
2409        if (rc)
2410                return rc;
2411
2412        /*
2413         * Read base addresses of the PCI230's two I/O regions from PCI
2414         * configuration register.
2415         */
2416        dev->iobase = pci_resource_start(pci_dev, 2);
2417        devpriv->daqio = pci_resource_start(pci_dev, 3);
2418        dev_dbg(dev->class_dev,
2419                "%s I/O region 1 0x%04lx I/O region 2 0x%04lx\n",
2420                dev->board_name, dev->iobase, devpriv->daqio);
2421        /* Read bits of DACCON register - only the output range. */
2422        devpriv->daccon = inw(devpriv->daqio + PCI230_DACCON) &
2423                          PCI230_DAC_OR_MASK;
2424        /*
2425         * Read hardware version register and set extended function register
2426         * if they exist.
2427         */
2428        if (pci_resource_len(pci_dev, 3) >= 32) {
2429                unsigned short extfunc = 0;
2430
2431                devpriv->hwver = inw(devpriv->daqio + PCI230P_HWVER);
2432                if (devpriv->hwver < board->min_hwver) {
2433                        dev_err(dev->class_dev,
2434                                "%s - bad hardware version - got %u, need %u\n",
2435                                dev->board_name, devpriv->hwver,
2436                                board->min_hwver);
2437                        return -EIO;
2438                }
2439                if (devpriv->hwver > 0) {
2440                        if (!board->have_dio) {
2441                                /*
2442                                 * No DIO ports.  Route counters' external gates
2443                                 * to the EXTTRIG signal (PCI260+ pin 17).
2444                                 * (Otherwise, they would be routed to DIO
2445                                 * inputs PC0, PC1 and PC2 which don't exist
2446                                 * on PCI260[+].)
2447                                 */
2448                                extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
2449                        }
2450                        if (board->ao_bits && devpriv->hwver >= 2) {
2451                                /* Enable DAC FIFO functionality. */
2452                                extfunc |= PCI230P2_EXTFUNC_DACFIFO;
2453                        }
2454                }
2455                outw(extfunc, devpriv->daqio + PCI230P_EXTFUNC);
2456                if (extfunc & PCI230P2_EXTFUNC_DACFIFO) {
2457                        /*
2458                         * Temporarily enable DAC FIFO, reset it and disable
2459                         * FIFO wraparound.
2460                         */
2461                        outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN |
2462                             PCI230P2_DAC_FIFO_RESET,
2463                             devpriv->daqio + PCI230_DACCON);
2464                        /* Clear DAC FIFO channel enable register. */
2465                        outw(0, devpriv->daqio + PCI230P2_DACEN);
2466                        /* Disable DAC FIFO. */
2467                        outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON);
2468                }
2469        }
2470        /* Disable board's interrupts. */
2471        outb(0, dev->iobase + PCI230_INT_SCE);
2472        /* Set ADC to a reasonable state. */
2473        devpriv->adcg = 0;
2474        devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE |
2475                          PCI230_ADC_IR_BIP;
2476        outw(1 << 0, devpriv->daqio + PCI230_ADCEN);
2477        outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG);
2478        outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
2479             devpriv->daqio + PCI230_ADCCON);
2480
2481        if (pci_dev->irq) {
2482                rc = request_irq(pci_dev->irq, pci230_interrupt, IRQF_SHARED,
2483                                 dev->board_name, dev);
2484                if (rc == 0)
2485                        dev->irq = pci_dev->irq;
2486        }
2487
2488        dev->pacer = comedi_8254_init(dev->iobase + PCI230_Z2_CT_BASE,
2489                                      0, I8254_IO8, 0);
2490        if (!dev->pacer)
2491                return -ENOMEM;
2492
2493        rc = comedi_alloc_subdevices(dev, 3);
2494        if (rc)
2495                return rc;
2496
2497        s = &dev->subdevices[0];
2498        /* analog input subdevice */
2499        s->type = COMEDI_SUBD_AI;
2500        s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
2501        s->n_chan = 16;
2502        s->maxdata = (1 << board->ai_bits) - 1;
2503        s->range_table = &pci230_ai_range;
2504        s->insn_read = pci230_ai_insn_read;
2505        s->len_chanlist = 256;  /* but there are restrictions. */
2506        if (dev->irq) {
2507                dev->read_subdev = s;
2508                s->subdev_flags |= SDF_CMD_READ;
2509                s->do_cmd = pci230_ai_cmd;
2510                s->do_cmdtest = pci230_ai_cmdtest;
2511                s->cancel = pci230_ai_cancel;
2512        }
2513
2514        s = &dev->subdevices[1];
2515        /* analog output subdevice */
2516        if (board->ao_bits) {
2517                s->type = COMEDI_SUBD_AO;
2518                s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
2519                s->n_chan = 2;
2520                s->maxdata = (1 << board->ao_bits) - 1;
2521                s->range_table = &pci230_ao_range;
2522                s->insn_write = pci230_ao_insn_write;
2523                s->len_chanlist = 2;
2524                if (dev->irq) {
2525                        dev->write_subdev = s;
2526                        s->subdev_flags |= SDF_CMD_WRITE;
2527                        s->do_cmd = pci230_ao_cmd;
2528                        s->do_cmdtest = pci230_ao_cmdtest;
2529                        s->cancel = pci230_ao_cancel;
2530                }
2531
2532                rc = comedi_alloc_subdev_readback(s);
2533                if (rc)
2534                        return rc;
2535        } else {
2536                s->type = COMEDI_SUBD_UNUSED;
2537        }
2538
2539        s = &dev->subdevices[2];
2540        /* digital i/o subdevice */
2541        if (board->have_dio) {
2542                rc = subdev_8255_init(dev, s, NULL, PCI230_PPI_X_BASE);
2543                if (rc)
2544                        return rc;
2545        } else {
2546                s->type = COMEDI_SUBD_UNUSED;
2547        }
2548
2549        return 0;
2550}
2551
2552static struct comedi_driver amplc_pci230_driver = {
2553        .driver_name    = "amplc_pci230",
2554        .module         = THIS_MODULE,
2555        .auto_attach    = pci230_auto_attach,
2556        .detach         = comedi_pci_detach,
2557};
2558
2559static int amplc_pci230_pci_probe(struct pci_dev *dev,
2560                                  const struct pci_device_id *id)
2561{
2562        return comedi_pci_auto_config(dev, &amplc_pci230_driver,
2563                                      id->driver_data);
2564}
2565
2566static const struct pci_device_id amplc_pci230_pci_table[] = {
2567        { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230) },
2568        { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260) },
2569        { 0 }
2570};
2571MODULE_DEVICE_TABLE(pci, amplc_pci230_pci_table);
2572
2573static struct pci_driver amplc_pci230_pci_driver = {
2574        .name           = "amplc_pci230",
2575        .id_table       = amplc_pci230_pci_table,
2576        .probe          = amplc_pci230_pci_probe,
2577        .remove         = comedi_pci_auto_unconfig,
2578};
2579module_comedi_pci_driver(amplc_pci230_driver, amplc_pci230_pci_driver);
2580
2581MODULE_AUTHOR("Comedi http://www.comedi.org");
2582MODULE_DESCRIPTION("Comedi driver for Amplicon PCI230(+) and PCI260(+)");
2583MODULE_LICENSE("GPL");
2584