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