1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  comedi/drivers/adl_pci9118.c
4  *
5  *  hardware driver for ADLink cards:
6  *   card:   PCI-9118DG, PCI-9118HG, PCI-9118HR
7  *   driver: pci9118dg,  pci9118hg,  pci9118hr
8  *
9  * Author: Michal Dobes <dobes@tesnet.cz>
10  *
11  */
12 
13 /*
14  * Driver: adl_pci9118
15  * Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
16  * Author: Michal Dobes <dobes@tesnet.cz>
17  * Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
18  * PCI-9118HR (pci9118hr)
19  * Status: works
20  *
21  * This driver supports AI, AO, DI and DO subdevices.
22  * AI subdevice supports cmd and insn interface,
23  * other subdevices support only insn interface.
24  * For AI:
25  * - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
26  * - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
27  * - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
28  * - It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
29  * cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
30  * - If return value of cmdtest is 5 then you've bad channel list
31  * (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
32  * ranges).
33  *
34  * There are some hardware limitations:
35  * a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
36  *  ended inputs.
37  * b) DMA transfers must have the length aligned to two samples (32 bit),
38  *  so there is some problems if cmd->chanlist_len is odd. This driver tries
39  *  bypass this with adding one sample to the end of the every scan and discard
40  *  it on output but this can't be used if cmd->scan_begin_src=TRIG_FOLLOW
41  *  and is used flag CMDF_WAKE_EOS, then driver switch to interrupt driven mode
42  *  with interrupt after every sample.
43  * c) If isn't used DMA then you can use only mode where
44  *  cmd->scan_begin_src=TRIG_FOLLOW.
45  *
46  * Configuration options:
47  * [0] - PCI bus of device (optional)
48  * [1] - PCI slot of device (optional)
49  *	 If bus/slot is not specified, then first available PCI
50  *	 card will be used.
51  * [2] - 0= standard 8 DIFF/16 SE channels configuration
52  *	 n = external multiplexer connected, 1 <= n <= 256
53  * [3] - ignored
54  * [4] - sample&hold signal - card can generate signal for external S&H board
55  *	 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
56  *	 0 != use ADCHN7(pin 23) signal is generated from driver, number say how
57  *		long delay is requested in ns and sign polarity of the hold
58  *		(in this case external multiplexor can serve only 128 channels)
59  * [5] - ignored
60  */
61 
62 /*
63  * FIXME
64  *
65  * All the supported boards have the same PCI vendor and device IDs, so
66  * auto-attachment of PCI devices will always find the first board type.
67  *
68  * Perhaps the boards have different subdevice IDs that we could use to
69  * distinguish them?
70  *
71  * Need some device attributes so the board type can be corrected after
72  * attachment if necessary, and possibly to set other options supported by
73  * manual attachment.
74  */
75 
76 #include <linux/module.h>
77 #include <linux/delay.h>
78 #include <linux/gfp.h>
79 #include <linux/interrupt.h>
80 #include <linux/io.h>
81 
82 #include "../comedi_pci.h"
83 
84 #include "amcc_s5933.h"
85 #include "comedi_8254.h"
86 
87 /*
88  * PCI BAR2 Register map (dev->iobase)
89  */
90 #define PCI9118_TIMER_BASE		0x00
91 #define PCI9118_AI_FIFO_REG		0x10
92 #define PCI9118_AO_REG(x)		(0x10 + ((x) * 4))
93 #define PCI9118_AI_STATUS_REG		0x18
94 #define PCI9118_AI_STATUS_NFULL		BIT(8)	/* 0=FIFO full (fatal) */
95 #define PCI9118_AI_STATUS_NHFULL	BIT(7)	/* 0=FIFO half full */
96 #define PCI9118_AI_STATUS_NEPTY		BIT(6)	/* 0=FIFO empty */
97 #define PCI9118_AI_STATUS_ACMP		BIT(5)	/* 1=about trigger complete */
98 #define PCI9118_AI_STATUS_DTH		BIT(4)	/* 1=ext. digital trigger */
99 #define PCI9118_AI_STATUS_BOVER		BIT(3)	/* 1=burst overrun (fatal) */
100 #define PCI9118_AI_STATUS_ADOS		BIT(2)	/* 1=A/D over speed (warn) */
101 #define PCI9118_AI_STATUS_ADOR		BIT(1)	/* 1=A/D overrun (fatal) */
102 #define PCI9118_AI_STATUS_ADRDY		BIT(0)	/* 1=A/D ready */
103 #define PCI9118_AI_CTRL_REG		0x18
104 #define PCI9118_AI_CTRL_UNIP		BIT(7)	/* 1=unipolar */
105 #define PCI9118_AI_CTRL_DIFF		BIT(6)	/* 1=differential inputs */
106 #define PCI9118_AI_CTRL_SOFTG		BIT(5)	/* 1=8254 software gate */
107 #define PCI9118_AI_CTRL_EXTG		BIT(4)	/* 1=8254 TGIN(pin 46) gate */
108 #define PCI9118_AI_CTRL_EXTM		BIT(3)	/* 1=ext. trigger (pin 44) */
109 #define PCI9118_AI_CTRL_TMRTR		BIT(2)	/* 1=8254 is trigger source */
110 #define PCI9118_AI_CTRL_INT		BIT(1)	/* 1=enable interrupt */
111 #define PCI9118_AI_CTRL_DMA		BIT(0)	/* 1=enable DMA */
112 #define PCI9118_DIO_REG			0x1c
113 #define PCI9118_SOFTTRG_REG		0x20
114 #define PCI9118_AI_CHANLIST_REG		0x24
115 #define PCI9118_AI_CHANLIST_RANGE(x)	(((x) & 0x3) << 8)
116 #define PCI9118_AI_CHANLIST_CHAN(x)	((x) << 0)
117 #define PCI9118_AI_BURST_NUM_REG	0x28
118 #define PCI9118_AI_AUTOSCAN_MODE_REG	0x2c
119 #define PCI9118_AI_CFG_REG		0x30
120 #define PCI9118_AI_CFG_PDTRG		BIT(7)	/* 1=positive trigger */
121 #define PCI9118_AI_CFG_PETRG		BIT(6)	/* 1=positive ext. trigger */
122 #define PCI9118_AI_CFG_BSSH		BIT(5)	/* 1=with sample & hold */
123 #define PCI9118_AI_CFG_BM		BIT(4)	/* 1=burst mode */
124 #define PCI9118_AI_CFG_BS		BIT(3)	/* 1=burst mode start */
125 #define PCI9118_AI_CFG_PM		BIT(2)	/* 1=post trigger */
126 #define PCI9118_AI_CFG_AM		BIT(1)	/* 1=about trigger */
127 #define PCI9118_AI_CFG_START		BIT(0)	/* 1=trigger start */
128 #define PCI9118_FIFO_RESET_REG		0x34
129 #define PCI9118_INT_CTRL_REG		0x38
130 #define PCI9118_INT_CTRL_TIMER		BIT(3)	/* timer interrupt */
131 #define PCI9118_INT_CTRL_ABOUT		BIT(2)	/* about trigger complete */
132 #define PCI9118_INT_CTRL_HFULL		BIT(1)	/* A/D FIFO half full */
133 #define PCI9118_INT_CTRL_DTRG		BIT(0)	/* ext. digital trigger */
134 
135 #define START_AI_EXT	0x01	/* start measure on external trigger */
136 #define STOP_AI_EXT	0x02	/* stop measure on external trigger */
137 #define STOP_AI_INT	0x08	/* stop measure on internal trigger */
138 
139 static const struct comedi_lrange pci9118_ai_range = {
140 	8, {
141 		BIP_RANGE(5),
142 		BIP_RANGE(2.5),
143 		BIP_RANGE(1.25),
144 		BIP_RANGE(0.625),
145 		UNI_RANGE(10),
146 		UNI_RANGE(5),
147 		UNI_RANGE(2.5),
148 		UNI_RANGE(1.25)
149 	}
150 };
151 
152 static const struct comedi_lrange pci9118hg_ai_range = {
153 	8, {
154 		BIP_RANGE(5),
155 		BIP_RANGE(0.5),
156 		BIP_RANGE(0.05),
157 		BIP_RANGE(0.005),
158 		UNI_RANGE(10),
159 		UNI_RANGE(1),
160 		UNI_RANGE(0.1),
161 		UNI_RANGE(0.01)
162 	}
163 };
164 
165 enum pci9118_boardid {
166 	BOARD_PCI9118DG,
167 	BOARD_PCI9118HG,
168 	BOARD_PCI9118HR,
169 };
170 
171 struct pci9118_boardinfo {
172 	const char *name;
173 	unsigned int ai_is_16bit:1;
174 	unsigned int is_hg:1;
175 };
176 
177 static const struct pci9118_boardinfo pci9118_boards[] = {
178 	[BOARD_PCI9118DG] = {
179 		.name		= "pci9118dg",
180 	},
181 	[BOARD_PCI9118HG] = {
182 		.name		= "pci9118hg",
183 		.is_hg		= 1,
184 	},
185 	[BOARD_PCI9118HR] = {
186 		.name		= "pci9118hr",
187 		.ai_is_16bit	= 1,
188 	},
189 };
190 
191 struct pci9118_dmabuf {
192 	unsigned short *virt;	/* virtual address of buffer */
193 	dma_addr_t hw;		/* hardware (bus) address of buffer */
194 	unsigned int size;	/* size of dma buffer in bytes */
195 	unsigned int use_size;	/* which size we may now use for transfer */
196 };
197 
198 struct pci9118_private {
199 	unsigned long iobase_a;	/* base+size for AMCC chip */
200 	unsigned int master:1;
201 	unsigned int dma_doublebuf:1;
202 	unsigned int ai_neverending:1;
203 	unsigned int usedma:1;
204 	unsigned int usemux:1;
205 	unsigned char ai_ctrl;
206 	unsigned char int_ctrl;
207 	unsigned char ai_cfg;
208 	unsigned int ai_do;		/* what do AI? 0=nothing, 1 to 4 mode */
209 	unsigned int ai_n_realscanlen;	/*
210 					 * what we must transfer for one
211 					 * outgoing scan include front/back adds
212 					 */
213 	unsigned int ai_act_dmapos;	/* position in actual real stream */
214 	unsigned int ai_add_front;	/*
215 					 * how many channels we must add
216 					 * before scan to satisfy S&H?
217 					 */
218 	unsigned int ai_add_back;	/*
219 					 * how many channels we must add
220 					 * before scan to satisfy DMA?
221 					 */
222 	unsigned int ai_flags;
223 	char ai12_startstop;		/*
224 					 * measure can start/stop
225 					 * on external trigger
226 					 */
227 	unsigned int dma_actbuf;		/* which buffer is used now */
228 	struct pci9118_dmabuf dmabuf[2];
229 	int softsshdelay;		/*
230 					 * >0 use software S&H,
231 					 * numer is requested delay in ns
232 					 */
233 	unsigned char softsshsample;	/*
234 					 * polarity of S&H signal
235 					 * in sample state
236 					 */
237 	unsigned char softsshhold;	/*
238 					 * polarity of S&H signal
239 					 * in hold state
240 					 */
241 	unsigned int ai_ns_min;
242 };
243 
pci9118_amcc_setup_dma(struct comedi_device * dev,unsigned int buf)244 static void pci9118_amcc_setup_dma(struct comedi_device *dev, unsigned int buf)
245 {
246 	struct pci9118_private *devpriv = dev->private;
247 	struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[buf];
248 
249 	/* set the master write address and transfer count */
250 	outl(dmabuf->hw, devpriv->iobase_a + AMCC_OP_REG_MWAR);
251 	outl(dmabuf->use_size, devpriv->iobase_a + AMCC_OP_REG_MWTC);
252 }
253 
pci9118_amcc_dma_ena(struct comedi_device * dev,bool enable)254 static void pci9118_amcc_dma_ena(struct comedi_device *dev, bool enable)
255 {
256 	struct pci9118_private *devpriv = dev->private;
257 	unsigned int mcsr;
258 
259 	mcsr = inl(devpriv->iobase_a + AMCC_OP_REG_MCSR);
260 	if (enable)
261 		mcsr |= RESET_A2P_FLAGS | A2P_HI_PRIORITY | EN_A2P_TRANSFERS;
262 	else
263 		mcsr &= ~EN_A2P_TRANSFERS;
264 	outl(mcsr, devpriv->iobase_a + AMCC_OP_REG_MCSR);
265 }
266 
pci9118_amcc_int_ena(struct comedi_device * dev,bool enable)267 static void pci9118_amcc_int_ena(struct comedi_device *dev, bool enable)
268 {
269 	struct pci9118_private *devpriv = dev->private;
270 	unsigned int intcsr;
271 
272 	/* enable/disable interrupt for AMCC Incoming Mailbox 4 (32-bit) */
273 	intcsr = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
274 	if (enable)
275 		intcsr |= 0x1f00;
276 	else
277 		intcsr &= ~0x1f00;
278 	outl(intcsr, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
279 }
280 
pci9118_ai_reset_fifo(struct comedi_device * dev)281 static void pci9118_ai_reset_fifo(struct comedi_device *dev)
282 {
283 	/* writing any value resets the A/D FIFO */
284 	outl(0, dev->iobase + PCI9118_FIFO_RESET_REG);
285 }
286 
pci9118_ai_check_chanlist(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)287 static int pci9118_ai_check_chanlist(struct comedi_device *dev,
288 				     struct comedi_subdevice *s,
289 				     struct comedi_cmd *cmd)
290 {
291 	struct pci9118_private *devpriv = dev->private;
292 	unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
293 	unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
294 	int i;
295 
296 	/* single channel scans are always ok */
297 	if (cmd->chanlist_len == 1)
298 		return 0;
299 
300 	for (i = 1; i < cmd->chanlist_len; i++) {
301 		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
302 		unsigned int range = CR_RANGE(cmd->chanlist[i]);
303 		unsigned int aref = CR_AREF(cmd->chanlist[i]);
304 
305 		if (aref != aref0) {
306 			dev_err(dev->class_dev,
307 				"Differential and single ended inputs can't be mixed!\n");
308 			return -EINVAL;
309 		}
310 		if (comedi_range_is_bipolar(s, range) !=
311 		    comedi_range_is_bipolar(s, range0)) {
312 			dev_err(dev->class_dev,
313 				"Bipolar and unipolar ranges can't be mixed!\n");
314 			return -EINVAL;
315 		}
316 		if (!devpriv->usemux && aref == AREF_DIFF &&
317 		    (chan >= (s->n_chan / 2))) {
318 			dev_err(dev->class_dev,
319 				"AREF_DIFF is only available for the first 8 channels!\n");
320 			return -EINVAL;
321 		}
322 	}
323 
324 	return 0;
325 }
326 
pci9118_set_chanlist(struct comedi_device * dev,struct comedi_subdevice * s,int n_chan,unsigned int * chanlist,int frontadd,int backadd)327 static void pci9118_set_chanlist(struct comedi_device *dev,
328 				 struct comedi_subdevice *s,
329 				 int n_chan, unsigned int *chanlist,
330 				 int frontadd, int backadd)
331 {
332 	struct pci9118_private *devpriv = dev->private;
333 	unsigned int chan0 = CR_CHAN(chanlist[0]);
334 	unsigned int range0 = CR_RANGE(chanlist[0]);
335 	unsigned int aref0 = CR_AREF(chanlist[0]);
336 	unsigned int ssh = 0x00;
337 	unsigned int val;
338 	int i;
339 
340 	/*
341 	 * Configure analog input based on the first chanlist entry.
342 	 * All entries are either unipolar or bipolar and single-ended
343 	 * or differential.
344 	 */
345 	devpriv->ai_ctrl = 0;
346 	if (comedi_range_is_unipolar(s, range0))
347 		devpriv->ai_ctrl |= PCI9118_AI_CTRL_UNIP;
348 	if (aref0 == AREF_DIFF)
349 		devpriv->ai_ctrl |= PCI9118_AI_CTRL_DIFF;
350 	outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
351 
352 	/* gods know why this sequence! */
353 	outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
354 	outl(0, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
355 	outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
356 
357 	/* insert channels for S&H */
358 	if (frontadd) {
359 		val = PCI9118_AI_CHANLIST_CHAN(chan0) |
360 		      PCI9118_AI_CHANLIST_RANGE(range0);
361 		ssh = devpriv->softsshsample;
362 		for (i = 0; i < frontadd; i++) {
363 			outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
364 			ssh = devpriv->softsshhold;
365 		}
366 	}
367 
368 	/* store chanlist */
369 	for (i = 0; i < n_chan; i++) {
370 		unsigned int chan = CR_CHAN(chanlist[i]);
371 		unsigned int range = CR_RANGE(chanlist[i]);
372 
373 		val = PCI9118_AI_CHANLIST_CHAN(chan) |
374 		      PCI9118_AI_CHANLIST_RANGE(range);
375 		outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
376 	}
377 
378 	/* insert channels to fit onto 32bit DMA */
379 	if (backadd) {
380 		val = PCI9118_AI_CHANLIST_CHAN(chan0) |
381 		      PCI9118_AI_CHANLIST_RANGE(range0);
382 		for (i = 0; i < backadd; i++)
383 			outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
384 	}
385 	/* close scan queue */
386 	outl(0, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
387 	/* udelay(100); important delay, or first sample will be crippled */
388 }
389 
pci9118_ai_mode4_switch(struct comedi_device * dev,unsigned int next_buf)390 static void pci9118_ai_mode4_switch(struct comedi_device *dev,
391 				    unsigned int next_buf)
392 {
393 	struct pci9118_private *devpriv = dev->private;
394 	struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[next_buf];
395 
396 	devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG |
397 			  PCI9118_AI_CFG_AM;
398 	outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
399 	comedi_8254_load(dev->pacer, 0, dmabuf->hw >> 1,
400 			 I8254_MODE0 | I8254_BINARY);
401 	devpriv->ai_cfg |= PCI9118_AI_CFG_START;
402 	outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
403 }
404 
pci9118_ai_samples_ready(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int n_raw_samples)405 static unsigned int pci9118_ai_samples_ready(struct comedi_device *dev,
406 					     struct comedi_subdevice *s,
407 					     unsigned int n_raw_samples)
408 {
409 	struct pci9118_private *devpriv = dev->private;
410 	struct comedi_cmd *cmd = &s->async->cmd;
411 	unsigned int start_pos = devpriv->ai_add_front;
412 	unsigned int stop_pos = start_pos + cmd->chanlist_len;
413 	unsigned int span_len = stop_pos + devpriv->ai_add_back;
414 	unsigned int dma_pos = devpriv->ai_act_dmapos;
415 	unsigned int whole_spans, n_samples, x;
416 
417 	if (span_len == cmd->chanlist_len)
418 		return n_raw_samples;	/* use all samples */
419 
420 	/*
421 	 * Not all samples are to be used.  Buffer contents consist of a
422 	 * possibly non-whole number of spans and a region of each span
423 	 * is to be used.
424 	 *
425 	 * Account for samples in whole number of spans.
426 	 */
427 	whole_spans = n_raw_samples / span_len;
428 	n_samples = whole_spans * cmd->chanlist_len;
429 	n_raw_samples -= whole_spans * span_len;
430 
431 	/*
432 	 * Deal with remaining samples which could overlap up to two spans.
433 	 */
434 	while (n_raw_samples) {
435 		if (dma_pos < start_pos) {
436 			/* Skip samples before start position. */
437 			x = start_pos - dma_pos;
438 			if (x > n_raw_samples)
439 				x = n_raw_samples;
440 			dma_pos += x;
441 			n_raw_samples -= x;
442 			if (!n_raw_samples)
443 				break;
444 		}
445 		if (dma_pos < stop_pos) {
446 			/* Include samples before stop position. */
447 			x = stop_pos - dma_pos;
448 			if (x > n_raw_samples)
449 				x = n_raw_samples;
450 			n_samples += x;
451 			dma_pos += x;
452 			n_raw_samples -= x;
453 		}
454 		/* Advance to next span. */
455 		start_pos += span_len;
456 		stop_pos += span_len;
457 	}
458 	return n_samples;
459 }
460 
pci9118_ai_dma_xfer(struct comedi_device * dev,struct comedi_subdevice * s,unsigned short * dma_buffer,unsigned int n_raw_samples)461 static void pci9118_ai_dma_xfer(struct comedi_device *dev,
462 				struct comedi_subdevice *s,
463 				unsigned short *dma_buffer,
464 				unsigned int n_raw_samples)
465 {
466 	struct pci9118_private *devpriv = dev->private;
467 	struct comedi_cmd *cmd = &s->async->cmd;
468 	unsigned int start_pos = devpriv->ai_add_front;
469 	unsigned int stop_pos = start_pos + cmd->chanlist_len;
470 	unsigned int span_len = stop_pos + devpriv->ai_add_back;
471 	unsigned int dma_pos = devpriv->ai_act_dmapos;
472 	unsigned int x;
473 
474 	if (span_len == cmd->chanlist_len) {
475 		/* All samples are to be copied. */
476 		comedi_buf_write_samples(s, dma_buffer, n_raw_samples);
477 		dma_pos += n_raw_samples;
478 	} else {
479 		/*
480 		 * Not all samples are to be copied.  Buffer contents consist
481 		 * of a possibly non-whole number of spans and a region of
482 		 * each span is to be copied.
483 		 */
484 		while (n_raw_samples) {
485 			if (dma_pos < start_pos) {
486 				/* Skip samples before start position. */
487 				x = start_pos - dma_pos;
488 				if (x > n_raw_samples)
489 					x = n_raw_samples;
490 				dma_pos += x;
491 				n_raw_samples -= x;
492 				if (!n_raw_samples)
493 					break;
494 			}
495 			if (dma_pos < stop_pos) {
496 				/* Copy samples before stop position. */
497 				x = stop_pos - dma_pos;
498 				if (x > n_raw_samples)
499 					x = n_raw_samples;
500 				comedi_buf_write_samples(s, dma_buffer, x);
501 				dma_pos += x;
502 				n_raw_samples -= x;
503 			}
504 			/* Advance to next span. */
505 			start_pos += span_len;
506 			stop_pos += span_len;
507 		}
508 	}
509 	/* Update position in span for next time. */
510 	devpriv->ai_act_dmapos = dma_pos % span_len;
511 }
512 
pci9118_exttrg_enable(struct comedi_device * dev,bool enable)513 static void pci9118_exttrg_enable(struct comedi_device *dev, bool enable)
514 {
515 	struct pci9118_private *devpriv = dev->private;
516 
517 	if (enable)
518 		devpriv->int_ctrl |= PCI9118_INT_CTRL_DTRG;
519 	else
520 		devpriv->int_ctrl &= ~PCI9118_INT_CTRL_DTRG;
521 	outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
522 
523 	if (devpriv->int_ctrl)
524 		pci9118_amcc_int_ena(dev, true);
525 	else
526 		pci9118_amcc_int_ena(dev, false);
527 }
528 
pci9118_calc_divisors(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int * tim1,unsigned int * tim2,unsigned int flags,int chans,unsigned int * div1,unsigned int * div2,unsigned int chnsshfront)529 static void pci9118_calc_divisors(struct comedi_device *dev,
530 				  struct comedi_subdevice *s,
531 				  unsigned int *tim1, unsigned int *tim2,
532 				  unsigned int flags, int chans,
533 				  unsigned int *div1, unsigned int *div2,
534 				  unsigned int chnsshfront)
535 {
536 	struct comedi_8254 *pacer = dev->pacer;
537 	struct comedi_cmd *cmd = &s->async->cmd;
538 
539 	*div1 = *tim2 / pacer->osc_base;	/* convert timer (burst) */
540 	*div2 = *tim1 / pacer->osc_base;	/* scan timer */
541 	*div2 = *div2 / *div1;			/* major timer is c1*c2 */
542 	if (*div2 < chans)
543 		*div2 = chans;
544 
545 	*tim2 = *div1 * pacer->osc_base;	/* real convert timer */
546 
547 	if (cmd->convert_src == TRIG_NOW && !chnsshfront) {
548 		/* use BSSH signal */
549 		if (*div2 < (chans + 2))
550 			*div2 = chans + 2;
551 	}
552 
553 	*tim1 = *div1 * *div2 * pacer->osc_base;
554 }
555 
pci9118_start_pacer(struct comedi_device * dev,int mode)556 static void pci9118_start_pacer(struct comedi_device *dev, int mode)
557 {
558 	if (mode == 1 || mode == 2 || mode == 4)
559 		comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
560 }
561 
pci9118_ai_cancel(struct comedi_device * dev,struct comedi_subdevice * s)562 static int pci9118_ai_cancel(struct comedi_device *dev,
563 			     struct comedi_subdevice *s)
564 {
565 	struct pci9118_private *devpriv = dev->private;
566 
567 	if (devpriv->usedma)
568 		pci9118_amcc_dma_ena(dev, false);
569 	pci9118_exttrg_enable(dev, false);
570 	comedi_8254_pacer_enable(dev->pacer, 1, 2, false);
571 	/* set default config (disable burst and triggers) */
572 	devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
573 	outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
574 	/* reset acquisition control */
575 	devpriv->ai_ctrl = 0;
576 	outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
577 	outl(0, dev->iobase + PCI9118_AI_BURST_NUM_REG);
578 	/* reset scan queue */
579 	outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
580 	outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
581 	pci9118_ai_reset_fifo(dev);
582 
583 	devpriv->int_ctrl = 0;
584 	outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
585 	pci9118_amcc_int_ena(dev, false);
586 
587 	devpriv->ai_do = 0;
588 	devpriv->usedma = 0;
589 
590 	devpriv->ai_act_dmapos = 0;
591 	s->async->inttrig = NULL;
592 	devpriv->ai_neverending = 0;
593 	devpriv->dma_actbuf = 0;
594 
595 	return 0;
596 }
597 
pci9118_ai_munge(struct comedi_device * dev,struct comedi_subdevice * s,void * data,unsigned int num_bytes,unsigned int start_chan_index)598 static void pci9118_ai_munge(struct comedi_device *dev,
599 			     struct comedi_subdevice *s, void *data,
600 			     unsigned int num_bytes,
601 			     unsigned int start_chan_index)
602 {
603 	struct pci9118_private *devpriv = dev->private;
604 	unsigned short *array = data;
605 	unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes);
606 	unsigned int i;
607 	__be16 *barray = data;
608 
609 	for (i = 0; i < num_samples; i++) {
610 		if (devpriv->usedma)
611 			array[i] = be16_to_cpu(barray[i]);
612 		if (s->maxdata == 0xffff)
613 			array[i] ^= 0x8000;
614 		else
615 			array[i] = (array[i] >> 4) & 0x0fff;
616 	}
617 }
618 
pci9118_ai_get_onesample(struct comedi_device * dev,struct comedi_subdevice * s)619 static void pci9118_ai_get_onesample(struct comedi_device *dev,
620 				     struct comedi_subdevice *s)
621 {
622 	struct pci9118_private *devpriv = dev->private;
623 	struct comedi_cmd *cmd = &s->async->cmd;
624 	unsigned short sampl;
625 
626 	sampl = inl(dev->iobase + PCI9118_AI_FIFO_REG);
627 
628 	comedi_buf_write_samples(s, &sampl, 1);
629 
630 	if (!devpriv->ai_neverending) {
631 		if (s->async->scans_done >= cmd->stop_arg)
632 			s->async->events |= COMEDI_CB_EOA;
633 	}
634 }
635 
pci9118_ai_get_dma(struct comedi_device * dev,struct comedi_subdevice * s)636 static void pci9118_ai_get_dma(struct comedi_device *dev,
637 			       struct comedi_subdevice *s)
638 {
639 	struct pci9118_private *devpriv = dev->private;
640 	struct comedi_cmd *cmd = &s->async->cmd;
641 	struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[devpriv->dma_actbuf];
642 	unsigned int n_all = comedi_bytes_to_samples(s, dmabuf->use_size);
643 	unsigned int n_valid;
644 	bool more_dma;
645 
646 	/* determine whether more DMA buffers to do after this one */
647 	n_valid = pci9118_ai_samples_ready(dev, s, n_all);
648 	more_dma = n_valid < comedi_nsamples_left(s, n_valid + 1);
649 
650 	/* switch DMA buffers and restart DMA if double buffering */
651 	if (more_dma && devpriv->dma_doublebuf) {
652 		devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
653 		pci9118_amcc_setup_dma(dev, devpriv->dma_actbuf);
654 		if (devpriv->ai_do == 4)
655 			pci9118_ai_mode4_switch(dev, devpriv->dma_actbuf);
656 	}
657 
658 	if (n_all)
659 		pci9118_ai_dma_xfer(dev, s, dmabuf->virt, n_all);
660 
661 	if (!devpriv->ai_neverending) {
662 		if (s->async->scans_done >= cmd->stop_arg)
663 			s->async->events |= COMEDI_CB_EOA;
664 	}
665 
666 	if (s->async->events & COMEDI_CB_CANCEL_MASK)
667 		more_dma = false;
668 
669 	/* restart DMA if not double buffering */
670 	if (more_dma && !devpriv->dma_doublebuf) {
671 		pci9118_amcc_setup_dma(dev, 0);
672 		if (devpriv->ai_do == 4)
673 			pci9118_ai_mode4_switch(dev, 0);
674 	}
675 }
676 
pci9118_interrupt(int irq,void * d)677 static irqreturn_t pci9118_interrupt(int irq, void *d)
678 {
679 	struct comedi_device *dev = d;
680 	struct comedi_subdevice *s = dev->read_subdev;
681 	struct pci9118_private *devpriv = dev->private;
682 	unsigned int intsrc;	/* IRQ reasons from card */
683 	unsigned int intcsr;	/* INT register from AMCC chip */
684 	unsigned int adstat;	/* STATUS register */
685 
686 	if (!dev->attached)
687 		return IRQ_NONE;
688 
689 	intsrc = inl(dev->iobase + PCI9118_INT_CTRL_REG) & 0xf;
690 	intcsr = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
691 
692 	if (!intsrc && !(intcsr & ANY_S593X_INT))
693 		return IRQ_NONE;
694 
695 	outl(intcsr | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
696 
697 	if (intcsr & MASTER_ABORT_INT) {
698 		dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
699 		s->async->events |= COMEDI_CB_ERROR;
700 		goto interrupt_exit;
701 	}
702 
703 	if (intcsr & TARGET_ABORT_INT) {
704 		dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
705 		s->async->events |= COMEDI_CB_ERROR;
706 		goto interrupt_exit;
707 	}
708 
709 	adstat = inl(dev->iobase + PCI9118_AI_STATUS_REG);
710 	if ((adstat & PCI9118_AI_STATUS_NFULL) == 0) {
711 		dev_err(dev->class_dev,
712 			"A/D FIFO Full status (Fatal Error!)\n");
713 		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
714 		goto interrupt_exit;
715 	}
716 	if (adstat & PCI9118_AI_STATUS_BOVER) {
717 		dev_err(dev->class_dev,
718 			"A/D Burst Mode Overrun Status (Fatal Error!)\n");
719 		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
720 		goto interrupt_exit;
721 	}
722 	if (adstat & PCI9118_AI_STATUS_ADOS) {
723 		dev_err(dev->class_dev, "A/D Over Speed Status (Warning!)\n");
724 		s->async->events |= COMEDI_CB_ERROR;
725 		goto interrupt_exit;
726 	}
727 	if (adstat & PCI9118_AI_STATUS_ADOR) {
728 		dev_err(dev->class_dev, "A/D Overrun Status (Fatal Error!)\n");
729 		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
730 		goto interrupt_exit;
731 	}
732 
733 	if (!devpriv->ai_do)
734 		return IRQ_HANDLED;
735 
736 	if (devpriv->ai12_startstop) {
737 		if ((adstat & PCI9118_AI_STATUS_DTH) &&
738 		    (intsrc & PCI9118_INT_CTRL_DTRG)) {
739 			/* start/stop of measure */
740 			if (devpriv->ai12_startstop & START_AI_EXT) {
741 				/* deactivate EXT trigger */
742 				devpriv->ai12_startstop &= ~START_AI_EXT;
743 				if (!(devpriv->ai12_startstop & STOP_AI_EXT))
744 					pci9118_exttrg_enable(dev, false);
745 
746 				/* start pacer */
747 				pci9118_start_pacer(dev, devpriv->ai_do);
748 				outl(devpriv->ai_ctrl,
749 				     dev->iobase + PCI9118_AI_CTRL_REG);
750 			} else if (devpriv->ai12_startstop & STOP_AI_EXT) {
751 				/* deactivate EXT trigger */
752 				devpriv->ai12_startstop &= ~STOP_AI_EXT;
753 				pci9118_exttrg_enable(dev, false);
754 
755 				/* on next interrupt measure will stop */
756 				devpriv->ai_neverending = 0;
757 			}
758 		}
759 	}
760 
761 	if (devpriv->usedma)
762 		pci9118_ai_get_dma(dev, s);
763 	else
764 		pci9118_ai_get_onesample(dev, s);
765 
766 interrupt_exit:
767 	comedi_handle_events(dev, s);
768 	return IRQ_HANDLED;
769 }
770 
pci9118_ai_cmd_start(struct comedi_device * dev)771 static void pci9118_ai_cmd_start(struct comedi_device *dev)
772 {
773 	struct pci9118_private *devpriv = dev->private;
774 
775 	outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
776 	outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
777 	if (devpriv->ai_do != 3) {
778 		pci9118_start_pacer(dev, devpriv->ai_do);
779 		devpriv->ai_ctrl |= PCI9118_AI_CTRL_SOFTG;
780 	}
781 	outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
782 }
783 
pci9118_ai_inttrig(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int trig_num)784 static int pci9118_ai_inttrig(struct comedi_device *dev,
785 			      struct comedi_subdevice *s,
786 			      unsigned int trig_num)
787 {
788 	struct comedi_cmd *cmd = &s->async->cmd;
789 
790 	if (trig_num != cmd->start_arg)
791 		return -EINVAL;
792 
793 	s->async->inttrig = NULL;
794 	pci9118_ai_cmd_start(dev);
795 
796 	return 1;
797 }
798 
pci9118_ai_setup_dma(struct comedi_device * dev,struct comedi_subdevice * s)799 static int pci9118_ai_setup_dma(struct comedi_device *dev,
800 				struct comedi_subdevice *s)
801 {
802 	struct pci9118_private *devpriv = dev->private;
803 	struct comedi_cmd *cmd = &s->async->cmd;
804 	struct pci9118_dmabuf *dmabuf0 = &devpriv->dmabuf[0];
805 	struct pci9118_dmabuf *dmabuf1 = &devpriv->dmabuf[1];
806 	unsigned int dmalen0 = dmabuf0->size;
807 	unsigned int dmalen1 = dmabuf1->size;
808 	unsigned int scan_bytes = devpriv->ai_n_realscanlen *
809 				  comedi_bytes_per_sample(s);
810 
811 	/* isn't output buff smaller that our DMA buff? */
812 	if (dmalen0 > s->async->prealloc_bufsz) {
813 		/* align to 32bit down */
814 		dmalen0 = s->async->prealloc_bufsz & ~3L;
815 	}
816 	if (dmalen1 > s->async->prealloc_bufsz) {
817 		/* align to 32bit down */
818 		dmalen1 = s->async->prealloc_bufsz & ~3L;
819 	}
820 
821 	/* we want wake up every scan? */
822 	if (devpriv->ai_flags & CMDF_WAKE_EOS) {
823 		if (dmalen0 < scan_bytes) {
824 			/* uff, too short DMA buffer, disable EOS support! */
825 			devpriv->ai_flags &= (~CMDF_WAKE_EOS);
826 			dev_info(dev->class_dev,
827 				 "WAR: DMA0 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n",
828 				  dmalen0, scan_bytes);
829 		} else {
830 			/* short first DMA buffer to one scan */
831 			dmalen0 = scan_bytes;
832 			if (dmalen0 < 4) {
833 				dev_info(dev->class_dev,
834 					 "ERR: DMA0 buf len bug? (%d<4)\n",
835 					 dmalen0);
836 				dmalen0 = 4;
837 			}
838 		}
839 	}
840 	if (devpriv->ai_flags & CMDF_WAKE_EOS) {
841 		if (dmalen1 < scan_bytes) {
842 			/* uff, too short DMA buffer, disable EOS support! */
843 			devpriv->ai_flags &= (~CMDF_WAKE_EOS);
844 			dev_info(dev->class_dev,
845 				 "WAR: DMA1 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n",
846 				 dmalen1, scan_bytes);
847 		} else {
848 			/* short second DMA buffer to one scan */
849 			dmalen1 = scan_bytes;
850 			if (dmalen1 < 4) {
851 				dev_info(dev->class_dev,
852 					 "ERR: DMA1 buf len bug? (%d<4)\n",
853 					 dmalen1);
854 				dmalen1 = 4;
855 			}
856 		}
857 	}
858 
859 	/* transfer without CMDF_WAKE_EOS */
860 	if (!(devpriv->ai_flags & CMDF_WAKE_EOS)) {
861 		unsigned int tmp;
862 
863 		/* if it's possible then align DMA buffers to length of scan */
864 		tmp = dmalen0;
865 		dmalen0 = (dmalen0 / scan_bytes) * scan_bytes;
866 		dmalen0 &= ~3L;
867 		if (!dmalen0)
868 			dmalen0 = tmp;	/* uff. very long scan? */
869 		tmp = dmalen1;
870 		dmalen1 = (dmalen1 / scan_bytes) * scan_bytes;
871 		dmalen1 &= ~3L;
872 		if (!dmalen1)
873 			dmalen1 = tmp;	/* uff. very long scan? */
874 		/*
875 		 * if measure isn't neverending then test, if it fits whole
876 		 * into one or two DMA buffers
877 		 */
878 		if (!devpriv->ai_neverending) {
879 			unsigned long long scanlen;
880 
881 			scanlen = (unsigned long long)scan_bytes *
882 				  cmd->stop_arg;
883 
884 			/* fits whole measure into one DMA buffer? */
885 			if (dmalen0 > scanlen) {
886 				dmalen0 = scanlen;
887 				dmalen0 &= ~3L;
888 			} else {
889 				/* fits whole measure into two DMA buffer? */
890 				if (dmalen1 > (scanlen - dmalen0)) {
891 					dmalen1 = scanlen - dmalen0;
892 					dmalen1 &= ~3L;
893 				}
894 			}
895 		}
896 	}
897 
898 	/* these DMA buffer size will be used */
899 	devpriv->dma_actbuf = 0;
900 	dmabuf0->use_size = dmalen0;
901 	dmabuf1->use_size = dmalen1;
902 
903 	pci9118_amcc_dma_ena(dev, false);
904 	pci9118_amcc_setup_dma(dev, 0);
905 	/* init DMA transfer */
906 	outl(0x00000000 | AINT_WRITE_COMPL,
907 	     devpriv->iobase_a + AMCC_OP_REG_INTCSR);
908 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
909 	pci9118_amcc_dma_ena(dev, true);
910 	outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS,
911 	     devpriv->iobase_a + AMCC_OP_REG_INTCSR);
912 						/* allow bus mastering */
913 
914 	return 0;
915 }
916 
pci9118_ai_cmd(struct comedi_device * dev,struct comedi_subdevice * s)917 static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
918 {
919 	struct pci9118_private *devpriv = dev->private;
920 	struct comedi_8254 *pacer = dev->pacer;
921 	struct comedi_cmd *cmd = &s->async->cmd;
922 	unsigned int addchans = 0;
923 	unsigned int scanlen;
924 
925 	devpriv->ai12_startstop = 0;
926 	devpriv->ai_flags = cmd->flags;
927 	devpriv->ai_add_front = 0;
928 	devpriv->ai_add_back = 0;
929 
930 	/* prepare for start/stop conditions */
931 	if (cmd->start_src == TRIG_EXT)
932 		devpriv->ai12_startstop |= START_AI_EXT;
933 	if (cmd->stop_src == TRIG_EXT) {
934 		devpriv->ai_neverending = 1;
935 		devpriv->ai12_startstop |= STOP_AI_EXT;
936 	}
937 	if (cmd->stop_src == TRIG_NONE)
938 		devpriv->ai_neverending = 1;
939 	if (cmd->stop_src == TRIG_COUNT)
940 		devpriv->ai_neverending = 0;
941 
942 	/*
943 	 * use additional sample at end of every scan
944 	 * to satisty DMA 32 bit transfer?
945 	 */
946 	devpriv->ai_add_front = 0;
947 	devpriv->ai_add_back = 0;
948 	if (devpriv->master) {
949 		devpriv->usedma = 1;
950 		if ((cmd->flags & CMDF_WAKE_EOS) &&
951 		    (cmd->scan_end_arg == 1)) {
952 			if (cmd->convert_src == TRIG_NOW)
953 				devpriv->ai_add_back = 1;
954 			if (cmd->convert_src == TRIG_TIMER) {
955 				devpriv->usedma = 0;
956 					/*
957 					 * use INT transfer if scanlist
958 					 * have only one channel
959 					 */
960 			}
961 		}
962 		if ((cmd->flags & CMDF_WAKE_EOS) &&
963 		    (cmd->scan_end_arg & 1) &&
964 		    (cmd->scan_end_arg > 1)) {
965 			if (cmd->scan_begin_src == TRIG_FOLLOW) {
966 				devpriv->usedma = 0;
967 				/*
968 				 * XXX maybe can be corrected to use 16 bit DMA
969 				 */
970 			} else {	/*
971 					 * well, we must insert one sample
972 					 * to end of EOS to meet 32 bit transfer
973 					 */
974 				devpriv->ai_add_back = 1;
975 			}
976 		}
977 	} else {	/* interrupt transfer don't need any correction */
978 		devpriv->usedma = 0;
979 	}
980 
981 	/*
982 	 * we need software S&H signal?
983 	 * It adds two samples before every scan as minimum
984 	 */
985 	if (cmd->convert_src == TRIG_NOW && devpriv->softsshdelay) {
986 		devpriv->ai_add_front = 2;
987 		if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
988 							/* move it to front */
989 			devpriv->ai_add_front++;
990 			devpriv->ai_add_back = 0;
991 		}
992 		if (cmd->convert_arg < devpriv->ai_ns_min)
993 			cmd->convert_arg = devpriv->ai_ns_min;
994 		addchans = devpriv->softsshdelay / cmd->convert_arg;
995 		if (devpriv->softsshdelay % cmd->convert_arg)
996 			addchans++;
997 		if (addchans > (devpriv->ai_add_front - 1)) {
998 							/* uff, still short */
999 			devpriv->ai_add_front = addchans + 1;
1000 			if (devpriv->usedma == 1)
1001 				if ((devpriv->ai_add_front +
1002 				     cmd->chanlist_len +
1003 				     devpriv->ai_add_back) & 1)
1004 					devpriv->ai_add_front++;
1005 							/* round up to 32 bit */
1006 		}
1007 	}
1008 	/* well, we now know what must be all added */
1009 	scanlen = devpriv->ai_add_front + cmd->chanlist_len +
1010 		  devpriv->ai_add_back;
1011 	/*
1012 	 * what we must take from card in real to have cmd->scan_end_arg
1013 	 * on output?
1014 	 */
1015 	devpriv->ai_n_realscanlen = scanlen *
1016 				    (cmd->scan_end_arg / cmd->chanlist_len);
1017 
1018 	if (scanlen > s->len_chanlist) {
1019 		dev_err(dev->class_dev,
1020 			"range/channel list is too long for actual configuration!\n");
1021 		return -EINVAL;
1022 	}
1023 
1024 	/*
1025 	 * Configure analog input and load the chanlist.
1026 	 * The acquisition control bits are enabled later.
1027 	 */
1028 	pci9118_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist,
1029 			     devpriv->ai_add_front, devpriv->ai_add_back);
1030 
1031 	/* Determine acquisition mode and calculate timing */
1032 	devpriv->ai_do = 0;
1033 	if (cmd->scan_begin_src != TRIG_TIMER &&
1034 	    cmd->convert_src == TRIG_TIMER) {
1035 		/* cascaded timers 1 and 2 are used for convert timing */
1036 		if (cmd->scan_begin_src == TRIG_EXT)
1037 			devpriv->ai_do = 4;
1038 		else
1039 			devpriv->ai_do = 1;
1040 
1041 		comedi_8254_cascade_ns_to_timer(pacer, &cmd->convert_arg,
1042 						devpriv->ai_flags &
1043 						CMDF_ROUND_NEAREST);
1044 		comedi_8254_update_divisors(pacer);
1045 
1046 		devpriv->ai_ctrl |= PCI9118_AI_CTRL_TMRTR;
1047 
1048 		if (!devpriv->usedma) {
1049 			devpriv->ai_ctrl |= PCI9118_AI_CTRL_INT;
1050 			devpriv->int_ctrl |= PCI9118_INT_CTRL_TIMER;
1051 		}
1052 
1053 		if (cmd->scan_begin_src == TRIG_EXT) {
1054 			struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[0];
1055 
1056 			devpriv->ai_cfg |= PCI9118_AI_CFG_AM;
1057 			outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
1058 			comedi_8254_load(pacer, 0, dmabuf->hw >> 1,
1059 					 I8254_MODE0 | I8254_BINARY);
1060 			devpriv->ai_cfg |= PCI9118_AI_CFG_START;
1061 		}
1062 	}
1063 
1064 	if (cmd->scan_begin_src == TRIG_TIMER &&
1065 	    cmd->convert_src != TRIG_EXT) {
1066 		if (!devpriv->usedma) {
1067 			dev_err(dev->class_dev,
1068 				"cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!\n");
1069 			return -EIO;
1070 		}
1071 
1072 		/* double timed action */
1073 		devpriv->ai_do = 2;
1074 
1075 		pci9118_calc_divisors(dev, s,
1076 				      &cmd->scan_begin_arg, &cmd->convert_arg,
1077 				      devpriv->ai_flags,
1078 				      devpriv->ai_n_realscanlen,
1079 				      &pacer->divisor1,
1080 				      &pacer->divisor2,
1081 				      devpriv->ai_add_front);
1082 
1083 		devpriv->ai_ctrl |= PCI9118_AI_CTRL_TMRTR;
1084 		devpriv->ai_cfg |= PCI9118_AI_CFG_BM | PCI9118_AI_CFG_BS;
1085 		if (cmd->convert_src == TRIG_NOW && !devpriv->softsshdelay)
1086 			devpriv->ai_cfg |= PCI9118_AI_CFG_BSSH;
1087 		outl(devpriv->ai_n_realscanlen,
1088 		     dev->iobase + PCI9118_AI_BURST_NUM_REG);
1089 	}
1090 
1091 	if (cmd->scan_begin_src == TRIG_FOLLOW &&
1092 	    cmd->convert_src == TRIG_EXT) {
1093 		/* external trigger conversion */
1094 		devpriv->ai_do = 3;
1095 
1096 		devpriv->ai_ctrl |= PCI9118_AI_CTRL_EXTM;
1097 	}
1098 
1099 	if (devpriv->ai_do == 0) {
1100 		dev_err(dev->class_dev,
1101 			"Unable to determine acquisition mode! BUG in (*do_cmdtest)?\n");
1102 		return -EINVAL;
1103 	}
1104 
1105 	if (devpriv->usedma)
1106 		devpriv->ai_ctrl |= PCI9118_AI_CTRL_DMA;
1107 
1108 	/* set default config (disable burst and triggers) */
1109 	devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
1110 	outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
1111 	udelay(1);
1112 	pci9118_ai_reset_fifo(dev);
1113 
1114 	/* clear A/D and INT status registers */
1115 	inl(dev->iobase + PCI9118_AI_STATUS_REG);
1116 	inl(dev->iobase + PCI9118_INT_CTRL_REG);
1117 
1118 	devpriv->ai_act_dmapos = 0;
1119 
1120 	if (devpriv->usedma) {
1121 		pci9118_ai_setup_dma(dev, s);
1122 
1123 		outl(0x02000000 | AINT_WRITE_COMPL,
1124 		     devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1125 	} else {
1126 		pci9118_amcc_int_ena(dev, true);
1127 	}
1128 
1129 	/* start async command now or wait for internal trigger */
1130 	if (cmd->start_src == TRIG_NOW)
1131 		pci9118_ai_cmd_start(dev);
1132 	else if (cmd->start_src == TRIG_INT)
1133 		s->async->inttrig = pci9118_ai_inttrig;
1134 
1135 	/* enable external trigger for command start/stop */
1136 	if (cmd->start_src == TRIG_EXT || cmd->stop_src == TRIG_EXT)
1137 		pci9118_exttrg_enable(dev, true);
1138 
1139 	return 0;
1140 }
1141 
pci9118_ai_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)1142 static int pci9118_ai_cmdtest(struct comedi_device *dev,
1143 			      struct comedi_subdevice *s,
1144 			      struct comedi_cmd *cmd)
1145 {
1146 	struct pci9118_private *devpriv = dev->private;
1147 	int err = 0;
1148 	unsigned int flags;
1149 	unsigned int arg;
1150 
1151 	/* Step 1 : check if triggers are trivially valid */
1152 
1153 	err |= comedi_check_trigger_src(&cmd->start_src,
1154 					TRIG_NOW | TRIG_EXT | TRIG_INT);
1155 
1156 	flags = TRIG_FOLLOW;
1157 	if (devpriv->master)
1158 		flags |= TRIG_TIMER | TRIG_EXT;
1159 	err |= comedi_check_trigger_src(&cmd->scan_begin_src, flags);
1160 
1161 	flags = TRIG_TIMER | TRIG_EXT;
1162 	if (devpriv->master)
1163 		flags |= TRIG_NOW;
1164 	err |= comedi_check_trigger_src(&cmd->convert_src, flags);
1165 
1166 	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1167 	err |= comedi_check_trigger_src(&cmd->stop_src,
1168 					TRIG_COUNT | TRIG_NONE | TRIG_EXT);
1169 
1170 	if (err)
1171 		return 1;
1172 
1173 	/* Step 2a : make sure trigger sources are unique */
1174 
1175 	err |= comedi_check_trigger_is_unique(cmd->start_src);
1176 	err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
1177 	err |= comedi_check_trigger_is_unique(cmd->convert_src);
1178 	err |= comedi_check_trigger_is_unique(cmd->stop_src);
1179 
1180 	/* Step 2b : and mutually compatible */
1181 
1182 	if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1183 		err |= -EINVAL;
1184 
1185 	if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
1186 	    (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW))))
1187 		err |= -EINVAL;
1188 
1189 	if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
1190 	    (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT))))
1191 		err |= -EINVAL;
1192 
1193 	if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1194 		err |= -EINVAL;
1195 
1196 	if (err)
1197 		return 2;
1198 
1199 	/* Step 3: check if arguments are trivially valid */
1200 
1201 	switch (cmd->start_src) {
1202 	case TRIG_NOW:
1203 	case TRIG_EXT:
1204 		err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
1205 		break;
1206 	case TRIG_INT:
1207 		/* start_arg is the internal trigger (any value) */
1208 		break;
1209 	}
1210 
1211 	if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
1212 		err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1213 
1214 	if ((cmd->scan_begin_src == TRIG_TIMER) &&
1215 	    (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
1216 		cmd->scan_begin_src = TRIG_FOLLOW;
1217 		cmd->convert_arg = cmd->scan_begin_arg;
1218 		cmd->scan_begin_arg = 0;
1219 	}
1220 
1221 	if (cmd->scan_begin_src == TRIG_TIMER) {
1222 		err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
1223 						    devpriv->ai_ns_min);
1224 	}
1225 
1226 	if (cmd->scan_begin_src == TRIG_EXT) {
1227 		if (cmd->scan_begin_arg) {
1228 			cmd->scan_begin_arg = 0;
1229 			err |= -EINVAL;
1230 			err |= comedi_check_trigger_arg_max(&cmd->scan_end_arg,
1231 							    65535);
1232 		}
1233 	}
1234 
1235 	if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
1236 		err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
1237 						    devpriv->ai_ns_min);
1238 	}
1239 
1240 	if (cmd->convert_src == TRIG_EXT)
1241 		err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
1242 
1243 	if (cmd->stop_src == TRIG_COUNT)
1244 		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
1245 	else	/* TRIG_NONE */
1246 		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
1247 
1248 	err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
1249 
1250 	err |= comedi_check_trigger_arg_min(&cmd->scan_end_arg,
1251 					    cmd->chanlist_len);
1252 
1253 	if ((cmd->scan_end_arg % cmd->chanlist_len)) {
1254 		cmd->scan_end_arg =
1255 		    cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
1256 		err |= -EINVAL;
1257 	}
1258 
1259 	if (err)
1260 		return 3;
1261 
1262 	/* step 4: fix up any arguments */
1263 
1264 	if (cmd->scan_begin_src == TRIG_TIMER) {
1265 		arg = cmd->scan_begin_arg;
1266 		comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
1267 		err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
1268 	}
1269 
1270 	if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
1271 		arg = cmd->convert_arg;
1272 		comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
1273 		err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
1274 
1275 		if (cmd->scan_begin_src == TRIG_TIMER &&
1276 		    cmd->convert_src == TRIG_NOW) {
1277 			if (cmd->convert_arg == 0) {
1278 				arg = devpriv->ai_ns_min *
1279 				      (cmd->scan_end_arg + 2);
1280 			} else {
1281 				arg = cmd->convert_arg * cmd->chanlist_len;
1282 			}
1283 			err |= comedi_check_trigger_arg_min(
1284 				&cmd->scan_begin_arg, arg);
1285 		}
1286 	}
1287 
1288 	if (err)
1289 		return 4;
1290 
1291 	/* Step 5: check channel list if it exists */
1292 
1293 	if (cmd->chanlist)
1294 		err |= pci9118_ai_check_chanlist(dev, s, cmd);
1295 
1296 	if (err)
1297 		return 5;
1298 
1299 	return 0;
1300 }
1301 
pci9118_ai_eoc(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned long context)1302 static int pci9118_ai_eoc(struct comedi_device *dev,
1303 			  struct comedi_subdevice *s,
1304 			  struct comedi_insn *insn,
1305 			  unsigned long context)
1306 {
1307 	unsigned int status;
1308 
1309 	status = inl(dev->iobase + PCI9118_AI_STATUS_REG);
1310 	if (status & PCI9118_AI_STATUS_ADRDY)
1311 		return 0;
1312 	return -EBUSY;
1313 }
1314 
pci9118_ai_start_conv(struct comedi_device * dev)1315 static void pci9118_ai_start_conv(struct comedi_device *dev)
1316 {
1317 	/* writing any value triggers an A/D conversion */
1318 	outl(0, dev->iobase + PCI9118_SOFTTRG_REG);
1319 }
1320 
pci9118_ai_insn_read(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)1321 static int pci9118_ai_insn_read(struct comedi_device *dev,
1322 				struct comedi_subdevice *s,
1323 				struct comedi_insn *insn,
1324 				unsigned int *data)
1325 {
1326 	struct pci9118_private *devpriv = dev->private;
1327 	unsigned int val;
1328 	int ret;
1329 	int i;
1330 
1331        /*
1332 	* Configure analog input based on the chanspec.
1333 	* Acqusition is software controlled without interrupts.
1334 	*/
1335 	pci9118_set_chanlist(dev, s, 1, &insn->chanspec, 0, 0);
1336 
1337 	/* set default config (disable burst and triggers) */
1338 	devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
1339 	outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
1340 
1341 	pci9118_ai_reset_fifo(dev);
1342 
1343 	for (i = 0; i < insn->n; i++) {
1344 		pci9118_ai_start_conv(dev);
1345 
1346 		ret = comedi_timeout(dev, s, insn, pci9118_ai_eoc, 0);
1347 		if (ret)
1348 			return ret;
1349 
1350 		val = inl(dev->iobase + PCI9118_AI_FIFO_REG);
1351 		if (s->maxdata == 0xffff)
1352 			data[i] = (val & 0xffff) ^ 0x8000;
1353 		else
1354 			data[i] = (val >> 4) & 0xfff;
1355 	}
1356 
1357 	return insn->n;
1358 }
1359 
pci9118_ao_insn_write(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)1360 static int pci9118_ao_insn_write(struct comedi_device *dev,
1361 				 struct comedi_subdevice *s,
1362 				 struct comedi_insn *insn,
1363 				 unsigned int *data)
1364 {
1365 	unsigned int chan = CR_CHAN(insn->chanspec);
1366 	unsigned int val = s->readback[chan];
1367 	int i;
1368 
1369 	for (i = 0; i < insn->n; i++) {
1370 		val = data[i];
1371 		outl(val, dev->iobase + PCI9118_AO_REG(chan));
1372 	}
1373 	s->readback[chan] = val;
1374 
1375 	return insn->n;
1376 }
1377 
pci9118_di_insn_bits(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)1378 static int pci9118_di_insn_bits(struct comedi_device *dev,
1379 				struct comedi_subdevice *s,
1380 				struct comedi_insn *insn,
1381 				unsigned int *data)
1382 {
1383 	/*
1384 	 * The digital inputs and outputs share the read register.
1385 	 * bits [7:4] are the digital outputs
1386 	 * bits [3:0] are the digital inputs
1387 	 */
1388 	data[1] = inl(dev->iobase + PCI9118_DIO_REG) & 0xf;
1389 
1390 	return insn->n;
1391 }
1392 
pci9118_do_insn_bits(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)1393 static int pci9118_do_insn_bits(struct comedi_device *dev,
1394 				struct comedi_subdevice *s,
1395 				struct comedi_insn *insn,
1396 				unsigned int *data)
1397 {
1398 	/*
1399 	 * The digital outputs are set with the same register that
1400 	 * the digital inputs and outputs are read from. But the
1401 	 * outputs are set with bits [3:0] so we can simply write
1402 	 * the s->state to set them.
1403 	 */
1404 	if (comedi_dio_update_state(s, data))
1405 		outl(s->state, dev->iobase + PCI9118_DIO_REG);
1406 
1407 	data[1] = s->state;
1408 
1409 	return insn->n;
1410 }
1411 
pci9118_reset(struct comedi_device * dev)1412 static void pci9118_reset(struct comedi_device *dev)
1413 {
1414 	/* reset analog input subsystem */
1415 	outl(0, dev->iobase + PCI9118_INT_CTRL_REG);
1416 	outl(0, dev->iobase + PCI9118_AI_CTRL_REG);
1417 	outl(0, dev->iobase + PCI9118_AI_CFG_REG);
1418 	pci9118_ai_reset_fifo(dev);
1419 
1420 	/* clear any pending interrupts and status */
1421 	inl(dev->iobase + PCI9118_INT_CTRL_REG);
1422 	inl(dev->iobase + PCI9118_AI_STATUS_REG);
1423 
1424 	/* reset DMA and scan queue */
1425 	outl(0, dev->iobase + PCI9118_AI_BURST_NUM_REG);
1426 	outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
1427 	outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
1428 
1429 	/* reset analog outputs to 0V */
1430 	outl(2047, dev->iobase + PCI9118_AO_REG(0));
1431 	outl(2047, dev->iobase + PCI9118_AO_REG(1));
1432 }
1433 
pci9118_find_pci(struct comedi_device * dev,struct comedi_devconfig * it)1434 static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
1435 					struct comedi_devconfig *it)
1436 {
1437 	struct pci_dev *pcidev = NULL;
1438 	int bus = it->options[0];
1439 	int slot = it->options[1];
1440 
1441 	for_each_pci_dev(pcidev) {
1442 		if (pcidev->vendor != PCI_VENDOR_ID_AMCC)
1443 			continue;
1444 		if (pcidev->device != 0x80d9)
1445 			continue;
1446 		if (bus || slot) {
1447 			/* requested particular bus/slot */
1448 			if (pcidev->bus->number != bus ||
1449 			    PCI_SLOT(pcidev->devfn) != slot)
1450 				continue;
1451 		}
1452 		return pcidev;
1453 	}
1454 	dev_err(dev->class_dev,
1455 		"no supported board found! (req. bus/slot : %d/%d)\n",
1456 		bus, slot);
1457 	return NULL;
1458 }
1459 
pci9118_alloc_dma(struct comedi_device * dev)1460 static void pci9118_alloc_dma(struct comedi_device *dev)
1461 {
1462 	struct pci9118_private *devpriv = dev->private;
1463 	struct pci9118_dmabuf *dmabuf;
1464 	int order;
1465 	int i;
1466 
1467 	for (i = 0; i < 2; i++) {
1468 		dmabuf = &devpriv->dmabuf[i];
1469 		for (order = 2; order >= 0; order--) {
1470 			dmabuf->virt =
1471 			    dma_alloc_coherent(dev->hw_dev, PAGE_SIZE << order,
1472 					       &dmabuf->hw, GFP_KERNEL);
1473 			if (dmabuf->virt)
1474 				break;
1475 		}
1476 		if (!dmabuf->virt)
1477 			break;
1478 		dmabuf->size = PAGE_SIZE << order;
1479 
1480 		if (i == 0)
1481 			devpriv->master = 1;
1482 		if (i == 1)
1483 			devpriv->dma_doublebuf = 1;
1484 	}
1485 }
1486 
pci9118_free_dma(struct comedi_device * dev)1487 static void pci9118_free_dma(struct comedi_device *dev)
1488 {
1489 	struct pci9118_private *devpriv = dev->private;
1490 	struct pci9118_dmabuf *dmabuf;
1491 	int i;
1492 
1493 	if (!devpriv)
1494 		return;
1495 
1496 	for (i = 0; i < 2; i++) {
1497 		dmabuf = &devpriv->dmabuf[i];
1498 		if (dmabuf->virt) {
1499 			dma_free_coherent(dev->hw_dev, dmabuf->size,
1500 					  dmabuf->virt, dmabuf->hw);
1501 		}
1502 	}
1503 }
1504 
pci9118_common_attach(struct comedi_device * dev,int ext_mux,int softsshdelay)1505 static int pci9118_common_attach(struct comedi_device *dev,
1506 				 int ext_mux, int softsshdelay)
1507 {
1508 	const struct pci9118_boardinfo *board = dev->board_ptr;
1509 	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1510 	struct pci9118_private *devpriv;
1511 	struct comedi_subdevice *s;
1512 	int ret;
1513 	int i;
1514 	u16 u16w;
1515 
1516 	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1517 	if (!devpriv)
1518 		return -ENOMEM;
1519 
1520 	ret = comedi_pci_enable(dev);
1521 	if (ret)
1522 		return ret;
1523 	pci_set_master(pcidev);
1524 
1525 	devpriv->iobase_a = pci_resource_start(pcidev, 0);
1526 	dev->iobase = pci_resource_start(pcidev, 2);
1527 
1528 	dev->pacer = comedi_8254_init(dev->iobase + PCI9118_TIMER_BASE,
1529 				      I8254_OSC_BASE_4MHZ, I8254_IO32, 0);
1530 	if (!dev->pacer)
1531 		return -ENOMEM;
1532 
1533 	pci9118_reset(dev);
1534 
1535 	if (pcidev->irq) {
1536 		ret = request_irq(pcidev->irq, pci9118_interrupt, IRQF_SHARED,
1537 				  dev->board_name, dev);
1538 		if (ret == 0) {
1539 			dev->irq = pcidev->irq;
1540 
1541 			pci9118_alloc_dma(dev);
1542 		}
1543 	}
1544 
1545 	if (ext_mux > 0) {
1546 		if (ext_mux > 256)
1547 			ext_mux = 256;	/* max 256 channels! */
1548 		if (softsshdelay > 0)
1549 			if (ext_mux > 128)
1550 				ext_mux = 128;
1551 		devpriv->usemux = 1;
1552 	} else {
1553 		devpriv->usemux = 0;
1554 	}
1555 
1556 	if (softsshdelay < 0) {
1557 		/* select sample&hold signal polarity */
1558 		devpriv->softsshdelay = -softsshdelay;
1559 		devpriv->softsshsample = 0x80;
1560 		devpriv->softsshhold = 0x00;
1561 	} else {
1562 		devpriv->softsshdelay = softsshdelay;
1563 		devpriv->softsshsample = 0x00;
1564 		devpriv->softsshhold = 0x80;
1565 	}
1566 
1567 	pci_read_config_word(pcidev, PCI_COMMAND, &u16w);
1568 	pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64);
1569 				/* Enable parity check for parity error */
1570 
1571 	ret = comedi_alloc_subdevices(dev, 4);
1572 	if (ret)
1573 		return ret;
1574 
1575 	/* Analog Input subdevice */
1576 	s = &dev->subdevices[0];
1577 	s->type		= COMEDI_SUBD_AI;
1578 	s->subdev_flags	= SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1579 	s->n_chan	= (devpriv->usemux) ? ext_mux : 16;
1580 	s->maxdata	= board->ai_is_16bit ? 0xffff : 0x0fff;
1581 	s->range_table	= board->is_hg ? &pci9118hg_ai_range
1582 				       : &pci9118_ai_range;
1583 	s->insn_read	= pci9118_ai_insn_read;
1584 	if (dev->irq) {
1585 		dev->read_subdev = s;
1586 		s->subdev_flags	|= SDF_CMD_READ;
1587 		s->len_chanlist	= 255;
1588 		s->do_cmdtest	= pci9118_ai_cmdtest;
1589 		s->do_cmd	= pci9118_ai_cmd;
1590 		s->cancel	= pci9118_ai_cancel;
1591 		s->munge	= pci9118_ai_munge;
1592 	}
1593 
1594 	if (s->maxdata == 0xffff) {
1595 		/*
1596 		 * 16-bit samples are from an ADS7805 A/D converter.
1597 		 * Minimum sampling rate is 10us.
1598 		 */
1599 		devpriv->ai_ns_min = 10000;
1600 	} else {
1601 		/*
1602 		 * 12-bit samples are from an ADS7800 A/D converter.
1603 		 * Minimum sampling rate is 3us.
1604 		 */
1605 		devpriv->ai_ns_min = 3000;
1606 	}
1607 
1608 	/* Analog Output subdevice */
1609 	s = &dev->subdevices[1];
1610 	s->type		= COMEDI_SUBD_AO;
1611 	s->subdev_flags	= SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
1612 	s->n_chan	= 2;
1613 	s->maxdata	= 0x0fff;
1614 	s->range_table	= &range_bipolar10;
1615 	s->insn_write	= pci9118_ao_insn_write;
1616 
1617 	ret = comedi_alloc_subdev_readback(s);
1618 	if (ret)
1619 		return ret;
1620 
1621 	/* the analog outputs were reset to 0V, make the readback match */
1622 	for (i = 0; i < s->n_chan; i++)
1623 		s->readback[i] = 2047;
1624 
1625 	/* Digital Input subdevice */
1626 	s = &dev->subdevices[2];
1627 	s->type		= COMEDI_SUBD_DI;
1628 	s->subdev_flags	= SDF_READABLE;
1629 	s->n_chan	= 4;
1630 	s->maxdata	= 1;
1631 	s->range_table	= &range_digital;
1632 	s->insn_bits	= pci9118_di_insn_bits;
1633 
1634 	/* Digital Output subdevice */
1635 	s = &dev->subdevices[3];
1636 	s->type		= COMEDI_SUBD_DO;
1637 	s->subdev_flags	= SDF_WRITABLE;
1638 	s->n_chan	= 4;
1639 	s->maxdata	= 1;
1640 	s->range_table	= &range_digital;
1641 	s->insn_bits	= pci9118_do_insn_bits;
1642 
1643 	/* get the current state of the digital outputs */
1644 	s->state = inl(dev->iobase + PCI9118_DIO_REG) >> 4;
1645 
1646 	return 0;
1647 }
1648 
pci9118_attach(struct comedi_device * dev,struct comedi_devconfig * it)1649 static int pci9118_attach(struct comedi_device *dev,
1650 			  struct comedi_devconfig *it)
1651 {
1652 	struct pci_dev *pcidev;
1653 	int ext_mux, softsshdelay;
1654 
1655 	ext_mux = it->options[2];
1656 	softsshdelay = it->options[4];
1657 
1658 	pcidev = pci9118_find_pci(dev, it);
1659 	if (!pcidev)
1660 		return -EIO;
1661 	comedi_set_hw_dev(dev, &pcidev->dev);
1662 
1663 	return pci9118_common_attach(dev, ext_mux, softsshdelay);
1664 }
1665 
pci9118_auto_attach(struct comedi_device * dev,unsigned long context)1666 static int pci9118_auto_attach(struct comedi_device *dev,
1667 			       unsigned long context)
1668 {
1669 	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1670 	const struct pci9118_boardinfo *board = NULL;
1671 
1672 	if (context < ARRAY_SIZE(pci9118_boards))
1673 		board = &pci9118_boards[context];
1674 	if (!board)
1675 		return -ENODEV;
1676 	dev->board_ptr = board;
1677 	dev->board_name = board->name;
1678 
1679 	/*
1680 	 * Need to 'get' the PCI device to match the 'put' in pci9118_detach().
1681 	 * (The 'put' also matches the implicit 'get' by pci9118_find_pci().)
1682 	 */
1683 	pci_dev_get(pcidev);
1684 	/* no external mux, no sample-hold delay */
1685 	return pci9118_common_attach(dev, 0, 0);
1686 }
1687 
pci9118_detach(struct comedi_device * dev)1688 static void pci9118_detach(struct comedi_device *dev)
1689 {
1690 	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1691 
1692 	if (dev->iobase)
1693 		pci9118_reset(dev);
1694 	comedi_pci_detach(dev);
1695 	pci9118_free_dma(dev);
1696 	pci_dev_put(pcidev);
1697 }
1698 
1699 static struct comedi_driver adl_pci9118_driver = {
1700 	.driver_name	= "adl_pci9118",
1701 	.module		= THIS_MODULE,
1702 	.attach		= pci9118_attach,
1703 	.auto_attach	= pci9118_auto_attach,
1704 	.detach		= pci9118_detach,
1705 	.num_names	= ARRAY_SIZE(pci9118_boards),
1706 	.board_name	= &pci9118_boards[0].name,
1707 	.offset		= sizeof(struct pci9118_boardinfo),
1708 };
1709 
adl_pci9118_pci_probe(struct pci_dev * dev,const struct pci_device_id * id)1710 static int adl_pci9118_pci_probe(struct pci_dev *dev,
1711 				 const struct pci_device_id *id)
1712 {
1713 	return comedi_pci_auto_config(dev, &adl_pci9118_driver,
1714 				      id->driver_data);
1715 }
1716 
1717 /* FIXME: All the supported board types have the same device ID! */
1718 static const struct pci_device_id adl_pci9118_pci_table[] = {
1719 	{ PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118DG },
1720 /*	{ PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118HG }, */
1721 /*	{ PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118HR }, */
1722 	{ 0 }
1723 };
1724 MODULE_DEVICE_TABLE(pci, adl_pci9118_pci_table);
1725 
1726 static struct pci_driver adl_pci9118_pci_driver = {
1727 	.name		= "adl_pci9118",
1728 	.id_table	= adl_pci9118_pci_table,
1729 	.probe		= adl_pci9118_pci_probe,
1730 	.remove		= comedi_pci_auto_unconfig,
1731 };
1732 module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver);
1733 
1734 MODULE_AUTHOR("Comedi https://www.comedi.org");
1735 MODULE_DESCRIPTION("Comedi low-level driver");
1736 MODULE_LICENSE("GPL");
1737