1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Comedi driver for Keithley DAS-1700/DAS-1800 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
10/*
11 * Driver: das1800
12 * Description: Keithley Metrabyte DAS1800 (& compatibles)
13 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
14 * Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
15 *   DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
16 *   DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
17 *   DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
18 *   DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
19 *   DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
20 *   DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
21 *   DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
22 *   DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
23 *   DAS-1802AO (das-1802ao)
24 * Status: works
25 *
26 * Configuration options:
27 *   [0] - I/O port base address
28 *   [1] - IRQ (optional, required for analog input cmd support)
29 *   [2] - DMA0 (optional, requires irq)
30 *   [3] - DMA1 (optional, requires irq and dma0)
31 *
32 * analog input cmd triggers supported:
33 *
34 *   start_src		TRIG_NOW	command starts immediately
35 *			TRIG_EXT	command starts on external pin TGIN
36 *
37 *   scan_begin_src	TRIG_FOLLOW	paced/external scans start immediately
38 *			TRIG_TIMER	burst scans start periodically
39 *			TRIG_EXT	burst scans start on external pin XPCLK
40 *
41 *   scan_end_src	TRIG_COUNT	scan ends after last channel
42 *
43 *   convert_src	TRIG_TIMER	paced/burst conversions are timed
44 *			TRIG_EXT	conversions on external pin XPCLK
45 *					(requires scan_begin_src == TRIG_FOLLOW)
46 *
47 *   stop_src		TRIG_COUNT	command stops after stop_arg scans
48 *			TRIG_EXT	command stops on external pin TGIN
49 *			TRIG_NONE	command runs until canceled
50 *
51 * If TRIG_EXT is used for both the start_src and stop_src, the first TGIN
52 * trigger starts the command, and the second trigger will stop it. If only
53 * one is TRIG_EXT, the first trigger will either stop or start the command.
54 * The external pin TGIN is normally set for negative edge triggering. It
55 * can be set to positive edge with the CR_INVERT flag. If TRIG_EXT is used
56 * for both the start_src and stop_src they must have the same polarity.
57 *
58 * Minimum conversion speed is limited to 64 microseconds (convert_arg <= 64000)
59 * for 'burst' scans. This limitation does not apply for 'paced' scans. The
60 * maximum conversion speed is limited by the board (convert_arg >= ai_speed).
61 * Maximum conversion speeds are not always achievable depending on the
62 * board setup (see user manual).
63 *
64 * NOTES:
65 * Only the DAS-1801ST has been tested by me.
66 * Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
67 *
68 * The waveform analog output on the 'ao' cards is not supported.
69 * If you need it, send me (Frank Hess) an email.
70 */
71
72#include <linux/module.h>
73#include <linux/interrupt.h>
74#include <linux/slab.h>
75#include <linux/io.h>
76#include <linux/comedi/comedidev.h>
77#include <linux/comedi/comedi_8254.h>
78#include <linux/comedi/comedi_isadma.h>
79
80/* misc. defines */
81#define DAS1800_SIZE           16	/* uses 16 io addresses */
82#define FIFO_SIZE              1024	/*  1024 sample fifo */
83#define DMA_BUF_SIZE           0x1ff00	/*  size in bytes of dma buffers */
84
85/* Registers for the das1800 */
86#define DAS1800_FIFO            0x0
87#define DAS1800_QRAM            0x0
88#define DAS1800_DAC             0x0
89#define DAS1800_SELECT          0x2
90#define   ADC                     0x0
91#define   QRAM                    0x1
92#define   DAC(a)                  (0x2 + a)
93#define DAS1800_DIGITAL         0x3
94#define DAS1800_CONTROL_A       0x4
95#define   FFEN                    0x1
96#define   CGEN                    0x4
97#define   CGSL                    0x8
98#define   TGEN                    0x10
99#define   TGSL                    0x20
100#define   TGPL                    0x40
101#define   ATEN                    0x80
102#define DAS1800_CONTROL_B       0x5
103#define   DMA_CH5                 0x1
104#define   DMA_CH6                 0x2
105#define   DMA_CH7                 0x3
106#define   DMA_CH5_CH6             0x5
107#define   DMA_CH6_CH7             0x6
108#define   DMA_CH7_CH5             0x7
109#define   DMA_ENABLED             0x3
110#define   DMA_DUAL                0x4
111#define   IRQ3                    0x8
112#define   IRQ5                    0x10
113#define   IRQ7                    0x18
114#define   IRQ10                   0x28
115#define   IRQ11                   0x30
116#define   IRQ15                   0x38
117#define   FIMD                    0x40
118#define DAS1800_CONTROL_C       0X6
119#define   IPCLK                   0x1
120#define   XPCLK                   0x3
121#define   BMDE                    0x4
122#define   CMEN                    0x8
123#define   UQEN                    0x10
124#define   SD                      0x40
125#define   UB                      0x80
126#define DAS1800_STATUS          0x7
127#define   INT                     0x1
128#define   DMATC                   0x2
129#define   CT0TC                   0x8
130#define   OVF                     0x10
131#define   FHF                     0x20
132#define   FNE                     0x40
133#define   CVEN                    0x80
134#define   CVEN_MASK               0x40
135#define   CLEAR_INTR_MASK         (CVEN_MASK | 0x1f)
136#define DAS1800_BURST_LENGTH    0x8
137#define DAS1800_BURST_RATE      0x9
138#define DAS1800_QRAM_ADDRESS    0xa
139#define DAS1800_COUNTER         0xc
140
141#define IOBASE2                   0x400
142
143static const struct comedi_lrange das1801_ai_range = {
144	8, {
145		BIP_RANGE(5),		/* bipolar gain = 1 */
146		BIP_RANGE(1),		/* bipolar gain = 10 */
147		BIP_RANGE(0.1),		/* bipolar gain = 50 */
148		BIP_RANGE(0.02),	/* bipolar gain = 250 */
149		UNI_RANGE(5),		/* unipolar gain = 1 */
150		UNI_RANGE(1),		/* unipolar gain = 10 */
151		UNI_RANGE(0.1),		/* unipolar gain = 50 */
152		UNI_RANGE(0.02)		/* unipolar gain = 250 */
153	}
154};
155
156static const struct comedi_lrange das1802_ai_range = {
157	8, {
158		BIP_RANGE(10),		/* bipolar gain = 1 */
159		BIP_RANGE(5),		/* bipolar gain = 2 */
160		BIP_RANGE(2.5),		/* bipolar gain = 4 */
161		BIP_RANGE(1.25),	/* bipolar gain = 8 */
162		UNI_RANGE(10),		/* unipolar gain = 1 */
163		UNI_RANGE(5),		/* unipolar gain = 2 */
164		UNI_RANGE(2.5),		/* unipolar gain = 4 */
165		UNI_RANGE(1.25)		/* unipolar gain = 8 */
166	}
167};
168
169/*
170 * The waveform analog outputs on the 'ao' boards are not currently
171 * supported. They have a comedi_lrange of:
172 * { 2, { BIP_RANGE(10), BIP_RANGE(5) } }
173 */
174
175enum das1800_boardid {
176	BOARD_DAS1701ST,
177	BOARD_DAS1701ST_DA,
178	BOARD_DAS1702ST,
179	BOARD_DAS1702ST_DA,
180	BOARD_DAS1702HR,
181	BOARD_DAS1702HR_DA,
182	BOARD_DAS1701AO,
183	BOARD_DAS1702AO,
184	BOARD_DAS1801ST,
185	BOARD_DAS1801ST_DA,
186	BOARD_DAS1802ST,
187	BOARD_DAS1802ST_DA,
188	BOARD_DAS1802HR,
189	BOARD_DAS1802HR_DA,
190	BOARD_DAS1801HC,
191	BOARD_DAS1802HC,
192	BOARD_DAS1801AO,
193	BOARD_DAS1802AO
194};
195
196/* board probe id values (hi byte of the digital input register) */
197#define DAS1800_ID_ST_DA		0x3
198#define DAS1800_ID_HR_DA		0x4
199#define DAS1800_ID_AO			0x5
200#define DAS1800_ID_HR			0x6
201#define DAS1800_ID_ST			0x7
202#define DAS1800_ID_HC			0x8
203
204struct das1800_board {
205	const char *name;
206	unsigned char id;
207	unsigned int ai_speed;
208	unsigned int is_01_series:1;
209};
210
211static const struct das1800_board das1800_boards[] = {
212	[BOARD_DAS1701ST] = {
213		.name		= "das-1701st",
214		.id		= DAS1800_ID_ST,
215		.ai_speed	= 6250,
216		.is_01_series	= 1,
217	},
218	[BOARD_DAS1701ST_DA] = {
219		.name		= "das-1701st-da",
220		.id		= DAS1800_ID_ST_DA,
221		.ai_speed	= 6250,
222		.is_01_series	= 1,
223	},
224	[BOARD_DAS1702ST] = {
225		.name		= "das-1702st",
226		.id		= DAS1800_ID_ST,
227		.ai_speed	= 6250,
228	},
229	[BOARD_DAS1702ST_DA] = {
230		.name		= "das-1702st-da",
231		.id		= DAS1800_ID_ST_DA,
232		.ai_speed	= 6250,
233	},
234	[BOARD_DAS1702HR] = {
235		.name		= "das-1702hr",
236		.id		= DAS1800_ID_HR,
237		.ai_speed	= 20000,
238	},
239	[BOARD_DAS1702HR_DA] = {
240		.name		= "das-1702hr-da",
241		.id		= DAS1800_ID_HR_DA,
242		.ai_speed	= 20000,
243	},
244	[BOARD_DAS1701AO] = {
245		.name		= "das-1701ao",
246		.id		= DAS1800_ID_AO,
247		.ai_speed	= 6250,
248		.is_01_series	= 1,
249	},
250	[BOARD_DAS1702AO] = {
251		.name		= "das-1702ao",
252		.id		= DAS1800_ID_AO,
253		.ai_speed	= 6250,
254	},
255	[BOARD_DAS1801ST] = {
256		.name		= "das-1801st",
257		.id		= DAS1800_ID_ST,
258		.ai_speed	= 3000,
259		.is_01_series	= 1,
260	},
261	[BOARD_DAS1801ST_DA] = {
262		.name		= "das-1801st-da",
263		.id		= DAS1800_ID_ST_DA,
264		.ai_speed	= 3000,
265		.is_01_series	= 1,
266	},
267	[BOARD_DAS1802ST] = {
268		.name		= "das-1802st",
269		.id		= DAS1800_ID_ST,
270		.ai_speed	= 3000,
271	},
272	[BOARD_DAS1802ST_DA] = {
273		.name		= "das-1802st-da",
274		.id		= DAS1800_ID_ST_DA,
275		.ai_speed	= 3000,
276	},
277	[BOARD_DAS1802HR] = {
278		.name		= "das-1802hr",
279		.id		= DAS1800_ID_HR,
280		.ai_speed	= 10000,
281	},
282	[BOARD_DAS1802HR_DA] = {
283		.name		= "das-1802hr-da",
284		.id		= DAS1800_ID_HR_DA,
285		.ai_speed	= 10000,
286	},
287	[BOARD_DAS1801HC] = {
288		.name		= "das-1801hc",
289		.id		= DAS1800_ID_HC,
290		.ai_speed	= 3000,
291		.is_01_series	= 1,
292	},
293	[BOARD_DAS1802HC] = {
294		.name		= "das-1802hc",
295		.id		= DAS1800_ID_HC,
296		.ai_speed	= 3000,
297	},
298	[BOARD_DAS1801AO] = {
299		.name		= "das-1801ao",
300		.id		= DAS1800_ID_AO,
301		.ai_speed	= 3000,
302		.is_01_series	= 1,
303	},
304	[BOARD_DAS1802AO] = {
305		.name		= "das-1802ao",
306		.id		= DAS1800_ID_AO,
307		.ai_speed	= 3000,
308	},
309};
310
311struct das1800_private {
312	struct comedi_isadma *dma;
313	int irq_dma_bits;
314	int dma_bits;
315	unsigned short *fifo_buf;
316	unsigned long iobase2;
317	bool ai_is_unipolar;
318};
319
320static void das1800_ai_munge(struct comedi_device *dev,
321			     struct comedi_subdevice *s,
322			     void *data, unsigned int num_bytes,
323			     unsigned int start_chan_index)
324{
325	struct das1800_private *devpriv = dev->private;
326	unsigned short *array = data;
327	unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes);
328	unsigned int i;
329
330	if (devpriv->ai_is_unipolar)
331		return;
332
333	for (i = 0; i < num_samples; i++)
334		array[i] = comedi_offset_munge(s, array[i]);
335}
336
337static void das1800_handle_fifo_half_full(struct comedi_device *dev,
338					  struct comedi_subdevice *s)
339{
340	struct das1800_private *devpriv = dev->private;
341	unsigned int nsamples = comedi_nsamples_left(s, FIFO_SIZE / 2);
342
343	insw(dev->iobase + DAS1800_FIFO, devpriv->fifo_buf, nsamples);
344	comedi_buf_write_samples(s, devpriv->fifo_buf, nsamples);
345}
346
347static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
348					  struct comedi_subdevice *s)
349{
350	struct comedi_cmd *cmd = &s->async->cmd;
351	unsigned short dpnt;
352
353	while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
354		dpnt = inw(dev->iobase + DAS1800_FIFO);
355		comedi_buf_write_samples(s, &dpnt, 1);
356
357		if (cmd->stop_src == TRIG_COUNT &&
358		    s->async->scans_done >= cmd->stop_arg)
359			break;
360	}
361}
362
363static void das1800_flush_dma_channel(struct comedi_device *dev,
364				      struct comedi_subdevice *s,
365				      struct comedi_isadma_desc *desc)
366{
367	unsigned int residue = comedi_isadma_disable(desc->chan);
368	unsigned int nbytes = desc->size - residue;
369	unsigned int nsamples;
370
371	/*  figure out how many points to read */
372	nsamples = comedi_bytes_to_samples(s, nbytes);
373	nsamples = comedi_nsamples_left(s, nsamples);
374
375	comedi_buf_write_samples(s, desc->virt_addr, nsamples);
376}
377
378static void das1800_flush_dma(struct comedi_device *dev,
379			      struct comedi_subdevice *s)
380{
381	struct das1800_private *devpriv = dev->private;
382	struct comedi_isadma *dma = devpriv->dma;
383	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
384	const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
385
386	das1800_flush_dma_channel(dev, s, desc);
387
388	if (dual_dma) {
389		/*  switch to other channel and flush it */
390		dma->cur_dma = 1 - dma->cur_dma;
391		desc = &dma->desc[dma->cur_dma];
392		das1800_flush_dma_channel(dev, s, desc);
393	}
394
395	/*  get any remaining samples in fifo */
396	das1800_handle_fifo_not_empty(dev, s);
397}
398
399static void das1800_handle_dma(struct comedi_device *dev,
400			       struct comedi_subdevice *s, unsigned int status)
401{
402	struct das1800_private *devpriv = dev->private;
403	struct comedi_isadma *dma = devpriv->dma;
404	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
405	const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
406
407	das1800_flush_dma_channel(dev, s, desc);
408
409	/* re-enable dma channel */
410	comedi_isadma_program(desc);
411
412	if (status & DMATC) {
413		/*  clear DMATC interrupt bit */
414		outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
415		/*  switch dma channels for next time, if appropriate */
416		if (dual_dma)
417			dma->cur_dma = 1 - dma->cur_dma;
418	}
419}
420
421static int das1800_ai_cancel(struct comedi_device *dev,
422			     struct comedi_subdevice *s)
423{
424	struct das1800_private *devpriv = dev->private;
425	struct comedi_isadma *dma = devpriv->dma;
426	struct comedi_isadma_desc *desc;
427	int i;
428
429	/* disable and stop conversions */
430	outb(0x0, dev->iobase + DAS1800_STATUS);
431	outb(0x0, dev->iobase + DAS1800_CONTROL_B);
432	outb(0x0, dev->iobase + DAS1800_CONTROL_A);
433
434	if (dma) {
435		for (i = 0; i < 2; i++) {
436			desc = &dma->desc[i];
437			if (desc->chan)
438				comedi_isadma_disable(desc->chan);
439		}
440	}
441
442	return 0;
443}
444
445static void das1800_ai_handler(struct comedi_device *dev)
446{
447	struct das1800_private *devpriv = dev->private;
448	struct comedi_subdevice *s = dev->read_subdev;
449	struct comedi_async *async = s->async;
450	struct comedi_cmd *cmd = &async->cmd;
451	unsigned int status = inb(dev->iobase + DAS1800_STATUS);
452
453	/* select adc register (spinlock is already held) */
454	outb(ADC, dev->iobase + DAS1800_SELECT);
455
456	/* get samples with dma, fifo, or polled as necessary */
457	if (devpriv->irq_dma_bits & DMA_ENABLED)
458		das1800_handle_dma(dev, s, status);
459	else if (status & FHF)
460		das1800_handle_fifo_half_full(dev, s);
461	else if (status & FNE)
462		das1800_handle_fifo_not_empty(dev, s);
463
464	/* if the card's fifo has overflowed */
465	if (status & OVF) {
466		/*  clear OVF interrupt bit */
467		outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
468		dev_err(dev->class_dev, "FIFO overflow\n");
469		async->events |= COMEDI_CB_ERROR;
470		comedi_handle_events(dev, s);
471		return;
472	}
473	/*  stop taking data if appropriate */
474	/* stop_src TRIG_EXT */
475	if (status & CT0TC) {
476		/*  clear CT0TC interrupt bit */
477		outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
478		/* get all remaining samples before quitting */
479		if (devpriv->irq_dma_bits & DMA_ENABLED)
480			das1800_flush_dma(dev, s);
481		else
482			das1800_handle_fifo_not_empty(dev, s);
483		async->events |= COMEDI_CB_EOA;
484	} else if (cmd->stop_src == TRIG_COUNT &&
485		   async->scans_done >= cmd->stop_arg) {
486		async->events |= COMEDI_CB_EOA;
487	}
488
489	comedi_handle_events(dev, s);
490}
491
492static int das1800_ai_poll(struct comedi_device *dev,
493			   struct comedi_subdevice *s)
494{
495	unsigned long flags;
496
497	/*
498	 * Protects the indirect addressing selected by DAS1800_SELECT
499	 * in das1800_ai_handler() also prevents race with das1800_interrupt().
500	 */
501	spin_lock_irqsave(&dev->spinlock, flags);
502
503	das1800_ai_handler(dev);
504
505	spin_unlock_irqrestore(&dev->spinlock, flags);
506
507	return comedi_buf_n_bytes_ready(s);
508}
509
510static irqreturn_t das1800_interrupt(int irq, void *d)
511{
512	struct comedi_device *dev = d;
513	unsigned int status;
514
515	if (!dev->attached) {
516		dev_err(dev->class_dev, "premature interrupt\n");
517		return IRQ_HANDLED;
518	}
519
520	/*
521	 * Protects the indirect addressing selected by DAS1800_SELECT
522	 * in das1800_ai_handler() also prevents race with das1800_ai_poll().
523	 */
524	spin_lock(&dev->spinlock);
525
526	status = inb(dev->iobase + DAS1800_STATUS);
527
528	/* if interrupt was not caused by das-1800 */
529	if (!(status & INT)) {
530		spin_unlock(&dev->spinlock);
531		return IRQ_NONE;
532	}
533	/* clear the interrupt status bit INT */
534	outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
535	/*  handle interrupt */
536	das1800_ai_handler(dev);
537
538	spin_unlock(&dev->spinlock);
539	return IRQ_HANDLED;
540}
541
542static int das1800_ai_fixup_paced_timing(struct comedi_device *dev,
543					 struct comedi_cmd *cmd)
544{
545	unsigned int arg = cmd->convert_arg;
546
547	/*
548	 * Paced mode:
549	 *	scan_begin_src is TRIG_FOLLOW
550	 *	convert_src is TRIG_TIMER
551	 *
552	 * The convert_arg sets the pacer sample acquisition time.
553	 * The max acquisition speed is limited to the boards
554	 * 'ai_speed' (this was already verified). The min speed is
555	 * limited by the cascaded 8254 timer.
556	 */
557	comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
558	return comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
559}
560
561static int das1800_ai_fixup_burst_timing(struct comedi_device *dev,
562					 struct comedi_cmd *cmd)
563{
564	unsigned int arg = cmd->convert_arg;
565	int err = 0;
566
567	/*
568	 * Burst mode:
569	 *	scan_begin_src is TRIG_TIMER or TRIG_EXT
570	 *	convert_src is TRIG_TIMER
571	 *
572	 * The convert_arg sets burst sample acquisition time.
573	 * The max acquisition speed is limited to the boards
574	 * 'ai_speed' (this was already verified). The min speed is
575	 * limiited to 64 microseconds,
576	 */
577	err |= comedi_check_trigger_arg_max(&arg, 64000);
578
579	/* round to microseconds then verify */
580	switch (cmd->flags & CMDF_ROUND_MASK) {
581	case CMDF_ROUND_NEAREST:
582	default:
583		arg = DIV_ROUND_CLOSEST(arg, 1000);
584		break;
585	case CMDF_ROUND_DOWN:
586		arg = arg / 1000;
587		break;
588	case CMDF_ROUND_UP:
589		arg = DIV_ROUND_UP(arg, 1000);
590		break;
591	}
592	err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg * 1000);
593
594	/*
595	 * The pacer can be used to set the scan sample rate. The max scan
596	 * speed is limited by the conversion speed and the number of channels
597	 * to convert. The min speed is limited by the cascaded 8254 timer.
598	 */
599	if (cmd->scan_begin_src == TRIG_TIMER) {
600		arg = cmd->convert_arg * cmd->chanlist_len;
601		err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
602
603		arg = cmd->scan_begin_arg;
604		comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
605		err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
606	}
607
608	return err;
609}
610
611static int das1800_ai_check_chanlist(struct comedi_device *dev,
612				     struct comedi_subdevice *s,
613				     struct comedi_cmd *cmd)
614{
615	unsigned int range = CR_RANGE(cmd->chanlist[0]);
616	bool unipolar0 = comedi_range_is_unipolar(s, range);
617	int i;
618
619	for (i = 1; i < cmd->chanlist_len; i++) {
620		range = CR_RANGE(cmd->chanlist[i]);
621
622		if (unipolar0 != comedi_range_is_unipolar(s, range)) {
623			dev_dbg(dev->class_dev,
624				"unipolar and bipolar ranges cannot be mixed in the chanlist\n");
625			return -EINVAL;
626		}
627	}
628
629	return 0;
630}
631
632static int das1800_ai_cmdtest(struct comedi_device *dev,
633			      struct comedi_subdevice *s,
634			      struct comedi_cmd *cmd)
635{
636	const struct das1800_board *board = dev->board_ptr;
637	int err = 0;
638
639	/* Step 1 : check if triggers are trivially valid */
640
641	err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
642	err |= comedi_check_trigger_src(&cmd->scan_begin_src,
643					TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
644	err |= comedi_check_trigger_src(&cmd->convert_src,
645					TRIG_TIMER | TRIG_EXT);
646	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
647	err |= comedi_check_trigger_src(&cmd->stop_src,
648					TRIG_COUNT | TRIG_EXT | TRIG_NONE);
649
650	if (err)
651		return 1;
652
653	/* Step 2a : make sure trigger sources are unique */
654
655	err |= comedi_check_trigger_is_unique(cmd->start_src);
656	err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
657	err |= comedi_check_trigger_is_unique(cmd->convert_src);
658	err |= comedi_check_trigger_is_unique(cmd->stop_src);
659
660	/* Step 2b : and mutually compatible */
661
662	/* burst scans must use timed conversions */
663	if (cmd->scan_begin_src != TRIG_FOLLOW &&
664	    cmd->convert_src != TRIG_TIMER)
665		err |= -EINVAL;
666
667	/* the external pin TGIN must use the same polarity */
668	if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
669		err |= comedi_check_trigger_arg_is(&cmd->start_arg,
670						   cmd->stop_arg);
671
672	if (err)
673		return 2;
674
675	/* Step 3: check if arguments are trivially valid */
676
677	if (cmd->start_arg == TRIG_NOW)
678		err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
679
680	if (cmd->convert_src == TRIG_TIMER) {
681		err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
682						    board->ai_speed);
683	}
684
685	err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
686	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
687					   cmd->chanlist_len);
688
689	switch (cmd->stop_src) {
690	case TRIG_COUNT:
691		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
692		break;
693	case TRIG_NONE:
694		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
695		break;
696	default:
697		break;
698	}
699
700	if (err)
701		return 3;
702
703	/* Step 4: fix up any arguments */
704
705	if (cmd->convert_src == TRIG_TIMER) {
706		if (cmd->scan_begin_src == TRIG_FOLLOW)
707			err |= das1800_ai_fixup_paced_timing(dev, cmd);
708		else /* TRIG_TIMER or TRIG_EXT */
709			err |= das1800_ai_fixup_burst_timing(dev, cmd);
710	}
711
712	if (err)
713		return 4;
714
715	/* Step 5: check channel list if it exists */
716	if (cmd->chanlist && cmd->chanlist_len > 0)
717		err |= das1800_ai_check_chanlist(dev, s, cmd);
718
719	if (err)
720		return 5;
721
722	return 0;
723}
724
725static unsigned char das1800_ai_chanspec_bits(struct comedi_subdevice *s,
726					      unsigned int chanspec)
727{
728	unsigned int range = CR_RANGE(chanspec);
729	unsigned int aref = CR_AREF(chanspec);
730	unsigned char bits;
731
732	bits = UQEN;
733	if (aref != AREF_DIFF)
734		bits |= SD;
735	if (aref == AREF_COMMON)
736		bits |= CMEN;
737	if (comedi_range_is_unipolar(s, range))
738		bits |= UB;
739
740	return bits;
741}
742
743static unsigned int das1800_ai_transfer_size(struct comedi_device *dev,
744					     struct comedi_subdevice *s,
745					     unsigned int maxbytes,
746					     unsigned int ns)
747{
748	struct comedi_cmd *cmd = &s->async->cmd;
749	unsigned int max_samples = comedi_bytes_to_samples(s, maxbytes);
750	unsigned int samples;
751
752	samples = max_samples;
753
754	/* for timed modes, make dma buffer fill in 'ns' time */
755	switch (cmd->scan_begin_src) {
756	case TRIG_FOLLOW:	/* not in burst mode */
757		if (cmd->convert_src == TRIG_TIMER)
758			samples = ns / cmd->convert_arg;
759		break;
760	case TRIG_TIMER:
761		samples = ns / (cmd->scan_begin_arg * cmd->chanlist_len);
762		break;
763	}
764
765	/* limit samples to what is remaining in the command */
766	samples = comedi_nsamples_left(s, samples);
767
768	if (samples > max_samples)
769		samples = max_samples;
770	if (samples < 1)
771		samples = 1;
772
773	return comedi_samples_to_bytes(s, samples);
774}
775
776static void das1800_ai_setup_dma(struct comedi_device *dev,
777				 struct comedi_subdevice *s)
778{
779	struct das1800_private *devpriv = dev->private;
780	struct comedi_isadma *dma = devpriv->dma;
781	struct comedi_isadma_desc *desc;
782	unsigned int bytes;
783
784	if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
785		return;
786
787	dma->cur_dma = 0;
788	desc = &dma->desc[0];
789
790	/* determine a dma transfer size to fill buffer in 0.3 sec */
791	bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000);
792
793	desc->size = bytes;
794	comedi_isadma_program(desc);
795
796	/* set up dual dma if appropriate */
797	if (devpriv->irq_dma_bits & DMA_DUAL) {
798		desc = &dma->desc[1];
799		desc->size = bytes;
800		comedi_isadma_program(desc);
801	}
802}
803
804static void das1800_ai_set_chanlist(struct comedi_device *dev,
805				    unsigned int *chanlist, unsigned int len)
806{
807	unsigned long flags;
808	unsigned int i;
809
810	/* protects the indirect addressing selected by DAS1800_SELECT */
811	spin_lock_irqsave(&dev->spinlock, flags);
812
813	/* select QRAM register and set start address */
814	outb(QRAM, dev->iobase + DAS1800_SELECT);
815	outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS);
816
817	/* make channel / gain list */
818	for (i = 0; i < len; i++) {
819		unsigned int chan = CR_CHAN(chanlist[i]);
820		unsigned int range = CR_RANGE(chanlist[i]);
821		unsigned short val;
822
823		val = chan | ((range & 0x3) << 8);
824		outw(val, dev->iobase + DAS1800_QRAM);
825	}
826
827	/* finish write to QRAM */
828	outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS);
829
830	spin_unlock_irqrestore(&dev->spinlock, flags);
831}
832
833static int das1800_ai_cmd(struct comedi_device *dev,
834			  struct comedi_subdevice *s)
835{
836	struct das1800_private *devpriv = dev->private;
837	int control_a, control_c;
838	struct comedi_async *async = s->async;
839	const struct comedi_cmd *cmd = &async->cmd;
840	unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
841
842	/*
843	 * Disable dma on CMDF_WAKE_EOS, or CMDF_PRIORITY (because dma in
844	 * handler is unsafe at hard real-time priority).
845	 */
846	if (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY))
847		devpriv->irq_dma_bits &= ~DMA_ENABLED;
848	else
849		devpriv->irq_dma_bits |= devpriv->dma_bits;
850	/*  interrupt on end of conversion for CMDF_WAKE_EOS */
851	if (cmd->flags & CMDF_WAKE_EOS) {
852		/*  interrupt fifo not empty */
853		devpriv->irq_dma_bits &= ~FIMD;
854	} else {
855		/*  interrupt fifo half full */
856		devpriv->irq_dma_bits |= FIMD;
857	}
858
859	das1800_ai_cancel(dev, s);
860
861	devpriv->ai_is_unipolar = comedi_range_is_unipolar(s, range0);
862
863	control_a = FFEN;
864	if (cmd->stop_src == TRIG_EXT)
865		control_a |= ATEN;
866	if (cmd->start_src == TRIG_EXT)
867		control_a |= TGEN | CGSL;
868	else /* TRIG_NOW */
869		control_a |= CGEN;
870	if (control_a & (ATEN | TGEN)) {
871		if ((cmd->start_arg & CR_INVERT) || (cmd->stop_arg & CR_INVERT))
872			control_a |= TGPL;
873	}
874
875	control_c = das1800_ai_chanspec_bits(s, cmd->chanlist[0]);
876	/* set clock source to internal or external */
877	if (cmd->scan_begin_src == TRIG_FOLLOW) {
878		/* not in burst mode */
879		if (cmd->convert_src == TRIG_TIMER) {
880			/* trig on cascaded counters */
881			control_c |= IPCLK;
882		} else { /* TRIG_EXT */
883			/* trig on falling edge of external trigger */
884			control_c |= XPCLK;
885		}
886	} else if (cmd->scan_begin_src == TRIG_TIMER) {
887		/* burst mode with internal pacer clock */
888		control_c |= BMDE | IPCLK;
889	} else { /* TRIG_EXT */
890		/* burst mode with external trigger */
891		control_c |= BMDE | XPCLK;
892	}
893
894	das1800_ai_set_chanlist(dev, cmd->chanlist, cmd->chanlist_len);
895
896	/* setup cascaded counters for conversion/scan frequency */
897	if ((cmd->scan_begin_src == TRIG_FOLLOW ||
898	     cmd->scan_begin_src == TRIG_TIMER) &&
899	    cmd->convert_src == TRIG_TIMER) {
900		comedi_8254_update_divisors(dev->pacer);
901		comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
902	}
903
904	/* setup counter 0 for 'about triggering' */
905	if (cmd->stop_src == TRIG_EXT)
906		comedi_8254_load(dev->pacer, 0, 1, I8254_MODE0 | I8254_BINARY);
907
908	das1800_ai_setup_dma(dev, s);
909	outb(control_c, dev->iobase + DAS1800_CONTROL_C);
910	/*  set conversion rate and length for burst mode */
911	if (control_c & BMDE) {
912		outb(cmd->convert_arg / 1000 - 1,	/* microseconds - 1 */
913		     dev->iobase + DAS1800_BURST_RATE);
914		outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
915	}
916
917	/* enable and start conversions */
918	outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B);
919	outb(control_a, dev->iobase + DAS1800_CONTROL_A);
920	outb(CVEN, dev->iobase + DAS1800_STATUS);
921
922	return 0;
923}
924
925static int das1800_ai_eoc(struct comedi_device *dev,
926			  struct comedi_subdevice *s,
927			  struct comedi_insn *insn,
928			  unsigned long context)
929{
930	unsigned char status;
931
932	status = inb(dev->iobase + DAS1800_STATUS);
933	if (status & FNE)
934		return 0;
935	return -EBUSY;
936}
937
938static int das1800_ai_insn_read(struct comedi_device *dev,
939				struct comedi_subdevice *s,
940				struct comedi_insn *insn,
941				unsigned int *data)
942{
943	unsigned int range = CR_RANGE(insn->chanspec);
944	bool is_unipolar = comedi_range_is_unipolar(s, range);
945	int ret = 0;
946	int n;
947	unsigned short dpnt;
948	unsigned long flags;
949
950	outb(das1800_ai_chanspec_bits(s, insn->chanspec),
951	     dev->iobase + DAS1800_CONTROL_C);		/* software pacer */
952	outb(CVEN, dev->iobase + DAS1800_STATUS);	/* enable conversions */
953	outb(0x0, dev->iobase + DAS1800_CONTROL_A);	/* reset fifo */
954	outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
955
956	das1800_ai_set_chanlist(dev, &insn->chanspec, 1);
957
958	/* protects the indirect addressing selected by DAS1800_SELECT */
959	spin_lock_irqsave(&dev->spinlock, flags);
960
961	/* select ai fifo register */
962	outb(ADC, dev->iobase + DAS1800_SELECT);
963
964	for (n = 0; n < insn->n; n++) {
965		/* trigger conversion */
966		outb(0, dev->iobase + DAS1800_FIFO);
967
968		ret = comedi_timeout(dev, s, insn, das1800_ai_eoc, 0);
969		if (ret)
970			break;
971
972		dpnt = inw(dev->iobase + DAS1800_FIFO);
973		if (!is_unipolar)
974			dpnt = comedi_offset_munge(s, dpnt);
975		data[n] = dpnt;
976	}
977	spin_unlock_irqrestore(&dev->spinlock, flags);
978
979	return ret ? ret : insn->n;
980}
981
982static int das1800_ao_insn_write(struct comedi_device *dev,
983				 struct comedi_subdevice *s,
984				 struct comedi_insn *insn,
985				 unsigned int *data)
986{
987	unsigned int chan = CR_CHAN(insn->chanspec);
988	unsigned int update_chan = s->n_chan - 1;
989	unsigned long flags;
990	int i;
991
992	/* protects the indirect addressing selected by DAS1800_SELECT */
993	spin_lock_irqsave(&dev->spinlock, flags);
994
995	for (i = 0; i < insn->n; i++) {
996		unsigned int val = data[i];
997
998		s->readback[chan] = val;
999
1000		val = comedi_offset_munge(s, val);
1001
1002		/* load this channel (and update if it's the last channel) */
1003		outb(DAC(chan), dev->iobase + DAS1800_SELECT);
1004		outw(val, dev->iobase + DAS1800_DAC);
1005
1006		/* update all channels */
1007		if (chan != update_chan) {
1008			val = comedi_offset_munge(s, s->readback[update_chan]);
1009
1010			outb(DAC(update_chan), dev->iobase + DAS1800_SELECT);
1011			outw(val, dev->iobase + DAS1800_DAC);
1012		}
1013	}
1014	spin_unlock_irqrestore(&dev->spinlock, flags);
1015
1016	return insn->n;
1017}
1018
1019static int das1800_di_insn_bits(struct comedi_device *dev,
1020				struct comedi_subdevice *s,
1021				struct comedi_insn *insn,
1022				unsigned int *data)
1023{
1024	data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1025	data[0] = 0;
1026
1027	return insn->n;
1028}
1029
1030static int das1800_do_insn_bits(struct comedi_device *dev,
1031				struct comedi_subdevice *s,
1032				struct comedi_insn *insn,
1033				unsigned int *data)
1034{
1035	if (comedi_dio_update_state(s, data))
1036		outb(s->state, dev->iobase + DAS1800_DIGITAL);
1037
1038	data[1] = s->state;
1039
1040	return insn->n;
1041}
1042
1043static void das1800_init_dma(struct comedi_device *dev,
1044			     struct comedi_devconfig *it)
1045{
1046	struct das1800_private *devpriv = dev->private;
1047	unsigned int *dma_chan;
1048
1049	/*
1050	 * it->options[2] is DMA channel 0
1051	 * it->options[3] is DMA channel 1
1052	 *
1053	 * Encode the DMA channels into 2 digit hexadecimal for switch.
1054	 */
1055	dma_chan = &it->options[2];
1056
1057	switch ((dma_chan[0] & 0x7) | (dma_chan[1] << 4)) {
1058	case 0x5:	/*  dma0 == 5 */
1059		devpriv->dma_bits = DMA_CH5;
1060		break;
1061	case 0x6:	/*  dma0 == 6 */
1062		devpriv->dma_bits = DMA_CH6;
1063		break;
1064	case 0x7:	/*  dma0 == 7 */
1065		devpriv->dma_bits = DMA_CH7;
1066		break;
1067	case 0x65:	/*  dma0 == 5, dma1 == 6 */
1068		devpriv->dma_bits = DMA_CH5_CH6;
1069		break;
1070	case 0x76:	/*  dma0 == 6, dma1 == 7 */
1071		devpriv->dma_bits = DMA_CH6_CH7;
1072		break;
1073	case 0x57:	/*  dma0 == 7, dma1 == 5 */
1074		devpriv->dma_bits = DMA_CH7_CH5;
1075		break;
1076	default:
1077		return;
1078	}
1079
1080	/* DMA can use 1 or 2 buffers, each with a separate channel */
1081	devpriv->dma = comedi_isadma_alloc(dev, dma_chan[1] ? 2 : 1,
1082					   dma_chan[0], dma_chan[1],
1083					   DMA_BUF_SIZE, COMEDI_ISADMA_READ);
1084	if (!devpriv->dma)
1085		devpriv->dma_bits = 0;
1086}
1087
1088static void das1800_free_dma(struct comedi_device *dev)
1089{
1090	struct das1800_private *devpriv = dev->private;
1091
1092	if (devpriv)
1093		comedi_isadma_free(devpriv->dma);
1094}
1095
1096static int das1800_probe(struct comedi_device *dev)
1097{
1098	const struct das1800_board *board = dev->board_ptr;
1099	unsigned char id;
1100
1101	id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;
1102
1103	/*
1104	 * The dev->board_ptr will be set by comedi_device_attach() if the
1105	 * board name provided by the user matches a board->name in this
1106	 * driver. If so, this function sanity checks the id to verify that
1107	 * the board is correct.
1108	 */
1109	if (board) {
1110		if (board->id == id)
1111			return 0;
1112		dev_err(dev->class_dev,
1113			"probed id does not match board id (0x%x != 0x%x)\n",
1114			id, board->id);
1115		return -ENODEV;
1116	}
1117
1118	 /*
1119	  * If the dev->board_ptr is not set, the user is trying to attach
1120	  * an unspecified board to this driver. In this case the id is used
1121	  * to 'probe' for the dev->board_ptr.
1122	  */
1123	switch (id) {
1124	case DAS1800_ID_ST_DA:
1125		/* das-1701st-da, das-1702st-da, das-1801st-da, das-1802st-da */
1126		board = &das1800_boards[BOARD_DAS1801ST_DA];
1127		break;
1128	case DAS1800_ID_HR_DA:
1129		/* das-1702hr-da, das-1802hr-da */
1130		board = &das1800_boards[BOARD_DAS1802HR_DA];
1131		break;
1132	case DAS1800_ID_AO:
1133		/* das-1701ao, das-1702ao, das-1801ao, das-1802ao */
1134		board = &das1800_boards[BOARD_DAS1801AO];
1135		break;
1136	case DAS1800_ID_HR:
1137		/*  das-1702hr, das-1802hr */
1138		board = &das1800_boards[BOARD_DAS1802HR];
1139		break;
1140	case DAS1800_ID_ST:
1141		/* das-1701st, das-1702st, das-1801st, das-1802st */
1142		board = &das1800_boards[BOARD_DAS1801ST];
1143		break;
1144	case DAS1800_ID_HC:
1145		/* das-1801hc, das-1802hc */
1146		board = &das1800_boards[BOARD_DAS1801HC];
1147		break;
1148	default:
1149		dev_err(dev->class_dev, "invalid probe id 0x%x\n", id);
1150		return -ENODEV;
1151	}
1152	dev->board_ptr = board;
1153	dev->board_name = board->name;
1154	dev_warn(dev->class_dev,
1155		 "probed id 0x%0x: %s series (not recommended)\n",
1156		 id, board->name);
1157	return 0;
1158}
1159
1160static int das1800_attach(struct comedi_device *dev,
1161			  struct comedi_devconfig *it)
1162{
1163	const struct das1800_board *board;
1164	struct das1800_private *devpriv;
1165	struct comedi_subdevice *s;
1166	unsigned int irq = it->options[1];
1167	bool is_16bit;
1168	int ret;
1169	int i;
1170
1171	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1172	if (!devpriv)
1173		return -ENOMEM;
1174
1175	ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE);
1176	if (ret)
1177		return ret;
1178
1179	ret = das1800_probe(dev);
1180	if (ret)
1181		return ret;
1182	board = dev->board_ptr;
1183
1184	is_16bit = board->id == DAS1800_ID_HR || board->id == DAS1800_ID_HR_DA;
1185
1186	/* waveform 'ao' boards have additional io ports */
1187	if (board->id == DAS1800_ID_AO) {
1188		unsigned long iobase2 = dev->iobase + IOBASE2;
1189
1190		ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE);
1191		if (ret)
1192			return ret;
1193		devpriv->iobase2 = iobase2;
1194	}
1195
1196	if (irq == 3 || irq == 5 || irq == 7 || irq == 10 || irq == 11 ||
1197	    irq == 15) {
1198		ret = request_irq(irq, das1800_interrupt, 0,
1199				  dev->board_name, dev);
1200		if (ret == 0) {
1201			dev->irq = irq;
1202
1203			switch (irq) {
1204			case 3:
1205				devpriv->irq_dma_bits |= 0x8;
1206				break;
1207			case 5:
1208				devpriv->irq_dma_bits |= 0x10;
1209				break;
1210			case 7:
1211				devpriv->irq_dma_bits |= 0x18;
1212				break;
1213			case 10:
1214				devpriv->irq_dma_bits |= 0x28;
1215				break;
1216			case 11:
1217				devpriv->irq_dma_bits |= 0x30;
1218				break;
1219			case 15:
1220				devpriv->irq_dma_bits |= 0x38;
1221				break;
1222			}
1223		}
1224	}
1225
1226	/* an irq and one dma channel is required to use dma */
1227	if (dev->irq & it->options[2])
1228		das1800_init_dma(dev, it);
1229
1230	devpriv->fifo_buf = kmalloc_array(FIFO_SIZE,
1231					  sizeof(*devpriv->fifo_buf),
1232					  GFP_KERNEL);
1233	if (!devpriv->fifo_buf)
1234		return -ENOMEM;
1235
1236	dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS1800_COUNTER,
1237					  I8254_OSC_BASE_5MHZ, I8254_IO8, 0);
1238	if (IS_ERR(dev->pacer))
1239		return PTR_ERR(dev->pacer);
1240
1241	ret = comedi_alloc_subdevices(dev, 4);
1242	if (ret)
1243		return ret;
1244
1245	/*
1246	 * Analog Input subdevice
1247	 *
1248	 * The "hc" type boards have 64 analog input channels and a 64
1249	 * entry QRAM fifo.
1250	 *
1251	 * All the other board types have 16 on-board channels. Each channel
1252	 * can be expanded to 16 channels with the addition of an EXP-1800
1253	 * expansion board for a total of 256 channels. The QRAM fifo on
1254	 * these boards has 256 entries.
1255	 *
1256	 * From the datasheets it's not clear what the comedi channel to
1257	 * actual physical channel mapping is when EXP-1800 boards are used.
1258	 */
1259	s = &dev->subdevices[0];
1260	s->type		= COMEDI_SUBD_AI;
1261	s->subdev_flags	= SDF_READABLE | SDF_DIFF | SDF_GROUND;
1262	if (board->id != DAS1800_ID_HC)
1263		s->subdev_flags	|= SDF_COMMON;
1264	s->n_chan	= (board->id == DAS1800_ID_HC) ? 64 : 256;
1265	s->maxdata	= is_16bit ? 0xffff : 0x0fff;
1266	s->range_table	= board->is_01_series ? &das1801_ai_range
1267					      : &das1802_ai_range;
1268	s->insn_read	= das1800_ai_insn_read;
1269	if (dev->irq) {
1270		dev->read_subdev = s;
1271		s->subdev_flags	|= SDF_CMD_READ;
1272		s->len_chanlist	= s->n_chan;
1273		s->do_cmd	= das1800_ai_cmd;
1274		s->do_cmdtest	= das1800_ai_cmdtest;
1275		s->poll		= das1800_ai_poll;
1276		s->cancel	= das1800_ai_cancel;
1277		s->munge	= das1800_ai_munge;
1278	}
1279
1280	/* Analog Output subdevice */
1281	s = &dev->subdevices[1];
1282	if (board->id == DAS1800_ID_ST_DA || board->id == DAS1800_ID_HR_DA) {
1283		s->type		= COMEDI_SUBD_AO;
1284		s->subdev_flags	= SDF_WRITABLE;
1285		s->n_chan	= (board->id == DAS1800_ID_ST_DA) ? 4 : 2;
1286		s->maxdata	= is_16bit ? 0xffff : 0x0fff;
1287		s->range_table	= &range_bipolar10;
1288		s->insn_write	= das1800_ao_insn_write;
1289
1290		ret = comedi_alloc_subdev_readback(s);
1291		if (ret)
1292			return ret;
1293
1294		/* initialize all channels to 0V */
1295		for (i = 0; i < s->n_chan; i++) {
1296			/* spinlock is not necessary during the attach */
1297			outb(DAC(i), dev->iobase + DAS1800_SELECT);
1298			outw(0, dev->iobase + DAS1800_DAC);
1299		}
1300	} else if (board->id == DAS1800_ID_AO) {
1301		/*
1302		 * 'ao' boards have waveform analog outputs that are not
1303		 * currently supported.
1304		 */
1305		s->type		= COMEDI_SUBD_UNUSED;
1306	} else {
1307		s->type		= COMEDI_SUBD_UNUSED;
1308	}
1309
1310	/* Digital Input subdevice */
1311	s = &dev->subdevices[2];
1312	s->type		= COMEDI_SUBD_DI;
1313	s->subdev_flags	= SDF_READABLE;
1314	s->n_chan	= 4;
1315	s->maxdata	= 1;
1316	s->range_table	= &range_digital;
1317	s->insn_bits	= das1800_di_insn_bits;
1318
1319	/* Digital Output subdevice */
1320	s = &dev->subdevices[3];
1321	s->type		= COMEDI_SUBD_DO;
1322	s->subdev_flags	= SDF_WRITABLE;
1323	s->n_chan	= (board->id == DAS1800_ID_HC) ? 8 : 4;
1324	s->maxdata	= 1;
1325	s->range_table	= &range_digital;
1326	s->insn_bits	= das1800_do_insn_bits;
1327
1328	das1800_ai_cancel(dev, dev->read_subdev);
1329
1330	/*  initialize digital out channels */
1331	outb(0, dev->iobase + DAS1800_DIGITAL);
1332
1333	return 0;
1334};
1335
1336static void das1800_detach(struct comedi_device *dev)
1337{
1338	struct das1800_private *devpriv = dev->private;
1339
1340	das1800_free_dma(dev);
1341	if (devpriv) {
1342		kfree(devpriv->fifo_buf);
1343		if (devpriv->iobase2)
1344			release_region(devpriv->iobase2, DAS1800_SIZE);
1345	}
1346	comedi_legacy_detach(dev);
1347}
1348
1349static struct comedi_driver das1800_driver = {
1350	.driver_name	= "das1800",
1351	.module		= THIS_MODULE,
1352	.attach		= das1800_attach,
1353	.detach		= das1800_detach,
1354	.num_names	= ARRAY_SIZE(das1800_boards),
1355	.board_name	= &das1800_boards[0].name,
1356	.offset		= sizeof(struct das1800_board),
1357};
1358module_comedi_driver(das1800_driver);
1359
1360MODULE_AUTHOR("Comedi https://www.comedi.org");
1361MODULE_DESCRIPTION("Comedi driver for DAS1800 compatible ISA boards");
1362MODULE_LICENSE("GPL");
1363