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