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