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 #undef PCI9118_EXTDEBUG /*
85 * if defined then driver prints
90 #ifdef PCI9118_EXTDEBUG
91 #define DPRINTK(fmt, args...) printk(fmt, ## args)
93 #define DPRINTK(fmt, args...)
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 vendor_id; /* PCI vendor a device ID of card */
227 int iorange_amcc; /* iorange for own S5933 region */
228 int iorange_9118; /* pass thru card region size */
229 int n_aichan; /* num of A/D chans */
230 int n_aichand; /* num of A/D chans in diff mode */
232 * num of A/D chans with
233 * external multiplexor
235 int n_aichanlist; /* len of chanlist */
236 int n_aochan; /* num of D/A chans */
237 int ai_maxdata; /* resolution of A/D */
238 int ao_maxdata; /* resolution of D/A */
239 const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */
240 const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */
241 unsigned int ai_ns_min; /* max sample speed of card v ns */
242 unsigned int ai_pacer_min; /*
243 * minimal pacer value
244 * (c1*c2 or c1 in burst)
246 int half_fifo_size; /* size of FIFO/2 */
250 struct pci9118_private {
251 unsigned long iobase_a; /* base+size for AMCC chip */
252 unsigned int master; /* master capable */
253 unsigned int usemux; /* we want to use external multiplexor! */
254 #ifdef PCI9118_PARANOIDCHECK
255 unsigned short chanlist[PCI9118_CHANLEN + 1]; /*
259 unsigned char chanlistlen; /* number of scanlist */
261 unsigned char AdControlReg; /* A/D control register */
262 unsigned char IntControlReg; /* Interrupt control register */
263 unsigned char AdFunctionReg; /* A/D function register */
264 char valid; /* driver is ok */
265 char ai_neverending; /* we do unlimited AI */
266 unsigned int i8254_osc_base; /* frequence of onboard oscilator */
267 unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */
268 unsigned int ai_act_scan; /* how many scans we finished */
269 unsigned int ai_buf_ptr; /* data buffer ptr in samples */
270 unsigned int ai_n_chan; /* how many channels is measured */
271 unsigned int ai_n_scanlen; /* len of actual scanlist */
272 unsigned int ai_n_realscanlen; /*
273 * what we must transfer for one
274 * outgoing scan include front/back adds
276 unsigned int ai_act_dmapos; /* position in actual real stream */
277 unsigned int ai_add_front; /*
278 * how many channels we must add
279 * before scan to satisfy S&H?
281 unsigned int ai_add_back; /*
282 * how many channels we must add
283 * before scan to satisfy DMA?
285 unsigned int *ai_chanlist; /* actual chanlist */
286 unsigned int ai_timer1;
287 unsigned int ai_timer2;
288 unsigned int ai_flags;
289 char ai12_startstop; /*
290 * measure can start/stop
291 * on external trigger
293 unsigned int ai_divisor1, ai_divisor2; /*
294 * divisors for start of measure
297 unsigned int ai_data_len;
299 short ao_data[2]; /* data output buffer */
300 unsigned int ai_scans; /* number of scans to do */
301 char dma_doublebuf; /* we can use double buffering */
302 unsigned int dma_actbuf; /* which buffer is used now */
303 short *dmabuf_virt[2]; /*
304 * pointers to begin of
307 unsigned long dmabuf_hw[2]; /* hw address of DMA buff */
308 unsigned int dmabuf_size[2]; /*
309 * size of dma buffer in bytes
311 unsigned int dmabuf_use_size[2]; /*
312 * which size we may now use
315 unsigned int dmabuf_used_size[2]; /* which size was truly used */
316 unsigned int dmabuf_panic_size[2];
317 unsigned int dmabuf_samples[2]; /* size in samples */
318 int dmabuf_pages[2]; /* number of pages in buffer */
319 unsigned char cnt0_users; /*
320 * bit field of 8254 CNT0 users
321 * (0-unused, 1-AO, 2-DI, 3-DO)
323 unsigned char exttrg_users; /*
324 * bit field of external trigger
325 * users(0-AI, 1-AO, 2-DI, 3-DO)
327 unsigned int cnt0_divisor; /* actual CNT0 divisor */
328 void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *,
332 * ptr to actual interrupt
335 unsigned char ai16bits; /* =1 16 bit card */
336 unsigned char usedma; /* =1 use DMA transfer and not INT */
337 unsigned char useeoshandle; /*
338 * =1 change WAKE_EOS DMA transfer
339 * to fit on every second
341 unsigned char usessh; /* =1 turn on S&H support */
343 * >0 use software S&H,
344 * numer is requested delay in ns
346 unsigned char softsshsample; /*
347 * polarity of S&H signal
350 unsigned char softsshhold; /*
351 * polarity of S&H signal
354 unsigned int ai_maskerr; /* which warning was printed */
355 unsigned int ai_maskharderr; /* on which error bits stops */
356 unsigned int ai_inttrig_start; /* TRIG_INT for start */
359 #define devpriv ((struct pci9118_private *)dev->private)
360 #define this_board ((struct boardtype *)dev->board_ptr)
363 ==============================================================================
366 static int check_channel_list(struct comedi_device *dev,
367 struct comedi_subdevice *s, int n_chan,
368 unsigned int *chanlist, int frontadd,
370 static int setup_channel_list(struct comedi_device *dev,
371 struct comedi_subdevice *s, int n_chan,
372 unsigned int *chanlist, int rot, int frontadd,
373 int backadd, int usedma, char eoshandle);
374 static void start_pacer(struct comedi_device *dev, int mode,
375 unsigned int divisor1, unsigned int divisor2);
376 static int pci9118_reset(struct comedi_device *dev);
377 static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source);
378 static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source);
379 static int pci9118_ai_cancel(struct comedi_device *dev,
380 struct comedi_subdevice *s);
381 static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
382 struct comedi_subdevice *s,
383 unsigned int *tim1, unsigned int *tim2,
384 unsigned int flags, int chans,
385 unsigned int *div1, unsigned int *div2,
386 char usessh, unsigned int chnsshfront);
389 ==============================================================================
391 static int pci9118_insn_read_ai(struct comedi_device *dev,
392 struct comedi_subdevice *s,
393 struct comedi_insn *insn, unsigned int *data)
398 devpriv->AdControlReg = AdControl_Int & 0xff;
399 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
400 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
402 * positive triggers, no S&H,
403 * no burst, burst stop,
409 if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
412 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
414 for (n = 0; n < insn->n; n++) {
415 outw(0, dev->iobase + PCI9118_SOFTTRG); /* start conversion */
419 if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
424 comedi_error(dev, "A/D insn timeout");
426 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
430 if (devpriv->ai16bits) {
433 PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
436 (inw(dev->iobase + PCI9118_AD_DATA) >> 4) & 0xfff;
440 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
446 ==============================================================================
448 static int pci9118_insn_write_ao(struct comedi_device *dev,
449 struct comedi_subdevice *s,
450 struct comedi_insn *insn, unsigned int *data)
454 ch = CR_CHAN(insn->chanspec);
456 chanreg = PCI9118_DA2;
458 chanreg = PCI9118_DA1;
461 for (n = 0; n < insn->n; n++) {
462 outl(data[n], dev->iobase + chanreg);
463 devpriv->ao_data[ch] = data[n];
470 ==============================================================================
472 static int pci9118_insn_read_ao(struct comedi_device *dev,
473 struct comedi_subdevice *s,
474 struct comedi_insn *insn, unsigned int *data)
478 chan = CR_CHAN(insn->chanspec);
479 for (n = 0; n < insn->n; n++)
480 data[n] = devpriv->ao_data[chan];
486 ==============================================================================
488 static int pci9118_insn_bits_di(struct comedi_device *dev,
489 struct comedi_subdevice *s,
490 struct comedi_insn *insn, unsigned int *data)
492 data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
498 ==============================================================================
500 static int pci9118_insn_bits_do(struct comedi_device *dev,
501 struct comedi_subdevice *s,
502 struct comedi_insn *insn, unsigned int *data)
505 s->state &= ~data[0];
506 s->state |= (data[0] & data[1]);
507 outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
515 ==============================================================================
517 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev)
519 devpriv->AdFunctionReg =
520 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
521 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
522 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
523 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
524 dev->iobase + PCI9118_CNT0);
525 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
526 dev->iobase + PCI9118_CNT0);
527 devpriv->AdFunctionReg |= AdFunction_Start;
528 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
531 static unsigned int defragment_dma_buffer(struct comedi_device *dev,
532 struct comedi_subdevice *s,
534 unsigned int num_samples)
536 unsigned int i = 0, j = 0;
537 unsigned int start_pos = devpriv->ai_add_front,
538 stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
539 unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
540 devpriv->ai_add_back;
542 for (i = 0; i < num_samples; i++) {
543 if (devpriv->ai_act_dmapos >= start_pos &&
544 devpriv->ai_act_dmapos < stop_pos) {
545 dma_buffer[j++] = dma_buffer[i];
547 devpriv->ai_act_dmapos++;
548 devpriv->ai_act_dmapos %= raw_scanlen;
555 ==============================================================================
557 static int move_block_from_dma(struct comedi_device *dev,
558 struct comedi_subdevice *s,
560 unsigned int num_samples)
562 unsigned int num_bytes;
564 num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
565 devpriv->ai_act_scan +=
566 (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
567 s->async->cur_chan += num_samples;
568 s->async->cur_chan %= devpriv->ai_n_scanlen;
570 cfc_write_array_to_buffer(s, dma_buffer,
571 num_samples * sizeof(short));
572 if (num_bytes < num_samples * sizeof(short))
578 ==============================================================================
580 static char pci9118_decode_error_status(struct comedi_device *dev,
581 struct comedi_subdevice *s,
585 comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
586 devpriv->ai_maskerr &= ~0x100L;
590 "A/D Burst Mode Overrun Status (Fatal Error!)");
591 devpriv->ai_maskerr &= ~0x008L;
594 comedi_error(dev, "A/D Over Speed Status (Warning!)");
595 devpriv->ai_maskerr &= ~0x004L;
598 comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
599 devpriv->ai_maskerr &= ~0x002L;
601 if (m & devpriv->ai_maskharderr) {
602 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
603 pci9118_ai_cancel(dev, s);
604 comedi_event(dev, s);
611 static void pci9118_ai_munge(struct comedi_device *dev,
612 struct comedi_subdevice *s, void *data,
613 unsigned int num_bytes,
614 unsigned int start_chan_index)
616 unsigned int i, num_samples = num_bytes / sizeof(short);
619 for (i = 0; i < num_samples; i++) {
621 array[i] = be16_to_cpu(array[i]);
622 if (devpriv->ai16bits)
625 array[i] = (array[i] >> 4) & 0x0fff;
631 ==============================================================================
633 static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
634 struct comedi_subdevice *s,
635 unsigned short int_adstat,
636 unsigned int int_amcc,
637 unsigned short int_daq)
639 register short sampl;
641 s->async->events = 0;
643 if (int_adstat & devpriv->ai_maskerr)
644 if (pci9118_decode_error_status(dev, s, int_adstat))
647 sampl = inw(dev->iobase + PCI9118_AD_DATA);
649 #ifdef PCI9118_PARANOIDCHECK
650 if (devpriv->ai16bits == 0) {
651 if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) {
654 ("comedi: A/D SAMPL - data dropout: "
655 "received channel %d, expected %d!\n",
657 devpriv->chanlist[s->async->cur_chan]);
658 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
659 pci9118_ai_cancel(dev, s);
660 comedi_event(dev, s);
665 cfc_write_to_buffer(s, sampl);
666 s->async->cur_chan++;
667 if (s->async->cur_chan >= devpriv->ai_n_scanlen) {
669 s->async->cur_chan %= devpriv->ai_n_scanlen;
670 devpriv->ai_act_scan++;
671 if (!(devpriv->ai_neverending))
672 if (devpriv->ai_act_scan >= devpriv->ai_scans) {
673 /* all data sampled */
674 pci9118_ai_cancel(dev, s);
675 s->async->events |= COMEDI_CB_EOA;
679 if (s->async->events)
680 comedi_event(dev, s);
684 ==============================================================================
686 static void interrupt_pci9118_ai_dma(struct comedi_device *dev,
687 struct comedi_subdevice *s,
688 unsigned short int_adstat,
689 unsigned int int_amcc,
690 unsigned short int_daq)
692 unsigned int next_dma_buf, samplesinbuf, sampls, m;
694 if (int_amcc & MASTER_ABORT_INT) {
695 comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
696 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
697 pci9118_ai_cancel(dev, s);
698 comedi_event(dev, s);
702 if (int_amcc & TARGET_ABORT_INT) {
703 comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
704 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
705 pci9118_ai_cancel(dev, s);
706 comedi_event(dev, s);
709 if (int_adstat & devpriv->ai_maskerr)
710 /* if (int_adstat & 0x106) */
711 if (pci9118_decode_error_status(dev, s, int_adstat))
714 samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1;
715 /* number of received real samples */
716 /* DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf); */
718 if (devpriv->dma_doublebuf) { /*
719 * switch DMA buffers if is used
722 next_dma_buf = 1 - devpriv->dma_actbuf;
723 outl(devpriv->dmabuf_hw[next_dma_buf],
724 devpriv->iobase_a + AMCC_OP_REG_MWAR);
725 outl(devpriv->dmabuf_use_size[next_dma_buf],
726 devpriv->iobase_a + AMCC_OP_REG_MWTC);
727 devpriv->dmabuf_used_size[next_dma_buf] =
728 devpriv->dmabuf_use_size[next_dma_buf];
729 if (devpriv->ai_do == 4)
730 interrupt_pci9118_ai_mode4_switch(dev);
734 m = devpriv->ai_data_len >> 1; /*
735 * how many samples is to
739 * DPRINTK("samps=%d m=%d %d %d\n",
740 * samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr);
743 move_block_from_dma(dev, s,
744 devpriv->dmabuf_virt[devpriv->dma_actbuf],
746 m = m - sampls; /* m= how many samples was transferred */
748 /* DPRINTK("YYY\n"); */
750 if (!devpriv->ai_neverending)
751 if (devpriv->ai_act_scan >= devpriv->ai_scans) {
752 /* all data sampled */
753 pci9118_ai_cancel(dev, s);
754 s->async->events |= COMEDI_CB_EOA;
757 if (devpriv->dma_doublebuf) { /* switch dma buffers */
758 devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
759 } else { /* restart DMA if is not used double buffering */
760 outl(devpriv->dmabuf_hw[0],
761 devpriv->iobase_a + AMCC_OP_REG_MWAR);
762 outl(devpriv->dmabuf_use_size[0],
763 devpriv->iobase_a + AMCC_OP_REG_MWTC);
764 if (devpriv->ai_do == 4)
765 interrupt_pci9118_ai_mode4_switch(dev);
768 comedi_event(dev, s);
772 ==============================================================================
774 static irqreturn_t interrupt_pci9118(int irq, void *d)
776 struct comedi_device *dev = d;
777 unsigned int int_daq = 0, int_amcc, int_adstat;
780 return IRQ_NONE; /* not fully initialized */
782 int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf;
783 /* get IRQ reasons from card */
784 int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
785 /* get INT register from AMCC chip */
788 * DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x
789 * MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n",
790 * int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR),
791 * inl(devpriv->iobase_a+AMCC_OP_REG_MWTC),
792 * inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do);
795 if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
796 return IRQ_NONE; /* interrupt from other source */
798 outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
799 /* shutdown IRQ reasons in AMCC */
801 int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff;
802 /* get STATUS register */
804 if (devpriv->ai_do) {
805 if (devpriv->ai12_startstop)
806 if ((int_adstat & AdStatus_DTH) &&
807 (int_daq & Int_DTrg)) {
808 /* start stop of measure */
809 if (devpriv->ai12_startstop & START_AI_EXT) {
810 devpriv->ai12_startstop &=
812 if (!(devpriv->ai12_startstop &
816 /* deactivate EXT trigger */
817 start_pacer(dev, devpriv->ai_do,
818 devpriv->ai_divisor1,
819 devpriv->ai_divisor2);
821 outl(devpriv->AdControlReg,
822 dev->iobase + PCI9118_ADCNTRL);
824 if (devpriv->ai12_startstop &
826 devpriv->ai12_startstop &=
830 /* deactivate EXT trigger */
831 devpriv->ai_neverending = 0;
833 * well, on next interrupt from
834 * DMA/EOC measure will stop
840 (devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat,
848 ==============================================================================
850 static int pci9118_ai_inttrig(struct comedi_device *dev,
851 struct comedi_subdevice *s, unsigned int trignum)
853 if (trignum != devpriv->ai_inttrig_start)
856 devpriv->ai12_startstop &= ~START_AI_INT;
857 s->async->inttrig = NULL;
859 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
860 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
861 if (devpriv->ai_do != 3) {
862 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
863 devpriv->ai_divisor2);
864 devpriv->AdControlReg |= AdControl_SoftG;
866 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
872 ==============================================================================
874 static int pci9118_ai_cmdtest(struct comedi_device *dev,
875 struct comedi_subdevice *s,
876 struct comedi_cmd *cmd)
880 unsigned int divisor1 = 0, divisor2 = 0;
882 /* step 1: make sure trigger sources are trivially valid */
884 tmp = cmd->start_src;
885 cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT;
886 if (!cmd->start_src || tmp != cmd->start_src)
889 tmp = cmd->scan_begin_src;
891 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW;
893 cmd->scan_begin_src &= TRIG_FOLLOW;
895 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
898 tmp = cmd->convert_src;
900 cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW;
902 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
904 if (!cmd->convert_src || tmp != cmd->convert_src)
907 tmp = cmd->scan_end_src;
908 cmd->scan_end_src &= TRIG_COUNT;
909 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
913 cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT;
914 if (!cmd->stop_src || tmp != cmd->stop_src)
922 * make sure trigger sources are
923 * unique and mutually compatible
926 if (cmd->start_src != TRIG_NOW &&
927 cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) {
928 cmd->start_src = TRIG_NOW;
932 if (cmd->scan_begin_src != TRIG_TIMER &&
933 cmd->scan_begin_src != TRIG_EXT &&
934 cmd->scan_begin_src != TRIG_INT &&
935 cmd->scan_begin_src != TRIG_FOLLOW) {
936 cmd->scan_begin_src = TRIG_FOLLOW;
940 if (cmd->convert_src != TRIG_TIMER &&
941 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) {
942 cmd->convert_src = TRIG_TIMER;
946 if (cmd->scan_end_src != TRIG_COUNT) {
947 cmd->scan_end_src = TRIG_COUNT;
951 if (cmd->stop_src != TRIG_NONE &&
952 cmd->stop_src != TRIG_COUNT &&
953 cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) {
954 cmd->stop_src = TRIG_COUNT;
958 if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
959 cmd->start_src = TRIG_NOW;
963 if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) {
964 cmd->start_src = TRIG_NOW;
968 if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
969 (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) {
970 cmd->convert_src = TRIG_TIMER;
974 if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
975 (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) {
976 cmd->convert_src = TRIG_TIMER;
980 if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
981 cmd->stop_src = TRIG_COUNT;
988 /* step 3: make sure arguments are trivially compatible */
990 if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
991 if (cmd->start_arg != 0) {
996 if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
997 if (cmd->scan_begin_arg != 0) {
998 cmd->scan_begin_arg = 0;
1002 if ((cmd->scan_begin_src == TRIG_TIMER) &&
1003 (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
1004 cmd->scan_begin_src = TRIG_FOLLOW;
1005 cmd->convert_arg = cmd->scan_begin_arg;
1006 cmd->scan_begin_arg = 0;
1009 if (cmd->scan_begin_src == TRIG_TIMER)
1010 if (cmd->scan_begin_arg < this_board->ai_ns_min) {
1011 cmd->scan_begin_arg = this_board->ai_ns_min;
1015 if (cmd->scan_begin_src == TRIG_EXT)
1016 if (cmd->scan_begin_arg) {
1017 cmd->scan_begin_arg = 0;
1019 if (cmd->scan_end_arg > 65535) {
1020 cmd->scan_end_arg = 65535;
1025 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
1026 if (cmd->convert_arg < this_board->ai_ns_min) {
1027 cmd->convert_arg = this_board->ai_ns_min;
1031 if (cmd->convert_src == TRIG_EXT)
1032 if (cmd->convert_arg) {
1033 cmd->convert_arg = 0;
1037 if (cmd->stop_src == TRIG_COUNT) {
1038 if (!cmd->stop_arg) {
1042 } else { /* TRIG_NONE */
1043 if (cmd->stop_arg != 0) {
1049 if (!cmd->chanlist_len) {
1050 cmd->chanlist_len = 1;
1054 if (cmd->chanlist_len > this_board->n_aichanlist) {
1055 cmd->chanlist_len = this_board->n_aichanlist;
1059 if (cmd->scan_end_arg < cmd->chanlist_len) {
1060 cmd->scan_end_arg = cmd->chanlist_len;
1064 if ((cmd->scan_end_arg % cmd->chanlist_len)) {
1066 cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
1073 /* step 4: fix up any arguments */
1075 if (cmd->scan_begin_src == TRIG_TIMER) {
1076 tmp = cmd->scan_begin_arg;
1077 /* printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1078 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1079 &divisor2, &cmd->scan_begin_arg,
1080 cmd->flags & TRIG_ROUND_MASK);
1081 /* printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1082 if (cmd->scan_begin_arg < this_board->ai_ns_min)
1083 cmd->scan_begin_arg = this_board->ai_ns_min;
1084 if (tmp != cmd->scan_begin_arg)
1088 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
1089 tmp = cmd->convert_arg;
1090 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1091 &divisor2, &cmd->convert_arg,
1092 cmd->flags & TRIG_ROUND_MASK);
1093 /* printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1094 if (cmd->convert_arg < this_board->ai_ns_min)
1095 cmd->convert_arg = this_board->ai_ns_min;
1096 if (tmp != cmd->convert_arg)
1098 if (cmd->scan_begin_src == TRIG_TIMER
1099 && cmd->convert_src == TRIG_NOW) {
1100 if (cmd->convert_arg == 0) {
1101 if (cmd->scan_begin_arg <
1102 this_board->ai_ns_min *
1103 (cmd->scan_end_arg + 2)) {
1104 cmd->scan_begin_arg =
1105 this_board->ai_ns_min *
1106 (cmd->scan_end_arg + 2);
1107 /* printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1111 if (cmd->scan_begin_arg <
1112 cmd->convert_arg * cmd->chanlist_len) {
1113 cmd->scan_begin_arg =
1116 /* printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
1127 if (!check_channel_list(dev, s, cmd->chanlist_len,
1128 cmd->chanlist, 0, 0))
1129 return 5; /* incorrect channels list */
1135 ==============================================================================
1137 static int Compute_and_setup_dma(struct comedi_device *dev)
1139 unsigned int dmalen0, dmalen1, i;
1141 DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n");
1142 dmalen0 = devpriv->dmabuf_size[0];
1143 dmalen1 = devpriv->dmabuf_size[1];
1144 DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1,
1145 devpriv->ai_data_len);
1146 /* isn't output buff smaller that our DMA buff? */
1147 if (dmalen0 > (devpriv->ai_data_len)) {
1148 dmalen0 = devpriv->ai_data_len & ~3L; /*
1149 * align to 32bit down
1152 if (dmalen1 > (devpriv->ai_data_len)) {
1153 dmalen1 = devpriv->ai_data_len & ~3L; /*
1154 * align to 32bit down
1157 DPRINTK("2 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1);
1159 /* we want wake up every scan? */
1160 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1161 if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
1162 /* uff, too short DMA buffer, disable EOS support! */
1163 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1165 ("comedi%d: WAR: DMA0 buf too short, can't "
1166 "support TRIG_WAKE_EOS (%d<%d)\n",
1167 dev->minor, dmalen0,
1168 devpriv->ai_n_realscanlen << 1);
1170 /* short first DMA buffer to one scan */
1171 dmalen0 = devpriv->ai_n_realscanlen << 1;
1173 ("21 dmalen0=%d ai_n_realscanlen=%d "
1174 "useeoshandle=%d\n",
1175 dmalen0, devpriv->ai_n_realscanlen,
1176 devpriv->useeoshandle);
1177 if (devpriv->useeoshandle)
1181 ("comedi%d: ERR: DMA0 buf len bug? "
1183 dev->minor, dmalen0);
1188 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1189 if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
1190 /* uff, too short DMA buffer, disable EOS support! */
1191 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1193 ("comedi%d: WAR: DMA1 buf too short, "
1194 "can't support TRIG_WAKE_EOS (%d<%d)\n",
1195 dev->minor, dmalen1,
1196 devpriv->ai_n_realscanlen << 1);
1198 /* short second DMA buffer to one scan */
1199 dmalen1 = devpriv->ai_n_realscanlen << 1;
1201 ("22 dmalen1=%d ai_n_realscanlen=%d "
1202 "useeoshandle=%d\n",
1203 dmalen1, devpriv->ai_n_realscanlen,
1204 devpriv->useeoshandle);
1205 if (devpriv->useeoshandle)
1209 ("comedi%d: ERR: DMA1 buf len bug? "
1211 dev->minor, dmalen1);
1217 DPRINTK("3 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1);
1218 /* transfer without TRIG_WAKE_EOS */
1219 if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
1220 /* if it's possible then align DMA buffers to length of scan */
1223 (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
1224 (devpriv->ai_n_realscanlen << 1);
1227 dmalen0 = i; /* uff. very long scan? */
1230 (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
1231 (devpriv->ai_n_realscanlen << 1);
1234 dmalen1 = i; /* uff. very long scan? */
1236 * if measure isn't neverending then test, if it fits whole
1237 * into one or two DMA buffers
1239 if (!devpriv->ai_neverending) {
1240 /* fits whole measure into one DMA buffer? */
1242 ((devpriv->ai_n_realscanlen << 1) *
1243 devpriv->ai_scans)) {
1245 ("3.0 ai_n_realscanlen=%d ai_scans=%d\n",
1246 devpriv->ai_n_realscanlen,
1249 (devpriv->ai_n_realscanlen << 1) *
1251 DPRINTK("3.1 dmalen0=%d dmalen1=%d\n", dmalen0,
1255 * fits whole measure into
1259 ((devpriv->ai_n_realscanlen << 1) *
1260 devpriv->ai_scans - dmalen0))
1262 (devpriv->ai_n_realscanlen << 1) *
1263 devpriv->ai_scans - dmalen0;
1264 DPRINTK("3.2 dmalen0=%d dmalen1=%d\n", dmalen0,
1271 DPRINTK("4 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1);
1273 /* these DMA buffer size will be used */
1274 devpriv->dma_actbuf = 0;
1275 devpriv->dmabuf_use_size[0] = dmalen0;
1276 devpriv->dmabuf_use_size[1] = dmalen1;
1278 DPRINTK("5 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1);
1280 if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
1281 devpriv->dmabuf_panic_size[0] =
1282 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1283 1) * devpriv->ai_n_scanlen * sizeof(short);
1284 devpriv->dmabuf_panic_size[1] =
1285 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1286 1) * devpriv->ai_n_scanlen * sizeof(short);
1288 devpriv->dmabuf_panic_size[0] =
1289 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
1290 devpriv->dmabuf_panic_size[1] =
1291 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
1295 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS),
1296 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
1297 outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
1298 outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
1299 /* init DMA transfer */
1300 outl(0x00000000 | AINT_WRITE_COMPL,
1301 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1302 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
1304 outl(inl(devpriv->iobase_a +
1305 AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
1306 EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
1307 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS,
1308 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1309 /* allow bus mastering */
1311 DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n");
1316 ==============================================================================
1318 static int pci9118_ai_docmd_sampl(struct comedi_device *dev,
1319 struct comedi_subdevice *s)
1321 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n",
1322 dev->minor, devpriv->ai_do);
1323 switch (devpriv->ai_do) {
1325 devpriv->AdControlReg |= AdControl_TmrTr;
1328 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
1331 devpriv->AdControlReg |= AdControl_ExtM;
1334 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
1338 "pci9118_ai_docmd_sampl() mode number bug!\n");
1342 devpriv->int_ai_func = interrupt_pci9118_ai_onesample;
1343 /* transfer function */
1345 if (devpriv->ai12_startstop)
1346 pci9118_exttrg_add(dev, EXTTRG_AI);
1347 /* activate EXT trigger */
1349 if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
1350 devpriv->IntControlReg |= Int_Timer;
1352 devpriv->AdControlReg |= AdControl_Int;
1354 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
1355 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1356 /* allow INT in AMCC */
1358 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1359 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1360 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1361 if (devpriv->ai_do != 3) {
1362 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1363 devpriv->ai_divisor2);
1364 devpriv->AdControlReg |= AdControl_SoftG;
1366 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1369 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n");
1374 ==============================================================================
1376 static int pci9118_ai_docmd_dma(struct comedi_device *dev,
1377 struct comedi_subdevice *s)
1379 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n",
1380 dev->minor, devpriv->ai_do, devpriv->usedma);
1381 Compute_and_setup_dma(dev);
1383 switch (devpriv->ai_do) {
1385 devpriv->AdControlReg |=
1386 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1389 devpriv->AdControlReg |=
1390 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1391 devpriv->AdFunctionReg =
1392 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
1394 if (devpriv->usessh && (!devpriv->softsshdelay))
1395 devpriv->AdFunctionReg |= AdFunction_BSSH;
1396 outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
1399 devpriv->AdControlReg |=
1400 ((AdControl_ExtM | AdControl_Dma) & 0xff);
1401 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1404 devpriv->AdControlReg |=
1405 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1406 devpriv->AdFunctionReg =
1407 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
1408 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1409 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1410 outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
1411 dev->iobase + PCI9118_CNT0);
1412 outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
1413 dev->iobase + PCI9118_CNT0);
1414 devpriv->AdFunctionReg |= AdFunction_Start;
1417 comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
1421 if (devpriv->ai12_startstop) {
1422 pci9118_exttrg_add(dev, EXTTRG_AI);
1423 /* activate EXT trigger */
1426 devpriv->int_ai_func = interrupt_pci9118_ai_dma;
1427 /* transfer function */
1429 outl(0x02000000 | AINT_WRITE_COMPL,
1430 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1432 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1433 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1434 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1435 if (devpriv->ai_do != 3) {
1436 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1437 devpriv->ai_divisor2);
1438 devpriv->AdControlReg |= AdControl_SoftG;
1440 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1443 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n");
1448 ==============================================================================
1450 static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1452 struct comedi_cmd *cmd = &s->async->cmd;
1453 unsigned int addchans = 0;
1456 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor);
1457 devpriv->ai12_startstop = 0;
1458 devpriv->ai_flags = cmd->flags;
1459 devpriv->ai_n_chan = cmd->chanlist_len;
1460 devpriv->ai_n_scanlen = cmd->scan_end_arg;
1461 devpriv->ai_chanlist = cmd->chanlist;
1462 devpriv->ai_data = s->async->prealloc_buf;
1463 devpriv->ai_data_len = s->async->prealloc_bufsz;
1464 devpriv->ai_timer1 = 0;
1465 devpriv->ai_timer2 = 0;
1466 devpriv->ai_add_front = 0;
1467 devpriv->ai_add_back = 0;
1468 devpriv->ai_maskerr = 0x10e;
1470 /* prepare for start/stop conditions */
1471 if (cmd->start_src == TRIG_EXT)
1472 devpriv->ai12_startstop |= START_AI_EXT;
1473 if (cmd->stop_src == TRIG_EXT) {
1474 devpriv->ai_neverending = 1;
1475 devpriv->ai12_startstop |= STOP_AI_EXT;
1477 if (cmd->start_src == TRIG_INT) {
1478 devpriv->ai12_startstop |= START_AI_INT;
1479 devpriv->ai_inttrig_start = cmd->start_arg;
1480 s->async->inttrig = pci9118_ai_inttrig;
1483 if (cmd->stop_src == TRIG_INT) {
1484 devpriv->ai_neverending = 1;
1485 devpriv->ai12_startstop |= STOP_AI_INT;
1488 if (cmd->stop_src == TRIG_NONE)
1489 devpriv->ai_neverending = 1;
1490 if (cmd->stop_src == TRIG_COUNT) {
1491 devpriv->ai_scans = cmd->stop_arg;
1492 devpriv->ai_neverending = 0;
1494 devpriv->ai_scans = 0;
1497 /* use sample&hold signal? */
1498 if (cmd->convert_src == TRIG_NOW)
1499 devpriv->usessh = 1;
1502 devpriv->usessh = 0;
1505 DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n",
1506 devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh,
1507 devpriv->ai12_startstop);
1510 * use additional sample at end of every scan
1511 * to satisty DMA 32 bit transfer?
1513 devpriv->ai_add_front = 0;
1514 devpriv->ai_add_back = 0;
1515 devpriv->useeoshandle = 0;
1516 if (devpriv->master) {
1517 devpriv->usedma = 1;
1518 if ((cmd->flags & TRIG_WAKE_EOS) &&
1519 (devpriv->ai_n_scanlen == 1)) {
1520 if (cmd->convert_src == TRIG_NOW)
1521 devpriv->ai_add_back = 1;
1522 if (cmd->convert_src == TRIG_TIMER) {
1523 devpriv->usedma = 0;
1525 * use INT transfer if scanlist
1526 * have only one channel
1530 if ((cmd->flags & TRIG_WAKE_EOS) &&
1531 (devpriv->ai_n_scanlen & 1) &&
1532 (devpriv->ai_n_scanlen > 1)) {
1533 if (cmd->scan_begin_src == TRIG_FOLLOW) {
1535 * vpriv->useeoshandle=1; // change DMA transfer
1536 * block to fit EOS on every second call
1538 devpriv->usedma = 0;
1540 * XXX maybe can be corrected to use 16 bit DMA
1543 * well, we must insert one sample
1544 * to end of EOS to meet 32 bit transfer
1546 devpriv->ai_add_back = 1;
1549 } else { /* interrupt transfer don't need any correction */
1550 devpriv->usedma = 0;
1554 * we need software S&H signal?
1555 * It adds two samples before every scan as minimum
1557 if (devpriv->usessh && devpriv->softsshdelay) {
1558 devpriv->ai_add_front = 2;
1559 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
1560 /* move it to front */
1561 devpriv->ai_add_front++;
1562 devpriv->ai_add_back = 0;
1564 if (cmd->convert_arg < this_board->ai_ns_min)
1565 cmd->convert_arg = this_board->ai_ns_min;
1566 addchans = devpriv->softsshdelay / cmd->convert_arg;
1567 if (devpriv->softsshdelay % cmd->convert_arg)
1569 if (addchans > (devpriv->ai_add_front - 1)) {
1570 /* uff, still short */
1571 devpriv->ai_add_front = addchans + 1;
1572 if (devpriv->usedma == 1)
1573 if ((devpriv->ai_add_front +
1574 devpriv->ai_n_chan +
1575 devpriv->ai_add_back) & 1)
1576 devpriv->ai_add_front++;
1577 /* round up to 32 bit */
1580 /* well, we now know what must be all added */
1581 devpriv->ai_n_realscanlen = /*
1582 * what we must take from card in real
1583 * to have ai_n_scanlen on output?
1585 (devpriv->ai_add_front + devpriv->ai_n_chan +
1586 devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
1587 devpriv->ai_n_chan);
1589 DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
1591 devpriv->ai_n_realscanlen, devpriv->ai_add_front,
1592 devpriv->ai_n_chan, devpriv->ai_add_back,
1593 devpriv->ai_n_scanlen);
1595 /* check and setup channel list */
1596 if (!check_channel_list(dev, s, devpriv->ai_n_chan,
1597 devpriv->ai_chanlist, devpriv->ai_add_front,
1598 devpriv->ai_add_back))
1600 if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
1601 devpriv->ai_chanlist, 0, devpriv->ai_add_front,
1602 devpriv->ai_add_back, devpriv->usedma,
1603 devpriv->useeoshandle))
1606 /* compute timers settings */
1608 * simplest way, fr=4Mhz/(tim1*tim2),
1609 * channel manipulation without timers effect
1611 if (((cmd->scan_begin_src == TRIG_FOLLOW) ||
1612 (cmd->scan_begin_src == TRIG_EXT) ||
1613 (cmd->scan_begin_src == TRIG_INT)) &&
1614 (cmd->convert_src == TRIG_TIMER)) {
1615 /* both timer is used for one time */
1616 if (cmd->scan_begin_src == TRIG_EXT)
1620 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1621 &cmd->scan_begin_arg, &cmd->convert_arg,
1623 devpriv->ai_n_realscanlen,
1624 &devpriv->ai_divisor1,
1625 &devpriv->ai_divisor2, devpriv->usessh,
1626 devpriv->ai_add_front);
1627 devpriv->ai_timer2 = cmd->convert_arg;
1630 if ((cmd->scan_begin_src == TRIG_TIMER) &&
1631 ((cmd->convert_src == TRIG_TIMER) ||
1632 (cmd->convert_src == TRIG_NOW))) {
1633 /* double timed action */
1634 if (!devpriv->usedma) {
1636 "cmd->scan_begin_src=TRIG_TIMER works "
1637 "only with bus mastering!");
1642 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1643 &cmd->scan_begin_arg, &cmd->convert_arg,
1645 devpriv->ai_n_realscanlen,
1646 &devpriv->ai_divisor1,
1647 &devpriv->ai_divisor2, devpriv->usessh,
1648 devpriv->ai_add_front);
1649 devpriv->ai_timer1 = cmd->scan_begin_arg;
1650 devpriv->ai_timer2 = cmd->convert_arg;
1653 if ((cmd->scan_begin_src == TRIG_FOLLOW)
1654 && (cmd->convert_src == TRIG_EXT)) {
1658 start_pacer(dev, -1, 0, 0); /* stop pacer */
1660 devpriv->AdControlReg = 0; /*
1661 * bipolar, S.E., use 8254, stop 8354,
1662 * internal trigger, soft trigger,
1665 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1666 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1668 * positive triggers, no S&H, no burst,
1669 * burst stop, no post trigger,
1670 * no about trigger, trigger stop
1672 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1674 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1675 inl(dev->iobase + PCI9118_ADSTAT); /*
1679 inl(dev->iobase + PCI9118_INTSRC);
1681 devpriv->ai_act_scan = 0;
1682 devpriv->ai_act_dmapos = 0;
1683 s->async->cur_chan = 0;
1684 devpriv->ai_buf_ptr = 0;
1686 if (devpriv->usedma)
1687 ret = pci9118_ai_docmd_dma(dev, s);
1689 ret = pci9118_ai_docmd_sampl(dev, s);
1691 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
1696 ==============================================================================
1698 static int check_channel_list(struct comedi_device *dev,
1699 struct comedi_subdevice *s, int n_chan,
1700 unsigned int *chanlist, int frontadd, int backadd)
1702 unsigned int i, differencial = 0, bipolar = 0;
1704 /* correct channel and range number check itself comedi/range.c */
1706 comedi_error(dev, "range/channel list is empty!");
1709 if ((frontadd + n_chan + backadd) > s->len_chanlist) {
1711 ("comedi%d: range/channel list is too long for "
1712 "actual configuration (%d>%d)!",
1713 dev->minor, n_chan, s->len_chanlist - frontadd - backadd);
1717 if (CR_AREF(chanlist[0]) == AREF_DIFF)
1718 differencial = 1; /* all input must be diff */
1719 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1720 bipolar = 1; /* all input must be bipolar */
1722 for (i = 1; i < n_chan; i++) { /* check S.E/diff */
1723 if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
1726 "Differencial and single ended "
1727 "inputs can't be mixtured!");
1730 if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
1733 "Bipolar and unipolar ranges "
1734 "can't be mixtured!");
1737 if (!devpriv->usemux && differencial &&
1738 (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
1740 "If AREF_DIFF is used then is "
1741 "available only first 8 channels!");
1750 ==============================================================================
1752 static int setup_channel_list(struct comedi_device *dev,
1753 struct comedi_subdevice *s, int n_chan,
1754 unsigned int *chanlist, int rot, int frontadd,
1755 int backadd, int usedma, char useeos)
1757 unsigned int i, differencial = 0, bipolar = 0;
1758 unsigned int scanquad, gain, ssh = 0x00;
1761 ("adl_pci9118 EDBG: BGN: setup_channel_list"
1762 "(%d,.,%d,.,%d,%d,%d,%d)\n",
1763 dev->minor, n_chan, rot, frontadd, backadd, usedma);
1770 if (CR_AREF(chanlist[0]) == AREF_DIFF)
1771 differencial = 1; /* all input must be diff */
1772 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
1773 bipolar = 1; /* all input must be bipolar */
1775 /* All is ok, so we can setup channel/range list */
1778 devpriv->AdControlReg |= AdControl_UniP;
1779 /* set unibipolar */
1781 devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
1782 /* enable bipolar */
1786 devpriv->AdControlReg |= AdControl_Diff;
1787 /* enable diff inputs */
1789 devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
1790 /* set single ended inputs */
1793 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1796 outl(2, dev->iobase + PCI9118_SCANMOD);
1797 /* gods know why this sequence! */
1798 outl(0, dev->iobase + PCI9118_SCANMOD);
1799 outl(1, dev->iobase + PCI9118_SCANMOD);
1801 #ifdef PCI9118_PARANOIDCHECK
1802 devpriv->chanlistlen = n_chan;
1803 for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
1804 devpriv->chanlist[i] = 0x55aa;
1807 if (frontadd) { /* insert channels for S&H */
1808 ssh = devpriv->softsshsample;
1809 DPRINTK("FA: %04x: ", ssh);
1810 for (i = 0; i < frontadd; i++) {
1811 /* store range list to card */
1812 scanquad = CR_CHAN(chanlist[0]);
1813 /* get channel number; */
1814 gain = CR_RANGE(chanlist[0]);
1815 /* get gain number */
1816 scanquad |= ((gain & 0x03) << 8);
1817 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1818 DPRINTK("%02x ", scanquad | ssh);
1819 ssh = devpriv->softsshhold;
1824 DPRINTK("SL: ", ssh);
1825 for (i = 0; i < n_chan; i++) { /* store range list to card */
1826 scanquad = CR_CHAN(chanlist[i]); /* get channel number */
1827 #ifdef PCI9118_PARANOIDCHECK
1828 devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
1830 gain = CR_RANGE(chanlist[i]); /* get gain number */
1831 scanquad |= ((gain & 0x03) << 8);
1832 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1833 DPRINTK("%02x ", scanquad | ssh);
1837 if (backadd) { /* insert channels for fit onto 32bit DMA */
1838 DPRINTK("BA: %04x: ", ssh);
1839 for (i = 0; i < backadd; i++) { /* store range list to card */
1840 scanquad = CR_CHAN(chanlist[0]);
1841 /* get channel number */
1842 gain = CR_RANGE(chanlist[0]); /* get gain number */
1843 scanquad |= ((gain & 0x03) << 8);
1844 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
1845 DPRINTK("%02x ", scanquad | ssh);
1849 #ifdef PCI9118_PARANOIDCHECK
1850 devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
1851 /* for 32bit operations */
1853 for (i = 1; i < n_chan; i++) { /* store range list to card */
1854 devpriv->chanlist[(n_chan + i) ^ usedma] =
1855 (CR_CHAN(chanlist[i]) & 0xf) << rot;
1857 devpriv->chanlist[(2 * n_chan) ^ usedma] =
1858 devpriv->chanlist[0 ^ usedma];
1859 /* for 32bit operations */
1864 #ifdef PCI9118_EXTDEBUG
1866 for (i = 0; i <= (useeos * n_chan); i++)
1867 DPRINTK("%04x ", devpriv->chanlist[i]);
1872 outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */
1873 /* udelay(100); important delay, or first sample will be crippled */
1875 DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
1876 return 1; /* we can serve this with scan logic */
1880 ==============================================================================
1881 calculate 8254 divisors if they are used for dual timing
1883 static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
1884 struct comedi_subdevice *s,
1885 unsigned int *tim1, unsigned int *tim2,
1886 unsigned int flags, int chans,
1887 unsigned int *div1, unsigned int *div2,
1888 char usessh, unsigned int chnsshfront)
1891 ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors"
1892 "(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n",
1893 mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront);
1897 if (*tim2 < this_board->ai_ns_min)
1898 *tim2 = this_board->ai_ns_min;
1899 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
1900 tim2, flags & TRIG_ROUND_NEAREST);
1901 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
1902 devpriv->i8254_osc_base, *div1, *div2, *tim1);
1905 if (*tim2 < this_board->ai_ns_min)
1906 *tim2 = this_board->ai_ns_min;
1907 DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1909 *div1 = *tim2 / devpriv->i8254_osc_base;
1910 /* convert timer (burst) */
1911 DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1913 if (*div1 < this_board->ai_pacer_min)
1914 *div1 = this_board->ai_pacer_min;
1915 DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1917 *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */
1918 DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1920 *div2 = *div2 / *div1; /* major timer is c1*c2 */
1921 DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1925 DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1928 *tim2 = *div1 * devpriv->i8254_osc_base;
1929 /* real convert timer */
1931 if (usessh & (chnsshfront == 0)) /* use BSSH signal */
1932 if (*div2 < (chans + 2))
1935 DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
1937 *tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
1938 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",
1939 devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2);
1942 DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
1947 ==============================================================================
1949 static void start_pacer(struct comedi_device *dev, int mode,
1950 unsigned int divisor1, unsigned int divisor2)
1952 outl(0x74, dev->iobase + PCI9118_CNTCTRL);
1953 outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
1954 /* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
1957 if ((mode == 1) || (mode == 2) || (mode == 4)) {
1958 outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
1959 outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
1960 outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
1961 outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
1966 ==============================================================================
1968 static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
1971 return -1; /* incorrect source */
1972 devpriv->exttrg_users |= (1 << source);
1973 devpriv->IntControlReg |= Int_DTrg;
1974 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1975 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
1976 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1977 /* allow INT in AMCC */
1982 ==============================================================================
1984 static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
1987 return -1; /* incorrect source */
1988 devpriv->exttrg_users &= ~(1 << source);
1989 if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */
1990 devpriv->IntControlReg &= ~Int_DTrg;
1991 if (!devpriv->IntControlReg) /* all IRQ disabled */
1992 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) &
1994 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1995 /* disable int in AMCC */
1996 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2002 ==============================================================================
2004 static int pci9118_ai_cancel(struct comedi_device *dev,
2005 struct comedi_subdevice *s)
2007 if (devpriv->usedma)
2008 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) &
2009 (~EN_A2P_TRANSFERS),
2010 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
2011 pci9118_exttrg_del(dev, EXTTRG_AI);
2012 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
2013 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2014 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2016 * positive triggers, no S&H, no burst,
2017 * burst stop, no post trigger,
2018 * no about trigger, trigger stop
2020 devpriv->AdControlReg = 0x00;
2021 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2023 * bipolar, S.E., use 8254, stop 8354,
2024 * internal trigger, soft trigger,
2025 * disable INT and DMA
2027 outl(0, dev->iobase + PCI9118_BURST);
2028 outl(1, dev->iobase + PCI9118_SCANMOD);
2029 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
2030 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
2033 devpriv->usedma = 0;
2035 devpriv->ai_act_scan = 0;
2036 devpriv->ai_act_dmapos = 0;
2037 s->async->cur_chan = 0;
2038 s->async->inttrig = NULL;
2039 devpriv->ai_buf_ptr = 0;
2040 devpriv->ai_neverending = 0;
2041 devpriv->dma_actbuf = 0;
2043 if (!devpriv->IntControlReg)
2044 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
2045 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
2046 /* allow INT in AMCC */
2052 ==============================================================================
2054 static int pci9118_reset(struct comedi_device *dev)
2056 devpriv->IntControlReg = 0;
2057 devpriv->exttrg_users = 0;
2058 inl(dev->iobase + PCI9118_INTCTRL);
2059 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
2060 /* disable interrupts source */
2061 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
2062 /* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
2063 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
2064 devpriv->AdControlReg = 0;
2065 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2067 * bipolar, S.E., use 8254,
2068 * stop 8354, internal trigger,
2070 * disable INT and DMA
2072 outl(0, dev->iobase + PCI9118_BURST);
2073 outl(1, dev->iobase + PCI9118_SCANMOD);
2074 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
2075 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
2076 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
2078 * positive triggers, no S&H,
2079 * no burst, burst stop,
2085 devpriv->ao_data[0] = 2047;
2086 devpriv->ao_data[1] = 2047;
2087 outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1);
2088 /* reset A/D outs to 0V */
2089 outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
2090 outl(0, dev->iobase + PCI9118_DO); /* reset digi outs to L */
2092 inl(dev->iobase + PCI9118_AD_DATA);
2093 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
2094 outl(0, dev->iobase + PCI9118_INTSRC); /* remove INT requests */
2095 inl(dev->iobase + PCI9118_ADSTAT); /* flush A/D status register */
2096 inl(dev->iobase + PCI9118_INTSRC); /* flush INT requests */
2097 devpriv->AdControlReg = 0;
2098 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
2100 * bipolar, S.E., use 8254,
2101 * stop 8354, internal trigger,
2103 * disable INT and DMA
2106 devpriv->cnt0_users = 0;
2107 devpriv->exttrg_users = 0;
2112 static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
2113 struct comedi_devconfig *it)
2115 struct pci_dev *pcidev = NULL;
2116 int bus = it->options[0];
2117 int slot = it->options[1];
2119 for_each_pci_dev(pcidev) {
2120 if (pcidev->vendor != PCI_VENDOR_ID_AMCC)
2122 if (pcidev->device != this_board->device_id)
2125 /* requested particular bus/slot */
2126 if (pcidev->bus->number != bus ||
2127 PCI_SLOT(pcidev->devfn) != slot)
2131 * Look for device that isn't in use.
2132 * Enable PCI device and request regions.
2134 if (comedi_pci_enable(pcidev, "adl_pci9118"))
2136 printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx",
2137 pcidev->bus->number,
2138 PCI_SLOT(pcidev->devfn),
2139 PCI_FUNC(pcidev->devfn),
2140 (unsigned long)pci_resource_start(pcidev, 2),
2141 (unsigned long)pci_resource_start(pcidev, 0));
2145 "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
2146 dev->minor, bus, slot);
2150 static int pci9118_attach(struct comedi_device *dev,
2151 struct comedi_devconfig *it)
2153 struct pci_dev *pcidev;
2154 struct comedi_subdevice *s;
2156 unsigned short master;
2160 printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name);
2162 if (it->options[3] & 1)
2163 master = 0; /* user don't want use bus master */
2167 ret = alloc_private(dev, sizeof(struct pci9118_private));
2169 printk(" - Allocation failed!\n");
2173 pcidev = pci9118_find_pci(dev, it);
2176 comedi_set_hw_dev(dev, &pcidev->dev);
2179 pci_set_master(pcidev);
2182 devpriv->iobase_a = pci_resource_start(pcidev, 0);
2183 dev->iobase = pci_resource_start(pcidev, 2);
2185 dev->board_name = this_board->name;
2189 if (it->options[3] & 2)
2190 irq = 0; /* user don't want use IRQ */
2192 if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
2193 "ADLink PCI-9118", dev)) {
2194 printk(", unable to allocate IRQ %d, DISABLING IT",
2196 irq = 0; /* Can't use IRQ */
2198 printk(", irq=%u", irq);
2201 printk(", IRQ disabled");
2206 if (master) { /* alloc DMA buffers */
2207 devpriv->dma_doublebuf = 0;
2208 for (i = 0; i < 2; i++) {
2209 for (pages = 4; pages >= 0; pages--) {
2210 devpriv->dmabuf_virt[i] =
2211 (short *)__get_free_pages(GFP_KERNEL,
2213 if (devpriv->dmabuf_virt[i])
2216 if (devpriv->dmabuf_virt[i]) {
2217 devpriv->dmabuf_pages[i] = pages;
2218 devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
2219 devpriv->dmabuf_samples[i] =
2220 devpriv->dmabuf_size[i] >> 1;
2221 devpriv->dmabuf_hw[i] =
2222 virt_to_bus((void *)
2223 devpriv->dmabuf_virt[i]);
2226 if (!devpriv->dmabuf_virt[0]) {
2227 printk(", Can't allocate DMA buffer, DMA disabled!");
2231 if (devpriv->dmabuf_virt[1])
2232 devpriv->dma_doublebuf = 1;
2236 devpriv->master = master;
2237 if (devpriv->master)
2238 printk(", bus master");
2240 printk(", no bus master");
2242 devpriv->usemux = 0;
2243 if (it->options[2] > 0) {
2244 devpriv->usemux = it->options[2];
2245 if (devpriv->usemux > 256)
2246 devpriv->usemux = 256; /* max 256 channels! */
2247 if (it->options[4] > 0)
2248 if (devpriv->usemux > 128) {
2249 devpriv->usemux = 128;
2250 /* max 128 channels with softare S&H! */
2252 printk(", ext. mux %d channels", devpriv->usemux);
2255 devpriv->softsshdelay = it->options[4];
2256 if (devpriv->softsshdelay < 0) {
2257 /* select sample&hold signal polarity */
2258 devpriv->softsshdelay = -devpriv->softsshdelay;
2259 devpriv->softsshsample = 0x80;
2260 devpriv->softsshhold = 0x00;
2262 devpriv->softsshsample = 0x00;
2263 devpriv->softsshhold = 0x80;
2268 pci_read_config_word(pcidev, PCI_COMMAND, &u16w);
2269 pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64);
2270 /* Enable parity check for parity error */
2272 ret = comedi_alloc_subdevices(dev, 4);
2276 s = dev->subdevices + 0;
2277 dev->read_subdev = s;
2278 s->type = COMEDI_SUBD_AI;
2279 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2280 if (devpriv->usemux)
2281 s->n_chan = devpriv->usemux;
2283 s->n_chan = this_board->n_aichan;
2285 s->maxdata = this_board->ai_maxdata;
2286 s->len_chanlist = this_board->n_aichanlist;
2287 s->range_table = this_board->rangelist_ai;
2288 s->cancel = pci9118_ai_cancel;
2289 s->insn_read = pci9118_insn_read_ai;
2291 s->subdev_flags |= SDF_CMD_READ;
2292 s->do_cmdtest = pci9118_ai_cmdtest;
2293 s->do_cmd = pci9118_ai_cmd;
2294 s->munge = pci9118_ai_munge;
2297 s = dev->subdevices + 1;
2298 s->type = COMEDI_SUBD_AO;
2299 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2300 s->n_chan = this_board->n_aochan;
2301 s->maxdata = this_board->ao_maxdata;
2302 s->len_chanlist = this_board->n_aochan;
2303 s->range_table = this_board->rangelist_ao;
2304 s->insn_write = pci9118_insn_write_ao;
2305 s->insn_read = pci9118_insn_read_ao;
2307 s = dev->subdevices + 2;
2308 s->type = COMEDI_SUBD_DI;
2309 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2312 s->len_chanlist = 4;
2313 s->range_table = &range_digital;
2314 s->io_bits = 0; /* all bits input */
2315 s->insn_bits = pci9118_insn_bits_di;
2317 s = dev->subdevices + 3;
2318 s->type = COMEDI_SUBD_DO;
2319 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2322 s->len_chanlist = 4;
2323 s->range_table = &range_digital;
2324 s->io_bits = 0xf; /* all bits output */
2325 s->insn_bits = pci9118_insn_bits_do;
2328 devpriv->i8254_osc_base = 250; /* 250ns=4MHz */
2329 devpriv->ai_maskharderr = 0x10a;
2330 /* default measure crash condition */
2331 if (it->options[5]) /* disable some requested */
2332 devpriv->ai_maskharderr &= ~it->options[5];
2334 switch (this_board->ai_maxdata) {
2336 devpriv->ai16bits = 1;
2339 devpriv->ai16bits = 0;
2345 static void pci9118_detach(struct comedi_device *dev)
2347 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
2353 free_irq(dev->irq, dev);
2354 if (devpriv->dmabuf_virt[0])
2355 free_pages((unsigned long)devpriv->dmabuf_virt[0],
2356 devpriv->dmabuf_pages[0]);
2357 if (devpriv->dmabuf_virt[1])
2358 free_pages((unsigned long)devpriv->dmabuf_virt[1],
2359 devpriv->dmabuf_pages[1]);
2363 comedi_pci_disable(pcidev);
2365 pci_dev_put(pcidev);
2369 static const struct boardtype boardtypes[] = {
2371 .name = "pci9118dg",
2372 .vendor_id = PCI_VENDOR_ID_AMCC,
2373 .device_id = 0x80d9,
2374 .iorange_amcc = AMCC_OP_REG_SIZE,
2375 .iorange_9118 = IORANGE_9118,
2379 .n_aichanlist = PCI9118_CHANLEN,
2381 .ai_maxdata = 0x0fff,
2382 .ao_maxdata = 0x0fff,
2383 .rangelist_ai = &range_pci9118dg_hr,
2384 .rangelist_ao = &range_bipolar10,
2387 .half_fifo_size = 512,
2389 .name = "pci9118hg",
2390 .vendor_id = PCI_VENDOR_ID_AMCC,
2391 .device_id = 0x80d9,
2392 .iorange_amcc = AMCC_OP_REG_SIZE,
2393 .iorange_9118 = IORANGE_9118,
2397 .n_aichanlist = PCI9118_CHANLEN,
2399 .ai_maxdata = 0x0fff,
2400 .ao_maxdata = 0x0fff,
2401 .rangelist_ai = &range_pci9118hg,
2402 .rangelist_ao = &range_bipolar10,
2405 .half_fifo_size = 512,
2407 .name = "pci9118hr",
2408 .vendor_id = PCI_VENDOR_ID_AMCC,
2409 .device_id = 0x80d9,
2410 .iorange_amcc = AMCC_OP_REG_SIZE,
2411 .iorange_9118 = IORANGE_9118,
2415 .n_aichanlist = PCI9118_CHANLEN,
2417 .ai_maxdata = 0xffff,
2418 .ao_maxdata = 0x0fff,
2419 .rangelist_ai = &range_pci9118dg_hr,
2420 .rangelist_ao = &range_bipolar10,
2423 .half_fifo_size = 512,
2427 static struct comedi_driver adl_pci9118_driver = {
2428 .driver_name = "adl_pci9118",
2429 .module = THIS_MODULE,
2430 .attach = pci9118_attach,
2431 .detach = pci9118_detach,
2432 .num_names = ARRAY_SIZE(boardtypes),
2433 .board_name = &boardtypes[0].name,
2434 .offset = sizeof(struct boardtype),
2437 static int __devinit adl_pci9118_pci_probe(struct pci_dev *dev,
2438 const struct pci_device_id *ent)
2440 return comedi_pci_auto_config(dev, &adl_pci9118_driver);
2443 static void __devexit adl_pci9118_pci_remove(struct pci_dev *dev)
2445 comedi_pci_auto_unconfig(dev);
2448 static DEFINE_PCI_DEVICE_TABLE(adl_pci9118_pci_table) = {
2449 { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) },
2452 MODULE_DEVICE_TABLE(pci, adl_pci9118_pci_table);
2454 static struct pci_driver adl_pci9118_pci_driver = {
2455 .name = "adl_pci9118",
2456 .id_table = adl_pci9118_pci_table,
2457 .probe = adl_pci9118_pci_probe,
2458 .remove = __devexit_p(adl_pci9118_pci_remove),
2460 module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver);
2462 MODULE_AUTHOR("Comedi http://www.comedi.org");
2463 MODULE_DESCRIPTION("Comedi low-level driver");
2464 MODULE_LICENSE("GPL");