cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

amplc_pci230.c (78095B)


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