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