2 * comedi/drivers/adl_pci9118.c
4 * hardware driver for ADLink cards:
5 * card: PCI-9118DG, PCI-9118HG, PCI-9118HR
6 * driver: pci9118dg, pci9118hg, pci9118hr
8 * Author: Michal Dobes <dobes@tesnet.cz>
13 Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
14 Author: Michal Dobes <dobes@tesnet.cz>
15 Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
16 PCI-9118HR (pci9118hr)
19 This driver supports AI, AO, DI and DO subdevices.
20 AI subdevice supports cmd and insn interface,
21 other subdevices support only insn interface.
23 - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
24 - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
25 - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
26 - It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
27 cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
28 - If return value of cmdtest is 5 then you've bad channel list
29 (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
32 There are some hardware limitations:
33 a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
35 b) DMA transfers must have the length aligned to two samples (32 bit),
36 so there is some problems if cmd->chanlist_len is odd. This driver tries
37 bypass this with adding one sample to the end of the every scan and discard
38 it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
39 and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
40 with interrupt after every sample.
41 c) If isn't used DMA then you can use only mode where
42 cmd->scan_begin_src=TRIG_FOLLOW.
44 Configuration options:
45 [0] - PCI bus of device (optional)
46 [1] - PCI slot of device (optional)
47 If bus/slot is not specified, then first available PCI
49 [2] - 0= standard 8 DIFF/16 SE channels configuration
50 n = external multiplexer connected, 1 <= n <= 256
51 [3] - 0=autoselect DMA or EOC interrupts operation
53 3 = disable DMA and INT, only insn interface will work
54 [4] - sample&hold signal - card can generate signal for external S&H board
55 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
56 0 != use ADCHN7(pin 23) signal is generated from driver, number say how
57 long delay is requested in ns and sign polarity of the hold
58 (in this case external multiplexor can serve only 128 channels)
59 [5] - 0=stop measure on all hardware errors
60 2 | = ignore ADOR - A/D Overrun status
61 8|=ignore Bover - A/D Burst Mode Overrun status
62 256|=ignore nFull - A/D FIFO Full status
69 * All the supported boards have the same PCI vendor and device IDs, so
70 * auto-attachment of PCI devices will always find the first board type.
72 * Perhaps the boards have different subdevice IDs that we could use to
75 * Need some device attributes so the board type can be corrected after
76 * attachment if necessary, and possibly to set other options supported by
80 #include <linux/pci.h>
81 #include <linux/delay.h>
82 #include <linux/gfp.h>
83 #include <linux/interrupt.h>
86 #include "../comedidev.h"
88 #include "amcc_s5933.h"
90 #include "comedi_fc.h"
92 /* paranoid checks are broken */
93 #undef PCI9118_PARANOIDCHECK /*
94 * if defined, then is used code which control
95 * correct channel number on every 12 bit sample
98 #define IORANGE_9118 64 /* I hope */
99 #define PCI9118_CHANLEN 255 /*
100 * len of chanlist, some source say 256,
101 * but reality looks like 255 :-(
104 #define PCI9118_CNT0 0x00 /* R/W: 8254 counter 0 */
105 #define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */
106 #define PCI9118_CNT2 0x08 /* R/W: 8254 counter 0 */
107 #define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
108 #define PCI9118_AD_DATA 0x10 /* R: A/D data */
109 #define PCI9118_DA1 0x10 /* W: D/A registers */
110 #define PCI9118_DA2 0x14
111 #define PCI9118_ADSTAT 0x18 /* R: A/D status register */
112 #define PCI9118_ADCNTRL 0x18 /* W: A/D control register */
113 #define PCI9118_DI 0x1c /* R: digi input register */
114 #define PCI9118_DO 0x1c /* W: digi output register */
115 #define PCI9118_SOFTTRG 0x20 /* W: soft trigger for A/D */
116 #define PCI9118_GAIN 0x24 /* W: A/D gain/channel register */
117 #define PCI9118_BURST 0x28 /* W: A/D burst number register */
118 #define PCI9118_SCANMOD 0x2c /* W: A/D auto scan mode */
119 #define PCI9118_ADFUNC 0x30 /* W: A/D function register */
120 #define PCI9118_DELFIFO 0x34 /* W: A/D data FIFO reset */
121 #define PCI9118_INTSRC 0x38 /* R: interrupt reason register */
122 #define PCI9118_INTCTRL 0x38 /* W: interrupt control register */
124 /* bits from A/D control register (PCI9118_ADCNTRL) */
125 #define AdControl_UniP 0x80 /* 1=bipolar, 0=unipolar */
126 #define AdControl_Diff 0x40 /* 1=differential, 0= single end inputs */
127 #define AdControl_SoftG 0x20 /* 1=8254 counter works, 0=counter stops */
128 #define AdControl_ExtG 0x10 /*
129 * 1=8254 countrol controlled by TGIN(pin 46),
130 * 0=controlled by SoftG
132 #define AdControl_ExtM 0x08 /*
133 * 1=external hardware trigger (pin 44),
136 #define AdControl_TmrTr 0x04 /*
137 * 1=8254 is iternal trigger source,
138 * 0=software trigger is source
139 * (register PCI9118_SOFTTRG)
141 #define AdControl_Int 0x02 /* 1=enable INT, 0=disable */
142 #define AdControl_Dma 0x01 /* 1=enable DMA, 0=disable */
144 /* bits from A/D function register (PCI9118_ADFUNC) */
145 #define AdFunction_PDTrg 0x80 /*
147 * 0=negative digital trigger
148 * (only positive is correct)
150 #define AdFunction_PETrg 0x40 /*
152 * 0=negative external trigger
153 * (only positive is correct)
155 #define AdFunction_BSSH 0x20 /* 1=with sample&hold, 0=without */
156 #define AdFunction_BM 0x10 /* 1=burst mode, 0=normal mode */
157 #define AdFunction_BS 0x08 /*
158 * 1=burst mode start,
161 #define AdFunction_PM 0x04 /*
162 * 1=post trigger mode,
165 #define AdFunction_AM 0x02 /*
166 * 1=about trigger mode,
167 * 0=not about trigger
169 #define AdFunction_Start 0x01 /* 1=trigger start, 0=trigger stop */
171 /* bits from A/D status register (PCI9118_ADSTAT) */
172 #define AdStatus_nFull 0x100 /* 0=FIFO full (fatal), 1=not full */
173 #define AdStatus_nHfull 0x080 /* 0=FIFO half full, 1=FIFO not half full */
174 #define AdStatus_nEpty 0x040 /* 0=FIFO empty, 1=FIFO not empty */
175 #define AdStatus_Acmp 0x020 /* */
176 #define AdStatus_DTH 0x010 /* 1=external digital trigger */
177 #define AdStatus_Bover 0x008 /* 1=burst mode overrun (fatal) */
178 #define AdStatus_ADOS 0x004 /* 1=A/D over speed (warning) */
179 #define AdStatus_ADOR 0x002 /* 1=A/D overrun (fatal) */
180 #define AdStatus_ADrdy 0x001 /* 1=A/D already ready, 0=not ready */
182 /* bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL) */
183 /* 1=interrupt occur, enable source, 0=interrupt not occur, disable source */
184 #define Int_Timer 0x08 /* timer interrupt */
185 #define Int_About 0x04 /* about trigger complete */
186 #define Int_Hfull 0x02 /* A/D FIFO hlaf full */
187 #define Int_DTrg 0x01 /* external digital trigger */
189 #define START_AI_EXT 0x01 /* start measure on external trigger */
190 #define STOP_AI_EXT 0x02 /* stop measure on external trigger */
191 #define START_AI_INT 0x04 /* start measure on internal trigger */
192 #define STOP_AI_INT 0x08 /* stop measure on internal trigger */
194 #define EXTTRG_AI 0 /* ext trg is used by AI */
196 static const struct comedi_lrange range_pci9118dg_hr = { 8, {
208 static const struct comedi_lrange range_pci9118hg = { 8, {
220 #define PCI9118_BIPOLAR_RANGES 4 /*
221 * used for test on mixture
226 const char *name; /* board name */
227 int device_id; /* PCI device ID of card */
228 int iorange_amcc; /* iorange for own S5933 region */
229 int iorange_9118; /* pass thru card region size */
230 int n_aichan; /* num of A/D chans */
231 int n_aichand; /* num of A/D chans in diff mode */
233 * num of A/D chans with
234 * external multiplexor
236 int n_aichanlist; /* len of chanlist */
237 int n_aochan; /* num of D/A chans */
238 int ai_maxdata; /* resolution of A/D */
239 int ao_maxdata; /* resolution of D/A */
240 const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */
241 const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */
242 unsigned int ai_ns_min; /* max sample speed of card v ns */
243 unsigned int ai_pacer_min; /*
244 * minimal pacer value
245 * (c1*c2 or c1 in burst)
247 int half_fifo_size; /* size of FIFO/2 */
251 static const struct boardtype boardtypes[] = {
255 .iorange_amcc = AMCC_OP_REG_SIZE,
256 .iorange_9118 = IORANGE_9118,
260 .n_aichanlist = PCI9118_CHANLEN,
262 .ai_maxdata = 0x0fff,
263 .ao_maxdata = 0x0fff,
264 .rangelist_ai = &range_pci9118dg_hr,
265 .rangelist_ao = &range_bipolar10,
268 .half_fifo_size = 512,
272 .iorange_amcc = AMCC_OP_REG_SIZE,
273 .iorange_9118 = IORANGE_9118,
277 .n_aichanlist = PCI9118_CHANLEN,
279 .ai_maxdata = 0x0fff,
280 .ao_maxdata = 0x0fff,
281 .rangelist_ai = &range_pci9118hg,
282 .rangelist_ao = &range_bipolar10,
285 .half_fifo_size = 512,
289 .iorange_amcc = AMCC_OP_REG_SIZE,
290 .iorange_9118 = IORANGE_9118,
294 .n_aichanlist = PCI9118_CHANLEN,
296 .ai_maxdata = 0xffff,
297 .ao_maxdata = 0x0fff,
298 .rangelist_ai = &range_pci9118dg_hr,
299 .rangelist_ao = &range_bipolar10,
302 .half_fifo_size = 512,
306 struct pci9118_private {
307 unsigned long iobase_a; /* base+size for AMCC chip */
308 unsigned int master; /* master capable */
309 unsigned int usemux; /* we want to use external multiplexor! */
310 #ifdef PCI9118_PARANOIDCHECK
311 unsigned short chanlist[PCI9118_CHANLEN + 1]; /*
315 unsigned char chanlistlen; /* number of scanlist */
317 unsigned char AdControlReg; /* A/D control register */
318 unsigned char IntControlReg; /* Interrupt control register */
319 unsigned char AdFunctionReg; /* A/D function register */
320 char valid; /* driver is ok */
321 char ai_neverending; /* we do unlimited AI */
322 unsigned int i8254_osc_base; /* frequence of onboard oscilator */
323 unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */
324 unsigned int ai_act_scan; /* how many scans we finished */
325 unsigned int ai_buf_ptr; /* data buffer ptr in samples */
326 unsigned int ai_n_chan; /* how many channels is measured */
327 unsigned int ai_n_scanlen; /* len of actual scanlist */
328 unsigned int ai_n_realscanlen; /*
329 * what we must transfer for one
330 * outgoing scan include front/back adds
332 unsigned int ai_act_dmapos; /* position in actual real stream */
333 unsigned int ai_add_front; /*
334 * how many channels we must add
335 * before scan to satisfy S&H?
337 unsigned int ai_add_back; /*
338 * how many channels we must add
339 * before scan to satisfy DMA?
341 unsigned int *ai_chanlist; /* actual chanlist */
342 unsigned int ai_timer1;
343 unsigned int ai_timer2;
344 unsigned int ai_flags;
345 char ai12_startstop; /*
346 * measure can start/stop
347 * on external trigger
349 unsigned int ai_divisor1, ai_divisor2; /*
350 * divisors for start of measure
353 unsigned int ai_data_len;
355 short ao_data[2]; /* data output buffer */
356 unsigned int ai_scans; /* number of scans to do */
357 char dma_doublebuf; /* we can use double buffering */
358 unsigned int dma_actbuf; /* which buffer is used now */
359 short *dmabuf_virt[2]; /*
360 * pointers to begin of
363 unsigned long dmabuf_hw[2]; /* hw address of DMA buff */
364 unsigned int dmabuf_size[2]; /*
365 * size of dma buffer in bytes
367 unsigned int dmabuf_use_size[2]; /*
368 * which size we may now use
371 unsigned int dmabuf_used_size[2]; /* which size was truly used */
372 unsigned int dmabuf_panic_size[2];
373 unsigned int dmabuf_samples[2]; /* size in samples */
374 int dmabuf_pages[2]; /* number of pages in buffer */
375 unsigned char cnt0_users; /*
376 * bit field of 8254 CNT0 users
377 * (0-unused, 1-AO, 2-DI, 3-DO)
379 unsigned char exttrg_users; /*
380 * bit field of external trigger
381 * users(0-AI, 1-AO, 2-DI, 3-DO)
383 unsigned int cnt0_divisor; /* actual CNT0 divisor */
384 void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *,
388 * ptr to actual interrupt
391 unsigned char ai16bits; /* =1 16 bit card */
392 unsigned char usedma; /* =1 use DMA transfer and not INT */
393 unsigned char useeoshandle; /*
394 * =1 change WAKE_EOS DMA transfer
395 * to fit on every second
397 unsigned char usessh; /* =1 turn on S&H support */
399 * >0 use software S&H,
400 * numer is requested delay in ns
402 unsigned char softsshsample; /*
403 * polarity of S&H signal
406 unsigned char softsshhold; /*
407 * polarity of S&H signal
410 unsigned int ai_maskerr; /* which warning was printed */
411 unsigned int ai_maskharderr; /* on which error bits stops */
412 unsigned int ai_inttrig_start; /* TRIG_INT for start */
415 static int check_channel_list(struct comedi_device *dev,
416 struct comedi_subdevice *s, int n_chan,
417 unsigned int *chanlist, int frontadd, int backadd)
419 const struct boardtype *this_board = comedi_board(dev);
420 struct pci9118_private *devpriv = dev->private;
421 unsigned int i, differencial = 0, bipolar = 0;
423 /* correct channel and range number check itself comedi/range.c */
425 comedi_error(dev, "range/channel list is empty!");
428 if ((frontadd + n_chan + backadd) > s->len_chanlist) {
430 "range/channel list is too long for actual configuration!\n");
434 if (CR_AREF(chanlist[0]) == AREF_DIFF)
435 differencial = 1; /* all input must be diff */
436 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
437 bipolar = 1; /* all input must be bipolar */
439 for (i = 1; i < n_chan; i++) { /* check S.E/diff */
440 if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
443 "Differencial and single ended "
444 "inputs can't be mixtured!");
447 if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
450 "Bipolar and unipolar ranges "
451 "can't be mixtured!");
454 if (!devpriv->usemux && differencial &&
455 (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
457 "If AREF_DIFF is used then is "
458 "available only first 8 channels!");
466 static int setup_channel_list(struct comedi_device *dev,
467 struct comedi_subdevice *s, int n_chan,
468 unsigned int *chanlist, int rot, int frontadd,
469 int backadd, int usedma, char useeos)
471 struct pci9118_private *devpriv = dev->private;
472 unsigned int i, differencial = 0, bipolar = 0;
473 unsigned int scanquad, gain, ssh = 0x00;
480 if (CR_AREF(chanlist[0]) == AREF_DIFF)
481 differencial = 1; /* all input must be diff */
482 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
483 bipolar = 1; /* all input must be bipolar */
485 /* All is ok, so we can setup channel/range list */
488 devpriv->AdControlReg |= AdControl_UniP;
491 devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
496 devpriv->AdControlReg |= AdControl_Diff;
497 /* enable diff inputs */
499 devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
500 /* set single ended inputs */
503 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
506 outl(2, dev->iobase + PCI9118_SCANMOD);
507 /* gods know why this sequence! */
508 outl(0, dev->iobase + PCI9118_SCANMOD);
509 outl(1, dev->iobase + PCI9118_SCANMOD);
511 #ifdef PCI9118_PARANOIDCHECK
512 devpriv->chanlistlen = n_chan;
513 for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
514 devpriv->chanlist[i] = 0x55aa;
517 if (frontadd) { /* insert channels for S&H */
518 ssh = devpriv->softsshsample;
519 for (i = 0; i < frontadd; i++) {
520 /* store range list to card */
521 scanquad = CR_CHAN(chanlist[0]);
522 /* get channel number; */
523 gain = CR_RANGE(chanlist[0]);
524 /* get gain number */
525 scanquad |= ((gain & 0x03) << 8);
526 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
527 ssh = devpriv->softsshhold;
531 for (i = 0; i < n_chan; i++) { /* store range list to card */
532 scanquad = CR_CHAN(chanlist[i]); /* get channel number */
533 #ifdef PCI9118_PARANOIDCHECK
534 devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
536 gain = CR_RANGE(chanlist[i]); /* get gain number */
537 scanquad |= ((gain & 0x03) << 8);
538 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
541 if (backadd) { /* insert channels for fit onto 32bit DMA */
542 for (i = 0; i < backadd; i++) { /* store range list to card */
543 scanquad = CR_CHAN(chanlist[0]);
544 /* get channel number */
545 gain = CR_RANGE(chanlist[0]); /* get gain number */
546 scanquad |= ((gain & 0x03) << 8);
547 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
550 #ifdef PCI9118_PARANOIDCHECK
551 devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
552 /* for 32bit operations */
554 for (i = 1; i < n_chan; i++) { /* store range list to card */
555 devpriv->chanlist[(n_chan + i) ^ usedma] =
556 (CR_CHAN(chanlist[i]) & 0xf) << rot;
558 devpriv->chanlist[(2 * n_chan) ^ usedma] =
559 devpriv->chanlist[0 ^ usedma];
560 /* for 32bit operations */
566 outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */
567 /* udelay(100); important delay, or first sample will be crippled */
569 return 1; /* we can serve this with scan logic */
572 static int pci9118_insn_read_ai(struct comedi_device *dev,
573 struct comedi_subdevice *s,
574 struct comedi_insn *insn, unsigned int *data)
576 struct pci9118_private *devpriv = dev->private;
579 devpriv->AdControlReg = AdControl_Int & 0xff;
580 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
581 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
583 * positive triggers, no S&H,
584 * no burst, burst stop,
590 if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
593 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
595 for (n = 0; n < insn->n; n++) {
596 outw(0, dev->iobase + PCI9118_SOFTTRG); /* start conversion */
600 if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
605 comedi_error(dev, "A/D insn timeout");
607 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
611 if (devpriv->ai16bits) {
614 PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
617 (inw(dev->iobase + PCI9118_AD_DATA) >> 4) & 0xfff;
621 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
626 static int pci9118_insn_write_ao(struct comedi_device *dev,
627 struct comedi_subdevice *s,
628 struct comedi_insn *insn, unsigned int *data)
630 struct pci9118_private *devpriv = dev->private;
633 ch = CR_CHAN(insn->chanspec);
635 chanreg = PCI9118_DA2;
637 chanreg = PCI9118_DA1;
640 for (n = 0; n < insn->n; n++) {
641 outl(data[n], dev->iobase + chanreg);
642 devpriv->ao_data[ch] = data[n];
648 static int pci9118_insn_read_ao(struct comedi_device *dev,
649 struct comedi_subdevice *s,
650 struct comedi_insn *insn, unsigned int *data)
652 struct pci9118_private *devpriv = dev->private;
655 chan = CR_CHAN(insn->chanspec);
656 for (n = 0; n < insn->n; n++)
657 data[n] = devpriv->ao_data[chan];
662 static int pci9118_insn_bits_di(struct comedi_device *dev,
663 struct comedi_subdevice *s,
664 struct comedi_insn *insn, unsigned int *data)
666 data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
671 static int pci9118_insn_bits_do(struct comedi_device *dev,
672 struct comedi_subdevice *s,
673 struct comedi_insn *insn, unsigned int *data)
676 s->state &= ~data[0];
677 s->state |= (data[0] & data[1]);
678 outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
685 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev)
687 struct pci9118_private *devpriv = dev->private;
689 devpriv->AdFunctionReg =
690 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
691 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
692 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
693 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
694 dev->iobase + PCI9118_CNT0);
695 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
696 dev->iobase + PCI9118_CNT0);
697 devpriv->AdFunctionReg |= AdFunction_Start;
698 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
701 static unsigned int defragment_dma_buffer(struct comedi_device *dev,
702 struct comedi_subdevice *s,
704 unsigned int num_samples)
706 struct pci9118_private *devpriv = dev->private;
707 unsigned int i = 0, j = 0;
708 unsigned int start_pos = devpriv->ai_add_front,
709 stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
710 unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
711 devpriv->ai_add_back;
713 for (i = 0; i < num_samples; i++) {
714 if (devpriv->ai_act_dmapos >= start_pos &&
715 devpriv->ai_act_dmapos < stop_pos) {
716 dma_buffer[j++] = dma_buffer[i];
718 devpriv->ai_act_dmapos++;
719 devpriv->ai_act_dmapos %= raw_scanlen;
725 static int move_block_from_dma(struct comedi_device *dev,
726 struct comedi_subdevice *s,
728 unsigned int num_samples)
730 struct pci9118_private *devpriv = dev->private;
731 unsigned int num_bytes;
733 num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
734 devpriv->ai_act_scan +=
735 (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
736 s->async->cur_chan += num_samples;
737 s->async->cur_chan %= devpriv->ai_n_scanlen;
739 cfc_write_array_to_buffer(s, dma_buffer,
740 num_samples * sizeof(short));
741 if (num_bytes < num_samples * sizeof(short))
746 static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
748 struct pci9118_private *devpriv = dev->private;
751 return -1; /* incorrect source */
752 devpriv->exttrg_users |= (1 << source);
753 devpriv->IntControlReg |= Int_DTrg;
754 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
755 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
756 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
757 /* allow INT in AMCC */
761 static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
763 struct pci9118_private *devpriv = dev->private;
766 return -1; /* incorrect source */
767 devpriv->exttrg_users &= ~(1 << source);
768 if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */
769 devpriv->IntControlReg &= ~Int_DTrg;
770 if (!devpriv->IntControlReg) /* all IRQ disabled */
771 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) &
773 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
774 /* disable int in AMCC */
775 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
780 static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
781 struct comedi_subdevice *s,
782 unsigned int *tim1, unsigned int *tim2,
783 unsigned int flags, int chans,
784 unsigned int *div1, unsigned int *div2,
785 char usessh, unsigned int chnsshfront)
787 const struct boardtype *this_board = comedi_board(dev);
788 struct pci9118_private *devpriv = dev->private;
793 if (*tim2 < this_board->ai_ns_min)
794 *tim2 = this_board->ai_ns_min;
795 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
796 tim2, flags & TRIG_ROUND_NEAREST);
799 if (*tim2 < this_board->ai_ns_min)
800 *tim2 = this_board->ai_ns_min;
801 *div1 = *tim2 / devpriv->i8254_osc_base;
802 /* convert timer (burst) */
803 if (*div1 < this_board->ai_pacer_min)
804 *div1 = this_board->ai_pacer_min;
805 *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */
806 *div2 = *div2 / *div1; /* major timer is c1*c2 */
810 *tim2 = *div1 * devpriv->i8254_osc_base;
811 /* real convert timer */
813 if (usessh && (chnsshfront == 0)) /* use BSSH signal */
814 if (*div2 < (chans + 2))
817 *tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
822 static void start_pacer(struct comedi_device *dev, int mode,
823 unsigned int divisor1, unsigned int divisor2)
825 outl(0x74, dev->iobase + PCI9118_CNTCTRL);
826 outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
827 /* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
830 if ((mode == 1) || (mode == 2) || (mode == 4)) {
831 outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
832 outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
833 outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
834 outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
838 static int pci9118_ai_cancel(struct comedi_device *dev,
839 struct comedi_subdevice *s)
841 struct pci9118_private *devpriv = dev->private;
844 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) &
846 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
847 pci9118_exttrg_del(dev, EXTTRG_AI);
848 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
849 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
850 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
852 * positive triggers, no S&H, no burst,
853 * burst stop, no post trigger,
854 * no about trigger, trigger stop
856 devpriv->AdControlReg = 0x00;
857 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
859 * bipolar, S.E., use 8254, stop 8354,
860 * internal trigger, soft trigger,
861 * disable INT and DMA
863 outl(0, dev->iobase + PCI9118_BURST);
864 outl(1, dev->iobase + PCI9118_SCANMOD);
865 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
866 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
871 devpriv->ai_act_scan = 0;
872 devpriv->ai_act_dmapos = 0;
873 s->async->cur_chan = 0;
874 s->async->inttrig = NULL;
875 devpriv->ai_buf_ptr = 0;
876 devpriv->ai_neverending = 0;
877 devpriv->dma_actbuf = 0;
879 if (!devpriv->IntControlReg)
880 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
881 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
882 /* allow INT in AMCC */
887 static char pci9118_decode_error_status(struct comedi_device *dev,
888 struct comedi_subdevice *s,
891 struct pci9118_private *devpriv = dev->private;
894 comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
895 devpriv->ai_maskerr &= ~0x100L;
899 "A/D Burst Mode Overrun Status (Fatal Error!)");
900 devpriv->ai_maskerr &= ~0x008L;
903 comedi_error(dev, "A/D Over Speed Status (Warning!)");
904 devpriv->ai_maskerr &= ~0x004L;
907 comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
908 devpriv->ai_maskerr &= ~0x002L;
910 if (m & devpriv->ai_maskharderr) {
911 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
912 pci9118_ai_cancel(dev, s);
913 comedi_event(dev, s);
920 static void pci9118_ai_munge(struct comedi_device *dev,
921 struct comedi_subdevice *s, void *data,
922 unsigned int num_bytes,
923 unsigned int start_chan_index)
925 struct pci9118_private *devpriv = dev->private;
926 unsigned int i, num_samples = num_bytes / sizeof(short);
929 for (i = 0; i < num_samples; i++) {
931 array[i] = be16_to_cpu(array[i]);
932 if (devpriv->ai16bits)
935 array[i] = (array[i] >> 4) & 0x0fff;
940 static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
941 struct comedi_subdevice *s,
942 unsigned short int_adstat,
943 unsigned int int_amcc,
944 unsigned short int_daq)
946 struct pci9118_private *devpriv = dev->private;
947 register short sampl;
949 s->async->events = 0;
951 if (int_adstat & devpriv->ai_maskerr)
952 if (pci9118_decode_error_status(dev, s, int_adstat))
955 sampl = inw(dev->iobase + PCI9118_AD_DATA);
957 #ifdef PCI9118_PARANOIDCHECK
958 if (devpriv->ai16bits == 0) {
959 if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) {
961 dev_info(dev->class_dev,
962 "A/D SAMPL - data dropout: received channel %d, expected %d!\n",
964 devpriv->chanlist[s->async->cur_chan]);
965 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
966 pci9118_ai_cancel(dev, s);
967 comedi_event(dev, s);
972 cfc_write_to_buffer(s, sampl);
973 s->async->cur_chan++;
974 if (s->async->cur_chan >= devpriv->ai_n_scanlen) {
976 s->async->cur_chan %= devpriv->ai_n_scanlen;
977 devpriv->ai_act_scan++;
978 if (!(devpriv->ai_neverending))
979 if (devpriv->ai_act_scan >= devpriv->ai_scans) {
980 /* all data sampled */
981 pci9118_ai_cancel(dev, s);
982 s->async->events |= COMEDI_CB_EOA;
986 if (s->async->events)
987 comedi_event(dev, s);
990 static void interrupt_pci9118_ai_dma(struct comedi_device *dev,
991 struct comedi_subdevice *s,
992 unsigned short int_adstat,
993 unsigned int int_amcc,
994 unsigned short int_daq)
996 struct pci9118_private *devpriv = dev->private;
997 unsigned int next_dma_buf, samplesinbuf, sampls, m;
999 if (int_amcc & MASTER_ABORT_INT) {
1000 comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
1001 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1002 pci9118_ai_cancel(dev, s);
1003 comedi_event(dev, s);
1007 if (int_amcc & TARGET_ABORT_INT) {
1008 comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
1009 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1010 pci9118_ai_cancel(dev, s);
1011 comedi_event(dev, s);
1014 if (int_adstat & devpriv->ai_maskerr)
1015 /* if (int_adstat & 0x106) */
1016 if (pci9118_decode_error_status(dev, s, int_adstat))
1019 samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1;
1020 /* number of received real samples */
1022 if (devpriv->dma_doublebuf) { /*
1023 * switch DMA buffers if is used
1026 next_dma_buf = 1 - devpriv->dma_actbuf;
1027 outl(devpriv->dmabuf_hw[next_dma_buf],
1028 devpriv->iobase_a + AMCC_OP_REG_MWAR);
1029 outl(devpriv->dmabuf_use_size[next_dma_buf],
1030 devpriv->iobase_a + AMCC_OP_REG_MWTC);
1031 devpriv->dmabuf_used_size[next_dma_buf] =
1032 devpriv->dmabuf_use_size[next_dma_buf];
1033 if (devpriv->ai_do == 4)
1034 interrupt_pci9118_ai_mode4_switch(dev);
1038 m = devpriv->ai_data_len >> 1; /*
1039 * how many samples is to
1043 move_block_from_dma(dev, s,
1044 devpriv->dmabuf_virt[devpriv->dma_actbuf],
1046 m = m - sampls; /* m= how many samples was transferred */
1049 if (!devpriv->ai_neverending)
1050 if (devpriv->ai_act_scan >= devpriv->ai_scans) {
1051 /* all data sampled */
1052 pci9118_ai_cancel(dev, s);
1053 s->async->events |= COMEDI_CB_EOA;
1056 if (devpriv->dma_doublebuf) { /* switch dma buffers */
1057 devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
1058 } else { /* restart DMA if is not used double buffering */
1059 outl(devpriv->dmabuf_hw[0],
1060 devpriv->iobase_a + AMCC_OP_REG_MWAR);
1061 outl(devpriv->dmabuf_use_size[0],
1062 devpriv->iobase_a + AMCC_OP_REG_MWTC);
1063 if (devpriv->ai_do == 4)
1064 interrupt_pci9118_ai_mode4_switch(dev);
1067 comedi_event(dev, s);
1070 static irqreturn_t interrupt_pci9118(int irq, void *d)
1072 struct comedi_device *dev = d;
1073 struct pci9118_private *devpriv = dev->private;
1074 unsigned int int_daq = 0, int_amcc, int_adstat;
1077 return IRQ_NONE; /* not fully initialized */
1079 int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf;
1080 /* get IRQ reasons from card */
1081 int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1082 /* get INT register from AMCC chip */
1084 if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
1085 return IRQ_NONE; /* interrupt from other source */
1087 outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1088 /* shutdown IRQ reasons in AMCC */
1090 int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff;
1091 /* get STATUS register */
1093 if (devpriv->ai_do) {
1094 if (devpriv->ai12_startstop)
1095 if ((int_adstat & AdStatus_DTH) &&
1096 (int_daq & Int_DTrg)) {
1097 /* start stop of measure */
1098 if (devpriv->ai12_startstop & START_AI_EXT) {
1099 devpriv->ai12_startstop &=
1101 if (!(devpriv->ai12_startstop &
1105 /* deactivate EXT trigger */
1106 start_pacer(dev, devpriv->ai_do,
1107 devpriv->ai_divisor1,
1108 devpriv->ai_divisor2);
1110 outl(devpriv->AdControlReg,
1111 dev->iobase + PCI9118_ADCNTRL);
1113 if (devpriv->ai12_startstop &
1115 devpriv->ai12_startstop &=
1119 /* deactivate EXT trigger */
1120 devpriv->ai_neverending = 0;
1122 * well, on next interrupt from
1123 * DMA/EOC measure will stop
1129 (devpriv->int_ai_func) (dev, &dev->subdevices[0], int_adstat,
1136 static int pci9118_ai_inttrig(struct comedi_device *dev,
1137 struct comedi_subdevice *s, unsigned int trignum)
1139 struct pci9118_private *devpriv = dev->private;
1141 if (trignum != devpriv->ai_inttrig_start)
1144 devpriv->ai12_startstop &= ~START_AI_INT;
1145 s->async->inttrig = NULL;
1147 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1148 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1149 if (devpriv->ai_do != 3) {
1150 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1151 devpriv->ai_divisor2);
1152 devpriv->AdControlReg |= AdControl_SoftG;
1154 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1159 static int pci9118_ai_cmdtest(struct comedi_device *dev,
1160 struct comedi_subdevice *s,
1161 struct comedi_cmd *cmd)
1163 const struct boardtype *this_board = comedi_board(dev);
1164 struct pci9118_private *devpriv = dev->private;
1168 unsigned int divisor1 = 0, divisor2 = 0;
1170 /* Step 1 : check if triggers are trivially valid */
1172 err |= cfc_check_trigger_src(&cmd->start_src,
1173 TRIG_NOW | TRIG_EXT | TRIG_INT);
1175 flags = TRIG_FOLLOW;
1176 if (devpriv->master)
1177 flags |= TRIG_TIMER | TRIG_EXT;
1178 err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1180 flags = TRIG_TIMER | TRIG_EXT;
1181 if (devpriv->master)
1183 err |= cfc_check_trigger_src(&cmd->convert_src, flags);
1185 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1186 err |= cfc_check_trigger_src(&cmd->stop_src,
1187 TRIG_COUNT | TRIG_NONE | TRIG_EXT);
1192 /* Step 2a : make sure trigger sources are unique */
1194 err |= cfc_check_trigger_is_unique(cmd->start_src);
1195 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1196 err |= cfc_check_trigger_is_unique(cmd->convert_src);
1197 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1199 /* Step 2b : and mutually compatible */
1201 if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1204 if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT)
1207 if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
1208 (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW))))
1211 if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
1212 (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT))))
1215 if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1221 /* Step 3: check if arguments are trivially valid */
1223 if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
1224 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1226 if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
1227 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1229 if ((cmd->scan_begin_src == TRIG_TIMER) &&
1230 (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
1231 cmd->scan_begin_src = TRIG_FOLLOW;
1232 cmd->convert_arg = cmd->scan_begin_arg;
1233 cmd->scan_begin_arg = 0;
1236 if (cmd->scan_begin_src == TRIG_TIMER)
1237 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1238 this_board->ai_ns_min);
1240 if (cmd->scan_begin_src == TRIG_EXT)
1241 if (cmd->scan_begin_arg) {
1242 cmd->scan_begin_arg = 0;
1244 err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg,
1248 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
1249 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
1250 this_board->ai_ns_min);
1252 if (cmd->convert_src == TRIG_EXT)
1253 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
1255 if (cmd->stop_src == TRIG_COUNT)
1256 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
1257 else /* TRIG_NONE */
1258 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1260 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
1261 err |= cfc_check_trigger_arg_max(&cmd->chanlist_len,
1262 this_board->n_aichanlist);
1264 err |= cfc_check_trigger_arg_min(&cmd->scan_end_arg,
1267 if ((cmd->scan_end_arg % cmd->chanlist_len)) {
1269 cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
1276 /* step 4: fix up any arguments */
1278 if (cmd->scan_begin_src == TRIG_TIMER) {
1279 tmp = cmd->scan_begin_arg;
1280 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1281 &divisor2, &cmd->scan_begin_arg,
1282 cmd->flags & TRIG_ROUND_MASK);
1283 if (cmd->scan_begin_arg < this_board->ai_ns_min)
1284 cmd->scan_begin_arg = this_board->ai_ns_min;
1285 if (tmp != cmd->scan_begin_arg)
1289 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
1290 tmp = cmd->convert_arg;
1291 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1292 &divisor2, &cmd->convert_arg,
1293 cmd->flags & TRIG_ROUND_MASK);
1294 if (cmd->convert_arg < this_board->ai_ns_min)
1295 cmd->convert_arg = this_board->ai_ns_min;
1296 if (tmp != cmd->convert_arg)
1298 if (cmd->scan_begin_src == TRIG_TIMER
1299 && cmd->convert_src == TRIG_NOW) {
1300 if (cmd->convert_arg == 0) {
1301 if (cmd->scan_begin_arg <
1302 this_board->ai_ns_min *
1303 (cmd->scan_end_arg + 2)) {
1304 cmd->scan_begin_arg =
1305 this_board->ai_ns_min *
1306 (cmd->scan_end_arg + 2);
1310 if (cmd->scan_begin_arg <
1311 cmd->convert_arg * cmd->chanlist_len) {
1312 cmd->scan_begin_arg =
1325 if (!check_channel_list(dev, s, cmd->chanlist_len,
1326 cmd->chanlist, 0, 0))
1327 return 5; /* incorrect channels list */
1332 static int Compute_and_setup_dma(struct comedi_device *dev)
1334 struct pci9118_private *devpriv = dev->private;
1335 unsigned int dmalen0, dmalen1, i;
1337 dmalen0 = devpriv->dmabuf_size[0];
1338 dmalen1 = devpriv->dmabuf_size[1];
1339 /* isn't output buff smaller that our DMA buff? */
1340 if (dmalen0 > (devpriv->ai_data_len)) {
1341 dmalen0 = devpriv->ai_data_len & ~3L; /*
1342 * align to 32bit down
1345 if (dmalen1 > (devpriv->ai_data_len)) {
1346 dmalen1 = devpriv->ai_data_len & ~3L; /*
1347 * align to 32bit down
1351 /* we want wake up every scan? */
1352 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1353 if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
1354 /* uff, too short DMA buffer, disable EOS support! */
1355 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1356 dev_info(dev->class_dev,
1357 "WAR: DMA0 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n",
1358 dmalen0, devpriv->ai_n_realscanlen << 1);
1360 /* short first DMA buffer to one scan */
1361 dmalen0 = devpriv->ai_n_realscanlen << 1;
1362 if (devpriv->useeoshandle)
1365 dev_info(dev->class_dev,
1366 "ERR: DMA0 buf len bug? (%d<4)\n",
1372 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1373 if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
1374 /* uff, too short DMA buffer, disable EOS support! */
1375 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1376 dev_info(dev->class_dev,
1377 "WAR: DMA1 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n",
1378 dmalen1, devpriv->ai_n_realscanlen << 1);
1380 /* short second DMA buffer to one scan */
1381 dmalen1 = devpriv->ai_n_realscanlen << 1;
1382 if (devpriv->useeoshandle)
1385 dev_info(dev->class_dev,
1386 "ERR: DMA1 buf len bug? (%d<4)\n",
1393 /* transfer without TRIG_WAKE_EOS */
1394 if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
1395 /* if it's possible then align DMA buffers to length of scan */
1398 (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
1399 (devpriv->ai_n_realscanlen << 1);
1402 dmalen0 = i; /* uff. very long scan? */
1405 (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
1406 (devpriv->ai_n_realscanlen << 1);
1409 dmalen1 = i; /* uff. very long scan? */
1411 * if measure isn't neverending then test, if it fits whole
1412 * into one or two DMA buffers
1414 if (!devpriv->ai_neverending) {
1415 /* fits whole measure into one DMA buffer? */
1417 ((devpriv->ai_n_realscanlen << 1) *
1418 devpriv->ai_scans)) {
1420 (devpriv->ai_n_realscanlen << 1) *
1424 * fits whole measure into
1428 ((devpriv->ai_n_realscanlen << 1) *
1429 devpriv->ai_scans - dmalen0))
1431 (devpriv->ai_n_realscanlen << 1) *
1432 devpriv->ai_scans - dmalen0;
1438 /* these DMA buffer size will be used */
1439 devpriv->dma_actbuf = 0;
1440 devpriv->dmabuf_use_size[0] = dmalen0;
1441 devpriv->dmabuf_use_size[1] = dmalen1;
1444 if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
1445 devpriv->dmabuf_panic_size[0] =
1446 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1447 1) * devpriv->ai_n_scanlen * sizeof(short);
1448 devpriv->dmabuf_panic_size[1] =
1449 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1450 1) * devpriv->ai_n_scanlen * sizeof(short);
1452 devpriv->dmabuf_panic_size[0] =
1453 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
1454 devpriv->dmabuf_panic_size[1] =
1455 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
1459 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS),
1460 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
1461 outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
1462 outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
1463 /* init DMA transfer */
1464 outl(0x00000000 | AINT_WRITE_COMPL,
1465 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1466 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
1468 outl(inl(devpriv->iobase_a +
1469 AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
1470 EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
1471 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS,
1472 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1473 /* allow bus mastering */
1478 static int pci9118_ai_docmd_sampl(struct comedi_device *dev,
1479 struct comedi_subdevice *s)
1481 struct pci9118_private *devpriv = dev->private;
1483 switch (devpriv->ai_do) {
1485 devpriv->AdControlReg |= AdControl_TmrTr;
1488 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
1491 devpriv->AdControlReg |= AdControl_ExtM;
1494 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
1498 "pci9118_ai_docmd_sampl() mode number bug!\n");
1502 devpriv->int_ai_func = interrupt_pci9118_ai_onesample;
1503 /* transfer function */
1505 if (devpriv->ai12_startstop)
1506 pci9118_exttrg_add(dev, EXTTRG_AI);
1507 /* activate EXT trigger */
1509 if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
1510 devpriv->IntControlReg |= Int_Timer;
1512 devpriv->AdControlReg |= AdControl_Int;
1514 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
1515 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1516 /* allow INT in AMCC */
1518 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1519 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1520 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1521 if (devpriv->ai_do != 3) {
1522 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1523 devpriv->ai_divisor2);
1524 devpriv->AdControlReg |= AdControl_SoftG;
1526 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1532 static int pci9118_ai_docmd_dma(struct comedi_device *dev,
1533 struct comedi_subdevice *s)
1535 struct pci9118_private *devpriv = dev->private;
1537 Compute_and_setup_dma(dev);
1539 switch (devpriv->ai_do) {
1541 devpriv->AdControlReg |=
1542 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1545 devpriv->AdControlReg |=
1546 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1547 devpriv->AdFunctionReg =
1548 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
1550 if (devpriv->usessh && (!devpriv->softsshdelay))
1551 devpriv->AdFunctionReg |= AdFunction_BSSH;
1552 outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
1555 devpriv->AdControlReg |=
1556 ((AdControl_ExtM | AdControl_Dma) & 0xff);
1557 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1560 devpriv->AdControlReg |=
1561 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1562 devpriv->AdFunctionReg =
1563 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
1564 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1565 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1566 outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
1567 dev->iobase + PCI9118_CNT0);
1568 outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
1569 dev->iobase + PCI9118_CNT0);
1570 devpriv->AdFunctionReg |= AdFunction_Start;
1573 comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
1577 if (devpriv->ai12_startstop) {
1578 pci9118_exttrg_add(dev, EXTTRG_AI);
1579 /* activate EXT trigger */
1582 devpriv->int_ai_func = interrupt_pci9118_ai_dma;
1583 /* transfer function */
1585 outl(0x02000000 | AINT_WRITE_COMPL,
1586 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1588 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1589 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1590 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1591 if (devpriv->ai_do != 3) {
1592 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1593 devpriv->ai_divisor2);
1594 devpriv->AdControlReg |= AdControl_SoftG;
1596 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1602 static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1604 const struct boardtype *this_board = comedi_board(dev);
1605 struct pci9118_private *devpriv = dev->private;
1606 struct comedi_cmd *cmd = &s->async->cmd;
1607 unsigned int addchans = 0;
1610 devpriv->ai12_startstop = 0;
1611 devpriv->ai_flags = cmd->flags;
1612 devpriv->ai_n_chan = cmd->chanlist_len;
1613 devpriv->ai_n_scanlen = cmd->scan_end_arg;
1614 devpriv->ai_chanlist = cmd->chanlist;
1615 devpriv->ai_data = s->async->prealloc_buf;
1616 devpriv->ai_data_len = s->async->prealloc_bufsz;
1617 devpriv->ai_timer1 = 0;
1618 devpriv->ai_timer2 = 0;
1619 devpriv->ai_add_front = 0;
1620 devpriv->ai_add_back = 0;
1621 devpriv->ai_maskerr = 0x10e;
1623 /* prepare for start/stop conditions */
1624 if (cmd->start_src == TRIG_EXT)
1625 devpriv->ai12_startstop |= START_AI_EXT;
1626 if (cmd->stop_src == TRIG_EXT) {
1627 devpriv->ai_neverending = 1;
1628 devpriv->ai12_startstop |= STOP_AI_EXT;
1630 if (cmd->start_src == TRIG_INT) {
1631 devpriv->ai12_startstop |= START_AI_INT;
1632 devpriv->ai_inttrig_start = cmd->start_arg;
1633 s->async->inttrig = pci9118_ai_inttrig;
1636 if (cmd->stop_src == TRIG_INT) {
1637 devpriv->ai_neverending = 1;
1638 devpriv->ai12_startstop |= STOP_AI_INT;
1641 if (cmd->stop_src == TRIG_NONE)
1642 devpriv->ai_neverending = 1;
1643 if (cmd->stop_src == TRIG_COUNT) {
1644 devpriv->ai_scans = cmd->stop_arg;
1645 devpriv->ai_neverending = 0;
1647 devpriv->ai_scans = 0;
1650 /* use sample&hold signal? */
1651 if (cmd->convert_src == TRIG_NOW)
1652 devpriv->usessh = 1;
1655 devpriv->usessh = 0;
1659 * use additional sample at end of every scan
1660 * to satisty DMA 32 bit transfer?
1662 devpriv->ai_add_front = 0;
1663 devpriv->ai_add_back = 0;
1664 devpriv->useeoshandle = 0;
1665 if (devpriv->master) {
1666 devpriv->usedma = 1;
1667 if ((cmd->flags & TRIG_WAKE_EOS) &&
1668 (devpriv->ai_n_scanlen == 1)) {
1669 if (cmd->convert_src == TRIG_NOW)
1670 devpriv->ai_add_back = 1;
1671 if (cmd->convert_src == TRIG_TIMER) {
1672 devpriv->usedma = 0;
1674 * use INT transfer if scanlist
1675 * have only one channel
1679 if ((cmd->flags & TRIG_WAKE_EOS) &&
1680 (devpriv->ai_n_scanlen & 1) &&
1681 (devpriv->ai_n_scanlen > 1)) {
1682 if (cmd->scan_begin_src == TRIG_FOLLOW) {
1684 * vpriv->useeoshandle=1; // change DMA transfer
1685 * block to fit EOS on every second call
1687 devpriv->usedma = 0;
1689 * XXX maybe can be corrected to use 16 bit DMA
1692 * well, we must insert one sample
1693 * to end of EOS to meet 32 bit transfer
1695 devpriv->ai_add_back = 1;
1698 } else { /* interrupt transfer don't need any correction */
1699 devpriv->usedma = 0;
1703 * we need software S&H signal?
1704 * It adds two samples before every scan as minimum
1706 if (devpriv->usessh && devpriv->softsshdelay) {
1707 devpriv->ai_add_front = 2;
1708 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
1709 /* move it to front */
1710 devpriv->ai_add_front++;
1711 devpriv->ai_add_back = 0;
1713 if (cmd->convert_arg < this_board->ai_ns_min)
1714 cmd->convert_arg = this_board->ai_ns_min;
1715 addchans = devpriv->softsshdelay / cmd->convert_arg;
1716 if (devpriv->softsshdelay % cmd->convert_arg)
1718 if (addchans > (devpriv->ai_add_front - 1)) {
1719 /* uff, still short */
1720 devpriv->ai_add_front = addchans + 1;
1721 if (devpriv->usedma == 1)
1722 if ((devpriv->ai_add_front +
1723 devpriv->ai_n_chan +
1724 devpriv->ai_add_back) & 1)
1725 devpriv->ai_add_front++;
1726 /* round up to 32 bit */
1729 /* well, we now know what must be all added */
1730 devpriv->ai_n_realscanlen = /*
1731 * what we must take from card in real
1732 * to have ai_n_scanlen on output?
1734 (devpriv->ai_add_front + devpriv->ai_n_chan +
1735 devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
1736 devpriv->ai_n_chan);
1738 /* check and setup channel list */
1739 if (!check_channel_list(dev, s, devpriv->ai_n_chan,
1740 devpriv->ai_chanlist, devpriv->ai_add_front,
1741 devpriv->ai_add_back))
1743 if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
1744 devpriv->ai_chanlist, 0, devpriv->ai_add_front,
1745 devpriv->ai_add_back, devpriv->usedma,
1746 devpriv->useeoshandle))
1749 /* compute timers settings */
1751 * simplest way, fr=4Mhz/(tim1*tim2),
1752 * channel manipulation without timers effect
1754 if (((cmd->scan_begin_src == TRIG_FOLLOW) ||
1755 (cmd->scan_begin_src == TRIG_EXT) ||
1756 (cmd->scan_begin_src == TRIG_INT)) &&
1757 (cmd->convert_src == TRIG_TIMER)) {
1758 /* both timer is used for one time */
1759 if (cmd->scan_begin_src == TRIG_EXT)
1763 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1764 &cmd->scan_begin_arg, &cmd->convert_arg,
1766 devpriv->ai_n_realscanlen,
1767 &devpriv->ai_divisor1,
1768 &devpriv->ai_divisor2, devpriv->usessh,
1769 devpriv->ai_add_front);
1770 devpriv->ai_timer2 = cmd->convert_arg;
1773 if ((cmd->scan_begin_src == TRIG_TIMER) &&
1774 ((cmd->convert_src == TRIG_TIMER) ||
1775 (cmd->convert_src == TRIG_NOW))) {
1776 /* double timed action */
1777 if (!devpriv->usedma) {
1779 "cmd->scan_begin_src=TRIG_TIMER works "
1780 "only with bus mastering!");
1785 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1786 &cmd->scan_begin_arg, &cmd->convert_arg,
1788 devpriv->ai_n_realscanlen,
1789 &devpriv->ai_divisor1,
1790 &devpriv->ai_divisor2, devpriv->usessh,
1791 devpriv->ai_add_front);
1792 devpriv->ai_timer1 = cmd->scan_begin_arg;
1793 devpriv->ai_timer2 = cmd->convert_arg;
1796 if ((cmd->scan_begin_src == TRIG_FOLLOW)
1797 && (cmd->convert_src == TRIG_EXT)) {
1801 start_pacer(dev, -1, 0, 0); /* stop pacer */
1803 devpriv->AdControlReg = 0; /*
1804 * bipolar, S.E., use 8254, stop 8354,
1805 * internal trigger, soft trigger,
1808 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1809 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1811 * positive triggers, no S&H, no burst,
1812 * burst stop, no post trigger,
1813 * no about trigger, trigger stop
1815 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1817 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1818 inl(dev->iobase + PCI9118_ADSTAT); /*
1822 inl(dev->iobase + PCI9118_INTSRC);
1824 devpriv->ai_act_scan = 0;
1825 devpriv->ai_act_dmapos = 0;
1826 s->async->cur_chan = 0;
1827 devpriv->ai_buf_ptr = 0;
1829 if (devpriv->usedma)
1830 ret = pci9118_ai_docmd_dma(dev, s);
1832 ret = pci9118_ai_docmd_sampl(dev, s);
1837 static int pci9118_reset(struct comedi_device *dev)
1839 struct pci9118_private *devpriv = dev->private;
1841 devpriv->IntControlReg = 0;
1842 devpriv->exttrg_users = 0;
1843 inl(dev->iobase + PCI9118_INTCTRL);
1844 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1845 /* disable interrupts source */
1846 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1847 /* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
1848 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
1849 devpriv->AdControlReg = 0;
1850 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1852 * bipolar, S.E., use 8254,
1853 * stop 8354, internal trigger,
1855 * disable INT and DMA
1857 outl(0, dev->iobase + PCI9118_BURST);
1858 outl(1, dev->iobase + PCI9118_SCANMOD);
1859 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
1860 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1861 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1863 * positive triggers, no S&H,
1864 * no burst, burst stop,
1870 devpriv->ao_data[0] = 2047;
1871 devpriv->ao_data[1] = 2047;
1872 outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1);
1873 /* reset A/D outs to 0V */
1874 outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
1875 outl(0, dev->iobase + PCI9118_DO); /* reset digi outs to L */
1877 inl(dev->iobase + PCI9118_AD_DATA);
1878 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1879 outl(0, dev->iobase + PCI9118_INTSRC); /* remove INT requests */
1880 inl(dev->iobase + PCI9118_ADSTAT); /* flush A/D status register */
1881 inl(dev->iobase + PCI9118_INTSRC); /* flush INT requests */
1882 devpriv->AdControlReg = 0;
1883 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1885 * bipolar, S.E., use 8254,
1886 * stop 8354, internal trigger,
1888 * disable INT and DMA
1891 devpriv->cnt0_users = 0;
1892 devpriv->exttrg_users = 0;
1898 * FIXME - this is pretty ineffective because all the supported board types
1899 * have the same device ID!
1901 static const struct boardtype *pci9118_find_boardinfo(struct pci_dev *pcidev)
1905 for (i = 0; i < ARRAY_SIZE(boardtypes); i++)
1906 if (pcidev->device == boardtypes[i].device_id)
1907 return &boardtypes[i];
1911 static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
1912 struct comedi_devconfig *it)
1914 const struct boardtype *this_board = comedi_board(dev);
1915 struct pci_dev *pcidev = NULL;
1916 int bus = it->options[0];
1917 int slot = it->options[1];
1919 for_each_pci_dev(pcidev) {
1920 if (pcidev->vendor != PCI_VENDOR_ID_AMCC)
1922 if (pcidev->device != this_board->device_id)
1925 /* requested particular bus/slot */
1926 if (pcidev->bus->number != bus ||
1927 PCI_SLOT(pcidev->devfn) != slot)
1932 dev_err(dev->class_dev,
1933 "no supported board found! (req. bus/slot : %d/%d)\n",
1938 static void pci9118_report_attach(struct comedi_device *dev, unsigned int irq)
1940 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1941 struct pci9118_private *devpriv = dev->private;
1946 snprintf(irqbuf, sizeof(irqbuf), "irq %u%s", irq,
1947 (dev->irq ? "" : " UNAVAILABLE"));
1949 snprintf(irqbuf, sizeof(irqbuf), "irq DISABLED");
1950 if (devpriv->usemux)
1951 snprintf(muxbuf, sizeof(muxbuf), "ext mux %u chans",
1954 snprintf(muxbuf, sizeof(muxbuf), "no ext mux");
1955 dev_info(dev->class_dev, "%s (pci %s, %s, %sbus master, %s) attached\n",
1956 dev->board_name, pci_name(pcidev), irqbuf,
1957 (devpriv->master ? "" : "no "), muxbuf);
1960 static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
1961 int master, int ext_mux, int softsshdelay,
1964 const struct boardtype *this_board = comedi_board(dev);
1965 struct pci9118_private *devpriv = dev->private;
1966 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1967 struct comedi_subdevice *s;
1972 dev->board_name = this_board->name;
1973 ret = comedi_pci_enable(dev);
1977 pci_set_master(pcidev);
1979 devpriv->iobase_a = pci_resource_start(pcidev, 0);
1980 dev->iobase = pci_resource_start(pcidev, 2);
1984 if (master) { /* alloc DMA buffers */
1985 devpriv->dma_doublebuf = 0;
1986 for (i = 0; i < 2; i++) {
1987 for (pages = 4; pages >= 0; pages--) {
1988 devpriv->dmabuf_virt[i] =
1989 (short *)__get_free_pages(GFP_KERNEL,
1991 if (devpriv->dmabuf_virt[i])
1994 if (devpriv->dmabuf_virt[i]) {
1995 devpriv->dmabuf_pages[i] = pages;
1996 devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
1997 devpriv->dmabuf_samples[i] =
1998 devpriv->dmabuf_size[i] >> 1;
1999 devpriv->dmabuf_hw[i] =
2000 virt_to_bus((void *)
2001 devpriv->dmabuf_virt[i]);
2004 if (!devpriv->dmabuf_virt[0]) {
2005 dev_warn(dev->class_dev,
2006 "Can't allocate DMA buffer, DMA disabled!\n");
2009 if (devpriv->dmabuf_virt[1])
2010 devpriv->dma_doublebuf = 1;
2012 devpriv->master = master;
2016 ext_mux = 256; /* max 256 channels! */
2017 if (softsshdelay > 0)
2020 devpriv->usemux = ext_mux;
2022 devpriv->usemux = 0;
2025 if (softsshdelay < 0) {
2026 /* select sample&hold signal polarity */
2027 devpriv->softsshdelay = -softsshdelay;
2028 devpriv->softsshsample = 0x80;
2029 devpriv->softsshhold = 0x00;
2031 devpriv->softsshdelay = softsshdelay;
2032 devpriv->softsshsample = 0x00;
2033 devpriv->softsshhold = 0x80;
2036 pci_read_config_word(pcidev, PCI_COMMAND, &u16w);
2037 pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64);
2038 /* Enable parity check for parity error */
2040 ret = comedi_alloc_subdevices(dev, 4);
2044 s = &dev->subdevices[0];
2045 dev->read_subdev = s;
2046 s->type = COMEDI_SUBD_AI;
2047 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2048 if (devpriv->usemux)
2049 s->n_chan = devpriv->usemux;
2051 s->n_chan = this_board->n_aichan;
2053 s->maxdata = this_board->ai_maxdata;
2054 s->len_chanlist = this_board->n_aichanlist;
2055 s->range_table = this_board->rangelist_ai;
2056 s->cancel = pci9118_ai_cancel;
2057 s->insn_read = pci9118_insn_read_ai;
2058 s->munge = pci9118_ai_munge;
2060 s = &dev->subdevices[1];
2061 s->type = COMEDI_SUBD_AO;
2062 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2063 s->n_chan = this_board->n_aochan;
2064 s->maxdata = this_board->ao_maxdata;
2065 s->len_chanlist = this_board->n_aochan;
2066 s->range_table = this_board->rangelist_ao;
2067 s->insn_write = pci9118_insn_write_ao;
2068 s->insn_read = pci9118_insn_read_ao;
2070 s = &dev->subdevices[2];
2071 s->type = COMEDI_SUBD_DI;
2072 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2075 s->len_chanlist = 4;
2076 s->range_table = &range_digital;
2077 s->io_bits = 0; /* all bits input */
2078 s->insn_bits = pci9118_insn_bits_di;
2080 s = &dev->subdevices[3];
2081 s->type = COMEDI_SUBD_DO;
2082 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2085 s->len_chanlist = 4;
2086 s->range_table = &range_digital;
2087 s->io_bits = 0xf; /* all bits output */
2088 s->insn_bits = pci9118_insn_bits_do;
2091 devpriv->i8254_osc_base = 250; /* 250ns=4MHz */
2092 devpriv->ai_maskharderr = 0x10a;
2093 /* default measure crash condition */
2094 if (hw_err_mask) /* disable some requested */
2095 devpriv->ai_maskharderr &= ~hw_err_mask;
2097 switch (this_board->ai_maxdata) {
2099 devpriv->ai16bits = 1;
2102 devpriv->ai16bits = 0;
2111 if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
2112 dev->board_name, dev)) {
2113 dev_warn(dev->class_dev,
2114 "unable to allocate IRQ %u, DISABLING IT\n",
2118 /* Enable AI commands */
2119 s = &dev->subdevices[0];
2120 s->subdev_flags |= SDF_CMD_READ;
2121 s->do_cmdtest = pci9118_ai_cmdtest;
2122 s->do_cmd = pci9118_ai_cmd;
2126 pci9118_report_attach(dev, irq);
2130 static int pci9118_attach(struct comedi_device *dev,
2131 struct comedi_devconfig *it)
2133 struct pci9118_private *devpriv;
2134 struct pci_dev *pcidev;
2135 int ext_mux, disable_irq, master, softsshdelay, hw_err_mask;
2137 ext_mux = it->options[2];
2138 master = ((it->options[3] & 1) == 0);
2139 disable_irq = ((it->options[3] & 2) != 0);
2140 softsshdelay = it->options[4];
2141 hw_err_mask = it->options[5];
2143 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
2146 dev->private = devpriv;
2148 pcidev = pci9118_find_pci(dev, it);
2151 comedi_set_hw_dev(dev, &pcidev->dev);
2153 return pci9118_common_attach(dev, disable_irq, master, ext_mux,
2154 softsshdelay, hw_err_mask);
2157 static int pci9118_auto_attach(struct comedi_device *dev,
2158 unsigned long context_unused)
2160 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
2161 struct pci9118_private *devpriv;
2163 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
2166 dev->private = devpriv;
2168 dev->board_ptr = pci9118_find_boardinfo(pcidev);
2169 if (dev->board_ptr == NULL) {
2170 dev_err(dev->class_dev,
2171 "adl_pci9118: cannot determine board type for pci %s\n",
2176 * Need to 'get' the PCI device to match the 'put' in pci9118_detach().
2177 * (The 'put' also matches the implicit 'get' by pci9118_find_pci().)
2179 pci_dev_get(pcidev);
2180 /* Don't disable irq, use bus master, no external mux,
2181 * no sample-hold delay, no error mask. */
2182 return pci9118_common_attach(dev, 0, 1, 0, 0, 0);
2185 static void pci9118_detach(struct comedi_device *dev)
2187 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
2188 struct pci9118_private *devpriv = dev->private;
2194 free_irq(dev->irq, dev);
2195 if (devpriv->dmabuf_virt[0])
2196 free_pages((unsigned long)devpriv->dmabuf_virt[0],
2197 devpriv->dmabuf_pages[0]);
2198 if (devpriv->dmabuf_virt[1])
2199 free_pages((unsigned long)devpriv->dmabuf_virt[1],
2200 devpriv->dmabuf_pages[1]);
2202 comedi_pci_disable(dev);
2204 pci_dev_put(pcidev);
2207 static struct comedi_driver adl_pci9118_driver = {
2208 .driver_name = "adl_pci9118",
2209 .module = THIS_MODULE,
2210 .attach = pci9118_attach,
2211 .auto_attach = pci9118_auto_attach,
2212 .detach = pci9118_detach,
2213 .num_names = ARRAY_SIZE(boardtypes),
2214 .board_name = &boardtypes[0].name,
2215 .offset = sizeof(struct boardtype),
2218 static int adl_pci9118_pci_probe(struct pci_dev *dev,
2219 const struct pci_device_id *id)
2221 return comedi_pci_auto_config(dev, &adl_pci9118_driver,
2225 static DEFINE_PCI_DEVICE_TABLE(adl_pci9118_pci_table) = {
2226 { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) },
2229 MODULE_DEVICE_TABLE(pci, adl_pci9118_pci_table);
2231 static struct pci_driver adl_pci9118_pci_driver = {
2232 .name = "adl_pci9118",
2233 .id_table = adl_pci9118_pci_table,
2234 .probe = adl_pci9118_pci_probe,
2235 .remove = comedi_pci_auto_unconfig,
2237 module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver);
2239 MODULE_AUTHOR("Comedi http://www.comedi.org");
2240 MODULE_DESCRIPTION("Comedi low-level driver");
2241 MODULE_LICENSE("GPL");