adl_pci9118.c revision a285bf995da256be5d96110ec0e7592cb6b2e600
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			}
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		}
1702		pci9118_calc_divisors(devpriv->ai_do, dev, s,
1703				      &cmd->scan_begin_arg, &cmd->convert_arg,
1704				      devpriv->ai_flags,
1705				      devpriv->ai_n_realscanlen,
1706				      &devpriv->ai_divisor1,
1707				      &devpriv->ai_divisor2, devpriv->usessh,
1708				      devpriv->ai_add_front);
1709		devpriv->ai_timer2 = cmd->convert_arg;
1710	}
1711
1712	if ((cmd->scan_begin_src == TRIG_TIMER) &&
1713		((cmd->convert_src == TRIG_TIMER) ||
1714		(cmd->convert_src == TRIG_NOW))) {
1715						/* double timed action */
1716		if (!devpriv->usedma) {
1717			comedi_error(dev,
1718				     "cmd->scan_begin_src=TRIG_TIMER works "
1719						"only with bus mastering!");
1720			return -EIO;
1721		}
1722
1723		devpriv->ai_do = 2;
1724		pci9118_calc_divisors(devpriv->ai_do, dev, s,
1725				      &cmd->scan_begin_arg, &cmd->convert_arg,
1726				      devpriv->ai_flags,
1727				      devpriv->ai_n_realscanlen,
1728				      &devpriv->ai_divisor1,
1729				      &devpriv->ai_divisor2, devpriv->usessh,
1730				      devpriv->ai_add_front);
1731		devpriv->ai_timer1 = cmd->scan_begin_arg;
1732		devpriv->ai_timer2 = cmd->convert_arg;
1733	}
1734
1735	if ((cmd->scan_begin_src == TRIG_FOLLOW)
1736	    && (cmd->convert_src == TRIG_EXT)) {
1737		devpriv->ai_do = 3;
1738	}
1739
1740	start_pacer(dev, -1, 0, 0);	/* stop pacer */
1741
1742	devpriv->AdControlReg = 0;	/*
1743					 * bipolar, S.E., use 8254, stop 8354,
1744					 * internal trigger, soft trigger,
1745					 * disable DMA
1746					 */
1747	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1748	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1749					/*
1750					 * positive triggers, no S&H, no burst,
1751					 * burst stop, no post trigger,
1752					 * no about trigger, trigger stop
1753					 */
1754	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1755	udelay(1);
1756	outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
1757	inl(dev->iobase + PCI9118_ADSTAT);	/*
1758						 * flush A/D and INT
1759						 * status register
1760						 */
1761	inl(dev->iobase + PCI9118_INTSRC);
1762
1763	devpriv->ai_act_scan = 0;
1764	devpriv->ai_act_dmapos = 0;
1765	s->async->cur_chan = 0;
1766	devpriv->ai_buf_ptr = 0;
1767
1768	if (devpriv->usedma)
1769		ret = pci9118_ai_docmd_dma(dev, s);
1770	else
1771		ret = pci9118_ai_docmd_sampl(dev, s);
1772
1773	DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
1774	return ret;
1775}
1776
1777/*
1778==============================================================================
1779*/
1780static int check_channel_list(struct comedi_device *dev,
1781			      struct comedi_subdevice *s, int n_chan,
1782			      unsigned int *chanlist, int frontadd, int backadd)
1783{
1784	unsigned int i, differencial = 0, bipolar = 0;
1785
1786	/* correct channel and range number check itself comedi/range.c */
1787	if (n_chan < 1) {
1788		comedi_error(dev, "range/channel list is empty!");
1789		return 0;
1790	}
1791	if ((frontadd + n_chan + backadd) > s->len_chanlist) {
1792		printk
1793		    ("comedi%d: range/channel list is too long for "
1794						"actual configuration (%d>%d)!",
1795		     dev->minor, n_chan, s->len_chanlist - frontadd - backadd);
1796		return 0;
1797	}
1798
1799	if (CR_AREF(chanlist[0]) == AREF_DIFF)
1800		differencial = 1;	/* all input must be diff */
1801	if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1802		bipolar = 1;	/* all input must be bipolar */
1803	if (n_chan > 1)
1804		for (i = 1; i < n_chan; i++) {	/* check S.E/diff */
1805			if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
1806			    (differencial)) {
1807				comedi_error(dev,
1808					     "Differencial and single ended "
1809						"inputs can't be mixtured!");
1810				return 0;
1811			}
1812			if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
1813			    (bipolar)) {
1814				comedi_error(dev,
1815					     "Bipolar and unipolar ranges "
1816							"can't be mixtured!");
1817				return 0;
1818			}
1819			if ((!devpriv->usemux) & (differencial) &
1820			    (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
1821				comedi_error(dev,
1822					     "If AREF_DIFF is used then is "
1823					"available only first 8 channels!");
1824				return 0;
1825			}
1826		}
1827
1828	return 1;
1829}
1830
1831/*
1832==============================================================================
1833*/
1834static int setup_channel_list(struct comedi_device *dev,
1835			      struct comedi_subdevice *s, int n_chan,
1836			      unsigned int *chanlist, int rot, int frontadd,
1837			      int backadd, int usedma, char useeos)
1838{
1839	unsigned int i, differencial = 0, bipolar = 0;
1840	unsigned int scanquad, gain, ssh = 0x00;
1841
1842	DPRINTK
1843	    ("adl_pci9118 EDBG: BGN: setup_channel_list"
1844						"(%d,.,%d,.,%d,%d,%d,%d)\n",
1845	     dev->minor, n_chan, rot, frontadd, backadd, usedma);
1846
1847	if (usedma == 1) {
1848		rot = 8;
1849		usedma = 0;
1850	}
1851
1852	if (CR_AREF(chanlist[0]) == AREF_DIFF)
1853		differencial = 1;	/* all input must be diff */
1854	if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1855		bipolar = 1;	/* all input must be bipolar */
1856
1857	/* All is ok, so we can setup channel/range list */
1858
1859	if (!bipolar) {
1860		devpriv->AdControlReg |= AdControl_UniP;
1861							/* set unibipolar */
1862	} else {
1863		devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
1864							/* enable bipolar */
1865	}
1866
1867	if (differencial) {
1868		devpriv->AdControlReg |= AdControl_Diff;
1869							/* enable diff inputs */
1870	} else {
1871		devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
1872						/* set single ended inputs */
1873	}
1874
1875	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1876								/* setup mode */
1877
1878	outl(2, dev->iobase + PCI9118_SCANMOD);
1879					/* gods know why this sequence! */
1880	outl(0, dev->iobase + PCI9118_SCANMOD);
1881	outl(1, dev->iobase + PCI9118_SCANMOD);
1882
1883#ifdef PCI9118_PARANOIDCHECK
1884	devpriv->chanlistlen = n_chan;
1885	for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
1886		devpriv->chanlist[i] = 0x55aa;
1887#endif
1888
1889	if (frontadd) {		/* insert channels for S&H */
1890		ssh = devpriv->softsshsample;
1891		DPRINTK("FA: %04x: ", ssh);
1892		for (i = 0; i < frontadd; i++) {
1893						/* store range list to card */
1894			scanquad = CR_CHAN(chanlist[0]);
1895						/* get channel number; */
1896			gain = CR_RANGE(chanlist[0]);
1897						/* get gain number */
1898			scanquad |= ((gain & 0x03) << 8);
1899			outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1900			DPRINTK("%02x ", scanquad | ssh);
1901			ssh = devpriv->softsshhold;
1902		}
1903		DPRINTK("\n ");
1904	}
1905
1906	DPRINTK("SL: ", ssh);
1907	for (i = 0; i < n_chan; i++) {	/* store range list to card */
1908		scanquad = CR_CHAN(chanlist[i]);	/* get channel number */
1909#ifdef PCI9118_PARANOIDCHECK
1910		devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
1911#endif
1912		gain = CR_RANGE(chanlist[i]);		/* get gain number */
1913		scanquad |= ((gain & 0x03) << 8);
1914		outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1915		DPRINTK("%02x ", scanquad | ssh);
1916	}
1917	DPRINTK("\n ");
1918
1919	if (backadd) {		/* insert channels for fit onto 32bit DMA */
1920		DPRINTK("BA: %04x: ", ssh);
1921		for (i = 0; i < backadd; i++) {	/* store range list to card */
1922			scanquad = CR_CHAN(chanlist[0]);
1923							/* get channel number */
1924			gain = CR_RANGE(chanlist[0]);	/* get gain number */
1925			scanquad |= ((gain & 0x03) << 8);
1926			outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1927			DPRINTK("%02x ", scanquad | ssh);
1928		}
1929		DPRINTK("\n ");
1930	}
1931#ifdef PCI9118_PARANOIDCHECK
1932	devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
1933						/* for 32bit operations */
1934	if (useeos) {
1935		for (i = 1; i < n_chan; i++) {	/* store range list to card */
1936			devpriv->chanlist[(n_chan + i) ^ usedma] =
1937			    (CR_CHAN(chanlist[i]) & 0xf) << rot;
1938		}
1939		devpriv->chanlist[(2 * n_chan) ^ usedma] =
1940						devpriv->chanlist[0 ^ usedma];
1941						/* for 32bit operations */
1942		useeos = 2;
1943	} else {
1944		useeos = 1;
1945	}
1946#ifdef PCI9118_EXTDEBUG
1947	DPRINTK("CHL: ");
1948	for (i = 0; i <= (useeos * n_chan); i++)
1949		DPRINTK("%04x ", devpriv->chanlist[i]);
1950
1951	DPRINTK("\n ");
1952#endif
1953#endif
1954	outl(0, dev->iobase + PCI9118_SCANMOD);	/* close scan queue */
1955	/* udelay(100); important delay, or first sample will be crippled */
1956
1957	DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
1958	return 1;		/* we can serve this with scan logic */
1959}
1960
1961/*
1962==============================================================================
1963  calculate 8254 divisors if they are used for dual timing
1964*/
1965static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
1966				  struct comedi_subdevice *s,
1967				  unsigned int *tim1, unsigned int *tim2,
1968				  unsigned int flags, int chans,
1969				  unsigned int *div1, unsigned int *div2,
1970				  char usessh, unsigned int chnsshfront)
1971{
1972	DPRINTK
1973	    ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors"
1974					"(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n",
1975	     mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront);
1976	switch (mode) {
1977	case 1:
1978	case 4:
1979		if (*tim2 < this_board->ai_ns_min)
1980			*tim2 = this_board->ai_ns_min;
1981		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
1982					  tim2, flags & TRIG_ROUND_NEAREST);
1983		DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
1984			devpriv->i8254_osc_base, *div1, *div2, *tim1);
1985		break;
1986	case 2:
1987		if (*tim2 < this_board->ai_ns_min)
1988			*tim2 = this_board->ai_ns_min;
1989		DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1990			*tim1, *tim2);
1991		*div1 = *tim2 / devpriv->i8254_osc_base;
1992						/* convert timer (burst) */
1993		DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1994			*tim1, *tim2);
1995		if (*div1 < this_board->ai_pacer_min)
1996			*div1 = this_board->ai_pacer_min;
1997		DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1998			*tim1, *tim2);
1999		*div2 = *tim1 / devpriv->i8254_osc_base;	/* scan timer */
2000		DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2001			*tim1, *tim2);
2002		*div2 = *div2 / *div1;		/* major timer is c1*c2 */
2003		DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2004			*tim1, *tim2);
2005		if (*div2 < chans)
2006			*div2 = chans;
2007		DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2008			*tim1, *tim2);
2009
2010		*tim2 = *div1 * devpriv->i8254_osc_base;
2011							/* real convert timer */
2012
2013		if (usessh & (chnsshfront == 0))	/* use BSSH signal */
2014			if (*div2 < (chans + 2))
2015				*div2 = chans + 2;
2016
2017		DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2018			*tim1, *tim2);
2019		*tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
2020		DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",
2021			devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2);
2022		break;
2023	}
2024	DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
2025		*div1, *div2);
2026}
2027
2028/*
2029==============================================================================
2030*/
2031static void start_pacer(struct comedi_device *dev, int mode,
2032			unsigned int divisor1, unsigned int divisor2)
2033{
2034	outl(0x74, dev->iobase + PCI9118_CNTCTRL);
2035	outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
2036/* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
2037	udelay(1);
2038
2039	if ((mode == 1) || (mode == 2) || (mode == 4)) {
2040		outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
2041		outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
2042		outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
2043		outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
2044	}
2045}
2046
2047/*
2048==============================================================================
2049*/
2050static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
2051{
2052	if (source > 3)
2053		return -1;				/* incorrect source */
2054	devpriv->exttrg_users |= (1 << source);
2055	devpriv->IntControlReg |= Int_DTrg;
2056	outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2057	outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
2058					devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2059							/* allow INT in AMCC */
2060	return 0;
2061}
2062
2063/*
2064==============================================================================
2065*/
2066static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
2067{
2068	if (source > 3)
2069		return -1;			/* incorrect source */
2070	devpriv->exttrg_users &= ~(1 << source);
2071	if (!devpriv->exttrg_users) {	/* shutdown ext trg intterrupts */
2072		devpriv->IntControlReg &= ~Int_DTrg;
2073		if (!devpriv->IntControlReg)	/* all IRQ disabled */
2074			outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) &
2075					(~0x00001f00),
2076					devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2077						/* disable int in AMCC */
2078		outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2079	}
2080	return 0;
2081}
2082
2083/*
2084==============================================================================
2085*/
2086static int pci9118_ai_cancel(struct comedi_device *dev,
2087			     struct comedi_subdevice *s)
2088{
2089	if (devpriv->usedma)
2090		outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) &
2091			(~EN_A2P_TRANSFERS),
2092			devpriv->iobase_a + AMCC_OP_REG_MCSR);	/* stop DMA */
2093	pci9118_exttrg_del(dev, EXTTRG_AI);
2094	start_pacer(dev, 0, 0, 0);	/* stop 8254 counters */
2095	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2096	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2097					/*
2098					 * positive triggers, no S&H, no burst,
2099					 * burst stop, no post trigger,
2100					 * no about trigger, trigger stop
2101					 */
2102	devpriv->AdControlReg = 0x00;
2103	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2104					/*
2105					 * bipolar, S.E., use 8254, stop 8354,
2106					 * internal trigger, soft trigger,
2107					 * disable INT and DMA
2108					 */
2109	outl(0, dev->iobase + PCI9118_BURST);
2110	outl(1, dev->iobase + PCI9118_SCANMOD);
2111	outl(2, dev->iobase + PCI9118_SCANMOD);	/* reset scan queue */
2112	outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
2113
2114	devpriv->ai_do = 0;
2115	devpriv->usedma = 0;
2116
2117	devpriv->ai_act_scan = 0;
2118	devpriv->ai_act_dmapos = 0;
2119	s->async->cur_chan = 0;
2120	s->async->inttrig = NULL;
2121	devpriv->ai_buf_ptr = 0;
2122	devpriv->ai_neverending = 0;
2123	devpriv->dma_actbuf = 0;
2124
2125	if (!devpriv->IntControlReg)
2126		outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
2127					devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2128							/* allow INT in AMCC */
2129
2130	return 0;
2131}
2132
2133/*
2134==============================================================================
2135*/
2136static int pci9118_reset(struct comedi_device *dev)
2137{
2138	devpriv->IntControlReg = 0;
2139	devpriv->exttrg_users = 0;
2140	inl(dev->iobase + PCI9118_INTCTRL);
2141	outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2142						/* disable interrupts source */
2143	outl(0x30, dev->iobase + PCI9118_CNTCTRL);
2144/* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
2145	start_pacer(dev, 0, 0, 0);		/* stop 8254 counters */
2146	devpriv->AdControlReg = 0;
2147	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2148						/*
2149						 * bipolar, S.E., use 8254,
2150						 * stop 8354, internal trigger,
2151						 * soft trigger,
2152						 * disable INT and DMA
2153						 */
2154	outl(0, dev->iobase + PCI9118_BURST);
2155	outl(1, dev->iobase + PCI9118_SCANMOD);
2156	outl(2, dev->iobase + PCI9118_SCANMOD);	/* reset scan queue */
2157	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2158	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2159						/*
2160						 * positive triggers, no S&H,
2161						 * no burst, burst stop,
2162						 * no post trigger,
2163						 * no about trigger,
2164						 * trigger stop
2165						 */
2166
2167	devpriv->ao_data[0] = 2047;
2168	devpriv->ao_data[1] = 2047;
2169	outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1);
2170						/* reset A/D outs to 0V */
2171	outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
2172	outl(0, dev->iobase + PCI9118_DO);	/* reset digi outs to L */
2173	udelay(10);
2174	inl(dev->iobase + PCI9118_AD_DATA);
2175	outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
2176	outl(0, dev->iobase + PCI9118_INTSRC);	/* remove INT requests */
2177	inl(dev->iobase + PCI9118_ADSTAT);	/* flush A/D status register */
2178	inl(dev->iobase + PCI9118_INTSRC);	/* flush INT requests */
2179	devpriv->AdControlReg = 0;
2180	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2181						/*
2182						 * bipolar, S.E., use 8254,
2183						 * stop 8354, internal trigger,
2184						 * soft trigger,
2185						 * disable INT and DMA
2186						 */
2187
2188	devpriv->cnt0_users = 0;
2189	devpriv->exttrg_users = 0;
2190
2191	return 0;
2192}
2193
2194/*
2195==============================================================================
2196*/
2197static int pci9118_attach(struct comedi_device *dev,
2198			  struct comedi_devconfig *it)
2199{
2200	struct comedi_subdevice *s;
2201	int ret, pages, i;
2202	unsigned short master;
2203	unsigned int irq;
2204	unsigned long iobase_a, iobase_9;
2205	struct pci_dev *pcidev;
2206	int opt_bus, opt_slot;
2207	const char *errstr;
2208	unsigned char pci_bus, pci_slot, pci_func;
2209	u16 u16w;
2210
2211	printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name);
2212
2213	opt_bus = it->options[0];
2214	opt_slot = it->options[1];
2215	if (it->options[3] & 1) {
2216		master = 0;	/* user don't want use bus master */
2217	} else {
2218		master = 1;
2219	}
2220
2221	ret = alloc_private(dev, sizeof(struct pci9118_private));
2222	if (ret < 0) {
2223		printk(" - Allocation failed!\n");
2224		return -ENOMEM;
2225	}
2226
2227	/* Look for matching PCI device */
2228	errstr = "not found!";
2229	pcidev = NULL;
2230	while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
2231						this_board->device_id,
2232						pcidev))) {
2233		/* Found matching vendor/device. */
2234		if (opt_bus || opt_slot) {
2235			/* Check bus/slot. */
2236			if (opt_bus != pcidev->bus->number
2237			    || opt_slot != PCI_SLOT(pcidev->devfn))
2238				continue;	/* no match */
2239		}
2240		/*
2241		 * Look for device that isn't in use.
2242		 * Enable PCI device and request regions.
2243		 */
2244		if (comedi_pci_enable(pcidev, "adl_pci9118")) {
2245			errstr =
2246			    "failed to enable PCI device and request regions!";
2247			continue;
2248		}
2249		break;
2250	}
2251
2252	if (!pcidev) {
2253		if (opt_bus || opt_slot) {
2254			printk(KERN_ERR " - Card at b:s %d:%d %s\n",
2255			       opt_bus, opt_slot, errstr);
2256		} else {
2257			printk(KERN_ERR " - Card %s\n", errstr);
2258		}
2259		return -EIO;
2260	}
2261
2262	if (master)
2263		pci_set_master(pcidev);
2264
2265
2266	pci_bus = pcidev->bus->number;
2267	pci_slot = PCI_SLOT(pcidev->devfn);
2268	pci_func = PCI_FUNC(pcidev->devfn);
2269	irq = pcidev->irq;
2270	iobase_a = pci_resource_start(pcidev, 0);
2271	iobase_9 = pci_resource_start(pcidev, 2);
2272
2273	printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus,
2274				pci_slot, pci_func, iobase_9, iobase_a);
2275
2276	dev->iobase = iobase_9;
2277	dev->board_name = this_board->name;
2278
2279	devpriv->pcidev = pcidev;
2280	devpriv->iobase_a = iobase_a;
2281
2282	pci9118_reset(dev);
2283
2284	if (it->options[3] & 2)
2285		irq = 0;	/* user don't want use IRQ */
2286	if (irq > 0) {
2287		if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
2288				"ADLink PCI-9118", dev)) {
2289			printk(", unable to allocate IRQ %d, DISABLING IT",
2290			       irq);
2291			irq = 0;	/* Can't use IRQ */
2292		} else {
2293			printk(", irq=%u", irq);
2294		}
2295	} else {
2296		printk(", IRQ disabled");
2297	}
2298
2299	dev->irq = irq;
2300
2301	if (master) {		/* alloc DMA buffers */
2302		devpriv->dma_doublebuf = 0;
2303		for (i = 0; i < 2; i++) {
2304			for (pages = 4; pages >= 0; pages--) {
2305				devpriv->dmabuf_virt[i] =
2306				    (short *)__get_free_pages(GFP_KERNEL,
2307							      pages);
2308				if (devpriv->dmabuf_virt[i])
2309					break;
2310			}
2311			if (devpriv->dmabuf_virt[i]) {
2312				devpriv->dmabuf_pages[i] = pages;
2313				devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
2314				devpriv->dmabuf_samples[i] =
2315				    devpriv->dmabuf_size[i] >> 1;
2316				devpriv->dmabuf_hw[i] =
2317				    virt_to_bus((void *)
2318						devpriv->dmabuf_virt[i]);
2319			}
2320		}
2321		if (!devpriv->dmabuf_virt[0]) {
2322			printk(", Can't allocate DMA buffer, DMA disabled!");
2323			master = 0;
2324		}
2325
2326		if (devpriv->dmabuf_virt[1])
2327			devpriv->dma_doublebuf = 1;
2328
2329	}
2330
2331	devpriv->master = master;
2332	if (devpriv->master)
2333		printk(", bus master");
2334	else
2335		printk(", no bus master");
2336
2337	devpriv->usemux = 0;
2338	if (it->options[2] > 0) {
2339		devpriv->usemux = it->options[2];
2340		if (devpriv->usemux > 256)
2341			devpriv->usemux = 256;	/* max 256 channels! */
2342		if (it->options[4] > 0)
2343			if (devpriv->usemux > 128) {
2344				devpriv->usemux = 128;
2345					/* max 128 channels with softare S&H! */
2346			}
2347		printk(", ext. mux %d channels", devpriv->usemux);
2348	}
2349
2350	devpriv->softsshdelay = it->options[4];
2351	if (devpriv->softsshdelay < 0) {
2352					/* select sample&hold signal polarity */
2353		devpriv->softsshdelay = -devpriv->softsshdelay;
2354		devpriv->softsshsample = 0x80;
2355		devpriv->softsshhold = 0x00;
2356	} else {
2357		devpriv->softsshsample = 0x00;
2358		devpriv->softsshhold = 0x80;
2359	}
2360
2361	printk(".\n");
2362
2363	pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
2364	pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64);
2365				/* Enable parity check for parity error */
2366
2367	ret = alloc_subdevices(dev, 4);
2368	if (ret < 0)
2369		return ret;
2370
2371	s = dev->subdevices + 0;
2372	dev->read_subdev = s;
2373	s->type = COMEDI_SUBD_AI;
2374	s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2375	if (devpriv->usemux)
2376		s->n_chan = devpriv->usemux;
2377	else
2378		s->n_chan = this_board->n_aichan;
2379
2380	s->maxdata = this_board->ai_maxdata;
2381	s->len_chanlist = this_board->n_aichanlist;
2382	s->range_table = this_board->rangelist_ai;
2383	s->cancel = pci9118_ai_cancel;
2384	s->insn_read = pci9118_insn_read_ai;
2385	if (dev->irq) {
2386		s->subdev_flags |= SDF_CMD_READ;
2387		s->do_cmdtest = pci9118_ai_cmdtest;
2388		s->do_cmd = pci9118_ai_cmd;
2389		s->munge = pci9118_ai_munge;
2390	}
2391
2392	s = dev->subdevices + 1;
2393	s->type = COMEDI_SUBD_AO;
2394	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2395	s->n_chan = this_board->n_aochan;
2396	s->maxdata = this_board->ao_maxdata;
2397	s->len_chanlist = this_board->n_aochan;
2398	s->range_table = this_board->rangelist_ao;
2399	s->insn_write = pci9118_insn_write_ao;
2400	s->insn_read = pci9118_insn_read_ao;
2401
2402	s = dev->subdevices + 2;
2403	s->type = COMEDI_SUBD_DI;
2404	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2405	s->n_chan = 4;
2406	s->maxdata = 1;
2407	s->len_chanlist = 4;
2408	s->range_table = &range_digital;
2409	s->io_bits = 0;		/* all bits input */
2410	s->insn_bits = pci9118_insn_bits_di;
2411
2412	s = dev->subdevices + 3;
2413	s->type = COMEDI_SUBD_DO;
2414	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2415	s->n_chan = 4;
2416	s->maxdata = 1;
2417	s->len_chanlist = 4;
2418	s->range_table = &range_digital;
2419	s->io_bits = 0xf;	/* all bits output */
2420	s->insn_bits = pci9118_insn_bits_do;
2421
2422	devpriv->valid = 1;
2423	devpriv->i8254_osc_base = 250;	/* 250ns=4MHz */
2424	devpriv->ai_maskharderr = 0x10a;
2425					/* default measure crash condition */
2426	if (it->options[5])		/* disable some requested */
2427		devpriv->ai_maskharderr &= ~it->options[5];
2428
2429	switch (this_board->ai_maxdata) {
2430	case 0xffff:
2431		devpriv->ai16bits = 1;
2432		break;
2433	default:
2434		devpriv->ai16bits = 0;
2435		break;
2436	}
2437	return 0;
2438}
2439
2440/*
2441==============================================================================
2442*/
2443static int pci9118_detach(struct comedi_device *dev)
2444{
2445	if (dev->private) {
2446		if (devpriv->valid)
2447			pci9118_reset(dev);
2448		if (dev->irq)
2449			free_irq(dev->irq, dev);
2450		if (devpriv->pcidev) {
2451			if (dev->iobase)
2452				comedi_pci_disable(devpriv->pcidev);
2453
2454			pci_dev_put(devpriv->pcidev);
2455		}
2456		if (devpriv->dmabuf_virt[0])
2457			free_pages((unsigned long)devpriv->dmabuf_virt[0],
2458				   devpriv->dmabuf_pages[0]);
2459		if (devpriv->dmabuf_virt[1])
2460			free_pages((unsigned long)devpriv->dmabuf_virt[1],
2461				   devpriv->dmabuf_pages[1]);
2462	}
2463
2464	return 0;
2465}
2466
2467/*
2468==============================================================================
2469*/
2470
2471MODULE_AUTHOR("Comedi http://www.comedi.org");
2472MODULE_DESCRIPTION("Comedi low-level driver");
2473MODULE_LICENSE("GPL");
2474