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