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