adl_pci9118.c revision 845d131e2b363717d8ac8db2c6b4417de8cf10b5
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 necessary 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#include <linux/io.h>
71
72#include "amcc_s5933.h"
73#include "8253.h"
74#include "comedi_pci.h"
75#include "comedi_fc.h"
76
77#define PCI_VENDOR_ID_AMCC	0x10e8
78
79/* paranoid checks are broken */
80#undef PCI9118_PARANOIDCHECK	/*
81				 * if defined, then is used code which control
82				 * correct channel number on every 12 bit sample
83				 */
84
85#undef PCI9118_EXTDEBUG		/*
86				 * if defined then driver prints
87				 * a lot of messages
88				 */
89
90#undef DPRINTK
91#ifdef PCI9118_EXTDEBUG
92#define DPRINTK(fmt, args...) printk(fmt, ## args)
93#else
94#define DPRINTK(fmt, args...)
95#endif
96
97#define IORANGE_9118 	64	/* I hope */
98#define PCI9118_CHANLEN	255	/*
99				 * len of chanlist, some source say 256,
100				 * but reality looks like 255 :-(
101				 */
102
103#define PCI9118_CNT0	0x00	/* R/W: 8254 counter 0 */
104#define PCI9118_CNT1	0x04	/* R/W: 8254 counter 0 */
105#define PCI9118_CNT2	0x08	/* R/W: 8254 counter 0 */
106#define PCI9118_CNTCTRL	0x0c	/* W:   8254 counter control */
107#define PCI9118_AD_DATA	0x10	/* R:   A/D data */
108#define PCI9118_DA1	0x10	/* W:   D/A registers */
109#define PCI9118_DA2	0x14
110#define PCI9118_ADSTAT	0x18	/* R:   A/D status register */
111#define PCI9118_ADCNTRL	0x18	/* W:   A/D control register */
112#define PCI9118_DI	0x1c	/* R:   digi input register */
113#define PCI9118_DO	0x1c	/* W:   digi output register */
114#define PCI9118_SOFTTRG	0x20	/* W:   soft trigger for A/D */
115#define PCI9118_GAIN	0x24	/* W:   A/D gain/channel register */
116#define PCI9118_BURST	0x28	/* W:   A/D burst number register */
117#define PCI9118_SCANMOD	0x2c	/* W:   A/D auto scan mode */
118#define PCI9118_ADFUNC	0x30	/* W:   A/D function register */
119#define PCI9118_DELFIFO	0x34	/* W:   A/D data FIFO reset */
120#define PCI9118_INTSRC	0x38	/* R:   interrupt reason register */
121#define PCI9118_INTCTRL	0x38	/* W:   interrupt control register */
122
123/* bits from A/D control register (PCI9118_ADCNTRL) */
124#define AdControl_UniP	0x80	/* 1=bipolar, 0=unipolar */
125#define AdControl_Diff	0x40	/* 1=differential, 0= single end inputs */
126#define AdControl_SoftG	0x20	/* 1=8254 counter works, 0=counter stops */
127#define	AdControl_ExtG	0x10	/*
128				 * 1=8254 countrol controlled by TGIN(pin 46),
129				 * 0=controlled by SoftG
130				 */
131#define AdControl_ExtM	0x08	/*
132				 * 1=external hardware trigger (pin 44),
133				 * 0=internal trigger
134				 */
135#define AdControl_TmrTr	0x04	/*
136				 * 1=8254 is iternal trigger source,
137				 * 0=software trigger is source
138				 * (register PCI9118_SOFTTRG)
139				 */
140#define AdControl_Int	0x02	/* 1=enable INT, 0=disable */
141#define AdControl_Dma	0x01	/* 1=enable DMA, 0=disable */
142
143/* bits from A/D function register (PCI9118_ADFUNC) */
144#define AdFunction_PDTrg	0x80	/*
145					 * 1=positive,
146					 * 0=negative digital trigger
147					 * (only positive is correct)
148					 */
149#define AdFunction_PETrg	0x40	/*
150					 * 1=positive,
151					 * 0=negative external trigger
152					 * (only positive is correct)
153					 */
154#define AdFunction_BSSH		0x20	/* 1=with sample&hold, 0=without */
155#define AdFunction_BM		0x10	/* 1=burst mode, 0=normal mode */
156#define AdFunction_BS		0x08	/*
157					 * 1=burst mode start,
158					 * 0=burst mode stop
159					 */
160#define AdFunction_PM		0x04	/*
161					 * 1=post trigger mode,
162					 * 0=not post trigger
163					 */
164#define AdFunction_AM		0x02	/*
165					 * 1=about trigger mode,
166					 * 0=not about trigger
167					 */
168#define AdFunction_Start	0x01	/* 1=trigger start, 0=trigger stop */
169
170/* bits from A/D status register (PCI9118_ADSTAT) */
171#define AdStatus_nFull	0x100	/* 0=FIFO full (fatal), 1=not full */
172#define AdStatus_nHfull	0x080	/* 0=FIFO half full, 1=FIFO not half full */
173#define AdStatus_nEpty	0x040	/* 0=FIFO empty, 1=FIFO not empty */
174#define AdStatus_Acmp	0x020	/*  */
175#define AdStatus_DTH	0x010	/* 1=external digital trigger */
176#define AdStatus_Bover	0x008	/* 1=burst mode overrun (fatal) */
177#define AdStatus_ADOS	0x004	/* 1=A/D over speed (warning) */
178#define AdStatus_ADOR	0x002	/* 1=A/D overrun (fatal) */
179#define AdStatus_ADrdy	0x001	/* 1=A/D already ready, 0=not ready */
180
181/* bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL) */
182/* 1=interrupt occur, enable source,  0=interrupt not occur, disable source */
183#define Int_Timer	0x08	/* timer interrupt */
184#define Int_About	0x04	/* about trigger complete */
185#define Int_Hfull	0x02	/* A/D FIFO hlaf full */
186#define Int_DTrg	0x01	/* external digital trigger */
187
188#define START_AI_EXT	0x01	/* start measure on external trigger */
189#define STOP_AI_EXT	0x02	/* stop measure on external trigger */
190#define START_AI_INT	0x04	/* start measure on internal trigger */
191#define STOP_AI_INT	0x08	/* stop measure on internal trigger */
192
193#define EXTTRG_AI	0	/* ext trg is used by AI */
194
195static const struct comedi_lrange range_pci9118dg_hr = { 8, {
196							     BIP_RANGE(5),
197							     BIP_RANGE(2.5),
198							     BIP_RANGE(1.25),
199							     BIP_RANGE(0.625),
200							     UNI_RANGE(10),
201							     UNI_RANGE(5),
202							     UNI_RANGE(2.5),
203							     UNI_RANGE(1.25)
204							     }
205};
206
207static const struct comedi_lrange range_pci9118hg = { 8, {
208							  BIP_RANGE(5),
209							  BIP_RANGE(0.5),
210							  BIP_RANGE(0.05),
211							  BIP_RANGE(0.005),
212							  UNI_RANGE(10),
213							  UNI_RANGE(1),
214							  UNI_RANGE(0.1),
215							  UNI_RANGE(0.01)
216							  }
217};
218
219#define PCI9118_BIPOLAR_RANGES	4	/*
220					 * used for test on mixture
221					 * of BIP/UNI ranges
222					 */
223
224static int pci9118_attach(struct comedi_device *dev,
225			  struct comedi_devconfig *it);
226static int pci9118_detach(struct comedi_device *dev);
227
228struct boardtype {
229	const char *name;		/* board name */
230	int vendor_id;			/* PCI vendor a device ID of card */
231	int device_id;
232	int iorange_amcc;		/* iorange for own S5933 region */
233	int iorange_9118;		/* pass thru card region size */
234	int n_aichan;			/* num of A/D chans */
235	int n_aichand;			/* num of A/D chans in diff mode */
236	int mux_aichan;			/*
237					 * num of A/D chans with
238					 * external multiplexor
239					 */
240	int n_aichanlist;		/* len of chanlist */
241	int n_aochan;			/* num of D/A chans */
242	int ai_maxdata;			/* resolution of A/D */
243	int ao_maxdata;			/* resolution of D/A */
244	const struct comedi_lrange *rangelist_ai;	/* rangelist for A/D */
245	const struct comedi_lrange *rangelist_ao;	/* rangelist for D/A */
246	unsigned int ai_ns_min;		/* max sample speed of card v ns */
247	unsigned int ai_pacer_min;	/*
248					 * minimal pacer value
249					 * (c1*c2 or c1 in burst)
250					 */
251	int half_fifo_size;		/* size of FIFO/2 */
252
253};
254
255static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
256	{ PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) },
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 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 transferred */
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 align 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			if (cmd->convert_src == TRIG_TIMER) {
1604				devpriv->usedma = 0;
1605					/*
1606					 * use INT transfer if scanlist
1607					 * have only one channel
1608					 */
1609			}
1610		}
1611		if ((cmd->flags & TRIG_WAKE_EOS) &&
1612		    (devpriv->ai_n_scanlen & 1) &&
1613		    (devpriv->ai_n_scanlen > 1)) {
1614			if (cmd->scan_begin_src == TRIG_FOLLOW) {
1615				/*
1616				 * vpriv->useeoshandle=1; // change DMA transfer
1617				 * block to fit EOS on every second call
1618				 */
1619				devpriv->usedma = 0;
1620				/*
1621				 * XXX maybe can be corrected to use 16 bit DMA
1622				 */
1623			} else {	/*
1624					 * well, we must insert one sample
1625					 * to end of EOS to meet 32 bit transfer
1626					 */
1627				devpriv->ai_add_back = 1;
1628			}
1629		}
1630	} else {	/* interrupt transfer don't need any correction */
1631		devpriv->usedma = 0;
1632	}
1633
1634	/*
1635	 * we need software S&H signal?
1636	 * It adds two samples before every scan as minimum
1637	 */
1638	if (devpriv->usessh && devpriv->softsshdelay) {
1639		devpriv->ai_add_front = 2;
1640		if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
1641							/* move it to front */
1642			devpriv->ai_add_front++;
1643			devpriv->ai_add_back = 0;
1644		}
1645		if (cmd->convert_arg < this_board->ai_ns_min)
1646			cmd->convert_arg = this_board->ai_ns_min;
1647		addchans = devpriv->softsshdelay / cmd->convert_arg;
1648		if (devpriv->softsshdelay % cmd->convert_arg)
1649			addchans++;
1650		if (addchans > (devpriv->ai_add_front - 1)) {
1651							/* uff, still short */
1652			devpriv->ai_add_front = addchans + 1;
1653			if (devpriv->usedma == 1)
1654				if ((devpriv->ai_add_front +
1655				     devpriv->ai_n_chan +
1656				     devpriv->ai_add_back) & 1)
1657					devpriv->ai_add_front++;
1658							/* round up to 32 bit */
1659		}
1660	}
1661	/* well, we now know what must be all added */
1662	devpriv->ai_n_realscanlen =	/*
1663					 * what we must take from card in real
1664					 * to have ai_n_scanlen on output?
1665					 */
1666	    (devpriv->ai_add_front + devpriv->ai_n_chan +
1667	     devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
1668				      devpriv->ai_n_chan);
1669
1670	DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
1671		devpriv->usedma,
1672		devpriv->ai_n_realscanlen, devpriv->ai_add_front,
1673		devpriv->ai_n_chan, devpriv->ai_add_back,
1674		devpriv->ai_n_scanlen);
1675
1676	/* check and setup channel list */
1677	if (!check_channel_list(dev, s, devpriv->ai_n_chan,
1678				devpriv->ai_chanlist, devpriv->ai_add_front,
1679				devpriv->ai_add_back))
1680		return -EINVAL;
1681	if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
1682				devpriv->ai_chanlist, 0, devpriv->ai_add_front,
1683				devpriv->ai_add_back, devpriv->usedma,
1684				devpriv->useeoshandle))
1685		return -EINVAL;
1686
1687	/* compute timers settings */
1688	/*
1689	 * simplest way, fr=4Mhz/(tim1*tim2),
1690	 * channel manipulation without timers effect
1691	 */
1692	if (((cmd->scan_begin_src == TRIG_FOLLOW) ||
1693		(cmd->scan_begin_src == TRIG_EXT) ||
1694		(cmd->scan_begin_src == TRIG_INT)) &&
1695		(cmd->convert_src == TRIG_TIMER)) {
1696					/* both timer is used for one time */
1697		if (cmd->scan_begin_src == TRIG_EXT)
1698			devpriv->ai_do = 4;
1699		else
1700			devpriv->ai_do = 1;
1701		pci9118_calc_divisors(devpriv->ai_do, dev, s,
1702				      &cmd->scan_begin_arg, &cmd->convert_arg,
1703				      devpriv->ai_flags,
1704				      devpriv->ai_n_realscanlen,
1705				      &devpriv->ai_divisor1,
1706				      &devpriv->ai_divisor2, devpriv->usessh,
1707				      devpriv->ai_add_front);
1708		devpriv->ai_timer2 = cmd->convert_arg;
1709	}
1710
1711	if ((cmd->scan_begin_src == TRIG_TIMER) &&
1712		((cmd->convert_src == TRIG_TIMER) ||
1713		(cmd->convert_src == TRIG_NOW))) {
1714						/* double timed action */
1715		if (!devpriv->usedma) {
1716			comedi_error(dev,
1717				     "cmd->scan_begin_src=TRIG_TIMER works "
1718						"only with bus mastering!");
1719			return -EIO;
1720		}
1721
1722		devpriv->ai_do = 2;
1723		pci9118_calc_divisors(devpriv->ai_do, dev, s,
1724				      &cmd->scan_begin_arg, &cmd->convert_arg,
1725				      devpriv->ai_flags,
1726				      devpriv->ai_n_realscanlen,
1727				      &devpriv->ai_divisor1,
1728				      &devpriv->ai_divisor2, devpriv->usessh,
1729				      devpriv->ai_add_front);
1730		devpriv->ai_timer1 = cmd->scan_begin_arg;
1731		devpriv->ai_timer2 = cmd->convert_arg;
1732	}
1733
1734	if ((cmd->scan_begin_src == TRIG_FOLLOW)
1735	    && (cmd->convert_src == TRIG_EXT)) {
1736		devpriv->ai_do = 3;
1737	}
1738
1739	start_pacer(dev, -1, 0, 0);	/* stop pacer */
1740
1741	devpriv->AdControlReg = 0;	/*
1742					 * bipolar, S.E., use 8254, stop 8354,
1743					 * internal trigger, soft trigger,
1744					 * disable DMA
1745					 */
1746	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1747	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1748					/*
1749					 * positive triggers, no S&H, no burst,
1750					 * burst stop, no post trigger,
1751					 * no about trigger, trigger stop
1752					 */
1753	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1754	udelay(1);
1755	outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
1756	inl(dev->iobase + PCI9118_ADSTAT);	/*
1757						 * flush A/D and INT
1758						 * status register
1759						 */
1760	inl(dev->iobase + PCI9118_INTSRC);
1761
1762	devpriv->ai_act_scan = 0;
1763	devpriv->ai_act_dmapos = 0;
1764	s->async->cur_chan = 0;
1765	devpriv->ai_buf_ptr = 0;
1766
1767	if (devpriv->usedma)
1768		ret = pci9118_ai_docmd_dma(dev, s);
1769	else
1770		ret = pci9118_ai_docmd_sampl(dev, s);
1771
1772	DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
1773	return ret;
1774}
1775
1776/*
1777==============================================================================
1778*/
1779static int check_channel_list(struct comedi_device *dev,
1780			      struct comedi_subdevice *s, int n_chan,
1781			      unsigned int *chanlist, int frontadd, int backadd)
1782{
1783	unsigned int i, differencial = 0, bipolar = 0;
1784
1785	/* correct channel and range number check itself comedi/range.c */
1786	if (n_chan < 1) {
1787		comedi_error(dev, "range/channel list is empty!");
1788		return 0;
1789	}
1790	if ((frontadd + n_chan + backadd) > s->len_chanlist) {
1791		printk
1792		    ("comedi%d: range/channel list is too long for "
1793						"actual configuration (%d>%d)!",
1794		     dev->minor, n_chan, s->len_chanlist - frontadd - backadd);
1795		return 0;
1796	}
1797
1798	if (CR_AREF(chanlist[0]) == AREF_DIFF)
1799		differencial = 1;	/* all input must be diff */
1800	if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1801		bipolar = 1;	/* all input must be bipolar */
1802	if (n_chan > 1)
1803		for (i = 1; i < n_chan; i++) {	/* check S.E/diff */
1804			if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
1805			    (differencial)) {
1806				comedi_error(dev,
1807					     "Differencial and single ended "
1808						"inputs can't be mixtured!");
1809				return 0;
1810			}
1811			if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
1812			    (bipolar)) {
1813				comedi_error(dev,
1814					     "Bipolar and unipolar ranges "
1815							"can't be mixtured!");
1816				return 0;
1817			}
1818			if ((!devpriv->usemux) & (differencial) &
1819			    (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
1820				comedi_error(dev,
1821					     "If AREF_DIFF is used then is "
1822					"available only first 8 channels!");
1823				return 0;
1824			}
1825		}
1826
1827	return 1;
1828}
1829
1830/*
1831==============================================================================
1832*/
1833static int setup_channel_list(struct comedi_device *dev,
1834			      struct comedi_subdevice *s, int n_chan,
1835			      unsigned int *chanlist, int rot, int frontadd,
1836			      int backadd, int usedma, char useeos)
1837{
1838	unsigned int i, differencial = 0, bipolar = 0;
1839	unsigned int scanquad, gain, ssh = 0x00;
1840
1841	DPRINTK
1842	    ("adl_pci9118 EDBG: BGN: setup_channel_list"
1843						"(%d,.,%d,.,%d,%d,%d,%d)\n",
1844	     dev->minor, n_chan, rot, frontadd, backadd, usedma);
1845
1846	if (usedma == 1) {
1847		rot = 8;
1848		usedma = 0;
1849	}
1850
1851	if (CR_AREF(chanlist[0]) == AREF_DIFF)
1852		differencial = 1;	/* all input must be diff */
1853	if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1854		bipolar = 1;	/* all input must be bipolar */
1855
1856	/* All is ok, so we can setup channel/range list */
1857
1858	if (!bipolar) {
1859		devpriv->AdControlReg |= AdControl_UniP;
1860							/* set unibipolar */
1861	} else {
1862		devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
1863							/* enable bipolar */
1864	}
1865
1866	if (differencial) {
1867		devpriv->AdControlReg |= AdControl_Diff;
1868							/* enable diff inputs */
1869	} else {
1870		devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
1871						/* set single ended inputs */
1872	}
1873
1874	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1875								/* setup mode */
1876
1877	outl(2, dev->iobase + PCI9118_SCANMOD);
1878					/* gods know why this sequence! */
1879	outl(0, dev->iobase + PCI9118_SCANMOD);
1880	outl(1, dev->iobase + PCI9118_SCANMOD);
1881
1882#ifdef PCI9118_PARANOIDCHECK
1883	devpriv->chanlistlen = n_chan;
1884	for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
1885		devpriv->chanlist[i] = 0x55aa;
1886#endif
1887
1888	if (frontadd) {		/* insert channels for S&H */
1889		ssh = devpriv->softsshsample;
1890		DPRINTK("FA: %04x: ", ssh);
1891		for (i = 0; i < frontadd; i++) {
1892						/* store range list to card */
1893			scanquad = CR_CHAN(chanlist[0]);
1894						/* get channel number; */
1895			gain = CR_RANGE(chanlist[0]);
1896						/* get gain number */
1897			scanquad |= ((gain & 0x03) << 8);
1898			outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1899			DPRINTK("%02x ", scanquad | ssh);
1900			ssh = devpriv->softsshhold;
1901		}
1902		DPRINTK("\n ");
1903	}
1904
1905	DPRINTK("SL: ", ssh);
1906	for (i = 0; i < n_chan; i++) {	/* store range list to card */
1907		scanquad = CR_CHAN(chanlist[i]);	/* get channel number */
1908#ifdef PCI9118_PARANOIDCHECK
1909		devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
1910#endif
1911		gain = CR_RANGE(chanlist[i]);		/* get gain number */
1912		scanquad |= ((gain & 0x03) << 8);
1913		outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1914		DPRINTK("%02x ", scanquad | ssh);
1915	}
1916	DPRINTK("\n ");
1917
1918	if (backadd) {		/* insert channels for fit onto 32bit DMA */
1919		DPRINTK("BA: %04x: ", ssh);
1920		for (i = 0; i < backadd; i++) {	/* store range list to card */
1921			scanquad = CR_CHAN(chanlist[0]);
1922							/* get channel number */
1923			gain = CR_RANGE(chanlist[0]);	/* get gain number */
1924			scanquad |= ((gain & 0x03) << 8);
1925			outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1926			DPRINTK("%02x ", scanquad | ssh);
1927		}
1928		DPRINTK("\n ");
1929	}
1930#ifdef PCI9118_PARANOIDCHECK
1931	devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
1932						/* for 32bit operations */
1933	if (useeos) {
1934		for (i = 1; i < n_chan; i++) {	/* store range list to card */
1935			devpriv->chanlist[(n_chan + i) ^ usedma] =
1936			    (CR_CHAN(chanlist[i]) & 0xf) << rot;
1937		}
1938		devpriv->chanlist[(2 * n_chan) ^ usedma] =
1939						devpriv->chanlist[0 ^ usedma];
1940						/* for 32bit operations */
1941		useeos = 2;
1942	} else {
1943		useeos = 1;
1944	}
1945#ifdef PCI9118_EXTDEBUG
1946	DPRINTK("CHL: ");
1947	for (i = 0; i <= (useeos * n_chan); i++)
1948		DPRINTK("%04x ", devpriv->chanlist[i]);
1949
1950	DPRINTK("\n ");
1951#endif
1952#endif
1953	outl(0, dev->iobase + PCI9118_SCANMOD);	/* close scan queue */
1954	/* udelay(100); important delay, or first sample will be crippled */
1955
1956	DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
1957	return 1;		/* we can serve this with scan logic */
1958}
1959
1960/*
1961==============================================================================
1962  calculate 8254 divisors if they are used for dual timing
1963*/
1964static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
1965				  struct comedi_subdevice *s,
1966				  unsigned int *tim1, unsigned int *tim2,
1967				  unsigned int flags, int chans,
1968				  unsigned int *div1, unsigned int *div2,
1969				  char usessh, unsigned int chnsshfront)
1970{
1971	DPRINTK
1972	    ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors"
1973					"(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n",
1974	     mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront);
1975	switch (mode) {
1976	case 1:
1977	case 4:
1978		if (*tim2 < this_board->ai_ns_min)
1979			*tim2 = this_board->ai_ns_min;
1980		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
1981					  tim2, flags & TRIG_ROUND_NEAREST);
1982		DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
1983			devpriv->i8254_osc_base, *div1, *div2, *tim1);
1984		break;
1985	case 2:
1986		if (*tim2 < this_board->ai_ns_min)
1987			*tim2 = this_board->ai_ns_min;
1988		DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1989			*tim1, *tim2);
1990		*div1 = *tim2 / devpriv->i8254_osc_base;
1991						/* convert timer (burst) */
1992		DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1993			*tim1, *tim2);
1994		if (*div1 < this_board->ai_pacer_min)
1995			*div1 = this_board->ai_pacer_min;
1996		DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1997			*tim1, *tim2);
1998		*div2 = *tim1 / devpriv->i8254_osc_base;	/* scan timer */
1999		DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2000			*tim1, *tim2);
2001		*div2 = *div2 / *div1;		/* major timer is c1*c2 */
2002		DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2003			*tim1, *tim2);
2004		if (*div2 < chans)
2005			*div2 = chans;
2006		DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2007			*tim1, *tim2);
2008
2009		*tim2 = *div1 * devpriv->i8254_osc_base;
2010							/* real convert timer */
2011
2012		if (usessh & (chnsshfront == 0))	/* use BSSH signal */
2013			if (*div2 < (chans + 2))
2014				*div2 = chans + 2;
2015
2016		DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
2017			*tim1, *tim2);
2018		*tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
2019		DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",
2020			devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2);
2021		break;
2022	}
2023	DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
2024		*div1, *div2);
2025}
2026
2027/*
2028==============================================================================
2029*/
2030static void start_pacer(struct comedi_device *dev, int mode,
2031			unsigned int divisor1, unsigned int divisor2)
2032{
2033	outl(0x74, dev->iobase + PCI9118_CNTCTRL);
2034	outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
2035/* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
2036	udelay(1);
2037
2038	if ((mode == 1) || (mode == 2) || (mode == 4)) {
2039		outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
2040		outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
2041		outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
2042		outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
2043	}
2044}
2045
2046/*
2047==============================================================================
2048*/
2049static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
2050{
2051	if (source > 3)
2052		return -1;				/* incorrect source */
2053	devpriv->exttrg_users |= (1 << source);
2054	devpriv->IntControlReg |= Int_DTrg;
2055	outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2056	outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
2057					devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2058							/* allow INT in AMCC */
2059	return 0;
2060}
2061
2062/*
2063==============================================================================
2064*/
2065static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
2066{
2067	if (source > 3)
2068		return -1;			/* incorrect source */
2069	devpriv->exttrg_users &= ~(1 << source);
2070	if (!devpriv->exttrg_users) {	/* shutdown ext trg intterrupts */
2071		devpriv->IntControlReg &= ~Int_DTrg;
2072		if (!devpriv->IntControlReg)	/* all IRQ disabled */
2073			outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) &
2074					(~0x00001f00),
2075					devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2076						/* disable int in AMCC */
2077		outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2078	}
2079	return 0;
2080}
2081
2082/*
2083==============================================================================
2084*/
2085static int pci9118_ai_cancel(struct comedi_device *dev,
2086			     struct comedi_subdevice *s)
2087{
2088	if (devpriv->usedma)
2089		outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) &
2090			(~EN_A2P_TRANSFERS),
2091			devpriv->iobase_a + AMCC_OP_REG_MCSR);	/* stop DMA */
2092	pci9118_exttrg_del(dev, EXTTRG_AI);
2093	start_pacer(dev, 0, 0, 0);	/* stop 8254 counters */
2094	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2095	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2096					/*
2097					 * positive triggers, no S&H, no burst,
2098					 * burst stop, no post trigger,
2099					 * no about trigger, trigger stop
2100					 */
2101	devpriv->AdControlReg = 0x00;
2102	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2103					/*
2104					 * bipolar, S.E., use 8254, stop 8354,
2105					 * internal trigger, soft trigger,
2106					 * disable INT and DMA
2107					 */
2108	outl(0, dev->iobase + PCI9118_BURST);
2109	outl(1, dev->iobase + PCI9118_SCANMOD);
2110	outl(2, dev->iobase + PCI9118_SCANMOD);	/* reset scan queue */
2111	outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
2112
2113	devpriv->ai_do = 0;
2114	devpriv->usedma = 0;
2115
2116	devpriv->ai_act_scan = 0;
2117	devpriv->ai_act_dmapos = 0;
2118	s->async->cur_chan = 0;
2119	s->async->inttrig = NULL;
2120	devpriv->ai_buf_ptr = 0;
2121	devpriv->ai_neverending = 0;
2122	devpriv->dma_actbuf = 0;
2123
2124	if (!devpriv->IntControlReg)
2125		outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
2126					devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2127							/* allow INT in AMCC */
2128
2129	return 0;
2130}
2131
2132/*
2133==============================================================================
2134*/
2135static int pci9118_reset(struct comedi_device *dev)
2136{
2137	devpriv->IntControlReg = 0;
2138	devpriv->exttrg_users = 0;
2139	inl(dev->iobase + PCI9118_INTCTRL);
2140	outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2141						/* disable interrupts source */
2142	outl(0x30, dev->iobase + PCI9118_CNTCTRL);
2143/* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
2144	start_pacer(dev, 0, 0, 0);		/* stop 8254 counters */
2145	devpriv->AdControlReg = 0;
2146	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2147						/*
2148						 * bipolar, S.E., use 8254,
2149						 * stop 8354, internal trigger,
2150						 * soft trigger,
2151						 * disable INT and DMA
2152						 */
2153	outl(0, dev->iobase + PCI9118_BURST);
2154	outl(1, dev->iobase + PCI9118_SCANMOD);
2155	outl(2, dev->iobase + PCI9118_SCANMOD);	/* reset scan queue */
2156	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2157	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2158						/*
2159						 * positive triggers, no S&H,
2160						 * no burst, burst stop,
2161						 * no post trigger,
2162						 * no about trigger,
2163						 * trigger stop
2164						 */
2165
2166	devpriv->ao_data[0] = 2047;
2167	devpriv->ao_data[1] = 2047;
2168	outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1);
2169						/* reset A/D outs to 0V */
2170	outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
2171	outl(0, dev->iobase + PCI9118_DO);	/* reset digi outs to L */
2172	udelay(10);
2173	inl(dev->iobase + PCI9118_AD_DATA);
2174	outl(0, dev->iobase + PCI9118_DELFIFO);	/* flush FIFO */
2175	outl(0, dev->iobase + PCI9118_INTSRC);	/* remove INT requests */
2176	inl(dev->iobase + PCI9118_ADSTAT);	/* flush A/D status register */
2177	inl(dev->iobase + PCI9118_INTSRC);	/* flush INT requests */
2178	devpriv->AdControlReg = 0;
2179	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2180						/*
2181						 * bipolar, S.E., use 8254,
2182						 * stop 8354, internal trigger,
2183						 * soft trigger,
2184						 * disable INT and DMA
2185						 */
2186
2187	devpriv->cnt0_users = 0;
2188	devpriv->exttrg_users = 0;
2189
2190	return 0;
2191}
2192
2193/*
2194==============================================================================
2195*/
2196static int pci9118_attach(struct comedi_device *dev,
2197			  struct comedi_devconfig *it)
2198{
2199	struct comedi_subdevice *s;
2200	int ret, pages, i;
2201	unsigned short master;
2202	unsigned int irq;
2203	unsigned long iobase_a, iobase_9;
2204	struct pci_dev *pcidev;
2205	int opt_bus, opt_slot;
2206	const char *errstr;
2207	unsigned char pci_bus, pci_slot, pci_func;
2208	u16 u16w;
2209
2210	printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name);
2211
2212	opt_bus = it->options[0];
2213	opt_slot = it->options[1];
2214	if (it->options[3] & 1)
2215		master = 0;	/* user don't want use bus master */
2216	else
2217		master = 1;
2218
2219	ret = alloc_private(dev, sizeof(struct pci9118_private));
2220	if (ret < 0) {
2221		printk(" - Allocation failed!\n");
2222		return -ENOMEM;
2223	}
2224
2225	/* Look for matching PCI device */
2226	errstr = "not found!";
2227	pcidev = NULL;
2228	while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
2229						this_board->device_id,
2230						pcidev))) {
2231		/* Found matching vendor/device. */
2232		if (opt_bus || opt_slot) {
2233			/* Check bus/slot. */
2234			if (opt_bus != pcidev->bus->number
2235			    || opt_slot != PCI_SLOT(pcidev->devfn))
2236				continue;	/* no match */
2237		}
2238		/*
2239		 * Look for device that isn't in use.
2240		 * Enable PCI device and request regions.
2241		 */
2242		if (comedi_pci_enable(pcidev, "adl_pci9118")) {
2243			errstr =
2244			    "failed to enable PCI device and request regions!";
2245			continue;
2246		}
2247		break;
2248	}
2249
2250	if (!pcidev) {
2251		if (opt_bus || opt_slot) {
2252			printk(KERN_ERR " - Card at b:s %d:%d %s\n",
2253			       opt_bus, opt_slot, errstr);
2254		} else {
2255			printk(KERN_ERR " - Card %s\n", errstr);
2256		}
2257		return -EIO;
2258	}
2259
2260	if (master)
2261		pci_set_master(pcidev);
2262
2263
2264	pci_bus = pcidev->bus->number;
2265	pci_slot = PCI_SLOT(pcidev->devfn);
2266	pci_func = PCI_FUNC(pcidev->devfn);
2267	irq = pcidev->irq;
2268	iobase_a = pci_resource_start(pcidev, 0);
2269	iobase_9 = pci_resource_start(pcidev, 2);
2270
2271	printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus,
2272				pci_slot, pci_func, iobase_9, iobase_a);
2273
2274	dev->iobase = iobase_9;
2275	dev->board_name = this_board->name;
2276
2277	devpriv->pcidev = pcidev;
2278	devpriv->iobase_a = iobase_a;
2279
2280	pci9118_reset(dev);
2281
2282	if (it->options[3] & 2)
2283		irq = 0;	/* user don't want use IRQ */
2284	if (irq > 0) {
2285		if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
2286				"ADLink PCI-9118", dev)) {
2287			printk(", unable to allocate IRQ %d, DISABLING IT",
2288			       irq);
2289			irq = 0;	/* Can't use IRQ */
2290		} else {
2291			printk(", irq=%u", irq);
2292		}
2293	} else {
2294		printk(", IRQ disabled");
2295	}
2296
2297	dev->irq = irq;
2298
2299	if (master) {		/* alloc DMA buffers */
2300		devpriv->dma_doublebuf = 0;
2301		for (i = 0; i < 2; i++) {
2302			for (pages = 4; pages >= 0; pages--) {
2303				devpriv->dmabuf_virt[i] =
2304				    (short *)__get_free_pages(GFP_KERNEL,
2305							      pages);
2306				if (devpriv->dmabuf_virt[i])
2307					break;
2308			}
2309			if (devpriv->dmabuf_virt[i]) {
2310				devpriv->dmabuf_pages[i] = pages;
2311				devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
2312				devpriv->dmabuf_samples[i] =
2313				    devpriv->dmabuf_size[i] >> 1;
2314				devpriv->dmabuf_hw[i] =
2315				    virt_to_bus((void *)
2316						devpriv->dmabuf_virt[i]);
2317			}
2318		}
2319		if (!devpriv->dmabuf_virt[0]) {
2320			printk(", Can't allocate DMA buffer, DMA disabled!");
2321			master = 0;
2322		}
2323
2324		if (devpriv->dmabuf_virt[1])
2325			devpriv->dma_doublebuf = 1;
2326
2327	}
2328
2329	devpriv->master = master;
2330	if (devpriv->master)
2331		printk(", bus master");
2332	else
2333		printk(", no bus master");
2334
2335	devpriv->usemux = 0;
2336	if (it->options[2] > 0) {
2337		devpriv->usemux = it->options[2];
2338		if (devpriv->usemux > 256)
2339			devpriv->usemux = 256;	/* max 256 channels! */
2340		if (it->options[4] > 0)
2341			if (devpriv->usemux > 128) {
2342				devpriv->usemux = 128;
2343					/* max 128 channels with softare S&H! */
2344			}
2345		printk(", ext. mux %d channels", devpriv->usemux);
2346	}
2347
2348	devpriv->softsshdelay = it->options[4];
2349	if (devpriv->softsshdelay < 0) {
2350					/* select sample&hold signal polarity */
2351		devpriv->softsshdelay = -devpriv->softsshdelay;
2352		devpriv->softsshsample = 0x80;
2353		devpriv->softsshhold = 0x00;
2354	} else {
2355		devpriv->softsshsample = 0x00;
2356		devpriv->softsshhold = 0x80;
2357	}
2358
2359	printk(".\n");
2360
2361	pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
2362	pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64);
2363				/* Enable parity check for parity error */
2364
2365	ret = alloc_subdevices(dev, 4);
2366	if (ret < 0)
2367		return ret;
2368
2369	s = dev->subdevices + 0;
2370	dev->read_subdev = s;
2371	s->type = COMEDI_SUBD_AI;
2372	s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2373	if (devpriv->usemux)
2374		s->n_chan = devpriv->usemux;
2375	else
2376		s->n_chan = this_board->n_aichan;
2377
2378	s->maxdata = this_board->ai_maxdata;
2379	s->len_chanlist = this_board->n_aichanlist;
2380	s->range_table = this_board->rangelist_ai;
2381	s->cancel = pci9118_ai_cancel;
2382	s->insn_read = pci9118_insn_read_ai;
2383	if (dev->irq) {
2384		s->subdev_flags |= SDF_CMD_READ;
2385		s->do_cmdtest = pci9118_ai_cmdtest;
2386		s->do_cmd = pci9118_ai_cmd;
2387		s->munge = pci9118_ai_munge;
2388	}
2389
2390	s = dev->subdevices + 1;
2391	s->type = COMEDI_SUBD_AO;
2392	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2393	s->n_chan = this_board->n_aochan;
2394	s->maxdata = this_board->ao_maxdata;
2395	s->len_chanlist = this_board->n_aochan;
2396	s->range_table = this_board->rangelist_ao;
2397	s->insn_write = pci9118_insn_write_ao;
2398	s->insn_read = pci9118_insn_read_ao;
2399
2400	s = dev->subdevices + 2;
2401	s->type = COMEDI_SUBD_DI;
2402	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2403	s->n_chan = 4;
2404	s->maxdata = 1;
2405	s->len_chanlist = 4;
2406	s->range_table = &range_digital;
2407	s->io_bits = 0;		/* all bits input */
2408	s->insn_bits = pci9118_insn_bits_di;
2409
2410	s = dev->subdevices + 3;
2411	s->type = COMEDI_SUBD_DO;
2412	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2413	s->n_chan = 4;
2414	s->maxdata = 1;
2415	s->len_chanlist = 4;
2416	s->range_table = &range_digital;
2417	s->io_bits = 0xf;	/* all bits output */
2418	s->insn_bits = pci9118_insn_bits_do;
2419
2420	devpriv->valid = 1;
2421	devpriv->i8254_osc_base = 250;	/* 250ns=4MHz */
2422	devpriv->ai_maskharderr = 0x10a;
2423					/* default measure crash condition */
2424	if (it->options[5])		/* disable some requested */
2425		devpriv->ai_maskharderr &= ~it->options[5];
2426
2427	switch (this_board->ai_maxdata) {
2428	case 0xffff:
2429		devpriv->ai16bits = 1;
2430		break;
2431	default:
2432		devpriv->ai16bits = 0;
2433		break;
2434	}
2435	return 0;
2436}
2437
2438/*
2439==============================================================================
2440*/
2441static int pci9118_detach(struct comedi_device *dev)
2442{
2443	if (dev->private) {
2444		if (devpriv->valid)
2445			pci9118_reset(dev);
2446		if (dev->irq)
2447			free_irq(dev->irq, dev);
2448		if (devpriv->pcidev) {
2449			if (dev->iobase)
2450				comedi_pci_disable(devpriv->pcidev);
2451
2452			pci_dev_put(devpriv->pcidev);
2453		}
2454		if (devpriv->dmabuf_virt[0])
2455			free_pages((unsigned long)devpriv->dmabuf_virt[0],
2456				   devpriv->dmabuf_pages[0]);
2457		if (devpriv->dmabuf_virt[1])
2458			free_pages((unsigned long)devpriv->dmabuf_virt[1],
2459				   devpriv->dmabuf_pages[1]);
2460	}
2461
2462	return 0;
2463}
2464
2465/*
2466==============================================================================
2467*/
2468
2469MODULE_AUTHOR("Comedi http://www.comedi.org");
2470MODULE_DESCRIPTION("Comedi low-level driver");
2471MODULE_LICENSE("GPL");
2472