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