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