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