das1800.c revision 0bdab509bf9c6d838dc0a3b1d68bbf841fc20b5a
1/*
2    comedi/drivers/das1800.c
3    Driver for Keitley das1700/das1800 series boards
4    Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
5
6    COMEDI - Linux Control and Measurement Device Interface
7    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18*/
19/*
20Driver: das1800
21Description: Keithley Metrabyte DAS1800 (& compatibles)
22Author: Frank Mori Hess <fmhess@users.sourceforge.net>
23Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
24  DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
25  DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
26  DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
27  DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
28  DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
29  DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
30  DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
31  DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
32  DAS-1802AO (das-1802ao)
33Status: works
34
35The waveform analog output on the 'ao' cards is not supported.
36If you need it, send me (Frank Hess) an email.
37
38Configuration options:
39  [0] - I/O port base address
40  [1] - IRQ (optional, required for timed or externally triggered conversions)
41  [2] - DMA0 (optional, requires irq)
42  [3] - DMA1 (optional, requires irq and dma0)
43*/
44/*
45
46This driver supports the following Keithley boards:
47
48das-1701st
49das-1701st-da
50das-1701ao
51das-1702st
52das-1702st-da
53das-1702hr
54das-1702hr-da
55das-1702ao
56das-1801st
57das-1801st-da
58das-1801hc
59das-1801ao
60das-1802st
61das-1802st-da
62das-1802hr
63das-1802hr-da
64das-1802hc
65das-1802ao
66
67Options:
68	[0] - base io address
69	[1] - irq (optional, required for timed or externally triggered conversions)
70	[2] - dma0 (optional, requires irq)
71	[3] - dma1 (optional, requires irq and dma0)
72
73irq can be omitted, although the cmd interface will not work without it.
74
75analog input cmd triggers supported:
76	start_src:      TRIG_NOW | TRIG_EXT
77	scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT
78	scan_end_src:   TRIG_COUNT
79	convert_src:    TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW)
80	stop_src:       TRIG_COUNT | TRIG_EXT | TRIG_NONE
81
82scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's
83'burst mode' which limits the valid conversion time to 64 microseconds
84(convert_arg <= 64000).  This limitation does not apply if scan_begin_src
85is TRIG_FOLLOW.
86
87NOTES:
88Only the DAS-1801ST has been tested by me.
89Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
90
91TODO:
92	Make it automatically allocate irq and dma channels if they are not specified
93	Add support for analog out on 'ao' cards
94	read insn for analog out
95*/
96
97#include <linux/interrupt.h>
98#include <linux/slab.h>
99#include <linux/io.h>
100#include "../comedidev.h"
101
102#include <linux/ioport.h>
103#include <asm/dma.h>
104
105#include "8253.h"
106#include "comedi_fc.h"
107
108/* misc. defines */
109#define DAS1800_SIZE           16	/* uses 16 io addresses */
110#define FIFO_SIZE              1024	/*  1024 sample fifo */
111#define TIMER_BASE             200	/*  5 Mhz master clock */
112#define UNIPOLAR               0x4	/*  bit that determines whether input range is uni/bipolar */
113#define DMA_BUF_SIZE           0x1ff00	/*  size in bytes of dma buffers */
114
115/* Registers for the das1800 */
116#define DAS1800_FIFO            0x0
117#define DAS1800_QRAM            0x0
118#define DAS1800_DAC             0x0
119#define DAS1800_SELECT          0x2
120#define   ADC                     0x0
121#define   QRAM                    0x1
122#define   DAC(a)                  (0x2 + a)
123#define DAS1800_DIGITAL         0x3
124#define DAS1800_CONTROL_A       0x4
125#define   FFEN                    0x1
126#define   CGEN                    0x4
127#define   CGSL                    0x8
128#define   TGEN                    0x10
129#define   TGSL                    0x20
130#define   ATEN                    0x80
131#define DAS1800_CONTROL_B       0x5
132#define   DMA_CH5                 0x1
133#define   DMA_CH6                 0x2
134#define   DMA_CH7                 0x3
135#define   DMA_CH5_CH6             0x5
136#define   DMA_CH6_CH7             0x6
137#define   DMA_CH7_CH5             0x7
138#define   DMA_ENABLED             0x3	/* mask used to determine if dma is enabled */
139#define   DMA_DUAL                0x4
140#define   IRQ3                    0x8
141#define   IRQ5                    0x10
142#define   IRQ7                    0x18
143#define   IRQ10                   0x28
144#define   IRQ11                   0x30
145#define   IRQ15                   0x38
146#define   FIMD                    0x40
147#define DAS1800_CONTROL_C       0X6
148#define   IPCLK                   0x1
149#define   XPCLK                   0x3
150#define   BMDE                    0x4
151#define   CMEN                    0x8
152#define   UQEN                    0x10
153#define   SD                      0x40
154#define   UB                      0x80
155#define DAS1800_STATUS          0x7
156/* bits that prevent interrupt status bits (and CVEN) from being cleared on write */
157#define   CLEAR_INTR_MASK         (CVEN_MASK | 0x1f)
158#define   INT                     0x1
159#define   DMATC                   0x2
160#define   CT0TC                   0x8
161#define   OVF                     0x10
162#define   FHF                     0x20
163#define   FNE                     0x40
164#define   CVEN_MASK               0x40	/*  masks CVEN on write */
165#define   CVEN                    0x80
166#define DAS1800_BURST_LENGTH    0x8
167#define DAS1800_BURST_RATE      0x9
168#define DAS1800_QRAM_ADDRESS    0xa
169#define DAS1800_COUNTER         0xc
170
171#define IOBASE2                   0x400	/* offset of additional ioports used on 'ao' cards */
172
173enum {
174	das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
175	das1702hr_da,
176	das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
177	das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
178};
179
180/* analog input ranges */
181static const struct comedi_lrange range_ai_das1801 = {
182	8,
183	{
184	 RANGE(-5, 5),
185	 RANGE(-1, 1),
186	 RANGE(-0.1, 0.1),
187	 RANGE(-0.02, 0.02),
188	 RANGE(0, 5),
189	 RANGE(0, 1),
190	 RANGE(0, 0.1),
191	 RANGE(0, 0.02),
192	 }
193};
194
195static const struct comedi_lrange range_ai_das1802 = {
196	8,
197	{
198	 RANGE(-10, 10),
199	 RANGE(-5, 5),
200	 RANGE(-2.5, 2.5),
201	 RANGE(-1.25, 1.25),
202	 RANGE(0, 10),
203	 RANGE(0, 5),
204	 RANGE(0, 2.5),
205	 RANGE(0, 1.25),
206	 }
207};
208
209struct das1800_board {
210	const char *name;
211	int ai_speed;		/* max conversion period in nanoseconds */
212	int resolution;		/* bits of ai resolution */
213	int qram_len;		/* length of card's channel / gain queue */
214	int common;		/* supports AREF_COMMON flag */
215	int do_n_chan;		/* number of digital output channels */
216	int ao_ability;		/* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
217	int ao_n_chan;		/* number of analog out channels */
218	const struct comedi_lrange *range_ai;	/* available input ranges */
219};
220
221/* Warning: the maximum conversion speeds listed below are
222 * not always achievable depending on board setup (see
223 * user manual.)
224 */
225static const struct das1800_board das1800_boards[] = {
226	{
227	 .name = "das-1701st",
228	 .ai_speed = 6250,
229	 .resolution = 12,
230	 .qram_len = 256,
231	 .common = 1,
232	 .do_n_chan = 4,
233	 .ao_ability = 0,
234	 .ao_n_chan = 0,
235	 .range_ai = &range_ai_das1801,
236	 },
237	{
238	 .name = "das-1701st-da",
239	 .ai_speed = 6250,
240	 .resolution = 12,
241	 .qram_len = 256,
242	 .common = 1,
243	 .do_n_chan = 4,
244	 .ao_ability = 1,
245	 .ao_n_chan = 4,
246	 .range_ai = &range_ai_das1801,
247	 },
248	{
249	 .name = "das-1702st",
250	 .ai_speed = 6250,
251	 .resolution = 12,
252	 .qram_len = 256,
253	 .common = 1,
254	 .do_n_chan = 4,
255	 .ao_ability = 0,
256	 .ao_n_chan = 0,
257	 .range_ai = &range_ai_das1802,
258	 },
259	{
260	 .name = "das-1702st-da",
261	 .ai_speed = 6250,
262	 .resolution = 12,
263	 .qram_len = 256,
264	 .common = 1,
265	 .do_n_chan = 4,
266	 .ao_ability = 1,
267	 .ao_n_chan = 4,
268	 .range_ai = &range_ai_das1802,
269	 },
270	{
271	 .name = "das-1702hr",
272	 .ai_speed = 20000,
273	 .resolution = 16,
274	 .qram_len = 256,
275	 .common = 1,
276	 .do_n_chan = 4,
277	 .ao_ability = 0,
278	 .ao_n_chan = 0,
279	 .range_ai = &range_ai_das1802,
280	 },
281	{
282	 .name = "das-1702hr-da",
283	 .ai_speed = 20000,
284	 .resolution = 16,
285	 .qram_len = 256,
286	 .common = 1,
287	 .do_n_chan = 4,
288	 .ao_ability = 1,
289	 .ao_n_chan = 2,
290	 .range_ai = &range_ai_das1802,
291	 },
292	{
293	 .name = "das-1701ao",
294	 .ai_speed = 6250,
295	 .resolution = 12,
296	 .qram_len = 256,
297	 .common = 1,
298	 .do_n_chan = 4,
299	 .ao_ability = 2,
300	 .ao_n_chan = 2,
301	 .range_ai = &range_ai_das1801,
302	 },
303	{
304	 .name = "das-1702ao",
305	 .ai_speed = 6250,
306	 .resolution = 12,
307	 .qram_len = 256,
308	 .common = 1,
309	 .do_n_chan = 4,
310	 .ao_ability = 2,
311	 .ao_n_chan = 2,
312	 .range_ai = &range_ai_das1802,
313	 },
314	{
315	 .name = "das-1801st",
316	 .ai_speed = 3000,
317	 .resolution = 12,
318	 .qram_len = 256,
319	 .common = 1,
320	 .do_n_chan = 4,
321	 .ao_ability = 0,
322	 .ao_n_chan = 0,
323	 .range_ai = &range_ai_das1801,
324	 },
325	{
326	 .name = "das-1801st-da",
327	 .ai_speed = 3000,
328	 .resolution = 12,
329	 .qram_len = 256,
330	 .common = 1,
331	 .do_n_chan = 4,
332	 .ao_ability = 0,
333	 .ao_n_chan = 4,
334	 .range_ai = &range_ai_das1801,
335	 },
336	{
337	 .name = "das-1802st",
338	 .ai_speed = 3000,
339	 .resolution = 12,
340	 .qram_len = 256,
341	 .common = 1,
342	 .do_n_chan = 4,
343	 .ao_ability = 0,
344	 .ao_n_chan = 0,
345	 .range_ai = &range_ai_das1802,
346	 },
347	{
348	 .name = "das-1802st-da",
349	 .ai_speed = 3000,
350	 .resolution = 12,
351	 .qram_len = 256,
352	 .common = 1,
353	 .do_n_chan = 4,
354	 .ao_ability = 1,
355	 .ao_n_chan = 4,
356	 .range_ai = &range_ai_das1802,
357	 },
358	{
359	 .name = "das-1802hr",
360	 .ai_speed = 10000,
361	 .resolution = 16,
362	 .qram_len = 256,
363	 .common = 1,
364	 .do_n_chan = 4,
365	 .ao_ability = 0,
366	 .ao_n_chan = 0,
367	 .range_ai = &range_ai_das1802,
368	 },
369	{
370	 .name = "das-1802hr-da",
371	 .ai_speed = 10000,
372	 .resolution = 16,
373	 .qram_len = 256,
374	 .common = 1,
375	 .do_n_chan = 4,
376	 .ao_ability = 1,
377	 .ao_n_chan = 2,
378	 .range_ai = &range_ai_das1802,
379	 },
380	{
381	 .name = "das-1801hc",
382	 .ai_speed = 3000,
383	 .resolution = 12,
384	 .qram_len = 64,
385	 .common = 0,
386	 .do_n_chan = 8,
387	 .ao_ability = 1,
388	 .ao_n_chan = 2,
389	 .range_ai = &range_ai_das1801,
390	 },
391	{
392	 .name = "das-1802hc",
393	 .ai_speed = 3000,
394	 .resolution = 12,
395	 .qram_len = 64,
396	 .common = 0,
397	 .do_n_chan = 8,
398	 .ao_ability = 1,
399	 .ao_n_chan = 2,
400	 .range_ai = &range_ai_das1802,
401	 },
402	{
403	 .name = "das-1801ao",
404	 .ai_speed = 3000,
405	 .resolution = 12,
406	 .qram_len = 256,
407	 .common = 1,
408	 .do_n_chan = 4,
409	 .ao_ability = 2,
410	 .ao_n_chan = 2,
411	 .range_ai = &range_ai_das1801,
412	 },
413	{
414	 .name = "das-1802ao",
415	 .ai_speed = 3000,
416	 .resolution = 12,
417	 .qram_len = 256,
418	 .common = 1,
419	 .do_n_chan = 4,
420	 .ao_ability = 2,
421	 .ao_n_chan = 2,
422	 .range_ai = &range_ai_das1802,
423	 },
424};
425
426struct das1800_private {
427	volatile unsigned int count;	/* number of data points left to be taken */
428	unsigned int divisor1;	/* value to load into board's counter 1 for timed conversions */
429	unsigned int divisor2;	/* value to load into board's counter 2 for timed conversions */
430	int do_bits;		/* digital output bits */
431	int irq_dma_bits;	/* bits for control register b */
432	/* dma bits for control register b, stored so that dma can be
433	 * turned on and off */
434	int dma_bits;
435	unsigned int dma0;	/* dma channels used */
436	unsigned int dma1;
437	volatile unsigned int dma_current;	/* dma channel currently in use */
438	uint16_t *ai_buf0;	/* pointers to dma buffers */
439	uint16_t *ai_buf1;
440	uint16_t *dma_current_buf;	/* pointer to dma buffer currently being used */
441	unsigned int dma_transfer_size;	/* size of transfer currently used, in bytes */
442	unsigned long iobase2;	/* secondary io address used for analog out on 'ao' boards */
443	short ao_update_bits;	/* remembers the last write to the 'update' dac */
444};
445
446/* analog out range for 'ao' boards */
447/*
448static const struct comedi_lrange range_ao_2 = {
449	2,
450	{
451		RANGE(-10, 10),
452		RANGE(-5, 5),
453	}
454};
455*/
456
457static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
458					    uint16_t sample)
459{
460	const struct das1800_board *thisboard = comedi_board(dev);
461
462	sample += 1 << (thisboard->resolution - 1);
463	return sample;
464}
465
466static void munge_data(struct comedi_device *dev, uint16_t * array,
467		       unsigned int num_elements)
468{
469	unsigned int i;
470	int unipolar;
471
472	/* see if card is using a unipolar or bipolar range so we can munge data correctly */
473	unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
474
475	/* convert to unsigned type if we are in a bipolar mode */
476	if (!unipolar) {
477		for (i = 0; i < num_elements; i++)
478			array[i] = munge_bipolar_sample(dev, array[i]);
479	}
480}
481
482static void das1800_handle_fifo_half_full(struct comedi_device *dev,
483					  struct comedi_subdevice *s)
484{
485	struct das1800_private *devpriv = dev->private;
486	int numPoints = 0;	/* number of points to read */
487	struct comedi_cmd *cmd = &s->async->cmd;
488
489	numPoints = FIFO_SIZE / 2;
490	/* if we only need some of the points */
491	if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
492		numPoints = devpriv->count;
493	insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
494	munge_data(dev, devpriv->ai_buf0, numPoints);
495	cfc_write_array_to_buffer(s, devpriv->ai_buf0,
496				  numPoints * sizeof(devpriv->ai_buf0[0]));
497	if (cmd->stop_src == TRIG_COUNT)
498		devpriv->count -= numPoints;
499	return;
500}
501
502static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
503					  struct comedi_subdevice *s)
504{
505	struct das1800_private *devpriv = dev->private;
506	short dpnt;
507	int unipolar;
508	struct comedi_cmd *cmd = &s->async->cmd;
509
510	unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
511
512	while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
513		if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
514			break;
515		dpnt = inw(dev->iobase + DAS1800_FIFO);
516		/* convert to unsigned type if we are in a bipolar mode */
517		if (!unipolar)
518			;
519		dpnt = munge_bipolar_sample(dev, dpnt);
520		cfc_write_to_buffer(s, dpnt);
521		if (cmd->stop_src == TRIG_COUNT)
522			devpriv->count--;
523	}
524
525	return;
526}
527
528/* Utility function used by das1800_flush_dma() and das1800_handle_dma().
529 * Assumes dma lock is held */
530static void das1800_flush_dma_channel(struct comedi_device *dev,
531				      struct comedi_subdevice *s,
532				      unsigned int channel, uint16_t *buffer)
533{
534	struct das1800_private *devpriv = dev->private;
535	unsigned int num_bytes, num_samples;
536	struct comedi_cmd *cmd = &s->async->cmd;
537
538	disable_dma(channel);
539
540	/* clear flip-flop to make sure 2-byte registers
541	 * get set correctly */
542	clear_dma_ff(channel);
543
544	/*  figure out how many points to read */
545	num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
546	num_samples = num_bytes / sizeof(short);
547
548	/* if we only need some of the points */
549	if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
550		num_samples = devpriv->count;
551
552	munge_data(dev, buffer, num_samples);
553	cfc_write_array_to_buffer(s, buffer, num_bytes);
554	if (s->async->cmd.stop_src == TRIG_COUNT)
555		devpriv->count -= num_samples;
556
557	return;
558}
559
560/* flushes remaining data from board when external trigger has stopped acquisition
561 * and we are using dma transfers */
562static void das1800_flush_dma(struct comedi_device *dev,
563			      struct comedi_subdevice *s)
564{
565	struct das1800_private *devpriv = dev->private;
566	unsigned long flags;
567	const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
568
569	flags = claim_dma_lock();
570	das1800_flush_dma_channel(dev, s, devpriv->dma_current,
571				  devpriv->dma_current_buf);
572
573	if (dual_dma) {
574		/*  switch to other channel and flush it */
575		if (devpriv->dma_current == devpriv->dma0) {
576			devpriv->dma_current = devpriv->dma1;
577			devpriv->dma_current_buf = devpriv->ai_buf1;
578		} else {
579			devpriv->dma_current = devpriv->dma0;
580			devpriv->dma_current_buf = devpriv->ai_buf0;
581		}
582		das1800_flush_dma_channel(dev, s, devpriv->dma_current,
583					  devpriv->dma_current_buf);
584	}
585
586	release_dma_lock(flags);
587
588	/*  get any remaining samples in fifo */
589	das1800_handle_fifo_not_empty(dev, s);
590
591	return;
592}
593
594static void das1800_handle_dma(struct comedi_device *dev,
595			       struct comedi_subdevice *s, unsigned int status)
596{
597	struct das1800_private *devpriv = dev->private;
598	unsigned long flags;
599	const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
600
601	flags = claim_dma_lock();
602	das1800_flush_dma_channel(dev, s, devpriv->dma_current,
603				  devpriv->dma_current_buf);
604	/*  re-enable  dma channel */
605	set_dma_addr(devpriv->dma_current,
606		     virt_to_bus(devpriv->dma_current_buf));
607	set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
608	enable_dma(devpriv->dma_current);
609	release_dma_lock(flags);
610
611	if (status & DMATC) {
612		/*  clear DMATC interrupt bit */
613		outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
614		/*  switch dma channels for next time, if appropriate */
615		if (dual_dma) {
616			/*  read data from the other channel next time */
617			if (devpriv->dma_current == devpriv->dma0) {
618				devpriv->dma_current = devpriv->dma1;
619				devpriv->dma_current_buf = devpriv->ai_buf1;
620			} else {
621				devpriv->dma_current = devpriv->dma0;
622				devpriv->dma_current_buf = devpriv->ai_buf0;
623			}
624		}
625	}
626
627	return;
628}
629
630static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
631{
632	struct das1800_private *devpriv = dev->private;
633
634	outb(0x0, dev->iobase + DAS1800_STATUS);	/* disable conversions */
635	outb(0x0, dev->iobase + DAS1800_CONTROL_B);	/* disable interrupts and dma */
636	outb(0x0, dev->iobase + DAS1800_CONTROL_A);	/* disable and clear fifo and stop triggering */
637	if (devpriv->dma0)
638		disable_dma(devpriv->dma0);
639	if (devpriv->dma1)
640		disable_dma(devpriv->dma1);
641	return 0;
642}
643
644/* the guts of the interrupt handler, that is shared with das1800_ai_poll */
645static void das1800_ai_handler(struct comedi_device *dev)
646{
647	struct das1800_private *devpriv = dev->private;
648	struct comedi_subdevice *s = &dev->subdevices[0];
649	struct comedi_async *async = s->async;
650	struct comedi_cmd *cmd = &async->cmd;
651	unsigned int status = inb(dev->iobase + DAS1800_STATUS);
652
653	async->events = 0;
654	/*  select adc for base address + 0 */
655	outb(ADC, dev->iobase + DAS1800_SELECT);
656	/*  dma buffer full */
657	if (devpriv->irq_dma_bits & DMA_ENABLED) {
658		/*  look for data from dma transfer even if dma terminal count hasn't happened yet */
659		das1800_handle_dma(dev, s, status);
660	} else if (status & FHF) {	/*  if fifo half full */
661		das1800_handle_fifo_half_full(dev, s);
662	} else if (status & FNE) {	/*  if fifo not empty */
663		das1800_handle_fifo_not_empty(dev, s);
664	}
665
666	async->events |= COMEDI_CB_BLOCK;
667	/* if the card's fifo has overflowed */
668	if (status & OVF) {
669		/*  clear OVF interrupt bit */
670		outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
671		comedi_error(dev, "DAS1800 FIFO overflow");
672		das1800_cancel(dev, s);
673		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
674		comedi_event(dev, s);
675		return;
676	}
677	/*  stop taking data if appropriate */
678	/* stop_src TRIG_EXT */
679	if (status & CT0TC) {
680		/*  clear CT0TC interrupt bit */
681		outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
682		/*  make sure we get all remaining data from board before quitting */
683		if (devpriv->irq_dma_bits & DMA_ENABLED)
684			das1800_flush_dma(dev, s);
685		else
686			das1800_handle_fifo_not_empty(dev, s);
687		das1800_cancel(dev, s);	/* disable hardware conversions */
688		async->events |= COMEDI_CB_EOA;
689	} else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) {	/*  stop_src TRIG_COUNT */
690		das1800_cancel(dev, s);	/* disable hardware conversions */
691		async->events |= COMEDI_CB_EOA;
692	}
693
694	comedi_event(dev, s);
695
696	return;
697}
698
699static int das1800_ai_poll(struct comedi_device *dev,
700			   struct comedi_subdevice *s)
701{
702	unsigned long flags;
703
704	/*  prevent race with interrupt handler */
705	spin_lock_irqsave(&dev->spinlock, flags);
706	das1800_ai_handler(dev);
707	spin_unlock_irqrestore(&dev->spinlock, flags);
708
709	return s->async->buf_write_count - s->async->buf_read_count;
710}
711
712static irqreturn_t das1800_interrupt(int irq, void *d)
713{
714	struct comedi_device *dev = d;
715	unsigned int status;
716
717	if (!dev->attached) {
718		comedi_error(dev, "premature interrupt");
719		return IRQ_HANDLED;
720	}
721
722	/* Prevent race with das1800_ai_poll() on multi processor systems.
723	 * Also protects indirect addressing in das1800_ai_handler */
724	spin_lock(&dev->spinlock);
725	status = inb(dev->iobase + DAS1800_STATUS);
726
727	/* if interrupt was not caused by das-1800 */
728	if (!(status & INT)) {
729		spin_unlock(&dev->spinlock);
730		return IRQ_NONE;
731	}
732	/* clear the interrupt status bit INT */
733	outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
734	/*  handle interrupt */
735	das1800_ai_handler(dev);
736
737	spin_unlock(&dev->spinlock);
738	return IRQ_HANDLED;
739}
740
741/* converts requested conversion timing to timing compatible with
742 * hardware, used only when card is in 'burst mode'
743 */
744static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
745{
746	unsigned int micro_sec;
747
748	/*  in burst mode, the maximum conversion time is 64 microseconds */
749	if (convert_arg > 64000)
750		convert_arg = 64000;
751
752	/*  the conversion time must be an integral number of microseconds */
753	switch (round_mode) {
754	case TRIG_ROUND_NEAREST:
755	default:
756		micro_sec = (convert_arg + 500) / 1000;
757		break;
758	case TRIG_ROUND_DOWN:
759		micro_sec = convert_arg / 1000;
760		break;
761	case TRIG_ROUND_UP:
762		micro_sec = (convert_arg - 1) / 1000 + 1;
763		break;
764	}
765
766	/*  return number of nanoseconds */
767	return micro_sec * 1000;
768}
769
770/* test analog input cmd */
771static int das1800_ai_do_cmdtest(struct comedi_device *dev,
772				 struct comedi_subdevice *s,
773				 struct comedi_cmd *cmd)
774{
775	const struct das1800_board *thisboard = comedi_board(dev);
776	struct das1800_private *devpriv = dev->private;
777	int err = 0;
778	unsigned int tmp_arg;
779	int i;
780	int unipolar;
781
782	/* Step 1 : check if triggers are trivially valid */
783
784	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
785	err |= cfc_check_trigger_src(&cmd->scan_begin_src,
786					TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
787	err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
788	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
789	err |= cfc_check_trigger_src(&cmd->stop_src,
790					TRIG_COUNT | TRIG_EXT | TRIG_NONE);
791
792	if (err)
793		return 1;
794
795	/* Step 2a : make sure trigger sources are unique */
796
797	err |= cfc_check_trigger_is_unique(cmd->start_src);
798	err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
799	err |= cfc_check_trigger_is_unique(cmd->convert_src);
800	err |= cfc_check_trigger_is_unique(cmd->stop_src);
801
802	/* Step 2b : and mutually compatible */
803
804	if (cmd->scan_begin_src != TRIG_FOLLOW &&
805	    cmd->convert_src != TRIG_TIMER)
806		err |= -EINVAL;
807
808	if (err)
809		return 2;
810
811	/* Step 3: check if arguments are trivially valid */
812
813	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
814
815	if (cmd->convert_src == TRIG_TIMER)
816		err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
817						 thisboard->ai_speed);
818
819	err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
820	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
821
822	switch (cmd->stop_src) {
823	case TRIG_COUNT:
824		err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
825		break;
826	case TRIG_NONE:
827		err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
828		break;
829	default:
830		break;
831	}
832
833	if (err)
834		return 3;
835
836	/* step 4: fix up any arguments */
837
838	if (cmd->convert_src == TRIG_TIMER) {
839		/*  if we are not in burst mode */
840		if (cmd->scan_begin_src == TRIG_FOLLOW) {
841			tmp_arg = cmd->convert_arg;
842			/* calculate counter values that give desired timing */
843			i8253_cascade_ns_to_timer_2div(TIMER_BASE,
844						       &(devpriv->divisor1),
845						       &(devpriv->divisor2),
846						       &(cmd->convert_arg),
847						       cmd->
848						       flags & TRIG_ROUND_MASK);
849			if (tmp_arg != cmd->convert_arg)
850				err++;
851		}
852		/*  if we are in burst mode */
853		else {
854			/*  check that convert_arg is compatible */
855			tmp_arg = cmd->convert_arg;
856			cmd->convert_arg =
857			    burst_convert_arg(cmd->convert_arg,
858					      cmd->flags & TRIG_ROUND_MASK);
859			if (tmp_arg != cmd->convert_arg)
860				err++;
861
862			if (cmd->scan_begin_src == TRIG_TIMER) {
863				/*  if scans are timed faster than conversion rate allows */
864				if (cmd->convert_arg * cmd->chanlist_len >
865				    cmd->scan_begin_arg) {
866					cmd->scan_begin_arg =
867					    cmd->convert_arg *
868					    cmd->chanlist_len;
869					err++;
870				}
871				tmp_arg = cmd->scan_begin_arg;
872				/* calculate counter values that give desired timing */
873				i8253_cascade_ns_to_timer_2div(TIMER_BASE,
874							       &(devpriv->
875								 divisor1),
876							       &(devpriv->
877								 divisor2),
878							       &(cmd->
879								 scan_begin_arg),
880							       cmd->
881							       flags &
882							       TRIG_ROUND_MASK);
883				if (tmp_arg != cmd->scan_begin_arg)
884					err++;
885			}
886		}
887	}
888
889	if (err)
890		return 4;
891
892	/*  make sure user is not trying to mix unipolar and bipolar ranges */
893	if (cmd->chanlist) {
894		unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
895		for (i = 1; i < cmd->chanlist_len; i++) {
896			if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
897				comedi_error(dev,
898					     "unipolar and bipolar ranges cannot be mixed in the chanlist");
899				err++;
900				break;
901			}
902		}
903	}
904
905	if (err)
906		return 5;
907
908	return 0;
909}
910
911/* returns appropriate bits for control register a, depending on command */
912static int control_a_bits(const struct comedi_cmd *cmd)
913{
914	int control_a;
915
916	control_a = FFEN;	/* enable fifo */
917	if (cmd->stop_src == TRIG_EXT)
918		control_a |= ATEN;
919	switch (cmd->start_src) {
920	case TRIG_EXT:
921		control_a |= TGEN | CGSL;
922		break;
923	case TRIG_NOW:
924		control_a |= CGEN;
925		break;
926	default:
927		break;
928	}
929
930	return control_a;
931}
932
933/* returns appropriate bits for control register c, depending on command */
934static int control_c_bits(const struct comedi_cmd *cmd)
935{
936	int control_c;
937	int aref;
938
939	/* set clock source to internal or external, select analog reference,
940	 * select unipolar / bipolar
941	 */
942	aref = CR_AREF(cmd->chanlist[0]);
943	control_c = UQEN;	/* enable upper qram addresses */
944	if (aref != AREF_DIFF)
945		control_c |= SD;
946	if (aref == AREF_COMMON)
947		control_c |= CMEN;
948	/* if a unipolar range was selected */
949	if (CR_RANGE(cmd->chanlist[0]) & UNIPOLAR)
950		control_c |= UB;
951	switch (cmd->scan_begin_src) {
952	case TRIG_FOLLOW:	/*  not in burst mode */
953		switch (cmd->convert_src) {
954		case TRIG_TIMER:
955			/* trig on cascaded counters */
956			control_c |= IPCLK;
957			break;
958		case TRIG_EXT:
959			/* trig on falling edge of external trigger */
960			control_c |= XPCLK;
961			break;
962		default:
963			break;
964		}
965		break;
966	case TRIG_TIMER:
967		/*  burst mode with internal pacer clock */
968		control_c |= BMDE | IPCLK;
969		break;
970	case TRIG_EXT:
971		/*  burst mode with external trigger */
972		control_c |= BMDE | XPCLK;
973		break;
974	default:
975		break;
976	}
977
978	return control_c;
979}
980
981/* loads counters with divisor1, divisor2 from private structure */
982static int das1800_set_frequency(struct comedi_device *dev)
983{
984	struct das1800_private *devpriv = dev->private;
985	int err = 0;
986
987	/*  counter 1, mode 2 */
988	if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
989		       2))
990		err++;
991	/*  counter 2, mode 2 */
992	if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
993		       2))
994		err++;
995	if (err)
996		return -1;
997
998	return 0;
999}
1000
1001/* sets up counters */
1002static int setup_counters(struct comedi_device *dev,
1003			  const struct comedi_cmd *cmd)
1004{
1005	struct das1800_private *devpriv = dev->private;
1006	unsigned int period;
1007
1008	/*  setup cascaded counters for conversion/scan frequency */
1009	switch (cmd->scan_begin_src) {
1010	case TRIG_FOLLOW:	/*  not in burst mode */
1011		if (cmd->convert_src == TRIG_TIMER) {
1012			/* set conversion frequency */
1013			period = cmd->convert_arg;
1014			i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1015						       &devpriv->divisor1,
1016						       &devpriv->divisor2,
1017						       &period,
1018						       cmd->flags &
1019							TRIG_ROUND_MASK);
1020			if (das1800_set_frequency(dev) < 0)
1021				return -1;
1022		}
1023		break;
1024	case TRIG_TIMER:	/*  in burst mode */
1025		/* set scan frequency */
1026		period = cmd->scan_begin_arg;
1027		i8253_cascade_ns_to_timer_2div(TIMER_BASE, &devpriv->divisor1,
1028					       &devpriv->divisor2, &period,
1029					       cmd->flags & TRIG_ROUND_MASK);
1030		if (das1800_set_frequency(dev) < 0)
1031			return -1;
1032		break;
1033	default:
1034		break;
1035	}
1036
1037	/*  setup counter 0 for 'about triggering' */
1038	if (cmd->stop_src == TRIG_EXT) {
1039		/*  load counter 0 in mode 0 */
1040		i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
1041	}
1042
1043	return 0;
1044}
1045
1046/* utility function that suggests a dma transfer size based on the conversion period 'ns' */
1047static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd)
1048{
1049	unsigned int size = DMA_BUF_SIZE;
1050	static const int sample_size = 2;	/*  size in bytes of one sample from board */
1051	unsigned int fill_time = 300000000;	/*  target time in nanoseconds for filling dma buffer */
1052	unsigned int max_size;	/*  maximum size we will allow for a transfer */
1053
1054	/*  make dma buffer fill in 0.3 seconds for timed modes */
1055	switch (cmd->scan_begin_src) {
1056	case TRIG_FOLLOW:	/*  not in burst mode */
1057		if (cmd->convert_src == TRIG_TIMER)
1058			size = (fill_time / cmd->convert_arg) * sample_size;
1059		break;
1060	case TRIG_TIMER:
1061		size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
1062		    sample_size;
1063		break;
1064	default:
1065		size = DMA_BUF_SIZE;
1066		break;
1067	}
1068
1069	/*  set a minimum and maximum size allowed */
1070	max_size = DMA_BUF_SIZE;
1071	/*  if we are taking limited number of conversions, limit transfer size to that */
1072	if (cmd->stop_src == TRIG_COUNT &&
1073	    cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
1074		max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
1075
1076	if (size > max_size)
1077		size = max_size;
1078	if (size < sample_size)
1079		size = sample_size;
1080
1081	return size;
1082}
1083
1084/* sets up dma */
1085static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
1086{
1087	struct das1800_private *devpriv = dev->private;
1088	unsigned long lock_flags;
1089	const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1090
1091	if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1092		return;
1093
1094	/* determine a reasonable dma transfer size */
1095	devpriv->dma_transfer_size = suggest_transfer_size(cmd);
1096	lock_flags = claim_dma_lock();
1097	disable_dma(devpriv->dma0);
1098	/* clear flip-flop to make sure 2-byte registers for
1099	 * count and address get set correctly */
1100	clear_dma_ff(devpriv->dma0);
1101	set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
1102	/*  set appropriate size of transfer */
1103	set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
1104	devpriv->dma_current = devpriv->dma0;
1105	devpriv->dma_current_buf = devpriv->ai_buf0;
1106	enable_dma(devpriv->dma0);
1107	/*  set up dual dma if appropriate */
1108	if (dual_dma) {
1109		disable_dma(devpriv->dma1);
1110		/* clear flip-flop to make sure 2-byte registers for
1111		 * count and address get set correctly */
1112		clear_dma_ff(devpriv->dma1);
1113		set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1114		/*  set appropriate size of transfer */
1115		set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1116		enable_dma(devpriv->dma1);
1117	}
1118	release_dma_lock(lock_flags);
1119
1120	return;
1121}
1122
1123/* programs channel/gain list into card */
1124static void program_chanlist(struct comedi_device *dev,
1125			     const struct comedi_cmd *cmd)
1126{
1127	int i, n, chan_range;
1128	unsigned long irq_flags;
1129	const int range_mask = 0x3;	/* masks unipolar/bipolar bit off range */
1130	const int range_bitshift = 8;
1131
1132	n = cmd->chanlist_len;
1133	/*  spinlock protects indirect addressing */
1134	spin_lock_irqsave(&dev->spinlock, irq_flags);
1135	outb(QRAM, dev->iobase + DAS1800_SELECT);	/* select QRAM for baseAddress + 0x0 */
1136	outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS);	/*set QRAM address start */
1137	/* make channel / gain list */
1138	for (i = 0; i < n; i++) {
1139		chan_range =
1140		    CR_CHAN(cmd->chanlist[i]) |
1141		    ((CR_RANGE(cmd->chanlist[i]) & range_mask) <<
1142		     range_bitshift);
1143		outw(chan_range, dev->iobase + DAS1800_QRAM);
1144	}
1145	outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS);	/*finish write to QRAM */
1146	spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1147
1148	return;
1149}
1150
1151/* analog input do_cmd */
1152static int das1800_ai_do_cmd(struct comedi_device *dev,
1153			     struct comedi_subdevice *s)
1154{
1155	struct das1800_private *devpriv = dev->private;
1156	int ret;
1157	int control_a, control_c;
1158	struct comedi_async *async = s->async;
1159	const struct comedi_cmd *cmd = &async->cmd;
1160
1161	if (!dev->irq) {
1162		comedi_error(dev,
1163			     "no irq assigned for das-1800, cannot do hardware conversions");
1164		return -1;
1165	}
1166
1167	/* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1168	 * (because dma in handler is unsafe at hard real-time priority) */
1169	if (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT))
1170		devpriv->irq_dma_bits &= ~DMA_ENABLED;
1171	else
1172		devpriv->irq_dma_bits |= devpriv->dma_bits;
1173	/*  interrupt on end of conversion for TRIG_WAKE_EOS */
1174	if (cmd->flags & TRIG_WAKE_EOS) {
1175		/*  interrupt fifo not empty */
1176		devpriv->irq_dma_bits &= ~FIMD;
1177	} else {
1178		/*  interrupt fifo half full */
1179		devpriv->irq_dma_bits |= FIMD;
1180	}
1181	/*  determine how many conversions we need */
1182	if (cmd->stop_src == TRIG_COUNT)
1183		devpriv->count = cmd->stop_arg * cmd->chanlist_len;
1184
1185	das1800_cancel(dev, s);
1186
1187	/*  determine proper bits for control registers */
1188	control_a = control_a_bits(cmd);
1189	control_c = control_c_bits(cmd);
1190
1191	/* setup card and start */
1192	program_chanlist(dev, cmd);
1193	ret = setup_counters(dev, cmd);
1194	if (ret < 0) {
1195		comedi_error(dev, "Error setting up counters");
1196		return ret;
1197	}
1198	setup_dma(dev, cmd);
1199	outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1200	/*  set conversion rate and length for burst mode */
1201	if (control_c & BMDE) {
1202		/*  program conversion period with number of microseconds minus 1 */
1203		outb(cmd->convert_arg / 1000 - 1,
1204		     dev->iobase + DAS1800_BURST_RATE);
1205		outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
1206	}
1207	outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B);	/*  enable irq/dma */
1208	outb(control_a, dev->iobase + DAS1800_CONTROL_A);	/* enable fifo and triggering */
1209	outb(CVEN, dev->iobase + DAS1800_STATUS);	/* enable conversions */
1210
1211	return 0;
1212}
1213
1214/* read analog input */
1215static int das1800_ai_rinsn(struct comedi_device *dev,
1216			    struct comedi_subdevice *s,
1217			    struct comedi_insn *insn, unsigned int *data)
1218{
1219	const struct das1800_board *thisboard = comedi_board(dev);
1220	int i, n;
1221	int chan, range, aref, chan_range;
1222	int timeout = 1000;
1223	short dpnt;
1224	int conv_flags = 0;
1225	unsigned long irq_flags;
1226
1227	/* set up analog reference and unipolar / bipolar mode */
1228	aref = CR_AREF(insn->chanspec);
1229	conv_flags |= UQEN;
1230	if (aref != AREF_DIFF)
1231		conv_flags |= SD;
1232	if (aref == AREF_COMMON)
1233		conv_flags |= CMEN;
1234	/* if a unipolar range was selected */
1235	if (CR_RANGE(insn->chanspec) & UNIPOLAR)
1236		conv_flags |= UB;
1237
1238	outb(conv_flags, dev->iobase + DAS1800_CONTROL_C);	/* software conversion enabled */
1239	outb(CVEN, dev->iobase + DAS1800_STATUS);	/* enable conversions */
1240	outb(0x0, dev->iobase + DAS1800_CONTROL_A);	/* reset fifo */
1241	outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
1242
1243	chan = CR_CHAN(insn->chanspec);
1244	/* mask of unipolar/bipolar bit from range */
1245	range = CR_RANGE(insn->chanspec) & 0x3;
1246	chan_range = chan | (range << 8);
1247	spin_lock_irqsave(&dev->spinlock, irq_flags);
1248	outb(QRAM, dev->iobase + DAS1800_SELECT);	/* select QRAM for baseAddress + 0x0 */
1249	outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS);	/* set QRAM address start */
1250	outw(chan_range, dev->iobase + DAS1800_QRAM);
1251	outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS);	/*finish write to QRAM */
1252	outb(ADC, dev->iobase + DAS1800_SELECT);	/* select ADC for baseAddress + 0x0 */
1253
1254	for (n = 0; n < insn->n; n++) {
1255		/* trigger conversion */
1256		outb(0, dev->iobase + DAS1800_FIFO);
1257		for (i = 0; i < timeout; i++) {
1258			if (inb(dev->iobase + DAS1800_STATUS) & FNE)
1259				break;
1260		}
1261		if (i == timeout) {
1262			comedi_error(dev, "timeout");
1263			n = -ETIME;
1264			goto exit;
1265		}
1266		dpnt = inw(dev->iobase + DAS1800_FIFO);
1267		/* shift data to offset binary for bipolar ranges */
1268		if ((conv_flags & UB) == 0)
1269			dpnt += 1 << (thisboard->resolution - 1);
1270		data[n] = dpnt;
1271	}
1272exit:
1273	spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1274
1275	return n;
1276}
1277
1278/* writes to an analog output channel */
1279static int das1800_ao_winsn(struct comedi_device *dev,
1280			    struct comedi_subdevice *s,
1281			    struct comedi_insn *insn, unsigned int *data)
1282{
1283	const struct das1800_board *thisboard = comedi_board(dev);
1284	struct das1800_private *devpriv = dev->private;
1285	int chan = CR_CHAN(insn->chanspec);
1286/* int range = CR_RANGE(insn->chanspec); */
1287	int update_chan = thisboard->ao_n_chan - 1;
1288	short output;
1289	unsigned long irq_flags;
1290
1291	/*   card expects two's complement data */
1292	output = data[0] - (1 << (thisboard->resolution - 1));
1293	/*  if the write is to the 'update' channel, we need to remember its value */
1294	if (chan == update_chan)
1295		devpriv->ao_update_bits = output;
1296	/*  write to channel */
1297	spin_lock_irqsave(&dev->spinlock, irq_flags);
1298	outb(DAC(chan), dev->iobase + DAS1800_SELECT);	/* select dac channel for baseAddress + 0x0 */
1299	outw(output, dev->iobase + DAS1800_DAC);
1300	/*  now we need to write to 'update' channel to update all dac channels */
1301	if (chan != update_chan) {
1302		outb(DAC(update_chan), dev->iobase + DAS1800_SELECT);	/* select 'update' channel for baseAddress + 0x0 */
1303		outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1304	}
1305	spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1306
1307	return 1;
1308}
1309
1310/* reads from digital input channels */
1311static int das1800_di_rbits(struct comedi_device *dev,
1312			    struct comedi_subdevice *s,
1313			    struct comedi_insn *insn, unsigned int *data)
1314{
1315
1316	data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1317	data[0] = 0;
1318
1319	return insn->n;
1320}
1321
1322/* writes to digital output channels */
1323static int das1800_do_wbits(struct comedi_device *dev,
1324			    struct comedi_subdevice *s,
1325			    struct comedi_insn *insn, unsigned int *data)
1326{
1327	struct das1800_private *devpriv = dev->private;
1328	unsigned int wbits;
1329
1330	/*  only set bits that have been masked */
1331	data[0] &= (1 << s->n_chan) - 1;
1332	wbits = devpriv->do_bits;
1333	wbits &= ~data[0];
1334	wbits |= data[0] & data[1];
1335	devpriv->do_bits = wbits;
1336
1337	outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1338
1339	data[1] = devpriv->do_bits;
1340
1341	return insn->n;
1342}
1343
1344static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
1345			    unsigned int dma1)
1346{
1347	struct das1800_private *devpriv = dev->private;
1348	unsigned long flags;
1349
1350	/*  need an irq to do dma */
1351	if (dev->irq && dma0) {
1352		/* encode dma0 and dma1 into 2 digit hexadecimal for switch */
1353		switch ((dma0 & 0x7) | (dma1 << 4)) {
1354		case 0x5:	/*  dma0 == 5 */
1355			devpriv->dma_bits |= DMA_CH5;
1356			break;
1357		case 0x6:	/*  dma0 == 6 */
1358			devpriv->dma_bits |= DMA_CH6;
1359			break;
1360		case 0x7:	/*  dma0 == 7 */
1361			devpriv->dma_bits |= DMA_CH7;
1362			break;
1363		case 0x65:	/*  dma0 == 5, dma1 == 6 */
1364			devpriv->dma_bits |= DMA_CH5_CH6;
1365			break;
1366		case 0x76:	/*  dma0 == 6, dma1 == 7 */
1367			devpriv->dma_bits |= DMA_CH6_CH7;
1368			break;
1369		case 0x57:	/*  dma0 == 7, dma1 == 5 */
1370			devpriv->dma_bits |= DMA_CH7_CH5;
1371			break;
1372		default:
1373			dev_err(dev->class_dev,
1374				"only supports dma channels 5 through 7\n");
1375			dev_err(dev->class_dev,
1376				"Dual dma only allows the following combinations:\n");
1377			dev_err(dev->class_dev,
1378				"dma 5,6 / 6,7 / or 7,5\n");
1379			return -EINVAL;
1380			break;
1381		}
1382		if (request_dma(dma0, dev->driver->driver_name)) {
1383			dev_err(dev->class_dev,
1384				"failed to allocate dma channel %i\n", dma0);
1385			return -EINVAL;
1386		}
1387		devpriv->dma0 = dma0;
1388		devpriv->dma_current = dma0;
1389		if (dma1) {
1390			if (request_dma(dma1, dev->driver->driver_name)) {
1391				dev_err(dev->class_dev,
1392					"failed to allocate dma channel %i\n",
1393					dma1);
1394				return -EINVAL;
1395			}
1396			devpriv->dma1 = dma1;
1397		}
1398		devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1399		if (devpriv->ai_buf0 == NULL)
1400			return -ENOMEM;
1401		devpriv->dma_current_buf = devpriv->ai_buf0;
1402		if (dma1) {
1403			devpriv->ai_buf1 =
1404			    kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1405			if (devpriv->ai_buf1 == NULL)
1406				return -ENOMEM;
1407		}
1408		flags = claim_dma_lock();
1409		disable_dma(devpriv->dma0);
1410		set_dma_mode(devpriv->dma0, DMA_MODE_READ);
1411		if (dma1) {
1412			disable_dma(devpriv->dma1);
1413			set_dma_mode(devpriv->dma1, DMA_MODE_READ);
1414		}
1415		release_dma_lock(flags);
1416	}
1417	return 0;
1418}
1419
1420static int das1800_probe(struct comedi_device *dev)
1421{
1422	int id;
1423	int board;
1424
1425	id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;	/* get id bits */
1426	board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
1427
1428	switch (id) {
1429	case 0x3:
1430		if (board == das1801st_da || board == das1802st_da ||
1431		    board == das1701st_da || board == das1702st_da) {
1432			dev_dbg(dev->class_dev, "Board model: %s\n",
1433				das1800_boards[board].name);
1434			return board;
1435		}
1436		printk
1437		    (" Board model (probed, not recommended): das-1800st-da series\n");
1438		return das1801st;
1439		break;
1440	case 0x4:
1441		if (board == das1802hr_da || board == das1702hr_da) {
1442			dev_dbg(dev->class_dev, "Board model: %s\n",
1443				das1800_boards[board].name);
1444			return board;
1445		}
1446		printk
1447		    (" Board model (probed, not recommended): das-1802hr-da\n");
1448		return das1802hr;
1449		break;
1450	case 0x5:
1451		if (board == das1801ao || board == das1802ao ||
1452		    board == das1701ao || board == das1702ao) {
1453			dev_dbg(dev->class_dev, "Board model: %s\n",
1454				das1800_boards[board].name);
1455			return board;
1456		}
1457		printk
1458		    (" Board model (probed, not recommended): das-1800ao series\n");
1459		return das1801ao;
1460		break;
1461	case 0x6:
1462		if (board == das1802hr || board == das1702hr) {
1463			dev_dbg(dev->class_dev, "Board model: %s\n",
1464				das1800_boards[board].name);
1465			return board;
1466		}
1467		printk
1468		    (" Board model (probed, not recommended): das-1802hr\n");
1469		return das1802hr;
1470		break;
1471	case 0x7:
1472		if (board == das1801st || board == das1802st ||
1473		    board == das1701st || board == das1702st) {
1474			dev_dbg(dev->class_dev, "Board model: %s\n",
1475				das1800_boards[board].name);
1476			return board;
1477		}
1478		printk
1479		    (" Board model (probed, not recommended): das-1800st series\n");
1480		return das1801st;
1481		break;
1482	case 0x8:
1483		if (board == das1801hc || board == das1802hc) {
1484			dev_dbg(dev->class_dev, "Board model: %s\n",
1485				das1800_boards[board].name);
1486			return board;
1487		}
1488		printk
1489		    (" Board model (probed, not recommended): das-1800hc series\n");
1490		return das1801hc;
1491		break;
1492	default:
1493		printk
1494		    (" Board model: probe returned 0x%x (unknown, please report)\n",
1495		     id);
1496		return board;
1497		break;
1498	}
1499	return -1;
1500}
1501
1502static int das1800_attach(struct comedi_device *dev,
1503			  struct comedi_devconfig *it)
1504{
1505	const struct das1800_board *thisboard = comedi_board(dev);
1506	struct das1800_private *devpriv;
1507	struct comedi_subdevice *s;
1508	unsigned int irq = it->options[1];
1509	unsigned int dma0 = it->options[2];
1510	unsigned int dma1 = it->options[3];
1511	int board;
1512	int ret;
1513
1514	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1515	if (!devpriv)
1516		return -ENOMEM;
1517
1518	ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE);
1519	if (ret)
1520		return ret;
1521
1522	board = das1800_probe(dev);
1523	if (board < 0) {
1524		dev_err(dev->class_dev, "unable to determine board type\n");
1525		return -ENODEV;
1526	}
1527
1528	dev->board_ptr = das1800_boards + board;
1529	thisboard = comedi_board(dev);
1530	dev->board_name = thisboard->name;
1531
1532	/*  if it is an 'ao' board with fancy analog out then we need extra io ports */
1533	if (thisboard->ao_ability == 2) {
1534		unsigned long iobase2 = dev->iobase + IOBASE2;
1535
1536		ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE);
1537		if (ret)
1538			return ret;
1539		devpriv->iobase2 = iobase2;
1540	}
1541
1542	/* grab our IRQ */
1543	if (irq) {
1544		if (request_irq(irq, das1800_interrupt, 0,
1545				dev->driver->driver_name, dev)) {
1546			dev_dbg(dev->class_dev, "unable to allocate irq %u\n",
1547				irq);
1548			return -EINVAL;
1549		}
1550	}
1551	dev->irq = irq;
1552
1553	/*  set bits that tell card which irq to use */
1554	switch (irq) {
1555	case 0:
1556		break;
1557	case 3:
1558		devpriv->irq_dma_bits |= 0x8;
1559		break;
1560	case 5:
1561		devpriv->irq_dma_bits |= 0x10;
1562		break;
1563	case 7:
1564		devpriv->irq_dma_bits |= 0x18;
1565		break;
1566	case 10:
1567		devpriv->irq_dma_bits |= 0x28;
1568		break;
1569	case 11:
1570		devpriv->irq_dma_bits |= 0x30;
1571		break;
1572	case 15:
1573		devpriv->irq_dma_bits |= 0x38;
1574		break;
1575	default:
1576		dev_err(dev->class_dev, "irq out of range\n");
1577		return -EINVAL;
1578		break;
1579	}
1580
1581	ret = das1800_init_dma(dev, dma0, dma1);
1582	if (ret < 0)
1583		return ret;
1584
1585	if (devpriv->ai_buf0 == NULL) {
1586		devpriv->ai_buf0 =
1587		    kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
1588		if (devpriv->ai_buf0 == NULL)
1589			return -ENOMEM;
1590	}
1591
1592	ret = comedi_alloc_subdevices(dev, 4);
1593	if (ret)
1594		return ret;
1595
1596	/* analog input subdevice */
1597	s = &dev->subdevices[0];
1598	dev->read_subdev = s;
1599	s->type = COMEDI_SUBD_AI;
1600	s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
1601	if (thisboard->common)
1602		s->subdev_flags |= SDF_COMMON;
1603	s->n_chan = thisboard->qram_len;
1604	s->len_chanlist = thisboard->qram_len;
1605	s->maxdata = (1 << thisboard->resolution) - 1;
1606	s->range_table = thisboard->range_ai;
1607	s->do_cmd = das1800_ai_do_cmd;
1608	s->do_cmdtest = das1800_ai_do_cmdtest;
1609	s->insn_read = das1800_ai_rinsn;
1610	s->poll = das1800_ai_poll;
1611	s->cancel = das1800_cancel;
1612
1613	/* analog out */
1614	s = &dev->subdevices[1];
1615	if (thisboard->ao_ability == 1) {
1616		s->type = COMEDI_SUBD_AO;
1617		s->subdev_flags = SDF_WRITABLE;
1618		s->n_chan = thisboard->ao_n_chan;
1619		s->maxdata = (1 << thisboard->resolution) - 1;
1620		s->range_table = &range_bipolar10;
1621		s->insn_write = das1800_ao_winsn;
1622	} else {
1623		s->type = COMEDI_SUBD_UNUSED;
1624	}
1625
1626	/* di */
1627	s = &dev->subdevices[2];
1628	s->type = COMEDI_SUBD_DI;
1629	s->subdev_flags = SDF_READABLE;
1630	s->n_chan = 4;
1631	s->maxdata = 1;
1632	s->range_table = &range_digital;
1633	s->insn_bits = das1800_di_rbits;
1634
1635	/* do */
1636	s = &dev->subdevices[3];
1637	s->type = COMEDI_SUBD_DO;
1638	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1639	s->n_chan = thisboard->do_n_chan;
1640	s->maxdata = 1;
1641	s->range_table = &range_digital;
1642	s->insn_bits = das1800_do_wbits;
1643
1644	das1800_cancel(dev, dev->read_subdev);
1645
1646	/*  initialize digital out channels */
1647	outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1648
1649	/*  initialize analog out channels */
1650	if (thisboard->ao_ability == 1) {
1651		/*  select 'update' dac channel for baseAddress + 0x0 */
1652		outb(DAC(thisboard->ao_n_chan - 1),
1653		     dev->iobase + DAS1800_SELECT);
1654		outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1655	}
1656
1657	return 0;
1658};
1659
1660static void das1800_detach(struct comedi_device *dev)
1661{
1662	struct das1800_private *devpriv = dev->private;
1663
1664	if (devpriv) {
1665		if (devpriv->dma0)
1666			free_dma(devpriv->dma0);
1667		if (devpriv->dma1)
1668			free_dma(devpriv->dma1);
1669		kfree(devpriv->ai_buf0);
1670		kfree(devpriv->ai_buf1);
1671		if (devpriv->iobase2)
1672			release_region(devpriv->iobase2, DAS1800_SIZE);
1673	}
1674	comedi_legacy_detach(dev);
1675}
1676
1677static struct comedi_driver das1800_driver = {
1678	.driver_name	= "das1800",
1679	.module		= THIS_MODULE,
1680	.attach		= das1800_attach,
1681	.detach		= das1800_detach,
1682	.num_names	= ARRAY_SIZE(das1800_boards),
1683	.board_name	= &das1800_boards[0].name,
1684	.offset		= sizeof(struct das1800_board),
1685};
1686module_comedi_driver(das1800_driver);
1687
1688MODULE_AUTHOR("Comedi http://www.comedi.org");
1689MODULE_DESCRIPTION("Comedi low-level driver");
1690MODULE_LICENSE("GPL");
1691