1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Comedi driver for National Instruments AT-A2150 boards
4  * Copyright (C) 2001, 2002 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: ni_at_a2150
12  * Description: National Instruments AT-A2150
13  * Author: Frank Mori Hess
14  * Status: works
15  * Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s)
16  *
17  * Configuration options:
18  *   [0] - I/O port base address
19  *   [1] - IRQ (optional, required for timed conversions)
20  *   [2] - DMA (optional, required for timed conversions)
21  *
22  * Yet another driver for obsolete hardware brought to you by Frank Hess.
23  * Testing and debugging help provided by Dave Andruczyk.
24  *
25  * If you want to ac couple the board's inputs, use AREF_OTHER.
26  *
27  * The only difference in the boards is their master clock frequencies.
28  *
29  * References (from ftp://ftp.natinst.com/support/manuals):
30  *   320360.pdf  AT-A2150 User Manual
31  *
32  * TODO:
33  * - analog level triggering
34  * - TRIG_WAKE_EOS
35  */
36 
37 #include <linux/module.h>
38 #include <linux/delay.h>
39 #include <linux/interrupt.h>
40 #include <linux/slab.h>
41 #include <linux/io.h>
42 
43 #include "../comedidev.h"
44 
45 #include "comedi_isadma.h"
46 #include "comedi_8254.h"
47 
48 #define A2150_DMA_BUFFER_SIZE	0xff00	/*  size in bytes of dma buffer */
49 
50 /* Registers and bits */
51 #define CONFIG_REG		0x0
52 #define   CHANNEL_BITS(x)	((x) & 0x7)
53 #define   CHANNEL_MASK		0x7
54 #define   CLOCK_SELECT_BITS(x)	(((x) & 0x3) << 3)
55 #define   CLOCK_DIVISOR_BITS(x)	(((x) & 0x3) << 5)
56 #define   CLOCK_MASK		(0xf << 3)
57 /* enable (don't internally ground) channels 0 and 1 */
58 #define   ENABLE0_BIT		0x80
59 /* enable (don't internally ground) channels 2 and 3 */
60 #define   ENABLE1_BIT		0x100
61 #define   AC0_BIT		0x200	/* ac couple channels 0,1 */
62 #define   AC1_BIT		0x400	/* ac couple channels 2,3 */
63 #define   APD_BIT		0x800	/* analog power down */
64 #define   DPD_BIT		0x1000	/* digital power down */
65 #define TRIGGER_REG		0x2	/* trigger config register */
66 #define   POST_TRIGGER_BITS	0x2
67 #define   DELAY_TRIGGER_BITS	0x3
68 #define   HW_TRIG_EN		0x10	/* enable hardware trigger */
69 #define FIFO_START_REG		0x6	/* software start aquistion trigger */
70 #define FIFO_RESET_REG		0x8	/* clears fifo + fifo flags */
71 #define FIFO_DATA_REG		0xa	/* read data */
72 #define DMA_TC_CLEAR_REG	0xe	/* clear dma terminal count interrupt */
73 #define STATUS_REG		0x12	/* read only */
74 #define   FNE_BIT		0x1	/* fifo not empty */
75 #define   OVFL_BIT		0x8	/* fifo overflow */
76 #define   EDAQ_BIT		0x10	/* end of acquisition interrupt */
77 #define   DCAL_BIT		0x20	/* offset calibration in progress */
78 #define   INTR_BIT		0x40	/* interrupt has occurred */
79 /* dma terminal count interrupt has occurred */
80 #define   DMA_TC_BIT		0x80
81 #define   ID_BITS(x)		(((x) >> 8) & 0x3)
82 #define IRQ_DMA_CNTRL_REG	0x12			/* write only */
83 #define   DMA_CHAN_BITS(x)	((x) & 0x7)		/* sets dma channel */
84 #define   DMA_EN_BIT		0x8			/* enables dma */
85 #define   IRQ_LVL_BITS(x)	(((x) & 0xf) << 4)	/* sets irq level */
86 #define   FIFO_INTR_EN_BIT	0x100	/* enable fifo interrupts */
87 #define   FIFO_INTR_FHF_BIT	0x200	/* interrupt fifo half full */
88 /* enable interrupt on dma terminal count */
89 #define   DMA_INTR_EN_BIT	0x800
90 #define   DMA_DEM_EN_BIT	0x1000	/* enables demand mode dma */
91 #define I8253_BASE_REG		0x14
92 
93 struct a2150_board {
94 	const char *name;
95 	int clock[4];		/* master clock periods, in nanoseconds */
96 	int num_clocks;		/* number of available master clock speeds */
97 	int ai_speed;		/* maximum conversion rate in nanoseconds */
98 };
99 
100 /* analog input range */
101 static const struct comedi_lrange range_a2150 = {
102 	1, {
103 		BIP_RANGE(2.828)
104 	}
105 };
106 
107 /* enum must match board indices */
108 enum { a2150_c, a2150_s };
109 static const struct a2150_board a2150_boards[] = {
110 	{
111 	 .name = "at-a2150c",
112 	 .clock = {31250, 22676, 20833, 19531},
113 	 .num_clocks = 4,
114 	 .ai_speed = 19531,
115 	 },
116 	{
117 	 .name = "at-a2150s",
118 	 .clock = {62500, 50000, 41667, 0},
119 	 .num_clocks = 3,
120 	 .ai_speed = 41667,
121 	 },
122 };
123 
124 struct a2150_private {
125 	struct comedi_isadma *dma;
126 	unsigned int count;	/* number of data points left to be taken */
127 	int irq_dma_bits;	/* irq/dma register bits */
128 	int config_bits;	/* config register bits */
129 };
130 
131 /* interrupt service routine */
a2150_interrupt(int irq,void * d)132 static irqreturn_t a2150_interrupt(int irq, void *d)
133 {
134 	struct comedi_device *dev = d;
135 	struct a2150_private *devpriv = dev->private;
136 	struct comedi_isadma *dma = devpriv->dma;
137 	struct comedi_isadma_desc *desc = &dma->desc[0];
138 	struct comedi_subdevice *s = dev->read_subdev;
139 	struct comedi_async *async = s->async;
140 	struct comedi_cmd *cmd = &async->cmd;
141 	unsigned short *buf = desc->virt_addr;
142 	unsigned int max_points, num_points, residue, leftover;
143 	unsigned short dpnt;
144 	int status;
145 	int i;
146 
147 	if (!dev->attached)
148 		return IRQ_HANDLED;
149 
150 	status = inw(dev->iobase + STATUS_REG);
151 	if ((status & INTR_BIT) == 0)
152 		return IRQ_NONE;
153 
154 	if (status & OVFL_BIT) {
155 		async->events |= COMEDI_CB_ERROR;
156 		comedi_handle_events(dev, s);
157 	}
158 
159 	if ((status & DMA_TC_BIT) == 0) {
160 		async->events |= COMEDI_CB_ERROR;
161 		comedi_handle_events(dev, s);
162 		return IRQ_HANDLED;
163 	}
164 
165 	/*
166 	 * residue is the number of bytes left to be done on the dma
167 	 * transfer.  It should always be zero at this point unless
168 	 * the stop_src is set to external triggering.
169 	 */
170 	residue = comedi_isadma_disable(desc->chan);
171 
172 	/* figure out how many points to read */
173 	max_points = comedi_bytes_to_samples(s, desc->size);
174 	num_points = max_points - comedi_bytes_to_samples(s, residue);
175 	if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
176 		num_points = devpriv->count;
177 
178 	/* figure out how many points will be stored next time */
179 	leftover = 0;
180 	if (cmd->stop_src == TRIG_NONE) {
181 		leftover = comedi_bytes_to_samples(s, desc->size);
182 	} else if (devpriv->count > max_points) {
183 		leftover = devpriv->count - max_points;
184 		if (leftover > max_points)
185 			leftover = max_points;
186 	}
187 	/*
188 	 * There should only be a residue if collection was stopped by having
189 	 * the stop_src set to an external trigger, in which case there
190 	 * will be no more data
191 	 */
192 	if (residue)
193 		leftover = 0;
194 
195 	for (i = 0; i < num_points; i++) {
196 		/* write data point to comedi buffer */
197 		dpnt = buf[i];
198 		/* convert from 2's complement to unsigned coding */
199 		dpnt ^= 0x8000;
200 		comedi_buf_write_samples(s, &dpnt, 1);
201 		if (cmd->stop_src == TRIG_COUNT) {
202 			if (--devpriv->count == 0) {	/* end of acquisition */
203 				async->events |= COMEDI_CB_EOA;
204 				break;
205 			}
206 		}
207 	}
208 	/* re-enable dma */
209 	if (leftover) {
210 		desc->size = comedi_samples_to_bytes(s, leftover);
211 		comedi_isadma_program(desc);
212 	}
213 
214 	comedi_handle_events(dev, s);
215 
216 	/* clear interrupt */
217 	outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
218 
219 	return IRQ_HANDLED;
220 }
221 
a2150_cancel(struct comedi_device * dev,struct comedi_subdevice * s)222 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
223 {
224 	struct a2150_private *devpriv = dev->private;
225 	struct comedi_isadma *dma = devpriv->dma;
226 	struct comedi_isadma_desc *desc = &dma->desc[0];
227 
228 	/* disable dma on card */
229 	devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
230 	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
231 
232 	/* disable computer's dma */
233 	comedi_isadma_disable(desc->chan);
234 
235 	/* clear fifo and reset triggering circuitry */
236 	outw(0, dev->iobase + FIFO_RESET_REG);
237 
238 	return 0;
239 }
240 
241 /*
242  * sets bits in devpriv->clock_bits to nearest approximation of requested
243  * period, adjusts requested period to actual timing.
244  */
a2150_get_timing(struct comedi_device * dev,unsigned int * period,unsigned int flags)245 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
246 			    unsigned int flags)
247 {
248 	const struct a2150_board *board = dev->board_ptr;
249 	struct a2150_private *devpriv = dev->private;
250 	int lub, glb, temp;
251 	int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
252 	int i, j;
253 
254 	/* initialize greatest lower and least upper bounds */
255 	lub_divisor_shift = 3;
256 	lub_index = 0;
257 	lub = board->clock[lub_index] * (1 << lub_divisor_shift);
258 	glb_divisor_shift = 0;
259 	glb_index = board->num_clocks - 1;
260 	glb = board->clock[glb_index] * (1 << glb_divisor_shift);
261 
262 	/* make sure period is in available range */
263 	if (*period < glb)
264 		*period = glb;
265 	if (*period > lub)
266 		*period = lub;
267 
268 	/* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
269 	for (i = 0; i < 4; i++) {
270 		/* there are a maximum of 4 master clocks */
271 		for (j = 0; j < board->num_clocks; j++) {
272 			/* temp is the period in nanosec we are evaluating */
273 			temp = board->clock[j] * (1 << i);
274 			/* if it is the best match yet */
275 			if (temp < lub && temp >= *period) {
276 				lub_divisor_shift = i;
277 				lub_index = j;
278 				lub = temp;
279 			}
280 			if (temp > glb && temp <= *period) {
281 				glb_divisor_shift = i;
282 				glb_index = j;
283 				glb = temp;
284 			}
285 		}
286 	}
287 	switch (flags & CMDF_ROUND_MASK) {
288 	case CMDF_ROUND_NEAREST:
289 	default:
290 		/* if least upper bound is better approximation */
291 		if (lub - *period < *period - glb)
292 			*period = lub;
293 		else
294 			*period = glb;
295 		break;
296 	case CMDF_ROUND_UP:
297 		*period = lub;
298 		break;
299 	case CMDF_ROUND_DOWN:
300 		*period = glb;
301 		break;
302 	}
303 
304 	/* set clock bits for config register appropriately */
305 	devpriv->config_bits &= ~CLOCK_MASK;
306 	if (*period == lub) {
307 		devpriv->config_bits |=
308 		    CLOCK_SELECT_BITS(lub_index) |
309 		    CLOCK_DIVISOR_BITS(lub_divisor_shift);
310 	} else {
311 		devpriv->config_bits |=
312 		    CLOCK_SELECT_BITS(glb_index) |
313 		    CLOCK_DIVISOR_BITS(glb_divisor_shift);
314 	}
315 
316 	return 0;
317 }
318 
a2150_set_chanlist(struct comedi_device * dev,unsigned int start_channel,unsigned int num_channels)319 static int a2150_set_chanlist(struct comedi_device *dev,
320 			      unsigned int start_channel,
321 			      unsigned int num_channels)
322 {
323 	struct a2150_private *devpriv = dev->private;
324 
325 	if (start_channel + num_channels > 4)
326 		return -1;
327 
328 	devpriv->config_bits &= ~CHANNEL_MASK;
329 
330 	switch (num_channels) {
331 	case 1:
332 		devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
333 		break;
334 	case 2:
335 		if (start_channel == 0)
336 			devpriv->config_bits |= CHANNEL_BITS(0x2);
337 		else if (start_channel == 2)
338 			devpriv->config_bits |= CHANNEL_BITS(0x3);
339 		else
340 			return -1;
341 		break;
342 	case 4:
343 		devpriv->config_bits |= CHANNEL_BITS(0x1);
344 		break;
345 	default:
346 		return -1;
347 	}
348 
349 	return 0;
350 }
351 
a2150_ai_check_chanlist(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)352 static int a2150_ai_check_chanlist(struct comedi_device *dev,
353 				   struct comedi_subdevice *s,
354 				   struct comedi_cmd *cmd)
355 {
356 	unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
357 	unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
358 	int i;
359 
360 	if (cmd->chanlist_len == 2 && (chan0 == 1 || chan0 == 3)) {
361 		dev_dbg(dev->class_dev,
362 			"length 2 chanlist must be channels 0,1 or channels 2,3\n");
363 		return -EINVAL;
364 	}
365 
366 	if (cmd->chanlist_len == 3) {
367 		dev_dbg(dev->class_dev,
368 			"chanlist must have 1,2 or 4 channels\n");
369 		return -EINVAL;
370 	}
371 
372 	for (i = 1; i < cmd->chanlist_len; i++) {
373 		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
374 		unsigned int aref = CR_AREF(cmd->chanlist[i]);
375 
376 		if (chan != (chan0 + i)) {
377 			dev_dbg(dev->class_dev,
378 				"entries in chanlist must be consecutive channels, counting upwards\n");
379 			return -EINVAL;
380 		}
381 
382 		if (chan == 2)
383 			aref0 = aref;
384 		if (aref != aref0) {
385 			dev_dbg(dev->class_dev,
386 				"channels 0/1 and 2/3 must have the same analog reference\n");
387 			return -EINVAL;
388 		}
389 	}
390 
391 	return 0;
392 }
393 
a2150_ai_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)394 static int a2150_ai_cmdtest(struct comedi_device *dev,
395 			    struct comedi_subdevice *s, struct comedi_cmd *cmd)
396 {
397 	const struct a2150_board *board = dev->board_ptr;
398 	int err = 0;
399 	unsigned int arg;
400 
401 	/* Step 1 : check if triggers are trivially valid */
402 
403 	err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
404 	err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
405 	err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
406 	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
407 	err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
408 
409 	if (err)
410 		return 1;
411 
412 	/* Step 2a : make sure trigger sources are unique */
413 
414 	err |= comedi_check_trigger_is_unique(cmd->start_src);
415 	err |= comedi_check_trigger_is_unique(cmd->stop_src);
416 
417 	/* Step 2b : and mutually compatible */
418 
419 	if (err)
420 		return 2;
421 
422 	/* Step 3: check if arguments are trivially valid */
423 
424 	err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
425 
426 	if (cmd->convert_src == TRIG_TIMER) {
427 		err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
428 						    board->ai_speed);
429 	}
430 
431 	err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
432 	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
433 					   cmd->chanlist_len);
434 
435 	if (cmd->stop_src == TRIG_COUNT)
436 		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
437 	else	/* TRIG_NONE */
438 		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
439 
440 	if (err)
441 		return 3;
442 
443 	/* step 4: fix up any arguments */
444 
445 	if (cmd->scan_begin_src == TRIG_TIMER) {
446 		arg = cmd->scan_begin_arg;
447 		a2150_get_timing(dev, &arg, cmd->flags);
448 		err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
449 	}
450 
451 	if (err)
452 		return 4;
453 
454 	/* Step 5: check channel list if it exists */
455 	if (cmd->chanlist && cmd->chanlist_len > 0)
456 		err |= a2150_ai_check_chanlist(dev, s, cmd);
457 
458 	if (err)
459 		return 5;
460 
461 	return 0;
462 }
463 
a2150_ai_cmd(struct comedi_device * dev,struct comedi_subdevice * s)464 static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
465 {
466 	struct a2150_private *devpriv = dev->private;
467 	struct comedi_isadma *dma = devpriv->dma;
468 	struct comedi_isadma_desc *desc = &dma->desc[0];
469 	struct comedi_async *async = s->async;
470 	struct comedi_cmd *cmd = &async->cmd;
471 	unsigned int old_config_bits = devpriv->config_bits;
472 	unsigned int trigger_bits;
473 
474 	if (cmd->flags & CMDF_PRIORITY) {
475 		dev_err(dev->class_dev,
476 			"dma incompatible with hard real-time interrupt (CMDF_PRIORITY), aborting\n");
477 		return -1;
478 	}
479 	/* clear fifo and reset triggering circuitry */
480 	outw(0, dev->iobase + FIFO_RESET_REG);
481 
482 	/* setup chanlist */
483 	if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
484 			       cmd->chanlist_len) < 0)
485 		return -1;
486 
487 	/* setup ac/dc coupling */
488 	if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
489 		devpriv->config_bits |= AC0_BIT;
490 	else
491 		devpriv->config_bits &= ~AC0_BIT;
492 	if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
493 		devpriv->config_bits |= AC1_BIT;
494 	else
495 		devpriv->config_bits &= ~AC1_BIT;
496 
497 	/* setup timing */
498 	a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
499 
500 	/* send timing, channel, config bits */
501 	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
502 
503 	/* initialize number of samples remaining */
504 	devpriv->count = cmd->stop_arg * cmd->chanlist_len;
505 
506 	comedi_isadma_disable(desc->chan);
507 
508 	/* set size of transfer to fill in 1/3 second */
509 #define ONE_THIRD_SECOND 333333333
510 	desc->size = comedi_bytes_per_sample(s) * cmd->chanlist_len *
511 		    ONE_THIRD_SECOND / cmd->scan_begin_arg;
512 	if (desc->size > desc->maxsize)
513 		desc->size = desc->maxsize;
514 	if (desc->size < comedi_bytes_per_sample(s))
515 		desc->size = comedi_bytes_per_sample(s);
516 	desc->size -= desc->size % comedi_bytes_per_sample(s);
517 
518 	comedi_isadma_program(desc);
519 
520 	/*
521 	 * Clear dma interrupt before enabling it, to try and get rid of
522 	 * that one spurious interrupt that has been happening.
523 	 */
524 	outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
525 
526 	/* enable dma on card */
527 	devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT;
528 	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
529 
530 	/* may need to wait 72 sampling periods if timing was changed */
531 	comedi_8254_load(dev->pacer, 2, 72, I8254_MODE0 | I8254_BINARY);
532 
533 	/* setup start triggering */
534 	trigger_bits = 0;
535 	/* decide if we need to wait 72 periods for valid data */
536 	if (cmd->start_src == TRIG_NOW &&
537 	    (old_config_bits & CLOCK_MASK) !=
538 	    (devpriv->config_bits & CLOCK_MASK)) {
539 		/* set trigger source to delay trigger */
540 		trigger_bits |= DELAY_TRIGGER_BITS;
541 	} else {
542 		/* otherwise no delay */
543 		trigger_bits |= POST_TRIGGER_BITS;
544 	}
545 	/* enable external hardware trigger */
546 	if (cmd->start_src == TRIG_EXT) {
547 		trigger_bits |= HW_TRIG_EN;
548 	} else if (cmd->start_src == TRIG_OTHER) {
549 		/*
550 		 * XXX add support for level/slope start trigger
551 		 * using TRIG_OTHER
552 		 */
553 		dev_err(dev->class_dev, "you shouldn't see this?\n");
554 	}
555 	/* send trigger config bits */
556 	outw(trigger_bits, dev->iobase + TRIGGER_REG);
557 
558 	/* start acquisition for soft trigger */
559 	if (cmd->start_src == TRIG_NOW)
560 		outw(0, dev->iobase + FIFO_START_REG);
561 
562 	return 0;
563 }
564 
a2150_ai_eoc(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned long context)565 static int a2150_ai_eoc(struct comedi_device *dev,
566 			struct comedi_subdevice *s,
567 			struct comedi_insn *insn,
568 			unsigned long context)
569 {
570 	unsigned int status;
571 
572 	status = inw(dev->iobase + STATUS_REG);
573 	if (status & FNE_BIT)
574 		return 0;
575 	return -EBUSY;
576 }
577 
a2150_ai_rinsn(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)578 static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
579 			  struct comedi_insn *insn, unsigned int *data)
580 {
581 	struct a2150_private *devpriv = dev->private;
582 	unsigned int n;
583 	int ret;
584 
585 	/* clear fifo and reset triggering circuitry */
586 	outw(0, dev->iobase + FIFO_RESET_REG);
587 
588 	/* setup chanlist */
589 	if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
590 		return -1;
591 
592 	/* set dc coupling */
593 	devpriv->config_bits &= ~AC0_BIT;
594 	devpriv->config_bits &= ~AC1_BIT;
595 
596 	/* send timing, channel, config bits */
597 	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
598 
599 	/* disable dma on card */
600 	devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
601 	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
602 
603 	/* setup start triggering */
604 	outw(0, dev->iobase + TRIGGER_REG);
605 
606 	/* start acquisition for soft trigger */
607 	outw(0, dev->iobase + FIFO_START_REG);
608 
609 	/*
610 	 * there is a 35.6 sample delay for data to get through the
611 	 * antialias filter
612 	 */
613 	for (n = 0; n < 36; n++) {
614 		ret = comedi_timeout(dev, s, insn, a2150_ai_eoc, 0);
615 		if (ret)
616 			return ret;
617 
618 		inw(dev->iobase + FIFO_DATA_REG);
619 	}
620 
621 	/* read data */
622 	for (n = 0; n < insn->n; n++) {
623 		ret = comedi_timeout(dev, s, insn, a2150_ai_eoc, 0);
624 		if (ret)
625 			return ret;
626 
627 		data[n] = inw(dev->iobase + FIFO_DATA_REG);
628 		data[n] ^= 0x8000;
629 	}
630 
631 	/* clear fifo and reset triggering circuitry */
632 	outw(0, dev->iobase + FIFO_RESET_REG);
633 
634 	return n;
635 }
636 
a2150_alloc_irq_and_dma(struct comedi_device * dev,struct comedi_devconfig * it)637 static void a2150_alloc_irq_and_dma(struct comedi_device *dev,
638 				    struct comedi_devconfig *it)
639 {
640 	struct a2150_private *devpriv = dev->private;
641 	unsigned int irq_num = it->options[1];
642 	unsigned int dma_chan = it->options[2];
643 
644 	/*
645 	 * Only IRQs 15, 14, 12-9, and 7-3 are valid.
646 	 * Only DMA channels 7-5 and 3-0 are valid.
647 	 */
648 	if (irq_num > 15 || dma_chan > 7 ||
649 	    !((1 << irq_num) & 0xdef8) || !((1 << dma_chan) & 0xef))
650 		return;
651 
652 	if (request_irq(irq_num, a2150_interrupt, 0, dev->board_name, dev))
653 		return;
654 
655 	/* DMA uses 1 buffer */
656 	devpriv->dma = comedi_isadma_alloc(dev, 1, dma_chan, dma_chan,
657 					   A2150_DMA_BUFFER_SIZE,
658 					   COMEDI_ISADMA_READ);
659 	if (!devpriv->dma) {
660 		free_irq(irq_num, dev);
661 	} else {
662 		dev->irq = irq_num;
663 		devpriv->irq_dma_bits = IRQ_LVL_BITS(irq_num) |
664 					DMA_CHAN_BITS(dma_chan);
665 	}
666 }
667 
a2150_free_dma(struct comedi_device * dev)668 static void a2150_free_dma(struct comedi_device *dev)
669 {
670 	struct a2150_private *devpriv = dev->private;
671 
672 	if (devpriv)
673 		comedi_isadma_free(devpriv->dma);
674 }
675 
a2150_probe(struct comedi_device * dev)676 static const struct a2150_board *a2150_probe(struct comedi_device *dev)
677 {
678 	int id = ID_BITS(inw(dev->iobase + STATUS_REG));
679 
680 	if (id >= ARRAY_SIZE(a2150_boards))
681 		return NULL;
682 
683 	return &a2150_boards[id];
684 }
685 
a2150_attach(struct comedi_device * dev,struct comedi_devconfig * it)686 static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
687 {
688 	const struct a2150_board *board;
689 	struct a2150_private *devpriv;
690 	struct comedi_subdevice *s;
691 	static const int timeout = 2000;
692 	int i;
693 	int ret;
694 
695 	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
696 	if (!devpriv)
697 		return -ENOMEM;
698 
699 	ret = comedi_request_region(dev, it->options[0], 0x1c);
700 	if (ret)
701 		return ret;
702 
703 	board = a2150_probe(dev);
704 	if (!board)
705 		return -ENODEV;
706 	dev->board_ptr = board;
707 	dev->board_name = board->name;
708 
709 	/* an IRQ and DMA are required to support async commands */
710 	a2150_alloc_irq_and_dma(dev, it);
711 
712 	dev->pacer = comedi_8254_init(dev->iobase + I8253_BASE_REG,
713 				      0, I8254_IO8, 0);
714 	if (!dev->pacer)
715 		return -ENOMEM;
716 
717 	ret = comedi_alloc_subdevices(dev, 1);
718 	if (ret)
719 		return ret;
720 
721 	/* analog input subdevice */
722 	s = &dev->subdevices[0];
723 	s->type = COMEDI_SUBD_AI;
724 	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER;
725 	s->n_chan = 4;
726 	s->maxdata = 0xffff;
727 	s->range_table = &range_a2150;
728 	s->insn_read = a2150_ai_rinsn;
729 	if (dev->irq) {
730 		dev->read_subdev = s;
731 		s->subdev_flags |= SDF_CMD_READ;
732 		s->len_chanlist = s->n_chan;
733 		s->do_cmd = a2150_ai_cmd;
734 		s->do_cmdtest = a2150_ai_cmdtest;
735 		s->cancel = a2150_cancel;
736 	}
737 
738 	/* set card's irq and dma levels */
739 	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
740 
741 	/* reset and sync adc clock circuitry */
742 	outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
743 	outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
744 	/* initialize configuration register */
745 	devpriv->config_bits = 0;
746 	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
747 	/* wait until offset calibration is done, then enable analog inputs */
748 	for (i = 0; i < timeout; i++) {
749 		if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
750 			break;
751 		usleep_range(1000, 3000);
752 	}
753 	if (i == timeout) {
754 		dev_err(dev->class_dev,
755 			"timed out waiting for offset calibration to complete\n");
756 		return -ETIME;
757 	}
758 	devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
759 	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
760 
761 	return 0;
762 };
763 
a2150_detach(struct comedi_device * dev)764 static void a2150_detach(struct comedi_device *dev)
765 {
766 	if (dev->iobase)
767 		outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
768 	a2150_free_dma(dev);
769 	comedi_legacy_detach(dev);
770 };
771 
772 static struct comedi_driver ni_at_a2150_driver = {
773 	.driver_name	= "ni_at_a2150",
774 	.module		= THIS_MODULE,
775 	.attach		= a2150_attach,
776 	.detach		= a2150_detach,
777 };
778 module_comedi_driver(ni_at_a2150_driver);
779 
780 MODULE_AUTHOR("Comedi https://www.comedi.org");
781 MODULE_DESCRIPTION("Comedi low-level driver");
782 MODULE_LICENSE("GPL");
783