pcl818.c revision 0a85b6f0ab0d2edb0d41b32697111ce0e4f43496
1/*
2   comedi/drivers/pcl818.c
3
4   Author:  Michal Dobes <dobes@tesnet.cz>
5
6   hardware driver for Advantech cards:
7    card:   PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818, PCL-718
8    driver: pcl818l,  pcl818h,  pcl818hd,  pcl818hg,  pcl818,  pcl718
9*/
10/*
11Driver: pcl818
12Description: Advantech PCL-818 cards, PCL-718
13Author: Michal Dobes <dobes@tesnet.cz>
14Devices: [Advantech] PCL-818L (pcl818l), PCL-818H (pcl818h),
15  PCL-818HD (pcl818hd), PCL-818HG (pcl818hg), PCL-818 (pcl818),
16  PCL-718 (pcl718)
17Status: works
18
19All cards have 16 SE/8 DIFF ADCs, one or two DACs, 16 DI and 16 DO.
20Differences are only at maximal sample speed, range list and FIFO
21support.
22The driver support AI mode 0, 1, 3 other subdevices (AO, DI, DO) support
23only mode 0. If DMA/FIFO/INT are disabled then AI support only mode 0.
24PCL-818HD and PCL-818HG support 1kword FIFO. Driver support this FIFO
25but this code is untested.
26A word or two about DMA. Driver support DMA operations at two ways:
271) DMA uses two buffers and after one is filled then is generated
28   INT and DMA restart with second buffer. With this mode I'm unable run
29   more that 80Ksamples/secs without data dropouts on K6/233.
302) DMA uses one buffer and run in autoinit mode and the data are
31   from DMA buffer moved on the fly with 2kHz interrupts from RTC.
32   This mode is used if the interrupt 8 is available for allocation.
33   If not, then first DMA mode is used. With this I can run at
34   full speed one card (100ksamples/secs) or two cards with
35   60ksamples/secs each (more is problem on account of ISA limitations).
36   To use this mode you must have compiled  kernel with disabled
37   "Enhanced Real Time Clock Support".
38   Maybe you can have problems if you use xntpd or similar.
39   If you've data dropouts with DMA mode 2 then:
40    a) disable IDE DMA
41    b) switch text mode console to fb.
42
43   Options for PCL-818L:
44    [0] - IO Base
45    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
46    [2] - DMA	(0=disable, 1, 3)
47    [3] - 0, 10=10MHz clock for 8254
48              1= 1MHz clock for 8254
49    [4] - 0,  5=A/D input  -5V.. +5V
50          1, 10=A/D input -10V..+10V
51    [5] - 0,  5=D/A output 0-5V  (internal reference -5V)
52          1, 10=D/A output 0-10V (internal reference -10V)
53	  2    =D/A output unknow (external reference)
54
55   Options for PCL-818, PCL-818H:
56    [0] - IO Base
57    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
58    [2] - DMA	(0=disable, 1, 3)
59    [3] - 0, 10=10MHz clock for 8254
60              1= 1MHz clock for 8254
61    [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
62          1, 10=D/A output 0-10V (internal reference -10V)
63	  2    =D/A output unknow (external reference)
64
65   Options for PCL-818HD, PCL-818HG:
66    [0] - IO Base
67    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
68    [2] - DMA/FIFO  (-1=use FIFO, 0=disable both FIFO and DMA,
69                      1=use DMA ch 1, 3=use DMA ch 3)
70    [3] - 0, 10=10MHz clock for 8254
71              1= 1MHz clock for 8254
72    [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
73          1, 10=D/A output 0-10V (internal reference -10V)
74   	  2    =D/A output unknow (external reference)
75
76   Options for PCL-718:
77    [0] - IO Base
78    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
79    [2] - DMA	(0=disable, 1, 3)
80    [3] - 0, 10=10MHz clock for 8254
81              1= 1MHz clock for 8254
82    [4] -     0=A/D Range is +/-10V
83	      1=             +/-5V
84	      2=             +/-2.5V
85	      3=             +/-1V
86	      4=             +/-0.5V
87	      5=  	     user defined bipolar
88	      6=	     0-10V
89	      7=	     0-5V
90 	      8=	     0-2V
91	      9=	     0-1V
92	     10=	     user defined unipolar
93    [5] - 0,  5=D/A outputs 0-5V  (internal reference -5V)
94          1, 10=D/A outputs 0-10V (internal reference -10V)
95	      2=D/A outputs unknow (external reference)
96    [6] - 0, 60=max  60kHz A/D sampling
97          1,100=max 100kHz A/D sampling (PCL-718 with Option 001 installed)
98
99*/
100
101#include "../comedidev.h"
102
103#include <linux/ioport.h>
104#include <linux/mc146818rtc.h>
105#include <linux/delay.h>
106#include <asm/dma.h>
107
108#include "8253.h"
109
110/* #define PCL818_MODE13_AO 1 */
111
112/* boards constants */
113
114#define boardPCL818L 0
115#define boardPCL818H 1
116#define boardPCL818HD 2
117#define boardPCL818HG 3
118#define boardPCL818 4
119#define boardPCL718 5
120
121/* IO space len */
122#define PCLx1x_RANGE 16
123/* IO space len if we use FIFO */
124#define PCLx1xFIFO_RANGE 32
125
126/* W: clear INT request */
127#define PCL818_CLRINT 8
128/* R: return status byte */
129#define PCL818_STATUS 8
130/* R: A/D high byte W: A/D range control */
131#define PCL818_RANGE 1
132/* R: next mux scan channel W: mux scan channel & range control pointer */
133#define PCL818_MUX 2
134/* R/W: operation control register */
135#define PCL818_CONTROL 9
136/* W: counter enable */
137#define PCL818_CNTENABLE 10
138
139/* R: low byte of A/D W: soft A/D trigger */
140#define PCL818_AD_LO 0
141/* R: high byte of A/D W: A/D range control */
142#define PCL818_AD_HI 1
143/* W: D/A low&high byte */
144#define PCL818_DA_LO 4
145#define PCL818_DA_HI 5
146/* R: low&high byte of DI */
147#define PCL818_DI_LO 3
148#define PCL818_DI_HI 11
149/* W: low&high byte of DO */
150#define PCL818_DO_LO 3
151#define PCL818_DO_HI 11
152/* W: PCL718 second D/A */
153#define PCL718_DA2_LO 6
154#define PCL718_DA2_HI 7
155/* counters */
156#define PCL818_CTR0 12
157#define PCL818_CTR1 13
158#define PCL818_CTR2 14
159/* W: counter control */
160#define PCL818_CTRCTL 15
161
162/* W: fifo enable/disable */
163#define PCL818_FI_ENABLE 6
164/* W: fifo interrupt clear */
165#define PCL818_FI_INTCLR 20
166/* W: fifo interrupt clear */
167#define PCL818_FI_FLUSH 25
168/* R: fifo status */
169#define PCL818_FI_STATUS 25
170/* R: one record from FIFO */
171#define PCL818_FI_DATALO 23
172#define PCL818_FI_DATAHI 23
173
174/* type of interrupt handler */
175#define INT_TYPE_AI1_INT 1
176#define INT_TYPE_AI1_DMA 2
177#define INT_TYPE_AI1_FIFO 3
178#define INT_TYPE_AI3_INT 4
179#define INT_TYPE_AI3_DMA 5
180#define INT_TYPE_AI3_FIFO 6
181#ifdef PCL818_MODE13_AO
182#define INT_TYPE_AO1_INT 7
183#define INT_TYPE_AO3_INT 8
184#endif
185
186#ifdef unused
187/* RTC stuff... */
188#define INT_TYPE_AI1_DMA_RTC 9
189#define INT_TYPE_AI3_DMA_RTC 10
190
191#define RTC_IRQ 	8
192#define RTC_IO_EXTENT	0x10
193#endif
194
195#define MAGIC_DMA_WORD 0x5a5a
196
197static const struct comedi_lrange range_pcl818h_ai = { 9, {
198							   BIP_RANGE(5),
199							   BIP_RANGE(2.5),
200							   BIP_RANGE(1.25),
201							   BIP_RANGE(0.625),
202							   UNI_RANGE(10),
203							   UNI_RANGE(5),
204							   UNI_RANGE(2.5),
205							   UNI_RANGE(1.25),
206							   BIP_RANGE(10),
207							   }
208};
209
210static const struct comedi_lrange range_pcl818hg_ai = { 10, {
211							     BIP_RANGE(5),
212							     BIP_RANGE(0.5),
213							     BIP_RANGE(0.05),
214							     BIP_RANGE(0.005),
215							     UNI_RANGE(10),
216							     UNI_RANGE(1),
217							     UNI_RANGE(0.1),
218							     UNI_RANGE(0.01),
219							     BIP_RANGE(10),
220							     BIP_RANGE(1),
221							     BIP_RANGE(0.1),
222							     BIP_RANGE(0.01),
223							     }
224};
225
226static const struct comedi_lrange range_pcl818l_l_ai = { 4, {
227							     BIP_RANGE(5),
228							     BIP_RANGE(2.5),
229							     BIP_RANGE(1.25),
230							     BIP_RANGE(0.625),
231							     }
232};
233
234static const struct comedi_lrange range_pcl818l_h_ai = { 4, {
235							     BIP_RANGE(10),
236							     BIP_RANGE(5),
237							     BIP_RANGE(2.5),
238							     BIP_RANGE(1.25),
239							     }
240};
241
242static const struct comedi_lrange range718_bipolar1 = { 1, {BIP_RANGE(1),} };
243static const struct comedi_lrange range718_bipolar0_5 =
244    { 1, {BIP_RANGE(0.5),} };
245static const struct comedi_lrange range718_unipolar2 = { 1, {UNI_RANGE(2),} };
246static const struct comedi_lrange range718_unipolar1 = { 1, {BIP_RANGE(1),} };
247
248static int pcl818_attach(struct comedi_device *dev,
249			 struct comedi_devconfig *it);
250static int pcl818_detach(struct comedi_device *dev);
251
252#ifdef unused
253static int RTC_lock = 0;	/* RTC lock */
254static int RTC_timer_lock = 0;	/* RTC int lock */
255#endif
256
257struct pcl818_board {
258
259	const char *name;	/*  driver name */
260	int n_ranges;		/*  len of range list */
261	int n_aichan_se;	/*  num of A/D chans in single ended  mode */
262	int n_aichan_diff;	/*  num of A/D chans in diferencial mode */
263	unsigned int ns_min;	/*  minimal alllowed delay between samples (in ns) */
264	int n_aochan;		/*  num of D/A chans */
265	int n_dichan;		/*  num of DI chans */
266	int n_dochan;		/*  num of DO chans */
267	const struct comedi_lrange *ai_range_type;	/*  default A/D rangelist */
268	const struct comedi_lrange *ao_range_type;	/*  default D/A rangelist */
269	unsigned int io_range;	/*  len of IO space */
270	unsigned int IRQbits;	/*  allowed interrupts */
271	unsigned int DMAbits;	/*  allowed DMA chans */
272	int ai_maxdata;		/*  maxdata for A/D */
273	int ao_maxdata;		/*  maxdata for D/A */
274	unsigned char fifo;	/*  1=board has FIFO */
275	int is_818;
276};
277
278static const struct pcl818_board boardtypes[] = {
279	{"pcl818l", 4, 16, 8, 25000, 1, 16, 16, &range_pcl818l_l_ai,
280	 &range_unipolar5, PCLx1x_RANGE, 0x00fc,
281	 0x0a, 0xfff, 0xfff, 0, 1},
282	{"pcl818h", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai,
283	 &range_unipolar5, PCLx1x_RANGE, 0x00fc,
284	 0x0a, 0xfff, 0xfff, 0, 1},
285	{"pcl818hd", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai,
286	 &range_unipolar5, PCLx1x_RANGE, 0x00fc,
287	 0x0a, 0xfff, 0xfff, 1, 1},
288	{"pcl818hg", 12, 16, 8, 10000, 1, 16, 16, &range_pcl818hg_ai,
289	 &range_unipolar5, PCLx1x_RANGE, 0x00fc,
290	 0x0a, 0xfff, 0xfff, 1, 1},
291	{"pcl818", 9, 16, 8, 10000, 2, 16, 16, &range_pcl818h_ai,
292	 &range_unipolar5, PCLx1x_RANGE, 0x00fc,
293	 0x0a, 0xfff, 0xfff, 0, 1},
294	{"pcl718", 1, 16, 8, 16000, 2, 16, 16, &range_unipolar5,
295	 &range_unipolar5, PCLx1x_RANGE, 0x00fc,
296	 0x0a, 0xfff, 0xfff, 0, 0},
297	/* pcm3718 */
298	{"pcm3718", 9, 16, 8, 10000, 0, 16, 16, &range_pcl818h_ai,
299	 &range_unipolar5, PCLx1x_RANGE, 0x00fc,
300	 0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ },
301};
302
303#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl818_board))
304
305static struct comedi_driver driver_pcl818 = {
306	.driver_name = "pcl818",
307	.module = THIS_MODULE,
308	.attach = pcl818_attach,
309	.detach = pcl818_detach,
310	.board_name = &boardtypes[0].name,
311	.num_names = n_boardtypes,
312	.offset = sizeof(struct pcl818_board),
313};
314
315COMEDI_INITCLEANUP(driver_pcl818);
316
317struct pcl818_private {
318
319	unsigned int dma;	/*  used DMA, 0=don't use DMA */
320	int dma_rtc;		/*  1=RTC used with DMA, 0=no RTC alloc */
321	unsigned int io_range;
322#ifdef unused
323	unsigned long rtc_iobase;	/*  RTC port region */
324	unsigned int rtc_iosize;
325	unsigned int rtc_irq;
326	struct timer_list rtc_irq_timer;	/*  timer for RTC sanity check */
327	unsigned long rtc_freq;	/*  RTC int freq */
328	int rtc_irq_blocked;	/*  1=we now do AI with DMA&RTC */
329#endif
330	unsigned long dmabuf[2];	/*  pointers to begin of DMA buffers */
331	unsigned int dmapages[2];	/*  len of DMA buffers in PAGE_SIZEs */
332	unsigned int hwdmaptr[2];	/*  hardware address of DMA buffers */
333	unsigned int hwdmasize[2];	/*  len of DMA buffers in Bytes */
334	unsigned int dmasamplsize;	/*  size in samples hwdmasize[0]/2 */
335	unsigned int last_top_dma;	/*  DMA pointer in last RTC int */
336	int next_dma_buf;	/*  which DMA buffer will be used next round */
337	long dma_runs_to_end;	/*  how many we must permorm DMA transfer to end of record */
338	unsigned long last_dma_run;	/*  how many bytes we must transfer on last DMA page */
339	unsigned char neverending_ai;	/*  if=1, then we do neverending record (you must use cancel()) */
340	unsigned int ns_min;	/*  manimal alllowed delay between samples (in us) for actual card */
341	int i8253_osc_base;	/*  1/frequency of on board oscilator in ns */
342	int irq_free;		/*  1=have allocated IRQ */
343	int irq_blocked;	/*  1=IRQ now uses any subdev */
344	int irq_was_now_closed;	/*  when IRQ finish, there's stored int818_mode for last interrupt */
345	int ai_mode;		/*  who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma */
346	struct comedi_subdevice *last_int_sub;	/*  ptr to subdevice which now finish */
347	int ai_act_scan;	/*  how many scans we finished */
348	int ai_act_chan;	/*  actual position in actual scan */
349	unsigned int act_chanlist[16];	/*  MUX setting for actual AI operations */
350	unsigned int act_chanlist_len;	/*  how long is actual MUX list */
351	unsigned int act_chanlist_pos;	/*  actual position in MUX list */
352	unsigned int ai_scans;	/*  len of scanlist */
353	unsigned int ai_n_chan;	/*  how many channels is measured */
354	unsigned int *ai_chanlist;	/*  actaul chanlist */
355	unsigned int ai_flags;	/*  flaglist */
356	unsigned int ai_data_len;	/*  len of data buffer */
357	short *ai_data;		/*  data buffer */
358	unsigned int ai_timer1;	/*  timers */
359	unsigned int ai_timer2;
360	struct comedi_subdevice *sub_ai;	/*  ptr to AI subdevice */
361	unsigned char usefifo;	/*  1=use fifo */
362	unsigned int ao_readback[2];
363};
364
365static const unsigned int muxonechan[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,	/*  used for gain list programming */
366	0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
367};
368
369#define devpriv ((struct pcl818_private *)dev->private)
370#define this_board ((const struct pcl818_board *)dev->board_ptr)
371
372/*
373==============================================================================
374*/
375static void setup_channel_list(struct comedi_device *dev,
376			       struct comedi_subdevice *s,
377			       unsigned int *chanlist, unsigned int n_chan,
378			       unsigned int seglen);
379static int check_channel_list(struct comedi_device *dev,
380			      struct comedi_subdevice *s,
381			      unsigned int *chanlist, unsigned int n_chan);
382
383static int pcl818_ai_cancel(struct comedi_device *dev,
384			    struct comedi_subdevice *s);
385static void start_pacer(struct comedi_device *dev, int mode,
386			unsigned int divisor1, unsigned int divisor2);
387
388#ifdef unused
389static int set_rtc_irq_bit(unsigned char bit);
390static void rtc_dropped_irq(unsigned long data);
391static int rtc_setfreq_irq(int freq);
392#endif
393
394/*
395==============================================================================
396   ANALOG INPUT MODE0, 818 cards, slow version
397*/
398static int pcl818_ai_insn_read(struct comedi_device *dev,
399			       struct comedi_subdevice *s,
400			       struct comedi_insn *insn, unsigned int *data)
401{
402	int n;
403	int timeout;
404
405	/* software trigger, DMA and INT off */
406	outb(0, dev->iobase + PCL818_CONTROL);
407
408	/* select channel */
409	outb(muxonechan[CR_CHAN(insn->chanspec)], dev->iobase + PCL818_MUX);
410
411	/* select gain */
412	outb(CR_RANGE(insn->chanspec), dev->iobase + PCL818_RANGE);
413
414	for (n = 0; n < insn->n; n++) {
415
416		/* clear INT (conversion end) flag */
417		outb(0, dev->iobase + PCL818_CLRINT);
418
419		/* start conversion */
420		outb(0, dev->iobase + PCL818_AD_LO);
421
422		timeout = 100;
423		while (timeout--) {
424			if (inb(dev->iobase + PCL818_STATUS) & 0x10)
425				goto conv_finish;
426			udelay(1);
427		}
428		comedi_error(dev, "A/D insn timeout");
429		/* clear INT (conversion end) flag */
430		outb(0, dev->iobase + PCL818_CLRINT);
431		return -EIO;
432
433conv_finish:
434		data[n] = ((inb(dev->iobase + PCL818_AD_HI) << 4) |
435			   (inb(dev->iobase + PCL818_AD_LO) >> 4));
436	}
437
438	return n;
439}
440
441/*
442==============================================================================
443   ANALOG OUTPUT MODE0, 818 cards
444   only one sample per call is supported
445*/
446static int pcl818_ao_insn_read(struct comedi_device *dev,
447			       struct comedi_subdevice *s,
448			       struct comedi_insn *insn, unsigned int *data)
449{
450	int n;
451	int chan = CR_CHAN(insn->chanspec);
452
453	for (n = 0; n < insn->n; n++) {
454		data[n] = devpriv->ao_readback[chan];
455	}
456
457	return n;
458}
459
460static int pcl818_ao_insn_write(struct comedi_device *dev,
461				struct comedi_subdevice *s,
462				struct comedi_insn *insn, unsigned int *data)
463{
464	int n;
465	int chan = CR_CHAN(insn->chanspec);
466
467	for (n = 0; n < insn->n; n++) {
468		devpriv->ao_readback[chan] = data[n];
469		outb((data[n] & 0x000f) << 4, dev->iobase +
470		     (chan ? PCL718_DA2_LO : PCL818_DA_LO));
471		outb((data[n] & 0x0ff0) >> 4, dev->iobase +
472		     (chan ? PCL718_DA2_HI : PCL818_DA_HI));
473	}
474
475	return n;
476}
477
478/*
479==============================================================================
480   DIGITAL INPUT MODE0, 818 cards
481
482   only one sample per call is supported
483*/
484static int pcl818_di_insn_bits(struct comedi_device *dev,
485			       struct comedi_subdevice *s,
486			       struct comedi_insn *insn, unsigned int *data)
487{
488	if (insn->n != 2)
489		return -EINVAL;
490
491	data[1] = inb(dev->iobase + PCL818_DI_LO) |
492	    (inb(dev->iobase + PCL818_DI_HI) << 8);
493
494	return 2;
495}
496
497/*
498==============================================================================
499   DIGITAL OUTPUT MODE0, 818 cards
500
501   only one sample per call is supported
502*/
503static int pcl818_do_insn_bits(struct comedi_device *dev,
504			       struct comedi_subdevice *s,
505			       struct comedi_insn *insn, unsigned int *data)
506{
507	if (insn->n != 2)
508		return -EINVAL;
509
510	s->state &= ~data[0];
511	s->state |= (data[0] & data[1]);
512
513	outb(s->state & 0xff, dev->iobase + PCL818_DO_LO);
514	outb((s->state >> 8), dev->iobase + PCL818_DO_HI);
515
516	data[1] = s->state;
517
518	return 2;
519}
520
521/*
522==============================================================================
523   analog input interrupt mode 1 & 3, 818 cards
524   one sample per interrupt version
525*/
526static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
527{
528	struct comedi_device *dev = d;
529	struct comedi_subdevice *s = dev->subdevices + 0;
530	int low;
531	int timeout = 50;	/* wait max 50us */
532
533	while (timeout--) {
534		if (inb(dev->iobase + PCL818_STATUS) & 0x10)
535			goto conv_finish;
536		udelay(1);
537	}
538	outb(0, dev->iobase + PCL818_STATUS);	/* clear INT request */
539	comedi_error(dev, "A/D mode1/3 IRQ without DRDY!");
540	pcl818_ai_cancel(dev, s);
541	s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
542	comedi_event(dev, s);
543	return IRQ_HANDLED;
544
545conv_finish:
546	low = inb(dev->iobase + PCL818_AD_LO);
547	comedi_buf_put(s->async, ((inb(dev->iobase + PCL818_AD_HI) << 4) | (low >> 4)));	/*  get one sample */
548	outb(0, dev->iobase + PCL818_CLRINT);	/* clear INT request */
549
550	if ((low & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {	/*  dropout! */
551		printk
552		    ("comedi: A/D mode1/3 IRQ - channel dropout %x!=%x !\n",
553		     (low & 0xf),
554		     devpriv->act_chanlist[devpriv->act_chanlist_pos]);
555		pcl818_ai_cancel(dev, s);
556		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
557		comedi_event(dev, s);
558		return IRQ_HANDLED;
559	}
560	if (s->async->cur_chan == 0) {
561		/*  printk("E"); */
562		devpriv->ai_act_scan--;
563	}
564
565	if (!devpriv->neverending_ai) {
566		if (devpriv->ai_act_scan == 0) {	/* all data sampled */
567			pcl818_ai_cancel(dev, s);
568			s->async->events |= COMEDI_CB_EOA;
569		}
570	}
571	comedi_event(dev, s);
572	return IRQ_HANDLED;
573}
574
575/*
576==============================================================================
577   analog input dma mode 1 & 3, 818 cards
578*/
579static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
580{
581	struct comedi_device *dev = d;
582	struct comedi_subdevice *s = dev->subdevices + 0;
583	int i, len, bufptr;
584	unsigned long flags;
585	short *ptr;
586
587	disable_dma(devpriv->dma);
588	devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
589	if ((devpriv->dma_runs_to_end) > -1 || devpriv->neverending_ai) {	/*  switch dma bufs */
590		set_dma_mode(devpriv->dma, DMA_MODE_READ);
591		flags = claim_dma_lock();
592		set_dma_addr(devpriv->dma,
593			     devpriv->hwdmaptr[devpriv->next_dma_buf]);
594		if (devpriv->dma_runs_to_end || devpriv->neverending_ai) {
595			set_dma_count(devpriv->dma,
596				      devpriv->hwdmasize[devpriv->
597							 next_dma_buf]);
598		} else {
599			set_dma_count(devpriv->dma, devpriv->last_dma_run);
600		}
601		release_dma_lock(flags);
602		enable_dma(devpriv->dma);
603	}
604	printk("comedi: A/D mode1/3 IRQ \n");
605
606	devpriv->dma_runs_to_end--;
607	outb(0, dev->iobase + PCL818_CLRINT);	/* clear INT request */
608	ptr = (short *)devpriv->dmabuf[1 - devpriv->next_dma_buf];
609
610	len = devpriv->hwdmasize[0] >> 1;
611	bufptr = 0;
612
613	for (i = 0; i < len; i++) {
614		if ((ptr[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {	/*  dropout! */
615			printk
616			    ("comedi: A/D mode1/3 DMA - channel dropout %d(card)!=%d(chanlist) at %d !\n",
617			     (ptr[bufptr] & 0xf),
618			     devpriv->act_chanlist[devpriv->act_chanlist_pos],
619			     devpriv->act_chanlist_pos);
620			pcl818_ai_cancel(dev, s);
621			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
622			comedi_event(dev, s);
623			return IRQ_HANDLED;
624		}
625
626		comedi_buf_put(s->async, ptr[bufptr++] >> 4);	/*  get one sample */
627
628		devpriv->act_chanlist_pos++;
629		if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
630			devpriv->ai_act_scan--;
631			devpriv->act_chanlist_pos = 0;
632		}
633
634		if (!devpriv->neverending_ai)
635			if (devpriv->ai_act_scan == 0) {	/* all data sampled */
636				pcl818_ai_cancel(dev, s);
637				s->async->events |= COMEDI_CB_EOA;
638				comedi_event(dev, s);
639				/*  printk("done int ai13 dma\n"); */
640				return IRQ_HANDLED;
641			}
642	}
643
644	if (len > 0)
645		comedi_event(dev, s);
646	return IRQ_HANDLED;
647}
648
649#ifdef unused
650/*
651==============================================================================
652   analog input dma mode 1 & 3 over RTC, 818 cards
653*/
654static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
655{
656	struct comedi_device *dev = d;
657	struct comedi_subdevice *s = dev->subdevices + 0;
658	unsigned long tmp;
659	unsigned int top1, top2, i, bufptr;
660	long ofs_dats;
661	short *dmabuf = (short *)devpriv->dmabuf[0];
662
663	/* outb(2,0x378); */
664	switch (devpriv->ai_mode) {
665	case INT_TYPE_AI1_DMA_RTC:
666	case INT_TYPE_AI3_DMA_RTC:
667		tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
668		mod_timer(&devpriv->rtc_irq_timer,
669			  jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
670
671		for (i = 0; i < 10; i++) {
672			top1 = get_dma_residue(devpriv->dma);
673			top2 = get_dma_residue(devpriv->dma);
674			if (top1 == top2)
675				break;
676		}
677
678		if (top1 != top2)
679			return IRQ_HANDLED;
680		top1 = devpriv->hwdmasize[0] - top1;	/*  where is now DMA in buffer */
681		top1 >>= 1;
682		ofs_dats = top1 - devpriv->last_top_dma;	/*  new samples from last call */
683		if (ofs_dats < 0)
684			ofs_dats = (devpriv->dmasamplsize) + ofs_dats;
685		if (!ofs_dats)
686			return IRQ_HANDLED;	/*  exit=no new samples from last call */
687		/*  obsluz data */
688		i = devpriv->last_top_dma - 1;
689		i &= (devpriv->dmasamplsize - 1);
690
691		if (dmabuf[i] != MAGIC_DMA_WORD) {	/*  DMA overflow! */
692			comedi_error(dev, "A/D mode1/3 DMA buffer overflow!");
693			/* printk("I %d dmabuf[i] %d %d\n",i,dmabuf[i],devpriv->dmasamplsize); */
694			pcl818_ai_cancel(dev, s);
695			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
696			comedi_event(dev, s);
697			return IRQ_HANDLED;
698		}
699		/* printk("r %ld ",ofs_dats); */
700
701		bufptr = devpriv->last_top_dma;
702
703		for (i = 0; i < ofs_dats; i++) {
704			if ((dmabuf[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {	/*  dropout! */
705				printk
706				    ("comedi: A/D mode1/3 DMA - channel dropout %d!=%d !\n",
707				     (dmabuf[bufptr] & 0xf),
708				     devpriv->
709				     act_chanlist[devpriv->act_chanlist_pos]);
710				pcl818_ai_cancel(dev, s);
711				s->async->events |=
712				    COMEDI_CB_EOA | COMEDI_CB_ERROR;
713				comedi_event(dev, s);
714				return IRQ_HANDLED;
715			}
716
717			comedi_buf_put(s->async, dmabuf[bufptr++] >> 4);	/*  get one sample */
718			bufptr &= (devpriv->dmasamplsize - 1);
719
720			if (s->async->cur_chan == 0) {
721				devpriv->ai_act_scan--;
722			}
723
724			if (!devpriv->neverending_ai)
725				if (devpriv->ai_act_scan == 0) {	/* all data sampled */
726					pcl818_ai_cancel(dev, s);
727					s->async->events |= COMEDI_CB_EOA;
728					comedi_event(dev, s);
729					/* printk("done int ai13 dma\n"); */
730					return IRQ_HANDLED;
731				}
732		}
733
734		devpriv->last_top_dma = bufptr;
735		bufptr--;
736		bufptr &= (devpriv->dmasamplsize - 1);
737		dmabuf[bufptr] = MAGIC_DMA_WORD;
738		comedi_event(dev, s);
739		/* outb(0,0x378); */
740		return IRQ_HANDLED;
741	}
742
743	/* outb(0,0x378); */
744	return IRQ_HANDLED;
745}
746#endif
747
748/*
749==============================================================================
750   analog input interrupt mode 1 & 3, 818HD/HG cards
751*/
752static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
753{
754	struct comedi_device *dev = d;
755	struct comedi_subdevice *s = dev->subdevices + 0;
756	int i, len, lo;
757
758	outb(0, dev->iobase + PCL818_FI_INTCLR);	/*  clear fifo int request */
759
760	lo = inb(dev->iobase + PCL818_FI_STATUS);
761
762	if (lo & 4) {
763		comedi_error(dev, "A/D mode1/3 FIFO overflow!");
764		pcl818_ai_cancel(dev, s);
765		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
766		comedi_event(dev, s);
767		return IRQ_HANDLED;
768	}
769
770	if (lo & 1) {
771		comedi_error(dev, "A/D mode1/3 FIFO interrupt without data!");
772		pcl818_ai_cancel(dev, s);
773		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
774		comedi_event(dev, s);
775		return IRQ_HANDLED;
776	}
777
778	if (lo & 2) {
779		len = 512;
780	} else {
781		len = 0;
782	}
783
784	for (i = 0; i < len; i++) {
785		lo = inb(dev->iobase + PCL818_FI_DATALO);
786		if ((lo & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {	/*  dropout! */
787			printk
788			    ("comedi: A/D mode1/3 FIFO - channel dropout %d!=%d !\n",
789			     (lo & 0xf),
790			     devpriv->act_chanlist[devpriv->act_chanlist_pos]);
791			pcl818_ai_cancel(dev, s);
792			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
793			comedi_event(dev, s);
794			return IRQ_HANDLED;
795		}
796
797		comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4));	/*  get one sample */
798
799		if (s->async->cur_chan == 0) {
800			devpriv->ai_act_scan--;
801		}
802
803		if (!devpriv->neverending_ai)
804			if (devpriv->ai_act_scan == 0) {	/* all data sampled */
805				pcl818_ai_cancel(dev, s);
806				s->async->events |= COMEDI_CB_EOA;
807				comedi_event(dev, s);
808				return IRQ_HANDLED;
809			}
810	}
811
812	if (len > 0)
813		comedi_event(dev, s);
814	return IRQ_HANDLED;
815}
816
817/*
818==============================================================================
819    INT procedure
820*/
821static irqreturn_t interrupt_pcl818(int irq, void *d)
822{
823	struct comedi_device *dev = d;
824
825	if (!dev->attached) {
826		comedi_error(dev, "premature interrupt");
827		return IRQ_HANDLED;
828	}
829	/* printk("I\n"); */
830
831	if (devpriv->irq_blocked && devpriv->irq_was_now_closed) {
832		if ((devpriv->neverending_ai || (!devpriv->neverending_ai &&
833						 devpriv->ai_act_scan > 0)) &&
834		    (devpriv->ai_mode == INT_TYPE_AI1_DMA ||
835		     devpriv->ai_mode == INT_TYPE_AI3_DMA)) {
836			/* The cleanup from ai_cancel() has been delayed
837			   until now because the card doesn't seem to like
838			   being reprogrammed while a DMA transfer is in
839			   progress.
840			 */
841			struct comedi_subdevice *s = dev->subdevices + 0;
842			devpriv->ai_act_scan = 0;
843			devpriv->neverending_ai = 0;
844			pcl818_ai_cancel(dev, s);
845		}
846
847		outb(0, dev->iobase + PCL818_CLRINT);	/* clear INT request */
848
849		return IRQ_HANDLED;
850	}
851
852	switch (devpriv->ai_mode) {
853	case INT_TYPE_AI1_DMA:
854	case INT_TYPE_AI3_DMA:
855		return interrupt_pcl818_ai_mode13_dma(irq, d);
856	case INT_TYPE_AI1_INT:
857	case INT_TYPE_AI3_INT:
858		return interrupt_pcl818_ai_mode13_int(irq, d);
859	case INT_TYPE_AI1_FIFO:
860	case INT_TYPE_AI3_FIFO:
861		return interrupt_pcl818_ai_mode13_fifo(irq, d);
862#ifdef PCL818_MODE13_AO
863	case INT_TYPE_AO1_INT:
864	case INT_TYPE_AO3_INT:
865		return interrupt_pcl818_ao_mode13_int(irq, d);
866#endif
867	default:
868		break;
869	}
870
871	outb(0, dev->iobase + PCL818_CLRINT);	/* clear INT request */
872
873	if ((!dev->irq) || (!devpriv->irq_free) || (!devpriv->irq_blocked)
874	    || (!devpriv->ai_mode)) {
875		comedi_error(dev, "bad IRQ!");
876		return IRQ_NONE;
877	}
878
879	comedi_error(dev, "IRQ from unknow source!");
880	return IRQ_NONE;
881}
882
883/*
884==============================================================================
885   ANALOG INPUT MODE 1 or 3 DMA , 818 cards
886*/
887static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev,
888				    struct comedi_subdevice *s)
889{
890	unsigned int flags;
891	unsigned int bytes;
892
893	printk("mode13dma_int, mode: %d\n", mode);
894	disable_dma(devpriv->dma);	/*  disable dma */
895	bytes = devpriv->hwdmasize[0];
896	if (!devpriv->neverending_ai) {
897		bytes = devpriv->ai_n_chan * devpriv->ai_scans * sizeof(short);	/*  how many */
898		devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0];	/*  how many DMA pages we must fiil */
899		devpriv->last_dma_run = bytes % devpriv->hwdmasize[0];	/* on last dma transfer must be moved */
900		devpriv->dma_runs_to_end--;
901		if (devpriv->dma_runs_to_end >= 0)
902			bytes = devpriv->hwdmasize[0];
903	}
904
905	devpriv->next_dma_buf = 0;
906	set_dma_mode(devpriv->dma, DMA_MODE_READ);
907	flags = claim_dma_lock();
908	clear_dma_ff(devpriv->dma);
909	set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
910	set_dma_count(devpriv->dma, bytes);
911	release_dma_lock(flags);
912	enable_dma(devpriv->dma);
913
914	if (mode == 1) {
915		devpriv->ai_mode = INT_TYPE_AI1_DMA;
916		outb(0x87 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Pacer+IRQ+DMA */
917	} else {
918		devpriv->ai_mode = INT_TYPE_AI3_DMA;
919		outb(0x86 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Ext trig+IRQ+DMA */
920	};
921}
922
923#ifdef unused
924/*
925==============================================================================
926   ANALOG INPUT MODE 1 or 3 DMA rtc, 818 cards
927*/
928static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device *dev,
929				    struct comedi_subdevice *s)
930{
931	unsigned int flags;
932	short *pole;
933
934	set_dma_mode(devpriv->dma, DMA_MODE_READ | DMA_AUTOINIT);
935	flags = claim_dma_lock();
936	clear_dma_ff(devpriv->dma);
937	set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
938	set_dma_count(devpriv->dma, devpriv->hwdmasize[0]);
939	release_dma_lock(flags);
940	enable_dma(devpriv->dma);
941	devpriv->last_top_dma = 0;	/* devpriv->hwdmasize[0]; */
942	pole = (short *)devpriv->dmabuf[0];
943	devpriv->dmasamplsize = devpriv->hwdmasize[0] / 2;
944	pole[devpriv->dmasamplsize - 1] = MAGIC_DMA_WORD;
945#ifdef unused
946	devpriv->rtc_freq = rtc_setfreq_irq(2048);
947	devpriv->rtc_irq_timer.expires =
948	    jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100;
949	devpriv->rtc_irq_timer.data = (unsigned long)dev;
950	devpriv->rtc_irq_timer.function = rtc_dropped_irq;
951
952	add_timer(&devpriv->rtc_irq_timer);
953#endif
954
955	if (mode == 1) {
956		devpriv->int818_mode = INT_TYPE_AI1_DMA_RTC;
957		outb(0x07 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Pacer+DMA */
958	} else {
959		devpriv->int818_mode = INT_TYPE_AI3_DMA_RTC;
960		outb(0x06 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Ext trig+DMA */
961	};
962}
963#endif
964
965/*
966==============================================================================
967   ANALOG INPUT MODE 1 or 3, 818 cards
968*/
969static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
970			      struct comedi_subdevice *s)
971{
972	struct comedi_cmd *cmd = &s->async->cmd;
973	int divisor1, divisor2;
974	unsigned int seglen;
975
976	printk("pcl818_ai_cmd_mode()\n");
977	if ((!dev->irq) && (!devpriv->dma_rtc)) {
978		comedi_error(dev, "IRQ not defined!");
979		return -EINVAL;
980	}
981
982	if (devpriv->irq_blocked)
983		return -EBUSY;
984
985	start_pacer(dev, -1, 0, 0);	/*  stop pacer */
986
987	seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
988				    devpriv->ai_n_chan);
989	if (seglen < 1)
990		return -EINVAL;
991	setup_channel_list(dev, s, devpriv->ai_chanlist,
992			   devpriv->ai_n_chan, seglen);
993
994	udelay(1);
995
996	devpriv->ai_act_scan = devpriv->ai_scans;
997	devpriv->ai_act_chan = 0;
998	devpriv->irq_blocked = 1;
999	devpriv->irq_was_now_closed = 0;
1000	devpriv->neverending_ai = 0;
1001	devpriv->act_chanlist_pos = 0;
1002	devpriv->dma_runs_to_end = 0;
1003
1004	if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1))
1005		devpriv->neverending_ai = 1;	/* well, user want neverending */
1006
1007	if (mode == 1) {
1008		i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
1009					  &divisor2, &cmd->convert_arg,
1010					  TRIG_ROUND_NEAREST);
1011		if (divisor1 == 1) {	/* PCL718/818 crash if any divisor is set to 1 */
1012			divisor1 = 2;
1013			divisor2 /= 2;
1014		}
1015		if (divisor2 == 1) {
1016			divisor2 = 2;
1017			divisor1 /= 2;
1018		}
1019	}
1020
1021	outb(0, dev->iobase + PCL818_CNTENABLE);	/* enable pacer */
1022
1023	switch (devpriv->dma) {
1024	case 1:		/*  DMA */
1025	case 3:
1026		if (devpriv->dma_rtc == 0) {
1027			pcl818_ai_mode13dma_int(mode, dev, s);
1028		}
1029#ifdef unused
1030		else {
1031			pcl818_ai_mode13dma_rtc(mode, dev, s);
1032		}
1033#else
1034		else {
1035			return -EINVAL;
1036		}
1037#endif
1038		break;
1039	case 0:
1040		if (!devpriv->usefifo) {
1041			/* IRQ */
1042			/* printk("IRQ\n"); */
1043			if (mode == 1) {
1044				devpriv->ai_mode = INT_TYPE_AI1_INT;
1045				/* Pacer+IRQ */
1046				outb(0x83 | (dev->irq << 4),
1047				     dev->iobase + PCL818_CONTROL);
1048			} else {
1049				devpriv->ai_mode = INT_TYPE_AI3_INT;
1050				/* Ext trig+IRQ */
1051				outb(0x82 | (dev->irq << 4),
1052				     dev->iobase + PCL818_CONTROL);
1053			}
1054		} else {
1055			/* FIFO */
1056			/* enable FIFO */
1057			outb(1, dev->iobase + PCL818_FI_ENABLE);
1058			if (mode == 1) {
1059				devpriv->ai_mode = INT_TYPE_AI1_FIFO;
1060				/* Pacer */
1061				outb(0x03, dev->iobase + PCL818_CONTROL);
1062			} else {
1063				devpriv->ai_mode = INT_TYPE_AI3_FIFO;
1064				outb(0x02, dev->iobase + PCL818_CONTROL);
1065			}
1066		}
1067	}
1068
1069	start_pacer(dev, mode, divisor1, divisor2);
1070
1071#ifdef unused
1072	switch (devpriv->ai_mode) {
1073	case INT_TYPE_AI1_DMA_RTC:
1074	case INT_TYPE_AI3_DMA_RTC:
1075		set_rtc_irq_bit(1);	/* start RTC */
1076		break;
1077	}
1078#endif
1079	printk("pcl818_ai_cmd_mode() end\n");
1080	return 0;
1081}
1082
1083#ifdef unused
1084/*
1085==============================================================================
1086   ANALOG OUTPUT MODE 1 or 3, 818 cards
1087*/
1088#ifdef PCL818_MODE13_AO
1089static int pcl818_ao_mode13(int mode, struct comedi_device *dev,
1090			    struct comedi_subdevice *s, comedi_trig * it)
1091{
1092	int divisor1, divisor2;
1093
1094	if (!dev->irq) {
1095		comedi_error(dev, "IRQ not defined!");
1096		return -EINVAL;
1097	}
1098
1099	if (devpriv->irq_blocked)
1100		return -EBUSY;
1101
1102	start_pacer(dev, -1, 0, 0);	/*  stop pacer */
1103
1104	devpriv->int13_act_scan = it->n;
1105	devpriv->int13_act_chan = 0;
1106	devpriv->irq_blocked = 1;
1107	devpriv->irq_was_now_closed = 0;
1108	devpriv->neverending_ai = 0;
1109	devpriv->act_chanlist_pos = 0;
1110
1111	if (mode == 1) {
1112		i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
1113					  &divisor2, &it->trigvar,
1114					  TRIG_ROUND_NEAREST);
1115		if (divisor1 == 1) {	/* PCL818 crash if any divisor is set to 1 */
1116			divisor1 = 2;
1117			divisor2 /= 2;
1118		}
1119		if (divisor2 == 1) {
1120			divisor2 = 2;
1121			divisor1 /= 2;
1122		}
1123	}
1124
1125	outb(0, dev->iobase + PCL818_CNTENABLE);	/* enable pacer */
1126	if (mode == 1) {
1127		devpriv->int818_mode = INT_TYPE_AO1_INT;
1128		outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Pacer+IRQ */
1129	} else {
1130		devpriv->int818_mode = INT_TYPE_AO3_INT;
1131		outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Ext trig+IRQ */
1132	};
1133
1134	start_pacer(dev, mode, divisor1, divisor2);
1135
1136	return 0;
1137}
1138
1139/*
1140==============================================================================
1141   ANALOG OUTPUT MODE 1, 818 cards
1142*/
1143static int pcl818_ao_mode1(struct comedi_device *dev,
1144			   struct comedi_subdevice *s, comedi_trig * it)
1145{
1146	return pcl818_ao_mode13(1, dev, s, it);
1147}
1148
1149/*
1150==============================================================================
1151   ANALOG OUTPUT MODE 3, 818 cards
1152*/
1153static int pcl818_ao_mode3(struct comedi_device *dev,
1154			   struct comedi_subdevice *s, comedi_trig * it)
1155{
1156	return pcl818_ao_mode13(3, dev, s, it);
1157}
1158#endif
1159#endif
1160
1161/*
1162==============================================================================
1163 Start/stop pacer onboard pacer
1164*/
1165static void start_pacer(struct comedi_device *dev, int mode,
1166			unsigned int divisor1, unsigned int divisor2)
1167{
1168	outb(0xb4, dev->iobase + PCL818_CTRCTL);
1169	outb(0x74, dev->iobase + PCL818_CTRCTL);
1170	udelay(1);
1171
1172	if (mode == 1) {
1173		outb(divisor2 & 0xff, dev->iobase + PCL818_CTR2);
1174		outb((divisor2 >> 8) & 0xff, dev->iobase + PCL818_CTR2);
1175		outb(divisor1 & 0xff, dev->iobase + PCL818_CTR1);
1176		outb((divisor1 >> 8) & 0xff, dev->iobase + PCL818_CTR1);
1177	}
1178}
1179
1180/*
1181==============================================================================
1182 Check if channel list from user is builded correctly
1183 If it's ok, then program scan/gain logic
1184*/
1185static int check_channel_list(struct comedi_device *dev,
1186			      struct comedi_subdevice *s,
1187			      unsigned int *chanlist, unsigned int n_chan)
1188{
1189	unsigned int chansegment[16];
1190	unsigned int i, nowmustbechan, seglen, segpos;
1191
1192	/* correct channel and range number check itself comedi/range.c */
1193	if (n_chan < 1) {
1194		comedi_error(dev, "range/channel list is empty!");
1195		return 0;
1196	}
1197
1198	if (n_chan > 1) {
1199		/*  first channel is everytime ok */
1200		chansegment[0] = chanlist[0];
1201		/*  build part of chanlist */
1202		for (i = 1, seglen = 1; i < n_chan; i++, seglen++) {
1203
1204			/* printk("%d. %d * %d\n",i,
1205			 * CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i]));*/
1206
1207			/* we detect loop, this must by finish */
1208
1209			if (chanlist[0] == chanlist[i])
1210				break;
1211			nowmustbechan =
1212			    (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
1213			if (nowmustbechan != CR_CHAN(chanlist[i])) {	/*  channel list isn't continous :-( */
1214				printk
1215				    ("comedi%d: pcl818: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
1216				     dev->minor, i, CR_CHAN(chanlist[i]),
1217				     nowmustbechan, CR_CHAN(chanlist[0]));
1218				return 0;
1219			}
1220			/*  well, this is next correct channel in list */
1221			chansegment[i] = chanlist[i];
1222		}
1223
1224		/*  check whole chanlist */
1225		for (i = 0, segpos = 0; i < n_chan; i++) {
1226			/* printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i])); */
1227			if (chanlist[i] != chansegment[i % seglen]) {
1228				printk
1229				    ("comedi%d: pcl818: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
1230				     dev->minor, i, CR_CHAN(chansegment[i]),
1231				     CR_RANGE(chansegment[i]),
1232				     CR_AREF(chansegment[i]),
1233				     CR_CHAN(chanlist[i % seglen]),
1234				     CR_RANGE(chanlist[i % seglen]),
1235				     CR_AREF(chansegment[i % seglen]));
1236				return 0;	/*  chan/gain list is strange */
1237			}
1238		}
1239	} else {
1240		seglen = 1;
1241	}
1242	printk("check_channel_list: seglen %d\n", seglen);
1243	return seglen;
1244}
1245
1246static void setup_channel_list(struct comedi_device *dev,
1247			       struct comedi_subdevice *s,
1248			       unsigned int *chanlist, unsigned int n_chan,
1249			       unsigned int seglen)
1250{
1251	int i;
1252
1253	devpriv->act_chanlist_len = seglen;
1254	devpriv->act_chanlist_pos = 0;
1255
1256	for (i = 0; i < seglen; i++) {	/*  store range list to card */
1257		devpriv->act_chanlist[i] = CR_CHAN(chanlist[i]);
1258		outb(muxonechan[CR_CHAN(chanlist[i])], dev->iobase + PCL818_MUX);	/* select channel */
1259		outb(CR_RANGE(chanlist[i]), dev->iobase + PCL818_RANGE);	/* select gain */
1260	}
1261
1262	udelay(1);
1263
1264	/* select channel interval to scan */
1265	outb(devpriv->act_chanlist[0] | (devpriv->act_chanlist[seglen -
1266							       1] << 4),
1267	     dev->iobase + PCL818_MUX);
1268}
1269
1270/*
1271==============================================================================
1272 Check if board is switched to SE (1) or DIFF(0) mode
1273*/
1274static int check_single_ended(unsigned int port)
1275{
1276	if (inb(port + PCL818_STATUS) & 0x20) {
1277		return 1;
1278	} else {
1279		return 0;
1280	}
1281}
1282
1283/*
1284==============================================================================
1285*/
1286static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
1287		      struct comedi_cmd *cmd)
1288{
1289	int err = 0;
1290	int tmp, divisor1, divisor2;
1291
1292	/* step 1: make sure trigger sources are trivially valid */
1293
1294	tmp = cmd->start_src;
1295	cmd->start_src &= TRIG_NOW;
1296	if (!cmd->start_src || tmp != cmd->start_src)
1297		err++;
1298
1299	tmp = cmd->scan_begin_src;
1300	cmd->scan_begin_src &= TRIG_FOLLOW;
1301	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1302		err++;
1303
1304	tmp = cmd->convert_src;
1305	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1306	if (!cmd->convert_src || tmp != cmd->convert_src)
1307		err++;
1308
1309	tmp = cmd->scan_end_src;
1310	cmd->scan_end_src &= TRIG_COUNT;
1311	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1312		err++;
1313
1314	tmp = cmd->stop_src;
1315	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1316	if (!cmd->stop_src || tmp != cmd->stop_src)
1317		err++;
1318
1319	if (err) {
1320		return 1;
1321	}
1322
1323	/* step 2: make sure trigger sources are unique and mutually compatible */
1324
1325	if (cmd->start_src != TRIG_NOW) {
1326		cmd->start_src = TRIG_NOW;
1327		err++;
1328	}
1329	if (cmd->scan_begin_src != TRIG_FOLLOW) {
1330		cmd->scan_begin_src = TRIG_FOLLOW;
1331		err++;
1332	}
1333	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
1334		err++;
1335
1336	if (cmd->scan_end_src != TRIG_COUNT) {
1337		cmd->scan_end_src = TRIG_COUNT;
1338		err++;
1339	}
1340
1341	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
1342		err++;
1343
1344	if (err) {
1345		return 2;
1346	}
1347
1348	/* step 3: make sure arguments are trivially compatible */
1349
1350	if (cmd->start_arg != 0) {
1351		cmd->start_arg = 0;
1352		err++;
1353	}
1354
1355	if (cmd->scan_begin_arg != 0) {
1356		cmd->scan_begin_arg = 0;
1357		err++;
1358	}
1359
1360	if (cmd->convert_src == TRIG_TIMER) {
1361		if (cmd->convert_arg < this_board->ns_min) {
1362			cmd->convert_arg = this_board->ns_min;
1363			err++;
1364		}
1365	} else {		/* TRIG_EXT */
1366		if (cmd->convert_arg != 0) {
1367			cmd->convert_arg = 0;
1368			err++;
1369		}
1370	}
1371
1372	if (!cmd->chanlist_len) {
1373		cmd->chanlist_len = 1;
1374		err++;
1375	}
1376	if (cmd->chanlist_len > s->n_chan) {
1377		cmd->chanlist_len = s->n_chan;
1378		err++;
1379	}
1380	if (cmd->scan_end_arg != cmd->chanlist_len) {
1381		cmd->scan_end_arg = cmd->chanlist_len;
1382		err++;
1383	}
1384	if (cmd->stop_src == TRIG_COUNT) {
1385		if (!cmd->stop_arg) {
1386			cmd->stop_arg = 1;
1387			err++;
1388		}
1389	} else {		/* TRIG_NONE */
1390		if (cmd->stop_arg != 0) {
1391			cmd->stop_arg = 0;
1392			err++;
1393		}
1394	}
1395
1396	if (err) {
1397		return 3;
1398	}
1399
1400	/* step 4: fix up any arguments */
1401
1402	if (cmd->convert_src == TRIG_TIMER) {
1403		tmp = cmd->convert_arg;
1404		i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
1405					  &divisor2, &cmd->convert_arg,
1406					  cmd->flags & TRIG_ROUND_MASK);
1407		if (cmd->convert_arg < this_board->ns_min)
1408			cmd->convert_arg = this_board->ns_min;
1409		if (tmp != cmd->convert_arg)
1410			err++;
1411	}
1412
1413	if (err) {
1414		return 4;
1415	}
1416
1417	/* step 5: complain about special chanlist considerations */
1418
1419	if (cmd->chanlist) {
1420		if (!check_channel_list(dev, s, cmd->chanlist,
1421					cmd->chanlist_len))
1422			return 5;	/*  incorrect channels list */
1423	}
1424
1425	return 0;
1426}
1427
1428/*
1429==============================================================================
1430*/
1431static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1432{
1433	struct comedi_cmd *cmd = &s->async->cmd;
1434	int retval;
1435
1436	printk("pcl818_ai_cmd()\n");
1437	devpriv->ai_n_chan = cmd->chanlist_len;
1438	devpriv->ai_chanlist = cmd->chanlist;
1439	devpriv->ai_flags = cmd->flags;
1440	devpriv->ai_data_len = s->async->prealloc_bufsz;
1441	devpriv->ai_data = s->async->prealloc_buf;
1442	devpriv->ai_timer1 = 0;
1443	devpriv->ai_timer2 = 0;
1444
1445	if (cmd->stop_src == TRIG_COUNT) {
1446		devpriv->ai_scans = cmd->stop_arg;
1447	} else {
1448		devpriv->ai_scans = 0;
1449	}
1450
1451	if (cmd->scan_begin_src == TRIG_FOLLOW) {	/*  mode 1, 3 */
1452		if (cmd->convert_src == TRIG_TIMER) {	/*  mode 1 */
1453			devpriv->ai_timer1 = cmd->convert_arg;
1454			retval = pcl818_ai_cmd_mode(1, dev, s);
1455			printk("pcl818_ai_cmd() end\n");
1456			return retval;
1457		}
1458		if (cmd->convert_src == TRIG_EXT) {	/*  mode 3 */
1459			return pcl818_ai_cmd_mode(3, dev, s);
1460		}
1461	}
1462
1463	return -1;
1464}
1465
1466/*
1467==============================================================================
1468 cancel any mode 1-4 AI
1469*/
1470static int pcl818_ai_cancel(struct comedi_device *dev,
1471			    struct comedi_subdevice *s)
1472{
1473	if (devpriv->irq_blocked > 0) {
1474		printk("pcl818_ai_cancel()\n");
1475		devpriv->irq_was_now_closed = 1;
1476
1477		switch (devpriv->ai_mode) {
1478#ifdef unused
1479		case INT_TYPE_AI1_DMA_RTC:
1480		case INT_TYPE_AI3_DMA_RTC:
1481			set_rtc_irq_bit(0);	/*  stop RTC */
1482			del_timer(&devpriv->rtc_irq_timer);
1483#endif
1484		case INT_TYPE_AI1_DMA:
1485		case INT_TYPE_AI3_DMA:
1486			if (devpriv->neverending_ai ||
1487			    (!devpriv->neverending_ai &&
1488			     devpriv->ai_act_scan > 0)) {
1489				/* wait for running dma transfer to end, do cleanup in interrupt */
1490				goto end;
1491			}
1492			disable_dma(devpriv->dma);
1493		case INT_TYPE_AI1_INT:
1494		case INT_TYPE_AI3_INT:
1495		case INT_TYPE_AI1_FIFO:
1496		case INT_TYPE_AI3_FIFO:
1497#ifdef PCL818_MODE13_AO
1498		case INT_TYPE_AO1_INT:
1499		case INT_TYPE_AO3_INT:
1500#endif
1501			outb(inb(dev->iobase + PCL818_CONTROL) & 0x73, dev->iobase + PCL818_CONTROL);	/* Stop A/D */
1502			udelay(1);
1503			start_pacer(dev, -1, 0, 0);
1504			outb(0, dev->iobase + PCL818_AD_LO);
1505			inb(dev->iobase + PCL818_AD_LO);
1506			inb(dev->iobase + PCL818_AD_HI);
1507			outb(0, dev->iobase + PCL818_CLRINT);	/* clear INT request */
1508			outb(0, dev->iobase + PCL818_CONTROL);	/* Stop A/D */
1509			if (devpriv->usefifo) {	/*  FIFO shutdown */
1510				outb(0, dev->iobase + PCL818_FI_INTCLR);
1511				outb(0, dev->iobase + PCL818_FI_FLUSH);
1512				outb(0, dev->iobase + PCL818_FI_ENABLE);
1513			}
1514			devpriv->irq_blocked = 0;
1515			devpriv->last_int_sub = s;
1516			devpriv->neverending_ai = 0;
1517			devpriv->ai_mode = 0;
1518			devpriv->irq_was_now_closed = 0;
1519			break;
1520		}
1521	}
1522
1523end:
1524	printk("pcl818_ai_cancel() end\n");
1525	return 0;
1526}
1527
1528/*
1529==============================================================================
1530 chech for PCL818
1531*/
1532static int pcl818_check(unsigned long iobase)
1533{
1534	outb(0x00, iobase + PCL818_MUX);
1535	udelay(1);
1536	if (inb(iobase + PCL818_MUX) != 0x00)
1537		return 1;	/* there isn't card */
1538	outb(0x55, iobase + PCL818_MUX);
1539	udelay(1);
1540	if (inb(iobase + PCL818_MUX) != 0x55)
1541		return 1;	/* there isn't card */
1542	outb(0x00, iobase + PCL818_MUX);
1543	udelay(1);
1544	outb(0x18, iobase + PCL818_CONTROL);
1545	udelay(1);
1546	if (inb(iobase + PCL818_CONTROL) != 0x18)
1547		return 1;	/* there isn't card */
1548	return 0;		/*  ok, card exist */
1549}
1550
1551/*
1552==============================================================================
1553 reset whole PCL-818 cards
1554*/
1555static void pcl818_reset(struct comedi_device *dev)
1556{
1557	if (devpriv->usefifo) {	/*  FIFO shutdown */
1558		outb(0, dev->iobase + PCL818_FI_INTCLR);
1559		outb(0, dev->iobase + PCL818_FI_FLUSH);
1560		outb(0, dev->iobase + PCL818_FI_ENABLE);
1561	}
1562	outb(0, dev->iobase + PCL818_DA_LO);	/*  DAC=0V */
1563	outb(0, dev->iobase + PCL818_DA_HI);
1564	udelay(1);
1565	outb(0, dev->iobase + PCL818_DO_HI);	/*  DO=$0000 */
1566	outb(0, dev->iobase + PCL818_DO_LO);
1567	udelay(1);
1568	outb(0, dev->iobase + PCL818_CONTROL);
1569	outb(0, dev->iobase + PCL818_CNTENABLE);
1570	outb(0, dev->iobase + PCL818_MUX);
1571	outb(0, dev->iobase + PCL818_CLRINT);
1572	outb(0xb0, dev->iobase + PCL818_CTRCTL);	/* Stop pacer */
1573	outb(0x70, dev->iobase + PCL818_CTRCTL);
1574	outb(0x30, dev->iobase + PCL818_CTRCTL);
1575	if (this_board->is_818) {
1576		outb(0, dev->iobase + PCL818_RANGE);
1577	} else {
1578		outb(0, dev->iobase + PCL718_DA2_LO);
1579		outb(0, dev->iobase + PCL718_DA2_HI);
1580	}
1581}
1582
1583#ifdef unused
1584/*
1585==============================================================================
1586  Enable(1)/disable(0) periodic interrupts from RTC
1587*/
1588static int set_rtc_irq_bit(unsigned char bit)
1589{
1590	unsigned char val;
1591	unsigned long flags;
1592
1593	if (bit == 1) {
1594		RTC_timer_lock++;
1595		if (RTC_timer_lock > 1)
1596			return 0;
1597	} else {
1598		RTC_timer_lock--;
1599		if (RTC_timer_lock < 0)
1600			RTC_timer_lock = 0;
1601		if (RTC_timer_lock > 0)
1602			return 0;
1603	}
1604
1605	save_flags(flags);
1606	cli();
1607	val = CMOS_READ(RTC_CONTROL);
1608	if (bit) {
1609		val |= RTC_PIE;
1610	} else {
1611		val &= ~RTC_PIE;
1612	}
1613	CMOS_WRITE(val, RTC_CONTROL);
1614	CMOS_READ(RTC_INTR_FLAGS);
1615	restore_flags(flags);
1616	return 0;
1617}
1618
1619/*
1620==============================================================================
1621  Restart RTC if something stop it (xntpd every 11 mins or large IDE transfers)
1622*/
1623static void rtc_dropped_irq(unsigned long data)
1624{
1625	struct comedi_device *dev = (void *)data;
1626	unsigned long flags, tmp;
1627
1628	switch (devpriv->int818_mode) {
1629	case INT_TYPE_AI1_DMA_RTC:
1630	case INT_TYPE_AI3_DMA_RTC:
1631		mod_timer(&devpriv->rtc_irq_timer,
1632			  jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
1633		save_flags(flags);
1634		cli();
1635		tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);	/* restart */
1636		restore_flags(flags);
1637		break;
1638	};
1639}
1640
1641/*
1642==============================================================================
1643  Set frequency of interrupts from RTC
1644*/
1645static int rtc_setfreq_irq(int freq)
1646{
1647	int tmp = 0;
1648	int rtc_freq;
1649	unsigned char val;
1650	unsigned long flags;
1651
1652	if (freq < 2)
1653		freq = 2;
1654	if (freq > 8192)
1655		freq = 8192;
1656
1657	while (freq > (1 << tmp))
1658		tmp++;
1659
1660	rtc_freq = 1 << tmp;
1661
1662	save_flags(flags);
1663	cli();
1664	val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
1665	val |= (16 - tmp);
1666	CMOS_WRITE(val, RTC_FREQ_SELECT);
1667	restore_flags(flags);
1668	return rtc_freq;
1669}
1670#endif
1671
1672/*
1673==============================================================================
1674  Free any resources that we have claimed
1675*/
1676static void free_resources(struct comedi_device *dev)
1677{
1678	/* printk("free_resource()\n"); */
1679	if (dev->private) {
1680		pcl818_ai_cancel(dev, devpriv->sub_ai);
1681		pcl818_reset(dev);
1682		if (devpriv->dma)
1683			free_dma(devpriv->dma);
1684		if (devpriv->dmabuf[0])
1685			free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
1686		if (devpriv->dmabuf[1])
1687			free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
1688#ifdef unused
1689		if (devpriv->rtc_irq)
1690			free_irq(devpriv->rtc_irq, dev);
1691		if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
1692			if (devpriv->rtc_iobase)
1693				release_region(devpriv->rtc_iobase,
1694					       devpriv->rtc_iosize);
1695		}
1696		if (devpriv->dma_rtc)
1697			RTC_lock--;
1698#endif
1699	}
1700
1701	if (dev->irq)
1702		free_irq(dev->irq, dev);
1703	if (dev->iobase)
1704		release_region(dev->iobase, devpriv->io_range);
1705	/* printk("free_resource() end\n"); */
1706}
1707
1708/*
1709==============================================================================
1710
1711   Initialization
1712
1713*/
1714static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1715{
1716	int ret;
1717	unsigned long iobase;
1718	unsigned int irq;
1719	int dma;
1720	unsigned long pages;
1721	struct comedi_subdevice *s;
1722
1723	ret = alloc_private(dev, sizeof(struct pcl818_private));
1724	if (ret < 0)
1725		return ret;	/* Can't alloc mem */
1726
1727	/* claim our I/O space */
1728	iobase = it->options[0];
1729	printk("comedi%d: pcl818:  board=%s, ioport=0x%03lx",
1730	       dev->minor, this_board->name, iobase);
1731	devpriv->io_range = this_board->io_range;
1732	if ((this_board->fifo) && (it->options[2] == -1)) {	/*  we've board with FIFO and we want to use FIFO */
1733		devpriv->io_range = PCLx1xFIFO_RANGE;
1734		devpriv->usefifo = 1;
1735	}
1736	if (!request_region(iobase, devpriv->io_range, "pcl818")) {
1737		printk("I/O port conflict\n");
1738		return -EIO;
1739	}
1740
1741	dev->iobase = iobase;
1742
1743	if (pcl818_check(iobase)) {
1744		printk(", I can't detect board. FAIL!\n");
1745		return -EIO;
1746	}
1747
1748	/* set up some name stuff */
1749	dev->board_name = this_board->name;
1750	/* grab our IRQ */
1751	irq = 0;
1752	if (this_board->IRQbits != 0) {	/* board support IRQ */
1753		irq = it->options[1];
1754		if (irq) {	/* we want to use IRQ */
1755			if (((1 << irq) & this_board->IRQbits) == 0) {
1756				printk
1757				    (", IRQ %u is out of allowed range, DISABLING IT",
1758				     irq);
1759				irq = 0;	/* Bad IRQ */
1760			} else {
1761				if (request_irq
1762				    (irq, interrupt_pcl818, 0, "pcl818", dev)) {
1763					printk
1764					    (", unable to allocate IRQ %u, DISABLING IT",
1765					     irq);
1766					irq = 0;	/* Can't use IRQ */
1767				} else {
1768					printk(", irq=%u", irq);
1769				}
1770			}
1771		}
1772	}
1773
1774	dev->irq = irq;
1775	if (irq) {
1776		devpriv->irq_free = 1;
1777	} /* 1=we have allocated irq */
1778	else {
1779		devpriv->irq_free = 0;
1780	}
1781	devpriv->irq_blocked = 0;	/* number of subdevice which use IRQ */
1782	devpriv->ai_mode = 0;	/* mode of irq */
1783
1784#ifdef unused
1785	/* grab RTC for DMA operations */
1786	devpriv->dma_rtc = 0;
1787	if (it->options[2] > 0) {	/*  we want to use DMA */
1788		if (RTC_lock == 0) {
1789			if (!request_region(RTC_PORT(0), RTC_IO_EXTENT,
1790					    "pcl818 (RTC)"))
1791				goto no_rtc;
1792		}
1793		devpriv->rtc_iobase = RTC_PORT(0);
1794		devpriv->rtc_iosize = RTC_IO_EXTENT;
1795		RTC_lock++;
1796		if (!request_irq(RTC_IRQ, interrupt_pcl818_ai_mode13_dma_rtc, 0,
1797				 "pcl818 DMA (RTC)", dev)) {
1798			devpriv->dma_rtc = 1;
1799			devpriv->rtc_irq = RTC_IRQ;
1800			printk(", dma_irq=%u", devpriv->rtc_irq);
1801		} else {
1802			RTC_lock--;
1803			if (RTC_lock == 0) {
1804				if (devpriv->rtc_iobase)
1805					release_region(devpriv->rtc_iobase,
1806						       devpriv->rtc_iosize);
1807			}
1808			devpriv->rtc_iobase = 0;
1809			devpriv->rtc_iosize = 0;
1810		}
1811	}
1812
1813no_rtc:
1814#endif
1815	/* grab our DMA */
1816	dma = 0;
1817	devpriv->dma = dma;
1818	if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0))
1819		goto no_dma;	/* if we haven't IRQ, we can't use DMA */
1820	if (this_board->DMAbits != 0) {	/* board support DMA */
1821		dma = it->options[2];
1822		if (dma < 1)
1823			goto no_dma;	/* DMA disabled */
1824		if (((1 << dma) & this_board->DMAbits) == 0) {
1825			printk(", DMA is out of allowed range, FAIL!\n");
1826			return -EINVAL;	/* Bad DMA */
1827		}
1828		ret = request_dma(dma, "pcl818");
1829		if (ret) {
1830			printk(", unable to allocate DMA %u, FAIL!\n", dma);
1831			return -EBUSY;	/* DMA isn't free */
1832		}
1833		devpriv->dma = dma;
1834		printk(", dma=%u", dma);
1835		pages = 2;	/* we need 16KB */
1836		devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
1837		if (!devpriv->dmabuf[0]) {
1838			printk(", unable to allocate DMA buffer, FAIL!\n");
1839			/* maybe experiment with try_to_free_pages() will help .... */
1840			return -EBUSY;	/* no buffer :-( */
1841		}
1842		devpriv->dmapages[0] = pages;
1843		devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
1844		devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE;
1845		/* printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); */
1846		if (devpriv->dma_rtc == 0) {	/*  we must do duble buff :-( */
1847			devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
1848			if (!devpriv->dmabuf[1]) {
1849				printk
1850				    (", unable to allocate DMA buffer, FAIL!\n");
1851				return -EBUSY;
1852			}
1853			devpriv->dmapages[1] = pages;
1854			devpriv->hwdmaptr[1] =
1855			    virt_to_bus((void *)devpriv->dmabuf[1]);
1856			devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
1857		}
1858	}
1859
1860no_dma:
1861
1862	ret = alloc_subdevices(dev, 4);
1863	if (ret < 0)
1864		return ret;
1865
1866	s = dev->subdevices + 0;
1867	if (!this_board->n_aichan_se) {
1868		s->type = COMEDI_SUBD_UNUSED;
1869	} else {
1870		s->type = COMEDI_SUBD_AI;
1871		devpriv->sub_ai = s;
1872		s->subdev_flags = SDF_READABLE;
1873		if (check_single_ended(dev->iobase)) {
1874			s->n_chan = this_board->n_aichan_se;
1875			s->subdev_flags |= SDF_COMMON | SDF_GROUND;
1876			printk(", %dchans S.E. DAC", s->n_chan);
1877		} else {
1878			s->n_chan = this_board->n_aichan_diff;
1879			s->subdev_flags |= SDF_DIFF;
1880			printk(", %dchans DIFF DAC", s->n_chan);
1881		}
1882		s->maxdata = this_board->ai_maxdata;
1883		s->len_chanlist = s->n_chan;
1884		s->range_table = this_board->ai_range_type;
1885		s->cancel = pcl818_ai_cancel;
1886		s->insn_read = pcl818_ai_insn_read;
1887		if ((irq) || (devpriv->dma_rtc)) {
1888			dev->read_subdev = s;
1889			s->subdev_flags |= SDF_CMD_READ;
1890			s->do_cmdtest = ai_cmdtest;
1891			s->do_cmd = ai_cmd;
1892		}
1893		if (this_board->is_818) {
1894			if ((it->options[4] == 1) || (it->options[4] == 10))
1895				s->range_table = &range_pcl818l_h_ai;	/*  secondary range list jumper selectable */
1896		} else {
1897			switch (it->options[4]) {
1898			case 0:
1899				s->range_table = &range_bipolar10;
1900				break;
1901			case 1:
1902				s->range_table = &range_bipolar5;
1903				break;
1904			case 2:
1905				s->range_table = &range_bipolar2_5;
1906				break;
1907			case 3:
1908				s->range_table = &range718_bipolar1;
1909				break;
1910			case 4:
1911				s->range_table = &range718_bipolar0_5;
1912				break;
1913			case 6:
1914				s->range_table = &range_unipolar10;
1915				break;
1916			case 7:
1917				s->range_table = &range_unipolar5;
1918				break;
1919			case 8:
1920				s->range_table = &range718_unipolar2;
1921				break;
1922			case 9:
1923				s->range_table = &range718_unipolar1;
1924				break;
1925			default:
1926				s->range_table = &range_unknown;
1927				break;
1928			}
1929		}
1930	}
1931
1932	s = dev->subdevices + 1;
1933	if (!this_board->n_aochan) {
1934		s->type = COMEDI_SUBD_UNUSED;
1935	} else {
1936		s->type = COMEDI_SUBD_AO;
1937		s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
1938		s->n_chan = this_board->n_aochan;
1939		s->maxdata = this_board->ao_maxdata;
1940		s->len_chanlist = this_board->n_aochan;
1941		s->range_table = this_board->ao_range_type;
1942		s->insn_read = pcl818_ao_insn_read;
1943		s->insn_write = pcl818_ao_insn_write;
1944#ifdef unused
1945#ifdef PCL818_MODE13_AO
1946		if (irq) {
1947			s->trig[1] = pcl818_ao_mode1;
1948			s->trig[3] = pcl818_ao_mode3;
1949		}
1950#endif
1951#endif
1952		if (this_board->is_818) {
1953			if ((it->options[4] == 1) || (it->options[4] == 10))
1954				s->range_table = &range_unipolar10;
1955			if (it->options[4] == 2)
1956				s->range_table = &range_unknown;
1957		} else {
1958			if ((it->options[5] == 1) || (it->options[5] == 10))
1959				s->range_table = &range_unipolar10;
1960			if (it->options[5] == 2)
1961				s->range_table = &range_unknown;
1962		}
1963	}
1964
1965	s = dev->subdevices + 2;
1966	if (!this_board->n_dichan) {
1967		s->type = COMEDI_SUBD_UNUSED;
1968	} else {
1969		s->type = COMEDI_SUBD_DI;
1970		s->subdev_flags = SDF_READABLE;
1971		s->n_chan = this_board->n_dichan;
1972		s->maxdata = 1;
1973		s->len_chanlist = this_board->n_dichan;
1974		s->range_table = &range_digital;
1975		s->insn_bits = pcl818_di_insn_bits;
1976	}
1977
1978	s = dev->subdevices + 3;
1979	if (!this_board->n_dochan) {
1980		s->type = COMEDI_SUBD_UNUSED;
1981	} else {
1982		s->type = COMEDI_SUBD_DO;
1983		s->subdev_flags = SDF_WRITABLE;
1984		s->n_chan = this_board->n_dochan;
1985		s->maxdata = 1;
1986		s->len_chanlist = this_board->n_dochan;
1987		s->range_table = &range_digital;
1988		s->insn_bits = pcl818_do_insn_bits;
1989	}
1990
1991	/* select 1/10MHz oscilator */
1992	if ((it->options[3] == 0) || (it->options[3] == 10)) {
1993		devpriv->i8253_osc_base = 100;
1994	} else {
1995		devpriv->i8253_osc_base = 1000;
1996	}
1997
1998	/* max sampling speed */
1999	devpriv->ns_min = this_board->ns_min;
2000
2001	if (!this_board->is_818) {
2002		if ((it->options[6] == 1) || (it->options[6] == 100))
2003			devpriv->ns_min = 10000;	/* extended PCL718 to 100kHz DAC */
2004	}
2005
2006	pcl818_reset(dev);
2007
2008	printk("\n");
2009
2010	return 0;
2011}
2012
2013/*
2014==============================================================================
2015  Removes device
2016 */
2017static int pcl818_detach(struct comedi_device *dev)
2018{
2019	/*   printk("comedi%d: pcl818: remove\n", dev->minor); */
2020	free_resources(dev);
2021	return 0;
2022}
2023