2 * comedi/drivers/adl_pci9118.c
4 * hardware driver for ADLink cards:
5 * card: PCI-9118DG, PCI-9118HG, PCI-9118HR
6 * driver: pci9118dg, pci9118hg, pci9118hr
8 * Author: Michal Dobes <dobes@tesnet.cz>
13 Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
14 Author: Michal Dobes <dobes@tesnet.cz>
15 Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
16 PCI-9118HR (pci9118hr)
19 This driver supports AI, AO, DI and DO subdevices.
20 AI subdevice supports cmd and insn interface,
21 other subdevices support only insn interface.
23 - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
24 - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
25 - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
26 - It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
27 cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
28 - If return value of cmdtest is 5 then you've bad channel list
29 (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
32 There are some hardware limitations:
33 a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
35 b) DMA transfers must have the length aligned to two samples (32 bit),
36 so there is some problems if cmd->chanlist_len is odd. This driver tries
37 bypass this with adding one sample to the end of the every scan and discard
38 it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
39 and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
40 with interrupt after every sample.
41 c) If isn't used DMA then you can use only mode where
42 cmd->scan_begin_src=TRIG_FOLLOW.
44 Configuration options:
45 [0] - PCI bus of device (optional)
46 [1] - PCI slot of device (optional)
47 If bus/slot is not specified, then first available PCI
49 [2] - 0= standard 8 DIFF/16 SE channels configuration
50 n = external multiplexer connected, 1 <= n <= 256
51 [3] - 0=autoselect DMA or EOC interrupts operation
53 3 = disable DMA and INT, only insn interface will work
54 [4] - sample&hold signal - card can generate signal for external S&H board
55 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
56 0 != use ADCHN7(pin 23) signal is generated from driver, number say how
57 long delay is requested in ns and sign polarity of the hold
58 (in this case external multiplexor can serve only 128 channels)
59 [5] - 0=stop measure on all hardware errors
60 2 | = ignore ADOR - A/D Overrun status
61 8|=ignore Bover - A/D Burst Mode Overrun status
62 256|=ignore nFull - A/D FIFO Full status
69 * All the supported boards have the same PCI vendor and device IDs, so
70 * auto-attachment of PCI devices will always find the first board type.
72 * Perhaps the boards have different subdevice IDs that we could use to
75 * Need some device attributes so the board type can be corrected after
76 * attachment if necessary, and possibly to set other options supported by
79 #include "../comedidev.h"
81 #include <linux/delay.h>
82 #include <linux/gfp.h>
83 #include <linux/interrupt.h>
86 #include "amcc_s5933.h"
88 #include "comedi_fc.h"
90 /* paranoid checks are broken */
91 #undef PCI9118_PARANOIDCHECK /*
92 * if defined, then is used code which control
93 * correct channel number on every 12 bit sample
96 #define IORANGE_9118 64 /* I hope */
97 #define PCI9118_CHANLEN 255 /*
98 * len of chanlist, some source say 256,
99 * but reality looks like 255 :-(
102 #define PCI9118_CNT0 0x00 /* R/W: 8254 counter 0 */
103 #define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */
104 #define PCI9118_CNT2 0x08 /* R/W: 8254 counter 0 */
105 #define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
106 #define PCI9118_AD_DATA 0x10 /* R: A/D data */
107 #define PCI9118_DA1 0x10 /* W: D/A registers */
108 #define PCI9118_DA2 0x14
109 #define PCI9118_ADSTAT 0x18 /* R: A/D status register */
110 #define PCI9118_ADCNTRL 0x18 /* W: A/D control register */
111 #define PCI9118_DI 0x1c /* R: digi input register */
112 #define PCI9118_DO 0x1c /* W: digi output register */
113 #define PCI9118_SOFTTRG 0x20 /* W: soft trigger for A/D */
114 #define PCI9118_GAIN 0x24 /* W: A/D gain/channel register */
115 #define PCI9118_BURST 0x28 /* W: A/D burst number register */
116 #define PCI9118_SCANMOD 0x2c /* W: A/D auto scan mode */
117 #define PCI9118_ADFUNC 0x30 /* W: A/D function register */
118 #define PCI9118_DELFIFO 0x34 /* W: A/D data FIFO reset */
119 #define PCI9118_INTSRC 0x38 /* R: interrupt reason register */
120 #define PCI9118_INTCTRL 0x38 /* W: interrupt control register */
122 /* bits from A/D control register (PCI9118_ADCNTRL) */
123 #define AdControl_UniP 0x80 /* 1=bipolar, 0=unipolar */
124 #define AdControl_Diff 0x40 /* 1=differential, 0= single end inputs */
125 #define AdControl_SoftG 0x20 /* 1=8254 counter works, 0=counter stops */
126 #define AdControl_ExtG 0x10 /*
127 * 1=8254 countrol controlled by TGIN(pin 46),
128 * 0=controlled by SoftG
130 #define AdControl_ExtM 0x08 /*
131 * 1=external hardware trigger (pin 44),
134 #define AdControl_TmrTr 0x04 /*
135 * 1=8254 is iternal trigger source,
136 * 0=software trigger is source
137 * (register PCI9118_SOFTTRG)
139 #define AdControl_Int 0x02 /* 1=enable INT, 0=disable */
140 #define AdControl_Dma 0x01 /* 1=enable DMA, 0=disable */
142 /* bits from A/D function register (PCI9118_ADFUNC) */
143 #define AdFunction_PDTrg 0x80 /*
145 * 0=negative digital trigger
146 * (only positive is correct)
148 #define AdFunction_PETrg 0x40 /*
150 * 0=negative external trigger
151 * (only positive is correct)
153 #define AdFunction_BSSH 0x20 /* 1=with sample&hold, 0=without */
154 #define AdFunction_BM 0x10 /* 1=burst mode, 0=normal mode */
155 #define AdFunction_BS 0x08 /*
156 * 1=burst mode start,
159 #define AdFunction_PM 0x04 /*
160 * 1=post trigger mode,
163 #define AdFunction_AM 0x02 /*
164 * 1=about trigger mode,
165 * 0=not about trigger
167 #define AdFunction_Start 0x01 /* 1=trigger start, 0=trigger stop */
169 /* bits from A/D status register (PCI9118_ADSTAT) */
170 #define AdStatus_nFull 0x100 /* 0=FIFO full (fatal), 1=not full */
171 #define AdStatus_nHfull 0x080 /* 0=FIFO half full, 1=FIFO not half full */
172 #define AdStatus_nEpty 0x040 /* 0=FIFO empty, 1=FIFO not empty */
173 #define AdStatus_Acmp 0x020 /* */
174 #define AdStatus_DTH 0x010 /* 1=external digital trigger */
175 #define AdStatus_Bover 0x008 /* 1=burst mode overrun (fatal) */
176 #define AdStatus_ADOS 0x004 /* 1=A/D over speed (warning) */
177 #define AdStatus_ADOR 0x002 /* 1=A/D overrun (fatal) */
178 #define AdStatus_ADrdy 0x001 /* 1=A/D already ready, 0=not ready */
180 /* bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL) */
181 /* 1=interrupt occur, enable source, 0=interrupt not occur, disable source */
182 #define Int_Timer 0x08 /* timer interrupt */
183 #define Int_About 0x04 /* about trigger complete */
184 #define Int_Hfull 0x02 /* A/D FIFO hlaf full */
185 #define Int_DTrg 0x01 /* external digital trigger */
187 #define START_AI_EXT 0x01 /* start measure on external trigger */
188 #define STOP_AI_EXT 0x02 /* stop measure on external trigger */
189 #define START_AI_INT 0x04 /* start measure on internal trigger */
190 #define STOP_AI_INT 0x08 /* stop measure on internal trigger */
192 #define EXTTRG_AI 0 /* ext trg is used by AI */
194 static const struct comedi_lrange range_pci9118dg_hr
= { 8, {
206 static const struct comedi_lrange range_pci9118hg
= { 8, {
218 #define PCI9118_BIPOLAR_RANGES 4 /*
219 * used for test on mixture
224 const char *name
; /* board name */
225 int device_id
; /* PCI device ID of card */
226 int iorange_amcc
; /* iorange for own S5933 region */
227 int iorange_9118
; /* pass thru card region size */
228 int n_aichan
; /* num of A/D chans */
229 int n_aichand
; /* num of A/D chans in diff mode */
231 * num of A/D chans with
232 * external multiplexor
234 int n_aichanlist
; /* len of chanlist */
235 int n_aochan
; /* num of D/A chans */
236 int ai_maxdata
; /* resolution of A/D */
237 int ao_maxdata
; /* resolution of D/A */
238 const struct comedi_lrange
*rangelist_ai
; /* rangelist for A/D */
239 const struct comedi_lrange
*rangelist_ao
; /* rangelist for D/A */
240 unsigned int ai_ns_min
; /* max sample speed of card v ns */
241 unsigned int ai_pacer_min
; /*
242 * minimal pacer value
243 * (c1*c2 or c1 in burst)
245 int half_fifo_size
; /* size of FIFO/2 */
249 static const struct boardtype boardtypes
[] = {
253 .iorange_amcc
= AMCC_OP_REG_SIZE
,
254 .iorange_9118
= IORANGE_9118
,
258 .n_aichanlist
= PCI9118_CHANLEN
,
260 .ai_maxdata
= 0x0fff,
261 .ao_maxdata
= 0x0fff,
262 .rangelist_ai
= &range_pci9118dg_hr
,
263 .rangelist_ao
= &range_bipolar10
,
266 .half_fifo_size
= 512,
270 .iorange_amcc
= AMCC_OP_REG_SIZE
,
271 .iorange_9118
= IORANGE_9118
,
275 .n_aichanlist
= PCI9118_CHANLEN
,
277 .ai_maxdata
= 0x0fff,
278 .ao_maxdata
= 0x0fff,
279 .rangelist_ai
= &range_pci9118hg
,
280 .rangelist_ao
= &range_bipolar10
,
283 .half_fifo_size
= 512,
287 .iorange_amcc
= AMCC_OP_REG_SIZE
,
288 .iorange_9118
= IORANGE_9118
,
292 .n_aichanlist
= PCI9118_CHANLEN
,
294 .ai_maxdata
= 0xffff,
295 .ao_maxdata
= 0x0fff,
296 .rangelist_ai
= &range_pci9118dg_hr
,
297 .rangelist_ao
= &range_bipolar10
,
300 .half_fifo_size
= 512,
304 struct pci9118_private
{
305 unsigned long iobase_a
; /* base+size for AMCC chip */
306 unsigned int master
; /* master capable */
307 unsigned int usemux
; /* we want to use external multiplexor! */
308 #ifdef PCI9118_PARANOIDCHECK
309 unsigned short chanlist
[PCI9118_CHANLEN
+ 1]; /*
313 unsigned char chanlistlen
; /* number of scanlist */
315 unsigned char AdControlReg
; /* A/D control register */
316 unsigned char IntControlReg
; /* Interrupt control register */
317 unsigned char AdFunctionReg
; /* A/D function register */
318 char valid
; /* driver is ok */
319 char ai_neverending
; /* we do unlimited AI */
320 unsigned int i8254_osc_base
; /* frequence of onboard oscilator */
321 unsigned int ai_do
; /* what do AI? 0=nothing, 1 to 4 mode */
322 unsigned int ai_act_scan
; /* how many scans we finished */
323 unsigned int ai_buf_ptr
; /* data buffer ptr in samples */
324 unsigned int ai_n_chan
; /* how many channels is measured */
325 unsigned int ai_n_scanlen
; /* len of actual scanlist */
326 unsigned int ai_n_realscanlen
; /*
327 * what we must transfer for one
328 * outgoing scan include front/back adds
330 unsigned int ai_act_dmapos
; /* position in actual real stream */
331 unsigned int ai_add_front
; /*
332 * how many channels we must add
333 * before scan to satisfy S&H?
335 unsigned int ai_add_back
; /*
336 * how many channels we must add
337 * before scan to satisfy DMA?
339 unsigned int *ai_chanlist
; /* actual chanlist */
340 unsigned int ai_timer1
;
341 unsigned int ai_timer2
;
342 unsigned int ai_flags
;
343 char ai12_startstop
; /*
344 * measure can start/stop
345 * on external trigger
347 unsigned int ai_divisor1
, ai_divisor2
; /*
348 * divisors for start of measure
351 unsigned int ai_data_len
;
353 short ao_data
[2]; /* data output buffer */
354 unsigned int ai_scans
; /* number of scans to do */
355 char dma_doublebuf
; /* we can use double buffering */
356 unsigned int dma_actbuf
; /* which buffer is used now */
357 short *dmabuf_virt
[2]; /*
358 * pointers to begin of
361 unsigned long dmabuf_hw
[2]; /* hw address of DMA buff */
362 unsigned int dmabuf_size
[2]; /*
363 * size of dma buffer in bytes
365 unsigned int dmabuf_use_size
[2]; /*
366 * which size we may now use
369 unsigned int dmabuf_used_size
[2]; /* which size was truly used */
370 unsigned int dmabuf_panic_size
[2];
371 unsigned int dmabuf_samples
[2]; /* size in samples */
372 int dmabuf_pages
[2]; /* number of pages in buffer */
373 unsigned char cnt0_users
; /*
374 * bit field of 8254 CNT0 users
375 * (0-unused, 1-AO, 2-DI, 3-DO)
377 unsigned char exttrg_users
; /*
378 * bit field of external trigger
379 * users(0-AI, 1-AO, 2-DI, 3-DO)
381 unsigned int cnt0_divisor
; /* actual CNT0 divisor */
382 void (*int_ai_func
) (struct comedi_device
*, struct comedi_subdevice
*,
386 * ptr to actual interrupt
389 unsigned char ai16bits
; /* =1 16 bit card */
390 unsigned char usedma
; /* =1 use DMA transfer and not INT */
391 unsigned char useeoshandle
; /*
392 * =1 change WAKE_EOS DMA transfer
393 * to fit on every second
395 unsigned char usessh
; /* =1 turn on S&H support */
397 * >0 use software S&H,
398 * numer is requested delay in ns
400 unsigned char softsshsample
; /*
401 * polarity of S&H signal
404 unsigned char softsshhold
; /*
405 * polarity of S&H signal
408 unsigned int ai_maskerr
; /* which warning was printed */
409 unsigned int ai_maskharderr
; /* on which error bits stops */
410 unsigned int ai_inttrig_start
; /* TRIG_INT for start */
413 static int check_channel_list(struct comedi_device
*dev
,
414 struct comedi_subdevice
*s
, int n_chan
,
415 unsigned int *chanlist
, int frontadd
, int backadd
)
417 const struct boardtype
*this_board
= comedi_board(dev
);
418 struct pci9118_private
*devpriv
= dev
->private;
419 unsigned int i
, differencial
= 0, bipolar
= 0;
421 /* correct channel and range number check itself comedi/range.c */
423 comedi_error(dev
, "range/channel list is empty!");
426 if ((frontadd
+ n_chan
+ backadd
) > s
->len_chanlist
) {
428 "range/channel list is too long for actual configuration!\n");
432 if (CR_AREF(chanlist
[0]) == AREF_DIFF
)
433 differencial
= 1; /* all input must be diff */
434 if (CR_RANGE(chanlist
[0]) < PCI9118_BIPOLAR_RANGES
)
435 bipolar
= 1; /* all input must be bipolar */
437 for (i
= 1; i
< n_chan
; i
++) { /* check S.E/diff */
438 if ((CR_AREF(chanlist
[i
]) == AREF_DIFF
) !=
441 "Differencial and single ended "
442 "inputs can't be mixtured!");
445 if ((CR_RANGE(chanlist
[i
]) < PCI9118_BIPOLAR_RANGES
) !=
448 "Bipolar and unipolar ranges "
449 "can't be mixtured!");
452 if (!devpriv
->usemux
&& differencial
&&
453 (CR_CHAN(chanlist
[i
]) >= this_board
->n_aichand
)) {
455 "If AREF_DIFF is used then is "
456 "available only first 8 channels!");
464 static int setup_channel_list(struct comedi_device
*dev
,
465 struct comedi_subdevice
*s
, int n_chan
,
466 unsigned int *chanlist
, int rot
, int frontadd
,
467 int backadd
, int usedma
, char useeos
)
469 struct pci9118_private
*devpriv
= dev
->private;
470 unsigned int i
, differencial
= 0, bipolar
= 0;
471 unsigned int scanquad
, gain
, ssh
= 0x00;
478 if (CR_AREF(chanlist
[0]) == AREF_DIFF
)
479 differencial
= 1; /* all input must be diff */
480 if (CR_RANGE(chanlist
[0]) < PCI9118_BIPOLAR_RANGES
)
481 bipolar
= 1; /* all input must be bipolar */
483 /* All is ok, so we can setup channel/range list */
486 devpriv
->AdControlReg
|= AdControl_UniP
;
489 devpriv
->AdControlReg
&= ((~AdControl_UniP
) & 0xff);
494 devpriv
->AdControlReg
|= AdControl_Diff
;
495 /* enable diff inputs */
497 devpriv
->AdControlReg
&= ((~AdControl_Diff
) & 0xff);
498 /* set single ended inputs */
501 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
504 outl(2, dev
->iobase
+ PCI9118_SCANMOD
);
505 /* gods know why this sequence! */
506 outl(0, dev
->iobase
+ PCI9118_SCANMOD
);
507 outl(1, dev
->iobase
+ PCI9118_SCANMOD
);
509 #ifdef PCI9118_PARANOIDCHECK
510 devpriv
->chanlistlen
= n_chan
;
511 for (i
= 0; i
< (PCI9118_CHANLEN
+ 1); i
++)
512 devpriv
->chanlist
[i
] = 0x55aa;
515 if (frontadd
) { /* insert channels for S&H */
516 ssh
= devpriv
->softsshsample
;
517 for (i
= 0; i
< frontadd
; i
++) {
518 /* store range list to card */
519 scanquad
= CR_CHAN(chanlist
[0]);
520 /* get channel number; */
521 gain
= CR_RANGE(chanlist
[0]);
522 /* get gain number */
523 scanquad
|= ((gain
& 0x03) << 8);
524 outl(scanquad
| ssh
, dev
->iobase
+ PCI9118_GAIN
);
525 ssh
= devpriv
->softsshhold
;
529 for (i
= 0; i
< n_chan
; i
++) { /* store range list to card */
530 scanquad
= CR_CHAN(chanlist
[i
]); /* get channel number */
531 #ifdef PCI9118_PARANOIDCHECK
532 devpriv
->chanlist
[i
^ usedma
] = (scanquad
& 0xf) << rot
;
534 gain
= CR_RANGE(chanlist
[i
]); /* get gain number */
535 scanquad
|= ((gain
& 0x03) << 8);
536 outl(scanquad
| ssh
, dev
->iobase
+ PCI9118_GAIN
);
539 if (backadd
) { /* insert channels for fit onto 32bit DMA */
540 for (i
= 0; i
< backadd
; i
++) { /* store range list to card */
541 scanquad
= CR_CHAN(chanlist
[0]);
542 /* get channel number */
543 gain
= CR_RANGE(chanlist
[0]); /* get gain number */
544 scanquad
|= ((gain
& 0x03) << 8);
545 outl(scanquad
| ssh
, dev
->iobase
+ PCI9118_GAIN
);
548 #ifdef PCI9118_PARANOIDCHECK
549 devpriv
->chanlist
[n_chan
^ usedma
] = devpriv
->chanlist
[0 ^ usedma
];
550 /* for 32bit operations */
552 for (i
= 1; i
< n_chan
; i
++) { /* store range list to card */
553 devpriv
->chanlist
[(n_chan
+ i
) ^ usedma
] =
554 (CR_CHAN(chanlist
[i
]) & 0xf) << rot
;
556 devpriv
->chanlist
[(2 * n_chan
) ^ usedma
] =
557 devpriv
->chanlist
[0 ^ usedma
];
558 /* for 32bit operations */
564 outl(0, dev
->iobase
+ PCI9118_SCANMOD
); /* close scan queue */
565 /* udelay(100); important delay, or first sample will be crippled */
567 return 1; /* we can serve this with scan logic */
570 static int pci9118_insn_read_ai(struct comedi_device
*dev
,
571 struct comedi_subdevice
*s
,
572 struct comedi_insn
*insn
, unsigned int *data
)
574 struct pci9118_private
*devpriv
= dev
->private;
577 devpriv
->AdControlReg
= AdControl_Int
& 0xff;
578 devpriv
->AdFunctionReg
= AdFunction_PDTrg
| AdFunction_PETrg
;
579 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
581 * positive triggers, no S&H,
582 * no burst, burst stop,
588 if (!setup_channel_list(dev
, s
, 1, &insn
->chanspec
, 0, 0, 0, 0, 0))
591 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
593 for (n
= 0; n
< insn
->n
; n
++) {
594 outw(0, dev
->iobase
+ PCI9118_SOFTTRG
); /* start conversion */
598 if (inl(dev
->iobase
+ PCI9118_ADSTAT
) & AdStatus_ADrdy
)
603 comedi_error(dev
, "A/D insn timeout");
605 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
609 if (devpriv
->ai16bits
) {
612 PCI9118_AD_DATA
) & 0xffff) ^ 0x8000;
615 (inw(dev
->iobase
+ PCI9118_AD_DATA
) >> 4) & 0xfff;
619 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
624 static int pci9118_insn_write_ao(struct comedi_device
*dev
,
625 struct comedi_subdevice
*s
,
626 struct comedi_insn
*insn
, unsigned int *data
)
628 struct pci9118_private
*devpriv
= dev
->private;
631 ch
= CR_CHAN(insn
->chanspec
);
633 chanreg
= PCI9118_DA2
;
635 chanreg
= PCI9118_DA1
;
638 for (n
= 0; n
< insn
->n
; n
++) {
639 outl(data
[n
], dev
->iobase
+ chanreg
);
640 devpriv
->ao_data
[ch
] = data
[n
];
646 static int pci9118_insn_read_ao(struct comedi_device
*dev
,
647 struct comedi_subdevice
*s
,
648 struct comedi_insn
*insn
, unsigned int *data
)
650 struct pci9118_private
*devpriv
= dev
->private;
653 chan
= CR_CHAN(insn
->chanspec
);
654 for (n
= 0; n
< insn
->n
; n
++)
655 data
[n
] = devpriv
->ao_data
[chan
];
660 static int pci9118_insn_bits_di(struct comedi_device
*dev
,
661 struct comedi_subdevice
*s
,
662 struct comedi_insn
*insn
, unsigned int *data
)
664 data
[1] = inl(dev
->iobase
+ PCI9118_DI
) & 0xf;
669 static int pci9118_insn_bits_do(struct comedi_device
*dev
,
670 struct comedi_subdevice
*s
,
671 struct comedi_insn
*insn
, unsigned int *data
)
674 s
->state
&= ~data
[0];
675 s
->state
|= (data
[0] & data
[1]);
676 outl(s
->state
& 0x0f, dev
->iobase
+ PCI9118_DO
);
683 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device
*dev
)
685 struct pci9118_private
*devpriv
= dev
->private;
687 devpriv
->AdFunctionReg
=
688 AdFunction_PDTrg
| AdFunction_PETrg
| AdFunction_AM
;
689 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
690 outl(0x30, dev
->iobase
+ PCI9118_CNTCTRL
);
691 outl((devpriv
->dmabuf_hw
[1 - devpriv
->dma_actbuf
] >> 1) & 0xff,
692 dev
->iobase
+ PCI9118_CNT0
);
693 outl((devpriv
->dmabuf_hw
[1 - devpriv
->dma_actbuf
] >> 9) & 0xff,
694 dev
->iobase
+ PCI9118_CNT0
);
695 devpriv
->AdFunctionReg
|= AdFunction_Start
;
696 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
699 static unsigned int defragment_dma_buffer(struct comedi_device
*dev
,
700 struct comedi_subdevice
*s
,
702 unsigned int num_samples
)
704 struct pci9118_private
*devpriv
= dev
->private;
705 unsigned int i
= 0, j
= 0;
706 unsigned int start_pos
= devpriv
->ai_add_front
,
707 stop_pos
= devpriv
->ai_add_front
+ devpriv
->ai_n_chan
;
708 unsigned int raw_scanlen
= devpriv
->ai_add_front
+ devpriv
->ai_n_chan
+
709 devpriv
->ai_add_back
;
711 for (i
= 0; i
< num_samples
; i
++) {
712 if (devpriv
->ai_act_dmapos
>= start_pos
&&
713 devpriv
->ai_act_dmapos
< stop_pos
) {
714 dma_buffer
[j
++] = dma_buffer
[i
];
716 devpriv
->ai_act_dmapos
++;
717 devpriv
->ai_act_dmapos
%= raw_scanlen
;
723 static int move_block_from_dma(struct comedi_device
*dev
,
724 struct comedi_subdevice
*s
,
726 unsigned int num_samples
)
728 struct pci9118_private
*devpriv
= dev
->private;
729 unsigned int num_bytes
;
731 num_samples
= defragment_dma_buffer(dev
, s
, dma_buffer
, num_samples
);
732 devpriv
->ai_act_scan
+=
733 (s
->async
->cur_chan
+ num_samples
) / devpriv
->ai_n_scanlen
;
734 s
->async
->cur_chan
+= num_samples
;
735 s
->async
->cur_chan
%= devpriv
->ai_n_scanlen
;
737 cfc_write_array_to_buffer(s
, dma_buffer
,
738 num_samples
* sizeof(short));
739 if (num_bytes
< num_samples
* sizeof(short))
744 static int pci9118_exttrg_add(struct comedi_device
*dev
, unsigned char source
)
746 struct pci9118_private
*devpriv
= dev
->private;
749 return -1; /* incorrect source */
750 devpriv
->exttrg_users
|= (1 << source
);
751 devpriv
->IntControlReg
|= Int_DTrg
;
752 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
753 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
) | 0x1f00,
754 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
755 /* allow INT in AMCC */
759 static int pci9118_exttrg_del(struct comedi_device
*dev
, unsigned char source
)
761 struct pci9118_private
*devpriv
= dev
->private;
764 return -1; /* incorrect source */
765 devpriv
->exttrg_users
&= ~(1 << source
);
766 if (!devpriv
->exttrg_users
) { /* shutdown ext trg intterrupts */
767 devpriv
->IntControlReg
&= ~Int_DTrg
;
768 if (!devpriv
->IntControlReg
) /* all IRQ disabled */
769 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
) &
771 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
772 /* disable int in AMCC */
773 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
778 static void pci9118_calc_divisors(char mode
, struct comedi_device
*dev
,
779 struct comedi_subdevice
*s
,
780 unsigned int *tim1
, unsigned int *tim2
,
781 unsigned int flags
, int chans
,
782 unsigned int *div1
, unsigned int *div2
,
783 char usessh
, unsigned int chnsshfront
)
785 const struct boardtype
*this_board
= comedi_board(dev
);
786 struct pci9118_private
*devpriv
= dev
->private;
791 if (*tim2
< this_board
->ai_ns_min
)
792 *tim2
= this_board
->ai_ns_min
;
793 i8253_cascade_ns_to_timer(devpriv
->i8254_osc_base
, div1
, div2
,
794 tim2
, flags
& TRIG_ROUND_NEAREST
);
797 if (*tim2
< this_board
->ai_ns_min
)
798 *tim2
= this_board
->ai_ns_min
;
799 *div1
= *tim2
/ devpriv
->i8254_osc_base
;
800 /* convert timer (burst) */
801 if (*div1
< this_board
->ai_pacer_min
)
802 *div1
= this_board
->ai_pacer_min
;
803 *div2
= *tim1
/ devpriv
->i8254_osc_base
; /* scan timer */
804 *div2
= *div2
/ *div1
; /* major timer is c1*c2 */
808 *tim2
= *div1
* devpriv
->i8254_osc_base
;
809 /* real convert timer */
811 if (usessh
& (chnsshfront
== 0)) /* use BSSH signal */
812 if (*div2
< (chans
+ 2))
815 *tim1
= *div1
* *div2
* devpriv
->i8254_osc_base
;
820 static void start_pacer(struct comedi_device
*dev
, int mode
,
821 unsigned int divisor1
, unsigned int divisor2
)
823 outl(0x74, dev
->iobase
+ PCI9118_CNTCTRL
);
824 outl(0xb4, dev
->iobase
+ PCI9118_CNTCTRL
);
825 /* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
828 if ((mode
== 1) || (mode
== 2) || (mode
== 4)) {
829 outl(divisor2
& 0xff, dev
->iobase
+ PCI9118_CNT2
);
830 outl((divisor2
>> 8) & 0xff, dev
->iobase
+ PCI9118_CNT2
);
831 outl(divisor1
& 0xff, dev
->iobase
+ PCI9118_CNT1
);
832 outl((divisor1
>> 8) & 0xff, dev
->iobase
+ PCI9118_CNT1
);
836 static int pci9118_ai_cancel(struct comedi_device
*dev
,
837 struct comedi_subdevice
*s
)
839 struct pci9118_private
*devpriv
= dev
->private;
842 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
) &
844 devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
); /* stop DMA */
845 pci9118_exttrg_del(dev
, EXTTRG_AI
);
846 start_pacer(dev
, 0, 0, 0); /* stop 8254 counters */
847 devpriv
->AdFunctionReg
= AdFunction_PDTrg
| AdFunction_PETrg
;
848 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
850 * positive triggers, no S&H, no burst,
851 * burst stop, no post trigger,
852 * no about trigger, trigger stop
854 devpriv
->AdControlReg
= 0x00;
855 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
857 * bipolar, S.E., use 8254, stop 8354,
858 * internal trigger, soft trigger,
859 * disable INT and DMA
861 outl(0, dev
->iobase
+ PCI9118_BURST
);
862 outl(1, dev
->iobase
+ PCI9118_SCANMOD
);
863 outl(2, dev
->iobase
+ PCI9118_SCANMOD
); /* reset scan queue */
864 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
869 devpriv
->ai_act_scan
= 0;
870 devpriv
->ai_act_dmapos
= 0;
871 s
->async
->cur_chan
= 0;
872 s
->async
->inttrig
= NULL
;
873 devpriv
->ai_buf_ptr
= 0;
874 devpriv
->ai_neverending
= 0;
875 devpriv
->dma_actbuf
= 0;
877 if (!devpriv
->IntControlReg
)
878 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
) | 0x1f00,
879 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
880 /* allow INT in AMCC */
885 static char pci9118_decode_error_status(struct comedi_device
*dev
,
886 struct comedi_subdevice
*s
,
889 struct pci9118_private
*devpriv
= dev
->private;
892 comedi_error(dev
, "A/D FIFO Full status (Fatal Error!)");
893 devpriv
->ai_maskerr
&= ~0x100L
;
897 "A/D Burst Mode Overrun Status (Fatal Error!)");
898 devpriv
->ai_maskerr
&= ~0x008L
;
901 comedi_error(dev
, "A/D Over Speed Status (Warning!)");
902 devpriv
->ai_maskerr
&= ~0x004L
;
905 comedi_error(dev
, "A/D Overrun Status (Fatal Error!)");
906 devpriv
->ai_maskerr
&= ~0x002L
;
908 if (m
& devpriv
->ai_maskharderr
) {
909 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
910 pci9118_ai_cancel(dev
, s
);
911 comedi_event(dev
, s
);
918 static void pci9118_ai_munge(struct comedi_device
*dev
,
919 struct comedi_subdevice
*s
, void *data
,
920 unsigned int num_bytes
,
921 unsigned int start_chan_index
)
923 struct pci9118_private
*devpriv
= dev
->private;
924 unsigned int i
, num_samples
= num_bytes
/ sizeof(short);
927 for (i
= 0; i
< num_samples
; i
++) {
929 array
[i
] = be16_to_cpu(array
[i
]);
930 if (devpriv
->ai16bits
)
933 array
[i
] = (array
[i
] >> 4) & 0x0fff;
938 static void interrupt_pci9118_ai_onesample(struct comedi_device
*dev
,
939 struct comedi_subdevice
*s
,
940 unsigned short int_adstat
,
941 unsigned int int_amcc
,
942 unsigned short int_daq
)
944 struct pci9118_private
*devpriv
= dev
->private;
945 register short sampl
;
947 s
->async
->events
= 0;
949 if (int_adstat
& devpriv
->ai_maskerr
)
950 if (pci9118_decode_error_status(dev
, s
, int_adstat
))
953 sampl
= inw(dev
->iobase
+ PCI9118_AD_DATA
);
955 #ifdef PCI9118_PARANOIDCHECK
956 if (devpriv
->ai16bits
== 0) {
957 if ((sampl
& 0x000f) != devpriv
->chanlist
[s
->async
->cur_chan
]) {
959 dev_info(dev
->class_dev
,
960 "A/D SAMPL - data dropout: received channel %d, expected %d!\n",
962 devpriv
->chanlist
[s
->async
->cur_chan
]);
963 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
964 pci9118_ai_cancel(dev
, s
);
965 comedi_event(dev
, s
);
970 cfc_write_to_buffer(s
, sampl
);
971 s
->async
->cur_chan
++;
972 if (s
->async
->cur_chan
>= devpriv
->ai_n_scanlen
) {
974 s
->async
->cur_chan
%= devpriv
->ai_n_scanlen
;
975 devpriv
->ai_act_scan
++;
976 if (!(devpriv
->ai_neverending
))
977 if (devpriv
->ai_act_scan
>= devpriv
->ai_scans
) {
978 /* all data sampled */
979 pci9118_ai_cancel(dev
, s
);
980 s
->async
->events
|= COMEDI_CB_EOA
;
984 if (s
->async
->events
)
985 comedi_event(dev
, s
);
988 static void interrupt_pci9118_ai_dma(struct comedi_device
*dev
,
989 struct comedi_subdevice
*s
,
990 unsigned short int_adstat
,
991 unsigned int int_amcc
,
992 unsigned short int_daq
)
994 struct pci9118_private
*devpriv
= dev
->private;
995 unsigned int next_dma_buf
, samplesinbuf
, sampls
, m
;
997 if (int_amcc
& MASTER_ABORT_INT
) {
998 comedi_error(dev
, "AMCC IRQ - MASTER DMA ABORT!");
999 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
1000 pci9118_ai_cancel(dev
, s
);
1001 comedi_event(dev
, s
);
1005 if (int_amcc
& TARGET_ABORT_INT
) {
1006 comedi_error(dev
, "AMCC IRQ - TARGET DMA ABORT!");
1007 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
1008 pci9118_ai_cancel(dev
, s
);
1009 comedi_event(dev
, s
);
1012 if (int_adstat
& devpriv
->ai_maskerr
)
1013 /* if (int_adstat & 0x106) */
1014 if (pci9118_decode_error_status(dev
, s
, int_adstat
))
1017 samplesinbuf
= devpriv
->dmabuf_use_size
[devpriv
->dma_actbuf
] >> 1;
1018 /* number of received real samples */
1020 if (devpriv
->dma_doublebuf
) { /*
1021 * switch DMA buffers if is used
1024 next_dma_buf
= 1 - devpriv
->dma_actbuf
;
1025 outl(devpriv
->dmabuf_hw
[next_dma_buf
],
1026 devpriv
->iobase_a
+ AMCC_OP_REG_MWAR
);
1027 outl(devpriv
->dmabuf_use_size
[next_dma_buf
],
1028 devpriv
->iobase_a
+ AMCC_OP_REG_MWTC
);
1029 devpriv
->dmabuf_used_size
[next_dma_buf
] =
1030 devpriv
->dmabuf_use_size
[next_dma_buf
];
1031 if (devpriv
->ai_do
== 4)
1032 interrupt_pci9118_ai_mode4_switch(dev
);
1036 m
= devpriv
->ai_data_len
>> 1; /*
1037 * how many samples is to
1041 move_block_from_dma(dev
, s
,
1042 devpriv
->dmabuf_virt
[devpriv
->dma_actbuf
],
1044 m
= m
- sampls
; /* m= how many samples was transferred */
1047 if (!devpriv
->ai_neverending
)
1048 if (devpriv
->ai_act_scan
>= devpriv
->ai_scans
) {
1049 /* all data sampled */
1050 pci9118_ai_cancel(dev
, s
);
1051 s
->async
->events
|= COMEDI_CB_EOA
;
1054 if (devpriv
->dma_doublebuf
) { /* switch dma buffers */
1055 devpriv
->dma_actbuf
= 1 - devpriv
->dma_actbuf
;
1056 } else { /* restart DMA if is not used double buffering */
1057 outl(devpriv
->dmabuf_hw
[0],
1058 devpriv
->iobase_a
+ AMCC_OP_REG_MWAR
);
1059 outl(devpriv
->dmabuf_use_size
[0],
1060 devpriv
->iobase_a
+ AMCC_OP_REG_MWTC
);
1061 if (devpriv
->ai_do
== 4)
1062 interrupt_pci9118_ai_mode4_switch(dev
);
1065 comedi_event(dev
, s
);
1068 static irqreturn_t
interrupt_pci9118(int irq
, void *d
)
1070 struct comedi_device
*dev
= d
;
1071 struct pci9118_private
*devpriv
= dev
->private;
1072 unsigned int int_daq
= 0, int_amcc
, int_adstat
;
1075 return IRQ_NONE
; /* not fully initialized */
1077 int_daq
= inl(dev
->iobase
+ PCI9118_INTSRC
) & 0xf;
1078 /* get IRQ reasons from card */
1079 int_amcc
= inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1080 /* get INT register from AMCC chip */
1082 if ((!int_daq
) && (!(int_amcc
& ANY_S593X_INT
)))
1083 return IRQ_NONE
; /* interrupt from other source */
1085 outl(int_amcc
| 0x00ff0000, devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1086 /* shutdown IRQ reasons in AMCC */
1088 int_adstat
= inw(dev
->iobase
+ PCI9118_ADSTAT
) & 0x1ff;
1089 /* get STATUS register */
1091 if (devpriv
->ai_do
) {
1092 if (devpriv
->ai12_startstop
)
1093 if ((int_adstat
& AdStatus_DTH
) &&
1094 (int_daq
& Int_DTrg
)) {
1095 /* start stop of measure */
1096 if (devpriv
->ai12_startstop
& START_AI_EXT
) {
1097 devpriv
->ai12_startstop
&=
1099 if (!(devpriv
->ai12_startstop
&
1103 /* deactivate EXT trigger */
1104 start_pacer(dev
, devpriv
->ai_do
,
1105 devpriv
->ai_divisor1
,
1106 devpriv
->ai_divisor2
);
1108 outl(devpriv
->AdControlReg
,
1109 dev
->iobase
+ PCI9118_ADCNTRL
);
1111 if (devpriv
->ai12_startstop
&
1113 devpriv
->ai12_startstop
&=
1117 /* deactivate EXT trigger */
1118 devpriv
->ai_neverending
= 0;
1120 * well, on next interrupt from
1121 * DMA/EOC measure will stop
1127 (devpriv
->int_ai_func
) (dev
, &dev
->subdevices
[0], int_adstat
,
1134 static int pci9118_ai_inttrig(struct comedi_device
*dev
,
1135 struct comedi_subdevice
*s
, unsigned int trignum
)
1137 struct pci9118_private
*devpriv
= dev
->private;
1139 if (trignum
!= devpriv
->ai_inttrig_start
)
1142 devpriv
->ai12_startstop
&= ~START_AI_INT
;
1143 s
->async
->inttrig
= NULL
;
1145 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
1146 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1147 if (devpriv
->ai_do
!= 3) {
1148 start_pacer(dev
, devpriv
->ai_do
, devpriv
->ai_divisor1
,
1149 devpriv
->ai_divisor2
);
1150 devpriv
->AdControlReg
|= AdControl_SoftG
;
1152 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
1157 static int pci9118_ai_cmdtest(struct comedi_device
*dev
,
1158 struct comedi_subdevice
*s
,
1159 struct comedi_cmd
*cmd
)
1161 const struct boardtype
*this_board
= comedi_board(dev
);
1162 struct pci9118_private
*devpriv
= dev
->private;
1166 unsigned int divisor1
= 0, divisor2
= 0;
1168 /* Step 1 : check if triggers are trivially valid */
1170 err
|= cfc_check_trigger_src(&cmd
->start_src
,
1171 TRIG_NOW
| TRIG_EXT
| TRIG_INT
);
1173 flags
= TRIG_FOLLOW
;
1174 if (devpriv
->master
)
1175 flags
|= TRIG_TIMER
| TRIG_EXT
;
1176 err
|= cfc_check_trigger_src(&cmd
->scan_begin_src
, flags
);
1178 flags
= TRIG_TIMER
| TRIG_EXT
;
1179 if (devpriv
->master
)
1181 err
|= cfc_check_trigger_src(&cmd
->convert_src
, flags
);
1183 err
|= cfc_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
1184 err
|= cfc_check_trigger_src(&cmd
->stop_src
,
1185 TRIG_COUNT
| TRIG_NONE
| TRIG_EXT
);
1190 /* Step 2a : make sure trigger sources are unique */
1192 err
|= cfc_check_trigger_is_unique(cmd
->start_src
);
1193 err
|= cfc_check_trigger_is_unique(cmd
->scan_begin_src
);
1194 err
|= cfc_check_trigger_is_unique(cmd
->convert_src
);
1195 err
|= cfc_check_trigger_is_unique(cmd
->stop_src
);
1197 /* Step 2b : and mutually compatible */
1199 if (cmd
->start_src
== TRIG_EXT
&& cmd
->scan_begin_src
== TRIG_EXT
)
1202 if (cmd
->start_src
== TRIG_INT
&& cmd
->scan_begin_src
== TRIG_INT
)
1205 if ((cmd
->scan_begin_src
& (TRIG_TIMER
| TRIG_EXT
)) &&
1206 (!(cmd
->convert_src
& (TRIG_TIMER
| TRIG_NOW
))))
1209 if ((cmd
->scan_begin_src
== TRIG_FOLLOW
) &&
1210 (!(cmd
->convert_src
& (TRIG_TIMER
| TRIG_EXT
))))
1213 if (cmd
->stop_src
== TRIG_EXT
&& cmd
->scan_begin_src
== TRIG_EXT
)
1219 /* Step 3: check if arguments are trivially valid */
1221 if (cmd
->start_src
& (TRIG_NOW
| TRIG_EXT
))
1222 err
|= cfc_check_trigger_arg_is(&cmd
->start_arg
, 0);
1224 if (cmd
->scan_begin_src
& (TRIG_FOLLOW
| TRIG_EXT
))
1225 err
|= cfc_check_trigger_arg_is(&cmd
->scan_begin_arg
, 0);
1227 if ((cmd
->scan_begin_src
== TRIG_TIMER
) &&
1228 (cmd
->convert_src
== TRIG_TIMER
) && (cmd
->scan_end_arg
== 1)) {
1229 cmd
->scan_begin_src
= TRIG_FOLLOW
;
1230 cmd
->convert_arg
= cmd
->scan_begin_arg
;
1231 cmd
->scan_begin_arg
= 0;
1234 if (cmd
->scan_begin_src
== TRIG_TIMER
)
1235 err
|= cfc_check_trigger_arg_min(&cmd
->scan_begin_arg
,
1236 this_board
->ai_ns_min
);
1238 if (cmd
->scan_begin_src
== TRIG_EXT
)
1239 if (cmd
->scan_begin_arg
) {
1240 cmd
->scan_begin_arg
= 0;
1242 err
|= cfc_check_trigger_arg_max(&cmd
->scan_end_arg
,
1246 if (cmd
->convert_src
& (TRIG_TIMER
| TRIG_NOW
))
1247 err
|= cfc_check_trigger_arg_min(&cmd
->convert_arg
,
1248 this_board
->ai_ns_min
);
1250 if (cmd
->convert_src
== TRIG_EXT
)
1251 err
|= cfc_check_trigger_arg_is(&cmd
->convert_arg
, 0);
1253 if (cmd
->stop_src
== TRIG_COUNT
)
1254 err
|= cfc_check_trigger_arg_min(&cmd
->stop_arg
, 1);
1255 else /* TRIG_NONE */
1256 err
|= cfc_check_trigger_arg_is(&cmd
->stop_arg
, 0);
1258 err
|= cfc_check_trigger_arg_min(&cmd
->chanlist_len
, 1);
1259 err
|= cfc_check_trigger_arg_max(&cmd
->chanlist_len
,
1260 this_board
->n_aichanlist
);
1262 err
|= cfc_check_trigger_arg_min(&cmd
->scan_end_arg
,
1265 if ((cmd
->scan_end_arg
% cmd
->chanlist_len
)) {
1267 cmd
->chanlist_len
* (cmd
->scan_end_arg
/ cmd
->chanlist_len
);
1274 /* step 4: fix up any arguments */
1276 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
1277 tmp
= cmd
->scan_begin_arg
;
1278 i8253_cascade_ns_to_timer(devpriv
->i8254_osc_base
, &divisor1
,
1279 &divisor2
, &cmd
->scan_begin_arg
,
1280 cmd
->flags
& TRIG_ROUND_MASK
);
1281 if (cmd
->scan_begin_arg
< this_board
->ai_ns_min
)
1282 cmd
->scan_begin_arg
= this_board
->ai_ns_min
;
1283 if (tmp
!= cmd
->scan_begin_arg
)
1287 if (cmd
->convert_src
& (TRIG_TIMER
| TRIG_NOW
)) {
1288 tmp
= cmd
->convert_arg
;
1289 i8253_cascade_ns_to_timer(devpriv
->i8254_osc_base
, &divisor1
,
1290 &divisor2
, &cmd
->convert_arg
,
1291 cmd
->flags
& TRIG_ROUND_MASK
);
1292 if (cmd
->convert_arg
< this_board
->ai_ns_min
)
1293 cmd
->convert_arg
= this_board
->ai_ns_min
;
1294 if (tmp
!= cmd
->convert_arg
)
1296 if (cmd
->scan_begin_src
== TRIG_TIMER
1297 && cmd
->convert_src
== TRIG_NOW
) {
1298 if (cmd
->convert_arg
== 0) {
1299 if (cmd
->scan_begin_arg
<
1300 this_board
->ai_ns_min
*
1301 (cmd
->scan_end_arg
+ 2)) {
1302 cmd
->scan_begin_arg
=
1303 this_board
->ai_ns_min
*
1304 (cmd
->scan_end_arg
+ 2);
1308 if (cmd
->scan_begin_arg
<
1309 cmd
->convert_arg
* cmd
->chanlist_len
) {
1310 cmd
->scan_begin_arg
=
1323 if (!check_channel_list(dev
, s
, cmd
->chanlist_len
,
1324 cmd
->chanlist
, 0, 0))
1325 return 5; /* incorrect channels list */
1330 static int Compute_and_setup_dma(struct comedi_device
*dev
)
1332 struct pci9118_private
*devpriv
= dev
->private;
1333 unsigned int dmalen0
, dmalen1
, i
;
1335 dmalen0
= devpriv
->dmabuf_size
[0];
1336 dmalen1
= devpriv
->dmabuf_size
[1];
1337 /* isn't output buff smaller that our DMA buff? */
1338 if (dmalen0
> (devpriv
->ai_data_len
)) {
1339 dmalen0
= devpriv
->ai_data_len
& ~3L; /*
1340 * align to 32bit down
1343 if (dmalen1
> (devpriv
->ai_data_len
)) {
1344 dmalen1
= devpriv
->ai_data_len
& ~3L; /*
1345 * align to 32bit down
1349 /* we want wake up every scan? */
1350 if (devpriv
->ai_flags
& TRIG_WAKE_EOS
) {
1351 if (dmalen0
< (devpriv
->ai_n_realscanlen
<< 1)) {
1352 /* uff, too short DMA buffer, disable EOS support! */
1353 devpriv
->ai_flags
&= (~TRIG_WAKE_EOS
);
1354 dev_info(dev
->class_dev
,
1355 "WAR: DMA0 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n",
1356 dmalen0
, devpriv
->ai_n_realscanlen
<< 1);
1358 /* short first DMA buffer to one scan */
1359 dmalen0
= devpriv
->ai_n_realscanlen
<< 1;
1360 if (devpriv
->useeoshandle
)
1363 dev_info(dev
->class_dev
,
1364 "ERR: DMA0 buf len bug? (%d<4)\n",
1370 if (devpriv
->ai_flags
& TRIG_WAKE_EOS
) {
1371 if (dmalen1
< (devpriv
->ai_n_realscanlen
<< 1)) {
1372 /* uff, too short DMA buffer, disable EOS support! */
1373 devpriv
->ai_flags
&= (~TRIG_WAKE_EOS
);
1374 dev_info(dev
->class_dev
,
1375 "WAR: DMA1 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n",
1376 dmalen1
, devpriv
->ai_n_realscanlen
<< 1);
1378 /* short second DMA buffer to one scan */
1379 dmalen1
= devpriv
->ai_n_realscanlen
<< 1;
1380 if (devpriv
->useeoshandle
)
1383 dev_info(dev
->class_dev
,
1384 "ERR: DMA1 buf len bug? (%d<4)\n",
1391 /* transfer without TRIG_WAKE_EOS */
1392 if (!(devpriv
->ai_flags
& TRIG_WAKE_EOS
)) {
1393 /* if it's possible then align DMA buffers to length of scan */
1396 (dmalen0
/ (devpriv
->ai_n_realscanlen
<< 1)) *
1397 (devpriv
->ai_n_realscanlen
<< 1);
1400 dmalen0
= i
; /* uff. very long scan? */
1403 (dmalen1
/ (devpriv
->ai_n_realscanlen
<< 1)) *
1404 (devpriv
->ai_n_realscanlen
<< 1);
1407 dmalen1
= i
; /* uff. very long scan? */
1409 * if measure isn't neverending then test, if it fits whole
1410 * into one or two DMA buffers
1412 if (!devpriv
->ai_neverending
) {
1413 /* fits whole measure into one DMA buffer? */
1415 ((devpriv
->ai_n_realscanlen
<< 1) *
1416 devpriv
->ai_scans
)) {
1418 (devpriv
->ai_n_realscanlen
<< 1) *
1422 * fits whole measure into
1426 ((devpriv
->ai_n_realscanlen
<< 1) *
1427 devpriv
->ai_scans
- dmalen0
))
1429 (devpriv
->ai_n_realscanlen
<< 1) *
1430 devpriv
->ai_scans
- dmalen0
;
1436 /* these DMA buffer size will be used */
1437 devpriv
->dma_actbuf
= 0;
1438 devpriv
->dmabuf_use_size
[0] = dmalen0
;
1439 devpriv
->dmabuf_use_size
[1] = dmalen1
;
1442 if (devpriv
->ai_n_scanlen
< this_board
->half_fifo_size
) {
1443 devpriv
->dmabuf_panic_size
[0] =
1444 (this_board
->half_fifo_size
/ devpriv
->ai_n_scanlen
+
1445 1) * devpriv
->ai_n_scanlen
* sizeof(short);
1446 devpriv
->dmabuf_panic_size
[1] =
1447 (this_board
->half_fifo_size
/ devpriv
->ai_n_scanlen
+
1448 1) * devpriv
->ai_n_scanlen
* sizeof(short);
1450 devpriv
->dmabuf_panic_size
[0] =
1451 (devpriv
->ai_n_scanlen
<< 1) % devpriv
->dmabuf_size
[0];
1452 devpriv
->dmabuf_panic_size
[1] =
1453 (devpriv
->ai_n_scanlen
<< 1) % devpriv
->dmabuf_size
[1];
1457 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
) & (~EN_A2P_TRANSFERS
),
1458 devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
); /* stop DMA */
1459 outl(devpriv
->dmabuf_hw
[0], devpriv
->iobase_a
+ AMCC_OP_REG_MWAR
);
1460 outl(devpriv
->dmabuf_use_size
[0], devpriv
->iobase_a
+ AMCC_OP_REG_MWTC
);
1461 /* init DMA transfer */
1462 outl(0x00000000 | AINT_WRITE_COMPL
,
1463 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1464 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
1466 outl(inl(devpriv
->iobase_a
+
1467 AMCC_OP_REG_MCSR
) | RESET_A2P_FLAGS
| A2P_HI_PRIORITY
|
1468 EN_A2P_TRANSFERS
, devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
);
1469 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
) | EN_A2P_TRANSFERS
,
1470 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1471 /* allow bus mastering */
1476 static int pci9118_ai_docmd_sampl(struct comedi_device
*dev
,
1477 struct comedi_subdevice
*s
)
1479 struct pci9118_private
*devpriv
= dev
->private;
1481 switch (devpriv
->ai_do
) {
1483 devpriv
->AdControlReg
|= AdControl_TmrTr
;
1486 comedi_error(dev
, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
1489 devpriv
->AdControlReg
|= AdControl_ExtM
;
1492 comedi_error(dev
, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
1496 "pci9118_ai_docmd_sampl() mode number bug!\n");
1500 devpriv
->int_ai_func
= interrupt_pci9118_ai_onesample
;
1501 /* transfer function */
1503 if (devpriv
->ai12_startstop
)
1504 pci9118_exttrg_add(dev
, EXTTRG_AI
);
1505 /* activate EXT trigger */
1507 if ((devpriv
->ai_do
== 1) || (devpriv
->ai_do
== 2))
1508 devpriv
->IntControlReg
|= Int_Timer
;
1510 devpriv
->AdControlReg
|= AdControl_Int
;
1512 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
) | 0x1f00,
1513 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1514 /* allow INT in AMCC */
1516 if (!(devpriv
->ai12_startstop
& (START_AI_EXT
| START_AI_INT
))) {
1517 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
1518 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1519 if (devpriv
->ai_do
!= 3) {
1520 start_pacer(dev
, devpriv
->ai_do
, devpriv
->ai_divisor1
,
1521 devpriv
->ai_divisor2
);
1522 devpriv
->AdControlReg
|= AdControl_SoftG
;
1524 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
1530 static int pci9118_ai_docmd_dma(struct comedi_device
*dev
,
1531 struct comedi_subdevice
*s
)
1533 struct pci9118_private
*devpriv
= dev
->private;
1535 Compute_and_setup_dma(dev
);
1537 switch (devpriv
->ai_do
) {
1539 devpriv
->AdControlReg
|=
1540 ((AdControl_TmrTr
| AdControl_Dma
) & 0xff);
1543 devpriv
->AdControlReg
|=
1544 ((AdControl_TmrTr
| AdControl_Dma
) & 0xff);
1545 devpriv
->AdFunctionReg
=
1546 AdFunction_PDTrg
| AdFunction_PETrg
| AdFunction_BM
|
1548 if (devpriv
->usessh
&& (!devpriv
->softsshdelay
))
1549 devpriv
->AdFunctionReg
|= AdFunction_BSSH
;
1550 outl(devpriv
->ai_n_realscanlen
, dev
->iobase
+ PCI9118_BURST
);
1553 devpriv
->AdControlReg
|=
1554 ((AdControl_ExtM
| AdControl_Dma
) & 0xff);
1555 devpriv
->AdFunctionReg
= AdFunction_PDTrg
| AdFunction_PETrg
;
1558 devpriv
->AdControlReg
|=
1559 ((AdControl_TmrTr
| AdControl_Dma
) & 0xff);
1560 devpriv
->AdFunctionReg
=
1561 AdFunction_PDTrg
| AdFunction_PETrg
| AdFunction_AM
;
1562 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1563 outl(0x30, dev
->iobase
+ PCI9118_CNTCTRL
);
1564 outl((devpriv
->dmabuf_hw
[0] >> 1) & 0xff,
1565 dev
->iobase
+ PCI9118_CNT0
);
1566 outl((devpriv
->dmabuf_hw
[0] >> 9) & 0xff,
1567 dev
->iobase
+ PCI9118_CNT0
);
1568 devpriv
->AdFunctionReg
|= AdFunction_Start
;
1571 comedi_error(dev
, "pci9118_ai_docmd_dma() mode number bug!\n");
1575 if (devpriv
->ai12_startstop
) {
1576 pci9118_exttrg_add(dev
, EXTTRG_AI
);
1577 /* activate EXT trigger */
1580 devpriv
->int_ai_func
= interrupt_pci9118_ai_dma
;
1581 /* transfer function */
1583 outl(0x02000000 | AINT_WRITE_COMPL
,
1584 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1586 if (!(devpriv
->ai12_startstop
& (START_AI_EXT
| START_AI_INT
))) {
1587 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1588 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
1589 if (devpriv
->ai_do
!= 3) {
1590 start_pacer(dev
, devpriv
->ai_do
, devpriv
->ai_divisor1
,
1591 devpriv
->ai_divisor2
);
1592 devpriv
->AdControlReg
|= AdControl_SoftG
;
1594 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
1600 static int pci9118_ai_cmd(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
1602 const struct boardtype
*this_board
= comedi_board(dev
);
1603 struct pci9118_private
*devpriv
= dev
->private;
1604 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
1605 unsigned int addchans
= 0;
1608 devpriv
->ai12_startstop
= 0;
1609 devpriv
->ai_flags
= cmd
->flags
;
1610 devpriv
->ai_n_chan
= cmd
->chanlist_len
;
1611 devpriv
->ai_n_scanlen
= cmd
->scan_end_arg
;
1612 devpriv
->ai_chanlist
= cmd
->chanlist
;
1613 devpriv
->ai_data
= s
->async
->prealloc_buf
;
1614 devpriv
->ai_data_len
= s
->async
->prealloc_bufsz
;
1615 devpriv
->ai_timer1
= 0;
1616 devpriv
->ai_timer2
= 0;
1617 devpriv
->ai_add_front
= 0;
1618 devpriv
->ai_add_back
= 0;
1619 devpriv
->ai_maskerr
= 0x10e;
1621 /* prepare for start/stop conditions */
1622 if (cmd
->start_src
== TRIG_EXT
)
1623 devpriv
->ai12_startstop
|= START_AI_EXT
;
1624 if (cmd
->stop_src
== TRIG_EXT
) {
1625 devpriv
->ai_neverending
= 1;
1626 devpriv
->ai12_startstop
|= STOP_AI_EXT
;
1628 if (cmd
->start_src
== TRIG_INT
) {
1629 devpriv
->ai12_startstop
|= START_AI_INT
;
1630 devpriv
->ai_inttrig_start
= cmd
->start_arg
;
1631 s
->async
->inttrig
= pci9118_ai_inttrig
;
1634 if (cmd
->stop_src
== TRIG_INT
) {
1635 devpriv
->ai_neverending
= 1;
1636 devpriv
->ai12_startstop
|= STOP_AI_INT
;
1639 if (cmd
->stop_src
== TRIG_NONE
)
1640 devpriv
->ai_neverending
= 1;
1641 if (cmd
->stop_src
== TRIG_COUNT
) {
1642 devpriv
->ai_scans
= cmd
->stop_arg
;
1643 devpriv
->ai_neverending
= 0;
1645 devpriv
->ai_scans
= 0;
1648 /* use sample&hold signal? */
1649 if (cmd
->convert_src
== TRIG_NOW
)
1650 devpriv
->usessh
= 1;
1653 devpriv
->usessh
= 0;
1657 * use additional sample at end of every scan
1658 * to satisty DMA 32 bit transfer?
1660 devpriv
->ai_add_front
= 0;
1661 devpriv
->ai_add_back
= 0;
1662 devpriv
->useeoshandle
= 0;
1663 if (devpriv
->master
) {
1664 devpriv
->usedma
= 1;
1665 if ((cmd
->flags
& TRIG_WAKE_EOS
) &&
1666 (devpriv
->ai_n_scanlen
== 1)) {
1667 if (cmd
->convert_src
== TRIG_NOW
)
1668 devpriv
->ai_add_back
= 1;
1669 if (cmd
->convert_src
== TRIG_TIMER
) {
1670 devpriv
->usedma
= 0;
1672 * use INT transfer if scanlist
1673 * have only one channel
1677 if ((cmd
->flags
& TRIG_WAKE_EOS
) &&
1678 (devpriv
->ai_n_scanlen
& 1) &&
1679 (devpriv
->ai_n_scanlen
> 1)) {
1680 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) {
1682 * vpriv->useeoshandle=1; // change DMA transfer
1683 * block to fit EOS on every second call
1685 devpriv
->usedma
= 0;
1687 * XXX maybe can be corrected to use 16 bit DMA
1690 * well, we must insert one sample
1691 * to end of EOS to meet 32 bit transfer
1693 devpriv
->ai_add_back
= 1;
1696 } else { /* interrupt transfer don't need any correction */
1697 devpriv
->usedma
= 0;
1701 * we need software S&H signal?
1702 * It adds two samples before every scan as minimum
1704 if (devpriv
->usessh
&& devpriv
->softsshdelay
) {
1705 devpriv
->ai_add_front
= 2;
1706 if ((devpriv
->usedma
== 1) && (devpriv
->ai_add_back
== 1)) {
1707 /* move it to front */
1708 devpriv
->ai_add_front
++;
1709 devpriv
->ai_add_back
= 0;
1711 if (cmd
->convert_arg
< this_board
->ai_ns_min
)
1712 cmd
->convert_arg
= this_board
->ai_ns_min
;
1713 addchans
= devpriv
->softsshdelay
/ cmd
->convert_arg
;
1714 if (devpriv
->softsshdelay
% cmd
->convert_arg
)
1716 if (addchans
> (devpriv
->ai_add_front
- 1)) {
1717 /* uff, still short */
1718 devpriv
->ai_add_front
= addchans
+ 1;
1719 if (devpriv
->usedma
== 1)
1720 if ((devpriv
->ai_add_front
+
1721 devpriv
->ai_n_chan
+
1722 devpriv
->ai_add_back
) & 1)
1723 devpriv
->ai_add_front
++;
1724 /* round up to 32 bit */
1727 /* well, we now know what must be all added */
1728 devpriv
->ai_n_realscanlen
= /*
1729 * what we must take from card in real
1730 * to have ai_n_scanlen on output?
1732 (devpriv
->ai_add_front
+ devpriv
->ai_n_chan
+
1733 devpriv
->ai_add_back
) * (devpriv
->ai_n_scanlen
/
1734 devpriv
->ai_n_chan
);
1736 /* check and setup channel list */
1737 if (!check_channel_list(dev
, s
, devpriv
->ai_n_chan
,
1738 devpriv
->ai_chanlist
, devpriv
->ai_add_front
,
1739 devpriv
->ai_add_back
))
1741 if (!setup_channel_list(dev
, s
, devpriv
->ai_n_chan
,
1742 devpriv
->ai_chanlist
, 0, devpriv
->ai_add_front
,
1743 devpriv
->ai_add_back
, devpriv
->usedma
,
1744 devpriv
->useeoshandle
))
1747 /* compute timers settings */
1749 * simplest way, fr=4Mhz/(tim1*tim2),
1750 * channel manipulation without timers effect
1752 if (((cmd
->scan_begin_src
== TRIG_FOLLOW
) ||
1753 (cmd
->scan_begin_src
== TRIG_EXT
) ||
1754 (cmd
->scan_begin_src
== TRIG_INT
)) &&
1755 (cmd
->convert_src
== TRIG_TIMER
)) {
1756 /* both timer is used for one time */
1757 if (cmd
->scan_begin_src
== TRIG_EXT
)
1761 pci9118_calc_divisors(devpriv
->ai_do
, dev
, s
,
1762 &cmd
->scan_begin_arg
, &cmd
->convert_arg
,
1764 devpriv
->ai_n_realscanlen
,
1765 &devpriv
->ai_divisor1
,
1766 &devpriv
->ai_divisor2
, devpriv
->usessh
,
1767 devpriv
->ai_add_front
);
1768 devpriv
->ai_timer2
= cmd
->convert_arg
;
1771 if ((cmd
->scan_begin_src
== TRIG_TIMER
) &&
1772 ((cmd
->convert_src
== TRIG_TIMER
) ||
1773 (cmd
->convert_src
== TRIG_NOW
))) {
1774 /* double timed action */
1775 if (!devpriv
->usedma
) {
1777 "cmd->scan_begin_src=TRIG_TIMER works "
1778 "only with bus mastering!");
1783 pci9118_calc_divisors(devpriv
->ai_do
, dev
, s
,
1784 &cmd
->scan_begin_arg
, &cmd
->convert_arg
,
1786 devpriv
->ai_n_realscanlen
,
1787 &devpriv
->ai_divisor1
,
1788 &devpriv
->ai_divisor2
, devpriv
->usessh
,
1789 devpriv
->ai_add_front
);
1790 devpriv
->ai_timer1
= cmd
->scan_begin_arg
;
1791 devpriv
->ai_timer2
= cmd
->convert_arg
;
1794 if ((cmd
->scan_begin_src
== TRIG_FOLLOW
)
1795 && (cmd
->convert_src
== TRIG_EXT
)) {
1799 start_pacer(dev
, -1, 0, 0); /* stop pacer */
1801 devpriv
->AdControlReg
= 0; /*
1802 * bipolar, S.E., use 8254, stop 8354,
1803 * internal trigger, soft trigger,
1806 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
1807 devpriv
->AdFunctionReg
= AdFunction_PDTrg
| AdFunction_PETrg
;
1809 * positive triggers, no S&H, no burst,
1810 * burst stop, no post trigger,
1811 * no about trigger, trigger stop
1813 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1815 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
1816 inl(dev
->iobase
+ PCI9118_ADSTAT
); /*
1820 inl(dev
->iobase
+ PCI9118_INTSRC
);
1822 devpriv
->ai_act_scan
= 0;
1823 devpriv
->ai_act_dmapos
= 0;
1824 s
->async
->cur_chan
= 0;
1825 devpriv
->ai_buf_ptr
= 0;
1827 if (devpriv
->usedma
)
1828 ret
= pci9118_ai_docmd_dma(dev
, s
);
1830 ret
= pci9118_ai_docmd_sampl(dev
, s
);
1835 static int pci9118_reset(struct comedi_device
*dev
)
1837 struct pci9118_private
*devpriv
= dev
->private;
1839 devpriv
->IntControlReg
= 0;
1840 devpriv
->exttrg_users
= 0;
1841 inl(dev
->iobase
+ PCI9118_INTCTRL
);
1842 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
1843 /* disable interrupts source */
1844 outl(0x30, dev
->iobase
+ PCI9118_CNTCTRL
);
1845 /* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
1846 start_pacer(dev
, 0, 0, 0); /* stop 8254 counters */
1847 devpriv
->AdControlReg
= 0;
1848 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
1850 * bipolar, S.E., use 8254,
1851 * stop 8354, internal trigger,
1853 * disable INT and DMA
1855 outl(0, dev
->iobase
+ PCI9118_BURST
);
1856 outl(1, dev
->iobase
+ PCI9118_SCANMOD
);
1857 outl(2, dev
->iobase
+ PCI9118_SCANMOD
); /* reset scan queue */
1858 devpriv
->AdFunctionReg
= AdFunction_PDTrg
| AdFunction_PETrg
;
1859 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1861 * positive triggers, no S&H,
1862 * no burst, burst stop,
1868 devpriv
->ao_data
[0] = 2047;
1869 devpriv
->ao_data
[1] = 2047;
1870 outl(devpriv
->ao_data
[0], dev
->iobase
+ PCI9118_DA1
);
1871 /* reset A/D outs to 0V */
1872 outl(devpriv
->ao_data
[1], dev
->iobase
+ PCI9118_DA2
);
1873 outl(0, dev
->iobase
+ PCI9118_DO
); /* reset digi outs to L */
1875 inl(dev
->iobase
+ PCI9118_AD_DATA
);
1876 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
1877 outl(0, dev
->iobase
+ PCI9118_INTSRC
); /* remove INT requests */
1878 inl(dev
->iobase
+ PCI9118_ADSTAT
); /* flush A/D status register */
1879 inl(dev
->iobase
+ PCI9118_INTSRC
); /* flush INT requests */
1880 devpriv
->AdControlReg
= 0;
1881 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
1883 * bipolar, S.E., use 8254,
1884 * stop 8354, internal trigger,
1886 * disable INT and DMA
1889 devpriv
->cnt0_users
= 0;
1890 devpriv
->exttrg_users
= 0;
1896 * FIXME - this is pretty ineffective because all the supported board types
1897 * have the same device ID!
1899 static const struct boardtype
*pci9118_find_boardinfo(struct pci_dev
*pcidev
)
1903 for (i
= 0; i
< ARRAY_SIZE(boardtypes
); i
++)
1904 if (pcidev
->device
== boardtypes
[i
].device_id
)
1905 return &boardtypes
[i
];
1909 static struct pci_dev
*pci9118_find_pci(struct comedi_device
*dev
,
1910 struct comedi_devconfig
*it
)
1912 const struct boardtype
*this_board
= comedi_board(dev
);
1913 struct pci_dev
*pcidev
= NULL
;
1914 int bus
= it
->options
[0];
1915 int slot
= it
->options
[1];
1917 for_each_pci_dev(pcidev
) {
1918 if (pcidev
->vendor
!= PCI_VENDOR_ID_AMCC
)
1920 if (pcidev
->device
!= this_board
->device_id
)
1923 /* requested particular bus/slot */
1924 if (pcidev
->bus
->number
!= bus
||
1925 PCI_SLOT(pcidev
->devfn
) != slot
)
1930 dev_err(dev
->class_dev
,
1931 "no supported board found! (req. bus/slot : %d/%d)\n",
1936 static void pci9118_report_attach(struct comedi_device
*dev
, unsigned int irq
)
1938 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1939 struct pci9118_private
*devpriv
= dev
->private;
1944 snprintf(irqbuf
, sizeof(irqbuf
), "irq %u%s", irq
,
1945 (dev
->irq
? "" : " UNAVAILABLE"));
1947 snprintf(irqbuf
, sizeof(irqbuf
), "irq DISABLED");
1948 if (devpriv
->usemux
)
1949 snprintf(muxbuf
, sizeof(muxbuf
), "ext mux %u chans",
1952 snprintf(muxbuf
, sizeof(muxbuf
), "no ext mux");
1953 dev_info(dev
->class_dev
, "%s (pci %s, %s, %sbus master, %s) attached\n",
1954 dev
->board_name
, pci_name(pcidev
), irqbuf
,
1955 (devpriv
->master
? "" : "no "), muxbuf
);
1958 static int pci9118_common_attach(struct comedi_device
*dev
, int disable_irq
,
1959 int master
, int ext_mux
, int softsshdelay
,
1962 const struct boardtype
*this_board
= comedi_board(dev
);
1963 struct pci9118_private
*devpriv
= dev
->private;
1964 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1965 struct comedi_subdevice
*s
;
1970 dev
->board_name
= this_board
->name
;
1971 ret
= comedi_pci_enable(pcidev
, dev
->board_name
);
1973 dev_err(dev
->class_dev
,
1974 "cannot enable PCI device %s\n", pci_name(pcidev
));
1978 pci_set_master(pcidev
);
1980 devpriv
->iobase_a
= pci_resource_start(pcidev
, 0);
1981 dev
->iobase
= pci_resource_start(pcidev
, 2);
1985 if (master
) { /* alloc DMA buffers */
1986 devpriv
->dma_doublebuf
= 0;
1987 for (i
= 0; i
< 2; i
++) {
1988 for (pages
= 4; pages
>= 0; pages
--) {
1989 devpriv
->dmabuf_virt
[i
] =
1990 (short *)__get_free_pages(GFP_KERNEL
,
1992 if (devpriv
->dmabuf_virt
[i
])
1995 if (devpriv
->dmabuf_virt
[i
]) {
1996 devpriv
->dmabuf_pages
[i
] = pages
;
1997 devpriv
->dmabuf_size
[i
] = PAGE_SIZE
* pages
;
1998 devpriv
->dmabuf_samples
[i
] =
1999 devpriv
->dmabuf_size
[i
] >> 1;
2000 devpriv
->dmabuf_hw
[i
] =
2001 virt_to_bus((void *)
2002 devpriv
->dmabuf_virt
[i
]);
2005 if (!devpriv
->dmabuf_virt
[0]) {
2006 dev_warn(dev
->class_dev
,
2007 "Can't allocate DMA buffer, DMA disabled!\n");
2010 if (devpriv
->dmabuf_virt
[1])
2011 devpriv
->dma_doublebuf
= 1;
2013 devpriv
->master
= master
;
2017 ext_mux
= 256; /* max 256 channels! */
2018 if (softsshdelay
> 0)
2021 devpriv
->usemux
= ext_mux
;
2023 devpriv
->usemux
= 0;
2026 if (softsshdelay
< 0) {
2027 /* select sample&hold signal polarity */
2028 devpriv
->softsshdelay
= -softsshdelay
;
2029 devpriv
->softsshsample
= 0x80;
2030 devpriv
->softsshhold
= 0x00;
2032 devpriv
->softsshdelay
= softsshdelay
;
2033 devpriv
->softsshsample
= 0x00;
2034 devpriv
->softsshhold
= 0x80;
2037 pci_read_config_word(pcidev
, PCI_COMMAND
, &u16w
);
2038 pci_write_config_word(pcidev
, PCI_COMMAND
, u16w
| 64);
2039 /* Enable parity check for parity error */
2041 ret
= comedi_alloc_subdevices(dev
, 4);
2045 s
= &dev
->subdevices
[0];
2046 dev
->read_subdev
= s
;
2047 s
->type
= COMEDI_SUBD_AI
;
2048 s
->subdev_flags
= SDF_READABLE
| SDF_COMMON
| SDF_GROUND
| SDF_DIFF
;
2049 if (devpriv
->usemux
)
2050 s
->n_chan
= devpriv
->usemux
;
2052 s
->n_chan
= this_board
->n_aichan
;
2054 s
->maxdata
= this_board
->ai_maxdata
;
2055 s
->len_chanlist
= this_board
->n_aichanlist
;
2056 s
->range_table
= this_board
->rangelist_ai
;
2057 s
->cancel
= pci9118_ai_cancel
;
2058 s
->insn_read
= pci9118_insn_read_ai
;
2059 s
->munge
= pci9118_ai_munge
;
2061 s
= &dev
->subdevices
[1];
2062 s
->type
= COMEDI_SUBD_AO
;
2063 s
->subdev_flags
= SDF_WRITABLE
| SDF_GROUND
| SDF_COMMON
;
2064 s
->n_chan
= this_board
->n_aochan
;
2065 s
->maxdata
= this_board
->ao_maxdata
;
2066 s
->len_chanlist
= this_board
->n_aochan
;
2067 s
->range_table
= this_board
->rangelist_ao
;
2068 s
->insn_write
= pci9118_insn_write_ao
;
2069 s
->insn_read
= pci9118_insn_read_ao
;
2071 s
= &dev
->subdevices
[2];
2072 s
->type
= COMEDI_SUBD_DI
;
2073 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
| SDF_COMMON
;
2076 s
->len_chanlist
= 4;
2077 s
->range_table
= &range_digital
;
2078 s
->io_bits
= 0; /* all bits input */
2079 s
->insn_bits
= pci9118_insn_bits_di
;
2081 s
= &dev
->subdevices
[3];
2082 s
->type
= COMEDI_SUBD_DO
;
2083 s
->subdev_flags
= SDF_WRITABLE
| SDF_GROUND
| SDF_COMMON
;
2086 s
->len_chanlist
= 4;
2087 s
->range_table
= &range_digital
;
2088 s
->io_bits
= 0xf; /* all bits output */
2089 s
->insn_bits
= pci9118_insn_bits_do
;
2092 devpriv
->i8254_osc_base
= 250; /* 250ns=4MHz */
2093 devpriv
->ai_maskharderr
= 0x10a;
2094 /* default measure crash condition */
2095 if (hw_err_mask
) /* disable some requested */
2096 devpriv
->ai_maskharderr
&= ~hw_err_mask
;
2098 switch (this_board
->ai_maxdata
) {
2100 devpriv
->ai16bits
= 1;
2103 devpriv
->ai16bits
= 0;
2112 if (request_irq(irq
, interrupt_pci9118
, IRQF_SHARED
,
2113 dev
->board_name
, dev
)) {
2114 dev_warn(dev
->class_dev
,
2115 "unable to allocate IRQ %u, DISABLING IT\n",
2119 /* Enable AI commands */
2120 s
= &dev
->subdevices
[0];
2121 s
->subdev_flags
|= SDF_CMD_READ
;
2122 s
->do_cmdtest
= pci9118_ai_cmdtest
;
2123 s
->do_cmd
= pci9118_ai_cmd
;
2127 pci9118_report_attach(dev
, irq
);
2131 static int pci9118_attach(struct comedi_device
*dev
,
2132 struct comedi_devconfig
*it
)
2134 struct pci9118_private
*devpriv
;
2135 struct pci_dev
*pcidev
;
2136 int ext_mux
, disable_irq
, master
, softsshdelay
, hw_err_mask
;
2138 ext_mux
= it
->options
[2];
2139 master
= ((it
->options
[3] & 1) == 0);
2140 disable_irq
= ((it
->options
[3] & 2) != 0);
2141 softsshdelay
= it
->options
[4];
2142 hw_err_mask
= it
->options
[5];
2144 devpriv
= kzalloc(sizeof(*devpriv
), GFP_KERNEL
);
2147 dev
->private = devpriv
;
2149 pcidev
= pci9118_find_pci(dev
, it
);
2152 comedi_set_hw_dev(dev
, &pcidev
->dev
);
2154 return pci9118_common_attach(dev
, disable_irq
, master
, ext_mux
,
2155 softsshdelay
, hw_err_mask
);
2158 static int pci9118_auto_attach(struct comedi_device
*dev
,
2159 unsigned long context_unused
)
2161 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
2162 struct pci9118_private
*devpriv
;
2164 devpriv
= kzalloc(sizeof(*devpriv
), GFP_KERNEL
);
2167 dev
->private = devpriv
;
2169 dev
->board_ptr
= pci9118_find_boardinfo(pcidev
);
2170 if (dev
->board_ptr
== NULL
) {
2171 dev_err(dev
->class_dev
,
2172 "adl_pci9118: cannot determine board type for pci %s\n",
2177 * Need to 'get' the PCI device to match the 'put' in pci9118_detach().
2178 * (The 'put' also matches the implicit 'get' by pci9118_find_pci().)
2180 pci_dev_get(pcidev
);
2181 /* Don't disable irq, use bus master, no external mux,
2182 * no sample-hold delay, no error mask. */
2183 return pci9118_common_attach(dev
, 0, 1, 0, 0, 0);
2186 static void pci9118_detach(struct comedi_device
*dev
)
2188 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
2189 struct pci9118_private
*devpriv
= dev
->private;
2195 free_irq(dev
->irq
, dev
);
2196 if (devpriv
->dmabuf_virt
[0])
2197 free_pages((unsigned long)devpriv
->dmabuf_virt
[0],
2198 devpriv
->dmabuf_pages
[0]);
2199 if (devpriv
->dmabuf_virt
[1])
2200 free_pages((unsigned long)devpriv
->dmabuf_virt
[1],
2201 devpriv
->dmabuf_pages
[1]);
2205 comedi_pci_disable(pcidev
);
2207 pci_dev_put(pcidev
);
2211 static struct comedi_driver adl_pci9118_driver
= {
2212 .driver_name
= "adl_pci9118",
2213 .module
= THIS_MODULE
,
2214 .attach
= pci9118_attach
,
2215 .auto_attach
= pci9118_auto_attach
,
2216 .detach
= pci9118_detach
,
2217 .num_names
= ARRAY_SIZE(boardtypes
),
2218 .board_name
= &boardtypes
[0].name
,
2219 .offset
= sizeof(struct boardtype
),
2222 static int adl_pci9118_pci_probe(struct pci_dev
*dev
,
2223 const struct pci_device_id
*ent
)
2225 return comedi_pci_auto_config(dev
, &adl_pci9118_driver
);
2228 static void adl_pci9118_pci_remove(struct pci_dev
*dev
)
2230 comedi_pci_auto_unconfig(dev
);
2233 static DEFINE_PCI_DEVICE_TABLE(adl_pci9118_pci_table
) = {
2234 { PCI_DEVICE(PCI_VENDOR_ID_AMCC
, 0x80d9) },
2237 MODULE_DEVICE_TABLE(pci
, adl_pci9118_pci_table
);
2239 static struct pci_driver adl_pci9118_pci_driver
= {
2240 .name
= "adl_pci9118",
2241 .id_table
= adl_pci9118_pci_table
,
2242 .probe
= adl_pci9118_pci_probe
,
2243 .remove
= adl_pci9118_pci_remove
,
2245 module_comedi_pci_driver(adl_pci9118_driver
, adl_pci9118_pci_driver
);
2247 MODULE_AUTHOR("Comedi http://www.comedi.org");
2248 MODULE_DESCRIPTION("Comedi low-level driver");
2249 MODULE_LICENSE("GPL");