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