GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / staging / comedi / drivers / amplc_pci224.c
1 /*
2  * comedi/drivers/amplc_pci224.c
3  * Driver for Amplicon PCI224 and PCI234 AO boards.
4  *
5  * Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
6  *
7  * COMEDI - Linux Control and Measurement Device Interface
8  * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  */
20
21 /*
22  * Driver: amplc_pci224
23  * Description: Amplicon PCI224, PCI234
24  * Author: Ian Abbott <abbotti@mev.co.uk>
25  * Devices: [Amplicon] PCI224 (amplc_pci224), PCI234
26  * Updated: Thu, 31 Jul 2014 11:08:03 +0000
27  * Status: works, but see caveats
28  *
29  * Supports:
30  *
31  *   - ao_insn read/write
32  *   - ao_do_cmd mode with the following sources:
33  *
34  *     - start_src         TRIG_INT        TRIG_EXT
35  *     - scan_begin_src    TRIG_TIMER      TRIG_EXT
36  *     - convert_src       TRIG_NOW
37  *     - scan_end_src      TRIG_COUNT
38  *     - stop_src          TRIG_COUNT      TRIG_EXT        TRIG_NONE
39  *
40  *     The channel list must contain at least one channel with no repeated
41  *     channels.  The scan end count must equal the number of channels in
42  *     the channel list.
43  *
44  *     There is only one external trigger source so only one of start_src,
45  *     scan_begin_src or stop_src may use TRIG_EXT.
46  *
47  * Configuration options:
48  *   none
49  *
50  * Manual configuration of PCI cards is not supported; they are configured
51  * automatically.
52  *
53  * Output range selection - PCI224:
54  *
55  *   Output ranges on PCI224 are partly software-selectable and partly
56  *   hardware-selectable according to jumper LK1.  All channels are set
57  *   to the same range:
58  *
59  *   - LK1 position 1-2 (factory default) corresponds to the following
60  *     comedi ranges:
61  *
62  *       0: [-10V,+10V]; 1: [-5V,+5V]; 2: [-2.5V,+2.5V], 3: [-1.25V,+1.25V],
63  *       4: [0,+10V],    5: [0,+5V],   6: [0,+2.5V],     7: [0,+1.25V]
64  *
65  *   - LK1 position 2-3 corresponds to the following Comedi ranges, using
66  *     an external voltage reference:
67  *
68  *       0: [-Vext,+Vext],
69  *       1: [0,+Vext]
70  *
71  * Output range selection - PCI234:
72  *
73  *   Output ranges on PCI234 are hardware-selectable according to jumper
74  *   LK1 which affects all channels, and jumpers LK2, LK3, LK4 and LK5
75  *   which affect channels 0, 1, 2 and 3 individually.  LK1 chooses between
76  *   an internal 5V reference and an external voltage reference (Vext).
77  *   LK2/3/4/5 choose (per channel) to double the reference or not according
78  *   to the following table:
79  *
80  *     LK1 position   LK2/3/4/5 pos  Comedi range
81  *     -------------  -------------  --------------
82  *     2-3 (factory)  1-2 (factory)  0: [-10V,+10V]
83  *     2-3 (factory)  2-3            1: [-5V,+5V]
84  *     1-2            1-2 (factory)  2: [-2*Vext,+2*Vext]
85  *     1-2            2-3            3: [-Vext,+Vext]
86  *
87  * Caveats:
88  *
89  *   1) All channels on the PCI224 share the same range.  Any change to the
90  *      range as a result of insn_write or a streaming command will affect
91  *      the output voltages of all channels, including those not specified
92  *      by the instruction or command.
93  *
94  *   2) For the analog output command,  the first scan may be triggered
95  *      falsely at the start of acquisition.  This occurs when the DAC scan
96  *      trigger source is switched from 'none' to 'timer' (scan_begin_src =
97  *      TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
98  *      of acquisition and the trigger source is at logic level 1 at the
99  *      time of the switch.  This is very likely for TRIG_TIMER.  For
100  *      TRIG_EXT, it depends on the state of the external line and whether
101  *      the CR_INVERT flag has been set.  The remaining scans are triggered
102  *      correctly.
103  */
104
105 #include <linux/module.h>
106 #include <linux/interrupt.h>
107 #include <linux/slab.h>
108
109 #include "../comedi_pci.h"
110
111 #include "comedi_8254.h"
112
113 /*
114  * PCI224/234 i/o space 1 (PCIBAR2) registers.
115  */
116 #define PCI224_Z2_BASE  0x14    /* 82C54 counter/timer */
117 #define PCI224_ZCLK_SCE 0x1A    /* Group Z Clock Configuration Register */
118 #define PCI224_ZGAT_SCE 0x1D    /* Group Z Gate Configuration Register */
119 #define PCI224_INT_SCE  0x1E    /* ISR Interrupt source mask register */
120                                 /* /Interrupt status */
121
122 /*
123  * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
124  */
125 #define PCI224_DACDATA  0x00    /* (w-o) DAC FIFO data. */
126 #define PCI224_SOFTTRIG 0x00    /* (r-o) DAC software scan trigger. */
127 #define PCI224_DACCON   0x02    /* (r/w) DAC status/configuration. */
128 #define PCI224_FIFOSIZ  0x04    /* (w-o) FIFO size for wraparound mode. */
129 #define PCI224_DACCEN   0x06    /* (w-o) DAC channel enable register. */
130
131 /*
132  * DACCON values.
133  */
134 /* (r/w) Scan trigger. */
135 #define PCI224_DACCON_TRIG(x)           (((x) & 0x7) << 0)
136 #define PCI224_DACCON_TRIG_MASK         PCI224_DACCON_TRIG(7)
137 #define PCI224_DACCON_TRIG_NONE         PCI224_DACCON_TRIG(0)   /* none */
138 #define PCI224_DACCON_TRIG_SW           PCI224_DACCON_TRIG(1)   /* soft trig */
139 #define PCI224_DACCON_TRIG_EXTP         PCI224_DACCON_TRIG(2)   /* ext + edge */
140 #define PCI224_DACCON_TRIG_EXTN         PCI224_DACCON_TRIG(3)   /* ext - edge */
141 #define PCI224_DACCON_TRIG_Z2CT0        PCI224_DACCON_TRIG(4)   /* Z2 CT0 out */
142 #define PCI224_DACCON_TRIG_Z2CT1        PCI224_DACCON_TRIG(5)   /* Z2 CT1 out */
143 #define PCI224_DACCON_TRIG_Z2CT2        PCI224_DACCON_TRIG(6)   /* Z2 CT2 out */
144 /* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
145 #define PCI224_DACCON_POLAR(x)          (((x) & 0x1) << 3)
146 #define PCI224_DACCON_POLAR_MASK        PCI224_DACCON_POLAR(1)
147 #define PCI224_DACCON_POLAR_UNI         PCI224_DACCON_POLAR(0)  /* [0,+V] */
148 #define PCI224_DACCON_POLAR_BI          PCI224_DACCON_POLAR(1)  /* [-V,+V] */
149 /* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
150 #define PCI224_DACCON_VREF(x)           (((x) & 0x3) << 4)
151 #define PCI224_DACCON_VREF_MASK         PCI224_DACCON_VREF(3)
152 #define PCI224_DACCON_VREF_1_25         PCI224_DACCON_VREF(0)   /* 1.25V */
153 #define PCI224_DACCON_VREF_2_5          PCI224_DACCON_VREF(1)   /* 2.5V */
154 #define PCI224_DACCON_VREF_5            PCI224_DACCON_VREF(2)   /* 5V */
155 #define PCI224_DACCON_VREF_10           PCI224_DACCON_VREF(3)   /* 10V */
156 /* (r/w) Wraparound mode enable (to play back stored waveform). */
157 #define PCI224_DACCON_FIFOWRAP          BIT(7)
158 /* (r/w) FIFO enable.  It MUST be set! */
159 #define PCI224_DACCON_FIFOENAB          BIT(8)
160 /* (r/w) FIFO interrupt trigger level (most values are not very useful). */
161 #define PCI224_DACCON_FIFOINTR(x)       (((x) & 0x7) << 9)
162 #define PCI224_DACCON_FIFOINTR_MASK     PCI224_DACCON_FIFOINTR(7)
163 #define PCI224_DACCON_FIFOINTR_EMPTY    PCI224_DACCON_FIFOINTR(0) /* empty */
164 #define PCI224_DACCON_FIFOINTR_NEMPTY   PCI224_DACCON_FIFOINTR(1) /* !empty */
165 #define PCI224_DACCON_FIFOINTR_NHALF    PCI224_DACCON_FIFOINTR(2) /* !half */
166 #define PCI224_DACCON_FIFOINTR_HALF     PCI224_DACCON_FIFOINTR(3) /* half */
167 #define PCI224_DACCON_FIFOINTR_NFULL    PCI224_DACCON_FIFOINTR(4) /* !full */
168 #define PCI224_DACCON_FIFOINTR_FULL     PCI224_DACCON_FIFOINTR(5) /* full */
169 /* (r-o) FIFO fill level. */
170 #define PCI224_DACCON_FIFOFL(x)         (((x) & 0x7) << 12)
171 #define PCI224_DACCON_FIFOFL_MASK       PCI224_DACCON_FIFOFL(7)
172 #define PCI224_DACCON_FIFOFL_EMPTY      PCI224_DACCON_FIFOFL(1) /* 0 */
173 #define PCI224_DACCON_FIFOFL_ONETOHALF  PCI224_DACCON_FIFOFL(0) /* 1-2048 */
174 #define PCI224_DACCON_FIFOFL_HALFTOFULL PCI224_DACCON_FIFOFL(4) /* 2049-4095 */
175 #define PCI224_DACCON_FIFOFL_FULL       PCI224_DACCON_FIFOFL(6) /* 4096 */
176 /* (r-o) DAC busy flag. */
177 #define PCI224_DACCON_BUSY              BIT(15)
178 /* (w-o) FIFO reset. */
179 #define PCI224_DACCON_FIFORESET         BIT(12)
180 /* (w-o) Global reset (not sure what it does). */
181 #define PCI224_DACCON_GLOBALRESET       BIT(13)
182
183 /*
184  * DAC FIFO size.
185  */
186 #define PCI224_FIFO_SIZE        4096
187
188 /*
189  * DAC FIFO guaranteed minimum room available, depending on reported fill level.
190  * The maximum room available depends on the reported fill level and how much
191  * has been written!
192  */
193 #define PCI224_FIFO_ROOM_EMPTY          PCI224_FIFO_SIZE
194 #define PCI224_FIFO_ROOM_ONETOHALF      (PCI224_FIFO_SIZE / 2)
195 #define PCI224_FIFO_ROOM_HALFTOFULL     1
196 #define PCI224_FIFO_ROOM_FULL           0
197
198 /*
199  * Counter/timer clock input configuration sources.
200  */
201 #define CLK_CLK         0       /* reserved (channel-specific clock) */
202 #define CLK_10MHZ       1       /* internal 10 MHz clock */
203 #define CLK_1MHZ        2       /* internal 1 MHz clock */
204 #define CLK_100KHZ      3       /* internal 100 kHz clock */
205 #define CLK_10KHZ       4       /* internal 10 kHz clock */
206 #define CLK_1KHZ        5       /* internal 1 kHz clock */
207 #define CLK_OUTNM1      6       /* output of channel-1 modulo total */
208 #define CLK_EXT         7       /* external clock */
209
210 static unsigned int pci224_clk_config(unsigned int chan, unsigned int src)
211 {
212         return ((chan & 3) << 3) | (src & 7);
213 }
214
215 /*
216  * Counter/timer gate input configuration sources.
217  */
218 #define GAT_VCC         0       /* VCC (i.e. enabled) */
219 #define GAT_GND         1       /* GND (i.e. disabled) */
220 #define GAT_EXT         2       /* reserved (external gate input) */
221 #define GAT_NOUTNM2     3       /* inverted output of channel-2 modulo total */
222
223 static unsigned int pci224_gat_config(unsigned int chan, unsigned int src)
224 {
225         return ((chan & 3) << 3) | (src & 7);
226 }
227
228 /*
229  * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
230  *
231  *              Channel's       Channel's
232  *              clock input     gate input
233  * Channel      CLK_OUTNM1      GAT_NOUTNM2
234  * -------      ----------      -----------
235  * Z2-CT0       Z2-CT2-OUT      /Z2-CT1-OUT
236  * Z2-CT1       Z2-CT0-OUT      /Z2-CT2-OUT
237  * Z2-CT2       Z2-CT1-OUT      /Z2-CT0-OUT
238  */
239
240 /*
241  * Interrupt enable/status bits
242  */
243 #define PCI224_INTR_EXT         0x01    /* rising edge on external input */
244 #define PCI224_INTR_DAC         0x04    /* DAC (FIFO) interrupt */
245 #define PCI224_INTR_Z2CT1       0x20    /* rising edge on Z2-CT1 output */
246
247 #define PCI224_INTR_EDGE_BITS   (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
248 #define PCI224_INTR_LEVEL_BITS  PCI224_INTR_DACFIFO
249
250 /*
251  * Handy macros.
252  */
253
254 /* Combine old and new bits. */
255 #define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
256
257 /* Current CPU.  XXX should this be hard_smp_processor_id()? */
258 #define THISCPU         smp_processor_id()
259
260 /* State bits for use with atomic bit operations. */
261 #define AO_CMD_STARTED  0
262
263 /*
264  * Range tables.
265  */
266
267 /*
268  * The ranges for PCI224.
269  *
270  * These are partly hardware-selectable by jumper LK1 and partly
271  * software-selectable.
272  *
273  * All channels share the same hardware range.
274  */
275 static const struct comedi_lrange range_pci224 = {
276         10, {
277                 /* jumper LK1 in position 1-2 (factory default) */
278                 BIP_RANGE(10),
279                 BIP_RANGE(5),
280                 BIP_RANGE(2.5),
281                 BIP_RANGE(1.25),
282                 UNI_RANGE(10),
283                 UNI_RANGE(5),
284                 UNI_RANGE(2.5),
285                 UNI_RANGE(1.25),
286                 /* jumper LK1 in position 2-3 */
287                 RANGE_ext(-1, 1),       /* bipolar [-Vext,+Vext] */
288                 RANGE_ext(0, 1),        /* unipolar [0,+Vext] */
289         }
290 };
291
292 static const unsigned short hwrange_pci224[10] = {
293         /* jumper LK1 in position 1-2 (factory default) */
294         PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
295         PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
296         PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
297         PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
298         PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
299         PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
300         PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
301         PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
302         /* jumper LK1 in position 2-3 */
303         PCI224_DACCON_POLAR_BI,
304         PCI224_DACCON_POLAR_UNI,
305 };
306
307 /* Used to check all channels set to the same range on PCI224. */
308 static const unsigned char range_check_pci224[10] = {
309         0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
310 };
311
312 /*
313  * The ranges for PCI234.
314  *
315  * These are all hardware-selectable by jumper LK1 affecting all channels,
316  * and jumpers LK2, LK3, LK4 and LK5 affecting channels 0, 1, 2 and 3
317  * individually.
318  */
319 static const struct comedi_lrange range_pci234 = {
320         4, {
321                 /* LK1: 1-2 (fact def), LK2/3/4/5: 2-3 (fac def) */
322                 BIP_RANGE(10),
323                 /* LK1: 1-2 (fact def), LK2/3/4/5: 1-2 */
324                 BIP_RANGE(5),
325                 /* LK1: 2-3, LK2/3/4/5: 2-3 (fac def) */
326                 RANGE_ext(-2, 2),       /* bipolar [-2*Vext,+2*Vext] */
327                 /* LK1: 2-3, LK2/3/4/5: 1-2 */
328                 RANGE_ext(-1, 1),       /* bipolar [-Vext,+Vext] */
329         }
330 };
331
332 /* N.B. PCI234 ignores the polarity bit, but software uses it. */
333 static const unsigned short hwrange_pci234[4] = {
334         PCI224_DACCON_POLAR_BI,
335         PCI224_DACCON_POLAR_BI,
336         PCI224_DACCON_POLAR_BI,
337         PCI224_DACCON_POLAR_BI,
338 };
339
340 /* Used to check all channels use same LK1 setting on PCI234. */
341 static const unsigned char range_check_pci234[4] = {
342         0, 0, 1, 1,
343 };
344
345 /*
346  * Board descriptions.
347  */
348
349 enum pci224_model { pci224_model, pci234_model };
350
351 struct pci224_board {
352         const char *name;
353         unsigned int ao_chans;
354         unsigned int ao_bits;
355         const struct comedi_lrange *ao_range;
356         const unsigned short *ao_hwrange;
357         const unsigned char *ao_range_check;
358 };
359
360 static const struct pci224_board pci224_boards[] = {
361         [pci224_model] = {
362                 .name           = "pci224",
363                 .ao_chans       = 16,
364                 .ao_bits        = 12,
365                 .ao_range       = &range_pci224,
366                 .ao_hwrange     = &hwrange_pci224[0],
367                 .ao_range_check = &range_check_pci224[0],
368         },
369         [pci234_model] = {
370                 .name           = "pci234",
371                 .ao_chans       = 4,
372                 .ao_bits        = 16,
373                 .ao_range       = &range_pci234,
374                 .ao_hwrange     = &hwrange_pci234[0],
375                 .ao_range_check = &range_check_pci234[0],
376         },
377 };
378
379 struct pci224_private {
380         unsigned long iobase1;
381         unsigned long state;
382         spinlock_t ao_spinlock; /* spinlock for AO command handling */
383         unsigned short *ao_scan_vals;
384         unsigned char *ao_scan_order;
385         int intr_cpuid;
386         short intr_running;
387         unsigned short daccon;
388         unsigned short ao_enab; /* max 16 channels so 'short' will do */
389         unsigned char intsce;
390 };
391
392 /*
393  * Called from the 'insn_write' function to perform a single write.
394  */
395 static void
396 pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
397                    unsigned int data)
398 {
399         const struct pci224_board *board = dev->board_ptr;
400         struct pci224_private *devpriv = dev->private;
401         unsigned short mangled;
402
403         /* Enable the channel. */
404         outw(1 << chan, dev->iobase + PCI224_DACCEN);
405         /* Set range and reset FIFO. */
406         devpriv->daccon = COMBINE(devpriv->daccon, board->ao_hwrange[range],
407                                   PCI224_DACCON_POLAR_MASK |
408                                   PCI224_DACCON_VREF_MASK);
409         outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
410              dev->iobase + PCI224_DACCON);
411         /*
412          * Mangle the data.  The hardware expects:
413          * - bipolar: 16-bit 2's complement
414          * - unipolar: 16-bit unsigned
415          */
416         mangled = (unsigned short)data << (16 - board->ao_bits);
417         if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
418             PCI224_DACCON_POLAR_BI) {
419                 mangled ^= 0x8000;
420         }
421         /* Write mangled data to the FIFO. */
422         outw(mangled, dev->iobase + PCI224_DACDATA);
423         /* Trigger the conversion. */
424         inw(dev->iobase + PCI224_SOFTTRIG);
425 }
426
427 static int pci224_ao_insn_write(struct comedi_device *dev,
428                                 struct comedi_subdevice *s,
429                                 struct comedi_insn *insn,
430                                 unsigned int *data)
431 {
432         unsigned int chan = CR_CHAN(insn->chanspec);
433         unsigned int range = CR_RANGE(insn->chanspec);
434         unsigned int val = s->readback[chan];
435         int i;
436
437         for (i = 0; i < insn->n; i++) {
438                 val = data[i];
439                 pci224_ao_set_data(dev, chan, range, val);
440         }
441         s->readback[chan] = val;
442
443         return insn->n;
444 }
445
446 /*
447  * Kills a command running on the AO subdevice.
448  */
449 static void pci224_ao_stop(struct comedi_device *dev,
450                            struct comedi_subdevice *s)
451 {
452         struct pci224_private *devpriv = dev->private;
453         unsigned long flags;
454
455         if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
456                 return;
457
458         spin_lock_irqsave(&devpriv->ao_spinlock, flags);
459         /* Kill the interrupts. */
460         devpriv->intsce = 0;
461         outb(0, devpriv->iobase1 + PCI224_INT_SCE);
462         /*
463          * Interrupt routine may or may not be running.  We may or may not
464          * have been called from the interrupt routine (directly or
465          * indirectly via a comedi_events() callback routine).  It's highly
466          * unlikely that we've been called from some other interrupt routine
467          * but who knows what strange things coders get up to!
468          *
469          * If the interrupt routine is currently running, wait for it to
470          * finish, unless we appear to have been called via the interrupt
471          * routine.
472          */
473         while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
474                 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
475                 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
476         }
477         spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
478         /* Reconfigure DAC for insn_write usage. */
479         outw(0, dev->iobase + PCI224_DACCEN);   /* Disable channels. */
480         devpriv->daccon =
481              COMBINE(devpriv->daccon,
482                      PCI224_DACCON_TRIG_SW | PCI224_DACCON_FIFOINTR_EMPTY,
483                      PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
484         outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
485              dev->iobase + PCI224_DACCON);
486 }
487
488 /*
489  * Handles start of acquisition for the AO subdevice.
490  */
491 static void pci224_ao_start(struct comedi_device *dev,
492                             struct comedi_subdevice *s)
493 {
494         struct pci224_private *devpriv = dev->private;
495         struct comedi_cmd *cmd = &s->async->cmd;
496         unsigned long flags;
497
498         set_bit(AO_CMD_STARTED, &devpriv->state);
499
500         /* Enable interrupts. */
501         spin_lock_irqsave(&devpriv->ao_spinlock, flags);
502         if (cmd->stop_src == TRIG_EXT)
503                 devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
504         else
505                 devpriv->intsce = PCI224_INTR_DAC;
506
507         outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
508         spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
509 }
510
511 /*
512  * Handles interrupts from the DAC FIFO.
513  */
514 static void pci224_ao_handle_fifo(struct comedi_device *dev,
515                                   struct comedi_subdevice *s)
516 {
517         struct pci224_private *devpriv = dev->private;
518         struct comedi_cmd *cmd = &s->async->cmd;
519         unsigned int num_scans = comedi_nscans_left(s, 0);
520         unsigned int room;
521         unsigned short dacstat;
522         unsigned int i, n;
523
524         /* Determine how much room is in the FIFO (in samples). */
525         dacstat = inw(dev->iobase + PCI224_DACCON);
526         switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
527         case PCI224_DACCON_FIFOFL_EMPTY:
528                 room = PCI224_FIFO_ROOM_EMPTY;
529                 if (cmd->stop_src == TRIG_COUNT &&
530                     s->async->scans_done >= cmd->stop_arg) {
531                         /* FIFO empty at end of counted acquisition. */
532                         s->async->events |= COMEDI_CB_EOA;
533                         comedi_handle_events(dev, s);
534                         return;
535                 }
536                 break;
537         case PCI224_DACCON_FIFOFL_ONETOHALF:
538                 room = PCI224_FIFO_ROOM_ONETOHALF;
539                 break;
540         case PCI224_DACCON_FIFOFL_HALFTOFULL:
541                 room = PCI224_FIFO_ROOM_HALFTOFULL;
542                 break;
543         default:
544                 room = PCI224_FIFO_ROOM_FULL;
545                 break;
546         }
547         if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
548                 /* FIFO is less than half-full. */
549                 if (num_scans == 0) {
550                         /* Nothing left to put in the FIFO. */
551                         dev_err(dev->class_dev, "AO buffer underrun\n");
552                         s->async->events |= COMEDI_CB_OVERFLOW;
553                 }
554         }
555         /* Determine how many new scans can be put in the FIFO. */
556         room /= cmd->chanlist_len;
557
558         /* Determine how many scans to process. */
559         if (num_scans > room)
560                 num_scans = room;
561
562         /* Process scans. */
563         for (n = 0; n < num_scans; n++) {
564                 comedi_buf_read_samples(s, &devpriv->ao_scan_vals[0],
565                                         cmd->chanlist_len);
566                 for (i = 0; i < cmd->chanlist_len; i++) {
567                         outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
568                              dev->iobase + PCI224_DACDATA);
569                 }
570         }
571         if (cmd->stop_src == TRIG_COUNT &&
572             s->async->scans_done >= cmd->stop_arg) {
573                 /*
574                  * Change FIFO interrupt trigger level to wait
575                  * until FIFO is empty.
576                  */
577                 devpriv->daccon = COMBINE(devpriv->daccon,
578                                           PCI224_DACCON_FIFOINTR_EMPTY,
579                                           PCI224_DACCON_FIFOINTR_MASK);
580                 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
581         }
582         if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
583             PCI224_DACCON_TRIG_NONE) {
584                 unsigned short trig;
585
586                 /*
587                  * This is the initial DAC FIFO interrupt at the
588                  * start of the acquisition.  The DAC's scan trigger
589                  * has been set to 'none' up until now.
590                  *
591                  * Now that data has been written to the FIFO, the
592                  * DAC's scan trigger source can be set to the
593                  * correct value.
594                  *
595                  * BUG: The first scan will be triggered immediately
596                  * if the scan trigger source is at logic level 1.
597                  */
598                 if (cmd->scan_begin_src == TRIG_TIMER) {
599                         trig = PCI224_DACCON_TRIG_Z2CT0;
600                 } else {
601                         /* cmd->scan_begin_src == TRIG_EXT */
602                         if (cmd->scan_begin_arg & CR_INVERT)
603                                 trig = PCI224_DACCON_TRIG_EXTN;
604                         else
605                                 trig = PCI224_DACCON_TRIG_EXTP;
606                 }
607                 devpriv->daccon =
608                     COMBINE(devpriv->daccon, trig, PCI224_DACCON_TRIG_MASK);
609                 outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
610         }
611
612         comedi_handle_events(dev, s);
613 }
614
615 static int pci224_ao_inttrig_start(struct comedi_device *dev,
616                                    struct comedi_subdevice *s,
617                                    unsigned int trig_num)
618 {
619         struct comedi_cmd *cmd = &s->async->cmd;
620
621         if (trig_num != cmd->start_arg)
622                 return -EINVAL;
623
624         s->async->inttrig = NULL;
625         pci224_ao_start(dev, s);
626
627         return 1;
628 }
629
630 static int pci224_ao_check_chanlist(struct comedi_device *dev,
631                                     struct comedi_subdevice *s,
632                                     struct comedi_cmd *cmd)
633 {
634         const struct pci224_board *board = dev->board_ptr;
635         unsigned int range_check_0;
636         unsigned int chan_mask = 0;
637         int i;
638
639         range_check_0 = board->ao_range_check[CR_RANGE(cmd->chanlist[0])];
640         for (i = 0; i < cmd->chanlist_len; i++) {
641                 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
642
643                 if (chan_mask & (1 << chan)) {
644                         dev_dbg(dev->class_dev,
645                                 "%s: entries in chanlist must contain no duplicate channels\n",
646                                 __func__);
647                         return -EINVAL;
648                 }
649                 chan_mask |= 1 << chan;
650
651                 if (board->ao_range_check[CR_RANGE(cmd->chanlist[i])] !=
652                     range_check_0) {
653                         dev_dbg(dev->class_dev,
654                                 "%s: entries in chanlist have incompatible ranges\n",
655                                 __func__);
656                         return -EINVAL;
657                 }
658         }
659
660         return 0;
661 }
662
663 #define MAX_SCAN_PERIOD         0xFFFFFFFFU
664 #define MIN_SCAN_PERIOD         2500
665 #define CONVERT_PERIOD          625
666
667 /*
668  * 'do_cmdtest' function for AO subdevice.
669  */
670 static int
671 pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
672                   struct comedi_cmd *cmd)
673 {
674         int err = 0;
675         unsigned int arg;
676
677         /* Step 1 : check if triggers are trivially valid */
678
679         err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
680         err |= comedi_check_trigger_src(&cmd->scan_begin_src,
681                                         TRIG_EXT | TRIG_TIMER);
682         err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
683         err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
684         err |= comedi_check_trigger_src(&cmd->stop_src,
685                                         TRIG_COUNT | TRIG_EXT | TRIG_NONE);
686
687         if (err)
688                 return 1;
689
690         /* Step 2a : make sure trigger sources are unique */
691
692         err |= comedi_check_trigger_is_unique(cmd->start_src);
693         err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
694         err |= comedi_check_trigger_is_unique(cmd->stop_src);
695
696         /* Step 2b : and mutually compatible */
697
698         /*
699          * There's only one external trigger signal (which makes these
700          * tests easier).  Only one thing can use it.
701          */
702         arg = 0;
703         if (cmd->start_src & TRIG_EXT)
704                 arg++;
705         if (cmd->scan_begin_src & TRIG_EXT)
706                 arg++;
707         if (cmd->stop_src & TRIG_EXT)
708                 arg++;
709         if (arg > 1)
710                 err |= -EINVAL;
711
712         if (err)
713                 return 2;
714
715         /* Step 3: check if arguments are trivially valid */
716
717         switch (cmd->start_src) {
718         case TRIG_INT:
719                 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
720                 break;
721         case TRIG_EXT:
722                 /* Force to external trigger 0. */
723                 if (cmd->start_arg & ~CR_FLAGS_MASK) {
724                         cmd->start_arg =
725                             COMBINE(cmd->start_arg, 0, ~CR_FLAGS_MASK);
726                         err |= -EINVAL;
727                 }
728                 /* The only flag allowed is CR_EDGE, which is ignored. */
729                 if (cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) {
730                         cmd->start_arg = COMBINE(cmd->start_arg, 0,
731                                                  CR_FLAGS_MASK & ~CR_EDGE);
732                         err |= -EINVAL;
733                 }
734                 break;
735         }
736
737         switch (cmd->scan_begin_src) {
738         case TRIG_TIMER:
739                 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
740                                                     MAX_SCAN_PERIOD);
741
742                 arg = cmd->chanlist_len * CONVERT_PERIOD;
743                 if (arg < MIN_SCAN_PERIOD)
744                         arg = MIN_SCAN_PERIOD;
745                 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
746                 break;
747         case TRIG_EXT:
748                 /* Force to external trigger 0. */
749                 if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) {
750                         cmd->scan_begin_arg =
751                             COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK);
752                         err |= -EINVAL;
753                 }
754                 /* Only allow flags CR_EDGE and CR_INVERT.  Ignore CR_EDGE. */
755                 if (cmd->scan_begin_arg & CR_FLAGS_MASK &
756                     ~(CR_EDGE | CR_INVERT)) {
757                         cmd->scan_begin_arg =
758                             COMBINE(cmd->scan_begin_arg, 0,
759                                     CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
760                         err |= -EINVAL;
761                 }
762                 break;
763         }
764
765         err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
766         err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
767                                            cmd->chanlist_len);
768
769         switch (cmd->stop_src) {
770         case TRIG_COUNT:
771                 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
772                 break;
773         case TRIG_EXT:
774                 /* Force to external trigger 0. */
775                 if (cmd->stop_arg & ~CR_FLAGS_MASK) {
776                         cmd->stop_arg =
777                             COMBINE(cmd->stop_arg, 0, ~CR_FLAGS_MASK);
778                         err |= -EINVAL;
779                 }
780                 /* The only flag allowed is CR_EDGE, which is ignored. */
781                 if (cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) {
782                         cmd->stop_arg =
783                             COMBINE(cmd->stop_arg, 0, CR_FLAGS_MASK & ~CR_EDGE);
784                 }
785                 break;
786         case TRIG_NONE:
787                 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
788                 break;
789         }
790
791         if (err)
792                 return 3;
793
794         /* Step 4: fix up any arguments. */
795
796         if (cmd->scan_begin_src == TRIG_TIMER) {
797                 arg = cmd->scan_begin_arg;
798                 /* Use two timers. */
799                 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
800                 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
801         }
802
803         if (err)
804                 return 4;
805
806         /* Step 5: check channel list if it exists */
807         if (cmd->chanlist && cmd->chanlist_len > 0)
808                 err |= pci224_ao_check_chanlist(dev, s, cmd);
809
810         if (err)
811                 return 5;
812
813         return 0;
814 }
815
816 static void pci224_ao_start_pacer(struct comedi_device *dev,
817                                   struct comedi_subdevice *s)
818 {
819         struct pci224_private *devpriv = dev->private;
820
821         /*
822          * The output of timer Z2-0 will be used as the scan trigger
823          * source.
824          */
825         /* Make sure Z2-0 is gated on.  */
826         outb(pci224_gat_config(0, GAT_VCC), devpriv->iobase1 + PCI224_ZGAT_SCE);
827         /* Cascading with Z2-2. */
828         /* Make sure Z2-2 is gated on.  */
829         outb(pci224_gat_config(2, GAT_VCC), devpriv->iobase1 + PCI224_ZGAT_SCE);
830         /* Z2-2 needs 10 MHz clock. */
831         outb(pci224_clk_config(2, CLK_10MHZ),
832              devpriv->iobase1 + PCI224_ZCLK_SCE);
833         /* Z2-0 is clocked from Z2-2's output. */
834         outb(pci224_clk_config(0, CLK_OUTNM1),
835              devpriv->iobase1 + PCI224_ZCLK_SCE);
836
837         comedi_8254_pacer_enable(dev->pacer, 2, 0, false);
838 }
839
840 static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
841 {
842         const struct pci224_board *board = dev->board_ptr;
843         struct pci224_private *devpriv = dev->private;
844         struct comedi_cmd *cmd = &s->async->cmd;
845         int range;
846         unsigned int i, j;
847         unsigned int ch;
848         unsigned int rank;
849         unsigned long flags;
850
851         /* Cannot handle null/empty chanlist. */
852         if (!cmd->chanlist || cmd->chanlist_len == 0)
853                 return -EINVAL;
854
855         /* Determine which channels are enabled and their load order.  */
856         devpriv->ao_enab = 0;
857
858         for (i = 0; i < cmd->chanlist_len; i++) {
859                 ch = CR_CHAN(cmd->chanlist[i]);
860                 devpriv->ao_enab |= 1U << ch;
861                 rank = 0;
862                 for (j = 0; j < cmd->chanlist_len; j++) {
863                         if (CR_CHAN(cmd->chanlist[j]) < ch)
864                                 rank++;
865                 }
866                 devpriv->ao_scan_order[rank] = i;
867         }
868
869         /* Set enabled channels. */
870         outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
871
872         /* Determine range and polarity.  All channels the same.  */
873         range = CR_RANGE(cmd->chanlist[0]);
874
875         /*
876          * Set DAC range and polarity.
877          * Set DAC scan trigger source to 'none'.
878          * Set DAC FIFO interrupt trigger level to 'not half full'.
879          * Reset DAC FIFO.
880          *
881          * N.B. DAC FIFO interrupts are currently disabled.
882          */
883         devpriv->daccon =
884             COMBINE(devpriv->daccon,
885                     board->ao_hwrange[range] | PCI224_DACCON_TRIG_NONE |
886                     PCI224_DACCON_FIFOINTR_NHALF,
887                     PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK |
888                     PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
889         outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
890              dev->iobase + PCI224_DACCON);
891
892         if (cmd->scan_begin_src == TRIG_TIMER) {
893                 comedi_8254_update_divisors(dev->pacer);
894                 pci224_ao_start_pacer(dev, s);
895         }
896
897         spin_lock_irqsave(&devpriv->ao_spinlock, flags);
898         if (cmd->start_src == TRIG_INT) {
899                 s->async->inttrig = pci224_ao_inttrig_start;
900         } else {        /* TRIG_EXT */
901                 /* Enable external interrupt trigger to start acquisition. */
902                 devpriv->intsce |= PCI224_INTR_EXT;
903                 outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
904         }
905         spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
906
907         return 0;
908 }
909
910 /*
911  * 'cancel' function for AO subdevice.
912  */
913 static int pci224_ao_cancel(struct comedi_device *dev,
914                             struct comedi_subdevice *s)
915 {
916         pci224_ao_stop(dev, s);
917         return 0;
918 }
919
920 /*
921  * 'munge' data for AO command.
922  */
923 static void
924 pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
925                 void *data, unsigned int num_bytes, unsigned int chan_index)
926 {
927         const struct pci224_board *board = dev->board_ptr;
928         struct comedi_cmd *cmd = &s->async->cmd;
929         unsigned short *array = data;
930         unsigned int length = num_bytes / sizeof(*array);
931         unsigned int offset;
932         unsigned int shift;
933         unsigned int i;
934
935         /* The hardware expects 16-bit numbers. */
936         shift = 16 - board->ao_bits;
937         /* Channels will be all bipolar or all unipolar. */
938         if ((board->ao_hwrange[CR_RANGE(cmd->chanlist[0])] &
939              PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
940                 /* Unipolar */
941                 offset = 0;
942         } else {
943                 /* Bipolar */
944                 offset = 32768;
945         }
946         /* Munge the data. */
947         for (i = 0; i < length; i++)
948                 array[i] = (array[i] << shift) - offset;
949 }
950
951 /*
952  * Interrupt handler.
953  */
954 static irqreturn_t pci224_interrupt(int irq, void *d)
955 {
956         struct comedi_device *dev = d;
957         struct pci224_private *devpriv = dev->private;
958         struct comedi_subdevice *s = dev->write_subdev;
959         struct comedi_cmd *cmd;
960         unsigned char intstat, valid_intstat;
961         unsigned char curenab;
962         int retval = 0;
963         unsigned long flags;
964
965         intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
966         if (intstat) {
967                 retval = 1;
968                 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
969                 valid_intstat = devpriv->intsce & intstat;
970                 /* Temporarily disable interrupt sources. */
971                 curenab = devpriv->intsce & ~intstat;
972                 outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
973                 devpriv->intr_running = 1;
974                 devpriv->intr_cpuid = THISCPU;
975                 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
976                 if (valid_intstat) {
977                         cmd = &s->async->cmd;
978                         if (valid_intstat & PCI224_INTR_EXT) {
979                                 devpriv->intsce &= ~PCI224_INTR_EXT;
980                                 if (cmd->start_src == TRIG_EXT)
981                                         pci224_ao_start(dev, s);
982                                 else if (cmd->stop_src == TRIG_EXT)
983                                         pci224_ao_stop(dev, s);
984                         }
985                         if (valid_intstat & PCI224_INTR_DAC)
986                                 pci224_ao_handle_fifo(dev, s);
987                 }
988                 /* Reenable interrupt sources. */
989                 spin_lock_irqsave(&devpriv->ao_spinlock, flags);
990                 if (curenab != devpriv->intsce) {
991                         outb(devpriv->intsce,
992                              devpriv->iobase1 + PCI224_INT_SCE);
993                 }
994                 devpriv->intr_running = 0;
995                 spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
996         }
997         return IRQ_RETVAL(retval);
998 }
999
1000 static int
1001 pci224_auto_attach(struct comedi_device *dev, unsigned long context_model)
1002 {
1003         struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
1004         const struct pci224_board *board = NULL;
1005         struct pci224_private *devpriv;
1006         struct comedi_subdevice *s;
1007         unsigned int irq;
1008         int ret;
1009
1010         if (context_model < ARRAY_SIZE(pci224_boards))
1011                 board = &pci224_boards[context_model];
1012         if (!board || !board->name) {
1013                 dev_err(dev->class_dev,
1014                         "amplc_pci224: BUG! cannot determine board type!\n");
1015                 return -EINVAL;
1016         }
1017         dev->board_ptr = board;
1018         dev->board_name = board->name;
1019
1020         dev_info(dev->class_dev, "amplc_pci224: attach pci %s - %s\n",
1021                  pci_name(pci_dev), dev->board_name);
1022
1023         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1024         if (!devpriv)
1025                 return -ENOMEM;
1026
1027         ret = comedi_pci_enable(dev);
1028         if (ret)
1029                 return ret;
1030
1031         spin_lock_init(&devpriv->ao_spinlock);
1032
1033         devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1034         dev->iobase = pci_resource_start(pci_dev, 3);
1035         irq = pci_dev->irq;
1036
1037         /* Allocate buffer to hold values for AO channel scan. */
1038         devpriv->ao_scan_vals = kmalloc_array(board->ao_chans,
1039                                               sizeof(devpriv->ao_scan_vals[0]),
1040                                               GFP_KERNEL);
1041         if (!devpriv->ao_scan_vals)
1042                 return -ENOMEM;
1043
1044         /* Allocate buffer to hold AO channel scan order. */
1045         devpriv->ao_scan_order =
1046                                 kmalloc_array(board->ao_chans,
1047                                               sizeof(devpriv->ao_scan_order[0]),
1048                                               GFP_KERNEL);
1049         if (!devpriv->ao_scan_order)
1050                 return -ENOMEM;
1051
1052         /* Disable interrupt sources. */
1053         devpriv->intsce = 0;
1054         outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1055
1056         /* Initialize the DAC hardware. */
1057         outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1058         outw(0, dev->iobase + PCI224_DACCEN);
1059         outw(0, dev->iobase + PCI224_FIFOSIZ);
1060         devpriv->daccon = PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1061                           PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY;
1062         outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1063              dev->iobase + PCI224_DACCON);
1064
1065         dev->pacer = comedi_8254_init(devpriv->iobase1 + PCI224_Z2_BASE,
1066                                       I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
1067         if (!dev->pacer)
1068                 return -ENOMEM;
1069
1070         ret = comedi_alloc_subdevices(dev, 1);
1071         if (ret)
1072                 return ret;
1073
1074         s = &dev->subdevices[0];
1075         /* Analog output subdevice. */
1076         s->type = COMEDI_SUBD_AO;
1077         s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1078         s->n_chan = board->ao_chans;
1079         s->maxdata = (1 << board->ao_bits) - 1;
1080         s->range_table = board->ao_range;
1081         s->insn_write = pci224_ao_insn_write;
1082         s->len_chanlist = s->n_chan;
1083         dev->write_subdev = s;
1084         s->do_cmd = pci224_ao_cmd;
1085         s->do_cmdtest = pci224_ao_cmdtest;
1086         s->cancel = pci224_ao_cancel;
1087         s->munge = pci224_ao_munge;
1088
1089         ret = comedi_alloc_subdev_readback(s);
1090         if (ret)
1091                 return ret;
1092
1093         if (irq) {
1094                 ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1095                                   dev->board_name, dev);
1096                 if (ret < 0) {
1097                         dev_err(dev->class_dev,
1098                                 "error! unable to allocate irq %u\n", irq);
1099                         return ret;
1100                 }
1101                 dev->irq = irq;
1102         }
1103
1104         return 0;
1105 }
1106
1107 static void pci224_detach(struct comedi_device *dev)
1108 {
1109         struct pci224_private *devpriv = dev->private;
1110
1111         comedi_pci_detach(dev);
1112         if (devpriv) {
1113                 kfree(devpriv->ao_scan_vals);
1114                 kfree(devpriv->ao_scan_order);
1115         }
1116 }
1117
1118 static struct comedi_driver amplc_pci224_driver = {
1119         .driver_name    = "amplc_pci224",
1120         .module         = THIS_MODULE,
1121         .detach         = pci224_detach,
1122         .auto_attach    = pci224_auto_attach,
1123         .board_name     = &pci224_boards[0].name,
1124         .offset         = sizeof(struct pci224_board),
1125         .num_names      = ARRAY_SIZE(pci224_boards),
1126 };
1127
1128 static int amplc_pci224_pci_probe(struct pci_dev *dev,
1129                                   const struct pci_device_id *id)
1130 {
1131         return comedi_pci_auto_config(dev, &amplc_pci224_driver,
1132                                       id->driver_data);
1133 }
1134
1135 static const struct pci_device_id amplc_pci224_pci_table[] = {
1136         { PCI_VDEVICE(AMPLICON, 0x0007), pci224_model },
1137         { PCI_VDEVICE(AMPLICON, 0x0008), pci234_model },
1138         { 0 }
1139 };
1140 MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);
1141
1142 static struct pci_driver amplc_pci224_pci_driver = {
1143         .name           = "amplc_pci224",
1144         .id_table       = amplc_pci224_pci_table,
1145         .probe          = amplc_pci224_pci_probe,
1146         .remove         = comedi_pci_auto_unconfig,
1147 };
1148 module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
1149
1150 MODULE_AUTHOR("Comedi http://www.comedi.org");
1151 MODULE_DESCRIPTION("Comedi driver for Amplicon PCI224 and PCI234 AO boards");
1152 MODULE_LICENSE("GPL");