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