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