1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65#include "../comedidev.h"
66#include "../pci_ids.h"
67
68#include <linux/delay.h>
69#include <linux/interrupt.h>
70
71#include "amcc_s5933.h"
72#include "8253.h"
73#include "comedi_pci.h"
74#include "comedi_fc.h"
75
76
77#undef PCI9118_PARANOIDCHECK
78
79#undef PCI9118_EXTDEBUG
80
81#undef DPRINTK
82#ifdef PCI9118_EXTDEBUG
83#define DPRINTK(fmt, args...) printk(fmt, ## args)
84#else
85#define DPRINTK(fmt, args...)
86#endif
87
88#define IORANGE_9118 64
89#define PCI9118_CHANLEN 255
90
91#define PCI9118_CNT0 0x00
92#define PCI9118_CNT1 0x04
93#define PCI9118_CNT2 0x08
94#define PCI9118_CNTCTRL 0x0c
95#define PCI9118_AD_DATA 0x10
96#define PCI9118_DA1 0x10
97#define PCI9118_DA2 0x14
98#define PCI9118_ADSTAT 0x18
99#define PCI9118_ADCNTRL 0x18
100#define PCI9118_DI 0x1c
101#define PCI9118_DO 0x1c
102#define PCI9118_SOFTTRG 0x20
103#define PCI9118_GAIN 0x24
104#define PCI9118_BURST 0x28
105#define PCI9118_SCANMOD 0x2c
106#define PCI9118_ADFUNC 0x30
107#define PCI9118_DELFIFO 0x34
108#define PCI9118_INTSRC 0x38
109#define PCI9118_INTCTRL 0x38
110
111
112#define AdControl_UniP 0x80
113#define AdControl_Diff 0x40
114#define AdControl_SoftG 0x20
115#define AdControl_ExtG 0x10
116#define AdControl_ExtM 0x08
117#define AdControl_TmrTr 0x04
118#define AdControl_Int 0x02
119#define AdControl_Dma 0x01
120
121
122#define AdFunction_PDTrg 0x80
123#define AdFunction_PETrg 0x40
124#define AdFunction_BSSH 0x20
125#define AdFunction_BM 0x10
126#define AdFunction_BS 0x08
127#define AdFunction_PM 0x04
128#define AdFunction_AM 0x02
129#define AdFunction_Start 0x01
130
131
132#define AdStatus_nFull 0x100
133#define AdStatus_nHfull 0x080
134#define AdStatus_nEpty 0x040
135#define AdStatus_Acmp 0x020
136#define AdStatus_DTH 0x010
137#define AdStatus_Bover 0x008
138#define AdStatus_ADOS 0x004
139#define AdStatus_ADOR 0x002
140#define AdStatus_ADrdy 0x001
141
142
143
144#define Int_Timer 0x08
145#define Int_About 0x04
146#define Int_Hfull 0x02
147#define Int_DTrg 0x01
148
149#define START_AI_EXT 0x01
150#define STOP_AI_EXT 0x02
151#define START_AI_INT 0x04
152#define STOP_AI_INT 0x08
153
154#define EXTTRG_AI 0
155
156static const struct comedi_lrange range_pci9118dg_hr = { 8, {
157 BIP_RANGE(5),
158 BIP_RANGE(2.5),
159 BIP_RANGE(1.25),
160 BIP_RANGE(0.625),
161 UNI_RANGE(10),
162 UNI_RANGE(5),
163 UNI_RANGE(2.5),
164 UNI_RANGE(1.25)
165 }
166};
167
168static const struct comedi_lrange range_pci9118hg = { 8, {
169 BIP_RANGE(5),
170 BIP_RANGE(0.5),
171 BIP_RANGE(0.05),
172 BIP_RANGE(0.005),
173 UNI_RANGE(10),
174 UNI_RANGE(1),
175 UNI_RANGE(0.1),
176 UNI_RANGE(0.01)
177 }
178};
179
180#define PCI9118_BIPOLAR_RANGES 4
181
182static int pci9118_attach(struct comedi_device *dev,
183 struct comedi_devconfig *it);
184static int pci9118_detach(struct comedi_device *dev);
185
186struct boardtype {
187 const char *name;
188 int vendor_id;
189 int device_id;
190 int iorange_amcc;
191 int iorange_9118;
192 int n_aichan;
193 int n_aichand;
194 int mux_aichan;
195 int n_aichanlist;
196 int n_aochan;
197 int ai_maxdata;
198 int ao_maxdata;
199 const struct comedi_lrange *rangelist_ai;
200 const struct comedi_lrange *rangelist_ao;
201 unsigned int ai_ns_min;
202 unsigned int ai_pacer_min;
203 int half_fifo_size;
204
205};
206
207static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
208 {
209 PCI_VENDOR_ID_AMCC, 0x80d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
210 0}
211};
212
213MODULE_DEVICE_TABLE(pci, pci9118_pci_table);
214
215static const struct boardtype boardtypes[] = {
216 {"pci9118dg", PCI_VENDOR_ID_AMCC, 0x80d9,
217 AMCC_OP_REG_SIZE, IORANGE_9118,
218 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
219 &range_pci9118dg_hr, &range_bipolar10,
220 3000, 12, 512},
221 {"pci9118hg", PCI_VENDOR_ID_AMCC, 0x80d9,
222 AMCC_OP_REG_SIZE, IORANGE_9118,
223 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
224 &range_pci9118hg, &range_bipolar10,
225 3000, 12, 512},
226 {"pci9118hr", PCI_VENDOR_ID_AMCC, 0x80d9,
227 AMCC_OP_REG_SIZE, IORANGE_9118,
228 16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff,
229 &range_pci9118dg_hr, &range_bipolar10,
230 10000, 40, 512},
231};
232
233#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
234
235static struct comedi_driver driver_pci9118 = {
236 .driver_name = "adl_pci9118",
237 .module = THIS_MODULE,
238 .attach = pci9118_attach,
239 .detach = pci9118_detach,
240 .num_names = n_boardtypes,
241 .board_name = &boardtypes[0].name,
242 .offset = sizeof(struct boardtype),
243};
244
245COMEDI_PCI_INITCLEANUP(driver_pci9118, pci9118_pci_table);
246
247struct pci9118_private {
248 unsigned long iobase_a;
249 unsigned int master;
250 struct pci_dev *pcidev;
251 unsigned int usemux;
252#ifdef PCI9118_PARANOIDCHECK
253 unsigned short chanlist[PCI9118_CHANLEN + 1];
254 unsigned char chanlistlen;
255#endif
256 unsigned char AdControlReg;
257 unsigned char IntControlReg;
258 unsigned char AdFunctionReg;
259 char valid;
260 char ai_neverending;
261 unsigned int i8254_osc_base;
262 unsigned int ai_do;
263 unsigned int ai_act_scan;
264 unsigned int ai_buf_ptr;
265 unsigned int ai_n_chan;
266 unsigned int ai_n_scanlen;
267 unsigned int ai_n_realscanlen;
268 unsigned int ai_act_dmapos;
269 unsigned int ai_add_front;
270 unsigned int ai_add_back;
271 unsigned int *ai_chanlist;
272 unsigned int ai_timer1;
273 unsigned int ai_timer2;
274 unsigned int ai_flags;
275 char ai12_startstop;
276 unsigned int ai_divisor1, ai_divisor2;
277 unsigned int ai_data_len;
278 short *ai_data;
279 short ao_data[2];
280 unsigned int ai_scans;
281 char dma_doublebuf;
282 unsigned int dma_actbuf;
283 short *dmabuf_virt[2];
284 unsigned long dmabuf_hw[2];
285 unsigned int dmabuf_size[2];
286 unsigned int dmabuf_use_size[2];
287 unsigned int dmabuf_used_size[2];
288 unsigned int dmabuf_panic_size[2];
289 unsigned int dmabuf_samples[2];
290 int dmabuf_pages[2];
291 unsigned char cnt0_users;
292 unsigned char exttrg_users;
293 unsigned int cnt0_divisor;
294 void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *, unsigned short, unsigned int, unsigned short);
295 unsigned char ai16bits;
296 unsigned char usedma;
297 unsigned char useeoshandle;
298 unsigned char usessh;
299 int softsshdelay;
300 unsigned char softsshsample;
301 unsigned char softsshhold;
302 unsigned int ai_maskerr;
303 unsigned int ai_maskharderr;
304 unsigned int ai_inttrig_start;
305};
306
307#define devpriv ((struct pci9118_private *)dev->private)
308#define this_board ((struct boardtype *)dev->board_ptr)
309
310
311
312
313
314static int check_channel_list(struct comedi_device *dev,
315 struct comedi_subdevice *s, int n_chan,
316 unsigned int *chanlist, int frontadd,
317 int backadd);
318static int setup_channel_list(struct comedi_device *dev,
319 struct comedi_subdevice *s, int n_chan,
320 unsigned int *chanlist, int rot, int frontadd,
321 int backadd, int usedma, char eoshandle);
322static void start_pacer(struct comedi_device *dev, int mode,
323 unsigned int divisor1, unsigned int divisor2);
324static int pci9118_reset(struct comedi_device *dev);
325static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source);
326static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source);
327static int pci9118_ai_cancel(struct comedi_device *dev,
328 struct comedi_subdevice *s);
329static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
330 struct comedi_subdevice *s,
331 unsigned int *tim1, unsigned int *tim2,
332 unsigned int flags, int chans,
333 unsigned int *div1, unsigned int *div2,
334 char usessh, unsigned int chnsshfront);
335
336
337
338
339static int pci9118_insn_read_ai(struct comedi_device *dev,
340 struct comedi_subdevice *s,
341 struct comedi_insn *insn, unsigned int *data)
342{
343
344 int n, timeout;
345
346 devpriv->AdControlReg = AdControl_Int & 0xff;
347 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
348 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
349
350 if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
351 return -EINVAL;
352
353 outl(0, dev->iobase + PCI9118_DELFIFO);
354
355 for (n = 0; n < insn->n; n++) {
356 outw(0, dev->iobase + PCI9118_SOFTTRG);
357 udelay(2);
358 timeout = 100;
359 while (timeout--) {
360 if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
361 goto conv_finish;
362 udelay(1);
363 }
364
365 comedi_error(dev, "A/D insn timeout");
366 data[n] = 0;
367 outl(0, dev->iobase + PCI9118_DELFIFO);
368 return -ETIME;
369
370conv_finish:
371 if (devpriv->ai16bits) {
372 data[n] =
373 (inl(dev->iobase +
374 PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
375 } else {
376 data[n] =
377 (inw(dev->iobase + PCI9118_AD_DATA) >> 4) & 0xfff;
378 }
379 }
380
381 outl(0, dev->iobase + PCI9118_DELFIFO);
382 return n;
383
384}
385
386
387
388
389static int pci9118_insn_write_ao(struct comedi_device *dev,
390 struct comedi_subdevice *s,
391 struct comedi_insn *insn, unsigned int *data)
392{
393 int n, chanreg, ch;
394
395 ch = CR_CHAN(insn->chanspec);
396 if (ch) {
397 chanreg = PCI9118_DA2;
398 } else {
399 chanreg = PCI9118_DA1;
400 }
401
402 for (n = 0; n < insn->n; n++) {
403 outl(data[n], dev->iobase + chanreg);
404 devpriv->ao_data[ch] = data[n];
405 }
406
407 return n;
408}
409
410
411
412
413static int pci9118_insn_read_ao(struct comedi_device *dev,
414 struct comedi_subdevice *s,
415 struct comedi_insn *insn, unsigned int *data)
416{
417 int n, chan;
418
419 chan = CR_CHAN(insn->chanspec);
420 for (n = 0; n < insn->n; n++)
421 data[n] = devpriv->ao_data[chan];
422
423 return n;
424}
425
426
427
428
429static int pci9118_insn_bits_di(struct comedi_device *dev,
430 struct comedi_subdevice *s,
431 struct comedi_insn *insn, unsigned int *data)
432{
433 data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
434
435 return 2;
436}
437
438
439
440
441static int pci9118_insn_bits_do(struct comedi_device *dev,
442 struct comedi_subdevice *s,
443 struct comedi_insn *insn, unsigned int *data)
444{
445 if (data[0]) {
446 s->state &= ~data[0];
447 s->state |= (data[0] & data[1]);
448 outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
449 }
450 data[1] = s->state;
451
452 return 2;
453}
454
455
456
457
458static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev)
459{
460 devpriv->AdFunctionReg =
461 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
462 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
463 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
464 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
465 dev->iobase + PCI9118_CNT0);
466 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
467 dev->iobase + PCI9118_CNT0);
468 devpriv->AdFunctionReg |= AdFunction_Start;
469 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
470}
471
472static unsigned int defragment_dma_buffer(struct comedi_device *dev,
473 struct comedi_subdevice *s,
474 short *dma_buffer,
475 unsigned int num_samples)
476{
477 unsigned int i = 0, j = 0;
478 unsigned int start_pos = devpriv->ai_add_front,
479 stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
480 unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
481 devpriv->ai_add_back;
482
483 for (i = 0; i < num_samples; i++) {
484 if (devpriv->ai_act_dmapos >= start_pos &&
485 devpriv->ai_act_dmapos < stop_pos) {
486 dma_buffer[j++] = dma_buffer[i];
487 }
488 devpriv->ai_act_dmapos++;
489 devpriv->ai_act_dmapos %= raw_scanlen;
490 }
491
492 return j;
493}
494
495
496
497
498static unsigned int move_block_from_dma(struct comedi_device *dev,
499 struct comedi_subdevice *s,
500 short *dma_buffer,
501 unsigned int num_samples)
502{
503 unsigned int num_bytes;
504
505 num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
506 devpriv->ai_act_scan +=
507 (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
508 s->async->cur_chan += num_samples;
509 s->async->cur_chan %= devpriv->ai_n_scanlen;
510 num_bytes =
511 cfc_write_array_to_buffer(s, dma_buffer,
512 num_samples * sizeof(short));
513 if (num_bytes < num_samples * sizeof(short))
514 return -1;
515 return 0;
516}
517
518
519
520
521static char pci9118_decode_error_status(struct comedi_device *dev,
522 struct comedi_subdevice *s,
523 unsigned char m)
524{
525 if (m & 0x100) {
526 comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
527 devpriv->ai_maskerr &= ~0x100L;
528 }
529 if (m & 0x008) {
530 comedi_error(dev,
531 "A/D Burst Mode Overrun Status (Fatal Error!)");
532 devpriv->ai_maskerr &= ~0x008L;
533 }
534 if (m & 0x004) {
535 comedi_error(dev, "A/D Over Speed Status (Warning!)");
536 devpriv->ai_maskerr &= ~0x004L;
537 }
538 if (m & 0x002) {
539 comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
540 devpriv->ai_maskerr &= ~0x002L;
541 }
542 if (m & devpriv->ai_maskharderr) {
543 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
544 pci9118_ai_cancel(dev, s);
545 comedi_event(dev, s);
546 return 1;
547 }
548
549 return 0;
550}
551
552static void pci9118_ai_munge(struct comedi_device *dev,
553 struct comedi_subdevice *s, void *data,
554 unsigned int num_bytes,
555 unsigned int start_chan_index)
556{
557 unsigned int i, num_samples = num_bytes / sizeof(short);
558 short *array = data;
559
560 for (i = 0; i < num_samples; i++) {
561 if (devpriv->usedma)
562 array[i] = be16_to_cpu(array[i]);
563 if (devpriv->ai16bits) {
564 array[i] ^= 0x8000;
565 } else {
566 array[i] = (array[i] >> 4) & 0x0fff;
567 }
568 }
569}
570
571
572
573
574static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
575 struct comedi_subdevice *s,
576 unsigned short int_adstat,
577 unsigned int int_amcc,
578 unsigned short int_daq)
579{
580 register short sampl;
581
582 s->async->events = 0;
583
584 if (int_adstat & devpriv->ai_maskerr)
585 if (pci9118_decode_error_status(dev, s, int_adstat))
586 return;
587
588 sampl = inw(dev->iobase + PCI9118_AD_DATA);
589
590#ifdef PCI9118_PARANOIDCHECK
591 if (devpriv->ai16bits == 0) {
592 if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) {
593 printk
594 ("comedi: A/D SAMPL - data dropout: received channel %d, expected %d!\n",
595 sampl & 0x000f,
596 devpriv->chanlist[s->async->cur_chan]);
597 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
598 pci9118_ai_cancel(dev, s);
599 comedi_event(dev, s);
600 return;
601 }
602 }
603#endif
604 cfc_write_to_buffer(s, sampl);
605 s->async->cur_chan++;
606 if (s->async->cur_chan >= devpriv->ai_n_scanlen) {
607 s->async->cur_chan %= devpriv->ai_n_scanlen;
608 devpriv->ai_act_scan++;
609 if (!(devpriv->ai_neverending))
610 if (devpriv->ai_act_scan >= devpriv->ai_scans) {
611 pci9118_ai_cancel(dev, s);
612 s->async->events |= COMEDI_CB_EOA;
613 }
614 }
615
616 if (s->async->events)
617 comedi_event(dev, s);
618}
619
620
621
622
623static void interrupt_pci9118_ai_dma(struct comedi_device *dev,
624 struct comedi_subdevice *s,
625 unsigned short int_adstat,
626 unsigned int int_amcc,
627 unsigned short int_daq)
628{
629 unsigned int next_dma_buf, samplesinbuf, sampls, m;
630
631 if (int_amcc & MASTER_ABORT_INT) {
632 comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
633 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
634 pci9118_ai_cancel(dev, s);
635 comedi_event(dev, s);
636 return;
637 }
638
639 if (int_amcc & TARGET_ABORT_INT) {
640 comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
641 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
642 pci9118_ai_cancel(dev, s);
643 comedi_event(dev, s);
644 return;
645 }
646
647 if (int_adstat & devpriv->ai_maskerr)
648
649 if (pci9118_decode_error_status(dev, s, int_adstat))
650 return;
651
652 samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1;
653
654
655 if (devpriv->dma_doublebuf) {
656 next_dma_buf = 1 - devpriv->dma_actbuf;
657 outl(devpriv->dmabuf_hw[next_dma_buf],
658 devpriv->iobase_a + AMCC_OP_REG_MWAR);
659 outl(devpriv->dmabuf_use_size[next_dma_buf],
660 devpriv->iobase_a + AMCC_OP_REG_MWTC);
661 devpriv->dmabuf_used_size[next_dma_buf] =
662 devpriv->dmabuf_use_size[next_dma_buf];
663 if (devpriv->ai_do == 4)
664 interrupt_pci9118_ai_mode4_switch(dev);
665 }
666
667 if (samplesinbuf) {
668 m = devpriv->ai_data_len >> 1;
669
670 sampls = m;
671 move_block_from_dma(dev, s,
672 devpriv->dmabuf_virt[devpriv->dma_actbuf],
673 samplesinbuf);
674 m = m - sampls;
675 }
676
677
678 if (!devpriv->ai_neverending)
679 if (devpriv->ai_act_scan >= devpriv->ai_scans) {
680 pci9118_ai_cancel(dev, s);
681 s->async->events |= COMEDI_CB_EOA;
682 }
683
684 if (devpriv->dma_doublebuf) {
685 devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
686 } else {
687 outl(devpriv->dmabuf_hw[0],
688 devpriv->iobase_a + AMCC_OP_REG_MWAR);
689 outl(devpriv->dmabuf_use_size[0],
690 devpriv->iobase_a + AMCC_OP_REG_MWTC);
691 if (devpriv->ai_do == 4)
692 interrupt_pci9118_ai_mode4_switch(dev);
693 }
694
695 comedi_event(dev, s);
696}
697
698
699
700
701static irqreturn_t interrupt_pci9118(int irq, void *d)
702{
703 struct comedi_device *dev = d;
704 unsigned int int_daq = 0, int_amcc, int_adstat;
705
706 if (!dev->attached)
707 return IRQ_NONE;
708
709 int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf;
710 int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
711
712
713
714 if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
715 return IRQ_NONE;
716
717 outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
718
719 int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff;
720
721 if (devpriv->ai_do) {
722 if (devpriv->ai12_startstop)
723 if ((int_adstat & AdStatus_DTH) && (int_daq & Int_DTrg)) {
724 if (devpriv->ai12_startstop & START_AI_EXT) {
725 devpriv->ai12_startstop &=
726 ~START_AI_EXT;
727 if (!(devpriv->ai12_startstop &
728 STOP_AI_EXT))
729 pci9118_exttrg_del(dev, EXTTRG_AI);
730 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, devpriv->ai_divisor2);
731 outl(devpriv->AdControlReg,
732 dev->iobase + PCI9118_ADCNTRL);
733 } else {
734 if (devpriv->ai12_startstop &
735 STOP_AI_EXT) {
736 devpriv->ai12_startstop &=
737 ~STOP_AI_EXT;
738 pci9118_exttrg_del(dev, EXTTRG_AI);
739 devpriv->ai_neverending = 0;
740 }
741 }
742 }
743
744 (devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat,
745 int_amcc, int_daq);
746
747 }
748 return IRQ_HANDLED;
749}
750
751
752
753
754static int pci9118_ai_inttrig(struct comedi_device *dev,
755 struct comedi_subdevice *s, unsigned int trignum)
756{
757 if (trignum != devpriv->ai_inttrig_start)
758 return -EINVAL;
759
760 devpriv->ai12_startstop &= ~START_AI_INT;
761 s->async->inttrig = NULL;
762
763 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
764 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
765 if (devpriv->ai_do != 3) {
766 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
767 devpriv->ai_divisor2);
768 devpriv->AdControlReg |= AdControl_SoftG;
769 }
770 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
771
772 return 1;
773}
774
775
776
777
778static int pci9118_ai_cmdtest(struct comedi_device *dev,
779 struct comedi_subdevice *s,
780 struct comedi_cmd *cmd)
781{
782 int err = 0;
783 int tmp, divisor1, divisor2;
784
785
786
787 tmp = cmd->start_src;
788 cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT;
789 if (!cmd->start_src || tmp != cmd->start_src)
790 err++;
791
792 tmp = cmd->scan_begin_src;
793 if (devpriv->master) {
794 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW;
795 } else {
796 cmd->scan_begin_src &= TRIG_FOLLOW;
797 }
798 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
799 err++;
800
801 tmp = cmd->convert_src;
802 if (devpriv->master) {
803 cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW;
804 } else {
805 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
806 }
807 if (!cmd->convert_src || tmp != cmd->convert_src)
808 err++;
809
810 tmp = cmd->scan_end_src;
811 cmd->scan_end_src &= TRIG_COUNT;
812 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
813 err++;
814
815 tmp = cmd->stop_src;
816 cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT;
817 if (!cmd->stop_src || tmp != cmd->stop_src)
818 err++;
819
820 if (err)
821 return 1;
822
823
824
825 if (cmd->start_src != TRIG_NOW &&
826 cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) {
827 cmd->start_src = TRIG_NOW;
828 err++;
829 }
830
831 if (cmd->scan_begin_src != TRIG_TIMER &&
832 cmd->scan_begin_src != TRIG_EXT &&
833 cmd->scan_begin_src != TRIG_INT &&
834 cmd->scan_begin_src != TRIG_FOLLOW) {
835 cmd->scan_begin_src = TRIG_FOLLOW;
836 err++;
837 }
838
839 if (cmd->convert_src != TRIG_TIMER &&
840 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) {
841 cmd->convert_src = TRIG_TIMER;
842 err++;
843 }
844
845 if (cmd->scan_end_src != TRIG_COUNT) {
846 cmd->scan_end_src = TRIG_COUNT;
847 err++;
848 }
849
850 if (cmd->stop_src != TRIG_NONE &&
851 cmd->stop_src != TRIG_COUNT &&
852 cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) {
853 cmd->stop_src = TRIG_COUNT;
854 err++;
855 }
856
857 if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
858 cmd->start_src = TRIG_NOW;
859 err++;
860 }
861
862 if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) {
863 cmd->start_src = TRIG_NOW;
864 err++;
865 }
866
867 if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
868 (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) {
869 cmd->convert_src = TRIG_TIMER;
870 err++;
871 }
872
873 if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
874 (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) {
875 cmd->convert_src = TRIG_TIMER;
876 err++;
877 }
878
879 if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
880 cmd->stop_src = TRIG_COUNT;
881 err++;
882 }
883
884 if (err)
885 return 2;
886
887
888
889 if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
890 if (cmd->start_arg != 0) {
891 cmd->start_arg = 0;
892 err++;
893 }
894
895 if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
896 if (cmd->scan_begin_arg != 0) {
897 cmd->scan_begin_arg = 0;
898 err++;
899 }
900
901 if ((cmd->scan_begin_src == TRIG_TIMER) &&
902 (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
903 cmd->scan_begin_src = TRIG_FOLLOW;
904 cmd->convert_arg = cmd->scan_begin_arg;
905 cmd->scan_begin_arg = 0;
906 }
907
908 if (cmd->scan_begin_src == TRIG_TIMER)
909 if (cmd->scan_begin_arg < this_board->ai_ns_min) {
910 cmd->scan_begin_arg = this_board->ai_ns_min;
911 err++;
912 }
913
914 if (cmd->scan_begin_src == TRIG_EXT)
915 if (cmd->scan_begin_arg) {
916 cmd->scan_begin_arg = 0;
917 err++;
918 if (cmd->scan_end_arg > 65535) {
919 cmd->scan_end_arg = 65535;
920 err++;
921 }
922 }
923
924 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
925 if (cmd->convert_arg < this_board->ai_ns_min) {
926 cmd->convert_arg = this_board->ai_ns_min;
927 err++;
928 }
929
930 if (cmd->convert_src == TRIG_EXT)
931 if (cmd->convert_arg) {
932 cmd->convert_arg = 0;
933 err++;
934 }
935
936 if (cmd->stop_src == TRIG_COUNT) {
937 if (!cmd->stop_arg) {
938 cmd->stop_arg = 1;
939 err++;
940 }
941 } else {
942 if (cmd->stop_arg != 0) {
943 cmd->stop_arg = 0;
944 err++;
945 }
946 }
947
948 if (!cmd->chanlist_len) {
949 cmd->chanlist_len = 1;
950 err++;
951 }
952
953 if (cmd->chanlist_len > this_board->n_aichanlist) {
954 cmd->chanlist_len = this_board->n_aichanlist;
955 err++;
956 }
957
958 if (cmd->scan_end_arg < cmd->chanlist_len) {
959 cmd->scan_end_arg = cmd->chanlist_len;
960 err++;
961 }
962
963 if ((cmd->scan_end_arg % cmd->chanlist_len)) {
964 cmd->scan_end_arg =
965 cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
966 err++;
967 }
968
969 if (err)
970 return 3;
971
972
973
974 if (cmd->scan_begin_src == TRIG_TIMER) {
975 tmp = cmd->scan_begin_arg;
976
977 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
978 &divisor2, &cmd->scan_begin_arg,
979 cmd->flags & TRIG_ROUND_MASK);
980
981 if (cmd->scan_begin_arg < this_board->ai_ns_min)
982 cmd->scan_begin_arg = this_board->ai_ns_min;
983 if (tmp != cmd->scan_begin_arg)
984 err++;
985 }
986
987 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
988 tmp = cmd->convert_arg;
989 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
990 &divisor2, &cmd->convert_arg,
991 cmd->flags & TRIG_ROUND_MASK);
992
993 if (cmd->convert_arg < this_board->ai_ns_min)
994 cmd->convert_arg = this_board->ai_ns_min;
995 if (tmp != cmd->convert_arg)
996 err++;
997 if (cmd->scan_begin_src == TRIG_TIMER
998 && cmd->convert_src == TRIG_NOW) {
999 if (cmd->convert_arg == 0) {
1000 if (cmd->scan_begin_arg <
1001 this_board->ai_ns_min *
1002 (cmd->scan_end_arg + 2)) {
1003 cmd->scan_begin_arg =
1004 this_board->ai_ns_min *
1005 (cmd->scan_end_arg + 2);
1006
1007 err++;
1008 }
1009 } else {
1010 if (cmd->scan_begin_arg <
1011 cmd->convert_arg * cmd->chanlist_len) {
1012 cmd->scan_begin_arg =
1013 cmd->convert_arg *
1014 cmd->chanlist_len;
1015
1016 err++;
1017 }
1018 }
1019 }
1020 }
1021
1022 if (err)
1023 return 4;
1024
1025 if (cmd->chanlist)
1026 if (!check_channel_list(dev, s, cmd->chanlist_len,
1027 cmd->chanlist, 0, 0))
1028 return 5;
1029
1030 return 0;
1031}
1032
1033
1034
1035
1036static int Compute_and_setup_dma(struct comedi_device *dev)
1037{
1038 unsigned int dmalen0, dmalen1, i;
1039
1040 DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n");
1041 dmalen0 = devpriv->dmabuf_size[0];
1042 dmalen1 = devpriv->dmabuf_size[1];
1043 DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1,
1044 devpriv->ai_data_len);
1045
1046 if (dmalen0 > (devpriv->ai_data_len)) {
1047 dmalen0 = devpriv->ai_data_len & ~3L;
1048 }
1049 if (dmalen1 > (devpriv->ai_data_len)) {
1050 dmalen1 = devpriv->ai_data_len & ~3L;
1051 }
1052 DPRINTK("2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1053
1054
1055 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1056 if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
1057
1058 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1059 printk
1060 ("comedi%d: WAR: DMA0 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
1061 dev->minor, dmalen0,
1062 devpriv->ai_n_realscanlen << 1);
1063 } else {
1064
1065 dmalen0 = devpriv->ai_n_realscanlen << 1;
1066 DPRINTK
1067 ("21 dmalen0=%d ai_n_realscanlen=%d useeoshandle=%d\n",
1068 dmalen0, devpriv->ai_n_realscanlen,
1069 devpriv->useeoshandle);
1070 if (devpriv->useeoshandle)
1071 dmalen0 += 2;
1072 if (dmalen0 < 4) {
1073 printk
1074 ("comedi%d: ERR: DMA0 buf len bug? (%d<4)\n",
1075 dev->minor, dmalen0);
1076 dmalen0 = 4;
1077 }
1078 }
1079 }
1080 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1081 if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
1082
1083 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1084 printk
1085 ("comedi%d: WAR: DMA1 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
1086 dev->minor, dmalen1,
1087 devpriv->ai_n_realscanlen << 1);
1088 } else {
1089
1090 dmalen1 = devpriv->ai_n_realscanlen << 1;
1091 DPRINTK
1092 ("22 dmalen1=%d ai_n_realscanlen=%d useeoshandle=%d\n",
1093 dmalen1, devpriv->ai_n_realscanlen,
1094 devpriv->useeoshandle);
1095 if (devpriv->useeoshandle)
1096 dmalen1 -= 2;
1097 if (dmalen1 < 4) {
1098 printk
1099 ("comedi%d: ERR: DMA1 buf len bug? (%d<4)\n",
1100 dev->minor, dmalen1);
1101 dmalen1 = 4;
1102 }
1103 }
1104 }
1105
1106 DPRINTK("3 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1107
1108 if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
1109
1110 i = dmalen0;
1111 dmalen0 =
1112 (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
1113 (devpriv->ai_n_realscanlen << 1);
1114 dmalen0 &= ~3L;
1115 if (!dmalen0)
1116 dmalen0 = i;
1117 i = dmalen1;
1118 dmalen1 =
1119 (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
1120 (devpriv->ai_n_realscanlen << 1);
1121 dmalen1 &= ~3L;
1122 if (!dmalen1)
1123 dmalen1 = i;
1124
1125 if (!devpriv->ai_neverending) {
1126
1127 if (dmalen0 >
1128 ((devpriv->ai_n_realscanlen << 1) *
1129 devpriv->ai_scans)) {
1130 DPRINTK
1131 ("3.0 ai_n_realscanlen=%d ai_scans=%d \n",
1132 devpriv->ai_n_realscanlen,
1133 devpriv->ai_scans);
1134 dmalen0 =
1135 (devpriv->ai_n_realscanlen << 1) *
1136 devpriv->ai_scans;
1137 DPRINTK("3.1 dmalen0=%d dmalen1=%d \n", dmalen0,
1138 dmalen1);
1139 dmalen0 &= ~3L;
1140 } else {
1141 if (dmalen1 >
1142 ((devpriv->ai_n_realscanlen << 1) *
1143 devpriv->ai_scans - dmalen0))
1144 dmalen1 =
1145 (devpriv->ai_n_realscanlen << 1) *
1146 devpriv->ai_scans - dmalen0;
1147 DPRINTK("3.2 dmalen0=%d dmalen1=%d \n", dmalen0,
1148 dmalen1);
1149 dmalen1 &= ~3L;
1150 }
1151 }
1152 }
1153
1154 DPRINTK("4 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1155
1156
1157 devpriv->dma_actbuf = 0;
1158 devpriv->dmabuf_use_size[0] = dmalen0;
1159 devpriv->dmabuf_use_size[1] = dmalen1;
1160
1161 DPRINTK("5 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
1162#if 0
1163 if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
1164 devpriv->dmabuf_panic_size[0] =
1165 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1166 1) * devpriv->ai_n_scanlen * sizeof(short);
1167 devpriv->dmabuf_panic_size[1] =
1168 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1169 1) * devpriv->ai_n_scanlen * sizeof(short);
1170 } else {
1171 devpriv->dmabuf_panic_size[0] =
1172 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
1173 devpriv->dmabuf_panic_size[1] =
1174 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
1175 }
1176#endif
1177
1178 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR);
1179 outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
1180 outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
1181
1182 outl(0x00000000 | AINT_WRITE_COMPL,
1183 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1184
1185
1186 outl(inl(devpriv->iobase_a +
1187 AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
1188 EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
1189 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1190
1191 DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n");
1192 return 0;
1193}
1194
1195
1196
1197
1198static int pci9118_ai_docmd_sampl(struct comedi_device *dev,
1199 struct comedi_subdevice *s)
1200{
1201 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n",
1202 dev->minor, devpriv->ai_do);
1203 switch (devpriv->ai_do) {
1204 case 1:
1205 devpriv->AdControlReg |= AdControl_TmrTr;
1206 break;
1207 case 2:
1208 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
1209 return -EIO;
1210 case 3:
1211 devpriv->AdControlReg |= AdControl_ExtM;
1212 break;
1213 case 4:
1214 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
1215 return -EIO;
1216 default:
1217 comedi_error(dev,
1218 "pci9118_ai_docmd_sampl() mode number bug!\n");
1219 return -EIO;
1220 };
1221
1222 devpriv->int_ai_func = interrupt_pci9118_ai_onesample;
1223
1224 if (devpriv->ai12_startstop)
1225 pci9118_exttrg_add(dev, EXTTRG_AI);
1226
1227 if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
1228 devpriv->IntControlReg |= Int_Timer;
1229
1230 devpriv->AdControlReg |= AdControl_Int;
1231
1232 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1233
1234 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1235 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1236 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1237 if (devpriv->ai_do != 3) {
1238 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1239 devpriv->ai_divisor2);
1240 devpriv->AdControlReg |= AdControl_SoftG;
1241 }
1242 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1243 }
1244
1245 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n");
1246 return 0;
1247}
1248
1249
1250
1251
1252static int pci9118_ai_docmd_dma(struct comedi_device *dev,
1253 struct comedi_subdevice *s)
1254{
1255 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n",
1256 dev->minor, devpriv->ai_do, devpriv->usedma);
1257 Compute_and_setup_dma(dev);
1258
1259 switch (devpriv->ai_do) {
1260 case 1:
1261 devpriv->AdControlReg |=
1262 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1263 break;
1264 case 2:
1265 devpriv->AdControlReg |=
1266 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1267 devpriv->AdFunctionReg =
1268 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
1269 AdFunction_BS;
1270 if (devpriv->usessh && (!devpriv->softsshdelay))
1271 devpriv->AdFunctionReg |= AdFunction_BSSH;
1272 outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
1273 break;
1274 case 3:
1275 devpriv->AdControlReg |=
1276 ((AdControl_ExtM | AdControl_Dma) & 0xff);
1277 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1278 break;
1279 case 4:
1280 devpriv->AdControlReg |=
1281 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1282 devpriv->AdFunctionReg =
1283 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
1284 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1285 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1286 outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
1287 dev->iobase + PCI9118_CNT0);
1288 outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
1289 dev->iobase + PCI9118_CNT0);
1290 devpriv->AdFunctionReg |= AdFunction_Start;
1291 break;
1292 default:
1293 comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
1294 return -EIO;
1295 };
1296
1297 if (devpriv->ai12_startstop) {
1298 pci9118_exttrg_add(dev, EXTTRG_AI);
1299 }
1300
1301 devpriv->int_ai_func = interrupt_pci9118_ai_dma;
1302
1303 outl(0x02000000 | AINT_WRITE_COMPL,
1304 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1305
1306 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1307 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1308 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1309 if (devpriv->ai_do != 3) {
1310 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1311 devpriv->ai_divisor2);
1312 devpriv->AdControlReg |= AdControl_SoftG;
1313 }
1314 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1315 }
1316
1317 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n");
1318 return 0;
1319}
1320
1321
1322
1323
1324static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1325{
1326 struct comedi_cmd *cmd = &s->async->cmd;
1327 unsigned int addchans = 0;
1328 int ret = 0;
1329
1330 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor);
1331 devpriv->ai12_startstop = 0;
1332 devpriv->ai_flags = cmd->flags;
1333 devpriv->ai_n_chan = cmd->chanlist_len;
1334 devpriv->ai_n_scanlen = cmd->scan_end_arg;
1335 devpriv->ai_chanlist = cmd->chanlist;
1336 devpriv->ai_data = s->async->prealloc_buf;
1337 devpriv->ai_data_len = s->async->prealloc_bufsz;
1338 devpriv->ai_timer1 = 0;
1339 devpriv->ai_timer2 = 0;
1340 devpriv->ai_add_front = 0;
1341 devpriv->ai_add_back = 0;
1342 devpriv->ai_maskerr = 0x10e;
1343
1344
1345 if (cmd->start_src == TRIG_EXT)
1346 devpriv->ai12_startstop |= START_AI_EXT;
1347 if (cmd->stop_src == TRIG_EXT) {
1348 devpriv->ai_neverending = 1;
1349 devpriv->ai12_startstop |= STOP_AI_EXT;
1350 }
1351 if (cmd->start_src == TRIG_INT) {
1352 devpriv->ai12_startstop |= START_AI_INT;
1353 devpriv->ai_inttrig_start = cmd->start_arg;
1354 s->async->inttrig = pci9118_ai_inttrig;
1355 }
1356#if 0
1357 if (cmd->stop_src == TRIG_INT) {
1358 devpriv->ai_neverending = 1;
1359 devpriv->ai12_startstop |= STOP_AI_INT;
1360 }
1361#endif
1362 if (cmd->stop_src == TRIG_NONE)
1363 devpriv->ai_neverending = 1;
1364 if (cmd->stop_src == TRIG_COUNT) {
1365 devpriv->ai_scans = cmd->stop_arg;
1366 devpriv->ai_neverending = 0;
1367 } else {
1368 devpriv->ai_scans = 0;
1369 }
1370
1371
1372 if (cmd->convert_src == TRIG_NOW) {
1373 devpriv->usessh = 1;
1374 }
1375 else {
1376 devpriv->usessh = 0;
1377 }
1378
1379 DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n",
1380 devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh,
1381 devpriv->ai12_startstop);
1382
1383
1384 devpriv->ai_add_front = 0;
1385 devpriv->ai_add_back = 0;
1386 devpriv->useeoshandle = 0;
1387 if (devpriv->master) {
1388 devpriv->usedma = 1;
1389 if ((cmd->flags & TRIG_WAKE_EOS) &&
1390 (devpriv->ai_n_scanlen == 1)) {
1391 if (cmd->convert_src == TRIG_NOW) {
1392 devpriv->ai_add_back = 1;
1393 }
1394 if (cmd->convert_src == TRIG_TIMER) {
1395 devpriv->usedma = 0;
1396 }
1397 }
1398 if ((cmd->flags & TRIG_WAKE_EOS) &&
1399 (devpriv->ai_n_scanlen & 1) &&
1400 (devpriv->ai_n_scanlen > 1)) {
1401 if (cmd->scan_begin_src == TRIG_FOLLOW) {
1402
1403 devpriv->usedma = 0;
1404 } else {
1405 devpriv->ai_add_back = 1;
1406 }
1407 }
1408 } else {
1409 devpriv->usedma = 0;
1410 }
1411
1412
1413 if (devpriv->usessh && devpriv->softsshdelay) {
1414 devpriv->ai_add_front = 2;
1415 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
1416 devpriv->ai_add_front++;
1417 devpriv->ai_add_back = 0;
1418 }
1419 if (cmd->convert_arg < this_board->ai_ns_min)
1420 cmd->convert_arg = this_board->ai_ns_min;
1421 addchans = devpriv->softsshdelay / cmd->convert_arg;
1422 if (devpriv->softsshdelay % cmd->convert_arg)
1423 addchans++;
1424 if (addchans > (devpriv->ai_add_front - 1)) {
1425 devpriv->ai_add_front = addchans + 1;
1426 if (devpriv->usedma == 1)
1427 if ((devpriv->ai_add_front +
1428 devpriv->ai_n_chan +
1429 devpriv->ai_add_back) & 1)
1430 devpriv->ai_add_front++;
1431 }
1432 }
1433
1434 devpriv->ai_n_realscanlen =
1435 (devpriv->ai_add_front + devpriv->ai_n_chan +
1436 devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
1437 devpriv->ai_n_chan);
1438
1439 DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
1440 devpriv->usedma,
1441 devpriv->ai_n_realscanlen, devpriv->ai_add_front,
1442 devpriv->ai_n_chan, devpriv->ai_add_back,
1443 devpriv->ai_n_scanlen);
1444
1445
1446 if (!check_channel_list(dev, s, devpriv->ai_n_chan,
1447 devpriv->ai_chanlist, devpriv->ai_add_front,
1448 devpriv->ai_add_back))
1449 return -EINVAL;
1450 if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
1451 devpriv->ai_chanlist, 0, devpriv->ai_add_front,
1452 devpriv->ai_add_back, devpriv->usedma,
1453 devpriv->useeoshandle))
1454 return -EINVAL;
1455
1456
1457
1458 if (((cmd->scan_begin_src == TRIG_FOLLOW) || (cmd->scan_begin_src == TRIG_EXT) || (cmd->scan_begin_src == TRIG_INT)) && (cmd->convert_src == TRIG_TIMER)) {
1459 if (cmd->scan_begin_src == TRIG_EXT) {
1460 devpriv->ai_do = 4;
1461 } else {
1462 devpriv->ai_do = 1;
1463 }
1464 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1465 &cmd->scan_begin_arg, &cmd->convert_arg,
1466 devpriv->ai_flags,
1467 devpriv->ai_n_realscanlen,
1468 &devpriv->ai_divisor1,
1469 &devpriv->ai_divisor2, devpriv->usessh,
1470 devpriv->ai_add_front);
1471 devpriv->ai_timer2 = cmd->convert_arg;
1472 }
1473
1474 if ((cmd->scan_begin_src == TRIG_TIMER) && ((cmd->convert_src == TRIG_TIMER) || (cmd->convert_src == TRIG_NOW))) {
1475 if (!devpriv->usedma) {
1476 comedi_error(dev,
1477 "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!");
1478 return -EIO;
1479 }
1480
1481 devpriv->ai_do = 2;
1482 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1483 &cmd->scan_begin_arg, &cmd->convert_arg,
1484 devpriv->ai_flags,
1485 devpriv->ai_n_realscanlen,
1486 &devpriv->ai_divisor1,
1487 &devpriv->ai_divisor2, devpriv->usessh,
1488 devpriv->ai_add_front);
1489 devpriv->ai_timer1 = cmd->scan_begin_arg;
1490 devpriv->ai_timer2 = cmd->convert_arg;
1491 }
1492
1493 if ((cmd->scan_begin_src == TRIG_FOLLOW)
1494 && (cmd->convert_src == TRIG_EXT)) {
1495 devpriv->ai_do = 3;
1496 }
1497
1498 start_pacer(dev, -1, 0, 0);
1499
1500 devpriv->AdControlReg = 0;
1501 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1502 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1503 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1504 udelay(1);
1505 outl(0, dev->iobase + PCI9118_DELFIFO);
1506 inl(dev->iobase + PCI9118_ADSTAT);
1507 inl(dev->iobase + PCI9118_INTSRC);
1508
1509 devpriv->ai_act_scan = 0;
1510 devpriv->ai_act_dmapos = 0;
1511 s->async->cur_chan = 0;
1512 devpriv->ai_buf_ptr = 0;
1513
1514 if (devpriv->usedma)
1515 ret = pci9118_ai_docmd_dma(dev, s);
1516 else
1517 ret = pci9118_ai_docmd_sampl(dev, s);
1518
1519 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
1520 return ret;
1521}
1522
1523
1524
1525
1526static int check_channel_list(struct comedi_device *dev,
1527 struct comedi_subdevice *s, int n_chan,
1528 unsigned int *chanlist, int frontadd, int backadd)
1529{
1530 unsigned int i, differencial = 0, bipolar = 0;
1531
1532
1533 if (n_chan < 1) {
1534 comedi_error(dev, "range/channel list is empty!");
1535 return 0;
1536 }
1537 if ((frontadd + n_chan + backadd) > s->len_chanlist) {
1538 printk
1539 ("comedi%d: range/channel list is too long for actual configuration (%d>%d)!",
1540 dev->minor, n_chan, s->len_chanlist - frontadd - backadd);
1541 return 0;
1542 }
1543
1544 if (CR_AREF(chanlist[0]) == AREF_DIFF)
1545 differencial = 1;
1546 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1547 bipolar = 1;
1548 if (n_chan > 1)
1549 for (i = 1; i < n_chan; i++) {
1550 if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
1551 (differencial)) {
1552 comedi_error(dev,
1553 "Differencial and single ended inputs cann't be mixtured!");
1554 return 0;
1555 }
1556 if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
1557 (bipolar)) {
1558 comedi_error(dev,
1559 "Bipolar and unipolar ranges cann't be mixtured!");
1560 return 0;
1561 }
1562 if ((!devpriv->usemux) & (differencial) &
1563 (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
1564 comedi_error(dev,
1565 "If AREF_DIFF is used then is available only first 8 channels!");
1566 return 0;
1567 }
1568 }
1569
1570 return 1;
1571}
1572
1573
1574
1575
1576static int setup_channel_list(struct comedi_device *dev,
1577 struct comedi_subdevice *s, int n_chan,
1578 unsigned int *chanlist, int rot, int frontadd,
1579 int backadd, int usedma, char useeos)
1580{
1581 unsigned int i, differencial = 0, bipolar = 0;
1582 unsigned int scanquad, gain, ssh = 0x00;
1583
1584 DPRINTK
1585 ("adl_pci9118 EDBG: BGN: setup_channel_list(%d,.,%d,.,%d,%d,%d,%d)\n",
1586 dev->minor, n_chan, rot, frontadd, backadd, usedma);
1587
1588 if (usedma == 1) {
1589 rot = 8;
1590 usedma = 0;
1591 }
1592
1593 if (CR_AREF(chanlist[0]) == AREF_DIFF)
1594 differencial = 1;
1595 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1596 bipolar = 1;
1597
1598
1599
1600 if (!bipolar) {
1601 devpriv->AdControlReg |= AdControl_UniP;
1602 } else {
1603 devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
1604 }
1605
1606 if (differencial) {
1607 devpriv->AdControlReg |= AdControl_Diff;
1608 } else {
1609 devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
1610 }
1611
1612 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1613
1614 outl(2, dev->iobase + PCI9118_SCANMOD);
1615 outl(0, dev->iobase + PCI9118_SCANMOD);
1616 outl(1, dev->iobase + PCI9118_SCANMOD);
1617
1618#ifdef PCI9118_PARANOIDCHECK
1619 devpriv->chanlistlen = n_chan;
1620 for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
1621 devpriv->chanlist[i] = 0x55aa;
1622#endif
1623
1624 if (frontadd) {
1625 ssh = devpriv->softsshsample;
1626 DPRINTK("FA: %04x: ", ssh);
1627 for (i = 0; i < frontadd; i++) {
1628 scanquad = CR_CHAN(chanlist[0]);
1629 gain = CR_RANGE(chanlist[0]);
1630 scanquad |= ((gain & 0x03) << 8);
1631 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1632 DPRINTK("%02x ", scanquad | ssh);
1633 ssh = devpriv->softsshhold;
1634 }
1635 DPRINTK("\n ");
1636 }
1637
1638 DPRINTK("SL: ", ssh);
1639 for (i = 0; i < n_chan; i++) {
1640 scanquad = CR_CHAN(chanlist[i]);
1641#ifdef PCI9118_PARANOIDCHECK
1642 devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
1643#endif
1644 gain = CR_RANGE(chanlist[i]);
1645 scanquad |= ((gain & 0x03) << 8);
1646 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1647 DPRINTK("%02x ", scanquad | ssh);
1648 }
1649 DPRINTK("\n ");
1650
1651 if (backadd) {
1652 DPRINTK("BA: %04x: ", ssh);
1653 for (i = 0; i < backadd; i++) {
1654 scanquad = CR_CHAN(chanlist[0]);
1655 gain = CR_RANGE(chanlist[0]);
1656 scanquad |= ((gain & 0x03) << 8);
1657 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1658 DPRINTK("%02x ", scanquad | ssh);
1659 }
1660 DPRINTK("\n ");
1661 }
1662#ifdef PCI9118_PARANOIDCHECK
1663 devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
1664 if (useeos) {
1665 for (i = 1; i < n_chan; i++) {
1666 devpriv->chanlist[(n_chan + i) ^ usedma] =
1667 (CR_CHAN(chanlist[i]) & 0xf) << rot;
1668 }
1669 devpriv->chanlist[(2 * n_chan) ^ usedma] = devpriv->chanlist[0 ^ usedma];
1670 useeos = 2;
1671 } else {
1672 useeos = 1;
1673 }
1674#ifdef PCI9118_EXTDEBUG
1675 DPRINTK("CHL: ");
1676 for (i = 0; i <= (useeos * n_chan); i++) {
1677 DPRINTK("%04x ", devpriv->chanlist[i]);
1678 }
1679 DPRINTK("\n ");
1680#endif
1681#endif
1682 outl(0, dev->iobase + PCI9118_SCANMOD);
1683
1684
1685 DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
1686 return 1;
1687}
1688
1689
1690
1691
1692
1693static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
1694 struct comedi_subdevice *s,
1695 unsigned int *tim1, unsigned int *tim2,
1696 unsigned int flags, int chans,
1697 unsigned int *div1, unsigned int *div2,
1698 char usessh, unsigned int chnsshfront)
1699{
1700 DPRINTK
1701 ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n",
1702 mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront);
1703 switch (mode) {
1704 case 1:
1705 case 4:
1706 if (*tim2 < this_board->ai_ns_min)
1707 *tim2 = this_board->ai_ns_min;
1708 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
1709 tim2, flags & TRIG_ROUND_NEAREST);
1710 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
1711 devpriv->i8254_osc_base, *div1, *div2, *tim1);
1712 break;
1713 case 2:
1714 if (*tim2 < this_board->ai_ns_min)
1715 *tim2 = this_board->ai_ns_min;
1716 DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1717 *tim1, *tim2);
1718 *div1 = *tim2 / devpriv->i8254_osc_base;
1719 DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1720 *tim1, *tim2);
1721 if (*div1 < this_board->ai_pacer_min)
1722 *div1 = this_board->ai_pacer_min;
1723 DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1724 *tim1, *tim2);
1725 *div2 = *tim1 / devpriv->i8254_osc_base;
1726 DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1727 *tim1, *tim2);
1728 *div2 = *div2 / *div1;
1729 DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1730 *tim1, *tim2);
1731 if (*div2 < chans)
1732 *div2 = chans;
1733 DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1734 *tim1, *tim2);
1735
1736 *tim2 = *div1 * devpriv->i8254_osc_base;
1737
1738 if (usessh & (chnsshfront == 0))
1739 if (*div2 < (chans + 2))
1740 *div2 = chans + 2;
1741
1742 DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1743 *tim1, *tim2);
1744 *tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
1745 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",
1746 devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2);
1747 break;
1748 }
1749 DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
1750 *div1, *div2);
1751}
1752
1753
1754
1755
1756static void start_pacer(struct comedi_device *dev, int mode,
1757 unsigned int divisor1, unsigned int divisor2)
1758{
1759 outl(0x74, dev->iobase + PCI9118_CNTCTRL);
1760 outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
1761
1762 udelay(1);
1763
1764 if ((mode == 1) || (mode == 2) || (mode == 4)) {
1765 outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
1766 outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
1767 outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
1768 outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
1769 }
1770}
1771
1772
1773
1774
1775static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
1776{
1777 if (source > 3)
1778 return -1;
1779 devpriv->exttrg_users |= (1 << source);
1780 devpriv->IntControlReg |= Int_DTrg;
1781 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1782 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1783 return 0;
1784}
1785
1786
1787
1788
1789static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
1790{
1791 if (source > 3)
1792 return -1;
1793 devpriv->exttrg_users &= ~(1 << source);
1794 if (!devpriv->exttrg_users) {
1795 devpriv->IntControlReg &= ~Int_DTrg;
1796 if (!devpriv->IntControlReg)
1797 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) & (~0x00001f00), devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1798 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1799 }
1800 return 0;
1801}
1802
1803
1804
1805
1806static int pci9118_ai_cancel(struct comedi_device *dev,
1807 struct comedi_subdevice *s)
1808{
1809 if (devpriv->usedma)
1810 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR);
1811 pci9118_exttrg_del(dev, EXTTRG_AI);
1812 start_pacer(dev, 0, 0, 0);
1813 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1814 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1815 devpriv->AdControlReg = 0x00;
1816 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1817 outl(0, dev->iobase + PCI9118_BURST);
1818 outl(1, dev->iobase + PCI9118_SCANMOD);
1819 outl(2, dev->iobase + PCI9118_SCANMOD);
1820 outl(0, dev->iobase + PCI9118_DELFIFO);
1821
1822 devpriv->ai_do = 0;
1823 devpriv->usedma = 0;
1824
1825 devpriv->ai_act_scan = 0;
1826 devpriv->ai_act_dmapos = 0;
1827 s->async->cur_chan = 0;
1828 s->async->inttrig = NULL;
1829 devpriv->ai_buf_ptr = 0;
1830 devpriv->ai_neverending = 0;
1831 devpriv->dma_actbuf = 0;
1832
1833 if (!devpriv->IntControlReg)
1834 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1835
1836 return 0;
1837}
1838
1839
1840
1841
1842static int pci9118_reset(struct comedi_device *dev)
1843{
1844 devpriv->IntControlReg = 0;
1845 devpriv->exttrg_users = 0;
1846 inl(dev->iobase + PCI9118_INTCTRL);
1847 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1848 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1849
1850 start_pacer(dev, 0, 0, 0);
1851 devpriv->AdControlReg = 0;
1852 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1853 outl(0, dev->iobase + PCI9118_BURST);
1854 outl(1, dev->iobase + PCI9118_SCANMOD);
1855 outl(2, dev->iobase + PCI9118_SCANMOD);
1856 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1857 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1858
1859 devpriv->ao_data[0] = 2047;
1860 devpriv->ao_data[1] = 2047;
1861 outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1);
1862 outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
1863 outl(0, dev->iobase + PCI9118_DO);
1864 udelay(10);
1865 inl(dev->iobase + PCI9118_AD_DATA);
1866 outl(0, dev->iobase + PCI9118_DELFIFO);
1867 outl(0, dev->iobase + PCI9118_INTSRC);
1868 inl(dev->iobase + PCI9118_ADSTAT);
1869 inl(dev->iobase + PCI9118_INTSRC);
1870 devpriv->AdControlReg = 0;
1871 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1872
1873 devpriv->cnt0_users = 0;
1874 devpriv->exttrg_users = 0;
1875
1876 return 0;
1877}
1878
1879
1880
1881
1882static int pci9118_attach(struct comedi_device *dev,
1883 struct comedi_devconfig *it)
1884{
1885 struct comedi_subdevice *s;
1886 int ret, pages, i;
1887 unsigned short master;
1888 unsigned int irq;
1889 unsigned long iobase_a, iobase_9;
1890 struct pci_dev *pcidev;
1891 int opt_bus, opt_slot;
1892 const char *errstr;
1893 unsigned char pci_bus, pci_slot, pci_func;
1894 u16 u16w;
1895
1896 printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name);
1897
1898 opt_bus = it->options[0];
1899 opt_slot = it->options[1];
1900 if (it->options[3] & 1) {
1901 master = 0;
1902 } else {
1903 master = 1;
1904 }
1905
1906 ret = alloc_private(dev, sizeof(struct pci9118_private));
1907 if (ret < 0) {
1908 printk(" - Allocation failed!\n");
1909 return -ENOMEM;
1910 }
1911
1912
1913 errstr = "not found!";
1914 pcidev = NULL;
1915 while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
1916 this_board->device_id,
1917 pcidev))) {
1918
1919 if (opt_bus || opt_slot) {
1920
1921 if (opt_bus != pcidev->bus->number
1922 || opt_slot != PCI_SLOT(pcidev->devfn))
1923 continue;
1924 }
1925
1926
1927
1928
1929 if (comedi_pci_enable(pcidev, "adl_pci9118")) {
1930 errstr =
1931 "failed to enable PCI device and request regions!";
1932 continue;
1933 }
1934 break;
1935 }
1936
1937 if (!pcidev) {
1938 if (opt_bus || opt_slot) {
1939 printk(" - Card at b:s %d:%d %s\n",
1940 opt_bus, opt_slot, errstr);
1941 } else {
1942 printk(" - Card %s\n", errstr);
1943 }
1944 return -EIO;
1945 }
1946
1947 if (master) {
1948 pci_set_master(pcidev);
1949 }
1950
1951 pci_bus = pcidev->bus->number;
1952 pci_slot = PCI_SLOT(pcidev->devfn);
1953 pci_func = PCI_FUNC(pcidev->devfn);
1954 irq = pcidev->irq;
1955 iobase_a = pci_resource_start(pcidev, 0);
1956 iobase_9 = pci_resource_start(pcidev, 2);
1957
1958 printk(", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, pci_slot,
1959 pci_func, iobase_9, iobase_a);
1960
1961 dev->iobase = iobase_9;
1962 dev->board_name = this_board->name;
1963
1964 devpriv->pcidev = pcidev;
1965 devpriv->iobase_a = iobase_a;
1966
1967 pci9118_reset(dev);
1968
1969 if (it->options[3] & 2)
1970 irq = 0;
1971 if (irq > 0) {
1972 if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
1973 "ADLink PCI-9118", dev)) {
1974 printk(", unable to allocate IRQ %d, DISABLING IT",
1975 irq);
1976 irq = 0;
1977 } else {
1978 printk(", irq=%u", irq);
1979 }
1980 } else {
1981 printk(", IRQ disabled");
1982 }
1983
1984 dev->irq = irq;
1985
1986 if (master) {
1987 devpriv->dma_doublebuf = 0;
1988 for (i = 0; i < 2; i++) {
1989 for (pages = 4; pages >= 0; pages--) {
1990 devpriv->dmabuf_virt[i] =
1991 (short *)__get_free_pages(GFP_KERNEL,
1992 pages);
1993 if (devpriv->dmabuf_virt[i])
1994 break;
1995 }
1996 if (devpriv->dmabuf_virt[i]) {
1997 devpriv->dmabuf_pages[i] = pages;
1998 devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
1999 devpriv->dmabuf_samples[i] =
2000 devpriv->dmabuf_size[i] >> 1;
2001 devpriv->dmabuf_hw[i] =
2002 virt_to_bus((void *)
2003 devpriv->dmabuf_virt[i]);
2004 }
2005 }
2006 if (!devpriv->dmabuf_virt[0]) {
2007 printk(", Can't allocate DMA buffer, DMA disabled!");
2008 master = 0;
2009 }
2010
2011 if (devpriv->dmabuf_virt[1])
2012 devpriv->dma_doublebuf = 1;
2013
2014 }
2015
2016 devpriv->master = master;
2017 if (devpriv->master)
2018 printk(", bus master");
2019 else
2020 printk(", no bus master");
2021
2022 devpriv->usemux = 0;
2023 if (it->options[2] > 0) {
2024 devpriv->usemux = it->options[2];
2025 if (devpriv->usemux > 256)
2026 devpriv->usemux = 256;
2027 if (it->options[4] > 0)
2028 if (devpriv->usemux > 128) {
2029 devpriv->usemux = 128;
2030 }
2031 printk(", ext. mux %d channels", devpriv->usemux);
2032 }
2033
2034 devpriv->softsshdelay = it->options[4];
2035 if (devpriv->softsshdelay < 0) {
2036 devpriv->softsshdelay = -devpriv->softsshdelay;
2037 devpriv->softsshsample = 0x80;
2038 devpriv->softsshhold = 0x00;
2039 } else {
2040 devpriv->softsshsample = 0x00;
2041 devpriv->softsshhold = 0x80;
2042 }
2043
2044 printk(".\n");
2045
2046 pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
2047 pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64);
2048
2049 ret = alloc_subdevices(dev, 4);
2050 if (ret < 0)
2051 return ret;
2052
2053 s = dev->subdevices + 0;
2054 dev->read_subdev = s;
2055 s->type = COMEDI_SUBD_AI;
2056 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2057 if (devpriv->usemux) {
2058 s->n_chan = devpriv->usemux;
2059 } else {
2060 s->n_chan = this_board->n_aichan;
2061 }
2062 s->maxdata = this_board->ai_maxdata;
2063 s->len_chanlist = this_board->n_aichanlist;
2064 s->range_table = this_board->rangelist_ai;
2065 s->cancel = pci9118_ai_cancel;
2066 s->insn_read = pci9118_insn_read_ai;
2067 if (dev->irq) {
2068 s->subdev_flags |= SDF_CMD_READ;
2069 s->do_cmdtest = pci9118_ai_cmdtest;
2070 s->do_cmd = pci9118_ai_cmd;
2071 s->munge = pci9118_ai_munge;
2072 }
2073
2074 s = dev->subdevices + 1;
2075 s->type = COMEDI_SUBD_AO;
2076 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2077 s->n_chan = this_board->n_aochan;
2078 s->maxdata = this_board->ao_maxdata;
2079 s->len_chanlist = this_board->n_aochan;
2080 s->range_table = this_board->rangelist_ao;
2081 s->insn_write = pci9118_insn_write_ao;
2082 s->insn_read = pci9118_insn_read_ao;
2083
2084 s = dev->subdevices + 2;
2085 s->type = COMEDI_SUBD_DI;
2086 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2087 s->n_chan = 4;
2088 s->maxdata = 1;
2089 s->len_chanlist = 4;
2090 s->range_table = &range_digital;
2091 s->io_bits = 0;
2092 s->insn_bits = pci9118_insn_bits_di;
2093
2094 s = dev->subdevices + 3;
2095 s->type = COMEDI_SUBD_DO;
2096 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2097 s->n_chan = 4;
2098 s->maxdata = 1;
2099 s->len_chanlist = 4;
2100 s->range_table = &range_digital;
2101 s->io_bits = 0xf;
2102 s->insn_bits = pci9118_insn_bits_do;
2103
2104 devpriv->valid = 1;
2105 devpriv->i8254_osc_base = 250;
2106 devpriv->ai_maskharderr = 0x10a;
2107 if (it->options[5])
2108 devpriv->ai_maskharderr &= ~it->options[5];
2109
2110 switch (this_board->ai_maxdata) {
2111 case 0xffff:
2112 devpriv->ai16bits = 1;
2113 break;
2114 default:
2115 devpriv->ai16bits = 0;
2116 break;
2117 }
2118 return 0;
2119}
2120
2121
2122
2123
2124static int pci9118_detach(struct comedi_device *dev)
2125{
2126 if (dev->private) {
2127 if (devpriv->valid)
2128 pci9118_reset(dev);
2129 if (dev->irq)
2130 free_irq(dev->irq, dev);
2131 if (devpriv->pcidev) {
2132 if (dev->iobase) {
2133 comedi_pci_disable(devpriv->pcidev);
2134 }
2135 pci_dev_put(devpriv->pcidev);
2136 }
2137 if (devpriv->dmabuf_virt[0])
2138 free_pages((unsigned long)devpriv->dmabuf_virt[0],
2139 devpriv->dmabuf_pages[0]);
2140 if (devpriv->dmabuf_virt[1])
2141 free_pages((unsigned long)devpriv->dmabuf_virt[1],
2142 devpriv->dmabuf_pages[1]);
2143 }
2144
2145 return 0;
2146}
2147
2148
2149
2150
2151