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