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