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