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/module.h>
81 #include <linux/pci.h>
82 #include <linux/delay.h>
83 #include <linux/gfp.h>
84 #include <linux/interrupt.h>
87 #include "../comedidev.h"
89 #include "amcc_s5933.h"
91 #include "comedi_fc.h"
93 /* paranoid checks are broken */
94 #undef PCI9118_PARANOIDCHECK /*
95 * if defined, then is used code which control
96 * correct channel number on every 12 bit sample
99 #define IORANGE_9118 64 /* I hope */
100 #define PCI9118_CHANLEN 255 /*
101 * len of chanlist, some source say 256,
102 * but reality looks like 255 :-(
105 #define PCI9118_CNT0 0x00 /* R/W: 8254 counter 0 */
106 #define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */
107 #define PCI9118_CNT2 0x08 /* R/W: 8254 counter 0 */
108 #define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
109 #define PCI9118_AD_DATA 0x10 /* R: A/D data */
110 #define PCI9118_DA1 0x10 /* W: D/A registers */
111 #define PCI9118_DA2 0x14
112 #define PCI9118_ADSTAT 0x18 /* R: A/D status register */
113 #define PCI9118_ADCNTRL 0x18 /* W: A/D control register */
114 #define PCI9118_DI 0x1c /* R: digi input register */
115 #define PCI9118_DO 0x1c /* W: digi output register */
116 #define PCI9118_SOFTTRG 0x20 /* W: soft trigger for A/D */
117 #define PCI9118_GAIN 0x24 /* W: A/D gain/channel register */
118 #define PCI9118_BURST 0x28 /* W: A/D burst number register */
119 #define PCI9118_SCANMOD 0x2c /* W: A/D auto scan mode */
120 #define PCI9118_ADFUNC 0x30 /* W: A/D function register */
121 #define PCI9118_DELFIFO 0x34 /* W: A/D data FIFO reset */
122 #define PCI9118_INTSRC 0x38 /* R: interrupt reason register */
123 #define PCI9118_INTCTRL 0x38 /* W: interrupt control register */
125 /* bits from A/D control register (PCI9118_ADCNTRL) */
126 #define AdControl_UniP 0x80 /* 1=bipolar, 0=unipolar */
127 #define AdControl_Diff 0x40 /* 1=differential, 0= single end inputs */
128 #define AdControl_SoftG 0x20 /* 1=8254 counter works, 0=counter stops */
129 #define AdControl_ExtG 0x10 /*
130 * 1=8254 countrol controlled by TGIN(pin 46),
131 * 0=controlled by SoftG
133 #define AdControl_ExtM 0x08 /*
134 * 1=external hardware trigger (pin 44),
137 #define AdControl_TmrTr 0x04 /*
138 * 1=8254 is iternal trigger source,
139 * 0=software trigger is source
140 * (register PCI9118_SOFTTRG)
142 #define AdControl_Int 0x02 /* 1=enable INT, 0=disable */
143 #define AdControl_Dma 0x01 /* 1=enable DMA, 0=disable */
145 /* bits from A/D function register (PCI9118_ADFUNC) */
146 #define AdFunction_PDTrg 0x80 /*
148 * 0=negative digital trigger
149 * (only positive is correct)
151 #define AdFunction_PETrg 0x40 /*
153 * 0=negative external trigger
154 * (only positive is correct)
156 #define AdFunction_BSSH 0x20 /* 1=with sample&hold, 0=without */
157 #define AdFunction_BM 0x10 /* 1=burst mode, 0=normal mode */
158 #define AdFunction_BS 0x08 /*
159 * 1=burst mode start,
162 #define AdFunction_PM 0x04 /*
163 * 1=post trigger mode,
166 #define AdFunction_AM 0x02 /*
167 * 1=about trigger mode,
168 * 0=not about trigger
170 #define AdFunction_Start 0x01 /* 1=trigger start, 0=trigger stop */
172 /* bits from A/D status register (PCI9118_ADSTAT) */
173 #define AdStatus_nFull 0x100 /* 0=FIFO full (fatal), 1=not full */
174 #define AdStatus_nHfull 0x080 /* 0=FIFO half full, 1=FIFO not half full */
175 #define AdStatus_nEpty 0x040 /* 0=FIFO empty, 1=FIFO not empty */
176 #define AdStatus_Acmp 0x020 /* */
177 #define AdStatus_DTH 0x010 /* 1=external digital trigger */
178 #define AdStatus_Bover 0x008 /* 1=burst mode overrun (fatal) */
179 #define AdStatus_ADOS 0x004 /* 1=A/D over speed (warning) */
180 #define AdStatus_ADOR 0x002 /* 1=A/D overrun (fatal) */
181 #define AdStatus_ADrdy 0x001 /* 1=A/D already ready, 0=not ready */
183 /* bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL) */
184 /* 1=interrupt occur, enable source, 0=interrupt not occur, disable source */
185 #define Int_Timer 0x08 /* timer interrupt */
186 #define Int_About 0x04 /* about trigger complete */
187 #define Int_Hfull 0x02 /* A/D FIFO hlaf full */
188 #define Int_DTrg 0x01 /* external digital trigger */
190 #define START_AI_EXT 0x01 /* start measure on external trigger */
191 #define STOP_AI_EXT 0x02 /* stop measure on external trigger */
192 #define START_AI_INT 0x04 /* start measure on internal trigger */
193 #define STOP_AI_INT 0x08 /* stop measure on internal trigger */
195 #define EXTTRG_AI 0 /* ext trg is used by AI */
197 static const struct comedi_lrange range_pci9118dg_hr = { 8, {
209 static const struct comedi_lrange range_pci9118hg = { 8, {
221 #define PCI9118_BIPOLAR_RANGES 4 /*
222 * used for test on mixture
227 const char *name; /* board name */
228 int device_id; /* PCI device ID of card */
229 int iorange_amcc; /* iorange for own S5933 region */
230 int iorange_9118; /* pass thru card region size */
231 int n_aichan; /* num of A/D chans */
232 int n_aichand; /* num of A/D chans in diff mode */
234 * num of A/D chans with
235 * external multiplexor
237 int n_aichanlist; /* len of chanlist */
238 int n_aochan; /* num of D/A chans */
239 int ai_maxdata; /* resolution of A/D */
240 int ao_maxdata; /* resolution of D/A */
241 const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */
242 const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */
243 unsigned int ai_ns_min; /* max sample speed of card v ns */
244 unsigned int ai_pacer_min; /*
245 * minimal pacer value
246 * (c1*c2 or c1 in burst)
248 int half_fifo_size; /* size of FIFO/2 */
252 static const struct boardtype boardtypes[] = {
256 .iorange_amcc = AMCC_OP_REG_SIZE,
257 .iorange_9118 = IORANGE_9118,
261 .n_aichanlist = PCI9118_CHANLEN,
263 .ai_maxdata = 0x0fff,
264 .ao_maxdata = 0x0fff,
265 .rangelist_ai = &range_pci9118dg_hr,
266 .rangelist_ao = &range_bipolar10,
269 .half_fifo_size = 512,
273 .iorange_amcc = AMCC_OP_REG_SIZE,
274 .iorange_9118 = IORANGE_9118,
278 .n_aichanlist = PCI9118_CHANLEN,
280 .ai_maxdata = 0x0fff,
281 .ao_maxdata = 0x0fff,
282 .rangelist_ai = &range_pci9118hg,
283 .rangelist_ao = &range_bipolar10,
286 .half_fifo_size = 512,
290 .iorange_amcc = AMCC_OP_REG_SIZE,
291 .iorange_9118 = IORANGE_9118,
295 .n_aichanlist = PCI9118_CHANLEN,
297 .ai_maxdata = 0xffff,
298 .ao_maxdata = 0x0fff,
299 .rangelist_ai = &range_pci9118dg_hr,
300 .rangelist_ao = &range_bipolar10,
303 .half_fifo_size = 512,
307 struct pci9118_private {
308 unsigned long iobase_a; /* base+size for AMCC chip */
309 unsigned int master; /* master capable */
310 unsigned int usemux; /* we want to use external multiplexor! */
311 #ifdef PCI9118_PARANOIDCHECK
312 unsigned short chanlist[PCI9118_CHANLEN + 1]; /*
316 unsigned char chanlistlen; /* number of scanlist */
318 unsigned char AdControlReg; /* A/D control register */
319 unsigned char IntControlReg; /* Interrupt control register */
320 unsigned char AdFunctionReg; /* A/D function register */
321 char valid; /* driver is ok */
322 char ai_neverending; /* we do unlimited AI */
323 unsigned int i8254_osc_base; /* frequence of onboard oscilator */
324 unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */
325 unsigned int ai_act_scan; /* how many scans we finished */
326 unsigned int ai_buf_ptr; /* data buffer ptr in samples */
327 unsigned int ai_n_chan; /* how many channels is measured */
328 unsigned int ai_n_scanlen; /* len of actual scanlist */
329 unsigned int ai_n_realscanlen; /*
330 * what we must transfer for one
331 * outgoing scan include front/back adds
333 unsigned int ai_act_dmapos; /* position in actual real stream */
334 unsigned int ai_add_front; /*
335 * how many channels we must add
336 * before scan to satisfy S&H?
338 unsigned int ai_add_back; /*
339 * how many channels we must add
340 * before scan to satisfy DMA?
342 unsigned int *ai_chanlist; /* actual chanlist */
343 unsigned int ai_timer1;
344 unsigned int ai_timer2;
345 unsigned int ai_flags;
346 char ai12_startstop; /*
347 * measure can start/stop
348 * on external trigger
350 unsigned int ai_divisor1, ai_divisor2; /*
351 * divisors for start of measure
354 unsigned int ai_data_len;
356 short ao_data[2]; /* data output buffer */
357 unsigned int ai_scans; /* number of scans to do */
358 char dma_doublebuf; /* we can use double buffering */
359 unsigned int dma_actbuf; /* which buffer is used now */
360 short *dmabuf_virt[2]; /*
361 * pointers to begin of
364 unsigned long dmabuf_hw[2]; /* hw address of DMA buff */
365 unsigned int dmabuf_size[2]; /*
366 * size of dma buffer in bytes
368 unsigned int dmabuf_use_size[2]; /*
369 * which size we may now use
372 unsigned int dmabuf_used_size[2]; /* which size was truly used */
373 unsigned int dmabuf_panic_size[2];
374 unsigned int dmabuf_samples[2]; /* size in samples */
375 int dmabuf_pages[2]; /* number of pages in buffer */
376 unsigned char cnt0_users; /*
377 * bit field of 8254 CNT0 users
378 * (0-unused, 1-AO, 2-DI, 3-DO)
380 unsigned char exttrg_users; /*
381 * bit field of external trigger
382 * users(0-AI, 1-AO, 2-DI, 3-DO)
384 unsigned int cnt0_divisor; /* actual CNT0 divisor */
385 void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *,
389 * ptr to actual interrupt
392 unsigned char ai16bits; /* =1 16 bit card */
393 unsigned char usedma; /* =1 use DMA transfer and not INT */
394 unsigned char useeoshandle; /*
395 * =1 change WAKE_EOS DMA transfer
396 * to fit on every second
398 unsigned char usessh; /* =1 turn on S&H support */
400 * >0 use software S&H,
401 * numer is requested delay in ns
403 unsigned char softsshsample; /*
404 * polarity of S&H signal
407 unsigned char softsshhold; /*
408 * polarity of S&H signal
411 unsigned int ai_maskerr; /* which warning was printed */
412 unsigned int ai_maskharderr; /* on which error bits stops */
413 unsigned int ai_inttrig_start; /* TRIG_INT for start */
416 static int check_channel_list(struct comedi_device *dev,
417 struct comedi_subdevice *s, int n_chan,
418 unsigned int *chanlist, int frontadd, int backadd)
420 const struct boardtype *this_board = comedi_board(dev);
421 struct pci9118_private *devpriv = dev->private;
422 unsigned int i, differencial = 0, bipolar = 0;
424 /* correct channel and range number check itself comedi/range.c */
426 comedi_error(dev, "range/channel list is empty!");
429 if ((frontadd + n_chan + backadd) > s->len_chanlist) {
431 "range/channel list is too long for actual configuration!\n");
435 if (CR_AREF(chanlist[0]) == AREF_DIFF)
436 differencial = 1; /* all input must be diff */
437 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
438 bipolar = 1; /* all input must be bipolar */
440 for (i = 1; i < n_chan; i++) { /* check S.E/diff */
441 if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
444 "Differencial and single ended "
445 "inputs can't be mixtured!");
448 if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
451 "Bipolar and unipolar ranges "
452 "can't be mixtured!");
455 if (!devpriv->usemux && differencial &&
456 (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
458 "If AREF_DIFF is used then is "
459 "available only first 8 channels!");
467 static int setup_channel_list(struct comedi_device *dev,
468 struct comedi_subdevice *s, int n_chan,
469 unsigned int *chanlist, int rot, int frontadd,
470 int backadd, int usedma, char useeos)
472 struct pci9118_private *devpriv = dev->private;
473 unsigned int i, differencial = 0, bipolar = 0;
474 unsigned int scanquad, gain, ssh = 0x00;
481 if (CR_AREF(chanlist[0]) == AREF_DIFF)
482 differencial = 1; /* all input must be diff */
483 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
484 bipolar = 1; /* all input must be bipolar */
486 /* All is ok, so we can setup channel/range list */
489 devpriv->AdControlReg |= AdControl_UniP;
492 devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
497 devpriv->AdControlReg |= AdControl_Diff;
498 /* enable diff inputs */
500 devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
501 /* set single ended inputs */
504 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
507 outl(2, dev->iobase + PCI9118_SCANMOD);
508 /* gods know why this sequence! */
509 outl(0, dev->iobase + PCI9118_SCANMOD);
510 outl(1, dev->iobase + PCI9118_SCANMOD);
512 #ifdef PCI9118_PARANOIDCHECK
513 devpriv->chanlistlen = n_chan;
514 for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
515 devpriv->chanlist[i] = 0x55aa;
518 if (frontadd) { /* insert channels for S&H */
519 ssh = devpriv->softsshsample;
520 for (i = 0; i < frontadd; i++) {
521 /* store range list to card */
522 scanquad = CR_CHAN(chanlist[0]);
523 /* get channel number; */
524 gain = CR_RANGE(chanlist[0]);
525 /* get gain number */
526 scanquad |= ((gain & 0x03) << 8);
527 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
528 ssh = devpriv->softsshhold;
532 for (i = 0; i < n_chan; i++) { /* store range list to card */
533 scanquad = CR_CHAN(chanlist[i]); /* get channel number */
534 #ifdef PCI9118_PARANOIDCHECK
535 devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
537 gain = CR_RANGE(chanlist[i]); /* get gain number */
538 scanquad |= ((gain & 0x03) << 8);
539 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
542 if (backadd) { /* insert channels for fit onto 32bit DMA */
543 for (i = 0; i < backadd; i++) { /* store range list to card */
544 scanquad = CR_CHAN(chanlist[0]);
545 /* get channel number */
546 gain = CR_RANGE(chanlist[0]); /* get gain number */
547 scanquad |= ((gain & 0x03) << 8);
548 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
551 #ifdef PCI9118_PARANOIDCHECK
552 devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
553 /* for 32bit operations */
555 for (i = 1; i < n_chan; i++) { /* store range list to card */
556 devpriv->chanlist[(n_chan + i) ^ usedma] =
557 (CR_CHAN(chanlist[i]) & 0xf) << rot;
559 devpriv->chanlist[(2 * n_chan) ^ usedma] =
560 devpriv->chanlist[0 ^ usedma];
561 /* for 32bit operations */
567 outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */
568 /* udelay(100); important delay, or first sample will be crippled */
570 return 1; /* we can serve this with scan logic */
573 static int pci9118_insn_read_ai(struct comedi_device *dev,
574 struct comedi_subdevice *s,
575 struct comedi_insn *insn, unsigned int *data)
577 struct pci9118_private *devpriv = dev->private;
580 devpriv->AdControlReg = AdControl_Int & 0xff;
581 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
582 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
584 * positive triggers, no S&H,
585 * no burst, burst stop,
591 if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
594 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
596 for (n = 0; n < insn->n; n++) {
597 outw(0, dev->iobase + PCI9118_SOFTTRG); /* start conversion */
601 if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
606 comedi_error(dev, "A/D insn timeout");
608 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
612 if (devpriv->ai16bits) {
615 PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
618 (inw(dev->iobase + PCI9118_AD_DATA) >> 4) & 0xfff;
622 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
627 static int pci9118_insn_write_ao(struct comedi_device *dev,
628 struct comedi_subdevice *s,
629 struct comedi_insn *insn, unsigned int *data)
631 struct pci9118_private *devpriv = dev->private;
634 ch = CR_CHAN(insn->chanspec);
636 chanreg = PCI9118_DA2;
638 chanreg = PCI9118_DA1;
641 for (n = 0; n < insn->n; n++) {
642 outl(data[n], dev->iobase + chanreg);
643 devpriv->ao_data[ch] = data[n];
649 static int pci9118_insn_read_ao(struct comedi_device *dev,
650 struct comedi_subdevice *s,
651 struct comedi_insn *insn, unsigned int *data)
653 struct pci9118_private *devpriv = dev->private;
656 chan = CR_CHAN(insn->chanspec);
657 for (n = 0; n < insn->n; n++)
658 data[n] = devpriv->ao_data[chan];
663 static int pci9118_insn_bits_di(struct comedi_device *dev,
664 struct comedi_subdevice *s,
665 struct comedi_insn *insn, unsigned int *data)
667 data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
672 static int pci9118_insn_bits_do(struct comedi_device *dev,
673 struct comedi_subdevice *s,
674 struct comedi_insn *insn, unsigned int *data)
677 s->state &= ~data[0];
678 s->state |= (data[0] & data[1]);
679 outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
686 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev)
688 struct pci9118_private *devpriv = dev->private;
690 devpriv->AdFunctionReg =
691 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
692 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
693 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
694 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
695 dev->iobase + PCI9118_CNT0);
696 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
697 dev->iobase + PCI9118_CNT0);
698 devpriv->AdFunctionReg |= AdFunction_Start;
699 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
702 static unsigned int defragment_dma_buffer(struct comedi_device *dev,
703 struct comedi_subdevice *s,
705 unsigned int num_samples)
707 struct pci9118_private *devpriv = dev->private;
708 unsigned int i = 0, j = 0;
709 unsigned int start_pos = devpriv->ai_add_front,
710 stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
711 unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
712 devpriv->ai_add_back;
714 for (i = 0; i < num_samples; i++) {
715 if (devpriv->ai_act_dmapos >= start_pos &&
716 devpriv->ai_act_dmapos < stop_pos) {
717 dma_buffer[j++] = dma_buffer[i];
719 devpriv->ai_act_dmapos++;
720 devpriv->ai_act_dmapos %= raw_scanlen;
726 static int move_block_from_dma(struct comedi_device *dev,
727 struct comedi_subdevice *s,
729 unsigned int num_samples)
731 struct pci9118_private *devpriv = dev->private;
732 unsigned int num_bytes;
734 num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
735 devpriv->ai_act_scan +=
736 (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
737 s->async->cur_chan += num_samples;
738 s->async->cur_chan %= devpriv->ai_n_scanlen;
740 cfc_write_array_to_buffer(s, dma_buffer,
741 num_samples * sizeof(short));
742 if (num_bytes < num_samples * sizeof(short))
747 static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
749 struct pci9118_private *devpriv = dev->private;
752 return -1; /* incorrect source */
753 devpriv->exttrg_users |= (1 << source);
754 devpriv->IntControlReg |= Int_DTrg;
755 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
756 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
757 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
758 /* allow INT in AMCC */
762 static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
764 struct pci9118_private *devpriv = dev->private;
767 return -1; /* incorrect source */
768 devpriv->exttrg_users &= ~(1 << source);
769 if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */
770 devpriv->IntControlReg &= ~Int_DTrg;
771 if (!devpriv->IntControlReg) /* all IRQ disabled */
772 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) &
774 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
775 /* disable int in AMCC */
776 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
781 static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
782 struct comedi_subdevice *s,
783 unsigned int *tim1, unsigned int *tim2,
784 unsigned int flags, int chans,
785 unsigned int *div1, unsigned int *div2,
786 char usessh, unsigned int chnsshfront)
788 const struct boardtype *this_board = comedi_board(dev);
789 struct pci9118_private *devpriv = dev->private;
794 if (*tim2 < this_board->ai_ns_min)
795 *tim2 = this_board->ai_ns_min;
796 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
797 tim2, flags & TRIG_ROUND_NEAREST);
800 if (*tim2 < this_board->ai_ns_min)
801 *tim2 = this_board->ai_ns_min;
802 *div1 = *tim2 / devpriv->i8254_osc_base;
803 /* convert timer (burst) */
804 if (*div1 < this_board->ai_pacer_min)
805 *div1 = this_board->ai_pacer_min;
806 *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */
807 *div2 = *div2 / *div1; /* major timer is c1*c2 */
811 *tim2 = *div1 * devpriv->i8254_osc_base;
812 /* real convert timer */
814 if (usessh && (chnsshfront == 0)) /* use BSSH signal */
815 if (*div2 < (chans + 2))
818 *tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
823 static void start_pacer(struct comedi_device *dev, int mode,
824 unsigned int divisor1, unsigned int divisor2)
826 outl(0x74, dev->iobase + PCI9118_CNTCTRL);
827 outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
828 /* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
831 if ((mode == 1) || (mode == 2) || (mode == 4)) {
832 outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
833 outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
834 outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
835 outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
839 static int pci9118_ai_cancel(struct comedi_device *dev,
840 struct comedi_subdevice *s)
842 struct pci9118_private *devpriv = dev->private;
845 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) &
847 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
848 pci9118_exttrg_del(dev, EXTTRG_AI);
849 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
850 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
851 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
853 * positive triggers, no S&H, no burst,
854 * burst stop, no post trigger,
855 * no about trigger, trigger stop
857 devpriv->AdControlReg = 0x00;
858 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
860 * bipolar, S.E., use 8254, stop 8354,
861 * internal trigger, soft trigger,
862 * disable INT and DMA
864 outl(0, dev->iobase + PCI9118_BURST);
865 outl(1, dev->iobase + PCI9118_SCANMOD);
866 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
867 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
872 devpriv->ai_act_scan = 0;
873 devpriv->ai_act_dmapos = 0;
874 s->async->cur_chan = 0;
875 s->async->inttrig = NULL;
876 devpriv->ai_buf_ptr = 0;
877 devpriv->ai_neverending = 0;
878 devpriv->dma_actbuf = 0;
880 if (!devpriv->IntControlReg)
881 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
882 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
883 /* allow INT in AMCC */
888 static char pci9118_decode_error_status(struct comedi_device *dev,
889 struct comedi_subdevice *s,
892 struct pci9118_private *devpriv = dev->private;
895 comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
896 devpriv->ai_maskerr &= ~0x100L;
900 "A/D Burst Mode Overrun Status (Fatal Error!)");
901 devpriv->ai_maskerr &= ~0x008L;
904 comedi_error(dev, "A/D Over Speed Status (Warning!)");
905 devpriv->ai_maskerr &= ~0x004L;
908 comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
909 devpriv->ai_maskerr &= ~0x002L;
911 if (m & devpriv->ai_maskharderr) {
912 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
913 pci9118_ai_cancel(dev, s);
914 comedi_event(dev, s);
921 static void pci9118_ai_munge(struct comedi_device *dev,
922 struct comedi_subdevice *s, void *data,
923 unsigned int num_bytes,
924 unsigned int start_chan_index)
926 struct pci9118_private *devpriv = dev->private;
927 unsigned int i, num_samples = num_bytes / sizeof(short);
930 for (i = 0; i < num_samples; i++) {
932 array[i] = be16_to_cpu(array[i]);
933 if (devpriv->ai16bits)
936 array[i] = (array[i] >> 4) & 0x0fff;
941 static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
942 struct comedi_subdevice *s,
943 unsigned short int_adstat,
944 unsigned int int_amcc,
945 unsigned short int_daq)
947 struct pci9118_private *devpriv = dev->private;
948 register short sampl;
950 s->async->events = 0;
952 if (int_adstat & devpriv->ai_maskerr)
953 if (pci9118_decode_error_status(dev, s, int_adstat))
956 sampl = inw(dev->iobase + PCI9118_AD_DATA);
958 #ifdef PCI9118_PARANOIDCHECK
959 if (devpriv->ai16bits == 0) {
960 if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) {
962 dev_info(dev->class_dev,
963 "A/D SAMPL - data dropout: received channel %d, expected %d!\n",
965 devpriv->chanlist[s->async->cur_chan]);
966 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
967 pci9118_ai_cancel(dev, s);
968 comedi_event(dev, s);
973 cfc_write_to_buffer(s, sampl);
974 s->async->cur_chan++;
975 if (s->async->cur_chan >= devpriv->ai_n_scanlen) {
977 s->async->cur_chan %= devpriv->ai_n_scanlen;
978 devpriv->ai_act_scan++;
979 if (!(devpriv->ai_neverending))
980 if (devpriv->ai_act_scan >= devpriv->ai_scans) {
981 /* all data sampled */
982 pci9118_ai_cancel(dev, s);
983 s->async->events |= COMEDI_CB_EOA;
987 if (s->async->events)
988 comedi_event(dev, s);
991 static void interrupt_pci9118_ai_dma(struct comedi_device *dev,
992 struct comedi_subdevice *s,
993 unsigned short int_adstat,
994 unsigned int int_amcc,
995 unsigned short int_daq)
997 struct pci9118_private *devpriv = dev->private;
998 unsigned int next_dma_buf, samplesinbuf, sampls, m;
1000 if (int_amcc & MASTER_ABORT_INT) {
1001 comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
1002 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1003 pci9118_ai_cancel(dev, s);
1004 comedi_event(dev, s);
1008 if (int_amcc & TARGET_ABORT_INT) {
1009 comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
1010 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1011 pci9118_ai_cancel(dev, s);
1012 comedi_event(dev, s);
1015 if (int_adstat & devpriv->ai_maskerr)
1016 /* if (int_adstat & 0x106) */
1017 if (pci9118_decode_error_status(dev, s, int_adstat))
1020 samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1;
1021 /* number of received real samples */
1023 if (devpriv->dma_doublebuf) { /*
1024 * switch DMA buffers if is used
1027 next_dma_buf = 1 - devpriv->dma_actbuf;
1028 outl(devpriv->dmabuf_hw[next_dma_buf],
1029 devpriv->iobase_a + AMCC_OP_REG_MWAR);
1030 outl(devpriv->dmabuf_use_size[next_dma_buf],
1031 devpriv->iobase_a + AMCC_OP_REG_MWTC);
1032 devpriv->dmabuf_used_size[next_dma_buf] =
1033 devpriv->dmabuf_use_size[next_dma_buf];
1034 if (devpriv->ai_do == 4)
1035 interrupt_pci9118_ai_mode4_switch(dev);
1039 m = devpriv->ai_data_len >> 1; /*
1040 * how many samples is to
1044 move_block_from_dma(dev, s,
1045 devpriv->dmabuf_virt[devpriv->dma_actbuf],
1047 m = m - sampls; /* m= how many samples was transferred */
1050 if (!devpriv->ai_neverending)
1051 if (devpriv->ai_act_scan >= devpriv->ai_scans) {
1052 /* all data sampled */
1053 pci9118_ai_cancel(dev, s);
1054 s->async->events |= COMEDI_CB_EOA;
1057 if (devpriv->dma_doublebuf) { /* switch dma buffers */
1058 devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
1059 } else { /* restart DMA if is not used double buffering */
1060 outl(devpriv->dmabuf_hw[0],
1061 devpriv->iobase_a + AMCC_OP_REG_MWAR);
1062 outl(devpriv->dmabuf_use_size[0],
1063 devpriv->iobase_a + AMCC_OP_REG_MWTC);
1064 if (devpriv->ai_do == 4)
1065 interrupt_pci9118_ai_mode4_switch(dev);
1068 comedi_event(dev, s);
1071 static irqreturn_t interrupt_pci9118(int irq, void *d)
1073 struct comedi_device *dev = d;
1074 struct pci9118_private *devpriv = dev->private;
1075 unsigned int int_daq = 0, int_amcc, int_adstat;
1078 return IRQ_NONE; /* not fully initialized */
1080 int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf;
1081 /* get IRQ reasons from card */
1082 int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1083 /* get INT register from AMCC chip */
1085 if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
1086 return IRQ_NONE; /* interrupt from other source */
1088 outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1089 /* shutdown IRQ reasons in AMCC */
1091 int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff;
1092 /* get STATUS register */
1094 if (devpriv->ai_do) {
1095 if (devpriv->ai12_startstop)
1096 if ((int_adstat & AdStatus_DTH) &&
1097 (int_daq & Int_DTrg)) {
1098 /* start stop of measure */
1099 if (devpriv->ai12_startstop & START_AI_EXT) {
1100 devpriv->ai12_startstop &=
1102 if (!(devpriv->ai12_startstop &
1106 /* deactivate EXT trigger */
1107 start_pacer(dev, devpriv->ai_do,
1108 devpriv->ai_divisor1,
1109 devpriv->ai_divisor2);
1111 outl(devpriv->AdControlReg,
1112 dev->iobase + PCI9118_ADCNTRL);
1114 if (devpriv->ai12_startstop &
1116 devpriv->ai12_startstop &=
1120 /* deactivate EXT trigger */
1121 devpriv->ai_neverending = 0;
1123 * well, on next interrupt from
1124 * DMA/EOC measure will stop
1130 (devpriv->int_ai_func) (dev, &dev->subdevices[0], int_adstat,
1137 static int pci9118_ai_inttrig(struct comedi_device *dev,
1138 struct comedi_subdevice *s, unsigned int trignum)
1140 struct pci9118_private *devpriv = dev->private;
1142 if (trignum != devpriv->ai_inttrig_start)
1145 devpriv->ai12_startstop &= ~START_AI_INT;
1146 s->async->inttrig = NULL;
1148 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1149 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1150 if (devpriv->ai_do != 3) {
1151 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1152 devpriv->ai_divisor2);
1153 devpriv->AdControlReg |= AdControl_SoftG;
1155 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1160 static int pci9118_ai_cmdtest(struct comedi_device *dev,
1161 struct comedi_subdevice *s,
1162 struct comedi_cmd *cmd)
1164 const struct boardtype *this_board = comedi_board(dev);
1165 struct pci9118_private *devpriv = dev->private;
1169 unsigned int divisor1 = 0, divisor2 = 0;
1171 /* Step 1 : check if triggers are trivially valid */
1173 err |= cfc_check_trigger_src(&cmd->start_src,
1174 TRIG_NOW | TRIG_EXT | TRIG_INT);
1176 flags = TRIG_FOLLOW;
1177 if (devpriv->master)
1178 flags |= TRIG_TIMER | TRIG_EXT;
1179 err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1181 flags = TRIG_TIMER | TRIG_EXT;
1182 if (devpriv->master)
1184 err |= cfc_check_trigger_src(&cmd->convert_src, flags);
1186 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1187 err |= cfc_check_trigger_src(&cmd->stop_src,
1188 TRIG_COUNT | TRIG_NONE | TRIG_EXT);
1193 /* Step 2a : make sure trigger sources are unique */
1195 err |= cfc_check_trigger_is_unique(cmd->start_src);
1196 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1197 err |= cfc_check_trigger_is_unique(cmd->convert_src);
1198 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1200 /* Step 2b : and mutually compatible */
1202 if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1205 if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT)
1208 if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
1209 (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW))))
1212 if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
1213 (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT))))
1216 if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1222 /* Step 3: check if arguments are trivially valid */
1224 if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
1225 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1227 if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
1228 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1230 if ((cmd->scan_begin_src == TRIG_TIMER) &&
1231 (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
1232 cmd->scan_begin_src = TRIG_FOLLOW;
1233 cmd->convert_arg = cmd->scan_begin_arg;
1234 cmd->scan_begin_arg = 0;
1237 if (cmd->scan_begin_src == TRIG_TIMER)
1238 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1239 this_board->ai_ns_min);
1241 if (cmd->scan_begin_src == TRIG_EXT)
1242 if (cmd->scan_begin_arg) {
1243 cmd->scan_begin_arg = 0;
1245 err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg,
1249 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
1250 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
1251 this_board->ai_ns_min);
1253 if (cmd->convert_src == TRIG_EXT)
1254 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
1256 if (cmd->stop_src == TRIG_COUNT)
1257 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
1258 else /* TRIG_NONE */
1259 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1261 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
1262 err |= cfc_check_trigger_arg_max(&cmd->chanlist_len,
1263 this_board->n_aichanlist);
1265 err |= cfc_check_trigger_arg_min(&cmd->scan_end_arg,
1268 if ((cmd->scan_end_arg % cmd->chanlist_len)) {
1270 cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
1277 /* step 4: fix up any arguments */
1279 if (cmd->scan_begin_src == TRIG_TIMER) {
1280 tmp = cmd->scan_begin_arg;
1281 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1282 &divisor2, &cmd->scan_begin_arg,
1283 cmd->flags & TRIG_ROUND_MASK);
1284 if (cmd->scan_begin_arg < this_board->ai_ns_min)
1285 cmd->scan_begin_arg = this_board->ai_ns_min;
1286 if (tmp != cmd->scan_begin_arg)
1290 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
1291 tmp = cmd->convert_arg;
1292 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1293 &divisor2, &cmd->convert_arg,
1294 cmd->flags & TRIG_ROUND_MASK);
1295 if (cmd->convert_arg < this_board->ai_ns_min)
1296 cmd->convert_arg = this_board->ai_ns_min;
1297 if (tmp != cmd->convert_arg)
1299 if (cmd->scan_begin_src == TRIG_TIMER
1300 && cmd->convert_src == TRIG_NOW) {
1301 if (cmd->convert_arg == 0) {
1302 if (cmd->scan_begin_arg <
1303 this_board->ai_ns_min *
1304 (cmd->scan_end_arg + 2)) {
1305 cmd->scan_begin_arg =
1306 this_board->ai_ns_min *
1307 (cmd->scan_end_arg + 2);
1311 if (cmd->scan_begin_arg <
1312 cmd->convert_arg * cmd->chanlist_len) {
1313 cmd->scan_begin_arg =
1326 if (!check_channel_list(dev, s, cmd->chanlist_len,
1327 cmd->chanlist, 0, 0))
1328 return 5; /* incorrect channels list */
1333 static int Compute_and_setup_dma(struct comedi_device *dev)
1335 struct pci9118_private *devpriv = dev->private;
1336 unsigned int dmalen0, dmalen1, i;
1338 dmalen0 = devpriv->dmabuf_size[0];
1339 dmalen1 = devpriv->dmabuf_size[1];
1340 /* isn't output buff smaller that our DMA buff? */
1341 if (dmalen0 > (devpriv->ai_data_len)) {
1342 dmalen0 = devpriv->ai_data_len & ~3L; /*
1343 * align to 32bit down
1346 if (dmalen1 > (devpriv->ai_data_len)) {
1347 dmalen1 = devpriv->ai_data_len & ~3L; /*
1348 * align to 32bit down
1352 /* we want wake up every scan? */
1353 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1354 if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
1355 /* uff, too short DMA buffer, disable EOS support! */
1356 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1357 dev_info(dev->class_dev,
1358 "WAR: DMA0 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n",
1359 dmalen0, devpriv->ai_n_realscanlen << 1);
1361 /* short first DMA buffer to one scan */
1362 dmalen0 = devpriv->ai_n_realscanlen << 1;
1363 if (devpriv->useeoshandle)
1366 dev_info(dev->class_dev,
1367 "ERR: DMA0 buf len bug? (%d<4)\n",
1373 if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1374 if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
1375 /* uff, too short DMA buffer, disable EOS support! */
1376 devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1377 dev_info(dev->class_dev,
1378 "WAR: DMA1 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n",
1379 dmalen1, devpriv->ai_n_realscanlen << 1);
1381 /* short second DMA buffer to one scan */
1382 dmalen1 = devpriv->ai_n_realscanlen << 1;
1383 if (devpriv->useeoshandle)
1386 dev_info(dev->class_dev,
1387 "ERR: DMA1 buf len bug? (%d<4)\n",
1394 /* transfer without TRIG_WAKE_EOS */
1395 if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
1396 /* if it's possible then align DMA buffers to length of scan */
1399 (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
1400 (devpriv->ai_n_realscanlen << 1);
1403 dmalen0 = i; /* uff. very long scan? */
1406 (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
1407 (devpriv->ai_n_realscanlen << 1);
1410 dmalen1 = i; /* uff. very long scan? */
1412 * if measure isn't neverending then test, if it fits whole
1413 * into one or two DMA buffers
1415 if (!devpriv->ai_neverending) {
1416 /* fits whole measure into one DMA buffer? */
1418 ((devpriv->ai_n_realscanlen << 1) *
1419 devpriv->ai_scans)) {
1421 (devpriv->ai_n_realscanlen << 1) *
1425 * fits whole measure into
1429 ((devpriv->ai_n_realscanlen << 1) *
1430 devpriv->ai_scans - dmalen0))
1432 (devpriv->ai_n_realscanlen << 1) *
1433 devpriv->ai_scans - dmalen0;
1439 /* these DMA buffer size will be used */
1440 devpriv->dma_actbuf = 0;
1441 devpriv->dmabuf_use_size[0] = dmalen0;
1442 devpriv->dmabuf_use_size[1] = dmalen1;
1445 if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
1446 devpriv->dmabuf_panic_size[0] =
1447 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1448 1) * devpriv->ai_n_scanlen * sizeof(short);
1449 devpriv->dmabuf_panic_size[1] =
1450 (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1451 1) * devpriv->ai_n_scanlen * sizeof(short);
1453 devpriv->dmabuf_panic_size[0] =
1454 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
1455 devpriv->dmabuf_panic_size[1] =
1456 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
1460 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS),
1461 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
1462 outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
1463 outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
1464 /* init DMA transfer */
1465 outl(0x00000000 | AINT_WRITE_COMPL,
1466 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1467 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
1469 outl(inl(devpriv->iobase_a +
1470 AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
1471 EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
1472 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS,
1473 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1474 /* allow bus mastering */
1479 static int pci9118_ai_docmd_sampl(struct comedi_device *dev,
1480 struct comedi_subdevice *s)
1482 struct pci9118_private *devpriv = dev->private;
1484 switch (devpriv->ai_do) {
1486 devpriv->AdControlReg |= AdControl_TmrTr;
1489 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
1492 devpriv->AdControlReg |= AdControl_ExtM;
1495 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
1499 "pci9118_ai_docmd_sampl() mode number bug!\n");
1503 devpriv->int_ai_func = interrupt_pci9118_ai_onesample;
1504 /* transfer function */
1506 if (devpriv->ai12_startstop)
1507 pci9118_exttrg_add(dev, EXTTRG_AI);
1508 /* activate EXT trigger */
1510 if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
1511 devpriv->IntControlReg |= Int_Timer;
1513 devpriv->AdControlReg |= AdControl_Int;
1515 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
1516 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1517 /* allow INT in AMCC */
1519 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1520 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1521 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1522 if (devpriv->ai_do != 3) {
1523 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1524 devpriv->ai_divisor2);
1525 devpriv->AdControlReg |= AdControl_SoftG;
1527 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1533 static int pci9118_ai_docmd_dma(struct comedi_device *dev,
1534 struct comedi_subdevice *s)
1536 struct pci9118_private *devpriv = dev->private;
1538 Compute_and_setup_dma(dev);
1540 switch (devpriv->ai_do) {
1542 devpriv->AdControlReg |=
1543 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1546 devpriv->AdControlReg |=
1547 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1548 devpriv->AdFunctionReg =
1549 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
1551 if (devpriv->usessh && (!devpriv->softsshdelay))
1552 devpriv->AdFunctionReg |= AdFunction_BSSH;
1553 outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
1556 devpriv->AdControlReg |=
1557 ((AdControl_ExtM | AdControl_Dma) & 0xff);
1558 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1561 devpriv->AdControlReg |=
1562 ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1563 devpriv->AdFunctionReg =
1564 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
1565 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1566 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1567 outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
1568 dev->iobase + PCI9118_CNT0);
1569 outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
1570 dev->iobase + PCI9118_CNT0);
1571 devpriv->AdFunctionReg |= AdFunction_Start;
1574 comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
1578 if (devpriv->ai12_startstop) {
1579 pci9118_exttrg_add(dev, EXTTRG_AI);
1580 /* activate EXT trigger */
1583 devpriv->int_ai_func = interrupt_pci9118_ai_dma;
1584 /* transfer function */
1586 outl(0x02000000 | AINT_WRITE_COMPL,
1587 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1589 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1590 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1591 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1592 if (devpriv->ai_do != 3) {
1593 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1594 devpriv->ai_divisor2);
1595 devpriv->AdControlReg |= AdControl_SoftG;
1597 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1603 static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1605 const struct boardtype *this_board = comedi_board(dev);
1606 struct pci9118_private *devpriv = dev->private;
1607 struct comedi_cmd *cmd = &s->async->cmd;
1608 unsigned int addchans = 0;
1611 devpriv->ai12_startstop = 0;
1612 devpriv->ai_flags = cmd->flags;
1613 devpriv->ai_n_chan = cmd->chanlist_len;
1614 devpriv->ai_n_scanlen = cmd->scan_end_arg;
1615 devpriv->ai_chanlist = cmd->chanlist;
1616 devpriv->ai_data = s->async->prealloc_buf;
1617 devpriv->ai_data_len = s->async->prealloc_bufsz;
1618 devpriv->ai_timer1 = 0;
1619 devpriv->ai_timer2 = 0;
1620 devpriv->ai_add_front = 0;
1621 devpriv->ai_add_back = 0;
1622 devpriv->ai_maskerr = 0x10e;
1624 /* prepare for start/stop conditions */
1625 if (cmd->start_src == TRIG_EXT)
1626 devpriv->ai12_startstop |= START_AI_EXT;
1627 if (cmd->stop_src == TRIG_EXT) {
1628 devpriv->ai_neverending = 1;
1629 devpriv->ai12_startstop |= STOP_AI_EXT;
1631 if (cmd->start_src == TRIG_INT) {
1632 devpriv->ai12_startstop |= START_AI_INT;
1633 devpriv->ai_inttrig_start = cmd->start_arg;
1634 s->async->inttrig = pci9118_ai_inttrig;
1637 if (cmd->stop_src == TRIG_INT) {
1638 devpriv->ai_neverending = 1;
1639 devpriv->ai12_startstop |= STOP_AI_INT;
1642 if (cmd->stop_src == TRIG_NONE)
1643 devpriv->ai_neverending = 1;
1644 if (cmd->stop_src == TRIG_COUNT) {
1645 devpriv->ai_scans = cmd->stop_arg;
1646 devpriv->ai_neverending = 0;
1648 devpriv->ai_scans = 0;
1651 /* use sample&hold signal? */
1652 if (cmd->convert_src == TRIG_NOW)
1653 devpriv->usessh = 1;
1656 devpriv->usessh = 0;
1660 * use additional sample at end of every scan
1661 * to satisty DMA 32 bit transfer?
1663 devpriv->ai_add_front = 0;
1664 devpriv->ai_add_back = 0;
1665 devpriv->useeoshandle = 0;
1666 if (devpriv->master) {
1667 devpriv->usedma = 1;
1668 if ((cmd->flags & TRIG_WAKE_EOS) &&
1669 (devpriv->ai_n_scanlen == 1)) {
1670 if (cmd->convert_src == TRIG_NOW)
1671 devpriv->ai_add_back = 1;
1672 if (cmd->convert_src == TRIG_TIMER) {
1673 devpriv->usedma = 0;
1675 * use INT transfer if scanlist
1676 * have only one channel
1680 if ((cmd->flags & TRIG_WAKE_EOS) &&
1681 (devpriv->ai_n_scanlen & 1) &&
1682 (devpriv->ai_n_scanlen > 1)) {
1683 if (cmd->scan_begin_src == TRIG_FOLLOW) {
1685 * vpriv->useeoshandle=1; // change DMA transfer
1686 * block to fit EOS on every second call
1688 devpriv->usedma = 0;
1690 * XXX maybe can be corrected to use 16 bit DMA
1693 * well, we must insert one sample
1694 * to end of EOS to meet 32 bit transfer
1696 devpriv->ai_add_back = 1;
1699 } else { /* interrupt transfer don't need any correction */
1700 devpriv->usedma = 0;
1704 * we need software S&H signal?
1705 * It adds two samples before every scan as minimum
1707 if (devpriv->usessh && devpriv->softsshdelay) {
1708 devpriv->ai_add_front = 2;
1709 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
1710 /* move it to front */
1711 devpriv->ai_add_front++;
1712 devpriv->ai_add_back = 0;
1714 if (cmd->convert_arg < this_board->ai_ns_min)
1715 cmd->convert_arg = this_board->ai_ns_min;
1716 addchans = devpriv->softsshdelay / cmd->convert_arg;
1717 if (devpriv->softsshdelay % cmd->convert_arg)
1719 if (addchans > (devpriv->ai_add_front - 1)) {
1720 /* uff, still short */
1721 devpriv->ai_add_front = addchans + 1;
1722 if (devpriv->usedma == 1)
1723 if ((devpriv->ai_add_front +
1724 devpriv->ai_n_chan +
1725 devpriv->ai_add_back) & 1)
1726 devpriv->ai_add_front++;
1727 /* round up to 32 bit */
1730 /* well, we now know what must be all added */
1731 devpriv->ai_n_realscanlen = /*
1732 * what we must take from card in real
1733 * to have ai_n_scanlen on output?
1735 (devpriv->ai_add_front + devpriv->ai_n_chan +
1736 devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
1737 devpriv->ai_n_chan);
1739 /* check and setup channel list */
1740 if (!check_channel_list(dev, s, devpriv->ai_n_chan,
1741 devpriv->ai_chanlist, devpriv->ai_add_front,
1742 devpriv->ai_add_back))
1744 if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
1745 devpriv->ai_chanlist, 0, devpriv->ai_add_front,
1746 devpriv->ai_add_back, devpriv->usedma,
1747 devpriv->useeoshandle))
1750 /* compute timers settings */
1752 * simplest way, fr=4Mhz/(tim1*tim2),
1753 * channel manipulation without timers effect
1755 if (((cmd->scan_begin_src == TRIG_FOLLOW) ||
1756 (cmd->scan_begin_src == TRIG_EXT) ||
1757 (cmd->scan_begin_src == TRIG_INT)) &&
1758 (cmd->convert_src == TRIG_TIMER)) {
1759 /* both timer is used for one time */
1760 if (cmd->scan_begin_src == TRIG_EXT)
1764 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1765 &cmd->scan_begin_arg, &cmd->convert_arg,
1767 devpriv->ai_n_realscanlen,
1768 &devpriv->ai_divisor1,
1769 &devpriv->ai_divisor2, devpriv->usessh,
1770 devpriv->ai_add_front);
1771 devpriv->ai_timer2 = cmd->convert_arg;
1774 if ((cmd->scan_begin_src == TRIG_TIMER) &&
1775 ((cmd->convert_src == TRIG_TIMER) ||
1776 (cmd->convert_src == TRIG_NOW))) {
1777 /* double timed action */
1778 if (!devpriv->usedma) {
1780 "cmd->scan_begin_src=TRIG_TIMER works "
1781 "only with bus mastering!");
1786 pci9118_calc_divisors(devpriv->ai_do, dev, s,
1787 &cmd->scan_begin_arg, &cmd->convert_arg,
1789 devpriv->ai_n_realscanlen,
1790 &devpriv->ai_divisor1,
1791 &devpriv->ai_divisor2, devpriv->usessh,
1792 devpriv->ai_add_front);
1793 devpriv->ai_timer1 = cmd->scan_begin_arg;
1794 devpriv->ai_timer2 = cmd->convert_arg;
1797 if ((cmd->scan_begin_src == TRIG_FOLLOW)
1798 && (cmd->convert_src == TRIG_EXT)) {
1802 start_pacer(dev, -1, 0, 0); /* stop pacer */
1804 devpriv->AdControlReg = 0; /*
1805 * bipolar, S.E., use 8254, stop 8354,
1806 * internal trigger, soft trigger,
1809 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1810 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1812 * positive triggers, no S&H, no burst,
1813 * burst stop, no post trigger,
1814 * no about trigger, trigger stop
1816 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1818 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1819 inl(dev->iobase + PCI9118_ADSTAT); /*
1823 inl(dev->iobase + PCI9118_INTSRC);
1825 devpriv->ai_act_scan = 0;
1826 devpriv->ai_act_dmapos = 0;
1827 s->async->cur_chan = 0;
1828 devpriv->ai_buf_ptr = 0;
1830 if (devpriv->usedma)
1831 ret = pci9118_ai_docmd_dma(dev, s);
1833 ret = pci9118_ai_docmd_sampl(dev, s);
1838 static int pci9118_reset(struct comedi_device *dev)
1840 struct pci9118_private *devpriv = dev->private;
1842 devpriv->IntControlReg = 0;
1843 devpriv->exttrg_users = 0;
1844 inl(dev->iobase + PCI9118_INTCTRL);
1845 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1846 /* disable interrupts source */
1847 outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1848 /* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
1849 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
1850 devpriv->AdControlReg = 0;
1851 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1853 * bipolar, S.E., use 8254,
1854 * stop 8354, internal trigger,
1856 * disable INT and DMA
1858 outl(0, dev->iobase + PCI9118_BURST);
1859 outl(1, dev->iobase + PCI9118_SCANMOD);
1860 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
1861 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1862 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1864 * positive triggers, no S&H,
1865 * no burst, burst stop,
1871 devpriv->ao_data[0] = 2047;
1872 devpriv->ao_data[1] = 2047;
1873 outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1);
1874 /* reset A/D outs to 0V */
1875 outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
1876 outl(0, dev->iobase + PCI9118_DO); /* reset digi outs to L */
1878 inl(dev->iobase + PCI9118_AD_DATA);
1879 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1880 outl(0, dev->iobase + PCI9118_INTSRC); /* remove INT requests */
1881 inl(dev->iobase + PCI9118_ADSTAT); /* flush A/D status register */
1882 inl(dev->iobase + PCI9118_INTSRC); /* flush INT requests */
1883 devpriv->AdControlReg = 0;
1884 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1886 * bipolar, S.E., use 8254,
1887 * stop 8354, internal trigger,
1889 * disable INT and DMA
1892 devpriv->cnt0_users = 0;
1893 devpriv->exttrg_users = 0;
1899 * FIXME - this is pretty ineffective because all the supported board types
1900 * have the same device ID!
1902 static const struct boardtype *pci9118_find_boardinfo(struct pci_dev *pcidev)
1906 for (i = 0; i < ARRAY_SIZE(boardtypes); i++)
1907 if (pcidev->device == boardtypes[i].device_id)
1908 return &boardtypes[i];
1912 static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
1913 struct comedi_devconfig *it)
1915 const struct boardtype *this_board = comedi_board(dev);
1916 struct pci_dev *pcidev = NULL;
1917 int bus = it->options[0];
1918 int slot = it->options[1];
1920 for_each_pci_dev(pcidev) {
1921 if (pcidev->vendor != PCI_VENDOR_ID_AMCC)
1923 if (pcidev->device != this_board->device_id)
1926 /* requested particular bus/slot */
1927 if (pcidev->bus->number != bus ||
1928 PCI_SLOT(pcidev->devfn) != slot)
1933 dev_err(dev->class_dev,
1934 "no supported board found! (req. bus/slot : %d/%d)\n",
1939 static void pci9118_report_attach(struct comedi_device *dev, unsigned int irq)
1941 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1942 struct pci9118_private *devpriv = dev->private;
1947 snprintf(irqbuf, sizeof(irqbuf), "irq %u%s", irq,
1948 (dev->irq ? "" : " UNAVAILABLE"));
1950 snprintf(irqbuf, sizeof(irqbuf), "irq DISABLED");
1951 if (devpriv->usemux)
1952 snprintf(muxbuf, sizeof(muxbuf), "ext mux %u chans",
1955 snprintf(muxbuf, sizeof(muxbuf), "no ext mux");
1956 dev_info(dev->class_dev, "%s (pci %s, %s, %sbus master, %s) attached\n",
1957 dev->board_name, pci_name(pcidev), irqbuf,
1958 (devpriv->master ? "" : "no "), muxbuf);
1961 static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
1962 int master, int ext_mux, int softsshdelay,
1965 const struct boardtype *this_board = comedi_board(dev);
1966 struct pci9118_private *devpriv = dev->private;
1967 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1968 struct comedi_subdevice *s;
1973 dev->board_name = this_board->name;
1974 ret = comedi_pci_enable(dev);
1978 pci_set_master(pcidev);
1980 devpriv->iobase_a = pci_resource_start(pcidev, 0);
1981 dev->iobase = pci_resource_start(pcidev, 2);
1985 if (master) { /* alloc DMA buffers */
1986 devpriv->dma_doublebuf = 0;
1987 for (i = 0; i < 2; i++) {
1988 for (pages = 4; pages >= 0; pages--) {
1989 devpriv->dmabuf_virt[i] =
1990 (short *)__get_free_pages(GFP_KERNEL,
1992 if (devpriv->dmabuf_virt[i])
1995 if (devpriv->dmabuf_virt[i]) {
1996 devpriv->dmabuf_pages[i] = pages;
1997 devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
1998 devpriv->dmabuf_samples[i] =
1999 devpriv->dmabuf_size[i] >> 1;
2000 devpriv->dmabuf_hw[i] =
2001 virt_to_bus((void *)
2002 devpriv->dmabuf_virt[i]);
2005 if (!devpriv->dmabuf_virt[0]) {
2006 dev_warn(dev->class_dev,
2007 "Can't allocate DMA buffer, DMA disabled!\n");
2010 if (devpriv->dmabuf_virt[1])
2011 devpriv->dma_doublebuf = 1;
2013 devpriv->master = master;
2017 ext_mux = 256; /* max 256 channels! */
2018 if (softsshdelay > 0)
2021 devpriv->usemux = ext_mux;
2023 devpriv->usemux = 0;
2026 if (softsshdelay < 0) {
2027 /* select sample&hold signal polarity */
2028 devpriv->softsshdelay = -softsshdelay;
2029 devpriv->softsshsample = 0x80;
2030 devpriv->softsshhold = 0x00;
2032 devpriv->softsshdelay = softsshdelay;
2033 devpriv->softsshsample = 0x00;
2034 devpriv->softsshhold = 0x80;
2037 pci_read_config_word(pcidev, PCI_COMMAND, &u16w);
2038 pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64);
2039 /* Enable parity check for parity error */
2041 ret = comedi_alloc_subdevices(dev, 4);
2045 s = &dev->subdevices[0];
2046 dev->read_subdev = s;
2047 s->type = COMEDI_SUBD_AI;
2048 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2049 if (devpriv->usemux)
2050 s->n_chan = devpriv->usemux;
2052 s->n_chan = this_board->n_aichan;
2054 s->maxdata = this_board->ai_maxdata;
2055 s->len_chanlist = this_board->n_aichanlist;
2056 s->range_table = this_board->rangelist_ai;
2057 s->cancel = pci9118_ai_cancel;
2058 s->insn_read = pci9118_insn_read_ai;
2059 s->munge = pci9118_ai_munge;
2061 s = &dev->subdevices[1];
2062 s->type = COMEDI_SUBD_AO;
2063 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2064 s->n_chan = this_board->n_aochan;
2065 s->maxdata = this_board->ao_maxdata;
2066 s->len_chanlist = this_board->n_aochan;
2067 s->range_table = this_board->rangelist_ao;
2068 s->insn_write = pci9118_insn_write_ao;
2069 s->insn_read = pci9118_insn_read_ao;
2071 s = &dev->subdevices[2];
2072 s->type = COMEDI_SUBD_DI;
2073 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2076 s->len_chanlist = 4;
2077 s->range_table = &range_digital;
2078 s->io_bits = 0; /* all bits input */
2079 s->insn_bits = pci9118_insn_bits_di;
2081 s = &dev->subdevices[3];
2082 s->type = COMEDI_SUBD_DO;
2083 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2086 s->len_chanlist = 4;
2087 s->range_table = &range_digital;
2088 s->io_bits = 0xf; /* all bits output */
2089 s->insn_bits = pci9118_insn_bits_do;
2092 devpriv->i8254_osc_base = 250; /* 250ns=4MHz */
2093 devpriv->ai_maskharderr = 0x10a;
2094 /* default measure crash condition */
2095 if (hw_err_mask) /* disable some requested */
2096 devpriv->ai_maskharderr &= ~hw_err_mask;
2098 switch (this_board->ai_maxdata) {
2100 devpriv->ai16bits = 1;
2103 devpriv->ai16bits = 0;
2112 if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
2113 dev->board_name, dev)) {
2114 dev_warn(dev->class_dev,
2115 "unable to allocate IRQ %u, DISABLING IT\n",
2119 /* Enable AI commands */
2120 s = &dev->subdevices[0];
2121 s->subdev_flags |= SDF_CMD_READ;
2122 s->do_cmdtest = pci9118_ai_cmdtest;
2123 s->do_cmd = pci9118_ai_cmd;
2127 pci9118_report_attach(dev, irq);
2131 static int pci9118_attach(struct comedi_device *dev,
2132 struct comedi_devconfig *it)
2134 struct pci9118_private *devpriv;
2135 struct pci_dev *pcidev;
2136 int ext_mux, disable_irq, master, softsshdelay, hw_err_mask;
2138 ext_mux = it->options[2];
2139 master = ((it->options[3] & 1) == 0);
2140 disable_irq = ((it->options[3] & 2) != 0);
2141 softsshdelay = it->options[4];
2142 hw_err_mask = it->options[5];
2144 devpriv = comedi_alloc_devpriv(dev, sizeof(*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 = comedi_alloc_devpriv(dev, sizeof(*devpriv));
2167 dev->board_ptr = pci9118_find_boardinfo(pcidev);
2168 if (dev->board_ptr == NULL) {
2169 dev_err(dev->class_dev,
2170 "adl_pci9118: cannot determine board type for pci %s\n",
2175 * Need to 'get' the PCI device to match the 'put' in pci9118_detach().
2176 * (The 'put' also matches the implicit 'get' by pci9118_find_pci().)
2178 pci_dev_get(pcidev);
2179 /* Don't disable irq, use bus master, no external mux,
2180 * no sample-hold delay, no error mask. */
2181 return pci9118_common_attach(dev, 0, 1, 0, 0, 0);
2184 static void pci9118_detach(struct comedi_device *dev)
2186 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
2187 struct pci9118_private *devpriv = dev->private;
2193 free_irq(dev->irq, dev);
2194 if (devpriv->dmabuf_virt[0])
2195 free_pages((unsigned long)devpriv->dmabuf_virt[0],
2196 devpriv->dmabuf_pages[0]);
2197 if (devpriv->dmabuf_virt[1])
2198 free_pages((unsigned long)devpriv->dmabuf_virt[1],
2199 devpriv->dmabuf_pages[1]);
2201 comedi_pci_disable(dev);
2203 pci_dev_put(pcidev);
2206 static struct comedi_driver adl_pci9118_driver = {
2207 .driver_name = "adl_pci9118",
2208 .module = THIS_MODULE,
2209 .attach = pci9118_attach,
2210 .auto_attach = pci9118_auto_attach,
2211 .detach = pci9118_detach,
2212 .num_names = ARRAY_SIZE(boardtypes),
2213 .board_name = &boardtypes[0].name,
2214 .offset = sizeof(struct boardtype),
2217 static int adl_pci9118_pci_probe(struct pci_dev *dev,
2218 const struct pci_device_id *id)
2220 return comedi_pci_auto_config(dev, &adl_pci9118_driver,
2224 static DEFINE_PCI_DEVICE_TABLE(adl_pci9118_pci_table) = {
2225 { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) },
2228 MODULE_DEVICE_TABLE(pci, adl_pci9118_pci_table);
2230 static struct pci_driver adl_pci9118_pci_driver = {
2231 .name = "adl_pci9118",
2232 .id_table = adl_pci9118_pci_table,
2233 .probe = adl_pci9118_pci_probe,
2234 .remove = comedi_pci_auto_unconfig,
2236 module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver);
2238 MODULE_AUTHOR("Comedi http://www.comedi.org");
2239 MODULE_DESCRIPTION("Comedi low-level driver");
2240 MODULE_LICENSE("GPL");