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