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