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 Driver: adl_pci9118
13 Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
14 Author: Michal Dobes <dobes@tesnet.cz>
15 Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
16   PCI-9118HR (pci9118hr)
17 Status: works
18 
19 This driver supports AI, AO, DI and DO subdevices.
20 AI subdevice supports cmd and insn interface,
21 other subdevices support only insn interface.
22 For AI:
23 - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
24 - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
25 - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
26 - It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
27   cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
28 - If return value of cmdtest is 5 then you've bad channel list
29   (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
30   ranges).
31 
32 There are some hardware limitations:
33 a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
34    ended inputs.
35 b) DMA transfers must have the length aligned to two samples (32 bit),
36    so there is some problems if cmd->chanlist_len is odd. This driver tries
37    bypass this with adding one sample to the end of the every scan and discard
38    it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
39    and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
40    with interrupt after every sample.
41 c) If isn't used DMA then you can use only mode where
42    cmd->scan_begin_src=TRIG_FOLLOW.
43 
44 Configuration options:
45   [0] - PCI bus of device (optional)
46   [1] - PCI slot of device (optional)
47 	If bus/slot is not specified, then first available PCI
48 	card will be used.
49   [2] - 0= standard 8 DIFF/16 SE channels configuration
50 	n = external multiplexer connected, 1 <= n <= 256
51   [3] - 0=autoselect DMA or EOC interrupts operation
52 	1 = disable DMA mode
53 	3 = disable DMA and INT, only insn interface will work
54   [4] - sample&hold signal - card can generate signal for external S&H board
55 	0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
56 	0 != use ADCHN7(pin 23) signal is generated from driver, number say how
57 		long delay is requested in ns and sign polarity of the hold
58 		(in this case external multiplexor can serve only 128 channels)
59   [5] - 0=stop measure on all hardware errors
60 	2 | = ignore ADOR - A/D Overrun status
61 	8|=ignore Bover - A/D Burst Mode Overrun status
62 	256|=ignore nFull - A/D FIFO Full status
63 
64 */
65 #include "../comedidev.h"
66 
67 #include <linux/delay.h>
68 #include <linux/gfp.h>
69 #include <linux/interrupt.h>
70 #include <linux/io.h>
71 
72 #include "amcc_s5933.h"
73 #include "8253.h"
74 #include "comedi_pci.h"
75 #include "comedi_fc.h"
76 
77 #define PCI_VENDOR_ID_AMCC	0x10e8
78 
79 /* paranoid checks are broken */
80 #undef PCI9118_PARANOIDCHECK	/*
81 				 * if defined, then is used code which control
82 				 * correct channel number on every 12 bit sample
83 				 */
84 
85 #undef PCI9118_EXTDEBUG		/*
86 				 * if defined then driver prints
87 				 * a lot of messages
88 				 */
89 
90 #undef DPRINTK
91 #ifdef PCI9118_EXTDEBUG
92 #define DPRINTK(fmt, args...) printk(fmt, ## args)
93 #else
94 #define DPRINTK(fmt, args...)
95 #endif
96 
97 #define IORANGE_9118 	64	/* I hope */
98 #define PCI9118_CHANLEN	255	/*
99 				 * len of chanlist, some source say 256,
100 				 * but reality looks like 255 :-(
101 				 */
102 
103 #define PCI9118_CNT0	0x00	/* R/W: 8254 counter 0 */
104 #define PCI9118_CNT1	0x04	/* R/W: 8254 counter 0 */
105 #define PCI9118_CNT2	0x08	/* R/W: 8254 counter 0 */
106 #define PCI9118_CNTCTRL	0x0c	/* W:   8254 counter control */
107 #define PCI9118_AD_DATA	0x10	/* R:   A/D data */
108 #define PCI9118_DA1	0x10	/* W:   D/A registers */
109 #define PCI9118_DA2	0x14
110 #define PCI9118_ADSTAT	0x18	/* R:   A/D status register */
111 #define PCI9118_ADCNTRL	0x18	/* W:   A/D control register */
112 #define PCI9118_DI	0x1c	/* R:   digi input register */
113 #define PCI9118_DO	0x1c	/* W:   digi output register */
114 #define PCI9118_SOFTTRG	0x20	/* W:   soft trigger for A/D */
115 #define PCI9118_GAIN	0x24	/* W:   A/D gain/channel register */
116 #define PCI9118_BURST	0x28	/* W:   A/D burst number register */
117 #define PCI9118_SCANMOD	0x2c	/* W:   A/D auto scan mode */
118 #define PCI9118_ADFUNC	0x30	/* W:   A/D function register */
119 #define PCI9118_DELFIFO	0x34	/* W:   A/D data FIFO reset */
120 #define PCI9118_INTSRC	0x38	/* R:   interrupt reason register */
121 #define PCI9118_INTCTRL	0x38	/* W:   interrupt control register */
122 
123 /* bits from A/D control register (PCI9118_ADCNTRL) */
124 #define AdControl_UniP	0x80	/* 1=bipolar, 0=unipolar */
125 #define AdControl_Diff	0x40	/* 1=differential, 0= single end inputs */
126 #define AdControl_SoftG	0x20	/* 1=8254 counter works, 0=counter stops */
127 #define	AdControl_ExtG	0x10	/*
128 				 * 1=8254 countrol controlled by TGIN(pin 46),
129 				 * 0=controlled by SoftG
130 				 */
131 #define AdControl_ExtM	0x08	/*
132 				 * 1=external hardware trigger (pin 44),
133 				 * 0=internal trigger
134 				 */
135 #define AdControl_TmrTr	0x04	/*
136 				 * 1=8254 is iternal trigger source,
137 				 * 0=software trigger is source
138 				 * (register PCI9118_SOFTTRG)
139 				 */
140 #define AdControl_Int	0x02	/* 1=enable INT, 0=disable */
141 #define AdControl_Dma	0x01	/* 1=enable DMA, 0=disable */
142 
143 /* bits from A/D function register (PCI9118_ADFUNC) */
144 #define AdFunction_PDTrg	0x80	/*
145 					 * 1=positive,
146 					 * 0=negative digital trigger
147 					 * (only positive is correct)
148 					 */
149 #define AdFunction_PETrg	0x40	/*
150 					 * 1=positive,
151 					 * 0=negative external trigger
152 					 * (only positive is correct)
153 					 */
154 #define AdFunction_BSSH		0x20	/* 1=with sample&hold, 0=without */
155 #define AdFunction_BM		0x10	/* 1=burst mode, 0=normal mode */
156 #define AdFunction_BS		0x08	/*
157 					 * 1=burst mode start,
158 					 * 0=burst mode stop
159 					 */
160 #define AdFunction_PM		0x04	/*
161 					 * 1=post trigger mode,
162 					 * 0=not post trigger
163 					 */
164 #define AdFunction_AM		0x02	/*
165 					 * 1=about trigger mode,
166 					 * 0=not about trigger
167 					 */
168 #define AdFunction_Start	0x01	/* 1=trigger start, 0=trigger stop */
169 
170 /* bits from A/D status register (PCI9118_ADSTAT) */
171 #define AdStatus_nFull	0x100	/* 0=FIFO full (fatal), 1=not full */
172 #define AdStatus_nHfull	0x080	/* 0=FIFO half full, 1=FIFO not half full */
173 #define AdStatus_nEpty	0x040	/* 0=FIFO empty, 1=FIFO not empty */
174 #define AdStatus_Acmp	0x020	/*  */
175 #define AdStatus_DTH	0x010	/* 1=external digital trigger */
176 #define AdStatus_Bover	0x008	/* 1=burst mode overrun (fatal) */
177 #define AdStatus_ADOS	0x004	/* 1=A/D over speed (warning) */
178 #define AdStatus_ADOR	0x002	/* 1=A/D overrun (fatal) */
179 #define AdStatus_ADrdy	0x001	/* 1=A/D already ready, 0=not ready */
180 
181 /* bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL) */
182 /* 1=interrupt occur, enable source,  0=interrupt not occur, disable source */
183 #define Int_Timer	0x08	/* timer interrupt */
184 #define Int_About	0x04	/* about trigger complete */
185 #define Int_Hfull	0x02	/* A/D FIFO hlaf full */
186 #define Int_DTrg	0x01	/* external digital trigger */
187 
188 #define START_AI_EXT	0x01	/* start measure on external trigger */
189 #define STOP_AI_EXT	0x02	/* stop measure on external trigger */
190 #define START_AI_INT	0x04	/* start measure on internal trigger */
191 #define STOP_AI_INT	0x08	/* stop measure on internal trigger */
192 
193 #define EXTTRG_AI	0	/* ext trg is used by AI */
194 
195 static const struct comedi_lrange range_pci9118dg_hr = { 8, {
196 							     BIP_RANGE(5),
197 							     BIP_RANGE(2.5),
198 							     BIP_RANGE(1.25),
199 							     BIP_RANGE(0.625),
200 							     UNI_RANGE(10),
201 							     UNI_RANGE(5),
202 							     UNI_RANGE(2.5),
203 							     UNI_RANGE(1.25)
204 							     }
205 };
206 
207 static const struct comedi_lrange range_pci9118hg = { 8, {
208 							  BIP_RANGE(5),
209 							  BIP_RANGE(0.5),
210 							  BIP_RANGE(0.05),
211 							  BIP_RANGE(0.005),
212 							  UNI_RANGE(10),
213 							  UNI_RANGE(1),
214 							  UNI_RANGE(0.1),
215 							  UNI_RANGE(0.01)
216 							  }
217 };
218 
219 #define PCI9118_BIPOLAR_RANGES	4	/*
220 					 * used for test on mixture
221 					 * of BIP/UNI ranges
222 					 */
223 
224 static int pci9118_attach(struct comedi_device *dev,
225 			  struct comedi_devconfig *it);
226 static int pci9118_detach(struct comedi_device *dev);
227 
228 struct boardtype {
229 	const char *name;		/* board name */
230 	int vendor_id;			/* PCI vendor a device ID of card */
231 	int device_id;
232 	int iorange_amcc;		/* iorange for own S5933 region */
233 	int iorange_9118;		/* pass thru card region size */
234 	int n_aichan;			/* num of A/D chans */
235 	int n_aichand;			/* num of A/D chans in diff mode */
236 	int mux_aichan;			/*
237 					 * num of A/D chans with
238 					 * external multiplexor
239 					 */
240 	int n_aichanlist;		/* len of chanlist */
241 	int n_aochan;			/* num of D/A chans */
242 	int ai_maxdata;			/* resolution of A/D */
243 	int ao_maxdata;			/* resolution of D/A */
244 	const struct comedi_lrange *rangelist_ai;	/* rangelist for A/D */
245 	const struct comedi_lrange *rangelist_ao;	/* rangelist for D/A */
246 	unsigned int ai_ns_min;		/* max sample speed of card v ns */
247 	unsigned int ai_pacer_min;	/*
248 					 * minimal pacer value
249 					 * (c1*c2 or c1 in burst)
250 					 */
251 	int half_fifo_size;		/* size of FIFO/2 */
252 
253 };
254 
255 static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
256 	{ PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) },
257 	{ 0 }
258 };
259 
260 MODULE_DEVICE_TABLE(pci, pci9118_pci_table);
261 
262 static const struct boardtype boardtypes[] = {
263 	{"pci9118dg", PCI_VENDOR_ID_AMCC, 0x80d9,
264 	 AMCC_OP_REG_SIZE, IORANGE_9118,
265 	 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
266 	 &range_pci9118dg_hr, &range_bipolar10,
267 	 3000, 12, 512},
268 	{"pci9118hg", PCI_VENDOR_ID_AMCC, 0x80d9,
269 	 AMCC_OP_REG_SIZE, IORANGE_9118,
270 	 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
271 	 &range_pci9118hg, &range_bipolar10,
272 	 3000, 12, 512},
273 	{"pci9118hr", PCI_VENDOR_ID_AMCC, 0x80d9,
274 	 AMCC_OP_REG_SIZE, IORANGE_9118,
275 	 16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff,
276 	 &range_pci9118dg_hr, &range_bipolar10,
277 	 10000, 40, 512},
278 };
279 
280 #define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
281 
282 static struct comedi_driver driver_pci9118 = {
283 	.driver_name = "adl_pci9118",
284 	.module = THIS_MODULE,
285 	.attach = pci9118_attach,
286 	.detach = pci9118_detach,
287 	.num_names = n_boardtypes,
288 	.board_name = &boardtypes[0].name,
289 	.offset = sizeof(struct boardtype),
290 };
291 
driver_pci9118_pci_probe(struct pci_dev * dev,const struct pci_device_id * ent)292 static int __devinit driver_pci9118_pci_probe(struct pci_dev *dev,
293 					      const struct pci_device_id *ent)
294 {
295 	return comedi_pci_auto_config(dev, driver_pci9118.driver_name);
296 }
297 
driver_pci9118_pci_remove(struct pci_dev * dev)298 static void __devexit driver_pci9118_pci_remove(struct pci_dev *dev)
299 {
300 	comedi_pci_auto_unconfig(dev);
301 }
302 
303 static struct pci_driver driver_pci9118_pci_driver = {
304 	.id_table = pci9118_pci_table,
305 	.probe = &driver_pci9118_pci_probe,
306 	.remove = __devexit_p(&driver_pci9118_pci_remove)
307 };
308 
driver_pci9118_init_module(void)309 static int __init driver_pci9118_init_module(void)
310 {
311 	int retval;
312 
313 	retval = comedi_driver_register(&driver_pci9118);
314 	if (retval < 0)
315 		return retval;
316 
317 	driver_pci9118_pci_driver.name = (char *)driver_pci9118.driver_name;
318 	return pci_register_driver(&driver_pci9118_pci_driver);
319 }
320 
driver_pci9118_cleanup_module(void)321 static void __exit driver_pci9118_cleanup_module(void)
322 {
323 	pci_unregister_driver(&driver_pci9118_pci_driver);
324 	comedi_driver_unregister(&driver_pci9118);
325 }
326 
327 module_init(driver_pci9118_init_module);
328 module_exit(driver_pci9118_cleanup_module);
329 
330 struct pci9118_private {
331 	unsigned long iobase_a;	/* base+size for AMCC chip */
332 	unsigned int master;	/* master capable */
333 	struct pci_dev *pcidev;	/* ptr to actual pcidev */
334 	unsigned int usemux;	/* we want to use external multiplexor! */
335 #ifdef PCI9118_PARANOIDCHECK
336 	unsigned short chanlist[PCI9118_CHANLEN + 1];	/*
337 							 * list of
338 							 * scanned channel
339 							 */
340 	unsigned char chanlistlen;	/* number of scanlist */
341 #endif
342 	unsigned char AdControlReg;	/* A/D control register */
343 	unsigned char IntControlReg;	/* Interrupt control register */
344 	unsigned char AdFunctionReg;	/* A/D function register */
345 	char valid;			/* driver is ok */
346 	char ai_neverending;		/* we do unlimited AI */
347 	unsigned int i8254_osc_base;	/* frequence of onboard oscilator */
348 	unsigned int ai_do;		/* what do AI? 0=nothing, 1 to 4 mode */
349 	unsigned int ai_act_scan;	/* how many scans we finished */
350 	unsigned int ai_buf_ptr;	/* data buffer ptr in samples */
351 	unsigned int ai_n_chan;		/* how many channels is measured */
352 	unsigned int ai_n_scanlen;	/* len of actual scanlist */
353 	unsigned int ai_n_realscanlen;	/*
354 					 * what we must transfer for one
355 					 * outgoing scan include front/back adds
356 					 */
357 	unsigned int ai_act_dmapos;	/* position in actual real stream */
358 	unsigned int ai_add_front;	/*
359 					 * how many channels we must add
360 					 * before scan to satisfy S&H?
361 					 */
362 	unsigned int ai_add_back;	/*
363 					 * how many channels we must add
364 					 * before scan to satisfy DMA?
365 					 */
366 	unsigned int *ai_chanlist;	/* actual chanlist */
367 	unsigned int ai_timer1;
368 	unsigned int ai_timer2;
369 	unsigned int ai_flags;
370 	char ai12_startstop;		/*
371 					 * measure can start/stop
372 					 * on external trigger
373 					 */
374 	unsigned int ai_divisor1, ai_divisor2;	/*
375 						 * divisors for start of measure
376 						 * on external start
377 						 */
378 	unsigned int ai_data_len;
379 	short *ai_data;
380 	short ao_data[2];			/* data output buffer */
381 	unsigned int ai_scans;			/* number of scans to do */
382 	char dma_doublebuf;			/* we can use double buffring */
383 	unsigned int dma_actbuf;		/* which buffer is used now */
384 	short *dmabuf_virt[2];			/*
385 						 * pointers to begin of
386 						 * DMA buffer
387 						 */
388 	unsigned long dmabuf_hw[2];		/* hw address of DMA buff */
389 	unsigned int dmabuf_size[2];		/*
390 						 * size of dma buffer in bytes
391 						 */
392 	unsigned int dmabuf_use_size[2];	/*
393 						 * which size we may now use
394 						 * for transfer
395 						 */
396 	unsigned int dmabuf_used_size[2];	/* which size was truly used */
397 	unsigned int dmabuf_panic_size[2];
398 	unsigned int dmabuf_samples[2];		/* size in samples */
399 	int dmabuf_pages[2];			/* number of pages in buffer */
400 	unsigned char cnt0_users;		/*
401 						 * bit field of 8254 CNT0 users
402 						 * (0-unused, 1-AO, 2-DI, 3-DO)
403 						 */
404 	unsigned char exttrg_users;		/*
405 						 * bit field of external trigger
406 						 * users(0-AI, 1-AO, 2-DI, 3-DO)
407 						 */
408 	unsigned int cnt0_divisor;		/* actual CNT0 divisor */
409 	void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *,
410 		unsigned short,
411 		unsigned int,
412 		unsigned short);	/*
413 					 * ptr to actual interrupt
414 					 * AI function
415 					 */
416 	unsigned char ai16bits;		/* =1 16 bit card */
417 	unsigned char usedma;		/* =1 use DMA transfer and not INT */
418 	unsigned char useeoshandle;	/*
419 					 * =1 change WAKE_EOS DMA transfer
420 					 * to fit on every second
421 					 */
422 	unsigned char usessh;		/* =1 turn on S&H support */
423 	int softsshdelay;		/*
424 					 * >0 use software S&H,
425 					 * numer is requested delay in ns
426 					 */
427 	unsigned char softsshsample;	/*
428 					 * polarity of S&H signal
429 					 * in sample state
430 					 */
431 	unsigned char softsshhold;	/*
432 					 * polarity of S&H signal
433 					 * in hold state
434 					 */
435 	unsigned int ai_maskerr;	/* which warning was printed */
436 	unsigned int ai_maskharderr;	/* on which error bits stops */
437 	unsigned int ai_inttrig_start;	/* TRIG_INT for start */
438 };
439 
440 #define devpriv ((struct pci9118_private *)dev->private)
441 #define this_board ((struct boardtype *)dev->board_ptr)
442 
443 /*
444 ==============================================================================
445 */
446 
447 static int check_channel_list(struct comedi_device *dev,
448 			      struct comedi_subdevice *s, int n_chan,
449 			      unsigned int *chanlist, int frontadd,
450 			      int backadd);
451 static int setup_channel_list(struct comedi_device *dev,
452 			      struct comedi_subdevice *s, int n_chan,
453 			      unsigned int *chanlist, int rot, int frontadd,
454 			      int backadd, int usedma, char eoshandle);
455 static void start_pacer(struct comedi_device *dev, int mode,
456 			unsigned int divisor1, unsigned int divisor2);
457 static int pci9118_reset(struct comedi_device *dev);
458 static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source);
459 static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source);
460 static int pci9118_ai_cancel(struct comedi_device *dev,
461 			     struct comedi_subdevice *s);
462 static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
463 				  struct comedi_subdevice *s,
464 				  unsigned int *tim1, unsigned int *tim2,
465 				  unsigned int flags, int chans,
466 				  unsigned int *div1, unsigned int *div2,
467 				  char usessh, unsigned int chnsshfront);
468 
469 /*
470 ==============================================================================
471 */
pci9118_insn_read_ai(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)472 static int pci9118_insn_read_ai(struct comedi_device *dev,
473 				struct comedi_subdevice *s,
474 				struct comedi_insn *insn, unsigned int *data)
475 {
476 
477 	int n, timeout;
478 
479 	devpriv->AdControlReg = AdControl_Int & 0xff;
480 	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
481 	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
482 						/*
483 						 * positive triggers, no S&H,
484 						 * no burst, burst stop,
485 						 * no post trigger,
486 						 * no about trigger,
487 						 * trigger stop
488 						 */
489 
490 	if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
491 		return -EINVAL;
492 
493 	outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
494 
495 	for (n = 0; n < insn->n; n++) {
496 		outw(0, dev->iobase + PCI9118_SOFTTRG);	/* start conversion */
497 		udelay(2);
498 		timeout = 100;
499 		while (timeout--) {
500 			if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
501 				goto conv_finish;
502 			udelay(1);
503 		}
504 
505 		comedi_error(dev, "A/D insn timeout");
506 		data[n] = 0;
507 		outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
508 		return -ETIME;
509 
510 conv_finish:
511 		if (devpriv->ai16bits) {
512 			data[n] =
513 			    (inl(dev->iobase +
514 				 PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
515 		} else {
516 			data[n] =
517 			    (inw(dev->iobase + PCI9118_AD_DATA) >> 4) & 0xfff;
518 		}
519 	}
520 
521 	outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
522 	return n;
523 
524 }
525 
526 /*
527 ==============================================================================
528 */
pci9118_insn_write_ao(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)529 static int pci9118_insn_write_ao(struct comedi_device *dev,
530 				 struct comedi_subdevice *s,
531 				 struct comedi_insn *insn, unsigned int *data)
532 {
533 	int n, chanreg, ch;
534 
535 	ch = CR_CHAN(insn->chanspec);
536 	if (ch)
537 		chanreg = PCI9118_DA2;
538 	else
539 		chanreg = PCI9118_DA1;
540 
541 
542 	for (n = 0; n < insn->n; n++) {
543 		outl(data[n], dev->iobase + chanreg);
544 		devpriv->ao_data[ch] = data[n];
545 	}
546 
547 	return n;
548 }
549 
550 /*
551 ==============================================================================
552 */
pci9118_insn_read_ao(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)553 static int pci9118_insn_read_ao(struct comedi_device *dev,
554 				struct comedi_subdevice *s,
555 				struct comedi_insn *insn, unsigned int *data)
556 {
557 	int n, chan;
558 
559 	chan = CR_CHAN(insn->chanspec);
560 	for (n = 0; n < insn->n; n++)
561 		data[n] = devpriv->ao_data[chan];
562 
563 	return n;
564 }
565 
566 /*
567 ==============================================================================
568 */
pci9118_insn_bits_di(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)569 static int pci9118_insn_bits_di(struct comedi_device *dev,
570 				struct comedi_subdevice *s,
571 				struct comedi_insn *insn, unsigned int *data)
572 {
573 	data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
574 
575 	return 2;
576 }
577 
578 /*
579 ==============================================================================
580 */
pci9118_insn_bits_do(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)581 static int pci9118_insn_bits_do(struct comedi_device *dev,
582 				struct comedi_subdevice *s,
583 				struct comedi_insn *insn, unsigned int *data)
584 {
585 	if (data[0]) {
586 		s->state &= ~data[0];
587 		s->state |= (data[0] & data[1]);
588 		outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
589 	}
590 	data[1] = s->state;
591 
592 	return 2;
593 }
594 
595 /*
596 ==============================================================================
597 */
interrupt_pci9118_ai_mode4_switch(struct comedi_device * dev)598 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev)
599 {
600 	devpriv->AdFunctionReg =
601 	    AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
602 	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
603 	outl(0x30, dev->iobase + PCI9118_CNTCTRL);
604 	outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
605 	     dev->iobase + PCI9118_CNT0);
606 	outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
607 	     dev->iobase + PCI9118_CNT0);
608 	devpriv->AdFunctionReg |= AdFunction_Start;
609 	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
610 }
611 
defragment_dma_buffer(struct comedi_device * dev,struct comedi_subdevice * s,short * dma_buffer,unsigned int num_samples)612 static unsigned int defragment_dma_buffer(struct comedi_device *dev,
613 					  struct comedi_subdevice *s,
614 					  short *dma_buffer,
615 					  unsigned int num_samples)
616 {
617 	unsigned int i = 0, j = 0;
618 	unsigned int start_pos = devpriv->ai_add_front,
619 	    stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
620 	unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
621 	    devpriv->ai_add_back;
622 
623 	for (i = 0; i < num_samples; i++) {
624 		if (devpriv->ai_act_dmapos >= start_pos &&
625 		    devpriv->ai_act_dmapos < stop_pos) {
626 			dma_buffer[j++] = dma_buffer[i];
627 		}
628 		devpriv->ai_act_dmapos++;
629 		devpriv->ai_act_dmapos %= raw_scanlen;
630 	}
631 
632 	return j;
633 }
634 
635 /*
636 ==============================================================================
637 */
move_block_from_dma(struct comedi_device * dev,struct comedi_subdevice * s,short * dma_buffer,unsigned int num_samples)638 static int move_block_from_dma(struct comedi_device *dev,
639 					struct comedi_subdevice *s,
640 					short *dma_buffer,
641 					unsigned int num_samples)
642 {
643 	unsigned int num_bytes;
644 
645 	num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
646 	devpriv->ai_act_scan +=
647 	    (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
648 	s->async->cur_chan += num_samples;
649 	s->async->cur_chan %= devpriv->ai_n_scanlen;
650 	num_bytes =
651 	    cfc_write_array_to_buffer(s, dma_buffer,
652 				      num_samples * sizeof(short));
653 	if (num_bytes < num_samples * sizeof(short))
654 		return -1;
655 	return 0;
656 }
657 
658 /*
659 ==============================================================================
660 */
pci9118_decode_error_status(struct comedi_device * dev,struct comedi_subdevice * s,unsigned char m)661 static char pci9118_decode_error_status(struct comedi_device *dev,
662 					struct comedi_subdevice *s,
663 					unsigned char m)
664 {
665 	if (m & 0x100) {
666 		comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
667 		devpriv->ai_maskerr &= ~0x100L;
668 	}
669 	if (m & 0x008) {
670 		comedi_error(dev,
671 			     "A/D Burst Mode Overrun Status (Fatal Error!)");
672 		devpriv->ai_maskerr &= ~0x008L;
673 	}
674 	if (m & 0x004) {
675 		comedi_error(dev, "A/D Over Speed Status (Warning!)");
676 		devpriv->ai_maskerr &= ~0x004L;
677 	}
678 	if (m & 0x002) {
679 		comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
680 		devpriv->ai_maskerr &= ~0x002L;
681 	}
682 	if (m & devpriv->ai_maskharderr) {
683 		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
684 		pci9118_ai_cancel(dev, s);
685 		comedi_event(dev, s);
686 		return 1;
687 	}
688 
689 	return 0;
690 }
691 
pci9118_ai_munge(struct comedi_device * dev,struct comedi_subdevice * s,void * data,unsigned int num_bytes,unsigned int start_chan_index)692 static void pci9118_ai_munge(struct comedi_device *dev,
693 			     struct comedi_subdevice *s, void *data,
694 			     unsigned int num_bytes,
695 			     unsigned int start_chan_index)
696 {
697 	unsigned int i, num_samples = num_bytes / sizeof(short);
698 	short *array = data;
699 
700 	for (i = 0; i < num_samples; i++) {
701 		if (devpriv->usedma)
702 			array[i] = be16_to_cpu(array[i]);
703 		if (devpriv->ai16bits)
704 			array[i] ^= 0x8000;
705 		else
706 			array[i] = (array[i] >> 4) & 0x0fff;
707 
708 	}
709 }
710 
711 /*
712 ==============================================================================
713 */
interrupt_pci9118_ai_onesample(struct comedi_device * dev,struct comedi_subdevice * s,unsigned short int_adstat,unsigned int int_amcc,unsigned short int_daq)714 static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
715 					   struct comedi_subdevice *s,
716 					   unsigned short int_adstat,
717 					   unsigned int int_amcc,
718 					   unsigned short int_daq)
719 {
720 	register short sampl;
721 
722 	s->async->events = 0;
723 
724 	if (int_adstat & devpriv->ai_maskerr)
725 		if (pci9118_decode_error_status(dev, s, int_adstat))
726 			return;
727 
728 	sampl = inw(dev->iobase + PCI9118_AD_DATA);
729 
730 #ifdef PCI9118_PARANOIDCHECK
731 	if (devpriv->ai16bits == 0) {
732 		if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) {
733 							/* data dropout! */
734 			printk
735 			    ("comedi: A/D  SAMPL - data dropout: "
736 				"received channel %d, expected %d!\n",
737 				sampl & 0x000f,
738 				devpriv->chanlist[s->async->cur_chan]);
739 			s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
740 			pci9118_ai_cancel(dev, s);
741 			comedi_event(dev, s);
742 			return;
743 		}
744 	}
745 #endif
746 	cfc_write_to_buffer(s, sampl);
747 	s->async->cur_chan++;
748 	if (s->async->cur_chan >= devpriv->ai_n_scanlen) {
749 							/* one scan done */
750 		s->async->cur_chan %= devpriv->ai_n_scanlen;
751 		devpriv->ai_act_scan++;
752 		if (!(devpriv->ai_neverending))
753 			if (devpriv->ai_act_scan >= devpriv->ai_scans) {
754 							/* all data sampled */
755 				pci9118_ai_cancel(dev, s);
756 				s->async->events |= COMEDI_CB_EOA;
757 			}
758 	}
759 
760 	if (s->async->events)
761 		comedi_event(dev, s);
762 }
763 
764 /*
765 ==============================================================================
766 */
interrupt_pci9118_ai_dma(struct comedi_device * dev,struct comedi_subdevice * s,unsigned short int_adstat,unsigned int int_amcc,unsigned short int_daq)767 static void interrupt_pci9118_ai_dma(struct comedi_device *dev,
768 				     struct comedi_subdevice *s,
769 				     unsigned short int_adstat,
770 				     unsigned int int_amcc,
771 				     unsigned short int_daq)
772 {
773 	unsigned int next_dma_buf, samplesinbuf, sampls, m;
774 
775 	if (int_amcc & MASTER_ABORT_INT) {
776 		comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
777 		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
778 		pci9118_ai_cancel(dev, s);
779 		comedi_event(dev, s);
780 		return;
781 	}
782 
783 	if (int_amcc & TARGET_ABORT_INT) {
784 		comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
785 		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
786 		pci9118_ai_cancel(dev, s);
787 		comedi_event(dev, s);
788 		return;
789 	}
790 	if (int_adstat & devpriv->ai_maskerr)
791 					/* if (int_adstat & 0x106) */
792 		if (pci9118_decode_error_status(dev, s, int_adstat))
793 			return;
794 
795 	samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1;
796 					/* number of received real samples */
797 /* DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf); */
798 
799 	if (devpriv->dma_doublebuf) {	/*
800 					 * switch DMA buffers if is used
801 					 * double buffering
802 					 */
803 		next_dma_buf = 1 - devpriv->dma_actbuf;
804 		outl(devpriv->dmabuf_hw[next_dma_buf],
805 		     devpriv->iobase_a + AMCC_OP_REG_MWAR);
806 		outl(devpriv->dmabuf_use_size[next_dma_buf],
807 		     devpriv->iobase_a + AMCC_OP_REG_MWTC);
808 		devpriv->dmabuf_used_size[next_dma_buf] =
809 		    devpriv->dmabuf_use_size[next_dma_buf];
810 		if (devpriv->ai_do == 4)
811 			interrupt_pci9118_ai_mode4_switch(dev);
812 	}
813 
814 	if (samplesinbuf) {
815 		m = devpriv->ai_data_len >> 1;	/*
816 						 * how many samples is to
817 						 * end of buffer
818 						 */
819 /*
820  * DPRINTK("samps=%d m=%d %d %d\n",
821  * samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr);
822  */
823 		sampls = m;
824 		move_block_from_dma(dev, s,
825 				    devpriv->dmabuf_virt[devpriv->dma_actbuf],
826 				    samplesinbuf);
827 		m = m - sampls;		/* m= how many samples was transferred */
828 	}
829 /* DPRINTK("YYY\n"); */
830 
831 	if (!devpriv->ai_neverending)
832 		if (devpriv->ai_act_scan >= devpriv->ai_scans) {
833 							/* all data sampled */
834 			pci9118_ai_cancel(dev, s);
835 			s->async->events |= COMEDI_CB_EOA;
836 		}
837 
838 	if (devpriv->dma_doublebuf) {	/* switch dma buffers */
839 		devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
840 	} else {	/* restart DMA if is not used double buffering */
841 		outl(devpriv->dmabuf_hw[0],
842 		     devpriv->iobase_a + AMCC_OP_REG_MWAR);
843 		outl(devpriv->dmabuf_use_size[0],
844 		     devpriv->iobase_a + AMCC_OP_REG_MWTC);
845 		if (devpriv->ai_do == 4)
846 			interrupt_pci9118_ai_mode4_switch(dev);
847 	}
848 
849 	comedi_event(dev, s);
850 }
851 
852 /*
853 ==============================================================================
854 */
interrupt_pci9118(int irq,void * d)855 static irqreturn_t interrupt_pci9118(int irq, void *d)
856 {
857 	struct comedi_device *dev = d;
858 	unsigned int int_daq = 0, int_amcc, int_adstat;
859 
860 	if (!dev->attached)
861 		return IRQ_NONE;	/* not fully initialized */
862 
863 	int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf;
864 					/* get IRQ reasons from card */
865 	int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
866 					/* get INT register from AMCC chip */
867 
868 /*
869  * DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x
870  * MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n",
871  * int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR),
872  * inl(devpriv->iobase_a+AMCC_OP_REG_MWTC),
873  * inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do);
874  */
875 
876 	if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
877 		return IRQ_NONE;	/* interrupt from other source */
878 
879 	outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
880 					/* shutdown IRQ reasons in AMCC */
881 
882 	int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff;
883 					/* get STATUS register */
884 
885 	if (devpriv->ai_do) {
886 		if (devpriv->ai12_startstop)
887 			if ((int_adstat & AdStatus_DTH) &&
888 							(int_daq & Int_DTrg)) {
889 						/* start stop of measure */
890 				if (devpriv->ai12_startstop & START_AI_EXT) {
891 					devpriv->ai12_startstop &=
892 					    ~START_AI_EXT;
893 					if (!(devpriv->ai12_startstop &
894 							STOP_AI_EXT))
895 							pci9118_exttrg_del
896 							(dev, EXTTRG_AI);
897 						/* deactivate EXT trigger */
898 					start_pacer(dev, devpriv->ai_do,
899 						devpriv->ai_divisor1,
900 						devpriv->ai_divisor2);
901 						/* start pacer */
902 					outl(devpriv->AdControlReg,
903 						dev->iobase + PCI9118_ADCNTRL);
904 				} else {
905 					if (devpriv->ai12_startstop &
906 						STOP_AI_EXT) {
907 						devpriv->ai12_startstop &=
908 							~STOP_AI_EXT;
909 						pci9118_exttrg_del
910 							(dev, EXTTRG_AI);
911 						/* deactivate EXT trigger */
912 						devpriv->ai_neverending = 0;
913 						/*
914 						 * well, on next interrupt from
915 						 * DMA/EOC measure will stop
916 						 */
917 					}
918 				}
919 			}
920 
921 		(devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat,
922 					int_amcc, int_daq);
923 
924 	}
925 	return IRQ_HANDLED;
926 }
927 
928 /*
929 ==============================================================================
930 */
pci9118_ai_inttrig(struct comedi_device * dev,struct comedi_subdevice * s,unsigned int trignum)931 static int pci9118_ai_inttrig(struct comedi_device *dev,
932 			      struct comedi_subdevice *s, unsigned int trignum)
933 {
934 	if (trignum != devpriv->ai_inttrig_start)
935 		return -EINVAL;
936 
937 	devpriv->ai12_startstop &= ~START_AI_INT;
938 	s->async->inttrig = NULL;
939 
940 	outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
941 	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
942 	if (devpriv->ai_do != 3) {
943 		start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
944 			    devpriv->ai_divisor2);
945 		devpriv->AdControlReg |= AdControl_SoftG;
946 	}
947 	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
948 
949 	return 1;
950 }
951 
952 /*
953 ==============================================================================
954 */
pci9118_ai_cmdtest(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_cmd * cmd)955 static int pci9118_ai_cmdtest(struct comedi_device *dev,
956 			      struct comedi_subdevice *s,
957 			      struct comedi_cmd *cmd)
958 {
959 	int err = 0;
960 	int tmp;
961 	unsigned int divisor1 = 0, divisor2 = 0;
962 
963 	/* step 1: make sure trigger sources are trivially valid */
964 
965 	tmp = cmd->start_src;
966 	cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT;
967 	if (!cmd->start_src || tmp != cmd->start_src)
968 		err++;
969 
970 	tmp = cmd->scan_begin_src;
971 	if (devpriv->master)
972 		cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW;
973 	else
974 		cmd->scan_begin_src &= TRIG_FOLLOW;
975 
976 	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
977 		err++;
978 
979 	tmp = cmd->convert_src;
980 	if (devpriv->master)
981 		cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW;
982 	else
983 		cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
984 
985 	if (!cmd->convert_src || tmp != cmd->convert_src)
986 		err++;
987 
988 	tmp = cmd->scan_end_src;
989 	cmd->scan_end_src &= TRIG_COUNT;
990 	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
991 		err++;
992 
993 	tmp = cmd->stop_src;
994 	cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT;
995 	if (!cmd->stop_src || tmp != cmd->stop_src)
996 		err++;
997 
998 	if (err)
999 		return 1;
1000 
1001 	/*
1002 	 * step 2:
1003 	 * make sure trigger sources are
1004 	 * unique and mutually compatible
1005 	 */
1006 
1007 	if (cmd->start_src != TRIG_NOW &&
1008 	    cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) {
1009 		cmd->start_src = TRIG_NOW;
1010 		err++;
1011 	}
1012 
1013 	if (cmd->scan_begin_src != TRIG_TIMER &&
1014 	    cmd->scan_begin_src != TRIG_EXT &&
1015 	    cmd->scan_begin_src != TRIG_INT &&
1016 	    cmd->scan_begin_src != TRIG_FOLLOW) {
1017 		cmd->scan_begin_src = TRIG_FOLLOW;
1018 		err++;
1019 	}
1020 
1021 	if (cmd->convert_src != TRIG_TIMER &&
1022 	    cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) {
1023 		cmd->convert_src = TRIG_TIMER;
1024 		err++;
1025 	}
1026 
1027 	if (cmd->scan_end_src != TRIG_COUNT) {
1028 		cmd->scan_end_src = TRIG_COUNT;
1029 		err++;
1030 	}
1031 
1032 	if (cmd->stop_src != TRIG_NONE &&
1033 	    cmd->stop_src != TRIG_COUNT &&
1034 	    cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) {
1035 		cmd->stop_src = TRIG_COUNT;
1036 		err++;
1037 	}
1038 
1039 	if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
1040 		cmd->start_src = TRIG_NOW;
1041 		err++;
1042 	}
1043 
1044 	if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) {
1045 		cmd->start_src = TRIG_NOW;
1046 		err++;
1047 	}
1048 
1049 	if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
1050 	    (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) {
1051 		cmd->convert_src = TRIG_TIMER;
1052 		err++;
1053 	}
1054 
1055 	if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
1056 	    (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) {
1057 		cmd->convert_src = TRIG_TIMER;
1058 		err++;
1059 	}
1060 
1061 	if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
1062 		cmd->stop_src = TRIG_COUNT;
1063 		err++;
1064 	}
1065 
1066 	if (err)
1067 		return 2;
1068 
1069 	/* step 3: make sure arguments are trivially compatible */
1070 
1071 	if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
1072 		if (cmd->start_arg != 0) {
1073 			cmd->start_arg = 0;
1074 			err++;
1075 		}
1076 
1077 	if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
1078 		if (cmd->scan_begin_arg != 0) {
1079 			cmd->scan_begin_arg = 0;
1080 			err++;
1081 		}
1082 
1083 	if ((cmd->scan_begin_src == TRIG_TIMER) &&
1084 	    (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
1085 		cmd->scan_begin_src = TRIG_FOLLOW;
1086 		cmd->convert_arg = cmd->scan_begin_arg;
1087 		cmd->scan_begin_arg = 0;
1088 	}
1089 
1090 	if (cmd->scan_begin_src == TRIG_TIMER)
1091 		if (cmd->scan_begin_arg < this_board->ai_ns_min) {
1092 			cmd->scan_begin_arg = this_board->ai_ns_min;
1093 			err++;
1094 		}
1095 
1096 	if (cmd->scan_begin_src == TRIG_EXT)
1097 		if (cmd->scan_begin_arg) {
1098 			cmd->scan_begin_arg = 0;
1099 			err++;
1100 			if (cmd->scan_end_arg > 65535) {
1101 				cmd->scan_end_arg = 65535;
1102 				err++;
1103 			}
1104 		}
1105 
1106 	if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
1107 		if (cmd->convert_arg < this_board->ai_ns_min) {
1108 			cmd->convert_arg = this_board->ai_ns_min;
1109 			err++;
1110 		}
1111 
1112 	if (cmd->convert_src == TRIG_EXT)
1113 		if (cmd->convert_arg) {
1114 			cmd->convert_arg = 0;
1115 			err++;
1116 		}
1117 
1118 	if (cmd->stop_src == TRIG_COUNT) {
1119 		if (!cmd->stop_arg) {
1120 			cmd->stop_arg = 1;
1121 			err++;
1122 		}
1123 	} else {		/* TRIG_NONE */
1124 		if (cmd->stop_arg != 0) {
1125 			cmd->stop_arg = 0;
1126 			err++;
1127 		}
1128 	}
1129 
1130 	if (!cmd->chanlist_len) {
1131 		cmd->chanlist_len = 1;
1132 		err++;
1133 	}
1134 
1135 	if (cmd->chanlist_len > this_board->n_aichanlist) {
1136 		cmd->chanlist_len = this_board->n_aichanlist;
1137 		err++;
1138 	}
1139 
1140 	if (cmd->scan_end_arg < cmd->chanlist_len) {
1141 		cmd->scan_end_arg = cmd->chanlist_len;
1142 		err++;
1143 	}
1144 
1145 	if ((cmd->scan_end_arg % cmd->chanlist_len)) {
1146 		cmd->scan_end_arg =
1147 		    cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
1148 		err++;
1149 	}
1150 
1151 	if (err)
1152 		return 3;
1153 
1154 	/* step 4: fix up any arguments */
1155 
1156 	if (cmd->scan_begin_src == TRIG_TIMER) {
1157 		tmp = cmd->scan_begin_arg;
1158 /* printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1159 		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1160 					  &divisor2, &cmd->scan_begin_arg,
1161 					  cmd->flags & TRIG_ROUND_MASK);
1162 /* printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1163 		if (cmd->scan_begin_arg < this_board->ai_ns_min)
1164 			cmd->scan_begin_arg = this_board->ai_ns_min;
1165 		if (tmp != cmd->scan_begin_arg)
1166 			err++;
1167 	}
1168 
1169 	if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
1170 		tmp = cmd->convert_arg;
1171 		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1172 					  &divisor2, &cmd->convert_arg,
1173 					  cmd->flags & TRIG_ROUND_MASK);
1174 /* printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1175 		if (cmd->convert_arg < this_board->ai_ns_min)
1176 			cmd->convert_arg = this_board->ai_ns_min;
1177 		if (tmp != cmd->convert_arg)
1178 			err++;
1179 		if (cmd->scan_begin_src == TRIG_TIMER
1180 		    && cmd->convert_src == TRIG_NOW) {
1181 			if (cmd->convert_arg == 0) {
1182 				if (cmd->scan_begin_arg <
1183 				    this_board->ai_ns_min *
1184 				    (cmd->scan_end_arg + 2)) {
1185 					cmd->scan_begin_arg =
1186 					    this_board->ai_ns_min *
1187 					    (cmd->scan_end_arg + 2);
1188 /* printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1189 					err++;
1190 				}
1191 			} else {
1192 				if (cmd->scan_begin_arg <
1193 				    cmd->convert_arg * cmd->chanlist_len) {
1194 					cmd->scan_begin_arg =
1195 					    cmd->convert_arg *
1196 					    cmd->chanlist_len;
1197 /* printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1198 					err++;
1199 				}
1200 			}
1201 		}
1202 	}
1203 
1204 	if (err)
1205 		return 4;
1206 
1207 	if (cmd->chanlist)
1208 		if (!check_channel_list(dev, s, cmd->chanlist_len,
1209 					cmd->chanlist, 0, 0))
1210 			return 5;	/* incorrect channels list */
1211 
1212 	return 0;
1213 }
1214 
1215 /*
1216 ==============================================================================
1217 */
Compute_and_setup_dma(struct comedi_device * dev)1218 static int Compute_and_setup_dma(struct comedi_device *dev)
1219 {
1220 	unsigned int dmalen0, dmalen1, i;
1221 
1222 	DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n");
1223 	dmalen0 = devpriv->dmabuf_size[0];
1224 	dmalen1 = devpriv->dmabuf_size[1];
1225 	DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1,
1226 		devpriv->ai_data_len);
1227 	/* isn't output buff smaller that our DMA buff? */
1228 	if (dmalen0 > (devpriv->ai_data_len)) {
1229 		dmalen0 = devpriv->ai_data_len & ~3L;	/*
1230 							 * align to 32bit down
1231 							 */
1232 	}
1233 	if (dmalen1 > (devpriv->ai_data_len)) {
1234 		dmalen1 = devpriv->ai_data_len & ~3L;	/*
1235 							 * align to 32bit down
1236 							 */
1237 	}
1238 	DPRINTK("2 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1);
1239 
1240 	/* we want wake up every scan? */
1241 	if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1242 		if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
1243 			/* uff, too short DMA buffer, disable EOS support! */
1244 			devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1245 			printk
1246 			    ("comedi%d: WAR: DMA0 buf too short, can't "
1247 					"support TRIG_WAKE_EOS (%d<%d)\n",
1248 			     dev->minor, dmalen0,
1249 			     devpriv->ai_n_realscanlen << 1);
1250 		} else {
1251 			/* short first DMA buffer to one scan */
1252 			dmalen0 = devpriv->ai_n_realscanlen << 1;
1253 			DPRINTK
1254 				("21 dmalen0=%d ai_n_realscanlen=%d "
1255 							"useeoshandle=%d\n",
1256 				dmalen0, devpriv->ai_n_realscanlen,
1257 				devpriv->useeoshandle);
1258 			if (devpriv->useeoshandle)
1259 				dmalen0 += 2;
1260 			if (dmalen0 < 4) {
1261 				printk
1262 					("comedi%d: ERR: DMA0 buf len bug? "
1263 								"(%d<4)\n",
1264 					dev->minor, dmalen0);
1265 				dmalen0 = 4;
1266 			}
1267 		}
1268 	}
1269 	if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1270 		if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
1271 			/* uff, too short DMA buffer, disable EOS support! */
1272 			devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1273 			printk
1274 			    ("comedi%d: WAR: DMA1 buf too short, "
1275 					"can't support TRIG_WAKE_EOS (%d<%d)\n",
1276 			     dev->minor, dmalen1,
1277 			     devpriv->ai_n_realscanlen << 1);
1278 		} else {
1279 			/* short second DMA buffer to one scan */
1280 			dmalen1 = devpriv->ai_n_realscanlen << 1;
1281 			DPRINTK
1282 			    ("22 dmalen1=%d ai_n_realscanlen=%d "
1283 							"useeoshandle=%d\n",
1284 			     dmalen1, devpriv->ai_n_realscanlen,
1285 			     devpriv->useeoshandle);
1286 			if (devpriv->useeoshandle)
1287 				dmalen1 -= 2;
1288 			if (dmalen1 < 4) {
1289 				printk
1290 					("comedi%d: ERR: DMA1 buf len bug? "
1291 								"(%d<4)\n",
1292 					dev->minor, dmalen1);
1293 				dmalen1 = 4;
1294 			}
1295 		}
1296 	}
1297 
1298 	DPRINTK("3 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1);
1299 	/* transfer without TRIG_WAKE_EOS */
1300 	if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
1301 		/* if it's possible then align DMA buffers to length of scan */
1302 		i = dmalen0;
1303 		dmalen0 =
1304 		    (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
1305 		    (devpriv->ai_n_realscanlen << 1);
1306 		dmalen0 &= ~3L;
1307 		if (!dmalen0)
1308 			dmalen0 = i;	/* uff. very long scan? */
1309 		i = dmalen1;
1310 		dmalen1 =
1311 		    (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
1312 		    (devpriv->ai_n_realscanlen << 1);
1313 		dmalen1 &= ~3L;
1314 		if (!dmalen1)
1315 			dmalen1 = i;	/* uff. very long scan? */
1316 		/*
1317 		 * if measure isn't neverending then test, if it fits whole
1318 		 * into one or two DMA buffers
1319 		 */
1320 		if (!devpriv->ai_neverending) {
1321 			/* fits whole measure into one DMA buffer? */
1322 			if (dmalen0 >
1323 			    ((devpriv->ai_n_realscanlen << 1) *
1324 			     devpriv->ai_scans)) {
1325 				DPRINTK
1326 				    ("3.0 ai_n_realscanlen=%d ai_scans=%d\n",
1327 				     devpriv->ai_n_realscanlen,
1328 				     devpriv->ai_scans);
1329 				dmalen0 =
1330 				    (devpriv->ai_n_realscanlen << 1) *
1331 				    devpriv->ai_scans;
1332 				DPRINTK("3.1 dmalen0=%d dmalen1=%d\n", dmalen0,
1333 					dmalen1);
1334 				dmalen0 &= ~3L;
1335 			} else {	/*
1336 					 * fits whole measure into
1337 					 * two DMA buffer?
1338 					 */
1339 				if (dmalen1 >
1340 				    ((devpriv->ai_n_realscanlen << 1) *
1341 				     devpriv->ai_scans - dmalen0))
1342 					dmalen1 =
1343 					    (devpriv->ai_n_realscanlen << 1) *
1344 					    devpriv->ai_scans - dmalen0;
1345 				DPRINTK("3.2 dmalen0=%d dmalen1=%d\n", dmalen0,
1346 					dmalen1);
1347 				dmalen1 &= ~3L;
1348 			}
1349 		}
1350 	}
1351 
1352 	DPRINTK("4 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1);
1353 
1354 	/* these DMA buffer size will be used */
1355 	devpriv->dma_actbuf = 0;
1356 	devpriv->dmabuf_use_size[0] = dmalen0;
1357 	devpriv->dmabuf_use_size[1] = dmalen1;
1358 
1359 	DPRINTK("5 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1);
1360 #if 0
1361 	if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
1362 		devpriv->dmabuf_panic_size[0] =
1363 		    (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1364 		     1) * devpriv->ai_n_scanlen * sizeof(short);
1365 		devpriv->dmabuf_panic_size[1] =
1366 		    (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1367 		     1) * devpriv->ai_n_scanlen * sizeof(short);
1368 	} else {
1369 		devpriv->dmabuf_panic_size[0] =
1370 		    (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
1371 		devpriv->dmabuf_panic_size[1] =
1372 		    (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
1373 	}
1374 #endif
1375 
1376 	outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS),
1377 			devpriv->iobase_a + AMCC_OP_REG_MCSR);	/* stop DMA */
1378 	outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
1379 	outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
1380 	/* init DMA transfer */
1381 	outl(0x00000000 | AINT_WRITE_COMPL,
1382 	     devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1383 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
1384 
1385 	outl(inl(devpriv->iobase_a +
1386 		 AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
1387 	     EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
1388 	outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS,
1389 			devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1390 						/* allow bus mastering */
1391 
1392 	DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n");
1393 	return 0;
1394 }
1395 
1396 /*
1397 ==============================================================================
1398 */
pci9118_ai_docmd_sampl(struct comedi_device * dev,struct comedi_subdevice * s)1399 static int pci9118_ai_docmd_sampl(struct comedi_device *dev,
1400 				  struct comedi_subdevice *s)
1401 {
1402 	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n",
1403 		dev->minor, devpriv->ai_do);
1404 	switch (devpriv->ai_do) {
1405 	case 1:
1406 		devpriv->AdControlReg |= AdControl_TmrTr;
1407 		break;
1408 	case 2:
1409 		comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
1410 		return -EIO;
1411 	case 3:
1412 		devpriv->AdControlReg |= AdControl_ExtM;
1413 		break;
1414 	case 4:
1415 		comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
1416 		return -EIO;
1417 	default:
1418 		comedi_error(dev,
1419 			     "pci9118_ai_docmd_sampl() mode number bug!\n");
1420 		return -EIO;
1421 	}
1422 
1423 	devpriv->int_ai_func = interrupt_pci9118_ai_onesample;
1424 						/* transfer function */
1425 
1426 	if (devpriv->ai12_startstop)
1427 		pci9118_exttrg_add(dev, EXTTRG_AI);
1428 						/* activate EXT trigger */
1429 
1430 	if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
1431 		devpriv->IntControlReg |= Int_Timer;
1432 
1433 	devpriv->AdControlReg |= AdControl_Int;
1434 
1435 	outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
1436 			devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1437 							/* allow INT in AMCC */
1438 
1439 	if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1440 		outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1441 		outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1442 		if (devpriv->ai_do != 3) {
1443 			start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1444 				    devpriv->ai_divisor2);
1445 			devpriv->AdControlReg |= AdControl_SoftG;
1446 		}
1447 		outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1448 	}
1449 
1450 	DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n");
1451 	return 0;
1452 }
1453 
1454 /*
1455 ==============================================================================
1456 */
pci9118_ai_docmd_dma(struct comedi_device * dev,struct comedi_subdevice * s)1457 static int pci9118_ai_docmd_dma(struct comedi_device *dev,
1458 				struct comedi_subdevice *s)
1459 {
1460 	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n",
1461 		dev->minor, devpriv->ai_do, devpriv->usedma);
1462 	Compute_and_setup_dma(dev);
1463 
1464 	switch (devpriv->ai_do) {
1465 	case 1:
1466 		devpriv->AdControlReg |=
1467 		    ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1468 		break;
1469 	case 2:
1470 		devpriv->AdControlReg |=
1471 		    ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1472 		devpriv->AdFunctionReg =
1473 		    AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
1474 		    AdFunction_BS;
1475 		if (devpriv->usessh && (!devpriv->softsshdelay))
1476 			devpriv->AdFunctionReg |= AdFunction_BSSH;
1477 		outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
1478 		break;
1479 	case 3:
1480 		devpriv->AdControlReg |=
1481 		    ((AdControl_ExtM | AdControl_Dma) & 0xff);
1482 		devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1483 		break;
1484 	case 4:
1485 		devpriv->AdControlReg |=
1486 		    ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1487 		devpriv->AdFunctionReg =
1488 		    AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
1489 		outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1490 		outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1491 		outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
1492 		     dev->iobase + PCI9118_CNT0);
1493 		outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
1494 		     dev->iobase + PCI9118_CNT0);
1495 		devpriv->AdFunctionReg |= AdFunction_Start;
1496 		break;
1497 	default:
1498 		comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
1499 		return -EIO;
1500 	}
1501 
1502 	if (devpriv->ai12_startstop) {
1503 		pci9118_exttrg_add(dev, EXTTRG_AI);
1504 						/* activate EXT trigger */
1505 	}
1506 
1507 	devpriv->int_ai_func = interrupt_pci9118_ai_dma;
1508 						/* transfer function */
1509 
1510 	outl(0x02000000 | AINT_WRITE_COMPL,
1511 	     devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1512 
1513 	if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1514 		outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1515 		outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1516 		if (devpriv->ai_do != 3) {
1517 			start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1518 				    devpriv->ai_divisor2);
1519 			devpriv->AdControlReg |= AdControl_SoftG;
1520 		}
1521 		outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1522 	}
1523 
1524 	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n");
1525 	return 0;
1526 }
1527 
1528 /*
1529 ==============================================================================
1530 */
pci9118_ai_cmd(struct comedi_device * dev,struct comedi_subdevice * s)1531 static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1532 {
1533 	struct comedi_cmd *cmd = &s->async->cmd;
1534 	unsigned int addchans = 0;
1535 	int ret = 0;
1536 
1537 	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor);
1538 	devpriv->ai12_startstop = 0;
1539 	devpriv->ai_flags = cmd->flags;
1540 	devpriv->ai_n_chan = cmd->chanlist_len;
1541 	devpriv->ai_n_scanlen = cmd->scan_end_arg;
1542 	devpriv->ai_chanlist = cmd->chanlist;
1543 	devpriv->ai_data = s->async->prealloc_buf;
1544 	devpriv->ai_data_len = s->async->prealloc_bufsz;
1545 	devpriv->ai_timer1 = 0;
1546 	devpriv->ai_timer2 = 0;
1547 	devpriv->ai_add_front = 0;
1548 	devpriv->ai_add_back = 0;
1549 	devpriv->ai_maskerr = 0x10e;
1550 
1551 	/* prepare for start/stop conditions */
1552 	if (cmd->start_src == TRIG_EXT)
1553 		devpriv->ai12_startstop |= START_AI_EXT;
1554 	if (cmd->stop_src == TRIG_EXT) {
1555 		devpriv->ai_neverending = 1;
1556 		devpriv->ai12_startstop |= STOP_AI_EXT;
1557 	}
1558 	if (cmd->start_src == TRIG_INT) {
1559 		devpriv->ai12_startstop |= START_AI_INT;
1560 		devpriv->ai_inttrig_start = cmd->start_arg;
1561 		s->async->inttrig = pci9118_ai_inttrig;
1562 	}
1563 #if 0
1564 	if (cmd->stop_src == TRIG_INT) {
1565 		devpriv->ai_neverending = 1;
1566 		devpriv->ai12_startstop |= STOP_AI_INT;
1567 	}
1568 #endif
1569 	if (cmd->stop_src == TRIG_NONE)
1570 		devpriv->ai_neverending = 1;
1571 	if (cmd->stop_src == TRIG_COUNT) {
1572 		devpriv->ai_scans = cmd->stop_arg;
1573 		devpriv->ai_neverending = 0;
1574 	} else {
1575 		devpriv->ai_scans = 0;
1576 	}
1577 
1578 	/* use sample&hold signal? */
1579 	if (cmd->convert_src == TRIG_NOW)
1580 		devpriv->usessh = 1;
1581 	/* yes */
1582 	else
1583 		devpriv->usessh = 0;
1584 				/*  no */
1585 
1586 	DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n",
1587 		devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh,
1588 		devpriv->ai12_startstop);
1589 
1590 	/*
1591 	 * use additional sample at end of every scan
1592 	 * to satisty DMA 32 bit transfer?
1593 	 */
1594 	devpriv->ai_add_front = 0;
1595 	devpriv->ai_add_back = 0;
1596 	devpriv->useeoshandle = 0;
1597 	if (devpriv->master) {
1598 		devpriv->usedma = 1;
1599 		if ((cmd->flags & TRIG_WAKE_EOS) &&
1600 		    (devpriv->ai_n_scanlen == 1)) {
1601 			if (cmd->convert_src == TRIG_NOW)
1602 				devpriv->ai_add_back = 1;
1603 			if (cmd->convert_src == TRIG_TIMER) {
1604 				devpriv->usedma = 0;
1605 					/*
1606 					 * use INT transfer if scanlist
1607 					 * have only one channel
1608 					 */
1609 			}
1610 		}
1611 		if ((cmd->flags & TRIG_WAKE_EOS) &&
1612 		    (devpriv->ai_n_scanlen & 1) &&
1613 		    (devpriv->ai_n_scanlen > 1)) {
1614 			if (cmd->scan_begin_src == TRIG_FOLLOW) {
1615 				/*
1616 				 * vpriv->useeoshandle=1; // change DMA transfer
1617 				 * block to fit EOS on every second call
1618 				 */
1619 				devpriv->usedma = 0;
1620 				/*
1621 				 * XXX maybe can be corrected to use 16 bit DMA
1622 				 */
1623 			} else {	/*
1624 					 * well, we must insert one sample
1625 					 * to end of EOS to meet 32 bit transfer
1626 					 */
1627 				devpriv->ai_add_back = 1;
1628 			}
1629 		}
1630 	} else {	/* interrupt transfer don't need any correction */
1631 		devpriv->usedma = 0;
1632 	}
1633 
1634 	/*
1635 	 * we need software S&H signal?
1636 	 * It adds two samples before every scan as minimum
1637 	 */
1638 	if (devpriv->usessh && devpriv->softsshdelay) {
1639 		devpriv->ai_add_front = 2;
1640 		if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
1641 							/* move it to front */
1642 			devpriv->ai_add_front++;
1643 			devpriv->ai_add_back = 0;
1644 		}
1645 		if (cmd->convert_arg < this_board->ai_ns_min)
1646 			cmd->convert_arg = this_board->ai_ns_min;
1647 		addchans = devpriv->softsshdelay / cmd->convert_arg;
1648 		if (devpriv->softsshdelay % cmd->convert_arg)
1649 			addchans++;
1650 		if (addchans > (devpriv->ai_add_front - 1)) {
1651 							/* uff, still short */
1652 			devpriv->ai_add_front = addchans + 1;
1653 			if (devpriv->usedma == 1)
1654 				if ((devpriv->ai_add_front +
1655 				     devpriv->ai_n_chan +
1656 				     devpriv->ai_add_back) & 1)
1657 					devpriv->ai_add_front++;
1658 							/* round up to 32 bit */
1659 		}
1660 	}
1661 	/* well, we now know what must be all added */
1662 	devpriv->ai_n_realscanlen =	/*
1663 					 * what we must take from card in real
1664 					 * to have ai_n_scanlen on output?
1665 					 */
1666 	    (devpriv->ai_add_front + devpriv->ai_n_chan +
1667 	     devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
1668 				      devpriv->ai_n_chan);
1669 
1670 	DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
1671 		devpriv->usedma,
1672 		devpriv->ai_n_realscanlen, devpriv->ai_add_front,
1673 		devpriv->ai_n_chan, devpriv->ai_add_back,
1674 		devpriv->ai_n_scanlen);
1675 
1676 	/* check and setup channel list */
1677 	if (!check_channel_list(dev, s, devpriv->ai_n_chan,
1678 				devpriv->ai_chanlist, devpriv->ai_add_front,
1679 				devpriv->ai_add_back))
1680 		return -EINVAL;
1681 	if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
1682 				devpriv->ai_chanlist, 0, devpriv->ai_add_front,
1683 				devpriv->ai_add_back, devpriv->usedma,
1684 				devpriv->useeoshandle))
1685 		return -EINVAL;
1686 
1687 	/* compute timers settings */
1688 	/*
1689 	 * simplest way, fr=4Mhz/(tim1*tim2),
1690 	 * channel manipulation without timers effect
1691 	 */
1692 	if (((cmd->scan_begin_src == TRIG_FOLLOW) ||
1693 		(cmd->scan_begin_src == TRIG_EXT) ||
1694 		(cmd->scan_begin_src == TRIG_INT)) &&
1695 		(cmd->convert_src == TRIG_TIMER)) {
1696 					/* both timer is used for one time */
1697 		if (cmd->scan_begin_src == TRIG_EXT)
1698 			devpriv->ai_do = 4;
1699 		else
1700 			devpriv->ai_do = 1;
1701 		pci9118_calc_divisors(devpriv->ai_do, dev, s,
1702 				      &cmd->scan_begin_arg, &cmd->convert_arg,
1703 				      devpriv->ai_flags,
1704 				      devpriv->ai_n_realscanlen,
1705 				      &devpriv->ai_divisor1,
1706 				      &devpriv->ai_divisor2, devpriv->usessh,
1707 				      devpriv->ai_add_front);
1708 		devpriv->ai_timer2 = cmd->convert_arg;
1709 	}
1710 
1711 	if ((cmd->scan_begin_src == TRIG_TIMER) &&
1712 		((cmd->convert_src == TRIG_TIMER) ||
1713 		(cmd->convert_src == TRIG_NOW))) {
1714 						/* double timed action */
1715 		if (!devpriv->usedma) {
1716 			comedi_error(dev,
1717 				     "cmd->scan_begin_src=TRIG_TIMER works "
1718 						"only with bus mastering!");
1719 			return -EIO;
1720 		}
1721 
1722 		devpriv->ai_do = 2;
1723 		pci9118_calc_divisors(devpriv->ai_do, dev, s,
1724 				      &cmd->scan_begin_arg, &cmd->convert_arg,
1725 				      devpriv->ai_flags,
1726 				      devpriv->ai_n_realscanlen,
1727 				      &devpriv->ai_divisor1,
1728 				      &devpriv->ai_divisor2, devpriv->usessh,
1729 				      devpriv->ai_add_front);
1730 		devpriv->ai_timer1 = cmd->scan_begin_arg;
1731 		devpriv->ai_timer2 = cmd->convert_arg;
1732 	}
1733 
1734 	if ((cmd->scan_begin_src == TRIG_FOLLOW)
1735 	    && (cmd->convert_src == TRIG_EXT)) {
1736 		devpriv->ai_do = 3;
1737 	}
1738 
1739 	start_pacer(dev, -1, 0, 0);	/* stop pacer */
1740 
1741 	devpriv->AdControlReg = 0;	/*
1742 					 * bipolar, S.E., use 8254, stop 8354,
1743 					 * internal trigger, soft trigger,
1744 					 * disable DMA
1745 					 */
1746 	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1747 	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1748 					/*
1749 					 * positive triggers, no S&H, no burst,
1750 					 * burst stop, no post trigger,
1751 					 * no about trigger, trigger stop
1752 					 */
1753 	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1754 	udelay(1);
1755 	outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
1756 	inl(dev->iobase + PCI9118_ADSTAT);	/*
1757 						 * flush A/D and INT
1758 						 * status register
1759 						 */
1760 	inl(dev->iobase + PCI9118_INTSRC);
1761 
1762 	devpriv->ai_act_scan = 0;
1763 	devpriv->ai_act_dmapos = 0;
1764 	s->async->cur_chan = 0;
1765 	devpriv->ai_buf_ptr = 0;
1766 
1767 	if (devpriv->usedma)
1768 		ret = pci9118_ai_docmd_dma(dev, s);
1769 	else
1770 		ret = pci9118_ai_docmd_sampl(dev, s);
1771 
1772 	DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
1773 	return ret;
1774 }
1775 
1776 /*
1777 ==============================================================================
1778 */
check_channel_list(struct comedi_device * dev,struct comedi_subdevice * s,int n_chan,unsigned int * chanlist,int frontadd,int backadd)1779 static int check_channel_list(struct comedi_device *dev,
1780 			      struct comedi_subdevice *s, int n_chan,
1781 			      unsigned int *chanlist, int frontadd, int backadd)
1782 {
1783 	unsigned int i, differencial = 0, bipolar = 0;
1784 
1785 	/* correct channel and range number check itself comedi/range.c */
1786 	if (n_chan < 1) {
1787 		comedi_error(dev, "range/channel list is empty!");
1788 		return 0;
1789 	}
1790 	if ((frontadd + n_chan + backadd) > s->len_chanlist) {
1791 		printk
1792 		    ("comedi%d: range/channel list is too long for "
1793 						"actual configuration (%d>%d)!",
1794 		     dev->minor, n_chan, s->len_chanlist - frontadd - backadd);
1795 		return 0;
1796 	}
1797 
1798 	if (CR_AREF(chanlist[0]) == AREF_DIFF)
1799 		differencial = 1;	/* all input must be diff */
1800 	if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1801 		bipolar = 1;	/* all input must be bipolar */
1802 	if (n_chan > 1)
1803 		for (i = 1; i < n_chan; i++) {	/* check S.E/diff */
1804 			if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
1805 			    (differencial)) {
1806 				comedi_error(dev,
1807 					     "Differencial and single ended "
1808 						"inputs can't be mixtured!");
1809 				return 0;
1810 			}
1811 			if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
1812 			    (bipolar)) {
1813 				comedi_error(dev,
1814 					     "Bipolar and unipolar ranges "
1815 							"can't be mixtured!");
1816 				return 0;
1817 			}
1818 			if ((!devpriv->usemux) & (differencial) &
1819 			    (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
1820 				comedi_error(dev,
1821 					     "If AREF_DIFF is used then is "
1822 					"available only first 8 channels!");
1823 				return 0;
1824 			}
1825 		}
1826 
1827 	return 1;
1828 }
1829 
1830 /*
1831 ==============================================================================
1832 */
setup_channel_list(struct comedi_device * dev,struct comedi_subdevice * s,int n_chan,unsigned int * chanlist,int rot,int frontadd,int backadd,int usedma,char useeos)1833 static int setup_channel_list(struct comedi_device *dev,
1834 			      struct comedi_subdevice *s, int n_chan,
1835 			      unsigned int *chanlist, int rot, int frontadd,
1836 			      int backadd, int usedma, char useeos)
1837 {
1838 	unsigned int i, differencial = 0, bipolar = 0;
1839 	unsigned int scanquad, gain, ssh = 0x00;
1840 
1841 	DPRINTK
1842 	    ("adl_pci9118 EDBG: BGN: setup_channel_list"
1843 						"(%d,.,%d,.,%d,%d,%d,%d)\n",
1844 	     dev->minor, n_chan, rot, frontadd, backadd, usedma);
1845 
1846 	if (usedma == 1) {
1847 		rot = 8;
1848 		usedma = 0;
1849 	}
1850 
1851 	if (CR_AREF(chanlist[0]) == AREF_DIFF)
1852 		differencial = 1;	/* all input must be diff */
1853 	if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1854 		bipolar = 1;	/* all input must be bipolar */
1855 
1856 	/* All is ok, so we can setup channel/range list */
1857 
1858 	if (!bipolar) {
1859 		devpriv->AdControlReg |= AdControl_UniP;
1860 							/* set unibipolar */
1861 	} else {
1862 		devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
1863 							/* enable bipolar */
1864 	}
1865 
1866 	if (differencial) {
1867 		devpriv->AdControlReg |= AdControl_Diff;
1868 							/* enable diff inputs */
1869 	} else {
1870 		devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
1871 						/* set single ended inputs */
1872 	}
1873 
1874 	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1875 								/* setup mode */
1876 
1877 	outl(2, dev->iobase + PCI9118_SCANMOD);
1878 					/* gods know why this sequence! */
1879 	outl(0, dev->iobase + PCI9118_SCANMOD);
1880 	outl(1, dev->iobase + PCI9118_SCANMOD);
1881 
1882 #ifdef PCI9118_PARANOIDCHECK
1883 	devpriv->chanlistlen = n_chan;
1884 	for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
1885 		devpriv->chanlist[i] = 0x55aa;
1886 #endif
1887 
1888 	if (frontadd) {		/* insert channels for S&H */
1889 		ssh = devpriv->softsshsample;
1890 		DPRINTK("FA: %04x: ", ssh);
1891 		for (i = 0; i < frontadd; i++) {
1892 						/* store range list to card */
1893 			scanquad = CR_CHAN(chanlist[0]);
1894 						/* get channel number; */
1895 			gain = CR_RANGE(chanlist[0]);
1896 						/* get gain number */
1897 			scanquad |= ((gain & 0x03) << 8);
1898 			outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1899 			DPRINTK("%02x ", scanquad | ssh);
1900 			ssh = devpriv->softsshhold;
1901 		}
1902 		DPRINTK("\n ");
1903 	}
1904 
1905 	DPRINTK("SL: ", ssh);
1906 	for (i = 0; i < n_chan; i++) {	/* store range list to card */
1907 		scanquad = CR_CHAN(chanlist[i]);	/* get channel number */
1908 #ifdef PCI9118_PARANOIDCHECK
1909 		devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
1910 #endif
1911 		gain = CR_RANGE(chanlist[i]);		/* get gain number */
1912 		scanquad |= ((gain & 0x03) << 8);
1913 		outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1914 		DPRINTK("%02x ", scanquad | ssh);
1915 	}
1916 	DPRINTK("\n ");
1917 
1918 	if (backadd) {		/* insert channels for fit onto 32bit DMA */
1919 		DPRINTK("BA: %04x: ", ssh);
1920 		for (i = 0; i < backadd; i++) {	/* store range list to card */
1921 			scanquad = CR_CHAN(chanlist[0]);
1922 							/* get channel number */
1923 			gain = CR_RANGE(chanlist[0]);	/* get gain number */
1924 			scanquad |= ((gain & 0x03) << 8);
1925 			outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1926 			DPRINTK("%02x ", scanquad | ssh);
1927 		}
1928 		DPRINTK("\n ");
1929 	}
1930 #ifdef PCI9118_PARANOIDCHECK
1931 	devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
1932 						/* for 32bit operations */
1933 	if (useeos) {
1934 		for (i = 1; i < n_chan; i++) {	/* store range list to card */
1935 			devpriv->chanlist[(n_chan + i) ^ usedma] =
1936 			    (CR_CHAN(chanlist[i]) & 0xf) << rot;
1937 		}
1938 		devpriv->chanlist[(2 * n_chan) ^ usedma] =
1939 						devpriv->chanlist[0 ^ usedma];
1940 						/* for 32bit operations */
1941 		useeos = 2;
1942 	} else {
1943 		useeos = 1;
1944 	}
1945 #ifdef PCI9118_EXTDEBUG
1946 	DPRINTK("CHL: ");
1947 	for (i = 0; i <= (useeos * n_chan); i++)
1948 		DPRINTK("%04x ", devpriv->chanlist[i]);
1949 
1950 	DPRINTK("\n ");
1951 #endif
1952 #endif
1953 	outl(0, dev->iobase + PCI9118_SCANMOD);	/* close scan queue */
1954 	/* udelay(100); important delay, or first sample will be crippled */
1955 
1956 	DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
1957 	return 1;		/* we can serve this with scan logic */
1958 }
1959 
1960 /*
1961 ==============================================================================
1962   calculate 8254 divisors if they are used for dual timing
1963 */
pci9118_calc_divisors(char mode,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,char usessh,unsigned int chnsshfront)1964 static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
1965 				  struct comedi_subdevice *s,
1966 				  unsigned int *tim1, unsigned int *tim2,
1967 				  unsigned int flags, int chans,
1968 				  unsigned int *div1, unsigned int *div2,
1969 				  char usessh, unsigned int chnsshfront)
1970 {
1971 	DPRINTK
1972 	    ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors"
1973 					"(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n",
1974 	     mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront);
1975 	switch (mode) {
1976 	case 1:
1977 	case 4:
1978 		if (*tim2 < this_board->ai_ns_min)
1979 			*tim2 = this_board->ai_ns_min;
1980 		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
1981 					  tim2, flags & TRIG_ROUND_NEAREST);
1982 		DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
1983 			devpriv->i8254_osc_base, *div1, *div2, *tim1);
1984 		break;
1985 	case 2:
1986 		if (*tim2 < this_board->ai_ns_min)
1987 			*tim2 = this_board->ai_ns_min;
1988 		DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1989 			*tim1, *tim2);
1990 		*div1 = *tim2 / devpriv->i8254_osc_base;
1991 						/* convert timer (burst) */
1992 		DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1993 			*tim1, *tim2);
1994 		if (*div1 < this_board->ai_pacer_min)
1995 			*div1 = this_board->ai_pacer_min;
1996 		DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1997 			*tim1, *tim2);
1998 		*div2 = *tim1 / devpriv->i8254_osc_base;	/* scan timer */
1999 		DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2000 			*tim1, *tim2);
2001 		*div2 = *div2 / *div1;		/* major timer is c1*c2 */
2002 		DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2003 			*tim1, *tim2);
2004 		if (*div2 < chans)
2005 			*div2 = chans;
2006 		DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2007 			*tim1, *tim2);
2008 
2009 		*tim2 = *div1 * devpriv->i8254_osc_base;
2010 							/* real convert timer */
2011 
2012 		if (usessh & (chnsshfront == 0))	/* use BSSH signal */
2013 			if (*div2 < (chans + 2))
2014 				*div2 = chans + 2;
2015 
2016 		DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2017 			*tim1, *tim2);
2018 		*tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
2019 		DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",
2020 			devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2);
2021 		break;
2022 	}
2023 	DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
2024 		*div1, *div2);
2025 }
2026 
2027 /*
2028 ==============================================================================
2029 */
start_pacer(struct comedi_device * dev,int mode,unsigned int divisor1,unsigned int divisor2)2030 static void start_pacer(struct comedi_device *dev, int mode,
2031 			unsigned int divisor1, unsigned int divisor2)
2032 {
2033 	outl(0x74, dev->iobase + PCI9118_CNTCTRL);
2034 	outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
2035 /* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
2036 	udelay(1);
2037 
2038 	if ((mode == 1) || (mode == 2) || (mode == 4)) {
2039 		outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
2040 		outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
2041 		outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
2042 		outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
2043 	}
2044 }
2045 
2046 /*
2047 ==============================================================================
2048 */
pci9118_exttrg_add(struct comedi_device * dev,unsigned char source)2049 static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
2050 {
2051 	if (source > 3)
2052 		return -1;				/* incorrect source */
2053 	devpriv->exttrg_users |= (1 << source);
2054 	devpriv->IntControlReg |= Int_DTrg;
2055 	outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2056 	outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
2057 					devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2058 							/* allow INT in AMCC */
2059 	return 0;
2060 }
2061 
2062 /*
2063 ==============================================================================
2064 */
pci9118_exttrg_del(struct comedi_device * dev,unsigned char source)2065 static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
2066 {
2067 	if (source > 3)
2068 		return -1;			/* incorrect source */
2069 	devpriv->exttrg_users &= ~(1 << source);
2070 	if (!devpriv->exttrg_users) {	/* shutdown ext trg intterrupts */
2071 		devpriv->IntControlReg &= ~Int_DTrg;
2072 		if (!devpriv->IntControlReg)	/* all IRQ disabled */
2073 			outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) &
2074 					(~0x00001f00),
2075 					devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2076 						/* disable int in AMCC */
2077 		outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2078 	}
2079 	return 0;
2080 }
2081 
2082 /*
2083 ==============================================================================
2084 */
pci9118_ai_cancel(struct comedi_device * dev,struct comedi_subdevice * s)2085 static int pci9118_ai_cancel(struct comedi_device *dev,
2086 			     struct comedi_subdevice *s)
2087 {
2088 	if (devpriv->usedma)
2089 		outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) &
2090 			(~EN_A2P_TRANSFERS),
2091 			devpriv->iobase_a + AMCC_OP_REG_MCSR);	/* stop DMA */
2092 	pci9118_exttrg_del(dev, EXTTRG_AI);
2093 	start_pacer(dev, 0, 0, 0);	/* stop 8254 counters */
2094 	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2095 	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2096 					/*
2097 					 * positive triggers, no S&H, no burst,
2098 					 * burst stop, no post trigger,
2099 					 * no about trigger, trigger stop
2100 					 */
2101 	devpriv->AdControlReg = 0x00;
2102 	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2103 					/*
2104 					 * bipolar, S.E., use 8254, stop 8354,
2105 					 * internal trigger, soft trigger,
2106 					 * disable INT and DMA
2107 					 */
2108 	outl(0, dev->iobase + PCI9118_BURST);
2109 	outl(1, dev->iobase + PCI9118_SCANMOD);
2110 	outl(2, dev->iobase + PCI9118_SCANMOD);	/* reset scan queue */
2111 	outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
2112 
2113 	devpriv->ai_do = 0;
2114 	devpriv->usedma = 0;
2115 
2116 	devpriv->ai_act_scan = 0;
2117 	devpriv->ai_act_dmapos = 0;
2118 	s->async->cur_chan = 0;
2119 	s->async->inttrig = NULL;
2120 	devpriv->ai_buf_ptr = 0;
2121 	devpriv->ai_neverending = 0;
2122 	devpriv->dma_actbuf = 0;
2123 
2124 	if (!devpriv->IntControlReg)
2125 		outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
2126 					devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2127 							/* allow INT in AMCC */
2128 
2129 	return 0;
2130 }
2131 
2132 /*
2133 ==============================================================================
2134 */
pci9118_reset(struct comedi_device * dev)2135 static int pci9118_reset(struct comedi_device *dev)
2136 {
2137 	devpriv->IntControlReg = 0;
2138 	devpriv->exttrg_users = 0;
2139 	inl(dev->iobase + PCI9118_INTCTRL);
2140 	outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2141 						/* disable interrupts source */
2142 	outl(0x30, dev->iobase + PCI9118_CNTCTRL);
2143 /* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
2144 	start_pacer(dev, 0, 0, 0);		/* stop 8254 counters */
2145 	devpriv->AdControlReg = 0;
2146 	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2147 						/*
2148 						 * bipolar, S.E., use 8254,
2149 						 * stop 8354, internal trigger,
2150 						 * soft trigger,
2151 						 * disable INT and DMA
2152 						 */
2153 	outl(0, dev->iobase + PCI9118_BURST);
2154 	outl(1, dev->iobase + PCI9118_SCANMOD);
2155 	outl(2, dev->iobase + PCI9118_SCANMOD);	/* reset scan queue */
2156 	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2157 	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2158 						/*
2159 						 * positive triggers, no S&H,
2160 						 * no burst, burst stop,
2161 						 * no post trigger,
2162 						 * no about trigger,
2163 						 * trigger stop
2164 						 */
2165 
2166 	devpriv->ao_data[0] = 2047;
2167 	devpriv->ao_data[1] = 2047;
2168 	outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1);
2169 						/* reset A/D outs to 0V */
2170 	outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
2171 	outl(0, dev->iobase + PCI9118_DO);	/* reset digi outs to L */
2172 	udelay(10);
2173 	inl(dev->iobase + PCI9118_AD_DATA);
2174 	outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
2175 	outl(0, dev->iobase + PCI9118_INTSRC);	/* remove INT requests */
2176 	inl(dev->iobase + PCI9118_ADSTAT);	/* flush A/D status register */
2177 	inl(dev->iobase + PCI9118_INTSRC);	/* flush INT requests */
2178 	devpriv->AdControlReg = 0;
2179 	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2180 						/*
2181 						 * bipolar, S.E., use 8254,
2182 						 * stop 8354, internal trigger,
2183 						 * soft trigger,
2184 						 * disable INT and DMA
2185 						 */
2186 
2187 	devpriv->cnt0_users = 0;
2188 	devpriv->exttrg_users = 0;
2189 
2190 	return 0;
2191 }
2192 
2193 /*
2194 ==============================================================================
2195 */
pci9118_attach(struct comedi_device * dev,struct comedi_devconfig * it)2196 static int pci9118_attach(struct comedi_device *dev,
2197 			  struct comedi_devconfig *it)
2198 {
2199 	struct comedi_subdevice *s;
2200 	int ret, pages, i;
2201 	unsigned short master;
2202 	unsigned int irq;
2203 	unsigned long iobase_a, iobase_9;
2204 	struct pci_dev *pcidev;
2205 	int opt_bus, opt_slot;
2206 	const char *errstr;
2207 	unsigned char pci_bus, pci_slot, pci_func;
2208 	u16 u16w;
2209 
2210 	printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name);
2211 
2212 	opt_bus = it->options[0];
2213 	opt_slot = it->options[1];
2214 	if (it->options[3] & 1)
2215 		master = 0;	/* user don't want use bus master */
2216 	else
2217 		master = 1;
2218 
2219 	ret = alloc_private(dev, sizeof(struct pci9118_private));
2220 	if (ret < 0) {
2221 		printk(" - Allocation failed!\n");
2222 		return -ENOMEM;
2223 	}
2224 
2225 	/* Look for matching PCI device */
2226 	errstr = "not found!";
2227 	pcidev = NULL;
2228 	while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
2229 						this_board->device_id,
2230 						pcidev))) {
2231 		/* Found matching vendor/device. */
2232 		if (opt_bus || opt_slot) {
2233 			/* Check bus/slot. */
2234 			if (opt_bus != pcidev->bus->number
2235 			    || opt_slot != PCI_SLOT(pcidev->devfn))
2236 				continue;	/* no match */
2237 		}
2238 		/*
2239 		 * Look for device that isn't in use.
2240 		 * Enable PCI device and request regions.
2241 		 */
2242 		if (comedi_pci_enable(pcidev, "adl_pci9118")) {
2243 			errstr =
2244 			    "failed to enable PCI device and request regions!";
2245 			continue;
2246 		}
2247 		break;
2248 	}
2249 
2250 	if (!pcidev) {
2251 		if (opt_bus || opt_slot) {
2252 			printk(KERN_ERR " - Card at b:s %d:%d %s\n",
2253 			       opt_bus, opt_slot, errstr);
2254 		} else {
2255 			printk(KERN_ERR " - Card %s\n", errstr);
2256 		}
2257 		return -EIO;
2258 	}
2259 
2260 	if (master)
2261 		pci_set_master(pcidev);
2262 
2263 
2264 	pci_bus = pcidev->bus->number;
2265 	pci_slot = PCI_SLOT(pcidev->devfn);
2266 	pci_func = PCI_FUNC(pcidev->devfn);
2267 	irq = pcidev->irq;
2268 	iobase_a = pci_resource_start(pcidev, 0);
2269 	iobase_9 = pci_resource_start(pcidev, 2);
2270 
2271 	printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus,
2272 				pci_slot, pci_func, iobase_9, iobase_a);
2273 
2274 	dev->iobase = iobase_9;
2275 	dev->board_name = this_board->name;
2276 
2277 	devpriv->pcidev = pcidev;
2278 	devpriv->iobase_a = iobase_a;
2279 
2280 	pci9118_reset(dev);
2281 
2282 	if (it->options[3] & 2)
2283 		irq = 0;	/* user don't want use IRQ */
2284 	if (irq > 0) {
2285 		if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
2286 				"ADLink PCI-9118", dev)) {
2287 			printk(", unable to allocate IRQ %d, DISABLING IT",
2288 			       irq);
2289 			irq = 0;	/* Can't use IRQ */
2290 		} else {
2291 			printk(", irq=%u", irq);
2292 		}
2293 	} else {
2294 		printk(", IRQ disabled");
2295 	}
2296 
2297 	dev->irq = irq;
2298 
2299 	if (master) {		/* alloc DMA buffers */
2300 		devpriv->dma_doublebuf = 0;
2301 		for (i = 0; i < 2; i++) {
2302 			for (pages = 4; pages >= 0; pages--) {
2303 				devpriv->dmabuf_virt[i] =
2304 				    (short *)__get_free_pages(GFP_KERNEL,
2305 							      pages);
2306 				if (devpriv->dmabuf_virt[i])
2307 					break;
2308 			}
2309 			if (devpriv->dmabuf_virt[i]) {
2310 				devpriv->dmabuf_pages[i] = pages;
2311 				devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
2312 				devpriv->dmabuf_samples[i] =
2313 				    devpriv->dmabuf_size[i] >> 1;
2314 				devpriv->dmabuf_hw[i] =
2315 				    virt_to_bus((void *)
2316 						devpriv->dmabuf_virt[i]);
2317 			}
2318 		}
2319 		if (!devpriv->dmabuf_virt[0]) {
2320 			printk(", Can't allocate DMA buffer, DMA disabled!");
2321 			master = 0;
2322 		}
2323 
2324 		if (devpriv->dmabuf_virt[1])
2325 			devpriv->dma_doublebuf = 1;
2326 
2327 	}
2328 
2329 	devpriv->master = master;
2330 	if (devpriv->master)
2331 		printk(", bus master");
2332 	else
2333 		printk(", no bus master");
2334 
2335 	devpriv->usemux = 0;
2336 	if (it->options[2] > 0) {
2337 		devpriv->usemux = it->options[2];
2338 		if (devpriv->usemux > 256)
2339 			devpriv->usemux = 256;	/* max 256 channels! */
2340 		if (it->options[4] > 0)
2341 			if (devpriv->usemux > 128) {
2342 				devpriv->usemux = 128;
2343 					/* max 128 channels with softare S&H! */
2344 			}
2345 		printk(", ext. mux %d channels", devpriv->usemux);
2346 	}
2347 
2348 	devpriv->softsshdelay = it->options[4];
2349 	if (devpriv->softsshdelay < 0) {
2350 					/* select sample&hold signal polarity */
2351 		devpriv->softsshdelay = -devpriv->softsshdelay;
2352 		devpriv->softsshsample = 0x80;
2353 		devpriv->softsshhold = 0x00;
2354 	} else {
2355 		devpriv->softsshsample = 0x00;
2356 		devpriv->softsshhold = 0x80;
2357 	}
2358 
2359 	printk(".\n");
2360 
2361 	pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
2362 	pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64);
2363 				/* Enable parity check for parity error */
2364 
2365 	ret = alloc_subdevices(dev, 4);
2366 	if (ret < 0)
2367 		return ret;
2368 
2369 	s = dev->subdevices + 0;
2370 	dev->read_subdev = s;
2371 	s->type = COMEDI_SUBD_AI;
2372 	s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2373 	if (devpriv->usemux)
2374 		s->n_chan = devpriv->usemux;
2375 	else
2376 		s->n_chan = this_board->n_aichan;
2377 
2378 	s->maxdata = this_board->ai_maxdata;
2379 	s->len_chanlist = this_board->n_aichanlist;
2380 	s->range_table = this_board->rangelist_ai;
2381 	s->cancel = pci9118_ai_cancel;
2382 	s->insn_read = pci9118_insn_read_ai;
2383 	if (dev->irq) {
2384 		s->subdev_flags |= SDF_CMD_READ;
2385 		s->do_cmdtest = pci9118_ai_cmdtest;
2386 		s->do_cmd = pci9118_ai_cmd;
2387 		s->munge = pci9118_ai_munge;
2388 	}
2389 
2390 	s = dev->subdevices + 1;
2391 	s->type = COMEDI_SUBD_AO;
2392 	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2393 	s->n_chan = this_board->n_aochan;
2394 	s->maxdata = this_board->ao_maxdata;
2395 	s->len_chanlist = this_board->n_aochan;
2396 	s->range_table = this_board->rangelist_ao;
2397 	s->insn_write = pci9118_insn_write_ao;
2398 	s->insn_read = pci9118_insn_read_ao;
2399 
2400 	s = dev->subdevices + 2;
2401 	s->type = COMEDI_SUBD_DI;
2402 	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2403 	s->n_chan = 4;
2404 	s->maxdata = 1;
2405 	s->len_chanlist = 4;
2406 	s->range_table = &range_digital;
2407 	s->io_bits = 0;		/* all bits input */
2408 	s->insn_bits = pci9118_insn_bits_di;
2409 
2410 	s = dev->subdevices + 3;
2411 	s->type = COMEDI_SUBD_DO;
2412 	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2413 	s->n_chan = 4;
2414 	s->maxdata = 1;
2415 	s->len_chanlist = 4;
2416 	s->range_table = &range_digital;
2417 	s->io_bits = 0xf;	/* all bits output */
2418 	s->insn_bits = pci9118_insn_bits_do;
2419 
2420 	devpriv->valid = 1;
2421 	devpriv->i8254_osc_base = 250;	/* 250ns=4MHz */
2422 	devpriv->ai_maskharderr = 0x10a;
2423 					/* default measure crash condition */
2424 	if (it->options[5])		/* disable some requested */
2425 		devpriv->ai_maskharderr &= ~it->options[5];
2426 
2427 	switch (this_board->ai_maxdata) {
2428 	case 0xffff:
2429 		devpriv->ai16bits = 1;
2430 		break;
2431 	default:
2432 		devpriv->ai16bits = 0;
2433 		break;
2434 	}
2435 	return 0;
2436 }
2437 
2438 /*
2439 ==============================================================================
2440 */
pci9118_detach(struct comedi_device * dev)2441 static int pci9118_detach(struct comedi_device *dev)
2442 {
2443 	if (dev->private) {
2444 		if (devpriv->valid)
2445 			pci9118_reset(dev);
2446 		if (dev->irq)
2447 			free_irq(dev->irq, dev);
2448 		if (devpriv->pcidev) {
2449 			if (dev->iobase)
2450 				comedi_pci_disable(devpriv->pcidev);
2451 
2452 			pci_dev_put(devpriv->pcidev);
2453 		}
2454 		if (devpriv->dmabuf_virt[0])
2455 			free_pages((unsigned long)devpriv->dmabuf_virt[0],
2456 				   devpriv->dmabuf_pages[0]);
2457 		if (devpriv->dmabuf_virt[1])
2458 			free_pages((unsigned long)devpriv->dmabuf_virt[1],
2459 				   devpriv->dmabuf_pages[1]);
2460 	}
2461 
2462 	return 0;
2463 }
2464 
2465 /*
2466 ==============================================================================
2467 */
2468 
2469 MODULE_AUTHOR("Comedi http://www.comedi.org");
2470 MODULE_DESCRIPTION("Comedi low-level driver");
2471 MODULE_LICENSE("GPL");
2472