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