Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pcl818.c
Go to the documentation of this file.
1 /*
2  comedi/drivers/pcl818.c
3 
4  Author: Michal Dobes <[email protected]>
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 <[email protected]>
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 
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 */
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 |=
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;
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 
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,
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,
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);
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);
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) {
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;
1754  if (check_single_ended(dev->iobase)) {
1755  s->n_chan = board->n_aichan_se;
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:
1781  break;
1782  case 1:
1784  break;
1785  case 2:
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:
1796  break;
1797  case 7:
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;
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))
1836  if (it->options[4] == 2)
1837  s->range_table = &range_unknown;
1838  } else {
1839  if ((it->options[5] == 1) || (it->options[5] == 10))
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;
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;
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");