]> Pileus Git - ~andy/linux/blob - drivers/staging/comedi/drivers/cb_pcidas.c
staging: comedi: cb_pcidas: remove forward declarations 1
[~andy/linux] / drivers / staging / comedi / drivers / cb_pcidas.c
1 /*
2     comedi/drivers/cb_pcidas.c
3
4     Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
5     David Schleef and the rest of the Comedi developers comunity.
6
7     Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
8     Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
9
10     COMEDI - Linux Control and Measurement Device Interface
11     Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
12
13     This program is free software; you can redistribute it and/or modify
14     it under the terms of the GNU General Public License as published by
15     the Free Software Foundation; either version 2 of the License, or
16     (at your option) any later version.
17
18     This program is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21     GNU General Public License for more details.
22
23     You should have received a copy of the GNU General Public License
24     along with this program; if not, write to the Free Software
25     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27 ************************************************************************
28 */
29 /*
30 Driver: cb_pcidas
31 Description: MeasurementComputing PCI-DAS series with the AMCC S5933 PCI controller
32 Author: Ivan Martinez <imr@oersted.dtu.dk>,
33   Frank Mori Hess <fmhess@users.sourceforge.net>
34 Updated: 2003-3-11
35 Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
36   PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
37   PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
38
39 Status:
40   There are many reports of the driver being used with most of the
41   supported cards. Despite no detailed log is maintained, it can
42   be said that the driver is quite tested and stable.
43
44   The boards may be autocalibrated using the comedi_calibrate
45   utility.
46
47 Configuration options:
48   [0] - PCI bus of device (optional)
49   [1] - PCI slot of device (optional)
50   If bus/slot is not specified, the first supported
51   PCI device found will be used.
52
53 For commands, the scanned channels must be consecutive
54 (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
55 range and aref.
56
57 AI Triggering:
58    For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used.
59    For 1602 series, the start_arg is interpreted as follows:
60      start_arg == 0                   => gated trigger (level high)
61      start_arg == CR_INVERT           => gated trigger (level low)
62      start_arg == CR_EDGE             => Rising edge
63      start_arg == CR_EDGE | CR_INVERT => Falling edge
64    For the other boards the trigger will be done on rising edge
65 */
66 /*
67
68 TODO:
69
70 analog triggering on 1602 series
71 */
72
73 #include "../comedidev.h"
74 #include <linux/delay.h>
75 #include <linux/interrupt.h>
76
77 #include "8253.h"
78 #include "8255.h"
79 #include "amcc_s5933.h"
80 #include "comedi_fc.h"
81
82 #undef CB_PCIDAS_DEBUG          /*  disable debugging code */
83 /* #define CB_PCIDAS_DEBUG         enable debugging code */
84
85 /* PCI vendor number of ComputerBoards/MeasurementComputing */
86 #define PCI_VENDOR_ID_CB        0x1307
87 #define TIMER_BASE 100          /*  10MHz master clock */
88 #define AI_BUFFER_SIZE 1024     /*  maximum fifo size of any supported board */
89 #define AO_BUFFER_SIZE 1024     /*  maximum fifo size of any supported board */
90 #define NUM_CHANNELS_8800 8
91 #define NUM_CHANNELS_7376 1
92 #define NUM_CHANNELS_8402 2
93 #define NUM_CHANNELS_DAC08 1
94
95 /* PCI-DAS base addresses */
96
97 /* indices of base address regions */
98 #define S5933_BADRINDEX 0
99 #define CONT_STAT_BADRINDEX 1
100 #define ADC_FIFO_BADRINDEX 2
101 #define PACER_BADRINDEX 3
102 #define AO_BADRINDEX 4
103 /* sizes of io regions */
104 #define CONT_STAT_SIZE 10
105 #define ADC_FIFO_SIZE 4
106 #define PACER_SIZE 12
107 #define AO_SIZE 4
108
109 /* Control/Status registers */
110 #define INT_ADCFIFO     0       /*  INTERRUPT / ADC FIFO register */
111 #define   INT_EOS 0x1           /*  interrupt end of scan */
112 #define   INT_FHF 0x2           /*  interrupt fifo half full */
113 #define   INT_FNE 0x3           /*  interrupt fifo not empty */
114 #define   INT_MASK 0x3          /*  mask of interrupt select bits */
115 #define   INTE 0x4              /*  interrupt enable */
116 #define   DAHFIE 0x8            /*  dac half full interrupt enable */
117 #define   EOAIE 0x10            /*  end of acquisition interrupt enable */
118 #define   DAHFI 0x20            /*  dac half full read status / write interrupt clear */
119 #define   EOAI 0x40             /*  read end of acq. interrupt status / write clear */
120 #define   INT 0x80              /*  read interrupt status / write clear */
121 #define   EOBI 0x200            /*  read end of burst interrupt status */
122 #define   ADHFI 0x400           /*  read half-full interrupt status */
123 #define   ADNEI 0x800           /*  read fifo not empty interrupt latch status */
124 #define   ADNE 0x1000           /*  read, fifo not empty (realtime, not latched) status */
125 #define   DAEMIE        0x1000  /*  write, dac empty interrupt enable */
126 #define   LADFUL 0x2000         /*  read fifo overflow / write clear */
127 #define   DAEMI 0x4000          /*  dac fifo empty interrupt status / write clear */
128
129 #define ADCMUX_CONT     2       /*  ADC CHANNEL MUX AND CONTROL register */
130 #define   BEGIN_SCAN(x) ((x) & 0xf)
131 #define   END_SCAN(x)   (((x) & 0xf) << 4)
132 #define   GAIN_BITS(x)  (((x) & 0x3) << 8)
133 #define   UNIP  0x800           /*  Analog front-end unipolar for range */
134 #define   SE    0x400           /*  Inputs in single-ended mode */
135 #define   PACER_MASK    0x3000  /*  pacer source bits */
136 #define   PACER_INT 0x1000      /*  internal pacer */
137 #define   PACER_EXT_FALL        0x2000  /*  external falling edge */
138 #define   PACER_EXT_RISE        0x3000  /*  external rising edge */
139 #define   EOC   0x4000          /*  adc not busy */
140
141 #define TRIG_CONTSTAT 4         /*  TRIGGER CONTROL/STATUS register */
142 #define   SW_TRIGGER 0x1        /*  software start trigger */
143 #define   EXT_TRIGGER 0x2       /*  external start trigger */
144 #define   ANALOG_TRIGGER 0x3    /*  external analog trigger */
145 #define   TRIGGER_MASK  0x3     /*  mask of bits that determine start trigger */
146 #define   TGPOL 0x04            /*  invert the edge/level of the external trigger (1602 only) */
147 #define   TGSEL 0x08            /*  if set edge triggered, otherwise level trigerred (1602 only) */
148 #define   TGEN  0x10            /*  enable external start trigger */
149 #define   BURSTE 0x20           /*  burst mode enable */
150 #define   XTRCL 0x80            /*  clear external trigger */
151
152 #define CALIBRATION_REG 6       /*  CALIBRATION register */
153 #define   SELECT_8800_BIT       0x100   /*  select 8800 caldac */
154 #define   SELECT_TRIMPOT_BIT    0x200   /*  select ad7376 trim pot */
155 #define   SELECT_DAC08_BIT      0x400   /*  select dac08 caldac */
156 #define   CAL_SRC_BITS(x)       (((x) & 0x7) << 11)
157 #define   CAL_EN_BIT    0x4000  /*  read calibration source instead of analog input channel 0 */
158 #define   SERIAL_DATA_IN_BIT    0x8000  /*  serial data stream going to 8800 and 7376 */
159
160 #define DAC_CSR 0x8             /*  dac control and status register */
161 enum dac_csr_bits {
162         DACEN = 0x2,            /*  dac enable */
163         DAC_MODE_UPDATE_BOTH = 0x80,    /*  update both dacs when dac0 is written */
164 };
165 static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
166 {
167         return (range & 0x3) << (8 + 2 * (channel & 0x1));
168 }
169
170 static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
171 {
172         return 0x3 << (8 + 2 * (channel & 0x1));
173 };
174
175 /* bits for 1602 series only */
176 enum dac_csr_bits_1602 {
177         DAC_EMPTY = 0x1,        /*  dac fifo empty, read, write clear */
178         DAC_START = 0x4,        /*  start/arm dac fifo operations */
179         DAC_PACER_MASK = 0x18,  /*  bits that set dac pacer source */
180         DAC_PACER_INT = 0x8,    /*  dac internal pacing */
181         DAC_PACER_EXT_FALL = 0x10,      /*  dac external pacing, falling edge */
182         DAC_PACER_EXT_RISE = 0x18,      /*  dac external pacing, rising edge */
183 };
184 static inline unsigned int DAC_CHAN_EN(unsigned int channel)
185 {
186         return 1 << (5 + (channel & 0x1));      /*  enable channel 0 or 1 */
187 };
188
189 /* analog input fifo */
190 #define ADCDATA 0               /*  ADC DATA register */
191 #define ADCFIFOCLR      2       /*  ADC FIFO CLEAR */
192
193 /* pacer, counter, dio registers */
194 #define ADC8254 0
195 #define DIO_8255 4
196 #define DAC8254 8
197
198 /* analog output registers for 100x, 1200 series */
199 static inline unsigned int DAC_DATA_REG(unsigned int channel)
200 {
201         return 2 * (channel & 0x1);
202 }
203
204 /* analog output registers for 1602 series*/
205 #define DACDATA 0               /*  DAC DATA register */
206 #define DACFIFOCLR      2       /*  DAC FIFO CLEAR */
207
208 /* bit in hexadecimal representation of range index that indicates unipolar input range */
209 #define IS_UNIPOLAR 0x4
210 /* analog input ranges for most boards */
211 static const struct comedi_lrange cb_pcidas_ranges = {
212         8,
213         {
214          BIP_RANGE(10),
215          BIP_RANGE(5),
216          BIP_RANGE(2.5),
217          BIP_RANGE(1.25),
218          UNI_RANGE(10),
219          UNI_RANGE(5),
220          UNI_RANGE(2.5),
221          UNI_RANGE(1.25)
222          }
223 };
224
225 /* pci-das1001 input ranges */
226 static const struct comedi_lrange cb_pcidas_alt_ranges = {
227         8,
228         {
229          BIP_RANGE(10),
230          BIP_RANGE(1),
231          BIP_RANGE(0.1),
232          BIP_RANGE(0.01),
233          UNI_RANGE(10),
234          UNI_RANGE(1),
235          UNI_RANGE(0.1),
236          UNI_RANGE(0.01)
237          }
238 };
239
240 /* analog output ranges */
241 static const struct comedi_lrange cb_pcidas_ao_ranges = {
242         4,
243         {
244          BIP_RANGE(5),
245          BIP_RANGE(10),
246          UNI_RANGE(5),
247          UNI_RANGE(10),
248          }
249 };
250
251 enum trimpot_model {
252         AD7376,
253         AD8402,
254 };
255
256 struct cb_pcidas_board {
257         const char *name;
258         unsigned short device_id;
259         int ai_se_chans;        /*  Inputs in single-ended mode */
260         int ai_diff_chans;      /*  Inputs in differential mode */
261         int ai_bits;            /*  analog input resolution */
262         int ai_speed;           /*  fastest conversion period in ns */
263         int ao_nchan;           /*  number of analog out channels */
264         int has_ao_fifo;        /*  analog output has fifo */
265         int ao_scan_speed;      /*  analog output speed for 1602 series (for a scan, not conversion) */
266         int fifo_size;          /*  number of samples fifo can hold */
267         const struct comedi_lrange *ranges;
268         enum trimpot_model trimpot;
269         unsigned has_dac08:1;
270         unsigned has_ai_trig_gated:1;   /* Tells if the AI trigger can be gated */
271         unsigned has_ai_trig_invert:1;  /* Tells if the AI trigger can be inverted */
272 };
273
274 static const struct cb_pcidas_board cb_pcidas_boards[] = {
275         {
276          .name = "pci-das1602/16",
277          .device_id = 0x1,
278          .ai_se_chans = 16,
279          .ai_diff_chans = 8,
280          .ai_bits = 16,
281          .ai_speed = 5000,
282          .ao_nchan = 2,
283          .has_ao_fifo = 1,
284          .ao_scan_speed = 10000,
285          .fifo_size = 512,
286          .ranges = &cb_pcidas_ranges,
287          .trimpot = AD8402,
288          .has_dac08 = 1,
289          .has_ai_trig_gated = 1,
290          .has_ai_trig_invert = 1,
291          },
292         {
293          .name = "pci-das1200",
294          .device_id = 0xF,
295          .ai_se_chans = 16,
296          .ai_diff_chans = 8,
297          .ai_bits = 12,
298          .ai_speed = 3200,
299          .ao_nchan = 2,
300          .has_ao_fifo = 0,
301          .fifo_size = 1024,
302          .ranges = &cb_pcidas_ranges,
303          .trimpot = AD7376,
304          .has_dac08 = 0,
305          .has_ai_trig_gated = 0,
306          .has_ai_trig_invert = 0,
307          },
308         {
309          .name = "pci-das1602/12",
310          .device_id = 0x10,
311          .ai_se_chans = 16,
312          .ai_diff_chans = 8,
313          .ai_bits = 12,
314          .ai_speed = 3200,
315          .ao_nchan = 2,
316          .has_ao_fifo = 1,
317          .ao_scan_speed = 4000,
318          .fifo_size = 1024,
319          .ranges = &cb_pcidas_ranges,
320          .trimpot = AD7376,
321          .has_dac08 = 0,
322          .has_ai_trig_gated = 1,
323          .has_ai_trig_invert = 1,
324          },
325         {
326          .name = "pci-das1200/jr",
327          .device_id = 0x19,
328          .ai_se_chans = 16,
329          .ai_diff_chans = 8,
330          .ai_bits = 12,
331          .ai_speed = 3200,
332          .ao_nchan = 0,
333          .has_ao_fifo = 0,
334          .fifo_size = 1024,
335          .ranges = &cb_pcidas_ranges,
336          .trimpot = AD7376,
337          .has_dac08 = 0,
338          .has_ai_trig_gated = 0,
339          .has_ai_trig_invert = 0,
340          },
341         {
342          .name = "pci-das1602/16/jr",
343          .device_id = 0x1C,
344          .ai_se_chans = 16,
345          .ai_diff_chans = 8,
346          .ai_bits = 16,
347          .ai_speed = 5000,
348          .ao_nchan = 0,
349          .has_ao_fifo = 0,
350          .fifo_size = 512,
351          .ranges = &cb_pcidas_ranges,
352          .trimpot = AD8402,
353          .has_dac08 = 1,
354          .has_ai_trig_gated = 1,
355          .has_ai_trig_invert = 1,
356          },
357         {
358          .name = "pci-das1000",
359          .device_id = 0x4C,
360          .ai_se_chans = 16,
361          .ai_diff_chans = 8,
362          .ai_bits = 12,
363          .ai_speed = 4000,
364          .ao_nchan = 0,
365          .has_ao_fifo = 0,
366          .fifo_size = 1024,
367          .ranges = &cb_pcidas_ranges,
368          .trimpot = AD7376,
369          .has_dac08 = 0,
370          .has_ai_trig_gated = 0,
371          .has_ai_trig_invert = 0,
372          },
373         {
374          .name = "pci-das1001",
375          .device_id = 0x1a,
376          .ai_se_chans = 16,
377          .ai_diff_chans = 8,
378          .ai_bits = 12,
379          .ai_speed = 6800,
380          .ao_nchan = 2,
381          .has_ao_fifo = 0,
382          .fifo_size = 1024,
383          .ranges = &cb_pcidas_alt_ranges,
384          .trimpot = AD7376,
385          .has_dac08 = 0,
386          .has_ai_trig_gated = 0,
387          .has_ai_trig_invert = 0,
388          },
389         {
390          .name = "pci-das1002",
391          .device_id = 0x1b,
392          .ai_se_chans = 16,
393          .ai_diff_chans = 8,
394          .ai_bits = 12,
395          .ai_speed = 6800,
396          .ao_nchan = 2,
397          .has_ao_fifo = 0,
398          .fifo_size = 1024,
399          .ranges = &cb_pcidas_ranges,
400          .trimpot = AD7376,
401          .has_dac08 = 0,
402          .has_ai_trig_gated = 0,
403          .has_ai_trig_invert = 0,
404          },
405 };
406
407 /*
408  * Useful for shorthand access to the particular board structure
409  */
410 #define thisboard ((const struct cb_pcidas_board *)dev->board_ptr)
411
412 /* this structure is for data unique to this hardware driver.  If
413    several hardware drivers keep similar information in this structure,
414    feel free to suggest moving the variable to the struct comedi_device struct.  */
415 struct cb_pcidas_private {
416         /* would be useful for a PCI device */
417         struct pci_dev *pci_dev;
418         /*  base addresses */
419         unsigned long s5933_config;
420         unsigned long control_status;
421         unsigned long adc_fifo;
422         unsigned long pacer_counter_dio;
423         unsigned long ao_registers;
424         /*  divisors of master clock for analog input pacing */
425         unsigned int divisor1;
426         unsigned int divisor2;
427         volatile unsigned int count;    /*  number of analog input samples remaining */
428         volatile unsigned int adc_fifo_bits;    /*  bits to write to interrupt/adcfifo register */
429         volatile unsigned int s5933_intcsr_bits;        /*  bits to write to amcc s5933 interrupt control/status register */
430         volatile unsigned int ao_control_bits;  /*  bits to write to ao control and status register */
431         short ai_buffer[AI_BUFFER_SIZE];
432         short ao_buffer[AO_BUFFER_SIZE];
433         /*  divisors of master clock for analog output pacing */
434         unsigned int ao_divisor1;
435         unsigned int ao_divisor2;
436         volatile unsigned int ao_count; /*  number of analog output samples remaining */
437         int ao_value[2];        /*  remember what the analog outputs are set to, to allow readback */
438         unsigned int caldac_value[NUM_CHANNELS_8800];   /*  for readback of caldac */
439         unsigned int trimpot_value[NUM_CHANNELS_8402];  /*  for readback of trimpot */
440         unsigned int dac08_value;
441         unsigned int calibration_source;
442 };
443
444 /*
445  * most drivers define the following macro to make it easy to
446  * access the private structure.
447  */
448 #define devpriv ((struct cb_pcidas_private *)dev->private)
449
450 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
451                                 struct comedi_subdevice *subdev,
452                                 unsigned int trig_num);
453 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status);
454 static int cb_pcidas_cancel(struct comedi_device *dev,
455                             struct comedi_subdevice *s);
456 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
457                                struct comedi_subdevice *s);
458 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
459                                     int round_flags);
460 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
461                              uint8_t value);
462 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value);
463 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
464                               uint8_t value);
465 static int nvram_read(struct comedi_device *dev, unsigned int address,
466                       uint8_t *data);
467
468 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
469 {
470         return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
471 }
472
473 /*
474  * "instructions" read/write data in "one-shot" or "software-triggered"
475  * mode.
476  */
477 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
478                               struct comedi_subdevice *s,
479                               struct comedi_insn *insn, unsigned int *data)
480 {
481         int n, i;
482         unsigned int bits;
483         static const int timeout = 10000;
484         int channel;
485         /*  enable calibration input if appropriate */
486         if (insn->chanspec & CR_ALT_SOURCE) {
487                 outw(cal_enable_bits(dev),
488                      devpriv->control_status + CALIBRATION_REG);
489                 channel = 0;
490         } else {
491                 outw(0, devpriv->control_status + CALIBRATION_REG);
492                 channel = CR_CHAN(insn->chanspec);
493         }
494         /*  set mux limits and gain */
495         bits = BEGIN_SCAN(channel) |
496             END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec));
497         /*  set unipolar/bipolar */
498         if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR)
499                 bits |= UNIP;
500         /*  set singleended/differential */
501         if (CR_AREF(insn->chanspec) != AREF_DIFF)
502                 bits |= SE;
503         outw(bits, devpriv->control_status + ADCMUX_CONT);
504
505         /* clear fifo */
506         outw(0, devpriv->adc_fifo + ADCFIFOCLR);
507
508         /* convert n samples */
509         for (n = 0; n < insn->n; n++) {
510                 /* trigger conversion */
511                 outw(0, devpriv->adc_fifo + ADCDATA);
512
513                 /* wait for conversion to end */
514                 /* return -ETIMEDOUT if there is a timeout */
515                 for (i = 0; i < timeout; i++) {
516                         if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
517                                 break;
518                 }
519                 if (i == timeout)
520                         return -ETIMEDOUT;
521
522                 /* read data */
523                 data[n] = inw(devpriv->adc_fifo + ADCDATA);
524         }
525
526         /* return the number of samples read/written */
527         return n;
528 }
529
530 static int ai_config_calibration_source(struct comedi_device *dev,
531                                         unsigned int *data)
532 {
533         static const int num_calibration_sources = 8;
534         unsigned int source = data[1];
535
536         if (source >= num_calibration_sources) {
537                 dev_err(dev->class_dev, "invalid calibration source: %i\n",
538                         source);
539                 return -EINVAL;
540         }
541
542         devpriv->calibration_source = source;
543
544         return 2;
545 }
546
547 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
548                           struct comedi_insn *insn, unsigned int *data)
549 {
550         int id = data[0];
551
552         switch (id) {
553         case INSN_CONFIG_ALT_SOURCE:
554                 return ai_config_calibration_source(dev, data);
555                 break;
556         default:
557                 return -EINVAL;
558                 break;
559         }
560         return -EINVAL;
561 }
562
563 /* analog output insn for pcidas-1000 and 1200 series */
564 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
565                                      struct comedi_subdevice *s,
566                                      struct comedi_insn *insn,
567                                      unsigned int *data)
568 {
569         int channel;
570         unsigned long flags;
571
572         /*  set channel and range */
573         channel = CR_CHAN(insn->chanspec);
574         spin_lock_irqsave(&dev->spinlock, flags);
575         devpriv->ao_control_bits &=
576             ~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel);
577         devpriv->ao_control_bits |=
578             DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec));
579         outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
580         spin_unlock_irqrestore(&dev->spinlock, flags);
581
582         /*  remember value for readback */
583         devpriv->ao_value[channel] = data[0];
584         /*  send data */
585         outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel));
586
587         return 1;
588 }
589
590 /* analog output insn for pcidas-1602 series */
591 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
592                                    struct comedi_subdevice *s,
593                                    struct comedi_insn *insn, unsigned int *data)
594 {
595         int channel;
596         unsigned long flags;
597
598         /*  clear dac fifo */
599         outw(0, devpriv->ao_registers + DACFIFOCLR);
600
601         /*  set channel and range */
602         channel = CR_CHAN(insn->chanspec);
603         spin_lock_irqsave(&dev->spinlock, flags);
604         devpriv->ao_control_bits &=
605             ~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) &
606             ~DAC_PACER_MASK;
607         devpriv->ao_control_bits |=
608             DACEN | DAC_RANGE(channel,
609                               CR_RANGE(insn->
610                                        chanspec)) | DAC_CHAN_EN(channel) |
611             DAC_START;
612         outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
613         spin_unlock_irqrestore(&dev->spinlock, flags);
614
615         /*  remember value for readback */
616         devpriv->ao_value[channel] = data[0];
617         /*  send data */
618         outw(data[0], devpriv->ao_registers + DACDATA);
619
620         return 1;
621 }
622
623 /* analog output readback insn */
624 /* XXX loses track of analog output value back after an analog ouput command is executed */
625 static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
626                                       struct comedi_subdevice *s,
627                                       struct comedi_insn *insn,
628                                       unsigned int *data)
629 {
630         data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
631
632         return 1;
633 }
634
635 static int eeprom_read_insn(struct comedi_device *dev,
636                             struct comedi_subdevice *s,
637                             struct comedi_insn *insn, unsigned int *data)
638 {
639         uint8_t nvram_data;
640         int retval;
641
642         retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
643         if (retval < 0)
644                 return retval;
645
646         data[0] = nvram_data;
647
648         return 1;
649 }
650
651 static int caldac_write_insn(struct comedi_device *dev,
652                              struct comedi_subdevice *s,
653                              struct comedi_insn *insn, unsigned int *data)
654 {
655         const unsigned int channel = CR_CHAN(insn->chanspec);
656
657         return caldac_8800_write(dev, channel, data[0]);
658 }
659
660 static int caldac_read_insn(struct comedi_device *dev,
661                             struct comedi_subdevice *s,
662                             struct comedi_insn *insn, unsigned int *data)
663 {
664         data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
665
666         return 1;
667 }
668
669 /* 1602/16 pregain offset */
670 static int dac08_write(struct comedi_device *dev, unsigned int value)
671 {
672         if (devpriv->dac08_value == value)
673                 return 1;
674
675         devpriv->dac08_value = value;
676
677         outw(cal_enable_bits(dev) | (value & 0xff),
678              devpriv->control_status + CALIBRATION_REG);
679         udelay(1);
680         outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff),
681              devpriv->control_status + CALIBRATION_REG);
682         udelay(1);
683         outw(cal_enable_bits(dev) | (value & 0xff),
684              devpriv->control_status + CALIBRATION_REG);
685         udelay(1);
686
687         return 1;
688 }
689
690 static int dac08_write_insn(struct comedi_device *dev,
691                             struct comedi_subdevice *s,
692                             struct comedi_insn *insn, unsigned int *data)
693 {
694         return dac08_write(dev, data[0]);
695 }
696
697 static int dac08_read_insn(struct comedi_device *dev,
698                            struct comedi_subdevice *s, struct comedi_insn *insn,
699                            unsigned int *data)
700 {
701         data[0] = devpriv->dac08_value;
702
703         return 1;
704 }
705
706 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
707                                    unsigned int channel, unsigned int value)
708 {
709         if (devpriv->trimpot_value[channel] == value)
710                 return 1;
711
712         devpriv->trimpot_value[channel] = value;
713         switch (thisboard->trimpot) {
714         case AD7376:
715                 trimpot_7376_write(dev, value);
716                 break;
717         case AD8402:
718                 trimpot_8402_write(dev, channel, value);
719                 break;
720         default:
721                 comedi_error(dev, "driver bug?");
722                 return -1;
723                 break;
724         }
725
726         return 1;
727 }
728
729 static int trimpot_write_insn(struct comedi_device *dev,
730                               struct comedi_subdevice *s,
731                               struct comedi_insn *insn, unsigned int *data)
732 {
733         unsigned int channel = CR_CHAN(insn->chanspec);
734
735         return cb_pcidas_trimpot_write(dev, channel, data[0]);
736 }
737
738 static int trimpot_read_insn(struct comedi_device *dev,
739                              struct comedi_subdevice *s,
740                              struct comedi_insn *insn, unsigned int *data)
741 {
742         unsigned int channel = CR_CHAN(insn->chanspec);
743
744         data[0] = devpriv->trimpot_value[channel];
745
746         return 1;
747 }
748
749 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
750                                 struct comedi_subdevice *s,
751                                 struct comedi_cmd *cmd)
752 {
753         int err = 0;
754         int tmp;
755         int i, gain, start_chan;
756
757         /* cmdtest tests a particular command to see if it is valid.
758          * Using the cmdtest ioctl, a user can create a valid cmd
759          * and then have it executes by the cmd ioctl.
760          *
761          * cmdtest returns 1,2,3,4 or 0, depending on which tests
762          * the command passes. */
763
764         /* step 1: make sure trigger sources are trivially valid */
765
766         tmp = cmd->start_src;
767         cmd->start_src &= TRIG_NOW | TRIG_EXT;
768         if (!cmd->start_src || tmp != cmd->start_src)
769                 err++;
770
771         tmp = cmd->scan_begin_src;
772         cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
773         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
774                 err++;
775
776         tmp = cmd->convert_src;
777         cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT;
778         if (!cmd->convert_src || tmp != cmd->convert_src)
779                 err++;
780
781         tmp = cmd->scan_end_src;
782         cmd->scan_end_src &= TRIG_COUNT;
783         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
784                 err++;
785
786         tmp = cmd->stop_src;
787         cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
788         if (!cmd->stop_src || tmp != cmd->stop_src)
789                 err++;
790
791         if (err)
792                 return 1;
793
794         /* step 2: make sure trigger sources are unique and mutually compatible */
795
796         if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
797                 err++;
798         if (cmd->scan_begin_src != TRIG_FOLLOW &&
799             cmd->scan_begin_src != TRIG_TIMER &&
800             cmd->scan_begin_src != TRIG_EXT)
801                 err++;
802         if (cmd->convert_src != TRIG_TIMER &&
803             cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
804                 err++;
805         if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
806                 err++;
807
808         /*  make sure trigger sources are compatible with each other */
809         if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
810                 err++;
811         if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
812                 err++;
813         if (cmd->start_src == TRIG_EXT &&
814             (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
815                 err++;
816
817         if (err)
818                 return 2;
819
820         /* step 3: make sure arguments are trivially compatible */
821
822         switch (cmd->start_src) {
823         case TRIG_EXT:
824                 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
825                 if ((cmd->start_arg
826                      & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
827                         cmd->start_arg &=
828                             ~(CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
829                         err++;
830                 }
831                 if (!thisboard->has_ai_trig_invert &&
832                     (cmd->start_arg & CR_INVERT)) {
833                         cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
834                         err++;
835                 }
836                 break;
837         default:
838                 if (cmd->start_arg != 0) {
839                         cmd->start_arg = 0;
840                         err++;
841                 }
842                 break;
843         }
844
845         if (cmd->scan_begin_src == TRIG_TIMER) {
846                 if (cmd->scan_begin_arg <
847                     thisboard->ai_speed * cmd->chanlist_len) {
848                         cmd->scan_begin_arg =
849                             thisboard->ai_speed * cmd->chanlist_len;
850                         err++;
851                 }
852         }
853         if (cmd->convert_src == TRIG_TIMER) {
854                 if (cmd->convert_arg < thisboard->ai_speed) {
855                         cmd->convert_arg = thisboard->ai_speed;
856                         err++;
857                 }
858         }
859
860         if (cmd->scan_end_arg != cmd->chanlist_len) {
861                 cmd->scan_end_arg = cmd->chanlist_len;
862                 err++;
863         }
864         if (cmd->stop_src == TRIG_NONE) {
865                 /* TRIG_NONE */
866                 if (cmd->stop_arg != 0) {
867                         cmd->stop_arg = 0;
868                         err++;
869                 }
870         }
871
872         if (err)
873                 return 3;
874
875         /* step 4: fix up any arguments */
876
877         if (cmd->scan_begin_src == TRIG_TIMER) {
878                 tmp = cmd->scan_begin_arg;
879                 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
880                                                &(devpriv->divisor1),
881                                                &(devpriv->divisor2),
882                                                &(cmd->scan_begin_arg),
883                                                cmd->flags & TRIG_ROUND_MASK);
884                 if (tmp != cmd->scan_begin_arg)
885                         err++;
886         }
887         if (cmd->convert_src == TRIG_TIMER) {
888                 tmp = cmd->convert_arg;
889                 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
890                                                &(devpriv->divisor1),
891                                                &(devpriv->divisor2),
892                                                &(cmd->convert_arg),
893                                                cmd->flags & TRIG_ROUND_MASK);
894                 if (tmp != cmd->convert_arg)
895                         err++;
896         }
897
898         if (err)
899                 return 4;
900
901         /*  check channel/gain list against card's limitations */
902         if (cmd->chanlist) {
903                 gain = CR_RANGE(cmd->chanlist[0]);
904                 start_chan = CR_CHAN(cmd->chanlist[0]);
905                 for (i = 1; i < cmd->chanlist_len; i++) {
906                         if (CR_CHAN(cmd->chanlist[i]) !=
907                             (start_chan + i) % s->n_chan) {
908                                 comedi_error(dev,
909                                              "entries in chanlist must be consecutive channels, counting upwards\n");
910                                 err++;
911                         }
912                         if (CR_RANGE(cmd->chanlist[i]) != gain) {
913                                 comedi_error(dev,
914                                              "entries in chanlist must all have the same gain\n");
915                                 err++;
916                         }
917                 }
918         }
919
920         if (err)
921                 return 5;
922
923         return 0;
924 }
925
926 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
927                             struct comedi_subdevice *s)
928 {
929         struct comedi_async *async = s->async;
930         struct comedi_cmd *cmd = &async->cmd;
931         unsigned int bits;
932         unsigned long flags;
933
934         /*  make sure CAL_EN_BIT is disabled */
935         outw(0, devpriv->control_status + CALIBRATION_REG);
936         /*  initialize before settings pacer source and count values */
937         outw(0, devpriv->control_status + TRIG_CONTSTAT);
938         /*  clear fifo */
939         outw(0, devpriv->adc_fifo + ADCFIFOCLR);
940
941         /*  set mux limits, gain and pacer source */
942         bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
943             END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
944             GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
945         /*  set unipolar/bipolar */
946         if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
947                 bits |= UNIP;
948         /*  set singleended/differential */
949         if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
950                 bits |= SE;
951         /*  set pacer source */
952         if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
953                 bits |= PACER_EXT_RISE;
954         else
955                 bits |= PACER_INT;
956         outw(bits, devpriv->control_status + ADCMUX_CONT);
957
958 #ifdef CB_PCIDAS_DEBUG
959         dev_dbg(dev->class_dev, "sent 0x%x to adcmux control\n", bits);
960 #endif
961
962         /*  load counters */
963         if (cmd->convert_src == TRIG_TIMER)
964                 cb_pcidas_load_counters(dev, &cmd->convert_arg,
965                                         cmd->flags & TRIG_ROUND_MASK);
966         else if (cmd->scan_begin_src == TRIG_TIMER)
967                 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
968                                         cmd->flags & TRIG_ROUND_MASK);
969
970         /*  set number of conversions */
971         if (cmd->stop_src == TRIG_COUNT)
972                 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
973         /*  enable interrupts */
974         spin_lock_irqsave(&dev->spinlock, flags);
975         devpriv->adc_fifo_bits |= INTE;
976         devpriv->adc_fifo_bits &= ~INT_MASK;
977         if (cmd->flags & TRIG_WAKE_EOS) {
978                 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
979                         devpriv->adc_fifo_bits |= INT_EOS;      /*  interrupt end of burst */
980                 else
981                         devpriv->adc_fifo_bits |= INT_FNE;      /*  interrupt fifo not empty */
982         } else {
983                 devpriv->adc_fifo_bits |= INT_FHF;      /* interrupt fifo half full */
984         }
985 #ifdef CB_PCIDAS_DEBUG
986         dev_dbg(dev->class_dev, "adc_fifo_bits are 0x%x\n",
987                 devpriv->adc_fifo_bits);
988 #endif
989         /*  enable (and clear) interrupts */
990         outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
991              devpriv->control_status + INT_ADCFIFO);
992         spin_unlock_irqrestore(&dev->spinlock, flags);
993
994         /*  set start trigger and burst mode */
995         bits = 0;
996         if (cmd->start_src == TRIG_NOW)
997                 bits |= SW_TRIGGER;
998         else if (cmd->start_src == TRIG_EXT) {
999                 bits |= EXT_TRIGGER | TGEN | XTRCL;
1000                 if (thisboard->has_ai_trig_invert
1001                     && (cmd->start_arg & CR_INVERT))
1002                         bits |= TGPOL;
1003                 if (thisboard->has_ai_trig_gated && (cmd->start_arg & CR_EDGE))
1004                         bits |= TGSEL;
1005         } else {
1006                 comedi_error(dev, "bug!");
1007                 return -1;
1008         }
1009         if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1010                 bits |= BURSTE;
1011         outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1012 #ifdef CB_PCIDAS_DEBUG
1013         dev_dbg(dev->class_dev, "sent 0x%x to trig control\n", bits);
1014 #endif
1015
1016         return 0;
1017 }
1018
1019 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1020                                 struct comedi_subdevice *s,
1021                                 struct comedi_cmd *cmd)
1022 {
1023         int err = 0;
1024         int tmp;
1025
1026         /* cmdtest tests a particular command to see if it is valid.
1027          * Using the cmdtest ioctl, a user can create a valid cmd
1028          * and then have it executes by the cmd ioctl.
1029          *
1030          * cmdtest returns 1,2,3,4 or 0, depending on which tests
1031          * the command passes. */
1032
1033         /* step 1: make sure trigger sources are trivially valid */
1034
1035         tmp = cmd->start_src;
1036         cmd->start_src &= TRIG_INT;
1037         if (!cmd->start_src || tmp != cmd->start_src)
1038                 err++;
1039
1040         tmp = cmd->scan_begin_src;
1041         cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
1042         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1043                 err++;
1044
1045         tmp = cmd->convert_src;
1046         cmd->convert_src &= TRIG_NOW;
1047         if (!cmd->convert_src || tmp != cmd->convert_src)
1048                 err++;
1049
1050         tmp = cmd->scan_end_src;
1051         cmd->scan_end_src &= TRIG_COUNT;
1052         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1053                 err++;
1054
1055         tmp = cmd->stop_src;
1056         cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1057         if (!cmd->stop_src || tmp != cmd->stop_src)
1058                 err++;
1059
1060         if (err)
1061                 return 1;
1062
1063         /* step 2: make sure trigger sources are unique and mutually compatible */
1064
1065         if (cmd->scan_begin_src != TRIG_TIMER &&
1066             cmd->scan_begin_src != TRIG_EXT)
1067                 err++;
1068         if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1069                 err++;
1070
1071         if (err)
1072                 return 2;
1073
1074         /* step 3: make sure arguments are trivially compatible */
1075
1076         if (cmd->start_arg != 0) {
1077                 cmd->start_arg = 0;
1078                 err++;
1079         }
1080
1081         if (cmd->scan_begin_src == TRIG_TIMER) {
1082                 if (cmd->scan_begin_arg < thisboard->ao_scan_speed) {
1083                         cmd->scan_begin_arg = thisboard->ao_scan_speed;
1084                         err++;
1085                 }
1086         }
1087
1088         if (cmd->scan_end_arg != cmd->chanlist_len) {
1089                 cmd->scan_end_arg = cmd->chanlist_len;
1090                 err++;
1091         }
1092         if (cmd->stop_src == TRIG_NONE) {
1093                 /* TRIG_NONE */
1094                 if (cmd->stop_arg != 0) {
1095                         cmd->stop_arg = 0;
1096                         err++;
1097                 }
1098         }
1099
1100         if (err)
1101                 return 3;
1102
1103         /* step 4: fix up any arguments */
1104
1105         if (cmd->scan_begin_src == TRIG_TIMER) {
1106                 tmp = cmd->scan_begin_arg;
1107                 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1108                                                &(devpriv->ao_divisor1),
1109                                                &(devpriv->ao_divisor2),
1110                                                &(cmd->scan_begin_arg),
1111                                                cmd->flags & TRIG_ROUND_MASK);
1112                 if (tmp != cmd->scan_begin_arg)
1113                         err++;
1114         }
1115
1116         if (err)
1117                 return 4;
1118
1119         /*  check channel/gain list against card's limitations */
1120         if (cmd->chanlist && cmd->chanlist_len > 1) {
1121                 if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1122                     CR_CHAN(cmd->chanlist[1]) != 1) {
1123                         comedi_error(dev,
1124                                      "channels must be ordered channel 0, channel 1 in chanlist\n");
1125                         err++;
1126                 }
1127         }
1128
1129         if (err)
1130                 return 5;
1131
1132         return 0;
1133 }
1134
1135 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1136                             struct comedi_subdevice *s)
1137 {
1138         struct comedi_async *async = s->async;
1139         struct comedi_cmd *cmd = &async->cmd;
1140         unsigned int i;
1141         unsigned long flags;
1142
1143         /*  set channel limits, gain */
1144         spin_lock_irqsave(&dev->spinlock, flags);
1145         for (i = 0; i < cmd->chanlist_len; i++) {
1146                 /*  enable channel */
1147                 devpriv->ao_control_bits |=
1148                     DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1149                 /*  set range */
1150                 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1151                                                       CR_RANGE(cmd->
1152                                                                chanlist[i]));
1153         }
1154
1155         /*  disable analog out before settings pacer source and count values */
1156         outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1157         spin_unlock_irqrestore(&dev->spinlock, flags);
1158
1159         /*  clear fifo */
1160         outw(0, devpriv->ao_registers + DACFIFOCLR);
1161
1162         /*  load counters */
1163         if (cmd->scan_begin_src == TRIG_TIMER) {
1164                 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1165                                                &(devpriv->ao_divisor1),
1166                                                &(devpriv->ao_divisor2),
1167                                                &(cmd->scan_begin_arg),
1168                                                cmd->flags);
1169
1170                 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1171                 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1172                            devpriv->ao_divisor1, 2);
1173                 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1174                            devpriv->ao_divisor2, 2);
1175         }
1176         /*  set number of conversions */
1177         if (cmd->stop_src == TRIG_COUNT)
1178                 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1179         /*  set pacer source */
1180         spin_lock_irqsave(&dev->spinlock, flags);
1181         switch (cmd->scan_begin_src) {
1182         case TRIG_TIMER:
1183                 devpriv->ao_control_bits |= DAC_PACER_INT;
1184                 break;
1185         case TRIG_EXT:
1186                 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1187                 break;
1188         default:
1189                 spin_unlock_irqrestore(&dev->spinlock, flags);
1190                 comedi_error(dev, "error setting dac pacer source");
1191                 return -1;
1192                 break;
1193         }
1194         spin_unlock_irqrestore(&dev->spinlock, flags);
1195
1196         async->inttrig = cb_pcidas_ao_inttrig;
1197
1198         return 0;
1199 }
1200
1201 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1202                                 struct comedi_subdevice *s,
1203                                 unsigned int trig_num)
1204 {
1205         unsigned int num_bytes, num_points = thisboard->fifo_size;
1206         struct comedi_async *async = s->async;
1207         struct comedi_cmd *cmd = &s->async->cmd;
1208         unsigned long flags;
1209
1210         if (trig_num != 0)
1211                 return -EINVAL;
1212
1213         /*  load up fifo */
1214         if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1215                 num_points = devpriv->ao_count;
1216
1217         num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1218                                                num_points * sizeof(short));
1219         num_points = num_bytes / sizeof(short);
1220
1221         if (cmd->stop_src == TRIG_COUNT)
1222                 devpriv->ao_count -= num_points;
1223         /*  write data to board's fifo */
1224         outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1225
1226         /*  enable dac half-full and empty interrupts */
1227         spin_lock_irqsave(&dev->spinlock, flags);
1228         devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1229 #ifdef CB_PCIDAS_DEBUG
1230         dev_dbg(dev->class_dev, "adc_fifo_bits are 0x%x\n",
1231                 devpriv->adc_fifo_bits);
1232 #endif
1233         /*  enable and clear interrupts */
1234         outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1235              devpriv->control_status + INT_ADCFIFO);
1236
1237         /*  start dac */
1238         devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1239         outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1240 #ifdef CB_PCIDAS_DEBUG
1241         dev_dbg(dev->class_dev, "sent 0x%x to dac control\n",
1242                 devpriv->ao_control_bits);
1243 #endif
1244         spin_unlock_irqrestore(&dev->spinlock, flags);
1245
1246         async->inttrig = NULL;
1247
1248         return 0;
1249 }
1250
1251 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1252 {
1253         struct comedi_device *dev = (struct comedi_device *)d;
1254         struct comedi_subdevice *s = dev->read_subdev;
1255         struct comedi_async *async;
1256         int status, s5933_status;
1257         int half_fifo = thisboard->fifo_size / 2;
1258         unsigned int num_samples, i;
1259         static const int timeout = 10000;
1260         unsigned long flags;
1261
1262         if (dev->attached == 0)
1263                 return IRQ_NONE;
1264
1265         async = s->async;
1266         async->events = 0;
1267
1268         s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1269 #ifdef CB_PCIDAS_DEBUG
1270         dev_dbg(dev->class_dev, "intcsr 0x%x\n", s5933_status);
1271         dev_dbg(dev->class_dev, "mbef 0x%x\n",
1272                 inl(devpriv->s5933_config + AMCC_OP_REG_MBEF));
1273 #endif
1274
1275         if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1276                 return IRQ_NONE;
1277
1278         /*  make sure mailbox 4 is empty */
1279         inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1280         /*  clear interrupt on amcc s5933 */
1281         outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1282              devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1283
1284         status = inw(devpriv->control_status + INT_ADCFIFO);
1285 #ifdef CB_PCIDAS_DEBUG
1286         if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0)
1287                 comedi_error(dev, "spurious interrupt");
1288 #endif
1289
1290         /*  check for analog output interrupt */
1291         if (status & (DAHFI | DAEMI))
1292                 handle_ao_interrupt(dev, status);
1293         /*  check for analog input interrupts */
1294         /*  if fifo half-full */
1295         if (status & ADHFI) {
1296                 /*  read data */
1297                 num_samples = half_fifo;
1298                 if (async->cmd.stop_src == TRIG_COUNT &&
1299                     num_samples > devpriv->count) {
1300                         num_samples = devpriv->count;
1301                 }
1302                 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1303                      num_samples);
1304                 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1305                                           num_samples * sizeof(short));
1306                 devpriv->count -= num_samples;
1307                 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1308                         async->events |= COMEDI_CB_EOA;
1309                         cb_pcidas_cancel(dev, s);
1310                 }
1311                 /*  clear half-full interrupt latch */
1312                 spin_lock_irqsave(&dev->spinlock, flags);
1313                 outw(devpriv->adc_fifo_bits | INT,
1314                      devpriv->control_status + INT_ADCFIFO);
1315                 spin_unlock_irqrestore(&dev->spinlock, flags);
1316                 /*  else if fifo not empty */
1317         } else if (status & (ADNEI | EOBI)) {
1318                 for (i = 0; i < timeout; i++) {
1319                         /*  break if fifo is empty */
1320                         if ((ADNE & inw(devpriv->control_status +
1321                                         INT_ADCFIFO)) == 0)
1322                                 break;
1323                         cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1324                         if (async->cmd.stop_src == TRIG_COUNT && --devpriv->count == 0) {       /* end of acquisition */
1325                                 cb_pcidas_cancel(dev, s);
1326                                 async->events |= COMEDI_CB_EOA;
1327                                 break;
1328                         }
1329                 }
1330                 /*  clear not-empty interrupt latch */
1331                 spin_lock_irqsave(&dev->spinlock, flags);
1332                 outw(devpriv->adc_fifo_bits | INT,
1333                      devpriv->control_status + INT_ADCFIFO);
1334                 spin_unlock_irqrestore(&dev->spinlock, flags);
1335         } else if (status & EOAI) {
1336                 comedi_error(dev,
1337                              "bug! encountered end of acquisition interrupt?");
1338                 /*  clear EOA interrupt latch */
1339                 spin_lock_irqsave(&dev->spinlock, flags);
1340                 outw(devpriv->adc_fifo_bits | EOAI,
1341                      devpriv->control_status + INT_ADCFIFO);
1342                 spin_unlock_irqrestore(&dev->spinlock, flags);
1343         }
1344         /* check for fifo overflow */
1345         if (status & LADFUL) {
1346                 comedi_error(dev, "fifo overflow");
1347                 /*  clear overflow interrupt latch */
1348                 spin_lock_irqsave(&dev->spinlock, flags);
1349                 outw(devpriv->adc_fifo_bits | LADFUL,
1350                      devpriv->control_status + INT_ADCFIFO);
1351                 spin_unlock_irqrestore(&dev->spinlock, flags);
1352                 cb_pcidas_cancel(dev, s);
1353                 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1354         }
1355
1356         comedi_event(dev, s);
1357
1358         return IRQ_HANDLED;
1359 }
1360
1361 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1362 {
1363         struct comedi_subdevice *s = dev->write_subdev;
1364         struct comedi_async *async = s->async;
1365         struct comedi_cmd *cmd = &async->cmd;
1366         unsigned int half_fifo = thisboard->fifo_size / 2;
1367         unsigned int num_points;
1368         unsigned long flags;
1369
1370         async->events = 0;
1371
1372         if (status & DAEMI) {
1373                 /*  clear dac empty interrupt latch */
1374                 spin_lock_irqsave(&dev->spinlock, flags);
1375                 outw(devpriv->adc_fifo_bits | DAEMI,
1376                      devpriv->control_status + INT_ADCFIFO);
1377                 spin_unlock_irqrestore(&dev->spinlock, flags);
1378                 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1379                         if (cmd->stop_src == TRIG_NONE ||
1380                             (cmd->stop_src == TRIG_COUNT
1381                              && devpriv->ao_count)) {
1382                                 comedi_error(dev, "dac fifo underflow");
1383                                 cb_pcidas_ao_cancel(dev, s);
1384                                 async->events |= COMEDI_CB_ERROR;
1385                         }
1386                         async->events |= COMEDI_CB_EOA;
1387                 }
1388         } else if (status & DAHFI) {
1389                 unsigned int num_bytes;
1390
1391                 /*  figure out how many points we are writing to fifo */
1392                 num_points = half_fifo;
1393                 if (cmd->stop_src == TRIG_COUNT &&
1394                     devpriv->ao_count < num_points)
1395                         num_points = devpriv->ao_count;
1396                 num_bytes =
1397                     cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1398                                                num_points * sizeof(short));
1399                 num_points = num_bytes / sizeof(short);
1400
1401                 if (async->cmd.stop_src == TRIG_COUNT)
1402                         devpriv->ao_count -= num_points;
1403                 /*  write data to board's fifo */
1404                 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1405                       num_points);
1406                 /*  clear half-full interrupt latch */
1407                 spin_lock_irqsave(&dev->spinlock, flags);
1408                 outw(devpriv->adc_fifo_bits | DAHFI,
1409                      devpriv->control_status + INT_ADCFIFO);
1410                 spin_unlock_irqrestore(&dev->spinlock, flags);
1411         }
1412
1413         comedi_event(dev, s);
1414 }
1415
1416 /* cancel analog input command */
1417 static int cb_pcidas_cancel(struct comedi_device *dev,
1418                             struct comedi_subdevice *s)
1419 {
1420         unsigned long flags;
1421
1422         spin_lock_irqsave(&dev->spinlock, flags);
1423         /*  disable interrupts */
1424         devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1425         outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1426         spin_unlock_irqrestore(&dev->spinlock, flags);
1427
1428         /*  disable start trigger source and burst mode */
1429         outw(0, devpriv->control_status + TRIG_CONTSTAT);
1430         /*  software pacer source */
1431         outw(0, devpriv->control_status + ADCMUX_CONT);
1432
1433         return 0;
1434 }
1435
1436 /* cancel analog output command */
1437 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1438                                struct comedi_subdevice *s)
1439 {
1440         unsigned long flags;
1441
1442         spin_lock_irqsave(&dev->spinlock, flags);
1443         /*  disable interrupts */
1444         devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1445         outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1446
1447         /*  disable output */
1448         devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1449         outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1450         spin_unlock_irqrestore(&dev->spinlock, flags);
1451
1452         return 0;
1453 }
1454
1455 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
1456                                     int rounding_flags)
1457 {
1458         i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
1459                                        &(devpriv->divisor2), ns,
1460                                        rounding_flags & TRIG_ROUND_MASK);
1461
1462         /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1463         i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
1464                    devpriv->divisor1, 2);
1465         i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
1466                    devpriv->divisor2, 2);
1467 }
1468
1469 static void write_calibration_bitstream(struct comedi_device *dev,
1470                                         unsigned int register_bits,
1471                                         unsigned int bitstream,
1472                                         unsigned int bitstream_length)
1473 {
1474         static const int write_delay = 1;
1475         unsigned int bit;
1476
1477         for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
1478                 if (bitstream & bit)
1479                         register_bits |= SERIAL_DATA_IN_BIT;
1480                 else
1481                         register_bits &= ~SERIAL_DATA_IN_BIT;
1482                 udelay(write_delay);
1483                 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
1484         }
1485 }
1486
1487 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
1488                              uint8_t value)
1489 {
1490         static const int num_caldac_channels = 8;
1491         static const int bitstream_length = 11;
1492         unsigned int bitstream = ((address & 0x7) << 8) | value;
1493         static const int caldac_8800_udelay = 1;
1494
1495         if (address >= num_caldac_channels) {
1496                 comedi_error(dev, "illegal caldac channel");
1497                 return -1;
1498         }
1499
1500         if (value == devpriv->caldac_value[address])
1501                 return 1;
1502
1503         devpriv->caldac_value[address] = value;
1504
1505         write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
1506                                     bitstream_length);
1507
1508         udelay(caldac_8800_udelay);
1509         outw(cal_enable_bits(dev) | SELECT_8800_BIT,
1510              devpriv->control_status + CALIBRATION_REG);
1511         udelay(caldac_8800_udelay);
1512         outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
1513
1514         return 1;
1515 }
1516
1517 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
1518 {
1519         static const int bitstream_length = 7;
1520         unsigned int bitstream = value & 0x7f;
1521         unsigned int register_bits;
1522         static const int ad7376_udelay = 1;
1523
1524         register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
1525         udelay(ad7376_udelay);
1526         outw(register_bits, devpriv->control_status + CALIBRATION_REG);
1527
1528         write_calibration_bitstream(dev, register_bits, bitstream,
1529                                     bitstream_length);
1530
1531         udelay(ad7376_udelay);
1532         outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
1533
1534         return 0;
1535 }
1536
1537 /* For 1602/16 only
1538  * ch 0 : adc gain
1539  * ch 1 : adc postgain offset */
1540 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
1541                               uint8_t value)
1542 {
1543         static const int bitstream_length = 10;
1544         unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
1545         unsigned int register_bits;
1546         static const int ad8402_udelay = 1;
1547
1548         register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
1549         udelay(ad8402_udelay);
1550         outw(register_bits, devpriv->control_status + CALIBRATION_REG);
1551
1552         write_calibration_bitstream(dev, register_bits, bitstream,
1553                                     bitstream_length);
1554
1555         udelay(ad8402_udelay);
1556         outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
1557
1558         return 0;
1559 }
1560
1561 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
1562 {
1563         static const int timeout = 1000;
1564         unsigned int i;
1565
1566         for (i = 0; i < timeout; i++) {
1567                 if ((inb(s5933_base_addr +
1568                          AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
1569                     == 0)
1570                         return 0;
1571                 udelay(1);
1572         }
1573         return -1;
1574 }
1575
1576 static int nvram_read(struct comedi_device *dev, unsigned int address,
1577                         uint8_t *data)
1578 {
1579         unsigned long iobase = devpriv->s5933_config;
1580
1581         if (wait_for_nvram_ready(iobase) < 0)
1582                 return -ETIMEDOUT;
1583
1584         outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
1585              iobase + AMCC_OP_REG_MCSR_NVCMD);
1586         outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
1587         outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
1588              iobase + AMCC_OP_REG_MCSR_NVCMD);
1589         outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
1590         outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
1591
1592         if (wait_for_nvram_ready(iobase) < 0)
1593                 return -ETIMEDOUT;
1594
1595         *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
1596
1597         return 0;
1598 }
1599
1600 static int cb_pcidas_attach(struct comedi_device *dev,
1601                             struct comedi_devconfig *it)
1602 {
1603         struct comedi_subdevice *s;
1604         struct pci_dev *pcidev = NULL;
1605         int index;
1606         int i;
1607         int ret;
1608
1609 /*
1610  * Allocate the private structure area.
1611  */
1612         if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0)
1613                 return -ENOMEM;
1614
1615 /*
1616  * Probe the device to determine what device in the series it is.
1617  */
1618
1619         for_each_pci_dev(pcidev) {
1620                 /*  is it not a computer boards card? */
1621                 if (pcidev->vendor != PCI_VENDOR_ID_CB)
1622                         continue;
1623                 /*  loop through cards supported by this driver */
1624                 for (index = 0; index < ARRAY_SIZE(cb_pcidas_boards); index++) {
1625                         if (cb_pcidas_boards[index].device_id != pcidev->device)
1626                                 continue;
1627                         /*  was a particular bus/slot requested? */
1628                         if (it->options[0] || it->options[1]) {
1629                                 /*  are we on the wrong bus/slot? */
1630                                 if (pcidev->bus->number != it->options[0] ||
1631                                     PCI_SLOT(pcidev->devfn) != it->options[1]) {
1632                                         continue;
1633                                 }
1634                         }
1635                         devpriv->pci_dev = pcidev;
1636                         dev->board_ptr = cb_pcidas_boards + index;
1637                         goto found;
1638                 }
1639         }
1640
1641         dev_err(dev->class_dev,
1642                 "No supported ComputerBoards/MeasurementComputing card found on requested position\n");
1643         return -EIO;
1644
1645 found:
1646
1647         dev_dbg(dev->class_dev, "Found %s on bus %i, slot %i\n",
1648                 cb_pcidas_boards[index].name, pcidev->bus->number,
1649                 PCI_SLOT(pcidev->devfn));
1650
1651         /*
1652          * Enable PCI device and reserve I/O ports.
1653          */
1654         if (comedi_pci_enable(pcidev, "cb_pcidas")) {
1655                 dev_err(dev->class_dev,
1656                         "Failed to enable PCI device and request regions\n");
1657                 return -EIO;
1658         }
1659         /*
1660          * Initialize devpriv->control_status and devpriv->adc_fifo to point to
1661          * their base address.
1662          */
1663         devpriv->s5933_config =
1664             pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX);
1665         devpriv->control_status =
1666             pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX);
1667         devpriv->adc_fifo =
1668             pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX);
1669         devpriv->pacer_counter_dio =
1670             pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX);
1671         if (thisboard->ao_nchan) {
1672                 devpriv->ao_registers =
1673                     pci_resource_start(devpriv->pci_dev, AO_BADRINDEX);
1674         }
1675         /*  disable and clear interrupts on amcc s5933 */
1676         outl(INTCSR_INBOX_INTR_STATUS,
1677              devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1678
1679         /*  get irq */
1680         if (request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt,
1681                         IRQF_SHARED, "cb_pcidas", dev)) {
1682                 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1683                         devpriv->pci_dev->irq);
1684                 return -EINVAL;
1685         }
1686         dev->irq = devpriv->pci_dev->irq;
1687
1688         /* Initialize dev->board_name */
1689         dev->board_name = thisboard->name;
1690
1691         ret = comedi_alloc_subdevices(dev, 7);
1692         if (ret)
1693                 return ret;
1694
1695         s = dev->subdevices + 0;
1696         /* analog input subdevice */
1697         dev->read_subdev = s;
1698         s->type = COMEDI_SUBD_AI;
1699         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1700         /* WARNING: Number of inputs in differential mode is ignored */
1701         s->n_chan = thisboard->ai_se_chans;
1702         s->len_chanlist = thisboard->ai_se_chans;
1703         s->maxdata = (1 << thisboard->ai_bits) - 1;
1704         s->range_table = thisboard->ranges;
1705         s->insn_read = cb_pcidas_ai_rinsn;
1706         s->insn_config = ai_config_insn;
1707         s->do_cmd = cb_pcidas_ai_cmd;
1708         s->do_cmdtest = cb_pcidas_ai_cmdtest;
1709         s->cancel = cb_pcidas_cancel;
1710
1711         /* analog output subdevice */
1712         s = dev->subdevices + 1;
1713         if (thisboard->ao_nchan) {
1714                 s->type = COMEDI_SUBD_AO;
1715                 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1716                 s->n_chan = thisboard->ao_nchan;
1717                 /*  analog out resolution is the same as analog input resolution, so use ai_bits */
1718                 s->maxdata = (1 << thisboard->ai_bits) - 1;
1719                 s->range_table = &cb_pcidas_ao_ranges;
1720                 s->insn_read = cb_pcidas_ao_readback_insn;
1721                 if (thisboard->has_ao_fifo) {
1722                         dev->write_subdev = s;
1723                         s->subdev_flags |= SDF_CMD_WRITE;
1724                         s->insn_write = cb_pcidas_ao_fifo_winsn;
1725                         s->do_cmdtest = cb_pcidas_ao_cmdtest;
1726                         s->do_cmd = cb_pcidas_ao_cmd;
1727                         s->cancel = cb_pcidas_ao_cancel;
1728                 } else {
1729                         s->insn_write = cb_pcidas_ao_nofifo_winsn;
1730                 }
1731         } else {
1732                 s->type = COMEDI_SUBD_UNUSED;
1733         }
1734
1735         /* 8255 */
1736         s = dev->subdevices + 2;
1737         subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255);
1738
1739         /*  serial EEPROM, */
1740         s = dev->subdevices + 3;
1741         s->type = COMEDI_SUBD_MEMORY;
1742         s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1743         s->n_chan = 256;
1744         s->maxdata = 0xff;
1745         s->insn_read = eeprom_read_insn;
1746
1747         /*  8800 caldac */
1748         s = dev->subdevices + 4;
1749         s->type = COMEDI_SUBD_CALIB;
1750         s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1751         s->n_chan = NUM_CHANNELS_8800;
1752         s->maxdata = 0xff;
1753         s->insn_read = caldac_read_insn;
1754         s->insn_write = caldac_write_insn;
1755         for (i = 0; i < s->n_chan; i++)
1756                 caldac_8800_write(dev, i, s->maxdata / 2);
1757
1758         /*  trim potentiometer */
1759         s = dev->subdevices + 5;
1760         s->type = COMEDI_SUBD_CALIB;
1761         s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1762         if (thisboard->trimpot == AD7376) {
1763                 s->n_chan = NUM_CHANNELS_7376;
1764                 s->maxdata = 0x7f;
1765         } else {
1766                 s->n_chan = NUM_CHANNELS_8402;
1767                 s->maxdata = 0xff;
1768         }
1769         s->insn_read = trimpot_read_insn;
1770         s->insn_write = trimpot_write_insn;
1771         for (i = 0; i < s->n_chan; i++)
1772                 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1773
1774         /*  dac08 caldac */
1775         s = dev->subdevices + 6;
1776         if (thisboard->has_dac08) {
1777                 s->type = COMEDI_SUBD_CALIB;
1778                 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1779                 s->n_chan = NUM_CHANNELS_DAC08;
1780                 s->insn_read = dac08_read_insn;
1781                 s->insn_write = dac08_write_insn;
1782                 s->maxdata = 0xff;
1783                 dac08_write(dev, s->maxdata / 2);
1784         } else
1785                 s->type = COMEDI_SUBD_UNUSED;
1786
1787         /*  make sure mailbox 4 is empty */
1788         inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1789         /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1790         devpriv->s5933_intcsr_bits =
1791             INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1792             INTCSR_INBOX_FULL_INT;
1793         /*  clear and enable interrupt on amcc s5933 */
1794         outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1795              devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1796
1797         return 1;
1798 }
1799
1800 static void cb_pcidas_detach(struct comedi_device *dev)
1801 {
1802         if (devpriv) {
1803                 if (devpriv->s5933_config) {
1804                         outl(INTCSR_INBOX_INTR_STATUS,
1805                              devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1806                 }
1807         }
1808         if (dev->irq)
1809                 free_irq(dev->irq, dev);
1810         if (dev->subdevices)
1811                 subdev_8255_cleanup(dev, dev->subdevices + 2);
1812         if (devpriv && devpriv->pci_dev) {
1813                 if (devpriv->s5933_config)
1814                         comedi_pci_disable(devpriv->pci_dev);
1815                 pci_dev_put(devpriv->pci_dev);
1816         }
1817 }
1818
1819 static struct comedi_driver cb_pcidas_driver = {
1820         .driver_name    = "cb_pcidas",
1821         .module         = THIS_MODULE,
1822         .attach         = cb_pcidas_attach,
1823         .detach         = cb_pcidas_detach,
1824 };
1825
1826 static int __devinit cb_pcidas_pci_probe(struct pci_dev *dev,
1827                                          const struct pci_device_id *ent)
1828 {
1829         return comedi_pci_auto_config(dev, &cb_pcidas_driver);
1830 }
1831
1832 static void __devexit cb_pcidas_pci_remove(struct pci_dev *dev)
1833 {
1834         comedi_pci_auto_unconfig(dev);
1835 }
1836
1837 static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
1838         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) },
1839         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) },
1840         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) },
1841         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) },
1842         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) },
1843         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) },
1844         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) },
1845         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) },
1846         { 0 }
1847 };
1848 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1849
1850 static struct pci_driver cb_pcidas_pci_driver = {
1851         .name           = "cb_pcidas",
1852         .id_table       = cb_pcidas_pci_table,
1853         .probe          = cb_pcidas_pci_probe,
1854         .remove         = __devexit_p(cb_pcidas_pci_remove)
1855 };
1856 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1857
1858 MODULE_AUTHOR("Comedi http://www.comedi.org");
1859 MODULE_DESCRIPTION("Comedi low-level driver");
1860 MODULE_LICENSE("GPL");