xref: /linux/drivers/comedi/drivers/das1800.c (revision fade5e5b)
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 
143 static 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 
156 static 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 
175 enum 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 
204 struct das1800_board {
205 	const char *name;
206 	unsigned char id;
207 	unsigned int ai_speed;
208 	unsigned int is_01_series:1;
209 };
210 
211 static 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 
311 struct 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 
das1800_ai_munge(struct comedi_device * dev,struct comedi_subdevice * s,void * data,unsigned int num_bytes,unsigned int start_chan_index)320 static 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 
das1800_handle_fifo_half_full(struct comedi_device * dev,struct comedi_subdevice * s)337 static 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 
das1800_handle_fifo_not_empty(struct comedi_device * dev,struct comedi_subdevice * s)347 static 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 
das1800_flush_dma_channel(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_isadma_desc * desc)363 static 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 
das1800_flush_dma(struct comedi_device * dev,struct comedi_subdevice * s)378 static 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 
das1800_handle_dma(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int status)399 static 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 
das1800_ai_cancel(struct comedi_device * dev,struct comedi_subdevice * s)421 static 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 
das1800_ai_handler(struct comedi_device * dev)445 static 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 
das1800_ai_poll(struct comedi_device * dev,struct comedi_subdevice * s)492 static 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 
das1800_interrupt(int irq,void * d)510 static 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 
das1800_ai_fixup_paced_timing(struct comedi_device * dev,struct comedi_cmd * cmd)542 static 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 
das1800_ai_fixup_burst_timing(struct comedi_device * dev,struct comedi_cmd * cmd)561 static 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 
das1800_ai_check_chanlist(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)611 static 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 
das1800_ai_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)632 static 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 
das1800_ai_chanspec_bits(struct comedi_subdevice * s,unsigned int chanspec)725 static 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 
das1800_ai_transfer_size(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int maxbytes,unsigned int ns)743 static 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 
das1800_ai_setup_dma(struct comedi_device * dev,struct comedi_subdevice * s)776 static 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 
das1800_ai_set_chanlist(struct comedi_device * dev,unsigned int * chanlist,unsigned int len)804 static 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 
das1800_ai_cmd(struct comedi_device * dev,struct comedi_subdevice * s)833 static 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 
das1800_ai_eoc(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned long context)925 static 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 
das1800_ai_insn_read(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)938 static 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 
das1800_ao_insn_write(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)982 static 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 
das1800_di_insn_bits(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)1019 static 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 
das1800_do_insn_bits(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)1030 static 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 
das1800_init_dma(struct comedi_device * dev,struct comedi_devconfig * it)1043 static 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 
das1800_free_dma(struct comedi_device * dev)1088 static 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 
das1800_probe(struct comedi_device * dev)1096 static 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 
das1800_attach(struct comedi_device * dev,struct comedi_devconfig * it)1160 static 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 
das1800_detach(struct comedi_device * dev)1336 static 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 
1349 static 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 };
1358 module_comedi_driver(das1800_driver);
1359 
1360 MODULE_AUTHOR("Comedi https://www.comedi.org");
1361 MODULE_DESCRIPTION("Comedi driver for DAS1800 compatible ISA boards");
1362 MODULE_LICENSE("GPL");
1363