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