Staging: fix assorted typos all over the place
[safe/jmp/linux-2.6] / drivers / staging / comedi / drivers / pcl818.c
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 /*
11 Driver: pcl818
12 Description: Advantech PCL-818 cards, PCL-718
13 Author: Michal Dobes <dobes@tesnet.cz>
14 Devices: [Advantech] PCL-818L (pcl818l), PCL-818H (pcl818h),
15   PCL-818HD (pcl818hd), PCL-818HG (pcl818hg), PCL-818 (pcl818),
16   PCL-718 (pcl718)
17 Status: works
18
19 All cards have 16 SE/8 DIFF ADCs, one or two DACs, 16 DI and 16 DO.
20 Differences are only at maximal sample speed, range list and FIFO
21 support.
22 The driver support AI mode 0, 1, 3 other subdevices (AO, DI, DO) support
23 only mode 0. If DMA/FIFO/INT are disabled then AI support only mode 0.
24 PCL-818HD and PCL-818HG support 1kword FIFO. Driver support this FIFO
25 but this code is untested.
26 A word or two about DMA. Driver support DMA operations at two ways:
27 1) 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.
30 2) 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 unknown (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 unknown (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 unknown (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 unknown (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
197 static 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
210 static 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
226 static 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
234 static 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
242 static const struct comedi_lrange range718_bipolar1 = { 1, {BIP_RANGE(1),} };
243 static const struct comedi_lrange range718_bipolar0_5 =
244     { 1, {BIP_RANGE(0.5),} };
245 static const struct comedi_lrange range718_unipolar2 = { 1, {UNI_RANGE(2),} };
246 static const struct comedi_lrange range718_unipolar1 = { 1, {BIP_RANGE(1),} };
247
248 static int pcl818_attach(struct comedi_device *dev,
249                          struct comedi_devconfig *it);
250 static int pcl818_detach(struct comedi_device *dev);
251
252 #ifdef unused
253 static int RTC_lock = 0;        /* RTC lock */
254 static int RTC_timer_lock = 0;  /* RTC int lock */
255 #endif
256
257 struct 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
278 static 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
305 static 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
315 COMEDI_INITCLEANUP(driver_pcl818);
316
317 struct 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
365 static 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 */
375 static 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);
379 static int check_channel_list(struct comedi_device *dev,
380                               struct comedi_subdevice *s,
381                               unsigned int *chanlist, unsigned int n_chan);
382
383 static int pcl818_ai_cancel(struct comedi_device *dev,
384                             struct comedi_subdevice *s);
385 static void start_pacer(struct comedi_device *dev, int mode,
386                         unsigned int divisor1, unsigned int divisor2);
387
388 #ifdef unused
389 static int set_rtc_irq_bit(unsigned char bit);
390 static void rtc_dropped_irq(unsigned long data);
391 static int rtc_setfreq_irq(int freq);
392 #endif
393
394 /*
395 ==============================================================================
396    ANALOG INPUT MODE0, 818 cards, slow version
397 */
398 static 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
433 conv_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 */
446 static 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
460 static 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 */
484 static 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 */
503 static 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 */
526 static 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
545 conv_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 */
579 static 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 */
654 static 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 */
752 static 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 */
821 static 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 unknown source!");
880         return IRQ_NONE;
881 }
882
883 /*
884 ==============================================================================
885    ANALOG INPUT MODE 1 or 3 DMA , 818 cards
886 */
887 static 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 */
928 static 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 */
969 static 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 = 0, divisor2 = 0;
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
1089 static int pcl818_ao_mode13(int mode, struct comedi_device *dev,
1090                             struct comedi_subdevice *s, comedi_trig * it)
1091 {
1092         int divisor1 = 0, divisor2 = 0;
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 */
1143 static 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 */
1153 static 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 */
1165 static 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 */
1185 static 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
1246 static 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 */
1274 static 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 */
1286 static 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 = 0, divisor2 = 0;
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 */
1431 static 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 */
1470 static 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
1523 end:
1524         printk("pcl818_ai_cancel() end\n");
1525         return 0;
1526 }
1527
1528 /*
1529 ==============================================================================
1530  chech for PCL818
1531 */
1532 static 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 */
1555 static 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 */
1588 static 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 */
1623 static 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 */
1645 static 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 */
1676 static 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 */
1714 static 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
1813 no_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
1860 no_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  */
2017 static 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 }