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