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