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