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