Version:  2.0.40 2.2.26 2.4.37 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us