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