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