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