cb_pcidas.c revision cb9cfd7ed3f6ed4c40167b4251cdb382b6b3ba1c
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/module.h>
65#include <linux/pci.h>
66#include <linux/delay.h>
67#include <linux/interrupt.h>
68
69#include "../comedidev.h"
70
71#include "8253.h"
72#include "8255.h"
73#include "amcc_s5933.h"
74#include "comedi_fc.h"
75
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(I8254_OSC_BASE_10MHZ,
883					  &devpriv->divisor1,
884					  &devpriv->divisor2,
885					  &cmd->scan_begin_arg, cmd->flags);
886		if (tmp != cmd->scan_begin_arg)
887			err++;
888	}
889	if (cmd->convert_src == TRIG_TIMER) {
890		tmp = cmd->convert_arg;
891		i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
892					  &devpriv->divisor1,
893					  &devpriv->divisor2,
894					  &cmd->convert_arg, cmd->flags);
895		if (tmp != cmd->convert_arg)
896			err++;
897	}
898
899	if (err)
900		return 4;
901
902	/*  check channel/gain list against card's limitations */
903	if (cmd->chanlist) {
904		gain = CR_RANGE(cmd->chanlist[0]);
905		start_chan = CR_CHAN(cmd->chanlist[0]);
906		for (i = 1; i < cmd->chanlist_len; i++) {
907			if (CR_CHAN(cmd->chanlist[i]) !=
908			    (start_chan + i) % s->n_chan) {
909				comedi_error(dev,
910					     "entries in chanlist must be consecutive channels, counting upwards\n");
911				err++;
912			}
913			if (CR_RANGE(cmd->chanlist[i]) != gain) {
914				comedi_error(dev,
915					     "entries in chanlist must all have the same gain\n");
916				err++;
917			}
918		}
919	}
920
921	if (err)
922		return 5;
923
924	return 0;
925}
926
927static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
928				    int rounding_flags)
929{
930	struct cb_pcidas_private *devpriv = dev->private;
931
932	i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
933				  &devpriv->divisor1, &devpriv->divisor2,
934				  ns, rounding_flags);
935
936	/* Write the values of ctr1 and ctr2 into counters 1 and 2 */
937	i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
938		   devpriv->divisor1, 2);
939	i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
940		   devpriv->divisor2, 2);
941}
942
943static int cb_pcidas_ai_cmd(struct comedi_device *dev,
944			    struct comedi_subdevice *s)
945{
946	const struct cb_pcidas_board *thisboard = comedi_board(dev);
947	struct cb_pcidas_private *devpriv = dev->private;
948	struct comedi_async *async = s->async;
949	struct comedi_cmd *cmd = &async->cmd;
950	unsigned int bits;
951	unsigned long flags;
952
953	/*  make sure CAL_EN_BIT is disabled */
954	outw(0, devpriv->control_status + CALIBRATION_REG);
955	/*  initialize before settings pacer source and count values */
956	outw(0, devpriv->control_status + TRIG_CONTSTAT);
957	/*  clear fifo */
958	outw(0, devpriv->adc_fifo + ADCFIFOCLR);
959
960	/*  set mux limits, gain and pacer source */
961	bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
962	    END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
963	    GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
964	/*  set unipolar/bipolar */
965	if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
966		bits |= UNIP;
967	/*  set singleended/differential */
968	if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
969		bits |= SE;
970	/*  set pacer source */
971	if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
972		bits |= PACER_EXT_RISE;
973	else
974		bits |= PACER_INT;
975	outw(bits, devpriv->control_status + ADCMUX_CONT);
976
977	/*  load counters */
978	if (cmd->convert_src == TRIG_TIMER)
979		cb_pcidas_load_counters(dev, &cmd->convert_arg,
980					cmd->flags & TRIG_ROUND_MASK);
981	else if (cmd->scan_begin_src == TRIG_TIMER)
982		cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
983					cmd->flags & TRIG_ROUND_MASK);
984
985	/*  set number of conversions */
986	if (cmd->stop_src == TRIG_COUNT)
987		devpriv->count = cmd->chanlist_len * cmd->stop_arg;
988	/*  enable interrupts */
989	spin_lock_irqsave(&dev->spinlock, flags);
990	devpriv->adc_fifo_bits |= INTE;
991	devpriv->adc_fifo_bits &= ~INT_MASK;
992	if (cmd->flags & TRIG_WAKE_EOS) {
993		if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
994			/* interrupt end of burst */
995			devpriv->adc_fifo_bits |= INT_EOS;
996		} else {
997			/* interrupt fifo not empty */
998			devpriv->adc_fifo_bits |= INT_FNE;
999		}
1000	} else {
1001		/* interrupt fifo half full */
1002		devpriv->adc_fifo_bits |= INT_FHF;
1003	}
1004
1005	/*  enable (and clear) interrupts */
1006	outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1007	     devpriv->control_status + INT_ADCFIFO);
1008	spin_unlock_irqrestore(&dev->spinlock, flags);
1009
1010	/*  set start trigger and burst mode */
1011	bits = 0;
1012	if (cmd->start_src == TRIG_NOW)
1013		bits |= SW_TRIGGER;
1014	else if (cmd->start_src == TRIG_EXT) {
1015		bits |= EXT_TRIGGER | TGEN | XTRCL;
1016		if (thisboard->is_1602) {
1017			if (cmd->start_arg & CR_INVERT)
1018				bits |= TGPOL;
1019			if (cmd->start_arg & CR_EDGE)
1020				bits |= TGSEL;
1021		}
1022	} else {
1023		comedi_error(dev, "bug!");
1024		return -1;
1025	}
1026	if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1027		bits |= BURSTE;
1028	outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1029
1030	return 0;
1031}
1032
1033static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1034				struct comedi_subdevice *s,
1035				struct comedi_cmd *cmd)
1036{
1037	const struct cb_pcidas_board *thisboard = comedi_board(dev);
1038	struct cb_pcidas_private *devpriv = dev->private;
1039	int err = 0;
1040	int tmp;
1041
1042	/* Step 1 : check if triggers are trivially valid */
1043
1044	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
1045	err |= cfc_check_trigger_src(&cmd->scan_begin_src,
1046					TRIG_TIMER | TRIG_EXT);
1047	err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1048	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1049	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1050
1051	if (err)
1052		return 1;
1053
1054	/* Step 2a : make sure trigger sources are unique */
1055
1056	err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1057	err |= cfc_check_trigger_is_unique(cmd->stop_src);
1058
1059	/* Step 2b : and mutually compatible */
1060
1061	if (err)
1062		return 2;
1063
1064	/* Step 3: check if arguments are trivially valid */
1065
1066	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1067
1068	if (cmd->scan_begin_src == TRIG_TIMER)
1069		err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1070						 thisboard->ao_scan_speed);
1071
1072	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1073
1074	if (cmd->stop_src == TRIG_NONE)
1075		err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1076
1077	if (err)
1078		return 3;
1079
1080	/* step 4: fix up any arguments */
1081
1082	if (cmd->scan_begin_src == TRIG_TIMER) {
1083		tmp = cmd->scan_begin_arg;
1084		i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
1085					  &devpriv->ao_divisor1,
1086					  &devpriv->ao_divisor2,
1087					  &cmd->scan_begin_arg, cmd->flags);
1088		if (tmp != cmd->scan_begin_arg)
1089			err++;
1090	}
1091
1092	if (err)
1093		return 4;
1094
1095	/*  check channel/gain list against card's limitations */
1096	if (cmd->chanlist && cmd->chanlist_len > 1) {
1097		if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1098		    CR_CHAN(cmd->chanlist[1]) != 1) {
1099			comedi_error(dev,
1100				     "channels must be ordered channel 0, channel 1 in chanlist\n");
1101			err++;
1102		}
1103	}
1104
1105	if (err)
1106		return 5;
1107
1108	return 0;
1109}
1110
1111/* cancel analog input command */
1112static int cb_pcidas_cancel(struct comedi_device *dev,
1113			    struct comedi_subdevice *s)
1114{
1115	struct cb_pcidas_private *devpriv = dev->private;
1116	unsigned long flags;
1117
1118	spin_lock_irqsave(&dev->spinlock, flags);
1119	/*  disable interrupts */
1120	devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1121	outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1122	spin_unlock_irqrestore(&dev->spinlock, flags);
1123
1124	/*  disable start trigger source and burst mode */
1125	outw(0, devpriv->control_status + TRIG_CONTSTAT);
1126	/*  software pacer source */
1127	outw(0, devpriv->control_status + ADCMUX_CONT);
1128
1129	return 0;
1130}
1131
1132static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1133				struct comedi_subdevice *s,
1134				unsigned int trig_num)
1135{
1136	const struct cb_pcidas_board *thisboard = comedi_board(dev);
1137	struct cb_pcidas_private *devpriv = dev->private;
1138	unsigned int num_bytes, num_points = thisboard->fifo_size;
1139	struct comedi_async *async = s->async;
1140	struct comedi_cmd *cmd = &s->async->cmd;
1141	unsigned long flags;
1142
1143	if (trig_num != 0)
1144		return -EINVAL;
1145
1146	/*  load up fifo */
1147	if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1148		num_points = devpriv->ao_count;
1149
1150	num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1151					       num_points * sizeof(short));
1152	num_points = num_bytes / sizeof(short);
1153
1154	if (cmd->stop_src == TRIG_COUNT)
1155		devpriv->ao_count -= num_points;
1156	/*  write data to board's fifo */
1157	outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1158
1159	/*  enable dac half-full and empty interrupts */
1160	spin_lock_irqsave(&dev->spinlock, flags);
1161	devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1162
1163	/*  enable and clear interrupts */
1164	outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1165	     devpriv->control_status + INT_ADCFIFO);
1166
1167	/*  start dac */
1168	devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1169	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1170
1171	spin_unlock_irqrestore(&dev->spinlock, flags);
1172
1173	async->inttrig = NULL;
1174
1175	return 0;
1176}
1177
1178static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1179			    struct comedi_subdevice *s)
1180{
1181	struct cb_pcidas_private *devpriv = dev->private;
1182	struct comedi_async *async = s->async;
1183	struct comedi_cmd *cmd = &async->cmd;
1184	unsigned int i;
1185	unsigned long flags;
1186
1187	/*  set channel limits, gain */
1188	spin_lock_irqsave(&dev->spinlock, flags);
1189	for (i = 0; i < cmd->chanlist_len; i++) {
1190		/*  enable channel */
1191		devpriv->ao_control_bits |=
1192		    DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1193		/*  set range */
1194		devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1195						      CR_RANGE(cmd->
1196							       chanlist[i]));
1197	}
1198
1199	/*  disable analog out before settings pacer source and count values */
1200	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1201	spin_unlock_irqrestore(&dev->spinlock, flags);
1202
1203	/*  clear fifo */
1204	outw(0, devpriv->ao_registers + DACFIFOCLR);
1205
1206	/*  load counters */
1207	if (cmd->scan_begin_src == TRIG_TIMER) {
1208		i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
1209					  &devpriv->ao_divisor1,
1210					  &devpriv->ao_divisor2,
1211					  &cmd->scan_begin_arg, cmd->flags);
1212
1213		/* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1214		i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1215			   devpriv->ao_divisor1, 2);
1216		i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1217			   devpriv->ao_divisor2, 2);
1218	}
1219	/*  set number of conversions */
1220	if (cmd->stop_src == TRIG_COUNT)
1221		devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1222	/*  set pacer source */
1223	spin_lock_irqsave(&dev->spinlock, flags);
1224	switch (cmd->scan_begin_src) {
1225	case TRIG_TIMER:
1226		devpriv->ao_control_bits |= DAC_PACER_INT;
1227		break;
1228	case TRIG_EXT:
1229		devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1230		break;
1231	default:
1232		spin_unlock_irqrestore(&dev->spinlock, flags);
1233		comedi_error(dev, "error setting dac pacer source");
1234		return -1;
1235		break;
1236	}
1237	spin_unlock_irqrestore(&dev->spinlock, flags);
1238
1239	async->inttrig = cb_pcidas_ao_inttrig;
1240
1241	return 0;
1242}
1243
1244/* cancel analog output command */
1245static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1246			       struct comedi_subdevice *s)
1247{
1248	struct cb_pcidas_private *devpriv = dev->private;
1249	unsigned long flags;
1250
1251	spin_lock_irqsave(&dev->spinlock, flags);
1252	/*  disable interrupts */
1253	devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1254	outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1255
1256	/*  disable output */
1257	devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1258	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1259	spin_unlock_irqrestore(&dev->spinlock, flags);
1260
1261	return 0;
1262}
1263
1264static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1265{
1266	const struct cb_pcidas_board *thisboard = comedi_board(dev);
1267	struct cb_pcidas_private *devpriv = dev->private;
1268	struct comedi_subdevice *s = dev->write_subdev;
1269	struct comedi_async *async = s->async;
1270	struct comedi_cmd *cmd = &async->cmd;
1271	unsigned int half_fifo = thisboard->fifo_size / 2;
1272	unsigned int num_points;
1273	unsigned long flags;
1274
1275	async->events = 0;
1276
1277	if (status & DAEMI) {
1278		/*  clear dac empty interrupt latch */
1279		spin_lock_irqsave(&dev->spinlock, flags);
1280		outw(devpriv->adc_fifo_bits | DAEMI,
1281		     devpriv->control_status + INT_ADCFIFO);
1282		spin_unlock_irqrestore(&dev->spinlock, flags);
1283		if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1284			if (cmd->stop_src == TRIG_NONE ||
1285			    (cmd->stop_src == TRIG_COUNT
1286			     && devpriv->ao_count)) {
1287				comedi_error(dev, "dac fifo underflow");
1288				cb_pcidas_ao_cancel(dev, s);
1289				async->events |= COMEDI_CB_ERROR;
1290			}
1291			async->events |= COMEDI_CB_EOA;
1292		}
1293	} else if (status & DAHFI) {
1294		unsigned int num_bytes;
1295
1296		/*  figure out how many points we are writing to fifo */
1297		num_points = half_fifo;
1298		if (cmd->stop_src == TRIG_COUNT &&
1299		    devpriv->ao_count < num_points)
1300			num_points = devpriv->ao_count;
1301		num_bytes =
1302		    cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1303					       num_points * sizeof(short));
1304		num_points = num_bytes / sizeof(short);
1305
1306		if (async->cmd.stop_src == TRIG_COUNT)
1307			devpriv->ao_count -= num_points;
1308		/*  write data to board's fifo */
1309		outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1310		      num_points);
1311		/*  clear half-full interrupt latch */
1312		spin_lock_irqsave(&dev->spinlock, flags);
1313		outw(devpriv->adc_fifo_bits | DAHFI,
1314		     devpriv->control_status + INT_ADCFIFO);
1315		spin_unlock_irqrestore(&dev->spinlock, flags);
1316	}
1317
1318	comedi_event(dev, s);
1319}
1320
1321static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1322{
1323	struct comedi_device *dev = (struct comedi_device *)d;
1324	const struct cb_pcidas_board *thisboard = comedi_board(dev);
1325	struct cb_pcidas_private *devpriv = dev->private;
1326	struct comedi_subdevice *s = dev->read_subdev;
1327	struct comedi_async *async;
1328	int status, s5933_status;
1329	int half_fifo = thisboard->fifo_size / 2;
1330	unsigned int num_samples, i;
1331	static const int timeout = 10000;
1332	unsigned long flags;
1333
1334	if (!dev->attached)
1335		return IRQ_NONE;
1336
1337	async = s->async;
1338	async->events = 0;
1339
1340	s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1341
1342	if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1343		return IRQ_NONE;
1344
1345	/*  make sure mailbox 4 is empty */
1346	inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1347	/*  clear interrupt on amcc s5933 */
1348	outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1349	     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1350
1351	status = inw(devpriv->control_status + INT_ADCFIFO);
1352
1353	/*  check for analog output interrupt */
1354	if (status & (DAHFI | DAEMI))
1355		handle_ao_interrupt(dev, status);
1356	/*  check for analog input interrupts */
1357	/*  if fifo half-full */
1358	if (status & ADHFI) {
1359		/*  read data */
1360		num_samples = half_fifo;
1361		if (async->cmd.stop_src == TRIG_COUNT &&
1362		    num_samples > devpriv->count) {
1363			num_samples = devpriv->count;
1364		}
1365		insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1366		     num_samples);
1367		cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1368					  num_samples * sizeof(short));
1369		devpriv->count -= num_samples;
1370		if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1371			async->events |= COMEDI_CB_EOA;
1372			cb_pcidas_cancel(dev, s);
1373		}
1374		/*  clear half-full interrupt latch */
1375		spin_lock_irqsave(&dev->spinlock, flags);
1376		outw(devpriv->adc_fifo_bits | INT,
1377		     devpriv->control_status + INT_ADCFIFO);
1378		spin_unlock_irqrestore(&dev->spinlock, flags);
1379		/*  else if fifo not empty */
1380	} else if (status & (ADNEI | EOBI)) {
1381		for (i = 0; i < timeout; i++) {
1382			/*  break if fifo is empty */
1383			if ((ADNE & inw(devpriv->control_status +
1384					INT_ADCFIFO)) == 0)
1385				break;
1386			cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1387			if (async->cmd.stop_src == TRIG_COUNT &&
1388			    --devpriv->count == 0) {
1389				/* end of acquisition */
1390				cb_pcidas_cancel(dev, s);
1391				async->events |= COMEDI_CB_EOA;
1392				break;
1393			}
1394		}
1395		/*  clear not-empty interrupt latch */
1396		spin_lock_irqsave(&dev->spinlock, flags);
1397		outw(devpriv->adc_fifo_bits | INT,
1398		     devpriv->control_status + INT_ADCFIFO);
1399		spin_unlock_irqrestore(&dev->spinlock, flags);
1400	} else if (status & EOAI) {
1401		comedi_error(dev,
1402			     "bug! encountered end of acquisition interrupt?");
1403		/*  clear EOA interrupt latch */
1404		spin_lock_irqsave(&dev->spinlock, flags);
1405		outw(devpriv->adc_fifo_bits | EOAI,
1406		     devpriv->control_status + INT_ADCFIFO);
1407		spin_unlock_irqrestore(&dev->spinlock, flags);
1408	}
1409	/* check for fifo overflow */
1410	if (status & LADFUL) {
1411		comedi_error(dev, "fifo overflow");
1412		/*  clear overflow interrupt latch */
1413		spin_lock_irqsave(&dev->spinlock, flags);
1414		outw(devpriv->adc_fifo_bits | LADFUL,
1415		     devpriv->control_status + INT_ADCFIFO);
1416		spin_unlock_irqrestore(&dev->spinlock, flags);
1417		cb_pcidas_cancel(dev, s);
1418		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1419	}
1420
1421	comedi_event(dev, s);
1422
1423	return IRQ_HANDLED;
1424}
1425
1426static int cb_pcidas_auto_attach(struct comedi_device *dev,
1427				 unsigned long context)
1428{
1429	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1430	const struct cb_pcidas_board *thisboard = NULL;
1431	struct cb_pcidas_private *devpriv;
1432	struct comedi_subdevice *s;
1433	int i;
1434	int ret;
1435
1436	if (context < ARRAY_SIZE(cb_pcidas_boards))
1437		thisboard = &cb_pcidas_boards[context];
1438	if (!thisboard)
1439		return -ENODEV;
1440	dev->board_ptr  = thisboard;
1441	dev->board_name = thisboard->name;
1442
1443	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1444	if (!devpriv)
1445		return -ENOMEM;
1446
1447	ret = comedi_pci_enable(dev);
1448	if (ret)
1449		return ret;
1450
1451	devpriv->s5933_config = pci_resource_start(pcidev, 0);
1452	devpriv->control_status = pci_resource_start(pcidev, 1);
1453	devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1454	devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3);
1455	if (thisboard->ao_nchan)
1456		devpriv->ao_registers = pci_resource_start(pcidev, 4);
1457
1458	/*  disable and clear interrupts on amcc s5933 */
1459	outl(INTCSR_INBOX_INTR_STATUS,
1460	     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1461
1462	if (request_irq(pcidev->irq, cb_pcidas_interrupt,
1463			IRQF_SHARED, dev->driver->driver_name, dev)) {
1464		dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1465			pcidev->irq);
1466		return -EINVAL;
1467	}
1468	dev->irq = pcidev->irq;
1469
1470	ret = comedi_alloc_subdevices(dev, 7);
1471	if (ret)
1472		return ret;
1473
1474	s = &dev->subdevices[0];
1475	/* analog input subdevice */
1476	dev->read_subdev = s;
1477	s->type = COMEDI_SUBD_AI;
1478	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1479	/* WARNING: Number of inputs in differential mode is ignored */
1480	s->n_chan = thisboard->ai_nchan;
1481	s->len_chanlist = thisboard->ai_nchan;
1482	s->maxdata = (1 << thisboard->ai_bits) - 1;
1483	s->range_table = thisboard->ranges;
1484	s->insn_read = cb_pcidas_ai_rinsn;
1485	s->insn_config = ai_config_insn;
1486	s->do_cmd = cb_pcidas_ai_cmd;
1487	s->do_cmdtest = cb_pcidas_ai_cmdtest;
1488	s->cancel = cb_pcidas_cancel;
1489
1490	/* analog output subdevice */
1491	s = &dev->subdevices[1];
1492	if (thisboard->ao_nchan) {
1493		s->type = COMEDI_SUBD_AO;
1494		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1495		s->n_chan = thisboard->ao_nchan;
1496		/*
1497		 * analog out resolution is the same as
1498		 * analog input resolution, so use ai_bits
1499		 */
1500		s->maxdata = (1 << thisboard->ai_bits) - 1;
1501		s->range_table = &cb_pcidas_ao_ranges;
1502		s->insn_read = cb_pcidas_ao_readback_insn;
1503		if (thisboard->has_ao_fifo) {
1504			dev->write_subdev = s;
1505			s->subdev_flags |= SDF_CMD_WRITE;
1506			s->insn_write = cb_pcidas_ao_fifo_winsn;
1507			s->do_cmdtest = cb_pcidas_ao_cmdtest;
1508			s->do_cmd = cb_pcidas_ao_cmd;
1509			s->cancel = cb_pcidas_ao_cancel;
1510		} else {
1511			s->insn_write = cb_pcidas_ao_nofifo_winsn;
1512		}
1513	} else {
1514		s->type = COMEDI_SUBD_UNUSED;
1515	}
1516
1517	/* 8255 */
1518	s = &dev->subdevices[2];
1519	ret = subdev_8255_init(dev, s, NULL,
1520			       devpriv->pacer_counter_dio + DIO_8255);
1521	if (ret)
1522		return ret;
1523
1524	/*  serial EEPROM, */
1525	s = &dev->subdevices[3];
1526	s->type = COMEDI_SUBD_MEMORY;
1527	s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1528	s->n_chan = 256;
1529	s->maxdata = 0xff;
1530	s->insn_read = eeprom_read_insn;
1531
1532	/*  8800 caldac */
1533	s = &dev->subdevices[4];
1534	s->type = COMEDI_SUBD_CALIB;
1535	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1536	s->n_chan = NUM_CHANNELS_8800;
1537	s->maxdata = 0xff;
1538	s->insn_read = caldac_read_insn;
1539	s->insn_write = caldac_write_insn;
1540	for (i = 0; i < s->n_chan; i++)
1541		caldac_8800_write(dev, i, s->maxdata / 2);
1542
1543	/*  trim potentiometer */
1544	s = &dev->subdevices[5];
1545	s->type = COMEDI_SUBD_CALIB;
1546	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1547	if (thisboard->trimpot == AD7376) {
1548		s->n_chan = NUM_CHANNELS_7376;
1549		s->maxdata = 0x7f;
1550	} else {
1551		s->n_chan = NUM_CHANNELS_8402;
1552		s->maxdata = 0xff;
1553	}
1554	s->insn_read = trimpot_read_insn;
1555	s->insn_write = trimpot_write_insn;
1556	for (i = 0; i < s->n_chan; i++)
1557		cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1558
1559	/*  dac08 caldac */
1560	s = &dev->subdevices[6];
1561	if (thisboard->has_dac08) {
1562		s->type = COMEDI_SUBD_CALIB;
1563		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1564		s->n_chan = NUM_CHANNELS_DAC08;
1565		s->insn_read = dac08_read_insn;
1566		s->insn_write = dac08_write_insn;
1567		s->maxdata = 0xff;
1568		dac08_write(dev, s->maxdata / 2);
1569	} else
1570		s->type = COMEDI_SUBD_UNUSED;
1571
1572	/*  make sure mailbox 4 is empty */
1573	inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1574	/* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1575	devpriv->s5933_intcsr_bits =
1576	    INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1577	    INTCSR_INBOX_FULL_INT;
1578	/*  clear and enable interrupt on amcc s5933 */
1579	outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1580	     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1581
1582	dev_info(dev->class_dev, "%s: %s attached\n",
1583		dev->driver->driver_name, dev->board_name);
1584
1585	return 0;
1586}
1587
1588static void cb_pcidas_detach(struct comedi_device *dev)
1589{
1590	struct cb_pcidas_private *devpriv = dev->private;
1591
1592	if (devpriv) {
1593		if (devpriv->s5933_config) {
1594			outl(INTCSR_INBOX_INTR_STATUS,
1595			     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1596		}
1597	}
1598	if (dev->irq)
1599		free_irq(dev->irq, dev);
1600	comedi_pci_disable(dev);
1601}
1602
1603static struct comedi_driver cb_pcidas_driver = {
1604	.driver_name	= "cb_pcidas",
1605	.module		= THIS_MODULE,
1606	.auto_attach	= cb_pcidas_auto_attach,
1607	.detach		= cb_pcidas_detach,
1608};
1609
1610static int cb_pcidas_pci_probe(struct pci_dev *dev,
1611			       const struct pci_device_id *id)
1612{
1613	return comedi_pci_auto_config(dev, &cb_pcidas_driver,
1614				      id->driver_data);
1615}
1616
1617static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
1618	{ PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
1619	{ PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
1620	{ PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
1621	{ PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
1622	{ PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
1623	{ PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
1624	{ PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
1625	{ PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
1626	{ 0 }
1627};
1628MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1629
1630static struct pci_driver cb_pcidas_pci_driver = {
1631	.name		= "cb_pcidas",
1632	.id_table	= cb_pcidas_pci_table,
1633	.probe		= cb_pcidas_pci_probe,
1634	.remove		= comedi_pci_auto_unconfig,
1635};
1636module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1637
1638MODULE_AUTHOR("Comedi http://www.comedi.org");
1639MODULE_DESCRIPTION("Comedi low-level driver");
1640MODULE_LICENSE("GPL");
1641