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