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
65 #include "../comedidev.h"
67 #include <linux/delay.h>
68 #include <linux/gfp.h>
69 #include <linux/interrupt.h>
72 #include "amcc_s5933.h"
74 #include "comedi_fc.h"
76 #define PCI_VENDOR_ID_AMCC 0x10e8
78 /* paranoid checks are broken */
79 #undef PCI9118_PARANOIDCHECK /*
80 * if defined, then is used code which control
81 * correct channel number on every 12 bit sample
84 #define IORANGE_9118 64 /* I hope */
85 #define PCI9118_CHANLEN 255 /*
86 * len of chanlist, some source say 256,
87 * but reality looks like 255 :-(
90 #define PCI9118_CNT0 0x00 /* R/W: 8254 counter 0 */
91 #define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */
92 #define PCI9118_CNT2 0x08 /* R/W: 8254 counter 0 */
93 #define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
94 #define PCI9118_AD_DATA 0x10 /* R: A/D data */
95 #define PCI9118_DA1 0x10 /* W: D/A registers */
96 #define PCI9118_DA2 0x14
97 #define PCI9118_ADSTAT 0x18 /* R: A/D status register */
98 #define PCI9118_ADCNTRL 0x18 /* W: A/D control register */
99 #define PCI9118_DI 0x1c /* R: digi input register */
100 #define PCI9118_DO 0x1c /* W: digi output register */
101 #define PCI9118_SOFTTRG 0x20 /* W: soft trigger for A/D */
102 #define PCI9118_GAIN 0x24 /* W: A/D gain/channel register */
103 #define PCI9118_BURST 0x28 /* W: A/D burst number register */
104 #define PCI9118_SCANMOD 0x2c /* W: A/D auto scan mode */
105 #define PCI9118_ADFUNC 0x30 /* W: A/D function register */
106 #define PCI9118_DELFIFO 0x34 /* W: A/D data FIFO reset */
107 #define PCI9118_INTSRC 0x38 /* R: interrupt reason register */
108 #define PCI9118_INTCTRL 0x38 /* W: interrupt control register */
110 /* bits from A/D control register (PCI9118_ADCNTRL) */
111 #define AdControl_UniP 0x80 /* 1=bipolar, 0=unipolar */
112 #define AdControl_Diff 0x40 /* 1=differential, 0= single end inputs */
113 #define AdControl_SoftG 0x20 /* 1=8254 counter works, 0=counter stops */
114 #define AdControl_ExtG 0x10 /*
115 * 1=8254 countrol controlled by TGIN(pin 46),
116 * 0=controlled by SoftG
118 #define AdControl_ExtM 0x08 /*
119 * 1=external hardware trigger (pin 44),
122 #define AdControl_TmrTr 0x04 /*
123 * 1=8254 is iternal trigger source,
124 * 0=software trigger is source
125 * (register PCI9118_SOFTTRG)
127 #define AdControl_Int 0x02 /* 1=enable INT, 0=disable */
128 #define AdControl_Dma 0x01 /* 1=enable DMA, 0=disable */
130 /* bits from A/D function register (PCI9118_ADFUNC) */
131 #define AdFunction_PDTrg 0x80 /*
133 * 0=negative digital trigger
134 * (only positive is correct)
136 #define AdFunction_PETrg 0x40 /*
138 * 0=negative external trigger
139 * (only positive is correct)
141 #define AdFunction_BSSH 0x20 /* 1=with sample&hold, 0=without */
142 #define AdFunction_BM 0x10 /* 1=burst mode, 0=normal mode */
143 #define AdFunction_BS 0x08 /*
144 * 1=burst mode start,
147 #define AdFunction_PM 0x04 /*
148 * 1=post trigger mode,
151 #define AdFunction_AM 0x02 /*
152 * 1=about trigger mode,
153 * 0=not about trigger
155 #define AdFunction_Start 0x01 /* 1=trigger start, 0=trigger stop */
157 /* bits from A/D status register (PCI9118_ADSTAT) */
158 #define AdStatus_nFull 0x100 /* 0=FIFO full (fatal), 1=not full */
159 #define AdStatus_nHfull 0x080 /* 0=FIFO half full, 1=FIFO not half full */
160 #define AdStatus_nEpty 0x040 /* 0=FIFO empty, 1=FIFO not empty */
161 #define AdStatus_Acmp 0x020 /* */
162 #define AdStatus_DTH 0x010 /* 1=external digital trigger */
163 #define AdStatus_Bover 0x008 /* 1=burst mode overrun (fatal) */
164 #define AdStatus_ADOS 0x004 /* 1=A/D over speed (warning) */
165 #define AdStatus_ADOR 0x002 /* 1=A/D overrun (fatal) */
166 #define AdStatus_ADrdy 0x001 /* 1=A/D already ready, 0=not ready */
168 /* bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL) */
169 /* 1=interrupt occur, enable source, 0=interrupt not occur, disable source */
170 #define Int_Timer 0x08 /* timer interrupt */
171 #define Int_About 0x04 /* about trigger complete */
172 #define Int_Hfull 0x02 /* A/D FIFO hlaf full */
173 #define Int_DTrg 0x01 /* external digital trigger */
175 #define START_AI_EXT 0x01 /* start measure on external trigger */
176 #define STOP_AI_EXT 0x02 /* stop measure on external trigger */
177 #define START_AI_INT 0x04 /* start measure on internal trigger */
178 #define STOP_AI_INT 0x08 /* stop measure on internal trigger */
180 #define EXTTRG_AI 0 /* ext trg is used by AI */
182 static const struct comedi_lrange range_pci9118dg_hr
= { 8, {
194 static const struct comedi_lrange range_pci9118hg
= { 8, {
206 #define PCI9118_BIPOLAR_RANGES 4 /*
207 * used for test on mixture
212 const char *name
; /* board name */
213 int vendor_id
; /* PCI vendor a device ID of card */
215 int iorange_amcc
; /* iorange for own S5933 region */
216 int iorange_9118
; /* pass thru card region size */
217 int n_aichan
; /* num of A/D chans */
218 int n_aichand
; /* num of A/D chans in diff mode */
220 * num of A/D chans with
221 * external multiplexor
223 int n_aichanlist
; /* len of chanlist */
224 int n_aochan
; /* num of D/A chans */
225 int ai_maxdata
; /* resolution of A/D */
226 int ao_maxdata
; /* resolution of D/A */
227 const struct comedi_lrange
*rangelist_ai
; /* rangelist for A/D */
228 const struct comedi_lrange
*rangelist_ao
; /* rangelist for D/A */
229 unsigned int ai_ns_min
; /* max sample speed of card v ns */
230 unsigned int ai_pacer_min
; /*
231 * minimal pacer value
232 * (c1*c2 or c1 in burst)
234 int half_fifo_size
; /* size of FIFO/2 */
238 struct pci9118_private
{
239 unsigned long iobase_a
; /* base+size for AMCC chip */
240 unsigned int master
; /* master capable */
241 unsigned int usemux
; /* we want to use external multiplexor! */
242 #ifdef PCI9118_PARANOIDCHECK
243 unsigned short chanlist
[PCI9118_CHANLEN
+ 1]; /*
247 unsigned char chanlistlen
; /* number of scanlist */
249 unsigned char AdControlReg
; /* A/D control register */
250 unsigned char IntControlReg
; /* Interrupt control register */
251 unsigned char AdFunctionReg
; /* A/D function register */
252 char valid
; /* driver is ok */
253 char ai_neverending
; /* we do unlimited AI */
254 unsigned int i8254_osc_base
; /* frequence of onboard oscilator */
255 unsigned int ai_do
; /* what do AI? 0=nothing, 1 to 4 mode */
256 unsigned int ai_act_scan
; /* how many scans we finished */
257 unsigned int ai_buf_ptr
; /* data buffer ptr in samples */
258 unsigned int ai_n_chan
; /* how many channels is measured */
259 unsigned int ai_n_scanlen
; /* len of actual scanlist */
260 unsigned int ai_n_realscanlen
; /*
261 * what we must transfer for one
262 * outgoing scan include front/back adds
264 unsigned int ai_act_dmapos
; /* position in actual real stream */
265 unsigned int ai_add_front
; /*
266 * how many channels we must add
267 * before scan to satisfy S&H?
269 unsigned int ai_add_back
; /*
270 * how many channels we must add
271 * before scan to satisfy DMA?
273 unsigned int *ai_chanlist
; /* actual chanlist */
274 unsigned int ai_timer1
;
275 unsigned int ai_timer2
;
276 unsigned int ai_flags
;
277 char ai12_startstop
; /*
278 * measure can start/stop
279 * on external trigger
281 unsigned int ai_divisor1
, ai_divisor2
; /*
282 * divisors for start of measure
285 unsigned int ai_data_len
;
287 short ao_data
[2]; /* data output buffer */
288 unsigned int ai_scans
; /* number of scans to do */
289 char dma_doublebuf
; /* we can use double buffering */
290 unsigned int dma_actbuf
; /* which buffer is used now */
291 short *dmabuf_virt
[2]; /*
292 * pointers to begin of
295 unsigned long dmabuf_hw
[2]; /* hw address of DMA buff */
296 unsigned int dmabuf_size
[2]; /*
297 * size of dma buffer in bytes
299 unsigned int dmabuf_use_size
[2]; /*
300 * which size we may now use
303 unsigned int dmabuf_used_size
[2]; /* which size was truly used */
304 unsigned int dmabuf_panic_size
[2];
305 unsigned int dmabuf_samples
[2]; /* size in samples */
306 int dmabuf_pages
[2]; /* number of pages in buffer */
307 unsigned char cnt0_users
; /*
308 * bit field of 8254 CNT0 users
309 * (0-unused, 1-AO, 2-DI, 3-DO)
311 unsigned char exttrg_users
; /*
312 * bit field of external trigger
313 * users(0-AI, 1-AO, 2-DI, 3-DO)
315 unsigned int cnt0_divisor
; /* actual CNT0 divisor */
316 void (*int_ai_func
) (struct comedi_device
*, struct comedi_subdevice
*,
320 * ptr to actual interrupt
323 unsigned char ai16bits
; /* =1 16 bit card */
324 unsigned char usedma
; /* =1 use DMA transfer and not INT */
325 unsigned char useeoshandle
; /*
326 * =1 change WAKE_EOS DMA transfer
327 * to fit on every second
329 unsigned char usessh
; /* =1 turn on S&H support */
331 * >0 use software S&H,
332 * numer is requested delay in ns
334 unsigned char softsshsample
; /*
335 * polarity of S&H signal
338 unsigned char softsshhold
; /*
339 * polarity of S&H signal
342 unsigned int ai_maskerr
; /* which warning was printed */
343 unsigned int ai_maskharderr
; /* on which error bits stops */
344 unsigned int ai_inttrig_start
; /* TRIG_INT for start */
347 static int check_channel_list(struct comedi_device
*dev
,
348 struct comedi_subdevice
*s
, int n_chan
,
349 unsigned int *chanlist
, int frontadd
, int backadd
)
351 const struct boardtype
*this_board
= comedi_board(dev
);
352 struct pci9118_private
*devpriv
= dev
->private;
353 unsigned int i
, differencial
= 0, bipolar
= 0;
355 /* correct channel and range number check itself comedi/range.c */
357 comedi_error(dev
, "range/channel list is empty!");
360 if ((frontadd
+ n_chan
+ backadd
) > s
->len_chanlist
) {
362 ("comedi%d: range/channel list is too long for "
363 "actual configuration (%d>%d)!",
364 dev
->minor
, n_chan
, s
->len_chanlist
- frontadd
- backadd
);
368 if (CR_AREF(chanlist
[0]) == AREF_DIFF
)
369 differencial
= 1; /* all input must be diff */
370 if (CR_RANGE(chanlist
[0]) < PCI9118_BIPOLAR_RANGES
)
371 bipolar
= 1; /* all input must be bipolar */
373 for (i
= 1; i
< n_chan
; i
++) { /* check S.E/diff */
374 if ((CR_AREF(chanlist
[i
]) == AREF_DIFF
) !=
377 "Differencial and single ended "
378 "inputs can't be mixtured!");
381 if ((CR_RANGE(chanlist
[i
]) < PCI9118_BIPOLAR_RANGES
) !=
384 "Bipolar and unipolar ranges "
385 "can't be mixtured!");
388 if (!devpriv
->usemux
&& differencial
&&
389 (CR_CHAN(chanlist
[i
]) >= this_board
->n_aichand
)) {
391 "If AREF_DIFF is used then is "
392 "available only first 8 channels!");
400 static int setup_channel_list(struct comedi_device
*dev
,
401 struct comedi_subdevice
*s
, int n_chan
,
402 unsigned int *chanlist
, int rot
, int frontadd
,
403 int backadd
, int usedma
, char useeos
)
405 struct pci9118_private
*devpriv
= dev
->private;
406 unsigned int i
, differencial
= 0, bipolar
= 0;
407 unsigned int scanquad
, gain
, ssh
= 0x00;
414 if (CR_AREF(chanlist
[0]) == AREF_DIFF
)
415 differencial
= 1; /* all input must be diff */
416 if (CR_RANGE(chanlist
[0]) < PCI9118_BIPOLAR_RANGES
)
417 bipolar
= 1; /* all input must be bipolar */
419 /* All is ok, so we can setup channel/range list */
422 devpriv
->AdControlReg
|= AdControl_UniP
;
425 devpriv
->AdControlReg
&= ((~AdControl_UniP
) & 0xff);
430 devpriv
->AdControlReg
|= AdControl_Diff
;
431 /* enable diff inputs */
433 devpriv
->AdControlReg
&= ((~AdControl_Diff
) & 0xff);
434 /* set single ended inputs */
437 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
440 outl(2, dev
->iobase
+ PCI9118_SCANMOD
);
441 /* gods know why this sequence! */
442 outl(0, dev
->iobase
+ PCI9118_SCANMOD
);
443 outl(1, dev
->iobase
+ PCI9118_SCANMOD
);
445 #ifdef PCI9118_PARANOIDCHECK
446 devpriv
->chanlistlen
= n_chan
;
447 for (i
= 0; i
< (PCI9118_CHANLEN
+ 1); i
++)
448 devpriv
->chanlist
[i
] = 0x55aa;
451 if (frontadd
) { /* insert channels for S&H */
452 ssh
= devpriv
->softsshsample
;
453 for (i
= 0; i
< frontadd
; i
++) {
454 /* store range list to card */
455 scanquad
= CR_CHAN(chanlist
[0]);
456 /* get channel number; */
457 gain
= CR_RANGE(chanlist
[0]);
458 /* get gain number */
459 scanquad
|= ((gain
& 0x03) << 8);
460 outl(scanquad
| ssh
, dev
->iobase
+ PCI9118_GAIN
);
461 ssh
= devpriv
->softsshhold
;
465 for (i
= 0; i
< n_chan
; i
++) { /* store range list to card */
466 scanquad
= CR_CHAN(chanlist
[i
]); /* get channel number */
467 #ifdef PCI9118_PARANOIDCHECK
468 devpriv
->chanlist
[i
^ usedma
] = (scanquad
& 0xf) << rot
;
470 gain
= CR_RANGE(chanlist
[i
]); /* get gain number */
471 scanquad
|= ((gain
& 0x03) << 8);
472 outl(scanquad
| ssh
, dev
->iobase
+ PCI9118_GAIN
);
475 if (backadd
) { /* insert channels for fit onto 32bit DMA */
476 for (i
= 0; i
< backadd
; i
++) { /* store range list to card */
477 scanquad
= CR_CHAN(chanlist
[0]);
478 /* get channel number */
479 gain
= CR_RANGE(chanlist
[0]); /* get gain number */
480 scanquad
|= ((gain
& 0x03) << 8);
481 outl(scanquad
| ssh
, dev
->iobase
+ PCI9118_GAIN
);
484 #ifdef PCI9118_PARANOIDCHECK
485 devpriv
->chanlist
[n_chan
^ usedma
] = devpriv
->chanlist
[0 ^ usedma
];
486 /* for 32bit operations */
488 for (i
= 1; i
< n_chan
; i
++) { /* store range list to card */
489 devpriv
->chanlist
[(n_chan
+ i
) ^ usedma
] =
490 (CR_CHAN(chanlist
[i
]) & 0xf) << rot
;
492 devpriv
->chanlist
[(2 * n_chan
) ^ usedma
] =
493 devpriv
->chanlist
[0 ^ usedma
];
494 /* for 32bit operations */
500 outl(0, dev
->iobase
+ PCI9118_SCANMOD
); /* close scan queue */
501 /* udelay(100); important delay, or first sample will be crippled */
503 return 1; /* we can serve this with scan logic */
506 static int pci9118_insn_read_ai(struct comedi_device
*dev
,
507 struct comedi_subdevice
*s
,
508 struct comedi_insn
*insn
, unsigned int *data
)
510 struct pci9118_private
*devpriv
= dev
->private;
513 devpriv
->AdControlReg
= AdControl_Int
& 0xff;
514 devpriv
->AdFunctionReg
= AdFunction_PDTrg
| AdFunction_PETrg
;
515 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
517 * positive triggers, no S&H,
518 * no burst, burst stop,
524 if (!setup_channel_list(dev
, s
, 1, &insn
->chanspec
, 0, 0, 0, 0, 0))
527 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
529 for (n
= 0; n
< insn
->n
; n
++) {
530 outw(0, dev
->iobase
+ PCI9118_SOFTTRG
); /* start conversion */
534 if (inl(dev
->iobase
+ PCI9118_ADSTAT
) & AdStatus_ADrdy
)
539 comedi_error(dev
, "A/D insn timeout");
541 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
545 if (devpriv
->ai16bits
) {
548 PCI9118_AD_DATA
) & 0xffff) ^ 0x8000;
551 (inw(dev
->iobase
+ PCI9118_AD_DATA
) >> 4) & 0xfff;
555 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
560 static int pci9118_insn_write_ao(struct comedi_device
*dev
,
561 struct comedi_subdevice
*s
,
562 struct comedi_insn
*insn
, unsigned int *data
)
564 struct pci9118_private
*devpriv
= dev
->private;
567 ch
= CR_CHAN(insn
->chanspec
);
569 chanreg
= PCI9118_DA2
;
571 chanreg
= PCI9118_DA1
;
574 for (n
= 0; n
< insn
->n
; n
++) {
575 outl(data
[n
], dev
->iobase
+ chanreg
);
576 devpriv
->ao_data
[ch
] = data
[n
];
582 static int pci9118_insn_read_ao(struct comedi_device
*dev
,
583 struct comedi_subdevice
*s
,
584 struct comedi_insn
*insn
, unsigned int *data
)
586 struct pci9118_private
*devpriv
= dev
->private;
589 chan
= CR_CHAN(insn
->chanspec
);
590 for (n
= 0; n
< insn
->n
; n
++)
591 data
[n
] = devpriv
->ao_data
[chan
];
596 static int pci9118_insn_bits_di(struct comedi_device
*dev
,
597 struct comedi_subdevice
*s
,
598 struct comedi_insn
*insn
, unsigned int *data
)
600 data
[1] = inl(dev
->iobase
+ PCI9118_DI
) & 0xf;
605 static int pci9118_insn_bits_do(struct comedi_device
*dev
,
606 struct comedi_subdevice
*s
,
607 struct comedi_insn
*insn
, unsigned int *data
)
610 s
->state
&= ~data
[0];
611 s
->state
|= (data
[0] & data
[1]);
612 outl(s
->state
& 0x0f, dev
->iobase
+ PCI9118_DO
);
619 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device
*dev
)
621 struct pci9118_private
*devpriv
= dev
->private;
623 devpriv
->AdFunctionReg
=
624 AdFunction_PDTrg
| AdFunction_PETrg
| AdFunction_AM
;
625 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
626 outl(0x30, dev
->iobase
+ PCI9118_CNTCTRL
);
627 outl((devpriv
->dmabuf_hw
[1 - devpriv
->dma_actbuf
] >> 1) & 0xff,
628 dev
->iobase
+ PCI9118_CNT0
);
629 outl((devpriv
->dmabuf_hw
[1 - devpriv
->dma_actbuf
] >> 9) & 0xff,
630 dev
->iobase
+ PCI9118_CNT0
);
631 devpriv
->AdFunctionReg
|= AdFunction_Start
;
632 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
635 static unsigned int defragment_dma_buffer(struct comedi_device
*dev
,
636 struct comedi_subdevice
*s
,
638 unsigned int num_samples
)
640 struct pci9118_private
*devpriv
= dev
->private;
641 unsigned int i
= 0, j
= 0;
642 unsigned int start_pos
= devpriv
->ai_add_front
,
643 stop_pos
= devpriv
->ai_add_front
+ devpriv
->ai_n_chan
;
644 unsigned int raw_scanlen
= devpriv
->ai_add_front
+ devpriv
->ai_n_chan
+
645 devpriv
->ai_add_back
;
647 for (i
= 0; i
< num_samples
; i
++) {
648 if (devpriv
->ai_act_dmapos
>= start_pos
&&
649 devpriv
->ai_act_dmapos
< stop_pos
) {
650 dma_buffer
[j
++] = dma_buffer
[i
];
652 devpriv
->ai_act_dmapos
++;
653 devpriv
->ai_act_dmapos
%= raw_scanlen
;
659 static int move_block_from_dma(struct comedi_device
*dev
,
660 struct comedi_subdevice
*s
,
662 unsigned int num_samples
)
664 struct pci9118_private
*devpriv
= dev
->private;
665 unsigned int num_bytes
;
667 num_samples
= defragment_dma_buffer(dev
, s
, dma_buffer
, num_samples
);
668 devpriv
->ai_act_scan
+=
669 (s
->async
->cur_chan
+ num_samples
) / devpriv
->ai_n_scanlen
;
670 s
->async
->cur_chan
+= num_samples
;
671 s
->async
->cur_chan
%= devpriv
->ai_n_scanlen
;
673 cfc_write_array_to_buffer(s
, dma_buffer
,
674 num_samples
* sizeof(short));
675 if (num_bytes
< num_samples
* sizeof(short))
680 static int pci9118_exttrg_add(struct comedi_device
*dev
, unsigned char source
)
682 struct pci9118_private
*devpriv
= dev
->private;
685 return -1; /* incorrect source */
686 devpriv
->exttrg_users
|= (1 << source
);
687 devpriv
->IntControlReg
|= Int_DTrg
;
688 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
689 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
) | 0x1f00,
690 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
691 /* allow INT in AMCC */
695 static int pci9118_exttrg_del(struct comedi_device
*dev
, unsigned char source
)
697 struct pci9118_private
*devpriv
= dev
->private;
700 return -1; /* incorrect source */
701 devpriv
->exttrg_users
&= ~(1 << source
);
702 if (!devpriv
->exttrg_users
) { /* shutdown ext trg intterrupts */
703 devpriv
->IntControlReg
&= ~Int_DTrg
;
704 if (!devpriv
->IntControlReg
) /* all IRQ disabled */
705 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
) &
707 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
708 /* disable int in AMCC */
709 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
714 static void pci9118_calc_divisors(char mode
, struct comedi_device
*dev
,
715 struct comedi_subdevice
*s
,
716 unsigned int *tim1
, unsigned int *tim2
,
717 unsigned int flags
, int chans
,
718 unsigned int *div1
, unsigned int *div2
,
719 char usessh
, unsigned int chnsshfront
)
721 const struct boardtype
*this_board
= comedi_board(dev
);
722 struct pci9118_private
*devpriv
= dev
->private;
727 if (*tim2
< this_board
->ai_ns_min
)
728 *tim2
= this_board
->ai_ns_min
;
729 i8253_cascade_ns_to_timer(devpriv
->i8254_osc_base
, div1
, div2
,
730 tim2
, flags
& TRIG_ROUND_NEAREST
);
733 if (*tim2
< this_board
->ai_ns_min
)
734 *tim2
= this_board
->ai_ns_min
;
735 *div1
= *tim2
/ devpriv
->i8254_osc_base
;
736 /* convert timer (burst) */
737 if (*div1
< this_board
->ai_pacer_min
)
738 *div1
= this_board
->ai_pacer_min
;
739 *div2
= *tim1
/ devpriv
->i8254_osc_base
; /* scan timer */
740 *div2
= *div2
/ *div1
; /* major timer is c1*c2 */
744 *tim2
= *div1
* devpriv
->i8254_osc_base
;
745 /* real convert timer */
747 if (usessh
& (chnsshfront
== 0)) /* use BSSH signal */
748 if (*div2
< (chans
+ 2))
751 *tim1
= *div1
* *div2
* devpriv
->i8254_osc_base
;
756 static void start_pacer(struct comedi_device
*dev
, int mode
,
757 unsigned int divisor1
, unsigned int divisor2
)
759 outl(0x74, dev
->iobase
+ PCI9118_CNTCTRL
);
760 outl(0xb4, dev
->iobase
+ PCI9118_CNTCTRL
);
761 /* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
764 if ((mode
== 1) || (mode
== 2) || (mode
== 4)) {
765 outl(divisor2
& 0xff, dev
->iobase
+ PCI9118_CNT2
);
766 outl((divisor2
>> 8) & 0xff, dev
->iobase
+ PCI9118_CNT2
);
767 outl(divisor1
& 0xff, dev
->iobase
+ PCI9118_CNT1
);
768 outl((divisor1
>> 8) & 0xff, dev
->iobase
+ PCI9118_CNT1
);
772 static int pci9118_ai_cancel(struct comedi_device
*dev
,
773 struct comedi_subdevice
*s
)
775 struct pci9118_private
*devpriv
= dev
->private;
778 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
) &
780 devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
); /* stop DMA */
781 pci9118_exttrg_del(dev
, EXTTRG_AI
);
782 start_pacer(dev
, 0, 0, 0); /* stop 8254 counters */
783 devpriv
->AdFunctionReg
= AdFunction_PDTrg
| AdFunction_PETrg
;
784 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
786 * positive triggers, no S&H, no burst,
787 * burst stop, no post trigger,
788 * no about trigger, trigger stop
790 devpriv
->AdControlReg
= 0x00;
791 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
793 * bipolar, S.E., use 8254, stop 8354,
794 * internal trigger, soft trigger,
795 * disable INT and DMA
797 outl(0, dev
->iobase
+ PCI9118_BURST
);
798 outl(1, dev
->iobase
+ PCI9118_SCANMOD
);
799 outl(2, dev
->iobase
+ PCI9118_SCANMOD
); /* reset scan queue */
800 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
805 devpriv
->ai_act_scan
= 0;
806 devpriv
->ai_act_dmapos
= 0;
807 s
->async
->cur_chan
= 0;
808 s
->async
->inttrig
= NULL
;
809 devpriv
->ai_buf_ptr
= 0;
810 devpriv
->ai_neverending
= 0;
811 devpriv
->dma_actbuf
= 0;
813 if (!devpriv
->IntControlReg
)
814 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
) | 0x1f00,
815 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
816 /* allow INT in AMCC */
821 static char pci9118_decode_error_status(struct comedi_device
*dev
,
822 struct comedi_subdevice
*s
,
825 struct pci9118_private
*devpriv
= dev
->private;
828 comedi_error(dev
, "A/D FIFO Full status (Fatal Error!)");
829 devpriv
->ai_maskerr
&= ~0x100L
;
833 "A/D Burst Mode Overrun Status (Fatal Error!)");
834 devpriv
->ai_maskerr
&= ~0x008L
;
837 comedi_error(dev
, "A/D Over Speed Status (Warning!)");
838 devpriv
->ai_maskerr
&= ~0x004L
;
841 comedi_error(dev
, "A/D Overrun Status (Fatal Error!)");
842 devpriv
->ai_maskerr
&= ~0x002L
;
844 if (m
& devpriv
->ai_maskharderr
) {
845 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
846 pci9118_ai_cancel(dev
, s
);
847 comedi_event(dev
, s
);
854 static void pci9118_ai_munge(struct comedi_device
*dev
,
855 struct comedi_subdevice
*s
, void *data
,
856 unsigned int num_bytes
,
857 unsigned int start_chan_index
)
859 struct pci9118_private
*devpriv
= dev
->private;
860 unsigned int i
, num_samples
= num_bytes
/ sizeof(short);
863 for (i
= 0; i
< num_samples
; i
++) {
865 array
[i
] = be16_to_cpu(array
[i
]);
866 if (devpriv
->ai16bits
)
869 array
[i
] = (array
[i
] >> 4) & 0x0fff;
874 static void interrupt_pci9118_ai_onesample(struct comedi_device
*dev
,
875 struct comedi_subdevice
*s
,
876 unsigned short int_adstat
,
877 unsigned int int_amcc
,
878 unsigned short int_daq
)
880 struct pci9118_private
*devpriv
= dev
->private;
881 register short sampl
;
883 s
->async
->events
= 0;
885 if (int_adstat
& devpriv
->ai_maskerr
)
886 if (pci9118_decode_error_status(dev
, s
, int_adstat
))
889 sampl
= inw(dev
->iobase
+ PCI9118_AD_DATA
);
891 #ifdef PCI9118_PARANOIDCHECK
892 if (devpriv
->ai16bits
== 0) {
893 if ((sampl
& 0x000f) != devpriv
->chanlist
[s
->async
->cur_chan
]) {
896 ("comedi: A/D SAMPL - data dropout: "
897 "received channel %d, expected %d!\n",
899 devpriv
->chanlist
[s
->async
->cur_chan
]);
900 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
901 pci9118_ai_cancel(dev
, s
);
902 comedi_event(dev
, s
);
907 cfc_write_to_buffer(s
, sampl
);
908 s
->async
->cur_chan
++;
909 if (s
->async
->cur_chan
>= devpriv
->ai_n_scanlen
) {
911 s
->async
->cur_chan
%= devpriv
->ai_n_scanlen
;
912 devpriv
->ai_act_scan
++;
913 if (!(devpriv
->ai_neverending
))
914 if (devpriv
->ai_act_scan
>= devpriv
->ai_scans
) {
915 /* all data sampled */
916 pci9118_ai_cancel(dev
, s
);
917 s
->async
->events
|= COMEDI_CB_EOA
;
921 if (s
->async
->events
)
922 comedi_event(dev
, s
);
925 static void interrupt_pci9118_ai_dma(struct comedi_device
*dev
,
926 struct comedi_subdevice
*s
,
927 unsigned short int_adstat
,
928 unsigned int int_amcc
,
929 unsigned short int_daq
)
931 struct pci9118_private
*devpriv
= dev
->private;
932 unsigned int next_dma_buf
, samplesinbuf
, sampls
, m
;
934 if (int_amcc
& MASTER_ABORT_INT
) {
935 comedi_error(dev
, "AMCC IRQ - MASTER DMA ABORT!");
936 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
937 pci9118_ai_cancel(dev
, s
);
938 comedi_event(dev
, s
);
942 if (int_amcc
& TARGET_ABORT_INT
) {
943 comedi_error(dev
, "AMCC IRQ - TARGET DMA ABORT!");
944 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
945 pci9118_ai_cancel(dev
, s
);
946 comedi_event(dev
, s
);
949 if (int_adstat
& devpriv
->ai_maskerr
)
950 /* if (int_adstat & 0x106) */
951 if (pci9118_decode_error_status(dev
, s
, int_adstat
))
954 samplesinbuf
= devpriv
->dmabuf_use_size
[devpriv
->dma_actbuf
] >> 1;
955 /* number of received real samples */
957 if (devpriv
->dma_doublebuf
) { /*
958 * switch DMA buffers if is used
961 next_dma_buf
= 1 - devpriv
->dma_actbuf
;
962 outl(devpriv
->dmabuf_hw
[next_dma_buf
],
963 devpriv
->iobase_a
+ AMCC_OP_REG_MWAR
);
964 outl(devpriv
->dmabuf_use_size
[next_dma_buf
],
965 devpriv
->iobase_a
+ AMCC_OP_REG_MWTC
);
966 devpriv
->dmabuf_used_size
[next_dma_buf
] =
967 devpriv
->dmabuf_use_size
[next_dma_buf
];
968 if (devpriv
->ai_do
== 4)
969 interrupt_pci9118_ai_mode4_switch(dev
);
973 m
= devpriv
->ai_data_len
>> 1; /*
974 * how many samples is to
978 move_block_from_dma(dev
, s
,
979 devpriv
->dmabuf_virt
[devpriv
->dma_actbuf
],
981 m
= m
- sampls
; /* m= how many samples was transferred */
984 if (!devpriv
->ai_neverending
)
985 if (devpriv
->ai_act_scan
>= devpriv
->ai_scans
) {
986 /* all data sampled */
987 pci9118_ai_cancel(dev
, s
);
988 s
->async
->events
|= COMEDI_CB_EOA
;
991 if (devpriv
->dma_doublebuf
) { /* switch dma buffers */
992 devpriv
->dma_actbuf
= 1 - devpriv
->dma_actbuf
;
993 } else { /* restart DMA if is not used double buffering */
994 outl(devpriv
->dmabuf_hw
[0],
995 devpriv
->iobase_a
+ AMCC_OP_REG_MWAR
);
996 outl(devpriv
->dmabuf_use_size
[0],
997 devpriv
->iobase_a
+ AMCC_OP_REG_MWTC
);
998 if (devpriv
->ai_do
== 4)
999 interrupt_pci9118_ai_mode4_switch(dev
);
1002 comedi_event(dev
, s
);
1005 static irqreturn_t
interrupt_pci9118(int irq
, void *d
)
1007 struct comedi_device
*dev
= d
;
1008 struct pci9118_private
*devpriv
= dev
->private;
1009 unsigned int int_daq
= 0, int_amcc
, int_adstat
;
1012 return IRQ_NONE
; /* not fully initialized */
1014 int_daq
= inl(dev
->iobase
+ PCI9118_INTSRC
) & 0xf;
1015 /* get IRQ reasons from card */
1016 int_amcc
= inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1017 /* get INT register from AMCC chip */
1019 if ((!int_daq
) && (!(int_amcc
& ANY_S593X_INT
)))
1020 return IRQ_NONE
; /* interrupt from other source */
1022 outl(int_amcc
| 0x00ff0000, devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1023 /* shutdown IRQ reasons in AMCC */
1025 int_adstat
= inw(dev
->iobase
+ PCI9118_ADSTAT
) & 0x1ff;
1026 /* get STATUS register */
1028 if (devpriv
->ai_do
) {
1029 if (devpriv
->ai12_startstop
)
1030 if ((int_adstat
& AdStatus_DTH
) &&
1031 (int_daq
& Int_DTrg
)) {
1032 /* start stop of measure */
1033 if (devpriv
->ai12_startstop
& START_AI_EXT
) {
1034 devpriv
->ai12_startstop
&=
1036 if (!(devpriv
->ai12_startstop
&
1040 /* deactivate EXT trigger */
1041 start_pacer(dev
, devpriv
->ai_do
,
1042 devpriv
->ai_divisor1
,
1043 devpriv
->ai_divisor2
);
1045 outl(devpriv
->AdControlReg
,
1046 dev
->iobase
+ PCI9118_ADCNTRL
);
1048 if (devpriv
->ai12_startstop
&
1050 devpriv
->ai12_startstop
&=
1054 /* deactivate EXT trigger */
1055 devpriv
->ai_neverending
= 0;
1057 * well, on next interrupt from
1058 * DMA/EOC measure will stop
1064 (devpriv
->int_ai_func
) (dev
, &dev
->subdevices
[0], int_adstat
,
1071 static int pci9118_ai_inttrig(struct comedi_device
*dev
,
1072 struct comedi_subdevice
*s
, unsigned int trignum
)
1074 struct pci9118_private
*devpriv
= dev
->private;
1076 if (trignum
!= devpriv
->ai_inttrig_start
)
1079 devpriv
->ai12_startstop
&= ~START_AI_INT
;
1080 s
->async
->inttrig
= NULL
;
1082 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
1083 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1084 if (devpriv
->ai_do
!= 3) {
1085 start_pacer(dev
, devpriv
->ai_do
, devpriv
->ai_divisor1
,
1086 devpriv
->ai_divisor2
);
1087 devpriv
->AdControlReg
|= AdControl_SoftG
;
1089 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
1094 static int pci9118_ai_cmdtest(struct comedi_device
*dev
,
1095 struct comedi_subdevice
*s
,
1096 struct comedi_cmd
*cmd
)
1098 const struct boardtype
*this_board
= comedi_board(dev
);
1099 struct pci9118_private
*devpriv
= dev
->private;
1103 unsigned int divisor1
= 0, divisor2
= 0;
1105 /* Step 1 : check if triggers are trivially valid */
1107 err
|= cfc_check_trigger_src(&cmd
->start_src
,
1108 TRIG_NOW
| TRIG_EXT
| TRIG_INT
);
1110 flags
= TRIG_FOLLOW
;
1111 if (devpriv
->master
)
1112 flags
|= TRIG_TIMER
| TRIG_EXT
;
1113 err
|= cfc_check_trigger_src(&cmd
->scan_begin_src
, flags
);
1115 flags
= TRIG_TIMER
| TRIG_EXT
;
1116 if (devpriv
->master
)
1118 err
|= cfc_check_trigger_src(&cmd
->convert_src
, flags
);
1120 err
|= cfc_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
1121 err
|= cfc_check_trigger_src(&cmd
->stop_src
,
1122 TRIG_COUNT
| TRIG_NONE
| TRIG_EXT
);
1127 /* Step 2a : make sure trigger sources are unique */
1129 err
|= cfc_check_trigger_is_unique(cmd
->start_src
);
1130 err
|= cfc_check_trigger_is_unique(cmd
->scan_begin_src
);
1131 err
|= cfc_check_trigger_is_unique(cmd
->convert_src
);
1132 err
|= cfc_check_trigger_is_unique(cmd
->stop_src
);
1134 /* Step 2b : and mutually compatible */
1136 if (cmd
->start_src
== TRIG_EXT
&& cmd
->scan_begin_src
== TRIG_EXT
)
1139 if (cmd
->start_src
== TRIG_INT
&& cmd
->scan_begin_src
== TRIG_INT
)
1142 if ((cmd
->scan_begin_src
& (TRIG_TIMER
| TRIG_EXT
)) &&
1143 (!(cmd
->convert_src
& (TRIG_TIMER
| TRIG_NOW
))))
1146 if ((cmd
->scan_begin_src
== TRIG_FOLLOW
) &&
1147 (!(cmd
->convert_src
& (TRIG_TIMER
| TRIG_EXT
))))
1150 if (cmd
->stop_src
== TRIG_EXT
&& cmd
->scan_begin_src
== TRIG_EXT
)
1156 /* step 3: make sure arguments are trivially compatible */
1158 if (cmd
->start_src
& (TRIG_NOW
| TRIG_EXT
))
1159 if (cmd
->start_arg
!= 0) {
1164 if (cmd
->scan_begin_src
& (TRIG_FOLLOW
| TRIG_EXT
))
1165 if (cmd
->scan_begin_arg
!= 0) {
1166 cmd
->scan_begin_arg
= 0;
1170 if ((cmd
->scan_begin_src
== TRIG_TIMER
) &&
1171 (cmd
->convert_src
== TRIG_TIMER
) && (cmd
->scan_end_arg
== 1)) {
1172 cmd
->scan_begin_src
= TRIG_FOLLOW
;
1173 cmd
->convert_arg
= cmd
->scan_begin_arg
;
1174 cmd
->scan_begin_arg
= 0;
1177 if (cmd
->scan_begin_src
== TRIG_TIMER
)
1178 if (cmd
->scan_begin_arg
< this_board
->ai_ns_min
) {
1179 cmd
->scan_begin_arg
= this_board
->ai_ns_min
;
1183 if (cmd
->scan_begin_src
== TRIG_EXT
)
1184 if (cmd
->scan_begin_arg
) {
1185 cmd
->scan_begin_arg
= 0;
1187 if (cmd
->scan_end_arg
> 65535) {
1188 cmd
->scan_end_arg
= 65535;
1193 if (cmd
->convert_src
& (TRIG_TIMER
| TRIG_NOW
))
1194 if (cmd
->convert_arg
< this_board
->ai_ns_min
) {
1195 cmd
->convert_arg
= this_board
->ai_ns_min
;
1199 if (cmd
->convert_src
== TRIG_EXT
)
1200 if (cmd
->convert_arg
) {
1201 cmd
->convert_arg
= 0;
1205 if (cmd
->stop_src
== TRIG_COUNT
) {
1206 if (!cmd
->stop_arg
) {
1210 } else { /* TRIG_NONE */
1211 if (cmd
->stop_arg
!= 0) {
1217 if (!cmd
->chanlist_len
) {
1218 cmd
->chanlist_len
= 1;
1222 if (cmd
->chanlist_len
> this_board
->n_aichanlist
) {
1223 cmd
->chanlist_len
= this_board
->n_aichanlist
;
1227 if (cmd
->scan_end_arg
< cmd
->chanlist_len
) {
1228 cmd
->scan_end_arg
= cmd
->chanlist_len
;
1232 if ((cmd
->scan_end_arg
% cmd
->chanlist_len
)) {
1234 cmd
->chanlist_len
* (cmd
->scan_end_arg
/ cmd
->chanlist_len
);
1241 /* step 4: fix up any arguments */
1243 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
1244 tmp
= cmd
->scan_begin_arg
;
1245 i8253_cascade_ns_to_timer(devpriv
->i8254_osc_base
, &divisor1
,
1246 &divisor2
, &cmd
->scan_begin_arg
,
1247 cmd
->flags
& TRIG_ROUND_MASK
);
1248 if (cmd
->scan_begin_arg
< this_board
->ai_ns_min
)
1249 cmd
->scan_begin_arg
= this_board
->ai_ns_min
;
1250 if (tmp
!= cmd
->scan_begin_arg
)
1254 if (cmd
->convert_src
& (TRIG_TIMER
| TRIG_NOW
)) {
1255 tmp
= cmd
->convert_arg
;
1256 i8253_cascade_ns_to_timer(devpriv
->i8254_osc_base
, &divisor1
,
1257 &divisor2
, &cmd
->convert_arg
,
1258 cmd
->flags
& TRIG_ROUND_MASK
);
1259 if (cmd
->convert_arg
< this_board
->ai_ns_min
)
1260 cmd
->convert_arg
= this_board
->ai_ns_min
;
1261 if (tmp
!= cmd
->convert_arg
)
1263 if (cmd
->scan_begin_src
== TRIG_TIMER
1264 && cmd
->convert_src
== TRIG_NOW
) {
1265 if (cmd
->convert_arg
== 0) {
1266 if (cmd
->scan_begin_arg
<
1267 this_board
->ai_ns_min
*
1268 (cmd
->scan_end_arg
+ 2)) {
1269 cmd
->scan_begin_arg
=
1270 this_board
->ai_ns_min
*
1271 (cmd
->scan_end_arg
+ 2);
1275 if (cmd
->scan_begin_arg
<
1276 cmd
->convert_arg
* cmd
->chanlist_len
) {
1277 cmd
->scan_begin_arg
=
1290 if (!check_channel_list(dev
, s
, cmd
->chanlist_len
,
1291 cmd
->chanlist
, 0, 0))
1292 return 5; /* incorrect channels list */
1297 static int Compute_and_setup_dma(struct comedi_device
*dev
)
1299 struct pci9118_private
*devpriv
= dev
->private;
1300 unsigned int dmalen0
, dmalen1
, i
;
1302 dmalen0
= devpriv
->dmabuf_size
[0];
1303 dmalen1
= devpriv
->dmabuf_size
[1];
1304 /* isn't output buff smaller that our DMA buff? */
1305 if (dmalen0
> (devpriv
->ai_data_len
)) {
1306 dmalen0
= devpriv
->ai_data_len
& ~3L; /*
1307 * align to 32bit down
1310 if (dmalen1
> (devpriv
->ai_data_len
)) {
1311 dmalen1
= devpriv
->ai_data_len
& ~3L; /*
1312 * align to 32bit down
1316 /* we want wake up every scan? */
1317 if (devpriv
->ai_flags
& TRIG_WAKE_EOS
) {
1318 if (dmalen0
< (devpriv
->ai_n_realscanlen
<< 1)) {
1319 /* uff, too short DMA buffer, disable EOS support! */
1320 devpriv
->ai_flags
&= (~TRIG_WAKE_EOS
);
1322 ("comedi%d: WAR: DMA0 buf too short, can't "
1323 "support TRIG_WAKE_EOS (%d<%d)\n",
1324 dev
->minor
, dmalen0
,
1325 devpriv
->ai_n_realscanlen
<< 1);
1327 /* short first DMA buffer to one scan */
1328 dmalen0
= devpriv
->ai_n_realscanlen
<< 1;
1329 if (devpriv
->useeoshandle
)
1333 ("comedi%d: ERR: DMA0 buf len bug? "
1335 dev
->minor
, dmalen0
);
1340 if (devpriv
->ai_flags
& TRIG_WAKE_EOS
) {
1341 if (dmalen1
< (devpriv
->ai_n_realscanlen
<< 1)) {
1342 /* uff, too short DMA buffer, disable EOS support! */
1343 devpriv
->ai_flags
&= (~TRIG_WAKE_EOS
);
1345 ("comedi%d: WAR: DMA1 buf too short, "
1346 "can't support TRIG_WAKE_EOS (%d<%d)\n",
1347 dev
->minor
, dmalen1
,
1348 devpriv
->ai_n_realscanlen
<< 1);
1350 /* short second DMA buffer to one scan */
1351 dmalen1
= devpriv
->ai_n_realscanlen
<< 1;
1352 if (devpriv
->useeoshandle
)
1356 ("comedi%d: ERR: DMA1 buf len bug? "
1358 dev
->minor
, dmalen1
);
1364 /* transfer without TRIG_WAKE_EOS */
1365 if (!(devpriv
->ai_flags
& TRIG_WAKE_EOS
)) {
1366 /* if it's possible then align DMA buffers to length of scan */
1369 (dmalen0
/ (devpriv
->ai_n_realscanlen
<< 1)) *
1370 (devpriv
->ai_n_realscanlen
<< 1);
1373 dmalen0
= i
; /* uff. very long scan? */
1376 (dmalen1
/ (devpriv
->ai_n_realscanlen
<< 1)) *
1377 (devpriv
->ai_n_realscanlen
<< 1);
1380 dmalen1
= i
; /* uff. very long scan? */
1382 * if measure isn't neverending then test, if it fits whole
1383 * into one or two DMA buffers
1385 if (!devpriv
->ai_neverending
) {
1386 /* fits whole measure into one DMA buffer? */
1388 ((devpriv
->ai_n_realscanlen
<< 1) *
1389 devpriv
->ai_scans
)) {
1391 (devpriv
->ai_n_realscanlen
<< 1) *
1395 * fits whole measure into
1399 ((devpriv
->ai_n_realscanlen
<< 1) *
1400 devpriv
->ai_scans
- dmalen0
))
1402 (devpriv
->ai_n_realscanlen
<< 1) *
1403 devpriv
->ai_scans
- dmalen0
;
1409 /* these DMA buffer size will be used */
1410 devpriv
->dma_actbuf
= 0;
1411 devpriv
->dmabuf_use_size
[0] = dmalen0
;
1412 devpriv
->dmabuf_use_size
[1] = dmalen1
;
1415 if (devpriv
->ai_n_scanlen
< this_board
->half_fifo_size
) {
1416 devpriv
->dmabuf_panic_size
[0] =
1417 (this_board
->half_fifo_size
/ devpriv
->ai_n_scanlen
+
1418 1) * devpriv
->ai_n_scanlen
* sizeof(short);
1419 devpriv
->dmabuf_panic_size
[1] =
1420 (this_board
->half_fifo_size
/ devpriv
->ai_n_scanlen
+
1421 1) * devpriv
->ai_n_scanlen
* sizeof(short);
1423 devpriv
->dmabuf_panic_size
[0] =
1424 (devpriv
->ai_n_scanlen
<< 1) % devpriv
->dmabuf_size
[0];
1425 devpriv
->dmabuf_panic_size
[1] =
1426 (devpriv
->ai_n_scanlen
<< 1) % devpriv
->dmabuf_size
[1];
1430 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
) & (~EN_A2P_TRANSFERS
),
1431 devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
); /* stop DMA */
1432 outl(devpriv
->dmabuf_hw
[0], devpriv
->iobase_a
+ AMCC_OP_REG_MWAR
);
1433 outl(devpriv
->dmabuf_use_size
[0], devpriv
->iobase_a
+ AMCC_OP_REG_MWTC
);
1434 /* init DMA transfer */
1435 outl(0x00000000 | AINT_WRITE_COMPL
,
1436 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1437 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
1439 outl(inl(devpriv
->iobase_a
+
1440 AMCC_OP_REG_MCSR
) | RESET_A2P_FLAGS
| A2P_HI_PRIORITY
|
1441 EN_A2P_TRANSFERS
, devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
);
1442 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
) | EN_A2P_TRANSFERS
,
1443 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1444 /* allow bus mastering */
1449 static int pci9118_ai_docmd_sampl(struct comedi_device
*dev
,
1450 struct comedi_subdevice
*s
)
1452 struct pci9118_private
*devpriv
= dev
->private;
1454 switch (devpriv
->ai_do
) {
1456 devpriv
->AdControlReg
|= AdControl_TmrTr
;
1459 comedi_error(dev
, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
1462 devpriv
->AdControlReg
|= AdControl_ExtM
;
1465 comedi_error(dev
, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
1469 "pci9118_ai_docmd_sampl() mode number bug!\n");
1473 devpriv
->int_ai_func
= interrupt_pci9118_ai_onesample
;
1474 /* transfer function */
1476 if (devpriv
->ai12_startstop
)
1477 pci9118_exttrg_add(dev
, EXTTRG_AI
);
1478 /* activate EXT trigger */
1480 if ((devpriv
->ai_do
== 1) || (devpriv
->ai_do
== 2))
1481 devpriv
->IntControlReg
|= Int_Timer
;
1483 devpriv
->AdControlReg
|= AdControl_Int
;
1485 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
) | 0x1f00,
1486 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1487 /* allow INT in AMCC */
1489 if (!(devpriv
->ai12_startstop
& (START_AI_EXT
| START_AI_INT
))) {
1490 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
1491 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1492 if (devpriv
->ai_do
!= 3) {
1493 start_pacer(dev
, devpriv
->ai_do
, devpriv
->ai_divisor1
,
1494 devpriv
->ai_divisor2
);
1495 devpriv
->AdControlReg
|= AdControl_SoftG
;
1497 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
1503 static int pci9118_ai_docmd_dma(struct comedi_device
*dev
,
1504 struct comedi_subdevice
*s
)
1506 struct pci9118_private
*devpriv
= dev
->private;
1508 Compute_and_setup_dma(dev
);
1510 switch (devpriv
->ai_do
) {
1512 devpriv
->AdControlReg
|=
1513 ((AdControl_TmrTr
| AdControl_Dma
) & 0xff);
1516 devpriv
->AdControlReg
|=
1517 ((AdControl_TmrTr
| AdControl_Dma
) & 0xff);
1518 devpriv
->AdFunctionReg
=
1519 AdFunction_PDTrg
| AdFunction_PETrg
| AdFunction_BM
|
1521 if (devpriv
->usessh
&& (!devpriv
->softsshdelay
))
1522 devpriv
->AdFunctionReg
|= AdFunction_BSSH
;
1523 outl(devpriv
->ai_n_realscanlen
, dev
->iobase
+ PCI9118_BURST
);
1526 devpriv
->AdControlReg
|=
1527 ((AdControl_ExtM
| AdControl_Dma
) & 0xff);
1528 devpriv
->AdFunctionReg
= AdFunction_PDTrg
| AdFunction_PETrg
;
1531 devpriv
->AdControlReg
|=
1532 ((AdControl_TmrTr
| AdControl_Dma
) & 0xff);
1533 devpriv
->AdFunctionReg
=
1534 AdFunction_PDTrg
| AdFunction_PETrg
| AdFunction_AM
;
1535 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1536 outl(0x30, dev
->iobase
+ PCI9118_CNTCTRL
);
1537 outl((devpriv
->dmabuf_hw
[0] >> 1) & 0xff,
1538 dev
->iobase
+ PCI9118_CNT0
);
1539 outl((devpriv
->dmabuf_hw
[0] >> 9) & 0xff,
1540 dev
->iobase
+ PCI9118_CNT0
);
1541 devpriv
->AdFunctionReg
|= AdFunction_Start
;
1544 comedi_error(dev
, "pci9118_ai_docmd_dma() mode number bug!\n");
1548 if (devpriv
->ai12_startstop
) {
1549 pci9118_exttrg_add(dev
, EXTTRG_AI
);
1550 /* activate EXT trigger */
1553 devpriv
->int_ai_func
= interrupt_pci9118_ai_dma
;
1554 /* transfer function */
1556 outl(0x02000000 | AINT_WRITE_COMPL
,
1557 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1559 if (!(devpriv
->ai12_startstop
& (START_AI_EXT
| START_AI_INT
))) {
1560 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1561 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
1562 if (devpriv
->ai_do
!= 3) {
1563 start_pacer(dev
, devpriv
->ai_do
, devpriv
->ai_divisor1
,
1564 devpriv
->ai_divisor2
);
1565 devpriv
->AdControlReg
|= AdControl_SoftG
;
1567 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
1573 static int pci9118_ai_cmd(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
1575 const struct boardtype
*this_board
= comedi_board(dev
);
1576 struct pci9118_private
*devpriv
= dev
->private;
1577 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
1578 unsigned int addchans
= 0;
1581 devpriv
->ai12_startstop
= 0;
1582 devpriv
->ai_flags
= cmd
->flags
;
1583 devpriv
->ai_n_chan
= cmd
->chanlist_len
;
1584 devpriv
->ai_n_scanlen
= cmd
->scan_end_arg
;
1585 devpriv
->ai_chanlist
= cmd
->chanlist
;
1586 devpriv
->ai_data
= s
->async
->prealloc_buf
;
1587 devpriv
->ai_data_len
= s
->async
->prealloc_bufsz
;
1588 devpriv
->ai_timer1
= 0;
1589 devpriv
->ai_timer2
= 0;
1590 devpriv
->ai_add_front
= 0;
1591 devpriv
->ai_add_back
= 0;
1592 devpriv
->ai_maskerr
= 0x10e;
1594 /* prepare for start/stop conditions */
1595 if (cmd
->start_src
== TRIG_EXT
)
1596 devpriv
->ai12_startstop
|= START_AI_EXT
;
1597 if (cmd
->stop_src
== TRIG_EXT
) {
1598 devpriv
->ai_neverending
= 1;
1599 devpriv
->ai12_startstop
|= STOP_AI_EXT
;
1601 if (cmd
->start_src
== TRIG_INT
) {
1602 devpriv
->ai12_startstop
|= START_AI_INT
;
1603 devpriv
->ai_inttrig_start
= cmd
->start_arg
;
1604 s
->async
->inttrig
= pci9118_ai_inttrig
;
1607 if (cmd
->stop_src
== TRIG_INT
) {
1608 devpriv
->ai_neverending
= 1;
1609 devpriv
->ai12_startstop
|= STOP_AI_INT
;
1612 if (cmd
->stop_src
== TRIG_NONE
)
1613 devpriv
->ai_neverending
= 1;
1614 if (cmd
->stop_src
== TRIG_COUNT
) {
1615 devpriv
->ai_scans
= cmd
->stop_arg
;
1616 devpriv
->ai_neverending
= 0;
1618 devpriv
->ai_scans
= 0;
1621 /* use sample&hold signal? */
1622 if (cmd
->convert_src
== TRIG_NOW
)
1623 devpriv
->usessh
= 1;
1626 devpriv
->usessh
= 0;
1630 * use additional sample at end of every scan
1631 * to satisty DMA 32 bit transfer?
1633 devpriv
->ai_add_front
= 0;
1634 devpriv
->ai_add_back
= 0;
1635 devpriv
->useeoshandle
= 0;
1636 if (devpriv
->master
) {
1637 devpriv
->usedma
= 1;
1638 if ((cmd
->flags
& TRIG_WAKE_EOS
) &&
1639 (devpriv
->ai_n_scanlen
== 1)) {
1640 if (cmd
->convert_src
== TRIG_NOW
)
1641 devpriv
->ai_add_back
= 1;
1642 if (cmd
->convert_src
== TRIG_TIMER
) {
1643 devpriv
->usedma
= 0;
1645 * use INT transfer if scanlist
1646 * have only one channel
1650 if ((cmd
->flags
& TRIG_WAKE_EOS
) &&
1651 (devpriv
->ai_n_scanlen
& 1) &&
1652 (devpriv
->ai_n_scanlen
> 1)) {
1653 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) {
1655 * vpriv->useeoshandle=1; // change DMA transfer
1656 * block to fit EOS on every second call
1658 devpriv
->usedma
= 0;
1660 * XXX maybe can be corrected to use 16 bit DMA
1663 * well, we must insert one sample
1664 * to end of EOS to meet 32 bit transfer
1666 devpriv
->ai_add_back
= 1;
1669 } else { /* interrupt transfer don't need any correction */
1670 devpriv
->usedma
= 0;
1674 * we need software S&H signal?
1675 * It adds two samples before every scan as minimum
1677 if (devpriv
->usessh
&& devpriv
->softsshdelay
) {
1678 devpriv
->ai_add_front
= 2;
1679 if ((devpriv
->usedma
== 1) && (devpriv
->ai_add_back
== 1)) {
1680 /* move it to front */
1681 devpriv
->ai_add_front
++;
1682 devpriv
->ai_add_back
= 0;
1684 if (cmd
->convert_arg
< this_board
->ai_ns_min
)
1685 cmd
->convert_arg
= this_board
->ai_ns_min
;
1686 addchans
= devpriv
->softsshdelay
/ cmd
->convert_arg
;
1687 if (devpriv
->softsshdelay
% cmd
->convert_arg
)
1689 if (addchans
> (devpriv
->ai_add_front
- 1)) {
1690 /* uff, still short */
1691 devpriv
->ai_add_front
= addchans
+ 1;
1692 if (devpriv
->usedma
== 1)
1693 if ((devpriv
->ai_add_front
+
1694 devpriv
->ai_n_chan
+
1695 devpriv
->ai_add_back
) & 1)
1696 devpriv
->ai_add_front
++;
1697 /* round up to 32 bit */
1700 /* well, we now know what must be all added */
1701 devpriv
->ai_n_realscanlen
= /*
1702 * what we must take from card in real
1703 * to have ai_n_scanlen on output?
1705 (devpriv
->ai_add_front
+ devpriv
->ai_n_chan
+
1706 devpriv
->ai_add_back
) * (devpriv
->ai_n_scanlen
/
1707 devpriv
->ai_n_chan
);
1709 /* check and setup channel list */
1710 if (!check_channel_list(dev
, s
, devpriv
->ai_n_chan
,
1711 devpriv
->ai_chanlist
, devpriv
->ai_add_front
,
1712 devpriv
->ai_add_back
))
1714 if (!setup_channel_list(dev
, s
, devpriv
->ai_n_chan
,
1715 devpriv
->ai_chanlist
, 0, devpriv
->ai_add_front
,
1716 devpriv
->ai_add_back
, devpriv
->usedma
,
1717 devpriv
->useeoshandle
))
1720 /* compute timers settings */
1722 * simplest way, fr=4Mhz/(tim1*tim2),
1723 * channel manipulation without timers effect
1725 if (((cmd
->scan_begin_src
== TRIG_FOLLOW
) ||
1726 (cmd
->scan_begin_src
== TRIG_EXT
) ||
1727 (cmd
->scan_begin_src
== TRIG_INT
)) &&
1728 (cmd
->convert_src
== TRIG_TIMER
)) {
1729 /* both timer is used for one time */
1730 if (cmd
->scan_begin_src
== TRIG_EXT
)
1734 pci9118_calc_divisors(devpriv
->ai_do
, dev
, s
,
1735 &cmd
->scan_begin_arg
, &cmd
->convert_arg
,
1737 devpriv
->ai_n_realscanlen
,
1738 &devpriv
->ai_divisor1
,
1739 &devpriv
->ai_divisor2
, devpriv
->usessh
,
1740 devpriv
->ai_add_front
);
1741 devpriv
->ai_timer2
= cmd
->convert_arg
;
1744 if ((cmd
->scan_begin_src
== TRIG_TIMER
) &&
1745 ((cmd
->convert_src
== TRIG_TIMER
) ||
1746 (cmd
->convert_src
== TRIG_NOW
))) {
1747 /* double timed action */
1748 if (!devpriv
->usedma
) {
1750 "cmd->scan_begin_src=TRIG_TIMER works "
1751 "only with bus mastering!");
1756 pci9118_calc_divisors(devpriv
->ai_do
, dev
, s
,
1757 &cmd
->scan_begin_arg
, &cmd
->convert_arg
,
1759 devpriv
->ai_n_realscanlen
,
1760 &devpriv
->ai_divisor1
,
1761 &devpriv
->ai_divisor2
, devpriv
->usessh
,
1762 devpriv
->ai_add_front
);
1763 devpriv
->ai_timer1
= cmd
->scan_begin_arg
;
1764 devpriv
->ai_timer2
= cmd
->convert_arg
;
1767 if ((cmd
->scan_begin_src
== TRIG_FOLLOW
)
1768 && (cmd
->convert_src
== TRIG_EXT
)) {
1772 start_pacer(dev
, -1, 0, 0); /* stop pacer */
1774 devpriv
->AdControlReg
= 0; /*
1775 * bipolar, S.E., use 8254, stop 8354,
1776 * internal trigger, soft trigger,
1779 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
1780 devpriv
->AdFunctionReg
= AdFunction_PDTrg
| AdFunction_PETrg
;
1782 * positive triggers, no S&H, no burst,
1783 * burst stop, no post trigger,
1784 * no about trigger, trigger stop
1786 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1788 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
1789 inl(dev
->iobase
+ PCI9118_ADSTAT
); /*
1793 inl(dev
->iobase
+ PCI9118_INTSRC
);
1795 devpriv
->ai_act_scan
= 0;
1796 devpriv
->ai_act_dmapos
= 0;
1797 s
->async
->cur_chan
= 0;
1798 devpriv
->ai_buf_ptr
= 0;
1800 if (devpriv
->usedma
)
1801 ret
= pci9118_ai_docmd_dma(dev
, s
);
1803 ret
= pci9118_ai_docmd_sampl(dev
, s
);
1808 static int pci9118_reset(struct comedi_device
*dev
)
1810 struct pci9118_private
*devpriv
= dev
->private;
1812 devpriv
->IntControlReg
= 0;
1813 devpriv
->exttrg_users
= 0;
1814 inl(dev
->iobase
+ PCI9118_INTCTRL
);
1815 outl(devpriv
->IntControlReg
, dev
->iobase
+ PCI9118_INTCTRL
);
1816 /* disable interrupts source */
1817 outl(0x30, dev
->iobase
+ PCI9118_CNTCTRL
);
1818 /* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
1819 start_pacer(dev
, 0, 0, 0); /* stop 8254 counters */
1820 devpriv
->AdControlReg
= 0;
1821 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
1823 * bipolar, S.E., use 8254,
1824 * stop 8354, internal trigger,
1826 * disable INT and DMA
1828 outl(0, dev
->iobase
+ PCI9118_BURST
);
1829 outl(1, dev
->iobase
+ PCI9118_SCANMOD
);
1830 outl(2, dev
->iobase
+ PCI9118_SCANMOD
); /* reset scan queue */
1831 devpriv
->AdFunctionReg
= AdFunction_PDTrg
| AdFunction_PETrg
;
1832 outl(devpriv
->AdFunctionReg
, dev
->iobase
+ PCI9118_ADFUNC
);
1834 * positive triggers, no S&H,
1835 * no burst, burst stop,
1841 devpriv
->ao_data
[0] = 2047;
1842 devpriv
->ao_data
[1] = 2047;
1843 outl(devpriv
->ao_data
[0], dev
->iobase
+ PCI9118_DA1
);
1844 /* reset A/D outs to 0V */
1845 outl(devpriv
->ao_data
[1], dev
->iobase
+ PCI9118_DA2
);
1846 outl(0, dev
->iobase
+ PCI9118_DO
); /* reset digi outs to L */
1848 inl(dev
->iobase
+ PCI9118_AD_DATA
);
1849 outl(0, dev
->iobase
+ PCI9118_DELFIFO
); /* flush FIFO */
1850 outl(0, dev
->iobase
+ PCI9118_INTSRC
); /* remove INT requests */
1851 inl(dev
->iobase
+ PCI9118_ADSTAT
); /* flush A/D status register */
1852 inl(dev
->iobase
+ PCI9118_INTSRC
); /* flush INT requests */
1853 devpriv
->AdControlReg
= 0;
1854 outl(devpriv
->AdControlReg
, dev
->iobase
+ PCI9118_ADCNTRL
);
1856 * bipolar, S.E., use 8254,
1857 * stop 8354, internal trigger,
1859 * disable INT and DMA
1862 devpriv
->cnt0_users
= 0;
1863 devpriv
->exttrg_users
= 0;
1868 static struct pci_dev
*pci9118_find_pci(struct comedi_device
*dev
,
1869 struct comedi_devconfig
*it
)
1871 const struct boardtype
*this_board
= comedi_board(dev
);
1872 struct pci_dev
*pcidev
= NULL
;
1873 int bus
= it
->options
[0];
1874 int slot
= it
->options
[1];
1876 for_each_pci_dev(pcidev
) {
1877 if (pcidev
->vendor
!= PCI_VENDOR_ID_AMCC
)
1879 if (pcidev
->device
!= this_board
->device_id
)
1882 /* requested particular bus/slot */
1883 if (pcidev
->bus
->number
!= bus
||
1884 PCI_SLOT(pcidev
->devfn
) != slot
)
1888 * Look for device that isn't in use.
1889 * Enable PCI device and request regions.
1891 if (comedi_pci_enable(pcidev
, "adl_pci9118"))
1893 printk(KERN_ERR
", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx",
1894 pcidev
->bus
->number
,
1895 PCI_SLOT(pcidev
->devfn
),
1896 PCI_FUNC(pcidev
->devfn
),
1897 (unsigned long)pci_resource_start(pcidev
, 2),
1898 (unsigned long)pci_resource_start(pcidev
, 0));
1902 "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
1903 dev
->minor
, bus
, slot
);
1907 static int pci9118_attach(struct comedi_device
*dev
,
1908 struct comedi_devconfig
*it
)
1910 const struct boardtype
*this_board
= comedi_board(dev
);
1911 struct pci9118_private
*devpriv
;
1912 struct pci_dev
*pcidev
;
1913 struct comedi_subdevice
*s
;
1915 unsigned short master
;
1919 printk("comedi%d: adl_pci9118: board=%s", dev
->minor
, this_board
->name
);
1921 if (it
->options
[3] & 1)
1922 master
= 0; /* user don't want use bus master */
1926 devpriv
= kzalloc(sizeof(*devpriv
), GFP_KERNEL
);
1929 dev
->private = devpriv
;
1931 pcidev
= pci9118_find_pci(dev
, it
);
1934 comedi_set_hw_dev(dev
, &pcidev
->dev
);
1937 pci_set_master(pcidev
);
1940 devpriv
->iobase_a
= pci_resource_start(pcidev
, 0);
1941 dev
->iobase
= pci_resource_start(pcidev
, 2);
1943 dev
->board_name
= this_board
->name
;
1947 if (it
->options
[3] & 2)
1948 irq
= 0; /* user don't want use IRQ */
1950 if (request_irq(irq
, interrupt_pci9118
, IRQF_SHARED
,
1951 "ADLink PCI-9118", dev
)) {
1952 printk(", unable to allocate IRQ %d, DISABLING IT",
1954 irq
= 0; /* Can't use IRQ */
1956 printk(", irq=%u", irq
);
1959 printk(", IRQ disabled");
1964 if (master
) { /* alloc DMA buffers */
1965 devpriv
->dma_doublebuf
= 0;
1966 for (i
= 0; i
< 2; i
++) {
1967 for (pages
= 4; pages
>= 0; pages
--) {
1968 devpriv
->dmabuf_virt
[i
] =
1969 (short *)__get_free_pages(GFP_KERNEL
,
1971 if (devpriv
->dmabuf_virt
[i
])
1974 if (devpriv
->dmabuf_virt
[i
]) {
1975 devpriv
->dmabuf_pages
[i
] = pages
;
1976 devpriv
->dmabuf_size
[i
] = PAGE_SIZE
* pages
;
1977 devpriv
->dmabuf_samples
[i
] =
1978 devpriv
->dmabuf_size
[i
] >> 1;
1979 devpriv
->dmabuf_hw
[i
] =
1980 virt_to_bus((void *)
1981 devpriv
->dmabuf_virt
[i
]);
1984 if (!devpriv
->dmabuf_virt
[0]) {
1985 printk(", Can't allocate DMA buffer, DMA disabled!");
1989 if (devpriv
->dmabuf_virt
[1])
1990 devpriv
->dma_doublebuf
= 1;
1994 devpriv
->master
= master
;
1995 if (devpriv
->master
)
1996 printk(", bus master");
1998 printk(", no bus master");
2000 devpriv
->usemux
= 0;
2001 if (it
->options
[2] > 0) {
2002 devpriv
->usemux
= it
->options
[2];
2003 if (devpriv
->usemux
> 256)
2004 devpriv
->usemux
= 256; /* max 256 channels! */
2005 if (it
->options
[4] > 0)
2006 if (devpriv
->usemux
> 128) {
2007 devpriv
->usemux
= 128;
2008 /* max 128 channels with softare S&H! */
2010 printk(", ext. mux %d channels", devpriv
->usemux
);
2013 devpriv
->softsshdelay
= it
->options
[4];
2014 if (devpriv
->softsshdelay
< 0) {
2015 /* select sample&hold signal polarity */
2016 devpriv
->softsshdelay
= -devpriv
->softsshdelay
;
2017 devpriv
->softsshsample
= 0x80;
2018 devpriv
->softsshhold
= 0x00;
2020 devpriv
->softsshsample
= 0x00;
2021 devpriv
->softsshhold
= 0x80;
2026 pci_read_config_word(pcidev
, PCI_COMMAND
, &u16w
);
2027 pci_write_config_word(pcidev
, PCI_COMMAND
, u16w
| 64);
2028 /* Enable parity check for parity error */
2030 ret
= comedi_alloc_subdevices(dev
, 4);
2034 s
= &dev
->subdevices
[0];
2035 dev
->read_subdev
= s
;
2036 s
->type
= COMEDI_SUBD_AI
;
2037 s
->subdev_flags
= SDF_READABLE
| SDF_COMMON
| SDF_GROUND
| SDF_DIFF
;
2038 if (devpriv
->usemux
)
2039 s
->n_chan
= devpriv
->usemux
;
2041 s
->n_chan
= this_board
->n_aichan
;
2043 s
->maxdata
= this_board
->ai_maxdata
;
2044 s
->len_chanlist
= this_board
->n_aichanlist
;
2045 s
->range_table
= this_board
->rangelist_ai
;
2046 s
->cancel
= pci9118_ai_cancel
;
2047 s
->insn_read
= pci9118_insn_read_ai
;
2049 s
->subdev_flags
|= SDF_CMD_READ
;
2050 s
->do_cmdtest
= pci9118_ai_cmdtest
;
2051 s
->do_cmd
= pci9118_ai_cmd
;
2052 s
->munge
= pci9118_ai_munge
;
2055 s
= &dev
->subdevices
[1];
2056 s
->type
= COMEDI_SUBD_AO
;
2057 s
->subdev_flags
= SDF_WRITABLE
| SDF_GROUND
| SDF_COMMON
;
2058 s
->n_chan
= this_board
->n_aochan
;
2059 s
->maxdata
= this_board
->ao_maxdata
;
2060 s
->len_chanlist
= this_board
->n_aochan
;
2061 s
->range_table
= this_board
->rangelist_ao
;
2062 s
->insn_write
= pci9118_insn_write_ao
;
2063 s
->insn_read
= pci9118_insn_read_ao
;
2065 s
= &dev
->subdevices
[2];
2066 s
->type
= COMEDI_SUBD_DI
;
2067 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
| SDF_COMMON
;
2070 s
->len_chanlist
= 4;
2071 s
->range_table
= &range_digital
;
2072 s
->io_bits
= 0; /* all bits input */
2073 s
->insn_bits
= pci9118_insn_bits_di
;
2075 s
= &dev
->subdevices
[3];
2076 s
->type
= COMEDI_SUBD_DO
;
2077 s
->subdev_flags
= SDF_WRITABLE
| SDF_GROUND
| SDF_COMMON
;
2080 s
->len_chanlist
= 4;
2081 s
->range_table
= &range_digital
;
2082 s
->io_bits
= 0xf; /* all bits output */
2083 s
->insn_bits
= pci9118_insn_bits_do
;
2086 devpriv
->i8254_osc_base
= 250; /* 250ns=4MHz */
2087 devpriv
->ai_maskharderr
= 0x10a;
2088 /* default measure crash condition */
2089 if (it
->options
[5]) /* disable some requested */
2090 devpriv
->ai_maskharderr
&= ~it
->options
[5];
2092 switch (this_board
->ai_maxdata
) {
2094 devpriv
->ai16bits
= 1;
2097 devpriv
->ai16bits
= 0;
2103 static void pci9118_detach(struct comedi_device
*dev
)
2105 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
2106 struct pci9118_private
*devpriv
= dev
->private;
2112 free_irq(dev
->irq
, dev
);
2113 if (devpriv
->dmabuf_virt
[0])
2114 free_pages((unsigned long)devpriv
->dmabuf_virt
[0],
2115 devpriv
->dmabuf_pages
[0]);
2116 if (devpriv
->dmabuf_virt
[1])
2117 free_pages((unsigned long)devpriv
->dmabuf_virt
[1],
2118 devpriv
->dmabuf_pages
[1]);
2122 comedi_pci_disable(pcidev
);
2124 pci_dev_put(pcidev
);
2128 static const struct boardtype boardtypes
[] = {
2130 .name
= "pci9118dg",
2131 .vendor_id
= PCI_VENDOR_ID_AMCC
,
2132 .device_id
= 0x80d9,
2133 .iorange_amcc
= AMCC_OP_REG_SIZE
,
2134 .iorange_9118
= IORANGE_9118
,
2138 .n_aichanlist
= PCI9118_CHANLEN
,
2140 .ai_maxdata
= 0x0fff,
2141 .ao_maxdata
= 0x0fff,
2142 .rangelist_ai
= &range_pci9118dg_hr
,
2143 .rangelist_ao
= &range_bipolar10
,
2146 .half_fifo_size
= 512,
2148 .name
= "pci9118hg",
2149 .vendor_id
= PCI_VENDOR_ID_AMCC
,
2150 .device_id
= 0x80d9,
2151 .iorange_amcc
= AMCC_OP_REG_SIZE
,
2152 .iorange_9118
= IORANGE_9118
,
2156 .n_aichanlist
= PCI9118_CHANLEN
,
2158 .ai_maxdata
= 0x0fff,
2159 .ao_maxdata
= 0x0fff,
2160 .rangelist_ai
= &range_pci9118hg
,
2161 .rangelist_ao
= &range_bipolar10
,
2164 .half_fifo_size
= 512,
2166 .name
= "pci9118hr",
2167 .vendor_id
= PCI_VENDOR_ID_AMCC
,
2168 .device_id
= 0x80d9,
2169 .iorange_amcc
= AMCC_OP_REG_SIZE
,
2170 .iorange_9118
= IORANGE_9118
,
2174 .n_aichanlist
= PCI9118_CHANLEN
,
2176 .ai_maxdata
= 0xffff,
2177 .ao_maxdata
= 0x0fff,
2178 .rangelist_ai
= &range_pci9118dg_hr
,
2179 .rangelist_ao
= &range_bipolar10
,
2182 .half_fifo_size
= 512,
2186 static struct comedi_driver adl_pci9118_driver
= {
2187 .driver_name
= "adl_pci9118",
2188 .module
= THIS_MODULE
,
2189 .attach
= pci9118_attach
,
2190 .detach
= pci9118_detach
,
2191 .num_names
= ARRAY_SIZE(boardtypes
),
2192 .board_name
= &boardtypes
[0].name
,
2193 .offset
= sizeof(struct boardtype
),
2196 static int __devinit
adl_pci9118_pci_probe(struct pci_dev
*dev
,
2197 const struct pci_device_id
*ent
)
2199 return comedi_pci_auto_config(dev
, &adl_pci9118_driver
);
2202 static void __devexit
adl_pci9118_pci_remove(struct pci_dev
*dev
)
2204 comedi_pci_auto_unconfig(dev
);
2207 static DEFINE_PCI_DEVICE_TABLE(adl_pci9118_pci_table
) = {
2208 { PCI_DEVICE(PCI_VENDOR_ID_AMCC
, 0x80d9) },
2211 MODULE_DEVICE_TABLE(pci
, adl_pci9118_pci_table
);
2213 static struct pci_driver adl_pci9118_pci_driver
= {
2214 .name
= "adl_pci9118",
2215 .id_table
= adl_pci9118_pci_table
,
2216 .probe
= adl_pci9118_pci_probe
,
2217 .remove
= __devexit_p(adl_pci9118_pci_remove
),
2219 module_comedi_pci_driver(adl_pci9118_driver
, adl_pci9118_pci_driver
);
2221 MODULE_AUTHOR("Comedi http://www.comedi.org");
2222 MODULE_DESCRIPTION("Comedi low-level driver");
2223 MODULE_LICENSE("GPL");